Class: HrLite::Admin::EmployeesController

Inherits:
LeadershipController show all
Defined in:
app/controllers/hr_lite/admin/employees_controller.rb

Overview

Employee HR profiles (leadership). Onboarding can create the login itself (config.onboard_user); offboarding stamps the exit date and revokes access (config.offboard_user) — nothing is ever deleted, payroll history is a statutory record.

Instance Method Summary collapse

Instance Method Details

#createObject



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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'app/controllers/hr_lite/admin/employees_controller.rb', line 26

def create
   = params.dig(:employee_profile, :new_user_email).present?
  @profile = EmployeeProfile.new(profile_params)
  saved = false

  # One transaction: a profile that fails validation used to leave the
  # freshly-created login committed — a role-bearing account with no HR
  # profile, invisible on every HR screen.
  ActiveRecord::Base.transaction do
    if 
      user = HrLite.config.onboard_user.call(
        name: params.dig(:employee_profile, :new_user_name).to_s,
        email: params.dig(:employee_profile, :new_user_email).to_s.strip,
        password: params.dig(:employee_profile, :new_user_password).to_s
      )
      @profile.user_id = user.id
    end

    saved = @profile.save
    raise ActiveRecord::Rollback unless saved
  end

  if saved
    if 
      invite_url = HrLite.config.invite_url_for&.call(@profile.user)
      Notifications.publish(
        "employee.onboarded",
        title: "Welcome aboard — your HR account is ready",
        body: invite_url ? "Set your password with the button below, then sign in with your email."
                         : "Sign in with your email; your manager has your starting password.",
        path: "/",
        link_url: invite_url,
        bell_to: [ @profile.user ],
        email_to: [ @profile.user ]
      )
    end
    redirect_to admin_employee_path(@profile), notice: "Employee #{'onboarded' if } profile created."
  else
    render :new, status: :unprocessable_entity
  end
rescue ActiveRecord::RecordInvalid => e
  @profile.errors.add(:base, "Could not create the login: #{e.record.errors.full_messages.to_sentence}")
  render :new, status: :unprocessable_entity
rescue ActiveRecord::RecordNotUnique
  @profile.errors.add(:base, "Could not create the login: that email already has an account")
  render :new, status: :unprocessable_entity
end

#editObject



74
75
76
# File 'app/controllers/hr_lite/admin/employees_controller.rb', line 74

def edit
  @profile = EmployeeProfile.find(params[:id])
end

#indexObject



8
9
10
11
12
13
14
# File 'app/controllers/hr_lite/admin/employees_controller.rb', line 8

def index
  @profiles = paginate(EmployeeProfile.includes(:user).order(:employee_code))
  # One pluck instead of an EXISTS query per employee.
  profiled = EmployeeProfile.pluck(:user_id).to_set
  @users_without_profile = HrLite.employees.reject { |u| profiled.include?(u.id) }
  @pending_resignations = Resignation.pending.includes(:user).recent_first
end

#newObject



22
23
24
# File 'app/controllers/hr_lite/admin/employees_controller.rb', line 22

def new
  @profile = EmployeeProfile.new(user_id: params[:user_id], date_of_joining: Date.current)
end

#offboardObject

Exit: stamps the date (attendance/payroll clip on it) and revokes access via the host hook. Audited via the profile update.



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'app/controllers/hr_lite/admin/employees_controller.rb', line 89

def offboard
  @profile = EmployeeProfile.find(params[:id])
  # `.to_date` on a raw param raises Date::Error and 500s; the
  # controller's own parser exists for exactly this.
  exit_date = params[:date_of_exit].present? ? parse_date_param(params[:date_of_exit]) : Date.current

  @profile.update!(date_of_exit: exit_date)
  begin
    HrLite.config.offboard_user.call(@profile.user)
  rescue => e
    Rails.logger.error("[hr_lite] offboard_user failed: #{e.class}: #{e.message}")
  end
  redirect_to admin_employee_path(@profile),
              notice: "Offboarded — last day #{exit_date.strftime('%d %b %Y')}, access revoked."
rescue ActiveRecord::RecordInvalid => e
  redirect_to admin_employee_path(@profile), alert: e.record.errors.full_messages.to_sentence
end

#showObject



16
17
18
19
20
# File 'app/controllers/hr_lite/admin/employees_controller.rb', line 16

def show
  @profile = EmployeeProfile.includes(:user).find(params[:id])
  @structures = SalaryStructure.where(user_id: @profile.user_id).order(effective_from: :desc)
  @pending_resignation = Resignation.pending.find_by(user_id: @profile.user_id)
end

#updateObject



78
79
80
81
82
83
84
85
# File 'app/controllers/hr_lite/admin/employees_controller.rb', line 78

def update
  @profile = EmployeeProfile.find(params[:id])
  if @profile.update(update_profile_params)
    redirect_to admin_employee_path(@profile), notice: "Employee profile updated."
  else
    render :edit, status: :unprocessable_entity
  end
end