update order print
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { Controller, Get, Post, Param, UseGuards, Patch, Query, Body, Delete } from '@nestjs/common';
|
||||
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
|
||||
import { ApiTags, ApiOperation, ApiBearerAuth, ApiOkResponse } from '@nestjs/swagger';
|
||||
import { OrderService } from '../providers/order.service';
|
||||
import { AuthGuard } from '../../auth/guards/auth.guard';
|
||||
import { UserId } from '../../../common/decorators/user-id.decorator';
|
||||
@@ -108,6 +108,7 @@ export class OrderController {
|
||||
@UseGuards(AdminAuthGuard)
|
||||
@Permissions(PermissionEnum.CREATE_PRINT)
|
||||
@ApiOperation({ summary: 'Create order print' })
|
||||
@ApiOkResponse({ description: 'Order print created or updated' })
|
||||
createPrint(@Param('orderId') orderId: string, @Body() body: CreateOrderPrintDto) {
|
||||
return this.orderService.createPrint(orderId, body);
|
||||
}
|
||||
@@ -116,6 +117,7 @@ export class OrderController {
|
||||
@UseGuards(AdminAuthGuard)
|
||||
@Permissions(PermissionEnum.VIEW_PRINT)
|
||||
@ApiOperation({ summary: 'Get order print' })
|
||||
@ApiOkResponse({ description: 'Order print details' })
|
||||
getPrint(@Param('orderId') orderId: string) {
|
||||
return this.orderService.getPrint(orderId);
|
||||
}
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
import {
|
||||
IsArray,
|
||||
} from 'class-validator';
|
||||
import { IsArray, ValidateNested } from 'class-validator';
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IField } from 'src/modules/request/interface/request.interface';
|
||||
|
||||
import { Type } from 'class-transformer';
|
||||
import { OrderPrintValueDto } from './order-print-value.dto';
|
||||
|
||||
export class CreateOrderPrintDto {
|
||||
|
||||
@ApiProperty({
|
||||
example: [
|
||||
{ fieldId: '', value: '' }
|
||||
]
|
||||
})
|
||||
@IsArray()
|
||||
fields: IField[];
|
||||
|
||||
@ApiProperty({
|
||||
type: [OrderPrintValueDto],
|
||||
example: [{ fieldId: '', value: '' }],
|
||||
})
|
||||
@IsArray()
|
||||
@ValidateNested({ each: true })
|
||||
@Type(() => OrderPrintValueDto)
|
||||
fields: OrderPrintValueDto[];
|
||||
}
|
||||
|
||||
|
||||
@@ -59,6 +59,21 @@ export class FindOrdersDto {
|
||||
@IsDateString()
|
||||
to?: string;
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
categoryId?: string;
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
userId?: string;
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
designerId?: string;
|
||||
|
||||
@ApiPropertyOptional({ default: 'createdAt' })
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import { IsNotEmpty, IsString } from 'class-validator';
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class OrderPrintValueDto {
|
||||
@ApiProperty({ example: '01HXXXXXXXXXXXXXXXXXXXXX' })
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
fieldId: string;
|
||||
|
||||
@ApiProperty({ example: 'some value' })
|
||||
@IsString()
|
||||
value: string;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import { Entity, Index, ManyToOne, OptionalProps, Property } from '@mikro-orm/core';
|
||||
import { BaseEntity } from 'src/common/entities/base.entity';
|
||||
import { Field } from 'src/modules/form-builder/entities/field.entity';
|
||||
import { OrderPrint } from './order-print.entity';
|
||||
|
||||
@Entity({ tableName: 'order_print_values' })
|
||||
@Index({ properties: ['orderPrint'] })
|
||||
export class OrderPrintValue extends BaseEntity {
|
||||
[OptionalProps]?: 'createdAt' | 'deletedAt';
|
||||
|
||||
@ManyToOne(() => OrderPrint)
|
||||
orderPrint!: OrderPrint;
|
||||
|
||||
@ManyToOne(() => Field)
|
||||
field!: Field;
|
||||
|
||||
@Property({ type: 'text' })
|
||||
value!: string;
|
||||
}
|
||||
@@ -1,18 +1,15 @@
|
||||
import { Entity, Property, OptionalProps, OneToOne } from '@mikro-orm/core';
|
||||
import { Collection, Entity, OneToMany, OptionalProps, OneToOne } from '@mikro-orm/core';
|
||||
import { BaseEntity } from 'src/common/entities/base.entity';
|
||||
import { IField } from 'src/modules/request/interface/request.interface';
|
||||
import { Order } from './order.entity';
|
||||
|
||||
import { OrderPrintValue } from './order-print-value.entity';
|
||||
|
||||
@Entity({ tableName: 'order_prints' })
|
||||
export class OrderPrint extends BaseEntity {
|
||||
[OptionalProps]?: 'createdAt' | 'deletedAt'
|
||||
|
||||
@Property({ type: 'json', nullable: true })
|
||||
fileds?: IField[]
|
||||
[OptionalProps]?: 'createdAt' | 'deletedAt';
|
||||
|
||||
@OneToMany(() => OrderPrintValue, (value) => value.orderPrint, { orphanRemoval: true })
|
||||
values = new Collection<OrderPrintValue>(this);
|
||||
|
||||
@OneToOne(() => Order, (order) => order.print, { mappedBy: 'print' })
|
||||
order!: Order
|
||||
|
||||
order!: Order;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,18 @@ export enum OrderStatusEnum {
|
||||
|
||||
export interface IAttachment { type: string, url: string }
|
||||
|
||||
export interface IOrderPrintValue {
|
||||
fieldId: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface IOrderPrintResponse {
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
deletedAt?: Date;
|
||||
fileds: IOrderPrintValue[];
|
||||
}
|
||||
|
||||
|
||||
export interface CreateOrder {
|
||||
userId: string
|
||||
|
||||
@@ -4,6 +4,7 @@ import { OrderService } from './providers/order.service';
|
||||
import { OrderController } from './controllers/order.controller';
|
||||
import { Order } from './entities/order.entity';
|
||||
import { OrderPrint } from './entities/order-print.entity';
|
||||
import { OrderPrintValue } from './entities/order-print-value.entity';
|
||||
import { AuthModule } from '../auth/auth.module';
|
||||
import { PaymentModule } from '../payment/payments.module';
|
||||
import { JwtModule } from '@nestjs/jwt';
|
||||
@@ -17,10 +18,11 @@ import { UtilsModule } from '../util/utils.module';
|
||||
import { ProductModule } from '../product/product.module';
|
||||
import { ChatModule } from '../chat/chat.module';
|
||||
import { OrderPrintRepository } from './repositories/order-print.repository';
|
||||
import { OrderPrintValueRepository } from './repositories/order-print-value.repository';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
MikroOrmModule.forFeature([Order, OrderPrint]),
|
||||
MikroOrmModule.forFeature([Order, OrderPrint, OrderPrintValue]),
|
||||
AuthModule,
|
||||
forwardRef(() => PaymentModule),
|
||||
JwtModule,
|
||||
@@ -33,7 +35,7 @@ import { OrderPrintRepository } from './repositories/order-print.repository';
|
||||
],
|
||||
controllers: [OrderController],
|
||||
providers: [OrderService, OrderRepository, OrderListeners,
|
||||
OrdersCrone, OrderPrintRepository],
|
||||
OrdersCrone, OrderPrintRepository, OrderPrintValueRepository],
|
||||
exports: [OrderRepository, OrderService],
|
||||
})
|
||||
export class OrderModule { }
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
CreateOrderAsAdminDto,
|
||||
} from '../dto/create-order.dto';
|
||||
import { UserService } from 'src/modules/user/providers/user.service';
|
||||
import { OrderStatusEnum } from '../interface/order.interface';
|
||||
import { OrderStatusEnum, IOrderPrintResponse } from '../interface/order.interface';
|
||||
import { Order } from '../entities/order.entity';
|
||||
import { AdminService } from 'src/modules/admin/providers/admin.service';
|
||||
import { UpdateOrderAsAdminDto } from '../dto/update-order.dto';
|
||||
@@ -19,8 +19,11 @@ import { InvoiceItem } from 'src/modules/invoice/entities/invoice-item.entity';
|
||||
import { PaginatedResult } from 'src/common/interfaces/pagination.interface';
|
||||
import { UpdateStatusDto } from '../dto/update-status.dto';
|
||||
import { CreateOrderPrintDto } from '../dto/create-order-print.dto';
|
||||
import { OrderPrintValueDto } from '../dto/order-print-value.dto';
|
||||
import { OrderPrint } from '../entities/order-print.entity';
|
||||
import { OrderPrintValue } from '../entities/order-print-value.entity';
|
||||
import { OrderPrintRepository } from '../repositories/order-print.repository';
|
||||
import { Field } from 'src/modules/form-builder/entities/field.entity';
|
||||
import { Request } from 'src/modules/request/entities/request.entity';
|
||||
import { Invoice } from 'src/modules/invoice/entities/invoice.entity';
|
||||
import { OrderCreatedEvent } from '../events/order.events';
|
||||
@@ -44,7 +47,7 @@ export class OrderService {
|
||||
let user: User | null = null
|
||||
|
||||
if (dto.invoiceItemId) {
|
||||
invoiceItem = await this.em.findOne(InvoiceItem, { id: dto.invoiceItemId }, { populate: ['invoice', 'invoice.user'] });
|
||||
invoiceItem = await this.em.findOne(InvoiceItem, { id: dto.invoiceItemId }, { populate: ['invoice', 'invoice.user', 'product'] });
|
||||
if (!invoiceItem) {
|
||||
throw new NotFoundException(`Invoice item with ID ${dto.invoiceItemId} not found.`);
|
||||
}
|
||||
@@ -86,6 +89,8 @@ export class OrderService {
|
||||
if (!product) {
|
||||
throw new NotFoundException(`Product with ID ${dto.productId} not found.`);
|
||||
}
|
||||
} else if (invoiceItem?.product) {
|
||||
product = invoiceItem.product;
|
||||
}
|
||||
|
||||
let designer = null;
|
||||
@@ -233,29 +238,74 @@ export class OrderService {
|
||||
return order
|
||||
}
|
||||
|
||||
async createPrint(orderId: string, dto: CreateOrderPrintDto): Promise<OrderPrint> {
|
||||
const order = await this.findOrderOrFail(orderId);
|
||||
|
||||
if (order.print) {
|
||||
order.print.fileds = dto.fields;
|
||||
await this.em.flush();
|
||||
return order.print;
|
||||
async createPrint(orderId: string, dto: CreateOrderPrintDto): Promise<IOrderPrintResponse> {
|
||||
const order = await this.em.findOne(Order, { id: orderId }, { populate: ['print'] });
|
||||
if (!order) {
|
||||
throw new NotFoundException(`Order with ID ${orderId} not found.`);
|
||||
}
|
||||
|
||||
const print = this.em.create(OrderPrint, {
|
||||
order,
|
||||
fileds: dto.fields,
|
||||
});
|
||||
const fieldMap = await this.resolvePrintFields(dto.fields);
|
||||
|
||||
let print = order.print;
|
||||
if (print) {
|
||||
await this.em.populate(print, ['values']);
|
||||
print.values.removeAll();
|
||||
} else {
|
||||
print = this.em.create(OrderPrint, { order });
|
||||
}
|
||||
|
||||
this.assignPrintValues(print, dto.fields, fieldMap);
|
||||
await this.em.persistAndFlush(print);
|
||||
return print;
|
||||
await this.em.populate(print, ['values', 'values.field']);
|
||||
return this.serializeOrderPrint(print);
|
||||
}
|
||||
|
||||
async getPrint(orderId: string) {
|
||||
const orderPrint = await this.orderPrintRepository.findOne({ order: { id: orderId } });
|
||||
async getPrint(orderId: string): Promise<IOrderPrintResponse> {
|
||||
const orderPrint = await this.orderPrintRepository.findOne(
|
||||
{ order: { id: orderId } },
|
||||
{ populate: ['values', 'values.field'] },
|
||||
);
|
||||
if (!orderPrint) {
|
||||
throw new NotFoundException(`Print with ID ${orderId} not found.`);
|
||||
}
|
||||
return orderPrint;
|
||||
return this.serializeOrderPrint(orderPrint);
|
||||
}
|
||||
|
||||
private serializeOrderPrint(print: OrderPrint): IOrderPrintResponse {
|
||||
return {
|
||||
id: print.id,
|
||||
createdAt: print.createdAt,
|
||||
deletedAt: print.deletedAt,
|
||||
fileds: print.values.getItems().map((item) => ({
|
||||
fieldId: item.field.id,
|
||||
value: item.value,
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
private async resolvePrintFields(dtoFields: OrderPrintValueDto[]): Promise<Map<string, Field>> {
|
||||
const fieldIds = [...new Set(dtoFields.map((field) => field.fieldId))];
|
||||
const fields = await this.em.find(Field, { id: { $in: fieldIds } });
|
||||
if (fields.length !== fieldIds.length) {
|
||||
throw new NotFoundException('One or more fields not found.');
|
||||
}
|
||||
return new Map(fields.map((field) => [field.id, field]));
|
||||
}
|
||||
|
||||
private assignPrintValues(
|
||||
print: OrderPrint,
|
||||
dtoFields: OrderPrintValueDto[],
|
||||
fieldMap: Map<string, Field>,
|
||||
): void {
|
||||
for (const dtoField of dtoFields) {
|
||||
print.values.add(
|
||||
this.em.create(OrderPrintValue, {
|
||||
orderPrint: print,
|
||||
field: fieldMap.get(dtoField.fieldId)!,
|
||||
value: dtoField.value,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------Hrlper Methods -----------
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { EntityManager, EntityRepository } from '@mikro-orm/postgresql';
|
||||
import { OrderPrintValue } from '../entities/order-print-value.entity';
|
||||
|
||||
@Injectable()
|
||||
export class OrderPrintValueRepository extends EntityRepository<OrderPrintValue> {
|
||||
constructor(readonly em: EntityManager) {
|
||||
super(em, OrderPrintValue);
|
||||
}
|
||||
}
|
||||
@@ -7,11 +7,9 @@ import { OrderStatusEnum } from '../interface/order.interface';
|
||||
import { FindOrdersDto } from '../dto/find-orders.dto';
|
||||
|
||||
|
||||
class FindOrdersOpts extends FindOrdersDto {
|
||||
userId?: string;
|
||||
adminId?: string;
|
||||
designerId?: string
|
||||
};
|
||||
// class FindOrdersOpts extends FindOrdersDto {
|
||||
// adminId?: string;
|
||||
// };
|
||||
|
||||
@Injectable()
|
||||
export class OrderRepository extends EntityRepository<Order> {
|
||||
@@ -19,7 +17,7 @@ export class OrderRepository extends EntityRepository<Order> {
|
||||
super(em, Order);
|
||||
}
|
||||
|
||||
async findAllPaginated(opts: FindOrdersOpts): Promise<PaginatedResult<Order>> {
|
||||
async findAllPaginated(opts: FindOrdersDto): Promise<PaginatedResult<Order>> {
|
||||
const {
|
||||
page = 1,
|
||||
limit = 10,
|
||||
@@ -30,8 +28,8 @@ export class OrderRepository extends EntityRepository<Order> {
|
||||
userId,
|
||||
from,
|
||||
to,
|
||||
categoryId,
|
||||
designerId,
|
||||
adminId
|
||||
} = opts;
|
||||
|
||||
const offset = (page - 1) * limit;
|
||||
@@ -63,6 +61,10 @@ export class OrderRepository extends EntityRepository<Order> {
|
||||
where.designer = { id: designerId };
|
||||
}
|
||||
|
||||
if (categoryId) {
|
||||
where.type = { id: categoryId };
|
||||
}
|
||||
|
||||
// Filter by date range
|
||||
if (from || to) {
|
||||
where.createdAt = {};
|
||||
|
||||
Reference in New Issue
Block a user