feat(database): initialize database schema and triggers
- Created initial database schema with tables for Users, Roles, Products, and related entities. - Added foreign key constraints to maintain data integrity across tables. - Implemented triggers for managing stock movements on insert, update, and delete operations. - Developed scripts to dump existing triggers and pull trigger definitions from the database.
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
"class-transformer": "^0.5.1",
|
||||
"class-validator": "^0.14.3",
|
||||
"dotenv": "^17.2.3",
|
||||
"mysql2": "^3.15.3",
|
||||
"reflect-metadata": "^0.2.2",
|
||||
"rxjs": "^7.8.1"
|
||||
},
|
||||
@@ -64,9 +65,11 @@
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "nest build",
|
||||
"dump-triggers": "tsx scripts/dump-triggers.ts",
|
||||
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
|
||||
"generate:permissions": "tsx scripts/generate-permissions.ts",
|
||||
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
|
||||
"pullDBTriggers": "tsx scripts/pull-triggers.ts",
|
||||
"start": "nest start",
|
||||
"start:debug": "nest start --debug --watch",
|
||||
"start:dev": "nest start --watch",
|
||||
|
||||
Generated
+3
@@ -35,6 +35,9 @@ importers:
|
||||
dotenv:
|
||||
specifier: ^17.2.3
|
||||
version: 17.2.3
|
||||
mysql2:
|
||||
specifier: ^3.15.3
|
||||
version: 3.15.3
|
||||
reflect-metadata:
|
||||
specifier: ^0.2.2
|
||||
version: 0.2.2
|
||||
|
||||
@@ -1,172 +0,0 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE `Users` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`mobileNumber` CHAR(11) NOT NULL,
|
||||
`password` VARCHAR(191) NOT NULL,
|
||||
`firstName` VARCHAR(191) NOT NULL,
|
||||
`lastName` VARCHAR(191) NOT NULL,
|
||||
`roleId` INTEGER NOT NULL,
|
||||
|
||||
UNIQUE INDEX `Users_mobileNumber_key`(`mobileNumber`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Roles` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(100) NOT NULL,
|
||||
`description` TEXT NULL,
|
||||
`permissions` JSON NULL,
|
||||
`createdAt` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`updatedAt` TIMESTAMP(0) NOT NULL,
|
||||
`deletedAt` TIMESTAMP(0) NULL,
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Products` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(255) NOT NULL,
|
||||
`description` TEXT NULL,
|
||||
`sku` VARCHAR(100) NULL,
|
||||
`barcode` VARCHAR(100) NULL,
|
||||
`imageUrl` VARCHAR(255) NULL,
|
||||
`attachmentId` BIGINT UNSIGNED NULL,
|
||||
`unit` VARCHAR(10) NOT NULL,
|
||||
`discount` DECIMAL(10, 2) NOT NULL DEFAULT 0.00,
|
||||
`quantity` DECIMAL(10, 2) NOT NULL DEFAULT 0.00,
|
||||
`alertQuantity` DECIMAL(10, 2) NOT NULL DEFAULT 5.00,
|
||||
`isActive` BOOLEAN NOT NULL DEFAULT true,
|
||||
`isFeatured` BOOLEAN NOT NULL DEFAULT false,
|
||||
`createdAt` TIMESTAMP(0) NULL,
|
||||
`updatedAt` TIMESTAMP(0) NULL,
|
||||
`deletedAt` TIMESTAMP(0) NULL,
|
||||
`productInfoId` INTEGER NOT NULL,
|
||||
|
||||
UNIQUE INDEX `products_sku_unique`(`sku`),
|
||||
UNIQUE INDEX `products_barcode_unique`(`barcode`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Product_info` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(255) NOT NULL,
|
||||
`description` TEXT NULL,
|
||||
`productType` VARCHAR(50) NULL DEFAULT 'simple',
|
||||
`metaData` JSON NULL,
|
||||
`createdAt` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`updatedAt` TIMESTAMP(0) NOT NULL,
|
||||
`deletedAt` TIMESTAMP(0) NULL,
|
||||
`brandId` INTEGER NULL,
|
||||
`categoryId` INTEGER NULL,
|
||||
`vendorId` INTEGER NOT NULL,
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Product_brands` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(100) NOT NULL,
|
||||
`description` TEXT NULL,
|
||||
`imageUrl` VARCHAR(255) NULL,
|
||||
`createdAt` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`updatedAt` TIMESTAMP(0) NOT NULL,
|
||||
`deletedAt` TIMESTAMP(0) NULL,
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Product_categories` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(100) NOT NULL,
|
||||
`description` TEXT NULL,
|
||||
`imageUrl` VARCHAR(255) NULL,
|
||||
`createdAt` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`updatedAt` TIMESTAMP(0) NOT NULL,
|
||||
`deletedAt` TIMESTAMP(0) NULL,
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Vendors` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`firstName` VARCHAR(255) NOT NULL,
|
||||
`lastName` VARCHAR(255) NOT NULL,
|
||||
`email` VARCHAR(255) NULL,
|
||||
`mobileNumber` CHAR(11) NOT NULL,
|
||||
`address` TEXT NULL,
|
||||
`city` VARCHAR(100) NULL,
|
||||
`state` VARCHAR(100) NULL,
|
||||
`country` VARCHAR(100) NULL,
|
||||
`isActive` BOOLEAN NOT NULL DEFAULT true,
|
||||
`createdAt` TIMESTAMP(0) NULL,
|
||||
`updatedAt` TIMESTAMP(0) NULL,
|
||||
`deletedAt` TIMESTAMP(0) NULL,
|
||||
|
||||
UNIQUE INDEX `Vendors_mobileNumber_key`(`mobileNumber`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Customers` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`firstName` VARCHAR(255) NOT NULL,
|
||||
`lastName` VARCHAR(255) NOT NULL,
|
||||
`email` VARCHAR(255) NULL,
|
||||
`mobileNumber` CHAR(11) NOT NULL,
|
||||
`address` TEXT NULL,
|
||||
`city` VARCHAR(100) NULL,
|
||||
`state` VARCHAR(100) NULL,
|
||||
`country` VARCHAR(100) NULL,
|
||||
`isActive` BOOLEAN NOT NULL DEFAULT true,
|
||||
`createdAt` TIMESTAMP(0) NULL,
|
||||
`updatedAt` TIMESTAMP(0) NULL,
|
||||
`deletedAt` TIMESTAMP(0) NULL,
|
||||
|
||||
UNIQUE INDEX `Customers_mobileNumber_key`(`mobileNumber`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Inventories` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(255) NOT NULL,
|
||||
`location` VARCHAR(255) NULL,
|
||||
`isActive` BOOLEAN NOT NULL DEFAULT true,
|
||||
`createdAt` TIMESTAMP(0) NOT NULL,
|
||||
`updatedAt` TIMESTAMP(0) NOT NULL,
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Stores` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(255) NOT NULL,
|
||||
`location` VARCHAR(255) NULL,
|
||||
`isActive` BOOLEAN NOT NULL DEFAULT true,
|
||||
`createdAt` TIMESTAMP(0) NOT NULL,
|
||||
`updatedAt` TIMESTAMP(0) NOT NULL,
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Users` ADD CONSTRAINT `Users_roleId_fkey` FOREIGN KEY (`roleId`) REFERENCES `Roles`(`id`) ON DELETE RESTRICT ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Products` ADD CONSTRAINT `Products_productInfoId_fkey` FOREIGN KEY (`productInfoId`) REFERENCES `Product_info`(`id`) ON DELETE RESTRICT ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Product_info` ADD CONSTRAINT `Product_info_brandId_fkey` FOREIGN KEY (`brandId`) REFERENCES `Product_brands`(`id`) ON DELETE SET NULL ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Product_info` ADD CONSTRAINT `Product_info_categoryId_fkey` FOREIGN KEY (`categoryId`) REFERENCES `Product_categories`(`id`) ON DELETE SET NULL ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Product_info` ADD CONSTRAINT `Product_info_vendorId_fkey` FOREIGN KEY (`vendorId`) REFERENCES `Vendors`(`id`) ON DELETE RESTRICT ON UPDATE NO ACTION;
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `vendorId` on the `Product_info` table. All the data in the column will be lost.
|
||||
- You are about to drop the `Vendors` table. If the table is not empty, all the data it contains will be lost.
|
||||
- Added the required column `supplierId` to the `Product_info` table without a default value. This is not possible if the table is not empty.
|
||||
|
||||
*/
|
||||
-- DropForeignKey
|
||||
ALTER TABLE `Product_info` DROP FOREIGN KEY `Product_info_vendorId_fkey`;
|
||||
|
||||
-- DropIndex
|
||||
DROP INDEX `Product_info_vendorId_fkey` ON `Product_info`;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE `Product_info` DROP COLUMN `vendorId`,
|
||||
ADD COLUMN `supplierId` INTEGER NOT NULL;
|
||||
|
||||
-- DropTable
|
||||
DROP TABLE `Vendors`;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Suppliers` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`firstName` VARCHAR(255) NOT NULL,
|
||||
`lastName` VARCHAR(255) NOT NULL,
|
||||
`email` VARCHAR(255) NULL,
|
||||
`mobileNumber` CHAR(11) NOT NULL,
|
||||
`address` TEXT NULL,
|
||||
`city` VARCHAR(100) NULL,
|
||||
`state` VARCHAR(100) NULL,
|
||||
`country` VARCHAR(100) NULL,
|
||||
`isActive` BOOLEAN NOT NULL DEFAULT true,
|
||||
`createdAt` TIMESTAMP(0) NULL,
|
||||
`updatedAt` TIMESTAMP(0) NULL,
|
||||
`deletedAt` TIMESTAMP(0) NULL,
|
||||
|
||||
UNIQUE INDEX `Suppliers_mobileNumber_key`(`mobileNumber`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Product_info` ADD CONSTRAINT `Product_info_supplierId_fkey` FOREIGN KEY (`supplierId`) REFERENCES `Suppliers`(`id`) ON DELETE RESTRICT ON UPDATE NO ACTION;
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `alertQuantity` on the `Products` table. All the data in the column will be lost.
|
||||
- You are about to drop the column `attachmentId` on the `Products` table. All the data in the column will be lost.
|
||||
- You are about to drop the column `discount` on the `Products` table. All the data in the column will be lost.
|
||||
- You are about to drop the column `imageUrl` on the `Products` table. All the data in the column will be lost.
|
||||
- You are about to drop the column `isActive` on the `Products` table. All the data in the column will be lost.
|
||||
- You are about to drop the column `isFeatured` on the `Products` table. All the data in the column will be lost.
|
||||
- You are about to drop the column `productInfoId` on the `Products` table. All the data in the column will be lost.
|
||||
- You are about to drop the column `quantity` on the `Products` table. All the data in the column will be lost.
|
||||
- You are about to drop the column `unit` on the `Products` table. All the data in the column will be lost.
|
||||
- You are about to drop the `Product_info` table. If the table is not empty, all the data it contains will be lost.
|
||||
- Made the column `createdAt` on table `Products` required. This step will fail if there are existing NULL values in that column.
|
||||
- Made the column `updatedAt` on table `Products` required. This step will fail if there are existing NULL values in that column.
|
||||
|
||||
*/
|
||||
-- DropForeignKey
|
||||
ALTER TABLE `Product_info` DROP FOREIGN KEY `Product_info_brandId_fkey`;
|
||||
|
||||
-- DropForeignKey
|
||||
ALTER TABLE `Product_info` DROP FOREIGN KEY `Product_info_categoryId_fkey`;
|
||||
|
||||
-- DropForeignKey
|
||||
ALTER TABLE `Product_info` DROP FOREIGN KEY `Product_info_supplierId_fkey`;
|
||||
|
||||
-- DropForeignKey
|
||||
ALTER TABLE `Products` DROP FOREIGN KEY `Products_productInfoId_fkey`;
|
||||
|
||||
-- DropIndex
|
||||
DROP INDEX `Products_productInfoId_fkey` ON `Products`;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE `Products` DROP COLUMN `alertQuantity`,
|
||||
DROP COLUMN `attachmentId`,
|
||||
DROP COLUMN `discount`,
|
||||
DROP COLUMN `imageUrl`,
|
||||
DROP COLUMN `isActive`,
|
||||
DROP COLUMN `isFeatured`,
|
||||
DROP COLUMN `productInfoId`,
|
||||
DROP COLUMN `quantity`,
|
||||
DROP COLUMN `unit`,
|
||||
ADD COLUMN `brandId` INTEGER NULL,
|
||||
ADD COLUMN `categoryId` INTEGER NULL,
|
||||
ADD COLUMN `metaData` JSON NULL,
|
||||
ADD COLUMN `productType` VARCHAR(50) NULL DEFAULT 'simple',
|
||||
MODIFY `createdAt` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
MODIFY `updatedAt` TIMESTAMP(0) NOT NULL;
|
||||
|
||||
-- DropTable
|
||||
DROP TABLE `Product_info`;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Product_Variants` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(255) NOT NULL,
|
||||
`basePrice` DECIMAL(10, 2) NOT NULL,
|
||||
`salePrice` DECIMAL(10, 2) NOT NULL,
|
||||
`description` TEXT NULL,
|
||||
`barcode` VARCHAR(100) NULL,
|
||||
`imageUrl` VARCHAR(255) NULL,
|
||||
`unit` VARCHAR(10) NULL,
|
||||
`quantity` DECIMAL(10, 2) NULL DEFAULT 0.00,
|
||||
`alertQuantity` DECIMAL(10, 2) NULL DEFAULT 5.00,
|
||||
`isActive` BOOLEAN NOT NULL DEFAULT true,
|
||||
`isFeatured` BOOLEAN NOT NULL DEFAULT false,
|
||||
`createdAt` TIMESTAMP(0) NULL,
|
||||
`updatedAt` TIMESTAMP(0) NULL,
|
||||
`deletedAt` TIMESTAMP(0) NULL,
|
||||
`productId` INTEGER NOT NULL,
|
||||
|
||||
UNIQUE INDEX `products_barcode_unique`(`barcode`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Product_Variants` ADD CONSTRAINT `Product_Variants_productId_fkey` FOREIGN KEY (`productId`) REFERENCES `Products`(`id`) ON DELETE RESTRICT ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Products` ADD CONSTRAINT `Products_brandId_fkey` FOREIGN KEY (`brandId`) REFERENCES `Product_brands`(`id`) ON DELETE SET NULL ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Products` ADD CONSTRAINT `Products_categoryId_fkey` FOREIGN KEY (`categoryId`) REFERENCES `Product_categories`(`id`) ON DELETE SET NULL ON UPDATE NO ACTION;
|
||||
@@ -1,10 +0,0 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `metaData` on the `Products` table. All the data in the column will be lost.
|
||||
- You are about to drop the column `productType` on the `Products` table. All the data in the column will be lost.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE `Products` DROP COLUMN `metaData`,
|
||||
DROP COLUMN `productType`;
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the `StockMovementsView` table. If the table is not empty, all the data it contains will be lost.
|
||||
- You are about to drop the `Stock_View` table. If the table is not empty, all the data it contains will be lost.
|
||||
- You are about to drop the `Total_Stock_View` table. If the table is not empty, all the data it contains will be lost.
|
||||
- You are about to drop the `stock_movements_view` table. If the table is not empty, all the data it contains will be lost.
|
||||
|
||||
*/
|
||||
-- DropTable
|
||||
DROP TABLE `StockMovementsView`;
|
||||
|
||||
-- DropTable
|
||||
DROP TABLE `Stock_View`;
|
||||
|
||||
-- DropTable
|
||||
DROP TABLE `Total_Stock_View`;
|
||||
|
||||
-- DropTable
|
||||
DROP TABLE `stock_movements_view`;
|
||||
@@ -1,13 +0,0 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- The primary key for the `stock_balance` table will be changed. If it partially fails, the table could be left without primary key constraint.
|
||||
- You are about to drop the column `itemId` on the `stock_balance` table. All the data in the column will be lost.
|
||||
- Added the required column `ProductId` to the `stock_balance` table without a default value. This is not possible if the table is not empty.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE `stock_balance` DROP PRIMARY KEY,
|
||||
DROP COLUMN `itemId`,
|
||||
ADD COLUMN `ProductId` INTEGER NOT NULL,
|
||||
ADD PRIMARY KEY (`ProductId`);
|
||||
@@ -1,9 +0,0 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- Added the required column `avgCost` to the `Stock_Movements` table without a default value. This is not possible if the table is not empty.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE `Stock_Movements` ADD COLUMN `avgCost` DECIMAL(10, 2) NOT NULL;
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- Added the required column `avgCost` to the `stock_balance` table without a default value. This is not possible if the table is not empty.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE `stock_balance` ADD COLUMN `avgCost` DECIMAL(65, 30) NOT NULL;
|
||||
|
||||
+203
-81
@@ -1,39 +1,168 @@
|
||||
/*
|
||||
Warnings:
|
||||
-- CreateTable
|
||||
CREATE TABLE `Users` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`mobileNumber` CHAR(11) NOT NULL,
|
||||
`password` VARCHAR(191) NOT NULL,
|
||||
`firstName` VARCHAR(191) NOT NULL,
|
||||
`lastName` VARCHAR(191) NOT NULL,
|
||||
`roleId` INTEGER NOT NULL,
|
||||
`createdAt` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`deletedAt` TIMESTAMP(0) NULL,
|
||||
`updatedAt` TIMESTAMP(0) NOT NULL,
|
||||
|
||||
- Made the column `createdAt` on table `Customers` required. This step will fail if there are existing NULL values in that column.
|
||||
- Made the column `updatedAt` on table `Customers` required. This step will fail if there are existing NULL values in that column.
|
||||
- Made the column `createdAt` on table `Product_Variants` required. This step will fail if there are existing NULL values in that column.
|
||||
- Made the column `updatedAt` on table `Product_Variants` required. This step will fail if there are existing NULL values in that column.
|
||||
- Made the column `createdAt` on table `Suppliers` required. This step will fail if there are existing NULL values in that column.
|
||||
- Made the column `updatedAt` on table `Suppliers` required. This step will fail if there are existing NULL values in that column.
|
||||
- Added the required column `updatedAt` to the `Users` table without a default value. This is not possible if the table is not empty.
|
||||
UNIQUE INDEX `Users_mobileNumber_key`(`mobileNumber`),
|
||||
INDEX `Users_roleId_fkey`(`roleId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE `Customers` MODIFY `createdAt` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
MODIFY `updatedAt` TIMESTAMP(0) NOT NULL;
|
||||
-- CreateTable
|
||||
CREATE TABLE `Roles` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(100) NOT NULL,
|
||||
`description` TEXT NULL,
|
||||
`permissions` JSON NULL,
|
||||
`createdAt` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`updatedAt` TIMESTAMP(0) NOT NULL,
|
||||
`deletedAt` TIMESTAMP(0) NULL,
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE `Inventories` ADD COLUMN `deletedAt` TIMESTAMP(0) NULL,
|
||||
MODIFY `createdAt` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0);
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE `Product_Variants` MODIFY `createdAt` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
MODIFY `updatedAt` TIMESTAMP(0) NOT NULL;
|
||||
-- CreateTable
|
||||
CREATE TABLE `Product_Variants` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(255) NOT NULL,
|
||||
`basePrice` DECIMAL(10, 2) NOT NULL,
|
||||
`salePrice` DECIMAL(10, 2) NOT NULL,
|
||||
`description` TEXT NULL,
|
||||
`barcode` VARCHAR(100) NULL,
|
||||
`imageUrl` VARCHAR(255) NULL,
|
||||
`unit` VARCHAR(10) NULL,
|
||||
`quantity` DECIMAL(10, 2) NULL DEFAULT 0.00,
|
||||
`alertQuantity` DECIMAL(10, 2) NULL DEFAULT 5.00,
|
||||
`isActive` BOOLEAN NOT NULL DEFAULT true,
|
||||
`isFeatured` BOOLEAN NOT NULL DEFAULT false,
|
||||
`createdAt` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`updatedAt` TIMESTAMP(0) NOT NULL,
|
||||
`deletedAt` TIMESTAMP(0) NULL,
|
||||
`productId` INTEGER NOT NULL,
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE `Stores` ADD COLUMN `deletedAt` TIMESTAMP(0) NULL,
|
||||
MODIFY `createdAt` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0);
|
||||
UNIQUE INDEX `products_barcode_unique`(`barcode`),
|
||||
INDEX `Product_Variants_productId_fkey`(`productId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE `Suppliers` MODIFY `createdAt` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
MODIFY `updatedAt` TIMESTAMP(0) NOT NULL;
|
||||
-- CreateTable
|
||||
CREATE TABLE `Products` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(255) NOT NULL,
|
||||
`description` TEXT NULL,
|
||||
`sku` VARCHAR(100) NULL,
|
||||
`barcode` VARCHAR(100) NULL,
|
||||
`createdAt` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`updatedAt` TIMESTAMP(0) NOT NULL,
|
||||
`deletedAt` TIMESTAMP(0) NULL,
|
||||
`brandId` INTEGER NULL,
|
||||
`categoryId` INTEGER NULL,
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE `Users` ADD COLUMN `createdAt` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
ADD COLUMN `deletedAt` TIMESTAMP(0) NULL,
|
||||
ADD COLUMN `updatedAt` TIMESTAMP(0) NOT NULL;
|
||||
UNIQUE INDEX `products_sku_unique`(`sku`),
|
||||
UNIQUE INDEX `products_barcode_unique`(`barcode`),
|
||||
INDEX `Products_brandId_fkey`(`brandId`),
|
||||
INDEX `Products_categoryId_fkey`(`categoryId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Product_brands` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(100) NOT NULL,
|
||||
`description` TEXT NULL,
|
||||
`imageUrl` VARCHAR(255) NULL,
|
||||
`createdAt` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`updatedAt` TIMESTAMP(0) NOT NULL,
|
||||
`deletedAt` TIMESTAMP(0) NULL,
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Product_categories` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(100) NOT NULL,
|
||||
`description` TEXT NULL,
|
||||
`imageUrl` VARCHAR(255) NULL,
|
||||
`createdAt` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`updatedAt` TIMESTAMP(0) NOT NULL,
|
||||
`deletedAt` TIMESTAMP(0) NULL,
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Suppliers` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`firstName` VARCHAR(255) NOT NULL,
|
||||
`lastName` VARCHAR(255) NOT NULL,
|
||||
`email` VARCHAR(255) NULL,
|
||||
`mobileNumber` CHAR(11) NOT NULL,
|
||||
`address` TEXT NULL,
|
||||
`city` VARCHAR(100) NULL,
|
||||
`state` VARCHAR(100) NULL,
|
||||
`country` VARCHAR(100) NULL,
|
||||
`isActive` BOOLEAN NOT NULL DEFAULT true,
|
||||
`createdAt` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`updatedAt` TIMESTAMP(0) NOT NULL,
|
||||
`deletedAt` TIMESTAMP(0) NULL,
|
||||
|
||||
UNIQUE INDEX `Suppliers_mobileNumber_key`(`mobileNumber`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Customers` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`firstName` VARCHAR(255) NOT NULL,
|
||||
`lastName` VARCHAR(255) NOT NULL,
|
||||
`email` VARCHAR(255) NULL,
|
||||
`mobileNumber` CHAR(11) NOT NULL,
|
||||
`address` TEXT NULL,
|
||||
`city` VARCHAR(100) NULL,
|
||||
`state` VARCHAR(100) NULL,
|
||||
`country` VARCHAR(100) NULL,
|
||||
`isActive` BOOLEAN NOT NULL DEFAULT true,
|
||||
`createdAt` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`updatedAt` TIMESTAMP(0) NOT NULL,
|
||||
`deletedAt` TIMESTAMP(0) NULL,
|
||||
|
||||
UNIQUE INDEX `Customers_mobileNumber_key`(`mobileNumber`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Inventories` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(255) NOT NULL,
|
||||
`location` VARCHAR(255) NULL,
|
||||
`isActive` BOOLEAN NOT NULL DEFAULT true,
|
||||
`createdAt` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`updatedAt` TIMESTAMP(0) NOT NULL,
|
||||
`deletedAt` TIMESTAMP(0) NULL,
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Stores` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(255) NOT NULL,
|
||||
`location` VARCHAR(255) NULL,
|
||||
`isActive` BOOLEAN NOT NULL DEFAULT true,
|
||||
`createdAt` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`updatedAt` TIMESTAMP(0) NOT NULL,
|
||||
`deletedAt` TIMESTAMP(0) NULL,
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Product_Charges` (
|
||||
@@ -51,6 +180,9 @@ CREATE TABLE `Product_Charges` (
|
||||
`inventoryId` INTEGER NOT NULL,
|
||||
`supplierId` INTEGER NOT NULL,
|
||||
|
||||
INDEX `Product_Charges_inventoryId_fkey`(`inventoryId`),
|
||||
INDEX `Product_Charges_productId_fkey`(`productId`),
|
||||
INDEX `Product_Charges_supplierId_fkey`(`supplierId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
@@ -67,6 +199,7 @@ CREATE TABLE `Orders` (
|
||||
`customerId` INTEGER NOT NULL,
|
||||
|
||||
UNIQUE INDEX `Orders_orderNumber_key`(`orderNumber`),
|
||||
INDEX `Orders_customerId_fkey`(`customerId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
@@ -82,6 +215,8 @@ CREATE TABLE `Purchase_Receipts` (
|
||||
`inventoryId` INTEGER NOT NULL,
|
||||
|
||||
UNIQUE INDEX `Purchase_Receipts_code_key`(`code`),
|
||||
INDEX `Purchase_Receipts_inventoryId_fkey`(`inventoryId`),
|
||||
INDEX `Purchase_Receipts_supplierId_fkey`(`supplierId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
@@ -91,10 +226,13 @@ CREATE TABLE `Purchase_Receipt_Items` (
|
||||
`count` DECIMAL(10, 2) NOT NULL,
|
||||
`fee` DECIMAL(10, 2) NOT NULL,
|
||||
`total` DECIMAL(10, 2) NOT NULL,
|
||||
`description` TEXT NULL,
|
||||
`createdAt` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`receiptId` INTEGER NOT NULL,
|
||||
`productId` INTEGER NOT NULL,
|
||||
|
||||
INDEX `Purchase_Receipt_Items_productId_fkey`(`productId`),
|
||||
INDEX `Purchase_Receipt_Items_receiptId_fkey`(`receiptId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
@@ -109,6 +247,7 @@ CREATE TABLE `Sales_Invoices` (
|
||||
`customerId` INTEGER NULL,
|
||||
|
||||
UNIQUE INDEX `Sales_Invoices_code_key`(`code`),
|
||||
INDEX `Sales_Invoices_customerId_fkey`(`customerId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
@@ -122,6 +261,8 @@ CREATE TABLE `Sales_Invoice_Items` (
|
||||
`invoiceId` INTEGER NOT NULL,
|
||||
`productId` INTEGER NOT NULL,
|
||||
|
||||
INDEX `Sales_Invoice_Items_invoiceId_fkey`(`invoiceId`),
|
||||
INDEX `Sales_Invoice_Items_productId_fkey`(`productId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
@@ -137,18 +278,22 @@ CREATE TABLE `Stock_Movements` (
|
||||
`createdAt` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`productId` INTEGER NOT NULL,
|
||||
`inventoryId` INTEGER NOT NULL,
|
||||
`avgCost` DECIMAL(10, 2) NOT NULL,
|
||||
|
||||
INDEX `Stock_Movements_inventoryId_fkey`(`inventoryId`),
|
||||
INDEX `Stock_Movements_productId_fkey`(`productId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `stock_balance` (
|
||||
`itemId` INTEGER NOT NULL,
|
||||
CREATE TABLE `Stock_Balance` (
|
||||
`quantity` DECIMAL(65, 30) NOT NULL,
|
||||
`totalCost` DECIMAL(65, 30) NOT NULL,
|
||||
`updatedAt` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`ProductId` INTEGER NOT NULL,
|
||||
`avgCost` DECIMAL(65, 30) NOT NULL,
|
||||
|
||||
PRIMARY KEY (`itemId`)
|
||||
PRIMARY KEY (`ProductId`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
@@ -161,6 +306,8 @@ CREATE TABLE `Inventory_Transfers` (
|
||||
`toInventoryId` INTEGER NOT NULL,
|
||||
|
||||
UNIQUE INDEX `Inventory_Transfers_code_key`(`code`),
|
||||
INDEX `Inventory_Transfers_fromInventoryId_fkey`(`fromInventoryId`),
|
||||
INDEX `Inventory_Transfers_toInventoryId_fkey`(`toInventoryId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
@@ -171,22 +318,11 @@ CREATE TABLE `Inventory_Transfer_Items` (
|
||||
`productId` INTEGER NOT NULL,
|
||||
`transferId` INTEGER NOT NULL,
|
||||
|
||||
INDEX `Inventory_Transfer_Items_productId_fkey`(`productId`),
|
||||
INDEX `Inventory_Transfer_Items_transferId_fkey`(`transferId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `StockMovementsView` (
|
||||
`id` INTEGER NULL,
|
||||
`type` VARCHAR(191) NULL,
|
||||
`productId` INTEGER NULL,
|
||||
`quantity` DECIMAL(65, 30) NULL,
|
||||
`fee` DECIMAL(65, 30) NULL,
|
||||
`totalCost` DECIMAL(65, 30) NULL,
|
||||
`referenceId` INTEGER NULL,
|
||||
`referenceType` VARCHAR(191) NULL,
|
||||
`createdAt` DATETIME(3) NULL
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Stock_Adjustments` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
@@ -195,61 +331,47 @@ CREATE TABLE `Stock_Adjustments` (
|
||||
`productId` INTEGER NOT NULL,
|
||||
`inventoryId` INTEGER NOT NULL,
|
||||
|
||||
INDEX `Stock_Adjustments_inventoryId_fkey`(`inventoryId`),
|
||||
INDEX `Stock_Adjustments_productId_fkey`(`productId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `stock_movements_view` (
|
||||
`id` INTEGER NULL,
|
||||
`productId` INTEGER NULL,
|
||||
`type` VARCHAR(191) NULL,
|
||||
`quantity` DECIMAL(65, 30) NULL,
|
||||
`fee` DECIMAL(65, 30) NULL,
|
||||
`totalCost` DECIMAL(65, 30) NULL,
|
||||
`referenceId` VARCHAR(191) NULL,
|
||||
`referenceType` VARCHAR(191) NULL,
|
||||
`createdAt` DATETIME(3) NULL,
|
||||
`currentStock` DECIMAL(65, 30) NULL,
|
||||
`currentAvgCost` DECIMAL(65, 30) NULL
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Stock_View` (
|
||||
`productId` INTEGER NULL,
|
||||
`inventoryId` INTEGER NULL,
|
||||
`stock` DECIMAL(65, 30) NULL
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Total_Stock_View` (
|
||||
`productId` INTEGER NULL,
|
||||
`stock` DECIMAL(65, 30) NULL
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Users` ADD CONSTRAINT `Users_roleId_fkey` FOREIGN KEY (`roleId`) REFERENCES `Roles`(`id`) ON DELETE RESTRICT ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Product_Charges` ADD CONSTRAINT `Product_Charges_productId_fkey` FOREIGN KEY (`productId`) REFERENCES `Products`(`id`) ON DELETE RESTRICT ON UPDATE NO ACTION;
|
||||
ALTER TABLE `Product_Variants` ADD CONSTRAINT `Product_Variants_productId_fkey` FOREIGN KEY (`productId`) REFERENCES `Products`(`id`) ON DELETE RESTRICT ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Products` ADD CONSTRAINT `Products_brandId_fkey` FOREIGN KEY (`brandId`) REFERENCES `Product_brands`(`id`) ON DELETE SET NULL ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Products` ADD CONSTRAINT `Products_categoryId_fkey` FOREIGN KEY (`categoryId`) REFERENCES `Product_categories`(`id`) ON DELETE SET NULL ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Product_Charges` ADD CONSTRAINT `Product_Charges_inventoryId_fkey` FOREIGN KEY (`inventoryId`) REFERENCES `Inventories`(`id`) ON DELETE RESTRICT ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Product_Charges` ADD CONSTRAINT `Product_Charges_productId_fkey` FOREIGN KEY (`productId`) REFERENCES `Products`(`id`) ON DELETE RESTRICT ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Product_Charges` ADD CONSTRAINT `Product_Charges_supplierId_fkey` FOREIGN KEY (`supplierId`) REFERENCES `Suppliers`(`id`) ON DELETE RESTRICT ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Orders` ADD CONSTRAINT `Orders_customerId_fkey` FOREIGN KEY (`customerId`) REFERENCES `Customers`(`id`) ON DELETE RESTRICT ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Purchase_Receipts` ADD CONSTRAINT `Purchase_Receipts_supplierId_fkey` FOREIGN KEY (`supplierId`) REFERENCES `Suppliers`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Purchase_Receipts` ADD CONSTRAINT `Purchase_Receipts_inventoryId_fkey` FOREIGN KEY (`inventoryId`) REFERENCES `Inventories`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Purchase_Receipt_Items` ADD CONSTRAINT `Purchase_Receipt_Items_receiptId_fkey` FOREIGN KEY (`receiptId`) REFERENCES `Purchase_Receipts`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
ALTER TABLE `Purchase_Receipts` ADD CONSTRAINT `Purchase_Receipts_supplierId_fkey` FOREIGN KEY (`supplierId`) REFERENCES `Suppliers`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Purchase_Receipt_Items` ADD CONSTRAINT `Purchase_Receipt_Items_productId_fkey` FOREIGN KEY (`productId`) REFERENCES `Products`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Purchase_Receipt_Items` ADD CONSTRAINT `Purchase_Receipt_Items_receiptId_fkey` FOREIGN KEY (`receiptId`) REFERENCES `Purchase_Receipts`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Sales_Invoices` ADD CONSTRAINT `Sales_Invoices_customerId_fkey` FOREIGN KEY (`customerId`) REFERENCES `Customers`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
@@ -260,10 +382,10 @@ ALTER TABLE `Sales_Invoice_Items` ADD CONSTRAINT `Sales_Invoice_Items_invoiceId_
|
||||
ALTER TABLE `Sales_Invoice_Items` ADD CONSTRAINT `Sales_Invoice_Items_productId_fkey` FOREIGN KEY (`productId`) REFERENCES `Products`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Stock_Movements` ADD CONSTRAINT `Stock_Movements_productId_fkey` FOREIGN KEY (`productId`) REFERENCES `Products`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
ALTER TABLE `Stock_Movements` ADD CONSTRAINT `Stock_Movements_inventoryId_fkey` FOREIGN KEY (`inventoryId`) REFERENCES `Inventories`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Stock_Movements` ADD CONSTRAINT `Stock_Movements_inventoryId_fkey` FOREIGN KEY (`inventoryId`) REFERENCES `Inventories`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
ALTER TABLE `Stock_Movements` ADD CONSTRAINT `Stock_Movements_productId_fkey` FOREIGN KEY (`productId`) REFERENCES `Products`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Inventory_Transfers` ADD CONSTRAINT `Inventory_Transfers_fromInventoryId_fkey` FOREIGN KEY (`fromInventoryId`) REFERENCES `Inventories`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
@@ -278,7 +400,7 @@ ALTER TABLE `Inventory_Transfer_Items` ADD CONSTRAINT `Inventory_Transfer_Items_
|
||||
ALTER TABLE `Inventory_Transfer_Items` ADD CONSTRAINT `Inventory_Transfer_Items_transferId_fkey` FOREIGN KEY (`transferId`) REFERENCES `Inventory_Transfers`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Stock_Adjustments` ADD CONSTRAINT `Stock_Adjustments_productId_fkey` FOREIGN KEY (`productId`) REFERENCES `Products`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
ALTER TABLE `Stock_Adjustments` ADD CONSTRAINT `Stock_Adjustments_inventoryId_fkey` FOREIGN KEY (`inventoryId`) REFERENCES `Inventories`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Stock_Adjustments` ADD CONSTRAINT `Stock_Adjustments_inventoryId_fkey` FOREIGN KEY (`inventoryId`) REFERENCES `Inventories`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
ALTER TABLE `Stock_Adjustments` ADD CONSTRAINT `Stock_Adjustments_productId_fkey` FOREIGN KEY (`productId`) REFERENCES `Products`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
@@ -246,6 +246,7 @@ model PurchaseReceiptItem {
|
||||
count Decimal @db.Decimal(10, 2)
|
||||
fee Decimal @db.Decimal(10, 2)
|
||||
total Decimal @db.Decimal(10, 2)
|
||||
description String? @db.Text
|
||||
createdAt DateTime @default(now()) @db.Timestamp(0)
|
||||
receiptId Int
|
||||
productId Int
|
||||
@@ -315,7 +316,7 @@ model StockBalance {
|
||||
ProductId Int @id
|
||||
avgCost Decimal
|
||||
|
||||
@@map("stock_balance")
|
||||
@@map("Stock_Balance")
|
||||
}
|
||||
|
||||
model InventoryTransfer {
|
||||
@@ -374,7 +375,7 @@ view StockMovements_View {
|
||||
current_stock Decimal?
|
||||
current_avg_cost Decimal?
|
||||
|
||||
@@map("stock_movements_view")
|
||||
@@map("Stock_Movements_View")
|
||||
@@ignore
|
||||
}
|
||||
|
||||
@@ -384,6 +385,8 @@ view inventory_overview {
|
||||
avgCost Decimal
|
||||
totalCost Decimal
|
||||
updatedAt DateTime @default(now()) @db.Timestamp(0)
|
||||
|
||||
@@map("Inventory_Overview")
|
||||
}
|
||||
|
||||
view stock_cardex {
|
||||
@@ -396,12 +399,16 @@ view stock_cardex {
|
||||
balance_quantity Decimal?
|
||||
balance_avg_cost Decimal?
|
||||
createdAt DateTime @default(now()) @db.Timestamp(0)
|
||||
|
||||
@@map("Stock_Cardex")
|
||||
}
|
||||
|
||||
view stock_view {
|
||||
productId Int
|
||||
inventoryId Int
|
||||
stock Decimal? @db.Decimal(32, 2)
|
||||
|
||||
@@map("Stock_View")
|
||||
}
|
||||
|
||||
enum OrderStatus {
|
||||
|
||||
@@ -0,0 +1,332 @@
|
||||
-- AUTO-GENERATED MYSQL TRIGGER DUMP
|
||||
-- Generated at: 2025-12-10T10:03:36.966Z
|
||||
|
||||
-- ------------------------------------------
|
||||
-- Trigger: trg_transfer_item_after_insert
|
||||
-- Event: INSERT
|
||||
-- Table: Inventory_Transfer_Items
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_transfer_item_after_insert`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_transfer_item_after_insert` AFTER INSERT ON `Inventory_Transfer_Items` FOR EACH ROW begin
|
||||
|
||||
DECLARE fromInv INT;
|
||||
DECLARE toInv INT;
|
||||
|
||||
SELECT fromInventoryId, toInventoryId INTO fromInv, toInv
|
||||
FROM Inventory_Transfers WHERE id = NEW.transferId;
|
||||
|
||||
-- OUT from source
|
||||
INSERT INTO Stock_Movements
|
||||
(type, quantity, referenceType, referenceId, productId, inventoryId, createdAt)
|
||||
VALUES
|
||||
('OUT', NEW.count, 'InventoryTransfer', NEW.transferId, NEW.productId, fromInv, NOW());
|
||||
|
||||
-- IN to destination
|
||||
INSERT INTO Stock_Movements
|
||||
(type, quantity, referenceType, referenceId, productId, inventoryId, createdAt)
|
||||
VALUES
|
||||
('IN', NEW.count, 'InventoryTransfer', NEW.transferId, NEW.productId, toInv, NOW());
|
||||
end;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- Trigger: trg_purchase_receipt_item_after_insert
|
||||
-- Event: INSERT
|
||||
-- Table: Purchase_Receipt_Items
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_purchase_receipt_item_after_insert`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_purchase_receipt_item_after_insert` AFTER INSERT ON `Purchase_Receipt_Items` FOR EACH ROW begin
|
||||
INSERT INTO Stock_Movements
|
||||
(
|
||||
type,
|
||||
quantity,
|
||||
fee,
|
||||
totalCost,
|
||||
referenceType,
|
||||
referenceId,
|
||||
productId,
|
||||
inventoryId,
|
||||
avgCost,
|
||||
createdAt
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
'IN',
|
||||
NEW.count,
|
||||
NEW.fee,
|
||||
NEW.total,
|
||||
'PURCHASE',
|
||||
NEW.receiptId,
|
||||
NEW.productId,
|
||||
(SELECT inventoryId FROM Purchase_Receipts WHERE id = NEW.receiptId),
|
||||
NEW.total / NEW.count,
|
||||
NOW()
|
||||
);
|
||||
end;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- Trigger: trg_purchase_receipt_item_after_update
|
||||
-- Event: UPDATE
|
||||
-- Table: Purchase_Receipt_Items
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_purchase_receipt_item_after_update`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_purchase_receipt_item_after_update` AFTER UPDATE ON `Purchase_Receipt_Items` FOR EACH ROW begin
|
||||
DELETE FROM Stock_Movements
|
||||
WHERE referenceType = 'PURCHASE'
|
||||
AND referenceId = NEW.receiptId
|
||||
AND productId = NEW.productId;
|
||||
|
||||
INSERT INTO Stock_Movements
|
||||
(
|
||||
type,
|
||||
quantity,
|
||||
referenceType,
|
||||
referenceId,
|
||||
productId,
|
||||
inventoryId,
|
||||
createdAt
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
'IN',
|
||||
NEW.count,
|
||||
'SALES',
|
||||
NEW.id,
|
||||
NEW.productId,
|
||||
(SELECT inventoryId FROM Stores LIMIT 1),
|
||||
NOW()
|
||||
);
|
||||
end;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- Trigger: trg_purchase_receipt_item_after_delete
|
||||
-- Event: DELETE
|
||||
-- Table: Purchase_Receipt_Items
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_purchase_receipt_item_after_delete`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_purchase_receipt_item_after_delete` AFTER DELETE ON `Purchase_Receipt_Items` FOR EACH ROW begin
|
||||
DELETE FROM Stock_Movements
|
||||
WHERE referenceType = 'PURCHASE'
|
||||
AND referenceId = OLD.receiptId
|
||||
AND productId = OLD.productId;
|
||||
end;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- Trigger: trg_sales_invoice_items_before_insert
|
||||
-- Event: INSERT
|
||||
-- Table: Sales_Invoice_Items
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_sales_invoice_items_before_insert`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_sales_invoice_items_before_insert` BEFORE INSERT ON `Sales_Invoice_Items` FOR EACH ROW begin
|
||||
DECLARE current_stock DECIMAL(10,2);
|
||||
|
||||
SELECT stock INTO current_stock
|
||||
FROM stock_view
|
||||
WHERE productId = NEW.productId
|
||||
LIMIT 1;
|
||||
|
||||
IF current_stock IS NULL THEN
|
||||
SET current_stock = 0;
|
||||
END IF;
|
||||
|
||||
IF NEW.count > current_stock THEN
|
||||
SIGNAL SQLSTATE '45000'
|
||||
SET MESSAGE_TEXT = 'Not enough stock to complete sale.';
|
||||
END IF;
|
||||
end;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- Trigger: trg_sales_invoice_items_after_insert
|
||||
-- Event: INSERT
|
||||
-- Table: Sales_Invoice_Items
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_sales_invoice_items_after_insert`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_sales_invoice_items_after_insert` AFTER INSERT ON `Sales_Invoice_Items` FOR EACH ROW begin
|
||||
INSERT INTO Stock_Movements
|
||||
(
|
||||
type,
|
||||
quantity,
|
||||
referenceType,
|
||||
referenceId,
|
||||
productId,
|
||||
inventoryId,
|
||||
createdAt
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
'IN',
|
||||
NEW.count,
|
||||
'PURCHASE',
|
||||
NEW.id,
|
||||
NEW.productId,
|
||||
(SELECT inventoryId FROM Sales_Invoices WHERE id = NEW.id),
|
||||
NOW()
|
||||
);
|
||||
end;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- Trigger: trg_stock_adjustment_after_insert
|
||||
-- Event: INSERT
|
||||
-- Table: Stock_Adjustments
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_stock_adjustment_after_insert`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_stock_adjustment_after_insert` AFTER INSERT ON `Stock_Adjustments` FOR EACH ROW begin
|
||||
INSERT INTO Stock_Movements
|
||||
(type, quantity, referenceType, referenceId, productId, inventoryId, createdAt)
|
||||
VALUES
|
||||
('ADJUST', NEW.adjustedQuantity, 'ADJUSTMENT', NEW.id, NEW.productId, NEW.inventoryId, NOW());
|
||||
end;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- Trigger: trg_stock_sale_insert
|
||||
-- Event: INSERT
|
||||
-- Table: Stock_Movements
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_stock_sale_insert`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_stock_sale_insert` AFTER INSERT ON `Stock_Movements` FOR EACH ROW BEGIN
|
||||
IF NEW.referenceType = 'SALES' THEN
|
||||
|
||||
UPDATE stock_balance
|
||||
SET
|
||||
quantity = quantity - NEW.quantity,
|
||||
totalCost = quantity * avgCost
|
||||
WHERE productId = NEW.productId ;
|
||||
|
||||
END IF;
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- Trigger: trg_stock_purchase_insert
|
||||
-- Event: INSERT
|
||||
-- Table: Stock_Movements
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_stock_purchase_insert`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_stock_purchase_insert` AFTER INSERT ON `Stock_Movements` FOR EACH ROW BEGIN
|
||||
IF NEW.referenceType = 'PURCHASE' THEN
|
||||
|
||||
INSERT INTO stock_balance (productId, quantity, avgCost, totalCost)
|
||||
VALUES (
|
||||
NEW.productId,
|
||||
NEW.quantity,
|
||||
NEW.fee,
|
||||
NEW.totalCost
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
quantity = quantity + NEW.quantity,
|
||||
totalCost = totalCost + NEW.totalCost,
|
||||
avgCost = totalCost / quantity;
|
||||
|
||||
END IF;
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- Trigger: trg_stock_movement_after_insert
|
||||
-- Event: INSERT
|
||||
-- Table: Stock_Movements
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_stock_movement_after_insert`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_stock_movement_after_insert` AFTER INSERT ON `Stock_Movements` FOR EACH ROW begin
|
||||
UPDATE Products pv
|
||||
SET pv.quantity = (
|
||||
SELECT COALESCE(SUM(
|
||||
CASE
|
||||
WHEN type = 'IN' THEN quantity
|
||||
WHEN type = 'OUT' THEN -quantity
|
||||
WHEN type = 'ADJUST' THEN quantity
|
||||
END
|
||||
), 0)
|
||||
FROM Stock_Movements
|
||||
WHERE productId = NEW.productId
|
||||
)
|
||||
WHERE pv.id = NEW.productId;
|
||||
end;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- Trigger: trg_stock_sale_update
|
||||
-- Event: UPDATE
|
||||
-- Table: Stock_Movements
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_stock_sale_update`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_stock_sale_update` AFTER UPDATE ON `Stock_Movements` FOR EACH ROW BEGIN
|
||||
IF OLD.referenceType = 'SALES' THEN
|
||||
UPDATE stock_balance
|
||||
SET
|
||||
quantity = quantity + OLD.quantity,
|
||||
totalCost = (quantity + OLD.quantity) * avgCost
|
||||
WHERE productId = OLD.productId;
|
||||
END IF;
|
||||
|
||||
IF NEW.referenceType = 'SALES' THEN
|
||||
UPDATE stock_balance
|
||||
SET
|
||||
quantity = quantity - NEW.quantity,
|
||||
totalCost = (quantity - NEW.quantity) * avgCost
|
||||
WHERE productId = NEW.productId;
|
||||
END IF;
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- Trigger: trg_stock_purchase_update
|
||||
-- Event: UPDATE
|
||||
-- Table: Stock_Movements
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_stock_purchase_update`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_stock_purchase_update` AFTER UPDATE ON `Stock_Movements` FOR EACH ROW BEGIN
|
||||
IF OLD.referenceType = 'PURCHASE' THEN
|
||||
UPDATE stock_balance
|
||||
SET
|
||||
quantity = quantity - OLD.quantity,
|
||||
totalCost = totalCost - (OLD.quantity * OLD.fee)
|
||||
WHERE productId = OLD.productId;
|
||||
END IF;
|
||||
|
||||
IF NEW.referenceType = 'PURCHASE' THEN
|
||||
INSERT INTO stock_balance (productId, quantity, avgCost, totalCost)
|
||||
VALUES (
|
||||
NEW.productId,
|
||||
NEW.quantity,
|
||||
NEW.fee,
|
||||
NEW.totalCost
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
quantity = quantity + NEW.quantity,
|
||||
totalCost = totalCost + NEW.totalCost,
|
||||
avgCost = totalCost / quantity;
|
||||
END IF;
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- Trigger: trg_stock_sale_delete
|
||||
-- Event: DELETE
|
||||
-- Table: Stock_Movements
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_stock_sale_delete`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_stock_sale_delete` AFTER DELETE ON `Stock_Movements` FOR EACH ROW BEGIN
|
||||
IF OLD.ReferenceType = 'SALES' THEN
|
||||
UPDATE stock_balance
|
||||
SET
|
||||
quantity = quantity + OLD.quantity,
|
||||
totalCost = (quantity + OLD.quantity) * avgCost
|
||||
WHERE productId = OLD.productId;
|
||||
END IF;
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- Trigger: trg_stock_purchase_delete
|
||||
-- Event: DELETE
|
||||
-- Table: Stock_Movements
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_stock_purchase_delete`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_stock_purchase_delete` AFTER DELETE ON `Stock_Movements` FOR EACH ROW BEGIN
|
||||
IF OLD.referenceType = 'PURCHASE' THEN
|
||||
UPDATE stock_balance
|
||||
SET
|
||||
quantity = quantity - OLD.quantity,
|
||||
totalCost = totalCost - (OLD.quantity * OLD.fee),
|
||||
avgCost = CASE
|
||||
WHEN quantity - OLD.quantity = 0 THEN 0
|
||||
ELSE (totalCost - (OLD.quantity * OLD.fee)) / (quantity - OLD.quantity)
|
||||
END
|
||||
WHERE productId = OLD.productId;
|
||||
END IF;
|
||||
END;
|
||||
|
||||
@@ -0,0 +1,326 @@
|
||||
-- AUTO-GENERATED MYSQL TRIGGER DUMP
|
||||
-- Generated at: 2025-12-10T10:03:36.966Z
|
||||
|
||||
-- ------------------------------------------
|
||||
-- Trigger: trg_transfer_item_after_insert
|
||||
-- Event: INSERT
|
||||
-- Table: Inventory_Transfer_Items
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_transfer_item_after_insert`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_transfer_item_after_insert` AFTER INSERT ON `Inventory_Transfer_Items` FOR EACH ROW begin
|
||||
|
||||
DECLARE fromInv INT;
|
||||
DECLARE toInv INT;
|
||||
|
||||
SELECT fromInventoryId, toInventoryId INTO fromInv, toInv
|
||||
FROM Inventory_Transfers WHERE id = NEW.transferId;
|
||||
|
||||
-- OUT from source
|
||||
INSERT INTO Stock_Movements
|
||||
(type, quantity, referenceType, referenceId, productId, inventoryId, createdAt)
|
||||
VALUES
|
||||
('OUT', NEW.count, 'InventoryTransfer', NEW.transferId, NEW.productId, fromInv, NOW());
|
||||
|
||||
-- IN to destination
|
||||
INSERT INTO Stock_Movements
|
||||
(type, quantity, referenceType, referenceId, productId, inventoryId, createdAt)
|
||||
VALUES
|
||||
('IN', NEW.count, 'InventoryTransfer', NEW.transferId, NEW.productId, toInv, NOW());
|
||||
end;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- Trigger: trg_purchase_receipt_item_after_insert
|
||||
-- Event: INSERT
|
||||
-- Table: Purchase_Receipt_Items
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_purchase_receipt_item_after_insert`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_purchase_receipt_item_after_insert` AFTER INSERT ON `Purchase_Receipt_Items` FOR EACH ROW begin
|
||||
INSERT INTO Stock_Movements
|
||||
(
|
||||
type,
|
||||
quantity,
|
||||
referenceType,
|
||||
referenceId,
|
||||
productId,
|
||||
inventoryId,
|
||||
createdAt
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
'IN',
|
||||
NEW.count,
|
||||
'PURCHASE',
|
||||
NEW.receiptId,
|
||||
NEW.productId,
|
||||
(SELECT inventoryId FROM Purchase_Receipts WHERE id = NEW.receiptId),
|
||||
NOW()
|
||||
);
|
||||
end;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- Trigger: trg_purchase_receipt_item_after_update
|
||||
-- Event: UPDATE
|
||||
-- Table: Purchase_Receipt_Items
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_purchase_receipt_item_after_update`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_purchase_receipt_item_after_update` AFTER UPDATE ON `Purchase_Receipt_Items` FOR EACH ROW begin
|
||||
DELETE FROM Stock_Movements
|
||||
WHERE referenceType = 'PURCHASE'
|
||||
AND referenceId = NEW.receiptId
|
||||
AND productId = NEW.productId;
|
||||
|
||||
INSERT INTO Stock_Movements
|
||||
(
|
||||
type,
|
||||
quantity,
|
||||
referenceType,
|
||||
referenceId,
|
||||
productId,
|
||||
inventoryId,
|
||||
createdAt
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
'IN',
|
||||
NEW.count,
|
||||
'SALES',
|
||||
NEW.id,
|
||||
NEW.productId,
|
||||
(SELECT inventoryId FROM Stores LIMIT 1),
|
||||
NOW()
|
||||
);
|
||||
end;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- Trigger: trg_purchase_receipt_item_after_delete
|
||||
-- Event: DELETE
|
||||
-- Table: Purchase_Receipt_Items
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_purchase_receipt_item_after_delete`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_purchase_receipt_item_after_delete` AFTER DELETE ON `Purchase_Receipt_Items` FOR EACH ROW begin
|
||||
DELETE FROM Stock_Movements
|
||||
WHERE referenceType = 'PURCHASE'
|
||||
AND referenceId = OLD.receiptId
|
||||
AND productId = OLD.productId;
|
||||
end;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- Trigger: trg_sales_invoice_items_before_insert
|
||||
-- Event: INSERT
|
||||
-- Table: Sales_Invoice_Items
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_sales_invoice_items_before_insert`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_sales_invoice_items_before_insert` BEFORE INSERT ON `Sales_Invoice_Items` FOR EACH ROW begin
|
||||
DECLARE current_stock DECIMAL(10,2);
|
||||
|
||||
SELECT stock INTO current_stock
|
||||
FROM stock_view
|
||||
WHERE productId = NEW.productId
|
||||
LIMIT 1;
|
||||
|
||||
IF current_stock IS NULL THEN
|
||||
SET current_stock = 0;
|
||||
END IF;
|
||||
|
||||
IF NEW.count > current_stock THEN
|
||||
SIGNAL SQLSTATE '45000'
|
||||
SET MESSAGE_TEXT = 'Not enough stock to complete sale.';
|
||||
END IF;
|
||||
end;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- Trigger: trg_sales_invoice_items_after_insert
|
||||
-- Event: INSERT
|
||||
-- Table: Sales_Invoice_Items
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_sales_invoice_items_after_insert`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_sales_invoice_items_after_insert` AFTER INSERT ON `Sales_Invoice_Items` FOR EACH ROW begin
|
||||
INSERT INTO Stock_Movements
|
||||
(
|
||||
type,
|
||||
quantity,
|
||||
referenceType,
|
||||
referenceId,
|
||||
productId,
|
||||
inventoryId,
|
||||
createdAt
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
'IN',
|
||||
NEW.count,
|
||||
'PURCHASE',
|
||||
NEW.id,
|
||||
NEW.productId,
|
||||
(SELECT inventoryId FROM Sales_Invoices WHERE id = NEW.id),
|
||||
NOW()
|
||||
);
|
||||
end;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- Trigger: trg_stock_adjustment_after_insert
|
||||
-- Event: INSERT
|
||||
-- Table: Stock_Adjustments
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_stock_adjustment_after_insert`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_stock_adjustment_after_insert` AFTER INSERT ON `Stock_Adjustments` FOR EACH ROW begin
|
||||
INSERT INTO Stock_Movements
|
||||
(type, quantity, referenceType, referenceId, productId, inventoryId, createdAt)
|
||||
VALUES
|
||||
('ADJUST', NEW.adjustedQuantity, 'ADJUSTMENT', NEW.id, NEW.productId, NEW.inventoryId, NOW());
|
||||
end;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- Trigger: trg_stock_sale_insert
|
||||
-- Event: INSERT
|
||||
-- Table: Stock_Movements
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_stock_sale_insert`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_stock_sale_insert` AFTER INSERT ON `Stock_Movements` FOR EACH ROW BEGIN
|
||||
IF NEW.referenceType = 'SALES' THEN
|
||||
|
||||
UPDATE stock_balance
|
||||
SET
|
||||
quantity = quantity - NEW.quantity,
|
||||
totalCost = quantity * avgCost
|
||||
WHERE productId = NEW.productId ;
|
||||
|
||||
END IF;
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- Trigger: trg_stock_purchase_insert
|
||||
-- Event: INSERT
|
||||
-- Table: Stock_Movements
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_stock_purchase_insert`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_stock_purchase_insert` AFTER INSERT ON `Stock_Movements` FOR EACH ROW BEGIN
|
||||
IF NEW.referenceType = 'PURCHASE' THEN
|
||||
|
||||
INSERT INTO stock_balance (productId, quantity, avgCost, totalCost)
|
||||
VALUES (
|
||||
NEW.productId,
|
||||
NEW.quantity,
|
||||
NEW.fee,
|
||||
NEW.totalCost
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
quantity = quantity + NEW.quantity,
|
||||
totalCost = totalCost + NEW.totalCost,
|
||||
avgCost = totalCost / quantity;
|
||||
|
||||
END IF;
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- Trigger: trg_stock_movement_after_insert
|
||||
-- Event: INSERT
|
||||
-- Table: Stock_Movements
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_stock_movement_after_insert`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_stock_movement_after_insert` AFTER INSERT ON `Stock_Movements` FOR EACH ROW begin
|
||||
UPDATE Products pv
|
||||
SET pv.quantity = (
|
||||
SELECT COALESCE(SUM(
|
||||
CASE
|
||||
WHEN type = 'IN' THEN quantity
|
||||
WHEN type = 'OUT' THEN -quantity
|
||||
WHEN type = 'ADJUST' THEN quantity
|
||||
END
|
||||
), 0)
|
||||
FROM Stock_Movements
|
||||
WHERE productId = NEW.productId
|
||||
)
|
||||
WHERE pv.id = NEW.productId;
|
||||
end;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- Trigger: trg_stock_sale_update
|
||||
-- Event: UPDATE
|
||||
-- Table: Stock_Movements
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_stock_sale_update`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_stock_sale_update` AFTER UPDATE ON `Stock_Movements` FOR EACH ROW BEGIN
|
||||
IF OLD.referenceType = 'SALES' THEN
|
||||
UPDATE stock_balance
|
||||
SET
|
||||
quantity = quantity + OLD.quantity,
|
||||
totalCost = (quantity + OLD.quantity) * avgCost
|
||||
WHERE productId = OLD.productId;
|
||||
END IF;
|
||||
|
||||
IF NEW.referenceType = 'SALES' THEN
|
||||
UPDATE stock_balance
|
||||
SET
|
||||
quantity = quantity - NEW.quantity,
|
||||
totalCost = (quantity - NEW.quantity) * avgCost
|
||||
WHERE productId = NEW.productId;
|
||||
END IF;
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- Trigger: trg_stock_purchase_update
|
||||
-- Event: UPDATE
|
||||
-- Table: Stock_Movements
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_stock_purchase_update`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_stock_purchase_update` AFTER UPDATE ON `Stock_Movements` FOR EACH ROW BEGIN
|
||||
IF OLD.referenceType = 'PURCHASE' THEN
|
||||
UPDATE stock_balance
|
||||
SET
|
||||
quantity = quantity - OLD.quantity,
|
||||
totalCost = totalCost - (OLD.quantity * OLD.fee)
|
||||
WHERE productId = OLD.productId;
|
||||
END IF;
|
||||
|
||||
IF NEW.referenceType = 'PURCHASE' THEN
|
||||
INSERT INTO stock_balance (productId, quantity, avgCost, totalCost)
|
||||
VALUES (
|
||||
NEW.productId,
|
||||
NEW.quantity,
|
||||
NEW.fee,
|
||||
NEW.totalCost
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
quantity = quantity + NEW.quantity,
|
||||
totalCost = totalCost + NEW.totalCost,
|
||||
avgCost = totalCost / quantity;
|
||||
END IF;
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- Trigger: trg_stock_sale_delete
|
||||
-- Event: DELETE
|
||||
-- Table: Stock_Movements
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_stock_sale_delete`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_stock_sale_delete` AFTER DELETE ON `Stock_Movements` FOR EACH ROW BEGIN
|
||||
IF OLD.ReferenceType = 'SALES' THEN
|
||||
UPDATE stock_balance
|
||||
SET
|
||||
quantity = quantity + OLD.quantity,
|
||||
totalCost = (quantity + OLD.quantity) * avgCost
|
||||
WHERE productId = OLD.productId;
|
||||
END IF;
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- Trigger: trg_stock_purchase_delete
|
||||
-- Event: DELETE
|
||||
-- Table: Stock_Movements
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_stock_purchase_delete`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_stock_purchase_delete` AFTER DELETE ON `Stock_Movements` FOR EACH ROW BEGIN
|
||||
IF OLD.referenceType = 'PURCHASE' THEN
|
||||
UPDATE stock_balance
|
||||
SET
|
||||
quantity = quantity - OLD.quantity,
|
||||
totalCost = totalCost - (OLD.quantity * OLD.fee),
|
||||
avgCost = CASE
|
||||
WHEN quantity - OLD.quantity = 0 THEN 0
|
||||
ELSE (totalCost - (OLD.quantity * OLD.fee)) / (quantity - OLD.quantity)
|
||||
END
|
||||
WHERE productId = OLD.productId;
|
||||
END IF;
|
||||
END;
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
import 'dotenv/config'
|
||||
import fs from 'fs'
|
||||
import mysql from 'mysql2/promise'
|
||||
import path from 'path'
|
||||
import { env } from 'prisma/config'
|
||||
|
||||
const OUTPUT_DIR = path.join(process.cwd(), 'prisma', 'triggers')
|
||||
|
||||
async function main() {
|
||||
const conn = await mysql.createConnection({
|
||||
host: env('DATABASE_HOST'),
|
||||
user: env('DATABASE_USER'),
|
||||
password: env('DATABASE_PASSWORD'),
|
||||
database: env('DATABASE_NAME'),
|
||||
port: Number(env('DATABASE_PORT')) || 3306,
|
||||
})
|
||||
|
||||
console.log('📌 Fetching triggers...')
|
||||
const [triggers] = (await conn.execute('SHOW TRIGGERS')) as [Array<any>, any]
|
||||
|
||||
if (triggers.length === 0) {
|
||||
console.log('⚠️ No triggers found in the database.')
|
||||
return
|
||||
}
|
||||
|
||||
// Ensure directory exists
|
||||
fs.mkdirSync(OUTPUT_DIR, { recursive: true })
|
||||
|
||||
const dumpFile = path.join(OUTPUT_DIR, `dump_triggers.sql`)
|
||||
|
||||
let sqlOutput = '-- AUTO-GENERATED MYSQL TRIGGER DUMP\n'
|
||||
sqlOutput += '-- Generated at: ' + new Date().toISOString() + '\n\n'
|
||||
|
||||
for (const trg of triggers) {
|
||||
const name = trg.Trigger
|
||||
console.log(`📥 Extracting trigger: ${name}`)
|
||||
|
||||
const [rows] = await conn.execute(`SHOW CREATE TRIGGER \`${name}\``)
|
||||
|
||||
const createStatement = rows[0]['SQL Original Statement']
|
||||
|
||||
sqlOutput += `-- ------------------------------------------\n`
|
||||
sqlOutput += `-- Trigger: ${name}\n`
|
||||
sqlOutput += `-- Event: ${trg.Event}\n`
|
||||
sqlOutput += `-- Table: ${trg.Table}\n`
|
||||
sqlOutput += `-- ------------------------------------------\n`
|
||||
sqlOutput += `DROP TRIGGER IF EXISTS \`${name}\`;\n`
|
||||
sqlOutput += `${createStatement};\n\n`
|
||||
}
|
||||
|
||||
fs.writeFileSync(dumpFile, sqlOutput)
|
||||
|
||||
console.log('✅ Triggers exported to:')
|
||||
console.log(` ${dumpFile}`)
|
||||
|
||||
await conn.end()
|
||||
}
|
||||
|
||||
main().catch(err => {
|
||||
console.error(err)
|
||||
process.exit(1)
|
||||
})
|
||||
@@ -0,0 +1,24 @@
|
||||
import 'dotenv/config'
|
||||
import mysql from 'mysql2/promise'
|
||||
import { env } from 'prisma/config'
|
||||
;(async () => {
|
||||
const db = await mysql.createConnection({
|
||||
host: env('DATABASE_HOST'),
|
||||
user: env('DATABASE_USER'),
|
||||
password: env('DATABASE_PASSWORD'),
|
||||
database: env('DATABASE_NAME'),
|
||||
port: Number(env('DATABASE_PORT')) || 3306,
|
||||
})
|
||||
|
||||
const [rows] = await db.query(`
|
||||
SELECT
|
||||
TRIGGER_NAME,
|
||||
ACTION_STATEMENT
|
||||
FROM INFORMATION_SCHEMA.TRIGGERS
|
||||
WHERE TRIGGER_SCHEMA = DATABASE();
|
||||
`)
|
||||
|
||||
console.log(rows)
|
||||
|
||||
await db.end()
|
||||
})()
|
||||
File diff suppressed because one or more lines are too long
@@ -2151,6 +2151,7 @@ export const PurchaseReceiptItemScalarFieldEnum = {
|
||||
count: 'count',
|
||||
fee: 'fee',
|
||||
total: 'total',
|
||||
description: 'description',
|
||||
createdAt: 'createdAt',
|
||||
receiptId: 'receiptId',
|
||||
productId: 'productId'
|
||||
@@ -2445,6 +2446,13 @@ export const PurchaseReceiptOrderByRelevanceFieldEnum = {
|
||||
export type PurchaseReceiptOrderByRelevanceFieldEnum = (typeof PurchaseReceiptOrderByRelevanceFieldEnum)[keyof typeof PurchaseReceiptOrderByRelevanceFieldEnum]
|
||||
|
||||
|
||||
export const PurchaseReceiptItemOrderByRelevanceFieldEnum = {
|
||||
description: 'description'
|
||||
} as const
|
||||
|
||||
export type PurchaseReceiptItemOrderByRelevanceFieldEnum = (typeof PurchaseReceiptItemOrderByRelevanceFieldEnum)[keyof typeof PurchaseReceiptItemOrderByRelevanceFieldEnum]
|
||||
|
||||
|
||||
export const SalesInvoiceOrderByRelevanceFieldEnum = {
|
||||
code: 'code',
|
||||
description: 'description'
|
||||
|
||||
@@ -302,6 +302,7 @@ export const PurchaseReceiptItemScalarFieldEnum = {
|
||||
count: 'count',
|
||||
fee: 'fee',
|
||||
total: 'total',
|
||||
description: 'description',
|
||||
createdAt: 'createdAt',
|
||||
receiptId: 'receiptId',
|
||||
productId: 'productId'
|
||||
@@ -596,6 +597,13 @@ export const PurchaseReceiptOrderByRelevanceFieldEnum = {
|
||||
export type PurchaseReceiptOrderByRelevanceFieldEnum = (typeof PurchaseReceiptOrderByRelevanceFieldEnum)[keyof typeof PurchaseReceiptOrderByRelevanceFieldEnum]
|
||||
|
||||
|
||||
export const PurchaseReceiptItemOrderByRelevanceFieldEnum = {
|
||||
description: 'description'
|
||||
} as const
|
||||
|
||||
export type PurchaseReceiptItemOrderByRelevanceFieldEnum = (typeof PurchaseReceiptItemOrderByRelevanceFieldEnum)[keyof typeof PurchaseReceiptItemOrderByRelevanceFieldEnum]
|
||||
|
||||
|
||||
export const SalesInvoiceOrderByRelevanceFieldEnum = {
|
||||
code: 'code',
|
||||
description: 'description'
|
||||
|
||||
@@ -49,6 +49,7 @@ export type PurchaseReceiptItemMinAggregateOutputType = {
|
||||
count: runtime.Decimal | null
|
||||
fee: runtime.Decimal | null
|
||||
total: runtime.Decimal | null
|
||||
description: string | null
|
||||
createdAt: Date | null
|
||||
receiptId: number | null
|
||||
productId: number | null
|
||||
@@ -59,6 +60,7 @@ export type PurchaseReceiptItemMaxAggregateOutputType = {
|
||||
count: runtime.Decimal | null
|
||||
fee: runtime.Decimal | null
|
||||
total: runtime.Decimal | null
|
||||
description: string | null
|
||||
createdAt: Date | null
|
||||
receiptId: number | null
|
||||
productId: number | null
|
||||
@@ -69,6 +71,7 @@ export type PurchaseReceiptItemCountAggregateOutputType = {
|
||||
count: number
|
||||
fee: number
|
||||
total: number
|
||||
description: number
|
||||
createdAt: number
|
||||
receiptId: number
|
||||
productId: number
|
||||
@@ -99,6 +102,7 @@ export type PurchaseReceiptItemMinAggregateInputType = {
|
||||
count?: true
|
||||
fee?: true
|
||||
total?: true
|
||||
description?: true
|
||||
createdAt?: true
|
||||
receiptId?: true
|
||||
productId?: true
|
||||
@@ -109,6 +113,7 @@ export type PurchaseReceiptItemMaxAggregateInputType = {
|
||||
count?: true
|
||||
fee?: true
|
||||
total?: true
|
||||
description?: true
|
||||
createdAt?: true
|
||||
receiptId?: true
|
||||
productId?: true
|
||||
@@ -119,6 +124,7 @@ export type PurchaseReceiptItemCountAggregateInputType = {
|
||||
count?: true
|
||||
fee?: true
|
||||
total?: true
|
||||
description?: true
|
||||
createdAt?: true
|
||||
receiptId?: true
|
||||
productId?: true
|
||||
@@ -216,6 +222,7 @@ export type PurchaseReceiptItemGroupByOutputType = {
|
||||
count: runtime.Decimal
|
||||
fee: runtime.Decimal
|
||||
total: runtime.Decimal
|
||||
description: string | null
|
||||
createdAt: Date
|
||||
receiptId: number
|
||||
productId: number
|
||||
@@ -249,6 +256,7 @@ export type PurchaseReceiptItemWhereInput = {
|
||||
count?: Prisma.DecimalFilter<"PurchaseReceiptItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
fee?: Prisma.DecimalFilter<"PurchaseReceiptItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total?: Prisma.DecimalFilter<"PurchaseReceiptItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
description?: Prisma.StringNullableFilter<"PurchaseReceiptItem"> | string | null
|
||||
createdAt?: Prisma.DateTimeFilter<"PurchaseReceiptItem"> | Date | string
|
||||
receiptId?: Prisma.IntFilter<"PurchaseReceiptItem"> | number
|
||||
productId?: Prisma.IntFilter<"PurchaseReceiptItem"> | number
|
||||
@@ -261,11 +269,13 @@ export type PurchaseReceiptItemOrderByWithRelationInput = {
|
||||
count?: Prisma.SortOrder
|
||||
fee?: Prisma.SortOrder
|
||||
total?: Prisma.SortOrder
|
||||
description?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
createdAt?: Prisma.SortOrder
|
||||
receiptId?: Prisma.SortOrder
|
||||
productId?: Prisma.SortOrder
|
||||
product?: Prisma.ProductOrderByWithRelationInput
|
||||
receipt?: Prisma.PurchaseReceiptOrderByWithRelationInput
|
||||
_relevance?: Prisma.PurchaseReceiptItemOrderByRelevanceInput
|
||||
}
|
||||
|
||||
export type PurchaseReceiptItemWhereUniqueInput = Prisma.AtLeast<{
|
||||
@@ -276,6 +286,7 @@ export type PurchaseReceiptItemWhereUniqueInput = Prisma.AtLeast<{
|
||||
count?: Prisma.DecimalFilter<"PurchaseReceiptItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
fee?: Prisma.DecimalFilter<"PurchaseReceiptItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total?: Prisma.DecimalFilter<"PurchaseReceiptItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
description?: Prisma.StringNullableFilter<"PurchaseReceiptItem"> | string | null
|
||||
createdAt?: Prisma.DateTimeFilter<"PurchaseReceiptItem"> | Date | string
|
||||
receiptId?: Prisma.IntFilter<"PurchaseReceiptItem"> | number
|
||||
productId?: Prisma.IntFilter<"PurchaseReceiptItem"> | number
|
||||
@@ -288,6 +299,7 @@ export type PurchaseReceiptItemOrderByWithAggregationInput = {
|
||||
count?: Prisma.SortOrder
|
||||
fee?: Prisma.SortOrder
|
||||
total?: Prisma.SortOrder
|
||||
description?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
createdAt?: Prisma.SortOrder
|
||||
receiptId?: Prisma.SortOrder
|
||||
productId?: Prisma.SortOrder
|
||||
@@ -306,6 +318,7 @@ export type PurchaseReceiptItemScalarWhereWithAggregatesInput = {
|
||||
count?: Prisma.DecimalWithAggregatesFilter<"PurchaseReceiptItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
fee?: Prisma.DecimalWithAggregatesFilter<"PurchaseReceiptItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total?: Prisma.DecimalWithAggregatesFilter<"PurchaseReceiptItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
description?: Prisma.StringNullableWithAggregatesFilter<"PurchaseReceiptItem"> | string | null
|
||||
createdAt?: Prisma.DateTimeWithAggregatesFilter<"PurchaseReceiptItem"> | Date | string
|
||||
receiptId?: Prisma.IntWithAggregatesFilter<"PurchaseReceiptItem"> | number
|
||||
productId?: Prisma.IntWithAggregatesFilter<"PurchaseReceiptItem"> | number
|
||||
@@ -315,6 +328,7 @@ export type PurchaseReceiptItemCreateInput = {
|
||||
count: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
fee: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
description?: string | null
|
||||
createdAt?: Date | string
|
||||
product: Prisma.ProductCreateNestedOneWithoutPurchaseReceiptItemsInput
|
||||
receipt: Prisma.PurchaseReceiptCreateNestedOneWithoutItemsInput
|
||||
@@ -325,6 +339,7 @@ export type PurchaseReceiptItemUncheckedCreateInput = {
|
||||
count: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
fee: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
description?: string | null
|
||||
createdAt?: Date | string
|
||||
receiptId: number
|
||||
productId: number
|
||||
@@ -334,6 +349,7 @@ export type PurchaseReceiptItemUpdateInput = {
|
||||
count?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
fee?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
product?: Prisma.ProductUpdateOneRequiredWithoutPurchaseReceiptItemsNestedInput
|
||||
receipt?: Prisma.PurchaseReceiptUpdateOneRequiredWithoutItemsNestedInput
|
||||
@@ -344,6 +360,7 @@ export type PurchaseReceiptItemUncheckedUpdateInput = {
|
||||
count?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
fee?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
receiptId?: Prisma.IntFieldUpdateOperationsInput | number
|
||||
productId?: Prisma.IntFieldUpdateOperationsInput | number
|
||||
@@ -354,6 +371,7 @@ export type PurchaseReceiptItemCreateManyInput = {
|
||||
count: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
fee: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
description?: string | null
|
||||
createdAt?: Date | string
|
||||
receiptId: number
|
||||
productId: number
|
||||
@@ -363,6 +381,7 @@ export type PurchaseReceiptItemUpdateManyMutationInput = {
|
||||
count?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
fee?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
}
|
||||
|
||||
@@ -371,6 +390,7 @@ export type PurchaseReceiptItemUncheckedUpdateManyInput = {
|
||||
count?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
fee?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
receiptId?: Prisma.IntFieldUpdateOperationsInput | number
|
||||
productId?: Prisma.IntFieldUpdateOperationsInput | number
|
||||
@@ -386,11 +406,18 @@ export type PurchaseReceiptItemOrderByRelationAggregateInput = {
|
||||
_count?: Prisma.SortOrder
|
||||
}
|
||||
|
||||
export type PurchaseReceiptItemOrderByRelevanceInput = {
|
||||
fields: Prisma.PurchaseReceiptItemOrderByRelevanceFieldEnum | Prisma.PurchaseReceiptItemOrderByRelevanceFieldEnum[]
|
||||
sort: Prisma.SortOrder
|
||||
search: string
|
||||
}
|
||||
|
||||
export type PurchaseReceiptItemCountOrderByAggregateInput = {
|
||||
id?: Prisma.SortOrder
|
||||
count?: Prisma.SortOrder
|
||||
fee?: Prisma.SortOrder
|
||||
total?: Prisma.SortOrder
|
||||
description?: Prisma.SortOrder
|
||||
createdAt?: Prisma.SortOrder
|
||||
receiptId?: Prisma.SortOrder
|
||||
productId?: Prisma.SortOrder
|
||||
@@ -410,6 +437,7 @@ export type PurchaseReceiptItemMaxOrderByAggregateInput = {
|
||||
count?: Prisma.SortOrder
|
||||
fee?: Prisma.SortOrder
|
||||
total?: Prisma.SortOrder
|
||||
description?: Prisma.SortOrder
|
||||
createdAt?: Prisma.SortOrder
|
||||
receiptId?: Prisma.SortOrder
|
||||
productId?: Prisma.SortOrder
|
||||
@@ -420,6 +448,7 @@ export type PurchaseReceiptItemMinOrderByAggregateInput = {
|
||||
count?: Prisma.SortOrder
|
||||
fee?: Prisma.SortOrder
|
||||
total?: Prisma.SortOrder
|
||||
description?: Prisma.SortOrder
|
||||
createdAt?: Prisma.SortOrder
|
||||
receiptId?: Prisma.SortOrder
|
||||
productId?: Prisma.SortOrder
|
||||
@@ -522,6 +551,7 @@ export type PurchaseReceiptItemCreateWithoutProductInput = {
|
||||
count: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
fee: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
description?: string | null
|
||||
createdAt?: Date | string
|
||||
receipt: Prisma.PurchaseReceiptCreateNestedOneWithoutItemsInput
|
||||
}
|
||||
@@ -531,6 +561,7 @@ export type PurchaseReceiptItemUncheckedCreateWithoutProductInput = {
|
||||
count: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
fee: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
description?: string | null
|
||||
createdAt?: Date | string
|
||||
receiptId: number
|
||||
}
|
||||
@@ -569,6 +600,7 @@ export type PurchaseReceiptItemScalarWhereInput = {
|
||||
count?: Prisma.DecimalFilter<"PurchaseReceiptItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
fee?: Prisma.DecimalFilter<"PurchaseReceiptItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total?: Prisma.DecimalFilter<"PurchaseReceiptItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
description?: Prisma.StringNullableFilter<"PurchaseReceiptItem"> | string | null
|
||||
createdAt?: Prisma.DateTimeFilter<"PurchaseReceiptItem"> | Date | string
|
||||
receiptId?: Prisma.IntFilter<"PurchaseReceiptItem"> | number
|
||||
productId?: Prisma.IntFilter<"PurchaseReceiptItem"> | number
|
||||
@@ -578,6 +610,7 @@ export type PurchaseReceiptItemCreateWithoutReceiptInput = {
|
||||
count: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
fee: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
description?: string | null
|
||||
createdAt?: Date | string
|
||||
product: Prisma.ProductCreateNestedOneWithoutPurchaseReceiptItemsInput
|
||||
}
|
||||
@@ -587,6 +620,7 @@ export type PurchaseReceiptItemUncheckedCreateWithoutReceiptInput = {
|
||||
count: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
fee: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
description?: string | null
|
||||
createdAt?: Date | string
|
||||
productId: number
|
||||
}
|
||||
@@ -622,6 +656,7 @@ export type PurchaseReceiptItemCreateManyProductInput = {
|
||||
count: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
fee: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
description?: string | null
|
||||
createdAt?: Date | string
|
||||
receiptId: number
|
||||
}
|
||||
@@ -630,6 +665,7 @@ export type PurchaseReceiptItemUpdateWithoutProductInput = {
|
||||
count?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
fee?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
receipt?: Prisma.PurchaseReceiptUpdateOneRequiredWithoutItemsNestedInput
|
||||
}
|
||||
@@ -639,6 +675,7 @@ export type PurchaseReceiptItemUncheckedUpdateWithoutProductInput = {
|
||||
count?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
fee?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
receiptId?: Prisma.IntFieldUpdateOperationsInput | number
|
||||
}
|
||||
@@ -648,6 +685,7 @@ export type PurchaseReceiptItemUncheckedUpdateManyWithoutProductInput = {
|
||||
count?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
fee?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
receiptId?: Prisma.IntFieldUpdateOperationsInput | number
|
||||
}
|
||||
@@ -657,6 +695,7 @@ export type PurchaseReceiptItemCreateManyReceiptInput = {
|
||||
count: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
fee: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
description?: string | null
|
||||
createdAt?: Date | string
|
||||
productId: number
|
||||
}
|
||||
@@ -665,6 +704,7 @@ export type PurchaseReceiptItemUpdateWithoutReceiptInput = {
|
||||
count?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
fee?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
product?: Prisma.ProductUpdateOneRequiredWithoutPurchaseReceiptItemsNestedInput
|
||||
}
|
||||
@@ -674,6 +714,7 @@ export type PurchaseReceiptItemUncheckedUpdateWithoutReceiptInput = {
|
||||
count?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
fee?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
productId?: Prisma.IntFieldUpdateOperationsInput | number
|
||||
}
|
||||
@@ -683,6 +724,7 @@ export type PurchaseReceiptItemUncheckedUpdateManyWithoutReceiptInput = {
|
||||
count?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
fee?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
productId?: Prisma.IntFieldUpdateOperationsInput | number
|
||||
}
|
||||
@@ -694,6 +736,7 @@ export type PurchaseReceiptItemSelect<ExtArgs extends runtime.Types.Extensions.I
|
||||
count?: boolean
|
||||
fee?: boolean
|
||||
total?: boolean
|
||||
description?: boolean
|
||||
createdAt?: boolean
|
||||
receiptId?: boolean
|
||||
productId?: boolean
|
||||
@@ -708,12 +751,13 @@ export type PurchaseReceiptItemSelectScalar = {
|
||||
count?: boolean
|
||||
fee?: boolean
|
||||
total?: boolean
|
||||
description?: boolean
|
||||
createdAt?: boolean
|
||||
receiptId?: boolean
|
||||
productId?: boolean
|
||||
}
|
||||
|
||||
export type PurchaseReceiptItemOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "count" | "fee" | "total" | "createdAt" | "receiptId" | "productId", ExtArgs["result"]["purchaseReceiptItem"]>
|
||||
export type PurchaseReceiptItemOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "count" | "fee" | "total" | "description" | "createdAt" | "receiptId" | "productId", ExtArgs["result"]["purchaseReceiptItem"]>
|
||||
export type PurchaseReceiptItemInclude<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
product?: boolean | Prisma.ProductDefaultArgs<ExtArgs>
|
||||
receipt?: boolean | Prisma.PurchaseReceiptDefaultArgs<ExtArgs>
|
||||
@@ -730,6 +774,7 @@ export type $PurchaseReceiptItemPayload<ExtArgs extends runtime.Types.Extensions
|
||||
count: runtime.Decimal
|
||||
fee: runtime.Decimal
|
||||
total: runtime.Decimal
|
||||
description: string | null
|
||||
createdAt: Date
|
||||
receiptId: number
|
||||
productId: number
|
||||
@@ -1108,6 +1153,7 @@ export interface PurchaseReceiptItemFieldRefs {
|
||||
readonly count: Prisma.FieldRef<"PurchaseReceiptItem", 'Decimal'>
|
||||
readonly fee: Prisma.FieldRef<"PurchaseReceiptItem", 'Decimal'>
|
||||
readonly total: Prisma.FieldRef<"PurchaseReceiptItem", 'Decimal'>
|
||||
readonly description: Prisma.FieldRef<"PurchaseReceiptItem", 'String'>
|
||||
readonly createdAt: Prisma.FieldRef<"PurchaseReceiptItem", 'DateTime'>
|
||||
readonly receiptId: Prisma.FieldRef<"PurchaseReceiptItem", 'Int'>
|
||||
readonly productId: Prisma.FieldRef<"PurchaseReceiptItem", 'Int'>
|
||||
|
||||
@@ -31,4 +31,9 @@ export class InventoriesController {
|
||||
remove(@Param('id') id: string) {
|
||||
return this.inventoriesService.remove(Number(id))
|
||||
}
|
||||
|
||||
@Get(':id/stock-movements')
|
||||
findStockMovements(@Param('id') id: string) {
|
||||
return this.inventoriesService.findStockMovements(Number(id))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { ShortEntity } from '../common/interfaces/response-models'
|
||||
import { ResponseMapper } from '../common/response/response-mapper'
|
||||
import { PrismaService } from '../prisma/prisma.service'
|
||||
|
||||
@@ -12,52 +11,18 @@ export class InventoriesService {
|
||||
}
|
||||
|
||||
async findAll() {
|
||||
const items = await this.prisma.inventory.findMany({
|
||||
include: { productCharges: { include: { product: true } } },
|
||||
})
|
||||
const items = await this.prisma.inventory.findMany()
|
||||
|
||||
const mapped = items.map(i => {
|
||||
const productsMap: Record<number, ShortEntity> = {}
|
||||
for (const pc of i.productCharges ?? []) {
|
||||
if (pc.product) {
|
||||
productsMap[pc.product.id] = { id: pc.product.id, name: pc.product.name }
|
||||
}
|
||||
}
|
||||
const groupedProducts = Object.values(productsMap)
|
||||
const { productCharges, ...rest } = i as any
|
||||
return { ...rest, groupedProducts }
|
||||
})
|
||||
|
||||
return ResponseMapper.list(mapped)
|
||||
return ResponseMapper.list(items)
|
||||
}
|
||||
|
||||
async findOne(id: number) {
|
||||
const item = await this.prisma.inventory.findUnique({
|
||||
where: { id },
|
||||
include: { productCharges: { include: { product: true } } },
|
||||
include: { purchaseReceipts: true },
|
||||
})
|
||||
if (!item) return null
|
||||
const productsMap: Record<number, { id: number; name: string; count: number }> = {}
|
||||
for (const pc of item.productCharges ?? []) {
|
||||
const pid = pc.productId
|
||||
const pname = pc.product?.name ?? `#${pid}`
|
||||
if (!productsMap[pid]) productsMap[pid] = { id: pid, name: pname, count: 0 }
|
||||
productsMap[pid].count += Number(pc.count)
|
||||
}
|
||||
|
||||
const productsWithCount = Object.values(productsMap)
|
||||
const groupedProducts: ShortEntity[] = productsWithCount.map(p => ({
|
||||
id: p.id,
|
||||
name: p.name,
|
||||
}))
|
||||
|
||||
const { productCharges, ...rest } = item as any
|
||||
const itemWithCounts = {
|
||||
...rest,
|
||||
products: productsWithCount,
|
||||
groupedProducts,
|
||||
}
|
||||
return ResponseMapper.single(itemWithCounts)
|
||||
return ResponseMapper.single(item)
|
||||
}
|
||||
|
||||
async update(id: number, data: any) {
|
||||
@@ -69,4 +34,21 @@ export class InventoriesService {
|
||||
const item = await this.prisma.inventory.delete({ where: { id } })
|
||||
return ResponseMapper.single(item)
|
||||
}
|
||||
|
||||
async findStockMovements(inventoryId: number) {
|
||||
// Return a flat list of stock movements, each including its product info
|
||||
const movements = await this.prisma.stockMovement.findMany({
|
||||
where: { inventoryId },
|
||||
include: { product: true },
|
||||
})
|
||||
// Map each movement to have a 'products' array (even if only one product)
|
||||
const mapped = movements.map(movement => {
|
||||
const { product, ...rest } = movement
|
||||
return {
|
||||
...rest,
|
||||
products: product ? [product] : [],
|
||||
}
|
||||
})
|
||||
return ResponseMapper.list(mapped)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +1,25 @@
|
||||
import { Type } from 'class-transformer'
|
||||
import { IsInt, IsNumber } from 'class-validator'
|
||||
import { IsNotEmpty, IsNumber, Min } from 'class-validator'
|
||||
|
||||
export class CreatePurchaseReceiptItemDto {
|
||||
@Type(() => Number)
|
||||
@IsNumber()
|
||||
@Min(0)
|
||||
count: number
|
||||
|
||||
@Type(() => Number)
|
||||
@IsNumber()
|
||||
@Min(0)
|
||||
fee: number
|
||||
|
||||
@Type(() => Number)
|
||||
@IsNumber()
|
||||
@Min(0)
|
||||
total: number
|
||||
|
||||
@Type(() => Number)
|
||||
@IsInt()
|
||||
receiptId: number
|
||||
|
||||
@Type(() => Number)
|
||||
@IsInt()
|
||||
@IsNotEmpty()
|
||||
productId: number
|
||||
|
||||
description?: string
|
||||
}
|
||||
|
||||
@@ -9,15 +9,17 @@ export class PurchaseReceiptItemsService {
|
||||
|
||||
async create(dto: CreatePurchaseReceiptItemDto) {
|
||||
const payload: any = { ...dto }
|
||||
if (Object.prototype.hasOwnProperty.call(payload, 'receiptId')) {
|
||||
payload.receipt = { connect: { id: Number(payload.receiptId) } }
|
||||
delete payload.receiptId
|
||||
}
|
||||
if (Object.prototype.hasOwnProperty.call(payload, 'productId')) {
|
||||
payload.product = { connect: { id: Number(payload.productId) } }
|
||||
delete payload.productId
|
||||
}
|
||||
|
||||
if (Object.prototype.hasOwnProperty.call(payload, 'receiptId')) {
|
||||
payload.receipt = { connect: { id: Number(payload.receiptId) } }
|
||||
delete payload.receiptId
|
||||
}
|
||||
payload.fee = String(payload.fee)
|
||||
payload.count = String(payload.count)
|
||||
payload.total = String(payload.total)
|
||||
const item = await this.prisma.purchaseReceiptItem.create({ data: payload })
|
||||
return ResponseMapper.create(item)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Type } from 'class-transformer'
|
||||
import { IsInt, IsNumber, IsOptional, IsString } from 'class-validator'
|
||||
import { ArrayMinSize, IsInt, IsNumber, IsOptional, IsString } from 'class-validator'
|
||||
import { CreatePurchaseReceiptItemDto } from '../../purchase-receipt-items/dto/create-purchase-receipt-item.dto'
|
||||
|
||||
export class CreatePurchaseReceiptDto {
|
||||
@IsString()
|
||||
@@ -20,4 +21,8 @@ export class CreatePurchaseReceiptDto {
|
||||
@Type(() => Number)
|
||||
@IsInt()
|
||||
inventoryId: number
|
||||
|
||||
@Type(() => Array)
|
||||
@ArrayMinSize(1)
|
||||
items: Array<Omit<CreatePurchaseReceiptItemDto, 'receiptId'>>
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { ResponseMapper } from '../common/response/response-mapper'
|
||||
import { Prisma } from '../generated/prisma/client'
|
||||
import { PrismaService } from '../prisma/prisma.service'
|
||||
import { CreatePurchaseReceiptDto } from './dto/create-purchase-receipt.dto'
|
||||
|
||||
@@ -8,17 +9,32 @@ export class PurchaseReceiptsService {
|
||||
constructor(private prisma: PrismaService) {}
|
||||
|
||||
async create(dto: CreatePurchaseReceiptDto) {
|
||||
const payload: any = { ...dto }
|
||||
if (Object.prototype.hasOwnProperty.call(payload, 'supplierId')) {
|
||||
payload.supplier = { connect: { id: Number(payload.supplierId) } }
|
||||
delete payload.supplierId
|
||||
const data: Prisma.PurchaseReceiptCreateInput = {
|
||||
code: dto.code,
|
||||
totalAmount: new Prisma.Decimal(dto.totalAmount),
|
||||
description: dto.description ?? null,
|
||||
supplier: { connect: { id: dto.supplierId } },
|
||||
inventory: { connect: { id: dto.inventoryId } },
|
||||
items: dto.items?.length
|
||||
? {
|
||||
create: dto.items.map((item, idx) => {
|
||||
const mapped = {
|
||||
count: new Prisma.Decimal(item.count ?? 0),
|
||||
fee: new Prisma.Decimal(item.fee ?? 0),
|
||||
total: new Prisma.Decimal(item.total ?? 0),
|
||||
description: item.description ?? null,
|
||||
product: { connect: { id: item.productId } },
|
||||
}
|
||||
if (Object.prototype.hasOwnProperty.call(payload, 'inventoryId')) {
|
||||
payload.inventory = { connect: { id: Number(payload.inventoryId) } }
|
||||
delete payload.inventoryId
|
||||
console.log(`[create] Step 3: Mapped item ${idx}:`, mapped)
|
||||
return mapped
|
||||
}),
|
||||
}
|
||||
|
||||
const item = await this.prisma.purchaseReceipt.create({ data: payload })
|
||||
: undefined,
|
||||
}
|
||||
const item = await this.prisma.purchaseReceipt.create({
|
||||
data,
|
||||
include: { items: true },
|
||||
})
|
||||
return ResponseMapper.create(item)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user