Feat(order): return reason and transaction methods (#7303)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user