Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class User < ActiveRecord::Base
- include Publi::UserExtension
- include Report::Reportable
- include ::Rankable
- self.ranking_parent_column_name = :unit_id
- acts_as_paranoid
- has_many_roles :admin, :moderator, :evaluative, :academic, :superior, :doctoral, default: :academic
- belongs_to :unit
- has_many :user_units
- has_many :editable_units, through: :user_units, source: :unit
- has_many :surveys
- has_many :achievements
- has_one :job_info
- has_many :achievement_files
- devise :database_authenticatable, :timeoutable,
- :rememberable, :trackable, :registerable,
- :validatable, :recoverable
- attr_accessor :updated_by, :default_password
- attr_accessible :email, :password, :password_confirmation, :remember_me,
- :updated_by, :first_name, :last_name, :unit, :unit_id, :all_units,
- :editable_unit_ids, :job_info_attributes, :default_password, :roles_mask,
- :deleted_at, :publi_id, :unarchived_at
- @@for_select_cache = {}
- accepts_nested_attributes_for :job_info
- set_mass_actions :destroy, :make_admin, :make_user
- define_perform_action(:make_admin) { role_for_all(:admin) }
- define_perform_action(:make_moderator) { role_for_all(:moderator) }
- define_perform_action(:make_evaluative) { role_for_all(:evaluative) }
- define_perform_action(:make_academic) { role_for_all(:academic) }
- define_perform_action(:make_superior) { role_for_all(:superior) }
- define_perform_action(:make_doctoral) { role_for_all(:doctoral) }
- validates :first_name, :last_name, presence: true
- validates :unit_id, presence: true, inclusion: { in: proc { Unit.pluck(:id) } }, reduce: true,
- unless: :admin?
- validates :roles, length: { minimum: 1 }
- validates :publi_id, numericality: true, if: proc { publi_id.present? }
- scope :filter_by_created_after, -> (date) { where("`#{table_name}`.`created_at` > ?", Date.parse(date)) }
- scope :filter_by_created_before, -> (date) { where("`#{table_name}`.`created_at` < ?", Date.parse(date)) }
- scope :filter_by_updated_after, -> (date) { where("`#{table_name}`.`updated_at` > ?", Date.parse(date)) }
- scope :filter_by_updated_before, -> (date) { where("`#{table_name}`.`updated_at` < ?", Date.parse(date)) }
- scope :filter_by_archived_after, -> (date) { with_deleted.where("`#{table_name}`.`deleted_at` IS NOT NULL AND `#{table_name}`.`deleted_at` > ?", Date.parse(date)) }
- scope :filter_by_archived_before, -> (date) { with_deleted.where("`#{table_name}`.`deleted_at` IS NOT NULL AND `#{table_name}`.`deleted_at` < ?", Date.parse(date)) }
- scope :filter_by_archived_users, -> (value) { where(value.to_i == 1 ? 'deleted_at IS NOT NULL' : 'deleted_at IS NULL') }
- scope :filter_by_owner, -> (unit_id) { where(unit_id: Unit.find(unit_id).descendants_and_self_ids) }
- scope :filter_by_role, -> (role) { with_role(role) }
- scope :filter_by_match, (lambda do |phrase|
- query = [
- "CONCAT(`#{table_name}`.`first_name`, ' ', `#{table_name}`.`last_name`) LIKE :phrase",
- "`#{table_name}`.`email` LIKE :phrase"
- ]
- where(query.join(' OR '), phrase: "%#{phrase}%")
- end)
- scope :with_job_info, -> { joins("LEFT OUTER JOIN `job_infos` ON `#{table_name}`.`id` = `job_infos`.`user_id`") }
- scope :with_any_achievement, -> { joins(:achievements).group("`#{table_name}`.`id`").having("COUNT(`achievements`.`id`) > 0") }
- scope :available_for_survey, (lambda do |user|
- with_job_info
- .where("`job_infos`.`job_type` IS NOT NULL AND `job_infos`.`job_type` <> ?", 'nd')
- .where(user.all_units ? {} : { unit_id: user.editable_unit_ids_with_subunits })
- end)
- before_validation :clear_units_if_all_units_checked
- after_commit :clear_for_select_cache
- def self.for_select(prefix = nil, user = nil)
- @for_select ||= {}
- if user.blank? || user.all_units
- @for_select[prefix] ||= connection.select_all(User.joins(:unit)
- .select('users.id, users.first_name, users.last_name, users.email, units.name as unit_name')
- .order('users.last_name', 'users.first_name')).map do |attributes|
- [user_label(attributes), "#{prefix}#{attributes['id']}"]
- end
- else
- where(unit_id: user.editable_unit_ids_with_subunits).order('last_name, first_name').map do |u|
- [u.label, "#{prefix}#{u.id}"]
- end
- end
- end
- def editable_unit_ids_with_subunits
- if self.editable_unit_ids.blank?
- unit.descendants_and_self_ids
- else
- result = []
- self.editable_unit_ids.each do |u|
- result += Unit.find(u).descendants_and_self_ids
- end
- result
- end
- end
- def self.unique_api_params
- connection
- .select_all(self.select('first_name, last_name, unit_id, publi_id')
- .order('last_name, first_name, unit_id, publi_id')
- .with_any_role(:academic, :doctoral, :evaluative, :superior))
- .map! { |value| [value['first_name'], value['last_name'], value['unit_id'], value['publi_id']] }
- .uniq
- end
- def self.find_by_name(fullname)
- # => hope that all users has names like "Foo Bar" or "Foo Bar-Baz"
- name = fullname.split
- if name.size > 2
- last_name = name.first + ' ' + name.second
- self.where(first_name: name.last, last_name: last_name).first
- else
- self.where(first_name: name.last, last_name: name.first).first
- end
- end
- def default_password=(value)
- self.password = self.password_confirmation = @default_password = value
- end
- def name
- "#{last_name} #{first_name}"
- end
- def label
- "#{name} <#{email}>".tap do |label|
- label << " (#{unit.name})" if unit
- end
- end
- def self.user_label(attributes)
- "#{attributes["last_name"]} #{attributes["first_name"]} <#{attributes["email"]}>".tap do |label|
- label << " (#{attributes["unit_name"]})" unless attributes['unit_name'].nil?
- end
- end
- # def label
- # for_select.select do |arr|
- # arr.last == id.to_s
- # end.first
- # end
- def all_units
- @all_units || editable_units.empty?
- end
- def all_units=(value)
- return @all_units = nil if value.nil?
- @all_units = (value.to_i == 1)
- end
- def summary(quantitative = false, options = {})
- Fields
- options.delete_if { |_k, v| v.blank? }
- archived = !!options[:archived]
- achievements_repository = archived ? achievements.with_deleted.where(archived: archived) : achievements
- a = achievements_repository
- .with_points
- .joins(:achievement_type)
- .where(summary_options_to_where_clause(options))
- if quantitative == true
- a.count(:points, group: '`achievement_types`.`group`')
- .tap { |hash| hash.default = 0 }
- else
- a.sum(:points, group: '`achievement_types`.`group`')
- .tap { |hash| hash.default = 0 }
- end
- end
- def publications_points
- achievements
- .joins(:achievement_type)
- .where(
- "achievement_types.group = ? AND achievement_types.subgroup IN (?)",
- 'II',
- ['1', '2', '3', '4']
- )
- .pluck(:points)
- .sum
- end
- def to_xlsx_row
- fields = [
- first_name,
- last_name,
- email,
- unit ? unit.name : 'n/a',
- unit ? unit.parentroot : 'n/a',
- unit ? unit.parentsecond : 'n/a',
- system_roles_str
- ]
- keys = (JobInfo.mile_stones_text + JobInfo.mile_stones_dates)
- if job_info
- keys.each do |key|
- v = job_info.send(key.to_sym)
- fields << (v.blank? ? 'n/a' : v)
- end
- else
- fields += (['n/a'] * keys.size)
- end
- fields
- end
- def self.to_xlsx
- Axlsx::Package.new do |xls|
- xls.workbook.add_worksheet(name: I18n.t('users.to_xlsx.sheet')) do |sheet|
- sheet << [
- I18n.t('users.to_xlsx.first_name'),
- I18n.t('users.to_xlsx.last_name'),
- I18n.t('users.to_xlsx.email'),
- I18n.t('users.to_xlsx.unit'),
- I18n.t('users.to_xlsx.department'),
- I18n.t('users.to_xlsx.institute'),
- I18n.t('users.to_xlsx.role')
- ] + (JobInfo.mile_stones_text + JobInfo.mile_stones_dates).collect { |key| I18n.t(key, scope: 'users.to_xlsx') }
- scoped.each do |users|
- sheet << users.to_xlsx_row
- end
- end
- end.to_stream.read
- end
- def achievement_to_xlsx_row(a, i)
- [
- i,
- a.label,
- a.achievement_year,
- a.points,
- a.created_at.strftime("%F"),
- a.publi_id
- ]
- end
- def achievements_to_xlsx(current_user)
- Axlsx::Package.new do |xls|
- xls.workbook.add_worksheet(name: name) do |sheet|
- sheet << ["Wykaz osiągnięć dla pracownika: #{name}"]
- sheet << ["Wygenerowane z systemu BOP #{DateTime.now.strftime("%F")} przez #{current_user.name}"]
- sheet << [
- "Lp.",
- "Nazwa osiagnięcia",
- "Rok osiągnięcia",
- "Punkty",
- "Data dodania",
- "Bibliografia ID"
- ]
- achievements_repository =
- deleted_at.present? ? achievements.with_deleted.where(archived: true) : achievements
- achievements_repository.each_with_index do |a, i|
- sheet << achievement_to_xlsx_row(a, i + 1)
- end
- end
- end.to_stream.read
- end
- def generate_detailed_report(params, created_by_name, archived = false)
- achievements_repository = archived ? achievements.with_deleted.where(archived: true) : achievements
- case params[:timespan]
- when 'all'
- @achievements_for_pdf = achievements_repository
- years_params = {}
- when 'year'
- @achievements_for_pdf = achievements_repository.where(achievement_year: params[:year])
- years_params = { year: params[:year] }
- when 'between'
- @achievements_for_pdf = achievements_repository.where('achievement_year >= ? AND achievement_year <= ?', params[:start_year], params[:end_year])
- years_params = { start_year: params[:start_year], end_year: params[:end_year] }
- end
- return if @achievements_for_pdf.count.zero?
- generate_pdf(created_by_name, years_params)
- end
- def system_roles_str
- rstr = ""
- if roles
- roles_str = roles.map { |r| I18n.t("helpers.roles.#{r.to_s}") }
- rstr = roles_str.join(", ")
- end
- return rstr
- end
- def is?(*role)
- !(roles & role).empty?
- end
- def more_than_one?
- User.where(first_name: first_name, last_name: last_name).size > 1
- end
- def user_index
- User.where(first_name: first_name, last_name: last_name).find_index(self) ||
- 0
- end
- delegate :job_type, :for_survey?, to: :job_info, allow_nil: true
- def self.to_autocomplete_json(query = '')
- { suggestions: scoped.select { |u| %r{} === u.label }.map { |user| { value: user.label, data: { id: user.id, name: user.name } } } }
- end
- def managable_units_ids
- units = Unit.where(id: user_units.pluck(:unit_id))
- units.inject([]) { |a, e| e.descendants_and_self_ids }
- end
- private
- def updated_by_admin?
- updated_by.present? && updated_by.admin?
- end
- def password_required?
- super && !updated_by_admin?
- end
- def clear_units_if_all_units_checked
- self.editable_units = [] if @all_units == true
- end
- def clear_for_select_cache
- @@for_select_cache = {}
- @for_select = {}
- end
- # methods for generating detailed report pdf
- def generate_pdf(created_by_name, years_params, output = StringIO.new)
- Prawn::Document.new do |pdf|
- pdf.font 'Open Sans'
- pdf.font_size 10
- pdf.fill_color 'FFFFFF'
- @width = [540]
- @column_widths = [30, 60, 340, 60, 50]
- i = 1
- points = { science: 0, dydactic: 0, organization: 0, other: 0 }
- by_group = @achievements_for_pdf.group_by do |a|
- a.achievement_type ? a.achievement_type.group_type : :other
- end
- by_group.each do |group, as|
- points[group] = as.sum { |a| a.points.to_f }
- by_group[group] = as.group_by do |a|
- a.achievement_type ? a.achievement_type.full_group : '0.'
- end
- by_group[group].each do |fg, as|
- by_group[group][fg] = as.group_by do |a|
- a.achievement_year
- end
- by_group[group][fg] = by_group[group][fg].sort_by { |k, v| k.to_i }.to_h
- end
- end
- by_group.default = {}
- generate_header(pdf, created_by_name, years_params)
- pdf.move_down 10
- generate_points_section(pdf, points, by_group[:science])
- pdf.move_down 10
- pdf.fill_color '000000'
- pdf.table(
- [['Lp.', 'Grupa', 'Nazwa osiagnięcia', 'Data dodania', 'Punkty']],
- column_widths: @column_widths,
- cell_style: { border_width: 0, padding: [5, 0, 5, 0], font_style: :bold }
- )
- groups = [:science, :dydactic, :organization, :other]
- groups.each do |key|
- i = generate_group(pdf, by_group[key], key, i)
- end
- pdf.number_pages '<page>', { at: [pdf.bounds.right - 50, 0], align: :right }
- end.render(output)
- output.rewind
- output
- end
- def generate_header(pdf, created_by_name, years_params)
- logo_path = Rails.root.join('app', 'assets', 'images', 'logo_us.png')
- pdf.table([[image: logo_path]], cell_style: { border_width: 0 })
- pdf.move_down 10
- pdf.table(
- [['Uniwersytet Szczeciński - wykaz osiągnięć naukowych, dydaktycznych, organizacyjnych']],
- column_widths: @width,
- row_colors: ['002060'],
- cell_style: { border_width: 0, padding: [5, 0, 5, 60], font_style: :bold }
- )
- pdf.fill_color '000000'
- pdf.table(
- [[last_name + ' ' + first_name]],
- column_widths: @width,
- row_colors: ['D9D9D9'],
- cell_style: { border_width: 0, padding: [5, 0, 5, 3], font_style: :bold }
- )
- if unit
- pdf.table(
- [[unit.parentroot]],
- column_widths: @width,
- cell_style: { border_width: 0, padding: [3, 0, 3, 0] }
- )
- pdf.table(
- [[unit.name]],
- column_widths: @width,
- cell_style: { border_width: 0, padding: [3, 0, 3, 0], font_style: :bold }
- )
- end
- pdf.table(
- [["Wygenerowane z systemu BOP #{Time.current.strftime('%Y-%m-%d')} przez #{created_by_name}"]],
- column_widths: @width,
- cell_style: { border_width: 0, padding: [2, 0, 2, 0], size: 8 }
- )
- if years_params[:start_year].present? && years_params[:end_year].present?
- pdf.table(
- [["Zakres lat od #{years_params[:start_year]} do #{years_params[:end_year]}"]],
- column_widths: @width,
- cell_style: { border_width: 0, padding: [2, 0, 2, 0], size: 8 }
- )
- elsif years_params[:year].present?
- pdf.table(
- [["Wybrany rok: #{years_params[:year]}"]],
- column_widths: @width,
- cell_style: { border_width: 0, padding: [2, 0, 2, 0], size: 8 }
- )
- end
- end
- def generate_points_section(pdf, points, science_as)
- pdf.fill_color 'FFFFFF'
- pdf.table(
- [['Podsumowanie punktacji:']],
- column_widths: @width,
- row_colors: ['C00000'],
- cell_style: { border_width: 0, font_style: :bold }
- )
- table_data = []
- points.each do |group, pts|
- table_data.push(["Suma punktów za #{get_group_title(group).downcase}", pts.round(2)])
- end
- pdf.fill_color '000000'
- pdf.table(
- [table_data[0]],
- column_widths: [490, 50],
- row_colors: ['D9D9D9'],
- cell_style: { border_width: 0, font_style: :bold }
- )
- science_pts = 0
- science_as.each do |_, years|
- science_pts += years.values.flatten.inject(0) { |sum, a| a.publi_id ? sum + a.points : sum }
- end
- pdf.fill_color '000000'
- pdf.table(
- [['w tym za publikacje', science_pts.round(2)]],
- column_widths: [394, 146],
- row_colors: ['D9D9D9'],
- cell_style: { border_width: 0, font_style: :bold, padding: [0, 0, 0, 102] }
- )
- pdf.fill_color '000000'
- pdf.table(
- table_data[1..3],
- column_widths: [490, 50],
- row_colors: ['D9D9D9'],
- cell_style: { border_width: 0, font_style: :bold }
- )
- pdf.fill_color 'FFFFFF'
- pdf.table(
- [['Suma punktów za wszystkie osiągnięcia', points.values.sum.round(2)]],
- column_widths: [490, 50],
- row_colors: ['002060'],
- cell_style: { border_width: 0, font_style: :bold }
- )
- end
- def generate_group(pdf, full_group, group_name, i)
- pdf.fill_color 'FFFFFF'
- return i if full_group.empty?
- pdf.table(
- [[get_group_title(group_name)]],
- column_widths: @width,
- row_colors: ['C00000'],
- cell_style: { border_width: 0, padding: [2, 0, 5, 210], font_style: :bold }
- )
- pdf.fill_color '000000'
- full_group.each do |group, years|
- full_group_name =
- if group == '0.'
- 'Usunięte grupy osiągnięć'
- else
- AchievementType.find_by_full_group(group).name
- end
- pdf.table(
- [[i, group, full_group_name, '', years.values.flatten.sum { |a| a.points.to_f }.round(2)]],
- column_widths: [30, 60, 400, 0, 50],
- row_colors: ['D9D9D9'],
- cell_style: { border_width: 0, font_style: :bold }
- )
- years.each do |year, as|
- pdf.fill_color(year.nil? ? 'FF0000' : 'FFFFFF')
- pdf.table(
- [['', "Rok osiągnięcia: #{year.nil? ? 'BRAK' : year}"]],
- column_widths: [90, 450],
- row_colors: ['002060'],
- cell_style: { border_width: 0, font_style: :bold }
- )
- pdf.fill_color '000000'
- as.each do |a|
- pdf.fill_color 'FF0000' if a.points.nil?
- pdf.table(
- [['', '', a.label, a.created_at.strftime('%Y-%m-%d'), a.points.nil? ? 'brak oceny' : a.points.round(2)]],
- column_widths: @column_widths,
- cell_style: { border_width: 0, padding: [5, 0, 5, 5] }
- )
- pdf.fill_color '000000' if a.points.nil?
- end
- end
- i += 1
- end
- i
- end
- def get_group_title(group_name)
- case group_name.to_sym
- when :science then 'Osiągnięcia naukowe'
- when :organization then 'Osiągnięcia organizacyjne'
- when :dydactic then 'Osiągnięcia dydaktyczne'
- else 'Inne osiągnięcia'
- end
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement