order entity modification
This commit is contained in:
@@ -10,19 +10,23 @@ import {
|
|||||||
PrimaryKey,
|
PrimaryKey,
|
||||||
BeforeCreate,
|
BeforeCreate,
|
||||||
type EventArgs,
|
type EventArgs,
|
||||||
|
OptionalProps
|
||||||
} from '@mikro-orm/core';
|
} from '@mikro-orm/core';
|
||||||
import { BaseEntity } from '../../../common/entities/base.entity';
|
|
||||||
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';
|
||||||
import { OrderItem } from './order-item.entity';
|
import { OrderItem } from './order-item.entity';
|
||||||
import { Payment } from 'src/modules/payment/entities/payment.entity';
|
import { Payment } from 'src/modules/payment/entities/payment.entity';
|
||||||
import { ulid } from 'ulid';
|
import { ulid } from 'ulid';
|
||||||
import { Admin } from 'src/modules/admin/entities/admin.entity';
|
import { Admin } from 'src/modules/admin/entities/admin.entity';
|
||||||
|
import { PaymentStatusEnum } from 'src/modules/payment/interface/payment';
|
||||||
|
|
||||||
@Entity({ tableName: 'orders' })
|
@Entity({ tableName: 'orders' })
|
||||||
@Index({ properties: ['user', 'status'] })
|
@Index({ properties: ['user', 'status'] })
|
||||||
@Index({ properties: ['status'] })
|
@Index({ properties: ['status'] })
|
||||||
export class Order extends BaseEntity {
|
export class Order {
|
||||||
|
[OptionalProps]?: 'createdAt' | 'deletedAt' | 'balance' | 'paidAmount'
|
||||||
|
| 'discount' | 'subTotal' | 'total' | 'taxAmount';
|
||||||
|
|
||||||
@PrimaryKey({ type: 'string', columnType: 'char(26)' })
|
@PrimaryKey({ type: 'string', columnType: 'char(26)' })
|
||||||
id: string = ulid()
|
id: string = ulid()
|
||||||
|
|
||||||
@@ -55,33 +59,60 @@ export class Order extends BaseEntity {
|
|||||||
orderNumber?: number;
|
orderNumber?: number;
|
||||||
|
|
||||||
|
|
||||||
@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 {
|
||||||
|
if (!this.items.isInitialized()) return 0;
|
||||||
|
return this.items
|
||||||
|
.getItems()
|
||||||
|
.reduce((sum, p) => sum + Number(p.discount), 0);
|
||||||
|
}
|
||||||
|
|
||||||
@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 {
|
||||||
|
if (!this.items.isInitialized()) return 0;
|
||||||
|
return this.items
|
||||||
|
.getItems()
|
||||||
|
.reduce((sum, p) => sum + Number(p.subTotal), 0)
|
||||||
|
}
|
||||||
|
|
||||||
@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 {
|
||||||
|
return this.enableTax ? this.total * 0.1 : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@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 {
|
||||||
|
return this.subTotal - this.discount + Number(this.taxAmount)
|
||||||
|
}
|
||||||
|
|
||||||
@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;
|
||||||
|
|
||||||
|
|
||||||
// private _balance!: number;
|
// private _balance!: number;
|
||||||
// get balance(): number {
|
|
||||||
// return this._balance
|
|
||||||
// }
|
|
||||||
// set balance(value) {
|
// set balance(value) {
|
||||||
// this._balance = this.total - this.paidAmount
|
// this._balance = this.total - this.paidAmount
|
||||||
// }
|
// }
|
||||||
|
|
||||||
@Property({ type: 'decimal', precision: 10, scale: 0, default: null, nullable: true })
|
|
||||||
balance?: number;
|
get paidAmount(): number {
|
||||||
|
if (!this.payments.isInitialized()) return 0;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
@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
|
||||||
@@ -105,6 +136,12 @@ export class Order extends BaseEntity {
|
|||||||
@Property({ type: 'boolean', default: false })
|
@Property({ type: 'boolean', default: false })
|
||||||
enableTax?: Boolean = false
|
enableTax?: Boolean = false
|
||||||
|
|
||||||
|
@Property({ defaultRaw: 'now()', columnType: 'timestamptz' })
|
||||||
|
createdAt: Date = new Date();
|
||||||
|
|
||||||
|
@Property({ nullable: true, columnType: 'timestamptz' })
|
||||||
|
deletedAt?: Date;
|
||||||
|
|
||||||
@BeforeCreate()
|
@BeforeCreate()
|
||||||
async generateOrderNumber(args: EventArgs<Order>) {
|
async generateOrderNumber(args: EventArgs<Order>) {
|
||||||
const em = args.em;
|
const em = args.em;
|
||||||
|
|||||||
@@ -42,14 +42,16 @@ export class OrderService {
|
|||||||
|
|
||||||
async createOrderAsAdmin(adminId: string, dto: CreateOrderAsAdminDto) {
|
async createOrderAsAdmin(adminId: string, dto: CreateOrderAsAdminDto) {
|
||||||
const order = await this.createOrder({ ...dto, adminId })
|
const order = await this.createOrder({ ...dto, adminId })
|
||||||
await this.calculateOrder(order)
|
// await this.calculateOrder(order)
|
||||||
this.em.flush()
|
// this.em.flush()
|
||||||
|
this.logger.log("Order created as admin")
|
||||||
return order
|
return order
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async createOrderAsUser(userId: string, dto: CreateOrderDto) {
|
async createOrderAsUser(userId: string, dto: CreateOrderDto) {
|
||||||
const order = await this.createOrder({ ...dto, userId, status: OrderStatusEnum.CREATED })
|
const order = await this.createOrder({ ...dto, userId, status: OrderStatusEnum.CREATED })
|
||||||
|
this.logger.log("Order created as admin")
|
||||||
return order
|
return order
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -101,13 +103,13 @@ export class OrderService {
|
|||||||
throw new BadRequestException("some products not found")
|
throw new BadRequestException("some products not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
items.forEach(item => {
|
for (const item of items) {
|
||||||
this.persistOrderItem(order, item)
|
this.persistOrderItem(order, item)
|
||||||
});
|
}
|
||||||
|
|
||||||
// TODO : calculation must be done after create order
|
// TODO : calculation must be done after create order
|
||||||
|
|
||||||
await this.calculateOrder(order)
|
// await this.calculateOrder(order)
|
||||||
|
|
||||||
// await em.flush()
|
// await em.flush()
|
||||||
|
|
||||||
@@ -131,7 +133,7 @@ export class OrderService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (adminId) {
|
if (adminId != undefined) {
|
||||||
const admin = await this.adminRepository.findOne({ id: adminId })
|
const admin = await this.adminRepository.findOne({ id: adminId })
|
||||||
if (!admin) {
|
if (!admin) {
|
||||||
throw new BadRequestException("Admin not found")
|
throw new BadRequestException("Admin not found")
|
||||||
@@ -140,7 +142,7 @@ export class OrderService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (designerId) {
|
if (designerId != undefined) {
|
||||||
const designer = await this.adminRepository.findOne({ id: designerId })
|
const designer = await this.adminRepository.findOne({ id: designerId })
|
||||||
if (!designer) {
|
if (!designer) {
|
||||||
throw new BadRequestException("designer not found")
|
throw new BadRequestException("designer not found")
|
||||||
@@ -148,31 +150,27 @@ export class OrderService {
|
|||||||
order.designer = designer
|
order.designer = designer
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attachments) {
|
if (attachments != undefined) {
|
||||||
order.attachments = attachments
|
order.attachments = attachments
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof enableTax !== 'undefined') {
|
if (enableTax != undefined) {
|
||||||
order.enableTax = enableTax
|
order.enableTax = enableTax
|
||||||
}
|
}
|
||||||
|
|
||||||
if (estimatedDays) {
|
if (estimatedDays != undefined) {
|
||||||
order.estimatedDays = estimatedDays
|
order.estimatedDays = estimatedDays
|
||||||
}
|
}
|
||||||
|
|
||||||
if (paymentMethod) {
|
if (paymentMethod != undefined) {
|
||||||
order.paymentMethod = paymentMethod
|
order.paymentMethod = paymentMethod
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status) {
|
if (status != undefined) {
|
||||||
order.status = status
|
order.status = status
|
||||||
}
|
}
|
||||||
|
|
||||||
this.em.persist(order)
|
await this.em.persistAndFlush(order)
|
||||||
|
|
||||||
await this.calculateOrder(order)
|
|
||||||
|
|
||||||
await this.em.flush()
|
|
||||||
|
|
||||||
return order
|
return order
|
||||||
}
|
}
|
||||||
@@ -180,11 +178,13 @@ export class OrderService {
|
|||||||
async updateOrderAsAdmin(orderId: string, dto: IUpdateOrder) {
|
async updateOrderAsAdmin(orderId: string, dto: IUpdateOrder) {
|
||||||
const order = await this.findOneOrFail(orderId)
|
const order = await this.findOneOrFail(orderId)
|
||||||
|
|
||||||
await this.updateOrder(order, dto)
|
const updateOrder= await this.updateOrder(order, dto)
|
||||||
|
|
||||||
const updateOrder = await this.calculateOrder(order)
|
// const updateOrder = await this.calculateOrder(order)
|
||||||
|
|
||||||
await this.em.flush()
|
// await this.em.flush()
|
||||||
|
|
||||||
|
this.logger.log("Order updated as admin")
|
||||||
|
|
||||||
return updateOrder
|
return updateOrder
|
||||||
}
|
}
|
||||||
@@ -216,9 +216,9 @@ export class OrderService {
|
|||||||
|
|
||||||
await this.em.flush()
|
await this.em.flush()
|
||||||
|
|
||||||
await this.calculateOrder(undefined, orderId)
|
// await this.calculateOrder(undefined, orderId)
|
||||||
|
|
||||||
await this.em.flush()
|
// await this.em.flush()
|
||||||
|
|
||||||
return orderItem
|
return orderItem
|
||||||
}
|
}
|
||||||
@@ -276,9 +276,9 @@ export class OrderService {
|
|||||||
|
|
||||||
const orderItem = await this.updateOrderItem(itemId, dto)
|
const orderItem = await this.updateOrderItem(itemId, dto)
|
||||||
|
|
||||||
await this.calculateOrder(undefined, orderId)
|
// await this.calculateOrder(undefined, orderId)
|
||||||
|
|
||||||
await this.em.flush()
|
// await this.em.flush()
|
||||||
|
|
||||||
return orderItem
|
return orderItem
|
||||||
}
|
}
|
||||||
@@ -337,9 +337,9 @@ export class OrderService {
|
|||||||
|
|
||||||
await this.removeOrderItem(itemId)
|
await this.removeOrderItem(itemId)
|
||||||
|
|
||||||
await this.calculateOrder(undefined, orderId)
|
// await this.calculateOrder(undefined, orderId)
|
||||||
|
|
||||||
await this.em.flush()
|
// await this.em.flush()
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -391,44 +391,44 @@ export class OrderService {
|
|||||||
return order
|
return order
|
||||||
}
|
}
|
||||||
|
|
||||||
async calculateOrder(inputOrder?: Order, orderId?: string) {
|
// async calculateOrder(inputOrder?: Order, orderId?: string) {
|
||||||
let order: undefined | Order = inputOrder
|
// let order: undefined | Order = inputOrder
|
||||||
|
|
||||||
if (!order && orderId) {
|
// if (!order && orderId) {
|
||||||
order = await this.findOneOrFail(orderId)
|
// order = await this.findOneOrFail(orderId)
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (!order) {
|
// if (!order) {
|
||||||
throw new BadRequestException("Order not found")
|
// throw new BadRequestException("Order not found")
|
||||||
}
|
// }
|
||||||
// calculate order financials
|
// // calculate order financials
|
||||||
let subTotal = 0
|
// const subTotal = order.items.reduce((sum, item) => {
|
||||||
let totalDiscount = 0
|
// return sum + item.subTotal
|
||||||
|
// }, 0)
|
||||||
|
|
||||||
// TODO : use reduce
|
// const totalDiscount = order.items.reduce((sum, item) => {
|
||||||
for (let orderItem of order.items) {
|
// return sum + Number(item.discount)
|
||||||
subTotal += orderItem.total
|
// }, 0)
|
||||||
totalDiscount += Number(orderItem.discount)
|
|
||||||
}
|
|
||||||
|
|
||||||
const totalBeforeTax = subTotal - totalDiscount
|
|
||||||
let tax = 0
|
|
||||||
|
|
||||||
if (order.enableTax) {
|
// const totalBeforeTax = subTotal - totalDiscount
|
||||||
tax = 0.1 * totalBeforeTax
|
// let tax = 0
|
||||||
}
|
|
||||||
|
|
||||||
const total = totalBeforeTax + tax
|
// if (order.enableTax) {
|
||||||
const paidAmount = await this.paymentRepository.getActualPaidAmount(order.id)
|
// tax = 0.1 * totalBeforeTax
|
||||||
// Update Order financial values
|
// }
|
||||||
order.subTotal = subTotal
|
|
||||||
order.discount = totalDiscount
|
|
||||||
order.taxAmount = tax
|
|
||||||
order.total = total
|
|
||||||
order.balance = total - paidAmount
|
|
||||||
|
|
||||||
return order
|
// const total = totalBeforeTax + tax
|
||||||
}
|
|
||||||
|
// // Update Order financial values
|
||||||
|
// // order.subTotal = subTotal
|
||||||
|
// // order.discount = totalDiscount
|
||||||
|
// // order.taxAmount = tax
|
||||||
|
// // order.total = total
|
||||||
|
// // order.balance = total - paidAmount
|
||||||
|
|
||||||
|
// return order
|
||||||
|
// }
|
||||||
|
|
||||||
async confirmOrderItem(userId: string, orderId: string, orderItemId: number) {
|
async confirmOrderItem(userId: string, orderId: string, orderItemId: number) {
|
||||||
|
|
||||||
@@ -477,7 +477,7 @@ export class OrderService {
|
|||||||
throw new BadRequestException("Order not found")
|
throw new BadRequestException("Order not found")
|
||||||
}
|
}
|
||||||
if (![OrderStatusEnum.CREATED, OrderStatusEnum.INVOICED].includes(order.status)) {
|
if (![OrderStatusEnum.CREATED, OrderStatusEnum.INVOICED].includes(order.status)) {
|
||||||
throw new BadRequestException("Order status must be of of Drfat or Invoiced")
|
throw new BadRequestException("Order status must be of of Draft or Invoiced")
|
||||||
}
|
}
|
||||||
if (order.payments.length > 0) {
|
if (order.payments.length > 0) {
|
||||||
throw new BadRequestException("order with payments can not be deleted!")
|
throw new BadRequestException("order with payments can not be deleted!")
|
||||||
@@ -522,7 +522,7 @@ export class OrderService {
|
|||||||
async createInvoice(orderId: string) {
|
async createInvoice(orderId: string) {
|
||||||
const order = await this.findOneOrFail(orderId)
|
const order = await this.findOneOrFail(orderId)
|
||||||
await this.updateStatus(orderId, OrderStatusEnum.INVOICED)
|
await this.updateStatus(orderId, OrderStatusEnum.INVOICED)
|
||||||
await this.calculateOrder(order)
|
// await this.calculateOrder(order)
|
||||||
await this.em.flush()
|
await this.em.flush()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -222,8 +222,8 @@ export class PaymentService {
|
|||||||
payment.transactionId = referenceId;
|
payment.transactionId = referenceId;
|
||||||
// TODO : use decimal js
|
// TODO : use decimal js
|
||||||
// does need persist or not
|
// does need persist or not
|
||||||
payment.order.paidAmount! += payment.amount
|
// payment.order.paidAmount! += payment.amount
|
||||||
payment.order.balance! -= payment.amount
|
// payment.order.balance! -= payment.amount
|
||||||
|
|
||||||
await em.flush();
|
await em.flush();
|
||||||
return payment;
|
return payment;
|
||||||
@@ -261,8 +261,8 @@ export class PaymentService {
|
|||||||
payment.failedAt = null;
|
payment.failedAt = null;
|
||||||
|
|
||||||
// TODO : use decimal js
|
// TODO : use decimal js
|
||||||
payment.order.paidAmount! += payment.amount
|
// payment.order.paidAmount! += payment.amount
|
||||||
payment.order.balance! -= payment.amount
|
// payment.order.balance! -= payment.amount
|
||||||
|
|
||||||
em.persist(payment);
|
em.persist(payment);
|
||||||
em.persist(payment.order);
|
em.persist(payment.order);
|
||||||
@@ -286,8 +286,8 @@ export class PaymentService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (payment.status == PaymentStatusEnum.Paid) {
|
if (payment.status == PaymentStatusEnum.Paid) {
|
||||||
payment.order.paidAmount! -= payment.amount
|
// payment.order.paidAmount! -= payment.amount
|
||||||
payment.order.balance! += payment.amount
|
// payment.order.balance! += payment.amount
|
||||||
|
|
||||||
em.persistAndFlush(payment.order)
|
em.persistAndFlush(payment.order)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user