hr_lite 0.4.0 → 0.5.2
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 +173 -1
- data/README.md +312 -99
- data/app/assets/javascripts/hr_lite/confirm.js +31 -0
- data/app/assets/stylesheets/hr_lite/hr_lite.css +28 -0
- data/app/controllers/hr_lite/admin/appraisals_controller.rb +1 -1
- data/app/controllers/hr_lite/admin/attendances_controller.rb +16 -1
- data/app/controllers/hr_lite/admin/audit_logs_controller.rb +4 -1
- data/app/controllers/hr_lite/admin/designation_changes_controller.rb +1 -1
- data/app/controllers/hr_lite/admin/employees_controller.rb +37 -13
- data/app/controllers/hr_lite/admin/leave_balances_controller.rb +15 -8
- data/app/controllers/hr_lite/admin/leave_requests_controller.rb +16 -0
- data/app/controllers/hr_lite/admin/payroll_runs_controller.rb +1 -1
- data/app/controllers/hr_lite/admin/resignations_controller.rb +17 -5
- data/app/controllers/hr_lite/admin/salary_slips_controller.rb +18 -3
- data/app/controllers/hr_lite/admin/salary_structures_controller.rb +1 -1
- data/app/controllers/hr_lite/admin/settings_controller.rb +1 -1
- data/app/controllers/hr_lite/admin/superadmin_controller.rb +21 -0
- data/app/controllers/hr_lite/application_controller.rb +5 -1
- data/app/controllers/hr_lite/org_controller.rb +6 -1
- data/app/controllers/hr_lite/resignations_controller.rb +6 -1
- data/app/helpers/hr_lite/application_helper.rb +7 -13
- data/app/jobs/hr_lite/application_job.rb +5 -0
- data/app/jobs/hr_lite/daily_digest_job.rb +1 -1
- data/app/jobs/hr_lite/leave_year_rollover_job.rb +1 -1
- data/app/jobs/hr_lite/payroll_auto_draft_job.rb +5 -2
- data/app/models/concerns/hr_lite/audited.rb +11 -4
- data/app/models/hr_lite/appraisal.rb +9 -1
- data/app/models/hr_lite/audit_log.rb +11 -0
- data/app/models/hr_lite/comp_off_request.rb +5 -15
- data/app/models/hr_lite/designation_change.rb +18 -1
- data/app/models/hr_lite/employee_profile.rb +26 -1
- data/app/models/hr_lite/leave_balance.rb +51 -5
- data/app/models/hr_lite/leave_request.rb +9 -1
- data/app/models/hr_lite/leave_type.rb +13 -3
- data/app/models/hr_lite/payroll_run.rb +39 -10
- data/app/models/hr_lite/regularization_request.rb +8 -0
- data/app/models/hr_lite/resignation.rb +27 -0
- data/app/models/hr_lite/salary_slip.rb +7 -3
- data/app/models/hr_lite/setting.rb +2 -0
- data/app/services/hr_lite/attendance_puncher.rb +8 -1
- data/app/services/hr_lite/calculators/esi.rb +7 -4
- data/app/services/hr_lite/calculators/professional_tax.rb +5 -1
- data/app/services/hr_lite/calculators/tds.rb +8 -1
- data/app/services/hr_lite/leave_day_counter.rb +9 -4
- data/app/services/hr_lite/overview_query.rb +12 -1
- data/app/services/hr_lite/payroll_run_processor.rb +5 -0
- data/app/services/hr_lite/slip_builder.rb +54 -8
- data/app/views/hr_lite/admin/attendances/index.html.erb +4 -1
- data/app/views/hr_lite/admin/comp_off_requests/show.html.erb +19 -5
- data/app/views/hr_lite/admin/employees/_form.html.erb +30 -3
- data/app/views/hr_lite/admin/employees/index.html.erb +3 -0
- data/app/views/hr_lite/admin/employees/show.html.erb +34 -18
- data/app/views/hr_lite/admin/leave_requests/show.html.erb +37 -5
- data/app/views/hr_lite/admin/overview/index.html.erb +21 -0
- data/app/views/hr_lite/admin/payroll_runs/show.html.erb +3 -1
- data/app/views/hr_lite/admin/regularization_requests/show.html.erb +18 -4
- data/app/views/hr_lite/admin/settings/edit.html.erb +7 -0
- data/app/views/hr_lite/attendance/_punch_card.html.erb +22 -2
- data/app/views/hr_lite/career/show.html.erb +7 -1
- data/app/views/hr_lite/salary_slips/_slip_detail.html.erb +5 -1
- data/app/views/hr_lite/salary_slips/pdf.html.erb +5 -5
- data/app/views/layouts/hr_lite/application.html.erb +47 -4
- data/config/routes.rb +1 -1
- data/db/migrate/20260720094454_add_employee_code_prefix_to_hr_lite_settings.rb +7 -0
- data/db/migrate/20260807184103_add_live_uniqueness_indexes_to_hr_lite.rb +28 -0
- data/db/migrate/20260807184426_add_fy_opening_to_hr_lite_employee_profiles.rb +14 -0
- data/db/migrate/20260807184939_add_out_of_window_days_to_hr_lite_salary_slips.rb +12 -0
- data/lib/hr_lite/amount_in_words.rb +15 -2
- data/lib/hr_lite/configuration.rb +8 -0
- data/lib/hr_lite/money.rb +18 -0
- data/lib/hr_lite/notifications.rb +23 -8
- data/lib/hr_lite/statutory_rate_card.rb +6 -1
- data/lib/hr_lite/version.rb +1 -1
- data/lib/hr_lite.rb +9 -1
- metadata +7 -1
data/lib/hr_lite/money.rb
CHANGED
|
@@ -29,5 +29,23 @@ module HrLite
|
|
|
29
29
|
def round_to_10(value)
|
|
30
30
|
(d(value) / 10).round(0, BigDecimal::ROUND_HALF_UP) * 10
|
|
31
31
|
end
|
|
32
|
+
|
|
33
|
+
# Indian digit grouping: 12,34,567 — not the western 1,234,567. It lives
|
|
34
|
+
# here rather than only in the view helper because the slip PDF is
|
|
35
|
+
# rendered by HOST code (config.render_pdf), where engine helpers are out
|
|
36
|
+
# of scope — which is why the PDF printed a bare "75000.0" next to the
|
|
37
|
+
# web slip's "₹75,000.00".
|
|
38
|
+
def format(amount)
|
|
39
|
+
return "—" if amount.nil?
|
|
40
|
+
|
|
41
|
+
whole, fraction = round2(amount).to_s("F").split(".")
|
|
42
|
+
sign = whole.start_with?("-") ? "-" : ""
|
|
43
|
+
whole = whole.delete_prefix("-")
|
|
44
|
+
if whole.length > 3
|
|
45
|
+
head = whole[0..-4].reverse.scan(/\d{1,2}/).join(",").reverse
|
|
46
|
+
whole = "#{head},#{whole[-3..]}"
|
|
47
|
+
end
|
|
48
|
+
"#{sign}#{HrLite.config.currency_symbol}#{whole}.#{fraction.ljust(2, '0')}"
|
|
49
|
+
end
|
|
32
50
|
end
|
|
33
51
|
end
|
|
@@ -49,17 +49,27 @@ module HrLite
|
|
|
49
49
|
DEFAULT_MATRIX.merge(HrLite.config.notification_matrix || {})
|
|
50
50
|
end
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
# `leadership:` overrides title/body/path for the leadership copies of an
|
|
53
|
+
# event. Some events are written in the second person and point at an
|
|
54
|
+
# employee-scoped path ("Your appraisal has been shared", /appraisals/7):
|
|
55
|
+
# fanned out verbatim, leadership read them as being about themselves and
|
|
56
|
+
# followed a link their own scope 404s or resolves to their own record.
|
|
57
|
+
def publish(event, title:, body: nil, path: nil, bell_to: [], email_to: [], lines: [],
|
|
58
|
+
diff: nil, link_url: nil, leadership: {})
|
|
53
59
|
row = matrix[event.to_s]
|
|
54
60
|
unless row
|
|
55
61
|
Rails.logger.warn("[hr_lite] unknown notification event #{event}")
|
|
56
62
|
return
|
|
57
63
|
end
|
|
58
64
|
|
|
65
|
+
lead_title = leadership[:title] || title
|
|
66
|
+
lead_body = leadership.key?(:body) ? leadership[:body] : body
|
|
67
|
+
lead_path = leadership[:path] || path
|
|
68
|
+
|
|
59
69
|
deliver_bells(event, row, bell_to, title, body, path)
|
|
60
70
|
deliver_emails(row, email_to, title, body, path, lines, link_url)
|
|
61
|
-
deliver_leadership_email(event, row,
|
|
62
|
-
deliver_leadership_bells(event, row, bell_to,
|
|
71
|
+
deliver_leadership_email(event, row, lead_title, lead_body, lead_path, lines, diff)
|
|
72
|
+
deliver_leadership_bells(event, row, bell_to, lead_title, lead_body, lead_path)
|
|
63
73
|
nil
|
|
64
74
|
end
|
|
65
75
|
|
|
@@ -76,15 +86,20 @@ module HrLite
|
|
|
76
86
|
def deliver_emails(row, email_to, title, body, path, lines, link_url = nil)
|
|
77
87
|
return unless row[:email]
|
|
78
88
|
|
|
89
|
+
# Rescued PER RECIPIENT. Wrapping the whole loop meant one bad address
|
|
90
|
+
# or a single enqueue failure silently dropped everyone after it — on
|
|
91
|
+
# a team-wide leave notice, most of the team.
|
|
79
92
|
Array(email_to).compact.uniq.each do |user|
|
|
80
93
|
next if user.email.blank?
|
|
81
94
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
95
|
+
begin
|
|
96
|
+
EventMailer.event(to: user.email, subject: title, heading: title,
|
|
97
|
+
body: body, lines: lines, path: path,
|
|
98
|
+
link_url: link_url).deliver_later
|
|
99
|
+
rescue => e
|
|
100
|
+
Rails.logger.error("[hr_lite] event email failed: #{e.class}: #{e.message}")
|
|
101
|
+
end
|
|
85
102
|
end
|
|
86
|
-
rescue => e
|
|
87
|
-
Rails.logger.error("[hr_lite] event email failed: #{e.class}: #{e.message}")
|
|
88
103
|
end
|
|
89
104
|
|
|
90
105
|
def deliver_leadership_email(event, row, title, body, path, lines, diff)
|
|
@@ -24,11 +24,16 @@ module HrLite
|
|
|
24
24
|
"none" => [],
|
|
25
25
|
"uttar_pradesh" => [],
|
|
26
26
|
"uttarakhand" => [],
|
|
27
|
-
|
|
27
|
+
# Inclusive lower bounds. `above: 24999` with a strict `>` taxed a
|
|
28
|
+
# prorated gross of ₹24,999.50, which is below the real threshold.
|
|
29
|
+
"karnataka" => [ { from: r("25000"), monthly: r("200") } ]
|
|
28
30
|
},
|
|
29
31
|
income_tax: {
|
|
30
32
|
"new" => {
|
|
31
33
|
standard_deduction: r("75000"), rebate_cap: r("1200000"), cess_rate: r("0.04"),
|
|
34
|
+
# §115BAC carries marginal relief just above the rebate cap; the
|
|
35
|
+
# old regime does not, so this is a per-regime flag.
|
|
36
|
+
marginal_relief: true,
|
|
32
37
|
slabs: [
|
|
33
38
|
[ r("0"), r("400000"), r("0") ],
|
|
34
39
|
[ r("400000"), r("800000"), r("0.05") ],
|
data/lib/hr_lite/version.rb
CHANGED
data/lib/hr_lite.rb
CHANGED
|
@@ -38,6 +38,10 @@ module HrLite
|
|
|
38
38
|
user.present? && !!config.leadership_check.call(user)
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
+
def superadmin?(user)
|
|
42
|
+
user.present? && !!config.superadmin_check.call(user)
|
|
43
|
+
end
|
|
44
|
+
|
|
41
45
|
# Leadership members resolvable to actual user records (for bell
|
|
42
46
|
# notifications). Emails configured but absent from the user table are
|
|
43
47
|
# still reachable by email — see Notifications.
|
|
@@ -48,8 +52,12 @@ module HrLite
|
|
|
48
52
|
user_klass.where("LOWER(#{user_klass.table_name}.email) IN (?)", emails)
|
|
49
53
|
end
|
|
50
54
|
|
|
55
|
+
# Every domain event that bells the admins calls this. Loading and
|
|
56
|
+
# instantiating the entire users table to run admin_check per row is fine
|
|
57
|
+
# at ten staff and silly at a thousand — so it starts from employees_scope
|
|
58
|
+
# (which a host narrows to real staff) rather than every row that exists.
|
|
51
59
|
def admin_users
|
|
52
|
-
|
|
60
|
+
employees.select { |u| admin?(u) }
|
|
53
61
|
end
|
|
54
62
|
|
|
55
63
|
# Everyone HR tracks (host-overridable to exclude bots/test accounts),
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hr_lite
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- kshitiz sinha
|
|
@@ -50,6 +50,7 @@ files:
|
|
|
50
50
|
- MIT-LICENSE
|
|
51
51
|
- README.md
|
|
52
52
|
- Rakefile
|
|
53
|
+
- app/assets/javascripts/hr_lite/confirm.js
|
|
53
54
|
- app/assets/javascripts/hr_lite/geo_punch.js
|
|
54
55
|
- app/assets/javascripts/hr_lite/mention.js
|
|
55
56
|
- app/assets/stylesheets/hr_lite/application.css
|
|
@@ -74,6 +75,7 @@ files:
|
|
|
74
75
|
- app/controllers/hr_lite/admin/salary_slips_controller.rb
|
|
75
76
|
- app/controllers/hr_lite/admin/salary_structures_controller.rb
|
|
76
77
|
- app/controllers/hr_lite/admin/settings_controller.rb
|
|
78
|
+
- app/controllers/hr_lite/admin/superadmin_controller.rb
|
|
77
79
|
- app/controllers/hr_lite/application_controller.rb
|
|
78
80
|
- app/controllers/hr_lite/appraisals_controller.rb
|
|
79
81
|
- app/controllers/hr_lite/attendance_controller.rb
|
|
@@ -236,6 +238,10 @@ files:
|
|
|
236
238
|
- db/migrate/20260719104316_create_hr_lite_comp_off_requests.rb
|
|
237
239
|
- db/migrate/20260719104317_create_hr_lite_regularization_requests.rb
|
|
238
240
|
- db/migrate/20260719162154_add_manager_to_hr_lite_employee_profiles.rb
|
|
241
|
+
- db/migrate/20260720094454_add_employee_code_prefix_to_hr_lite_settings.rb
|
|
242
|
+
- db/migrate/20260807184103_add_live_uniqueness_indexes_to_hr_lite.rb
|
|
243
|
+
- db/migrate/20260807184426_add_fy_opening_to_hr_lite_employee_profiles.rb
|
|
244
|
+
- db/migrate/20260807184939_add_out_of_window_days_to_hr_lite_salary_slips.rb
|
|
239
245
|
- lib/generators/hr_lite/install/install_generator.rb
|
|
240
246
|
- lib/generators/hr_lite/install/templates/AFTER_INSTALL
|
|
241
247
|
- lib/generators/hr_lite/install/templates/initializer.rb
|