@classytic/payroll 1.0.0 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +535 -574
  2. package/dist/attendance.calculator-BZcv2iii.d.ts +336 -0
  3. package/dist/calculators/index.d.ts +4 -0
  4. package/dist/calculators/index.js +439 -0
  5. package/dist/calculators/index.js.map +1 -0
  6. package/dist/core/index.d.ts +321 -0
  7. package/dist/core/index.js +1962 -0
  8. package/dist/core/index.js.map +1 -0
  9. package/dist/error-helpers-Bm6lMny2.d.ts +740 -0
  10. package/dist/index-BKLkuSAs.d.ts +3858 -0
  11. package/dist/index.d.ts +2684 -0
  12. package/dist/index.js +11454 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/payroll-states-DBt0XVm-.d.ts +598 -0
  15. package/dist/prorating.calculator-C33fWBQf.d.ts +135 -0
  16. package/dist/schemas/index.d.ts +4 -0
  17. package/dist/schemas/index.js +1472 -0
  18. package/dist/schemas/index.js.map +1 -0
  19. package/dist/types-bZdAJueH.d.ts +2271 -0
  20. package/dist/utils/index.d.ts +1007 -0
  21. package/dist/utils/index.js +1789 -0
  22. package/dist/utils/index.js.map +1 -0
  23. package/package.json +81 -24
  24. package/src/config.js +0 -177
  25. package/src/core/compensation.manager.js +0 -242
  26. package/src/core/employment.manager.js +0 -224
  27. package/src/core/payroll.manager.js +0 -499
  28. package/src/enums.js +0 -141
  29. package/src/factories/compensation.factory.js +0 -198
  30. package/src/factories/employee.factory.js +0 -173
  31. package/src/factories/payroll.factory.js +0 -247
  32. package/src/hrm.orchestrator.js +0 -139
  33. package/src/index.js +0 -172
  34. package/src/init.js +0 -41
  35. package/src/models/payroll-record.model.js +0 -126
  36. package/src/plugins/employee.plugin.js +0 -157
  37. package/src/schemas/employment.schema.js +0 -126
  38. package/src/services/compensation.service.js +0 -231
  39. package/src/services/employee.service.js +0 -162
  40. package/src/services/payroll.service.js +0 -213
  41. package/src/utils/calculation.utils.js +0 -91
  42. package/src/utils/date.utils.js +0 -120
  43. package/src/utils/logger.js +0 -36
  44. package/src/utils/query-builders.js +0 -185
  45. package/src/utils/validation.utils.js +0 -122
