@cogenta/commerce 0.2.0 → 0.4.3

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 (95) hide show
  1. package/dist/admin/permissions.d.ts +8 -0
  2. package/dist/admin/permissions.d.ts.map +1 -1
  3. package/dist/admin/permissions.js +1 -0
  4. package/dist/admin/permissions.js.map +1 -1
  5. package/dist/admin/router.d.ts +47 -5
  6. package/dist/admin/router.d.ts.map +1 -1
  7. package/dist/admin/router.js +942 -24
  8. package/dist/admin/router.js.map +1 -1
  9. package/dist/cart/store.d.ts +23 -0
  10. package/dist/cart/store.d.ts.map +1 -1
  11. package/dist/cart/store.js +49 -2
  12. package/dist/cart/store.js.map +1 -1
  13. package/dist/catalog/csv.d.ts +29 -0
  14. package/dist/catalog/csv.d.ts.map +1 -0
  15. package/dist/catalog/csv.js +396 -0
  16. package/dist/catalog/csv.js.map +1 -0
  17. package/dist/catalog/store.d.ts +24 -4
  18. package/dist/catalog/store.d.ts.map +1 -1
  19. package/dist/catalog/store.js +238 -11
  20. package/dist/catalog/store.js.map +1 -1
  21. package/dist/catalog/types.d.ts +92 -0
  22. package/dist/catalog/types.d.ts.map +1 -1
  23. package/dist/catalog/types.js +20 -0
  24. package/dist/catalog/types.js.map +1 -1
  25. package/dist/coupon/store.d.ts +63 -5
  26. package/dist/coupon/store.d.ts.map +1 -1
  27. package/dist/coupon/store.js +140 -7
  28. package/dist/coupon/store.js.map +1 -1
  29. package/dist/customer/store.d.ts +17 -0
  30. package/dist/customer/store.d.ts.map +1 -1
  31. package/dist/customer/store.js +26 -0
  32. package/dist/customer/store.js.map +1 -1
  33. package/dist/index.d.ts +18 -8
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +9 -3
  36. package/dist/index.js.map +1 -1
  37. package/dist/invoice/credit-note.d.ts +45 -0
  38. package/dist/invoice/credit-note.d.ts.map +1 -0
  39. package/dist/invoice/credit-note.js +109 -0
  40. package/dist/invoice/credit-note.js.map +1 -0
  41. package/dist/invoice/sequence.d.ts +21 -0
  42. package/dist/invoice/sequence.d.ts.map +1 -0
  43. package/dist/invoice/sequence.js +64 -0
  44. package/dist/invoice/sequence.js.map +1 -0
  45. package/dist/invoice/store.d.ts +23 -1
  46. package/dist/invoice/store.d.ts.map +1 -1
  47. package/dist/invoice/store.js +23 -56
  48. package/dist/invoice/store.js.map +1 -1
  49. package/dist/order/csv.d.ts +24 -0
  50. package/dist/order/csv.d.ts.map +1 -0
  51. package/dist/order/csv.js +42 -0
  52. package/dist/order/csv.js.map +1 -0
  53. package/dist/order/notify.d.ts +65 -0
  54. package/dist/order/notify.d.ts.map +1 -0
  55. package/dist/order/notify.js +180 -0
  56. package/dist/order/notify.js.map +1 -0
  57. package/dist/order/store.d.ts +58 -1
  58. package/dist/order/store.d.ts.map +1 -1
  59. package/dist/order/store.js +145 -10
  60. package/dist/order/store.js.map +1 -1
  61. package/dist/order/types.d.ts +35 -1
  62. package/dist/order/types.d.ts.map +1 -1
  63. package/dist/order/types.js +2 -0
  64. package/dist/order/types.js.map +1 -1
  65. package/dist/payment/paypal.d.ts +9 -0
  66. package/dist/payment/paypal.d.ts.map +1 -0
  67. package/dist/payment/paypal.js +583 -0
  68. package/dist/payment/paypal.js.map +1 -0
  69. package/dist/payment/registry.d.ts +15 -6
  70. package/dist/payment/registry.d.ts.map +1 -1
  71. package/dist/payment/registry.js +17 -6
  72. package/dist/payment/registry.js.map +1 -1
  73. package/dist/payment/types.d.ts +6 -0
  74. package/dist/payment/types.d.ts.map +1 -1
  75. package/dist/shipping/store.d.ts +29 -3
  76. package/dist/shipping/store.d.ts.map +1 -1
  77. package/dist/shipping/store.js +68 -4
  78. package/dist/shipping/store.js.map +1 -1
  79. package/dist/subscription/renewal-notifier.d.ts +17 -0
  80. package/dist/subscription/renewal-notifier.d.ts.map +1 -0
  81. package/dist/subscription/renewal-notifier.js +33 -0
  82. package/dist/subscription/renewal-notifier.js.map +1 -0
  83. package/dist/subscription/store.d.ts +126 -3
  84. package/dist/subscription/store.d.ts.map +1 -1
  85. package/dist/subscription/store.js +348 -8
  86. package/dist/subscription/store.js.map +1 -1
  87. package/dist/tables.d.ts +17 -0
  88. package/dist/tables.d.ts.map +1 -1
  89. package/dist/tables.js +273 -0
  90. package/dist/tables.js.map +1 -1
  91. package/dist/tax/store.d.ts +20 -0
  92. package/dist/tax/store.d.ts.map +1 -1
  93. package/dist/tax/store.js +51 -7
  94. package/dist/tax/store.js.map +1 -1
  95. package/package.json +3 -2
package/dist/index.js CHANGED
@@ -1,14 +1,19 @@
1
1
  export { COMMERCE_ANONYMOUS, COMMERCE_PERMISSIONS, createCommercePermissions, DEFAULT_COMMERCE_ROLES, } from './admin/permissions.js';
2
2
  export { createCommerceAdminRouter } from './admin/router.js';
3
- export { CART_STATUSES, CART_TTL_MS, couponRefusal, createCartStore } from './cart/store.js';
3
+ export { CART_STATUSES, CART_TTL_MS, couponRefusal, createCartStore, DEFAULT_CART_ABANDON_MS, } from './cart/store.js';
4
4
  export { computeTotals } from './cart/totals.js';
