import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { ArrayNotEmpty, IsArray, IsIn, IsLatitude, IsLongitude, IsNumber, IsOptional, IsString, IsUrl, IsUUID, ValidateIf, } from 'class-validator'; import { PaginationQueryDto } from '../../../../common/http/response'; import { CORE_STATUSES } from '../../../../common/value-objects/status/status'; import { CHECK_IN_METHODS } from '../../shared/check-in-verification'; export class VisitCheckInDto { @ApiProperty({ format: 'uuid' }) @IsUUID('4') customerId!: string; @ApiPropertyOptional({ format: 'uuid' }) @IsOptional() @IsUUID('4') planId?: string; @ApiProperty({ enum: CHECK_IN_METHODS }) @IsIn([...CHECK_IN_METHODS]) method!: string; @ApiPropertyOptional() @ValidateIf((dto: VisitCheckInDto) => dto.method === 'nfc') @IsString() nfcId?: string; @ApiPropertyOptional() @ValidateIf((dto: VisitCheckInDto) => dto.method === 'qr') @IsString() qrCode?: string; @ApiProperty() @IsLatitude() latitude!: number; @ApiProperty() @IsLongitude() longitude!: number; @ApiPropertyOptional() @IsOptional() @IsUrl({ require_protocol: true, protocols: ['https'] }) photoUrl?: string; } export class VisitCheckOutDto { @ApiProperty({ enum: CHECK_IN_METHODS }) @IsIn([...CHECK_IN_METHODS]) method!: string; @ApiPropertyOptional() @ValidateIf((dto: VisitCheckOutDto) => dto.method === 'nfc') @IsString() nfcId?: string; @ApiPropertyOptional() @ValidateIf((dto: VisitCheckOutDto) => dto.method === 'qr') @IsString() qrCode?: string; @ApiProperty() @IsLatitude() latitude!: number; @ApiProperty() @IsLongitude() longitude!: number; @ApiPropertyOptional() @IsOptional() @IsUrl({ require_protocol: true, protocols: ['https'] }) photoUrl?: string; } export class UpdateVisitStatusDto { @ApiProperty({ enum: CORE_STATUSES }) @IsIn([...CORE_STATUSES]) status!: string; } export class BulkIdsDto { @ApiProperty({ type: [String], format: 'uuid' }) @IsArray() @ArrayNotEmpty() @IsUUID('4', { each: true }) ids!: string[]; } export class BulkStatusDto { @ApiProperty({ type: [String], format: 'uuid' }) @IsArray() @ArrayNotEmpty() @IsUUID('4', { each: true }) ids!: string[]; @ApiProperty({ enum: CORE_STATUSES }) @IsIn([...CORE_STATUSES]) status!: string; } export class ListVisitsQueryDto extends PaginationQueryDto { @ApiPropertyOptional({ format: 'uuid' }) @IsOptional() @IsUUID('4') employeeId?: string; @ApiPropertyOptional({ format: 'uuid' }) @IsOptional() @IsUUID('4') customerId?: string; @ApiPropertyOptional({ description: 'Unix ms start of calendar day' }) @IsOptional() @IsNumber() date?: number; @ApiPropertyOptional({ enum: CORE_STATUSES }) @IsOptional() @IsIn([...CORE_STATUSES]) status?: string; @ApiPropertyOptional() @IsOptional() @IsString() search?: string; } class RelationDto { @ApiProperty({ format: 'uuid' }) id!: string; @ApiProperty() code!: string; @ApiProperty() name!: string; } class UserRelationDto { @ApiProperty({ format: 'uuid' }) id!: string; @ApiProperty() username!: string; } export class VisitDto { @ApiProperty({ format: 'uuid' }) id!: string; @ApiProperty({ type: RelationDto }) employee!: RelationDto; @ApiProperty({ type: RelationDto }) customer!: RelationDto; @ApiProperty({ format: 'uuid', nullable: true }) attendanceId!: string | null; @ApiProperty({ format: 'uuid', nullable: true }) planId!: string | null; @ApiProperty({ format: 'uuid', nullable: true }) planDestinationId!: string | null; @ApiProperty() date!: number; @ApiProperty() checkInAt!: number; @ApiProperty({ enum: CHECK_IN_METHODS }) checkInMethod!: string; @ApiProperty() checkInLatitude!: number; @ApiProperty() checkInLongitude!: number; @ApiProperty({ nullable: true }) checkInPhotoUrl!: string | null; @ApiProperty({ nullable: true }) checkInDistanceMeters!: number | null; @ApiProperty({ nullable: true }) checkOutAt!: number | null; @ApiProperty({ enum: CHECK_IN_METHODS, nullable: true }) checkOutMethod!: string | null; @ApiProperty({ nullable: true }) checkOutLatitude!: number | null; @ApiProperty({ nullable: true }) checkOutLongitude!: number | null; @ApiProperty({ nullable: true }) checkOutPhotoUrl!: string | null; @ApiProperty({ nullable: true }) checkOutDistanceMeters!: number | null; @ApiProperty() status!: string; @ApiProperty() createdAt!: number; @ApiProperty() updatedAt!: number; @ApiProperty({ type: UserRelationDto }) createdBy!: UserRelationDto; @ApiProperty({ type: UserRelationDto }) updatedBy!: UserRelationDto; }