@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/server/tax-return-source.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\n/**\n * Storefront sales on the operator's sales tax return (AGL-1904, AGL-3080).\n *\n * The operator's return sums its own invoices; this is the storefront's half\n * of it, answered through the platform's tax return source contract\n * (`@aglyn/aglyn/plugin-manager/plugin-tax-return-sources`). It reads\n * `storefrontTaxCollected` — a SEPARATE collection from the operator's own\n * invoices, queried and reported separately, because a storefront row's\n * money is mostly the merchant's while an invoice row's is the operator's.\n * Summing the two would put other companies' receipts into the return's\n * total sales, which is why they never meet in one query and never share a\n * figure.\n *\n * What it answers, all worded for the filing jurisdiction the platform\n * resolved:\n *\n * - **The three liability buckets**, never summed — see\n * `model/storefront-tax-summary.ts`.\n * - **A blocking finding for the platform-liable tax** in the filing\n * jurisdiction. Every storefront checkout is created on the platform's\n * own account, so a `mode: 'stripe'` store's shopper is charged tax Stripe\n * computes against the PLATFORM's registrations — measured, not inferred.\n * That money is in the platform's balance and is NOT in the filing\n * figures, which sum the operator's own sales only. Filing those without\n * deciding what to do with this figure is exactly the shortfall an\n * auditor finds. It states the mechanics and asks for a decision; it does\n * NOT assert a marketplace-facilitator position — that attaches by\n * operation of law and belongs to counsel, not to this report.\n * - **Two lines beneath the filing figures** — the platform-liable tax and\n * the merchant's own rate, stated side by side and never folded into a\n * form item, because this report does not decide how storefront receipts\n * are reported and adding them to one would be deciding it silently.\n * - **Facilitated sales by buyer state** — the economic-nexus question\n * (AGL-1956), with the three buckets SUMMED per jurisdiction on purpose:\n * a threshold counts the sale whoever remits it. Who remits is still\n * carried per row.\n *\n * Truncation and rows no period can reach are reported, and the platform\n * raises each as a blocking finding of its own.\n */\n\nimport { firebaseAdmin } from '@aglyn/tenant-data-admin'\nimport { PLATFORM_BRAND_NAME } from '@aglyn/aglyn/app-utils/platform-brand'\nimport {\n asRowDate,\n centsToDollars,\n} from '@aglyn/aglyn/app-utils/tax-jurisdiction-figures'\nimport type {\n TaxReturnExportBlock,\n TaxReturnFiling,\n TaxReturnFilingLine,\n TaxReturnFinding,\n TaxReturnSectionTable,\n TaxReturnSource,\n TaxReturnSourceAnswer,\n TaxReturnSourceRequest,\n} from '@aglyn/aglyn/plugin-manager/plugin-tax-return-sources'\nimport {\n storefrontTaxSummary,\n type StorefrontTaxReturnRowInput,\n type StorefrontTaxSummary,\n} from '../model/storefront-tax-summary'\n\n/** One row of the storefront listing, as the working papers carry it. */\nexport interface StorefrontTaxRow {\n id: string\n hostId: string | null\n orgId: string | null\n paidAt: string | null\n taxMode: string | null\n taxLiability: string | null\n grossCents: number\n taxCents: number\n taxableSalesCents: number\n state: string | null\n country: string | null\n}\n\n/** A liability bucket, ready to print. */\nexport interface StorefrontTaxBucketRow {\n id: 'aglynLiable' | 'merchantManual' | 'connectedAccountLiable'\n label: string\n /** Who owes it — the sentence that decides whether it is on this return. */\n liability: string\n transactionCount: number\n grossDollars: string\n taxableSalesDollars: string\n taxCollectedDollars: string\n /** True when this row is money in the platform's balance under its registration. */\n platformLiable: boolean\n}\n\n/** One state's facilitated storefront sales, for the nexus question. */\nexport interface StorefrontFacilitatedJurisdictionRow {\n jurisdiction: string\n /** True for the one jurisdiction this deployment files a return in. */\n isFilingJurisdiction: boolean\n transactionCount: number\n totalSalesDollars: string\n taxCollectedDollars: string\n /** The part of `taxCollectedDollars` the platform holds and must remit. */\n platformLiableTaxDollars: string\n /** True when NO tax was collected on any sale into this state. */\n untaxed: boolean\n}\n\n/**\n * Storefront tax in the FILING jurisdiction that Stripe computed against the\n * platform's own registrations.\n *\n * The one figure that decides whether a period can be filed from the filing\n * lines alone. Deliberately excludes `merchantManual` — a merchant's own\n * configured rate never touched those registrations. Read against the\n * configured jurisdiction rather than Texas, because a hard-coded key answers\n * `0.00` everywhere else — and a zero here reads as \"nothing to decide\" on\n * the one finding that blocks filing.\n */\nexport function storefrontPlatformLiableCents(\n summary: StorefrontTaxSummary | null | undefined,\n filing: TaxReturnFiling,\n): number {\n const figures = summary?.aglynLiable?.byJurisdiction?.[filing.code]\n const cents = Number(figures?.taxCollectedCents ?? 0)\n return Number.isFinite(cents) ? cents : 0\n}\n\n/** The merchant's own configured tax in the filing jurisdiction. */\nfunction merchantManualCents(\n summary: StorefrontTaxSummary | null | undefined,\n filing: TaxReturnFiling,\n): number {\n return Number(\n summary?.merchantManual?.byJurisdiction?.[filing.code]?.taxCollectedCents ?? 0,\n )\n}\n\n/** The storefront's findings. The platform raises the non-zero ones. */\nexport function storefrontTaxFindings(\n summary: StorefrontTaxSummary,\n filing: TaxReturnFiling,\n): TaxReturnFinding[] {\n const brand = PLATFORM_BRAND_NAME\n return [\n {\n // BLOCKING on purpose — see the module note.\n id: 'storefrontAglynLiableTax',\n severity: 'blocking',\n count: storefrontPlatformLiableCents(summary, filing),\n label: `${filing.label} storefront tax collected under ${brand}’s registration`,\n detail:\n 'Cents. Charged to shoppers on merchants’ storefront sales, computed ' +\n 'by Stripe Tax against THE PLATFORM’s registrations (the session is ' +\n 'created on the platform account), and settled into the platform’s ' +\n `balance. It is NOT included in ${filing.figuresName} below. Decide ` +\n 'with counsel how it is reported before filing — do not file as if ' +\n 'it were zero.',\n },\n {\n id: 'storefrontUnclassified',\n severity: 'blocking',\n count: Number(summary?.attention?.rowsUnclassified ?? 0),\n label: 'Storefront rows with an unrecognised tax mode',\n detail:\n 'Not counted in any storefront bucket, so they are in no figure at ' +\n 'all. Classify them before filing.',\n },\n {\n id: 'storefrontMissingTaxableBase',\n severity: 'review',\n count: Number(summary?.attention?.rowsMissingTaxableBase ?? 0),\n label: 'Storefront rows with tax but no stated base',\n detail:\n 'Tax was collected but Stripe’s taxable_amount could not be read, so ' +\n 'the storefront taxable-sales figure understates the base. Re-read ' +\n 'the session in Stripe with the tax breakdown expanded.',\n },\n ]\n}\n\n/**\n * The two lines beneath the filing figures: the platform-liable tax and the\n * merchant's own rate, separately, and outside every form item.\n */\nexport function storefrontFilingLines(\n summary: StorefrontTaxSummary,\n filing: TaxReturnFiling,\n): TaxReturnFilingLine[] {\n const brand = PLATFORM_BRAND_NAME\n const platformLiable = centsToDollars(storefrontPlatformLiableCents(summary, filing))\n const merchant = centsToDollars(merchantManualCents(summary, filing))\n if (filing.form === 'tx-webfile') {\n return [\n {\n item: '—',\n label: `${filing.label} storefront tax under ${brand}’s registration (NOT in ${filing.figuresName})`,\n dollars: platformLiable,\n note:\n `Collected from shoppers on merchants’ sales and held in ${brand}’s ` +\n 'balance. Excluded from every item above. Its treatment on the ' +\n 'return is a question for counsel — see AGL-1904.',\n },\n {\n item: '—',\n label: `${filing.label} storefront tax under the MERCHANT’s own rate (not ${brand}’s)`,\n dollars: merchant,\n note:\n `A manual-mode store’s own configured rate. ${brand}’s registrations ` +\n 'played no part in computing it. Shown so it is visibly NOT the line ' +\n 'above — the two must never be added together.',\n },\n ]\n }\n return [\n {\n item: '—',\n label: `${filing.code} storefront tax under the platform’s registration (NOT in the figures above)`,\n dollars: platformLiable,\n note:\n 'Collected from shoppers on merchants’ sales and held in the ' +\n 'platform’s balance. Excluded from every figure above. Its treatment ' +\n 'on the return is a question for the operator’s own counsel.',\n },\n {\n item: '—',\n label: `${filing.code} storefront tax under the MERCHANT’s own rate`,\n dollars: merchant,\n note:\n 'A manual-mode store’s own configured rate. The platform’s ' +\n 'registrations played no part in computing it. Shown so it is ' +\n 'visibly NOT the line above — the two must never be added together.',\n },\n ]\n}\n\n/** The three liability buckets, in the order a reader decides them. */\nexport function storefrontBucketRows(\n summary: StorefrontTaxSummary,\n): StorefrontTaxBucketRow[] {\n const brand = PLATFORM_BRAND_NAME\n const buckets: Array<{\n id: StorefrontTaxBucketRow['id']\n label: string\n liability: string\n platformLiable: boolean\n }> = [\n {\n id: 'aglynLiable',\n label: `Computed against ${brand}’s registrations`,\n liability: `In ${brand}’s balance. Stripe Tax computed it on ${brand}’s platform account.`,\n platformLiable: true,\n },\n {\n id: 'merchantManual',\n label: 'Merchant’s own configured rate',\n liability: `The merchant’s. It never touched an ${brand} registration and is not ${brand}’s to remit.`,\n platformLiable: false,\n },\n {\n id: 'connectedAccountLiable',\n label: 'Stripe Tax named the connected account liable',\n liability: 'The connected account’s. Empty today.',\n platformLiable: false,\n },\n ]\n return buckets.map((bucket) => {\n const figures = summary?.[bucket.id]\n return {\n id: bucket.id,\n label: bucket.label,\n liability: bucket.liability,\n transactionCount: Number(figures?.transactionCount ?? 0),\n grossDollars: centsToDollars(figures?.grossCents),\n taxableSalesDollars: centsToDollars(figures?.taxableSalesCents),\n taxCollectedDollars: centsToDollars(figures?.taxCollectedCents),\n platformLiable: bucket.platformLiable,\n }\n })\n}\n\n/**\n * FACILITATED SALES BY STATE — the economic-nexus question (AGL-1956).\n *\n * The question a state asks a marketplace facilitator is \"how much did you\n * facilitate INTO this state, and in how many transactions\" — not \"how much\n * tax did you collect there\". A state the operator is not registered in\n * collects nothing by definition, which is exactly why collection cannot be\n * the measure: the states worth watching are the ones showing $0 tax and a\n * rising sales figure.\n *\n * So this SUMS the three liability buckets per jurisdiction. The rule that\n * the operator's own invoices and storefront rows are never summed still\n * holds — nothing here touches the operator's own sales; within the\n * storefront collection the buckets differ only in WHO REMITS, and a nexus\n * threshold counts the sale whoever remits it. Who remits is still carried\n * per row, because \"do we have nexus here\" and \"what do we owe here\" are\n * answered off the same rows and must not blur.\n *\n * ⚠️ A LOWER BOUND, deliberately rather than silently: `storefront-tax-record.ts`\n * files no row at all for a sale whose `taxMode` resolves to `none`, so a\n * wholly untaxed storefront sale is invisible here — the population nexus\n * detection most needs. Closing it is a write-side change recorded on\n * AGL-1956. The filing jurisdiction does not depend on any of this: a filer\n * registered where it is established has no in-state threshold left to cross.\n */\nexport function storefrontFacilitatedJurisdictionRows(\n summary: StorefrontTaxSummary | null | undefined,\n filing: TaxReturnFiling,\n): StorefrontFacilitatedJurisdictionRow[] {\n if (!summary) return []\n const totals = new Map<\n string,\n { count: number; salesCents: number; taxCents: number; platformCents: number }\n >()\n const buckets: Array<[StorefrontTaxBucketRow['id'], boolean]> = [\n ['aglynLiable', true],\n ['merchantManual', false],\n ['connectedAccountLiable', false],\n ]\n for (const [id, platformLiable] of buckets) {\n const byJurisdiction = summary[id]?.byJurisdiction ?? {}\n for (const [jurisdiction, figures] of Object.entries(byJurisdiction)) {\n const entry = totals.get(jurisdiction) ?? {\n count: 0,\n salesCents: 0,\n taxCents: 0,\n platformCents: 0,\n }\n const taxCents = Number(figures?.taxCollectedCents ?? 0)\n entry.count += Number(figures?.transactionCount ?? 0)\n entry.salesCents += Number(figures?.totalSalesCents ?? 0)\n entry.taxCents += taxCents\n if (platformLiable) entry.platformCents += taxCents\n totals.set(jurisdiction, entry)\n }\n }\n return [...totals.entries()]\n .map(([jurisdiction, entry]) => ({\n jurisdiction,\n isFilingJurisdiction: jurisdiction === filing.code,\n transactionCount: entry.count,\n totalSalesDollars: centsToDollars(entry.salesCents),\n taxCollectedDollars: centsToDollars(entry.taxCents),\n platformLiableTaxDollars: centsToDollars(entry.platformCents),\n untaxed: entry.taxCents === 0,\n }))\n .sort(\n (a, b) =>\n // The filing jurisdiction first — it is the one obligation that does\n // not wait on a threshold — then by the figure a threshold is\n // actually measured against.\n Number(b.isFilingJurisdiction) - Number(a.isFilingJurisdiction) ||\n Number(b.totalSalesDollars) - Number(a.totalSalesDollars) ||\n a.jurisdiction.localeCompare(b.jurisdiction),\n )\n}\n\n/** The storefront's two tables on the return's screen. */\nfunction storefrontTables(\n summary: StorefrontTaxSummary,\n filing: TaxReturnFiling,\n): TaxReturnSectionTable[] {\n const brand = PLATFORM_BRAND_NAME\n return [\n {\n // Split by who owes it, never summed — one \"storefront tax\" total would\n // merge two facts into a number that is true of neither.\n columns: [\n { label: 'Bucket' },\n { label: 'Sales', numeric: true },\n { label: 'Gross', numeric: true, money: true },\n { label: 'Taxable sales', numeric: true, money: true },\n { label: 'Tax collected', numeric: true, money: true },\n ],\n rows: storefrontBucketRows(summary).map((row) => ({\n key: row.id,\n cells: [\n {\n text: row.label,\n caption: row.liability,\n ...(row.platformLiable\n ? { tag: { label: `${brand} holds this`, tone: 'attention' as const } }\n : {}),\n },\n { text: String(row.transactionCount) },\n { text: `$${row.grossDollars}` },\n { text: `$${row.taxableSalesDollars}` },\n { text: `$${row.taxCollectedDollars}`, strong: row.platformLiable },\n ],\n })),\n empty: 'This period’s response carries no storefront figures.',\n },\n {\n heading: 'Facilitated sales by buyer state',\n description:\n `What ${brand} facilitated into each state, whoever remits the ` +\n 'tax — the figure an economic-nexus threshold is measured ' +\n `against. ${filing.code} needs no threshold: the filer is ` +\n 'established there, so the obligation is unconditional. A ' +\n 'region showing sales and no tax is the one to watch.',\n columns: [\n { label: 'Buyer state' },\n { label: 'Sales', numeric: true },\n { label: 'Total sales', numeric: true, money: true },\n { label: 'Tax collected', numeric: true, money: true },\n { label: `Of which ${brand} owes`, numeric: true, money: true },\n ],\n rows: storefrontFacilitatedJurisdictionRows(summary, filing).map((row) => ({\n key: row.jurisdiction,\n cells: [\n {\n text: row.jurisdiction === 'unknown' ? 'Not stated' : row.jurisdiction,\n ...(row.isFilingJurisdiction\n ? { tag: { label: 'Registered', tone: 'attention' as const } }\n : row.untaxed\n ? { tag: { label: 'No tax collected', tone: 'neutral' as const } }\n : {}),\n },\n { text: String(row.transactionCount) },\n { text: `$${row.totalSalesDollars}` },\n { text: `$${row.taxCollectedDollars}` },\n {\n text: `$${row.platformLiableTaxDollars}`,\n strong: Number(row.platformLiableTaxDollars) > 0,\n },\n ],\n })),\n empty: 'No storefront sales recorded in this period.',\n footnote:\n 'A LOWER BOUND. A storefront sale that collected no tax at ' +\n 'all files no row, so it is missing here — which is exactly ' +\n 'the population a nexus check wants. Recorded on AGL-1956.',\n },\n ]\n}\n\n/**\n * The storefront's blocks of the working-papers export: the nexus figures\n * beside the operator's own sales by jurisdiction — a different taxpayer's\n * money and never summed with them — and the liability buckets after the\n * working papers.\n */\nfunction storefrontExports(\n summary: StorefrontTaxSummary,\n filing: TaxReturnFiling,\n): TaxReturnExportBlock[] {\n const brand = PLATFORM_BRAND_NAME\n const facilitated = storefrontFacilitatedJurisdictionRows(summary, filing)\n return [\n {\n placement: 'jurisdictions',\n rows: [\n ['Facilitated sales by buyer state (merchants’ storefronts)'],\n [\n 'Buyer state',\n 'Sales',\n 'Total sales (USD)',\n 'Tax collected (USD)',\n `Of which ${brand} owes (USD)`,\n ],\n ...(facilitated.length\n ? facilitated.map((row) => [\n row.jurisdiction,\n String(row.transactionCount),\n row.totalSalesDollars,\n row.taxCollectedDollars,\n row.platformLiableTaxDollars,\n ])\n : [['—', '0', '0.00', '0.00', '0.00']]),\n [\n 'LOWER BOUND — a storefront sale that collected no tax files no row, ' +\n `so it is absent here. ${filing.code} needs no threshold: the filer ` +\n 'is established there.',\n ],\n ],\n },\n {\n placement: 'sections',\n rows: [\n [\n 'Storefront commerce tax by liability (AGL-1904) — NOT in ' +\n (filing.form === 'tx-webfile' ? 'the Webfile figures' : 'the breakdown above'),\n ],\n [\n 'Bucket',\n 'Who owes it',\n 'Transactions',\n 'Gross (USD)',\n 'Taxable sales (USD)',\n 'Tax collected (USD)',\n ],\n ...storefrontBucketRows(summary).map((row) => [\n row.label,\n row.liability,\n String(row.transactionCount),\n row.grossDollars,\n row.taxableSalesDollars,\n row.taxCollectedDollars,\n ]),\n ],\n },\n ]\n}\n\n/** One storefront row as the working papers carry it. */\nfunction projectRow(row: StorefrontTaxReturnRowInput): StorefrontTaxRow {\n return {\n id: row.id,\n hostId: typeof row.hostId === 'string' ? row.hostId : null,\n orgId: row.orgId ?? null,\n paidAt: asRowDate(row.paidAt)?.toISOString() ?? null,\n taxMode: typeof row.taxMode === 'string' ? row.taxMode : null,\n taxLiability: typeof row.taxLiability === 'string' ? row.taxLiability : null,\n grossCents: Number(row.grossCents ?? 0),\n taxCents: Number(row.taxCents ?? 0),\n taxableSalesCents: (Array.isArray(row.taxLines) ? row.taxLines : [])\n .map((line) => Number(line?.taxableAmountCents ?? 0))\n .reduce((sum, base) => sum + (Number.isFinite(base) ? base : 0), 0),\n state: typeof row.customerAddress?.state === 'string' ? row.customerAddress.state : null,\n country:\n typeof row.customerAddress?.country === 'string' ? row.customerAddress.country : null,\n }\n}\n\n/**\n * The storefront's answer for one period, from rows already read. Pure, so\n * the section a preparer reads can be proved from fixtures.\n */\nexport function storefrontTaxReturnAnswer(\n read: {\n rows: readonly StorefrontTaxReturnRowInput[]\n truncated: boolean\n undatedRows: number\n },\n request: TaxReturnSourceRequest,\n): TaxReturnSourceAnswer {\n const brand = PLATFORM_BRAND_NAME\n const { filing } = request\n const summary = storefrontTaxSummary(read.rows, request)\n return {\n id: 'storefront',\n name: 'Storefront',\n title: 'Storefront commerce tax — merchants’ sales',\n help:\n 'Tax charged to shoppers on merchants’ storefronts, split by who owes it. None of it is in the filing figures above.',\n intro:\n `None of this is in the ${\n filing.form === 'tx-webfile' ? 'Webfile' : 'breakdown'\n } figures above, which sum ` +\n `${brand}’s OWN sales only. The first row is the one that ` +\n `needs a decision: those sessions are created on ${brand}’s ` +\n `platform account, so Stripe computed that tax against ` +\n `${brand}’s registrations and it settled into ${brand}’s balance.`,\n truncated: read.truncated,\n undatedRows: read.undatedRows,\n findings: storefrontTaxFindings(summary, filing),\n filingLines: storefrontFilingLines(summary, filing),\n tables: storefrontTables(summary, filing),\n figures: [],\n exports: storefrontExports(summary, filing),\n summary,\n rows: read.rows.map(projectRow),\n }\n}\n\n/**\n * The storefront's source, registered on the console's API surface: the\n * staff return awaits that surface before it asks.\n *\n * Two queries, and the second is the honesty check: the period query ranges\n * on `paidAt`, and a Firestore range query CANNOT match a document whose\n * field is null — so a row that failed to date itself would be invisible to\n * every period. The equality probe counts those rows, over all of them, and\n * the platform blocks the return on any.\n */\nexport const commerceTaxReturnSource: TaxReturnSource = {\n async read(request) {\n const collection = firebaseAdmin.app().firestore().collection('storefrontTaxCollected')\n const [inPeriod, undated] = await Promise.all([\n collection\n .where('paidAt', '>=', request.start)\n .where('paidAt', '<', request.end)\n .limit(request.rowCap + 1)\n .get(),\n collection.where('paidAt', '==', null).count().get(),\n ])\n const rows: StorefrontTaxReturnRowInput[] = inPeriod.docs\n .slice(0, request.rowCap)\n .map((doc) => ({\n id: doc.id,\n ...(doc.data() as Omit<StorefrontTaxReturnRowInput, 'id'>),\n }))\n return storefrontTaxReturnAnswer(\n {\n rows,\n truncated: inPeriod.size > request.rowCap,\n undatedRows: Number(undated.data().count ?? 0),\n },\n request,\n )\n },\n}\n"],"names":["firebaseAdmin","PLATFORM_BRAND_NAME","asRowDate","centsToDollars","storefrontTaxSummary","storefrontPlatformLiableCents","summary","filing","figures","aglynLiable","byJurisdiction","code","cents","Number","taxCollectedCents","isFinite","merchantManualCents","merchantManual","storefrontTaxFindings","brand","id","severity","count","label","detail","figuresName","attention","rowsUnclassified","rowsMissingTaxableBase","storefrontFilingLines","platformLiable","merchant","form","item","dollars","note","storefrontBucketRows","buckets","liability","map","bucket","transactionCount","grossDollars","grossCents","taxableSalesDollars","taxableSalesCents","taxCollectedDollars","storefrontFacilitatedJurisdictionRows","totals","Map","jurisdiction","Object","entries","entry","get","salesCents","taxCents","platformCents","totalSalesCents","set","isFilingJurisdiction","totalSalesDollars","platformLiableTaxDollars","untaxed","sort","a","b","localeCompare","storefrontTables","columns","numeric","money","rows","row","key","cells","text","caption","tag","tone","String","strong","empty","heading","description","footnote","storefrontExports","facilitated","placement","length","projectRow","hostId","orgId","paidAt","toISOString","taxMode","taxLiability","Array","isArray","taxLines","line","taxableAmountCents","reduce","sum","base","state","customerAddress","country","storefrontTaxReturnAnswer","read","request","name","title","help","intro","truncated","undatedRows","findings","filingLines","tables","exports","commerceTaxReturnSource","undated","collection","app","firestore","inPeriod","Promise","all","where","start","end","limit","rowCap","docs","slice","doc","data","size"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/server/tax-return-source.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\n/**\n * Storefront sales on the operator's sales tax return (AGL-1904, AGL-3080).\n *\n * The operator's return sums its own invoices; this is the storefront's half\n * of it, answered through the platform's tax return source contract\n * (`@aglyn/aglyn/plugin-manager/plugin-tax-return-sources`). It reads\n * `storefrontTaxCollected` — a SEPARATE collection from the operator's own\n * invoices, queried and reported separately, because a storefront row's\n * money is mostly the merchant's while an invoice row's is the operator's.\n * Summing the two would put other companies' receipts into the return's\n * total sales, which is why they never meet in one query and never share a\n * figure.\n *\n * What it answers, all worded for the filing jurisdiction the platform\n * resolved:\n *\n * - **The three liability buckets**, never summed — see\n * `model/storefront-tax-summary.ts`.\n * - **A blocking finding for the platform-liable tax** in the filing\n * jurisdiction. Every storefront checkout is created on the platform's\n * own account, so a `mode: 'stripe'` store's shopper is charged tax Stripe\n * computes against the PLATFORM's registrations — measured, not inferred.\n * That money is in the platform's balance and is NOT in the filing\n * figures, which sum the operator's own sales only. Filing those without\n * deciding what to do with this figure is exactly the shortfall an\n * auditor finds. It states the mechanics and asks for a decision; it does\n * NOT assert a marketplace-facilitator position — that attaches by\n * operation of law and belongs to counsel, not to this report.\n * - **Two lines beneath the filing figures** — the platform-liable tax and\n * the merchant's own rate, stated side by side and never folded into a\n * form item, because this report does not decide how storefront receipts\n * are reported and adding them to one would be deciding it silently.\n * - **Facilitated sales by buyer state** — the economic-nexus question\n * (AGL-1956), with the three buckets SUMMED per jurisdiction on purpose:\n * a threshold counts the sale whoever remits it. Who remits is still\n * carried per row.\n *\n * Truncation and rows no period can reach are reported, and the platform\n * raises each as a blocking finding of its own.\n */\n\nimport { firebaseAdmin } from '@aglyn/tenant-data-admin'\nimport { PLATFORM_BRAND_NAME } from '@aglyn/aglyn/app-utils/platform-brand'\nimport {\n asRowDate,\n centsToDollars,\n} from '@aglyn/aglyn/app-utils/tax-jurisdiction-figures'\nimport type {\n TaxReturnExportBlock,\n TaxReturnFiling,\n TaxReturnFilingLine,\n TaxReturnFinding,\n TaxReturnSectionTable,\n TaxReturnSource,\n TaxReturnSourceAnswer,\n TaxReturnSourceRequest,\n} from '@aglyn/aglyn/plugin-manager/plugin-tax-return-sources'\nimport {\n storefrontTaxSummary,\n type StorefrontTaxReturnRowInput,\n type StorefrontTaxSummary,\n} from '../model/storefront-tax-summary'\nimport { readPosHardwareTaxReturn } from './pos-hardware-tax-return-source'\nimport { POS_HARDWARE_SALES_COLLECTION } from '../model/pos-hardware'\nimport {\n posHardwareStorefrontParts,\n storefrontRowsWithoutInPersonHardware,\n} from '../model/pos-hardware-tax-summary'\nimport { statedTaxableBase } from '../model/own-store-tax-summary'\nimport {\n ownStoreTaxReturnAnswer,\n readOwnStoreOrders,\n resolveOwnStores,\n type OwnStores,\n} from './own-store-tax-return-source'\n\n/**\n * How far either side of the period an in-person hardware record is read,\n * to meet the storefront row its register sale filed: the two are written\n * seconds apart, so a week is more than enough for either edge.\n */\nconst IN_PERSON_ROW_MARGIN_MS = 7 * 24 * 60 * 60 * 1000\n\n/** One row of the storefront listing, as the working papers carry it. */\nexport interface StorefrontTaxRow {\n id: string\n hostId: string | null\n orgId: string | null\n paidAt: string | null\n taxMode: string | null\n taxLiability: string | null\n grossCents: number\n taxCents: number\n taxableSalesCents: number\n state: string | null\n country: string | null\n}\n\n/** A liability bucket, ready to print. */\nexport interface StorefrontTaxBucketRow {\n id: 'aglynLiable' | 'merchantManual' | 'connectedAccountLiable'\n label: string\n /** Who owes it — the sentence that decides whether it is on this return. */\n liability: string\n transactionCount: number\n grossDollars: string\n taxableSalesDollars: string\n taxCollectedDollars: string\n /** True when this row is money in the platform's balance under its registration. */\n platformLiable: boolean\n}\n\n/** One state's facilitated storefront sales, for the nexus question. */\nexport interface StorefrontFacilitatedJurisdictionRow {\n jurisdiction: string\n /** True for the one jurisdiction this deployment files a return in. */\n isFilingJurisdiction: boolean\n transactionCount: number\n totalSalesDollars: string\n taxCollectedDollars: string\n /** The part of `taxCollectedDollars` the platform holds and must remit. */\n platformLiableTaxDollars: string\n /** True when NO tax was collected on any sale into this state. */\n untaxed: boolean\n}\n\n/**\n * Storefront tax in the FILING jurisdiction that Stripe computed against the\n * platform's own registrations.\n *\n * The one figure that decides whether a period can be filed from the filing\n * lines alone. Deliberately excludes `merchantManual` — a merchant's own\n * configured rate never touched those registrations. Read against the\n * configured jurisdiction rather than Texas, because a hard-coded key answers\n * `0.00` everywhere else — and a zero here reads as \"nothing to decide\" on\n * the one finding that blocks filing.\n */\nexport function storefrontPlatformLiableCents(\n summary: StorefrontTaxSummary | null | undefined,\n filing: TaxReturnFiling,\n): number {\n const figures = summary?.aglynLiable?.byJurisdiction?.[filing.code]\n const cents = Number(figures?.taxCollectedCents ?? 0)\n return Number.isFinite(cents) ? cents : 0\n}\n\n/** The merchant's own configured tax in the filing jurisdiction. */\nfunction merchantManualCents(\n summary: StorefrontTaxSummary | null | undefined,\n filing: TaxReturnFiling,\n): number {\n return Number(\n summary?.merchantManual?.byJurisdiction?.[filing.code]?.taxCollectedCents ?? 0,\n )\n}\n\n/** The storefront's findings. The platform raises the non-zero ones. */\nexport function storefrontTaxFindings(\n summary: StorefrontTaxSummary,\n filing: TaxReturnFiling,\n): TaxReturnFinding[] {\n const brand = PLATFORM_BRAND_NAME\n return [\n {\n // BLOCKING on purpose — see the module note.\n id: 'storefrontAglynLiableTax',\n severity: 'blocking',\n count: storefrontPlatformLiableCents(summary, filing),\n label: `${filing.label} storefront tax collected under ${brand}’s registration`,\n detail:\n 'Cents. Charged to shoppers on merchants’ storefront sales, computed ' +\n 'by Stripe Tax against THE PLATFORM’s registrations (the session is ' +\n 'created on the platform account), and settled into the platform’s ' +\n `balance. It is NOT included in ${filing.figuresName} below. Decide ` +\n 'with counsel how it is reported before filing — do not file as if ' +\n 'it were zero.',\n },\n {\n id: 'storefrontUnclassified',\n severity: 'blocking',\n count: Number(summary?.attention?.rowsUnclassified ?? 0),\n label: 'Storefront rows with an unrecognised tax mode',\n detail:\n 'Not counted in any storefront bucket, so they are in no figure at ' +\n 'all. Classify them before filing.',\n },\n {\n id: 'storefrontMissingTaxableBase',\n severity: 'review',\n count: Number(summary?.attention?.rowsMissingTaxableBase ?? 0),\n label: 'Storefront rows with tax but no stated base',\n detail:\n 'Tax was collected but Stripe’s taxable_amount could not be read, so ' +\n 'the storefront taxable-sales figure understates the base. Re-read ' +\n 'the session in Stripe with the tax breakdown expanded.',\n },\n ]\n}\n\n/**\n * The two lines beneath the filing figures: the platform-liable tax and the\n * merchant's own rate, separately, and outside every form item.\n */\nexport function storefrontFilingLines(\n summary: StorefrontTaxSummary,\n filing: TaxReturnFiling,\n): TaxReturnFilingLine[] {\n const brand = PLATFORM_BRAND_NAME\n const platformLiable = centsToDollars(storefrontPlatformLiableCents(summary, filing))\n const merchant = centsToDollars(merchantManualCents(summary, filing))\n if (filing.form === 'tx-webfile') {\n return [\n {\n item: '—',\n label: `${filing.label} storefront tax under ${brand}’s registration (NOT in ${filing.figuresName})`,\n dollars: platformLiable,\n note:\n `Collected from shoppers on merchants’ sales and held in ${brand}’s ` +\n 'balance. Excluded from every item above. Its treatment on the ' +\n 'return is a question for counsel — see AGL-1904.',\n },\n {\n item: '—',\n label: `${filing.label} storefront tax under the MERCHANT’s own rate (not ${brand}’s)`,\n dollars: merchant,\n note:\n `A manual-mode store’s own configured rate. ${brand}’s registrations ` +\n 'played no part in computing it. Shown so it is visibly NOT the line ' +\n 'above — the two must never be added together.',\n },\n ]\n }\n return [\n {\n item: '—',\n label: `${filing.code} storefront tax under the platform’s registration (NOT in the figures above)`,\n dollars: platformLiable,\n note:\n 'Collected from shoppers on merchants’ sales and held in the ' +\n 'platform’s balance. Excluded from every figure above. Its treatment ' +\n 'on the return is a question for the operator’s own counsel.',\n },\n {\n item: '—',\n label: `${filing.code} storefront tax under the MERCHANT’s own rate`,\n dollars: merchant,\n note:\n 'A manual-mode store’s own configured rate. The platform’s ' +\n 'registrations played no part in computing it. Shown so it is ' +\n 'visibly NOT the line above — the two must never be added together.',\n },\n ]\n}\n\n/** The three liability buckets, in the order a reader decides them. */\nexport function storefrontBucketRows(\n summary: StorefrontTaxSummary,\n): StorefrontTaxBucketRow[] {\n const brand = PLATFORM_BRAND_NAME\n const buckets: Array<{\n id: StorefrontTaxBucketRow['id']\n label: string\n liability: string\n platformLiable: boolean\n }> = [\n {\n id: 'aglynLiable',\n label: `Computed against ${brand}’s registrations`,\n liability: `In ${brand}’s balance. Stripe Tax computed it on ${brand}’s platform account.`,\n platformLiable: true,\n },\n {\n id: 'merchantManual',\n label: 'Merchant’s own configured rate',\n liability: `The merchant’s. It never touched an ${brand} registration and is not ${brand}’s to remit.`,\n platformLiable: false,\n },\n {\n id: 'connectedAccountLiable',\n label: 'Stripe Tax named the connected account liable',\n liability: 'The connected account’s. Empty today.',\n platformLiable: false,\n },\n ]\n return buckets.map((bucket) => {\n const figures = summary?.[bucket.id]\n return {\n id: bucket.id,\n label: bucket.label,\n liability: bucket.liability,\n transactionCount: Number(figures?.transactionCount ?? 0),\n grossDollars: centsToDollars(figures?.grossCents),\n taxableSalesDollars: centsToDollars(figures?.taxableSalesCents),\n taxCollectedDollars: centsToDollars(figures?.taxCollectedCents),\n platformLiable: bucket.platformLiable,\n }\n })\n}\n\n/**\n * FACILITATED SALES BY STATE — the economic-nexus question (AGL-1956).\n *\n * The question a state asks a marketplace facilitator is \"how much did you\n * facilitate INTO this state, and in how many transactions\" — not \"how much\n * tax did you collect there\". A state the operator is not registered in\n * collects nothing by definition, which is exactly why collection cannot be\n * the measure: the states worth watching are the ones showing $0 tax and a\n * rising sales figure.\n *\n * So this SUMS the three liability buckets per jurisdiction. The rule that\n * the operator's own invoices and storefront rows are never summed still\n * holds — nothing here touches the operator's own sales; within the\n * storefront collection the buckets differ only in WHO REMITS, and a nexus\n * threshold counts the sale whoever remits it. Who remits is still carried\n * per row, because \"do we have nexus here\" and \"what do we owe here\" are\n * answered off the same rows and must not blur.\n *\n * ⚠️ A LOWER BOUND, deliberately rather than silently: `storefront-tax-record.ts`\n * files no row at all for a sale whose `taxMode` resolves to `none`, so a\n * wholly untaxed storefront sale is invisible here — the population nexus\n * detection most needs. Closing it is a write-side change recorded on\n * AGL-1956. The filing jurisdiction does not depend on any of this: a filer\n * registered where it is established has no in-state threshold left to cross.\n */\nexport function storefrontFacilitatedJurisdictionRows(\n summary: StorefrontTaxSummary | null | undefined,\n filing: TaxReturnFiling,\n): StorefrontFacilitatedJurisdictionRow[] {\n if (!summary) return []\n const totals = new Map<\n string,\n { count: number; salesCents: number; taxCents: number; platformCents: number }\n >()\n const buckets: Array<[StorefrontTaxBucketRow['id'], boolean]> = [\n ['aglynLiable', true],\n ['merchantManual', false],\n ['connectedAccountLiable', false],\n ]\n for (const [id, platformLiable] of buckets) {\n const byJurisdiction = summary[id]?.byJurisdiction ?? {}\n for (const [jurisdiction, figures] of Object.entries(byJurisdiction)) {\n const entry = totals.get(jurisdiction) ?? {\n count: 0,\n salesCents: 0,\n taxCents: 0,\n platformCents: 0,\n }\n const taxCents = Number(figures?.taxCollectedCents ?? 0)\n entry.count += Number(figures?.transactionCount ?? 0)\n entry.salesCents += Number(figures?.totalSalesCents ?? 0)\n entry.taxCents += taxCents\n if (platformLiable) entry.platformCents += taxCents\n totals.set(jurisdiction, entry)\n }\n }\n return [...totals.entries()]\n .map(([jurisdiction, entry]) => ({\n jurisdiction,\n isFilingJurisdiction: jurisdiction === filing.code,\n transactionCount: entry.count,\n totalSalesDollars: centsToDollars(entry.salesCents),\n taxCollectedDollars: centsToDollars(entry.taxCents),\n platformLiableTaxDollars: centsToDollars(entry.platformCents),\n untaxed: entry.taxCents === 0,\n }))\n .sort(\n (a, b) =>\n // The filing jurisdiction first — it is the one obligation that does\n // not wait on a threshold — then by the figure a threshold is\n // actually measured against.\n Number(b.isFilingJurisdiction) - Number(a.isFilingJurisdiction) ||\n Number(b.totalSalesDollars) - Number(a.totalSalesDollars) ||\n a.jurisdiction.localeCompare(b.jurisdiction),\n )\n}\n\n/** The storefront's two tables on the return's screen. */\nfunction storefrontTables(\n summary: StorefrontTaxSummary,\n filing: TaxReturnFiling,\n): TaxReturnSectionTable[] {\n const brand = PLATFORM_BRAND_NAME\n return [\n {\n // Split by who owes it, never summed — one \"storefront tax\" total would\n // merge two facts into a number that is true of neither.\n columns: [\n { label: 'Bucket' },\n { label: 'Sales', numeric: true },\n { label: 'Gross', numeric: true, money: true },\n { label: 'Taxable sales', numeric: true, money: true },\n { label: 'Tax collected', numeric: true, money: true },\n ],\n rows: storefrontBucketRows(summary).map((row) => ({\n key: row.id,\n cells: [\n {\n text: row.label,\n caption: row.liability,\n ...(row.platformLiable\n ? { tag: { label: `${brand} holds this`, tone: 'attention' as const } }\n : {}),\n },\n { text: String(row.transactionCount) },\n { text: `$${row.grossDollars}` },\n { text: `$${row.taxableSalesDollars}` },\n { text: `$${row.taxCollectedDollars}`, strong: row.platformLiable },\n ],\n })),\n empty: 'This period’s response carries no storefront figures.',\n },\n {\n heading: 'Facilitated sales by buyer state',\n description:\n `What ${brand} facilitated into each state, whoever remits the ` +\n 'tax — the figure an economic-nexus threshold is measured ' +\n `against. ${filing.code} needs no threshold: the filer is ` +\n 'established there, so the obligation is unconditional. A ' +\n 'region showing sales and no tax is the one to watch.',\n columns: [\n { label: 'Buyer state' },\n { label: 'Sales', numeric: true },\n { label: 'Total sales', numeric: true, money: true },\n { label: 'Tax collected', numeric: true, money: true },\n { label: `Of which ${brand} owes`, numeric: true, money: true },\n ],\n rows: storefrontFacilitatedJurisdictionRows(summary, filing).map((row) => ({\n key: row.jurisdiction,\n cells: [\n {\n text: row.jurisdiction === 'unknown' ? 'Not stated' : row.jurisdiction,\n ...(row.isFilingJurisdiction\n ? { tag: { label: 'Registered', tone: 'attention' as const } }\n : row.untaxed\n ? { tag: { label: 'No tax collected', tone: 'neutral' as const } }\n : {}),\n },\n { text: String(row.transactionCount) },\n { text: `$${row.totalSalesDollars}` },\n { text: `$${row.taxCollectedDollars}` },\n {\n text: `$${row.platformLiableTaxDollars}`,\n strong: Number(row.platformLiableTaxDollars) > 0,\n },\n ],\n })),\n empty: 'No storefront sales recorded in this period.',\n footnote:\n 'A LOWER BOUND. A storefront sale that collected no tax at ' +\n 'all files no row, so it is missing here — which is exactly ' +\n 'the population a nexus check wants. Recorded on AGL-1956.',\n },\n ]\n}\n\n/**\n * The storefront's blocks of the working-papers export: the nexus figures\n * beside the operator's own sales by jurisdiction — a different taxpayer's\n * money and never summed with them — and the liability buckets after the\n * working papers.\n */\nfunction storefrontExports(\n summary: StorefrontTaxSummary,\n filing: TaxReturnFiling,\n): TaxReturnExportBlock[] {\n const brand = PLATFORM_BRAND_NAME\n const facilitated = storefrontFacilitatedJurisdictionRows(summary, filing)\n return [\n {\n placement: 'jurisdictions',\n rows: [\n ['Facilitated sales by buyer state (merchants’ storefronts)'],\n [\n 'Buyer state',\n 'Sales',\n 'Total sales (USD)',\n 'Tax collected (USD)',\n `Of which ${brand} owes (USD)`,\n ],\n ...(facilitated.length\n ? facilitated.map((row) => [\n row.jurisdiction,\n String(row.transactionCount),\n row.totalSalesDollars,\n row.taxCollectedDollars,\n row.platformLiableTaxDollars,\n ])\n : [['—', '0', '0.00', '0.00', '0.00']]),\n [\n 'LOWER BOUND — a storefront sale that collected no tax files no row, ' +\n `so it is absent here. ${filing.code} needs no threshold: the filer ` +\n 'is established there.',\n ],\n ],\n },\n {\n placement: 'sections',\n rows: [\n [\n 'Storefront commerce tax by liability (AGL-1904) — NOT in ' +\n (filing.form === 'tx-webfile' ? 'the Webfile figures' : 'the breakdown above'),\n ],\n [\n 'Bucket',\n 'Who owes it',\n 'Transactions',\n 'Gross (USD)',\n 'Taxable sales (USD)',\n 'Tax collected (USD)',\n ],\n ...storefrontBucketRows(summary).map((row) => [\n row.label,\n row.liability,\n String(row.transactionCount),\n row.grossDollars,\n row.taxableSalesDollars,\n row.taxCollectedDollars,\n ]),\n ],\n },\n ]\n}\n\n/** One storefront row as the working papers carry it. */\nfunction projectRow(row: StorefrontTaxReturnRowInput): StorefrontTaxRow {\n return {\n id: row.id,\n hostId: typeof row.hostId === 'string' ? row.hostId : null,\n orgId: row.orgId ?? null,\n paidAt: asRowDate(row.paidAt)?.toISOString() ?? null,\n taxMode: typeof row.taxMode === 'string' ? row.taxMode : null,\n taxLiability: typeof row.taxLiability === 'string' ? row.taxLiability : null,\n grossCents: Number(row.grossCents ?? 0),\n taxCents: Number(row.taxCents ?? 0),\n taxableSalesCents: (Array.isArray(row.taxLines) ? row.taxLines : [])\n .map((line) => Number(line?.taxableAmountCents ?? 0))\n .reduce((sum, base) => sum + (Number.isFinite(base) ? base : 0), 0),\n state: typeof row.customerAddress?.state === 'string' ? row.customerAddress.state : null,\n country:\n typeof row.customerAddress?.country === 'string' ? row.customerAddress.country : null,\n }\n}\n\n/**\n * The storefront's answer for one period, from rows already read. Pure, so\n * the section a preparer reads can be proved from fixtures.\n */\nexport function storefrontTaxReturnAnswer(\n read: {\n rows: readonly StorefrontTaxReturnRowInput[]\n truncated: boolean\n undatedRows: number\n /** Rows of the operator's own stores, which their own card folds in instead (AGL-4038). */\n ownStoreRows?: number\n },\n request: TaxReturnSourceRequest,\n): TaxReturnSourceAnswer {\n const brand = PLATFORM_BRAND_NAME\n const { filing } = request\n const summary = storefrontTaxSummary(read.rows, request)\n return {\n id: 'storefront',\n name: 'Storefront',\n title: 'Storefront commerce tax — merchants’ sales',\n help:\n 'Tax charged to shoppers on merchants’ storefronts, split by who owes it. None of it is in the filing figures above.',\n intro:\n `None of this is in the ${\n filing.form === 'tx-webfile' ? 'Webfile' : 'breakdown'\n } figures above, which sum ` +\n `${brand}’s OWN sales only. The first row is the one that ` +\n `needs a decision: those sessions are created on ${brand}’s ` +\n `platform account, so Stripe computed that tax against ` +\n `${brand}’s registrations and it settled into ${brand}’s balance.`,\n truncated: read.truncated,\n undatedRows: read.undatedRows,\n findings: storefrontTaxFindings(summary, filing),\n filingLines: storefrontFilingLines(summary, filing),\n tables: storefrontTables(summary, filing),\n figures: read.ownStoreRows\n ? [\n {\n label: `Rows of ${brand}’s own stores`,\n value: String(read.ownStoreRows),\n note: `${brand}’s own sales, not a merchant’s: on the own stores card and folded into the filing figures, never here.`,\n },\n ]\n : [],\n exports: storefrontExports(summary, filing),\n summary,\n rows: read.rows.map(projectRow),\n }\n}\n\n/**\n * Commerce's source, registered on the console's API surface: the staff\n * return awaits that surface before it asks. It answers three sections, one\n * per kind of sale commerce records apart:\n *\n * - the storefront's FACILITATED sales — merchants' money (below);\n * - the POS hardware shop's, the operator's own\n * (`pos-hardware-tax-return-source.ts`, AGL-4038);\n * - the operator's own stores', its own too (`own-store-tax-return-source.ts`,\n * AGL-4038).\n *\n * The operator's own stores are resolved FIRST, because each of the others\n * leaves their sales to the third: the storefront drops their tax rows (and\n * hands their stated bases over), and the hardware section folds in no\n * reader sold at their registers. So every sale is counted once. Any read\n * failing refuses all three, so a half-read commerce never reads as a\n * complete one.\n */\nexport const commerceTaxReturnSource: TaxReturnSource = {\n async read(request) {\n const own = await resolveOwnStores()\n const ownHostIds = new Set(own.stores.map((store) => store.hostId))\n const [storefrontRead, hardware, ownOrders] = await Promise.all([\n readStorefrontTaxRows(request),\n readPosHardwareTaxReturn(request, { ownHostIds }),\n readOwnStoreOrders(request, own.stores),\n ])\n const isOwn = (row: StorefrontTaxReturnRowInput) => isOwnStoreRow(row, own)\n const ownRows = storefrontRead.rows.filter(isOwn)\n const storefront = storefrontTaxReturnAnswer(\n { ...storefrontRead, rows: storefrontRead.rows.filter((row) => !isOwn(row)), ownStoreRows: ownRows.length },\n request,\n )\n // The base Stripe stated on an own store's online sale, by its order id\n // (an online order is keyed by its Checkout Session, as its row is).\n const statedBases = new Map<string, number>()\n for (const row of ownRows) {\n const base = statedTaxableBase(Array.isArray(row.taxLines) ? row.taxLines : [])\n if (base !== null) statedBases.set(row.id, base)\n }\n const ownStores = ownStoreTaxReturnAnswer({ own, read: ownOrders, statedBases }, request)\n return [storefront, hardware, ownStores]\n },\n}\n\n/** Whether a storefront tax row is one of the operator's own stores' (AGL-4038). */\nexport function isOwnStoreRow(\n row: Pick<StorefrontTaxReturnRowInput, 'hostId' | 'orgId'>,\n own: OwnStores,\n): boolean {\n if (typeof row.hostId === 'string' && own.stores.some((store) => store.hostId === row.hostId)) return true\n return Boolean(own.orgId) && row.orgId === own.orgId\n}\n\n/**\n * The storefront's section.\n *\n * Two queries, and the second is the honesty check: the period query ranges\n * on `paidAt`, and a Firestore range query CANNOT match a document whose\n * field is null — so a row that failed to date itself would be invisible to\n * every period. The equality probe counts those rows, over all of them, and\n * the platform blocks the return on any.\n */\nexport async function readStorefrontTaxReturn(\n request: TaxReturnSourceRequest,\n): Promise<TaxReturnSourceAnswer> {\n return storefrontTaxReturnAnswer(await readStorefrontTaxRows(request), request)\n}\n\n/** The storefront's rows for the period, before any is set aside. See {@link readStorefrontTaxReturn}. */\nexport async function readStorefrontTaxRows(request: TaxReturnSourceRequest): Promise<{\n rows: StorefrontTaxReturnRowInput[]\n truncated: boolean\n undatedRows: number\n}> {\n const firestore = firebaseAdmin.app().firestore()\n const collection = firestore.collection('storefrontTaxCollected')\n const [inPeriod, undated, inPerson] = await Promise.all([\n collection\n .where('paidAt', '>=', request.start)\n .where('paidAt', '<', request.end)\n .limit(request.rowCap + 1)\n .get(),\n collection.where('paidAt', '==', null).count().get(),\n // The platform's own in-person hardware sales around the period\n // (AGL-4038): the hardware section counts them, so their part of the\n // register sale's storefront row comes out here (`posHardwareSales`\n // `source, paidAtMs`).\n firestore\n .collection(POS_HARDWARE_SALES_COLLECTION)\n .where('source', '==', 'in_person')\n .where('paidAtMs', '>=', request.start.getTime() - IN_PERSON_ROW_MARGIN_MS)\n .where('paidAtMs', '<', request.end.getTime() + IN_PERSON_ROW_MARGIN_MS)\n .limit(request.rowCap)\n .get(),\n ])\n const rows: StorefrontTaxReturnRowInput[] = storefrontRowsWithoutInPersonHardware(\n inPeriod.docs.slice(0, request.rowCap).map((doc) => ({\n id: doc.id,\n ...(doc.data() as Omit<StorefrontTaxReturnRowInput, 'id'>),\n })),\n posHardwareStorefrontParts(inPerson.docs.map((doc) => doc.data())),\n )\n return {\n rows,\n truncated: inPeriod.size > request.rowCap,\n undatedRows: Number(undated.data().count ?? 0),\n }\n}\n"],"names":["firebaseAdmin","PLATFORM_BRAND_NAME","asRowDate","centsToDollars","storefrontTaxSummary","readPosHardwareTaxReturn","POS_HARDWARE_SALES_COLLECTION","posHardwareStorefrontParts","storefrontRowsWithoutInPersonHardware","statedTaxableBase","ownStoreTaxReturnAnswer","readOwnStoreOrders","resolveOwnStores","IN_PERSON_ROW_MARGIN_MS","storefrontPlatformLiableCents","summary","filing","figures","aglynLiable","byJurisdiction","code","cents","Number","taxCollectedCents","isFinite","merchantManualCents","merchantManual","storefrontTaxFindings","brand","id","severity","count","label","detail","figuresName","attention","rowsUnclassified","rowsMissingTaxableBase","storefrontFilingLines","platformLiable","merchant","form","item","dollars","note","storefrontBucketRows","buckets","liability","map","bucket","transactionCount","grossDollars","grossCents","taxableSalesDollars","taxableSalesCents","taxCollectedDollars","storefrontFacilitatedJurisdictionRows","totals","Map","jurisdiction","Object","entries","entry","get","salesCents","taxCents","platformCents","totalSalesCents","set","isFilingJurisdiction","totalSalesDollars","platformLiableTaxDollars","untaxed","sort","a","b","localeCompare","storefrontTables","columns","numeric","money","rows","row","key","cells","text","caption","tag","tone","String","strong","empty","heading","description","footnote","storefrontExports","facilitated","placement","length","projectRow","hostId","orgId","paidAt","toISOString","taxMode","taxLiability","Array","isArray","taxLines","line","taxableAmountCents","reduce","sum","base","state","customerAddress","country","storefrontTaxReturnAnswer","read","request","name","title","help","intro","truncated","undatedRows","findings","filingLines","tables","ownStoreRows","value","exports","commerceTaxReturnSource","own","ownHostIds","Set","stores","store","storefrontRead","hardware","ownOrders","Promise","all","readStorefrontTaxRows","isOwn","isOwnStoreRow","ownRows","filter","storefront","statedBases","ownStores","some","Boolean","readStorefrontTaxReturn","undated","firestore","app","collection","inPeriod","inPerson","where","start","end","limit","rowCap","getTime","docs","slice","doc","data","size"],"mappings":"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"}
|
package/src/lib/server.js
CHANGED
|
@@ -266,6 +266,83 @@ registerPluginJob({
|
|
|
266
266
|
}
|
|
267
267
|
}
|
|
268
268
|
});
|
|
269
|
+
/**
|
|
270
|
+
* The monthly 4G charge for Stripe Reader S710s (AGL-4038): each workspace
|
|
271
|
+
* whose readers had 4G in the month just ended is charged once, through
|
|
272
|
+
* core's usage-invoice charge. Every six hours, so the charge goes out early
|
|
273
|
+
* on the 1st and one that could not reach Stripe is tried again the same
|
|
274
|
+
* day; a month already settled costs a read per workspace. Nothing runs
|
|
275
|
+
* where 4G is not offered (`POS_CELLULAR_MONTHLY_COST_CENTS` unset).
|
|
276
|
+
* Per-host: a store locked for security or abuse is not charged while it is.
|
|
277
|
+
*/ registerPluginJob({
|
|
278
|
+
pluginId: BUNDLE_ID,
|
|
279
|
+
name: 'pos-cellular-billing',
|
|
280
|
+
intervalMinutes: 6 * 60,
|
|
281
|
+
description: 'Charge each workspace for 4G on its Stripe Reader S710s for the month just ended, once (AGL-4038).',
|
|
282
|
+
lockdown: {
|
|
283
|
+
scope: 'per-host'
|
|
284
|
+
},
|
|
285
|
+
handler: async (gate)=>{
|
|
286
|
+
if (!process.env.STRIPE_SECRET_KEY || !process.env.POS_CELLULAR_MONTHLY_COST_CENTS) return;
|
|
287
|
+
const { runPosCellularBilling } = await import("./server/pos-cellular-billing.js");
|
|
288
|
+
const report = await runPosCellularBilling(gate);
|
|
289
|
+
if (report.workspaces || report.storesGone || report.warned || report.turnedOff || report.paidLate) {
|
|
290
|
+
console.info(`commerce: 4G for ${report.month} — ${report.paid} paid, ${report.open} left open, ` + `${report.failed} not reached, ${report.unbillable} not billable, ${report.deferred} deferred, ` + `${report.storesGone} deleted stores turned off; unpaid charges: ${report.warned} warned, ` + `${report.paidLate} paid since, ${report.turnedOff} turned off`);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
/**
|
|
295
|
+
* Card reader start-up screens (AGL-4048) that went stale with nobody opening
|
|
296
|
+
* the POS devices card: a logo changed on the organization profile or the
|
|
297
|
+
* white-label brand, or the logo's file replaced in the media library. Every
|
|
298
|
+
* 15 minutes, like the recovery pair: a store whose screen did not move costs
|
|
299
|
+
* a few reads and no Stripe call, and nothing a merchant saves waits on it.
|
|
300
|
+
* A screen Stripe refused is retried after six hours here, and at once when
|
|
301
|
+
* the card is opened.
|
|
302
|
+
*/ registerPluginJob({
|
|
303
|
+
pluginId: BUNDLE_ID,
|
|
304
|
+
name: 'pos-reader-splash-refresh',
|
|
305
|
+
intervalMinutes: RECOVERY_JOB_INTERVAL_MINUTES,
|
|
306
|
+
description: 'Bring card reader start-up screens up to date after a logo change (AGL-4048).',
|
|
307
|
+
lockdown: {
|
|
308
|
+
scope: 'per-host'
|
|
309
|
+
},
|
|
310
|
+
handler: async (gate)=>{
|
|
311
|
+
if (!process.env.STRIPE_SECRET_KEY) return;
|
|
312
|
+
const { refreshPosReaderSplashes } = await import("./server/pos-reader-splash.js");
|
|
313
|
+
const result = await refreshPosReaderSplashes(gate);
|
|
314
|
+
if (result.applied || result.failed || result.more) {
|
|
315
|
+
console.info(`commerce: reader start-up screens — ${result.applied} updated, ` + `${result.failed} failed${result.more ? ', more stores than one pass reaches' : ''}`);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
/**
|
|
320
|
+
* Cards taken offline whose sale never synced (AGL-4039).
|
|
321
|
+
*
|
|
322
|
+
* HOURLY. The alert falls due six hours after the intent was first seen, and
|
|
323
|
+
* Stripe's authorization lasts about two days, so an hour's delay costs
|
|
324
|
+
* nothing and leaves the beat one collection-group range read that is empty in
|
|
325
|
+
* the ordinary case. It never captures: without the sale there is no fee to
|
|
326
|
+
* capture with, so it tells the operator and the site's managers instead.
|
|
327
|
+
*
|
|
328
|
+
* Not gated on `isEmailConfigured()`: the console notification and the
|
|
329
|
+
* operator alert both work without mail.
|
|
330
|
+
*/ registerPluginJob({
|
|
331
|
+
pluginId: BUNDLE_ID,
|
|
332
|
+
name: 'offline-card-unsynced',
|
|
333
|
+
intervalMinutes: 60,
|
|
334
|
+
description: 'Tell the operator and the site when a card taken offline reached Stripe but its sale never synced (AGL-4039).',
|
|
335
|
+
lockdown: {
|
|
336
|
+
scope: 'per-host'
|
|
337
|
+
},
|
|
338
|
+
handler: async (gate)=>{
|
|
339
|
+
const { scanUnsyncedOfflineCards } = await import("./server/pos-offline-card-reconcile.js");
|
|
340
|
+
const scan = await scanUnsyncedOfflineCards(gate);
|
|
341
|
+
if (scan.alerted) {
|
|
342
|
+
console.warn(`commerce: ${scan.alerted} cards taken offline have no synced sale`);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
});
|
|
269
346
|
/**
|
|
270
347
|
* A visitor's payment door: it opens a Stripe Checkout Session for whoever
|
|
271
348
|
* calls it, so the dispatcher holds it to the card-testing counters
|
|
@@ -435,6 +512,11 @@ registerPluginJob({
|
|
|
435
512
|
// (AGL-4046): availability re-asked inside the transaction that writes, so
|
|
436
513
|
// two staff cannot hand out the last unit at once. Loaded on first call.
|
|
437
514
|
registerPluginApiRoute('commerce/reservations/walk-in', async (req, res)=>(await import("./server/reservation-walk-in.js")).reservationWalkInHandler(req, res));
|
|
515
|
+
// A stay's guest count after it is booked (AGL-4043), from the Reservations
|
|
516
|
+
// card and the check-in screen: the walk-in's gate, and the stay's
|
|
517
|
+
// check-ins for today on brought in line in the same transaction. Loaded
|
|
518
|
+
// on first call.
|
|
519
|
+
registerPluginApiRoute('commerce/reservations/guests', async (req, res)=>(await import("./server/reservation-guests.js")).reservationGuestsHandler(req, res));
|
|
438
520
|
// The products list's Duplicate and Delete for the native apps (AGL-3841):
|
|
439
521
|
// the console's own copy and soft delete, with the site-wide cache drop.
|
|
440
522
|
registerPluginApiRoute('commerce/products/duplicate', async (req, res)=>(await import("./server/products-write.js")).productDuplicateHandler(req, res));
|
|
@@ -502,13 +584,29 @@ registerPluginJob({
|
|
|
502
584
|
// and order list, gated like a sale and hidden until the deployment prices
|
|
503
585
|
// it; and the staff page's orders, which name no site. Loaded on first call.
|
|
504
586
|
registerPluginApiRoute('commerce/pos-hardware', async (req, res)=>(await import("./server/pos-hardware.js")).posHardwareHandler(req, res));
|
|
587
|
+
// Selling a card reader in person at the platform's own store's register
|
|
588
|
+
// (AGL-4038): whether this store is that seller. Gated like a sale, and
|
|
589
|
+
// silent about the configuration on every other store. Loaded on first call.
|
|
590
|
+
registerPluginApiRoute('commerce/pos-hardware-sale', async (req, res)=>(await import("./server/pos-hardware-sale.js")).posHardwareSaleHandler(req, res));
|
|
505
591
|
// A store's card reader start-up screen (AGL-4048): the POS devices card's
|
|
506
|
-
// setting, gated like a sale, and the staff page's platform default.
|
|
507
|
-
//
|
|
592
|
+
// setting, gated like a sale, and the staff page's platform default. Each
|
|
593
|
+
// loads with its first call; the drawing they ask for is the images
|
|
594
|
+
// route's, below.
|
|
508
595
|
registerPluginApiRoute('commerce/pos-reader-splash', async (req, res)=>(await import("./server/pos-reader-splash.js")).posReaderSplashHandler(req, res));
|
|
509
596
|
registerPluginApiRoute('commerce/admin/reader-splash', {
|
|
510
597
|
web: async (request)=>(await import("./server/pos-reader-splash-admin.js")).posReaderSplashAdmin(request)
|
|
511
598
|
});
|
|
599
|
+
// The image work behind both (AGL-4048): drawing a screen and reading an
|
|
600
|
+
// uploaded one take `sharp`, whose native library only the console's
|
|
601
|
+
// plugins' image function ships (`/api/plugin-images/…`), so the plugin
|
|
602
|
+
// API's function does not carry it. Called by our own servers, signed; a
|
|
603
|
+
// machine's door.
|
|
604
|
+
registerPluginApiRoute('commerce/pos-reader-splash-images', {
|
|
605
|
+
web: async (request)=>(await import("./server/pos-reader-splash-images-route.js")).posReaderSplashImagesRoute(request)
|
|
606
|
+
}, {
|
|
607
|
+
machine: true,
|
|
608
|
+
images: true
|
|
609
|
+
});
|
|
512
610
|
registerPluginApiRoute('commerce/admin/hardware-orders', {
|
|
513
611
|
web: async (request)=>(await import("./server/pos-hardware-admin.js")).posHardwareAdminOrders(request)
|
|
514
612
|
});
|