Add Tahesab jewelry accounting integration with multi-DB connections.
Encrypt tokens server-side, sync customers both ways, show balances/documents on the person Assets tab, and push sanads with idempotent Factor_Code logging. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,290 @@
|
||||
import {
|
||||
IsBoolean,
|
||||
IsIn,
|
||||
IsInt,
|
||||
IsNumber,
|
||||
IsOptional,
|
||||
IsString,
|
||||
IsUrl,
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@IsInt()
|
||||
@Min(1)
|
||||
moshtariCode!: number;
|
||||
|
||||
/** اگر داده شود به این شخص لینک میشود؛ وگرنه شخص جدید ساخته میشود */
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
personId?: string;
|
||||
}
|
||||
|
||||
export class SearchTahesabDto {
|
||||
@IsString()
|
||||
connectionId!: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
phone?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
name?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsInt()
|
||||
moshtariCode?: number;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// silence unused import warnings for ValidateNested/Type if unused
|
||||
void ValidateNested;
|
||||
void Type;
|
||||
void IsUrl;
|
||||
Reference in New Issue
Block a user