@classytic/payroll 2.7.5 → 2.8.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.
- package/README.md +333 -323
- package/dist/attendance.calculator-BZcv2iii.d.ts +336 -0
- package/dist/calculators/index.d.ts +3 -299
- package/dist/calculators/index.js +154 -19
- package/dist/calculators/index.js.map +1 -1
- package/dist/core/index.d.ts +321 -0
- package/dist/core/index.js +1962 -0
- package/dist/core/index.js.map +1 -0
- package/dist/{employee-identity-Cq2wo9-2.d.ts → error-helpers-Bm6lMny2.d.ts} +257 -7
- package/dist/{index-DjB72l6e.d.ts → index-BKLkuSAs.d.ts} +248 -132
- package/dist/index.d.ts +418 -658
- package/dist/index.js +1179 -373
- package/dist/index.js.map +1 -1
- package/dist/payroll-states-DBt0XVm-.d.ts +598 -0
- package/dist/{prorating.calculator-C7sdFiG2.d.ts → prorating.calculator-C33fWBQf.d.ts} +2 -2
- package/dist/schemas/index.d.ts +2 -2
- package/dist/schemas/index.js +95 -75
- package/dist/schemas/index.js.map +1 -1
- package/dist/{types-BVDjiVGS.d.ts → types-bZdAJueH.d.ts} +427 -12
- package/dist/utils/index.d.ts +17 -5
- package/dist/utils/index.js +185 -25
- package/dist/utils/index.js.map +1 -1
- package/package.json +5 -1
package/dist/schemas/index.js
CHANGED
|
@@ -123,76 +123,6 @@ var TAX_STATUS = {
|
|
|
123
123
|
CANCELLED: "cancelled"
|
|
124
124
|
};
|
|
125
125
|
var TAX_STATUS_VALUES = Object.values(TAX_STATUS);
|
|
126
|
-
|
|
127
|
-
// src/config.ts
|
|
128
|
-
var HRM_CONFIG = {
|
|
129
|
-
dataRetention: {
|
|
130
|
-
/**
|
|
131
|
-
* Default retention period for payroll records in seconds
|
|
132
|
-
*
|
|
133
|
-
* STANDARD APPROACH: expireAt field + configurable TTL index
|
|
134
|
-
*
|
|
135
|
-
* ## How It Works:
|
|
136
|
-
* 1. Set expireAt date on each payroll record
|
|
137
|
-
* 2. Call PayrollRecord.configureRetention() at app startup
|
|
138
|
-
* 3. MongoDB deletes documents when expireAt is reached
|
|
139
|
-
*
|
|
140
|
-
* ## Usage:
|
|
141
|
-
*
|
|
142
|
-
* @example Configure at initialization
|
|
143
|
-
* ```typescript
|
|
144
|
-
* await payroll.init({ ... });
|
|
145
|
-
* await PayrollRecord.configureRetention(0); // 0 = delete when expireAt reached
|
|
146
|
-
* ```
|
|
147
|
-
*
|
|
148
|
-
* @example Set expireAt per record
|
|
149
|
-
* ```typescript
|
|
150
|
-
* const expireAt = PayrollRecord.calculateExpireAt(7); // 7 years
|
|
151
|
-
* await PayrollRecord.updateOne({ _id }, { expireAt });
|
|
152
|
-
* ```
|
|
153
|
-
*
|
|
154
|
-
* ## Jurisdiction Requirements:
|
|
155
|
-
* - USA: 7 years → 220752000 seconds
|
|
156
|
-
* - EU/UK: 6 years → 189216000 seconds
|
|
157
|
-
* - Germany: 10 years → 315360000 seconds
|
|
158
|
-
* - India: 8 years → 252288000 seconds
|
|
159
|
-
*
|
|
160
|
-
* Set to 0 to disable TTL
|
|
161
|
-
*/
|
|
162
|
-
payrollRecordsTTL: 63072e3}};
|
|
163
|
-
var ORG_ROLES = {
|
|
164
|
-
OWNER: {
|
|
165
|
-
key: "owner",
|
|
166
|
-
label: "Owner",
|
|
167
|
-
description: "Full organization access (set by Organization model)"
|
|
168
|
-
},
|
|
169
|
-
MANAGER: {
|
|
170
|
-
key: "manager",
|
|
171
|
-
label: "Manager",
|
|
172
|
-
description: "Management and administrative features"
|
|
173
|
-
},
|
|
174
|
-
TRAINER: {
|
|
175
|
-
key: "trainer",
|
|
176
|
-
label: "Trainer",
|
|
177
|
-
description: "Training and coaching features"
|
|
178
|
-
},
|
|
179
|
-
STAFF: {
|
|
180
|
-
key: "staff",
|
|
181
|
-
label: "Staff",
|
|
182
|
-
description: "General staff access to basic features"
|
|
183
|
-
},
|
|
184
|
-
INTERN: {
|
|
185
|
-
key: "intern",
|
|
186
|
-
label: "Intern",
|
|
187
|
-
description: "Limited access for interns"
|
|
188
|
-
},
|
|
189
|
-
CONSULTANT: {
|
|
190
|
-
key: "consultant",
|
|
191
|
-
label: "Consultant",
|
|
192
|
-
description: "Project-based consultant access"
|
|
193
|
-
}
|
|
194
|
-
};
|
|
195
|
-
Object.values(ORG_ROLES).map((role) => role.key);
|
|
196
126
|
var periodSchema = new Schema(
|
|
197
127
|
{
|
|
198
128
|
month: { type: Number, required: true, min: 1, max: 12 },
|
|
@@ -1311,7 +1241,63 @@ function createPayrollRecordFields(options = {}) {
|
|
|
1311
1241
|
reversalTransactionId: { type: Schema.Types.ObjectId },
|
|
1312
1242
|
originalPayrollId: { type: Schema.Types.ObjectId },
|
|
1313
1243
|
// TTL expiration (per-document)
|
|
1314
|
-
expireAt: { type: Date }
|
|
1244
|
+
expireAt: { type: Date },
|
|
1245
|
+
// Payroll run type (v2.8.0+)
|
|
1246
|
+
payrollRunType: {
|
|
1247
|
+
type: String,
|
|
1248
|
+
enum: ["regular", "off-cycle", "supplemental", "retroactive"],
|
|
1249
|
+
default: "regular"
|
|
1250
|
+
},
|
|
1251
|
+
// Payment frequency at time of processing (v2.9.0+)
|
|
1252
|
+
// Stored for proper idempotency key reconstruction in void/reverse operations
|
|
1253
|
+
paymentFrequency: {
|
|
1254
|
+
type: String,
|
|
1255
|
+
enum: PAYMENT_FREQUENCY_VALUES,
|
|
1256
|
+
default: "monthly"
|
|
1257
|
+
},
|
|
1258
|
+
// Retroactive adjustment details (v2.8.0+)
|
|
1259
|
+
retroactiveAdjustment: {
|
|
1260
|
+
type: new Schema(
|
|
1261
|
+
{
|
|
1262
|
+
originalPeriod: {
|
|
1263
|
+
month: { type: Number, required: true, min: 1, max: 12 },
|
|
1264
|
+
year: { type: Number, required: true }
|
|
1265
|
+
},
|
|
1266
|
+
originalPayrollId: { type: Schema.Types.ObjectId },
|
|
1267
|
+
reason: { type: String, required: true },
|
|
1268
|
+
adjustmentAmount: { type: Number, required: true },
|
|
1269
|
+
approved: { type: Boolean },
|
|
1270
|
+
approvedBy: { type: Schema.Types.ObjectId },
|
|
1271
|
+
approvedAt: { type: Date }
|
|
1272
|
+
},
|
|
1273
|
+
{ _id: false }
|
|
1274
|
+
),
|
|
1275
|
+
required: false
|
|
1276
|
+
},
|
|
1277
|
+
// Employer contributions (v2.8.0+)
|
|
1278
|
+
employerContributions: [
|
|
1279
|
+
{
|
|
1280
|
+
type: {
|
|
1281
|
+
type: String,
|
|
1282
|
+
enum: ["social_security", "pension", "unemployment", "health_insurance", "other"],
|
|
1283
|
+
required: true
|
|
1284
|
+
},
|
|
1285
|
+
amount: { type: Number, required: true },
|
|
1286
|
+
description: { type: String },
|
|
1287
|
+
mandatory: { type: Boolean },
|
|
1288
|
+
referenceNumber: { type: String }
|
|
1289
|
+
}
|
|
1290
|
+
],
|
|
1291
|
+
// Corrections history (v2.8.0+)
|
|
1292
|
+
corrections: [
|
|
1293
|
+
{
|
|
1294
|
+
previousAmount: { type: Number },
|
|
1295
|
+
newAmount: { type: Number },
|
|
1296
|
+
reason: { type: String },
|
|
1297
|
+
correctedBy: { type: Schema.Types.ObjectId, ref: userRef },
|
|
1298
|
+
correctedAt: { type: Date, default: Date.now }
|
|
1299
|
+
}
|
|
1300
|
+
]
|
|
1315
1301
|
};
|
|
1316
1302
|
}
|
|
1317
1303
|
var employeeIndexes = [
|
|
@@ -1342,17 +1328,51 @@ var employeeIndexes = [
|
|
|
1342
1328
|
{ fields: { organizationId: 1, "compensation.netSalary": -1 } }
|
|
1343
1329
|
];
|
|
1344
1330
|
var payrollRecordIndexes = [
|
|
1345
|
-
|
|
1331
|
+
/**
|
|
1332
|
+
* UNIQUE Compound Index (v2.9.0+) - PRIMARY duplicate protection
|
|
1333
|
+
*
|
|
1334
|
+
* Prevents duplicate payrolls at the database level for the same:
|
|
1335
|
+
* - Organization, Employee, Period (month + year + startDate), Payroll run type
|
|
1336
|
+
*
|
|
1337
|
+
* The period.startDate is critical for non-monthly frequencies (weekly, bi_weekly,
|
|
1338
|
+
* daily, hourly) where multiple payroll runs can occur within the same calendar month.
|
|
1339
|
+
*
|
|
1340
|
+
* Partial filter excludes voided records to allow re-processing.
|
|
1341
|
+
* Duplicate inserts fail with E11000 → converted to DuplicatePayrollError.
|
|
1342
|
+
*/
|
|
1343
|
+
{
|
|
1344
|
+
fields: {
|
|
1345
|
+
organizationId: 1,
|
|
1346
|
+
employeeId: 1,
|
|
1347
|
+
"period.month": 1,
|
|
1348
|
+
"period.year": 1,
|
|
1349
|
+
"period.startDate": 1,
|
|
1350
|
+
payrollRunType: 1
|
|
1351
|
+
},
|
|
1352
|
+
options: {
|
|
1353
|
+
unique: true,
|
|
1354
|
+
name: "unique_payroll_per_period_startdate_runtype",
|
|
1355
|
+
// Only enforce for non-voided records (uses $eq which is supported in partial indexes)
|
|
1356
|
+
// When a record is voided, isVoided is set to true, excluding it from unique constraint
|
|
1357
|
+
partialFilterExpression: {
|
|
1358
|
+
isVoided: { $eq: false }
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1361
|
+
},
|
|
1362
|
+
// Composite index for common queries
|
|
1346
1363
|
{ fields: { organizationId: 1, employeeId: 1, "period.month": 1, "period.year": 1 } },
|
|
1347
1364
|
{ fields: { organizationId: 1, "period.year": 1, "period.month": 1 } },
|
|
1348
1365
|
{ fields: { employeeId: 1, "period.year": -1, "period.month": -1 } },
|
|
1349
1366
|
{ fields: { status: 1, createdAt: -1 } },
|
|
1350
1367
|
{ fields: { organizationId: 1, status: 1, "period.payDate": 1 } },
|
|
1368
|
+
// Index for payroll run type queries (supplemental, retroactive, etc.)
|
|
1369
|
+
{ fields: { organizationId: 1, payrollRunType: 1, "period.year": 1, "period.month": 1 } },
|
|
1370
|
+
// TTL index using expireAt field for per-document retention (jurisdiction-specific)
|
|
1351
1371
|
{
|
|
1352
|
-
fields: {
|
|
1372
|
+
fields: { expireAt: 1 },
|
|
1353
1373
|
options: {
|
|
1354
|
-
expireAfterSeconds:
|
|
1355
|
-
//
|
|
1374
|
+
expireAfterSeconds: 0
|
|
1375
|
+
// Delete immediately when expireAt is reached
|
|
1356
1376
|
}
|
|
1357
1377
|
}
|
|
1358
1378
|
];
|