hr_lite 0.31.0 → 0.35.1

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.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +30 -0
  3. data/app/assets/javascripts/hr_lite/chart_tip.js +33 -0
  4. data/app/assets/javascripts/hr_lite/countdown.js +12 -0
  5. data/app/assets/javascripts/hr_lite/crm_picker.js +27 -0
  6. data/app/assets/javascripts/hr_lite/emoji_pick.js +11 -0
  7. data/app/assets/stylesheets/hr_lite/hr_lite.css +59 -0
  8. data/app/controllers/hr_lite/admin/attendances_controller.rb +8 -5
  9. data/app/controllers/hr_lite/admin/employees_controller.rb +1 -1
  10. data/app/controllers/hr_lite/admin/holidays_controller.rb +17 -9
  11. data/app/controllers/hr_lite/admin/settings_controller.rb +1 -1
  12. data/app/controllers/hr_lite/admin/work_locations_controller.rb +41 -0
  13. data/app/controllers/hr_lite/admin/work_modes_controller.rb +72 -0
  14. data/app/controllers/hr_lite/admin/work_time_controller.rb +39 -0
  15. data/app/controllers/hr_lite/attendance_controller.rb +2 -1
  16. data/app/controllers/hr_lite/calendar_controller.rb +3 -2
  17. data/app/controllers/hr_lite/comp_off_requests_controller.rb +1 -1
  18. data/app/controllers/hr_lite/holidays_controller.rb +3 -2
  19. data/app/controllers/hr_lite/team_controller.rb +13 -0
  20. data/app/controllers/hr_lite/work_locations_controller.rb +44 -0
  21. data/app/controllers/hr_lite/work_modes_controller.rb +40 -0
  22. data/app/controllers/hr_lite/work_time_controller.rb +14 -0
  23. data/app/helpers/hr_lite/application_helper.rb +43 -2
  24. data/app/jobs/hr_lite/attendance_close_job.rb +12 -5
  25. data/app/jobs/hr_lite/calendar_meeting_start_job.rb +31 -0
  26. data/app/jobs/hr_lite/calendar_meeting_sync_job.rb +55 -0
  27. data/app/jobs/hr_lite/work_mode_expire_job.rb +12 -0
  28. data/app/models/hr_lite/attendance_penalty.rb +2 -2
  29. data/app/models/hr_lite/attendance_record.rb +7 -0
  30. data/app/models/hr_lite/comp_off_request.rb +2 -2
  31. data/app/models/hr_lite/employee_profile.rb +2 -0
  32. data/app/models/hr_lite/holiday.rb +11 -5
  33. data/app/models/hr_lite/leave_balance.rb +1 -1
  34. data/app/models/hr_lite/leave_request.rb +1 -1
  35. data/app/models/hr_lite/regularization_request.rb +1 -1
  36. data/app/models/hr_lite/setting.rb +2 -0
  37. data/app/models/hr_lite/work_location.rb +62 -0
  38. data/app/models/hr_lite/work_mode_event.rb +84 -0
  39. data/app/services/hr_lite/attendance_puncher.rb +60 -19
  40. data/app/services/hr_lite/day_status.rb +1 -1
  41. data/app/services/hr_lite/leave_day_counter.rb +5 -7
  42. data/app/services/hr_lite/team_day.rb +6 -6
  43. data/app/services/hr_lite/today_checkins.rb +41 -0
  44. data/app/services/hr_lite/work_mode_durations.rb +237 -0
  45. data/app/services/hr_lite/work_mode_switch.rb +144 -0
  46. data/app/services/hr_lite/work_status.rb +60 -0
  47. data/app/services/hr_lite/working_calendar.rb +11 -2
  48. data/app/views/hr_lite/admin/attendances/show.html.erb +1 -1
  49. data/app/views/hr_lite/admin/employees/_form.html.erb +7 -1
  50. data/app/views/hr_lite/admin/holidays/index.html.erb +10 -1
  51. data/app/views/hr_lite/admin/settings/edit.html.erb +9 -0
  52. data/app/views/hr_lite/admin/shared/_approvals_tabs.html.erb +4 -1
  53. data/app/views/hr_lite/admin/wfh_requests/index.html.erb +2 -2
  54. data/app/views/hr_lite/admin/work_locations/index.html.erb +42 -0
  55. data/app/views/hr_lite/admin/work_modes/index.html.erb +105 -0
  56. data/app/views/hr_lite/admin/work_time/index.html.erb +42 -0
  57. data/app/views/hr_lite/attendance/_calendar_connection.html.erb +15 -0
  58. data/app/views/hr_lite/attendance/_crm_picker.html.erb +9 -0
  59. data/app/views/hr_lite/attendance/_custom_status.html.erb +26 -0
  60. data/app/views/hr_lite/attendance/_punch_card.html.erb +26 -6
  61. data/app/views/hr_lite/attendance/_work_mode.html.erb +92 -0
  62. data/app/views/hr_lite/attendance/show.html.erb +4 -1
  63. data/app/views/hr_lite/holidays/_next_holiday.html.erb +1 -1
  64. data/app/views/hr_lite/home/_today_checkins.html.erb +31 -0
  65. data/app/views/hr_lite/home/index.html.erb +5 -0
  66. data/app/views/hr_lite/team/show.html.erb +25 -4
  67. data/app/views/hr_lite/work_locations/index.html.erb +52 -0
  68. data/app/views/hr_lite/work_time/_bars.html.erb +44 -0
  69. data/app/views/hr_lite/work_time/_donut.html.erb +36 -0
  70. data/app/views/hr_lite/work_time/_report.html.erb +74 -0
  71. data/app/views/hr_lite/work_time/_timeline.html.erb +26 -0
  72. data/app/views/hr_lite/work_time/show.html.erb +10 -0
  73. data/config/routes.rb +16 -0
  74. data/db/migrate/20261013110000_create_hr_lite_work_locations.rb +23 -0
  75. data/db/migrate/20261013110100_add_work_mode_to_hr_lite_attendance_records.rb +7 -0
  76. data/db/migrate/20261013110200_add_field_staff_to_hr_lite_employee_profiles.rb +5 -0
  77. data/db/migrate/20261013110300_create_hr_lite_work_mode_events.rb +30 -0
  78. data/db/migrate/20261013110400_add_break_minutes_to_hr_lite_settings.rb +6 -0
  79. data/db/migrate/20261013120000_grant_hr_lite_work_analytics.rb +14 -0
  80. data/db/migrate/20261013130000_add_office_location_to_hr_lite_holidays.rb +12 -0
  81. data/db/migrate/20261013130100_add_office_location_to_hr_lite_employee_profiles.rb +6 -0
  82. data/db/migrate/20261013140000_add_calendar_and_crm_to_hr_lite_work_mode_events.rb +9 -0
  83. data/db/migrate/20261013140100_add_custom_status_to_hr_lite_work_mode_events.rb +9 -0
  84. data/lib/hr_lite/configuration.rb +13 -1
  85. data/lib/hr_lite/notifications.rb +9 -4
  86. data/lib/hr_lite/permissions.rb +1 -0
  87. data/lib/hr_lite/role_seeds.rb +4 -2
  88. data/lib/hr_lite/seeds.rb +1 -1
  89. data/lib/hr_lite/version.rb +1 -1
  90. metadata +44 -1
