import { ArrayMaxSize, IsArray, IsBoolean, IsIn, IsInt, IsNumber, IsOptional, IsString, IsUrl, Max, MaxLength, Min, MinLength, ValidateNested, } from 'class-validator'; import { Type } from 'class-transformer'; export class CreateTahesabConnectionDto { @IsString() @MinLength(1) @MaxLength(120) label!: string; @IsString() @MinLength(8) @MaxLength(500) baseUrl!: string; @IsString() @MinLength(1) @MaxLength(120) dbName!: string; @IsString() @MinLength(8) @MaxLength(2000) token!: string; @IsOptional() @IsBoolean() enabled?: boolean; @IsOptional() @IsBoolean() isDefault?: boolean; @IsOptional() @IsBoolean() allowInsecureTls?: boolean; } export class UpdateTahesabConnectionDto { @IsOptional() @IsString() @MinLength(1) @MaxLength(120) label?: string; @IsOptional() @IsString() @MinLength(8) @MaxLength(500) baseUrl?: string; @IsOptional() @IsString() @MinLength(1) @MaxLength(120) dbName?: string; @IsOptional() @IsString() @MinLength(8) @MaxLength(2000) token?: string; @IsOptional() @IsBoolean() enabled?: boolean; @IsOptional() @IsBoolean() isDefault?: boolean; @IsOptional() @IsBoolean() allowInsecureTls?: boolean; /** ساعت‌های ۰ تا ۲۳. آرایهٔ خالی یعنی خاموش. */ @IsOptional() @IsArray() @ArrayMaxSize(6) @Type(() => Number) @IsInt({ each: true }) @Min(0, { each: true }) @Max(23, { each: true }) customerSyncHours?: number[]; } export class ManualLinkDto { @IsString() connectionId!: string; @IsInt() @Min(1) moshtariCode!: number; } export class MatchPersonDto { @IsString() connectionId!: string; /** اگر true باشد و دقیقاً یک نتیجه باشد، لینک می‌شود */ @IsOptional() @IsBoolean() autoLinkIfUnique?: boolean; } export class CreateInTahesabDto { @IsString() connectionId!: string; @IsOptional() @IsString() groupName?: string; @IsOptional() @IsInt() jensFelez?: number; } export class ImportFromTahesabDto { @IsString() connectionId!: string; @Type(() => Number) @IsInt() @Min(1) moshtariCode!: number; /** اگر داده شود به این شخص لینک می‌شود؛ وگرنه شخص جدید ساخته می‌شود */ @IsOptional() @IsString() personId?: string; } export class ImportBulkFromTahesabDto { @IsString() connectionId!: string; @IsOptional() @IsArray() @Type(() => Number) @IsInt({ each: true }) moshtariCodes?: number[]; @IsOptional() @Type(() => Number) @IsInt() @Min(1) fromCode?: number; @IsOptional() @Type(() => Number) @IsInt() @Min(1) toCode?: number; /** اگر true باشد یک صفحه از مشتریان (بازهٔ کد) خوانده می‌شود */ @IsOptional() @IsBoolean() listAll?: boolean; /** صفحهٔ بازهٔ کد هنگام listAll (پیش‌فرض ۱) */ @IsOptional() @Type(() => Number) @IsInt() @Min(1) page?: number; @IsOptional() @Type(() => Number) @IsInt() @Min(100) @Max(2000) pageSize?: number; } export class SyncGroupsPageDto { @IsString() connectionId!: string; @IsOptional() @Type(() => Number) @IsInt() @Min(1) page?: number; @IsOptional() @Type(() => Number) @IsInt() @Min(100) @Max(2000) pageSize?: number; } /** اجرای دستی همگام‌سازی همهٔ مشتریان (وارد + به‌روز کردن لینک‌شده‌ها) */ export class SyncAllCustomersDto { @IsString() connectionId!: string; } export class ExportPeopleToTahesabDto { @IsString() connectionId!: string; /** هر درخواست چند نفر؛ هر نفر چند تماس با ته‌حساب دارد */ @IsArray() @ArrayMaxSize(25) @IsString({ each: true }) personIds!: string[]; } export class SearchTahesabDto { @IsString() connectionId!: string; @IsOptional() @IsString() phone?: string; @IsOptional() @IsString() name?: string; @IsOptional() @Type(() => Number) @IsInt() moshtariCode?: number; /** لیست بازه‌ای با DoListMoshtari-ByCode */ @IsOptional() @Type(() => Number) @IsInt() @Min(1) fromCode?: number; @IsOptional() @Type(() => Number) @IsInt() @Min(1) toCode?: number; /** بازه خالی در UI → مرور صفحه‌ای همهٔ مشتریان */ @IsOptional() @IsBoolean() listAll?: boolean; /** * صفحهٔ بازهٔ کد برای listAll (۱ = کد ۱…۲۰۰۰، ۲ = ۲۰۰۱…۴۰۰۰، …). * سقف ۵۰۰۰ دیگر اعمال نمی‌شود. */ @IsOptional() @Type(() => Number) @IsInt() @Min(1) page?: number; /** اندازهٔ پنجرهٔ کد در هر صفحه (پیش‌فرض ۲۰۰۰، حداکثر ۲۰۰۰) */ @IsOptional() @Type(() => Number) @IsInt() @Min(100) @Max(2000) pageSize?: number; } export class SearchTahesabProductsDto { @IsString() connectionId!: string; /** فیلتر اختیاری روی نام کارساخته */ @IsOptional() @IsString() @MaxLength(200) q?: string; } export class ImportProductFromTahesabDto { @IsString() connectionId!: string; @IsString() @MinLength(1) @MaxLength(200) name!: string; /** اگر داده شود به این محصول لینک می‌شود؛ وگرنه محصول جدید ساخته می‌شود */ @IsOptional() @IsString() productId?: string; } export class ImportBulkProductsFromTahesabDto { @IsString() connectionId!: string; /** اگر خالی باشد همهٔ نام‌های کارساخته وارد می‌شوند */ @IsOptional() @IsArray() @IsString({ each: true }) names?: string[]; } export class ListAsnadQueryDto { @IsOptional() @IsString() connectionId?: string; /** تاریخ شمسی YYYY-MM-DD */ @IsString() from!: string; @IsString() to!: string; } const SANAD_TYPES = [ 'buy_sale_gold', 'buy_sale_sekeh', 'talab_bedehi', 'vkh_gold', 'vkh_bank', ] as const; export class PushSanadDto { @IsString() connectionId!: string; @IsIn(SANAD_TYPES) docType!: (typeof SANAD_TYPES)[number]; @IsInt() year!: number; @IsInt() @Min(1) month!: number; @IsInt() @Min(1) day!: number; @IsOptional() @IsString() @MaxLength(500) sharh?: string; // gold / sekeh / vkh gold @IsOptional() @IsNumber() vazn?: number; @IsOptional() @IsNumber() ayar?: number; @IsOptional() @IsIn([0, 1]) buyOrSale?: 0 | 1; @IsOptional() @IsNumber() mazaneh?: number; @IsOptional() @IsIn([0, 1]) mazanehIsGeram?: 0 | 1; @IsOptional() @IsIn([0, 1]) isAbshode?: 0 | 1; @IsOptional() @IsNumber() mablaghKol?: number; @IsOptional() @IsNumber() count?: number; @IsOptional() @IsString() nameSekeh?: string; @IsOptional() @IsIn([0, 1]) isBedehiOrTalab?: 0 | 1; @IsOptional() @IsNumber() mablagh?: number; @IsOptional() @IsString() baabat?: string; @IsOptional() @IsInt() havalehBeMcode?: number; @IsOptional() @IsString() angNumber?: string; @IsOptional() @IsString() nameAz?: string; @IsOptional() @IsIn([0, 1]) isVoroodOrKhorooj?: 0 | 1; @IsOptional() @IsIn([0, 1]) isDaryaftOrPardakht?: 0 | 1; @IsOptional() @IsString() nameBank?: string; @IsOptional() @IsString() codeRahgiri?: string; @IsOptional() @IsInt() jensFelez?: number; @IsOptional() @IsString() arzName?: string; /** اگر ارسال شود و قبلاً success بوده، همان پاسخ برمی‌گردد (retry امن) */ @IsOptional() @IsString() @MinLength(20) factorCode?: string; } export class SyncAsnadReportDto { @IsOptional() @IsString() connectionId?: string; @IsString() @MinLength(8) @MaxLength(12) from!: string; @IsString() @MinLength(8) @MaxLength(12) to!: string; /** اگر باشد، فقط سندهای همین شخص گرفته می‌شود */ @IsOptional() @IsString() personId?: string; /** اگر باشد، فقط مشتریان این گروه‌ها (و زیرگروه‌ها) گرفته می‌شوند */ @IsOptional() @IsArray() @IsString({ each: true }) @ArrayMaxSize(200) groupIds?: string[]; } export class UpdateTahesabInvoiceSettingsDto { /** null = حذف لوگو */ @IsOptional() logoDataUrl?: string | null; @IsOptional() @IsString() @MaxLength(200) companyName?: string; @IsOptional() @IsString() @MaxLength(200) companySubtitle?: string; @IsOptional() @IsString() @MaxLength(500) address?: string; @IsOptional() @IsString() @MaxLength(80) phone?: string; @IsOptional() @IsString() @MaxLength(1000) headerText?: string; @IsOptional() @IsString() @MaxLength(1000) footerText?: string; } // silence unused import warnings for ValidateNested/Type if unused void ValidateNested; void Type; void IsUrl;