@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
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Query Builders - Fluent API, Type-Safe, Beautiful
|
|
3
|
-
* Inspired by Angular's RxJS and Playwright's chaining
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import mongoose from 'mongoose';
|
|
7
|
-
|
|
8
|
-
export const toObjectId = (id) =>
|
|
9
|
-
id instanceof mongoose.Types.ObjectId ? id : new mongoose.Types.ObjectId(id);
|
|
10
|
-
|
|
11
|
-
export class QueryBuilder {
|
|
12
|
-
constructor(initialQuery = {}) {
|
|
13
|
-
this.query = { ...initialQuery };
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
where(field, value) {
|
|
17
|
-
this.query[field] = value;
|
|
18
|
-
return this;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
whereIn(field, values) {
|
|
22
|
-
this.query[field] = { $in: values };
|
|
23
|
-
return this;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
whereNotIn(field, values) {
|
|
27
|
-
this.query[field] = { $nin: values };
|
|
28
|
-
return this;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
whereGte(field, value) {
|
|
32
|
-
this.query[field] = { ...this.query[field], $gte: value };
|
|
33
|
-
return this;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
whereLte(field, value) {
|
|
37
|
-
this.query[field] = { ...this.query[field], $lte: value };
|
|
38
|
-
return this;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
whereBetween(field, start, end) {
|
|
42
|
-
this.query[field] = { $gte: start, $lte: end };
|
|
43
|
-
return this;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
whereExists(field) {
|
|
47
|
-
this.query[field] = { $exists: true };
|
|
48
|
-
return this;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
whereNotExists(field) {
|
|
52
|
-
this.query[field] = { $exists: false };
|
|
53
|
-
return this;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
build() {
|
|
57
|
-
return this.query;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export const createQueryBuilder = (initialQuery) => new QueryBuilder(initialQuery);
|
|
62
|
-
|
|
63
|
-
export class EmployeeQueryBuilder extends QueryBuilder {
|
|
64
|
-
forOrganization(organizationId) {
|
|
65
|
-
return this.where('organizationId', toObjectId(organizationId));
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
forUser(userId) {
|
|
69
|
-
return this.where('userId', toObjectId(userId));
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
withStatus(...statuses) {
|
|
73
|
-
return statuses.length === 1
|
|
74
|
-
? this.where('status', statuses[0])
|
|
75
|
-
: this.whereIn('status', statuses);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
active() {
|
|
79
|
-
return this.withStatus('active');
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
employed() {
|
|
83
|
-
return this.whereIn('status', ['active', 'on_leave', 'suspended']);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
inDepartment(department) {
|
|
87
|
-
return this.where('department', department);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
inPosition(position) {
|
|
91
|
-
return this.where('position', position);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
withEmploymentType(type) {
|
|
95
|
-
return this.where('employmentType', type);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
hiredAfter(date) {
|
|
99
|
-
return this.whereGte('hireDate', date);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
hiredBefore(date) {
|
|
103
|
-
return this.whereLte('hireDate', date);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export class PayrollQueryBuilder extends QueryBuilder {
|
|
108
|
-
forOrganization(organizationId) {
|
|
109
|
-
return this.where('organizationId', toObjectId(organizationId));
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
forEmployee(employeeId) {
|
|
113
|
-
return this.where('employeeId', toObjectId(employeeId));
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
forPeriod(month, year) {
|
|
117
|
-
if (month) this.where('period.month', month);
|
|
118
|
-
if (year) this.where('period.year', year);
|
|
119
|
-
return this;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
withStatus(...statuses) {
|
|
123
|
-
return statuses.length === 1
|
|
124
|
-
? this.where('status', statuses[0])
|
|
125
|
-
: this.whereIn('status', statuses);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
paid() {
|
|
129
|
-
return this.withStatus('paid');
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
pending() {
|
|
133
|
-
return this.withStatus('pending', 'processing');
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
inDateRange(start, end) {
|
|
137
|
-
return this.whereBetween('paymentDate', start, end);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
export const employee = () => new EmployeeQueryBuilder();
|
|
142
|
-
export const payroll = () => new PayrollQueryBuilder();
|
|
143
|
-
|
|
144
|
-
export const buildEmployeeQuery = ({ organizationId, userId, statuses }) => {
|
|
145
|
-
const builder = employee().forOrganization(organizationId);
|
|
146
|
-
|
|
147
|
-
if (userId) builder.forUser(userId);
|
|
148
|
-
if (statuses) builder.withStatus(...statuses);
|
|
149
|
-
|
|
150
|
-
return builder.build();
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
export const buildPayrollQuery = ({ employeeId, period, statuses }) => {
|
|
154
|
-
const builder = payroll().forEmployee(employeeId);
|
|
155
|
-
|
|
156
|
-
if (period) builder.forPeriod(period.month, period.year);
|
|
157
|
-
if (statuses) builder.withStatus(...statuses);
|
|
158
|
-
|
|
159
|
-
return builder.build();
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
export const buildAggregationPipeline = (...stages) => stages.filter(Boolean);
|
|
163
|
-
|
|
164
|
-
export const matchStage = (query) => ({ $match: query });
|
|
165
|
-
|
|
166
|
-
export const groupStage = (groupBy, aggregations) => ({
|
|
167
|
-
$group: {
|
|
168
|
-
_id: groupBy,
|
|
169
|
-
...aggregations,
|
|
170
|
-
},
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
export const sortStage = (sortBy) => ({ $sort: sortBy });
|
|
174
|
-
|
|
175
|
-
export const limitStage = (limit) => ({ $limit: limit });
|
|
176
|
-
|
|
177
|
-
export const projectStage = (fields) => ({ $project: fields });
|
|
178
|
-
|
|
179
|
-
export const lookupStage = ({ from, localField, foreignField, as }) => ({
|
|
180
|
-
$lookup: { from, localField, foreignField, as },
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
export const unwindStage = (path, options = {}) => ({
|
|
184
|
-
$unwind: { path, ...options },
|
|
185
|
-
});
|
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Validation Utilities - Fluent, Composable, Type-Safe
|
|
3
|
-
* Beautiful validation with clear semantics
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export const isActive = (employee) =>
|
|
7
|
-
employee?.status === 'active';
|
|
8
|
-
|
|
9
|
-
export const isOnLeave = (employee) =>
|
|
10
|
-
employee?.status === 'on_leave';
|
|
11
|
-
|
|
12
|
-
export const isSuspended = (employee) =>
|
|
13
|
-
employee?.status === 'suspended';
|
|
14
|
-
|
|
15
|
-
export const isTerminated = (employee) =>
|
|
16
|
-
employee?.status === 'terminated';
|
|
17
|
-
|
|
18
|
-
export const isEmployed = (employee) =>
|
|
19
|
-
isActive(employee) || isOnLeave(employee) || isSuspended(employee);
|
|
20
|
-
|
|
21
|
-
export const canReceiveSalary = (employee) =>
|
|
22
|
-
isActive(employee) || isOnLeave(employee);
|
|
23
|
-
|
|
24
|
-
export const canUpdateEmployment = (employee) =>
|
|
25
|
-
!isTerminated(employee);
|
|
26
|
-
|
|
27
|
-
export const isInProbation = (employee, now = new Date()) =>
|
|
28
|
-
employee?.probationEndDate && new Date(employee.probationEndDate) > now;
|
|
29
|
-
|
|
30
|
-
export const hasCompletedProbation = (employee, now = new Date()) =>
|
|
31
|
-
employee?.probationEndDate && new Date(employee.probationEndDate) <= now;
|
|
32
|
-
|
|
33
|
-
export const hasCompensation = (employee) =>
|
|
34
|
-
employee?.compensation?.baseAmount > 0;
|
|
35
|
-
|
|
36
|
-
export const isEligibleForBonus = (employee, requiredMonths = 6) => {
|
|
37
|
-
if (!isActive(employee)) return false;
|
|
38
|
-
const monthsEmployed = monthsBetween(employee.hireDate, new Date());
|
|
39
|
-
return monthsEmployed >= requiredMonths;
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
export const isValidCompensation = (compensation) =>
|
|
43
|
-
compensation?.baseAmount > 0 &&
|
|
44
|
-
compensation?.frequency &&
|
|
45
|
-
compensation?.currency;
|
|
46
|
-
|
|
47
|
-
export const isValidBankDetails = (bankDetails) =>
|
|
48
|
-
bankDetails?.accountNumber &&
|
|
49
|
-
bankDetails?.bankName &&
|
|
50
|
-
bankDetails?.accountHolderName;
|
|
51
|
-
|
|
52
|
-
export const hasRequiredFields = (obj, fields) =>
|
|
53
|
-
fields.every((field) => obj?.[field] !== undefined && obj?.[field] !== null);
|
|
54
|
-
|
|
55
|
-
export const createValidator = (validationFns) => (data) => {
|
|
56
|
-
const errors = [];
|
|
57
|
-
|
|
58
|
-
for (const [field, validator] of Object.entries(validationFns)) {
|
|
59
|
-
const result = validator(data[field], data);
|
|
60
|
-
if (result !== true) {
|
|
61
|
-
errors.push({ field, message: result });
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return {
|
|
66
|
-
isValid: errors.length === 0,
|
|
67
|
-
errors,
|
|
68
|
-
};
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
export const required = (fieldName) => (value) =>
|
|
72
|
-
value !== undefined && value !== null && value !== ''
|
|
73
|
-
? true
|
|
74
|
-
: `${fieldName} is required`;
|
|
75
|
-
|
|
76
|
-
export const min = (minValue, fieldName) => (value) =>
|
|
77
|
-
value >= minValue ? true : `${fieldName} must be at least ${minValue}`;
|
|
78
|
-
|
|
79
|
-
export const max = (maxValue, fieldName) => (value) =>
|
|
80
|
-
value <= maxValue ? true : `${fieldName} must not exceed ${maxValue}`;
|
|
81
|
-
|
|
82
|
-
export const inRange = (minValue, maxValue, fieldName) => (value) =>
|
|
83
|
-
value >= minValue && value <= maxValue
|
|
84
|
-
? true
|
|
85
|
-
: `${fieldName} must be between ${minValue} and ${maxValue}`;
|
|
86
|
-
|
|
87
|
-
export const oneOf = (allowedValues, fieldName) => (value) =>
|
|
88
|
-
allowedValues.includes(value)
|
|
89
|
-
? true
|
|
90
|
-
: `${fieldName} must be one of: ${allowedValues.join(', ')}`;
|
|
91
|
-
|
|
92
|
-
export const compose = (...validators) => (value, data) => {
|
|
93
|
-
for (const validator of validators) {
|
|
94
|
-
const result = validator(value, data);
|
|
95
|
-
if (result !== true) return result;
|
|
96
|
-
}
|
|
97
|
-
return true;
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
// Additional validators
|
|
101
|
-
export const isPositive = (fieldName) => (value) =>
|
|
102
|
-
value > 0 ? true : `${fieldName} must be positive`;
|
|
103
|
-
|
|
104
|
-
export const isValidStatus = (value) =>
|
|
105
|
-
['active', 'on_leave', 'suspended', 'terminated'].includes(value);
|
|
106
|
-
|
|
107
|
-
export const isValidEmploymentType = (value) =>
|
|
108
|
-
['full_time', 'part_time', 'contract', 'internship'].includes(value);
|
|
109
|
-
|
|
110
|
-
// Aliases for consistency
|
|
111
|
-
export const minValue = min;
|
|
112
|
-
export const maxValue = max;
|
|
113
|
-
export const isInRange = inRange;
|
|
114
|
-
|
|
115
|
-
const monthsBetween = (start, end) => {
|
|
116
|
-
const startDate = new Date(start);
|
|
117
|
-
const endDate = new Date(end);
|
|
118
|
-
return (
|
|
119
|
-
(endDate.getFullYear() - startDate.getFullYear()) * 12 +
|
|
120
|
-
(endDate.getMonth() - startDate.getMonth())
|
|
121
|
-
);
|
|
122
|
-
};
|