@classytic/payroll 1.0.2 → 2.3.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.
Potentially problematic release.
This version of @classytic/payroll might be problematic. Click here for more details.
- package/README.md +2599 -574
- package/dist/calculators/index.d.ts +433 -0
- package/dist/calculators/index.js +283 -0
- package/dist/calculators/index.js.map +1 -0
- package/dist/core/index.d.ts +314 -0
- package/dist/core/index.js +1166 -0
- package/dist/core/index.js.map +1 -0
- package/dist/employee-identity-DXhgOgXE.d.ts +473 -0
- package/dist/employee.factory-BlZqhiCk.d.ts +189 -0
- package/dist/idempotency-Cw2CWicb.d.ts +52 -0
- package/dist/index.d.ts +902 -0
- package/dist/index.js +9108 -0
- package/dist/index.js.map +1 -0
- package/dist/jurisdiction/index.d.ts +660 -0
- package/dist/jurisdiction/index.js +533 -0
- package/dist/jurisdiction/index.js.map +1 -0
- package/dist/payroll.d.ts +429 -0
- package/dist/payroll.js +5192 -0
- package/dist/payroll.js.map +1 -0
- package/dist/schemas/index.d.ts +3262 -0
- package/dist/schemas/index.js +780 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/services/index.d.ts +582 -0
- package/dist/services/index.js +2172 -0
- package/dist/services/index.js.map +1 -0
- package/dist/shift-compliance/index.d.ts +1171 -0
- package/dist/shift-compliance/index.js +1479 -0
- package/dist/shift-compliance/index.js.map +1 -0
- package/dist/types-BN3K_Uhr.d.ts +1842 -0
- package/dist/utils/index.d.ts +893 -0
- package/dist/utils/index.js +1515 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +72 -37
- package/dist/types/config.d.ts +0 -162
- package/dist/types/core/compensation.manager.d.ts +0 -54
- package/dist/types/core/employment.manager.d.ts +0 -49
- package/dist/types/core/payroll.manager.d.ts +0 -60
- package/dist/types/enums.d.ts +0 -117
- package/dist/types/factories/compensation.factory.d.ts +0 -196
- package/dist/types/factories/employee.factory.d.ts +0 -149
- package/dist/types/factories/payroll.factory.d.ts +0 -319
- package/dist/types/hrm.orchestrator.d.ts +0 -47
- package/dist/types/index.d.ts +0 -20
- package/dist/types/init.d.ts +0 -30
- package/dist/types/models/payroll-record.model.d.ts +0 -3
- package/dist/types/plugins/employee.plugin.d.ts +0 -2
- package/dist/types/schemas/employment.schema.d.ts +0 -959
- package/dist/types/services/compensation.service.d.ts +0 -94
- package/dist/types/services/employee.service.d.ts +0 -28
- package/dist/types/services/payroll.service.d.ts +0 -30
- package/dist/types/utils/calculation.utils.d.ts +0 -26
- package/dist/types/utils/date.utils.d.ts +0 -35
- package/dist/types/utils/logger.d.ts +0 -12
- package/dist/types/utils/query-builders.d.ts +0 -83
- package/dist/types/utils/validation.utils.d.ts +0 -33
- package/payroll.d.ts +0 -241
- package/src/config.js +0 -177
- package/src/core/compensation.manager.js +0 -242
- package/src/core/employment.manager.js +0 -224
- package/src/core/payroll.manager.js +0 -499
- package/src/enums.js +0 -141
- package/src/factories/compensation.factory.js +0 -198
- package/src/factories/employee.factory.js +0 -173
- package/src/factories/payroll.factory.js +0 -413
- package/src/hrm.orchestrator.js +0 -139
- package/src/index.js +0 -172
- package/src/init.js +0 -62
- package/src/models/payroll-record.model.js +0 -126
- package/src/plugins/employee.plugin.js +0 -164
- package/src/schemas/employment.schema.js +0 -126
- package/src/services/compensation.service.js +0 -231
- package/src/services/employee.service.js +0 -162
- package/src/services/payroll.service.js +0 -213
- package/src/utils/calculation.utils.js +0 -91
- package/src/utils/date.utils.js +0 -120
- package/src/utils/logger.js +0 -36
- package/src/utils/query-builders.js +0 -185
- package/src/utils/validation.utils.js +0 -122
|
@@ -0,0 +1,1171 @@
|
|
|
1
|
+
import { O as ObjectIdLike } from '../types-BN3K_Uhr.js';
|
|
2
|
+
import * as mongoose from 'mongoose';
|
|
3
|
+
import { Schema, SchemaDefinition } from 'mongoose';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @classytic/payroll - Shift Compliance Types
|
|
7
|
+
*
|
|
8
|
+
* Clean, modern type definitions for shift-based attendance management.
|
|
9
|
+
* No legacy baggage - one proper standard.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/** How penalties are calculated */
|
|
13
|
+
type PenaltyMode = 'flat' | 'per-minute' | 'percentage' | 'tiered';
|
|
14
|
+
/** When overtime kicks in */
|
|
15
|
+
type OvertimeMode = 'daily' | 'weekly' | 'monthly';
|
|
16
|
+
/** When to reset occurrence counters */
|
|
17
|
+
type ResetPeriod = 'daily' | 'weekly' | 'monthly' | 'quarterly' | 'yearly';
|
|
18
|
+
/** Clock-in rounding mode */
|
|
19
|
+
type RoundingMode = 'nearest' | 'up' | 'down';
|
|
20
|
+
/**
|
|
21
|
+
* Tiered penalty configuration for progressive discipline.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* [
|
|
26
|
+
* { from: 1, to: 2, penalty: 0, warning: true }, // 1st-2nd: warning only
|
|
27
|
+
* { from: 3, to: 4, penalty: 25 }, // 3rd-4th: $25
|
|
28
|
+
* { from: 5, penalty: 50 } // 5th+: $50
|
|
29
|
+
* ]
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
interface PenaltyTier {
|
|
33
|
+
/** Occurrence number start (inclusive) */
|
|
34
|
+
from: number;
|
|
35
|
+
/** Occurrence number end (inclusive, optional for open-ended) */
|
|
36
|
+
to?: number;
|
|
37
|
+
/** Penalty amount for this tier */
|
|
38
|
+
penalty: number;
|
|
39
|
+
/** If true, log warning but don't deduct money */
|
|
40
|
+
warning?: boolean;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Maximum penalties per period configuration
|
|
44
|
+
*/
|
|
45
|
+
interface MaxPenaltiesPerPeriod {
|
|
46
|
+
/** Maximum number of penalties allowed */
|
|
47
|
+
count: number;
|
|
48
|
+
/** Period type */
|
|
49
|
+
period: ResetPeriod;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Weekend premium configuration
|
|
53
|
+
*/
|
|
54
|
+
interface WeekendPremium {
|
|
55
|
+
/** Saturday premium multiplier (e.g., 1.5 for time-and-a-half) */
|
|
56
|
+
saturday: number;
|
|
57
|
+
/** Sunday premium multiplier (e.g., 2.0 for double time) */
|
|
58
|
+
sunday: number;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Night shift differential configuration
|
|
62
|
+
*/
|
|
63
|
+
interface NightShiftDifferential {
|
|
64
|
+
/** Start hour (24h format, e.g., 22 = 10pm) */
|
|
65
|
+
startHour: number;
|
|
66
|
+
/** End hour (24h format, e.g., 6 = 6am) */
|
|
67
|
+
endHour: number;
|
|
68
|
+
/** Premium multiplier (e.g., 1.2 = 20% extra) */
|
|
69
|
+
multiplier: number;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Late arrival policy configuration
|
|
73
|
+
*/
|
|
74
|
+
interface LateArrivalPolicy {
|
|
75
|
+
/** Enable late arrival tracking */
|
|
76
|
+
enabled: boolean;
|
|
77
|
+
/** Grace period in minutes (no penalty if late < this) */
|
|
78
|
+
gracePeriod: number;
|
|
79
|
+
/** How to calculate penalty */
|
|
80
|
+
mode: PenaltyMode;
|
|
81
|
+
/** Fixed penalty amount per occurrence */
|
|
82
|
+
flatAmount?: number;
|
|
83
|
+
/** Penalty per minute late */
|
|
84
|
+
perMinuteRate?: number;
|
|
85
|
+
/** Penalty as percentage of daily wage (e.g., 2 = 2%) */
|
|
86
|
+
percentageRate?: number;
|
|
87
|
+
/** Progressive penalties based on occurrence count */
|
|
88
|
+
tiers?: PenaltyTier[];
|
|
89
|
+
/** Maximum penalties allowed per period */
|
|
90
|
+
maxPenaltiesPerPeriod?: MaxPenaltiesPerPeriod;
|
|
91
|
+
/** Maximum total penalty amount per period */
|
|
92
|
+
maxPenaltyAmount?: {
|
|
93
|
+
amount: number;
|
|
94
|
+
period: ResetPeriod;
|
|
95
|
+
};
|
|
96
|
+
/** When to reset occurrence counter */
|
|
97
|
+
resetOccurrenceCount?: ResetPeriod;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Early departure policy configuration
|
|
101
|
+
* (Same structure as late arrival)
|
|
102
|
+
*/
|
|
103
|
+
type EarlyDeparturePolicy = LateArrivalPolicy;
|
|
104
|
+
/**
|
|
105
|
+
* Overtime bonus configuration
|
|
106
|
+
*/
|
|
107
|
+
interface OvertimePolicy {
|
|
108
|
+
/** Enable overtime bonuses */
|
|
109
|
+
enabled: boolean;
|
|
110
|
+
/** When overtime kicks in */
|
|
111
|
+
mode: OvertimeMode;
|
|
112
|
+
/** Hours per day before overtime (e.g., 8) */
|
|
113
|
+
dailyThreshold?: number;
|
|
114
|
+
/** Overtime multiplier for daily (e.g., 1.5 = time and half) */
|
|
115
|
+
dailyMultiplier?: number;
|
|
116
|
+
/** Hours per week before overtime (e.g., 40) */
|
|
117
|
+
weeklyThreshold?: number;
|
|
118
|
+
/** Overtime multiplier for weekly */
|
|
119
|
+
weeklyMultiplier?: number;
|
|
120
|
+
/** Hours per month before overtime (e.g., 160) */
|
|
121
|
+
monthlyThreshold?: number;
|
|
122
|
+
/** Overtime multiplier for monthly */
|
|
123
|
+
monthlyMultiplier?: number;
|
|
124
|
+
/** Weekend premium pay (null = disabled) */
|
|
125
|
+
weekendPremium?: WeekendPremium;
|
|
126
|
+
/** Night shift premium (null = disabled) */
|
|
127
|
+
nightShiftDifferential?: NightShiftDifferential;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Clock-in rounding configuration
|
|
131
|
+
*/
|
|
132
|
+
interface ClockRoundingPolicy {
|
|
133
|
+
/** Enable clock-in rounding */
|
|
134
|
+
enabled: boolean;
|
|
135
|
+
/** Round to nearest X minutes */
|
|
136
|
+
roundTo: 5 | 10 | 15;
|
|
137
|
+
/** Rounding mode */
|
|
138
|
+
mode: RoundingMode;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Complete attendance policy configuration.
|
|
142
|
+
*
|
|
143
|
+
* This is what organizations define and what we use for calculations.
|
|
144
|
+
* Users can store this in DB, config file, or pass directly.
|
|
145
|
+
*/
|
|
146
|
+
interface AttendancePolicy {
|
|
147
|
+
/** Unique policy ID (optional, for DB storage) */
|
|
148
|
+
id?: string;
|
|
149
|
+
/** Organization this policy belongs to (optional, for multi-tenant) */
|
|
150
|
+
organizationId?: ObjectIdLike;
|
|
151
|
+
/** Policy name for display */
|
|
152
|
+
name: string;
|
|
153
|
+
/** Policy description */
|
|
154
|
+
description?: string;
|
|
155
|
+
/** Who this policy applies to (optional, for targeted policies) */
|
|
156
|
+
appliesTo?: {
|
|
157
|
+
departments?: string[];
|
|
158
|
+
positions?: string[];
|
|
159
|
+
employeeIds?: ObjectIdLike[];
|
|
160
|
+
all?: boolean;
|
|
161
|
+
};
|
|
162
|
+
/** Late arrival rules */
|
|
163
|
+
lateArrival: LateArrivalPolicy;
|
|
164
|
+
/** Early departure rules */
|
|
165
|
+
earlyDeparture: EarlyDeparturePolicy;
|
|
166
|
+
/** Overtime bonus rules */
|
|
167
|
+
overtime: OvertimePolicy;
|
|
168
|
+
/** Clock-in rounding rules */
|
|
169
|
+
clockRounding?: ClockRoundingPolicy;
|
|
170
|
+
/** When this policy becomes effective */
|
|
171
|
+
effectiveFrom: Date;
|
|
172
|
+
/** When this policy expires (null = no expiry) */
|
|
173
|
+
effectiveTo?: Date | null;
|
|
174
|
+
/** Is this policy active */
|
|
175
|
+
active: boolean;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Single late arrival occurrence
|
|
179
|
+
*/
|
|
180
|
+
interface LateOccurrence {
|
|
181
|
+
/** Date of late arrival */
|
|
182
|
+
date: Date;
|
|
183
|
+
/** Scheduled clock-in time */
|
|
184
|
+
scheduledTime: Date;
|
|
185
|
+
/** Actual clock-in time */
|
|
186
|
+
actualTime: Date;
|
|
187
|
+
/** Minutes late (calculated: actual - scheduled) */
|
|
188
|
+
minutesLate: number;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Single early departure occurrence
|
|
192
|
+
*/
|
|
193
|
+
interface EarlyOccurrence {
|
|
194
|
+
/** Date of early departure */
|
|
195
|
+
date: Date;
|
|
196
|
+
/** Scheduled clock-out time */
|
|
197
|
+
scheduledTime: Date;
|
|
198
|
+
/** Actual clock-out time */
|
|
199
|
+
actualTime: Date;
|
|
200
|
+
/** Minutes early (calculated: scheduled - actual) */
|
|
201
|
+
minutesEarly: number;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Single overtime occurrence
|
|
205
|
+
*/
|
|
206
|
+
interface OvertimeOccurrence {
|
|
207
|
+
/** Date of overtime */
|
|
208
|
+
date: Date;
|
|
209
|
+
/** Type of overtime */
|
|
210
|
+
type: 'daily' | 'weekly' | 'monthly' | 'weekend-saturday' | 'weekend-sunday' | 'night-shift';
|
|
211
|
+
/** Overtime hours */
|
|
212
|
+
hours: number;
|
|
213
|
+
/** Applicable multiplier */
|
|
214
|
+
multiplier: number;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Shift compliance data for a period.
|
|
218
|
+
*
|
|
219
|
+
* This is what users send us - we do the calculations.
|
|
220
|
+
*/
|
|
221
|
+
interface ShiftComplianceData {
|
|
222
|
+
/** Number of late arrivals */
|
|
223
|
+
lateArrivals?: number;
|
|
224
|
+
/** Total minutes late (sum of all occurrences) */
|
|
225
|
+
totalLateMinutes?: number;
|
|
226
|
+
/** Detailed late occurrences (optional, for breakdown) */
|
|
227
|
+
lateOccurrences?: LateOccurrence[];
|
|
228
|
+
/** Number of early departures */
|
|
229
|
+
earlyDepartures?: number;
|
|
230
|
+
/** Total minutes early */
|
|
231
|
+
totalEarlyMinutes?: number;
|
|
232
|
+
/** Detailed early occurrences */
|
|
233
|
+
earlyOccurrences?: EarlyOccurrence[];
|
|
234
|
+
/** Total overtime hours */
|
|
235
|
+
overtimeHours?: number;
|
|
236
|
+
/** Total overtime days (for daily mode) */
|
|
237
|
+
overtimeDays?: number;
|
|
238
|
+
/** Detailed overtime breakdown */
|
|
239
|
+
overtimeOccurrences?: OvertimeOccurrence[];
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Late penalty calculation result
|
|
243
|
+
*/
|
|
244
|
+
interface LatePenaltyResult {
|
|
245
|
+
/** Total penalty amount */
|
|
246
|
+
amount: number;
|
|
247
|
+
/** Number of occurrences processed */
|
|
248
|
+
occurrences: number;
|
|
249
|
+
/** Breakdown per occurrence */
|
|
250
|
+
breakdown: Array<{
|
|
251
|
+
date: Date;
|
|
252
|
+
minutesLate: number;
|
|
253
|
+
penaltyAmount: number;
|
|
254
|
+
tier?: number;
|
|
255
|
+
waived: boolean;
|
|
256
|
+
reason?: string;
|
|
257
|
+
}>;
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Early departure penalty result
|
|
261
|
+
*/
|
|
262
|
+
type EarlyDeparturePenaltyResult = LatePenaltyResult;
|
|
263
|
+
/**
|
|
264
|
+
* Overtime bonus calculation result
|
|
265
|
+
*/
|
|
266
|
+
interface OvertimeBonusResult {
|
|
267
|
+
/** Total bonus amount */
|
|
268
|
+
amount: number;
|
|
269
|
+
/** Total overtime hours */
|
|
270
|
+
hours: number;
|
|
271
|
+
/** Breakdown by type */
|
|
272
|
+
breakdown: Array<{
|
|
273
|
+
date: Date;
|
|
274
|
+
type: string;
|
|
275
|
+
hours: number;
|
|
276
|
+
rate: number;
|
|
277
|
+
multiplier: number;
|
|
278
|
+
amount: number;
|
|
279
|
+
}>;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Shift differential calculation result
|
|
283
|
+
*/
|
|
284
|
+
interface ShiftDifferentialResult {
|
|
285
|
+
/** Total differential amount */
|
|
286
|
+
amount: number;
|
|
287
|
+
/** Hours that qualify for differential */
|
|
288
|
+
hours: number;
|
|
289
|
+
/** Type of differential */
|
|
290
|
+
type: 'night' | 'weekend';
|
|
291
|
+
/** Multiplier applied */
|
|
292
|
+
multiplier: number;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Complete shift compliance calculation result.
|
|
296
|
+
*
|
|
297
|
+
* This is what we return after processing.
|
|
298
|
+
*/
|
|
299
|
+
interface ShiftComplianceResult {
|
|
300
|
+
/** Late arrival penalties */
|
|
301
|
+
latePenalty: LatePenaltyResult;
|
|
302
|
+
/** Early departure penalties */
|
|
303
|
+
earlyDeparturePenalty: EarlyDeparturePenaltyResult;
|
|
304
|
+
/** Overtime bonuses */
|
|
305
|
+
overtimeBonus: OvertimeBonusResult;
|
|
306
|
+
/** Shift differential bonuses (if any) */
|
|
307
|
+
shiftDifferential?: ShiftDifferentialResult;
|
|
308
|
+
/** Total penalties (to deduct from salary) */
|
|
309
|
+
totalPenalties: number;
|
|
310
|
+
/** Total bonuses (to add to salary) */
|
|
311
|
+
totalBonuses: number;
|
|
312
|
+
/** Net adjustment (bonuses - penalties) */
|
|
313
|
+
netAdjustment: number;
|
|
314
|
+
/** Compliance score (0-100) */
|
|
315
|
+
complianceScore: number;
|
|
316
|
+
/** Total occurrence count (late + early) */
|
|
317
|
+
occurrenceCount: number;
|
|
318
|
+
/** Is employee at risk (near termination threshold) */
|
|
319
|
+
isAtRisk: boolean;
|
|
320
|
+
/** Policy ID that was used */
|
|
321
|
+
policyId?: string;
|
|
322
|
+
/** Policy name */
|
|
323
|
+
policyName: string;
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Input for shift compliance calculation
|
|
327
|
+
*/
|
|
328
|
+
interface CalculateShiftComplianceInput {
|
|
329
|
+
/** Attendance data for the period */
|
|
330
|
+
attendance: ShiftComplianceData;
|
|
331
|
+
/** Policy to apply */
|
|
332
|
+
policy: AttendancePolicy;
|
|
333
|
+
/** Daily wage (for percentage-based penalties) */
|
|
334
|
+
dailyWage: number;
|
|
335
|
+
/** Hourly rate (for overtime calculations) */
|
|
336
|
+
hourlyRate: number;
|
|
337
|
+
/** Current occurrence count (for tiered penalties, optional) */
|
|
338
|
+
currentOccurrenceCount?: number;
|
|
339
|
+
/** Employee ID (for logging, optional) */
|
|
340
|
+
employeeId?: ObjectIdLike;
|
|
341
|
+
/** Period info (for logging, optional) */
|
|
342
|
+
period?: {
|
|
343
|
+
month: number;
|
|
344
|
+
year: number;
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Manager override for waiving penalties
|
|
349
|
+
*/
|
|
350
|
+
interface PenaltyOverride {
|
|
351
|
+
/** Which penalty to override */
|
|
352
|
+
penaltyId: string;
|
|
353
|
+
/** Employee affected */
|
|
354
|
+
employeeId: ObjectIdLike;
|
|
355
|
+
/** Manager who made the override */
|
|
356
|
+
overriddenBy: ObjectIdLike;
|
|
357
|
+
/** When the override was made */
|
|
358
|
+
overriddenAt: Date;
|
|
359
|
+
/** Original penalty amount */
|
|
360
|
+
originalAmount: number;
|
|
361
|
+
/** New amount (0 = fully waived) */
|
|
362
|
+
newAmount: number;
|
|
363
|
+
/** Reason for override */
|
|
364
|
+
reason: string;
|
|
365
|
+
/** Does this need approval */
|
|
366
|
+
approvalRequired?: boolean;
|
|
367
|
+
/** Who approved (if approval required) */
|
|
368
|
+
approvedBy?: ObjectIdLike;
|
|
369
|
+
/** When approved */
|
|
370
|
+
approvedAt?: Date;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* @classytic/payroll - Late Penalty Calculator
|
|
375
|
+
*
|
|
376
|
+
* Pure functions for calculating late arrival penalties.
|
|
377
|
+
* No side effects, no DB calls - just math.
|
|
378
|
+
*/
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Calculate penalty using flat rate per occurrence
|
|
382
|
+
*
|
|
383
|
+
* @example
|
|
384
|
+
* ```typescript
|
|
385
|
+
* // $50 per late occurrence
|
|
386
|
+
* const result = calculateFlatPenalty(3, 50);
|
|
387
|
+
* // → { amount: 150, occurrences: 3 }
|
|
388
|
+
* ```
|
|
389
|
+
*/
|
|
390
|
+
declare function calculateFlatPenalty(occurrenceCount: number, flatAmount: number): {
|
|
391
|
+
amount: number;
|
|
392
|
+
occurrences: number;
|
|
393
|
+
};
|
|
394
|
+
/**
|
|
395
|
+
* Calculate penalty based on minutes late
|
|
396
|
+
*
|
|
397
|
+
* @example
|
|
398
|
+
* ```typescript
|
|
399
|
+
* // $2 per minute, 45 minutes late
|
|
400
|
+
* const result = calculatePerMinutePenalty(45, 2);
|
|
401
|
+
* // → { amount: 90, minutes: 45 }
|
|
402
|
+
* ```
|
|
403
|
+
*/
|
|
404
|
+
declare function calculatePerMinutePenalty(totalMinutesLate: number, perMinuteRate: number): {
|
|
405
|
+
amount: number;
|
|
406
|
+
minutes: number;
|
|
407
|
+
};
|
|
408
|
+
/**
|
|
409
|
+
* Calculate penalty as percentage of daily wage
|
|
410
|
+
*
|
|
411
|
+
* @example
|
|
412
|
+
* ```typescript
|
|
413
|
+
* // 2% of $500 daily wage, 3 late occurrences
|
|
414
|
+
* const result = calculatePercentagePenalty(3, 2, 500);
|
|
415
|
+
* // → { amount: 30, percentage: 2 }
|
|
416
|
+
* ```
|
|
417
|
+
*/
|
|
418
|
+
declare function calculatePercentagePenalty(occurrenceCount: number, percentageRate: number, dailyWage: number): {
|
|
419
|
+
amount: number;
|
|
420
|
+
percentage: number;
|
|
421
|
+
};
|
|
422
|
+
/**
|
|
423
|
+
* Calculate total tiered penalties for multiple occurrences
|
|
424
|
+
*
|
|
425
|
+
* @example
|
|
426
|
+
* ```typescript
|
|
427
|
+
* const tiers = [
|
|
428
|
+
* { from: 1, to: 2, penalty: 0, warning: true },
|
|
429
|
+
* { from: 3, to: 4, penalty: 25 },
|
|
430
|
+
* { from: 5, penalty: 50 },
|
|
431
|
+
* ];
|
|
432
|
+
*
|
|
433
|
+
* // Employee has 5 late occurrences
|
|
434
|
+
* const result = calculateTieredPenalty(5, 2, tiers);
|
|
435
|
+
* // → {
|
|
436
|
+
* // amount: 125, // 0 + 0 + 25 + 25 + 50
|
|
437
|
+
* // breakdown: [...]
|
|
438
|
+
* // }
|
|
439
|
+
* ```
|
|
440
|
+
*/
|
|
441
|
+
declare function calculateTieredPenalty(newOccurrences: number, currentOccurrenceCount: number, tiers: PenaltyTier[]): {
|
|
442
|
+
amount: number;
|
|
443
|
+
breakdown: Array<{
|
|
444
|
+
occurrence: number;
|
|
445
|
+
penalty: number;
|
|
446
|
+
tier?: number;
|
|
447
|
+
warning: boolean;
|
|
448
|
+
}>;
|
|
449
|
+
};
|
|
450
|
+
/**
|
|
451
|
+
* Calculate late arrival penalties based on policy
|
|
452
|
+
*
|
|
453
|
+
* @example
|
|
454
|
+
* ```typescript
|
|
455
|
+
* const policy: LateArrivalPolicy = {
|
|
456
|
+
* enabled: true,
|
|
457
|
+
* gracePeriod: 5,
|
|
458
|
+
* mode: 'flat',
|
|
459
|
+
* flatAmount: 50,
|
|
460
|
+
* };
|
|
461
|
+
*
|
|
462
|
+
* const occurrences: LateOccurrence[] = [
|
|
463
|
+
* { date: new Date(), scheduledTime, actualTime, minutesLate: 10 },
|
|
464
|
+
* { date: new Date(), scheduledTime, actualTime, minutesLate: 3 }, // Within grace
|
|
465
|
+
* ];
|
|
466
|
+
*
|
|
467
|
+
* const result = calculateLatePenalty({
|
|
468
|
+
* policy,
|
|
469
|
+
* occurrences,
|
|
470
|
+
* dailyWage: 500,
|
|
471
|
+
* });
|
|
472
|
+
* // → { amount: 50, occurrences: 1, breakdown: [...] }
|
|
473
|
+
* ```
|
|
474
|
+
*/
|
|
475
|
+
declare function calculateLatePenalty(input: {
|
|
476
|
+
policy: LateArrivalPolicy;
|
|
477
|
+
occurrences?: LateOccurrence[];
|
|
478
|
+
lateCount?: number;
|
|
479
|
+
totalLateMinutes?: number;
|
|
480
|
+
dailyWage?: number;
|
|
481
|
+
currentOccurrenceCount?: number;
|
|
482
|
+
}): LatePenaltyResult;
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* @classytic/payroll - Overtime Calculator
|
|
486
|
+
*
|
|
487
|
+
* Pure functions for calculating overtime bonuses.
|
|
488
|
+
* No side effects, no DB calls - just math.
|
|
489
|
+
*/
|
|
490
|
+
|
|
491
|
+
/**
|
|
492
|
+
* Calculate daily overtime bonus
|
|
493
|
+
*
|
|
494
|
+
* @example
|
|
495
|
+
* ```typescript
|
|
496
|
+
* // Employee worked 10 hours, threshold is 8, rate is $100/hour
|
|
497
|
+
* const result = calculateDailyOvertime(10, 8, 1.5, 100);
|
|
498
|
+
* // → { amount: 100, overtimeHours: 2 }
|
|
499
|
+
* // Calculation: 2 hours × $100 × 0.5 (extra) = $100
|
|
500
|
+
* ```
|
|
501
|
+
*/
|
|
502
|
+
declare function calculateDailyOvertime(hoursWorked: number, threshold: number, multiplier: number, hourlyRate: number): {
|
|
503
|
+
amount: number;
|
|
504
|
+
overtimeHours: number;
|
|
505
|
+
};
|
|
506
|
+
/**
|
|
507
|
+
* Calculate weekly overtime bonus
|
|
508
|
+
*
|
|
509
|
+
* @example
|
|
510
|
+
* ```typescript
|
|
511
|
+
* // Employee worked 45 hours, threshold is 40, rate is $100/hour
|
|
512
|
+
* const result = calculateWeeklyOvertime(45, 40, 1.5, 100);
|
|
513
|
+
* // → { amount: 250, overtimeHours: 5 }
|
|
514
|
+
* ```
|
|
515
|
+
*/
|
|
516
|
+
declare function calculateWeeklyOvertime(hoursWorked: number, threshold: number, multiplier: number, hourlyRate: number): {
|
|
517
|
+
amount: number;
|
|
518
|
+
overtimeHours: number;
|
|
519
|
+
};
|
|
520
|
+
/**
|
|
521
|
+
* Calculate monthly overtime bonus
|
|
522
|
+
*
|
|
523
|
+
* @example
|
|
524
|
+
* ```typescript
|
|
525
|
+
* // Employee worked 170 hours, threshold is 160
|
|
526
|
+
* const result = calculateMonthlyOvertime(170, 160, 1.5, 100);
|
|
527
|
+
* // → { amount: 500, overtimeHours: 10 }
|
|
528
|
+
* ```
|
|
529
|
+
*/
|
|
530
|
+
declare function calculateMonthlyOvertime(hoursWorked: number, threshold: number, multiplier: number, hourlyRate: number): {
|
|
531
|
+
amount: number;
|
|
532
|
+
overtimeHours: number;
|
|
533
|
+
};
|
|
534
|
+
/**
|
|
535
|
+
* Calculate weekend premium pay
|
|
536
|
+
*
|
|
537
|
+
* @example
|
|
538
|
+
* ```typescript
|
|
539
|
+
* // Employee worked 8 hours on Saturday
|
|
540
|
+
* const result = calculateWeekendPremium(8, 1.5, 100, 'saturday');
|
|
541
|
+
* // → { amount: 400, hours: 8 }
|
|
542
|
+
* // Regular: 8 × $100 = $800
|
|
543
|
+
* // Premium: 8 × $100 × 0.5 (extra) = $400
|
|
544
|
+
* ```
|
|
545
|
+
*/
|
|
546
|
+
declare function calculateWeekendPremium(hours: number, multiplier: number, hourlyRate: number, day: 'saturday' | 'sunday'): {
|
|
547
|
+
amount: number;
|
|
548
|
+
hours: number;
|
|
549
|
+
day: string;
|
|
550
|
+
};
|
|
551
|
+
/**
|
|
552
|
+
* Calculate night shift differential
|
|
553
|
+
*
|
|
554
|
+
* @example
|
|
555
|
+
* ```typescript
|
|
556
|
+
* // Employee worked 8 hours during night shift (10pm-6am)
|
|
557
|
+
* const result = calculateNightShiftDifferential(8, 1.2, 100);
|
|
558
|
+
* // → { amount: 160, hours: 8 }
|
|
559
|
+
* // Differential: 8 × $100 × 0.2 (extra) = $160
|
|
560
|
+
* ```
|
|
561
|
+
*/
|
|
562
|
+
declare function calculateNightShiftDifferential(hours: number, multiplier: number, hourlyRate: number): {
|
|
563
|
+
amount: number;
|
|
564
|
+
hours: number;
|
|
565
|
+
};
|
|
566
|
+
/**
|
|
567
|
+
* Calculate all overtime bonuses based on policy
|
|
568
|
+
*
|
|
569
|
+
* @example
|
|
570
|
+
* ```typescript
|
|
571
|
+
* const policy: OvertimePolicy = {
|
|
572
|
+
* enabled: true,
|
|
573
|
+
* mode: 'daily',
|
|
574
|
+
* dailyThreshold: 8,
|
|
575
|
+
* dailyMultiplier: 1.5,
|
|
576
|
+
* };
|
|
577
|
+
*
|
|
578
|
+
* const occurrences: OvertimeOccurrence[] = [
|
|
579
|
+
* { date: new Date(), type: 'daily', hours: 2, multiplier: 1.5 },
|
|
580
|
+
* { date: new Date(), type: 'weekend-sunday', hours: 8, multiplier: 2.0 },
|
|
581
|
+
* ];
|
|
582
|
+
*
|
|
583
|
+
* const result = calculateOvertimeBonus({
|
|
584
|
+
* policy,
|
|
585
|
+
* occurrences,
|
|
586
|
+
* hourlyRate: 100,
|
|
587
|
+
* });
|
|
588
|
+
* ```
|
|
589
|
+
*/
|
|
590
|
+
declare function calculateOvertimeBonus(input: {
|
|
591
|
+
policy: OvertimePolicy;
|
|
592
|
+
occurrences?: OvertimeOccurrence[];
|
|
593
|
+
overtimeHours?: number;
|
|
594
|
+
overtimeDays?: number;
|
|
595
|
+
hourlyRate: number;
|
|
596
|
+
}): OvertimeBonusResult;
|
|
597
|
+
|
|
598
|
+
/**
|
|
599
|
+
* @classytic/payroll - Shift Compliance Calculators
|
|
600
|
+
*
|
|
601
|
+
* Main calculator that orchestrates all shift compliance calculations.
|
|
602
|
+
*/
|
|
603
|
+
|
|
604
|
+
/**
|
|
605
|
+
* Calculate complete shift compliance adjustments.
|
|
606
|
+
*
|
|
607
|
+
* This is the main function users call. It takes attendance data + policy
|
|
608
|
+
* and returns penalties + bonuses.
|
|
609
|
+
*
|
|
610
|
+
* @example
|
|
611
|
+
* ```typescript
|
|
612
|
+
* const attendance: ShiftComplianceData = {
|
|
613
|
+
* lateArrivals: 3,
|
|
614
|
+
* totalLateMinutes: 45,
|
|
615
|
+
* earlyDepartures: 1,
|
|
616
|
+
* totalEarlyMinutes: 20,
|
|
617
|
+
* overtimeHours: 8,
|
|
618
|
+
* };
|
|
619
|
+
*
|
|
620
|
+
* const policy: AttendancePolicy = {
|
|
621
|
+
* name: 'Manufacturing Policy',
|
|
622
|
+
* lateArrival: {
|
|
623
|
+
* enabled: true,
|
|
624
|
+
* gracePeriod: 0,
|
|
625
|
+
* mode: 'flat',
|
|
626
|
+
* flatAmount: 50,
|
|
627
|
+
* },
|
|
628
|
+
* earlyDeparture: {
|
|
629
|
+
* enabled: true,
|
|
630
|
+
* gracePeriod: 0,
|
|
631
|
+
* mode: 'flat',
|
|
632
|
+
* flatAmount: 75,
|
|
633
|
+
* },
|
|
634
|
+
* overtime: {
|
|
635
|
+
* enabled: true,
|
|
636
|
+
* mode: 'daily',
|
|
637
|
+
* dailyThreshold: 8,
|
|
638
|
+
* dailyMultiplier: 1.5,
|
|
639
|
+
* },
|
|
640
|
+
* effectiveFrom: new Date(),
|
|
641
|
+
* active: true,
|
|
642
|
+
* };
|
|
643
|
+
*
|
|
644
|
+
* const result = calculateShiftCompliance({
|
|
645
|
+
* attendance,
|
|
646
|
+
* policy,
|
|
647
|
+
* dailyWage: 1500,
|
|
648
|
+
* hourlyRate: 200,
|
|
649
|
+
* });
|
|
650
|
+
*
|
|
651
|
+
* // result = {
|
|
652
|
+
* // latePenalty: { amount: 150, ... },
|
|
653
|
+
* // earlyDeparturePenalty: { amount: 75, ... },
|
|
654
|
+
* // overtimeBonus: { amount: 800, ... },
|
|
655
|
+
* // totalPenalties: 225,
|
|
656
|
+
* // totalBonuses: 800,
|
|
657
|
+
* // netAdjustment: 575, // +800 - 225
|
|
658
|
+
* // ...
|
|
659
|
+
* // }
|
|
660
|
+
* ```
|
|
661
|
+
*/
|
|
662
|
+
declare function calculateShiftCompliance(input: CalculateShiftComplianceInput): ShiftComplianceResult;
|
|
663
|
+
|
|
664
|
+
/**
|
|
665
|
+
* @classytic/payroll - Shift Compliance Configuration
|
|
666
|
+
*
|
|
667
|
+
* Default configurations and industry-standard preset policies.
|
|
668
|
+
*/
|
|
669
|
+
|
|
670
|
+
/**
|
|
671
|
+
* Default attendance policy (moderate, office-friendly)
|
|
672
|
+
*/
|
|
673
|
+
declare const DEFAULT_ATTENDANCE_POLICY: Omit<AttendancePolicy, 'name' | 'effectiveFrom' | 'active'>;
|
|
674
|
+
/**
|
|
675
|
+
* Manufacturing/Factory policy (strict, zero tolerance)
|
|
676
|
+
*/
|
|
677
|
+
declare const MANUFACTURING_POLICY: Omit<AttendancePolicy, 'name' | 'effectiveFrom' | 'active'>;
|
|
678
|
+
/**
|
|
679
|
+
* Retail policy (flexible with weekend premiums)
|
|
680
|
+
*/
|
|
681
|
+
declare const RETAIL_POLICY: Omit<AttendancePolicy, 'name' | 'effectiveFrom' | 'active'>;
|
|
682
|
+
/**
|
|
683
|
+
* Office/Tech policy (very flexible, progressive discipline)
|
|
684
|
+
*/
|
|
685
|
+
declare const OFFICE_POLICY: Omit<AttendancePolicy, 'name' | 'effectiveFrom' | 'active'>;
|
|
686
|
+
/**
|
|
687
|
+
* Healthcare policy (night shift differential, weekend premiums)
|
|
688
|
+
*/
|
|
689
|
+
declare const HEALTHCARE_POLICY: Omit<AttendancePolicy, 'name' | 'effectiveFrom' | 'active'>;
|
|
690
|
+
/**
|
|
691
|
+
* Hospitality policy (flexible, weekend/night premiums)
|
|
692
|
+
*/
|
|
693
|
+
declare const HOSPITALITY_POLICY: Omit<AttendancePolicy, 'name' | 'effectiveFrom' | 'active'>;
|
|
694
|
+
/**
|
|
695
|
+
* Get a complete policy from a preset
|
|
696
|
+
*
|
|
697
|
+
* @example
|
|
698
|
+
* ```typescript
|
|
699
|
+
* const policy = createPolicyFromPreset('manufacturing', {
|
|
700
|
+
* name: 'Factory Floor Policy',
|
|
701
|
+
* organizationId: orgId,
|
|
702
|
+
* });
|
|
703
|
+
* ```
|
|
704
|
+
*/
|
|
705
|
+
declare function createPolicyFromPreset(preset: 'default' | 'manufacturing' | 'retail' | 'office' | 'healthcare' | 'hospitality', overrides?: Partial<AttendancePolicy>): AttendancePolicy;
|
|
706
|
+
|
|
707
|
+
/**
|
|
708
|
+
* @classytic/payroll - Shift Compliance Fluent Builders
|
|
709
|
+
*
|
|
710
|
+
* DX-friendly fluent API for creating attendance policies programmatically.
|
|
711
|
+
*
|
|
712
|
+
* @example
|
|
713
|
+
* ```typescript
|
|
714
|
+
* const policy = AttendancePolicyBuilder.create()
|
|
715
|
+
* .named('Tech Department Policy')
|
|
716
|
+
* .description('Flexible policy for tech workers')
|
|
717
|
+
* .lateArrival()
|
|
718
|
+
* .enable()
|
|
719
|
+
* .gracePeriod(15)
|
|
720
|
+
* .tieredPenalty()
|
|
721
|
+
* .tier(1, 3).warning()
|
|
722
|
+
* .tier(4, 5).penalty(20)
|
|
723
|
+
* .tier(6).penalty(40)
|
|
724
|
+
* .end()
|
|
725
|
+
* .maxPenalties(3, 'monthly')
|
|
726
|
+
* .resetOccurrences('quarterly')
|
|
727
|
+
* .end()
|
|
728
|
+
* .overtime()
|
|
729
|
+
* .enable()
|
|
730
|
+
* .mode('weekly')
|
|
731
|
+
* .weeklyThreshold(40, 1.5)
|
|
732
|
+
* .end()
|
|
733
|
+
* .build();
|
|
734
|
+
* ```
|
|
735
|
+
*/
|
|
736
|
+
|
|
737
|
+
/**
|
|
738
|
+
* Builder for late arrival or early departure policies.
|
|
739
|
+
* Uses same structure for both since the logic is identical.
|
|
740
|
+
*/
|
|
741
|
+
declare class LatePolicyBuilder<TParent = unknown> {
|
|
742
|
+
private policy;
|
|
743
|
+
private parent?;
|
|
744
|
+
constructor(parent?: TParent);
|
|
745
|
+
/**
|
|
746
|
+
* Enable this policy
|
|
747
|
+
*/
|
|
748
|
+
enable(): this;
|
|
749
|
+
/**
|
|
750
|
+
* Disable this policy
|
|
751
|
+
*/
|
|
752
|
+
disable(): this;
|
|
753
|
+
/**
|
|
754
|
+
* Set grace period in minutes (how many minutes late before penalty applies)
|
|
755
|
+
*/
|
|
756
|
+
gracePeriod(minutes: number): this;
|
|
757
|
+
/**
|
|
758
|
+
* Use flat penalty mode (same penalty for each occurrence)
|
|
759
|
+
*
|
|
760
|
+
* @param amount - Penalty amount per occurrence
|
|
761
|
+
*/
|
|
762
|
+
flatPenalty(amount: number): this;
|
|
763
|
+
/**
|
|
764
|
+
* Use per-minute penalty mode (penalty based on minutes late)
|
|
765
|
+
*
|
|
766
|
+
* @param rate - Penalty per minute late
|
|
767
|
+
*/
|
|
768
|
+
perMinutePenalty(rate: number): this;
|
|
769
|
+
/**
|
|
770
|
+
* Use percentage penalty mode (percentage of daily wage)
|
|
771
|
+
*
|
|
772
|
+
* @param percentage - Percentage of daily wage (e.g., 2 for 2%)
|
|
773
|
+
*/
|
|
774
|
+
percentagePenalty(percentage: number): this;
|
|
775
|
+
/**
|
|
776
|
+
* Start building tiered penalty (progressive discipline)
|
|
777
|
+
*
|
|
778
|
+
* @example
|
|
779
|
+
* ```typescript
|
|
780
|
+
* .tieredPenalty()
|
|
781
|
+
* .tier(1, 2).warning()
|
|
782
|
+
* .tier(3, 4).penalty(25)
|
|
783
|
+
* .tier(5).penalty(50)
|
|
784
|
+
* .end()
|
|
785
|
+
* ```
|
|
786
|
+
*/
|
|
787
|
+
tieredPenalty(): TieredPenaltyBuilder<this>;
|
|
788
|
+
/**
|
|
789
|
+
* Set maximum penalties per period (caps total penalties)
|
|
790
|
+
*
|
|
791
|
+
* @param count - Max number of penalties
|
|
792
|
+
* @param period - Period type ('daily' | 'weekly' | 'monthly' | 'quarterly' | 'yearly')
|
|
793
|
+
*/
|
|
794
|
+
maxPenalties(count: number, period: 'daily' | 'weekly' | 'monthly' | 'quarterly' | 'yearly'): this;
|
|
795
|
+
/**
|
|
796
|
+
* Set when to reset occurrence counter
|
|
797
|
+
*
|
|
798
|
+
* @param period - Reset period ('monthly' | 'quarterly' | 'yearly')
|
|
799
|
+
*/
|
|
800
|
+
resetOccurrences(period: 'monthly' | 'quarterly' | 'yearly'): this;
|
|
801
|
+
/**
|
|
802
|
+
* Add a custom tier (advanced usage)
|
|
803
|
+
*/
|
|
804
|
+
addTier(tier: PenaltyTier): this;
|
|
805
|
+
/**
|
|
806
|
+
* Finish building this policy and return to parent builder
|
|
807
|
+
*/
|
|
808
|
+
end(): TParent;
|
|
809
|
+
/**
|
|
810
|
+
* Build the policy (for standalone usage)
|
|
811
|
+
*/
|
|
812
|
+
build(): LateArrivalPolicy;
|
|
813
|
+
/** @internal */
|
|
814
|
+
_getPolicy(): Partial<LateArrivalPolicy>;
|
|
815
|
+
}
|
|
816
|
+
/**
|
|
817
|
+
* Builder for tiered penalties (progressive discipline)
|
|
818
|
+
*/
|
|
819
|
+
declare class TieredPenaltyBuilder<TParent> {
|
|
820
|
+
private tiers;
|
|
821
|
+
private parent;
|
|
822
|
+
private currentTier;
|
|
823
|
+
constructor(parent: TParent);
|
|
824
|
+
/**
|
|
825
|
+
* Start a new tier
|
|
826
|
+
*
|
|
827
|
+
* @param from - Starting occurrence number (1-indexed)
|
|
828
|
+
* @param to - Ending occurrence number (optional, omit for open-ended tier)
|
|
829
|
+
*/
|
|
830
|
+
tier(from: number, to?: number): this;
|
|
831
|
+
/**
|
|
832
|
+
* Set this tier as warning only (no financial penalty)
|
|
833
|
+
*/
|
|
834
|
+
warning(): this;
|
|
835
|
+
/**
|
|
836
|
+
* Set penalty amount for this tier
|
|
837
|
+
*/
|
|
838
|
+
penalty(amount: number): this;
|
|
839
|
+
/**
|
|
840
|
+
* Finish building tiers and return to parent
|
|
841
|
+
*/
|
|
842
|
+
end(): TParent;
|
|
843
|
+
private saveTier;
|
|
844
|
+
}
|
|
845
|
+
/**
|
|
846
|
+
* Builder for overtime policies
|
|
847
|
+
*/
|
|
848
|
+
declare class OvertimePolicyBuilder<TParent = unknown> {
|
|
849
|
+
private policy;
|
|
850
|
+
private parent?;
|
|
851
|
+
constructor(parent?: TParent);
|
|
852
|
+
/**
|
|
853
|
+
* Enable overtime calculations
|
|
854
|
+
*/
|
|
855
|
+
enable(): this;
|
|
856
|
+
/**
|
|
857
|
+
* Disable overtime calculations
|
|
858
|
+
*/
|
|
859
|
+
disable(): this;
|
|
860
|
+
/**
|
|
861
|
+
* Set overtime calculation mode
|
|
862
|
+
*/
|
|
863
|
+
mode(mode: 'daily' | 'weekly' | 'monthly'): this;
|
|
864
|
+
/**
|
|
865
|
+
* Set daily overtime threshold and multiplier
|
|
866
|
+
*
|
|
867
|
+
* @param hours - Hours threshold (e.g., 8)
|
|
868
|
+
* @param multiplier - Overtime multiplier (e.g., 1.5 for time-and-a-half)
|
|
869
|
+
*/
|
|
870
|
+
dailyThreshold(hours: number, multiplier: number): this;
|
|
871
|
+
/**
|
|
872
|
+
* Set weekly overtime threshold and multiplier
|
|
873
|
+
*
|
|
874
|
+
* @param hours - Hours threshold (e.g., 40)
|
|
875
|
+
* @param multiplier - Overtime multiplier (e.g., 1.5 for time-and-a-half)
|
|
876
|
+
*/
|
|
877
|
+
weeklyThreshold(hours: number, multiplier: number): this;
|
|
878
|
+
/**
|
|
879
|
+
* Set monthly overtime threshold and multiplier
|
|
880
|
+
*
|
|
881
|
+
* @param hours - Hours threshold (e.g., 160)
|
|
882
|
+
* @param multiplier - Overtime multiplier (e.g., 2.0 for double time)
|
|
883
|
+
*/
|
|
884
|
+
monthlyThreshold(hours: number, multiplier: number): this;
|
|
885
|
+
/**
|
|
886
|
+
* Set weekend premium rates
|
|
887
|
+
*
|
|
888
|
+
* @param saturday - Saturday multiplier (e.g., 1.5)
|
|
889
|
+
* @param sunday - Sunday multiplier (e.g., 2.0)
|
|
890
|
+
*/
|
|
891
|
+
weekendPremium(saturday: number, sunday: number): this;
|
|
892
|
+
/**
|
|
893
|
+
* Set night shift differential
|
|
894
|
+
*
|
|
895
|
+
* @param startHour - Start hour (24-hour format, e.g., 22 for 10pm)
|
|
896
|
+
* @param endHour - End hour (24-hour format, e.g., 6 for 6am)
|
|
897
|
+
* @param multiplier - Night shift multiplier (e.g., 1.3 for 30% premium)
|
|
898
|
+
*/
|
|
899
|
+
nightShiftDifferential(startHour: number, endHour: number, multiplier: number): this;
|
|
900
|
+
/**
|
|
901
|
+
* Finish building this policy and return to parent builder
|
|
902
|
+
*/
|
|
903
|
+
end(): TParent;
|
|
904
|
+
/**
|
|
905
|
+
* Build the policy (for standalone usage)
|
|
906
|
+
*/
|
|
907
|
+
build(): OvertimePolicy;
|
|
908
|
+
/** @internal */
|
|
909
|
+
_getPolicy(): Partial<OvertimePolicy>;
|
|
910
|
+
}
|
|
911
|
+
/**
|
|
912
|
+
* Builder for clock rounding policies
|
|
913
|
+
*/
|
|
914
|
+
declare class ClockRoundingPolicyBuilder<TParent = unknown> {
|
|
915
|
+
private policy;
|
|
916
|
+
private parent?;
|
|
917
|
+
constructor(parent?: TParent);
|
|
918
|
+
/**
|
|
919
|
+
* Enable clock rounding
|
|
920
|
+
*/
|
|
921
|
+
enable(): this;
|
|
922
|
+
/**
|
|
923
|
+
* Disable clock rounding
|
|
924
|
+
*/
|
|
925
|
+
disable(): this;
|
|
926
|
+
/**
|
|
927
|
+
* Set rounding interval in minutes
|
|
928
|
+
*
|
|
929
|
+
* @param minutes - Round to nearest N minutes (e.g., 5, 10, 15)
|
|
930
|
+
*/
|
|
931
|
+
roundTo(minutes: 5 | 10 | 15): this;
|
|
932
|
+
/**
|
|
933
|
+
* Set rounding mode
|
|
934
|
+
*
|
|
935
|
+
* @param mode - 'up' (favor employee) | 'down' (favor employer) | 'nearest' (neutral)
|
|
936
|
+
*/
|
|
937
|
+
roundingMode(mode: 'up' | 'down' | 'nearest'): this;
|
|
938
|
+
/**
|
|
939
|
+
* Finish building this policy and return to parent builder
|
|
940
|
+
*/
|
|
941
|
+
end(): TParent;
|
|
942
|
+
/**
|
|
943
|
+
* Build the policy (for standalone usage)
|
|
944
|
+
*/
|
|
945
|
+
build(): ClockRoundingPolicy;
|
|
946
|
+
/** @internal */
|
|
947
|
+
_getPolicy(): Partial<ClockRoundingPolicy>;
|
|
948
|
+
}
|
|
949
|
+
/**
|
|
950
|
+
* Main builder for creating complete attendance policies
|
|
951
|
+
*
|
|
952
|
+
* @example
|
|
953
|
+
* ```typescript
|
|
954
|
+
* const policy = AttendancePolicyBuilder.create()
|
|
955
|
+
* .named('Manufacturing Policy')
|
|
956
|
+
* .description('Strict policy for factory floor')
|
|
957
|
+
* .organizationId(orgId)
|
|
958
|
+
* .lateArrival()
|
|
959
|
+
* .enable()
|
|
960
|
+
* .gracePeriod(0)
|
|
961
|
+
* .flatPenalty(100)
|
|
962
|
+
* .maxPenalties(5, 'monthly')
|
|
963
|
+
* .resetOccurrences('quarterly')
|
|
964
|
+
* .end()
|
|
965
|
+
* .earlyDeparture()
|
|
966
|
+
* .enable()
|
|
967
|
+
* .gracePeriod(0)
|
|
968
|
+
* .flatPenalty(150)
|
|
969
|
+
* .end()
|
|
970
|
+
* .overtime()
|
|
971
|
+
* .enable()
|
|
972
|
+
* .mode('daily')
|
|
973
|
+
* .dailyThreshold(8, 1.5)
|
|
974
|
+
* .weeklyThreshold(40, 2.0)
|
|
975
|
+
* .end()
|
|
976
|
+
* .clockRounding()
|
|
977
|
+
* .enable()
|
|
978
|
+
* .roundTo(15)
|
|
979
|
+
* .roundingMode('down')
|
|
980
|
+
* .end()
|
|
981
|
+
* .effectiveFrom(new Date('2025-01-01'))
|
|
982
|
+
* .build();
|
|
983
|
+
* ```
|
|
984
|
+
*/
|
|
985
|
+
declare class AttendancePolicyBuilder {
|
|
986
|
+
private policy;
|
|
987
|
+
private lateArrivalBuilder?;
|
|
988
|
+
private earlyDepartureBuilder?;
|
|
989
|
+
private overtimeBuilder?;
|
|
990
|
+
private clockRoundingBuilder?;
|
|
991
|
+
/**
|
|
992
|
+
* Create a new policy builder
|
|
993
|
+
*/
|
|
994
|
+
static create(): AttendancePolicyBuilder;
|
|
995
|
+
/**
|
|
996
|
+
* Set policy name
|
|
997
|
+
*/
|
|
998
|
+
named(name: string): this;
|
|
999
|
+
/**
|
|
1000
|
+
* Set policy description
|
|
1001
|
+
*/
|
|
1002
|
+
description(description: string): this;
|
|
1003
|
+
/**
|
|
1004
|
+
* Set organization ID (for multi-tenant systems)
|
|
1005
|
+
*/
|
|
1006
|
+
organizationId(id: ObjectIdLike): this;
|
|
1007
|
+
/**
|
|
1008
|
+
* Set policy ID (for updates)
|
|
1009
|
+
*/
|
|
1010
|
+
id(id: string): this;
|
|
1011
|
+
/**
|
|
1012
|
+
* Set effective from date
|
|
1013
|
+
*/
|
|
1014
|
+
effectiveFrom(date: Date): this;
|
|
1015
|
+
/**
|
|
1016
|
+
* Set effective to date (when policy expires)
|
|
1017
|
+
*/
|
|
1018
|
+
effectiveTo(date: Date | null): this;
|
|
1019
|
+
/**
|
|
1020
|
+
* Set policy active status
|
|
1021
|
+
*/
|
|
1022
|
+
active(active: boolean): this;
|
|
1023
|
+
/**
|
|
1024
|
+
* Start building late arrival policy
|
|
1025
|
+
*/
|
|
1026
|
+
lateArrival(): LatePolicyBuilder<this>;
|
|
1027
|
+
/**
|
|
1028
|
+
* Start building early departure policy
|
|
1029
|
+
*/
|
|
1030
|
+
earlyDeparture(): LatePolicyBuilder<this>;
|
|
1031
|
+
/**
|
|
1032
|
+
* Start building overtime policy
|
|
1033
|
+
*/
|
|
1034
|
+
overtime(): OvertimePolicyBuilder<this>;
|
|
1035
|
+
/**
|
|
1036
|
+
* Start building clock rounding policy
|
|
1037
|
+
*/
|
|
1038
|
+
clockRounding(): ClockRoundingPolicyBuilder<this>;
|
|
1039
|
+
/**
|
|
1040
|
+
* Build the complete attendance policy
|
|
1041
|
+
*/
|
|
1042
|
+
build(): AttendancePolicy;
|
|
1043
|
+
}
|
|
1044
|
+
/**
|
|
1045
|
+
* Create a standalone late arrival policy builder
|
|
1046
|
+
*/
|
|
1047
|
+
declare function createLatePolicyBuilder(): LatePolicyBuilder<void>;
|
|
1048
|
+
/**
|
|
1049
|
+
* Create a standalone overtime policy builder
|
|
1050
|
+
*/
|
|
1051
|
+
declare function createOvertimePolicyBuilder(): OvertimePolicyBuilder<void>;
|
|
1052
|
+
/**
|
|
1053
|
+
* Create a standalone clock rounding policy builder
|
|
1054
|
+
*/
|
|
1055
|
+
declare function createClockRoundingPolicyBuilder(): ClockRoundingPolicyBuilder<void>;
|
|
1056
|
+
|
|
1057
|
+
/**
|
|
1058
|
+
* Schema definition for penalty tiers (progressive discipline)
|
|
1059
|
+
*/
|
|
1060
|
+
declare const PenaltyTierSchemaDefinition: SchemaDefinition;
|
|
1061
|
+
/**
|
|
1062
|
+
* Schema for penalty tiers
|
|
1063
|
+
*/
|
|
1064
|
+
declare const PenaltyTierSchema: Schema;
|
|
1065
|
+
/**
|
|
1066
|
+
* Schema definition for max penalties per period
|
|
1067
|
+
*/
|
|
1068
|
+
declare const MaxPenaltiesSchemaDefinition: SchemaDefinition;
|
|
1069
|
+
/**
|
|
1070
|
+
* Schema for max penalties per period
|
|
1071
|
+
*/
|
|
1072
|
+
declare const MaxPenaltiesSchema: Schema;
|
|
1073
|
+
/**
|
|
1074
|
+
* Schema definition for late arrival policy
|
|
1075
|
+
*/
|
|
1076
|
+
declare const LateArrivalPolicySchemaDefinition: SchemaDefinition;
|
|
1077
|
+
/**
|
|
1078
|
+
* Schema for late arrival policy
|
|
1079
|
+
*/
|
|
1080
|
+
declare const LateArrivalPolicySchema: Schema;
|
|
1081
|
+
/**
|
|
1082
|
+
* Schema definition for early departure policy
|
|
1083
|
+
* (Same structure as late arrival policy)
|
|
1084
|
+
*/
|
|
1085
|
+
declare const EarlyDeparturePolicySchemaDefinition: {
|
|
1086
|
+
[path: string]: mongoose.SchemaDefinitionProperty<undefined, any, any>;
|
|
1087
|
+
};
|
|
1088
|
+
/**
|
|
1089
|
+
* Schema for early departure policy
|
|
1090
|
+
*/
|
|
1091
|
+
declare const EarlyDeparturePolicySchema: Schema;
|
|
1092
|
+
/**
|
|
1093
|
+
* Schema definition for weekend premium
|
|
1094
|
+
*/
|
|
1095
|
+
declare const WeekendPremiumSchemaDefinition: SchemaDefinition;
|
|
1096
|
+
/**
|
|
1097
|
+
* Schema for weekend premium
|
|
1098
|
+
*/
|
|
1099
|
+
declare const WeekendPremiumSchema: Schema;
|
|
1100
|
+
/**
|
|
1101
|
+
* Schema definition for night shift differential
|
|
1102
|
+
*/
|
|
1103
|
+
declare const NightShiftDifferentialSchemaDefinition: SchemaDefinition;
|
|
1104
|
+
/**
|
|
1105
|
+
* Schema for night shift differential
|
|
1106
|
+
*/
|
|
1107
|
+
declare const NightShiftDifferentialSchema: Schema;
|
|
1108
|
+
/**
|
|
1109
|
+
* Schema definition for overtime policy
|
|
1110
|
+
*/
|
|
1111
|
+
declare const OvertimePolicySchemaDefinition: SchemaDefinition;
|
|
1112
|
+
/**
|
|
1113
|
+
* Schema for overtime policy
|
|
1114
|
+
*/
|
|
1115
|
+
declare const OvertimePolicySchema: Schema;
|
|
1116
|
+
/**
|
|
1117
|
+
* Schema definition for clock rounding policy
|
|
1118
|
+
*/
|
|
1119
|
+
declare const ClockRoundingPolicySchemaDefinition: SchemaDefinition;
|
|
1120
|
+
/**
|
|
1121
|
+
* Schema for clock rounding policy
|
|
1122
|
+
*/
|
|
1123
|
+
declare const ClockRoundingPolicySchema: Schema;
|
|
1124
|
+
/**
|
|
1125
|
+
* Schema definition for attendance policy
|
|
1126
|
+
*
|
|
1127
|
+
* Users can extend this with their own fields:
|
|
1128
|
+
* ```typescript
|
|
1129
|
+
* const CustomPolicySchema = new Schema({
|
|
1130
|
+
* ...AttendancePolicySchemaDefinition,
|
|
1131
|
+
* approvedBy: { type: Schema.Types.ObjectId, ref: 'User' },
|
|
1132
|
+
* department: String,
|
|
1133
|
+
* });
|
|
1134
|
+
* ```
|
|
1135
|
+
*/
|
|
1136
|
+
declare const AttendancePolicySchemaDefinition: SchemaDefinition;
|
|
1137
|
+
/**
|
|
1138
|
+
* Main Attendance Policy Schema
|
|
1139
|
+
*
|
|
1140
|
+
* @example
|
|
1141
|
+
* ```typescript
|
|
1142
|
+
* import { AttendancePolicySchema } from '@classytic/payroll';
|
|
1143
|
+
* import { model } from 'mongoose';
|
|
1144
|
+
*
|
|
1145
|
+
* const AttendancePolicy = model('AttendancePolicy', AttendancePolicySchema);
|
|
1146
|
+
*
|
|
1147
|
+
* // Create a new policy
|
|
1148
|
+
* const policy = new AttendancePolicy({
|
|
1149
|
+
* name: 'Tech Department Policy',
|
|
1150
|
+
* lateArrival: { ... },
|
|
1151
|
+
* earlyDeparture: { ... },
|
|
1152
|
+
* overtime: { ... },
|
|
1153
|
+
* });
|
|
1154
|
+
* await policy.save();
|
|
1155
|
+
* ```
|
|
1156
|
+
*/
|
|
1157
|
+
declare const AttendancePolicySchema: Schema;
|
|
1158
|
+
/**
|
|
1159
|
+
* Instance methods interface
|
|
1160
|
+
*/
|
|
1161
|
+
interface AttendancePolicyDocument {
|
|
1162
|
+
isCurrentlyActive(): boolean;
|
|
1163
|
+
}
|
|
1164
|
+
/**
|
|
1165
|
+
* Static methods interface
|
|
1166
|
+
*/
|
|
1167
|
+
interface AttendancePolicyModel {
|
|
1168
|
+
findActiveForOrganization(organizationId: any, date?: Date): Promise<any>;
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
export { type AttendancePolicy, AttendancePolicyBuilder, type AttendancePolicyDocument, type AttendancePolicyModel, AttendancePolicySchema, AttendancePolicySchemaDefinition, type CalculateShiftComplianceInput, type ClockRoundingPolicy, ClockRoundingPolicyBuilder, ClockRoundingPolicySchema, ClockRoundingPolicySchemaDefinition, DEFAULT_ATTENDANCE_POLICY, type EarlyDeparturePenaltyResult, type EarlyDeparturePolicy, EarlyDeparturePolicySchema, EarlyDeparturePolicySchemaDefinition, type EarlyOccurrence, HEALTHCARE_POLICY, HOSPITALITY_POLICY, type LateArrivalPolicy, LateArrivalPolicySchema, LateArrivalPolicySchemaDefinition, type LateOccurrence, type LatePenaltyResult, LatePolicyBuilder, MANUFACTURING_POLICY, type MaxPenaltiesPerPeriod, MaxPenaltiesSchema, MaxPenaltiesSchemaDefinition, type NightShiftDifferential, NightShiftDifferentialSchema, NightShiftDifferentialSchemaDefinition, OFFICE_POLICY, ObjectIdLike, type OvertimeBonusResult, type OvertimeMode, type OvertimeOccurrence, type OvertimePolicy, OvertimePolicyBuilder, OvertimePolicySchema, OvertimePolicySchemaDefinition, type PenaltyMode, type PenaltyOverride, type PenaltyTier, PenaltyTierSchema, PenaltyTierSchemaDefinition, RETAIL_POLICY, type ResetPeriod, type RoundingMode, type ShiftComplianceData, type ShiftComplianceResult, type ShiftDifferentialResult, TieredPenaltyBuilder, type WeekendPremium, WeekendPremiumSchema, WeekendPremiumSchemaDefinition, calculateDailyOvertime, calculateFlatPenalty, calculateLatePenalty, calculateMonthlyOvertime, calculateNightShiftDifferential, calculateOvertimeBonus, calculatePerMinutePenalty, calculatePercentagePenalty, calculateShiftCompliance, calculateTieredPenalty, calculateWeekendPremium, calculateWeeklyOvertime, createClockRoundingPolicyBuilder, createLatePolicyBuilder, createOvertimePolicyBuilder, createPolicyFromPreset, AttendancePolicySchema as default };
|