Class: HrLite::CompOffRequest

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

Overview

"I worked on a weekend/holiday — credit me a day off." Approval credits the comp-off leave type's balance (an adjustment, so it shows up in the normal balance chips and can be spent through the ordinary leave flow).

Defined Under Namespace

Classes: MissingCompOffType, StaleOffDay

Constant Summary collapse

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

Instance Method Summary collapse

Instance Method Details

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

Credits the comp-off balance inside the row lock, so a double-tap cannot credit twice. Fails loudly when no comp-off type is configured or the day stopped being an off day (holiday edited away).

Raises:



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'app/models/hr_lite/comp_off_request.rb', line 43

def approve!(actor:, note: nil)
  type = LeaveType.comp_off_type
  raise MissingCompOffType if type.nil?

  transition!("approved", actor, note) do
    raise StaleOffDay if WorkingCalendar.new(date_worked..date_worked).working_day?(date_worked)

    # (A duplicate live request for the same date cannot exist — the
    # partial unique index on [user_id, date_worked] guarantees it.)
    credit_balance!(type)
  end

  Notifications.publish(
    "comp_off.approved",
    title: "Comp-off approved — #{credit_days.to_f} day#{'s' if credit_days > 1} credited for #{date_worked.strftime('%d %b')}",
    body: decision_note.presence,
    path: "/comp_off_requests",
    bell_to: [ user ], email_to: [ user ]
  )
  true
end

#cancel!(actor:) ⇒ Object



77
78
79
80
81
82
83
84
85
86
# File 'app/models/hr_lite/comp_off_request.rb', line 77

def cancel!(actor:)
  transition!("cancelled", actor, nil)
  Notifications.publish(
    "comp_off.cancelled",
    title: "#{HrLite.display_name(user)} cancelled a comp-off request (#{date_worked.strftime('%d %b')})",
    path: "/admin/comp_off_requests",
    bell_to: HrLite.admin_users
  )
  true
end

#credit_daysObject



29
30
31
# File 'app/models/hr_lite/comp_off_request.rb', line 29

def credit_days
  half_day ? BigDecimal("0.5") : BigDecimal("1")
end

#punchObject

Shown to the approver: proof the person actually punched that day.



34
35
36
# File 'app/models/hr_lite/comp_off_request.rb', line 34

def punch
  AttendanceRecord.find_by(user_id: user_id, date: date_worked)
end

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



65
66
67
68
69
70
71
72
73
74
75
# File 'app/models/hr_lite/comp_off_request.rb', line 65

def reject!(actor:, note:)
  transition!("rejected", actor, note)
  Notifications.publish(
    "comp_off.rejected",
    title: "Comp-off rejected — #{date_worked.strftime('%d %b')}",
    body: decision_note.presence,
    path: "/comp_off_requests",
    bell_to: [ user ], email_to: [ user ]
  )
  true
end