feat: add config module with controller and service

- Implemented ConfigController for handling config-related requests.
- Created ConfigService for business logic related to configurations.
- Added CreateConfigDto for validating configuration data.

feat: add good categories module with controller and service

- Implemented GoodCategoriesController for managing good categories.
- Created GoodCategoriesService for business logic related to good categories.
- Added CreateGoodCategoryDto for validating good category data.

feat: add goods module with controller and service

- Implemented GoodsController for managing goods.
- Created GoodsService for business logic related to goods.
- Added CreateGoodDto for validating good data.

feat: add profile module with controller and service

- Implemented ProfileController for managing user profiles.
- Created ProfileService for business logic related to profiles.
- Added CreateProfileDto for profile data structure.

feat: add sales invoice payments module with controller and service

- Implemented SalesInvoicePaymentsController for managing invoice payments.
- Created SalesInvoicePaymentsService for business logic related to payments.
- Added CreateSalesInvoicePaymentDto for validating payment data.

feat: add service categories module with controller and service

- Implemented ServiceCategoriesController for managing service categories.
- Created ServiceCategoriesService for business logic related to service categories.
- Added CreateServiceCategoryDto for validating service category data.

feat: add services module with controller and service

- Implemented ServicesController for managing services.
- Created ServicesService for business logic related to services.
- Added CreateServiceDto for validating service data.

feat: add trigger logs module with controller and service

- Implemented TriggerLogsController for managing trigger logs.
- Created TriggerLogsService for business logic related to trigger logs.
- Added CreateTriggerLogDto for validating trigger log data.

feat: add uploaders module for handling file uploads

