feat(medusa): Migrate and fix order service (#1894)
* feat(medusa): Migrate and fix order service * fix(medusa): Order service pass Payment instead of the session: * fix(medusa): Remove unnecessary method in the client library * test(medusa): Fix unit tests * test(medusa): Fix unit tests * fix(medusa): Typo * test(meduas): fix unit test * feat(medusa): Update base service used and missing transaction * test(meduas): fix unit test * fix(medusa): cleanup and missing transaction * fix(medusa): missing withTransaction on some mocks * feat(medusa): Update order service method visibility * include feedback * feat(medusa); revert order payment status" * test(medusa): fix unit Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
1998902a94
commit
b54d5178c9
@@ -15,21 +15,12 @@ import {
|
||||
AdminPostOrdersOrderSwapsReq,
|
||||
AdminPostOrdersOrderSwapsSwapFulfillmentsReq,
|
||||
AdminPostOrdersOrderSwapsSwapShipmentsReq,
|
||||
AdminPostOrdersReq,
|
||||
} from "@medusajs/medusa"
|
||||
import qs from "qs"
|
||||
import { ResponsePromise } from "../../typings"
|
||||
import BaseResource from "../base"
|
||||
|
||||
class AdminOrdersResource extends BaseResource {
|
||||
create(
|
||||
payload: AdminPostOrdersReq,
|
||||
customHeaders: Record<string, any> = {}
|
||||
): ResponsePromise<AdminOrdersRes> {
|
||||
const path = `/admin/orders`
|
||||
return this.client.request("POST", path, payload, {}, customHeaders)
|
||||
}
|
||||
|
||||
update(
|
||||
id: string,
|
||||
payload: AdminPostOrdersOrderReq,
|
||||
@@ -261,15 +252,6 @@ class AdminOrdersResource extends BaseResource {
|
||||
const path = `/admin/orders/${id}/claims/${claimId}/shipments`
|
||||
return this.client.request("POST", path, payload, {}, customHeaders)
|
||||
}
|
||||
|
||||
deleteMetadata(
|
||||
id: string,
|
||||
key: string,
|
||||
customHeaders: Record<string, any> = {}
|
||||
): ResponsePromise<AdminOrdersRes> {
|
||||
const path = `/admin/orders/${id}/metadata/${key}`
|
||||
return this.client.request("DELETE", path, undefined, {}, customHeaders)
|
||||
}
|
||||
}
|
||||
|
||||
export default AdminOrdersResource
|
||||
|
||||
@@ -7,28 +7,12 @@ import {
|
||||
AdminPostOrdersOrderReturnsReq,
|
||||
AdminPostOrdersOrderShipmentReq,
|
||||
AdminPostOrdersOrderShippingMethodsReq,
|
||||
AdminPostOrdersReq,
|
||||
} from "@medusajs/medusa"
|
||||
import { Response } from "@medusajs/medusa-js"
|
||||
import { useMutation, UseMutationOptions, useQueryClient } from "react-query"
|
||||
import { useMedusa } from "../../../contexts/medusa"
|
||||
import { buildOptions } from "../../utils/buildOptions"
|
||||
|
||||
export const useAdminCreateOrder = (
|
||||
options?: UseMutationOptions<
|
||||
Response<AdminOrdersRes>,
|
||||
Error,
|
||||
AdminPostOrdersReq
|
||||
>
|
||||
) => {
|
||||
const { client } = useMedusa()
|
||||
const queryClient = useQueryClient()
|
||||
return useMutation(
|
||||
(payload: AdminPostOrdersReq) => client.admin.orders.create(payload),
|
||||
buildOptions(queryClient, adminOrderKeys.lists(), options)
|
||||
)
|
||||
}
|
||||
|
||||
export const useAdminUpdateOrder = (
|
||||
id: string,
|
||||
options?: UseMutationOptions<
|
||||
@@ -234,16 +218,3 @@ export const useAdminArchiveOrder = (
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
export const useAdminDeleteOrderMetadata = (
|
||||
id: string,
|
||||
options?: UseMutationOptions<Response<AdminOrdersRes>, Error, string>
|
||||
) => {
|
||||
const { client } = useMedusa()
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
return useMutation(
|
||||
(key: string) => client.admin.orders.deleteMetadata(id, key),
|
||||
buildOptions(queryClient, adminOrderKeys.detail(id), options)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import {
|
||||
useAdminCreateOrder,
|
||||
useAdminUpdateOrder,
|
||||
useAdminDeleteOrderMetadata,
|
||||
useAdminCompleteOrder,
|
||||
useAdminCapturePayment,
|
||||
useAdminRefundPayment,
|
||||
@@ -16,67 +14,6 @@ import { renderHook } from "@testing-library/react-hooks"
|
||||
import { fixtures } from "../../../../mocks/data"
|
||||
import { createWrapper } from "../../../utils"
|
||||
|
||||
describe("useAdminCreateOrder hook", () => {
|
||||
test("creates a order and returns it", async () => {
|
||||
const order = {
|
||||
email: "lebron@james.com",
|
||||
billing_address: {
|
||||
company: "medusa",
|
||||
first_name: "Jane",
|
||||
last_name: "Medusan",
|
||||
address_1: "jane street",
|
||||
address_2: "2nd floor",
|
||||
city: "copenhagen",
|
||||
country_code: "dk",
|
||||
province: "copenhagen",
|
||||
postal_code: "382793",
|
||||
phone: "4897394",
|
||||
metadata: null,
|
||||
},
|
||||
shipping_address: {
|
||||
company: "medusa",
|
||||
first_name: "Jane",
|
||||
last_name: "Medusan",
|
||||
address_1: "jane street",
|
||||
address_2: "2nd floor",
|
||||
city: "copenhagen",
|
||||
country_code: "dk",
|
||||
province: "copenhagen",
|
||||
postal_code: "382793",
|
||||
phone: "4897394",
|
||||
metadata: null,
|
||||
},
|
||||
items: [
|
||||
{
|
||||
variant_id: "test-variant",
|
||||
quantity: 1,
|
||||
},
|
||||
],
|
||||
region: "test-region",
|
||||
customer_id: "cus_test",
|
||||
payment_method: {
|
||||
provider_id: "test-pay",
|
||||
},
|
||||
}
|
||||
|
||||
const { result, waitFor } = renderHook(() => useAdminCreateOrder(), {
|
||||
wrapper: createWrapper(),
|
||||
})
|
||||
|
||||
result.current.mutate(order)
|
||||
|
||||
await waitFor(() => result.current.isSuccess)
|
||||
|
||||
expect(result.current.data.response.status).toEqual(200)
|
||||
expect(result.current.data.order).toEqual(
|
||||
expect.objectContaining({
|
||||
...fixtures.get("order"),
|
||||
...order,
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("useAdminUpdateOrder hook", () => {
|
||||
test("updates a order and returns it", async () => {
|
||||
const order = {
|
||||
@@ -290,23 +227,3 @@ describe("useAdminCancelFulfillment hook", () => {
|
||||
expect(result.current.data.order).toEqual(fixtures.get("order"))
|
||||
})
|
||||
})
|
||||
|
||||
describe("useAdminDeleteOrderMetadata hook", () => {
|
||||
test("remove metadata field on order", async () => {
|
||||
const id = fixtures.get("order").id
|
||||
|
||||
const { result, waitFor } = renderHook(
|
||||
() => useAdminDeleteOrderMetadata(id),
|
||||
{
|
||||
wrapper: createWrapper(),
|
||||
}
|
||||
)
|
||||
|
||||
result.current.mutate("some_key")
|
||||
|
||||
await waitFor(() => result.current.isSuccess)
|
||||
|
||||
expect(result.current.data.response.status).toEqual(200)
|
||||
expect(result.current.data.order).toEqual(fixtures.get("order"))
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,144 +0,0 @@
|
||||
import { IdMap } from "medusa-test-utils"
|
||||
import { request } from "../../../../../helpers/test-request"
|
||||
import {
|
||||
orders,
|
||||
OrderServiceMock,
|
||||
} from "../../../../../services/__mocks__/order"
|
||||
|
||||
describe("POST /admin/orders", () => {
|
||||
describe("successful creation", () => {
|
||||
let subject
|
||||
|
||||
beforeAll(async () => {
|
||||
subject = await request("POST", "/admin/orders", {
|
||||
payload: {
|
||||
email: "virgil@vandijk.dk",
|
||||
billing_address: {
|
||||
first_name: "Virgil",
|
||||
last_name: "Van Dijk",
|
||||
address_1: "24 Dunks Drive",
|
||||
city: "Los Angeles",
|
||||
country_code: "US",
|
||||
province: "CA",
|
||||
postal_code: "93011",
|
||||
phone: "+1 (222) 333 4444",
|
||||
},
|
||||
shipping_address: {
|
||||
first_name: "Virgil",
|
||||
last_name: "Van Dijk",
|
||||
address_1: "24 Dunks Drive",
|
||||
city: "Los Angeles",
|
||||
country_code: "US",
|
||||
province: "CA",
|
||||
postal_code: "93011",
|
||||
phone: "+1 (222) 333 4444",
|
||||
},
|
||||
items: [
|
||||
{
|
||||
_id: IdMap.getId("existingLine"),
|
||||
title: "merge line",
|
||||
description: "This is a new line",
|
||||
thumbnail: "test-img-yeah.com/thumb",
|
||||
content: {
|
||||
unit_price: 123,
|
||||
variant: {
|
||||
_id: IdMap.getId("can-cover"),
|
||||
},
|
||||
product: {
|
||||
_id: IdMap.getId("validId"),
|
||||
},
|
||||
quantity: 1,
|
||||
},
|
||||
quantity: 10,
|
||||
},
|
||||
],
|
||||
region: IdMap.getId("testRegion"),
|
||||
customer_id: IdMap.getId("testCustomer"),
|
||||
payment_method: {
|
||||
provider_id: "default_provider",
|
||||
data: {},
|
||||
},
|
||||
shipping_method: [
|
||||
{
|
||||
provider_id: "default_provider",
|
||||
profile_id: IdMap.getId("validId"),
|
||||
price: 123,
|
||||
data: {},
|
||||
items: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
adminSession: {
|
||||
jwt: {
|
||||
userId: IdMap.getId("admin_user"),
|
||||
},
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
it("returns 200", () => {
|
||||
expect(subject.status).toEqual(200)
|
||||
})
|
||||
|
||||
it("calls OrderService create", () => {
|
||||
expect(OrderServiceMock.create).toHaveBeenCalledTimes(1)
|
||||
expect(OrderServiceMock.create).toHaveBeenCalledWith({
|
||||
email: "virgil@vandijk.dk",
|
||||
billing_address: {
|
||||
first_name: "Virgil",
|
||||
last_name: "Van Dijk",
|
||||
address_1: "24 Dunks Drive",
|
||||
city: "Los Angeles",
|
||||
country_code: "US",
|
||||
province: "CA",
|
||||
postal_code: "93011",
|
||||
phone: "+1 (222) 333 4444",
|
||||
},
|
||||
shipping_address: {
|
||||
first_name: "Virgil",
|
||||
last_name: "Van Dijk",
|
||||
address_1: "24 Dunks Drive",
|
||||
city: "Los Angeles",
|
||||
country_code: "US",
|
||||
province: "CA",
|
||||
postal_code: "93011",
|
||||
phone: "+1 (222) 333 4444",
|
||||
},
|
||||
items: [
|
||||
{
|
||||
_id: IdMap.getId("existingLine"),
|
||||
title: "merge line",
|
||||
description: "This is a new line",
|
||||
thumbnail: "test-img-yeah.com/thumb",
|
||||
content: {
|
||||
unit_price: 123,
|
||||
variant: {
|
||||
_id: IdMap.getId("can-cover"),
|
||||
},
|
||||
product: {
|
||||
_id: IdMap.getId("validId"),
|
||||
},
|
||||
quantity: 1,
|
||||
},
|
||||
quantity: 10,
|
||||
},
|
||||
],
|
||||
region: IdMap.getId("testRegion"),
|
||||
customer_id: IdMap.getId("testCustomer"),
|
||||
payment_method: {
|
||||
provider_id: "default_provider",
|
||||
data: {},
|
||||
},
|
||||
shipping_method: [
|
||||
{
|
||||
provider_id: "default_provider",
|
||||
profile_id: IdMap.getId("validId"),
|
||||
price: 123,
|
||||
data: {},
|
||||
items: [],
|
||||
},
|
||||
],
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -1,35 +0,0 @@
|
||||
import { IdMap } from "medusa-test-utils"
|
||||
import { request } from "../../../../../helpers/test-request"
|
||||
import { OrderServiceMock } from "../../../../../services/__mocks__/order"
|
||||
|
||||
describe("DELETE /admin/orders/:id/metadata/key", () => {
|
||||
describe("successfully deletes metadata on order", () => {
|
||||
let subject
|
||||
|
||||
beforeAll(async () => {
|
||||
subject = await request(
|
||||
"DELETE",
|
||||
`/admin/orders/${IdMap.getId("test-order")}/metadata/test-key`,
|
||||
{
|
||||
adminSession: {
|
||||
jwt: {
|
||||
userId: IdMap.getId("admin_user"),
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
it("returns 200", () => {
|
||||
expect(subject.status).toEqual(200)
|
||||
})
|
||||
|
||||
it("calls OrderService deleteMetadata", () => {
|
||||
expect(OrderServiceMock.deleteMetadata).toHaveBeenCalledTimes(1)
|
||||
expect(OrderServiceMock.deleteMetadata).toHaveBeenCalledWith(
|
||||
IdMap.getId("test-order"),
|
||||
"test-key"
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -92,7 +92,7 @@ export class AdminPostOrdersOrderFulfillmentsReq {
|
||||
|
||||
@IsObject()
|
||||
@IsOptional()
|
||||
metadata?: object
|
||||
metadata?: Record<string, unknown>
|
||||
}
|
||||
|
||||
class Item {
|
||||
|
||||
@@ -1,203 +0,0 @@
|
||||
import { Type } from "class-transformer"
|
||||
import {
|
||||
IsEmail,
|
||||
IsOptional,
|
||||
ValidateNested,
|
||||
IsArray,
|
||||
IsString,
|
||||
IsBoolean,
|
||||
IsObject,
|
||||
IsInt,
|
||||
IsNotEmpty,
|
||||
} from "class-validator"
|
||||
import { OrderService } from "../../../../services"
|
||||
import { AddressPayload } from "../../../../types/common"
|
||||
import { validator } from "../../../../utils/validator"
|
||||
/**
|
||||
* @oas [post] /orders
|
||||
* operationId: "PostOrders"
|
||||
* summary: "Create an order"
|
||||
* description: "Creates and order"
|
||||
* x-authenticated: true
|
||||
* requestBody:
|
||||
* content:
|
||||
* application/json:
|
||||
* required:
|
||||
* - email
|
||||
* - billing_address
|
||||
* - shipping_address
|
||||
* - items
|
||||
* - region
|
||||
* - customer_id
|
||||
* - payment_method
|
||||
* - shipping_method
|
||||
* schema:
|
||||
* properties:
|
||||
* status:
|
||||
* description: status of the order
|
||||
* type: string
|
||||
* email:
|
||||
* description: the email for the order
|
||||
* type: string
|
||||
* billing_address:
|
||||
* description: Billing address
|
||||
* anyOf:
|
||||
* - $ref: "#/components/schemas/address
|
||||
* shipping_address:
|
||||
* description: Shipping address
|
||||
* anyOf:
|
||||
* - $ref: "#/components/schemas/address
|
||||
* items:
|
||||
* description: The Line Items for the order
|
||||
* type: array
|
||||
* region:
|
||||
* description: Region where the order belongs
|
||||
* type: string
|
||||
* discounts:
|
||||
* description: Discounts applied to the order
|
||||
* type: array
|
||||
* customer_id:
|
||||
* description: id of the customer
|
||||
* type: string
|
||||
* payment_method:
|
||||
* description: payment method chosen for the order
|
||||
* type: object
|
||||
* required:
|
||||
* - provider_id
|
||||
* properties:
|
||||
* provider_id:
|
||||
* type: string
|
||||
* description: id of the payment provider
|
||||
* data:
|
||||
* description: Data relevant for the given payment method
|
||||
* type: object
|
||||
* shipping_method:
|
||||
* description: The Shipping Method used for shipping the order.
|
||||
* type: object
|
||||
* required:
|
||||
* - provider_id
|
||||
* - profile_id
|
||||
* - price
|
||||
* properties:
|
||||
* provider_id:
|
||||
* type: string
|
||||
* description: The id of the shipping provider.
|
||||
* profile_id:
|
||||
* type: string
|
||||
* description: The id of the shipping profile.
|
||||
* price:
|
||||
* type: integer
|
||||
* description: The price of the shipping.
|
||||
* data:
|
||||
* type: object
|
||||
* description: Data relevant to the specific shipping method.
|
||||
* items:
|
||||
* type: array
|
||||
* description: Items to ship
|
||||
* no_notification:
|
||||
* description: A flag to indicate if no notifications should be emitted related to the updated order.
|
||||
* type: boolean
|
||||
* tags:
|
||||
* - Order
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* order:
|
||||
* $ref: "#/components/schemas/order"
|
||||
*/
|
||||
|
||||
export default async (req, res) => {
|
||||
const validated = await validator(AdminPostOrdersReq, req.body)
|
||||
|
||||
const orderService: OrderService = req.scope.resolve("orderService")
|
||||
let order = await orderService.create(validated)
|
||||
order = await orderService.decorate(order, [], ["region"])
|
||||
|
||||
res.status(200).json({ order })
|
||||
}
|
||||
|
||||
export class AdminPostOrdersReq {
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
status?: string
|
||||
|
||||
@IsEmail()
|
||||
@IsNotEmpty()
|
||||
email: string
|
||||
|
||||
@IsNotEmpty()
|
||||
@ValidateNested()
|
||||
@Type(() => AddressPayload)
|
||||
billing_address: AddressPayload
|
||||
|
||||
@IsNotEmpty()
|
||||
@ValidateNested()
|
||||
@Type(() => AddressPayload)
|
||||
shipping_address: AddressPayload
|
||||
|
||||
@IsArray()
|
||||
@IsNotEmpty()
|
||||
items: object[]
|
||||
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
region: string
|
||||
|
||||
@IsArray()
|
||||
@IsOptional()
|
||||
discounts?: object[]
|
||||
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
customer_id: string
|
||||
|
||||
@IsNotEmpty()
|
||||
@ValidateNested()
|
||||
@Type(() => PaymentMethod)
|
||||
payment_method: PaymentMethod
|
||||
|
||||
@IsNotEmpty()
|
||||
@ValidateNested({ each: true })
|
||||
@Type(() => ShippingMethod)
|
||||
shipping_method?: ShippingMethod[]
|
||||
|
||||
@IsBoolean()
|
||||
@IsOptional()
|
||||
no_notification?: boolean
|
||||
}
|
||||
|
||||
class PaymentMethod {
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
provider_id: string
|
||||
|
||||
@IsObject()
|
||||
@IsOptional()
|
||||
data?: object
|
||||
}
|
||||
|
||||
class ShippingMethod {
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
provider_id: string
|
||||
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
profile_id: string
|
||||
|
||||
@IsInt()
|
||||
@IsNotEmpty()
|
||||
price: number
|
||||
|
||||
@IsObject()
|
||||
@IsOptional()
|
||||
data?: object
|
||||
|
||||
@IsArray()
|
||||
@IsOptional()
|
||||
items?: object[]
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
import { defaultAdminOrdersRelations, defaultAdminOrdersFields } from "."
|
||||
import { OrderService } from "../../../../services"
|
||||
import { validator } from "../../../../utils/validator"
|
||||
import { TrackingLink } from "../../../../models"
|
||||
/**
|
||||
* @oas [post] /orders/{id}/shipment
|
||||
* operationId: "PostOrdersOrderShipment"
|
||||
@@ -56,8 +57,13 @@ export default async (req, res) => {
|
||||
await orderService.createShipment(
|
||||
id,
|
||||
validated.fulfillment_id,
|
||||
validated.tracking_numbers?.map((n) => ({ tracking_number: n })),
|
||||
{ no_notification: validated.no_notification }
|
||||
validated.tracking_numbers?.map((n) => ({
|
||||
tracking_number: n,
|
||||
})) as TrackingLink[],
|
||||
{
|
||||
metadata: {},
|
||||
no_notification: validated.no_notification,
|
||||
}
|
||||
)
|
||||
|
||||
const order = await orderService.retrieve(id, {
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
import { OrderService } from "../../../../services"
|
||||
|
||||
/**
|
||||
* @oas [delete] /order/{id}/metadata/{key}
|
||||
* operationId: "DeleteOrdersOrderMetadataKey"
|
||||
* summary: "Delete Metadata"
|
||||
* description: "Deletes a metadata key."
|
||||
* x-authenticated: true
|
||||
* parameters:
|
||||
* - (path) id=* {string} The id of the Order.
|
||||
* - (path) key=* {string} The metadata key.
|
||||
* tags:
|
||||
* - Order
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* order:
|
||||
* $ref: "#/components/schemas/order"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const { id, key } = req.params
|
||||
|
||||
const orderService: OrderService = req.scope.resolve("orderService")
|
||||
|
||||
await orderService.deleteMetadata(id, key)
|
||||
|
||||
const order = await orderService.retrieve(id, {
|
||||
relations: ["region", "customer", "swaps"],
|
||||
})
|
||||
|
||||
res.status(200).json({ order })
|
||||
}
|
||||
@@ -48,11 +48,6 @@ export default (app, featureFlagRouter: FlagRouter) => {
|
||||
middlewares.wrap(require("./get-order").default)
|
||||
)
|
||||
|
||||
/**
|
||||
* Create a new order
|
||||
*/
|
||||
route.post("/", middlewares.wrap(require("./create-order").default))
|
||||
|
||||
/**
|
||||
* Update an order
|
||||
*/
|
||||
@@ -225,14 +220,6 @@ export default (app, featureFlagRouter: FlagRouter) => {
|
||||
middlewares.wrap(require("./create-claim-shipment").default)
|
||||
)
|
||||
|
||||
/**
|
||||
* Delete metadata key / value pair.
|
||||
*/
|
||||
route.delete(
|
||||
"/:id/metadata/:key",
|
||||
middlewares.wrap(require("./delete-metadata").default)
|
||||
)
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
@@ -314,7 +301,7 @@ export const defaultAdminOrdersFields = [
|
||||
"paid_total",
|
||||
"refundable_amount",
|
||||
"no_notification",
|
||||
]
|
||||
] as (keyof Order)[]
|
||||
|
||||
export const allowedAdminOrdersFields = [
|
||||
"id",
|
||||
@@ -393,11 +380,9 @@ export * from "./complete-order"
|
||||
export * from "./create-claim"
|
||||
export * from "./create-claim-shipment"
|
||||
export * from "./create-fulfillment"
|
||||
export * from "./create-order"
|
||||
export * from "./create-shipment"
|
||||
export * from "./create-swap"
|
||||
export * from "./create-swap-shipment"
|
||||
export * from "./delete-metadata"
|
||||
export * from "./fulfill-claim"
|
||||
export * from "./fulfill-swap"
|
||||
export * from "./get-order"
|
||||
|
||||
@@ -3,6 +3,7 @@ import { pick } from "lodash"
|
||||
import { OrderService } from "../../../../services"
|
||||
import { AdminListOrdersSelector } from "../../../../types/orders"
|
||||
import { Type } from "class-transformer"
|
||||
import { Order } from "../../../../models"
|
||||
|
||||
/**
|
||||
* @oas [get] /orders
|
||||
@@ -55,7 +56,7 @@ export default async (req, res) => {
|
||||
req.listConfig
|
||||
)
|
||||
|
||||
let data = orders
|
||||
let data: Partial<Order>[] = orders
|
||||
|
||||
const fields = [...select, ...relations]
|
||||
if (fields.length) {
|
||||
|
||||
@@ -52,17 +52,17 @@ import { validator } from "../../../../utils/validator"
|
||||
* type: string
|
||||
* payment_method:
|
||||
* description:
|
||||
* type: object
|
||||
* type: Record<string, unknown>
|
||||
* properties:
|
||||
* provider_id:
|
||||
* type: string
|
||||
* description: id of the payment provider
|
||||
* data:
|
||||
* description: Data relevant for the given payment method
|
||||
* type: object
|
||||
* type: Record<string, unknown>
|
||||
* shipping_method:
|
||||
* description: The Shipping Method used for shipping the order.
|
||||
* type: object
|
||||
* type: Record<string, unknown>
|
||||
* properties:
|
||||
* provider_id:
|
||||
* type: string
|
||||
@@ -74,7 +74,7 @@ import { validator } from "../../../../utils/validator"
|
||||
* type: integer
|
||||
* description: The price of the shipping.
|
||||
* data:
|
||||
* type: object
|
||||
* type: Record<string, unknown>
|
||||
* description: Data relevant to the specific shipping method.
|
||||
* items:
|
||||
* type: array
|
||||
@@ -129,7 +129,7 @@ export class AdminPostOrdersOrderReq {
|
||||
|
||||
@IsArray()
|
||||
@IsOptional()
|
||||
items?: object[]
|
||||
items?: Record<string, unknown>[]
|
||||
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
@@ -137,7 +137,7 @@ export class AdminPostOrdersOrderReq {
|
||||
|
||||
@IsArray()
|
||||
@IsOptional()
|
||||
discounts?: object[]
|
||||
discounts?: Record<string, unknown>[]
|
||||
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
@@ -165,7 +165,7 @@ class PaymentMethod {
|
||||
|
||||
@IsObject()
|
||||
@IsOptional()
|
||||
data?: object
|
||||
data?: Record<string, unknown>
|
||||
}
|
||||
|
||||
class ShippingMethod {
|
||||
@@ -183,9 +183,9 @@ class ShippingMethod {
|
||||
|
||||
@IsObject()
|
||||
@IsOptional()
|
||||
data?: object
|
||||
data?: Record<string, unknown>
|
||||
|
||||
@IsArray()
|
||||
@IsOptional()
|
||||
items?: object[]
|
||||
items?: Record<string, unknown>[]
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ import {
|
||||
allowedStoreOrdersFields,
|
||||
allowedStoreOrdersRelations,
|
||||
} from "../orders"
|
||||
import { FindConfig } from "../../../../types/common"
|
||||
import { Order } from "../../../../models"
|
||||
|
||||
/**
|
||||
* @oas [get] /customers/me/orders
|
||||
@@ -77,7 +79,7 @@ export default async (req, res) => {
|
||||
skip: validated.offset,
|
||||
take: validated.limit,
|
||||
order: { created_at: "DESC" },
|
||||
}
|
||||
} as FindConfig<Order>
|
||||
|
||||
const [orders, count] = await orderService.listAndCount(selector, listConfig)
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ export const defaultStoreOrdersFields = [
|
||||
"gift_card_total",
|
||||
"subtotal",
|
||||
"total",
|
||||
]
|
||||
] as (keyof Order)[]
|
||||
|
||||
export const allowedStoreOrdersRelations = [
|
||||
"shipping_address",
|
||||
|
||||
@@ -65,4 +65,5 @@ export * from "./store"
|
||||
export * from "./swap"
|
||||
export * from "./tax-provider"
|
||||
export * from "./tax-rate"
|
||||
export * from "./tracking-link"
|
||||
export * from "./user"
|
||||
|
||||
@@ -242,7 +242,7 @@ export class Order extends BaseEntity {
|
||||
// Total fields
|
||||
shipping_total: number
|
||||
discount_total: number
|
||||
tax_total: number
|
||||
tax_total: number | null
|
||||
refunded_total: number
|
||||
total: number
|
||||
subtotal: number
|
||||
|
||||
@@ -7,10 +7,10 @@ import {
|
||||
ManyToOne,
|
||||
Unique,
|
||||
} from "typeorm"
|
||||
import { BaseEntity } from "../interfaces/models/base-entity"
|
||||
import { BaseEntity } from "../interfaces"
|
||||
import { DbAwareColumn } from "../utils/db-aware-column"
|
||||
import { Cart } from "./cart"
|
||||
import { generateEntityId } from "../utils/generate-entity-id"
|
||||
import { generateEntityId } from "../utils"
|
||||
|
||||
export enum PaymentSessionStatus {
|
||||
AUTHORIZED = "authorized",
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Order } from "../models"
|
||||
@EntityRepository(Order)
|
||||
export class OrderRepository extends Repository<Order> {
|
||||
public async findWithRelations(
|
||||
relations: Array<keyof Order> = [],
|
||||
relations: string[] = [],
|
||||
optionsWithoutRelations: Omit<FindManyOptions<Order>, "relations"> = {}
|
||||
): Promise<Order[]> {
|
||||
const entities = await this.find(optionsWithoutRelations)
|
||||
@@ -38,7 +38,7 @@ export class OrderRepository extends Repository<Order> {
|
||||
}
|
||||
|
||||
public async findOneWithRelations(
|
||||
relations: Array<keyof Order> = [],
|
||||
relations: string[] = [],
|
||||
optionsWithoutRelations: Omit<FindManyOptions<Order>, "relations"> = {}
|
||||
): Promise<Order> {
|
||||
// Limit 1
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { IdMap } from "medusa-test-utils"
|
||||
|
||||
export const TotalsServiceMock = {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
getTotal: jest.fn().mockImplementation((cart) => {
|
||||
if (cart.total) {
|
||||
return cart.total
|
||||
|
||||
@@ -15,6 +15,9 @@ const eventBusService = {
|
||||
|
||||
describe("CartService", () => {
|
||||
const totalsService = {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
getTotal: (o) => {
|
||||
return o.total || 0
|
||||
},
|
||||
|
||||
@@ -4,6 +4,9 @@ import { InventoryServiceMock } from "../__mocks__/inventory"
|
||||
|
||||
describe("OrderService", () => {
|
||||
const totalsService = {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
getLineItemRefund: () => {},
|
||||
getTotal: (o) => {
|
||||
return o.total || 0
|
||||
@@ -45,35 +48,6 @@ describe("OrderService", () => {
|
||||
...InventoryServiceMock,
|
||||
}
|
||||
|
||||
describe("create", () => {
|
||||
const orderRepo = MockRepository({ create: (f) => f })
|
||||
const orderService = new OrderService({
|
||||
manager: MockManager,
|
||||
orderRepository: orderRepo,
|
||||
totalsService,
|
||||
eventBusService,
|
||||
})
|
||||
|
||||
beforeEach(async () => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
it("calls order model functions", async () => {
|
||||
await orderService.create({
|
||||
email: "oliver@test.dk",
|
||||
})
|
||||
|
||||
expect(orderRepo.create).toHaveBeenCalledTimes(1)
|
||||
expect(orderRepo.create).toHaveBeenCalledWith({
|
||||
email: "oliver@test.dk",
|
||||
})
|
||||
|
||||
expect(orderRepo.save).toHaveBeenCalledWith({
|
||||
email: "oliver@test.dk",
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("createFromCart", () => {
|
||||
const orderRepo = MockRepository({
|
||||
create: (p) => p,
|
||||
@@ -336,7 +310,7 @@ describe("OrderService", () => {
|
||||
expect(giftCardService.update).toHaveBeenCalledTimes(1)
|
||||
expect(giftCardService.update).toHaveBeenCalledWith("gid", {
|
||||
balance: 0,
|
||||
disabled: true,
|
||||
is_disabled: true,
|
||||
})
|
||||
|
||||
expect(giftCardService.createTransaction).toHaveBeenCalledTimes(1)
|
||||
|
||||
@@ -1,12 +1,5 @@
|
||||
import { In } from "typeorm"
|
||||
import { IdMap, MockRepository, MockManager } from "medusa-test-utils"
|
||||
import ShippingProfileService from "../shipping-profile"
|
||||
//import { ShippingProfileModelMock } from "../../models/__mocks__/shipping-profile"
|
||||
//import { ProductServiceMock, products } from "../__mocks__/product"
|
||||
//import {
|
||||
// ShippingOptionServiceMock,
|
||||
// shippingOptions,
|
||||
//} from "../__mocks__/shipping-option"
|
||||
|
||||
describe("ShippingProfileService", () => {
|
||||
describe("retrieve", () => {
|
||||
@@ -202,6 +195,9 @@ describe("ShippingProfileService", () => {
|
||||
}
|
||||
|
||||
const customShippingOptionService = {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
list: jest.fn().mockImplementation(({ cart_id }, config) => {
|
||||
if (cart_id === "cso-cart") {
|
||||
return Promise.resolve([
|
||||
|
||||
@@ -100,7 +100,11 @@ const calculateAdjustment = (cart, lineItem, discount) => {
|
||||
|
||||
describe("TotalsService", () => {
|
||||
const container = {
|
||||
taxProviderService: {},
|
||||
taxProviderService: {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
},
|
||||
taxCalculationStrategy: {},
|
||||
}
|
||||
|
||||
@@ -537,6 +541,9 @@ describe("TotalsService", () => {
|
||||
|
||||
const cradle = {
|
||||
taxProviderService: {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
getTaxLines: getTaxLinesMock,
|
||||
},
|
||||
taxCalculationStrategy: {
|
||||
|
||||
@@ -302,7 +302,7 @@ class FulfillmentService extends TransactionBaseService<FulfillmentService> {
|
||||
*/
|
||||
async createShipment(
|
||||
fulfillmentId: string,
|
||||
trackingLinks: { tracking_number: string }[],
|
||||
trackingLinks?: { tracking_number: string }[],
|
||||
config: CreateShipmentConfig = {
|
||||
metadata: {},
|
||||
no_notification: undefined,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -407,14 +407,12 @@ class PricingService extends TransactionBaseService<PricingService> {
|
||||
pricingContext.automatic_taxes &&
|
||||
pricingContext.price_selection.region_id
|
||||
) {
|
||||
shippingOptionRates =
|
||||
await this.taxProviderService.getRegionRatesForShipping(
|
||||
shippingOption.id,
|
||||
{
|
||||
id: pricingContext.price_selection.region_id,
|
||||
tax_rate: pricingContext.tax_rate,
|
||||
}
|
||||
)
|
||||
shippingOptionRates = await this.taxProviderService
|
||||
.withTransaction(this.manager_)
|
||||
.getRegionRatesForShipping(shippingOption.id, {
|
||||
id: pricingContext.price_selection.region_id,
|
||||
tax_rate: pricingContext.tax_rate,
|
||||
})
|
||||
}
|
||||
|
||||
const price = shippingOption.amount || 0
|
||||
|
||||
@@ -430,12 +430,14 @@ class ShippingProfileService extends BaseService {
|
||||
admin_only: false,
|
||||
}
|
||||
|
||||
const customShippingOptions = await this.customShippingOptionService_.list(
|
||||
{
|
||||
cart_id: cart.id,
|
||||
},
|
||||
{ select: ["id", "shipping_option_id", "price"] }
|
||||
)
|
||||
const customShippingOptions = await this.customShippingOptionService_
|
||||
.withTransaction(this.manager_)
|
||||
.list(
|
||||
{
|
||||
cart_id: cart.id,
|
||||
},
|
||||
{ select: ["id", "shipping_option_id", "price"] }
|
||||
)
|
||||
|
||||
const hasCustomShippingOptions = customShippingOptions?.length
|
||||
// if there are custom shipping options associated with the cart, use those
|
||||
@@ -443,9 +445,11 @@ class ShippingProfileService extends BaseService {
|
||||
selector.id = customShippingOptions.map((cso) => cso.shipping_option_id)
|
||||
}
|
||||
|
||||
const rawOpts = await this.shippingOptionService_.list(selector, {
|
||||
relations: ["requirements", "profile"],
|
||||
})
|
||||
const rawOpts = await this.shippingOptionService_
|
||||
.withTransaction(this.manager_)
|
||||
.list(selector, {
|
||||
relations: ["requirements", "profile"],
|
||||
})
|
||||
|
||||
// if there are custom shipping options associated with the cart, return cart shipping options with custom price
|
||||
if (hasCustomShippingOptions) {
|
||||
@@ -464,10 +468,9 @@ class ShippingProfileService extends BaseService {
|
||||
const options = await Promise.all(
|
||||
rawOpts.map(async (so) => {
|
||||
try {
|
||||
const option = await this.shippingOptionService_.validateCartOption(
|
||||
so,
|
||||
cart
|
||||
)
|
||||
const option = await this.shippingOptionService_
|
||||
.withTransaction(this.manager_)
|
||||
.validateCartOption(so, cart)
|
||||
if (option) {
|
||||
return option
|
||||
}
|
||||
|
||||
@@ -1,30 +1,32 @@
|
||||
import { MedusaError } from "medusa-core-utils"
|
||||
import { AwilixContainer } from "awilix"
|
||||
import { BaseService } from "medusa-interfaces"
|
||||
import { EntityManager, UpdateResult } from "typeorm"
|
||||
import { EntityManager } from "typeorm"
|
||||
import Redis from "ioredis"
|
||||
|
||||
import { LineItemTaxLineRepository } from "../repositories/line-item-tax-line"
|
||||
import { ShippingMethodTaxLineRepository } from "../repositories/shipping-method-tax-line"
|
||||
import { TaxProviderRepository } from "../repositories/tax-provider"
|
||||
import { LineItemTaxLine } from "../models/line-item-tax-line"
|
||||
import { TaxProvider } from "../models/tax-provider"
|
||||
import { LineItem } from "../models/line-item"
|
||||
import { ShippingMethodTaxLine } from "../models/shipping-method-tax-line"
|
||||
import { ShippingMethod } from "../models/shipping-method"
|
||||
import { Region } from "../models/region"
|
||||
import { Cart } from "../models/cart"
|
||||
import {
|
||||
LineItemTaxLine,
|
||||
TaxProvider,
|
||||
LineItem,
|
||||
ShippingMethodTaxLine,
|
||||
ShippingMethod,
|
||||
Region,
|
||||
Cart,
|
||||
} from "../models"
|
||||
import { isCart } from "../types/cart"
|
||||
import { PostgresError } from "../utils/exception-formatter"
|
||||
import {
|
||||
ITaxService,
|
||||
ItemTaxCalculationLine,
|
||||
TaxCalculationContext,
|
||||
} from "../interfaces/tax-service"
|
||||
TransactionBaseService,
|
||||
} from "../interfaces"
|
||||
|
||||
import { TaxServiceRate } from "../types/tax-service"
|
||||
|
||||
import TaxRateService from "./tax-rate"
|
||||
import EventBusService from "./event-bus"
|
||||
|
||||
const CACHE_TIME = 30 // seconds
|
||||
|
||||
@@ -36,18 +38,20 @@ type RegionDetails = {
|
||||
/**
|
||||
* Finds tax providers and assists in tax related operations.
|
||||
*/
|
||||
class TaxProviderService extends BaseService {
|
||||
private container_: AwilixContainer
|
||||
private manager_: EntityManager
|
||||
private transactionManager_: EntityManager
|
||||
private taxRateService_: TaxRateService
|
||||
private taxLineRepo_: typeof LineItemTaxLineRepository
|
||||
private smTaxLineRepo_: typeof ShippingMethodTaxLineRepository
|
||||
private taxProviderRepo_: typeof TaxProviderRepository
|
||||
private redis_: Redis
|
||||
class TaxProviderService extends TransactionBaseService<TaxProviderService> {
|
||||
protected manager_: EntityManager
|
||||
protected transactionManager_: EntityManager
|
||||
|
||||
protected readonly container_: AwilixContainer
|
||||
protected readonly taxRateService_: TaxRateService
|
||||
protected readonly taxLineRepo_: typeof LineItemTaxLineRepository
|
||||
protected readonly smTaxLineRepo_: typeof ShippingMethodTaxLineRepository
|
||||
protected readonly taxProviderRepo_: typeof TaxProviderRepository
|
||||
protected readonly redis_: Redis
|
||||
protected readonly eventBus_: EventBusService
|
||||
|
||||
constructor(container: AwilixContainer) {
|
||||
super()
|
||||
super(container)
|
||||
|
||||
this.container_ = container
|
||||
this.taxLineRepo_ = container["lineItemTaxLineRepository"]
|
||||
@@ -59,19 +63,6 @@ class TaxProviderService extends BaseService {
|
||||
this.redis_ = container["redisClient"]
|
||||
}
|
||||
|
||||
withTransaction(transactionManager: EntityManager): TaxProviderService {
|
||||
if (!transactionManager) {
|
||||
return this
|
||||
}
|
||||
|
||||
const cloned = new TaxProviderService(this.container_)
|
||||
|
||||
cloned.transactionManager_ = transactionManager
|
||||
cloned.manager_ = transactionManager
|
||||
|
||||
return cloned
|
||||
}
|
||||
|
||||
async list(): Promise<TaxProvider[]> {
|
||||
const tpRepo = this.manager_.getCustomRepository(this.taxProviderRepo_)
|
||||
return tpRepo.find({})
|
||||
@@ -101,15 +92,19 @@ class TaxProviderService extends BaseService {
|
||||
}
|
||||
|
||||
async clearTaxLines(cartId: string): Promise<void> {
|
||||
const taxLineRepo = this.manager_.getCustomRepository(this.taxLineRepo_)
|
||||
const shippingTaxRepo = this.manager_.getCustomRepository(
|
||||
this.smTaxLineRepo_
|
||||
)
|
||||
return await this.atomicPhase_(async (transactionManager) => {
|
||||
const taxLineRepo = transactionManager.getCustomRepository(
|
||||
this.taxLineRepo_
|
||||
)
|
||||
const shippingTaxRepo = transactionManager.getCustomRepository(
|
||||
this.smTaxLineRepo_
|
||||
)
|
||||
|
||||
await Promise.all([
|
||||
taxLineRepo.deleteForCart(cartId),
|
||||
shippingTaxRepo.deleteForCart(cartId),
|
||||
])
|
||||
await Promise.all([
|
||||
taxLineRepo.deleteForCart(cartId),
|
||||
shippingTaxRepo.deleteForCart(cartId),
|
||||
])
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -122,43 +117,47 @@ class TaxProviderService extends BaseService {
|
||||
cartOrLineItems: Cart | LineItem[],
|
||||
calculationContext: TaxCalculationContext
|
||||
): Promise<(ShippingMethodTaxLine | LineItemTaxLine)[]> {
|
||||
let taxLines: (ShippingMethodTaxLine | LineItemTaxLine)[] = []
|
||||
if (isCart(cartOrLineItems)) {
|
||||
taxLines = await this.getTaxLines(
|
||||
cartOrLineItems.items,
|
||||
calculationContext
|
||||
return await this.atomicPhase_(async (transactionManager) => {
|
||||
let taxLines: (ShippingMethodTaxLine | LineItemTaxLine)[] = []
|
||||
if (isCart(cartOrLineItems)) {
|
||||
taxLines = await this.getTaxLines(
|
||||
cartOrLineItems.items,
|
||||
calculationContext
|
||||
)
|
||||
} else {
|
||||
taxLines = await this.getTaxLines(cartOrLineItems, calculationContext)
|
||||
}
|
||||
|
||||
const itemTaxLineRepo = transactionManager.getCustomRepository(
|
||||
this.taxLineRepo_
|
||||
)
|
||||
const shippingTaxLineRepo = transactionManager.getCustomRepository(
|
||||
this.smTaxLineRepo_
|
||||
)
|
||||
} else {
|
||||
taxLines = await this.getTaxLines(cartOrLineItems, calculationContext)
|
||||
}
|
||||
|
||||
const itemTaxLineRepo = this.manager_.getCustomRepository(this.taxLineRepo_)
|
||||
const shippingTaxLineRepo = this.manager_.getCustomRepository(
|
||||
this.smTaxLineRepo_
|
||||
)
|
||||
const { shipping, lineItems } = taxLines.reduce<{
|
||||
shipping: ShippingMethodTaxLine[]
|
||||
lineItems: LineItemTaxLine[]
|
||||
}>(
|
||||
(acc, tl) => {
|
||||
if ("item_id" in tl) {
|
||||
acc.lineItems.push(tl)
|
||||
} else {
|
||||
acc.shipping.push(tl)
|
||||
}
|
||||
|
||||
const { shipping, lineItems } = taxLines.reduce<{
|
||||
shipping: ShippingMethodTaxLine[]
|
||||
lineItems: LineItemTaxLine[]
|
||||
}>(
|
||||
(acc, tl) => {
|
||||
if ("item_id" in tl) {
|
||||
acc.lineItems.push(tl)
|
||||
} else {
|
||||
acc.shipping.push(tl)
|
||||
}
|
||||
return acc
|
||||
},
|
||||
{ shipping: [], lineItems: [] }
|
||||
)
|
||||
|
||||
return acc
|
||||
},
|
||||
{ shipping: [], lineItems: [] }
|
||||
)
|
||||
|
||||
return (
|
||||
await Promise.all([
|
||||
itemTaxLineRepo.upsertLines(lineItems),
|
||||
shippingTaxLineRepo.upsertLines(shipping),
|
||||
])
|
||||
).flat()
|
||||
return (
|
||||
await Promise.all([
|
||||
itemTaxLineRepo.upsertLines(lineItems),
|
||||
shippingTaxLineRepo.upsertLines(shipping),
|
||||
])
|
||||
).flat()
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -172,11 +171,13 @@ class TaxProviderService extends BaseService {
|
||||
shippingMethod: ShippingMethod,
|
||||
calculationContext: TaxCalculationContext
|
||||
): Promise<(ShippingMethodTaxLine | LineItemTaxLine)[]> {
|
||||
const taxLines = await this.getShippingTaxLines(
|
||||
shippingMethod,
|
||||
calculationContext
|
||||
)
|
||||
return this.manager_.save(taxLines)
|
||||
return await this.atomicPhase_(async (transactionManager) => {
|
||||
const taxLines = await this.getShippingTaxLines(
|
||||
shippingMethod,
|
||||
calculationContext
|
||||
)
|
||||
return await transactionManager.save(taxLines)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -339,9 +340,9 @@ class TaxProviderService extends BaseService {
|
||||
}
|
||||
|
||||
let toReturn: TaxServiceRate[] = []
|
||||
const optionRates = await this.taxRateService_.listByShippingOption(
|
||||
optionId
|
||||
)
|
||||
const optionRates = await this.taxRateService_
|
||||
.withTransaction(this.manager_)
|
||||
.listByShippingOption(optionId)
|
||||
|
||||
if (optionRates.length > 0) {
|
||||
toReturn = optionRates.map((pr) => {
|
||||
|
||||
@@ -97,9 +97,9 @@ class TotalsService extends TransactionBaseService<TotalsService> {
|
||||
private taxCalculationStrategy_: ITaxCalculationStrategy
|
||||
|
||||
constructor({
|
||||
manager,
|
||||
taxProviderService,
|
||||
taxCalculationStrategy,
|
||||
manager,
|
||||
}: TotalsServiceProps) {
|
||||
super({
|
||||
taxProviderService,
|
||||
@@ -107,6 +107,7 @@ class TotalsService extends TransactionBaseService<TotalsService> {
|
||||
manager,
|
||||
})
|
||||
|
||||
this.manager_ = manager
|
||||
this.taxProviderService_ = taxProviderService
|
||||
this.taxCalculationStrategy_ = taxCalculationStrategy
|
||||
this.manager_ = manager
|
||||
@@ -214,10 +215,9 @@ class TotalsService extends TransactionBaseService<TotalsService> {
|
||||
|
||||
taxLines = shippingMethod.tax_lines
|
||||
} else {
|
||||
const orderLines = await this.taxProviderService_.getTaxLines(
|
||||
cartOrOrder.items,
|
||||
calculationContext
|
||||
)
|
||||
const orderLines = await this.taxProviderService_
|
||||
.withTransaction(this.manager_)
|
||||
.getTaxLines(cartOrOrder.items, calculationContext)
|
||||
|
||||
taxLines = orderLines.filter((ol) => {
|
||||
if ("shipping_method_id" in ol) {
|
||||
@@ -343,10 +343,9 @@ class TotalsService extends TransactionBaseService<TotalsService> {
|
||||
)
|
||||
}
|
||||
} else {
|
||||
taxLines = await this.taxProviderService_.getTaxLines(
|
||||
cartOrOrder.items,
|
||||
calculationContext
|
||||
)
|
||||
taxLines = await this.taxProviderService_
|
||||
.withTransaction(this.manager_)
|
||||
.getTaxLines(cartOrOrder.items, calculationContext)
|
||||
|
||||
if (cartOrOrder.type === "swap") {
|
||||
const returnTaxLines = cartOrOrder.items.flatMap((i) => {
|
||||
|
||||
@@ -15,6 +15,7 @@ import { BatchJobStatus } from "../../../types/batch-job"
|
||||
import { prepareListQuery } from "../../../utils/get-query-config"
|
||||
import { FlagRouter } from "../../../utils/flag-router"
|
||||
import SalesChannelFeatureFlag from "../../../loaders/feature-flags/sales-channels"
|
||||
import { FindConfig } from "../../../types/common"
|
||||
|
||||
type InjectedDependencies = {
|
||||
fileService: IFileService<never>
|
||||
@@ -146,7 +147,7 @@ class OrderExportStrategy extends AbstractBatchJobStrategy<OrderExportStrategy>
|
||||
skip: offset as number,
|
||||
order: { created_at: "DESC" },
|
||||
take: Math.min(batchJob.context.batch_size ?? Infinity, limit),
|
||||
})
|
||||
} as FindConfig<Order>)
|
||||
count = orderCount
|
||||
}
|
||||
|
||||
@@ -199,11 +200,11 @@ class OrderExportStrategy extends AbstractBatchJobStrategy<OrderExportStrategy>
|
||||
order: { created_at: "DESC" },
|
||||
skip: offset,
|
||||
take: Math.min(batchJob.context.batch_size ?? Infinity, limit),
|
||||
}
|
||||
} as FindConfig<Order>
|
||||
)
|
||||
|
||||
orderCount = batchJob.context?.batch_size ?? count
|
||||
let orders = []
|
||||
let orders: Order[] = []
|
||||
|
||||
const lineDescriptor = this.getLineDescriptor(
|
||||
list_config.select as string[],
|
||||
@@ -230,7 +231,7 @@ class OrderExportStrategy extends AbstractBatchJobStrategy<OrderExportStrategy>
|
||||
...list_config,
|
||||
skip: offset,
|
||||
take: Math.min(orderCount - offset, limit),
|
||||
})
|
||||
} as FindConfig<Order>)
|
||||
|
||||
orders.forEach((order) => {
|
||||
const line = this.buildCSVLine(order, lineDescriptor)
|
||||
|
||||
@@ -137,7 +137,7 @@ export const orderExportPropertiesDescriptors: OrderDescriptor[] = [
|
||||
{
|
||||
fieldName: "tax_total",
|
||||
title: "Tax Total",
|
||||
accessor: (order: Order): string => order.tax_total.toString(),
|
||||
accessor: (order: Order): string => order.tax_total?.toString() ?? "",
|
||||
},
|
||||
{
|
||||
fieldName: "total",
|
||||
|
||||
@@ -68,7 +68,7 @@ export type CartUpdateProps = {
|
||||
billing_address?: AddressPayload | string
|
||||
shipping_address?: AddressPayload | string
|
||||
completed_at?: Date
|
||||
payment_authorized_at?: Date
|
||||
payment_authorized_at?: Date | null
|
||||
gift_cards?: GiftCard[]
|
||||
discounts?: Discount[]
|
||||
customer_id?: string
|
||||
|
||||
@@ -19,5 +19,7 @@ export type CreateGiftCardTransactionInput = {
|
||||
gift_card_id: string
|
||||
order_id: string
|
||||
amount: number
|
||||
created_at: Date
|
||||
created_at?: Date
|
||||
is_taxable?: boolean
|
||||
tax_rate?: number | null
|
||||
}
|
||||
|
||||
@@ -9,8 +9,8 @@ import {
|
||||
ValidateNested,
|
||||
} from "class-validator"
|
||||
import { IsType } from "../utils/validators/is-type"
|
||||
import { Order } from "../models/order"
|
||||
import { DateComparisonOperator } from "./common"
|
||||
import { Order, Payment } from "../models"
|
||||
import { AddressPayload, DateComparisonOperator } from "./common"
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export function isOrder(object: any): object is Order {
|
||||
@@ -47,6 +47,55 @@ enum PaymentStatus {
|
||||
requires_action = "requires_action",
|
||||
}
|
||||
|
||||
export type CreateOrderInput = {
|
||||
status?: OrderStatus
|
||||
email: string
|
||||
billing_address: AddressPayload
|
||||
shipping_address: AddressPayload
|
||||
items: Record<string, unknown>[]
|
||||
region: string
|
||||
discounts?: Record<string, unknown>[]
|
||||
customer_id: string
|
||||
payment_method: {
|
||||
provider_id: string
|
||||
ata?: Record<string, unknown>
|
||||
}
|
||||
shipping_method?: {
|
||||
provider_id: string
|
||||
profile_id: string
|
||||
price: number
|
||||
data?: Record<string, unknown>
|
||||
items?: Record<string, unknown>[]
|
||||
}[]
|
||||
no_notification?: boolean
|
||||
}
|
||||
|
||||
export type UpdateOrderInput = {
|
||||
email?: string
|
||||
billing_address?: AddressPayload
|
||||
shipping_address?: AddressPayload
|
||||
items?: object[]
|
||||
region?: string
|
||||
discounts?: object[]
|
||||
customer_id?: string
|
||||
payment_method?: {
|
||||
provider_id?: string
|
||||
data?: Record<string, unknown>
|
||||
}
|
||||
shipping_method?: {
|
||||
provider_id?: string
|
||||
profile_id?: string
|
||||
price?: number
|
||||
data?: Record<string, unknown>
|
||||
items?: Record<string, unknown>[]
|
||||
}[]
|
||||
no_notification?: boolean
|
||||
payment?: Payment
|
||||
status?: OrderStatus
|
||||
fulfillment_status?: FulfillmentStatus
|
||||
payment_status?: PaymentStatus
|
||||
metadata?: Record<string, unknown>
|
||||
}
|
||||
export class AdminListOrdersSelector {
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
|
||||
Reference in New Issue
Block a user