import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { IsIn, IsNotEmpty, IsNumber, IsPositive, IsString, Matches, Min, MaxLength, ValidateIf, } from 'class-validator'; export const MANUAL_MOVEMENT_TYPES = ['CORRECTION', 'DISPOSAL'] as const; export type ManualMovementType = (typeof MANUAL_MOVEMENT_TYPES)[number]; export const MAX_REASON_LENGTH = 500; const FINITE = { allowNaN: false, allowInfinity: false } as const; /** * CORRECTION (inventory): the rest counted in the box. DISPOSAL: a positive * quantity that leaves the lot, with a reason. TREATMENT bookings come only * from a treatment. */ export class CreateMovementDto { @ApiProperty({ enum: MANUAL_MOVEMENT_TYPES }) @IsIn(MANUAL_MOVEMENT_TYPES) type!: ManualMovementType; @ApiPropertyOptional({ description: 'CORRECTION: der tatsächliche Rest' }) @ValidateIf((dto: CreateMovementDto) => dto.type === 'CORRECTION') @IsNumber(FINITE) @Min(0) actualRemaining?: number; @ApiPropertyOptional({ description: 'DISPOSAL: Menge, positiv' }) @ValidateIf((dto: CreateMovementDto) => dto.type === 'DISPOSAL') @IsNumber(FINITE) @IsPositive() quantity?: number; @ApiPropertyOptional({ description: 'DISPOSAL: Pflicht' }) @ValidateIf( (dto: CreateMovementDto) => dto.type === 'DISPOSAL' || dto.reason != null, ) @IsString() @IsNotEmpty() @Matches(/\S/, { message: 'reason darf nicht nur aus Leerzeichen bestehen' }) @MaxLength(MAX_REASON_LENGTH) reason?: string; }