@aglyn/plugins-commerce 1.0.0-beta.230 → 1.0.0-beta.231
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +13 -13
- package/src/index.d.ts +0 -1
- package/src/index.js +0 -1
- package/src/index.js.map +1 -1
- package/src/lib/barcode/barcode-decode.d.ts +71 -0
- package/src/lib/barcode/barcode-decode.js +498 -0
- package/src/lib/barcode/barcode-decode.js.map +1 -0
- package/src/lib/barcode/barcode-encode.d.ts +44 -0
- package/src/lib/barcode/barcode-encode.js +138 -0
- package/src/lib/barcode/barcode-encode.js.map +1 -0
- package/src/lib/barcode/barcode-scanner.component.d.ts +23 -0
- package/src/lib/barcode/barcode-scanner.component.js +260 -0
- package/src/lib/barcode/barcode-scanner.component.js.map +1 -0
- package/src/lib/barcode/scan-button.component.d.ts +10 -0
- package/src/lib/barcode/scan-button.component.js +62 -0
- package/src/lib/barcode/scan-button.component.js.map +1 -0
- package/src/lib/barcode/scanner-wedge.d.ts +35 -0
- package/src/lib/barcode/scanner-wedge.js +108 -0
- package/src/lib/barcode/scanner-wedge.js.map +1 -0
- package/src/lib/components/account.js +10 -1
- package/src/lib/components/account.js.map +1 -1
- package/src/lib/components/cart-extras.d.ts +45 -0
- package/src/lib/components/cart-extras.js +127 -0
- package/src/lib/components/cart-extras.js.map +1 -0
- package/src/lib/components/cart.js +82 -15
- package/src/lib/components/cart.js.map +1 -1
- package/src/lib/components/checkout-return-notice.d.ts +26 -0
- package/src/lib/components/checkout-return-notice.js +48 -0
- package/src/lib/components/checkout-return-notice.js.map +1 -0
- package/src/lib/components/commerce-console-page.js +124 -0
- package/src/lib/components/commerce-console-page.js.map +1 -1
- package/src/lib/components/commerce-console-sections.d.ts +1 -1
- package/src/lib/components/commerce-console-sections.js +4 -0
- package/src/lib/components/commerce-console-sections.js.map +1 -1
- package/src/lib/components/console/bulk-fulfill.d.ts +44 -0
- package/src/lib/components/console/bulk-fulfill.js +84 -0
- package/src/lib/components/console/bulk-fulfill.js.map +1 -0
- package/src/lib/components/console/customer-notifications-card.component.d.ts +19 -0
- package/src/lib/components/console/customer-notifications-card.component.js +149 -0
- package/src/lib/components/console/customer-notifications-card.component.js.map +1 -0
- package/src/lib/components/console/host-orders-card.component.js +84 -5
- package/src/lib/components/console/host-orders-card.component.js.map +1 -1
- package/src/lib/components/console/locations-card.component.js +164 -57
- package/src/lib/components/console/locations-card.component.js.map +1 -1
- package/src/lib/components/console/order-detail-dialog.component.js +209 -61
- package/src/lib/components/console/order-detail-dialog.component.js.map +1 -1
- package/src/lib/components/console/order-fulfillment-panel.component.d.ts +48 -0
- package/src/lib/components/console/order-fulfillment-panel.component.js +542 -0
- package/src/lib/components/console/order-fulfillment-panel.component.js.map +1 -0
- package/src/lib/components/console/order-invoice.component.d.ts +33 -0
- package/src/lib/components/console/order-invoice.component.js +81 -0
- package/src/lib/components/console/order-invoice.component.js.map +1 -0
- package/src/lib/components/console/order-receipt-resend.component.d.ts +21 -0
- package/src/lib/components/console/order-receipt-resend.component.js +203 -0
- package/src/lib/components/console/order-receipt-resend.component.js.map +1 -0
- package/src/lib/components/console/order-returns.component.d.ts +36 -0
- package/src/lib/components/console/order-returns.component.js +142 -0
- package/src/lib/components/console/order-returns.component.js.map +1 -0
- package/src/lib/components/console/order-shipping-actions.component.d.ts +54 -0
- package/src/lib/components/console/order-shipping-actions.component.js +149 -0
- package/src/lib/components/console/order-shipping-actions.component.js.map +1 -0
- package/src/lib/components/console/order-webhooks-card.component.d.ts +50 -0
- package/src/lib/components/console/order-webhooks-card.component.js +623 -0
- package/src/lib/components/console/order-webhooks-card.component.js.map +1 -0
- package/src/lib/components/console/order-zones.d.ts +155 -0
- package/src/lib/components/console/order-zones.js +40 -0
- package/src/lib/components/console/order-zones.js.map +1 -0
- package/src/lib/components/console/payment-methods-card.component.d.ts +67 -0
- package/src/lib/components/console/payment-methods-card.component.js +395 -0
- package/src/lib/components/console/payment-methods-card.component.js.map +1 -0
- package/src/lib/components/console/pos/pos-api.d.ts +124 -0
- package/src/lib/components/console/pos/pos-api.js +101 -0
- package/src/lib/components/console/pos/pos-api.js.map +1 -0
- package/src/lib/components/console/pos/pos-cart-panel.component.d.ts +36 -0
- package/src/lib/components/console/pos/pos-cart-panel.component.js +160 -0
- package/src/lib/components/console/pos/pos-cart-panel.component.js.map +1 -0
- package/src/lib/components/console/pos/pos-item-dialog.component.d.ts +39 -0
- package/src/lib/components/console/pos/pos-item-dialog.component.js +352 -0
- package/src/lib/components/console/pos/pos-item-dialog.component.js.map +1 -0
- package/src/lib/components/console/pos/pos-product-grid.component.d.ts +47 -0
- package/src/lib/components/console/pos/pos-product-grid.component.js +272 -0
- package/src/lib/components/console/pos/pos-product-grid.component.js.map +1 -0
- package/src/lib/components/console/pos/pos-receipt-panel.component.d.ts +27 -0
- package/src/lib/components/console/pos/pos-receipt-panel.component.js +282 -0
- package/src/lib/components/console/pos/pos-receipt-panel.component.js.map +1 -0
- package/src/lib/components/console/pos/pos-tender-dialogs.component.d.ts +53 -0
- package/src/lib/components/console/pos/pos-tender-dialogs.component.js +445 -0
- package/src/lib/components/console/pos/pos-tender-dialogs.component.js.map +1 -0
- package/src/lib/components/console/pos/pos-tender-panel.component.d.ts +31 -0
- package/src/lib/components/console/pos/pos-tender-panel.component.js +640 -0
- package/src/lib/components/console/pos/pos-tender-panel.component.js.map +1 -0
- package/src/lib/components/console/pos/use-pos-display.d.ts +43 -0
- package/src/lib/components/console/pos/use-pos-display.js +161 -0
- package/src/lib/components/console/pos/use-pos-display.js.map +1 -0
- package/src/lib/components/console/pos-devices-card.component.d.ts +14 -0
- package/src/lib/components/console/pos-devices-card.component.js +546 -0
- package/src/lib/components/console/pos-devices-card.component.js.map +1 -0
- package/src/lib/components/console/pos-display/brand-screen.d.ts +33 -0
- package/src/lib/components/console/pos-display/brand-screen.js +85 -0
- package/src/lib/components/console/pos-display/brand-screen.js.map +1 -0
- package/src/lib/components/console/pos-display/cart-screen.d.ts +29 -0
- package/src/lib/components/console/pos-display/cart-screen.js +166 -0
- package/src/lib/components/console/pos-display/cart-screen.js.map +1 -0
- package/src/lib/components/console/pos-display/pairing-screen.d.ts +24 -0
- package/src/lib/components/console/pos-display/pairing-screen.js +127 -0
- package/src/lib/components/console/pos-display/pairing-screen.js.map +1 -0
- package/src/lib/components/console/pos-display/pos-display-api.d.ts +90 -0
- package/src/lib/components/console/pos-display/pos-display-api.js +140 -0
- package/src/lib/components/console/pos-display/pos-display-api.js.map +1 -0
- package/src/lib/components/console/pos-display/receipt-screen.d.ts +35 -0
- package/src/lib/components/console/pos-display/receipt-screen.js +200 -0
- package/src/lib/components/console/pos-display/receipt-screen.js.map +1 -0
- package/src/lib/components/console/pos-display/tip-screen.d.ts +36 -0
- package/src/lib/components/console/pos-display/tip-screen.js +211 -0
- package/src/lib/components/console/pos-display/tip-screen.js.map +1 -0
- package/src/lib/components/console/pos-display-page.component.d.ts +16 -0
- package/src/lib/components/console/pos-display-page.component.js +407 -0
- package/src/lib/components/console/pos-display-page.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-customer-lookup.component.d.ts +40 -0
- package/src/lib/components/console/pos-ops/pos-customer-lookup.component.js +289 -0
- package/src/lib/components/console/pos-ops/pos-customer-lookup.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-last-receipt.component.d.ts +34 -0
- package/src/lib/components/console/pos-ops/pos-last-receipt.component.js +61 -0
- package/src/lib/components/console/pos-ops/pos-last-receipt.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-operations-bar.component.d.ts +38 -0
- package/src/lib/components/console/pos-ops/pos-operations-bar.component.js +129 -0
- package/src/lib/components/console/pos-ops/pos-operations-bar.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-ops-api.d.ts +37 -0
- package/src/lib/components/console/pos-ops/pos-ops-api.js +60 -0
- package/src/lib/components/console/pos-ops/pos-ops-api.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-pin-pad.component.d.ts +48 -0
- package/src/lib/components/console/pos-ops/pos-pin-pad.component.js +220 -0
- package/src/lib/components/console/pos-ops/pos-pin-pad.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-receipt-actions.component.d.ts +63 -0
- package/src/lib/components/console/pos-ops/pos-receipt-actions.component.js +186 -0
- package/src/lib/components/console/pos-ops/pos-receipt-actions.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-receipt.d.ts +39 -0
- package/src/lib/components/console/pos-ops/pos-receipt.js +182 -0
- package/src/lib/components/console/pos-ops/pos-receipt.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-return-dialog.component.d.ts +40 -0
- package/src/lib/components/console/pos-ops/pos-return-dialog.component.js +465 -0
- package/src/lib/components/console/pos-ops/pos-return-dialog.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-shift-history-card.component.d.ts +29 -0
- package/src/lib/components/console/pos-ops/pos-shift-history-card.component.js +253 -0
- package/src/lib/components/console/pos-ops/pos-shift-history-card.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-shift-panel.component.d.ts +34 -0
- package/src/lib/components/console/pos-ops/pos-shift-panel.component.js +494 -0
- package/src/lib/components/console/pos-ops/pos-shift-panel.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-shift-report.component.d.ts +37 -0
- package/src/lib/components/console/pos-ops/pos-shift-report.component.js +102 -0
- package/src/lib/components/console/pos-ops/pos-shift-report.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-staff-pins-card.component.d.ts +30 -0
- package/src/lib/components/console/pos-ops/pos-staff-pins-card.component.js +277 -0
- package/src/lib/components/console/pos-ops/pos-staff-pins-card.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/register-ops.d.ts +28 -0
- package/src/lib/components/console/pos-ops/register-ops.js +28 -0
- package/src/lib/components/console/pos-ops/register-ops.js.map +1 -0
- package/src/lib/components/console/pos-ops/use-pos-cashier.d.ts +46 -0
- package/src/lib/components/console/pos-ops/use-pos-cashier.js +128 -0
- package/src/lib/components/console/pos-ops/use-pos-cashier.js.map +1 -0
- package/src/lib/components/console/pos-ops/use-pos-sale-receipt.d.ts +36 -0
- package/src/lib/components/console/pos-ops/use-pos-sale-receipt.js +64 -0
- package/src/lib/components/console/pos-ops/use-pos-sale-receipt.js.map +1 -0
- package/src/lib/components/console/pos-page.component.d.ts +13 -5
- package/src/lib/components/console/pos-page.component.js +729 -657
- package/src/lib/components/console/pos-page.component.js.map +1 -1
- package/src/lib/components/console/product-editor-dialog.component.js +51 -7
- package/src/lib/components/console/product-editor-dialog.component.js.map +1 -1
- package/src/lib/components/console/product-labels-dialog.component.d.ts +13 -0
- package/src/lib/components/console/product-labels-dialog.component.js +197 -0
- package/src/lib/components/console/product-labels-dialog.component.js.map +1 -0
- package/src/lib/components/console/product-register-fields.component.d.ts +19 -0
- package/src/lib/components/console/product-register-fields.component.js +241 -0
- package/src/lib/components/console/product-register-fields.component.js.map +1 -0
- package/src/lib/components/console/product-zones.d.ts +44 -0
- package/src/lib/components/console/product-zones.js.map +1 -1
- package/src/lib/components/console/products-hub-card.component.js +12 -0
- package/src/lib/components/console/products-hub-card.component.js.map +1 -1
- package/src/lib/components/console/register-hardware-card.component.d.ts +33 -0
- package/src/lib/components/console/register-hardware-card.component.js +826 -0
- package/src/lib/components/console/register-hardware-card.component.js.map +1 -0
- package/src/lib/components/console/registers-card.component.js +24 -5
- package/src/lib/components/console/registers-card.component.js.map +1 -1
- package/src/lib/components/console/return-actions.d.ts +38 -0
- package/src/lib/components/console/return-actions.js +76 -0
- package/src/lib/components/console/return-actions.js.map +1 -0
- package/src/lib/components/console/return-detail-dialog.component.d.ts +34 -0
- package/src/lib/components/console/return-detail-dialog.component.js +718 -0
- package/src/lib/components/console/return-detail-dialog.component.js.map +1 -0
- package/src/lib/components/console/return-settings-card.component.d.ts +34 -0
- package/src/lib/components/console/return-settings-card.component.js +195 -0
- package/src/lib/components/console/return-settings-card.component.js.map +1 -0
- package/src/lib/components/console/return-zones.d.ts +87 -0
- package/src/lib/components/console/return-zones.js +31 -0
- package/src/lib/components/console/return-zones.js.map +1 -0
- package/src/lib/components/console/returns-card.component.d.ts +45 -0
- package/src/lib/components/console/returns-card.component.js +159 -0
- package/src/lib/components/console/returns-card.component.js.map +1 -0
- package/src/lib/components/console/shipping-settings-card.component.js +161 -5
- package/src/lib/components/console/shipping-settings-card.component.js.map +1 -1
- package/src/lib/components/console/shippingeasy-card.component.d.ts +59 -0
- package/src/lib/components/console/shippingeasy-card.component.js +378 -0
- package/src/lib/components/console/shippingeasy-card.component.js.map +1 -0
- package/src/lib/components/console/shipstation-card.component.d.ts +35 -0
- package/src/lib/components/console/shipstation-card.component.js +345 -0
- package/src/lib/components/console/shipstation-card.component.js.map +1 -0
- package/src/lib/components/console/start-return-dialog.component.d.ts +40 -0
- package/src/lib/components/console/start-return-dialog.component.js +243 -0
- package/src/lib/components/console/start-return-dialog.component.js.map +1 -0
- package/src/lib/components/console/stock-movements-card.component.js +2 -1
- package/src/lib/components/console/stock-movements-card.component.js.map +1 -1
- package/src/lib/components/console/store-settings-card.component.js +2 -66
- package/src/lib/components/console/store-settings-card.component.js.map +1 -1
- package/src/lib/components/console/store-zones.d.ts +42 -0
- package/src/lib/components/console/store-zones.js +39 -0
- package/src/lib/components/console/store-zones.js.map +1 -0
- package/src/lib/components/order-status.d.ts +36 -0
- package/src/lib/components/order-status.js +502 -0
- package/src/lib/components/order-status.js.map +1 -0
- package/src/lib/components/product-detail.js +41 -2
- package/src/lib/components/product-detail.js.map +1 -1
- package/src/lib/components/return-request.d.ts +32 -0
- package/src/lib/components/return-request.js +576 -0
- package/src/lib/components/return-request.js.map +1 -0
- package/src/lib/components/storefront-payment-appearance.d.ts +32 -0
- package/src/lib/components/storefront-payment-appearance.js +114 -0
- package/src/lib/components/storefront-payment-appearance.js.map +1 -0
- package/src/lib/components/storefront-payment-element.d.ts +57 -1
- package/src/lib/components/storefront-payment-element.js +332 -33
- package/src/lib/components/storefront-payment-element.js.map +1 -1
- package/src/lib/constants/order-status.d.ts +22 -0
- package/src/lib/constants/order-status.js +22 -0
- package/src/lib/constants/order-status.js.map +1 -0
- package/src/lib/constants/return-request.d.ts +27 -0
- package/src/lib/constants/return-request.js +32 -0
- package/src/lib/constants/return-request.js.map +1 -0
- package/src/lib/constants/stock-movement-query.js +2 -1
- package/src/lib/constants/stock-movement-query.js.map +1 -1
- package/src/lib/declarations.console-server.js +9 -0
- package/src/lib/declarations.console-server.js.map +1 -1
- package/src/lib/declarations.server.d.ts +2 -1
- package/src/lib/declarations.server.js +47 -1
- package/src/lib/declarations.server.js.map +1 -1
- package/src/lib/model/buyer-notifications.d.ts +59 -0
- package/src/lib/model/buyer-notifications.js +97 -0
- package/src/lib/model/buyer-notifications.js.map +1 -0
- package/src/lib/model/commerce-orders.d.ts +127 -1
- package/src/lib/model/commerce-orders.js +24 -15
- package/src/lib/model/commerce-orders.js.map +1 -1
- package/src/lib/model/commerce-payment-methods.d.ts +146 -0
- package/src/lib/model/commerce-payment-methods.js +247 -0
- package/src/lib/model/commerce-payment-methods.js.map +1 -0
- package/src/lib/model/commerce-pos-ops.d.ts +437 -0
- package/src/lib/model/commerce-pos-ops.js +721 -0
- package/src/lib/model/commerce-pos-ops.js.map +1 -0
- package/src/lib/model/commerce-pos.d.ts +263 -0
- package/src/lib/model/commerce-pos.js +375 -0
- package/src/lib/model/commerce-pos.js.map +1 -0
- package/src/lib/model/commerce-printers.d.ts +211 -0
- package/src/lib/model/commerce-printers.js +181 -0
- package/src/lib/model/commerce-printers.js.map +1 -0
- package/src/lib/model/commerce-receipt.d.ts +97 -0
- package/src/lib/model/commerce-receipt.js +180 -0
- package/src/lib/model/commerce-receipt.js.map +1 -0
- package/src/lib/model/commerce-returns.d.ts +207 -0
- package/src/lib/model/commerce-returns.js +300 -0
- package/src/lib/model/commerce-returns.js.map +1 -0
- package/src/lib/model/commerce-shipping.d.ts +44 -1
- package/src/lib/model/commerce-shipping.js +53 -9
- package/src/lib/model/commerce-shipping.js.map +1 -1
- package/src/lib/model/commerce-tax-engine.d.ts +90 -0
- package/src/lib/model/commerce-tax-engine.js +129 -0
- package/src/lib/model/commerce-tax-engine.js.map +1 -0
- package/src/lib/model/commerce.d.ts +88 -2
- package/src/lib/model/commerce.js +89 -1
- package/src/lib/model/commerce.js.map +1 -1
- package/src/lib/model/index.d.ts +15 -0
- package/src/lib/model/index.js +15 -0
- package/src/lib/model/index.js.map +1 -1
- package/src/lib/model/order-events.d.ts +154 -0
- package/src/lib/model/order-events.js +153 -0
- package/src/lib/model/order-events.js.map +1 -0
- package/src/lib/model/order-fulfillment.d.ts +117 -0
- package/src/lib/model/order-fulfillment.js +217 -0
- package/src/lib/model/order-fulfillment.js.map +1 -0
- package/src/lib/model/order-history.d.ts +58 -0
- package/src/lib/model/order-history.js +22 -0
- package/src/lib/model/order-history.js.map +1 -0
- package/src/lib/model/order-list-fields.d.ts +9 -1
- package/src/lib/model/order-list-fields.js +7 -1
- package/src/lib/model/order-list-fields.js.map +1 -1
- package/src/lib/model/order-shipping-export.d.ts +91 -0
- package/src/lib/model/order-shipping-export.js +192 -0
- package/src/lib/model/order-shipping-export.js.map +1 -0
- package/src/lib/model/order-status-view.d.ts +103 -0
- package/src/lib/model/order-status-view.js +156 -0
- package/src/lib/model/order-status-view.js.map +1 -0
- package/src/lib/model/order-webhooks.d.ts +142 -0
- package/src/lib/model/order-webhooks.js +91 -0
- package/src/lib/model/order-webhooks.js.map +1 -0
- package/src/lib/model/product-channel.d.ts +56 -0
- package/src/lib/model/product-channel.js +86 -0
- package/src/lib/model/product-channel.js.map +1 -0
- package/src/lib/model/product-modifiers.d.ts +80 -0
- package/src/lib/model/product-modifiers.js +140 -0
- package/src/lib/model/product-modifiers.js.map +1 -0
- package/src/lib/model/shippingeasy.d.ts +94 -0
- package/src/lib/model/shippingeasy.js +267 -0
- package/src/lib/model/shippingeasy.js.map +1 -0
- package/src/lib/model/shipstation.d.ts +125 -0
- package/src/lib/model/shipstation.js +399 -0
- package/src/lib/model/shipstation.js.map +1 -0
- package/src/lib/model/smart-collection-reads.d.ts +32 -0
- package/src/lib/model/smart-collection-reads.js +63 -0
- package/src/lib/model/smart-collection-reads.js.map +1 -0
- package/src/lib/model/tracking-url.d.ts +74 -0
- package/src/lib/model/tracking-url.js +159 -0
- package/src/lib/model/tracking-url.js.map +1 -0
- package/src/lib/plugin-config.d.ts +13 -0
- package/src/lib/plugin-config.js +77 -5
- package/src/lib/plugin-config.js.map +1 -1
- package/src/lib/plugin.js +23 -0
- package/src/lib/plugin.js.map +1 -1
- package/src/lib/pos-ops-config.d.ts +39 -0
- package/src/lib/pos-ops-config.js +88 -0
- package/src/lib/pos-ops-config.js.map +1 -0
- package/src/lib/printing/print-document.d.ts +106 -0
- package/src/lib/printing/print-document.js +464 -0
- package/src/lib/printing/print-document.js.map +1 -0
- package/src/lib/printing/product-labels.d.ts +58 -0
- package/src/lib/printing/product-labels.js +116 -0
- package/src/lib/printing/product-labels.js.map +1 -0
- package/src/lib/printing/render-epson.d.ts +57 -0
- package/src/lib/printing/render-epson.js +135 -0
- package/src/lib/printing/render-epson.js.map +1 -0
- package/src/lib/printing/render-star.d.ts +45 -0
- package/src/lib/printing/render-star.js +100 -0
- package/src/lib/printing/render-star.js.map +1 -0
- package/src/lib/printing/render-text.d.ts +25 -0
- package/src/lib/printing/render-text.js +53 -0
- package/src/lib/printing/render-text.js.map +1 -0
- package/src/lib/server/api-v1/openapi.js +27 -4
- package/src/lib/server/api-v1/openapi.js.map +1 -1
- package/src/lib/server/api-v1/order-view.d.ts +67 -0
- package/src/lib/server/api-v1/order-view.js +120 -0
- package/src/lib/server/api-v1/order-view.js.map +1 -0
- package/src/lib/server/api-v1/orders-and-products.js +58 -65
- package/src/lib/server/api-v1/orders-and-products.js.map +1 -1
- package/src/lib/server/billing-webhook.js +135 -28
- package/src/lib/server/billing-webhook.js.map +1 -1
- package/src/lib/server/cancel-order.js +29 -0
- package/src/lib/server/cancel-order.js.map +1 -1
- package/src/lib/server/carrier-rates-availability.d.ts +26 -0
- package/src/lib/server/carrier-rates-availability.js +76 -0
- package/src/lib/server/carrier-rates-availability.js.map +1 -0
- package/src/lib/server/carrier-shipping.d.ts +84 -0
- package/src/lib/server/carrier-shipping.js +135 -0
- package/src/lib/server/carrier-shipping.js.map +1 -0
- package/src/lib/server/cart-checkout.d.ts +2 -0
- package/src/lib/server/cart-checkout.js +226 -22
- package/src/lib/server/cart-checkout.js.map +1 -1
- package/src/lib/server/checkout-extras.d.ts +64 -0
- package/src/lib/server/checkout-extras.js +157 -0
- package/src/lib/server/checkout-extras.js.map +1 -0
- package/src/lib/server/{feed.d.ts → checkout-status.d.ts} +2 -7
- package/src/lib/server/checkout-status.js +111 -0
- package/src/lib/server/checkout-status.js.map +1 -0
- package/src/lib/server/checkout.js +86 -9
- package/src/lib/server/checkout.js.map +1 -1
- package/src/lib/server/draft-order.js +34 -5
- package/src/lib/server/draft-order.js.map +1 -1
- package/src/lib/server/fulfill-order.d.ts +127 -10
- package/src/lib/server/fulfill-order.js +451 -49
- package/src/lib/server/fulfill-order.js.map +1 -1
- package/src/lib/server/legacy-feed.d.ts +28 -0
- package/src/lib/server/legacy-feed.js +52 -0
- package/src/lib/server/legacy-feed.js.map +1 -0
- package/src/lib/server/native-checkout.d.ts +34 -15
- package/src/lib/server/native-checkout.js +32 -17
- package/src/lib/server/native-checkout.js.map +1 -1
- package/src/lib/server/order-event-host-emit.d.ts +23 -0
- package/src/lib/server/order-event-host-emit.js +30 -0
- package/src/lib/server/order-event-host-emit.js.map +1 -0
- package/src/lib/server/order-event-triggers.d.ts +37 -0
- package/src/lib/server/order-event-triggers.js +119 -0
- package/src/lib/server/order-event-triggers.js.map +1 -0
- package/src/lib/server/order-events.d.ts +62 -0
- package/src/lib/server/order-events.js +109 -0
- package/src/lib/server/order-events.js.map +1 -0
- package/src/lib/server/order-history.d.ts +23 -0
- package/src/lib/server/order-history.js +65 -0
- package/src/lib/server/order-history.js.map +1 -0
- package/src/lib/server/order-notifications.d.ts +185 -0
- package/src/lib/server/order-notifications.js +567 -0
- package/src/lib/server/order-notifications.js.map +1 -0
- package/src/lib/server/order-receipt-send.d.ts +39 -0
- package/src/lib/server/order-receipt-send.js +151 -0
- package/src/lib/server/order-receipt-send.js.map +1 -0
- package/src/lib/server/order-status-token.d.ts +31 -0
- package/src/lib/server/order-status-token.js +75 -0
- package/src/lib/server/order-status-token.js.map +1 -0
- package/src/lib/server/order-status.d.ts +58 -0
- package/src/lib/server/order-status.js +141 -0
- package/src/lib/server/order-status.js.map +1 -0
- package/src/lib/server/order-webhooks.d.ts +108 -0
- package/src/lib/server/order-webhooks.js +622 -0
- package/src/lib/server/order-webhooks.js.map +1 -0
- package/src/lib/server/orders-shipping-prepare.d.ts +26 -0
- package/src/lib/server/orders-shipping-prepare.js +121 -0
- package/src/lib/server/orders-shipping-prepare.js.map +1 -0
- package/src/lib/server/payment-method-domains.d.ts +209 -0
- package/src/lib/server/payment-method-domains.js +444 -0
- package/src/lib/server/payment-method-domains.js.map +1 -0
- package/src/lib/server/payment-methods.d.ts +77 -0
- package/src/lib/server/payment-methods.js +284 -0
- package/src/lib/server/payment-methods.js.map +1 -0
- package/src/lib/server/pos-auth.d.ts +50 -0
- package/src/lib/server/pos-auth.js +121 -0
- package/src/lib/server/pos-auth.js.map +1 -0
- package/src/lib/server/pos-customer.d.ts +49 -0
- package/src/lib/server/pos-customer.js +257 -0
- package/src/lib/server/pos-customer.js.map +1 -0
- package/src/lib/server/pos-display.d.ts +57 -0
- package/src/lib/server/pos-display.js +419 -0
- package/src/lib/server/pos-display.js.map +1 -0
- package/src/lib/server/pos-fee-month.d.ts +34 -0
- package/src/lib/server/pos-fee-month.js +36 -0
- package/src/lib/server/pos-fee-month.js.map +1 -0
- package/src/lib/server/pos-ops-gate.d.ts +161 -0
- package/src/lib/server/pos-ops-gate.js +295 -0
- package/src/lib/server/pos-ops-gate.js.map +1 -0
- package/src/lib/server/pos-ops-routes.d.ts +22 -0
- package/src/lib/server/pos-ops-routes.js +36 -0
- package/src/lib/server/pos-ops-routes.js.map +1 -0
- package/src/lib/server/pos-order.d.ts +1 -18
- package/src/lib/server/pos-order.js +222 -42
- package/src/lib/server/pos-order.js.map +1 -1
- package/src/lib/server/pos-payment.d.ts +39 -0
- package/src/lib/server/pos-payment.js +922 -0
- package/src/lib/server/pos-payment.js.map +1 -0
- package/src/lib/server/pos-print.d.ts +82 -0
- package/src/lib/server/pos-print.js +193 -0
- package/src/lib/server/pos-print.js.map +1 -0
- package/src/lib/server/pos-readers.d.ts +27 -0
- package/src/lib/server/pos-readers.js +276 -0
- package/src/lib/server/pos-readers.js.map +1 -0
- package/src/lib/server/pos-refund-authority.d.ts +60 -0
- package/src/lib/server/pos-refund-authority.js +72 -0
- package/src/lib/server/pos-refund-authority.js.map +1 -0
- package/src/lib/server/pos-return.d.ts +58 -0
- package/src/lib/server/pos-return.js +891 -0
- package/src/lib/server/pos-return.js.map +1 -0
- package/src/lib/server/pos-sale-stamp.d.ts +66 -0
- package/src/lib/server/pos-sale-stamp.js +84 -0
- package/src/lib/server/pos-sale-stamp.js.map +1 -0
- package/src/lib/server/pos-sale.d.ts +170 -0
- package/src/lib/server/pos-sale.js +461 -0
- package/src/lib/server/pos-sale.js.map +1 -0
- package/src/lib/server/pos-shift.d.ts +45 -0
- package/src/lib/server/pos-shift.js +484 -0
- package/src/lib/server/pos-shift.js.map +1 -0
- package/src/lib/server/pos-staff-pin.d.ts +26 -0
- package/src/lib/server/pos-staff-pin.js +339 -0
- package/src/lib/server/pos-staff-pin.js.map +1 -0
- package/src/lib/server/pos-stripe.d.ts +91 -0
- package/src/lib/server/pos-stripe.js +129 -0
- package/src/lib/server/pos-stripe.js.map +1 -0
- package/src/lib/server/pos-terminal-connection-token.d.ts +48 -0
- package/src/lib/server/pos-terminal-connection-token.js +166 -0
- package/src/lib/server/pos-terminal-connection-token.js.map +1 -0
- package/src/lib/server/pos-terminal.d.ts +218 -0
- package/src/lib/server/pos-terminal.js +1014 -0
- package/src/lib/server/pos-terminal.js.map +1 -0
- package/src/lib/server/print-queue.d.ts +124 -0
- package/src/lib/server/print-queue.js +301 -0
- package/src/lib/server/print-queue.js.map +1 -0
- package/src/lib/server/printer-poll.d.ts +75 -0
- package/src/lib/server/printer-poll.js +325 -0
- package/src/lib/server/printer-poll.js.map +1 -0
- package/src/lib/server/printer-secret.d.ts +39 -0
- package/src/lib/server/printer-secret.js +56 -0
- package/src/lib/server/printer-secret.js.map +1 -0
- package/src/lib/server/printers.d.ts +114 -0
- package/src/lib/server/printers.js +546 -0
- package/src/lib/server/printers.js.map +1 -0
- package/src/lib/server/product-catalog.d.ts +42 -0
- package/src/lib/server/product-catalog.js +305 -0
- package/src/lib/server/product-catalog.js.map +1 -0
- package/src/lib/server/refund.js +110 -45
- package/src/lib/server/refund.js.map +1 -1
- package/src/lib/server/reserve.js +2 -0
- package/src/lib/server/reserve.js.map +1 -1
- package/src/lib/server/return-status-action.d.ts +37 -0
- package/src/lib/server/return-status-action.js +57 -0
- package/src/lib/server/return-status-action.js.map +1 -0
- package/src/lib/server/returns.d.ts +119 -0
- package/src/lib/server/returns.js +938 -0
- package/src/lib/server/returns.js.map +1 -0
- package/src/lib/server/shipment-records.d.ts +36 -0
- package/src/lib/server/shipment-records.js +289 -0
- package/src/lib/server/shipment-records.js.map +1 -0
- package/src/lib/server/shipping-connector-gates.d.ts +40 -0
- package/src/lib/server/shipping-connector-gates.js +97 -0
- package/src/lib/server/shipping-connector-gates.js.map +1 -0
- package/src/lib/server/shipping-connectors.d.ts +29 -0
- package/src/lib/server/shipping-connectors.js +236 -0
- package/src/lib/server/shipping-connectors.js.map +1 -0
- package/src/lib/server/shippingeasy.d.ts +238 -0
- package/src/lib/server/shippingeasy.js +787 -0
- package/src/lib/server/shippingeasy.js.map +1 -0
- package/src/lib/server/shipstation.d.ts +129 -0
- package/src/lib/server/shipstation.js +483 -0
- package/src/lib/server/shipstation.js.map +1 -0
- package/src/lib/server/site-page-resolver.d.ts +5 -0
- package/src/lib/server/site-page-resolver.js +156 -1
- package/src/lib/server/site-page-resolver.js.map +1 -1
- package/src/lib/server/stock-levels.d.ts +21 -0
- package/src/lib/server/stock-levels.js +263 -0
- package/src/lib/server/stock-levels.js.map +1 -0
- package/src/lib/server/stripe-refund.d.ts +47 -0
- package/src/lib/server/stripe-refund.js +87 -0
- package/src/lib/server/stripe-refund.js.map +1 -0
- package/src/lib/server/supplier-update.js +46 -5
- package/src/lib/server/supplier-update.js.map +1 -1
- package/src/lib/server/tax-engine-quote.d.ts +47 -0
- package/src/lib/server/tax-engine-quote.js +105 -0
- package/src/lib/server/tax-engine-quote.js.map +1 -0
- package/src/lib/server.js +138 -2
- package/src/lib/server.js.map +1 -1
- package/src/lib/site.js +12 -0
- package/src/lib/site.js.map +1 -1
- package/src/lib/subprocessors.d.ts +26 -0
- package/src/lib/subprocessors.js +50 -0
- package/src/lib/subprocessors.js.map +1 -0
- package/src/lib/tenant-emails.js +461 -3
- package/src/lib/tenant-emails.js.map +1 -1
- package/src/lib/testing/fake-firestore.d.ts +45 -0
- package/src/lib/testing/fake-firestore.js +189 -0
- package/src/lib/testing/fake-firestore.js.map +1 -0
- package/src/lib/testing/memory-firestore.d.ts +123 -0
- package/src/lib/testing/memory-firestore.js +274 -0
- package/src/lib/testing/memory-firestore.js.map +1 -0
- package/src/lib/testing/pos-ops-harness.d.ts +50 -0
- package/src/lib/testing/pos-ops-harness.js +184 -0
- package/src/lib/testing/pos-ops-harness.js.map +1 -0
- package/src/lib/testing/pos-ops-memory-firestore.d.ts +55 -0
- package/src/lib/testing/pos-ops-memory-firestore.js +376 -0
- package/src/lib/testing/pos-ops-memory-firestore.js.map +1 -0
- package/src/lib/transfer/records-transfer.d.ts +11 -1
- package/src/lib/transfer/records-transfer.js +127 -5
- package/src/lib/transfer/records-transfer.js.map +1 -1
- package/src/lib/transfer/records.server.d.ts +9 -2
- package/src/lib/transfer/records.server.js +58 -7
- package/src/lib/transfer/records.server.js.map +1 -1
- package/src/lib/transfer/register-transfer-resources.js +40 -1
- package/src/lib/transfer/register-transfer-resources.js.map +1 -1
- package/src/lib/transfer/register-transfer-ui.js +4 -1
- package/src/lib/transfer/register-transfer-ui.js.map +1 -1
- package/src/lib/transfer/shipping-presets.d.ts +23 -0
- package/src/lib/transfer/shipping-presets.js +156 -0
- package/src/lib/transfer/shipping-presets.js.map +1 -0
- package/src/lib/transfer/tracking-transfer.d.ts +101 -0
- package/src/lib/transfer/tracking-transfer.js +546 -0
- package/src/lib/transfer/tracking-transfer.js.map +1 -0
- package/src/lib/transfer/tracking.server.d.ts +37 -0
- package/src/lib/transfer/tracking.server.js +393 -0
- package/src/lib/transfer/tracking.server.js.map +1 -0
- package/src/lib/transfer/transfer-keys.d.ts +2 -1
- package/src/lib/transfer/transfer-keys.js +6 -2
- package/src/lib/transfer/transfer-keys.js.map +1 -1
- package/src/lib/utils/code128.d.ts +37 -0
- package/src/lib/utils/code128.js +199 -0
- package/src/lib/utils/code128.js.map +1 -0
- package/src/lib/utils/order-invoice.d.ts +55 -0
- package/src/lib/utils/order-invoice.js +127 -0
- package/src/lib/utils/order-invoice.js.map +1 -0
- package/src/lib/utils/use-checkout-return-notice.d.ts +34 -0
- package/src/lib/utils/use-checkout-return-notice.js +78 -0
- package/src/lib/utils/use-checkout-return-notice.js.map +1 -0
- package/src/lib/server/feed.js +0 -69
- package/src/lib/server/feed.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/transfer/records-transfer.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n buildTransferPlan,\n isBlankTransferValue,\n TRANSFER_FILE_SAMPLE_ROW,\n TRANSFER_SYSTEM_GROUP,\n type BuildTransferPlanInput,\n type MatchKeySpec,\n type PlannedTransferRow,\n type TransferField,\n type TransferFieldChange,\n type TransferPlan,\n type TransferPlanSummary,\n type TransferWarningSample,\n} from '@aglyn/aglyn/data-transfer'\nimport type { PicklistSpec } from '@aglyn/aglyn/app-utils/picklists'\nimport { commerceSlug } from '../model/commerce'\nimport type { DiscountKind, HostDiscount } from '../model/commerce-discounts'\nimport { GIFT_CARD_CONFIRM_STEP_ID } from './transfer-keys'\nimport {\n GIFT_CARD_CURRENCY,\n giftCardAmountProblem,\n giftCardCodeOf,\n giftCardCodeProblem,\n type HostGiftCard,\n} from '../model/commerce-gift-cards'\nimport {\n ORDER_CHANNEL_LABELS,\n ORDER_STATUS_LABELS,\n liftLegacyOrder,\n type HostOrder,\n type OrderAddress,\n} from '../model/commerce-orders'\n\n/*\n * ORDERS, DISCOUNTS, COUPONS, GIFT CARDS AND CATEGORIES AS FILES (AGL-3531):\n * each resource's fields, and its stored document as the record a file\n * names. Pure — the server half is `records.server.ts`.\n *\n * ## What imports, and why the rest does not\n *\n * - Categories, discounts and coupons import: each is a document a person\n * writes from the console with nothing derived behind it, so a file\n * writes the same fields the console's card does. A discount or coupon\n * created from a file starts SWITCHED OFF unless the file says Active —\n * a promotion going live from a spreadsheet is money leaving the store.\n * How many times one was used is history, exported and never written.\n * - Orders are exported only: an order is the record of a sale, written by\n * checkout, the register or a paid draft.\n * - Gift cards import by ISSUING each card (AGL-3551, below), never by\n * writing a balance: a balance is money a shopper can spend. A gift\n * card's ID is its code, so the file is worth what the cards are.\n */\n\nconst iso = (ms: unknown): string | null => {\n const time =\n typeof ms === 'number'\n ? ms\n : ms && typeof (ms as { toMillis?: () => number }).toMillis === 'function'\n ? (ms as { toMillis: () => number }).toMillis()\n : ms && typeof (ms as { toDate?: () => Date }).toDate === 'function'\n ? ((ms as { toDate: () => Date }).toDate()?.getTime() ?? NaN)\n : NaN\n return Number.isFinite(time) ? new Date(time).toISOString() : null\n}\n\nconst dollars = (cents: unknown): number | null => {\n const value = Number(cents)\n return cents === null || cents === undefined || !Number.isFinite(value) ? null : Math.round(value) / 100\n}\n\nconst text = (value: unknown): string => (value === null || value === undefined ? '' : String(value).trim())\n\n/** A planned row's changes, by field id. */\nexport function rowChanges(row: PlannedTransferRow): Record<string, unknown> {\n return Object.fromEntries(row.diff.map((change) => [change.fieldId, change.after]))\n}\n\n/**\n * The core's plan with the fields a NEW record cannot be made without\n * marked required — never in the catalog, where a required field must be\n * mapped, and a file that only switches discounts off would be refused.\n */\nexport function planWithCreateRequired(input: BuildTransferPlanInput, required: readonly string[]): TransferPlan {\n return buildTransferPlan({\n ...input,\n fields: input.fields.map((field) => (required.includes(field.id) ? { ...field, required: true } : field)),\n })\n}\n\n/*==========================================\n * ORDERS\n *=========================================*/\n\nexport const ORDER_TRANSFER_FIELDS: readonly TransferField[] = [\n { id: 'number', label: 'Order number', group: 'order', type: 'integer', readOnly: true },\n { id: 'date', label: 'Date', group: 'order', type: 'datetime', readOnly: true },\n { id: 'status', label: 'Status', group: 'order', type: 'text', readOnly: true },\n { id: 'channel', label: 'Channel', group: 'order', type: 'text', readOnly: true },\n { id: 'customerEmail', label: 'Customer email', group: 'customer', type: 'email', readOnly: true },\n { id: 'customerName', label: 'Customer name', group: 'customer', type: 'text', readOnly: true },\n {\n id: 'product',\n label: 'Product',\n group: 'items',\n type: 'text',\n readOnly: true,\n description: 'The first line’s product, and how many more the order holds.',\n },\n { id: 'items', label: 'Items', group: 'items', type: 'longText', readOnly: true, description: 'Every line: quantity × name (variant), SKU.' },\n { id: 'itemCount', label: 'Units', group: 'items', type: 'integer', readOnly: true },\n { id: 'subtotal', label: 'Items subtotal', group: 'money', type: 'number', readOnly: true },\n { id: 'shipping', label: 'Shipping', group: 'money', type: 'number', readOnly: true },\n { id: 'tax', label: 'Tax', group: 'money', type: 'number', readOnly: true },\n { id: 'discount', label: 'Discount', group: 'money', type: 'number', readOnly: true },\n { id: 'total', label: 'Total', group: 'money', type: 'number', readOnly: true, description: 'What was charged, in dollars.' },\n { id: 'fee', label: 'Fee', group: 'money', type: 'number', readOnly: true },\n { id: 'refunded', label: 'Refunded', group: 'money', type: 'number', readOnly: true },\n { id: 'net', label: 'Net', group: 'money', type: 'number', readOnly: true, description: 'The total less what was refunded.' },\n { id: 'coupon', label: 'Coupon', group: 'money', type: 'text', readOnly: true },\n { id: 'shippingAddress', label: 'Shipping address', group: 'customer', type: 'text', readOnly: true },\n { id: 'billingAddress', label: 'Billing address', group: 'customer', type: 'text', readOnly: true },\n { id: 'note', label: 'Note', group: 'order', type: 'longText', readOnly: true },\n { id: 'dispute', label: 'Dispute', group: 'order', type: 'text', readOnly: true },\n { id: 'paymentIntentId', label: 'Payment ID', group: TRANSFER_SYSTEM_GROUP.id, type: 'text', system: true },\n]\n\nexport const ORDER_TRANSFER_GROUPS = [\n { id: 'order', label: 'Order' },\n { id: 'customer', label: 'Customer' },\n { id: 'items', label: 'Items' },\n { id: 'money', label: 'Money' },\n]\n\n/** An order as a stored document, with the id the export reads it under. */\nexport type StoredOrder = Partial<HostOrder> & {\n createdAt?: unknown\n createdAtMs?: number\n amountCents?: number\n feeCents?: number\n productId?: string\n}\n\nconst addressLine = (address: OrderAddress | undefined): string | null => {\n if (!address) return null\n const parts = [address.name, address.line1, address.line2, address.city, address.state, address.postalCode, address.country]\n .map(text)\n .filter(Boolean)\n return parts.length ? parts.join(', ') : null\n}\n\n/**\n * One order as a file names it. The money is what was ACTUALLY charged:\n * the order's `totals`, and the legacy flat fields only where a buy-now order\n * of old carries nothing else (AGL-1747) — a POS or draft order has no flat\n * field, and reading those first exported every one of them at $0.00. A\n * legacy row is named from `productNames`, never as \"Product\".\n */\nexport function orderRecord(\n id: string,\n stored: StoredOrder,\n productNames: Readonly<Record<string, string>> = {},\n): Record<string, unknown> {\n const lifted = liftLegacyOrder(stored)\n const lineItems = stored.lineItems ?? []\n const first = lineItems[0]?.name ?? productNames[stored.productId ?? ''] ?? stored.productId ?? ''\n const totals = lifted.totals\n const totalCents = Number(totals?.totalCents ?? stored.amountCents ?? 0)\n const refundedCents = Number(stored.refundedCents ?? 0)\n return {\n id,\n number: typeof stored.number === 'number' ? stored.number : null,\n date: iso(stored.createdAt) ?? iso(stored.createdAtMs),\n status: ORDER_STATUS_LABELS[lifted.status] ?? lifted.status,\n channel: ORDER_CHANNEL_LABELS[lifted.channel ?? 'online'] ?? lifted.channel ?? 'online',\n customerEmail: stored.customerEmail ?? null,\n customerName: stored.customerName ?? null,\n product: lineItems.length > 1 ? `${first} +${lineItems.length - 1} more` : first || null,\n items: lineItems.length\n ? lineItems\n .map(\n (line) =>\n `${line.quantity} × ${line.name}${line.variantLabel ? ` (${line.variantLabel})` : ''}${line.sku ? `, ${line.sku}` : ''}`,\n )\n .join('; ')\n : null,\n itemCount: lineItems.reduce((sum, line) => sum + (Number(line.quantity) || 0), 0),\n subtotal: dollars(totals?.itemsCents),\n shipping: dollars(totals?.shippingCents),\n tax: dollars(totals?.taxCents),\n discount: dollars(totals?.discountCents),\n total: dollars(totalCents),\n fee: dollars(totals?.feeCents ?? stored.feeCents ?? 0),\n refunded: dollars(refundedCents),\n net: dollars(totalCents - refundedCents),\n coupon: stored.couponCode ?? null,\n shippingAddress: addressLine(stored.shippingAddress),\n billingAddress: addressLine(stored.billingAddress),\n note: stored.note ?? null,\n dispute: stored.dispute ? text((stored.dispute as { status?: string }).status) || 'open' : null,\n paymentIntentId: stored.paymentIntentId ?? null,\n }\n}\n\n/*==========================================\n * DISCOUNTS\n *=========================================*/\n\nexport const DISCOUNT_KIND_PICKLIST = 'commerce.discountKind'\n\nconst DISCOUNT_KIND_LABELS: Record<DiscountKind, string> = {\n percent: 'Percent off',\n fixed: 'Amount off',\n free_shipping: 'Free shipping',\n}\n\nexport const DISCOUNT_KIND_SPEC: PicklistSpec = {\n restricted: true,\n standardValues: Object.entries(DISCOUNT_KIND_LABELS).map(([id, label]) => ({ id, label })),\n defaultValueId: 'percent',\n}\n\n/** A discount kind's id from a label or id in any case, or `null`. */\nexport function discountKindOf(value: unknown): DiscountKind | null {\n const key = text(value).toLowerCase()\n const found = Object.entries(DISCOUNT_KIND_LABELS).find(\n ([id, label]) => id === key || label.toLowerCase() === key,\n )\n return found ? (found[0] as DiscountKind) : null\n}\n\nexport const DISCOUNT_TRANSFER_FIELDS: readonly TransferField[] = [\n {\n id: 'code',\n label: 'Code',\n group: 'discount',\n type: 'text',\n aliases: ['discount code', 'promo code', 'coupon code'],\n description: 'What a shopper types; blank for a discount that applies on its own.',\n },\n { id: 'name', label: 'Name', group: 'discount', type: 'text', aliases: ['title', 'discount name'] },\n {\n id: 'kind',\n label: 'Kind',\n group: 'discount',\n type: 'picklist',\n picklistId: DISCOUNT_KIND_PICKLIST,\n aliases: ['type', 'discount type', 'value type'],\n description: 'Percent off, Amount off or Free shipping. Needed for a new discount.',\n },\n { id: 'percentOff', label: 'Percent off', group: 'discount', type: 'integer', aliases: ['percent', 'percentage'] },\n { id: 'amountOff', label: 'Amount off', group: 'discount', type: 'currency', aliases: ['amount', 'value'] },\n {\n id: 'minimumSubtotal',\n label: 'Minimum subtotal',\n group: 'conditions',\n type: 'currency',\n aliases: ['minimum', 'minimum purchase', 'minimum subtotal'],\n },\n {\n id: 'productIds',\n label: 'Product IDs',\n group: 'conditions',\n type: 'text',\n description: 'The products it covers, by their IDs separated by commas; blank covers the whole store.',\n },\n { id: 'maxRedemptions', label: 'Use limit', group: 'conditions', type: 'integer', aliases: ['usage limit', 'max uses'] },\n { id: 'startsAt', label: 'Starts', group: 'conditions', type: 'datetime', aliases: ['start date', 'starts at'] },\n { id: 'endsAt', label: 'Ends', group: 'conditions', type: 'datetime', aliases: ['end date', 'ends at', 'expires'] },\n {\n id: 'active',\n label: 'Active',\n group: 'discount',\n type: 'boolean',\n aliases: ['enabled', 'status'],\n description: 'A new discount starts switched off unless the file says it is active.',\n },\n { id: 'redemptions', label: 'Times used', group: 'conditions', type: 'integer', readOnly: true },\n]\n\nexport const DISCOUNT_MATCH_KEYS: readonly MatchKeySpec[] = [\n { fieldId: 'code', normalizer: 'caseless' },\n { fieldId: 'name', normalizer: 'name' },\n { fieldId: 'id', normalizer: 'aglynId' },\n]\n\n/** A code as the discounts card stores it: upper case, letters, digits, `_` and `-`. */\nexport function promotionCode(value: unknown, max = 40): string {\n return text(value)\n .toUpperCase()\n .replace(/[^A-Z0-9_-]/g, '')\n .slice(0, max)\n}\n\nconst cents = (value: unknown): number | null => {\n if (value === null || value === undefined || value === '') return null\n if (typeof value === 'object' && 'amountMinor' in (value as object)) return Math.round(Number((value as { amountMinor: number }).amountMinor))\n const number = Number(value)\n return Number.isFinite(number) ? Math.round(number * 100) : null\n}\n\nconst msOf = (value: unknown): number | null => {\n if (value === null || value === undefined || value === '') return null\n const time = typeof value === 'number' ? value : Date.parse(String(value))\n return Number.isFinite(time) ? time : null\n}\n\nexport function discountRecord(id: string, stored: Partial<HostDiscount> & { code?: string | null }): Record<string, unknown> {\n return {\n id,\n code: stored.code || null,\n name: stored.name ?? null,\n kind: DISCOUNT_KIND_LABELS[stored.kind as DiscountKind] ?? stored.kind ?? null,\n percentOff: stored.kind === 'percent' ? (stored.valuePct ?? null) : null,\n amountOff: stored.kind === 'fixed' ? dollars(stored.valueCents) : null,\n minimumSubtotal: dollars(stored.minSubtotalCents),\n productIds: stored.productIds?.length ? stored.productIds.join(', ') : null,\n maxRedemptions: stored.maxRedemptions ?? null,\n startsAt: iso(stored.startAtMs),\n endsAt: iso(stored.endAtMs),\n active: stored.enabled !== false,\n redemptions: stored.redemptions ?? 0,\n }\n}\n\n/**\n * The document a discount's changes make, over what it holds: the stored\n * shape the discounts card writes, or the sentence refusing it.\n */\nexport function discountWrite(\n current: (Partial<HostDiscount> & { code?: string | null }) | null,\n changes: Readonly<Record<string, unknown>>,\n): { doc: Record<string, unknown> } | { problem: string } {\n const doc: Record<string, unknown> = current ? { ...current } : { enabled: false, redemptions: 0 }\n const has = (fieldId: string) => fieldId in changes\n if (has('code')) doc['code'] = promotionCode(changes['code']) || null\n if (has('name')) doc['name'] = text(changes['name']).slice(0, 80) || null\n if (has('kind')) doc['kind'] = discountKindOf(changes['kind'])\n if (has('percentOff')) doc['valuePct'] = changes['percentOff'] === null ? null : Math.round(Number(changes['percentOff']))\n if (has('amountOff')) doc['valueCents'] = cents(changes['amountOff'])\n if (has('minimumSubtotal')) doc['minSubtotalCents'] = cents(changes['minimumSubtotal'])\n if (has('productIds')) {\n const ids = text(changes['productIds']).split(/[,;|\\s]+/).map(text).filter(Boolean)\n doc['productIds'] = ids.length ? [...new Set(ids)] : null\n }\n if (has('maxRedemptions')) {\n const limit = Number(changes['maxRedemptions'])\n doc['maxRedemptions'] = changes['maxRedemptions'] === null || !Number.isFinite(limit) ? null : Math.max(1, Math.round(limit))\n }\n if (has('startsAt')) doc['startAtMs'] = msOf(changes['startsAt'])\n if (has('endsAt')) doc['endAtMs'] = msOf(changes['endsAt'])\n if (has('active')) doc['enabled'] = changes['active'] === true\n if (!('code' in doc)) doc['code'] = null\n const kind = doc['kind'] as DiscountKind | null | undefined\n if (!kind) return { problem: 'Say what kind of discount it is: Percent off, Amount off or Free shipping.' }\n if (kind === 'percent') {\n const pct = Number(doc['valuePct'])\n if (!(pct >= 1 && pct <= 100)) return { problem: 'A percent-off discount takes 1 to 100 percent.' }\n }\n if (kind === 'fixed' && !(Number(doc['valueCents']) > 0)) return { problem: 'An amount-off discount needs an amount.' }\n if (!doc['code'] && !text(doc['name'])) return { problem: 'A discount with no code needs a name shoppers see.' }\n const start = doc['startAtMs'] as number | null\n const end = doc['endAtMs'] as number | null\n if (start != null && end != null && end <= start) return { problem: 'A discount ends after it starts.' }\n return { doc }\n}\n\n/*==========================================\n * COUPONS\n *=========================================*/\n\nexport const COUPON_TRANSFER_FIELDS: readonly TransferField[] = [\n {\n id: 'code',\n label: 'Code',\n group: 'coupon',\n type: 'text',\n matchKey: true,\n aliases: ['coupon code', 'promo code', 'discount code'],\n description: 'What a shopper types; a coupon’s code is its ID, so it is never changed.',\n },\n { id: 'percentOff', label: 'Percent off', group: 'coupon', type: 'integer', aliases: ['percent', 'percentage', 'value'] },\n { id: 'maxRedemptions', label: 'Use limit', group: 'coupon', type: 'integer', aliases: ['usage limit', 'max uses'] },\n { id: 'expiresAt', label: 'Expires', group: 'coupon', type: 'datetime', aliases: ['expiry', 'expires at', 'end date'] },\n {\n id: 'active',\n label: 'Active',\n group: 'coupon',\n type: 'boolean',\n aliases: ['enabled', 'status'],\n description: 'A new coupon starts switched off unless the file says it is active.',\n },\n { id: 'redemptions', label: 'Times used', group: 'coupon', type: 'integer', readOnly: true },\n { id: 'createdAt', label: 'Created', group: TRANSFER_SYSTEM_GROUP.id, type: 'datetime', system: true },\n]\n\nexport const COUPON_MATCH_KEYS: readonly MatchKeySpec[] = [\n { fieldId: 'code', normalizer: 'caseless' },\n { fieldId: 'id', normalizer: 'aglynId' },\n]\n\nexport interface StoredCoupon {\n percentOff?: number\n enabled?: boolean\n redemptions?: number\n maxRedemptions?: number\n expiresAtMs?: number\n createdAt?: unknown\n}\n\nexport function couponRecord(id: string, stored: StoredCoupon): Record<string, unknown> {\n return {\n id,\n code: id,\n percentOff: stored.percentOff ?? null,\n maxRedemptions: stored.maxRedemptions ?? null,\n expiresAt: iso(stored.expiresAtMs),\n active: stored.enabled !== false,\n redemptions: stored.redemptions ?? 0,\n createdAt: iso(stored.createdAt),\n }\n}\n\n/** A coupon's document from its changes, as the coupons card writes one, or the refusal. */\nexport function couponWrite(\n current: StoredCoupon | null,\n changes: Readonly<Record<string, unknown>>,\n): { doc: Record<string, unknown> } | { problem: string } {\n const doc: Record<string, unknown> = current ? { ...current } : { enabled: false, redemptions: 0 }\n if ('percentOff' in changes) doc['percentOff'] = Math.round(Number(changes['percentOff']))\n if ('maxRedemptions' in changes) {\n const limit = Number(changes['maxRedemptions'])\n doc['maxRedemptions'] = changes['maxRedemptions'] === null || !Number.isFinite(limit) ? null : Math.max(1, Math.round(limit))\n }\n if ('expiresAt' in changes) doc['expiresAtMs'] = msOf(changes['expiresAt'])\n if ('active' in changes) doc['enabled'] = changes['active'] === true\n const pct = Number(doc['percentOff'])\n if (!(pct > 0 && pct <= 100)) return { problem: 'A coupon takes 1 to 100 percent off.' }\n return { doc }\n}\n\n/*==========================================\n * GIFT CARDS\n *=========================================*/\n\n/*\n * A GIFT CARD IMPORT ISSUES CARDS (AGL-3551). A row is never written as a\n * balance: each one the dry run passes is issued through the same path as\n * the Gift cards card's Issue (`issueGiftCard`), so its amount is bounded,\n * its code is never overwritten and its activity line is written.\n *\n * - The plan mints the code a row will carry — the file's own, a new one for\n * a blank cell, or a new one for a row whose code another card holds and\n * whose Conflicts choice is \"create a new record\" — so the dry run shows\n * every card exactly as it will be issued.\n * - A row whose code another card holds and whose choice is \"update\" is\n * refused: a file never changes a card. \"Skip\" leaves the card as it is.\n * - Every card the dry run passes adds to a total the person types back on\n * the wizard's Confirm step (`GIFT_CARD_CONFIRM_STEP_ID`). The server reads\n * the typed total from `extras` and issues nothing unless it is exactly\n * the total of the cards about to be issued.\n */\n\nexport const GIFT_CARD_TRANSFER_FIELDS: readonly TransferField[] = [\n {\n id: 'code',\n label: 'Code',\n group: 'card',\n type: 'text',\n matchKey: true,\n aliases: ['gift card code', 'card code', 'gift card number', 'card number'],\n description:\n 'The card’s code, which spends its balance: keep the file as safe as the cards. On import, a blank code gets a new one.',\n },\n {\n id: 'balance',\n label: 'Balance',\n group: 'card',\n type: 'currency',\n aliases: ['amount', 'value', 'current balance', 'remaining balance', 'balance remaining'],\n description: 'On import, what the card is issued for, in US dollars — the balance it carries over.',\n },\n {\n id: 'currency',\n label: 'Currency',\n group: 'card',\n type: 'text',\n aliases: ['currency code'],\n description: 'Optional. Cards are held in US dollars; a row in another currency is refused, never converted.',\n },\n { id: 'initial', label: 'Issued for', group: 'card', type: 'number', readOnly: true },\n { id: 'status', label: 'Status', group: 'card', type: 'text', readOnly: true, description: 'Active, Used up, Frozen or Voided.' },\n {\n id: 'recipientEmail',\n label: 'Recipient email',\n group: 'card',\n type: 'email',\n aliases: ['email', 'customer email', 'recipient'],\n },\n { id: 'orderId', label: 'Order ID', group: 'card', type: 'text', readOnly: true, description: 'Blank for a card issued by hand.' },\n { id: 'note', label: 'Note', group: 'card', type: 'text', aliases: ['notes', 'message'] },\n { id: 'issuedAt', label: 'Issued', group: 'card', type: 'datetime', readOnly: true },\n { id: 'lastUsedAt', label: 'Last used', group: 'card', type: 'datetime', readOnly: true },\n]\n\n/** A card is found by its code, which is its ID. */\nexport const GIFT_CARD_MATCH_KEYS: readonly MatchKeySpec[] = [\n { fieldId: 'code', normalizer: 'caseless' },\n { fieldId: 'id', normalizer: 'aglynId' },\n]\n\n/** The fields an issued card's undo entry holds: any of them moving means the card was spent. */\nexport const GIFT_CARD_UNDO_FIELDS = ['balance', 'status', 'lastUsedAt'] as const\n\nexport type StoredGiftCard = HostGiftCard & {\n initialCents?: number\n recipientEmail?: string | null\n orderId?: string | null\n note?: string\n createdAtMs?: number\n lastUsedAtMs?: number\n importJobId?: string\n importRow?: number\n}\n\nexport function giftCardRecord(id: string, stored: StoredGiftCard): Record<string, unknown> {\n const balance = Number(stored.balanceCents ?? 0)\n return {\n id,\n code: id,\n balance: dollars(balance),\n currency: GIFT_CARD_CURRENCY,\n initial: dollars(stored.initialCents),\n status: stored.voidedAtMs ? 'Voided' : stored.frozenAtMs ? 'Frozen' : balance > 0 ? 'Active' : 'Used up',\n recipientEmail: stored.recipientEmail ?? null,\n orderId: stored.orderId ?? null,\n note: stored.note ?? null,\n issuedAt: iso(stored.createdAtMs),\n lastUsedAt: iso(stored.lastUsedAtMs),\n }\n}\n\n/** Dollars and cents as a person reads them: `$1,250.00`. */\nexport function giftCardMoney(amountCents: number): string {\n return `$${(amountCents / 100).toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`\n}\n\n/** A total as a person types it (`1250`, `$1,250.00`), in cents; `null` for anything else. */\nexport function typedDollarsToCents(typed: unknown): number | null {\n const body = String(typed ?? '')\n .trim()\n .replace(/^\\$|^usd\\s*/i, '')\n .replace(/\\s*usd$/i, '')\n .replace(/,/g, '')\n .trim()\n if (!/^\\d+(\\.\\d{1,2})?$/.test(body)) return null\n return Math.round(Number(body) * 100)\n}\n\n/** The Confirm step's answer. */\nexport interface GiftCardConfirmation {\n /** The total the person typed, in cents. */\n totalCents: number\n /** Email each card's recipient their code as it is issued. */\n email: boolean\n}\n\n/** The Confirm step's answer from `extras`, or `null` for none: a total is a whole number of cents. */\nexport function readGiftCardConfirmation(\n extras: Readonly<Record<string, unknown>> | undefined,\n): GiftCardConfirmation | null {\n const value = extras?.[GIFT_CARD_CONFIRM_STEP_ID]\n if (!value || typeof value !== 'object') return null\n const totalCents = (value as Record<string, unknown>)['totalCents']\n if (typeof totalCents !== 'number' || !Number.isInteger(totalCents) || totalCents <= 0) return null\n return { totalCents, email: (value as Record<string, unknown>)['email'] === true }\n}\n\n/** The card one planned row issues, as the plan decided it. */\nexport interface GiftCardRowPlan {\n /** The code the card is issued under. */\n code: string\n /** The file's code was taken, and the person chose a new one. */\n newCode: boolean\n /** The file named no code, so one was made. */\n madeCode: boolean\n amountCents: number\n recipientEmail: string | null\n note: string | null\n /** Why the row issues nothing; the `gift-card-issuable` invariant fails it. */\n problem?: string\n /** What every card this import issues adds up to. */\n totalCents: number\n /** Whether the person typed exactly that total on the Confirm step. */\n confirmed: boolean\n}\n\nexport type GiftCardPlannedRow = PlannedTransferRow & { giftCard?: GiftCardRowPlan }\n\n/** A money cell in cents and its currency: the derived amount, or a number as dollars. */\nfunction giftCardAmount(value: unknown): { cents: number; currency: string } | null {\n if (value === null || value === undefined || value === '') return null\n if (typeof value === 'object' && 'amountMinor' in (value as object)) {\n const amount = value as { amountMinor: number; currency?: string }\n return { cents: Math.round(Number(amount.amountMinor)), currency: text(amount.currency).toUpperCase() || GIFT_CARD_CURRENCY }\n }\n const number = Number(value)\n return Number.isFinite(number) ? { cents: Math.round(number * 100), currency: GIFT_CARD_CURRENCY } : null\n}\n\n/** The card a row's changes issue, or the sentence refusing it. */\nexport function giftCardIssueOf(\n changes: Readonly<Record<string, unknown>>,\n code: { value: string; fromFile: boolean },\n): Omit<GiftCardRowPlan, 'newCode' | 'madeCode' | 'totalCents' | 'confirmed'> {\n const recipientEmail = text(changes['recipientEmail']).toLowerCase().slice(0, 200) || null\n const note = text(changes['note']).slice(0, 200) || null\n const base = { code: code.value, amountCents: 0, recipientEmail, note }\n const codeProblem = code.fromFile ? giftCardCodeProblem(code.value) : null\n if (codeProblem) return { ...base, problem: codeProblem }\n const amount = giftCardAmount(changes['balance'])\n if (!amount) return { ...base, problem: 'Say what the card is issued for in the Balance column.' }\n const named = text(changes['currency']).toUpperCase()\n for (const currency of [amount.currency, named].filter(Boolean)) {\n if (currency !== GIFT_CARD_CURRENCY) {\n return { ...base, problem: `Gift cards are held in US dollars; ${currency} is not converted.` }\n }\n }\n const amountProblem = giftCardAmountProblem(amount.cents)\n if (amountProblem) return { ...base, problem: amountProblem }\n return { ...base, amountCents: amount.cents }\n}\n\n/**\n * The core's plan for a gift card file, made into the cards it issues: each\n * create carrying the card it issues ({@link GiftCardRowPlan}), each row\n * that would change an existing card refused, the total of every card\n * counted, and a `screening` warning stating that total — and, when the\n * Confirm step's answer is missing or names another total, that nothing is\n * issued until it is confirmed.\n */\nexport function planGiftCardRows(\n plan: TransferPlan,\n input: {\n confirmation: GiftCardConfirmation | null\n mintCode: () => string\n /** The file's codes a card on the site already holds, however the file spelled them. */\n taken?: ReadonlySet<string>\n },\n): TransferPlan {\n const issuing = new Map<string, number>()\n const rows = plan.rows.map((row): GiftCardPlannedRow => {\n if (row.verdict === 'update' || row.verdict === 'unchanged') {\n const code = row.recordId ?? ''\n return {\n ...row,\n verdict: 'update',\n diff: [],\n giftCard: {\n code,\n newCode: false,\n madeCode: false,\n amountCents: 0,\n recipientEmail: null,\n note: null,\n problem:\n `A gift card with the code ${code} already exists, and a file never changes a card. ` +\n 'On the Conflicts step, skip this row, or create a new record to issue it under a new code.',\n totalCents: 0,\n confirmed: false,\n },\n }\n }\n if (row.verdict !== 'create') return row\n const changes = rowChanges(row)\n const fileCode = giftCardCodeOf(changes['code'])\n // A create for a row that matched a card is the person's \"create a new\n // record\": the card it names keeps its code, and this one gets another.\n const newCode = Boolean(fileCode) && row.match.kind !== 'new'\n const madeCode = !fileCode\n const code = newCode || madeCode ? input.mintCode() : fileCode\n const fromFile = !newCode && !madeCode\n let issue = giftCardIssueOf(changes, { value: code, fromFile })\n const earlier = issuing.get(code)\n if (!issue.problem && fromFile && input.taken?.has(code)) {\n issue = { ...issue, problem: `A gift card with the code ${code} already exists, and a file never changes a card.` }\n } else if (!issue.problem && earlier !== undefined) {\n issue = { ...issue, problem: `Row ${earlier + 1} issues the code ${code} already.` }\n }\n if (!issue.problem) issuing.set(code, row.index)\n const diff: TransferFieldChange[] = [\n ...row.diff.filter((change) => change.fieldId !== 'code'),\n { fieldId: 'code', before: null, after: code, mode: 'overwrite', source: 'default', rule: 'written' },\n ]\n return { ...row, diff, giftCard: { ...issue, newCode, madeCode, totalCents: 0, confirmed: false } }\n })\n\n const issued = rows.filter(\n (row): row is GiftCardPlannedRow & { giftCard: GiftCardRowPlan } =>\n row.verdict === 'create' && Boolean(row.giftCard) && !row.giftCard?.problem,\n )\n const totalCents = issued.reduce((sum, row) => sum + row.giftCard.amountCents, 0)\n const confirmed = input.confirmation?.totalCents === totalCents\n for (const row of rows) {\n if (row.giftCard) row.giftCard = { ...row.giftCard, totalCents, confirmed }\n }\n\n const warnings = plan.warnings.filter((warning) => warning.class !== 'screening')\n if (issued.length) {\n const samples: TransferWarningSample[] = [\n {\n row: TRANSFER_FILE_SAMPLE_ROW,\n fieldId: 'balance',\n value: giftCardMoney(totalCents),\n detail: `Issues ${issued.length.toLocaleString('en-US')} gift card${issued.length === 1 ? '' : 's'} worth ${giftCardMoney(totalCents)} in total.`,\n },\n ]\n if (!confirmed) {\n samples.push({\n row: TRANSFER_FILE_SAMPLE_ROW,\n detail: input.confirmation\n ? `The total confirmed was ${giftCardMoney(input.confirmation.totalCents)}, not ${giftCardMoney(totalCents)}: no card is issued until the total is confirmed again on the Confirm step.`\n : 'The total has not been confirmed: no card is issued until it is typed on the Confirm step.',\n })\n }\n warnings.push({\n class: 'screening',\n count: issued.length,\n rows: issued.length,\n fieldIds: ['balance'],\n samples,\n requiresAcknowledgement: true,\n })\n }\n const summary: TransferPlanSummary = { create: 0, update: 0, unchanged: 0, skip: 0, fail: 0, total: rows.length }\n for (const row of rows) summary[row.verdict] += 1\n return {\n rows,\n summary,\n warnings,\n acknowledgementsRequired: warnings.filter((warning) => warning.requiresAcknowledgement).map((warning) => warning.class),\n }\n}\n\n/*==========================================\n * CATEGORIES\n *=========================================*/\n\nexport const CATEGORY_TRANSFER_FIELDS: readonly TransferField[] = [\n { id: 'name', label: 'Name', group: 'category', type: 'text', aliases: ['category', 'category name', 'title'] },\n {\n id: 'slug',\n label: 'Slug',\n group: 'category',\n type: 'text',\n readOnly: true,\n matchKey: true,\n aliases: ['handle'],\n description: 'Made from the name, as the console makes it; a file finds a category by it.',\n },\n {\n id: 'parent',\n label: 'Parent',\n group: 'category',\n type: 'text',\n aliases: ['parent category', 'parent slug'],\n description: 'The parent category’s slug or name; blank for a top-level category.',\n },\n { id: 'order', label: 'Position', group: 'category', type: 'integer', aliases: ['sort order', 'order'] },\n]\n\nexport const CATEGORY_MATCH_KEYS: readonly MatchKeySpec[] = [\n { fieldId: 'slug', normalizer: 'slug' },\n { fieldId: 'name', normalizer: 'name' },\n { fieldId: 'id', normalizer: 'aglynId' },\n]\n\nexport interface StoredCategory {\n name?: string\n slug?: string\n parentId?: string | null\n order?: number\n}\n\nexport function categoryRecord(\n id: string,\n stored: StoredCategory,\n slugs: ReadonlyMap<string, string> = new Map(),\n): Record<string, unknown> {\n return {\n id,\n name: stored.name ?? null,\n slug: stored.slug ?? null,\n parent: stored.parentId ? (slugs.get(stored.parentId) ?? stored.parentId) : null,\n order: typeof stored.order === 'number' ? stored.order : null,\n }\n}\n\n/** Every category's slug, name and parent, by id: what a parent is resolved against. */\nexport type CategoryIndex = Map<string, StoredCategory>\n\n/** The category a parent cell names — by id, slug, then name — or `null`. */\nexport function resolveCategoryParent(index: CategoryIndex, value: unknown): string | null {\n const wanted = text(value)\n if (!wanted) return null\n if (index.has(wanted)) return wanted\n const slug = commerceSlug(wanted)\n for (const [id, category] of index) if (category.slug === slug) return id\n const name = wanted.toLowerCase()\n for (const [id, category] of index) if (text(category.name).toLowerCase() === name) return id\n return null\n}\n\n/**\n * A category's document from its changes: the name and the slug made from\n * it, the parent resolved — never itself or one of its own descendants —\n * and the position. A parent the site does not have is refused, not\n * guessed.\n */\nexport function categoryWrite(\n id: string,\n current: StoredCategory | null,\n changes: Readonly<Record<string, unknown>>,\n index: CategoryIndex,\n): { doc: Record<string, unknown> } | { problem: string } {\n const doc: Record<string, unknown> = current ? { ...current } : { parentId: null }\n if ('name' in changes) {\n const name = text(changes['name']).slice(0, 80)\n if (!name) return { problem: 'A category needs a name.' }\n doc['name'] = name\n doc['slug'] = commerceSlug(name) || id\n }\n if (!text(doc['name'])) return { problem: 'A category needs a name.' }\n if ('parent' in changes) {\n if (isBlankTransferValue(changes['parent'])) doc['parentId'] = null\n else {\n const parentId = resolveCategoryParent(index, changes['parent'])\n if (!parentId) return { problem: `No category \"${text(changes['parent'])}\" to put it under.` }\n for (let at: string | null = parentId, steps = 0; at && steps < 100; steps += 1) {\n if (at === id) return { problem: 'A category cannot sit under itself or one of its own.' }\n at = index.get(at)?.parentId ?? null\n }\n doc['parentId'] = parentId\n }\n }\n if ('order' in changes) {\n const order = Number(changes['order'])\n doc['order'] = changes['order'] === null || !Number.isFinite(order) ? null : Math.round(order)\n }\n return { doc }\n}\n"],"names":["buildTransferPlan","isBlankTransferValue","TRANSFER_FILE_SAMPLE_ROW","TRANSFER_SYSTEM_GROUP","commerceSlug","GIFT_CARD_CONFIRM_STEP_ID","GIFT_CARD_CURRENCY","giftCardAmountProblem","giftCardCodeOf","giftCardCodeProblem","ORDER_CHANNEL_LABELS","ORDER_STATUS_LABELS","liftLegacyOrder","iso","ms","time","toMillis","toDate","getTime","NaN","Number","isFinite","Date","toISOString","dollars","cents","value","undefined","Math","round","text","String","trim","rowChanges","row","Object","fromEntries","diff","map","change","fieldId","after","planWithCreateRequired","input","required","fields","field","includes","id","ORDER_TRANSFER_FIELDS","label","group","type","readOnly","description","system","ORDER_TRANSFER_GROUPS","addressLine","address","parts","name","line1","line2","city","state","postalCode","country","filter","Boolean","length","join","orderRecord","stored","productNames","lineItems","totals","lifted","first","productId","totalCents","amountCents","refundedCents","number","date","createdAt","createdAtMs","status","channel","customerEmail","customerName","product","items","line","quantity","variantLabel","sku","itemCount","reduce","sum","subtotal","itemsCents","shipping","shippingCents","tax","taxCents","discount","discountCents","total","fee","feeCents","refunded","net","coupon","couponCode","shippingAddress","billingAddress","note","dispute","paymentIntentId","DISCOUNT_KIND_PICKLIST","DISCOUNT_KIND_LABELS","percent","fixed","free_shipping","DISCOUNT_KIND_SPEC","restricted","standardValues","entries","defaultValueId","discountKindOf","key","toLowerCase","found","find","DISCOUNT_TRANSFER_FIELDS","aliases","picklistId","DISCOUNT_MATCH_KEYS","normalizer","promotionCode","max","toUpperCase","replace","slice","amountMinor","msOf","parse","discountRecord","code","kind","percentOff","valuePct","amountOff","valueCents","minimumSubtotal","minSubtotalCents","productIds","maxRedemptions","startsAt","startAtMs","endsAt","endAtMs","active","enabled","redemptions","discountWrite","current","changes","doc","has","ids","split","Set","limit","problem","pct","start","end","COUPON_TRANSFER_FIELDS","matchKey","COUPON_MATCH_KEYS","couponRecord","expiresAt","expiresAtMs","couponWrite","GIFT_CARD_TRANSFER_FIELDS","GIFT_CARD_MATCH_KEYS","GIFT_CARD_UNDO_FIELDS","giftCardRecord","balance","balanceCents","currency","initial","initialCents","voidedAtMs","frozenAtMs","recipientEmail","orderId","issuedAt","lastUsedAt","lastUsedAtMs","giftCardMoney","toLocaleString","minimumFractionDigits","maximumFractionDigits","typedDollarsToCents","typed","body","test","readGiftCardConfirmation","extras","isInteger","email","giftCardAmount","amount","giftCardIssueOf","base","codeProblem","fromFile","named","amountProblem","planGiftCardRows","plan","issuing","Map","rows","verdict","recordId","giftCard","newCode","madeCode","confirmed","fileCode","match","mintCode","issue","earlier","get","taken","set","index","before","mode","source","rule","issued","confirmation","warnings","warning","class","samples","detail","push","count","fieldIds","requiresAcknowledgement","summary","create","update","unchanged","skip","fail","acknowledgementsRequired","CATEGORY_TRANSFER_FIELDS","CATEGORY_MATCH_KEYS","categoryRecord","slugs","slug","parent","parentId","order","resolveCategoryParent","wanted","category","categoryWrite","at","steps"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/transfer/records-transfer.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n buildTransferPlan,\n isBlankTransferValue,\n TRANSFER_FILE_SAMPLE_ROW,\n TRANSFER_SYSTEM_GROUP,\n type BuildTransferPlanInput,\n type MatchKeySpec,\n type PlannedTransferRow,\n type TransferField,\n type TransferFieldChange,\n type TransferPlan,\n type TransferPlanSummary,\n type TransferWarningSample,\n} from '@aglyn/aglyn/data-transfer'\nimport type { PicklistSpec } from '@aglyn/aglyn/app-utils/picklists'\nimport { commerceSlug } from '../model/commerce'\nimport type { DiscountKind, HostDiscount } from '../model/commerce-discounts'\nimport { GIFT_CARD_CONFIRM_STEP_ID } from './transfer-keys'\nimport {\n GIFT_CARD_CURRENCY,\n giftCardAmountProblem,\n giftCardCodeOf,\n giftCardCodeProblem,\n type HostGiftCard,\n} from '../model/commerce-gift-cards'\nimport {\n ORDER_CHANNEL_LABELS,\n ORDER_STATUS_LABELS,\n liftLegacyOrder,\n type HostOrder,\n type OrderAddress,\n} from '../model/commerce-orders'\nimport { orderShippingRecord, type ProductWeights } from '../model/order-shipping-export'\n\n/*\n * ORDERS, DISCOUNTS, COUPONS, GIFT CARDS AND CATEGORIES AS FILES (AGL-3531):\n * each resource's fields, and its stored document as the record a file\n * names. Pure — the server half is `records.server.ts`.\n *\n * ## What imports, and why the rest does not\n *\n * - Categories, discounts and coupons import: each is a document a person\n * writes from the console with nothing derived behind it, so a file\n * writes the same fields the console's card does. A discount or coupon\n * created from a file starts SWITCHED OFF unless the file says Active —\n * a promotion going live from a spreadsheet is money leaving the store.\n * How many times one was used is history, exported and never written.\n * - Orders are exported only: an order is the record of a sale, written by\n * checkout, the register or a paid draft.\n * - Gift cards import by ISSUING each card (AGL-3551, below), never by\n * writing a balance: a balance is money a shopper can spend. A gift\n * card's ID is its code, so the file is worth what the cards are.\n */\n\nconst iso = (ms: unknown): string | null => {\n const time =\n typeof ms === 'number'\n ? ms\n : ms && typeof (ms as { toMillis?: () => number }).toMillis === 'function'\n ? (ms as { toMillis: () => number }).toMillis()\n : ms && typeof (ms as { toDate?: () => Date }).toDate === 'function'\n ? ((ms as { toDate: () => Date }).toDate()?.getTime() ?? NaN)\n : NaN\n return Number.isFinite(time) ? new Date(time).toISOString() : null\n}\n\nconst dollars = (cents: unknown): number | null => {\n const value = Number(cents)\n return cents === null || cents === undefined || !Number.isFinite(value) ? null : Math.round(value) / 100\n}\n\nconst text = (value: unknown): string => (value === null || value === undefined ? '' : String(value).trim())\n\n/** A planned row's changes, by field id. */\nexport function rowChanges(row: PlannedTransferRow): Record<string, unknown> {\n return Object.fromEntries(row.diff.map((change) => [change.fieldId, change.after]))\n}\n\n/**\n * The core's plan with the fields a NEW record cannot be made without\n * marked required — never in the catalog, where a required field must be\n * mapped, and a file that only switches discounts off would be refused.\n */\nexport function planWithCreateRequired(input: BuildTransferPlanInput, required: readonly string[]): TransferPlan {\n return buildTransferPlan({\n ...input,\n fields: input.fields.map((field) => (required.includes(field.id) ? { ...field, required: true } : field)),\n })\n}\n\n/*==========================================\n * ORDERS\n *=========================================*/\n\n/**\n * What a label tool reads (AGL-3613): the ship-to address split into its\n * parts, what is still to be packed and what it weighs — `orderShippingRecord`.\n * The weight is the remaining units' recorded product weights; blank when\n * no product records one, so the tool uses its default package instead.\n */\nexport const ORDER_SHIPPING_FIELDS: readonly TransferField[] = [\n { id: 'orderRef', label: 'Order reference', group: 'shipping', type: 'text', readOnly: true, description: 'The order number, as a label tool sends it back.' },\n { id: 'shipName', label: 'Ship to name', group: 'shipping', type: 'text', readOnly: true },\n { id: 'shipLine1', label: 'Ship to address line 1', group: 'shipping', type: 'text', readOnly: true },\n { id: 'shipLine2', label: 'Ship to address line 2', group: 'shipping', type: 'text', readOnly: true },\n { id: 'shipCity', label: 'Ship to city', group: 'shipping', type: 'text', readOnly: true },\n { id: 'shipState', label: 'Ship to state', group: 'shipping', type: 'text', readOnly: true },\n { id: 'shipPostalCode', label: 'Ship to postal code', group: 'shipping', type: 'text', readOnly: true },\n { id: 'shipCountry', label: 'Ship to country', group: 'shipping', type: 'text', readOnly: true },\n { id: 'shipPhone', label: 'Ship to phone', group: 'shipping', type: 'phone', readOnly: true },\n { id: 'shipEmail', label: 'Ship to email', group: 'shipping', type: 'email', readOnly: true },\n { id: 'itemsToShip', label: 'Items to ship', group: 'shipping', type: 'longText', readOnly: true, description: 'What is still to ship: quantity × name (variant), SKU.' },\n { id: 'unitsToShip', label: 'Units to ship', group: 'shipping', type: 'integer', readOnly: true },\n { id: 'weightOz', label: 'Weight (oz)', group: 'shipping', type: 'number', readOnly: true },\n { id: 'weightLb', label: 'Weight (lb)', group: 'shipping', type: 'number', readOnly: true },\n { id: 'weightUnit', label: 'Weight unit', group: 'shipping', type: 'text', readOnly: true, description: 'Always oz, beside Weight (oz), for tools that ask for the unit.' },\n]\n\n/** The shipping fields' ids, which an export reads product weights for. */\nexport const ORDER_SHIPPING_FIELD_IDS: readonly string[] = ORDER_SHIPPING_FIELDS.map((field) => field.id)\n\nexport const ORDER_TRANSFER_FIELDS: readonly TransferField[] = [\n { id: 'number', label: 'Order number', group: 'order', type: 'integer', readOnly: true },\n { id: 'date', label: 'Date', group: 'order', type: 'datetime', readOnly: true },\n { id: 'status', label: 'Status', group: 'order', type: 'text', readOnly: true },\n { id: 'channel', label: 'Channel', group: 'order', type: 'text', readOnly: true },\n { id: 'customerEmail', label: 'Customer email', group: 'customer', type: 'email', readOnly: true },\n { id: 'customerName', label: 'Customer name', group: 'customer', type: 'text', readOnly: true },\n {\n id: 'product',\n label: 'Product',\n group: 'items',\n type: 'text',\n readOnly: true,\n description: 'The first line’s product, and how many more the order holds.',\n },\n { id: 'items', label: 'Items', group: 'items', type: 'longText', readOnly: true, description: 'Every line: quantity × name (variant), SKU.' },\n { id: 'itemCount', label: 'Units', group: 'items', type: 'integer', readOnly: true },\n { id: 'subtotal', label: 'Items subtotal', group: 'money', type: 'number', readOnly: true },\n { id: 'shipping', label: 'Shipping', group: 'money', type: 'number', readOnly: true },\n { id: 'tax', label: 'Tax', group: 'money', type: 'number', readOnly: true },\n { id: 'discount', label: 'Discount', group: 'money', type: 'number', readOnly: true },\n { id: 'total', label: 'Total', group: 'money', type: 'number', readOnly: true, description: 'What was charged, in dollars.' },\n { id: 'fee', label: 'Fee', group: 'money', type: 'number', readOnly: true },\n { id: 'refunded', label: 'Refunded', group: 'money', type: 'number', readOnly: true },\n { id: 'net', label: 'Net', group: 'money', type: 'number', readOnly: true, description: 'The total less what was refunded.' },\n { id: 'coupon', label: 'Coupon', group: 'money', type: 'text', readOnly: true },\n { id: 'shippingAddress', label: 'Shipping address', group: 'customer', type: 'text', readOnly: true },\n { id: 'billingAddress', label: 'Billing address', group: 'customer', type: 'text', readOnly: true },\n { id: 'note', label: 'Note', group: 'order', type: 'longText', readOnly: true },\n { id: 'dispute', label: 'Dispute', group: 'order', type: 'text', readOnly: true },\n { id: 'paymentIntentId', label: 'Payment ID', group: TRANSFER_SYSTEM_GROUP.id, type: 'text', system: true },\n ...ORDER_SHIPPING_FIELDS,\n]\n\nexport const ORDER_TRANSFER_GROUPS = [\n { id: 'order', label: 'Order' },\n { id: 'customer', label: 'Customer' },\n { id: 'items', label: 'Items' },\n { id: 'money', label: 'Money' },\n { id: 'shipping', label: 'Shipping' },\n]\n\n/** An order as a stored document, with the id the export reads it under. */\nexport type StoredOrder = Partial<HostOrder> & {\n createdAt?: unknown\n createdAtMs?: number\n amountCents?: number\n feeCents?: number\n productId?: string\n}\n\nconst addressLine = (address: OrderAddress | undefined): string | null => {\n if (!address) return null\n const parts = [address.name, address.line1, address.line2, address.city, address.state, address.postalCode, address.country]\n .map(text)\n .filter(Boolean)\n return parts.length ? parts.join(', ') : null\n}\n\n/**\n * One order as a file names it. The money is what was ACTUALLY charged:\n * the order's `totals`, and the legacy flat fields only where a buy-now order\n * of old carries nothing else (AGL-1747) — a POS or draft order has no flat\n * field, and reading those first exported every one of them at $0.00. A\n * legacy row is named from `productNames`, never as \"Product\".\n */\nexport function orderRecord(\n id: string,\n stored: StoredOrder,\n productNames: Readonly<Record<string, string>> = {},\n weights: ProductWeights = {},\n): Record<string, unknown> {\n const lifted = liftLegacyOrder(stored)\n const lineItems = stored.lineItems ?? []\n const first = lineItems[0]?.name ?? productNames[stored.productId ?? ''] ?? stored.productId ?? ''\n const totals = lifted.totals\n const totalCents = Number(totals?.totalCents ?? stored.amountCents ?? 0)\n const refundedCents = Number(stored.refundedCents ?? 0)\n return {\n id,\n number: typeof stored.number === 'number' ? stored.number : null,\n date: iso(stored.createdAt) ?? iso(stored.createdAtMs),\n status: ORDER_STATUS_LABELS[lifted.status] ?? lifted.status,\n channel: ORDER_CHANNEL_LABELS[lifted.channel ?? 'online'] ?? lifted.channel ?? 'online',\n customerEmail: stored.customerEmail ?? null,\n customerName: stored.customerName ?? null,\n product: lineItems.length > 1 ? `${first} +${lineItems.length - 1} more` : first || null,\n items: lineItems.length\n ? lineItems\n .map(\n (line) =>\n `${line.quantity} × ${line.name}${line.variantLabel ? ` (${line.variantLabel})` : ''}${line.sku ? `, ${line.sku}` : ''}`,\n )\n .join('; ')\n : null,\n itemCount: lineItems.reduce((sum, line) => sum + (Number(line.quantity) || 0), 0),\n subtotal: dollars(totals?.itemsCents),\n shipping: dollars(totals?.shippingCents),\n tax: dollars(totals?.taxCents),\n discount: dollars(totals?.discountCents),\n total: dollars(totalCents),\n fee: dollars(totals?.feeCents ?? stored.feeCents ?? 0),\n refunded: dollars(refundedCents),\n net: dollars(totalCents - refundedCents),\n coupon: stored.couponCode ?? null,\n shippingAddress: addressLine(stored.shippingAddress),\n billingAddress: addressLine(stored.billingAddress),\n note: stored.note ?? null,\n dispute: stored.dispute ? text((stored.dispute as { status?: string }).status) || 'open' : null,\n paymentIntentId: stored.paymentIntentId ?? null,\n ...orderShippingRecord(id, stored, weights),\n }\n}\n\n/*==========================================\n * DISCOUNTS\n *=========================================*/\n\nexport const DISCOUNT_KIND_PICKLIST = 'commerce.discountKind'\n\nconst DISCOUNT_KIND_LABELS: Record<DiscountKind, string> = {\n percent: 'Percent off',\n fixed: 'Amount off',\n free_shipping: 'Free shipping',\n}\n\nexport const DISCOUNT_KIND_SPEC: PicklistSpec = {\n restricted: true,\n standardValues: Object.entries(DISCOUNT_KIND_LABELS).map(([id, label]) => ({ id, label })),\n defaultValueId: 'percent',\n}\n\n/** A discount kind's id from a label or id in any case, or `null`. */\nexport function discountKindOf(value: unknown): DiscountKind | null {\n const key = text(value).toLowerCase()\n const found = Object.entries(DISCOUNT_KIND_LABELS).find(\n ([id, label]) => id === key || label.toLowerCase() === key,\n )\n return found ? (found[0] as DiscountKind) : null\n}\n\nexport const DISCOUNT_TRANSFER_FIELDS: readonly TransferField[] = [\n {\n id: 'code',\n label: 'Code',\n group: 'discount',\n type: 'text',\n aliases: ['discount code', 'promo code', 'coupon code'],\n description: 'What a shopper types; blank for a discount that applies on its own.',\n },\n { id: 'name', label: 'Name', group: 'discount', type: 'text', aliases: ['title', 'discount name'] },\n {\n id: 'kind',\n label: 'Kind',\n group: 'discount',\n type: 'picklist',\n picklistId: DISCOUNT_KIND_PICKLIST,\n aliases: ['type', 'discount type', 'value type'],\n description: 'Percent off, Amount off or Free shipping. Needed for a new discount.',\n },\n { id: 'percentOff', label: 'Percent off', group: 'discount', type: 'integer', aliases: ['percent', 'percentage'] },\n { id: 'amountOff', label: 'Amount off', group: 'discount', type: 'currency', aliases: ['amount', 'value'] },\n {\n id: 'minimumSubtotal',\n label: 'Minimum subtotal',\n group: 'conditions',\n type: 'currency',\n aliases: ['minimum', 'minimum purchase', 'minimum subtotal'],\n },\n {\n id: 'productIds',\n label: 'Product IDs',\n group: 'conditions',\n type: 'text',\n description: 'The products it covers, by their IDs separated by commas; blank covers the whole store.',\n },\n { id: 'maxRedemptions', label: 'Use limit', group: 'conditions', type: 'integer', aliases: ['usage limit', 'max uses'] },\n { id: 'startsAt', label: 'Starts', group: 'conditions', type: 'datetime', aliases: ['start date', 'starts at'] },\n { id: 'endsAt', label: 'Ends', group: 'conditions', type: 'datetime', aliases: ['end date', 'ends at', 'expires'] },\n {\n id: 'active',\n label: 'Active',\n group: 'discount',\n type: 'boolean',\n aliases: ['enabled', 'status'],\n description: 'A new discount starts switched off unless the file says it is active.',\n },\n { id: 'redemptions', label: 'Times used', group: 'conditions', type: 'integer', readOnly: true },\n]\n\nexport const DISCOUNT_MATCH_KEYS: readonly MatchKeySpec[] = [\n { fieldId: 'code', normalizer: 'caseless' },\n { fieldId: 'name', normalizer: 'name' },\n { fieldId: 'id', normalizer: 'aglynId' },\n]\n\n/** A code as the discounts card stores it: upper case, letters, digits, `_` and `-`. */\nexport function promotionCode(value: unknown, max = 40): string {\n return text(value)\n .toUpperCase()\n .replace(/[^A-Z0-9_-]/g, '')\n .slice(0, max)\n}\n\nconst cents = (value: unknown): number | null => {\n if (value === null || value === undefined || value === '') return null\n if (typeof value === 'object' && 'amountMinor' in (value as object)) return Math.round(Number((value as { amountMinor: number }).amountMinor))\n const number = Number(value)\n return Number.isFinite(number) ? Math.round(number * 100) : null\n}\n\nconst msOf = (value: unknown): number | null => {\n if (value === null || value === undefined || value === '') return null\n const time = typeof value === 'number' ? value : Date.parse(String(value))\n return Number.isFinite(time) ? time : null\n}\n\nexport function discountRecord(id: string, stored: Partial<HostDiscount> & { code?: string | null }): Record<string, unknown> {\n return {\n id,\n code: stored.code || null,\n name: stored.name ?? null,\n kind: DISCOUNT_KIND_LABELS[stored.kind as DiscountKind] ?? stored.kind ?? null,\n percentOff: stored.kind === 'percent' ? (stored.valuePct ?? null) : null,\n amountOff: stored.kind === 'fixed' ? dollars(stored.valueCents) : null,\n minimumSubtotal: dollars(stored.minSubtotalCents),\n productIds: stored.productIds?.length ? stored.productIds.join(', ') : null,\n maxRedemptions: stored.maxRedemptions ?? null,\n startsAt: iso(stored.startAtMs),\n endsAt: iso(stored.endAtMs),\n active: stored.enabled !== false,\n redemptions: stored.redemptions ?? 0,\n }\n}\n\n/**\n * The document a discount's changes make, over what it holds: the stored\n * shape the discounts card writes, or the sentence refusing it.\n */\nexport function discountWrite(\n current: (Partial<HostDiscount> & { code?: string | null }) | null,\n changes: Readonly<Record<string, unknown>>,\n): { doc: Record<string, unknown> } | { problem: string } {\n const doc: Record<string, unknown> = current ? { ...current } : { enabled: false, redemptions: 0 }\n const has = (fieldId: string) => fieldId in changes\n if (has('code')) doc['code'] = promotionCode(changes['code']) || null\n if (has('name')) doc['name'] = text(changes['name']).slice(0, 80) || null\n if (has('kind')) doc['kind'] = discountKindOf(changes['kind'])\n if (has('percentOff')) doc['valuePct'] = changes['percentOff'] === null ? null : Math.round(Number(changes['percentOff']))\n if (has('amountOff')) doc['valueCents'] = cents(changes['amountOff'])\n if (has('minimumSubtotal')) doc['minSubtotalCents'] = cents(changes['minimumSubtotal'])\n if (has('productIds')) {\n const ids = text(changes['productIds']).split(/[,;|\\s]+/).map(text).filter(Boolean)\n doc['productIds'] = ids.length ? [...new Set(ids)] : null\n }\n if (has('maxRedemptions')) {\n const limit = Number(changes['maxRedemptions'])\n doc['maxRedemptions'] = changes['maxRedemptions'] === null || !Number.isFinite(limit) ? null : Math.max(1, Math.round(limit))\n }\n if (has('startsAt')) doc['startAtMs'] = msOf(changes['startsAt'])\n if (has('endsAt')) doc['endAtMs'] = msOf(changes['endsAt'])\n if (has('active')) doc['enabled'] = changes['active'] === true\n if (!('code' in doc)) doc['code'] = null\n const kind = doc['kind'] as DiscountKind | null | undefined\n if (!kind) return { problem: 'Say what kind of discount it is: Percent off, Amount off or Free shipping.' }\n if (kind === 'percent') {\n const pct = Number(doc['valuePct'])\n if (!(pct >= 1 && pct <= 100)) return { problem: 'A percent-off discount takes 1 to 100 percent.' }\n }\n if (kind === 'fixed' && !(Number(doc['valueCents']) > 0)) return { problem: 'An amount-off discount needs an amount.' }\n if (!doc['code'] && !text(doc['name'])) return { problem: 'A discount with no code needs a name shoppers see.' }\n const start = doc['startAtMs'] as number | null\n const end = doc['endAtMs'] as number | null\n if (start != null && end != null && end <= start) return { problem: 'A discount ends after it starts.' }\n return { doc }\n}\n\n/*==========================================\n * COUPONS\n *=========================================*/\n\nexport const COUPON_TRANSFER_FIELDS: readonly TransferField[] = [\n {\n id: 'code',\n label: 'Code',\n group: 'coupon',\n type: 'text',\n matchKey: true,\n aliases: ['coupon code', 'promo code', 'discount code'],\n description: 'What a shopper types; a coupon’s code is its ID, so it is never changed.',\n },\n { id: 'percentOff', label: 'Percent off', group: 'coupon', type: 'integer', aliases: ['percent', 'percentage', 'value'] },\n { id: 'maxRedemptions', label: 'Use limit', group: 'coupon', type: 'integer', aliases: ['usage limit', 'max uses'] },\n { id: 'expiresAt', label: 'Expires', group: 'coupon', type: 'datetime', aliases: ['expiry', 'expires at', 'end date'] },\n {\n id: 'active',\n label: 'Active',\n group: 'coupon',\n type: 'boolean',\n aliases: ['enabled', 'status'],\n description: 'A new coupon starts switched off unless the file says it is active.',\n },\n { id: 'redemptions', label: 'Times used', group: 'coupon', type: 'integer', readOnly: true },\n { id: 'createdAt', label: 'Created', group: TRANSFER_SYSTEM_GROUP.id, type: 'datetime', system: true },\n]\n\nexport const COUPON_MATCH_KEYS: readonly MatchKeySpec[] = [\n { fieldId: 'code', normalizer: 'caseless' },\n { fieldId: 'id', normalizer: 'aglynId' },\n]\n\nexport interface StoredCoupon {\n percentOff?: number\n enabled?: boolean\n redemptions?: number\n maxRedemptions?: number\n expiresAtMs?: number\n createdAt?: unknown\n}\n\nexport function couponRecord(id: string, stored: StoredCoupon): Record<string, unknown> {\n return {\n id,\n code: id,\n percentOff: stored.percentOff ?? null,\n maxRedemptions: stored.maxRedemptions ?? null,\n expiresAt: iso(stored.expiresAtMs),\n active: stored.enabled !== false,\n redemptions: stored.redemptions ?? 0,\n createdAt: iso(stored.createdAt),\n }\n}\n\n/** A coupon's document from its changes, as the coupons card writes one, or the refusal. */\nexport function couponWrite(\n current: StoredCoupon | null,\n changes: Readonly<Record<string, unknown>>,\n): { doc: Record<string, unknown> } | { problem: string } {\n const doc: Record<string, unknown> = current ? { ...current } : { enabled: false, redemptions: 0 }\n if ('percentOff' in changes) doc['percentOff'] = Math.round(Number(changes['percentOff']))\n if ('maxRedemptions' in changes) {\n const limit = Number(changes['maxRedemptions'])\n doc['maxRedemptions'] = changes['maxRedemptions'] === null || !Number.isFinite(limit) ? null : Math.max(1, Math.round(limit))\n }\n if ('expiresAt' in changes) doc['expiresAtMs'] = msOf(changes['expiresAt'])\n if ('active' in changes) doc['enabled'] = changes['active'] === true\n const pct = Number(doc['percentOff'])\n if (!(pct > 0 && pct <= 100)) return { problem: 'A coupon takes 1 to 100 percent off.' }\n return { doc }\n}\n\n/*==========================================\n * GIFT CARDS\n *=========================================*/\n\n/*\n * A GIFT CARD IMPORT ISSUES CARDS (AGL-3551). A row is never written as a\n * balance: each one the dry run passes is issued through the same path as\n * the Gift cards card's Issue (`issueGiftCard`), so its amount is bounded,\n * its code is never overwritten and its activity line is written.\n *\n * - The plan mints the code a row will carry — the file's own, a new one for\n * a blank cell, or a new one for a row whose code another card holds and\n * whose Conflicts choice is \"create a new record\" — so the dry run shows\n * every card exactly as it will be issued.\n * - A row whose code another card holds and whose choice is \"update\" is\n * refused: a file never changes a card. \"Skip\" leaves the card as it is.\n * - Every card the dry run passes adds to a total the person types back on\n * the wizard's Confirm step (`GIFT_CARD_CONFIRM_STEP_ID`). The server reads\n * the typed total from `extras` and issues nothing unless it is exactly\n * the total of the cards about to be issued.\n */\n\nexport const GIFT_CARD_TRANSFER_FIELDS: readonly TransferField[] = [\n {\n id: 'code',\n label: 'Code',\n group: 'card',\n type: 'text',\n matchKey: true,\n aliases: ['gift card code', 'card code', 'gift card number', 'card number'],\n description:\n 'The card’s code, which spends its balance: keep the file as safe as the cards. On import, a blank code gets a new one.',\n },\n {\n id: 'balance',\n label: 'Balance',\n group: 'card',\n type: 'currency',\n aliases: ['amount', 'value', 'current balance', 'remaining balance', 'balance remaining'],\n description: 'On import, what the card is issued for, in US dollars — the balance it carries over.',\n },\n {\n id: 'currency',\n label: 'Currency',\n group: 'card',\n type: 'text',\n aliases: ['currency code'],\n description: 'Optional. Cards are held in US dollars; a row in another currency is refused, never converted.',\n },\n { id: 'initial', label: 'Issued for', group: 'card', type: 'number', readOnly: true },\n { id: 'status', label: 'Status', group: 'card', type: 'text', readOnly: true, description: 'Active, Used up, Frozen or Voided.' },\n {\n id: 'recipientEmail',\n label: 'Recipient email',\n group: 'card',\n type: 'email',\n aliases: ['email', 'customer email', 'recipient'],\n },\n { id: 'orderId', label: 'Order ID', group: 'card', type: 'text', readOnly: true, description: 'Blank for a card issued by hand.' },\n { id: 'note', label: 'Note', group: 'card', type: 'text', aliases: ['notes', 'message'] },\n { id: 'issuedAt', label: 'Issued', group: 'card', type: 'datetime', readOnly: true },\n { id: 'lastUsedAt', label: 'Last used', group: 'card', type: 'datetime', readOnly: true },\n]\n\n/** A card is found by its code, which is its ID. */\nexport const GIFT_CARD_MATCH_KEYS: readonly MatchKeySpec[] = [\n { fieldId: 'code', normalizer: 'caseless' },\n { fieldId: 'id', normalizer: 'aglynId' },\n]\n\n/** The fields an issued card's undo entry holds: any of them moving means the card was spent. */\nexport const GIFT_CARD_UNDO_FIELDS = ['balance', 'status', 'lastUsedAt'] as const\n\nexport type StoredGiftCard = HostGiftCard & {\n initialCents?: number\n recipientEmail?: string | null\n orderId?: string | null\n note?: string\n createdAtMs?: number\n lastUsedAtMs?: number\n importJobId?: string\n importRow?: number\n}\n\nexport function giftCardRecord(id: string, stored: StoredGiftCard): Record<string, unknown> {\n const balance = Number(stored.balanceCents ?? 0)\n return {\n id,\n code: id,\n balance: dollars(balance),\n currency: GIFT_CARD_CURRENCY,\n initial: dollars(stored.initialCents),\n status: stored.voidedAtMs ? 'Voided' : stored.frozenAtMs ? 'Frozen' : balance > 0 ? 'Active' : 'Used up',\n recipientEmail: stored.recipientEmail ?? null,\n orderId: stored.orderId ?? null,\n note: stored.note ?? null,\n issuedAt: iso(stored.createdAtMs),\n lastUsedAt: iso(stored.lastUsedAtMs),\n }\n}\n\n/** Dollars and cents as a person reads them: `$1,250.00`. */\nexport function giftCardMoney(amountCents: number): string {\n return `$${(amountCents / 100).toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`\n}\n\n/** A total as a person types it (`1250`, `$1,250.00`), in cents; `null` for anything else. */\nexport function typedDollarsToCents(typed: unknown): number | null {\n const body = String(typed ?? '')\n .trim()\n .replace(/^\\$|^usd\\s*/i, '')\n .replace(/\\s*usd$/i, '')\n .replace(/,/g, '')\n .trim()\n if (!/^\\d+(\\.\\d{1,2})?$/.test(body)) return null\n return Math.round(Number(body) * 100)\n}\n\n/** The Confirm step's answer. */\nexport interface GiftCardConfirmation {\n /** The total the person typed, in cents. */\n totalCents: number\n /** Email each card's recipient their code as it is issued. */\n email: boolean\n}\n\n/** The Confirm step's answer from `extras`, or `null` for none: a total is a whole number of cents. */\nexport function readGiftCardConfirmation(\n extras: Readonly<Record<string, unknown>> | undefined,\n): GiftCardConfirmation | null {\n const value = extras?.[GIFT_CARD_CONFIRM_STEP_ID]\n if (!value || typeof value !== 'object') return null\n const totalCents = (value as Record<string, unknown>)['totalCents']\n if (typeof totalCents !== 'number' || !Number.isInteger(totalCents) || totalCents <= 0) return null\n return { totalCents, email: (value as Record<string, unknown>)['email'] === true }\n}\n\n/** The card one planned row issues, as the plan decided it. */\nexport interface GiftCardRowPlan {\n /** The code the card is issued under. */\n code: string\n /** The file's code was taken, and the person chose a new one. */\n newCode: boolean\n /** The file named no code, so one was made. */\n madeCode: boolean\n amountCents: number\n recipientEmail: string | null\n note: string | null\n /** Why the row issues nothing; the `gift-card-issuable` invariant fails it. */\n problem?: string\n /** What every card this import issues adds up to. */\n totalCents: number\n /** Whether the person typed exactly that total on the Confirm step. */\n confirmed: boolean\n}\n\nexport type GiftCardPlannedRow = PlannedTransferRow & { giftCard?: GiftCardRowPlan }\n\n/** A money cell in cents and its currency: the derived amount, or a number as dollars. */\nfunction giftCardAmount(value: unknown): { cents: number; currency: string } | null {\n if (value === null || value === undefined || value === '') return null\n if (typeof value === 'object' && 'amountMinor' in (value as object)) {\n const amount = value as { amountMinor: number; currency?: string }\n return { cents: Math.round(Number(amount.amountMinor)), currency: text(amount.currency).toUpperCase() || GIFT_CARD_CURRENCY }\n }\n const number = Number(value)\n return Number.isFinite(number) ? { cents: Math.round(number * 100), currency: GIFT_CARD_CURRENCY } : null\n}\n\n/** The card a row's changes issue, or the sentence refusing it. */\nexport function giftCardIssueOf(\n changes: Readonly<Record<string, unknown>>,\n code: { value: string; fromFile: boolean },\n): Omit<GiftCardRowPlan, 'newCode' | 'madeCode' | 'totalCents' | 'confirmed'> {\n const recipientEmail = text(changes['recipientEmail']).toLowerCase().slice(0, 200) || null\n const note = text(changes['note']).slice(0, 200) || null\n const base = { code: code.value, amountCents: 0, recipientEmail, note }\n const codeProblem = code.fromFile ? giftCardCodeProblem(code.value) : null\n if (codeProblem) return { ...base, problem: codeProblem }\n const amount = giftCardAmount(changes['balance'])\n if (!amount) return { ...base, problem: 'Say what the card is issued for in the Balance column.' }\n const named = text(changes['currency']).toUpperCase()\n for (const currency of [amount.currency, named].filter(Boolean)) {\n if (currency !== GIFT_CARD_CURRENCY) {\n return { ...base, problem: `Gift cards are held in US dollars; ${currency} is not converted.` }\n }\n }\n const amountProblem = giftCardAmountProblem(amount.cents)\n if (amountProblem) return { ...base, problem: amountProblem }\n return { ...base, amountCents: amount.cents }\n}\n\n/**\n * The core's plan for a gift card file, made into the cards it issues: each\n * create carrying the card it issues ({@link GiftCardRowPlan}), each row\n * that would change an existing card refused, the total of every card\n * counted, and a `screening` warning stating that total — and, when the\n * Confirm step's answer is missing or names another total, that nothing is\n * issued until it is confirmed.\n */\nexport function planGiftCardRows(\n plan: TransferPlan,\n input: {\n confirmation: GiftCardConfirmation | null\n mintCode: () => string\n /** The file's codes a card on the site already holds, however the file spelled them. */\n taken?: ReadonlySet<string>\n },\n): TransferPlan {\n const issuing = new Map<string, number>()\n const rows = plan.rows.map((row): GiftCardPlannedRow => {\n if (row.verdict === 'update' || row.verdict === 'unchanged') {\n const code = row.recordId ?? ''\n return {\n ...row,\n verdict: 'update',\n diff: [],\n giftCard: {\n code,\n newCode: false,\n madeCode: false,\n amountCents: 0,\n recipientEmail: null,\n note: null,\n problem:\n `A gift card with the code ${code} already exists, and a file never changes a card. ` +\n 'On the Conflicts step, skip this row, or create a new record to issue it under a new code.',\n totalCents: 0,\n confirmed: false,\n },\n }\n }\n if (row.verdict !== 'create') return row\n const changes = rowChanges(row)\n const fileCode = giftCardCodeOf(changes['code'])\n // A create for a row that matched a card is the person's \"create a new\n // record\": the card it names keeps its code, and this one gets another.\n const newCode = Boolean(fileCode) && row.match.kind !== 'new'\n const madeCode = !fileCode\n const code = newCode || madeCode ? input.mintCode() : fileCode\n const fromFile = !newCode && !madeCode\n let issue = giftCardIssueOf(changes, { value: code, fromFile })\n const earlier = issuing.get(code)\n if (!issue.problem && fromFile && input.taken?.has(code)) {\n issue = { ...issue, problem: `A gift card with the code ${code} already exists, and a file never changes a card.` }\n } else if (!issue.problem && earlier !== undefined) {\n issue = { ...issue, problem: `Row ${earlier + 1} issues the code ${code} already.` }\n }\n if (!issue.problem) issuing.set(code, row.index)\n const diff: TransferFieldChange[] = [\n ...row.diff.filter((change) => change.fieldId !== 'code'),\n { fieldId: 'code', before: null, after: code, mode: 'overwrite', source: 'default', rule: 'written' },\n ]\n return { ...row, diff, giftCard: { ...issue, newCode, madeCode, totalCents: 0, confirmed: false } }\n })\n\n const issued = rows.filter(\n (row): row is GiftCardPlannedRow & { giftCard: GiftCardRowPlan } =>\n row.verdict === 'create' && Boolean(row.giftCard) && !row.giftCard?.problem,\n )\n const totalCents = issued.reduce((sum, row) => sum + row.giftCard.amountCents, 0)\n const confirmed = input.confirmation?.totalCents === totalCents\n for (const row of rows) {\n if (row.giftCard) row.giftCard = { ...row.giftCard, totalCents, confirmed }\n }\n\n const warnings = plan.warnings.filter((warning) => warning.class !== 'screening')\n if (issued.length) {\n const samples: TransferWarningSample[] = [\n {\n row: TRANSFER_FILE_SAMPLE_ROW,\n fieldId: 'balance',\n value: giftCardMoney(totalCents),\n detail: `Issues ${issued.length.toLocaleString('en-US')} gift card${issued.length === 1 ? '' : 's'} worth ${giftCardMoney(totalCents)} in total.`,\n },\n ]\n if (!confirmed) {\n samples.push({\n row: TRANSFER_FILE_SAMPLE_ROW,\n detail: input.confirmation\n ? `The total confirmed was ${giftCardMoney(input.confirmation.totalCents)}, not ${giftCardMoney(totalCents)}: no card is issued until the total is confirmed again on the Confirm step.`\n : 'The total has not been confirmed: no card is issued until it is typed on the Confirm step.',\n })\n }\n warnings.push({\n class: 'screening',\n count: issued.length,\n rows: issued.length,\n fieldIds: ['balance'],\n samples,\n requiresAcknowledgement: true,\n })\n }\n const summary: TransferPlanSummary = { create: 0, update: 0, unchanged: 0, skip: 0, fail: 0, total: rows.length }\n for (const row of rows) summary[row.verdict] += 1\n return {\n rows,\n summary,\n warnings,\n acknowledgementsRequired: warnings.filter((warning) => warning.requiresAcknowledgement).map((warning) => warning.class),\n }\n}\n\n/*==========================================\n * CATEGORIES\n *=========================================*/\n\nexport const CATEGORY_TRANSFER_FIELDS: readonly TransferField[] = [\n { id: 'name', label: 'Name', group: 'category', type: 'text', aliases: ['category', 'category name', 'title'] },\n {\n id: 'slug',\n label: 'Slug',\n group: 'category',\n type: 'text',\n readOnly: true,\n matchKey: true,\n aliases: ['handle'],\n description: 'Made from the name, as the console makes it; a file finds a category by it.',\n },\n {\n id: 'parent',\n label: 'Parent',\n group: 'category',\n type: 'text',\n aliases: ['parent category', 'parent slug'],\n description: 'The parent category’s slug or name; blank for a top-level category.',\n },\n { id: 'order', label: 'Position', group: 'category', type: 'integer', aliases: ['sort order', 'order'] },\n]\n\nexport const CATEGORY_MATCH_KEYS: readonly MatchKeySpec[] = [\n { fieldId: 'slug', normalizer: 'slug' },\n { fieldId: 'name', normalizer: 'name' },\n { fieldId: 'id', normalizer: 'aglynId' },\n]\n\nexport interface StoredCategory {\n name?: string\n slug?: string\n parentId?: string | null\n order?: number\n}\n\nexport function categoryRecord(\n id: string,\n stored: StoredCategory,\n slugs: ReadonlyMap<string, string> = new Map(),\n): Record<string, unknown> {\n return {\n id,\n name: stored.name ?? null,\n slug: stored.slug ?? null,\n parent: stored.parentId ? (slugs.get(stored.parentId) ?? stored.parentId) : null,\n order: typeof stored.order === 'number' ? stored.order : null,\n }\n}\n\n/** Every category's slug, name and parent, by id: what a parent is resolved against. */\nexport type CategoryIndex = Map<string, StoredCategory>\n\n/** The category a parent cell names — by id, slug, then name — or `null`. */\nexport function resolveCategoryParent(index: CategoryIndex, value: unknown): string | null {\n const wanted = text(value)\n if (!wanted) return null\n if (index.has(wanted)) return wanted\n const slug = commerceSlug(wanted)\n for (const [id, category] of index) if (category.slug === slug) return id\n const name = wanted.toLowerCase()\n for (const [id, category] of index) if (text(category.name).toLowerCase() === name) return id\n return null\n}\n\n/**\n * A category's document from its changes: the name and the slug made from\n * it, the parent resolved — never itself or one of its own descendants —\n * and the position. A parent the site does not have is refused, not\n * guessed.\n */\nexport function categoryWrite(\n id: string,\n current: StoredCategory | null,\n changes: Readonly<Record<string, unknown>>,\n index: CategoryIndex,\n): { doc: Record<string, unknown> } | { problem: string } {\n const doc: Record<string, unknown> = current ? { ...current } : { parentId: null }\n if ('name' in changes) {\n const name = text(changes['name']).slice(0, 80)\n if (!name) return { problem: 'A category needs a name.' }\n doc['name'] = name\n doc['slug'] = commerceSlug(name) || id\n }\n if (!text(doc['name'])) return { problem: 'A category needs a name.' }\n if ('parent' in changes) {\n if (isBlankTransferValue(changes['parent'])) doc['parentId'] = null\n else {\n const parentId = resolveCategoryParent(index, changes['parent'])\n if (!parentId) return { problem: `No category \"${text(changes['parent'])}\" to put it under.` }\n for (let at: string | null = parentId, steps = 0; at && steps < 100; steps += 1) {\n if (at === id) return { problem: 'A category cannot sit under itself or one of its own.' }\n at = index.get(at)?.parentId ?? null\n }\n doc['parentId'] = parentId\n }\n }\n if ('order' in changes) {\n const order = Number(changes['order'])\n doc['order'] = changes['order'] === null || !Number.isFinite(order) ? null : Math.round(order)\n }\n return { doc }\n}\n"],"names":["buildTransferPlan","isBlankTransferValue","TRANSFER_FILE_SAMPLE_ROW","TRANSFER_SYSTEM_GROUP","commerceSlug","GIFT_CARD_CONFIRM_STEP_ID","GIFT_CARD_CURRENCY","giftCardAmountProblem","giftCardCodeOf","giftCardCodeProblem","ORDER_CHANNEL_LABELS","ORDER_STATUS_LABELS","liftLegacyOrder","orderShippingRecord","iso","ms","time","toMillis","toDate","getTime","NaN","Number","isFinite","Date","toISOString","dollars","cents","value","undefined","Math","round","text","String","trim","rowChanges","row","Object","fromEntries","diff","map","change","fieldId","after","planWithCreateRequired","input","required","fields","field","includes","id","ORDER_SHIPPING_FIELDS","label","group","type","readOnly","description","ORDER_SHIPPING_FIELD_IDS","ORDER_TRANSFER_FIELDS","system","ORDER_TRANSFER_GROUPS","addressLine","address","parts","name","line1","line2","city","state","postalCode","country","filter","Boolean","length","join","orderRecord","stored","productNames","weights","lineItems","totals","lifted","first","productId","totalCents","amountCents","refundedCents","number","date","createdAt","createdAtMs","status","channel","customerEmail","customerName","product","items","line","quantity","variantLabel","sku","itemCount","reduce","sum","subtotal","itemsCents","shipping","shippingCents","tax","taxCents","discount","discountCents","total","fee","feeCents","refunded","net","coupon","couponCode","shippingAddress","billingAddress","note","dispute","paymentIntentId","DISCOUNT_KIND_PICKLIST","DISCOUNT_KIND_LABELS","percent","fixed","free_shipping","DISCOUNT_KIND_SPEC","restricted","standardValues","entries","defaultValueId","discountKindOf","key","toLowerCase","found","find","DISCOUNT_TRANSFER_FIELDS","aliases","picklistId","DISCOUNT_MATCH_KEYS","normalizer","promotionCode","max","toUpperCase","replace","slice","amountMinor","msOf","parse","discountRecord","code","kind","percentOff","valuePct","amountOff","valueCents","minimumSubtotal","minSubtotalCents","productIds","maxRedemptions","startsAt","startAtMs","endsAt","endAtMs","active","enabled","redemptions","discountWrite","current","changes","doc","has","ids","split","Set","limit","problem","pct","start","end","COUPON_TRANSFER_FIELDS","matchKey","COUPON_MATCH_KEYS","couponRecord","expiresAt","expiresAtMs","couponWrite","GIFT_CARD_TRANSFER_FIELDS","GIFT_CARD_MATCH_KEYS","GIFT_CARD_UNDO_FIELDS","giftCardRecord","balance","balanceCents","currency","initial","initialCents","voidedAtMs","frozenAtMs","recipientEmail","orderId","issuedAt","lastUsedAt","lastUsedAtMs","giftCardMoney","toLocaleString","minimumFractionDigits","maximumFractionDigits","typedDollarsToCents","typed","body","test","readGiftCardConfirmation","extras","isInteger","email","giftCardAmount","amount","giftCardIssueOf","base","codeProblem","fromFile","named","amountProblem","planGiftCardRows","plan","issuing","Map","rows","verdict","recordId","giftCard","newCode","madeCode","confirmed","fileCode","match","mintCode","issue","earlier","get","taken","set","index","before","mode","source","rule","issued","confirmation","warnings","warning","class","samples","detail","push","count","fieldIds","requiresAcknowledgement","summary","create","update","unchanged","skip","fail","acknowledgementsRequired","CATEGORY_TRANSFER_FIELDS","CATEGORY_MATCH_KEYS","categoryRecord","slugs","slug","parent","parentId","order","resolveCategoryParent","wanted","category","categoryWrite","at","steps"],"mappings":"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"}
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import { type PlannedTransferRow, type TransferChunk, type TransferUndoSnapshot } from '@aglyn/aglyn/data-transfer';
|
|
18
18
|
import type { PluginTransferResource, TransferApplyResult, TransferApplyWriter, TransferResourceContext, TransferRevertDecisions, TransferRevertResult } from '@aglyn/aglyn/plugin-manager/plugin-transfer-resources';
|
|
19
|
+
import type { ProductWeights } from '../model/order-shipping-export';
|
|
19
20
|
import { type CategoryIndex } from './records-transfer';
|
|
20
21
|
import { type CommerceListSource, type Firestore } from './server-common';
|
|
21
22
|
export type Doc = Record<string, unknown>;
|
|
@@ -28,13 +29,19 @@ export interface RecordsSpec {
|
|
|
28
29
|
record(id: string, data: Doc, extra: RecordsExtra): Record<string, unknown>;
|
|
29
30
|
/** The values a document is found by, per match key. */
|
|
30
31
|
matchValues(id: string, data: Doc): Record<string, unknown>;
|
|
31
|
-
/**
|
|
32
|
-
|
|
32
|
+
/**
|
|
33
|
+
* What a lookup or export reads once per call, besides the documents. An
|
|
34
|
+
* export names the fields it writes, so a read only some fields need is
|
|
35
|
+
* skipped when none of them is asked for.
|
|
36
|
+
*/
|
|
37
|
+
extra?(firestore: Firestore, ctx: TransferResourceContext, docs: readonly FirebaseFirestore.DocumentSnapshot[], fieldIds?: readonly string[]): Promise<RecordsExtra>;
|
|
33
38
|
/** Finds documents by a key's values (at most 30); the id key is read directly. */
|
|
34
39
|
find?: Record<string, (collection: Collection, values: string[]) => FirebaseFirestore.Query>;
|
|
35
40
|
}
|
|
36
41
|
export type RecordsExtra = {
|
|
37
42
|
productNames?: Record<string, string>;
|
|
43
|
+
/** Each product's variant weights in grams, for the shipping columns (AGL-3613). */
|
|
44
|
+
weights?: ProductWeights;
|
|
38
45
|
categories?: CategoryIndex;
|
|
39
46
|
};
|
|
40
47
|
/** The reading hooks every records resource shares: count, a page of an export, and the lookup. */
|
|
@@ -44,7 +44,7 @@ async function readPage(spec, ctx, cursor, fieldIds, options, firestore) {
|
|
|
44
44
|
refuseFilterWithout(spec, options);
|
|
45
45
|
const pageSize = Math.max(1, Math.min(500, (_ref = options == null ? void 0 : options.pageSize) != null ? _ref : 500));
|
|
46
46
|
const page = await readSourcePage(firestore, sourceFor(spec, firestore, ctx), cursor, options, pageSize);
|
|
47
|
-
const extra = await ((_spec_extra = spec.extra) != null ? _spec_extra : noExtra)(firestore, ctx, page.docs);
|
|
47
|
+
const extra = await ((_spec_extra = spec.extra) != null ? _spec_extra : noExtra)(firestore, ctx, page.docs, fieldIds);
|
|
48
48
|
const rows = page.docs.map((doc)=>{
|
|
49
49
|
var _doc_data;
|
|
50
50
|
const record = spec.record(doc.id, (_doc_data = doc.data()) != null ? _doc_data : {}, extra);
|
|
@@ -153,20 +153,37 @@ async function lookup(spec, ctx, requests, firestore) {
|
|
|
153
153
|
}
|
|
154
154
|
/*==========================================
|
|
155
155
|
* ORDERS — exported only
|
|
156
|
-
*=========================================*/
|
|
156
|
+
*=========================================*/ /**
|
|
157
|
+
* The orders list's query, with the one predicate the list itself never
|
|
158
|
+
* shows: `requiresShipping`, which the orders card's Export for shipping
|
|
159
|
+
* asks (AGL-3613) and every creator stamps.
|
|
160
|
+
*/ const ORDER_EXPORT_QUERY = _extends({}, ORDER_LIST_QUERY, {
|
|
161
|
+
fields: [
|
|
162
|
+
...ORDER_LIST_QUERY.fields,
|
|
163
|
+
{
|
|
164
|
+
column: 'requiresShipping',
|
|
165
|
+
kind: 'exact',
|
|
166
|
+
path: 'requiresShipping',
|
|
167
|
+
operators: [
|
|
168
|
+
'equals'
|
|
169
|
+
]
|
|
170
|
+
}
|
|
171
|
+
]
|
|
172
|
+
});
|
|
173
|
+
const ORDERS = {
|
|
157
174
|
collection: (firestore, ctx)=>hostRefOf(firestore, ctx).collection('orders'),
|
|
158
175
|
source: {
|
|
159
|
-
declaration:
|
|
176
|
+
declaration: ORDER_EXPORT_QUERY,
|
|
160
177
|
order: {
|
|
161
178
|
path: 'createdAtMs',
|
|
162
179
|
direction: 'desc'
|
|
163
180
|
}
|
|
164
181
|
},
|
|
165
|
-
record: (id, data, extra)=>orderRecord(id, data, extra.productNames),
|
|
182
|
+
record: (id, data, extra)=>orderRecord(id, data, extra.productNames, extra.weights),
|
|
166
183
|
matchValues: (id)=>({
|
|
167
184
|
id
|
|
168
185
|
}),
|
|
169
|
-
/** A legacy flat row is named by its product, read for that page alone. */ async extra (firestore, ctx, docs) {
|
|
186
|
+
/** A legacy flat row is named by its product, read for that page alone. */ async extra (firestore, ctx, docs, fieldIds) {
|
|
170
187
|
const ids = [
|
|
171
188
|
...new Set(docs.filter((doc)=>{
|
|
172
189
|
var _doc_get;
|
|
@@ -180,11 +197,45 @@ async function lookup(spec, ctx, requests, firestore) {
|
|
|
180
197
|
if (doc.exists && doc.get('name')) productNames[doc.id] = String(doc.get('name'));
|
|
181
198
|
}
|
|
182
199
|
}
|
|
183
|
-
|
|
200
|
+
// The page's products are read for their weights only when a weight
|
|
201
|
+
// column is written (AGL-3613) — never for an ordinary orders export.
|
|
202
|
+
const wantsWeight = (fieldIds != null ? fieldIds : []).some((fieldId)=>fieldId === 'weightOz' || fieldId === 'weightLb' || fieldId === 'weightUnit');
|
|
203
|
+
return _extends({
|
|
184
204
|
productNames
|
|
185
|
-
}
|
|
205
|
+
}, wantsWeight ? {
|
|
206
|
+
weights: await productWeightsFor(firestore, ctx, docs)
|
|
207
|
+
} : {});
|
|
186
208
|
}
|
|
187
209
|
};
|
|
210
|
+
/**
|
|
211
|
+
* The products a page of orders names, by variant weight in grams. One
|
|
212
|
+
* `getAll` per hundred products.
|
|
213
|
+
*/ async function productWeightsFor(firestore, ctx, docs) {
|
|
214
|
+
const ids = [
|
|
215
|
+
...new Set(docs.flatMap((doc)=>{
|
|
216
|
+
var _doc_get;
|
|
217
|
+
return ((_doc_get = doc.get('lineItems')) != null ? _doc_get : []).map((line)=>typeof (line == null ? void 0 : line.productId) === 'string' ? line.productId : '').filter((id)=>id && !id.includes('/'));
|
|
218
|
+
}))
|
|
219
|
+
];
|
|
220
|
+
const weights = {};
|
|
221
|
+
const products = hostRefOf(firestore, ctx).collection('products');
|
|
222
|
+
for(let at = 0; at < ids.length; at += 100){
|
|
223
|
+
for (const doc of (await firestore.getAll(...ids.slice(at, at + 100).map((id)=>products.doc(id))))){
|
|
224
|
+
var _doc_get;
|
|
225
|
+
if (!doc.exists) continue;
|
|
226
|
+
const variants = (_doc_get = doc.get('variants')) != null ? _doc_get : [];
|
|
227
|
+
const byVariant = {};
|
|
228
|
+
for (const [index, variant] of variants.entries()){
|
|
229
|
+
const grams = Number(variant == null ? void 0 : variant.weightGrams);
|
|
230
|
+
if (!Number.isFinite(grams) || grams <= 0) continue;
|
|
231
|
+
if (variant == null ? void 0 : variant.id) byVariant[variant.id] = grams;
|
|
232
|
+
if (index === 0) byVariant[''] = grams;
|
|
233
|
+
}
|
|
234
|
+
if (Object.keys(byVariant).length) weights[doc.id] = byVariant;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return weights;
|
|
238
|
+
}
|
|
188
239
|
export const ordersTransfer = exportOnly(ORDERS, 'orders', 'Orders are exported, never imported: an order is the record of a sale, written by checkout, the register or a paid draft.');
|
|
189
240
|
/*==========================================
|
|
190
241
|
* IMPORTABLE RECORDS
|