@ksefnik/core 0.0.1
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/LICENSE +21 -0
- package/dist/bank/auto-detect.d.ts +3 -0
- package/dist/bank/auto-detect.d.ts.map +1 -0
- package/dist/bank/auto-detect.js +29 -0
- package/dist/bank/auto-detect.js.map +1 -0
- package/dist/bank/index.d.ts +10 -0
- package/dist/bank/index.d.ts.map +1 -0
- package/dist/bank/index.js +20 -0
- package/dist/bank/index.js.map +1 -0
- package/dist/bank/nip-extractor.d.ts +3 -0
- package/dist/bank/nip-extractor.d.ts.map +1 -0
- package/dist/bank/nip-extractor.js +36 -0
- package/dist/bank/nip-extractor.js.map +1 -0
- package/dist/bank/parsers/csv-base.d.ts +4 -0
- package/dist/bank/parsers/csv-base.d.ts.map +1 -0
- package/dist/bank/parsers/csv-base.js +48 -0
- package/dist/bank/parsers/csv-base.js.map +1 -0
- package/dist/bank/parsers/index.d.ts +8 -0
- package/dist/bank/parsers/index.d.ts.map +1 -0
- package/dist/bank/parsers/index.js +21 -0
- package/dist/bank/parsers/index.js.map +1 -0
- package/dist/bank/parsers/ing.parser.d.ts +7 -0
- package/dist/bank/parsers/ing.parser.d.ts.map +1 -0
- package/dist/bank/parsers/ing.parser.js +43 -0
- package/dist/bank/parsers/ing.parser.js.map +1 -0
- package/dist/bank/parsers/mbank.parser.d.ts +7 -0
- package/dist/bank/parsers/mbank.parser.d.ts.map +1 -0
- package/dist/bank/parsers/mbank.parser.js +39 -0
- package/dist/bank/parsers/mbank.parser.js.map +1 -0
- package/dist/bank/parsers/mt940.parser.d.ts +7 -0
- package/dist/bank/parsers/mt940.parser.d.ts.map +1 -0
- package/dist/bank/parsers/mt940.parser.js +57 -0
- package/dist/bank/parsers/mt940.parser.js.map +1 -0
- package/dist/bank/parsers/pko.parser.d.ts +7 -0
- package/dist/bank/parsers/pko.parser.d.ts.map +1 -0
- package/dist/bank/parsers/pko.parser.js +38 -0
- package/dist/bank/parsers/pko.parser.js.map +1 -0
- package/dist/bank/parsers/santander.parser.d.ts +7 -0
- package/dist/bank/parsers/santander.parser.d.ts.map +1 -0
- package/dist/bank/parsers/santander.parser.js +46 -0
- package/dist/bank/parsers/santander.parser.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/ksef/cache.d.ts +12 -0
- package/dist/ksef/cache.d.ts.map +1 -0
- package/dist/ksef/cache.js +36 -0
- package/dist/ksef/cache.js.map +1 -0
- package/dist/ksef/index.d.ts +6 -0
- package/dist/ksef/index.d.ts.map +1 -0
- package/dist/ksef/index.js +5 -0
- package/dist/ksef/index.js.map +1 -0
- package/dist/ksef/ksef.adapter.d.ts +16 -0
- package/dist/ksef/ksef.adapter.d.ts.map +1 -0
- package/dist/ksef/ksef.adapter.js +81 -0
- package/dist/ksef/ksef.adapter.js.map +1 -0
- package/dist/ksef/retry.d.ts +7 -0
- package/dist/ksef/retry.d.ts.map +1 -0
- package/dist/ksef/retry.js +41 -0
- package/dist/ksef/retry.js.map +1 -0
- package/dist/ksef/session.d.ts +16 -0
- package/dist/ksef/session.d.ts.map +1 -0
- package/dist/ksef/session.js +39 -0
- package/dist/ksef/session.js.map +1 -0
- package/dist/ksef/types.d.ts +56 -0
- package/dist/ksef/types.d.ts.map +1 -0
- package/dist/ksef/types.js +2 -0
- package/dist/ksef/types.js.map +1 -0
- package/dist/ksefnik.d.ts +51 -0
- package/dist/ksefnik.d.ts.map +1 -0
- package/dist/ksefnik.js +104 -0
- package/dist/ksefnik.js.map +1 -0
- package/dist/matching/context.d.ts +5 -0
- package/dist/matching/context.d.ts.map +1 -0
- package/dist/matching/context.js +19 -0
- package/dist/matching/context.js.map +1 -0
- package/dist/matching/index.d.ts +6 -0
- package/dist/matching/index.d.ts.map +1 -0
- package/dist/matching/index.js +6 -0
- package/dist/matching/index.js.map +1 -0
- package/dist/matching/passes/exact.pass.d.ts +3 -0
- package/dist/matching/passes/exact.pass.d.ts.map +1 -0
- package/dist/matching/passes/exact.pass.js +34 -0
- package/dist/matching/passes/exact.pass.js.map +1 -0
- package/dist/matching/passes/fuzzy.pass.d.ts +3 -0
- package/dist/matching/passes/fuzzy.pass.d.ts.map +1 -0
- package/dist/matching/passes/fuzzy.pass.js +40 -0
- package/dist/matching/passes/fuzzy.pass.js.map +1 -0
- package/dist/matching/passes/index.d.ts +9 -0
- package/dist/matching/passes/index.d.ts.map +1 -0
- package/dist/matching/passes/index.js +21 -0
- package/dist/matching/passes/index.js.map +1 -0
- package/dist/matching/passes/invoice-ref.pass.d.ts +3 -0
- package/dist/matching/passes/invoice-ref.pass.d.ts.map +1 -0
- package/dist/matching/passes/invoice-ref.pass.js +32 -0
- package/dist/matching/passes/invoice-ref.pass.js.map +1 -0
- package/dist/matching/passes/ksef-ref.pass.d.ts +3 -0
- package/dist/matching/passes/ksef-ref.pass.d.ts.map +1 -0
- package/dist/matching/passes/ksef-ref.pass.js +25 -0
- package/dist/matching/passes/ksef-ref.pass.js.map +1 -0
- package/dist/matching/passes/partial.pass.d.ts +3 -0
- package/dist/matching/passes/partial.pass.d.ts.map +1 -0
- package/dist/matching/passes/partial.pass.js +55 -0
- package/dist/matching/passes/partial.pass.js.map +1 -0
- package/dist/matching/passes/proximity.pass.d.ts +3 -0
- package/dist/matching/passes/proximity.pass.d.ts.map +1 -0
- package/dist/matching/passes/proximity.pass.js +49 -0
- package/dist/matching/passes/proximity.pass.js.map +1 -0
- package/dist/matching/pipeline.d.ts +3 -0
- package/dist/matching/pipeline.d.ts.map +1 -0
- package/dist/matching/pipeline.js +76 -0
- package/dist/matching/pipeline.js.map +1 -0
- package/dist/matching/scoring.d.ts +5 -0
- package/dist/matching/scoring.d.ts.map +1 -0
- package/dist/matching/scoring.js +28 -0
- package/dist/matching/scoring.js.map +1 -0
- package/dist/plugins/index.d.ts +3 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +3 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/loader.d.ts +3 -0
- package/dist/plugins/loader.d.ts.map +1 -0
- package/dist/plugins/loader.js +13 -0
- package/dist/plugins/loader.js.map +1 -0
- package/dist/plugins/registry.d.ts +8 -0
- package/dist/plugins/registry.d.ts.map +1 -0
- package/dist/plugins/registry.js +15 -0
- package/dist/plugins/registry.js.map +1 -0
- package/dist/storage/in-memory.storage.d.ts +13 -0
- package/dist/storage/in-memory.storage.d.ts.map +1 -0
- package/dist/storage/in-memory.storage.js +57 -0
- package/dist/storage/in-memory.storage.js.map +1 -0
- package/dist/storage/index.d.ts +3 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +3 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/sqlite.storage.d.ts +13 -0
- package/dist/storage/sqlite.storage.d.ts.map +1 -0
- package/dist/storage/sqlite.storage.js +225 -0
- package/dist/storage/sqlite.storage.js.map +1 -0
- package/dist/validation/engine.d.ts +10 -0
- package/dist/validation/engine.d.ts.map +1 -0
- package/dist/validation/engine.js +19 -0
- package/dist/validation/engine.js.map +1 -0
- package/dist/validation/index.d.ts +6 -0
- package/dist/validation/index.d.ts.map +1 -0
- package/dist/validation/index.js +4 -0
- package/dist/validation/index.js.map +1 -0
- package/dist/validation/rule.d.ts +17 -0
- package/dist/validation/rule.d.ts.map +1 -0
- package/dist/validation/rule.js +2 -0
- package/dist/validation/rule.js.map +1 -0
- package/dist/validation/rules/amount-max.d.ts +3 -0
- package/dist/validation/rules/amount-max.d.ts.map +1 -0
- package/dist/validation/rules/amount-max.js +14 -0
- package/dist/validation/rules/amount-max.js.map +1 -0
- package/dist/validation/rules/amount-positive.d.ts +3 -0
- package/dist/validation/rules/amount-positive.d.ts.map +1 -0
- package/dist/validation/rules/amount-positive.js +13 -0
- package/dist/validation/rules/amount-positive.js.map +1 -0
- package/dist/validation/rules/buyer-nip-format.d.ts +3 -0
- package/dist/validation/rules/buyer-nip-format.d.ts.map +1 -0
- package/dist/validation/rules/buyer-nip-format.js +16 -0
- package/dist/validation/rules/buyer-nip-format.js.map +1 -0
- package/dist/validation/rules/currency-valid.d.ts +3 -0
- package/dist/validation/rules/currency-valid.d.ts.map +1 -0
- package/dist/validation/rules/currency-valid.js +13 -0
- package/dist/validation/rules/currency-valid.js.map +1 -0
- package/dist/validation/rules/date-not-future.d.ts +3 -0
- package/dist/validation/rules/date-not-future.d.ts.map +1 -0
- package/dist/validation/rules/date-not-future.js +18 -0
- package/dist/validation/rules/date-not-future.js.map +1 -0
- package/dist/validation/rules/date-order.d.ts +3 -0
- package/dist/validation/rules/date-order.d.ts.map +1 -0
- package/dist/validation/rules/date-order.js +15 -0
- package/dist/validation/rules/date-order.js.map +1 -0
- package/dist/validation/rules/date-range.d.ts +3 -0
- package/dist/validation/rules/date-range.d.ts.map +1 -0
- package/dist/validation/rules/date-range.js +18 -0
- package/dist/validation/rules/date-range.js.map +1 -0
- package/dist/validation/rules/date-valid.d.ts +3 -0
- package/dist/validation/rules/date-valid.d.ts.map +1 -0
- package/dist/validation/rules/date-valid.js +15 -0
- package/dist/validation/rules/date-valid.js.map +1 -0
- package/dist/validation/rules/description-length.d.ts +3 -0
- package/dist/validation/rules/description-length.d.ts.map +1 -0
- package/dist/validation/rules/description-length.js +19 -0
- package/dist/validation/rules/description-length.js.map +1 -0
- package/dist/validation/rules/duplicate-check.d.ts +3 -0
- package/dist/validation/rules/duplicate-check.d.ts.map +1 -0
- package/dist/validation/rules/duplicate-check.js +17 -0
- package/dist/validation/rules/duplicate-check.js.map +1 -0
- package/dist/validation/rules/index.d.ts +24 -0
- package/dist/validation/rules/index.d.ts.map +1 -0
- package/dist/validation/rules/index.js +44 -0
- package/dist/validation/rules/index.js.map +1 -0
- package/dist/validation/rules/invoice-number-format.d.ts +3 -0
- package/dist/validation/rules/invoice-number-format.d.ts.map +1 -0
- package/dist/validation/rules/invoice-number-format.js +14 -0
- package/dist/validation/rules/invoice-number-format.js.map +1 -0
- package/dist/validation/rules/ksef-reference-format.d.ts +3 -0
- package/dist/validation/rules/ksef-reference-format.d.ts.map +1 -0
- package/dist/validation/rules/ksef-reference-format.js +18 -0
- package/dist/validation/rules/ksef-reference-format.js.map +1 -0
- package/dist/validation/rules/line-items-sum.d.ts +3 -0
- package/dist/validation/rules/line-items-sum.d.ts.map +1 -0
- package/dist/validation/rules/line-items-sum.js +17 -0
- package/dist/validation/rules/line-items-sum.js.map +1 -0
- package/dist/validation/rules/nip-format.d.ts +3 -0
- package/dist/validation/rules/nip-format.d.ts.map +1 -0
- package/dist/validation/rules/nip-format.js +14 -0
- package/dist/validation/rules/nip-format.js.map +1 -0
- package/dist/validation/rules/nip-not-zeros.d.ts +3 -0
- package/dist/validation/rules/nip-not-zeros.d.ts.map +1 -0
- package/dist/validation/rules/nip-not-zeros.js +12 -0
- package/dist/validation/rules/nip-not-zeros.js.map +1 -0
- package/dist/validation/rules/quantity-positive.d.ts +3 -0
- package/dist/validation/rules/quantity-positive.d.ts.map +1 -0
- package/dist/validation/rules/quantity-positive.js +21 -0
- package/dist/validation/rules/quantity-positive.js.map +1 -0
- package/dist/validation/rules/required-fields.d.ts +3 -0
- package/dist/validation/rules/required-fields.d.ts.map +1 -0
- package/dist/validation/rules/required-fields.js +18 -0
- package/dist/validation/rules/required-fields.js.map +1 -0
- package/dist/validation/rules/seller-buyer-different.d.ts +3 -0
- package/dist/validation/rules/seller-buyer-different.d.ts.map +1 -0
- package/dist/validation/rules/seller-buyer-different.js +15 -0
- package/dist/validation/rules/seller-buyer-different.js.map +1 -0
- package/dist/validation/rules/vat-calculation.d.ts +3 -0
- package/dist/validation/rules/vat-calculation.d.ts.map +1 -0
- package/dist/validation/rules/vat-calculation.js +19 -0
- package/dist/validation/rules/vat-calculation.js.map +1 -0
- package/dist/validation/rules/vat-rate-valid.d.ts +3 -0
- package/dist/validation/rules/vat-rate-valid.d.ts.map +1 -0
- package/dist/validation/rules/vat-rate-valid.js +22 -0
- package/dist/validation/rules/vat-rate-valid.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exact.pass.d.ts","sourceRoot":"","sources":["../../../src/matching/passes/exact.pass.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAgC,MAAM,iBAAiB,CAAA;AAGvF,eAAO,MAAM,SAAS,EAAE,kBAkCvB,CAAA"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { extractFirstNIP } from '../../bank/nip-extractor.js';
|
|
2
|
+
export const exactPass = {
|
|
3
|
+
name: 'exact',
|
|
4
|
+
order: 200,
|
|
5
|
+
async run(context) {
|
|
6
|
+
const results = [];
|
|
7
|
+
const usedTxIds = new Set();
|
|
8
|
+
for (const invoice of context.invoices) {
|
|
9
|
+
for (const tx of context.transactions) {
|
|
10
|
+
if (usedTxIds.has(tx.id))
|
|
11
|
+
continue;
|
|
12
|
+
const txAmount = Math.abs(tx.amount);
|
|
13
|
+
if (txAmount !== invoice.grossAmount)
|
|
14
|
+
continue;
|
|
15
|
+
const nip = tx.senderNIP ?? tx.recipientNIP ?? extractFirstNIP(tx.description);
|
|
16
|
+
if (!nip || nip !== invoice.sellerNIP)
|
|
17
|
+
continue;
|
|
18
|
+
results.push({
|
|
19
|
+
invoiceId: invoice.id,
|
|
20
|
+
transactionId: tx.id,
|
|
21
|
+
confidence: 95,
|
|
22
|
+
reasons: [
|
|
23
|
+
`Exact amount match: ${txAmount} grosze`,
|
|
24
|
+
`NIP match: ${nip}`,
|
|
25
|
+
],
|
|
26
|
+
});
|
|
27
|
+
usedTxIds.add(tx.id);
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return results;
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=exact.pass.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exact.pass.js","sourceRoot":"","sources":["../../../src/matching/passes/exact.pass.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAE7D,MAAM,CAAC,MAAM,SAAS,GAAuB;IAC3C,IAAI,EAAE,OAAO;IACb,KAAK,EAAE,GAAG;IAEV,KAAK,CAAC,GAAG,CAAC,OAAwB;QAChC,MAAM,OAAO,GAAkB,EAAE,CAAA;QACjC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAA;QAEnC,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACvC,KAAK,MAAM,EAAE,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;gBACtC,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;oBAAE,SAAQ;gBAElC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,CAAA;gBACpC,IAAI,QAAQ,KAAK,OAAO,CAAC,WAAW;oBAAE,SAAQ;gBAE9C,MAAM,GAAG,GAAG,EAAE,CAAC,SAAS,IAAI,EAAE,CAAC,YAAY,IAAI,eAAe,CAAC,EAAE,CAAC,WAAW,CAAC,CAAA;gBAC9E,IAAI,CAAC,GAAG,IAAI,GAAG,KAAK,OAAO,CAAC,SAAS;oBAAE,SAAQ;gBAE/C,OAAO,CAAC,IAAI,CAAC;oBACX,SAAS,EAAE,OAAO,CAAC,EAAE;oBACrB,aAAa,EAAE,EAAE,CAAC,EAAE;oBACpB,UAAU,EAAE,EAAE;oBACd,OAAO,EAAE;wBACP,uBAAuB,QAAQ,SAAS;wBACxC,cAAc,GAAG,EAAE;qBACpB;iBACF,CAAC,CAAA;gBACF,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;gBACpB,MAAK;YACP,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAA;IAChB,CAAC;CACF,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fuzzy.pass.d.ts","sourceRoot":"","sources":["../../../src/matching/passes/fuzzy.pass.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAgC,MAAM,iBAAiB,CAAA;AAKvF,eAAO,MAAM,SAAS,EAAE,kBAuCvB,CAAA"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ratio } from 'fuzzball';
|
|
2
|
+
const FUZZY_THRESHOLD = 80;
|
|
3
|
+
export const fuzzyPass = {
|
|
4
|
+
name: 'fuzzy',
|
|
5
|
+
order: 400,
|
|
6
|
+
async run(context) {
|
|
7
|
+
const results = [];
|
|
8
|
+
const usedTxIds = new Set();
|
|
9
|
+
for (const invoice of context.invoices) {
|
|
10
|
+
if (!invoice.sellerName)
|
|
11
|
+
continue;
|
|
12
|
+
for (const tx of context.transactions) {
|
|
13
|
+
if (usedTxIds.has(tx.id))
|
|
14
|
+
continue;
|
|
15
|
+
// Amount must match exactly
|
|
16
|
+
if (Math.abs(tx.amount) !== invoice.grossAmount)
|
|
17
|
+
continue;
|
|
18
|
+
const txName = tx.senderName ?? tx.recipientName;
|
|
19
|
+
if (!txName)
|
|
20
|
+
continue;
|
|
21
|
+
const score = ratio(invoice.sellerName, txName);
|
|
22
|
+
if (score >= FUZZY_THRESHOLD) {
|
|
23
|
+
results.push({
|
|
24
|
+
invoiceId: invoice.id,
|
|
25
|
+
transactionId: tx.id,
|
|
26
|
+
confidence: 80,
|
|
27
|
+
reasons: [
|
|
28
|
+
`Fuzzy name match: "${invoice.sellerName}" ~ "${txName}" (score: ${score})`,
|
|
29
|
+
`Exact amount match: ${Math.abs(tx.amount)} grosze`,
|
|
30
|
+
],
|
|
31
|
+
});
|
|
32
|
+
usedTxIds.add(tx.id);
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return results;
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=fuzzy.pass.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fuzzy.pass.js","sourceRoot":"","sources":["../../../src/matching/passes/fuzzy.pass.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAA;AAEhC,MAAM,eAAe,GAAG,EAAE,CAAA;AAE1B,MAAM,CAAC,MAAM,SAAS,GAAuB;IAC3C,IAAI,EAAE,OAAO;IACb,KAAK,EAAE,GAAG;IAEV,KAAK,CAAC,GAAG,CAAC,OAAwB;QAChC,MAAM,OAAO,GAAkB,EAAE,CAAA;QACjC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAA;QAEnC,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACvC,IAAI,CAAC,OAAO,CAAC,UAAU;gBAAE,SAAQ;YAEjC,KAAK,MAAM,EAAE,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;gBACtC,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;oBAAE,SAAQ;gBAElC,4BAA4B;gBAC5B,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,OAAO,CAAC,WAAW;oBAAE,SAAQ;gBAEzD,MAAM,MAAM,GAAG,EAAE,CAAC,UAAU,IAAI,EAAE,CAAC,aAAa,CAAA;gBAChD,IAAI,CAAC,MAAM;oBAAE,SAAQ;gBAErB,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,MAAM,CAAC,CAAA;gBAC/C,IAAI,KAAK,IAAI,eAAe,EAAE,CAAC;oBAC7B,OAAO,CAAC,IAAI,CAAC;wBACX,SAAS,EAAE,OAAO,CAAC,EAAE;wBACrB,aAAa,EAAE,EAAE,CAAC,EAAE;wBACpB,UAAU,EAAE,EAAE;wBACd,OAAO,EAAE;4BACP,sBAAsB,OAAO,CAAC,UAAU,QAAQ,MAAM,aAAa,KAAK,GAAG;4BAC3E,uBAAuB,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS;yBACpD;qBACF,CAAC,CAAA;oBACF,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;oBACpB,MAAK;gBACP,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAA;IAChB,CAAC;CACF,CAAA"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ReconciliationPass } from '@ksefnik/shared';
|
|
2
|
+
export { ksefRefPass } from './ksef-ref.pass.js';
|
|
3
|
+
export { exactPass } from './exact.pass.js';
|
|
4
|
+
export { invoiceRefPass } from './invoice-ref.pass.js';
|
|
5
|
+
export { fuzzyPass } from './fuzzy.pass.js';
|
|
6
|
+
export { partialPass } from './partial.pass.js';
|
|
7
|
+
export { proximityPass } from './proximity.pass.js';
|
|
8
|
+
export declare const defaultPasses: ReconciliationPass[];
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/matching/passes/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAQzD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAEnD,eAAO,MAAM,aAAa,EAAE,kBAAkB,EAOX,CAAA"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ksefRefPass } from './ksef-ref.pass.js';
|
|
2
|
+
import { exactPass } from './exact.pass.js';
|
|
3
|
+
import { invoiceRefPass } from './invoice-ref.pass.js';
|
|
4
|
+
import { fuzzyPass } from './fuzzy.pass.js';
|
|
5
|
+
import { partialPass } from './partial.pass.js';
|
|
6
|
+
import { proximityPass } from './proximity.pass.js';
|
|
7
|
+
export { ksefRefPass } from './ksef-ref.pass.js';
|
|
8
|
+
export { exactPass } from './exact.pass.js';
|
|
9
|
+
export { invoiceRefPass } from './invoice-ref.pass.js';
|
|
10
|
+
export { fuzzyPass } from './fuzzy.pass.js';
|
|
11
|
+
export { partialPass } from './partial.pass.js';
|
|
12
|
+
export { proximityPass } from './proximity.pass.js';
|
|
13
|
+
export const defaultPasses = [
|
|
14
|
+
ksefRefPass,
|
|
15
|
+
exactPass,
|
|
16
|
+
invoiceRefPass,
|
|
17
|
+
fuzzyPass,
|
|
18
|
+
partialPass,
|
|
19
|
+
proximityPass,
|
|
20
|
+
].sort((a, b) => a.order - b.order);
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/matching/passes/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAEnD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAEnD,MAAM,CAAC,MAAM,aAAa,GAAyB;IACjD,WAAW;IACX,SAAS;IACT,cAAc;IACd,SAAS;IACT,WAAW;IACX,aAAa;CACd,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invoice-ref.pass.d.ts","sourceRoot":"","sources":["../../../src/matching/passes/invoice-ref.pass.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAgC,MAAM,iBAAiB,CAAA;AAEvF,eAAO,MAAM,cAAc,EAAE,kBAkC5B,CAAA"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export const invoiceRefPass = {
|
|
2
|
+
name: 'invoice-ref',
|
|
3
|
+
order: 300,
|
|
4
|
+
async run(context) {
|
|
5
|
+
const results = [];
|
|
6
|
+
const usedTxIds = new Set();
|
|
7
|
+
for (const invoice of context.invoices) {
|
|
8
|
+
const ref = invoice.invoiceNumber.toLowerCase();
|
|
9
|
+
for (const tx of context.transactions) {
|
|
10
|
+
if (usedTxIds.has(tx.id))
|
|
11
|
+
continue;
|
|
12
|
+
if (tx.description.toLowerCase().includes(ref)) {
|
|
13
|
+
const amountMatches = Math.abs(tx.amount) === invoice.grossAmount;
|
|
14
|
+
const confidence = amountMatches ? 90 : 75;
|
|
15
|
+
const reasons = [`Invoice number "${invoice.invoiceNumber}" found in transaction description`];
|
|
16
|
+
if (amountMatches)
|
|
17
|
+
reasons.push('Amount also matches');
|
|
18
|
+
results.push({
|
|
19
|
+
invoiceId: invoice.id,
|
|
20
|
+
transactionId: tx.id,
|
|
21
|
+
confidence,
|
|
22
|
+
reasons,
|
|
23
|
+
});
|
|
24
|
+
usedTxIds.add(tx.id);
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return results;
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=invoice-ref.pass.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invoice-ref.pass.js","sourceRoot":"","sources":["../../../src/matching/passes/invoice-ref.pass.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,cAAc,GAAuB;IAChD,IAAI,EAAE,aAAa;IACnB,KAAK,EAAE,GAAG;IAEV,KAAK,CAAC,GAAG,CAAC,OAAwB;QAChC,MAAM,OAAO,GAAkB,EAAE,CAAA;QACjC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAA;QAEnC,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACvC,MAAM,GAAG,GAAG,OAAO,CAAC,aAAa,CAAC,WAAW,EAAE,CAAA;YAE/C,KAAK,MAAM,EAAE,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;gBACtC,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;oBAAE,SAAQ;gBAElC,IAAI,EAAE,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC/C,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,OAAO,CAAC,WAAW,CAAA;oBACjE,MAAM,UAAU,GAAG,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;oBAC1C,MAAM,OAAO,GAAG,CAAC,mBAAmB,OAAO,CAAC,aAAa,oCAAoC,CAAC,CAAA;oBAC9F,IAAI,aAAa;wBAAE,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAA;oBAEtD,OAAO,CAAC,IAAI,CAAC;wBACX,SAAS,EAAE,OAAO,CAAC,EAAE;wBACrB,aAAa,EAAE,EAAE,CAAC,EAAE;wBACpB,UAAU;wBACV,OAAO;qBACR,CAAC,CAAA;oBACF,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;oBACpB,MAAK;gBACP,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAA;IAChB,CAAC;CACF,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ksef-ref.pass.d.ts","sourceRoot":"","sources":["../../../src/matching/passes/ksef-ref.pass.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAgC,MAAM,iBAAiB,CAAA;AAEvF,eAAO,MAAM,WAAW,EAAE,kBA2BzB,CAAA"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export const ksefRefPass = {
|
|
2
|
+
name: 'ksef-ref',
|
|
3
|
+
order: 100,
|
|
4
|
+
async run(context) {
|
|
5
|
+
const results = [];
|
|
6
|
+
for (const invoice of context.invoices) {
|
|
7
|
+
if (!invoice.ksefReference)
|
|
8
|
+
continue;
|
|
9
|
+
const ref = invoice.ksefReference.toLowerCase();
|
|
10
|
+
for (const tx of context.transactions) {
|
|
11
|
+
if (tx.description.toLowerCase().includes(ref)) {
|
|
12
|
+
results.push({
|
|
13
|
+
invoiceId: invoice.id,
|
|
14
|
+
transactionId: tx.id,
|
|
15
|
+
confidence: 99,
|
|
16
|
+
reasons: [`KSeF reference "${invoice.ksefReference}" found in transaction description`],
|
|
17
|
+
});
|
|
18
|
+
break;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return results;
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=ksef-ref.pass.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ksef-ref.pass.js","sourceRoot":"","sources":["../../../src/matching/passes/ksef-ref.pass.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,WAAW,GAAuB;IAC7C,IAAI,EAAE,UAAU;IAChB,KAAK,EAAE,GAAG;IAEV,KAAK,CAAC,GAAG,CAAC,OAAwB;QAChC,MAAM,OAAO,GAAkB,EAAE,CAAA;QAEjC,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACvC,IAAI,CAAC,OAAO,CAAC,aAAa;gBAAE,SAAQ;YAEpC,MAAM,GAAG,GAAG,OAAO,CAAC,aAAa,CAAC,WAAW,EAAE,CAAA;YAE/C,KAAK,MAAM,EAAE,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;gBACtC,IAAI,EAAE,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC/C,OAAO,CAAC,IAAI,CAAC;wBACX,SAAS,EAAE,OAAO,CAAC,EAAE;wBACrB,aAAa,EAAE,EAAE,CAAC,EAAE;wBACpB,UAAU,EAAE,EAAE;wBACd,OAAO,EAAE,CAAC,mBAAmB,OAAO,CAAC,aAAa,oCAAoC,CAAC;qBACxF,CAAC,CAAA;oBACF,MAAK;gBACP,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAA;IAChB,CAAC;CACF,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"partial.pass.d.ts","sourceRoot":"","sources":["../../../src/matching/passes/partial.pass.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAgC,MAAM,iBAAiB,CAAA;AAEvF,eAAO,MAAM,WAAW,EAAE,kBA0DzB,CAAA"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export const partialPass = {
|
|
2
|
+
name: 'partial',
|
|
3
|
+
order: 450,
|
|
4
|
+
async run(context) {
|
|
5
|
+
const results = [];
|
|
6
|
+
// Group transactions by NIP
|
|
7
|
+
const txByNip = new Map();
|
|
8
|
+
for (const tx of context.transactions) {
|
|
9
|
+
const nip = tx.senderNIP ?? tx.recipientNIP;
|
|
10
|
+
if (!nip)
|
|
11
|
+
continue;
|
|
12
|
+
const group = txByNip.get(nip) ?? [];
|
|
13
|
+
group.push(tx);
|
|
14
|
+
txByNip.set(nip, group);
|
|
15
|
+
}
|
|
16
|
+
for (const invoice of context.invoices) {
|
|
17
|
+
const txs = txByNip.get(invoice.sellerNIP);
|
|
18
|
+
if (!txs || txs.length < 2)
|
|
19
|
+
continue;
|
|
20
|
+
// Greedy: sort by amount descending, try to sum up to grossAmount
|
|
21
|
+
const sorted = [...txs].sort((a, b) => Math.abs(b.amount) - Math.abs(a.amount));
|
|
22
|
+
const selected = [];
|
|
23
|
+
let remaining = invoice.grossAmount;
|
|
24
|
+
for (const tx of sorted) {
|
|
25
|
+
const absAmount = Math.abs(tx.amount);
|
|
26
|
+
if (absAmount <= remaining) {
|
|
27
|
+
selected.push(tx.id);
|
|
28
|
+
remaining -= absAmount;
|
|
29
|
+
}
|
|
30
|
+
if (remaining === 0)
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
if (selected.length < 2)
|
|
34
|
+
continue;
|
|
35
|
+
const ratio = (invoice.grossAmount - remaining) / invoice.grossAmount;
|
|
36
|
+
if (ratio < 0.95)
|
|
37
|
+
continue;
|
|
38
|
+
const isExact = remaining === 0;
|
|
39
|
+
const confidence = isExact ? 70 : 50;
|
|
40
|
+
results.push({
|
|
41
|
+
invoiceId: invoice.id,
|
|
42
|
+
transactionId: selected[0],
|
|
43
|
+
transactionIds: selected,
|
|
44
|
+
confidence,
|
|
45
|
+
reasons: [
|
|
46
|
+
`Partial match: ${selected.length} transactions from NIP ${invoice.sellerNIP}`,
|
|
47
|
+
`Sum covers ${Math.round(ratio * 100)}% of invoice amount`,
|
|
48
|
+
isExact ? 'Exact sum match' : 'Approximate sum match',
|
|
49
|
+
],
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
return results;
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
//# sourceMappingURL=partial.pass.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"partial.pass.js","sourceRoot":"","sources":["../../../src/matching/passes/partial.pass.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,WAAW,GAAuB;IAC7C,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,GAAG;IAEV,KAAK,CAAC,GAAG,CAAC,OAAwB;QAChC,MAAM,OAAO,GAAkB,EAAE,CAAA;QAEjC,4BAA4B;QAC5B,MAAM,OAAO,GAAG,IAAI,GAAG,EAAuC,CAAA;QAC9D,KAAK,MAAM,EAAE,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;YACtC,MAAM,GAAG,GAAG,EAAE,CAAC,SAAS,IAAI,EAAE,CAAC,YAAY,CAAA;YAC3C,IAAI,CAAC,GAAG;gBAAE,SAAQ;YAClB,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAA;YACpC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;YACd,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;QACzB,CAAC;QAED,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACvC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;YAC1C,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC;gBAAE,SAAQ;YAEpC,kEAAkE;YAClE,MAAM,MAAM,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA;YAC/E,MAAM,QAAQ,GAAa,EAAE,CAAA;YAC7B,IAAI,SAAS,GAAG,OAAO,CAAC,WAAW,CAAA;YAEnC,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;gBACxB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,CAAA;gBACrC,IAAI,SAAS,IAAI,SAAS,EAAE,CAAC;oBAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;oBACpB,SAAS,IAAI,SAAS,CAAA;gBACxB,CAAC;gBACD,IAAI,SAAS,KAAK,CAAC;oBAAE,MAAK;YAC5B,CAAC;YAED,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;gBAAE,SAAQ;YAEjC,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,WAAW,CAAA;YACrE,IAAI,KAAK,GAAG,IAAI;gBAAE,SAAQ;YAE1B,MAAM,OAAO,GAAG,SAAS,KAAK,CAAC,CAAA;YAC/B,MAAM,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;YAEpC,OAAO,CAAC,IAAI,CAAC;gBACX,SAAS,EAAE,OAAO,CAAC,EAAE;gBACrB,aAAa,EAAE,QAAQ,CAAC,CAAC,CAAE;gBAC3B,cAAc,EAAE,QAAQ;gBACxB,UAAU;gBACV,OAAO,EAAE;oBACP,kBAAkB,QAAQ,CAAC,MAAM,0BAA0B,OAAO,CAAC,SAAS,EAAE;oBAC9E,cAAc,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,qBAAqB;oBAC1D,OAAO,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,uBAAuB;iBACtD;aACF,CAAC,CAAA;QACJ,CAAC;QAED,OAAO,OAAO,CAAA;IAChB,CAAC;CACF,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proximity.pass.d.ts","sourceRoot":"","sources":["../../../src/matching/passes/proximity.pass.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAgC,MAAM,iBAAiB,CAAA;AAGvF,eAAO,MAAM,aAAa,EAAE,kBAuD3B,CAAA"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { clampConfidence } from '../scoring.js';
|
|
2
|
+
export const proximityPass = {
|
|
3
|
+
name: 'proximity',
|
|
4
|
+
order: 500,
|
|
5
|
+
async run(context) {
|
|
6
|
+
const results = [];
|
|
7
|
+
const usedTxIds = new Set();
|
|
8
|
+
for (const invoice of context.invoices) {
|
|
9
|
+
const target = invoice.grossAmount;
|
|
10
|
+
const minAmount = Math.floor(target * 0.95);
|
|
11
|
+
const maxAmount = Math.ceil(target * 1.05);
|
|
12
|
+
const referenceDate = invoice.dueDate ?? invoice.issueDate;
|
|
13
|
+
let bestMatch = null;
|
|
14
|
+
for (const tx of context.transactions) {
|
|
15
|
+
if (usedTxIds.has(tx.id))
|
|
16
|
+
continue;
|
|
17
|
+
const absAmount = Math.abs(tx.amount);
|
|
18
|
+
if (absAmount < minAmount || absAmount > maxAmount)
|
|
19
|
+
continue;
|
|
20
|
+
const daysDiff = Math.abs((new Date(tx.date).getTime() - new Date(referenceDate).getTime()) / (1000 * 60 * 60 * 24));
|
|
21
|
+
if (daysDiff > 30)
|
|
22
|
+
continue;
|
|
23
|
+
const proximityFactor = 1 - daysDiff / 30;
|
|
24
|
+
const confidence = clampConfidence(50 + 20 * proximityFactor);
|
|
25
|
+
if (!bestMatch || confidence > bestMatch.confidence) {
|
|
26
|
+
bestMatch = {
|
|
27
|
+
txId: tx.id,
|
|
28
|
+
confidence,
|
|
29
|
+
reasons: [
|
|
30
|
+
`Amount within 5%: invoice ${target}, transaction ${absAmount}`,
|
|
31
|
+
`Date proximity: ${Math.round(daysDiff)} days apart`,
|
|
32
|
+
],
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (bestMatch) {
|
|
37
|
+
results.push({
|
|
38
|
+
invoiceId: invoice.id,
|
|
39
|
+
transactionId: bestMatch.txId,
|
|
40
|
+
confidence: bestMatch.confidence,
|
|
41
|
+
reasons: bestMatch.reasons,
|
|
42
|
+
});
|
|
43
|
+
usedTxIds.add(bestMatch.txId);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return results;
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
//# sourceMappingURL=proximity.pass.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proximity.pass.js","sourceRoot":"","sources":["../../../src/matching/passes/proximity.pass.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAE/C,MAAM,CAAC,MAAM,aAAa,GAAuB;IAC/C,IAAI,EAAE,WAAW;IACjB,KAAK,EAAE,GAAG;IAEV,KAAK,CAAC,GAAG,CAAC,OAAwB;QAChC,MAAM,OAAO,GAAkB,EAAE,CAAA;QACjC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAA;QAEnC,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACvC,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW,CAAA;YAClC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;YAC3C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;YAC1C,MAAM,aAAa,GAAG,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,SAAS,CAAA;YAE1D,IAAI,SAAS,GAAmE,IAAI,CAAA;YAEpF,KAAK,MAAM,EAAE,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;gBACtC,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;oBAAE,SAAQ;gBAElC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,CAAA;gBACrC,IAAI,SAAS,GAAG,SAAS,IAAI,SAAS,GAAG,SAAS;oBAAE,SAAQ;gBAE5D,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CACvB,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,aAAa,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAC1F,CAAA;gBACD,IAAI,QAAQ,GAAG,EAAE;oBAAE,SAAQ;gBAE3B,MAAM,eAAe,GAAG,CAAC,GAAG,QAAQ,GAAG,EAAE,CAAA;gBACzC,MAAM,UAAU,GAAG,eAAe,CAAC,EAAE,GAAG,EAAE,GAAG,eAAe,CAAC,CAAA;gBAE7D,IAAI,CAAC,SAAS,IAAI,UAAU,GAAG,SAAS,CAAC,UAAU,EAAE,CAAC;oBACpD,SAAS,GAAG;wBACV,IAAI,EAAE,EAAE,CAAC,EAAE;wBACX,UAAU;wBACV,OAAO,EAAE;4BACP,6BAA6B,MAAM,iBAAiB,SAAS,EAAE;4BAC/D,mBAAmB,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,aAAa;yBACrD;qBACF,CAAA;gBACH,CAAC;YACH,CAAC;YAED,IAAI,SAAS,EAAE,CAAC;gBACd,OAAO,CAAC,IAAI,CAAC;oBACX,SAAS,EAAE,OAAO,CAAC,EAAE;oBACrB,aAAa,EAAE,SAAS,CAAC,IAAI;oBAC7B,UAAU,EAAE,SAAS,CAAC,UAAU;oBAChC,OAAO,EAAE,SAAS,CAAC,OAAO;iBAC3B,CAAC,CAAA;gBACF,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;YAC/B,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAA;IAChB,CAAC;CACF,CAAA"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { Invoice, BankTransaction, ReconciliationReport, ReconciliationPass } from '@ksefnik/shared';
|
|
2
|
+
export declare function runPipeline(invoices: Invoice[], transactions: BankTransaction[], passes: ReconciliationPass[]): Promise<ReconciliationReport>;
|
|
3
|
+
//# sourceMappingURL=pipeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/matching/pipeline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EACP,eAAe,EAEf,oBAAoB,EACpB,kBAAkB,EAGnB,MAAM,iBAAiB,CAAA;AAGxB,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,OAAO,EAAE,EACnB,YAAY,EAAE,eAAe,EAAE,EAC/B,MAAM,EAAE,kBAAkB,EAAE,GAC3B,OAAO,CAAC,oBAAoB,CAAC,CAoE/B"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { getUnmatchedInvoices, getUnmatchedTransactions } from './context.js';
|
|
2
|
+
export async function runPipeline(invoices, transactions, passes) {
|
|
3
|
+
const startTime = Date.now();
|
|
4
|
+
const sortedPasses = [...passes].sort((a, b) => a.order - b.order);
|
|
5
|
+
const allMatches = [];
|
|
6
|
+
const passBreakdown = {};
|
|
7
|
+
for (const pass of sortedPasses) {
|
|
8
|
+
const unmatchedInvoices = getUnmatchedInvoices(invoices, allMatches);
|
|
9
|
+
const unmatchedTransactions = getUnmatchedTransactions(transactions, allMatches);
|
|
10
|
+
if (unmatchedInvoices.length === 0 || unmatchedTransactions.length === 0)
|
|
11
|
+
break;
|
|
12
|
+
const context = {
|
|
13
|
+
invoices: unmatchedInvoices,
|
|
14
|
+
transactions: unmatchedTransactions,
|
|
15
|
+
alreadyMatched: allMatches,
|
|
16
|
+
};
|
|
17
|
+
const results = await pass.run(context);
|
|
18
|
+
const newMatches = resultsToMatches(results, pass.name);
|
|
19
|
+
// Deduplicate: don't match already-matched invoices or transactions
|
|
20
|
+
const matchedInvoiceIds = new Set(allMatches.map((m) => m.invoiceId));
|
|
21
|
+
const matchedTxIds = new Set();
|
|
22
|
+
for (const m of allMatches) {
|
|
23
|
+
matchedTxIds.add(m.transactionId);
|
|
24
|
+
if (m.transactionIds)
|
|
25
|
+
m.transactionIds.forEach((id) => matchedTxIds.add(id));
|
|
26
|
+
}
|
|
27
|
+
for (const match of newMatches) {
|
|
28
|
+
if (matchedInvoiceIds.has(match.invoiceId))
|
|
29
|
+
continue;
|
|
30
|
+
if (matchedTxIds.has(match.transactionId))
|
|
31
|
+
continue;
|
|
32
|
+
allMatches.push(match);
|
|
33
|
+
matchedInvoiceIds.add(match.invoiceId);
|
|
34
|
+
matchedTxIds.add(match.transactionId);
|
|
35
|
+
if (match.transactionIds)
|
|
36
|
+
match.transactionIds.forEach((id) => matchedTxIds.add(id));
|
|
37
|
+
passBreakdown[pass.name] = (passBreakdown[pass.name] ?? 0) + 1;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const unmatchedInvoices = getUnmatchedInvoices(invoices, allMatches);
|
|
41
|
+
const unmatchedTxs = getUnmatchedTransactions(transactions, allMatches);
|
|
42
|
+
const avgConfidence = allMatches.length > 0
|
|
43
|
+
? allMatches.reduce((sum, m) => sum + m.confidence, 0) / allMatches.length
|
|
44
|
+
: 0;
|
|
45
|
+
return {
|
|
46
|
+
id: crypto.randomUUID(),
|
|
47
|
+
matched: allMatches,
|
|
48
|
+
unmatchedInvoices,
|
|
49
|
+
unmatchedTransactions: unmatchedTxs,
|
|
50
|
+
summary: {
|
|
51
|
+
totalInvoices: invoices.length,
|
|
52
|
+
totalTransactions: transactions.length,
|
|
53
|
+
matchedCount: allMatches.length,
|
|
54
|
+
unmatchedInvoiceCount: unmatchedInvoices.length,
|
|
55
|
+
unmatchedTransactionCount: unmatchedTxs.length,
|
|
56
|
+
averageConfidence: Math.round(avgConfidence * 100) / 100,
|
|
57
|
+
passBreakdown,
|
|
58
|
+
},
|
|
59
|
+
runAt: new Date().toISOString(),
|
|
60
|
+
durationMs: Date.now() - startTime,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function resultsToMatches(results, passName) {
|
|
64
|
+
return results.map((r) => ({
|
|
65
|
+
id: crypto.randomUUID(),
|
|
66
|
+
invoiceId: r.invoiceId,
|
|
67
|
+
transactionId: r.transactionId,
|
|
68
|
+
transactionIds: r.transactionIds,
|
|
69
|
+
confidence: r.confidence,
|
|
70
|
+
passName,
|
|
71
|
+
reasons: r.reasons,
|
|
72
|
+
confirmed: false,
|
|
73
|
+
createdAt: new Date().toISOString(),
|
|
74
|
+
}));
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../src/matching/pipeline.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAA;AAE7E,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,QAAmB,EACnB,YAA+B,EAC/B,MAA4B;IAE5B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IAC5B,MAAM,YAAY,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAA;IAElE,MAAM,UAAU,GAAY,EAAE,CAAA;IAC9B,MAAM,aAAa,GAA2B,EAAE,CAAA;IAEhD,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;QAChC,MAAM,iBAAiB,GAAG,oBAAoB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;QACpE,MAAM,qBAAqB,GAAG,wBAAwB,CAAC,YAAY,EAAE,UAAU,CAAC,CAAA;QAEhF,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,IAAI,qBAAqB,CAAC,MAAM,KAAK,CAAC;YAAE,MAAK;QAE/E,MAAM,OAAO,GAAoB;YAC/B,QAAQ,EAAE,iBAAiB;YAC3B,YAAY,EAAE,qBAAqB;YACnC,cAAc,EAAE,UAAU;SAC3B,CAAA;QAED,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QACvC,MAAM,UAAU,GAAG,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;QAEvD,oEAAoE;QACpE,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAA;QACrE,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAA;QACtC,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;YAC3B,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,CAAA;YACjC,IAAI,CAAC,CAAC,cAAc;gBAAE,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;QAC9E,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;YAC/B,IAAI,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC;gBAAE,SAAQ;YACpD,IAAI,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC;gBAAE,SAAQ;YAEnD,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YACtB,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;YACtC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,CAAA;YACrC,IAAI,KAAK,CAAC,cAAc;gBAAE,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;YAEpF,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAA;QAChE,CAAC;IACH,CAAC;IAED,MAAM,iBAAiB,GAAG,oBAAoB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;IACpE,MAAM,YAAY,GAAG,wBAAwB,CAAC,YAAY,EAAE,UAAU,CAAC,CAAA;IAEvE,MAAM,aAAa,GACjB,UAAU,CAAC,MAAM,GAAG,CAAC;QACnB,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,GAAG,UAAU,CAAC,MAAM;QAC1E,CAAC,CAAC,CAAC,CAAA;IAEP,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE;QACvB,OAAO,EAAE,UAAU;QACnB,iBAAiB;QACjB,qBAAqB,EAAE,YAAY;QACnC,OAAO,EAAE;YACP,aAAa,EAAE,QAAQ,CAAC,MAAM;YAC9B,iBAAiB,EAAE,YAAY,CAAC,MAAM;YACtC,YAAY,EAAE,UAAU,CAAC,MAAM;YAC/B,qBAAqB,EAAE,iBAAiB,CAAC,MAAM;YAC/C,yBAAyB,EAAE,YAAY,CAAC,MAAM;YAC9C,iBAAiB,EAAE,IAAI,CAAC,KAAK,CAAC,aAAa,GAAG,GAAG,CAAC,GAAG,GAAG;YACxD,aAAa;SACd;QACD,KAAK,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QAC/B,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;KACnC,CAAA;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,OAAsB,EAAE,QAAgB;IAChE,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACzB,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE;QACvB,SAAS,EAAE,CAAC,CAAC,SAAS;QACtB,aAAa,EAAE,CAAC,CAAC,aAAa;QAC9B,cAAc,EAAE,CAAC,CAAC,cAAc;QAChC,UAAU,EAAE,CAAC,CAAC,UAAU;QACxB,QAAQ;QACR,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,SAAS,EAAE,KAAK;QAChB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC,CAAC,CAAA;AACL,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function clampConfidence(score: number): number;
|
|
2
|
+
export declare function dateProximityBonus(invoiceDate: string, transactionDate: string, maxDays?: number): number;
|
|
3
|
+
export declare function amountMatchBonus(invoiceAmount: number, transactionAmount: number): number;
|
|
4
|
+
export declare function agePenalty(transactionDate: string, now?: Date): number;
|
|
5
|
+
//# sourceMappingURL=scoring.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scoring.d.ts","sourceRoot":"","sources":["../../src/matching/scoring.ts"],"names":[],"mappings":"AAAA,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,MAAM,EACvB,OAAO,GAAE,MAAW,GACnB,MAAM,CASR;AAED,wBAAgB,gBAAgB,CAAC,aAAa,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,GAAG,MAAM,CAGzF;AAED,wBAAgB,UAAU,CAAC,eAAe,EAAE,MAAM,EAAE,GAAG,GAAE,IAAiB,GAAG,MAAM,CAKlF"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export function clampConfidence(score) {
|
|
2
|
+
return Math.max(0, Math.min(100, Math.round(score)));
|
|
3
|
+
}
|
|
4
|
+
export function dateProximityBonus(invoiceDate, transactionDate, maxDays = 30) {
|
|
5
|
+
const inv = new Date(invoiceDate).getTime();
|
|
6
|
+
const tx = new Date(transactionDate).getTime();
|
|
7
|
+
const diffDays = Math.abs(inv - tx) / (1000 * 60 * 60 * 24);
|
|
8
|
+
if (diffDays <= 3)
|
|
9
|
+
return 10;
|
|
10
|
+
if (diffDays <= 7)
|
|
11
|
+
return 5;
|
|
12
|
+
if (diffDays <= maxDays)
|
|
13
|
+
return 0;
|
|
14
|
+
return -10;
|
|
15
|
+
}
|
|
16
|
+
export function amountMatchBonus(invoiceAmount, transactionAmount) {
|
|
17
|
+
if (Math.abs(transactionAmount) === invoiceAmount)
|
|
18
|
+
return 5;
|
|
19
|
+
return 0;
|
|
20
|
+
}
|
|
21
|
+
export function agePenalty(transactionDate, now = new Date()) {
|
|
22
|
+
const tx = new Date(transactionDate).getTime();
|
|
23
|
+
const diffDays = (now.getTime() - tx) / (1000 * 60 * 60 * 24);
|
|
24
|
+
if (diffDays > 60)
|
|
25
|
+
return -10;
|
|
26
|
+
return 0;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=scoring.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scoring.js","sourceRoot":"","sources":["../../src/matching/scoring.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;AACtD,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,WAAmB,EACnB,eAAuB,EACvB,UAAkB,EAAE;IAEpB,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC,OAAO,EAAE,CAAA;IAC3C,MAAM,EAAE,GAAG,IAAI,IAAI,CAAC,eAAe,CAAC,CAAC,OAAO,EAAE,CAAA;IAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAA;IAE3D,IAAI,QAAQ,IAAI,CAAC;QAAE,OAAO,EAAE,CAAA;IAC5B,IAAI,QAAQ,IAAI,CAAC;QAAE,OAAO,CAAC,CAAA;IAC3B,IAAI,QAAQ,IAAI,OAAO;QAAE,OAAO,CAAC,CAAA;IACjC,OAAO,CAAC,EAAE,CAAA;AACZ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,aAAqB,EAAE,iBAAyB;IAC/E,IAAI,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,KAAK,aAAa;QAAE,OAAO,CAAC,CAAA;IAC3D,OAAO,CAAC,CAAA;AACV,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,eAAuB,EAAE,MAAY,IAAI,IAAI,EAAE;IACxE,MAAM,EAAE,GAAG,IAAI,IAAI,CAAC,eAAe,CAAC,CAAC,OAAO,EAAE,CAAA;IAC9C,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAA;IAC7D,IAAI,QAAQ,GAAG,EAAE;QAAE,OAAO,CAAC,EAAE,CAAA;IAC7B,OAAO,CAAC,CAAA;AACV,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/plugins/loader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEjD,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CASzE"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export async function loadPlugin(name) {
|
|
2
|
+
try {
|
|
3
|
+
const mod = await import(name);
|
|
4
|
+
const plugin = mod.default ?? mod;
|
|
5
|
+
if (!plugin.name || !plugin.version)
|
|
6
|
+
return null;
|
|
7
|
+
return plugin;
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/plugins/loader.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAY;IAC3C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAA;QAC9B,MAAM,MAAM,GAAe,GAAG,CAAC,OAAO,IAAI,GAAG,CAAA;QAC7C,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO;YAAE,OAAO,IAAI,CAAA;QAChD,OAAO,MAAM,CAAA;IACf,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { KsefPlugin, ReconciliationPass } from '@ksefnik/shared';
|
|
2
|
+
export declare class PluginRegistry {
|
|
3
|
+
private plugins;
|
|
4
|
+
register(plugin: KsefPlugin): void;
|
|
5
|
+
list(): KsefPlugin[];
|
|
6
|
+
getPasses(): ReconciliationPass[];
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/plugins/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAGrE,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAmB;IAElC,QAAQ,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;IAIlC,IAAI,IAAI,UAAU,EAAE;IAIpB,SAAS,IAAI,kBAAkB,EAAE;CAIlC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { defaultPasses } from '../matching/passes/index.js';
|
|
2
|
+
export class PluginRegistry {
|
|
3
|
+
plugins = [];
|
|
4
|
+
register(plugin) {
|
|
5
|
+
this.plugins.push(plugin);
|
|
6
|
+
}
|
|
7
|
+
list() {
|
|
8
|
+
return [...this.plugins];
|
|
9
|
+
}
|
|
10
|
+
getPasses() {
|
|
11
|
+
const pluginPasses = this.plugins.flatMap((p) => p.reconciliationPasses?.() ?? []);
|
|
12
|
+
return [...defaultPasses, ...pluginPasses].sort((a, b) => a.order - b.order);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/plugins/registry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAE3D,MAAM,OAAO,cAAc;IACjB,OAAO,GAAiB,EAAE,CAAA;IAElC,QAAQ,CAAC,MAAkB;QACzB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IAC3B,CAAC;IAED,IAAI;QACF,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAA;IAC1B,CAAC;IAED,SAAS;QACP,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,oBAAoB,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;QAClF,OAAO,CAAC,GAAG,aAAa,EAAE,GAAG,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAA;IAC9E,CAAC;CACF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Storage, InvoiceQuery, TransactionQuery, Invoice, BankTransaction, ReconciliationReport } from '@ksefnik/shared';
|
|
2
|
+
export declare class InMemoryStorage implements Storage {
|
|
3
|
+
private invoices;
|
|
4
|
+
private transactions;
|
|
5
|
+
private reports;
|
|
6
|
+
saveInvoices(invoices: Invoice[]): Promise<void>;
|
|
7
|
+
getInvoices(query?: InvoiceQuery): Promise<Invoice[]>;
|
|
8
|
+
saveTransactions(txs: BankTransaction[]): Promise<void>;
|
|
9
|
+
getTransactions(query?: TransactionQuery): Promise<BankTransaction[]>;
|
|
10
|
+
saveReport(report: ReconciliationReport): Promise<void>;
|
|
11
|
+
getReport(id: string): Promise<ReconciliationReport | null>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=in-memory.storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-memory.storage.d.ts","sourceRoot":"","sources":["../../src/storage/in-memory.storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EACP,YAAY,EACZ,gBAAgB,EAChB,OAAO,EACP,eAAe,EACf,oBAAoB,EACrB,MAAM,iBAAiB,CAAA;AAExB,qBAAa,eAAgB,YAAW,OAAO;IAC7C,OAAO,CAAC,QAAQ,CAA6B;IAC7C,OAAO,CAAC,YAAY,CAAqC;IACzD,OAAO,CAAC,OAAO,CAA0C;IAEnD,YAAY,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAMhD,WAAW,CAAC,KAAK,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAmBrD,gBAAgB,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAMvD,eAAe,CAAC,KAAK,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAsBrE,UAAU,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvD,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;CAGlE"}
|