Tahesab: show raw data from Tahesab, invoice-style document view with metal labels

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-08 13:49:54 +03:30
co-authored by Cursor
parent 2f3646d085
commit e6755d0c2e
4 changed files with 608 additions and 100 deletions
@@ -6,7 +6,7 @@ import {
import { Prisma } from '@prisma/client';
import { PrismaService } from '../../prisma/prisma.service';
import { TahesabConnectionsService } from './connections.service';
import { normalizeMandehResponse } from './tahesab-methods';
import { extractMandehRaw, normalizeMandehResponse } from './tahesab-methods';
@Injectable()
export class TahesabBalanceService {
@@ -78,11 +78,14 @@ export class TahesabBalanceService {
data: { lastBalanceSyncedAt: cache.fetchedAt },
});
const rawView = extractMandehRaw(raw);
return {
connectionId: resolvedId,
connectionLabel: link.connection.label,
dbName: link.connection.dbName,
moshtariCode: link.moshtariCode,
mandehFields: rawView.fields,
mandehDetailRaw: rawView.details,
goldBalance: normalized.goldBalance,
rialBalance: normalized.rialBalance,
currencyBalance: normalized.currencyBalance,
@@ -116,11 +119,14 @@ export class TahesabBalanceService {
return this.getAssets(organizationId, personId, connectionId);
}
const c = link.balanceCache;
const rawView = extractMandehRaw(c.rawResponse);
return {
connectionId: resolvedId,
connectionLabel: link.connection.label,
dbName: link.connection.dbName,
moshtariCode: link.moshtariCode,
mandehFields: rawView.fields,
mandehDetailRaw: rawView.details,
goldBalance: c.goldBalance,
rialBalance: c.rialBalance,
currencyBalance: c.currencyBalance,
@@ -72,6 +72,44 @@ function detailStatus(amount: number): 'بس' | 'بد' {
return amount < 0 ? 'بس' : 'بد';
}
function rawStr(v: unknown): string | null {
if (v === null || v === undefined) return null;
const s = String(v);
return s === 'null' || s === 'undefined' ? null : s;
}
/** فیلدهای پاسخ مانده بدون هیچ تبدیل/محاسبه، به ترتیب خود ته‌حساب */
export function extractMandehRaw(raw: unknown): {
fields: Array<{ key: string; value: string | null }>;
details: Array<{
Name: string;
Value: string | null;
Value1: string | null;
Value2: string | null;
Value3: string | null;
Value4: string | null;
}>;
} {
const row = (raw as { MandeHesab?: Array<Record<string, unknown>> } | null)
?.MandeHesab?.[0];
if (!row || typeof row !== 'object') return { fields: [], details: [] };
const fields = Object.entries(row)
.filter(([k, v]) => k !== 'details' && (v === null || typeof v !== 'object'))
.map(([key, v]) => ({ key, value: rawStr(v) }));
const details = (Array.isArray(row.details) ? row.details : []).map((item) => {
const it = (item ?? {}) as Record<string, unknown>;
return {
Name: String(it.Name ?? ''),
Value: rawStr(it.Value),
Value1: rawStr(it.Value1),
Value2: rawStr(it.Value2),
Value3: rawStr(it.Value3),
Value4: rawStr(it.Value4),
};
});
return { fields, details };
}
/** نرمال‌سازی پاسخ getmandehesabbycode مثل همکار */
export function normalizeMandehResponse(raw: unknown): NormalizedAssets {
const root = raw as {