clean order services
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { ConflictException, Injectable, NotFoundException } from '@nestjs/common';
|
||||
import { BadRequestException, ConflictException, Injectable, NotFoundException } from '@nestjs/common';
|
||||
import { Admin } from '../entities/admin.entity';
|
||||
import { Role } from '../../roles/entities/role.entity';
|
||||
import { EntityManager, RequiredEntityData } from '@mikro-orm/postgresql';
|
||||
@@ -113,4 +113,12 @@ export class AdminService {
|
||||
// TODO :L is this correct to soft delete
|
||||
return this.em.removeAndFlush(admin);
|
||||
}
|
||||
|
||||
async findOrFail(adminId: string) {
|
||||
const admin = await this.findById(adminId)
|
||||
if (!admin) {
|
||||
throw new BadRequestException("Admin not found")
|
||||
}
|
||||
return admin
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ export class OrderController {
|
||||
@UseGuards(AuthGuard)
|
||||
@ApiOperation({ summary: 'create order ' })
|
||||
createOrder(@UserId() userId: string, @Body() body: CreateOrderDto) {
|
||||
console.log(userId)
|
||||
return this.orderService.createOrderAsUser(userId, body);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ export class CreateOrderItemDtoAsAdmin {
|
||||
|
||||
@IsInt()
|
||||
@ApiProperty()
|
||||
productId: bigint;
|
||||
productId: number;
|
||||
|
||||
@ApiProperty()
|
||||
@IsNumber()
|
||||
@@ -76,7 +76,7 @@ export class CreateOrderItemDto {
|
||||
|
||||
@IsInt()
|
||||
@ApiProperty()
|
||||
productId: bigint;
|
||||
productId: number;
|
||||
|
||||
@ApiProperty()
|
||||
@IsNumber()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Entity, Formula, Index, ManyToOne, PrimaryKey, Property } from '@mikro-orm/core';
|
||||
import { Entity, Formula, Index, ManyToOne, OptionalProps, 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';
|
||||
@@ -7,7 +7,8 @@ import { IAttribute } from '../interface/order.interface';
|
||||
|
||||
@Entity({ tableName: 'order_items' })
|
||||
@Index({ properties: ['order'] })
|
||||
export class OrderItem extends BaseEntity {
|
||||
export class OrderItem {
|
||||
[OptionalProps]?: 'createdAt' | 'deletedAt' | 'subTotal' | 'total';
|
||||
|
||||
@PrimaryKey({ type: 'bigint', autoincrement: true })
|
||||
id: bigint
|
||||
@@ -52,4 +53,10 @@ export class OrderItem extends BaseEntity {
|
||||
|
||||
@Property({ nullable: true, columnType: 'timestamptz' })
|
||||
confirmedAt?: Date;
|
||||
|
||||
@Property({ defaultRaw: 'now()', columnType: 'timestamptz' })
|
||||
createdAt: Date = new Date();
|
||||
|
||||
@Property({ nullable: true, columnType: 'timestamptz' })
|
||||
deletedAt?: Date;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import { Product } from "src/modules/product/entities/product.entity"
|
||||
import { Order } from "../entities/order.entity"
|
||||
|
||||
export enum OrderStatusEnum {
|
||||
CREATED = 'created',
|
||||
|
||||
@@ -26,21 +29,27 @@ export enum OrderStatusEnum {
|
||||
}
|
||||
|
||||
|
||||
export interface IAddOrderItem {
|
||||
productId: bigint;
|
||||
export interface CreateOrderItemParam{
|
||||
quantity: number
|
||||
attributes?: IAttribute[]
|
||||
description?: string
|
||||
attachments?: { url: string, type: string }[]
|
||||
unitPrice?: number
|
||||
discount?: number
|
||||
}
|
||||
|
||||
|
||||
export interface CreateOrderParam {
|
||||
userId: string
|
||||
items: Array<{
|
||||
productId: number,
|
||||
quantity: number
|
||||
attributes: IAttribute[]
|
||||
description: string
|
||||
attachments: { url: string, type: string }[]
|
||||
unitPrice?: number
|
||||
discount?: number
|
||||
}
|
||||
|
||||
export type IUpdateOrderItem = Partial<IAddOrderItem>
|
||||
|
||||
export interface ICreateOrder {
|
||||
userId: string
|
||||
items: IAddOrderItem[];
|
||||
}>;
|
||||
status: OrderStatusEnum
|
||||
//optional
|
||||
enableTax?: Boolean
|
||||
@@ -51,6 +60,17 @@ export interface ICreateOrder {
|
||||
designerId?: string
|
||||
}
|
||||
|
||||
export type IUpdateOrder = Partial<Omit<ICreateOrder, 'items'>>
|
||||
export type UpdateOrderParam = Partial<Omit<CreateOrderParam, 'items'>>
|
||||
|
||||
|
||||
export interface UpdateOrderItem {
|
||||
productId?: number,
|
||||
quantity?: number
|
||||
attributes?: IAttribute[]
|
||||
description?: string
|
||||
attachments?: { url: string, type: string }[]
|
||||
unitPrice?: number
|
||||
discount?: number
|
||||
}
|
||||
|
||||
export interface IAttribute { attributeId: number, value: string | number | boolean }
|
||||
@@ -1,15 +1,18 @@
|
||||
import { Injectable, BadRequestException, Logger } from '@nestjs/common';
|
||||
import { EntityManager } from '@mikro-orm/postgresql';
|
||||
import { OrderItem } from '../entities/order-item.entity';
|
||||
import { OrderRepository } from '../repositories/order.repository';
|
||||
import { FindOrdersDto } from '../dto/find-orders.dto';
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||
import {
|
||||
CreateOrderDto, CreateOrderItemAsUserDto,
|
||||
CreateOrderItemDtoAsAdmin, CreateOrderAsAdminDto
|
||||
CreateOrderItemDtoAsAdmin
|
||||
} from '../dto/create-order.dto';
|
||||
import { UserService } from 'src/modules/user/providers/user.service';
|
||||
import { IAddOrderItem, ICreateOrder, OrderStatusEnum, IUpdateOrderItem, IUpdateOrder } from '../interface/order.interface';
|
||||
import {
|
||||
CreateOrderItemParam,
|
||||
CreateOrderParam, OrderStatusEnum,
|
||||
UpdateOrderItem, UpdateOrderParam
|
||||
} from '../interface/order.interface';
|
||||
import { OrderItemRepository } from '../repositories/order-item.repository';
|
||||
import { ProductService } from 'src/modules/product/providers/product.service';
|
||||
import { ProductRepository } from 'src/modules/product/repositories/product.repository';
|
||||
@@ -20,6 +23,9 @@ import { Order } from '../entities/order.entity';
|
||||
import { PaymentRepository } from 'src/modules/payment/repositories/payment.repository';
|
||||
import { UpdateOrderItemDtoAsAdmin, UpdateOrderItemDtoAsUser } from '../dto/update-order-item.dto';
|
||||
import { Admin } from 'src/modules/admin/entities/admin.entity';
|
||||
import { Product } from 'src/modules/product/entities/product.entity';
|
||||
import { AdminService } from 'src/modules/admin/providers/admin.service';
|
||||
import { OrderItem } from '../entities/order-item.entity';
|
||||
|
||||
|
||||
@Injectable()
|
||||
@@ -31,6 +37,7 @@ export class OrderService {
|
||||
private readonly orderRepository: OrderRepository,
|
||||
private readonly orderItemRepository: OrderItemRepository,
|
||||
private readonly userService: UserService,
|
||||
private readonly adminService: AdminService,
|
||||
private readonly productService: ProductService,
|
||||
private readonly productRepository: ProductRepository,
|
||||
private readonly ticketRepository: TicketRepository,
|
||||
@@ -40,7 +47,7 @@ export class OrderService {
|
||||
private readonly paymentRepository: PaymentRepository,
|
||||
) { }
|
||||
|
||||
async createOrderAsAdmin(adminId: string, dto: CreateOrderAsAdminDto) {
|
||||
async createOrderAsAdmin(adminId: string, dto: CreateOrderParam) {
|
||||
const order = await this.createOrder({ ...dto, adminId })
|
||||
// await this.calculateOrder(order)
|
||||
// this.em.flush()
|
||||
@@ -56,129 +63,11 @@ export class OrderService {
|
||||
|
||||
}
|
||||
|
||||
async createOrder(dto: ICreateOrder) {
|
||||
const { items, userId, attachments, designerId, enableTax, estimatedDays, paymentMethod, status, adminId } = dto
|
||||
|
||||
const user = await this.userService.findById(userId)
|
||||
if (!user) {
|
||||
throw new BadRequestException("User not found!")
|
||||
}
|
||||
async updateOrderAsAdmin(orderId: string, param: UpdateOrderParam) {
|
||||
const order = await this.findOrderOrFail(orderId)
|
||||
|
||||
let admin: null | Admin = null
|
||||
if (adminId) {
|
||||
admin = await this.adminRepository.findOne({ id: adminId })
|
||||
if (!admin) {
|
||||
throw new BadRequestException("Admin not found")
|
||||
}
|
||||
}
|
||||
|
||||
let designer: null | Admin = null
|
||||
if (designerId) {
|
||||
designer = await this.adminRepository.findOne({ id: designerId })
|
||||
if (!designer) {
|
||||
throw new BadRequestException("designer not found")
|
||||
}
|
||||
}
|
||||
|
||||
return this.em.transactional(async (em) => {
|
||||
|
||||
const order = this.orderRepository.create({
|
||||
creator: admin,
|
||||
user,
|
||||
attachments,
|
||||
designer,
|
||||
enableTax,
|
||||
estimatedDays,
|
||||
paymentMethod,
|
||||
status,
|
||||
})
|
||||
|
||||
em.persist(order)
|
||||
|
||||
const productIds = items.map(item => item.productId)
|
||||
|
||||
const products = await this.productRepository.find({
|
||||
id: { $in: productIds }
|
||||
})
|
||||
if (productIds.length !== products.length) {
|
||||
throw new BadRequestException("some products not found")
|
||||
}
|
||||
|
||||
for (const item of items) {
|
||||
await this.persistOrderItem(order, item)
|
||||
}
|
||||
|
||||
// TODO : calculation must be done after create order
|
||||
|
||||
// await this.calculateOrder(order)
|
||||
|
||||
await em.flush()
|
||||
|
||||
return order
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
|
||||
async updateOrder(order: Order, dto: IUpdateOrder) {
|
||||
const { attachments, adminId, designerId, enableTax, estimatedDays, paymentMethod, status, userId } = dto
|
||||
|
||||
|
||||
if (userId) {
|
||||
const user = await this.userService.findById(userId)
|
||||
if (!user) {
|
||||
throw new BadRequestException("User not found!")
|
||||
}
|
||||
order.user = user
|
||||
}
|
||||
|
||||
|
||||
if (adminId != undefined) {
|
||||
const admin = await this.adminRepository.findOne({ id: adminId })
|
||||
if (!admin) {
|
||||
throw new BadRequestException("Admin not found")
|
||||
}
|
||||
order.creator = admin
|
||||
}
|
||||
|
||||
|
||||
if (designerId != undefined) {
|
||||
const designer = await this.adminRepository.findOne({ id: designerId })
|
||||
if (!designer) {
|
||||
throw new BadRequestException("designer not found")
|
||||
}
|
||||
order.designer = designer
|
||||
}
|
||||
|
||||
if (attachments != undefined) {
|
||||
order.attachments = attachments
|
||||
}
|
||||
|
||||
if (enableTax != undefined) {
|
||||
order.enableTax = enableTax
|
||||
}
|
||||
|
||||
if (estimatedDays != undefined) {
|
||||
order.estimatedDays = estimatedDays
|
||||
}
|
||||
|
||||
if (paymentMethod != undefined) {
|
||||
order.paymentMethod = paymentMethod
|
||||
}
|
||||
|
||||
if (status != undefined) {
|
||||
order.status = status
|
||||
}
|
||||
|
||||
await this.em.persistAndFlush(order)
|
||||
|
||||
return order
|
||||
}
|
||||
|
||||
async updateOrderAsAdmin(orderId: string, dto: IUpdateOrder) {
|
||||
const order = await this.findOneOrFail(orderId)
|
||||
|
||||
const updateOrder = await this.updateOrder(order, dto)
|
||||
const updateOrder = await this.updateOrder(order, param)
|
||||
|
||||
// const updateOrder = await this.calculateOrder(order)
|
||||
|
||||
@@ -191,7 +80,7 @@ export class OrderService {
|
||||
|
||||
async addOrderItemAsUser(userId: string, orderId: string, dto: CreateOrderItemAsUserDto) {
|
||||
|
||||
const order = await this.findOneOrFail(orderId)
|
||||
const order = await this.findOrderOrFail(orderId)
|
||||
|
||||
if (order.status !== OrderStatusEnum.CREATED) {
|
||||
throw new BadRequestException(`You can not update when status is ${order.status}`)
|
||||
@@ -201,7 +90,9 @@ export class OrderService {
|
||||
throw new BadRequestException(`This order doest belongs to you!`)
|
||||
}
|
||||
|
||||
const orderItem = this.persistOrderItem(order, dto)
|
||||
const product = await this.productService.findOneOrFail(dto.productId)
|
||||
|
||||
const orderItem = this.createOrderItem(order, product, dto)
|
||||
|
||||
await this.em.flush()
|
||||
|
||||
@@ -210,9 +101,11 @@ export class OrderService {
|
||||
|
||||
async addOrderItemAsAdmin(orderId: string, dto: CreateOrderItemDtoAsAdmin) {
|
||||
|
||||
const order = await this.findOneOrFail(orderId)
|
||||
const order = await this.findOrderOrFail(orderId)
|
||||
|
||||
const orderItem = this.persistOrderItem(order, dto)
|
||||
const product = await this.productService.findOneOrFail(dto.productId)
|
||||
|
||||
const orderItem = this.createOrderItem(order, product, dto)
|
||||
|
||||
await this.em.flush()
|
||||
|
||||
@@ -223,39 +116,10 @@ export class OrderService {
|
||||
return orderItem
|
||||
}
|
||||
|
||||
private async persistOrderItem(order: Order, dto: IAddOrderItem) {
|
||||
const { attributes, description, productId, quantity, attachments, discount, unitPrice } = dto
|
||||
|
||||
const found = order.items.find(it => it.product.id == productId)
|
||||
if (found) {
|
||||
throw new BadRequestException(`Product already exists`)
|
||||
}
|
||||
console.log(productId)
|
||||
const product = await this.productRepository.findOne({ id: productId })
|
||||
if (!product) {
|
||||
throw new BadRequestException(`Product not found`)
|
||||
}
|
||||
const orderItem = this.orderItemRepository.create({
|
||||
order,
|
||||
attributes,
|
||||
description,
|
||||
quantity,
|
||||
attachments,
|
||||
subTotal: 0,
|
||||
discount: discount ?? 0,
|
||||
total: 0,
|
||||
unitPrice: unitPrice ?? 0,
|
||||
product
|
||||
})
|
||||
|
||||
this.em.persist(orderItem)
|
||||
|
||||
return orderItem
|
||||
}
|
||||
|
||||
async updateOrderItemAsUser(userId: string, orderId: string, itemId: string, dto: UpdateOrderItemDtoAsUser) {
|
||||
|
||||
const order = await this.findOneOrFail(orderId)
|
||||
const order = await this.findOrderOrFail(orderId)
|
||||
|
||||
if (order.user.id !== userId) {
|
||||
throw new BadRequestException(`This order doesnt belongs to you`)
|
||||
@@ -272,7 +136,7 @@ export class OrderService {
|
||||
|
||||
async updateOrderItemAsAdmin(orderId: string, itemId: string, dto: UpdateOrderItemDtoAsAdmin) {
|
||||
|
||||
const order = await this.findOneOrFail(orderId)
|
||||
await this.findOrderOrFail(orderId)
|
||||
|
||||
const orderItem = await this.updateOrderItem(itemId, dto)
|
||||
|
||||
@@ -283,57 +147,10 @@ export class OrderService {
|
||||
return orderItem
|
||||
}
|
||||
|
||||
async updateOrderItem(itemId: string, dto: IUpdateOrderItem) {
|
||||
const { attributes, description, productId, quantity, attachments, discount, unitPrice } = dto
|
||||
|
||||
const orderItem = await this.orderItemRepository.findOne({
|
||||
id: itemId
|
||||
})
|
||||
|
||||
if (!orderItem) {
|
||||
throw new BadRequestException(`orderItem not found`)
|
||||
}
|
||||
|
||||
// product is changed
|
||||
if (productId && orderItem.product.id !== productId) {
|
||||
const product = await this.productRepository.findOne({ id: productId })
|
||||
|
||||
if (!product) {
|
||||
throw new BadRequestException(`product not found`)
|
||||
}
|
||||
|
||||
orderItem.product = product
|
||||
}
|
||||
|
||||
if (attributes) {
|
||||
orderItem.attributes = attributes
|
||||
}
|
||||
if (description) {
|
||||
orderItem.description = description
|
||||
}
|
||||
if (quantity) {
|
||||
orderItem.quantity = quantity
|
||||
}
|
||||
|
||||
if (attachments) {
|
||||
orderItem.attachments = attachments
|
||||
}
|
||||
if (discount) {
|
||||
orderItem.discount = discount
|
||||
}
|
||||
|
||||
if (unitPrice) {
|
||||
orderItem.unitPrice = unitPrice
|
||||
}
|
||||
|
||||
await this.em.flush()
|
||||
|
||||
return orderItem
|
||||
}
|
||||
|
||||
async removeOrderItemAsAdmin(orderId: string, itemId: string) {
|
||||
|
||||
const order = await this.findOneOrFail(orderId)
|
||||
const order = await this.findOrderOrFail(orderId)
|
||||
|
||||
await this.removeOrderItem(itemId)
|
||||
|
||||
@@ -346,7 +163,7 @@ export class OrderService {
|
||||
|
||||
async removeOrderItemAsUser(userId: string, orderId: string, itemId: string) {
|
||||
|
||||
const order = await this.findOneOrFail(orderId)
|
||||
const order = await this.findOrderOrFail(orderId)
|
||||
|
||||
if (order.user.id !== userId) {
|
||||
throw new BadRequestException(`this order is not belongs to you`)
|
||||
@@ -361,36 +178,12 @@ export class OrderService {
|
||||
return true
|
||||
}
|
||||
|
||||
async removeOrderItem(itemId: string) {
|
||||
|
||||
const orderItem = await this.orderItemRepository.findOne({
|
||||
id: itemId
|
||||
})
|
||||
|
||||
if (!orderItem) {
|
||||
throw new BadRequestException(`orderItem not found`)
|
||||
}
|
||||
|
||||
await this.em.removeAndFlush(orderItem)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
async findUserOrders(userId: string, dto: FindOrdersDto) {
|
||||
const orders = await this.orderRepository.findAllPaginated({ userId, ...dto })
|
||||
return orders
|
||||
}
|
||||
|
||||
async findOneOrFail(orderId: string) {
|
||||
const order = await this.orderRepository.findOne({ id: orderId },
|
||||
{ populate: ['items', 'items.product', 'payments'] })
|
||||
if (!order) {
|
||||
throw new BadRequestException('Order not found')
|
||||
}
|
||||
return order
|
||||
}
|
||||
|
||||
// async calculateOrder(inputOrder?: Order, orderId?: string) {
|
||||
// let order: undefined | Order = inputOrder
|
||||
|
||||
@@ -471,6 +264,219 @@ export class OrderService {
|
||||
|
||||
}
|
||||
|
||||
|
||||
async removeOrderAsUser(orderId: string) {
|
||||
const order = await this.orderRepository.findOne({ id: orderId })
|
||||
if (!order) {
|
||||
throw new BadRequestException("Order not found")
|
||||
}
|
||||
|
||||
if (![OrderStatusEnum.CREATED].includes(order.status)) {
|
||||
throw new BadRequestException("Order can not be deleted")
|
||||
}
|
||||
|
||||
return this.hardDeleteOrder(orderId)
|
||||
}
|
||||
|
||||
async updateStatus(orderId: string, newStatus: OrderStatusEnum) {
|
||||
|
||||
const order = await this.findOrderOrFail(orderId)
|
||||
|
||||
order.status = newStatus
|
||||
|
||||
await this.em.flush()
|
||||
|
||||
return order
|
||||
}
|
||||
|
||||
async createInvoice(orderId: string) {
|
||||
const order = await this.findOrderOrFail(orderId)
|
||||
await this.updateStatus(orderId, OrderStatusEnum.INVOICED)
|
||||
// await this.calculateOrder(order)
|
||||
await this.em.flush()
|
||||
}
|
||||
|
||||
// ==================== Entity Methods ====================
|
||||
|
||||
private async createOrderItem(order: Order, product: Product, dto: CreateOrderItemParam, em?: EntityManager) {
|
||||
const { attributes, description, quantity, attachments, discount, unitPrice } = dto
|
||||
const eM = em ?? this.em
|
||||
return eM.create(
|
||||
OrderItem,
|
||||
{
|
||||
order,
|
||||
attributes,
|
||||
description,
|
||||
quantity,
|
||||
attachments,
|
||||
discount: discount ?? undefined,
|
||||
unitPrice: unitPrice ?? undefined,
|
||||
product
|
||||
})
|
||||
}
|
||||
|
||||
// ==================== Core Logic ====================
|
||||
|
||||
async createOrder(dto: CreateOrderParam) {
|
||||
const { items, userId, attachments, designerId, enableTax,
|
||||
estimatedDays, paymentMethod, status, adminId } = dto
|
||||
|
||||
// Validate and fetch all required entities
|
||||
const user = await this.userService.findOrFail(userId)
|
||||
const admin = adminId ? await this.adminService.findOrFail(adminId) : undefined
|
||||
const designer = designerId ? await this.adminService.findOrFail(designerId) : undefined
|
||||
const products = await this.productService.findProductsByIds(items.map(item => item.productId))
|
||||
|
||||
|
||||
return this.em.transactional(async (em) => {
|
||||
|
||||
const order = this.em.create(Order, {
|
||||
creator: admin,
|
||||
user,
|
||||
attachments,
|
||||
designer,
|
||||
enableTax,
|
||||
estimatedDays,
|
||||
paymentMethod,
|
||||
status,
|
||||
})
|
||||
|
||||
em.persist(order)
|
||||
|
||||
for (const item of items) {
|
||||
const product = products.find(p => Number(p.id) === item.productId)
|
||||
|
||||
if (!product) {
|
||||
throw new BadRequestException("Product not found!")
|
||||
}
|
||||
|
||||
const orderItem = await this.createOrderItem(order, product, item, em)
|
||||
|
||||
order.items.add(orderItem)
|
||||
}
|
||||
|
||||
// TODO : calculation must be done after create order
|
||||
|
||||
// await this.calculateOrder(order)
|
||||
|
||||
await em.flush()
|
||||
|
||||
return order
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
|
||||
async updateOrder(order: Order, param: UpdateOrderParam) {
|
||||
const { attachments, adminId, designerId, enableTax,
|
||||
estimatedDays, paymentMethod, status, userId } = param
|
||||
|
||||
|
||||
if (userId) {
|
||||
const user = await this.userService.findOrFail(userId)
|
||||
order.user = user
|
||||
}
|
||||
|
||||
|
||||
if (adminId != undefined) {
|
||||
const admin = await this.adminService.findOrFail(adminId)
|
||||
order.creator = admin
|
||||
}
|
||||
|
||||
|
||||
if (designerId != undefined) {
|
||||
const designer = await this.adminService.findOrFail(designerId)
|
||||
order.designer = designer
|
||||
}
|
||||
|
||||
if (attachments != undefined) {
|
||||
order.attachments = attachments
|
||||
}
|
||||
|
||||
if (enableTax != undefined) {
|
||||
order.enableTax = enableTax
|
||||
}
|
||||
|
||||
if (estimatedDays != undefined) {
|
||||
order.estimatedDays = estimatedDays
|
||||
}
|
||||
|
||||
if (paymentMethod != undefined) {
|
||||
order.paymentMethod = paymentMethod
|
||||
}
|
||||
|
||||
if (status != undefined) {
|
||||
order.status = status
|
||||
}
|
||||
|
||||
await this.em.persistAndFlush(order)
|
||||
|
||||
return order
|
||||
}
|
||||
|
||||
async updateOrderItem(itemId: string, dto: UpdateOrderItem) {
|
||||
const { attributes, description, productId, quantity, attachments, discount, unitPrice } = dto
|
||||
|
||||
const orderItem = await this.orderItemRepository.findOne({
|
||||
id: itemId
|
||||
})
|
||||
|
||||
if (!orderItem) {
|
||||
throw new BadRequestException(`orderItem not found`)
|
||||
}
|
||||
|
||||
// product is changed
|
||||
if (productId && Number(orderItem.product.id) !== productId) {
|
||||
const product = await this.productRepository.findOne({ id: productId })
|
||||
|
||||
if (!product) {
|
||||
throw new BadRequestException(`product not found`)
|
||||
}
|
||||
|
||||
orderItem.product = product
|
||||
}
|
||||
|
||||
if (attributes) {
|
||||
orderItem.attributes = attributes
|
||||
}
|
||||
if (description) {
|
||||
orderItem.description = description
|
||||
}
|
||||
if (quantity) {
|
||||
orderItem.quantity = quantity
|
||||
}
|
||||
|
||||
if (attachments) {
|
||||
orderItem.attachments = attachments
|
||||
}
|
||||
if (discount) {
|
||||
orderItem.discount = discount
|
||||
}
|
||||
|
||||
if (unitPrice) {
|
||||
orderItem.unitPrice = unitPrice
|
||||
}
|
||||
|
||||
await this.em.flush()
|
||||
|
||||
return orderItem
|
||||
}
|
||||
|
||||
async removeOrderItem(itemId: string) {
|
||||
|
||||
const orderItem = await this.orderItemRepository.findOne({
|
||||
id: itemId
|
||||
})
|
||||
|
||||
if (!orderItem) {
|
||||
throw new BadRequestException(`orderItem not found`)
|
||||
}
|
||||
|
||||
await this.em.removeAndFlush(orderItem)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
async hardDeleteOrder(orderId: string) {
|
||||
const order = await this.orderRepository.findOne({ id: orderId })
|
||||
if (!order) {
|
||||
@@ -493,36 +499,16 @@ export class OrderService {
|
||||
|
||||
}
|
||||
|
||||
async removeOrderAsUser(orderId: string) {
|
||||
const order = await this.orderRepository.findOne({ id: orderId })
|
||||
// ==================== Helper Methods ====================
|
||||
|
||||
async findOrderOrFail(orderId: string) {
|
||||
const order = await this.orderRepository.findOne({ id: orderId },
|
||||
{ populate: ['items', 'items.product', 'payments'] })
|
||||
if (!order) {
|
||||
throw new BadRequestException("Order not found")
|
||||
throw new BadRequestException('Order not found')
|
||||
}
|
||||
|
||||
if (![OrderStatusEnum.CREATED].includes(order.status)) {
|
||||
throw new BadRequestException("Order can not be deleted")
|
||||
}
|
||||
|
||||
return this.hardDeleteOrder(orderId)
|
||||
}
|
||||
|
||||
async updateStatus(orderId: string, newStatus: OrderStatusEnum) {
|
||||
const order = await this.orderRepository.findOne({ id: orderId })
|
||||
if (!order) {
|
||||
throw new BadRequestException("Order not found")
|
||||
}
|
||||
|
||||
order.status = newStatus
|
||||
|
||||
await this.em.flush()
|
||||
|
||||
return order
|
||||
}
|
||||
|
||||
async createInvoice(orderId: string) {
|
||||
const order = await this.findOneOrFail(orderId)
|
||||
await this.updateStatus(orderId, OrderStatusEnum.INVOICED)
|
||||
// await this.calculateOrder(order)
|
||||
await this.em.flush()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ export class PaymentService {
|
||||
private async loadAndValidateOrder(orderId: string, dto: PayOrderDto, adminId?: string): Promise<OrderPaymentContext> {
|
||||
const { amount, method, attachments, description, gateway } = dto
|
||||
|
||||
const order = await this.orderService.findOneOrFail(orderId)
|
||||
const order = await this.orderService.findOrderOrFail(orderId)
|
||||
|
||||
if (!order) {
|
||||
throw new NotFoundException(OrderMessage.NOT_FOUND);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||
import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common';
|
||||
import { CreateproductDto } from '../dto/create-product.dto';
|
||||
import { FindproductsDto } from '../dto/find-products.dto';
|
||||
import { ProductRepository } from '../repositories/product.repository';
|
||||
@@ -140,4 +140,19 @@ export class ProductService {
|
||||
|
||||
}
|
||||
|
||||
async findProductsByIds(productIds: number[]) {
|
||||
const products = await this.productRepository.find({
|
||||
id: { $in: productIds }
|
||||
})
|
||||
if (productIds.length !== products.length) {
|
||||
throw new BadRequestException("some products not found")
|
||||
}
|
||||
return products
|
||||
}
|
||||
|
||||
async findOneOrFail(productId: number) {
|
||||
const product = await this.productRepository.findOne({ id: productId });
|
||||
if (!product) throw new NotFoundException(productMessage.NOT_FOUND);
|
||||
return product;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,5 +68,12 @@ export class UserService {
|
||||
return this.userRepository.findAllPaginated(dto)
|
||||
}
|
||||
|
||||
async findOrFail(userId: string) {
|
||||
const user = await this.findById(userId)
|
||||
if (!user) {
|
||||
throw new BadRequestException("User not found!")
|
||||
}
|
||||
return user
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user