Class: TimeOffBalance

Inherits:
ApplicationRecord show all
Includes:
Models::Auditable
Defined in:
app/models/time_off_balance.rb

Overview

== Schema Information

Table name: time_off_balances
Database name: primary

id :bigint not null, primary key
amount :decimal(, )
category :enum default("accrual"), not null
date :date
note :text
created_at :datetime not null
updated_at :datetime not null
employee_id :integer
time_off_policy_id(References the policy that influenced the balance) :integer
time_off_request_id :integer
time_off_type_id :integer

Indexes

index_time_off_balances_on_date (date)
index_time_off_balances_on_employee_id (employee_id)
index_time_off_balances_on_time_off_policy_id (time_off_policy_id)
index_time_off_balances_on_time_off_request_id (time_off_request_id)
index_time_off_balances_on_time_off_type_id (time_off_type_id)

Foreign Keys

fk_rails_... (employee_id => parties.id)
fk_rails_... (time_off_request_id => time_off_requests.id)
fk_rails_... (time_off_type_id => time_off_types.id)

Constant Summary

Constants included from Models::Auditable

Models::Auditable::ALWAYS_IGNORED

Constants included from Models::Schedulable

Models::Schedulable::SIMPLE_FORM_OPTIONS

Instance Attribute Summary collapse

Belongs to collapse

Methods included from Models::Auditable

#creator, #updater

Class Method Summary collapse

Methods included from Models::Auditable

#all_skipped_columns, #audit_reference_data, #should_not_save_version, #stamp_record

Methods inherited from ApplicationRecord

ransackable_associations, ransackable_attributes, ransackable_scopes, ransortable_attributes, #to_relation

Methods included from Models::Schedulable

config

Methods included from Models::AfterCommittable

#after_commit

Methods included from Models::EventPublishable

#publish_event

Instance Attribute Details

#amountBigDecimal (readonly)

Returns:

  • (BigDecimal)

Validations:



43
# File 'app/models/time_off_balance.rb', line 43

validates :amount, presence: true

#categoryEnum (readonly)

Returns:

  • (Enum)

Validations:

  • Uniqueness ({ scope: %i[time_off_request_id amount date], message: "already exists with the same time_off_request_id, amount, and date", conditions: -> { where.not(time_off_request_id: nil) } })


47
# File 'app/models/time_off_balance.rb', line 47

validates :category, presence: true

#noteString (readonly)

Returns:

  • (String)


45
# File 'app/models/time_off_balance.rb', line 45

validates :note, presence: true

Class Method Details

.calculate_accruals(policy, start_date, end_date) ⇒ void

Parameters:

  • policy (Object)
  • start_date (Object)
  • end_date (Object)
  • policy (Object)
  • start_date (Object)
  • end_date (Object)

Returns:

  • (void)
  • (void)


99
100
101
102
103
104
105
106
107
# File 'app/models/time_off_balance.rb', line 99

def self.calculate_accruals(policy, start_date, end_date)
  return 0 unless policy.accrual_rate && start_date && end_date

  # Determine number of periods within the range
  periods = ((end_date - start_date).to_i / (policy.accrual_period == 'weekly' ? 7 : 0)).to_i

  # Calculate total accruals
  periods * policy.accrual_rate
end

.categories_for_selectvoid

This method returns an undefined value.



86
87
88
89
# File 'app/models/time_off_balance.rb', line 86

def self.categories_for_select
  [['Manual Adjustment', 'manual_adjustment']]
  # categories.keys.map { |key| [key.titleize, key] }
end

.deduct_balance_for_request(request) ⇒ void

Parameters:

  • request (Object)
  • request (Object)

Returns:

  • (void)
  • (void)


134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'app/models/time_off_balance.rb', line 134

def self.deduct_balance_for_request(request)
  # Deduct balances from the first day of the approved request
  request.time_off_request_dates.each do |request_date|
    create!(
      employee_id: request.employee_id,
      time_off_type_id: request.time_off_type_id,
      time_off_request_id: request.id,
      date: request_date.date,
      amount: -request_date.amount,
      note: "Deduction for time-off request ##{request.id}"
    )
  end
end

.initialize_balance_for_employee(employee) ⇒ void

This method returns an undefined value.

Methods for managing balances

Parameters:

  • employee (Object)


66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'app/models/time_off_balance.rb', line 66

def self.initialize_balance_for_employee(employee)
  # Assign initial balance for each time-off type based on policy
  employee.time_off_policy_assignments.each do |policy_assignment|
    policy = policy_assignment.time_off_policy
    accrual_start_date = policy_assignment.accrual_start_date

    # Calculate total accruals from the start date until now
    balance_to_date = calculate_accruals(policy, accrual_start_date, Date.current)

    create!(
      employee_id: employee.id,
      time_off_type_id: policy.time_off_type_id,
      date: Date.current,
      amount: balance_to_date,
      note: "Initial balance for #{policy.name}"
    )
  end
end

.perform_biweekly_accrualsvoid

This method returns an undefined value.



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'app/models/time_off_balance.rb', line 110

def self.perform_biweekly_accruals
  Employee.includes(:time_off_policy_assignments).find_each do |employee|
    employee.time_off_policy_assignments.each do |policy_assignment|
      policy = policy_assignment.time_off_policy
      next unless policy

      # Accrue for the current biweekly period
      accrual_date = policy.accrues_at_period_start ? Date.current.beginning_of_week(:sunday) : Date.current.end_of_week(:saturday)

      create!(
        employee_id: employee.id,
        time_off_type_id: policy.time_off_type_id,
        date: accrual_date,
        amount: policy.accrual_rate,
        note: "Biweekly accrual for #{policy.name}"
      )
    end
  end
end

Instance Method Details

#employeeEmployee?

Returns:



36
# File 'app/models/time_off_balance.rb', line 36

belongs_to :employee

#time_off_requestTimeOffRequest?

Returns:



40
# File 'app/models/time_off_balance.rb', line 40

belongs_to :time_off_request, optional: true

#time_off_typeTimeOffType?

Returns:



38
# File 'app/models/time_off_balance.rb', line 38

belongs_to :time_off_type