Class: HrLite::LeaveRequest

Inherits:
ApplicationRecord show all
Defined in:
app/models/hr_lite/leave_request.rb

Constant Summary collapse

STATUSES =
%w[pending approved rejected cancelled].freeze

Instance Method Summary collapse

Instance Method Details

#approve!(actor:, note: nil) ⇒ Object

Returns false (leaving the request pending) when the balance no longer covers it — the re-check runs inside the row lock so two concurrent approvals cannot overdraw one balance.



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

def approve!(actor:, note: nil)
  insufficient = false
  transition!("approved", actor, note) do
    if insufficient_balance_now?
      insufficient = true
      raise ActiveRecord::Rollback
    end
  end
  return false if insufficient

  notify_decision("Leave approved")
  notify_team
  true
end

#balanceObject



99
100
101
# File 'app/models/hr_lite/leave_request.rb', line 99

def balance
  LeaveBalance.for(user, leave_type, LeaveYear.key_for(start_date))
end

#cancel!(actor:) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'app/models/hr_lite/leave_request.rb', line 74

def cancel!(actor:)
  was_approved = approved?
  self.status = "cancelled"
  self.decided_by_id = actor.id
  self.decided_at = Time.current
  save!

  Notifications.publish(
    "leave.cancelled",
    title: "#{HrLite.display_name(user)} cancelled #{was_approved ? 'approved ' : ''}leave " \
           "(#{date_range_label})",
    path: "/admin/leave_requests",
    bell_to: HrLite.admin_users
  )
  true
end

#cancellable_by?(actor) ⇒ Boolean

Owner may cancel while pending, or an approved future leave (quota returns automatically because used is computed). Admins may cancel any pending/approved future leave.

Returns:

  • (Boolean)


68
69
70
71
72
# File 'app/models/hr_lite/leave_request.rb', line 68

def cancellable_by?(actor)
  return false unless pending? || (approved? && start_date > Date.current)

  user_id == actor.id || HrLite.admin?(actor) || HrLite.leadership?(actor)
end

#date_range_labelObject



91
92
93
94
95
96
97
# File 'app/models/hr_lite/leave_request.rb', line 91

def date_range_label
  if start_date == end_date
    "#{start_date.strftime('%d %b')}#{half_day ? ' (half day)' : ''}"
  else
    "#{start_date.strftime('%d %b')}#{end_date.strftime('%d %b')}"
  end
end

#paid?Boolean

Returns:

  • (Boolean)


35
36
37
# File 'app/models/hr_lite/leave_request.rb', line 35

def paid?
  leave_type.paid
end

#reject!(actor:, note:) ⇒ Object



59
60
61
62
63
# File 'app/models/hr_lite/leave_request.rb', line 59

def reject!(actor:, note:)
  transition!("rejected", actor, note)
  notify_decision("Leave rejected")
  true
end