@@ -0,0 +1,6 @@
1
+ class AddOfficeLocationToHrLiteEmployeeProfiles < ActiveRecord::Migration[8.1]
2
+ def change
3
+ add_column :hr_lite_employee_profiles, :office_location_id, :bigint
4
+ add_index :hr_lite_employee_profiles, :office_location_id
5
+ end
6
+ end
@@ -0,0 +1,9 @@
1
+ class AddCalendarAndCrmToHrLiteWorkModeEvents < ActiveRecord::Migration[8.1]
2
+ def change
3
+ add_column :hr_lite_work_mode_events, :calendar_event_id, :string
4
+ add_column :hr_lite_work_mode_events, :crm_ref, :string
5
+ # A calendar meeting opens at most once per person, however often we sync.
6
+ add_index :hr_lite_work_mode_events, [ :user_id, :calendar_event_id ], unique: true,
7
+ where: "calendar_event_id IS NOT NULL", name: "index_hr_lite_work_mode_events_one_per_calendar_event"
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class AddCustomStatusToHrLiteWorkModeEvents < ActiveRecord::Migration[8.1]
2
+ # A third layer: a person's own status ("In Goa till Friday" + an emoji),
3
+ # alongside their work mode and any break or meeting.
4
+ def change
5
+ add_column :hr_lite_work_mode_events, :emoji, :string
6
+ remove_check_constraint :hr_lite_work_mode_events, "layer IN ('primary','overlay')", name: "hr_lite_work_mode_events_layer"
7
+ add_check_constraint :hr_lite_work_mode_events, "layer IN ('primary','overlay','status')", name: "hr_lite_work_mode_events_layer"
8
+ end
9
+ end
@@ -20,7 +20,19 @@ module HrLite
20
20
  # true = check-in slots, late penalties and HR buffers (default off)
