Skip to content

Conversation

@fPolic
Copy link
Contributor

@fPolic fPolic commented Nov 26, 2025

Summary

What — What changes are introduced in this PR?

Add ability to apply/remove promotions from outbound exchange item.


Checklist

Please ensure the following before requesting a review:

  • I have added a changeset for this PR
    • Every non-breaking change should be marked as a patch
    • To add a changeset, run yarn changeset and follow the prompts
  • The changes are covered by relevant tests
  • I have verified the code works as intended locally
  • I have linked the related issue(s) if applicable

Screen.Recording.2025-11-26.at.18.49.37.mov

TODO

  • finish and expand testing
  • revamp how inbound/outbound total is calculated on the FE
  • cover few more missing edge cases
  • fix loading of intial flag state

CLOSES CORE-1291


Note

Adds a toggle to carry over promotions on exchanges/order changes, wiring DB, workflows, API/SDK, admin UI, and tests to apply/remove adjustments accordingly.

  • Backend/Core:
    • Workflows/Steps: Introduce compute-adjustments-for-preview (generalized), on-carry-promotions-flag-set, update-order-change workflow, and list-order-change-actions-by-type step; compute or delete ITEM_ADJUSTMENTS_REPLACE based on order_change.carry_over_promotions.
    • Integration: Hook into exchange and order-edit flows to recompute adjustments when items change or flag toggles.
    • API: Add POST /admin/order-changes/:id to update carry_over_promotions and return order_change.
    • Types: Extend AdminOrderChange and mutations/responses with carry_over_promotions; add AdminOrderChangeResponse.
    • DB/Model: Add nullable boolean carry_over_promotions to order_change (migration + model + query config).
  • SDK:
    • Add sdk.admin.order.updateOrderChange(id, { carry_over_promotions }).
  • Admin Dashboard (UI):
    • Add "Carry over promotions" switch in exchange create form with tooltip; default state from preview.order_change and updates via new mutation; adjust totals calculation; show applied promo codes icon in order summary.
    • Add useUpdateOrderChange hook; i18n strings/schema updates.
  • Tests:
    • Integration tests for exchanges toggling promotions (enabled/disabled before request) and order edits enabling flag; verify preview/final adjustments and totals.

Written by Cursor Bugbot for commit 44398cd. This will update automatically on new commits. Configure here.

@fPolic fPolic requested a review from a team as a code owner November 26, 2025 10:54
@changeset-bot
Copy link

changeset-bot bot commented Nov 26, 2025

🦋 Changeset detected

Latest commit: 44398cd

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 74 packages
Name Type
@medusajs/dashboard Patch
@medusajs/core-flows Patch
@medusajs/order Patch
@medusajs/js-sdk Patch
@medusajs/types Patch
@medusajs/medusa Patch
@medusajs/admin-bundler Patch
integration-tests-http Patch
@medusajs/draft-order Patch
@medusajs/framework Patch
@medusajs/modules-sdk Patch
@medusajs/orchestration Patch
@medusajs/utils Patch
@medusajs/workflows-sdk Patch
@medusajs/medusa-oas-cli Patch
@medusajs/test-utils Patch
@medusajs/analytics Patch
@medusajs/api-key Patch
@medusajs/auth Patch
@medusajs/cache-inmemory Patch
@medusajs/cache-redis Patch
@medusajs/caching Patch
@medusajs/cart Patch
@medusajs/currency Patch
@medusajs/customer Patch
@medusajs/event-bus-local Patch
@medusajs/event-bus-redis Patch
@medusajs/file Patch
@medusajs/fulfillment Patch
@medusajs/index Patch
@medusajs/inventory Patch
@medusajs/link-modules Patch
@medusajs/locking Patch
@medusajs/notification Patch
@medusajs/payment Patch
@medusajs/pricing Patch
@medusajs/product Patch
@medusajs/promotion Patch
@medusajs/region Patch
@medusajs/sales-channel Patch
@medusajs/settings Patch
@medusajs/stock-location Patch
@medusajs/store Patch
@medusajs/tax Patch
@medusajs/user Patch
@medusajs/workflow-engine-inmemory Patch
@medusajs/workflow-engine-redis Patch
@medusajs/analytics-local Patch
@medusajs/analytics-posthog Patch
@medusajs/auth-emailpass Patch
@medusajs/auth-github Patch
@medusajs/auth-google Patch
@medusajs/caching-redis Patch
@medusajs/file-local Patch
@medusajs/file-s3 Patch
@medusajs/fulfillment-manual Patch
@medusajs/locking-postgres Patch
@medusajs/locking-redis Patch
@medusajs/notification-local Patch
@medusajs/notification-sendgrid Patch
@medusajs/payment-stripe Patch
@medusajs/oas-github-ci Patch
@medusajs/cli Patch
@medusajs/deps Patch
@medusajs/telemetry Patch
@medusajs/admin-sdk Patch
@medusajs/admin-shared Patch
@medusajs/admin-vite-plugin Patch
@medusajs/icons Patch
@medusajs/toolbox Patch
@medusajs/ui-preset Patch
create-medusa-app Patch
medusa-dev-cli Patch
@medusajs/ui Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@fPolic fPolic marked this pull request as draft November 26, 2025 10:54
@vercel
Copy link

