feat(medusa): Swaps on swaps (#229)

Co-authored-by: Sebastian Rindom <skrindom@gmail.com>
This commit is contained in:
Oliver Windall Juhl
2021-04-20 10:55:15 +02:00
committed by GitHub
co-authored by Sebastian Rindom
parent 2f3e3fde80
commit f8f1f57fa1
29 changed files with 1578 additions and 3276 deletions
@@ -51,6 +51,7 @@ const defaultFields = [
"updated_at",
"metadata",
"items.refundable",
"swaps.additional_items.refundable",
"shipping_total",
"discount_total",
"tax_total",
@@ -58,6 +59,7 @@ const defaultFields = [
"gift_card_total",
"subtotal",
"total",
"paid_total",
"refundable_amount",
]
@@ -37,21 +37,18 @@ describe("POST /admin/orders/:id/return", () => {
it("calls OrderService return", () => {
expect(ReturnService.create).toHaveBeenCalledTimes(1)
expect(ReturnService.create).toHaveBeenCalledWith(
{
order_id: IdMap.getId("test-order"),
idempotency_key: "testkey",
items: [
{
item_id: IdMap.getId("existingLine"),
quantity: 10,
},
],
refund_amount: 10,
shipping_method: undefined,
},
orders.testOrder
)
expect(ReturnService.create).toHaveBeenCalledWith({
order_id: IdMap.getId("test-order"),
idempotency_key: "testkey",
items: [
{
item_id: IdMap.getId("existingLine"),
quantity: 10,
},
],
refund_amount: 10,
shipping_method: undefined,
})
})
})
@@ -88,21 +85,18 @@ describe("POST /admin/orders/:id/return", () => {
it("calls OrderService return", () => {
expect(ReturnService.create).toHaveBeenCalledTimes(1)
expect(ReturnService.create).toHaveBeenCalledWith(
{
order_id: IdMap.getId("test-order"),
idempotency_key: "testkey",
items: [
{
item_id: IdMap.getId("existingLine"),
quantity: 10,
},
],
refund_amount: 0,
shipping_method: undefined,
},
orders.testOrder
)
expect(ReturnService.create).toHaveBeenCalledWith({
order_id: IdMap.getId("test-order"),
idempotency_key: "testkey",
items: [
{
item_id: IdMap.getId("existingLine"),
quantity: 10,
},
],
refund_amount: 0,
shipping_method: undefined,
})
})
})
@@ -139,21 +133,18 @@ describe("POST /admin/orders/:id/return", () => {
it("calls OrderService return", () => {
expect(ReturnService.create).toHaveBeenCalledTimes(1)
expect(ReturnService.create).toHaveBeenCalledWith(
{
order_id: IdMap.getId("test-order"),
idempotency_key: "testkey",
items: [
{
item_id: IdMap.getId("existingLine"),
quantity: 10,
},
],
refund_amount: 0,
shipping_method: undefined,
},
orders.testOrder
)
expect(ReturnService.create).toHaveBeenCalledWith({
order_id: IdMap.getId("test-order"),
idempotency_key: "testkey",
items: [
{
item_id: IdMap.getId("existingLine"),
quantity: 10,
},
],
refund_amount: 0,
shipping_method: undefined,
})
})
})
@@ -194,24 +185,21 @@ describe("POST /admin/orders/:id/return", () => {
it("calls OrderService return", () => {
expect(ReturnService.create).toHaveBeenCalledTimes(1)
expect(ReturnService.create).toHaveBeenCalledWith(
{
order_id: IdMap.getId("test-order"),
idempotency_key: "testkey",
items: [
{
item_id: IdMap.getId("existingLine"),
quantity: 10,
},
],
refund_amount: 100,
shipping_method: {
option_id: "opt_1234",
price: 12,
expect(ReturnService.create).toHaveBeenCalledWith({
order_id: IdMap.getId("test-order"),
idempotency_key: "testkey",
items: [
{
item_id: IdMap.getId("existingLine"),
quantity: 10,
},
],
refund_amount: 100,
shipping_method: {
option_id: "opt_1234",
price: 12,
},
orders.testOrder
)
})
expect(ReturnService.fulfill).toHaveBeenCalledTimes(1)
expect(ReturnService.fulfill).toHaveBeenCalledWith("return")
@@ -124,7 +124,7 @@ export default async (req, res) => {
.withTransaction(manager)
.retrieve(id, {
select: ["refunded_total", "total"],
relations: ["items", "swaps"],
relations: ["items", "swaps", "swaps.additional_items"],
})
const swap = await swapService
@@ -78,14 +78,6 @@ export default app => {
middlewares.wrap(require("./request-return").default)
)
/**
* Register a requested return
*/
route.post(
"/:id/return/:return_id/receive",
middlewares.wrap(require("./receive-return").default)
)
/**
* Cancel an order.
*/
@@ -234,6 +226,7 @@ export const defaultFields = [
"updated_at",
"metadata",
"items.refundable",
"swaps.additional_items.refundable",
"shipping_total",
"discount_total",
"tax_total",
@@ -241,6 +234,7 @@ export const defaultFields = [
"gift_card_total",
"subtotal",
"total",
"paid_total",
"refundable_amount",
]
@@ -267,6 +261,7 @@ export const allowedFields = [
"subtotal",
"gift_card_total",
"total",
"paid_total",
"refundable_amount",
]
@@ -123,13 +123,6 @@ export default async (req, res) => {
const { key, error } = await idempotencyKeyService.workStage(
idempotencyKey.idempotency_key,
async manager => {
const order = await orderService
.withTransaction(manager)
.retrieve(id, {
select: ["refunded_total", "total"],
relations: ["items"],
})
const returnObj = {
order_id: id,
idempotency_key: idempotencyKey.idempotency_key,
@@ -150,7 +143,7 @@ export default async (req, res) => {
const createdReturn = await returnService
.withTransaction(manager)
.create(returnObj, order)
.create(returnObj)
if (value.return_shipping) {
await returnService
@@ -208,7 +201,7 @@ export default async (req, res) => {
order = await returnService
.withTransaction(manager)
.receiveReturn(order.id, ret.id, value.items, value.refund)
.receive(ret.id, value.items, value.refund)
}
order = await orderService.withTransaction(manager).retrieve(id, {
@@ -0,0 +1,58 @@
import { IdMap } from "medusa-test-utils"
import { request } from "../../../../../helpers/test-request"
import { OrderServiceMock } from "../../../../../services/__mocks__/order"
import { ReturnService } from "../../../../../services/__mocks__/return"
describe("POST /admin/returns/:id/receive", () => {
describe("successfully receives a return", () => {
let subject
beforeAll(async () => {
subject = await request(
"POST",
`/admin/returns/${IdMap.getId("test-return")}/receive`,
{
payload: {
items: [
{
item_id: IdMap.getId("test"),
quantity: 2,
},
],
},
adminSession: {
jwt: {
userId: IdMap.getId("admin_user"),
},
},
}
)
})
it("returns 200", () => {
expect(subject.status).toEqual(200)
})
it("calls ReturnService receive", () => {
expect(ReturnService.receive).toHaveBeenCalledTimes(1)
expect(ReturnService.receive).toHaveBeenCalledWith(
IdMap.getId("test-return"),
[{ item_id: IdMap.getId("test"), quantity: 2 }],
undefined,
true
)
})
it("calls OrderService registerReturnReceived", () => {
expect(OrderServiceMock.registerReturnReceived).toHaveBeenCalledTimes(1)
expect(OrderServiceMock.registerReturnReceived).toHaveBeenCalledWith(
IdMap.getId("test-order"),
{
id: IdMap.getId("test-return"),
order_id: IdMap.getId("test-order"),
},
undefined
)
})
})
})
@@ -11,5 +11,10 @@ export default app => {
*/
route.get("/", middlewares.wrap(require("./list-returns").default))
route.post(
"/:id/receive",
middlewares.wrap(require("./receive-return").default)
)
return app
}
@@ -1,14 +1,12 @@
import { MedusaError, Validator } from "medusa-core-utils"
import { defaultRelations, defaultFields } from "./"
/**
* @oas [post] /orders/{id}/returns/{return_id}/receive
* operationId: "PostOrdersOrderReturnsReturnReceive"
* @oas [post] /returns/{id}receive
* operationId: "PostReturnsReturnReceive"
* summary: "Receive a Return"
* description: "Registers a Return as received."
* description: "Registers a Return as received. Updates statuses on Orders and Swaps accordingly."
* parameters:
* - (path) id=* {string} The id of the Order.
* - (path) return_id=* {string} The id of the Return.
* - (path) id=* {string} The id of the Return.
* requestBody:
* content:
* application/json:
@@ -29,7 +27,7 @@ import { defaultRelations, defaultFields } from "./"
* description: The amount to refund.
* type: integer
* tags:
* - Order
* - Return
* responses:
* 200:
* description: OK
@@ -37,11 +35,11 @@ import { defaultRelations, defaultFields } from "./"
* application/json:
* schema:
* properties:
* order:
* $ref: "#/components/schemas/order"
* return:
* $ref: "#/components/schemas/return"
*/
export default async (req, res) => {
const { id, return_id } = req.params
const { id } = req.params
const schema = Validator.object().keys({
items: Validator.array()
@@ -61,28 +59,43 @@ export default async (req, res) => {
}
try {
const returnService = req.scope.resolve("returnService")
const orderService = req.scope.resolve("orderService")
const swapService = req.scope.resolve("swapService")
const entityManager = req.scope.resolve("manager")
let refundAmount = value.refund
let receivedReturn
await entityManager.transaction(async manager => {
let refundAmount = value.refund
if (typeof value.refund !== "undefined" && value.refund < 0) {
refundAmount = 0
}
if (typeof value.refund !== "undefined" && value.refund < 0) {
refundAmount = 0
}
let order = await orderService.receiveReturn(
id,
return_id,
value.items,
refundAmount,
true
)
receivedReturn = await returnService
.withTransaction(manager)
.receive(id, value.items, refundAmount, true)
order = await orderService.retrieve(id, {
select: defaultFields,
relations: defaultRelations,
if (receivedReturn.order_id) {
await orderService
.withTransaction(manager)
.registerReturnReceived(
receivedReturn.order_id,
receivedReturn,
refundAmount
)
}
if (receivedReturn.swap_id) {
await swapService
.withTransaction(manager)
.registerReceived(receivedReturn.swap_id)
}
})
res.status(200).json({ order })
receivedReturn = await returnService.retrieve(id, { relations: ["swap"] })
res.status(200).json({ return: receivedReturn })
} catch (err) {
throw err
}