21
21
  :attendance_slots,
22
22
  # true = check-in only inside an active office radius, unless WFH is approved for the day
23
- :office_geofence
23
+ :office_geofence,
24
+ # ->(user, from, to) { [{ id:, title:, starts_at:, ends_at: }] } — timed,
25
+ # accepted events; starts Meeting mode by itself. Pairs with calendar_users.
26
+ :calendar_events,
27
+ # -> { user ids with a connected calendar }
28
+ :calendar_users,
29
+ # ->(user) { { connected:, label:, connect_url:, disconnect_url: } or nil } —
30
+ # the one-click "Connect Google Calendar" button (nil = no button)
31
+ :calendar_connection,
32
+ # ->(user, query) { [{ id:, label: }] } — leads to link to a client meeting
33
+ :crm_search,
34
+ # ->(id) { { label:, url: } or nil } — one lead, to validate and link it
35
+ :crm_find
24
36
 
25
37
  attr_reader :leave_year_start_month, :slip_release_day, :self_regularization, :work_hours
26
38
 
@@ -72,7 +72,10 @@ module HrLite
72
72
  "wfh.requested" => { bell: true, email: false, leadership_email: true, leadership_bell: false },
73
73
  "wfh.approved" => { bell: true, email: true, leadership_email: false, leadership_bell: false },
74
74
  "wfh.rejected" => { bell: true, email: true, leadership_email: false, leadership_bell: false },
75
- "wfh.cancelled" => { bell: true, email: false, leadership_email: false, leadership_bell: false }
75
+ "wfh.cancelled" => { bell: true, email: false, leadership_email: false, leadership_bell: false },
76
+ "work_location.requested" => { bell: true, email: false, leadership_email: false, leadership_bell: false },
77
+ "work_location.approved" => { bell: true, email: true, leadership_email: false, leadership_bell: false },
78
+ "work_location.rejected" => { bell: true, email: true, leadership_email: false, leadership_bell: false }
76
79
  }.freeze
77
80
 
78
81
  class << self
@@ -131,9 +134,11 @@ module HrLite
131
134
  next if user.email.blank?
132
135
 
133
136
  begin
134
- EventMailer.event(to: user.email, subject: title, heading: title,
135
- body: body, lines: lines, path: path,
136
- link_url: link_url).deliver_later
137
+ mail = EventMailer.event(to: user.email, subject: title, heading: title,
138
+ body: body, lines: lines, path: path, link_url: link_url)
139
+ # Busy or in a meeting: the email waits until that ends.
140
+ held = WorkStatus.do_not_disturb_until(user.id) if HrLite.config.office_geofence
141
+ held ? mail.deliver_later(wait_until: held) : mail.deliver_later
137
142
  rescue => e
138
143
  Rails.logger.error("[hr_lite] event email failed: #{e.class}: #{e.message}")
