hr_lite 0.54.0 → 0.56.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 +71 -0
- 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/search.js +1 -1
- data/app/assets/stylesheets/hr_lite/hr_lite.css +18 -9
- data/app/controllers/hr_lite/admin/attendances_controller.rb +10 -3
- data/app/controllers/hr_lite/admin/audit_logs_controller.rb +1 -0
- data/app/controllers/hr_lite/admin/employees_controller.rb +11 -4
- data/app/controllers/hr_lite/admin/expenses_controller.rb +6 -2
- data/app/controllers/hr_lite/admin/hr_requests_controller.rb +4 -0
- data/app/controllers/hr_lite/admin/leave_requests_controller.rb +4 -1
- data/app/controllers/hr_lite/admin/payroll_runs_controller.rb +9 -5
- 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/tax_declarations_controller.rb +13 -3
- data/app/controllers/hr_lite/approvals_controller.rb +1 -0
- data/app/controllers/hr_lite/home_controller.rb +2 -2
- 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 +20 -14
- 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 +14 -0
- data/app/models/hr_lite/benefit_enrolment.rb +3 -1
- 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 +13 -5
- 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 +18 -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 +1 -1
- 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/payroll_run_processor.rb +3 -0
- data/app/services/hr_lite/slip_builder.rb +17 -9
- 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/show.html.erb +3 -1
- 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/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 +5 -5
- data/app/views/hr_lite/admin/designation_changes/new.html.erb +4 -3
- data/app/views/hr_lite/admin/documents/index.html.erb +8 -3
- data/app/views/hr_lite/admin/documents/show.html.erb +2 -1
- data/app/views/hr_lite/admin/employees/_form.html.erb +12 -5
- data/app/views/hr_lite/admin/employees/show.html.erb +38 -32
- data/app/views/hr_lite/admin/expenses/index.html.erb +4 -3
- data/app/views/hr_lite/admin/holidays/index.html.erb +5 -4
- data/app/views/hr_lite/admin/hr_requests/index.html.erb +1 -1
- data/app/views/hr_lite/admin/hr_requests/show.html.erb +4 -3
- 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 +5 -3
- data/app/views/hr_lite/admin/leave_types/edit.html.erb +4 -4
- data/app/views/hr_lite/admin/leave_types/index.html.erb +3 -3
- data/app/views/hr_lite/admin/loans/index.html.erb +2 -2
- 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/payroll_runs/index.html.erb +2 -2
- data/app/views/hr_lite/admin/payroll_runs/show.html.erb +10 -7
- data/app/views/hr_lite/admin/policies/index.html.erb +1 -1
- data/app/views/hr_lite/admin/policies/new.html.erb +2 -2
- data/app/views/hr_lite/admin/regularization_requests/index.html.erb +3 -4
- data/app/views/hr_lite/admin/regularization_requests/show.html.erb +4 -5
- 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 +6 -5
- 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 +3 -3
- 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 +2 -0
- data/app/views/hr_lite/admin/wfh_requests/index.html.erb +17 -16
- data/app/views/hr_lite/admin/wfh_requests/show.html.erb +2 -4
- 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 +1 -1
- 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 +2 -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 +4 -4
- 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 +2 -2
- data/app/views/hr_lite/id_cards/show.html.erb +5 -1
- data/app/views/hr_lite/leave_requests/_balance_chips.html.erb +2 -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/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/salary_slips/_slip_detail.html.erb +2 -2
- data/app/views/hr_lite/salary_slips/pdf.html.erb +1 -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 +1 -1
- 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/db/migrate/20261017161441_make_hr_lite_benefit_enrolments_unique_while_open.rb +8 -0
- data/db/migrate/20261017161443_add_attendance_record_id_index_to_hr_lite_work_mode_events.rb +5 -0
- data/lib/hr_lite/notifications.rb +5 -2
- data/lib/hr_lite/version.rb +1 -1
- metadata +4 -1
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
<tr>
|
|
15
15
|
<td data-label="Employee"><%= hr_display_name(employee) %><% if @no_joining_date.include?(employee.id) %><br><span class="hrl-badge hrl-badge--bad">No joining date — no leave accrues</span><% end %></td>
|
|
16
16
|
<% @types.each do |type| %>
|
|
17
|
-
<% balance = HrLite::LeaveBalance.for(employee, type, @year) %>
|
|
18
|
-
<td data-label="<%= type.code %>" class="hrl-num"><span><strong><%= hrl_days(
|
|
17
|
+
<% balance = HrLite::LeaveBalance.for(employee, type, @year); used = balance.used; entitled = balance.entitled # each once: both query %>
|
|
18
|
+
<td data-label="<%= type.code %>" class="hrl-num"><span><strong><%= hrl_days(entitled - used) %></strong> left<br><span class="hrl-small hrl-muted"><%= hrl_days(used) %>/<%= hrl_days(entitled) %> used</span><% if (held = balance.penalty_days).positive? %><br><span class="hrl-small"><%= hrl_days(held) %> held for penalties</span><% end %></span></td>
|
|
19
19
|
<% end %>
|
|
20
20
|
</tr>
|
|
21
21
|
<% end %>
|
|
@@ -28,10 +28,12 @@
|
|
|
28
28
|
<section class="hrl-card">
|
|
29
29
|
<h2 class="hrl-card__title">Adjust a balance</h2>
|
|
30
30
|
<p class="hrl-small hrl-muted">Positive credits (comp-off), negative debits. Fully audited.</p>
|
|
31
|
-
<%= form_with url: hr_lite.adjust_admin_leave_balances_path, method: :post, local: true
|
|
31
|
+
<%= form_with url: hr_lite.adjust_admin_leave_balances_path, method: :post, local: true,
|
|
32
|
+
data: { turbo_confirm: "Change this leave balance? It shows on the person's leave at once." } do %>
|
|
32
33
|
<div class="hrl-field">
|
|
33
34
|
<label for="adj_user">Employee</label>
|
|
34
|
-
<select name="user_id" id="adj_user" class="hrl-input">
|
|
35
|
+
<select name="user_id" id="adj_user" class="hrl-input" required data-hrl-filter="Type a name to filter">
|
|
36
|
+
<option value="">Choose…</option>
|
|
35
37
|
<% @employees.each do |employee| %>
|
|
36
38
|
<option value="<%= employee.id %>"><%= hr_display_name(employee) %></option>
|
|
37
39
|
<% end %>
|
|
@@ -8,8 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
<div class="hrl-row hrl-row--mb">
|
|
10
10
|
<% HrLite::LeaveRequest::STATUSES.each do |status| %>
|
|
11
|
-
|
|
12
|
-
href="<%= hr_lite.admin_leave_requests_path(status: status) %>"><%= status.humanize %></a>
|
|
11
|
+
<%= link_to status.humanize, hr_lite.admin_leave_requests_path(status: status), class: "hrl-btn", aria: { current: ("true" if @status == status) } %>
|
|
13
12
|
<% end %>
|
|
14
13
|
</div>
|
|
15
14
|
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
<% if @request.reason.present? %><dt>Reason</dt><dd><%= @request.reason %></dd><% end %>
|
|
16
16
|
<% unless @request.leave_type.unlimited? %>
|
|
17
17
|
<dt>Balance</dt>
|
|
18
|
-
<dd><%= hrl_days(@balance.available) %> of <%= hrl_days(@balance.entitled) %> available</dd>
|
|
18
|
+
<dd><%= hrl_days(@balance.available(as_of: @request.start_date)) %> of <%= hrl_days(@balance.entitled(as_of: @request.start_date)) %> available</dd>
|
|
19
19
|
<% if (@request.pending? || @request.approved?) && (short = @request.days_beyond_balance).positive? %>
|
|
20
20
|
<dt>Loss of pay</dt><dd><%= hrl_days(short) %> day(s) beyond the balance will be unpaid</dd>
|
|
21
21
|
<% end %>
|
|
@@ -60,7 +60,8 @@
|
|
|
60
60
|
<%# Approve and reject are two separate forms on purpose. Rails binds the
|
|
61
61
|
CSRF token to the form's OWN action, so one form retargeted with
|
|
62
62
|
`formaction:` can never pass verification on the second endpoint. %>
|
|
63
|
-
<%= form_with url: hr_lite.approve_admin_leave_request_path(@request), method: :post, local: true
|
|
63
|
+
<%= form_with url: hr_lite.approve_admin_leave_request_path(@request), method: :post, local: true,
|
|
64
|
+
html: { data: { turbo_confirm: "Approve #{hr_display_name(@request.user)}'s leave, #{@request.date_range_label}?" } } do %>
|
|
64
65
|
<div class="hrl-field">
|
|
65
66
|
<label for="approve_note">Note (optional)</label>
|
|
66
67
|
<textarea name="decision_note" id="approve_note" class="hrl-input"></textarea>
|
|
@@ -73,7 +74,8 @@
|
|
|
73
74
|
|
|
74
75
|
<section class="hrl-card">
|
|
75
76
|
<h2 class="hrl-card__title">Reject</h2>
|
|
76
|
-
<%= form_with url: hr_lite.reject_admin_leave_request_path(@request), method: :post, local: true
|
|
77
|
+
<%= form_with url: hr_lite.reject_admin_leave_request_path(@request), method: :post, local: true,
|
|
78
|
+
html: { data: { turbo_confirm: "Reject #{hr_display_name(@request.user)}'s leave, #{@request.date_range_label}?" } } do %>
|
|
77
79
|
<div class="hrl-field">
|
|
78
80
|
<label for="reject_note">Reason (required)</label>
|
|
79
81
|
<textarea name="decision_note" id="reject_note" class="hrl-input" required></textarea>
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<% content_for(:page_title) { "Edit leave type" } %>
|
|
2
2
|
<div class="hrl-page__head">
|
|
3
3
|
<h1 class="hrl-page__title">Edit <%= @leave_type.name %></h1>
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
</div>
|
|
5
|
+
<%= render "form", leave_type: @leave_type, url: hr_lite.admin_leave_type_path(@leave_type), method: :patch %>
|
|
6
|
+
<div class="hrl-row hrl-mt">
|
|
7
|
+
<%= button_to "Delete", hr_lite.admin_leave_type_path(@leave_type), method: :delete,
|
|
6
8
|
class: "hrl-btn hrl-btn--danger",
|
|
7
9
|
form: { data: { turbo_confirm: "Delete this leave type?" } } %>
|
|
8
|
-
</div>
|
|
9
10
|
</div>
|
|
10
|
-
<%= render "form", leave_type: @leave_type, url: hr_lite.admin_leave_type_path(@leave_type), method: :patch %>
|
|
@@ -14,13 +14,13 @@
|
|
|
14
14
|
<% @leave_types.each do |type| %>
|
|
15
15
|
<tr>
|
|
16
16
|
<td data-label="Type">
|
|
17
|
-
<span class="hrl-badge" style="
|
|
17
|
+
<span class="hrl-badge hrl-badge--type" style="--hrl-type: <%= type.color %>"><%= type.code %></span>
|
|
18
18
|
<%= type.name %>
|
|
19
19
|
<% unless type.active %><span class="hrl-badge hrl-badge--muted">Inactive</span><% end %>
|
|
20
20
|
</td>
|
|
21
|
-
<td data-label="Quota" class="hrl-num"><%= type.unlimited? ? "Unlimited" : type.annual_quota
|
|
21
|
+
<td data-label="Quota" class="hrl-num"><%= type.unlimited? ? "Unlimited" : "#{hrl_days(type.annual_quota)} days" %></td>
|
|
22
22
|
<td data-label="Accrual"><%= type.accrual.humanize %></td>
|
|
23
|
-
<td data-label="Carry cap" class="hrl-num"><%= type.carry_forward_cap.
|
|
23
|
+
<td data-label="Carry cap" class="hrl-num"><%= type.carry_forward_cap ? "#{hrl_days(type.carry_forward_cap)} days" : "—" %></td>
|
|
24
24
|
<td data-label="Paid"><%= type.paid ? "Yes" : "No" %></td>
|
|
25
25
|
<td data-label="">
|
|
26
26
|
<a class="hrl-btn" href="<%= hr_lite.edit_admin_leave_type_path(type) %>">Edit</a>
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
<p>Outstanding across every active loan: <strong><%= hrl_money(@outstanding) %></strong></p>
|
|
11
11
|
<div class="hrl-row">
|
|
12
12
|
<% HrLite::Loan::STATUSES.each do |status| %>
|
|
13
|
-
<a class="hrl-btn <%= "
|
|
13
|
+
<a class="hrl-btn" <%= "aria-current=true" if @status == status %>
|
|
14
14
|
href="<%= hr_lite.admin_loans_path(status: status) %>"><%= status.humanize %></a>
|
|
15
15
|
<% end %>
|
|
16
16
|
</div>
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
<td data-label="Instalment" class="hrl-num"><%= hrl_money(loan.monthly_instalment) %></td>
|
|
32
32
|
<td data-label="Outstanding" class="hrl-num"><%= hrl_money(loan.outstanding) %></td>
|
|
33
33
|
<td data-label="">
|
|
34
|
-
<a class="hrl-
|
|
34
|
+
<a class="hrl-btn" href="<%= hr_lite.admin_loan_path(loan) %>">Open</a>
|
|
35
35
|
</td>
|
|
36
36
|
</tr>
|
|
37
37
|
<% end %>
|
|
@@ -4,18 +4,14 @@
|
|
|
4
4
|
</div>
|
|
5
5
|
|
|
6
6
|
<section class="hrl-card">
|
|
7
|
-
<
|
|
8
|
-
<
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
<% if @loan.reason.present? %><tr><td data-label="Reason"><%= @loan.reason %></td></tr><% end %>
|
|
16
|
-
</tbody>
|
|
17
|
-
</table>
|
|
18
|
-
</div>
|
|
7
|
+
<dl class="hrl-deflist">
|
|
8
|
+
<dt>Status</dt><dd><%= @loan.status.humanize %></dd>
|
|
9
|
+
<dt>Monthly instalment</dt><dd><%= hrl_money(@loan.monthly_instalment) %></dd>
|
|
10
|
+
<dt>Starts</dt><dd><%= @loan.starts_on.strftime("%b %Y") %></dd>
|
|
11
|
+
<dt>Repaid</dt><dd><%= hrl_money(@loan.repaid) %></dd>
|
|
12
|
+
<dt>Outstanding</dt><dd><strong><%= hrl_money(@loan.outstanding) %></strong></dd>
|
|
13
|
+
<% if @loan.reason.present? %><dt>Reason</dt><dd><%= @loan.reason %></dd><% end %>
|
|
14
|
+
</dl>
|
|
19
15
|
|
|
20
16
|
<% if @loan.active? %>
|
|
21
17
|
<div class="hrl-row">
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<% content_for(:page_title) { "Edit office" } %>
|
|
2
2
|
<div class="hrl-page__head">
|
|
3
3
|
<h1 class="hrl-page__title">Edit <%= @office_location.name %></h1>
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
</div>
|
|
5
|
+
<%= render "form", office_location: @office_location, url: hr_lite.admin_office_location_path(@office_location), method: :patch %>
|
|
6
|
+
<div class="hrl-row hrl-mt">
|
|
7
|
+
<%= button_to "Delete", hr_lite.admin_office_location_path(@office_location), method: :delete,
|
|
6
8
|
class: "hrl-btn hrl-btn--danger",
|
|
7
9
|
form: { data: { turbo_confirm: "Remove this office?" } } %>
|
|
8
|
-
</div>
|
|
9
10
|
</div>
|
|
10
|
-
<%= render "form", office_location: @office_location, url: hr_lite.admin_office_location_path(@office_location), method: :patch %>
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
<% if @runs.any? %>
|
|
11
11
|
<div class="hrl-table-wrap">
|
|
12
12
|
<table class="hrl-table hrl-table--stack">
|
|
13
|
-
<thead><tr><th>Period</th><th>Status</th><th>Slips</th><th>Net
|
|
13
|
+
<thead><tr><th>Period</th><th>Status</th><th>Slips</th><th>Net payout</th><th></th></tr></thead>
|
|
14
14
|
<tbody>
|
|
15
15
|
<% @runs.each do |run| %>
|
|
16
16
|
<tr>
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
<span class="hrl-badge <%= { "published" => "hrl-badge--ok", "finalized" => "hrl-badge--warn", "draft" => "hrl-badge--muted" }[run.status] %>"><%= run.status.humanize %></span>
|
|
20
20
|
</td>
|
|
21
21
|
<td data-label="Slips" class="hrl-num"><%= run.salary_slips.size %></td>
|
|
22
|
-
<td data-label="Net
|
|
22
|
+
<td data-label="Net payout" class="hrl-num"><%= hrl_money(run.total_net) %></td>
|
|
23
23
|
<td data-label=""><a class="hrl-btn" href="<%= hr_lite.admin_payroll_run_path(run) %>">Open</a></td>
|
|
24
24
|
</tr>
|
|
25
25
|
<% end %>
|
|
@@ -2,7 +2,7 @@
|
|
|
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>
|
|
@@ -29,7 +29,7 @@
|
|
|
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
33
|
form: { data: { turbo_confirm: ("Recompute #{@run.label}? This clears #{hr_display_name(@run.first_approved_by)}'s approval." if @run.first_approved_by) } } %>
|
|
34
34
|
<% end %>
|
|
35
35
|
<% if @run.review? && hr_can?("payroll.approve", scope: :all) && @run.first_approved_by_id != hr_current_user.id %>
|
|
@@ -56,6 +56,9 @@
|
|
|
56
56
|
<p class="hrl-small hrl-muted hrl-mt">
|
|
57
57
|
<% if @run.review? %>
|
|
58
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.
|
|
59
62
|
<% elsif @run.auto_approved_at %>
|
|
60
63
|
Approved automatically on <%= @run.auto_approved_at.strftime("%-d %b") %> — nobody had approved it by the 3rd.
|
|
61
64
|
<% end %>
|
|
@@ -66,20 +69,20 @@
|
|
|
66
69
|
<% if @slips.any? %>
|
|
67
70
|
<div class="hrl-table-wrap">
|
|
68
71
|
<table class="hrl-table hrl-table--stack">
|
|
69
|
-
<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>
|
|
70
73
|
<tbody>
|
|
71
74
|
<% @slips.each do |slip| %>
|
|
72
75
|
<tr>
|
|
73
76
|
<td data-label="Employee"><%= hr_display_name(slip.user) %></td>
|
|
74
|
-
<td data-label="
|
|
75
|
-
<td data-label="LOP" class="hrl-num">
|
|
76
|
-
<%= 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) %>
|
|
77
80
|
<% if slip.lop_override %><span class="hrl-badge hrl-badge--warn">override</span><% end %>
|
|
78
81
|
</td>
|
|
79
82
|
<td data-label="Gross" class="hrl-num"><%= hrl_money(slip.gross_earnings) %></td>
|
|
80
83
|
<td data-label="Deductions" class="hrl-num"><%= hrl_money(slip.total_deductions) %></td>
|
|
81
84
|
<td data-label="Net" class="hrl-num"><strong><%= hrl_money(slip.net_pay) %></strong></td>
|
|
82
|
-
<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>
|
|
83
86
|
</tr>
|
|
84
87
|
<% end %>
|
|
85
88
|
</tbody>
|
|
@@ -17,7 +17,7 @@
|
|
|
17
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,12 +8,12 @@
|
|
|
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
18
|
<%= f.submit "Publish", class: "hrl-btn hrl-btn--primary",
|
|
19
19
|
data: { turbo_confirm: "Publish and notify #{pluralize(HrLite.active_employees.size, 'person')} by email?" } %>
|
|
@@ -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" %>
|
|
@@ -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,7 +37,7 @@
|
|
|
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">
|
|
@@ -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 %>
|
|
@@ -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 %>
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
</section>
|
|
54
54
|
<% end %>
|
|
55
55
|
|
|
56
|
+
<% if @declaration.submitted? %>
|
|
56
57
|
<section class="hrl-card">
|
|
57
58
|
<h2 class="hrl-card__title">Decide</h2>
|
|
58
59
|
<div class="hrl-row">
|
|
@@ -71,3 +72,4 @@
|
|
|
71
72
|
<%= submit_tag "Send back", class: "hrl-btn" %>
|
|
72
73
|
<% end %>
|
|
73
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? %>
|