@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
|
@@ -0,0 +1,938 @@
|
|
|
1
|
+
import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
2
|
+
/**
|
|
3
|
+
* @license
|
|
4
|
+
* Copyright 2026 Aglyn LLC
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this file except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*/ import * as Aglyn from "@aglyn/aglyn/server";
|
|
18
|
+
import { createResourceUid } from "@aglyn/aglyn/app-utils/create-resource-uid";
|
|
19
|
+
import { findUserByUidAcrossPools, firebaseAdmin, getOrgForHost, hostSendingIdentity, meterHostEmail, notifyHostManagers, renderHostEmailWithTokens } from "@aglyn/tenant-data-admin";
|
|
20
|
+
import { isEmailConfigured, sendEmail } from "@aglyn/shared-util-email";
|
|
21
|
+
import * as CommerceModel from "../model/index.js";
|
|
22
|
+
import { RETURN_APPROVED_EVENT, RETURN_DECLINED_EVENT, RETURN_RECEIVED_EVENT, RETURN_REFUNDED_EVENT, RETURN_REQUESTED_EVENT } from "../model/order-events.js";
|
|
23
|
+
import { raiseOrderEvent, stageOrderEvent } from "./order-events.js";
|
|
24
|
+
import { orderStatusUrl, verifyOrderStatusToken } from "./order-status-token.js";
|
|
25
|
+
import { readActiveMemberSession } from "./membership.js";
|
|
26
|
+
import { resolveTrackedRestockLines } from "./restock-flag.js";
|
|
27
|
+
import { refundHandler } from "./refund.js";
|
|
28
|
+
const hostRefFor = (firestore, hostId)=>firestore.collection('hosts').doc(hostId);
|
|
29
|
+
const isId = (value)=>Boolean(value) && value.length <= 200 && !/^__.*__$/.test(value) && !value.includes('/');
|
|
30
|
+
/** The store's settings document and what the return emails need from the host. */ async function readStore(firestore, hostId) {
|
|
31
|
+
var _ref, _ref1, _settings_currency;
|
|
32
|
+
const hostRef = hostRefFor(firestore, hostId);
|
|
33
|
+
const [host, store] = await Promise.all([
|
|
34
|
+
hostRef.get().catch(()=>null),
|
|
35
|
+
hostRef.collection('settings').doc('store').get().catch(()=>null)
|
|
36
|
+
]);
|
|
37
|
+
const settings = (_ref = store == null ? void 0 : store.data()) != null ? _ref : {};
|
|
38
|
+
return {
|
|
39
|
+
host: (_ref1 = host == null ? void 0 : host.data()) != null ? _ref1 : {},
|
|
40
|
+
returnSettings: CommerceModel.readReturnSettings(settings['returns']),
|
|
41
|
+
currency: String((_settings_currency = settings['currency']) != null ? _settings_currency : 'USD').toUpperCase()
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function money(cents, currency) {
|
|
45
|
+
try {
|
|
46
|
+
return new Intl.NumberFormat('en-US', {
|
|
47
|
+
style: 'currency',
|
|
48
|
+
currency
|
|
49
|
+
}).format(cents / 100);
|
|
50
|
+
} catch (unused) {
|
|
51
|
+
return `$${(cents / 100).toFixed(2)}`;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/** The return as an event carries it. */ function returnEventView(id, entry) {
|
|
55
|
+
var _entry_refundCents;
|
|
56
|
+
return {
|
|
57
|
+
id,
|
|
58
|
+
status: entry.status,
|
|
59
|
+
lines: entry.lines.map((line)=>_extends({}, line)),
|
|
60
|
+
refundCents: (_entry_refundCents = entry.refundCents) != null ? _entry_refundCents : null,
|
|
61
|
+
restock: entry.restock ? entry.restock.lines.map((line)=>_extends({}, line)) : null
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/** "1× House Blend — Arrived damaged", one per line. */ function returnItemsText(order, entry) {
|
|
65
|
+
return entry.lines.map((line)=>{
|
|
66
|
+
var _ref, _CommerceModel_RETURN_REASON_LABELS_line_reason;
|
|
67
|
+
var _order_lineItems_line_lineItemId, _order_lineItems;
|
|
68
|
+
return `${line.quantity}× ${(_ref = (_order_lineItems = order.lineItems) == null ? void 0 : (_order_lineItems_line_lineItemId = _order_lineItems[line.lineItemId]) == null ? void 0 : _order_lineItems_line_lineItemId.name) != null ? _ref : `line ${line.lineItemId}`} — ${(_CommerceModel_RETURN_REASON_LABELS_line_reason = CommerceModel.RETURN_REASON_LABELS[line.reason]) != null ? _CommerceModel_RETURN_REASON_LABELS_line_reason : line.reason}`;
|
|
69
|
+
}).join('\n');
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Opens a return. A buyer's starts `requested`; a merchant's starts
|
|
73
|
+
* `approved`, since the merchant asking is the approval.
|
|
74
|
+
*/ export async function openReturn(request) {
|
|
75
|
+
var _request_now, _request_note;
|
|
76
|
+
const firestore = firebaseAdmin.app().firestore();
|
|
77
|
+
const hostRef = hostRefFor(firestore, request.hostId);
|
|
78
|
+
const orderRef = hostRef.collection('orders').doc(request.orderId);
|
|
79
|
+
const { returnSettings } = await readStore(firestore, request.hostId);
|
|
80
|
+
const now = (_request_now = request.now) != null ? _request_now : Date.now();
|
|
81
|
+
const note = String((_request_note = request.note) != null ? _request_note : '').trim().slice(0, CommerceModel.RETURN_NOTE_MAX);
|
|
82
|
+
return firestore.runTransaction(async (transaction)=>{
|
|
83
|
+
var _orderSnapshot_data, _order_customerEmail, _order_customerName;
|
|
84
|
+
const orderSnapshot = await transaction.get(orderRef);
|
|
85
|
+
if (!orderSnapshot.exists) return {
|
|
86
|
+
outcome: 'no_such_order'
|
|
87
|
+
};
|
|
88
|
+
const existing = await transaction.get(hostRef.collection('returns').where('orderId', '==', request.orderId));
|
|
89
|
+
const order = CommerceModel.liftLegacyOrder((_orderSnapshot_data = orderSnapshot.data()) != null ? _orderSnapshot_data : {});
|
|
90
|
+
const verdict = CommerceModel.validateReturnRequest({
|
|
91
|
+
order,
|
|
92
|
+
existing: existing.docs.map((entry)=>entry.data()),
|
|
93
|
+
settings: returnSettings,
|
|
94
|
+
lines: request.lines,
|
|
95
|
+
by: request.by,
|
|
96
|
+
now
|
|
97
|
+
});
|
|
98
|
+
if (!('lines' in verdict)) {
|
|
99
|
+
return {
|
|
100
|
+
outcome: 'refused',
|
|
101
|
+
message: CommerceModel.describeReturnRequestProblem(verdict)
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
const status = request.by === 'merchant' ? 'approved' : 'requested';
|
|
105
|
+
const entry = _extends({
|
|
106
|
+
orderId: request.orderId,
|
|
107
|
+
orderNumber: CommerceModel.returnOrderNumber(order, request.orderId),
|
|
108
|
+
customerEmail: (_order_customerEmail = order.customerEmail) != null ? _order_customerEmail : null,
|
|
109
|
+
customerName: (_order_customerName = order.customerName) != null ? _order_customerName : null,
|
|
110
|
+
lines: verdict.lines.map((line)=>{
|
|
111
|
+
var _ref;
|
|
112
|
+
var _order_lineItems_line_lineItemId, _order_lineItems;
|
|
113
|
+
return _extends({}, line, {
|
|
114
|
+
name: String((_ref = (_order_lineItems = order.lineItems) == null ? void 0 : (_order_lineItems_line_lineItemId = _order_lineItems[line.lineItemId]) == null ? void 0 : _order_lineItems_line_lineItemId.name) != null ? _ref : '').slice(0, 200)
|
|
115
|
+
});
|
|
116
|
+
}),
|
|
117
|
+
status,
|
|
118
|
+
requestedBy: request.by
|
|
119
|
+
}, note ? request.by === 'buyer' ? {
|
|
120
|
+
customerNote: note
|
|
121
|
+
} : {
|
|
122
|
+
merchantNote: note
|
|
123
|
+
} : {}, {
|
|
124
|
+
timeline: [
|
|
125
|
+
{
|
|
126
|
+
atMs: now,
|
|
127
|
+
event: status,
|
|
128
|
+
detail: `${request.by === 'buyer' ? 'Requested by the buyer' : 'Opened by the store'}: ${CommerceModel.describeReturnLines(order, verdict.lines)}`
|
|
129
|
+
}
|
|
130
|
+
],
|
|
131
|
+
createdAtMs: now,
|
|
132
|
+
updatedAtMs: now
|
|
133
|
+
});
|
|
134
|
+
const returnRef = hostRef.collection('returns').doc(createResourceUid());
|
|
135
|
+
transaction.create(returnRef, entry);
|
|
136
|
+
const orderPatch = {
|
|
137
|
+
timeline: CommerceModel.appendOrderEvent(order, 'return-requested', CommerceModel.describeReturnLines(order, verdict.lines), now)
|
|
138
|
+
};
|
|
139
|
+
transaction.update(orderRef, orderPatch);
|
|
140
|
+
stageOrderEvent(transaction, RETURN_REQUESTED_EVENT, {
|
|
141
|
+
hostId: request.hostId,
|
|
142
|
+
orderId: request.orderId,
|
|
143
|
+
key: `return:${returnRef.id}`,
|
|
144
|
+
order: _extends({}, orderSnapshot.data(), orderPatch),
|
|
145
|
+
extra: {
|
|
146
|
+
return: returnEventView(returnRef.id, entry)
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
// The store opening a return is its approval.
|
|
150
|
+
if (status === 'approved') {
|
|
151
|
+
stageOrderEvent(transaction, RETURN_APPROVED_EVENT, {
|
|
152
|
+
hostId: request.hostId,
|
|
153
|
+
orderId: request.orderId,
|
|
154
|
+
key: `return-approved:${returnRef.id}`,
|
|
155
|
+
order: _extends({}, orderSnapshot.data(), orderPatch),
|
|
156
|
+
extra: {
|
|
157
|
+
return: returnEventView(returnRef.id, entry)
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
return {
|
|
162
|
+
outcome: 'created',
|
|
163
|
+
returnId: returnRef.id,
|
|
164
|
+
entry,
|
|
165
|
+
order
|
|
166
|
+
};
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
const ACTION_TARGET = {
|
|
170
|
+
approve: 'approved',
|
|
171
|
+
decline: 'declined',
|
|
172
|
+
close: 'closed'
|
|
173
|
+
};
|
|
174
|
+
/**
|
|
175
|
+
* Approve, decline, close, a note, or a return label — the writes that move
|
|
176
|
+
* no stock and no money. The transition is re-asked under the write.
|
|
177
|
+
*/ export async function changeReturn(request) {
|
|
178
|
+
var _request_now;
|
|
179
|
+
const firestore = firebaseAdmin.app().firestore();
|
|
180
|
+
const hostRef = hostRefFor(firestore, request.hostId);
|
|
181
|
+
const returnRef = hostRef.collection('returns').doc(request.returnId);
|
|
182
|
+
const now = (_request_now = request.now) != null ? _request_now : Date.now();
|
|
183
|
+
const note = request.merchantNote === undefined ? undefined : String(request.merchantNote).trim().slice(0, CommerceModel.RETURN_NOTE_MAX);
|
|
184
|
+
return firestore.runTransaction(async (transaction)=>{
|
|
185
|
+
var _orderSnapshot_data;
|
|
186
|
+
const snapshot = await transaction.get(returnRef);
|
|
187
|
+
if (!snapshot.exists) return {
|
|
188
|
+
outcome: 'no_such_return'
|
|
189
|
+
};
|
|
190
|
+
const entry = snapshot.data();
|
|
191
|
+
const orderSnapshot = await transaction.get(hostRef.collection('orders').doc(entry.orderId));
|
|
192
|
+
const order = orderSnapshot.exists ? CommerceModel.liftLegacyOrder((_orderSnapshot_data = orderSnapshot.data()) != null ? _orderSnapshot_data : {}) : null;
|
|
193
|
+
const target = ACTION_TARGET[request.action];
|
|
194
|
+
let patch;
|
|
195
|
+
if (target) {
|
|
196
|
+
if (entry.status === target) return {
|
|
197
|
+
outcome: 'already',
|
|
198
|
+
entry
|
|
199
|
+
};
|
|
200
|
+
if (!CommerceModel.canTransitionReturn(entry.status, target)) {
|
|
201
|
+
return {
|
|
202
|
+
outcome: 'refused',
|
|
203
|
+
message: `A return that is ${CommerceModel.RETURN_STATUS_LABELS[entry.status].toLowerCase()} cannot be ${CommerceModel.RETURN_STATUS_LABELS[target].toLowerCase()}`
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
patch = _extends({
|
|
207
|
+
status: target
|
|
208
|
+
}, note !== undefined && note ? {
|
|
209
|
+
merchantNote: note
|
|
210
|
+
} : {}, {
|
|
211
|
+
timeline: CommerceModel.appendReturnEvent(entry, target, note || undefined, now)
|
|
212
|
+
});
|
|
213
|
+
} else if (request.action === 'attach-label') {
|
|
214
|
+
var _label_carrier, _label_trackingNumber, _ref;
|
|
215
|
+
const label = request.label;
|
|
216
|
+
if (!(label == null ? void 0 : label.labelUrl) || !/^https:\/\//i.test(label.labelUrl)) {
|
|
217
|
+
return {
|
|
218
|
+
outcome: 'refused',
|
|
219
|
+
message: 'A return label needs an https link'
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
if (!CommerceModel.returnIsOpen(entry) || entry.status === 'refunded') {
|
|
223
|
+
return {
|
|
224
|
+
outcome: 'refused',
|
|
225
|
+
message: 'This return is finished; a label can no longer be attached'
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
const carrier = String((_label_carrier = label.carrier) != null ? _label_carrier : '').trim().slice(0, 40);
|
|
229
|
+
const trackingNumber = String((_label_trackingNumber = label.trackingNumber) != null ? _label_trackingNumber : '').trim().slice(0, 60);
|
|
230
|
+
const trackingUrl = (_ref = label.trackingUrl && /^https:\/\//i.test(label.trackingUrl) ? label.trackingUrl : null) != null ? _ref : CommerceModel.trackingUrlFor(carrier, trackingNumber);
|
|
231
|
+
patch = {
|
|
232
|
+
returnLabel: _extends({
|
|
233
|
+
carrier,
|
|
234
|
+
trackingNumber,
|
|
235
|
+
labelUrl: String(label.labelUrl).slice(0, 2048)
|
|
236
|
+
}, trackingUrl ? {
|
|
237
|
+
trackingUrl
|
|
238
|
+
} : {}, {
|
|
239
|
+
attachedAtMs: now
|
|
240
|
+
}),
|
|
241
|
+
timeline: CommerceModel.appendReturnEvent(entry, 'label', `${carrier} ${trackingNumber}`.trim() || 'Return label attached', now)
|
|
242
|
+
};
|
|
243
|
+
} else {
|
|
244
|
+
patch = {
|
|
245
|
+
merchantNote: note != null ? note : '',
|
|
246
|
+
timeline: CommerceModel.appendReturnEvent(entry, 'note', note || 'Note cleared', now)
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
transaction.update(returnRef, _extends({}, patch, {
|
|
250
|
+
updatedAtMs: now
|
|
251
|
+
}));
|
|
252
|
+
const changed = _extends({}, entry, patch, {
|
|
253
|
+
updatedAtMs: now
|
|
254
|
+
});
|
|
255
|
+
const event = target === 'approved' ? RETURN_APPROVED_EVENT : target === 'declined' ? RETURN_DECLINED_EVENT : null;
|
|
256
|
+
if (event && orderSnapshot.exists) {
|
|
257
|
+
var _orderSnapshot_data1;
|
|
258
|
+
stageOrderEvent(transaction, event, {
|
|
259
|
+
hostId: request.hostId,
|
|
260
|
+
orderId: entry.orderId,
|
|
261
|
+
key: `return-${target}:${request.returnId}`,
|
|
262
|
+
order: (_orderSnapshot_data1 = orderSnapshot.data()) != null ? _orderSnapshot_data1 : {},
|
|
263
|
+
extra: {
|
|
264
|
+
return: returnEventView(request.returnId, changed)
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
return {
|
|
269
|
+
outcome: 'changed',
|
|
270
|
+
entry: changed,
|
|
271
|
+
order
|
|
272
|
+
};
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* The parcel arrived: the return is `received`, and the units the merchant
|
|
277
|
+
* chose go back on the shelf, at the location they chose. A unit the sale
|
|
278
|
+
* never took off a tracked count (an untracked variant, a deleted product)
|
|
279
|
+
* has nothing to go back to and is left out, as a cancellation leaves it.
|
|
280
|
+
*/ export async function receiveReturn(request) {
|
|
281
|
+
var _request_now, _request_locationId;
|
|
282
|
+
const firestore = firebaseAdmin.app().firestore();
|
|
283
|
+
const hostRef = hostRefFor(firestore, request.hostId);
|
|
284
|
+
const returnRef = hostRef.collection('returns').doc(request.returnId);
|
|
285
|
+
const now = (_request_now = request.now) != null ? _request_now : Date.now();
|
|
286
|
+
const locationId = String((_request_locationId = request.locationId) != null ? _request_locationId : '').trim().slice(0, 100);
|
|
287
|
+
return firestore.runTransaction(async (transaction)=>{
|
|
288
|
+
var _orderSnapshot_data;
|
|
289
|
+
const snapshot = await transaction.get(returnRef);
|
|
290
|
+
if (!snapshot.exists) return {
|
|
291
|
+
outcome: 'no_such_return'
|
|
292
|
+
};
|
|
293
|
+
const entry = snapshot.data();
|
|
294
|
+
if (entry.status === 'received' || entry.restock) return {
|
|
295
|
+
outcome: 'already',
|
|
296
|
+
entry
|
|
297
|
+
};
|
|
298
|
+
if (!CommerceModel.canTransitionReturn(entry.status, 'received')) {
|
|
299
|
+
return {
|
|
300
|
+
outcome: 'refused',
|
|
301
|
+
message: `A return that is ${CommerceModel.RETURN_STATUS_LABELS[entry.status].toLowerCase()} cannot be received`
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
// What may go back: at most what the return covers, per line.
|
|
305
|
+
const covered = new Map(entry.lines.map((line)=>[
|
|
306
|
+
line.lineItemId,
|
|
307
|
+
line.quantity
|
|
308
|
+
]));
|
|
309
|
+
const wanted = new Map();
|
|
310
|
+
for (const line of request.restock){
|
|
311
|
+
var _wanted_get, _covered_get;
|
|
312
|
+
const lineItemId = Number(line == null ? void 0 : line.lineItemId);
|
|
313
|
+
const quantity = Number(line == null ? void 0 : line.quantity);
|
|
314
|
+
if (!covered.has(lineItemId)) {
|
|
315
|
+
return {
|
|
316
|
+
outcome: 'refused',
|
|
317
|
+
message: `Line ${lineItemId} is not part of this return`
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
if (!Number.isInteger(quantity) || quantity < 0) {
|
|
321
|
+
return {
|
|
322
|
+
outcome: 'refused',
|
|
323
|
+
message: 'Restock quantities must be whole numbers'
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
const total = ((_wanted_get = wanted.get(lineItemId)) != null ? _wanted_get : 0) + quantity;
|
|
327
|
+
if (total > ((_covered_get = covered.get(lineItemId)) != null ? _covered_get : 0)) {
|
|
328
|
+
return {
|
|
329
|
+
outcome: 'refused',
|
|
330
|
+
message: `Only ${covered.get(lineItemId)} of line ${lineItemId} came back`
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
if (quantity > 0) wanted.set(lineItemId, total);
|
|
334
|
+
}
|
|
335
|
+
if (locationId && wanted.size > 0) {
|
|
336
|
+
const location = await transaction.get(hostRef.collection('locations').doc(locationId));
|
|
337
|
+
if (!location.exists) return {
|
|
338
|
+
outcome: 'refused',
|
|
339
|
+
message: 'That stock location no longer exists'
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
const orderRef = hostRef.collection('orders').doc(entry.orderId);
|
|
343
|
+
const orderSnapshot = await transaction.get(orderRef);
|
|
344
|
+
const order = orderSnapshot.exists ? CommerceModel.liftLegacyOrder((_orderSnapshot_data = orderSnapshot.data()) != null ? _orderSnapshot_data : {}) : null;
|
|
345
|
+
// Every read before any write, as a transaction requires.
|
|
346
|
+
const tracked = order && wanted.size > 0 ? await resolveTrackedRestockLines(hostRef, order, (ref)=>transaction.get(ref)) : {
|
|
347
|
+
lines: [],
|
|
348
|
+
products: new Map()
|
|
349
|
+
};
|
|
350
|
+
const byProduct = new Map();
|
|
351
|
+
for (const line of tracked.lines){
|
|
352
|
+
var _wanted_get1, _line_lineIndex, _byProduct_get;
|
|
353
|
+
const quantity = Math.min(line.quantity, (_wanted_get1 = wanted.get((_line_lineIndex = line.lineIndex) != null ? _line_lineIndex : -1)) != null ? _wanted_get1 : 0);
|
|
354
|
+
if (quantity <= 0) continue;
|
|
355
|
+
byProduct.set(line.productId, [
|
|
356
|
+
...(_byProduct_get = byProduct.get(line.productId)) != null ? _byProduct_get : [],
|
|
357
|
+
{
|
|
358
|
+
variantId: line.variantId,
|
|
359
|
+
quantity
|
|
360
|
+
}
|
|
361
|
+
]);
|
|
362
|
+
}
|
|
363
|
+
let units = 0;
|
|
364
|
+
for (const [productId, lines] of byProduct){
|
|
365
|
+
const product = tracked.products.get(productId);
|
|
366
|
+
if (!product) continue;
|
|
367
|
+
let variants = product.variants;
|
|
368
|
+
for (const line of lines){
|
|
369
|
+
variants = CommerceModel.adjustVariantInventory({
|
|
370
|
+
variants
|
|
371
|
+
}, line.variantId, line.quantity, locationId || undefined);
|
|
372
|
+
}
|
|
373
|
+
transaction.update(hostRef.collection('products').doc(productId), _extends({
|
|
374
|
+
variants
|
|
375
|
+
}, CommerceModel.productStockFields(_extends({}, product, {
|
|
376
|
+
variants
|
|
377
|
+
})), {
|
|
378
|
+
updatedAtMs: now
|
|
379
|
+
}));
|
|
380
|
+
for (const line of lines){
|
|
381
|
+
units += line.quantity;
|
|
382
|
+
transaction.create(hostRef.collection('inventoryAdjustments').doc(createResourceUid()), _extends({
|
|
383
|
+
productId,
|
|
384
|
+
variantId: line.variantId,
|
|
385
|
+
delta: line.quantity,
|
|
386
|
+
reason: 'restock',
|
|
387
|
+
orderId: entry.orderId
|
|
388
|
+
}, locationId ? {
|
|
389
|
+
locationId
|
|
390
|
+
} : {}, {
|
|
391
|
+
atMs: now
|
|
392
|
+
}));
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
const restock = _extends({
|
|
396
|
+
lines: [
|
|
397
|
+
...wanted.entries()
|
|
398
|
+
].map(([lineItemId, quantity])=>({
|
|
399
|
+
lineItemId,
|
|
400
|
+
quantity
|
|
401
|
+
}))
|
|
402
|
+
}, locationId ? {
|
|
403
|
+
locationId
|
|
404
|
+
} : {}, {
|
|
405
|
+
atMs: now
|
|
406
|
+
});
|
|
407
|
+
const patch = {
|
|
408
|
+
status: 'received',
|
|
409
|
+
restock,
|
|
410
|
+
timeline: CommerceModel.appendReturnEvent(entry, 'received', units > 0 ? `${units} ${units === 1 ? 'unit' : 'units'} back in stock` : 'Nothing restocked', now),
|
|
411
|
+
updatedAtMs: now
|
|
412
|
+
};
|
|
413
|
+
transaction.update(returnRef, patch);
|
|
414
|
+
const received = _extends({}, entry, patch);
|
|
415
|
+
if (order) {
|
|
416
|
+
const orderPatch = {
|
|
417
|
+
timeline: CommerceModel.appendOrderEvent(order, 'return-received', units > 0 ? `${units} restocked` : undefined, now)
|
|
418
|
+
};
|
|
419
|
+
transaction.update(orderRef, orderPatch);
|
|
420
|
+
stageOrderEvent(transaction, RETURN_RECEIVED_EVENT, {
|
|
421
|
+
hostId: request.hostId,
|
|
422
|
+
orderId: entry.orderId,
|
|
423
|
+
key: `return-received:${request.returnId}`,
|
|
424
|
+
order: _extends({}, orderSnapshot.data(), orderPatch),
|
|
425
|
+
extra: {
|
|
426
|
+
return: returnEventView(request.returnId, received)
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
return {
|
|
431
|
+
outcome: 'changed',
|
|
432
|
+
entry: received,
|
|
433
|
+
order,
|
|
434
|
+
units
|
|
435
|
+
};
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Records a refund that went through the order's refund route against the
|
|
440
|
+
* return, and answers the order's restock question with what the return
|
|
441
|
+
* already did, so the merchant is not asked to restock the same units again.
|
|
442
|
+
*/ export async function markReturnRefunded(request) {
|
|
443
|
+
var _request_now;
|
|
444
|
+
const firestore = firebaseAdmin.app().firestore();
|
|
445
|
+
const hostRef = hostRefFor(firestore, request.hostId);
|
|
446
|
+
const returnRef = hostRef.collection('returns').doc(request.returnId);
|
|
447
|
+
const now = (_request_now = request.now) != null ? _request_now : Date.now();
|
|
448
|
+
return firestore.runTransaction(async (transaction)=>{
|
|
449
|
+
var _orderSnapshot_data;
|
|
450
|
+
const snapshot = await transaction.get(returnRef);
|
|
451
|
+
if (!snapshot.exists) return {
|
|
452
|
+
outcome: 'no_such_return'
|
|
453
|
+
};
|
|
454
|
+
const entry = snapshot.data();
|
|
455
|
+
if (entry.status === 'refunded' || entry.refundedAtMs) return {
|
|
456
|
+
outcome: 'already',
|
|
457
|
+
entry
|
|
458
|
+
};
|
|
459
|
+
const orderRef = hostRef.collection('orders').doc(entry.orderId);
|
|
460
|
+
const orderSnapshot = await transaction.get(orderRef);
|
|
461
|
+
const order = orderSnapshot.exists ? CommerceModel.liftLegacyOrder((_orderSnapshot_data = orderSnapshot.data()) != null ? _orderSnapshot_data : {}) : null;
|
|
462
|
+
const patch = {
|
|
463
|
+
status: 'refunded',
|
|
464
|
+
refundedAtMs: now,
|
|
465
|
+
refundCents: Math.max(0, Math.round(request.refundCents)),
|
|
466
|
+
timeline: CommerceModel.appendReturnEvent(entry, 'refunded', undefined, now),
|
|
467
|
+
updatedAtMs: now
|
|
468
|
+
};
|
|
469
|
+
transaction.update(returnRef, patch);
|
|
470
|
+
const check = order == null ? void 0 : order.restockCheck;
|
|
471
|
+
if (order && check && !check.resolution && entry.restock) {
|
|
472
|
+
const restocked = entry.restock.lines.some((line)=>line.quantity > 0);
|
|
473
|
+
transaction.update(orderRef, {
|
|
474
|
+
restockCheck: _extends({}, check, {
|
|
475
|
+
resolution: restocked ? 'restocked' : 'dismissed',
|
|
476
|
+
resolvedAtMs: now
|
|
477
|
+
}, request.uid ? {
|
|
478
|
+
resolvedBy: request.uid
|
|
479
|
+
} : {}),
|
|
480
|
+
timeline: CommerceModel.appendOrderEvent(order, 'restock-check', restocked ? 'answered by the return — restocked' : 'answered by the return — no restock', now)
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
return {
|
|
484
|
+
outcome: 'changed',
|
|
485
|
+
entry: _extends({}, entry, patch),
|
|
486
|
+
order
|
|
487
|
+
};
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
/** Calls the order's own refund route in-process, with the caller's credentials. */ async function callRefundRoute(req, body, idempotencyKey) {
|
|
491
|
+
var _req_headers_authorization;
|
|
492
|
+
let status = 200;
|
|
493
|
+
let payload = {};
|
|
494
|
+
const res = {
|
|
495
|
+
status (code) {
|
|
496
|
+
status = code;
|
|
497
|
+
return res;
|
|
498
|
+
},
|
|
499
|
+
json (value) {
|
|
500
|
+
payload = value != null ? value : {};
|
|
501
|
+
return res;
|
|
502
|
+
},
|
|
503
|
+
send (value) {
|
|
504
|
+
payload = {
|
|
505
|
+
error: String(value != null ? value : '')
|
|
506
|
+
};
|
|
507
|
+
return res;
|
|
508
|
+
},
|
|
509
|
+
setHeader () {
|
|
510
|
+
return res;
|
|
511
|
+
},
|
|
512
|
+
end () {
|
|
513
|
+
return res;
|
|
514
|
+
}
|
|
515
|
+
};
|
|
516
|
+
await refundHandler(_extends({}, req, {
|
|
517
|
+
method: 'POST',
|
|
518
|
+
headers: {
|
|
519
|
+
authorization: String((_req_headers_authorization = req.headers.authorization) != null ? _req_headers_authorization : ''),
|
|
520
|
+
'idempotency-key': idempotencyKey
|
|
521
|
+
},
|
|
522
|
+
body
|
|
523
|
+
}), res);
|
|
524
|
+
return {
|
|
525
|
+
status,
|
|
526
|
+
body: payload
|
|
527
|
+
};
|
|
528
|
+
}
|
|
529
|
+
async function sendReturnEmail(hostId, key, to, tokens, fallback) {
|
|
530
|
+
if (!to || !isEmailConfigured()) return;
|
|
531
|
+
try {
|
|
532
|
+
var _ref;
|
|
533
|
+
const firestore = firebaseAdmin.app().firestore();
|
|
534
|
+
const designed = await renderHostEmailWithTokens(firestore, hostId, key, tokens);
|
|
535
|
+
const org = await getOrgForHost(hostId).catch(()=>null);
|
|
536
|
+
await sendEmail(_extends({
|
|
537
|
+
to,
|
|
538
|
+
subject: (_ref = designed == null ? void 0 : designed.subject) != null ? _ref : fallback.subject,
|
|
539
|
+
text: (designed == null ? void 0 : designed.text) || fallback.text
|
|
540
|
+
}, (designed == null ? void 0 : designed.html) ? {
|
|
541
|
+
html: designed.html
|
|
542
|
+
} : {}, {
|
|
543
|
+
fromName: Aglyn.resolveBrandingProfile(org == null ? void 0 : org.org).fromName,
|
|
544
|
+
sendingIdentity: await hostSendingIdentity(hostId),
|
|
545
|
+
audience: 'tenant',
|
|
546
|
+
context: key,
|
|
547
|
+
// Owed to the recipient by their own order (AGL-3356).
|
|
548
|
+
owedFor: 'order'
|
|
549
|
+
}));
|
|
550
|
+
await meterHostEmail(hostId);
|
|
551
|
+
} catch (error) {
|
|
552
|
+
// A return that is recorded is not undone because its email failed.
|
|
553
|
+
console.error(`[returns] ${key} not sent`, hostId, error);
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
/** Tells the store a buyer asked, in the console and by email to the owner. */ async function tellStoreOfRequest(hostId, returnId, entry, order) {
|
|
557
|
+
var _entry_customerEmail, _entry_customerEmail1, _entry_customerNote, _entry_customerEmail2;
|
|
558
|
+
var _org, _this, _this1;
|
|
559
|
+
const items = returnItemsText(order, entry);
|
|
560
|
+
await notifyHostManagers(hostId, {
|
|
561
|
+
type: 'content.order',
|
|
562
|
+
title: `Return requested for order ${entry.orderNumber}`,
|
|
563
|
+
body: `${(_entry_customerEmail = entry.customerEmail) != null ? _entry_customerEmail : 'A buyer'} wants to return ${CommerceModel.describeReturnLines(order, entry.lines)} from order ${entry.orderNumber} on {site}.`,
|
|
564
|
+
link: `/${hostId}/products/returns?return=${encodeURIComponent(returnId)}`
|
|
565
|
+
}, {
|
|
566
|
+
skipOwnerEmail: true
|
|
567
|
+
}).catch(()=>undefined);
|
|
568
|
+
const ownerUid = (_this = await getOrgForHost(hostId).catch(()=>null)) == null ? void 0 : (_org = _this.org) == null ? void 0 : _org.ownerUid;
|
|
569
|
+
const owner = ownerUid ? (_this1 = await findUserByUidAcrossPools(ownerUid).catch(()=>null)) == null ? void 0 : _this1.record : null;
|
|
570
|
+
if (!(owner == null ? void 0 : owner.email)) return;
|
|
571
|
+
await sendReturnEmail(hostId, 'return-requested', owner.email, {
|
|
572
|
+
'order.number': entry.orderNumber,
|
|
573
|
+
'return.items': items,
|
|
574
|
+
'buyer.email': String((_entry_customerEmail1 = entry.customerEmail) != null ? _entry_customerEmail1 : ''),
|
|
575
|
+
'return.customerNote': String((_entry_customerNote = entry.customerNote) != null ? _entry_customerNote : '')
|
|
576
|
+
}, {
|
|
577
|
+
subject: `Return requested for order ${entry.orderNumber}`,
|
|
578
|
+
text: `${(_entry_customerEmail2 = entry.customerEmail) != null ? _entry_customerEmail2 : 'A buyer'} wants to return items from order ${entry.orderNumber}.\n\n${items}` + (entry.customerNote ? `\n\n"${entry.customerNote}"` : '') + `\n\nApprove or decline it under Products → Returns.`
|
|
579
|
+
});
|
|
580
|
+
}
|
|
581
|
+
/** Tells the buyer what happened to their return. */ async function tellBuyer(hostId, key, entry, order) {
|
|
582
|
+
var _ref, _entry_customerEmail, _orderStatusUrl, _entry_refundCents, _entry_merchantNote;
|
|
583
|
+
const to = String((_ref = (_entry_customerEmail = entry.customerEmail) != null ? _entry_customerEmail : order == null ? void 0 : order.customerEmail) != null ? _ref : '').trim();
|
|
584
|
+
if (!to || !order) return;
|
|
585
|
+
const firestore = firebaseAdmin.app().firestore();
|
|
586
|
+
const store = await readStore(firestore, hostId);
|
|
587
|
+
const statusUrl = (_orderStatusUrl = orderStatusUrl(store.host, hostId, entry.orderId)) != null ? _orderStatusUrl : '';
|
|
588
|
+
const items = returnItemsText(order, entry);
|
|
589
|
+
const label = entry.returnLabel ? `Print your return label: ${entry.returnLabel.labelUrl}` + (entry.returnLabel.trackingNumber ? ` (${[
|
|
590
|
+
entry.returnLabel.carrier,
|
|
591
|
+
entry.returnLabel.trackingNumber
|
|
592
|
+
].filter(Boolean).join(' ')})` : '') : '';
|
|
593
|
+
const refundTotal = money((_entry_refundCents = entry.refundCents) != null ? _entry_refundCents : 0, store.currency);
|
|
594
|
+
const tokens = {
|
|
595
|
+
'order.number': entry.orderNumber,
|
|
596
|
+
'return.items': items,
|
|
597
|
+
'return.note': String((_entry_merchantNote = entry.merchantNote) != null ? _entry_merchantNote : ''),
|
|
598
|
+
'return.label': label,
|
|
599
|
+
'return.refundTotal': refundTotal,
|
|
600
|
+
'order.statusUrl': statusUrl
|
|
601
|
+
};
|
|
602
|
+
const fallback = key === 'return-approved' ? {
|
|
603
|
+
subject: `Your return for order ${entry.orderNumber} is approved`,
|
|
604
|
+
text: `Your return is approved:\n\n${items}` + (entry.merchantNote ? `\n\n${entry.merchantNote}` : '') + (label ? `\n\n${label}` : '')
|
|
605
|
+
} : key === 'return-declined' ? {
|
|
606
|
+
subject: `About your return for order ${entry.orderNumber}`,
|
|
607
|
+
text: `We could not accept the return of:\n\n${items}` + (entry.merchantNote ? `\n\n${entry.merchantNote}` : '')
|
|
608
|
+
} : {
|
|
609
|
+
subject: `Your refund for order ${entry.orderNumber}`,
|
|
610
|
+
text: `We received your return and refunded ${refundTotal}.\n\n${items}`
|
|
611
|
+
};
|
|
612
|
+
if (statusUrl) fallback.text += `\n\nView your order: ${statusUrl}`;
|
|
613
|
+
await sendReturnEmail(hostId, key, to, tokens, fallback);
|
|
614
|
+
}
|
|
615
|
+
// ---------------------------------------------------------------------------
|
|
616
|
+
// The buyer's door (tenant)
|
|
617
|
+
// ---------------------------------------------------------------------------
|
|
618
|
+
/**
|
|
619
|
+
* Whether this request may act for the buyer of this order: the signed-in
|
|
620
|
+
* site member whose email the order carries, or the holder of the order's
|
|
621
|
+
* signed status link. Neither reveals whether the order exists to anyone
|
|
622
|
+
* else — both refusals read the same.
|
|
623
|
+
*/ async function buyerMayActFor(req, hostId, orderId, token, order) {
|
|
624
|
+
var _session_member_get, _order_customerEmail;
|
|
625
|
+
if (token && verifyOrderStatusToken(hostId, orderId, token)) return true;
|
|
626
|
+
const session = await readActiveMemberSession(req, hostId);
|
|
627
|
+
if (session.status !== 'active') return false;
|
|
628
|
+
const memberEmail = String((_session_member_get = session.member.get('email')) != null ? _session_member_get : '').trim().toLowerCase();
|
|
629
|
+
return Boolean(memberEmail) && memberEmail === String((_order_customerEmail = order.customerEmail) != null ? _order_customerEmail : '').trim().toLowerCase();
|
|
630
|
+
}
|
|
631
|
+
/**
|
|
632
|
+
* `GET /api/commerce/return-request?hostId&orderId&t` — what the buyer may
|
|
633
|
+
* send back and until when, and the returns already open.
|
|
634
|
+
* `POST` with `{ hostId, orderId, t?, lines: [{ lineItemId, quantity, reason }], note? }`
|
|
635
|
+
* opens a return.
|
|
636
|
+
*/ export const returnRequestHandler = async (req, res)=>{
|
|
637
|
+
var _ref, _input_hostId, _ref1, _input_orderId, _ref2, _input_t;
|
|
638
|
+
if (req.method !== 'GET' && req.method !== 'POST') {
|
|
639
|
+
return res.status(405).json({
|
|
640
|
+
error: 'Method not allowed'
|
|
641
|
+
});
|
|
642
|
+
}
|
|
643
|
+
const input = (_ref = req.method === 'GET' ? req.query : typeof req.body === 'string' ? JSON.parse(req.body) : req.body) != null ? _ref : {};
|
|
644
|
+
const hostId = String((_input_hostId = input.hostId) != null ? _input_hostId : '');
|
|
645
|
+
const orderId = String((_ref1 = (_input_orderId = input.orderId) != null ? _input_orderId : input.o) != null ? _ref1 : '');
|
|
646
|
+
const token = String((_ref2 = (_input_t = input.t) != null ? _input_t : input.token) != null ? _ref2 : '').slice(0, 100);
|
|
647
|
+
if (!isId(hostId) || !isId(orderId)) return res.status(400).json({
|
|
648
|
+
error: 'Missing hostId or orderId'
|
|
649
|
+
});
|
|
650
|
+
try {
|
|
651
|
+
var _orderSnapshot_data, _input_note;
|
|
652
|
+
const firestore = firebaseAdmin.app().firestore();
|
|
653
|
+
const hostRef = hostRefFor(firestore, hostId);
|
|
654
|
+
const orderSnapshot = await hostRef.collection('orders').doc(orderId).get();
|
|
655
|
+
const order = orderSnapshot.exists ? CommerceModel.liftLegacyOrder((_orderSnapshot_data = orderSnapshot.data()) != null ? _orderSnapshot_data : {}) : null;
|
|
656
|
+
if (!order || !await buyerMayActFor(req, hostId, orderId, token, order)) {
|
|
657
|
+
return res.status(404).json({
|
|
658
|
+
error: 'We could not find that order'
|
|
659
|
+
});
|
|
660
|
+
}
|
|
661
|
+
if (req.method === 'GET') {
|
|
662
|
+
const [{ returnSettings }, existing] = await Promise.all([
|
|
663
|
+
readStore(firestore, hostId),
|
|
664
|
+
hostRef.collection('returns').where('orderId', '==', orderId).get()
|
|
665
|
+
]);
|
|
666
|
+
const returns = existing.docs.map((entry)=>_extends({
|
|
667
|
+
id: entry.id
|
|
668
|
+
}, entry.data()));
|
|
669
|
+
const endsAt = CommerceModel.returnWindowEndsAtMs(order, returnSettings);
|
|
670
|
+
return res.status(200).json({
|
|
671
|
+
enabled: returnSettings.enabled,
|
|
672
|
+
windowEndsAtMs: endsAt,
|
|
673
|
+
windowOpen: endsAt === null || Date.now() <= endsAt,
|
|
674
|
+
lines: CommerceModel.returnableLines(order, returns, returnSettings),
|
|
675
|
+
reasons: CommerceModel.RETURN_REASONS.map((reason)=>({
|
|
676
|
+
value: reason,
|
|
677
|
+
label: CommerceModel.RETURN_REASON_LABELS[reason]
|
|
678
|
+
})),
|
|
679
|
+
returns: returns.map((entry)=>_extends({
|
|
680
|
+
id: entry.id,
|
|
681
|
+
status: entry.status,
|
|
682
|
+
lines: entry.lines,
|
|
683
|
+
createdAtMs: entry.createdAtMs
|
|
684
|
+
}, entry.returnLabel ? {
|
|
685
|
+
returnLabel: {
|
|
686
|
+
labelUrl: entry.returnLabel.labelUrl,
|
|
687
|
+
carrier: entry.returnLabel.carrier,
|
|
688
|
+
trackingNumber: entry.returnLabel.trackingNumber
|
|
689
|
+
}
|
|
690
|
+
} : {}, entry.status === 'declined' && entry.merchantNote ? {
|
|
691
|
+
merchantNote: entry.merchantNote
|
|
692
|
+
} : {}))
|
|
693
|
+
});
|
|
694
|
+
}
|
|
695
|
+
const outcome = await openReturn({
|
|
696
|
+
hostId,
|
|
697
|
+
orderId,
|
|
698
|
+
lines: Array.isArray(input.lines) ? input.lines.slice(0, 100) : [],
|
|
699
|
+
note: String((_input_note = input.note) != null ? _input_note : ''),
|
|
700
|
+
by: 'buyer'
|
|
701
|
+
});
|
|
702
|
+
if (outcome.outcome === 'no_such_order') return res.status(404).json({
|
|
703
|
+
error: 'We could not find that order'
|
|
704
|
+
});
|
|
705
|
+
if (outcome.outcome === 'refused') return res.status(409).json({
|
|
706
|
+
error: outcome.message
|
|
707
|
+
});
|
|
708
|
+
await tellStoreOfRequest(hostId, outcome.returnId, outcome.entry, outcome.order);
|
|
709
|
+
return res.status(200).json({
|
|
710
|
+
ok: true,
|
|
711
|
+
returnId: outcome.returnId,
|
|
712
|
+
status: outcome.entry.status
|
|
713
|
+
});
|
|
714
|
+
} catch (error) {
|
|
715
|
+
console.error('return request failed', error);
|
|
716
|
+
return res.status(500).json({
|
|
717
|
+
error: 'Your return could not be requested. Please try again.'
|
|
718
|
+
});
|
|
719
|
+
}
|
|
720
|
+
};
|
|
721
|
+
// ---------------------------------------------------------------------------
|
|
722
|
+
// The merchant's door (console)
|
|
723
|
+
// ---------------------------------------------------------------------------
|
|
724
|
+
const MERCHANT_ACTIONS = [
|
|
725
|
+
'create',
|
|
726
|
+
'approve',
|
|
727
|
+
'decline',
|
|
728
|
+
'close',
|
|
729
|
+
'note',
|
|
730
|
+
'attach-label',
|
|
731
|
+
'receive',
|
|
732
|
+
'refund'
|
|
733
|
+
];
|
|
734
|
+
/**
|
|
735
|
+
* `POST /api/commerce/returns` with `{ hostId, action, … }`. Admins and
|
|
736
|
+
* editors run the return; the refund goes through the order's refund route,
|
|
737
|
+
* which asks for an admin of the whole workspace on its own.
|
|
738
|
+
*/ export const returnsHandler = async (req, res)=>{
|
|
739
|
+
var _req_headers_authorization, _ref, _body_hostId, _body_action, _body_returnId;
|
|
740
|
+
if (req.method !== 'POST') return res.status(405).json({
|
|
741
|
+
error: 'Method not allowed'
|
|
742
|
+
});
|
|
743
|
+
const authorization = String((_req_headers_authorization = req.headers.authorization) != null ? _req_headers_authorization : '');
|
|
744
|
+
const idToken = authorization.startsWith('Bearer ') ? authorization.slice('Bearer '.length) : undefined;
|
|
745
|
+
if (!idToken) return res.status(401).json({
|
|
746
|
+
error: 'Unauthenticated'
|
|
747
|
+
});
|
|
748
|
+
const body = (_ref = typeof req.body === 'string' ? JSON.parse(req.body) : req.body) != null ? _ref : {};
|
|
749
|
+
const hostId = String((_body_hostId = body.hostId) != null ? _body_hostId : '');
|
|
750
|
+
const action = String((_body_action = body.action) != null ? _body_action : '');
|
|
751
|
+
const returnId = String((_body_returnId = body.returnId) != null ? _body_returnId : '');
|
|
752
|
+
if (!isId(hostId)) return res.status(400).json({
|
|
753
|
+
error: 'Missing hostId'
|
|
754
|
+
});
|
|
755
|
+
if (!MERCHANT_ACTIONS.includes(action)) return res.status(400).json({
|
|
756
|
+
error: 'Unknown action'
|
|
757
|
+
});
|
|
758
|
+
if (action !== 'create' && !isId(returnId)) return res.status(400).json({
|
|
759
|
+
error: 'Missing returnId'
|
|
760
|
+
});
|
|
761
|
+
try {
|
|
762
|
+
var _hostSnapshot_get;
|
|
763
|
+
const decoded = await firebaseAdmin.app().auth().verifyIdToken(idToken);
|
|
764
|
+
const firestore = firebaseAdmin.app().firestore();
|
|
765
|
+
const hostSnapshot = await hostRefFor(firestore, hostId).get();
|
|
766
|
+
if (!hostSnapshot.exists) return res.status(404).json({
|
|
767
|
+
error: 'Unknown site'
|
|
768
|
+
});
|
|
769
|
+
const role = ((_hostSnapshot_get = hostSnapshot.get('memberRoles')) != null ? _hostSnapshot_get : {})[decoded.uid];
|
|
770
|
+
if (role !== 'admin' && role !== 'editor') return res.status(403).json({
|
|
771
|
+
error: 'Not permitted'
|
|
772
|
+
});
|
|
773
|
+
if (action === 'create') {
|
|
774
|
+
var _body_orderId, _body_note;
|
|
775
|
+
const orderId = String((_body_orderId = body.orderId) != null ? _body_orderId : '');
|
|
776
|
+
if (!isId(orderId)) return res.status(400).json({
|
|
777
|
+
error: 'Missing orderId'
|
|
778
|
+
});
|
|
779
|
+
const outcome = await openReturn({
|
|
780
|
+
hostId,
|
|
781
|
+
orderId,
|
|
782
|
+
lines: Array.isArray(body.lines) ? body.lines.slice(0, 100) : [],
|
|
783
|
+
note: String((_body_note = body.note) != null ? _body_note : ''),
|
|
784
|
+
by: 'merchant'
|
|
785
|
+
});
|
|
786
|
+
if (outcome.outcome === 'no_such_order') return res.status(404).json({
|
|
787
|
+
error: 'Unknown order'
|
|
788
|
+
});
|
|
789
|
+
if (outcome.outcome === 'refused') return res.status(409).json({
|
|
790
|
+
error: outcome.message
|
|
791
|
+
});
|
|
792
|
+
if (body.notify !== false) await tellBuyer(hostId, 'return-approved', outcome.entry, outcome.order);
|
|
793
|
+
return res.status(200).json({
|
|
794
|
+
ok: true,
|
|
795
|
+
returnId: outcome.returnId,
|
|
796
|
+
status: outcome.entry.status
|
|
797
|
+
});
|
|
798
|
+
}
|
|
799
|
+
if (action === 'receive') {
|
|
800
|
+
var _outcome_units;
|
|
801
|
+
const outcome = await receiveReturn({
|
|
802
|
+
hostId,
|
|
803
|
+
returnId,
|
|
804
|
+
restock: Array.isArray(body.restock) ? body.restock.slice(0, 100) : [],
|
|
805
|
+
locationId: body.locationId ? String(body.locationId) : undefined
|
|
806
|
+
});
|
|
807
|
+
if (outcome.outcome === 'no_such_return') return res.status(404).json({
|
|
808
|
+
error: 'Unknown return'
|
|
809
|
+
});
|
|
810
|
+
if (outcome.outcome === 'refused') return res.status(409).json({
|
|
811
|
+
error: outcome.message
|
|
812
|
+
});
|
|
813
|
+
return res.status(200).json(_extends({
|
|
814
|
+
ok: true
|
|
815
|
+
}, outcome.outcome === 'already' ? {
|
|
816
|
+
already: true
|
|
817
|
+
} : {
|
|
818
|
+
units: (_outcome_units = outcome.units) != null ? _outcome_units : 0
|
|
819
|
+
}, {
|
|
820
|
+
status: outcome.entry.status
|
|
821
|
+
}));
|
|
822
|
+
}
|
|
823
|
+
if (action === 'refund') {
|
|
824
|
+
var _orderSnapshot_data;
|
|
825
|
+
const returnSnapshot = await hostRefFor(firestore, hostId).collection('returns').doc(returnId).get();
|
|
826
|
+
if (!returnSnapshot.exists) return res.status(404).json({
|
|
827
|
+
error: 'Unknown return'
|
|
828
|
+
});
|
|
829
|
+
const entry = returnSnapshot.data();
|
|
830
|
+
if (entry.status === 'refunded' || entry.refundedAtMs) {
|
|
831
|
+
return res.status(200).json({
|
|
832
|
+
ok: true,
|
|
833
|
+
already: true,
|
|
834
|
+
status: entry.status
|
|
835
|
+
});
|
|
836
|
+
}
|
|
837
|
+
if (!CommerceModel.canTransitionReturn(entry.status, 'refunded')) {
|
|
838
|
+
return res.status(409).json({
|
|
839
|
+
error: `A return that is ${CommerceModel.RETURN_STATUS_LABELS[entry.status].toLowerCase()} cannot be refunded`
|
|
840
|
+
});
|
|
841
|
+
}
|
|
842
|
+
const orderSnapshot = await hostRefFor(firestore, hostId).collection('orders').doc(entry.orderId).get();
|
|
843
|
+
if (!orderSnapshot.exists) return res.status(404).json({
|
|
844
|
+
error: 'The order for this return is gone'
|
|
845
|
+
});
|
|
846
|
+
const order = CommerceModel.liftLegacyOrder((_orderSnapshot_data = orderSnapshot.data()) != null ? _orderSnapshot_data : {});
|
|
847
|
+
const suggested = CommerceModel.returnRefundCents(order, entry.lines);
|
|
848
|
+
const amountCents = body.amountCents == null ? suggested : Math.round(Number(body.amountCents));
|
|
849
|
+
if (!Number.isFinite(amountCents) || amountCents <= 0) {
|
|
850
|
+
return res.status(400).json({
|
|
851
|
+
error: 'The refund amount must be above zero'
|
|
852
|
+
});
|
|
853
|
+
}
|
|
854
|
+
const wholeLines = CommerceModel.returnWholeLineIds(order, entry.lines).filter((index)=>!CommerceModel.orderLineRefunded(order, index));
|
|
855
|
+
const namedWorth = CommerceModel.orderLineRefundCents(order, wholeLines);
|
|
856
|
+
// Lines are named only when the amount covers them in full, which is
|
|
857
|
+
// what the refund route requires before it withdraws a line's
|
|
858
|
+
// entitlements; a smaller amount refunds by amount alone.
|
|
859
|
+
const refund = await callRefundRoute(req, _extends({
|
|
860
|
+
hostId,
|
|
861
|
+
orderId: entry.orderId,
|
|
862
|
+
amountCents
|
|
863
|
+
}, wholeLines.length > 0 && amountCents >= namedWorth ? {
|
|
864
|
+
lineItemIds: wholeLines
|
|
865
|
+
} : {}), // One refund per return: asking again replays rather than pays twice.
|
|
866
|
+
`return:${hostId}:${returnId}`);
|
|
867
|
+
if (refund.status !== 200) {
|
|
868
|
+
var _ref1;
|
|
869
|
+
var _refund_body;
|
|
870
|
+
return res.status(refund.status).json({
|
|
871
|
+
error: (_ref1 = (_refund_body = refund.body) == null ? void 0 : _refund_body.error) != null ? _ref1 : 'Refund failed'
|
|
872
|
+
});
|
|
873
|
+
}
|
|
874
|
+
const marked = await markReturnRefunded({
|
|
875
|
+
hostId,
|
|
876
|
+
returnId,
|
|
877
|
+
refundCents: amountCents,
|
|
878
|
+
uid: decoded.uid
|
|
879
|
+
});
|
|
880
|
+
if (marked.outcome === 'changed') {
|
|
881
|
+
await raiseOrderEvent(RETURN_REFUNDED_EVENT, {
|
|
882
|
+
hostId,
|
|
883
|
+
orderId: entry.orderId,
|
|
884
|
+
key: `return-refunded:${returnId}`,
|
|
885
|
+
extra: {
|
|
886
|
+
return: returnEventView(returnId, marked.entry)
|
|
887
|
+
}
|
|
888
|
+
});
|
|
889
|
+
await tellBuyer(hostId, 'return-refunded', marked.entry, marked.order);
|
|
890
|
+
}
|
|
891
|
+
return res.status(200).json({
|
|
892
|
+
ok: true,
|
|
893
|
+
refundCents: amountCents,
|
|
894
|
+
status: 'refunded'
|
|
895
|
+
});
|
|
896
|
+
}
|
|
897
|
+
const outcome = await changeReturn(_extends({
|
|
898
|
+
hostId,
|
|
899
|
+
returnId,
|
|
900
|
+
action: action
|
|
901
|
+
}, body.merchantNote !== undefined ? {
|
|
902
|
+
merchantNote: String(body.merchantNote)
|
|
903
|
+
} : {}, action === 'attach-label' ? {
|
|
904
|
+
label: body.label
|
|
905
|
+
} : {}));
|
|
906
|
+
if (outcome.outcome === 'no_such_return') return res.status(404).json({
|
|
907
|
+
error: 'Unknown return'
|
|
908
|
+
});
|
|
909
|
+
if (outcome.outcome === 'refused') return res.status(409).json({
|
|
910
|
+
error: outcome.message
|
|
911
|
+
});
|
|
912
|
+
if (outcome.outcome === 'changed' && body.notify !== false) {
|
|
913
|
+
if (action === 'approve') await tellBuyer(hostId, 'return-approved', outcome.entry, outcome.order);
|
|
914
|
+
if (action === 'decline') await tellBuyer(hostId, 'return-declined', outcome.entry, outcome.order);
|
|
915
|
+
// A label attached after the approval reaches the buyer the same way,
|
|
916
|
+
// in the approval email, which carries it.
|
|
917
|
+
if (action === 'attach-label' && outcome.entry.status === 'approved') {
|
|
918
|
+
await tellBuyer(hostId, 'return-approved', outcome.entry, outcome.order);
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
return res.status(200).json(_extends({
|
|
922
|
+
ok: true
|
|
923
|
+
}, outcome.outcome === 'already' ? {
|
|
924
|
+
already: true
|
|
925
|
+
} : {}, {
|
|
926
|
+
status: outcome.entry.status
|
|
927
|
+
}));
|
|
928
|
+
} catch (error) {
|
|
929
|
+
console.error('returns action failed', action, error);
|
|
930
|
+
// Every write here is a transaction or keyed (the refund), so asking
|
|
931
|
+
// again lands once.
|
|
932
|
+
return res.status(500).json({
|
|
933
|
+
error: 'The return could not be updated. Retrying is safe.'
|
|
934
|
+
});
|
|
935
|
+
}
|
|
936
|
+
};
|
|
937
|
+
|
|
938
|
+
//# sourceMappingURL=returns.js.map
|