kassza 0.12.0 → 0.14.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/README.en.md +48 -0
- package/README.md +427 -32
- package/agents/README.md +26 -6
- package/agents/api.md +218 -3
- package/agents/pitfalls.md +27 -3
- package/agents/recipes.md +280 -51
- package/agents/skills/kassza/SKILL.md +14 -8
- package/agents/skills/migrate-from-szamlazz-js/SKILL.md +39 -0
- package/dist/batch/index.cjs +346 -0
- package/dist/batch/index.d.cts +91 -0
- package/dist/batch/index.d.ts +91 -0
- package/dist/batch/index.js +339 -0
- package/dist/cli.cjs +643 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +643 -0
- package/dist/client-CLFvJCVW.cjs +1452 -0
- package/dist/{client-CL3fuH6A.js → client-Cvf-hTz_.js} +306 -515
- package/dist/client-DeWWQ-RZ.d.ts +341 -0
- package/dist/client-SVZu25MB.d.cts +341 -0
- package/dist/context-CFNKzStE.d.cts +449 -0
- package/dist/context-kb33TgzE.d.ts +449 -0
- package/dist/cookie-stores/index.cjs +21 -150
- package/dist/cookie-stores/index.d.cts +4 -63
- package/dist/cookie-stores/index.d.ts +4 -63
- package/dist/cookie-stores/index.js +3 -144
- package/dist/create-CflXrPip.js +204 -0
- package/dist/create-CvUvLUaT.cjs +257 -0
- package/dist/{create-once-D0pwuenl.cjs → create-once-9yxR_Er_.cjs} +291 -33
- package/dist/create-once-Bh6fOWkW.d.cts +20 -0
- package/dist/{create-once-CqdYmQD8.js → create-once-Ca2gMk1h.js} +250 -34
- package/dist/create-once-VKp0tVow.d.ts +20 -0
- package/dist/{crypto-B8lERvR1.cjs → crypto-Dpn4FHQ6.cjs} +9 -0
- package/dist/{crypto-DK_osBVy.js → crypto-usDg8L2K.js} +4 -1
- package/dist/data-link/index.cjs +232 -0
- package/dist/data-link/index.d.cts +29 -0
- package/dist/data-link/index.d.ts +29 -0
- package/dist/data-link/index.js +224 -0
- package/dist/delegation/index.cjs +35 -34
- package/dist/delegation/index.d.cts +2 -1
- package/dist/delegation/index.d.ts +2 -1
- package/dist/delegation/index.js +4 -3
- package/dist/{errors-DLrb0g64.js → errors-DtN4g5Z9.js} +9 -1
- package/dist/{errors-DxeuTslP.cjs → errors-EE96_6D_.cjs} +20 -0
- package/dist/get-BdMTseh4.cjs +271 -0
- package/dist/get-Byc9T5WO.d.cts +151 -0
- package/dist/get-Byc9T5WO.d.ts +151 -0
- package/dist/get-CZEShCcj.js +260 -0
- package/dist/index-BhUPY_EH.d.cts +109 -0
- package/dist/index-BqGgQ4t3.d.ts +109 -0
- package/dist/{index-CYAGCdKJ.d.cts → index-C-7yWV7L.d.cts} +24 -1
- package/dist/{index-CYAGCdKJ.d.ts → index-C-7yWV7L.d.ts} +24 -1
- package/dist/index.cjs +19 -5
- package/dist/index.d.cts +11 -19
- package/dist/index.d.ts +11 -19
- package/dist/index.js +6 -6
- package/dist/ipn/index.cjs +26 -5
- package/dist/ipn/index.d.cts +12 -1
- package/dist/ipn/index.d.ts +12 -1
- package/dist/ipn/index.js +26 -6
- package/dist/issue-Bin4tKD_.cjs +988 -0
- package/dist/issue-DMA1Nbr1.js +905 -0
- package/dist/journal/index.cjs +454 -0
- package/dist/journal/index.d.cts +18 -0
- package/dist/journal/index.d.ts +18 -0
- package/dist/journal/index.js +445 -0
- package/dist/journal-DvI81Kt7.d.cts +114 -0
- package/dist/journal-Y9qrIB8G.d.ts +114 -0
- package/dist/mcp/index.cjs +10 -0
- package/dist/mcp/index.d.cts +71 -0
- package/dist/mcp/index.d.ts +71 -0
- package/dist/mcp/index.js +2 -0
- package/dist/money/index.cjs +2 -1
- package/dist/money/index.d.cts +2 -2
- package/dist/money/index.d.ts +2 -2
- package/dist/money/index.js +2 -2
- package/dist/{money-DAA7OwiO.js → money-Cw457SD6.js} +120 -12
- package/dist/{money-DrhGkWHW.cjs → money-K9j0wPit.cjs} +124 -10
- package/dist/nav/index.cjs +1046 -0
- package/dist/nav/index.d.cts +247 -0
- package/dist/nav/index.d.ts +247 -0
- package/dist/nav/index.js +1012 -0
- package/dist/nav-BNbc8U0R.cjs +203 -0
- package/dist/nav-BcCerwWS.js +156 -0
- package/dist/node/index.cjs +124 -0
- package/dist/node/index.d.cts +35 -0
- package/dist/node/index.d.ts +35 -0
- package/dist/node/index.js +120 -0
- package/dist/observe/index.cjs +311 -0
- package/dist/observe/index.d.cts +53 -0
- package/dist/observe/index.d.ts +53 -0
- package/dist/observe/index.js +303 -0
- package/dist/once-BN_3B5OF.cjs +103 -0
- package/dist/once-CqqZxsXG.js +74 -0
- package/dist/parse-Cr7yQ3_z.js +291 -0
- package/dist/parse-DOA2XQ3e.cjs +380 -0
- package/dist/payments/barion.cjs +26 -2
- package/dist/payments/barion.d.cts +2 -2
- package/dist/payments/barion.d.ts +2 -2
- package/dist/payments/barion.js +26 -2
- package/dist/payments/index.cjs +7 -2
- package/dist/payments/index.d.cts +4 -4
- package/dist/payments/index.d.ts +4 -4
- package/dist/payments/index.js +3 -3
- package/dist/payments/paypal.cjs +16 -2
- package/dist/payments/paypal.d.cts +2 -2
- package/dist/payments/paypal.d.ts +2 -2
- package/dist/payments/paypal.js +16 -2
- package/dist/payments/revolut.cjs +17 -3
- package/dist/payments/revolut.d.cts +2 -2
- package/dist/payments/revolut.d.ts +2 -2
- package/dist/payments/revolut.js +17 -3
- package/dist/payments/simplepay.cjs +37 -5
- package/dist/payments/simplepay.d.cts +2 -2
- package/dist/payments/simplepay.d.ts +2 -2
- package/dist/payments/simplepay.js +37 -5
- package/dist/payments/stripe.cjs +20 -3
- package/dist/payments/stripe.d.cts +2 -2
- package/dist/payments/stripe.d.ts +2 -2
- package/dist/payments/stripe.js +20 -3
- package/dist/push-BXj0Sf0Z.d.ts +52 -0
- package/dist/push-D4nNbCNV.d.cts +52 -0
- package/dist/reference-B5TATqb5.js +124 -0
- package/dist/reference-BIdYMK0t.cjs +183 -0
- package/dist/reports/index.cjs +11 -164
- package/dist/reports/index.d.cts +1 -1
- package/dist/reports/index.d.ts +1 -1
- package/dist/reports/index.js +1 -154
- package/dist/request-body-CH6ZGOrq.cjs +34 -0
- package/dist/request-body-uZHMRlQr.js +29 -0
- package/dist/serialize-B2eFh3D-.js +219 -0
- package/dist/serialize-CquIsxA-.cjs +290 -0
- package/dist/server-BrJUbXs7.js +1505 -0
- package/dist/server-Dw9j8Mnd.cjs +1558 -0
- package/dist/session-Ckl5eJhV.d.ts +7 -0
- package/dist/{session-CKOuE6Jc.cjs → session-DeM5vjvC.cjs} +69 -13
- package/dist/{session-rMKaJcmq.js → session-SaEEXu2N.js} +58 -14
- package/dist/session-YbChChx7.d.cts +7 -0
- package/dist/storage/fs.cjs +1 -1
- package/dist/storage/fs.js +1 -1
- package/dist/storage/index.cjs +1 -1
- package/dist/storage/index.js +1 -1
- package/dist/store-C1rHd9DB.d.cts +19 -0
- package/dist/store-C1rHd9DB.d.ts +19 -0
- package/dist/stores/index.cjs +24 -0
- package/dist/stores/index.d.cts +4 -0
- package/dist/stores/index.d.ts +4 -0
- package/dist/stores/index.js +3 -0
- package/dist/stores-BNrS0dWl.cjs +506 -0
- package/dist/stores-DhjGBrl_.js +441 -0
- package/dist/testing/index.cjs +1500 -15
- package/dist/testing/index.d.cts +198 -3
- package/dist/testing/index.d.ts +198 -3
- package/dist/testing/index.js +1498 -15
- package/dist/{types-COf1LAD-.d.ts → types-B1A8mUIE.d.cts} +14 -2
- package/dist/{types-COf1LAD-.d.cts → types-ByAEvGsZ.d.ts} +14 -2
- package/dist/{types-k--zHf4l.d.ts → types-D1zDOH_F.d.ts} +1 -1
- package/dist/{types-DH8QoNZK.d.cts → types-lnKkQdot.d.cts} +1 -1
- package/dist/warnings-B3DXnveC.d.cts +31 -0
- package/dist/warnings-B3DXnveC.d.ts +31 -0
- package/dist/warnings-DeIw5RFj.cjs +20 -0
- package/dist/warnings-DwTl5J-2.js +15 -0
- package/dist/{webhook-D4lvtex1.js → webhook-CQVShAfI.js} +47 -26
- package/dist/{webhook-C76bV-4R.cjs → webhook-Ckj-_hPD.cjs} +70 -25
- package/dist/webhook-CmdhGiH5.d.cts +11 -0
- package/dist/webhook-D6lEejob.d.ts +11 -0
- package/llms.txt +6 -5
- package/package.json +134 -4
- package/dist/client-CickRRFr.d.ts +0 -838
- package/dist/client-CsmGIFRS.cjs +0 -1637
- package/dist/client-DvWZoX_E.d.cts +0 -838
- package/dist/issue-BsyYdrIG.cjs +0 -1531
- package/dist/issue-C6Fcjvln.js +0 -1274
- package/dist/session-Dm_45x8K.d.cts +0 -11
- package/dist/session-Dm_45x8K.d.ts +0 -11
- package/dist/webhook-CfaDgcL0.d.cts +0 -6
- package/dist/webhook-q2OzNwd7.d.ts +0 -6
|
@@ -1,11 +1,16 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
import {
|
|
1
|
+
import { a as registerPayment, c as resolveInvoice, d as TAXPAYER_TYPE_CODES, h as AGENT_ACTIONS, i as clearPayments, o as optionalAgentDate, p as emitDocumentEvent, r as registerPaymentOnce, s as presentText, t as createReceiptOnce, u as INVOICE_TEMPLATES } from "./create-once-Ca2gMk1h.js";
|
|
2
|
+
import { i as createAgentError, o as isSzamlazzError, r as SzamlazzError, s as parseErrorCode } from "./errors-DtN4g5Z9.js";
|
|
3
3
|
import { t as base64ToBytes } from "./binary-D0M9U2MD.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import { a as optionalEl, c as childNumber, d as findChildren, l as childText, n as buildXmlDocument, r as el, s as childBoolean, u as findChild } from "./serialize-B2eFh3D-.js";
|
|
5
|
+
import { a as looksLikeXml, c as readDocumentHeaders, d as throwIfHeaderError, f as throwIfHttpError, h as unexpectedResponse, m as throwIfXmlFailure, n as parseReceiptResponse, o as parseDoneText, p as throwIfTextError, r as createAgentResponse, s as parseResponseXml, u as throwIfAnyError } from "./parse-Cr7yQ3_z.js";
|
|
6
|
+
import { i as sessionKeyFor, n as memoryCookieStore, r as mergeSetCookies, t as SESSION_TTL_SECONDS } from "./session-SaEEXu2N.js";
|
|
7
|
+
import { t as emitWarning } from "./warnings-DwTl5J-2.js";
|
|
8
|
+
import { l as createInvoiceOnce, m as guardOnce, n as issueForPayment, o as convertReceiptToInvoice } from "./issue-DMA1Nbr1.js";
|
|
7
9
|
import { r as formatVatRate } from "./vat-v_dcWCto.js";
|
|
8
|
-
import {
|
|
10
|
+
import { a as summarizeItems } from "./money-Cw457SD6.js";
|
|
11
|
+
import { a as optionalText, c as requireText, i as optionalAgentDate$1, l as resolveInvoiceReference, o as parseInvoiceResult, s as referenceValue, t as AGENT_XSD_BASE_URL, u as validationError } from "./reference-B5TATqb5.js";
|
|
12
|
+
import { t as getInvoice } from "./get-CZEShCcj.js";
|
|
13
|
+
import { a as optionalText$1, c as validateTemplate$1, i as RECEIPT_XSD_BASE_URL, o as receiptValidationError, r as createReceipt, s as requireReceiptNumber } from "./create-CflXrPip.js";
|
|
9
14
|
//#region src/core/attempt-ledger.ts
|
|
10
15
|
const ATTEMPT_LEDGER_TTL_SECONDS = 86400;
|
|
11
16
|
const ATTEMPT_LEDGER_KEY_PREFIX = "szamlazz:attempts:";
|
|
@@ -35,17 +40,63 @@ function parseCount(value) {
|
|
|
35
40
|
const parsed = Number.parseInt(value, 10);
|
|
36
41
|
return Number.isInteger(parsed) && parsed > 0 ? parsed : 0;
|
|
37
42
|
}
|
|
43
|
+
function createLocalCounter() {
|
|
44
|
+
const counts = /* @__PURE__ */ new Map();
|
|
45
|
+
const get = (key) => {
|
|
46
|
+
const entry = counts.get(key);
|
|
47
|
+
if (!entry) return 0;
|
|
48
|
+
if (entry.expiresAt <= Date.now()) {
|
|
49
|
+
counts.delete(key);
|
|
50
|
+
return 0;
|
|
51
|
+
}
|
|
52
|
+
return entry.count;
|
|
53
|
+
};
|
|
54
|
+
return {
|
|
55
|
+
get,
|
|
56
|
+
bump(key) {
|
|
57
|
+
const count = get(key) + 1;
|
|
58
|
+
counts.delete(key);
|
|
59
|
+
counts.set(key, {
|
|
60
|
+
count,
|
|
61
|
+
expiresAt: Date.now() + ATTEMPT_LEDGER_TTL_SECONDS * 1e3
|
|
62
|
+
});
|
|
63
|
+
if (counts.size > 1e3) {
|
|
64
|
+
const oldest = counts.keys().next().value;
|
|
65
|
+
if (oldest !== void 0) counts.delete(oldest);
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
clear(key) {
|
|
69
|
+
counts.delete(key);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
}
|
|
38
73
|
function createAttemptLedger(store) {
|
|
74
|
+
const local = createLocalCounter();
|
|
75
|
+
const unpersisted = createLocalCounter();
|
|
39
76
|
return {
|
|
40
77
|
async failures(key) {
|
|
41
|
-
return parseCount(await store.get(key));
|
|
78
|
+
return parseCount(await store.get(key)) + unpersisted.get(key);
|
|
79
|
+
},
|
|
80
|
+
fallbackFailures(key) {
|
|
81
|
+
return local.get(key);
|
|
42
82
|
},
|
|
43
|
-
async recordFailure(key
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
83
|
+
async recordFailure(key) {
|
|
84
|
+
local.bump(key);
|
|
85
|
+
try {
|
|
86
|
+
if (store.increment) {
|
|
87
|
+
await store.increment(key, ATTEMPT_LEDGER_TTL_SECONDS);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const current = parseCount(await store.get(key));
|
|
91
|
+
await store.set(key, String(current + 1), ATTEMPT_LEDGER_TTL_SECONDS);
|
|
92
|
+
} catch (error) {
|
|
93
|
+
unpersisted.bump(key);
|
|
94
|
+
throw error;
|
|
95
|
+
}
|
|
47
96
|
},
|
|
48
97
|
async reset(key) {
|
|
98
|
+
local.clear(key);
|
|
99
|
+
unpersisted.clear(key);
|
|
49
100
|
await store.delete(key);
|
|
50
101
|
}
|
|
51
102
|
};
|
|
@@ -60,6 +111,7 @@ function attemptLimitError(action, key, failures) {
|
|
|
60
111
|
}
|
|
61
112
|
const DEFAULT_SAFE_ATTEMPTS = 3;
|
|
62
113
|
const DEFAULT_RETRY_DELAY_MS = 1e3;
|
|
114
|
+
const RETRY_JITTER = .2;
|
|
63
115
|
function readEnv(name) {
|
|
64
116
|
const value = (globalThis.process?.env)?.[name]?.trim();
|
|
65
117
|
return value ? value : void 0;
|
|
@@ -109,22 +161,49 @@ function sleep(ms, signal) {
|
|
|
109
161
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
110
162
|
});
|
|
111
163
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
164
|
+
function hookWarning(name, action, error) {
|
|
165
|
+
return {
|
|
166
|
+
kind: "hook",
|
|
167
|
+
message: `A(z) ${name} hook hibát dobott, a kassza figyelmen kívül hagyta.`,
|
|
168
|
+
error,
|
|
169
|
+
action,
|
|
170
|
+
operation: name
|
|
171
|
+
};
|
|
118
172
|
}
|
|
119
|
-
function callHook(
|
|
173
|
+
function callHook(hooks, name, event) {
|
|
174
|
+
const hook = hooks[name];
|
|
120
175
|
if (!hook) return;
|
|
121
176
|
try {
|
|
122
177
|
const result = hook(event);
|
|
123
|
-
if (result instanceof Promise) result.catch(() =>
|
|
124
|
-
} catch {
|
|
125
|
-
|
|
178
|
+
if (result instanceof Promise) result.catch((error) => emitWarning(hooks.onWarning, hookWarning(name, event.action, error)));
|
|
179
|
+
} catch (error) {
|
|
180
|
+
emitWarning(hooks.onWarning, hookWarning(name, event.action, error));
|
|
126
181
|
}
|
|
127
182
|
}
|
|
183
|
+
function parseRetryAfter(value, now) {
|
|
184
|
+
if (value === null) return void 0;
|
|
185
|
+
const trimmed = value.trim();
|
|
186
|
+
if (/^\d+$/.test(trimmed)) return Number(trimmed) * 1e3;
|
|
187
|
+
const date = Date.parse(trimmed);
|
|
188
|
+
if (Number.isNaN(date)) return void 0;
|
|
189
|
+
return Math.max(0, date - now);
|
|
190
|
+
}
|
|
191
|
+
function retryDelay(baseMs, attempt, random = Math.random()) {
|
|
192
|
+
const backoff = baseMs * 2 ** (attempt - 1);
|
|
193
|
+
return Math.round(backoff * (.8 + 2 * RETRY_JITTER * random));
|
|
194
|
+
}
|
|
195
|
+
function resolveLedgerMode(value) {
|
|
196
|
+
if (value === void 0 || value === "fail-open" || value === "fail-closed") return value ?? "fail-open";
|
|
197
|
+
throw configurationError(`Az attemptLedgerMode értéke 'fail-open' vagy 'fail-closed' lehet, kapott: ${String(value)}`);
|
|
198
|
+
}
|
|
199
|
+
function storeUnavailableError(action, error) {
|
|
200
|
+
return new SzamlazzError("A próbálkozás-napló tárolója nem érhető el, ezért a kassza nem küldte el a kérést.", {
|
|
201
|
+
category: "store_unavailable",
|
|
202
|
+
action,
|
|
203
|
+
cause: error,
|
|
204
|
+
hint: "Az attemptLedgerMode: 'fail-closed' beállítás miatt a kassza nem küld kérést, amíg a napló (például a Redis) nem elérhető. Állítsd helyre a tárolót, vagy válts 'fail-open' módra."
|
|
205
|
+
});
|
|
206
|
+
}
|
|
128
207
|
function clampAttempts(value) {
|
|
129
208
|
if (value === void 0) return DEFAULT_SAFE_ATTEMPTS;
|
|
130
209
|
if (!Number.isInteger(value) || value < 1) throw configurationError(`A maxAttempts értéke legalább 1 egész szám legyen, kapott: ${value}`);
|
|
@@ -164,11 +243,27 @@ function createAgentContext(options = {}) {
|
|
|
164
243
|
return sessionKeyPromise;
|
|
165
244
|
};
|
|
166
245
|
const hooks = options.hooks ?? {};
|
|
246
|
+
const warn = (warning) => emitWarning(hooks.onWarning, warning);
|
|
167
247
|
const ledger = options.attemptLedger ? createAttemptLedger(options.attemptLedger) : void 0;
|
|
248
|
+
const ledgerMode = resolveLedgerMode(options.attemptLedgerMode);
|
|
249
|
+
async function ignoreStoreFailure(operation, action, run) {
|
|
250
|
+
try {
|
|
251
|
+
return await run();
|
|
252
|
+
} catch (error) {
|
|
253
|
+
warn({
|
|
254
|
+
kind: "session",
|
|
255
|
+
message: `A session cookie tároló "${operation}" művelete sikertelen, a kérés session nélkül folytatódik.`,
|
|
256
|
+
error,
|
|
257
|
+
action,
|
|
258
|
+
operation
|
|
259
|
+
});
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
168
263
|
const cooldownMs = resolveCooldown(options.maintenanceCooldownMs);
|
|
169
264
|
let blockedUntil = 0;
|
|
170
265
|
async function send(request) {
|
|
171
|
-
const cookie = cookieStore ? await ignoreStoreFailure(async () => cookieStore.get(await resolveSessionKey())) : void 0;
|
|
266
|
+
const cookie = cookieStore ? await ignoreStoreFailure("get", request.action, async () => cookieStore.get(await resolveSessionKey())) : void 0;
|
|
172
267
|
request.signal?.throwIfAborted();
|
|
173
268
|
const headers = new Headers({ Accept: "application/xml, application/pdf, text/plain, */*" });
|
|
174
269
|
if (cookie) headers.set("Cookie", cookie);
|
|
@@ -199,12 +294,15 @@ function createAgentContext(options = {}) {
|
|
|
199
294
|
}
|
|
200
295
|
if (cookieStore) {
|
|
201
296
|
const merged = mergeSetCookies(cookie, response.headers);
|
|
202
|
-
if (merged) await ignoreStoreFailure(async () => cookieStore.set(await resolveSessionKey(), merged, SESSION_TTL_SECONDS));
|
|
297
|
+
if (merged) await ignoreStoreFailure("set", request.action, async () => cookieStore.set(await resolveSessionKey(), merged, SESSION_TTL_SECONDS));
|
|
203
298
|
}
|
|
204
|
-
return
|
|
299
|
+
return {
|
|
300
|
+
response: createAgentResponse(request.action, response.status, response.headers, body),
|
|
301
|
+
sessionReused: Boolean(cookie)
|
|
302
|
+
};
|
|
205
303
|
}
|
|
206
304
|
async function resetSession() {
|
|
207
|
-
if (cookieStore) await ignoreStoreFailure(async () => cookieStore.delete(await resolveSessionKey()));
|
|
305
|
+
if (cookieStore) await ignoreStoreFailure("delete", void 0, async () => cookieStore.delete(await resolveSessionKey()));
|
|
208
306
|
}
|
|
209
307
|
async function resetAttempts(key) {
|
|
210
308
|
if (ledger) await ledger.reset(key);
|
|
@@ -220,6 +318,41 @@ function createAgentContext(options = {}) {
|
|
|
220
318
|
}))
|
|
221
319
|
});
|
|
222
320
|
}
|
|
321
|
+
function ledgerWarning(operation, action, error) {
|
|
322
|
+
warn({
|
|
323
|
+
kind: "ledger",
|
|
324
|
+
message: `A próbálkozás-napló tárolójának "${operation}" művelete sikertelen. A kassza a folyamaton belüli számlálót használja, a folyamatok közötti védelem most nem él.`,
|
|
325
|
+
error,
|
|
326
|
+
action,
|
|
327
|
+
operation
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
async function readFailures(action, key) {
|
|
331
|
+
if (!ledger || key === void 0) return 0;
|
|
332
|
+
try {
|
|
333
|
+
return await ledger.failures(key);
|
|
334
|
+
} catch (error) {
|
|
335
|
+
if (ledgerMode === "fail-closed") throw storeUnavailableError(action, error);
|
|
336
|
+
ledgerWarning("get", action, error);
|
|
337
|
+
return ledger.fallbackFailures(key);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
async function recordFailure(action, key) {
|
|
341
|
+
if (!ledger || key === void 0) return;
|
|
342
|
+
try {
|
|
343
|
+
await ledger.recordFailure(key);
|
|
344
|
+
} catch (error) {
|
|
345
|
+
ledgerWarning("increment", action, error);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
async function clearFailures(action, key) {
|
|
349
|
+
if (!ledger || key === void 0) return;
|
|
350
|
+
try {
|
|
351
|
+
await ledger.reset(key);
|
|
352
|
+
} catch (error) {
|
|
353
|
+
ledgerWarning("delete", action, error);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
223
356
|
function assertNoCooldown(action) {
|
|
224
357
|
const remainingMs = blockedUntil - Date.now();
|
|
225
358
|
if (remainingMs > 0) throw maintenanceCooldownError(action, remainingMs);
|
|
@@ -227,45 +360,72 @@ function createAgentContext(options = {}) {
|
|
|
227
360
|
async function execute(request, parse) {
|
|
228
361
|
const maxAttempts = request.safeToRetry ? safeAttempts : 1;
|
|
229
362
|
const ledgerKey = await ledgerKeyFor(request);
|
|
363
|
+
const requestId = crypto.randomUUID();
|
|
230
364
|
for (let attempt = 1;; attempt++) {
|
|
231
365
|
assertNoCooldown(request.action);
|
|
232
|
-
const failures =
|
|
366
|
+
const failures = await readFailures(request.action, ledgerKey);
|
|
233
367
|
if (ledgerKey !== void 0 && failures >= 5) throw attemptLimitError(request.action, ledgerKey, failures);
|
|
234
368
|
const startedAt = Date.now();
|
|
235
|
-
|
|
369
|
+
let retryAfterMs;
|
|
370
|
+
const base = {
|
|
236
371
|
action: request.action,
|
|
237
|
-
attempt
|
|
238
|
-
|
|
372
|
+
attempt,
|
|
373
|
+
requestId
|
|
374
|
+
};
|
|
375
|
+
callHook(hooks, "onRequest", base);
|
|
239
376
|
try {
|
|
240
|
-
const response = await send(request);
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
377
|
+
const { response, sessionReused } = await send(request);
|
|
378
|
+
retryAfterMs = parseRetryAfter(response.headers.get("retry-after"), Date.now());
|
|
379
|
+
callHook(hooks, "onResponse", {
|
|
380
|
+
...base,
|
|
244
381
|
status: response.status,
|
|
245
|
-
durationMs: Date.now() - startedAt
|
|
382
|
+
durationMs: Date.now() - startedAt,
|
|
383
|
+
responseBytes: response.body.byteLength,
|
|
384
|
+
sessionReused
|
|
246
385
|
});
|
|
247
386
|
const result = await parse(response);
|
|
248
|
-
if (
|
|
387
|
+
if (failures > 0) await clearFailures(request.action, ledgerKey);
|
|
388
|
+
callHook(hooks, "onComplete", {
|
|
389
|
+
...base,
|
|
390
|
+
outcome: "success",
|
|
391
|
+
durationMs: Date.now() - startedAt,
|
|
392
|
+
willRetry: false
|
|
393
|
+
});
|
|
249
394
|
return result;
|
|
250
395
|
} catch (error) {
|
|
251
|
-
if (!(error instanceof SzamlazzError))
|
|
252
|
-
|
|
396
|
+
if (!(error instanceof SzamlazzError)) {
|
|
397
|
+
callHook(hooks, "onComplete", {
|
|
398
|
+
...base,
|
|
399
|
+
outcome: "error",
|
|
400
|
+
durationMs: Date.now() - startedAt,
|
|
401
|
+
willRetry: false
|
|
402
|
+
});
|
|
403
|
+
throw error;
|
|
404
|
+
}
|
|
405
|
+
if (countsAsFailedAttempt(error)) await recordFailure(request.action, ledgerKey);
|
|
253
406
|
if (error.category === "maintenance" && cooldownMs > 0) blockedUntil = Date.now() + cooldownMs;
|
|
254
|
-
const willRetry = error.retryable && attempt < maxAttempts && !(error.category === "maintenance" && cooldownMs > 0);
|
|
255
|
-
callHook(hooks
|
|
256
|
-
|
|
257
|
-
|
|
407
|
+
const willRetry = error.retryable && attempt < maxAttempts && !(error.category === "maintenance" && cooldownMs > 0) && (retryAfterMs === void 0 || retryAfterMs <= 6e4);
|
|
408
|
+
callHook(hooks, "onError", {
|
|
409
|
+
...base,
|
|
410
|
+
error,
|
|
411
|
+
willRetry
|
|
412
|
+
});
|
|
413
|
+
callHook(hooks, "onComplete", {
|
|
414
|
+
...base,
|
|
415
|
+
outcome: "error",
|
|
416
|
+
durationMs: Date.now() - startedAt,
|
|
258
417
|
error,
|
|
259
418
|
willRetry
|
|
260
419
|
});
|
|
261
420
|
if (error.category === "auth") await resetSession();
|
|
262
421
|
if (!willRetry) throw error;
|
|
263
|
-
await sleep(retryDelayMs
|
|
422
|
+
await sleep(Math.max(retryDelay(retryDelayMs, attempt), retryAfterMs ?? 0), request.signal);
|
|
264
423
|
}
|
|
265
424
|
}
|
|
266
425
|
}
|
|
267
426
|
return {
|
|
268
427
|
credentials,
|
|
428
|
+
warn,
|
|
269
429
|
execute,
|
|
270
430
|
resetSession,
|
|
271
431
|
resetAttempts
|
|
@@ -412,12 +572,12 @@ function sellerNode(seller) {
|
|
|
412
572
|
function buyerLedgerNode(ledger) {
|
|
413
573
|
if (!ledger) return void 0;
|
|
414
574
|
return optionalEl("vevoFokonyv", [
|
|
415
|
-
optionalEl("konyvelesDatum", optionalAgentDate
|
|
575
|
+
optionalEl("konyvelesDatum", optionalAgentDate(ledger.bookingDate, "buyer.ledger.bookingDate")),
|
|
416
576
|
textEl("vevoAzonosito", ledger.buyerId),
|
|
417
577
|
textEl("vevoFokonyviSzam", ledger.ledgerAccount),
|
|
418
578
|
optionalEl("folyamatosTelj", ledger.continuousFulfillment),
|
|
419
|
-
optionalEl("elszDatumTol", optionalAgentDate
|
|
420
|
-
optionalEl("elszDatumIg", optionalAgentDate
|
|
579
|
+
optionalEl("elszDatumTol", optionalAgentDate(ledger.settlementPeriodStart, "buyer.ledger.settlementPeriodStart")),
|
|
580
|
+
optionalEl("elszDatumIg", optionalAgentDate(ledger.settlementPeriodEnd, "buyer.ledger.settlementPeriodEnd"))
|
|
421
581
|
]);
|
|
422
582
|
}
|
|
423
583
|
function buyerNode(buyer, sendEmail) {
|
|
@@ -486,8 +646,8 @@ function itemLedgerNode(ledger, label) {
|
|
|
486
646
|
textEl("gazdasagiEsemAfa", ledger.vatEconomicEvent),
|
|
487
647
|
textEl("arbevetelFokonyviSzam", ledger.revenueLedgerAccount),
|
|
488
648
|
textEl("afaFokonyviSzam", ledger.vatLedgerAccount),
|
|
489
|
-
optionalEl("elszDatumTol", optionalAgentDate
|
|
490
|
-
optionalEl("elszDatumIg", optionalAgentDate
|
|
649
|
+
optionalEl("elszDatumTol", optionalAgentDate(ledger.settlementPeriodStart, `${label} settlementPeriodStart`)),
|
|
650
|
+
optionalEl("elszDatumIg", optionalAgentDate(ledger.settlementPeriodEnd, `${label} settlementPeriodEnd`))
|
|
491
651
|
]);
|
|
492
652
|
}
|
|
493
653
|
function itemNode(item, index) {
|
|
@@ -524,6 +684,9 @@ function renderInvoiceXml(credentials, invoice, options = {}) {
|
|
|
524
684
|
]
|
|
525
685
|
});
|
|
526
686
|
}
|
|
687
|
+
function buildCreateInvoiceXml(credentials, defaults, input, now = /* @__PURE__ */ new Date()) {
|
|
688
|
+
return renderInvoiceXml(credentials, resolveInvoice(defaults, input, now));
|
|
689
|
+
}
|
|
527
690
|
//#endregion
|
|
528
691
|
//#region src/invoices/create.ts
|
|
529
692
|
function buildRequest(ctx, invoice, preview, options) {
|
|
@@ -550,455 +713,6 @@ async function previewInvoice(ctx, defaults, input, options = {}) {
|
|
|
550
713
|
return ctx.execute(buildRequest(ctx, invoice, true, options), (response) => parseInvoicePreviewResponse(response, items));
|
|
551
714
|
}
|
|
552
715
|
//#endregion
|
|
553
|
-
//#region src/invoices/reference.ts
|
|
554
|
-
const AGENT_XSD_BASE_URL = "https://www.szamlazz.hu/szamla/docs/xsds/";
|
|
555
|
-
function validationError(message) {
|
|
556
|
-
return new SzamlazzError(message, { category: "validation" });
|
|
557
|
-
}
|
|
558
|
-
function requireText(value, message) {
|
|
559
|
-
const trimmed = typeof value === "string" ? value.trim() : "";
|
|
560
|
-
if (trimmed === "") throw validationError(message);
|
|
561
|
-
return trimmed;
|
|
562
|
-
}
|
|
563
|
-
function optionalText(value) {
|
|
564
|
-
const trimmed = value?.trim();
|
|
565
|
-
return trimmed ? trimmed : void 0;
|
|
566
|
-
}
|
|
567
|
-
function agentDate(input, field) {
|
|
568
|
-
try {
|
|
569
|
-
return toAgentDate(input);
|
|
570
|
-
} catch (error) {
|
|
571
|
-
const detail = error instanceof Error ? error.message : String(error);
|
|
572
|
-
throw new SzamlazzError(`Érvénytelen dátum (${field}): ${detail}`, {
|
|
573
|
-
category: "validation",
|
|
574
|
-
cause: error
|
|
575
|
-
});
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
function optionalAgentDate(input, field) {
|
|
579
|
-
return input === void 0 ? void 0 : agentDate(input, field);
|
|
580
|
-
}
|
|
581
|
-
const REFERENCE_KEYS = [
|
|
582
|
-
"invoiceNumber",
|
|
583
|
-
"orderNumber",
|
|
584
|
-
"externalId"
|
|
585
|
-
];
|
|
586
|
-
const REFERENCE_HINT$1 = "Add meg a számlaszámot szövegként, vagy pontosan egyet ezek közül: { invoiceNumber }, { orderNumber }, { externalId }.";
|
|
587
|
-
function resolveInvoiceReference(reference) {
|
|
588
|
-
if (typeof reference === "string") return {
|
|
589
|
-
kind: "invoiceNumber",
|
|
590
|
-
value: requireText(reference, `Üres számlaszám. ${REFERENCE_HINT$1}`)
|
|
591
|
-
};
|
|
592
|
-
if (typeof reference !== "object" || reference === null) throw validationError(`Érvénytelen bizonylat-hivatkozás. ${REFERENCE_HINT$1}`);
|
|
593
|
-
const record = reference;
|
|
594
|
-
const present = REFERENCE_KEYS.filter((key) => record[key] !== void 0);
|
|
595
|
-
const [kind] = present;
|
|
596
|
-
if (kind === void 0 || present.length > 1) throw validationError(`Érvénytelen bizonylat-hivatkozás. ${REFERENCE_HINT$1}`);
|
|
597
|
-
return {
|
|
598
|
-
kind,
|
|
599
|
-
value: requireText(record[kind], `Üres ${kind} érték. ${REFERENCE_HINT$1}`)
|
|
600
|
-
};
|
|
601
|
-
}
|
|
602
|
-
function referenceValue(reference, kind) {
|
|
603
|
-
return reference.kind === kind ? reference.value : void 0;
|
|
604
|
-
}
|
|
605
|
-
function readNumericHeader(headers, name) {
|
|
606
|
-
const value = readHeader$1(headers, name);
|
|
607
|
-
if (value === void 0) return void 0;
|
|
608
|
-
const parsed = Number(value.replace(",", "."));
|
|
609
|
-
return Number.isFinite(parsed) ? parsed : void 0;
|
|
610
|
-
}
|
|
611
|
-
function headerSummary(response) {
|
|
612
|
-
const headers = readDocumentHeaders(response.headers);
|
|
613
|
-
return {
|
|
614
|
-
number: headers.number,
|
|
615
|
-
netTotal: headers.netTotal,
|
|
616
|
-
grossTotal: headers.grossTotal,
|
|
617
|
-
outstanding: readNumericHeader(response.headers, "szlahu_kintlevoseg"),
|
|
618
|
-
buyerAccountUrl: headers.buyerAccountUrl
|
|
619
|
-
};
|
|
620
|
-
}
|
|
621
|
-
function decodeResponsePdf(root, response) {
|
|
622
|
-
const encoded = childText(root, "pdf");
|
|
623
|
-
if (encoded === void 0) return void 0;
|
|
624
|
-
try {
|
|
625
|
-
return base64ToBytes(encoded);
|
|
626
|
-
} catch (error) {
|
|
627
|
-
throw new SzamlazzError("A válaszban kapott PDF nem érvényes base64.", {
|
|
628
|
-
category: "unexpected_response",
|
|
629
|
-
action: response.action,
|
|
630
|
-
httpStatus: response.status,
|
|
631
|
-
cause: error
|
|
632
|
-
});
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
|
-
function readInvoiceResultXml(root, response) {
|
|
636
|
-
const headers = headerSummary(response);
|
|
637
|
-
return {
|
|
638
|
-
number: childText(root, "szamlaszam") ?? headers.number,
|
|
639
|
-
netTotal: childNumber(root, "szamlanetto") ?? headers.netTotal,
|
|
640
|
-
grossTotal: childNumber(root, "szamlabrutto") ?? headers.grossTotal,
|
|
641
|
-
outstanding: childNumber(root, "kintlevoseg") ?? headers.outstanding,
|
|
642
|
-
buyerAccountUrl: childText(root, "vevoifiokurl") ?? headers.buyerAccountUrl,
|
|
643
|
-
pdf: decodeResponsePdf(root, response)
|
|
644
|
-
};
|
|
645
|
-
}
|
|
646
|
-
const INVOICE_RESULT_ROOT = "xmlszamlavalasz";
|
|
647
|
-
function parseInvoiceResult(response) {
|
|
648
|
-
throwIfHeaderError(response);
|
|
649
|
-
if (response.isPdf) return {
|
|
650
|
-
...headerSummary(response),
|
|
651
|
-
pdf: response.body
|
|
652
|
-
};
|
|
653
|
-
throwIfTextError(response);
|
|
654
|
-
throwIfHttpError(response);
|
|
655
|
-
if (looksLikeXml(response)) {
|
|
656
|
-
const root = parseResponseXml(response);
|
|
657
|
-
throwIfXmlFailure(root, response);
|
|
658
|
-
if (root.name !== INVOICE_RESULT_ROOT || childText(root, "sikeres")?.toLowerCase() !== "true") throw unexpectedResponse(response, `${INVOICE_RESULT_ROOT} XML választ vártunk.`);
|
|
659
|
-
return readInvoiceResultXml(root, response);
|
|
660
|
-
}
|
|
661
|
-
const headers = headerSummary(response);
|
|
662
|
-
const done = parseDoneText(response.text());
|
|
663
|
-
if (done) return {
|
|
664
|
-
...headers,
|
|
665
|
-
number: done.number ?? headers.number
|
|
666
|
-
};
|
|
667
|
-
if (headers.number !== void 0) return headers;
|
|
668
|
-
throw unexpectedResponse(response);
|
|
669
|
-
}
|
|
670
|
-
//#endregion
|
|
671
|
-
//#region src/invoices/get.ts
|
|
672
|
-
const INVOICE_DOCUMENT_TYPE_CODES = {
|
|
673
|
-
invoice: "SZ",
|
|
674
|
-
proforma: "D",
|
|
675
|
-
advance: "ES",
|
|
676
|
-
final: "VS",
|
|
677
|
-
corrective: "HS",
|
|
678
|
-
reversal: "SS",
|
|
679
|
-
deliveryNote: "SL"
|
|
680
|
-
};
|
|
681
|
-
function buildGetInvoiceXml(credentials, reference, query = {}) {
|
|
682
|
-
const resolved = resolveInvoiceReference(reference);
|
|
683
|
-
return buildXmlDocument({
|
|
684
|
-
root: "xmlszamlaxml",
|
|
685
|
-
namespace: "http://www.szamlazz.hu/xmlszamlaxml",
|
|
686
|
-
schemaLocation: `${AGENT_XSD_BASE_URL}agentxml/xmlszamlaxml.xsd`,
|
|
687
|
-
children: [
|
|
688
|
-
...credentials,
|
|
689
|
-
optionalEl("szamlaszam", referenceValue(resolved, "invoiceNumber")),
|
|
690
|
-
optionalEl("rendelesSzam", referenceValue(resolved, "orderNumber")),
|
|
691
|
-
optionalEl("pdf", query.includePdf),
|
|
692
|
-
optionalEl("szamlaKulsoAzon", referenceValue(resolved, "externalId"))
|
|
693
|
-
]
|
|
694
|
-
});
|
|
695
|
-
}
|
|
696
|
-
var InvoiceReader = class {
|
|
697
|
-
response;
|
|
698
|
-
constructor(response) {
|
|
699
|
-
this.response = response;
|
|
700
|
-
}
|
|
701
|
-
missing(path) {
|
|
702
|
-
return unexpectedResponse(this.response, `Hiányzik a(z) <${path}> elem a számla XML-ből.`);
|
|
703
|
-
}
|
|
704
|
-
element(parent, name, path) {
|
|
705
|
-
const child = findChild(parent, name);
|
|
706
|
-
if (!child) throw this.missing(path);
|
|
707
|
-
return child;
|
|
708
|
-
}
|
|
709
|
-
text(parent, name, path) {
|
|
710
|
-
const value = childText(parent, name);
|
|
711
|
-
if (value === void 0) throw this.missing(`${path}/${name}`);
|
|
712
|
-
return value;
|
|
713
|
-
}
|
|
714
|
-
number(parent, name, path) {
|
|
715
|
-
const value = childNumber(parent, name);
|
|
716
|
-
if (value === void 0) throw this.missing(`${path}/${name}`);
|
|
717
|
-
return value;
|
|
718
|
-
}
|
|
719
|
-
};
|
|
720
|
-
function readAddress(element) {
|
|
721
|
-
if (!element) return void 0;
|
|
722
|
-
return {
|
|
723
|
-
name: childText(element, "nev"),
|
|
724
|
-
country: childText(element, "orszag"),
|
|
725
|
-
zip: childText(element, "irsz"),
|
|
726
|
-
city: childText(element, "telepules"),
|
|
727
|
-
address: childText(element, "cim")
|
|
728
|
-
};
|
|
729
|
-
}
|
|
730
|
-
function readSeller(root, reader) {
|
|
731
|
-
const seller = reader.element(root, "szallito", "szallito");
|
|
732
|
-
const bank = findChild(seller, "bank");
|
|
733
|
-
return {
|
|
734
|
-
id: childNumber(seller, "id"),
|
|
735
|
-
name: reader.text(seller, "nev", "szallito"),
|
|
736
|
-
address: readAddress(findChild(seller, "cim")),
|
|
737
|
-
postalAddress: readAddress(findChild(seller, "postacim")),
|
|
738
|
-
taxNumber: childText(seller, "adoszam"),
|
|
739
|
-
groupTaxNumber: childText(seller, "csoportazonosito"),
|
|
740
|
-
euTaxNumber: childText(seller, "adoszameu"),
|
|
741
|
-
bank: bank && {
|
|
742
|
-
name: childText(bank, "nev"),
|
|
743
|
-
accountNumber: childText(bank, "bankszamla")
|
|
744
|
-
}
|
|
745
|
-
};
|
|
746
|
-
}
|
|
747
|
-
const DOCUMENT_TYPES_BY_CODE = new Map(Object.entries(INVOICE_DOCUMENT_TYPE_CODES).map(([type, code]) => [code, type]));
|
|
748
|
-
const E_INVOICE_CODES = /* @__PURE__ */ new Set([2, 3]);
|
|
749
|
-
function readHeader(root, reader) {
|
|
750
|
-
const header = reader.element(root, "alap", "alap");
|
|
751
|
-
const typeCode = reader.text(header, "tipus", "alap");
|
|
752
|
-
const appearanceCode = childNumber(header, "eszamla");
|
|
753
|
-
return {
|
|
754
|
-
id: childNumber(header, "id"),
|
|
755
|
-
number: reader.text(header, "szamlaszam", "alap"),
|
|
756
|
-
economicEventId: childNumber(header, "gazdEsemAzon"),
|
|
757
|
-
sourceSystem: childNumber(header, "forras"),
|
|
758
|
-
registrationNumber: childText(header, "iktatoszam"),
|
|
759
|
-
type: DOCUMENT_TYPES_BY_CODE.get(typeCode) ?? "unknown",
|
|
760
|
-
typeCode,
|
|
761
|
-
eInvoice: appearanceCode !== void 0 && E_INVOICE_CODES.has(appearanceCode),
|
|
762
|
-
appearanceCode,
|
|
763
|
-
referencedInvoiceNumber: childText(header, "hivszamlaszam"),
|
|
764
|
-
referencedProformaNumber: childText(header, "hivdijbekszam"),
|
|
765
|
-
issueDate: reader.text(header, "kelt", "alap"),
|
|
766
|
-
fulfillmentDate: childText(header, "telj"),
|
|
767
|
-
dueDate: childText(header, "fizh"),
|
|
768
|
-
paymentMethod: childText(header, "fizmod"),
|
|
769
|
-
unifiedPaymentMethod: childText(header, "fizmodunified"),
|
|
770
|
-
cash: childBoolean(header, "keszpenz"),
|
|
771
|
-
orderNumber: childText(header, "rendelesszam"),
|
|
772
|
-
language: childText(header, "nyelv"),
|
|
773
|
-
currency: childText(header, "devizanem"),
|
|
774
|
-
exchangeBank: childText(header, "devizabank"),
|
|
775
|
-
exchangeRate: childNumber(header, "devizaarf"),
|
|
776
|
-
comment: childText(header, "megjegyzes"),
|
|
777
|
-
vatType: childText(header, "afatipus"),
|
|
778
|
-
cashAccounting: childBoolean(header, "penzforg"),
|
|
779
|
-
kata: childBoolean(header, "kata"),
|
|
780
|
-
kataLedger: childBoolean(header, "katafokonyv"),
|
|
781
|
-
email: childText(header, "email"),
|
|
782
|
-
test: childBoolean(header, "teszt"),
|
|
783
|
-
reversed: childBoolean(header, "sztornozott")
|
|
784
|
-
};
|
|
785
|
-
}
|
|
786
|
-
function readBuyerLedger(element) {
|
|
787
|
-
if (!element) return void 0;
|
|
788
|
-
return {
|
|
789
|
-
ledgerAccount: childText(element, "vevo"),
|
|
790
|
-
buyerId: childText(element, "vevoazon"),
|
|
791
|
-
bookingDate: childText(element, "datum"),
|
|
792
|
-
continuousFulfillment: childBoolean(element, "folyamatostelj"),
|
|
793
|
-
settlementPeriodStart: childText(element, "elszDatTol") ?? childText(element, "elszdattol"),
|
|
794
|
-
settlementPeriodEnd: childText(element, "elszDatIg") ?? childText(element, "elszdatig")
|
|
795
|
-
};
|
|
796
|
-
}
|
|
797
|
-
function readBuyer(root, reader) {
|
|
798
|
-
const buyer = reader.element(root, "vevo", "vevo");
|
|
799
|
-
return {
|
|
800
|
-
id: childNumber(buyer, "id"),
|
|
801
|
-
name: reader.text(buyer, "nev", "vevo"),
|
|
802
|
-
identifier: childText(buyer, "azonosito"),
|
|
803
|
-
address: readAddress(findChild(buyer, "cim")),
|
|
804
|
-
postalAddress: readAddress(findChild(buyer, "postacim")),
|
|
805
|
-
email: childText(buyer, "email"),
|
|
806
|
-
taxNumber: childText(buyer, "adoszam"),
|
|
807
|
-
groupTaxNumber: childText(buyer, "csoportazonosito"),
|
|
808
|
-
euTaxNumber: childText(buyer, "adoszameu"),
|
|
809
|
-
location: childNumber(buyer, "lokacio"),
|
|
810
|
-
privatePerson: childBoolean(buyer, "privatePersonIndicator"),
|
|
811
|
-
ledger: readBuyerLedger(findChild(buyer, "fokonyv"))
|
|
812
|
-
};
|
|
813
|
-
}
|
|
814
|
-
function readItemLedger(element) {
|
|
815
|
-
if (!element) return void 0;
|
|
816
|
-
return {
|
|
817
|
-
revenueLedgerAccount: childText(element, "arbevetel"),
|
|
818
|
-
vatLedgerAccount: childText(element, "afa"),
|
|
819
|
-
economicEvent: childText(element, "gazdasagiesemeny"),
|
|
820
|
-
vatEconomicEvent: childText(element, "gazdasagiesemenyafa"),
|
|
821
|
-
settlementPeriodStart: childText(element, "elszdattol"),
|
|
822
|
-
settlementPeriodEnd: childText(element, "elszdatig")
|
|
823
|
-
};
|
|
824
|
-
}
|
|
825
|
-
function readItem(item, reader) {
|
|
826
|
-
const path = "tetelek/tetel";
|
|
827
|
-
return {
|
|
828
|
-
name: reader.text(item, "nev", path),
|
|
829
|
-
identifier: childText(item, "azonosito"),
|
|
830
|
-
quantity: reader.number(item, "mennyiseg", path),
|
|
831
|
-
unit: childText(item, "mennyisegiegyseg"),
|
|
832
|
-
netUnitPrice: reader.number(item, "nettoegysegar", path),
|
|
833
|
-
vat: reader.number(item, "afakulcs", path),
|
|
834
|
-
vatCode: childText(item, "afatipus"),
|
|
835
|
-
netAmount: reader.number(item, "netto", path),
|
|
836
|
-
marginVatBase: childNumber(item, "arresafaalap"),
|
|
837
|
-
vatAmount: reader.number(item, "afa", path),
|
|
838
|
-
grossAmount: reader.number(item, "brutto", path),
|
|
839
|
-
comment: childText(item, "megjegyzes"),
|
|
840
|
-
position: childNumber(item, "sztetordering"),
|
|
841
|
-
ledger: readItemLedger(findChild(item, "fokonyv"))
|
|
842
|
-
};
|
|
843
|
-
}
|
|
844
|
-
function readLabels(element) {
|
|
845
|
-
return findChildren(element, "cimke").flatMap((label) => {
|
|
846
|
-
const value = label.text.trim();
|
|
847
|
-
return value === "" ? [] : [value];
|
|
848
|
-
});
|
|
849
|
-
}
|
|
850
|
-
function readFinancialItem(item, reader) {
|
|
851
|
-
const path = "qutetek/qutet";
|
|
852
|
-
return {
|
|
853
|
-
name: reader.text(item, "nev", path),
|
|
854
|
-
vat: reader.number(item, "afakulcs", path),
|
|
855
|
-
vatCode: childText(item, "afatipus"),
|
|
856
|
-
netAmount: reader.number(item, "netto", path),
|
|
857
|
-
vatAmount: reader.number(item, "afa", path),
|
|
858
|
-
grossAmount: reader.number(item, "brutto", path),
|
|
859
|
-
settlementPeriodStart: childText(item, "elszdattol"),
|
|
860
|
-
settlementPeriodEnd: childText(item, "elszdatig"),
|
|
861
|
-
vatDeduction: childNumber(item, "afalevon"),
|
|
862
|
-
labels: readLabels(findChild(item, "cimkek"))
|
|
863
|
-
};
|
|
864
|
-
}
|
|
865
|
-
function readTotals(root, reader) {
|
|
866
|
-
const totals = reader.element(root, "osszegek", "osszegek");
|
|
867
|
-
const total = reader.element(totals, "totalossz", "osszegek/totalossz");
|
|
868
|
-
const path = "osszegek/totalossz";
|
|
869
|
-
return {
|
|
870
|
-
netAmount: reader.number(total, "netto", path),
|
|
871
|
-
vatAmount: reader.number(total, "afa", path),
|
|
872
|
-
grossAmount: reader.number(total, "brutto", path),
|
|
873
|
-
byVat: findChildren(totals, "afakulcsossz").map((entry) => ({
|
|
874
|
-
vat: reader.number(entry, "afakulcs", "osszegek/afakulcsossz"),
|
|
875
|
-
vatCode: childText(entry, "afatipus"),
|
|
876
|
-
netAmount: reader.number(entry, "netto", "osszegek/afakulcsossz"),
|
|
877
|
-
vatAmount: reader.number(entry, "afa", "osszegek/afakulcsossz"),
|
|
878
|
-
grossAmount: reader.number(entry, "brutto", "osszegek/afakulcsossz")
|
|
879
|
-
}))
|
|
880
|
-
};
|
|
881
|
-
}
|
|
882
|
-
function readPayment(payment, reader) {
|
|
883
|
-
const path = "kifizetesek/kifizetes";
|
|
884
|
-
return {
|
|
885
|
-
date: reader.text(payment, "datum", path),
|
|
886
|
-
method: reader.text(payment, "jogcim", path),
|
|
887
|
-
amount: reader.number(payment, "osszeg", path),
|
|
888
|
-
comment: childText(payment, "megjegyzes"),
|
|
889
|
-
bankAccountNumber: childText(payment, "bankszamlaszam"),
|
|
890
|
-
bankTransactionId: childNumber(payment, "banktranzid"),
|
|
891
|
-
exchangeRate: childNumber(payment, "devizaarf")
|
|
892
|
-
};
|
|
893
|
-
}
|
|
894
|
-
function parseInvoiceDetailsXml(root, response) {
|
|
895
|
-
const reader = new InvoiceReader(response);
|
|
896
|
-
return {
|
|
897
|
-
seller: readSeller(root, reader),
|
|
898
|
-
header: readHeader(root, reader),
|
|
899
|
-
buyer: readBuyer(root, reader),
|
|
900
|
-
items: findChildren(findChild(root, "tetelek"), "tetel").map((item) => readItem(item, reader)),
|
|
901
|
-
financialItems: findChildren(findChild(root, "qutetek"), "qutet").map((item) => readFinancialItem(item, reader)),
|
|
902
|
-
labels: readLabels(findChild(root, "cimkek")),
|
|
903
|
-
totals: readTotals(root, reader),
|
|
904
|
-
payments: findChildren(findChild(root, "kifizetesek"), "kifizetes").map((payment) => readPayment(payment, reader)),
|
|
905
|
-
pdf: decodeResponsePdf(root, response)
|
|
906
|
-
};
|
|
907
|
-
}
|
|
908
|
-
function parseGetInvoiceResponse(response) {
|
|
909
|
-
throwIfHeaderError(response);
|
|
910
|
-
throwIfTextError(response);
|
|
911
|
-
throwIfHttpError(response);
|
|
912
|
-
const root = parseResponseXml(response);
|
|
913
|
-
throwIfXmlFailure(root, response);
|
|
914
|
-
if (root.name !== "szamla") throw unexpectedResponse(response, "A számla XML (<szamla>) helyett más válasz érkezett.");
|
|
915
|
-
return parseInvoiceDetailsXml(root, response);
|
|
916
|
-
}
|
|
917
|
-
async function getInvoice(ctx, reference, query = {}, options = {}) {
|
|
918
|
-
const xml = buildGetInvoiceXml(ctx.credentials, reference, query);
|
|
919
|
-
return ctx.execute({
|
|
920
|
-
action: "getInvoiceXml",
|
|
921
|
-
xml,
|
|
922
|
-
signal: options.signal,
|
|
923
|
-
safeToRetry: true
|
|
924
|
-
}, parseGetInvoiceResponse);
|
|
925
|
-
}
|
|
926
|
-
function normalizeRegisterInput(input) {
|
|
927
|
-
const payments = "payments" in input ? input.payments : [{
|
|
928
|
-
amount: input.amount,
|
|
929
|
-
method: input.method ?? "átutalás",
|
|
930
|
-
date: input.date,
|
|
931
|
-
description: input.description
|
|
932
|
-
}];
|
|
933
|
-
if (!Array.isArray(payments) || payments.length === 0) throw validationError("Adj meg legalább egy befizetést (payments). A korábbi befizetések törléséhez a clearPayments függvényt használd.");
|
|
934
|
-
if (payments.length > 5) throw validationError(`Egy kérésben legfeljebb 5 befizetés rögzíthető, kapott: ${payments.length}.`);
|
|
935
|
-
return {
|
|
936
|
-
invoiceNumber: input.invoiceNumber,
|
|
937
|
-
taxNumber: input.taxNumber,
|
|
938
|
-
additive: input.additive ?? true,
|
|
939
|
-
payments
|
|
940
|
-
};
|
|
941
|
-
}
|
|
942
|
-
function normalizeClearInput(input) {
|
|
943
|
-
const target = typeof input === "string" ? { invoiceNumber: input } : input;
|
|
944
|
-
return {
|
|
945
|
-
invoiceNumber: target.invoiceNumber,
|
|
946
|
-
taxNumber: target.taxNumber,
|
|
947
|
-
additive: false,
|
|
948
|
-
payments: []
|
|
949
|
-
};
|
|
950
|
-
}
|
|
951
|
-
function paymentNode(payment, index) {
|
|
952
|
-
const position = index + 1;
|
|
953
|
-
if (typeof payment.amount !== "number" || !Number.isFinite(payment.amount)) throw validationError(`A(z) ${position}. befizetés összege (amount) nem véges szám.`);
|
|
954
|
-
return el("kifizetes", [
|
|
955
|
-
el("datum", payment.date === void 0 ? todayInBudapest() : agentDate(payment.date, "date")),
|
|
956
|
-
el("jogcim", requireText(payment.method, `Add meg a(z) ${position}. befizetés módját (method).`)),
|
|
957
|
-
el("osszeg", payment.amount),
|
|
958
|
-
optionalEl("leiras", optionalText(payment.description))
|
|
959
|
-
]);
|
|
960
|
-
}
|
|
961
|
-
function buildPaymentXml(credentials, request) {
|
|
962
|
-
const invoiceNumber = requireText(request.invoiceNumber, "Add meg a számla számát (invoiceNumber), amelyhez a befizetés tartozik.");
|
|
963
|
-
return buildXmlDocument({
|
|
964
|
-
root: "xmlszamlakifiz",
|
|
965
|
-
namespace: "http://www.szamlazz.hu/xmlszamlakifiz",
|
|
966
|
-
schemaLocation: `${AGENT_XSD_BASE_URL}agentkifiz/xmlszamlakifiz.xsd`,
|
|
967
|
-
children: [el("beallitasok", [
|
|
968
|
-
...credentials,
|
|
969
|
-
el("szamlaszam", invoiceNumber),
|
|
970
|
-
optionalEl("adoszam", optionalText(request.taxNumber)),
|
|
971
|
-
el("additiv", request.additive),
|
|
972
|
-
el("valaszVerzio", 2)
|
|
973
|
-
]), ...request.payments.map(paymentNode)]
|
|
974
|
-
});
|
|
975
|
-
}
|
|
976
|
-
function parseRegisterPaymentResponse(response, invoiceNumber) {
|
|
977
|
-
const result = parseInvoiceResult(response);
|
|
978
|
-
return {
|
|
979
|
-
invoiceNumber: result.number ?? invoiceNumber.trim(),
|
|
980
|
-
netTotal: result.netTotal,
|
|
981
|
-
grossTotal: result.grossTotal,
|
|
982
|
-
outstanding: result.outstanding,
|
|
983
|
-
buyerAccountUrl: result.buyerAccountUrl
|
|
984
|
-
};
|
|
985
|
-
}
|
|
986
|
-
function sendPaymentRequest(ctx, request, options) {
|
|
987
|
-
const xml = buildPaymentXml(ctx.credentials, request);
|
|
988
|
-
return ctx.execute({
|
|
989
|
-
action: "registerPayment",
|
|
990
|
-
xml,
|
|
991
|
-
signal: options.signal,
|
|
992
|
-
safeToRetry: !request.additive
|
|
993
|
-
}, (response) => parseRegisterPaymentResponse(response, request.invoiceNumber));
|
|
994
|
-
}
|
|
995
|
-
async function registerPayment(ctx, input, options = {}) {
|
|
996
|
-
return sendPaymentRequest(ctx, normalizeRegisterInput(input), options);
|
|
997
|
-
}
|
|
998
|
-
async function clearPayments(ctx, input, options = {}) {
|
|
999
|
-
return sendPaymentRequest(ctx, normalizeClearInput(input), options);
|
|
1000
|
-
}
|
|
1001
|
-
//#endregion
|
|
1002
716
|
//#region src/invoices/pdf.ts
|
|
1003
717
|
function buildInvoicePdfXml(credentials, reference) {
|
|
1004
718
|
const resolved = resolveInvoiceReference(reference);
|
|
@@ -1110,8 +824,8 @@ function buildReverseInvoiceXml(credentials, input) {
|
|
|
1110
824
|
]),
|
|
1111
825
|
el("fejlec", [
|
|
1112
826
|
el("szamlaszam", invoiceNumber),
|
|
1113
|
-
optionalEl("keltDatum", optionalAgentDate(options.issueDate, "issueDate")),
|
|
1114
|
-
optionalEl("teljesitesDatum", optionalAgentDate(options.fulfillmentDate, "fulfillmentDate")),
|
|
827
|
+
optionalEl("keltDatum", optionalAgentDate$1(options.issueDate, "issueDate")),
|
|
828
|
+
optionalEl("teljesitesDatum", optionalAgentDate$1(options.fulfillmentDate, "fulfillmentDate")),
|
|
1115
829
|
optionalEl("megjegyzes", optionalText(options.comment)),
|
|
1116
830
|
el("tipus", "SS"),
|
|
1117
831
|
optionalEl("szamlaSablon", validateTemplate(options.template))
|
|
@@ -1455,6 +1169,54 @@ async function queryTaxpayer(ctx, taxNumber, options = {}) {
|
|
|
1455
1169
|
}, parseQueryTaxpayerResponse);
|
|
1456
1170
|
}
|
|
1457
1171
|
//#endregion
|
|
1172
|
+
//#region src/taxpayer/cache.ts
|
|
1173
|
+
const TAXPAYER_CACHE_KEY_PREFIX = "szamlazz:taxpayer:";
|
|
1174
|
+
const DEFAULT_TAXPAYER_TTL_SECONDS = 86400;
|
|
1175
|
+
const DEFAULT_TAXPAYER_INVALID_TTL_SECONDS = 600;
|
|
1176
|
+
function positiveSeconds(value, fallback, field) {
|
|
1177
|
+
if (value === void 0) return fallback;
|
|
1178
|
+
if (!Number.isFinite(value) || value < 1) throw new SzamlazzError(`A(z) ${field} legalább 1 másodperc legyen, kapott: ${String(value)}`, { category: "configuration" });
|
|
1179
|
+
return Math.ceil(value);
|
|
1180
|
+
}
|
|
1181
|
+
function parseCached(value) {
|
|
1182
|
+
if (typeof value !== "string" || value === "") return void 0;
|
|
1183
|
+
try {
|
|
1184
|
+
const parsed = JSON.parse(value);
|
|
1185
|
+
if (typeof parsed !== "object" || parsed === null) return void 0;
|
|
1186
|
+
const info = parsed;
|
|
1187
|
+
return typeof info.valid === "boolean" && Array.isArray(info.addresses) ? info : void 0;
|
|
1188
|
+
} catch {
|
|
1189
|
+
return;
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
function cachedTaxpayerQuery(query, options, warn) {
|
|
1193
|
+
const ttl = positiveSeconds(options.ttlSeconds, DEFAULT_TAXPAYER_TTL_SECONDS, "ttlSeconds");
|
|
1194
|
+
const invalidTtl = positiveSeconds(options.invalidTtlSeconds, 600, "invalidTtlSeconds");
|
|
1195
|
+
const report = (operation, error) => warn?.({
|
|
1196
|
+
kind: "cache",
|
|
1197
|
+
message: `Az adószám-gyorsítótár "${operation}" művelete sikertelen, a kassza a Számlázz.hu-tól kérdez.`,
|
|
1198
|
+
error,
|
|
1199
|
+
action: "queryTaxpayer",
|
|
1200
|
+
operation
|
|
1201
|
+
});
|
|
1202
|
+
return async (taxNumber, requestOptions) => {
|
|
1203
|
+
const key = `${TAXPAYER_CACHE_KEY_PREFIX}${toTaxpayerId(taxNumber)}`;
|
|
1204
|
+
try {
|
|
1205
|
+
const cached = parseCached(await options.store.get(key));
|
|
1206
|
+
if (cached) return cached;
|
|
1207
|
+
} catch (error) {
|
|
1208
|
+
report("get", error);
|
|
1209
|
+
}
|
|
1210
|
+
const info = await query(taxNumber, requestOptions);
|
|
1211
|
+
try {
|
|
1212
|
+
await options.store.set(key, JSON.stringify(info), info.valid ? ttl : invalidTtl);
|
|
1213
|
+
} catch (error) {
|
|
1214
|
+
report("set", error);
|
|
1215
|
+
}
|
|
1216
|
+
return info;
|
|
1217
|
+
};
|
|
1218
|
+
}
|
|
1219
|
+
//#endregion
|
|
1458
1220
|
//#region src/client.ts
|
|
1459
1221
|
const CREDENTIAL_PROBE_INVOICE_NUMBER = "KASSZA-CREDENTIAL-PROBE-0";
|
|
1460
1222
|
async function nullIfNotFound(promise) {
|
|
@@ -1477,11 +1239,14 @@ function invoiceNumberOf(input) {
|
|
|
1477
1239
|
function receiptNumberOf(input) {
|
|
1478
1240
|
return typeof input === "string" ? input : input.receiptNumber;
|
|
1479
1241
|
}
|
|
1480
|
-
function
|
|
1242
|
+
function createDocumentEmitter(hook, options) {
|
|
1243
|
+
return { emit: (event) => emitDocumentEvent(hook, event, options) };
|
|
1244
|
+
}
|
|
1245
|
+
function createInvoicesApi(ctx, defaults, events, guard) {
|
|
1481
1246
|
const api = {
|
|
1482
1247
|
async create(input, options) {
|
|
1483
1248
|
const document = await createInvoice(ctx, defaults, input, options);
|
|
1484
|
-
await
|
|
1249
|
+
await events.emit({
|
|
1485
1250
|
kind: "invoice",
|
|
1486
1251
|
action: "created",
|
|
1487
1252
|
number: document.number,
|
|
@@ -1490,11 +1255,11 @@ function createInvoicesApi(ctx, defaults, onDocument) {
|
|
|
1490
1255
|
});
|
|
1491
1256
|
return document;
|
|
1492
1257
|
},
|
|
1493
|
-
createOnce: (input, options) => createInvoiceOnce(api, input, options),
|
|
1258
|
+
createOnce: (input, options) => createInvoiceOnce(api, input, options, guard),
|
|
1494
1259
|
preview: (input, options) => previewInvoice(ctx, defaults, input, options),
|
|
1495
1260
|
async reverse(input, options) {
|
|
1496
1261
|
const document = await reverseInvoice(ctx, input, options);
|
|
1497
|
-
await
|
|
1262
|
+
await events.emit({
|
|
1498
1263
|
kind: "invoice",
|
|
1499
1264
|
action: "reversed",
|
|
1500
1265
|
number: document.number,
|
|
@@ -1505,7 +1270,7 @@ function createInvoicesApi(ctx, defaults, onDocument) {
|
|
|
1505
1270
|
},
|
|
1506
1271
|
async registerPayment(input, options) {
|
|
1507
1272
|
const document = await registerPayment(ctx, input, options);
|
|
1508
|
-
await
|
|
1273
|
+
await events.emit({
|
|
1509
1274
|
kind: "invoice",
|
|
1510
1275
|
action: "payment",
|
|
1511
1276
|
number: document.invoiceNumber,
|
|
@@ -1513,9 +1278,10 @@ function createInvoicesApi(ctx, defaults, onDocument) {
|
|
|
1513
1278
|
});
|
|
1514
1279
|
return document;
|
|
1515
1280
|
},
|
|
1281
|
+
registerPaymentOnce: (input, options) => registerPaymentOnce(api, input, options, guard),
|
|
1516
1282
|
async clearPayments(input, options) {
|
|
1517
1283
|
const document = await clearPayments(ctx, input, options);
|
|
1518
|
-
await
|
|
1284
|
+
await events.emit({
|
|
1519
1285
|
kind: "invoice",
|
|
1520
1286
|
action: "payment",
|
|
1521
1287
|
number: document.invoiceNumber,
|
|
@@ -1530,11 +1296,20 @@ function createInvoicesApi(ctx, defaults, onDocument) {
|
|
|
1530
1296
|
};
|
|
1531
1297
|
return api;
|
|
1532
1298
|
}
|
|
1533
|
-
function
|
|
1299
|
+
function convertedJoin(result) {
|
|
1300
|
+
return {
|
|
1301
|
+
receipt: result.receipt,
|
|
1302
|
+
invoice: {
|
|
1303
|
+
...result.invoice,
|
|
1304
|
+
created: false
|
|
1305
|
+
}
|
|
1306
|
+
};
|
|
1307
|
+
}
|
|
1308
|
+
function createReceiptsApi(ctx, defaults, invoices, events, guard) {
|
|
1534
1309
|
const api = {
|
|
1535
1310
|
async create(input, options) {
|
|
1536
1311
|
const document = await createReceipt(ctx, defaults, input, options);
|
|
1537
|
-
await
|
|
1312
|
+
await events.emit({
|
|
1538
1313
|
kind: "receipt",
|
|
1539
1314
|
action: "created",
|
|
1540
1315
|
number: document.number,
|
|
@@ -1542,10 +1317,10 @@ function createReceiptsApi(ctx, defaults, invoices, onDocument) {
|
|
|
1542
1317
|
});
|
|
1543
1318
|
return document;
|
|
1544
1319
|
},
|
|
1545
|
-
createOnce: (input, options) => createReceiptOnce(api, input, options),
|
|
1320
|
+
createOnce: (input, options) => createReceiptOnce(api, input, options, guard),
|
|
1546
1321
|
async reverse(input, options) {
|
|
1547
1322
|
const document = await reverseReceipt(ctx, input, options);
|
|
1548
|
-
await
|
|
1323
|
+
await events.emit({
|
|
1549
1324
|
kind: "receipt",
|
|
1550
1325
|
action: "reversed",
|
|
1551
1326
|
number: document.number,
|
|
@@ -1557,22 +1332,38 @@ function createReceiptsApi(ctx, defaults, invoices, onDocument) {
|
|
|
1557
1332
|
get: (input, options) => getReceipt(ctx, input, options),
|
|
1558
1333
|
find: (input, options) => nullIfNotFound(getReceipt(ctx, input, options)),
|
|
1559
1334
|
send: (input, options) => sendReceipt(ctx, input, options),
|
|
1560
|
-
convertToInvoice: (input, options) =>
|
|
1335
|
+
convertToInvoice: (input, options = {}) => guardOnce(guard, `convert:${input.receiptNumber?.trim() ?? ""}`, {
|
|
1336
|
+
...options,
|
|
1337
|
+
lock: false
|
|
1338
|
+
}, () => convertReceiptToInvoice({
|
|
1561
1339
|
receipts: api,
|
|
1562
1340
|
invoices
|
|
1563
|
-
}, input, options)
|
|
1341
|
+
}, input, options), convertedJoin)
|
|
1564
1342
|
};
|
|
1565
1343
|
return api;
|
|
1566
1344
|
}
|
|
1345
|
+
function onceScopeOf(ctx) {
|
|
1346
|
+
return ctx.credentials.map((node) => `${node.name}=${String(node.content)}`).join("\n");
|
|
1347
|
+
}
|
|
1567
1348
|
function createKassza(options = {}) {
|
|
1568
1349
|
const ctx = createAgentContext(options);
|
|
1569
|
-
const
|
|
1570
|
-
|
|
1571
|
-
|
|
1350
|
+
const events = createDocumentEmitter(options.hooks?.onDocument, {
|
|
1351
|
+
mode: options.hooks?.onDocumentError,
|
|
1352
|
+
onWarning: options.hooks?.onWarning
|
|
1353
|
+
});
|
|
1354
|
+
const guard = {
|
|
1355
|
+
scope: onceScopeOf(ctx),
|
|
1356
|
+
lock: options.createOnceLock,
|
|
1357
|
+
warn: ctx.warn
|
|
1358
|
+
};
|
|
1359
|
+
const directQuery = (taxNumber, requestOptions) => queryTaxpayer(ctx, taxNumber, requestOptions);
|
|
1360
|
+
const taxpayerQuery = options.taxpayerCache ? cachedTaxpayerQuery(directQuery, options.taxpayerCache, ctx.warn) : directQuery;
|
|
1361
|
+
const invoices = createInvoicesApi(ctx, options.defaults?.invoice ?? {}, events, guard);
|
|
1362
|
+
const receipts = createReceiptsApi(ctx, options.defaults?.receipt ?? {}, invoices, events, guard);
|
|
1572
1363
|
return {
|
|
1573
1364
|
invoices,
|
|
1574
1365
|
receipts,
|
|
1575
|
-
taxpayer: { query:
|
|
1366
|
+
taxpayer: { query: taxpayerQuery },
|
|
1576
1367
|
async verifyCredentials(requestOptions) {
|
|
1577
1368
|
try {
|
|
1578
1369
|
await getInvoicePdf(ctx, CREDENTIAL_PROBE_INVOICE_NUMBER, requestOptions);
|
|
@@ -1593,4 +1384,4 @@ function createKassza(options = {}) {
|
|
|
1593
1384
|
};
|
|
1594
1385
|
}
|
|
1595
1386
|
//#endregion
|
|
1596
|
-
export {
|
|
1387
|
+
export { queryTaxpayer as a, createAgentContext as c, attemptLedgerKey as d, TAXPAYER_CACHE_KEY_PREFIX as i, ATTEMPT_LEDGER_KEY_PREFIX as l, DEFAULT_TAXPAYER_INVALID_TTL_SECONDS as n, getInvoicePdf as o, DEFAULT_TAXPAYER_TTL_SECONDS as r, buildCreateInvoiceXml as s, createKassza as t, ATTEMPT_LEDGER_TTL_SECONDS as u };
|