139
144
  end
@@ -30,6 +30,7 @@ module HrLite
30
30
  "profile.manage" => [ "People", "Create and edit employee profiles, onboard and offboard" ],
31
31
  "attendance.view" => [ "Attendance", "See attendance records" ],
32
32
  "attendance.manage" => [ "Attendance", "Correct punches and decide regularization tickets" ],
33
+ "work_analytics.view" => [ "Attendance", "See another person's work-time analytics (time per work mode, day timelines)" ],
33
34
  "leave.request" => [ "Leave", "Apply for leave and comp-off" ],
34
35
  "leave.view" => [ "Leave", "See leave requests and balances" ],
35
36
  "leave.approve" => [ "Leave", "Approve, reject and cancel leave and comp-off" ],
@@ -41,7 +41,8 @@ module HrLite
41
41
  "document.view" => "all", "tax.view" => "all", "tax.manage" => "all",
42
42
  "expense.claim" => "self", "benefit.view" => "all", "benefit.manage" => "all",
43
43
  "hr_request.raise" => "self", "hr_request.manage" => "all", "policy.view" => "all",
44
- "asset.view" => "all", "asset.manage" => "all", "checklist.manage" => "all"
44
+ "asset.view" => "all", "asset.manage" => "all", "checklist.manage" => "all",
45
+ "work_analytics.view" => "all"
45
46
  }
46
47
  },
47
48
  Role::FINANCE => {
@@ -67,7 +68,8 @@ module HrLite
67
68
  "settings.manage" => "all", "audit.view" => "all", "payroll.view" => "self",
68
69
  "document.view" => "all", "expense.approve" => "all", "benefit.manage" => "all",
69
70
  "hr_request.manage" => "all", "policy.view" => "all", "policy.manage" => "all",
70
- "asset.view" => "all", "asset.manage" => "all", "checklist.manage" => "all"
71
+ "asset.view" => "all", "asset.manage" => "all", "checklist.manage" => "all",
72
+ "work_analytics.view" => "all"
71
73
  }
72
74
  },
73
75
  Role::CA => {
data/lib/hr_lite/seeds.rb CHANGED
@@ -47,7 +47,7 @@ module HrLite
47
47
  [ Date.new(year, 8, 15), "Independence Day" ],
48
48
  [ Date.new(year, 10, 2), "Gandhi Jayanti" ]
49
49
  ].filter_map do |date, name|
50
- next if Holiday.exists?(date: date)
50
+ next if Holiday.exists?(date: date, office_location_id: nil)
51
51
 
52
52
  Holiday.create!(date: date, name: name)
53
53
  "holiday #{name} #{year}"
@@ -1,3 +1,3 @@
1
1
  module HrLite
2
- VERSION = "0.31.0"
2
+ VERSION = "0.35.1"
3
3
  end
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.31.0
4
+ version: 0.35.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - kshitiz sinha
@@ -64,7 +64,11 @@ files:
64
64
  - MIT-LICENSE
65
65
  - README.md
66
66
  - Rakefile
67
+ - app/assets/javascripts/hr_lite/chart_tip.js
67
68
  - app/assets/javascripts/hr_lite/confirm.js
69
+ - app/assets/javascripts/hr_lite/countdown.js
70
+ - app/assets/javascripts/hr_lite/crm_picker.js
71
+ - app/assets/javascripts/hr_lite/emoji_pick.js
68
72
  - app/assets/javascripts/hr_lite/geo_punch.js
69
73
  - app/assets/javascripts/hr_lite/mention.js
70
74
  - app/assets/javascripts/hr_lite/nav.js
@@ -116,6 +120,9 @@ files:
116
120
  - app/controllers/hr_lite/admin/superadmin_controller.rb
117
121
  - app/controllers/hr_lite/admin/tax_declarations_controller.rb
118
122
  - app/controllers/hr_lite/admin/wfh_requests_controller.rb
