Add a small internal warehouse and party balances when Tahesab is off.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-10 22:24:16 +03:30
co-authored by Cursor
parent 55432ff979
commit 212d02f664
19 changed files with 1449 additions and 6 deletions
@@ -0,0 +1,80 @@
-- CreateTable
CREATE TABLE "Warehouse" (
"id" TEXT NOT NULL,
"organizationId" TEXT NOT NULL,
"name" TEXT NOT NULL,
"isDefault" BOOLEAN NOT NULL DEFAULT true,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Warehouse_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "StockMovement" (
"id" TEXT NOT NULL,
"organizationId" TEXT NOT NULL,
"warehouseId" TEXT NOT NULL,
"productId" TEXT NOT NULL,
"type" TEXT NOT NULL,
"quantity" DECIMAL(18,2) NOT NULL,
"note" TEXT,
"invoiceId" TEXT,
"occurredAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "StockMovement_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "PartyOpeningBalance" (
"id" TEXT NOT NULL,
"organizationId" TEXT NOT NULL,
"personId" TEXT NOT NULL,
"amount" DECIMAL(18,2) NOT NULL,
"currency" TEXT NOT NULL DEFAULT 'IRR',
"note" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "PartyOpeningBalance_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE INDEX "Warehouse_organizationId_isDefault_idx" ON "Warehouse"("organizationId", "isDefault");
-- CreateIndex
CREATE INDEX "StockMovement_organizationId_productId_occurredAt_idx" ON "StockMovement"("organizationId", "productId", "occurredAt");
-- CreateIndex
CREATE INDEX "StockMovement_invoiceId_idx" ON "StockMovement"("invoiceId");
-- CreateIndex
CREATE INDEX "StockMovement_warehouseId_idx" ON "StockMovement"("warehouseId");
-- CreateIndex
CREATE UNIQUE INDEX "PartyOpeningBalance_organizationId_personId_key" ON "PartyOpeningBalance"("organizationId", "personId");
-- CreateIndex
CREATE INDEX "PartyOpeningBalance_personId_idx" ON "PartyOpeningBalance"("personId");
-- AddForeignKey
ALTER TABLE "Warehouse" ADD CONSTRAINT "Warehouse_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "StockMovement" ADD CONSTRAINT "StockMovement_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "StockMovement" ADD CONSTRAINT "StockMovement_warehouseId_fkey" FOREIGN KEY ("warehouseId") REFERENCES "Warehouse"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "StockMovement" ADD CONSTRAINT "StockMovement_productId_fkey" FOREIGN KEY ("productId") REFERENCES "Product"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "StockMovement" ADD CONSTRAINT "StockMovement_invoiceId_fkey" FOREIGN KEY ("invoiceId") REFERENCES "Invoice"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "PartyOpeningBalance" ADD CONSTRAINT "PartyOpeningBalance_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "PartyOpeningBalance" ADD CONSTRAINT "PartyOpeningBalance_personId_fkey" FOREIGN KEY ("personId") REFERENCES "Person"("id") ON DELETE CASCADE ON UPDATE CASCADE;
+60
View File
@@ -180,6 +180,9 @@ model Organization {
noteAiSuggestions NoteAiSuggestion[]
accountingConnections AccountingConnection[]
accountingSyncJobs AccountingSyncJob[]
warehouses Warehouse[]
stockMovements StockMovement[]
partyOpenings PartyOpeningBalance[]
}
model User {
@@ -283,6 +286,7 @@ model Person {
memoryItems MemoryItem[]
accountingLinks PersonAccountingLink[]
accountingDocuments AccountingDocumentLog[]
openingBalances PartyOpeningBalance[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@ -545,6 +549,7 @@ model Product {
lineItems DealLineItem[]
quoteLineItems QuoteLineItem[]
invoiceLineItems InvoiceLineItem[]
stockMovements StockMovement[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@ -725,6 +730,7 @@ model Invoice {
lineItems InvoiceLineItem[]
payments Payment[]
installments InvoiceInstallment[]
stockMovements StockMovement[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@ -1210,3 +1216,57 @@ model AccountingSyncJob {
@@index([organizationId, createdAt])
}
/// انبار داخلی — وقتی ته‌حساب وصل نیست
model Warehouse {
id String @id @default(cuid())
organizationId String
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
name String
isDefault Boolean @default(true)
movements StockMovement[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([organizationId, isDefault])
}
/// گردش کالا؛ مقدار مثبت ورود، منفی خروج
model StockMovement {
id String @id @default(cuid())
organizationId String
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
warehouseId String
warehouse Warehouse @relation(fields: [warehouseId], references: [id], onDelete: Cascade)
productId String
product Product @relation(fields: [productId], references: [id], onDelete: Cascade)
/// opening | purchase | sale | credit | adjustment
type String
quantity Decimal @db.Decimal(18, 2)
note String?
invoiceId String?
invoice Invoice? @relation(fields: [invoiceId], references: [id], onDelete: Cascade)
occurredAt DateTime @default(now())
createdAt DateTime @default(now())
@@index([organizationId, productId, occurredAt])
@@index([invoiceId])
@@index([warehouseId])
}
/// مانده اول دوره طرف‌حساب (مثبت = بدهکار ما)
model PartyOpeningBalance {
id String @id @default(cuid())
organizationId String
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
personId String
person Person @relation(fields: [personId], references: [id], onDelete: Cascade)
amount Decimal @db.Decimal(18, 2)
currency String @default("IRR")
note String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([organizationId, personId])
@@index([personId])
}