import { Entity, Index, ManyToOne, OneToMany, Property, Collection, Cascade, Enum, BeforeCreate, Unique, type EventArgs, } from '@mikro-orm/core'; import { BaseEntity } from '../../../common/entities/base.entity'; import { OrderCouponDetail, OrderStatus } from '../interface/order.interface'; import { User } from '../../users/entities/user.entity'; import { Shop } from '../../shops/entities/shop.entity'; import { PaymentMethod } from '../../payments/entities/payment-method.entity'; import { OrderItem } from './order-item.entity'; import { Delivery } from '../../delivery/entities/delivery.entity'; import { OrderUserAddress, OrderCarAddress } from '../interface/order.interface'; import { Payment } from 'src/modules/payments/entities/payment.entity'; @Entity({ tableName: 'orders' }) @Unique({ properties: ['shop', 'orderNumber'] }) @Index({ properties: ['shop', 'status'] }) @Index({ properties: ['user', 'status'] }) @Index({ properties: ['shop', 'orderNumber'] }) @Index({ properties: ['status'] }) export class Order extends BaseEntity { @ManyToOne(() => User) user!: User; @ManyToOne(() => Shop) shop!: Shop; @ManyToOne(() => Delivery) deliveryMethod!: Delivery; @OneToMany(() => Payment, payment => payment.order, { cascade: [Cascade.ALL], orphanRemoval: true, }) payments = new Collection(this); @OneToMany(() => OrderItem, item => item.order, { cascade: [Cascade.ALL], orphanRemoval: true, }) items = new Collection(this); @Property({ type: 'json', nullable: true }) userAddress?: OrderUserAddress | null; // for car delivery @Property({ type: 'json', nullable: true }) carAddress?: OrderCarAddress | null; @ManyToOne(() => PaymentMethod) paymentMethod: PaymentMethod; @Property({ type: 'int', defaultRaw: `nextval('order_number_seq')` }) orderNumber!: number; @Property({ type: 'decimal', precision: 10, scale: 0, default: 0 }) couponDiscount: number = 0; @Property({ type: 'jsonb', nullable: true }) couponDetail?: OrderCouponDetail | null; @Property({ type: 'decimal', precision: 10, scale: 0, default: 0 }) itemsDiscount: number = 0; @Property({ type: 'decimal', precision: 10, scale: 0, default: 0 }) totalDiscount: number = 0; @Property({ type: 'decimal', precision: 10, scale: 0 }) subTotal!: number; @Property({ type: 'decimal', precision: 10, scale: 0, default: 0 }) tax: number = 0; @Property({ type: 'decimal', precision: 10, scale: 0, default: 0 }) deliveryFee: number = 0; @Property({ type: 'decimal', precision: 10, scale: 0 }) total!: number; @Property({ type: 'int', default: 0 }) totalItems: number = 0; @Property({ type: 'text', nullable: true }) description?: string; @Property({ nullable: true }) tableNumber?: string; @Enum(() => OrderStatus) status!: OrderStatus; @Property({ type: 'json', nullable: true }) history: Array<{ status: OrderStatus; changedAt: Date; desc: string | null }> = []; }