2026-06-12 20:37:33 +03:30
|
|
|
|
import { ApiPropertyOptional } from '@nestjs/swagger';
|
|
|
|
|
|
import {
|
|
|
|
|
|
IsBoolean,
|
|
|
|
|
|
IsInt,
|
|
|
|
|
|
IsLatitude,
|
|
|
|
|
|
IsLongitude,
|
|
|
|
|
|
IsOptional,
|
|
|
|
|
|
IsString,
|
|
|
|
|
|
IsUUID,
|
|
|
|
|
|
Matches,
|
|
|
|
|
|
Max,
|
|
|
|
|
|
MaxLength,
|
|
|
|
|
|
Min,
|
|
|
|
|
|
} from 'class-validator';
|
2026-05-12 16:17:39 +03:30
|
|
|
|
|
2026-06-12 20:37:33 +03:30
|
|
|
|
export class UpdateBusinessDto {
|
|
|
|
|
|
@ApiPropertyOptional({ example: 'Shine Carwash' })
|
|
|
|
|
|
@IsOptional()
|
|
|
|
|
|
@IsString()
|
|
|
|
|
|
@MaxLength(150)
|
|
|
|
|
|
title?: string;
|
|
|
|
|
|
|
|
|
|
|
|
@ApiPropertyOptional({ example: 'shine-carwash' })
|
|
|
|
|
|
@IsOptional()
|
|
|
|
|
|
@IsString()
|
|
|
|
|
|
@MaxLength(120)
|
|
|
|
|
|
@Matches(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, {
|
|
|
|
|
|
message: 'slug must be lowercase words separated by hyphens',
|
|
|
|
|
|
})
|
|
|
|
|
|
slug?: string;
|
|
|
|
|
|
|
|
|
|
|
|
@ApiPropertyOptional({ format: 'uuid' })
|
|
|
|
|
|
@IsOptional()
|
|
|
|
|
|
@IsUUID()
|
|
|
|
|
|
categoryId?: string;
|
2026-05-12 16:17:39 +03:30
|
|
|
|
|
2026-06-11 12:19:28 +03:30
|
|
|
|
@ApiPropertyOptional({ example: 'تمیزی که میدرخشد', nullable: true })
|
|
|
|
|
|
@IsOptional()
|
|
|
|
|
|
@IsString()
|
|
|
|
|
|
@MaxLength(150)
|
2026-06-12 20:37:33 +03:30
|
|
|
|
subtitle?: string | null;
|
|
|
|
|
|
|
|
|
|
|
|
@ApiPropertyOptional({ example: 'Premium carwash service', nullable: true })
|
|
|
|
|
|
@IsOptional()
|
|
|
|
|
|
@IsString()
|
|
|
|
|
|
@MaxLength(500)
|
|
|
|
|
|
description?: string | null;
|
|
|
|
|
|
|
|
|
|
|
|
@ApiPropertyOptional({ example: '09123456789', nullable: true })
|
|
|
|
|
|
@IsOptional()
|
|
|
|
|
|
@IsString()
|
|
|
|
|
|
@MaxLength(20)
|
|
|
|
|
|
contactPhone?: string | null;
|
|
|
|
|
|
|
|
|
|
|
|
@ApiPropertyOptional({ example: 'Main street', nullable: true })
|
|
|
|
|
|
@IsOptional()
|
|
|
|
|
|
@IsString()
|
|
|
|
|
|
@MaxLength(500)
|
|
|
|
|
|
address?: string | null;
|
|
|
|
|
|
|
|
|
|
|
|
@ApiPropertyOptional({ example: 35.6892, nullable: true })
|
|
|
|
|
|
@IsOptional()
|
|
|
|
|
|
@IsLatitude()
|
|
|
|
|
|
latitude?: number | null;
|
|
|
|
|
|
|
|
|
|
|
|
@ApiPropertyOptional({ example: 51.389, nullable: true })
|
|
|
|
|
|
@IsOptional()
|
|
|
|
|
|
@IsLongitude()
|
|
|
|
|
|
longitude?: number | null;
|
|
|
|
|
|
|
|
|
|
|
|
@ApiPropertyOptional({ format: 'uuid', nullable: true })
|
|
|
|
|
|
@IsOptional()
|
|
|
|
|
|
@IsUUID()
|
|
|
|
|
|
ownerId?: string | null;
|
|
|
|
|
|
|
|
|
|
|
|
@ApiPropertyOptional({ example: true })
|
|
|
|
|
|
@IsOptional()
|
|
|
|
|
|
@IsBoolean()
|
|
|
|
|
|
isActive?: boolean;
|
|
|
|
|
|
|
|
|
|
|
|
@ApiPropertyOptional({
|
|
|
|
|
|
example: false,
|
|
|
|
|
|
description: 'When true, services are priced per owner-defined class (e.g. car size)',
|
|
|
|
|
|
})
|
|
|
|
|
|
@IsOptional()
|
|
|
|
|
|
@IsBoolean()
|
|
|
|
|
|
serviceClassesEnabled?: boolean;
|
|
|
|
|
|
|
|
|
|
|
|
@ApiPropertyOptional({
|
|
|
|
|
|
example: 1,
|
|
|
|
|
|
description: 'How many customers can be served at the same time',
|
|
|
|
|
|
minimum: 1,
|
|
|
|
|
|
maximum: 20,
|
|
|
|
|
|
})
|
|
|
|
|
|
@IsOptional()
|
|
|
|
|
|
@IsInt()
|
|
|
|
|
|
@Min(1)
|
|
|
|
|
|
@Max(20)
|
|
|
|
|
|
concurrentCapacity?: number;
|
|
|
|
|
|
|
|
|
|
|
|
@ApiPropertyOptional({
|
|
|
|
|
|
example: 30,
|
|
|
|
|
|
description: 'Minutes between available booking slot start times',
|
|
|
|
|
|
minimum: 5,
|
|
|
|
|
|
maximum: 120,
|
|
|
|
|
|
})
|
|
|
|
|
|
@IsOptional()
|
|
|
|
|
|
@IsInt()
|
|
|
|
|
|
@Min(5)
|
|
|
|
|
|
@Max(120)
|
|
|
|
|
|
slotStepMinutes?: number;
|
2026-06-29 15:46:24 +03:30
|
|
|
|
|
|
|
|
|
|
@ApiPropertyOptional({
|
|
|
|
|
|
example: false,
|
|
|
|
|
|
description:
|
|
|
|
|
|
'When true, customer bookings are approved automatically and proceed to online payment',
|
|
|
|
|
|
})
|
|
|
|
|
|
@IsOptional()
|
|
|
|
|
|
@IsBoolean()
|
|
|
|
|
|
autoApproveBookings?: boolean;
|
2026-06-29 19:31:26 +03:30
|
|
|
|
|
|
|
|
|
|
@ApiPropertyOptional({
|
|
|
|
|
|
example: false,
|
|
|
|
|
|
description:
|
|
|
|
|
|
'When true, customers see an optional gratuity (tip) step after rating a completed booking',
|
|
|
|
|
|
})
|
|
|
|
|
|
@IsOptional()
|
|
|
|
|
|
@IsBoolean()
|
|
|
|
|
|
tipsEnabled?: boolean;
|
2026-07-16 12:40:52 +03:30
|
|
|
|
|
|
|
|
|
|
@ApiPropertyOptional({
|
|
|
|
|
|
example: true,
|
|
|
|
|
|
description: 'When true, a promotional percentage discount is active for this business',
|
|
|
|
|
|
})
|
|
|
|
|
|
@IsOptional()
|
|
|
|
|
|
@IsBoolean()
|
|
|
|
|
|
promoDiscountEnabled?: boolean;
|
|
|
|
|
|
|
|
|
|
|
|
@ApiPropertyOptional({
|
|
|
|
|
|
example: 'اولین رزرو شما',
|
|
|
|
|
|
nullable: true,
|
|
|
|
|
|
description: 'Display title for the promo (owner-defined)',
|
|
|
|
|
|
})
|
|
|
|
|
|
@IsOptional()
|
|
|
|
|
|
@IsString()
|
|
|
|
|
|
@MaxLength(150)
|
|
|
|
|
|
promoDiscountTitle?: string | null;
|
|
|
|
|
|
|
|
|
|
|
|
@ApiPropertyOptional({
|
|
|
|
|
|
example: 10,
|
|
|
|
|
|
nullable: true,
|
|
|
|
|
|
description: 'Discount percent (1–100)',
|
|
|
|
|
|
minimum: 1,
|
|
|
|
|
|
maximum: 100,
|
|
|
|
|
|
})
|
|
|
|
|
|
@IsOptional()
|
|
|
|
|
|
@IsInt()
|
|
|
|
|
|
@Min(1)
|
|
|
|
|
|
@Max(100)
|
|
|
|
|
|
promoDiscountPercent?: number | null;
|
|
|
|
|
|
|
|
|
|
|
|
@ApiPropertyOptional({
|
|
|
|
|
|
example: 'NEW10',
|
|
|
|
|
|
nullable: true,
|
|
|
|
|
|
description: 'Display code shown to customers (auto-applied when eligible)',
|
|
|
|
|
|
})
|
|
|
|
|
|
@IsOptional()
|
|
|
|
|
|
@IsString()
|
|
|
|
|
|
@MaxLength(40)
|
|
|
|
|
|
promoDiscountCode?: string | null;
|
|
|
|
|
|
|
|
|
|
|
|
@ApiPropertyOptional({
|
|
|
|
|
|
example: 'first_booking',
|
|
|
|
|
|
enum: ['first_booking', 'always'],
|
|
|
|
|
|
description:
|
|
|
|
|
|
'first_booking = only the customer’s first booking at this business; always = every booking while enabled',
|
|
|
|
|
|
})
|
|
|
|
|
|
@IsOptional()
|
|
|
|
|
|
@IsString()
|
|
|
|
|
|
@Matches(/^(first_booking|always)$/)
|
|
|
|
|
|
promoDiscountMode?: 'first_booking' | 'always';
|
2026-06-12 20:37:33 +03:30
|
|
|
|
}
|