@ekwo-ai/camt053 0.4.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.
- package/LICENSE +21 -0
- package/README.md +240 -0
- package/dist/decimal.d.ts +20 -0
- package/dist/decimal.d.ts.map +1 -0
- package/dist/decimal.js +46 -0
- package/dist/decimal.js.map +1 -0
- package/dist/errors.d.ts +31 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +9 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +454 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +210 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +11 -0
- package/dist/types.js.map +1 -0
- package/dist/xml.d.ts +40 -0
- package/dist/xml.d.ts.map +1 -0
- package/dist/xml.js +274 -0
- package/dist/xml.js.map +1 -0
- package/package.json +56 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
import { formatScaled, parseUnsigned, signedText } from './decimal.js';
|
|
2
|
+
import { StatementFileError } from './errors.js';
|
|
3
|
+
import { parseXml } from './xml.js';
|
|
4
|
+
export { StatementFileError } from './errors.js';
|
|
5
|
+
/**
|
|
6
|
+
* The versions of camt.053 this package's tests hold against the schema ISO
|
|
7
|
+
* publishes for each: a fixture per version validates, and is read. Another
|
|
8
|
+
* version of the same message is still read — the elements this package takes
|
|
9
|
+
* have kept their names since 2009 — and reported as `version_not_verified`.
|
|
10
|
+
*/
|
|
11
|
+
export const VERIFIED_VERSIONS = [
|
|
12
|
+
'02',
|
|
13
|
+
'03',
|
|
14
|
+
'04',
|
|
15
|
+
'05',
|
|
16
|
+
'06',
|
|
17
|
+
'07',
|
|
18
|
+
'08',
|
|
19
|
+
'09',
|
|
20
|
+
'10',
|
|
21
|
+
'11',
|
|
22
|
+
'12',
|
|
23
|
+
'13',
|
|
24
|
+
'14',
|
|
25
|
+
];
|
|
26
|
+
const NAMESPACE = /^urn:iso:std:iso:20022:tech:xsd:camt\.053\.001\.([0-9]{2})$/;
|
|
27
|
+
const DEFAULTS = { maxBytes: 32 * 1024 * 1024, maxDepth: 64, maxElements: 2_000_000 };
|
|
28
|
+
// --- walking the tree ------------------------------------------------------
|
|
29
|
+
function child(parent, name) {
|
|
30
|
+
if (!parent)
|
|
31
|
+
return undefined;
|
|
32
|
+
for (const candidate of parent.children) {
|
|
33
|
+
if (candidate.name === name && candidate.namespace === parent.namespace)
|
|
34
|
+
return candidate;
|
|
35
|
+
}
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
function children(parent, name) {
|
|
39
|
+
if (!parent)
|
|
40
|
+
return [];
|
|
41
|
+
return parent.children.filter((candidate) => candidate.name === name && candidate.namespace === parent.namespace);
|
|
42
|
+
}
|
|
43
|
+
function descend(parent, ...path) {
|
|
44
|
+
let current = parent;
|
|
45
|
+
for (const name of path)
|
|
46
|
+
current = child(current, name);
|
|
47
|
+
return current;
|
|
48
|
+
}
|
|
49
|
+
/** The trimmed text at a path, or null when absent or empty. */
|
|
50
|
+
function text(parent, ...path) {
|
|
51
|
+
const value = descend(parent, ...path)?.text.trim();
|
|
52
|
+
return value === undefined || value === '' ? null : value;
|
|
53
|
+
}
|
|
54
|
+
// --- small readers ---------------------------------------------------------
|
|
55
|
+
const DAY = /^([0-9]{4})-([0-9]{2})-([0-9]{2})(?:Z|[+-][0-9]{2}:[0-9]{2})?$/;
|
|
56
|
+
const DAY_TIME = /^([0-9]{4})-([0-9]{2})-([0-9]{2})T[0-9]{2}:[0-9]{2}:[0-9]{2}(?:\.[0-9]+)?(?:Z|[+-][0-9]{2}:[0-9]{2})?$/;
|
|
57
|
+
/**
|
|
58
|
+
* The day of an ISO date or date-time, **as written**. `2026-03-31T23:30:00+02:00`
|
|
59
|
+
* is 31 March: the bank wrote that day, and moving it to UTC would book it on
|
|
60
|
+
* another. `undefined` when the text is not a date.
|
|
61
|
+
*/
|
|
62
|
+
function day(raw) {
|
|
63
|
+
const match = DAY.exec(raw) ?? DAY_TIME.exec(raw);
|
|
64
|
+
if (!match)
|
|
65
|
+
return undefined;
|
|
66
|
+
const year = Number(match[1]);
|
|
67
|
+
const month = Number(match[2]);
|
|
68
|
+
const date = Number(match[3]);
|
|
69
|
+
if (month < 1 || month > 12 || date < 1)
|
|
70
|
+
return undefined;
|
|
71
|
+
const leap = (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
|
|
72
|
+
const length = [31, leap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month - 1];
|
|
73
|
+
if (date > length)
|
|
74
|
+
return undefined;
|
|
75
|
+
return `${match[1]}-${match[2]}-${match[3]}`;
|
|
76
|
+
}
|
|
77
|
+
/** A `Dt | DtTm` choice, or a bare date or date-time element. */
|
|
78
|
+
function rawDate(element) {
|
|
79
|
+
if (!element)
|
|
80
|
+
return null;
|
|
81
|
+
return text(element, 'Dt') ?? text(element, 'DtTm') ?? (element.text.trim() || null);
|
|
82
|
+
}
|
|
83
|
+
/** ISO 13616: move four characters to the end, letters to numbers, mod 97 is 1. */
|
|
84
|
+
export function isValidIban(iban) {
|
|
85
|
+
if (!/^[A-Z]{2}[0-9]{2}[A-Za-z0-9]{1,30}$/.test(iban))
|
|
86
|
+
return false;
|
|
87
|
+
const rearranged = (iban.slice(4) + iban.slice(0, 4)).toUpperCase();
|
|
88
|
+
let remainder = 0;
|
|
89
|
+
for (const character of rearranged) {
|
|
90
|
+
const code = character.charCodeAt(0);
|
|
91
|
+
const value = code >= 65 ? code - 55 : code - 48;
|
|
92
|
+
remainder = (value > 9 ? remainder * 100 + value : remainder * 10 + value) % 97;
|
|
93
|
+
}
|
|
94
|
+
return remainder === 1;
|
|
95
|
+
}
|
|
96
|
+
function accountIdentifier(id) {
|
|
97
|
+
const iban = text(id, 'IBAN');
|
|
98
|
+
if (iban !== null)
|
|
99
|
+
return { kind: 'iban', value: iban.replace(/\s+/g, '').toUpperCase() };
|
|
100
|
+
const other = child(id, 'Othr');
|
|
101
|
+
const value = text(other, 'Id');
|
|
102
|
+
if (value === null)
|
|
103
|
+
return null;
|
|
104
|
+
return {
|
|
105
|
+
kind: 'other',
|
|
106
|
+
value,
|
|
107
|
+
scheme: text(other, 'SchmeNm', 'Cd') ?? text(other, 'SchmeNm', 'Prtry'),
|
|
108
|
+
issuer: text(other, 'Issr'),
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
function bic(agent) {
|
|
112
|
+
const institution = child(agent, 'FinInstnId');
|
|
113
|
+
return text(institution, 'BICFI') ?? text(institution, 'BIC');
|
|
114
|
+
}
|
|
115
|
+
/** A party's name: directly under it until version 06, under `Pty` or `Agt` after. */
|
|
116
|
+
function partyName(party) {
|
|
117
|
+
return (text(party, 'Nm') ?? text(party, 'Pty', 'Nm') ?? text(party, 'Agt', 'FinInstnId', 'Nm'));
|
|
118
|
+
}
|
|
119
|
+
function bankTransactionCode(code) {
|
|
120
|
+
if (!code)
|
|
121
|
+
return null;
|
|
122
|
+
const out = {
|
|
123
|
+
domain: text(code, 'Domn', 'Cd'),
|
|
124
|
+
family: text(code, 'Domn', 'Fmly', 'Cd'),
|
|
125
|
+
subFamily: text(code, 'Domn', 'Fmly', 'SubFmlyCd'),
|
|
126
|
+
proprietary: text(code, 'Prtry', 'Cd'),
|
|
127
|
+
proprietaryIssuer: text(code, 'Prtry', 'Issr'),
|
|
128
|
+
};
|
|
129
|
+
return Object.values(out).every((value) => value === null) ? null : out;
|
|
130
|
+
}
|
|
131
|
+
function remittance(information) {
|
|
132
|
+
const out = { unstructured: [], structured: [] };
|
|
133
|
+
for (const free of children(information, 'Ustrd')) {
|
|
134
|
+
const value = free.text.trim();
|
|
135
|
+
if (value !== '')
|
|
136
|
+
out.unstructured.push(value);
|
|
137
|
+
}
|
|
138
|
+
for (const structured of children(information, 'Strd')) {
|
|
139
|
+
const creditor = child(structured, 'CdtrRefInf');
|
|
140
|
+
const reference = text(creditor, 'Ref');
|
|
141
|
+
if (reference === null)
|
|
142
|
+
continue;
|
|
143
|
+
out.structured.push({
|
|
144
|
+
reference,
|
|
145
|
+
type: text(creditor, 'Tp', 'CdOrPrtry', 'Cd') ?? text(creditor, 'Tp', 'CdOrPrtry', 'Prtry'),
|
|
146
|
+
issuer: text(creditor, 'Tp', 'Issr'),
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
return out;
|
|
150
|
+
}
|
|
151
|
+
/** `Amt` and its `CdtDbtInd`, signed from the account holder's side. */
|
|
152
|
+
function signedAmount(amount, direction) {
|
|
153
|
+
if (!amount || (direction !== 'CRDT' && direction !== 'DBIT'))
|
|
154
|
+
return null;
|
|
155
|
+
const scaled = parseUnsigned(amount.text);
|
|
156
|
+
if (scaled === null)
|
|
157
|
+
return null;
|
|
158
|
+
const negative = direction === 'DBIT';
|
|
159
|
+
return {
|
|
160
|
+
scaled: negative ? -scaled : scaled,
|
|
161
|
+
text: signedText(amount.text, negative),
|
|
162
|
+
currency: amount.attributes['Ccy'] ?? null,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
// --- a statement -----------------------------------------------------------
|
|
166
|
+
function readStatement(stmt, position, version, violations) {
|
|
167
|
+
const report = (code, message, line) => {
|
|
168
|
+
violations.push(line === undefined
|
|
169
|
+
? { code, message, statement: position }
|
|
170
|
+
: { code, message, statement: position, line });
|
|
171
|
+
};
|
|
172
|
+
const dayOf = (element, what, line) => {
|
|
173
|
+
const raw = rawDate(element);
|
|
174
|
+
if (raw === null)
|
|
175
|
+
return null;
|
|
176
|
+
const value = day(raw);
|
|
177
|
+
if (value === undefined) {
|
|
178
|
+
report('invalid_date', `${what} "${raw}" is not a date`, line);
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
return value;
|
|
182
|
+
};
|
|
183
|
+
const id = text(stmt, 'Id');
|
|
184
|
+
const acct = child(stmt, 'Acct');
|
|
185
|
+
const identifier = accountIdentifier(child(acct, 'Id'));
|
|
186
|
+
if (id === null || identifier === null) {
|
|
187
|
+
throw new StatementFileError('incomplete_statement', `statement ${position} has no ${id === null ? 'identifier' : 'account identifier'}: there is nothing to attach its lines to`);
|
|
188
|
+
}
|
|
189
|
+
if (identifier.kind === 'iban' && !isValidIban(identifier.value)) {
|
|
190
|
+
report('invalid_iban', `the account ${identifier.value} is written as an IBAN and fails its own check digits`);
|
|
191
|
+
}
|
|
192
|
+
// Balances.
|
|
193
|
+
const balances = [];
|
|
194
|
+
const scaledBalances = new Map();
|
|
195
|
+
for (const bal of children(stmt, 'Bal')) {
|
|
196
|
+
const type = text(bal, 'Tp', 'CdOrPrtry', 'Cd') ?? text(bal, 'Tp', 'CdOrPrtry', 'Prtry') ?? '';
|
|
197
|
+
const signed = signedAmount(child(bal, 'Amt'), text(bal, 'CdtDbtInd'));
|
|
198
|
+
if (signed === null || signed.currency === null) {
|
|
199
|
+
report('invalid_amount', `the ${type || 'unnamed'} balance "${child(bal, 'Amt')?.text.trim() ?? ''}" is not an amount with a direction and a currency`);
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
const balance = {
|
|
203
|
+
type,
|
|
204
|
+
amount: signed.text,
|
|
205
|
+
currency: signed.currency,
|
|
206
|
+
date: dayOf(child(bal, 'Dt'), `the date of the ${type} balance`),
|
|
207
|
+
};
|
|
208
|
+
balances.push(balance);
|
|
209
|
+
scaledBalances.set(balance, signed.scaled);
|
|
210
|
+
}
|
|
211
|
+
const openingBalance = balances.find((balance) => balance.type === 'OPBD') ??
|
|
212
|
+
balances.find((balance) => balance.type === 'PRCD') ??
|
|
213
|
+
null;
|
|
214
|
+
const closingBalance = balances.find((balance) => balance.type === 'CLBD') ?? null;
|
|
215
|
+
if (!openingBalance) {
|
|
216
|
+
report('opening_balance_missing', 'the statement carries no opening booked balance (OPBD or PRCD)');
|
|
217
|
+
}
|
|
218
|
+
if (!closingBalance) {
|
|
219
|
+
report('closing_balance_missing', 'the statement carries no closing booked balance (CLBD)');
|
|
220
|
+
}
|
|
221
|
+
const accountCurrency = text(acct, 'Ccy') ?? openingBalance?.currency ?? closingBalance?.currency ?? null;
|
|
222
|
+
let checkable = openingBalance !== null && closingBalance !== null;
|
|
223
|
+
for (const balance of [openingBalance, closingBalance]) {
|
|
224
|
+
if (balance && accountCurrency !== null && balance.currency !== accountCurrency) {
|
|
225
|
+
report('balance_currency_mismatch', `the ${balance.type} balance is in ${balance.currency} and the account in ${accountCurrency}`);
|
|
226
|
+
checkable = false;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
// Lines.
|
|
230
|
+
const lines = [];
|
|
231
|
+
let movement = 0n;
|
|
232
|
+
const bankReferences = new Map();
|
|
233
|
+
const entryReferences = new Map();
|
|
234
|
+
children(stmt, 'Ntry').forEach((ntry, entryIndex) => {
|
|
235
|
+
const entry = entryIndex + 1;
|
|
236
|
+
const first = lines.length + 1;
|
|
237
|
+
const direction = text(ntry, 'CdtDbtInd');
|
|
238
|
+
const status = text(ntry, 'Sts', 'Cd') ?? text(ntry, 'Sts', 'Prtry') ?? text(ntry, 'Sts') ?? '';
|
|
239
|
+
const booked = status === 'BOOK';
|
|
240
|
+
const reversal = text(ntry, 'RvslInd') === 'true' || text(ntry, 'RvslInd') === '1';
|
|
241
|
+
const amount = signedAmount(child(ntry, 'Amt'), direction);
|
|
242
|
+
const entryBankReference = text(ntry, 'AcctSvcrRef');
|
|
243
|
+
const entryReference = text(ntry, 'NtryRef');
|
|
244
|
+
if (direction !== 'CRDT' && direction !== 'DBIT') {
|
|
245
|
+
report('invalid_direction', `entry ${entry} is neither a credit nor a debit ("${direction ?? ''}")`, first);
|
|
246
|
+
}
|
|
247
|
+
else if (amount === null) {
|
|
248
|
+
report('invalid_amount', `the amount of entry ${entry}, "${child(ntry, 'Amt')?.text.trim() ?? ''}", is not an amount`, first);
|
|
249
|
+
}
|
|
250
|
+
if (amount === null) {
|
|
251
|
+
if (booked)
|
|
252
|
+
checkable = false;
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
if (accountCurrency !== null && amount.currency !== accountCurrency) {
|
|
256
|
+
report('foreign_currency_entry', `entry ${entry} is in ${amount.currency ?? 'no currency'} and the account in ${accountCurrency ?? 'none'}; it is reported, not converted`, first);
|
|
257
|
+
if (booked)
|
|
258
|
+
checkable = false;
|
|
259
|
+
}
|
|
260
|
+
else if (booked) {
|
|
261
|
+
movement += amount.scaled;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
for (const [reference, seen, code, what] of [
|
|
265
|
+
[entryBankReference, bankReferences, 'duplicate_bank_reference', 'bank reference'],
|
|
266
|
+
[entryReference, entryReferences, 'duplicate_entry_reference', 'entry reference'],
|
|
267
|
+
]) {
|
|
268
|
+
if (reference === null)
|
|
269
|
+
continue;
|
|
270
|
+
const earlier = seen.get(reference);
|
|
271
|
+
if (earlier === undefined)
|
|
272
|
+
seen.set(reference, entry);
|
|
273
|
+
else
|
|
274
|
+
report(code, `entries ${earlier} and ${entry} carry the same ${what}, ${reference}`, first);
|
|
275
|
+
}
|
|
276
|
+
const bookingDate = dayOf(child(ntry, 'BookgDt'), `the booking date of entry ${entry}`, first);
|
|
277
|
+
const valueDate = dayOf(child(ntry, 'ValDt'), `the value date of entry ${entry}`, first);
|
|
278
|
+
if (booked && child(ntry, 'BookgDt') === undefined) {
|
|
279
|
+
report('booking_date_missing', `entry ${entry} has no booking date`, first);
|
|
280
|
+
}
|
|
281
|
+
// The transactions under the entry, and whether they can stand for it.
|
|
282
|
+
const details = children(ntry, 'NtryDtls').flatMap((block) => children(block, 'TxDtls'));
|
|
283
|
+
const batchCount = children(ntry, 'NtryDtls')
|
|
284
|
+
.map((block) => text(block, 'Btch', 'NbOfTxs'))
|
|
285
|
+
.find((count) => count !== null);
|
|
286
|
+
if (batchCount !== undefined && details.length > 0 && Number(batchCount) !== details.length) {
|
|
287
|
+
report('batch_count_mismatch', `entry ${entry} announces ${batchCount} transactions and details ${details.length}`, first);
|
|
288
|
+
}
|
|
289
|
+
let parts = null;
|
|
290
|
+
if (details.length >= 2 && amount !== null) {
|
|
291
|
+
const read = details.map((detail) => signedAmount(child(detail, 'Amt') ?? descend(detail, 'AmtDtls', 'TxAmt', 'Amt'), text(detail, 'CdtDbtInd') ?? direction));
|
|
292
|
+
const whole = read.every((part) => part !== null && part.currency === amount.currency);
|
|
293
|
+
const sum = whole ? read.reduce((total, part) => total + part.scaled, 0n) : null;
|
|
294
|
+
if (whole && sum === amount.scaled) {
|
|
295
|
+
parts = read;
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
report('batch_not_split', whole
|
|
299
|
+
? `the ${details.length} transactions of entry ${entry} add up to ${formatScaled(sum)} and the entry is ${amount.text}; it is kept as one line`
|
|
300
|
+
: `the ${details.length} transactions of entry ${entry} do not each carry an amount in ${amount.currency ?? 'the entry currency'}; it is kept as one line`, first);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
const build = (detail, part, nth) => {
|
|
304
|
+
const lineAmount = part ?? amount;
|
|
305
|
+
const refs = child(detail, 'Refs');
|
|
306
|
+
const parties = child(detail, 'RltdPties');
|
|
307
|
+
const agents = child(detail, 'RltdAgts');
|
|
308
|
+
// Who is on the other side: the debtor of money coming in, the creditor
|
|
309
|
+
// of money going out — and the reverse when the entry undoes an earlier
|
|
310
|
+
// one, where the parties keep the roles they had in the original.
|
|
311
|
+
const credit = lineAmount !== null ? lineAmount.scaled >= 0n : direction === 'CRDT';
|
|
312
|
+
const side = credit !== reversal ? 'Dbtr' : 'Cdtr';
|
|
313
|
+
const account = accountIdentifier(descend(parties, `${side}Acct`, 'Id'));
|
|
314
|
+
const counterparty = {
|
|
315
|
+
name: partyName(child(parties, side)),
|
|
316
|
+
account,
|
|
317
|
+
agentBic: bic(child(agents, `${side}Agt`)),
|
|
318
|
+
ultimateName: partyName(child(parties, `Ultmt${side}`)),
|
|
319
|
+
};
|
|
320
|
+
const index = lines.length + 1;
|
|
321
|
+
if (account?.kind === 'iban' && !isValidIban(account.value)) {
|
|
322
|
+
report('invalid_iban', `the counterparty account ${account.value} is written as an IBAN and fails its own check digits`, index);
|
|
323
|
+
}
|
|
324
|
+
const amountDetails = child(detail, 'AmtDtls') ?? child(ntry, 'AmtDtls');
|
|
325
|
+
const instructed = descend(amountDetails, 'InstdAmt', 'Amt');
|
|
326
|
+
const instructedCurrency = instructed?.attributes['Ccy'];
|
|
327
|
+
lines.push({
|
|
328
|
+
index,
|
|
329
|
+
entry,
|
|
330
|
+
detail: nth,
|
|
331
|
+
detailCount: nth === null ? null : details.length,
|
|
332
|
+
status,
|
|
333
|
+
booked,
|
|
334
|
+
reversal,
|
|
335
|
+
bookingDate,
|
|
336
|
+
valueDate,
|
|
337
|
+
amount: lineAmount?.text ?? null,
|
|
338
|
+
currency: lineAmount?.currency ?? null,
|
|
339
|
+
entryAmount: nth === null ? null : (amount?.text ?? null),
|
|
340
|
+
bankReference: text(refs, 'AcctSvcrRef') ?? entryBankReference,
|
|
341
|
+
entryReference,
|
|
342
|
+
endToEndId: text(refs, 'EndToEndId'),
|
|
343
|
+
transactionId: text(refs, 'TxId'),
|
|
344
|
+
instructionId: text(refs, 'InstrId'),
|
|
345
|
+
paymentInformationId: text(refs, 'PmtInfId'),
|
|
346
|
+
mandateId: text(refs, 'MndtId'),
|
|
347
|
+
counterparty: Object.values(counterparty).every((value) => value === null)
|
|
348
|
+
? null
|
|
349
|
+
: counterparty,
|
|
350
|
+
remittance: remittance(child(detail, 'RmtInf')),
|
|
351
|
+
bankTransactionCode: bankTransactionCode(child(detail, 'BkTxCd')) ?? bankTransactionCode(child(ntry, 'BkTxCd')),
|
|
352
|
+
returnReason: text(detail, 'RtrInf', 'Rsn', 'Cd') ?? text(detail, 'RtrInf', 'Rsn', 'Prtry'),
|
|
353
|
+
instructedAmount: instructed && instructedCurrency !== undefined && parseUnsigned(instructed.text) !== null
|
|
354
|
+
? { amount: signedText(instructed.text, false), currency: instructedCurrency }
|
|
355
|
+
: null,
|
|
356
|
+
exchangeRate: text(amountDetails, 'InstdAmt', 'CcyXchg', 'XchgRate') ??
|
|
357
|
+
text(amountDetails, 'TxAmt', 'CcyXchg', 'XchgRate') ??
|
|
358
|
+
text(amountDetails, 'CntrValAmt', 'CcyXchg', 'XchgRate'),
|
|
359
|
+
additionalInformation: text(detail, 'AddtlTxInf') ?? text(ntry, 'AddtlNtryInf'),
|
|
360
|
+
});
|
|
361
|
+
};
|
|
362
|
+
if (parts)
|
|
363
|
+
details.forEach((detail, nth) => build(detail, parts[nth], nth + 1));
|
|
364
|
+
else
|
|
365
|
+
build(details.length === 1 ? details[0] : undefined, null, null);
|
|
366
|
+
});
|
|
367
|
+
// Opening plus what was booked is the closing, or the file says so.
|
|
368
|
+
let balanced = null;
|
|
369
|
+
if (checkable && openingBalance && closingBalance) {
|
|
370
|
+
const opening = scaledBalances.get(openingBalance);
|
|
371
|
+
const closing = scaledBalances.get(closingBalance);
|
|
372
|
+
const computed = opening + movement;
|
|
373
|
+
balanced = computed === closing;
|
|
374
|
+
if (!balanced) {
|
|
375
|
+
report('balance_mismatch', `opening ${openingBalance.amount} plus booked entries ${formatScaled(movement)} is ${formatScaled(computed)}, and the statement closes at ${closingBalance.amount}: a difference of ${formatScaled(closing - computed)} ${closingBalance.currency}`);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
const pagination = child(stmt, 'StmtPgntn');
|
|
379
|
+
const period = child(stmt, 'FrToDt');
|
|
380
|
+
if (!VERIFIED_VERSIONS.includes(version)) {
|
|
381
|
+
report('version_not_verified', `camt.053.001.${version} is read, and is not a version this package is tested against`);
|
|
382
|
+
}
|
|
383
|
+
return {
|
|
384
|
+
id,
|
|
385
|
+
electronicSequenceNumber: text(stmt, 'ElctrncSeqNb'),
|
|
386
|
+
legalSequenceNumber: text(stmt, 'LglSeqNb'),
|
|
387
|
+
createdAt: text(stmt, 'CreDtTm'),
|
|
388
|
+
period: period
|
|
389
|
+
? {
|
|
390
|
+
from: dayOf(child(period, 'FrDtTm'), 'the start of the period'),
|
|
391
|
+
to: dayOf(child(period, 'ToDtTm'), 'the end of the period'),
|
|
392
|
+
}
|
|
393
|
+
: null,
|
|
394
|
+
page: pagination
|
|
395
|
+
? {
|
|
396
|
+
number: text(pagination, 'PgNb') ?? '',
|
|
397
|
+
last: ['true', '1'].includes(text(pagination, 'LastPgInd') ?? ''),
|
|
398
|
+
}
|
|
399
|
+
: null,
|
|
400
|
+
account: {
|
|
401
|
+
identifier,
|
|
402
|
+
currency: text(acct, 'Ccy'),
|
|
403
|
+
name: text(acct, 'Nm'),
|
|
404
|
+
ownerName: text(acct, 'Ownr', 'Nm'),
|
|
405
|
+
servicerBic: bic(child(acct, 'Svcr')),
|
|
406
|
+
},
|
|
407
|
+
openingBalance,
|
|
408
|
+
closingBalance,
|
|
409
|
+
balances,
|
|
410
|
+
lines,
|
|
411
|
+
balanced,
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* Read a camt.053 file — a string, or the bytes as they came — into its
|
|
416
|
+
* statements, their lines, and what does not add up.
|
|
417
|
+
*
|
|
418
|
+
* Throws a `StatementFileError` for what is not a readable camt.053 at all.
|
|
419
|
+
* Everything else comes back, with the trouble named in `violations` and
|
|
420
|
+
* nothing silently repaired: a closing balance that does not follow from the
|
|
421
|
+
* opening one is returned as the bank wrote it, and reported.
|
|
422
|
+
*/
|
|
423
|
+
export function readCamt053(input, options = {}) {
|
|
424
|
+
const root = parseXml(input, {
|
|
425
|
+
maxBytes: options.maxBytes ?? DEFAULTS.maxBytes,
|
|
426
|
+
maxDepth: options.maxDepth ?? DEFAULTS.maxDepth,
|
|
427
|
+
maxElements: options.maxElements ?? DEFAULTS.maxElements,
|
|
428
|
+
});
|
|
429
|
+
const match = NAMESPACE.exec(root.namespace);
|
|
430
|
+
if (root.name !== 'Document' || !match) {
|
|
431
|
+
throw new StatementFileError('not_a_statement', `the document element is <${root.name}> in "${root.namespace}", not a camt.053 Document`);
|
|
432
|
+
}
|
|
433
|
+
if (match[1] === '01') {
|
|
434
|
+
throw new StatementFileError('unsupported_version', 'camt.053.001.01 is another message under the same name — other elements for the message, the balances and the account — and is refused rather than half read');
|
|
435
|
+
}
|
|
436
|
+
const message = child(root, 'BkToCstmrStmt');
|
|
437
|
+
const stmts = children(message, 'Stmt');
|
|
438
|
+
if (stmts.length === 0) {
|
|
439
|
+
throw new StatementFileError('incomplete_statement', 'the file holds no statement (Stmt)');
|
|
440
|
+
}
|
|
441
|
+
const version = match[1];
|
|
442
|
+
const violations = [];
|
|
443
|
+
const statements = stmts.map((stmt, index) => readStatement(stmt, index + 1, version, violations));
|
|
444
|
+
return {
|
|
445
|
+
namespace: root.namespace,
|
|
446
|
+
version,
|
|
447
|
+
versionVerified: VERIFIED_VERSIONS.includes(version),
|
|
448
|
+
messageId: text(message, 'GrpHdr', 'MsgId'),
|
|
449
|
+
createdAt: text(message, 'GrpHdr', 'CreDtTm'),
|
|
450
|
+
statements,
|
|
451
|
+
violations,
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|