hr_lite 0.53.0 → 0.55.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +73 -0
- data/README.md +5 -2
- data/app/assets/javascripts/hr_lite/confirm.js +9 -5
- data/app/assets/javascripts/hr_lite/countdown.js +9 -2
- data/app/assets/javascripts/hr_lite/emoji_pick.js +4 -4
- data/app/assets/javascripts/hr_lite/search.js +1 -1
- data/app/assets/stylesheets/hr_lite/hr_lite.css +24 -14
- data/app/controllers/hr_lite/admin/attendances_controller.rb +12 -3
- data/app/controllers/hr_lite/admin/audit_logs_controller.rb +1 -0
- data/app/controllers/hr_lite/admin/comp_off_requests_controller.rb +1 -1
- data/app/controllers/hr_lite/admin/documents_controller.rb +1 -1
- data/app/controllers/hr_lite/admin/employees_controller.rb +11 -4
- data/app/controllers/hr_lite/admin/expenses_controller.rb +17 -1
- data/app/controllers/hr_lite/admin/hr_requests_controller.rb +4 -0
- data/app/controllers/hr_lite/admin/leave_requests_controller.rb +5 -2
- data/app/controllers/hr_lite/admin/payroll_runs_controller.rb +9 -5
- data/app/controllers/hr_lite/admin/regularization_requests_controller.rb +1 -1
- data/app/controllers/hr_lite/admin/reports_controller.rb +3 -2
- data/app/controllers/hr_lite/admin/salary_structures_controller.rb +2 -0
- data/app/controllers/hr_lite/admin/statutory_rate_cards_controller.rb +2 -1
- data/app/controllers/hr_lite/admin/tax_declarations_controller.rb +15 -4
- data/app/controllers/hr_lite/admin/work_locations_controller.rb +1 -1
- data/app/controllers/hr_lite/approvals_controller.rb +1 -0
- data/app/controllers/hr_lite/home_controller.rb +2 -11
- data/app/controllers/hr_lite/loans_controller.rb +1 -1
- data/app/controllers/hr_lite/regularization_requests_controller.rb +4 -4
- data/app/controllers/hr_lite/tax_declarations_controller.rb +9 -5
- data/app/helpers/hr_lite/application_helper.rb +34 -9
- data/app/jobs/hr_lite/attendance_close_job.rb +1 -1
- data/app/jobs/hr_lite/payroll_compute_job.rb +12 -0
- data/app/models/concerns/hr_lite/audited.rb +3 -1
- data/app/models/concerns/hr_lite/encrypted_money.rb +8 -5
- data/app/models/hr_lite/attendance_record.rb +21 -4
- data/app/models/hr_lite/comp_off_request.rb +2 -0
- data/app/models/hr_lite/document.rb +1 -1
- data/app/models/hr_lite/expense.rb +3 -0
- data/app/models/hr_lite/hr_request.rb +2 -0
- data/app/models/hr_lite/kudo.rb +2 -2
- data/app/models/hr_lite/leave_request.rb +25 -6
- data/app/models/hr_lite/payroll_line_item.rb +8 -0
- data/app/models/hr_lite/payroll_run.rb +15 -6
- data/app/models/hr_lite/regularization_request.rb +2 -2
- data/app/models/hr_lite/resignation.rb +5 -1
- data/app/models/hr_lite/role.rb +5 -0
- data/app/models/hr_lite/salary_slip.rb +2 -1
- data/app/models/hr_lite/statutory_rate_card_record.rb +6 -0
- data/app/models/hr_lite/tax_declaration.rb +5 -0
- data/app/services/hr_lite/attendance_puncher.rb +4 -0
- data/app/services/hr_lite/overview_query.rb +0 -12
- data/app/services/hr_lite/work_status.rb +5 -2
- data/app/views/hr_lite/admin/assets/index.html.erb +9 -2
- data/app/views/hr_lite/admin/attendances/index.html.erb +4 -4
- data/app/views/hr_lite/admin/attendances/show.html.erb +4 -2
- data/app/views/hr_lite/admin/attendances/summary.html.erb +5 -2
- data/app/views/hr_lite/admin/audit_logs/index.html.erb +6 -4
- data/app/views/hr_lite/admin/benefits/index.html.erb +10 -4
- data/app/views/hr_lite/admin/ca_reviews/index.html.erb +3 -3
- data/app/views/hr_lite/admin/checklists/index.html.erb +3 -3
- data/app/views/hr_lite/admin/comp_off_requests/index.html.erb +1 -2
- data/app/views/hr_lite/admin/comp_off_requests/show.html.erb +6 -6
- data/app/views/hr_lite/admin/designation_changes/new.html.erb +4 -3
- data/app/views/hr_lite/admin/documents/index.html.erb +9 -4
- data/app/views/hr_lite/admin/documents/show.html.erb +1 -0
- data/app/views/hr_lite/admin/employees/_form.html.erb +12 -5
- data/app/views/hr_lite/admin/employees/show.html.erb +40 -33
- data/app/views/hr_lite/admin/expense_categories/index.html.erb +1 -1
- data/app/views/hr_lite/admin/expenses/index.html.erb +7 -4
- data/app/views/hr_lite/admin/holidays/index.html.erb +7 -5
- data/app/views/hr_lite/admin/hr_requests/index.html.erb +3 -3
- data/app/views/hr_lite/admin/hr_requests/show.html.erb +5 -4
- data/app/views/hr_lite/admin/leave_balances/index.html.erb +6 -4
- data/app/views/hr_lite/admin/leave_requests/index.html.erb +1 -2
- data/app/views/hr_lite/admin/leave_requests/show.html.erb +6 -4
- data/app/views/hr_lite/admin/leave_types/edit.html.erb +4 -4
- data/app/views/hr_lite/admin/leave_types/index.html.erb +5 -5
- data/app/views/hr_lite/admin/loans/index.html.erb +1 -1
- data/app/views/hr_lite/admin/loans/new.html.erb +1 -1
- data/app/views/hr_lite/admin/loans/show.html.erb +8 -12
- data/app/views/hr_lite/admin/office_locations/edit.html.erb +4 -4
- data/app/views/hr_lite/admin/office_locations/index.html.erb +1 -1
- data/app/views/hr_lite/admin/overview/index.html.erb +10 -31
- data/app/views/hr_lite/admin/payroll_line_items/new.html.erb +2 -1
- data/app/views/hr_lite/admin/payroll_runs/index.html.erb +3 -3
- data/app/views/hr_lite/admin/payroll_runs/show.html.erb +15 -10
- data/app/views/hr_lite/admin/performance_plans/_form.html.erb +2 -1
- data/app/views/hr_lite/admin/policies/index.html.erb +2 -2
- data/app/views/hr_lite/admin/policies/new.html.erb +4 -3
- data/app/views/hr_lite/admin/regularization_requests/index.html.erb +3 -4
- data/app/views/hr_lite/admin/regularization_requests/show.html.erb +5 -6
- data/app/views/hr_lite/admin/reports/index.html.erb +3 -6
- data/app/views/hr_lite/admin/reports/show.html.erb +16 -2
- data/app/views/hr_lite/admin/roles/_form.html.erb +8 -6
- data/app/views/hr_lite/admin/roles/edit.html.erb +4 -2
- data/app/views/hr_lite/admin/roles/index.html.erb +1 -1
- data/app/views/hr_lite/admin/salary_slips/show.html.erb +3 -2
- data/app/views/hr_lite/admin/salary_structures/_form.html.erb +1 -0
- data/app/views/hr_lite/admin/settings/edit.html.erb +5 -1
- data/app/views/hr_lite/admin/statutory_rate_cards/_form.html.erb +14 -10
- data/app/views/hr_lite/admin/statutory_rate_cards/index.html.erb +3 -1
- data/app/views/hr_lite/admin/tax_declarations/index.html.erb +1 -1
- data/app/views/hr_lite/admin/tax_declarations/show.html.erb +8 -4
- data/app/views/hr_lite/admin/wfh_requests/index.html.erb +17 -16
- data/app/views/hr_lite/admin/wfh_requests/show.html.erb +3 -5
- data/app/views/hr_lite/admin/work_locations/index.html.erb +1 -1
- data/app/views/hr_lite/admin/work_modes/index.html.erb +1 -1
- data/app/views/hr_lite/approvals/index.html.erb +5 -4
- data/app/views/hr_lite/attendance/_custom_status.html.erb +7 -9
- data/app/views/hr_lite/attendance/_month_grid.html.erb +9 -9
- data/app/views/hr_lite/attendance/_penalties.html.erb +2 -2
- data/app/views/hr_lite/attendance/_punch_card.html.erb +10 -4
- data/app/views/hr_lite/attendance/_slot.html.erb +9 -6
- data/app/views/hr_lite/attendance/_trail.html.erb +1 -1
- data/app/views/hr_lite/attendance/_work_mode.html.erb +1 -1
- data/app/views/hr_lite/attendance/show.html.erb +7 -5
- data/app/views/hr_lite/calendar/show.html.erb +2 -2
- data/app/views/hr_lite/comp_off_requests/index.html.erb +1 -1
- data/app/views/hr_lite/comp_off_requests/new.html.erb +1 -1
- data/app/views/hr_lite/documents/_upload_form.html.erb +1 -1
- data/app/views/hr_lite/employee_profiles/show.html.erb +4 -2
- data/app/views/hr_lite/home/index.html.erb +6 -5
- data/app/views/hr_lite/id_cards/show.html.erb +5 -1
- data/app/views/hr_lite/leave_requests/_balance_chips.html.erb +3 -2
- data/app/views/hr_lite/leave_requests/new.html.erb +17 -8
- data/app/views/hr_lite/leave_requests/show.html.erb +2 -0
- data/app/views/hr_lite/loans/index.html.erb +1 -1
- data/app/views/hr_lite/org/show.html.erb +1 -1
- data/app/views/hr_lite/regularization_requests/index.html.erb +7 -7
- data/app/views/hr_lite/regularization_requests/new.html.erb +7 -5
- data/app/views/hr_lite/resignations/show.html.erb +2 -1
- data/app/views/hr_lite/salary_slips/_slip_detail.html.erb +7 -7
- data/app/views/hr_lite/salary_slips/pdf.html.erb +2 -1
- data/app/views/hr_lite/tax/_computation.html.erb +1 -1
- data/app/views/hr_lite/tax_declarations/show.html.erb +4 -4
- data/app/views/hr_lite/team/show.html.erb +8 -7
- data/app/views/hr_lite/timelines/show.html.erb +1 -0
- data/app/views/hr_lite/wfh_requests/index.html.erb +3 -3
- data/app/views/hr_lite/work_time/_bars.html.erb +5 -4
- data/app/views/hr_lite/work_time/_donut.html.erb +1 -1
- data/app/views/hr_lite/work_time/_report.html.erb +14 -8
- data/app/views/layouts/hr_lite/application.html.erb +1 -0
- data/app/views/layouts/hr_lite/mailer.html.erb +10 -2
- data/app/views/layouts/hr_lite/mailer.text.erb +4 -1
- data/config/routes.rb +1 -1
- data/lib/hr_lite/amount_in_words.rb +7 -5
- data/lib/hr_lite/notifications.rb +5 -2
- data/lib/hr_lite/statutory_seeds.rb +1 -1
- data/lib/hr_lite/version.rb +1 -1
- metadata +2 -1
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
<div class="hrl-page__head">
|
|
3
3
|
<h1 class="hrl-page__title">Payroll — <%= @run.label %></h1>
|
|
4
4
|
<div class="hrl-page__actions">
|
|
5
|
-
|
|
5
|
+
<% if hr_can?("payroll.manage", scope: :all) %><a class="hrl-btn" href="<%= hr_lite.admin_payroll_line_items_path(month: @run.period_month.strftime("%Y-%m")) %>">One-off items</a><% end %>
|
|
6
6
|
<a class="hrl-btn" href="<%= hr_lite.admin_payroll_runs_path %>">All runs</a>
|
|
7
7
|
</div>
|
|
8
8
|
</div>
|
|
9
9
|
|
|
10
|
-
<div class="hrl-kpis">
|
|
10
|
+
<div class="hrl-kpis hrl-kpis--money">
|
|
11
11
|
<div class="hrl-kpi"><div class="hrl-kpi__value"><%= @slips.size %></div><div class="hrl-kpi__label">Slips</div></div>
|
|
12
12
|
<div class="hrl-kpi"><div class="hrl-kpi__value"><%= hrl_money(@run.total_gross) %></div><div class="hrl-kpi__label">Gross</div></div>
|
|
13
13
|
<div class="hrl-kpi"><div class="hrl-kpi__value"><%= hrl_money(@run.total_net) %></div><div class="hrl-kpi__label">Net payout</div></div>
|
|
14
|
-
<div class="hrl-kpi"><div class="hrl-kpi__value"><%= hrl_money(@run.total_employer_cost) %></div><div class="hrl-kpi__label">Employer
|
|
14
|
+
<div class="hrl-kpi"><div class="hrl-kpi__value"><%= hrl_money(@run.total_employer_cost) %></div><div class="hrl-kpi__label">Employer contributions</div></div>
|
|
15
15
|
</div>
|
|
16
16
|
|
|
17
17
|
<% if @run.warnings.any? %>
|
|
@@ -29,12 +29,14 @@
|
|
|
29
29
|
<% manager = hr_can?("payroll.manage", scope: :all) %>
|
|
30
30
|
<% if manager && (@run.draft? || @run.review? || @run.processing?) %>
|
|
31
31
|
<%= button_to @run.draft? ? "Compute" : "Recompute", hr_lite.compute_admin_payroll_run_path(@run),
|
|
32
|
-
method: :post, class: "hrl-btn"
|
|
32
|
+
method: :post, class: @run.draft? ? "hrl-btn hrl-btn--primary" : "hrl-btn",
|
|
33
|
+
form: { data: { turbo_confirm: ("Recompute #{@run.label}? This clears #{hr_display_name(@run.first_approved_by)}'s approval." if @run.first_approved_by) } } %>
|
|
33
34
|
<% end %>
|
|
34
35
|
<% if @run.review? && hr_can?("payroll.approve", scope: :all) && @run.first_approved_by_id != hr_current_user.id %>
|
|
35
36
|
<%= button_to @run.first_approved_by_id ? "Approve and publish" : "Approve", hr_lite.approve_admin_payroll_run_path(@run),
|
|
36
37
|
method: :post, class: "hrl-btn hrl-btn--primary",
|
|
37
|
-
form: { data: { turbo_confirm: @run.first_approved_by_id ? "Approve #{@run.label}? This finalizes the run and publishes the slips." : "Approve #{@run.label}?"
|
|
38
|
+
form: { data: { turbo_confirm: [ @run.first_approved_by_id ? "Approve #{@run.label}? This finalizes the run and publishes the slips." : "Approve #{@run.label}?",
|
|
39
|
+
*("Blocking warnings: #{@run.blocking_warnings.join('; ')}" if @run.blocking_warnings.any?) ].join("\n\n") } } %>
|
|
38
40
|
<% end %>
|
|
39
41
|
<% if manager && @run.finalized? %>
|
|
40
42
|
<%= button_to "Unlock", hr_lite.unlock_admin_payroll_run_path(@run), method: :post, class: "hrl-btn" %>
|
|
@@ -54,6 +56,9 @@
|
|
|
54
56
|
<p class="hrl-small hrl-muted hrl-mt">
|
|
55
57
|
<% if @run.review? %>
|
|
56
58
|
<%= @run.first_approved_by ? "Approved by #{hr_display_name(@run.first_approved_by)} on #{@run.first_approved_at.strftime('%-d %b')} — one more approver (HR or Super Admin) publishes it." : "Needs two approvals (HR and Super Admin). If nobody approves by the 3rd, a run with no blocking warnings is approved automatically." %>
|
|
59
|
+
<% elsif @run.processing? %>
|
|
60
|
+
<% content_for(:head) { tag.meta("http-equiv": "refresh", content: "3") } %>
|
|
61
|
+
Computing… this page refreshes until the slips are ready.
|
|
57
62
|
<% elsif @run.auto_approved_at %>
|
|
58
63
|
Approved automatically on <%= @run.auto_approved_at.strftime("%-d %b") %> — nobody had approved it by the 3rd.
|
|
59
64
|
<% end %>
|
|
@@ -64,20 +69,20 @@
|
|
|
64
69
|
<% if @slips.any? %>
|
|
65
70
|
<div class="hrl-table-wrap">
|
|
66
71
|
<table class="hrl-table hrl-table--stack">
|
|
67
|
-
<thead><tr><th>Employee</th><th>
|
|
72
|
+
<thead><tr><th>Employee</th><th>Paid days</th><th><abbr title="Loss of pay: unpaid days">LOP</abbr></th><th>Gross</th><th>Deductions</th><th>Net</th><th></th></tr></thead>
|
|
68
73
|
<tbody>
|
|
69
74
|
<% @slips.each do |slip| %>
|
|
70
75
|
<tr>
|
|
71
76
|
<td data-label="Employee"><%= hr_display_name(slip.user) %></td>
|
|
72
|
-
<td data-label="
|
|
73
|
-
<td data-label="LOP" class="hrl-num">
|
|
74
|
-
<%= slip.effective_lop_days %>
|
|
77
|
+
<td data-label="Paid days" class="hrl-num"><%= hrl_days(slip.payable_days) %></td>
|
|
78
|
+
<td data-label="Unpaid (LOP)" class="hrl-num">
|
|
79
|
+
<%= hrl_days(slip.effective_lop_days) %>
|
|
75
80
|
<% if slip.lop_override %><span class="hrl-badge hrl-badge--warn">override</span><% end %>
|
|
76
81
|
</td>
|
|
77
82
|
<td data-label="Gross" class="hrl-num"><%= hrl_money(slip.gross_earnings) %></td>
|
|
78
83
|
<td data-label="Deductions" class="hrl-num"><%= hrl_money(slip.total_deductions) %></td>
|
|
79
84
|
<td data-label="Net" class="hrl-num"><strong><%= hrl_money(slip.net_pay) %></strong></td>
|
|
80
|
-
<td data-label=""><a class="hrl-
|
|
85
|
+
<td data-label=""><a class="hrl-btn" href="<%= hr_lite.admin_salary_slip_path(slip) %>">Detail</a></td>
|
|
81
86
|
</tr>
|
|
82
87
|
<% end %>
|
|
83
88
|
</tbody>
|
|
@@ -22,7 +22,8 @@
|
|
|
22
22
|
<div class="hrl-field"><%= f.label :outcome_note, "Outcome note" %><%= f.text_area :outcome_note, rows: 3 %></div>
|
|
23
23
|
<% end %>
|
|
24
24
|
<div class="hrl-form-actions">
|
|
25
|
-
<%= f.submit plan.persisted? ? "Save" : "Start PIP", class: "hrl-btn hrl-btn--primary"
|
|
25
|
+
<%= f.submit plan.persisted? ? "Save" : "Start PIP", class: "hrl-btn hrl-btn--primary",
|
|
26
|
+
data: { turbo_confirm: ("Save? Passed or failed closes the plan for good and tells the employee." if plan.persisted?) } %>
|
|
26
27
|
<a class="hrl-btn" href="<%= hr_lite.admin_performance_plans_path %>">Cancel</a>
|
|
27
28
|
</div>
|
|
28
29
|
<% end %>
|
|
@@ -14,10 +14,10 @@
|
|
|
14
14
|
<tbody>
|
|
15
15
|
<% @policies.each do |policy| %>
|
|
16
16
|
<tr>
|
|
17
|
-
<td data-label="Title"><%= policy.title
|
|
17
|
+
<td data-label="Title"><a class="hrl-card__link" href="<%= hr_lite.policy_path(policy) %>"><%= policy.title %></a> <span class="hrl-badge hrl-badge--muted">v<%= policy.version %></span></td>
|
|
18
18
|
<td data-label="Kind"><%= policy.announcement? ? "Announcement" : "Policy" %></td>
|
|
19
19
|
<td data-label="In force"><%= policy.effective_from.strftime("%d %b %Y") %></td>
|
|
20
|
-
<td data-label="Still to acknowledge"
|
|
20
|
+
<td data-label="Still to acknowledge"><% if policy.announcement? %>—<% else %><% waiting = policy.outstanding_for.to_a %><details><summary class="hrl-btn"><%= pluralize(waiting.size, "person") %></summary><%= waiting.map { |u| hr_display_name(u) }.to_sentence %></details><% end %></td>
|
|
21
21
|
</tr>
|
|
22
22
|
<% end %>
|
|
23
23
|
</tbody>
|
|
@@ -8,14 +8,15 @@
|
|
|
8
8
|
<%= form_with model: @policy, url: hr_lite.admin_policies_path, method: :post, local: true do |f| %>
|
|
9
9
|
<%= render "hr_lite/shared/form_errors", record: @policy %>
|
|
10
10
|
<div class="hrl-field"><%= f.label :title %><%= f.text_field :title, required: true %></div>
|
|
11
|
-
<div class="hrl-field"><%= f.label :body, "Text" %><%= f.text_area :body, rows: 10, required: true %></div>
|
|
12
|
-
<div class="hrl-field"><%= f.label :effective_from, "In force from" %><%= f.date_field :effective_from %></div>
|
|
13
11
|
<div class="hrl-field hrl-field--check">
|
|
14
12
|
<%= f.check_box :acknowledgement_required %>
|
|
15
13
|
<%= f.label :acknowledgement_required, "Policy — everyone must acknowledge it (untick for an announcement)" %>
|
|
16
14
|
</div>
|
|
15
|
+
<div class="hrl-field"><%= f.label :body, "Text" %><%= f.text_area :body, rows: 10, required: true %></div>
|
|
16
|
+
<div class="hrl-field"><%= f.label :effective_from, "In force from" %><%= f.date_field :effective_from %></div>
|
|
17
17
|
<div class="hrl-form-actions">
|
|
18
|
-
<%= f.submit "Publish", class: "hrl-btn hrl-btn--primary"
|
|
18
|
+
<%= f.submit "Publish", class: "hrl-btn hrl-btn--primary",
|
|
19
|
+
data: { turbo_confirm: "Publish and notify #{pluralize(HrLite.active_employees.size, 'person')} by email?" } %>
|
|
19
20
|
<a class="hrl-btn" href="<%= hr_lite.admin_policies_path %>">Cancel</a>
|
|
20
21
|
</div>
|
|
21
22
|
<% end %>
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
<% content_for(:page_title) { "
|
|
1
|
+
<% content_for(:page_title) { "Day fixes" } %>
|
|
2
2
|
<div class="hrl-page__head">
|
|
3
|
-
<h1 class="hrl-page__title">
|
|
3
|
+
<h1 class="hrl-page__title">Day fixes</h1>
|
|
4
4
|
</div>
|
|
5
5
|
|
|
6
6
|
<div class="hrl-row hrl-row--mb">
|
|
7
7
|
<span class="hrl-small hrl-muted">Status</span>
|
|
8
8
|
<% HrLite::RegularizationRequest::STATUSES.each do |status| %>
|
|
9
|
-
|
|
10
|
-
href="<%= hr_lite.admin_regularization_requests_path(status: status) %>"><%= status.humanize %></a>
|
|
9
|
+
<%= link_to status.humanize, hr_lite.admin_regularization_requests_path(status: status), class: "hrl-btn", aria: { current: ("true" if @status == status) } %>
|
|
11
10
|
<% end %>
|
|
12
11
|
</div>
|
|
13
12
|
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
<% content_for(:page_title) { "Ticket — #{hr_display_name(@request.user)}" } %>
|
|
2
|
+
<a class="hrl-backlink" href="<%= hr_lite.admin_regularization_requests_path %>"><span aria-hidden="true">‹</span> Approvals</a>
|
|
2
3
|
<div class="hrl-page__head">
|
|
3
4
|
<h1 class="hrl-page__title">Regularization — <%= hr_display_name(@request.user) %></h1>
|
|
4
|
-
<div class="hrl-page__actions">
|
|
5
|
-
<a class="hrl-btn" href="<%= hr_lite.admin_regularization_requests_path %>">All tickets</a>
|
|
6
|
-
<a class="hrl-btn" href="<%= hr_lite.admin_attendance_path(@request.user_id, month: @request.date.strftime("%Y-%m")) %>">Their month</a>
|
|
7
|
-
</div>
|
|
8
5
|
</div>
|
|
9
6
|
|
|
10
7
|
<section class="hrl-card">
|
|
@@ -28,6 +25,7 @@
|
|
|
28
25
|
<% if @request.decision_note.present? %> · <%= @request.decision_note %><% end %></dd>
|
|
29
26
|
<% end %>
|
|
30
27
|
</dl>
|
|
28
|
+
<a class="hrl-card__link" href="<%= hr_lite.admin_attendance_path(@request.user_id, month: @request.date.strftime("%Y-%m")) %>">Their month</a>
|
|
31
29
|
</section>
|
|
32
30
|
|
|
33
31
|
<% if @request.pending? %>
|
|
@@ -38,7 +36,8 @@
|
|
|
38
36
|
<%# Approve and reject are two separate forms on purpose. Rails binds the
|
|
39
37
|
CSRF token to the form's OWN action, so one form retargeted with
|
|
40
38
|
`formaction:` can never pass verification on the second endpoint. %>
|
|
41
|
-
<%= form_with url: hr_lite.approve_admin_regularization_request_path(@request), method: :post, local: true
|
|
39
|
+
<%= form_with url: hr_lite.approve_admin_regularization_request_path(@request), method: :post, local: true,
|
|
40
|
+
html: { data: { turbo_confirm: "Write the proposed times onto #{hr_display_name(@request.user)}'s attendance for #{@request.date.strftime('%d %b %Y')}?" } } do |f| %>
|
|
42
41
|
<div class="hrl-field">
|
|
43
42
|
<%= f.label :decision_note, "Note (optional)", for: "approve_note" %>
|
|
44
43
|
<%= f.text_area :decision_note, id: "approve_note" %>
|
|
@@ -54,7 +53,7 @@
|
|
|
54
53
|
<%= form_with url: hr_lite.reject_admin_regularization_request_path(@request), method: :post, local: true do |f| %>
|
|
55
54
|
<div class="hrl-field">
|
|
56
55
|
<%= f.label :decision_note, "Reason (required)", for: "reject_note" %>
|
|
57
|
-
<%= f.text_area :decision_note, id: "reject_note" %>
|
|
56
|
+
<%= f.text_area :decision_note, id: "reject_note", required: true %>
|
|
58
57
|
</div>
|
|
59
58
|
<div class="hrl-form-actions">
|
|
60
59
|
<%= f.button "Reject", type: :submit, class: "hrl-btn hrl-btn--danger" %>
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
<%= form_with url: hr_lite.admin_reports_path, method: :get, local: true do %>
|
|
10
10
|
<div class="hrl-field">
|
|
11
11
|
<%= label_tag :month, "Month" %>
|
|
12
|
-
<%=
|
|
12
|
+
<%= month_field_tag :month, @month.strftime("%Y-%m"), max: Date.current.strftime("%Y-%m"), class: "hrl-input" %>
|
|
13
13
|
</div>
|
|
14
14
|
<div class="hrl-form-actions">
|
|
15
15
|
<%= submit_tag "Change month", class: "hrl-btn" %>
|
|
@@ -26,11 +26,8 @@
|
|
|
26
26
|
<tr>
|
|
27
27
|
<td data-label="Report"><%= label %></td>
|
|
28
28
|
<td data-label="">
|
|
29
|
-
<a class="hrl-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
<a class="hrl-small"
|
|
33
|
-
href="<%= hr_lite.admin_report_path(name, month: @month.strftime("%Y-%m"), format: :csv) %>">CSV</a>
|
|
29
|
+
<a class="hrl-btn" href="<%= hr_lite.admin_report_path(name, month: @month.strftime("%Y-%m")) %>">Open</a>
|
|
30
|
+
<a class="hrl-btn" href="<%= hr_lite.admin_report_path(name, month: @month.strftime("%Y-%m"), format: :csv) %>">CSV</a>
|
|
34
31
|
</td>
|
|
35
32
|
</tr>
|
|
36
33
|
<% end %>
|
|
@@ -1,7 +1,21 @@
|
|
|
1
1
|
<% content_for(:page_title) { @reports_title = HrLite::Admin::ReportsController::REPORTS[@name] } %>
|
|
2
|
+
<% content_for(:back) { "Reports" } %>
|
|
3
|
+
<%# The screen reads like the rest of the app; the CSV keeps raw values for spreadsheets. %>
|
|
4
|
+
<% heading = ->(h) { h == "LOP" ? "Unpaid days (LOP)" : h }
|
|
5
|
+
shown = lambda do |header, value|
|
|
6
|
+
if value.blank? then "—"
|
|
7
|
+
elsif header == "Amount" then hrl_money(value)
|
|
8
|
+
elsif header.in?([ "Joined", "Left", "Spent on" ]) then Date.parse(value.to_s).strftime("%d %b %Y")
|
|
9
|
+
elsif header == "Status" then value.to_s.humanize
|
|
10
|
+
elsif value.is_a?(Float) then hrl_days(value)
|
|
11
|
+
else value
|
|
12
|
+
end
|
|
13
|
+
end %>
|
|
2
14
|
<div class="hrl-page__head">
|
|
3
15
|
<h1 class="hrl-page__title"><%= HrLite::Admin::ReportsController::REPORTS[@name] %></h1>
|
|
4
16
|
<div class="hrl-page__actions">
|
|
17
|
+
<a class="hrl-btn" href="<%= hr_lite.admin_report_path(@name, month: @month.prev_month.strftime("%Y-%m")) %>">‹ <%= @month.prev_month.strftime("%b %Y") %></a>
|
|
18
|
+
<% if @month.next_month <= Date.current %><a class="hrl-btn" href="<%= hr_lite.admin_report_path(@name, month: @month.next_month.strftime("%Y-%m")) %>"><%= @month.next_month.strftime("%b %Y") %> ›</a><% end %>
|
|
5
19
|
<a class="hrl-btn"
|
|
6
20
|
href="<%= hr_lite.admin_report_path(@name, month: @month.strftime("%Y-%m"), format: :csv) %>">Download CSV</a>
|
|
7
21
|
</div>
|
|
@@ -15,13 +29,13 @@
|
|
|
15
29
|
<div class="hrl-table-wrap">
|
|
16
30
|
<table class="hrl-table hrl-table--stack">
|
|
17
31
|
<thead>
|
|
18
|
-
<tr><% @rows.first.keys.each do |header| %><th><%= header %></th><% end %></tr>
|
|
32
|
+
<tr><% @rows.first.keys.each do |header| %><th><%= heading.(header) %></th><% end %></tr>
|
|
19
33
|
</thead>
|
|
20
34
|
<tbody>
|
|
21
35
|
<% @rows.each do |row| %>
|
|
22
36
|
<tr>
|
|
23
37
|
<% row.each do |header, value| %>
|
|
24
|
-
<td data-label="<%= header %>"><%= value %></td>
|
|
38
|
+
<td data-label="<%= heading.(header) %>"><%= shown.(header, value) %></td>
|
|
25
39
|
<% end %>
|
|
26
40
|
</tr>
|
|
27
41
|
<% end %>
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
<% if role.system? %>
|
|
8
8
|
<%= f.text_field :name, disabled: true %>
|
|
9
9
|
<span class="hrl-small hrl-muted">
|
|
10
|
-
Built-in roles keep their name
|
|
11
|
-
|
|
10
|
+
Built-in roles keep their name, because the system finds them by it.
|
|
11
|
+
The permissions below are yours to change.
|
|
12
12
|
</span>
|
|
13
13
|
<% else %>
|
|
14
14
|
<%= f.text_field :name %>
|
|
@@ -20,8 +20,9 @@
|
|
|
20
20
|
</div>
|
|
21
21
|
|
|
22
22
|
<% HrLite::Permissions.grouped.each do |group, keys| %>
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
<% granted = keys.count { |k| (role.grant_map[k] || "none") != "none" } %>
|
|
24
|
+
<details class="hrl-card" <%= "open" if granted.positive? %>>
|
|
25
|
+
<summary class="hrl-btn hrl-btn--block"><%= group %> · <%= granted %> of <%= keys.size %> granted</summary>
|
|
25
26
|
<% keys.each do |key| %>
|
|
26
27
|
<% held = role.grant_map[key] || "none" %>
|
|
27
28
|
<div class="hrl-field">
|
|
@@ -36,11 +37,12 @@
|
|
|
36
37
|
id: "grants_#{key.tr('.', '_')}" %>
|
|
37
38
|
</div>
|
|
38
39
|
<% end %>
|
|
39
|
-
</
|
|
40
|
+
</details>
|
|
40
41
|
<% end %>
|
|
41
42
|
|
|
42
43
|
<div class="hrl-form-actions">
|
|
43
|
-
<%= f.submit "Save", class: "hrl-btn hrl-btn--primary"
|
|
44
|
+
<%= f.submit "Save", class: "hrl-btn hrl-btn--primary",
|
|
45
|
+
data: { turbo_confirm: ("Save? Everyone holding #{role.name} gets these permissions at once." if role.persisted?) } %>
|
|
44
46
|
<a class="hrl-btn" href="<%= hr_lite.admin_roles_path %>">Cancel</a>
|
|
45
47
|
</div>
|
|
46
48
|
<% end %>
|
|
@@ -38,13 +38,15 @@
|
|
|
38
38
|
</div>
|
|
39
39
|
<% end %>
|
|
40
40
|
|
|
41
|
-
<%= form_with url: hr_lite.admin_role_assignments_path(@role), method: :post, local: true
|
|
41
|
+
<%= form_with url: hr_lite.admin_role_assignments_path(@role), method: :post, local: true,
|
|
42
|
+
data: { turbo_confirm: "Give the #{@role.name} role to the person you picked? Their access changes at once." } do %>
|
|
42
43
|
<div class="hrl-field">
|
|
43
44
|
<%= label_tag :user_id, "Add somebody to this role" %>
|
|
44
45
|
<% held = @role.role_assignments.map(&:user_id) %>
|
|
45
46
|
<%= select_tag :user_id,
|
|
46
47
|
options_for_select(HrLite.employees.reject { |u| held.include?(u.id) }
|
|
47
|
-
.map { |u| [ hr_display_name(u), u.id ] })
|
|
48
|
+
.map { |u| [ hr_display_name(u), u.id ] }),
|
|
49
|
+
include_blank: "Choose…", required: true, data: { hrl_filter: "Type a name to filter" } %>
|
|
48
50
|
</div>
|
|
49
51
|
<div class="hrl-form-actions">
|
|
50
52
|
<%= submit_tag "Add", class: "hrl-btn hrl-btn--primary" %>
|
|
@@ -11,8 +11,9 @@
|
|
|
11
11
|
<section class="hrl-card">
|
|
12
12
|
<h2 class="hrl-card__title">Tax working</h2>
|
|
13
13
|
<dl class="hrl-deflist">
|
|
14
|
-
<% @slip.tax_details_hash.each do |key, value| %>
|
|
15
|
-
<dt><%= key.humanize %></dt
|
|
14
|
+
<% @slip.tax_details_hash.except("high_income_review").each do |key, value| %>
|
|
15
|
+
<dt><%= key == "fy_tds_already_deducted" ? "TDS already deducted this year" : key.humanize %></dt>
|
|
16
|
+
<dd><%= key.in?(%w[regime months_remaining]) ? value.to_s.humanize : hrl_money(value) %></dd>
|
|
16
17
|
<% end %>
|
|
17
18
|
</dl>
|
|
18
19
|
<% if @slip.tax_details_hash["high_income_review"] == "true" %>
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
<div class="hrl-field">
|
|
6
6
|
<%= f.label :annual_ctc, "Annual CTC (₹ a year)" %>
|
|
7
7
|
<%= f.number_field :annual_ctc, step: 1, min: 1, required: true, value: (structure.annual_ctc || breakup&.dig(:annual_ctc))&.round %>
|
|
8
|
+
<% if structure.annual_ctc %><p class="hrl-hint">= <%= hrl_money(structure.annual_ctc) %> a year</p><% end %>
|
|
8
9
|
<p class="hrl-hint">The only amount you type. Saving splits it: Basic 50%, HRA 50% of Basic in a metro (40% elsewhere), employer PF, ESI and gratuity (4.81% of Basic) inside the CTC, the rest as special allowance.</p>
|
|
9
10
|
</div>
|
|
10
11
|
<div class="hrl-field">
|
|
@@ -6,11 +6,13 @@
|
|
|
6
6
|
<section class="hrl-card">
|
|
7
7
|
<%= form_with model: @setting, url: hr_lite.admin_setting_path, method: :patch, local: true do |f| %>
|
|
8
8
|
<%= render "hr_lite/shared/form_errors", record: @setting %>
|
|
9
|
+
<h2 class="hrl-card__title">Working week</h2>
|
|
9
10
|
<div class="hrl-field">
|
|
10
11
|
<%= f.label :weekend_policy, "Weekly off policy" %>
|
|
11
|
-
<%= f.select :weekend_policy,
|
|
12
|
+
<%= f.select :weekend_policy, { "Sunday only" => "sun_only", "Saturday and Sunday" => "sat_sun", "Sunday, 2nd and 4th Saturday" => "second_fourth_sat_sun" }.select { |_, v| v.in?(HrLite::Setting::WEEKEND_POLICIES) } %>
|
|
12
13
|
<p class="hrl-hint">Drives working-day math everywhere: leave counting, attendance, payroll.</p>
|
|
13
14
|
</div>
|
|
15
|
+
<h2 class="hrl-card__title hrl-mt">Breaks</h2>
|
|
14
16
|
<div class="hrl-field">
|
|
15
17
|
<%= f.label :lunch_break_minutes, "Lunch break limit (minutes)" %>
|
|
16
18
|
<%= f.number_field :lunch_break_minutes, min: 5, max: 120 %>
|
|
@@ -20,6 +22,7 @@
|
|
|
20
22
|
<%= f.label :short_break_minutes, "Short break limit (minutes)" %>
|
|
21
23
|
<%= f.number_field :short_break_minutes, min: 1, max: 60 %>
|
|
22
24
|
</div>
|
|
25
|
+
<h2 class="hrl-card__title hrl-mt">Working day</h2>
|
|
23
26
|
<div class="hrl-field">
|
|
24
27
|
<%= f.label :day_minutes, "Working day (minutes, break included)" %>
|
|
25
28
|
<%= f.number_field :day_minutes, min: 240, max: 720, step: 15 %>
|
|
@@ -39,6 +42,7 @@
|
|
|
39
42
|
<%= f.time_field :recheck_in_until %>
|
|
40
43
|
<p class="hrl-hint">After checking out, a person can check in again once a day inside these hours.</p>
|
|
41
44
|
</div>
|
|
45
|
+
<h2 class="hrl-card__title hrl-mt">Penalties and codes</h2>
|
|
42
46
|
<div class="hrl-field">
|
|
43
47
|
<%= f.label :penalty_leave_type_id, "Penalties come off" %>
|
|
44
48
|
<%= f.collection_select :penalty_leave_type_id, HrLite::LeaveType.active, :id, :name, { include_blank: "No leave (penalties stay as time)" }, data: { hrl_filter: "Type a leave type to filter" } %>
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
|
|
19
19
|
<fieldset>
|
|
20
20
|
<legend>Provident fund</legend>
|
|
21
|
-
<% { employee_rate: "Employee rate (0.12 = 12%)", employer_rate: "Employer rate",
|
|
22
|
-
eps_rate: "EPS rate", wage_ceiling: "PF wage ceiling (₹)",
|
|
21
|
+
<% { employee_rate: "Employee rate (0.12 = 12%)", employer_rate: "Employer rate (0.12 = 12%)",
|
|
22
|
+
eps_rate: "EPS rate (0.0833 = 8.33%)", wage_ceiling: "PF wage ceiling (₹)",
|
|
23
23
|
eps_wage_ceiling: "EPS wage ceiling (₹)", edli_rate: "EDLI rate",
|
|
24
24
|
edli_ceiling: "EDLI ceiling (₹)", admin_rate: "PF admin rate" }.each do |key, label| %>
|
|
25
25
|
<div class="hrl-field">
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
|
|
33
33
|
<fieldset>
|
|
34
34
|
<legend>ESI</legend>
|
|
35
|
-
<% { employee_rate: "Employee rate", employer_rate: "Employer rate",
|
|
35
|
+
<% { employee_rate: "Employee rate (0.0075 = 0.75%)", employer_rate: "Employer rate (0.0325 = 3.25%)",
|
|
36
36
|
gross_ceiling: "Gross ceiling (₹)" }.each do |key, label| %>
|
|
37
37
|
<div class="hrl-field">
|
|
38
38
|
<%= label_tag "statutory_rate_card_esi_#{key}", label %>
|
|
@@ -68,16 +68,20 @@
|
|
|
68
68
|
the open-ended top rate.
|
|
69
69
|
</p>
|
|
70
70
|
<% slabs = Array(table["slabs"]) %>
|
|
71
|
-
<% (
|
|
72
|
-
|
|
71
|
+
<% num = ->(v) { v && number_with_precision(v, precision: 4, strip_insignificant_zeros: true) } %>
|
|
72
|
+
<div class="hrl-slabs">
|
|
73
|
+
<span class="hrl-small" aria-hidden="true">From ₹</span>
|
|
74
|
+
<span class="hrl-small" aria-hidden="true">Up to ₹</span>
|
|
75
|
+
<span class="hrl-small" aria-hidden="true">Rate (0.05 = 5%)</span>
|
|
76
|
+
<% (slabs + [ nil, nil ]).each_with_index do |row, index| %>
|
|
73
77
|
<%= text_field_tag "statutory_rate_card[income_tax][#{regime}][slabs][#{index}][from]",
|
|
74
|
-
row&.first,
|
|
78
|
+
num.(row&.first), class: "hrl-input", inputmode: "decimal", "aria-label": "Band #{index + 1} from ₹" %>
|
|
75
79
|
<%= text_field_tag "statutory_rate_card[income_tax][#{regime}][slabs][#{index}][to]",
|
|
76
|
-
row&.at(1),
|
|
80
|
+
num.(row&.at(1)), class: "hrl-input", inputmode: "decimal", "aria-label": "Band #{index + 1} up to ₹ (blank = top)" %>
|
|
77
81
|
<%= text_field_tag "statutory_rate_card[income_tax][#{regime}][slabs][#{index}][rate]",
|
|
78
|
-
row&.last,
|
|
79
|
-
|
|
80
|
-
|
|
82
|
+
num.(row&.last), class: "hrl-input", inputmode: "decimal", "aria-label": "Band #{index + 1} rate" %>
|
|
83
|
+
<% end %>
|
|
84
|
+
</div>
|
|
81
85
|
</fieldset>
|
|
82
86
|
<% end %>
|
|
83
87
|
|
|
@@ -16,10 +16,12 @@
|
|
|
16
16
|
<table class="hrl-table hrl-table--stack">
|
|
17
17
|
<thead><tr><th>Year</th><th>PF ceiling</th><th>ESI ceiling</th><th>Verified</th><th></th></tr></thead>
|
|
18
18
|
<tbody>
|
|
19
|
+
<% live = HrLite::StatutoryRateCardRecord.effective_for(Date.current.beginning_of_month) %>
|
|
19
20
|
<% @cards.each do |card| %>
|
|
20
21
|
<tr>
|
|
21
22
|
<td data-label="Year">
|
|
22
23
|
<strong>FY <%= card.financial_year %></strong>
|
|
24
|
+
<% if card == live %><span class="hrl-badge hrl-badge--ok">In force</span><% end %>
|
|
23
25
|
<div class="hrl-small hrl-muted">from <%= card.effective_from.strftime("%d %b %Y") %></div>
|
|
24
26
|
</td>
|
|
25
27
|
<td data-label="PF ceiling" class="hrl-num"><%= HrLite::Money.format(card.to_card[:pf][:wage_ceiling]) %></td>
|
|
@@ -33,7 +35,7 @@
|
|
|
33
35
|
<% end %>
|
|
34
36
|
</td>
|
|
35
37
|
<td data-label="">
|
|
36
|
-
<a class="hrl-
|
|
38
|
+
<a class="hrl-btn" href="<%= hr_lite.edit_admin_statutory_rate_card_path(card) %>">Edit</a>
|
|
37
39
|
</td>
|
|
38
40
|
</tr>
|
|
39
41
|
<% end %>
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
<td data-label="Regime"><%= declaration.regime.humanize %></td>
|
|
27
27
|
<td data-label="Claimed" class="hrl-num"><%= hrl_money(declaration.declared_total) %></td>
|
|
28
28
|
<td data-label="">
|
|
29
|
-
<a class="hrl-
|
|
29
|
+
<a class="hrl-btn" href="<%= hr_lite.admin_tax_declaration_path(declaration) %>">Check</a>
|
|
30
30
|
</td>
|
|
31
31
|
</tr>
|
|
32
32
|
<% end %>
|
|
@@ -48,24 +48,28 @@
|
|
|
48
48
|
<% end %>
|
|
49
49
|
<div class="hrl-form-actions">
|
|
50
50
|
<%= f.submit "Record amounts", class: "hrl-btn" %>
|
|
51
|
+
<%= f.submit "Record and verify", name: "verify", class: "hrl-btn" %>
|
|
51
52
|
</div>
|
|
52
53
|
</section>
|
|
53
54
|
<% end %>
|
|
54
55
|
|
|
56
|
+
<% if @declaration.submitted? %>
|
|
55
57
|
<section class="hrl-card">
|
|
56
58
|
<h2 class="hrl-card__title">Decide</h2>
|
|
57
59
|
<div class="hrl-row">
|
|
60
|
+
<% unproven = @declaration.tax_declaration_items.reject { |item| item.proofs.attached? }.map { |item| item.section_label.split(" — ").first } %>
|
|
58
61
|
<%= button_to "Accept all and verify", hr_lite.accept_all_admin_tax_declaration_path(@declaration),
|
|
59
|
-
method: :post, class: "hrl-btn hrl-btn--primary"
|
|
60
|
-
|
|
61
|
-
|
|
62
|
+
method: :post, class: "hrl-btn hrl-btn--primary",
|
|
63
|
+
form: { data: { turbo_confirm: [ "Accept every claimed amount and verify? The employee can no longer edit it.",
|
|
64
|
+
("No proof attached: #{unproven.to_sentence}." if unproven.any?) ].compact.join(" ") } } %>
|
|
62
65
|
</div>
|
|
63
66
|
<%= form_with url: hr_lite.reject_admin_tax_declaration_path(@declaration),
|
|
64
67
|
method: :post, local: true do %>
|
|
65
68
|
<div class="hrl-field">
|
|
66
69
|
<%= label_tag :note, "What is missing (required to send back)" %>
|
|
67
|
-
<%= text_field_tag :note %>
|
|
70
|
+
<%= text_field_tag :note, nil, class: "hrl-input" %>
|
|
68
71
|
</div>
|
|
69
72
|
<%= submit_tag "Send back", class: "hrl-btn" %>
|
|
70
73
|
<% end %>
|
|
71
74
|
</section>
|
|
75
|
+
<% end %>
|
|
@@ -3,7 +3,22 @@
|
|
|
3
3
|
<h1 class="hrl-page__title">Work from home</h1>
|
|
4
4
|
</div>
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
<% if @grantable.any? %>
|
|
7
|
+
<section class="hrl-card">
|
|
8
|
+
<h2 class="hrl-card__title">Give WFH</h2>
|
|
9
|
+
<p class="hrl-small hrl-muted">Approved straight away, up to <%= HrLite::WfhRequest::HR_MAX_DAYS %> days from today or later.</p>
|
|
10
|
+
<%= form_with url: hr_lite.admin_wfh_requests_path, method: :post, local: true do %>
|
|
11
|
+
<div class="hrl-field"><label for="grant-user">Employee</label><%= select_tag :user_id, options_for_select(@grantable.map { |u| [ hr_display_name(u), u.id ] }), include_blank: "Choose one", required: true, id: "grant-user", data: { hrl_filter: ("Type a name to filter" if @grantable.size > 5) } %></div>
|
|
12
|
+
<div class="hrl-field"><label for="grant-from">From</label><%= date_field_tag :start_date, Date.current, min: Date.current, required: true, id: "grant-from" %></div>
|
|
13
|
+
<div class="hrl-field"><label for="grant-to">To</label><%= date_field_tag :end_date, Date.current, min: Date.current, required: true, id: "grant-to" %></div>
|
|
14
|
+
<div class="hrl-field"><label for="grant-reason">Reason</label><%= text_area_tag :reason, nil, rows: 2, required: true, id: "grant-reason" %></div>
|
|
15
|
+
<div class="hrl-form-actions"><button type="submit" class="hrl-btn hrl-btn--primary">Give WFH</button></div>
|
|
16
|
+
<% end %>
|
|
17
|
+
</section>
|
|
18
|
+
<% end %>
|
|
19
|
+
|
|
20
|
+
<details class="hrl-card"<%= " open" if request.query_string.present? %>>
|
|
21
|
+
<summary class="hrl-btn hrl-btn--block">Filter</summary>
|
|
7
22
|
<%= form_with url: hr_lite.admin_wfh_requests_path, method: :get, local: true do %>
|
|
8
23
|
<div class="hrl-field"><label for="wfh-from">From</label><%= date_field_tag :from, @from, id: "wfh-from" %></div>
|
|
9
24
|
<div class="hrl-field"><label for="wfh-to">To</label><%= date_field_tag :to, @to, id: "wfh-to" %></div>
|
|
@@ -19,7 +34,7 @@
|
|
|
19
34
|
<a class="hrl-btn" href="<%= hr_lite.admin_wfh_requests_path %>">Reset</a>
|
|
20
35
|
</div>
|
|
21
36
|
<% end %>
|
|
22
|
-
</
|
|
37
|
+
</details>
|
|
23
38
|
|
|
24
39
|
<div class="hrl-kpis">
|
|
25
40
|
<div class="hrl-kpi"><div class="hrl-kpi__value"><%= @kpis[:requested] %></div><div class="hrl-kpi__label">Employees requested</div></div>
|
|
@@ -48,20 +63,6 @@
|
|
|
48
63
|
<% end %>
|
|
49
64
|
</section>
|
|
50
65
|
|
|
51
|
-
<% if @grantable.any? %>
|
|
52
|
-
<section class="hrl-card">
|
|
53
|
-
<h2 class="hrl-card__title">Give WFH</h2>
|
|
54
|
-
<p class="hrl-small hrl-muted">Approved straight away, up to <%= HrLite::WfhRequest::HR_MAX_DAYS %> days from today or later.</p>
|
|
55
|
-
<%= form_with url: hr_lite.admin_wfh_requests_path, method: :post, local: true do %>
|
|
56
|
-
<div class="hrl-field"><label for="grant-user">Employee</label><%= select_tag :user_id, options_for_select(@grantable.map { |u| [ hr_display_name(u), u.id ] }), include_blank: "Choose one", required: true, id: "grant-user", data: { hrl_filter: ("Type a name to filter" if @grantable.size > 5) } %></div>
|
|
57
|
-
<div class="hrl-field"><label for="grant-from">From</label><%= date_field_tag :start_date, Date.current, min: Date.current, required: true, id: "grant-from" %></div>
|
|
58
|
-
<div class="hrl-field"><label for="grant-to">To</label><%= date_field_tag :end_date, Date.current, min: Date.current, required: true, id: "grant-to" %></div>
|
|
59
|
-
<div class="hrl-field"><label for="grant-reason">Reason</label><%= text_area_tag :reason, nil, rows: 2, required: true, id: "grant-reason" %></div>
|
|
60
|
-
<div class="hrl-form-actions"><button type="submit" class="hrl-btn hrl-btn--primary">Give WFH</button></div>
|
|
61
|
-
<% end %>
|
|
62
|
-
</section>
|
|
63
|
-
<% end %>
|
|
64
|
-
|
|
65
66
|
<section class="hrl-card">
|
|
66
67
|
<h2 class="hrl-card__title">Schedules <%= @from.strftime("%-d %b") %> – <%= @to.strftime("%-d %b") %></h2>
|
|
67
68
|
<% if @requests.any? %>
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
<% content_for(:page_title) { "WFH — #{hr_display_name(@request.user)}" } %>
|
|
2
|
+
<a class="hrl-backlink" href="<%= hr_lite.admin_wfh_requests_path %>"><span aria-hidden="true">‹</span> Approvals</a>
|
|
2
3
|
<div class="hrl-page__head">
|
|
3
4
|
<h1 class="hrl-page__title">WFH — <%= hr_display_name(@request.user) %></h1>
|
|
4
|
-
<div class="hrl-page__actions">
|
|
5
|
-
<a class="hrl-btn" href="<%= hr_lite.admin_wfh_requests_path %>">All WFH</a>
|
|
6
|
-
<a class="hrl-btn" href="<%= hr_lite.admin_attendance_path(@request.user_id, month: @request.start_date.strftime("%Y-%m")) %>">Their month</a>
|
|
7
|
-
</div>
|
|
8
5
|
</div>
|
|
9
6
|
|
|
10
7
|
<section class="hrl-card">
|
|
@@ -19,6 +16,7 @@
|
|
|
19
16
|
<% if @request.decision_note.present? %> · <%= @request.decision_note %><% end %></dd>
|
|
20
17
|
<% end %>
|
|
21
18
|
</dl>
|
|
19
|
+
<a class="hrl-card__link" href="<%= hr_lite.admin_attendance_path(@request.user_id, month: @request.start_date.strftime("%Y-%m")) %>">Their month</a>
|
|
22
20
|
</section>
|
|
23
21
|
|
|
24
22
|
<% if @request.pending? && @decidable %>
|
|
@@ -33,7 +31,7 @@
|
|
|
33
31
|
<section class="hrl-card">
|
|
34
32
|
<h2 class="hrl-card__title">Reject</h2>
|
|
35
33
|
<%= form_with url: hr_lite.reject_admin_wfh_request_path(@request), method: :post, local: true do |f| %>
|
|
36
|
-
<div class="hrl-field"><%= f.label :decision_note, "Remark (required)", for: "reject_note" %><%= f.text_area :decision_note, id: "reject_note" %></div>
|
|
34
|
+
<div class="hrl-field"><%= f.label :decision_note, "Remark (required)", for: "reject_note" %><%= f.text_area :decision_note, id: "reject_note", required: true %></div>
|
|
37
35
|
<div class="hrl-form-actions"><%= f.button "Reject", type: :submit, class: "hrl-btn hrl-btn--danger" %></div>
|
|
38
36
|
<% end %>
|
|
39
37
|
</section>
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<div class="hrl-row hrl-row--mb">
|
|
7
7
|
<span class="hrl-small hrl-muted">Status</span>
|
|
8
8
|
<% HrLite::WorkLocation::STATUSES.each do |status| %>
|
|
9
|
-
<a class="hrl-btn <%=
|
|
9
|
+
<a class="hrl-btn" <%= "aria-current=true" if @status == status %> href="<%= hr_lite.admin_work_locations_path(status: status) %>"><%= status.humanize %></a>
|
|
10
10
|
<% end %>
|
|
11
11
|
</div>
|
|
12
12
|
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
<details>
|
|
91
91
|
<summary class="hrl-btn">Set their mode</summary>
|
|
92
92
|
<%= form_with url: hr_lite.admin_work_mode_override_path(@person.id), method: :post, local: true do %>
|
|
93
|
-
<div class="hrl-field"><label for="ov-mode">Mode</label><%= select_tag :mode, options_for_select(HrLite::WorkModeSwitch::SELECTABLE.map { |m| [ HrLite::WorkModeEvent.label(m), m ] }), id: "ov-mode" %></div>
|
|
93
|
+
<div class="hrl-field"><label for="ov-mode">Mode</label><%= select_tag :mode, options_for_select(HrLite::WorkModeSwitch::SELECTABLE.map { |m| [ HrLite::WorkModeEvent.label(m), m ] }), id: "ov-mode", data: { hrl_filter: "Type a mode" } %></div>
|
|
94
94
|
<div class="hrl-field"><label for="ov-title">Title / purpose (meeting, travel, client meeting)</label><input class="hrl-input" id="ov-title" name="title" maxlength="120"></div>
|
|
95
95
|
<div class="hrl-field"><label for="ov-client">Client</label><input class="hrl-input" id="ov-client" name="client" maxlength="120"></div>
|
|
96
96
|
<div class="hrl-field"><label for="ov-dest">Destination</label><input class="hrl-input" id="ov-dest" name="destination" maxlength="120"></div>
|