use formula

This commit is contained in:
2026-01-27 10:35:23 +03:30
parent b858cbed38
commit 75f2c4b73e
2 changed files with 119 additions and 38 deletions
@@ -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 { BaseEntity } from '../../../common/entities/base.entity';
import { Order } from './order.entity'; import { Order } from './order.entity';
import { Product } from 'src/modules/product/entities/product.entity'; import { Product } from 'src/modules/product/entities/product.entity';
@@ -8,6 +8,7 @@ import { IAttribute } from '../interface/order.interface';
@Entity({ tableName: 'order_items' }) @Entity({ tableName: 'order_items' })
@Index({ properties: ['order'] }) @Index({ properties: ['order'] })
export class OrderItem extends BaseEntity { export class OrderItem extends BaseEntity {
@PrimaryKey({ type: 'bigint', autoincrement: true }) @PrimaryKey({ type: 'bigint', autoincrement: true })
id: bigint id: bigint
@@ -26,16 +27,19 @@ export class OrderItem extends BaseEntity {
@Property({ type: 'decimal', precision: 10, scale: 0, nullable: true, }) @Property({ type: 'decimal', precision: 10, scale: 0, nullable: true, })
unitPrice?: number; unitPrice?: number;
get subTotal(): number { @Formula(alias => `
return Number(this.unitPrice) * (this.quantity) COALESCE(${alias}.unit_price, 0) * ${alias}.quantity
} `)
subTotal!: number;
@Property({ type: 'decimal', precision: 10, scale: 0, nullable: true }) @Property({ type: 'decimal', precision: 10, scale: 0, nullable: true })
discount?: number; discount?: number;
get total(): number { @Formula(alias => `
return Number(this.subTotal) - Number(this.discount || 0) (COALESCE(${alias}.unit_price, 0) * ${alias}.quantity)
} - COALESCE(${alias}.discount, 0)
`)
total!: number;
@Property({ type: 'text', nullable: true }) @Property({ type: 'text', nullable: true })
description?: string; description?: string;
+108 -31
View File
@@ -10,7 +10,8 @@ import {
PrimaryKey, PrimaryKey,
BeforeCreate, BeforeCreate,
type EventArgs, type EventArgs,
OptionalProps OptionalProps,
Formula
} from '@mikro-orm/core'; } from '@mikro-orm/core';
import { OrderStatusEnum } from '../interface/order.interface'; import { OrderStatusEnum } from '../interface/order.interface';
import { User } from '../../user/entities/user.entity'; import { User } from '../../user/entities/user.entity';
@@ -25,7 +26,7 @@ import { PaymentStatusEnum } from 'src/modules/payment/interface/payment';
@Index({ properties: ['status'] }) @Index({ properties: ['status'] })
export class Order { export class Order {
[OptionalProps]?: 'createdAt' | 'deletedAt' | 'balance' | 'paidAmount' [OptionalProps]?: 'createdAt' | 'deletedAt' | 'balance' | 'paidAmount'
| 'discount' | 'subTotal' | 'total' | 'taxAmount'; | 'discount' | 'subTotal' | 'total' | 'taxAmount';
@PrimaryKey({ type: 'string', columnType: 'char(26)' }) @PrimaryKey({ type: 'string', columnType: 'char(26)' })
id: string = ulid() id: string = ulid()
@@ -61,34 +62,76 @@ export class Order {
// @Property({ type: 'decimal', precision: 10, scale: 0, default: null, nullable: true }) // @Property({ type: 'decimal', precision: 10, scale: 0, default: null, nullable: true })
// discount?: number; // discount?: number;
get discount(): number { @Formula(alias => `
if (!this.items.isInitialized()) return 0; (
return this.items SELECT COALESCE(SUM(oi.discount), 0)
.getItems() FROM order_items oi
.reduce((sum, p) => sum + Number(p.discount), 0); WHERE oi.order_id = ${alias}.id
} )
`)
discount!: number;
// @Property({ type: 'decimal', precision: 10, scale: 0, default: null, nullable: true }) // @Property({ type: 'decimal', precision: 10, scale: 0, default: null, nullable: true })
// subTotal?: number; // subTotal?: number;
get subTotal(): number { @Formula(alias => `
if (!this.items.isInitialized()) return 0; (
return this.items SELECT COALESCE(SUM(oi.sub_total), 0)
.getItems() FROM order_items oi
.reduce((sum, p) => sum + Number(p.subTotal), 0) WHERE oi.order_id = ${alias}.id
} )
`)
subTotal!: number;
// @Property({ type: 'decimal', precision: 10, scale: 0, default: null, nullable: true }) // @Property({ type: 'decimal', precision: 10, scale: 0, default: null, nullable: true })
// taxAmount?: number; // taxAmount?: number;
get taxAmount(): number { @Formula(alias => `
return this.enableTax ? this.total * 0.1 : 0 (
} 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 }) // @Property({ type: 'decimal', precision: 10, scale: 0, default: null, nullable: true })
// total?: number; // total?: number;
get total(): number { @Formula(alias => `
return this.subTotal - this.discount + Number(this.taxAmount) (
} (
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 }) // @Property({ type: 'decimal', precision: 10, scale: 0, default: null, nullable: true })
// paidAmount?: number; // paidAmount?: number;
@@ -100,19 +143,53 @@ export class Order {
// } // }
get paidAmount(): number { @Formula(alias => `
if (!this.payments.isInitialized()) return 0; (
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 { @Formula(alias => `
const total = Number(this.total ?? 0); (
return total - this.paidAmount; (
} (
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 }) @Property({ type: 'int', nullable: true })
estimatedDays?: number; // number of days to be done estimatedDays?: number; // number of days to be done