Skip to content

Product bundles add-on (spec 0085) - #2732

Draft
glennjacobs wants to merge 9 commits into
2.xfrom
spec/0085-product-bundles
Draft

glennjacobs wants to merge 9 commits into
2.xfrom
spec/0085-product-bundles

Conversation

@glennjacobs

Copy link
Copy Markdown
Contributor

Summary

Implements spec 0085: a new first-party lunarphp/bundles package that sells a set of product variants as one product, plus the two small core seams it needs.

  • Core (slices 1-2): order_lines.parent_line_id with OrderLine::parent()/components()/isComponent() and a topLevel scope; the creation stages skip component lines; refundableQuantity() is 0 for components; ProductVariant::getTotalInventory()/canBeFulfilledAtQuantity() now delegate to a new ResolvesInventory action contract (VariantInventory DTO), bound in ActionServiceProvider. Additive; no contract signatures change. The order_lines baseline migration is edited in place (v2 alpha rule).
  • Panel first party (slice 6): component lines nest under their parent in the order view and pick lists ("Part of ..."), the refund composer and "Other items" list top-level lines only; Section is exported from @lunarphp/panel.
  • packages/bundles (slices 3-5): Bundle/BundleGroup/BundleComponent on a variant; fixed and configurable bundles; fixed or components pricing with materialised price rows and repricing listeners plus lunar:bundles:reprice; derived stock through a decorator on ResolvesInventory; cart-line selection validator and a cart_lines pricing stage; an order-creation stage that gives every bundle line zero-priced component lines so fulfilment and stock commitment work unchanged.
  • Panel add-on (slices 7-8): a SectionExtension on Catalog with the bundle editor on the product and variant pages, an "Included in bundles" sidebar card, a Bundle badge column and "Bundles only" filter on the products table, 16 locales.
  • Demo data (slice 9): two bundles seeded when the package is installed.

Docs PR: lunarphp/docs docs/product-bundles (opened alongside this one).

Notes for review

  • No third-party dependency is added; composer.json changes are the sub-package wiring and a suggest on demo-data.
  • Deviations from the spec are recorded in the spec's implementation plan (always-visible badge column, the extra GET bundles/products/{product} route, a cart_lines pipeline stage instead of a cart-line modifier because core never invokes calculating()).
  • Pre-existing, not fixed here: OrderLineQuantity::validate() lazy loads $orderLine->order, which trips preventLazyLoading on an orderIdToUpdate re-run that changes a line quantity.
  • Open questions from the spec (mixed-rate tax, the inventory card on a bundle variant, per-component refunds, queued repricing) are unchanged.

Test plan

  • vendor/bin/pest --testsuite core --parallel (1291 passed)
  • vendor/bin/pest --testsuite panel --parallel (937 passed)
  • vendor/bin/pest --testsuite bundles --parallel (71 passed)
  • vendor/bin/pest --testsuite demo-data --parallel (34 passed)
  • vendor/bin/phpstan analyse --no-progress --memory-limit=2G
  • vendor/bin/pint --dirty
  • panel npm run type-check, npm test; add-on and panel bundles rebuilt
  • translation completeness script: 0 missing, 0 stale

🤖 Generated with Claude Code

glennjacobs and others added 8 commits September 15, 2026 08:48
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…c 0085, slices 1-2)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… (spec 0085, slice 6)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…(spec 0085, slice 9)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ed-in card and products table badge (spec 0085, slices 7-8)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…equired groups, pricing-switch confirmation, listener tests

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… on a re-run

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

1 participant