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
|
@@ -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 %>
|
|
@@ -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>
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
</section>
|
|
14
14
|
<% end %>
|
|
15
15
|
|
|
16
|
-
<% rows = hrl_inbox_rows %>
|
|
16
|
+
<% rows = hrl_inbox_rows.reject { |_, record| @in_flow.include?([ record.class.polymorphic_name, record.id ]) } %>
|
|
17
17
|
<section class="hrl-card">
|
|
18
18
|
<% if @approvals.empty? && rows.empty? %>
|
|
19
19
|
<p class="hrl-muted">Nothing is waiting on you.</p>
|
|
@@ -4,6 +4,15 @@
|
|
|
4
4
|
link_builder = local_assigns[:link_builder]
|
|
5
5
|
pending_dates = local_assigns[:pending_dates]
|
|
6
6
|
states = HrLite::ApplicationHelper::DAY_STATES %>
|
|
7
|
+
<div class="hrl-legend hrl-small">
|
|
8
|
+
<% states.except(:upcoming).each_value do |code, word, mod| %>
|
|
9
|
+
<span class="hrl-badge hrl-mgrid__key hrl-mgrid__day--<%= mod %>"><%= code %> <%= word %></span>
|
|
10
|
+
<% end %>
|
|
11
|
+
<span class="hrl-badge hrl-mgrid__key hrl-mgrid__day--today">Today</span>
|
|
12
|
+
<span class="hrl-badge hrl-mgrid__key"><span class="hrl-mgrid__flag" aria-hidden="true"></span> Flagged</span>
|
|
13
|
+
<% if pending_dates %><span class="hrl-badge hrl-mgrid__key hrl-mgrid__day--pending">Fix pending</span><% end %>
|
|
14
|
+
<span class="hrl-badge hrl-mgrid__key hrl-mgrid__day--muted">Upcoming</span>
|
|
15
|
+
</div>
|
|
7
16
|
<div class="hrl-mgrid" role="group" aria-label="Attendance for <%= month.strftime('%B %Y') %>">
|
|
8
17
|
<% %w[Mo Tu We Th Fr Sa Su].each do |d| %>
|
|
9
18
|
<div class="hrl-mgrid__head"><%= d %></div>
|
|
@@ -25,12 +34,3 @@
|
|
|
25
34
|
</div>
|
|
26
35
|
<% end %>
|
|
27
36
|
</div>
|
|
28
|
-
<div class="hrl-legend hrl-small">
|
|
29
|
-
<% states.except(:upcoming).each_value do |code, word, mod| %>
|
|
30
|
-
<span class="hrl-badge hrl-mgrid__key hrl-mgrid__day--<%= mod %>"><%= code %> <%= word %></span>
|
|
31
|
-
<% end %>
|
|
32
|
-
<span class="hrl-badge hrl-mgrid__key hrl-mgrid__day--today">Today</span>
|
|
33
|
-
<span class="hrl-badge hrl-mgrid__key"><span class="hrl-mgrid__flag" aria-hidden="true"></span> Flagged</span>
|
|
34
|
-
<% if pending_dates %><span class="hrl-badge hrl-mgrid__key hrl-mgrid__day--pending">Fix pending</span><% end %>
|
|
35
|
-
<span class="hrl-badge hrl-mgrid__key hrl-mgrid__day--muted">Upcoming</span>
|
|
36
|
-
</div>
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
leave_type = HrLite::Setting.instance.penalty_leave_type %>
|
|
4
4
|
<section class="hrl-card" id="penalties">
|
|
5
5
|
<h2 class="hrl-card__title">Penalty hours</h2>
|
|
6
|
-
<p><strong><%= hrl_duration(held * 60) %></strong> held · <%= hrl_days(HrLite::AttendancePenalty.days_for(held))
|
|
7
|
-
<p class="hrl-hint">Penalties add up until HR removes them
|
|
6
|
+
<p><strong><%= hrl_duration(held * 60) %></strong> held · <%= pluralize(hrl_days(HrLite::AttendancePenalty.days_for(held)), "day") %><%= " of #{leave_type.name}" if leave_type %></p>
|
|
7
|
+
<p class="hrl-hint">Penalties add up until HR removes them.<% if leave_type %> Every 5 hours holds half a day of leave, which can't be applied for.<% end %></p>
|
|
8
8
|
<% HrLite::PenaltyRemoval.where(user_id: user.id).includes(:removed_by).order(created_at: :desc).each do |removal| %>
|
|
9
9
|
<div class="hrl-feed__item hrl-small"><div class="hrl-feed__body">Removed <%= hrl_duration(removal.minutes * 60) %> on <%= removal.created_at.strftime("%-d %b %Y") %> by <%= hr_display_name(removal.removed_by) %>: <%= removal.reason %></div></div>
|
|
10
10
|
<% end %>
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
<div class="hrl-row hrl-row--mb hrl-small">
|
|
15
15
|
<% if record&.check_in_at && !record.check_out_at %>
|
|
16
|
-
<span class="hrl-badge hrl-badge--ok">In since <%= record.check_in_at.strftime("%H:%M") %> · <%= hrl_duration(Time.current - record.check_in_at) %> so far</span>
|
|
16
|
+
<span class="hrl-badge hrl-badge--ok">In since <%= record.check_in_at.strftime("%H:%M") %> · <span data-hrl-since="<%= record.check_in_at.iso8601 %>"><%= hrl_duration(Time.current - record.check_in_at) %> so far</span></span>
|
|
17
17
|
<% elsif record&.check_in_at %>
|
|
18
18
|
<span class="hrl-badge hrl-badge--ok">In <%= record.check_in_at.strftime("%H:%M") %></span>
|
|
19
19
|
<% end %>
|
|
@@ -142,9 +142,7 @@
|
|
|
142
142
|
|
|
143
143
|
<% if local_assigns.key?(:attention) %>
|
|
144
144
|
<div class="hrl-row">
|
|
145
|
-
<a class="hrl-btn" href="<%= hr_lite.
|
|
146
|
-
<% if HrLite.config.office_geofence %><a class="hrl-btn" href="<%= hr_lite.wfh_requests_path %>">Request WFH</a><% end %>
|
|
147
|
-
<a class="hrl-btn" href="<%= hr_lite.new_regularization_request_path %>">Fix a punch</a>
|
|
145
|
+
<a class="hrl-btn" href="<%= hr_lite.new_regularization_request_path %>">Fix a day</a>
|
|
148
146
|
<a class="hrl-btn" href="<%= hr_lite.new_comp_off_request_path %>">Comp-off</a>
|
|
149
147
|
<% if hr_lite_route?(:salary_slips_path) %><a class="hrl-btn" href="<%= hr_lite.salary_slips_path %>">Payslip</a><% end %>
|
|
150
148
|
</div>
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
<% elsif due %>
|
|
13
13
|
<% left = due - Time.current %>
|
|
14
14
|
<p class="hrl-small">Checked in <%= record.check_in_at.strftime("%H:%M") %> · checkout at <strong><%= due.strftime("%H:%M") %></strong> ·
|
|
15
|
-
<%= left.positive? ? "#{hrl_duration(left)} left" : "you can check out" %></p>
|
|
15
|
+
<span data-hrl-countdown="<%= due.iso8601 %>" data-hrl-done="you can check out"><%= left.positive? ? "#{hrl_duration(left)} left" : "you can check out" %></span></p>
|
|
16
16
|
<% end %>
|
|
17
17
|
<% HrLite::AttendancePenalty.active.where(user_id: hr_current_user.id, date: Date.current).each do |penalty| %>
|
|
18
18
|
<p class="hrl-small"><span class="hrl-badge hrl-badge--warn">+<%= penalty.minutes %> min</span> <%= penalty.label %></p>
|
|
@@ -23,11 +23,14 @@
|
|
|
23
23
|
<label for="hrl-slot-start">Check-in slot</label>
|
|
24
24
|
<%= select_tag :start_minute, options_for_select(HrLite::AttendanceSlot::START_MINUTES.map { |m| [ "#{HrLite::AttendanceSlot.label(m)} – out #{HrLite::AttendanceSlot.label(m + HrLite::EmployeeProfile.day_minutes_for(hr_current_user.id))}", m ] }, start), id: "hrl-slot-start" %>
|
|
25
25
|
</div>
|
|
26
|
-
<
|
|
27
|
-
<
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
<fieldset class="hrl-field">
|
|
27
|
+
<legend>Lock this slot for</legend>
|
|
28
|
+
<div class="hrl-mode-switch">
|
|
29
|
+
<% HrLite::AttendanceSlot::PERIODS.each do |period, word| %>
|
|
30
|
+
<button type="submit" name="period" value="<%= period %>" class="hrl-btn" data-turbo-confirm="Lock this slot for <%= word.downcase %>? After that only HR can change it."><%= word %></button>
|
|
31
|
+
<% end %>
|
|
32
|
+
</div>
|
|
33
|
+
</fieldset>
|
|
31
34
|
<p class="hrl-small hrl-muted">Once saved, only HR can change it for that period.</p>
|
|
32
35
|
<% end %>
|
|
33
36
|
<% end %>
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<% if home_m %> · <%= number_with_delimiter(home_m) %> m from home<% end %>
|
|
9
9
|
<% if accuracy %> · ±<%= accuracy %> m<% end %></div>
|
|
10
10
|
<% end %>
|
|
11
|
-
<% if (punches = record.punches).size > 2 %>
|
|
11
|
+
<% if (punches = local_assigns.fetch(:punches) { record.punches }).size > 2 %>
|
|
12
12
|
<div class="hrl-punch-line">All punches: <%= punches.join(" · ") %></div>
|
|
13
13
|
<% end %>
|
|
14
14
|
<% if (route = record.route_url) %>
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
</div>
|
|
14
14
|
<%= render "hr_lite/attendance/custom_status", status: status %>
|
|
15
15
|
<%= render "hr_lite/attendance/calendar_connection" %>
|
|
16
|
-
<% if status.half_day_leave %><p class="hrl-small hrl-muted">Half-day leave today (<%= status.half_day_leave.half_day_part || "half day" %>).</p><% end %>
|
|
16
|
+
<% if status.half_day_leave %><p class="hrl-small hrl-muted">Half-day leave today (<%= HrLite::DAY_PARTS.rassoc(status.half_day_leave.half_day_part)&.first&.downcase || "half day" %>).</p><% end %>
|
|
17
17
|
|
|
18
18
|
<% if working %>
|
|
19
19
|
<% if status.overlay %>
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
<div class="hrl-row hrl-right">
|
|
15
15
|
<% { present: "ok", half_day: "ok", leave: nil, absent: "bad" }.each do |kind, tone| %>
|
|
16
16
|
<% code, word = HrLite::ApplicationHelper::DAY_STATES[kind] %>
|
|
17
|
-
<span class="<%= class_names("hrl-badge", "hrl-badge--#{tone}": tone) %>" role="img" aria-label="<%= word %> <%= pluralize(@counts[kind], "day") %>"><%=
|
|
17
|
+
<span class="<%= class_names("hrl-badge", "hrl-badge--#{tone}": tone) %>" role="img" aria-label="<%= word %> <%= pluralize(@counts[kind], "day") %>"><%= word %> <%= @counts[kind] %></span>
|
|
18
18
|
<% end %>
|
|
19
19
|
</div>
|
|
20
20
|
</div>
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
link_builder: ->(d) { hr_lite.attendance_path(month: @month.strftime("%Y-%m"), day: d.iso8601, anchor: "day") if d <= Date.current } %>
|
|
23
23
|
<p class="hrl-small hrl-muted hrl-mt">Forgot to check in or out on some day?</p>
|
|
24
24
|
<div class="hrl-row">
|
|
25
|
-
<a class="hrl-btn" href="<%= hr_lite.new_regularization_request_path %>">
|
|
26
|
-
<a class="hrl-btn" href="<%= hr_lite.regularization_requests_path %>">
|
|
25
|
+
<a class="hrl-btn" href="<%= hr_lite.new_regularization_request_path %>">Fix a day</a>
|
|
26
|
+
<a class="hrl-btn" href="<%= hr_lite.regularization_requests_path %>">Day fixes</a>
|
|
27
27
|
</div>
|
|
28
28
|
</section>
|
|
29
29
|
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
<% if leave %><dt>Leave</dt><dd><%= leave.leave_type.name %></dd><% end %>
|
|
49
49
|
<% if @day_info.kind == :holiday %><dt>Holiday</dt><dd><%= HrLite::Holiday.company_wide.for_office(HrLite::WorkingCalendar.office_for(hr_current_user.id)).where(date: @day).pick(:name) %></dd><% end %>
|
|
50
50
|
<% if rec&.flagged? %><dt>Flag</dt><dd><%= rec.flag_note %></dd><% end %>
|
|
51
|
-
<% if @day_ticket %><dt>
|
|
51
|
+
<% if @day_ticket %><dt>Day fix</dt><dd><%= hrl_request_status_badge(@day_ticket.status) %> <%= @day_ticket.times_label %></dd><% end %>
|
|
52
52
|
</dl>
|
|
53
53
|
<% unless %i[holiday weekend leave].include?(@day_info.kind) || @day_ticket&.pending? %>
|
|
54
54
|
<a class="hrl-btn hrl-btn--primary hrl-btn--block hrl-mt" href="<%= hr_lite.new_regularization_request_path(date: @day) %>">Fix this day</a>
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
<% (first.cwday - 1).times do %><div></div><% end %>
|
|
21
21
|
<% (first..@month.end_of_month).each do |date| %>
|
|
22
22
|
<% cell_class, code =
|
|
23
|
-
if @
|
|
23
|
+
if @calendar.holiday?(date) then [ "hrl-mgrid__day--holiday", "H" ]
|
|
24
24
|
elsif @calendar.weekend?(date) then "hrl-mgrid__day--weekend"
|
|
25
25
|
elsif @leaves[date].any? then [ "hrl-mgrid__day--leave", "#{@leaves[date].size} off" ]
|
|
26
26
|
end %>
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
|
|
41
41
|
<%# Names only — the leave type is the employee's own business. Leave keeps its label's "(first half)" note. %>
|
|
42
42
|
<% day = ->(d) { d.strftime("%a %-d %b") }
|
|
43
|
-
agenda = @holidays.values.flatten.map { |h| [ h.date, "#{day.(h.date)}: #{h.name} (holiday)" ] } +
|
|
43
|
+
agenda = @holidays.values.flatten.map { |h| [ h.date, "#{day.(h.date)}: #{h.name} (#{h.optional ? 'optional holiday' : 'holiday'})" ] } +
|
|
44
44
|
@leaves.values.flatten.uniq.map { |r| [ [ r.start_date, first ].max, "#{[ r.start_date, r.end_date ].uniq.map(&day).join(' – ')}#{r.date_range_label[/ \(.+\)/]}: #{hr_display_name(r.user)}, on leave" ] } %>
|
|
45
45
|
<% if agenda.any? %>
|
|
46
46
|
<ul class="hrl-feed hrl-small hrl-mt">
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
<section class="hrl-card">
|
|
11
11
|
<p class="hrl-small hrl-muted">
|
|
12
|
-
Worked on a weekend or holiday? Request a comp-off — once
|
|
12
|
+
Worked on a weekend or holiday? Request a comp-off — once it is approved,
|
|
13
13
|
<%= @comp_off_type ? "your #{@comp_off_type.name} balance is credited" : "a day is credited to your balance" %>
|
|
14
14
|
and you spend it through the normal leave flow.
|
|
15
15
|
</p>
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
<%= f.label :half_day, "I worked only half the day (credits 0.5)" %>
|
|
19
19
|
</div>
|
|
20
20
|
<div class="hrl-field">
|
|
21
|
-
<%= f.label :reason, "What did you work on?
|
|
21
|
+
<%= f.label :reason, "What did you work on?" %>
|
|
22
22
|
<%= f.text_area :reason, required: true %>
|
|
23
23
|
</div>
|
|
24
24
|
<div class="hrl-form-actions">
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<%# locals: document, url (where it posts), open (start expanded) — one upload form for My documents and HR's view of a person. %>
|
|
2
2
|
<details class="hrl-card" <%= "open" if open || document.errors.any? %>>
|
|
3
|
-
<summary class="hrl-btn
|
|
3
|
+
<summary class="hrl-btn">Upload a document</summary>
|
|
4
4
|
<%= form_with model: document, url: url, method: :post, local: true, class: "hrl-mt" do |f| %>
|
|
5
5
|
<%= render "hr_lite/shared/form_errors", record: document %>
|
|
6
6
|
<div class="hrl-field">
|
|
@@ -19,8 +19,10 @@
|
|
|
19
19
|
<dt>Bank</dt><dd><%= [ @profile.bank_name, @profile.masked_account ].compact.join(" ").presence || "—" %></dd>
|
|
20
20
|
</dl>
|
|
21
21
|
<a class="hrl-btn hrl-mt" href="<%= hr_lite.org_path %>">Org chart</a>
|
|
22
|
-
<p class="hrl-small hrl-muted hrl-mt">Something wrong?
|
|
23
|
-
|
|
22
|
+
<p class="hrl-small hrl-muted hrl-mt">Something wrong?
|
|
23
|
+
<%= link_to_if hr_can?("hr_request.raise"), "Ask leadership to correct it", hr_lite.new_hr_request_path, class: "hrl-card__link" %> — changes are audited.</p>
|
|
24
|
+
<hr>
|
|
25
|
+
<a class="hrl-btn" href="<%= hr_lite.resignation_path %>">Resignation</a>
|
|
24
26
|
</section>
|
|
25
27
|
<% else %>
|
|
26
28
|
<p class="hrl-card hrl-card--empty">Your HR profile has not been set up yet.</p>
|
|
@@ -20,7 +20,8 @@
|
|
|
20
20
|
<% @mine_pending.each do |req| %>
|
|
21
21
|
<% title, detail, href = case req
|
|
22
22
|
when HrLite::LeaveRequest then [ req.leave_type.name, "#{req.date_range_label} · #{pluralize(hrl_days(req.days_count), 'day')}", hr_lite.leave_request_path(req) ]
|
|
23
|
-
when HrLite::RegularizationRequest then [ "
|
|
23
|
+
when HrLite::RegularizationRequest then [ "Day fix", "#{req.date.strftime('%a %-d %b')} · #{req.times_label}", hr_lite.regularization_requests_path ]
|
|
24
|
+
when HrLite::WfhRequest then [ "Work from home", [ req.start_date, req.end_date ].uniq.map { |d| d.strftime("%a %-d %b") }.join(" – "), hr_lite.wfh_requests_path ]
|
|
24
25
|
else [ "Comp-off", "Worked #{req.date_worked.strftime('%a %-d %b')}", hr_lite.comp_off_requests_path ]
|
|
25
26
|
end %>
|
|
26
27
|
<a class="hrl-listrow" href="<%= href %>">
|
|
@@ -37,7 +38,6 @@
|
|
|
37
38
|
<section class="hrl-card">
|
|
38
39
|
<h2 class="hrl-card__title">On leave this week</h2>
|
|
39
40
|
<%= render "hr_lite/leave_requests/out_list", leaves: @out_week, empty: "Nobody is on leave this week." %>
|
|
40
|
-
<a class="hrl-card__link" href="<%= hr_lite.team_path %>">Team board</a>
|
|
41
41
|
</section>
|
|
42
42
|
|
|
43
43
|
<% if @awards.any? %>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<% content_for(:page_title) { "ID card" } %>
|
|
2
2
|
<% content_for(:tabrow) { render "hr_lite/shared/person_tabs", user: @user } if params[:user_id] %>
|
|
3
|
+
<% content_for(:back, "Employees") if params[:user_id] %>
|
|
3
4
|
<% company = HrLite.config.company.call %>
|
|
4
5
|
<% brand = company[:brand].presence || company[:name].presence || "HR" %>
|
|
5
6
|
<% own = @user == hr_current_user %>
|
|
@@ -24,7 +25,7 @@
|
|
|
24
25
|
</div>
|
|
25
26
|
<div class="hrl-idcard__photo">
|
|
26
27
|
<% if @profile.photo.attached? %>
|
|
27
|
-
<img src="<%= Rails.application.routes.url_helpers.rails_storage_proxy_path(@profile.photo, disposition: "inline", only_path: true) %>" alt="<%= hr_display_name(@user) %>">
|
|
28
|
+
<img src="<%= Rails.application.routes.url_helpers.rails_storage_proxy_path(@profile.photo, disposition: "inline", only_path: true, expires_in: 1.hour) %>" alt="<%= hr_display_name(@user) %>">
|
|
28
29
|
<% else %>
|
|
29
30
|
<span><%= hr_display_name(@user).to_s.scan(/\b[[:alpha:]]/).first(2).join.upcase %></span>
|
|
30
31
|
<% end %>
|
|
@@ -63,6 +64,9 @@
|
|
|
63
64
|
</div>
|
|
64
65
|
|
|
65
66
|
<div class="hrl-idcard-actions">
|
|
67
|
+
<% if own && (@profile.blood_group.blank? || @profile.emergency_contact.blank?) && hr_can?("hr_request.raise") %>
|
|
68
|
+
<a class="hrl-card__link hrl-idcard-help" href="<%= hr_lite.new_hr_request_path %>">Missing details? Ask HR</a>
|
|
69
|
+
<% end %>
|
|
66
70
|
<button type="button" class="hrl-btn hrl-btn--primary" data-hrl-print>Print</button>
|
|
67
71
|
<button type="button" class="hrl-btn" data-hrl-share="id-card-<%= @profile.employee_code %>.png">Share</button>
|
|
68
72
|
<% if own && @print_requested %>
|
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
<% if types.any? %>
|
|
7
7
|
<div class="hrl-row">
|
|
8
8
|
<% types.each do |type| %>
|
|
9
|
-
<% balance = HrLite::LeaveBalance.for(user, type, HrLite::LeaveYear.current_key) %>
|
|
9
|
+
<% balance = HrLite::LeaveBalance.for(user, type, HrLite::LeaveYear.current_key); entitled = balance.entitled %>
|
|
10
10
|
<% pending = HrLite::LeaveRequest.pending.where(user_id: user.id, leave_type_id: type.id, start_date: HrLite::LeaveYear.range(HrLite::LeaveYear.current_key)).sum(&:days_count) %>
|
|
11
11
|
<span class="hrl-badge hrl-badge--type" style="--hrl-type: <%= type.color %>">
|
|
12
|
-
<%= type.name %> · <%= hrl_days(balance.
|
|
12
|
+
<%= type.name %> · <%= hrl_days(entitled - balance.used) %> of <%= hrl_days(entitled) %> left<% if pending.positive? %> · <%= hrl_days(pending) %> pending<% end %><% if (held = balance.penalty_days).positive? %> · <%= hrl_days(held) %> held for penalties<% end %>
|
|
13
13
|
</span>
|
|
14
14
|
<% end %>
|
|
15
15
|
</div>
|
|
@@ -7,38 +7,47 @@
|
|
|
7
7
|
<section class="hrl-card">
|
|
8
8
|
<%= form_with model: @request, url: hr_lite.leave_requests_path, local: true do |f| %>
|
|
9
9
|
<%= render "hr_lite/shared/form_errors", record: @request %>
|
|
10
|
+
<% bad = ->(attr) { "hrl-#{attr}-error" if @request.errors[attr].any? } %>
|
|
11
|
+
<% say = ->(attr) { tag.p(@request.errors.full_messages_for(attr).to_sentence, id: bad.(attr), class: "hrl-hint hrl-hint--bad") if bad.(attr) } %>
|
|
10
12
|
<div class="hrl-field">
|
|
11
13
|
<%= f.label :leave_type_id, "Type", id: "hrl-leave-type", for: nil %>
|
|
12
14
|
<% left = @balances.index_by(&:leave_type_id) %>
|
|
13
|
-
|
|
14
|
-
<% HrLite::LeaveType.active.each_with_index do |type, i| %>
|
|
15
|
+
<%= tag.div(class: "hrl-chiprow", role: "radiogroup", aria: { labelledby: "hrl-leave-type", describedby: bad.(:leave_type) }) do %>
|
|
16
|
+
<% HrLite::LeaveType.active.reject { |t| t.comp_off && (b = left[t.id]) && b.available <= 0 }.each_with_index do |type, i| %>
|
|
15
17
|
<label><%= f.radio_button :leave_type_id, type.id, required: i.zero? %><span><%= type.name.sub(/ leave\z/i, "") %><%= " · #{hrl_days(left[type.id].available)} left" if left[type.id] %><% if left[type.id] && (held = left[type.id].penalty_days).positive? %> · <%= hrl_days(held) %> held for penalties<% end %><%= " · Unpaid" unless type.paid %></span></label>
|
|
16
18
|
<% end %>
|
|
17
|
-
|
|
19
|
+
<% end %>
|
|
20
|
+
<%= say.(:leave_type) %>
|
|
18
21
|
<p class="hrl-hint">Days beyond your balance are unpaid (loss of pay), cut from that month's salary.<% if (capped = @balances.find { |b| b.penalty_days.positive? }) %> Today you can apply for at most <%= hrl_days(capped.applicable) %> days of <%= capped.leave_type.name %>, <%= hrl_days(capped.penalty_days) %> held for penalties.<% end %></p>
|
|
22
|
+
<% if (profile = HrLite::EmployeeProfile.find_by(user_id: hr_current_user.id))&.on_probation? %>
|
|
23
|
+
<p class="hrl-hint">On probation until <%= profile.probation_until.strftime("%d %b %Y") %>: at most 1 day of leave a month, of any type.</p>
|
|
24
|
+
<% end %>
|
|
19
25
|
</div>
|
|
20
26
|
<div class="hrl-field">
|
|
21
27
|
<%= f.label :start_date, "From" %>
|
|
22
|
-
<%= f.date_field :start_date, required: true %>
|
|
28
|
+
<%= f.date_field :start_date, required: true, aria: { describedby: bad.(:start_date) } %>
|
|
29
|
+
<%= say.(:start_date) %>
|
|
23
30
|
</div>
|
|
24
31
|
<div class="hrl-field">
|
|
25
32
|
<%= f.label :end_date, "To (leave blank for one day)" %>
|
|
26
|
-
<%= f.date_field :end_date %>
|
|
33
|
+
<%= f.date_field :end_date, aria: { describedby: bad.(:end_date) } %>
|
|
34
|
+
<%= say.(:end_date) %>
|
|
27
35
|
</div>
|
|
28
36
|
<div class="hrl-field">
|
|
29
37
|
<%= f.label :half_day_part, "Day", id: "hrl-day-part", for: nil %>
|
|
30
|
-
|
|
38
|
+
<%= tag.div(class: "hrl-chiprow", role: "radiogroup", aria: { labelledby: "hrl-day-part", describedby: bad.(:half_day) }) do %>
|
|
31
39
|
<% HrLite::DAY_PARTS.each do |label, value| %>
|
|
32
40
|
<label><%= f.radio_button :half_day_part, value %><span><%= label %></span></label>
|
|
33
41
|
<% end %>
|
|
34
|
-
|
|
42
|
+
<% end %>
|
|
43
|
+
<%= say.(:half_day) %>
|
|
35
44
|
</div>
|
|
36
45
|
<div class="hrl-field">
|
|
37
46
|
<%= f.label :reason, "Reason (optional)" %>
|
|
38
47
|
<%= f.text_area :reason %>
|
|
39
48
|
</div>
|
|
40
49
|
<div class="hrl-form-actions">
|
|
41
|
-
<%= f.submit "
|
|
50
|
+
<%= f.submit "Send for approval", class: "hrl-btn hrl-btn--primary" %>
|
|
42
51
|
<a class="hrl-btn" href="<%= hr_lite.leave_requests_path %>">Cancel</a>
|
|
43
52
|
</div>
|
|
44
53
|
<% end %>
|
|
@@ -19,5 +19,7 @@
|
|
|
19
19
|
<%= button_to "Cancel this leave", hr_lite.cancel_leave_request_path(@request), method: :post,
|
|
20
20
|
class: "hrl-btn hrl-btn--danger hrl-mt",
|
|
21
21
|
form: { data: { turbo_confirm: "Cancel this leave request?" } } %>
|
|
22
|
+
<% elsif @request.approved? %>
|
|
23
|
+
<p class="hrl-hint hrl-mt">This leave has started, so it can no longer be cancelled here. Ask HR if it needs cancelling.</p>
|
|
22
24
|
<% end %>
|
|
23
25
|
</section>
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
<% content_for(:page_title) { "
|
|
1
|
+
<% content_for(:page_title) { "Day fixes" } %>
|
|
2
2
|
<% content_for(:back, "Attendance") %>
|
|
3
3
|
<div class="hrl-page__head">
|
|
4
|
-
<h1 class="hrl-page__title">
|
|
4
|
+
<h1 class="hrl-page__title">Day fixes</h1>
|
|
5
5
|
<div class="hrl-page__actions">
|
|
6
|
-
<a class="hrl-btn hrl-btn--primary" href="<%= hr_lite.new_regularization_request_path %>">
|
|
6
|
+
<a class="hrl-btn hrl-btn--primary" href="<%= hr_lite.new_regularization_request_path %>">Fix a day</a>
|
|
7
7
|
</div>
|
|
8
8
|
</div>
|
|
9
9
|
|
|
10
10
|
<section class="hrl-card">
|
|
11
11
|
<p class="hrl-small hrl-muted">
|
|
12
|
-
Forgot to check in or out?
|
|
13
|
-
|
|
12
|
+
Forgot to check in or out? Fix a day with the actual times — once your
|
|
13
|
+
manager or HR approves, your attendance for that day is fixed automatically.
|
|
14
14
|
</p>
|
|
15
15
|
<% if @requests.any? %>
|
|
16
16
|
<div class="hrl-table-wrap">
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
<td data-label="" class="<%= 'hrl-cell--void' unless request.pending? %>">
|
|
27
27
|
<% if request.pending? %>
|
|
28
28
|
<%= button_to "Cancel", hr_lite.cancel_regularization_request_path(request), method: :post,
|
|
29
|
-
class: "hrl-btn hrl-btn--danger", form: { data: { turbo_confirm: "Cancel this
|
|
29
|
+
class: "hrl-btn hrl-btn--danger", form: { data: { turbo_confirm: "Cancel this day fix?" } } %>
|
|
30
30
|
<% end %>
|
|
31
31
|
</td>
|
|
32
32
|
</tr>
|
|
@@ -36,6 +36,6 @@
|
|
|
36
36
|
</div>
|
|
37
37
|
<%= hrl_pagination %>
|
|
38
38
|
<% else %>
|
|
39
|
-
<p class="hrl-card--empty">No
|
|
39
|
+
<p class="hrl-card--empty">No day fixes yet.</p>
|
|
40
40
|
<% end %>
|
|
41
41
|
</section>
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
<% content_for(:page_title) { "
|
|
1
|
+
<% content_for(:page_title) { "Fix a day" } %>
|
|
2
2
|
<% content_for(:back, "Attendance") %>
|
|
3
3
|
<div class="hrl-page__head">
|
|
4
|
-
<h1 class="hrl-page__title">
|
|
4
|
+
<h1 class="hrl-page__title">Fix a day</h1>
|
|
5
5
|
</div>
|
|
6
6
|
|
|
7
7
|
<section class="hrl-card">
|
|
8
8
|
<%= form_with model: @request, url: hr_lite.regularization_requests_path, scope: :regularization_request, local: true do |f| %>
|
|
9
9
|
<%= render "hr_lite/shared/form_errors", record: @request %>
|
|
10
10
|
<% if (rule = HrLite.config.self_regularization) %>
|
|
11
|
-
<p class="hrl-small hrl-muted">A missed punch or short day on a working day from today back to <%= rule[:within_days] %> days ago is fixed as soon as you submit, up to <%= rule[:per_week] %> times a week. Anything else goes to HR
|
|
11
|
+
<p class="hrl-small hrl-muted">A missed punch or short day on a working day from today back to <%= rule[:within_days] %> days ago is fixed as soon as you submit, up to <%= rule[:per_week] %> times a week. Anything else goes to your manager or HR for approval.</p>
|
|
12
12
|
<% end %>
|
|
13
13
|
<div class="hrl-field">
|
|
14
14
|
<%= f.label :date, "Which day needs fixing?" %>
|
|
@@ -25,11 +25,13 @@
|
|
|
25
25
|
<p class="hrl-hint">Leave blank if only check-in is missing. Short day? Leave both times blank and give the reason.</p>
|
|
26
26
|
</div>
|
|
27
27
|
<div class="hrl-field">
|
|
28
|
-
<%= f.label :reason, "Why does this day need fixing?
|
|
28
|
+
<%= f.label :reason, "Why does this day need fixing?" %>
|
|
29
29
|
<%= f.text_area :reason, required: true %>
|
|
30
30
|
</div>
|
|
31
|
+
<% fix_now = rule && @request.date && (probe = HrLite::RegularizationRequest.new(date: @request.date, user_id: hr_current_user.id)).self_fixable? %>
|
|
32
|
+
<% if fix_now %><p class="hrl-hint"><%= @request.date.strftime("%a %-d %b") %> is fixed as soon as you submit. Self-fixes left this week: <%= probe.self_fixes_left %>.</p><% end %>
|
|
31
33
|
<div class="hrl-form-actions">
|
|
32
|
-
<%= f.submit "
|
|
34
|
+
<%= f.submit fix_now ? "Fix now" : "Send for approval", class: "hrl-btn hrl-btn--primary" %>
|
|
33
35
|
<a class="hrl-btn" href="<%= hr_lite.regularization_requests_path %>">Cancel</a>
|
|
34
36
|
</div>
|
|
35
37
|
<% end %>
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<div class="hrl-kpi"><div class="hrl-kpi__value"><%= hrl_money(slip.net_pay) %></div><div class="hrl-kpi__label">Net pay</div></div>
|
|
4
4
|
<div class="hrl-kpi"><div class="hrl-kpi__value"><%= hrl_money(slip.gross_earnings) %></div><div class="hrl-kpi__label">Gross</div></div>
|
|
5
5
|
<div class="hrl-kpi"><div class="hrl-kpi__value"><%= hrl_money(slip.total_deductions) %></div><div class="hrl-kpi__label">Deductions</div></div>
|
|
6
|
-
<div class="hrl-kpi"><div class="hrl-kpi__value"><%= hrl_days(slip.payable_days) %> / <%= hrl_days(slip.effective_lop_days) %></div><div class="hrl-kpi__label">Payable / LOP days</div></div>
|
|
6
|
+
<div class="hrl-kpi"><div class="hrl-kpi__value"><%= hrl_days(slip.payable_days) %> / <%= hrl_days(slip.effective_lop_days) %></div><div class="hrl-kpi__label">Payable / <abbr title="Loss of pay: unpaid days">LOP</abbr> days</div></div>
|
|
7
7
|
</div>
|
|
8
8
|
<div class="hrl-grid hrl-grid--2">
|
|
9
9
|
<section class="hrl-card">
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
<%# Out-of-window days are named rather than silently dropped: without them
|
|
47
47
|
a mid-month joiner's row does not add up to the month. %>
|
|
48
48
|
<dt>Days</dt>
|
|
49
|
-
<dd><%= hrl_days(slip.payable_days) %> payable / <%= hrl_days(slip.effective_lop_days) %> LOP
|
|
49
|
+
<dd><%= hrl_days(slip.payable_days) %> payable / <%= hrl_days(slip.effective_lop_days) %> <abbr title="Loss of pay: unpaid days">LOP</abbr><% if slip.out_of_window_days.to_f.positive? %>
|
|
50
50
|
/ <%= hrl_days(slip.out_of_window_days) %> outside employment<% end %> of <%= slip.days_in_month %></dd>
|
|
51
51
|
<% if profile %>
|
|
52
52
|
<dt>Employee code</dt><dd><%= profile.employee_code %></dd>
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
</td>
|
|
34
34
|
</tr>
|
|
35
35
|
<tr>
|
|
36
|
-
<td>Payable days: <%= @slip.payable_days %> / <%= @slip.days_in_month %> (
|
|
36
|
+
<td>Payable days: <%= @slip.payable_days.to_s.delete_suffix(".0") %> / <%= @slip.days_in_month %> (unpaid <%= @slip.effective_lop_days.to_s.delete_suffix(".0") %>)</td>
|
|
37
37
|
<td class="num"><% if @profile&.masked_account %>Bank: <%= @profile.bank_name %> <%= @profile.masked_account %><% end %></td>
|
|
38
38
|
</tr>
|
|
39
39
|
</tbody>
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
<table class="hrl-table hrl-tax-working__table">
|
|
35
35
|
<tbody>
|
|
36
36
|
<tr><td>Salary paid so far this year</td><td class="hrl-num"><%= hrl_rupees(tax.paid_gross) %></td></tr>
|
|
37
|
-
<tr><td>Expected for the rest of the year (<%= hrl_rupees(tax.structure.monthly_gross) %> × <%= s.months_left %>)</td><td class="hrl-num"><%= hrl_rupees(tax.projected_gross) %></td></tr>
|
|
37
|
+
<tr><td>Expected for the rest of the year, before unpaid days (<%= hrl_rupees(tax.structure.monthly_gross) %> × <%= s.months_left %>)</td><td class="hrl-num"><%= hrl_rupees(tax.projected_gross) %></td></tr>
|
|
38
38
|
<tr class="hrl-tax-working__total"><td>Gross salary for the year</td><td class="hrl-num"><%= hrl_rupees(s.gross) %></td></tr>
|
|
39
39
|
<% if s.hra_exemption.positive? %><tr><td>Less HRA exemption (from rent)</td><td class="hrl-num">− <%= hrl_rupees(s.hra_exemption) %></td></tr><% end %>
|
|
40
40
|
<tr><td>Less standard deduction</td><td class="hrl-num">− <%= hrl_rupees(s.standard_deduction) %></td></tr>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<% content_for(:page_title) { "Tax" } %>
|
|
2
2
|
<% submittable = @declaration.persisted? && (@declaration.draft? || @declaration.rejected?) %>
|
|
3
|
-
<% locked = @declaration.verified? %>
|
|
3
|
+
<% locked = @declaration.verified? || @declaration.submitted? %>
|
|
4
4
|
<div class="hrl-page__head">
|
|
5
5
|
<h1 class="hrl-page__title">Tax — <%= @declaration.label %></h1>
|
|
6
6
|
</div>
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
<section class="hrl-card">
|
|
15
15
|
<p>
|
|
16
|
-
Declaration:
|
|
16
|
+
Declaration: <% if @declaration.verified? %><span class="hrl-badge hrl-badge--ok">Verified</span><% elsif @declaration.rejected? %><span class="hrl-badge hrl-badge--bad">Sent back</span><% else %><%= hrl_request_status_badge(@declaration.status) %><% end %>
|
|
17
17
|
<% if @declaration.note.present? %><span class="hrl-small hrl-muted">— <%= @declaration.note %></span><% end %>
|
|
18
18
|
</p>
|
|
19
19
|
<fieldset class="hrl-field" <%= "disabled" if locked %>>
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
</div>
|
|
27
27
|
<% end %>
|
|
28
28
|
</fieldset>
|
|
29
|
-
</
|
|
29
|
+
</section>
|
|
30
30
|
|
|
31
31
|
<details class="hrl-card" <%= "open" if @declaration.regime != "new" || @declaration.errors.any? %>>
|
|
32
32
|
<summary class="hrl-btn">Investments and rent (old regime only)</summary>
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
<% if submittable %><button type="submit" name="submit_to_hr" value="1" class="hrl-btn hrl-btn--primary">Submit to HR</button><% end %>
|
|
70
70
|
</div>
|
|
71
71
|
<% else %>
|
|
72
|
-
<p class="hrl-small hrl-muted"
|
|
72
|
+
<p class="hrl-small hrl-muted"><%= @declaration.verified? ? "HR has verified this year's declaration." : "Sent to HR to check the proof." %> To change anything, ask HR through Help › Ask HR.</p>
|
|
73
73
|
<% end %>
|
|
74
74
|
<% end %>
|
|
75
75
|
<% content_for(:scripts) { javascript_include_tag "hr_lite/tax_preview", defer: true } %>
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
<% content_for(:page_title) { "Team" } %>
|
|
1
|
+
<% content_for(:page_title) { "Team board" } %>
|
|
2
2
|
<div class="hrl-page__head">
|
|
3
|
-
<h1 class="hrl-page__title">Team — <%= @date == Date.current ? "today" : @date.strftime("%A, %d %B") %></h1>
|
|
3
|
+
<h1 class="hrl-page__title">Team board — <%= @date == Date.current ? "today" : @date.strftime("%A, %d %B") %></h1>
|
|
4
4
|
<div class="hrl-page__actions">
|
|
5
|
-
<a class="hrl-btn"
|
|
5
|
+
<a class="hrl-btn" href="<%= hr_lite.team_path(date: (@date - 1).strftime("%Y-%m-%d")) %>"><span aria-hidden="true">‹</span> <%= @date == Date.current ? "Yesterday" : "Previous day" %></a>
|
|
6
6
|
<% unless @date == Date.current %>
|
|
7
7
|
<a class="hrl-btn" href="<%= hr_lite.team_path %>">Today</a>
|
|
8
8
|
<% end %>
|
|
9
9
|
<% if @date < Date.current %>
|
|
10
|
-
<a class="hrl-btn"
|
|
10
|
+
<a class="hrl-btn" href="<%= hr_lite.team_path(date: (@date + 1).strftime("%Y-%m-%d")) %>">Next day <span aria-hidden="true">›</span></a>
|
|
11
11
|
<% end %>
|
|
12
12
|
</div>
|
|
13
13
|
</div>
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
<div class="hrl-kpi"><div class="hrl-kpi__value"><%= kpis[:checked_in] %></div><div class="hrl-kpi__label">Checked in</div></div>
|
|
18
18
|
<div class="hrl-kpi"><div class="hrl-kpi__value"><%= kpis[:on_leave] %></div><div class="hrl-kpi__label">On leave</div></div>
|
|
19
19
|
<div class="hrl-kpi"><div class="hrl-kpi__value"><%= kpis[:not_in] %></div><div class="hrl-kpi__label">Not in</div></div>
|
|
20
|
-
<div class="hrl-kpi"><div class="hrl-kpi__value"><%= @board.rows.size %></div><div class="hrl-kpi__label">
|
|
20
|
+
<div class="hrl-kpi"><div class="hrl-kpi__value"><%= @board.rows.size %></div><div class="hrl-kpi__label">People</div></div>
|
|
21
21
|
</div>
|
|
22
22
|
|
|
23
23
|
<% if @statuses %>
|
|
@@ -48,7 +48,8 @@
|
|
|
48
48
|
<span class="hrl-badge hrl-badge--muted">+<%= row.profile.buffer_minutes / 60 %>h buffer · <%= HrLite::EmployeeProfile::BUFFER_REASONS[row.profile.buffer_reason] %></span><% end %></span>
|
|
49
49
|
</td>
|
|
50
50
|
<% if (st = @statuses&.dig(row.user.id)) %>
|
|
51
|
-
|
|
51
|
+
<%# A derived status (offline, leave, holiday) repeats the Status cell; phone cards skip it. %>
|
|
52
|
+
<td data-label="Now" class="<%= 'hrl-cell--void' unless st.primary.event || st.custom %>"><span class="hrl-modes"><%= hrl_status_icons(st) %></span>
|
|
52
53
|
<span class="hrl-small"><%= st.primary.place || st.primary.label %><% if st.overlay %> · <%= st.overlay.label %><% end %>
|
|
53
54
|
<% if (till = st.overlay&.until || (st.primary.until if st.primary.until.respond_to?(:hour))) %> · until <%= till.strftime("%H:%M") %><% end %></span>
|
|
54
55
|
<% if st.updated_at %><span class="hrl-small hrl-muted"> · since <%= st.updated_at.strftime("%H:%M") %></span><% end %>
|
|
@@ -66,5 +67,5 @@
|
|
|
66
67
|
<p class="hrl-card--empty">Nobody to show<%= @rows ? " for these filters" : " for this date" %>.</p>
|
|
67
68
|
<% end %>
|
|
68
69
|
<p class="hrl-small hrl-muted hrl-mt">Forgot a punch yourself?
|
|
69
|
-
<a class="hrl-card__link" href="<%= hr_lite.new_regularization_request_path %>">
|
|
70
|
+
<a class="hrl-card__link" href="<%= hr_lite.new_regularization_request_path %>">Fix a day</a></p>
|
|
70
71
|
</section>
|