Add salesperson commissions on issued invoices and a cheque register.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-11 01:09:59 +03:30
co-authored by Cursor
parent 535c428270
commit 9a991fc1f1
22 changed files with 1238 additions and 11 deletions
@@ -0,0 +1,75 @@
-- AlterTable
ALTER TABLE "User" ADD COLUMN "commissionPercent" DECIMAL(8,2) NOT NULL DEFAULT 0;
-- AlterTable
ALTER TABLE "Invoice" ADD COLUMN "commissionPercent" DECIMAL(8,2),
ADD COLUMN "commissionFixedAmount" DECIMAL(18,2);
-- CreateTable
CREATE TABLE "CommissionEntry" (
"id" TEXT NOT NULL,
"organizationId" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"invoiceId" TEXT NOT NULL,
"percent" DECIMAL(8,2) NOT NULL,
"amount" DECIMAL(18,2) NOT NULL,
"currency" TEXT NOT NULL DEFAULT 'IRR',
"status" TEXT NOT NULL DEFAULT 'posted',
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "CommissionEntry_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Cheque" (
"id" TEXT NOT NULL,
"organizationId" TEXT NOT NULL,
"paymentId" TEXT NOT NULL,
"invoiceId" TEXT NOT NULL,
"number" TEXT NOT NULL,
"bank" TEXT NOT NULL,
"dueDate" TIMESTAMP(3) NOT NULL,
"status" TEXT NOT NULL DEFAULT 'pending',
"notes" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Cheque_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "CommissionEntry_invoiceId_key" ON "CommissionEntry"("invoiceId");
-- CreateIndex
CREATE INDEX "CommissionEntry_organizationId_userId_createdAt_idx" ON "CommissionEntry"("organizationId", "userId", "createdAt");
-- CreateIndex
CREATE INDEX "CommissionEntry_status_idx" ON "CommissionEntry"("status");
-- CreateIndex
CREATE UNIQUE INDEX "Cheque_paymentId_key" ON "Cheque"("paymentId");
-- CreateIndex
CREATE INDEX "Cheque_organizationId_status_dueDate_idx" ON "Cheque"("organizationId", "status", "dueDate");
-- CreateIndex
CREATE INDEX "Cheque_invoiceId_idx" ON "Cheque"("invoiceId");
-- AddForeignKey
ALTER TABLE "CommissionEntry" ADD CONSTRAINT "CommissionEntry_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "CommissionEntry" ADD CONSTRAINT "CommissionEntry_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "CommissionEntry" ADD CONSTRAINT "CommissionEntry_invoiceId_fkey" FOREIGN KEY ("invoiceId") REFERENCES "Invoice"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Cheque" ADD CONSTRAINT "Cheque_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Cheque" ADD CONSTRAINT "Cheque_paymentId_fkey" FOREIGN KEY ("paymentId") REFERENCES "Payment"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Cheque" ADD CONSTRAINT "Cheque_invoiceId_fkey" FOREIGN KEY ("invoiceId") REFERENCES "Invoice"("id") ON DELETE CASCADE ON UPDATE CASCADE;
+52
View File
@@ -183,6 +183,8 @@ model Organization {
warehouses Warehouse[]
stockMovements StockMovement[]
partyOpenings PartyOpeningBalance[]
commissionEntries CommissionEntry[]
cheques Cheque[]
}
model User {
@@ -209,6 +211,8 @@ model User {
noteAttachments NoteAttachment[] @relation("NoteAttachmentUploader")
notifications Notification[]
salesGoals SalesGoal[] @relation("SalesGoalUser")
commissionPercent Decimal @default(0) @db.Decimal(8, 2)
commissionEntries CommissionEntry[]
assignedTickets Ticket[] @relation("TicketAssignee")
reportedTickets Ticket[] @relation("TicketReporter")
ticketMessages TicketMessage[] @relation("TicketMessageAuthor")
@@ -731,6 +735,10 @@ model Invoice {
payments Payment[]
installments InvoiceInstallment[]
stockMovements StockMovement[]
commissionPercent Decimal? @db.Decimal(8, 2)
commissionFixedAmount Decimal? @db.Decimal(18, 2)
commissionEntry CommissionEntry?
cheques Cheque[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@ -772,6 +780,7 @@ model Payment {
notes String?
installmentId String? @unique
installment InvoiceInstallment? @relation(fields: [installmentId], references: [id], onDelete: SetNull)
cheque Cheque?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@ -1254,6 +1263,49 @@ model StockMovement {
@@index([warehouseId])
}
/// پورسانت کارشناس بعد از صدور فاکتور
model CommissionEntry {
id String @id @default(cuid())
organizationId String
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
invoiceId String @unique
invoice Invoice @relation(fields: [invoiceId], references: [id], onDelete: Cascade)
percent Decimal @db.Decimal(8, 2)
amount Decimal @db.Decimal(18, 2)
currency String @default("IRR")
/// posted | void
status String @default("posted")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([organizationId, userId, createdAt])
@@index([status])
}
/// چک دریافتی وصل به پرداخت فاکتور
model Cheque {
id String @id @default(cuid())
organizationId String
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
paymentId String @unique
payment Payment @relation(fields: [paymentId], references: [id], onDelete: Cascade)
invoiceId String
invoice Invoice @relation(fields: [invoiceId], references: [id], onDelete: Cascade)
number String
bank String
dueDate DateTime
/// pending | cleared | bounced
status String @default("pending")
notes String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([organizationId, status, dueDate])
@@index([invoiceId])
}
/// مانده اول دوره طرف‌حساب (مثبت = بدهکار ما)
model PartyOpeningBalance {
id String @id @default(cuid())