import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { IsString, IsNotEmpty, IsArray, ArrayMinSize, IsBoolean, IsOptional, ValidateIf, ValidateNested, IsEnum, IsInt, } from 'class-validator'; import { Type } from 'class-transformer'; import { IsMoneyAmountString } from 'src/common/validators/money-amount-string.validator'; import { ClaimRequiredDocumentType } from 'src/Types&Enums/claim-request-management/required-document-type.enum'; import { DamagedPartItem } from 'src/claim-request-management/dto/capture-requirements-v2.dto'; import { DaghiOption } from 'src/Types&Enums/claim-request-management/daghi-option.enum'; import { TypeOfDamage } from 'src/Types&Enums/claim-request-management/type-of-damage.enum'; export class DaghiDetailsV2Dto { @ApiProperty({ enum: DaghiOption, description: 'Daghi option: ارزش لوازم بازیافتی, تحویل داغی, فاقد ارزش, با احتساب داغی', }) @IsEnum(DaghiOption) option: DaghiOption; @ApiPropertyOptional({ description: `Required when option is '${DaghiOption.RECYCLED_PARTS_VALUE}' (Toman; 100,000 to 10,000,000,000).`, }) @ValidateIf( (daghi: DaghiDetailsV2Dto) => daghi.option === DaghiOption.RECYCLED_PARTS_VALUE, ) @IsString() @IsNotEmpty() @IsMoneyAmountString() price?: string; } export class PartPricingV2Dto { @ApiProperty({ example: 201, description: 'Numeric catalog part id from claim detail `damagedParts[].partId`.', }) @IsInt() partId: number; @ApiProperty({ enum: TypeOfDamage, description: "'change' requires price; 'repair' may omit it.", }) @IsEnum(TypeOfDamage) typeOfDamage: TypeOfDamage; @ApiPropertyOptional({ example: "5000000", description: "Required for change lines; omitted for repair lines. Every supplied amount must be between 100,000 and 10,000,000,000 Toman.", }) @ValidateIf( (part: PartPricingV2Dto) => part.typeOfDamage === TypeOfDamage.Change || (part.price != null && (typeof part.price !== 'string' || part.price.trim() !== '')), ) @IsString() @IsNotEmpty() @IsMoneyAmountString() price: string; @ApiProperty({ example: "2000000", description: "Labor in Toman (integer string; 100,000 to 10,000,000,000).", }) @IsString() @IsNotEmpty() @IsMoneyAmountString() salary: string; @ApiProperty({ example: "7000000", description: "Line total in Toman (integer string; 100,000 to 10,000,000,000).", }) @IsString() @IsNotEmpty() @IsMoneyAmountString() totalPayment: string; @ApiPropertyOptional({ type: DaghiDetailsV2Dto, description: "Required for change lines; omit for repair lines.", }) @ValidateIf( (part: PartPricingV2Dto) => part.typeOfDamage === TypeOfDamage.Change, ) @IsNotEmpty() @ValidateNested() @Type(() => DaghiDetailsV2Dto) daghi?: DaghiDetailsV2Dto; @ApiProperty({ example: false, description: "If true, the owner must upload a repair factor image for this line; expert confirms cost later (validate-factors). Priced lines omit this or set false.", }) @IsBoolean() factorNeeded: boolean; } export class SubmitExpertReplyV2Dto { @ApiPropertyOptional({ example: 'Front door and hood have severe paint damage', description: "Optional expert note about the damage assessment.", }) @IsOptional() @IsString() description?: string; @ApiProperty({ type: [PartPricingV2Dto], description: "One line per damaged part (`partId` from claim detail `damagedParts[]`), plus pricing, `daghi`, and `factorNeeded`.", }) @IsArray() @ArrayMinSize(1) @ValidateNested({ each: true }) @Type(() => PartPricingV2Dto) parts: PartPricingV2Dto[]; } export class ClaimSubmitResendV2Dto { @ApiPropertyOptional({ description: "Instructions for the owner. At least one of description, resendDocuments, or resendCarParts must be non-empty.", }) @IsOptional() @IsString() resendDescription?: string; @ApiPropertyOptional({ type: [String], enum: ClaimRequiredDocumentType, description: "Document keys to re-upload; each value must be a ClaimRequiredDocumentType string (e.g. national_card).", }) @IsOptional() @IsArray() @IsEnum(ClaimRequiredDocumentType, { each: true }) resendDocuments?: ClaimRequiredDocumentType[]; @ApiPropertyOptional({ type: [DamagedPartItem] }) @IsOptional() @IsArray() @ValidateNested({ each: true }) @Type(() => DamagedPartItem) resendCarParts?: DamagedPartItem[]; }