Feat(order): return reason and transaction methods (#7303)

This commit is contained in:
Carlos R. L. Rodrigues
2024-05-13 13:15:25 -03:00
committed by GitHub
parent 8958214350
commit 6c94d0205c
23 changed files with 1036 additions and 6 deletions

View File

@@ -8,7 +8,7 @@ import {
getSelectsAndRelationsFromObjectArray,
promiseAll,
} from "@medusajs/utils"
import { createStep, StepResponse } from "@medusajs/workflows-sdk"
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
type UpdateCustomerGroupStepInput = {
selector: FilterableCustomerGroupProps
@@ -51,6 +51,7 @@ export const updateCustomerGroupsStep = createStep(
prevCustomerGroups.map((c) =>
service.updateCustomerGroups(c.id, {
name: c.name,
metadata: c.metadata,
})
)
)

View File

@@ -0,0 +1,2 @@
export * from "./workflows"
export * from "./steps"

View File

@@ -0,0 +1,36 @@
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
import {
CreateOrderReturnReasonDTO,
IOrderModuleService,
} from "@medusajs/types"
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
export const createReturnReasonsStepId = "create-return-reasons"
export const createReturnReasonsStep = createStep(
createReturnReasonsStepId,
async (data: CreateOrderReturnReasonDTO[], { container }) => {
const service = container.resolve<IOrderModuleService>(
ModuleRegistrationName.ORDER
)
const createdReturnReasons = await service.createReturnReasons(data)
return new StepResponse(
createdReturnReasons,
createdReturnReasons.map(
(createdReturnReasons) => createdReturnReasons.id
)
)
},
async (createdReturnReasonIds, { container }) => {
if (!createdReturnReasonIds?.length) {
return
}
const service = container.resolve<IOrderModuleService>(
ModuleRegistrationName.ORDER
)
await service.deleteReturnReasons(createdReturnReasonIds)
}
)

View File

@@ -0,0 +1,30 @@
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
import { IOrderModuleService } from "@medusajs/types"
import { createStep, StepResponse } from "@medusajs/workflows-sdk"
type DeleteReturnReasonStepInput = string[]
export const deleteReturnReasonStepId = "delete-return-reasons"
export const deleteReturnReasonStep = createStep(
deleteReturnReasonStepId,
async (ids: DeleteReturnReasonStepInput, { container }) => {
const service = container.resolve<IOrderModuleService>(
ModuleRegistrationName.ORDER
)
await service.softDeleteReturnReasons(ids)
return new StepResponse(void 0, ids)
},
async (prevReturnReasons, { container }) => {
if (!prevReturnReasons) {
return
}
const service = container.resolve<IOrderModuleService>(
ModuleRegistrationName.ORDER
)
await service.restoreReturnReasons(prevReturnReasons)
}
)

View File

@@ -0,0 +1,3 @@
export * from "./create-return-reasons"
export * from "./delete-return-reasons"
export * from "./update-return-resons"

View File

@@ -0,0 +1,61 @@
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
import {
FilterableOrderReturnReasonProps,
IOrderModuleService,
ReturnReasonUpdatableFields,
} from "@medusajs/types"
import {
getSelectsAndRelationsFromObjectArray,
promiseAll,
} from "@medusajs/utils"
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
type UpdateReturnReasonStepInput = {
selector: FilterableOrderReturnReasonProps
update: ReturnReasonUpdatableFields
}
export const updateReturnReasonStepId = "update-return-reasons"
export const updateReturnReasonsStep = createStep(
updateReturnReasonStepId,
async (data: UpdateReturnReasonStepInput, { container }) => {
const service = container.resolve<IOrderModuleService>(
ModuleRegistrationName.ORDER
)
const { selects, relations } = getSelectsAndRelationsFromObjectArray([
data.update,
])
const prevReturnReasons = await service.listReturnReasons(data.selector, {
select: selects,
relations,
})
const reasons = await service.updateReturnReasons(
data.selector,
data.update
)
return new StepResponse(reasons, prevReturnReasons)
},
async (prevReturnReasons, { container }) => {
if (!prevReturnReasons) {
return
}
const service = container.resolve<IOrderModuleService>(
ModuleRegistrationName.ORDER
)
await promiseAll(
prevReturnReasons.map((c) =>
service.updateReturnReasons(c.id, {
value: c.value,
label: c.label,
description: c.description,
metadata: c.metadata,
})
)
)
}
)

View File

@@ -0,0 +1,18 @@
import {
CreateOrderReturnReasonDTO,
OrderReturnReasonDTO,
} from "@medusajs/types"
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
import { createReturnReasonsStep } from "../steps"
type WorkflowInput = { data: CreateOrderReturnReasonDTO[] }
export const createReturnReasonsWorkflowId = "create-return-reasons"
export const createReturnReasonsWorkflow = createWorkflow(
createReturnReasonsWorkflowId,
(
input: WorkflowData<WorkflowInput>
): WorkflowData<OrderReturnReasonDTO[]> => {
return createReturnReasonsStep(input.data)
}
)

View File

@@ -0,0 +1,12 @@
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
import { deleteReturnReasonStep } from "../steps"
type WorkflowInput = { ids: string[] }
export const deleteReturnReasonsWorkflowId = "delete-return-reasons"
export const deleteReturnReasonsWorkflow = createWorkflow(
deleteReturnReasonsWorkflowId,
(input: WorkflowData<WorkflowInput>): WorkflowData<void> => {
return deleteReturnReasonStep(input.ids)
}
)

View File

@@ -0,0 +1,3 @@
export * from "./create-return-reasons"
export * from "./delete-return-reasons"
export * from "./update-return-reasons"

View File

@@ -0,0 +1,22 @@
import {
FilterableOrderReturnReasonProps,
OrderReturnReasonDTO,
ReturnReasonUpdatableFields,
} from "@medusajs/types"
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
import { updateReturnReasonsStep } from "../steps"
type WorkflowInput = {
selector: FilterableOrderReturnReasonProps
update: ReturnReasonUpdatableFields
}
export const updateReturnReasonsWorkflowId = "update-return-reasons"
export const updateReturnReasonsWorkflow = createWorkflow(
updateReturnReasonsWorkflowId,
(
input: WorkflowData<WorkflowInput>
): WorkflowData<OrderReturnReasonDTO[]> => {
return updateReturnReasonsStep(input)
}
)

View File

@@ -1255,6 +1255,95 @@ export interface OrderTransactionDTO {
updated_at: Date | string
}
export interface OrderTransactionDTO {
/**
* The ID of the transaction
*/
id: string
/**
* The ID of the associated order
*/
order_id: string
/**
* The associated order
*
* @expandable
*/
order: OrderDTO
/**
* The amount of the transaction
*/
amount: BigNumberValue
/**
* The raw amount of the transaction
*/
raw_amount: BigNumberRawValue
/**
* The currency code of the transaction
*/
currency_code: string
/**
* The reference of the transaction
*/
reference: string
/**
* The ID of the reference
*/
reference_id: string
/**
* The metadata of the transaction
*/
metadata: Record<string, unknown> | null
/**
* When the transaction was created
*/
created_at: Date | string
/**
* When the transaction was updated
*/
updated_at: Date | string
}
export interface OrderReturnReasonDTO {
/**
* The ID of the return reason
*/
id: string
/**
* The unique value of the return reason
*/
value: string
/**
* The label of the return reason
*/
label: string
/**
* The description of the return reason
*/
description?: string
/**
* The parent return reason ID
*/
parent_return_reason_id?: string
parent_return_reason?: OrderReturnReasonDTO
return_reason_children?: OrderReturnReasonDTO[]
/**
* The metadata of the return reason
*/
metadata: Record<string, unknown> | null
/**
* When the return reason was created
*/
created_at: Date | string
/**
* When the return reason was updated
*/
updated_at: Date | string
}
export interface FilterableOrderProps
extends BaseFilterable<FilterableOrderProps> {
id?: string | string[]
@@ -1369,3 +1458,10 @@ export interface FilterableOrderItemProps
version?: string | string[] | OperatorMap<string>
item_id?: string | string[] | OperatorMap<string>
}
export interface FilterableOrderReturnReasonProps {
id?: string | string[]
value?: string | string[]
label?: string
description?: string
}

View File

@@ -1,5 +1,10 @@
import { BigNumberInput } from "../totals"
import { OrderItemDTO, OrderLineItemDTO } from "./common"
import {
OrderItemDTO,
OrderLineItemDTO,
OrderReturnReasonDTO,
OrderTransactionDTO,
} from "./common"
/** ADDRESS START */
export interface UpsertOrderAddressDTO {
@@ -310,10 +315,13 @@ export interface UpdateOrderChangeActionDTO {
export interface CreateOrderTransactionDTO {
order_id: string
description?: string
reference_type?: string
reference_id?: string
internal_note?: string
created_by?: string
amount: BigNumberInput
currency_code: string
reference?: string
reference_id?: string
metadata?: Record<string, unknown> | null
}
@@ -321,11 +329,18 @@ export interface UpdateOrderTransactionDTO {
id: string
amount?: BigNumberInput
currency_code?: string
description?: string
internal_note?: string
reference?: string
reference_id?: string
metadata?: Record<string, unknown> | null
}
export interface UpdateOrderTransactionWithSelectorDTO {
selector: Partial<OrderTransactionDTO>
data: Partial<UpdateOrderTransactionDTO>
}
/** ORDER TRANSACTION END */
/** ORDER DETAIL START */
@@ -401,3 +416,31 @@ export interface CreateOrderReturnDTO {
}
/** ORDER bundled action flows */
export interface CreateOrderReturnReasonDTO {
value: string
label: string
description?: string
parent_return_reason_id?: string
metadata?: Record<string, unknown> | null
}
export interface UpdateOrderReturnReasonDTO {
id?: string
label?: string
value?: string
description?: string
metadata?: Record<string, unknown> | null
}
export interface ReturnReasonUpdatableFields {
value?: string
label?: string
description?: string
metadata?: Record<string, unknown> | null
}
export interface UpdateOrderReturnReasonWithSelectorDTO {
selector: Partial<OrderReturnReasonDTO>
data: Partial<UpdateOrderReturnReasonDTO>
}

View File

@@ -8,9 +8,11 @@ import {
FilterableOrderLineItemProps,
FilterableOrderLineItemTaxLineProps,
FilterableOrderProps,
FilterableOrderReturnReasonProps,
FilterableOrderShippingMethodAdjustmentProps,
FilterableOrderShippingMethodProps,
FilterableOrderShippingMethodTaxLineProps,
FilterableOrderTransactionProps,
OrderAddressDTO,
OrderChangeActionDTO,
OrderChangeDTO,
@@ -19,9 +21,11 @@ import {
OrderLineItemAdjustmentDTO,
OrderLineItemDTO,
OrderLineItemTaxLineDTO,
OrderReturnReasonDTO,
OrderShippingMethodAdjustmentDTO,
OrderShippingMethodDTO,
OrderShippingMethodTaxLineDTO,
OrderTransactionDTO,
} from "./common"
import {
CancelOrderChangeDTO,
@@ -35,9 +39,11 @@ import {
CreateOrderLineItemForOrderDTO,
CreateOrderLineItemTaxLineDTO,
CreateOrderReturnDTO,
CreateOrderReturnReasonDTO,
CreateOrderShippingMethodAdjustmentDTO,
CreateOrderShippingMethodDTO,
CreateOrderShippingMethodTaxLineDTO,
CreateOrderTransactionDTO,
DeclineOrderChangeDTO,
RegisterOrderFulfillmentDTO,
RegisterOrderShipmentDTO,
@@ -48,8 +54,12 @@ import {
UpdateOrderLineItemDTO,
UpdateOrderLineItemTaxLineDTO,
UpdateOrderLineItemWithSelectorDTO,
UpdateOrderReturnReasonDTO,
UpdateOrderReturnReasonWithSelectorDTO,
UpdateOrderShippingMethodAdjustmentDTO,
UpdateOrderShippingMethodTaxLineDTO,
UpdateOrderTransactionDTO,
UpdateOrderTransactionWithSelectorDTO,
UpsertOrderLineItemAdjustmentDTO,
} from "./mutations"
@@ -1389,6 +1399,112 @@ export interface IOrderModuleService extends IModuleService {
revertLastVersion(orderId: string, sharedContext?: Context): Promise<void>
retrieveTransaction(
id: string,
config?: FindConfig<OrderTransactionDTO>,
sharedContext?: Context
): Promise<OrderTransactionDTO>
listTransactions(
filters: FilterableOrderTransactionProps,
config?: FindConfig<OrderTransactionDTO>,
sharedContext?: Context
): Promise<OrderTransactionDTO[]>
addTransactions(
data: CreateOrderTransactionDTO,
sharedContext?: Context
): Promise<OrderTransactionDTO>
addTransactions(
data: CreateOrderTransactionDTO[],
sharedContext?: Context
): Promise<OrderTransactionDTO[]>
updateTransactions(
data: UpdateOrderTransactionWithSelectorDTO[]
): Promise<OrderTransactionDTO[]>
updateTransactions(
selector: Partial<FilterableOrderTransactionProps>,
data: Partial<UpdateOrderTransactionDTO>,
sharedContext?: Context
): Promise<OrderTransactionDTO[]>
updateTransactions(
id: string,
data: Partial<UpdateOrderTransactionDTO>,
sharedContext?: Context
): Promise<OrderTransactionDTO>
deleteTransactions(
returnReasonIds: string[],
sharedContext?: Context
): Promise<void>
softDeleteTransactions<TReturnableLinkableKeys extends string = string>(
storeIds: string[],
config?: SoftDeleteReturn<TReturnableLinkableKeys>,
sharedContext?: Context
): Promise<Record<string, string[]> | void>
restoreTransactions<TReturnableLinkableKeys extends string = string>(
storeIds: string[],
config?: RestoreReturn<TReturnableLinkableKeys>,
sharedContext?: Context
): Promise<Record<string, string[]> | void>
retrieveReturnReason(
reasonId: string,
config?: FindConfig<OrderReturnReasonDTO>,
sharedContext?: Context
): Promise<OrderReturnReasonDTO>
listReturnReasons(
filters: FilterableOrderReturnReasonProps,
config?: FindConfig<OrderReturnReasonDTO>,
sharedContext?: Context
): Promise<OrderReturnReasonDTO[]>
createReturnReasons(
returnReasonData: CreateOrderReturnReasonDTO,
sharedContext?: Context
): Promise<OrderReturnReasonDTO>
createReturnReasons(
returnReasonData: CreateOrderReturnReasonDTO[],
sharedContext?: Context
): Promise<OrderReturnReasonDTO[]>
updateReturnReasons(
data: UpdateOrderReturnReasonWithSelectorDTO[]
): Promise<OrderReturnReasonDTO[]>
updateReturnReasons(
selector: Partial<FilterableOrderReturnReasonProps>,
data: Partial<UpdateOrderReturnReasonDTO>,
sharedContext?: Context
): Promise<OrderReturnReasonDTO[]>
updateReturnReasons(
id: string,
data: Partial<UpdateOrderReturnReasonDTO>,
sharedContext?: Context
): Promise<OrderReturnReasonDTO>
deleteReturnReasons(
returnReasonIds: string[],
sharedContext?: Context
): Promise<void>
softDeleteReturnReasons<TReturnableLinkableKeys extends string = string>(
storeIds: string[],
config?: SoftDeleteReturn<TReturnableLinkableKeys>,
sharedContext?: Context
): Promise<Record<string, string[]> | void>
restoreReturnReasons<TReturnableLinkableKeys extends string = string>(
storeIds: string[],
config?: RestoreReturn<TReturnableLinkableKeys>,
sharedContext?: Context
): Promise<Record<string, string[]> | void>
// Bundled flows
registerFulfillment(
data: RegisterOrderFulfillmentDTO,

View File

@@ -0,0 +1,19 @@
import { MiddlewareRoute } from "../../../loaders/helpers/routing/types"
import { validateAndTransformBody } from "../../utils/validate-body"
import { validateAndTransformQuery } from "../../utils/validate-query"
import * as QueryConfig from "./query-config"
import { ReturnsParams, StorePostReturnsReqSchema } from "./validators"
export const storeRegionRoutesMiddlewares: MiddlewareRoute[] = [
{
method: ["POST"],
matcher: "/store/returns/create-return",
middlewares: [
validateAndTransformBody(StorePostReturnsReqSchema),
validateAndTransformQuery(
ReturnsParams,
QueryConfig.retrieveTransformQueryConfig
),
],
},
]

View File

@@ -0,0 +1,13 @@
export const defaultReturnFields = [
"id",
"order_id",
"created_at",
"updated_at",
"deleted_at",
"metadata",
]
export const retrieveTransformQueryConfig = {
defaults: defaultReturnFields,
isList: false,
}

View File

@@ -0,0 +1,10 @@
import { CreateOrderReturnDTO } from "@medusajs/types"
import { MedusaRequest, MedusaResponse } from "../../../types/routing"
export const POST = async (req: MedusaRequest, res: MedusaResponse) => {
const input = [req.validatedBody as CreateOrderReturnDTO]
// TODO: create return workflow
res.status(200).json({ return: {} })
}

View File

@@ -0,0 +1,32 @@
import { z } from "zod"
import { createFindParams, createSelectParams } from "../../utils/validators"
export type ReturnParamsType = z.infer<typeof ReturnParams>
export const ReturnParams = createSelectParams()
export type ReturnsParamsType = z.infer<typeof ReturnsParams>
export const ReturnsParams = createFindParams().merge(
z.object({
id: z.union([z.string(), z.array(z.string())]).optional(),
order_id: z.union([z.string(), z.array(z.string())]).optional(),
$and: z.lazy(() => ReturnsParams.array()).optional(),
$or: z.lazy(() => ReturnsParams.array()).optional(),
})
)
const ReturnShippingSchema = z.object({
option_id: z.string(),
})
const ItemSchema = z.object({
item_id: z.string(),
quantity: z.number().min(1),
reason_id: z.string().optional(),
note: z.string().optional(),
})
export const StorePostReturnsReqSchema = z.object({
order_id: z.string(),
items: z.array(ItemSchema),
return_shipping: ReturnShippingSchema.optional(),
})

View File

@@ -0,0 +1,94 @@
import { Modules } from "@medusajs/modules-sdk"
import { IOrderModuleService } from "@medusajs/types"
import { SuiteOptions, moduleIntegrationTestRunner } from "medusa-test-utils"
jest.setTimeout(100000)
moduleIntegrationTestRunner({
moduleName: Modules.ORDER,
testSuite: ({ service }: SuiteOptions<IOrderModuleService>) => {
describe("Order Module Service - Returns", () => {
it("should create return reasons", async function () {
const reason = await service.createReturnReasons({
value: "test",
label: "label test",
description: "description test",
})
expect(reason).toEqual({
id: expect.any(String),
value: "test",
label: "label test",
description: "description test",
return_reason_children: [],
metadata: null,
deleted_at: null,
})
})
it("should create return reasons with parent", async function () {
const reason = await service.createReturnReasons({
value: "test",
label: "label test",
description: "description test",
})
const reason2 = await service.createReturnReasons({
value: "test 2.0",
label: "child",
parent_return_reason_id: reason.id,
})
const reason3 = await service.createReturnReasons({
value: "test 3.0",
label: "child 3",
parent_return_reason_id: reason.id,
})
const getChild = await service.retrieveReturnReason(reason2.id, {
relations: ["parent_return_reason"],
})
expect(getChild).toEqual(
expect.objectContaining({
id: reason2.id,
value: "test 2.0",
label: "child",
parent_return_reason_id: reason.id,
parent_return_reason: expect.objectContaining({
id: reason.id,
value: "test",
label: "label test",
description: "description test",
parent_return_reason_id: null,
}),
})
)
const getParent = await service.retrieveReturnReason(reason.id, {
relations: ["return_reason_children"],
})
expect(getParent).toEqual(
expect.objectContaining({
id: reason.id,
value: "test",
label: "label test",
description: "description test",
return_reason_children: [
expect.objectContaining({
id: reason2.id,
value: "test 2.0",
label: "child",
parent_return_reason_id: reason.id,
}),
expect.objectContaining({
id: reason3.id,
value: "test 3.0",
label: "child 3",
parent_return_reason_id: reason.id,
}),
],
})
)
})
})
},
})

View File

@@ -1,12 +1,14 @@
import { Modules } from "@medusajs/modules-sdk"
import { ModuleJoinerConfig } from "@medusajs/types"
import { MapToConfig } from "@medusajs/utils"
import { LineItem } from "@models"
import { LineItem, ReturnReason } from "@models"
import Order from "./models/order"
export const LinkableKeys: Record<string, string> = {
order_id: Order.name,
order_item_id: LineItem.name,
return_reason_id: ReturnReason.name,
return_reason_value: ReturnReason.name,
}
const entityLinkableKeysMap: MapToConfig = {}
@@ -31,5 +33,11 @@ export const joinerConfig: ModuleJoinerConfig = {
entity: Order.name,
},
},
{
name: ["return_reason", "return_reasons"],
args: {
entity: ReturnReason.name,
},
},
],
} as ModuleJoinerConfig

View File

@@ -466,6 +466,28 @@ export class Migration20240219102530 extends Migration {
CREATE INDEX IF NOT EXISTS "IDX_order_transaction_reference_id" ON "order_transaction" (
reference_id
);
CREATE TABLE IF NOT EXISTS "return_reason"
(
id character varying NOT NULL,
value character varying NOT NULL,
label character varying NOT NULL,
description character varying,
metadata JSONB NULL,
parent_return_reason_id character varying,
created_at timestamp with time zone NOT NULL DEFAULT now(),
updated_at timestamp with time zone NOT NULL DEFAULT now(),
deleted_at timestamp with time zone,
CONSTRAINT "return_reason_pkey" PRIMARY KEY (id),
CONSTRAINT "return_reason_parent_return_reason_id_foreign" FOREIGN KEY (parent_return_reason_id)
REFERENCES "return_reason" (id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
);
CREATE UNIQUE INDEX IF NOT EXISTS "IDX_return_reason_value" ON "return_reason" USING btree (value ASC NULLS LAST)
WHERE deleted_at IS NOT NULL;
ALTER TABLE if exists "order"
ADD CONSTRAINT "order_shipping_address_id_foreign" FOREIGN KEY ("shipping_address_id") REFERENCES "order_address" ("id") ON

View File

@@ -8,6 +8,7 @@ export { default as OrderChangeAction } from "./order-change-action"
export { default as OrderItem } from "./order-item"
export { default as OrderShippingMethod } from "./order-shipping-method"
export { default as OrderSummary } from "./order-summary"
export { default as ReturnReason } from "./return-reason"
export { default as ShippingMethod } from "./shipping-method"
export { default as ShippingMethodAdjustment } from "./shipping-method-adjustment"
export { default as ShippingMethodTaxLine } from "./shipping-method-tax-line"

View File

@@ -0,0 +1,105 @@
import { DAL } from "@medusajs/types"
import {
createPsqlIndexStatementHelper,
generateEntityId,
} from "@medusajs/utils"
import {
BeforeCreate,
Cascade,
Entity,
ManyToOne,
OnInit,
OneToMany,
OptionalProps,
PrimaryKey,
Property,
} from "@mikro-orm/core"
const DeletedAtIndex = createPsqlIndexStatementHelper({
tableName: "return_reason",
columns: "deleted_at",
where: "deleted_at IS NOT NULL",
})
const ValueIndex = createPsqlIndexStatementHelper({
tableName: "return_reason",
columns: "value",
where: "deleted_at IS NOT NULL",
})
const ParentIndex = createPsqlIndexStatementHelper({
tableName: "return_reason",
columns: "parent_return_reason_id",
where: "deleted_at IS NOT NULL",
})
type OptionalOrderProps = "parent_return_reason" | DAL.EntityDateColumns
@Entity({ tableName: "return_reason" })
export default class ReturnReason {
[OptionalProps]?: OptionalOrderProps
@PrimaryKey({ columnType: "text" })
id: string
@Property({ columnType: "text" })
@ValueIndex.MikroORMIndex()
value: string
@Property({ columnType: "text" })
label: string
@Property({ columnType: "text", nullable: true })
description: string | null = null
@Property({ columnType: "text", nullable: true })
@ParentIndex.MikroORMIndex()
parent_return_reason_id?: string | null
@ManyToOne({
entity: () => ReturnReason,
fieldName: "parent_return_reason_id",
nullable: true,
cascade: [Cascade.PERSIST],
})
parent_return_reason?: ReturnReason | null
@OneToMany(
() => ReturnReason,
(return_reason) => return_reason.parent_return_reason,
{ cascade: [Cascade.PERSIST] }
)
return_reason_children: ReturnReason[]
@Property({ columnType: "jsonb", nullable: true })
metadata: Record<string, unknown> | null = null
@Property({
onCreate: () => new Date(),
columnType: "timestamptz",
defaultRaw: "now()",
})
created_at: Date
@Property({
onCreate: () => new Date(),
onUpdate: () => new Date(),
columnType: "timestamptz",
defaultRaw: "now()",
})
updated_at: Date
@Property({ columnType: "timestamptz", nullable: true })
@DeletedAtIndex.MikroORMIndex()
deleted_at: Date | null = null
@BeforeCreate()
onCreate() {
this.id = generateEntityId(this.id, "rr")
}
@OnInit()
onInit() {
this.id = generateEntityId(this.id, "rr")
}
}

View File

@@ -10,6 +10,8 @@ import {
OrderDTO,
OrderTypes,
UpdateOrderItemWithSelectorDTO,
UpdateOrderReturnReasonDTO,
UpdateOrderTransactionDTO,
} from "@medusajs/types"
import {
createRawPropertiesFromBigNumber,
@@ -37,6 +39,7 @@ import {
OrderItem,
OrderShippingMethod,
OrderSummary,
ReturnReason,
ShippingMethod,
ShippingMethodAdjustment,
ShippingMethodTaxLine,
@@ -75,6 +78,7 @@ type InjectedDependencies = {
orderItemService: ModulesSdkTypes.InternalModuleService<any>
orderSummaryService: ModulesSdkTypes.InternalModuleService<any>
orderShippingMethodService: ModulesSdkTypes.InternalModuleService<any>
returnReasonService: ModulesSdkTypes.InternalModuleService<any>
}
const generateMethodForModels = [
@@ -91,6 +95,7 @@ const generateMethodForModels = [
OrderItem,
OrderSummary,
OrderShippingMethod,
ReturnReason,
]
export default class OrderModuleService<
@@ -107,7 +112,8 @@ export default class OrderModuleService<
TOrderChangeAction extends OrderChangeAction = OrderChangeAction,
TOrderItem extends OrderItem = OrderItem,
TOrderSummary extends OrderSummary = OrderSummary,
TOrderShippingMethod extends OrderShippingMethod = OrderShippingMethod
TOrderShippingMethod extends OrderShippingMethod = OrderShippingMethod,
TReturnReason extends ReturnReason = ReturnReason
>
extends ModulesSdkUtils.abstractModuleServiceFactory<
InjectedDependencies,
@@ -128,6 +134,7 @@ export default class OrderModuleService<
OrderItem: { dto: OrderTypes.OrderItemDTO }
OrderSummary: { dto: OrderTypes.OrderSummaryDTO }
OrderShippingMethod: { dto: OrderShippingMethod }
ReturnReason: { dto: OrderTypes.OrderReturnReasonDTO }
}
>(Order, generateMethodForModels, entityNameToLinkableKeysMap)
implements IOrderModuleService
@@ -147,6 +154,7 @@ export default class OrderModuleService<
protected orderItemService_: ModulesSdkTypes.InternalModuleService<TOrderItem>
protected orderSummaryService_: ModulesSdkTypes.InternalModuleService<TOrderSummary>
protected orderShippingMethodService_: ModulesSdkTypes.InternalModuleService<TOrderShippingMethod>
protected returnReasonService_: ModulesSdkTypes.InternalModuleService<TReturnReason>
constructor(
{
@@ -165,6 +173,7 @@ export default class OrderModuleService<
orderItemService,
orderSummaryService,
orderShippingMethodService,
returnReasonService,
}: InjectedDependencies,
protected readonly moduleDeclaration: InternalModuleDeclaration
) {
@@ -186,6 +195,7 @@ export default class OrderModuleService<
this.orderItemService_ = orderItemService
this.orderSummaryService_ = orderSummaryService
this.orderShippingMethodService_ = orderShippingMethodService
this.returnReasonService_ = returnReasonService
}
__joinerConfig(): ModuleJoinerConfig {
@@ -2261,4 +2271,277 @@ export default class OrderModuleService<
await this.confirmOrderChange(change[0].id, sharedContext)
}
public async addTransactions(
transactionData: OrderTypes.CreateOrderTransactionDTO,
sharedContext?: Context
): Promise<OrderTypes.OrderTransactionDTO>
public async addTransactions(
transactionData: OrderTypes.CreateOrderTransactionDTO[],
sharedContext?: Context
): Promise<OrderTypes.OrderTransactionDTO[]>
@InjectTransactionManager("baseRepository_")
public async addTransactions(
transactionData:
| OrderTypes.CreateOrderTransactionDTO
| OrderTypes.CreateOrderTransactionDTO[],
sharedContext?: Context
): Promise<
OrderTypes.OrderTransactionDTO | OrderTypes.OrderTransactionDTO[]
> {
const data = Array.isArray(transactionData)
? transactionData
: [transactionData]
const created = await this.transactionService_.create(data, sharedContext)
return await this.baseRepository_.serialize<OrderTypes.OrderTransactionDTO>(
!Array.isArray(transactionData) ? created[0] : created,
{
populate: true,
}
)
}
updateTransactions(
data: OrderTypes.UpdateOrderTransactionWithSelectorDTO[]
): Promise<OrderTypes.OrderTransactionDTO[]>
updateTransactions(
selector: Partial<OrderTypes.FilterableOrderTransactionProps>,
data: OrderTypes.UpdateOrderTransactionDTO,
sharedContext?: Context
): Promise<OrderTypes.OrderTransactionDTO[]>
updateTransactions(
id: string,
data: Partial<OrderTypes.UpdateOrderTransactionDTO>,
sharedContext?: Context
): Promise<OrderTypes.OrderTransactionDTO>
@InjectManager("baseRepository_")
async updateTransactions(
idOrDataOrSelector:
| string
| OrderTypes.UpdateOrderTransactionWithSelectorDTO[]
| Partial<OrderTypes.FilterableOrderTransactionProps>,
data?:
| OrderTypes.UpdateOrderTransactionDTO
| Partial<OrderTypes.UpdateOrderTransactionDTO>,
@MedusaContext() sharedContext: Context = {}
): Promise<
OrderTypes.OrderTransactionDTO[] | OrderTypes.OrderTransactionDTO
> {
let trxs: Transaction[] = []
if (isString(idOrDataOrSelector)) {
const trx = await this.updateTransaction_(
idOrDataOrSelector,
data as Partial<OrderTypes.UpdateOrderTransactionDTO>,
sharedContext
)
return await this.baseRepository_.serialize<OrderTypes.OrderTransactionDTO>(
trx,
{
populate: true,
}
)
}
const toUpdate = Array.isArray(idOrDataOrSelector)
? idOrDataOrSelector
: [
{
selector: idOrDataOrSelector,
data: data,
} as OrderTypes.UpdateOrderTransactionWithSelectorDTO,
]
trxs = await this.updateTransactionsWithSelector_(toUpdate, sharedContext)
return await this.baseRepository_.serialize<
OrderTypes.OrderTransactionDTO[]
>(trxs, {
populate: true,
})
}
@InjectTransactionManager("baseRepository_")
protected async updateTransaction_(
trxId: string,
data: Partial<OrderTypes.UpdateOrderTransactionDTO>,
@MedusaContext() sharedContext: Context = {}
): Promise<Transaction> {
const [trx] = await this.transactionService_.update(
[{ id: trxId, ...data }],
sharedContext
)
return trx
}
@InjectTransactionManager("baseRepository_")
protected async updateTransactionsWithSelector_(
updates: OrderTypes.UpdateOrderTransactionWithSelectorDTO[],
@MedusaContext() sharedContext: Context = {}
): Promise<Transaction[]> {
let toUpdate: UpdateOrderTransactionDTO[] = []
for (const { selector, data } of updates) {
const trxs = await super.listTransactions(
{ ...selector },
{},
sharedContext
)
trxs.forEach((trx) => {
toUpdate.push({
...data,
id: trx.id,
})
})
}
return await this.transactionService_.update(toUpdate, sharedContext)
}
public async createReturnReasons(
transactionData: OrderTypes.CreateOrderReturnReasonDTO,
sharedContext?: Context
): Promise<OrderTypes.OrderReturnReasonDTO>
public async createReturnReasons(
transactionData: OrderTypes.CreateOrderReturnReasonDTO[],
sharedContext?: Context
): Promise<OrderTypes.OrderReturnReasonDTO[]>
@InjectTransactionManager("baseRepository_")
public async createReturnReasons(
returnReasonData:
| OrderTypes.CreateOrderReturnReasonDTO
| OrderTypes.CreateOrderReturnReasonDTO[],
sharedContext?: Context
): Promise<
OrderTypes.OrderReturnReasonDTO | OrderTypes.OrderReturnReasonDTO[]
> {
const data = Array.isArray(returnReasonData)
? returnReasonData
: [returnReasonData]
const created = await this.returnReasonService_.create(data, sharedContext)
return await this.baseRepository_.serialize<OrderTypes.OrderReturnReasonDTO>(
!Array.isArray(returnReasonData) ? created[0] : created,
{
populate: true,
}
)
}
updateReturnReasons(
data: OrderTypes.UpdateOrderReturnReasonWithSelectorDTO[]
): Promise<OrderTypes.OrderReturnReasonDTO[]>
updateReturnReasons(
selector: Partial<OrderTypes.FilterableOrderReturnReasonProps>,
data: OrderTypes.UpdateOrderReturnReasonDTO,
sharedContext?: Context
): Promise<OrderTypes.OrderReturnReasonDTO[]>
updateReturnReasons(
id: string,
data: Partial<OrderTypes.UpdateOrderReturnReasonDTO>,
sharedContext?: Context
): Promise<OrderTypes.OrderReturnReasonDTO>
@InjectManager("baseRepository_")
async updateReturnReasons(
idOrDataOrSelector:
| string
| OrderTypes.UpdateOrderReturnReasonWithSelectorDTO[]
| Partial<OrderTypes.FilterableOrderReturnReasonProps>,
data?:
| OrderTypes.UpdateOrderReturnReasonDTO
| Partial<OrderTypes.UpdateOrderReturnReasonDTO>,
@MedusaContext() sharedContext: Context = {}
): Promise<
OrderTypes.OrderReturnReasonDTO[] | OrderTypes.OrderReturnReasonDTO
> {
let reasons: ReturnReason[] = []
if (isString(idOrDataOrSelector)) {
const reason = await this.updateReturnReason_(
idOrDataOrSelector,
data as Partial<OrderTypes.UpdateOrderReturnReasonDTO>,
sharedContext
)
return await this.baseRepository_.serialize<OrderTypes.OrderReturnReasonDTO>(
reason,
{
populate: true,
}
)
}
const toUpdate = Array.isArray(idOrDataOrSelector)
? idOrDataOrSelector
: [
{
selector: idOrDataOrSelector,
data: data,
} as OrderTypes.UpdateOrderReturnReasonWithSelectorDTO,
]
reasons = await this.updateReturnReasonsWithSelector_(
toUpdate,
sharedContext
)
return await this.baseRepository_.serialize<
OrderTypes.OrderReturnReasonDTO[]
>(reasons, {
populate: true,
})
}
@InjectTransactionManager("baseRepository_")
protected async updateReturnReason_(
reasonId: string,
data: Partial<OrderTypes.UpdateOrderReturnReasonDTO>,
@MedusaContext() sharedContext: Context = {}
): Promise<ReturnReason> {
const [reason] = await this.returnReasonService_.update(
[{ id: reasonId, ...data }],
sharedContext
)
return reason
}
@InjectTransactionManager("baseRepository_")
protected async updateReturnReasonsWithSelector_(
updates: OrderTypes.UpdateOrderReturnReasonWithSelectorDTO[],
@MedusaContext() sharedContext: Context = {}
): Promise<ReturnReason[]> {
let toUpdate: UpdateOrderReturnReasonDTO[] = []
for (const { selector, data } of updates) {
const reasons = await super.listReturnReasons(
{ ...selector },
{},
sharedContext
)
reasons.forEach((reason) => {
toUpdate.push({
...data,
id: reason.id,
})
})
}
return await this.returnReasonService_.update(toUpdate, sharedContext)
}
}