@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,1046 @@
|
|
|
1
|
+
import { Types } from 'mongoose';
|
|
2
|
+
|
|
3
|
+
// src/utils/logger.ts
|
|
4
|
+
var createConsoleLogger = () => ({
|
|
5
|
+
info: (message, meta) => {
|
|
6
|
+
if (meta) {
|
|
7
|
+
console.log(`[Payroll] INFO: ${message}`, meta);
|
|
8
|
+
} else {
|
|
9
|
+
console.log(`[Payroll] INFO: ${message}`);
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
error: (message, meta) => {
|
|
13
|
+
if (meta) {
|
|
14
|
+
console.error(`[Payroll] ERROR: ${message}`, meta);
|
|
15
|
+
} else {
|
|
16
|
+
console.error(`[Payroll] ERROR: ${message}`);
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
warn: (message, meta) => {
|
|
20
|
+
if (meta) {
|
|
21
|
+
console.warn(`[Payroll] WARN: ${message}`, meta);
|
|
22
|
+
} else {
|
|
23
|
+
console.warn(`[Payroll] WARN: ${message}`);
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
debug: (message, meta) => {
|
|
27
|
+
if (process.env.NODE_ENV !== "production") {
|
|
28
|
+
if (meta) {
|
|
29
|
+
console.log(`[Payroll] DEBUG: ${message}`, meta);
|
|
30
|
+
} else {
|
|
31
|
+
console.log(`[Payroll] DEBUG: ${message}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
var currentLogger = createConsoleLogger();
|
|
37
|
+
var loggingEnabled = true;
|
|
38
|
+
function getLogger() {
|
|
39
|
+
return currentLogger;
|
|
40
|
+
}
|
|
41
|
+
function setLogger(logger2) {
|
|
42
|
+
currentLogger = logger2;
|
|
43
|
+
}
|
|
44
|
+
function resetLogger() {
|
|
45
|
+
currentLogger = createConsoleLogger();
|
|
46
|
+
}
|
|
47
|
+
function createChildLogger(prefix) {
|
|
48
|
+
const parent = currentLogger;
|
|
49
|
+
return {
|
|
50
|
+
info: (message, meta) => parent.info(`[${prefix}] ${message}`, meta),
|
|
51
|
+
error: (message, meta) => parent.error(`[${prefix}] ${message}`, meta),
|
|
52
|
+
warn: (message, meta) => parent.warn(`[${prefix}] ${message}`, meta),
|
|
53
|
+
debug: (message, meta) => parent.debug(`[${prefix}] ${message}`, meta)
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function createSilentLogger() {
|
|
57
|
+
return {
|
|
58
|
+
info: () => {
|
|
59
|
+
},
|
|
60
|
+
error: () => {
|
|
61
|
+
},
|
|
62
|
+
warn: () => {
|
|
63
|
+
},
|
|
64
|
+
debug: () => {
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function enableLogging() {
|
|
69
|
+
loggingEnabled = true;
|
|
70
|
+
}
|
|
71
|
+
function disableLogging() {
|
|
72
|
+
loggingEnabled = false;
|
|
73
|
+
}
|
|
74
|
+
function isLoggingEnabled() {
|
|
75
|
+
return loggingEnabled;
|
|
76
|
+
}
|
|
77
|
+
var logger = {
|
|
78
|
+
info: (message, meta) => {
|
|
79
|
+
if (loggingEnabled) currentLogger.info(message, meta);
|
|
80
|
+
},
|
|
81
|
+
error: (message, meta) => {
|
|
82
|
+
if (loggingEnabled) currentLogger.error(message, meta);
|
|
83
|
+
},
|
|
84
|
+
warn: (message, meta) => {
|
|
85
|
+
if (loggingEnabled) currentLogger.warn(message, meta);
|
|
86
|
+
},
|
|
87
|
+
debug: (message, meta) => {
|
|
88
|
+
if (loggingEnabled) currentLogger.debug(message, meta);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
// src/utils/date.ts
|
|
93
|
+
function addDays(date, days) {
|
|
94
|
+
const result = new Date(date);
|
|
95
|
+
result.setDate(result.getDate() + days);
|
|
96
|
+
return result;
|
|
97
|
+
}
|
|
98
|
+
function addMonths(date, months) {
|
|
99
|
+
const result = new Date(date);
|
|
100
|
+
result.setMonth(result.getMonth() + months);
|
|
101
|
+
return result;
|
|
102
|
+
}
|
|
103
|
+
function addYears(date, years) {
|
|
104
|
+
const result = new Date(date);
|
|
105
|
+
result.setFullYear(result.getFullYear() + years);
|
|
106
|
+
return result;
|
|
107
|
+
}
|
|
108
|
+
function subDays(date, days) {
|
|
109
|
+
return addDays(date, -days);
|
|
110
|
+
}
|
|
111
|
+
function subMonths(date, months) {
|
|
112
|
+
return addMonths(date, -months);
|
|
113
|
+
}
|
|
114
|
+
function startOfMonth(date) {
|
|
115
|
+
const result = new Date(date);
|
|
116
|
+
result.setDate(1);
|
|
117
|
+
result.setHours(0, 0, 0, 0);
|
|
118
|
+
return result;
|
|
119
|
+
}
|
|
120
|
+
function endOfMonth(date) {
|
|
121
|
+
const result = new Date(date);
|
|
122
|
+
result.setMonth(result.getMonth() + 1, 0);
|
|
123
|
+
result.setHours(23, 59, 59, 999);
|
|
124
|
+
return result;
|
|
125
|
+
}
|
|
126
|
+
function startOfYear(date) {
|
|
127
|
+
const result = new Date(date);
|
|
128
|
+
result.setMonth(0, 1);
|
|
129
|
+
result.setHours(0, 0, 0, 0);
|
|
130
|
+
return result;
|
|
131
|
+
}
|
|
132
|
+
function endOfYear(date) {
|
|
133
|
+
const result = new Date(date);
|
|
134
|
+
result.setMonth(11, 31);
|
|
135
|
+
result.setHours(23, 59, 59, 999);
|
|
136
|
+
return result;
|
|
137
|
+
}
|
|
138
|
+
function startOfDay(date) {
|
|
139
|
+
const result = new Date(date);
|
|
140
|
+
result.setHours(0, 0, 0, 0);
|
|
141
|
+
return result;
|
|
142
|
+
}
|
|
143
|
+
function endOfDay(date) {
|
|
144
|
+
const result = new Date(date);
|
|
145
|
+
result.setHours(23, 59, 59, 999);
|
|
146
|
+
return result;
|
|
147
|
+
}
|
|
148
|
+
function diffInDays(start, end) {
|
|
149
|
+
return Math.ceil(
|
|
150
|
+
(new Date(end).getTime() - new Date(start).getTime()) / (1e3 * 60 * 60 * 24)
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
function diffInMonths(start, end) {
|
|
154
|
+
const startDate = new Date(start);
|
|
155
|
+
const endDate = new Date(end);
|
|
156
|
+
return (endDate.getFullYear() - startDate.getFullYear()) * 12 + (endDate.getMonth() - startDate.getMonth());
|
|
157
|
+
}
|
|
158
|
+
function diffInYears(start, end) {
|
|
159
|
+
return Math.floor(diffInMonths(start, end) / 12);
|
|
160
|
+
}
|
|
161
|
+
var daysBetween = diffInDays;
|
|
162
|
+
var monthsBetween = diffInMonths;
|
|
163
|
+
function isWeekday(date) {
|
|
164
|
+
const day = new Date(date).getDay();
|
|
165
|
+
return day >= 1 && day <= 5;
|
|
166
|
+
}
|
|
167
|
+
function isWeekend(date) {
|
|
168
|
+
const day = new Date(date).getDay();
|
|
169
|
+
return day === 0 || day === 6;
|
|
170
|
+
}
|
|
171
|
+
function getDayOfWeek(date) {
|
|
172
|
+
return new Date(date).getDay();
|
|
173
|
+
}
|
|
174
|
+
function getDayName(date) {
|
|
175
|
+
const days = [
|
|
176
|
+
"Sunday",
|
|
177
|
+
"Monday",
|
|
178
|
+
"Tuesday",
|
|
179
|
+
"Wednesday",
|
|
180
|
+
"Thursday",
|
|
181
|
+
"Friday",
|
|
182
|
+
"Saturday"
|
|
183
|
+
];
|
|
184
|
+
return days[getDayOfWeek(date)];
|
|
185
|
+
}
|
|
186
|
+
function getPayPeriod(month, year) {
|
|
187
|
+
const startDate = new Date(year, month - 1, 1);
|
|
188
|
+
return {
|
|
189
|
+
month,
|
|
190
|
+
year,
|
|
191
|
+
startDate: startOfMonth(startDate),
|
|
192
|
+
endDate: endOfMonth(startDate)
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
function getCurrentPeriod(date = /* @__PURE__ */ new Date()) {
|
|
196
|
+
const d = new Date(date);
|
|
197
|
+
return {
|
|
198
|
+
year: d.getFullYear(),
|
|
199
|
+
month: d.getMonth() + 1
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
function getWorkingDaysInMonth(year, month) {
|
|
203
|
+
const start = new Date(year, month - 1, 1);
|
|
204
|
+
const end = endOfMonth(start);
|
|
205
|
+
let count = 0;
|
|
206
|
+
const current = new Date(start);
|
|
207
|
+
while (current <= end) {
|
|
208
|
+
if (isWeekday(current)) {
|
|
209
|
+
count++;
|
|
210
|
+
}
|
|
211
|
+
current.setDate(current.getDate() + 1);
|
|
212
|
+
}
|
|
213
|
+
return count;
|
|
214
|
+
}
|
|
215
|
+
function getDaysInMonth(year, month) {
|
|
216
|
+
return new Date(year, month, 0).getDate();
|
|
217
|
+
}
|
|
218
|
+
function calculateProbationEnd(hireDate, probationMonths) {
|
|
219
|
+
if (!probationMonths || probationMonths <= 0) return null;
|
|
220
|
+
return addMonths(hireDate, probationMonths);
|
|
221
|
+
}
|
|
222
|
+
function isOnProbation(probationEndDate, now = /* @__PURE__ */ new Date()) {
|
|
223
|
+
if (!probationEndDate) return false;
|
|
224
|
+
return now < new Date(probationEndDate);
|
|
225
|
+
}
|
|
226
|
+
function calculateYearsOfService(hireDate, terminationDate) {
|
|
227
|
+
const end = terminationDate || /* @__PURE__ */ new Date();
|
|
228
|
+
const days = diffInDays(hireDate, end);
|
|
229
|
+
return Math.max(0, Math.floor(days / 365.25 * 10) / 10);
|
|
230
|
+
}
|
|
231
|
+
function isDateInRange(date, start, end) {
|
|
232
|
+
const checkDate = new Date(date);
|
|
233
|
+
return checkDate >= new Date(start) && checkDate <= new Date(end);
|
|
234
|
+
}
|
|
235
|
+
function getPayPeriodDateRange(month, year) {
|
|
236
|
+
const period = getPayPeriod(month, year);
|
|
237
|
+
return { start: period.startDate, end: period.endDate };
|
|
238
|
+
}
|
|
239
|
+
function formatDateForDB(date) {
|
|
240
|
+
if (!date) return "";
|
|
241
|
+
return new Date(date).toISOString();
|
|
242
|
+
}
|
|
243
|
+
function parseDBDate(dateString) {
|
|
244
|
+
if (!dateString) return null;
|
|
245
|
+
return new Date(dateString);
|
|
246
|
+
}
|
|
247
|
+
function formatPeriod({ month, year }) {
|
|
248
|
+
return `${String(month).padStart(2, "0")}/${year}`;
|
|
249
|
+
}
|
|
250
|
+
function parsePeriod(periodString) {
|
|
251
|
+
const [month, year] = periodString.split("/").map(Number);
|
|
252
|
+
return { month, year };
|
|
253
|
+
}
|
|
254
|
+
function getMonthName(month) {
|
|
255
|
+
const months = [
|
|
256
|
+
"January",
|
|
257
|
+
"February",
|
|
258
|
+
"March",
|
|
259
|
+
"April",
|
|
260
|
+
"May",
|
|
261
|
+
"June",
|
|
262
|
+
"July",
|
|
263
|
+
"August",
|
|
264
|
+
"September",
|
|
265
|
+
"October",
|
|
266
|
+
"November",
|
|
267
|
+
"December"
|
|
268
|
+
];
|
|
269
|
+
return months[month - 1] || "";
|
|
270
|
+
}
|
|
271
|
+
function getShortMonthName(month) {
|
|
272
|
+
const months = [
|
|
273
|
+
"Jan",
|
|
274
|
+
"Feb",
|
|
275
|
+
"Mar",
|
|
276
|
+
"Apr",
|
|
277
|
+
"May",
|
|
278
|
+
"Jun",
|
|
279
|
+
"Jul",
|
|
280
|
+
"Aug",
|
|
281
|
+
"Sep",
|
|
282
|
+
"Oct",
|
|
283
|
+
"Nov",
|
|
284
|
+
"Dec"
|
|
285
|
+
];
|
|
286
|
+
return months[month - 1] || "";
|
|
287
|
+
}
|
|
288
|
+
var date_default = {
|
|
289
|
+
addDays,
|
|
290
|
+
addMonths,
|
|
291
|
+
addYears,
|
|
292
|
+
subDays,
|
|
293
|
+
subMonths,
|
|
294
|
+
startOfMonth,
|
|
295
|
+
endOfMonth,
|
|
296
|
+
startOfYear,
|
|
297
|
+
endOfYear,
|
|
298
|
+
startOfDay,
|
|
299
|
+
endOfDay,
|
|
300
|
+
diffInDays,
|
|
301
|
+
diffInMonths,
|
|
302
|
+
diffInYears,
|
|
303
|
+
daysBetween,
|
|
304
|
+
monthsBetween,
|
|
305
|
+
isWeekday,
|
|
306
|
+
isWeekend,
|
|
307
|
+
getDayOfWeek,
|
|
308
|
+
getDayName,
|
|
309
|
+
getPayPeriod,
|
|
310
|
+
getCurrentPeriod,
|
|
311
|
+
getWorkingDaysInMonth,
|
|
312
|
+
getDaysInMonth,
|
|
313
|
+
calculateProbationEnd,
|
|
314
|
+
isOnProbation,
|
|
315
|
+
calculateYearsOfService,
|
|
316
|
+
isDateInRange,
|
|
317
|
+
getPayPeriodDateRange,
|
|
318
|
+
formatDateForDB,
|
|
319
|
+
parseDBDate,
|
|
320
|
+
formatPeriod,
|
|
321
|
+
parsePeriod,
|
|
322
|
+
getMonthName,
|
|
323
|
+
getShortMonthName
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
// src/utils/calculation.ts
|
|
327
|
+
function sum(numbers) {
|
|
328
|
+
return numbers.reduce((total, n) => total + n, 0);
|
|
329
|
+
}
|
|
330
|
+
function sumBy(items, getter) {
|
|
331
|
+
return items.reduce((total, item) => total + getter(item), 0);
|
|
332
|
+
}
|
|
333
|
+
function sumAllowances(allowances) {
|
|
334
|
+
return sumBy(allowances, (a) => a.amount);
|
|
335
|
+
}
|
|
336
|
+
function sumDeductions(deductions) {
|
|
337
|
+
return sumBy(deductions, (d) => d.amount);
|
|
338
|
+
}
|
|
339
|
+
function applyPercentage(amount, percentage) {
|
|
340
|
+
return Math.round(amount * (percentage / 100));
|
|
341
|
+
}
|
|
342
|
+
function calculatePercentage(part, total) {
|
|
343
|
+
return total > 0 ? Math.round(part / total * 100) : 0;
|
|
344
|
+
}
|
|
345
|
+
function roundTo(value, decimals = 2) {
|
|
346
|
+
const factor = Math.pow(10, decimals);
|
|
347
|
+
return Math.round(value * factor) / factor;
|
|
348
|
+
}
|
|
349
|
+
function calculateGross(baseAmount, allowances) {
|
|
350
|
+
return baseAmount + sumAllowances(allowances);
|
|
351
|
+
}
|
|
352
|
+
function calculateNet(gross, deductions) {
|
|
353
|
+
return Math.max(0, gross - sumDeductions(deductions));
|
|
354
|
+
}
|
|
355
|
+
function calculateTotalCompensation(baseAmount, allowances, deductions) {
|
|
356
|
+
const gross = calculateGross(baseAmount, allowances);
|
|
357
|
+
const totalDeductions = sumDeductions(deductions);
|
|
358
|
+
const net = calculateNet(gross, deductions);
|
|
359
|
+
return { gross, net, deductions: totalDeductions };
|
|
360
|
+
}
|
|
361
|
+
function calculateAllowanceAmount(allowance, baseAmount) {
|
|
362
|
+
if (allowance.isPercentage && allowance.value !== void 0) {
|
|
363
|
+
return applyPercentage(baseAmount, allowance.value);
|
|
364
|
+
}
|
|
365
|
+
return allowance.amount;
|
|
366
|
+
}
|
|
367
|
+
function calculateDeductionAmount(deduction, baseAmount) {
|
|
368
|
+
if (deduction.isPercentage && deduction.value !== void 0) {
|
|
369
|
+
return applyPercentage(baseAmount, deduction.value);
|
|
370
|
+
}
|
|
371
|
+
return deduction.amount;
|
|
372
|
+
}
|
|
373
|
+
function calculateAllowances(allowances, baseAmount) {
|
|
374
|
+
return allowances.map((allowance) => ({
|
|
375
|
+
...allowance,
|
|
376
|
+
calculatedAmount: calculateAllowanceAmount(allowance, baseAmount)
|
|
377
|
+
}));
|
|
378
|
+
}
|
|
379
|
+
function calculateDeductions(deductions, baseAmount) {
|
|
380
|
+
return deductions.map((deduction) => ({
|
|
381
|
+
...deduction,
|
|
382
|
+
calculatedAmount: calculateDeductionAmount(deduction, baseAmount)
|
|
383
|
+
}));
|
|
384
|
+
}
|
|
385
|
+
function calculateCompensationBreakdown(compensation) {
|
|
386
|
+
const { baseAmount, allowances = [], deductions = [] } = compensation;
|
|
387
|
+
const calculatedAllowances = calculateAllowances(allowances, baseAmount);
|
|
388
|
+
const calculatedDeductions = calculateDeductions(deductions, baseAmount);
|
|
389
|
+
const grossAmount = baseAmount + sumBy(calculatedAllowances, (a) => a.calculatedAmount);
|
|
390
|
+
const netAmount = grossAmount - sumBy(calculatedDeductions, (d) => d.calculatedAmount);
|
|
391
|
+
return {
|
|
392
|
+
baseAmount,
|
|
393
|
+
allowances: calculatedAllowances,
|
|
394
|
+
deductions: calculatedDeductions,
|
|
395
|
+
grossAmount,
|
|
396
|
+
netAmount: Math.max(0, netAmount)
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
function calculateProRating(hireDate, periodStart, periodEnd) {
|
|
400
|
+
const totalDays = diffInDays(periodStart, periodEnd) + 1;
|
|
401
|
+
if (hireDate <= periodStart) {
|
|
402
|
+
return {
|
|
403
|
+
isProRated: false,
|
|
404
|
+
totalDays,
|
|
405
|
+
actualDays: totalDays,
|
|
406
|
+
ratio: 1
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
if (hireDate > periodStart && hireDate <= periodEnd) {
|
|
410
|
+
const actualDays = diffInDays(hireDate, periodEnd) + 1;
|
|
411
|
+
const ratio = actualDays / totalDays;
|
|
412
|
+
return {
|
|
413
|
+
isProRated: true,
|
|
414
|
+
totalDays,
|
|
415
|
+
actualDays,
|
|
416
|
+
ratio
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
return {
|
|
420
|
+
isProRated: false,
|
|
421
|
+
totalDays,
|
|
422
|
+
actualDays: 0,
|
|
423
|
+
ratio: 0
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
function applyProRating(amount, proRating) {
|
|
427
|
+
return Math.round(amount * proRating.ratio);
|
|
428
|
+
}
|
|
429
|
+
function calculateProRatedSalary(baseAmount, hireDate, period) {
|
|
430
|
+
const proRating = calculateProRating(hireDate, period.startDate, period.endDate);
|
|
431
|
+
const amount = applyProRating(baseAmount, proRating);
|
|
432
|
+
return { amount, proRating };
|
|
433
|
+
}
|
|
434
|
+
function applyTaxBrackets(amount, brackets) {
|
|
435
|
+
let tax = 0;
|
|
436
|
+
for (const bracket of brackets) {
|
|
437
|
+
if (amount > bracket.min) {
|
|
438
|
+
const taxableAmount = Math.min(amount, bracket.max) - bracket.min;
|
|
439
|
+
tax += taxableAmount * bracket.rate;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
return Math.round(tax);
|
|
443
|
+
}
|
|
444
|
+
function calculateTax(amount, brackets) {
|
|
445
|
+
const tax = applyTaxBrackets(amount, brackets);
|
|
446
|
+
return {
|
|
447
|
+
gross: amount,
|
|
448
|
+
tax,
|
|
449
|
+
net: amount - tax
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
function pipe(...fns) {
|
|
453
|
+
return (value) => fns.reduce((acc, fn) => fn(acc), value);
|
|
454
|
+
}
|
|
455
|
+
function compose(...fns) {
|
|
456
|
+
return (value) => fns.reduceRight((acc, fn) => fn(acc), value);
|
|
457
|
+
}
|
|
458
|
+
function createAllowanceCalculator(allowances) {
|
|
459
|
+
return (baseSalary) => calculateAllowances(allowances, baseSalary);
|
|
460
|
+
}
|
|
461
|
+
function createDeductionCalculator(deductions) {
|
|
462
|
+
return (baseSalary) => calculateDeductions(deductions, baseSalary);
|
|
463
|
+
}
|
|
464
|
+
function calculateOvertime(hourlyRate, overtimeHours, multiplier = 1.5) {
|
|
465
|
+
return Math.round(hourlyRate * overtimeHours * multiplier);
|
|
466
|
+
}
|
|
467
|
+
function calculateHourlyRate(monthlySalary, hoursPerMonth = 176) {
|
|
468
|
+
return Math.round(monthlySalary / hoursPerMonth);
|
|
469
|
+
}
|
|
470
|
+
function calculateDailyRate(monthlySalary, daysPerMonth = 22) {
|
|
471
|
+
return Math.round(monthlySalary / daysPerMonth);
|
|
472
|
+
}
|
|
473
|
+
var calculation_default = {
|
|
474
|
+
sum,
|
|
475
|
+
sumBy,
|
|
476
|
+
sumAllowances,
|
|
477
|
+
sumDeductions,
|
|
478
|
+
applyPercentage,
|
|
479
|
+
calculatePercentage,
|
|
480
|
+
roundTo,
|
|
481
|
+
calculateGross,
|
|
482
|
+
calculateNet,
|
|
483
|
+
calculateTotalCompensation,
|
|
484
|
+
calculateAllowanceAmount,
|
|
485
|
+
calculateDeductionAmount,
|
|
486
|
+
calculateAllowances,
|
|
487
|
+
calculateDeductions,
|
|
488
|
+
calculateCompensationBreakdown,
|
|
489
|
+
calculateProRating,
|
|
490
|
+
applyProRating,
|
|
491
|
+
calculateProRatedSalary,
|
|
492
|
+
applyTaxBrackets,
|
|
493
|
+
calculateTax,
|
|
494
|
+
pipe,
|
|
495
|
+
compose,
|
|
496
|
+
createAllowanceCalculator,
|
|
497
|
+
createDeductionCalculator,
|
|
498
|
+
calculateOvertime,
|
|
499
|
+
calculateHourlyRate,
|
|
500
|
+
calculateDailyRate
|
|
501
|
+
};
|
|
502
|
+
|
|
503
|
+
// src/enums.ts
|
|
504
|
+
var EMPLOYMENT_TYPE = {
|
|
505
|
+
FULL_TIME: "full_time",
|
|
506
|
+
PART_TIME: "part_time",
|
|
507
|
+
CONTRACT: "contract",
|
|
508
|
+
INTERN: "intern",
|
|
509
|
+
CONSULTANT: "consultant"
|
|
510
|
+
};
|
|
511
|
+
var EMPLOYMENT_TYPE_VALUES = Object.values(EMPLOYMENT_TYPE);
|
|
512
|
+
var EMPLOYEE_STATUS = {
|
|
513
|
+
ACTIVE: "active",
|
|
514
|
+
ON_LEAVE: "on_leave",
|
|
515
|
+
SUSPENDED: "suspended",
|
|
516
|
+
TERMINATED: "terminated"
|
|
517
|
+
};
|
|
518
|
+
var EMPLOYEE_STATUS_VALUES = Object.values(EMPLOYEE_STATUS);
|
|
519
|
+
|
|
520
|
+
// src/utils/validation.ts
|
|
521
|
+
function isActive(employee2) {
|
|
522
|
+
return employee2?.status === "active";
|
|
523
|
+
}
|
|
524
|
+
function isOnLeave(employee2) {
|
|
525
|
+
return employee2?.status === "on_leave";
|
|
526
|
+
}
|
|
527
|
+
function isSuspended(employee2) {
|
|
528
|
+
return employee2?.status === "suspended";
|
|
529
|
+
}
|
|
530
|
+
function isTerminated(employee2) {
|
|
531
|
+
return employee2?.status === "terminated";
|
|
532
|
+
}
|
|
533
|
+
function isEmployed(employee2) {
|
|
534
|
+
return isActive(employee2) || isOnLeave(employee2) || isSuspended(employee2);
|
|
535
|
+
}
|
|
536
|
+
function canReceiveSalary(employee2) {
|
|
537
|
+
return (isActive(employee2) || isOnLeave(employee2)) && (employee2.compensation?.baseAmount ?? 0) > 0;
|
|
538
|
+
}
|
|
539
|
+
function canUpdateEmployment(employee2) {
|
|
540
|
+
return !isTerminated(employee2);
|
|
541
|
+
}
|
|
542
|
+
function hasCompensation(employee2) {
|
|
543
|
+
return (employee2.compensation?.baseAmount ?? 0) > 0;
|
|
544
|
+
}
|
|
545
|
+
function isValidCompensation(compensation) {
|
|
546
|
+
return !!(compensation?.baseAmount && compensation.baseAmount > 0 && compensation.frequency && compensation.currency);
|
|
547
|
+
}
|
|
548
|
+
function isValidBankDetails(bankDetails) {
|
|
549
|
+
return !!(bankDetails?.accountNumber && bankDetails.bankName && bankDetails.accountName);
|
|
550
|
+
}
|
|
551
|
+
function isInProbation(employee2, now = /* @__PURE__ */ new Date()) {
|
|
552
|
+
if (!employee2?.probationEndDate) return false;
|
|
553
|
+
return new Date(employee2.probationEndDate) > now;
|
|
554
|
+
}
|
|
555
|
+
function hasCompletedProbation(employee2, now = /* @__PURE__ */ new Date()) {
|
|
556
|
+
if (!employee2?.probationEndDate) return true;
|
|
557
|
+
return new Date(employee2.probationEndDate) <= now;
|
|
558
|
+
}
|
|
559
|
+
function isEligibleForBonus(employee2, requiredMonths = 6) {
|
|
560
|
+
if (!isActive(employee2) || !employee2.hireDate) return false;
|
|
561
|
+
const monthsEmployed = diffInMonths(employee2.hireDate, /* @__PURE__ */ new Date());
|
|
562
|
+
return monthsEmployed >= requiredMonths;
|
|
563
|
+
}
|
|
564
|
+
function isEligibleForPayroll(employee2) {
|
|
565
|
+
const reasons = [];
|
|
566
|
+
if (!isActive(employee2) && !isOnLeave(employee2)) {
|
|
567
|
+
reasons.push("Employee is not in active or on-leave status");
|
|
568
|
+
}
|
|
569
|
+
if (!hasCompensation(employee2)) {
|
|
570
|
+
reasons.push("Employee has no valid compensation");
|
|
571
|
+
}
|
|
572
|
+
return {
|
|
573
|
+
eligible: reasons.length === 0,
|
|
574
|
+
reasons
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
function required(fieldName) {
|
|
578
|
+
return (value) => value !== void 0 && value !== null && value !== "" ? true : `${fieldName} is required`;
|
|
579
|
+
}
|
|
580
|
+
function min(minValue2, fieldName) {
|
|
581
|
+
return (value) => value >= minValue2 ? true : `${fieldName} must be at least ${minValue2}`;
|
|
582
|
+
}
|
|
583
|
+
function max(maxValue2, fieldName) {
|
|
584
|
+
return (value) => value <= maxValue2 ? true : `${fieldName} must not exceed ${maxValue2}`;
|
|
585
|
+
}
|
|
586
|
+
function inRange(minValue2, maxValue2, fieldName) {
|
|
587
|
+
return (value) => value >= minValue2 && value <= maxValue2 ? true : `${fieldName} must be between ${minValue2} and ${maxValue2}`;
|
|
588
|
+
}
|
|
589
|
+
function isPositive(fieldName) {
|
|
590
|
+
return (value) => value > 0 ? true : `${fieldName} must be positive`;
|
|
591
|
+
}
|
|
592
|
+
function oneOf(allowedValues, fieldName) {
|
|
593
|
+
return (value) => allowedValues.includes(value) ? true : `${fieldName} must be one of: ${allowedValues.join(", ")}`;
|
|
594
|
+
}
|
|
595
|
+
function isValidStatus(value) {
|
|
596
|
+
return EMPLOYEE_STATUS_VALUES.includes(value);
|
|
597
|
+
}
|
|
598
|
+
function isValidEmploymentType(value) {
|
|
599
|
+
return EMPLOYMENT_TYPE_VALUES.includes(value);
|
|
600
|
+
}
|
|
601
|
+
function composeValidators(...validators) {
|
|
602
|
+
return (value, data) => {
|
|
603
|
+
for (const validator of validators) {
|
|
604
|
+
const result = validator(value, data);
|
|
605
|
+
if (result !== true) return result;
|
|
606
|
+
}
|
|
607
|
+
return true;
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
function createValidator(validationFns) {
|
|
611
|
+
return (data) => {
|
|
612
|
+
const errors = [];
|
|
613
|
+
for (const [field, validator] of Object.entries(validationFns)) {
|
|
614
|
+
const result = validator(data[field], data);
|
|
615
|
+
if (result !== true) {
|
|
616
|
+
errors.push(result);
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
return {
|
|
620
|
+
valid: errors.length === 0,
|
|
621
|
+
errors
|
|
622
|
+
};
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
function hasRequiredFields(obj, fields) {
|
|
626
|
+
const missing = fields.filter(
|
|
627
|
+
(field) => obj[field] === void 0 || obj[field] === null
|
|
628
|
+
);
|
|
629
|
+
return {
|
|
630
|
+
valid: missing.length === 0,
|
|
631
|
+
missing
|
|
632
|
+
};
|
|
633
|
+
}
|
|
634
|
+
var minValue = min;
|
|
635
|
+
var maxValue = max;
|
|
636
|
+
var isInRange = inRange;
|
|
637
|
+
var validation_default = {
|
|
638
|
+
// Status validators
|
|
639
|
+
isActive,
|
|
640
|
+
isOnLeave,
|
|
641
|
+
isSuspended,
|
|
642
|
+
isTerminated,
|
|
643
|
+
isEmployed,
|
|
644
|
+
canReceiveSalary,
|
|
645
|
+
canUpdateEmployment,
|
|
646
|
+
// Compensation validators
|
|
647
|
+
hasCompensation,
|
|
648
|
+
isValidCompensation,
|
|
649
|
+
isValidBankDetails,
|
|
650
|
+
// Probation validators
|
|
651
|
+
isInProbation,
|
|
652
|
+
hasCompletedProbation,
|
|
653
|
+
// Eligibility validators
|
|
654
|
+
isEligibleForBonus,
|
|
655
|
+
isEligibleForPayroll,
|
|
656
|
+
// Field validators
|
|
657
|
+
required,
|
|
658
|
+
min,
|
|
659
|
+
max,
|
|
660
|
+
inRange,
|
|
661
|
+
isPositive,
|
|
662
|
+
oneOf,
|
|
663
|
+
// Enum validators
|
|
664
|
+
isValidStatus,
|
|
665
|
+
isValidEmploymentType,
|
|
666
|
+
// Composite validators
|
|
667
|
+
composeValidators,
|
|
668
|
+
createValidator,
|
|
669
|
+
hasRequiredFields
|
|
670
|
+
};
|
|
671
|
+
function toObjectId(id) {
|
|
672
|
+
if (id instanceof Types.ObjectId) return id;
|
|
673
|
+
return new Types.ObjectId(id);
|
|
674
|
+
}
|
|
675
|
+
function safeToObjectId(id) {
|
|
676
|
+
if (id instanceof Types.ObjectId) return id;
|
|
677
|
+
if (typeof id === "string" && Types.ObjectId.isValid(id)) {
|
|
678
|
+
return new Types.ObjectId(id);
|
|
679
|
+
}
|
|
680
|
+
return null;
|
|
681
|
+
}
|
|
682
|
+
function isValidObjectId(value) {
|
|
683
|
+
if (value instanceof Types.ObjectId) return true;
|
|
684
|
+
if (typeof value === "string") return Types.ObjectId.isValid(value);
|
|
685
|
+
return false;
|
|
686
|
+
}
|
|
687
|
+
var QueryBuilder = class {
|
|
688
|
+
query;
|
|
689
|
+
constructor(initialQuery = {}) {
|
|
690
|
+
this.query = { ...initialQuery };
|
|
691
|
+
}
|
|
692
|
+
/**
|
|
693
|
+
* Add where condition
|
|
694
|
+
*/
|
|
695
|
+
where(field, value) {
|
|
696
|
+
this.query[field] = value;
|
|
697
|
+
return this;
|
|
698
|
+
}
|
|
699
|
+
/**
|
|
700
|
+
* Add $in condition
|
|
701
|
+
*/
|
|
702
|
+
whereIn(field, values) {
|
|
703
|
+
this.query[field] = { $in: values };
|
|
704
|
+
return this;
|
|
705
|
+
}
|
|
706
|
+
/**
|
|
707
|
+
* Add $nin condition
|
|
708
|
+
*/
|
|
709
|
+
whereNotIn(field, values) {
|
|
710
|
+
this.query[field] = { $nin: values };
|
|
711
|
+
return this;
|
|
712
|
+
}
|
|
713
|
+
/**
|
|
714
|
+
* Add $gte condition
|
|
715
|
+
*/
|
|
716
|
+
whereGte(field, value) {
|
|
717
|
+
const existing = this.query[field] || {};
|
|
718
|
+
this.query[field] = { ...existing, $gte: value };
|
|
719
|
+
return this;
|
|
720
|
+
}
|
|
721
|
+
/**
|
|
722
|
+
* Add $lte condition
|
|
723
|
+
*/
|
|
724
|
+
whereLte(field, value) {
|
|
725
|
+
const existing = this.query[field] || {};
|
|
726
|
+
this.query[field] = { ...existing, $lte: value };
|
|
727
|
+
return this;
|
|
728
|
+
}
|
|
729
|
+
/**
|
|
730
|
+
* Add $gt condition
|
|
731
|
+
*/
|
|
732
|
+
whereGt(field, value) {
|
|
733
|
+
const existing = this.query[field] || {};
|
|
734
|
+
this.query[field] = { ...existing, $gt: value };
|
|
735
|
+
return this;
|
|
736
|
+
}
|
|
737
|
+
/**
|
|
738
|
+
* Add $lt condition
|
|
739
|
+
*/
|
|
740
|
+
whereLt(field, value) {
|
|
741
|
+
const existing = this.query[field] || {};
|
|
742
|
+
this.query[field] = { ...existing, $lt: value };
|
|
743
|
+
return this;
|
|
744
|
+
}
|
|
745
|
+
/**
|
|
746
|
+
* Add between condition
|
|
747
|
+
*/
|
|
748
|
+
whereBetween(field, start, end) {
|
|
749
|
+
this.query[field] = { $gte: start, $lte: end };
|
|
750
|
+
return this;
|
|
751
|
+
}
|
|
752
|
+
/**
|
|
753
|
+
* Add $exists condition
|
|
754
|
+
*/
|
|
755
|
+
whereExists(field) {
|
|
756
|
+
this.query[field] = { $exists: true };
|
|
757
|
+
return this;
|
|
758
|
+
}
|
|
759
|
+
/**
|
|
760
|
+
* Add $exists: false condition
|
|
761
|
+
*/
|
|
762
|
+
whereNotExists(field) {
|
|
763
|
+
this.query[field] = { $exists: false };
|
|
764
|
+
return this;
|
|
765
|
+
}
|
|
766
|
+
/**
|
|
767
|
+
* Add $ne condition
|
|
768
|
+
*/
|
|
769
|
+
whereNot(field, value) {
|
|
770
|
+
this.query[field] = { $ne: value };
|
|
771
|
+
return this;
|
|
772
|
+
}
|
|
773
|
+
/**
|
|
774
|
+
* Add regex condition
|
|
775
|
+
*/
|
|
776
|
+
whereRegex(field, pattern, flags = "i") {
|
|
777
|
+
this.query[field] = { $regex: pattern, $options: flags };
|
|
778
|
+
return this;
|
|
779
|
+
}
|
|
780
|
+
/**
|
|
781
|
+
* Merge another query
|
|
782
|
+
*/
|
|
783
|
+
merge(otherQuery) {
|
|
784
|
+
this.query = { ...this.query, ...otherQuery };
|
|
785
|
+
return this;
|
|
786
|
+
}
|
|
787
|
+
/**
|
|
788
|
+
* Build and return the query
|
|
789
|
+
*/
|
|
790
|
+
build() {
|
|
791
|
+
return { ...this.query };
|
|
792
|
+
}
|
|
793
|
+
};
|
|
794
|
+
var EmployeeQueryBuilder = class extends QueryBuilder {
|
|
795
|
+
/**
|
|
796
|
+
* Filter by organization
|
|
797
|
+
*/
|
|
798
|
+
forOrganization(organizationId) {
|
|
799
|
+
return this.where("organizationId", toObjectId(organizationId));
|
|
800
|
+
}
|
|
801
|
+
/**
|
|
802
|
+
* Filter by user
|
|
803
|
+
*/
|
|
804
|
+
forUser(userId) {
|
|
805
|
+
return this.where("userId", toObjectId(userId));
|
|
806
|
+
}
|
|
807
|
+
/**
|
|
808
|
+
* Filter by status(es)
|
|
809
|
+
*/
|
|
810
|
+
withStatus(...statuses) {
|
|
811
|
+
if (statuses.length === 1) {
|
|
812
|
+
return this.where("status", statuses[0]);
|
|
813
|
+
}
|
|
814
|
+
return this.whereIn("status", statuses);
|
|
815
|
+
}
|
|
816
|
+
/**
|
|
817
|
+
* Filter active employees
|
|
818
|
+
*/
|
|
819
|
+
active() {
|
|
820
|
+
return this.withStatus("active");
|
|
821
|
+
}
|
|
822
|
+
/**
|
|
823
|
+
* Filter employed employees (not terminated)
|
|
824
|
+
*/
|
|
825
|
+
employed() {
|
|
826
|
+
return this.whereIn("status", ["active", "on_leave", "suspended"]);
|
|
827
|
+
}
|
|
828
|
+
/**
|
|
829
|
+
* Filter terminated employees
|
|
830
|
+
*/
|
|
831
|
+
terminated() {
|
|
832
|
+
return this.withStatus("terminated");
|
|
833
|
+
}
|
|
834
|
+
/**
|
|
835
|
+
* Filter by department
|
|
836
|
+
*/
|
|
837
|
+
inDepartment(department) {
|
|
838
|
+
return this.where("department", department);
|
|
839
|
+
}
|
|
840
|
+
/**
|
|
841
|
+
* Filter by position
|
|
842
|
+
*/
|
|
843
|
+
inPosition(position) {
|
|
844
|
+
return this.where("position", position);
|
|
845
|
+
}
|
|
846
|
+
/**
|
|
847
|
+
* Filter by employment type
|
|
848
|
+
*/
|
|
849
|
+
withEmploymentType(type) {
|
|
850
|
+
return this.where("employmentType", type);
|
|
851
|
+
}
|
|
852
|
+
/**
|
|
853
|
+
* Filter by hire date (after)
|
|
854
|
+
*/
|
|
855
|
+
hiredAfter(date) {
|
|
856
|
+
return this.whereGte("hireDate", date);
|
|
857
|
+
}
|
|
858
|
+
/**
|
|
859
|
+
* Filter by hire date (before)
|
|
860
|
+
*/
|
|
861
|
+
hiredBefore(date) {
|
|
862
|
+
return this.whereLte("hireDate", date);
|
|
863
|
+
}
|
|
864
|
+
/**
|
|
865
|
+
* Filter by minimum salary
|
|
866
|
+
*/
|
|
867
|
+
withMinSalary(amount) {
|
|
868
|
+
return this.whereGte("compensation.netSalary", amount);
|
|
869
|
+
}
|
|
870
|
+
/**
|
|
871
|
+
* Filter by maximum salary
|
|
872
|
+
*/
|
|
873
|
+
withMaxSalary(amount) {
|
|
874
|
+
return this.whereLte("compensation.netSalary", amount);
|
|
875
|
+
}
|
|
876
|
+
/**
|
|
877
|
+
* Filter by salary range
|
|
878
|
+
*/
|
|
879
|
+
withSalaryRange(min2, max2) {
|
|
880
|
+
return this.whereBetween("compensation.netSalary", min2, max2);
|
|
881
|
+
}
|
|
882
|
+
};
|
|
883
|
+
var PayrollQueryBuilder = class extends QueryBuilder {
|
|
884
|
+
/**
|
|
885
|
+
* Filter by organization
|
|
886
|
+
*/
|
|
887
|
+
forOrganization(organizationId) {
|
|
888
|
+
return this.where("organizationId", toObjectId(organizationId));
|
|
889
|
+
}
|
|
890
|
+
/**
|
|
891
|
+
* Filter by employee
|
|
892
|
+
*/
|
|
893
|
+
forEmployee(employeeId) {
|
|
894
|
+
return this.where("employeeId", toObjectId(employeeId));
|
|
895
|
+
}
|
|
896
|
+
/**
|
|
897
|
+
* Filter by period
|
|
898
|
+
*/
|
|
899
|
+
forPeriod(month, year) {
|
|
900
|
+
if (month !== void 0) {
|
|
901
|
+
this.where("period.month", month);
|
|
902
|
+
}
|
|
903
|
+
if (year !== void 0) {
|
|
904
|
+
this.where("period.year", year);
|
|
905
|
+
}
|
|
906
|
+
return this;
|
|
907
|
+
}
|
|
908
|
+
/**
|
|
909
|
+
* Filter by status(es)
|
|
910
|
+
*/
|
|
911
|
+
withStatus(...statuses) {
|
|
912
|
+
if (statuses.length === 1) {
|
|
913
|
+
return this.where("status", statuses[0]);
|
|
914
|
+
}
|
|
915
|
+
return this.whereIn("status", statuses);
|
|
916
|
+
}
|
|
917
|
+
/**
|
|
918
|
+
* Filter paid records
|
|
919
|
+
*/
|
|
920
|
+
paid() {
|
|
921
|
+
return this.withStatus("paid");
|
|
922
|
+
}
|
|
923
|
+
/**
|
|
924
|
+
* Filter pending records
|
|
925
|
+
*/
|
|
926
|
+
pending() {
|
|
927
|
+
return this.whereIn("status", ["pending", "processing"]);
|
|
928
|
+
}
|
|
929
|
+
/**
|
|
930
|
+
* Filter by date range
|
|
931
|
+
*/
|
|
932
|
+
inDateRange(start, end) {
|
|
933
|
+
return this.whereBetween("period.payDate", start, end);
|
|
934
|
+
}
|
|
935
|
+
/**
|
|
936
|
+
* Filter exported records
|
|
937
|
+
*/
|
|
938
|
+
exported() {
|
|
939
|
+
return this.where("exported", true);
|
|
940
|
+
}
|
|
941
|
+
/**
|
|
942
|
+
* Filter not exported records
|
|
943
|
+
*/
|
|
944
|
+
notExported() {
|
|
945
|
+
return this.where("exported", false);
|
|
946
|
+
}
|
|
947
|
+
};
|
|
948
|
+
function employee() {
|
|
949
|
+
return new EmployeeQueryBuilder();
|
|
950
|
+
}
|
|
951
|
+
function payroll() {
|
|
952
|
+
return new PayrollQueryBuilder();
|
|
953
|
+
}
|
|
954
|
+
function createQueryBuilder(initialQuery) {
|
|
955
|
+
return new QueryBuilder(initialQuery);
|
|
956
|
+
}
|
|
957
|
+
function buildEmployeeQuery(options) {
|
|
958
|
+
const builder = employee().forOrganization(options.organizationId);
|
|
959
|
+
if (options.userId) {
|
|
960
|
+
builder.forUser(options.userId);
|
|
961
|
+
}
|
|
962
|
+
if (options.statuses) {
|
|
963
|
+
builder.withStatus(...options.statuses);
|
|
964
|
+
}
|
|
965
|
+
if (options.department) {
|
|
966
|
+
builder.inDepartment(options.department);
|
|
967
|
+
}
|
|
968
|
+
if (options.employmentType) {
|
|
969
|
+
builder.withEmploymentType(options.employmentType);
|
|
970
|
+
}
|
|
971
|
+
return builder.build();
|
|
972
|
+
}
|
|
973
|
+
function buildPayrollQuery(options) {
|
|
974
|
+
const builder = payroll();
|
|
975
|
+
if (options.organizationId) {
|
|
976
|
+
builder.forOrganization(options.organizationId);
|
|
977
|
+
}
|
|
978
|
+
if (options.employeeId) {
|
|
979
|
+
builder.forEmployee(options.employeeId);
|
|
980
|
+
}
|
|
981
|
+
if (options.month || options.year) {
|
|
982
|
+
builder.forPeriod(options.month, options.year);
|
|
983
|
+
}
|
|
984
|
+
if (options.statuses) {
|
|
985
|
+
builder.withStatus(...options.statuses);
|
|
986
|
+
}
|
|
987
|
+
return builder.build();
|
|
988
|
+
}
|
|
989
|
+
function buildAggregationPipeline(...stages) {
|
|
990
|
+
return stages.filter((stage) => !!stage);
|
|
991
|
+
}
|
|
992
|
+
function matchStage(query) {
|
|
993
|
+
return { $match: query };
|
|
994
|
+
}
|
|
995
|
+
function groupStage(groupBy, aggregations) {
|
|
996
|
+
return {
|
|
997
|
+
$group: {
|
|
998
|
+
_id: groupBy,
|
|
999
|
+
...aggregations
|
|
1000
|
+
}
|
|
1001
|
+
};
|
|
1002
|
+
}
|
|
1003
|
+
function sortStage(sortBy) {
|
|
1004
|
+
return { $sort: sortBy };
|
|
1005
|
+
}
|
|
1006
|
+
function limitStage(limit) {
|
|
1007
|
+
return { $limit: limit };
|
|
1008
|
+
}
|
|
1009
|
+
function skipStage(skip) {
|
|
1010
|
+
return { $skip: skip };
|
|
1011
|
+
}
|
|
1012
|
+
function projectStage(fields) {
|
|
1013
|
+
return { $project: fields };
|
|
1014
|
+
}
|
|
1015
|
+
function lookupStage(options) {
|
|
1016
|
+
return { $lookup: options };
|
|
1017
|
+
}
|
|
1018
|
+
function unwindStage(path, options = {}) {
|
|
1019
|
+
return { $unwind: { path, ...options } };
|
|
1020
|
+
}
|
|
1021
|
+
var query_builders_default = {
|
|
1022
|
+
toObjectId,
|
|
1023
|
+
safeToObjectId,
|
|
1024
|
+
isValidObjectId,
|
|
1025
|
+
QueryBuilder,
|
|
1026
|
+
EmployeeQueryBuilder,
|
|
1027
|
+
PayrollQueryBuilder,
|
|
1028
|
+
employee,
|
|
1029
|
+
payroll,
|
|
1030
|
+
createQueryBuilder,
|
|
1031
|
+
buildEmployeeQuery,
|
|
1032
|
+
buildPayrollQuery,
|
|
1033
|
+
buildAggregationPipeline,
|
|
1034
|
+
matchStage,
|
|
1035
|
+
groupStage,
|
|
1036
|
+
sortStage,
|
|
1037
|
+
limitStage,
|
|
1038
|
+
skipStage,
|
|
1039
|
+
projectStage,
|
|
1040
|
+
lookupStage,
|
|
1041
|
+
unwindStage
|
|
1042
|
+
};
|
|
1043
|
+
|
|
1044
|
+
export { EmployeeQueryBuilder, PayrollQueryBuilder, QueryBuilder, addDays, addMonths, addYears, applyPercentage, applyProRating, applyTaxBrackets, buildAggregationPipeline, buildEmployeeQuery, buildPayrollQuery, calculateAllowanceAmount, calculateAllowances, calculateCompensationBreakdown, calculateDailyRate, calculateDeductionAmount, calculateDeductions, calculateGross, calculateHourlyRate, calculateNet, calculateOvertime, calculatePercentage, calculateProRatedSalary, calculateProRating, calculateProbationEnd, calculateTax, calculateTotalCompensation, calculateYearsOfService, calculation_default as calculationUtils, canReceiveSalary, canUpdateEmployment, compose, composeValidators, createAllowanceCalculator, createChildLogger, createDeductionCalculator, createQueryBuilder, createSilentLogger, createValidator, date_default as dateUtils, daysBetween, diffInDays, diffInMonths, diffInYears, disableLogging, employee, enableLogging, endOfDay, endOfMonth, endOfYear, formatDateForDB, formatPeriod, getCurrentPeriod, getDayName, getDayOfWeek, getDaysInMonth, getLogger, getMonthName, getPayPeriod, getPayPeriodDateRange, getShortMonthName, getWorkingDaysInMonth, groupStage, hasCompensation, hasCompletedProbation, hasRequiredFields, inRange, isActive, isDateInRange, isEligibleForBonus, isEligibleForPayroll, isEmployed, isInProbation, isInRange, isLoggingEnabled, isOnLeave, isOnProbation, isPositive, isSuspended, isTerminated, isValidBankDetails, isValidCompensation, isValidEmploymentType, isValidObjectId, isValidStatus, isWeekday, isWeekend, limitStage, logger, lookupStage, matchStage, max, maxValue, min, minValue, monthsBetween, oneOf, parseDBDate, parsePeriod, payroll, pipe, projectStage, query_builders_default as queryBuilders, required, resetLogger, roundTo, safeToObjectId, setLogger, skipStage, sortStage, startOfDay, startOfMonth, startOfYear, subDays, subMonths, sum, sumAllowances, sumBy, sumDeductions, toObjectId, unwindStage, validation_default as validationUtils };
|
|
1045
|
+
//# sourceMappingURL=index.js.map
|
|
1046
|
+
//# sourceMappingURL=index.js.map
|