Skip to content

feat(checkout): lock shipment options the cart already decided on - #480

Open
FreekVR wants to merge 3 commits into
mainfrom
fix/INT-1596-cart-shipment-options
Open

feat(checkout): lock shipment options the cart already decided on#480
FreekVR wants to merge 3 commits into
mainfrom
fix/INT-1596-cart-shipment-options

Conversation

@FreekVR

@FreekVR FreekVR commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Lets the plugin pass the cart's calculated shipment options into the widget, so options the shop already decided on show as checked and locked.

The plugin can pass a new optional top-level cartShipmentOptions key (per carrier, camelCase option name → boolean), next to initial and address. When an option the consumer cannot choose (like age check) is active on the cart, the widget looks up its capability rules and shows every option it requires as checked and locked, and every option it excludes as unchecked and locked. One module (useShipmentOptionsState) decides all shipment option state; the option list and the selector only read from it.

The shop's allow* settings keep deciding what the consumer sees: an option that is not allowed never renders, forced or not; the plugin still enforces it at export. Forced options keep their configured surcharge (like priceSignature) — being forced doesn't make an option free. Without cartShipmentOptions the widget behaves exactly as before, so older plugin versions keep working.

Merge order for INT-1596:

  1. This PR — its release adds cartShipmentOptions to the widget input.
  2. fix(admin): enforce carrier rules on shipment options in settings and orders js-pdk#381 — bump @myparcel-dev/delivery-options there afterwards to turn its typecheck green.
  3. feat(checkout): pass the cart's shipment options to the delivery options widget pdk#510 — independent, can merge any time.

Fixes INT-1596
Subtask: INT-1733

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings July 24, 2026 07:12
@FreekVR
FreekVR requested a review from a team as a code owner July 24, 2026 07:12
@netlify

netlify Bot commented Jul 24, 2026

Copy link
Copy Markdown

Deploy Preview for myparcel-delivery-options ready!

Name Link
🔨 Latest commit d79a56f
🔍 Latest deploy log https://app.netlify.com/projects/myparcel-delivery-options/deploys/6a7c65f6fcef020008bb65b1
😎 Deploy Preview https://deploy-preview-480--myparcel-delivery-options.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@codecov

codecov Bot commented Jul 24, 2026

Copy link
Copy Markdown

Bundle Report

Changes will increase total bundle size by 4.13kB (1.41%) ⬆️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
@myparcel-dev/delivery-options-MyParcelDeliveryOptionsLib-esm 168.47kB 2.25kB (1.35%) ⬆️
@myparcel-dev/delivery-options-MyParcelDeliveryOptionsLib-umd 127.59kB 1.88kB (1.49%) ⬆️

Affected Assets, Files, and Routes:

view changes for bundle: @myparcel-dev/delivery-options-MyParcelDeliveryOptionsLib-esm

Assets Changed:

Asset Name Size Change Total Size Change (%)
myparcel.lib.esm.js 2.25kB 168.47kB 1.35%

Files in myparcel.lib.esm.js:

  • ./src/config/setConfiguration.ts → Total Size: 691 bytes

  • ./src/composables/events/useResolvedValues.ts → Total Size: 3.44kB

  • ./src/stores/useCartShipmentOptionsStore.ts → Total Size: 352 bytes

  • ./src/composables/useShipmentOptionsState.ts → Total Size: 4.87kB

  • ./src/composables/useShipmentOptionsOptions.ts → Total Size: 905 bytes

  • ./src/config/validateConfiguration.ts → Total Size: 4.23kB

view changes for bundle: @myparcel-dev/delivery-options-MyParcelDeliveryOptionsLib-umd

Assets Changed:

Asset Name Size Change Total Size Change (%)
myparcel.lib.js 1.88kB 127.59kB 1.49%

