@voyant-travel/plugin-smartbill 0.119.2

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.
Files changed (96) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +324 -0
  3. package/dist/artifacts.d.ts +80 -0
  4. package/dist/artifacts.d.ts.map +1 -0
  5. package/dist/artifacts.js +295 -0
  6. package/dist/client/errors.d.ts +28 -0
  7. package/dist/client/errors.d.ts.map +1 -0
  8. package/dist/client/errors.js +32 -0
  9. package/dist/client/fetch.d.ts +4 -0
  10. package/dist/client/fetch.d.ts.map +1 -0
  11. package/dist/client/fetch.js +32 -0
  12. package/dist/client/rate-limit.d.ts +8 -0
  13. package/dist/client/rate-limit.d.ts.map +1 -0
  14. package/dist/client/rate-limit.js +54 -0
  15. package/dist/client/resilience.d.ts +36 -0
  16. package/dist/client/resilience.d.ts.map +1 -0
  17. package/dist/client/resilience.js +23 -0
  18. package/dist/client.d.ts +67 -0
  19. package/dist/client.d.ts.map +1 -0
  20. package/dist/client.js +234 -0
  21. package/dist/hono.d.ts +199 -0
  22. package/dist/hono.d.ts.map +1 -0
  23. package/dist/hono.js +77 -0
  24. package/dist/index.d.ts +22 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +10 -0
  27. package/dist/invoice-ui-data.d.ts +46 -0
  28. package/dist/invoice-ui-data.d.ts.map +1 -0
  29. package/dist/invoice-ui-data.js +62 -0
  30. package/dist/invoice-ui.d.ts +438 -0
  31. package/dist/invoice-ui.d.ts.map +1 -0
  32. package/dist/invoice-ui.js +97 -0
  33. package/dist/mapping.d.ts +50 -0
  34. package/dist/mapping.d.ts.map +1 -0
  35. package/dist/mapping.js +219 -0
  36. package/dist/mock/node.d.ts +4 -0
  37. package/dist/mock/node.d.ts.map +1 -0
  38. package/dist/mock/node.js +14 -0
  39. package/dist/mock/pdf.d.ts +7 -0
  40. package/dist/mock/pdf.d.ts.map +1 -0
  41. package/dist/mock/pdf.js +44 -0
  42. package/dist/mock/types.d.ts +94 -0
  43. package/dist/mock/types.d.ts.map +1 -0
  44. package/dist/mock/types.js +1 -0
  45. package/dist/mock.d.ts +4 -0
  46. package/dist/mock.d.ts.map +1 -0
  47. package/dist/mock.js +431 -0
  48. package/dist/plugin.d.ts +55 -0
  49. package/dist/plugin.d.ts.map +1 -0
  50. package/dist/plugin.js +192 -0
  51. package/dist/runtime.d.ts +25 -0
  52. package/dist/runtime.d.ts.map +1 -0
  53. package/dist/runtime.js +42 -0
  54. package/dist/settlement.d.ts +33 -0
  55. package/dist/settlement.d.ts.map +1 -0
  56. package/dist/settlement.js +65 -0
  57. package/dist/sync/events.d.ts +5 -0
  58. package/dist/sync/events.d.ts.map +1 -0
  59. package/dist/sync/events.js +96 -0
  60. package/dist/sync/helpers.d.ts +66 -0
  61. package/dist/sync/helpers.d.ts.map +1 -0
  62. package/dist/sync/helpers.js +353 -0
  63. package/dist/sync/invoice.d.ts +3 -0
  64. package/dist/sync/invoice.d.ts.map +1 -0
  65. package/dist/sync/invoice.js +25 -0
  66. package/dist/sync/types.d.ts +71 -0
  67. package/dist/sync/types.d.ts.map +1 -0
  68. package/dist/sync/types.js +1 -0
  69. package/dist/sync.d.ts +4 -0
  70. package/dist/sync.d.ts.map +1 -0
  71. package/dist/sync.js +2 -0
  72. package/dist/types.d.ts +189 -0
  73. package/dist/types.d.ts.map +1 -0
  74. package/dist/types.js +1 -0
  75. package/dist/validation.d.ts +39 -0
  76. package/dist/validation.d.ts.map +1 -0
  77. package/dist/validation.js +120 -0
  78. package/dist/workflow-candidates.d.ts +36 -0
  79. package/dist/workflow-candidates.d.ts.map +1 -0
  80. package/dist/workflow-candidates.js +182 -0
  81. package/dist/workflow-remote-discovery.d.ts +6 -0
  82. package/dist/workflow-remote-discovery.d.ts.map +1 -0
  83. package/dist/workflow-remote-discovery.js +83 -0
  84. package/dist/workflows/refs.d.ts +13 -0
  85. package/dist/workflows/refs.d.ts.map +1 -0
  86. package/dist/workflows/refs.js +51 -0
  87. package/dist/workflows/spaced-client.d.ts +5 -0
  88. package/dist/workflows/spaced-client.d.ts.map +1 -0
  89. package/dist/workflows/spaced-client.js +44 -0
  90. package/dist/workflows/types.d.ts +142 -0
  91. package/dist/workflows/types.d.ts.map +1 -0
  92. package/dist/workflows/types.js +1 -0
  93. package/dist/workflows.d.ts +5 -0
  94. package/dist/workflows.d.ts.map +1 -0
  95. package/dist/workflows.js +229 -0
  96. package/package.json +129 -0
