@accounter/server 0.0.9-alpha-20251217093036-7168648b507d62946aa287af4ea690b73b077b2d → 0.0.9-alpha-20251217131153-65f961a4072436d7f1042ea8ea4d96534cb3650e
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -8
- package/dist/server/src/modules/charges-matcher/__tests__/auto-match-integration.test.js +45 -122
- package/dist/server/src/modules/charges-matcher/__tests__/auto-match-integration.test.js.map +1 -1
- package/dist/server/src/modules/charges-matcher/__tests__/auto-match.test.js +45 -29
- package/dist/server/src/modules/charges-matcher/__tests__/auto-match.test.js.map +1 -1
- package/dist/server/src/modules/charges-matcher/__tests__/charge-validator.test.js +2 -11
- package/dist/server/src/modules/charges-matcher/__tests__/charge-validator.test.js.map +1 -1
- package/dist/server/src/modules/charges-matcher/__tests__/date-confidence.test.js +25 -0
- package/dist/server/src/modules/charges-matcher/__tests__/date-confidence.test.js.map +1 -1
- package/dist/server/src/modules/charges-matcher/__tests__/document-aggregator.test.js.map +1 -1
- package/dist/server/src/modules/charges-matcher/__tests__/document-amount.test.js +65 -64
- package/dist/server/src/modules/charges-matcher/__tests__/document-amount.test.js.map +1 -1
- package/dist/server/src/modules/charges-matcher/__tests__/match-scorer.test.js +494 -60
- package/dist/server/src/modules/charges-matcher/__tests__/match-scorer.test.js.map +1 -1
- package/dist/server/src/modules/charges-matcher/__tests__/single-match-integration.test.js +34 -98
- package/dist/server/src/modules/charges-matcher/__tests__/single-match-integration.test.js.map +1 -1
- package/dist/server/src/modules/charges-matcher/__tests__/single-match.test.js +79 -59
- package/dist/server/src/modules/charges-matcher/__tests__/single-match.test.js.map +1 -1
- package/dist/server/src/modules/charges-matcher/helpers/charge-validator.helper.js +6 -4
- package/dist/server/src/modules/charges-matcher/helpers/charge-validator.helper.js.map +1 -1
- package/dist/server/src/modules/charges-matcher/helpers/date-confidence.helper.d.ts +9 -2
- package/dist/server/src/modules/charges-matcher/helpers/date-confidence.helper.js +24 -2
- package/dist/server/src/modules/charges-matcher/helpers/date-confidence.helper.js.map +1 -1
- package/dist/server/src/modules/charges-matcher/helpers/document-amount.helper.d.ts +1 -4
- package/dist/server/src/modules/charges-matcher/helpers/document-amount.helper.js +2 -1
- package/dist/server/src/modules/charges-matcher/helpers/document-amount.helper.js.map +1 -1
- package/dist/server/src/modules/charges-matcher/index.d.ts +0 -1
- package/dist/server/src/modules/charges-matcher/index.js +0 -1
- package/dist/server/src/modules/charges-matcher/index.js.map +1 -1
- package/dist/server/src/modules/charges-matcher/providers/auto-match.provider.d.ts +2 -1
- package/dist/server/src/modules/charges-matcher/providers/auto-match.provider.js +2 -2
- package/dist/server/src/modules/charges-matcher/providers/auto-match.provider.js.map +1 -1
- package/dist/server/src/modules/charges-matcher/providers/charges-matcher.provider.js +2 -2
- package/dist/server/src/modules/charges-matcher/providers/charges-matcher.provider.js.map +1 -1
- package/dist/server/src/modules/charges-matcher/providers/document-aggregator.d.ts +4 -5
- package/dist/server/src/modules/charges-matcher/providers/document-aggregator.js +5 -4
- package/dist/server/src/modules/charges-matcher/providers/document-aggregator.js.map +1 -1
- package/dist/server/src/modules/charges-matcher/providers/match-scorer.provider.d.ts +5 -3
- package/dist/server/src/modules/charges-matcher/providers/match-scorer.provider.js +70 -13
- package/dist/server/src/modules/charges-matcher/providers/match-scorer.provider.js.map +1 -1
- package/dist/server/src/modules/charges-matcher/providers/single-match.provider.d.ts +4 -2
- package/dist/server/src/modules/charges-matcher/providers/single-match.provider.js +15 -7
- package/dist/server/src/modules/charges-matcher/providers/single-match.provider.js.map +1 -1
- package/dist/server/src/modules/charges-matcher/providers/transaction-aggregator.d.ts +1 -1
- package/dist/server/src/modules/charges-matcher/types.d.ts +2 -4
- package/dist/server/src/modules/charges-matcher/types.js.map +1 -1
- package/package.json +2 -2
- package/src/modules/charges-matcher/README.md +14 -3
- package/src/modules/charges-matcher/__tests__/auto-match-integration.test.ts +52 -100
- package/src/modules/charges-matcher/__tests__/auto-match.test.ts +51 -29
- package/src/modules/charges-matcher/__tests__/charge-validator.test.ts +2 -13
- package/src/modules/charges-matcher/__tests__/date-confidence.test.ts +29 -0
- package/src/modules/charges-matcher/__tests__/document-aggregator.test.ts +0 -1
- package/src/modules/charges-matcher/__tests__/document-amount.test.ts +66 -65
- package/src/modules/charges-matcher/__tests__/match-scorer.test.ts +552 -60
- package/src/modules/charges-matcher/__tests__/single-match-integration.test.ts +43 -73
- package/src/modules/charges-matcher/__tests__/single-match.test.ts +81 -59
- package/src/modules/charges-matcher/documentation/SPEC.md +276 -4
- package/src/modules/charges-matcher/helpers/charge-validator.helper.ts +7 -5
- package/src/modules/charges-matcher/helpers/date-confidence.helper.ts +32 -2
- package/src/modules/charges-matcher/helpers/document-amount.helper.ts +2 -12
- package/src/modules/charges-matcher/index.ts +0 -1
- package/src/modules/charges-matcher/providers/auto-match.provider.ts +5 -3
- package/src/modules/charges-matcher/providers/charges-matcher.provider.ts +8 -2
- package/src/modules/charges-matcher/providers/document-aggregator.ts +12 -11
- package/src/modules/charges-matcher/providers/match-scorer.provider.ts +97 -17
- package/src/modules/charges-matcher/providers/single-match.provider.ts +21 -8
- package/src/modules/charges-matcher/providers/transaction-aggregator.ts +1 -1
- package/src/modules/charges-matcher/types.ts +2 -5
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest';
|
|
2
2
|
import {
|
|
3
3
|
normalizeDocumentAmount,
|
|
4
|
-
type DocumentType,
|
|
5
4
|
} from '../helpers/document-amount.helper.js';
|
|
6
5
|
|
|
6
|
+
import { DocumentType } from '../../../shared/enums.js';
|
|
7
|
+
|
|
7
8
|
describe('Document Amount Normalization', () => {
|
|
8
9
|
describe('INVOICE - Business is Debtor (User is Creditor)', () => {
|
|
9
10
|
it('should return positive amount when business is debtor', () => {
|
|
10
11
|
// Business owes user (user is creditor, business is debtor)
|
|
11
|
-
const result = normalizeDocumentAmount(100, false,
|
|
12
|
+
const result = normalizeDocumentAmount(100, false, DocumentType.Invoice);
|
|
12
13
|
expect(result).toBe(100);
|
|
13
14
|
});
|
|
14
15
|
|
|
15
16
|
it('should handle decimal amounts', () => {
|
|
16
|
-
const result = normalizeDocumentAmount(150.75, false,
|
|
17
|
+
const result = normalizeDocumentAmount(150.75, false, DocumentType.Invoice);
|
|
17
18
|
expect(result).toBe(150.75);
|
|
18
19
|
});
|
|
19
20
|
|
|
20
21
|
it('should handle large amounts', () => {
|
|
21
|
-
const result = normalizeDocumentAmount(1000000, false,
|
|
22
|
+
const result = normalizeDocumentAmount(1000000, false, DocumentType.Invoice);
|
|
22
23
|
expect(result).toBe(1000000);
|
|
23
24
|
});
|
|
24
25
|
});
|
|
@@ -26,17 +27,17 @@ describe('Document Amount Normalization', () => {
|
|
|
26
27
|
describe('INVOICE - Business is Creditor (User is Debtor)', () => {
|
|
27
28
|
it('should return negative amount when business is creditor', () => {
|
|
28
29
|
// User owes business (user is debtor, business is creditor)
|
|
29
|
-
const result = normalizeDocumentAmount(100, true,
|
|
30
|
+
const result = normalizeDocumentAmount(100, true, DocumentType.Invoice);
|
|
30
31
|
expect(result).toBe(-100);
|
|
31
32
|
});
|
|
32
33
|
|
|
33
34
|
it('should handle decimal amounts', () => {
|
|
34
|
-
const result = normalizeDocumentAmount(250.50, true,
|
|
35
|
+
const result = normalizeDocumentAmount(250.50, true, DocumentType.Invoice);
|
|
35
36
|
expect(result).toBe(-250.50);
|
|
36
37
|
});
|
|
37
38
|
|
|
38
39
|
it('should handle large amounts', () => {
|
|
39
|
-
const result = normalizeDocumentAmount(5000000, true,
|
|
40
|
+
const result = normalizeDocumentAmount(5000000, true, DocumentType.Invoice);
|
|
40
41
|
expect(result).toBe(-5000000);
|
|
41
42
|
});
|
|
42
43
|
});
|
|
@@ -44,17 +45,17 @@ describe('Document Amount Normalization', () => {
|
|
|
44
45
|
describe('CREDIT_INVOICE - Business is Debtor (User is Creditor)', () => {
|
|
45
46
|
it('should return negative amount for credit invoice with business debtor', () => {
|
|
46
47
|
// Credit invoice: user owes refund to business (opposite of regular invoice)
|
|
47
|
-
const result = normalizeDocumentAmount(100, false,
|
|
48
|
+
const result = normalizeDocumentAmount(100, false, DocumentType.CreditInvoice);
|
|
48
49
|
expect(result).toBe(-100);
|
|
49
50
|
});
|
|
50
51
|
|
|
51
52
|
it('should handle decimal amounts', () => {
|
|
52
|
-
const result = normalizeDocumentAmount(75.25, false,
|
|
53
|
+
const result = normalizeDocumentAmount(75.25, false, DocumentType.CreditInvoice);
|
|
53
54
|
expect(result).toBe(-75.25);
|
|
54
55
|
});
|
|
55
56
|
|
|
56
57
|
it('should handle large amounts', () => {
|
|
57
|
-
const result = normalizeDocumentAmount(2000000, false,
|
|
58
|
+
const result = normalizeDocumentAmount(2000000, false, DocumentType.CreditInvoice);
|
|
58
59
|
expect(result).toBe(-2000000);
|
|
59
60
|
});
|
|
60
61
|
});
|
|
@@ -62,101 +63,101 @@ describe('Document Amount Normalization', () => {
|
|
|
62
63
|
describe('CREDIT_INVOICE - Business is Creditor (User is Debtor)', () => {
|
|
63
64
|
it('should return positive amount for credit invoice with business creditor (double negation)', () => {
|
|
64
65
|
// Credit invoice: business owes refund to user (double negation: -1 * -1 = 1)
|
|
65
|
-
const result = normalizeDocumentAmount(100, true,
|
|
66
|
+
const result = normalizeDocumentAmount(100, true, DocumentType.CreditInvoice);
|
|
66
67
|
expect(result).toBe(100);
|
|
67
68
|
});
|
|
68
69
|
|
|
69
70
|
it('should handle decimal amounts', () => {
|
|
70
|
-
const result = normalizeDocumentAmount(125.99, true,
|
|
71
|
+
const result = normalizeDocumentAmount(125.99, true, DocumentType.CreditInvoice);
|
|
71
72
|
expect(result).toBe(125.99);
|
|
72
73
|
});
|
|
73
74
|
|
|
74
75
|
it('should handle large amounts', () => {
|
|
75
|
-
const result = normalizeDocumentAmount(3000000, true,
|
|
76
|
+
const result = normalizeDocumentAmount(3000000, true, DocumentType.CreditInvoice);
|
|
76
77
|
expect(result).toBe(3000000);
|
|
77
78
|
});
|
|
78
79
|
});
|
|
79
80
|
|
|
80
81
|
describe('RECEIPT - Business is Debtor (User is Creditor)', () => {
|
|
81
82
|
it('should return positive amount when business is debtor', () => {
|
|
82
|
-
const result = normalizeDocumentAmount(100, false,
|
|
83
|
+
const result = normalizeDocumentAmount(100, false, DocumentType.Receipt);
|
|
83
84
|
expect(result).toBe(100);
|
|
84
85
|
});
|
|
85
86
|
|
|
86
87
|
it('should handle typical receipt amounts', () => {
|
|
87
|
-
const result = normalizeDocumentAmount(49.99, false,
|
|
88
|
+
const result = normalizeDocumentAmount(49.99, false, DocumentType.Receipt);
|
|
88
89
|
expect(result).toBe(49.99);
|
|
89
90
|
});
|
|
90
91
|
});
|
|
91
92
|
|
|
92
93
|
describe('RECEIPT - Business is Creditor (User is Debtor)', () => {
|
|
93
94
|
it('should return negative amount when business is creditor', () => {
|
|
94
|
-
const result = normalizeDocumentAmount(100, true,
|
|
95
|
+
const result = normalizeDocumentAmount(100, true, DocumentType.Receipt);
|
|
95
96
|
expect(result).toBe(-100);
|
|
96
97
|
});
|
|
97
98
|
|
|
98
99
|
it('should handle typical receipt amounts', () => {
|
|
99
|
-
const result = normalizeDocumentAmount(89.50, true,
|
|
100
|
+
const result = normalizeDocumentAmount(89.50, true, DocumentType.Receipt);
|
|
100
101
|
expect(result).toBe(-89.50);
|
|
101
102
|
});
|
|
102
103
|
});
|
|
103
104
|
|
|
104
105
|
describe('INVOICE_RECEIPT - Business is Debtor (User is Creditor)', () => {
|
|
105
106
|
it('should return positive amount when business is debtor', () => {
|
|
106
|
-
const result = normalizeDocumentAmount(100, false,
|
|
107
|
+
const result = normalizeDocumentAmount(100, false, DocumentType.InvoiceReceipt);
|
|
107
108
|
expect(result).toBe(100);
|
|
108
109
|
});
|
|
109
110
|
|
|
110
111
|
it('should handle combined invoice-receipt amounts', () => {
|
|
111
|
-
const result = normalizeDocumentAmount(350.00, false,
|
|
112
|
+
const result = normalizeDocumentAmount(350.00, false, DocumentType.InvoiceReceipt);
|
|
112
113
|
expect(result).toBe(350.00);
|
|
113
114
|
});
|
|
114
115
|
});
|
|
115
116
|
|
|
116
117
|
describe('INVOICE_RECEIPT - Business is Creditor (User is Debtor)', () => {
|
|
117
118
|
it('should return negative amount when business is creditor', () => {
|
|
118
|
-
const result = normalizeDocumentAmount(100, true,
|
|
119
|
+
const result = normalizeDocumentAmount(100, true, DocumentType.InvoiceReceipt);
|
|
119
120
|
expect(result).toBe(-100);
|
|
120
121
|
});
|
|
121
122
|
|
|
122
123
|
it('should handle combined invoice-receipt amounts', () => {
|
|
123
|
-
const result = normalizeDocumentAmount(425.75, true,
|
|
124
|
+
const result = normalizeDocumentAmount(425.75, true, DocumentType.InvoiceReceipt);
|
|
124
125
|
expect(result).toBe(-425.75);
|
|
125
126
|
});
|
|
126
127
|
});
|
|
127
128
|
|
|
128
129
|
describe('OTHER Document Type', () => {
|
|
129
130
|
it('should handle OTHER type with business debtor', () => {
|
|
130
|
-
const result = normalizeDocumentAmount(100, false,
|
|
131
|
+
const result = normalizeDocumentAmount(100, false, DocumentType.Other);
|
|
131
132
|
expect(result).toBe(100);
|
|
132
133
|
});
|
|
133
134
|
|
|
134
135
|
it('should handle OTHER type with business creditor', () => {
|
|
135
|
-
const result = normalizeDocumentAmount(100, true,
|
|
136
|
+
const result = normalizeDocumentAmount(100, true, DocumentType.Other);
|
|
136
137
|
expect(result).toBe(-100);
|
|
137
138
|
});
|
|
138
139
|
});
|
|
139
140
|
|
|
140
141
|
describe('PROFORMA Document Type', () => {
|
|
141
142
|
it('should handle PROFORMA type with business debtor', () => {
|
|
142
|
-
const result = normalizeDocumentAmount(100, false,
|
|
143
|
+
const result = normalizeDocumentAmount(100, false, DocumentType.Proforma);
|
|
143
144
|
expect(result).toBe(100);
|
|
144
145
|
});
|
|
145
146
|
|
|
146
147
|
it('should handle PROFORMA type with business creditor', () => {
|
|
147
|
-
const result = normalizeDocumentAmount(100, true,
|
|
148
|
+
const result = normalizeDocumentAmount(100, true, DocumentType.Proforma);
|
|
148
149
|
expect(result).toBe(-100);
|
|
149
150
|
});
|
|
150
151
|
});
|
|
151
152
|
|
|
152
153
|
describe('UNPROCESSED Document Type', () => {
|
|
153
154
|
it('should handle UNPROCESSED type with business debtor', () => {
|
|
154
|
-
const result = normalizeDocumentAmount(100, false,
|
|
155
|
+
const result = normalizeDocumentAmount(100, false, DocumentType.Unprocessed);
|
|
155
156
|
expect(result).toBe(100);
|
|
156
157
|
});
|
|
157
158
|
|
|
158
159
|
it('should handle UNPROCESSED type with business creditor', () => {
|
|
159
|
-
const result = normalizeDocumentAmount(100, true,
|
|
160
|
+
const result = normalizeDocumentAmount(100, true, DocumentType.Unprocessed);
|
|
160
161
|
expect(result).toBe(-100);
|
|
161
162
|
});
|
|
162
163
|
});
|
|
@@ -164,58 +165,58 @@ describe('Document Amount Normalization', () => {
|
|
|
164
165
|
describe('Negative Input Amounts (Absolute Value First)', () => {
|
|
165
166
|
it('should convert negative input to positive for INVOICE with business debtor', () => {
|
|
166
167
|
// Input is -100, should become |−100| = 100
|
|
167
|
-
const result = normalizeDocumentAmount(-100, false,
|
|
168
|
+
const result = normalizeDocumentAmount(-100, false, DocumentType.Invoice);
|
|
168
169
|
expect(result).toBe(100);
|
|
169
170
|
});
|
|
170
171
|
|
|
171
172
|
it('should convert negative input to negative for INVOICE with business creditor', () => {
|
|
172
173
|
// Input is -100, should become |−100| * -1 = -100
|
|
173
|
-
const result = normalizeDocumentAmount(-100, true,
|
|
174
|
+
const result = normalizeDocumentAmount(-100, true, DocumentType.Invoice);
|
|
174
175
|
expect(result).toBe(-100);
|
|
175
176
|
});
|
|
176
177
|
|
|
177
178
|
it('should convert negative input for CREDIT_INVOICE with business debtor', () => {
|
|
178
179
|
// Input is -100, should become |−100| * -1 = -100
|
|
179
|
-
const result = normalizeDocumentAmount(-100, false,
|
|
180
|
+
const result = normalizeDocumentAmount(-100, false, DocumentType.CreditInvoice);
|
|
180
181
|
expect(result).toBe(-100);
|
|
181
182
|
});
|
|
182
183
|
|
|
183
184
|
it('should convert negative input for CREDIT_INVOICE with business creditor', () => {
|
|
184
185
|
// Input is -100, should become |−100| * -1 * -1 = 100
|
|
185
|
-
const result = normalizeDocumentAmount(-100, true,
|
|
186
|
+
const result = normalizeDocumentAmount(-100, true, DocumentType.CreditInvoice);
|
|
186
187
|
expect(result).toBe(100);
|
|
187
188
|
});
|
|
188
189
|
|
|
189
190
|
it('should handle negative decimal amounts', () => {
|
|
190
|
-
const result = normalizeDocumentAmount(-250.50, false,
|
|
191
|
+
const result = normalizeDocumentAmount(-250.50, false, DocumentType.Invoice);
|
|
191
192
|
expect(result).toBe(250.50);
|
|
192
193
|
});
|
|
193
194
|
|
|
194
195
|
it('should handle large negative amounts', () => {
|
|
195
|
-
const result = normalizeDocumentAmount(-1000000, true,
|
|
196
|
+
const result = normalizeDocumentAmount(-1000000, true, DocumentType.Receipt);
|
|
196
197
|
expect(result).toBe(-1000000);
|
|
197
198
|
});
|
|
198
199
|
});
|
|
199
200
|
|
|
200
201
|
describe('Zero Amounts', () => {
|
|
201
202
|
it('should handle zero amount with business debtor', () => {
|
|
202
|
-
const result = normalizeDocumentAmount(0, false,
|
|
203
|
+
const result = normalizeDocumentAmount(0, false, DocumentType.Invoice);
|
|
203
204
|
expect(result).toBe(0);
|
|
204
205
|
});
|
|
205
206
|
|
|
206
207
|
it('should handle zero amount with business creditor', () => {
|
|
207
|
-
const result = normalizeDocumentAmount(0, true,
|
|
208
|
+
const result = normalizeDocumentAmount(0, true, DocumentType.Invoice);
|
|
208
209
|
expect(result).toBe(-0); // JavaScript has -0, but 0 === -0 is true
|
|
209
210
|
});
|
|
210
211
|
|
|
211
212
|
it('should handle zero for CREDIT_INVOICE', () => {
|
|
212
|
-
const result = normalizeDocumentAmount(0, false,
|
|
213
|
+
const result = normalizeDocumentAmount(0, false, DocumentType.CreditInvoice);
|
|
213
214
|
expect(result).toBe(-0);
|
|
214
215
|
});
|
|
215
216
|
|
|
216
217
|
it('should verify zero equality regardless of sign', () => {
|
|
217
|
-
const result1 = normalizeDocumentAmount(0, false,
|
|
218
|
-
const result2 = normalizeDocumentAmount(0, true,
|
|
218
|
+
const result1 = normalizeDocumentAmount(0, false, DocumentType.Invoice);
|
|
219
|
+
const result2 = normalizeDocumentAmount(0, true, DocumentType.Invoice);
|
|
219
220
|
expect(result1).toBe(0);
|
|
220
221
|
// In JavaScript, -0 and 0 are loosely equal but Object.is distinguishes them
|
|
221
222
|
// For our purposes, they are functionally equivalent
|
|
@@ -226,42 +227,42 @@ describe('Document Amount Normalization', () => {
|
|
|
226
227
|
describe('Very Large Amounts', () => {
|
|
227
228
|
it('should handle very large positive amounts', () => {
|
|
228
229
|
const largeAmount = 999999999.99;
|
|
229
|
-
const result = normalizeDocumentAmount(largeAmount, false,
|
|
230
|
+
const result = normalizeDocumentAmount(largeAmount, false, DocumentType.Invoice);
|
|
230
231
|
expect(result).toBe(largeAmount);
|
|
231
232
|
});
|
|
232
233
|
|
|
233
234
|
it('should handle very large amounts with creditor negation', () => {
|
|
234
235
|
const largeAmount = 999999999.99;
|
|
235
|
-
const result = normalizeDocumentAmount(largeAmount, true,
|
|
236
|
+
const result = normalizeDocumentAmount(largeAmount, true, DocumentType.Invoice);
|
|
236
237
|
expect(result).toBe(-largeAmount);
|
|
237
238
|
});
|
|
238
239
|
|
|
239
240
|
it('should handle very large amounts with CREDIT_INVOICE', () => {
|
|
240
241
|
const largeAmount = 888888888.88;
|
|
241
|
-
const result = normalizeDocumentAmount(largeAmount, true,
|
|
242
|
+
const result = normalizeDocumentAmount(largeAmount, true, DocumentType.CreditInvoice);
|
|
242
243
|
expect(result).toBe(largeAmount);
|
|
243
244
|
});
|
|
244
245
|
|
|
245
246
|
it('should handle maximum safe integer', () => {
|
|
246
247
|
const maxSafe = Number.MAX_SAFE_INTEGER;
|
|
247
|
-
const result = normalizeDocumentAmount(maxSafe, false,
|
|
248
|
+
const result = normalizeDocumentAmount(maxSafe, false, DocumentType.Invoice);
|
|
248
249
|
expect(result).toBe(maxSafe);
|
|
249
250
|
});
|
|
250
251
|
});
|
|
251
252
|
|
|
252
253
|
describe('Small Decimal Amounts', () => {
|
|
253
254
|
it('should handle very small decimal amounts', () => {
|
|
254
|
-
const result = normalizeDocumentAmount(0.01, false,
|
|
255
|
+
const result = normalizeDocumentAmount(0.01, false, DocumentType.Invoice);
|
|
255
256
|
expect(result).toBe(0.01);
|
|
256
257
|
});
|
|
257
258
|
|
|
258
259
|
it('should handle fractional cents', () => {
|
|
259
|
-
const result = normalizeDocumentAmount(0.001, true,
|
|
260
|
+
const result = normalizeDocumentAmount(0.001, true, DocumentType.Receipt);
|
|
260
261
|
expect(result).toBe(-0.001);
|
|
261
262
|
});
|
|
262
263
|
|
|
263
264
|
it('should preserve precision for small decimals', () => {
|
|
264
|
-
const result = normalizeDocumentAmount(1.23456789, false,
|
|
265
|
+
const result = normalizeDocumentAmount(1.23456789, false, DocumentType.Invoice);
|
|
265
266
|
expect(result).toBe(1.23456789);
|
|
266
267
|
});
|
|
267
268
|
});
|
|
@@ -277,32 +278,32 @@ describe('Document Amount Normalization', () => {
|
|
|
277
278
|
description: string;
|
|
278
279
|
}> = [
|
|
279
280
|
// INVOICE
|
|
280
|
-
{ type:
|
|
281
|
-
{ type:
|
|
281
|
+
{ type: DocumentType.Invoice, isCreditor: false, input: 100, expected: 100, description: 'INVOICE, business debtor' },
|
|
282
|
+
{ type: DocumentType.Invoice, isCreditor: true, input: 100, expected: -100, description: 'INVOICE, business creditor' },
|
|
282
283
|
|
|
283
284
|
// CREDIT_INVOICE
|
|
284
|
-
{ type:
|
|
285
|
-
{ type:
|
|
285
|
+
{ type: DocumentType.CreditInvoice, isCreditor: false, input: 100, expected: -100, description: 'CREDIT_INVOICE, business debtor' },
|
|
286
|
+
{ type: DocumentType.CreditInvoice, isCreditor: true, input: 100, expected: 100, description: 'CREDIT_INVOICE, business creditor (double neg)' },
|
|
286
287
|
|
|
287
288
|
// RECEIPT
|
|
288
|
-
{ type:
|
|
289
|
-
{ type:
|
|
289
|
+
{ type: DocumentType.Receipt, isCreditor: false, input: 100, expected: 100, description: 'RECEIPT, business debtor' },
|
|
290
|
+
{ type: DocumentType.Receipt, isCreditor: true, input: 100, expected: -100, description: 'RECEIPT, business creditor' },
|
|
290
291
|
|
|
291
292
|
// INVOICE_RECEIPT
|
|
292
|
-
{ type:
|
|
293
|
-
{ type:
|
|
293
|
+
{ type: DocumentType.InvoiceReceipt, isCreditor: false, input: 100, expected: 100, description: 'INVOICE_RECEIPT, business debtor' },
|
|
294
|
+
{ type: DocumentType.InvoiceReceipt, isCreditor: true, input: 100, expected: -100, description: 'INVOICE_RECEIPT, business creditor' },
|
|
294
295
|
|
|
295
296
|
// OTHER
|
|
296
|
-
{ type:
|
|
297
|
-
{ type:
|
|
297
|
+
{ type: DocumentType.Other, isCreditor: false, input: 100, expected: 100, description: 'OTHER, business debtor' },
|
|
298
|
+
{ type: DocumentType.Other, isCreditor: true, input: 100, expected: -100, description: 'OTHER, business creditor' },
|
|
298
299
|
|
|
299
300
|
// PROFORMA
|
|
300
|
-
{ type:
|
|
301
|
-
{ type:
|
|
301
|
+
{ type: DocumentType.Proforma, isCreditor: false, input: 100, expected: 100, description: 'PROFORMA, business debtor' },
|
|
302
|
+
{ type: DocumentType.Proforma, isCreditor: true, input: 100, expected: -100, description: 'PROFORMA, business creditor' },
|
|
302
303
|
|
|
303
304
|
// UNPROCESSED
|
|
304
|
-
{ type:
|
|
305
|
-
{ type:
|
|
305
|
+
{ type: DocumentType.Unprocessed, isCreditor: false, input: 100, expected: 100, description: 'UNPROCESSED, business debtor' },
|
|
306
|
+
{ type: DocumentType.Unprocessed, isCreditor: true, input: 100, expected: -100, description: 'UNPROCESSED, business creditor' },
|
|
306
307
|
];
|
|
307
308
|
|
|
308
309
|
testCases.forEach(({ type, isCreditor, input, expected, description }) => {
|
|
@@ -315,37 +316,37 @@ describe('Document Amount Normalization', () => {
|
|
|
315
316
|
describe('Real-World Scenarios', () => {
|
|
316
317
|
it('should normalize customer invoice (business sends invoice to customer)', () => {
|
|
317
318
|
// Business is creditor (customer owes business)
|
|
318
|
-
const result = normalizeDocumentAmount(1500, true,
|
|
319
|
+
const result = normalizeDocumentAmount(1500, true, DocumentType.Invoice);
|
|
319
320
|
expect(result).toBe(-1500); // Negative because user owes
|
|
320
321
|
});
|
|
321
322
|
|
|
322
323
|
it('should normalize vendor invoice (vendor sends invoice to business)', () => {
|
|
323
324
|
// Business is debtor (business owes vendor)
|
|
324
|
-
const result = normalizeDocumentAmount(750, false,
|
|
325
|
+
const result = normalizeDocumentAmount(750, false, DocumentType.Invoice);
|
|
325
326
|
expect(result).toBe(750); // Positive because vendor owes user
|
|
326
327
|
});
|
|
327
328
|
|
|
328
329
|
it('should normalize customer refund (credit invoice to customer)', () => {
|
|
329
330
|
// Business owes customer a refund
|
|
330
|
-
const result = normalizeDocumentAmount(200, true,
|
|
331
|
+
const result = normalizeDocumentAmount(200, true, DocumentType.CreditInvoice);
|
|
331
332
|
expect(result).toBe(200); // Positive because business owes refund
|
|
332
333
|
});
|
|
333
334
|
|
|
334
335
|
it('should normalize vendor credit note (credit invoice from vendor)', () => {
|
|
335
336
|
// Vendor gives credit note to business
|
|
336
|
-
const result = normalizeDocumentAmount(150, false,
|
|
337
|
+
const result = normalizeDocumentAmount(150, false, DocumentType.CreditInvoice);
|
|
337
338
|
expect(result).toBe(-150); // Negative because business owes vendor less now
|
|
338
339
|
});
|
|
339
340
|
|
|
340
341
|
it('should normalize payment receipt from customer', () => {
|
|
341
342
|
// Customer pays business
|
|
342
|
-
const result = normalizeDocumentAmount(500, true,
|
|
343
|
+
const result = normalizeDocumentAmount(500, true, DocumentType.Receipt);
|
|
343
344
|
expect(result).toBe(-500); // Negative because customer paid
|
|
344
345
|
});
|
|
345
346
|
|
|
346
347
|
it('should normalize payment receipt to vendor', () => {
|
|
347
348
|
// Business pays vendor
|
|
348
|
-
const result = normalizeDocumentAmount(300, false,
|
|
349
|
+
const result = normalizeDocumentAmount(300, false, DocumentType.Receipt);
|
|
349
350
|
expect(result).toBe(300); // Positive because business paid
|
|
350
351
|
});
|
|
351
352
|
});
|