Class: HrLite::Resignation

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

Overview

Employee-initiated exit. One open resignation per person; accepting it stamps the employee profile's exit date (which payroll and attendance already respect) and notifies both sides. Withdrawal is allowed while pending — leaving should never need an email thread.

Constant Summary collapse

STATUSES =
%w[pending accepted withdrawn].freeze

Instance Method Summary collapse

Instance Method Details

#accept!(actor:, last_day: nil, note: nil) ⇒ Object

Raises:

  • (ActiveRecord::RecordInvalid.new(self))


24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'app/models/hr_lite/resignation.rb', line 24

def accept!(actor:, last_day: nil, note: nil)
  raise ActiveRecord::RecordInvalid.new(self), "not pending" unless pending?

  final_day = last_day.presence || proposed_last_day
  transaction do
    update!(status: "accepted", decided_by_id: actor.id, decided_at: Time.current,
            decision_note: note.presence, proposed_last_day: final_day)
    profile = EmployeeProfile.find_by(user_id: user_id)
    profile&.update!(date_of_exit: final_day)
  end

  Notifications.publish(
    "resignation.accepted",
    title: "Resignation accepted — last working day #{final_day.strftime('%d %b %Y')}",
    body: note.presence,
    path: "/resignation",
    bell_to: [ user ],
    email_to: [ user ]
  )
  true
end

#withdraw!(actor:) ⇒ Object

Raises:

  • (ActiveRecord::RecordInvalid.new(self))


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

def withdraw!(actor:)
  raise ActiveRecord::RecordInvalid.new(self), "not pending" unless pending? && actor.id == user_id

  update!(status: "withdrawn", decided_at: Time.current)
  Notifications.publish(
    "resignation.withdrawn",
    title: "#{HrLite.display_name(user)} withdrew their resignation",
    path: "/admin/employees",
    bell_to: HrLite.admin_users
  )
  true
end