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
45
46
47
48
49
50
51
52
53
# 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)
    # Someone can resign before HR ever created their profile. That is not
    # a reason to refuse the resignation — but the caller has to know
    # nothing was stamped, because the screen used to claim it was.
    @exit_date_recorded = profile.present?
    profile&.update!(date_of_exit: final_day)
  end

  # Notice periods are the normal case, so access is revoked here only
  # when the last day has already passed. Otherwise the person keeps
  # working it out and leadership revokes from the employee page.
  revoke_access! if final_day <= Date.current

  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

#exit_date_recorded?Boolean

False when the person had no employee profile to stamp — see accept!.

Returns:

  • (Boolean)


69
70
71
# File 'app/models/hr_lite/resignation.rb', line 69

def exit_date_recorded?
  @exit_date_recorded
end

#withdraw!(actor:) ⇒ Object

Raises:

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


55
56
57
58
59
60
61
62
63
64
65
66
# File 'app/models/hr_lite/resignation.rb', line 55

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