5
+ export { applyProductsImport, exportProductsCsv, previewProductsImport } from './catalog/csv.js';
5
6
  export { createCatalogStore } from './catalog/store.js';
6
- export { PRODUCT_STATUSES } from './catalog/types.js';
7
+ export { isOnSale, PRODUCT_STATUSES, STOCK_MOVEMENT_REASONS } from './catalog/types.js';
7
8
  export { COUPON_KINDS, createCouponStore, discountFor, normaliseCode, } from './coupon/store.js';
8
9
  export { createCustomerStore, normaliseEmail } from './customer/store.js';
10
+ export { createCreditNoteStore } from './invoice/credit-note.js';
9
11
  export { renderInvoicePdf } from './invoice/pdf.js';
12
+ export { claimSequenceNumber, formatSequenceNumber } from './invoice/sequence.js';
10
13
  export { createInvoiceStore, formatInvoiceNumber, pdfDocumentFor } from './invoice/store.js';
11
14
  export { applyBasisPoints, assertCurrency, assertMinor, assertSameCurrency, distribute, formatMoney, minorUnitExponent, normaliseCurrency, } from './money.js';
15
+ export { ordersToCsv } from './order/csv.js';
16
+ export { buildConfirmationMessage, buildShipmentMessage, createOrderEmailQueue, MAX_ATTEMPTS as ORDER_EMAIL_MAX_ATTEMPTS, ORDER_EMAIL_KINDS, } from './order/notify.js';
12
17
  export { createOrderStore, referenceFrom } from './order/store.js';
13
18
  export { assertTransition, canTransition, holdsStock, ORDER_EVENT_KINDS, ORDER_STATUSES, } from './order/types.js';
14
19
  export { createManualPaymentGateway, manualPaymentDriver, transferReference, } from './payment/manual.js';
@@ -17,7 +22,8 @@ export { createPaymentStore } from './payment/store.js';
17
22
  export { stripePaymentDriver } from './payment/stripe.js';
18
23
  export { PAYMENT_STATUSES } from './payment/types.js';
19
24
  export { createShippingStore, SHIPPING_KINDS, storedRate } from './shipping/store.js';
20
- export { advancePeriod, createSubscriptionStore, INTERVAL_UNITS, SUBSCRIPTION_STATUSES, } from './subscription/store.js';
25
+ export { createEmailRenewalNotifier } from './subscription/renewal-notifier.js';
26
+ export { advancePeriod, createSubscriptionStore, DEFAULT_DUNNING_SCHEDULE_DAYS, DEFAULT_RENEWAL_NOTICE_DAYS, INTERVAL_UNITS, SUBSCRIPTION_STATUSES, } from './subscription/store.js';
21
27
  export { ensureCommerceTables, TABLES } from './tables.js';
22
28
  export { createTaxStore, taxFor } from './tax/store.js';
