Class: EmployeeReview
Overview
== Schema Information
Table name: employee_reviews
Database name: primary
id :integer not null, primary key
appraisal_and_development_of_people :integer
appraisal_and_development_of_people_emp_cmts :text
appraisal_and_development_of_people_sup_cmts :text
communication_skills :integer
communication_skills_emp_cmts :text
communication_skills_sup_cmts :text
employee_comments :text
end_period :date
leadership_ability_sup_cmts :text
maximum_score :integer
planning_and_organization :integer
planning_and_organization_emp_cmts :text
planning_and_organization_sup_cmts :text
pto_reviewed :boolean default(FALSE)
review :jsonb
review_date :date not null
review_name :string(255) not null
review_type :string not null
start_period :date
state :string(255) not null
supervisor_comments :text
total_score :integer
created_at :datetime not null
updated_at :datetime not null
creator_id :integer
employee_record_id :integer
reviewer_id :integer
updater_id :integer
Indexes
employee_reviews_employee_record_id_idx (employee_record_id)
employee_reviews_reviewer_id_idx (reviewer_id)
idx_review_name_er_id (review_name,employee_record_id)
idx_review_type_er_id (review_type,employee_record_id)
Foreign Keys
employee_reviews_employee_record_id_fk (employee_record_id => employee_records.id) ON DELETE => cascade
employee_reviews_reviewer_id_fk (reviewer_id => employee_records.id) ON DELETE => nullify
Defined Under Namespace
Classes: ReviewItem
Constant Summary
collapse
- REVIEW_ITEMS_BY_TYPE =
{
kpi: %i[sales_goals_progression
sales_channel_revenue
customer_performance_review
proactive_calls
sales_goals_vs_promised_orders
call_volumes_call_report
call_volumes_call_block
opportunity_conversion
lead_conversion],
quarterly: %i[growth
initiative
resourcefulness
attendance_and_reliability
improvements
achievements
strength_utilization]
}.freeze
Models::Auditable::ALWAYS_IGNORED
Instance Attribute Summary collapse
#creator, #updater
Class Method Summary
collapse
Instance Method Summary
collapse
#all_skipped_columns, #audit_reference_data, #should_not_save_version, #stamp_record
ransackable_associations, ransackable_attributes, ransackable_scopes, ransortable_attributes, #to_relation
#publish_event
Instance Attribute Details
#employee_record_id ⇒ Object
81
|
# File 'app/models/employee_review.rb', line 81
validates :review_date, :review_name, :start_period, :end_period, :employee_record_id, presence: true
|
#end_period ⇒ Object
81
|
# File 'app/models/employee_review.rb', line 81
validates :review_date, :review_name, :start_period, :end_period, :employee_record_id, presence: true
|
#review_date ⇒ Object
81
|
# File 'app/models/employee_review.rb', line 81
validates :review_date, :review_name, :start_period, :end_period, :employee_record_id, presence: true
|
#review_name ⇒ Object
80
|
# File 'app/models/employee_review.rb', line 80
validates :review_name, uniqueness: { scope: :employee_record_id }
|
#reviewer_id ⇒ Object
82
|
# File 'app/models/employee_review.rb', line 82
validates :reviewer_id, presence: { unless: :in_progress? }
|
#start_period ⇒ Object
81
|
# File 'app/models/employee_review.rb', line 81
validates :review_date, :review_name, :start_period, :end_period, :employee_record_id, presence: true
|
#warnings ⇒ Object
Returns the value of attribute warnings.
52
53
54
|
# File 'app/models/employee_review.rb', line 52
def warnings
@warnings
end
|
Class Method Details
.active ⇒ ActiveRecord::Relation<EmployeeReview>
A relation of EmployeeReviews that are active. Active Record Scope
95
|
# File 'app/models/employee_review.rb', line 95
scope :active, -> { where.not(state: %w[complete cancelled]) }
|
.all_states_for_select ⇒ Object
154
155
156
|
# File 'app/models/employee_review.rb', line 154
def self.all_states_for_select
state_machines[:state].states.map(&:name)
end
|
.build_for_employee(employee:, review_type:, reviewer_employee_record:) ⇒ Object
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
|
# File 'app/models/employee_review.rb', line 158
def self.build_for_employee(employee:, review_type:, reviewer_employee_record:)
employee_review = employee.employee_record.employee_reviews.build
employee_review.reviewer = reviewer_employee_record
employee_review.review_type = review_type
case review_type.to_sym
when :quarterly
employee_review.start_period = Date.current.beginning_of_quarter
employee_review.end_period = Date.current.end_of_quarter
employee_review.review_name = "#{Date.current.quarter_index.ordinalize} QTR #{Date.current.year} Review & Goals"
when :kpi
employee_review.start_period = Date.current.beginning_of_week - 2.weeks
employee_review.end_period = Date.current.end_of_week - 2.weeks
employee_review.review_name = "KPI Review #{employee_review.start_period} to #{employee_review.end_period}"
end
employee_review.review_date = [Date.current, employee_review.end_period.next_business_day].max
employee_review
end
|
.current_goals ⇒ ActiveRecord::Relation<EmployeeReview>
A relation of EmployeeReviews that are current goals. Active Record Scope
94
|
# File 'app/models/employee_review.rb', line 94
scope :current_goals, -> { goals_on(Date.current) }
|
.goals_on ⇒ ActiveRecord::Relation<EmployeeReview>
A relation of EmployeeReviews that are goals on. Active Record Scope
93
|
# File 'app/models/employee_review.rb', line 93
scope :goals_on, ->(date) { where(EmployeeReview[:start_period].lteq(date)).where(EmployeeReview[:end_period].gteq(date)) }
|
.overlapping ⇒ ActiveRecord::Relation<EmployeeReview>
A relation of EmployeeReviews that are overlapping. Active Record Scope
92
|
# File 'app/models/employee_review.rb', line 92
scope :overlapping, ->(review) { where(review_type: review.review_type).where("(DATE_PART('day',?::timestamp - start_period::timestamp) * DATE_PART('day', end_period::timestamp - ?::timestamp)) >= 0", review.end_period, review.start_period) }
|
.ratings_collection ⇒ Object
150
151
152
|
# File 'app/models/employee_review.rb', line 150
def self.ratings_collection
(1..5).to_a.map { |e| [I18n.t("employee_review.rank_summary.#{e.humanize}"), e] }
end
|
Instance Method Details
#all_goals_finalized? ⇒ Boolean
230
231
232
233
234
|
# File 'app/models/employee_review.rb', line 230
def all_goals_finalized?
(
employee_goals.finalized.size == employee_goals.size
)
end
|
#check_reward_allocation ⇒ Object
Check if allocated reward exceeds earned reward
266
267
268
269
270
|
# File 'app/models/employee_review.rb', line 266
def check_reward_allocation
return unless reward_allocation_amount > earned_reward
errors.add(:base, 'Allocated reward exceeds earned reward')
end
|
#default_review_items ⇒ Object
204
205
206
|
# File 'app/models/employee_review.rb', line 204
def default_review_items
default_review_items_keys.index_with { |key| {} }
end
|
#default_review_items_keys ⇒ Object
200
201
202
|
# File 'app/models/employee_review.rb', line 200
def default_review_items_keys
REVIEW_ITEMS_BY_TYPE[review_type.to_sym]
end
|
#earned_reward ⇒ Object
240
241
242
|
# File 'app/models/employee_review.rb', line 240
def earned_reward
employee_goals.sum(:earned_reward)
end
|
#employee_email ⇒ Object
181
182
183
|
# File 'app/models/employee_review.rb', line 181
def employee_email
employee_record.party.email
end
|
#employee_goals ⇒ ActiveRecord::Relation<EmployeeGoal>
77
|
# File 'app/models/employee_review.rb', line 77
has_many :employee_goals, inverse_of: :employee_review, dependent: :destroy
|
#employee_name ⇒ Object
252
253
254
|
# File 'app/models/employee_review.rb', line 252
def employee_name
employee_record&.employee&.full_name
end
|
75
|
# File 'app/models/employee_review.rb', line 75
belongs_to :employee_record, inverse_of: :employee_reviews, optional: true
|
#goals_defined? ⇒ Boolean
236
237
238
|
# File 'app/models/employee_review.rb', line 236
def goals_defined?
employee_goals.active.present?
end
|
#kpi? ⇒ Boolean
212
213
214
|
# File 'app/models/employee_review.rb', line 212
def kpi?
review_type.to_sym == :kpi
end
|
#notify_allocate_reward_to_complete ⇒ Object
#notify_process_reward_to_complete ⇒ Object
#overlaps?(other) ⇒ Boolean
Check if a given interval overlaps this interval
261
262
263
|
# File 'app/models/employee_review.rb', line 261
def overlaps?(other)
(start_period - other.end_period) * (other.start_period - end_period) >= 0
end
|
#possible_events ⇒ Object
216
217
218
|
# File 'app/models/employee_review.rb', line 216
def possible_events
state_transitions.map(&:event).sort
end
|
#potential_reward ⇒ Object
256
257
258
|
# File 'app/models/employee_review.rb', line 256
def potential_reward
employee_goals.sum(:potential_reward)
end
|
#previous_review_of_same_type ⇒ Object
193
194
195
196
197
198
|
# File 'app/models/employee_review.rb', line 193
def previous_review_of_same_type
EmployeeReview.where(review_type: review_type)
.where(employee_record_id: employee_record_id)
.where(EmployeeReview[:end_period].lt(start_period))
.order('employee_reviews.end_period DESC').first
end
|
#quarterly? ⇒ Boolean
208
209
210
|
# File 'app/models/employee_review.rb', line 208
def quarterly?
review_type.to_sym == :quarterly
end
|
#remaining_reward_for_employee ⇒ Object
248
249
250
|
# File 'app/models/employee_review.rb', line 248
def remaining_reward_for_employee
[earned_reward - reward_allocation_amount, 0].max
end
|
#reset_review_items ⇒ Object
220
221
222
223
|
# File 'app/models/employee_review.rb', line 220
def reset_review_items
set_default_review_items
save
end
|
#review ⇒ Object
276
277
278
279
280
281
282
|
# File 'app/models/employee_review.rb', line 276
def review
review_hash_raw = read_attribute(:review)
review_hash_sorted = review_hash_raw.sort_by { |k, _v| default_review_items_keys.index(k.to_sym) || 999 }.to_h
review_hash_sorted.map { |review_key, review_item_properties| ReviewItem.new(review_key, review_item_properties) }
end
|
#review_attributes=(attributes) ⇒ Object
284
285
286
287
288
289
290
291
292
293
294
|
# File 'app/models/employee_review.rb', line 284
def review_attributes=(attributes)
review_items = {}
attributes.each do |_index, attrs|
next if attrs.delete('_destroy') == '1'
factor = attrs.delete('factor')
review_items[factor.to_sym] = attrs
end
self[:review] = review_items
review_will_change!
end
|
#reviewable? ⇒ Boolean
272
273
274
|
# File 'app/models/employee_review.rb', line 272
def reviewable?
%i[in_progress process_reward complete].include?(state.to_sym)
end
|
76
|
# File 'app/models/employee_review.rb', line 76
belongs_to :reviewer, class_name: 'EmployeeRecord', inverse_of: :employee_reviewed, optional: true
|
#reviewer_email ⇒ Object
185
186
187
|
# File 'app/models/employee_review.rb', line 185
def reviewer_email
reviewer&.party&.email
end
|
#reward_allocation_amount ⇒ Object
244
245
246
|
# File 'app/models/employee_review.rb', line 244
def reward_allocation_amount
reward_allocations.to_a.map { |a| a.amount || 0.0 }.sum
end
|
#reward_allocations ⇒ ActiveRecord::Relation<RewardAllocation>
78
|
# File 'app/models/employee_review.rb', line 78
has_many :reward_allocations, inverse_of: :employee_review, dependent: :destroy
|
#set_default_review_items ⇒ Object
225
226
227
228
|
# File 'app/models/employee_review.rb', line 225
def set_default_review_items
self[:review] = default_review_items
review_will_change!
end
|
#to_s ⇒ Object
177
178
179
|
# File 'app/models/employee_review.rb', line 177
def to_s
"#{review_name} (#{start_period.to_fs(:crm_date_only)} to #{end_period.to_fs(:crm_date_only)})"
end
|
#total_donation ⇒ Object
189
190
191
|
# File 'app/models/employee_review.rb', line 189
def total_donation
reward_allocations.map(&:total_donation).compact.sum
end
|