fix(utils,core-flows): subtotal calculation and returns location (#13497)

* fix(utils,core-flows): subtotal calculation and returns location

* changeset

* fix test

* var

* rm extra field from test

* fix original total

* fix partial refunds and pending difference

* fix test

* fix test

* test

* extract to util

* original total and update payment when receive return

* original_subtotal

* default fields

* test

* calculate pending difference

* revert claims test

* pending difference

* creadit line fix

* if
This commit is contained in:
Carlos R. L. Rodrigues
2025-09-18 12:50:40 -03:00
committed by GitHub
parent 4736c58da5
commit 9563ee446f
37 changed files with 746 additions and 204 deletions

View File

@@ -22,8 +22,10 @@ medusaIntegrationTestRunner({
let returnReason
let inventoryItem
let inventoryItemExtra
let inventoryItemExtra2
let location
let productExtra
let productExtra2
const shippingProviderId = "manual_test-provider"
beforeEach(async () => {
@@ -123,6 +125,31 @@ medusaIntegrationTestRunner({
)
).data.product
productExtra2 = (
await api.post(
"/admin/products",
{
title: "Extra product 2, same price",
shipping_profile_id: shippingProfile.id,
options: [{ title: "size", values: ["large", "small"] }],
variants: [
{
title: "my variant 2",
sku: "variant-sku-2",
options: { size: "large" },
prices: [
{
currency_code: "usd",
amount: 25,
},
],
},
],
},
adminHeaders
)
).data.product
returnReason = (
await api.post(
"/admin/return-reasons",
@@ -269,6 +296,10 @@ medusaIntegrationTestRunner({
await api.get(`/admin/inventory-items?sku=variant-sku`, adminHeaders)
).data.inventory_items[0]
inventoryItemExtra2 = (
await api.get(`/admin/inventory-items?sku=variant-sku-2`, adminHeaders)
).data.inventory_items[0]
await api.post(
`/admin/inventory-items/${inventoryItemExtra.id}/location-levels`,
{
@@ -278,6 +309,15 @@ medusaIntegrationTestRunner({
adminHeaders
)
await api.post(
`/admin/inventory-items/${inventoryItemExtra2.id}/location-levels`,
{
location_id: location.id,
stocked_quantity: 2,
},
adminHeaders
)
const remoteLink = container.resolve(
ContainerRegistrationKeys.REMOTE_LINK
)
@@ -323,6 +363,14 @@ medusaIntegrationTestRunner({
inventory_item_id: inventoryItemExtra.id,
},
},
{
[Modules.PRODUCT]: {
variant_id: productExtra2.variants[0].id,
},
[Modules.INVENTORY]: {
inventory_item_id: inventoryItemExtra2.id,
},
},
])
// create reservation for inventory item that is initially on the order
@@ -440,6 +488,95 @@ medusaIntegrationTestRunner({
})
describe("Exchanges lifecycle", () => {
it("test full exchange flow", async () => {
const orderBefore = (
await api.get(`/admin/orders/${order.id}`, adminHeaders)
).data.order
let result = await api.post(
"/admin/exchanges",
{
order_id: order.id,
description: "Test",
},
adminHeaders
)
expect(result.data.exchange.created_by).toEqual(expect.any(String))
const exchangeId = result.data.exchange.id
const item = order.items[0]
result = await api.post(
`/admin/exchanges/${exchangeId}/inbound/items`,
{
items: [
{
id: item.id,
reason_id: returnReason.id,
quantity: 2,
},
],
},
adminHeaders
)
// New Item
result = await api.post(
`/admin/exchanges/${exchangeId}/outbound/items`,
{
items: [
{
variant_id: productExtra2.variants[0].id,
quantity: 2,
},
],
},
adminHeaders
)
result = await api.post(
`/admin/exchanges/${exchangeId}/request`,
{},
adminHeaders
)
const returnId = result.data.exchange.return_id
result = (await api.get(`/admin/orders/${order.id}`, adminHeaders)).data
.order
expect(orderBefore.total).toBe(61)
expect(result.total).toBe(112)
// receive return
await api.post(`/admin/returns/${returnId}/receive`, {}, adminHeaders)
await api.post(
`/admin/returns/${returnId}/receive-items`,
{
items: [
{
id: item.id,
quantity: 2,
},
],
},
adminHeaders
)
await api.post(
`/admin/returns/${returnId}/receive/confirm`,
{},
adminHeaders
)
result = (await api.get(`/admin/orders/${order.id}`, adminHeaders)).data
.order
expect(orderBefore.total).toBe(61)
expect(result.total).toBe(62) // +1 is from taxes of the new item
})
it("Full flow with 2 orders", async () => {
let result = await api.post(
"/admin/exchanges",

View File

@@ -6,6 +6,7 @@ import {
AdminStockLocation,
MedusaContainer,
} from "@medusajs/types"
import { ContainerRegistrationKeys, Modules } from "@medusajs/utils"
import {
adminHeaders,
generatePublishableKey,
@@ -175,6 +176,26 @@ export async function createOrderSeeder({
adminHeaders
)
const remoteLink = container.resolve(ContainerRegistrationKeys.LINK)
await remoteLink.create([
{
[Modules.SALES_CHANNEL]: {
sales_channel_id: salesChannel.id,
},
[Modules.STOCK_LOCATION]: {
stock_location_id: stockLocation.id,
},
},
{
[Modules.PRODUCT]: {
variant_id: product.variants[0].id,
},
[Modules.INVENTORY]: {
inventory_item_id: inventoryItem.id,
},
},
])
/**
* Create shipping options for each shipping profile provided
*/

View File

@@ -32,7 +32,35 @@ medusaIntegrationTestRunner({
adminHeaders
)
await api.post(`/admin/claims/${claim.id}/request`, {}, adminHeaders)
const createdClaim = await api.post(
`/admin/claims/${claim.id}/request`,
{},
adminHeaders
)
const returnOrder = createdClaim.data.return
const returnId = returnOrder.id
await api.post(`/admin/returns/${returnId}/receive`, {}, adminHeaders)
let lineItem = returnOrder.items[0].item
await api.post(
`/admin/returns/${returnId}/receive-items`,
{
items: [
{
id: lineItem.id,
quantity: returnOrder.items[0].quantity,
},
],
},
adminHeaders
)
await api.post(
`/admin/returns/${returnId}/receive/confirm`,
{},
adminHeaders
)
}
beforeEach(async () => {
@@ -64,10 +92,6 @@ medusaIntegrationTestRunner({
})
describe("with outstanding amount due to claim", () => {
beforeEach(async () => {
await createClaim({ order })
})
it("should capture an authorized payment", async () => {
const payment = order.payment_collections[0].payments[0]
@@ -189,6 +213,8 @@ medusaIntegrationTestRunner({
adminHeaders
)
await createClaim({ order })
const refundReason = (
await api.post(
`/admin/refund-reasons`,
@@ -253,6 +279,8 @@ medusaIntegrationTestRunner({
)
).data.refund_reason
await createClaim({ order })
await api.post(
`/admin/payments/${payment.id}/refund`,
{
@@ -311,6 +339,8 @@ medusaIntegrationTestRunner({
adminHeaders
)
await createClaim({ order })
await api.post(
`/admin/payments/${payment.id}/refund`,
{ amount: 25 },

View File

@@ -1,9 +1,9 @@
import { medusaIntegrationTestRunner } from "@medusajs/test-utils"
import {
ContainerRegistrationKeys,
Modules,
RuleOperator,
} from "@medusajs/utils"
import { medusaIntegrationTestRunner } from "@medusajs/test-utils"
import {
adminHeaders,
createAdminUser,
@@ -478,6 +478,16 @@ medusaIntegrationTestRunner({
adminHeaders
)
expect(result.data.order_preview.summary).toEqual(
expect.objectContaining({
transaction_total: 0,
current_order_total: 61,
pending_difference: 11,
paid_total: 0,
refunded_total: 0,
})
)
expect(result.data.order_preview).toEqual(
expect.objectContaining({
id: order.id,

View File

@@ -1,8 +1,18 @@
import { createOrderChangeWorkflow, createOrderWorkflow, } from "@medusajs/core-flows"
import {
createOrderChangeWorkflow,
createOrderWorkflow,
} from "@medusajs/core-flows"
import { medusaIntegrationTestRunner } from "@medusajs/test-utils"
import { CreateOrderLineItemDTO, IOrderModuleService, OrderDTO, } from "@medusajs/types"
import {
CreateOrderLineItemDTO,
IOrderModuleService,
OrderDTO,
} from "@medusajs/types"
import { Modules, ProductStatus } from "@medusajs/utils"
import { adminHeaders, createAdminUser, } from "../../../helpers/create-admin-user"
import {
adminHeaders,
createAdminUser,
} from "../../../helpers/create-admin-user"
jest.setTimeout(50000)
@@ -288,6 +298,7 @@ medusaIntegrationTestRunner({
discount_total: 1.1,
discount_tax_total: 0.1,
original_total: 61,
original_subtotal: 60,
original_tax_total: 1,
item_total: 50,
item_subtotal: 50,
@@ -433,6 +444,7 @@ medusaIntegrationTestRunner({
subtotal: 50,
total: 50,
original_total: 50,
original_subtotal: 50,
discount_total: 0,
discount_tax_total: 0,
discount_subtotal: 0,
@@ -490,6 +502,10 @@ medusaIntegrationTestRunner({
precision: 20,
value: "0",
},
raw_original_subtotal: {
precision: 20,
value: "50",
},
raw_return_dismissed_total: {
precision: 20,
value: "0",