@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,582 @@
|
|
|
1
|
+
import { Model, ClientSession } from 'mongoose';
|
|
2
|
+
import { E as EmployeeDocument, z as HRMConfig, O as ObjectIdLike, I as Department, aK as EmployeeStatus, g as OperationContext, X as Compensation, aL as PayrollPeriod, aM as PayrollBreakdown, aN as PaymentMethod, P as PayrollRecordDocument, aO as CompensationBreakdownResult, N as Allowance, Q as Deduction, v as TaxWithholdingDocument, aP as AnyModel, Z as EventBus, aQ as ObjectId, G as GetPendingTaxParams, w as TaxSummaryParams, x as TaxSummaryResult, M as MarkTaxPaidParams, aR as TaxType, aS as TaxStatus } from '../types-BN3K_Uhr.js';
|
|
3
|
+
import { C as CreateEmployeeParams } from '../employee.factory-BlZqhiCk.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @classytic/payroll - Employee Service
|
|
7
|
+
*
|
|
8
|
+
* High-level employee operations with dependency injection
|
|
9
|
+
*
|
|
10
|
+
* ⚠️ **INTERNAL USE ONLY**
|
|
11
|
+
*
|
|
12
|
+
* This service is for internal use by the Payroll class only.
|
|
13
|
+
* All methods enforce organizationId isolation for multi-tenant safety.
|
|
14
|
+
*
|
|
15
|
+
* **For application code:**
|
|
16
|
+
* - Use `Payroll` class methods (recommended, full orchestration)
|
|
17
|
+
* - Use `findEmployeeSecure()` utility for secure lookups
|
|
18
|
+
* - Do NOT use EmployeeService directly
|
|
19
|
+
*
|
|
20
|
+
* This service is intentionally not exported from the package.
|
|
21
|
+
*
|
|
22
|
+
* @internal
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
declare class EmployeeService {
|
|
26
|
+
private readonly EmployeeModel;
|
|
27
|
+
private readonly config;
|
|
28
|
+
constructor(EmployeeModel: Model<EmployeeDocument>, config?: HRMConfig);
|
|
29
|
+
/**
|
|
30
|
+
* Find employee by ID with organization validation
|
|
31
|
+
*
|
|
32
|
+
* ⚠️ SECURITY: Always validates employee belongs to specified organization
|
|
33
|
+
*
|
|
34
|
+
* @throws {Error} If employee not found or doesn't belong to organization
|
|
35
|
+
*/
|
|
36
|
+
findById(employeeId: ObjectIdLike, organizationId: ObjectIdLike, // Required for multi-tenant isolation
|
|
37
|
+
options?: {
|
|
38
|
+
session?: ClientSession;
|
|
39
|
+
populate?: boolean;
|
|
40
|
+
}): Promise<EmployeeDocument | null>;
|
|
41
|
+
/**
|
|
42
|
+
* Find employee by user and organization
|
|
43
|
+
*/
|
|
44
|
+
findByUserId(userId: ObjectIdLike, organizationId: ObjectIdLike, options?: {
|
|
45
|
+
session?: ClientSession;
|
|
46
|
+
}): Promise<EmployeeDocument | null>;
|
|
47
|
+
/**
|
|
48
|
+
* Find employee by employeeId (human-readable ID)
|
|
49
|
+
*/
|
|
50
|
+
findByEmployeeId(employeeId: string, organizationId: ObjectIdLike, options?: {
|
|
51
|
+
session?: ClientSession;
|
|
52
|
+
}): Promise<EmployeeDocument | null>;
|
|
53
|
+
/**
|
|
54
|
+
* Find employee by email (guest employees)
|
|
55
|
+
*/
|
|
56
|
+
findByEmail(email: string, organizationId: ObjectIdLike, options?: {
|
|
57
|
+
session?: ClientSession;
|
|
58
|
+
}): Promise<EmployeeDocument | null>;
|
|
59
|
+
/**
|
|
60
|
+
* Find all guest employees (no userId)
|
|
61
|
+
*/
|
|
62
|
+
findGuestEmployees(organizationId: ObjectIdLike, options?: {
|
|
63
|
+
session?: ClientSession;
|
|
64
|
+
}): Promise<EmployeeDocument[]>;
|
|
65
|
+
/**
|
|
66
|
+
* Find active employees in organization
|
|
67
|
+
*/
|
|
68
|
+
findActive(organizationId: ObjectIdLike, options?: {
|
|
69
|
+
session?: ClientSession;
|
|
70
|
+
projection?: Record<string, number>;
|
|
71
|
+
}): Promise<EmployeeDocument[]>;
|
|
72
|
+
/**
|
|
73
|
+
* Find employed employees (not terminated)
|
|
74
|
+
*/
|
|
75
|
+
findEmployed(organizationId: ObjectIdLike, options?: {
|
|
76
|
+
session?: ClientSession;
|
|
77
|
+
projection?: Record<string, number>;
|
|
78
|
+
}): Promise<EmployeeDocument[]>;
|
|
79
|
+
/**
|
|
80
|
+
* Find employees by department
|
|
81
|
+
*/
|
|
82
|
+
findByDepartment(organizationId: ObjectIdLike, department: Department, options?: {
|
|
83
|
+
session?: ClientSession;
|
|
84
|
+
}): Promise<EmployeeDocument[]>;
|
|
85
|
+
/**
|
|
86
|
+
* Find employees eligible for payroll
|
|
87
|
+
*/
|
|
88
|
+
findEligibleForPayroll(organizationId: ObjectIdLike, options?: {
|
|
89
|
+
session?: ClientSession;
|
|
90
|
+
}): Promise<EmployeeDocument[]>;
|
|
91
|
+
/**
|
|
92
|
+
* Create new employee
|
|
93
|
+
*/
|
|
94
|
+
create(params: CreateEmployeeParams, options?: {
|
|
95
|
+
session?: ClientSession;
|
|
96
|
+
}): Promise<EmployeeDocument>;
|
|
97
|
+
/**
|
|
98
|
+
* Update employee status with organization validation
|
|
99
|
+
*
|
|
100
|
+
* ⚠️ SECURITY: Validates employee belongs to organization before update
|
|
101
|
+
*/
|
|
102
|
+
updateStatus(employeeId: ObjectIdLike, organizationId: ObjectIdLike, // Required for multi-tenant isolation
|
|
103
|
+
status: EmployeeStatus, context?: OperationContext, options?: {
|
|
104
|
+
session?: ClientSession;
|
|
105
|
+
}): Promise<EmployeeDocument>;
|
|
106
|
+
/**
|
|
107
|
+
* Update employee compensation with organization validation
|
|
108
|
+
*
|
|
109
|
+
* ⚠️ SECURITY: Validates employee belongs to organization before update
|
|
110
|
+
*
|
|
111
|
+
* NOTE: This merges the compensation fields rather than replacing the entire object.
|
|
112
|
+
* To update allowances/deductions, use addAllowance/removeAllowance methods.
|
|
113
|
+
*/
|
|
114
|
+
updateCompensation(employeeId: ObjectIdLike, organizationId: ObjectIdLike, // Required for multi-tenant isolation
|
|
115
|
+
compensation: Partial<Compensation>, options?: {
|
|
116
|
+
session?: ClientSession;
|
|
117
|
+
}): Promise<EmployeeDocument>;
|
|
118
|
+
/**
|
|
119
|
+
* Get employee statistics for organization
|
|
120
|
+
*/
|
|
121
|
+
getEmployeeStats(organizationId: ObjectIdLike, options?: {
|
|
122
|
+
session?: ClientSession;
|
|
123
|
+
}): Promise<{
|
|
124
|
+
total: number;
|
|
125
|
+
active: number;
|
|
126
|
+
employed: number;
|
|
127
|
+
canReceiveSalary: number;
|
|
128
|
+
byStatus: Record<string, number>;
|
|
129
|
+
byDepartment: Record<string, number>;
|
|
130
|
+
}>;
|
|
131
|
+
/**
|
|
132
|
+
* Group employees by status
|
|
133
|
+
*/
|
|
134
|
+
private groupByStatus;
|
|
135
|
+
/**
|
|
136
|
+
* Group employees by department
|
|
137
|
+
*/
|
|
138
|
+
private groupByDepartment;
|
|
139
|
+
/**
|
|
140
|
+
* Check if employee is active
|
|
141
|
+
*/
|
|
142
|
+
isActive(employee: EmployeeDocument): boolean;
|
|
143
|
+
/**
|
|
144
|
+
* Check if employee is employed
|
|
145
|
+
*/
|
|
146
|
+
isEmployed(employee: EmployeeDocument): boolean;
|
|
147
|
+
/**
|
|
148
|
+
* Check if employee can receive salary
|
|
149
|
+
*/
|
|
150
|
+
canReceiveSalary(employee: EmployeeDocument): boolean;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Create employee service instance
|
|
154
|
+
*/
|
|
155
|
+
declare function createEmployeeService(EmployeeModel: Model<EmployeeDocument>, config?: HRMConfig): EmployeeService;
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* @classytic/payroll - Payroll Factory
|
|
159
|
+
*
|
|
160
|
+
* Clean object creation for payroll records
|
|
161
|
+
* Immutable operations and builder pattern
|
|
162
|
+
*/
|
|
163
|
+
|
|
164
|
+
interface PayrollData {
|
|
165
|
+
employeeId: ObjectIdLike;
|
|
166
|
+
organizationId: ObjectIdLike;
|
|
167
|
+
period: PayrollPeriod;
|
|
168
|
+
breakdown: PayrollBreakdown;
|
|
169
|
+
status: 'pending';
|
|
170
|
+
processedAt: null;
|
|
171
|
+
paidAt: null;
|
|
172
|
+
metadata: {
|
|
173
|
+
currency: string;
|
|
174
|
+
paymentMethod?: PaymentMethod;
|
|
175
|
+
notes?: string;
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* @classytic/payroll - Payroll Service
|
|
181
|
+
*
|
|
182
|
+
* High-level payroll operations with dependency injection
|
|
183
|
+
*/
|
|
184
|
+
|
|
185
|
+
declare class PayrollService {
|
|
186
|
+
private readonly PayrollModel;
|
|
187
|
+
private readonly employeeService;
|
|
188
|
+
constructor(PayrollModel: Model<PayrollRecordDocument>, employeeService: EmployeeService);
|
|
189
|
+
/**
|
|
190
|
+
* Find payroll by ID
|
|
191
|
+
*/
|
|
192
|
+
findById(payrollId: ObjectIdLike, options?: {
|
|
193
|
+
session?: ClientSession;
|
|
194
|
+
}): Promise<PayrollRecordDocument | null>;
|
|
195
|
+
/**
|
|
196
|
+
* Find payrolls by employee
|
|
197
|
+
*/
|
|
198
|
+
findByEmployee(employeeId: ObjectIdLike, organizationId: ObjectIdLike, options?: {
|
|
199
|
+
session?: ClientSession;
|
|
200
|
+
limit?: number;
|
|
201
|
+
}): Promise<PayrollRecordDocument[]>;
|
|
202
|
+
/**
|
|
203
|
+
* Find payrolls for a period
|
|
204
|
+
*/
|
|
205
|
+
findForPeriod(organizationId: ObjectIdLike, month: number, year: number, options?: {
|
|
206
|
+
session?: ClientSession;
|
|
207
|
+
}): Promise<PayrollRecordDocument[]>;
|
|
208
|
+
/**
|
|
209
|
+
* Find pending payrolls
|
|
210
|
+
*/
|
|
211
|
+
findPending(organizationId: ObjectIdLike, month: number, year: number, options?: {
|
|
212
|
+
session?: ClientSession;
|
|
213
|
+
}): Promise<PayrollRecordDocument[]>;
|
|
214
|
+
/**
|
|
215
|
+
* Find payroll by employee and period
|
|
216
|
+
*/
|
|
217
|
+
findByEmployeeAndPeriod(employeeId: ObjectIdLike, organizationId: ObjectIdLike, month: number, year: number, options?: {
|
|
218
|
+
session?: ClientSession;
|
|
219
|
+
}): Promise<PayrollRecordDocument | null>;
|
|
220
|
+
/**
|
|
221
|
+
* Create payroll record
|
|
222
|
+
*/
|
|
223
|
+
create(data: PayrollData, options?: {
|
|
224
|
+
session?: ClientSession;
|
|
225
|
+
}): Promise<PayrollRecordDocument>;
|
|
226
|
+
/**
|
|
227
|
+
* Generate payroll for employee with organization validation
|
|
228
|
+
*
|
|
229
|
+
* ⚠️ SECURITY: Validates employee belongs to organization
|
|
230
|
+
*/
|
|
231
|
+
generateForEmployee(employeeId: ObjectIdLike, organizationId: ObjectIdLike, month: number, year: number, options?: {
|
|
232
|
+
session?: ClientSession;
|
|
233
|
+
}): Promise<PayrollRecordDocument>;
|
|
234
|
+
/**
|
|
235
|
+
* Generate batch payroll
|
|
236
|
+
*/
|
|
237
|
+
generateBatch(organizationId: ObjectIdLike, month: number, year: number, options?: {
|
|
238
|
+
session?: ClientSession;
|
|
239
|
+
}): Promise<{
|
|
240
|
+
success: boolean;
|
|
241
|
+
generated: number;
|
|
242
|
+
skipped: number;
|
|
243
|
+
payrolls: PayrollRecordDocument[];
|
|
244
|
+
message: string;
|
|
245
|
+
}>;
|
|
246
|
+
/**
|
|
247
|
+
* Mark payroll as paid with organization validation
|
|
248
|
+
*
|
|
249
|
+
* ⚠️ SECURITY: Validates payroll belongs to organization
|
|
250
|
+
*/
|
|
251
|
+
markAsPaid(payrollId: ObjectIdLike, organizationId: ObjectIdLike, // Required for multi-tenant isolation
|
|
252
|
+
paymentDetails?: {
|
|
253
|
+
paidAt?: Date;
|
|
254
|
+
transactionId?: ObjectIdLike;
|
|
255
|
+
paymentMethod?: PaymentMethod;
|
|
256
|
+
}, options?: {
|
|
257
|
+
session?: ClientSession;
|
|
258
|
+
}): Promise<PayrollRecordDocument>;
|
|
259
|
+
/**
|
|
260
|
+
* Mark payroll as processed with organization validation
|
|
261
|
+
*
|
|
262
|
+
* ⚠️ SECURITY: Validates payroll belongs to organization
|
|
263
|
+
*/
|
|
264
|
+
markAsProcessed(payrollId: ObjectIdLike, organizationId: ObjectIdLike, // Required for multi-tenant isolation
|
|
265
|
+
options?: {
|
|
266
|
+
session?: ClientSession;
|
|
267
|
+
}): Promise<PayrollRecordDocument>;
|
|
268
|
+
/**
|
|
269
|
+
* Calculate period summary
|
|
270
|
+
*/
|
|
271
|
+
calculatePeriodSummary(organizationId: ObjectIdLike, month: number, year: number, options?: {
|
|
272
|
+
session?: ClientSession;
|
|
273
|
+
}): Promise<{
|
|
274
|
+
period: {
|
|
275
|
+
month: number;
|
|
276
|
+
year: number;
|
|
277
|
+
};
|
|
278
|
+
count: number;
|
|
279
|
+
totalGross: number;
|
|
280
|
+
totalNet: number;
|
|
281
|
+
totalAllowances: number;
|
|
282
|
+
totalDeductions: number;
|
|
283
|
+
byStatus: Record<string, number>;
|
|
284
|
+
}>;
|
|
285
|
+
/**
|
|
286
|
+
* Get employee payroll history
|
|
287
|
+
*/
|
|
288
|
+
getEmployeePayrollHistory(employeeId: ObjectIdLike, organizationId: ObjectIdLike, limit?: number, options?: {
|
|
289
|
+
session?: ClientSession;
|
|
290
|
+
}): Promise<PayrollRecordDocument[]>;
|
|
291
|
+
/**
|
|
292
|
+
* Get overview stats
|
|
293
|
+
*/
|
|
294
|
+
getOverviewStats(organizationId: ObjectIdLike, options?: {
|
|
295
|
+
session?: ClientSession;
|
|
296
|
+
}): Promise<{
|
|
297
|
+
currentPeriod: {
|
|
298
|
+
month: number;
|
|
299
|
+
year: number;
|
|
300
|
+
};
|
|
301
|
+
count: number;
|
|
302
|
+
totalGross: number;
|
|
303
|
+
totalNet: number;
|
|
304
|
+
totalAllowances: number;
|
|
305
|
+
totalDeductions: number;
|
|
306
|
+
byStatus: Record<string, number>;
|
|
307
|
+
}>;
|
|
308
|
+
/**
|
|
309
|
+
* Group payrolls by status
|
|
310
|
+
*/
|
|
311
|
+
private groupByStatus;
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Create payroll service instance
|
|
315
|
+
*/
|
|
316
|
+
declare function createPayrollService(PayrollModel: Model<PayrollRecordDocument>, employeeService: EmployeeService): PayrollService;
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* @classytic/payroll - Compensation Service
|
|
320
|
+
*
|
|
321
|
+
* High-level compensation operations with dependency injection
|
|
322
|
+
*/
|
|
323
|
+
|
|
324
|
+
declare class CompensationService {
|
|
325
|
+
private readonly EmployeeModel;
|
|
326
|
+
constructor(EmployeeModel: Model<EmployeeDocument>);
|
|
327
|
+
/**
|
|
328
|
+
* Get employee compensation with organization validation
|
|
329
|
+
*
|
|
330
|
+
* ⚠️ SECURITY: Validates employee belongs to organization
|
|
331
|
+
*/
|
|
332
|
+
getEmployeeCompensation(employeeId: ObjectIdLike, organizationId: ObjectIdLike, // Required for multi-tenant isolation
|
|
333
|
+
options?: {
|
|
334
|
+
session?: ClientSession;
|
|
335
|
+
}): Promise<Compensation>;
|
|
336
|
+
/**
|
|
337
|
+
* Calculate compensation breakdown with organization validation
|
|
338
|
+
*
|
|
339
|
+
* ⚠️ SECURITY: Validates employee belongs to organization
|
|
340
|
+
*/
|
|
341
|
+
calculateBreakdown(employeeId: ObjectIdLike, organizationId: ObjectIdLike, // Required for multi-tenant isolation
|
|
342
|
+
options?: {
|
|
343
|
+
session?: ClientSession;
|
|
344
|
+
}): Promise<CompensationBreakdownResult>;
|
|
345
|
+
/**
|
|
346
|
+
* Update base amount with organization validation
|
|
347
|
+
*
|
|
348
|
+
* ⚠️ SECURITY: Validates employee belongs to organization before update
|
|
349
|
+
*/
|
|
350
|
+
updateBaseAmount(employeeId: ObjectIdLike, organizationId: ObjectIdLike, // Required for multi-tenant isolation
|
|
351
|
+
newAmount: number, effectiveFrom?: Date, options?: {
|
|
352
|
+
session?: ClientSession;
|
|
353
|
+
}): Promise<CompensationBreakdownResult>;
|
|
354
|
+
/**
|
|
355
|
+
* Apply salary increment with organization validation
|
|
356
|
+
*
|
|
357
|
+
* ⚠️ SECURITY: Validates employee belongs to organization before update
|
|
358
|
+
*/
|
|
359
|
+
applyIncrement(employeeId: ObjectIdLike, organizationId: ObjectIdLike, // Required for multi-tenant isolation
|
|
360
|
+
params: {
|
|
361
|
+
percentage?: number;
|
|
362
|
+
amount?: number;
|
|
363
|
+
effectiveFrom?: Date;
|
|
364
|
+
}, options?: {
|
|
365
|
+
session?: ClientSession;
|
|
366
|
+
}): Promise<CompensationBreakdownResult>;
|
|
367
|
+
/**
|
|
368
|
+
* Add allowance with organization validation
|
|
369
|
+
*
|
|
370
|
+
* ⚠️ SECURITY: Validates employee belongs to organization before update
|
|
371
|
+
*/
|
|
372
|
+
addAllowance(employeeId: ObjectIdLike, organizationId: ObjectIdLike, // Required for multi-tenant isolation
|
|
373
|
+
allowance: {
|
|
374
|
+
type: Allowance['type'];
|
|
375
|
+
value: number;
|
|
376
|
+
isPercentage?: boolean;
|
|
377
|
+
name?: string;
|
|
378
|
+
taxable?: boolean;
|
|
379
|
+
}, options?: {
|
|
380
|
+
session?: ClientSession;
|
|
381
|
+
}): Promise<CompensationBreakdownResult>;
|
|
382
|
+
/**
|
|
383
|
+
* Remove allowance with organization validation
|
|
384
|
+
*
|
|
385
|
+
* ⚠️ SECURITY: Validates employee belongs to organization before update
|
|
386
|
+
*/
|
|
387
|
+
removeAllowance(employeeId: ObjectIdLike, organizationId: ObjectIdLike, // Required for multi-tenant isolation
|
|
388
|
+
allowanceType: Allowance['type'], options?: {
|
|
389
|
+
session?: ClientSession;
|
|
390
|
+
}): Promise<CompensationBreakdownResult>;
|
|
391
|
+
/**
|
|
392
|
+
* Add deduction with organization validation
|
|
393
|
+
*
|
|
394
|
+
* ⚠️ SECURITY: Validates employee belongs to organization before update
|
|
395
|
+
*/
|
|
396
|
+
addDeduction(employeeId: ObjectIdLike, organizationId: ObjectIdLike, // Required for multi-tenant isolation
|
|
397
|
+
deduction: {
|
|
398
|
+
type: Deduction['type'];
|
|
399
|
+
value: number;
|
|
400
|
+
isPercentage?: boolean;
|
|
401
|
+
name?: string;
|
|
402
|
+
auto?: boolean;
|
|
403
|
+
}, options?: {
|
|
404
|
+
session?: ClientSession;
|
|
405
|
+
}): Promise<CompensationBreakdownResult>;
|
|
406
|
+
/**
|
|
407
|
+
* Remove deduction with organization validation
|
|
408
|
+
*
|
|
409
|
+
* ⚠️ SECURITY: Validates employee belongs to organization before update
|
|
410
|
+
*/
|
|
411
|
+
removeDeduction(employeeId: ObjectIdLike, organizationId: ObjectIdLike, // Required for multi-tenant isolation
|
|
412
|
+
deductionType: Deduction['type'], options?: {
|
|
413
|
+
session?: ClientSession;
|
|
414
|
+
}): Promise<CompensationBreakdownResult>;
|
|
415
|
+
/**
|
|
416
|
+
* Set standard compensation with organization validation
|
|
417
|
+
*
|
|
418
|
+
* ⚠️ SECURITY: Validates employee belongs to organization before update
|
|
419
|
+
*/
|
|
420
|
+
setStandardCompensation(employeeId: ObjectIdLike, organizationId: ObjectIdLike, // Required for multi-tenant isolation
|
|
421
|
+
baseAmount: number, options?: {
|
|
422
|
+
session?: ClientSession;
|
|
423
|
+
}): Promise<CompensationBreakdownResult>;
|
|
424
|
+
/**
|
|
425
|
+
* Compare compensation between two employees
|
|
426
|
+
*
|
|
427
|
+
* ⚠️ SECURITY: Validates both employees belong to organization
|
|
428
|
+
*/
|
|
429
|
+
compareCompensation(employeeId1: ObjectIdLike, employeeId2: ObjectIdLike, organizationId: ObjectIdLike, // Required for multi-tenant isolation
|
|
430
|
+
options?: {
|
|
431
|
+
session?: ClientSession;
|
|
432
|
+
}): Promise<{
|
|
433
|
+
employee1: CompensationBreakdownResult;
|
|
434
|
+
employee2: CompensationBreakdownResult;
|
|
435
|
+
difference: {
|
|
436
|
+
base: number;
|
|
437
|
+
gross: number;
|
|
438
|
+
net: number;
|
|
439
|
+
};
|
|
440
|
+
ratio: {
|
|
441
|
+
base: number;
|
|
442
|
+
gross: number;
|
|
443
|
+
net: number;
|
|
444
|
+
};
|
|
445
|
+
}>;
|
|
446
|
+
/**
|
|
447
|
+
* Get department compensation stats
|
|
448
|
+
*/
|
|
449
|
+
getDepartmentCompensationStats(organizationId: ObjectIdLike, department: Department, options?: {
|
|
450
|
+
session?: ClientSession;
|
|
451
|
+
}): Promise<{
|
|
452
|
+
department: string;
|
|
453
|
+
employeeCount: number;
|
|
454
|
+
totalBase: number;
|
|
455
|
+
totalGross: number;
|
|
456
|
+
totalNet: number;
|
|
457
|
+
averageBase: number;
|
|
458
|
+
averageGross: number;
|
|
459
|
+
averageNet: number;
|
|
460
|
+
}>;
|
|
461
|
+
/**
|
|
462
|
+
* Get organization compensation stats
|
|
463
|
+
*/
|
|
464
|
+
getOrganizationCompensationStats(organizationId: ObjectIdLike, options?: {
|
|
465
|
+
session?: ClientSession;
|
|
466
|
+
}): Promise<{
|
|
467
|
+
employeeCount: number;
|
|
468
|
+
totalBase: number;
|
|
469
|
+
totalGross: number;
|
|
470
|
+
totalNet: number;
|
|
471
|
+
averageBase: number;
|
|
472
|
+
averageGross: number;
|
|
473
|
+
averageNet: number;
|
|
474
|
+
byDepartment: Record<string, {
|
|
475
|
+
count: number;
|
|
476
|
+
totalNet: number;
|
|
477
|
+
}>;
|
|
478
|
+
}>;
|
|
479
|
+
/**
|
|
480
|
+
* Find employee helper with organization validation
|
|
481
|
+
*
|
|
482
|
+
* ⚠️ SECURITY: Always validates employee belongs to organization
|
|
483
|
+
*/
|
|
484
|
+
private findEmployee;
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Create compensation service instance
|
|
488
|
+
*/
|
|
489
|
+
declare function createCompensationService(EmployeeModel: Model<EmployeeDocument>): CompensationService;
|
|
490
|
+
|
|
491
|
+
/**
|
|
492
|
+
* @classytic/payroll - Tax Withholding Service
|
|
493
|
+
*
|
|
494
|
+
* Business logic for tax withholding tracking and management
|
|
495
|
+
*/
|
|
496
|
+
|
|
497
|
+
interface TaxWithholdingServiceConfig {
|
|
498
|
+
TaxWithholdingModel: Model<TaxWithholdingDocument>;
|
|
499
|
+
TransactionModel?: AnyModel;
|
|
500
|
+
events?: EventBus;
|
|
501
|
+
}
|
|
502
|
+
interface CreateFromBreakdownParams {
|
|
503
|
+
organizationId: ObjectId;
|
|
504
|
+
employeeId: ObjectId;
|
|
505
|
+
userId?: ObjectId;
|
|
506
|
+
payrollRecordId: ObjectId;
|
|
507
|
+
transactionId: ObjectId;
|
|
508
|
+
period: PayrollPeriod;
|
|
509
|
+
breakdown: PayrollBreakdown;
|
|
510
|
+
currency?: string;
|
|
511
|
+
session?: ClientSession;
|
|
512
|
+
context?: OperationContext;
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Service for managing tax withholdings
|
|
516
|
+
*
|
|
517
|
+
* Provides methods for creating, querying, and updating tax withholding records
|
|
518
|
+
*/
|
|
519
|
+
declare class TaxWithholdingService {
|
|
520
|
+
private readonly TaxWithholdingModel;
|
|
521
|
+
private readonly TransactionModel?;
|
|
522
|
+
private readonly events?;
|
|
523
|
+
constructor(TaxWithholdingModel: Model<TaxWithholdingDocument>, TransactionModel?: AnyModel | undefined, events?: EventBus | undefined);
|
|
524
|
+
/**
|
|
525
|
+
* Create tax withholding records from payroll breakdown
|
|
526
|
+
*
|
|
527
|
+
* Extracts tax deductions from the breakdown and creates separate
|
|
528
|
+
* TaxWithholding records for each tax type
|
|
529
|
+
*/
|
|
530
|
+
createFromBreakdown(params: CreateFromBreakdownParams): Promise<TaxWithholdingDocument[]>;
|
|
531
|
+
/**
|
|
532
|
+
* Get pending tax withholdings with optional filters
|
|
533
|
+
*/
|
|
534
|
+
getPending(params: GetPendingTaxParams): Promise<TaxWithholdingDocument[]>;
|
|
535
|
+
/**
|
|
536
|
+
* Get tax summary aggregated by type, period, or employee
|
|
537
|
+
*/
|
|
538
|
+
getSummary(params: TaxSummaryParams): Promise<TaxSummaryResult>;
|
|
539
|
+
/**
|
|
540
|
+
* Mark tax withholdings as paid
|
|
541
|
+
*
|
|
542
|
+
* Updates status, optionally creates government payment transaction,
|
|
543
|
+
* and emits tax:paid event
|
|
544
|
+
*/
|
|
545
|
+
markPaid(params: MarkTaxPaidParams): Promise<{
|
|
546
|
+
withholdings: TaxWithholdingDocument[];
|
|
547
|
+
transaction?: any;
|
|
548
|
+
}>;
|
|
549
|
+
/**
|
|
550
|
+
* Get tax withholdings for a specific payroll record
|
|
551
|
+
*/
|
|
552
|
+
getByPayrollRecord(payrollRecordId: ObjectIdLike): Promise<TaxWithholdingDocument[]>;
|
|
553
|
+
/**
|
|
554
|
+
* Get tax withholdings for a specific employee
|
|
555
|
+
*/
|
|
556
|
+
getByEmployee(employeeId: ObjectIdLike, options?: {
|
|
557
|
+
year?: number;
|
|
558
|
+
taxType?: TaxType;
|
|
559
|
+
status?: TaxStatus;
|
|
560
|
+
}): Promise<TaxWithholdingDocument[]>;
|
|
561
|
+
/**
|
|
562
|
+
* Check if deduction type is a tax deduction
|
|
563
|
+
*/
|
|
564
|
+
private isTaxDeduction;
|
|
565
|
+
/**
|
|
566
|
+
* Map deduction type to TaxType enum
|
|
567
|
+
*/
|
|
568
|
+
private mapDeductionTypeToTaxType;
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* Create a new TaxWithholdingService instance
|
|
572
|
+
*
|
|
573
|
+
* @example
|
|
574
|
+
* const service = createTaxWithholdingService({
|
|
575
|
+
* TaxWithholdingModel,
|
|
576
|
+
* TransactionModel,
|
|
577
|
+
* events: eventBus
|
|
578
|
+
* });
|
|
579
|
+
*/
|
|
580
|
+
declare function createTaxWithholdingService(config: TaxWithholdingServiceConfig): TaxWithholdingService;
|
|
581
|
+
|
|
582
|
+
export { CompensationService, type CreateFromBreakdownParams, EmployeeService, PayrollService, TaxWithholdingService, type TaxWithholdingServiceConfig, createCompensationService, createEmployeeService, createPayrollService, createTaxWithholdingService };
|