feat: gate treasury as an org module and group money inputs

Link optional invoice and cheque settlements to cash accounts, and let superadmin enable the finance module per organization.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-18 19:33:09 +03:30
co-authored by Cursor
parent ab538b8304
commit 8981a552fc
25 changed files with 509 additions and 33 deletions
+41
View File
@@ -211,6 +211,8 @@ model Organization {
financialPayrolls FinancialPayroll[]
financialRecurringItems FinancialRecurringItem[]
financialReconciliations FinancialReconciliation[]
financialAuditLogs FinancialAuditLog[]
financialAttachments FinancialAttachment[]
wooCommerceConnections WooCommerceConnection[]
montifyConnections MontifyConnection[]
voipConnections VoipConnection[]
@@ -1181,6 +1183,8 @@ model Payment {
method PaymentMethod @default(transfer)
paidAt DateTime @default(now())
notes String?
/// اگر پر باشد، این پرداخت یک‌بار در صندوق نشسته است
financialAccountId String?
installmentId String? @unique
installment InvoiceInstallment? @relation(fields: [installmentId], references: [id], onDelete: SetNull)
cheque Cheque?
@@ -1840,6 +1844,8 @@ model Cheque {
/// in = دریافتی، out = پرداختی
direction String @default("in")
reminderNotifiedAt DateTime?
/// حساب صندوق برای لحظهٔ وصول؛ تا قبل از وصول موجودی را عوض نمی‌کند
financialAccountId String?
notes String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@ -2071,6 +2077,7 @@ model FinancialDocument {
voidedAt DateTime?
voidReason String?
movements FinancialMovement[]
attachments FinancialAttachment[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@ -2094,6 +2101,8 @@ model FinancialMovement {
installment FinancialInstallment? @relation(fields: [installmentId], references: [id], onDelete: SetNull)
payrollId String?
payroll FinancialPayroll? @relation(fields: [payrollId], references: [id], onDelete: SetNull)
paymentId String?
chequeId String?
/// in | out
direction String
amount Decimal @db.Decimal(18, 2)
@@ -2113,6 +2122,38 @@ model FinancialMovement {
@@index([receivableId])
@@index([installmentId])
@@index([payrollId])
@@index([paymentId])
@@index([chequeId])
}
model FinancialAuditLog {
id String @id @default(cuid())
organizationId String
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
entityType String
entityId String
action String
before Json?
after Json?
actorUserId String?
createdAt DateTime @default(now())
@@index([organizationId, entityType, entityId, createdAt])
}
model FinancialAttachment {
id String @id @default(cuid())
organizationId String
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
documentId String
document FinancialDocument @relation(fields: [documentId], references: [id], onDelete: Cascade)
fileName String
mimeType String
storageKey String
createdById String?
createdAt DateTime @default(now())
@@index([documentId])
}
model FinancialPayroll {