Commit Graph

16 Commits

Author SHA1 Message Date
Fabian @ Blax Software f10d5c2f04 feat(tax): configurable TaxService applied across every checkout path
Blax\Shop\Services\TaxService::rates($exempt, $rates=null) is one source of
truth that turns "which rate(s)" (config shop.tax.rates or an explicit list)
and "is this customer exempt" into the array Stripe expects. It fails loud
(TaxRateNotConfiguredException) when shop.tax.require is set and no rate is
configured for a non-exempt charge, instead of silently billing 0% VAT.

New config('shop.tax') block (SHOP_TAX_RATES / SHOP_TAX_REQUIRE). Unit tested.

Consumers (learn-atc #1509) delegate getApplicableTaxRates() here so no path
can apply the rate twice (Stripe rejects duplicate tax rates) or drop VAT to 0%.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-21 08:23:56 +02:00
Fabian @ Blax Software b154d8fea2 feat(seats): assignable license seats — buy N, assign/reassign/reclaim per user
A seat-based product (meta.seat_based) sold at quantity N provisions N
assignable LicenseSeat rows instead of granting the buyer. Assigning a seat
runs the product's existing ProductAction grants against the seat holder via
an explicit `grantee` (resolution: grantee ?? purchaser ?? subscription->user),
so a seat confers exactly the product's access with zero duplicated grant logic.

- LicenseSeat model: assign / reassign / reclaim / retire / refreshGrant
- SeatService: idempotent provisioning for one-time purchases and subscriptions
  (sizes the pool to quantity; renewal extends expiry + re-grants held seats)
- SeatAssigned / SeatReassigned / SeatRevoked events
- Product::isSeatBased(); ProductPurchase + Subscription provision on
  completion / lifecycle hooks
- license_seats migration + factory; config `shop.seats` block
- 15 new tests (purchase, subscription, renewal, retire, delegation, gating)

Backward compatible: with no `grantee` the buyer grant is unchanged, and seat
behavior is gated behind the per-product meta flag + config `shop.seats.enabled`.
Full package suite green: 1425 tests / 3812 assertions / 0 failures.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-29 10:07:58 +02:00
Fabian @ Blax Software d4ae9339ac feat(subscriptions): Cashier-backed subscription lifecycle with product link + events
Adds the package's missing subscription lifecycle so any host app gets
duration-aware, product-linked subscriptions without re-implementing billing:

- Models: Subscription (extends Laravel\Cashier\Subscription) + SubscriptionItem,
  in the package's UUID convention, resolved through shop.models/shop.tables.
  Subscription gains product()/resolveProduct(), callProductActions() (runs the
  product's ProductActions with the subscription + an access-expiry override),
  and recordStarted()/recordRenewed()/recordCanceled() lifecycle hooks.
- Events: SubscriptionStarted / SubscriptionRenewed / SubscriptionCanceled,
  carrying the Cashier subscription so host subclasses work too.
- Migration: UUID subscriptions / subscription_items tables (hasTable-guarded,
  config table names, nullable product_id + current_period_* columns).
- ShopServiceProvider points Cashier at these models by default; opt out via
  shop.subscriptions.register_cashier_models for apps that subclass Cashier.

Additive and backward-compatible (registration is config-gated, tables are
guarded). Adds SubscriptionLifecycleTest; full suite 1409 green. Docs + README.
2026-06-02 11:40:15 +02:00
Fabian @ Blax Software 0cfbdf221d BF edgecases, R structure, A tests 2026-05-18 13:05: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 6e9c9043ae I order, A handy methods 2025-12-29 10:26:51 +01:00
Fabian @ Blax Software 9c1fcd6cfd AM orders 2025-12-29 09:59:02 +01:00
Fabian @ Blax Software c43910b927 I checkout session, pool cart price_id 2025-12-17 18:33:34 +01:00
Fabian @ Blax Software 3045f72304 BFI cart, A stripe logic, checkout & tests, A tests, RA pool product 2025-12-15 14:10:59 +01:00
Fabian @ Blax Software 4a303c0f3f I category methods, IRA product relations & tests 2025-12-05 09:21:07 +01:00
a6a2f5842 a4fedcdb58 A tests, I product action 2025-11-29 20:09:19 +01:00
a6a2f5842 929e87bc28 AI payment process & payment provider files 2025-11-26 11:09:52 +01:00
a6a2f5842 856686e292 A traits, concerns, services 2025-11-26 00:05:46 +01:00
a6a2f5842 fda536deea BFIM bugfixed failed tests 2025-11-22 18:09:45 +01:00
a6a2f5842 8fa194e7e6 BF added model table config 2025-11-21 15:22:40 +01:00
a6a2f5842 d610cc5717 init 2025-11-21 11:49:41 +01:00