23
29
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,yBAAyB,EACzB,sBAAsB,GACvB,MAAM,wBAAwB,CAAA;AAO/B,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAA;AAU7D,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAE5F,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAEhD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAavD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAQrD,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,WAAW,EACX,aAAa,GACd,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AASnD,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAE5F,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,WAAW,EACX,kBAAkB,EAClB,UAAU,EACV,WAAW,EACX,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,YAAY,CAAA;AAQnB,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAElE,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,UAAU,EACV,iBAAiB,EACjB,cAAc,GACf,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,0BAA0B,EAC1B,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,qBAAqB,CAAA;AAE5B,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAE7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAczD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAWrD,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAWrF,OAAO,EACL,aAAa,EACb,uBAAuB,EACvB,cAAc,EACd,qBAAqB,GACtB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,oBAAoB,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAQ1D,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,yBAAyB,EACzB,sBAAsB,GACvB,MAAM,wBAAwB,CAAA;AAO/B,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAA;AAU7D,OAAO,EACL,aAAa,EACb,WAAW,EACX,aAAa,EACb,eAAe,EACf,uBAAuB,GACxB,MAAM,iBAAiB,CAAA;AAExB,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAQhD,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAA;AAEhG,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAiBvD,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAUvF,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,WAAW,EACX,aAAa,GACd,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAOzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;AAEhE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AASjF,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAE5F,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,WAAW,EACX,kBAAkB,EAClB,UAAU,EACV,WAAW,EACX,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAQ5C,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,qBAAqB,EACrB,YAAY,IAAI,wBAAwB,EACxC,iBAAiB,GAClB,MAAM,mBAAmB,CAAA;AAU1B,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAUlE,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,UAAU,EACV,iBAAiB,EACjB,cAAc,GACf,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,0BAA0B,EAC1B,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,qBAAqB,CAAA;AAE5B,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAE7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAczD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAWrD,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AACrF,OAAO,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAA;AAoB/E,OAAO,EACL,aAAa,EACb,uBAAuB,EACvB,6BAA6B,EAC7B,2BAA2B,EAC3B,cAAc,EACd,qBAAqB,GACtB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,oBAAoB,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAQ1D,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA"}
@@ -0,0 +1,45 @@
1
+ import { type DatabaseHandle } from '@cogenta/core';
2
+ import type { OrderStore } from '../order/store.js';
3
+ import type { InvoiceDocument, SellerDetails } from './store.js';
4
+ /**
5
+ * A refund's accounting counterpart (fiche 52 task 6): "Avoir : nouvelle
6
+ * série de numérotation réutilisant le compare-and-set d'`invoice/store.ts`."
7
+ * One credit note per refund — never per order, since an order can be
8
+ * refunded in several instalments and each one needs its own number — issued
9
+ * in its own series (`CN-2026`, distinct from an invoice's own `2026`) so
10
+ * neither numbering can ever collide with or shadow the other, while both
11
+ * still share one compare-and-set sequence table (`sequence.ts`).
12
+ */
13
+ export interface CreditNote {
14
+ readonly id: string;
15
+ readonly orderId: string;
16
+ readonly refundId: string;
17
+ readonly series: string;
18
+ readonly seq: number;
19
+ readonly number: string;
20
+ readonly issuedAt: string;
21
+ readonly currency: string;
22
+ readonly amountMinor: number;
23
+ readonly reason: string | null;
24
+ readonly document: InvoiceDocument;
25
+ }
26
+ export interface IssueCreditNoteInput {
27
+ readonly orderId: string;
28
+ readonly refundId: string;
29
+ readonly amountMinor: number;
30
+ readonly reason?: string | null;
31
+ readonly series?: string;
32
+ readonly actorId?: string | null;
33
+ }
34
+ export interface CreditNoteStoreDependencies {
35
+ readonly orders: OrderStore;
36
+ readonly seller: SellerDetails;
37
+ }
38
+ export interface CreditNoteStore {
39
+ issue(input: IssueCreditNoteInput): Promise<CreditNote>;
40
+ read(id: string): Promise<CreditNote | null>;
41
+ readByRefund(refundId: string): Promise<CreditNote | null>;
42
+ listForOrder(orderId: string): Promise<readonly CreditNote[]>;
43
+ }
44
+ export declare function createCreditNoteStore(db: DatabaseHandle, dependencies: CreditNoteStoreDependencies, now?: () => number): CreditNoteStore;
45
+ //# sourceMappingURL=credit-note.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credit-note.d.ts","sourceRoot":"","sources":["../../src/invoice/credit-note.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,cAAc,EAKpB,MAAM,eAAe,CAAA;AACtB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAKnD,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAEhE;;;;;;;;GAQG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAA;CACnC;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACjC;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAA;IAC3B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAA;CAC/B;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;IACvD,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAA;IAC5C,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAA;IAC1D,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,UAAU,EAAE,CAAC,CAAA;CAC9D;AAoED,wBAAgB,qBAAqB,CACnC,EAAE,EAAE,cAAc,EAClB,YAAY,EAAE,2BAA2B,EACzC,GAAG,GAAE,MAAM,MAAiB,GAC3B,eAAe,CAyFjB"}
@@ -0,0 +1,109 @@
1
+ import { CogentaError, identifier, newId, sql, } from '@cogenta/core';
2
+ import { toInt, toNullableText, toText } from '../rows.js';
3
+ import { TABLES } from '../tables.js';
4
+ import { claimSequenceNumber, formatSequenceNumber } from './sequence.js';
5
+ function decode(row) {
6
+ return {
7
+ id: toText(row.id, 'credit_note.id'),
8
+ orderId: toText(row.order_id, 'credit_note.order_id'),
9
+ refundId: toText(row.refund_id, 'credit_note.refund_id'),
10
+ series: toText(row.series, 'credit_note.series'),
11
+ seq: toInt(row.seq, 'credit_note.seq'),
12
+ number: toText(row.number, 'credit_note.number'),
13
+ issuedAt: toText(row.issued_at, 'credit_note.issued_at'),
14
+ currency: toText(row.currency, 'credit_note.currency'),
15
+ amountMinor: toInt(row.amount_minor, 'credit_note.amount_minor'),
16
+ reason: toNullableText(row.reason),
17
+ document: JSON.parse(toText(row.document, 'credit_note.document')),
18
+ };
19
+ }
20
+ function documentFor(order, number, issuedAt, amountMinor, seller) {
21
+ return {
22
+ number,
23
+ issuedAt,
24
+ orderReference: order.reference,
25
+ seller: seller.address,
26
+ buyer: [order.email],
27
+ currency: order.currency,
28
+ // A credit note shows what it refunds, not the whole order again — one
29
+ // line, the amount actually returned, rather than re-listing goods the
30
+ // customer kept.
31
+ lines: [
32
+ {
33
+ sku: '—',
34
+ title: `Refund on order ${order.reference}`,
35
+ quantity: 1,
36
+ unitPriceMinor: amountMinor,
37
+ taxRateBp: 0,
38
+ totalMinor: amountMinor,
39
+ },
40
+ ],
41
+ subtotalMinor: amountMinor,
42
+ discountMinor: 0,
43
+ shippingMinor: 0,
44
+ taxMinor: 0,
45
+ totalMinor: amountMinor,
46
+ footer: seller.footer ?? null,
47
+ };
48
+ }
49
+ export function createCreditNoteStore(db, dependencies, now = Date.now) {
50
+ const d = db.dialect;
51
+ const table = identifier(TABLES.creditNotes, d);
52
+ async function read(id, executor = db) {
53
+ const result = await executor.query(sql `select * from ${table} where id = ${id}`);
54
+ const row = result.rows[0];
55
+ return row === undefined ? null : decode(row);
56
+ }
57
+ return {
58
+ issue: async (input) => {
59
+ const order = await dependencies.orders.read(input.orderId);
60
+ if (order === null) {
61
+ throw new CogentaError({
62
+ code: 'COMMERCE_ORDER_NOT_FOUND',
63
+ message: 'This order does not exist.',
64
+ hint: 'Check the order reference.',
65
+ });
66
+ }
67
+ const existing = await db.query(sql `select * from ${table} where refund_id = ${input.refundId}`);
68
+ if (existing.rows[0] !== undefined)
69
+ return decode(existing.rows[0]);
70
+ const issuedAt = new Date(now()).toISOString();
71
+ const series = input.series ?? `CN-${issuedAt.slice(0, 4)}`;
72
+ const id = newId(now);
73
+ return db.transaction(async (tx) => {
74
+ const seq = await claimSequenceNumber(tx, d, series);
75
+ const number = formatSequenceNumber(series, seq);
76
+ const document = documentFor(order, number, issuedAt, input.amountMinor, dependencies.seller);
77
+ await tx.query(sql `
78
+ insert into ${table} (id, order_id, refund_id, series, seq, number, issued_at,
79
+ currency, amount_minor, reason, document)
80
+ values (${id}, ${order.id}, ${input.refundId}, ${series}, ${seq}, ${number}, ${issuedAt},
81
+ ${order.currency}, ${input.amountMinor}, ${input.reason ?? null}, ${JSON.stringify(document)})`);
82
+ await dependencies.orders.record(order.id, 'note', {
83
+ note: `Credit note ${number} issued for refund ${input.refundId}.`,
84
+ actorId: input.actorId ?? null,
85
+ }, tx);
86
+ const stored = await read(id, tx);
87
+ if (stored === null) {
88
+ throw new CogentaError({
89
+ code: 'COMMERCE_CREDIT_NOTE_NOT_FOUND',
90
+ message: 'The credit note was not stored.',
91
+ hint: 'Check that the commerce tables exist (ensureCommerceTables).',
92
+ });
93
+ }
94
+ return stored;
95
+ }, { immediate: true });
96
+ },
97
+ read,
98
+ readByRefund: async (refundId) => {
99
+ const result = await db.query(sql `select * from ${table} where refund_id = ${refundId}`);
100
+ const row = result.rows[0];
101
+ return row === undefined ? null : decode(row);
102
+ },
103
+ listForOrder: async (orderId) => {
104
+ const result = await db.query(sql `select * from ${table} where order_id = ${orderId} order by seq asc`);
105
+ return result.rows.map(decode);
106
+ },
107
+ };
108
+ }
109
+ //# sourceMappingURL=credit-note.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credit-note.js","sourceRoot":"","sources":["../../src/invoice/credit-note.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { type DatabaseDialect, type SqlExecutor } from '@cogenta/core';
2
+ /** `2026-000042` / `CN-2026-000003`. Zero-padded so the numbers sort as strings too. */
3
+ export declare function formatSequenceNumber(series: string, seq: number): string;
4
+ /**
5
+ * Takes the next number in a series, atomically — shared by invoices
6
+ * (`invoice/store.ts`) and credit notes (`invoice/credit-note.ts`, fiche 52
7
+ * task 6), both series living in the same `cogenta_commerce_invoice_sequences`
8
+ * table, told apart only by their series string (an invoice's is the year,
9
+ * `2026`; a credit note's is `CN-2026` — see `credit-note.ts`).
10
+ *
11
+ * `update … set next_seq = next_seq + 1 where series = ? and next_seq = ?` —
12
+ * a compare-and-set whose `rowsAffected` decides the race, the same idiom
13
+ * that makes stock safe and a password reset token single use. Two documents
14
+ * issued in the same millisecond get consecutive numbers, never the same one.
15
+ *
16
+ * Emphatically not `count(*) + 1`: that hands out a duplicate under any
17
+ * concurrency at all, and re-issues a number that a deleted row used to
18
+ * hold. A number, once handed out, is spent.
19
+ */
20
+ export declare function claimSequenceNumber(tx: SqlExecutor, dialect: DatabaseDialect, series: string): Promise<number>;
21
+ //# sourceMappingURL=sequence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sequence.d.ts","sourceRoot":"","sources":["../../src/invoice/sequence.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,eAAe,EAEpB,KAAK,WAAW,EAEjB,MAAM,eAAe,CAAA;AAItB,wFAAwF;AACxF,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAExE;AAYD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,mBAAmB,CACvC,EAAE,EAAE,WAAW,EACf,OAAO,EAAE,eAAe,EACxB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,CAkCjB"}
@@ -0,0 +1,64 @@
1
+ import { CogentaError, identifier, sql, } from '@cogenta/core';
2
+ import { toInt } from '../rows.js';
3
+ import { TABLES } from '../tables.js';
4
+ /** `2026-000042` / `CN-2026-000003`. Zero-padded so the numbers sort as strings too. */
5
+ export function formatSequenceNumber(series, seq) {
6
+ return `${series}-${String(seq).padStart(6, '0')}`;
7
+ }
8
+ /**
9
+ * How many attempts at claiming the next number before giving up.
10
+ *
11
+ * The claim is a compare-and-set, so a loser retries with the value it just
12
+ * read. Under real contention two or three attempts is already unusual; ten is
13
+ * a number nobody reaches without something else being wrong, and failing
14
+ * loudly then is better than spinning.
15
+ */
16
+ const CLAIM_ATTEMPTS = 10;
17
+ /**
18
+ * Takes the next number in a series, atomically — shared by invoices
19
+ * (`invoice/store.ts`) and credit notes (`invoice/credit-note.ts`, fiche 52
20
+ * task 6), both series living in the same `cogenta_commerce_invoice_sequences`
21
+ * table, told apart only by their series string (an invoice's is the year,
22
+ * `2026`; a credit note's is `CN-2026` — see `credit-note.ts`).
23
+ *
24
+ * `update … set next_seq = next_seq + 1 where series = ? and next_seq = ?` —
25
+ * a compare-and-set whose `rowsAffected` decides the race, the same idiom
26
+ * that makes stock safe and a password reset token single use. Two documents
27
+ * issued in the same millisecond get consecutive numbers, never the same one.
28
+ *
29
+ * Emphatically not `count(*) + 1`: that hands out a duplicate under any
30
+ * concurrency at all, and re-issues a number that a deleted row used to
31
+ * hold. A number, once handed out, is spent.
32
+ */
33
+ export async function claimSequenceNumber(tx, dialect, series) {
34
+ const sequences = identifier(TABLES.invoiceSequences, dialect);
35
+ for (let attempt = 0; attempt < CLAIM_ATTEMPTS; attempt += 1) {
36
+ const current = await tx.query(sql `select next_seq from ${sequences} where series = ${series}`);
37
+ const row = current.rows[0];
38
+ if (row === undefined) {
39
+ // First document of the series. A duplicate primary key here means
40
+ // somebody else created it in between, so the loop reads it and
41
+ // competes for the increment like everyone else.
42
+ try {
43
+ await tx.query(sql `insert into ${sequences} (series, next_seq) values (${series}, ${2})`);
44
+ return 1;
45
+ }
46
+ catch {
47
+ continue;
48
+ }
49
+ }
50
+ const next = toInt(row.next_seq, 'invoice_sequence.next_seq');
51
+ const claimed = await tx.query(sql `
52
+ update ${sequences} set next_seq = ${next + 1}
53
+ where series = ${series} and next_seq = ${next}`);
54
+ if (claimed.rowsAffected > 0)
55
+ return next;
56
+ }
57
+ throw new CogentaError({
58
+ code: 'COMMERCE_INVOICE_SEQUENCE_CONFLICT',
59
+ message: `Could not take the next number in series "${series}".`,
60
+ hint: 'The sequence is under unusually heavy contention. Retry the issue.',
61
+ details: { series, attempts: CLAIM_ATTEMPTS },
62
+ });
63
+ }
64
+ //# sourceMappingURL=sequence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sequence.js","sourceRoot":"","sources":["../../src/invoice/sequence.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EAEZ,UAAU,EAEV,GAAG,GACJ,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAClC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAErC,wFAAwF;AACxF,MAAM,UAAU,oBAAoB,CAAC,MAAc,EAAE,GAAW;IAC9D,OAAO,GAAG,MAAM,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAA;AACpD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,cAAc,GAAG,EAAE,CAAA;AAEzB;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,EAAe,EACf,OAAwB,EACxB,MAAc;IAEd,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAA;IAE9D,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,cAAc,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC;QAC7D,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,KAAK,CAC5B,GAAG,CAAA,wBAAwB,SAAS,mBAAmB,MAAM,EAAE,CAChE,CAAA;QACD,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAE3B,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACtB,mEAAmE;YACnE,gEAAgE;YAChE,iDAAiD;YACjD,IAAI,CAAC;gBACH,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,CAAA,eAAe,SAAS,+BAA+B,MAAM,KAAK,CAAC,GAAG,CAAC,CAAA;gBACzF,OAAO,CAAC,CAAA;YACV,CAAC;YAAC,MAAM,CAAC;gBACP,SAAQ;YACV,CAAC;QACH,CAAC;QAED,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,2BAA2B,CAAC,CAAA;QAC7D,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,CAAA;eACvB,SAAS,mBAAmB,IAAI,GAAG,CAAC;uBAC5B,MAAM,mBAAmB,IAAI,EAAE,CAAC,CAAA;QACnD,IAAI,OAAO,CAAC,YAAY,GAAG,CAAC;YAAE,OAAO,IAAI,CAAA;IAC3C,CAAC;IAED,MAAM,IAAI,YAAY,CAAC;QACrB,IAAI,EAAE,oCAAoC;QAC1C,OAAO,EAAE,6CAA6C,MAAM,IAAI;QAChE,IAAI,EAAE,oEAAoE;QAC1E,OAAO,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE;KAC9C,CAAC,CAAA;AACJ,CAAC"}
@@ -81,8 +81,30 @@ export interface InvoiceStore {
81
81
  }): Promise<readonly Invoice[]>;
