Commit Graph

15 Commits

Author SHA1 Message Date
Fabian @ Blax Software 96b9a19287 feat(fulfillment): add model-agnostic PurchaseCompleted event
Introduce a first-class PurchaseCompleted lifecycle event so host apps can run
fulfillment (grant access, send receipts, provision licences) without coupling
to the ProductAction table or to a concrete purchasable model. It fires when a
purchase is created already-COMPLETED and when one transitions into COMPLETED,
and is transition-guarded so it does not re-fire on unrelated saves of an
already-completed purchase.

Also generalise the built-in ProductAction fulfillment in ProductPurchase:
the actionable product is now resolved via config('shop.models.product') /
'...product_price' (instead of a hard instanceof the bundled Product), and
callActions() is only invoked when the resolved product exposes it — so apps
overriding the models, or using IsSimplePurchasable host models, complete
cleanly. Existing behaviour for the bundled Product is unchanged.

Adds 4 EventsWiredUpTest cases; full suite 1404 green. Docs + README updated.
2026-06-02 11:19:21 +02:00
Fabian @ Blax Software 30dc3755d2 test: pin clock in loan-vocabulary test; docs: bump suite counts to 1400/3755
PurchaseResourceTest::it_translates_e_commerce_columns_into_loan_vocabulary
relied on the real wall clock falling inside the fixture's loan window
(2026-05-14..2026-05-28); once that window passed, the loan resolved to
`overdue` and the test failed. Freeze the clock inside the window like its
sibling tests already do.

Update the README test/assertion badges and the Testing section to the current
suite size (1400 tests, 3755 assertions) after the subscription-checkout tests.
2026-06-02 09:48:26 +02:00
Fabian @ Blax Software 6d22e130ed A cart availability + test 2026-05-19 11:17:35 +02:00
Fabian @ Blax Software ab8ea6afec BF stock calculation 2026-05-18 11:54:11 +02:00
Fabian @ Blax Software 8eb1802ef8 feat: promote IsLoanableProduct to MayBeLoanableProduct on Product
Renames the host-attached IsLoanableProduct trait to MayBeLoanableProduct
and mixes it directly into Product, matching the existing MayBePoolProduct
shape. Hosts opt in with a single DEFAULT_TYPE constant — no more manual
`use ...Trait` ceremony to forget:

    class Book extends Product
    {
        public const DEFAULT_TYPE = ProductType::LOANABLE;
    }

The boot hook reads DEFAULT_TYPE on the concrete class and only applies
the LOANABLE creating-defaults (type, status, is_visible, manage_stock)
when it matches; type-specific helpers (checkOutTo, total_quantity,
available_quantity) early-out via isLoanable() so they're harmless on
non-loanable products. checkOutTo now throws NotLoanableProductException
when called on the wrong type, mirroring NotPoolProductException.

Also fixes total_quantity for the loan lifecycle: previously summed every
INCREASE entry in product_stocks, which inflated the displayed total
after each loan cycle because returns fire increaseStock(). Now reports
physical inventory as availableStock + activeLoans.

README gains a Testing section that surfaces the current phpunit summary
line, plus passing and assertion-count badges linking to it.
2026-05-16 12:17:38 +02:00
Fabian @ Blax Software fe41475c84 I loanable product type, tiered pricing, lifecycle events, host helpers 2026-05-15 10:27:59 +02:00
Fabian @ Blax Software 80bc7293b1 I readme 2026-05-14 10:44:31 +02:00
Fabian @ Blax Software 136b7ade63 A prompts, I docs/readme, BF orders, R tests locations 2025-12-30 09:29:43 +01:00
Fabian @ Blax Software cabae43950 A facades, U readme 2025-12-09 10:59:46 +01:00
a6a2f5842 676951cda0 AI readme, tests 2025-12-03 14:12:22 +01:00
a6a2f5842 a4fedcdb58 A tests, I product action 2025-11-29 20:09:19 +01:00
a6a2f5842 ffc8716c22 A stripe & BFI cart 2025-11-28 10:24:07 +01:00
a6a2f5842 ce41dea486 A add example products command, I cleanup 2025-11-21 15:52:06 +01:00
a6a2f5842 756801f649 I minor 2025-11-21 11:59:25 +01:00
a6a2f5842 d610cc5717 init 2025-11-21 11:49:41 +01:00