diff --git a/src/modules/order/dto/create-order.dto.ts b/src/modules/order/dto/create-order.dto.ts index fddbcf4..009fff7 100644 --- a/src/modules/order/dto/create-order.dto.ts +++ b/src/modules/order/dto/create-order.dto.ts @@ -10,7 +10,7 @@ import { } from 'class-validator'; import { ApiPropertyOptional, ApiProperty } from '@nestjs/swagger'; import { Type } from 'class-transformer'; -import { IAttachment, IField, OrderStatusEnum } from '../interface/order.interface'; +import { IAttachment, IField, OrderItemStatusEnum } from '../interface/order.interface'; export class CreateOrderItemAsUserDto { @@ -22,6 +22,10 @@ export class CreateOrderItemAsUserDto { @IsNumber() quantity: number + @ApiProperty({ enum: OrderItemStatusEnum }) + @IsEnum(() => OrderItemStatusEnum) + status: OrderItemStatusEnum + @ApiProperty() @IsArray() attributes: IField[] @@ -113,8 +117,8 @@ export class CreateOrderAsAdminDto { unitPrice: 150000, discount: 20000, adminDescription: '', - description:'توضیحات کاربر', - + description: 'توضیحات کاربر', + } ] }) @@ -137,8 +141,5 @@ export class CreateOrderAsAdminDto { @IsInt() estimatedDays: number - @ApiProperty({ enum: OrderStatusEnum }) - @IsEnum(OrderStatusEnum) - status: OrderStatusEnum } diff --git a/src/modules/order/entities/order-item.entity.ts b/src/modules/order/entities/order-item.entity.ts index 15cb6d7..fb11edb 100644 --- a/src/modules/order/entities/order-item.entity.ts +++ b/src/modules/order/entities/order-item.entity.ts @@ -1,7 +1,7 @@ -import { Entity, Formula, Index, ManyToOne, OptionalProps, Property } from '@mikro-orm/core'; +import { Entity, Enum, Index, ManyToOne, OptionalProps, Property } from '@mikro-orm/core'; import { Order } from './order.entity'; import { Product } from 'src/modules/product/entities/product.entity'; -import { IAttachment, IField } from '../interface/order.interface'; +import { IAttachment, IField, OrderItemStatusEnum } from '../interface/order.interface'; import { Admin } from 'src/modules/admin/entities/admin.entity'; import { BaseEntity } from 'src/common/entities/base.entity'; @@ -17,6 +17,9 @@ export class OrderItem extends BaseEntity { @ManyToOne(() => Product) product!: Product; + @Enum(() => OrderItemStatusEnum) + status!: OrderItemStatusEnum; + @ManyToOne(() => Admin, { nullable: true }) designer?: Admin @@ -26,24 +29,23 @@ export class OrderItem extends BaseEntity { @Property({ type: 'int' }) quantity!: number; - @Property({ type: 'decimal', precision: 10, scale: 0, nullable: true, }) + @Property({ type: 'int', nullable: true, }) unitPrice?: number; // @Formula(alias => ` // COALESCE(${alias}.unit_price, 0) * ${alias}.quantity // `) @Property({ - type: 'decimal', precision: 10, - columnType: 'numeric(10,0) GENERATED ALWAYS AS (COALESCE(unit_price, 0) * quantity) STORED', + type: 'int', + columnType: 'int GENERATED ALWAYS AS (COALESCE(unit_price, 0) * quantity) STORED', persist: false, - scale: 0, - nullable: true + nullable: true }) subTotal!: number; @Property({ - type: 'decimal', precision: 10, - scale: 0, nullable: true + type: 'int', + nullable: true }) discount?: number; @@ -52,9 +54,9 @@ export class OrderItem extends BaseEntity { // - COALESCE(${alias}.discount, 0) // `) @Property({ - type: 'decimal', precision: 10, - scale: 0, nullable: true, - columnType: 'numeric(10,0) GENERATED ALWAYS AS ((COALESCE(unit_price, 0) * quantity) - COALESCE(discount, 0)) STORED', + type: 'int', + nullable: true, + columnType: 'int GENERATED ALWAYS AS ((COALESCE(unit_price, 0) * quantity) - COALESCE(discount, 0)) STORED', persist: false }) total!: number; diff --git a/src/modules/order/entities/order.entity.ts b/src/modules/order/entities/order.entity.ts index 9fc248a..592a64e 100644 --- a/src/modules/order/entities/order.entity.ts +++ b/src/modules/order/entities/order.entity.ts @@ -8,12 +8,8 @@ import { Cascade, Enum, PrimaryKey, - BeforeCreate, - type EventArgs, OptionalProps, - Formula } from '@mikro-orm/core'; -import { OrderStatusEnum } from '../interface/order.interface'; import { User } from '../../user/entities/user.entity'; import { OrderItem } from './order-item.entity'; import { Payment } from 'src/modules/payment/entities/payment.entity'; @@ -21,13 +17,12 @@ import { ulid } from 'ulid'; import { Admin } from 'src/modules/admin/entities/admin.entity'; import { PaymentStatusEnum } from 'src/modules/payment/interface/payment'; import { BaseEntity } from 'src/common/entities/base.entity'; +import { OrderStatusEnum } from '../interface/order.interface'; @Entity({ tableName: 'orders' }) -@Index({ properties: ['user', 'status'] }) -@Index({ properties: ['status'] }) -export class Order extends BaseEntity{ - [OptionalProps]?: 'createdAt' | 'deletedAt' | 'balance' | 'paidAmount' - | 'discount' | 'subTotal' | 'total' | 'taxAmount'; +@Index({ properties: ['user'] }) +export class Order extends BaseEntity { + [OptionalProps]?: 'createdAt' | 'deletedAt' | 'orderNumber'|'paidAmount'|'balance'; @PrimaryKey({ type: 'string', columnType: 'char(26)' }) id: string = ulid() @@ -51,140 +46,32 @@ export class Order extends BaseEntity{ @ManyToOne(() => Admin, { nullable: true }) creator?: Admin + @Property({ type: 'int', defaultRaw: `nextval('order_number_seq')` }) + orderNumber!: number; + @Property({ type: 'int', nullable: true }) - orderNumber?: number; + discount?: number; - // @Property({ type: 'decimal', precision: 10, scale: 0, default: null, nullable: true }) - // discount?: number; - @Formula(alias => ` - ( - SELECT COALESCE(SUM(oi.discount), 0) - FROM order_items oi - WHERE oi.order_id = ${alias}.id - ) - `) - discount!: number; + @Property({ type: 'int', nullable: true }) + subTotal?: number; - // @Property({ type: 'decimal', precision: 10, scale: 0, default: null, nullable: true }) - // subTotal?: number; - @Formula(alias => ` - ( - SELECT COALESCE(SUM(COALESCE(oi.unit_price, 0) * oi.quantity), 0) - FROM order_items oi - WHERE oi.order_id = ${alias}.id - ) -`) - subTotal!: number; + @Property({ type: 'int', nullable: true }) + taxAmount?: number; - // @Property({ type: 'decimal', precision: 10, scale: 0, default: null, nullable: true }) - // taxAmount?: number; - @Formula(alias => ` - ( - CASE - WHEN ${alias}.enable_tax = true THEN - ( - SELECT COALESCE(SUM(COALESCE(oi.unit_price, 0) * oi.quantity), 0) - FROM order_items oi - WHERE oi.order_id = ${alias}.id - ) * 0.1 - ELSE 0 - END - ) - `) - taxAmount!: number; + @Property({ type: 'int', nullable: true }) + total?: number; - - // @Property({ type: 'decimal', precision: 10, scale: 0, default: null, nullable: true }) - // total?: number; - @Formula(alias => ` - ( - ( - SELECT COALESCE(SUM(COALESCE(oi.unit_price, 0) * oi.quantity), 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(COALESCE(oi.unit_price, 0) * oi.quantity), 0) - FROM order_items oi - WHERE oi.order_id = ${alias}.id - ) * 0.1 - ELSE 0 - END - ) - `) - total!: number; + @Property({ type: 'int', default: 0 }) + paidAmount: number = 0; - // @Property({ type: 'decimal', precision: 10, scale: 0, default: null, nullable: true }) - // paidAmount?: number; - - - // private _balance!: number; - // set balance(value) { - // this._balance = this.total - this.paidAmount - // } - - - @Formula(alias => ` - ( - SELECT COALESCE(SUM(p.amount), 0) - FROM payments p - WHERE p.order_id = ${alias}.id - AND p.status = '${PaymentStatusEnum.Paid}' - ) - `) - paidAmount!: number; - - - @Formula(alias => ` - ( - ( - ( - SELECT COALESCE(SUM(COALESCE(oi.unit_price, 0) * oi.quantity), 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(COALESCE(oi.unit_price, 0) * oi.quantity), 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', default: 0 }) + balance: number = 0; @Property({ type: 'int', nullable: true }) @@ -192,7 +79,7 @@ export class Order extends BaseEntity{ @Enum(() => OrderStatusEnum) - status!: OrderStatusEnum; + status: OrderStatusEnum = OrderStatusEnum.REQUEST; @Property({ type: 'string', nullable: true }) @@ -202,26 +89,7 @@ export class Order extends BaseEntity{ invoicedAt?: Date; @Property({ type: 'boolean', default: false }) - enableTax?: Boolean = false + enableTax?: boolean = false - @BeforeCreate() - async generateOrderNumber(args: EventArgs) { - const em = args.em; - const order = args.entity; - - - const maxOrder = await em.findOne( - Order, - { id: { $ne: null } }, - { - orderBy: { orderNumber: 'DESC' }, - fields: ['orderNumber'], - }, - ); - - // Set the next order number (1 if no orders exist, otherwise max + 1) - order.orderNumber = maxOrder?.orderNumber ? maxOrder.orderNumber + 1 : 1; - } - } diff --git a/src/modules/order/interface/order.interface.ts b/src/modules/order/interface/order.interface.ts index 1f4b536..32ec4e1 100644 --- a/src/modules/order/interface/order.interface.ts +++ b/src/modules/order/interface/order.interface.ts @@ -2,6 +2,15 @@ import { Admin } from "src/modules/admin/entities/admin.entity" import { Product } from "src/modules/product/entities/product.entity" export enum OrderStatusEnum { + REQUEST = 'request', + + INVOICED = 'invoiced', + + ORDER = 'order', + +} + +export enum OrderItemStatusEnum { CREATED = 'created', INVOICED = 'invoiced', @@ -35,6 +44,7 @@ export interface IAttachment { type: string, url: string } export interface CreateOrderItem { productId: string, quantity: number + status: OrderItemStatusEnum, attributes?: IField[] description?: string attachments?: IAttachment[] @@ -53,7 +63,7 @@ export type CreateOrderItemPopulated = Omit