@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.
Potentially problematic release.
This version of @classytic/payroll might be problematic. Click here for more details.
- 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 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/core/result.ts","../../src/core/events.ts","../../src/core/plugin.ts","../../src/utils/logger.ts","../../src/config.ts","../../src/core/container.ts","../../src/core/config.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * @classytic/payroll - Result Type\r\n *\r\n * Rust-inspired Result type for type-safe error handling\r\n * No more try/catch everywhere - explicit error handling\r\n */\r\n\r\n// ============================================================================\r\n// Result Type Definition\r\n// ============================================================================\r\n\r\n/** Success result */\r\nexport interface Ok<T> {\r\n readonly ok: true;\r\n readonly value: T;\r\n}\r\n\r\n/** Error result */\r\nexport interface Err<E> {\r\n readonly ok: false;\r\n readonly error: E;\r\n}\r\n\r\n/** Result type - either success or error */\r\nexport type Result<T, E = Error> = Ok<T> | Err<E>;\r\n\r\n// ============================================================================\r\n// Constructors\r\n// ============================================================================\r\n\r\n/**\r\n * Create a success result\r\n */\r\nexport function ok<T>(value: T): Ok<T> {\r\n return { ok: true, value };\r\n}\r\n\r\n/**\r\n * Create an error result\r\n */\r\nexport function err<E>(error: E): Err<E> {\r\n return { ok: false, error };\r\n}\r\n\r\n// ============================================================================\r\n// Type Guards\r\n// ============================================================================\r\n\r\n/**\r\n * Check if result is success\r\n */\r\nexport function isOk<T, E>(result: Result<T, E>): result is Ok<T> {\r\n return result.ok === true;\r\n}\r\n\r\n/**\r\n * Check if result is error\r\n */\r\nexport function isErr<T, E>(result: Result<T, E>): result is Err<E> {\r\n return result.ok === false;\r\n}\r\n\r\n// ============================================================================\r\n// Unwrap Functions\r\n// ============================================================================\r\n\r\n/**\r\n * Unwrap result value or throw error\r\n */\r\nexport function unwrap<T, E>(result: Result<T, E>): T {\r\n if (isOk(result)) {\r\n return result.value;\r\n }\r\n throw result.error;\r\n}\r\n\r\n/**\r\n * Unwrap result value or return default\r\n */\r\nexport function unwrapOr<T, E>(result: Result<T, E>, defaultValue: T): T {\r\n if (isOk(result)) {\r\n return result.value;\r\n }\r\n return defaultValue;\r\n}\r\n\r\n/**\r\n * Unwrap result value or compute default\r\n */\r\nexport function unwrapOrElse<T, E>(\r\n result: Result<T, E>,\r\n fn: (error: E) => T\r\n): T {\r\n if (isOk(result)) {\r\n return result.value;\r\n }\r\n return fn(result.error);\r\n}\r\n\r\n// ============================================================================\r\n// Transformation Functions\r\n// ============================================================================\r\n\r\n/**\r\n * Map success value\r\n */\r\nexport function map<T, U, E>(\r\n result: Result<T, E>,\r\n fn: (value: T) => U\r\n): Result<U, E> {\r\n if (isOk(result)) {\r\n return ok(fn(result.value));\r\n }\r\n return result;\r\n}\r\n\r\n/**\r\n * Map error value\r\n */\r\nexport function mapErr<T, E, F>(\r\n result: Result<T, E>,\r\n fn: (error: E) => F\r\n): Result<T, F> {\r\n if (isErr(result)) {\r\n return err(fn(result.error));\r\n }\r\n return result;\r\n}\r\n\r\n/**\r\n * FlatMap (chain) success value\r\n */\r\nexport function flatMap<T, U, E>(\r\n result: Result<T, E>,\r\n fn: (value: T) => Result<U, E>\r\n): Result<U, E> {\r\n if (isOk(result)) {\r\n return fn(result.value);\r\n }\r\n return result;\r\n}\r\n\r\n// ============================================================================\r\n// Utility Functions\r\n// ============================================================================\r\n\r\n/**\r\n * Try/catch wrapper for async functions\r\n */\r\nexport async function tryCatch<T, E = Error>(\r\n fn: () => Promise<T>,\r\n errorTransform?: (error: unknown) => E\r\n): Promise<Result<T, E>> {\r\n try {\r\n const value = await fn();\r\n return ok(value);\r\n } catch (error) {\r\n if (errorTransform) {\r\n return err(errorTransform(error));\r\n }\r\n return err(error as E);\r\n }\r\n}\r\n\r\n/**\r\n * Try/catch wrapper for sync functions\r\n */\r\nexport function tryCatchSync<T, E = Error>(\r\n fn: () => T,\r\n errorTransform?: (error: unknown) => E\r\n): Result<T, E> {\r\n try {\r\n const value = fn();\r\n return ok(value);\r\n } catch (error) {\r\n if (errorTransform) {\r\n return err(errorTransform(error));\r\n }\r\n return err(error as E);\r\n }\r\n}\r\n\r\n/**\r\n * Combine multiple results into one\r\n */\r\nexport function all<T, E>(results: Result<T, E>[]): Result<T[], E> {\r\n const values: T[] = [];\r\n for (const result of results) {\r\n if (isErr(result)) {\r\n return result;\r\n }\r\n values.push(result.value);\r\n }\r\n return ok(values);\r\n}\r\n\r\n/**\r\n * Pattern match on result\r\n */\r\nexport function match<T, E, R>(\r\n result: Result<T, E>,\r\n handlers: {\r\n ok: (value: T) => R;\r\n err: (error: E) => R;\r\n }\r\n): R {\r\n if (isOk(result)) {\r\n return handlers.ok(result.value);\r\n }\r\n return handlers.err(result.error);\r\n}\r\n\r\n/**\r\n * Convert Promise<Result> to Result<Promise>\r\n */\r\nexport async function fromPromise<T, E = Error>(\r\n promise: Promise<T>,\r\n errorTransform?: (error: unknown) => E\r\n): Promise<Result<T, E>> {\r\n return tryCatch(() => promise, errorTransform);\r\n}\r\n\r\n/**\r\n * Create Result from nullable value\r\n */\r\nexport function fromNullable<T, E>(\r\n value: T | null | undefined,\r\n error: E\r\n): Result<T, E> {\r\n if (value === null || value === undefined) {\r\n return err(error);\r\n }\r\n return ok(value);\r\n}\r\n\r\n// ============================================================================\r\n// Result Class (OOP Alternative)\r\n// ============================================================================\r\n\r\nexport class ResultClass<T, E = Error> {\r\n private constructor(private readonly result: Result<T, E>) {}\r\n\r\n static ok<T>(value: T): ResultClass<T, never> {\r\n return new ResultClass(ok(value));\r\n }\r\n\r\n static err<E>(error: E): ResultClass<never, E> {\r\n return new ResultClass(err(error));\r\n }\r\n\r\n static async fromAsync<T, E = Error>(\r\n fn: () => Promise<T>,\r\n errorTransform?: (error: unknown) => E\r\n ): Promise<ResultClass<T, E>> {\r\n const result = await tryCatch(fn, errorTransform);\r\n return new ResultClass(result);\r\n }\r\n\r\n isOk(): boolean {\r\n return isOk(this.result);\r\n }\r\n\r\n isErr(): boolean {\r\n return isErr(this.result);\r\n }\r\n\r\n unwrap(): T {\r\n return unwrap(this.result);\r\n }\r\n\r\n unwrapOr(defaultValue: T): T {\r\n return unwrapOr(this.result, defaultValue);\r\n }\r\n\r\n map<U>(fn: (value: T) => U): ResultClass<U, E> {\r\n return new ResultClass(map(this.result, fn));\r\n }\r\n\r\n mapErr<F>(fn: (error: E) => F): ResultClass<T, F> {\r\n return new ResultClass(mapErr(this.result, fn));\r\n }\r\n\r\n flatMap<U>(fn: (value: T) => Result<U, E>): ResultClass<U, E> {\r\n return new ResultClass(flatMap(this.result, fn));\r\n }\r\n\r\n match<R>(handlers: { ok: (value: T) => R; err: (error: E) => R }): R {\r\n return match(this.result, handlers);\r\n }\r\n\r\n toResult(): Result<T, E> {\r\n return this.result;\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// Alias for convenience\r\n// ============================================================================\r\n\r\nexport const Result = {\r\n ok,\r\n err,\r\n isOk,\r\n isErr,\r\n unwrap,\r\n unwrapOr,\r\n unwrapOrElse,\r\n map,\r\n mapErr,\r\n flatMap,\r\n tryCatch,\r\n tryCatchSync,\r\n all,\r\n match,\r\n fromPromise,\r\n fromNullable,\r\n};\r\n\r\n","/**\r\n * @classytic/payroll - Event System\r\n *\r\n * Type-safe event emitter for payroll lifecycle events\r\n * Enables loose coupling and extensibility\r\n */\r\n\r\nimport type {\r\n PayrollEvent,\r\n EmployeeDocument,\r\n PayrollRecordDocument,\r\n ObjectId,\r\n OperationContext,\r\n} from '../types.js';\r\n\r\n// ============================================================================\r\n// Event Payload Types\r\n// ============================================================================\r\n\r\nexport interface EmployeeHiredEventPayload {\r\n employee: {\r\n id: ObjectId;\r\n employeeId: string;\r\n position: string;\r\n department?: string;\r\n };\r\n organizationId: ObjectId;\r\n context?: OperationContext;\r\n}\r\n\r\nexport interface EmployeeTerminatedEventPayload {\r\n employee: {\r\n id: ObjectId;\r\n employeeId: string;\r\n name?: string;\r\n };\r\n terminationDate: Date;\r\n reason?: string;\r\n organizationId: ObjectId;\r\n context?: OperationContext;\r\n}\r\n\r\nexport interface EmployeeRehiredEventPayload {\r\n employee: {\r\n id: ObjectId;\r\n employeeId: string;\r\n position: string;\r\n };\r\n previousTerminationDate?: Date;\r\n organizationId: ObjectId;\r\n context?: OperationContext;\r\n}\r\n\r\nexport interface SalaryUpdatedEventPayload {\r\n employee: {\r\n id: ObjectId;\r\n employeeId: string;\r\n };\r\n previousSalary: number;\r\n newSalary: number;\r\n effectiveFrom: Date;\r\n organizationId: ObjectId;\r\n context?: OperationContext;\r\n}\r\n\r\nexport interface SalaryProcessedEventPayload {\r\n employee: {\r\n id: ObjectId;\r\n employeeId: string;\r\n name?: string;\r\n };\r\n payroll: {\r\n id: ObjectId;\r\n period: { month: number; year: number };\r\n grossAmount: number;\r\n netAmount: number;\r\n };\r\n transactionId: ObjectId;\r\n organizationId: ObjectId;\r\n context?: OperationContext;\r\n}\r\n\r\nexport interface SalaryFailedEventPayload {\r\n employee: {\r\n id: ObjectId;\r\n employeeId: string;\r\n };\r\n period: { month: number; year: number };\r\n error: string;\r\n organizationId: ObjectId;\r\n context?: OperationContext;\r\n}\r\n\r\nexport interface PayrollCompletedEventPayload {\r\n organizationId: ObjectId;\r\n period: { month: number; year: number };\r\n summary: {\r\n total: number;\r\n successful: number;\r\n failed: number;\r\n totalAmount: number;\r\n };\r\n context?: OperationContext;\r\n}\r\n\r\nexport interface PayrollExportedEventPayload {\r\n organizationId: ObjectId;\r\n dateRange: { start: Date; end: Date };\r\n recordCount: number;\r\n format: string;\r\n context?: OperationContext;\r\n}\r\n\r\nexport interface CompensationChangedEventPayload {\r\n employee: {\r\n id: ObjectId;\r\n employeeId: string;\r\n };\r\n changeType: 'allowance_added' | 'allowance_removed' | 'deduction_added' | 'deduction_removed';\r\n details: {\r\n type: string;\r\n amount: number;\r\n };\r\n organizationId: ObjectId;\r\n context?: OperationContext;\r\n}\r\n\r\nexport interface MilestoneAchievedEventPayload {\r\n employee: {\r\n id: ObjectId;\r\n employeeId: string;\r\n name?: string;\r\n };\r\n milestone: {\r\n type: 'tenure' | 'salary' | 'payments';\r\n value: number;\r\n message: string;\r\n };\r\n organizationId: ObjectId;\r\n}\r\n\r\n// ============================================================================\r\n// Event Map\r\n// ============================================================================\r\n\r\nexport interface PayrollEventMap {\r\n 'employee:hired': EmployeeHiredEventPayload;\r\n 'employee:terminated': EmployeeTerminatedEventPayload;\r\n 'employee:rehired': EmployeeRehiredEventPayload;\r\n 'salary:updated': SalaryUpdatedEventPayload;\r\n 'salary:processed': SalaryProcessedEventPayload;\r\n 'salary:failed': SalaryFailedEventPayload;\r\n 'payroll:completed': PayrollCompletedEventPayload;\r\n 'payroll:exported': PayrollExportedEventPayload;\r\n 'compensation:changed': CompensationChangedEventPayload;\r\n 'milestone:achieved': MilestoneAchievedEventPayload;\r\n}\r\n\r\nexport type PayrollEventType = keyof PayrollEventMap;\r\n\r\n// ============================================================================\r\n// Event Handler Types\r\n// ============================================================================\r\n\r\nexport type EventHandler<T> = (payload: T) => void | Promise<void>;\r\n\r\nexport type PayrollEventHandler<K extends PayrollEventType> = EventHandler<\r\n PayrollEventMap[K]\r\n>;\r\n\r\n// ============================================================================\r\n// EventBus Class\r\n// ============================================================================\r\n\r\nexport class EventBus {\r\n private handlers = new Map<\r\n PayrollEventType,\r\n Set<EventHandler<unknown>>\r\n >();\r\n\r\n /**\r\n * Register an event handler\r\n */\r\n on<K extends PayrollEventType>(\r\n event: K,\r\n handler: PayrollEventHandler<K>\r\n ): () => void {\r\n if (!this.handlers.has(event)) {\r\n this.handlers.set(event, new Set());\r\n }\r\n this.handlers.get(event)!.add(handler as EventHandler<unknown>);\r\n\r\n // Return unsubscribe function\r\n return () => this.off(event, handler);\r\n }\r\n\r\n /**\r\n * Register a one-time event handler\r\n */\r\n once<K extends PayrollEventType>(\r\n event: K,\r\n handler: PayrollEventHandler<K>\r\n ): () => void {\r\n const wrappedHandler: PayrollEventHandler<K> = async (payload) => {\r\n this.off(event, wrappedHandler);\r\n await handler(payload);\r\n };\r\n return this.on(event, wrappedHandler);\r\n }\r\n\r\n /**\r\n * Remove an event handler\r\n */\r\n off<K extends PayrollEventType>(\r\n event: K,\r\n handler: PayrollEventHandler<K>\r\n ): void {\r\n const eventHandlers = this.handlers.get(event);\r\n if (eventHandlers) {\r\n eventHandlers.delete(handler as EventHandler<unknown>);\r\n }\r\n }\r\n\r\n /**\r\n * Emit an event\r\n */\r\n async emit<K extends PayrollEventType>(\r\n event: K,\r\n payload: PayrollEventMap[K]\r\n ): Promise<void> {\r\n const eventHandlers = this.handlers.get(event);\r\n if (!eventHandlers || eventHandlers.size === 0) {\r\n return;\r\n }\r\n\r\n const handlers = Array.from(eventHandlers);\r\n await Promise.all(\r\n handlers.map(async (handler) => {\r\n try {\r\n await handler(payload);\r\n } catch (error) {\r\n console.error(`Event handler error for ${event}:`, error);\r\n }\r\n })\r\n );\r\n }\r\n\r\n /**\r\n * Emit event synchronously (fire-and-forget)\r\n */\r\n emitSync<K extends PayrollEventType>(\r\n event: K,\r\n payload: PayrollEventMap[K]\r\n ): void {\r\n void this.emit(event, payload);\r\n }\r\n\r\n /**\r\n * Remove all handlers for an event\r\n */\r\n removeAllListeners(event?: PayrollEventType): void {\r\n if (event) {\r\n this.handlers.delete(event);\r\n } else {\r\n this.handlers.clear();\r\n }\r\n }\r\n\r\n /**\r\n * Get listener count for an event\r\n */\r\n listenerCount(event: PayrollEventType): number {\r\n return this.handlers.get(event)?.size ?? 0;\r\n }\r\n\r\n /**\r\n * Get all registered events\r\n */\r\n eventNames(): PayrollEventType[] {\r\n return Array.from(this.handlers.keys());\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// Default EventBus Instance\r\n// ============================================================================\r\n\r\nlet defaultEventBus: EventBus | null = null;\r\n\r\n/**\r\n * Get or create the default event bus\r\n */\r\nexport function getEventBus(): EventBus {\r\n if (!defaultEventBus) {\r\n defaultEventBus = new EventBus();\r\n }\r\n return defaultEventBus;\r\n}\r\n\r\n/**\r\n * Create a new event bus instance\r\n */\r\nexport function createEventBus(): EventBus {\r\n return new EventBus();\r\n}\r\n\r\n/**\r\n * Reset the default event bus (for testing)\r\n */\r\nexport function resetEventBus(): void {\r\n if (defaultEventBus) {\r\n defaultEventBus.removeAllListeners();\r\n }\r\n defaultEventBus = null;\r\n}\r\n\r\n// ============================================================================\r\n// Convenience Functions\r\n// ============================================================================\r\n\r\n/**\r\n * Subscribe to employee hired events\r\n */\r\nexport function onEmployeeHired(\r\n handler: PayrollEventHandler<'employee:hired'>\r\n): () => void {\r\n return getEventBus().on('employee:hired', handler);\r\n}\r\n\r\n/**\r\n * Subscribe to salary processed events\r\n */\r\nexport function onSalaryProcessed(\r\n handler: PayrollEventHandler<'salary:processed'>\r\n): () => void {\r\n return getEventBus().on('salary:processed', handler);\r\n}\r\n\r\n/**\r\n * Subscribe to payroll completed events\r\n */\r\nexport function onPayrollCompleted(\r\n handler: PayrollEventHandler<'payroll:completed'>\r\n): () => void {\r\n return getEventBus().on('payroll:completed', handler);\r\n}\r\n\r\n/**\r\n * Subscribe to milestone achieved events\r\n */\r\nexport function onMilestoneAchieved(\r\n handler: PayrollEventHandler<'milestone:achieved'>\r\n): () => void {\r\n return getEventBus().on('milestone:achieved', handler);\r\n}\r\n\r\n","/**\r\n * @classytic/payroll - Plugin System\r\n *\r\n * Extensible plugin architecture for customization\r\n * Follows patterns from popular libraries like Mongoose, Fastify\r\n */\r\n\r\nimport type { PayrollInstance, PayrollPlugin, Logger } from '../types.js';\r\nimport type { EventBus, PayrollEventType, PayrollEventMap } from './events.js';\r\n\r\n// ============================================================================\r\n// Plugin Context\r\n// ============================================================================\r\n\r\nexport interface PluginContext {\r\n /** Payroll instance */\r\n payroll: PayrollInstance;\r\n /** Event bus for subscribing to events */\r\n events: EventBus;\r\n /** Logger instance */\r\n logger: PluginLogger;\r\n /** Configuration getter */\r\n getConfig: <T>(key: string) => T | undefined;\r\n /** Register a hook */\r\n addHook: <K extends PayrollEventType>(\r\n event: K,\r\n handler: (payload: PayrollEventMap[K]) => void | Promise<void>\r\n ) => () => void;\r\n}\r\n\r\nexport interface PluginLogger {\r\n info(message: string, meta?: Record<string, unknown>): void;\r\n error(message: string, meta?: Record<string, unknown>): void;\r\n warn(message: string, meta?: Record<string, unknown>): void;\r\n debug(message: string, meta?: Record<string, unknown>): void;\r\n}\r\n\r\n// ============================================================================\r\n// Plugin Hooks\r\n// ============================================================================\r\n\r\nexport interface PluginHooks {\r\n /** Called before employee is hired */\r\n beforeHire?: (params: unknown) => void | Promise<void>;\r\n /** Called after employee is hired */\r\n afterHire?: (employee: unknown) => void | Promise<void>;\r\n /** Called before salary is processed */\r\n beforeProcessSalary?: (params: unknown) => void | Promise<void>;\r\n /** Called after salary is processed */\r\n afterProcessSalary?: (result: unknown) => void | Promise<void>;\r\n /** Called before termination */\r\n beforeTerminate?: (params: unknown) => void | Promise<void>;\r\n /** Called after termination */\r\n afterTerminate?: (employee: unknown) => void | Promise<void>;\r\n /** Called on any error */\r\n onError?: (error: Error, context: string) => void | Promise<void>;\r\n}\r\n\r\n// ============================================================================\r\n// ClockIn Plugin Interface\r\n// ============================================================================\r\n\r\nexport interface PayrollPluginDefinition {\r\n name: string;\r\n version?: string;\r\n hooks?: PluginHooks;\r\n init?: (context: PluginContext) => void | Promise<void>;\r\n destroy?: () => void | Promise<void>;\r\n}\r\n\r\n// ============================================================================\r\n// Plugin Manager\r\n// ============================================================================\r\n\r\nexport class PluginManager {\r\n private plugins = new Map<string, PayrollPluginDefinition>();\r\n private hooks = new Map<keyof PluginHooks, Array<NonNullable<PluginHooks[keyof PluginHooks]>>>();\r\n\r\n constructor(private context: PluginContext) {}\r\n\r\n /**\r\n * Register a plugin\r\n */\r\n async register(plugin: PayrollPluginDefinition): Promise<void> {\r\n if (this.plugins.has(plugin.name)) {\r\n throw new Error(`Plugin \"${plugin.name}\" is already registered`);\r\n }\r\n\r\n // Register hooks\r\n if (plugin.hooks) {\r\n for (const [hookName, handler] of Object.entries(plugin.hooks)) {\r\n if (handler) {\r\n this.addHook(hookName as keyof PluginHooks, handler);\r\n }\r\n }\r\n }\r\n\r\n // Initialize plugin\r\n if (plugin.init) {\r\n await plugin.init(this.context);\r\n }\r\n\r\n this.plugins.set(plugin.name, plugin);\r\n this.context.logger.debug(`Plugin \"${plugin.name}\" registered`);\r\n }\r\n\r\n /**\r\n * Unregister a plugin\r\n */\r\n async unregister(name: string): Promise<void> {\r\n const plugin = this.plugins.get(name);\r\n if (!plugin) {\r\n return;\r\n }\r\n\r\n if (plugin.destroy) {\r\n await plugin.destroy();\r\n }\r\n\r\n this.plugins.delete(name);\r\n this.context.logger.debug(`Plugin \"${name}\" unregistered`);\r\n }\r\n\r\n /**\r\n * Add a hook handler\r\n */\r\n private addHook<K extends keyof PluginHooks>(\r\n hookName: K,\r\n handler: NonNullable<PluginHooks[K]>\r\n ): void {\r\n if (!this.hooks.has(hookName)) {\r\n this.hooks.set(hookName, []);\r\n }\r\n this.hooks.get(hookName)!.push(handler);\r\n }\r\n\r\n /**\r\n * Execute hooks for a given event\r\n */\r\n async executeHooks<K extends keyof PluginHooks>(\r\n hookName: K,\r\n ...args: Parameters<NonNullable<PluginHooks[K]>>\r\n ): Promise<void> {\r\n const handlers = this.hooks.get(hookName);\r\n if (!handlers || handlers.length === 0) {\r\n return;\r\n }\r\n\r\n for (const handler of handlers) {\r\n try {\r\n await (handler as (...args: unknown[]) => void | Promise<void>)(...args);\r\n } catch (error) {\r\n this.context.logger.error(`Hook \"${hookName}\" error:`, { error });\r\n // Execute onError hooks\r\n const errorHandlers = this.hooks.get('onError');\r\n if (errorHandlers) {\r\n for (const errorHandler of errorHandlers) {\r\n try {\r\n await (errorHandler as PluginHooks['onError'])!(error as Error, hookName);\r\n } catch {\r\n // Ignore errors in error handlers\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Get registered plugin names\r\n */\r\n getPluginNames(): string[] {\r\n return Array.from(this.plugins.keys());\r\n }\r\n\r\n /**\r\n * Check if plugin is registered\r\n */\r\n hasPlugin(name: string): boolean {\r\n return this.plugins.has(name);\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// Plugin Definition Helper\r\n// ============================================================================\r\n\r\n/**\r\n * Define a plugin with type safety\r\n */\r\nexport function definePlugin(\r\n definition: PayrollPluginDefinition\r\n): PayrollPluginDefinition {\r\n return definition;\r\n}\r\n\r\n// ============================================================================\r\n// Built-in Plugins\r\n// ============================================================================\r\n\r\n/**\r\n * Logging plugin - logs all payroll events\r\n */\r\nexport const loggingPlugin = definePlugin({\r\n name: 'logging',\r\n version: '1.0.0',\r\n init: (context) => {\r\n // Subscribe to all events\r\n context.addHook('employee:hired', (payload) => {\r\n context.logger.info('Employee hired', {\r\n employeeId: payload.employee.employeeId,\r\n position: payload.employee.position,\r\n });\r\n });\r\n\r\n context.addHook('salary:processed', (payload) => {\r\n context.logger.info('Salary processed', {\r\n employeeId: payload.employee.employeeId,\r\n amount: payload.payroll.netAmount,\r\n period: payload.payroll.period,\r\n });\r\n });\r\n\r\n context.addHook('employee:terminated', (payload) => {\r\n context.logger.info('Employee terminated', {\r\n employeeId: payload.employee.employeeId,\r\n reason: payload.reason,\r\n });\r\n });\r\n },\r\n hooks: {\r\n onError: (error, context) => {\r\n console.error(`[Payroll Error] ${context}:`, error.message);\r\n },\r\n },\r\n});\r\n\r\n/**\r\n * Metrics plugin - collects payroll metrics\r\n */\r\nexport const metricsPlugin = definePlugin({\r\n name: 'metrics',\r\n version: '1.0.0',\r\n init: (context) => {\r\n const metrics = {\r\n employeesHired: 0,\r\n employeesTerminated: 0,\r\n salariesProcessed: 0,\r\n totalPaid: 0,\r\n errors: 0,\r\n };\r\n\r\n context.addHook('employee:hired', () => {\r\n metrics.employeesHired++;\r\n });\r\n\r\n context.addHook('employee:terminated', () => {\r\n metrics.employeesTerminated++;\r\n });\r\n\r\n context.addHook('salary:processed', (payload) => {\r\n metrics.salariesProcessed++;\r\n metrics.totalPaid += payload.payroll.netAmount;\r\n });\r\n\r\n // Expose metrics on payroll instance\r\n (context.payroll as unknown as { metrics: typeof metrics }).metrics = metrics;\r\n },\r\n hooks: {\r\n onError: (error, context) => {\r\n // Increment error counter\r\n },\r\n },\r\n});\r\n\r\n/**\r\n * Notification plugin - sends notifications for events\r\n */\r\nexport interface NotificationPluginOptions {\r\n onHired?: (employee: { id: unknown; name?: string }) => void | Promise<void>;\r\n onTerminated?: (employee: { id: unknown; name?: string }) => void | Promise<void>;\r\n onSalaryProcessed?: (details: { \r\n employee: { id: unknown; name?: string };\r\n amount: number;\r\n }) => void | Promise<void>;\r\n onMilestone?: (details: {\r\n employee: { id: unknown; name?: string };\r\n milestone: string;\r\n }) => void | Promise<void>;\r\n}\r\n\r\nexport function createNotificationPlugin(\r\n options: NotificationPluginOptions\r\n): PayrollPluginDefinition {\r\n return definePlugin({\r\n name: 'notification',\r\n version: '1.0.0',\r\n init: (context) => {\r\n if (options.onHired) {\r\n context.addHook('employee:hired', async (payload) => {\r\n await options.onHired!({\r\n id: payload.employee.id,\r\n name: payload.employee.position,\r\n });\r\n });\r\n }\r\n\r\n if (options.onTerminated) {\r\n context.addHook('employee:terminated', async (payload) => {\r\n await options.onTerminated!({\r\n id: payload.employee.id,\r\n name: payload.employee.name,\r\n });\r\n });\r\n }\r\n\r\n if (options.onSalaryProcessed) {\r\n context.addHook('salary:processed', async (payload) => {\r\n await options.onSalaryProcessed!({\r\n employee: {\r\n id: payload.employee.id,\r\n name: payload.employee.name,\r\n },\r\n amount: payload.payroll.netAmount,\r\n });\r\n });\r\n }\r\n\r\n if (options.onMilestone) {\r\n context.addHook('milestone:achieved', async (payload) => {\r\n await options.onMilestone!({\r\n employee: {\r\n id: payload.employee.id,\r\n name: payload.employee.name,\r\n },\r\n milestone: payload.milestone.message,\r\n });\r\n });\r\n }\r\n },\r\n });\r\n}\r\n\r\n// Alias for backwards compatibility\r\nexport const notificationPlugin = createNotificationPlugin({});\r\n\r\n","/**\r\n * @classytic/payroll - Logger\r\n *\r\n * Pluggable logger abstraction\r\n * Defaults to console, can be replaced with pino, winston, etc.\r\n */\r\n\r\nimport type { Logger } from '../types.js';\r\n\r\n// ============================================================================\r\n// Default Logger Implementation\r\n// ============================================================================\r\n\r\nconst createConsoleLogger = (): Logger => ({\r\n info: (message: string, meta?: Record<string, unknown>) => {\r\n if (meta) {\r\n console.log(`[Payroll] INFO: ${message}`, meta);\r\n } else {\r\n console.log(`[Payroll] INFO: ${message}`);\r\n }\r\n },\r\n error: (message: string, meta?: Record<string, unknown>) => {\r\n if (meta) {\r\n console.error(`[Payroll] ERROR: ${message}`, meta);\r\n } else {\r\n console.error(`[Payroll] ERROR: ${message}`);\r\n }\r\n },\r\n warn: (message: string, meta?: Record<string, unknown>) => {\r\n if (meta) {\r\n console.warn(`[Payroll] WARN: ${message}`, meta);\r\n } else {\r\n console.warn(`[Payroll] WARN: ${message}`);\r\n }\r\n },\r\n debug: (message: string, meta?: Record<string, unknown>) => {\r\n if (process.env.NODE_ENV !== 'production') {\r\n if (meta) {\r\n console.log(`[Payroll] DEBUG: ${message}`, meta);\r\n } else {\r\n console.log(`[Payroll] DEBUG: ${message}`);\r\n }\r\n }\r\n },\r\n});\r\n\r\n// ============================================================================\r\n// Logger State\r\n// ============================================================================\r\n\r\nlet currentLogger: Logger = createConsoleLogger();\r\nlet loggingEnabled = true;\r\n\r\n// ============================================================================\r\n// Logger Functions\r\n// ============================================================================\r\n\r\n/**\r\n * Get the current logger instance\r\n */\r\nexport function getLogger(): Logger {\r\n return currentLogger;\r\n}\r\n\r\n/**\r\n * Set a custom logger instance\r\n */\r\nexport function setLogger(logger: Logger): void {\r\n currentLogger = logger;\r\n}\r\n\r\n/**\r\n * Reset to default console logger\r\n */\r\nexport function resetLogger(): void {\r\n currentLogger = createConsoleLogger();\r\n}\r\n\r\n/**\r\n * Create a child logger with prefix\r\n */\r\nexport function createChildLogger(prefix: string): Logger {\r\n const parent = currentLogger;\r\n return {\r\n info: (message: string, meta?: Record<string, unknown>) =>\r\n parent.info(`[${prefix}] ${message}`, meta),\r\n error: (message: string, meta?: Record<string, unknown>) =>\r\n parent.error(`[${prefix}] ${message}`, meta),\r\n warn: (message: string, meta?: Record<string, unknown>) =>\r\n parent.warn(`[${prefix}] ${message}`, meta),\r\n debug: (message: string, meta?: Record<string, unknown>) =>\r\n parent.debug(`[${prefix}] ${message}`, meta),\r\n };\r\n}\r\n\r\n/**\r\n * Create a silent logger (for testing)\r\n */\r\nexport function createSilentLogger(): Logger {\r\n return {\r\n info: () => {},\r\n error: () => {},\r\n warn: () => {},\r\n debug: () => {},\r\n };\r\n}\r\n\r\n/**\r\n * Enable logging globally\r\n */\r\nexport function enableLogging(): void {\r\n loggingEnabled = true;\r\n}\r\n\r\n/**\r\n * Disable logging globally (useful for production)\r\n */\r\nexport function disableLogging(): void {\r\n loggingEnabled = false;\r\n}\r\n\r\n/**\r\n * Check if logging is enabled\r\n */\r\nexport function isLoggingEnabled(): boolean {\r\n return loggingEnabled;\r\n}\r\n\r\n// ============================================================================\r\n// Logger Proxy Object\r\n// ============================================================================\r\n\r\n/**\r\n * Logger proxy that always delegates to currentLogger\r\n * Respects global logging enabled/disabled state\r\n */\r\nexport const logger: Logger = {\r\n info: (message: string, meta?: Record<string, unknown>) => {\r\n if (loggingEnabled) currentLogger.info(message, meta);\r\n },\r\n error: (message: string, meta?: Record<string, unknown>) => {\r\n if (loggingEnabled) currentLogger.error(message, meta);\r\n },\r\n warn: (message: string, meta?: Record<string, unknown>) => {\r\n if (loggingEnabled) currentLogger.warn(message, meta);\r\n },\r\n debug: (message: string, meta?: Record<string, unknown>) => {\r\n if (loggingEnabled) currentLogger.debug(message, meta);\r\n },\r\n};\r\n\r\nexport default logger;\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 - Dependency Container\r\n *\r\n * Simple dependency injection container for service management\r\n * Enables clean dependency injection and testing\r\n */\r\n\r\nimport type { Model, ClientSession } from 'mongoose';\r\nimport type { Logger, HRMConfig, SingleTenantConfig } from '../types.js';\r\nimport { getLogger } from '../utils/logger.js';\r\nimport { HRM_CONFIG, mergeConfig } from '../config.js';\r\n\r\n// ============================================================================\r\n// Container Types\r\n// ============================================================================\r\n\r\nexport interface ModelsContainer {\r\n EmployeeModel: Model<any>;\r\n PayrollRecordModel: Model<any>;\r\n TransactionModel: Model<any>;\r\n AttendanceModel?: Model<any> | null;\r\n}\r\n\r\nexport interface ContainerConfig {\r\n models: ModelsContainer;\r\n config?: Partial<HRMConfig>;\r\n singleTenant?: SingleTenantConfig | null;\r\n logger?: Logger;\r\n}\r\n\r\n// ============================================================================\r\n// Container Class\r\n// ============================================================================\r\n\r\nexport class Container {\r\n private static instance: Container | null = null;\r\n \r\n private _models: ModelsContainer | null = null;\r\n private _config: HRMConfig = HRM_CONFIG;\r\n private _singleTenant: SingleTenantConfig | null = null;\r\n private _logger: Logger;\r\n private _initialized = false;\r\n\r\n private constructor() {\r\n this._logger = getLogger();\r\n }\r\n\r\n /**\r\n * Get singleton instance\r\n */\r\n static getInstance(): Container {\r\n if (!Container.instance) {\r\n Container.instance = new Container();\r\n }\r\n return Container.instance;\r\n }\r\n\r\n /**\r\n * Reset instance (for testing)\r\n */\r\n static resetInstance(): void {\r\n Container.instance = null;\r\n }\r\n\r\n /**\r\n * Initialize container with configuration\r\n */\r\n initialize(config: ContainerConfig): void {\r\n if (this._initialized) {\r\n this._logger.warn('Container already initialized, re-initializing');\r\n }\r\n\r\n this._models = config.models;\r\n this._config = mergeConfig(config.config);\r\n this._singleTenant = config.singleTenant ?? null;\r\n \r\n if (config.logger) {\r\n this._logger = config.logger;\r\n }\r\n\r\n this._initialized = true;\r\n\r\n this._logger.info('Container initialized', {\r\n hasEmployeeModel: !!this._models.EmployeeModel,\r\n hasPayrollRecordModel: !!this._models.PayrollRecordModel,\r\n hasTransactionModel: !!this._models.TransactionModel,\r\n hasAttendanceModel: !!this._models.AttendanceModel,\r\n isSingleTenant: !!this._singleTenant,\r\n });\r\n }\r\n\r\n /**\r\n * Check if container is initialized\r\n */\r\n isInitialized(): boolean {\r\n return this._initialized;\r\n }\r\n\r\n /**\r\n * Ensure container is initialized\r\n */\r\n private ensureInitialized(): void {\r\n if (!this._initialized || !this._models) {\r\n throw new Error(\r\n 'Payroll not initialized. Call Payroll.initialize() first.'\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Get models container\r\n */\r\n getModels(): ModelsContainer {\r\n this.ensureInitialized();\r\n return this._models!;\r\n }\r\n\r\n /**\r\n * Get Employee model\r\n */\r\n getEmployeeModel(): Model<any> {\r\n this.ensureInitialized();\r\n return this._models!.EmployeeModel;\r\n }\r\n\r\n /**\r\n * Get PayrollRecord model\r\n */\r\n getPayrollRecordModel(): Model<any> {\r\n this.ensureInitialized();\r\n return this._models!.PayrollRecordModel;\r\n }\r\n\r\n /**\r\n * Get Transaction model\r\n */\r\n getTransactionModel(): Model<any> {\r\n this.ensureInitialized();\r\n return this._models!.TransactionModel;\r\n }\r\n\r\n /**\r\n * Get Attendance model (optional)\r\n */\r\n getAttendanceModel(): Model<any> | null {\r\n this.ensureInitialized();\r\n return this._models!.AttendanceModel ?? null;\r\n }\r\n\r\n /**\r\n * Get configuration\r\n */\r\n getConfig(): HRMConfig {\r\n return this._config;\r\n }\r\n\r\n /**\r\n * Get specific config section\r\n */\r\n getConfigSection<K extends keyof HRMConfig>(section: K): HRMConfig[K] {\r\n return this._config[section];\r\n }\r\n\r\n /**\r\n * Check if single-tenant mode\r\n */\r\n isSingleTenant(): boolean {\r\n return !!this._singleTenant;\r\n }\r\n\r\n /**\r\n * Get single-tenant config\r\n */\r\n getSingleTenantConfig(): SingleTenantConfig | null {\r\n return this._singleTenant;\r\n }\r\n\r\n /**\r\n * Get organization ID (for single-tenant mode)\r\n */\r\n getOrganizationId(): string | null {\r\n if (!this._singleTenant || !this._singleTenant.organizationId) return null;\r\n return typeof this._singleTenant.organizationId === 'string'\r\n ? this._singleTenant.organizationId\r\n : this._singleTenant.organizationId.toString();\r\n }\r\n\r\n /**\r\n * Get logger\r\n */\r\n getLogger(): Logger {\r\n return this._logger;\r\n }\r\n\r\n /**\r\n * Set logger\r\n */\r\n setLogger(logger: Logger): void {\r\n this._logger = logger;\r\n }\r\n\r\n /**\r\n * Has attendance integration\r\n */\r\n hasAttendanceIntegration(): boolean {\r\n return (\r\n !!this._models?.AttendanceModel &&\r\n this._config.payroll.attendanceIntegration\r\n );\r\n }\r\n\r\n /**\r\n * Create operation context with defaults\r\n */\r\n createOperationContext(\r\n overrides?: Partial<{\r\n userId: string;\r\n userName: string;\r\n userRole: string;\r\n organizationId: string;\r\n session: ClientSession;\r\n }>\r\n ): {\r\n userId?: string;\r\n userName?: string;\r\n userRole?: string;\r\n organizationId?: string;\r\n session?: ClientSession;\r\n } {\r\n const context: Record<string, unknown> = {};\r\n\r\n // Auto-inject organizationId in single-tenant mode\r\n if (this._singleTenant?.autoInject && !overrides?.organizationId) {\r\n context.organizationId = this.getOrganizationId();\r\n }\r\n\r\n return { ...context, ...overrides };\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// Convenience Functions\r\n// ============================================================================\r\n\r\n/**\r\n * Get container instance\r\n */\r\nexport function getContainer(): Container {\r\n return Container.getInstance();\r\n}\r\n\r\n/**\r\n * Initialize container\r\n */\r\nexport function initializeContainer(config: ContainerConfig): void {\r\n Container.getInstance().initialize(config);\r\n}\r\n\r\n/**\r\n * Check if container is initialized\r\n */\r\nexport function isContainerInitialized(): boolean {\r\n return Container.getInstance().isInitialized();\r\n}\r\n\r\n/**\r\n * Get models from container\r\n */\r\nexport function getModels(): ModelsContainer {\r\n return Container.getInstance().getModels();\r\n}\r\n\r\n/**\r\n * Get config from container\r\n */\r\nexport function getConfig(): HRMConfig {\r\n return Container.getInstance().getConfig();\r\n}\r\n\r\n/**\r\n * Check if single-tenant mode\r\n */\r\nexport function isSingleTenant(): boolean {\r\n return Container.getInstance().isSingleTenant();\r\n}\r\n\r\n","/**\r\n * @classytic/payroll - Configuration & Calculation Utilities\r\n *\r\n * DESIGN PRINCIPLES:\r\n * 1. Accept data, don't manage it\r\n * 2. Pure functions - easy to test, no side effects\r\n * 3. Smart defaults that work out of the box\r\n * 4. Override at operation time when needed\r\n *\r\n * The payroll package CALCULATES, it doesn't STORE calendars/holidays.\r\n * Your app manages that data and passes it when needed.\r\n */\r\n\r\n// ============================================================================\r\n// Types\r\n// ============================================================================\r\n\r\n/** Work schedule configuration */\r\nexport interface WorkSchedule {\r\n /** Working days (0=Sun, 1=Mon, ..., 6=Sat). Default: Mon-Fri */\r\n workDays: number[];\r\n /** Hours per work day. Default: 8 */\r\n hoursPerDay: number;\r\n}\r\n\r\n/** Options passed when processing payroll */\r\nexport interface PayrollProcessingOptions {\r\n /** Holidays in this period (from YOUR app's holiday model) */\r\n holidays?: Date[];\r\n /** Override work schedule for this operation */\r\n workSchedule?: Partial<WorkSchedule>;\r\n /** Skip tax calculation */\r\n skipTax?: boolean;\r\n /** Skip proration (pay full amount regardless of hire/termination date) */\r\n skipProration?: boolean;\r\n /** Skip attendance deduction */\r\n skipAttendance?: boolean;\r\n}\r\n\r\n/** Working days calculation result */\r\nexport interface WorkingDaysResult {\r\n /** Total calendar days in period */\r\n totalDays: number;\r\n /** Working days (excluding weekends and holidays) */\r\n workingDays: number;\r\n /** Weekend days */\r\n weekends: number;\r\n /** Holiday count */\r\n holidays: number;\r\n}\r\n\r\n/** Proration calculation result */\r\nexport interface ProrationResult {\r\n /** Proration ratio (0-1) */\r\n ratio: number;\r\n /** Reason for proration */\r\n reason: 'full' | 'new_hire' | 'termination' | 'both';\r\n /** Whether salary should be prorated */\r\n isProrated: boolean;\r\n}\r\n\r\n/** Tax calculation result */\r\nexport interface TaxResult {\r\n /** Tax amount */\r\n amount: number;\r\n /** Effective tax rate */\r\n effectiveRate: number;\r\n}\r\n\r\n/** Attendance data (from YOUR attendance system) */\r\nexport interface AttendanceInput {\r\n /** Expected work days in period */\r\n expectedDays: number;\r\n /** Actual days worked */\r\n actualDays: number;\r\n}\r\n\r\n/** Complete salary calculation result */\r\nexport interface SalaryCalculationResult {\r\n /** Original base salary */\r\n baseSalary: number;\r\n /** Prorated base salary */\r\n proratedBase: number;\r\n /** Total allowances */\r\n totalAllowances: number;\r\n /** Total deductions (excluding tax) */\r\n totalDeductions: number;\r\n /** Attendance deduction */\r\n attendanceDeduction: number;\r\n /** Gross salary (prorated base + allowances) */\r\n grossSalary: number;\r\n /** Tax amount */\r\n taxAmount: number;\r\n /** Net salary (gross - all deductions - tax) */\r\n netSalary: number;\r\n /** Proration details */\r\n proration: ProrationResult;\r\n /** Working days details */\r\n workingDays: WorkingDaysResult;\r\n /** Itemized breakdown */\r\n breakdown: {\r\n allowances: Array<{ type: string; amount: number; taxable: boolean }>;\r\n deductions: Array<{ type: string; amount: number }>;\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// Country Defaults\r\n// ============================================================================\r\n\r\nexport const COUNTRY_DEFAULTS: Record<string, {\r\n currency: string;\r\n workDays: number[];\r\n taxBrackets: Array<{ min: number; max: number; rate: number }>;\r\n}> = {\r\n US: {\r\n currency: 'USD',\r\n workDays: [1, 2, 3, 4, 5], // Mon-Fri\r\n taxBrackets: [\r\n { min: 0, max: 11000, rate: 0.10 },\r\n { min: 11000, max: 44725, rate: 0.12 },\r\n { min: 44725, max: 95375, rate: 0.22 },\r\n { min: 95375, max: 182100, rate: 0.24 },\r\n { min: 182100, max: Infinity, rate: 0.32 },\r\n ],\r\n },\r\n BD: {\r\n currency: 'BDT',\r\n workDays: [0, 1, 2, 3, 4], // Sun-Thu\r\n taxBrackets: [\r\n { min: 0, max: 350000, rate: 0 },\r\n { min: 350000, max: 450000, rate: 0.05 },\r\n { min: 450000, max: 750000, rate: 0.10 },\r\n { min: 750000, max: 1150000, rate: 0.15 },\r\n { min: 1150000, max: Infinity, rate: 0.20 },\r\n ],\r\n },\r\n UK: {\r\n currency: 'GBP',\r\n workDays: [1, 2, 3, 4, 5],\r\n taxBrackets: [\r\n { min: 0, max: 12570, rate: 0 },\r\n { min: 12570, max: 50270, rate: 0.20 },\r\n { min: 50270, max: 125140, rate: 0.40 },\r\n { min: 125140, max: Infinity, rate: 0.45 },\r\n ],\r\n },\r\n IN: {\r\n currency: 'INR',\r\n workDays: [1, 2, 3, 4, 5, 6], // Mon-Sat\r\n taxBrackets: [\r\n { min: 0, max: 300000, rate: 0 },\r\n { min: 300000, max: 600000, rate: 0.05 },\r\n { min: 600000, max: 900000, rate: 0.10 },\r\n { min: 900000, max: 1200000, rate: 0.15 },\r\n { min: 1200000, max: Infinity, rate: 0.20 },\r\n ],\r\n },\r\n};\r\n\r\n// ============================================================================\r\n// Default Configuration\r\n// ============================================================================\r\n\r\nexport const DEFAULT_WORK_SCHEDULE: WorkSchedule = {\r\n workDays: [1, 2, 3, 4, 5], // Monday to Friday\r\n hoursPerDay: 8,\r\n};\r\n\r\nexport const DEFAULT_TAX_BRACKETS = COUNTRY_DEFAULTS.US.taxBrackets;\r\n\r\n// ============================================================================\r\n// Pure Calculation Functions\r\n// ============================================================================\r\n\r\n/**\r\n * Count working days in a date range\r\n *\r\n * @example\r\n * const result = countWorkingDays(\r\n * new Date('2024-03-01'),\r\n * new Date('2024-03-31'),\r\n * { workDays: [1,2,3,4,5], holidays: companyHolidays }\r\n * );\r\n */\r\nexport function countWorkingDays(\r\n startDate: Date,\r\n endDate: Date,\r\n options: {\r\n workDays?: number[];\r\n holidays?: Date[];\r\n } = {}\r\n): WorkingDaysResult {\r\n const workDays = options.workDays || DEFAULT_WORK_SCHEDULE.workDays;\r\n const holidaySet = new Set(\r\n (options.holidays || []).map(d => new Date(d).toDateString())\r\n );\r\n\r\n let totalDays = 0;\r\n let workingDays = 0;\r\n let holidays = 0;\r\n let weekends = 0;\r\n\r\n const current = new Date(startDate);\r\n current.setHours(0, 0, 0, 0);\r\n const end = new Date(endDate);\r\n end.setHours(0, 0, 0, 0);\r\n\r\n while (current <= end) {\r\n totalDays++;\r\n const isHoliday = holidaySet.has(current.toDateString());\r\n const isWorkDay = workDays.includes(current.getDay());\r\n\r\n if (isHoliday) {\r\n holidays++;\r\n } else if (isWorkDay) {\r\n workingDays++;\r\n } else {\r\n weekends++;\r\n }\r\n\r\n current.setDate(current.getDate() + 1);\r\n }\r\n\r\n return { totalDays, workingDays, weekends, holidays };\r\n}\r\n\r\n/**\r\n * Calculate proration ratio for partial months\r\n *\r\n * @example\r\n * const proration = calculateProration(\r\n * employee.hireDate,\r\n * employee.terminationDate,\r\n * periodStart,\r\n * periodEnd\r\n * );\r\n */\r\nexport function calculateProration(\r\n hireDate: Date,\r\n terminationDate: Date | null | undefined,\r\n periodStart: Date,\r\n periodEnd: Date\r\n): ProrationResult {\r\n const hire = new Date(hireDate);\r\n hire.setHours(0, 0, 0, 0);\r\n const term = terminationDate ? new Date(terminationDate) : null;\r\n if (term) term.setHours(0, 0, 0, 0);\r\n const start = new Date(periodStart);\r\n start.setHours(0, 0, 0, 0);\r\n const end = new Date(periodEnd);\r\n end.setHours(0, 0, 0, 0);\r\n\r\n // Employee not active in this period\r\n if (hire > end || (term && term < start)) {\r\n return { ratio: 0, reason: 'full', isProrated: true };\r\n }\r\n\r\n // Effective dates within the period\r\n const effectiveStart = hire > start ? hire : start;\r\n const effectiveEnd = term && term < end ? term : end;\r\n\r\n // Calculate days\r\n const totalDays = Math.ceil((end.getTime() - start.getTime()) / 86400000) + 1;\r\n const actualDays = Math.ceil((effectiveEnd.getTime() - effectiveStart.getTime()) / 86400000) + 1;\r\n const ratio = Math.min(1, Math.max(0, actualDays / totalDays));\r\n\r\n // Determine reason\r\n const isNewHire = hire > start;\r\n const isTermination = term !== null && term < end;\r\n \r\n let reason: ProrationResult['reason'] = 'full';\r\n if (isNewHire && isTermination) {\r\n reason = 'both';\r\n } else if (isNewHire) {\r\n reason = 'new_hire';\r\n } else if (isTermination) {\r\n reason = 'termination';\r\n }\r\n\r\n return { ratio, reason, isProrated: ratio < 1 };\r\n}\r\n\r\n/**\r\n * Calculate tax using brackets (annualized)\r\n *\r\n * @example\r\n * const tax = calculateTax(monthlyIncome, 'USD');\r\n */\r\nexport function calculateTax(\r\n monthlyIncome: number,\r\n currency: string,\r\n customBrackets?: Array<{ min: number; max: number; rate: number }>\r\n): TaxResult {\r\n const brackets = customBrackets || COUNTRY_DEFAULTS[currency]?.taxBrackets || DEFAULT_TAX_BRACKETS;\r\n \r\n // Annualize for bracket calculation\r\n const annualIncome = monthlyIncome * 12;\r\n let annualTax = 0;\r\n\r\n for (const bracket of brackets) {\r\n if (annualIncome <= bracket.min) continue;\r\n const taxableInBracket = Math.min(annualIncome, bracket.max) - bracket.min;\r\n annualTax += taxableInBracket * bracket.rate;\r\n }\r\n\r\n const monthlyTax = Math.round(annualTax / 12);\r\n const effectiveRate = monthlyIncome > 0 ? monthlyTax / monthlyIncome : 0;\r\n\r\n return { amount: monthlyTax, effectiveRate };\r\n}\r\n\r\n/**\r\n * Calculate attendance deduction\r\n *\r\n * @example\r\n * const deduction = calculateAttendanceDeduction(22, 20, dailyRate);\r\n */\r\nexport function calculateAttendanceDeduction(\r\n expectedDays: number,\r\n actualDays: number,\r\n dailyRate: number,\r\n maxDeductionPercent = 100\r\n): number {\r\n const absentDays = Math.max(0, expectedDays - actualDays);\r\n const deduction = Math.round(absentDays * dailyRate);\r\n const maxDeduction = Math.round((dailyRate * expectedDays * maxDeductionPercent) / 100);\r\n return Math.min(deduction, maxDeduction);\r\n}\r\n\r\n/**\r\n * Calculate complete salary breakdown\r\n *\r\n * This is the main function for salary calculation.\r\n * Pass all data from YOUR app, get back complete breakdown.\r\n *\r\n * @example\r\n * const result = calculateSalaryBreakdown({\r\n * baseSalary: 100000,\r\n * currency: 'USD',\r\n * hireDate: employee.hireDate,\r\n * terminationDate: employee.terminationDate,\r\n * periodStart: new Date('2024-03-01'),\r\n * periodEnd: new Date('2024-03-31'),\r\n * allowances: [{ type: 'housing', amount: 20000, taxable: true }],\r\n * deductions: [{ type: 'provident_fund', amount: 5000 }],\r\n * options: { holidays: companyHolidays },\r\n * attendance: { expectedDays: 22, actualDays: 20 },\r\n * });\r\n */\r\nexport function calculateSalaryBreakdown(params: {\r\n baseSalary: number;\r\n currency: string;\r\n hireDate: Date;\r\n terminationDate?: Date | null;\r\n periodStart: Date;\r\n periodEnd: Date;\r\n allowances?: Array<{ type: string; amount: number; taxable?: boolean }>;\r\n deductions?: Array<{ type: string; amount: number }>;\r\n options?: PayrollProcessingOptions;\r\n attendance?: AttendanceInput;\r\n}): SalaryCalculationResult {\r\n const {\r\n baseSalary,\r\n currency,\r\n hireDate,\r\n terminationDate,\r\n periodStart,\r\n periodEnd,\r\n allowances = [],\r\n deductions = [],\r\n options = {},\r\n attendance,\r\n } = params;\r\n\r\n // 1. Calculate working days\r\n const workSchedule = { ...DEFAULT_WORK_SCHEDULE, ...options.workSchedule };\r\n const workingDays = countWorkingDays(periodStart, periodEnd, {\r\n workDays: workSchedule.workDays,\r\n holidays: options.holidays,\r\n });\r\n\r\n // 2. Calculate proration\r\n const proration = options.skipProration\r\n ? { ratio: 1, reason: 'full' as const, isProrated: false }\r\n : calculateProration(hireDate, terminationDate, periodStart, periodEnd);\r\n\r\n // 3. Prorate base salary\r\n const proratedBase = Math.round(baseSalary * proration.ratio);\r\n\r\n // 4. Process allowances (prorate)\r\n const processedAllowances = allowances.map(a => ({\r\n type: a.type,\r\n amount: Math.round(a.amount * proration.ratio),\r\n taxable: a.taxable ?? true,\r\n }));\r\n const totalAllowances = processedAllowances.reduce((sum, a) => sum + a.amount, 0);\r\n\r\n // 5. Process deductions (prorate)\r\n const processedDeductions = deductions.map(d => ({\r\n type: d.type,\r\n amount: Math.round(d.amount * proration.ratio),\r\n }));\r\n\r\n // 6. Attendance deduction\r\n let attendanceDeduction = 0;\r\n if (attendance && !options.skipAttendance && workingDays.workingDays > 0) {\r\n const dailyRate = proratedBase / workingDays.workingDays;\r\n attendanceDeduction = calculateAttendanceDeduction(\r\n attendance.expectedDays,\r\n attendance.actualDays,\r\n dailyRate\r\n );\r\n if (attendanceDeduction > 0) {\r\n processedDeductions.push({ type: 'attendance', amount: attendanceDeduction });\r\n }\r\n }\r\n\r\n // 7. Calculate gross salary\r\n const grossSalary = proratedBase + totalAllowances;\r\n\r\n // 8. Calculate tax\r\n let taxAmount = 0;\r\n if (!options.skipTax) {\r\n const taxableAllowances = processedAllowances\r\n .filter(a => a.taxable)\r\n .reduce((sum, a) => sum + a.amount, 0);\r\n const taxableIncome = proratedBase + taxableAllowances;\r\n const taxResult = calculateTax(taxableIncome, currency);\r\n taxAmount = taxResult.amount;\r\n if (taxAmount > 0) {\r\n processedDeductions.push({ type: 'tax', amount: taxAmount });\r\n }\r\n }\r\n\r\n // 9. Calculate net salary\r\n const totalDeductions = processedDeductions\r\n .filter(d => d.type !== 'tax' && d.type !== 'attendance')\r\n .reduce((sum, d) => sum + d.amount, 0);\r\n const netSalary = grossSalary - totalDeductions - attendanceDeduction - taxAmount;\r\n\r\n return {\r\n baseSalary,\r\n proratedBase,\r\n totalAllowances,\r\n totalDeductions,\r\n attendanceDeduction,\r\n grossSalary,\r\n taxAmount,\r\n netSalary,\r\n proration,\r\n workingDays,\r\n breakdown: {\r\n allowances: processedAllowances,\r\n deductions: processedDeductions,\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Get pay period dates for a given month\r\n *\r\n * @example\r\n * const period = getPayPeriod(3, 2024); // March 2024\r\n */\r\nexport function getPayPeriod(\r\n month: number,\r\n year: number,\r\n payDay = 28\r\n): { startDate: Date; endDate: Date; payDate: Date } {\r\n const startDate = new Date(year, month - 1, 1);\r\n const endDate = new Date(year, month, 0); // Last day of month\r\n const payDate = new Date(year, month - 1, Math.min(payDay, endDate.getDate()));\r\n return { startDate, endDate, payDate };\r\n}\r\n\r\n"]}
|