feat(tahesab): sales report snapshot with org-module gate

Sync linked asnad into CRM, filter by group/kind/metal, and require the tahesab superadmin module plus reports role access.
This commit is contained in:
2026-10-22 18:20:46 +03:30
parent 65cf4e9a66
commit ade43fea0f
11 changed files with 1490 additions and 3 deletions
+49
View File
@@ -196,6 +196,7 @@ model Organization {
noteAiSuggestions NoteAiSuggestion[]
accountingConnections AccountingConnection[]
accountingSyncJobs AccountingSyncJob[]
accountingAsnadLines AccountingAsnadLine[]
warehouses Warehouse[]
stockMovements StockMovement[]
partyOpenings PartyOpeningBalance[]
@@ -614,6 +615,7 @@ model Person {
memoryItems MemoryItem[]
accountingLinks PersonAccountingLink[]
accountingDocuments AccountingDocumentLog[]
asnadLines AccountingAsnadLine[]
openingBalances PartyOpeningBalance[]
cheques Cheque[]
trackingLinks TrackingLink[]
@@ -1747,6 +1749,7 @@ model AccountingConnection {
productLinks ProductAccountingLink[]
documentLogs AccountingDocumentLog[]
balanceCaches AccountingBalanceCache[]
asnadLines AccountingAsnadLine[]
@@unique([organizationId, baseUrl, dbName])
@@index([organizationId, enabled])
@@ -1766,6 +1769,7 @@ model PersonAccountingLink {
linkedAt DateTime @default(now())
lastBalanceSyncedAt DateTime?
balanceCache AccountingBalanceCache?
asnadLines AccountingAsnadLine[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@ -1844,6 +1848,51 @@ model AccountingBalanceCache {
@@index([connectionId])
}
/// اسنپ‌شات ردیف‌های DoListAsnad برای گزارش فروش گروهی
model AccountingAsnadLine {
id String @id @default(cuid())
organizationId String
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
connectionId String
connection AccountingConnection @relation(fields: [connectionId], references: [id], onDelete: Cascade)
personId String?
person Person? @relation(fields: [personId], references: [id], onDelete: SetNull)
linkId String?
link PersonAccountingLink? @relation(fields: [linkId], references: [id], onDelete: SetNull)
moshtariCode Int
/// کلید پایدار برای upsert: ID ته‌حساب یا f:factor|r:radif|t:tarikh|n:no
lineKey String
tahesabId Int?
factorCode String?
shFactor Int?
radif Int?
/// شمسی YYYY-MM-DD
tarikh String
noRaw String @default("")
/// sale | return | purchase | other
kind String @default("other")
jensFelez Int?
noKar String?
vazn Float?
tabdilVazn Float?
mali Float?
count Float?
ayar Float?
mazaneh Float?
fi Float?
sharh1 String?
syncedAt DateTime @default(now())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([connectionId, lineKey])
@@index([organizationId, connectionId, tarikh])
@@index([organizationId, kind])
@@index([personId])
@@index([linkId])
@@index([moshtariCode])
}
model AccountingSyncJob {
id String @id @default(cuid())
organizationId String