82
82
  /** The PDF for an invoice. Regenerated from the snapshot, byte-identical. */
83
83
  pdf(id: string): Promise<Uint8Array>;
84
+ /**
85
+ * A real invoice PDF for an order that has not been (and may never be)
86
+ * issued — fiche 54 task 2. Built from the exact same `documentFor`/
87
+ * `pdfDocumentFor`/`renderInvoicePdf` chain `issue()`+`pdf()` use, so a
88
+ * preview is never a second, drifting implementation of what an invoice
89
+ * looks like. What makes it a preview and not a side effect: no row is
90
+ * written, no order event is recorded, and above all no number is claimed
91
+ * from `claimNumber` — a real invoice number is gapless and never reused,
92
+ * so spending one on a screen a shop owner might reload ten times while
93
+ * tuning the template would corrupt the one thing this file exists to
94
+ * protect. `"PREVIEW"` in the number field is not a placeholder chosen for
95
+ * looks: it is what stops the output from ever being mistaken for a real,
96
+ * legally-numbered document.
97
+ */
98
+ preview(orderId: string): Promise<Uint8Array>;
84
99
  }
85
- /** `2026-000042`. Zero-padded so the numbers sort as strings too. */
100
+ /**
101
+ * `2026-000042`. Zero-padded so the numbers sort as strings too.
102
+ *
103
+ * A thin alias of `formatSequenceNumber` (`sequence.ts`), kept under its
104
+ * original name for source compatibility — this was this package's public
105
+ * export before the sequence-claiming logic moved out to be shared with
106
+ * credit notes (fiche 52 task 6).
107
+ */
86
108
  export declare function formatInvoiceNumber(series: string, seq: number): string;
