This commit is contained in:
2026-02-18 22:15:50 +03:30
parent 84270ccb46
commit 3afcd2e4b3
8 changed files with 135 additions and 19 deletions
@@ -37,7 +37,7 @@ export enum OrderItemStatusEnum {
CANCELED = 'canceled',
}
export interface IField { fieldId: number, value: string }
export interface IAttachment { type: string, url: string }
+59 -1
View File
@@ -1 +1,59 @@
export class CreateRequestDto {}
import {
IsString,
IsInt,
IsArray,
IsNumber,
IsNotEmpty,
ArrayMinSize,
IsOptional,
} from 'class-validator';
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import { IAttachment, IField } from '../interface/request.interface';
export class CreateRequestItemDto {
@IsString()
@IsNotEmpty()
@ApiProperty()
productId: string;
@IsNumber()
@ApiProperty()
quantity: number;
@ApiPropertyOptional({ type: 'array', items: { type: 'object', properties: { fieldId: { type: 'number' }, value: { type: 'string' } } } })
@IsOptional()
@IsArray()
attributes?: IField[];
@ApiPropertyOptional()
@IsOptional()
@IsString()
description?: string;
@ApiPropertyOptional({ type: 'array', items: { type: 'object', properties: { type: { type: 'string' }, url: { type: 'string' } } } })
@IsOptional()
@IsArray()
attachments?: IAttachment[];
}
export class CreateRequestDto {
@IsArray()
@ApiProperty({
isArray: true,
type: [CreateRequestItemDto],
example: [
{
productId: '01ARZ3NDEKTSV4RRFFQ69G5FAV',
quantity: 100,
attributes: [{ fieldId: 1, value: 'blue' }],
attachments: [{ url: '', type: 'image' }],
description: 'توضیحات',
},
],
})
@IsNotEmpty()
@ArrayMinSize(1, { message: 'At least one item is required' })
@Type(() => CreateRequestItemDto)
items: CreateRequestItemDto[];
}
@@ -2,9 +2,8 @@ import { Entity, ManyToOne, OptionalProps, Property } from '@mikro-orm/core';
import { Product } from 'src/modules/product/entities/product.entity';
import { BaseEntity } from 'src/common/entities/base.entity';
import { Request } from './request.entity';
import { IAttachment } from '../interface/request.interface';
import { IAttachment, IField } from '../interface/request.interface';
@Entity({ tableName: 'request_items' })
export class RequestItem extends BaseEntity {
[OptionalProps]?: 'createdAt' | 'deletedAt';
@@ -12,10 +11,12 @@ export class RequestItem extends BaseEntity {
@ManyToOne(() => Product)
product!: Product;
@Property({ type: 'json', nullable: true })
attributes?: IField[]
@ManyToOne(() => Request)
request!: Request;
@Property({ type: 'int' })
quantity!: number;
@@ -19,7 +19,7 @@ import { RequestStatusEnum } from '../enum/request';
@Entity({ tableName: 'requests' })
@Index({ properties: ['user'] })
export class Request extends BaseEntity {
[OptionalProps]?: 'createdAt' | 'deletedAt'
[OptionalProps]?: 'createdAt' | 'deletedAt'|'requestNumber'
@PrimaryKey({ type: 'string', columnType: 'char(26)' })
id: string = ulid()
@@ -1 +1,3 @@
export interface IAttachment { type: string, url: string }
export interface IField { fieldId: number, value: string }
+17 -10
View File
@@ -1,33 +1,40 @@
import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common';
import { Controller, Get, Post, Body, Patch, Param, Delete, UseGuards } from '@nestjs/common';
import { RequestService } from './request.service';
import { CreateRequestDto } from './dto/create-request.dto';
import { UpdateRequestDto } from './dto/update-request.dto';
import { AuthGuard } from '../auth/guards/auth.guard';
import { UserId } from 'src/common/decorators';
@Controller('request')
@Controller()
export class RequestController {
constructor(private readonly requestService: RequestService) {}
constructor(private readonly requestService: RequestService) { }
@Post()
create(@Body() createRequestDto: CreateRequestDto) {
return this.requestService.create(createRequestDto);
@Post('public/request')
@UseGuards(AuthGuard)
create(@Body() dto: CreateRequestDto, @UserId() userId: string) {
return this.requestService.create(dto, userId);
}
@Get()
@Get('public/request')
@UseGuards(AuthGuard)
findAll() {
return this.requestService.findAll();
}
@Get(':id')
@Get('public/request:id')
@UseGuards(AuthGuard)
findOne(@Param('id') id: string) {
return this.requestService.findOne(+id);
}
@Patch(':id')
@Patch('public/request:id')
@UseGuards(AuthGuard)
update(@Param('id') id: string, @Body() updateRequestDto: UpdateRequestDto) {
return this.requestService.update(+id, updateRequestDto);
}
@Delete(':id')
@Delete('public/request:id')
@UseGuards(AuthGuard)
remove(@Param('id') id: string) {
return this.requestService.remove(+id);
}
+10
View File
@@ -1,8 +1,18 @@
import { Module } from '@nestjs/common';
import { MikroOrmModule } from '@mikro-orm/nestjs';
import { RequestService } from './request.service';
import { RequestController } from './request.controller';
import { Request } from './entities/request.entity';
import { RequestItem } from './entities/request-item.entity';
import { UserModule } from '../user/user.module';
import { ProductModule } from '../product/product.module';
@Module({
imports: [
MikroOrmModule.forFeature([Request, RequestItem]),
UserModule,
ProductModule,
],
controllers: [RequestController],
providers: [RequestService],
})
+40 -2
View File
@@ -1,11 +1,49 @@
import { Injectable } from '@nestjs/common';
import { EntityManager } from '@mikro-orm/postgresql';
import { CreateRequestDto } from './dto/create-request.dto';
import { UpdateRequestDto } from './dto/update-request.dto';
import { Request } from './entities/request.entity';
import { RequestItem } from './entities/request-item.entity';
import { RequestStatusEnum } from './enum/request';
import { UserService } from '../user/providers/user.service';
import { ProductService } from '../product/providers/product.service';
@Injectable()
export class RequestService {
create(createRequestDto: CreateRequestDto) {
return 'This action adds a new request';
constructor(
private readonly em: EntityManager,
private readonly userService: UserService,
private readonly productService: ProductService,
) {}
async create(createRequestDto: CreateRequestDto, userId: string) {
const { items } = createRequestDto;
const user = await this.userService.findOrFail(userId);
return this.em.transactional(async (em) => {
const request = em.create(Request, {
user,
status: RequestStatusEnum.PENDING,
});
em.persist(request);
for (const item of items) {
const product = await this.productService.findOneOrFail(item.productId);
const requestItem = em.create(RequestItem, {
request,
product,
quantity: item.quantity,
attributes: item.attributes,
description: item.description,
attachments: item.attachments,
});
request.items.add(requestItem);
}
await em.flush();
return request;
});
}
findAll() {