Module: Models::EmployeeTimeOffAccruals

Extended by:
ActiveSupport::Concern
Includes:
EmployeeTimeOffDeductions, EmployeeTimeOffRollover
Included in:
Employee
Defined in:
app/concerns/models/employee_time_off_accruals.rb

Overview

Weekly/periodic time-off accrual processing for Employee.

Instance Method Summary collapse

Methods included from EmployeeTimeOffRollover

#process_policy_transitions, #process_rollover_and_expiry

Methods included from EmployeeTimeOffDeductions

#process_time_off_requests

Instance Method Details

#create_balance(**attrs) ⇒ TimeOffBalance

Creates a TimeOffBalance row, defaulting the category to 'accrual'.

Parameters:

  • attrs (Hash)

    attributes for the new TimeOffBalance row

Options Hash (**attrs):

  • category (String)

    balance category (defaults to 'accrual')

Returns:

Raises:

  • (ActiveRecord::RecordInvalid)

    if the balance fails validation



309
310
311
312
# File 'app/concerns/models/employee_time_off_accruals.rb', line 309

def create_balance(**attrs)
  attrs[:category] ||= 'accrual'
  time_off_balances.create!(**attrs)
end

#current_time_off_policy_for(time_off_type, as_of_date = Date.current) ⇒ TimeOffPolicy?

Finds the time-off policy currently in effect for the employee based on
tenure since hire date.

Picks the policy with the highest min_tenure whose tenure window
contains the employee's tenure as of as_of_date.

Parameters:

  • time_off_type (TimeOffType)

    the type of time off to look up

  • as_of_date (Date) (defaults to: Date.current)

    date at which tenure is evaluated

Returns:

  • (TimeOffPolicy, nil)

    the matching policy, or nil if the employee
    has no hire date or no policy covers the tenure window



45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'app/concerns/models/employee_time_off_accruals.rb', line 45

def current_time_off_policy_for(time_off_type, as_of_date = Date.current)
  return nil if employee_record&.hire_date.blank?

  tenure = (as_of_date - employee_record.hire_date).to_i / 365.25

  time_off_type.time_off_policies
               .joins(:time_off_policy_assignments)
               .where(time_off_policy_assignments: { employee_id: id })
               .where(min_tenure: ..tenure)
               .where('max_tenure >= ? OR max_tenure IS NULL', tenure)
               .order(min_tenure: :desc)
               .first
end

#process_accruals(simulate_date: nil) ⇒ void

This method returns an undefined value.

Processes time-off accruals for the employee's active policy assignment.

Finds the active policy assignment as of the effective date, dispatches
the appropriate accrual based on the policy's frequency (weekly, monthly,
yearly, or custom interval), then processes any non-accruable deductions.

Parameters:

  • simulate_date (Date, nil) (defaults to: nil)

    optional date to simulate the run for
    (skips persisting regular accruals; still evaluates end-of-year partials)



21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'app/concerns/models/employee_time_off_accruals.rb', line 21

def process_accruals(simulate_date: nil)
  return if time_off_policy_assignments.blank?

  effective_date = simulate_date || Date.current
  active_assignment = active_policy_assignment(effective_date)
  return unless active_assignment

  policy = active_assignment.time_off_policy
  time_off_type = policy.time_off_type

  dispatch_accrual(active_assignment, policy, time_off_type, simulate_date:)
  process_non_accruable_deductions(active_assignment.employee, simulate_date:)
end

#process_work_schedule_transitionsvoid

This method returns an undefined value.

Expires approved work schedules whose expiry date is today.



62
63
64
# File 'app/concerns/models/employee_time_off_accruals.rb', line 62

def process_work_schedule_transitions
  work_schedules.where(expiry_date: Date.current, state: 'approved').find_each(&:expire!)
end