@@ -0,0 +1,353 @@
1
+ import { financeService } from "@voyant-travel/finance";
2
+ import { isSmartbillPdfPersistMetadataUpdateError, persistSmartbillInvoiceArtifact, recordSmartbillInvoiceArtifactFailure, retrySmartbillInvoiceArtifact, } from "../artifacts.js";
3
+ export async function findProformaSmartbillRef(db, proformaId) {
4
+ const refs = await financeService.listInvoiceExternalRefs(db, proformaId);
5
+ const ref = refs.find((candidate) => isMatchingSmartbillRef(candidate, "proforma"));
6
+ if (!ref)
7
+ return null;
8
+ const metadata = coerceMetadata(ref.metadata);
9
+ const seriesName = metadataString(metadata, "series") ??
10
+ metadataString(metadata, "seriesName") ??
11
+ metadataString(metadata, "estimateSeriesName");
12
+ const number = metadataString(metadata, "number") ?? ref.externalNumber ?? ref.externalId ?? null;
13
+ return seriesName && number ? { ref, seriesName, number } : null;
14
+ }
15
+ export async function findExistingSmartbillRef(event, documentType, body, runtime) {
16
+ if (runtime.idempotency.skipExistingExternalRef === false)
17
+ return null;
18
+ const db = await resolveArtifactDb(event, documentType, body, undefined, runtime);
19
+ if (!db)
20
+ return null;
21
+ const refs = await financeService.listInvoiceExternalRefs(db, event.id);
22
+ return refs.find((ref) => isMatchingSmartbillRef(ref, documentType)) ?? null;
23
+ }
24
+ export async function findSmartbillRefForCancellation(db, invoiceId) {
25
+ const refs = await financeService.listInvoiceExternalRefs(db, invoiceId);
26
+ return (refs.find((ref) => {
27
+ if (ref.provider !== "smartbill")
28
+ return false;
29
+ const metadataDocumentType = metadataString(coerceMetadata(ref.metadata), "documentType");
30
+ return !metadataDocumentType || metadataDocumentType === "invoice";
31
+ }) ??
32
+ refs.find((ref) => ref.provider === "smartbill") ??
33
+ null);
34
+ }
35
+ export async function resolveSmartbillCancellationTarget(event, externalRef, pluginOptions) {
36
+ const metadata = coerceMetadata(externalRef?.metadata);
37
+ const number = eventString(event, "externalNumber") ??
38
+ externalRef?.externalNumber ??
39
+ externalRef?.externalId ??
40
+ metadataString(metadata, "number") ??
41
+ event.invoiceNumber;
42
+ if (!number)
43
+ return null;
44
+ const seriesName = eventString(event, "externalSeriesName") ??
45
+ metadataString(metadata, "seriesName") ??
46
+ metadataString(metadata, "series") ??
47
+ (await resolveSeriesName(pluginOptions.seriesName, event));
48
+ return { seriesName, number };
49
+ }
50
+ export async function recordSmartbillCancellation(event, target, result, externalRef, runtime, pluginOptions) {
51
+ const db = await resolveArtifactDb(event, "invoice", undefined, undefined, runtime, pluginOptions);
52
+ if (!db)
53
+ return;
54
+ const metadata = coerceMetadata(externalRef?.metadata);
55
+ await financeService.registerInvoiceExternalRef(db, event.id, {
56
+ provider: "smartbill",
57
+ externalId: externalRef?.externalId ?? target.number,
58
+ externalNumber: externalRef?.externalNumber ?? target.number,
59
+ externalUrl: externalRef?.externalUrl ?? null,
60
+ status: "cancelled",
61
+ syncedAt: new Date().toISOString(),
62
+ syncError: null,
63
+ metadata: {
64
+ ...(metadata ?? {}),
65
+ companyVatCode: pluginOptions.companyVatCode,
66
+ seriesName: target.seriesName,
67
+ series: target.seriesName,
68
+ number: target.number,
69
+ documentType: "invoice",
70
+ cancelledAt: new Date().toISOString(),
71
+ cancelStatus: result.status ?? null,
72
+ cancelMessage: result.message ?? null,
73
+ },
74
+ });
75
+ }
76
+ export async function handleExistingSmartbillRef(event, documentType, body, externalRef, runtime) {
77
+ runtime.logger.info?.(`[smartbill] ${documentType} already has SmartBill ref for ${event.id}; skipping create`, externalRef);
78
+ await applyExternalAllocationFromRefIfRequired(event, documentType, body, externalRef, runtime);
79
+ await writeBackInvoiceNumberFromRefIfRequired(event, documentType, body, externalRef, runtime);
80
+ let artifact = null;
81
+ try {
82
+ artifact = await retrySmartbillInvoiceArtifact({
83
+ runtime: runtime.artifacts,
84
+ client: runtime.client,
85
+ externalRef,
86
+ documentType,
87
+ });
88
+ if (artifact.status === "persisted") {
89
+ runtime.logger.info?.(`[smartbill] ${documentType} PDF re-attached for ${event.id}`, artifact);
90
+ }
91
+ }
92
+ catch (err) {
93
+ const message = isSmartbillPdfPersistMetadataUpdateError(err)
94
+ ? `[smartbill] artifact re-attach metadata update failed for ${event.id}`
95
+ : `[smartbill] artifact re-attach failed for ${event.id}`;
96
+ runtime.logger.error(message, err);
97
+ }
98
+ return { status: "existing_ref", invoiceId: event.id, documentType, externalRef, artifact };
99
+ }
100
+ export async function persistArtifact(event, documentType, body, result, runtime) {
101
+ try {
102
+ const persisted = await persistSmartbillInvoiceArtifact({
103
+ runtime: runtime.artifacts,
104
+ client: runtime.client,
105
+ event,
106
+ documentType,
107
+ body,
108
+ result,
109
+ });
110
+ if (persisted.status === "persisted") {
111
+ runtime.logger.info?.(`[smartbill] ${documentType} PDF persisted for ${event.id}`, persisted);
112
+ }
113
+ return persisted;
114
+ }
115
+ catch (err) {
116
+ if (isSmartbillPdfPersistMetadataUpdateError(err)) {
117
+ runtime.logger.error(`[smartbill] artifact persistence metadata update failed for ${event.id}`, err);
118
+ return null;
119
+ }
120
+ runtime.logger.error(`[smartbill] artifact persistence failed for ${event.id}`, err);
121
+ try {
122
+ await recordSmartbillInvoiceArtifactFailure({
123
+ runtime: runtime.artifacts,
124
+ event,
125
+ documentType,
126
+ body,
127
+ result,
128
+ error: err,
129
+ });
130
+ }
131
+ catch (recordError) {
132
+ runtime.logger.error(`[smartbill] artifact failure external-ref update failed for ${event.id}`, recordError);
133
+ }
134
+ return null;
135
+ }
136
+ }
137
+ export async function applyExternalAllocationIfRequired(event, documentType, body, result, runtime) {
138
+ if (event.externalAllocationRequired !== true || !result.number)
139
+ return;
140
+ await applyExternalAllocationNumber(event, documentType, body, result, runtime, formatExternalInvoiceNumber(result.series ?? body.seriesName, result.number));
141
+ }
142
+ async function applyExternalAllocationNumber(event, documentType, body, result, runtime, invoiceNumber) {
143
+ const db = await resolveArtifactDb(event, documentType, body, result, runtime);
144
+ if (!db) {
145
+ throw new Error("SmartBill external allocation requires artifact database access");
146
+ }
147
+ const allocation = await financeService.applyExternalInvoiceAllocation(db, event.id, {
148
+ invoiceNumber,
149
+ });
150
+ if (allocation.status === "applied") {
151
+ runtime.logger.info?.(`[smartbill] external number applied for ${event.id}`, allocation.invoice);
152
+ }
153
+ }
154
+ async function applyExternalAllocationFromRefIfRequired(event, documentType, body, externalRef, runtime) {
155
+ if (event.externalAllocationRequired !== true)
156
+ return;
157
+ const metadata = coerceMetadata(externalRef.metadata);
158
+ const number = metadataString(metadata, "number") ??
159
+ externalRef.externalNumber ??
160
+ externalRef.externalId ??
161
+ null;
162
+ if (!number) {
163
+ throw new Error("SmartBill external allocation requires an existing external number");
164
+ }
165
+ const refSeries = metadataString(metadata, "series") ?? metadataString(metadata, "seriesName");
166
+ const refResult = {
167
+ number,
168
+ series: refSeries ?? undefined,
169
+ url: externalRef.externalUrl ?? undefined,
170
+ };
171
+ await applyExternalAllocationNumber(event, documentType, body, refResult, runtime, formatExternalInvoiceNumber(refSeries ?? undefined, number));
172
+ }
173
+ async function resolveWriteBackInvoiceNumber(event, body, result, writeBackInvoiceNumber, options = {}) {
174
+ if (!writeBackInvoiceNumber)
175
+ return null;
176
+ if (typeof writeBackInvoiceNumber === "function") {
177
+ const invoiceNumber = await writeBackInvoiceNumber(event, result);
178
+ if (typeof invoiceNumber !== "string" || invoiceNumber.trim().length === 0) {
179
+ throw new Error("SmartBill invoice number write-back formatter returned an empty value");
180
+ }
181
+ return invoiceNumber;
182
+ }
183
+ if (!result.number)
184
+ return null;
185
+ const series = result.series ?? (options.useBodySeriesFallback === false ? undefined : body.seriesName);
186
+ return formatExternalInvoiceNumber(series, result.number);
187
+ }
188
+ export async function writeBackInvoiceNumberIfRequired(event, documentType, body, result, runtime) {
189
+ const invoiceNumber = await resolveWriteBackInvoiceNumber(event, body, result, runtime.writeBackInvoiceNumber);
190
+ if (!invoiceNumber)
191
+ return;
192
+ await writeBackResolvedInvoiceNumber(event, documentType, body, result, runtime, invoiceNumber);
193
+ }
194
+ async function writeBackResolvedInvoiceNumber(event, documentType, body, result, runtime, invoiceNumber) {
195
+ const db = await resolveArtifactDb(event, documentType, body, result, runtime);
196
+ if (!db) {
197
+ throw new Error("SmartBill invoice number write-back requires artifact database access");
198
+ }
199
+ const invoice = await financeService.updateInvoice(db, event.id, { invoiceNumber });
200
+ if (!invoice) {
201
+ throw new Error(`SmartBill invoice number write-back failed for missing invoice ${event.id}`);
202
+ }
203
+ runtime.logger.info?.(`[smartbill] invoice number write-back applied for ${event.id}`, invoice);
204
+ }
205
+ async function writeBackInvoiceNumberFromRefIfRequired(event, documentType, body, externalRef, runtime) {
206
+ if (!runtime.writeBackInvoiceNumber)
207
+ return;
208
+ const metadata = coerceMetadata(externalRef.metadata);
209
+ const number = metadataString(metadata, "number") ??
210
+ externalRef.externalNumber ??
211
+ externalRef.externalId ??
212
+ null;
213
+ if (!number)
214
+ return;
215
+ const refSeries = metadataString(metadata, "series") ?? metadataString(metadata, "seriesName");
216
+ const refResult = {
217
+ number,
218
+ series: refSeries ?? undefined,
219
+ url: externalRef.externalUrl ?? undefined,
220
+ };
221
+ const invoiceNumber = await resolveWriteBackInvoiceNumber(event, body, refResult, runtime.writeBackInvoiceNumber, { useBodySeriesFallback: false });
222
+ if (!invoiceNumber)
223
+ return;
224
+ await writeBackResolvedInvoiceNumber(event, documentType, body, refResult, runtime, invoiceNumber);
225
+ }
226
+ export async function recordSyncError(event, documentType, err, runtime, pluginOptions) {
227
+ try {
228
+ await runtime.onError?.(event, err);
229
+ }
230
+ catch (handlerError) {
231
+ runtime.logger.error(`[smartbill] onError handler failed for ${event.id}`, handlerError);
232
+ }
233
+ try {
234
+ const db = await resolveArtifactDb(event, documentType, undefined, undefined, runtime, pluginOptions);
235
+ if (!db)
236
+ return;
237
+ const refs = await financeService.listInvoiceExternalRefs(db, event.id);
238
+ const matchingRef = refs.find((ref) => isMatchingSmartbillRef(ref, documentType));
239
+ if (matchingRef) {
240
+ await financeService.registerInvoiceExternalRef(db, event.id, {
241
+ provider: "smartbill",
242
+ externalId: matchingRef.externalId ?? null,
243
+ externalNumber: matchingRef.externalNumber ?? null,
244
+ externalUrl: matchingRef.externalUrl ?? null,
245
+ status: matchingRef.status ?? "error",
246
+ syncedAt: new Date().toISOString(),
247
+ syncError: errorMessage(err),
248
+ metadata: {
249
+ ...(coerceMetadata(matchingRef.metadata) ?? {}),
250
+ documentType,
251
+ },
252
+ });
253
+ return;
254
+ }
255
+ await financeService.registerInvoiceExternalRef(db, event.id, {
256
+ provider: "smartbill",
257
+ externalId: null,
258
+ externalNumber: null,
259
+ externalUrl: null,
260
+ status: "error",
261
+ syncedAt: new Date().toISOString(),
262
+ syncError: errorMessage(err),
263
+ metadata: { documentType },
264
+ });
265
+ }
266
+ catch (recordError) {
267
+ runtime.logger.error(`[smartbill] error external-ref recording failed for ${event.id}`, recordError);
268
+ }
269
+ }
270
+ export async function resolveArtifactDb(event, documentType, body, result, runtime, pluginOptions) {
271
+ if (!runtime.artifacts.db)
272
+ return null;
273
+ const context = {
274
+ event,
275
+ documentType,
276
+ body: body ?? {
277
+ companyVatCode: pluginOptions?.companyVatCode ?? "",
278
+ client: { name: "Client" },
279
+ seriesName: await resolveSeriesName(pluginOptions?.seriesName, event),
280
+ currency: "RON",
281
+ products: [],
282
+ },
283
+ result: result ?? {},
284
+ };
285
+ return (await resolveMaybe(runtime.artifacts.db, context)) ?? null;
286
+ }
287
+ export function withDefaultArtifactDb(pluginOptions, db) {
288
+ if (pluginOptions.artifacts?.db || pluginOptions.db)
289
+ return pluginOptions;
290
+ return {
291
+ ...pluginOptions,
292
+ artifacts: {
293
+ ...pluginOptions.artifacts,
294
+ db,
295
+ },
296
+ };
297
+ }
298
+ export function documentTypeForInvoice(invoice) {
299
+ if (invoice.invoiceType === "proforma")
300
+ return "proforma";
301
+ if (invoice.invoiceType === "invoice")
302
+ return "invoice";
303
+ return null;
304
+ }
305
+ async function resolveSeriesName(seriesName, event) {
306
+ if (typeof seriesName === "function")
307
+ return seriesName(event);
308
+ return seriesName ?? "unknown";
309
+ }
310
+ async function resolveMaybe(value, context) {
311
+ return typeof value === "function"
312
+ ? await value(context)
313
+ : value;
314
+ }
315
+ function errorMessage(error) {
316
+ if (error instanceof Error) {
317
+ const maybeCode = error.code;
318
+ const code = typeof maybeCode === "string" ? maybeCode : null;
319
+ return code ? `${code}: ${error.message}` : error.message;
320
+ }
321
+ return String(error);
322
+ }
323
+ function coerceMetadata(value) {
324
+ return value && typeof value === "object" && !Array.isArray(value)
325
+ ? value
326
+ : null;
327
+ }
328
+ function metadataString(metadata, key) {
329
+ const value = metadata?.[key];
330
+ return typeof value === "string" && value.length > 0 ? value : null;
331
+ }
332
+ function eventString(event, key) {
333
+ const value = event[key];
334
+ return typeof value === "string" && value.length > 0 ? value : null;
335
+ }
336
+ function formatExternalInvoiceNumber(seriesName, number) {
337
+ const trimmedNumber = number.trim();
338
+ const trimmedSeries = seriesName?.trim();
339
+ if (!trimmedSeries || trimmedNumber.startsWith(`${trimmedSeries}-`))
340
+ return trimmedNumber;
341
+ return `${trimmedSeries}-${trimmedNumber}`;
342
+ }
343
+ function isUsableSmartbillRef(ref) {
344
+ return (ref.provider === "smartbill" &&
345
+ ref.status !== "error" &&
346
+ Boolean(ref.externalNumber || ref.externalId));
347
+ }
348
+ export function isMatchingSmartbillRef(ref, documentType) {
349
+ if (!isUsableSmartbillRef(ref))
350
+ return false;
351
+ const metadataDocumentType = metadataString(coerceMetadata(ref.metadata), "documentType");
352
+ return !metadataDocumentType || metadataDocumentType === documentType;
353
+ }
@@ -0,0 +1,3 @@
1
+ import type { SyncSmartbillInvoiceInput, SyncSmartbillInvoiceResult } from "./types.js";
2
+ export declare function syncSmartbillInvoice({ db, invoiceId, pluginOptions, client, issueRuntime, }: SyncSmartbillInvoiceInput): Promise<SyncSmartbillInvoiceResult>;
3
+ //# sourceMappingURL=invoice.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invoice.d.ts","sourceRoot":"","sources":["../../src/sync/invoice.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,yBAAyB,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAA;AAEvF,wBAAsB,oBAAoB,CAAC,EACzC,EAAE,EACF,SAAS,EACT,aAAa,EACb,MAAM,EACN,YAAY,GACb,EAAE,yBAAyB,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAqBjE"}
@@ -0,0 +1,25 @@
1
+ import { buildInvoiceIssuedEvent, financeService } from "@voyant-travel/finance";
2
+ import { createSmartbillSyncRuntime } from "../runtime.js";
3
+ import { parseSmartbillPluginOptions } from "../validation.js";
4
+ import { syncSmartbillInvoiceEvent } from "./events.js";
5
+ import { documentTypeForInvoice, withDefaultArtifactDb } from "./helpers.js";
6
+ export async function syncSmartbillInvoice({ db, invoiceId, pluginOptions, client, issueRuntime, }) {
7
+ const invoice = await financeService.getInvoiceById(db, invoiceId);
8
+ if (!invoice)
9
+ return { status: "not_found", invoiceId };
10
+ const documentType = documentTypeForInvoice(invoice);
11
+ if (!documentType) {
12
+ return { status: "unsupported_document_type", invoiceId, invoiceType: invoice.invoiceType };
13
+ }
14
+ const validatedOptions = parseSmartbillPluginOptions(withDefaultArtifactDb(pluginOptions, db));
15
+ const runtime = createSmartbillSyncRuntime(validatedOptions, client ? { client } : undefined);
16
+ const issuedEvent = await buildInvoiceIssuedEvent(db, invoice, issueRuntime);
17
+ const event = { ...issuedEvent, id: issuedEvent.invoiceId };
18
+ return syncSmartbillInvoiceEvent({
19
+ event,
20
+ documentType,
21
+ runtime,
22
+ pluginOptions: validatedOptions,
23
+ operationLabel: documentType === "proforma" ? "createProforma" : "createInvoice",
24
+ });
25
+ }
@@ -0,0 +1,71 @@
1
+ import type { InvoiceIssueRuntime } from "@voyant-travel/finance";
2
+ import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
3
+ import type { persistSmartbillInvoiceArtifact, retrySmartbillInvoiceArtifact, SmartbillDocumentType, SmartbillExternalRef } from "../artifacts.js";
4
+ import type { SmartbillClientApi } from "../client.js";
5
+ import type { SmartbillPluginOptions } from "../plugin.js";
6
+ import type { SmartbillSyncRuntime } from "../runtime.js";
7
+ import type { SmartbillInvoiceResponse, VoyantInvoiceEvent } from "../types.js";
8
+ export interface SyncSmartbillInvoiceInput {
9
+ db: PostgresJsDatabase;
10
+ invoiceId: string;
11
+ pluginOptions: SmartbillPluginOptions;
12
+ client?: SmartbillClientApi;
13
+ issueRuntime?: Omit<InvoiceIssueRuntime, "eventBus">;
14
+ }
15
+ export interface SyncSmartbillInvoiceEventInput {
16
+ event: VoyantInvoiceEvent;
17
+ documentType: SmartbillDocumentType;
18
+ runtime: SmartbillSyncRuntime;
19
+ pluginOptions: Pick<SmartbillPluginOptions, "companyVatCode" | "seriesName">;
20
+ operationLabel?: string;
21
+ }
22
+ export interface SyncSmartbillProformaConversionInput {
23
+ event: VoyantInvoiceEvent & {
24
+ proformaId?: unknown;
25
+ proformaInvoiceNumber?: unknown;
26
+ };
27
+ runtime: SmartbillSyncRuntime;
28
+ pluginOptions: Pick<SmartbillPluginOptions, "companyVatCode" | "seriesName">;
29
+ }
30
+ export interface SyncSmartbillInvoiceVoidEventInput {
31
+ event: VoyantInvoiceEvent;
32
+ runtime: SmartbillSyncRuntime;
33
+ pluginOptions: Pick<SmartbillPluginOptions, "companyVatCode" | "seriesName">;
34
+ }
35
+ export type SyncSmartbillInvoiceResult = {
36
+ status: "not_found";
37
+ invoiceId: string;
38
+ } | {
39
+ status: "unsupported_document_type";
40
+ invoiceId: string;
41
+ invoiceType: string;
42
+ } | SyncSmartbillInvoiceEventResult;
43
+ export type SyncSmartbillInvoiceEventResult = {
44
+ status: "existing_ref";
45
+ invoiceId: string;
46
+ documentType: SmartbillDocumentType;
47
+ externalRef: SmartbillExternalRef;
48
+ artifact: Awaited<ReturnType<typeof retrySmartbillInvoiceArtifact>> | null;
49
+ } | {
50
+ status: "created";
51
+ invoiceId: string;
52
+ documentType: SmartbillDocumentType;
53
+ result: SmartbillInvoiceResponse;
54
+ artifact: Awaited<ReturnType<typeof persistSmartbillInvoiceArtifact>> | null;
55
+ };
56
+ export type SyncSmartbillProformaConversionResult = SyncSmartbillInvoiceEventResult;
57
+ export type SyncSmartbillInvoiceVoidEventResult = {
58
+ status: "cancelled";
59
+ invoiceId: string;
60
+ seriesName: string;
61
+ number: string;
62
+ externalRef: SmartbillExternalRef | null;
63
+ } | {
64
+ status: "already_cancelled";
65
+ invoiceId: string;
66
+ externalRef: SmartbillExternalRef;
67
+ } | {
68
+ status: "missing_number";
69
+ invoiceId: string;
70
+ };
71
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sync/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
package/dist/sync.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ export { syncSmartbillInvoiceEvent, syncSmartbillInvoiceVoidEvent, syncSmartbillProformaConversion, } from "./sync/events.js";
2
+ export { syncSmartbillInvoice } from "./sync/invoice.js";
3
+ export type { SyncSmartbillInvoiceEventInput, SyncSmartbillInvoiceEventResult, SyncSmartbillInvoiceInput, SyncSmartbillInvoiceResult, SyncSmartbillInvoiceVoidEventInput, SyncSmartbillInvoiceVoidEventResult, SyncSmartbillProformaConversionInput, SyncSmartbillProformaConversionResult, } from "./sync/types.js";
4
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,EACzB,6BAA6B,EAC7B,+BAA+B,GAChC,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AACxD,YAAY,EACV,8BAA8B,EAC9B,+BAA+B,EAC/B,yBAAyB,EACzB,0BAA0B,EAC1B,kCAAkC,EAClC,mCAAmC,EACnC,oCAAoC,EACpC,qCAAqC,GACtC,MAAM,iBAAiB,CAAA"}
package/dist/sync.js ADDED
@@ -0,0 +1,2 @@
1
+ export { syncSmartbillInvoiceEvent, syncSmartbillInvoiceVoidEvent, syncSmartbillProformaConversion, } from "./sync/events.js";
2
+ export { syncSmartbillInvoice } from "./sync/invoice.js";
@@ -0,0 +1,189 @@
1
+ /**
2
+ * Minimal shape for Voyant invoice events. The plugin accepts anything with
3
+ * at least these fields; everything else is passed through to the mapper.
4
+ */
5
+ export interface VoyantInvoiceEvent {
6
+ id: string;
7
+ invoiceNumber?: string;
8
+ externalAllocationRequired?: boolean;
9
+ /**
10
+ * When `true`, the SmartBill plugin ignores this event instead of
11
+ * pushing the document upstream. Set by the issuer when the operator
12
+ * opted out of external sync for this specific invoice.
13
+ */
14
+ skipExternalSync?: boolean;
15
+ [key: string]: unknown;
16
+ }
17
+ /**
18
+ * SmartBill invoice line item (product).
19
+ * @see https://api.smartbill.ro/#!/Factura/createInvoice
20
+ */
21
+ export interface SmartbillProduct {
22
+ name: string;
23
+ code?: string;
24
+ /** SmartBill's invoice/estimate API field for the product unit name. */
25
+ measuringUnitName?: string;
26
+ /** @deprecated SmartBill ignores this field; use `measuringUnitName`. */
27
+ measureUnit?: string;
28
+ quantity: number;
29
+ price: number;
30
+ currency: string;
31
+ isTaxIncluded: boolean;
32
+ isDiscount?: boolean;
33
+ taxName?: string;
34
+ taxPercentage?: number;
35
+ isService?: boolean;
36
+ saveToDb?: boolean;
37
+ warehouseName?: string;
38
+ }
39
+ /**
40
+ * SmartBill invoice client.
41
+ */
42
+ export interface SmartbillClient {
43
+ name: string;
44
+ vatCode?: string;
45
+ regCom?: string;
46
+ address?: string;
47
+ city?: string;
48
+ county?: string;
49
+ country?: string;
50
+ isTaxPayer?: boolean;
51
+ email?: string;
52
+ phone?: string;
53
+ contact?: string;
54
+ saveToDb?: boolean;
55
+ }
56
+ /**
57
+ * SmartBill invoice body as accepted by the `POST /invoice` endpoint.
58
+ */
59
+ export interface SmartbillInvoiceBody {
60
+ companyVatCode: string;
61
+ client: SmartbillClient;
62
+ seriesName: string;
63
+ number?: string;
64
+ isDraft?: boolean;
65
+ currency: string;
66
+ language?: string;
67
+ dueDate?: string;
68
+ issueDate?: string;
69
+ deliveryDate?: string;
70
+ precision?: number;
71
+ useEstimateDetails?: boolean;
72
+ exchangeRate?: number;
73
+ mentions?: string;
74
+ observations?: string;
75
+ estimate?: {
76
+ seriesName: string;
77
+ number: string;
78
+ };
79
+ useStock?: boolean;
80
+ products: SmartbillProduct[];
81
+ usePaymentTax?: boolean;
82
+ payment?: {
83
+ type: string;
84
+ value: number;
85
+ isCash: boolean;
86
+ };
87
+ }
88
+ /**
89
+ * Live-API response envelope shared by most SmartBill endpoints.
90
+ *
91
+ * The live API returns `status: "Ok"` on success and `status: "Error"` (or
92
+ * an HTTP non-2xx) on failure. `errorText` carries the machine-readable
93
+ * cause; `message` is a human-readable note.
94
+ */
95
+ export interface SmartbillEnvelope {
96
+ /** "Ok" on success, "Error" on failure. */
97
+ status?: string;
98
+ message?: string;
99
+ errorText?: string;
100
+ }
101
+ /**
102
+ * SmartBill API response for invoice / estimate creation.
103
+ */
104
+ export interface SmartbillInvoiceResponse extends SmartbillEnvelope {
105
+ number?: string;
106
+ series?: string;
107
+ url?: string;
108
+ }
109
+ /**
110
+ * SmartBill API response for the PDF endpoints. Live SmartBill responds
111
+ * with raw PDF bytes and `Content-Type: application/pdf`.
112
+ */
113
+ export interface SmartbillPdfResponse {
114
+ /** Raw PDF bytes returned by SmartBill. */
115
+ bytes: Uint8Array;
116
+ /** Content-Type header from the response. */
117
+ contentType: string;
118
+ }
119
+ /**
120
+ * SmartBill API response for `GET /invoice/paymentstatus`.
121
+ *
122
+ * Live shape: the envelope's `status` is `"Ok"` / `"Error"`, while payment
123
+ * state is carried by `paid: boolean` plus the amount fields. `payments`
124
+ * is the per-receipt list. The mock and the live API both populate these.
125
+ */
126
+ export interface SmartbillStatusResponse extends SmartbillEnvelope {
127
+ /** True when the invoice has been fully paid. */
128
+ paid?: boolean;
129
+ invoiceTotalAmount?: number;
130
+ paidAmount?: number;
131
+ unpaidAmount?: number;
132
+ payments?: SmartbillPaymentEntry[];
133
+ }
134
+ export interface SmartbillPaymentEntry {
135
+ type?: string;
136
+ value?: number;
137
+ paidDate?: string;
138
+ [key: string]: unknown;
139
+ }
140
+ /**
141
+ * Response shape for `GET /tax`.
142
+ */
143
+ export interface SmartbillTaxesResponse extends SmartbillEnvelope {
144
+ taxes?: Array<{
145
+ name: string;
146
+ percentage: number;
147
+ }>;
148
+ }
149
+ /**
150
+ * Response shape for `GET /series`. `type` is `"f"` (factură / invoice) or
151
+ * `"p"` (proformă).
152
+ */
153
+ export interface SmartbillSeriesResponse extends SmartbillEnvelope {
154
+ list?: Array<{
155
+ name: string;
156
+ nextNumber: number;
157
+ type: "f" | "p";
158
+ }>;
159
+ }
160
+ /**
161
+ * Response shape for `GET /estimate/invoices` (proforma → invoice
162
+ * conversion lookup).
163
+ */
164
+ export interface SmartbillEstimateInvoicesResponse extends SmartbillEnvelope {
165
+ series?: string;
166
+ number?: string;
167
+ areInvoicesCreated?: boolean;
168
+ invoices?: SmartbillInvoiceResponse[];
169
+ }
170
+ /**
171
+ * Minimal `fetch` shape the SmartBill client depends on. Mirrors the
172
+ * subset of the global `fetch` Response that the client uses, so the
173
+ * global `fetch` and the mock server both fit.
174
+ */
175
+ export type SmartbillFetch = (input: string, init: {
176
+ method: string;
177
+ headers: Record<string, string>;
178
+ body?: string;
179
+ }) => Promise<{
180
+ ok: boolean;
181
+ status: number;
182
+ json: () => Promise<unknown>;
183
+ text: () => Promise<string>;
184
+ arrayBuffer: () => Promise<ArrayBuffer>;
185
+ headers?: {
186
+ get(name: string): string | null;
187
+ };
188
+ }>;
189
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}