@@ -1,247 +0,0 @@
1
- /**
2
- * Payroll Factory - Beautiful Salary Calculation & Record Creation
3
- * Clean, testable, immutable payroll object creation
4
- */
5
-
6
- import {
7
- calculateGross,
8
- calculateNet,
9
- createAllowanceCalculator,
10
- createDeductionCalculator,
11
- } from '../utils/calculation.utils.js';
12
-
13
- import { getPayPeriod } from '../utils/date.utils.js';
14
-
15
- export class PayrollFactory {
16
- static create({
17
- employeeId,
18
- organizationId,
19
- baseAmount,
20
- allowances = [],
21
- deductions = [],
22
- period = {},
23
- metadata = {},
24
- }) {
25
- const calculatedAllowances = this.calculateAllowances(baseAmount, allowances);
26
- const calculatedDeductions = this.calculateDeductions(baseAmount, deductions);
27
-
28
- const gross = calculateGross(baseAmount, calculatedAllowances);
29
- const net = calculateNet(gross, calculatedDeductions);
30
-
31
- return {
32
- employeeId,
33
- organizationId,
34
- period: this.createPeriod(period),
35
- breakdown: {
36
- baseAmount,
37
- allowances: calculatedAllowances,
38
- deductions: calculatedDeductions,
39
- grossSalary: gross,
40
- netSalary: net,
41
- },
42
- status: 'pending',
43
- processedAt: null,
44
- paidAt: null,
45
- metadata: {
46
- currency: metadata.currency || 'BDT',
47
- paymentMethod: metadata.paymentMethod,
48
- notes: metadata.notes,
49
- },
50
- };
51
- }
52
-
53
- static createPeriod({ month, year } = {}) {
54
- const now = new Date();
55
- return getPayPeriod(
56
- month || now.getMonth() + 1,
57
- year || now.getFullYear()
58
- );
59
- }
60
-
61
- static calculateAllowances(baseAmount, allowances) {
62
- return allowances.map((allowance) => {
63
- const amount = allowance.isPercentage
64
- ? (baseAmount * allowance.value) / 100
65
- : allowance.value;
66
-
67
- return {
68
- type: allowance.type,
69
- name: allowance.name || allowance.type,
70
- amount,
71
- isPercentage: allowance.isPercentage || false,
72
- value: allowance.value,
73
- };
74
- });
75
- }
76
-
77
- static calculateDeductions(baseAmount, deductions) {
78
- return deductions.map((deduction) => {
79
- const amount = deduction.isPercentage
80
- ? (baseAmount * deduction.value) / 100
81
- : deduction.value;
82
-
83
- return {
84
- type: deduction.type,
85
- name: deduction.name || deduction.type,
86
- amount,
87
- isPercentage: deduction.isPercentage || false,
88
- value: deduction.value,
89
- };
90
- });
91
- }
92
-
93
- static createBonus({ type, amount, reason, approvedBy }) {
94
- return {
95
- type,
96
- amount,
97
- reason,
98
- approvedBy,
99
- approvedAt: new Date(),
100
- };
101
- }
102
-
103
- static createDeduction({ type, amount, reason, appliedBy }) {
104
- return {
105
- type,
106
- amount,
107
- reason,
108
- appliedBy,
109
- appliedAt: new Date(),
110
- };
111
- }
112
-
113
- static markAsPaid(payroll, { paidAt = new Date(), transactionId, paymentMethod } = {}) {
114
- return {
115
- ...payroll,
116
- status: 'paid',
117
- paidAt,
118
- processedAt: payroll.processedAt || paidAt,
119
- metadata: {
120
- ...payroll.metadata,
121
- transactionId,
122
- paymentMethod: paymentMethod || payroll.metadata.paymentMethod,
123
- },
124
- };
125
- }
126
-
127
- static markAsProcessed(payroll, { processedAt = new Date() } = {}) {
128
- return {
129
- ...payroll,
130
- status: 'processed',
131
- processedAt,
132
- };
133
- }
134
- }
135
-
136
- export class PayrollBuilder {
137
- constructor() {
138
- this.data = {
139
- allowances: [],
140
- deductions: [],
141
- period: {},
142
- metadata: {},
143
- };
144
- }
145
-
146
- forEmployee(employeeId) {
147
- this.data.employeeId = employeeId;
148
- return this;
149
- }
150
-
151
- inOrganization(organizationId) {
152
- this.data.organizationId = organizationId;
153
- return this;
154
- }
155
-
156
- withBaseAmount(amount) {
157
- this.data.baseAmount = amount;
158
- return this;
159
- }
160
-
161
- forPeriod(month, year) {
162
- this.data.period = { month, year };
163
- return this;
164
- }
165
-
166
- addAllowance(type, value, isPercentage = false, name = null) {
167
- this.data.allowances.push({ type, value, isPercentage, name });
168
- return this;
169
- }
170
-
171
- addDeduction(type, value, isPercentage = false, name = null) {
172
- this.data.deductions.push({ type, value, isPercentage, name });
173
- return this;
174
- }
175
-
176
- addBonus(amount, reason, approvedBy) {
177
- this.data.allowances.push({
178
- type: 'bonus',
179
- value: amount,
180
- isPercentage: false,
181
- name: reason,
182
- });
183
- return this;
184
- }
185
-
186
- withCurrency(currency) {
187
- this.data.metadata.currency = currency;
188
- return this;
189
- }
190
-
191
- withPaymentMethod(method) {
192
- this.data.metadata.paymentMethod = method;
193
- return this;
194
- }
195
-
196
- withNotes(notes) {
197
- this.data.metadata.notes = notes;
198
- return this;
199
- }
200
-
201
- build() {
202
- return PayrollFactory.create(this.data);
203
- }
204
- }
205
-
206
- export const createPayroll = () => new PayrollBuilder();
207
-
208
- /**
209
- * Batch Payroll Factory - Process multiple employees
210
- */
211
- export class BatchPayrollFactory {
212
- static createBatch(employees, { month, year, organizationId }) {
213
- return employees.map((employee) =>
214
- PayrollFactory.create({
215
- employeeId: employee._id || employee.userId,
216
- organizationId: organizationId || employee.organizationId,
217
- baseAmount: employee.compensation.baseAmount,
218
- allowances: employee.compensation.allowances || [],
219
- deductions: employee.compensation.deductions || [],
220
- period: { month, year },
221
- })
222
- );
223
- }
224
-
225
- static calculateTotalPayroll(payrolls) {
226
- return payrolls.reduce(
227
- (totals, payroll) => ({
228
- count: totals.count + 1,
229
- totalGross: totals.totalGross + payroll.breakdown.grossSalary,
230
- totalNet: totals.totalNet + payroll.breakdown.netSalary,
231
- totalAllowances:
232
- totals.totalAllowances +
233
- payroll.breakdown.allowances.reduce((sum, a) => sum + a.amount, 0),
234
- totalDeductions:
235
- totals.totalDeductions +
236
- payroll.breakdown.deductions.reduce((sum, d) => sum + d.amount, 0),
237
- }),
238
- {
239
- count: 0,
240
- totalGross: 0,
241
- totalNet: 0,
242
- totalAllowances: 0,
243
- totalDeductions: 0,
244
- }
245
- );
246
- }
247
- }
@@ -1,139 +0,0 @@
1
- import * as EmploymentManager from './core/employment.manager.js';
2
- import * as CompensationManager from './core/compensation.manager.js';
3
- import * as PayrollManager from './core/payroll.manager.js';
4
- import logger from './utils/logger.js';
5
-
6
- class HRMOrchestrator {
7
- constructor() {
8
- this._models = null;
9
- this._initialized = false;
10
- }
11
-
12
- configure({ EmployeeModel, PayrollRecordModel, TransactionModel, AttendanceModel = null }) {
13
- if (!EmployeeModel || !PayrollRecordModel || !TransactionModel) {
14
- throw new Error('EmployeeModel, PayrollRecordModel, and TransactionModel are required');
15
- }
16
-
17
- this._models = { EmployeeModel, PayrollRecordModel, TransactionModel, AttendanceModel };
18
- this._initialized = true;
19
-
20
- logger.info('HRM Orchestrator configured', {
21
- hasEmployeeModel: !!EmployeeModel,
22
- hasPayrollRecordModel: !!PayrollRecordModel,
23
- hasTransactionModel: !!TransactionModel,
24
- hasAttendanceModel: !!AttendanceModel,
25
- });
26
- }
27
-
28
- _ensureInitialized() {
29
- if (!this._initialized) {
30
- throw new Error(
31
- 'HRM Orchestrator not initialized. ' +
32
- 'Call initializeHRM({ EmployeeModel, PayrollRecordModel, TransactionModel }) in bootstrap.'
33
- );
34
- }
35
- }
36
-
37
- isInitialized() {
38
- return this._initialized;
39
- }
40
-
41
- async hire(params) {
42
- this._ensureInitialized();
43
- return await EmploymentManager.hireEmployee({ ...this._models, ...params });
44
- }
45
-
46
- async updateEmployment(params) {
47
- this._ensureInitialized();
48
- return await EmploymentManager.updateEmployment({ ...this._models, ...params });
49
- }
50
-
51
- async terminate(params) {
52
- this._ensureInitialized();
53
- return await EmploymentManager.terminateEmployee({ ...this._models, ...params });
54
- }
55
-
56
- async reHire(params) {
57
- this._ensureInitialized();
58
- return await EmploymentManager.reHireEmployee({ ...this._models, ...params });
59
- }
60
-
61
- async listEmployees(params) {
62
- this._ensureInitialized();
63
- return await EmploymentManager.getEmployeeList({ ...this._models, ...params });
64
- }
65
-
66
- async getEmployee(params) {
67
- this._ensureInitialized();
68
- return await EmploymentManager.getEmployeeById({ ...this._models, ...params });
69
- }
70
-
71
- async updateSalary(params) {
72
- this._ensureInitialized();
73
- return await CompensationManager.updateSalary({ ...this._models, ...params });
74
- }
75
-
76
- async addAllowance(params) {
77
- this._ensureInitialized();
78
- return await CompensationManager.addAllowance({ ...this._models, ...params });
79
- }
80
-
81
- async removeAllowance(params) {
82
- this._ensureInitialized();
83
- return await CompensationManager.removeAllowance({ ...this._models, ...params });
84
- }
85
-
86
- async addDeduction(params) {
87
- this._ensureInitialized();
88
- return await CompensationManager.addDeduction({ ...this._models, ...params });
89
- }
90
-
91
- async removeDeduction(params) {
92
- this._ensureInitialized();
93
- return await CompensationManager.removeDeduction({ ...this._models, ...params });
94
- }
95
-
96
- async updateBankDetails(params) {
97
- this._ensureInitialized();
98
- return await CompensationManager.updateBankDetails({ ...this._models, ...params });
99
- }
100
-
101
- async processSalary(params) {
102
- this._ensureInitialized();
103
- return await PayrollManager.processSalary({ ...this._models, ...params });
104
- }
105
-
106
- async processBulkPayroll(params) {
107
- this._ensureInitialized();
108
- return await PayrollManager.processBulkPayroll({ ...this._models, ...params });
109
- }
110
-
111
- async payrollHistory(params) {
112
- this._ensureInitialized();
113
- return await PayrollManager.getPayrollHistory({ ...this._models, ...params });
114
- }
115
-
116
- async payrollSummary(params) {
117
- this._ensureInitialized();
118
- return await PayrollManager.getPayrollSummary({ ...this._models, ...params });
119
- }
120
-
121
- async exportPayroll(params) {
122
- this._ensureInitialized();
123
- return await PayrollManager.exportPayrollData({ ...this._models, ...params });
124
- }
125
-
126
- getEmployeeModel() {
127
- this._ensureInitialized();
128
- return this._models.EmployeeModel;
129
- }
130
-
131
- getPayrollRecordModel() {
132
- this._ensureInitialized();
133
- return this._models.PayrollRecordModel;
134
- }
135
- }
136
-
137
- export const hrmOrchestrator = new HRMOrchestrator();
138
- export const hrm = hrmOrchestrator;
139
- export default hrm;
package/src/index.js DELETED
@@ -1,172 +0,0 @@
1
- export { initializeHRM, isInitialized } from './init.js';
2
-
3
- // Logger configuration (for custom logger injection)
4
- export { setLogger } from './utils/logger.js';
5
-
6
- export {
7
- EMPLOYMENT_TYPE,
8
- EMPLOYMENT_TYPE_VALUES,
9
- EMPLOYEE_STATUS,
10
- EMPLOYEE_STATUS_VALUES,
11
- DEPARTMENT,
12
- DEPARTMENT_VALUES,
13
- PAYMENT_FREQUENCY,
14
- PAYMENT_FREQUENCY_VALUES,
15
- PAYMENT_METHOD,
16
- PAYMENT_METHOD_VALUES,
17
- ALLOWANCE_TYPE,
18
- ALLOWANCE_TYPE_VALUES,
19
- DEDUCTION_TYPE,
20
- DEDUCTION_TYPE_VALUES,
21
- PAYROLL_STATUS,
22
- PAYROLL_STATUS_VALUES,
23
- TERMINATION_REASON,
24
- TERMINATION_REASON_VALUES,
25
- HRM_TRANSACTION_CATEGORIES,
26
- HRM_CATEGORY_VALUES,
27
- isHRMManagedCategory,
28
- } from './enums.js';
29
-
30
- export {
31
- HRM_CONFIG,
32
- SALARY_BANDS,
33
- TAX_BRACKETS,
34
- ORG_ROLES,
35
- ORG_ROLE_KEYS,
36
- ROLE_MAPPING,
37
- calculateTax,
38
- getSalaryBand,
39
- determineOrgRole,
40
- } from './config.js';
41
-
42
- export {
43
- employmentFields,
44
- allowanceSchema,
45
- deductionSchema,
46
- compensationSchema,
47
- workScheduleSchema,
48
- bankDetailsSchema,
49
- employmentHistorySchema,
50
- payrollStatsSchema,
51
- } from './schemas/employment.schema.js';
52
-
53
- export { employeePlugin } from './plugins/employee.plugin.js';
54
-
55
- export { default as PayrollRecord } from './models/payroll-record.model.js';
56
-
57
- export { hrm, hrmOrchestrator } from './hrm.orchestrator.js';
58
-
59
- import { hrm as hrmDefault } from './hrm.orchestrator.js';
60
- export default hrmDefault;
61
-
62
- // ============================================
63
- // Pure Utilities - Testable, Reusable Functions
64
- // ============================================
65
-
66
- export {
67
- addDays,
68
- addMonths,
69
- diffInDays,
70
- diffInMonths,
71
- startOfMonth,
72
- endOfMonth,
73
- startOfYear,
74
- endOfYear,
75
- isWeekday,
76
- isWeekend,
77
- getPayPeriod,
78
- getCurrentPeriod,
79
- calculateProbationEnd,
80
- formatDateForDB,
81
- parseDBDate,
82
- } from './utils/date.utils.js';
83
-
84
- export {
85
- sum,
86
- sumBy,
87
- sumAllowances,
88
- sumDeductions,
89
- calculateGross,
90
- calculateNet,
91
- applyPercentage,
92
- calculatePercentage,
93
- createAllowanceCalculator,
94
- createDeductionCalculator,
95
- calculateTotalCompensation,
96
- pipe,
97
- compose,
98
- } from './utils/calculation.utils.js';
99
-
100
- export {
101
- isActive,
102
- isOnLeave,
103
- isSuspended,
104
- isTerminated,
105
- isEmployed,
106
- canReceiveSalary,
107
- hasCompensation,
108
- required,
109
- minValue,
110
- maxValue,
111
- isInRange,
112
- isPositive,
113
- isValidStatus,
114
- isValidEmploymentType,
115
- compose as composeValidators,
116
- } from './utils/validation.utils.js';
117
-
118
- // ============================================
119
- // Query Builders - Fluent API for MongoDB
120
- // ============================================
121
-
122
- export {
123
- QueryBuilder,
124
- EmployeeQueryBuilder,
125
- PayrollQueryBuilder,
126
- employee,
127
- payroll,
128
- toObjectId,
129
- } from './utils/query-builders.js';
130
-
131
- // ============================================
132
- // Factory Methods - Clean Object Creation
133
- // ============================================
134
-
135
- export {
136
- EmployeeFactory,
137
- EmployeeBuilder,
138
- createEmployee,
139
- } from './factories/employee.factory.js';
140
-
141
- export {
142
- PayrollFactory,
143
- PayrollBuilder,
144
- BatchPayrollFactory,
145
- createPayroll,
146
- } from './factories/payroll.factory.js';
147
-
148
- export {
149
- CompensationFactory,
150
- CompensationBuilder,
151
- CompensationPresets,
152
- createCompensation,
153
- } from './factories/compensation.factory.js';
154
-
155
- // ============================================
156
- // Service Layer - Clean Abstractions with DI
157
- // ============================================
158
-
159
- export {
160
- EmployeeService,
161
- createEmployeeService,
162
- } from './services/employee.service.js';
163
-
164
- export {
165
- PayrollService,
166
- createPayrollService,
167
- } from './services/payroll.service.js';
168
-
169
- export {
170
- CompensationService,
171
- createCompensationService,
172
- } from './services/compensation.service.js';
package/src/init.js DELETED
@@ -1,41 +0,0 @@
1
- import { hrm } from './hrm.orchestrator.js';
2
- import logger, { setLogger } from './utils/logger.js';
3
-
4
- let initialized = false;
5
-
6
- export function initializeHRM({ EmployeeModel, PayrollRecordModel, TransactionModel, AttendanceModel = null, logger: customLogger }) {
7
- // Allow users to inject their own logger
8
- if (customLogger) {
9
- setLogger(customLogger);
10
- }
11
-
12
- if (initialized) {
13
- logger.warn('HRM already initialized, skipping');
14
- return;
15
- }
16
-
17
- if (!EmployeeModel || !PayrollRecordModel || !TransactionModel) {
18
- throw new Error(
19
- 'HRM initialization requires EmployeeModel, PayrollRecordModel, and TransactionModel'
20
- );
21
- }
22
-
23
- hrm.configure({
24
- EmployeeModel,
25
- PayrollRecordModel,
26
- TransactionModel,
27
- AttendanceModel,
28
- });
29
-
30
- initialized = true;
31
-
32
- logger.info('HRM library initialized', {
33
- hasAttendanceIntegration: !!AttendanceModel,
34
- });
35
- }
36
-
37
- export function isInitialized() {
38
- return initialized;
39
- }
40
-
41
- export default initializeHRM;