diff --git a/src/modules/order/entities/order-item.entity.ts b/src/modules/order/entities/order-item.entity.ts index 73378e5..da61674 100644 --- a/src/modules/order/entities/order-item.entity.ts +++ b/src/modules/order/entities/order-item.entity.ts @@ -1,4 +1,4 @@ -import { Entity, Index, ManyToOne, PrimaryKey, Property } from '@mikro-orm/core'; +import { Entity, Formula, Index, ManyToOne, PrimaryKey, Property } from '@mikro-orm/core'; import { BaseEntity } from '../../../common/entities/base.entity'; import { Order } from './order.entity'; import { Product } from 'src/modules/product/entities/product.entity'; @@ -8,6 +8,7 @@ import { IAttribute } from '../interface/order.interface'; @Entity({ tableName: 'order_items' }) @Index({ properties: ['order'] }) export class OrderItem extends BaseEntity { + @PrimaryKey({ type: 'bigint', autoincrement: true }) id: bigint @@ -26,16 +27,19 @@ export class OrderItem extends BaseEntity { @Property({ type: 'decimal', precision: 10, scale: 0, nullable: true, }) unitPrice?: number; - get subTotal(): number { - return Number(this.unitPrice) * (this.quantity) - } + @Formula(alias => ` + COALESCE(${alias}.unit_price, 0) * ${alias}.quantity + `) + subTotal!: number; @Property({ type: 'decimal', precision: 10, scale: 0, nullable: true }) discount?: number; - get total(): number { - return Number(this.subTotal) - Number(this.discount || 0) - } + @Formula(alias => ` + (COALESCE(${alias}.unit_price, 0) * ${alias}.quantity) + - COALESCE(${alias}.discount, 0) + `) + total!: number; @Property({ type: 'text', nullable: true }) description?: string; diff --git a/src/modules/order/entities/order.entity.ts b/src/modules/order/entities/order.entity.ts index a69e0d2..97c7d1d 100644 --- a/src/modules/order/entities/order.entity.ts +++ b/src/modules/order/entities/order.entity.ts @@ -10,7 +10,8 @@ import { PrimaryKey, BeforeCreate, type EventArgs, - OptionalProps + OptionalProps, + Formula } from '@mikro-orm/core'; import { OrderStatusEnum } from '../interface/order.interface'; import { User } from '../../user/entities/user.entity'; @@ -25,7 +26,7 @@ import { PaymentStatusEnum } from 'src/modules/payment/interface/payment'; @Index({ properties: ['status'] }) export class Order { [OptionalProps]?: 'createdAt' | 'deletedAt' | 'balance' | 'paidAmount' - | 'discount' | 'subTotal' | 'total' | 'taxAmount'; + | 'discount' | 'subTotal' | 'total' | 'taxAmount'; @PrimaryKey({ type: 'string', columnType: 'char(26)' }) id: string = ulid() @@ -61,34 +62,76 @@ export class Order { // @Property({ type: 'decimal', precision: 10, scale: 0, default: null, nullable: true }) // discount?: number; - get discount(): number { - if (!this.items.isInitialized()) return 0; - return this.items - .getItems() - .reduce((sum, p) => sum + Number(p.discount), 0); - } + @Formula(alias => ` + ( + SELECT COALESCE(SUM(oi.discount), 0) + FROM order_items oi + WHERE oi.order_id = ${alias}.id + ) + `) + discount!: number; + // @Property({ type: 'decimal', precision: 10, scale: 0, default: null, nullable: true }) // subTotal?: number; - get subTotal(): number { - if (!this.items.isInitialized()) return 0; - return this.items - .getItems() - .reduce((sum, p) => sum + Number(p.subTotal), 0) - } + @Formula(alias => ` + ( + SELECT COALESCE(SUM(oi.sub_total), 0) + FROM order_items oi + WHERE oi.order_id = ${alias}.id + ) + `) + subTotal!: number; + // @Property({ type: 'decimal', precision: 10, scale: 0, default: null, nullable: true }) // taxAmount?: number; - get taxAmount(): number { - return this.enableTax ? this.total * 0.1 : 0 - } + @Formula(alias => ` + ( + CASE + WHEN ${alias}.enable_tax = true THEN + ( + SELECT COALESCE(SUM(oi.sub_total), 0) + FROM order_items oi + WHERE oi.order_id = ${alias}.id + ) * 0.1 + ELSE 0 + END + ) + `) + taxAmount!: number; + // @Property({ type: 'decimal', precision: 10, scale: 0, default: null, nullable: true }) // total?: number; - get total(): number { - return this.subTotal - this.discount + Number(this.taxAmount) - } + @Formula(alias => ` + ( + ( + SELECT COALESCE(SUM(oi.sub_total), 0) + FROM order_items oi + WHERE oi.order_id = ${alias}.id + ) + - + ( + SELECT COALESCE(SUM(oi.discount), 0) + FROM order_items oi + WHERE oi.order_id = ${alias}.id + ) + + + CASE + WHEN ${alias}.enable_tax = true THEN + ( + SELECT COALESCE(SUM(oi.sub_total), 0) + FROM order_items oi + WHERE oi.order_id = ${alias}.id + ) * 0.1 + ELSE 0 + END + ) + `) + total!: number; + // @Property({ type: 'decimal', precision: 10, scale: 0, default: null, nullable: true }) // paidAmount?: number; @@ -100,19 +143,53 @@ export class Order { // } - get paidAmount(): number { - if (!this.payments.isInitialized()) return 0; + @Formula(alias => ` + ( + SELECT COALESCE(SUM(p.amount), 0) + FROM payments p + WHERE p.order_id = ${alias}.id + AND p.status = '${PaymentStatusEnum.Paid}' + ) + `) + paidAmount!: number; - return this.payments - .getItems() - .filter(p => p.status == PaymentStatusEnum.Paid) - .reduce((sum, p) => sum + Number(p.amount), 0); - } - get balance(): number { - const total = Number(this.total ?? 0); - return total - this.paidAmount; - } + @Formula(alias => ` + ( + ( + ( + SELECT COALESCE(SUM(oi.sub_total), 0) + FROM order_items oi + WHERE oi.order_id = ${alias}.id + ) + - + ( + SELECT COALESCE(SUM(oi.discount), 0) + FROM order_items oi + WHERE oi.order_id = ${alias}.id + ) + + + CASE + WHEN ${alias}.enable_tax = true THEN + ( + SELECT COALESCE(SUM(oi.sub_total), 0) + FROM order_items oi + WHERE oi.order_id = ${alias}.id + ) * 0.1 + ELSE 0 + END + ) + - + ( + SELECT COALESCE(SUM(p.amount), 0) + FROM payments p + WHERE p.order_id = ${alias}.id + AND p.status = '${PaymentStatusEnum.Paid}' + ) + ) + `) + balance!: number; + @Property({ type: 'int', nullable: true }) estimatedDays?: number; // number of days to be done