87
109
  export declare function createInvoiceStore(db: DatabaseHandle, dependencies: InvoiceStoreDependencies, now?: () => number): InvoiceStore;
88
110
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/invoice/store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/invoice/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,cAAc,EAKpB,MAAM,eAAe,CAAA;AAEtB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAInD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAIlD;;;;;;;GAOG;AACH,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,4DAA4D;IAC5D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,oEAAoE;IACpE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,wEAAwE;IACxE,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAA;CACnC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;IAClC,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,KAAK,EAAE,SAAS;QACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;QACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;QACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;QACzB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;QAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;QAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;KAC5B,EAAE,CAAA;IACH,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAC/B;AAED,MAAM,WAAW,aAAa;IAC5B,yEAAyE;IACzE,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;IACnC,qEAAqE;IACrE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,uEAAuE;IACvE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACzC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACjC;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAA;IAC3B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAA;CAC/B;AAED,MAAM,WAAW,YAAY;IAC3B,2DAA2D;IAC3D,KAAK,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACjD,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAA;IACzC,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAA;IACrD,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAA;IACrD,IAAI,CAAC,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,SAAS,OAAO,EAAE,CAAC,CAAA;IAClG,6EAA6E;IAC7E,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;IACpC;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;CAC9C;AA4BD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAEvE;AAED,wBAAgB,kBAAkB,CAChC,EAAE,EAAE,cAAc,EAClB,YAAY,EAAE,wBAAwB,EACtC,GAAG,GAAE,MAAM,MAAiB,GAC3B,YAAY,CAwJd;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,eAAe,GAAG,kBAAkB,CA6B5E"}
@@ -3,6 +3,7 @@ import { formatMoney } from '../money.js';
3
3
  import { toInt, toText } from '../rows.js';
4
4
  import { TABLES } from '../tables.js';
5
5
  import { renderInvoicePdf } from './pdf.js';
