@classytic/payroll 2.0.0 → 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 -253
- 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 +85 -251
- package/dist/core/index.js +286 -91
- package/dist/core/index.js.map +1 -1
- 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 +618 -683
- package/dist/index.js +8336 -3580
- package/dist/index.js.map +1 -1
- 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 +261 -65
- package/dist/payroll.js +4164 -1075
- package/dist/payroll.js.map +1 -1
- package/dist/schemas/index.d.ts +1176 -783
- package/dist/schemas/index.js +368 -28
- package/dist/schemas/index.js.map +1 -1
- package/dist/services/index.d.ts +582 -3
- package/dist/services/index.js +572 -96
- package/dist/services/index.js.map +1 -1
- 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 +22 -2
- package/dist/utils/index.js +470 -1
- package/dist/utils/index.js.map +1 -1
- package/package.json +24 -6
- package/dist/index-CTjHlCzz.d.ts +0 -721
- package/dist/plugin-D9mOr3_d.d.ts +0 -333
- package/dist/types-BSYyX2KJ.d.ts +0 -671
package/dist/schemas/index.js
CHANGED
|
@@ -39,6 +39,16 @@ var PAYMENT_FREQUENCY = {
|
|
|
39
39
|
DAILY: "daily"
|
|
40
40
|
};
|
|
41
41
|
var PAYMENT_FREQUENCY_VALUES = Object.values(PAYMENT_FREQUENCY);
|
|
42
|
+
var PAYMENT_METHOD = {
|
|
43
|
+
BANK: "bank",
|
|
44
|
+
CASH: "cash",
|
|
45
|
+
MOBILE: "mobile",
|
|
46
|
+
BKASH: "bkash",
|
|
47
|
+
NAGAD: "nagad",
|
|
48
|
+
ROCKET: "rocket",
|
|
49
|
+
CHECK: "check"
|
|
50
|
+
};
|
|
51
|
+
var PAYMENT_METHOD_VALUES = Object.values(PAYMENT_METHOD);
|
|
42
52
|
var ALLOWANCE_TYPE = {
|
|
43
53
|
HOUSING: "housing",
|
|
44
54
|
TRANSPORT: "transport",
|
|
@@ -77,6 +87,40 @@ var TERMINATION_REASON = {
|
|
|
77
87
|
OTHER: "other"
|
|
78
88
|
};
|
|
79
89
|
var TERMINATION_REASON_VALUES = Object.values(TERMINATION_REASON);
|
|
90
|
+
var LEAVE_TYPE = {
|
|
91
|
+
ANNUAL: "annual",
|
|
92
|
+
SICK: "sick",
|
|
93
|
+
UNPAID: "unpaid",
|
|
94
|
+
MATERNITY: "maternity",
|
|
95
|
+
PATERNITY: "paternity",
|
|
96
|
+
BEREAVEMENT: "bereavement",
|
|
97
|
+
COMPENSATORY: "compensatory",
|
|
98
|
+
OTHER: "other"
|
|
99
|
+
};
|
|
100
|
+
var LEAVE_TYPE_VALUES = Object.values(LEAVE_TYPE);
|
|
101
|
+
var LEAVE_REQUEST_STATUS = {
|
|
102
|
+
PENDING: "pending",
|
|
103
|
+
APPROVED: "approved",
|
|
104
|
+
REJECTED: "rejected",
|
|
105
|
+
CANCELLED: "cancelled"
|
|
106
|
+
};
|
|
107
|
+
var LEAVE_REQUEST_STATUS_VALUES = Object.values(LEAVE_REQUEST_STATUS);
|
|
108
|
+
var TAX_TYPE = {
|
|
109
|
+
INCOME_TAX: "income_tax",
|
|
110
|
+
SOCIAL_SECURITY: "social_security",
|
|
111
|
+
HEALTH_INSURANCE: "health_insurance",
|
|
112
|
+
PENSION: "pension",
|
|
113
|
+
EMPLOYMENT_INSURANCE: "employment_insurance",
|
|
114
|
+
LOCAL_TAX: "local_tax",
|
|
115
|
+
OTHER: "other"
|
|
116
|
+
};
|
|
117
|
+
var TAX_TYPE_VALUES = Object.values(TAX_TYPE);
|
|
118
|
+
var TAX_STATUS = {
|
|
119
|
+
PENDING: "pending",
|
|
120
|
+
SUBMITTED: "submitted",
|
|
121
|
+
PAID: "paid"
|
|
122
|
+
};
|
|
123
|
+
var TAX_STATUS_VALUES = Object.values(TAX_STATUS);
|
|
80
124
|
|
|
81
125
|
// src/config.ts
|
|
82
126
|
var HRM_CONFIG = {
|
|
@@ -115,6 +159,267 @@ var ORG_ROLES = {
|
|
|
115
159
|
}
|
|
116
160
|
};
|
|
117
161
|
Object.values(ORG_ROLES).map((role) => role.key);
|
|
162
|
+
var periodSchema = new Schema(
|
|
163
|
+
{
|
|
164
|
+
month: { type: Number, required: true, min: 1, max: 12 },
|
|
165
|
+
year: { type: Number, required: true, min: 2020 },
|
|
166
|
+
startDate: { type: Date, required: true },
|
|
167
|
+
endDate: { type: Date, required: true },
|
|
168
|
+
payDate: { type: Date, required: true }
|
|
169
|
+
},
|
|
170
|
+
{ _id: false }
|
|
171
|
+
);
|
|
172
|
+
var leaveBalanceSchema = new Schema(
|
|
173
|
+
{
|
|
174
|
+
type: {
|
|
175
|
+
type: String,
|
|
176
|
+
enum: LEAVE_TYPE_VALUES,
|
|
177
|
+
required: true
|
|
178
|
+
},
|
|
179
|
+
allocated: { type: Number, default: 0, min: 0 },
|
|
180
|
+
used: { type: Number, default: 0, min: 0 },
|
|
181
|
+
pending: { type: Number, default: 0, min: 0 },
|
|
182
|
+
carriedOver: { type: Number, default: 0, min: 0 },
|
|
183
|
+
expiresAt: { type: Date },
|
|
184
|
+
year: { type: Number, required: true }
|
|
185
|
+
},
|
|
186
|
+
{ _id: false }
|
|
187
|
+
);
|
|
188
|
+
var leaveBalanceFields = {
|
|
189
|
+
leaveBalances: [leaveBalanceSchema]
|
|
190
|
+
};
|
|
191
|
+
var leaveRequestFields = {
|
|
192
|
+
organizationId: {
|
|
193
|
+
type: Schema.Types.ObjectId,
|
|
194
|
+
ref: "Organization",
|
|
195
|
+
required: false
|
|
196
|
+
// Optional for single-tenant mode
|
|
197
|
+
},
|
|
198
|
+
employeeId: {
|
|
199
|
+
type: Schema.Types.ObjectId,
|
|
200
|
+
required: true
|
|
201
|
+
},
|
|
202
|
+
userId: {
|
|
203
|
+
type: Schema.Types.ObjectId,
|
|
204
|
+
ref: "User",
|
|
205
|
+
required: true
|
|
206
|
+
},
|
|
207
|
+
type: {
|
|
208
|
+
type: String,
|
|
209
|
+
enum: LEAVE_TYPE_VALUES,
|
|
210
|
+
required: true
|
|
211
|
+
},
|
|
212
|
+
startDate: { type: Date, required: true },
|
|
213
|
+
endDate: { type: Date, required: true },
|
|
214
|
+
days: { type: Number, required: true, min: 0.5 },
|
|
215
|
+
halfDay: { type: Boolean, default: false },
|
|
216
|
+
reason: { type: String },
|
|
217
|
+
status: {
|
|
218
|
+
type: String,
|
|
219
|
+
enum: LEAVE_REQUEST_STATUS_VALUES,
|
|
220
|
+
default: "pending"
|
|
221
|
+
},
|
|
222
|
+
reviewedBy: { type: Schema.Types.ObjectId, ref: "User" },
|
|
223
|
+
reviewedAt: { type: Date },
|
|
224
|
+
reviewNotes: { type: String },
|
|
225
|
+
attachments: [{ type: String }],
|
|
226
|
+
metadata: { type: Schema.Types.Mixed, default: {} }
|
|
227
|
+
};
|
|
228
|
+
var leaveRequestIndexes = [
|
|
229
|
+
{ fields: { organizationId: 1, employeeId: 1, startDate: -1 } },
|
|
230
|
+
{ fields: { organizationId: 1, status: 1, createdAt: -1 } },
|
|
231
|
+
{ fields: { employeeId: 1, status: 1 } },
|
|
232
|
+
// Most relevant for single-tenant
|
|
233
|
+
{ fields: { organizationId: 1, type: 1, status: 1 } }
|
|
234
|
+
];
|
|
235
|
+
var leaveRequestTTLIndex = {
|
|
236
|
+
fields: { createdAt: 1 },
|
|
237
|
+
options: {
|
|
238
|
+
expireAfterSeconds: 63072e3,
|
|
239
|
+
// 2 years default
|
|
240
|
+
partialFilterExpression: {
|
|
241
|
+
status: { $in: ["approved", "rejected", "cancelled"] }
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
function applyLeaveRequestIndexes(schema, options = {}) {
|
|
246
|
+
if (!options.createIndexes) return;
|
|
247
|
+
for (const { fields } of leaveRequestIndexes) {
|
|
248
|
+
schema.index(fields);
|
|
249
|
+
}
|
|
250
|
+
if (options.enableTTL) {
|
|
251
|
+
schema.index(leaveRequestTTLIndex.fields, {
|
|
252
|
+
...leaveRequestTTLIndex.options,
|
|
253
|
+
expireAfterSeconds: options.ttlSeconds ?? leaveRequestTTLIndex.options.expireAfterSeconds
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
function createLeaveRequestSchema(additionalFields = {}, options = {}) {
|
|
258
|
+
const fields = { ...leaveRequestFields };
|
|
259
|
+
if (options.requireOrganizationId) {
|
|
260
|
+
fields.organizationId = {
|
|
261
|
+
...fields.organizationId,
|
|
262
|
+
required: true
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
const schema = new Schema(
|
|
266
|
+
{
|
|
267
|
+
...fields,
|
|
268
|
+
...additionalFields
|
|
269
|
+
},
|
|
270
|
+
{ timestamps: true }
|
|
271
|
+
);
|
|
272
|
+
applyLeaveRequestIndexes(schema, options);
|
|
273
|
+
schema.virtual("isPending").get(function() {
|
|
274
|
+
return this.status === "pending";
|
|
275
|
+
});
|
|
276
|
+
schema.virtual("isApproved").get(function() {
|
|
277
|
+
return this.status === "approved";
|
|
278
|
+
});
|
|
279
|
+
schema.virtual("isRejected").get(function() {
|
|
280
|
+
return this.status === "rejected";
|
|
281
|
+
});
|
|
282
|
+
schema.virtual("isCancelled").get(function() {
|
|
283
|
+
return this.status === "cancelled";
|
|
284
|
+
});
|
|
285
|
+
schema.virtual("durationInDays").get(function() {
|
|
286
|
+
return this.days;
|
|
287
|
+
});
|
|
288
|
+
return schema;
|
|
289
|
+
}
|
|
290
|
+
var taxWithholdingFields = {
|
|
291
|
+
organizationId: {
|
|
292
|
+
type: Schema.Types.ObjectId,
|
|
293
|
+
required: true,
|
|
294
|
+
ref: "Organization",
|
|
295
|
+
index: true
|
|
296
|
+
},
|
|
297
|
+
employeeId: {
|
|
298
|
+
type: Schema.Types.ObjectId,
|
|
299
|
+
required: true,
|
|
300
|
+
ref: "Employee",
|
|
301
|
+
index: true
|
|
302
|
+
},
|
|
303
|
+
userId: {
|
|
304
|
+
type: Schema.Types.ObjectId,
|
|
305
|
+
required: false,
|
|
306
|
+
ref: "User"
|
|
307
|
+
},
|
|
308
|
+
payrollRecordId: {
|
|
309
|
+
type: Schema.Types.ObjectId,
|
|
310
|
+
required: true,
|
|
311
|
+
ref: "PayrollRecord",
|
|
312
|
+
index: true
|
|
313
|
+
},
|
|
314
|
+
transactionId: {
|
|
315
|
+
type: Schema.Types.ObjectId,
|
|
316
|
+
required: true,
|
|
317
|
+
ref: "Transaction",
|
|
318
|
+
index: true
|
|
319
|
+
},
|
|
320
|
+
period: {
|
|
321
|
+
type: periodSchema,
|
|
322
|
+
required: true
|
|
323
|
+
},
|
|
324
|
+
amount: {
|
|
325
|
+
type: Number,
|
|
326
|
+
required: true,
|
|
327
|
+
min: 0
|
|
328
|
+
},
|
|
329
|
+
currency: {
|
|
330
|
+
type: String,
|
|
331
|
+
default: "BDT"
|
|
332
|
+
},
|
|
333
|
+
taxType: {
|
|
334
|
+
type: String,
|
|
335
|
+
enum: TAX_TYPE_VALUES,
|
|
336
|
+
required: true
|
|
337
|
+
},
|
|
338
|
+
taxRate: {
|
|
339
|
+
type: Number,
|
|
340
|
+
required: true,
|
|
341
|
+
min: 0,
|
|
342
|
+
max: 1
|
|
343
|
+
},
|
|
344
|
+
taxableAmount: {
|
|
345
|
+
type: Number,
|
|
346
|
+
required: true,
|
|
347
|
+
min: 0
|
|
348
|
+
},
|
|
349
|
+
status: {
|
|
350
|
+
type: String,
|
|
351
|
+
enum: TAX_STATUS_VALUES,
|
|
352
|
+
default: "pending"
|
|
353
|
+
},
|
|
354
|
+
submittedAt: Date,
|
|
355
|
+
paidAt: Date,
|
|
356
|
+
governmentTransactionId: {
|
|
357
|
+
type: Schema.Types.ObjectId,
|
|
358
|
+
ref: "Transaction"
|
|
359
|
+
},
|
|
360
|
+
referenceNumber: String,
|
|
361
|
+
notes: String,
|
|
362
|
+
metadata: {
|
|
363
|
+
type: Schema.Types.Mixed,
|
|
364
|
+
default: {}
|
|
365
|
+
}
|
|
366
|
+
};
|
|
367
|
+
var taxWithholdingIndexes = [
|
|
368
|
+
{
|
|
369
|
+
fields: { organizationId: 1, status: 1, "period.year": 1, "period.month": 1 }
|
|
370
|
+
},
|
|
371
|
+
{
|
|
372
|
+
fields: { employeeId: 1, "period.year": -1, "period.month": -1 }
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
fields: { payrollRecordId: 1 }
|
|
376
|
+
},
|
|
377
|
+
{
|
|
378
|
+
fields: { transactionId: 1 }
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
fields: { organizationId: 1, taxType: 1, status: 1 }
|
|
382
|
+
},
|
|
383
|
+
{
|
|
384
|
+
fields: { governmentTransactionId: 1 },
|
|
385
|
+
options: { sparse: true }
|
|
386
|
+
}
|
|
387
|
+
];
|
|
388
|
+
function applyTaxWithholdingIndexes(schema) {
|
|
389
|
+
for (const { fields, options } of taxWithholdingIndexes) {
|
|
390
|
+
schema.index(fields, options);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
function createTaxWithholdingSchema(additionalFields = {}) {
|
|
394
|
+
const schema = new Schema(
|
|
395
|
+
{
|
|
396
|
+
...taxWithholdingFields,
|
|
397
|
+
...additionalFields
|
|
398
|
+
},
|
|
399
|
+
{ timestamps: true }
|
|
400
|
+
);
|
|
401
|
+
applyTaxWithholdingIndexes(schema);
|
|
402
|
+
schema.virtual("isPending").get(function() {
|
|
403
|
+
return this.status === "pending";
|
|
404
|
+
});
|
|
405
|
+
schema.virtual("isPaid").get(function() {
|
|
406
|
+
return this.status === "paid";
|
|
407
|
+
});
|
|
408
|
+
schema.virtual("isSubmitted").get(function() {
|
|
409
|
+
return this.status === "submitted";
|
|
410
|
+
});
|
|
411
|
+
schema.methods.markAsSubmitted = function(submittedAt = /* @__PURE__ */ new Date()) {
|
|
412
|
+
this.status = "submitted";
|
|
413
|
+
this.submittedAt = submittedAt;
|
|
414
|
+
};
|
|
415
|
+
schema.methods.markAsPaid = function(transactionId, referenceNumber, paidAt = /* @__PURE__ */ new Date()) {
|
|
416
|
+
this.status = "paid";
|
|
417
|
+
this.governmentTransactionId = transactionId;
|
|
418
|
+
this.referenceNumber = referenceNumber;
|
|
419
|
+
this.paidAt = paidAt;
|
|
420
|
+
};
|
|
421
|
+
return schema;
|
|
422
|
+
}
|
|
118
423
|
|
|
119
424
|
// src/schemas/index.ts
|
|
120
425
|
var allowanceSchema = new Schema(
|
|
@@ -219,7 +524,15 @@ var employmentFields = {
|
|
|
219
524
|
userId: {
|
|
220
525
|
type: Schema.Types.ObjectId,
|
|
221
526
|
ref: "User",
|
|
222
|
-
required:
|
|
527
|
+
required: false
|
|
528
|
+
// Allow guest employees (no user account)
|
|
529
|
+
},
|
|
530
|
+
email: {
|
|
531
|
+
type: String,
|
|
532
|
+
trim: true,
|
|
533
|
+
lowercase: true,
|
|
534
|
+
required: false
|
|
535
|
+
// For guest employees without user account
|
|
223
536
|
},
|
|
224
537
|
organizationId: {
|
|
225
538
|
type: Schema.Types.ObjectId,
|
|
@@ -253,20 +566,22 @@ var payrollBreakdownSchema = new Schema(
|
|
|
253
566
|
baseAmount: { type: Number, required: true, min: 0 },
|
|
254
567
|
allowances: [
|
|
255
568
|
{
|
|
256
|
-
type: { type: String },
|
|
257
|
-
amount: { type: Number, min: 0 },
|
|
569
|
+
type: { type: String, required: true },
|
|
570
|
+
amount: { type: Number, required: true, min: 0 },
|
|
258
571
|
taxable: { type: Boolean, default: true }
|
|
259
572
|
}
|
|
260
573
|
],
|
|
261
574
|
deductions: [
|
|
262
575
|
{
|
|
263
|
-
type: { type: String },
|
|
264
|
-
amount: { type: Number, min: 0 },
|
|
576
|
+
type: { type: String, required: true },
|
|
577
|
+
amount: { type: Number, required: true, min: 0 },
|
|
265
578
|
description: { type: String }
|
|
266
579
|
}
|
|
267
580
|
],
|
|
268
581
|
grossSalary: { type: Number, required: true, min: 0 },
|
|
269
582
|
netSalary: { type: Number, required: true, min: 0 },
|
|
583
|
+
taxableAmount: { type: Number, default: 0, min: 0 },
|
|
584
|
+
taxAmount: { type: Number, default: 0, min: 0 },
|
|
270
585
|
workingDays: { type: Number, min: 0 },
|
|
271
586
|
actualDays: { type: Number, min: 0 },
|
|
272
587
|
proRatedAmount: { type: Number, default: 0, min: 0 },
|
|
@@ -276,32 +591,21 @@ var payrollBreakdownSchema = new Schema(
|
|
|
276
591
|
},
|
|
277
592
|
{ _id: false }
|
|
278
593
|
);
|
|
279
|
-
var periodSchema = new Schema(
|
|
280
|
-
{
|
|
281
|
-
month: { type: Number, required: true, min: 1, max: 12 },
|
|
282
|
-
year: { type: Number, required: true, min: 2020 },
|
|
283
|
-
startDate: { type: Date, required: true },
|
|
284
|
-
endDate: { type: Date, required: true },
|
|
285
|
-
payDate: { type: Date, required: true }
|
|
286
|
-
},
|
|
287
|
-
{ _id: false }
|
|
288
|
-
);
|
|
289
594
|
var payrollRecordFields = {
|
|
290
595
|
organizationId: {
|
|
291
596
|
type: Schema.Types.ObjectId,
|
|
292
597
|
ref: "Organization",
|
|
293
|
-
required: true
|
|
294
|
-
index: true
|
|
598
|
+
required: true
|
|
295
599
|
},
|
|
296
600
|
employeeId: {
|
|
297
601
|
type: Schema.Types.ObjectId,
|
|
298
|
-
required: true
|
|
299
|
-
index: true
|
|
602
|
+
required: true
|
|
300
603
|
},
|
|
301
604
|
userId: {
|
|
302
605
|
type: Schema.Types.ObjectId,
|
|
303
606
|
ref: "User",
|
|
304
|
-
|
|
607
|
+
required: false
|
|
608
|
+
// Optional for guest employees
|
|
305
609
|
},
|
|
306
610
|
period: { type: periodSchema, required: true },
|
|
307
611
|
breakdown: { type: payrollBreakdownSchema, required: true },
|
|
@@ -309,20 +613,56 @@ var payrollRecordFields = {
|
|
|
309
613
|
status: {
|
|
310
614
|
type: String,
|
|
311
615
|
enum: PAYROLL_STATUS_VALUES,
|
|
312
|
-
default: "pending"
|
|
313
|
-
index: true
|
|
616
|
+
default: "pending"
|
|
314
617
|
},
|
|
618
|
+
processedAt: { type: Date },
|
|
315
619
|
paidAt: { type: Date },
|
|
316
|
-
paymentMethod: {
|
|
620
|
+
paymentMethod: {
|
|
621
|
+
type: String,
|
|
622
|
+
enum: PAYMENT_METHOD_VALUES
|
|
623
|
+
},
|
|
317
624
|
processedBy: { type: Schema.Types.ObjectId, ref: "User" },
|
|
318
625
|
notes: { type: String },
|
|
319
626
|
payslipUrl: { type: String },
|
|
627
|
+
metadata: {
|
|
628
|
+
type: Schema.Types.Mixed,
|
|
629
|
+
default: {}
|
|
630
|
+
},
|
|
320
631
|
exported: { type: Boolean, default: false },
|
|
321
|
-
exportedAt: { type: Date }
|
|
632
|
+
exportedAt: { type: Date },
|
|
633
|
+
corrections: [
|
|
634
|
+
{
|
|
635
|
+
previousAmount: Number,
|
|
636
|
+
newAmount: Number,
|
|
637
|
+
reason: String,
|
|
638
|
+
correctedBy: { type: Schema.Types.ObjectId, ref: "User" },
|
|
639
|
+
correctedAt: { type: Date, default: Date.now }
|
|
640
|
+
}
|
|
641
|
+
]
|
|
322
642
|
};
|
|
323
643
|
var employeeIndexes = [
|
|
324
644
|
{ fields: { organizationId: 1, employeeId: 1 }, options: { unique: true } },
|
|
325
|
-
|
|
645
|
+
// Partial unique index: Only includes docs with userId field (excludes guest employees)
|
|
646
|
+
// Uses partialFilterExpression instead of sparse for compound indexes
|
|
647
|
+
{
|
|
648
|
+
fields: { userId: 1, organizationId: 1 },
|
|
649
|
+
options: {
|
|
650
|
+
unique: true,
|
|
651
|
+
partialFilterExpression: { userId: { $exists: true } }
|
|
652
|
+
}
|
|
653
|
+
},
|
|
654
|
+
// Partial unique index: Only includes non-terminated docs with email
|
|
655
|
+
// This allows email reuse when employees are terminated and rehired
|
|
656
|
+
{
|
|
657
|
+
fields: { email: 1, organizationId: 1 },
|
|
658
|
+
options: {
|
|
659
|
+
unique: true,
|
|
660
|
+
partialFilterExpression: {
|
|
661
|
+
email: { $exists: true },
|
|
662
|
+
status: { $in: ["active", "on_leave", "suspended"] }
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
},
|
|
326
666
|
{ fields: { organizationId: 1, status: 1 } },
|
|
327
667
|
{ fields: { organizationId: 1, department: 1 } },
|
|
328
668
|
{ fields: { organizationId: 1, "compensation.netSalary": -1 } }
|
|
@@ -339,8 +679,8 @@ var payrollRecordIndexes = [
|
|
|
339
679
|
{
|
|
340
680
|
fields: { createdAt: 1 },
|
|
341
681
|
options: {
|
|
342
|
-
expireAfterSeconds: HRM_CONFIG.dataRetention.payrollRecordsTTL
|
|
343
|
-
|
|
682
|
+
expireAfterSeconds: HRM_CONFIG.dataRetention.payrollRecordsTTL
|
|
683
|
+
// TTL applies to ALL records (user handles backups/exports at app level)
|
|
344
684
|
}
|
|
345
685
|
}
|
|
346
686
|
];
|
|
@@ -435,6 +775,6 @@ var schemas_default = {
|
|
|
435
775
|
createPayrollRecordSchema
|
|
436
776
|
};
|
|
437
777
|
|
|
438
|
-
export { allowanceSchema, applyEmployeeIndexes, applyPayrollRecordIndexes, bankDetailsSchema, compensationSchema, createEmployeeSchema, createPayrollRecordSchema, deductionSchema, schemas_default as default, employeeIndexes, employmentFields, employmentHistorySchema, payrollBreakdownSchema, payrollRecordFields, payrollRecordIndexes, payrollStatsSchema, periodSchema, workScheduleSchema };
|
|
778
|
+
export { allowanceSchema, applyEmployeeIndexes, applyLeaveRequestIndexes, applyPayrollRecordIndexes, applyTaxWithholdingIndexes, bankDetailsSchema, compensationSchema, createEmployeeSchema, createLeaveRequestSchema, createPayrollRecordSchema, createTaxWithholdingSchema, deductionSchema, schemas_default as default, employeeIndexes, employmentFields, employmentHistorySchema, leaveBalanceFields, leaveBalanceSchema, leaveRequestFields, leaveRequestIndexes, leaveRequestTTLIndex, payrollBreakdownSchema, payrollRecordFields, payrollRecordIndexes, payrollStatsSchema, periodSchema, taxWithholdingFields, taxWithholdingIndexes, workScheduleSchema };
|
|
439
779
|
//# sourceMappingURL=index.js.map
|
|
440
780
|
//# sourceMappingURL=index.js.map
|