feat(medusa): Implement premises of order edit retrieval (#2183)
**What** - Implements the admin/store retrieval end point - Service implementation of the retrieve method - Service implementation of the computeLineItems method which aggregates the right line item based on the changes that are made - client - medusa-js api - medusa-react queries hooks **Tests** - Unit tests of the retrieval end points - Unit tests of the service retrieve method and computeLineItems - Integration tests for admin/store - client - medusa-js tests - medusa-react hooks tests FIXES CORE-492
This commit is contained in:
committed by
GitHub
parent
3efeb6b84f
commit
f863d28b9a
@@ -29,6 +29,7 @@ export * from "./routes/admin/invites"
|
||||
export * from "./routes/admin/notes"
|
||||
export * from "./routes/admin/notifications"
|
||||
export * from "./routes/admin/orders"
|
||||
export * from "./routes/admin/order-edits"
|
||||
export * from "./routes/admin/price-lists"
|
||||
export * from "./routes/admin/product-tags"
|
||||
export * from "./routes/admin/product-types"
|
||||
@@ -52,6 +53,7 @@ export * from "./routes/store/collections"
|
||||
export * from "./routes/store/customers"
|
||||
export * from "./routes/store/gift-cards"
|
||||
export * from "./routes/store/orders"
|
||||
export * from "./routes/store/order-edits"
|
||||
export * from "./routes/store/products"
|
||||
export * from "./routes/store/regions"
|
||||
export * from "./routes/store/return-reasons"
|
||||
|
||||
@@ -15,6 +15,7 @@ import inviteRoutes, { unauthenticatedInviteRoutes } from "./invites"
|
||||
import noteRoutes from "./notes"
|
||||
import notificationRoutes from "./notifications"
|
||||
import orderRoutes from "./orders"
|
||||
import orderEditRoutes from "./order-edits"
|
||||
import priceListRoutes from "./price-lists"
|
||||
import productTagRoutes from "./product-tags"
|
||||
import productTypesRoutes from "./product-types"
|
||||
@@ -79,6 +80,7 @@ export default (app, container, config) => {
|
||||
noteRoutes(route)
|
||||
notificationRoutes(route)
|
||||
orderRoutes(route, featureFlagRouter)
|
||||
orderEditRoutes(route, featureFlagRouter)
|
||||
priceListRoutes(route, featureFlagRouter)
|
||||
productRoutes(route, featureFlagRouter)
|
||||
productTagRoutes(route)
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import { IdMap } from "medusa-test-utils"
|
||||
import { request } from "../../../../../helpers/test-request"
|
||||
import { orderEditServiceMock } from "../../../../../services/__mocks__/order-edit"
|
||||
import OrderEditingFeatureFlag from "../../../../../loaders/feature-flags/order-editing"
|
||||
import {
|
||||
defaultOrderEditFields,
|
||||
defaultOrderEditRelations,
|
||||
} from "../../../../../types/order-edit"
|
||||
|
||||
describe("GET /admin/order-edits/:id", () => {
|
||||
describe("successfully gets an order edit", () => {
|
||||
const orderEditId = IdMap.getId("testCreatedOrder")
|
||||
let subject
|
||||
|
||||
beforeAll(async () => {
|
||||
subject = await request("GET", `/admin/order-edits/${orderEditId}`, {
|
||||
adminSession: {
|
||||
jwt: {
|
||||
userId: IdMap.getId("admin_user"),
|
||||
},
|
||||
},
|
||||
flags: [OrderEditingFeatureFlag],
|
||||
})
|
||||
})
|
||||
|
||||
afterAll(() => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
it("calls orderService retrieve", () => {
|
||||
expect(orderEditServiceMock.retrieve).toHaveBeenCalledTimes(1)
|
||||
expect(orderEditServiceMock.retrieve).toHaveBeenCalledWith(orderEditId, {
|
||||
select: defaultOrderEditFields,
|
||||
relations: defaultOrderEditRelations,
|
||||
})
|
||||
expect(orderEditServiceMock.computeLineItems).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it("returns order", () => {
|
||||
expect(subject.body.order_edit.id).toEqual(orderEditId)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,68 @@
|
||||
import { Request, Response } from "express"
|
||||
import { OrderEditService } from "../../../../services"
|
||||
|
||||
/**
|
||||
* @oas [get] /order-edits/{id}
|
||||
* operationId: "GetOrderEditsOrderEdit"
|
||||
* summary: "Retrieve an OrderEdit"
|
||||
* description: "Retrieves a OrderEdit."
|
||||
* x-authenticated: true
|
||||
* parameters:
|
||||
* - (path) id=* {string} The ID of the OrderEdit.
|
||||
* x-codeSamples:
|
||||
* - lang: JavaScript
|
||||
* label: JS Client
|
||||
* source: |
|
||||
* import Medusa from "@medusajs/medusa-js"
|
||||
* const medusa = new Medusa({ baseUrl: MEDUSA_BACKEND_URL, maxRetries: 3 })
|
||||
* // must be previously logged in or use api token
|
||||
* medusa.admin.orderEdit.retrieve(orderEditId)
|
||||
* .then(({ order_edit }) => {
|
||||
* console.log(order_edit.id);
|
||||
* });
|
||||
* - lang: Shell
|
||||
* label: cURL
|
||||
* source: |
|
||||
* curl --location --request GET 'https://medusa-url.com/admin/order-edits/{id}' \
|
||||
* --header 'Authorization: Bearer {api_token}'
|
||||
* security:
|
||||
* - api_token: []
|
||||
* - cookie_auth: []
|
||||
* tags:
|
||||
* - OrderEdit
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* order_edit:
|
||||
* $ref: "#/components/schemas/order_edit"
|
||||
* "400":
|
||||
* $ref: "#/components/responses/400_error"
|
||||
* "401":
|
||||
* $ref: "#/components/responses/unauthorized"
|
||||
* "404":
|
||||
* $ref: "#/components/responses/not_found_error"
|
||||
* "409":
|
||||
* $ref: "#/components/responses/invalid_state_error"
|
||||
* "422":
|
||||
* $ref: "#/components/responses/invalid_request_error"
|
||||
* "500":
|
||||
* $ref: "#/components/responses/500_error"
|
||||
*/
|
||||
export default async (req: Request, res: Response) => {
|
||||
const orderEditService: OrderEditService =
|
||||
req.scope.resolve("orderEditService")
|
||||
|
||||
const { id } = req.params
|
||||
const retrieveConfig = req.retrieveConfig
|
||||
|
||||
const orderEdit = await orderEditService.retrieve(id, retrieveConfig)
|
||||
const { items, removedItems } = await orderEditService.computeLineItems(id)
|
||||
orderEdit.items = items
|
||||
orderEdit.removed_items = removedItems
|
||||
|
||||
return res.json({ order_edit: orderEdit })
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import { Router } from "express"
|
||||
import middlewares, { transformQuery } from "../../../middlewares"
|
||||
import { EmptyQueryParams } from "../../../../types/common"
|
||||
import { isFeatureFlagEnabled } from "../../../middlewares/feature-flag-enabled"
|
||||
import OrderEditingFeatureFlag from "../../../../loaders/feature-flags/order-editing"
|
||||
import {
|
||||
defaultOrderEditFields,
|
||||
defaultOrderEditRelations,
|
||||
} from "../../../../types/order-edit"
|
||||
import { OrderEdit } from "../../../../models"
|
||||
|
||||
const route = Router()
|
||||
|
||||
export default (app) => {
|
||||
app.use(
|
||||
"/order-edits",
|
||||
isFeatureFlagEnabled(OrderEditingFeatureFlag.key),
|
||||
route
|
||||
)
|
||||
|
||||
route.get(
|
||||
"/:id",
|
||||
transformQuery(EmptyQueryParams, {
|
||||
defaultRelations: defaultOrderEditRelations,
|
||||
defaultFields: defaultOrderEditFields,
|
||||
isList: false,
|
||||
}),
|
||||
middlewares.wrap(require("./get-order-edit").default)
|
||||
)
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
export type AdminOrdersEditsRes = {
|
||||
order_edit: OrderEdit
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import collectionRoutes from "./collections"
|
||||
import customerRoutes from "./customers"
|
||||
import giftCardRoutes from "./gift-cards"
|
||||
import orderRoutes from "./orders"
|
||||
import orderEditRoutes from "./order-edits"
|
||||
import productRoutes from "./products"
|
||||
import regionRoutes from "./regions"
|
||||
import returnReasonRoutes from "./return-reasons"
|
||||
@@ -35,6 +36,7 @@ export default (app, container, config) => {
|
||||
customerRoutes(route, container)
|
||||
productRoutes(route)
|
||||
orderRoutes(route)
|
||||
orderEditRoutes(route)
|
||||
cartRoutes(route, container)
|
||||
shippingOptionRoutes(route)
|
||||
regionRoutes(route)
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import { IdMap } from "medusa-test-utils"
|
||||
import { request } from "../../../../../helpers/test-request"
|
||||
import { orderEditServiceMock } from "../../../../../services/__mocks__/order-edit"
|
||||
import OrderEditingFeatureFlag from "../../../../../loaders/feature-flags/order-editing"
|
||||
import {
|
||||
defaultOrderEditFields,
|
||||
defaultOrderEditRelations,
|
||||
} from "../../../../../types/order-edit"
|
||||
import { storeOrderEditNotAllowedFields } from "../index"
|
||||
|
||||
describe("GET /store/order-edits/:id", () => {
|
||||
describe("successfully gets an order edit", () => {
|
||||
const orderEditId = IdMap.getId("testCreatedOrder")
|
||||
let subject
|
||||
|
||||
beforeAll(async () => {
|
||||
subject = await request("GET", `/store/order-edits/${orderEditId}`, {
|
||||
flags: [OrderEditingFeatureFlag],
|
||||
})
|
||||
})
|
||||
|
||||
afterAll(() => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
it("calls orderService retrieve", () => {
|
||||
expect(orderEditServiceMock.retrieve).toHaveBeenCalledTimes(1)
|
||||
expect(orderEditServiceMock.retrieve).toHaveBeenCalledWith(orderEditId, {
|
||||
select: defaultOrderEditFields.filter(
|
||||
(field) => !storeOrderEditNotAllowedFields.includes(field)
|
||||
),
|
||||
relations: defaultOrderEditRelations.filter(
|
||||
(field) => !storeOrderEditNotAllowedFields.includes(field)
|
||||
),
|
||||
})
|
||||
expect(orderEditServiceMock.computeLineItems).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it("returns order", () => {
|
||||
expect(subject.body.order_edit.id).toEqual(orderEditId)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,62 @@
|
||||
import { Request, Response } from "express"
|
||||
import { OrderEditService } from "../../../../services"
|
||||
|
||||
/**
|
||||
* @oas [get] /order-edits/{id}
|
||||
* operationId: "GetOrderEditsOrderEdit"
|
||||
* summary: "Retrieve an OrderEdit"
|
||||
* description: "Retrieves a OrderEdit."
|
||||
* parameters:
|
||||
* - (path) id=* {string} The ID of the OrderEdit.
|
||||
* x-codeSamples:
|
||||
* - lang: JavaScript
|
||||
* label: JS Client
|
||||
* source: |
|
||||
* import Medusa from "@medusajs/medusa-js"
|
||||
* const medusa = new Medusa({ baseUrl: MEDUSA_BACKEND_URL, maxRetries: 3 })
|
||||
* medusa.orderEdit.retrieve(orderEditId)
|
||||
* .then(({ order_edit }) => {
|
||||
* console.log(order_edit.id);
|
||||
* });
|
||||
* - lang: Shell
|
||||
* label: cURL
|
||||
* source: |
|
||||
* curl --location --request GET 'https://medusa-url.com/store/order-edits/{id}'
|
||||
* tags:
|
||||
* - OrderEdit
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* order_edit:
|
||||
* $ref: "#/components/schemas/order_edit"
|
||||
* "400":
|
||||
* $ref: "#/components/responses/400_error"
|
||||
* "401":
|
||||
* $ref: "#/components/responses/unauthorized"
|
||||
* "404":
|
||||
* $ref: "#/components/responses/not_found_error"
|
||||
* "409":
|
||||
* $ref: "#/components/responses/invalid_state_error"
|
||||
* "422":
|
||||
* $ref: "#/components/responses/invalid_request_error"
|
||||
* "500":
|
||||
* $ref: "#/components/responses/500_error"
|
||||
*/
|
||||
export default async (req: Request, res: Response) => {
|
||||
const orderEditService: OrderEditService =
|
||||
req.scope.resolve("orderEditService")
|
||||
|
||||
const { id } = req.params
|
||||
const retrieveConfig = req.retrieveConfig
|
||||
|
||||
const orderEdit = await orderEditService.retrieve(id, retrieveConfig)
|
||||
const { items, removedItems } = await orderEditService.computeLineItems(id)
|
||||
orderEdit.items = items
|
||||
orderEdit.removed_items = removedItems
|
||||
|
||||
return res.json({ order_edit: orderEdit })
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
import { Router } from "express"
|
||||
import middlewares, { transformQuery } from "../../../middlewares"
|
||||
import { EmptyQueryParams } from "../../../../types/common"
|
||||
import { isFeatureFlagEnabled } from "../../../middlewares/feature-flag-enabled"
|
||||
import OrderEditingFeatureFlag from "../../../../loaders/feature-flags/order-editing"
|
||||
import {
|
||||
defaultOrderEditFields,
|
||||
defaultOrderEditRelations,
|
||||
} from "../../../../types/order-edit"
|
||||
import { OrderEdit } from "../../../../models"
|
||||
|
||||
const route = Router()
|
||||
|
||||
export default (app) => {
|
||||
app.use(
|
||||
"/order-edits",
|
||||
isFeatureFlagEnabled(OrderEditingFeatureFlag.key),
|
||||
route
|
||||
)
|
||||
|
||||
route.get(
|
||||
"/:id",
|
||||
transformQuery(EmptyQueryParams, {
|
||||
defaultRelations: defaultOrderEditRelations.filter(
|
||||
(field) => !storeOrderEditNotAllowedFields.includes(field)
|
||||
),
|
||||
defaultFields: defaultOrderEditFields.filter(
|
||||
(field) => !storeOrderEditNotAllowedFields.includes(field)
|
||||
),
|
||||
allowedFields: defaultOrderEditFields,
|
||||
isList: false,
|
||||
}),
|
||||
middlewares.wrap(require("./get-order-edit").default)
|
||||
)
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
export type StoreOrderEditsRes = {
|
||||
order_edit: Omit<
|
||||
OrderEdit,
|
||||
"internal_note" | "created_by" | "confirmed_by" | "canceled_by"
|
||||
>
|
||||
}
|
||||
|
||||
export const storeOrderEditNotAllowedFields = [
|
||||
"internal_note",
|
||||
"created_by",
|
||||
"confirmed_by",
|
||||
"canceled_by",
|
||||
]
|
||||
Reference in New Issue
Block a user