123
+ - app/controllers/hr_lite/admin/work_locations_controller.rb
124
+ - app/controllers/hr_lite/admin/work_modes_controller.rb
125
+ - app/controllers/hr_lite/admin/work_time_controller.rb
119
126
  - app/controllers/hr_lite/application_controller.rb
120
127
  - app/controllers/hr_lite/appraisals_controller.rb
121
128
  - app/controllers/hr_lite/approvals_controller.rb
@@ -145,18 +152,24 @@ files:
145
152
  - app/controllers/hr_lite/timelines_controller.rb
146
153
  - app/controllers/hr_lite/users_controller.rb
147
154
  - app/controllers/hr_lite/wfh_requests_controller.rb
155
+ - app/controllers/hr_lite/work_locations_controller.rb
156
+ - app/controllers/hr_lite/work_modes_controller.rb
157
+ - app/controllers/hr_lite/work_time_controller.rb
148
158
  - app/helpers/hr_lite/application_helper.rb
149
159
  - app/jobs/hr_lite/application_job.rb
150
160
  - app/jobs/hr_lite/approval_escalation_job.rb
151
161
  - app/jobs/hr_lite/attendance_close_job.rb
152
162
  - app/jobs/hr_lite/ca_review_overdue_job.rb
153
163
  - app/jobs/hr_lite/ca_review_reminder_job.rb
164
+ - app/jobs/hr_lite/calendar_meeting_start_job.rb
165
+ - app/jobs/hr_lite/calendar_meeting_sync_job.rb
154
166
  - app/jobs/hr_lite/daily_digest_job.rb
155
167
  - app/jobs/hr_lite/document_expiry_job.rb
156
168
  - app/jobs/hr_lite/leave_year_rollover_job.rb
157
169
  - app/jobs/hr_lite/payroll_auto_approve_job.rb
158
170
  - app/jobs/hr_lite/payroll_auto_draft_job.rb
159
171
  - app/jobs/hr_lite/slips_ready_job.rb
172
+ - app/jobs/hr_lite/work_mode_expire_job.rb
160
173
  - app/mailers/hr_lite/application_mailer.rb
161
174
  - app/mailers/hr_lite/event_mailer.rb
162
175
  - app/models/concerns/hr_lite/approvable.rb
@@ -215,6 +228,8 @@ files:
215
228
  - app/models/hr_lite/tax_declaration.rb
216
229
  - app/models/hr_lite/tax_declaration_item.rb
217
230
  - app/models/hr_lite/wfh_request.rb
231
+ - app/models/hr_lite/work_location.rb
232
+ - app/models/hr_lite/work_mode_event.rb
218
233
  - app/services/hr_lite/access.rb
219
234
  - app/services/hr_lite/approval_route.rb
220
235
  - app/services/hr_lite/attendance_puncher.rb
@@ -233,6 +248,10 @@ files:
233
248
  - app/services/hr_lite/tax_computation.rb
234
249
  - app/services/hr_lite/team_day.rb
235
250
  - app/services/hr_lite/timeline.rb
251
+ - app/services/hr_lite/today_checkins.rb
252
+ - app/services/hr_lite/work_mode_durations.rb
253
+ - app/services/hr_lite/work_mode_switch.rb
254
+ - app/services/hr_lite/work_status.rb
236
255
  - app/services/hr_lite/working_calendar.rb
237
256
  - app/views/hr_lite/admin/appraisals/_form.html.erb
238
257
  - app/views/hr_lite/admin/appraisals/edit.html.erb
@@ -322,13 +341,20 @@ files:
322
341
  - app/views/hr_lite/admin/tax_declarations/show.html.erb
323
342
  - app/views/hr_lite/admin/wfh_requests/index.html.erb
324
343
  - app/views/hr_lite/admin/wfh_requests/show.html.erb
344
+ - app/views/hr_lite/admin/work_locations/index.html.erb
345
+ - app/views/hr_lite/admin/work_modes/index.html.erb
346
+ - app/views/hr_lite/admin/work_time/index.html.erb
325
347
  - app/views/hr_lite/appraisals/index.html.erb