Files in myparcel.lib.js:

  • ./src/config/validateConfiguration.ts → Total Size: 4.23kB

  • ./src/composables/events/useResolvedValues.ts → Total Size: 3.44kB

  • ./src/stores/useCartShipmentOptionsStore.ts → Total Size: 356 bytes

  • ./src/config/setConfiguration.ts → Total Size: 691 bytes

  • ./src/views/MyParcelDeliveryOptions/Delivery/ShipmentOptionsSelector/ShipmentOptionsSelector.vue → Total Size: 0 bytes

  • ./src/composables/useShipmentOptionsOptions.ts → Total Size: 909 bytes

  • ./src/composables/useShipmentOptionsState.ts → Total Size: 4.92kB

@codecov

codecov Bot commented Jul 24, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 76.42276% with 29 lines in your changes missing coverage. Please review.
✅ Project coverage is 70.16%. Comparing base (356e66e) to head (d79a56f).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...options/src/composables/useShipmentOptionsState.ts 75.71% 0 Missing and 17 partials ⚠️
libs/shared/src/utils/capabilitiesMapping.ts 57.14% 5 Missing and 1 partial ⚠️
...livery-options/src/config/validateConfiguration.ts 83.33% 0 Missing and 2 partials ⚠️
...hipmentOptionsSelector/ShipmentOptionsSelector.vue 75.00% 2 Missing ⚠️
...s/src/__tests__/utils/mockDeliveryOptionsConfig.ts 0.00% 0 Missing and 1 partial ⚠️
...ps/delivery-options/src/config/setConfiguration.ts 50.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #480      +/-   ##
==========================================
- Coverage   70.25%   70.16%   -0.09%     
==========================================
  Files         262      263       +1     
  Lines        2938     2970      +32     
  Branches      437      445       +8     
==========================================
+ Hits         2064     2084      +20     
  Misses        539      539              
- Partials      335      347      +12     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the delivery-options widget input to accept cart-calculated shipment options (per carrier) and uses that data to enforce capability requires/excludes so that cart-decided options are reflected as checked/unchecked and locked in the UI. It centralizes shipment option rendering/locking/defaulting logic into a single composable to ensure consistent state across the selector and option list.

Changes:

  • Add cartShipmentOptions to the configuration types and configuration pipeline, including sanitization/normalization and a dedicated store.
  • Introduce useShipmentOptionsState (with a pure resolveShipmentOptionsState) as the single source of truth for shipment option visibility, defaults, and forced on/off state; remove useShipmentOptionRules.
  • Expand shared capability→shipment-option mapping utilities to support plugin cart option name translation (camelCase) back to capability keys, and adjust tests/mocks accordingly.

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated no comments.

