@classytic/payroll 1.0.2 → 2.0.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 +168 -489
- package/dist/core/index.d.ts +480 -0
- package/dist/core/index.js +971 -0
- package/dist/core/index.js.map +1 -0
- package/dist/index-CTjHlCzz.d.ts +721 -0
- package/dist/index.d.ts +967 -0
- package/dist/index.js +4352 -0
- package/dist/index.js.map +1 -0
- package/dist/payroll.d.ts +233 -0
- package/dist/payroll.js +2103 -0
- package/dist/payroll.js.map +1 -0
- package/dist/plugin-D9mOr3_d.d.ts +333 -0
- package/dist/schemas/index.d.ts +2869 -0
- package/dist/schemas/index.js +440 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/services/index.d.ts +3 -0
- package/dist/services/index.js +1696 -0
- package/dist/services/index.js.map +1 -0
- package/dist/types-BSYyX2KJ.d.ts +671 -0
- package/dist/utils/index.d.ts +873 -0
- package/dist/utils/index.js +1046 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +54 -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,440 @@
|
|
|
1
|
+
import { Schema } from 'mongoose';
|
|
2
|
+
|
|
3
|
+
// src/schemas/index.ts
|
|
4
|
+
|
|
5
|
+
// src/enums.ts
|
|
6
|
+
var EMPLOYMENT_TYPE = {
|
|
7
|
+
FULL_TIME: "full_time",
|
|
8
|
+
PART_TIME: "part_time",
|
|
9
|
+
CONTRACT: "contract",
|
|
10
|
+
INTERN: "intern",
|
|
11
|
+
CONSULTANT: "consultant"
|
|
12
|
+
};
|
|
13
|
+
var EMPLOYMENT_TYPE_VALUES = Object.values(EMPLOYMENT_TYPE);
|
|
14
|
+
var EMPLOYEE_STATUS = {
|
|
15
|
+
ACTIVE: "active",
|
|
16
|
+
ON_LEAVE: "on_leave",
|
|
17
|
+
SUSPENDED: "suspended",
|
|
18
|
+
TERMINATED: "terminated"
|
|
19
|
+
};
|
|
20
|
+
var EMPLOYEE_STATUS_VALUES = Object.values(EMPLOYEE_STATUS);
|
|
21
|
+
var DEPARTMENT = {
|
|
22
|
+
MANAGEMENT: "management",
|
|
23
|
+
TRAINING: "training",
|
|
24
|
+
SALES: "sales",
|
|
25
|
+
OPERATIONS: "operations",
|
|
26
|
+
SUPPORT: "support",
|
|
27
|
+
HR: "hr",
|
|
28
|
+
MAINTENANCE: "maintenance",
|
|
29
|
+
MARKETING: "marketing",
|
|
30
|
+
FINANCE: "finance",
|
|
31
|
+
IT: "it"
|
|
32
|
+
};
|
|
33
|
+
var DEPARTMENT_VALUES = Object.values(DEPARTMENT);
|
|
34
|
+
var PAYMENT_FREQUENCY = {
|
|
35
|
+
MONTHLY: "monthly",
|
|
36
|
+
BI_WEEKLY: "bi_weekly",
|
|
37
|
+
WEEKLY: "weekly",
|
|
38
|
+
HOURLY: "hourly",
|
|
39
|
+
DAILY: "daily"
|
|
40
|
+
};
|
|
41
|
+
var PAYMENT_FREQUENCY_VALUES = Object.values(PAYMENT_FREQUENCY);
|
|
42
|
+
var ALLOWANCE_TYPE = {
|
|
43
|
+
HOUSING: "housing",
|
|
44
|
+
TRANSPORT: "transport",
|
|
45
|
+
MEAL: "meal",
|
|
46
|
+
MOBILE: "mobile",
|
|
47
|
+
MEDICAL: "medical",
|
|
48
|
+
EDUCATION: "education",
|
|
49
|
+
BONUS: "bonus",
|
|
50
|
+
OTHER: "other"
|
|
51
|
+
};
|
|
52
|
+
var ALLOWANCE_TYPE_VALUES = Object.values(ALLOWANCE_TYPE);
|
|
53
|
+
var DEDUCTION_TYPE = {
|
|
54
|
+
TAX: "tax",
|
|
55
|
+
LOAN: "loan",
|
|
56
|
+
ADVANCE: "advance",
|
|
57
|
+
PROVIDENT_FUND: "provident_fund",
|
|
58
|
+
INSURANCE: "insurance",
|
|
59
|
+
ABSENCE: "absence",
|
|
60
|
+
OTHER: "other"
|
|
61
|
+
};
|
|
62
|
+
var DEDUCTION_TYPE_VALUES = Object.values(DEDUCTION_TYPE);
|
|
63
|
+
var PAYROLL_STATUS = {
|
|
64
|
+
PENDING: "pending",
|
|
65
|
+
PROCESSING: "processing",
|
|
66
|
+
PAID: "paid",
|
|
67
|
+
FAILED: "failed",
|
|
68
|
+
CANCELLED: "cancelled"
|
|
69
|
+
};
|
|
70
|
+
var PAYROLL_STATUS_VALUES = Object.values(PAYROLL_STATUS);
|
|
71
|
+
var TERMINATION_REASON = {
|
|
72
|
+
RESIGNATION: "resignation",
|
|
73
|
+
RETIREMENT: "retirement",
|
|
74
|
+
TERMINATION: "termination",
|
|
75
|
+
CONTRACT_END: "contract_end",
|
|
76
|
+
MUTUAL_AGREEMENT: "mutual_agreement",
|
|
77
|
+
OTHER: "other"
|
|
78
|
+
};
|
|
79
|
+
var TERMINATION_REASON_VALUES = Object.values(TERMINATION_REASON);
|
|
80
|
+
|
|
81
|
+
// src/config.ts
|
|
82
|
+
var HRM_CONFIG = {
|
|
83
|
+
dataRetention: {
|
|
84
|
+
payrollRecordsTTL: 63072e3}};
|
|
85
|
+
var ORG_ROLES = {
|
|
86
|
+
OWNER: {
|
|
87
|
+
key: "owner",
|
|
88
|
+
label: "Owner",
|
|
89
|
+
description: "Full organization access (set by Organization model)"
|
|
90
|
+
},
|
|
91
|
+
MANAGER: {
|
|
92
|
+
key: "manager",
|
|
93
|
+
label: "Manager",
|
|
94
|
+
description: "Management and administrative features"
|
|
95
|
+
},
|
|
96
|
+
TRAINER: {
|
|
97
|
+
key: "trainer",
|
|
98
|
+
label: "Trainer",
|
|
99
|
+
description: "Training and coaching features"
|
|
100
|
+
},
|
|
101
|
+
STAFF: {
|
|
102
|
+
key: "staff",
|
|
103
|
+
label: "Staff",
|
|
104
|
+
description: "General staff access to basic features"
|
|
105
|
+
},
|
|
106
|
+
INTERN: {
|
|
107
|
+
key: "intern",
|
|
108
|
+
label: "Intern",
|
|
109
|
+
description: "Limited access for interns"
|
|
110
|
+
},
|
|
111
|
+
CONSULTANT: {
|
|
112
|
+
key: "consultant",
|
|
113
|
+
label: "Consultant",
|
|
114
|
+
description: "Project-based consultant access"
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
Object.values(ORG_ROLES).map((role) => role.key);
|
|
118
|
+
|
|
119
|
+
// src/schemas/index.ts
|
|
120
|
+
var allowanceSchema = new Schema(
|
|
121
|
+
{
|
|
122
|
+
type: {
|
|
123
|
+
type: String,
|
|
124
|
+
enum: ALLOWANCE_TYPE_VALUES,
|
|
125
|
+
required: true
|
|
126
|
+
},
|
|
127
|
+
name: { type: String },
|
|
128
|
+
amount: { type: Number, required: true, min: 0 },
|
|
129
|
+
isPercentage: { type: Boolean, default: false },
|
|
130
|
+
value: { type: Number },
|
|
131
|
+
taxable: { type: Boolean, default: true },
|
|
132
|
+
recurring: { type: Boolean, default: true },
|
|
133
|
+
effectiveFrom: { type: Date, default: () => /* @__PURE__ */ new Date() },
|
|
134
|
+
effectiveTo: { type: Date }
|
|
135
|
+
},
|
|
136
|
+
{ _id: false }
|
|
137
|
+
);
|
|
138
|
+
var deductionSchema = new Schema(
|
|
139
|
+
{
|
|
140
|
+
type: {
|
|
141
|
+
type: String,
|
|
142
|
+
enum: DEDUCTION_TYPE_VALUES,
|
|
143
|
+
required: true
|
|
144
|
+
},
|
|
145
|
+
name: { type: String },
|
|
146
|
+
amount: { type: Number, required: true, min: 0 },
|
|
147
|
+
isPercentage: { type: Boolean, default: false },
|
|
148
|
+
value: { type: Number },
|
|
149
|
+
auto: { type: Boolean, default: false },
|
|
150
|
+
recurring: { type: Boolean, default: true },
|
|
151
|
+
effectiveFrom: { type: Date, default: () => /* @__PURE__ */ new Date() },
|
|
152
|
+
effectiveTo: { type: Date },
|
|
153
|
+
description: { type: String }
|
|
154
|
+
},
|
|
155
|
+
{ _id: false }
|
|
156
|
+
);
|
|
157
|
+
var compensationSchema = new Schema(
|
|
158
|
+
{
|
|
159
|
+
baseAmount: { type: Number, required: true, min: 0 },
|
|
160
|
+
frequency: {
|
|
161
|
+
type: String,
|
|
162
|
+
enum: PAYMENT_FREQUENCY_VALUES,
|
|
163
|
+
default: "monthly"
|
|
164
|
+
},
|
|
165
|
+
currency: { type: String, default: "BDT" },
|
|
166
|
+
allowances: [allowanceSchema],
|
|
167
|
+
deductions: [deductionSchema],
|
|
168
|
+
grossSalary: { type: Number, default: 0 },
|
|
169
|
+
netSalary: { type: Number, default: 0 },
|
|
170
|
+
effectiveFrom: { type: Date, default: () => /* @__PURE__ */ new Date() },
|
|
171
|
+
lastModified: { type: Date, default: () => /* @__PURE__ */ new Date() }
|
|
172
|
+
},
|
|
173
|
+
{ _id: false }
|
|
174
|
+
);
|
|
175
|
+
var workScheduleSchema = new Schema(
|
|
176
|
+
{
|
|
177
|
+
hoursPerWeek: { type: Number, min: 0, max: 168 },
|
|
178
|
+
hoursPerDay: { type: Number, min: 0, max: 24 },
|
|
179
|
+
workingDays: [{ type: Number, min: 0, max: 6 }],
|
|
180
|
+
shiftStart: { type: String },
|
|
181
|
+
shiftEnd: { type: String }
|
|
182
|
+
},
|
|
183
|
+
{ _id: false }
|
|
184
|
+
);
|
|
185
|
+
var bankDetailsSchema = new Schema(
|
|
186
|
+
{
|
|
187
|
+
accountName: { type: String },
|
|
188
|
+
accountNumber: { type: String },
|
|
189
|
+
bankName: { type: String },
|
|
190
|
+
branchName: { type: String },
|
|
191
|
+
routingNumber: { type: String }
|
|
192
|
+
},
|
|
193
|
+
{ _id: false }
|
|
194
|
+
);
|
|
195
|
+
var employmentHistorySchema = new Schema(
|
|
196
|
+
{
|
|
197
|
+
hireDate: { type: Date, required: true },
|
|
198
|
+
terminationDate: { type: Date, required: true },
|
|
199
|
+
reason: { type: String, enum: TERMINATION_REASON_VALUES },
|
|
200
|
+
finalSalary: { type: Number },
|
|
201
|
+
position: { type: String },
|
|
202
|
+
department: { type: String },
|
|
203
|
+
notes: { type: String }
|
|
204
|
+
},
|
|
205
|
+
{ timestamps: true }
|
|
206
|
+
);
|
|
207
|
+
var payrollStatsSchema = new Schema(
|
|
208
|
+
{
|
|
209
|
+
totalPaid: { type: Number, default: 0, min: 0 },
|
|
210
|
+
lastPaymentDate: { type: Date },
|
|
211
|
+
nextPaymentDate: { type: Date },
|
|
212
|
+
paymentsThisYear: { type: Number, default: 0, min: 0 },
|
|
213
|
+
averageMonthly: { type: Number, default: 0, min: 0 },
|
|
214
|
+
updatedAt: { type: Date, default: () => /* @__PURE__ */ new Date() }
|
|
215
|
+
},
|
|
216
|
+
{ _id: false }
|
|
217
|
+
);
|
|
218
|
+
var employmentFields = {
|
|
219
|
+
userId: {
|
|
220
|
+
type: Schema.Types.ObjectId,
|
|
221
|
+
ref: "User",
|
|
222
|
+
required: true
|
|
223
|
+
},
|
|
224
|
+
organizationId: {
|
|
225
|
+
type: Schema.Types.ObjectId,
|
|
226
|
+
ref: "Organization",
|
|
227
|
+
required: true
|
|
228
|
+
},
|
|
229
|
+
employeeId: { type: String, required: true },
|
|
230
|
+
employmentType: {
|
|
231
|
+
type: String,
|
|
232
|
+
enum: EMPLOYMENT_TYPE_VALUES,
|
|
233
|
+
default: "full_time"
|
|
234
|
+
},
|
|
235
|
+
status: {
|
|
236
|
+
type: String,
|
|
237
|
+
enum: EMPLOYEE_STATUS_VALUES,
|
|
238
|
+
default: "active"
|
|
239
|
+
},
|
|
240
|
+
department: { type: String, enum: DEPARTMENT_VALUES },
|
|
241
|
+
position: { type: String, required: true },
|
|
242
|
+
hireDate: { type: Date, required: true },
|
|
243
|
+
terminationDate: { type: Date },
|
|
244
|
+
probationEndDate: { type: Date },
|
|
245
|
+
employmentHistory: [employmentHistorySchema],
|
|
246
|
+
compensation: { type: compensationSchema, required: true },
|
|
247
|
+
workSchedule: workScheduleSchema,
|
|
248
|
+
bankDetails: bankDetailsSchema,
|
|
249
|
+
payrollStats: { type: payrollStatsSchema, default: () => ({}) }
|
|
250
|
+
};
|
|
251
|
+
var payrollBreakdownSchema = new Schema(
|
|
252
|
+
{
|
|
253
|
+
baseAmount: { type: Number, required: true, min: 0 },
|
|
254
|
+
allowances: [
|
|
255
|
+
{
|
|
256
|
+
type: { type: String },
|
|
257
|
+
amount: { type: Number, min: 0 },
|
|
258
|
+
taxable: { type: Boolean, default: true }
|
|
259
|
+
}
|
|
260
|
+
],
|
|
261
|
+
deductions: [
|
|
262
|
+
{
|
|
263
|
+
type: { type: String },
|
|
264
|
+
amount: { type: Number, min: 0 },
|
|
265
|
+
description: { type: String }
|
|
266
|
+
}
|
|
267
|
+
],
|
|
268
|
+
grossSalary: { type: Number, required: true, min: 0 },
|
|
269
|
+
netSalary: { type: Number, required: true, min: 0 },
|
|
270
|
+
workingDays: { type: Number, min: 0 },
|
|
271
|
+
actualDays: { type: Number, min: 0 },
|
|
272
|
+
proRatedAmount: { type: Number, default: 0, min: 0 },
|
|
273
|
+
attendanceDeduction: { type: Number, default: 0, min: 0 },
|
|
274
|
+
overtimeAmount: { type: Number, default: 0, min: 0 },
|
|
275
|
+
bonusAmount: { type: Number, default: 0, min: 0 }
|
|
276
|
+
},
|
|
277
|
+
{ _id: false }
|
|
278
|
+
);
|
|
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
|
+
var payrollRecordFields = {
|
|
290
|
+
organizationId: {
|
|
291
|
+
type: Schema.Types.ObjectId,
|
|
292
|
+
ref: "Organization",
|
|
293
|
+
required: true,
|
|
294
|
+
index: true
|
|
295
|
+
},
|
|
296
|
+
employeeId: {
|
|
297
|
+
type: Schema.Types.ObjectId,
|
|
298
|
+
required: true,
|
|
299
|
+
index: true
|
|
300
|
+
},
|
|
301
|
+
userId: {
|
|
302
|
+
type: Schema.Types.ObjectId,
|
|
303
|
+
ref: "User",
|
|
304
|
+
index: true
|
|
305
|
+
},
|
|
306
|
+
period: { type: periodSchema, required: true },
|
|
307
|
+
breakdown: { type: payrollBreakdownSchema, required: true },
|
|
308
|
+
transactionId: { type: Schema.Types.ObjectId, ref: "Transaction" },
|
|
309
|
+
status: {
|
|
310
|
+
type: String,
|
|
311
|
+
enum: PAYROLL_STATUS_VALUES,
|
|
312
|
+
default: "pending",
|
|
313
|
+
index: true
|
|
314
|
+
},
|
|
315
|
+
paidAt: { type: Date },
|
|
316
|
+
paymentMethod: { type: String },
|
|
317
|
+
processedBy: { type: Schema.Types.ObjectId, ref: "User" },
|
|
318
|
+
notes: { type: String },
|
|
319
|
+
payslipUrl: { type: String },
|
|
320
|
+
exported: { type: Boolean, default: false },
|
|
321
|
+
exportedAt: { type: Date }
|
|
322
|
+
};
|
|
323
|
+
var employeeIndexes = [
|
|
324
|
+
{ fields: { organizationId: 1, employeeId: 1 }, options: { unique: true } },
|
|
325
|
+
{ fields: { userId: 1, organizationId: 1 }, options: { unique: true } },
|
|
326
|
+
{ fields: { organizationId: 1, status: 1 } },
|
|
327
|
+
{ fields: { organizationId: 1, department: 1 } },
|
|
328
|
+
{ fields: { organizationId: 1, "compensation.netSalary": -1 } }
|
|
329
|
+
];
|
|
330
|
+
var payrollRecordIndexes = [
|
|
331
|
+
{
|
|
332
|
+
fields: { organizationId: 1, employeeId: 1, "period.month": 1, "period.year": 1 },
|
|
333
|
+
options: { unique: true }
|
|
334
|
+
},
|
|
335
|
+
{ fields: { organizationId: 1, "period.year": 1, "period.month": 1 } },
|
|
336
|
+
{ fields: { employeeId: 1, "period.year": -1, "period.month": -1 } },
|
|
337
|
+
{ fields: { status: 1, createdAt: -1 } },
|
|
338
|
+
{ fields: { organizationId: 1, status: 1, "period.payDate": 1 } },
|
|
339
|
+
{
|
|
340
|
+
fields: { createdAt: 1 },
|
|
341
|
+
options: {
|
|
342
|
+
expireAfterSeconds: HRM_CONFIG.dataRetention.payrollRecordsTTL,
|
|
343
|
+
partialFilterExpression: { exported: true }
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
];
|
|
347
|
+
function applyEmployeeIndexes(schema) {
|
|
348
|
+
for (const { fields, options } of employeeIndexes) {
|
|
349
|
+
schema.index(fields, options);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
function applyPayrollRecordIndexes(schema) {
|
|
353
|
+
for (const { fields, options } of payrollRecordIndexes) {
|
|
354
|
+
schema.index(fields, options);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
function createEmployeeSchema(additionalFields = {}) {
|
|
358
|
+
const schema = new Schema(
|
|
359
|
+
{
|
|
360
|
+
...employmentFields,
|
|
361
|
+
...additionalFields
|
|
362
|
+
},
|
|
363
|
+
{ timestamps: true }
|
|
364
|
+
);
|
|
365
|
+
applyEmployeeIndexes(schema);
|
|
366
|
+
return schema;
|
|
367
|
+
}
|
|
368
|
+
function createPayrollRecordSchema(additionalFields = {}) {
|
|
369
|
+
const schema = new Schema(
|
|
370
|
+
{
|
|
371
|
+
...payrollRecordFields,
|
|
372
|
+
...additionalFields
|
|
373
|
+
},
|
|
374
|
+
{ timestamps: true }
|
|
375
|
+
);
|
|
376
|
+
applyPayrollRecordIndexes(schema);
|
|
377
|
+
schema.virtual("totalAmount").get(function() {
|
|
378
|
+
return this.breakdown?.netSalary || 0;
|
|
379
|
+
});
|
|
380
|
+
schema.virtual("isPaid").get(function() {
|
|
381
|
+
return this.status === "paid";
|
|
382
|
+
});
|
|
383
|
+
schema.virtual("periodLabel").get(function() {
|
|
384
|
+
const months = [
|
|
385
|
+
"Jan",
|
|
386
|
+
"Feb",
|
|
387
|
+
"Mar",
|
|
388
|
+
"Apr",
|
|
389
|
+
"May",
|
|
390
|
+
"Jun",
|
|
391
|
+
"Jul",
|
|
392
|
+
"Aug",
|
|
393
|
+
"Sep",
|
|
394
|
+
"Oct",
|
|
395
|
+
"Nov",
|
|
396
|
+
"Dec"
|
|
397
|
+
];
|
|
398
|
+
return `${months[this.period.month - 1]} ${this.period.year}`;
|
|
399
|
+
});
|
|
400
|
+
schema.methods.markAsPaid = function(transactionId, paidAt = /* @__PURE__ */ new Date()) {
|
|
401
|
+
this.status = "paid";
|
|
402
|
+
this.transactionId = transactionId;
|
|
403
|
+
this.paidAt = paidAt;
|
|
404
|
+
};
|
|
405
|
+
schema.methods.markAsExported = function() {
|
|
406
|
+
this.exported = true;
|
|
407
|
+
this.exportedAt = /* @__PURE__ */ new Date();
|
|
408
|
+
};
|
|
409
|
+
schema.methods.canBeDeleted = function() {
|
|
410
|
+
return this.exported && this.status === "paid";
|
|
411
|
+
};
|
|
412
|
+
return schema;
|
|
413
|
+
}
|
|
414
|
+
var schemas_default = {
|
|
415
|
+
// Sub-schemas
|
|
416
|
+
allowanceSchema,
|
|
417
|
+
deductionSchema,
|
|
418
|
+
compensationSchema,
|
|
419
|
+
workScheduleSchema,
|
|
420
|
+
bankDetailsSchema,
|
|
421
|
+
employmentHistorySchema,
|
|
422
|
+
payrollStatsSchema,
|
|
423
|
+
payrollBreakdownSchema,
|
|
424
|
+
periodSchema,
|
|
425
|
+
// Fields
|
|
426
|
+
employmentFields,
|
|
427
|
+
payrollRecordFields,
|
|
428
|
+
// Indexes
|
|
429
|
+
employeeIndexes,
|
|
430
|
+
payrollRecordIndexes,
|
|
431
|
+
applyEmployeeIndexes,
|
|
432
|
+
applyPayrollRecordIndexes,
|
|
433
|
+
// Schema creators
|
|
434
|
+
createEmployeeSchema,
|
|
435
|
+
createPayrollRecordSchema
|
|
436
|
+
};
|
|
437
|
+
|
|
438
|
+
export { allowanceSchema, applyEmployeeIndexes, applyPayrollRecordIndexes, bankDetailsSchema, compensationSchema, createEmployeeSchema, createPayrollRecordSchema, deductionSchema, schemas_default as default, employeeIndexes, employmentFields, employmentHistorySchema, payrollBreakdownSchema, payrollRecordFields, payrollRecordIndexes, payrollStatsSchema, periodSchema, workScheduleSchema };
|
|
439
|
+
//# sourceMappingURL=index.js.map
|
|
440
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/enums.ts","../../src/config.ts","../../src/schemas/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * @classytic/payroll - Enums\r\n *\r\n * Type-safe enum definitions with const assertions\r\n * Single source of truth for all enum values\r\n */\r\n\r\nimport type {\r\n EmploymentType,\r\n EmployeeStatus,\r\n Department,\r\n PaymentFrequency,\r\n PaymentMethod,\r\n AllowanceType,\r\n DeductionType,\r\n PayrollStatus,\r\n TerminationReason,\r\n HRMTransactionCategory,\r\n SalaryBand,\r\n OrgRole,\r\n} from './types.js';\r\n\r\n// ============================================================================\r\n// Employment Type\r\n// ============================================================================\r\n\r\nexport const EMPLOYMENT_TYPE = {\r\n FULL_TIME: 'full_time',\r\n PART_TIME: 'part_time',\r\n CONTRACT: 'contract',\r\n INTERN: 'intern',\r\n CONSULTANT: 'consultant',\r\n} as const satisfies Record<string, EmploymentType>;\r\n\r\nexport const EMPLOYMENT_TYPE_VALUES = Object.values(EMPLOYMENT_TYPE);\r\n\r\nexport function isValidEmploymentType(value: string): value is EmploymentType {\r\n return EMPLOYMENT_TYPE_VALUES.includes(value as EmploymentType);\r\n}\r\n\r\n// ============================================================================\r\n// Employee Status\r\n// ============================================================================\r\n\r\nexport const EMPLOYEE_STATUS = {\r\n ACTIVE: 'active',\r\n ON_LEAVE: 'on_leave',\r\n SUSPENDED: 'suspended',\r\n TERMINATED: 'terminated',\r\n} as const satisfies Record<string, EmployeeStatus>;\r\n\r\nexport const EMPLOYEE_STATUS_VALUES = Object.values(EMPLOYEE_STATUS);\r\n\r\nexport function isValidEmployeeStatus(value: string): value is EmployeeStatus {\r\n return EMPLOYEE_STATUS_VALUES.includes(value as EmployeeStatus);\r\n}\r\n\r\nexport function isActiveStatus(status: EmployeeStatus): boolean {\r\n return status === EMPLOYEE_STATUS.ACTIVE;\r\n}\r\n\r\nexport function isEmployedStatus(status: EmployeeStatus): boolean {\r\n return status !== EMPLOYEE_STATUS.TERMINATED;\r\n}\r\n\r\nexport function canReceiveSalaryStatus(status: EmployeeStatus): boolean {\r\n return status === EMPLOYEE_STATUS.ACTIVE || status === EMPLOYEE_STATUS.ON_LEAVE;\r\n}\r\n\r\n// ============================================================================\r\n// Department\r\n// ============================================================================\r\n\r\nexport const DEPARTMENT = {\r\n MANAGEMENT: 'management',\r\n TRAINING: 'training',\r\n SALES: 'sales',\r\n OPERATIONS: 'operations',\r\n SUPPORT: 'support',\r\n HR: 'hr',\r\n MAINTENANCE: 'maintenance',\r\n MARKETING: 'marketing',\r\n FINANCE: 'finance',\r\n IT: 'it',\r\n} as const satisfies Record<string, Department>;\r\n\r\nexport const DEPARTMENT_VALUES = Object.values(DEPARTMENT);\r\n\r\nexport function isValidDepartment(value: string): value is Department {\r\n return DEPARTMENT_VALUES.includes(value as Department);\r\n}\r\n\r\n// ============================================================================\r\n// Payment Frequency\r\n// ============================================================================\r\n\r\nexport const PAYMENT_FREQUENCY = {\r\n MONTHLY: 'monthly',\r\n BI_WEEKLY: 'bi_weekly',\r\n WEEKLY: 'weekly',\r\n HOURLY: 'hourly',\r\n DAILY: 'daily',\r\n} as const satisfies Record<string, PaymentFrequency>;\r\n\r\nexport const PAYMENT_FREQUENCY_VALUES = Object.values(PAYMENT_FREQUENCY);\r\n\r\nexport function isValidPaymentFrequency(value: string): value is PaymentFrequency {\r\n return PAYMENT_FREQUENCY_VALUES.includes(value as PaymentFrequency);\r\n}\r\n\r\n// ============================================================================\r\n// Payment Method\r\n// ============================================================================\r\n\r\nexport const PAYMENT_METHOD = {\r\n BANK: 'bank',\r\n CASH: 'cash',\r\n MOBILE: 'mobile',\r\n BKASH: 'bkash',\r\n NAGAD: 'nagad',\r\n ROCKET: 'rocket',\r\n CHECK: 'check',\r\n} as const satisfies Record<string, PaymentMethod>;\r\n\r\nexport const PAYMENT_METHOD_VALUES = Object.values(PAYMENT_METHOD);\r\n\r\nexport function isValidPaymentMethod(value: string): value is PaymentMethod {\r\n return PAYMENT_METHOD_VALUES.includes(value as PaymentMethod);\r\n}\r\n\r\n// ============================================================================\r\n// Allowance Type\r\n// ============================================================================\r\n\r\nexport const ALLOWANCE_TYPE = {\r\n HOUSING: 'housing',\r\n TRANSPORT: 'transport',\r\n MEAL: 'meal',\r\n MOBILE: 'mobile',\r\n MEDICAL: 'medical',\r\n EDUCATION: 'education',\r\n BONUS: 'bonus',\r\n OTHER: 'other',\r\n} as const satisfies Record<string, AllowanceType>;\r\n\r\nexport const ALLOWANCE_TYPE_VALUES = Object.values(ALLOWANCE_TYPE);\r\n\r\nexport function isValidAllowanceType(value: string): value is AllowanceType {\r\n return ALLOWANCE_TYPE_VALUES.includes(value as AllowanceType);\r\n}\r\n\r\n// ============================================================================\r\n// Deduction Type\r\n// ============================================================================\r\n\r\nexport const DEDUCTION_TYPE = {\r\n TAX: 'tax',\r\n LOAN: 'loan',\r\n ADVANCE: 'advance',\r\n PROVIDENT_FUND: 'provident_fund',\r\n INSURANCE: 'insurance',\r\n ABSENCE: 'absence',\r\n OTHER: 'other',\r\n} as const satisfies Record<string, DeductionType>;\r\n\r\nexport const DEDUCTION_TYPE_VALUES = Object.values(DEDUCTION_TYPE);\r\n\r\nexport function isValidDeductionType(value: string): value is DeductionType {\r\n return DEDUCTION_TYPE_VALUES.includes(value as DeductionType);\r\n}\r\n\r\n// ============================================================================\r\n// Payroll Status\r\n// ============================================================================\r\n\r\nexport const PAYROLL_STATUS = {\r\n PENDING: 'pending',\r\n PROCESSING: 'processing',\r\n PAID: 'paid',\r\n FAILED: 'failed',\r\n CANCELLED: 'cancelled',\r\n} as const satisfies Record<string, PayrollStatus>;\r\n\r\nexport const PAYROLL_STATUS_VALUES = Object.values(PAYROLL_STATUS);\r\n\r\nexport function isValidPayrollStatus(value: string): value is PayrollStatus {\r\n return PAYROLL_STATUS_VALUES.includes(value as PayrollStatus);\r\n}\r\n\r\nexport function isCompletedPayrollStatus(status: PayrollStatus): boolean {\r\n return status === PAYROLL_STATUS.PAID;\r\n}\r\n\r\nexport function isPendingPayrollStatus(status: PayrollStatus): boolean {\r\n return status === PAYROLL_STATUS.PENDING || status === PAYROLL_STATUS.PROCESSING;\r\n}\r\n\r\n// ============================================================================\r\n// Termination Reason\r\n// ============================================================================\r\n\r\nexport const TERMINATION_REASON = {\r\n RESIGNATION: 'resignation',\r\n RETIREMENT: 'retirement',\r\n TERMINATION: 'termination',\r\n CONTRACT_END: 'contract_end',\r\n MUTUAL_AGREEMENT: 'mutual_agreement',\r\n OTHER: 'other',\r\n} as const satisfies Record<string, TerminationReason>;\r\n\r\nexport const TERMINATION_REASON_VALUES = Object.values(TERMINATION_REASON);\r\n\r\nexport function isValidTerminationReason(value: string): value is TerminationReason {\r\n return TERMINATION_REASON_VALUES.includes(value as TerminationReason);\r\n}\r\n\r\n// ============================================================================\r\n// HRM Transaction Categories\r\n// ============================================================================\r\n\r\nexport const HRM_TRANSACTION_CATEGORIES = {\r\n SALARY: 'salary',\r\n BONUS: 'bonus',\r\n COMMISSION: 'commission',\r\n OVERTIME: 'overtime',\r\n SEVERANCE: 'severance',\r\n} as const satisfies Record<string, HRMTransactionCategory>;\r\n\r\nexport const HRM_CATEGORY_VALUES = Object.values(HRM_TRANSACTION_CATEGORIES);\r\n\r\nexport function isHRMManagedCategory(category: string): category is HRMTransactionCategory {\r\n return HRM_CATEGORY_VALUES.includes(category as HRMTransactionCategory);\r\n}\r\n\r\n// ============================================================================\r\n// Salary Band\r\n// ============================================================================\r\n\r\nexport const SALARY_BAND = {\r\n INTERN: 'intern',\r\n JUNIOR: 'junior',\r\n MID: 'mid',\r\n SENIOR: 'senior',\r\n LEAD: 'lead',\r\n EXECUTIVE: 'executive',\r\n CUSTOM: 'custom',\r\n} as const satisfies Record<string, SalaryBand>;\r\n\r\nexport const SALARY_BAND_VALUES = Object.values(SALARY_BAND);\r\n\r\nexport function isValidSalaryBand(value: string): value is SalaryBand {\r\n return SALARY_BAND_VALUES.includes(value as SalaryBand);\r\n}\r\n\r\n// ============================================================================\r\n// Organization Role\r\n// ============================================================================\r\n\r\nexport const ORG_ROLE = {\r\n OWNER: 'owner',\r\n MANAGER: 'manager',\r\n TRAINER: 'trainer',\r\n STAFF: 'staff',\r\n INTERN: 'intern',\r\n CONSULTANT: 'consultant',\r\n} as const satisfies Record<string, OrgRole>;\r\n\r\nexport const ORG_ROLE_VALUES = Object.values(ORG_ROLE);\r\n\r\nexport function isValidOrgRole(value: string): value is OrgRole {\r\n return ORG_ROLE_VALUES.includes(value as OrgRole);\r\n}\r\n\r\n// ============================================================================\r\n// Default Export\r\n// ============================================================================\r\n\r\nexport default {\r\n EMPLOYMENT_TYPE,\r\n EMPLOYMENT_TYPE_VALUES,\r\n EMPLOYEE_STATUS,\r\n EMPLOYEE_STATUS_VALUES,\r\n DEPARTMENT,\r\n DEPARTMENT_VALUES,\r\n PAYMENT_FREQUENCY,\r\n PAYMENT_FREQUENCY_VALUES,\r\n PAYMENT_METHOD,\r\n PAYMENT_METHOD_VALUES,\r\n ALLOWANCE_TYPE,\r\n ALLOWANCE_TYPE_VALUES,\r\n DEDUCTION_TYPE,\r\n DEDUCTION_TYPE_VALUES,\r\n PAYROLL_STATUS,\r\n PAYROLL_STATUS_VALUES,\r\n TERMINATION_REASON,\r\n TERMINATION_REASON_VALUES,\r\n HRM_TRANSACTION_CATEGORIES,\r\n HRM_CATEGORY_VALUES,\r\n SALARY_BAND,\r\n SALARY_BAND_VALUES,\r\n ORG_ROLE,\r\n ORG_ROLE_VALUES,\r\n};\r\n\r\n","/**\r\n * @classytic/payroll - Configuration\r\n *\r\n * Centralized configuration with type safety\r\n * Configurable defaults for different use cases\r\n */\r\n\r\nimport type {\r\n HRMConfig,\r\n TaxBracket,\r\n SalaryBandRange,\r\n RoleMappingConfig,\r\n OrgRole,\r\n SalaryBand,\r\n Department,\r\n EmploymentType,\r\n PaymentFrequency,\r\n DeepPartial,\r\n} from './types.js';\r\n\r\n// ============================================================================\r\n// Default Configuration\r\n// ============================================================================\r\n\r\nexport const HRM_CONFIG: HRMConfig = {\r\n dataRetention: {\r\n payrollRecordsTTL: 63072000, // 2 years in seconds\r\n exportWarningDays: 30,\r\n archiveBeforeDeletion: true,\r\n },\r\n\r\n payroll: {\r\n defaultCurrency: 'BDT',\r\n allowProRating: true,\r\n attendanceIntegration: true,\r\n autoDeductions: true,\r\n overtimeEnabled: false,\r\n overtimeMultiplier: 1.5,\r\n },\r\n\r\n salary: {\r\n minimumWage: 0,\r\n maximumAllowances: 10,\r\n maximumDeductions: 10,\r\n defaultFrequency: 'monthly',\r\n },\r\n\r\n employment: {\r\n defaultProbationMonths: 3,\r\n maxProbationMonths: 6,\r\n allowReHiring: true,\r\n trackEmploymentHistory: true,\r\n },\r\n\r\n validation: {\r\n requireBankDetails: false,\r\n requireEmployeeId: true,\r\n uniqueEmployeeIdPerOrg: true,\r\n allowMultiTenantEmployees: true,\r\n },\r\n};\r\n\r\n// ============================================================================\r\n// Salary Bands Configuration\r\n// ============================================================================\r\n\r\nexport const SALARY_BANDS: Record<Exclude<SalaryBand, 'custom'>, SalaryBandRange> = {\r\n intern: { min: 10000, max: 20000 },\r\n junior: { min: 20000, max: 40000 },\r\n mid: { min: 40000, max: 70000 },\r\n senior: { min: 70000, max: 120000 },\r\n lead: { min: 100000, max: 200000 },\r\n executive: { min: 150000, max: 500000 },\r\n};\r\n\r\n// ============================================================================\r\n// Tax Brackets Configuration\r\n// ============================================================================\r\n\r\nexport const TAX_BRACKETS: Record<string, TaxBracket[]> = {\r\n BDT: [\r\n { min: 0, max: 300000, rate: 0 },\r\n { min: 300000, max: 400000, rate: 0.05 },\r\n { min: 400000, max: 500000, rate: 0.10 },\r\n { min: 500000, max: 600000, rate: 0.15 },\r\n { min: 600000, max: 3000000, rate: 0.20 },\r\n { min: 3000000, max: Infinity, rate: 0.25 },\r\n ],\r\n USD: [\r\n { min: 0, max: 10000, rate: 0.10 },\r\n { min: 10000, max: 40000, rate: 0.12 },\r\n { min: 40000, max: 85000, rate: 0.22 },\r\n { min: 85000, max: 165000, rate: 0.24 },\r\n { min: 165000, max: 215000, rate: 0.32 },\r\n { min: 215000, max: 540000, rate: 0.35 },\r\n { min: 540000, max: Infinity, rate: 0.37 },\r\n ],\r\n};\r\n\r\n// ============================================================================\r\n// Organization Roles Configuration\r\n// ============================================================================\r\n\r\nexport interface OrgRoleDefinition {\r\n key: OrgRole;\r\n label: string;\r\n description: string;\r\n}\r\n\r\nexport const ORG_ROLES: Record<Uppercase<OrgRole>, OrgRoleDefinition> = {\r\n OWNER: {\r\n key: 'owner',\r\n label: 'Owner',\r\n description: 'Full organization access (set by Organization model)',\r\n },\r\n MANAGER: {\r\n key: 'manager',\r\n label: 'Manager',\r\n description: 'Management and administrative features',\r\n },\r\n TRAINER: {\r\n key: 'trainer',\r\n label: 'Trainer',\r\n description: 'Training and coaching features',\r\n },\r\n STAFF: {\r\n key: 'staff',\r\n label: 'Staff',\r\n description: 'General staff access to basic features',\r\n },\r\n INTERN: {\r\n key: 'intern',\r\n label: 'Intern',\r\n description: 'Limited access for interns',\r\n },\r\n CONSULTANT: {\r\n key: 'consultant',\r\n label: 'Consultant',\r\n description: 'Project-based consultant access',\r\n },\r\n};\r\n\r\nexport const ORG_ROLE_KEYS = Object.values(ORG_ROLES).map((role) => role.key);\r\n\r\n// ============================================================================\r\n// Role Mapping Configuration\r\n// ============================================================================\r\n\r\nexport const ROLE_MAPPING: RoleMappingConfig = {\r\n byDepartment: {\r\n management: 'manager',\r\n training: 'trainer',\r\n sales: 'staff',\r\n operations: 'staff',\r\n finance: 'staff',\r\n hr: 'staff',\r\n marketing: 'staff',\r\n it: 'staff',\r\n support: 'staff',\r\n maintenance: 'staff',\r\n },\r\n\r\n byEmploymentType: {\r\n full_time: 'staff',\r\n part_time: 'staff',\r\n contract: 'consultant',\r\n intern: 'intern',\r\n consultant: 'consultant',\r\n },\r\n\r\n default: 'staff',\r\n};\r\n\r\n// ============================================================================\r\n// Configuration Functions\r\n// ============================================================================\r\n\r\n/**\r\n * Calculate tax based on annual income\r\n */\r\nexport function calculateTax(annualIncome: number, currency = 'BDT'): number {\r\n const brackets = TAX_BRACKETS[currency];\r\n if (!brackets) return 0;\r\n\r\n let tax = 0;\r\n for (const bracket of brackets) {\r\n if (annualIncome > bracket.min) {\r\n const taxableAmount = Math.min(annualIncome, bracket.max) - bracket.min;\r\n tax += taxableAmount * bracket.rate;\r\n }\r\n }\r\n return Math.round(tax);\r\n}\r\n\r\n/**\r\n * Get salary band for a given amount\r\n */\r\nexport function getSalaryBand(amount: number): SalaryBand {\r\n for (const [band, range] of Object.entries(SALARY_BANDS)) {\r\n if (amount >= range.min && amount <= range.max) {\r\n return band as SalaryBand;\r\n }\r\n }\r\n return 'custom';\r\n}\r\n\r\n/**\r\n * Determine the appropriate organization role for an employee\r\n */\r\nexport function determineOrgRole(employmentData: {\r\n department?: Department | string;\r\n type?: EmploymentType | string;\r\n position?: string;\r\n}): OrgRole {\r\n const { department, type: employmentType } = employmentData;\r\n\r\n // Priority 1: Department-based mapping\r\n if (department && department in ROLE_MAPPING.byDepartment) {\r\n return ROLE_MAPPING.byDepartment[department as keyof typeof ROLE_MAPPING.byDepartment];\r\n }\r\n\r\n // Priority 2: Employment type mapping\r\n if (employmentType && employmentType in ROLE_MAPPING.byEmploymentType) {\r\n return ROLE_MAPPING.byEmploymentType[employmentType as keyof typeof ROLE_MAPPING.byEmploymentType];\r\n }\r\n\r\n // Priority 3: Default role\r\n return ROLE_MAPPING.default;\r\n}\r\n\r\n/**\r\n * Get pay periods per year based on frequency\r\n */\r\nexport function getPayPeriodsPerYear(frequency: PaymentFrequency): number {\r\n const periodsMap: Record<PaymentFrequency, number> = {\r\n monthly: 12,\r\n bi_weekly: 26,\r\n weekly: 52,\r\n daily: 365,\r\n hourly: 2080, // Assuming 40 hours/week * 52 weeks\r\n };\r\n return periodsMap[frequency];\r\n}\r\n\r\n/**\r\n * Calculate monthly equivalent from any frequency\r\n */\r\nexport function toMonthlyAmount(amount: number, frequency: PaymentFrequency): number {\r\n const periodsPerYear = getPayPeriodsPerYear(frequency);\r\n return Math.round((amount * periodsPerYear) / 12);\r\n}\r\n\r\n/**\r\n * Calculate annual equivalent from any frequency\r\n */\r\nexport function toAnnualAmount(amount: number, frequency: PaymentFrequency): number {\r\n const periodsPerYear = getPayPeriodsPerYear(frequency);\r\n return Math.round(amount * periodsPerYear);\r\n}\r\n\r\n/**\r\n * Merge configuration with defaults\r\n */\r\nexport function mergeConfig(\r\n customConfig: Partial<HRMConfig> | DeepPartial<HRMConfig> | undefined\r\n): HRMConfig {\r\n if (!customConfig) return HRM_CONFIG;\r\n\r\n return {\r\n dataRetention: { ...HRM_CONFIG.dataRetention, ...customConfig.dataRetention },\r\n payroll: { ...HRM_CONFIG.payroll, ...customConfig.payroll },\r\n salary: { ...HRM_CONFIG.salary, ...customConfig.salary },\r\n employment: { ...HRM_CONFIG.employment, ...customConfig.employment },\r\n validation: { ...HRM_CONFIG.validation, ...customConfig.validation },\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// Default Export\r\n// ============================================================================\r\n\r\nexport default {\r\n HRM_CONFIG,\r\n SALARY_BANDS,\r\n TAX_BRACKETS,\r\n ORG_ROLES,\r\n ORG_ROLE_KEYS,\r\n ROLE_MAPPING,\r\n calculateTax,\r\n getSalaryBand,\r\n determineOrgRole,\r\n getPayPeriodsPerYear,\r\n toMonthlyAmount,\r\n toAnnualAmount,\r\n mergeConfig,\r\n};\r\n\r\n","/**\r\n * @classytic/payroll - Mongoose Schemas\r\n *\r\n * Reusable schema definitions for employee and payroll models\r\n * Can be spread into your own schemas\r\n */\r\n\r\nimport mongoose, { Schema, type SchemaDefinition } from 'mongoose';\r\nimport {\r\n EMPLOYMENT_TYPE_VALUES,\r\n EMPLOYEE_STATUS_VALUES,\r\n DEPARTMENT_VALUES,\r\n PAYMENT_FREQUENCY_VALUES,\r\n ALLOWANCE_TYPE_VALUES,\r\n DEDUCTION_TYPE_VALUES,\r\n TERMINATION_REASON_VALUES,\r\n PAYROLL_STATUS_VALUES,\r\n} from '../enums.js';\r\nimport { HRM_CONFIG } from '../config.js';\r\n\r\n// ============================================================================\r\n// Sub-Schemas\r\n// ============================================================================\r\n\r\n/**\r\n * Allowance schema definition\r\n */\r\nexport const allowanceSchema = new Schema(\r\n {\r\n type: {\r\n type: String,\r\n enum: ALLOWANCE_TYPE_VALUES,\r\n required: true,\r\n },\r\n name: { type: String },\r\n amount: { type: Number, required: true, min: 0 },\r\n isPercentage: { type: Boolean, default: false },\r\n value: { type: Number },\r\n taxable: { type: Boolean, default: true },\r\n recurring: { type: Boolean, default: true },\r\n effectiveFrom: { type: Date, default: () => new Date() },\r\n effectiveTo: { type: Date },\r\n },\r\n { _id: false }\r\n);\r\n\r\n/**\r\n * Deduction schema definition\r\n */\r\nexport const deductionSchema = new Schema(\r\n {\r\n type: {\r\n type: String,\r\n enum: DEDUCTION_TYPE_VALUES,\r\n required: true,\r\n },\r\n name: { type: String },\r\n amount: { type: Number, required: true, min: 0 },\r\n isPercentage: { type: Boolean, default: false },\r\n value: { type: Number },\r\n auto: { type: Boolean, default: false },\r\n recurring: { type: Boolean, default: true },\r\n effectiveFrom: { type: Date, default: () => new Date() },\r\n effectiveTo: { type: Date },\r\n description: { type: String },\r\n },\r\n { _id: false }\r\n);\r\n\r\n/**\r\n * Compensation schema definition\r\n */\r\nexport const compensationSchema = new Schema(\r\n {\r\n baseAmount: { type: Number, required: true, min: 0 },\r\n frequency: {\r\n type: String,\r\n enum: PAYMENT_FREQUENCY_VALUES,\r\n default: 'monthly',\r\n },\r\n currency: { type: String, default: 'BDT' },\r\n allowances: [allowanceSchema],\r\n deductions: [deductionSchema],\r\n grossSalary: { type: Number, default: 0 },\r\n netSalary: { type: Number, default: 0 },\r\n effectiveFrom: { type: Date, default: () => new Date() },\r\n lastModified: { type: Date, default: () => new Date() },\r\n },\r\n { _id: false }\r\n);\r\n\r\n/**\r\n * Work schedule schema definition\r\n */\r\nexport const workScheduleSchema = new Schema(\r\n {\r\n hoursPerWeek: { type: Number, min: 0, max: 168 },\r\n hoursPerDay: { type: Number, min: 0, max: 24 },\r\n workingDays: [{ type: Number, min: 0, max: 6 }],\r\n shiftStart: { type: String },\r\n shiftEnd: { type: String },\r\n },\r\n { _id: false }\r\n);\r\n\r\n/**\r\n * Bank details schema definition\r\n */\r\nexport const bankDetailsSchema = new Schema(\r\n {\r\n accountName: { type: String },\r\n accountNumber: { type: String },\r\n bankName: { type: String },\r\n branchName: { type: String },\r\n routingNumber: { type: String },\r\n },\r\n { _id: false }\r\n);\r\n\r\n/**\r\n * Employment history entry schema\r\n */\r\nexport const employmentHistorySchema = new Schema(\r\n {\r\n hireDate: { type: Date, required: true },\r\n terminationDate: { type: Date, required: true },\r\n reason: { type: String, enum: TERMINATION_REASON_VALUES },\r\n finalSalary: { type: Number },\r\n position: { type: String },\r\n department: { type: String },\r\n notes: { type: String },\r\n },\r\n { timestamps: true }\r\n);\r\n\r\n/**\r\n * Payroll stats schema (pre-calculated)\r\n */\r\nexport const payrollStatsSchema = new Schema(\r\n {\r\n totalPaid: { type: Number, default: 0, min: 0 },\r\n lastPaymentDate: { type: Date },\r\n nextPaymentDate: { type: Date },\r\n paymentsThisYear: { type: Number, default: 0, min: 0 },\r\n averageMonthly: { type: Number, default: 0, min: 0 },\r\n updatedAt: { type: Date, default: () => new Date() },\r\n },\r\n { _id: false }\r\n);\r\n\r\n// ============================================================================\r\n// Employment Fields (Spread into Employee Schema)\r\n// ============================================================================\r\n\r\n/**\r\n * Employment fields to spread into your Employee schema\r\n * \r\n * @example\r\n * const employeeSchema = new Schema({\r\n * ...employmentFields,\r\n * // Your custom fields\r\n * certifications: [{ name: String, issuedDate: Date }],\r\n * });\r\n */\r\nexport const employmentFields: SchemaDefinition = {\r\n userId: {\r\n type: Schema.Types.ObjectId,\r\n ref: 'User',\r\n required: true,\r\n },\r\n organizationId: {\r\n type: Schema.Types.ObjectId,\r\n ref: 'Organization',\r\n required: true,\r\n },\r\n employeeId: { type: String, required: true },\r\n employmentType: {\r\n type: String,\r\n enum: EMPLOYMENT_TYPE_VALUES,\r\n default: 'full_time',\r\n },\r\n status: {\r\n type: String,\r\n enum: EMPLOYEE_STATUS_VALUES,\r\n default: 'active',\r\n },\r\n department: { type: String, enum: DEPARTMENT_VALUES },\r\n position: { type: String, required: true },\r\n hireDate: { type: Date, required: true },\r\n terminationDate: { type: Date },\r\n probationEndDate: { type: Date },\r\n employmentHistory: [employmentHistorySchema],\r\n compensation: { type: compensationSchema, required: true },\r\n workSchedule: workScheduleSchema,\r\n bankDetails: bankDetailsSchema,\r\n payrollStats: { type: payrollStatsSchema, default: () => ({}) },\r\n};\r\n\r\n// ============================================================================\r\n// Payroll Record Sub-Schemas\r\n// ============================================================================\r\n\r\n/**\r\n * Payroll breakdown schema\r\n */\r\nexport const payrollBreakdownSchema = new Schema(\r\n {\r\n baseAmount: { type: Number, required: true, min: 0 },\r\n allowances: [\r\n {\r\n type: { type: String },\r\n amount: { type: Number, min: 0 },\r\n taxable: { type: Boolean, default: true },\r\n },\r\n ],\r\n deductions: [\r\n {\r\n type: { type: String },\r\n amount: { type: Number, min: 0 },\r\n description: { type: String },\r\n },\r\n ],\r\n grossSalary: { type: Number, required: true, min: 0 },\r\n netSalary: { type: Number, required: true, min: 0 },\r\n workingDays: { type: Number, min: 0 },\r\n actualDays: { type: Number, min: 0 },\r\n proRatedAmount: { type: Number, default: 0, min: 0 },\r\n attendanceDeduction: { type: Number, default: 0, min: 0 },\r\n overtimeAmount: { type: Number, default: 0, min: 0 },\r\n bonusAmount: { type: Number, default: 0, min: 0 },\r\n },\r\n { _id: false }\r\n);\r\n\r\n/**\r\n * Payroll period schema\r\n */\r\nexport const periodSchema = new Schema(\r\n {\r\n month: { type: Number, required: true, min: 1, max: 12 },\r\n year: { type: Number, required: true, min: 2020 },\r\n startDate: { type: Date, required: true },\r\n endDate: { type: Date, required: true },\r\n payDate: { type: Date, required: true },\r\n },\r\n { _id: false }\r\n);\r\n\r\n/**\r\n * Payroll record fields to spread into PayrollRecord schema\r\n */\r\nexport const payrollRecordFields: SchemaDefinition = {\r\n organizationId: {\r\n type: Schema.Types.ObjectId,\r\n ref: 'Organization',\r\n required: true,\r\n index: true,\r\n },\r\n employeeId: {\r\n type: Schema.Types.ObjectId,\r\n required: true,\r\n index: true,\r\n },\r\n userId: {\r\n type: Schema.Types.ObjectId,\r\n ref: 'User',\r\n index: true,\r\n },\r\n period: { type: periodSchema, required: true },\r\n breakdown: { type: payrollBreakdownSchema, required: true },\r\n transactionId: { type: Schema.Types.ObjectId, ref: 'Transaction' },\r\n status: {\r\n type: String,\r\n enum: PAYROLL_STATUS_VALUES,\r\n default: 'pending',\r\n index: true,\r\n },\r\n paidAt: { type: Date },\r\n paymentMethod: { type: String },\r\n processedBy: { type: Schema.Types.ObjectId, ref: 'User' },\r\n notes: { type: String },\r\n payslipUrl: { type: String },\r\n exported: { type: Boolean, default: false },\r\n exportedAt: { type: Date },\r\n};\r\n\r\n// ============================================================================\r\n// Index Definitions\r\n// ============================================================================\r\n\r\n/**\r\n * Recommended indexes for Employee schema\r\n */\r\nexport const employeeIndexes = [\r\n { fields: { organizationId: 1, employeeId: 1 }, options: { unique: true } },\r\n { fields: { userId: 1, organizationId: 1 }, options: { unique: true } },\r\n { fields: { organizationId: 1, status: 1 } },\r\n { fields: { organizationId: 1, department: 1 } },\r\n { fields: { organizationId: 1, 'compensation.netSalary': -1 } },\r\n];\r\n\r\n/**\r\n * Recommended indexes for PayrollRecord schema\r\n */\r\nexport const payrollRecordIndexes = [\r\n {\r\n fields: { organizationId: 1, employeeId: 1, 'period.month': 1, 'period.year': 1 },\r\n options: { unique: true },\r\n },\r\n { fields: { organizationId: 1, 'period.year': 1, 'period.month': 1 } },\r\n { fields: { employeeId: 1, 'period.year': -1, 'period.month': -1 } },\r\n { fields: { status: 1, createdAt: -1 } },\r\n { fields: { organizationId: 1, status: 1, 'period.payDate': 1 } },\r\n {\r\n fields: { createdAt: 1 },\r\n options: {\r\n expireAfterSeconds: HRM_CONFIG.dataRetention.payrollRecordsTTL,\r\n partialFilterExpression: { exported: true },\r\n },\r\n },\r\n];\r\n\r\n/**\r\n * Apply indexes to schema\r\n */\r\nexport function applyEmployeeIndexes(schema: Schema): void {\r\n for (const { fields, options } of employeeIndexes) {\r\n schema.index(fields as unknown as Record<string, 1 | -1>, options);\r\n }\r\n}\r\n\r\n/**\r\n * Apply payroll record indexes to schema\r\n */\r\nexport function applyPayrollRecordIndexes(schema: Schema): void {\r\n for (const { fields, options } of payrollRecordIndexes) {\r\n schema.index(fields as unknown as Record<string, 1 | -1>, options);\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// Complete Schema Creators\r\n// ============================================================================\r\n\r\n/**\r\n * Create a complete Employee schema with all HRM fields\r\n */\r\nexport function createEmployeeSchema(\r\n additionalFields: SchemaDefinition = {}\r\n): Schema {\r\n const schema = new Schema(\r\n {\r\n ...employmentFields,\r\n ...additionalFields,\r\n },\r\n { timestamps: true }\r\n );\r\n\r\n applyEmployeeIndexes(schema);\r\n return schema;\r\n}\r\n\r\n/**\r\n * Create a complete PayrollRecord schema\r\n */\r\nexport function createPayrollRecordSchema(\r\n additionalFields: SchemaDefinition = {}\r\n): Schema {\r\n const schema = new Schema(\r\n {\r\n ...payrollRecordFields,\r\n ...additionalFields,\r\n },\r\n { timestamps: true }\r\n );\r\n\r\n applyPayrollRecordIndexes(schema);\r\n\r\n // Virtual: totalAmount\r\n schema.virtual('totalAmount').get(function () {\r\n return this.breakdown?.netSalary || 0;\r\n });\r\n\r\n // Virtual: isPaid\r\n schema.virtual('isPaid').get(function () {\r\n return this.status === 'paid';\r\n });\r\n\r\n // Virtual: periodLabel\r\n schema.virtual('periodLabel').get(function () {\r\n const months = [\r\n 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',\r\n 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec',\r\n ];\r\n return `${months[this.period.month - 1]} ${this.period.year}`;\r\n });\r\n\r\n // Method: markAsPaid\r\n schema.methods.markAsPaid = function (\r\n transactionId: mongoose.Types.ObjectId,\r\n paidAt = new Date()\r\n ) {\r\n this.status = 'paid';\r\n this.transactionId = transactionId;\r\n this.paidAt = paidAt;\r\n };\r\n\r\n // Method: markAsExported\r\n schema.methods.markAsExported = function () {\r\n this.exported = true;\r\n this.exportedAt = new Date();\r\n };\r\n\r\n // Method: canBeDeleted\r\n schema.methods.canBeDeleted = function (): boolean {\r\n return this.exported && this.status === 'paid';\r\n };\r\n\r\n return schema;\r\n}\r\n\r\n\r\n// ============================================================================\r\n// Default Export\r\n// ============================================================================\r\n\r\nexport default {\r\n // Sub-schemas\r\n allowanceSchema,\r\n deductionSchema,\r\n compensationSchema,\r\n workScheduleSchema,\r\n bankDetailsSchema,\r\n employmentHistorySchema,\r\n payrollStatsSchema,\r\n payrollBreakdownSchema,\r\n periodSchema,\r\n // Fields\r\n employmentFields,\r\n payrollRecordFields,\r\n // Indexes\r\n employeeIndexes,\r\n payrollRecordIndexes,\r\n applyEmployeeIndexes,\r\n applyPayrollRecordIndexes,\r\n // Schema creators\r\n createEmployeeSchema,\r\n createPayrollRecordSchema,\r\n};\r\n\r\n"]}
|