Align DoListAsnad with Hamkar (4 args) and treat empty ERROR as [].

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-05 11:18:37 +03:30
co-authored by Cursor
parent 1ac23e13c1
commit 3ab102ddae
3 changed files with 49 additions and 19 deletions
@@ -12,6 +12,16 @@ import {
SanadBuilders,
} from './tahesab-methods';
function normalizeShamsiYmd(input: string): string {
const m = /^(\d{4})-(\d{1,2})-(\d{1,2})$/.exec(input.trim());
if (!m) {
throw new BadRequestException(
'تاریخ از/تا باید شمسی با قالب YYYY-MM-DD باشد.',
);
}
return `${m[1]}-${m[2]!.padStart(2, '0')}-${m[3]!.padStart(2, '0')}`;
}
function asAsnadList(raw: unknown): Array<Record<string, unknown>> {
if (!raw) return [];
if (Array.isArray(raw)) return raw as Array<Record<string, unknown>>;
@@ -66,25 +76,27 @@ export class TahesabDocumentsService {
to: string,
connectionId?: string,
) {
if (!/^\d{4}-\d{1,2}-\d{1,2}$/.test(from) || !/^\d{4}-\d{1,2}-\d{1,2}$/.test(to)) {
throw new BadRequestException(
'تاریخ از/تا باید شمسی با قالب YYYY-MM-DD باشد.',
);
}
const fromNorm = normalizeShamsiYmd(from);
const toNorm = normalizeShamsiYmd(to);
const resolvedId = await this.connections.resolveConnectionId(
organizationId,
connectionId,
);
const link = await this.requireLink(organizationId, personId, resolvedId);
const { api } = await this.connections.getApi(organizationId, resolvedId);
// Count_Last = سقف تعداد سند برگشتی (۰ در نمونه گاهی خالی برمی‌گرداند)
const raw = await api.doListAsnad(500, link.moshtariCode, from, to);
// Count_Last = -1 مثل همکار (مانده ردیف‌به‌ردیف / همه در بازه)
const raw = await api.doListAsnad(
-1,
link.moshtariCode,
fromNorm,
toNorm,
);
const items = asAsnadList(raw);
return {
connectionId: resolvedId,
moshtariCode: link.moshtariCode,
from,
to,
from: fromNorm,
to: toNorm,
items,
count: items.length,
};
@@ -20,6 +20,11 @@ export type TahesabCallOptions = {
method?: 'GET' | 'POST';
allowInsecureTls?: boolean;
timeoutMs?: number;
/**
* اگر ته‌حساب با فیلد ERROR و متن منطبق جواب داد، به‌جای ۵۰۲
* مقدار خالی ([] ) برگردان — مثل «رکوردی یافت نشد» در DoListAsnad.
*/
emptyResultOnError?: RegExp;
};
function extractTahesabError(json: unknown, text: string): string {
@@ -109,6 +114,17 @@ export class TahesabHttpClient {
// بعضی متدها با ۲۰۰ و فیلد ERROR برمی‌گردند
if (json && typeof json === 'object' && 'ERROR' in (json as object)) {
const detail = extractTahesabError(json, text);
if (
detail &&
opts.emptyResultOnError &&
opts.emptyResultOnError.test(detail)
) {
this.logger.debug(
`Tahesab ${path} empty-on-error: ${detail.slice(0, 120)}`,
);
resolve([] as T);
return;
}
reject(
new BadGatewayException(
detail ? `ته‌حساب: ${detail}` : `خطای ته‌حساب برای ${path}`,
@@ -1,5 +1,5 @@
import { randomBytes } from 'crypto';
import type { TahesabHttpClient } from './tahesab-http.client';
import type { TahesabHttpClient, TahesabCallOptions } from './tahesab-http.client';
export type ConnCreds = {
baseUrl: string;
@@ -146,6 +146,7 @@ export class TahesabApi {
args?: unknown[],
method?: 'GET' | 'POST',
timeoutMs?: number,
extra?: Pick<TahesabCallOptions, 'emptyResultOnError'>,
) {
return this.http.call<T>({
...this.creds,
@@ -154,6 +155,7 @@ export class TahesabApi {
args,
method,
timeoutMs,
...extra,
});
}
@@ -222,15 +224,15 @@ export class TahesabApi {
fromShamsi: string,
toShamsi: string,
) {
// OpenAPI: Count_Last, Moshtari_Code, AzTarikhShamsi, TaTarikhShamsi, FilterNoSanad, Mande_Jens_Felez
return this.call('DoListAsnad', 'DoListAsnad', [
countLast,
moshtariCode,
fromShamsi,
toShamsi,
'',
0,
]);
// مثل همکار: فقط ۴ پارامتر (Count_Last, Code, از, تا) — پارامتر اضافه باعث خطای ته‌حساب می‌شود
return this.call(
'DoListAsnad',
'DoListAsnad',
[countLast, moshtariCode, fromShamsi, toShamsi],
'POST',
55_000,
{ emptyResultOnError: /رکوردی یافت نشد/i },
);
}
doListNameSekeh() {