Show a summary per file
File Description
libs/shared/src/utils/capabilitiesMapping.ts Adds a single source-of-truth shipment-option map and introduces mapCartShipmentOptionToCapability() for plugin cart option name translation.
libs/shared/src/types/config.types.ts Introduces CartShipmentOptions type and wires optional cartShipmentOptions into config input/output types.
libs/shared/src/data/config.ts Adds KEY_CART_SHIPMENT_OPTIONS for consistent configuration key access.
libs/shared/src/tests/mocks/mockCapabilitiesResponse.ts Exports DEFAULT_OPTION and extends mock capabilities with age-check rules for new behavior coverage.
apps/delivery-options/src/views/MyParcelDeliveryOptions/Delivery/ShipmentOptionsSelector/ShipmentOptionsSelector.vue Switches enforcement/defaulting logic to useShipmentOptionsState.
apps/delivery-options/src/stores/useCartShipmentOptionsStore.ts New store to hold per-carrier cart shipment options while preserving reactive identity across updates.
apps/delivery-options/src/stores/index.ts Exposes the new cart shipment options store from the stores barrel.
apps/delivery-options/src/config/validateConfiguration.ts Sanitizes cartShipmentOptions input (type-safety, carrier normalization, boolean filtering, __proto__ hardening).
apps/delivery-options/src/config/validateConfiguration.spec.ts Adds unit tests for cartShipmentOptions validation/sanitization behavior.
apps/delivery-options/src/config/setConfiguration.ts Applies validated cartShipmentOptions into the new store on configuration set.
apps/delivery-options/src/composables/useShipmentOptionsState.ts New single-owner module implementing forced/default/rendering state resolution, including cart-derived forcing.
apps/delivery-options/src/composables/useShipmentOptionsState.spec.ts Adds tests for cart-driven forcing plus existing requires/excludes/default behaviors.
apps/delivery-options/src/composables/useShipmentOptionsOptions.ts Refactors option list building to consume optionStates from useShipmentOptionsState and only add label/price.
apps/delivery-options/src/composables/useShipmentOptionsOptions.spec.ts Adds test ensuring disallowed options never render even when forced by cart rules.
apps/delivery-options/src/composables/useShipmentOptionRules.ts Removes the old rules composable now superseded by useShipmentOptionsState.
apps/delivery-options/src/composables/index.ts Updates exports to remove useShipmentOptionRules and export useShipmentOptionsState.
apps/delivery-options/src/tests/utils/mockDeliveryOptionsConfig.ts Ensures cart shipment options store is updated/reset during test config mocking.
apps/delivery-options/src/snapshots/index.spec.ts.snap Updates public export snapshot to include new exports and remove deleted composable.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@myparcel-bot myparcel-bot Bot added the changes requested (Auto) label Jul 24, 2026
@myparcel-bot
myparcel-bot Bot force-pushed the fix/INT-1596-cart-shipment-options branch 2 times, most recently from 5897d82 to da6b3f5 Compare July 28, 2026 12:53
@FreekVR
FreekVR requested a review from NabDevs July 29, 2026 09:24
@myparcel-bot myparcel-bot Bot removed the changes requested (Auto) label Jul 29, 2026
@myparcel-bot myparcel-bot Bot added the approved (Auto) label Jul 29, 2026
@myparcel-bot
myparcel-bot Bot force-pushed the fix/INT-1596-cart-shipment-options branch 2 times, most recently from fd414d7 to ea5fb50 Compare August 3, 2026 07:14
FreekVR and others added 3 commits August 12, 2026 14:23
The plugin can now pass the cart's calculated shipment options to the widget
through a new optional top-level `cartShipmentOptions` key (per carrier,
camelCase option name → boolean), next to `initial` and `address`. When an
option the consumer cannot choose (like age check) is active on the cart, the
widget looks up its capability rules and shows every option it requires as
checked and locked, and every option it excludes as unchecked and locked.

One module (`useShipmentOptionsState`) now decides all shipment option state —
what renders, what is forced on or off, defaults and prices; the option list
and the selector only read from it. Rules are evaluated on the capabilities
key-space, so options without a consumer UI (like age check) can force the
ones that do have one.

The shop's allow* settings keep deciding what the consumer sees: an option
that is not allowed never renders, forced or not; the plugin still enforces it
at export. Without `cartShipmentOptions` the widget behaves exactly as before.

Resolves INT-1596

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…place

Cart shipment options arrive under the plugin's names ('ageCheck') while the
widget works with its own ('age_check'), which meant a second lookup table and
a third vocabulary inside the option rules. The names are now translated where
the rest of the configuration is cleaned up, so everything past that point
speaks one language, and the one reverse lookup covers every shipment option
instead of only the ones a consumer can select.

Resolves INT-1596

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… inputs

Which options are forced, which start out checked, which are shown and which
count as selected are now four separate calculations, each over only the data it
needs. The selection follows from them instead of being written into the
consumer's choices, so an option the chosen carrier no longer offers disappears
by itself and options that were only checked because a rule forced them do not
linger after switching carriers.

This also fixes unchecking two options in a row: because everything was
calculated together, the starting state looked new on every click, and emptying
the selection made the widget apply it again — putting both options back.

The cart's calculated value now decides the starting state of options the
consumer can pick: on means checked to begin with, off means unchecked, either
way still theirs to change. Options that cannot be selected in the widget keep
working purely through the capability rules, so they can force an option they
require without ever being shown or sent themselves.

Resolves INT-1596

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@FreekVR
FreekVR force-pushed the fix/INT-1596-cart-shipment-options branch from ea5fb50 to d79a56f Compare August 12, 2026 12:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved (Auto)

Development

Successfully merging this pull request may close these issues.

4 participants