fix(medusa): RMA on items from swaps and claims (#1182)

This commit is contained in:
Kasper Fabricius Kristensen
2022-05-17 11:19:46 +02:00
committed by GitHub
parent a87e1cdf65
commit 5ae5f15e98
6 changed files with 524 additions and 7 deletions
@@ -4,6 +4,7 @@ const {
Order,
LineItem,
CustomShippingOption,
ShippingMethod,
} = require("@medusajs/medusa")
const setupServer = require("../../../helpers/setup-server")
@@ -914,6 +915,215 @@ describe("/admin/orders", () => {
])
})
it("creates a claim on a claim additional item", async () => {
const api = useApi()
const response = await api
.post(
"/admin/orders/test-order/claims",
{
type: "replace",
shipping_methods: [
{
id: "test-method",
},
],
claim_items: [
{
item_id: "test-item",
quantity: 1,
reason: "production_failure",
tags: ["fluff"],
images: ["https://test.image.com"],
},
],
additional_items: [
{
variant_id: "test-variant",
quantity: 1,
},
],
},
{
headers: {
Authorization: "Bearer test_token",
},
}
)
.catch((err) => {
console.log(err)
})
const cid = response.data.order.claims[0].id
const fulRes = await api.post(
`/admin/orders/test-order/claims/${cid}/fulfillments`,
{},
{
headers: {
Authorization: "Bearer test_token",
},
}
)
const claimItemIdToClaim =
fulRes.data.order.claims[0].additional_items[0].id
const claimRes = await api
.post(
"/admin/orders/test-order/claims",
{
type: "replace",
shipping_methods: [
{
id: "test-method",
},
],
claim_items: [
{
item_id: claimItemIdToClaim,
quantity: 1,
reason: "production_failure",
tags: ["fluff"],
images: ["https://test.image2.com"],
},
],
additional_items: [
{
variant_id: "test-variant-2",
quantity: 1,
},
],
},
{
headers: {
Authorization: "Bearer test_token",
},
}
)
.catch((err) => {
console.log(err)
})
expect(claimRes.status).toEqual(200)
expect(claimRes.data.order.claims.length).toEqual(2)
const newClaim = claimRes.data.order.claims.find(
(c) => c.fulfillment_status === "not_fulfilled"
)
expect(newClaim.claim_items[0].item.id).toEqual(claimItemIdToClaim)
})
it("creates a claim on a swap additional item", async () => {
const api = useApi()
// create a swap
const response = await api
.post(
"/admin/orders/test-order/swaps",
{
custom_shipping_options: [{ option_id: "test-option", price: 0 }],
return_items: [
{
item_id: "test-item",
quantity: 1,
},
],
additional_items: [{ variant_id: "test-variant-2", quantity: 1 }],
},
{
headers: {
authorization: "Bearer test_token",
},
}
)
.catch((e) => console.log(e))
const sid = response.data.order.swaps[0].id
const manager = dbConnection.manager
// add a shipping method so we can fulfill the swap
const sm = await manager.create(ShippingMethod, {
id: "test-method-swap-cart",
swap_id: sid,
shipping_option_id: "test-option",
price: 0,
data: {},
})
await manager.save(sm)
// fulfill the swap
const fulRes = await api
.post(
`/admin/orders/test-order/swaps/${sid}/fulfillments`,
{},
{
headers: {
Authorization: "Bearer test_token",
},
}
)
.catch((e) => console.log(e))
// ship the swap
await api
.post(
`/admin/orders/test-order/swaps/${sid}/shipments`,
{
fulfillment_id: fulRes.data.order.swaps[0].fulfillments[0].id,
},
{
headers: {
Authorization: "Bearer test_token",
},
}
)
.catch((e) => console.log(e))
const claimItemIdToClaim =
fulRes.data.order.swaps[0].additional_items[0].id
// create a claim on the exchange
const claimRes = await api
.post(
"/admin/orders/test-order/claims",
{
type: "replace",
claim_items: [
{
item_id: claimItemIdToClaim,
quantity: 1,
reason: "production_failure",
tags: ["fluff"],
images: ["https://test.image2.com"],
},
],
additional_items: [
{
variant_id: "test-variant-2",
quantity: 1,
},
],
},
{
headers: {
Authorization: "Bearer test_token",
},
}
)
.catch((err) => {
console.log(err)
})
expect(claimRes.status).toEqual(200)
expect(claimRes.data.order.claims.length).toEqual(1)
const newClaim = claimRes.data.order.claims[0]
expect(newClaim.claim_items[0].item.id).toEqual(claimItemIdToClaim)
})
it("Only allow canceling claim after canceling fulfillments", async () => {
const order_id = "order-with-claim"
@@ -0,0 +1,270 @@
const path = require("path")
import { ReturnReason, ShippingMethod } from "@medusajs/medusa"
const setupServer = require("../../../helpers/setup-server")
const { useApi } = require("../../../helpers/use-api")
const { initDb, useDb } = require("../../../helpers/use-db")
const orderSeeder = require("../../helpers/order-seeder")
const adminSeeder = require("../../helpers/admin-seeder")
jest.setTimeout(30000)
describe("/admin/returns", () => {
let medusaProcess
let dbConnection
beforeAll(async () => {
const cwd = path.resolve(path.join(__dirname, "..", ".."))
dbConnection = await initDb({ cwd })
medusaProcess = await setupServer({ cwd })
})
afterAll(async () => {
const db = useDb()
await db.shutdown()
medusaProcess.kill()
})
describe("POST /admin/returns/:id", () => {
let rrId
beforeEach(async () => {
try {
await adminSeeder(dbConnection)
await orderSeeder(dbConnection)
const created = dbConnection.manager.create(ReturnReason, {
value: "too_big",
label: "Too Big",
})
const resultRR = await dbConnection.manager.save(created)
rrId = resultRR.id
} catch (err) {
console.log(err)
throw err
}
})
afterEach(async () => {
const db = useDb()
await db.teardown()
})
it("should receive a return on an item added through swap additional items", async () => {
const api = useApi()
// create a swap
const response = await api
.post(
"/admin/orders/test-order/swaps",
{
custom_shipping_options: [{ option_id: "test-option", price: 0 }],
return_items: [
{
item_id: "test-item",
quantity: 1,
},
],
additional_items: [{ variant_id: "test-variant-2", quantity: 1 }],
},
{
headers: {
authorization: "Bearer test_token",
},
}
)
.catch((e) => console.log(e))
const sid = response.data.order.swaps[0].id
const manager = dbConnection.manager
// add a shipping method so we can fulfill the swap
const sm = await manager.create(ShippingMethod, {
id: "test-method-swap-cart",
swap_id: sid,
shipping_option_id: "test-option",
price: 0,
data: {},
})
await manager.save(sm)
// fulfill the swap
const fulRes = await api
.post(
`/admin/orders/test-order/swaps/${sid}/fulfillments`,
{},
{
headers: {
Authorization: "Bearer test_token",
},
}
)
.catch((e) => console.log(e))
// ship the swap
await api
.post(
`/admin/orders/test-order/swaps/${sid}/shipments`,
{
fulfillment_id: fulRes.data.order.swaps[0].fulfillments[0].id,
},
{
headers: {
Authorization: "Bearer test_token",
},
}
)
.catch((e) => console.log(e))
const swapItemId = fulRes.data.order.swaps[0].additional_items[0].id
// request a return
const returnRes = await api
.post(
`/admin/orders/test-order/return`,
{
items: [
{
item_id: swapItemId,
quantity: 1,
reason_id: rrId,
},
],
},
{
headers: {
Authorization: "Bearer test_token",
},
}
)
.catch((e) => console.log(e.response))
const returnId = returnRes.data.order.returns[0].id
const receiveRes = await api
.post(
`/admin/returns/${returnId}/receive`,
{
items: [
{
item_id: swapItemId,
quantity: 1,
},
],
},
{
headers: {
Authorization: "Bearer test_token",
},
}
)
.catch((e) => console.log(e.response))
expect(receiveRes.status).toEqual(200)
})
it("should receive a return on an item added through claim additional items", async () => {
const api = useApi()
const response = await api
.post(
"/admin/orders/test-order/claims",
{
type: "replace",
shipping_methods: [
{
id: "test-method",
},
],
claim_items: [
{
item_id: "test-item",
quantity: 1,
reason: "production_failure",
tags: ["fluff"],
images: ["https://test.image.com"],
},
],
additional_items: [
{
variant_id: "test-variant",
quantity: 1,
},
],
},
{
headers: {
Authorization: "Bearer test_token",
},
}
)
.catch((err) => {
console.log(err)
})
const cid = response.data.order.claims[0].id
const fulRes = await api.post(
`/admin/orders/test-order/claims/${cid}/fulfillments`,
{},
{
headers: {
Authorization: "Bearer test_token",
},
}
)
const claimItemId = fulRes.data.order.claims[0].additional_items[0].id
// request a return
const returnRes = await api
.post(
`/admin/orders/test-order/return`,
{
items: [
{
item_id: claimItemId,
quantity: 1,
reason_id: rrId,
},
],
return_shipping: {
option_id: "test-option",
price: 0,
}
},
{
headers: {
Authorization: "Bearer test_token",
},
}
)
.catch((e) => console.log(e.response))
const returnId = returnRes.data.order.returns[0].id
const receiveRes = await api
.post(
`/admin/returns/${returnId}/receive`,
{
items: [
{
item_id: claimItemId,
quantity: 1,
},
],
},
{
headers: {
Authorization: "Bearer test_token",
},
}
)
.catch((e) => console.log(e.response))
expect(receiveRes.status).toEqual(200)
})
})
})
@@ -153,6 +153,7 @@ module.exports = async (connection, data = {}) => {
currency_code: "usd",
amount_refunded: 0,
provider_id: "test-pay",
captured_at: new Date(),
data: {},
},
],
@@ -1,17 +1,17 @@
import { Type } from "class-transformer"
import {
IsArray,
IsOptional,
ValidateNested,
IsBoolean,
IsObject,
IsString,
IsEnum,
IsInt,
IsNotEmpty,
IsEnum,
IsObject,
IsOptional,
IsString,
ValidateNested,
} from "class-validator"
import { MedusaError } from "medusa-core-utils"
import { defaultAdminOrdersRelations, defaultAdminOrdersFields } from "."
import { defaultAdminOrdersFields, defaultAdminOrdersRelations } from "."
import { AddressPayload } from "../../../../types/common"
import { validator } from "../../../../utils/validator"
@@ -177,6 +177,12 @@ export default async (req, res) => {
"items.tax_lines",
"discounts",
"discounts.rule",
"claims",
"claims.additional_items",
"claims.additional_items.tax_lines",
"swaps",
"swaps.additional_items",
"swaps.additional_items.tax_lines",
],
})
+29 -1
View File
@@ -230,7 +230,35 @@ class ClaimService extends BaseService {
let toRefund = refund_amount
if (type === "refund" && typeof refund_amount === "undefined") {
const lines = claim_items.map((ci) => {
const orderItem = order.items.find((oi) => oi.id === ci.item_id)
const allOrderItems = order.items
if (order.swaps?.length) {
for (const swap of order.swaps) {
swap.additional_items.forEach((it) => {
if (
it.shipped_quantity ||
it.shipped_quantity === it.fulfilled_quantity
) {
allOrderItems.push(it)
}
})
}
}
if (order.claims?.length) {
for (const claim of order.claims) {
claim.additional_items.forEach((it) => {
if (
it.shipped_quantity ||
it.shipped_quantity === it.fulfilled_quantity
) {
allOrderItems.push(it)
}
})
}
}
const orderItem = allOrderItems.find((oi) => oi.id === ci.item_id)
return {
...orderItem,
quantity: ci.quantity,
+2
View File
@@ -563,6 +563,8 @@ class ReturnService extends BaseService {
"region",
"swaps",
"swaps.additional_items",
"claims",
"claims.additional_items",
],
})