From 75811cd4b36727098c68b06b98eff1c7c933c615 Mon Sep 17 00:00:00 2001 From: "Carlos R. L. Rodrigues" <37986729+carlos-r-l-rodrigues@users.noreply.github.com> Date: Wed, 12 Jun 2024 14:49:15 -0300 Subject: [PATCH] feat(order): Claim and Exchange entities (#7681) --- .../src/order/workflows/create-orders.ts | 10 +- packages/core/utils/src/order/status.ts | 28 +++ .../src/migrations/Migration20240604100512.ts | 140 +++++++++++++-- .../order/src/models/claim-item-image.ts | 86 +++++++++ .../modules/order/src/models/claim-item.ts | 109 ++++++++++++ packages/modules/order/src/models/claim.ts | 166 ++++++++++++++++++ packages/modules/order/src/models/exchange.ts | 166 ++++++++++++++++++ packages/modules/order/src/models/index.ts | 4 + .../modules/order/src/models/line-item.ts | 7 +- .../order/src/models/order-change-action.ts | 2 +- .../modules/order/src/models/order-change.ts | 2 +- .../modules/order/src/models/order-item.ts | 52 +++++- .../order/src/models/order-shipping-method.ts | 50 +++++- .../modules/order/src/models/order-summary.ts | 2 +- packages/modules/order/src/models/return.ts | 60 +++---- .../modules/order/src/models/transaction.ts | 46 ++++- .../src/services/actions/create-return.ts | 1 + .../src/services/actions/receive-return.ts | 2 + 18 files changed, 877 insertions(+), 56 deletions(-) create mode 100644 packages/modules/order/src/models/claim-item-image.ts create mode 100644 packages/modules/order/src/models/claim-item.ts create mode 100644 packages/modules/order/src/models/claim.ts create mode 100644 packages/modules/order/src/models/exchange.ts diff --git a/packages/core/core-flows/src/order/workflows/create-orders.ts b/packages/core/core-flows/src/order/workflows/create-orders.ts index f4aa99e88f..c478ffd5a2 100644 --- a/packages/core/core-flows/src/order/workflows/create-orders.ts +++ b/packages/core/core-flows/src/order/workflows/create-orders.ts @@ -1,5 +1,5 @@ import { CreateOrderDTO, OrderDTO } from "@medusajs/types" -import { MathBN, MedusaError } from "@medusajs/utils" +import { MathBN, MedusaError, isPresent } from "@medusajs/utils" import { WorkflowData, createWorkflow, @@ -50,8 +50,16 @@ function prepareLineItems(data) { } function getOrderInput(data) { + const shippingAddress = data.input.shipping_address ?? { id: undefined } + delete shippingAddress.id + + const billingAddress = data.input.billing_address ?? { id: undefined } + delete billingAddress.id + const data_ = { ...data.input, + shipping_address: isPresent(shippingAddress) ? shippingAddress : undefined, + billing_address: isPresent(billingAddress) ? billingAddress : undefined, currency_code: data.input.currency_code ?? data.region.currency_code, region_id: data.region.id, } diff --git a/packages/core/utils/src/order/status.ts b/packages/core/utils/src/order/status.ts index 40d2affaee..deae1f40e6 100644 --- a/packages/core/utils/src/order/status.ts +++ b/packages/core/utils/src/order/status.ts @@ -53,3 +53,31 @@ export enum ReturnStatus { */ CANCELED = "canceled", } + +/** + * @enum + * + * The claim's type. + */ +export enum ClaimType { + /** + * The claim refunds an amount to the customer. + */ + REFUND = "refund", + /** + * The claim replaces the returned item with a new one. + */ + REPLACE = "replace", +} + +/** + * @enum + * + * The claim's item reason. + */ +export enum ClaimReason { + MISSING_ITEM = "missing_item", + WRONG_ITEM = "wrong_item", + PRODUCTION_FAILURE = "production_failure", + OTHER = "other", +} diff --git a/packages/modules/order/src/migrations/Migration20240604100512.ts b/packages/modules/order/src/migrations/Migration20240604100512.ts index 9edbbe12ef..3d4505980c 100644 --- a/packages/modules/order/src/migrations/Migration20240604100512.ts +++ b/packages/modules/order/src/migrations/Migration20240604100512.ts @@ -157,6 +157,13 @@ export class Migration20240604100512 extends Migration { + CREATE TYPE return_status_enum AS ENUM ( + 'requested', + 'received', + 'partially_received', + 'canceled' + ); + CREATE TABLE IF NOT EXISTS "return" ( "id" TEXT NOT NULL, "order_id" TEXT NOT NULL, @@ -164,7 +171,7 @@ export class Migration20240604100512 extends Migration { "exchange_id" TEXT NULL, "order_version" INTEGER NOT NULL, "display_id" SERIAL, - "status" text NOT NULL, + "status" return_status_enum NOT NULL DEFAULT 'requested', "no_notification" boolean NULL, "refund_amount" NUMERIC NULL, "raw_refund_amount" JSONB NULL, @@ -176,16 +183,6 @@ export class Migration20240604100512 extends Migration { "canceled_at" timestamptz NULL, CONSTRAINT "return_pkey" PRIMARY KEY ("id") ); - - CREATE TYPE return_status_enum AS ENUM ( - 'requested', - 'received', - 'partially_received', - 'canceled' - ); - ALTER TABLE "return" ALTER COLUMN status DROP DEFAULT; - ALTER TABLE "return" ALTER COLUMN status TYPE return_status_enum USING (status::text::return_status_enum); - ALTER TABLE "return" ALTER COLUMN status SET DEFAULT 'requested'; CREATE INDEX IF NOT EXISTS "IDX_return_order_id" ON "return" ( order_id @@ -206,6 +203,127 @@ export class Migration20240604100512 extends Migration { display_id ) WHERE deleted_at IS NOT NULL; + + + + CREATE TABLE IF NOT EXISTS "order_exchange" ( + "id" TEXT NOT NULL, + "order_id" TEXT NOT NULL, + "return_id" TEXT NULL, + "order_version" INTEGER NOT NULL, + "display_id" SERIAL, + "no_notification" BOOLEAN NULL, + "refund_amount" NUMERIC NULL, + "raw_refund_amount" JSONB NULL, + "allow_backorder" BOOLEAN NOT NULL DEFAULT FALSE, + "difference_due" NUMERIC NULL, + "raw_difference_due" JSONB NULL, + "metadata" JSONB NULL, + "created_at" timestamptz NOT NULL DEFAULT now(), + "updated_at" timestamptz NOT NULL DEFAULT now(), + "deleted_at" timestamptz NULL, + "canceled_at" timestamptz NULL, + CONSTRAINT "order_exchange_pkey" PRIMARY KEY ("id") + ); + + CREATE INDEX IF NOT EXISTS "IDX_order_exchange_display_id" ON "order_exchange" ("display_id") + WHERE deleted_at IS NOT NULL; + + CREATE INDEX IF NOT EXISTS "IDX_order_exchange_deleted_at" ON "order_exchange" ("deleted_at") + WHERE deleted_at IS NOT NULL; + + CREATE INDEX IF NOT EXISTS "IDX_order_exchange_order_id" ON "order_exchange" ("order_id") + WHERE deleted_at IS NOT NULL; + + CREATE INDEX IF NOT EXISTS "IDX_order_exchange_return_id" ON "order_exchange" ("return_id") + WHERE return_id IS NOT NULL AND deleted_at IS NOT NULL; + + + + CREATE TYPE order_claim_type_enum AS ENUM ( + 'refund', + 'replace' + ); + + CREATE TABLE IF NOT EXISTS "order_claim" ( + "id" TEXT NOT NULL, + "order_id" TEXT NOT NULL, + "return_id" TEXT NULL, + "order_version" INTEGER NOT NULL, + "display_id" SERIAL, + "type" order_claim_type_enum NOT NULL, + "no_notification" BOOLEAN NULL, + "refund_amount" NUMERIC NULL, + "raw_refund_amount" JSONB NULL, + "metadata" JSONB NULL, + "created_at" timestamptz NOT NULL DEFAULT now(), + "updated_at" timestamptz NOT NULL DEFAULT now(), + "deleted_at" timestamptz NULL, + "canceled_at" timestamptz NULL, + CONSTRAINT "order_claim_pkey" PRIMARY KEY ("id") + ); + + CREATE INDEX IF NOT EXISTS "IDX_order_claim_display_id" ON "order_claim" ("display_id") + WHERE deleted_at IS NOT NULL; + + CREATE INDEX IF NOT EXISTS "IDX_order_claim_deleted_at" ON "order_claim" ("deleted_at") + WHERE deleted_at IS NOT NULL; + + CREATE INDEX IF NOT EXISTS "IDX_order_claim_order_id" ON "order_claim" ("order_id") + WHERE deleted_at IS NOT NULL; + + CREATE INDEX IF NOT EXISTS "IDX_order_claim_return_id" ON "order_claim" ("return_id") + WHERE return_id IS NOT NULL AND deleted_at IS NOT NULL; + + + + CREATE TYPE claim_reason_enum AS ENUM ( + 'missing_item', + 'wrong_item', + 'production_failure', + 'other' + ); + + CREATE TABLE IF NOT EXISTS "order_claim_item" ( + "id" TEXT NOT NULL, + "claim_id" TEXT NOT NULL, + "item_id" TEXT NOT NULL, + "reason" claim_reason_enum NOT NULL, + "note" TEXT NULL, + "metadata" JSONB NULL, + "created_at" timestamptz NOT NULL DEFAULT now(), + "updated_at" timestamptz NOT NULL DEFAULT now(), + "deleted_at" timestamptz NULL, + CONSTRAINT "order_claim_item_pkey" PRIMARY KEY ("id") + ); + + CREATE INDEX IF NOT EXISTS "IDX_order_claim_item_deleted_at" ON "order_claim_item" ("deleted_at") + WHERE deleted_at IS NOT NULL; + + CREATE INDEX IF NOT EXISTS "IDX_order_claim_item_claim_id" ON "order_claim_item" ("claim_id") + WHERE deleted_at IS NOT NULL; + + CREATE INDEX IF NOT EXISTS "IDX_order_claim_item_item_id" ON "order_claim_item" ("item_id") + WHERE deleted_at IS NOT NULL; + + + + CREATE TABLE IF NOT EXISTS "order_claim_item_image" ( + "id" TEXT NOT NULL, + "claim_item_id" TEXT NOT NULL, + "url" TEXT NOT NULL, + "metadata" JSONB NULL, + "created_at" timestamptz NOT NULL DEFAULT now(), + "updated_at" timestamptz NOT NULL DEFAULT now(), + "deleted_at" timestamptz NULL, + CONSTRAINT "order_claim_item_image_pkey" PRIMARY KEY ("id") + ); + + CREATE INDEX IF NOT EXISTS "IDX_order_claim_item_image_claim_item_id" ON "order_claim_item_image" ("claim_item_id") + WHERE "deleted_at" IS NOT NULL; + + CREATE INDEX IF NOT EXISTS "IDX_order_claim_item_image_deleted_at" ON "order_claim_item_image" ("deleted_at") + WHERE "deleted_at" IS NOT NULL; ` this.addSql(sql) } diff --git a/packages/modules/order/src/models/claim-item-image.ts b/packages/modules/order/src/models/claim-item-image.ts new file mode 100644 index 0000000000..2047627f50 --- /dev/null +++ b/packages/modules/order/src/models/claim-item-image.ts @@ -0,0 +1,86 @@ +import { DAL } from "@medusajs/types" +import { + createPsqlIndexStatementHelper, + generateEntityId, +} from "@medusajs/utils" +import { + BeforeCreate, + Entity, + ManyToOne, + OnInit, + OptionalProps, + PrimaryKey, + Property, +} from "@mikro-orm/core" +import ClaimItem from "./claim-item" + +type OptionalClaimItemImageProps = DAL.EntityDateColumns + +const ClaimItemImageDeletedAtIndex = createPsqlIndexStatementHelper({ + tableName: "order_claim_item_image", + columns: "deleted_at", + where: "deleted_at IS NOT NULL", +}) + +const ClaimItemIdIndex = createPsqlIndexStatementHelper({ + tableName: "order_claim_item_image", + columns: ["claim_item_id"], + where: "deleted_at IS NOT NULL", +}) + +@Entity({ tableName: "order_claim_item_image" }) +export default class ClaimItemImage { + [OptionalProps]?: OptionalClaimItemImageProps + + @PrimaryKey({ columnType: "text" }) + id: string + + @ManyToOne({ + entity: () => ClaimItem, + mapToPk: true, + fieldName: "claim_item_id", + columnType: "text", + }) + @ClaimItemIdIndex.MikroORMIndex() + claim_item_id: string + + @ManyToOne(() => ClaimItem, { + persist: false, + }) + item: ClaimItem + + @Property({ columnType: "text" }) + url: string + + @Property({ columnType: "jsonb", nullable: true }) + metadata: Record | 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 }) + @ClaimItemImageDeletedAtIndex.MikroORMIndex() + deleted_at: Date | null = null + + @BeforeCreate() + onCreate() { + this.id = generateEntityId(this.id, "ordclaimimg") + } + + @OnInit() + onInit() { + this.id = generateEntityId(this.id, "ordclaimimg") + } +} diff --git a/packages/modules/order/src/models/claim-item.ts b/packages/modules/order/src/models/claim-item.ts new file mode 100644 index 0000000000..1e09c563bc --- /dev/null +++ b/packages/modules/order/src/models/claim-item.ts @@ -0,0 +1,109 @@ +import { DAL } from "@medusajs/types" +import { + ClaimReason, + createPsqlIndexStatementHelper, + generateEntityId, +} from "@medusajs/utils" +import { + BeforeCreate, + Cascade, + Collection, + Entity, + Enum, + ManyToOne, + OnInit, + OneToMany, + OptionalProps, + PrimaryKey, + Property, +} from "@mikro-orm/core" +import Claim from "./claim" +import ClaimItemImage from "./claim-item-image" +import LineItem from "./line-item" + +type OptionalLineItemProps = DAL.EntityDateColumns + +const ClaimIdIndex = createPsqlIndexStatementHelper({ + tableName: "order_claim_item", + columns: "claim_id", +}) + +const ItemIdIndex = createPsqlIndexStatementHelper({ + tableName: "order_claim_item", + columns: "item_id", +}) + +@Entity({ tableName: "order_claim_item" }) +export default class OrderClaimItem { + [OptionalProps]?: OptionalLineItemProps + + @PrimaryKey({ columnType: "text" }) + id: string + + @OneToMany(() => ClaimItemImage, (ci) => ci.item, { + cascade: [Cascade.PERSIST, Cascade.REMOVE], + }) + images = new Collection(this) + + @Enum({ items: () => ClaimReason }) + reason: ClaimReason + + @ManyToOne(() => Claim, { + columnType: "text", + fieldName: "claim_id", + mapToPk: true, + onDelete: "cascade", + }) + @ClaimIdIndex.MikroORMIndex() + claim_id: string + + @ManyToOne(() => Claim, { + persist: false, + }) + claim: Claim + + @ManyToOne({ + entity: () => LineItem, + fieldName: "item_id", + mapToPk: true, + columnType: "text", + }) + @ItemIdIndex.MikroORMIndex() + item_id: string + + @ManyToOne(() => LineItem, { + persist: false, + }) + item: LineItem + + @Property({ columnType: "text", nullable: true }) + note: string + + @Property({ columnType: "jsonb", nullable: true }) + metadata: Record | 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 + + @BeforeCreate() + onCreate() { + this.id = generateEntityId(this.id, "ordclaimitem") + } + + @OnInit() + onInit() { + this.id = generateEntityId(this.id, "ordclaimitem") + } +} diff --git a/packages/modules/order/src/models/claim.ts b/packages/modules/order/src/models/claim.ts new file mode 100644 index 0000000000..3bdc122b78 --- /dev/null +++ b/packages/modules/order/src/models/claim.ts @@ -0,0 +1,166 @@ +import { BigNumberRawValue, DAL } from "@medusajs/types" +import { + BigNumber, + ClaimType, + MikroOrmBigNumberProperty, + createPsqlIndexStatementHelper, + generateEntityId, +} from "@medusajs/utils" +import { + BeforeCreate, + Cascade, + Collection, + Entity, + Enum, + ManyToOne, + OnInit, + OneToMany, + OneToOne, + OptionalProps, + PrimaryKey, + Property, +} from "@mikro-orm/core" +import ClaimItem from "./claim-item" +import Order from "./order" +import OrderItem from "./order-item" +import OrderShippingMethod from "./order-shipping-method" +import Return from "./return" + +type OptionalOrderClaimProps = DAL.EntityDateColumns + +const DisplayIdIndex = createPsqlIndexStatementHelper({ + tableName: "order_claim", + columns: "display_id", + where: "deleted_at IS NOT NULL", +}) + +const OrderClaimDeletedAtIndex = createPsqlIndexStatementHelper({ + tableName: "order_claim", + columns: "deleted_at", + where: "deleted_at IS NOT NULL", +}) + +const OrderIdIndex = createPsqlIndexStatementHelper({ + tableName: "order_claim", + columns: ["order_id"], + where: "deleted_at IS NOT NULL", +}) + +const ReturnIdIndex = createPsqlIndexStatementHelper({ + tableName: "order_claim", + columns: "return_id", + where: "return_id IS NOT NULL AND deleted_at IS NOT NULL", +}) + +@Entity({ tableName: "order_claim" }) +export default class OrderClaim { + [OptionalProps]?: OptionalOrderClaimProps + + @PrimaryKey({ columnType: "text" }) + id: string + + @ManyToOne({ + entity: () => Order, + mapToPk: true, + fieldName: "order_id", + columnType: "text", + }) + @OrderIdIndex.MikroORMIndex() + order_id: string + + @ManyToOne(() => Order, { + persist: false, + }) + order: Order + + @OneToOne({ + entity: () => Return, + mappedBy: (ret) => ret.claim, + cascade: ["soft-remove"] as any, + fieldName: "return_id", + nullable: true, + owner: true, + }) + return: Return + + @Property({ columnType: "text", nullable: true }) + @ReturnIdIndex.MikroORMIndex() + return_id: string | null = null + + @Property({ + columnType: "integer", + }) + order_version: number + + @Property({ autoincrement: true, primary: false }) + @DisplayIdIndex.MikroORMIndex() + display_id: number + + @Enum({ items: () => ClaimType }) + type: ClaimType + + @Property({ columnType: "boolean", nullable: true }) + no_notification: boolean | null = null + + @MikroOrmBigNumberProperty({ + nullable: true, + }) + refund_amount: BigNumber | number + + @Property({ columnType: "jsonb", nullable: true }) + raw_refund_amount: BigNumberRawValue + + @OneToMany(() => OrderItem, (itemDetail) => itemDetail.claim, { + cascade: [Cascade.PERSIST], + }) + items = new Collection(this) + + @OneToMany(() => ClaimItem, (itemDetail) => itemDetail.claim, { + cascade: [Cascade.PERSIST], + }) + claim_items = new Collection(this) + + @OneToMany( + () => OrderShippingMethod, + (shippingMethod) => shippingMethod.claim, + { + cascade: [Cascade.PERSIST], + } + ) + shipping_methods = new Collection(this) + + @Property({ columnType: "jsonb", nullable: true }) + metadata: Record | 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 }) + @OrderClaimDeletedAtIndex.MikroORMIndex() + deleted_at: Date | null = null + + @Property({ columnType: "timestamptz", nullable: true }) + canceled_at: Date | null = null + + @BeforeCreate() + onCreate() { + this.id = generateEntityId(this.id, "ordclaim") + } + + @OnInit() + onInit() { + this.id = generateEntityId(this.id, "ordclaim") + } +} diff --git a/packages/modules/order/src/models/exchange.ts b/packages/modules/order/src/models/exchange.ts new file mode 100644 index 0000000000..ba0499af26 --- /dev/null +++ b/packages/modules/order/src/models/exchange.ts @@ -0,0 +1,166 @@ +import { BigNumberRawValue, DAL } from "@medusajs/types" +import { + BigNumber, + MikroOrmBigNumberProperty, + createPsqlIndexStatementHelper, + generateEntityId, +} from "@medusajs/utils" +import { + BeforeCreate, + Cascade, + Collection, + Entity, + ManyToOne, + OnInit, + OneToMany, + OneToOne, + OptionalProps, + PrimaryKey, + Property, +} from "@mikro-orm/core" +import Order from "./order" +import OrderItem from "./order-item" +import OrderShippingMethod from "./order-shipping-method" +import Return from "./return" + +type OptionalOrderExchangeProps = DAL.EntityDateColumns + +const DisplayIdIndex = createPsqlIndexStatementHelper({ + tableName: "order_exchange", + columns: "display_id", + where: "deleted_at IS NOT NULL", +}) + +const OrderExchangeDeletedAtIndex = createPsqlIndexStatementHelper({ + tableName: "order_exchange", + columns: "deleted_at", + where: "deleted_at IS NOT NULL", +}) + +const OrderIdIndex = createPsqlIndexStatementHelper({ + tableName: "order_exchange", + columns: ["order_id"], + where: "deleted_at IS NOT NULL", +}) + +const ReturnIdIndex = createPsqlIndexStatementHelper({ + tableName: "order_exchange", + columns: "return_id", + where: "return_id IS NOT NULL AND deleted_at IS NOT NULL", +}) + +@Entity({ tableName: "order_exchange" }) +export default class OrderExchange { + [OptionalProps]?: OptionalOrderExchangeProps + + @PrimaryKey({ columnType: "text" }) + id: string + + @ManyToOne({ + entity: () => Order, + mapToPk: true, + fieldName: "order_id", + columnType: "text", + }) + @OrderIdIndex.MikroORMIndex() + order_id: string + + @ManyToOne(() => Order, { + persist: false, + }) + order: Order + + @OneToOne({ + entity: () => Return, + mappedBy: (ret) => ret.exchange, + cascade: ["soft-remove"] as any, + fieldName: "return_id", + nullable: true, + owner: true, + }) + return: Return + + @Property({ columnType: "text", nullable: true }) + @ReturnIdIndex.MikroORMIndex() + return_id: string | null = null + + @Property({ + columnType: "integer", + }) + order_version: number + + @Property({ autoincrement: true, primary: false }) + @DisplayIdIndex.MikroORMIndex() + display_id: number + + @Property({ columnType: "boolean", nullable: true }) + no_notification: boolean | null = null + + @MikroOrmBigNumberProperty({ + nullable: true, + }) + refund_amount: BigNumber | number + + @Property({ columnType: "jsonb", nullable: true }) + raw_refund_amount: BigNumberRawValue + + @MikroOrmBigNumberProperty({ + nullable: true, + }) + difference_due: BigNumber | number + + @Property({ columnType: "jsonb", nullable: true }) + raw_difference_due: BigNumberRawValue + + @Property({ columnType: "boolean", default: false }) + allow_backorder: boolean = false + + @OneToMany(() => OrderItem, (itemDetail) => itemDetail.exchange, { + cascade: [Cascade.PERSIST], + }) + items = new Collection(this) + + @OneToMany( + () => OrderShippingMethod, + (shippingMethod) => shippingMethod.exchange, + { + cascade: [Cascade.PERSIST], + } + ) + shipping_methods = new Collection(this) + + @Property({ columnType: "jsonb", nullable: true }) + metadata: Record | 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 }) + @OrderExchangeDeletedAtIndex.MikroORMIndex() + deleted_at: Date | null = null + + @Property({ columnType: "timestamptz", nullable: true }) + canceled_at: Date | null = null + + @BeforeCreate() + onCreate() { + this.id = generateEntityId(this.id, "ordexchange") + } + + @OnInit() + onInit() { + this.id = generateEntityId(this.id, "ordexchange") + } +} diff --git a/packages/modules/order/src/models/index.ts b/packages/modules/order/src/models/index.ts index 9c282f3838..c9a09a74bf 100644 --- a/packages/modules/order/src/models/index.ts +++ b/packages/modules/order/src/models/index.ts @@ -1,4 +1,8 @@ export { default as Address } from "./address" +export { default as Claim } from "./claim" +export { default as ClaimItem } from "./claim-item" +export { default as ClaimItemImage } from "./claim-item-image" +export { default as Exchange } from "./exchange" export { default as LineItem } from "./line-item" export { default as LineItemAdjustment } from "./line-item-adjustment" export { default as LineItemTaxLine } from "./line-item-tax-line" diff --git a/packages/modules/order/src/models/line-item.ts b/packages/modules/order/src/models/line-item.ts index 5d981d9b0c..6ce119cce0 100644 --- a/packages/modules/order/src/models/line-item.ts +++ b/packages/modules/order/src/models/line-item.ts @@ -19,12 +19,7 @@ import { import LineItemAdjustment from "./line-item-adjustment" import LineItemTaxLine from "./line-item-tax-line" -type OptionalLineItemProps = - | "is_discoutable" - | "is_tax_inclusive" - | "compare_at_unit_price" - | "requires_shipping" - | DAL.EntityDateColumns +type OptionalLineItemProps = DAL.EntityDateColumns const ProductIdIndex = createPsqlIndexStatementHelper({ tableName: "order_line_item", diff --git a/packages/modules/order/src/models/order-change-action.ts b/packages/modules/order/src/models/order-change-action.ts index 498552d7cd..53dda0ad16 100644 --- a/packages/modules/order/src/models/order-change-action.ts +++ b/packages/modules/order/src/models/order-change-action.ts @@ -14,9 +14,9 @@ import { PrimaryKey, Property, } from "@mikro-orm/core" -import { Return } from "@models" import Order from "./order" import OrderChange from "./order-change" +import Return from "./return" type OptionalLineItemProps = DAL.EntityDateColumns diff --git a/packages/modules/order/src/models/order-change.ts b/packages/modules/order/src/models/order-change.ts index 72f20e63f8..8c68a48929 100644 --- a/packages/modules/order/src/models/order-change.ts +++ b/packages/modules/order/src/models/order-change.ts @@ -16,10 +16,10 @@ import { PrimaryKey, Property, } from "@mikro-orm/core" -import { Return } from "@models" import { OrderChangeStatus, OrderChangeType } from "@types" import Order from "./order" import OrderChangeAction from "./order-change-action" +import Return from "./return" type OptionalLineItemProps = DAL.EntityDateColumns diff --git a/packages/modules/order/src/models/order-item.ts b/packages/modules/order/src/models/order-item.ts index 27b5a12d63..d9c8dbb8c6 100644 --- a/packages/modules/order/src/models/order-item.ts +++ b/packages/modules/order/src/models/order-item.ts @@ -14,9 +14,11 @@ import { PrimaryKey, Property, } from "@mikro-orm/core" -import { Return } from "@models" +import Claim from "./claim" +import Exchange from "./exchange" import LineItem from "./line-item" import Order from "./order" +import Return from "./return" type OptionalLineItemProps = DAL.EntityDateColumns @@ -32,6 +34,18 @@ const ReturnIdIndex = createPsqlIndexStatementHelper({ where: "return_id IS NOT NULL AND deleted_at IS NOT NULL", }) +const ExchangeIdIndex = createPsqlIndexStatementHelper({ + tableName: "order_item", + columns: ["exchange_id"], + where: "exchange_id IS NOT NULL AND deleted_at IS NOT NULL", +}) + +const ClaimIdIndex = createPsqlIndexStatementHelper({ + tableName: "order_item", + columns: ["claim_id"], + where: "claim_id IS NOT NULL AND deleted_at IS NOT NULL", +}) + const OrderVersionIndex = createPsqlIndexStatementHelper({ tableName: "order_item", columns: ["version"], @@ -86,6 +100,36 @@ export default class OrderItem { }) return: Return + @ManyToOne({ + entity: () => Exchange, + mapToPk: true, + fieldName: "exchange_id", + columnType: "text", + nullable: true, + }) + @ExchangeIdIndex.MikroORMIndex() + exchange_id: string | null + + @ManyToOne(() => Exchange, { + persist: false, + }) + exchange: Exchange + + @ManyToOne({ + entity: () => Claim, + mapToPk: true, + fieldName: "claim_id", + columnType: "text", + nullable: true, + }) + @ClaimIdIndex.MikroORMIndex() + claim_id: string | null + + @ManyToOne(() => Claim, { + persist: false, + }) + claim: Claim + @Property({ columnType: "integer" }) @OrderVersionIndex.MikroORMIndex() version: number @@ -172,6 +216,9 @@ export default class OrderItem { onCreate() { this.id = generateEntityId(this.id, "orditem") this.order_id ??= this.order?.id + this.return_id ??= this.return?.id + this.exchange_id ??= this.exchange?.id + this.claim_id ??= this.claim?.id this.item_id ??= this.item?.id this.version ??= this.order?.version } @@ -180,6 +227,9 @@ export default class OrderItem { onInit() { this.id = generateEntityId(this.id, "orditem") this.order_id ??= this.order?.id + this.return_id ??= this.return?.id + this.exchange_id ??= this.exchange?.id + this.claim_id ??= this.claim?.id this.item_id ??= this.item?.id this.version ??= this.order?.version } diff --git a/packages/modules/order/src/models/order-shipping-method.ts b/packages/modules/order/src/models/order-shipping-method.ts index 123de91a0f..f22fd99d70 100644 --- a/packages/modules/order/src/models/order-shipping-method.ts +++ b/packages/modules/order/src/models/order-shipping-method.ts @@ -12,8 +12,10 @@ import { PrimaryKey, Property, } from "@mikro-orm/core" -import { Return } from "@models" +import Claim from "./claim" +import Exchange from "./exchange" import Order from "./order" +import Return from "./return" import ShippingMethod from "./shipping-method" type OptionalShippingMethodProps = DAL.EntityDateColumns @@ -30,6 +32,18 @@ const ReturnIdIndex = createPsqlIndexStatementHelper({ where: "return_id IS NOT NULL AND deleted_at IS NOT NULL", }) +const ExchangeIdIndex = createPsqlIndexStatementHelper({ + tableName: "order_shipping", + columns: ["exchange_id"], + where: "exchange_id IS NOT NULL AND deleted_at IS NOT NULL", +}) + +const ClaimIdIndex = createPsqlIndexStatementHelper({ + tableName: "order_shipping", + columns: ["claim_id"], + where: "claim_id IS NOT NULL AND deleted_at IS NOT NULL", +}) + const OrderVersionIndex = createPsqlIndexStatementHelper({ tableName: "order_shipping", columns: ["version"], @@ -84,6 +98,36 @@ export default class OrderShippingMethod { }) return: Return + @ManyToOne({ + entity: () => Exchange, + mapToPk: true, + fieldName: "exchange_id", + columnType: "text", + nullable: true, + }) + @ExchangeIdIndex.MikroORMIndex() + exchange_id: string | null + + @ManyToOne(() => Exchange, { + persist: false, + }) + exchange: Exchange + + @ManyToOne({ + entity: () => Claim, + mapToPk: true, + fieldName: "claim_id", + columnType: "text", + nullable: true, + }) + @ClaimIdIndex.MikroORMIndex() + claim_id: string | null + + @ManyToOne(() => Claim, { + persist: false, + }) + claim: Claim + @Property({ columnType: "integer" }) @OrderVersionIndex.MikroORMIndex() version: number @@ -125,6 +169,8 @@ export default class OrderShippingMethod { onCreate() { this.id = generateEntityId(this.id, "ordspmv") this.order_id ??= this.order?.id + this.return_id ??= this.return?.id + this.exchange_id ??= this.exchange?.id this.shipping_method_id ??= this.shipping_method?.id this.version ??= this.order?.version } @@ -133,6 +179,8 @@ export default class OrderShippingMethod { onInit() { this.id = generateEntityId(this.id, "ordspmv") this.order_id ??= this.order?.id + this.return_id ??= this.return?.id + this.exchange_id ??= this.exchange?.id this.shipping_method_id ??= this.shipping_method?.id this.version ??= this.order?.version } diff --git a/packages/modules/order/src/models/order-summary.ts b/packages/modules/order/src/models/order-summary.ts index 4870bb9d72..0399ac4d87 100644 --- a/packages/modules/order/src/models/order-summary.ts +++ b/packages/modules/order/src/models/order-summary.ts @@ -11,7 +11,7 @@ import { PrimaryKey, Property, } from "@mikro-orm/core" -import { Order } from "@models" +import Order from "./order" type OrderSummaryTotals = { total: BigNumber diff --git a/packages/modules/order/src/models/return.ts b/packages/modules/order/src/models/return.ts index dbe61e4763..12a1da507f 100644 --- a/packages/modules/order/src/models/return.ts +++ b/packages/modules/order/src/models/return.ts @@ -15,12 +15,16 @@ import { ManyToOne, OnInit, OneToMany, + OneToOne, OptionalProps, PrimaryKey, Property, } from "@mikro-orm/core" -import { OrderItem, OrderShippingMethod } from "@models" +import Claim from "./claim" +import Exchange from "./exchange" import Order from "./order" +import OrderItem from "./order-item" +import OrderShippingMethod from "./order-shipping-method" type OptionalReturnProps = DAL.EntityDateColumns @@ -42,18 +46,18 @@ const OrderIdIndex = createPsqlIndexStatementHelper({ where: "deleted_at IS NOT NULL", }) +const ExchangeIdIndex = createPsqlIndexStatementHelper({ + tableName: "return", + columns: ["exchange_id"], + where: "exchange_id IS NOT NULL AND deleted_at IS NOT NULL", +}) + const ClaimIdIndex = createPsqlIndexStatementHelper({ tableName: "return", columns: ["claim_id"], where: "claim_id IS NOT NULL AND deleted_at IS NOT NULL", }) -const ExchageIdIndex = createPsqlIndexStatementHelper({ - tableName: "return", - columns: ["exchange_id"], - where: "exchange_id IS NOT NULL AND deleted_at IS NOT NULL", -}) - @Entity({ tableName: "return" }) export default class Return { [OptionalProps]?: OptionalReturnProps @@ -75,37 +79,29 @@ export default class Return { }) order: Order - /* - @ManyToOne({ - entity: () => Claim, - mapToPk: true, - fieldName: "claim_id", - columnType: "text", - nullable: true, - }) - @ClaimIdIndex.MikroORMIndex() - claim_id: string | null - - @ManyToOne(() => Claim, { - persist: false, - }) - claim: Claim | null - - @ManyToOne({ + @OneToOne({ entity: () => Exchange, - mapToPk: true, + cascade: ["soft-remove"] as any, fieldName: "exchange_id", - columnType: "text", nullable: true, }) - @ExchangeIdIndex.MikroORMIndex() - exchange_id: string | null + exchange: Exchange - @ManyToOne(() => Exchange, { - persist: false, + @Property({ columnType: "text", nullable: true }) + @ExchangeIdIndex.MikroORMIndex() + exchange_id: string | null = null + + @OneToOne({ + entity: () => Claim, + cascade: ["soft-remove"] as any, + fieldName: "claim_id", + nullable: true, }) - exchange: Exchange | null - */ + claim: Claim + + @Property({ columnType: "text", nullable: true }) + @ClaimIdIndex.MikroORMIndex() + claim_id: string | null = null @Property({ columnType: "integer", diff --git a/packages/modules/order/src/models/transaction.ts b/packages/modules/order/src/models/transaction.ts index e79079dbf2..63191ac1d1 100644 --- a/packages/modules/order/src/models/transaction.ts +++ b/packages/modules/order/src/models/transaction.ts @@ -14,8 +14,10 @@ import { PrimaryKey, Property, } from "@mikro-orm/core" -import { Return } from "@models" +import Claim from "./claim" +import Exchange from "./exchange" import Order from "./order" +import Return from "./return" type OptionalLineItemProps = DAL.EntityDateColumns @@ -37,6 +39,18 @@ const ReturnIdIndex = createPsqlIndexStatementHelper({ where: "return_id IS NOT NULL AND deleted_at IS NOT NULL", }) +const ExchangeIdIndex = createPsqlIndexStatementHelper({ + tableName: "order_item", + columns: ["exchange_id"], + where: "exchange_id IS NOT NULL AND deleted_at IS NOT NULL", +}) + +const ClaimIdIndex = createPsqlIndexStatementHelper({ + tableName: "order_item", + columns: ["claim_id"], + where: "claim_id IS NOT NULL AND deleted_at IS NOT NULL", +}) + const CurrencyCodeIndex = createPsqlIndexStatementHelper({ tableName: "order_transaction", columns: "currency_code", @@ -93,6 +107,36 @@ export default class Transaction { }) return: Return + @ManyToOne({ + entity: () => Exchange, + mapToPk: true, + fieldName: "exchange_id", + columnType: "text", + nullable: true, + }) + @ExchangeIdIndex.MikroORMIndex() + exchange_id: string | null + + @ManyToOne(() => Exchange, { + persist: false, + }) + exchange: Exchange + + @ManyToOne({ + entity: () => Claim, + mapToPk: true, + fieldName: "claim_id", + columnType: "text", + nullable: true, + }) + @ClaimIdIndex.MikroORMIndex() + claim_id: string | null + + @ManyToOne(() => Claim, { + persist: false, + }) + claim: Claim + @Property({ columnType: "integer", defaultRaw: "1", diff --git a/packages/modules/order/src/services/actions/create-return.ts b/packages/modules/order/src/services/actions/create-return.ts index cf5a77b975..4e1f13c824 100644 --- a/packages/modules/order/src/services/actions/create-return.ts +++ b/packages/modules/order/src/services/actions/create-return.ts @@ -30,6 +30,7 @@ export async function createReturn( order_id: data.order_id, order_version: order.version, status: ReturnStatus.REQUESTED, + // TODO: add refund amount / calculate? // refund_amount: data.refund_amount ?? null, }, ], diff --git a/packages/modules/order/src/services/actions/receive-return.ts b/packages/modules/order/src/services/actions/receive-return.ts index 304f11454c..a17539d289 100644 --- a/packages/modules/order/src/services/actions/receive-return.ts +++ b/packages/modules/order/src/services/actions/receive-return.ts @@ -1,5 +1,6 @@ import { Context, OrderTypes } from "@medusajs/types" import { MathBN, ReturnStatus } from "@medusajs/utils" +import { OrderChangeType } from "@types" import { ChangeActionType } from "../../utils" export async function receiveReturn( @@ -35,6 +36,7 @@ export async function receiveReturn( order_id: returnEntry.order_id, reference: "return", reference_id: returnEntry.id, + change_type: OrderChangeType.RETURN, description: data.description, internal_note: data.internal_note, created_by: data.created_by,