diff --git a/docs/scratch/orders-feature-survey.html b/docs/scratch/orders-feature-survey.html new file mode 100644 index 0000000..ac10bd1 --- /dev/null +++ b/docs/scratch/orders-feature-survey.html @@ -0,0 +1,450 @@ +
+ Where the Checkout survey stopped — the instant Order exists — this
+ one starts. A feature-by-feature pass across Shopify, WooCommerce, PrestaShop, and
+ (briefly) Magento's post-placement order layer — sourced, not recalled from memory —
+ checked against what Lunar's Order model and the
+ already-shipped Filament ManageOrder page actually support
+ today. For deciding what the new Order module needs to own, not a
+ build order.
+
One field, or several axes — and who's allowed to move it.
+ +ManageOrder::paymentStatus() derives a real value from transactions()/captureTotal()/refundTotal()/intentTotal() — but it's a computed display value on the admin page, not a stored column or something the rest of the system (mailers, automations) can key off. Shopify and Magento both make payment status a first-class, independently-queryable dimension; here it's derived on the fly, once, in one Filament page.paymentStatus() exists for shipment/fulfillment state — Order has no shipments() relation of its own at all; it's added dynamically by Modules\Core\Shipping\Providers\ShippingServiceProvider::resolveRelationUsing(), outside Order's own boundary (see docs/checkout.md, "Where Order would likely absorb work"). Every platform researched (Shopify, Woo, PrestaShop, Magento) treats "has this shipped" as derivable from child records, not a manually-set field — Lunar has the child records (Shipment) but no derived status method reading them.ManageOrder ships a working UpdateStatusAction out of the box, backed by config('lunar.orders.statuses') — a flat, merchant-configured list, each entry carrying a label/color/favourite flag. Closer to WooCommerce's single linear field than Shopify's multi-axis split.config('lunar.orders.statuses') already declares mailers and notifications arrays — the PrestaShop-style shape is there in config — but per the Checkout survey's finding, nothing in core actually reads and dispatches from those keys on a transition. The data model for "status carries behavior" exists; the behavior doesn't.OrderStatusUpdated/equivalent exists anywhere in core. UpdateStatusAction just writes the column. Anything wanting to react to a status change — a confirmation email, a webhook, re-deriving payment/fulfillment status — has to hook the raw Eloquent Order::updated() event and diff status itself.Turning a placed order into a package that moves.
+ +Modules\Core\Shipping\Models\Shipment (carrier, tracking reference, label-printed timestamp, manifest reference) already exists and belongs to Order. Built this session, ahead of most gaps in this survey — the record shape is closer to Magento's per-shipment entity than Woo's "no shipment entity at all."Shipment has no quantity-per-line or order_line_id concept — it's one shipment record per carrier voucher, with a parent_reference for ACS's own multipart-voucher case (one physical order split into multiple packages by the carrier), not a per-line-item fulfillment split decided by staff. Closer to "multiple packages for one shipment" than Magento's true per-line partial-shipment model.Modules\Core\Shipping\Extensions\OrderViewExtension adds a working "Create Shipment" header action to ManageOrder, resolving a CarrierFulfillmentInterface by the order's chosen shipping method and calling createShipment() — genuinely wired, not a stub. Currently lives under Shipping, flagged in docs/checkout.md as conceptually an Order concern.Shipment.tracking_reference/carrier exist and are populated by createShipment(); PollShipmentTrackingJob (scheduled every 30 minutes) keeps ShipmentInfo checkpoints current via CarrierFulfillmentInterface::trackShipment(). Genuinely ahead of PrestaShop's thin order_carrier.tracking_number field — this has a real checkpoint history, not just one string.ShipmentInfo, TrackingStatus enum including Delivered) but nothing writes them back onto Order.status — a delivered shipment doesn't move the order out of whatever status it was already in. Every platform researched treats "delivered" as a status a customer/staff can see on the order, not something buried one relation away.PollShipmentTrackingJob's own status updates either.Money moving back out, and orders that never should have been placed.
+ +ManageOrder's refund action already exists — picks a transaction, an amount (validated against availableToRefund()), and notes, then calls the driver's own Transaction::refund(). This is genuinely native, matching Woo/Magento's line-item-adjacent (if not line-item-exact) refund UX.ManageOrder's capture action + requiresCapture()/canBeRefunded() guard methods already exist, delegating to Transaction::capture() — this is the Stripe "authorize now, capture later" flow's admin-side half, already built ahead of most gaps here.ManageOrder — a cancellation today would just be picking a "cancelled"-labeled entry from the generic status dropdown (01), with no automatic refund trigger, no stock-release logic, and no distinction from any other manual status edit.paymentStatus() recomputes correctly from transactions when the admin page loads, but a refund doesn't push the order into a refunded/partially-refunded overall status the way Shopify's displayFinancialStatus does automatically.The one area every researched platform treats as optional, not core.
+ +Return/RMA model, status set, or request flow exists anywhere in this codebase. Consistent with the research: Shopify is the only platform of the four with this genuinely native; PrestaShop ships it off-by-default; Magento gates it behind the paid Adobe Commerce tier; WooCommerce lacks it entirely. Safe to treat as a real gap, not an urgent one.CarrierFulfillmentInterface already has the label-printing primitive (printLabel()) a return label would reuse, so the carrier-side plumbing isn't the blocker, the RMA request/approval model is.Changing a placed order — and where every platform draws the line.
+ +Shipment existing, per the pattern all four researched platforms converge on.OrderAddress rows are snapshotted at creation (see Checkout survey, 02) and nothing in ManageOrder exposes editing them afterward — every platform researched treats address edits as lower-risk than line-item edits and allows them more freely; this codebase currently allows neither.ManageOrder's edit_tags action already works — the one piece of native post-placement editing that exists today, via HasTags on the Order model.The one thing every researched platform treats as non-negotiable.
+ +Order already uses Spatie's LogsActivity trait — every save is recorded with a diff, same underlying mechanism already relied on elsewhere in this codebase (staff activity log, translation history). Structurally equivalent to PrestaShop's order_history table, just via a different package.