vercel bot commented Nov 26, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

8 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
api-reference Ignored Ignored Nov 28, 2025 2:54pm
api-reference-v2 Ignored Ignored Preview Nov 28, 2025 2:54pm
cloud-docs Ignored Ignored Preview Nov 28, 2025 2:54pm
docs-ui Ignored Ignored Preview Nov 28, 2025 2:54pm
docs-v2 Ignored Ignored Preview Nov 28, 2025 2:54pm
medusa-docs Ignored Ignored Preview Nov 28, 2025 2:54pm
resources-docs Ignored Ignored Preview Nov 28, 2025 2:54pm
user-guide Ignored Ignored Preview Nov 28, 2025 2:54pm

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

This is the final PR Bugbot will review for you during this billing cycle

Your free Bugbot reviews will reset on December 17

Details

Your team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

@fPolic fPolic marked this pull request as ready for review November 27, 2025 09:35
@fPolic fPolic requested a review from olivermrbl November 27, 2025 09:35
Copy link
Contributor

@olivermrbl olivermrbl left a comment

Choose a reason for hiding this comment

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

Overall LGTM, few nits

acc =
acc +
((action?.details.quantity || 0) / item.quantity) *
item.total
Copy link

Choose a reason for hiding this comment

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

Bug: Missing optional chaining on details causes potential TypeError

The calculation for inbound total uses action?.details.quantity which only applies optional chaining to action, not to details. According to the type definition, details can be null (details: Record<string, unknown> | null). If action exists but action.details is null, accessing .quantity will throw a TypeError. The codebase elsewhere uses the safer pattern action?.details?.quantity with optional chaining on both properties.

Fix in Cursor Fix in Web

carry_over_promotions: checked,
})
}
}}
Copy link

Choose a reason for hiding this comment

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

Bug: Toggle state not reverted on API failure

The onChange(checked) call updates the form state immediately before the updateOrderChange API call completes. If the API call fails, the form's carry_over_promotions value remains toggled while the backend retains the previous value. The onError handler only displays a toast without reverting the form state. Since the exchange confirmation uses the backend value (not the form value), users will see a toggle indicating promotions will carry over, but the actual exchange behavior won't apply promotions. The onChange call needs to be moved after the successful API call, or the state needs to be reverted in the error handling.

Fix in Cursor Fix in Web

acc =
acc +
((action?.details.quantity || 0) / item.quantity) *
item.total
Copy link

Choose a reason for hiding this comment

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

Bug: Potential division by zero in inbound total calculation

The inbound total calculation divides by item.quantity without checking if it's zero. The expression ((action?.details.quantity || 0) / item.quantity) * item.total would produce NaN or Infinity if item.quantity is 0. While order items should typically always have a positive quantity, if there's any data integrity issue, this would cause incorrect monetary values to be displayed in the UI. Adding a guard like item.quantity || 1 or checking before division would prevent this edge case.

Fix in Cursor Fix in Web

Copy link
Contributor

@olivermrbl olivermrbl left a comment

Choose a reason for hiding this comment

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

Nice LGTM!

@olivermrbl
Copy link
Contributor

/snapshot-this

@github-actions
Copy link
Contributor

🚀 A snapshot release has been made for this PR

Test the snapshots by updating your package.json with the newly published versions:

yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]

Latest commit: 9d1f09a

@fPolic
Copy link
Contributor Author

fPolic commented Nov 28, 2025

tought: now when exchange is confirmed, and promotions are not carried over, it's not clear from the summary on the order details how the promotion has been applied. We might consider adding an indicator with promotions per line item as we did for edit items recently, wdyt - something to tackle in a follow up?

@olivermrbl
Copy link
Contributor

/snapshot-this

@github-actions
Copy link
Contributor

🚀 A snapshot release has been made for this PR

Test the snapshots by updating your package.json with the newly published versions:

yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]

Latest commit: 9d1f09a

Copy link
Contributor

@olivermrbl olivermrbl left a comment

Choose a reason for hiding this comment

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

Feel free to merge

@fPolic
Copy link
Contributor Author

fPolic commented Nov 28, 2025

/snapshot-this

@github-actions
Copy link
Contributor

🚀 A snapshot release has been made for this PR

Test the snapshots by updating your package.json with the newly published versions:

yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]
yarn add @medusajs/[email protected]

Latest commit: 9d1f09a

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants