hr_lite 0.50.0 → 0.51.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 +7 -0
- data/app/controllers/hr_lite/admin/attendances_controller.rb +15 -0
- data/app/controllers/hr_lite/admin/employees_controller.rb +4 -1
- data/app/models/hr_lite/attendance_record.rb +2 -2
- data/app/models/hr_lite/employee_profile.rb +7 -2
- data/app/models/hr_lite/repeat_rule.rb +74 -0
- data/app/views/hr_lite/admin/attendances/summary.html.erb +20 -0
- data/app/views/hr_lite/admin/employees/_form.html.erb +1 -5
- data/app/views/hr_lite/admin/employees/_shorter_day_fields.html.erb +30 -0
- data/app/views/hr_lite/attendance/_punch_card.html.erb +2 -2
- data/config/routes.rb +1 -1
- data/db/migrate/20261016100000_add_hours_allowance_repeat_to_hr_lite_employee_profiles.rb +5 -0
- data/lib/hr_lite/version.rb +1 -1
- metadata +4 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 29f3f6694be039bef5c21d9548eaf1aaf8ff7c60191b0e92e2903c9fac7769fe
|
|
4
|
+
data.tar.gz: 361260627747e8ca8280401e985ef777cc8b267864fc6ccc0229ddf84670e939
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fbe31ca225879b95e882ee76b5cca183ef535c124c75616ebde7cd350bc03bff252febf09d6e7375f0dcf395ab19593548140667e6aa358b707be8f405c0f6f3
|
|
7
|
+
data.tar.gz: 39472b4fffa414eaafcbb2a7fb366354608d79f91f1cabe3e41d1e5a32380a2f7b42460fe3539e726850e163cea5680b5531aa4edf5ab7e79449d16e425e4091
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.51.0] - 2026-10-16
|
|
11
|
+
|
|
12
|
+
- Shorter day on a repeat: HR or admin give a person 30, 60 or 90 minutes off the working day (so 7h at the least) on a pattern set like a calendar's custom repeat: every N days, every N weeks on chosen weekdays, or every N months on the start's date, from a start date, ending never, on a date, or after N times. No repeat means every day, as before.
|
|
13
|
+
- Set it on the person's This week screen (Shorter day card) or on their employee profile; both edit the same fields. The card shows the pattern to anyone who can open the screen. The form and the reason show only to those who manage profiles company-wide, and never on your own record.
|
|
14
|
+
- The day's required hours, the short-day check and the "Your day" badge follow the pattern, and This week marks each day it covers with "Day 7h 00m".
|
|
15
|
+
- Migration: `hr_lite_employee_profiles.hours_allowance_repeat` (string). Hosts rebuild their schema on the bump.
|
|
16
|
+
|
|
10
17
|
## [0.50.0] - 2026-10-16
|
|
11
18
|
|
|
12
19
|
- Global search: one box for screens and people. It opens with ⌘K or Ctrl+K anywhere, from **Search** at the top of the sidebar, or from **Search** in the phone's More sheet. Typing (2 letters or more) lists matching screens and people; arrows move, Enter opens, and Escape closes. With JavaScript off, Search opens the `/search` page.
|
|
@@ -136,6 +136,21 @@ module HrLite
|
|
|
136
136
|
@penalties = AttendancePenalty.active.where(user_id: @employee.id, date: range).group(:date).sum(:minutes)
|
|
137
137
|
@balances = LeaveType.active.where(paid: true).map { |type| LeaveBalance.for(@employee, type, LeaveYear.current_key) }
|
|
138
138
|
@requests = summary_requests(@employee, range)
|
|
139
|
+
@profile = EmployeeProfile.find_by(user_id: @employee.id)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# The shorter day and its repeat, from This week: the employee form's own
|
|
143
|
+
# gate (profile.manage, company-wide) and never your own record.
|
|
144
|
+
def shorter_day
|
|
145
|
+
return hr_access_denied unless hr_can?("profile.manage", scope: :all)
|
|
146
|
+
@employee = find_visible_employee
|
|
147
|
+
raise ActiveRecord::RecordNotFound if @employee.id == hr_current_user.id
|
|
148
|
+
|
|
149
|
+
profile = EmployeeProfile.find_by!(user_id: @employee.id)
|
|
150
|
+
saved = profile.update(params.require(:employee_profile).permit(:hours_allowance_minutes, :hours_allowance_reason)
|
|
151
|
+
.merge(hours_allowance_repeat: RepeatRule.from_params(params.fetch(:repeat, {}))&.to_s))
|
|
152
|
+
redirect_to summary_admin_attendance_path(@employee.id, anchor: "shorter-day"),
|
|
153
|
+
saved ? { notice: "Shorter day saved." } : { alert: profile.errors.full_messages.to_sentence }
|
|
139
154
|
end
|
|
140
155
|
|
|
141
156
|
# HR sets a locked slot from today for the period.
|
|
@@ -125,8 +125,11 @@ module HrLite
|
|
|
125
125
|
# hands one person's PAN, bank details and pay history to another, so it
|
|
126
126
|
# is a create-time field only.
|
|
127
127
|
def update_profile_params
|
|
128
|
-
profile_params.except(:user_id)
|
|
128
|
+
profile_params.except(:user_id).merge(repeat_param)
|
|
129
129
|
end
|
|
130
|
+
|
|
131
|
+
# The shorter day's repeat (RepeatRule); absent when the form has no repeat fields.
|
|
132
|
+
def repeat_param = params.key?(:repeat) ? { hours_allowance_repeat: RepeatRule.from_params(params[:repeat])&.to_s } : {}
|
|
130
133
|
end
|
|
131
134
|
end
|
|
132
135
|
end
|
|
@@ -54,7 +54,7 @@ module HrLite
|
|
|
54
54
|
# The working day HR sets in Settings, less the person's allowance. Nil when
|
|
55
55
|
# the host turns hours rules off (config.work_hours), and on Saturdays.
|
|
56
56
|
def required_minutes
|
|
57
|
-
EmployeeProfile.day_minutes_for(user_id) unless HrLite.config.work_hours.nil? || date.saturday?
|
|
57
|
+
EmployeeProfile.day_minutes_for(user_id, on: date) unless HrLite.config.work_hours.nil? || date.saturday?
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
# Hours worked, not the clock: an early start counts.
|
|
@@ -71,7 +71,7 @@ module HrLite
|
|
|
71
71
|
return unless HrLite.config.attendance_slots && check_in_at
|
|
72
72
|
|
|
73
73
|
extra = AttendancePenalty.active.where(user_id: user_id, date: date).sum(:minutes)
|
|
74
|
-
check_in_at + (EmployeeProfile.day_minutes_for(user_id) + extra).minutes
|
|
74
|
+
check_in_at + (EmployeeProfile.day_minutes_for(user_id, on: date) + extra).minutes
|
|
75
75
|
end
|
|
76
76
|
|
|
77
77
|
def worked_under?(minutes) = !!(minutes && worked_duration && worked_duration < minutes.minutes)
|
|
@@ -41,8 +41,13 @@ module HrLite
|
|
|
41
41
|
validates :hours_allowance_minutes, inclusion: { in: HOURS_ALLOWANCE_MINUTES }, allow_nil: true
|
|
42
42
|
validates :hours_allowance_reason, presence: true, if: :hours_allowance_minutes
|
|
43
43
|
|
|
44
|
-
# One person's working day: HR's day in Settings less their
|
|
45
|
-
|
|
44
|
+
# One person's working day on a date: HR's day in Settings less their
|
|
45
|
+
# allowance, on the days its repeat covers (no repeat = every day).
|
|
46
|
+
def self.day_minutes_for(user_id, on: Date.current)
|
|
47
|
+
minutes, repeat = where(user_id: user_id).pick(:hours_allowance_minutes, :hours_allowance_repeat)
|
|
48
|
+
applies = minutes && (repeat.blank? || RepeatRule.parse(repeat).occurs_on?(on))
|
|
49
|
+
Setting.instance.day_minutes - (applies ? minutes : 0)
|
|
50
|
+
end
|
|
46
51
|
|
|
47
52
|
TAX_REGIMES = %w[new old].freeze
|
|
48
53
|
BLOOD_GROUPS = %w[A+ A- B+ B- AB+ AB- O+ O-].freeze
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
module HrLite
|
|
2
|
+
# A calendar repeat, like Google Calendar's custom repeat (an RRULE subset):
|
|
3
|
+
# every N days, weeks (on chosen weekdays) or months (on the start's date),
|
|
4
|
+
# from a start date, ending never, on a date, or after N times. Stored as
|
|
5
|
+
# text, e.g. "FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,WE,FR;DTSTART=2026-10-20;COUNT=12".
|
|
6
|
+
class RepeatRule
|
|
7
|
+
FREQS = { "DAILY" => "day", "WEEKLY" => "week", "MONTHLY" => "month" }.freeze
|
|
8
|
+
DAYS = %w[SU MO TU WE TH FR SA].freeze # index = Date#wday
|
|
9
|
+
|
|
10
|
+
attr_reader :freq, :interval, :days, :from, :until_date, :count
|
|
11
|
+
|
|
12
|
+
def self.parse(text)
|
|
13
|
+
return if text.blank?
|
|
14
|
+
|
|
15
|
+
parts = text.split(";").to_h { |part| part.split("=", 2) }
|
|
16
|
+
new(freq: parts["FREQ"], interval: parts["INTERVAL"], days: parts["BYDAY"].to_s.split(","),
|
|
17
|
+
from: parts["DTSTART"], until_date: parts["UNTIL"], count: parts["COUNT"])
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# The form's repeat[...] fields; a blank frequency means every day (no rule).
|
|
21
|
+
def self.from_params(params)
|
|
22
|
+
return if params[:freq].blank?
|
|
23
|
+
|
|
24
|
+
new(freq: params[:freq], interval: params[:interval], days: Array(params[:days]).compact_blank, from: params[:from],
|
|
25
|
+
until_date: (params[:until] if params[:ends] == "on"), count: (params[:count] if params[:ends] == "after"))
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def initialize(freq:, interval: 1, days: [], from: nil, until_date: nil, count: nil)
|
|
29
|
+
@freq = FREQS.key?(freq.to_s.upcase) ? freq.to_s.upcase : "DAILY"
|
|
30
|
+
@interval = [ interval.to_i, 1 ].max
|
|
31
|
+
@days = days.map(&:upcase) & DAYS
|
|
32
|
+
@from = to_date(from) || Date.current
|
|
33
|
+
@until_date = to_date(until_date)
|
|
34
|
+
@count = count.to_i.positive? ? count.to_i : nil
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def to_s
|
|
38
|
+
[ "FREQ=#{freq}", "INTERVAL=#{interval}", ("BYDAY=#{days.join(',')}" if days.any?), "DTSTART=#{from.iso8601}",
|
|
39
|
+
("UNTIL=#{until_date.iso8601}" if until_date), ("COUNT=#{count}" if count) ].compact.join(";")
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def occurs_on?(date)
|
|
43
|
+
return false if date < from || (until_date && date > until_date) || !matches?(date)
|
|
44
|
+
|
|
45
|
+
count.nil? || (from..date).count { |day| matches?(day) } <= count
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# "Every 2 weeks on Mon, Wed, Fri from 20 Oct 2026, 12 times"
|
|
49
|
+
def describe
|
|
50
|
+
every = interval == 1 ? "Every #{FREQS[freq]}" : "Every #{interval} #{FREQS[freq]}s"
|
|
51
|
+
on = (" on #{days.map { |d| Date::ABBR_DAYNAMES[DAYS.index(d)] }.join(', ')}" if freq == "WEEKLY" && days.any?)
|
|
52
|
+
ends = until_date ? ", until #{until_date.strftime('%-d %b %Y')}" : (", #{count} times" if count)
|
|
53
|
+
"#{every}#{on} from #{from.strftime('%-d %b %Y')}#{ends}"
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
private
|
|
57
|
+
|
|
58
|
+
def matches?(date)
|
|
59
|
+
case freq
|
|
60
|
+
when "DAILY" then ((date - from).to_i % interval).zero?
|
|
61
|
+
when "WEEKLY"
|
|
62
|
+
(days.any? ? days.include?(DAYS[date.wday]) : date.wday == from.wday) &&
|
|
63
|
+
(((date.beginning_of_week - from.beginning_of_week).to_i / 7) % interval).zero?
|
|
64
|
+
else date.day == from.day && (((date.year * 12) + date.month - (from.year * 12) - from.month) % interval).zero?
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def to_date(value)
|
|
69
|
+
value.is_a?(Date) ? value : Date.iso8601(value.to_s)
|
|
70
|
+
rescue Date::Error
|
|
71
|
+
nil
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -33,6 +33,9 @@
|
|
|
33
33
|
<div class="hrl-feed__body hrl-small">
|
|
34
34
|
<strong><%= date.strftime("%a %-d %b") %></strong>
|
|
35
35
|
<span class="hrl-badge <%= tones[day.kind] %>"><%= HrLite::ApplicationHelper::DAY_STATES[day.kind][1] %></span>
|
|
36
|
+
<% if @profile&.hours_allowance_minutes && (length = HrLite::EmployeeProfile.day_minutes_for(@employee.id, on: date)) < HrLite::Setting.instance.day_minutes %>
|
|
37
|
+
<span class="hrl-badge hrl-badge--muted">Day <%= hrl_duration(length * 60) %></span>
|
|
38
|
+
<% end %>
|
|
36
39
|
<% if rec&.check_in_at %>
|
|
37
40
|
<div>In <%= rec.check_in_at.strftime("%H:%M") %><% if rec.check_out_at %> · Out <%= rec.check_out_at.strftime("%H:%M") %> · <%= hrl_duration(rec.worked_duration) %> worked<% end %></div>
|
|
38
41
|
<% end %>
|
|
@@ -47,6 +50,23 @@
|
|
|
47
50
|
<% end %>
|
|
48
51
|
</section>
|
|
49
52
|
|
|
53
|
+
<% if @profile %>
|
|
54
|
+
<section class="hrl-card" id="shorter-day">
|
|
55
|
+
<h2 class="hrl-card__title">Shorter day</h2>
|
|
56
|
+
<p class="hrl-small"><% if @profile.hours_allowance_minutes %><strong><%= @profile.hours_allowance_minutes %> min less</strong> · <%= HrLite::RepeatRule.parse(@profile.hours_allowance_repeat)&.describe || "Every day" %><% else %>None<% end %></p>
|
|
57
|
+
<% if @employee.id != hr_current_user.id && hr_can?("profile.manage", scope: :all) %>
|
|
58
|
+
<% if @profile.hours_allowance_reason.present? %><p class="hrl-small hrl-muted">Reason: <%= @profile.hours_allowance_reason %></p><% end %>
|
|
59
|
+
<details>
|
|
60
|
+
<summary class="hrl-btn hrl-btn--block"><%= @profile.hours_allowance_minutes ? "Change shorter day" : "Set a shorter day" %></summary>
|
|
61
|
+
<%= form_with model: @profile, scope: :employee_profile, url: hr_lite.shorter_day_admin_attendance_path(@employee.id), method: :patch, local: true do |f| %>
|
|
62
|
+
<%= render "hr_lite/admin/employees/shorter_day_fields", f: f, profile: @profile %>
|
|
63
|
+
<button type="submit" class="hrl-btn hrl-btn--primary">Save shorter day</button>
|
|
64
|
+
<% end %>
|
|
65
|
+
</details>
|
|
66
|
+
<% end %>
|
|
67
|
+
</section>
|
|
68
|
+
<% end %>
|
|
69
|
+
|
|
50
70
|
<section class="hrl-card">
|
|
51
71
|
<h2 class="hrl-card__title">Requests</h2>
|
|
52
72
|
<% if @requests.empty? %><p class="hrl-card--empty">No requests in this <%= @period.kind %>.</p><% end %>
|
|
@@ -90,11 +90,7 @@
|
|
|
90
90
|
</div>
|
|
91
91
|
<div class="hrl-field"><%= f.label :buffer_note, "Buffer note (HR only; required for Other)" %><%= f.text_area :buffer_note, rows: 2 %></div>
|
|
92
92
|
<% end %>
|
|
93
|
-
|
|
94
|
-
<%= f.label :hours_allowance_minutes, "Shorter day (e.g. a long commute; lowers the hours they must work)" %>
|
|
95
|
-
<%= f.select :hours_allowance_minutes, HrLite::EmployeeProfile::HOURS_ALLOWANCE_MINUTES.map { |m| [ "#{m} min less", m ] }, include_blank: "None" %>
|
|
96
|
-
</div>
|
|
97
|
-
<div class="hrl-field"><%= f.label :hours_allowance_reason, "Shorter day reason (HR only; required)" %><%= f.text_area :hours_allowance_reason, rows: 2 %></div>
|
|
93
|
+
<%= render "hr_lite/admin/employees/shorter_day_fields", f: f, profile: f.object %>
|
|
98
94
|
<% if HrLite.config.office_geofence %>
|
|
99
95
|
<div class="hrl-field hrl-field--check"><%= f.check_box :permanent_wfh %><%= f.label :permanent_wfh, "Permanent work from home (every working day counts as approved WFH; check-in still within 500 m of their approved home location)" %></div>
|
|
100
96
|
<div class="hrl-field hrl-field--check"><%= f.check_box :field_staff %><%= f.label :field_staff, "Field staff (e.g. sales: may check in from anywhere as Travelling or Client meeting, with purpose and place)" %></div>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<%# locals: f (employee_profile form), profile — the shorter day and the days it repeats on (repeat[...] → RepeatRule). %>
|
|
2
|
+
<% rule = HrLite::RepeatRule.parse(profile.hours_allowance_repeat)
|
|
3
|
+
ends = rule&.until_date ? "on" : (rule&.count ? "after" : "never") %>
|
|
4
|
+
<div class="hrl-field">
|
|
5
|
+
<%= f.label :hours_allowance_minutes, "Shorter day (e.g. a long commute; lowers the hours they must work)" %>
|
|
6
|
+
<%= f.select :hours_allowance_minutes, HrLite::EmployeeProfile::HOURS_ALLOWANCE_MINUTES.map { |m| [ "#{m} min less", m ] }, include_blank: "None" %>
|
|
7
|
+
</div>
|
|
8
|
+
<div class="hrl-field">
|
|
9
|
+
<label for="repeat-freq">Repeats</label>
|
|
10
|
+
<%= select_tag "repeat[freq]", options_for_select([ [ "Every day", "" ], [ "Every N days", "DAILY" ], [ "Every N weeks, on the days below", "WEEKLY" ], [ "Every N months, on the start's date", "MONTHLY" ] ], rule&.freq), id: "repeat-freq" %>
|
|
11
|
+
</div>
|
|
12
|
+
<div class="hrl-field"><label for="repeat-interval">N (every how many)</label><%= number_field_tag "repeat[interval]", rule&.interval || 1, min: 1, max: 12, id: "repeat-interval", class: "hrl-input" %></div>
|
|
13
|
+
<fieldset class="hrl-field">
|
|
14
|
+
<legend>Days (weekly)</legend>
|
|
15
|
+
<div class="hrl-row">
|
|
16
|
+
<% HrLite::RepeatRule::DAYS.rotate(1).each do |day| %>
|
|
17
|
+
<label class="hrl-field--check"><%= check_box_tag "repeat[days][]", day, rule&.days&.include?(day), id: "repeat-#{day}" %> <%= Date::ABBR_DAYNAMES[HrLite::RepeatRule::DAYS.index(day)] %></label>
|
|
18
|
+
<% end %>
|
|
19
|
+
</div>
|
|
20
|
+
</fieldset>
|
|
21
|
+
<div class="hrl-field"><label for="repeat-from">Starts</label><%= date_field_tag "repeat[from]", rule&.from || Date.current, id: "repeat-from" %></div>
|
|
22
|
+
<fieldset class="hrl-field">
|
|
23
|
+
<legend>Ends</legend>
|
|
24
|
+
<label class="hrl-field--check"><%= radio_button_tag "repeat[ends]", "never", ends == "never", id: "repeat-ends-never" %> Never</label>
|
|
25
|
+
<label class="hrl-field--check"><%= radio_button_tag "repeat[ends]", "on", ends == "on", id: "repeat-ends-on" %> On a date</label>
|
|
26
|
+
<label class="hrl-field--check"><%= radio_button_tag "repeat[ends]", "after", ends == "after", id: "repeat-ends-after" %> After a number of times</label>
|
|
27
|
+
</fieldset>
|
|
28
|
+
<div class="hrl-field"><label for="repeat-until">End date (for "On a date")</label><%= date_field_tag "repeat[until]", rule&.until_date, id: "repeat-until" %></div>
|
|
29
|
+
<div class="hrl-field"><label for="repeat-count">Times (for "After a number of times")</label><%= number_field_tag "repeat[count]", rule&.count, min: 1, id: "repeat-count", class: "hrl-input" %></div>
|
|
30
|
+
<div class="hrl-field"><%= f.label :hours_allowance_reason, "Shorter day reason (HR only; required)" %><%= f.text_area :hours_allowance_reason, rows: 2 %></div>
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
<% if record&.work_mode_label %>
|
|
24
24
|
<span class="hrl-badge hrl-badge--ok"><%= record.work_mode_label %></span>
|
|
25
25
|
<% end %>
|
|
26
|
-
<% if HrLite::EmployeeProfile.
|
|
27
|
-
<span class="hrl-badge hrl-badge--muted">Your day <%= hrl_duration(
|
|
26
|
+
<% if (my_day = HrLite::EmployeeProfile.day_minutes_for(hr_current_user.id)) < HrLite::Setting.instance.day_minutes %>
|
|
27
|
+
<span class="hrl-badge hrl-badge--muted">Your day <%= hrl_duration(my_day * 60) %></span>
|
|
28
28
|
<% end %>
|
|
29
29
|
<% if record&.check_in_place == "home" && record.work_location %>
|
|
30
30
|
<span class="hrl-badge hrl-badge--muted"><%= record.work_location.name %> · <%= HrLite::WorkLocation::FENCE_M %> m</span>
|
data/config/routes.rb
CHANGED
|
@@ -74,7 +74,7 @@ HrLite::Engine.routes.draw do
|
|
|
74
74
|
get "overview", to: "overview#index"
|
|
75
75
|
resources :attendances, only: %i[index show update], param: :user_id do
|
|
76
76
|
collection { get :week }
|
|
77
|
-
member { get :summary; post :slot; post :unlock_slot; post :remove_penalty; post :remove_penalty_hours }
|
|
77
|
+
member { get :summary; patch :shorter_day; post :slot; post :unlock_slot; post :remove_penalty; post :remove_penalty_hours }
|
|
78
78
|
end
|
|
79
79
|
resources :leave_requests, only: %i[index show new create edit update] do
|
|
80
80
|
member { post :approve; post :reject; post :cancel }
|
data/lib/hr_lite/version.rb
CHANGED
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.51.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- kshitiz sinha
|
|
@@ -220,6 +220,7 @@ files:
|
|
|
220
220
|
- app/models/hr_lite/policy_acknowledgement.rb
|
|
221
221
|
- app/models/hr_lite/professional_tax_slab.rb
|
|
222
222
|
- app/models/hr_lite/regularization_request.rb
|
|
223
|
+
- app/models/hr_lite/repeat_rule.rb
|
|
223
224
|
- app/models/hr_lite/resignation.rb
|
|
224
225
|
- app/models/hr_lite/role.rb
|
|
225
226
|
- app/models/hr_lite/role_assignment.rb
|
|
@@ -282,6 +283,7 @@ files:
|
|
|
282
283
|
- app/views/hr_lite/admin/documents/index.html.erb
|
|
283
284
|
- app/views/hr_lite/admin/documents/show.html.erb
|
|
284
285
|
- app/views/hr_lite/admin/employees/_form.html.erb
|
|
286
|
+
- app/views/hr_lite/admin/employees/_shorter_day_fields.html.erb
|
|
285
287
|
- app/views/hr_lite/admin/employees/edit.html.erb
|
|
286
288
|
- app/views/hr_lite/admin/employees/index.html.erb
|
|
287
289
|
- app/views/hr_lite/admin/employees/new.html.erb
|
|
@@ -499,6 +501,7 @@ files:
|
|
|
499
501
|
- db/migrate/20261015100000_create_hr_lite_attendance_punches.rb
|
|
500
502
|
- db/migrate/20261016090000_add_penalty_leave_type_to_hr_lite_settings.rb
|
|
501
503
|
- db/migrate/20261016091000_create_hr_lite_penalty_removals.rb
|
|
504
|
+
- db/migrate/20261016100000_add_hours_allowance_repeat_to_hr_lite_employee_profiles.rb
|
|
502
505
|
- lib/generators/hr_lite/install/install_generator.rb
|
|
503
506
|
- lib/generators/hr_lite/install/templates/AFTER_INSTALL
|
|
504
507
|
- lib/generators/hr_lite/install/templates/initializer.rb
|