refactor: dtos validation

This commit is contained in:
Ahmed Bouhuolia
2025-03-20 05:42:19 +02:00
parent fd65ee9428
commit 136cc907bb
105 changed files with 1641 additions and 366 deletions

View File

@@ -1,8 +1,6 @@
import {
ICreateWarehouseTransferDTO,
IEditWarehouseTransferDTO,
IGetWarehousesTransfersFilterDTO,
} from '@/modules/Warehouses/Warehouse.types';
import { Injectable } from '@nestjs/common';
import { ModelObject } from 'objection';
import { IGetWarehousesTransfersFilterDTO } from '@/modules/Warehouses/Warehouse.types';
import { CreateWarehouseTransfer } from './commands/CreateWarehouseTransfer';
import { DeleteWarehouseTransfer } from './commands/DeleteWarehouseTransfer';
import { EditWarehouseTransfer } from './commands/EditWarehouseTransfer';
@@ -10,9 +8,11 @@ import { GetWarehouseTransfer } from './queries/GetWarehouseTransfer';
import { GetWarehouseTransfers } from './queries/GetWarehouseTransfers';
import { InitiateWarehouseTransfer } from './commands/InitiateWarehouseTransfer';
import { TransferredWarehouseTransfer } from './commands/TransferredWarehouseTransfer';
import { Injectable } from '@nestjs/common';
import { WarehouseTransfer } from './models/WarehouseTransfer';
import { ModelObject } from 'objection';
import {
CreateWarehouseTransferDto,
EditWarehouseTransferDto,
} from './dtos/WarehouseTransfer.dto';
@Injectable()
export class WarehouseTransferApplication {
@@ -32,7 +32,7 @@ export class WarehouseTransferApplication {
* @returns {Promise<ModelObject<WarehouseTransfer>>}
*/
public createWarehouseTransfer = (
createWarehouseTransferDTO: ICreateWarehouseTransferDTO,
createWarehouseTransferDTO: CreateWarehouseTransferDto,
): Promise<ModelObject<WarehouseTransfer>> => {
return this.createWarehouseTransferService.createWarehouseTransfer(
createWarehouseTransferDTO,
@@ -46,7 +46,7 @@ export class WarehouseTransferApplication {
*/
public editWarehouseTransfer = (
warehouseTransferId: number,
editWarehouseTransferDTO: IEditWarehouseTransferDTO,
editWarehouseTransferDTO: EditWarehouseTransferDto,
): Promise<ModelObject<WarehouseTransfer>> => {
return this.editWarehouseTransferService.editWarehouseTransfer(
warehouseTransferId,
@@ -69,8 +69,8 @@ export class WarehouseTransferApplication {
/**
* Retrieves warehouse transfer transaction.
* @param {number} warehouseTransferId
* @returns {Promise<IWarehouseTransfer>}
* @param {number} warehouseTransferId - Warehouse transfer id.
* @returns {Promise<ModelObject<WarehouseTransfer>>}
*/
public getWarehouseTransfer = (
warehouseTransferId: number,

View File

@@ -9,13 +9,13 @@ import {
Query,
Inject,
} from '@nestjs/common';
import { WarehouseTransferApplication } from './WarehouseTransferApplication';
import {
ICreateWarehouseTransferDTO,
IEditWarehouseTransferDTO,
} from '@/modules/Warehouses/Warehouse.types';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { WarehouseTransferApplication } from './WarehouseTransferApplication';
import { PublicRoute } from '../Auth/Jwt.guard';
import {
CreateWarehouseTransferDto,
EditWarehouseTransferDto,
} from './dtos/WarehouseTransfer.dto';
@Controller('warehouse-transfers')
@ApiTags('warehouse-transfers')
@@ -40,7 +40,7 @@ export class WarehouseTransfersController {
'The warehouse transfer transaction has been created successfully.',
})
async createWarehouseTransfer(
@Body() createWarehouseTransferDTO: ICreateWarehouseTransferDTO,
@Body() createWarehouseTransferDTO: CreateWarehouseTransferDto,
) {
const warehouse =
await this.warehouseTransferApplication.createWarehouseTransfer(
@@ -66,14 +66,13 @@ export class WarehouseTransfersController {
})
async editWarehouseTransfer(
@Param('id') id: number,
@Body() editWarehouseTransferDTO: IEditWarehouseTransferDTO,
@Body() editWarehouseTransferDTO: EditWarehouseTransferDto,
) {
const warehouseTransfer =
await this.warehouseTransferApplication.editWarehouseTransfer(
id,
editWarehouseTransferDTO,
);
return {
id: warehouseTransfer.id,
message:

View File

@@ -1,16 +1,15 @@
import { ModelObject } from 'objection';
import { Inject, Injectable } from '@nestjs/common';
import { ERRORS } from '../constants';
import { WarehouseTransfer } from '../models/WarehouseTransfer';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { ItemsEntriesService } from '@/modules/Items/ItemsEntries.service';
import { Inject, Injectable } from '@nestjs/common';
import { ServiceError } from '@/modules/Items/ServiceError';
import { ModelObject } from 'objection';
import { Item } from '@/modules/Items/models/Item';
import {
ICreateWarehouseTransferDTO,
IEditWarehouseTransferDTO,
} from '@/modules/Warehouses/Warehouse.types';
import { Warehouse } from '@/modules/Warehouses/models/Warehouse.model';
import {
CreateWarehouseTransferDto,
EditWarehouseTransferDto,
} from '../dtos/WarehouseTransfer.dto';
@Injectable()
export class CommandWarehouseTransfer {
@@ -25,7 +24,7 @@ export class CommandWarehouseTransfer {
) {}
/**
*
* Throws error if warehouse transfer not found.
* @param {WarehouseTransfer} warehouseTransfer
*/
throwIfTransferNotFound = (warehouseTransfer: WarehouseTransfer) => {
@@ -35,9 +34,9 @@ export class CommandWarehouseTransfer {
};
/**
*
* Retrieves the warehouse transfer or throw not found service error.
* @param {number} branchId
* @returns
* @returns {Promise<WarehouseTransfer>}
*/
async getWarehouseTransferOrThrowNotFound(branchId: number) {
const foundTransfer = await this.warehouseTransferModel()
@@ -55,9 +54,7 @@ export class CommandWarehouseTransfer {
* @param {ICreateWarehouseTransferDTO|IEditWarehouseTransferDTO} warehouseTransferDTO
*/
validateWarehouseFromToNotSame(
warehouseTransferDTO:
| ICreateWarehouseTransferDTO
| IEditWarehouseTransferDTO,
warehouseTransferDTO: CreateWarehouseTransferDto | EditWarehouseTransferDto,
) {
if (
warehouseTransferDTO.fromWarehouseId ===
@@ -69,12 +66,10 @@ export class CommandWarehouseTransfer {
/**
* Validates entries items should be inventory.
* @param {IItem[]} items
* @param {ModelObject<Item>[]} items - Items.
* @returns {void}
*/
validateItemsShouldBeInventory = (
items: ModelObject<Item>[],
): void => {
validateItemsShouldBeInventory = (items: ModelObject<Item>[]): void => {
const nonInventoryItems = items.filter((item) => item.type !== 'inventory');
if (nonInventoryItems.length > 0) {
@@ -85,9 +80,9 @@ export class CommandWarehouseTransfer {
};
/**
*
* @param {number} fromWarehouseId
* @returns
* Retrieves the to warehouse or throw not found service error.
* @param {number} fromWarehouseId - From warehouse id.
* @returns {Promise<Warehouse>}
*/
getToWarehouseOrThrow = async (fromWarehouseId: number) => {
const warehouse = await this.warehouseModel()

View File

@@ -20,6 +20,10 @@ import { events } from '@/common/events/events';
import { IInventoryItemCostMeta } from '@/modules/InventoryCost/types/InventoryCost.types';
import { ModelObject } from 'objection';
import { WarehouseTransferEntry } from '../models/WarehouseTransferEntry';
import {
CreateWarehouseTransferDto,
WarehouseTransferEntryDto,
} from '../dtos/WarehouseTransfer.dto';
@Injectable()
export class CreateWarehouseTransfer {
@@ -48,11 +52,11 @@ export class CreateWarehouseTransfer {
/**
* Transformes the givne new warehouse transfer DTO to model.
* @param {ICreateWarehouseTransferDTO} warehouseTransferDTO
* @param {ICreateWarehouseTransferDTO} warehouseTransferDTO
* @returns {IWarehouseTransfer}
*/
private transformDTOToModel = async (
warehouseTransferDTO: ICreateWarehouseTransferDTO,
warehouseTransferDTO: CreateWarehouseTransferDto,
): Promise<ModelObject<WarehouseTransfer>> => {
const entries = await this.transformEntries(
warehouseTransferDTO,
@@ -91,8 +95,8 @@ export class CreateWarehouseTransfer {
private transformEntryAssocAverageCost = R.curry(
(
inventoryItemsCostMap: Map<number, IInventoryItemCostMeta>,
entry: IWarehouseTransferEntryDTO,
): IWarehouseTransferEntryDTO => {
entry: WarehouseTransferEntryDto,
): WarehouseTransferEntryDto => {
const itemValuation = inventoryItemsCostMap.get(entry.itemId);
const itemCost = get(itemValuation, 'average', 0);
@@ -107,8 +111,8 @@ export class CreateWarehouseTransfer {
* @returns {Promise<IWarehouseTransferEntryDTO[]>}
*/
public transformEntries = async (
warehouseTransferDTO: ICreateWarehouseTransferDTO,
entries: IWarehouseTransferEntryDTO[],
warehouseTransferDTO: CreateWarehouseTransferDto,
entries: WarehouseTransferEntryDto[],
): Promise<ModelObject<WarehouseTransferEntry>[]> => {
const inventoryItemsIds = warehouseTransferDTO.entries.map((e) => e.itemId);
@@ -127,17 +131,15 @@ export class CreateWarehouseTransfer {
/**
* Authorize warehouse transfer before creating.
* @param {number} tenantId
* @param {ICreateWarehouseTransferDTO} warehouseTransferDTO
* @param {CreateWarehouseTransferDto} warehouseTransferDTO - Warehouse transfer DTO.
*/
public authorize = async (
warehouseTransferDTO: ICreateWarehouseTransferDTO,
warehouseTransferDTO: CreateWarehouseTransferDto,
) => {
// Validate warehouse from and to should not be the same.
this.commandWarehouseTransfer.validateWarehouseFromToNotSame(
warehouseTransferDTO,
);
// Retrieves the from warehouse or throw not found service error.
const fromWarehouse =
await this.commandWarehouseTransfer.getFromWarehouseOrThrow(
@@ -162,7 +164,7 @@ export class CreateWarehouseTransfer {
* @returns {Promise<ModelObject<WarehouseTransfer>>}
*/
public createWarehouseTransfer = async (
warehouseTransferDTO: ICreateWarehouseTransferDTO,
warehouseTransferDTO: CreateWarehouseTransferDto,
): Promise<ModelObject<WarehouseTransfer>> => {
// Authorize warehouse transfer before creating.
await this.authorize(warehouseTransferDTO);

View File

@@ -13,9 +13,17 @@ import { events } from '@/common/events/events';
import { WarehouseTransfer } from '../models/WarehouseTransfer';
import { ItemsEntriesService } from '@/modules/Items/ItemsEntries.service';
import { ModelObject } from 'objection';
import { EditWarehouseTransferDto } from '../dtos/WarehouseTransfer.dto';
@Injectable()
export class EditWarehouseTransfer {
/**
* @param {UnitOfWork} uow - Unit of work service.
* @param {EventEmitter2} eventPublisher - Event emitter service.
* @param {CommandWarehouseTransfer} commandWarehouseTransfer - Command warehouse transfer service.
* @param {ItemsEntriesService} itemsEntries - Items entries service.
* @param {TenantModelProxy<WarehouseTransfer>} warehouseTransferModel - Warehouse transfer model.
*/
constructor(
private readonly uow: UnitOfWork,
private readonly eventPublisher: EventEmitter2,
@@ -36,7 +44,7 @@ export class EditWarehouseTransfer {
*/
public editWarehouseTransfer = async (
warehouseTransferId: number,
editWarehouseDTO: IEditWarehouseTransferDTO,
editWarehouseDTO: EditWarehouseTransferDto,
): Promise<ModelObject<WarehouseTransfer>> => {
// Retrieves the old warehouse transfer transaction.
const oldWarehouseTransfer = await this.warehouseTransferModel()

View File

@@ -0,0 +1,72 @@
import { Type } from 'class-transformer';
import {
IsArray,
IsBoolean,
IsDate,
IsDecimal,
IsInt,
IsNotEmpty,
IsNumber,
IsOptional,
IsPositive,
IsString,
ValidateNested,
ArrayMinSize,
} from 'class-validator';
export class WarehouseTransferEntryDto {
@IsNotEmpty()
index: number;
@IsNotEmpty()
@IsInt()
itemId: number;
@IsOptional()
@IsString()
description?: string;
@IsNotEmpty()
@IsInt()
@IsPositive()
quantity: number;
@IsOptional()
@IsDecimal()
cost?: number;
}
export class CommandWarehouseTransferDto {
@IsNotEmpty()
@IsInt()
fromWarehouseId: number;
@IsNotEmpty()
@IsInt()
toWarehouseId: number;
@IsNotEmpty()
@IsDate()
date: Date;
@IsOptional()
@IsString()
transactionNumber?: string;
@IsBoolean()
@IsOptional()
transferInitiated: boolean = false;
@IsBoolean()
@IsOptional()
transferDelivered: boolean = false;
@IsArray()
@ArrayMinSize(1)
@ValidateNested({ each: true })
@Type(() => WarehouseTransferEntryDto)
entries: WarehouseTransferEntryDto[];
}
export class CreateWarehouseTransferDto extends CommandWarehouseTransferDto {}
export class EditWarehouseTransferDto extends CommandWarehouseTransferDto {}