6
+ import { claimSequenceNumber, formatSequenceNumber } from './sequence.js';
6
7
  function decode(row) {
7
8
  return {
8
9
  id: toText(row.id, 'invoice.id'),
@@ -16,66 +17,20 @@ function decode(row) {
16
17
  document: JSON.parse(toText(row.document, 'invoice.document')),
17
18
  };
18
19
  }
19
- /** `2026-000042`. Zero-padded so the numbers sort as strings too. */
20
- export function formatInvoiceNumber(series, seq) {
21
- return `${series}-${String(seq).padStart(6, '0')}`;
22
- }
23
20
  /**
24
- * How many attempts at claiming the next number before giving up.
21
+ * `2026-000042`. Zero-padded so the numbers sort as strings too.
25
22
  *
26
- * The claim is a compare-and-set, so a loser retries with the value it just
27
- * read. Under real contention two or three attempts is already unusual; ten is
28
- * a number nobody reaches without something else being wrong, and failing
29
- * loudly then is better than spinning.
23
+ * A thin alias of `formatSequenceNumber` (`sequence.ts`), kept under its
24
+ * original name for source compatibility this was this package's public
25
+ * export before the sequence-claiming logic moved out to be shared with
26
+ * credit notes (fiche 52 task 6).
30
27
  */
31
- const CLAIM_ATTEMPTS = 10;
28
+ export function formatInvoiceNumber(series, seq) {
29
+ return formatSequenceNumber(series, seq);
30
+ }
32
31
  export function createInvoiceStore(db, dependencies, now = Date.now) {
33
32
  const d = db.dialect;
34
33
  const invoices = identifier(TABLES.invoices, d);
35
- const sequences = identifier(TABLES.invoiceSequences, d);
36
- /**
37
- * Takes the next number in a series, atomically.
38
- *
39
- * `update … set next_seq = next_seq + 1 where series = ? and next_seq = ?`
40
- * — a compare-and-set whose `rowsAffected` decides the race, the same idiom
41
- * that makes stock safe and a password reset token single use. Two invoices
42
- * issued in the same millisecond get consecutive numbers, never the same
43
- * one.
44
- *
45
- * Emphatically not `count(*) + 1`: that hands out a duplicate under any
46
- * concurrency at all, and re-issues a number that a deleted row used to
47
- * hold. A number, once handed out, is spent.
48
- */
49
- async function claimNumber(tx, series) {
50
- for (let attempt = 0; attempt < CLAIM_ATTEMPTS; attempt += 1) {
51
- const current = await tx.query(sql `select next_seq from ${sequences} where series = ${series}`);
52
- const row = current.rows[0];
53
- if (row === undefined) {
54
- // First invoice of the series. A duplicate primary key here means
55
- // somebody else created it in between, so the loop reads it and
56
- // competes for the increment like everyone else.
57
- try {
58
- await tx.query(sql `insert into ${sequences} (series, next_seq) values (${series}, ${2})`);
59
- return 1;
60
- }
61
- catch {
62
- continue;
63
- }
64
- }
65
- const next = toInt(row.next_seq, 'invoice_sequence.next_seq');
66
- const claimed = await tx.query(sql `
67
- update ${sequences} set next_seq = ${next + 1}
68
- where series = ${series} and next_seq = ${next}`);
69
- if (claimed.rowsAffected > 0)
70
- return next;
71
- }
72
- throw new CogentaError({
73
- code: 'COMMERCE_INVOICE_SEQUENCE_CONFLICT',
74
- message: `Could not take the next number in invoice series "${series}".`,
75
- hint: 'The sequence is under unusually heavy contention. Retry the issue.',
76
- details: { series, attempts: CLAIM_ATTEMPTS },
77
- });
78
- }
79
34
  async function read(id, executor = db) {
80
35
  const result = await executor.query(sql `select * from ${invoices} where id = ${id}`);
81
36
  const row = result.rows[0];
@@ -132,8 +87,8 @@ export function createInvoiceStore(db, dependencies, now = Date.now) {
132
87
  // The number is taken inside the same transaction that writes the
133
88
  // invoice. If the write fails, the increment rolls back with it and
134
89
  // the number is not burned — which is what "gapless" requires.
135
- const seq = await claimNumber(tx, series);
136
- const number = formatInvoiceNumber(series, seq);
90
+ const seq = await claimSequenceNumber(tx, d, series);
91
+ const number = formatSequenceNumber(series, seq);
137
92
  const document = documentFor(order, number, issuedAt, input.buyerAddress ?? []);
138
93
  await tx.query(sql `
139
94
  insert into ${invoices} (id, order_id, series, seq, number, issued_at, currency, total_minor, document)
@@ -179,6 +134,18 @@ export function createInvoiceStore(db, dependencies, now = Date.now) {
179
134
  }
180
135
  return renderInvoicePdf(pdfDocumentFor(invoice.document));
181
136
  },
137
+ preview: async (orderId) => {
138
+ const order = await dependencies.orders.read(orderId);
139
+ if (order === null) {
140
+ throw new CogentaError({
141
+ code: 'COMMERCE_ORDER_NOT_FOUND',
142
+ message: 'This order does not exist.',
143
+ hint: 'Check the order reference.',
144
+ });
145
+ }
146
+ const document = documentFor(order, 'PREVIEW', new Date(now()).toISOString(), []);
147
+ return renderInvoicePdf(pdfDocumentFor(document));
148
+ },
182
149
  };
183
150
  }
184
151
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/invoice/store.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EAEZ,UAAU,EACV,KAAK,EAEL,GAAG,GACJ,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAGzC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAErC,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAkG3C,SAAS,MAAM,CAAC,GAAe;IAC7B,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,YAAY,CAAC;QAChC,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,kBAAkB,CAAC;QACjD,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC;QAC5C,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,aAAa,CAAC;QAClC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC;QAC5C,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,mBAAmB,CAAC;QACpD,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,kBAAkB,CAAC;QAClD,UAAU,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,qBAAqB,CAAC;QACzD,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAoB;KAClF,CAAA;AACH,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,mBAAmB,CAAC,MAAc,EAAE,GAAW;IAC7D,OAAO,GAAG,MAAM,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAA;AACpD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,cAAc,GAAG,EAAE,CAAA;AAEzB,MAAM,UAAU,kBAAkB,CAChC,EAAkB,EAClB,YAAsC,EACtC,GAAG,GAAiB,IAAI,CAAC,GAAG;IAE5B,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAA;IACpB,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA;IAC/C,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAA;IAExD;;;;;;;;;;;;OAYG;IACH,KAAK,UAAU,WAAW,CAAC,EAAe,EAAE,MAAc;QACxD,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,cAAc,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC;YAC7D,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,KAAK,CAC5B,GAAG,CAAA,wBAAwB,SAAS,mBAAmB,MAAM,EAAE,CAChE,CAAA;YACD,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YAE3B,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;gBACtB,kEAAkE;gBAClE,gEAAgE;gBAChE,iDAAiD;gBACjD,IAAI,CAAC;oBACH,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,CAAA,eAAe,SAAS,+BAA+B,MAAM,KAAK,CAAC,GAAG,CAAC,CAAA;oBACzF,OAAO,CAAC,CAAA;gBACV,CAAC;gBAAC,MAAM,CAAC;oBACP,SAAQ;gBACV,CAAC;YACH,CAAC;YAED,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,2BAA2B,CAAC,CAAA;YAC7D,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,CAAA;iBACvB,SAAS,mBAAmB,IAAI,GAAG,CAAC;yBAC5B,MAAM,mBAAmB,IAAI,EAAE,CAAC,CAAA;YACnD,IAAI,OAAO,CAAC,YAAY,GAAG,CAAC;gBAAE,OAAO,IAAI,CAAA;QAC3C,CAAC;QAED,MAAM,IAAI,YAAY,CAAC;YACrB,IAAI,EAAE,oCAAoC;YAC1C,OAAO,EAAE,qDAAqD,MAAM,IAAI;YACxE,IAAI,EAAE,oEAAoE;YAC1E,OAAO,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE;SAC9C,CAAC,CAAA;IACJ,CAAC;IAED,KAAK,UAAU,IAAI,CAAC,EAAU,EAAE,QAAQ,GAAgB,EAAE;QACxD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAa,GAAG,CAAA,iBAAiB,QAAQ,eAAe,EAAE,EAAE,CAAC,CAAA;QAChG,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAC1B,OAAO,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IAC/C,CAAC;IAED,SAAS,WAAW,CAAC,KAAY,EAAE,MAAc,EAAE,QAAgB,EAAE,KAAwB;QAC3F,MAAM,QAAQ,GAAoB;YAChC,MAAM;YACN,QAAQ;YACR,cAAc,EAAE,KAAK,CAAC,SAAS;YAC/B,MAAM,EAAE,YAAY,CAAC,MAAM,CAAC,OAAO;YACnC,KAAK,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC;YAC/C,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBAChC,GAAG,EAAE,IAAI,CAAC,GAAG;gBACb,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,cAAc,EAAE,IAAI,CAAC,cAAc;gBACnC,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,UAAU,EAAE,IAAI,CAAC,UAAU;aAC5B,CAAC,CAAC;YACH,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,MAAM,EAAE,YAAY,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI;SAC3C,CAAA;QACD,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,OAAO;QACL,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;YACrB,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;YAC3D,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACnB,MAAM,IAAI,YAAY,CAAC;oBACrB,IAAI,EAAE,0BAA0B;oBAChC,OAAO,EAAE,4BAA4B;oBACrC,IAAI,EAAE,4BAA4B;iBACnC,CAAC,CAAA;YACJ,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,KAAK,CAC7B,GAAG,CAAA,iBAAiB,QAAQ,qBAAqB,KAAK,CAAC,OAAO,EAAE,CACjE,CAAA;YACD,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;gBACnC,MAAM,IAAI,YAAY,CAAC;oBACrB,IAAI,EAAE,iCAAiC;oBACvC,OAAO,EAAE,uCAAuC;oBAChD,IAAI,EAAE,4EAA4E;oBAClF,OAAO,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE;iBACpC,CAAC,CAAA;YACJ,CAAC;YAED,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,WAAW,EAAE,CAAA;YAC9C,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;YACnD,MAAM,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAAA;YAErB,OAAO,EAAE,CAAC,WAAW,CACnB,KAAK,EAAE,EAAE,EAAE,EAAE;gBACX,kEAAkE;gBAClE,oEAAoE;gBACpE,+DAA+D;gBAC/D,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;gBACzC,MAAM,MAAM,GAAG,mBAAmB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;gBAC/C,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,YAAY,IAAI,EAAE,CAAC,CAAA;gBAE/E,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,CAAA;0BACF,QAAQ;sBACZ,EAAE,KAAK,KAAK,CAAC,EAAE,KAAK,MAAM,KAAK,GAAG,KAAK,MAAM,KAAK,QAAQ;sBAC1D,KAAK,CAAC,QAAQ,KAAK,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;gBAEhF,MAAM,YAAY,CAAC,MAAM,CAAC,MAAM,CAC9B,KAAK,CAAC,EAAE,EACR,UAAU,EACV,EAAE,IAAI,EAAE,WAAW,MAAM,UAAU,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,IAAI,EAAE,EACrE,EAAE,CACH,CAAA;gBAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;gBACjC,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;oBACpB,MAAM,IAAI,YAAY,CAAC;wBACrB,IAAI,EAAE,4BAA4B;wBAClC,OAAO,EAAE,6BAA6B;wBACtC,IAAI,EAAE,8DAA8D;qBACrE,CAAC,CAAA;gBACJ,CAAC;gBACD,OAAO,MAAM,CAAA;YACf,CAAC,EACD,EAAE,SAAS,EAAE,IAAI,EAAE,CACpB,CAAA;QACH,CAAC;QAED,IAAI;QAEJ,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YAC7B,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,KAAK,CAC3B,GAAG,CAAA,iBAAiB,QAAQ,qBAAqB,OAAO,EAAE,CAC3D,CAAA;YACD,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YAC1B,OAAO,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAC/C,CAAC;QAED,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YAC7B,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,KAAK,CAC3B,GAAG,CAAA,iBAAiB,QAAQ,mBAAmB,MAAM,EAAE,CACxD,CAAA;YACD,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YAC1B,OAAO,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAC/C,CAAC;QAED,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YACtB,MAAM,MAAM,GACV,OAAO,EAAE,MAAM,KAAK,SAAS;gBAC3B,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAa,GAAG,CAAA,iBAAiB,QAAQ,+BAA+B,CAAC;gBACzF,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CACZ,GAAG,CAAA,iBAAiB,QAAQ,mBAAmB,OAAO,CAAC,MAAM,mBAAmB,CACjF,CAAA;YACP,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QAChE,CAAC;QAED,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE;YAChB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,CAAA;YAC9B,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;gBACrB,MAAM,IAAI,YAAY,CAAC;oBACrB,IAAI,EAAE,4BAA4B;oBAClC,OAAO,EAAE,8BAA8B;oBACvC,IAAI,EAAE,2BAA2B;iBAClC,CAAC,CAAA;YACJ,CAAC;YACD,OAAO,gBAAgB,CAAC,cAAc,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAA;QAC3D,CAAC;KACF,CAAA;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,QAAyB;IACtD,MAAM,KAAK,GAAG,CAAC,WAAmB,EAAU,EAAE,CAC5C,WAAW,CAAC,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAA;IAE3D,MAAM,MAAM,GAAuB,CAAC,CAAC,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,CAAA;IAChF,IAAI,QAAQ,CAAC,aAAa,GAAG,CAAC;QAAE,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,IAAI,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAA;IAC9F,IAAI,QAAQ,CAAC,aAAa,GAAG,CAAC;QAAE,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,CAAA;IACxF,IAAI,QAAQ,CAAC,QAAQ,GAAG,CAAC;QAAE,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;IACzE,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;IAElD,OAAO;QACL,KAAK,EAAE,SAAS;QAChB,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;QACxC,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,OAAO,EAAE,CAAC,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC;QACxD,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACnC,KAAK,EAAE;gBACL,IAAI,CAAC,GAAG;gBACR,IAAI,CAAC,KAAK;gBACV,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;gBACrB,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC;gBAC1B,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC;aACvB;SACF,CAAC,CAAC;QACH,MAAM;QACN,GAAG,CAAC,QAAQ,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;KACjE,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/invoice/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { Order } from './types.js';
2
+ /**
3
+ * The accounting export (fiche 52 task 7). "Décisions à trancher — Format de
4
+ * l'export comptable — à figer et documenter avant l'implémentation" is
5
+ * resolved here: **one row per order**, RFC 4180 CSV, one column per figure
6
+ * an accountant reconciling a bank statement against this shop's orders
7
+ * needs — reference, date, buyer, currency, the four figures that sum to the
8
+ * total, the order's current status, and its invoice number when one was
9
+ * issued. A row-per-order-*line* export (the other reasonable choice) is
10
+ * deliberately not built: it would need a second, incompatible column set
11
+ * (per-line SKU/quantity) and this fiche's acceptance criteria only names
12
+ * "export comptable" in the singular, order-level sense the rest of this
13
+ * fiche (address, tracking, refunds) already works at. Zero dependency
14
+ * (R9) — a CSV writer for flat, known-shape rows is a handful of lines, not
15
+ * a library.
16
+ */
17
+ export interface OrderExportRow {
18
+ readonly order: Order;
19
+ /** The invoice number for this order, or null when none was issued. */
20
+ readonly invoiceNumber: string | null;
21
+ }
22
+ /** `\r\n` line endings, as RFC 4180 asks for — every spreadsheet reads it either way. */
23
+ export declare function ordersToCsv(rows: readonly OrderExportRow[]): string;
24
+ //# sourceMappingURL=csv.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csv.d.ts","sourceRoot":"","sources":["../../src/order/csv.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAEvC;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;IACrB,uEAAuE;IACvE,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;CACtC;AAwCD,yFAAyF;AACzF,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,cAAc,EAAE,GAAG,MAAM,CAGnE"}
@@ -0,0 +1,42 @@
1
+ const COLUMNS = [
2
+ 'reference',
3
+ 'placed_at',
4
+ 'status',
5
+ 'email',
6
+ 'currency',
7
+ 'subtotal_minor',
8
+ 'discount_minor',
9
+ 'shipping_minor',
10
+ 'tax_minor',
11
+ 'total_minor',
12
+ 'invoice_number',
13
+ ];
14
+ /** RFC 4180: a field containing a comma, a quote or a newline is quoted, with `"` doubled. */
15
+ function escapeCsvField(value) {
16
+ if (/[",\n\r]/u.test(value))
17
+ return `"${value.replace(/"/gu, '""')}"`;
18
+ return value;
19
+ }
20
+ function rowToCsvLine(row) {
21
+ const { order } = row;
22
+ const fields = [
23
+ order.reference,
24
+ order.placedAt,
25
+ order.status,
26
+ order.email,
27
+ order.currency,
28
+ String(order.subtotalMinor),
29
+ String(order.discountMinor),
30
+ String(order.shippingMinor),
31
+ String(order.taxMinor),
32
+ String(order.totalMinor),
33
+ row.invoiceNumber ?? '',
34
+ ];
35
+ return fields.map(escapeCsvField).join(',');
36
+ }
37
+ /** `\r\n` line endings, as RFC 4180 asks for — every spreadsheet reads it either way. */
38
+ export function ordersToCsv(rows) {
39
+ const lines = [COLUMNS.join(','), ...rows.map(rowToCsvLine)];
40
+ return `${lines.join('\r\n')}\r\n`;
41
+ }
42
+ //# sourceMappingURL=csv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csv.js","sourceRoot":"","sources":["../../src/order/csv.ts"],"names":[],"mappings":"AAuBA,MAAM,OAAO,GAAG;IACd,WAAW;IACX,WAAW;IACX,QAAQ;IACR,OAAO;IACP,UAAU;IACV,gBAAgB;IAChB,gBAAgB;IAChB,gBAAgB;IAChB,WAAW;IACX,aAAa;IACb,gBAAgB;CACR,CAAA;AAEV,8FAA8F;AAC9F,SAAS,cAAc,CAAC,KAAa;IACnC,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAA;IACrE,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAS,YAAY,CAAC,GAAmB;IACvC,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,CAAA;IACrB,MAAM,MAAM,GAAG;QACb,KAAK,CAAC,SAAS;QACf,KAAK,CAAC,QAAQ;QACd,KAAK,CAAC,MAAM;QACZ,KAAK,CAAC,KAAK;QACX,KAAK,CAAC,QAAQ;QACd,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC;QAC3B,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC;QAC3B,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC;QAC3B,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC;QACtB,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC;QACxB,GAAG,CAAC,aAAa,IAAI,EAAE;KACxB,CAAA;IACD,OAAO,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAC7C,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,WAAW,CAAC,IAA+B;IACzD,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAA;IAC5D,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAA;AACpC,CAAC"}