diff --git a/src/store/dto/store-items.dto.ts b/src/store/dto/store-items.dto.ts index ec29397..bc9cb2e 100644 --- a/src/store/dto/store-items.dto.ts +++ b/src/store/dto/store-items.dto.ts @@ -8,6 +8,7 @@ import { IsString, Min, MinLength, + ValidateIf, ValidateNested, } from 'class-validator'; @@ -21,21 +22,34 @@ export class StoreItemVariantSelectionDto { optionId!: string; } +/** Keep null as null; avoid `Number(null) === 0`. */ +function nullableNumber({ value }: { value: unknown }) { + if (value === null || value === undefined || value === '') return null; + const n = typeof value === 'number' ? value : Number(value); + return Number.isFinite(n) ? n : value; +} + export class CreateStoreItemVariantDto { @IsArray() @ValidateNested({ each: true }) @Type(() => StoreItemVariantSelectionDto) selections!: StoreItemVariantSelectionDto[]; + /** null / omitted = contact for price */ @IsOptional() + @Transform(nullableNumber) + @ValidateIf((_, v) => v !== null && v !== undefined) @IsNumber() @Min(0) - price?: number; + price?: number | null; + /** null / omitted = unlimited stock */ @IsOptional() + @Transform(nullableNumber) + @ValidateIf((_, v) => v !== null && v !== undefined) @IsInt() @Min(0) - stockQuantity?: number; + stockQuantity?: number | null; } export class BatchCreateStoreItemsDto { @@ -117,14 +131,18 @@ export class ListPublicStoreItemsDto { export class UpdateStoreItemVariantDto { @IsOptional() + @Transform(nullableNumber) + @ValidateIf((_, v) => v !== null && v !== undefined) @IsNumber() @Min(0) - price?: number; + price?: number | null; @IsOptional() + @Transform(nullableNumber) + @ValidateIf((_, v) => v !== null && v !== undefined) @IsInt() @Min(0) - stockQuantity?: number; + stockQuantity?: number | null; @IsOptional() @IsNumber() @@ -167,13 +185,19 @@ export class SyncStoreItemVariantRowDto { @Type(() => StoreItemVariantSelectionDto) selections!: StoreItemVariantSelectionDto[]; + /** null = contact for price */ + @Transform(nullableNumber) + @ValidateIf((_, v) => v !== null && v !== undefined) @IsNumber() @Min(0) - price!: number; + price!: number | null; + /** null = unlimited stock */ + @Transform(nullableNumber) + @ValidateIf((_, v) => v !== null && v !== undefined) @IsInt() @Min(0) - stockQuantity!: number; + stockQuantity!: number | null; } export class SyncProductStoreItemVariantsDto { diff --git a/src/store/store-items.service.ts b/src/store/store-items.service.ts index b0e5da3..de3d004 100644 --- a/src/store/store-items.service.ts +++ b/src/store/store-items.service.ts @@ -916,11 +916,11 @@ export class StoreItemsService { existingKeys.add(key); batchKeys.add(key); - if (item.price !== undefined && item.price < 0) { + if (item.price != null && item.price < 0) { throw new BadRequestException('Price cannot be negative'); } - if (item.stockQuantity !== undefined && item.stockQuantity < 0) { + if (item.stockQuantity != null && item.stockQuantity < 0) { throw new BadRequestException('Stock cannot be negative'); } }