@aglyn/plugins-commerce 1.0.0-beta.285 → 1.0.0-beta.287
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/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 +11 -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 +67 -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/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 +29 -0
- package/src/lib/server/commerce-site-keys.js +40 -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/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 +15 -4
- package/src/lib/server/pos-ops-gate.js +42 -9
- 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-return.d.ts +10 -0
- package/src/lib/server/pos-return.js +26 -1
- 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 +25 -20
- 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 +34 -11
- 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
|
@@ -18,21 +18,36 @@ import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
|
18
18
|
import { emailUnverifiedResponse, firebaseAdmin, isImpersonationSession } from "@aglyn/tenant-data-admin";
|
|
19
19
|
import { addAdminAudit } from "@aglyn/tenant-data-admin/server/admin-audit-write";
|
|
20
20
|
import { invalidIdTokenResponse } from "@aglyn/tenant-data-admin/server/id-token-refusal";
|
|
21
|
-
import { isPosHardwareOrderStatus, nextPosHardwareStatus, POS_HARDWARE_ORDER_ID, POS_HARDWARE_ORDERS_COLLECTION, POS_HARDWARE_STATUS_STAMP,
|
|
21
|
+
import { isPosHardwareOrderStatus, nextPosHardwareStatus, POS_HARDWARE_ORDER_ID, POS_HARDWARE_ORDERS_COLLECTION, POS_HARDWARE_STATUS_STAMP, posHardwareBuyerErasedPatch, posHardwareOrderSource, posHardwareSaleRecord, posHardwareSaleSetOptions } from "../model/pos-hardware.js";
|
|
22
22
|
import { fulfillmentTrackingUrl } from "../model/tracking-url.js";
|
|
23
|
-
import { hardwareOrdersRef, posHardwareOrderNumber, posHardwareSaleRef } from "./pos-hardware.js";
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
23
|
+
import { hardwareOrdersRef, posHardwareInPersonConfig, posHardwareOrderNumber, posHardwareSaleRef } from "./pos-hardware.js";
|
|
24
|
+
import { cancelAndRefundPosHardwareOrder } from "./pos-hardware-cancel.js";
|
|
25
|
+
import { sendPosHardwareEmail, sendPosHardwareEmailOnce } from "./pos-hardware-notify.js";
|
|
26
26
|
/*==========================================
|
|
27
27
|
* `/api/commerce/admin/hardware-orders` (AGL-4038): the staff end of the POS
|
|
28
28
|
* hardware shop, for the Hardware orders staff page.
|
|
29
29
|
*
|
|
30
|
-
* GET every workspace's orders, newest first, optionally one status
|
|
30
|
+
* GET every workspace's orders, newest first, optionally one status,
|
|
31
|
+
* or `?attach=pending`: the in-person sales nobody has said whose
|
|
32
|
+
* they are yet (AGL-4038), after recording any paid sale on the
|
|
33
|
+
* seller store still waiting to be recorded
|
|
31
34
|
* POST update record Stripe's order id and the tracking, or move the
|
|
32
35
|
* order one step on (Ordered → Shipped → Delivered →
|
|
33
36
|
* Registered); Shipped needs a tracking number
|
|
34
37
|
* cancel cancel and refund in full, before it ships
|
|
35
38
|
* refund refund in full, before it ships
|
|
39
|
+
* refund an order sold in person (AGL-4038): what is left of it,
|
|
40
|
+
* through the register sale's own card refund on the
|
|
41
|
+
* selling store's account (`pos-hardware-returns.ts`)
|
|
42
|
+
* Each of the three takes `notifyBuyer`, the dialog's "Email the
|
|
43
|
+
* buyer" (AGL-4038): true sends the buyer the canceled-and-refunded
|
|
44
|
+
* email (online) or the refunded email (in person), once, under the
|
|
45
|
+
* same claim a closure sends it under; false sends nothing. Absent
|
|
46
|
+
* reads as the dialog's default, true. It is in the audit row.
|
|
47
|
+
* decline-return decline a buyer's open return request, with a note
|
|
48
|
+
* forget-buyer take the buyer's address and account off an order
|
|
49
|
+
* sold in person (AGL-4038), for a privacy request from
|
|
50
|
+
* someone who never made an account
|
|
36
51
|
*
|
|
37
52
|
* Staff only. Reading is open to every staff role; every write is `super` or
|
|
38
53
|
* `billing`, because each one changes what a customer is told or returns
|
|
@@ -52,7 +67,7 @@ const json = (body, status = 200)=>Response.json(body, {
|
|
|
52
67
|
}
|
|
53
68
|
});
|
|
54
69
|
/** An order as the staff page lists it. */ function staffView(id, order) {
|
|
55
|
-
var _order_contactEmail, _order_lines, _order_subtotalCents, _order_shipping, _order_taxCents, _order_totalCents, _order_stripeCheckoutSessionId, _order_stripePaymentIntentId, _order_stripeHardwareOrderId, _order_tracking, _order_createdAtMs, _order_updatedAtMs;
|
|
70
|
+
var _order_contactEmail, _order_lines, _order_subtotalCents, _order_shipping, _order_taxCents, _order_totalCents, _order_stripeCheckoutSessionId, _order_stripePaymentIntentId, _order_stripeHardwareOrderId, _order_tracking, _order_createdAtMs, _order_updatedAtMs, _order_discountCents, _order_posSale, _order_paidTo, _order_attachment, _order_units, _order_refundedCents, _order_refunds, _order_returnRequest;
|
|
56
71
|
return {
|
|
57
72
|
id,
|
|
58
73
|
number: posHardwareOrderNumber(id),
|
|
@@ -72,7 +87,18 @@ const json = (body, status = 200)=>Response.json(body, {
|
|
|
72
87
|
livemode: order.livemode === true,
|
|
73
88
|
refundPending: Boolean(order.refundRequestedAtMs),
|
|
74
89
|
createdAtMs: (_order_createdAtMs = order.createdAtMs) != null ? _order_createdAtMs : 0,
|
|
75
|
-
updatedAtMs: (_order_updatedAtMs = order.updatedAtMs) != null ? _order_updatedAtMs : 0
|
|
90
|
+
updatedAtMs: (_order_updatedAtMs = order.updatedAtMs) != null ? _order_updatedAtMs : 0,
|
|
91
|
+
// Sold in person at the platform's own store (AGL-4038): where, how it
|
|
92
|
+
// was paid and into which account, and whose it is.
|
|
93
|
+
source: posHardwareOrderSource(order),
|
|
94
|
+
discountCents: (_order_discountCents = order.discountCents) != null ? _order_discountCents : 0,
|
|
95
|
+
posSale: (_order_posSale = order.posSale) != null ? _order_posSale : null,
|
|
96
|
+
paidTo: (_order_paidTo = order.paidTo) != null ? _order_paidTo : null,
|
|
97
|
+
attachment: (_order_attachment = order.attachment) != null ? _order_attachment : null,
|
|
98
|
+
units: (_order_units = order.units) != null ? _order_units : [],
|
|
99
|
+
refundedCents: (_order_refundedCents = order.refundedCents) != null ? _order_refundedCents : 0,
|
|
100
|
+
refunds: (_order_refunds = order.refunds) != null ? _order_refunds : [],
|
|
101
|
+
returnRequest: (_order_returnRequest = order.returnRequest) != null ? _order_returnRequest : null
|
|
76
102
|
};
|
|
77
103
|
}
|
|
78
104
|
let Refusal = class Refusal extends Error {
|
|
@@ -120,18 +146,35 @@ async function handler(request) {
|
|
|
120
146
|
const role = String((_decoded_staffRole = decoded['staffRole']) != null ? _decoded_staffRole : 'support');
|
|
121
147
|
const firestore = firebaseAdmin.app().firestore();
|
|
122
148
|
if (method === 'GET') {
|
|
123
|
-
var _ref, _ref1, _ref2;
|
|
149
|
+
var _ref, _ref1, _ref2, _ref3, _ref4;
|
|
124
150
|
var _shown_;
|
|
125
151
|
const requested = String((_ref = query == null ? void 0 : query['status']) != null ? _ref : '');
|
|
152
|
+
const attach = String((_ref1 = query == null ? void 0 : query['attach']) != null ? _ref1 : '');
|
|
153
|
+
if (attach && attach !== 'pending') return json({
|
|
154
|
+
error: 'Unknown filter'
|
|
155
|
+
}, 400);
|
|
156
|
+
const returns = String((_ref2 = query == null ? void 0 : query['returns']) != null ? _ref2 : '');
|
|
157
|
+
if (returns && returns !== 'requested') return json({
|
|
158
|
+
error: 'Unknown filter'
|
|
159
|
+
}, 400);
|
|
126
160
|
let ordersQuery = firestore.collectionGroup(POS_HARDWARE_ORDERS_COLLECTION);
|
|
127
|
-
if (requested) {
|
|
161
|
+
if (returns === 'requested') {
|
|
162
|
+
// Buyers' open return requests (AGL-4038), oldest waiting first in the
|
|
163
|
+
// newest-first list like every other filter.
|
|
164
|
+
ordersQuery = ordersQuery.where('returnRequest.state', '==', 'requested');
|
|
165
|
+
} else if (attach === 'pending') {
|
|
166
|
+
// A sale whose recording was missed is recorded before the list is read.
|
|
167
|
+
const config = posHardwareInPersonConfig();
|
|
168
|
+
if (config) await (await import("./pos-hardware-in-person.js")).sweepInPersonPosHardwareSales(config);
|
|
169
|
+
ordersQuery = ordersQuery.where('attachment.state', '==', 'pending');
|
|
170
|
+
} else if (requested) {
|
|
128
171
|
if (!isPosHardwareOrderStatus(requested)) return json({
|
|
129
172
|
error: 'Unknown status'
|
|
130
173
|
}, 400);
|
|
131
174
|
ordersQuery = ordersQuery.where('status', '==', requested);
|
|
132
175
|
}
|
|
133
176
|
ordersQuery = ordersQuery.orderBy('createdAtMs', 'desc');
|
|
134
|
-
const after = String((
|
|
177
|
+
const after = String((_ref3 = query == null ? void 0 : query['after']) != null ? _ref3 : '');
|
|
135
178
|
if (after) {
|
|
136
179
|
if (!CURSOR.test(after)) return json({
|
|
137
180
|
error: 'Unknown page'
|
|
@@ -146,7 +189,7 @@ async function handler(request) {
|
|
|
146
189
|
const shown = docs.slice(0, PAGE);
|
|
147
190
|
return json({
|
|
148
191
|
orders: shown.map((doc)=>staffView(doc.id, doc.data())),
|
|
149
|
-
next: docs.length > PAGE ? (
|
|
192
|
+
next: docs.length > PAGE ? (_ref4 = (_shown_ = shown[shown.length - 1]) == null ? void 0 : _shown_.ref.path) != null ? _ref4 : null : null,
|
|
150
193
|
pageSize: PAGE,
|
|
151
194
|
canWrite: WRITE_ROLES.includes(role)
|
|
152
195
|
});
|
|
@@ -173,9 +216,25 @@ async function handler(request) {
|
|
|
173
216
|
actorUid: decoded.uid,
|
|
174
217
|
actorEmail: decoded.email ? String(decoded.email) : null
|
|
175
218
|
};
|
|
219
|
+
// "Email the buyer" (AGL-4038): explicit when sent, the dialog's default when not.
|
|
220
|
+
const notifyRaw = input['notifyBuyer'];
|
|
221
|
+
if (notifyRaw !== undefined && typeof notifyRaw !== 'boolean') {
|
|
222
|
+
return json({
|
|
223
|
+
error: 'notifyBuyer must be true or false'
|
|
224
|
+
}, 400);
|
|
225
|
+
}
|
|
226
|
+
const notifyBuyer = notifyRaw !== false;
|
|
176
227
|
if (action === 'update') return await updateOrder(firestore, ref, orgId, orderId, input, actor);
|
|
228
|
+
if (action === 'forget-buyer') return await forgetBuyer(firestore, ref, orgId, orderId, actor);
|
|
229
|
+
if (action === 'decline-return') return await inPersonReturn(firestore, orgId, orderId, action, input, actor);
|
|
230
|
+
if (action === 'refund-return') return await onlineReturnRefund(firestore, orgId, orderId, input, actor, notifyBuyer);
|
|
231
|
+
// Handed over at the sale, an in-person order is never canceled: either
|
|
232
|
+
// button refunds it, its own way.
|
|
233
|
+
if ((action === 'refund' || action === 'cancel') && await soldInPerson(ref)) {
|
|
234
|
+
return await inPersonReturn(firestore, orgId, orderId, 'refund', input, actor, notifyBuyer);
|
|
235
|
+
}
|
|
177
236
|
if (action === 'cancel' || action === 'refund') {
|
|
178
|
-
return await refundOrder(firestore,
|
|
237
|
+
return await refundOrder(firestore, orgId, orderId, action, actor, notifyBuyer);
|
|
179
238
|
}
|
|
180
239
|
return json({
|
|
181
240
|
error: 'Unknown action'
|
|
@@ -232,7 +291,7 @@ async function updateOrder(firestore, ref, orgId, orderId, input, actor) {
|
|
|
232
291
|
}
|
|
233
292
|
const after = _extends({}, before, patch);
|
|
234
293
|
transaction.update(ref, patch);
|
|
235
|
-
transaction.set(posHardwareSaleRef(orderId), posHardwareSaleRecord(orderId, after));
|
|
294
|
+
transaction.set(posHardwareSaleRef(orderId), posHardwareSaleRecord(orderId, after), posHardwareSaleSetOptions(after));
|
|
236
295
|
return {
|
|
237
296
|
before,
|
|
238
297
|
after,
|
|
@@ -265,81 +324,185 @@ async function updateOrder(firestore, ref, orgId, orderId, input, actor) {
|
|
|
265
324
|
order: staffView(orderId, outcome.after)
|
|
266
325
|
});
|
|
267
326
|
}
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
327
|
+
/** Whether an order was sold in person (AGL-4038), which refunds its own way. */ async function soldInPerson(ref) {
|
|
328
|
+
const snapshot = await ref.get();
|
|
329
|
+
return snapshot.exists && posHardwareOrderSource(snapshot.data()) === 'in_person';
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* A refund or a declined return of an order sold in person (AGL-4038): the
|
|
333
|
+
* refund goes back through the register sale's own card refund on the
|
|
334
|
+
* selling store's account, never the platform's Checkout.
|
|
335
|
+
*/ async function inPersonReturn(firestore, orgId, orderId, action, input, actor, notifyBuyer = false) {
|
|
336
|
+
const returns = await import("./pos-hardware-returns.js");
|
|
337
|
+
try {
|
|
338
|
+
var _outcome_order_refunds, _outcome_before_refundedCents, _outcome_order_refundedCents, _ref;
|
|
339
|
+
var _outcome_order_returnRequest;
|
|
340
|
+
const outcome = action === 'refund' ? await returns.refundInPersonPosHardwareOrder({
|
|
341
|
+
config: posHardwareInPersonConfig(),
|
|
342
|
+
orgId,
|
|
343
|
+
orderId,
|
|
344
|
+
actorUid: actor.actorUid
|
|
345
|
+
}) : await returns.declinePosHardwareReturn({
|
|
346
|
+
orgId,
|
|
347
|
+
orderId,
|
|
348
|
+
actorUid: actor.actorUid,
|
|
349
|
+
note: input['note']
|
|
350
|
+
});
|
|
351
|
+
// The refund just made, told once by its own key, when staff chose to.
|
|
352
|
+
const made = action === 'refund' ? ((_outcome_order_refunds = outcome.order.refunds) != null ? _outcome_order_refunds : []).slice(-1)[0] : undefined;
|
|
353
|
+
const buyerEmail = action !== 'refund' ? undefined : !notifyBuyer ? 'off' : made ? await sendPosHardwareEmailOnce('refunded', orderId, outcome.order, `refunded:${made.key}`) : 'skipped';
|
|
354
|
+
await addAdminAudit(firestore, _extends({
|
|
355
|
+
action: action === 'refund' ? 'pos-hardware-order-refund' : 'pos-hardware-return-decline'
|
|
356
|
+
}, actor, {
|
|
357
|
+
scope: 'posHardwareOrder',
|
|
358
|
+
target: `orgs/${orgId}/${POS_HARDWARE_ORDERS_COLLECTION}/${orderId}`,
|
|
359
|
+
orgId,
|
|
360
|
+
before: {
|
|
361
|
+
status: outcome.before.status,
|
|
362
|
+
refundedCents: (_outcome_before_refundedCents = outcome.before.refundedCents) != null ? _outcome_before_refundedCents : 0
|
|
363
|
+
},
|
|
364
|
+
after: _extends({
|
|
365
|
+
status: outcome.order.status,
|
|
366
|
+
refundedCents: (_outcome_order_refundedCents = outcome.order.refundedCents) != null ? _outcome_order_refundedCents : 0,
|
|
367
|
+
returnRequest: (_ref = (_outcome_order_returnRequest = outcome.order.returnRequest) == null ? void 0 : _outcome_order_returnRequest.state) != null ? _ref : null
|
|
368
|
+
}, action === 'refund' ? {
|
|
369
|
+
notifyBuyer,
|
|
370
|
+
buyerEmail
|
|
371
|
+
} : {}),
|
|
372
|
+
at: firebaseAdmin.firestore.FieldValue.serverTimestamp()
|
|
373
|
+
}));
|
|
374
|
+
return json(_extends({
|
|
375
|
+
ok: true,
|
|
376
|
+
order: staffView(orderId, outcome.order)
|
|
377
|
+
}, buyerEmail ? {
|
|
378
|
+
buyerEmail
|
|
379
|
+
} : {}));
|
|
380
|
+
} catch (error) {
|
|
381
|
+
if (error instanceof returns.PosHardwareReturnRefusal) throw new Refusal(error.message, error.status);
|
|
382
|
+
throw error;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Refunds an ONLINE order the buyer sent back (AGL-4038), once its return
|
|
387
|
+
* was requested: the items and their tax, less any restocking fee Stripe
|
|
388
|
+
* charged, to the card it was paid with. The buyer is emailed once by the
|
|
389
|
+
* refund's key, when staff chose to.
|
|
390
|
+
*/ async function onlineReturnRefund(firestore, orgId, orderId, input, actor, notifyBuyer) {
|
|
391
|
+
const returns = await import("./pos-hardware-returns.js");
|
|
392
|
+
try {
|
|
393
|
+
var _outcome_order_refunds, _outcome_before_refundedCents, _outcome_order_refundedCents, _ref, _ref1;
|
|
394
|
+
var _outcome_order_returnRequest;
|
|
395
|
+
const outcome = await returns.refundReturnedOnlinePosHardwareOrder({
|
|
396
|
+
orgId,
|
|
397
|
+
orderId,
|
|
398
|
+
actorUid: actor.actorUid,
|
|
399
|
+
restockingFeeCents: input['restockingFeeCents']
|
|
400
|
+
});
|
|
401
|
+
const made = ((_outcome_order_refunds = outcome.order.refunds) != null ? _outcome_order_refunds : []).slice(-1)[0];
|
|
402
|
+
const buyerEmail = !notifyBuyer ? 'off' : made ? await sendPosHardwareEmailOnce('returnRefunded', orderId, outcome.order, `refunded:${made.key}`) : 'skipped';
|
|
403
|
+
await addAdminAudit(firestore, _extends({
|
|
404
|
+
action: 'pos-hardware-return-refund'
|
|
405
|
+
}, actor, {
|
|
406
|
+
scope: 'posHardwareOrder',
|
|
407
|
+
target: `orgs/${orgId}/${POS_HARDWARE_ORDERS_COLLECTION}/${orderId}`,
|
|
408
|
+
orgId,
|
|
409
|
+
before: {
|
|
410
|
+
status: outcome.before.status,
|
|
411
|
+
refundedCents: (_outcome_before_refundedCents = outcome.before.refundedCents) != null ? _outcome_before_refundedCents : 0
|
|
412
|
+
},
|
|
413
|
+
after: {
|
|
414
|
+
status: outcome.order.status,
|
|
415
|
+
refundedCents: (_outcome_order_refundedCents = outcome.order.refundedCents) != null ? _outcome_order_refundedCents : 0,
|
|
416
|
+
refundId: (_ref = made == null ? void 0 : made.stripeRefundId) != null ? _ref : null,
|
|
417
|
+
returnRequest: (_ref1 = (_outcome_order_returnRequest = outcome.order.returnRequest) == null ? void 0 : _outcome_order_returnRequest.state) != null ? _ref1 : null,
|
|
418
|
+
notifyBuyer,
|
|
419
|
+
buyerEmail
|
|
420
|
+
},
|
|
421
|
+
at: firebaseAdmin.firestore.FieldValue.serverTimestamp()
|
|
422
|
+
}));
|
|
423
|
+
return json({
|
|
424
|
+
ok: true,
|
|
425
|
+
order: staffView(orderId, outcome.order),
|
|
426
|
+
buyerEmail
|
|
427
|
+
});
|
|
428
|
+
} catch (error) {
|
|
429
|
+
if (error instanceof returns.PosHardwareReturnRefusal) throw new Refusal(error.message, error.status);
|
|
430
|
+
throw error;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* Takes the buyer off an order sold in person (AGL-4038): the same patch an
|
|
435
|
+
* account erasure applies, for a buyer an erasure cannot reach because they
|
|
436
|
+
* have no account. The order, its amounts and the store's tax region stay.
|
|
437
|
+
*/ async function forgetBuyer(firestore, ref, orgId, orderId, actor) {
|
|
438
|
+
var _after_buyerErasedAtMs;
|
|
439
|
+
const after = await firestore.runTransaction(async (transaction)=>{
|
|
275
440
|
const snapshot = await transaction.get(ref);
|
|
276
441
|
if (!snapshot.exists) throw new Refusal('No such order', 404);
|
|
277
|
-
const
|
|
278
|
-
if (
|
|
279
|
-
order,
|
|
280
|
-
already: true
|
|
281
|
-
};
|
|
282
|
-
if (!posHardwareRefundable(order.status)) {
|
|
283
|
-
throw new Refusal('This order has shipped, so it can no longer be canceled or refunded here. Arrange a return with Stripe instead.', 409);
|
|
442
|
+
const before = snapshot.data();
|
|
443
|
+
if (posHardwareOrderSource(before) !== 'in_person') {
|
|
444
|
+
throw new Refusal('Only an order sold in person has a buyer to remove here.', 409);
|
|
284
445
|
}
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
return
|
|
290
|
-
order,
|
|
291
|
-
already: false
|
|
292
|
-
};
|
|
446
|
+
const patch = posHardwareBuyerErasedPatch(before, Date.now());
|
|
447
|
+
const next = _extends({}, before, patch);
|
|
448
|
+
transaction.update(ref, patch);
|
|
449
|
+
transaction.set(posHardwareSaleRef(orderId), posHardwareSaleRecord(orderId, next), posHardwareSaleSetOptions(next));
|
|
450
|
+
return next;
|
|
293
451
|
});
|
|
294
|
-
|
|
452
|
+
await addAdminAudit(firestore, _extends({
|
|
453
|
+
action: 'pos-hardware-order-forget-buyer'
|
|
454
|
+
}, actor, {
|
|
455
|
+
scope: 'posHardwareOrder',
|
|
456
|
+
target: `orgs/${orgId}/${POS_HARDWARE_ORDERS_COLLECTION}/${orderId}`,
|
|
457
|
+
orgId,
|
|
458
|
+
before: null,
|
|
459
|
+
after: {
|
|
460
|
+
buyerErasedAtMs: (_after_buyerErasedAtMs = after.buyerErasedAtMs) != null ? _after_buyerErasedAtMs : null
|
|
461
|
+
},
|
|
462
|
+
at: firebaseAdmin.firestore.FieldValue.serverTimestamp()
|
|
463
|
+
}));
|
|
464
|
+
return json({
|
|
295
465
|
ok: true,
|
|
296
|
-
order: staffView(orderId,
|
|
466
|
+
order: staffView(orderId, after)
|
|
297
467
|
});
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
468
|
+
}
|
|
469
|
+
async function refundOrder(firestore, orgId, orderId, action, actor, notifyBuyer) {
|
|
470
|
+
const finalStatus = action === 'cancel' ? 'canceled' : 'refunded';
|
|
471
|
+
// The one cancel-and-refund path (`pos-hardware-cancel.ts`), which a
|
|
472
|
+
// workspace or account closure takes too: claimed under the lock, refunded
|
|
473
|
+
// once under one key, settled with the sale record.
|
|
474
|
+
const result = await cancelAndRefundPosHardwareOrder({
|
|
475
|
+
orgId,
|
|
476
|
+
orderId,
|
|
477
|
+
finalStatus,
|
|
478
|
+
reason: 'staff'
|
|
307
479
|
});
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
480
|
+
switch(result.outcome){
|
|
481
|
+
case 'missing':
|
|
482
|
+
throw new Refusal('No such order', 404);
|
|
483
|
+
case 'already':
|
|
484
|
+
{
|
|
485
|
+
// Pressed again — after a closure, or after an email that failed: the
|
|
486
|
+
// buyer is told now if they never were, and never twice.
|
|
487
|
+
const buyerEmail = notifyBuyer ? await sendPosHardwareEmailOnce('canceled', orderId, result.order) : 'off';
|
|
488
|
+
return json({
|
|
489
|
+
ok: true,
|
|
490
|
+
order: staffView(orderId, result.order),
|
|
491
|
+
buyerEmail
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
case 'not-refundable':
|
|
495
|
+
throw new Refusal('This order has shipped, so it can no longer be canceled or refunded here. Arrange a return with Stripe instead.', 409);
|
|
496
|
+
case 'no-payment':
|
|
497
|
+
throw new Refusal('This order has no payment to refund.', 409);
|
|
498
|
+
case 'refused':
|
|
499
|
+
return json({
|
|
500
|
+
error: result.message
|
|
501
|
+
}, 502);
|
|
318
502
|
}
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
[POS_HARDWARE_STATUS_STAMP[finalStatus]]: now,
|
|
323
|
-
updatedAtMs: now,
|
|
324
|
-
refundId: String(refund.body.id),
|
|
325
|
-
refundedCents: Number((_ref = (_refund_body_amount = refund.body.amount) != null ? _refund_body_amount : claim.order.totalCents) != null ? _ref : 0),
|
|
326
|
-
refundRequestedAtMs: firebaseAdmin.firestore.FieldValue.delete()
|
|
327
|
-
};
|
|
328
|
-
const settled = _extends({}, claim.order);
|
|
329
|
-
delete settled.refundRequestedAtMs;
|
|
330
|
-
const after = _extends({}, settled, {
|
|
331
|
-
status: finalStatus,
|
|
332
|
-
[POS_HARDWARE_STATUS_STAMP[finalStatus]]: now,
|
|
333
|
-
updatedAtMs: now,
|
|
334
|
-
refundId: patch.refundId,
|
|
335
|
-
refundedCents: patch.refundedCents
|
|
336
|
-
});
|
|
337
|
-
// The order and its retained sale record move together: the record is
|
|
338
|
-
// what the refund is accounted from once the workspace is gone.
|
|
339
|
-
await firestore.runTransaction(async (transaction)=>{
|
|
340
|
-
transaction.update(ref, patch);
|
|
341
|
-
transaction.set(posHardwareSaleRef(orderId), posHardwareSaleRecord(orderId, after));
|
|
342
|
-
});
|
|
503
|
+
// Canceled or refunded, it will not ship: the one canceled-and-refunded
|
|
504
|
+
// email, once, under the claim a closure sends it under (AGL-4038).
|
|
505
|
+
const buyerEmail = notifyBuyer ? await sendPosHardwareEmailOnce('canceled', orderId, result.order) : 'off';
|
|
343
506
|
await addAdminAudit(firestore, _extends({
|
|
344
507
|
action: `pos-hardware-order-${action}`
|
|
345
508
|
}, actor, {
|
|
@@ -347,18 +510,21 @@ async function refundOrder(firestore, ref, orgId, orderId, action, actor) {
|
|
|
347
510
|
target: `orgs/${orgId}/${POS_HARDWARE_ORDERS_COLLECTION}/${orderId}`,
|
|
348
511
|
orgId,
|
|
349
512
|
before: {
|
|
350
|
-
status:
|
|
513
|
+
status: result.before.status
|
|
351
514
|
},
|
|
352
515
|
after: {
|
|
353
516
|
status: finalStatus,
|
|
354
|
-
refundId:
|
|
355
|
-
refundedCents:
|
|
517
|
+
refundId: result.order.refundId,
|
|
518
|
+
refundedCents: result.order.refundedCents,
|
|
519
|
+
notifyBuyer,
|
|
520
|
+
buyerEmail
|
|
356
521
|
},
|
|
357
522
|
at: firebaseAdmin.firestore.FieldValue.serverTimestamp()
|
|
358
523
|
}));
|
|
359
524
|
return json({
|
|
360
525
|
ok: true,
|
|
361
|
-
order: staffView(orderId,
|
|
526
|
+
order: staffView(orderId, result.order),
|
|
527
|
+
buyerEmail
|
|
362
528
|
});
|
|
363
529
|
}
|
|
364
530
|
export { handler as posHardwareAdminOrders };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/server/pos-hardware-admin.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { pluginRequestFromWeb } from '@aglyn/aglyn/server'\nimport {\n emailUnverifiedResponse,\n firebaseAdmin,\n isImpersonationSession,\n} from '@aglyn/tenant-data-admin'\nimport { addAdminAudit } from '@aglyn/tenant-data-admin/server/admin-audit-write'\nimport { invalidIdTokenResponse } from '@aglyn/tenant-data-admin/server/id-token-refusal'\nimport {\n isPosHardwareOrderStatus,\n nextPosHardwareStatus,\n POS_HARDWARE_ORDER_ID,\n POS_HARDWARE_ORDERS_COLLECTION,\n POS_HARDWARE_STATUS_STAMP,\n posHardwareRefundable,\n posHardwareSaleRecord,\n type PosHardwareOrder,\n type PosHardwareOrderStatus,\n type PosHardwareTracking,\n} from '../model/pos-hardware'\nimport { fulfillmentTrackingUrl } from '../model/tracking-url'\nimport { hardwareOrdersRef, posHardwareOrderNumber, posHardwareSaleRef } from './pos-hardware'\nimport { sendPosHardwareEmail } from './pos-hardware-notify'\nimport { posStripe } from './pos-stripe'\n\n/*==========================================\n * `/api/commerce/admin/hardware-orders` (AGL-4038): the staff end of the POS\n * hardware shop, for the Hardware orders staff page.\n *\n * GET every workspace's orders, newest first, optionally one status\n * POST update record Stripe's order id and the tracking, or move the\n * order one step on (Ordered → Shipped → Delivered →\n * Registered); Shipped needs a tracking number\n * cancel cancel and refund in full, before it ships\n * refund refund in full, before it ships\n *\n * Staff only. Reading is open to every staff role; every write is `super` or\n * `billing`, because each one changes what a customer is told or returns\n * their money. Every write is an `adminAudit` row, and each one rewrites the\n * order's retained sale record (`posHardwareSales/{orderId}`) from the order\n * as it now stands, in the same transaction.\n *=========================================*/\n\n/** One page of the staff list. */\nconst PAGE = 25\n/** A page cursor is the path of the last order the previous page showed. */\nconst CURSOR = /^orgs\\/[^/]+\\/hardwareOrders\\/[^/]+$/\nconst WRITE_ROLES = ['super', 'billing']\n\nconst json = (body: unknown, status = 200) =>\n Response.json(body, { status, headers: { 'Cache-Control': 'no-store' } })\n\n/** An order as the staff page lists it. */\nfunction staffView(id: string, order: PosHardwareOrder) {\n return {\n id,\n number: posHardwareOrderNumber(id),\n orgId: order.orgId,\n hostId: order.hostId,\n status: order.status,\n contactEmail: order.contactEmail ?? null,\n lines: order.lines ?? [],\n subtotalCents: order.subtotalCents ?? 0,\n shipping: order.shipping ?? null,\n taxCents: order.taxCents ?? 0,\n totalCents: order.totalCents ?? 0,\n stripeCheckoutSessionId: order.stripeCheckoutSessionId ?? null,\n stripePaymentIntentId: order.stripePaymentIntentId ?? null,\n stripeHardwareOrderId: order.stripeHardwareOrderId ?? null,\n tracking: order.tracking ?? null,\n livemode: order.livemode === true,\n refundPending: Boolean((order as { refundRequestedAtMs?: number }).refundRequestedAtMs),\n createdAtMs: order.createdAtMs ?? 0,\n updatedAtMs: order.updatedAtMs ?? 0,\n }\n}\n\nexport type StaffHardwareOrderView = ReturnType<typeof staffView>\n\nclass Refusal extends Error {\n constructor(\n message: string,\n readonly status: number,\n ) {\n super(message)\n }\n}\n\n/** A tracking entry from the request, or `undefined` when none was sent. */\nfunction trackingFrom(raw: unknown): PosHardwareTracking | null | undefined {\n if (raw === undefined) return undefined\n if (raw === null) return null\n const carrier = String((raw as { carrier?: unknown })?.carrier ?? '').trim().slice(0, 60)\n const number = String((raw as { number?: unknown })?.number ?? '').trim().slice(0, 80)\n const url = String((raw as { url?: unknown })?.url ?? '').trim().slice(0, 500)\n if (!carrier || !number) throw new Refusal('Enter the carrier and the tracking number.', 400)\n return {\n carrier,\n number,\n // An https link typed by staff wins; otherwise one is built for a known\n // carrier, and an unknown one has none.\n url: fulfillmentTrackingUrl({ carrier, trackingNumber: number, trackingUrl: url || null }),\n }\n}\n\nasync function handler(request: Request): Promise<Response> {\n const { method, query, body, headers: rawHeaders } = await pluginRequestFromWeb(request)\n const headers = rawHeaders as Partial<Record<string, string>>\n const authorization = headers.authorization ?? ''\n const idToken = authorization.startsWith('Bearer ') ? authorization.slice('Bearer '.length) : undefined\n if (!idToken) return json({ error: 'Unauthenticated' }, 401)\n\n try {\n const decoded = await firebaseAdmin.app().auth().verifyIdToken(idToken)\n if (!decoded.email_verified && !isImpersonationSession(decoded)) return emailUnverifiedResponse()\n if (!decoded['staff']) return json({ error: 'Staff only' }, 403)\n // A missing role claim reads as the least one, never as super.\n const role = String(decoded['staffRole'] ?? 'support')\n const firestore = firebaseAdmin.app().firestore()\n\n if (method === 'GET') {\n const requested = String(query?.['status'] ?? '')\n let ordersQuery: any = firestore.collectionGroup(POS_HARDWARE_ORDERS_COLLECTION)\n if (requested) {\n if (!isPosHardwareOrderStatus(requested)) return json({ error: 'Unknown status' }, 400)\n ordersQuery = ordersQuery.where('status', '==', requested)\n }\n ordersQuery = ordersQuery.orderBy('createdAtMs', 'desc')\n const after = String(query?.['after'] ?? '')\n if (after) {\n if (!CURSOR.test(after)) return json({ error: 'Unknown page' }, 400)\n const cursor = await firestore.doc(after).get()\n // An order deleted since the page was read starts the list over\n // rather than answering an empty page.\n if (cursor.exists) ordersQuery = ordersQuery.startAfter(cursor)\n }\n const snapshot = await ordersQuery.limit(PAGE + 1).get()\n const docs = snapshot.docs as Array<{ id: string; ref: { path: string }; data: () => PosHardwareOrder }>\n const shown = docs.slice(0, PAGE)\n return json({\n orders: shown.map((doc) => staffView(doc.id, doc.data())),\n next: docs.length > PAGE ? (shown[shown.length - 1]?.ref.path ?? null) : null,\n pageSize: PAGE,\n canWrite: WRITE_ROLES.includes(role),\n })\n }\n\n if (method !== 'POST') return json({ error: 'Method not allowed' }, 405)\n if (!WRITE_ROLES.includes(role)) {\n return json({ error: 'Changing a hardware order requires the super or billing staff role.' }, 403)\n }\n const input = (body ?? {}) as Record<string, unknown>\n const action = String(input['action'] ?? '')\n const orgId = String(input['orgId'] ?? '')\n const orderId = String(input['orderId'] ?? '')\n if (!orgId || !/^[A-Za-z0-9_-]{1,128}$/.test(orgId) || !POS_HARDWARE_ORDER_ID.test(orderId)) {\n return json({ error: 'orgId or orderId is missing or malformed' }, 400)\n }\n const ref = hardwareOrdersRef(orgId).doc(orderId)\n const actor = { actorUid: decoded.uid, actorEmail: decoded.email ? String(decoded.email) : null }\n\n if (action === 'update') return await updateOrder(firestore, ref, orgId, orderId, input, actor)\n if (action === 'cancel' || action === 'refund') {\n return await refundOrder(firestore, ref, orgId, orderId, action, actor)\n }\n return json({ error: 'Unknown action' }, 400)\n } catch (error) {\n if (error instanceof Refusal) return json({ error: error.message }, error.status)\n const unauthenticated = invalidIdTokenResponse(error)\n if (unauthenticated) return unauthenticated\n console.error('[pos-hardware-admin]', error)\n return json({ error: 'Hardware orders failed' }, 500)\n }\n}\n\ntype Actor = { actorUid: string; actorEmail: string | null }\n\nasync function updateOrder(\n firestore: any,\n ref: any,\n orgId: string,\n orderId: string,\n input: Record<string, unknown>,\n actor: Actor,\n): Promise<Response> {\n const tracking = trackingFrom(input['tracking'])\n const hardwareOrderIdRaw = input['stripeHardwareOrderId']\n const stripeHardwareOrderId =\n hardwareOrderIdRaw === undefined ? undefined : String(hardwareOrderIdRaw ?? '').trim().slice(0, 120) || null\n const advanceTo = input['status'] === undefined ? undefined : String(input['status'])\n if (advanceTo !== undefined && !isPosHardwareOrderStatus(advanceTo)) {\n return json({ error: 'Unknown status' }, 400)\n }\n\n const outcome = await firestore.runTransaction(async (transaction: any) => {\n const snapshot = await transaction.get(ref)\n if (!snapshot.exists) throw new Refusal('No such order', 404)\n const before = snapshot.data() as PosHardwareOrder & { refundRequestedAtMs?: number }\n if (before.status === 'canceled' || before.status === 'refunded') {\n throw new Refusal('This order was canceled or refunded and can no longer change.', 409)\n }\n const now = Date.now()\n const patch: Record<string, unknown> = { updatedAtMs: now }\n if (stripeHardwareOrderId !== undefined) patch['stripeHardwareOrderId'] = stripeHardwareOrderId\n if (tracking !== undefined) patch['tracking'] = tracking\n let reached: PosHardwareOrderStatus | null = null\n if (advanceTo !== undefined && advanceTo !== before.status) {\n if (nextPosHardwareStatus(before.status) !== advanceTo) {\n throw new Refusal(`An order that is ${before.status} cannot move to ${advanceTo}.`, 409)\n }\n if (before.refundRequestedAtMs) throw new Refusal('A refund is in progress for this order.', 409)\n const trackingAfter = tracking !== undefined ? tracking : before.tracking\n if (advanceTo === 'shipped' && !trackingAfter?.number) {\n throw new Refusal('Add the tracking number before marking the order shipped.', 400)\n }\n patch['status'] = advanceTo\n patch[POS_HARDWARE_STATUS_STAMP[advanceTo]] = now\n reached = advanceTo\n }\n const after = { ...before, ...patch } as PosHardwareOrder\n transaction.update(ref, patch)\n transaction.set(posHardwareSaleRef(orderId), posHardwareSaleRecord(orderId, after))\n return { before, after, reached }\n })\n\n await addAdminAudit(firestore, {\n action: 'pos-hardware-order-update',\n ...actor,\n scope: 'posHardwareOrder',\n target: `orgs/${orgId}/${POS_HARDWARE_ORDERS_COLLECTION}/${orderId}`,\n orgId,\n before: {\n status: outcome.before.status,\n stripeHardwareOrderId: outcome.before.stripeHardwareOrderId ?? null,\n tracking: outcome.before.tracking ?? null,\n },\n after: {\n status: outcome.after.status,\n stripeHardwareOrderId: outcome.after.stripeHardwareOrderId ?? null,\n tracking: outcome.after.tracking ?? null,\n },\n at: firebaseAdmin.firestore.FieldValue.serverTimestamp(),\n })\n // Told once per step: the transaction above lets only one caller reach it.\n if (outcome.reached === 'shipped') await sendPosHardwareEmail('shipped', orderId, outcome.after)\n if (outcome.reached === 'delivered') await sendPosHardwareEmail('delivered', orderId, outcome.after)\n return json({ ok: true, order: staffView(orderId, outcome.after) })\n}\n\nasync function refundOrder(\n firestore: any,\n ref: any,\n orgId: string,\n orderId: string,\n action: 'cancel' | 'refund',\n actor: Actor,\n): Promise<Response> {\n const finalStatus: PosHardwareOrderStatus = action === 'cancel' ? 'canceled' : 'refunded'\n // Claim the refund under the lock first, so the order cannot be marked\n // shipped while the money is on its way back, and two presses refund once.\n const claim = await firestore.runTransaction(async (transaction: any) => {\n const snapshot = await transaction.get(ref)\n if (!snapshot.exists) throw new Refusal('No such order', 404)\n const order = snapshot.data() as PosHardwareOrder & { refundRequestedAtMs?: number }\n if (order.status === finalStatus) return { order, already: true }\n if (!posHardwareRefundable(order.status)) {\n throw new Refusal(\n 'This order has shipped, so it can no longer be canceled or refunded here. Arrange a return with Stripe instead.',\n 409,\n )\n }\n if (!order.stripePaymentIntentId) throw new Refusal('This order has no payment to refund.', 409)\n transaction.update(ref, { refundRequestedAtMs: Date.now() })\n return { order, already: false }\n })\n if (claim.already) return json({ ok: true, order: staffView(orderId, claim.order) })\n\n const refund = await posStripe('POST', 'refunds', {\n params: {\n payment_intent: claim.order.stripePaymentIntentId,\n 'metadata[type]': 'pos-hardware-order',\n 'metadata[orderId]': orderId,\n 'metadata[orgId]': orgId,\n },\n // One refund per order, whichever of the two acts asked for it.\n idempotencyKey: `pos-hw-refund-${orderId}`,\n })\n if (!refund.ok || !refund.body?.id) {\n await ref.update({ refundRequestedAtMs: firebaseAdmin.firestore.FieldValue.delete() }).catch(() => undefined)\n console.error('[pos-hardware-admin] refund refused', orderId, refund.status, refund.body?.error?.code)\n return json({ error: String(refund.body?.error?.message ?? '') || 'Stripe refused the refund.' }, 502)\n }\n const now = Date.now()\n const patch = {\n status: finalStatus,\n [POS_HARDWARE_STATUS_STAMP[finalStatus]]: now,\n updatedAtMs: now,\n refundId: String(refund.body.id),\n refundedCents: Number(refund.body.amount ?? claim.order.totalCents ?? 0),\n refundRequestedAtMs: firebaseAdmin.firestore.FieldValue.delete(),\n }\n const settled = { ...claim.order }\n delete settled.refundRequestedAtMs\n const after: PosHardwareOrder = {\n ...settled,\n status: finalStatus,\n [POS_HARDWARE_STATUS_STAMP[finalStatus]]: now,\n updatedAtMs: now,\n refundId: patch.refundId,\n refundedCents: patch.refundedCents,\n }\n // The order and its retained sale record move together: the record is\n // what the refund is accounted from once the workspace is gone.\n await firestore.runTransaction(async (transaction: any) => {\n transaction.update(ref, patch)\n transaction.set(posHardwareSaleRef(orderId), posHardwareSaleRecord(orderId, after))\n })\n await addAdminAudit(firestore, {\n action: `pos-hardware-order-${action}`,\n ...actor,\n scope: 'posHardwareOrder',\n target: `orgs/${orgId}/${POS_HARDWARE_ORDERS_COLLECTION}/${orderId}`,\n orgId,\n before: { status: claim.order.status },\n after: { status: finalStatus, refundId: patch.refundId, refundedCents: patch.refundedCents },\n at: firebaseAdmin.firestore.FieldValue.serverTimestamp(),\n })\n return json({ ok: true, order: staffView(orderId, after) })\n}\n\nexport { handler as posHardwareAdminOrders }\n"],"names":["pluginRequestFromWeb","emailUnverifiedResponse","firebaseAdmin","isImpersonationSession","addAdminAudit","invalidIdTokenResponse","isPosHardwareOrderStatus","nextPosHardwareStatus","POS_HARDWARE_ORDER_ID","POS_HARDWARE_ORDERS_COLLECTION","POS_HARDWARE_STATUS_STAMP","posHardwareRefundable","posHardwareSaleRecord","fulfillmentTrackingUrl","hardwareOrdersRef","posHardwareOrderNumber","posHardwareSaleRef","sendPosHardwareEmail","posStripe","PAGE","CURSOR","WRITE_ROLES","json","body","status","Response","headers","staffView","id","order","number","orgId","hostId","contactEmail","lines","subtotalCents","shipping","taxCents","totalCents","stripeCheckoutSessionId","stripePaymentIntentId","stripeHardwareOrderId","tracking","livemode","refundPending","Boolean","refundRequestedAtMs","createdAtMs","updatedAtMs","Refusal","Error","message","trackingFrom","raw","undefined","carrier","String","trim","slice","url","trackingNumber","trackingUrl","handler","request","method","query","rawHeaders","authorization","idToken","startsWith","length","error","decoded","input","app","auth","verifyIdToken","email_verified","role","firestore","shown","requested","ordersQuery","collectionGroup","where","orderBy","after","test","cursor","doc","get","exists","startAfter","snapshot","limit","docs","orders","map","data","next","ref","path","pageSize","canWrite","includes","action","orderId","actor","actorUid","uid","actorEmail","email","updateOrder","refundOrder","unauthenticated","console","outcome","hardwareOrderIdRaw","advanceTo","runTransaction","transaction","before","now","Date","patch","reached","trackingAfter","update","set","scope","target","at","FieldValue","serverTimestamp","ok","refund","finalStatus","claim","already","params","payment_intent","idempotencyKey","delete","catch","code","refundId","refundedCents","Number","amount","settled","posHardwareAdminOrders"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/server/pos-hardware-admin.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { pluginRequestFromWeb } from '@aglyn/aglyn/server'\nimport {\n emailUnverifiedResponse,\n firebaseAdmin,\n isImpersonationSession,\n} from '@aglyn/tenant-data-admin'\nimport { addAdminAudit } from '@aglyn/tenant-data-admin/server/admin-audit-write'\nimport { invalidIdTokenResponse } from '@aglyn/tenant-data-admin/server/id-token-refusal'\nimport {\n isPosHardwareOrderStatus,\n nextPosHardwareStatus,\n POS_HARDWARE_ORDER_ID,\n POS_HARDWARE_ORDERS_COLLECTION,\n POS_HARDWARE_STATUS_STAMP,\n posHardwareBuyerErasedPatch,\n posHardwareOrderSource,\n posHardwareSaleRecord,\n posHardwareSaleSetOptions,\n type PosHardwareOrder,\n type PosHardwareOrderStatus,\n type PosHardwareTracking,\n} from '../model/pos-hardware'\nimport { fulfillmentTrackingUrl } from '../model/tracking-url'\nimport {\n hardwareOrdersRef,\n posHardwareInPersonConfig,\n posHardwareOrderNumber,\n posHardwareSaleRef,\n} from './pos-hardware'\nimport { cancelAndRefundPosHardwareOrder } from './pos-hardware-cancel'\nimport { sendPosHardwareEmail, sendPosHardwareEmailOnce } from './pos-hardware-notify'\n\n/*==========================================\n * `/api/commerce/admin/hardware-orders` (AGL-4038): the staff end of the POS\n * hardware shop, for the Hardware orders staff page.\n *\n * GET every workspace's orders, newest first, optionally one status,\n * or `?attach=pending`: the in-person sales nobody has said whose\n * they are yet (AGL-4038), after recording any paid sale on the\n * seller store still waiting to be recorded\n * POST update record Stripe's order id and the tracking, or move the\n * order one step on (Ordered → Shipped → Delivered →\n * Registered); Shipped needs a tracking number\n * cancel cancel and refund in full, before it ships\n * refund refund in full, before it ships\n * refund an order sold in person (AGL-4038): what is left of it,\n * through the register sale's own card refund on the\n * selling store's account (`pos-hardware-returns.ts`)\n * Each of the three takes `notifyBuyer`, the dialog's \"Email the\n * buyer\" (AGL-4038): true sends the buyer the canceled-and-refunded\n * email (online) or the refunded email (in person), once, under the\n * same claim a closure sends it under; false sends nothing. Absent\n * reads as the dialog's default, true. It is in the audit row.\n * decline-return decline a buyer's open return request, with a note\n * forget-buyer take the buyer's address and account off an order\n * sold in person (AGL-4038), for a privacy request from\n * someone who never made an account\n *\n * Staff only. Reading is open to every staff role; every write is `super` or\n * `billing`, because each one changes what a customer is told or returns\n * their money. Every write is an `adminAudit` row, and each one rewrites the\n * order's retained sale record (`posHardwareSales/{orderId}`) from the order\n * as it now stands, in the same transaction.\n *=========================================*/\n\n/** One page of the staff list. */\nconst PAGE = 25\n/** A page cursor is the path of the last order the previous page showed. */\nconst CURSOR = /^orgs\\/[^/]+\\/hardwareOrders\\/[^/]+$/\nconst WRITE_ROLES = ['super', 'billing']\n\nconst json = (body: unknown, status = 200) =>\n Response.json(body, { status, headers: { 'Cache-Control': 'no-store' } })\n\n/** An order as the staff page lists it. */\nfunction staffView(id: string, order: PosHardwareOrder) {\n return {\n id,\n number: posHardwareOrderNumber(id),\n orgId: order.orgId,\n hostId: order.hostId,\n status: order.status,\n contactEmail: order.contactEmail ?? null,\n lines: order.lines ?? [],\n subtotalCents: order.subtotalCents ?? 0,\n shipping: order.shipping ?? null,\n taxCents: order.taxCents ?? 0,\n totalCents: order.totalCents ?? 0,\n stripeCheckoutSessionId: order.stripeCheckoutSessionId ?? null,\n stripePaymentIntentId: order.stripePaymentIntentId ?? null,\n stripeHardwareOrderId: order.stripeHardwareOrderId ?? null,\n tracking: order.tracking ?? null,\n livemode: order.livemode === true,\n refundPending: Boolean((order as { refundRequestedAtMs?: number }).refundRequestedAtMs),\n createdAtMs: order.createdAtMs ?? 0,\n updatedAtMs: order.updatedAtMs ?? 0,\n // Sold in person at the platform's own store (AGL-4038): where, how it\n // was paid and into which account, and whose it is.\n source: posHardwareOrderSource(order),\n discountCents: order.discountCents ?? 0,\n posSale: order.posSale ?? null,\n paidTo: order.paidTo ?? null,\n attachment: order.attachment ?? null,\n units: order.units ?? [],\n refundedCents: order.refundedCents ?? 0,\n refunds: order.refunds ?? [],\n returnRequest: order.returnRequest ?? null,\n }\n}\n\nexport type StaffHardwareOrderView = ReturnType<typeof staffView>\n\nclass Refusal extends Error {\n constructor(\n message: string,\n readonly status: number,\n ) {\n super(message)\n }\n}\n\n/** A tracking entry from the request, or `undefined` when none was sent. */\nfunction trackingFrom(raw: unknown): PosHardwareTracking | null | undefined {\n if (raw === undefined) return undefined\n if (raw === null) return null\n const carrier = String((raw as { carrier?: unknown })?.carrier ?? '').trim().slice(0, 60)\n const number = String((raw as { number?: unknown })?.number ?? '').trim().slice(0, 80)\n const url = String((raw as { url?: unknown })?.url ?? '').trim().slice(0, 500)\n if (!carrier || !number) throw new Refusal('Enter the carrier and the tracking number.', 400)\n return {\n carrier,\n number,\n // An https link typed by staff wins; otherwise one is built for a known\n // carrier, and an unknown one has none.\n url: fulfillmentTrackingUrl({ carrier, trackingNumber: number, trackingUrl: url || null }),\n }\n}\n\nasync function handler(request: Request): Promise<Response> {\n const { method, query, body, headers: rawHeaders } = await pluginRequestFromWeb(request)\n const headers = rawHeaders as Partial<Record<string, string>>\n const authorization = headers.authorization ?? ''\n const idToken = authorization.startsWith('Bearer ') ? authorization.slice('Bearer '.length) : undefined\n if (!idToken) return json({ error: 'Unauthenticated' }, 401)\n\n try {\n const decoded = await firebaseAdmin.app().auth().verifyIdToken(idToken)\n if (!decoded.email_verified && !isImpersonationSession(decoded)) return emailUnverifiedResponse()\n if (!decoded['staff']) return json({ error: 'Staff only' }, 403)\n // A missing role claim reads as the least one, never as super.\n const role = String(decoded['staffRole'] ?? 'support')\n const firestore = firebaseAdmin.app().firestore()\n\n if (method === 'GET') {\n const requested = String(query?.['status'] ?? '')\n const attach = String(query?.['attach'] ?? '')\n if (attach && attach !== 'pending') return json({ error: 'Unknown filter' }, 400)\n const returns = String(query?.['returns'] ?? '')\n if (returns && returns !== 'requested') return json({ error: 'Unknown filter' }, 400)\n let ordersQuery: any = firestore.collectionGroup(POS_HARDWARE_ORDERS_COLLECTION)\n if (returns === 'requested') {\n // Buyers' open return requests (AGL-4038), oldest waiting first in the\n // newest-first list like every other filter.\n ordersQuery = ordersQuery.where('returnRequest.state', '==', 'requested')\n } else if (attach === 'pending') {\n // A sale whose recording was missed is recorded before the list is read.\n const config = posHardwareInPersonConfig()\n if (config) await (await import('./pos-hardware-in-person')).sweepInPersonPosHardwareSales(config)\n ordersQuery = ordersQuery.where('attachment.state', '==', 'pending')\n } else if (requested) {\n if (!isPosHardwareOrderStatus(requested)) return json({ error: 'Unknown status' }, 400)\n ordersQuery = ordersQuery.where('status', '==', requested)\n }\n ordersQuery = ordersQuery.orderBy('createdAtMs', 'desc')\n const after = String(query?.['after'] ?? '')\n if (after) {\n if (!CURSOR.test(after)) return json({ error: 'Unknown page' }, 400)\n const cursor = await firestore.doc(after).get()\n // An order deleted since the page was read starts the list over\n // rather than answering an empty page.\n if (cursor.exists) ordersQuery = ordersQuery.startAfter(cursor)\n }\n const snapshot = await ordersQuery.limit(PAGE + 1).get()\n const docs = snapshot.docs as Array<{ id: string; ref: { path: string }; data: () => PosHardwareOrder }>\n const shown = docs.slice(0, PAGE)\n return json({\n orders: shown.map((doc) => staffView(doc.id, doc.data())),\n next: docs.length > PAGE ? (shown[shown.length - 1]?.ref.path ?? null) : null,\n pageSize: PAGE,\n canWrite: WRITE_ROLES.includes(role),\n })\n }\n\n if (method !== 'POST') return json({ error: 'Method not allowed' }, 405)\n if (!WRITE_ROLES.includes(role)) {\n return json({ error: 'Changing a hardware order requires the super or billing staff role.' }, 403)\n }\n const input = (body ?? {}) as Record<string, unknown>\n const action = String(input['action'] ?? '')\n const orgId = String(input['orgId'] ?? '')\n const orderId = String(input['orderId'] ?? '')\n if (!orgId || !/^[A-Za-z0-9_-]{1,128}$/.test(orgId) || !POS_HARDWARE_ORDER_ID.test(orderId)) {\n return json({ error: 'orgId or orderId is missing or malformed' }, 400)\n }\n const ref = hardwareOrdersRef(orgId).doc(orderId)\n const actor = { actorUid: decoded.uid, actorEmail: decoded.email ? String(decoded.email) : null }\n // \"Email the buyer\" (AGL-4038): explicit when sent, the dialog's default when not.\n const notifyRaw = input['notifyBuyer']\n if (notifyRaw !== undefined && typeof notifyRaw !== 'boolean') {\n return json({ error: 'notifyBuyer must be true or false' }, 400)\n }\n const notifyBuyer = notifyRaw !== false\n\n if (action === 'update') return await updateOrder(firestore, ref, orgId, orderId, input, actor)\n if (action === 'forget-buyer') return await forgetBuyer(firestore, ref, orgId, orderId, actor)\n if (action === 'decline-return') return await inPersonReturn(firestore, orgId, orderId, action, input, actor)\n if (action === 'refund-return') return await onlineReturnRefund(firestore, orgId, orderId, input, actor, notifyBuyer)\n // Handed over at the sale, an in-person order is never canceled: either\n // button refunds it, its own way.\n if ((action === 'refund' || action === 'cancel') && (await soldInPerson(ref))) {\n return await inPersonReturn(firestore, orgId, orderId, 'refund', input, actor, notifyBuyer)\n }\n if (action === 'cancel' || action === 'refund') {\n return await refundOrder(firestore, orgId, orderId, action, actor, notifyBuyer)\n }\n return json({ error: 'Unknown action' }, 400)\n } catch (error) {\n if (error instanceof Refusal) return json({ error: error.message }, error.status)\n const unauthenticated = invalidIdTokenResponse(error)\n if (unauthenticated) return unauthenticated\n console.error('[pos-hardware-admin]', error)\n return json({ error: 'Hardware orders failed' }, 500)\n }\n}\n\ntype Actor = { actorUid: string; actorEmail: string | null }\n\nasync function updateOrder(\n firestore: any,\n ref: any,\n orgId: string,\n orderId: string,\n input: Record<string, unknown>,\n actor: Actor,\n): Promise<Response> {\n const tracking = trackingFrom(input['tracking'])\n const hardwareOrderIdRaw = input['stripeHardwareOrderId']\n const stripeHardwareOrderId =\n hardwareOrderIdRaw === undefined ? undefined : String(hardwareOrderIdRaw ?? '').trim().slice(0, 120) || null\n const advanceTo = input['status'] === undefined ? undefined : String(input['status'])\n if (advanceTo !== undefined && !isPosHardwareOrderStatus(advanceTo)) {\n return json({ error: 'Unknown status' }, 400)\n }\n\n const outcome = await firestore.runTransaction(async (transaction: any) => {\n const snapshot = await transaction.get(ref)\n if (!snapshot.exists) throw new Refusal('No such order', 404)\n const before = snapshot.data() as PosHardwareOrder & { refundRequestedAtMs?: number }\n if (before.status === 'canceled' || before.status === 'refunded') {\n throw new Refusal('This order was canceled or refunded and can no longer change.', 409)\n }\n const now = Date.now()\n const patch: Record<string, unknown> = { updatedAtMs: now }\n if (stripeHardwareOrderId !== undefined) patch['stripeHardwareOrderId'] = stripeHardwareOrderId\n if (tracking !== undefined) patch['tracking'] = tracking\n let reached: PosHardwareOrderStatus | null = null\n if (advanceTo !== undefined && advanceTo !== before.status) {\n if (nextPosHardwareStatus(before.status) !== advanceTo) {\n throw new Refusal(`An order that is ${before.status} cannot move to ${advanceTo}.`, 409)\n }\n if (before.refundRequestedAtMs) throw new Refusal('A refund is in progress for this order.', 409)\n const trackingAfter = tracking !== undefined ? tracking : before.tracking\n if (advanceTo === 'shipped' && !trackingAfter?.number) {\n throw new Refusal('Add the tracking number before marking the order shipped.', 400)\n }\n patch['status'] = advanceTo\n patch[POS_HARDWARE_STATUS_STAMP[advanceTo]] = now\n reached = advanceTo\n }\n const after = { ...before, ...patch } as PosHardwareOrder\n transaction.update(ref, patch)\n transaction.set(posHardwareSaleRef(orderId), posHardwareSaleRecord(orderId, after), posHardwareSaleSetOptions(after))\n return { before, after, reached }\n })\n\n await addAdminAudit(firestore, {\n action: 'pos-hardware-order-update',\n ...actor,\n scope: 'posHardwareOrder',\n target: `orgs/${orgId}/${POS_HARDWARE_ORDERS_COLLECTION}/${orderId}`,\n orgId,\n before: {\n status: outcome.before.status,\n stripeHardwareOrderId: outcome.before.stripeHardwareOrderId ?? null,\n tracking: outcome.before.tracking ?? null,\n },\n after: {\n status: outcome.after.status,\n stripeHardwareOrderId: outcome.after.stripeHardwareOrderId ?? null,\n tracking: outcome.after.tracking ?? null,\n },\n at: firebaseAdmin.firestore.FieldValue.serverTimestamp(),\n })\n // Told once per step: the transaction above lets only one caller reach it.\n if (outcome.reached === 'shipped') await sendPosHardwareEmail('shipped', orderId, outcome.after)\n if (outcome.reached === 'delivered') await sendPosHardwareEmail('delivered', orderId, outcome.after)\n return json({ ok: true, order: staffView(orderId, outcome.after) })\n}\n\n/** Whether an order was sold in person (AGL-4038), which refunds its own way. */\nasync function soldInPerson(ref: any): Promise<boolean> {\n const snapshot = await ref.get()\n return snapshot.exists && posHardwareOrderSource(snapshot.data()) === 'in_person'\n}\n\n/**\n * A refund or a declined return of an order sold in person (AGL-4038): the\n * refund goes back through the register sale's own card refund on the\n * selling store's account, never the platform's Checkout.\n */\nasync function inPersonReturn(\n firestore: any,\n orgId: string,\n orderId: string,\n action: 'refund' | 'decline-return',\n input: Record<string, unknown>,\n actor: Actor,\n notifyBuyer = false,\n): Promise<Response> {\n const returns = await import('./pos-hardware-returns')\n try {\n const outcome =\n action === 'refund'\n ? await returns.refundInPersonPosHardwareOrder({\n config: posHardwareInPersonConfig(),\n orgId,\n orderId,\n actorUid: actor.actorUid,\n })\n : await returns.declinePosHardwareReturn({ orgId, orderId, actorUid: actor.actorUid, note: input['note'] })\n // The refund just made, told once by its own key, when staff chose to.\n const made = action === 'refund' ? (outcome.order.refunds ?? []).slice(-1)[0] : undefined\n const buyerEmail =\n action !== 'refund'\n ? undefined\n : !notifyBuyer\n ? 'off'\n : made\n ? await sendPosHardwareEmailOnce('refunded', orderId, outcome.order, `refunded:${made.key}`)\n : 'skipped'\n await addAdminAudit(firestore, {\n action: action === 'refund' ? 'pos-hardware-order-refund' : 'pos-hardware-return-decline',\n ...actor,\n scope: 'posHardwareOrder',\n target: `orgs/${orgId}/${POS_HARDWARE_ORDERS_COLLECTION}/${orderId}`,\n orgId,\n before: { status: outcome.before.status, refundedCents: outcome.before.refundedCents ?? 0 },\n after: {\n status: outcome.order.status,\n refundedCents: outcome.order.refundedCents ?? 0,\n returnRequest: outcome.order.returnRequest?.state ?? null,\n ...(action === 'refund' ? { notifyBuyer, buyerEmail } : {}),\n },\n at: firebaseAdmin.firestore.FieldValue.serverTimestamp(),\n })\n return json({ ok: true, order: staffView(orderId, outcome.order), ...(buyerEmail ? { buyerEmail } : {}) })\n } catch (error) {\n if (error instanceof returns.PosHardwareReturnRefusal) throw new Refusal(error.message, error.status)\n throw error\n }\n}\n\n/**\n * Refunds an ONLINE order the buyer sent back (AGL-4038), once its return\n * was requested: the items and their tax, less any restocking fee Stripe\n * charged, to the card it was paid with. The buyer is emailed once by the\n * refund's key, when staff chose to.\n */\nasync function onlineReturnRefund(\n firestore: any,\n orgId: string,\n orderId: string,\n input: Record<string, unknown>,\n actor: Actor,\n notifyBuyer: boolean,\n): Promise<Response> {\n const returns = await import('./pos-hardware-returns')\n try {\n const outcome = await returns.refundReturnedOnlinePosHardwareOrder({\n orgId,\n orderId,\n actorUid: actor.actorUid,\n restockingFeeCents: input['restockingFeeCents'],\n })\n const made = (outcome.order.refunds ?? []).slice(-1)[0]\n const buyerEmail = !notifyBuyer\n ? 'off'\n : made\n ? await sendPosHardwareEmailOnce('returnRefunded', orderId, outcome.order, `refunded:${made.key}`)\n : 'skipped'\n await addAdminAudit(firestore, {\n action: 'pos-hardware-return-refund',\n ...actor,\n scope: 'posHardwareOrder',\n target: `orgs/${orgId}/${POS_HARDWARE_ORDERS_COLLECTION}/${orderId}`,\n orgId,\n before: { status: outcome.before.status, refundedCents: outcome.before.refundedCents ?? 0 },\n after: {\n status: outcome.order.status,\n refundedCents: outcome.order.refundedCents ?? 0,\n refundId: made?.stripeRefundId ?? null,\n returnRequest: outcome.order.returnRequest?.state ?? null,\n notifyBuyer,\n buyerEmail,\n },\n at: firebaseAdmin.firestore.FieldValue.serverTimestamp(),\n })\n return json({ ok: true, order: staffView(orderId, outcome.order), buyerEmail })\n } catch (error) {\n if (error instanceof returns.PosHardwareReturnRefusal) throw new Refusal(error.message, error.status)\n throw error\n }\n}\n\n/**\n * Takes the buyer off an order sold in person (AGL-4038): the same patch an\n * account erasure applies, for a buyer an erasure cannot reach because they\n * have no account. The order, its amounts and the store's tax region stay.\n */\nasync function forgetBuyer(firestore: any, ref: any, orgId: string, orderId: string, actor: Actor): Promise<Response> {\n const after = await firestore.runTransaction(async (transaction: any) => {\n const snapshot = await transaction.get(ref)\n if (!snapshot.exists) throw new Refusal('No such order', 404)\n const before = snapshot.data() as PosHardwareOrder\n if (posHardwareOrderSource(before) !== 'in_person') {\n throw new Refusal('Only an order sold in person has a buyer to remove here.', 409)\n }\n const patch = posHardwareBuyerErasedPatch(before, Date.now())\n const next = { ...before, ...patch } as PosHardwareOrder\n transaction.update(ref, patch)\n transaction.set(posHardwareSaleRef(orderId), posHardwareSaleRecord(orderId, next), posHardwareSaleSetOptions(next))\n return next\n })\n await addAdminAudit(firestore, {\n action: 'pos-hardware-order-forget-buyer',\n ...actor,\n scope: 'posHardwareOrder',\n target: `orgs/${orgId}/${POS_HARDWARE_ORDERS_COLLECTION}/${orderId}`,\n orgId,\n before: null,\n after: { buyerErasedAtMs: after.buyerErasedAtMs ?? null },\n at: firebaseAdmin.firestore.FieldValue.serverTimestamp(),\n })\n return json({ ok: true, order: staffView(orderId, after) })\n}\n\nasync function refundOrder(\n firestore: any,\n orgId: string,\n orderId: string,\n action: 'cancel' | 'refund',\n actor: Actor,\n notifyBuyer: boolean,\n): Promise<Response> {\n const finalStatus = action === 'cancel' ? 'canceled' : 'refunded'\n // The one cancel-and-refund path (`pos-hardware-cancel.ts`), which a\n // workspace or account closure takes too: claimed under the lock, refunded\n // once under one key, settled with the sale record.\n const result = await cancelAndRefundPosHardwareOrder({ orgId, orderId, finalStatus, reason: 'staff' })\n switch (result.outcome) {\n case 'missing':\n throw new Refusal('No such order', 404)\n case 'already': {\n // Pressed again — after a closure, or after an email that failed: the\n // buyer is told now if they never were, and never twice.\n const buyerEmail = notifyBuyer ? await sendPosHardwareEmailOnce('canceled', orderId, result.order) : 'off'\n return json({ ok: true, order: staffView(orderId, result.order), buyerEmail })\n }\n case 'not-refundable':\n throw new Refusal(\n 'This order has shipped, so it can no longer be canceled or refunded here. Arrange a return with Stripe instead.',\n 409,\n )\n case 'no-payment':\n throw new Refusal('This order has no payment to refund.', 409)\n case 'refused':\n return json({ error: result.message }, 502)\n }\n // Canceled or refunded, it will not ship: the one canceled-and-refunded\n // email, once, under the claim a closure sends it under (AGL-4038).\n const buyerEmail = notifyBuyer ? await sendPosHardwareEmailOnce('canceled', orderId, result.order) : 'off'\n await addAdminAudit(firestore, {\n action: `pos-hardware-order-${action}`,\n ...actor,\n scope: 'posHardwareOrder',\n target: `orgs/${orgId}/${POS_HARDWARE_ORDERS_COLLECTION}/${orderId}`,\n orgId,\n before: { status: result.before.status },\n after: {\n status: finalStatus,\n refundId: result.order.refundId,\n refundedCents: result.order.refundedCents,\n notifyBuyer,\n buyerEmail,\n },\n at: firebaseAdmin.firestore.FieldValue.serverTimestamp(),\n })\n return json({ ok: true, order: staffView(orderId, result.order), buyerEmail })\n}\n\nexport { handler as posHardwareAdminOrders }\n"],"names":["pluginRequestFromWeb","emailUnverifiedResponse","firebaseAdmin","isImpersonationSession","addAdminAudit","invalidIdTokenResponse","isPosHardwareOrderStatus","nextPosHardwareStatus","POS_HARDWARE_ORDER_ID","POS_HARDWARE_ORDERS_COLLECTION","POS_HARDWARE_STATUS_STAMP","posHardwareBuyerErasedPatch","posHardwareOrderSource","posHardwareSaleRecord","posHardwareSaleSetOptions","fulfillmentTrackingUrl","hardwareOrdersRef","posHardwareInPersonConfig","posHardwareOrderNumber","posHardwareSaleRef","cancelAndRefundPosHardwareOrder","sendPosHardwareEmail","sendPosHardwareEmailOnce","PAGE","CURSOR","WRITE_ROLES","json","body","status","Response","headers","staffView","id","order","number","orgId","hostId","contactEmail","lines","subtotalCents","shipping","taxCents","totalCents","stripeCheckoutSessionId","stripePaymentIntentId","stripeHardwareOrderId","tracking","livemode","refundPending","Boolean","refundRequestedAtMs","createdAtMs","updatedAtMs","source","discountCents","posSale","paidTo","attachment","units","refundedCents","refunds","returnRequest","Refusal","Error","message","trackingFrom","raw","undefined","carrier","String","trim","slice","url","trackingNumber","trackingUrl","handler","request","method","query","rawHeaders","authorization","idToken","startsWith","length","error","decoded","input","app","auth","verifyIdToken","email_verified","role","firestore","shown","requested","attach","returns","ordersQuery","collectionGroup","where","config","sweepInPersonPosHardwareSales","orderBy","after","test","cursor","doc","get","exists","startAfter","snapshot","limit","docs","orders","map","data","next","ref","path","pageSize","canWrite","includes","action","orderId","actor","actorUid","uid","actorEmail","email","notifyRaw","notifyBuyer","updateOrder","forgetBuyer","inPersonReturn","onlineReturnRefund","soldInPerson","refundOrder","unauthenticated","console","outcome","hardwareOrderIdRaw","advanceTo","runTransaction","transaction","before","now","Date","patch","reached","trackingAfter","update","set","scope","target","at","FieldValue","serverTimestamp","ok","refundInPersonPosHardwareOrder","declinePosHardwareReturn","note","made","buyerEmail","key","state","PosHardwareReturnRefusal","refundReturnedOnlinePosHardwareOrder","restockingFeeCents","refundId","stripeRefundId","buyerErasedAtMs","finalStatus","result","reason","posHardwareAdminOrders"],"mappings":"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"}
|