Stock is scoped to a catalog + cost centers only, per direction that physical GRV/stock-take/recipe transactions belong in an external system (Matrix), not this accounting app. Stock Control/GRN/Variance/ PPV GL accounts are now plain postable accounts rather than locked control accounts. Also fixes session loss on page refresh: auth stores now persist to localStorage, and ProtectedRoute waits for rehydration before deciding to redirect to login. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JWqiUSojMLUoN7mrJqdEbN
286 lines
11 KiB
SQL
286 lines
11 KiB
SQL
-- CreateEnum
|
|
CREATE TYPE "CostingMethod" AS ENUM ('MANUAL', 'LATEST', 'MOVING_AVERAGE');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "StockMovementType" AS ENUM ('RECEIPT', 'ISSUE', 'TRANSFER_IN', 'TRANSFER_OUT', 'CONSUMPTION', 'PRODUCTION_IN', 'PRODUCTION_OUT', 'ADJUSTMENT_IN', 'ADJUSTMENT_OUT');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "StockDocumentStatus" AS ENUM ('DRAFT', 'POSTED', 'VOID');
|
|
|
|
-- AlterEnum
|
|
ALTER TYPE "ControlAccountType" ADD VALUE 'GRN';
|
|
|
|
-- DropForeignKey
|
|
ALTER TABLE "APInvoiceLine" DROP CONSTRAINT "APInvoiceLine_expenseGLAccountId_fkey";
|
|
|
|
-- AlterTable
|
|
ALTER TABLE "APInvoiceLine" ADD COLUMN "grvLineId" INTEGER,
|
|
ALTER COLUMN "expenseGLAccountId" DROP NOT NULL;
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "Warehouse" (
|
|
"id" SERIAL NOT NULL,
|
|
"code" TEXT NOT NULL,
|
|
"name" TEXT NOT NULL,
|
|
"branchSegmentValueId" INTEGER NOT NULL,
|
|
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
|
|
|
CONSTRAINT "Warehouse_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "StockItem" (
|
|
"id" SERIAL NOT NULL,
|
|
"code" TEXT NOT NULL,
|
|
"name" TEXT NOT NULL,
|
|
"unitOfMeasure" TEXT NOT NULL,
|
|
"costingMethod" "CostingMethod" NOT NULL DEFAULT 'MOVING_AVERAGE',
|
|
"manualCost" DECIMAL(18,4),
|
|
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "StockItem_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "StockLevel" (
|
|
"id" SERIAL NOT NULL,
|
|
"itemId" INTEGER NOT NULL,
|
|
"warehouseId" INTEGER NOT NULL,
|
|
"quantityOnHand" DECIMAL(18,4) NOT NULL DEFAULT 0,
|
|
"averageCost" DECIMAL(18,4) NOT NULL DEFAULT 0,
|
|
"lastCost" DECIMAL(18,4) NOT NULL DEFAULT 0,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "StockLevel_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "StockMovement" (
|
|
"id" SERIAL NOT NULL,
|
|
"itemId" INTEGER NOT NULL,
|
|
"warehouseId" INTEGER NOT NULL,
|
|
"movementType" "StockMovementType" NOT NULL,
|
|
"quantity" DECIMAL(18,4) NOT NULL,
|
|
"unitCost" DECIMAL(18,4) NOT NULL,
|
|
"totalCost" DECIMAL(18,2) NOT NULL,
|
|
"movementDate" TIMESTAMP(3) NOT NULL,
|
|
"description" TEXT,
|
|
"branchSegmentValueId" INTEGER NOT NULL,
|
|
"sourceType" TEXT,
|
|
"sourceId" INTEGER,
|
|
"journalEntryId" INTEGER,
|
|
"createdById" INTEGER NOT NULL,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "StockMovement_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "Recipe" (
|
|
"id" SERIAL NOT NULL,
|
|
"code" TEXT NOT NULL,
|
|
"name" TEXT NOT NULL,
|
|
"outputItemId" INTEGER NOT NULL,
|
|
"yieldQuantity" DECIMAL(18,4) NOT NULL,
|
|
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
|
|
|
CONSTRAINT "Recipe_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "RecipeComponent" (
|
|
"id" SERIAL NOT NULL,
|
|
"recipeId" INTEGER NOT NULL,
|
|
"componentItemId" INTEGER NOT NULL,
|
|
"quantity" DECIMAL(18,4) NOT NULL,
|
|
|
|
CONSTRAINT "RecipeComponent_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "StockAdjustment" (
|
|
"id" SERIAL NOT NULL,
|
|
"adjustmentNumber" TEXT NOT NULL,
|
|
"warehouseId" INTEGER NOT NULL,
|
|
"branchSegmentValueId" INTEGER NOT NULL,
|
|
"adjustmentDate" TIMESTAMP(3) NOT NULL,
|
|
"reference" TEXT,
|
|
"status" "StockDocumentStatus" NOT NULL DEFAULT 'DRAFT',
|
|
"journalEntryId" INTEGER,
|
|
"createdById" INTEGER NOT NULL,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "StockAdjustment_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "StockAdjustmentLine" (
|
|
"id" SERIAL NOT NULL,
|
|
"adjustmentId" INTEGER NOT NULL,
|
|
"itemId" INTEGER NOT NULL,
|
|
"systemQuantity" DECIMAL(18,4) NOT NULL,
|
|
"countedQuantity" DECIMAL(18,4) NOT NULL,
|
|
"unitCost" DECIMAL(18,4) NOT NULL,
|
|
"varianceValue" DECIMAL(18,2) NOT NULL,
|
|
|
|
CONSTRAINT "StockAdjustmentLine_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "GoodsReceivedVoucher" (
|
|
"id" SERIAL NOT NULL,
|
|
"grvNumber" TEXT NOT NULL,
|
|
"supplierId" INTEGER NOT NULL,
|
|
"warehouseId" INTEGER NOT NULL,
|
|
"branchSegmentValueId" INTEGER NOT NULL,
|
|
"grvDate" TIMESTAMP(3) NOT NULL,
|
|
"reference" TEXT,
|
|
"status" "StockDocumentStatus" NOT NULL DEFAULT 'DRAFT',
|
|
"journalEntryId" INTEGER,
|
|
"createdById" INTEGER NOT NULL,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "GoodsReceivedVoucher_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "GoodsReceivedVoucherLine" (
|
|
"id" SERIAL NOT NULL,
|
|
"grvId" INTEGER NOT NULL,
|
|
"itemId" INTEGER NOT NULL,
|
|
"quantity" DECIMAL(18,4) NOT NULL,
|
|
"unitPrice" DECIMAL(18,4) NOT NULL,
|
|
"lineTotal" DECIMAL(18,2) NOT NULL,
|
|
"matchedQuantity" DECIMAL(18,4) NOT NULL DEFAULT 0,
|
|
|
|
CONSTRAINT "GoodsReceivedVoucherLine_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "Warehouse_code_key" ON "Warehouse"("code");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "Warehouse_branchSegmentValueId_idx" ON "Warehouse"("branchSegmentValueId");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "StockItem_code_key" ON "StockItem"("code");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "StockLevel_itemId_warehouseId_key" ON "StockLevel"("itemId", "warehouseId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "StockMovement_itemId_warehouseId_idx" ON "StockMovement"("itemId", "warehouseId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "StockMovement_sourceType_sourceId_idx" ON "StockMovement"("sourceType", "sourceId");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "Recipe_code_key" ON "Recipe"("code");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "Recipe_outputItemId_key" ON "Recipe"("outputItemId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "RecipeComponent_recipeId_idx" ON "RecipeComponent"("recipeId");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "StockAdjustment_adjustmentNumber_key" ON "StockAdjustment"("adjustmentNumber");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "StockAdjustment_warehouseId_idx" ON "StockAdjustment"("warehouseId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "StockAdjustment_branchSegmentValueId_idx" ON "StockAdjustment"("branchSegmentValueId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "StockAdjustment_status_idx" ON "StockAdjustment"("status");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "StockAdjustmentLine_adjustmentId_idx" ON "StockAdjustmentLine"("adjustmentId");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "GoodsReceivedVoucher_grvNumber_key" ON "GoodsReceivedVoucher"("grvNumber");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "GoodsReceivedVoucher_supplierId_idx" ON "GoodsReceivedVoucher"("supplierId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "GoodsReceivedVoucher_warehouseId_idx" ON "GoodsReceivedVoucher"("warehouseId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "GoodsReceivedVoucher_branchSegmentValueId_idx" ON "GoodsReceivedVoucher"("branchSegmentValueId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "GoodsReceivedVoucher_status_idx" ON "GoodsReceivedVoucher"("status");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "GoodsReceivedVoucherLine_grvId_idx" ON "GoodsReceivedVoucherLine"("grvId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "APInvoiceLine_grvLineId_idx" ON "APInvoiceLine"("grvLineId");
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "JournalEntryLine" ADD CONSTRAINT "JournalEntryLine_stockMovementId_fkey" FOREIGN KEY ("stockMovementId") REFERENCES "StockMovement"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "APInvoiceLine" ADD CONSTRAINT "APInvoiceLine_expenseGLAccountId_fkey" FOREIGN KEY ("expenseGLAccountId") REFERENCES "GLAccount"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "APInvoiceLine" ADD CONSTRAINT "APInvoiceLine_grvLineId_fkey" FOREIGN KEY ("grvLineId") REFERENCES "GoodsReceivedVoucherLine"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Warehouse" ADD CONSTRAINT "Warehouse_branchSegmentValueId_fkey" FOREIGN KEY ("branchSegmentValueId") REFERENCES "AccountSegmentValue"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "StockLevel" ADD CONSTRAINT "StockLevel_itemId_fkey" FOREIGN KEY ("itemId") REFERENCES "StockItem"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "StockLevel" ADD CONSTRAINT "StockLevel_warehouseId_fkey" FOREIGN KEY ("warehouseId") REFERENCES "Warehouse"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "StockMovement" ADD CONSTRAINT "StockMovement_itemId_fkey" FOREIGN KEY ("itemId") REFERENCES "StockItem"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "StockMovement" ADD CONSTRAINT "StockMovement_warehouseId_fkey" FOREIGN KEY ("warehouseId") REFERENCES "Warehouse"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "StockMovement" ADD CONSTRAINT "StockMovement_createdById_fkey" FOREIGN KEY ("createdById") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Recipe" ADD CONSTRAINT "Recipe_outputItemId_fkey" FOREIGN KEY ("outputItemId") REFERENCES "StockItem"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "RecipeComponent" ADD CONSTRAINT "RecipeComponent_recipeId_fkey" FOREIGN KEY ("recipeId") REFERENCES "Recipe"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "RecipeComponent" ADD CONSTRAINT "RecipeComponent_componentItemId_fkey" FOREIGN KEY ("componentItemId") REFERENCES "StockItem"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "StockAdjustment" ADD CONSTRAINT "StockAdjustment_warehouseId_fkey" FOREIGN KEY ("warehouseId") REFERENCES "Warehouse"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "StockAdjustment" ADD CONSTRAINT "StockAdjustment_createdById_fkey" FOREIGN KEY ("createdById") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "StockAdjustmentLine" ADD CONSTRAINT "StockAdjustmentLine_adjustmentId_fkey" FOREIGN KEY ("adjustmentId") REFERENCES "StockAdjustment"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "StockAdjustmentLine" ADD CONSTRAINT "StockAdjustmentLine_itemId_fkey" FOREIGN KEY ("itemId") REFERENCES "StockItem"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "GoodsReceivedVoucher" ADD CONSTRAINT "GoodsReceivedVoucher_supplierId_fkey" FOREIGN KEY ("supplierId") REFERENCES "Supplier"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "GoodsReceivedVoucher" ADD CONSTRAINT "GoodsReceivedVoucher_warehouseId_fkey" FOREIGN KEY ("warehouseId") REFERENCES "Warehouse"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "GoodsReceivedVoucher" ADD CONSTRAINT "GoodsReceivedVoucher_createdById_fkey" FOREIGN KEY ("createdById") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "GoodsReceivedVoucherLine" ADD CONSTRAINT "GoodsReceivedVoucherLine_grvId_fkey" FOREIGN KEY ("grvId") REFERENCES "GoodsReceivedVoucher"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "GoodsReceivedVoucherLine" ADD CONSTRAINT "GoodsReceivedVoucherLine_itemId_fkey" FOREIGN KEY ("itemId") REFERENCES "StockItem"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|