326
348
  - app/views/hr_lite/appraisals/show.html.erb
327
349
  - app/views/hr_lite/approvals/index.html.erb
350
+ - app/views/hr_lite/attendance/_calendar_connection.html.erb
351
+ - app/views/hr_lite/attendance/_crm_picker.html.erb
352
+ - app/views/hr_lite/attendance/_custom_status.html.erb
328
353
  - app/views/hr_lite/attendance/_month_grid.html.erb
329
354
  - app/views/hr_lite/attendance/_penalties.html.erb
330
355
  - app/views/hr_lite/attendance/_punch_card.html.erb
331
356
  - app/views/hr_lite/attendance/_slot.html.erb
357
+ - app/views/hr_lite/attendance/_work_mode.html.erb
332
358
  - app/views/hr_lite/attendance/show.html.erb
333
359
  - app/views/hr_lite/benefits/index.html.erb
334
360
  - app/views/hr_lite/calendar/show.html.erb
@@ -345,6 +371,7 @@ files:
345
371
  - app/views/hr_lite/expenses/new.html.erb
346
372
  - app/views/hr_lite/holidays/_next_holiday.html.erb
347
373
  - app/views/hr_lite/holidays/index.html.erb
374
+ - app/views/hr_lite/home/_today_checkins.html.erb
348
375
  - app/views/hr_lite/home/index.html.erb
349
376
  - app/views/hr_lite/hr_requests/index.html.erb
350
377
  - app/views/hr_lite/hr_requests/new.html.erb
@@ -379,6 +406,12 @@ files:
379
406
  - app/views/hr_lite/timelines/_events.html.erb
380
407
  - app/views/hr_lite/timelines/show.html.erb
381
408
  - app/views/hr_lite/wfh_requests/index.html.erb
409
+ - app/views/hr_lite/work_locations/index.html.erb
410
+ - app/views/hr_lite/work_time/_bars.html.erb
411
+ - app/views/hr_lite/work_time/_donut.html.erb
412
+ - app/views/hr_lite/work_time/_report.html.erb
413
+ - app/views/hr_lite/work_time/_timeline.html.erb
414
+ - app/views/hr_lite/work_time/show.html.erb
382
415
  - app/views/layouts/hr_lite/application.html.erb
383
416
  - app/views/layouts/hr_lite/mailer.html.erb
384
417
  - app/views/layouts/hr_lite/mailer.text.erb
@@ -440,6 +473,16 @@ files:
440
473
  - db/migrate/20261013100000_create_hr_lite_wfh_requests.rb
441
474
  - db/migrate/20261013100100_add_wfh_request_id_to_hr_lite_attendance_records.rb
442
475
  - db/migrate/20261013100200_add_permanent_wfh_to_hr_lite_employee_profiles.rb
476
+ - db/migrate/20261013110000_create_hr_lite_work_locations.rb
477
+ - db/migrate/20261013110100_add_work_mode_to_hr_lite_attendance_records.rb
478
+ - db/migrate/20261013110200_add_field_staff_to_hr_lite_employee_profiles.rb
479
+ - db/migrate/20261013110300_create_hr_lite_work_mode_events.rb
480
+ - db/migrate/20261013110400_add_break_minutes_to_hr_lite_settings.rb
481
+ - db/migrate/20261013120000_grant_hr_lite_work_analytics.rb
482
+ - db/migrate/20261013130000_add_office_location_to_hr_lite_holidays.rb
483
+ - db/migrate/20261013130100_add_office_location_to_hr_lite_employee_profiles.rb
484
+ - db/migrate/20261013140000_add_calendar_and_crm_to_hr_lite_work_mode_events.rb
485
+ - db/migrate/20261013140100_add_custom_status_to_hr_lite_work_mode_events.rb
443
486
  - lib/generators/hr_lite/install/install_generator.rb
444
487
  - lib/generators/hr_lite/install/templates/AFTER_INSTALL
445
488
  - lib/generators/hr_lite/install/templates/initializer.rb