@aglyn/plugins-commerce 1.0.0-beta.285 → 1.0.0-beta.288
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/README.md +1 -1
- package/package.json +13 -13
- package/src/lib/components/cart.js +25 -12
- package/src/lib/components/cart.js.map +1 -1
- package/src/lib/components/commerce-console-page.js +70 -13
- package/src/lib/components/commerce-console-page.js.map +1 -1
- package/src/lib/components/console/order-detail-dialog.component.js +2 -1
- package/src/lib/components/console/order-detail-dialog.component.js.map +1 -1
- package/src/lib/components/console/order-webhooks-card.component.js +1 -1
- package/src/lib/components/console/order-webhooks-card.component.js.map +1 -1
- package/src/lib/components/console/payment-methods-card.component.js +1 -1
- package/src/lib/components/console/payment-methods-card.component.js.map +1 -1
- package/src/lib/components/console/pos/pos-cart-panel.component.d.ts +5 -0
- package/src/lib/components/console/pos/pos-cart-panel.component.js +18 -12
- package/src/lib/components/console/pos/pos-cart-panel.component.js.map +1 -1
- package/src/lib/components/console/pos/pos-hardware-api.d.ts +76 -5
- package/src/lib/components/console/pos/pos-hardware-api.js +53 -11
- package/src/lib/components/console/pos/pos-hardware-api.js.map +1 -1
- package/src/lib/components/console/pos/pos-hardware-buyer.component.d.ts +18 -0
- package/src/lib/components/console/pos/pos-hardware-buyer.component.js +629 -0
- package/src/lib/components/console/pos/pos-hardware-buyer.component.js.map +1 -0
- package/src/lib/components/console/pos/pos-hardware-sale-api.d.ts +162 -0
- package/src/lib/components/console/pos/pos-hardware-sale-api.js +122 -0
- package/src/lib/components/console/pos/pos-hardware-sale-api.js.map +1 -0
- package/src/lib/components/console/pos/pos-hardware-sale-terms.component.d.ts +39 -0
- package/src/lib/components/console/pos/pos-hardware-sale-terms.component.js +251 -0
- package/src/lib/components/console/pos/pos-hardware-sale-terms.component.js.map +1 -0
- package/src/lib/components/console/pos/use-pos-display.js +50 -0
- package/src/lib/components/console/pos/use-pos-display.js.map +1 -1
- package/src/lib/components/console/pos-cellular-control.component.d.ts +41 -0
- package/src/lib/components/console/pos-cellular-control.component.js +211 -0
- package/src/lib/components/console/pos-cellular-control.component.js.map +1 -0
- package/src/lib/components/console/pos-devices-card.component.d.ts +9 -1
- package/src/lib/components/console/pos-devices-card.component.js +47 -15
- package/src/lib/components/console/pos-devices-card.component.js.map +1 -1
- package/src/lib/components/console/pos-display/pos-display-api.d.ts +6 -0
- package/src/lib/components/console/pos-display/pos-display-api.js +8 -1
- package/src/lib/components/console/pos-display/pos-display-api.js.map +1 -1
- package/src/lib/components/console/pos-display-page.component.d.ts +13 -0
- package/src/lib/components/console/pos-display-page.component.js +44 -2
- package/src/lib/components/console/pos-display-page.component.js.map +1 -1
- package/src/lib/components/console/pos-hardware-card.component.d.ts +12 -4
- package/src/lib/components/console/pos-hardware-card.component.js +157 -36
- package/src/lib/components/console/pos-hardware-card.component.js.map +1 -1
- package/src/lib/components/console/pos-hardware-orders-staff-page.component.js +360 -80
- package/src/lib/components/console/pos-hardware-orders-staff-page.component.js.map +1 -1
- package/src/lib/components/console/pos-hardware-terms-page.component.d.ts +34 -0
- package/src/lib/components/console/pos-hardware-terms-page.component.js +257 -0
- package/src/lib/components/console/pos-hardware-terms-page.component.js.map +1 -0
- package/src/lib/components/console/pos-hardware-terms-sign-page.component.d.ts +27 -0
- package/src/lib/components/console/pos-hardware-terms-sign-page.component.js +104 -0
- package/src/lib/components/console/pos-hardware-terms-sign-page.component.js.map +1 -0
- package/src/lib/components/console/pos-hardware-waiting-card.component.d.ts +24 -0
- package/src/lib/components/console/pos-hardware-waiting-card.component.js +205 -0
- package/src/lib/components/console/pos-hardware-waiting-card.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-check-in-dialog.component.js +297 -201
- package/src/lib/components/console/pos-ops/pos-check-in-dialog.component.js.map +1 -1
- package/src/lib/components/console/pos-ops/pos-check-ins-card.component.d.ts +3 -0
- package/src/lib/components/console/pos-ops/pos-check-ins-card.component.js +260 -92
- package/src/lib/components/console/pos-ops/pos-check-ins-card.component.js.map +1 -1
- package/src/lib/components/console/pos-ops/pos-operations-bar.component.d.ts +9 -0
- package/src/lib/components/console/pos-ops/pos-operations-bar.component.js +15 -6
- package/src/lib/components/console/pos-ops/pos-operations-bar.component.js.map +1 -1
- package/src/lib/components/console/pos-ops/pos-rain-check-dialog.component.d.ts +25 -0
- package/src/lib/components/console/pos-ops/pos-rain-check-dialog.component.js +136 -0
- package/src/lib/components/console/pos-ops/pos-rain-check-dialog.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-shift-panel.component.d.ts +6 -0
- package/src/lib/components/console/pos-ops/pos-shift-panel.component.js +48 -31
- package/src/lib/components/console/pos-ops/pos-shift-panel.component.js.map +1 -1
- package/src/lib/components/console/pos-page.component.d.ts +1 -1
- package/src/lib/components/console/pos-page.component.js +63 -12
- package/src/lib/components/console/pos-page.component.js.map +1 -1
- package/src/lib/components/console/pos-reader-splash-setting.component.js +1 -1
- package/src/lib/components/console/pos-reader-splash-setting.component.js.map +1 -1
- package/src/lib/components/console/product-check-in-fields.component.d.ts +4 -2
- package/src/lib/components/console/product-check-in-fields.component.js +60 -14
- package/src/lib/components/console/product-check-in-fields.component.js.map +1 -1
- package/src/lib/components/console/product-editor-dialog.component.js +44 -1
- package/src/lib/components/console/product-editor-dialog.component.js.map +1 -1
- package/src/lib/components/console/product-hardware-sku-field.component.d.ts +19 -0
- package/src/lib/components/console/product-hardware-sku-field.component.js +92 -0
- package/src/lib/components/console/product-hardware-sku-field.component.js.map +1 -0
- package/src/lib/components/console/product-kiosk-offer-field.component.d.ts +22 -0
- package/src/lib/components/console/product-kiosk-offer-field.component.js +94 -0
- package/src/lib/components/console/product-kiosk-offer-field.component.js.map +1 -0
- package/src/lib/components/console/product-register-fields.component.d.ts +4 -0
- package/src/lib/components/console/product-register-fields.component.js +31 -2
- package/src/lib/components/console/product-register-fields.component.js.map +1 -1
- package/src/lib/components/console/products-hub-card.component.js +11 -2
- package/src/lib/components/console/products-hub-card.component.js.map +1 -1
- package/src/lib/components/console/register-hardware-card.component.d.ts +11 -0
- package/src/lib/components/console/register-hardware-card.component.js +56 -27
- package/src/lib/components/console/register-hardware-card.component.js.map +1 -1
- package/src/lib/components/console/reservation-guests-dialog.component.d.ts +28 -0
- package/src/lib/components/console/reservation-guests-dialog.component.js +189 -0
- package/src/lib/components/console/reservation-guests-dialog.component.js.map +1 -0
- package/src/lib/components/console/reservations-card.component.d.ts +9 -0
- package/src/lib/components/console/reservations-card.component.js +158 -23
- package/src/lib/components/console/reservations-card.component.js.map +1 -1
- package/src/lib/components/console/shippingeasy-card.component.js +1 -1
- package/src/lib/components/console/shippingeasy-card.component.js.map +1 -1
- package/src/lib/components/console/shipstation-card.component.d.ts +1 -1
- package/src/lib/components/console/shipstation-card.component.js +3 -3
- package/src/lib/components/console/shipstation-card.component.js.map +1 -1
- package/src/lib/components/product-detail.d.ts +4 -0
- package/src/lib/components/product-detail.js +40 -5
- package/src/lib/components/product-detail.js.map +1 -1
- package/src/lib/components/product-reviews.js +28 -11
- package/src/lib/components/product-reviews.js.map +1 -1
- package/src/lib/components/reservation-widget.js +28 -5
- package/src/lib/components/reservation-widget.js.map +1 -1
- package/src/lib/components/use-day-picker.d.ts +25 -0
- package/src/lib/components/use-day-picker.js +57 -0
- package/src/lib/components/use-day-picker.js.map +1 -0
- package/src/lib/constants/operator-alerts.d.ts +55 -0
- package/src/lib/constants/operator-alerts.js +156 -1
- package/src/lib/constants/operator-alerts.js.map +1 -1
- package/src/lib/declarations.console-server.js +54 -1
- package/src/lib/declarations.console-server.js.map +1 -1
- package/src/lib/declarations.d.ts +4 -2
- package/src/lib/declarations.js +15 -4
- package/src/lib/declarations.js.map +1 -1
- package/src/lib/declarations.server.js +9 -0
- package/src/lib/declarations.server.js.map +1 -1
- package/src/lib/model/commerce-cart.d.ts +9 -1
- package/src/lib/model/commerce-cart.js +4 -3
- package/src/lib/model/commerce-cart.js.map +1 -1
- package/src/lib/model/commerce-check-in-product.d.ts +26 -0
- package/src/lib/model/commerce-check-in-product.js +64 -2
- package/src/lib/model/commerce-check-in-product.js.map +1 -1
- package/src/lib/model/commerce-check-in-record.d.ts +127 -0
- package/src/lib/model/commerce-check-in-record.js +36 -0
- package/src/lib/model/commerce-check-in-record.js.map +1 -0
- package/src/lib/model/commerce-check-in.d.ts +91 -87
- package/src/lib/model/commerce-check-in.js +186 -62
- package/src/lib/model/commerce-check-in.js.map +1 -1
- package/src/lib/model/commerce-kiosk-offer.d.ts +31 -0
- package/src/lib/model/commerce-kiosk-offer.js +35 -0
- package/src/lib/model/commerce-kiosk-offer.js.map +1 -0
- package/src/lib/model/commerce-orders.d.ts +76 -0
- package/src/lib/model/commerce-orders.js +6 -0
- package/src/lib/model/commerce-orders.js.map +1 -1
- package/src/lib/model/commerce-pos-day-report.d.ts +54 -1
- package/src/lib/model/commerce-pos-day-report.js +39 -2
- package/src/lib/model/commerce-pos-day-report.js.map +1 -1
- package/src/lib/model/commerce-pos-offline.d.ts +1 -1
- package/src/lib/model/commerce-pos-offline.js +6 -1
- package/src/lib/model/commerce-pos-offline.js.map +1 -1
- package/src/lib/model/commerce-pos-ops.js +3 -2
- package/src/lib/model/commerce-pos-ops.js.map +1 -1
- package/src/lib/model/commerce-pos.d.ts +36 -3
- package/src/lib/model/commerce-pos.js +14 -6
- package/src/lib/model/commerce-pos.js.map +1 -1
- package/src/lib/model/commerce-receipt.js +3 -2
- package/src/lib/model/commerce-receipt.js.map +1 -1
- package/src/lib/model/commerce-reservations.d.ts +69 -4
- package/src/lib/model/commerce-reservations.js +57 -5
- package/src/lib/model/commerce-reservations.js.map +1 -1
- package/src/lib/model/commerce.d.ts +66 -0
- package/src/lib/model/commerce.js +15 -0
- package/src/lib/model/commerce.js.map +1 -1
- package/src/lib/model/order-list-fields.d.ts +11 -0
- package/src/lib/model/order-list-fields.js +17 -1
- package/src/lib/model/order-list-fields.js.map +1 -1
- package/src/lib/model/own-store-tax-summary.d.ts +152 -0
- package/src/lib/model/own-store-tax-summary.js +288 -0
- package/src/lib/model/own-store-tax-summary.js.map +1 -0
- package/src/lib/model/plugin-permissions.d.ts +74 -0
- package/src/lib/model/plugin-permissions.js +224 -7
- package/src/lib/model/plugin-permissions.js.map +1 -1
- package/src/lib/model/pos-cellular.d.ts +223 -0
- package/src/lib/model/pos-cellular.js +293 -0
- package/src/lib/model/pos-cellular.js.map +1 -0
- package/src/lib/model/pos-hardware-in-person.d.ts +98 -0
- package/src/lib/model/pos-hardware-in-person.js +224 -0
- package/src/lib/model/pos-hardware-in-person.js.map +1 -0
- package/src/lib/model/pos-hardware-tax-summary.d.ts +166 -0
- package/src/lib/model/pos-hardware-tax-summary.js +225 -0
- package/src/lib/model/pos-hardware-tax-summary.js.map +1 -0
- package/src/lib/model/pos-hardware-terms.d.ts +74 -0
- package/src/lib/model/pos-hardware-terms.js +115 -0
- package/src/lib/model/pos-hardware-terms.js.map +1 -0
- package/src/lib/model/pos-hardware.d.ts +349 -7
- package/src/lib/model/pos-hardware.js +291 -20
- package/src/lib/model/pos-hardware.js.map +1 -1
- package/src/lib/model/product-write.d.ts +10 -0
- package/src/lib/model/product-write.js +4 -2
- package/src/lib/model/product-write.js.map +1 -1
- package/src/lib/model/workspace-site-permissions.d.ts +26 -0
- package/src/lib/model/workspace-site-permissions.js +81 -0
- package/src/lib/model/workspace-site-permissions.js.map +1 -0
- package/src/lib/plugin.js +16 -0
- package/src/lib/plugin.js.map +1 -1
- package/src/lib/server/billing-webhook.js +25 -1
- package/src/lib/server/billing-webhook.js.map +1 -1
- package/src/lib/server/cancel-order.js +7 -5
- package/src/lib/server/cancel-order.js.map +1 -1
- package/src/lib/server/cart-checkout.js +20 -8
- package/src/lib/server/cart-checkout.js.map +1 -1
- package/src/lib/server/cart.js +29 -0
- package/src/lib/server/cart.js.map +1 -1
- package/src/lib/server/checkout.js +42 -13
- package/src/lib/server/checkout.js.map +1 -1
- package/src/lib/server/collection-membership.d.ts +4 -0
- package/src/lib/server/collection-membership.js +5 -10
- package/src/lib/server/collection-membership.js.map +1 -1
- package/src/lib/server/commerce-site-keys.d.ts +48 -0
- package/src/lib/server/commerce-site-keys.js +61 -0
- package/src/lib/server/commerce-site-keys.js.map +1 -0
- package/src/lib/server/draft-order.js +8 -5
- package/src/lib/server/draft-order.js.map +1 -1
- package/src/lib/server/fulfill-order.js +7 -5
- package/src/lib/server/fulfill-order.js.map +1 -1
- package/src/lib/server/gift-cards.js +8 -5
- package/src/lib/server/gift-cards.js.map +1 -1
- package/src/lib/server/local-fulfillment-status.js +9 -6
- package/src/lib/server/local-fulfillment-status.js.map +1 -1
- package/src/lib/server/member-post.js +6 -5
- package/src/lib/server/member-post.js.map +1 -1
- package/src/lib/server/membership-admin-password.d.ts +4 -2
- package/src/lib/server/membership-admin-password.js +10 -8
- package/src/lib/server/membership-admin-password.js.map +1 -1
- package/src/lib/server/membership-admin-remove.d.ts +7 -5
- package/src/lib/server/membership-admin-remove.js +9 -9
- package/src/lib/server/membership-admin-remove.js.map +1 -1
- package/src/lib/server/order-notifications.js +5 -2
- package/src/lib/server/order-notifications.js.map +1 -1
- package/src/lib/server/order-print.js +7 -5
- package/src/lib/server/order-print.js.map +1 -1
- package/src/lib/server/order-receipt-send.js +8 -5
- package/src/lib/server/order-receipt-send.js.map +1 -1
- package/src/lib/server/order-webhooks.js +8 -8
- package/src/lib/server/order-webhooks.js.map +1 -1
- package/src/lib/server/orders-shipping-prepare.js +9 -6
- package/src/lib/server/orders-shipping-prepare.js.map +1 -1
- package/src/lib/server/own-store-tax-return-source.d.ts +47 -0
- package/src/lib/server/own-store-tax-return-source.js +312 -0
- package/src/lib/server/own-store-tax-return-source.js.map +1 -0
- package/src/lib/server/payment-methods.js +13 -9
- package/src/lib/server/payment-methods.js.map +1 -1
- package/src/lib/server/pos-auth.d.ts +37 -6
- package/src/lib/server/pos-auth.js +40 -15
- package/src/lib/server/pos-auth.js.map +1 -1
- package/src/lib/server/pos-cellular-billing.d.ts +81 -0
- package/src/lib/server/pos-cellular-billing.js +711 -0
- package/src/lib/server/pos-cellular-billing.js.map +1 -0
- package/src/lib/server/pos-cellular-notify.d.ts +47 -0
- package/src/lib/server/pos-cellular-notify.js +150 -0
- package/src/lib/server/pos-cellular-notify.js.map +1 -0
- package/src/lib/server/pos-cellular.d.ts +88 -0
- package/src/lib/server/pos-cellular.js +339 -0
- package/src/lib/server/pos-cellular.js.map +1 -0
- package/src/lib/server/pos-check-in.d.ts +5 -1
- package/src/lib/server/pos-check-in.js +296 -28
- package/src/lib/server/pos-check-in.js.map +1 -1
- package/src/lib/server/pos-day-report.js +29 -3
- package/src/lib/server/pos-day-report.js.map +1 -1
- package/src/lib/server/pos-display.d.ts +16 -0
- package/src/lib/server/pos-display.js +129 -2
- package/src/lib/server/pos-display.js.map +1 -1
- package/src/lib/server/pos-hardware-admin.d.ts +10 -1
- package/src/lib/server/pos-hardware-admin.js +250 -84
- package/src/lib/server/pos-hardware-admin.js.map +1 -1
- package/src/lib/server/pos-hardware-attach.d.ts +105 -0
- package/src/lib/server/pos-hardware-attach.js +443 -0
- package/src/lib/server/pos-hardware-attach.js.map +1 -0
- package/src/lib/server/pos-hardware-buyer-lookup.d.ts +58 -0
- package/src/lib/server/pos-hardware-buyer-lookup.js +180 -0
- package/src/lib/server/pos-hardware-buyer-lookup.js.map +1 -0
- package/src/lib/server/pos-hardware-buyer-record.d.ts +29 -0
- package/src/lib/server/pos-hardware-buyer-record.js +86 -0
- package/src/lib/server/pos-hardware-buyer-record.js.map +1 -0
- package/src/lib/server/pos-hardware-cancel.d.ts +58 -0
- package/src/lib/server/pos-hardware-cancel.js +147 -0
- package/src/lib/server/pos-hardware-cancel.js.map +1 -0
- package/src/lib/server/pos-hardware-closure-notices.d.ts +27 -0
- package/src/lib/server/pos-hardware-closure-notices.js +85 -0
- package/src/lib/server/pos-hardware-closure-notices.js.map +1 -0
- package/src/lib/server/pos-hardware-closure.d.ts +60 -0
- package/src/lib/server/pos-hardware-closure.js +153 -0
- package/src/lib/server/pos-hardware-closure.js.map +1 -0
- package/src/lib/server/pos-hardware-in-person.d.ts +61 -0
- package/src/lib/server/pos-hardware-in-person.js +236 -0
- package/src/lib/server/pos-hardware-in-person.js.map +1 -0
- package/src/lib/server/pos-hardware-notify.d.ts +40 -2
- package/src/lib/server/pos-hardware-notify.js +195 -14
- package/src/lib/server/pos-hardware-notify.js.map +1 -1
- package/src/lib/server/pos-hardware-readers.d.ts +115 -0
- package/src/lib/server/pos-hardware-readers.js +430 -0
- package/src/lib/server/pos-hardware-readers.js.map +1 -0
- package/src/lib/server/pos-hardware-returns.d.ts +116 -0
- package/src/lib/server/pos-hardware-returns.js +502 -0
- package/src/lib/server/pos-hardware-returns.js.map +1 -0
- package/src/lib/server/pos-hardware-sale-fields.d.ts +28 -0
- package/src/lib/server/pos-hardware-sale-fields.js +44 -0
- package/src/lib/server/pos-hardware-sale-fields.js.map +1 -0
- package/src/lib/server/pos-hardware-sale.d.ts +54 -0
- package/src/lib/server/pos-hardware-sale.js +369 -0
- package/src/lib/server/pos-hardware-sale.js.map +1 -0
- package/src/lib/server/pos-hardware-tax-return-source.d.ts +99 -0
- package/src/lib/server/pos-hardware-tax-return-source.js +462 -0
- package/src/lib/server/pos-hardware-tax-return-source.js.map +1 -0
- package/src/lib/server/pos-hardware-terms.d.ts +64 -0
- package/src/lib/server/pos-hardware-terms.js +154 -0
- package/src/lib/server/pos-hardware-terms.js.map +1 -0
- package/src/lib/server/pos-hardware-user-eraser.d.ts +3 -0
- package/src/lib/server/pos-hardware-user-eraser.js +31 -7
- package/src/lib/server/pos-hardware-user-eraser.js.map +1 -1
- package/src/lib/server/pos-hardware-webhook.d.ts +5 -0
- package/src/lib/server/pos-hardware-webhook.js +51 -6
- package/src/lib/server/pos-hardware-webhook.js.map +1 -1
- package/src/lib/server/pos-hardware.d.ts +74 -1
- package/src/lib/server/pos-hardware.js +175 -10
- package/src/lib/server/pos-hardware.js.map +1 -1
- package/src/lib/server/pos-kiosk.d.ts +2 -0
- package/src/lib/server/pos-kiosk.js +17 -12
- package/src/lib/server/pos-kiosk.js.map +1 -1
- package/src/lib/server/pos-offline-card-order.d.ts +64 -0
- package/src/lib/server/pos-offline-card-order.js +102 -0
- package/src/lib/server/pos-offline-card-order.js.map +1 -0
- package/src/lib/server/pos-offline-card-reconcile.d.ts +67 -1
- package/src/lib/server/pos-offline-card-reconcile.js +215 -18
- package/src/lib/server/pos-offline-card-reconcile.js.map +1 -1
- package/src/lib/server/pos-offline-sync.d.ts +39 -0
- package/src/lib/server/pos-offline-sync.js +190 -55
- package/src/lib/server/pos-offline-sync.js.map +1 -1
- package/src/lib/server/pos-ops-gate.d.ts +28 -9
- package/src/lib/server/pos-ops-gate.js +50 -19
- package/src/lib/server/pos-ops-gate.js.map +1 -1
- package/src/lib/server/pos-ops-routes.js +24 -0
- package/src/lib/server/pos-ops-routes.js.map +1 -1
- package/src/lib/server/pos-order-refund-ids.d.ts +28 -0
- package/src/lib/server/pos-order-refund-ids.js +31 -0
- package/src/lib/server/pos-order-refund-ids.js.map +1 -0
- package/src/lib/server/pos-order.js +52 -49
- package/src/lib/server/pos-order.js.map +1 -1
- package/src/lib/server/pos-payment.js +1 -1
- package/src/lib/server/pos-payment.js.map +1 -1
- package/src/lib/server/pos-reader-splash-admin.js +30 -32
- package/src/lib/server/pos-reader-splash-admin.js.map +1 -1
- package/src/lib/server/pos-reader-splash-images-route.d.ts +17 -0
- package/src/lib/server/pos-reader-splash-images-route.js +113 -0
- package/src/lib/server/pos-reader-splash-images-route.js.map +1 -0
- package/src/lib/server/pos-reader-splash-images.d.ts +51 -0
- package/src/lib/server/pos-reader-splash-images.js +123 -0
- package/src/lib/server/pos-reader-splash-images.js.map +1 -0
- package/src/lib/server/pos-reader-splash.d.ts +68 -1
- package/src/lib/server/pos-reader-splash.js +182 -11
- package/src/lib/server/pos-reader-splash.js.map +1 -1
- package/src/lib/server/pos-readers.d.ts +29 -0
- package/src/lib/server/pos-readers.js +134 -35
- package/src/lib/server/pos-readers.js.map +1 -1
- package/src/lib/server/pos-refund-authority.d.ts +3 -1
- package/src/lib/server/pos-refund-authority.js +3 -2
- package/src/lib/server/pos-refund-authority.js.map +1 -1
- package/src/lib/server/pos-return.d.ts +10 -0
- package/src/lib/server/pos-return.js +29 -7
- package/src/lib/server/pos-return.js.map +1 -1
- package/src/lib/server/pos-sale.js +6 -1
- package/src/lib/server/pos-sale.js.map +1 -1
- package/src/lib/server/pos-shift.js +11 -0
- package/src/lib/server/pos-shift.js.map +1 -1
- package/src/lib/server/pos-staff-pin.js +29 -24
- package/src/lib/server/pos-staff-pin.js.map +1 -1
- package/src/lib/server/pos-terminal.d.ts +14 -4
- package/src/lib/server/pos-terminal.js +34 -38
- package/src/lib/server/pos-terminal.js.map +1 -1
- package/src/lib/server/printers.d.ts +7 -3
- package/src/lib/server/printers.js +18 -12
- package/src/lib/server/printers.js.map +1 -1
- package/src/lib/server/product-drafts.d.ts +11 -1
- package/src/lib/server/product-drafts.js +12 -8
- package/src/lib/server/product-drafts.js.map +1 -1
- package/src/lib/server/product.d.ts +15 -1
- package/src/lib/server/product.js +16 -3
- package/src/lib/server/product.js.map +1 -1
- package/src/lib/server/products-write.d.ts +26 -2
- package/src/lib/server/products-write.js +19 -7
- package/src/lib/server/products-write.js.map +1 -1
- package/src/lib/server/refund.js +55 -42
- package/src/lib/server/refund.js.map +1 -1
- package/src/lib/server/reservation-availability-query.d.ts +8 -0
- package/src/lib/server/reservation-availability-query.js +11 -1
- package/src/lib/server/reservation-availability-query.js.map +1 -1
- package/src/lib/server/reservation-availability.d.ts +1 -1
- package/src/lib/server/reservation-availability.js +7 -2
- package/src/lib/server/reservation-availability.js.map +1 -1
- package/src/lib/server/reservation-guests.d.ts +32 -0
- package/src/lib/server/reservation-guests.js +285 -0
- package/src/lib/server/reservation-guests.js.map +1 -0
- package/src/lib/server/reservation-walk-in.d.ts +11 -1
- package/src/lib/server/reservation-walk-in.js +56 -12
- package/src/lib/server/reservation-walk-in.js.map +1 -1
- package/src/lib/server/reserve.js +18 -5
- package/src/lib/server/reserve.js.map +1 -1
- package/src/lib/server/returns.js +9 -6
- package/src/lib/server/returns.js.map +1 -1
- package/src/lib/server/reviews.d.ts +22 -2
- package/src/lib/server/reviews.js +88 -20
- package/src/lib/server/reviews.js.map +1 -1
- package/src/lib/server/shipping-connectors.js +10 -11
- package/src/lib/server/shipping-connectors.js.map +1 -1
- package/src/lib/server/site-page-resolver.js +20 -3
- package/src/lib/server/site-page-resolver.js.map +1 -1
- package/src/lib/server/store-day.d.ts +33 -0
- package/src/lib/server/store-day.js +46 -0
- package/src/lib/server/store-day.js.map +1 -0
- package/src/lib/server/store-setup-ai-writer.d.ts +2 -1
- package/src/lib/server/store-setup-ai-writer.js +5 -6
- package/src/lib/server/store-setup-ai-writer.js.map +1 -1
- package/src/lib/server/storefront-tax.d.ts +13 -0
- package/src/lib/server/storefront-tax.js +8 -1
- package/src/lib/server/storefront-tax.js.map +1 -1
- package/src/lib/server/tax-return-source.d.ts +32 -3
- package/src/lib/server/tax-return-source.js +99 -20
- package/src/lib/server/tax-return-source.js.map +1 -1
- package/src/lib/server.js +100 -2
- package/src/lib/server.js.map +1 -1
- package/src/lib/testing/fake-firestore.js +58 -16
- package/src/lib/testing/fake-firestore.js.map +1 -1
- package/src/lib/testing/pos-ops-memory-firestore.js +18 -4
- package/src/lib/testing/pos-ops-memory-firestore.js.map +1 -1
- package/src/lib/testing/site-register-permissions.d.ts +29 -0
- package/src/lib/testing/site-register-permissions.js +38 -0
- package/src/lib/testing/site-register-permissions.js.map +1 -0
- package/src/lib/transfer/tracking.server.js +8 -5
- package/src/lib/transfer/tracking.server.js.map +1 -1
- package/src/lib/utils/add-to-cart.d.ts +2 -0
- package/src/lib/utils/add-to-cart.js +6 -3
- package/src/lib/utils/add-to-cart.js.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/components/commerce-console-page.tsx"],"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'use client'\n\nimport type { ConsolePluginPageProps } from '@aglyn/aglyn'\nimport { GridItems } from '@aglyn/shared-ui-jsx'\nimport { HubSections } from '@aglyn/shared-ui-next'\nimport type { ReactNode } from 'react'\nimport {\n COMMERCE_SETTINGS_PAGE_ZONES,\n type CommerceConsoleSectionId,\n type CommerceSettingsSectionId,\n} from './commerce-console-sections'\nimport CatalogOrganizationCard from './console/catalog-organization-card.component'\nimport CommerceAnalyticsCard from './console/commerce-analytics-card.component'\nimport CustomerNotificationsCard from './console/customer-notifications-card.component'\nimport DiscountsCard from './console/discounts-card.component'\nimport GiftCardsCard from './console/gift-cards-card.component'\nimport HostCouponsCard from './console/host-coupons-card.component'\nimport HostOrdersCard from './console/host-orders-card.component'\nimport LocationsCard from './console/locations-card.component'\nimport LocalDeliverySettingsCard from './console/local-delivery-settings-card.component'\nimport PickupDeliveryQueueCard from './console/pickup-delivery-queue-card.component'\nimport MemberPostsCard from './console/member-posts-card.component'\nimport OrderWebhooksCard from './console/order-webhooks-card.component'\nimport PaymentsSettingsCard from './console/payments-settings-card.component'\nimport PosCheckInsCard from './console/pos-ops/pos-check-ins-card.component'\nimport PosDayTotalsCard from './console/pos-ops/pos-day-totals-card.component'\nimport PosShiftHistoryCard from './console/pos-ops/pos-shift-history-card.component'\nimport PosStaffPinsCard from './console/pos-ops/pos-staff-pins-card.component'\nimport PaymentMethodsCard from './console/payment-methods-card.component'\nimport ProductsHubCard from './console/products-hub-card.component'\nimport RecoveryQueueCard from './console/recovery-queue-card.component'\nimport RegistersCard from './console/registers-card.component'\nimport RegisterHardwareCards from './console/register-hardware-card.component'\nimport PosDevicesCard from './console/pos-devices-card.component'\nimport PosHardwareCard from './console/pos-hardware-card.component'\nimport ReservationsCard from './console/reservations-card.component'\nimport ReturnSettingsCard from './console/return-settings-card.component'\nimport ReturnsCard from './console/returns-card.component'\nimport ReviewsModerationCard from './console/reviews-moderation-card.component'\nimport ReviewSettingsCard from './console/review-settings-card.component'\nimport ShippingSettingsCard from './console/shipping-settings-card.component'\nimport ShipStationCard from './console/shipstation-card.component'\nimport ShippingEasyCard from './console/shippingeasy-card.component'\nimport StockMovementsCard from './console/stock-movements-card.component'\nimport StoreSettingsCard from './console/store-settings-card.component'\nimport StorefrontTaxSummaryCard from './console/storefront-tax-summary-card.component'\nimport SuppliersCard from './console/suppliers-card.component'\nimport TaxSettingsCard from './console/tax-settings-card.component'\nimport { COMMERCE_PROMOTIONS_ZONE } from './console/store-zones'\nimport { useConsoleWidgetSlot } from '@aglyn/aglyn/app-utils/console-widget-slot-context'\n\n/**\n * A settings page's zone (AGL-3612, AGL-3713): other plugins' settings for\n * the store — label settings, carrier accounts, a tax service — under the\n * page's own cards. One zone per page, from `COMMERCE_SETTINGS_PAGE_ZONES`;\n * Integrations draws `commerceSettings`, where a widget naming no page lands.\n */\nfunction CommerceSettingsZone(props: {\n hostId: string\n page: CommerceSettingsSectionId\n}) {\n const WidgetSlot = useConsoleWidgetSlot()\n return WidgetSlot ? (\n <WidgetSlot\n slot={COMMERCE_SETTINGS_PAGE_ZONES[props.page]}\n hostId={props.hostId}\n orgId={undefined}\n />\n ) : null\n}\n\n/** One settings page: its cards in order, then its zone (AGL-3713). */\nfunction settingsPage(\n page: CommerceSettingsSectionId,\n hostId: string,\n cards: readonly ReactNode[],\n): ReactNode {\n return (\n <GridItems\n spacing={3}\n items={[\n ...cards.map((children) => ({ size: { xs: 12 }, children })),\n {\n size: { xs: 12 },\n children: <CommerceSettingsZone hostId={hostId} page={page} />,\n },\n ]}\n />\n )\n}\n\n/**\n * The `commercePromotions` zone (AGL-3640): other plugins' programs beside\n * the store's own money-off surfaces — a rewards program first.\n */\nfunction CommercePromotionsZone(props: { hostId: string }) {\n const WidgetSlot = useConsoleWidgetSlot()\n return WidgetSlot ? (\n <WidgetSlot slot={COMMERCE_PROMOTIONS_ZONE.id} hostId={props.hostId} orgId={undefined} />\n ) : null\n}\n\n/**\n * The body of one commerce section, built only when that section is the one\n * being read (AGL-2501).\n *\n * A function rather than a map of nodes on purpose: a `Record<id, ReactNode>`\n * would CONSTRUCT every section every render, and each card opens its Firestore\n * listens on mount — which is the entire cost this page exists to stop paying.\n * Only the returned branch is ever built.\n */\nfunction sectionBody(\n section: CommerceConsoleSectionId,\n hostId: string,\n canManagePos: boolean,\n): ReactNode {\n switch (section) {\n case 'catalog':\n return (\n <GridItems\n spacing={3}\n items={[\n { size: { xs: 12 }, children: <ProductsHubCard hostId={hostId} /> },\n {\n size: { xs: 12 },\n children: <CatalogOrganizationCard hostId={hostId} />,\n },\n // The ledger every stock writer fills and nothing displayed\n // (AGL-2341). Directly under the catalog, because the question\n // it answers — \"why does this count disagree with the shelf\" —\n // is asked while looking at the count.\n {\n size: { xs: 12 },\n children: <StockMovementsCard hostId={hostId} />,\n },\n { size: { xs: 12 }, children: <MemberPostsCard hostId={hostId} /> },\n ]}\n />\n )\n case 'orders':\n return (\n <GridItems\n spacing={3}\n items={[\n { size: { xs: 12 }, children: <HostOrdersCard hostId={hostId} /> },\n // What to prepare, hand over and drive out (AGL-3624). Renders\n // nothing for a store with no pickup and no local delivery.\n {\n size: { xs: 12 },\n children: <PickupDeliveryQueueCard hostId={hostId} />,\n },\n // The two queues that feed orders rather than record them\n // (AGL-2227): checkouts that stalled and shoppers waiting on\n // stock. Beneath the orders list because both are pre-order.\n {\n size: { xs: 12 },\n children: <RecoveryQueueCard hostId={hostId} />,\n },\n // One day's or one event's totals across every register, shift\n // and cashier (AGL-4037), above the shifts it adds up.\n {\n size: { xs: 12 },\n children: <PosDayTotalsCard hostId={hostId} canManagePos={canManagePos} />,\n },\n // Who is due at the window and who checked in (AGL-4043), beside\n // the day's totals.\n {\n size: { xs: 12 },\n children: <PosCheckInsCard hostId={hostId} canManagePos={canManagePos} />,\n },\n {\n size: { xs: 12 },\n children: <PosShiftHistoryCard hostId={hostId} />,\n },\n ]}\n />\n )\n case 'returns':\n // Returns (AGL-3611); `?return={id}` opens one on arrival.\n return <ReturnsCard hostId={hostId} />\n case 'promotions':\n return (\n <GridItems\n spacing={3}\n items={[\n { size: { xs: 12 }, children: <DiscountsCard hostId={hostId} /> },\n { size: { xs: 12 }, children: <HostCouponsCard hostId={hostId} /> },\n // Store credit lives with the other money-off surfaces\n // (AGL-2226) — it had no console anywhere before this.\n { size: { xs: 12 }, children: <GiftCardsCard hostId={hostId} /> },\n {\n size: { xs: 12 },\n children: <ReviewsModerationCard hostId={hostId} />,\n },\n // Who may review, and the review-request email (AGL-3736),\n // beside the queue those reviews land in.\n {\n size: { xs: 12 },\n children: <ReviewSettingsCard hostId={hostId} />,\n },\n {\n size: { xs: 12 },\n children: <CommercePromotionsZone hostId={hostId} />,\n },\n ]}\n />\n )\n case 'reservations':\n return <ReservationsCard hostId={hostId} />\n /*\n * The store's settings, a page each (AGL-3713). They were one `settings`\n * section — every card below in one column — and its old address opens\n * Payments (`COMMERCE_RETIRED_SECTIONS`). Each page is its cards, then\n * the zone where other plugins' cards for that page land.\n */\n case 'payments':\n return settingsPage(section, hostId, [\n <PaymentsSettingsCard key=\"payments\" hostId={hostId} />,\n // What shoppers may pay with (AGL-3629), beside the account the\n // money lands in.\n <PaymentMethodsCard key=\"methods\" hostId={hostId} />,\n ])\n case 'checkout':\n return settingsPage(section, hostId, [\n <StoreSettingsCard key=\"store\" hostId={hostId} />,\n // Whether buyers may ask for a return online (AGL-3611): the store's\n // policy, beside the terms and guest-checkout rules above it.\n <ReturnSettingsCard key=\"returns\" hostId={hostId} />,\n ])\n case 'taxes':\n return settingsPage(section, hostId, [\n <TaxSettingsCard key=\"tax\" hostId={hostId} />,\n ])\n case 'shipping':\n return settingsPage(section, hostId, [\n <ShippingSettingsCard key=\"shipping\" hostId={hostId} />,\n // Where parcels ship from, and pickup, per location.\n <LocationsCard key=\"locations\" hostId={hostId} />,\n // The store's own delivery (AGL-3624); pickup is per location, on\n // the Inventory locations card above.\n <LocalDeliverySettingsCard key=\"local\" hostId={hostId} />,\n <SuppliersCard key=\"suppliers\" hostId={hostId} />,\n <ShipStationCard key=\"shipstation\" hostId={hostId} />,\n // ShippingEasy, with the merchant's own keys (AGL-3633).\n <ShippingEasyCard key=\"shippingeasy\" hostId={hostId} />,\n ])\n case 'notifications':\n return settingsPage(section, hostId, [\n <CustomerNotificationsCard key=\"customers\" hostId={hostId} />,\n // The store's own endpoints for order events (AGL-3611). Renders\n // nothing for a person who may not manage them.\n <OrderWebhooksCard key=\"webhooks\" hostId={hostId} />,\n ])\n case 'pos':\n return settingsPage(section, hostId, [\n <RegistersCard key=\"registers\" hostId={hostId} />,\n <PosStaffPinsCard key=\"pins\" hostId={hostId} />,\n // A register's printers, cash drawer and status (AGL-3619), one card\n // per register, after the list that names them.\n <RegisterHardwareCards key=\"hardware\" hostId={hostId} />,\n <PosDevicesCard\n key=\"devices\"\n hostId={hostId}\n canManagePos={canManagePos}\n />,\n // Card readers bought from the platform (AGL-4038), after the card\n // that registers them. Draws nothing until the deployment opens the\n // shop.\n <PosHardwareCard\n key=\"hardware-shop\"\n hostId={hostId}\n canManagePos={canManagePos}\n />,\n ])\n case 'channels':\n case 'integrations':\n // Other plugins' cards only; the rail leaves either page out while\n // its zone has nothing to draw (`onlyWithZones`).\n return settingsPage(section, hostId, [])\n case 'analytics':\n return (\n // Two cards since AGL-2440. The tax summary lives here rather\n // than on the Taxes settings page because that page CONFIGURES tax and\n // this REPORTS what was collected — a merchant reading a figure\n // they may file from should not be one field away from changing\n // the rate that produced it.\n <GridItems\n spacing={3}\n items={[\n {\n size: { xs: 12 },\n children: <CommerceAnalyticsCard hostId={hostId} />,\n },\n {\n size: { xs: 12 },\n children: <StorefrontTaxSummaryCard hostId={hostId} />,\n },\n ]}\n />\n )\n default:\n return null\n }\n}\n\n/**\n * Commerce console page (AGL-395): the Products management surface, owned by\n * the commerce plugin and rendered by the shell's generic plugin route. The\n * product editor's media browser is supplied by the shell's\n * ConsoleMediaPickerProvider (the media library is org/session coupled and\n * stays in the app).\n *\n * ## Sections are ROUTES (AGL-2501)\n *\n * The sections hold thirty-two Firestore listens between them, and a tab\n * strip mounts every panel: opening Catalog also subscribed the orders,\n * promotions, reservations, settings and analytics cards. The `limit()` on\n * those queries is the bill — several ask for 500, and one load reached a\n * ceiling of ~4,460 documents to render one tab.\n *\n * `HubTabs lazy` bought that back as a flag somebody has to remember. A URL\n * per section makes it structural instead: the page builds one section's body\n * and the others do not exist to subscribe. Three things come with it that the\n * tab version faked — a section is linkable, the back button walks sections,\n * and which one is open is a fact about the URL rather than state kept in sync\n * with it. `commerce-console-read-cost.spec.tsx` meters it at the Firestore\n * boundary and refuses a section that listens before it is opened.\n *\n * The shell resolves the section, gates it and hands back the rail's hrefs;\n * this page only has to say what each section contains.\n */\nexport function CommerceConsolePage(props: ConsolePluginPageProps) {\n const { hostId, section, sections, basePath, permissions, hostRole } = props\n /*\n * The register's own gate, for the devices card's Pair display (AGL-3712):\n * `managePos` on a site role that may run it — what the server's\n * `mayWorkRegister` asks. The server stays the enforcement point.\n */\n const canManagePos = permissions?.managePos === true && hostRole?.canPublish === true\n\n /*\n * Nothing, deliberately, while the redirect is in flight.\n *\n * Rendering the default section here instead would issue that section's\n * listens on a URL that is about to be replaced — paying for Catalog on\n * every arrival at `/products`, which is every click of the nav tab.\n */\n if (!section || !sections?.length || !basePath) return null\n\n return (\n <HubSections sections={sections}>\n {sectionBody(section as CommerceConsoleSectionId, hostId, canManagePos)}\n </HubSections>\n )\n}\nCommerceConsolePage.displayName = 'CommerceConsolePage'\n\nexport default CommerceConsolePage\n"],"names":["GridItems","HubSections","COMMERCE_SETTINGS_PAGE_ZONES","CatalogOrganizationCard","CommerceAnalyticsCard","CustomerNotificationsCard","DiscountsCard","GiftCardsCard","HostCouponsCard","HostOrdersCard","LocationsCard","LocalDeliverySettingsCard","PickupDeliveryQueueCard","MemberPostsCard","OrderWebhooksCard","PaymentsSettingsCard","PosCheckInsCard","PosDayTotalsCard","PosShiftHistoryCard","PosStaffPinsCard","PaymentMethodsCard","ProductsHubCard","RecoveryQueueCard","RegistersCard","RegisterHardwareCards","PosDevicesCard","PosHardwareCard","ReservationsCard","ReturnSettingsCard","ReturnsCard","ReviewsModerationCard","ReviewSettingsCard","ShippingSettingsCard","ShipStationCard","ShippingEasyCard","StockMovementsCard","StoreSettingsCard","StorefrontTaxSummaryCard","SuppliersCard","TaxSettingsCard","COMMERCE_PROMOTIONS_ZONE","useConsoleWidgetSlot","CommerceSettingsZone","props","WidgetSlot","slot","page","hostId","orgId","undefined","settingsPage","cards","spacing","items","map","children","size","xs","CommercePromotionsZone","id","sectionBody","section","canManagePos","CommerceConsolePage","sections","basePath","permissions","hostRole","managePos","canPublish","length","displayName"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/components/commerce-console-page.tsx"],"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'use client'\n\nimport type { ConsolePluginPageProps } from '@aglyn/aglyn'\nimport { GridItems } from '@aglyn/shared-ui-jsx'\nimport { HubSections } from '@aglyn/shared-ui-next'\nimport { lazy, Suspense, type ReactNode } from 'react'\nimport { Stack } from '@mui/material'\nimport {\n COMMERCE_SETTINGS_PAGE_ZONES,\n type CommerceConsoleSectionId,\n type CommerceSettingsSectionId,\n} from './commerce-console-sections'\nimport CatalogOrganizationCard from './console/catalog-organization-card.component'\nimport CommerceAnalyticsCard from './console/commerce-analytics-card.component'\nimport CustomerNotificationsCard from './console/customer-notifications-card.component'\nimport DiscountsCard from './console/discounts-card.component'\nimport GiftCardsCard from './console/gift-cards-card.component'\nimport HostCouponsCard from './console/host-coupons-card.component'\nimport HostOrdersCard from './console/host-orders-card.component'\nimport LocationsCard from './console/locations-card.component'\nimport LocalDeliverySettingsCard from './console/local-delivery-settings-card.component'\nimport PickupDeliveryQueueCard from './console/pickup-delivery-queue-card.component'\nimport MemberPostsCard from './console/member-posts-card.component'\nimport OrderWebhooksCard from './console/order-webhooks-card.component'\nimport PaymentsSettingsCard from './console/payments-settings-card.component'\nimport PosCheckInsCard from './console/pos-ops/pos-check-ins-card.component'\nimport PosDayTotalsCard from './console/pos-ops/pos-day-totals-card.component'\nimport PosShiftHistoryCard from './console/pos-ops/pos-shift-history-card.component'\nimport PosStaffPinsCard from './console/pos-ops/pos-staff-pins-card.component'\nimport PaymentMethodsCard from './console/payment-methods-card.component'\nimport ProductsHubCard from './console/products-hub-card.component'\nimport RecoveryQueueCard from './console/recovery-queue-card.component'\nimport RegistersCard from './console/registers-card.component'\nimport RegisterHardwareCards from './console/register-hardware-card.component'\nimport PosDevicesCard from './console/pos-devices-card.component'\nimport PosHardwareCard from './console/pos-hardware-card.component'\n\n/**\n * Card readers the workspace bought in person, waiting to be set up\n * (AGL-4038): its own chunk, drawn only while there is one.\n */\nconst PosHardwareWaitingCard = lazy(() => import('./console/pos-hardware-waiting-card.component'))\nimport { holdsPosPermission, posPermissionRefusal } from '../model/plugin-permissions'\nimport ReservationsCard from './console/reservations-card.component'\nimport ReturnSettingsCard from './console/return-settings-card.component'\nimport ReturnsCard from './console/returns-card.component'\nimport ReviewsModerationCard from './console/reviews-moderation-card.component'\nimport ReviewSettingsCard from './console/review-settings-card.component'\nimport ShippingSettingsCard from './console/shipping-settings-card.component'\nimport ShipStationCard from './console/shipstation-card.component'\nimport ShippingEasyCard from './console/shippingeasy-card.component'\nimport StockMovementsCard from './console/stock-movements-card.component'\nimport StoreSettingsCard from './console/store-settings-card.component'\nimport StorefrontTaxSummaryCard from './console/storefront-tax-summary-card.component'\nimport SuppliersCard from './console/suppliers-card.component'\nimport TaxSettingsCard from './console/tax-settings-card.component'\nimport { COMMERCE_PROMOTIONS_ZONE } from './console/store-zones'\nimport { useConsoleWidgetSlot } from '@aglyn/aglyn/app-utils/console-widget-slot-context'\n\n/**\n * A settings page's zone (AGL-3612, AGL-3713): other plugins' settings for\n * the store — label settings, carrier accounts, a tax service — under the\n * page's own cards. One zone per page, from `COMMERCE_SETTINGS_PAGE_ZONES`;\n * Integrations draws `commerceSettings`, where a widget naming no page lands.\n */\nfunction CommerceSettingsZone(props: {\n hostId: string\n page: CommerceSettingsSectionId\n}) {\n const WidgetSlot = useConsoleWidgetSlot()\n return WidgetSlot ? (\n <WidgetSlot\n slot={COMMERCE_SETTINGS_PAGE_ZONES[props.page]}\n hostId={props.hostId}\n orgId={undefined}\n />\n ) : null\n}\n\n/** One settings page: its cards in order, then its zone (AGL-3713). */\nfunction settingsPage(\n page: CommerceSettingsSectionId,\n hostId: string,\n cards: readonly ReactNode[],\n): ReactNode {\n return (\n <GridItems\n spacing={3}\n items={[\n ...cards.map((children) => ({ size: { xs: 12 }, children })),\n {\n size: { xs: 12 },\n children: <CommerceSettingsZone hostId={hostId} page={page} />,\n },\n ]}\n />\n )\n}\n\n/**\n * The `commercePromotions` zone (AGL-3640): other plugins' programs beside\n * the store's own money-off surfaces — a rewards program first.\n */\nfunction CommercePromotionsZone(props: { hostId: string }) {\n const WidgetSlot = useConsoleWidgetSlot()\n return WidgetSlot ? (\n <WidgetSlot slot={COMMERCE_PROMOTIONS_ZONE.id} hostId={props.hostId} orgId={undefined} />\n ) : null\n}\n\n/**\n * The body of one commerce section, built only when that section is the one\n * being read (AGL-2501).\n *\n * A function rather than a map of nodes on purpose: a `Record<id, ReactNode>`\n * would CONSTRUCT every section every render, and each card opens its Firestore\n * listens on mount — which is the entire cost this page exists to stop paying.\n * Only the returned branch is ever built.\n */\nfunction sectionBody(\n section: CommerceConsoleSectionId,\n hostId: string,\n canManagePos: boolean,\n /** The register's finer keys this page's cards ask (AGL-4047). */\n pos: { canSetUpDevices: boolean; canBuyHardware: boolean; canCashDrawer: boolean } = {\n canSetUpDevices: canManagePos,\n canBuyHardware: canManagePos,\n canCashDrawer: canManagePos,\n },\n /** The reservation keys this site decides for the member (AGL-4047). */\n reservations: { canManage: boolean; canWalkIn: boolean } = { canManage: true, canWalkIn: true },\n): ReactNode {\n switch (section) {\n case 'catalog':\n return (\n <GridItems\n spacing={3}\n items={[\n { size: { xs: 12 }, children: <ProductsHubCard hostId={hostId} /> },\n {\n size: { xs: 12 },\n children: <CatalogOrganizationCard hostId={hostId} />,\n },\n // The ledger every stock writer fills and nothing displayed\n // (AGL-2341). Directly under the catalog, because the question\n // it answers — \"why does this count disagree with the shelf\" —\n // is asked while looking at the count.\n {\n size: { xs: 12 },\n children: <StockMovementsCard hostId={hostId} />,\n },\n { size: { xs: 12 }, children: <MemberPostsCard hostId={hostId} /> },\n ]}\n />\n )\n case 'orders':\n return (\n <GridItems\n spacing={3}\n items={[\n { size: { xs: 12 }, children: <HostOrdersCard hostId={hostId} /> },\n // What to prepare, hand over and drive out (AGL-3624). Renders\n // nothing for a store with no pickup and no local delivery.\n {\n size: { xs: 12 },\n children: <PickupDeliveryQueueCard hostId={hostId} />,\n },\n // The two queues that feed orders rather than record them\n // (AGL-2227): checkouts that stalled and shoppers waiting on\n // stock. Beneath the orders list because both are pre-order.\n {\n size: { xs: 12 },\n children: <RecoveryQueueCard hostId={hostId} />,\n },\n // One day's or one event's totals across every register, shift\n // and cashier (AGL-4037), above the shifts it adds up.\n {\n size: { xs: 12 },\n children: <PosDayTotalsCard hostId={hostId} canManagePos={canManagePos} />,\n },\n // Who is due at the window and who checked in (AGL-4043), beside\n // the day's totals.\n {\n size: { xs: 12 },\n children: <PosCheckInsCard hostId={hostId} canManagePos={canManagePos} />,\n },\n {\n size: { xs: 12 },\n children: <PosShiftHistoryCard hostId={hostId} />,\n },\n ]}\n />\n )\n case 'returns':\n // Returns (AGL-3611); `?return={id}` opens one on arrival.\n return <ReturnsCard hostId={hostId} />\n case 'promotions':\n return (\n <GridItems\n spacing={3}\n items={[\n { size: { xs: 12 }, children: <DiscountsCard hostId={hostId} /> },\n { size: { xs: 12 }, children: <HostCouponsCard hostId={hostId} /> },\n // Store credit lives with the other money-off surfaces\n // (AGL-2226) — it had no console anywhere before this.\n { size: { xs: 12 }, children: <GiftCardsCard hostId={hostId} /> },\n {\n size: { xs: 12 },\n children: <ReviewsModerationCard hostId={hostId} />,\n },\n // Who may review, and the review-request email (AGL-3736),\n // beside the queue those reviews land in.\n {\n size: { xs: 12 },\n children: <ReviewSettingsCard hostId={hostId} />,\n },\n {\n size: { xs: 12 },\n children: <CommercePromotionsZone hostId={hostId} />,\n },\n ]}\n />\n )\n case 'reservations':\n return (\n <ReservationsCard\n hostId={hostId}\n canManage={reservations.canManage}\n canWalkIn={reservations.canWalkIn}\n />\n )\n /*\n * The store's settings, a page each (AGL-3713). They were one `settings`\n * section — every card below in one column — and its old address opens\n * Payments (`COMMERCE_RETIRED_SECTIONS`). Each page is its cards, then\n * the zone where other plugins' cards for that page land.\n */\n case 'payments':\n return settingsPage(section, hostId, [\n <PaymentsSettingsCard key=\"payments\" hostId={hostId} />,\n // What shoppers may pay with (AGL-3629), beside the account the\n // money lands in.\n <PaymentMethodsCard key=\"methods\" hostId={hostId} />,\n ])\n case 'checkout':\n return settingsPage(section, hostId, [\n <StoreSettingsCard key=\"store\" hostId={hostId} />,\n // Whether buyers may ask for a return online (AGL-3611): the store's\n // policy, beside the terms and guest-checkout rules above it.\n <ReturnSettingsCard key=\"returns\" hostId={hostId} />,\n ])\n case 'taxes':\n return settingsPage(section, hostId, [\n <TaxSettingsCard key=\"tax\" hostId={hostId} />,\n ])\n case 'shipping':\n return settingsPage(section, hostId, [\n <ShippingSettingsCard key=\"shipping\" hostId={hostId} />,\n // Where parcels ship from, and pickup, per location.\n <LocationsCard key=\"locations\" hostId={hostId} />,\n // The store's own delivery (AGL-3624); pickup is per location, on\n // the Inventory locations card above.\n <LocalDeliverySettingsCard key=\"local\" hostId={hostId} />,\n <SuppliersCard key=\"suppliers\" hostId={hostId} />,\n <ShipStationCard key=\"shipstation\" hostId={hostId} />,\n // ShippingEasy, with the merchant's own keys (AGL-3633).\n <ShippingEasyCard key=\"shippingeasy\" hostId={hostId} />,\n ])\n case 'notifications':\n return settingsPage(section, hostId, [\n <CustomerNotificationsCard key=\"customers\" hostId={hostId} />,\n // The store's own endpoints for order events (AGL-3611). Renders\n // nothing for a person who may not manage them.\n <OrderWebhooksCard key=\"webhooks\" hostId={hostId} />,\n ])\n case 'pos':\n return settingsPage(section, hostId, [\n // A reader bought in person waits at the top until it is set up\n // (AGL-4038), in the registers' own grid cell so an empty one\n // leaves no gap.\n <Stack key=\"registers\" spacing={3}>\n <Suspense fallback={null}>\n <PosHardwareWaitingCard\n hostId={hostId}\n {...(pos.canSetUpDevices ? {} : { devicesBlockedReason: posPermissionRefusal('posDevices') })}\n />\n </Suspense>\n <RegistersCard hostId={hostId} />\n </Stack>,\n <PosStaffPinsCard key=\"pins\" hostId={hostId} />,\n // A register's printers, cash drawer and status (AGL-3619), one card\n // per register, after the list that names them.\n <RegisterHardwareCards\n key=\"hardware\"\n hostId={hostId}\n blocked={{\n ...(pos.canSetUpDevices ? {} : { devices: posPermissionRefusal('posDevices') }),\n ...(pos.canCashDrawer ? {} : { drawer: posPermissionRefusal('posCashDrawer') }),\n }}\n />,\n <PosDevicesCard\n key=\"devices\"\n hostId={hostId}\n canManagePos={canManagePos}\n canSetUpDevices={pos.canSetUpDevices}\n />,\n // Card readers bought from the platform (AGL-4038), after the card\n // that registers them. Draws nothing until the deployment opens the\n // shop.\n <PosHardwareCard\n key=\"hardware-shop\"\n hostId={hostId}\n canManagePos={canManagePos}\n canBuyHardware={pos.canBuyHardware}\n />,\n ])\n case 'channels':\n case 'integrations':\n // Other plugins' cards only; the rail leaves either page out while\n // its zone has nothing to draw (`onlyWithZones`).\n return settingsPage(section, hostId, [])\n case 'analytics':\n return (\n // Two cards since AGL-2440. The tax summary lives here rather\n // than on the Taxes settings page because that page CONFIGURES tax and\n // this REPORTS what was collected — a merchant reading a figure\n // they may file from should not be one field away from changing\n // the rate that produced it.\n <GridItems\n spacing={3}\n items={[\n {\n size: { xs: 12 },\n children: <CommerceAnalyticsCard hostId={hostId} />,\n },\n {\n size: { xs: 12 },\n children: <StorefrontTaxSummaryCard hostId={hostId} />,\n },\n ]}\n />\n )\n default:\n return null\n }\n}\n\n/**\n * Commerce console page (AGL-395): the Products management surface, owned by\n * the commerce plugin and rendered by the shell's generic plugin route. The\n * product editor's media browser is supplied by the shell's\n * ConsoleMediaPickerProvider (the media library is org/session coupled and\n * stays in the app).\n *\n * ## Sections are ROUTES (AGL-2501)\n *\n * The sections hold thirty-two Firestore listens between them, and a tab\n * strip mounts every panel: opening Catalog also subscribed the orders,\n * promotions, reservations, settings and analytics cards. The `limit()` on\n * those queries is the bill — several ask for 500, and one load reached a\n * ceiling of ~4,460 documents to render one tab.\n *\n * `HubTabs lazy` bought that back as a flag somebody has to remember. A URL\n * per section makes it structural instead: the page builds one section's body\n * and the others do not exist to subscribe. Three things come with it that the\n * tab version faked — a section is linkable, the back button walks sections,\n * and which one is open is a fact about the URL rather than state kept in sync\n * with it. `commerce-console-read-cost.spec.tsx` meters it at the Firestore\n * boundary and refuses a section that listens before it is opened.\n *\n * The shell resolves the section, gates it and hands back the rail's hrefs;\n * this page only has to say what each section contains.\n */\nexport function CommerceConsolePage(props: ConsolePluginPageProps) {\n const { hostId, section, sections, basePath, permissions } = props\n /*\n * The register's own gate, for the devices card's Pair display (AGL-3712):\n * `managePos` — what the server's `mayWorkRegister` asks. The key decides,\n * not the site role (AGL-4047). The server stays the enforcement point.\n */\n const canManagePos = permissions?.managePos === true\n // The register's finer keys (AGL-4047), each following `managePos` unless a\n // role or the member sets it — what the devices and hardware routes ask.\n // Buying hardware stands on its own: the Hardware card is this page's for a\n // member who holds it without the register.\n const pos = {\n canSetUpDevices: canManagePos && holdsPosPermission(permissions, 'posDevices'),\n canBuyHardware: holdsPosPermission(permissions, 'posBuyHardware'),\n canCashDrawer: canManagePos && holdsPosPermission(permissions, 'posCashDrawer'),\n }\n // The reservation keys (AGL-4047), whose preset is the member's role on\n // this site; the shell decides them for the site in view. A map that does\n // not carry one (a shell that predates them) leaves the card as it was:\n // the rules and the routes decide.\n const reservations = {\n canManage: permissions?.['commerce.reservations'] !== false,\n canWalkIn: permissions?.['commerce.walkIns'] !== false,\n }\n\n /*\n * Nothing, deliberately, while the redirect is in flight.\n *\n * Rendering the default section here instead would issue that section's\n * listens on a URL that is about to be replaced — paying for Catalog on\n * every arrival at `/products`, which is every click of the nav tab.\n */\n if (!section || !sections?.length || !basePath) return null\n\n return (\n <HubSections sections={sections}>\n {sectionBody(section as CommerceConsoleSectionId, hostId, canManagePos, pos, reservations)}\n </HubSections>\n )\n}\nCommerceConsolePage.displayName = 'CommerceConsolePage'\n\nexport default CommerceConsolePage\n"],"names":["GridItems","HubSections","lazy","Suspense","Stack","COMMERCE_SETTINGS_PAGE_ZONES","CatalogOrganizationCard","CommerceAnalyticsCard","CustomerNotificationsCard","DiscountsCard","GiftCardsCard","HostCouponsCard","HostOrdersCard","LocationsCard","LocalDeliverySettingsCard","PickupDeliveryQueueCard","MemberPostsCard","OrderWebhooksCard","PaymentsSettingsCard","PosCheckInsCard","PosDayTotalsCard","PosShiftHistoryCard","PosStaffPinsCard","PaymentMethodsCard","ProductsHubCard","RecoveryQueueCard","RegistersCard","RegisterHardwareCards","PosDevicesCard","PosHardwareCard","PosHardwareWaitingCard","holdsPosPermission","posPermissionRefusal","ReservationsCard","ReturnSettingsCard","ReturnsCard","ReviewsModerationCard","ReviewSettingsCard","ShippingSettingsCard","ShipStationCard","ShippingEasyCard","StockMovementsCard","StoreSettingsCard","StorefrontTaxSummaryCard","SuppliersCard","TaxSettingsCard","COMMERCE_PROMOTIONS_ZONE","useConsoleWidgetSlot","CommerceSettingsZone","props","WidgetSlot","slot","page","hostId","orgId","undefined","settingsPage","cards","spacing","items","map","children","size","xs","CommercePromotionsZone","id","sectionBody","section","canManagePos","pos","canSetUpDevices","canBuyHardware","canCashDrawer","reservations","canManage","canWalkIn","fallback","devicesBlockedReason","blocked","devices","drawer","CommerceConsolePage","sections","basePath","permissions","managePos","length","displayName"],"mappings":"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"}
|
|
@@ -795,7 +795,8 @@ const usd = (cents)=>`$${((cents != null ? cents : 0) / 100).toFixed(2)}`;
|
|
|
795
795
|
textDecoration: 'line-through'
|
|
796
796
|
} : {}),
|
|
797
797
|
color: withdrawn ? 'text.secondary' : 'text.primary',
|
|
798
|
-
children: `${line.quantity}× ${line.name}` + (line.variantLabel ? ` — ${line.variantLabel}` : '')
|
|
798
|
+
children: `${line.quantity}× ${line.name}` + (line.variantLabel ? ` — ${line.variantLabel}` : '') + // The day the buyer chose to use a pass (AGL-4043).
|
|
799
|
+
(line.useDayKey ? ` · for ${CommerceModel.checkInDayLabel(line.useDayKey)}` : '')
|
|
799
800
|
}),
|
|
800
801
|
fulfilledByLine[index] ? /*#__PURE__*/ _jsx(Chip, {
|
|
801
802
|
label: `${fulfilledByLine[index]} of ${line.quantity} fulfilled`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../../libs/plugins/commerce/src/lib/components/console/order-detail-dialog.component.tsx"],"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'use client'\n\nimport * as CommerceModel from '../../model'\nimport { buildPackingSlipHtml } from '../../utils/order-packing-slip'\nimport { orderRefundPrompt, REFUND_BLOCKED_BY_DISPUTE } from '../../model/order-dialog'\n// The CRM's address from the SHARED builder, not the plugin (AGL-2622): the\n// CRM already reaches marketing, and marketing reaches commerce, so an\n// import of the CRM from here would close a cycle between the three\n// plugins. The shared builder is pinned against the CRM's own routes by a\n// spec, so the address is the same one the hub resolves.\nimport { pluginRecordByEmailHref } from '@aglyn/aglyn/plugin-manager/plugin-record-routes'\nimport { describePaymentRisk } from '@aglyn/aglyn/app-utils/payment-risk'\nimport { AppLink, useConfirmationContext } from '@aglyn/shared-ui-jsx'\nimport { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport {\n Button,\n Chip,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n Divider,\n Stack,\n TextField,\n Tooltip,\n Typography,\n} from '@mui/material'\nimport { doc, getDoc, runTransaction, updateDoc } from 'firebase/firestore'\nimport { useParams } from 'next/navigation'\nimport { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { useFirestore, useUser } from '@aglyn/tenant-feature-instance'\nimport OrderLocalFulfillmentPanel from './order-local-fulfillment-panel.component'\nimport { authorizedFetch } from '@aglyn/shared-util-http/authorized-token'\nimport {\n type ConsoleWidgetSlotRenderer,\n useConsoleWidgetSlot,\n} from '@aglyn/aglyn/app-utils/console-widget-slot-context'\nimport {\n consoleOrderZoneOrder,\n FulfillItemsPanel,\n FulfillmentList,\n type FulfillItemsSubmission,\n toZoneFulfillment,\n} from './order-fulfillment-panel.component'\nimport {\n type ConsoleFulfillmentRequest,\n type ConsoleOrderZoneFulfillment,\n ORDER_DETAIL_ZONE,\n ORDER_FULFILLMENT_ZONE,\n} from './order-zones'\nimport { OrderInvoiceButton } from './order-invoice.component'\nimport { OrderReceiptResend } from './order-receipt-resend.component'\nimport { OrderReturns } from './order-returns.component'\nimport { PosReceiptActions } from './pos-ops/pos-receipt-actions.component'\nimport { OrderOfflineNotice } from './order-offline-notice.component'\n\nexport interface OrderDetailDialogProps {\n hostId: string\n order: (CommerceModel.HostOrder & { $id: string }) | null\n onClose: () => void\n}\n\nconst STATUS_COLOR: Record<\n string,\n 'default' | 'success' | 'warning' | 'error' | 'info'\n> = {\n pending: 'warning',\n paid: 'info',\n partially_fulfilled: 'info',\n fulfilled: 'success',\n delivered: 'success',\n cancelled: 'default',\n refunded: 'error',\n}\n\n/**\n * The dispute chip's colour (AGL-1796).\n *\n * `open` is WARNING rather than error because it is the case that still has a\n * deadline on it — the merchant can still act, and a red chip on a case they\n * might win says the money is gone when it is not. `lost` is the one that took\n * the money, and shares `refunded`'s red for that reason.\n */\nexport const DISPUTE_COLOR: Record<\n CommerceModel.OrderDisputeTone,\n 'default' | 'success' | 'warning' | 'error'\n> = {\n open: 'warning',\n lost: 'error',\n won: 'success',\n settled: 'default',\n}\n\nconst usd = (cents: number | undefined) =>\n `$${((cents ?? 0) / 100).toFixed(2)}`\n\n/**\n * A zone hosted in the dialog, drawn again only when what it is handed\n * changes — the product editor's reasoning (AGL-3423): the shell's renderer\n * is not memoized, and the dialog redraws on every keystroke in its fields.\n */\nconst HostedZone = memo(function HostedZone(\n props: { renderer: ConsoleWidgetSlotRenderer; slot: string } & Record<string, unknown>,\n) {\n const { renderer: Renderer, ...zone } = props\n return <Renderer {...zone} />\n})\n\n/** A fresh key for one attempt at a write the route dedupes on. */\nconst newAttemptKey = () =>\n globalThis.crypto?.randomUUID?.() ??\n `${Date.now()}-${Math.random().toString(36).slice(2)}`\n\n/**\n * Order detail (AGL-287): timeline, line items, totals, and the actions\n * the status machine allows — fulfill with tracking, refund, cancel, mark\n * delivered (each a server route that re-asks the transition under the\n * write), notes, printable packing slip.\n */\nexport function OrderDetailDialog(props: OrderDetailDialogProps) {\n const { hostId, order: rawOrder, onClose } = props\n const firestore = useFirestore()\n const { data: user } = useUser()\n const { enqueueSnackbar } = useSnackbar()\n const { confirm } = useConfirmationContext()\n const [fulfilling, setFulfilling] = useState(false)\n // The store's currency, which a hand-entered shipping cost is typed in\n // (AGL-3705). Read when the Fulfill items panel opens, not before.\n const [storeCurrency, setStoreCurrency] = useState<string | undefined>(undefined)\n useEffect(() => {\n if (!fulfilling || storeCurrency) return\n let live = true\n // A failed read leaves the field in US dollars, the store default.\n Promise.resolve()\n .then(() => getDoc(doc(firestore, 'hosts', hostId, 'settings', 'store')))\n .then((snapshot) => {\n const currency = String(snapshot.get('currency') ?? '').trim()\n if (live && currency) setStoreCurrency(currency.toUpperCase())\n })\n .catch(() => undefined)\n return () => {\n live = false\n }\n }, [fulfilling, storeCurrency, firestore, hostId])\n const WidgetSlot = useConsoleWidgetSlot()\n const [note, setNote] = useState('')\n const [busy, setBusy] = useState(false)\n\n const order = rawOrder ? CommerceModel.liftLegacyOrder(rawOrder) : null\n const orderId = rawOrder?.$id\n /*\n * Where the buyer's CONTACT is (AGL-2622). A checkout that carried an\n * address updated a person in the CRM — a customer, with this order on\n * their timeline — and the dialog links there by the address, because\n * the contact's id is minted at capture and nothing on the order holds\n * it. The Contacts list is the lookup and opens the record on one match,\n * at the address the plugin that keeps contacts publishes; where none\n * does, there is no link. A guest checkout with no address updated\n * nobody, so there is no link either. Built from the route params already\n * in the URL — no document is read to draw a link — and absent until they\n * settle, so the dialog never offers a link to a half-built address.\n */\n const params = useParams<{ orgSlug?: string; host?: string }>()\n const customerCrmHref =\n params?.orgSlug && params?.host && order?.customerEmail\n ? pluginRecordByEmailHref(\n 'contact',\n { orgSlug: String(params.orgSlug), host: String(params.host) },\n String(order.customerEmail),\n )\n : null\n\n /**\n * The one client write left in this dialog, and it is timeline-only ON\n * PURPOSE: notes carry no status, so `ORDER_TRANSITIONS` has nothing to say\n * about them and they stay out of the server routes' way. Every status\n * write goes through a route that re-asks the transition under the write —\n * cancel (AGL-1818), fulfil and mark-delivered (AGL-1819), refund\n * (AGL-1696). The moment a status rides along with a note, it must move\n * too; `order-fulfill-wiring.spec.tsx` pins the patch to `timeline` alone.\n */\n const write = useCallback(\n async (patch: Record<string, unknown>) => {\n if (!orderId) return\n await updateDoc(doc(firestore, 'hosts', hostId, 'orders', orderId), patch)\n },\n [firestore, hostId, orderId],\n )\n\n /**\n * Fulfil and mark-delivered go through `/api/commerce/fulfill-order`\n * (AGL-1819), not a client write — the same stale-dialog hole the cancel\n * swap (AGL-1818) closed: `can(…)` below only decides whether to RENDER\n * the buttons, so a dialog held open while the order was refunded in\n * another tab used to write `fulfilled` straight onto it. The route\n * re-asks `canTransitionOrder` inside the transaction that writes the\n * status, and that race now comes back as a 409 carrying the state that\n * refused.\n *\n * The messages follow the AGL-1784/1786 contract — say what happened: a\n * 409 is the guard refusing, not the machinery failing; the route's own\n * 500 is a rolled-back transaction (nothing landed, retry is safe and\n * correct); an answer with no JSON word from the handler, or no answer at\n * all, is NOT KNOWN — never \"nothing happened\". A retry is safe in every\n * case because the route writes once: a repeat finds the order already in\n * the target status and returns `already` without appending a second copy\n * of the same fulfillment.\n */\n const transition = useCallback(\n async (\n to: 'fulfilled' | 'delivered' | null,\n extra: Record<string, unknown>,\n copy: {\n done: string\n already: string\n subject: string\n action: string\n partial?: string\n },\n headers: Record<string, string> = {},\n ): Promise<false | Record<string, any>> => {\n if (!orderId) return false\n setBusy(true)\n try {\n let response: Response\n try {\n response = await authorizedFetch(\n user,\n '/api/commerce/fulfill-order',\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...headers },\n body: JSON.stringify({ hostId, orderId, ...(to ? { to } : {}), ...extra }),\n },\n )\n } catch (error) {\n console.error(error)\n enqueueSnackbar(\n `The request did not complete, so it is NOT known whether ${copy.subject}. ` +\n 'Reopen the order to check — retrying is safe, the server ' +\n 'writes it once.',\n { variant: 'error', allowDuplicate: true },\n )\n return false\n }\n const payload: any = await response.json().catch(() => ({}))\n if (!response.ok) {\n if (response.status === 409) {\n // The transition guard refusing: the order moved on (refunded,\n // cancelled) while this dialog was open. The route's message\n // names the state that refused it, and nothing was written.\n enqueueSnackbar(\n payload?.error ?? `This order can no longer be ${to ?? 'changed'}`,\n {\n variant: 'warning',\n allowDuplicate: true,\n },\n )\n } else if (payload?.error && response.status < 500) {\n // A refusal that wrote nothing — session, role, or an order that\n // is not there. The route's own word, verbatim.\n enqueueSnackbar(payload.error, {\n variant: 'error',\n allowDuplicate: true,\n })\n } else if (payload?.error) {\n // The route's 500 is a rolled-back transaction: nothing landed.\n // Only the handler's own JSON word licenses saying so.\n enqueueSnackbar(\n `${payload.error} — nothing changed, the order is as it was. Retrying is safe.`,\n { variant: 'error', allowDuplicate: true },\n )\n } else {\n // No JSON word from the handler (a gateway page, a proxy\n // timeout): whether the write landed is NOT known.\n enqueueSnackbar(\n `The ${copy.action} failed (${response.status}) and it is NOT ` +\n 'known whether it landed. Reopen the order to check — ' +\n 'retrying is safe, the server writes it once.',\n { variant: 'error', allowDuplicate: true },\n )\n }\n return false\n }\n enqueueSnackbar(\n payload?.already\n ? copy.already\n : payload?.status === 'partially_fulfilled' && copy.partial\n ? copy.partial\n : copy.done,\n {\n variant: 'success',\n persist: false,\n },\n )\n return payload ?? {}\n } finally {\n setBusy(false)\n }\n },\n [orderId, user, hostId, enqueueSnackbar],\n )\n\n /**\n * One key per shipment attempt (AGL-3611), the refund's shape: a partial\n * shipment leaves the order open to more, so \"already in the target\n * status\" cannot catch its retry — the key does. Retired on a definitive\n * answer; kept across a network failure or a 5xx, the window it covers.\n */\n const fulfillKey = useRef('')\n useEffect(() => {\n fulfillKey.current = ''\n }, [orderId])\n\n const fulfill = useCallback(\n async (submission: FulfillItemsSubmission, key: string) => {\n const payload = await transition(\n 'fulfilled',\n {\n ...(submission.lineItems ? { lineItems: submission.lineItems } : {}),\n ...(submission.carrier ? { carrier: submission.carrier } : {}),\n ...(submission.trackingNumber ? { trackingNumber: submission.trackingNumber } : {}),\n ...(submission.trackingUrl ? { trackingUrl: submission.trackingUrl } : {}),\n ...(submission.labelUrl ? { labelUrl: submission.labelUrl } : {}),\n ...(typeof submission.shippingCostCents === 'number'\n ? { shippingCostCents: submission.shippingCostCents }\n : {}),\n ...(submission.notify ? {} : { notify: false }),\n },\n {\n done: 'Order fulfilled',\n partial: 'Items fulfilled — the rest are still to ship',\n already: 'Order was already fulfilled',\n subject: 'the order was fulfilled',\n action: 'fulfillment',\n },\n { 'Idempotency-Key': key },\n )\n return payload\n },\n [transition],\n )\n\n const handleFulfill = useCallback(\n async (submission: FulfillItemsSubmission) => {\n if (!order) return false\n if (!fulfillKey.current) fulfillKey.current = newAttemptKey()\n const payload = await fulfill(submission, fulfillKey.current)\n // The refused or unknown case keeps the form open — there is nothing to\n // celebrate, and the tracking is not yet recorded anywhere.\n if (payload) {\n fulfillKey.current = ''\n setFulfilling(false)\n }\n return Boolean(payload)\n },\n [order, fulfill],\n )\n\n const handleUpdateTracking = useCallback(\n async (\n fulfillmentId: string,\n next: { carrier: string; trackingNumber: string; trackingUrl?: string },\n ) =>\n Boolean(\n await transition(\n null,\n { action: 'update-tracking', fulfillmentId, ...next },\n {\n done: 'Tracking updated',\n already: 'Tracking was already up to date',\n subject: 'the tracking was updated',\n action: 'tracking update',\n },\n ),\n ),\n [transition],\n )\n\n const handleCancelFulfillment = useCallback(\n async (fulfillmentId: string) => {\n const confirmed = await confirm({\n title: 'Cancel this shipment?',\n description:\n 'Its items go back to unfulfilled and can be shipped again. The buyer is not told.',\n confirmationText: 'Cancel shipment',\n confirmationButtonProps: { color: 'error' },\n })\n .then(() => true)\n .catch(() => false)\n if (!confirmed) return\n await transition(\n null,\n { action: 'cancel-fulfillment', fulfillmentId },\n {\n done: 'Shipment canceled',\n already: 'Shipment was already canceled',\n subject: 'the shipment was canceled',\n action: 'shipment cancel',\n },\n )\n },\n [confirm, transition],\n )\n\n /**\n * A widget's shipment (the zones' `recordFulfillment`): the same route,\n * keyed by the widget's own attempt key, and a throw with the route's words\n * when it refuses, so the widget can tell the merchant why.\n */\n const recordFulfillment = useCallback(\n async (request: ConsoleFulfillmentRequest): Promise<ConsoleOrderZoneFulfillment> => {\n const payload = await fulfill(\n {\n ...(request.lineItems ? { lineItems: request.lineItems.map((entry) => ({ ...entry })) } : {}),\n carrier: String(request.carrier ?? ''),\n trackingNumber: String(request.trackingNumber ?? ''),\n ...(request.trackingUrl ? { trackingUrl: request.trackingUrl } : {}),\n ...(request.labelUrl ? { labelUrl: request.labelUrl } : {}),\n notify: request.notify !== false,\n },\n String(request.idempotencyKey || newAttemptKey()),\n )\n if (!payload || !payload.fulfillment || !order) {\n throw new Error('The shipment was not recorded. Check the order and try again.')\n }\n setFulfilling(false)\n return toZoneFulfillment(order, payload.fulfillment)\n },\n [fulfill, order],\n )\n\n const zoneOrder = useMemo(\n () => (order && orderId ? consoleOrderZoneOrder(order, orderId) : null),\n // `rawOrder` is the snapshot; `order` is derived from it on each render.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [rawOrder, orderId],\n )\n\n const handleDelivered = useCallback(async () => {\n if (!order) return\n await transition(\n 'delivered',\n {},\n {\n done: 'Order marked delivered',\n already: 'Order was already marked delivered',\n subject: 'the order was marked delivered',\n action: 'delivery update',\n },\n )\n }, [order, transition])\n\n /**\n * Cancel goes through `/api/commerce/cancel-order` (AGL-1818), not a client\n * write. The status flip and the stock release are one transaction there,\n * and the route re-asks `canTransitionOrder` under the same lock — the\n * `can('cancelled')` gate below only decides whether to RENDER the button,\n * so a dialog held open while the order ships in another tab used to write\n * `cancelled` straight onto a `fulfilled` order. Now that race comes back\n * as a 409 carrying the state that refused it.\n *\n * The messages follow the AGL-1784/1786 contract — say what happened:\n * a 409 is the guard refusing, not the cancel machinery failing; the\n * route's own 500 is a rolled-back transaction (nothing landed, retry is\n * safe and correct); an answer with no JSON word from the handler, or no\n * answer at all, is NOT KNOWN — never \"nothing happened\". A retry is safe\n * in every case because the route cancels once: a second cancel finds\n * `cancelled` and returns success without touching stock.\n */\n const handleCancel = useCallback(async () => {\n if (!order || !orderId) return\n const confirmed = await confirm({\n title: 'Cancel this order?',\n description:\n 'The buyer is NOT refunded automatically — refund first if they paid.',\n confirmationText: 'Cancel order',\n confirmationButtonProps: { color: 'error' },\n })\n .then(() => true)\n .catch(() => false)\n if (!confirmed) return\n setBusy(true)\n try {\n let response: Response\n try {\n response = await authorizedFetch(user, '/api/commerce/cancel-order', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ hostId, orderId }),\n })\n } catch (error) {\n console.error(error)\n enqueueSnackbar(\n 'The request did not complete, so it is NOT known whether the ' +\n 'order was canceled. Reopen the order to check — retrying is ' +\n 'safe, the server cancels once.',\n { variant: 'error', allowDuplicate: true },\n )\n return\n }\n const payload: any = await response.json().catch(() => ({}))\n if (!response.ok) {\n if (response.status === 409) {\n // The transition guard refusing: the order moved on (shipped,\n // refunded) while this dialog was open. The route's message names\n // the state that refused it, and nothing was written.\n enqueueSnackbar(\n payload?.error ?? 'This order can no longer be canceled',\n {\n variant: 'warning',\n allowDuplicate: true,\n },\n )\n } else if (payload?.error && response.status < 500) {\n // A refusal that wrote nothing — session, role, or an order that\n // is not there. The route's own word, verbatim.\n enqueueSnackbar(payload.error, {\n variant: 'error',\n allowDuplicate: true,\n })\n } else if (payload?.error) {\n // The route's 500 is a rolled-back transaction: nothing landed and\n // the order is still open. Only the handler's own JSON word\n // licenses saying so.\n enqueueSnackbar(\n `${payload.error} — nothing changed, the order is still open. Retrying is safe.`,\n { variant: 'error', allowDuplicate: true },\n )\n } else {\n // No JSON word from the handler (a gateway page, a proxy timeout):\n // whether the cancel landed is NOT known.\n enqueueSnackbar(\n `The cancel failed (${response.status}) and it is NOT known ` +\n 'whether it landed. Reopen the order to check — retrying is ' +\n 'safe, the server cancels once.',\n { variant: 'error', allowDuplicate: true },\n )\n }\n return\n }\n const units = Number(payload?.units ?? 0)\n enqueueSnackbar(\n payload?.alreadyCancelled\n ? 'Order was already canceled'\n : units > 0\n ? `Order canceled — ${units} ${units === 1 ? 'unit' : 'units'} returned to stock`\n : 'Order canceled',\n { variant: 'success', persist: false },\n )\n } finally {\n setBusy(false)\n }\n }, [order, orderId, user, hostId, confirm, enqueueSnackbar])\n\n /**\n * Idempotency key for ONE refund attempt (AGL-1696), the same shape the POS\n * register uses for a sale (AGL-1691).\n *\n * Minted lazily so a retry of this attempt — a lost response, a second\n * click, the admin reopening the dialog after a timeout — reuses it and the\n * server replays instead of sending the money again. Retired on a definitive\n * answer, which makes the NEXT refund a new attempt: two partial refunds of\n * the same amount on the same order are two real refunds, and keying on the\n * order (or the amount) would silently swallow the second.\n *\n * NOT retired on a network failure or a 5xx — that is precisely the window\n * the key exists to cover.\n */\n const attemptKey = useRef('')\n useEffect(() => {\n attemptKey.current = ''\n }, [orderId])\n\n /**\n * `lineItemIds` scopes the refund to named lines (AGL-2454).\n *\n * Without it a partial refund is an AMOUNT and nothing else, so the product\n * cannot know which goods came back and revokes nothing — a 99%-refunded\n * order kept its downloads, licence keys, gated pages and verified review.\n * Naming the lines is the only way that question gets an honest answer, and\n * the route derives the amount FROM the lines rather than trusting a figure\n * typed beside them.\n */\n const handleRefund = useCallback(async (lineItemIds?: number[]) => {\n if (!order || !orderId) return\n const scoped = (lineItemIds ?? []).length > 0\n // The SERVER's figure, not a second derivation of it (`orderLineRefundCents`\n // inside the prompt): the list value `unitAmountCents x quantity` is more\n // than the buyer paid on a discounted order.\n const prompt = orderRefundPrompt(order, lineItemIds ?? [])\n const confirmed = await confirm({\n title: prompt.title,\n description: prompt.text,\n confirmationText: 'Refund',\n confirmationButtonProps: { color: 'error' },\n })\n .then(() => true)\n .catch(() => false)\n if (!confirmed) return\n setBusy(true)\n // `randomUUID` needs a secure context, which the console always is, but\n // fall back rather than throw on a refund.\n if (!attemptKey.current) {\n attemptKey.current =\n globalThis.crypto?.randomUUID?.() ??\n `${Date.now()}-${Math.random().toString(36).slice(2)}`\n }\n try {\n const response = await authorizedFetch(user, '/api/commerce/refund', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Idempotency-Key': attemptKey.current,\n },\n body: JSON.stringify({\n hostId,\n orderId,\n ...(scoped ? { lineItemIds } : {}),\n }),\n })\n const payload = await response.json()\n // A definitive answer ends this attempt either way: the next refund is a\n // new one and must get a new key. A 5xx or a thrown fetch keeps the key,\n // so pressing Refund again dedupes rather than sends a second transfer.\n if (response.status < 500) attemptKey.current = ''\n if (!response.ok) {\n // A 409 is a guard REFUSING — the status machine, or the open-dispute\n // block (AGL-1809), whose body explains what to do instead — not the\n // refund machinery failing. The route wrote nothing, so it surfaces\n // verbatim as a warning, same as the cancel path's 409 (AGL-1818).\n enqueueSnackbar(payload?.error ?? 'Refund failed', {\n variant: response.status === 409 ? 'warning' : 'error',\n allowDuplicate: true,\n })\n } else {\n enqueueSnackbar('Refund issued', { variant: 'success', persist: false })\n }\n } finally {\n setBusy(false)\n }\n }, [order, orderId, user, hostId, confirm, enqueueSnackbar])\n\n /**\n * Answer the restock question a reversal flagged (AGL-1806).\n *\n * The answer MOVES NO STOCK, which is AGL-1797's ledger argument and it is\n * binding: the products hub's \"Adjust stock\" is the one stock writer (it\n * writes the counts AND the `InventoryAdjustment` row the hub renders as\n * history), so \"Restocked\" here is clicked AFTER the merchant used it, and\n * \"No restock\" says the goods are not recoverable. Either answer only sets\n * the `resolution` triple `OrderRestockCheck` declares and says so on the\n * timeline.\n *\n * A TRANSACTION rather than the dialog's plain `write`, keyed on the\n * rendered `flaggedAtMs`, because an answer must land ONCE. The flag writer\n * re-asks an ANSWERED question after the next reversal, and the cancel\n * route (AGL-1808) answers an open one itself when it returns the stock —\n * so a stale dialog writing blind would either re-answer a settled question\n * or replace a brand-new one with a resolved copy of the old. The\n * transaction re-reads on the server (the web SDK will not run one from\n * cache — the products hub's `writeGuardedBySeed` refusal of unconfirmed\n * data, by other means) and refuses both cases with the truth: nothing was\n * written.\n */\n const handleRestockAnswer = useCallback(\n async (resolution: 'restocked' | 'dismissed') => {\n const check = order?.restockCheck\n if (!order || !orderId || !check || check.resolution) return\n setBusy(true)\n try {\n const reference = doc(firestore, 'hosts', hostId, 'orders', orderId)\n const verdict = await runTransaction(firestore, async (transaction) => {\n const snapshot = await transaction.get(reference)\n if (!snapshot.exists()) return 'gone'\n const current = CommerceModel.liftLegacyOrder(\n (snapshot.data() ?? {}) as never,\n )\n const answer = CommerceModel.restockAnswer(\n current,\n check.flaggedAtMs,\n resolution,\n String((user as any)?.uid ?? ''),\n )\n if (answer.verdict !== 'recorded') return answer.verdict\n // The SERVER's timeline, not the dialog's — a note landed from\n // another tab must survive the append (`restockAnswer` appends to\n // `current`).\n transaction.update(reference, answer.update)\n return 'recorded'\n })\n if (verdict === 'recorded') {\n enqueueSnackbar(\n resolution === 'restocked'\n ? 'Recorded as restocked'\n : 'Recorded — no restock',\n { variant: 'success', persist: false },\n )\n } else if (verdict === 'answered') {\n // The cancel route, or another admin, got there first.\n enqueueSnackbar(\n 'This restock question was already answered — nothing changed.',\n { variant: 'info', persist: false },\n )\n } else if (verdict === 'changed') {\n // A later reversal re-asked; this dialog shows the OLD question.\n enqueueSnackbar(\n 'The restock question changed while this dialog was open — ' +\n 'nothing was written. Reopen the order to see the current one.',\n { variant: 'warning', allowDuplicate: true },\n )\n } else {\n enqueueSnackbar('This order no longer exists — nothing was written.', {\n variant: 'warning',\n allowDuplicate: true,\n })\n }\n } catch (error) {\n // A transaction is all-or-nothing, and a thrown one did not commit.\n console.error(error)\n enqueueSnackbar(\n 'The answer was not recorded — it needs a live connection and the ' +\n 'editor or admin role. Nothing changed; answering again is safe.',\n { variant: 'error', allowDuplicate: true },\n )\n } finally {\n setBusy(false)\n }\n },\n [order, orderId, firestore, hostId, user, enqueueSnackbar],\n )\n\n const handleNote = useCallback(async () => {\n const update = order ? CommerceModel.orderNoteUpdate(order, note) : null\n if (!update) return\n await write(update)\n setNote('')\n }, [order, note, write])\n\n const handlePackingSlip = useCallback(() => {\n if (!order) return\n const win = window.open('', '_blank', 'width=600,height=800')\n if (!win) return\n // Every value is escaped by the builder (AGL-2283): this is\n // `document.write` into an `about:blank` popup, which inherits the\n // console's origin, and the address is typed by the shopper.\n win.document.write(buildPackingSlipHtml(order, orderId))\n win.document.close()\n // Print from the opener, not from an injected inline script (AGL-523) —\n // the popup inherits this document's CSP, where an un-nonced inline\n // script is blocked under the enforcing policy. Same reasoning as the POS\n // receipt.\n win.focus()\n win.print()\n }, [order, orderId])\n\n if (!order) return null\n const totals = order.totals\n const can = (to: CommerceModel.OrderStatus) => CommerceModel.canTransitionOrder(order.status, to)\n // A lost chargeback leaves `status: 'refunded'` (AGL-1787), so the status\n // chip alone tells the merchant they chose this. The badge is the correction.\n const dispute = CommerceModel.describeOrderDispute(order)\n // An early fraud warning or a Radar review on the payment (AGL-3360).\n const paymentRisk = describePaymentRisk(order.paymentRisk)\n const reversal = CommerceModel.splitOrderReversal(order)\n // The restock question a reversal flagged, while it is still open\n // (AGL-1806). Absent `resolution` IS the open state — the writer only ever\n // re-flags an answered check (AGL-1797).\n const restock =\n order.restockCheck && !order.restockCheck.resolution\n ? order.restockCheck\n : null\n // Whether the reversal NAMED the lines this question is about (AGL-2325).\n // AGL-2454 gave a refund a line selection, and `flagOrderRestock` now scopes\n // the question to it — so the \"we cannot tell which goods came back\" caveat\n // below is true of an amount-only reversal and false of this one. Asked of\n // the order's own withdrawal record rather than of a flag on the check, so a\n // prompt written before line indexes existed reads as the amount-only case\n // it was.\n const fulfilledByLine = CommerceModel.orderLineFulfillmentStates(order).map(\n (state) => state.fulfilledQuantity,\n )\n return (\n <Dialog open onClose={onClose} maxWidth=\"sm\" fullWidth>\n <DialogTitle>\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center' }}>\n <span>{`Order ${CommerceModel.formatOrderNumber(order, orderId)}`}</span>\n <Chip\n label={order.status.replace('_', ' ')}\n size=\"small\"\n color={STATUS_COLOR[order.status] ?? 'default'}\n variant=\"outlined\"\n />\n {dispute ? (\n <Tooltip title={dispute.detail}>\n <Chip\n label={dispute.label}\n size=\"small\"\n color={DISPUTE_COLOR[dispute.tone]}\n variant=\"filled\"\n />\n </Tooltip>\n ) : null}\n {paymentRisk ? (\n <Tooltip title={paymentRisk.detail}>\n <Chip\n label={paymentRisk.label}\n size=\"small\"\n color=\"warning\"\n variant=\"filled\"\n />\n </Tooltip>\n ) : null}\n {order.channel && order.channel !== 'online' ? (\n <Chip label={order.channel} size=\"small\" variant=\"outlined\" />\n ) : null}\n </Stack>\n </DialogTitle>\n <DialogContent sx={{ display: 'flex', flexDirection: 'column', gap: 1.5 }}>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {[order.customerName, order.customerEmail]\n .filter(Boolean)\n .join(' · ') || 'Guest buyer'}\n </Typography>\n {(order.lineItems ?? []).map((line, index) => {\n // WHAT THIS LINE IS STILL ENTITLED TO, per line (AGL-2454). A refund\n // used to be a number on the order and nothing more, so the merchant\n // could not see — and the product could not enforce — which goods had\n // come back.\n const withdrawn = CommerceModel.orderLineRefunded(order, index)\n return (\n <Stack key={index} direction=\"row\" spacing={1} sx={{ alignItems: 'center' }}>\n <Typography\n variant=\"body2\"\n sx={{\n flex: 1,\n ...(withdrawn ? { textDecoration: 'line-through' } : {}),\n }}\n color={withdrawn ? 'text.secondary' : 'text.primary'}\n >\n {`${line.quantity}× ${line.name}` +\n (line.variantLabel ? ` — ${line.variantLabel}` : '')}\n </Typography>\n {fulfilledByLine[index] ? (\n <Chip\n label={`${fulfilledByLine[index]} of ${line.quantity} fulfilled`}\n size=\"small\"\n variant=\"outlined\"\n />\n ) : null}\n {withdrawn ? (\n <Chip label=\"refunded\" size=\"small\" color=\"error\" variant=\"outlined\" />\n ) : can('refunded') &&\n !CommerceModel.orderDisputeBlocksRefund(order) ? (\n <Button\n size=\"small\"\n color=\"error\"\n disabled={busy}\n onClick={() => handleRefund([index])}\n >\n {'Refund line'}\n </Button>\n ) : null}\n <Typography variant=\"body2\">\n {usd(line.unitAmountCents * line.quantity)}\n </Typography>\n </Stack>\n )\n })}\n {CommerceModel.orderRefundState(order) !== 'none' ? (\n // The state, said in words (AGL-2454). \"Partially refunded, no lines\n // withdrawn\" is the honest reading of an amount-only refund, and it\n // is what tells a merchant their buyer still has the downloads.\n <Typography variant=\"caption\" color=\"error\">\n {CommerceModel.orderRefundSummary(order)}\n </Typography>\n ) : null}\n {totals ? (\n <>\n <Divider />\n {(\n [\n ['Items', totals.itemsCents],\n ['Shipping', totals.shippingCents],\n // Optional lines the buyer took at checkout (AGL-3635), by name.\n ...(order.extras ?? []).map((extra) => [extra.label, extra.amountCents]),\n ['Tax', totals.taxCents],\n ['Discount', -totals.discountCents],\n ['Total', totals.totalCents],\n ] as Array<[string, number]>\n ).map(([label, cents]) => (\n <Stack key={label} direction=\"row\">\n <Typography\n variant=\"body2\"\n sx={{ flex: 1 }}\n color={label === 'Total' ? 'text.primary' : 'text.secondary'}\n >\n {label}\n </Typography>\n <Typography\n variant=\"body2\"\n sx={{ fontWeight: label === 'Total' ? 600 : 400 }}\n >\n {`${cents < 0 ? '-' : ''}${usd(Math.abs(cents))}`}\n </Typography>\n </Stack>\n ))}\n {/*\n HOW the tax on this order was computed (AGL-2451). The `Tax` row\n above states an amount and nothing about which machinery produced\n it, and a merchant reading one order could not tell Stripe Tax\n (computed against Aglyn's registrations) from their own configured\n rate. Those are different facts about whose registration the money\n is held under, and the order is where a merchant looks.\n\n Describes the mechanism and makes NO remittance determination —\n the constraint AGL-2440's report ships under. An order written\n before the stamp existed says so, rather than being rendered as\n \"no tax\": absent means NOT RECORDED, and `describeOrderTaxMode`\n is where that distinction is kept.\n */}\n <Typography variant=\"caption\" color=\"text.secondary\">\n {CommerceModel.describeOrderTaxMode(order.taxMode)}\n </Typography>\n {/*\n Both figures live in `refundedCents` (AGL-1787), so a lost\n chargeback used to render as \"Refunded $62.00\" — the merchant's\n own decision, spelled the same as money taken from them. Split by\n door, and show BOTH when a partial refund and a chargeback each\n took a piece.\n */}\n {reversal.refundedCents ? (\n <Typography variant=\"caption\" color=\"error\">\n {`Refunded ${usd(reversal.refundedCents)}`}\n </Typography>\n ) : null}\n {reversal.chargedBackCents ? (\n <Typography variant=\"caption\" color=\"error\">\n {`Charged back ${usd(reversal.chargedBackCents)}`}\n </Typography>\n ) : null}\n </>\n ) : null}\n {restock ? (\n <>\n <Divider />\n <Stack spacing={0.5}>\n <Typography variant=\"subtitle2\">{'Restock check'}</Typography>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {CommerceModel.describeRestockCheck(restock, order)}\n </Typography>\n {restock.lines.map((line, index) => (\n <Typography key={index} variant=\"caption\" color=\"text.secondary\">\n {`${line.quantity}× ${line.name ?? line.productId}` +\n (line.variantLabel ? ` — ${line.variantLabel}` : '')}\n </Typography>\n ))}\n <Typography variant=\"caption\" color=\"text.secondary\">\n {'If goods came back, put them on the shelf with \"Adjust ' +\n 'stock\" in the products hub first — these answers move no ' +\n 'stock, they only clear this question.'}\n </Typography>\n <Stack direction=\"row\" spacing={1}>\n <Button\n size=\"small\"\n variant=\"outlined\"\n disabled={busy}\n onClick={() => handleRestockAnswer('restocked')}\n >\n {'Restocked'}\n </Button>\n <Button\n size=\"small\"\n disabled={busy}\n onClick={() => handleRestockAnswer('dismissed')}\n >\n {'No restock'}\n </Button>\n </Stack>\n </Stack>\n </>\n ) : null}\n {/* A register sale rung offline, and what its sync found (AGL-3625). */}\n <OrderOfflineNotice order={order} />\n {/* Pickup or the store's own delivery, and its next step (AGL-3624). */}\n {orderId ? <OrderLocalFulfillmentPanel hostId={hostId} orderId={orderId} order={order} /> : null}\n <Divider />\n <Typography variant=\"subtitle2\">{'Timeline'}</Typography>\n {(order.timeline ?? [])\n .slice()\n .reverse()\n .map((event, index) => (\n <Typography key={index} variant=\"caption\" color=\"text.secondary\">\n {`${new Date(event.atMs).toLocaleString()} — ${event.event}` +\n (event.detail ? `: ${event.detail}` : '')}\n </Typography>\n ))}\n <Stack direction=\"row\" spacing={1}>\n <TextField\n label=\"Add note\"\n value={note}\n onChange={(event) => setNote(event.target.value)}\n size=\"small\"\n sx={{ flex: 1 }}\n />\n <Button size=\"small\" disabled={!note.trim()} onClick={handleNote}>\n {'Add'}\n </Button>\n </Stack>\n <FulfillmentList\n order={order}\n busy={busy}\n onUpdateTracking={handleUpdateTracking}\n onCancelFulfillment={handleCancelFulfillment}\n />\n {fulfilling ? (\n <FulfillItemsPanel\n order={order}\n busy={busy}\n onSubmit={handleFulfill}\n currency={storeCurrency}\n onCancel={() => setFulfilling(false)}\n renderZone={\n WidgetSlot && zoneOrder\n ? (selection, applyTracking) => (\n <HostedZone\n renderer={WidgetSlot}\n slot={ORDER_FULFILLMENT_ZONE.id}\n hostId={hostId}\n orgId={undefined}\n order={zoneOrder}\n recordFulfillment={recordFulfillment}\n selection={selection}\n applyTracking={applyTracking}\n />\n )\n : undefined\n }\n />\n ) : null}\n {/*\n The order zone (AGL-3611): a widget reads the order and records a\n shipment through `recordFulfillment`, this dialog's own route.\n */}\n {WidgetSlot && zoneOrder ? (\n <HostedZone\n renderer={WidgetSlot}\n slot={ORDER_DETAIL_ZONE.id}\n hostId={hostId}\n orgId={undefined}\n order={zoneOrder}\n recordFulfillment={recordFulfillment}\n />\n ) : null}\n {/* The order's returns and \"Start return\" (AGL-3611). */}\n {orderId ? <OrderReturns hostId={hostId} orderId={orderId} order={order} /> : null}\n {order.paymentLinkUrl && order.status === 'pending' ? (\n <Button\n size=\"small\"\n sx={{ alignSelf: 'flex-start' }}\n onClick={() => {\n navigator.clipboard.writeText(String(order.paymentLinkUrl))\n enqueueSnackbar('Payment link copied', {\n variant: 'success',\n persist: false,\n })\n }}\n >\n {'Copy payment link'}\n </Button>\n ) : null}\n </DialogContent>\n <DialogActions>\n {customerCrmHref ? (\n <Button\n component={AppLink as any}\n {...({ componentVariant: 'naked', nativeButton: false } as any)}\n href={customerCrmHref}\n >\n {'View customer in CRM'}\n </Button>\n ) : null}\n <Button onClick={handlePackingSlip}>{'Packing slip'}</Button>\n {orderId ? <OrderInvoiceButton hostId={hostId} orderId={orderId} order={order} /> : null}\n {orderId ? <OrderReceiptResend hostId={hostId} orderId={orderId} order={order} /> : null}\n {orderId && order.channel === 'pos' ? (\n // The register's 80mm receipt, its gift receipt and a reprint on\n // the register's cloud printer (AGL-3609).\n <PosReceiptActions hostId={hostId} orderId={orderId} order={order} cloudPrint=\"reprint\" />\n ) : null}\n {can('cancelled') ? (\n <Button color=\"error\" disabled={busy} onClick={handleCancel}>\n {'Cancel order'}\n </Button>\n ) : null}\n {can('refunded') ? (\n // Disabled on `orderDisputeBlocksRefund`, NOT the badge's broader\n // `orderHasOpenDispute` (AGL-1820): a formal open dispute means the\n // bank already pulled the funds and the route answers 409\n // (AGL-1809), while an open INQUIRY shows the badge but must keep\n // this button live — a full refund is how an inquiry is resolved.\n CommerceModel.orderDisputeBlocksRefund(order) ? (\n <Tooltip title={REFUND_BLOCKED_BY_DISPUTE}>\n {/* A disabled button fires no pointer events; the wrapper\n carries the hover for the tooltip. */}\n <span>\n <Button color=\"error\" disabled>\n {'Refund'}\n </Button>\n </span>\n </Tooltip>\n ) : (\n <Button\n color=\"error\"\n disabled={busy}\n onClick={() => handleRefund()}\n >\n {'Refund'}\n </Button>\n )\n ) : null}\n {(can('fulfilled') || can('partially_fulfilled')) && !fulfilling ? (\n <Button\n variant=\"contained\"\n color=\"primary\"\n onClick={() => setFulfilling(true)}\n >\n {'Fulfill…'}\n </Button>\n ) : null}\n {can('delivered') ? (\n <Button disabled={busy} onClick={handleDelivered}>\n {'Mark delivered'}\n </Button>\n ) : null}\n <Button onClick={onClose}>{'Close'}</Button>\n </DialogActions>\n </Dialog>\n )\n}\nOrderDetailDialog.displayName = 'OrderDetailDialog'\n\nexport default OrderDetailDialog\n"],"names":["CommerceModel","buildPackingSlipHtml","orderRefundPrompt","REFUND_BLOCKED_BY_DISPUTE","pluginRecordByEmailHref","describePaymentRisk","AppLink","useConfirmationContext","useSnackbar","Button","Chip","Dialog","DialogActions","DialogContent","DialogTitle","Divider","Stack","TextField","Tooltip","Typography","doc","getDoc","runTransaction","updateDoc","useParams","memo","useCallback","useEffect","useMemo","useRef","useState","useFirestore","useUser","OrderLocalFulfillmentPanel","authorizedFetch","useConsoleWidgetSlot","consoleOrderZoneOrder","FulfillItemsPanel","FulfillmentList","toZoneFulfillment","ORDER_DETAIL_ZONE","ORDER_FULFILLMENT_ZONE","OrderInvoiceButton","OrderReceiptResend","OrderReturns","PosReceiptActions","OrderOfflineNotice","STATUS_COLOR","pending","paid","partially_fulfilled","fulfilled","delivered","cancelled","refunded","DISPUTE_COLOR","open","lost","won","settled","usd","cents","toFixed","HostedZone","props","renderer","Renderer","zone","newAttemptKey","globalThis","crypto","randomUUID","Date","now","Math","random","toString","slice","OrderDetailDialog","order","hostId","rawOrder","onClose","firestore","data","user","enqueueSnackbar","confirm","fulfilling","setFulfilling","storeCurrency","setStoreCurrency","undefined","live","Promise","resolve","then","snapshot","currency","String","get","trim","toUpperCase","catch","WidgetSlot","note","setNote","busy","setBusy","liftLegacyOrder","orderId","$id","params","customerCrmHref","orgSlug","host","customerEmail","write","patch","transition","to","extra","copy","headers","response","method","body","JSON","stringify","error","console","subject","variant","allowDuplicate","payload","json","ok","status","action","already","partial","done","persist","fulfillKey","current","fulfill","submission","key","lineItems","carrier","trackingNumber","trackingUrl","labelUrl","shippingCostCents","notify","handleFulfill","Boolean","handleUpdateTracking","fulfillmentId","next","handleCancelFulfillment","confirmed","title","description","confirmationText","confirmationButtonProps","color","recordFulfillment","request","map","entry","idempotencyKey","fulfillment","Error","zoneOrder","handleDelivered","handleCancel","units","Number","alreadyCancelled","attemptKey","handleRefund","lineItemIds","scoped","length","prompt","text","handleRestockAnswer","resolution","check","restockCheck","reference","verdict","transaction","exists","answer","restockAnswer","flaggedAtMs","uid","update","handleNote","orderNoteUpdate","handlePackingSlip","win","window","document","close","focus","print","totals","can","canTransitionOrder","dispute","describeOrderDispute","paymentRisk","reversal","splitOrderReversal","restock","fulfilledByLine","orderLineFulfillmentStates","state","fulfilledQuantity","maxWidth","fullWidth","direction","spacing","sx","alignItems","span","formatOrderNumber","label","replace","size","detail","tone","channel","display","flexDirection","gap","customerName","filter","join","line","index","withdrawn","orderLineRefunded","flex","textDecoration","quantity","name","variantLabel","orderDisputeBlocksRefund","disabled","onClick","unitAmountCents","orderRefundState","orderRefundSummary","itemsCents","shippingCents","extras","amountCents","taxCents","discountCents","totalCents","fontWeight","abs","describeOrderTaxMode","taxMode","refundedCents","chargedBackCents","describeRestockCheck","lines","productId","timeline","reverse","event","atMs","toLocaleString","value","onChange","target","onUpdateTracking","onCancelFulfillment","onSubmit","onCancel","renderZone","selection","applyTracking","slot","id","orgId","paymentLinkUrl","alignSelf","navigator","clipboard","writeText","component","componentVariant","nativeButton","href","cloudPrint","displayName"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../libs/plugins/commerce/src/lib/components/console/order-detail-dialog.component.tsx"],"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'use client'\n\nimport * as CommerceModel from '../../model'\nimport { buildPackingSlipHtml } from '../../utils/order-packing-slip'\nimport { orderRefundPrompt, REFUND_BLOCKED_BY_DISPUTE } from '../../model/order-dialog'\n// The CRM's address from the SHARED builder, not the plugin (AGL-2622): the\n// CRM already reaches marketing, and marketing reaches commerce, so an\n// import of the CRM from here would close a cycle between the three\n// plugins. The shared builder is pinned against the CRM's own routes by a\n// spec, so the address is the same one the hub resolves.\nimport { pluginRecordByEmailHref } from '@aglyn/aglyn/plugin-manager/plugin-record-routes'\nimport { describePaymentRisk } from '@aglyn/aglyn/app-utils/payment-risk'\nimport { AppLink, useConfirmationContext } from '@aglyn/shared-ui-jsx'\nimport { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport {\n Button,\n Chip,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n Divider,\n Stack,\n TextField,\n Tooltip,\n Typography,\n} from '@mui/material'\nimport { doc, getDoc, runTransaction, updateDoc } from 'firebase/firestore'\nimport { useParams } from 'next/navigation'\nimport { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { useFirestore, useUser } from '@aglyn/tenant-feature-instance'\nimport OrderLocalFulfillmentPanel from './order-local-fulfillment-panel.component'\nimport { authorizedFetch } from '@aglyn/shared-util-http/authorized-token'\nimport {\n type ConsoleWidgetSlotRenderer,\n useConsoleWidgetSlot,\n} from '@aglyn/aglyn/app-utils/console-widget-slot-context'\nimport {\n consoleOrderZoneOrder,\n FulfillItemsPanel,\n FulfillmentList,\n type FulfillItemsSubmission,\n toZoneFulfillment,\n} from './order-fulfillment-panel.component'\nimport {\n type ConsoleFulfillmentRequest,\n type ConsoleOrderZoneFulfillment,\n ORDER_DETAIL_ZONE,\n ORDER_FULFILLMENT_ZONE,\n} from './order-zones'\nimport { OrderInvoiceButton } from './order-invoice.component'\nimport { OrderReceiptResend } from './order-receipt-resend.component'\nimport { OrderReturns } from './order-returns.component'\nimport { PosReceiptActions } from './pos-ops/pos-receipt-actions.component'\nimport { OrderOfflineNotice } from './order-offline-notice.component'\n\nexport interface OrderDetailDialogProps {\n hostId: string\n order: (CommerceModel.HostOrder & { $id: string }) | null\n onClose: () => void\n}\n\nconst STATUS_COLOR: Record<\n string,\n 'default' | 'success' | 'warning' | 'error' | 'info'\n> = {\n pending: 'warning',\n paid: 'info',\n partially_fulfilled: 'info',\n fulfilled: 'success',\n delivered: 'success',\n cancelled: 'default',\n refunded: 'error',\n}\n\n/**\n * The dispute chip's colour (AGL-1796).\n *\n * `open` is WARNING rather than error because it is the case that still has a\n * deadline on it — the merchant can still act, and a red chip on a case they\n * might win says the money is gone when it is not. `lost` is the one that took\n * the money, and shares `refunded`'s red for that reason.\n */\nexport const DISPUTE_COLOR: Record<\n CommerceModel.OrderDisputeTone,\n 'default' | 'success' | 'warning' | 'error'\n> = {\n open: 'warning',\n lost: 'error',\n won: 'success',\n settled: 'default',\n}\n\nconst usd = (cents: number | undefined) =>\n `$${((cents ?? 0) / 100).toFixed(2)}`\n\n/**\n * A zone hosted in the dialog, drawn again only when what it is handed\n * changes — the product editor's reasoning (AGL-3423): the shell's renderer\n * is not memoized, and the dialog redraws on every keystroke in its fields.\n */\nconst HostedZone = memo(function HostedZone(\n props: { renderer: ConsoleWidgetSlotRenderer; slot: string } & Record<string, unknown>,\n) {\n const { renderer: Renderer, ...zone } = props\n return <Renderer {...zone} />\n})\n\n/** A fresh key for one attempt at a write the route dedupes on. */\nconst newAttemptKey = () =>\n globalThis.crypto?.randomUUID?.() ??\n `${Date.now()}-${Math.random().toString(36).slice(2)}`\n\n/**\n * Order detail (AGL-287): timeline, line items, totals, and the actions\n * the status machine allows — fulfill with tracking, refund, cancel, mark\n * delivered (each a server route that re-asks the transition under the\n * write), notes, printable packing slip.\n */\nexport function OrderDetailDialog(props: OrderDetailDialogProps) {\n const { hostId, order: rawOrder, onClose } = props\n const firestore = useFirestore()\n const { data: user } = useUser()\n const { enqueueSnackbar } = useSnackbar()\n const { confirm } = useConfirmationContext()\n const [fulfilling, setFulfilling] = useState(false)\n // The store's currency, which a hand-entered shipping cost is typed in\n // (AGL-3705). Read when the Fulfill items panel opens, not before.\n const [storeCurrency, setStoreCurrency] = useState<string | undefined>(undefined)\n useEffect(() => {\n if (!fulfilling || storeCurrency) return\n let live = true\n // A failed read leaves the field in US dollars, the store default.\n Promise.resolve()\n .then(() => getDoc(doc(firestore, 'hosts', hostId, 'settings', 'store')))\n .then((snapshot) => {\n const currency = String(snapshot.get('currency') ?? '').trim()\n if (live && currency) setStoreCurrency(currency.toUpperCase())\n })\n .catch(() => undefined)\n return () => {\n live = false\n }\n }, [fulfilling, storeCurrency, firestore, hostId])\n const WidgetSlot = useConsoleWidgetSlot()\n const [note, setNote] = useState('')\n const [busy, setBusy] = useState(false)\n\n const order = rawOrder ? CommerceModel.liftLegacyOrder(rawOrder) : null\n const orderId = rawOrder?.$id\n /*\n * Where the buyer's CONTACT is (AGL-2622). A checkout that carried an\n * address updated a person in the CRM — a customer, with this order on\n * their timeline — and the dialog links there by the address, because\n * the contact's id is minted at capture and nothing on the order holds\n * it. The Contacts list is the lookup and opens the record on one match,\n * at the address the plugin that keeps contacts publishes; where none\n * does, there is no link. A guest checkout with no address updated\n * nobody, so there is no link either. Built from the route params already\n * in the URL — no document is read to draw a link — and absent until they\n * settle, so the dialog never offers a link to a half-built address.\n */\n const params = useParams<{ orgSlug?: string; host?: string }>()\n const customerCrmHref =\n params?.orgSlug && params?.host && order?.customerEmail\n ? pluginRecordByEmailHref(\n 'contact',\n { orgSlug: String(params.orgSlug), host: String(params.host) },\n String(order.customerEmail),\n )\n : null\n\n /**\n * The one client write left in this dialog, and it is timeline-only ON\n * PURPOSE: notes carry no status, so `ORDER_TRANSITIONS` has nothing to say\n * about them and they stay out of the server routes' way. Every status\n * write goes through a route that re-asks the transition under the write —\n * cancel (AGL-1818), fulfil and mark-delivered (AGL-1819), refund\n * (AGL-1696). The moment a status rides along with a note, it must move\n * too; `order-fulfill-wiring.spec.tsx` pins the patch to `timeline` alone.\n */\n const write = useCallback(\n async (patch: Record<string, unknown>) => {\n if (!orderId) return\n await updateDoc(doc(firestore, 'hosts', hostId, 'orders', orderId), patch)\n },\n [firestore, hostId, orderId],\n )\n\n /**\n * Fulfil and mark-delivered go through `/api/commerce/fulfill-order`\n * (AGL-1819), not a client write — the same stale-dialog hole the cancel\n * swap (AGL-1818) closed: `can(…)` below only decides whether to RENDER\n * the buttons, so a dialog held open while the order was refunded in\n * another tab used to write `fulfilled` straight onto it. The route\n * re-asks `canTransitionOrder` inside the transaction that writes the\n * status, and that race now comes back as a 409 carrying the state that\n * refused.\n *\n * The messages follow the AGL-1784/1786 contract — say what happened: a\n * 409 is the guard refusing, not the machinery failing; the route's own\n * 500 is a rolled-back transaction (nothing landed, retry is safe and\n * correct); an answer with no JSON word from the handler, or no answer at\n * all, is NOT KNOWN — never \"nothing happened\". A retry is safe in every\n * case because the route writes once: a repeat finds the order already in\n * the target status and returns `already` without appending a second copy\n * of the same fulfillment.\n */\n const transition = useCallback(\n async (\n to: 'fulfilled' | 'delivered' | null,\n extra: Record<string, unknown>,\n copy: {\n done: string\n already: string\n subject: string\n action: string\n partial?: string\n },\n headers: Record<string, string> = {},\n ): Promise<false | Record<string, any>> => {\n if (!orderId) return false\n setBusy(true)\n try {\n let response: Response\n try {\n response = await authorizedFetch(\n user,\n '/api/commerce/fulfill-order',\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...headers },\n body: JSON.stringify({ hostId, orderId, ...(to ? { to } : {}), ...extra }),\n },\n )\n } catch (error) {\n console.error(error)\n enqueueSnackbar(\n `The request did not complete, so it is NOT known whether ${copy.subject}. ` +\n 'Reopen the order to check — retrying is safe, the server ' +\n 'writes it once.',\n { variant: 'error', allowDuplicate: true },\n )\n return false\n }\n const payload: any = await response.json().catch(() => ({}))\n if (!response.ok) {\n if (response.status === 409) {\n // The transition guard refusing: the order moved on (refunded,\n // cancelled) while this dialog was open. The route's message\n // names the state that refused it, and nothing was written.\n enqueueSnackbar(\n payload?.error ?? `This order can no longer be ${to ?? 'changed'}`,\n {\n variant: 'warning',\n allowDuplicate: true,\n },\n )\n } else if (payload?.error && response.status < 500) {\n // A refusal that wrote nothing — session, role, or an order that\n // is not there. The route's own word, verbatim.\n enqueueSnackbar(payload.error, {\n variant: 'error',\n allowDuplicate: true,\n })\n } else if (payload?.error) {\n // The route's 500 is a rolled-back transaction: nothing landed.\n // Only the handler's own JSON word licenses saying so.\n enqueueSnackbar(\n `${payload.error} — nothing changed, the order is as it was. Retrying is safe.`,\n { variant: 'error', allowDuplicate: true },\n )\n } else {\n // No JSON word from the handler (a gateway page, a proxy\n // timeout): whether the write landed is NOT known.\n enqueueSnackbar(\n `The ${copy.action} failed (${response.status}) and it is NOT ` +\n 'known whether it landed. Reopen the order to check — ' +\n 'retrying is safe, the server writes it once.',\n { variant: 'error', allowDuplicate: true },\n )\n }\n return false\n }\n enqueueSnackbar(\n payload?.already\n ? copy.already\n : payload?.status === 'partially_fulfilled' && copy.partial\n ? copy.partial\n : copy.done,\n {\n variant: 'success',\n persist: false,\n },\n )\n return payload ?? {}\n } finally {\n setBusy(false)\n }\n },\n [orderId, user, hostId, enqueueSnackbar],\n )\n\n /**\n * One key per shipment attempt (AGL-3611), the refund's shape: a partial\n * shipment leaves the order open to more, so \"already in the target\n * status\" cannot catch its retry — the key does. Retired on a definitive\n * answer; kept across a network failure or a 5xx, the window it covers.\n */\n const fulfillKey = useRef('')\n useEffect(() => {\n fulfillKey.current = ''\n }, [orderId])\n\n const fulfill = useCallback(\n async (submission: FulfillItemsSubmission, key: string) => {\n const payload = await transition(\n 'fulfilled',\n {\n ...(submission.lineItems ? { lineItems: submission.lineItems } : {}),\n ...(submission.carrier ? { carrier: submission.carrier } : {}),\n ...(submission.trackingNumber ? { trackingNumber: submission.trackingNumber } : {}),\n ...(submission.trackingUrl ? { trackingUrl: submission.trackingUrl } : {}),\n ...(submission.labelUrl ? { labelUrl: submission.labelUrl } : {}),\n ...(typeof submission.shippingCostCents === 'number'\n ? { shippingCostCents: submission.shippingCostCents }\n : {}),\n ...(submission.notify ? {} : { notify: false }),\n },\n {\n done: 'Order fulfilled',\n partial: 'Items fulfilled — the rest are still to ship',\n already: 'Order was already fulfilled',\n subject: 'the order was fulfilled',\n action: 'fulfillment',\n },\n { 'Idempotency-Key': key },\n )\n return payload\n },\n [transition],\n )\n\n const handleFulfill = useCallback(\n async (submission: FulfillItemsSubmission) => {\n if (!order) return false\n if (!fulfillKey.current) fulfillKey.current = newAttemptKey()\n const payload = await fulfill(submission, fulfillKey.current)\n // The refused or unknown case keeps the form open — there is nothing to\n // celebrate, and the tracking is not yet recorded anywhere.\n if (payload) {\n fulfillKey.current = ''\n setFulfilling(false)\n }\n return Boolean(payload)\n },\n [order, fulfill],\n )\n\n const handleUpdateTracking = useCallback(\n async (\n fulfillmentId: string,\n next: { carrier: string; trackingNumber: string; trackingUrl?: string },\n ) =>\n Boolean(\n await transition(\n null,\n { action: 'update-tracking', fulfillmentId, ...next },\n {\n done: 'Tracking updated',\n already: 'Tracking was already up to date',\n subject: 'the tracking was updated',\n action: 'tracking update',\n },\n ),\n ),\n [transition],\n )\n\n const handleCancelFulfillment = useCallback(\n async (fulfillmentId: string) => {\n const confirmed = await confirm({\n title: 'Cancel this shipment?',\n description:\n 'Its items go back to unfulfilled and can be shipped again. The buyer is not told.',\n confirmationText: 'Cancel shipment',\n confirmationButtonProps: { color: 'error' },\n })\n .then(() => true)\n .catch(() => false)\n if (!confirmed) return\n await transition(\n null,\n { action: 'cancel-fulfillment', fulfillmentId },\n {\n done: 'Shipment canceled',\n already: 'Shipment was already canceled',\n subject: 'the shipment was canceled',\n action: 'shipment cancel',\n },\n )\n },\n [confirm, transition],\n )\n\n /**\n * A widget's shipment (the zones' `recordFulfillment`): the same route,\n * keyed by the widget's own attempt key, and a throw with the route's words\n * when it refuses, so the widget can tell the merchant why.\n */\n const recordFulfillment = useCallback(\n async (request: ConsoleFulfillmentRequest): Promise<ConsoleOrderZoneFulfillment> => {\n const payload = await fulfill(\n {\n ...(request.lineItems ? { lineItems: request.lineItems.map((entry) => ({ ...entry })) } : {}),\n carrier: String(request.carrier ?? ''),\n trackingNumber: String(request.trackingNumber ?? ''),\n ...(request.trackingUrl ? { trackingUrl: request.trackingUrl } : {}),\n ...(request.labelUrl ? { labelUrl: request.labelUrl } : {}),\n notify: request.notify !== false,\n },\n String(request.idempotencyKey || newAttemptKey()),\n )\n if (!payload || !payload.fulfillment || !order) {\n throw new Error('The shipment was not recorded. Check the order and try again.')\n }\n setFulfilling(false)\n return toZoneFulfillment(order, payload.fulfillment)\n },\n [fulfill, order],\n )\n\n const zoneOrder = useMemo(\n () => (order && orderId ? consoleOrderZoneOrder(order, orderId) : null),\n // `rawOrder` is the snapshot; `order` is derived from it on each render.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [rawOrder, orderId],\n )\n\n const handleDelivered = useCallback(async () => {\n if (!order) return\n await transition(\n 'delivered',\n {},\n {\n done: 'Order marked delivered',\n already: 'Order was already marked delivered',\n subject: 'the order was marked delivered',\n action: 'delivery update',\n },\n )\n }, [order, transition])\n\n /**\n * Cancel goes through `/api/commerce/cancel-order` (AGL-1818), not a client\n * write. The status flip and the stock release are one transaction there,\n * and the route re-asks `canTransitionOrder` under the same lock — the\n * `can('cancelled')` gate below only decides whether to RENDER the button,\n * so a dialog held open while the order ships in another tab used to write\n * `cancelled` straight onto a `fulfilled` order. Now that race comes back\n * as a 409 carrying the state that refused it.\n *\n * The messages follow the AGL-1784/1786 contract — say what happened:\n * a 409 is the guard refusing, not the cancel machinery failing; the\n * route's own 500 is a rolled-back transaction (nothing landed, retry is\n * safe and correct); an answer with no JSON word from the handler, or no\n * answer at all, is NOT KNOWN — never \"nothing happened\". A retry is safe\n * in every case because the route cancels once: a second cancel finds\n * `cancelled` and returns success without touching stock.\n */\n const handleCancel = useCallback(async () => {\n if (!order || !orderId) return\n const confirmed = await confirm({\n title: 'Cancel this order?',\n description:\n 'The buyer is NOT refunded automatically — refund first if they paid.',\n confirmationText: 'Cancel order',\n confirmationButtonProps: { color: 'error' },\n })\n .then(() => true)\n .catch(() => false)\n if (!confirmed) return\n setBusy(true)\n try {\n let response: Response\n try {\n response = await authorizedFetch(user, '/api/commerce/cancel-order', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ hostId, orderId }),\n })\n } catch (error) {\n console.error(error)\n enqueueSnackbar(\n 'The request did not complete, so it is NOT known whether the ' +\n 'order was canceled. Reopen the order to check — retrying is ' +\n 'safe, the server cancels once.',\n { variant: 'error', allowDuplicate: true },\n )\n return\n }\n const payload: any = await response.json().catch(() => ({}))\n if (!response.ok) {\n if (response.status === 409) {\n // The transition guard refusing: the order moved on (shipped,\n // refunded) while this dialog was open. The route's message names\n // the state that refused it, and nothing was written.\n enqueueSnackbar(\n payload?.error ?? 'This order can no longer be canceled',\n {\n variant: 'warning',\n allowDuplicate: true,\n },\n )\n } else if (payload?.error && response.status < 500) {\n // A refusal that wrote nothing — session, role, or an order that\n // is not there. The route's own word, verbatim.\n enqueueSnackbar(payload.error, {\n variant: 'error',\n allowDuplicate: true,\n })\n } else if (payload?.error) {\n // The route's 500 is a rolled-back transaction: nothing landed and\n // the order is still open. Only the handler's own JSON word\n // licenses saying so.\n enqueueSnackbar(\n `${payload.error} — nothing changed, the order is still open. Retrying is safe.`,\n { variant: 'error', allowDuplicate: true },\n )\n } else {\n // No JSON word from the handler (a gateway page, a proxy timeout):\n // whether the cancel landed is NOT known.\n enqueueSnackbar(\n `The cancel failed (${response.status}) and it is NOT known ` +\n 'whether it landed. Reopen the order to check — retrying is ' +\n 'safe, the server cancels once.',\n { variant: 'error', allowDuplicate: true },\n )\n }\n return\n }\n const units = Number(payload?.units ?? 0)\n enqueueSnackbar(\n payload?.alreadyCancelled\n ? 'Order was already canceled'\n : units > 0\n ? `Order canceled — ${units} ${units === 1 ? 'unit' : 'units'} returned to stock`\n : 'Order canceled',\n { variant: 'success', persist: false },\n )\n } finally {\n setBusy(false)\n }\n }, [order, orderId, user, hostId, confirm, enqueueSnackbar])\n\n /**\n * Idempotency key for ONE refund attempt (AGL-1696), the same shape the POS\n * register uses for a sale (AGL-1691).\n *\n * Minted lazily so a retry of this attempt — a lost response, a second\n * click, the admin reopening the dialog after a timeout — reuses it and the\n * server replays instead of sending the money again. Retired on a definitive\n * answer, which makes the NEXT refund a new attempt: two partial refunds of\n * the same amount on the same order are two real refunds, and keying on the\n * order (or the amount) would silently swallow the second.\n *\n * NOT retired on a network failure or a 5xx — that is precisely the window\n * the key exists to cover.\n */\n const attemptKey = useRef('')\n useEffect(() => {\n attemptKey.current = ''\n }, [orderId])\n\n /**\n * `lineItemIds` scopes the refund to named lines (AGL-2454).\n *\n * Without it a partial refund is an AMOUNT and nothing else, so the product\n * cannot know which goods came back and revokes nothing — a 99%-refunded\n * order kept its downloads, licence keys, gated pages and verified review.\n * Naming the lines is the only way that question gets an honest answer, and\n * the route derives the amount FROM the lines rather than trusting a figure\n * typed beside them.\n */\n const handleRefund = useCallback(async (lineItemIds?: number[]) => {\n if (!order || !orderId) return\n const scoped = (lineItemIds ?? []).length > 0\n // The SERVER's figure, not a second derivation of it (`orderLineRefundCents`\n // inside the prompt): the list value `unitAmountCents x quantity` is more\n // than the buyer paid on a discounted order.\n const prompt = orderRefundPrompt(order, lineItemIds ?? [])\n const confirmed = await confirm({\n title: prompt.title,\n description: prompt.text,\n confirmationText: 'Refund',\n confirmationButtonProps: { color: 'error' },\n })\n .then(() => true)\n .catch(() => false)\n if (!confirmed) return\n setBusy(true)\n // `randomUUID` needs a secure context, which the console always is, but\n // fall back rather than throw on a refund.\n if (!attemptKey.current) {\n attemptKey.current =\n globalThis.crypto?.randomUUID?.() ??\n `${Date.now()}-${Math.random().toString(36).slice(2)}`\n }\n try {\n const response = await authorizedFetch(user, '/api/commerce/refund', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Idempotency-Key': attemptKey.current,\n },\n body: JSON.stringify({\n hostId,\n orderId,\n ...(scoped ? { lineItemIds } : {}),\n }),\n })\n const payload = await response.json()\n // A definitive answer ends this attempt either way: the next refund is a\n // new one and must get a new key. A 5xx or a thrown fetch keeps the key,\n // so pressing Refund again dedupes rather than sends a second transfer.\n if (response.status < 500) attemptKey.current = ''\n if (!response.ok) {\n // A 409 is a guard REFUSING — the status machine, or the open-dispute\n // block (AGL-1809), whose body explains what to do instead — not the\n // refund machinery failing. The route wrote nothing, so it surfaces\n // verbatim as a warning, same as the cancel path's 409 (AGL-1818).\n enqueueSnackbar(payload?.error ?? 'Refund failed', {\n variant: response.status === 409 ? 'warning' : 'error',\n allowDuplicate: true,\n })\n } else {\n enqueueSnackbar('Refund issued', { variant: 'success', persist: false })\n }\n } finally {\n setBusy(false)\n }\n }, [order, orderId, user, hostId, confirm, enqueueSnackbar])\n\n /**\n * Answer the restock question a reversal flagged (AGL-1806).\n *\n * The answer MOVES NO STOCK, which is AGL-1797's ledger argument and it is\n * binding: the products hub's \"Adjust stock\" is the one stock writer (it\n * writes the counts AND the `InventoryAdjustment` row the hub renders as\n * history), so \"Restocked\" here is clicked AFTER the merchant used it, and\n * \"No restock\" says the goods are not recoverable. Either answer only sets\n * the `resolution` triple `OrderRestockCheck` declares and says so on the\n * timeline.\n *\n * A TRANSACTION rather than the dialog's plain `write`, keyed on the\n * rendered `flaggedAtMs`, because an answer must land ONCE. The flag writer\n * re-asks an ANSWERED question after the next reversal, and the cancel\n * route (AGL-1808) answers an open one itself when it returns the stock —\n * so a stale dialog writing blind would either re-answer a settled question\n * or replace a brand-new one with a resolved copy of the old. The\n * transaction re-reads on the server (the web SDK will not run one from\n * cache — the products hub's `writeGuardedBySeed` refusal of unconfirmed\n * data, by other means) and refuses both cases with the truth: nothing was\n * written.\n */\n const handleRestockAnswer = useCallback(\n async (resolution: 'restocked' | 'dismissed') => {\n const check = order?.restockCheck\n if (!order || !orderId || !check || check.resolution) return\n setBusy(true)\n try {\n const reference = doc(firestore, 'hosts', hostId, 'orders', orderId)\n const verdict = await runTransaction(firestore, async (transaction) => {\n const snapshot = await transaction.get(reference)\n if (!snapshot.exists()) return 'gone'\n const current = CommerceModel.liftLegacyOrder(\n (snapshot.data() ?? {}) as never,\n )\n const answer = CommerceModel.restockAnswer(\n current,\n check.flaggedAtMs,\n resolution,\n String((user as any)?.uid ?? ''),\n )\n if (answer.verdict !== 'recorded') return answer.verdict\n // The SERVER's timeline, not the dialog's — a note landed from\n // another tab must survive the append (`restockAnswer` appends to\n // `current`).\n transaction.update(reference, answer.update)\n return 'recorded'\n })\n if (verdict === 'recorded') {\n enqueueSnackbar(\n resolution === 'restocked'\n ? 'Recorded as restocked'\n : 'Recorded — no restock',\n { variant: 'success', persist: false },\n )\n } else if (verdict === 'answered') {\n // The cancel route, or another admin, got there first.\n enqueueSnackbar(\n 'This restock question was already answered — nothing changed.',\n { variant: 'info', persist: false },\n )\n } else if (verdict === 'changed') {\n // A later reversal re-asked; this dialog shows the OLD question.\n enqueueSnackbar(\n 'The restock question changed while this dialog was open — ' +\n 'nothing was written. Reopen the order to see the current one.',\n { variant: 'warning', allowDuplicate: true },\n )\n } else {\n enqueueSnackbar('This order no longer exists — nothing was written.', {\n variant: 'warning',\n allowDuplicate: true,\n })\n }\n } catch (error) {\n // A transaction is all-or-nothing, and a thrown one did not commit.\n console.error(error)\n enqueueSnackbar(\n 'The answer was not recorded — it needs a live connection and the ' +\n 'editor or admin role. Nothing changed; answering again is safe.',\n { variant: 'error', allowDuplicate: true },\n )\n } finally {\n setBusy(false)\n }\n },\n [order, orderId, firestore, hostId, user, enqueueSnackbar],\n )\n\n const handleNote = useCallback(async () => {\n const update = order ? CommerceModel.orderNoteUpdate(order, note) : null\n if (!update) return\n await write(update)\n setNote('')\n }, [order, note, write])\n\n const handlePackingSlip = useCallback(() => {\n if (!order) return\n const win = window.open('', '_blank', 'width=600,height=800')\n if (!win) return\n // Every value is escaped by the builder (AGL-2283): this is\n // `document.write` into an `about:blank` popup, which inherits the\n // console's origin, and the address is typed by the shopper.\n win.document.write(buildPackingSlipHtml(order, orderId))\n win.document.close()\n // Print from the opener, not from an injected inline script (AGL-523) —\n // the popup inherits this document's CSP, where an un-nonced inline\n // script is blocked under the enforcing policy. Same reasoning as the POS\n // receipt.\n win.focus()\n win.print()\n }, [order, orderId])\n\n if (!order) return null\n const totals = order.totals\n const can = (to: CommerceModel.OrderStatus) => CommerceModel.canTransitionOrder(order.status, to)\n // A lost chargeback leaves `status: 'refunded'` (AGL-1787), so the status\n // chip alone tells the merchant they chose this. The badge is the correction.\n const dispute = CommerceModel.describeOrderDispute(order)\n // An early fraud warning or a Radar review on the payment (AGL-3360).\n const paymentRisk = describePaymentRisk(order.paymentRisk)\n const reversal = CommerceModel.splitOrderReversal(order)\n // The restock question a reversal flagged, while it is still open\n // (AGL-1806). Absent `resolution` IS the open state — the writer only ever\n // re-flags an answered check (AGL-1797).\n const restock =\n order.restockCheck && !order.restockCheck.resolution\n ? order.restockCheck\n : null\n // Whether the reversal NAMED the lines this question is about (AGL-2325).\n // AGL-2454 gave a refund a line selection, and `flagOrderRestock` now scopes\n // the question to it — so the \"we cannot tell which goods came back\" caveat\n // below is true of an amount-only reversal and false of this one. Asked of\n // the order's own withdrawal record rather than of a flag on the check, so a\n // prompt written before line indexes existed reads as the amount-only case\n // it was.\n const fulfilledByLine = CommerceModel.orderLineFulfillmentStates(order).map(\n (state) => state.fulfilledQuantity,\n )\n return (\n <Dialog open onClose={onClose} maxWidth=\"sm\" fullWidth>\n <DialogTitle>\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center' }}>\n <span>{`Order ${CommerceModel.formatOrderNumber(order, orderId)}`}</span>\n <Chip\n label={order.status.replace('_', ' ')}\n size=\"small\"\n color={STATUS_COLOR[order.status] ?? 'default'}\n variant=\"outlined\"\n />\n {dispute ? (\n <Tooltip title={dispute.detail}>\n <Chip\n label={dispute.label}\n size=\"small\"\n color={DISPUTE_COLOR[dispute.tone]}\n variant=\"filled\"\n />\n </Tooltip>\n ) : null}\n {paymentRisk ? (\n <Tooltip title={paymentRisk.detail}>\n <Chip\n label={paymentRisk.label}\n size=\"small\"\n color=\"warning\"\n variant=\"filled\"\n />\n </Tooltip>\n ) : null}\n {order.channel && order.channel !== 'online' ? (\n <Chip label={order.channel} size=\"small\" variant=\"outlined\" />\n ) : null}\n </Stack>\n </DialogTitle>\n <DialogContent sx={{ display: 'flex', flexDirection: 'column', gap: 1.5 }}>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {[order.customerName, order.customerEmail]\n .filter(Boolean)\n .join(' · ') || 'Guest buyer'}\n </Typography>\n {(order.lineItems ?? []).map((line, index) => {\n // WHAT THIS LINE IS STILL ENTITLED TO, per line (AGL-2454). A refund\n // used to be a number on the order and nothing more, so the merchant\n // could not see — and the product could not enforce — which goods had\n // come back.\n const withdrawn = CommerceModel.orderLineRefunded(order, index)\n return (\n <Stack key={index} direction=\"row\" spacing={1} sx={{ alignItems: 'center' }}>\n <Typography\n variant=\"body2\"\n sx={{\n flex: 1,\n ...(withdrawn ? { textDecoration: 'line-through' } : {}),\n }}\n color={withdrawn ? 'text.secondary' : 'text.primary'}\n >\n {`${line.quantity}× ${line.name}` +\n (line.variantLabel ? ` — ${line.variantLabel}` : '') +\n // The day the buyer chose to use a pass (AGL-4043).\n (line.useDayKey ? ` · for ${CommerceModel.checkInDayLabel(line.useDayKey)}` : '')}\n </Typography>\n {fulfilledByLine[index] ? (\n <Chip\n label={`${fulfilledByLine[index]} of ${line.quantity} fulfilled`}\n size=\"small\"\n variant=\"outlined\"\n />\n ) : null}\n {withdrawn ? (\n <Chip label=\"refunded\" size=\"small\" color=\"error\" variant=\"outlined\" />\n ) : can('refunded') &&\n !CommerceModel.orderDisputeBlocksRefund(order) ? (\n <Button\n size=\"small\"\n color=\"error\"\n disabled={busy}\n onClick={() => handleRefund([index])}\n >\n {'Refund line'}\n </Button>\n ) : null}\n <Typography variant=\"body2\">\n {usd(line.unitAmountCents * line.quantity)}\n </Typography>\n </Stack>\n )\n })}\n {CommerceModel.orderRefundState(order) !== 'none' ? (\n // The state, said in words (AGL-2454). \"Partially refunded, no lines\n // withdrawn\" is the honest reading of an amount-only refund, and it\n // is what tells a merchant their buyer still has the downloads.\n <Typography variant=\"caption\" color=\"error\">\n {CommerceModel.orderRefundSummary(order)}\n </Typography>\n ) : null}\n {totals ? (\n <>\n <Divider />\n {(\n [\n ['Items', totals.itemsCents],\n ['Shipping', totals.shippingCents],\n // Optional lines the buyer took at checkout (AGL-3635), by name.\n ...(order.extras ?? []).map((extra) => [extra.label, extra.amountCents]),\n ['Tax', totals.taxCents],\n ['Discount', -totals.discountCents],\n ['Total', totals.totalCents],\n ] as Array<[string, number]>\n ).map(([label, cents]) => (\n <Stack key={label} direction=\"row\">\n <Typography\n variant=\"body2\"\n sx={{ flex: 1 }}\n color={label === 'Total' ? 'text.primary' : 'text.secondary'}\n >\n {label}\n </Typography>\n <Typography\n variant=\"body2\"\n sx={{ fontWeight: label === 'Total' ? 600 : 400 }}\n >\n {`${cents < 0 ? '-' : ''}${usd(Math.abs(cents))}`}\n </Typography>\n </Stack>\n ))}\n {/*\n HOW the tax on this order was computed (AGL-2451). The `Tax` row\n above states an amount and nothing about which machinery produced\n it, and a merchant reading one order could not tell Stripe Tax\n (computed against Aglyn's registrations) from their own configured\n rate. Those are different facts about whose registration the money\n is held under, and the order is where a merchant looks.\n\n Describes the mechanism and makes NO remittance determination —\n the constraint AGL-2440's report ships under. An order written\n before the stamp existed says so, rather than being rendered as\n \"no tax\": absent means NOT RECORDED, and `describeOrderTaxMode`\n is where that distinction is kept.\n */}\n <Typography variant=\"caption\" color=\"text.secondary\">\n {CommerceModel.describeOrderTaxMode(order.taxMode)}\n </Typography>\n {/*\n Both figures live in `refundedCents` (AGL-1787), so a lost\n chargeback used to render as \"Refunded $62.00\" — the merchant's\n own decision, spelled the same as money taken from them. Split by\n door, and show BOTH when a partial refund and a chargeback each\n took a piece.\n */}\n {reversal.refundedCents ? (\n <Typography variant=\"caption\" color=\"error\">\n {`Refunded ${usd(reversal.refundedCents)}`}\n </Typography>\n ) : null}\n {reversal.chargedBackCents ? (\n <Typography variant=\"caption\" color=\"error\">\n {`Charged back ${usd(reversal.chargedBackCents)}`}\n </Typography>\n ) : null}\n </>\n ) : null}\n {restock ? (\n <>\n <Divider />\n <Stack spacing={0.5}>\n <Typography variant=\"subtitle2\">{'Restock check'}</Typography>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {CommerceModel.describeRestockCheck(restock, order)}\n </Typography>\n {restock.lines.map((line, index) => (\n <Typography key={index} variant=\"caption\" color=\"text.secondary\">\n {`${line.quantity}× ${line.name ?? line.productId}` +\n (line.variantLabel ? ` — ${line.variantLabel}` : '')}\n </Typography>\n ))}\n <Typography variant=\"caption\" color=\"text.secondary\">\n {'If goods came back, put them on the shelf with \"Adjust ' +\n 'stock\" in the products hub first — these answers move no ' +\n 'stock, they only clear this question.'}\n </Typography>\n <Stack direction=\"row\" spacing={1}>\n <Button\n size=\"small\"\n variant=\"outlined\"\n disabled={busy}\n onClick={() => handleRestockAnswer('restocked')}\n >\n {'Restocked'}\n </Button>\n <Button\n size=\"small\"\n disabled={busy}\n onClick={() => handleRestockAnswer('dismissed')}\n >\n {'No restock'}\n </Button>\n </Stack>\n </Stack>\n </>\n ) : null}\n {/* A register sale rung offline, and what its sync found (AGL-3625). */}\n <OrderOfflineNotice order={order} />\n {/* Pickup or the store's own delivery, and its next step (AGL-3624). */}\n {orderId ? <OrderLocalFulfillmentPanel hostId={hostId} orderId={orderId} order={order} /> : null}\n <Divider />\n <Typography variant=\"subtitle2\">{'Timeline'}</Typography>\n {(order.timeline ?? [])\n .slice()\n .reverse()\n .map((event, index) => (\n <Typography key={index} variant=\"caption\" color=\"text.secondary\">\n {`${new Date(event.atMs).toLocaleString()} — ${event.event}` +\n (event.detail ? `: ${event.detail}` : '')}\n </Typography>\n ))}\n <Stack direction=\"row\" spacing={1}>\n <TextField\n label=\"Add note\"\n value={note}\n onChange={(event) => setNote(event.target.value)}\n size=\"small\"\n sx={{ flex: 1 }}\n />\n <Button size=\"small\" disabled={!note.trim()} onClick={handleNote}>\n {'Add'}\n </Button>\n </Stack>\n <FulfillmentList\n order={order}\n busy={busy}\n onUpdateTracking={handleUpdateTracking}\n onCancelFulfillment={handleCancelFulfillment}\n />\n {fulfilling ? (\n <FulfillItemsPanel\n order={order}\n busy={busy}\n onSubmit={handleFulfill}\n currency={storeCurrency}\n onCancel={() => setFulfilling(false)}\n renderZone={\n WidgetSlot && zoneOrder\n ? (selection, applyTracking) => (\n <HostedZone\n renderer={WidgetSlot}\n slot={ORDER_FULFILLMENT_ZONE.id}\n hostId={hostId}\n orgId={undefined}\n order={zoneOrder}\n recordFulfillment={recordFulfillment}\n selection={selection}\n applyTracking={applyTracking}\n />\n )\n : undefined\n }\n />\n ) : null}\n {/*\n The order zone (AGL-3611): a widget reads the order and records a\n shipment through `recordFulfillment`, this dialog's own route.\n */}\n {WidgetSlot && zoneOrder ? (\n <HostedZone\n renderer={WidgetSlot}\n slot={ORDER_DETAIL_ZONE.id}\n hostId={hostId}\n orgId={undefined}\n order={zoneOrder}\n recordFulfillment={recordFulfillment}\n />\n ) : null}\n {/* The order's returns and \"Start return\" (AGL-3611). */}\n {orderId ? <OrderReturns hostId={hostId} orderId={orderId} order={order} /> : null}\n {order.paymentLinkUrl && order.status === 'pending' ? (\n <Button\n size=\"small\"\n sx={{ alignSelf: 'flex-start' }}\n onClick={() => {\n navigator.clipboard.writeText(String(order.paymentLinkUrl))\n enqueueSnackbar('Payment link copied', {\n variant: 'success',\n persist: false,\n })\n }}\n >\n {'Copy payment link'}\n </Button>\n ) : null}\n </DialogContent>\n <DialogActions>\n {customerCrmHref ? (\n <Button\n component={AppLink as any}\n {...({ componentVariant: 'naked', nativeButton: false } as any)}\n href={customerCrmHref}\n >\n {'View customer in CRM'}\n </Button>\n ) : null}\n <Button onClick={handlePackingSlip}>{'Packing slip'}</Button>\n {orderId ? <OrderInvoiceButton hostId={hostId} orderId={orderId} order={order} /> : null}\n {orderId ? <OrderReceiptResend hostId={hostId} orderId={orderId} order={order} /> : null}\n {orderId && order.channel === 'pos' ? (\n // The register's 80mm receipt, its gift receipt and a reprint on\n // the register's cloud printer (AGL-3609).\n <PosReceiptActions hostId={hostId} orderId={orderId} order={order} cloudPrint=\"reprint\" />\n ) : null}\n {can('cancelled') ? (\n <Button color=\"error\" disabled={busy} onClick={handleCancel}>\n {'Cancel order'}\n </Button>\n ) : null}\n {can('refunded') ? (\n // Disabled on `orderDisputeBlocksRefund`, NOT the badge's broader\n // `orderHasOpenDispute` (AGL-1820): a formal open dispute means the\n // bank already pulled the funds and the route answers 409\n // (AGL-1809), while an open INQUIRY shows the badge but must keep\n // this button live — a full refund is how an inquiry is resolved.\n CommerceModel.orderDisputeBlocksRefund(order) ? (\n <Tooltip title={REFUND_BLOCKED_BY_DISPUTE}>\n {/* A disabled button fires no pointer events; the wrapper\n carries the hover for the tooltip. */}\n <span>\n <Button color=\"error\" disabled>\n {'Refund'}\n </Button>\n </span>\n </Tooltip>\n ) : (\n <Button\n color=\"error\"\n disabled={busy}\n onClick={() => handleRefund()}\n >\n {'Refund'}\n </Button>\n )\n ) : null}\n {(can('fulfilled') || can('partially_fulfilled')) && !fulfilling ? (\n <Button\n variant=\"contained\"\n color=\"primary\"\n onClick={() => setFulfilling(true)}\n >\n {'Fulfill…'}\n </Button>\n ) : null}\n {can('delivered') ? (\n <Button disabled={busy} onClick={handleDelivered}>\n {'Mark delivered'}\n </Button>\n ) : null}\n <Button onClick={onClose}>{'Close'}</Button>\n </DialogActions>\n </Dialog>\n )\n}\nOrderDetailDialog.displayName = 'OrderDetailDialog'\n\nexport default OrderDetailDialog\n"],"names":["CommerceModel","buildPackingSlipHtml","orderRefundPrompt","REFUND_BLOCKED_BY_DISPUTE","pluginRecordByEmailHref","describePaymentRisk","AppLink","useConfirmationContext","useSnackbar","Button","Chip","Dialog","DialogActions","DialogContent","DialogTitle","Divider","Stack","TextField","Tooltip","Typography","doc","getDoc","runTransaction","updateDoc","useParams","memo","useCallback","useEffect","useMemo","useRef","useState","useFirestore","useUser","OrderLocalFulfillmentPanel","authorizedFetch","useConsoleWidgetSlot","consoleOrderZoneOrder","FulfillItemsPanel","FulfillmentList","toZoneFulfillment","ORDER_DETAIL_ZONE","ORDER_FULFILLMENT_ZONE","OrderInvoiceButton","OrderReceiptResend","OrderReturns","PosReceiptActions","OrderOfflineNotice","STATUS_COLOR","pending","paid","partially_fulfilled","fulfilled","delivered","cancelled","refunded","DISPUTE_COLOR","open","lost","won","settled","usd","cents","toFixed","HostedZone","props","renderer","Renderer","zone","newAttemptKey","globalThis","crypto","randomUUID","Date","now","Math","random","toString","slice","OrderDetailDialog","order","hostId","rawOrder","onClose","firestore","data","user","enqueueSnackbar","confirm","fulfilling","setFulfilling","storeCurrency","setStoreCurrency","undefined","live","Promise","resolve","then","snapshot","currency","String","get","trim","toUpperCase","catch","WidgetSlot","note","setNote","busy","setBusy","liftLegacyOrder","orderId","$id","params","customerCrmHref","orgSlug","host","customerEmail","write","patch","transition","to","extra","copy","headers","response","method","body","JSON","stringify","error","console","subject","variant","allowDuplicate","payload","json","ok","status","action","already","partial","done","persist","fulfillKey","current","fulfill","submission","key","lineItems","carrier","trackingNumber","trackingUrl","labelUrl","shippingCostCents","notify","handleFulfill","Boolean","handleUpdateTracking","fulfillmentId","next","handleCancelFulfillment","confirmed","title","description","confirmationText","confirmationButtonProps","color","recordFulfillment","request","map","entry","idempotencyKey","fulfillment","Error","zoneOrder","handleDelivered","handleCancel","units","Number","alreadyCancelled","attemptKey","handleRefund","lineItemIds","scoped","length","prompt","text","handleRestockAnswer","resolution","check","restockCheck","reference","verdict","transaction","exists","answer","restockAnswer","flaggedAtMs","uid","update","handleNote","orderNoteUpdate","handlePackingSlip","win","window","document","close","focus","print","totals","can","canTransitionOrder","dispute","describeOrderDispute","paymentRisk","reversal","splitOrderReversal","restock","fulfilledByLine","orderLineFulfillmentStates","state","fulfilledQuantity","maxWidth","fullWidth","direction","spacing","sx","alignItems","span","formatOrderNumber","label","replace","size","detail","tone","channel","display","flexDirection","gap","customerName","filter","join","line","index","withdrawn","orderLineRefunded","flex","textDecoration","quantity","name","variantLabel","useDayKey","checkInDayLabel","orderDisputeBlocksRefund","disabled","onClick","unitAmountCents","orderRefundState","orderRefundSummary","itemsCents","shippingCents","extras","amountCents","taxCents","discountCents","totalCents","fontWeight","abs","describeOrderTaxMode","taxMode","refundedCents","chargedBackCents","describeRestockCheck","lines","productId","timeline","reverse","event","atMs","toLocaleString","value","onChange","target","onUpdateTracking","onCancelFulfillment","onSubmit","onCancel","renderZone","selection","applyTracking","slot","id","orgId","paymentLinkUrl","alignSelf","navigator","clipboard","writeText","component","componentVariant","nativeButton","href","cloudPrint","displayName"],"mappings":"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"}
|
|
@@ -68,7 +68,7 @@ const ROUTE = '/api/commerce/order-webhooks';
|
|
|
68
68
|
}).then((payload)=>{
|
|
69
69
|
if (active) setStatus(payload);
|
|
70
70
|
}).catch(()=>{
|
|
71
|
-
//
|
|
71
|
+
// Without "Manage order webhooks" (AGL-4047), or the route is down: the
|
|
72
72
|
// card is not this person's to use.
|
|
73
73
|
if (active) setStatus(null);
|
|
74
74
|
});
|