@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,62 @@
1
+ import { z } from "zod";
2
+ export const smartbillInvoiceExternalRefSchema = z.object({
3
+ id: z.string(),
4
+ invoiceId: z.string(),
5
+ provider: z.string(),
6
+ externalId: z.string().nullable(),
7
+ externalNumber: z.string().nullable(),
8
+ externalUrl: z.string().nullable(),
9
+ status: z.string().nullable(),
10
+ metadata: z.record(z.string(), z.unknown()).nullable(),
11
+ syncedAt: z.union([z.string(), z.date()]).nullable(),
12
+ syncError: z.string().nullable(),
13
+ createdAt: z.union([z.string(), z.date()]).nullable(),
14
+ updatedAt: z.union([z.string(), z.date()]).nullable(),
15
+ });
16
+ export const smartbillInvoiceExternalRefsResponseSchema = z.object({
17
+ data: z.array(smartbillInvoiceExternalRefSchema),
18
+ });
19
+ export function selectSmartbillInvoiceRef(refs) {
20
+ return refs.find((ref) => ref.provider === "smartbill") ?? null;
21
+ }
22
+ export function resolveSmartbillInvoiceReferenceParts(ref) {
23
+ const metadata = coerceMetadata(ref?.metadata);
24
+ return {
25
+ companyVatCode: readMetadataString(metadata, "companyVatCode", "vatCode"),
26
+ seriesName: readMetadataString(metadata, "seriesName", "series"),
27
+ number: readMetadataString(metadata, "number", "invoiceNumber") ??
28
+ ref?.externalNumber ??
29
+ ref?.externalId ??
30
+ null,
31
+ documentType: readMetadataString(metadata, "documentType"),
32
+ };
33
+ }
34
+ export function getSmartbillInvoiceDocumentLinks(ref) {
35
+ const metadata = coerceMetadata(ref?.metadata);
36
+ const candidates = [
37
+ { label: "SmartBill document", href: ref?.externalUrl },
38
+ { label: "SmartBill PDF", href: readMetadataString(metadata, "pdfUrl", "downloadUrl") },
39
+ { label: "SmartBill invoice", href: readMetadataString(metadata, "invoiceUrl", "documentUrl") },
40
+ ];
41
+ const seen = new Set();
42
+ return candidates.flatMap((candidate) => {
43
+ const href = candidate.href?.trim();
44
+ if (!href || seen.has(href))
45
+ return [];
46
+ seen.add(href);
47
+ return [{ label: candidate.label, href }];
48
+ });
49
+ }
50
+ function coerceMetadata(value) {
51
+ return value && typeof value === "object" && !Array.isArray(value)
52
+ ? value
53
+ : null;
54
+ }
55
+ function readMetadataString(metadata, ...keys) {
56
+ for (const key of keys) {
57
+ const value = metadata?.[key];
58
+ if (typeof value === "string" && value.trim())
59
+ return value.trim();
60
+ }
61
+ return null;
62
+ }
@@ -0,0 +1,438 @@
1
+ import type { ReactNode } from "react";
2
+ import { type SmartbillInvoiceExternalRef } from "./invoice-ui-data.js";
3
+ export { getSmartbillInvoiceDocumentLinks, resolveSmartbillInvoiceReferenceParts, type SmartbillInvoiceDocumentLink, type SmartbillInvoiceExternalRef, type SmartbillInvoiceReferenceParts, selectSmartbillInvoiceRef, } from "./invoice-ui-data.js";
4
+ export interface UseSmartbillInvoiceRefsOptions {
5
+ enabled?: boolean;
6
+ }
7
+ export interface SmartbillInvoiceAction {
8
+ label?: string;
9
+ pending?: boolean;
10
+ disabled?: boolean;
11
+ onClick: () => void | Promise<void>;
12
+ }
13
+ export interface SmartbillInvoicePanelProps {
14
+ invoiceId: string;
15
+ externalRef?: SmartbillInvoiceExternalRef | null;
16
+ title?: ReactNode;
17
+ className?: string;
18
+ hideWhenEmpty?: boolean;
19
+ sendAction?: SmartbillInvoiceAction;
20
+ retryAction?: SmartbillInvoiceAction;
21
+ convertProformaAction?: SmartbillInvoiceAction;
22
+ extraActions?: ReactNode;
23
+ }
24
+ export declare function useSmartbillInvoiceRefs(invoiceId: string | null | undefined, options?: UseSmartbillInvoiceRefsOptions): import("@tanstack/react-query").UseQueryResult<{
25
+ id: string;
26
+ invoiceId: string;
27
+ provider: string;
28
+ externalId: string | null;
29
+ externalNumber: string | null;
30
+ externalUrl: string | null;
31
+ status: string | null;
32
+ metadata: Record<string, unknown> | null;
33
+ syncedAt: string | Date | null;
34
+ syncError: string | null;
35
+ createdAt: string | Date | null;
36
+ updatedAt: string | Date | null;
37
+ }[], Error>;
38
+ export declare function useSmartbillInvoiceRef(invoiceId: string | null | undefined, options?: UseSmartbillInvoiceRefsOptions): {
39
+ data: {
40
+ id: string;
41
+ invoiceId: string;
42
+ provider: string;
43
+ externalId: string | null;
44
+ externalNumber: string | null;
45
+ externalUrl: string | null;
46
+ status: string | null;
47
+ metadata: Record<string, unknown> | null;
48
+ syncedAt: string | Date | null;
49
+ syncError: string | null;
50
+ createdAt: string | Date | null;
51
+ updatedAt: string | Date | null;
52
+ } | null | undefined;
53
+ error: Error;
54
+ isError: true;
55
+ isPending: false;
56
+ isLoading: false;
57
+ isLoadingError: false;
58
+ isRefetchError: true;
59
+ isSuccess: false;
60
+ isPlaceholderData: false;
61
+ status: "error";
62
+ dataUpdatedAt: number;
63
+ errorUpdatedAt: number;
64
+ failureCount: number;
65
+ failureReason: Error | null;
66
+ errorUpdateCount: number;
67
+ isFetched: boolean;
68
+ isFetchedAfterMount: boolean;
69
+ isFetching: boolean;
70
+ isInitialLoading: boolean;
71
+ isPaused: boolean;
72
+ isRefetching: boolean;
73
+ isStale: boolean;
74
+ isEnabled: boolean;
75
+ refetch: (options?: import("@tanstack/react-query").RefetchOptions) => Promise<import("@tanstack/react-query").QueryObserverResult<{
76
+ id: string;
77
+ invoiceId: string;
78
+ provider: string;
79
+ externalId: string | null;
80
+ externalNumber: string | null;
81
+ externalUrl: string | null;
82
+ status: string | null;
83
+ metadata: Record<string, unknown> | null;
84
+ syncedAt: string | Date | null;
85
+ syncError: string | null;
86
+ createdAt: string | Date | null;
87
+ updatedAt: string | Date | null;
88
+ }[], Error>>;
89
+ fetchStatus: import("@tanstack/react-query").FetchStatus;
90
+ promise: Promise<{
91
+ id: string;
92
+ invoiceId: string;
93
+ provider: string;
94
+ externalId: string | null;
95
+ externalNumber: string | null;
96
+ externalUrl: string | null;
97
+ status: string | null;
98
+ metadata: Record<string, unknown> | null;
99
+ syncedAt: string | Date | null;
100
+ syncError: string | null;
101
+ createdAt: string | Date | null;
102
+ updatedAt: string | Date | null;
103
+ }[]>;
104
+ } | {
105
+ data: {
106
+ id: string;
107
+ invoiceId: string;
108
+ provider: string;
109
+ externalId: string | null;
110
+ externalNumber: string | null;
111
+ externalUrl: string | null;
112
+ status: string | null;
113
+ metadata: Record<string, unknown> | null;
114
+ syncedAt: string | Date | null;
115
+ syncError: string | null;
116
+ createdAt: string | Date | null;
117
+ updatedAt: string | Date | null;
118
+ } | null | undefined;
119
+ error: null;
120
+ isError: false;
121
+ isPending: false;
122
+ isLoading: false;
123
+ isLoadingError: false;
124
+ isRefetchError: false;
125
+ isSuccess: true;
126
+ isPlaceholderData: false;
127
+ status: "success";
128
+ dataUpdatedAt: number;
129
+ errorUpdatedAt: number;
130
+ failureCount: number;
131
+ failureReason: Error | null;
132
+ errorUpdateCount: number;
133
+ isFetched: boolean;
134
+ isFetchedAfterMount: boolean;
135
+ isFetching: boolean;
136
+ isInitialLoading: boolean;
137
+ isPaused: boolean;
138
+ isRefetching: boolean;
139
+ isStale: boolean;
140
+ isEnabled: boolean;
141
+ refetch: (options?: import("@tanstack/react-query").RefetchOptions) => Promise<import("@tanstack/react-query").QueryObserverResult<{
142
+ id: string;
143
+ invoiceId: string;
144
+ provider: string;
145
+ externalId: string | null;
146
+ externalNumber: string | null;
147
+ externalUrl: string | null;
148
+ status: string | null;
149
+ metadata: Record<string, unknown> | null;
150
+ syncedAt: string | Date | null;
151
+ syncError: string | null;
152
+ createdAt: string | Date | null;
153
+ updatedAt: string | Date | null;
154
+ }[], Error>>;
155
+ fetchStatus: import("@tanstack/react-query").FetchStatus;
156
+ promise: Promise<{
157
+ id: string;
158
+ invoiceId: string;
159
+ provider: string;
160
+ externalId: string | null;
161
+ externalNumber: string | null;
162
+ externalUrl: string | null;
163
+ status: string | null;
164
+ metadata: Record<string, unknown> | null;
165
+ syncedAt: string | Date | null;
166
+ syncError: string | null;
167
+ createdAt: string | Date | null;
168
+ updatedAt: string | Date | null;
169
+ }[]>;
170
+ } | {
171
+ data: {
172
+ id: string;
173
+ invoiceId: string;
174
+ provider: string;
175
+ externalId: string | null;
176
+ externalNumber: string | null;
177
+ externalUrl: string | null;
178
+ status: string | null;
179
+ metadata: Record<string, unknown> | null;
180
+ syncedAt: string | Date | null;
181
+ syncError: string | null;
182
+ createdAt: string | Date | null;
183
+ updatedAt: string | Date | null;
184
+ } | null | undefined;
185
+ error: Error;
186
+ isError: true;
187
+ isPending: false;
188
+ isLoading: false;
189
+ isLoadingError: true;
190
+ isRefetchError: false;
191
+ isSuccess: false;
192
+ isPlaceholderData: false;
193
+ status: "error";
194
+ dataUpdatedAt: number;
195
+ errorUpdatedAt: number;
196
+ failureCount: number;
197
+ failureReason: Error | null;
198
+ errorUpdateCount: number;
199
+ isFetched: boolean;
200
+ isFetchedAfterMount: boolean;
201
+ isFetching: boolean;
202
+ isInitialLoading: boolean;
203
+ isPaused: boolean;
204
+ isRefetching: boolean;
205
+ isStale: boolean;
206
+ isEnabled: boolean;
207
+ refetch: (options?: import("@tanstack/react-query").RefetchOptions) => Promise<import("@tanstack/react-query").QueryObserverResult<{
208
+ id: string;
209
+ invoiceId: string;
210
+ provider: string;
211
+ externalId: string | null;
212
+ externalNumber: string | null;
213
+ externalUrl: string | null;
214
+ status: string | null;
215
+ metadata: Record<string, unknown> | null;
216
+ syncedAt: string | Date | null;
217
+ syncError: string | null;
218
+ createdAt: string | Date | null;
219
+ updatedAt: string | Date | null;
220
+ }[], Error>>;
221
+ fetchStatus: import("@tanstack/react-query").FetchStatus;
222
+ promise: Promise<{
223
+ id: string;
224
+ invoiceId: string;
225
+ provider: string;
226
+ externalId: string | null;
227
+ externalNumber: string | null;
228
+ externalUrl: string | null;
229
+ status: string | null;
230
+ metadata: Record<string, unknown> | null;
231
+ syncedAt: string | Date | null;
232
+ syncError: string | null;
233
+ createdAt: string | Date | null;
234
+ updatedAt: string | Date | null;
235
+ }[]>;
236
+ } | {
237
+ data: {
238
+ id: string;
239
+ invoiceId: string;
240
+ provider: string;
241
+ externalId: string | null;
242
+ externalNumber: string | null;
243
+ externalUrl: string | null;
244
+ status: string | null;
245
+ metadata: Record<string, unknown> | null;
246
+ syncedAt: string | Date | null;
247
+ syncError: string | null;
248
+ createdAt: string | Date | null;
249
+ updatedAt: string | Date | null;
250
+ } | null | undefined;
251
+ error: null;
252
+ isError: false;
253
+ isPending: true;
254
+ isLoading: true;
255
+ isLoadingError: false;
256
+ isRefetchError: false;
257
+ isSuccess: false;
258
+ isPlaceholderData: false;
259
+ status: "pending";
260
+ dataUpdatedAt: number;
261
+ errorUpdatedAt: number;
262
+ failureCount: number;
263
+ failureReason: Error | null;
264
+ errorUpdateCount: number;
265
+ isFetched: boolean;
266
+ isFetchedAfterMount: boolean;
267
+ isFetching: boolean;
268
+ isInitialLoading: boolean;
269
+ isPaused: boolean;
270
+ isRefetching: boolean;
271
+ isStale: boolean;
272
+ isEnabled: boolean;
273
+ refetch: (options?: import("@tanstack/react-query").RefetchOptions) => Promise<import("@tanstack/react-query").QueryObserverResult<{
274
+ id: string;
275
+ invoiceId: string;
276
+ provider: string;
277
+ externalId: string | null;
278
+ externalNumber: string | null;
279
+ externalUrl: string | null;
280
+ status: string | null;
281
+ metadata: Record<string, unknown> | null;
282
+ syncedAt: string | Date | null;
283
+ syncError: string | null;
284
+ createdAt: string | Date | null;
285
+ updatedAt: string | Date | null;
286
+ }[], Error>>;
287
+ fetchStatus: import("@tanstack/react-query").FetchStatus;
288
+ promise: Promise<{
289
+ id: string;
290
+ invoiceId: string;
291
+ provider: string;
292
+ externalId: string | null;
293
+ externalNumber: string | null;
294
+ externalUrl: string | null;
295
+ status: string | null;
296
+ metadata: Record<string, unknown> | null;
297
+ syncedAt: string | Date | null;
298
+ syncError: string | null;
299
+ createdAt: string | Date | null;
300
+ updatedAt: string | Date | null;
301
+ }[]>;
302
+ } | {
303
+ data: {
304
+ id: string;
305
+ invoiceId: string;
306
+ provider: string;
307
+ externalId: string | null;
308
+ externalNumber: string | null;
309
+ externalUrl: string | null;
310
+ status: string | null;
311
+ metadata: Record<string, unknown> | null;
312
+ syncedAt: string | Date | null;
313
+ syncError: string | null;
314
+ createdAt: string | Date | null;
315
+ updatedAt: string | Date | null;
316
+ } | null | undefined;
317
+ error: null;
318
+ isError: false;
319
+ isPending: true;
320
+ isLoadingError: false;
321
+ isRefetchError: false;
322
+ isSuccess: false;
323
+ isPlaceholderData: false;
324
+ status: "pending";
325
+ dataUpdatedAt: number;
326
+ errorUpdatedAt: number;
327
+ failureCount: number;
328
+ failureReason: Error | null;
329
+ errorUpdateCount: number;
330
+ isFetched: boolean;
331
+ isFetchedAfterMount: boolean;
332
+ isFetching: boolean;
333
+ isLoading: boolean;
334
+ isInitialLoading: boolean;
335
+ isPaused: boolean;
336
+ isRefetching: boolean;
337
+ isStale: boolean;
338
+ isEnabled: boolean;
339
+ refetch: (options?: import("@tanstack/react-query").RefetchOptions) => Promise<import("@tanstack/react-query").QueryObserverResult<{
340
+ id: string;
341
+ invoiceId: string;
342
+ provider: string;
343
+ externalId: string | null;
344
+ externalNumber: string | null;
345
+ externalUrl: string | null;
346
+ status: string | null;
347
+ metadata: Record<string, unknown> | null;
348
+ syncedAt: string | Date | null;
349
+ syncError: string | null;
350
+ createdAt: string | Date | null;
351
+ updatedAt: string | Date | null;
352
+ }[], Error>>;
353
+ fetchStatus: import("@tanstack/react-query").FetchStatus;
354
+ promise: Promise<{
355
+ id: string;
356
+ invoiceId: string;
357
+ provider: string;
358
+ externalId: string | null;
359
+ externalNumber: string | null;
360
+ externalUrl: string | null;
361
+ status: string | null;
362
+ metadata: Record<string, unknown> | null;
363
+ syncedAt: string | Date | null;
364
+ syncError: string | null;
365
+ createdAt: string | Date | null;
366
+ updatedAt: string | Date | null;
367
+ }[]>;
368
+ } | {
369
+ data: {
370
+ id: string;
371
+ invoiceId: string;
372
+ provider: string;
373
+ externalId: string | null;
374
+ externalNumber: string | null;
375
+ externalUrl: string | null;
376
+ status: string | null;
377
+ metadata: Record<string, unknown> | null;
378
+ syncedAt: string | Date | null;
379
+ syncError: string | null;
380
+ createdAt: string | Date | null;
381
+ updatedAt: string | Date | null;
382
+ } | null | undefined;
383
+ isError: false;
384
+ error: null;
385
+ isPending: false;
386
+ isLoading: false;
387
+ isLoadingError: false;
388
+ isRefetchError: false;
389
+ isSuccess: true;
390
+ isPlaceholderData: true;
391
+ status: "success";
392
+ dataUpdatedAt: number;
393
+ errorUpdatedAt: number;
394
+ failureCount: number;
395
+ failureReason: Error | null;
396
+ errorUpdateCount: number;
397
+ isFetched: boolean;
398
+ isFetchedAfterMount: boolean;
399
+ isFetching: boolean;
400
+ isInitialLoading: boolean;
401
+ isPaused: boolean;
402
+ isRefetching: boolean;
403
+ isStale: boolean;
404
+ isEnabled: boolean;
405
+ refetch: (options?: import("@tanstack/react-query").RefetchOptions) => Promise<import("@tanstack/react-query").QueryObserverResult<{
406
+ id: string;
407
+ invoiceId: string;
408
+ provider: string;
409
+ externalId: string | null;
410
+ externalNumber: string | null;
411
+ externalUrl: string | null;
412
+ status: string | null;
413
+ metadata: Record<string, unknown> | null;
414
+ syncedAt: string | Date | null;
415
+ syncError: string | null;
416
+ createdAt: string | Date | null;
417
+ updatedAt: string | Date | null;
418
+ }[], Error>>;
419
+ fetchStatus: import("@tanstack/react-query").FetchStatus;
420
+ promise: Promise<{
421
+ id: string;
422
+ invoiceId: string;
423
+ provider: string;
424
+ externalId: string | null;
425
+ externalNumber: string | null;
426
+ externalUrl: string | null;
427
+ status: string | null;
428
+ metadata: Record<string, unknown> | null;
429
+ syncedAt: string | Date | null;
430
+ syncError: string | null;
431
+ createdAt: string | Date | null;
432
+ updatedAt: string | Date | null;
433
+ }[]>;
434
+ };
435
+ export declare function SmartbillInvoicePanel({ invoiceId, externalRef, title, className, hideWhenEmpty, sendAction, retryAction, convertProformaAction, extraActions, }: SmartbillInvoicePanelProps): import("react/jsx-runtime").JSX.Element | null;
436
+ export declare function useSmartbillInvoiceSyncAction(invoiceId: string): SmartbillInvoiceAction;
437
+ export declare function useSmartbillConvertProformaAction(invoiceId: string): SmartbillInvoiceAction;
438
+ //# sourceMappingURL=invoice-ui.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invoice-ui.d.ts","sourceRoot":"","sources":["../src/invoice-ui.tsx"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC,OAAO,EAGL,KAAK,2BAA2B,EAGjC,MAAM,sBAAsB,CAAA;AAI7B,OAAO,EACL,gCAAgC,EAChC,qCAAqC,EACrC,KAAK,4BAA4B,EACjC,KAAK,2BAA2B,EAChC,KAAK,8BAA8B,EACnC,yBAAyB,GAC1B,MAAM,sBAAsB,CAAA;AAE7B,MAAM,WAAW,8BAA8B;IAC7C,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,OAAO,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACpC;AAED,MAAM,WAAW,0BAA0B;IACzC,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,2BAA2B,GAAG,IAAI,CAAA;IAChD,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,UAAU,CAAC,EAAE,sBAAsB,CAAA;IACnC,WAAW,CAAC,EAAE,sBAAsB,CAAA;IACpC,qBAAqB,CAAC,EAAE,sBAAsB,CAAA;IAC9C,YAAY,CAAC,EAAE,SAAS,CAAA;CACzB;AAED,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACpC,OAAO,GAAE,8BAAmC;;;;;;;;;;;;;YAiB7C;AAED,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACpC,OAAO,GAAE,8BAAmC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAO7C;AAED,wBAAgB,qBAAqB,CAAC,EACpC,SAAS,EACT,WAAW,EACX,KAAmB,EACnB,SAAS,EACT,aAAqB,EACrB,UAAU,EACV,WAAW,EACX,qBAAqB,EACrB,YAAY,GACb,EAAE,0BAA0B,kDAuG5B;AAED,wBAAgB,6BAA6B,CAAC,SAAS,EAAE,MAAM,GAAG,sBAAsB,CAuBvF;AAED,wBAAgB,iCAAiC,CAAC,SAAS,EAAE,MAAM,GAAG,sBAAsB,CAuB3F"}
@@ -0,0 +1,97 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
4
+ import { fetchWithValidation, useVoyantFinanceContext } from "@voyant-travel/finance-react";
5
+ import { Badge, Button, buttonVariants, Card, CardAction, CardContent, CardHeader, CardTitle, } from "@voyant-travel/ui/components";
6
+ import { cn } from "@voyant-travel/ui/lib/utils";
7
+ import { ArrowRightLeft, ExternalLink, FileText, Loader2, RefreshCw, Send } from "lucide-react";
8
+ import { z } from "zod";
9
+ import { getSmartbillInvoiceDocumentLinks, resolveSmartbillInvoiceReferenceParts, selectSmartbillInvoiceRef, smartbillInvoiceExternalRefsResponseSchema, } from "./invoice-ui-data.js";
10
+ const actionResponseSchema = z.object({ data: z.unknown().optional() });
11
+ export { getSmartbillInvoiceDocumentLinks, resolveSmartbillInvoiceReferenceParts, selectSmartbillInvoiceRef, } from "./invoice-ui-data.js";
12
+ export function useSmartbillInvoiceRefs(invoiceId, options = {}) {
13
+ const { baseUrl, fetcher } = useVoyantFinanceContext();
14
+ const { enabled = true } = options;
15
+ return useQuery({
16
+ queryKey: ["voyant", "smartbill", "invoice", invoiceId, "external-refs"],
17
+ queryFn: async () => {
18
+ const response = await fetchWithValidation(`/v1/finance/invoices/${encodeURIComponent(invoiceId ?? "")}/external-refs`, smartbillInvoiceExternalRefsResponseSchema, { baseUrl, fetcher });
19
+ return response.data.filter((ref) => ref.provider === "smartbill");
20
+ },
21
+ enabled: enabled && Boolean(invoiceId),
22
+ });
23
+ }
24
+ export function useSmartbillInvoiceRef(invoiceId, options = {}) {
25
+ const query = useSmartbillInvoiceRefs(invoiceId, options);
26
+ return {
27
+ ...query,
28
+ data: query.data ? selectSmartbillInvoiceRef(query.data) : undefined,
29
+ };
30
+ }
31
+ export function SmartbillInvoicePanel({ invoiceId, externalRef, title = "SmartBill", className, hideWhenEmpty = false, sendAction, retryAction, convertProformaAction, extraActions, }) {
32
+ const query = useSmartbillInvoiceRef(invoiceId, { enabled: externalRef === undefined });
33
+ const defaultSyncAction = useSmartbillInvoiceSyncAction(invoiceId);
34
+ const defaultConvertProformaAction = useSmartbillConvertProformaAction(invoiceId);
35
+ const ref = externalRef === undefined ? query.data : externalRef;
36
+ const isLoading = externalRef === undefined && query.isPending;
37
+ const isError = externalRef === undefined && query.isError;
38
+ if (hideWhenEmpty && !isLoading && !isError && !ref) {
39
+ return null;
40
+ }
41
+ const reference = resolveSmartbillInvoiceReferenceParts(ref);
42
+ const documentLinks = getSmartbillInvoiceDocumentLinks(ref);
43
+ const status = ref?.syncError ? "error" : (ref?.status ?? null);
44
+ const effectiveSendAction = sendAction ?? defaultSyncAction;
45
+ const effectiveRetryAction = retryAction ?? (ref ? defaultSyncAction : undefined);
46
+ const effectiveConvertProformaAction = convertProformaAction ?? defaultConvertProformaAction;
47
+ const canConvertProforma = reference.documentType === "proforma" && Boolean(effectiveConvertProformaAction);
48
+ return (_jsxs(Card, { "data-slot": "smartbill-invoice-panel", size: "sm", className: className, children: [_jsxs(CardHeader, { children: [_jsxs(CardTitle, { className: "flex min-w-0 items-center gap-2", children: [_jsx(FileText, { className: "size-4 text-muted-foreground", "aria-hidden": "true" }), _jsx("span", { className: "truncate", children: title })] }), _jsx(CardAction, { children: status ? (_jsx(Badge, { variant: status === "error" ? "destructive" : "outline", children: status })) : null })] }), _jsxs(CardContent, { className: "grid gap-4", children: [isLoading ? (_jsxs("div", { className: "flex items-center gap-2 text-muted-foreground text-sm", children: [_jsx(Loader2, { className: "size-4 animate-spin", "aria-hidden": "true" }), "Loading SmartBill state"] })) : isError ? (_jsx("p", { className: "text-destructive text-sm", children: "SmartBill state could not be loaded." })) : ref ? (_jsxs("div", { className: "grid gap-3 text-sm", children: [_jsxs("dl", { className: "grid gap-2 sm:grid-cols-2", children: [_jsx(SmartbillField, { label: "Series", children: reference.seriesName ?? "-" }), _jsx(SmartbillField, { label: "Number", children: reference.number ?? "-" }), _jsx(SmartbillField, { label: "Type", children: reference.documentType ?? "-" }), _jsx(SmartbillField, { label: "Synced", children: formatDateTime(ref.syncedAt) ?? "-" })] }), ref.syncError ? (_jsx("p", { className: "rounded-md border border-destructive/20 bg-destructive/5 p-2 text-destructive", children: ref.syncError })) : null, documentLinks.length > 0 ? (_jsx("div", { className: "flex flex-wrap gap-2", children: documentLinks.map((link) => (_jsxs("a", { href: link.href, target: "_blank", rel: "noreferrer", className: buttonVariants({ variant: "outline", size: "sm" }), children: [_jsx(ExternalLink, { className: "size-4", "aria-hidden": "true" }), link.label] }, link.href))) })) : null] })) : (_jsx("p", { className: "text-muted-foreground text-sm", children: "No SmartBill reference is linked yet." })), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [!ref && !isLoading && !isError ? (_jsx(SmartbillActionButton, { action: effectiveSendAction, icon: _jsx(Send, { className: "size-4" }), children: effectiveSendAction.label ?? "Send to SmartBill" })) : null, effectiveRetryAction ? (_jsx(SmartbillActionButton, { action: effectiveRetryAction, icon: _jsx(RefreshCw, { className: "size-4" }), children: effectiveRetryAction.label ?? "Retry sync" })) : null, canConvertProforma && effectiveConvertProformaAction ? (_jsx(SmartbillActionButton, { action: effectiveConvertProformaAction, icon: _jsx(ArrowRightLeft, { className: "size-4" }), children: effectiveConvertProformaAction.label ?? "Convert proforma" })) : null, extraActions] })] })] }));
49
+ }
50
+ export function useSmartbillInvoiceSyncAction(invoiceId) {
51
+ const { baseUrl, fetcher } = useVoyantFinanceContext();
52
+ const queryClient = useQueryClient();
53
+ const mutation = useMutation({
54
+ mutationFn: async () => fetchWithValidation(`/v1/admin/smartbill/invoices/${encodeURIComponent(invoiceId)}/sync`, actionResponseSchema, { baseUrl, fetcher }, { method: "POST" }),
55
+ onSuccess: async () => {
56
+ await queryClient.invalidateQueries({ queryKey: ["voyant"] });
57
+ },
58
+ });
59
+ return {
60
+ pending: mutation.isPending,
61
+ disabled: !invoiceId,
62
+ onClick: async () => {
63
+ await mutation.mutateAsync();
64
+ },
65
+ };
66
+ }
67
+ export function useSmartbillConvertProformaAction(invoiceId) {
68
+ const { baseUrl, fetcher } = useVoyantFinanceContext();
69
+ const queryClient = useQueryClient();
70
+ const mutation = useMutation({
71
+ mutationFn: async () => fetchWithValidation(`/v1/finance/invoices/${encodeURIComponent(invoiceId)}/convert-to-invoice`, actionResponseSchema, { baseUrl, fetcher }, { method: "POST", body: JSON.stringify({}) }),
72
+ onSuccess: async () => {
73
+ await queryClient.invalidateQueries({ queryKey: ["voyant"] });
74
+ },
75
+ });
76
+ return {
77
+ pending: mutation.isPending,
78
+ disabled: !invoiceId,
79
+ onClick: async () => {
80
+ await mutation.mutateAsync();
81
+ },
82
+ };
83
+ }
84
+ function SmartbillField({ label, children }) {
85
+ return (_jsxs("div", { className: "grid gap-1", children: [_jsx("dt", { className: "text-muted-foreground text-xs uppercase", children: label }), _jsx("dd", { className: "break-words font-medium", children: children })] }));
86
+ }
87
+ function SmartbillActionButton({ action, icon, children, }) {
88
+ return (_jsxs(Button, { type: "button", variant: "outline", size: "sm", disabled: action.disabled || action.pending, onClick: () => void action.onClick(), children: [_jsx("span", { className: cn(action.pending && "animate-spin"), children: action.pending ? _jsx(Loader2, { className: "size-4", "aria-hidden": "true" }) : icon }), children] }));
89
+ }
90
+ function formatDateTime(value) {
91
+ if (!value)
92
+ return null;
93
+ const date = value instanceof Date ? value : new Date(value);
94
+ if (Number.isNaN(date.getTime()))
95
+ return null;
96
+ return new Intl.DateTimeFormat(undefined, { dateStyle: "medium", timeStyle: "short" }).format(date);
97
+ }
@@ -0,0 +1,50 @@
1
+ import type { SmartbillClient, SmartbillInvoiceBody, SmartbillProduct, VoyantInvoiceEvent } from "./types.js";
2
+ export type SmartbillMaybePromise<T> = T | Promise<T>;
3
+ export type SmartbillEventValue<T> = T | ((event: VoyantInvoiceEvent) => SmartbillMaybePromise<T>);
4
+ /**
5
+ * Options for the default invoice mapper.
6
+ */
7
+ export interface SmartbillMappingOptions {
8
+ /** Romanian company VAT code (e.g. `"RO12345678"`). */
9
+ companyVatCode: string;
10
+ /** SmartBill invoice series name (e.g. `"A"`), or an event-specific resolver. */
11
+ seriesName: SmartbillEventValue<string>;
12
+ /** Invoice language. Defaults to `"RO"`. */
13
+ language?: string;
14
+ /** Whether VAT is included in line item prices. Defaults to `true`. */
15
+ isTaxIncluded?: boolean;
16
+ /** SmartBill product unit name. Defaults to `"buc"`. */
17
+ measuringUnitName?: SmartbillEventValue<string | null | undefined>;
18
+ /** Whether to use Art. 311 special regime (margin scheme for travel). */
19
+ art311SpecialRegime?: boolean;
20
+ /** Text appended to mentions when Art. 311 special regime is enabled. */
21
+ art311SpecialRegimeText?: string;
22
+ /** SmartBill mentions override, or an event-specific resolver. Defaults to event.mentions. */
23
+ mentions?: SmartbillEventValue<string | null | undefined>;
24
+ /** SmartBill observations override, or an event-specific resolver. Defaults to event.observations. */
25
+ observations?: SmartbillEventValue<string | null | undefined>;
26
+ }
27
+ /**
28
+ * Extract the SmartBill client block from a Voyant invoice event.
29
+ * Falls back to SmartBill-parseable defaults for fields the API treats as required.
30
+ */
31
+ export declare function mapClient(event: VoyantInvoiceEvent): SmartbillClient;
32
+ /**
33
+ * Extract SmartBill product lines from a Voyant invoice event.
34
+ * Expects `event.lineItems` to be an array of objects with at minimum
35
+ * `description`/`name`, `quantity`, `unitPrice`, `currency`.
36
+ */
37
+ export declare function mapLineItems(event: VoyantInvoiceEvent, options: Pick<SmartbillMappingOptions, "isTaxIncluded"> & {
38
+ measuringUnitName?: string;
39
+ }): SmartbillProduct[];
40
+ /**
41
+ * Map a full Voyant invoice event to a SmartBill invoice body.
42
+ */
43
+ export declare function mapVoyantInvoiceToSmartbill(event: VoyantInvoiceEvent, options: SmartbillMappingOptions): SmartbillInvoiceBody;
44
+ /**
45
+ * Async variant of the default mapper. Use this when mapping options include
46
+ * promise-returning callbacks such as `seriesName`, `mentions`, or
47
+ * `observations`.
48
+ */
49
+ export declare function mapVoyantInvoiceToSmartbillAsync(event: VoyantInvoiceEvent, options: SmartbillMappingOptions): Promise<SmartbillInvoiceBody>;
50
+ //# sourceMappingURL=mapping.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mapping.d.ts","sourceRoot":"","sources":["../src/mapping.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,EACnB,MAAM,YAAY,CAAA;AAEnB,MAAM,MAAM,qBAAqB,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;AAErD,MAAM,MAAM,mBAAmB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,kBAAkB,KAAK,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAA;AASlG;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,uDAAuD;IACvD,cAAc,EAAE,MAAM,CAAA;IACtB,iFAAiF;IACjF,UAAU,EAAE,mBAAmB,CAAC,MAAM,CAAC,CAAA;IACvC,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,uEAAuE;IACvE,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,wDAAwD;IACxD,iBAAiB,CAAC,EAAE,mBAAmB,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAA;IAClE,yEAAyE;IACzE,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B,yEAAyE;IACzE,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,8FAA8F;IAC9F,QAAQ,CAAC,EAAE,mBAAmB,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAA;IACzD,sGAAsG;IACtG,YAAY,CAAC,EAAE,mBAAmB,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAA;CAC9D;AAgBD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,kBAAkB,GAAG,eAAe,CAkBpE;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,kBAAkB,EACzB,OAAO,EAAE,IAAI,CAAC,uBAAuB,EAAE,eAAe,CAAC,GAAG;IAAE,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAAE,GACvF,gBAAgB,EAAE,CAqBpB;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,kBAAkB,EACzB,OAAO,EAAE,uBAAuB,GAC/B,oBAAoB,CAEtB;AAED;;;;GAIG;AACH,wBAAsB,gCAAgC,CACpD,KAAK,EAAE,kBAAkB,EACzB,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,oBAAoB,CAAC,CAE/B"}