- Implemented UploadersController for managing file uploads.
- Created ImageUploaderService for image upload logic.
- Created UploaderService for file handling and storage.
This commit is contained in:
2026-02-12 20:31:04 +03:30
parent de14d531e1
commit a073af76fe
116 changed files with 6108 additions and 3977 deletions
@@ -0,0 +1,245 @@
/*
Warnings:
- The primary key for the `Sales_Invoice_Payments` table will be changed. If it partially fails, the table could be left without primary key constraint.
- You are about to drop the column `createdAt` on the `Sales_Invoice_Payments` table. All the data in the column will be lost.
- You are about to drop the column `invoiceId` on the `Sales_Invoice_Payments` table. All the data in the column will be lost.
- You are about to drop the column `paidAt` on the `Sales_Invoice_Payments` table. All the data in the column will be lost.
- You are about to drop the column `paymentMethod` on the `Sales_Invoice_Payments` table. All the data in the column will be lost.
- You are about to drop the `Customers` table. If the table is not empty, all the data it contains will be lost.
- You are about to drop the `Good_categories` table. If the table is not empty, all the data it contains will be lost.
- You are about to drop the `Goods` table. If the table is not empty, all the data it contains will be lost.
- You are about to drop the `Sales_Invoice_Items` table. If the table is not empty, all the data it contains will be lost.
- You are about to drop the `Sales_Invoices` table. If the table is not empty, all the data it contains will be lost.
- You are about to drop the `Service_categories` table. If the table is not empty, all the data it contains will be lost.
- You are about to drop the `Services` table. If the table is not empty, all the data it contains will be lost.
- You are about to drop the `Trigger_Logs` table. If the table is not empty, all the data it contains will be lost.
- Added the required column `invoice_id` to the `Sales_Invoice_Payments` table without a default value. This is not possible if the table is not empty.
- Added the required column `paid_at` to the `Sales_Invoice_Payments` table without a default value. This is not possible if the table is not empty.
- Added the required column `payment_method` to the `Sales_Invoice_Payments` table without a default value. This is not possible if the table is not empty.
*/
-- DropForeignKey
ALTER TABLE `Goods` DROP FOREIGN KEY `Goods_categoryId_fkey`;
-- DropForeignKey
ALTER TABLE `Sales_Invoice_Items` DROP FOREIGN KEY `Sales_Invoice_Items_goodId_fkey`;
-- DropForeignKey
ALTER TABLE `Sales_Invoice_Items` DROP FOREIGN KEY `Sales_Invoice_Items_invoiceId_fkey`;
-- DropForeignKey
ALTER TABLE `Sales_Invoice_Items` DROP FOREIGN KEY `Sales_Invoice_Items_serviceId_fkey`;
-- DropForeignKey
ALTER TABLE `Sales_Invoice_Payments` DROP FOREIGN KEY `Sales_Invoice_Payments_invoiceId_fkey`;
-- DropForeignKey
ALTER TABLE `Sales_Invoices` DROP FOREIGN KEY `Sales_Invoices_customerId_fkey`;
-- DropForeignKey
ALTER TABLE `Services` DROP FOREIGN KEY `Services_categoryId_fkey`;
-- DropIndex
DROP INDEX `Sales_Invoice_Payments_invoiceId_idx` ON `Sales_Invoice_Payments`;
-- AlterTable
ALTER TABLE `Sales_Invoice_Payments` DROP PRIMARY KEY,
DROP COLUMN `createdAt`,
DROP COLUMN `invoiceId`,
DROP COLUMN `paidAt`,
DROP COLUMN `paymentMethod`,
ADD COLUMN `created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
ADD COLUMN `invoice_id` VARCHAR(191) NOT NULL,
ADD COLUMN `paid_at` DATETIME(3) NOT NULL,
ADD COLUMN `payment_method` ENUM('CASH', 'CARD', 'BANK', 'CHECK', 'OTHER') NOT NULL,
MODIFY `id` VARCHAR(191) NOT NULL,
ADD PRIMARY KEY (`id`);
-- DropTable
DROP TABLE `Customers`;
-- DropTable
DROP TABLE `Good_categories`;
-- DropTable
DROP TABLE `Goods`;
-- DropTable
DROP TABLE `Sales_Invoice_Items`;
-- DropTable
DROP TABLE `Sales_Invoices`;
-- DropTable
DROP TABLE `Service_categories`;
-- DropTable
DROP TABLE `Services`;
-- DropTable
DROP TABLE `Trigger_Logs`;
-- CreateTable
CREATE TABLE `customers` (
`id` VARCHAR(191) NOT NULL,
`first_name` VARCHAR(255) NOT NULL,
`last_name` VARCHAR(255) NOT NULL,
`email` VARCHAR(255) NULL,
`mobile_number` CHAR(11) NOT NULL,
`address` TEXT NULL,
`is_active` BOOLEAN NOT NULL DEFAULT true,
`created_at` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
`updated_at` TIMESTAMP(0) NOT NULL,
`deleted_at` TIMESTAMP(0) NULL,
UNIQUE INDEX `customers_mobile_number_key`(`mobile_number`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `devices` (
`account_id` VARCHAR(255) NULL,
`app_version` VARCHAR(20) NOT NULL,
`build_number` VARCHAR(20) NOT NULL,
`device_id` VARCHAR(255) NOT NULL,
`platform` VARCHAR(100) NOT NULL,
`brand` VARCHAR(100) NOT NULL,
`model` VARCHAR(100) NOT NULL,
`device` VARCHAR(100) NOT NULL,
`os_version` VARCHAR(20) NOT NULL,
`sdk_version` VARCHAR(20) NOT NULL,
`release_number` VARCHAR(20) NOT NULL,
`browser_name` VARCHAR(100) NULL,
PRIMARY KEY (`device_id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `goods` (
`id` VARCHAR(191) NOT NULL,
`name` VARCHAR(255) NOT NULL,
`description` TEXT NULL,
`sku` VARCHAR(100) NOT NULL,
`local_sku` VARCHAR(100) NOT NULL,
`barcode` VARCHAR(100) NULL,
`created_at` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
`updated_at` TIMESTAMP(0) NOT NULL,
`deleted_at` TIMESTAMP(0) NULL,
`category_id` VARCHAR(191) NULL,
`base_sale_price` DECIMAL(15, 0) NOT NULL DEFAULT 0.00,
UNIQUE INDEX `goods_local_sku_key`(`local_sku`),
UNIQUE INDEX `goods_barcode_key`(`barcode`),
INDEX `goods_category_id_idx`(`category_id`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `good_categories` (
`id` VARCHAR(191) NOT NULL,
`name` VARCHAR(100) NOT NULL,
`description` TEXT NULL,
`image_url` VARCHAR(255) NULL,
`created_at` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
`updated_at` TIMESTAMP(0) NOT NULL,
`deleted_at` TIMESTAMP(0) NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `trigger_logs` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`message` TEXT NOT NULL,
`createdAt` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
`name` TEXT NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `sales_invoices` (
`id` VARCHAR(191) NOT NULL,
`code` VARCHAR(100) NOT NULL,
`total_amount` DECIMAL(15, 2) NOT NULL,
`description` TEXT NULL,
`created_at` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
`updated_at` TIMESTAMP(0) NOT NULL,
`customer_id` VARCHAR(191) NULL,
UNIQUE INDEX `sales_invoices_code_key`(`code`),
INDEX `sales_invoices_customer_id_idx`(`customer_id`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `sales_invoice_items` (
`id` VARCHAR(191) NOT NULL,
`count` DECIMAL(10, 0) NOT NULL,
`unit_price` DECIMAL(15, 2) NOT NULL DEFAULT 0.00,
`total_amount` DECIMAL(15, 2) NOT NULL DEFAULT 0.00,
`created_at` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
`invoice_id` VARCHAR(191) NOT NULL,
`good_id` VARCHAR(191) NOT NULL,
`service_id` VARCHAR(191) NOT NULL,
INDEX `sales_invoice_items_invoice_id_good_id_idx`(`invoice_id`, `good_id`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `services` (
`id` VARCHAR(191) NOT NULL,
`name` VARCHAR(255) NOT NULL,
`description` TEXT NULL,
`sku` VARCHAR(100) NOT NULL,
`barcode` VARCHAR(100) NULL,
`createdAt` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
`updatedAt` TIMESTAMP(0) NOT NULL,
`deletedAt` TIMESTAMP(0) NULL,
`categoryId` VARCHAR(191) NULL,
`baseSalePrice` DECIMAL(15, 0) NOT NULL DEFAULT 0.00,
UNIQUE INDEX `services_sku_key`(`sku`),
UNIQUE INDEX `services_barcode_key`(`barcode`),
INDEX `services_categoryId_idx`(`categoryId`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `service_categories` (
`id` VARCHAR(191) NOT NULL,
`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;
-- CreateIndex
CREATE INDEX `Sales_Invoice_Payments_invoice_id_idx` ON `Sales_Invoice_Payments`(`invoice_id`);
-- AddForeignKey
ALTER TABLE `goods` ADD CONSTRAINT `goods_category_id_fkey` FOREIGN KEY (`category_id`) REFERENCES `good_categories`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `sales_invoices` ADD CONSTRAINT `sales_invoices_customer_id_fkey` FOREIGN KEY (`customer_id`) REFERENCES `customers`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `sales_invoice_items` ADD CONSTRAINT `sales_invoice_items_invoice_id_fkey` FOREIGN KEY (`invoice_id`) REFERENCES `sales_invoices`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `sales_invoice_items` ADD CONSTRAINT `sales_invoice_items_good_id_fkey` FOREIGN KEY (`good_id`) REFERENCES `goods`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `sales_invoice_items` ADD CONSTRAINT `sales_invoice_items_service_id_fkey` FOREIGN KEY (`service_id`) REFERENCES `services`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `Sales_Invoice_Payments` ADD CONSTRAINT `Sales_Invoice_Payments_invoice_id_fkey` FOREIGN KEY (`invoice_id`) REFERENCES `sales_invoices`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `services` ADD CONSTRAINT `services_categoryId_fkey` FOREIGN KEY (`categoryId`) REFERENCES `service_categories`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
@@ -0,0 +1,13 @@
/*
Warnings:
- The primary key for the `devices` table will be changed. If it partially fails, the table could be left without primary key constraint.
- You are about to drop the column `device_id` on the `devices` table. All the data in the column will be lost.
- Added the required column `uuid` to the `devices` table without a default value. This is not possible if the table is not empty.
*/
-- AlterTable
ALTER TABLE `devices` DROP PRIMARY KEY,
DROP COLUMN `device_id`,
ADD COLUMN `uuid` VARCHAR(255) NOT NULL,
ADD PRIMARY KEY (`uuid`);
@@ -0,0 +1,8 @@
/*
Warnings:
- A unique constraint covering the columns `[uuid]` on the table `devices` will be added. If there are existing duplicate values, this will fail.
*/
-- CreateIndex
CREATE UNIQUE INDEX `devices_uuid_key` ON `devices`(`uuid`);
@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE `devices` ADD COLUMN `fcm_token` VARCHAR(100) NULL;
@@ -0,0 +1,87 @@
/*
Warnings:
- You are about to drop the column `createdAt` on the `service_categories` table. All the data in the column will be lost.
- You are about to drop the column `deletedAt` on the `service_categories` table. All the data in the column will be lost.
- You are about to drop the column `imageUrl` on the `service_categories` table. All the data in the column will be lost.
- You are about to drop the column `updatedAt` on the `service_categories` table. All the data in the column will be lost.
- You are about to drop the column `baseSalePrice` on the `services` table. All the data in the column will be lost.
- You are about to drop the column `categoryId` on the `services` table. All the data in the column will be lost.
- You are about to drop the column `createdAt` on the `services` table. All the data in the column will be lost.
- You are about to drop the column `deletedAt` on the `services` table. All the data in the column will be lost.
- You are about to drop the column `updatedAt` on the `services` table. All the data in the column will be lost.
- A unique constraint covering the columns `[local_sku]` on the table `services` will be added. If there are existing duplicate values, this will fail.
- Added the required column `account_id` to the `customers` table without a default value. This is not possible if the table is not empty.
- Added the required column `complex_id` to the `customers` table without a default value. This is not possible if the table is not empty.
- Added the required column `account_id` to the `good_categories` table without a default value. This is not possible if the table is not empty.
- Added the required column `complex_id` to the `good_categories` table without a default value. This is not possible if the table is not empty.
- Added the required column `account_id` to the `goods` table without a default value. This is not possible if the table is not empty.
- Added the required column `complex_id` to the `goods` table without a default value. This is not possible if the table is not empty.
- Added the required column `account_id` to the `sales_invoices` table without a default value. This is not possible if the table is not empty.
- Added the required column `complex_id` to the `sales_invoices` table without a default value. This is not possible if the table is not empty.
- Added the required column `account_id` to the `service_categories` table without a default value. This is not possible if the table is not empty.
- Added the required column `complex_id` to the `service_categories` table without a default value. This is not possible if the table is not empty.
- Added the required column `updated_at` to the `service_categories` table without a default value. This is not possible if the table is not empty.
- Added the required column `account_id` to the `services` table without a default value. This is not possible if the table is not empty.
- Added the required column `complex_id` to the `services` table without a default value. This is not possible if the table is not empty.
- Added the required column `updated_at` to the `services` table without a default value. This is not possible if the table is not empty.
*/
-- DropForeignKey
ALTER TABLE `services` DROP FOREIGN KEY `services_categoryId_fkey`;
-- DropIndex
DROP INDEX `services_categoryId_idx` ON `services`;
-- AlterTable
ALTER TABLE `customers` ADD COLUMN `account_id` VARCHAR(191) NOT NULL,
ADD COLUMN `complex_id` VARCHAR(191) NOT NULL;
-- AlterTable
ALTER TABLE `good_categories` ADD COLUMN `account_id` VARCHAR(191) NOT NULL,
ADD COLUMN `complex_id` VARCHAR(191) NOT NULL;
-- AlterTable
ALTER TABLE `goods` ADD COLUMN `account_id` VARCHAR(191) NOT NULL,
ADD COLUMN `complex_id` VARCHAR(191) NOT NULL,
MODIFY `local_sku` VARCHAR(100) NULL;
-- AlterTable
ALTER TABLE `sales_invoices` ADD COLUMN `account_id` VARCHAR(191) NOT NULL,
ADD COLUMN `complex_id` VARCHAR(191) NOT NULL;
-- AlterTable
ALTER TABLE `service_categories` DROP COLUMN `createdAt`,
DROP COLUMN `deletedAt`,
DROP COLUMN `imageUrl`,
DROP COLUMN `updatedAt`,
ADD COLUMN `account_id` VARCHAR(191) NOT NULL,
ADD COLUMN `complex_id` VARCHAR(191) NOT NULL,
ADD COLUMN `created_at` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
ADD COLUMN `deleted_at` TIMESTAMP(0) NULL,
ADD COLUMN `image_url` VARCHAR(255) NULL,
ADD COLUMN `updated_at` TIMESTAMP(0) NOT NULL;
-- AlterTable
ALTER TABLE `services` DROP COLUMN `baseSalePrice`,
DROP COLUMN `categoryId`,
DROP COLUMN `createdAt`,
DROP COLUMN `deletedAt`,
DROP COLUMN `updatedAt`,
ADD COLUMN `account_id` VARCHAR(191) NOT NULL,
ADD COLUMN `base_sale_price` DECIMAL(15, 0) NOT NULL DEFAULT 0.00,
ADD COLUMN `category_id` VARCHAR(191) NULL,
ADD COLUMN `complex_id` VARCHAR(191) NOT NULL,
ADD COLUMN `created_at` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
ADD COLUMN `deleted_at` TIMESTAMP(0) NULL,
ADD COLUMN `local_sku` VARCHAR(100) NULL,
ADD COLUMN `updated_at` TIMESTAMP(0) NOT NULL;
-- CreateIndex
CREATE UNIQUE INDEX `services_local_sku_key` ON `services`(`local_sku`);
-- CreateIndex
CREATE INDEX `services_category_id_idx` ON `services`(`category_id`);
-- AddForeignKey
ALTER TABLE `services` ADD CONSTRAINT `services_category_id_fkey` FOREIGN KEY (`category_id`) REFERENCES `service_categories`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
@@ -0,0 +1,27 @@
/*
Warnings:
- You are about to drop the `Sales_Invoice_Payments` table. If the table is not empty, all the data it contains will be lost.
*/
-- DropForeignKey
ALTER TABLE `Sales_Invoice_Payments` DROP FOREIGN KEY `Sales_Invoice_Payments_invoice_id_fkey`;
-- DropTable
DROP TABLE `Sales_Invoice_Payments`;
-- CreateTable
CREATE TABLE `sales_invoice_payments` (
`id` VARCHAR(191) NOT NULL,
`invoice_id` VARCHAR(191) NOT NULL,
`amount` DECIMAL(15, 2) NOT NULL,
`payment_method` ENUM('CASH', 'CARD', 'BANK', 'CHECK', 'OTHER') NOT NULL,
`paid_at` DATETIME(3) NOT NULL,
`created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
INDEX `sales_invoice_payments_invoice_id_idx`(`invoice_id`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- AddForeignKey
ALTER TABLE `sales_invoice_payments` ADD CONSTRAINT `sales_invoice_payments_invoice_id_fkey` FOREIGN KEY (`invoice_id`) REFERENCES `sales_invoices`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
+19
View File
@@ -0,0 +1,19 @@
model Customer {
id String @id @default(uuid())
first_name String @db.VarChar(255)
last_name String @db.VarChar(255)
email String? @db.VarChar(255)
mobile_number String @unique @db.Char(11)
address String? @db.Text
is_active Boolean @default(true)
account_id String
complex_id String
created_at DateTime @default(now()) @db.Timestamp(0)
updated_at DateTime @updatedAt @db.Timestamp(0)
deleted_at DateTime? @db.Timestamp(0)
sales_invoices SalesInvoice[]
@@map("customers")
}
+18
View File
@@ -0,0 +1,18 @@
model Device {
account_id String? @db.VarChar(255)
app_version String @db.VarChar(20)
build_number String @db.VarChar(20)
uuid String @id @unique() @db.VarChar(255)
platform String @db.VarChar(100)
brand String @db.VarChar(100)
model String @db.VarChar(100)
device String @db.VarChar(100)
os_version String @db.VarChar(20)
sdk_version String @db.VarChar(20)
release_number String @db.VarChar(20)
browser_name String? @db.VarChar(100)
fcm_token String? @db.VarChar(100)
@@map("devices")
}
+28 -22
View File
@@ -1,31 +1,37 @@
model Good {
id Int @id @default(autoincrement())
name String @db.VarChar(255)
description String? @db.Text
sku String @db.VarChar(100)
localSku String @unique() @db.VarChar(100)
barcode String? @unique() @db.VarChar(100)
createdAt DateTime @default(now()) @db.Timestamp(0)
updatedAt DateTime @updatedAt @db.Timestamp(0)
deletedAt DateTime? @db.Timestamp(0)
categoryId Int?
baseSalePrice Decimal @default(0.00) @db.Decimal(15, 0)
category GoodCategory? @relation(fields: [categoryId], references: [id])
salesInvoiceItems SalesInvoiceItem[]
id String @id @default(uuid())
name String @db.VarChar(255)
description String? @db.Text
sku String @db.VarChar(100)
local_sku String? @unique() @db.VarChar(100)
barcode String? @unique() @db.VarChar(100)
created_at DateTime @default(now()) @db.Timestamp(0)
updated_at DateTime @updatedAt @db.Timestamp(0)
deleted_at DateTime? @db.Timestamp(0)
category_id String?
base_sale_price Decimal @default(0.00) @db.Decimal(15, 0)
account_id String
complex_id String
@@index([categoryId])
@@map("Goods")
category GoodCategory? @relation(fields: [category_id], references: [id])
sales_invoice_items SalesInvoiceItem[]
@@index([category_id])
@@map("goods")
}
model GoodCategory {
id Int @id @default(autoincrement())
id String @id @default(uuid())
name String @db.VarChar(100)
description String? @db.Text
imageUrl String? @db.VarChar(255)
createdAt DateTime @default(now()) @db.Timestamp(0)
updatedAt DateTime @updatedAt @db.Timestamp(0)
deletedAt DateTime? @db.Timestamp(0)
goods Good[]
image_url String? @db.VarChar(255)
account_id String
complex_id String
created_at DateTime @default(now()) @db.Timestamp(0)
updated_at DateTime @updatedAt @db.Timestamp(0)
deleted_at DateTime? @db.Timestamp(0)
@@map("Good_categories")
goods Good[]
@@map("good_categories")
}
+1 -17
View File
@@ -1,24 +1,8 @@
model Customer {
id Int @id @default(autoincrement())
firstName String @db.VarChar(255)
lastName String @db.VarChar(255)
email String? @db.VarChar(255)
mobileNumber String @unique @db.Char(11)
address String? @db.Text
isActive Boolean @default(true)
createdAt DateTime @default(now()) @db.Timestamp(0)
updatedAt DateTime @updatedAt @db.Timestamp(0)
deletedAt DateTime? @db.Timestamp(0)
salesInvoices SalesInvoice[]
@@map("Customers")
}
model TriggerLog {
id Int @id @default(autoincrement())
message String @db.Text
createdAt DateTime @default(now()) @db.Timestamp(0)
name String @db.Text
@@map("Trigger_Logs")
@@map("trigger_logs")
}
+38 -34
View File
@@ -1,46 +1,50 @@
model SalesInvoice {
id Int @id @default(autoincrement())
code String @unique @db.VarChar(100)
totalAmount Decimal @db.Decimal(15, 2)
description String? @db.Text
createdAt DateTime @default(now()) @db.Timestamp(0)
updatedAt DateTime @updatedAt @db.Timestamp(0)
customerId Int?
customer Customer? @relation(fields: [customerId], references: [id])
items SalesInvoiceItem[]
salesInvoicePayments SalesInvoicePayment[]
id String @id @default(uuid())
code String @unique @db.VarChar(100)
total_amount Decimal @db.Decimal(15, 2)
description String? @db.Text
created_at DateTime @default(now()) @db.Timestamp(0)
updated_at DateTime @updatedAt @db.Timestamp(0)
customer_id String?
account_id String
complex_id String
@@index([customerId])
@@map("Sales_Invoices")
customer Customer? @relation(fields: [customer_id], references: [id])
items SalesInvoiceItem[]
sales_invoice_payments SalesInvoicePayment[]
@@index([customer_id])
@@map("sales_invoices")
}
model SalesInvoiceItem {
id Int @id @default(autoincrement())
count Decimal @db.Decimal(10, 0)
unitPrice Decimal @default(0.00) @db.Decimal(15, 2)
totalAmount Decimal @default(0.00) @db.Decimal(15, 2)
createdAt DateTime @default(now()) @db.Timestamp(0)
invoiceId Int
goodId Int
serviceId Int
invoice SalesInvoice @relation(fields: [invoiceId], references: [id])
good Good? @relation(fields: [goodId], references: [id])
service Service? @relation(fields: [serviceId], references: [id])
id String @id @default(uuid())
count Decimal @db.Decimal(10, 0)
unit_price Decimal @default(0.00) @db.Decimal(15, 2)
total_amount Decimal @default(0.00) @db.Decimal(15, 2)
created_at DateTime @default(now()) @db.Timestamp(0)
invoice_id String
good_id String
service_id String
@@index([invoiceId, goodId])
@@map("Sales_Invoice_Items")
invoice SalesInvoice @relation(fields: [invoice_id], references: [id])
good Good? @relation(fields: [good_id], references: [id])
service Service? @relation(fields: [service_id], references: [id])
@@index([invoice_id, good_id])
@@map("sales_invoice_items")
}
model SalesInvoicePayment {
id Int @id @default(autoincrement())
invoiceId Int
amount Decimal @db.Decimal(15, 2)
paymentMethod PaymentMethodType
paidAt DateTime
createdAt DateTime @default(now())
id String @id @default(uuid())
invoice_id String
amount Decimal @db.Decimal(15, 2)
payment_method PaymentMethodType
paid_at DateTime
created_at DateTime @default(now())
invoice SalesInvoice @relation(fields: [invoiceId], references: [id])
invoice SalesInvoice @relation(fields: [invoice_id], references: [id])
@@index([invoiceId])
@@map("Sales_Invoice_Payments")
@@index([invoice_id])
@@map("sales_invoice_payments")
}
+28 -21
View File
@@ -1,30 +1,37 @@
model Service {
id Int @id @default(autoincrement())
name String @db.VarChar(255)
description String? @db.Text
sku String @unique() @db.VarChar(100)
barcode String? @unique() @db.VarChar(100)
createdAt DateTime @default(now()) @db.Timestamp(0)
updatedAt DateTime @updatedAt @db.Timestamp(0)
deletedAt DateTime? @db.Timestamp(0)
categoryId Int?
baseSalePrice Decimal @default(0.00) @db.Decimal(15, 0)
category ServiceCategory? @relation(fields: [categoryId], references: [id])
salesInvoiceItems SalesInvoiceItem[]
id String @id @default(uuid())
name String @db.VarChar(255)
description String? @db.Text
sku String @unique() @db.VarChar(100)
local_sku String? @unique() @db.VarChar(100)
barcode String? @unique() @db.VarChar(100)
created_at DateTime @default(now()) @db.Timestamp(0)
updated_at DateTime @updatedAt @db.Timestamp(0)
deleted_at DateTime? @db.Timestamp(0)
category_id String?
base_sale_price Decimal @default(0.00) @db.Decimal(15, 0)
account_id String
complex_id String
@@index([categoryId])
@@map("Services")
category ServiceCategory? @relation(fields: [category_id], references: [id])
sales_invoice_items SalesInvoiceItem[]
@@index([category_id])
@@map("services")
}
model ServiceCategory {
id Int @id @default(autoincrement())
id String @id @default(uuid())
name String @db.VarChar(100)
description String? @db.Text
imageUrl String? @db.VarChar(255)
createdAt DateTime @default(now()) @db.Timestamp(0)
updatedAt DateTime @updatedAt @db.Timestamp(0)
deletedAt DateTime? @db.Timestamp(0)
services Service[]
image_url String? @db.VarChar(255)
account_id String
complex_id String
created_at DateTime @default(now()) @db.Timestamp(0)
updated_at DateTime @updatedAt @db.Timestamp(0)
deleted_at DateTime? @db.Timestamp(0)
@@map("Service_categories")
services Service[]
@@map("service_categories")
}
+314 -315
View File
@@ -1,321 +1,320 @@
import { prisma } from '../src/lib/prisma'
async function main() {
if ((await prisma.role.count()) === 0) {
await prisma.role.upsert({
where: { id: 0, name: 'Admin' },
update: {},
create: {
name: 'Admin',
},
})
}
if ((await prisma.user.count()) === 0) {
const adminRole = await prisma.role.findUnique({ where: { name: 'Admin' } })
if (!adminRole) {
return
}
await prisma.user.upsert({
where: { id: 1, firstName: 'عباس', lastName: 'حسنی' },
update: {},
create: {
firstName: 'عباس',
lastName: 'حسنی',
roleId: adminRole.id,
mobileNumber: '09120258156',
password: '12345678',
},
})
}
if ((await prisma.inventory.count()) === 0) {
await prisma.inventory.createMany({
data: [
{ name: 'انبار مرکزی', location: 'تهران', isPointOfSale: false, isActive: true },
{
name: 'فروشگاه حضوری',
location: 'مرکز شهر',
isPointOfSale: true,
isActive: true,
},
{
name: 'فروشگاه اینترنتی',
location: 'مرکز شهر',
isPointOfSale: true,
isActive: true,
},
],
})
}
if ((await prisma.productCategory.count()) === 0) {
await prisma.productCategory.createMany({
data: Array.from({ length: 10 }, (_, i) => ({ name: `دسته‌ی ${i + 1}` })),
})
}
if ((await prisma.productBrand.count()) === 0) {
await prisma.productBrand.createMany({
data: Array.from({ length: 10 }, (_, i) => ({ name: `برند ${i + 1}` })),
})
}
if ((await prisma.supplier.count()) === 0) {
await prisma.supplier.createMany({
data: Array.from({ length: 9 }, (_, i) => ({
firstName: 'تامین‌',
lastName: `کننده ${i + 1}`,
mobileNumber: `0912000000${i + 1}`,
email: `supplier${i + 1}@example.com`,
})),
})
}
if ((await prisma.customer.count()) === 0) {
await prisma.customer.createMany({
data: Array.from({ length: 5 }, (_, i) => ({
firstName: 'مشتری',
lastName: `${i + 1}`,
mobileNumber: `0913000000${i + 1}`,
email: `customer${i + 1}@example.com`,
})),
})
}
if ((await prisma.product.count()) === 0) {
const categories = await prisma.productCategory.findMany()
const brands = await prisma.productBrand.findMany()
await prisma.product.createMany({
data: Array.from({ length: 20 }, (_, i) => ({
name: `کالای ${i + 1}`,
sku: `SKU-${1000 + i + 1}`,
salePrice: parseInt((Math.random() * (100 - 10) + 10).toString()) * 10000,
categoryId: categories[i % categories.length].id,
brandId: brands[i % brands.length].id,
})),
})
}
if ((await prisma.bank.count()) === 0) {
await prisma.bank.createMany({
data: [
{
name: 'آینده',
shortName: 'ain',
},
{
name: 'ایران زمین',
shortName: 'irz',
},
{
name: 'اقتصاد نوین',
shortName: 'eqn',
},
{
name: 'انصار',
shortName: 'ans',
},
{
name: 'پاسارگاد',
shortName: 'pas',
},
{
name: 'پارسیان',
shortName: 'prs',
},
{
name: 'پست‌ بانک ایران',
shortName: 'pbi',
},
{
name: 'تجارت',
shortName: 'tej',
},
{
name: 'توسعه تعاون',
shortName: 'tav',
},
{
name: 'توسعه صادرات',
shortName: 'tes',
},
{
name: 'حکمت ایرانیان',
shortName: 'hek',
},
{
name: 'رفاه کارگران',
shortName: 'ref',
},
{
name: 'قرض‌الحسنه رسالت',
shortName: 'res',
},
{
name: 'قرض‌الحسنه مهر ایران',
shortName: 'meh',
},
{
name: 'قوامین',
shortName: 'qva',
},
{
name: 'کشاورزی',
shortName: 'kes',
},
{
name: 'کوثر',
shortName: 'kos',
},
{
name: 'دی',
shortName: 'diy',
},
{
name: 'صنعت و معدن',
shortName: 'san',
},
{
name: 'سینا',
shortName: 'sin',
},
{
name: 'سرمایه',
shortName: 'sar',
},
{
name: 'سپه',
shortName: 'sep',
},
{
name: 'شهر',
shortName: 'shr',
},
{
name: 'صادرات ایران',
shortName: 'sir',
},
{
name: 'سامان',
shortName: 'sam',
},
{
name: 'مرکزی',
shortName: 'mar',
},
{
name: 'مسکن',
shortName: 'mas',
},
{
name: 'ملت',
shortName: 'mel',
},
{
name: 'ملی ایران',
shortName: 'mli',
},
{
name: 'مهر اقتصاد',
shortName: 'meg',
},
{
name: 'کارآفرین',
shortName: 'kar',
},
{
name: 'تات',
shortName: 'tat',
},
],
})
}
if ((await prisma.bankBranch.count()) === 0) {
await prisma.bankBranch.createMany({
data: [
{
bankId: 1,
name: 'شعبه مرکزی',
code: '001',
},
{
bankId: 2,
name: 'شعبه مرکزی',
code: '002',
},
{
bankId: 1,
name: 'شعبه ونک',
code: '003',
},
],
})
}
if ((await prisma.bankAccount.count()) === 0) {
await prisma.bankAccount.createMany({
data: [
{
branchId: 1,
accountNumber: '1234567890',
name: 'حساب اصلی آینده',
iban: 'IR000123456789012345678901',
},
{
branchId: 2,
accountNumber: '0987654321',
name: 'حساب اصلی ایران زمین',
iban: 'IR000987654321098765432109',
},
{
branchId: 3,
accountNumber: '1122334455',
name: 'حساب ونک آینده',
iban: 'IR000112233445566778899001',
},
],
})
}
if ((await prisma.inventoryBankAccount.count()) === 0) {
const inventories = await prisma.inventory.findMany()
const bankAccounts = await prisma.bankAccount.findMany()
if (inventories.length || bankAccounts.length) {
// Assign bank accounts to inventories
const inventoryBankAccounts = []
for (let i = 0; i < inventories.length; i++) {
const inventory = inventories[i]
const bankAccount = bankAccounts[i % bankAccounts.length] // Cycle through bank accounts
// @ts-ignore
inventoryBankAccounts.push({
inventoryId: inventory.id,
bankAccountId: bankAccount.id,
})
}
await prisma.inventoryBankAccount.createMany({
data: inventoryBankAccounts,
})
}
}
if ((await prisma.posAccount.count()) === 0) {
const inventories = await prisma.inventory.findMany({
where: { isPointOfSale: true },
})
const inventoryBankAccounts = await prisma.inventoryBankAccount.findMany()
const posAccounts = []
for (let i = 0; i < inventories.length; i++) {
const inventory = inventories[i]
// Find a bank account assigned to this inventory
const inventoryBankAccount = inventoryBankAccounts.find(
iba => iba.inventoryId === inventory.id,
)
if (inventoryBankAccount) {
// @ts-ignore
posAccounts.push({
name: `پوز ${inventory.name}`,
code: `POS${(i + 1).toString().padStart(3, '0')}`,
description: `پوز فروشگاه ${inventory.name}`,
inventoryId: inventory.id,
bankAccountId: inventoryBankAccount.bankAccountId,
})
}
}
await prisma.posAccount.createMany({
data: posAccounts,
})
}
// if ((await prisma.role.count()) === 0) {
// await prisma.role.upsert({
// where: { id: 0, name: 'Admin' },
// update: {},
// create: {
// name: 'Admin',
// },
// })
// }
// if ((await prisma.user.count()) === 0) {
// const adminRole = await prisma.role.findUnique({ where: { name: 'Admin' } })
// if (!adminRole) {
// return
// }
// await prisma.user.upsert({
// where: { id: 1, firstName: 'عباس', lastName: 'حسنی' },
// update: {},
// create: {
// firstName: 'عباس',
// lastName: 'حسنی',
// roleId: adminRole.id,
// mobileNumber: '09120258156',
// password: '12345678',
// },
// })
// }
// if ((await prisma.inventory.count()) === 0) {
// await prisma.inventory.createMany({
// data: [
// { name: 'انبار مرکزی', location: 'تهران', isPointOfSale: false, isActive: true },
// {
// name: 'فروشگاه حضوری',
// location: 'مرکز شهر',
// isPointOfSale: true,
// isActive: true,
// },
// {
// name: 'فروشگاه اینترنتی',
// location: 'مرکز شهر',
// isPointOfSale: true,
// isActive: true,
// },
// ],
// })
// }
// if ((await prisma.productCategory.count()) === 0) {
// await prisma.productCategory.createMany({
// data: Array.from({ length: 10 }, (_, i) => ({ name: `دسته‌ی ${i + 1}` })),
// })
// }
// if ((await prisma.productBrand.count()) === 0) {
// await prisma.productBrand.createMany({
// data: Array.from({ length: 10 }, (_, i) => ({ name: `برند ${i + 1}` })),
// })
// }
// if ((await prisma.supplier.count()) === 0) {
// await prisma.supplier.createMany({
// data: Array.from({ length: 9 }, (_, i) => ({
// firstName: 'تامین‌',
// lastName: `کننده ${i + 1}`,
// mobileNumber: `0912000000${i + 1}`,
// email: `supplier${i + 1}@example.com`,
// })),
// })
// }
// if ((await prisma.customer.count()) === 0) {
// await prisma.customer.createMany({
// data: Array.from({ length: 5 }, (_, i) => ({
// firstName: 'مشتری',
// lastName: `${i + 1}`,
// mobileNumber: `0913000000${i + 1}`,
// email: `customer${i + 1}@example.com`,
// })),
// })
// }
// if ((await prisma.product.count()) === 0) {
// const categories = await prisma.productCategory.findMany()
// const brands = await prisma.productBrand.findMany()
// await prisma.product.createMany({
// data: Array.from({ length: 20 }, (_, i) => ({
// name: `کالای ${i + 1}`,
// sku: `SKU-${1000 + i + 1}`,
// salePrice: parseInt((Math.random() * (100 - 10) + 10).toString()) * 10000,
// categoryId: categories[i % categories.length].id,
// brandId: brands[i % brands.length].id,
// })),
// })
// }
// if ((await prisma.bank.count()) === 0) {
// await prisma.bank.createMany({
// data: [
// {
// name: 'آینده',
// shortName: 'ain',
// },
// {
// name: 'ایران زمین',
// shortName: 'irz',
// },
// {
// name: 'اقتصاد نوین',
// shortName: 'eqn',
// },
// {
// name: 'انصار',
// shortName: 'ans',
// },
// {
// name: 'پاسارگاد',
// shortName: 'pas',
// },
// {
// name: 'پارسیان',
// shortName: 'prs',
// },
// {
// name: 'پست‌ بانک ایران',
// shortName: 'pbi',
// },
// {
// name: 'تجارت',
// shortName: 'tej',
// },
// {
// name: 'توسعه تعاون',
// shortName: 'tav',
// },
// {
// name: 'توسعه صادرات',
// shortName: 'tes',
// },
// {
// name: 'حکمت ایرانیان',
// shortName: 'hek',
// },
// {
// name: 'رفاه کارگران',
// shortName: 'ref',
// },
// {
// name: 'قرض‌الحسنه رسالت',
// shortName: 'res',
// },
// {
// name: 'قرض‌الحسنه مهر ایران',
// shortName: 'meh',
// },
// {
// name: 'قوامین',
// shortName: 'qva',
// },
// {
// name: 'کشاورزی',
// shortName: 'kes',
// },
// {
// name: 'کوثر',
// shortName: 'kos',
// },
// {
// name: 'دی',
// shortName: 'diy',
// },
// {
// name: 'صنعت و معدن',
// shortName: 'san',
// },
// {
// name: 'سینا',
// shortName: 'sin',
// },
// {
// name: 'سرمایه',
// shortName: 'sar',
// },
// {
// name: 'سپه',
// shortName: 'sep',
// },
// {
// name: 'شهر',
// shortName: 'shr',
// },
// {
// name: 'صادرات ایران',
// shortName: 'sir',
// },
// {
// name: 'سامان',
// shortName: 'sam',
// },
// {
// name: 'مرکزی',
// shortName: 'mar',
// },
// {
// name: 'مسکن',
// shortName: 'mas',
// },
// {
// name: 'ملت',
// shortName: 'mel',
// },
// {
// name: 'ملی ایران',
// shortName: 'mli',
// },
// {
// name: 'مهر اقتصاد',
// shortName: 'meg',
// },
// {
// name: 'کارآفرین',
// shortName: 'kar',
// },
// {
// name: 'تات',
// shortName: 'tat',
// },
// ],
// })
// }
// if ((await prisma.bankBranch.count()) === 0) {
// await prisma.bankBranch.createMany({
// data: [
// {
// bankId: 1,
// name: 'شعبه مرکزی',
// code: '001',
// },
// {
// bankId: 2,
// name: 'شعبه مرکزی',
// code: '002',
// },
// {
// bankId: 1,
// name: 'شعبه ونک',
// code: '003',
// },
// ],
// })
// }
// if ((await prisma.bankAccount.count()) === 0) {
// await prisma.bankAccount.createMany({
// data: [
// {
// branchId: 1,
// accountNumber: '1234567890',
// name: 'حساب اصلی آینده',
// iban: 'IR000123456789012345678901',
// },
// {
// branchId: 2,
// accountNumber: '0987654321',
// name: 'حساب اصلی ایران زمین',
// iban: 'IR000987654321098765432109',
// },
// {
// branchId: 3,
// accountNumber: '1122334455',
// name: 'حساب ونک آینده',
// iban: 'IR000112233445566778899001',
// },
// ],
// })
// }
// if ((await prisma.inventoryBankAccount.count()) === 0) {
// const inventories = await prisma.inventory.findMany()
// const bankAccounts = await prisma.bankAccount.findMany()
// if (inventories.length || bankAccounts.length) {
// // Assign bank accounts to inventories
// const inventoryBankAccounts = []
// for (let i = 0; i < inventories.length; i++) {
// const inventory = inventories[i]
// const bankAccount = bankAccounts[i % bankAccounts.length] // Cycle through bank accounts
// // @ts-ignore
// inventoryBankAccounts.push({
// inventoryId: inventory.id,
// bankAccountId: bankAccount.id,
// })
// }
// await prisma.inventoryBankAccount.createMany({
// data: inventoryBankAccounts,
// })
// }
// }
// if ((await prisma.posAccount.count()) === 0) {
// const inventories = await prisma.inventory.findMany({
// where: { isPointOfSale: true },
// })
// const inventoryBankAccounts = await prisma.inventoryBankAccount.findMany()
// const posAccounts = []
// for (let i = 0; i < inventories.length; i++) {
// const inventory = inventories[i]
// // Find a bank account assigned to this inventory
// const inventoryBankAccount = inventoryBankAccounts.find(
// iba => iba.inventoryId === inventory.id,
// )
// if (inventoryBankAccount) {
// // @ts-ignore
// posAccounts.push({
// name: `پوز ${inventory.name}`,
// code: `POS${(i + 1).toString().padStart(3, '0')}`,
// description: `پوز فروشگاه ${inventory.name}`,
// inventoryId: inventory.id,
// bankAccountId: inventoryBankAccount.bankAccountId,
// })
// }
// }
// await prisma.posAccount.createMany({
// data: posAccounts,
// })
// }
// Seed purchase, transfer, and sales transactions
// const inventories = await prisma.inventory.findMany()
// const products = await prisma.product.findMany({ take: 5 }) // select 5 products for demo