hvp-shared 6.69.0 → 6.70.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.
@@ -20,3 +20,4 @@ export * from './qvet-cash-flow.enums';
20
20
  export * from './time-off.enums';
21
21
  export * from './time-off.constants';
22
22
  export * from './hris.constants';
23
+ export * from './payroll-features.constants';
@@ -36,3 +36,4 @@ __exportStar(require("./qvet-cash-flow.enums"), exports);
36
36
  __exportStar(require("./time-off.enums"), exports);
37
37
  __exportStar(require("./time-off.constants"), exports);
38
38
  __exportStar(require("./hris.constants"), exports);
39
+ __exportStar(require("./payroll-features.constants"), exports);
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Payroll Features by Employment Type (GH#204)
3
+ *
4
+ * Defines which payroll calculation features each employment type supports
5
+ * and how legal concepts are renamed for hourly-based types.
6
+ *
7
+ * Used by:
8
+ * - Backend: payroll calculation engine (which items to include)
9
+ * - Frontend: payroll estimate UI (which fields to show/hide)
10
+ */
11
+ import { EmploymentType } from "./employment.enums";
12
+ /**
13
+ * Hourly-based types use non-legal denomination for certain concepts
14
+ * to avoid labor law implications (prima → apoyo, aguinaldo → apoyo de fin de año).
15
+ */
16
+ export declare function isHourlyBasedType(type: EmploymentType): boolean;
17
+ /**
18
+ * Salary-based types use legal denomination (prima dominical, aguinaldo, etc.)
19
+ * and are eligible for full tax calculation (ISR).
20
+ */
21
+ export declare function isSalaryBasedType(type: EmploymentType): boolean;
22
+ /**
23
+ * Payroll calculation features that can be toggled per employment type.
24
+ *
25
+ * Note: hasImss and hasCfdi are driven by the employment's config flags
26
+ * (hasImss, payrollStampingMode), NOT hardcoded here.
27
+ */
28
+ export interface PayrollFeatures {
29
+ /** Base pay: salary (halfWeekFixedIncome) or hourly (hours × rate) */
30
+ usesHourlyBasePay: boolean;
31
+ /** Attendance-based deductions (absences, tardiness, unworked hours) */
32
+ hasAttendanceDiscounts: boolean;
33
+ /** Punctuality bonus (salary types only) */
34
+ hasPunctualityBonus: boolean;
35
+ /** Overtime: simple, double, triple (salary types only) */
36
+ hasOvertime: boolean;
37
+ /** Guaranteed income top-up */
38
+ hasGuaranteedIncome: boolean;
39
+ /** ISR tax withholding */
40
+ hasIsr: boolean;
41
+ /** Aguinaldo / apoyo de fin de año */
42
+ hasAguinaldo: boolean;
43
+ /** PTU (profit sharing) */
44
+ hasPtu: boolean;
45
+ /** Legal concept names renamed to non-legal ("apoyo") denomination */
46
+ usesRenamedConcepts: boolean;
47
+ /** Generates a real payroll (as opposed to only nominal) */
48
+ generatesRealPayroll: boolean;
49
+ }
50
+ export declare const PAYROLL_FEATURES: Record<EmploymentType, PayrollFeatures>;
51
+ /**
52
+ * Payroll concept keys that have different labels depending on whether
53
+ * the employment type is salary-based (legal terms) or hourly-based (non-legal).
54
+ *
55
+ * Hourly-based types use "apoyo" denomination to avoid labor law implications.
56
+ */
57
+ export declare const PAYROLL_CONCEPT_LABELS: Record<string, {
58
+ salary: string;
59
+ hourly: string;
60
+ }>;
61
+ /**
62
+ * Get the display label for a payroll concept based on employment type.
63
+ *
64
+ * @param conceptKey - Key from PAYROLL_CONCEPT_LABELS (e.g., "sundayBonus")
65
+ * @param employmentType - The employment type to determine denomination
66
+ * @returns The correct Spanish label for this concept
67
+ */
68
+ export declare function getPayrollConceptLabel(conceptKey: string, employmentType: EmploymentType): string;
@@ -0,0 +1,159 @@
1
+ "use strict";
2
+ /**
3
+ * Payroll Features by Employment Type (GH#204)
4
+ *
5
+ * Defines which payroll calculation features each employment type supports
6
+ * and how legal concepts are renamed for hourly-based types.
7
+ *
8
+ * Used by:
9
+ * - Backend: payroll calculation engine (which items to include)
10
+ * - Frontend: payroll estimate UI (which fields to show/hide)
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.PAYROLL_CONCEPT_LABELS = exports.PAYROLL_FEATURES = void 0;
14
+ exports.isHourlyBasedType = isHourlyBasedType;
15
+ exports.isSalaryBasedType = isSalaryBasedType;
16
+ exports.getPayrollConceptLabel = getPayrollConceptLabel;
17
+ const employment_enums_1 = require("./employment.enums");
18
+ // ─── Employment Type Classification Helpers ──────────────────────────────────
19
+ /**
20
+ * Hourly-based types use non-legal denomination for certain concepts
21
+ * to avoid labor law implications (prima → apoyo, aguinaldo → apoyo de fin de año).
22
+ */
23
+ function isHourlyBasedType(type) {
24
+ return (type === employment_enums_1.EmploymentType.hourly_agreed ||
25
+ type === employment_enums_1.EmploymentType.casual ||
26
+ type === employment_enums_1.EmploymentType.intern);
27
+ }
28
+ /**
29
+ * Salary-based types use legal denomination (prima dominical, aguinaldo, etc.)
30
+ * and are eligible for full tax calculation (ISR).
31
+ */
32
+ function isSalaryBasedType(type) {
33
+ return (type === employment_enums_1.EmploymentType.payroll ||
34
+ type === employment_enums_1.EmploymentType.payroll_draft);
35
+ }
36
+ exports.PAYROLL_FEATURES = {
37
+ [employment_enums_1.EmploymentType.payroll]: {
38
+ usesHourlyBasePay: false,
39
+ hasAttendanceDiscounts: true,
40
+ hasPunctualityBonus: true,
41
+ hasOvertime: true,
42
+ hasGuaranteedIncome: true,
43
+ hasIsr: true,
44
+ hasAguinaldo: true,
45
+ hasPtu: true,
46
+ usesRenamedConcepts: false,
47
+ generatesRealPayroll: true,
48
+ },
49
+ [employment_enums_1.EmploymentType.payroll_draft]: {
50
+ usesHourlyBasePay: false,
51
+ hasAttendanceDiscounts: true,
52
+ hasPunctualityBonus: true,
53
+ hasOvertime: true,
54
+ hasGuaranteedIncome: true,
55
+ hasIsr: false,
56
+ hasAguinaldo: true,
57
+ hasPtu: true,
58
+ usesRenamedConcepts: false,
59
+ generatesRealPayroll: true,
60
+ },
61
+ [employment_enums_1.EmploymentType.hourly_agreed]: {
62
+ usesHourlyBasePay: true,
63
+ hasAttendanceDiscounts: true,
64
+ hasPunctualityBonus: false,
65
+ hasOvertime: false,
66
+ hasGuaranteedIncome: false,
67
+ hasIsr: false,
68
+ hasAguinaldo: true,
69
+ hasPtu: true,
70
+ usesRenamedConcepts: true,
71
+ generatesRealPayroll: true,
72
+ },
73
+ [employment_enums_1.EmploymentType.casual]: {
74
+ usesHourlyBasePay: true,
75
+ hasAttendanceDiscounts: false,
76
+ hasPunctualityBonus: false,
77
+ hasOvertime: false,
78
+ hasGuaranteedIncome: false,
79
+ hasIsr: false,
80
+ hasAguinaldo: true,
81
+ hasPtu: true,
82
+ usesRenamedConcepts: true,
83
+ generatesRealPayroll: true,
84
+ },
85
+ [employment_enums_1.EmploymentType.intern]: {
86
+ usesHourlyBasePay: true,
87
+ hasAttendanceDiscounts: false,
88
+ hasPunctualityBonus: false,
89
+ hasOvertime: false,
90
+ hasGuaranteedIncome: false,
91
+ hasIsr: false,
92
+ hasAguinaldo: true,
93
+ hasPtu: true,
94
+ usesRenamedConcepts: true,
95
+ generatesRealPayroll: true,
96
+ },
97
+ [employment_enums_1.EmploymentType.coverage_only]: {
98
+ usesHourlyBasePay: false,
99
+ hasAttendanceDiscounts: false,
100
+ hasPunctualityBonus: false,
101
+ hasOvertime: false,
102
+ hasGuaranteedIncome: false,
103
+ hasIsr: false,
104
+ hasAguinaldo: false,
105
+ hasPtu: false,
106
+ usesRenamedConcepts: false,
107
+ generatesRealPayroll: false,
108
+ },
109
+ [employment_enums_1.EmploymentType.contractor]: {
110
+ usesHourlyBasePay: false,
111
+ hasAttendanceDiscounts: false,
112
+ hasPunctualityBonus: false,
113
+ hasOvertime: false,
114
+ hasGuaranteedIncome: false,
115
+ hasIsr: false,
116
+ hasAguinaldo: false,
117
+ hasPtu: false,
118
+ usesRenamedConcepts: false,
119
+ generatesRealPayroll: false,
120
+ },
121
+ };
122
+ // ─── Payroll Concept Denomination ───────────────────────────────────────────
123
+ /**
124
+ * Payroll concept keys that have different labels depending on whether
125
+ * the employment type is salary-based (legal terms) or hourly-based (non-legal).
126
+ *
127
+ * Hourly-based types use "apoyo" denomination to avoid labor law implications.
128
+ */
129
+ exports.PAYROLL_CONCEPT_LABELS = {
130
+ sundayBonus: {
131
+ salary: "Prima dominical",
132
+ hourly: "Apoyo dominical",
133
+ },
134
+ holidayOrRestExtraPay: {
135
+ salary: "Pago extra por día festivo",
136
+ hourly: "Apoyo por día festivo",
137
+ },
138
+ vacationBonus: {
139
+ salary: "Prima vacacional",
140
+ hourly: "Apoyo vacacional",
141
+ },
142
+ endYearBonus: {
143
+ salary: "Aguinaldo",
144
+ hourly: "Apoyo de fin de año",
145
+ },
146
+ };
147
+ /**
148
+ * Get the display label for a payroll concept based on employment type.
149
+ *
150
+ * @param conceptKey - Key from PAYROLL_CONCEPT_LABELS (e.g., "sundayBonus")
151
+ * @param employmentType - The employment type to determine denomination
152
+ * @returns The correct Spanish label for this concept
153
+ */
154
+ function getPayrollConceptLabel(conceptKey, employmentType) {
155
+ const entry = exports.PAYROLL_CONCEPT_LABELS[conceptKey];
156
+ if (!entry)
157
+ return conceptKey;
158
+ return isHourlyBasedType(employmentType) ? entry.hourly : entry.salary;
159
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hvp-shared",
3
- "version": "6.69.0",
3
+ "version": "6.70.0",
4
4
  "description": "Shared types and utilities for HVP backend and frontend",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",