feat(medusa): Configurable returnable_items on order decorate totals (#3276)

This commit is contained in:
Adrien de Peretti authored and GitHub committed 2023-02-21 14:48:49 +01:00
1 parent b393d74a10
commit d11ab924b8
36 files changed
+673 -307

No files matched your search

+5
View File
@@ -0,0 +1,5 @@
---
"@medusajs/medusa": patch
---
feat(medusa): Configurable returnable_items on order decorate totals
@@ -292,46 +292,3 @@ Array [
] ]
`; `;
exports[`/admin/price-lists POST /admin/price-lists/:id/prices/batch Adds a batch of new prices where a MA record have a \`region_id\` instead of \`currency_code\` 1`] = `
Array [
Object {
"amount": 70,
"created_at": Any<String>,
"currency_code": "usd",
"deleted_at": null,
"id": "ma_test_4",
"max_quantity": null,
"min_quantity": null,
"price_list_id": "pl_with_some_ma",
"region_id": null,
"updated_at": Any<String>,
"variant_id": "test-variant",
},
Object {
"amount": 100,
"created_at": Any<String>,
"currency_code": "eur",
"deleted_at": null,
"id": Any<String>,
"max_quantity": null,
"min_quantity": null,
"price_list_id": "pl_with_some_ma",
"region_id": "region-pl",
"updated_at": Any<String>,
"variant_id": "test-variant",
},
Object {
"amount": 200,
"created_at": Any<String>,
"currency_code": "usd",
"deleted_at": null,
"id": Any<String>,
"max_quantity": null,
"min_quantity": null,
"price_list_id": "pl_with_some_ma",
"region_id": null,
"updated_at": Any<String>,
"variant_id": "test-variant",
},
]
`;
@@ -859,45 +859,47 @@ describe("/admin/price-lists", () => {
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
expect(response.data.price_list.prices.length).toEqual(3) // initially this PL has 1 MA record expect(response.data.price_list.prices.length).toEqual(3) // initially this PL has 1 MA record
expect(response.data.price_list.prices).toMatchSnapshot([ expect(response.data.price_list.prices).toEqual(
{ expect.arrayContaining([
id: "ma_test_4", expect.objectContaining({
currency_code: "usd", id: "ma_test_4",
amount: 70, currency_code: "usd",
price_list_id: "pl_with_some_ma", amount: 70,
variant_id: "test-variant", price_list_id: "pl_with_some_ma",
region_id: null, variant_id: "test-variant",
created_at: expect.any(String), region_id: null,
updated_at: expect.any(String), created_at: expect.any(String),
deleted_at: null, updated_at: expect.any(String),
}, deleted_at: null,
{ }),
id: expect.any(String), expect.objectContaining({
currency_code: "eur", id: expect.any(String),
amount: 100, currency_code: "usd",
min_quantity: null, amount: 200,
max_quantity: null, min_quantity: null,
price_list_id: "pl_with_some_ma", max_quantity: null,
variant_id: "test-variant", price_list_id: "pl_with_some_ma",
region_id: "region-pl", variant_id: "test-variant",
created_at: expect.any(String), region_id: null,
updated_at: expect.any(String), created_at: expect.any(String),
deleted_at: null, updated_at: expect.any(String),
}, deleted_at: null,
{ }),
id: expect.any(String), expect.objectContaining({
currency_code: "usd", id: expect.any(String),
amount: 200, currency_code: "eur",
min_quantity: null, amount: 100,
max_quantity: null, min_quantity: null,
price_list_id: "pl_with_some_ma", max_quantity: null,
variant_id: "test-variant", price_list_id: "pl_with_some_ma",
region_id: null, variant_id: "test-variant",
created_at: expect.any(String), region_id: "region-pl",
updated_at: expect.any(String), created_at: expect.any(String),
deleted_at: null, updated_at: expect.any(String),
}, deleted_at: null,
]) }),
])
)
}) })
}) })
@@ -301,7 +301,7 @@ describe("/admin/swaps", () => {
// ********* CREATE SWAP ********* // ********* CREATE SWAP *********
const createSwap = await api.post( const createSwap = await api.post(
`/admin/orders/${completedOrder.data.data.id}/swaps`, `/admin/orders/${completedOrder.data.data.id}/swaps?fields=returnable_items`,
{ {
return_items: [ return_items: [
{ {
@@ -318,6 +318,13 @@ describe("/admin/swaps", () => {
} }
) )
expect(createSwap.data.order.returnable_items).toHaveLength(1)
expect(createSwap.data.order.returnable_items[0]).toEqual(
expect.objectContaining({
id: "line-item",
})
)
let swap = createSwap.data.order.swaps[0] let swap = createSwap.data.order.swaps[0]
// ********* PREPARE SWAP CART ********* // ********* PREPARE SWAP CART *********
@@ -349,7 +356,7 @@ describe("/admin/swaps", () => {
{} {}
) )
// ********* VALIDATE ********* // ********* VALIDATE *********
expect(swap.data.swap.difference_due).toBe(swapCart.data.cart.total) expect(swap.data.swap.difference_due).toBe(swapCart.data.cart.total)
}) })
}) })
@@ -7,6 +7,7 @@ import { default as requireCustomerAuthentication } from "./require-customer-aut
export { canAccessBatchJob } from "./batch-job/can-access-batch-job" export { canAccessBatchJob } from "./batch-job/can-access-batch-job"
export { getRequestedBatchJob } from "./batch-job/get-requested-batch-job" export { getRequestedBatchJob } from "./batch-job/get-requested-batch-job"
export { doesConditionBelongToDiscount } from "./discount/does-condition-belong-to-discount" export { doesConditionBelongToDiscount } from "./discount/does-condition-belong-to-discount"
export { transformIncludesOptions } from "./transform-includes-options"
export { transformBody } from "./transform-body" export { transformBody } from "./transform-body"
export { transformQuery } from "./transform-query" export { transformQuery } from "./transform-query"
@@ -0,0 +1,58 @@
import { NextFunction, Request, Response } from "express"
import { Order } from "../../models"
import { MedusaError } from "medusa-core-utils"
/**
* Retrieve the includes options from the fields query param.
* If the include option is present then assigned it to includes on req
* @param allowedIncludesFields The list of fields that can be passed and assign to req.includes
* @param expectedIncludesFields The list of fields that the consumer can pass to the end point using this middleware. It is a subset of `allowedIncludesFields`
*/
export function transformIncludesOptions(
allowedIncludesFields: string[] = [],
expectedIncludesFields: string[] = []
) {
return (req: Request, res: Response, next: NextFunction): void => {
if (!allowedIncludesFields.length || !req.query["fields"]) {
return next()
}
const fields = (req.query["fields"] as string).split(",") ?? []
for (const includesField of allowedIncludesFields) {
const fieldIndex = fields.indexOf(includesField as keyof Order) ?? -1
const isPresent = fieldIndex !== -1
if (isPresent) {
fields.splice(fieldIndex, 1)
if (!expectedIncludesFields.includes(includesField)) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
`The field "${includesField}" is not supported by this end point. ${
expectedIncludesFields.length
? `The includes fields can be one of entity properties or in [${expectedIncludesFields.join(
", "
)}]`
: ""
}`
)
}
req["includes"] = req["includes"] ?? {}
req["includes"][includesField] = true
}
}
if (req.query["fields"]) {
if (fields.length) {
req.query["fields"] = fields.join(",")
} else {
delete req.query["fields"]
}
}
next()
}
}
@@ -53,6 +53,12 @@ export function transformQuery<
] as unknown as string[] ] as unknown as string[]
} }
const includesFields = Object.keys(req["includes"] ?? {})
if (includesFields.length) {
req.allowedProperties = req.allowedProperties ?? []
req.allowedProperties.push(...includesFields)
}
if (queryConfig?.isList) { if (queryConfig?.isList) {
req.listConfig = prepareListQuery( req.listConfig = prepareListQuery(
validated, validated,
@@ -48,6 +48,9 @@ describe("GET /admin/orders", () => {
), ),
// TODO [MEDUSA_FF_SALES_CHANNELS]: Remove when sales channel flag is removed entirely // TODO [MEDUSA_FF_SALES_CHANNELS]: Remove when sales channel flag is removed entirely
relations: [...defaultAdminOrdersRelations, "sales_channel"], relations: [...defaultAdminOrdersRelations, "sales_channel"],
},
{
includes: undefined,
} }
) )
}) })
@@ -5,11 +5,10 @@ import {
IsOptional, IsOptional,
IsString, IsString,
} from "class-validator" } from "class-validator"
import { defaultAdminOrdersFields, defaultAdminOrdersRelations } from "."
import { OrderService } from "../../../../services" import { OrderService } from "../../../../services"
import { validator } from "../../../../utils/validator"
import { EntityManager } from "typeorm" import { EntityManager } from "typeorm"
import { FindParams } from "../../../../types/common"
/** /**
* @oas [post] /orders/{id}/shipping-methods * @oas [post] /orders/{id}/shipping-methods
@@ -18,6 +17,8 @@ import { EntityManager } from "typeorm"
* description: "Adds a Shipping Method to an Order. If another Shipping Method exists with the same Shipping Profile, the previous Shipping Method will be replaced." * description: "Adds a Shipping Method to an Order. If another Shipping Method exists with the same Shipping Profile, the previous Shipping Method will be replaced."
* parameters: * parameters:
* - (path) id=* {string} The ID of the Order. * - (path) id=* {string} The ID of the Order.
* - (query) expand {string} Comma separated list of relations to include in the result.
* - (query) fields {string} Comma separated list of fields to include in the result.
* requestBody: * requestBody:
* content: * content:
* application/json: * application/json:
@@ -26,6 +27,7 @@ import { EntityManager } from "typeorm"
* x-authenticated: true * x-authenticated: true
* x-codegen: * x-codegen:
* method: addShippingMethod * method: addShippingMethod
* params: AdminPostOrdersOrderShippingMethodsParams
* x-codeSamples: * x-codeSamples:
* - lang: JavaScript * - lang: JavaScript
* label: JS Client * label: JS Client
@@ -78,10 +80,7 @@ import { EntityManager } from "typeorm"
export default async (req, res) => { export default async (req, res) => {
const { id } = req.params const { id } = req.params
const validated = await validator( const validated = req.validatedBody
AdminPostOrdersOrderShippingMethodsReq,
req.body
)
const orderService: OrderService = req.scope.resolve("orderService") const orderService: OrderService = req.scope.resolve("orderService")
@@ -94,9 +93,8 @@ export default async (req, res) => {
}) })
}) })
const order = await orderService.retrieve(id, { const order = await orderService.retrieveWithTotals(id, req.retrieveConfig, {
select: defaultAdminOrdersFields, includes: req.includes,
relations: defaultAdminOrdersRelations,
}) })
res.status(200).json({ order }) res.status(200).json({ order })
@@ -132,3 +130,5 @@ export class AdminPostOrdersOrderShippingMethodsReq {
@IsOptional() @IsOptional()
data?: Record<string, unknown> = {} data?: Record<string, unknown> = {}
} }
export class AdminPostOrdersOrderShippingMethodsParams extends FindParams {}
@@ -1,5 +1,6 @@
import { OrderService } from "../../../../services" import { OrderService } from "../../../../services"
import { EntityManager } from "typeorm" import { EntityManager } from "typeorm"
import { FindParams } from "../../../../types/common"
/** /**
* @oas [post] /orders/{id}/archive * @oas [post] /orders/{id}/archive
@@ -9,8 +10,11 @@ import { EntityManager } from "typeorm"
* x-authenticated: true * x-authenticated: true
* parameters: * parameters:
* - (path) id=* {string} The ID of the Order. * - (path) id=* {string} The ID of the Order.
* - (query) expand {string} Comma separated list of relations to include in the result.
* - (query) fields {string} Comma separated list of fields to include in the result.
* x-codegen: * x-codegen:
* method: archive * method: archive
* params: AdminPostOrdersOrderArchiveParams
* x-codeSamples: * x-codeSamples:
* - lang: JavaScript * - lang: JavaScript
* label: JS Client * label: JS Client
@@ -62,9 +66,11 @@ export default async (req, res) => {
return await orderService.withTransaction(transactionManager).archive(id) return await orderService.withTransaction(transactionManager).archive(id)
}) })
const order = await orderService.retrieve(id, { const order = await orderService.retrieveWithTotals(id, req.retrieveConfig, {
relations: ["region", "customer", "swaps"], includes: req.includes,
}) })
res.json({ order }) res.json({ order })
} }
export class AdminPostOrdersOrderArchiveParams extends FindParams {}
@@ -1,8 +1,8 @@
import { ClaimService, OrderService } from "../../../../services" import { ClaimService, OrderService } from "../../../../services"
import { defaultAdminOrdersFields, defaultAdminOrdersRelations } from "."
import { EntityManager } from "typeorm" import { EntityManager } from "typeorm"
import { MedusaError } from "medusa-core-utils" import { MedusaError } from "medusa-core-utils"
import { FindParams } from "../../../../types/common"
/** /**
* @oas [post] /orders/{id}/claims/{claim_id}/cancel * @oas [post] /orders/{id}/claims/{claim_id}/cancel
@@ -13,8 +13,11 @@ import { MedusaError } from "medusa-core-utils"
* parameters: * parameters:
* - (path) id=* {string} The ID of the Order. * - (path) id=* {string} The ID of the Order.
* - (path) claim_id=* {string} The ID of the Claim. * - (path) claim_id=* {string} The ID of the Claim.
* - (query) expand {string} Comma separated list of relations to include in the result.
* - (query) fields {string} Comma separated list of fields to include in the result.
* x-codegen: * x-codegen:
* method: cancelClaim * method: cancelClaim
* params: AdminPostOrdersClaimCancel
* x-codeSamples: * x-codeSamples:
* - lang: JavaScript * - lang: JavaScript
* label: JS Client * label: JS Client
@@ -78,10 +81,11 @@ export default async (req, res) => {
.cancel(claim_id) .cancel(claim_id)
}) })
const order = await orderService.retrieve(id, { const order = await orderService.retrieveWithTotals(id, req.retrieveConfig, {
select: defaultAdminOrdersFields, includes: req.includes,
relations: defaultAdminOrdersRelations,
}) })
res.json({ order }) res.json({ order })
} }
export class AdminPostOrdersClaimCancel extends FindParams {}
@@ -3,10 +3,10 @@ import {
FulfillmentService, FulfillmentService,
OrderService, OrderService,
} from "../../../../services" } from "../../../../services"
import { defaultAdminOrdersFields, defaultAdminOrdersRelations } from "."
import { EntityManager } from "typeorm" import { EntityManager } from "typeorm"
import { MedusaError } from "medusa-core-utils" import { MedusaError } from "medusa-core-utils"
import { FindParams } from "../../../../types/common"
/** /**
* @oas [post] /orders/{id}/claims/{claim_id}/fulfillments/{fulfillment_id}/cancel * @oas [post] /orders/{id}/claims/{claim_id}/fulfillments/{fulfillment_id}/cancel
@@ -18,8 +18,11 @@ import { MedusaError } from "medusa-core-utils"
* - (path) id=* {string} The ID of the Order which the Claim relates to. * - (path) id=* {string} The ID of the Order which the Claim relates to.
* - (path) claim_id=* {string} The ID of the Claim which the Fulfillment relates to. * - (path) claim_id=* {string} The ID of the Claim which the Fulfillment relates to.
* - (path) fulfillment_id=* {string} The ID of the Fulfillment. * - (path) fulfillment_id=* {string} The ID of the Fulfillment.
* - (query) expand {string} Comma separated list of relations to include in the result.
* - (query) fields {string} Comma separated list of fields to include in the result.
* x-codegen: * x-codegen:
* method: cancelClaimFulfillment * method: cancelClaimFulfillment
* params: AdminPostOrdersClaimFulfillmentsCancelParams
* x-codeSamples: * x-codeSamples:
* - lang: JavaScript * - lang: JavaScript
* label: JS Client * label: JS Client
@@ -94,9 +97,11 @@ export default async (req, res) => {
.cancelFulfillment(fulfillment_id) .cancelFulfillment(fulfillment_id)
}) })
const order = await orderService.retrieve(id, { const order = await orderService.retrieveWithTotals(id, req.retrieveConfig, {
select: defaultAdminOrdersFields, includes: req.includes,
relations: defaultAdminOrdersRelations,
}) })
res.json({ order }) res.json({ order })
} }
export class AdminPostOrdersClaimFulfillmentsCancelParams extends FindParams {}
@@ -3,10 +3,10 @@ import {
OrderService, OrderService,
SwapService, SwapService,
} from "../../../../services" } from "../../../../services"
import { defaultAdminOrdersFields, defaultAdminOrdersRelations } from "."
import { EntityManager } from "typeorm" import { EntityManager } from "typeorm"
import { MedusaError } from "medusa-core-utils" import { MedusaError } from "medusa-core-utils"
import { FindParams } from "../../../../types/common"
/** /**
* @oas [post] /orders/{id}/swaps/{swap_id}/fulfillments/{fulfillment_id}/cancel * @oas [post] /orders/{id}/swaps/{swap_id}/fulfillments/{fulfillment_id}/cancel
@@ -18,8 +18,11 @@ import { MedusaError } from "medusa-core-utils"
* - (path) id=* {string} The ID of the Order which the Swap relates to. * - (path) id=* {string} The ID of the Order which the Swap relates to.
* - (path) swap_id=* {string} The ID of the Swap which the Fulfillment relates to. * - (path) swap_id=* {string} The ID of the Swap which the Fulfillment relates to.
* - (path) fulfillment_id=* {string} The ID of the Fulfillment. * - (path) fulfillment_id=* {string} The ID of the Fulfillment.
* - (query) expand {string} Comma separated list of relations to include in the result.
* - (query) fields {string} Comma separated list of fields to include in the result.
* x-codegen: * x-codegen:
* method: cancelSwapFulfillment * method: cancelSwapFulfillment
* params: AdminPostOrdersSwapFulfillementsCancelParams
* x-codeSamples: * x-codeSamples:
* - lang: JavaScript * - lang: JavaScript
* label: JS Client * label: JS Client
@@ -94,10 +97,12 @@ export default async (req, res) => {
.cancelFulfillment(fulfillment_id) .cancelFulfillment(fulfillment_id)
}) })
const order = await orderService.retrieve(id, { const order = await orderService.retrieveWithTotals(id, req.retrieveConfig, {
select: defaultAdminOrdersFields, includes: req.includes,
relations: defaultAdminOrdersRelations,
}) })
res.json({ order }) res.json({ order })
} }
// eslint-disable-next-line max-len
export class AdminPostOrdersOrderSwapFulfillementsCancelParams extends FindParams {}
@@ -3,12 +3,12 @@ import {
OrderService, OrderService,
ProductVariantInventoryService, ProductVariantInventoryService,
} from "../../../../services" } from "../../../../services"
import { defaultAdminOrdersFields, defaultAdminOrdersRelations } from "."
import { EntityManager } from "typeorm" import { EntityManager } from "typeorm"
import { MedusaError } from "medusa-core-utils" import { MedusaError } from "medusa-core-utils"
import { Fulfillment } from "../../../../models" import { Fulfillment } from "../../../../models"
import { IInventoryService } from "../../../../interfaces" import { IInventoryService } from "../../../../interfaces"
import { FindParams } from "../../../../types/common"
/** /**
* @oas [post] /orders/{id}/fulfillments/{fulfillment_id}/cancel * @oas [post] /orders/{id}/fulfillments/{fulfillment_id}/cancel
@@ -19,8 +19,11 @@ import { IInventoryService } from "../../../../interfaces"
* parameters: * parameters:
* - (path) id=* {string} The ID of the Order which the Fulfillment relates to. * - (path) id=* {string} The ID of the Order which the Fulfillment relates to.
* - (path) fulfillment_id=* {string} The ID of the Fulfillment * - (path) fulfillment_id=* {string} The ID of the Fulfillment
* - (query) expand {string} Comma separated list of relations to include in the result.
* - (query) fields {string} Comma separated list of fields to include in the result.
* x-codegen: * x-codegen:
* method: cancelFulfillment * method: cancelFulfillment
* params: AdminPostOrdersOrderFulfillementsCancelParams
* x-codeSamples: * x-codeSamples:
* - lang: JavaScript * - lang: JavaScript
* label: JS Client * label: JS Client
@@ -101,9 +104,8 @@ export default async (req, res) => {
} }
}) })
const order = await orderService.retrieve(id, { const order = await orderService.retrieveWithTotals(id, req.retrieveConfig, {
select: defaultAdminOrdersFields, includes: req.includes,
relations: defaultAdminOrdersRelations,
}) })
res.json({ order }) res.json({ order })
@@ -128,3 +130,5 @@ export const adjustInventoryForCancelledFulfillment = async (
}) })
) )
} }
export class AdminPostOrdersOrderFulfillementsCancelParams extends FindParams {}
@@ -1,7 +1,6 @@
import { defaultAdminOrdersFields, defaultAdminOrdersRelations } from "."
import { OrderService } from "../../../../services" import { OrderService } from "../../../../services"
import { EntityManager } from "typeorm" import { EntityManager } from "typeorm"
import { FindParams } from "../../../../types/common"
/** /**
* @oas [post] /orders/{id}/cancel * @oas [post] /orders/{id}/cancel
@@ -11,8 +10,11 @@ import { EntityManager } from "typeorm"
* x-authenticated: true * x-authenticated: true
* parameters: * parameters:
* - (path) id=* {string} The ID of the Order. * - (path) id=* {string} The ID of the Order.
* - (query) expand {string} Comma separated list of relations to include in the result.
* - (query) fields {string} Comma separated list of fields to include in the result.
* x-codegen: * x-codegen:
* method: cancel * method: cancel
* params: AdminPostOrdersOrderCancel
* x-codeSamples: * x-codeSamples:
* - lang: JavaScript * - lang: JavaScript
* label: JS Client * label: JS Client
@@ -63,10 +65,11 @@ export default async (req, res) => {
return await orderService.withTransaction(transactionManager).cancel(id) return await orderService.withTransaction(transactionManager).cancel(id)
}) })
const order = await orderService.retrieve(id, { const order = await orderService.retrieveWithTotals(id, req.retrieveConfig, {
select: defaultAdminOrdersFields, includes: req.includes,
relations: defaultAdminOrdersRelations,
}) })
res.json({ order }) res.json({ order })
} }
export class AdminPostOrdersOrderCancel extends FindParams {}
@@ -1,8 +1,8 @@
import { OrderService, SwapService } from "../../../../services" import { OrderService, SwapService } from "../../../../services"
import { defaultAdminOrdersFields, defaultAdminOrdersRelations } from "."
import { EntityManager } from "typeorm" import { EntityManager } from "typeorm"
import { MedusaError } from "medusa-core-utils" import { MedusaError } from "medusa-core-utils"
import { FindParams } from "../../../../types/common"
/** /**
* @oas [post] /orders/{id}/swaps/{swap_id}/cancel * @oas [post] /orders/{id}/swaps/{swap_id}/cancel
@@ -13,8 +13,11 @@ import { MedusaError } from "medusa-core-utils"
* parameters: * parameters:
* - (path) id=* {string} The ID of the Order. * - (path) id=* {string} The ID of the Order.
* - (path) swap_id=* {string} The ID of the Swap. * - (path) swap_id=* {string} The ID of the Swap.
* - (query) expand {string} Comma separated list of relations to include in the result.
* - (query) fields {string} Comma separated list of fields to include in the result.
* x-codegen: * x-codegen:
* method: cancelSwap * method: cancelSwap
* params: AdminPostOrdersSwapCancelParams
* x-codeSamples: * x-codeSamples:
* - lang: JavaScript * - lang: JavaScript
* label: JS Client * label: JS Client
@@ -76,10 +79,11 @@ export default async (req, res) => {
return await swapService.withTransaction(transactionManager).cancel(swap_id) return await swapService.withTransaction(transactionManager).cancel(swap_id)
}) })
const order = await orderService.retrieve(id, { const order = await orderService.retrieveWithTotals(id, req.retrieveConfig, {
select: defaultAdminOrdersFields, includes: req.includes,
relations: defaultAdminOrdersRelations,
}) })
res.json({ order }) res.json({ order })
} }
export class AdminPostOrdersSwapCancelParams extends FindParams {}
@@ -1,7 +1,6 @@
import { defaultAdminOrdersFields, defaultAdminOrdersRelations } from "."
import { OrderService } from "../../../../services" import { OrderService } from "../../../../services"
import { EntityManager } from "typeorm" import { EntityManager } from "typeorm"
import { FindParams } from "../../../../types/common"
/** /**
* @oas [post] /orders/{id}/capture * @oas [post] /orders/{id}/capture
@@ -11,8 +10,11 @@ import { EntityManager } from "typeorm"
* x-authenticated: true * x-authenticated: true
* parameters: * parameters:
* - (path) id=* {string} The ID of the Order. * - (path) id=* {string} The ID of the Order.
* - (query) expand {string} Comma separated list of relations to include in the result.
* - (query) fields {string} Comma separated list of fields to include in the result.
* x-codegen: * x-codegen:
* method: capturePayment * method: capturePayment
* params: AdminPostOrdersOrderCaptureParams
* x-codeSamples: * x-codeSamples:
* - lang: JavaScript * - lang: JavaScript
* label: JS Client * label: JS Client
@@ -66,10 +68,11 @@ export default async (req, res) => {
.capturePayment(id) .capturePayment(id)
}) })
const order = await orderService.retrieve(id, { const order = await orderService.retrieveWithTotals(id, req.retrieveConfig, {
select: defaultAdminOrdersFields, includes: req.includes,
relations: defaultAdminOrdersRelations,
}) })
res.json({ order }) res.json({ order })
} }
export class AdminPostOrdersOrderCaptureParams extends FindParams {}
@@ -1,5 +1,6 @@
import { OrderService } from "../../../../services" import { OrderService } from "../../../../services"
import { EntityManager } from "typeorm" import { EntityManager } from "typeorm"
import { FindParams } from "../../../../types/common"
/** /**
* @oas [post] /orders/{id}/complete * @oas [post] /orders/{id}/complete
@@ -9,8 +10,11 @@ import { EntityManager } from "typeorm"
* x-authenticated: true * x-authenticated: true
* parameters: * parameters:
* - (path) id=* {string} The ID of the Order. * - (path) id=* {string} The ID of the Order.
* - (query) expand {string} Comma separated list of relations to include in the result.
* - (query) fields {string} Comma separated list of fields to include in the result.
* x-codegen: * x-codegen:
* method: complete * method: complete
* params: AdminPostOrdersOrderCompleteParams
* x-codeSamples: * x-codeSamples:
* - lang: JavaScript * - lang: JavaScript
* label: JS Client * label: JS Client
@@ -64,9 +68,11 @@ export default async (req, res) => {
.completeOrder(id) .completeOrder(id)
}) })
const order = await orderService.retrieve(id, { const order = await orderService.retrieveWithTotals(id, req.retrieveConfig, {
relations: ["region", "customer", "swaps"], includes: req.includes,
}) })
res.json({ order }) res.json({ order })
} }
export class AdminPostOrdersOrderCompleteParams extends FindParams {}
@@ -1,9 +1,7 @@
import { ClaimService, OrderService } from "../../../../services" import { ClaimService, OrderService } from "../../../../services"
import { IsArray, IsNotEmpty, IsOptional, IsString } from "class-validator" import { IsArray, IsNotEmpty, IsOptional, IsString } from "class-validator"
import { defaultAdminOrdersFields, defaultAdminOrdersRelations } from "."
import { validator } from "../../../../utils/validator"
import { EntityManager } from "typeorm" import { EntityManager } from "typeorm"
import { FindParams } from "../../../../types/common"
/** /**
* @oas [post] /orders/{id}/claims/{claim_id}/shipments * @oas [post] /orders/{id}/claims/{claim_id}/shipments
@@ -14,6 +12,8 @@ import { EntityManager } from "typeorm"
* parameters: * parameters:
* - (path) id=* {string} The ID of the Order. * - (path) id=* {string} The ID of the Order.
* - (path) claim_id=* {string} The ID of the Claim. * - (path) claim_id=* {string} The ID of the Claim.
* - (query) expand {string} Comma separated list of relations to include in the result.
* - (query) fields {string} Comma separated list of fields to include in the result.
* requestBody: * requestBody:
* content: * content:
* application/json: * application/json:
@@ -21,6 +21,7 @@ import { EntityManager } from "typeorm"
* $ref: "#/components/schemas/AdminPostOrdersOrderClaimsClaimShipmentsReq" * $ref: "#/components/schemas/AdminPostOrdersOrderClaimsClaimShipmentsReq"
* x-codegen: * x-codegen:
* method: createClaimShipment * method: createClaimShipment
* params: AdminPostOrdersOrderClaimsClaimShipmentsParams
* x-codeSamples: * x-codeSamples:
* - lang: JavaScript * - lang: JavaScript
* label: JS Client * label: JS Client
@@ -71,10 +72,7 @@ import { EntityManager } from "typeorm"
export default async (req, res) => { export default async (req, res) => {
const { id, claim_id } = req.params const { id, claim_id } = req.params
const validated = await validator( const validated = req.validatedBody
AdminPostOrdersOrderClaimsClaimShipmentsReq,
req.body
)
const orderService: OrderService = req.scope.resolve("orderService") const orderService: OrderService = req.scope.resolve("orderService")
const claimService: ClaimService = req.scope.resolve("claimService") const claimService: ClaimService = req.scope.resolve("claimService")
@@ -90,9 +88,8 @@ export default async (req, res) => {
) )
}) })
const order = await orderService.retrieve(id, { const order = await orderService.retrieveWithTotals(id, req.retrieveConfig, {
select: defaultAdminOrdersFields, includes: req.includes,
relations: defaultAdminOrdersRelations,
}) })
res.json({ order }) res.json({ order })
@@ -123,3 +120,6 @@ export class AdminPostOrdersOrderClaimsClaimShipmentsReq {
@IsString({ each: true }) @IsString({ each: true })
tracking_numbers?: string[] tracking_numbers?: string[]
} }
// eslint-disable-next-line max-len
export class AdminPostOrdersOrderClaimsClaimShipmentsParams extends FindParams {}
@@ -9,15 +9,13 @@ import {
IsString, IsString,
ValidateNested, ValidateNested,
} from "class-validator" } from "class-validator"
import { defaultAdminOrdersFields, defaultAdminOrdersRelations } from "."
import { ClaimReason, ClaimType } from "../../../../models" import { ClaimReason, ClaimType } from "../../../../models"
import { Type } from "class-transformer" import { Type } from "class-transformer"
import { MedusaError } from "medusa-core-utils" import { MedusaError } from "medusa-core-utils"
import { EntityManager } from "typeorm" import { EntityManager } from "typeorm"
import { ClaimTypeValue } from "../../../../types/claim" import { ClaimTypeValue } from "../../../../types/claim"
import { AddressPayload } from "../../../../types/common" import { AddressPayload, FindParams } from "../../../../types/common"
import { validator } from "../../../../utils/validator"
/** /**
* @oas [post] /order/{id}/claims * @oas [post] /order/{id}/claims
@@ -27,6 +25,8 @@ import { validator } from "../../../../utils/validator"
* x-authenticated: true * x-authenticated: true
* parameters: * parameters:
* - (path) id=* {string} The ID of the Order. * - (path) id=* {string} The ID of the Order.
* - (query) expand {string} Comma separated list of relations to include in the result.
* - (query) fields {string} Comma separated list of fields to include in the result.
* requestBody: * requestBody:
* content: * content:
* application/json: * application/json:
@@ -34,6 +34,7 @@ import { validator } from "../../../../utils/validator"
* $ref: "#/components/schemas/AdminPostOrdersOrderClaimsReq" * $ref: "#/components/schemas/AdminPostOrdersOrderClaimsReq"
* x-codegen: * x-codegen:
* method: createClaim * method: createClaim
* params: AdminPostOrdersOrderClaimsParams
* x-codeSamples: * x-codeSamples:
* - lang: JavaScript * - lang: JavaScript
* label: JS Client * label: JS Client
@@ -97,7 +98,7 @@ import { validator } from "../../../../utils/validator"
export default async (req, res) => { export default async (req, res) => {
const { id } = req.params const { id } = req.params
const value = await validator(AdminPostOrdersOrderClaimsReq, req.body) const value = req.validatedBody
const idempotencyKeyService = req.scope.resolve("idempotencyKeyService") const idempotencyKeyService = req.scope.resolve("idempotencyKeyService")
const manager: EntityManager = req.scope.resolve("manager") const manager: EntityManager = req.scope.resolve("manager")
@@ -247,9 +248,8 @@ export default async (req, res) => {
order = await orderService order = await orderService
.withTransaction(manager) .withTransaction(manager)
.retrieve(id, { .retrieveWithTotals(id, req.retrieveConfig, {
select: defaultAdminOrdersFields, includes: req.includes,
relations: defaultAdminOrdersRelations,
}) })
return { return {
@@ -508,3 +508,5 @@ class AdditionalItem {
@IsNotEmpty() @IsNotEmpty()
quantity: number quantity: number
} }
export class AdminPostOrdersOrderClaimsParams extends FindParams {}
@@ -9,16 +9,15 @@ import {
ValidateNested, ValidateNested,
} from "class-validator" } from "class-validator"
import { Transform, Type } from "class-transformer" import { Transform, Type } from "class-transformer"
import { defaultAdminOrdersFields, defaultAdminOrdersRelations } from "."
import { EntityManager } from "typeorm" import { EntityManager } from "typeorm"
import { import {
OrderService, OrderService,
ProductVariantInventoryService, ProductVariantInventoryService,
} from "../../../../services" } from "../../../../services"
import { validator } from "../../../../utils/validator"
import { optionalBooleanMapper } from "../../../../utils/validators/is-boolean" import { optionalBooleanMapper } from "../../../../utils/validators/is-boolean"
import { Fulfillment, LineItem } from "../../../../models" import { Fulfillment, LineItem } from "../../../../models"
import { FindParams } from "../../../../types/common"
/** /**
* @oas [post] /orders/{id}/fulfillment * @oas [post] /orders/{id}/fulfillment
@@ -28,6 +27,8 @@ import { Fulfillment, LineItem } from "../../../../models"
* x-authenticated: true * x-authenticated: true
* parameters: * parameters:
* - (path) id=* {string} The ID of the Order. * - (path) id=* {string} The ID of the Order.
* - (query) expand {string} Comma separated list of relations to include in the result.
* - (query) fields {string} Comma separated list of fields to include in the result.
* requestBody: * requestBody:
* content: * content:
* application/json: * application/json:
@@ -35,6 +36,7 @@ import { Fulfillment, LineItem } from "../../../../models"
* $ref: "#/components/schemas/AdminPostOrdersOrderFulfillmentsReq" * $ref: "#/components/schemas/AdminPostOrdersOrderFulfillmentsReq"
* x-codegen: * x-codegen:
* method: createFulfillment * method: createFulfillment
* params: AdminPostOrdersOrderFulfillmentsParams
* x-codeSamples: * x-codeSamples:
* - lang: JavaScript * - lang: JavaScript
* label: JS Client * label: JS Client
@@ -95,10 +97,7 @@ import { Fulfillment, LineItem } from "../../../../models"
export default async (req, res) => { export default async (req, res) => {
const { id } = req.params const { id } = req.params
const validated = await validator( const validated = req.validatedBody
AdminPostOrdersOrderFulfillmentsReq,
req.body
)
const orderService: OrderService = req.scope.resolve("orderService") const orderService: OrderService = req.scope.resolve("orderService")
const pvInventoryService: ProductVariantInventoryService = req.scope.resolve( const pvInventoryService: ProductVariantInventoryService = req.scope.resolve(
@@ -136,9 +135,8 @@ export default async (req, res) => {
} }
}) })
const order = await orderService.retrieve(id, { const order = await orderService.retrieveWithTotals(id, req.retrieveConfig, {
select: defaultAdminOrdersFields, includes: req.includes,
relations: defaultAdminOrdersRelations,
}) })
res.json({ order }) res.json({ order })
@@ -239,3 +237,5 @@ class Item {
@IsNotEmpty() @IsNotEmpty()
quantity: number quantity: number
} }
export class AdminPostOrdersOrderFulfillmentsParams extends FindParams {}
@@ -5,12 +5,11 @@ import {
IsOptional, IsOptional,
IsString, IsString,
} from "class-validator" } from "class-validator"
import { defaultAdminOrdersFields, defaultAdminOrdersRelations } from "."
import { EntityManager } from "typeorm" import { EntityManager } from "typeorm"
import { OrderService } from "../../../../services" import { OrderService } from "../../../../services"
import { TrackingLink } from "../../../../models" import { TrackingLink } from "../../../../models"
import { validator } from "../../../../utils/validator" import { FindParams } from "../../../../types/common"
/** /**
* @oas [post] /orders/{id}/shipment * @oas [post] /orders/{id}/shipment
@@ -20,6 +19,8 @@ import { validator } from "../../../../utils/validator"
* x-authenticated: true * x-authenticated: true
* parameters: * parameters:
* - (path) id=* {string} The ID of the Order. * - (path) id=* {string} The ID of the Order.
* - (query) expand {string} Comma separated list of relations to include in the result.
* - (query) fields {string} Comma separated list of fields to include in the result.
* requestBody: * requestBody:
* content: * content:
* application/json: * application/json:
@@ -27,6 +28,7 @@ import { validator } from "../../../../utils/validator"
* $ref: "#/components/schemas/AdminPostOrdersOrderShipmentReq" * $ref: "#/components/schemas/AdminPostOrdersOrderShipmentReq"
* x-codegen: * x-codegen:
* method: createShipment * method: createShipment
* params: AdminPostOrdersOrderShipmentParams
* x-codeSamples: * x-codeSamples:
* - lang: JavaScript * - lang: JavaScript
* label: JS Client * label: JS Client
@@ -77,7 +79,7 @@ import { validator } from "../../../../utils/validator"
export default async (req, res) => { export default async (req, res) => {
const { id } = req.params const { id } = req.params
const validated = await validator(AdminPostOrdersOrderShipmentReq, req.body) const validated = req.validatedBody
const orderService: OrderService = req.scope.resolve("orderService") const orderService: OrderService = req.scope.resolve("orderService")
@@ -98,9 +100,8 @@ export default async (req, res) => {
) )
}) })
const order = await orderService.retrieve(id, { const order = await orderService.retrieveWithTotals(id, req.retrieveConfig, {
select: defaultAdminOrdersFields, includes: req.includes,
relations: defaultAdminOrdersRelations,
}) })
res.json({ order }) res.json({ order })
@@ -138,3 +139,5 @@ export class AdminPostOrdersOrderShipmentReq {
@IsOptional() @IsOptional()
no_notification?: boolean no_notification?: boolean
} }
export class AdminPostOrdersOrderShipmentParams extends FindParams {}
@@ -6,10 +6,10 @@ import {
IsString, IsString,
} from "class-validator" } from "class-validator"
import { OrderService, SwapService } from "../../../../services" import { OrderService, SwapService } from "../../../../services"
import { defaultAdminOrdersFields, defaultAdminOrdersRelations } from "."
import { EntityManager } from "typeorm" import { EntityManager } from "typeorm"
import { validator } from "../../../../utils/validator" import { validator } from "../../../../utils/validator"
import { FindParams } from "../../../../types/common"
/** /**
* @oas [post] /orders/{id}/swaps/{swap_id}/shipments * @oas [post] /orders/{id}/swaps/{swap_id}/shipments
@@ -20,6 +20,8 @@ import { validator } from "../../../../utils/validator"
* parameters: * parameters:
* - (path) id=* {string} The ID of the Order. * - (path) id=* {string} The ID of the Order.
* - (path) swap_id=* {string} The ID of the Swap. * - (path) swap_id=* {string} The ID of the Swap.
* - (query) expand {string} Comma separated list of relations to include in the result.
* - (query) fields {string} Comma separated list of fields to include in the result.
* requestBody: * requestBody:
* content: * content:
* application/json: * application/json:
@@ -27,6 +29,7 @@ import { validator } from "../../../../utils/validator"
* $ref: "#/components/schemas/AdminPostOrdersOrderSwapsSwapShipmentsReq" * $ref: "#/components/schemas/AdminPostOrdersOrderSwapsSwapShipmentsReq"
* x-codegen: * x-codegen:
* method: createSwapShipment * method: createSwapShipment
* params: AdminPostOrdersOrderSwapsSwapShipmentsParams
* x-codeSamples: * x-codeSamples:
* - lang: JavaScript * - lang: JavaScript
* label: JS Client * label: JS Client
@@ -95,9 +98,8 @@ export default async (req, res) => {
) )
}) })
const order = await orderService.retrieve(id, { const order = await orderService.retrieveWithTotals(id, req.retrieveConfig, {
select: defaultAdminOrdersFields, includes: req.includes,
relations: defaultAdminOrdersRelations,
}) })
res.json({ order }) res.json({ order })
@@ -135,3 +137,5 @@ export class AdminPostOrdersOrderSwapsSwapShipmentsReq {
@IsOptional() @IsOptional()
no_notification?: boolean no_notification?: boolean
} }
export class AdminPostOrdersOrderSwapsSwapShipmentsParams extends FindParams {}
@@ -16,12 +16,11 @@ import {
Min, Min,
ValidateNested, ValidateNested,
} from "class-validator" } from "class-validator"
import { defaultAdminOrdersFields, defaultAdminOrdersRelations } from "."
import { EntityManager } from "typeorm" import { EntityManager } from "typeorm"
import { MedusaError } from "medusa-core-utils" import { MedusaError } from "medusa-core-utils"
import { Type } from "class-transformer" import { Type } from "class-transformer"
import { validator } from "../../../../utils/validator" import { FindParams } from "../../../../types/common"
/** /**
* @oas [post] /order/{id}/swaps * @oas [post] /order/{id}/swaps
@@ -31,6 +30,8 @@ import { validator } from "../../../../utils/validator"
* x-authenticated: true * x-authenticated: true
* parameters: * parameters:
* - (path) id=* {string} The ID of the Order. * - (path) id=* {string} The ID of the Order.
* - (query) expand {string} (Comma separated) Which fields should be expanded the order of the result.
* - (query) fields {string} (Comma separated) Which fields should be included the order of the result.
* requestBody: * requestBody:
* content: * content:
* application/json: * application/json:
@@ -38,6 +39,7 @@ import { validator } from "../../../../utils/validator"
* $ref: "#/components/schemas/AdminPostOrdersOrderSwapsReq" * $ref: "#/components/schemas/AdminPostOrdersOrderSwapsReq"
* x-codegen: * x-codegen:
* method: createSwap * method: createSwap
* queryParams: AdminPostOrdersOrderSwapsParams
* x-codeSamples: * x-codeSamples:
* - lang: JavaScript * - lang: JavaScript
* label: JS Client * label: JS Client
@@ -98,7 +100,7 @@ import { validator } from "../../../../utils/validator"
export default async (req, res) => { export default async (req, res) => {
const { id } = req.params const { id } = req.params
const validated = await validator(AdminPostOrdersOrderSwapsReq, req.body) const validated = req.validatedBody
const idempotencyKeyService: IdempotencyKeyService = req.scope.resolve( const idempotencyKeyService: IdempotencyKeyService = req.scope.resolve(
"idempotencyKeyService" "idempotencyKeyService"
@@ -208,9 +210,8 @@ export default async (req, res) => {
const order = await orderService const order = await orderService
.withTransaction(transactionManager) .withTransaction(transactionManager)
.retrieve(id, { .retrieveWithTotals(id, req.retrieveConfig, {
select: defaultAdminOrdersFields, includes: req.includes,
relations: defaultAdminOrdersRelations,
}) })
return { return {
@@ -411,3 +412,5 @@ class AdditionalItem {
@IsNotEmpty() @IsNotEmpty()
quantity: number quantity: number
} }
export class AdminPostOrdersOrderSwapsParams extends FindParams {}
@@ -1,9 +1,8 @@
import { ClaimService, OrderService } from "../../../../services" import { ClaimService, OrderService } from "../../../../services"
import { IsBoolean, IsObject, IsOptional } from "class-validator" import { IsBoolean, IsObject, IsOptional } from "class-validator"
import { defaultAdminOrdersFields, defaultAdminOrdersRelations } from "."
import { EntityManager } from "typeorm" import { EntityManager } from "typeorm"
import { validator } from "../../../../utils/validator" import { FindParams } from "../../../../types/common"
/** /**
* @oas [post] /orders/{id}/claims/{claim_id}/fulfillments * @oas [post] /orders/{id}/claims/{claim_id}/fulfillments
@@ -14,6 +13,8 @@ import { validator } from "../../../../utils/validator"
* parameters: * parameters:
* - (path) id=* {string} The ID of the Order. * - (path) id=* {string} The ID of the Order.
* - (path) claim_id=* {string} The ID of the Claim. * - (path) claim_id=* {string} The ID of the Claim.
* - (query) expand {string} Comma separated list of relations to include in the result.
* - (query) fields {string} Comma separated list of fields to include in the result.
* requestBody: * requestBody:
* content: * content:
* application/json: * application/json:
@@ -21,6 +22,7 @@ import { validator } from "../../../../utils/validator"
* $ref: "#/components/schemas/AdminPostOrdersOrderClaimsClaimFulfillmentsReq" * $ref: "#/components/schemas/AdminPostOrdersOrderClaimsClaimFulfillmentsReq"
* x-codegen: * x-codegen:
* method: fulfillClaim * method: fulfillClaim
* params: AdminPostOrdersOrderClaimsClaimFulfillmentsReq
* x-codeSamples: * x-codeSamples:
* - lang: JavaScript * - lang: JavaScript
* label: JS Client * label: JS Client
@@ -65,10 +67,7 @@ import { validator } from "../../../../utils/validator"
export default async (req, res) => { export default async (req, res) => {
const { id, claim_id } = req.params const { id, claim_id } = req.params
const validated = await validator( const validated = req.validatedBody
AdminPostOrdersOrderClaimsClaimFulfillmentsReq,
req.body
)
const orderService: OrderService = req.scope.resolve("orderService") const orderService: OrderService = req.scope.resolve("orderService")
const claimService: ClaimService = req.scope.resolve("claimService") const claimService: ClaimService = req.scope.resolve("claimService")
@@ -81,9 +80,8 @@ export default async (req, res) => {
}) })
}) })
const order = await orderService.retrieve(id, { const order = await orderService.retrieveWithTotals(id, req.retrieveConfig, {
select: defaultAdminOrdersFields, includes: req.includes,
relations: defaultAdminOrdersRelations,
}) })
res.status(200).json({ order }) res.status(200).json({ order })
@@ -109,3 +107,6 @@ export class AdminPostOrdersOrderClaimsClaimFulfillmentsReq {
@IsOptional() @IsOptional()
no_notification?: boolean no_notification?: boolean
} }
// eslint-disable-next-line max-len
export class AdminPostOrdersOrderClaimsClaimFulfillmentsParams extends FindParams {}
@@ -1,9 +1,9 @@
import { IsBoolean, IsObject, IsOptional } from "class-validator" import { IsBoolean, IsObject, IsOptional } from "class-validator"
import { OrderService, SwapService } from "../../../../services" import { OrderService, SwapService } from "../../../../services"
import { defaultAdminOrdersFields, defaultAdminOrdersRelations } from "."
import { EntityManager } from "typeorm" import { EntityManager } from "typeorm"
import { validator } from "../../../../utils/validator" import { validator } from "../../../../utils/validator"
import { FindParams } from "../../../../types/common"
/** /**
* @oas [post] /orders/{id}/swaps/{swap_id}/fulfillments * @oas [post] /orders/{id}/swaps/{swap_id}/fulfillments
@@ -14,6 +14,8 @@ import { validator } from "../../../../utils/validator"
* parameters: * parameters:
* - (path) id=* {string} The ID of the Order. * - (path) id=* {string} The ID of the Order.
* - (path) swap_id=* {string} The ID of the Swap. * - (path) swap_id=* {string} The ID of the Swap.
* - (query) expand {string} Comma separated list of relations to include in the result.
* - (query) fields {string} Comma separated list of fields to include in the result.
* requestBody: * requestBody:
* content: * content:
* application/json: * application/json:
@@ -21,6 +23,7 @@ import { validator } from "../../../../utils/validator"
* $ref: "#/components/schemas/AdminPostOrdersOrderSwapsSwapFulfillmentsReq" * $ref: "#/components/schemas/AdminPostOrdersOrderSwapsSwapFulfillmentsReq"
* x-codegen: * x-codegen:
* method: fulfillSwap * method: fulfillSwap
* params: AdminPostOrdersOrderSwapsSwapFulfillmentsParams
* x-codeSamples: * x-codeSamples:
* - lang: JavaScript * - lang: JavaScript
* label: JS Client * label: JS Client
@@ -81,9 +84,8 @@ export default async (req, res) => {
}) })
}) })
const order = await orderService.retrieve(id, { const order = await orderService.retrieveWithTotals(id, req.retrieveConfig, {
select: defaultAdminOrdersFields, includes: req.includes,
relations: defaultAdminOrdersRelations,
}) })
res.status(200).json({ order }) res.status(200).json({ order })
@@ -109,3 +111,6 @@ export class AdminPostOrdersOrderSwapsSwapFulfillmentsReq {
@IsOptional() @IsOptional()
no_notification?: boolean no_notification?: boolean
} }
// eslint-disable-next-line max-len
export class AdminPostOrdersOrderSwapsSwapFulfillmentsParams extends FindParams {}
@@ -60,9 +60,11 @@ export default async (req, res) => {
const orderService: OrderService = req.scope.resolve("orderService") const orderService: OrderService = req.scope.resolve("orderService")
const order = await orderService.retrieveWithTotals(id, req.retrieveConfig) const order = await orderService.retrieveWithTotals(id, req.retrieveConfig, {
includes: req.includes,
})
res.json({ order }) res.json({ order: order })
} }
export class AdminGetOrdersOrderParams extends FindParams {} export class AdminGetOrdersOrderParams extends FindParams {}
@@ -6,12 +6,72 @@ import { FindParams, PaginatedResponse } from "../../../../types/common"
import { FlagRouter } from "../../../../utils/flag-router" import { FlagRouter } from "../../../../utils/flag-router"
import middlewares, { import middlewares, {
transformBody, transformBody,
transformIncludesOptions,
transformQuery, transformQuery,
} from "../../../middlewares" } from "../../../middlewares"
import { checkRegisteredModules } from "../../../middlewares/check-registered-modules" import { checkRegisteredModules } from "../../../middlewares/check-registered-modules"
import { AdminOrdersOrderLineItemReservationReq } from "./create-reservation-for-line-item" import { AdminOrdersOrderLineItemReservationReq } from "./create-reservation-for-line-item"
import { AdminGetOrdersOrderReservationsParams } from "./get-reservations" import { AdminGetOrdersOrderReservationsParams } from "./get-reservations"
import { AdminGetOrdersParams } from "./list-orders" import { AdminGetOrdersParams } from "./list-orders"
import {
AdminPostOrdersOrderSwapsParams,
AdminPostOrdersOrderSwapsReq,
} from "./create-swap"
import {
AdminPostOrdersOrderParams,
AdminPostOrdersOrderReq,
} from "./update-order"
import { AdminPostOrdersOrderCompleteParams } from "./complete-order"
import {
AdminPostOrdersOrderRefundsParams,
AdminPostOrdersOrderRefundsReq,
} from "./refund-payment"
import { AdminPostOrdersOrderCaptureParams } from "./capture-payment"
import {
AdminPostOrdersOrderFulfillmentsParams,
AdminPostOrdersOrderFulfillmentsReq,
} from "./create-fulfillment"
import { AdminPostOrdersOrderFulfillementsCancelParams } from "./cancel-fulfillment"
import { AdminPostOrdersOrderSwapFulfillementsCancelParams } from "./cancel-fulfillment-swap"
import { AdminPostOrdersClaimFulfillmentsCancelParams } from "./cancel-fulfillment-claim"
import {
AdminPostOrdersOrderShipmentParams,
AdminPostOrdersOrderShipmentReq,
} from "./create-shipment"
import {
AdminPostOrdersOrderReturnsParams,
AdminPostOrdersOrderReturnsReq,
} from "./request-return"
import { AdminPostOrdersOrderCancel } from "./cancel-order"
import {
AdminPostOrdersOrderShippingMethodsParams,
AdminPostOrdersOrderShippingMethodsReq,
} from "./add-shipping-method"
import { AdminPostOrdersOrderArchiveParams } from "./archive-order"
import { AdminPostOrdersSwapCancelParams } from "./cancel-swap"
import { AdminPostOrdersOrderSwapsSwapFulfillmentsParams } from "./fulfill-swap"
import {
AdminPostOrdersOrderSwapsSwapShipmentsParams,
AdminPostOrdersOrderSwapsSwapShipmentsReq,
} from "./create-swap-shipment"
import { AdminPostOrdersOrderSwapsSwapProcessPaymentParams } from "./process-swap-payment"
import {
AdminPostOrdersOrderClaimsParams,
AdminPostOrdersOrderClaimsReq,
} from "./create-claim"
import { AdminPostOrdersClaimCancel } from "./cancel-claim"
import {
AdminPostOrdersOrderClaimsClaimParams,
AdminPostOrdersOrderClaimsClaimReq,
} from "./update-claim"
import {
AdminPostOrdersOrderClaimsClaimFulfillmentsParams,
AdminPostOrdersOrderClaimsClaimFulfillmentsReq,
} from "./fulfill-claim"
import {
AdminPostOrdersOrderClaimsClaimShipmentsParams,
AdminPostOrdersOrderClaimsClaimShipmentsReq,
} from "./create-claim-shipment"
const route = Router() const route = Router()
@@ -31,6 +91,7 @@ export default (app, featureFlagRouter: FlagRouter) => {
*/ */
route.get( route.get(
"/", "/",
transformIncludesOptions(allowedOrderIncludesFields),
transformQuery(AdminGetOrdersParams, { transformQuery(AdminGetOrdersParams, {
defaultRelations: relations, defaultRelations: relations,
defaultFields: defaultAdminOrdersFields, defaultFields: defaultAdminOrdersFields,
@@ -44,21 +105,12 @@ export default (app, featureFlagRouter: FlagRouter) => {
*/ */
route.get( route.get(
"/:id", "/:id",
transformQuery(FindParams, { transformIncludesOptions(allowedOrderIncludesFields, [
AvailableOrderIncludesFields.RETURNABLE_ITEMS,
]),
transformQuery(AdminPostOrdersOrderParams, {
defaultRelations: relations, defaultRelations: relations,
defaultFields: defaultFields.filter((field) => { defaultFields: defaultFields,
return ![
"shipping_total",
"discount_total",
"tax_total",
"refunded_total",
"total",
"subtotal",
"refundable_amount",
"gift_card_total",
"gift_card_tax_total",
].includes(field)
}),
isList: false, isList: false,
}), }),
middlewares.wrap(require("./get-order").default) middlewares.wrap(require("./get-order").default)
@@ -67,13 +119,29 @@ export default (app, featureFlagRouter: FlagRouter) => {
/** /**
* Update an order * Update an order
*/ */
route.post("/:id", middlewares.wrap(require("./update-order").default)) route.post(
"/:id",
transformIncludesOptions(allowedOrderIncludesFields),
transformBody(AdminPostOrdersOrderReq),
transformQuery(FindParams, {
defaultRelations: relations,
defaultFields: defaultFields,
isList: false,
}),
middlewares.wrap(require("./update-order").default)
)
/** /**
* Mark an order as completed * Mark an order as completed
*/ */
route.post( route.post(
"/:id/complete", "/:id/complete",
transformIncludesOptions(allowedOrderIncludesFields),
transformQuery(AdminPostOrdersOrderCompleteParams, {
defaultRelations: relations,
defaultFields: defaultFields,
isList: false,
}),
middlewares.wrap(require("./complete-order").default) middlewares.wrap(require("./complete-order").default)
) )
@@ -82,6 +150,13 @@ export default (app, featureFlagRouter: FlagRouter) => {
*/ */
route.post( route.post(
"/:id/refund", "/:id/refund",
transformIncludesOptions(allowedOrderIncludesFields),
transformBody(AdminPostOrdersOrderRefundsReq),
transformQuery(AdminPostOrdersOrderRefundsParams, {
defaultRelations: relations,
defaultFields: defaultFields,
isList: false,
}),
middlewares.wrap(require("./refund-payment").default) middlewares.wrap(require("./refund-payment").default)
) )
@@ -90,6 +165,12 @@ export default (app, featureFlagRouter: FlagRouter) => {
*/ */
route.post( route.post(
"/:id/capture", "/:id/capture",
transformIncludesOptions(allowedOrderIncludesFields),
transformQuery(AdminPostOrdersOrderCaptureParams, {
defaultRelations: relations,
defaultFields: defaultFields,
isList: false,
}),
middlewares.wrap(require("./capture-payment").default) middlewares.wrap(require("./capture-payment").default)
) )
@@ -98,6 +179,13 @@ export default (app, featureFlagRouter: FlagRouter) => {
*/ */
route.post( route.post(
"/:id/fulfillment", "/:id/fulfillment",
transformIncludesOptions(allowedOrderIncludesFields),
transformBody(AdminPostOrdersOrderFulfillmentsReq),
transformQuery(AdminPostOrdersOrderFulfillmentsParams, {
defaultRelations: relations,
defaultFields: defaultFields,
isList: false,
}),
middlewares.wrap(require("./create-fulfillment").default) middlewares.wrap(require("./create-fulfillment").default)
) )
@@ -106,6 +194,12 @@ export default (app, featureFlagRouter: FlagRouter) => {
*/ */
route.post( route.post(
"/:id/fulfillments/:fulfillment_id/cancel", "/:id/fulfillments/:fulfillment_id/cancel",
transformIncludesOptions(allowedOrderIncludesFields),
transformQuery(AdminPostOrdersOrderFulfillementsCancelParams, {
defaultRelations: relations,
defaultFields: defaultFields,
isList: false,
}),
middlewares.wrap(require("./cancel-fulfillment").default) middlewares.wrap(require("./cancel-fulfillment").default)
) )
@@ -114,6 +208,12 @@ export default (app, featureFlagRouter: FlagRouter) => {
*/ */
route.post( route.post(
"/:id/swaps/:swap_id/fulfillments/:fulfillment_id/cancel", "/:id/swaps/:swap_id/fulfillments/:fulfillment_id/cancel",
transformIncludesOptions(allowedOrderIncludesFields),
transformQuery(AdminPostOrdersOrderSwapFulfillementsCancelParams, {
defaultRelations: relations,
defaultFields: defaultFields,
isList: false,
}),
middlewares.wrap(require("./cancel-fulfillment-swap").default) middlewares.wrap(require("./cancel-fulfillment-swap").default)
) )
@@ -122,6 +222,12 @@ export default (app, featureFlagRouter: FlagRouter) => {
*/ */
route.post( route.post(
"/:id/claims/:claim_id/fulfillments/:fulfillment_id/cancel", "/:id/claims/:claim_id/fulfillments/:fulfillment_id/cancel",
transformIncludesOptions(allowedOrderIncludesFields),
transformQuery(AdminPostOrdersClaimFulfillmentsCancelParams, {
defaultRelations: relations,
defaultFields: defaultFields,
isList: false,
}),
middlewares.wrap(require("./cancel-fulfillment-claim").default) middlewares.wrap(require("./cancel-fulfillment-claim").default)
) )
@@ -130,6 +236,13 @@ export default (app, featureFlagRouter: FlagRouter) => {
*/ */
route.post( route.post(
"/:id/shipment", "/:id/shipment",
transformIncludesOptions(allowedOrderIncludesFields),
transformBody(AdminPostOrdersOrderShipmentReq),
transformQuery(AdminPostOrdersOrderShipmentParams, {
defaultRelations: relations,
defaultFields: defaultFields,
isList: false,
}),
middlewares.wrap(require("./create-shipment").default) middlewares.wrap(require("./create-shipment").default)
) )
@@ -138,19 +251,42 @@ export default (app, featureFlagRouter: FlagRouter) => {
*/ */
route.post( route.post(
"/:id/return", "/:id/return",
transformIncludesOptions(allowedOrderIncludesFields),
transformBody(AdminPostOrdersOrderReturnsReq),
transformQuery(AdminPostOrdersOrderReturnsParams, {
defaultRelations: relations,
defaultFields: defaultFields,
isList: false,
}),
middlewares.wrap(require("./request-return").default) middlewares.wrap(require("./request-return").default)
) )
/** /**
* Cancel an order. * Cancel an order.
*/ */
route.post("/:id/cancel", middlewares.wrap(require("./cancel-order").default)) route.post(
"/:id/cancel",
transformIncludesOptions(allowedOrderIncludesFields),
transformQuery(AdminPostOrdersOrderCancel, {
defaultRelations: relations,
defaultFields: defaultFields,
isList: false,
}),
middlewares.wrap(require("./cancel-order").default)
)
/** /**
* Add a shipping method * Add a shipping method
*/ */
route.post( route.post(
"/:id/shipping-methods", "/:id/shipping-methods",
transformIncludesOptions(allowedOrderIncludesFields),
transformBody(AdminPostOrdersOrderShippingMethodsReq),
transformQuery(AdminPostOrdersOrderShippingMethodsParams, {
defaultRelations: relations,
defaultFields: defaultFields,
isList: false,
}),
middlewares.wrap(require("./add-shipping-method").default) middlewares.wrap(require("./add-shipping-method").default)
) )
@@ -159,19 +295,43 @@ export default (app, featureFlagRouter: FlagRouter) => {
*/ */
route.post( route.post(
"/:id/archive", "/:id/archive",
transformIncludesOptions(allowedOrderIncludesFields),
transformQuery(AdminPostOrdersOrderArchiveParams, {
defaultRelations: relations,
defaultFields: defaultFields,
isList: false,
}),
middlewares.wrap(require("./archive-order").default) middlewares.wrap(require("./archive-order").default)
) )
/** /**
* Creates a swap, requests a return and prepares a cart for payment. * Creates a swap, requests a return and prepares a cart for payment.
*/ */
route.post("/:id/swaps", middlewares.wrap(require("./create-swap").default)) route.post(
"/:id/swaps",
transformIncludesOptions(allowedOrderIncludesFields, [
AvailableOrderIncludesFields.RETURNABLE_ITEMS,
]),
transformBody(AdminPostOrdersOrderSwapsReq),
transformQuery(AdminPostOrdersOrderSwapsParams, {
defaultRelations: relations,
defaultFields: defaultFields,
isList: false,
}),
middlewares.wrap(require("./create-swap").default)
)
/** /**
* Cancels a swap. * Cancels a swap.
*/ */
route.post( route.post(
"/:id/swaps/:swap_id/cancel", "/:id/swaps/:swap_id/cancel",
transformIncludesOptions(allowedOrderIncludesFields),
transformQuery(AdminPostOrdersSwapCancelParams, {
defaultRelations: relations,
defaultFields: defaultFields,
isList: false,
}),
middlewares.wrap(require("./cancel-swap").default) middlewares.wrap(require("./cancel-swap").default)
) )
@@ -180,6 +340,12 @@ export default (app, featureFlagRouter: FlagRouter) => {
*/ */
route.post( route.post(
"/:id/swaps/:swap_id/fulfillments", "/:id/swaps/:swap_id/fulfillments",
transformIncludesOptions(allowedOrderIncludesFields),
transformQuery(AdminPostOrdersOrderSwapsSwapFulfillmentsParams, {
defaultRelations: relations,
defaultFields: defaultFields,
isList: false,
}),
middlewares.wrap(require("./fulfill-swap").default) middlewares.wrap(require("./fulfill-swap").default)
) )
@@ -188,6 +354,13 @@ export default (app, featureFlagRouter: FlagRouter) => {
*/ */
route.post( route.post(
"/:id/swaps/:swap_id/shipments", "/:id/swaps/:swap_id/shipments",
transformIncludesOptions(allowedOrderIncludesFields),
transformBody(AdminPostOrdersOrderSwapsSwapShipmentsReq),
transformQuery(AdminPostOrdersOrderSwapsSwapShipmentsParams, {
defaultRelations: relations,
defaultFields: defaultFields,
isList: false,
}),
middlewares.wrap(require("./create-swap-shipment").default) middlewares.wrap(require("./create-swap-shipment").default)
) )
@@ -196,19 +369,41 @@ export default (app, featureFlagRouter: FlagRouter) => {
*/ */
route.post( route.post(
"/:id/swaps/:swap_id/process-payment", "/:id/swaps/:swap_id/process-payment",
transformIncludesOptions(allowedOrderIncludesFields),
transformQuery(AdminPostOrdersOrderSwapsSwapProcessPaymentParams, {
defaultRelations: relations,
defaultFields: defaultFields,
isList: false,
}),
middlewares.wrap(require("./process-swap-payment").default) middlewares.wrap(require("./process-swap-payment").default)
) )
/** /**
* Creates a claim * Creates a claim
*/ */
route.post("/:id/claims", middlewares.wrap(require("./create-claim").default)) route.post(
"/:id/claims",
transformIncludesOptions(allowedOrderIncludesFields),
transformBody(AdminPostOrdersOrderClaimsReq),
transformQuery(AdminPostOrdersOrderClaimsParams, {
defaultRelations: relations,
defaultFields: defaultFields,
isList: false,
}),
middlewares.wrap(require("./create-claim").default)
)
/** /**
* Cancels a claim * Cancels a claim
*/ */
route.post( route.post(
"/:id/claims/:claim_id/cancel", "/:id/claims/:claim_id/cancel",
transformIncludesOptions(allowedOrderIncludesFields),
transformQuery(AdminPostOrdersClaimCancel, {
defaultRelations: relations,
defaultFields: defaultFields,
isList: false,
}),
middlewares.wrap(require("./cancel-claim").default) middlewares.wrap(require("./cancel-claim").default)
) )
@@ -217,6 +412,13 @@ export default (app, featureFlagRouter: FlagRouter) => {
*/ */
route.post( route.post(
"/:id/claims/:claim_id", "/:id/claims/:claim_id",
transformIncludesOptions(allowedOrderIncludesFields),
transformBody(AdminPostOrdersOrderClaimsClaimReq),
transformQuery(AdminPostOrdersOrderClaimsClaimParams, {
defaultRelations: relations,
defaultFields: defaultFields,
isList: false,
}),
middlewares.wrap(require("./update-claim").default) middlewares.wrap(require("./update-claim").default)
) )
@@ -225,6 +427,13 @@ export default (app, featureFlagRouter: FlagRouter) => {
*/ */
route.post( route.post(
"/:id/claims/:claim_id/fulfillments", "/:id/claims/:claim_id/fulfillments",
transformIncludesOptions(allowedOrderIncludesFields),
transformBody(AdminPostOrdersOrderClaimsClaimFulfillmentsReq),
transformQuery(AdminPostOrdersOrderClaimsClaimFulfillmentsParams, {
defaultRelations: relations,
defaultFields: defaultFields,
isList: false,
}),
middlewares.wrap(require("./fulfill-claim").default) middlewares.wrap(require("./fulfill-claim").default)
) )
@@ -233,6 +442,13 @@ export default (app, featureFlagRouter: FlagRouter) => {
*/ */
route.post( route.post(
"/:id/claims/:claim_id/shipments", "/:id/claims/:claim_id/shipments",
transformIncludesOptions(allowedOrderIncludesFields),
transformBody(AdminPostOrdersOrderClaimsClaimShipmentsReq),
transformQuery(AdminPostOrdersOrderClaimsClaimShipmentsParams, {
defaultRelations: relations,
defaultFields: defaultFields,
isList: false,
}),
middlewares.wrap(require("./create-claim-shipment").default) middlewares.wrap(require("./create-claim-shipment").default)
) )
@@ -358,15 +574,6 @@ export const defaultAdminOrdersFields = [
"items.refundable", "items.refundable",
"swaps.additional_items.refundable", "swaps.additional_items.refundable",
"claims.additional_items.refundable", "claims.additional_items.refundable",
"shipping_total",
"discount_total",
"tax_total",
"refunded_total",
"gift_card_total",
"subtotal",
"total",
"paid_total",
"refundable_amount",
"no_notification", "no_notification",
] as (keyof Order)[] ] as (keyof Order)[]
@@ -387,6 +594,14 @@ export const filterableAdminOrdersFields = [
"updated_at", "updated_at",
] ]
export const AvailableOrderIncludesFields = {
RETURNABLE_ITEMS: "returnable_items",
}
export const allowedOrderIncludesFields = [
AvailableOrderIncludesFields.RETURNABLE_ITEMS,
]
export * from "./add-shipping-method" export * from "./add-shipping-method"
export * from "./archive-order" export * from "./archive-order"
export * from "./cancel-claim" export * from "./cancel-claim"
@@ -1,7 +1,7 @@
import { OrderService, SwapService } from "../../../../services" import { OrderService, SwapService } from "../../../../services"
import { defaultAdminOrdersFields, defaultAdminOrdersRelations } from "."
import { EntityManager } from "typeorm" import { EntityManager } from "typeorm"
import { FindParams } from "../../../../types/common"
/** /**
* @oas [post] /orders/{id}/swaps/{swap_id}/process-payment * @oas [post] /orders/{id}/swaps/{swap_id}/process-payment
@@ -12,8 +12,11 @@ import { EntityManager } from "typeorm"
* parameters: * parameters:
* - (path) id=* {string} The ID of the Order. * - (path) id=* {string} The ID of the Order.
* - (path) swap_id=* {string} The ID of the Swap. * - (path) swap_id=* {string} The ID of the Swap.
* - (query) expand {string} Comma separated list of relations to include in the result.
* - (query) fields {string} Comma separated list of fields to include in the result.
* x-codegen: * x-codegen:
* method: processSwapPayment * method: processSwapPayment
* params: AdminPostOrdersOrderSwapsSwapProcessPaymentParams
* x-codeSamples: * x-codeSamples:
* - lang: JavaScript * - lang: JavaScript
* label: JS Client * label: JS Client
@@ -64,12 +67,14 @@ export default async (req, res) => {
await entityManager.transaction(async (manager) => { await entityManager.transaction(async (manager) => {
await swapService.withTransaction(manager).processDifference(swap_id) await swapService.withTransaction(manager).processDifference(swap_id)
const order = await orderService.withTransaction(manager).retrieve(id, {
select: defaultAdminOrdersFields,
relations: defaultAdminOrdersRelations,
})
res.json({ order })
}) })
const order = await orderService.retrieveWithTotals(id, req.retrieveConfig, {
includes: req.includes,
})
res.json({ order })
} }
// eslint-disable-next-line max-len
export class AdminPostOrdersOrderSwapsSwapProcessPaymentParams extends FindParams {}
@@ -5,11 +5,10 @@ import {
IsOptional, IsOptional,
IsString, IsString,
} from "class-validator" } from "class-validator"
import { defaultAdminOrdersFields, defaultAdminOrdersRelations } from "."
import { OrderService } from "../../../../services" import { OrderService } from "../../../../services"
import { validator } from "../../../../utils/validator"
import { EntityManager } from "typeorm" import { EntityManager } from "typeorm"
import { FindParams } from "../../../../types/common"
/** /**
* @oas [post] /orders/{id}/refund * @oas [post] /orders/{id}/refund
@@ -19,6 +18,8 @@ import { EntityManager } from "typeorm"
* x-authenticated: true * x-authenticated: true
* parameters: * parameters:
* - (path) id=* {string} The ID of the Order. * - (path) id=* {string} The ID of the Order.
* - (query) expand {string} Comma separated list of relations to include in the result.
* - (query) fields {string} Comma separated list of fields to include in the result.
* requestBody: * requestBody:
* content: * content:
* application/json: * application/json:
@@ -26,6 +27,7 @@ import { EntityManager } from "typeorm"
* $ref: "#/components/schemas/AdminPostOrdersOrderRefundsReq" * $ref: "#/components/schemas/AdminPostOrdersOrderRefundsReq"
* x-codegen: * x-codegen:
* method: refundPayment * method: refundPayment
* params: AdminPostOrdersOrderRefundsParams
* x-codeSamples: * x-codeSamples:
* - lang: JavaScript * - lang: JavaScript
* label: JS Client * label: JS Client
@@ -78,7 +80,7 @@ import { EntityManager } from "typeorm"
export default async (req, res) => { export default async (req, res) => {
const { id } = req.params const { id } = req.params
const validated = await validator(AdminPostOrdersOrderRefundsReq, req.body) const validated = req.validatedBody
const orderService: OrderService = req.scope.resolve("orderService") const orderService: OrderService = req.scope.resolve("orderService")
@@ -91,9 +93,8 @@ export default async (req, res) => {
}) })
}) })
const order = await orderService.retrieve(id, { const order = await orderService.retrieveWithTotals(id, req.retrieveConfig, {
select: defaultAdminOrdersFields, includes: req.includes,
relations: defaultAdminOrdersRelations,
}) })
res.status(200).json({ order }) res.status(200).json({ order })
@@ -136,3 +137,5 @@ export class AdminPostOrdersOrderRefundsReq {
@IsOptional() @IsOptional()
no_notification?: boolean no_notification?: boolean
} }
export class AdminPostOrdersOrderRefundsParams extends FindParams {}
@@ -6,7 +6,6 @@ import {
IsString, IsString,
ValidateNested, ValidateNested,
} from "class-validator" } from "class-validator"
import { defaultAdminOrdersFields, defaultAdminOrdersRelations } from "."
import { import {
EventBusService, EventBusService,
OrderService, OrderService,
@@ -18,7 +17,7 @@ import { isDefined, MedusaError } from "medusa-core-utils"
import { EntityManager } from "typeorm" import { EntityManager } from "typeorm"
import { Order, Return } from "../../../../models" import { Order, Return } from "../../../../models"
import { OrdersReturnItem } from "../../../../types/orders" import { OrdersReturnItem } from "../../../../types/orders"
import { validator } from "../../../../utils/validator" import { FindParams } from "../../../../types/common"
/** /**
* @oas [post] /orders/{id}/return * @oas [post] /orders/{id}/return
@@ -28,6 +27,8 @@ import { validator } from "../../../../utils/validator"
* x-authenticated: true * x-authenticated: true
* parameters: * parameters:
* - (path) id=* {string} The ID of the Order. * - (path) id=* {string} The ID of the Order.
* - (query) expand {string} Comma separated list of relations to include in the result.
* - (query) fields {string} Comma separated list of fields to include in the result.
* requestBody: * requestBody:
* content: * content:
* application/json: * application/json:
@@ -35,6 +36,7 @@ import { validator } from "../../../../utils/validator"
* $ref: "#/components/schemas/AdminPostOrdersOrderReturnsReq" * $ref: "#/components/schemas/AdminPostOrdersOrderReturnsReq"
* x-codegen: * x-codegen:
* method: requestReturn * method: requestReturn
* params: AdminPostOrdersOrderReturnsParams
* x-codeSamples: * x-codeSamples:
* - lang: JavaScript * - lang: JavaScript
* label: JS Client * label: JS Client
@@ -96,7 +98,7 @@ import { validator } from "../../../../utils/validator"
export default async (req, res) => { export default async (req, res) => {
const { id } = req.params const { id } = req.params
const value = await validator(AdminPostOrdersOrderReturnsReq, req.body) const value = req.validatedBody
const idempotencyKeyService = req.scope.resolve("idempotencyKeyService") const idempotencyKeyService = req.scope.resolve("idempotencyKeyService")
const manager: EntityManager = req.scope.resolve("manager") const manager: EntityManager = req.scope.resolve("manager")
@@ -152,14 +154,16 @@ export default async (req, res) => {
} }
} }
const order = await orderService let evaluatedNoNotification = value.no_notification
.withTransaction(manager)
.retrieve(id) if (!isDefined(evaluatedNoNotification)) {
const order = await orderService
.withTransaction(manager)
.retrieve(id)
evaluatedNoNotification = order.no_notification
}
const evaluatedNoNotification =
value.no_notification !== undefined
? value.no_notification
: order.no_notification
returnObj.no_notification = evaluatedNoNotification returnObj.no_notification = evaluatedNoNotification
const createdReturn = await returnService const createdReturn = await returnService
@@ -174,7 +178,7 @@ export default async (req, res) => {
await eventBus await eventBus
.withTransaction(manager) .withTransaction(manager)
.emit("order.return_requested", { .emit(OrderService.Events.RETURN_REQUESTED, {
id, id,
return_id: createdReturn.id, return_id: createdReturn.id,
no_notification: evaluatedNoNotification, no_notification: evaluatedNoNotification,
@@ -198,9 +202,7 @@ export default async (req, res) => {
idempotencyKey = await idempotencyKeyService idempotencyKey = await idempotencyKeyService
.withTransaction(transactionManager) .withTransaction(transactionManager)
.workStage(idempotencyKey.idempotency_key, async (manager) => { .workStage(idempotencyKey.idempotency_key, async (manager) => {
let order: Order | Return = await orderService let order: Order | Return
.withTransaction(manager)
.retrieve(id, { relations: ["returns"] })
/** /**
* If we are ready to receive immediately, we find the newly created return * If we are ready to receive immediately, we find the newly created return
@@ -229,9 +231,8 @@ export default async (req, res) => {
order = await orderService order = await orderService
.withTransaction(manager) .withTransaction(manager)
.retrieve(id, { .retrieveWithTotals(id, req.retrieveConfig, {
select: defaultAdminOrdersFields, includes: req.includes,
relations: defaultAdminOrdersRelations,
}) })
return { return {
@@ -374,3 +375,5 @@ class ReturnShipping {
@IsOptional() @IsOptional()
price?: number price?: number
} }
export class AdminPostOrdersOrderReturnsParams extends FindParams {}
@@ -8,12 +8,12 @@ import {
IsString, IsString,
ValidateNested, ValidateNested,
} from "class-validator" } from "class-validator"
import { defaultAdminOrdersFields, defaultAdminOrdersRelations } from "."
import { ClaimService, OrderService } from "../../../../services" import { ClaimService, OrderService } from "../../../../services"
import { Type } from "class-transformer" import { Type } from "class-transformer"
import { EntityManager } from "typeorm" import { EntityManager } from "typeorm"
import { validator } from "../../../../utils/validator" import { validator } from "../../../../utils/validator"
import { FindParams } from "../../../../types/common"
/** /**
* @oas [post] /order/{id}/claims/{claim_id} * @oas [post] /order/{id}/claims/{claim_id}
@@ -24,6 +24,8 @@ import { validator } from "../../../../utils/validator"
* parameters: * parameters:
* - (path) id=* {string} The ID of the Order. * - (path) id=* {string} The ID of the Order.
* - (path) claim_id=* {string} The ID of the Claim. * - (path) claim_id=* {string} The ID of the Claim.
* - (query) expand {string} Comma separated list of relations to include in the result.
* - (query) fields {string} Comma separated list of fields to include in the result.
* requestBody: * requestBody:
* content: * content:
* application/json: * application/json:
@@ -31,6 +33,7 @@ import { validator } from "../../../../utils/validator"
* $ref: "#/components/schemas/AdminPostOrdersOrderClaimsClaimReq" * $ref: "#/components/schemas/AdminPostOrdersOrderClaimsClaimReq"
* x-codegen: * x-codegen:
* method: updateClaim * method: updateClaim
* params: AdminPostOrdersOrderClaimsClaimParams
* x-codeSamples: * x-codeSamples:
* - lang: JavaScript * - lang: JavaScript
* label: JS Client * label: JS Client
@@ -96,9 +99,8 @@ export default async (req, res) => {
.update(claim_id, validated) .update(claim_id, validated)
}) })
const data = await orderService.retrieve(id, { const data = await orderService.retrieveWithTotals(id, req.retrieveConfig, {
select: defaultAdminOrdersFields, includes: req.includes,
relations: defaultAdminOrdersRelations,
}) })
res.json({ order: data }) res.json({ order: data })
@@ -277,3 +279,5 @@ class Tag {
@IsOptional() @IsOptional()
value?: string value?: string
} }
export class AdminPostOrdersOrderClaimsClaimParams extends FindParams {}
@@ -8,13 +8,11 @@ import {
IsString, IsString,
ValidateNested, ValidateNested,
} from "class-validator" } from "class-validator"
import { defaultAdminOrdersFields, defaultAdminOrdersRelations } from "."
import { AddressPayload } from "../../../../types/common" import { AddressPayload, FindParams } from "../../../../types/common"
import { EntityManager } from "typeorm" import { EntityManager } from "typeorm"
import { OrderService } from "../../../../services" import { OrderService } from "../../../../services"
import { Type } from "class-transformer" import { Type } from "class-transformer"
import { validator } from "../../../../utils/validator"
/** /**
* @oas [post] /orders/{id} * @oas [post] /orders/{id}
@@ -24,6 +22,8 @@ import { validator } from "../../../../utils/validator"
* x-authenticated: true * x-authenticated: true
* parameters: * parameters:
* - (path) id=* {string} The ID of the Order. * - (path) id=* {string} The ID of the Order.
* - (query) expand {string} Comma separated list of relations to include in the result.
* - (query) fields {string} Comma separated list of fields to include in the result.
* requestBody: * requestBody:
* content: * content:
* application/json: * application/json:
@@ -31,6 +31,7 @@ import { validator } from "../../../../utils/validator"
* $ref: "#/components/schemas/AdminPostOrdersOrderReq" * $ref: "#/components/schemas/AdminPostOrdersOrderReq"
* x-codegen: * x-codegen:
* method: update * method: update
* params: AdminPostOrdersOrderParams
* x-codeSamples: * x-codeSamples:
* - lang: JavaScript * - lang: JavaScript
* label: JS Client * label: JS Client
@@ -82,20 +83,17 @@ import { validator } from "../../../../utils/validator"
export default async (req, res) => { export default async (req, res) => {
const { id } = req.params const { id } = req.params
const value = await validator(AdminPostOrdersOrderReq, req.body)
const orderService: OrderService = req.scope.resolve("orderService") const orderService: OrderService = req.scope.resolve("orderService")
const manager: EntityManager = req.scope.resolve("manager") const manager: EntityManager = req.scope.resolve("manager")
await manager.transaction(async (transactionManager) => { await manager.transaction(async (transactionManager) => {
return await orderService return await orderService
.withTransaction(transactionManager) .withTransaction(transactionManager)
.update(id, value) .update(id, req.validatedBody)
}) })
const order = await orderService.retrieve(id, { const order = await orderService.retrieveWithTotals(id, req.retrieveConfig, {
select: defaultAdminOrdersFields, includes: req.includes,
relations: defaultAdminOrdersRelations,
}) })
res.status(200).json({ order }) res.status(200).json({ order })
@@ -244,3 +242,5 @@ class ShippingMethod {
@IsOptional() @IsOptional()
items?: Record<string, unknown>[] items?: Record<string, unknown>[]
} }
export class AdminPostOrdersOrderParams extends FindParams {}
+7
View File
@@ -257,6 +257,8 @@ export class Order extends BaseEntity {
gift_card_total: number gift_card_total: number
gift_card_tax_total: number gift_card_tax_total: number
returnable_items?: LineItem[]
@BeforeInsert() @BeforeInsert()
private async beforeInsert(): Promise<void> { private async beforeInsert(): Promise<void> {
this.id = generateEntityId(this.id, "order") this.id = generateEntityId(this.id, "order")
@@ -547,6 +549,11 @@ export class Order extends BaseEntity {
* description: The total of gift cards with taxes * description: The total of gift cards with taxes
* type: integer * type: integer
* example: 0 * example: 0
* returnable_items:
* description: The items that are returnable as part of the order, order swaps or order claims
* type: array
* items:
* $ref: "#/components/schemas/LineItem"
* created_at: * created_at:
* description: The date with timezone at which the resource was created. * description: The date with timezone at which the resource was created.
* type: string * type: string
+77 -52
View File
@@ -26,7 +26,7 @@ import {
CreateFulfillmentOrder, CreateFulfillmentOrder,
FulFillmentItemType, FulFillmentItemType,
} from "../types/fulfillment" } from "../types/fulfillment"
import { UpdateOrderInput } from "../types/orders" import { TotalsContext, UpdateOrderInput } from "../types/orders"
import { CreateShippingMethodDto } from "../types/shipping-options" import { CreateShippingMethodDto } from "../types/shipping-options"
import { buildQuery, isString, setMetadata } from "../utils" import { buildQuery, isString, setMetadata } from "../utils"
import { FlagRouter } from "../utils/flag-router" import { FlagRouter } from "../utils/flag-router"
@@ -77,10 +77,6 @@ type InjectedDependencies = {
productVariantInventoryService: ProductVariantInventoryService productVariantInventoryService: ProductVariantInventoryService
} }
type TotalsConfig = {
force_taxes?: boolean
}
class OrderService extends TransactionBaseService { class OrderService extends TransactionBaseService {
static readonly Events = { static readonly Events = {
GIFT_CARD_CREATED: "order.gift_card_created", GIFT_CARD_CREATED: "order.gift_card_created",
@@ -422,12 +418,12 @@ class OrderService extends TransactionBaseService {
async retrieveWithTotals( async retrieveWithTotals(
orderId: string, orderId: string,
options: FindConfig<Order> = {}, options: FindConfig<Order> = {},
totalsConfig: TotalsConfig = {} context: TotalsContext = {}
): Promise<Order> { ): Promise<Order> {
const relations = this.getTotalsRelations(options) const relations = this.getTotalsRelations(options)
const order = await this.retrieve(orderId, { ...options, relations }) const order = await this.retrieve(orderId, { ...options, relations })
return await this.decorateTotals(order, totalsConfig) return await this.decorateTotals(order, context)
} }
/** /**
@@ -1702,17 +1698,24 @@ class OrderService extends TransactionBaseService {
return order return order
} }
async decorateTotals(order: Order, totalsFields?: string[]): Promise<Order>
async decorateTotals(order: Order, context?: TotalsContext): Promise<Order>
/** /**
* Calculate and attach the different total fields on the object * Calculate and attach the different total fields on the object
* @param order * @param order
* @param totalsFieldsOrConfig * @param totalsFieldsOrContext
*/ */
async decorateTotals( async decorateTotals(
order: Order, order: Order,
totalsFieldsOrConfig?: string[] | TotalsConfig totalsFieldsOrContext?: string[] | TotalsContext
): Promise<Order> { ): Promise<Order> {
if (Array.isArray(totalsFieldsOrConfig)) { if (Array.isArray(totalsFieldsOrContext)) {
return await this.decorateTotalsLegacy(order, totalsFieldsOrConfig) if (totalsFieldsOrContext.length) {
return await this.decorateTotalsLegacy(order, totalsFieldsOrContext)
}
totalsFieldsOrContext = {}
} }
const manager = this.transactionManager_ ?? this.manager_ const manager = this.transactionManager_ ?? this.manager_
@@ -1721,10 +1724,31 @@ class OrderService extends TransactionBaseService {
const calculationContext = await this.totalsService_.getCalculationContext( const calculationContext = await this.totalsService_.getCalculationContext(
order order
) )
const orderItems = [...(order.items ?? [])]
const { returnable_items } = totalsFieldsOrContext?.includes ?? {}
const returnableItems: LineItem[] | undefined = isDefined(returnable_items)
? []
: undefined
const isReturnableItem = (item) =>
returnable_items &&
(item.returned_quantity ?? 0) < (item.shipped_quantity ?? 0)
const allItems: LineItem[] = [...(order.items ?? [])]
if (returnable_items) {
// All items must receive their totals and if some of them are returnable
// They will be pushed to `returnable_items` at a later point
allItems.push(
...(order.swaps?.map((s) => s.additional_items ?? []).flat() ?? []),
...(order.claims?.map((c) => c.additional_items ?? []).flat() ?? [])
)
}
const orderShippingMethods = [...(order.shipping_methods ?? [])] const orderShippingMethods = [...(order.shipping_methods ?? [])]
const itemsTotals = await newTotalsServiceTx.getLineItemTotals(orderItems, { const itemsTotals = await newTotalsServiceTx.getLineItemTotals(allItems, {
taxRate: order.tax_rate, taxRate: order.tax_rate,
includeTax: true, includeTax: true,
calculationContext, calculationContext,
@@ -1752,28 +1776,23 @@ class OrderService extends TransactionBaseService {
let shipping_tax_total = 0 let shipping_tax_total = 0
order.items = (order.items || []).map((item) => { order.items = (order.items || []).map((item) => {
const refundable = newTotalsServiceTx.getLineItemRefund( item.quantity = item.quantity - (item.returned_quantity || 0)
{ const refundable = newTotalsServiceTx.getLineItemRefund(item, {
...item, calculationContext,
quantity: item.quantity - (item.returned_quantity || 0), taxRate: order.tax_rate,
}, })
{
calculationContext,
taxRate: order.tax_rate,
}
)
const itemWithTotals = { Object.assign(item, itemsTotals[item.id] ?? {}, { refundable })
...item,
...(itemsTotals[item.id] ?? {}), order.subtotal += item.subtotal ?? 0
refundable, order.discount_total += item.discount_total ?? 0
item_tax_total += item.tax_total ?? 0
if (isReturnableItem(item)) {
returnableItems?.push(item)
} }
order.subtotal += itemWithTotals.subtotal ?? 0 return item
order.discount_total += itemWithTotals.discount_total ?? 0
item_tax_total += itemWithTotals.tax_total ?? 0
return itemWithTotals as LineItem
}) })
order.shipping_methods = (order.shipping_methods || []).map( order.shipping_methods = (order.shipping_methods || []).map(
@@ -1806,32 +1825,36 @@ class OrderService extends TransactionBaseService {
for (const swap of order.swaps ?? []) { for (const swap of order.swaps ?? []) {
swap.additional_items = swap.additional_items.map((item) => { swap.additional_items = swap.additional_items.map((item) => {
item.refundable = newTotalsServiceTx.getLineItemRefund( item.quantity = item.quantity - (item.returned_quantity || 0)
{ const refundable = newTotalsServiceTx.getLineItemRefund(item, {
...item, calculationContext,
quantity: item.quantity - (item.returned_quantity || 0), taxRate: order.tax_rate,
}, })
{
calculationContext, Object.assign(item, itemsTotals[item.id] ?? {}, { refundable })
taxRate: order.tax_rate,
} if (isReturnableItem(item)) {
) returnableItems?.push(item)
}
return item return item
}) })
} }
for (const claim of order.claims ?? []) { for (const claim of order.claims ?? []) {
claim.additional_items = claim.additional_items.map((item) => { claim.additional_items = claim.additional_items.map((item) => {
item.refundable = newTotalsServiceTx.getLineItemRefund( item.quantity = item.quantity - (item.returned_quantity || 0)
{ const refundable = newTotalsServiceTx.getLineItemRefund(item, {
...item, calculationContext,
quantity: item.quantity - (item.returned_quantity || 0), taxRate: order.tax_rate,
}, })
{
calculationContext, Object.assign(item, itemsTotals[item.id] ?? {}, { refundable })
taxRate: order.tax_rate,
} if (isReturnableItem(item)) {
) returnableItems?.push(item)
}
return item return item
}) })
} }
@@ -1842,6 +1865,8 @@ class OrderService extends TransactionBaseService {
order.tax_total - order.tax_total -
(order.gift_card_total + order.discount_total) (order.gift_card_total + order.discount_total)
order.returnable_items = returnableItems
return order return order
} }
+5
View File
@@ -17,6 +17,11 @@ export function isOrder(object: any): object is Order {
return object.object === "order" return object.object === "order"
} }
export type TotalsContext = {
force_taxes?: boolean
includes?: { returnable_items?: boolean }
}
enum OrderStatus { enum OrderStatus {
pending = "pending", pending = "pending",
completed = "completed", completed = "completed",