feat(checkout): pass the cart's shipment options to the delivery options widget - #510
feat(checkout): pass the cart's shipment options to the delivery options widget#510FreekVR wants to merge 5 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR extends the checkout context with cart-calculated shipment options per carrier (so the delivery options widget can display/lock merchant-forced options like 18+) and fixes the age-check (18+) locking logic on the carrier settings UI to only apply when age check is explicitly enabled.
Changes:
- Add
DeliveryOptionsServiceInterface::createCartShipmentOptions()and compute per-carrier shipment options by running a cart-derived synthetic order through the export calculation pipeline. - Add
CheckoutContext::cartShipmentOptionsand convert calculatedShipmentOptionstri-state values into widget-format booleans at the context boundary. - Fix carrier settings UI behavior so signature/only-recipient are locked only when age check is explicitly
ENABLED, and update/add regression tests + fixtures to reflect real capability requires/excludes rules.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/Unit/Frontend/View/CarrierSettingsItemViewTest.php | Adds regression coverage for strict tri-state operations and correct locking behavior for age check. |
| tests/Unit/App/Order/Service/PdkOrderOptionsServiceTest.php | Adds regression test ensuring capability “requires/excludes” are enforced when age check originates from carrier settings. |
| tests/Unit/App/DeliveryOptions/Service/DeliveryOptionsServiceCartShipmentOptionsTest.php | New tests covering per-carrier cart shipment-options calculation and exposure through checkout context as widget booleans. |
| tests/Unit/App/Action/Backend/Order/ExportOrderActionTest.php | Strengthens export assertions for age check cascading behavior. |
| tests/SdkApi/Response/ExampleContractDefinitionsResponse.php | Documents API asymmetry: requires/excludes relations live on capabilities, not contract definitions. |
| tests/Bootstrap/MockCarrierCapabilitiesRepository.php | Updates permissive capabilities fixture with real age-verification requires/excludes relations. |
| tests/snapshots/SettingsViewTest__it_gets_settings_view_with_data_set_carrier_settings__1.json | Snapshot update reflecting strict $eq conditions for read-only behavior. |
| tests/snapshots/FrontendRenderServiceTest__it_renders_component_with_data_set_plugin_settings__1.json | Snapshot update reflecting strict $eq conditions for read-only behavior. |
| tests/snapshots/FrontendRenderServiceTest__it_renders_component_with_data_set_delivery_options__1.json | Snapshot update adding cartShipmentOptions to checkout context output. |
| tests/snapshots/ContextServiceTest__it_gets_context_data_with_data_set_delivery_options_config__1.json | Snapshot update adding cartShipmentOptions to checkout context output. |
| src/Shipment/Model/ShipmentOptions.php | Adds ShipmentOptions::toBooleanOptions() to convert strict tri-state options to widget booleans. |
| src/Shipment/Collection/ShipmentOptionsCollection.php | Introduces a typed collection for ShipmentOptions, used as return type for cart shipment options per carrier. |
| src/Frontend/View/CarrierSettingsItemView.php | Fixes age-check dependent locking to only apply when age check is explicitly enabled. |
| src/Context/Model/CheckoutContext.php | Adds cartShipmentOptions to the checkout context and populates it from the cart calculation pipeline. |
| src/App/DeliveryOptions/Service/DeliveryOptionsService.php | Implements cart shipment option calculation per carrier via synthetic order + export pipeline. |
| src/App/DeliveryOptions/Contract/DeliveryOptionsServiceInterface.php | Adds new createCartShipmentOptions() contract method. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #510 +/- ##
============================================
- Coverage 94.33% 94.25% -0.08%
- Complexity 2414 2434 +20
============================================
Files 352 352
Lines 7726 7784 +58
============================================
+ Hits 7288 7337 +49
- Misses 438 447 +9 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
NabDevs
left a comment
There was a problem hiding this comment.
1 thing to check, looks good otherwise.
1a5abae to
f38fb67
Compare
f38fb67 to
f030936
Compare
* Guard carrier settings * test: clean carrier guard * fix: validate carrier entries * fix: ignore malformed carrier settings * refactor: simplify carrier settings guard
The checkout context now contains, per carrier, the shipment options an order from this cart would be exported with — resolved through the same settings chain and capabilities rules the export runs. The delivery options widget uses this to show and lock options that are already decided on the merchant side, like 18+ forcing signature and only recipient on. Also fixes the carrier settings screen locking signature and only recipient while 18+ was merely inheriting, and gives the test fixtures the real age verification rules from the capabilities API so the requires propagation is pinned by tests end to end. Resolves INT-1596 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…in the age check export test The createCartShipmentOptions docblock claimed the result is converted to the capabilities key-space; it returns calculated ShipmentOptions models, and the widget-format boolean conversion happens at the CheckoutContext boundary. The age check export test now also asserts that receipt code is off, matching the capability rules it already describes. Resolves INT-1596 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…tion uses the customer note Building the checkout context runs the cart through the same calculation an export does, on an order that only exists in memory. With [CUSTOMER_NOTE] in the label description setting, that calculation asked the shop for the order's notes, and looking notes up without an order identifier throws in WooCommerce and PrestaShop — taking the checkout down with it. An order without an identifier now simply has no notes, so nothing asks the shop for them, and the cart's order is built with empty notes to say so up front. Tests use a note repository that rejects a missing identifier like the platforms do, so this cannot pass silently again. Resolves INT-1596 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…s from the cart the application should degrade gracefully if the shipment options from a pending cart cannot be calculated for whatever reason
f030936 to
6538122
Compare
Adds the cart's calculated shipment options to the checkout context, and fixes the age check (18+) rules on the carrier settings screen.
The checkout context gets a new optional cartShipmentOptions key (a sibling of config): per carrier, the widget's camelCase option name → boolean, calculated by running the cart through the same pipeline an order export uses. The delivery options widget shows those options (like the ones 18+ requires) as checked and locked for the consumer; without the key the widget behaves as before. js-pdk forwards the key to the widget in myparcelnl/js-pdk#381.
On the carrier settings screen the 18+ rules now lock signature and only recipient only when 18+ is actually on — the lock previously also matched "inherit". Test fixtures now carry the real capability rules for age verification (requires signature and only recipient, excludes receipt code), with regression tests pinning the export path.
Merge order for INT-1596:
Fixes INT-1596
Subtask: INT-1732
🤖 Generated with Claude Code