@@ -0,0 +1,13 @@
|
|||||||
|
import { Migration } from '@mikro-orm/migrations';
|
||||||
|
|
||||||
|
export class Migration20260626120000 extends Migration {
|
||||||
|
|
||||||
|
override async up(): Promise<void> {
|
||||||
|
this.addSql(`alter table "requests" drop column if exists "status";`);
|
||||||
|
}
|
||||||
|
|
||||||
|
override async down(): Promise<void> {
|
||||||
|
this.addSql(`alter table "requests" add column "status" text check ("status" in ('pending', 'invoiced')) not null default 'pending';`);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -11,8 +11,6 @@ import { User } from '../user/entities/user.entity';
|
|||||||
import { ProductService } from '../product/providers/product.service';
|
import { ProductService } from '../product/providers/product.service';
|
||||||
import { InvoiceRepository } from './repositories/invoice.repository';
|
import { InvoiceRepository } from './repositories/invoice.repository';
|
||||||
import { InvoiceCreatedEvent } from './events/invoice.events';
|
import { InvoiceCreatedEvent } from './events/invoice.events';
|
||||||
import { RequestStatusEnum } from '../request/enum/request';
|
|
||||||
|
|
||||||
const TAX_RATE = 0.1;
|
const TAX_RATE = 0.1;
|
||||||
|
|
||||||
type ResolvedItemDiscount = {
|
type ResolvedItemDiscount = {
|
||||||
@@ -145,7 +143,7 @@ export class InvoiceService {
|
|||||||
if (!requestEntity) {
|
if (!requestEntity) {
|
||||||
throw new NotFoundException('Request not found');
|
throw new NotFoundException('Request not found');
|
||||||
}
|
}
|
||||||
requestEntity.status = RequestStatusEnum.INVOICED;
|
requestEntity.deletedAt = new Date();
|
||||||
}
|
}
|
||||||
|
|
||||||
await em.flush();
|
await em.flush();
|
||||||
|
|||||||
@@ -4,13 +4,10 @@ import {
|
|||||||
IsNumber,
|
IsNumber,
|
||||||
Min,
|
Min,
|
||||||
IsIn,
|
IsIn,
|
||||||
IsEnum,
|
|
||||||
IsDateString,
|
IsDateString,
|
||||||
IsArray,
|
|
||||||
} from 'class-validator';
|
} from 'class-validator';
|
||||||
import { Type, Transform } from 'class-transformer';
|
import { Type } from 'class-transformer';
|
||||||
import { ApiPropertyOptional } from '@nestjs/swagger';
|
import { ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
import { RequestStatusEnum } from '../enum/request';
|
|
||||||
|
|
||||||
const sortOrderOptions = ['asc', 'desc'] as const;
|
const sortOrderOptions = ['asc', 'desc'] as const;
|
||||||
type SortOrder = (typeof sortOrderOptions)[number];
|
type SortOrder = (typeof sortOrderOptions)[number];
|
||||||
@@ -30,17 +27,6 @@ export class FindRequestsDto {
|
|||||||
@Min(1)
|
@Min(1)
|
||||||
limit: number = 10;
|
limit: number = 10;
|
||||||
|
|
||||||
@ApiPropertyOptional({
|
|
||||||
description: 'Filter by request statuses',
|
|
||||||
enum: RequestStatusEnum,
|
|
||||||
isArray: true,
|
|
||||||
})
|
|
||||||
@IsOptional()
|
|
||||||
@Transform(({ value }) => (Array.isArray(value) ? value : value?.split(',')))
|
|
||||||
@IsArray()
|
|
||||||
@IsEnum(RequestStatusEnum, { each: true })
|
|
||||||
statuses?: RequestStatusEnum[];
|
|
||||||
|
|
||||||
@ApiPropertyOptional({
|
@ApiPropertyOptional({
|
||||||
description: 'Search by request number or user info',
|
description: 'Search by request number or user info',
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import {
|
|||||||
Property,
|
Property,
|
||||||
Collection,
|
Collection,
|
||||||
Cascade,
|
Cascade,
|
||||||
Enum,
|
|
||||||
PrimaryKey,
|
PrimaryKey,
|
||||||
OptionalProps,
|
OptionalProps,
|
||||||
} from '@mikro-orm/core';
|
} from '@mikro-orm/core';
|
||||||
@@ -14,7 +13,6 @@ import { User } from '../../user/entities/user.entity';
|
|||||||
import { ulid } from 'ulid';
|
import { ulid } from 'ulid';
|
||||||
import { BaseEntity } from 'src/common/entities/base.entity';
|
import { BaseEntity } from 'src/common/entities/base.entity';
|
||||||
import { RequestItem } from './request-item.entity';
|
import { RequestItem } from './request-item.entity';
|
||||||
import { RequestStatusEnum } from '../enum/request';
|
|
||||||
import { Invoice } from 'src/modules/invoice/entities/invoice.entity';
|
import { Invoice } from 'src/modules/invoice/entities/invoice.entity';
|
||||||
|
|
||||||
@Entity({ tableName: 'requests' })
|
@Entity({ tableName: 'requests' })
|
||||||
@@ -45,8 +43,4 @@ export class Request extends BaseEntity {
|
|||||||
})
|
})
|
||||||
requestNumber: number;
|
requestNumber: number;
|
||||||
|
|
||||||
|
|
||||||
@Enum(() => RequestStatusEnum)
|
|
||||||
status: RequestStatusEnum = RequestStatusEnum.PENDING;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
|
|
||||||
export enum RequestStatusEnum{
|
|
||||||
PENDING = 'pending',
|
|
||||||
INVOICED = 'invoiced',
|
|
||||||
}
|
|
||||||
@@ -4,7 +4,6 @@ import { FilterQuery } from '@mikro-orm/core';
|
|||||||
import { Request } from '../entities/request.entity';
|
import { Request } from '../entities/request.entity';
|
||||||
import { PaginatedResult } from 'src/common/interfaces/pagination.interface';
|
import { PaginatedResult } from 'src/common/interfaces/pagination.interface';
|
||||||
import { FindRequestsDto } from '../dto/find-requests.dto';
|
import { FindRequestsDto } from '../dto/find-requests.dto';
|
||||||
import { RequestStatusEnum } from '../enum/request';
|
|
||||||
|
|
||||||
class FindRequestsOpts extends FindRequestsDto {
|
class FindRequestsOpts extends FindRequestsDto {
|
||||||
userId?: string;
|
userId?: string;
|
||||||
@@ -20,7 +19,6 @@ export class RequestRepository extends EntityRepository<Request> {
|
|||||||
const {
|
const {
|
||||||
page = 1,
|
page = 1,
|
||||||
limit = 10,
|
limit = 10,
|
||||||
statuses,
|
|
||||||
search,
|
search,
|
||||||
orderBy = 'createdAt',
|
orderBy = 'createdAt',
|
||||||
order = 'desc',
|
order = 'desc',
|
||||||
@@ -37,19 +35,6 @@ export class RequestRepository extends EntityRepository<Request> {
|
|||||||
where.user = { id: userId };
|
where.user = { id: userId };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (statuses) {
|
|
||||||
const normalizedStatuses = Array.isArray(statuses) ? statuses : [statuses];
|
|
||||||
const validStatuses = normalizedStatuses.filter((s): s is RequestStatusEnum => !!s);
|
|
||||||
|
|
||||||
if (validStatuses.length > 0) {
|
|
||||||
if (validStatuses.length === 1) {
|
|
||||||
where.status = validStatuses[0];
|
|
||||||
} else {
|
|
||||||
where.status = { $in: validStatuses };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (from || to) {
|
if (from || to) {
|
||||||
where.createdAt = {};
|
where.createdAt = {};
|
||||||
if (from) {
|
if (from) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Injectable, NotFoundException, BadRequestException } from '@nestjs/common';
|
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||||
import { EntityManager } from '@mikro-orm/postgresql';
|
import { EntityManager } from '@mikro-orm/postgresql';
|
||||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||||
import { CreateRequestDto } from './dto/create-request.dto';
|
import { CreateRequestDto } from './dto/create-request.dto';
|
||||||
@@ -6,7 +6,6 @@ import { UpdateRequestDto } from './dto/update-request.dto';
|
|||||||
import { FindRequestsDto } from './dto/find-requests.dto';
|
import { FindRequestsDto } from './dto/find-requests.dto';
|
||||||
import { Request } from './entities/request.entity';
|
import { Request } from './entities/request.entity';
|
||||||
import { RequestItem } from './entities/request-item.entity';
|
import { RequestItem } from './entities/request-item.entity';
|
||||||
import { RequestStatusEnum } from './enum/request';
|
|
||||||
import { UserService } from '../user/providers/user.service';
|
import { UserService } from '../user/providers/user.service';
|
||||||
import { ProductService } from '../product/providers/product.service';
|
import { ProductService } from '../product/providers/product.service';
|
||||||
import { FieldRepository } from '../form-builder/repository/field.repository';
|
import { FieldRepository } from '../form-builder/repository/field.repository';
|
||||||
@@ -32,7 +31,6 @@ export class RequestService {
|
|||||||
const request = await this.em.transactional(async (em) => {
|
const request = await this.em.transactional(async (em) => {
|
||||||
const request = em.create(Request, {
|
const request = em.create(Request, {
|
||||||
user,
|
user,
|
||||||
status: RequestStatusEnum.PENDING,
|
|
||||||
});
|
});
|
||||||
em.persist(request);
|
em.persist(request);
|
||||||
|
|
||||||
@@ -134,10 +132,6 @@ export class RequestService {
|
|||||||
throw new NotFoundException('Request not found');
|
throw new NotFoundException('Request not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request.status !== RequestStatusEnum.PENDING) {
|
|
||||||
throw new BadRequestException('Only pending requests can be updated');
|
|
||||||
}
|
|
||||||
|
|
||||||
const { items } = updateRequestDto;
|
const { items } = updateRequestDto;
|
||||||
if (items?.length) {
|
if (items?.length) {
|
||||||
return this.em.transactional(async (em) => {
|
return this.em.transactional(async (em) => {
|
||||||
@@ -208,9 +202,6 @@ export class RequestService {
|
|||||||
if (!request) {
|
if (!request) {
|
||||||
throw new NotFoundException('Request not found');
|
throw new NotFoundException('Request not found');
|
||||||
}
|
}
|
||||||
if (request.status !== RequestStatusEnum.PENDING) {
|
|
||||||
throw new BadRequestException('Only pending requests can be deleted');
|
|
||||||
}
|
|
||||||
request.deletedAt = new Date();
|
request.deletedAt = new Date();
|
||||||
await this.em.flush();
|
await this.em.flush();
|
||||||
return request;
|
return request;
|
||||||
|
|||||||
Reference in New Issue
Block a user