@kernhq/module-hr 0.10.0 → 0.10.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.
- package/dist/contract/attendance.d.ts +1 -0
- package/dist/contract/attendance.d.ts.map +1 -1
- package/dist/contract/attendance.js +9 -0
- package/dist/contract/attendance.js.map +1 -1
- package/dist/contract/capabilities.d.ts +16 -0
- package/dist/contract/capabilities.d.ts.map +1 -1
- package/dist/contract/capabilities.js +16 -0
- package/dist/contract/capabilities.js.map +1 -1
- package/dist/contract/router.d.ts +1 -0
- package/dist/contract/router.d.ts.map +1 -1
- package/dist/policy/accrual.d.ts +35 -4
- package/dist/policy/accrual.d.ts.map +1 -1
- package/dist/policy/accrual.js +141 -15
- package/dist/policy/accrual.js.map +1 -1
- package/dist/policy/working-time.d.ts +115 -9
- package/dist/policy/working-time.d.ts.map +1 -1
- package/dist/policy/working-time.js +120 -20
- package/dist/policy/working-time.js.map +1 -1
- package/dist/server/jobs.d.ts +14 -6
- package/dist/server/jobs.d.ts.map +1 -1
- package/dist/server/jobs.js +489 -144
- package/dist/server/jobs.js.map +1 -1
- package/dist/server/packs/index.d.ts +14 -0
- package/dist/server/packs/index.d.ts.map +1 -1
- package/dist/server/packs/index.js +19 -0
- package/dist/server/packs/index.js.map +1 -1
- package/dist/server/router.d.ts +1888 -111
- package/dist/server/router.d.ts.map +1 -1
- package/dist/server/router.js +154 -63
- package/dist/server/router.js.map +1 -1
- package/dist/server/schema.d.ts +17 -0
- package/dist/server/schema.d.ts.map +1 -1
- package/dist/server/schema.js +81 -2
- package/dist/server/schema.js.map +1 -1
- package/dist/server/services/approvals.d.ts +0 -2
- package/dist/server/services/approvals.d.ts.map +1 -1
- package/dist/server/services/approvals.js +12 -4
- package/dist/server/services/approvals.js.map +1 -1
- package/dist/server/services/attendance.d.ts +120 -8
- package/dist/server/services/attendance.d.ts.map +1 -1
- package/dist/server/services/attendance.js +226 -14
- package/dist/server/services/attendance.js.map +1 -1
- package/dist/server/services/ledger.d.ts +0 -2
- package/dist/server/services/ledger.d.ts.map +1 -1
- package/dist/server/services/ledger.js +1 -2
- package/dist/server/services/ledger.js.map +1 -1
- package/dist/server/services/policies.d.ts +6 -2
- package/dist/server/services/policies.d.ts.map +1 -1
- package/dist/server/services/policies.js +7 -2
- package/dist/server/services/policies.js.map +1 -1
- package/migrations/0005_approval_requester.sql +11 -1
- package/migrations/0006_schedule_no_overlap.sql +85 -0
- package/migrations/0007_hot_path_indexes.sql +38 -0
- package/migrations/0009_beyond_cap_minutes.sql +15 -0
- package/migrations/meta/0005_snapshot.json +4047 -0
- package/migrations/meta/0007_snapshot.json +4225 -0
- package/migrations/meta/0009_snapshot.json +4231 -0
- package/migrations/meta/_journal.json +21 -0
- package/package.json +7 -7
- package/src/client/components/ClockControls.svelte +127 -20
- package/src/client/components/ClockControls.test.ts +446 -0
- package/src/client/components/DelegationDialog.svelte +12 -3
- package/src/client/components/LeaveRequestDialog.svelte +254 -25
- package/src/client/components/PersonFormDialog.svelte +53 -3
- package/src/client/components/PersonPanel.svelte +134 -26
- package/src/client/i18n.ts +5 -927
- package/src/client/messages.test.ts +154 -0
- package/src/client/messages.ts +3388 -0
- package/src/client/mock.ts +1576 -161
- package/src/client/module.ts +15 -1
- package/src/client/pages/ApprovalsPage.svelte +120 -46
- package/src/client/pages/AttendancePage.svelte +106 -20
- package/src/client/pages/DirectoryPage.svelte +192 -55
- package/src/client/pages/LeavePage.svelte +280 -25
- package/src/client/pages/OfficesPage.svelte +26 -8
- package/src/client/pages/leave-and-attendance.test.ts +588 -0
- package/src/client/query.ts +12 -0
- package/src/client/settings/CalendarsSettings.svelte +1363 -12
- package/src/client/settings/CapabilitiesSettings.svelte +276 -19
- package/src/client/settings/GeneralSettings.svelte +420 -0
- package/src/client/settings/LeaveSettings.svelte +884 -12
- package/src/client/settings/OfficesSettings.svelte +1182 -12
- package/src/client/settings/SchedulesSettings.svelte +1149 -12
- package/src/client/summary.ts +14 -7
- package/src/client/widgets/ApprovalsWidget.svelte +133 -20
- package/src/client/widgets/HeadcountWidget.svelte +74 -8
- package/src/client/widgets/LeaveBalanceWidget.svelte +40 -5
- package/src/client/widgets/WhosOutWidget.svelte +47 -8
- package/src/contract/attendance.ts +9 -0
- package/src/contract/capabilities.ts +17 -0
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { type Tx } from '@kernhq/kernel';
|
|
2
|
-
import { inArray, sql } from 'drizzle-orm';
|
|
3
2
|
import { type RoundingPolicy, type ShiftSpec } from '../../policy/working-time.js';
|
|
3
|
+
import { punches } from '../schema.js';
|
|
4
|
+
import { PolicyService } from './policies.js';
|
|
5
|
+
import { ResolveService } from './resolve.js';
|
|
4
6
|
/**
|
|
5
7
|
* Punches and the day sheet.
|
|
6
8
|
*
|
|
@@ -21,19 +23,77 @@ export interface ResolvedSchedule {
|
|
|
21
23
|
}
|
|
22
24
|
/** A schedule with no shifts: somebody with no assignment still clocks in, they just owe no hours. */
|
|
23
25
|
export declare const NO_SCHEDULE: ResolvedSchedule;
|
|
26
|
+
/** A punch exactly as it is stored. What `attribute` hands back, and what the router's guard reads. */
|
|
27
|
+
export type PunchRow = typeof punches.$inferSelect;
|
|
28
|
+
/**
|
|
29
|
+
* One decision about one instant, and everything that follows from it.
|
|
30
|
+
*
|
|
31
|
+
* A punch needs three answers that must agree: which day it counts towards, whether the transition
|
|
32
|
+
* it asks for is possible at all, and what the clock widget was showing the person before they
|
|
33
|
+
* pressed anything. They used to be computed in three places from three reads. Here they are one
|
|
34
|
+
* value, so a disagreement between them is not something the code can express.
|
|
35
|
+
*/
|
|
36
|
+
export interface Attribution {
|
|
37
|
+
/** The business date this punch belongs to. */
|
|
38
|
+
businessDate: string;
|
|
39
|
+
/** What that date schedules, if anything. */
|
|
40
|
+
shift: ShiftSpec | null;
|
|
41
|
+
/** The live punches already filed on it, oldest first. */
|
|
42
|
+
punches: PunchRow[];
|
|
43
|
+
/** What those say: whether a shift, and a break, are still running. */
|
|
44
|
+
open: {
|
|
45
|
+
clockedIn: boolean;
|
|
46
|
+
onBreak: boolean;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
24
49
|
export declare class AttendanceService {
|
|
50
|
+
private readonly resolve;
|
|
51
|
+
private readonly policies;
|
|
52
|
+
/**
|
|
53
|
+
* Both collaborators are defaulted so `new AttendanceService()` still reads as a leaf service.
|
|
54
|
+
* The period is asked about on every recomputation, and who belongs to a legal entity is asked
|
|
55
|
+
* on every lock — neither question has a second implementation in this module and neither may
|
|
56
|
+
* grow one here.
|
|
57
|
+
*/
|
|
58
|
+
constructor(resolve?: ResolveService, policies?: PolicyService);
|
|
25
59
|
/** The schedule in force for a person on a date, as something the pure layer can use. */
|
|
26
60
|
scheduleFor(tx: Tx, workspaceId: string, personId: string, on: string): Promise<ResolvedSchedule>;
|
|
61
|
+
/**
|
|
62
|
+
* Which shift a punch made at `atMs` joins — decided once, from the punches that are already filed.
|
|
63
|
+
*
|
|
64
|
+
* This is the circularity that made the last three attempts at the night-shift boundary
|
|
65
|
+
* unfixable. The shift a punch belonged to was worked out from the clock alone; the guard that
|
|
66
|
+
* decides whether the punch is even possible was then built by reading `punchesOn(that date)`. So
|
|
67
|
+
* the guard could only ever confirm the attribution's own choice, and where the choice was wrong
|
|
68
|
+
* the person was told they were not clocked in at the end of a shift they had just worked. The
|
|
69
|
+
* fact that settles it — is a shift still open — is a question about punches, so it is asked
|
|
70
|
+
* *before* the attribution instead of after it.
|
|
71
|
+
*
|
|
72
|
+
* Both candidate dates come back in one statement, the punch's own local date and the one before
|
|
73
|
+
* it, on `hr_punches_person_idx`. That is fewer queries than the path it replaces, and it is what
|
|
74
|
+
* makes the guard and the attribution incapable of drifting apart: they are the same rows.
|
|
75
|
+
*/
|
|
76
|
+
attribute(tx: Tx, workspaceId: string, personId: string, atMs: number, timezone: string, schedule: ResolvedSchedule): Promise<Attribution>;
|
|
27
77
|
/**
|
|
28
78
|
* Record a punch.
|
|
29
79
|
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
80
|
+
* Both the instant and the day it counts towards arrive decided. `at` is the server's clock unless
|
|
81
|
+
* the offline sync path says otherwise, and `businessDate` is `attribute`'s answer for that same
|
|
82
|
+
* instant — this method used to attribute the punch a second time, from its own `new Date()`
|
|
83
|
+
* rather than from the instant the caller had already reasoned about. Two answers to one question,
|
|
84
|
+
* a millisecond apart, is how both ends of one shift end up on two sheets.
|
|
85
|
+
*
|
|
86
|
+
* `clientReportedAt` is kept beside the instant with the measured skew so an offline sync can be
|
|
87
|
+
* told from a device whose clock is wrong — and a claim beyond the threshold is marked `disputed`
|
|
88
|
+
* rather than silently accepted or silently dropped.
|
|
33
89
|
*/
|
|
34
90
|
record(tx: Tx, workspaceId: string, input: {
|
|
35
91
|
personId: string;
|
|
36
92
|
direction: 'in' | 'out' | 'break_start' | 'break_end';
|
|
93
|
+
/** The instant, exactly as it was attributed. */
|
|
94
|
+
at: Date;
|
|
95
|
+
/** `attribute`'s answer for that instant, never re-derived here. */
|
|
96
|
+
businessDate: string;
|
|
37
97
|
timezone: string;
|
|
38
98
|
method: string;
|
|
39
99
|
clientReportedAt?: string | null;
|
|
@@ -41,9 +101,9 @@ export declare class AttendanceService {
|
|
|
41
101
|
geo?: Record<string, number> | null;
|
|
42
102
|
note?: string | null;
|
|
43
103
|
idempotencyKey?: string | null;
|
|
44
|
-
/** Set only by the offline sync path, where
|
|
45
|
-
|
|
46
|
-
}
|
|
104
|
+
/** Set only by the offline sync path, where `at` genuinely is the client's claim. */
|
|
105
|
+
claimed?: boolean;
|
|
106
|
+
}): Promise<{
|
|
47
107
|
createdAt: Date;
|
|
48
108
|
id: string;
|
|
49
109
|
timezone: string;
|
|
@@ -95,6 +155,59 @@ export declare class AttendanceService {
|
|
|
95
155
|
recomputeDay(tx: Tx, workspaceId: string, personId: string, businessDate: string, timezone: string, schedule: ResolvedSchedule): Promise<{
|
|
96
156
|
locked: boolean;
|
|
97
157
|
}>;
|
|
158
|
+
/**
|
|
159
|
+
* The overtime rules that apply to one person on one date, as numbers a pure function can use.
|
|
160
|
+
*
|
|
161
|
+
* Resolved here rather than passed in, unlike the schedule: `computeDay` may not touch the
|
|
162
|
+
* database and every caller of `recomputeDay` would otherwise have to walk the policy ladder
|
|
163
|
+
* itself, which is how a rule ends up applied on three paths out of four.
|
|
164
|
+
*
|
|
165
|
+
* Undefined where no policy applies, which is what a workspace that never configured overtime
|
|
166
|
+
* means — every minute past the schedule counts, exactly as it did before the policy was read at
|
|
167
|
+
* all.
|
|
168
|
+
*/
|
|
169
|
+
private overtimePolicyFor;
|
|
170
|
+
/**
|
|
171
|
+
* Overtime already counted this year, on the days *before* this one.
|
|
172
|
+
*
|
|
173
|
+
* Strictly before, so a day's figure depends only on days that precede it and recomputing one
|
|
174
|
+
* cannot depend on the order the sweep happens to visit them in. The days after it are then stale
|
|
175
|
+
* against a cap that filled earlier, which the nightly recomputation settles — an order-dependent
|
|
176
|
+
* sheet would not settle at all.
|
|
177
|
+
*
|
|
178
|
+
* The year is the calendar one, because `capMinutesPerYear` is what the config offers; a legal
|
|
179
|
+
* entity closing its year elsewhere would need the cap to say so first.
|
|
180
|
+
*/
|
|
181
|
+
private overtimeCountedBefore;
|
|
182
|
+
/**
|
|
183
|
+
* Stamp `locked` on every day a period covers — and on nobody else's.
|
|
184
|
+
*
|
|
185
|
+
* A period with no legal entity is the whole workspace's. One that names an entity closes *that
|
|
186
|
+
* entity's* month: `PolicyService.isLocked` has always read it that way, and until this method
|
|
187
|
+
* existed the day sheet did not, so closing the Turkish entity's January froze the Dutch and
|
|
188
|
+
* Iranian ones too. Two enforcement mechanisms disagreeing about who a period covers is worse
|
|
189
|
+
* than either of them being wrong on its own, because each looks right from where it is read.
|
|
190
|
+
*
|
|
191
|
+
* Membership is asked of the resolution ladder rather than joined here: which entity somebody is
|
|
192
|
+
* in is not a column on `people` — the employment in force says, and where it does not, their
|
|
193
|
+
* primary office does — and that order has exactly one implementation in this module. It is asked
|
|
194
|
+
* **as of each day**, the same date `isLocked` will be asked about later, because the day is what
|
|
195
|
+
* belongs to an entity: resolving everybody once at the period's last day stamped the whole month
|
|
196
|
+
* of somebody who transferred in halfway through it, including the half they spent elsewhere —
|
|
197
|
+
* days no Dutch period had closed, frozen by a Turkish one.
|
|
198
|
+
*
|
|
199
|
+
* Releasing is not the mirror of stamping. The exclusion constraint keys on
|
|
200
|
+
* `coalesce(legal_entity_id, …)`, so a workspace-wide period and an entity's period may cover the
|
|
201
|
+
* same dates on purpose — and reopening the narrower one must not unlock a month the wider one
|
|
202
|
+
* has filed. So a day is released only where nothing still closes it. That reads the period's own
|
|
203
|
+
* status, which the handler writes before calling this: a period reopening itself would otherwise
|
|
204
|
+
* be the reason it cannot let go.
|
|
205
|
+
*/
|
|
206
|
+
setPeriodLock(tx: Tx, workspaceId: string, period: {
|
|
207
|
+
legalEntityId: string | null;
|
|
208
|
+
startsOn: string;
|
|
209
|
+
endsOn: string;
|
|
210
|
+
}, locked: boolean): Promise<number>;
|
|
98
211
|
/** Which business dates a person has punches on, in a range. Drives a bulk recompute. */
|
|
99
212
|
datesWithPunches(tx: Tx, workspaceId: string, personId: string, from: string, to: string): Promise<string[]>;
|
|
100
213
|
/**
|
|
@@ -146,5 +259,4 @@ export declare class AttendanceService {
|
|
|
146
259
|
};
|
|
147
260
|
}>;
|
|
148
261
|
}
|
|
149
|
-
export { inArray, sql };
|
|
150
262
|
//# sourceMappingURL=attendance.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attendance.d.ts","sourceRoot":"","sources":["../../../src/server/services/attendance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,EAAE,EAAU,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"attendance.d.ts","sourceRoot":"","sources":["../../../src/server/services/attendance.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { KernError, uuidv7 } from '@kernhq/kernel';
|
|
2
|
-
import { and, asc, eq, gte, inArray, isNull, lte, sql } from 'drizzle-orm';
|
|
2
|
+
import { and, asc, eq, gte, inArray, isNull, lt, lte, or, sql } from 'drizzle-orm';
|
|
3
3
|
import { weekdayOf } from '../../policy/calendar.js';
|
|
4
|
-
import {
|
|
4
|
+
import { dateIn, previousDate } from '../../policy/time.js';
|
|
5
|
+
import { attributeToShift, computeDay, openState, } from '../../policy/working-time.js';
|
|
5
6
|
import { attendanceDays, leaveRequestDays, punches, scheduleAssignments, schedules } from '../schema.js';
|
|
6
7
|
import { inForceOn } from './db.js';
|
|
8
|
+
import { PolicyService } from './policies.js';
|
|
9
|
+
import { ResolveService } from './resolve.js';
|
|
7
10
|
/** A schedule with no shifts: somebody with no assignment still clocks in, they just owe no hours. */
|
|
8
11
|
export const NO_SCHEDULE = {
|
|
9
12
|
shiftFor: () => null,
|
|
@@ -12,6 +15,18 @@ export const NO_SCHEDULE = {
|
|
|
12
15
|
scheduleId: null,
|
|
13
16
|
};
|
|
14
17
|
export class AttendanceService {
|
|
18
|
+
resolve;
|
|
19
|
+
policies;
|
|
20
|
+
/**
|
|
21
|
+
* Both collaborators are defaulted so `new AttendanceService()` still reads as a leaf service.
|
|
22
|
+
* The period is asked about on every recomputation, and who belongs to a legal entity is asked
|
|
23
|
+
* on every lock — neither question has a second implementation in this module and neither may
|
|
24
|
+
* grow one here.
|
|
25
|
+
*/
|
|
26
|
+
constructor(resolve = new ResolveService(), policies = new PolicyService(resolve)) {
|
|
27
|
+
this.resolve = resolve;
|
|
28
|
+
this.policies = policies;
|
|
29
|
+
}
|
|
15
30
|
/** The schedule in force for a person on a date, as something the pure layer can use. */
|
|
16
31
|
async scheduleFor(tx, workspaceId, personId, on) {
|
|
17
32
|
const [assignment] = await tx
|
|
@@ -50,21 +65,57 @@ export class AttendanceService {
|
|
|
50
65
|
autoClockOutAfterMinutes: schedule.autoClockOutAfterMinutes,
|
|
51
66
|
};
|
|
52
67
|
}
|
|
68
|
+
/**
|
|
69
|
+
* Which shift a punch made at `atMs` joins — decided once, from the punches that are already filed.
|
|
70
|
+
*
|
|
71
|
+
* This is the circularity that made the last three attempts at the night-shift boundary
|
|
72
|
+
* unfixable. The shift a punch belonged to was worked out from the clock alone; the guard that
|
|
73
|
+
* decides whether the punch is even possible was then built by reading `punchesOn(that date)`. So
|
|
74
|
+
* the guard could only ever confirm the attribution's own choice, and where the choice was wrong
|
|
75
|
+
* the person was told they were not clocked in at the end of a shift they had just worked. The
|
|
76
|
+
* fact that settles it — is a shift still open — is a question about punches, so it is asked
|
|
77
|
+
* *before* the attribution instead of after it.
|
|
78
|
+
*
|
|
79
|
+
* Both candidate dates come back in one statement, the punch's own local date and the one before
|
|
80
|
+
* it, on `hr_punches_person_idx`. That is fewer queries than the path it replaces, and it is what
|
|
81
|
+
* makes the guard and the attribution incapable of drifting apart: they are the same rows.
|
|
82
|
+
*/
|
|
83
|
+
async attribute(tx, workspaceId, personId, atMs, timezone, schedule) {
|
|
84
|
+
const local = dateIn(atMs, timezone);
|
|
85
|
+
const yesterday = previousDate(local);
|
|
86
|
+
const rows = await tx
|
|
87
|
+
.select()
|
|
88
|
+
.from(punches)
|
|
89
|
+
.where(and(eq(punches.workspaceId, workspaceId), eq(punches.personId, personId), inArray(punches.businessDate, [yesterday, local]), isNull(punches.voidedByPunchId)))
|
|
90
|
+
.orderBy(asc(punches.at));
|
|
91
|
+
const filedOn = (date) => rows.filter((r) => r.businessDate === date);
|
|
92
|
+
const { businessDate, shift } = attributeToShift(atMs, timezone, (d) => schedule.shiftFor(d), {
|
|
93
|
+
onLocalDate: openState(filedOn(local)).clockedIn,
|
|
94
|
+
onPreviousDate: openState(filedOn(yesterday)).clockedIn,
|
|
95
|
+
workedPreviousDate: filedOn(yesterday).length > 0,
|
|
96
|
+
});
|
|
97
|
+
const mine = filedOn(businessDate);
|
|
98
|
+
return { businessDate, shift, punches: mine, open: openState(mine) };
|
|
99
|
+
}
|
|
53
100
|
/**
|
|
54
101
|
* Record a punch.
|
|
55
102
|
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
103
|
+
* Both the instant and the day it counts towards arrive decided. `at` is the server's clock unless
|
|
104
|
+
* the offline sync path says otherwise, and `businessDate` is `attribute`'s answer for that same
|
|
105
|
+
* instant — this method used to attribute the punch a second time, from its own `new Date()`
|
|
106
|
+
* rather than from the instant the caller had already reasoned about. Two answers to one question,
|
|
107
|
+
* a millisecond apart, is how both ends of one shift end up on two sheets.
|
|
108
|
+
*
|
|
109
|
+
* `clientReportedAt` is kept beside the instant with the measured skew so an offline sync can be
|
|
110
|
+
* told from a device whose clock is wrong — and a claim beyond the threshold is marked `disputed`
|
|
111
|
+
* rather than silently accepted or silently dropped.
|
|
59
112
|
*/
|
|
60
|
-
async record(tx, workspaceId, input
|
|
113
|
+
async record(tx, workspaceId, input) {
|
|
61
114
|
const serverNow = new Date();
|
|
62
|
-
const at = input.claimedAt ?? serverNow;
|
|
63
115
|
const clientAt = input.clientReportedAt ? new Date(input.clientReportedAt) : null;
|
|
64
116
|
const skewMs = clientAt ? clientAt.getTime() - serverNow.getTime() : null;
|
|
65
117
|
// A claim more than an hour out is not a slow network; it is a clock somebody should look at.
|
|
66
|
-
const trust = input.
|
|
67
|
-
const businessDate = businessDateFor(at.getTime(), input.timezone, schedule.shiftFor(new Date(at.getTime()).toISOString().slice(0, 10)));
|
|
118
|
+
const trust = input.claimed ? (Math.abs(skewMs ?? 0) > 3600_000 ? 'disputed' : 'claimed') : 'trusted';
|
|
68
119
|
const [row] = await tx
|
|
69
120
|
.insert(punches)
|
|
70
121
|
.values({
|
|
@@ -72,10 +123,10 @@ export class AttendanceService {
|
|
|
72
123
|
workspaceId,
|
|
73
124
|
personId: input.personId,
|
|
74
125
|
direction: input.direction,
|
|
75
|
-
at,
|
|
126
|
+
at: input.at,
|
|
76
127
|
clientReportedAt: clientAt,
|
|
77
128
|
skewMs,
|
|
78
|
-
businessDate,
|
|
129
|
+
businessDate: input.businessDate,
|
|
79
130
|
timezone: input.timezone,
|
|
80
131
|
method: input.method,
|
|
81
132
|
officeId: input.officeId ?? null,
|
|
@@ -104,13 +155,36 @@ export class AttendanceService {
|
|
|
104
155
|
* month looks identical to one that had nothing to do.
|
|
105
156
|
*/
|
|
106
157
|
async recomputeDay(tx, workspaceId, personId, businessDate, timezone, schedule) {
|
|
158
|
+
const day = and(eq(attendanceDays.workspaceId, workspaceId), eq(attendanceDays.personId, personId), eq(attendanceDays.businessDate, businessDate));
|
|
107
159
|
const [existing] = await tx
|
|
108
160
|
.select({ locked: attendanceDays.locked })
|
|
109
161
|
.from(attendanceDays)
|
|
110
|
-
.where(
|
|
162
|
+
.where(day)
|
|
111
163
|
.limit(1);
|
|
112
|
-
|
|
164
|
+
// Which entity's payroll a day belongs to is a question **about that day**, so it is asked here
|
|
165
|
+
// rather than taken as an argument. Every caller had one to hand and three of them had the
|
|
166
|
+
// wrong one: `clockContext` resolves as of today and its answer was then applied to arbitrary
|
|
167
|
+
// past dates by `punches.void`, `days.recompute` over a whole range, and an approved
|
|
168
|
+
// regularization — so somebody who changed legal entity had March recomputed against the entity
|
|
169
|
+
// they joined in April, found it open, and wrote into a month already filed.
|
|
170
|
+
const { legalEntityId } = await this.resolve.forPerson(tx, workspaceId, personId, businessDate);
|
|
171
|
+
// The column is a *cache* of the period's status, and the period is the authority — asked
|
|
172
|
+
// first, every time, and in both directions. A cache that defaults to false lies about every
|
|
173
|
+
// date the lock swept before the row existed: `periods.lock` stamps the rows that are there,
|
|
174
|
+
// and the first punch on a date inside a closed month then creates a fresh one at the default.
|
|
175
|
+
// Believing a `true` before asking lied the other way, and only ever grew: a row stamped by a
|
|
176
|
+
// lock that has since been reopened, or by a person's employment being corrected underneath
|
|
177
|
+
// one, refused recomputation for ever with nothing behind it.
|
|
178
|
+
//
|
|
179
|
+
// So where a row exists the flag is repaired from the period in whichever direction disagrees —
|
|
180
|
+
// upwards here, downwards in the rebuild below. Where none exists none is written: an absent
|
|
181
|
+
// sheet reads as "nothing was filed for that day", which is true, while a permanently frozen
|
|
182
|
+
// half-day reads as a figure somebody can act on, which it is not.
|
|
183
|
+
if (await this.policies.isLocked(tx, workspaceId, businessDate, legalEntityId)) {
|
|
184
|
+
if (existing && !existing.locked)
|
|
185
|
+
await tx.update(attendanceDays).set({ locked: true }).where(day);
|
|
113
186
|
return { locked: true };
|
|
187
|
+
}
|
|
114
188
|
const rows = await this.punchesOn(tx, workspaceId, personId, businessDate);
|
|
115
189
|
const punchInputs = rows.map((r) => ({
|
|
116
190
|
at: r.at.getTime(),
|
|
@@ -123,12 +197,14 @@ export class AttendanceService {
|
|
|
123
197
|
.from(leaveRequestDays)
|
|
124
198
|
.where(and(eq(leaveRequestDays.workspaceId, workspaceId), eq(leaveRequestDays.personId, personId), eq(leaveRequestDays.date, businessDate), eq(leaveRequestDays.counted, true), eq(leaveRequestDays.status, 'approved')))
|
|
125
199
|
.limit(1);
|
|
200
|
+
const overtimePolicy = await this.overtimePolicyFor(tx, workspaceId, personId, businessDate);
|
|
126
201
|
const computed = computeDay({
|
|
127
202
|
businessDate,
|
|
128
203
|
timeZone: timezone,
|
|
129
204
|
shift: schedule.shiftFor(businessDate),
|
|
130
205
|
punches: punchInputs,
|
|
131
206
|
rounding: schedule.rounding,
|
|
207
|
+
overtime: overtimePolicy,
|
|
132
208
|
excused: !!onLeave,
|
|
133
209
|
});
|
|
134
210
|
const status = onLeave && computed.workedMinutes === 0 ? 'leave' : computed.status;
|
|
@@ -143,6 +219,7 @@ export class AttendanceService {
|
|
|
143
219
|
workedMinutes: computed.workedMinutes,
|
|
144
220
|
breakMinutes: computed.breakMinutes,
|
|
145
221
|
overtimeMinutes: computed.overtimeMinutes,
|
|
222
|
+
beyondCapMinutes: computed.beyondCapMinutes,
|
|
146
223
|
lateMinutes: computed.lateMinutes,
|
|
147
224
|
earlyLeaveMinutes: computed.earlyLeaveMinutes,
|
|
148
225
|
status,
|
|
@@ -160,6 +237,7 @@ export class AttendanceService {
|
|
|
160
237
|
workedMinutes: computed.workedMinutes,
|
|
161
238
|
breakMinutes: computed.breakMinutes,
|
|
162
239
|
overtimeMinutes: computed.overtimeMinutes,
|
|
240
|
+
beyondCapMinutes: computed.beyondCapMinutes,
|
|
163
241
|
lateMinutes: computed.lateMinutes,
|
|
164
242
|
earlyLeaveMinutes: computed.earlyLeaveMinutes,
|
|
165
243
|
status,
|
|
@@ -169,10 +247,145 @@ export class AttendanceService {
|
|
|
169
247
|
lastOut: computed.lastOut ? new Date(computed.lastOut) : null,
|
|
170
248
|
policyHash: hashSchedule(schedule),
|
|
171
249
|
computedAt: new Date(),
|
|
250
|
+
// The other half of the repair: no period closes this date, so a row still carrying the
|
|
251
|
+
// flag lets go of it here. Rebuilding the figures while leaving `locked` true would
|
|
252
|
+
// publish a sheet nothing can move next to a flag saying nothing may.
|
|
253
|
+
locked: false,
|
|
172
254
|
},
|
|
173
255
|
});
|
|
174
256
|
return { locked: false };
|
|
175
257
|
}
|
|
258
|
+
/**
|
|
259
|
+
* The overtime rules that apply to one person on one date, as numbers a pure function can use.
|
|
260
|
+
*
|
|
261
|
+
* Resolved here rather than passed in, unlike the schedule: `computeDay` may not touch the
|
|
262
|
+
* database and every caller of `recomputeDay` would otherwise have to walk the policy ladder
|
|
263
|
+
* itself, which is how a rule ends up applied on three paths out of four.
|
|
264
|
+
*
|
|
265
|
+
* Undefined where no policy applies, which is what a workspace that never configured overtime
|
|
266
|
+
* means — every minute past the schedule counts, exactly as it did before the policy was read at
|
|
267
|
+
* all.
|
|
268
|
+
*/
|
|
269
|
+
async overtimePolicyFor(tx, workspaceId, personId, businessDate) {
|
|
270
|
+
const resolved = await this.policies.forPerson(tx, workspaceId, personId, 'overtime', businessDate);
|
|
271
|
+
if (!resolved.config)
|
|
272
|
+
return undefined;
|
|
273
|
+
const config = resolved.config;
|
|
274
|
+
const capMinutes = config.capMinutesPerYear ?? null;
|
|
275
|
+
return {
|
|
276
|
+
thresholdMinutes: config.thresholdMinutes ?? 0,
|
|
277
|
+
capMinutes,
|
|
278
|
+
alreadyCountedMinutes: capMinutes === null ? 0 : await this.overtimeCountedBefore(tx, workspaceId, personId, businessDate),
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Overtime already counted this year, on the days *before* this one.
|
|
283
|
+
*
|
|
284
|
+
* Strictly before, so a day's figure depends only on days that precede it and recomputing one
|
|
285
|
+
* cannot depend on the order the sweep happens to visit them in. The days after it are then stale
|
|
286
|
+
* against a cap that filled earlier, which the nightly recomputation settles — an order-dependent
|
|
287
|
+
* sheet would not settle at all.
|
|
288
|
+
*
|
|
289
|
+
* The year is the calendar one, because `capMinutesPerYear` is what the config offers; a legal
|
|
290
|
+
* entity closing its year elsewhere would need the cap to say so first.
|
|
291
|
+
*/
|
|
292
|
+
async overtimeCountedBefore(tx, workspaceId, personId, businessDate) {
|
|
293
|
+
const [row] = await tx
|
|
294
|
+
.select({ minutes: sql `coalesce(sum(${attendanceDays.overtimeMinutes}), 0)` })
|
|
295
|
+
.from(attendanceDays)
|
|
296
|
+
.where(and(eq(attendanceDays.workspaceId, workspaceId), eq(attendanceDays.personId, personId), gte(attendanceDays.businessDate, `${businessDate.slice(0, 4)}-01-01`), lt(attendanceDays.businessDate, businessDate)));
|
|
297
|
+
return Number(row?.minutes ?? 0);
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Stamp `locked` on every day a period covers — and on nobody else's.
|
|
301
|
+
*
|
|
302
|
+
* A period with no legal entity is the whole workspace's. One that names an entity closes *that
|
|
303
|
+
* entity's* month: `PolicyService.isLocked` has always read it that way, and until this method
|
|
304
|
+
* existed the day sheet did not, so closing the Turkish entity's January froze the Dutch and
|
|
305
|
+
* Iranian ones too. Two enforcement mechanisms disagreeing about who a period covers is worse
|
|
306
|
+
* than either of them being wrong on its own, because each looks right from where it is read.
|
|
307
|
+
*
|
|
308
|
+
* Membership is asked of the resolution ladder rather than joined here: which entity somebody is
|
|
309
|
+
* in is not a column on `people` — the employment in force says, and where it does not, their
|
|
310
|
+
* primary office does — and that order has exactly one implementation in this module. It is asked
|
|
311
|
+
* **as of each day**, the same date `isLocked` will be asked about later, because the day is what
|
|
312
|
+
* belongs to an entity: resolving everybody once at the period's last day stamped the whole month
|
|
313
|
+
* of somebody who transferred in halfway through it, including the half they spent elsewhere —
|
|
314
|
+
* days no Dutch period had closed, frozen by a Turkish one.
|
|
315
|
+
*
|
|
316
|
+
* Releasing is not the mirror of stamping. The exclusion constraint keys on
|
|
317
|
+
* `coalesce(legal_entity_id, …)`, so a workspace-wide period and an entity's period may cover the
|
|
318
|
+
* same dates on purpose — and reopening the narrower one must not unlock a month the wider one
|
|
319
|
+
* has filed. So a day is released only where nothing still closes it. That reads the period's own
|
|
320
|
+
* status, which the handler writes before calling this: a period reopening itself would otherwise
|
|
321
|
+
* be the reason it cannot let go.
|
|
322
|
+
*/
|
|
323
|
+
async setPeriodLock(tx, workspaceId, period, locked) {
|
|
324
|
+
const inRange = [
|
|
325
|
+
eq(attendanceDays.workspaceId, workspaceId),
|
|
326
|
+
gte(attendanceDays.businessDate, period.startsOn),
|
|
327
|
+
lte(attendanceDays.businessDate, period.endsOn),
|
|
328
|
+
];
|
|
329
|
+
// Closing a period that names no entity closes the workspace, and there is nothing to ask the
|
|
330
|
+
// ladder about: one statement, as it always was. Every other combination needs to know which
|
|
331
|
+
// entity somebody was in on the day — to decide whether the period covers them, or whether
|
|
332
|
+
// anything else still does.
|
|
333
|
+
if (!period.legalEntityId && locked) {
|
|
334
|
+
const swept = await tx
|
|
335
|
+
.update(attendanceDays)
|
|
336
|
+
.set({ locked })
|
|
337
|
+
.where(and(...inRange))
|
|
338
|
+
.returning({ id: attendanceDays.id });
|
|
339
|
+
return swept.length;
|
|
340
|
+
}
|
|
341
|
+
const candidates = await tx
|
|
342
|
+
.selectDistinct({ personId: attendanceDays.personId, businessDate: attendanceDays.businessDate })
|
|
343
|
+
.from(attendanceDays)
|
|
344
|
+
.where(and(...inRange));
|
|
345
|
+
if (!candidates.length)
|
|
346
|
+
return 0;
|
|
347
|
+
// One resolution per date rather than per row: a month is at most thirty-one ladder walks
|
|
348
|
+
// whatever the headcount, where a walk per person-day would be that times everybody.
|
|
349
|
+
const peopleOn = new Map();
|
|
350
|
+
for (const c of candidates)
|
|
351
|
+
peopleOn.set(c.businessDate, [...(peopleOn.get(c.businessDate) ?? []), c.personId]);
|
|
352
|
+
const entityOn = new Map();
|
|
353
|
+
for (const [date, ids] of peopleOn) {
|
|
354
|
+
const resolved = await this.resolve.forPeople(tx, workspaceId, [...new Set(ids)], date);
|
|
355
|
+
for (const id of ids)
|
|
356
|
+
entityOn.set(`${id}|${date}`, resolved.get(id)?.legalEntityId ?? null);
|
|
357
|
+
}
|
|
358
|
+
const stillClosed = new Map();
|
|
359
|
+
const closedByAnything = async (date, entity) => {
|
|
360
|
+
const key = `${entity ?? 'workspace'}|${date}`;
|
|
361
|
+
const seen = stillClosed.get(key);
|
|
362
|
+
if (seen !== undefined)
|
|
363
|
+
return seen;
|
|
364
|
+
const answer = await this.policies.isLocked(tx, workspaceId, date, entity);
|
|
365
|
+
stillClosed.set(key, answer);
|
|
366
|
+
return answer;
|
|
367
|
+
};
|
|
368
|
+
const mine = [];
|
|
369
|
+
for (const c of candidates) {
|
|
370
|
+
const entity = entityOn.get(`${c.personId}|${c.businessDate}`) ?? null;
|
|
371
|
+
if (period.legalEntityId && entity !== period.legalEntityId)
|
|
372
|
+
continue;
|
|
373
|
+
if (!locked && (await closedByAnything(c.businessDate, entity)))
|
|
374
|
+
continue;
|
|
375
|
+
mine.push(c);
|
|
376
|
+
}
|
|
377
|
+
if (!mine.length)
|
|
378
|
+
return 0;
|
|
379
|
+
const days = new Map();
|
|
380
|
+
for (const m of mine)
|
|
381
|
+
days.set(m.personId, [...(days.get(m.personId) ?? []), m.businessDate]);
|
|
382
|
+
const rows = await tx
|
|
383
|
+
.update(attendanceDays)
|
|
384
|
+
.set({ locked })
|
|
385
|
+
.where(and(eq(attendanceDays.workspaceId, workspaceId), or(...[...days].map(([personId, dates]) => and(eq(attendanceDays.personId, personId), inArray(attendanceDays.businessDate, dates))))))
|
|
386
|
+
.returning({ id: attendanceDays.id });
|
|
387
|
+
return rows.length;
|
|
388
|
+
}
|
|
176
389
|
/** Which business dates a person has punches on, in a range. Drives a bulk recompute. */
|
|
177
390
|
async datesWithPunches(tx, workspaceId, personId, from, to) {
|
|
178
391
|
const rows = await tx
|
|
@@ -235,5 +448,4 @@ export class AttendanceService {
|
|
|
235
448
|
function hashSchedule(schedule) {
|
|
236
449
|
return `${schedule.scheduleId ?? 'none'}:${schedule.rounding.stepMinutes}:${schedule.rounding.direction}`;
|
|
237
450
|
}
|
|
238
|
-
export { inArray, sql };
|
|
239
451
|
//# sourceMappingURL=attendance.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attendance.js","sourceRoot":"","sources":["../../../src/server/services/attendance.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"attendance.js","sourceRoot":"","sources":["../../../src/server/services/attendance.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { type Tx } from '@kernhq/kernel';
|
|
2
|
-
import { inArray } from 'drizzle-orm';
|
|
3
2
|
import type { LedgerKind } from '../../contract/index.js';
|
|
4
3
|
/**
|
|
5
4
|
* The leave balance, and the concurrency that makes it hard.
|
|
@@ -131,5 +130,4 @@ export declare class LedgerService {
|
|
|
131
130
|
rebuildCursors(tx: Tx, workspaceId: string, personIds: string[]): Promise<void>;
|
|
132
131
|
}
|
|
133
132
|
export declare const yearOf: (isoDate: string) => number;
|
|
134
|
-
export { inArray };
|
|
135
133
|
//# sourceMappingURL=ledger.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ledger.d.ts","sourceRoot":"","sources":["../../../src/server/services/ledger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,EAAE,EAAU,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"ledger.d.ts","sourceRoot":"","sources":["../../../src/server/services/ledger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,EAAE,EAAU,MAAM,gBAAgB,CAAA;AAE3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AAGzD;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,cAAc,EAAE,MAAM,CAAA;IACtB,aAAa,EAAE,MAAM,CAAA;IACrB,cAAc,EAAE,MAAM,CAAA;CACvB;AAED,0FAA0F;AAC1F,eAAO,MAAM,MAAM,GAAI,SAAS,MAAM,EAAE,MAAM,MAAM,KAAG,MACgD,CAAA;AAEvG,sFAAsF;AACtF,eAAO,MAAM,eAAe,QAAS,CAAA;AAErC,qBAAa,aAAa;IACxB;;;;;;OAMG;IACG,QAAQ,CAAC,EAAE,EAAE,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;;;;cAmDvD,KAAK,GAAG,UAAU,GAAG,MAAM;;;;;;;;;IAYpD;;;;;OAKG;IACG,WAAW,CACf,EAAE,EAAE,EAAE,EACN,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC;IA6BlB,gEAAgE;IAC1D,MAAM,CACV,EAAE,EAAE,EAAE,EACN,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE;QACL,QAAQ,EAAE,MAAM,CAAA;QAChB,WAAW,EAAE,MAAM,CAAA;QACnB,IAAI,EAAE,UAAU,CAAA;QAChB,aAAa,EAAE,MAAM,CAAA;QACrB,WAAW,EAAE,MAAM,CAAA;QACnB,UAAU,EAAE,MAAM,CAAA;QAClB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACzB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QAC/B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACtB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACzB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAC3B;;;;;;;;;;;;;;;;IAyBH;;;;;;OAMG;IACG,OAAO,CACX,EAAE,EAAE,EAAE,EACN,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,EAAE,EAAE,MAAM;;;;;;;;;;;;;;;;IAiCZ,yDAAyD;IACnD,UAAU,CAAC,EAAE,EAAE,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;;;;;;;;;;;;;;;;IAO/D,oGAAoG;IAC9F,cAAc,CAAC,EAAE,EAAE,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE;CAuBtE;AAED,eAAO,MAAM,MAAM,GAAI,SAAS,MAAM,KAAG,MAAqC,CAAA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { KernError, uuidv7 } from '@kernhq/kernel';
|
|
2
|
-
import { and, eq,
|
|
2
|
+
import { and, eq, sql } from 'drizzle-orm';
|
|
3
3
|
import { leaveBalanceCursor, leaveLedger, leaveRequestDays, leaveTypes } from '../schema.js';
|
|
4
4
|
/** A minute count in whatever unit the type displays. Hours to one place, days to two. */
|
|
5
5
|
export const toUnit = (minutes, unit) => unit === 'hour' ? Math.round((minutes / 60) * 10) / 10 : Math.round((minutes / (60 * 8)) * 100) / 100;
|
|
@@ -174,5 +174,4 @@ export class LedgerService {
|
|
|
174
174
|
}
|
|
175
175
|
}
|
|
176
176
|
export const yearOf = (isoDate) => Number(isoDate.slice(0, 4));
|
|
177
|
-
export { inArray };
|
|
178
177
|
//# sourceMappingURL=ledger.js.map
|