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 { 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;
+108 -31
View File
@@ -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