hr_lite 0.1.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 +7 -0
- data/CHANGELOG.md +33 -0
- data/MIT-LICENSE +20 -0
- data/README.md +166 -0
- data/Rakefile +3 -0
- data/app/assets/javascripts/hr_lite/geo_punch.js +61 -0
- data/app/assets/javascripts/hr_lite/mention.js +100 -0
- data/app/assets/stylesheets/hr_lite/application.css +15 -0
- data/app/assets/stylesheets/hr_lite/hr_lite.css +239 -0
- data/app/controllers/hr_lite/admin/appraisals_controller.rb +74 -0
- data/app/controllers/hr_lite/admin/attendances_controller.rb +79 -0
- data/app/controllers/hr_lite/admin/audit_logs_controller.rb +9 -0
- data/app/controllers/hr_lite/admin/base_controller.rb +16 -0
- data/app/controllers/hr_lite/admin/designation_changes_controller.rb +33 -0
- data/app/controllers/hr_lite/admin/employees_controller.rb +53 -0
- data/app/controllers/hr_lite/admin/holidays_controller.rb +70 -0
- data/app/controllers/hr_lite/admin/leadership_controller.rb +18 -0
- data/app/controllers/hr_lite/admin/leave_balances_controller.rb +41 -0
- data/app/controllers/hr_lite/admin/leave_requests_controller.rb +41 -0
- data/app/controllers/hr_lite/admin/leave_types_controller.rb +54 -0
- data/app/controllers/hr_lite/admin/office_locations_controller.rb +46 -0
- data/app/controllers/hr_lite/admin/overview_controller.rb +12 -0
- data/app/controllers/hr_lite/admin/payroll_runs_controller.rb +93 -0
- data/app/controllers/hr_lite/admin/salary_slips_controller.rb +44 -0
- data/app/controllers/hr_lite/admin/salary_structures_controller.rb +49 -0
- data/app/controllers/hr_lite/admin/settings_controller.rb +18 -0
- data/app/controllers/hr_lite/application_controller.rb +76 -0
- data/app/controllers/hr_lite/appraisals_controller.rb +18 -0
- data/app/controllers/hr_lite/attendance_controller.rb +37 -0
- data/app/controllers/hr_lite/calendar_controller.rb +20 -0
- data/app/controllers/hr_lite/career_controller.rb +9 -0
- data/app/controllers/hr_lite/employee_profiles_controller.rb +9 -0
- data/app/controllers/hr_lite/holidays_controller.rb +9 -0
- data/app/controllers/hr_lite/home_controller.rb +7 -0
- data/app/controllers/hr_lite/kudos_controller.rb +36 -0
- data/app/controllers/hr_lite/leave_balances_controller.rb +11 -0
- data/app/controllers/hr_lite/leave_requests_controller.rb +56 -0
- data/app/controllers/hr_lite/salary_slips_controller.rb +39 -0
- data/app/controllers/hr_lite/users_controller.rb +9 -0
- data/app/helpers/hr_lite/application_helper.rb +105 -0
- data/app/jobs/hr_lite/application_job.rb +4 -0
- data/app/jobs/hr_lite/daily_digest_job.rb +33 -0
- data/app/jobs/hr_lite/leave_year_rollover_job.rb +29 -0
- data/app/mailers/hr_lite/application_mailer.rb +5 -0
- data/app/mailers/hr_lite/event_mailer.rb +33 -0
- data/app/models/concerns/hr_lite/audited.rb +70 -0
- data/app/models/concerns/hr_lite/encrypted_money.rb +32 -0
- data/app/models/hr_lite/application_record.rb +5 -0
- data/app/models/hr_lite/appraisal.rb +89 -0
- data/app/models/hr_lite/attendance_record.rb +41 -0
- data/app/models/hr_lite/audit_log.rb +17 -0
- data/app/models/hr_lite/designation_change.rb +52 -0
- data/app/models/hr_lite/employee_profile.rb +72 -0
- data/app/models/hr_lite/holiday.rb +18 -0
- data/app/models/hr_lite/kudo.rb +54 -0
- data/app/models/hr_lite/kudo_mention.rb +8 -0
- data/app/models/hr_lite/leave_balance.rb +42 -0
- data/app/models/hr_lite/leave_request.rb +207 -0
- data/app/models/hr_lite/leave_type.rb +22 -0
- data/app/models/hr_lite/office_location.rb +21 -0
- data/app/models/hr_lite/payroll_run.rb +112 -0
- data/app/models/hr_lite/salary_slip.rb +78 -0
- data/app/models/hr_lite/salary_structure.rb +49 -0
- data/app/models/hr_lite/setting.rb +14 -0
- data/app/services/hr_lite/attendance_puncher.rb +103 -0
- data/app/services/hr_lite/attendance_summary.rb +98 -0
- data/app/services/hr_lite/calculators/esi.rb +25 -0
- data/app/services/hr_lite/calculators/pf.rb +32 -0
- data/app/services/hr_lite/calculators/professional_tax.rb +20 -0
- data/app/services/hr_lite/calculators/proration.rb +30 -0
- data/app/services/hr_lite/calculators/tds.rb +74 -0
- data/app/services/hr_lite/day_status.rb +49 -0
- data/app/services/hr_lite/leave_day_counter.rb +24 -0
- data/app/services/hr_lite/overview_query.rb +39 -0
- data/app/services/hr_lite/payroll_run_processor.rb +46 -0
- data/app/services/hr_lite/pdf_renderer.rb +23 -0
- data/app/services/hr_lite/slip_builder.rb +106 -0
- data/app/services/hr_lite/working_calendar.rb +41 -0
- data/app/views/hr_lite/admin/appraisals/_form.html.erb +29 -0
- data/app/views/hr_lite/admin/appraisals/edit.html.erb +6 -0
- data/app/views/hr_lite/admin/appraisals/new.html.erb +6 -0
- data/app/views/hr_lite/admin/attendances/index.html.erb +49 -0
- data/app/views/hr_lite/admin/attendances/show.html.erb +55 -0
- data/app/views/hr_lite/admin/audit_logs/index.html.erb +39 -0
- data/app/views/hr_lite/admin/designation_changes/new.html.erb +19 -0
- data/app/views/hr_lite/admin/employees/_form.html.erb +40 -0
- data/app/views/hr_lite/admin/employees/edit.html.erb +3 -0
- data/app/views/hr_lite/admin/employees/index.html.erb +40 -0
- data/app/views/hr_lite/admin/employees/new.html.erb +3 -0
- data/app/views/hr_lite/admin/employees/show.html.erb +75 -0
- data/app/views/hr_lite/admin/holidays/index.html.erb +59 -0
- data/app/views/hr_lite/admin/leave_balances/index.html.erb +58 -0
- data/app/views/hr_lite/admin/leave_requests/index.html.erb +35 -0
- data/app/views/hr_lite/admin/leave_requests/show.html.erb +39 -0
- data/app/views/hr_lite/admin/leave_types/_form.html.erb +27 -0
- data/app/views/hr_lite/admin/leave_types/edit.html.erb +10 -0
- data/app/views/hr_lite/admin/leave_types/index.html.erb +39 -0
- data/app/views/hr_lite/admin/leave_types/new.html.erb +3 -0
- data/app/views/hr_lite/admin/office_locations/_form.html.erb +18 -0
- data/app/views/hr_lite/admin/office_locations/edit.html.erb +10 -0
- data/app/views/hr_lite/admin/office_locations/index.html.erb +30 -0
- data/app/views/hr_lite/admin/office_locations/new.html.erb +3 -0
- data/app/views/hr_lite/admin/overview/index.html.erb +72 -0
- data/app/views/hr_lite/admin/payroll_runs/index.html.erb +33 -0
- data/app/views/hr_lite/admin/payroll_runs/new.html.erb +20 -0
- data/app/views/hr_lite/admin/payroll_runs/show.html.erb +76 -0
- data/app/views/hr_lite/admin/salary_slips/show.html.erb +42 -0
- data/app/views/hr_lite/admin/salary_structures/_form.html.erb +25 -0
- data/app/views/hr_lite/admin/salary_structures/edit.html.erb +6 -0
- data/app/views/hr_lite/admin/salary_structures/new.html.erb +6 -0
- data/app/views/hr_lite/admin/settings/edit.html.erb +18 -0
- data/app/views/hr_lite/appraisals/index.html.erb +22 -0
- data/app/views/hr_lite/appraisals/show.html.erb +32 -0
- data/app/views/hr_lite/attendance/_month_grid.html.erb +41 -0
- data/app/views/hr_lite/attendance/_punch_card.html.erb +41 -0
- data/app/views/hr_lite/attendance/show.html.erb +22 -0
- data/app/views/hr_lite/calendar/show.html.erb +45 -0
- data/app/views/hr_lite/career/show.html.erb +49 -0
- data/app/views/hr_lite/employee_profiles/show.html.erb +22 -0
- data/app/views/hr_lite/event_mailer/event.html.erb +10 -0
- data/app/views/hr_lite/event_mailer/event.text.erb +10 -0
- data/app/views/hr_lite/event_mailer/leadership.html.erb +27 -0
- data/app/views/hr_lite/event_mailer/leadership.text.erb +16 -0
- data/app/views/hr_lite/holidays/_next_holiday.html.erb +12 -0
- data/app/views/hr_lite/holidays/index.html.erb +30 -0
- data/app/views/hr_lite/home/index.html.erb +25 -0
- data/app/views/hr_lite/kudos/_kudo.html.erb +17 -0
- data/app/views/hr_lite/kudos/index.html.erb +39 -0
- data/app/views/hr_lite/leave_balances/index.html.erb +19 -0
- data/app/views/hr_lite/leave_requests/_balance_chips.html.erb +17 -0
- data/app/views/hr_lite/leave_requests/index.html.erb +37 -0
- data/app/views/hr_lite/leave_requests/new.html.erb +36 -0
- data/app/views/hr_lite/leave_requests/show.html.erb +25 -0
- data/app/views/hr_lite/salary_slips/_slip_detail.html.erb +48 -0
- data/app/views/hr_lite/salary_slips/index.html.erb +29 -0
- data/app/views/hr_lite/salary_slips/pdf.html.erb +72 -0
- data/app/views/hr_lite/salary_slips/show.html.erb +12 -0
- data/app/views/hr_lite/shared/_form_errors.html.erb +10 -0
- data/app/views/hr_lite/shared/_pagination.html.erb +11 -0
- data/app/views/layouts/hr_lite/application.html.erb +56 -0
- data/app/views/layouts/hr_lite/mailer.html.erb +30 -0
- data/app/views/layouts/hr_lite/mailer.text.erb +6 -0
- data/app/views/layouts/hr_lite/pdf.html.erb +26 -0
- data/config/routes.rb +57 -0
- data/db/migrate/20260718190726_create_hr_lite_kudos.rb +14 -0
- data/db/migrate/20260718190727_create_hr_lite_kudo_mentions.rb +12 -0
- data/db/migrate/20260718190728_create_hr_lite_audit_logs.rb +15 -0
- data/db/migrate/20260718192342_create_hr_lite_office_locations.rb +13 -0
- data/db/migrate/20260718192343_create_hr_lite_attendance_records.rb +27 -0
- data/db/migrate/20260718193045_create_hr_lite_holidays.rb +14 -0
- data/db/migrate/20260718193046_create_hr_lite_leave_types.rb +20 -0
- data/db/migrate/20260718193047_create_hr_lite_leave_balances.rb +17 -0
- data/db/migrate/20260718193048_create_hr_lite_leave_requests.rb +23 -0
- data/db/migrate/20260718193049_create_hr_lite_settings.rb +10 -0
- data/db/migrate/20260718194534_create_hr_lite_employee_profiles.rb +27 -0
- data/db/migrate/20260718194535_create_hr_lite_salary_structures.rb +23 -0
- data/db/migrate/20260718194536_create_hr_lite_payroll_runs.rb +20 -0
- data/db/migrate/20260718194537_create_hr_lite_salary_slips.rb +28 -0
- data/db/migrate/20260718195953_create_hr_lite_appraisals.rb +22 -0
- data/db/migrate/20260718195954_create_hr_lite_designation_changes.rb +17 -0
- data/lib/generators/hr_lite/install/install_generator.rb +29 -0
- data/lib/generators/hr_lite/install/templates/AFTER_INSTALL +35 -0
- data/lib/generators/hr_lite/install/templates/initializer.rb +45 -0
- data/lib/hr_lite/configuration.rb +60 -0
- data/lib/hr_lite/current.rb +7 -0
- data/lib/hr_lite/engine.rb +39 -0
- data/lib/hr_lite/geo.rb +22 -0
- data/lib/hr_lite/mention_parser.rb +18 -0
- data/lib/hr_lite/money.rb +33 -0
- data/lib/hr_lite/notifications.rb +99 -0
- data/lib/hr_lite/seeds.rb +42 -0
- data/lib/hr_lite/statutory_rate_card.rb +60 -0
- data/lib/hr_lite/version.rb +3 -0
- data/lib/hr_lite.rb +104 -0
- data/lib/tasks/hr_lite_tasks.rake +8 -0
- metadata +250 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<% content_for(:page_title) { "Career" } %>
|
|
2
|
+
<div class="hrl-page__head">
|
|
3
|
+
<h1 class="hrl-page__title">My career</h1>
|
|
4
|
+
</div>
|
|
5
|
+
|
|
6
|
+
<section class="hrl-card">
|
|
7
|
+
<h2 class="hrl-card__title">Current role</h2>
|
|
8
|
+
<p><strong><%= @profile&.designation.presence || "Not set yet" %></strong>
|
|
9
|
+
<% if @profile %><span class="hrl-muted hrl-small">since <%= (@changes.first&.effective_date || @profile.date_of_joining).strftime("%b %Y") %></span><% end %>
|
|
10
|
+
</p>
|
|
11
|
+
</section>
|
|
12
|
+
|
|
13
|
+
<section class="hrl-card">
|
|
14
|
+
<h2 class="hrl-card__title">Role history</h2>
|
|
15
|
+
<% if @changes.any? %>
|
|
16
|
+
<% @changes.each do |change| %>
|
|
17
|
+
<div class="hrl-feed__item">
|
|
18
|
+
<div class="hrl-feed__body">
|
|
19
|
+
<strong><%= change.to_designation %></strong>
|
|
20
|
+
<% if change.from_designation.present? %><span class="hrl-muted">(from <%= change.from_designation %>)</span><% end %>
|
|
21
|
+
<div class="hrl-feed__meta">
|
|
22
|
+
Effective <%= change.effective_date.strftime("%d %b %Y") %>
|
|
23
|
+
<% if change.note.present? %> · <%= change.note %><% end %>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
<% end %>
|
|
28
|
+
<% else %>
|
|
29
|
+
<p class="hrl-muted hrl-small">No role changes recorded yet.</p>
|
|
30
|
+
<% end %>
|
|
31
|
+
</section>
|
|
32
|
+
|
|
33
|
+
<section class="hrl-card">
|
|
34
|
+
<h2 class="hrl-card__title">Appraisals</h2>
|
|
35
|
+
<% if @appraisals.any? %>
|
|
36
|
+
<% @appraisals.each do |appraisal| %>
|
|
37
|
+
<div class="hrl-feed__item">
|
|
38
|
+
<div class="hrl-feed__body">
|
|
39
|
+
<strong><%= appraisal.period_label %></strong>
|
|
40
|
+
<% if appraisal.rating %><span class="hrl-badge hrl-badge--ok"><%= appraisal.rating %>/5</span><% end %>
|
|
41
|
+
<% if appraisal.outcome != "none" %><span class="hrl-badge"><%= appraisal.outcome.humanize %></span><% end %>
|
|
42
|
+
</div>
|
|
43
|
+
<a class="hrl-btn" href="<%= hr_lite.appraisal_path(appraisal) %>">Read</a>
|
|
44
|
+
</div>
|
|
45
|
+
<% end %>
|
|
46
|
+
<% else %>
|
|
47
|
+
<p class="hrl-muted hrl-small">No shared appraisals yet.</p>
|
|
48
|
+
<% end %>
|
|
49
|
+
</section>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<% content_for(:page_title) { "My HR profile" } %>
|
|
2
|
+
<div class="hrl-page__head">
|
|
3
|
+
<h1 class="hrl-page__title">My HR profile</h1>
|
|
4
|
+
</div>
|
|
5
|
+
|
|
6
|
+
<% if @profile %>
|
|
7
|
+
<section class="hrl-card">
|
|
8
|
+
<dl class="hrl-deflist">
|
|
9
|
+
<dt>Employee code</dt><dd><%= @profile.employee_code %></dd>
|
|
10
|
+
<dt>Designation</dt><dd><%= @profile.designation.presence || "—" %></dd>
|
|
11
|
+
<dt>Department</dt><dd><%= @profile.department.presence || "—" %></dd>
|
|
12
|
+
<dt>Joined</dt><dd><%= @profile.date_of_joining.strftime("%d %B %Y") %></dd>
|
|
13
|
+
<dt>Tax regime</dt><dd><%= @profile.tax_regime.humanize %></dd>
|
|
14
|
+
<dt>PAN</dt><dd><%= @profile.masked_pan || "—" %></dd>
|
|
15
|
+
<dt>PF UAN</dt><dd><%= @profile.masked_uan || "—" %></dd>
|
|
16
|
+
<dt>Bank</dt><dd><%= [ @profile.bank_name, @profile.masked_account ].compact.join(" ").presence || "—" %></dd>
|
|
17
|
+
</dl>
|
|
18
|
+
<p class="hrl-small hrl-muted hrl-mt">Something wrong? Ask leadership to correct it — changes are audited.</p>
|
|
19
|
+
</section>
|
|
20
|
+
<% else %>
|
|
21
|
+
<p class="hrl-card hrl-card--empty">Your HR profile has not been set up yet.</p>
|
|
22
|
+
<% end %>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<h1><%= @heading %></h1>
|
|
2
|
+
<% if @body.present? %><p><%= @body %></p><% end %>
|
|
3
|
+
<% if @lines.any? %>
|
|
4
|
+
<ul class="lines">
|
|
5
|
+
<% @lines.each do |line| %><li><%= line %></li><% end %>
|
|
6
|
+
</ul>
|
|
7
|
+
<% end %>
|
|
8
|
+
<% if @cta_url %>
|
|
9
|
+
<a class="btn" href="<%= @cta_url %>">Open in HR</a>
|
|
10
|
+
<% end %>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<h1><%= @heading %></h1>
|
|
2
|
+
<% if @body.present? %><p><%= @body %></p><% end %>
|
|
3
|
+
<% if @lines.any? %>
|
|
4
|
+
<ul class="lines">
|
|
5
|
+
<% @lines.each do |line| %><li><%= line %></li><% end %>
|
|
6
|
+
</ul>
|
|
7
|
+
<% end %>
|
|
8
|
+
<% if @diff.present? %>
|
|
9
|
+
<table class="diff">
|
|
10
|
+
<tr><th>Field</th><th>Change</th></tr>
|
|
11
|
+
<% @diff.each do |attr, change| %>
|
|
12
|
+
<tr>
|
|
13
|
+
<td><%= attr.to_s.humanize %></td>
|
|
14
|
+
<td>
|
|
15
|
+
<% if change.is_a?(Array) %>
|
|
16
|
+
<%= change[0].inspect %> → <%= change[1].inspect %>
|
|
17
|
+
<% else %>
|
|
18
|
+
<%= change %>
|
|
19
|
+
<% end %>
|
|
20
|
+
</td>
|
|
21
|
+
</tr>
|
|
22
|
+
<% end %>
|
|
23
|
+
</table>
|
|
24
|
+
<% end %>
|
|
25
|
+
<% if @cta_url %>
|
|
26
|
+
<a class="btn" href="<%= @cta_url %>">Open in HR</a>
|
|
27
|
+
<% end %>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<%= @heading %>
|
|
2
|
+
<% if @body.present? %>
|
|
3
|
+
<%= @body %>
|
|
4
|
+
<% end %>
|
|
5
|
+
<% @lines.each do |line| %>
|
|
6
|
+
- <%= line %>
|
|
7
|
+
<% end %>
|
|
8
|
+
<% if @diff.present? %>
|
|
9
|
+
Changes:
|
|
10
|
+
<% @diff.each do |attr, change| %>
|
|
11
|
+
- <%= attr.to_s.humanize %>: <%= change.is_a?(Array) ? "#{change[0].inspect} -> #{change[1].inspect}" : change %>
|
|
12
|
+
<% end %>
|
|
13
|
+
<% end %>
|
|
14
|
+
<% if @cta_url %>
|
|
15
|
+
<%= @cta_url %>
|
|
16
|
+
<% end %>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<section class="hrl-card">
|
|
2
|
+
<h2 class="hrl-card__title">Next holiday</h2>
|
|
3
|
+
<% holiday = HrLite::Holiday.company_wide.upcoming.first %>
|
|
4
|
+
<% if holiday %>
|
|
5
|
+
<p><strong><%= holiday.name %></strong><br>
|
|
6
|
+
<span class="hrl-muted hrl-small"><%= holiday.date.strftime("%A, %d %B %Y") %>
|
|
7
|
+
(<%= (holiday.date - Date.current).to_i %> days away)</span></p>
|
|
8
|
+
<% else %>
|
|
9
|
+
<p class="hrl-muted hrl-small">No upcoming holidays on the calendar.</p>
|
|
10
|
+
<% end %>
|
|
11
|
+
<a class="hrl-small" href="<%= hr_lite.calendar_path %>">Company calendar</a>
|
|
12
|
+
</section>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<% content_for(:page_title) { "Holidays" } %>
|
|
2
|
+
<div class="hrl-page__head">
|
|
3
|
+
<h1 class="hrl-page__title">Holidays <%= @year %></h1>
|
|
4
|
+
<div class="hrl-page__actions">
|
|
5
|
+
<a class="hrl-btn" href="<%= hr_lite.holidays_path(year: @year - 1) %>"><%= @year - 1 %></a>
|
|
6
|
+
<a class="hrl-btn" href="<%= hr_lite.holidays_path(year: @year + 1) %>"><%= @year + 1 %></a>
|
|
7
|
+
<a class="hrl-btn" href="<%= hr_lite.calendar_path %>">Calendar</a>
|
|
8
|
+
</div>
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
<section class="hrl-card">
|
|
12
|
+
<% if @holidays.any? %>
|
|
13
|
+
<div class="hrl-table-wrap">
|
|
14
|
+
<table class="hrl-table hrl-table--stack">
|
|
15
|
+
<thead><tr><th>Date</th><th>Holiday</th><th></th></tr></thead>
|
|
16
|
+
<tbody>
|
|
17
|
+
<% @holidays.each do |holiday| %>
|
|
18
|
+
<tr>
|
|
19
|
+
<td data-label="Date"><%= holiday.date.strftime("%a, %d %b") %></td>
|
|
20
|
+
<td data-label="Holiday"><%= holiday.name %></td>
|
|
21
|
+
<td data-label=""><% if holiday.optional %><span class="hrl-badge hrl-badge--muted">Optional</span><% end %></td>
|
|
22
|
+
</tr>
|
|
23
|
+
<% end %>
|
|
24
|
+
</tbody>
|
|
25
|
+
</table>
|
|
26
|
+
</div>
|
|
27
|
+
<% else %>
|
|
28
|
+
<p class="hrl-card--empty">No holidays recorded for <%= @year %>.</p>
|
|
29
|
+
<% end %>
|
|
30
|
+
</section>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<div class="hrl-page__head">
|
|
2
|
+
<h1 class="hrl-page__title">Hello, <%= hr_display_name(hr_current_user) %></h1>
|
|
3
|
+
</div>
|
|
4
|
+
|
|
5
|
+
<div class="hrl-grid hrl-grid--2">
|
|
6
|
+
<%= render "hr_lite/attendance/punch_card" %>
|
|
7
|
+
<%= render "hr_lite/leave_requests/balance_chips" %>
|
|
8
|
+
<%= render "hr_lite/holidays/next_holiday" %>
|
|
9
|
+
|
|
10
|
+
<section class="hrl-card">
|
|
11
|
+
<h2 class="hrl-card__title">Latest kudos</h2>
|
|
12
|
+
<% if @latest_kudos.any? %>
|
|
13
|
+
<div class="hrl-feed">
|
|
14
|
+
<%= render partial: "hr_lite/kudos/kudo", collection: @latest_kudos %>
|
|
15
|
+
</div>
|
|
16
|
+
<% else %>
|
|
17
|
+
<p class="hrl-muted hrl-small">No kudos yet — be the first to appreciate a teammate.</p>
|
|
18
|
+
<% end %>
|
|
19
|
+
<a class="hrl-btn hrl-mt" href="<%= hr_lite.kudos_path %>">Give kudos</a>
|
|
20
|
+
</section>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<% content_for :scripts do %>
|
|
24
|
+
<%= javascript_include_tag "hr_lite/geo_punch", defer: true %>
|
|
25
|
+
<% end %>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<div class="hrl-feed__item" id="kudo_<%= kudo.id %>">
|
|
2
|
+
<span class="hrl-avatar" aria-hidden="true"><%= hr_display_name(kudo.giver).first(1).upcase %></span>
|
|
3
|
+
<div class="hrl-feed__body">
|
|
4
|
+
<div class="hrl-row">
|
|
5
|
+
<strong><%= hr_display_name(kudo.giver) %></strong>
|
|
6
|
+
<% if kudo.badge_label %>
|
|
7
|
+
<span class="hrl-badge"><%= kudo.badge_label %></span>
|
|
8
|
+
<% end %>
|
|
9
|
+
<span class="hrl-feed__meta hrl-right"><%= time_ago_in_words(kudo.created_at) %> ago</span>
|
|
10
|
+
</div>
|
|
11
|
+
<p><%= render_kudo_message(kudo) %></p>
|
|
12
|
+
<% if kudo.deletable_by?(hr_current_user) %>
|
|
13
|
+
<%= button_to "Remove", hr_lite.kudo_path(kudo), method: :delete, class: "hrl-btn hrl-btn--danger hrl-small",
|
|
14
|
+
form: { data: { turbo_confirm: "Remove this kudos?" } } %>
|
|
15
|
+
<% end %>
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<div class="hrl-page__head">
|
|
2
|
+
<h1 class="hrl-page__title">Kudos wall</h1>
|
|
3
|
+
<p class="hrl-page__sub">Appreciate teammates publicly. Mention people with @ — they get notified.</p>
|
|
4
|
+
</div>
|
|
5
|
+
|
|
6
|
+
<section class="hrl-card">
|
|
7
|
+
<%= form_with model: @kudo, url: hr_lite.kudos_path, local: true do |f| %>
|
|
8
|
+
<%= render "hr_lite/shared/form_errors", record: @kudo %>
|
|
9
|
+
<div class="hrl-field">
|
|
10
|
+
<%= f.label :message, "Say something nice" %>
|
|
11
|
+
<div class="hrl-mention-wrap" data-hrl-mention data-search-url="<%= hr_lite.users_search_path %>">
|
|
12
|
+
<%= f.text_area :message, placeholder: "Type @ to mention a teammate…", maxlength: 1000 %>
|
|
13
|
+
</div>
|
|
14
|
+
</div>
|
|
15
|
+
<div class="hrl-field">
|
|
16
|
+
<%= f.label :badge, "Badge (optional)" %>
|
|
17
|
+
<div class="hrl-chiprow">
|
|
18
|
+
<% HrLite::Kudo::BADGES.each do |key, label| %>
|
|
19
|
+
<label><%= f.radio_button :badge, key %><span><%= label %></span></label>
|
|
20
|
+
<% end %>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
<div class="hrl-form-actions">
|
|
24
|
+
<%= f.submit "Post kudos", class: "hrl-btn hrl-btn--primary" %>
|
|
25
|
+
</div>
|
|
26
|
+
<% end %>
|
|
27
|
+
</section>
|
|
28
|
+
|
|
29
|
+
<section class="hrl-card">
|
|
30
|
+
<% if @kudos.any? %>
|
|
31
|
+
<div class="hrl-feed">
|
|
32
|
+
<%= render partial: "hr_lite/kudos/kudo", collection: @kudos %>
|
|
33
|
+
</div>
|
|
34
|
+
<% else %>
|
|
35
|
+
<p class="hrl-card--empty">No kudos yet. Start the wall.</p>
|
|
36
|
+
<% end %>
|
|
37
|
+
</section>
|
|
38
|
+
|
|
39
|
+
<%= hrl_pagination %>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<% content_for(:page_title) { "Leave balances" } %>
|
|
2
|
+
<div class="hrl-page__head">
|
|
3
|
+
<h1 class="hrl-page__title">Leave balances <%= @year %></h1>
|
|
4
|
+
</div>
|
|
5
|
+
|
|
6
|
+
<div class="hrl-grid hrl-grid--2">
|
|
7
|
+
<% @balances.each do |balance| %>
|
|
8
|
+
<section class="hrl-card">
|
|
9
|
+
<h2 class="hrl-card__title"><%= balance.leave_type.name %></h2>
|
|
10
|
+
<dl class="hrl-deflist">
|
|
11
|
+
<dt>Entitled</dt><dd><%= balance.entitled.to_f %></dd>
|
|
12
|
+
<dt>Used</dt><dd><%= balance.used.to_f %></dd>
|
|
13
|
+
<dt>Available</dt><dd><strong><%= balance.available.to_f %></strong></dd>
|
|
14
|
+
<% if balance.carried_forward.positive? %><dt>Carried forward</dt><dd><%= balance.carried_forward.to_f %></dd><% end %>
|
|
15
|
+
<% if balance.adjustment.nonzero? %><dt>Adjustments</dt><dd><%= balance.adjustment.to_f %> <span class="hrl-muted hrl-small"><%= balance.adjustment_note %></span></dd><% end %>
|
|
16
|
+
</dl>
|
|
17
|
+
</section>
|
|
18
|
+
<% end %>
|
|
19
|
+
</div>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<section class="hrl-card">
|
|
2
|
+
<h2 class="hrl-card__title">Leave balance <%= Date.current.year %></h2>
|
|
3
|
+
<% types = HrLite::LeaveType.active.where(paid: true).where.not(annual_quota: nil) %>
|
|
4
|
+
<% if types.any? %>
|
|
5
|
+
<div class="hrl-row">
|
|
6
|
+
<% types.each do |type| %>
|
|
7
|
+
<% balance = HrLite::LeaveBalance.for(hr_current_user, type, Date.current.year) %>
|
|
8
|
+
<span class="hrl-badge" style="background: <%= type.color %>1f; color: <%= type.color %>;">
|
|
9
|
+
<%= type.code %> <%= balance.available.to_f %>/<%= balance.entitled.to_f %>
|
|
10
|
+
</span>
|
|
11
|
+
<% end %>
|
|
12
|
+
</div>
|
|
13
|
+
<a class="hrl-btn hrl-mt" href="<%= hr_lite.new_leave_request_path %>">Apply for leave</a>
|
|
14
|
+
<% else %>
|
|
15
|
+
<p class="hrl-muted hrl-small">No leave types configured yet.</p>
|
|
16
|
+
<% end %>
|
|
17
|
+
</section>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<% content_for(:page_title) { "Leaves" } %>
|
|
2
|
+
<div class="hrl-page__head">
|
|
3
|
+
<h1 class="hrl-page__title">My leaves</h1>
|
|
4
|
+
<div class="hrl-page__actions">
|
|
5
|
+
<a class="hrl-btn hrl-btn--primary" href="<%= hr_lite.new_leave_request_path %>">Apply</a>
|
|
6
|
+
</div>
|
|
7
|
+
</div>
|
|
8
|
+
|
|
9
|
+
<%= render "hr_lite/leave_requests/balance_chips" %>
|
|
10
|
+
|
|
11
|
+
<section class="hrl-card">
|
|
12
|
+
<% if @requests.any? %>
|
|
13
|
+
<div class="hrl-table-wrap">
|
|
14
|
+
<table class="hrl-table hrl-table--stack">
|
|
15
|
+
<thead><tr><th>Type</th><th>Dates</th><th>Days</th><th>Status</th><th></th></tr></thead>
|
|
16
|
+
<tbody>
|
|
17
|
+
<% @requests.each do |request| %>
|
|
18
|
+
<tr>
|
|
19
|
+
<td data-label="Type"><span class="hrl-badge" style="background: <%= request.leave_type.color %>1f; color: <%= request.leave_type.color %>;"><%= request.leave_type.code %></span></td>
|
|
20
|
+
<td data-label="Dates"><%= request.date_range_label %></td>
|
|
21
|
+
<td data-label="Days" class="hrl-num"><%= request.days_count.to_f %></td>
|
|
22
|
+
<td data-label="Status">
|
|
23
|
+
<span class="hrl-badge <%= { "approved" => "hrl-badge--ok", "rejected" => "hrl-badge--bad", "cancelled" => "hrl-badge--muted" }[request.status] %>"><%= request.status.humanize %></span>
|
|
24
|
+
</td>
|
|
25
|
+
<td data-label="">
|
|
26
|
+
<a class="hrl-small" href="<%= hr_lite.leave_request_path(request) %>">View</a>
|
|
27
|
+
</td>
|
|
28
|
+
</tr>
|
|
29
|
+
<% end %>
|
|
30
|
+
</tbody>
|
|
31
|
+
</table>
|
|
32
|
+
</div>
|
|
33
|
+
<%= hrl_pagination %>
|
|
34
|
+
<% else %>
|
|
35
|
+
<p class="hrl-card--empty">No leave requests yet.</p>
|
|
36
|
+
<% end %>
|
|
37
|
+
</section>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<% content_for(:page_title) { "Apply for leave" } %>
|
|
2
|
+
<div class="hrl-page__head">
|
|
3
|
+
<h1 class="hrl-page__title">Apply for leave</h1>
|
|
4
|
+
</div>
|
|
5
|
+
|
|
6
|
+
<%= render "hr_lite/leave_requests/balance_chips" %>
|
|
7
|
+
|
|
8
|
+
<section class="hrl-card">
|
|
9
|
+
<%= form_with model: @request, url: hr_lite.leave_requests_path, local: true do |f| %>
|
|
10
|
+
<%= render "hr_lite/shared/form_errors", record: @request %>
|
|
11
|
+
<div class="hrl-field">
|
|
12
|
+
<%= f.label :leave_type_id, "Type" %>
|
|
13
|
+
<%= f.collection_select :leave_type_id, HrLite::LeaveType.active, :id, :name %>
|
|
14
|
+
</div>
|
|
15
|
+
<div class="hrl-field">
|
|
16
|
+
<%= f.label :start_date, "From" %>
|
|
17
|
+
<%= f.date_field :start_date %>
|
|
18
|
+
</div>
|
|
19
|
+
<div class="hrl-field">
|
|
20
|
+
<%= f.label :end_date, "To" %>
|
|
21
|
+
<%= f.date_field :end_date %>
|
|
22
|
+
</div>
|
|
23
|
+
<div class="hrl-field hrl-field--check">
|
|
24
|
+
<%= f.check_box :half_day %>
|
|
25
|
+
<%= f.label :half_day, "Half day (single-day requests only)" %>
|
|
26
|
+
</div>
|
|
27
|
+
<div class="hrl-field">
|
|
28
|
+
<%= f.label :reason, "Reason (optional)" %>
|
|
29
|
+
<%= f.text_area :reason %>
|
|
30
|
+
</div>
|
|
31
|
+
<div class="hrl-form-actions">
|
|
32
|
+
<%= f.submit "Submit request", class: "hrl-btn hrl-btn--primary" %>
|
|
33
|
+
<a class="hrl-btn" href="<%= hr_lite.leave_requests_path %>">Cancel</a>
|
|
34
|
+
</div>
|
|
35
|
+
<% end %>
|
|
36
|
+
</section>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<% content_for(:page_title) { "Leave request" } %>
|
|
2
|
+
<div class="hrl-page__head">
|
|
3
|
+
<h1 class="hrl-page__title">Leave request</h1>
|
|
4
|
+
<div class="hrl-page__actions">
|
|
5
|
+
<a class="hrl-btn" href="<%= hr_lite.leave_requests_path %>">Back</a>
|
|
6
|
+
</div>
|
|
7
|
+
</div>
|
|
8
|
+
|
|
9
|
+
<section class="hrl-card">
|
|
10
|
+
<dl class="hrl-deflist">
|
|
11
|
+
<dt>Type</dt><dd><%= @request.leave_type.name %></dd>
|
|
12
|
+
<dt>Dates</dt><dd><%= @request.date_range_label %></dd>
|
|
13
|
+
<dt>Days</dt><dd><%= @request.days_count.to_f %></dd>
|
|
14
|
+
<dt>Status</dt><dd><span class="hrl-badge"><%= @request.status.humanize %></span></dd>
|
|
15
|
+
<% if @request.reason.present? %><dt>Reason</dt><dd><%= @request.reason %></dd><% end %>
|
|
16
|
+
<% if @request.decision_note.present? %><dt>Decision note</dt><dd><%= @request.decision_note %></dd><% end %>
|
|
17
|
+
<% if @request.decided_at %><dt>Decided</dt><dd><%= @request.decided_at.strftime("%d %b %Y") %> by <%= hr_display_name(@request.decided_by) %></dd><% end %>
|
|
18
|
+
</dl>
|
|
19
|
+
|
|
20
|
+
<% if @request.cancellable_by?(hr_current_user) %>
|
|
21
|
+
<%= button_to "Cancel this leave", hr_lite.cancel_leave_request_path(@request), method: :post,
|
|
22
|
+
class: "hrl-btn hrl-btn--danger hrl-mt",
|
|
23
|
+
form: { data: { turbo_confirm: "Cancel this leave request?" } } %>
|
|
24
|
+
<% end %>
|
|
25
|
+
</section>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<%# locals: slip, profile — shared by employee show, admin show %>
|
|
2
|
+
<div class="hrl-grid hrl-grid--2">
|
|
3
|
+
<section class="hrl-card">
|
|
4
|
+
<h2 class="hrl-card__title">Earnings</h2>
|
|
5
|
+
<div class="hrl-table-wrap">
|
|
6
|
+
<table class="hrl-table">
|
|
7
|
+
<thead><tr><th>Component</th><th class="hrl-num">Full</th><th class="hrl-num">Earned</th></tr></thead>
|
|
8
|
+
<tbody>
|
|
9
|
+
<% slip.earnings_rows.each do |row| %>
|
|
10
|
+
<tr>
|
|
11
|
+
<td><%= row["label"] %></td>
|
|
12
|
+
<td class="hrl-num"><%= hrl_money(row["full_amount"]) %></td>
|
|
13
|
+
<td class="hrl-num"><%= hrl_money(row["amount"]) %></td>
|
|
14
|
+
</tr>
|
|
15
|
+
<% end %>
|
|
16
|
+
<tr><td><strong>Gross</strong></td><td></td><td class="hrl-num"><strong><%= hrl_money(slip.gross_earnings) %></strong></td></tr>
|
|
17
|
+
</tbody>
|
|
18
|
+
</table>
|
|
19
|
+
</div>
|
|
20
|
+
</section>
|
|
21
|
+
|
|
22
|
+
<section class="hrl-card">
|
|
23
|
+
<h2 class="hrl-card__title">Deductions</h2>
|
|
24
|
+
<div class="hrl-table-wrap">
|
|
25
|
+
<table class="hrl-table">
|
|
26
|
+
<tbody>
|
|
27
|
+
<% slip.deductions_rows.each do |row| %>
|
|
28
|
+
<tr><td><%= row["label"] %></td><td class="hrl-num"><%= hrl_money(row["amount"]) %></td></tr>
|
|
29
|
+
<% end %>
|
|
30
|
+
<tr><td><strong>Total deductions</strong></td><td class="hrl-num"><strong><%= hrl_money(slip.total_deductions) %></strong></td></tr>
|
|
31
|
+
</tbody>
|
|
32
|
+
</table>
|
|
33
|
+
</div>
|
|
34
|
+
</section>
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
<section class="hrl-card">
|
|
38
|
+
<dl class="hrl-deflist">
|
|
39
|
+
<dt>Net pay</dt><dd><strong><%= hrl_money(slip.net_pay) %></strong> (<%= hrl_amount_in_words(slip.net_pay) %>)</dd>
|
|
40
|
+
<dt>Days</dt><dd><%= slip.payable_days %> payable / <%= slip.effective_lop_days %> LOP of <%= slip.days_in_month %></dd>
|
|
41
|
+
<% if profile %>
|
|
42
|
+
<dt>Employee code</dt><dd><%= profile.employee_code %></dd>
|
|
43
|
+
<% if profile.masked_uan %><dt>PF UAN</dt><dd><%= profile.masked_uan %></dd><% end %>
|
|
44
|
+
<% if profile.masked_pan %><dt>PAN</dt><dd><%= profile.masked_pan %></dd><% end %>
|
|
45
|
+
<% if profile.masked_account %><dt>Bank</dt><dd><%= profile.bank_name %> <%= profile.masked_account %></dd><% end %>
|
|
46
|
+
<% end %>
|
|
47
|
+
</dl>
|
|
48
|
+
</section>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<% content_for(:page_title) { "Salary slips" } %>
|
|
2
|
+
<div class="hrl-page__head">
|
|
3
|
+
<h1 class="hrl-page__title">My salary slips</h1>
|
|
4
|
+
</div>
|
|
5
|
+
|
|
6
|
+
<section class="hrl-card">
|
|
7
|
+
<% if @slips.any? %>
|
|
8
|
+
<div class="hrl-table-wrap">
|
|
9
|
+
<table class="hrl-table hrl-table--stack">
|
|
10
|
+
<thead><tr><th>Period</th><th>Net pay</th><th></th></tr></thead>
|
|
11
|
+
<tbody>
|
|
12
|
+
<% @slips.each do |slip| %>
|
|
13
|
+
<tr>
|
|
14
|
+
<td data-label="Period"><%= slip.period_month.strftime("%B %Y") %></td>
|
|
15
|
+
<td data-label="Net pay" class="hrl-num"><strong><%= hrl_money(slip.net_pay) %></strong></td>
|
|
16
|
+
<td data-label="">
|
|
17
|
+
<a class="hrl-btn" href="<%= hr_lite.salary_slip_path(slip) %>">View</a>
|
|
18
|
+
<a class="hrl-btn" href="<%= hr_lite.salary_slip_path(slip, format: :pdf) %>">PDF</a>
|
|
19
|
+
</td>
|
|
20
|
+
</tr>
|
|
21
|
+
<% end %>
|
|
22
|
+
</tbody>
|
|
23
|
+
</table>
|
|
24
|
+
</div>
|
|
25
|
+
<%= hrl_pagination %>
|
|
26
|
+
<% else %>
|
|
27
|
+
<p class="hrl-card--empty">No published salary slips yet.</p>
|
|
28
|
+
<% end %>
|
|
29
|
+
</section>
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
<% company = HrLite.config.company.call %>
|
|
2
|
+
<div class="pdf-card">
|
|
3
|
+
<div class="pdf-head">
|
|
4
|
+
<div>
|
|
5
|
+
<div class="pdf-company"><%= company[:name] %></div>
|
|
6
|
+
<% if company[:address].present? %><div class="pdf-muted"><%= company[:address] %></div><% end %>
|
|
7
|
+
</div>
|
|
8
|
+
<div style="text-align:right;">
|
|
9
|
+
<h1>Salary slip</h1>
|
|
10
|
+
<div class="pdf-muted"><%= @slip.period_month.strftime("%B %Y") %></div>
|
|
11
|
+
</div>
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
<table>
|
|
15
|
+
<tbody>
|
|
16
|
+
<tr>
|
|
17
|
+
<td><strong><%= HrLite.display_name(@slip.user) %></strong>
|
|
18
|
+
<% if @profile&.designation.present? %> · <%= @profile.designation %><% end %></td>
|
|
19
|
+
<td class="num">Employee code: <%= @profile&.employee_code || "—" %></td>
|
|
20
|
+
</tr>
|
|
21
|
+
<tr>
|
|
22
|
+
<td>
|
|
23
|
+
<% if @profile&.department.present? %>Dept: <%= @profile.department %> · <% end %>
|
|
24
|
+
<% if @profile&.date_of_joining %>DOJ: <%= @profile.date_of_joining.strftime("%d %b %Y") %><% end %>
|
|
25
|
+
</td>
|
|
26
|
+
<td class="num">
|
|
27
|
+
<% if @profile&.masked_uan %>UAN: <%= @profile.masked_uan %> · <% end %>
|
|
28
|
+
<% if @profile&.masked_pan %>PAN: <%= @profile.masked_pan %><% end %>
|
|
29
|
+
</td>
|
|
30
|
+
</tr>
|
|
31
|
+
<tr>
|
|
32
|
+
<td>Payable days: <%= @slip.payable_days %> / <%= @slip.days_in_month %> (LOP <%= @slip.effective_lop_days %>)</td>
|
|
33
|
+
<td class="num"><% if @profile&.masked_account %>Bank: <%= @profile.bank_name %> <%= @profile.masked_account %><% end %></td>
|
|
34
|
+
</tr>
|
|
35
|
+
</tbody>
|
|
36
|
+
</table>
|
|
37
|
+
|
|
38
|
+
<div class="cols">
|
|
39
|
+
<div>
|
|
40
|
+
<table>
|
|
41
|
+
<thead><tr><th>Earnings</th><th class="num">Full</th><th class="num">Earned</th></tr></thead>
|
|
42
|
+
<tbody>
|
|
43
|
+
<% @slip.earnings_rows.each do |row| %>
|
|
44
|
+
<tr><td><%= row["label"] %></td><td class="num"><%= row["full_amount"] %></td><td class="num"><%= row["amount"] %></td></tr>
|
|
45
|
+
<% end %>
|
|
46
|
+
<tr class="total"><td>Gross</td><td></td><td class="num"><%= @slip.gross_earnings.to_s("F") %></td></tr>
|
|
47
|
+
</tbody>
|
|
48
|
+
</table>
|
|
49
|
+
</div>
|
|
50
|
+
<div>
|
|
51
|
+
<table>
|
|
52
|
+
<thead><tr><th>Deductions</th><th class="num">Amount</th></tr></thead>
|
|
53
|
+
<tbody>
|
|
54
|
+
<% @slip.deductions_rows.each do |row| %>
|
|
55
|
+
<tr><td><%= row["label"] %></td><td class="num"><%= row["amount"] %></td></tr>
|
|
56
|
+
<% end %>
|
|
57
|
+
<tr class="total"><td>Total deductions</td><td class="num"><%= @slip.total_deductions.to_s("F") %></td></tr>
|
|
58
|
+
</tbody>
|
|
59
|
+
</table>
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
|
|
63
|
+
<div class="pdf-net">
|
|
64
|
+
Net pay: <%= HrLite.config.currency_symbol %><%= @slip.net_pay.to_s("F") %>
|
|
65
|
+
(<%= hrl_amount_in_words(@slip.net_pay) %>)
|
|
66
|
+
</div>
|
|
67
|
+
|
|
68
|
+
<p class="pdf-foot">
|
|
69
|
+
Computer-generated payslip — no signature required. Statutory figures are computed on a
|
|
70
|
+
projection basis; verify with your accountant. Generated <%= Time.current.strftime("%d %b %Y") %>.
|
|
71
|
+
</p>
|
|
72
|
+
</div>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<% content_for(:page_title) { "Slip #{@slip.period_month.strftime('%b %Y')}" } %>
|
|
2
|
+
<div class="hrl-page__head">
|
|
3
|
+
<h1 class="hrl-page__title">Salary slip — <%= @slip.period_month.strftime("%B %Y") %></h1>
|
|
4
|
+
<div class="hrl-page__actions">
|
|
5
|
+
<a class="hrl-btn" href="<%= hr_lite.salary_slips_path %>">All slips</a>
|
|
6
|
+
<a class="hrl-btn hrl-btn--primary" href="<%= hr_lite.salary_slip_path(@slip, format: :pdf) %>">Download PDF</a>
|
|
7
|
+
</div>
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
<%= render "hr_lite/salary_slips/slip_detail", slip: @slip, profile: @slip.user_profile %>
|
|
11
|
+
|
|
12
|
+
<p class="hrl-small hrl-muted">Computer-generated payslip. Verify statutory figures with your accountant.</p>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<% if record.errors.any? %>
|
|
2
|
+
<div class="hrl-errors">
|
|
3
|
+
<strong><%= pluralize(record.errors.count, "problem") %> prevented saving:</strong>
|
|
4
|
+
<ul>
|
|
5
|
+
<% record.errors.full_messages.each do |message| %>
|
|
6
|
+
<li><%= message %></li>
|
|
7
|
+
<% end %>
|
|
8
|
+
</ul>
|
|
9
|
+
</div>
|
|
10
|
+
<% end %>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<% if (@total_pages || 1) > 1 %>
|
|
2
|
+
<nav class="hrl-pager" aria-label="Pagination">
|
|
3
|
+
<% if @page > 1 %>
|
|
4
|
+
<%= link_to "Previous", url_for(request.query_parameters.merge(page: @page - 1)), class: "hrl-btn" %>
|
|
5
|
+
<% end %>
|
|
6
|
+
<span class="hrl-pager__info">Page <%= @page %> of <%= @total_pages %> (<%= @total_count %>)</span>
|
|
7
|
+
<% if @page < @total_pages %>
|
|
8
|
+
<%= link_to "Next", url_for(request.query_parameters.merge(page: @page + 1)), class: "hrl-btn" %>
|
|
9
|
+
<% end %>
|
|
10
|
+
</nav>
|
|
11
|
+
<% end %>
|