Compare commits
18 Commits
c11166b365
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 636daca703 | |||
| 9bf294a1f3 | |||
| 839f6de691 | |||
| 826041b07a | |||
| f87e5b9d8e | |||
| 652177862d | |||
| ac2e7f5dab | |||
| f94a108948 | |||
| d51b677f26 | |||
| 9170d8cd5a | |||
| 5f70b95589 | |||
| d2bd576277 | |||
| 23bfe1ecbe | |||
| 47a27fb54f | |||
| f61100bf25 | |||
| 25e589551b | |||
| 5ce560ce97 | |||
| b2d8fdc8a0 |
@@ -128,3 +128,55 @@ Typecheck before handoff:
|
||||
```bash
|
||||
pnpm -s tsc --noEmit
|
||||
```
|
||||
|
||||
# INVESTIGATION LIMITS
|
||||
|
||||
For localized fixes:
|
||||
|
||||
- maximum 3 file reads before first edit
|
||||
- maximum 1 related-file read unless required
|
||||
- maximum 5 total file reads before implementation
|
||||
|
||||
Stop searching once the target service, controller, DTO, schema, or repository method is identified.
|
||||
|
||||
# TARGETED READ RULES
|
||||
|
||||
Do not read files larger than 300 lines unless required.
|
||||
|
||||
For known symbols:
|
||||
|
||||
1. rtk grep
|
||||
2. rtk smart
|
||||
3. read only the relevant section
|
||||
|
||||
Avoid opening entire services, modules, or controllers for localized changes.
|
||||
|
||||
Prefer symbol-level inspection.
|
||||
|
||||
# REVIEW MODE
|
||||
|
||||
During reviews:
|
||||
|
||||
- inspect changed files only
|
||||
- avoid repository-wide searches
|
||||
- avoid architecture exploration
|
||||
- avoid reading unrelated modules
|
||||
|
||||
Review only code affected by the diff.
|
||||
|
||||
# HARD TOKEN LIMITS
|
||||
|
||||
For localized fixes:
|
||||
|
||||
- Never read more than 5 files before the first edit.
|
||||
- Never read a file larger than 300 lines unless the target symbol cannot be isolated.
|
||||
- Never open an entire service, controller, or module when a symbol-level read is possible.
|
||||
- Never reread a file already summarized by `rtk smart` unless implementation details are required.
|
||||
|
||||
When a file exceeds 300 lines:
|
||||
|
||||
1. rtk grep
|
||||
2. rtk smart
|
||||
3. read only the required section
|
||||
|
||||
Avoid full-file reads.
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- A unique constraint covering the columns `[business_activity_id,postal_code,national_id]` on the table `customer_individuals` will be added. If there are existing duplicate values, this will fail.
|
||||
- A unique constraint covering the columns `[business_activity_id,postal_code,registration_number]` on the table `customer_legal` will be added. If there are existing duplicate values, this will fail.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE `customer_individuals` MODIFY `first_name` VARCHAR(255) NULL,
|
||||
MODIFY `last_name` VARCHAR(255) NULL,
|
||||
MODIFY `national_id` CHAR(10) NULL,
|
||||
MODIFY `mobile_number` CHAR(15) NULL,
|
||||
MODIFY `postal_code` CHAR(10) NULL,
|
||||
MODIFY `economic_code` CHAR(14) NULL;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE `customer_legal` MODIFY `name` VARCHAR(255) NULL,
|
||||
MODIFY `economic_code` CHAR(11) NULL,
|
||||
MODIFY `postal_code` CHAR(10) NULL;
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX `customer_individuals_business_activity_id_postal_code_nation_key` ON `customer_individuals`(`business_activity_id`, `postal_code`, `national_id`);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX `customer_legal_business_activity_id_postal_code_registration_key` ON `customer_legal`(`business_activity_id`, `postal_code`, `registration_number`);
|
||||
@@ -0,0 +1,50 @@
|
||||
-- ALTER TABLE
|
||||
ALTER TABLE `sales_invoices`
|
||||
ADD COLUMN `last_attempt_no` INT NULL,
|
||||
ADD COLUMN `last_tsp_status` ENUM(
|
||||
'NOT_SEND',
|
||||
'QUEUED',
|
||||
'FISCAL_QUEUED',
|
||||
'SEND_FAILURE',
|
||||
'SUCCESS',
|
||||
'FAILURE'
|
||||
) NULL;
|
||||
|
||||
-- INDEX
|
||||
CREATE INDEX `sales_invoices_pos_id_invoice_date_idx`
|
||||
ON `sales_invoices` (`pos_id`, `invoice_date`);
|
||||
|
||||
-- BACKFILL LAST ATTEMPT
|
||||
UPDATE sales_invoices si
|
||||
JOIN (
|
||||
SELECT invoice_id, attempt_no, status
|
||||
FROM (
|
||||
SELECT
|
||||
invoice_id,
|
||||
attempt_no,
|
||||
status,
|
||||
ROW_NUMBER() OVER (
|
||||
PARTITION BY invoice_id
|
||||
ORDER BY created_at DESC
|
||||
) rn
|
||||
FROM sale_invoice_tsp_attempts
|
||||
) t
|
||||
WHERE rn = 1
|
||||
) la ON la.invoice_id = si.id
|
||||
SET
|
||||
si.last_attempt_no = la.attempt_no,
|
||||
si.last_tsp_status = la.status;
|
||||
|
||||
-- SET NOT_SEND FOR NO ATTEMPTS
|
||||
UPDATE sales_invoices si
|
||||
LEFT JOIN sale_invoice_tsp_attempts att
|
||||
ON att.invoice_id = si.id
|
||||
SET
|
||||
si.last_attempt_no = NULL,
|
||||
si.last_tsp_status = 'NOT_SEND'
|
||||
WHERE att.invoice_id IS NULL;
|
||||
|
||||
-- SAFETY FILL
|
||||
UPDATE sales_invoices
|
||||
SET last_tsp_status = 'NOT_SEND'
|
||||
WHERE last_tsp_status IS NULL;
|
||||
@@ -13,33 +13,35 @@ model Customer {
|
||||
}
|
||||
|
||||
model CustomerIndividual {
|
||||
first_name String @db.VarChar(255)
|
||||
last_name String @db.VarChar(255)
|
||||
national_id String @db.Char(10)
|
||||
mobile_number String @db.Char(15)
|
||||
postal_code String @db.Char(10)
|
||||
economic_code String? @db.Char(10)
|
||||
first_name String? @db.VarChar(255)
|
||||
last_name String? @db.VarChar(255)
|
||||
national_id String? @db.Char(10)
|
||||
mobile_number String? @db.Char(15)
|
||||
postal_code String? @db.Char(10)
|
||||
economic_code String? @db.Char(14)
|
||||
customer_id String @id
|
||||
business_activity_id String
|
||||
business_activity BusinessActivity @relation(fields: [business_activity_id], references: [id])
|
||||
customer Customer @relation(fields: [customer_id], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([business_activity_id, national_id])
|
||||
@@unique([business_activity_id, postal_code, national_id])
|
||||
@@index([business_activity_id])
|
||||
@@map("customer_individuals")
|
||||
}
|
||||
|
||||
model CustomerLegal {
|
||||
name String @db.VarChar(255)
|
||||
economic_code String @db.Char(10)
|
||||
name String? @db.VarChar(255)
|
||||
economic_code String? @db.Char(11)
|
||||
registration_number String? @db.Char(20)
|
||||
postal_code String @db.Char(10)
|
||||
postal_code String? @db.Char(10)
|
||||
customer_id String @id
|
||||
business_activity_id String
|
||||
business_activity BusinessActivity @relation(fields: [business_activity_id], references: [id])
|
||||
customer Customer @relation(fields: [customer_id], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([business_activity_id, economic_code])
|
||||
@@unique([business_activity_id, postal_code, registration_number])
|
||||
@@index([business_activity_id])
|
||||
@@map("customer_legal")
|
||||
}
|
||||
|
||||
@@ -1,63 +1,66 @@
|
||||
model SalesInvoice {
|
||||
id String @id @default(uuid())
|
||||
code String @unique @db.VarChar(100)
|
||||
total_amount Decimal @db.Decimal(15, 2)
|
||||
id String @id @default(uuid())
|
||||
code String @unique @db.VarChar(100)
|
||||
total_amount Decimal @db.Decimal(15, 2)
|
||||
invoice_number Int
|
||||
invoice_date DateTime @default(now()) @db.Timestamp(0)
|
||||
invoice_date DateTime @default(now()) @db.Timestamp(0)
|
||||
type TspProviderRequestType
|
||||
tax_id String? @unique @db.VarChar(32)
|
||||
notes String? @db.Text
|
||||
tax_id String? @unique @db.VarChar(32)
|
||||
notes String? @db.Text
|
||||
unknown_customer Json?
|
||||
created_at DateTime @default(now()) @db.Timestamp(0)
|
||||
updated_at DateTime @updatedAt @db.Timestamp(0)
|
||||
main_id String? @db.VarChar(50)
|
||||
ref_id String? @unique @db.VarChar(50)
|
||||
created_at DateTime @default(now()) @db.Timestamp(0)
|
||||
updated_at DateTime @updatedAt @db.Timestamp(0)
|
||||
main_id String? @db.VarChar(50)
|
||||
ref_id String? @unique @db.VarChar(50)
|
||||
customer_id String?
|
||||
consumer_account_id String
|
||||
pos_id String
|
||||
settlement_type InvoiceSettlementType
|
||||
discount_amount Decimal? @db.Decimal(15, 2)
|
||||
tax_amount Decimal? @db.Decimal(15, 2)
|
||||
discount_amount Decimal? @db.Decimal(15, 2)
|
||||
tax_amount Decimal? @db.Decimal(15, 2)
|
||||
last_tsp_status TspProviderResponseStatus?
|
||||
last_attempt_no Int?
|
||||
tsp_attempts SaleInvoiceTspAttempts[]
|
||||
items SalesInvoiceItem[]
|
||||
payments SalesInvoicePayment[]
|
||||
consumer_account ConsumerAccount @relation(fields: [consumer_account_id], references: [id])
|
||||
customer Customer? @relation(fields: [customer_id], references: [id])
|
||||
pos Pos @relation(fields: [pos_id], references: [id])
|
||||
reference_invoice SalesInvoice? @relation("SalesInvoiceReference", fields: [ref_id], references: [id])
|
||||
referenced_by SalesInvoice? @relation("SalesInvoiceReference")
|
||||
consumer_account ConsumerAccount @relation(fields: [consumer_account_id], references: [id])
|
||||
customer Customer? @relation(fields: [customer_id], references: [id])
|
||||
pos Pos @relation(fields: [pos_id], references: [id])
|
||||
reference_invoice SalesInvoice? @relation("SalesInvoiceReference", fields: [ref_id], references: [id])
|
||||
referenced_by SalesInvoice? @relation("SalesInvoiceReference")
|
||||
|
||||
@@unique([invoice_number, pos_id])
|
||||
@@index([pos_id, invoice_date])
|
||||
@@index([ref_id])
|
||||
@@index([tax_id])
|
||||
@@index([consumer_account_id], map: "sales_invoices_consumer_account_id_fkey")
|
||||
@@index([customer_id], map: "sales_invoices_customer_id_fkey")
|
||||
@@index([pos_id], map: "sales_invoices_pos_id_fkey")
|
||||
@@map("sales_invoices")
|
||||
}
|
||||
|
||||
model SalesInvoiceItem {
|
||||
id String @id @default(ulid())
|
||||
quantity Decimal @db.Decimal(10, 0)
|
||||
measure_unit_text String @db.VarChar(50)
|
||||
measure_unit_code String @db.VarChar(50)
|
||||
sku_code String @db.VarChar(50)
|
||||
sku_vat Decimal @default(0.00) @db.Decimal(15, 2)
|
||||
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)
|
||||
discount Decimal @default(0.00) @db.Decimal(15, 2)
|
||||
notes String? @db.Text
|
||||
id String @id @default(ulid())
|
||||
quantity Decimal @db.Decimal(10, 0)
|
||||
measure_unit_text String @db.VarChar(50)
|
||||
measure_unit_code String @db.VarChar(50)
|
||||
sku_code String @db.VarChar(50)
|
||||
sku_vat Decimal @default(0.00) @db.Decimal(15, 2)
|
||||
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)
|
||||
discount Decimal @default(0.00) @db.Decimal(15, 2)
|
||||
notes String? @db.Text
|
||||
payload Json?
|
||||
good_snapshot Json
|
||||
invoice_id String
|
||||
good_id String
|
||||
service_id String?
|
||||
discount_amount Decimal? @db.Decimal(15, 2)
|
||||
tax_amount Decimal? @db.Decimal(15, 2)
|
||||
good Good @relation(fields: [good_id], references: [id])
|
||||
invoice SalesInvoice @relation(fields: [invoice_id], references: [id])
|
||||
service Service? @relation(fields: [service_id], references: [id])
|
||||
discount_amount Decimal? @db.Decimal(15, 2)
|
||||
tax_amount Decimal? @db.Decimal(15, 2)
|
||||
|
||||
good Good @relation(fields: [good_id], references: [id])
|
||||
invoice SalesInvoice @relation(fields: [invoice_id], references: [id])
|
||||
service Service? @relation(fields: [service_id], references: [id])
|
||||
|
||||
@@index([invoice_id, good_id])
|
||||
@@index([good_id], map: "sales_invoice_items_good_id_fkey")
|
||||
|
||||
+4
-3
@@ -1,7 +1,10 @@
|
||||
import { PasswordUtil } from '@/common/utils/password.util'
|
||||
import { GoodPricingModel } from '@/generated/prisma/enums'
|
||||
import { GoodCreateManyInput } from '@/generated/prisma/models'
|
||||
import { prisma } from '../src/lib/prisma'
|
||||
import { PrismaClient } from '../src/generated/prisma/client'
|
||||
import { prismaAdapter } from '../src/lib/prisma'
|
||||
|
||||
const prisma = new PrismaClient({ adapter: prismaAdapter })
|
||||
|
||||
async function main() {
|
||||
const password = await PasswordUtil.hash('123456')
|
||||
@@ -198,8 +201,6 @@ async function main() {
|
||||
code: sku_code,
|
||||
},
|
||||
})
|
||||
console.log(name)
|
||||
console.log(sku?.id)
|
||||
|
||||
if (sku) {
|
||||
return {
|
||||
|
||||
@@ -1,548 +0,0 @@
|
||||
-- AUTO-GENERATED MYSQL TRIGGER DUMP
|
||||
-- Generated at: 2026-01-06T16:09:38.959Z
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 1
|
||||
-- Trigger: trg_bank_account_transaction_after_delete
|
||||
-- Event: DELETE
|
||||
-- Table: Bank_Account_Transactions
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_bank_account_transaction_after_delete`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_bank_account_transaction_after_delete` AFTER DELETE ON `Bank_Account_Transactions` FOR EACH ROW BEGIN
|
||||
UPDATE `Bank_Account_Balance` SET balance = balance - OLD.amount WHERE `bankAccountId` = OLD.bankAccountId;
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 2
|
||||
-- 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;
|
||||
DECLARE _avgCost DECIMAL(10,2);
|
||||
DECLARE latestQuantityInOrigin DECIMAL(10,2);
|
||||
DECLARE latestQuantityInDestination DECIMAL(10,2);
|
||||
|
||||
SELECT fromInventoryId, toInventoryId INTO fromInv, toInv
|
||||
FROM Inventory_Transfers WHERE id = NEW.transferId;
|
||||
|
||||
SELECT COALESCE(avgCost, 0), COALESCE(quantity, 0) INTO _avgCost, latestQuantityInOrigin FROM Stock_Balance
|
||||
WHERE ProductId = NEW.productId AND inventoryId = fromInv LIMIT 1;
|
||||
|
||||
SELECT COALESCE(quantity, 0) INTO latestQuantityInDestination FROM Stock_Balance
|
||||
WHERE ProductId = NEW.productId AND inventoryId = toInv LIMIT 1;
|
||||
|
||||
|
||||
-- OUT from source
|
||||
INSERT INTO Stock_Movements
|
||||
(type, quantity, unitPrice, totalCost, avgCost, referenceType, referenceId, productId, inventoryId, counterInventoryId, createdAt, remainedInStock)
|
||||
VALUES
|
||||
('OUT', NEW.count, _avgCost, _avgCost*NEW.count, _avgCost, 'INVENTORY_TRANSFER', NEW.transferId, NEW.productId, fromInv, toInv, NOW(), latestQuantityInOrigin-NEW.count);
|
||||
|
||||
-- IN to destination
|
||||
INSERT INTO Stock_Movements
|
||||
(type, quantity, unitPrice, totalCost, avgCost, referenceType, referenceId, productId, inventoryId, counterInventoryId, createdAt, remainedInStock)
|
||||
VALUES
|
||||
('IN', NEW.count,_avgCost, _avgCost*NEW.count,_avgCost, 'INVENTORY_TRANSFER', NEW.transferId, NEW.productId, toInv, fromInv, NOW(), latestQuantityInOrigin-NEW.count);
|
||||
end;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 3
|
||||
-- Trigger: trg_order_item_after_update
|
||||
-- Event: UPDATE
|
||||
-- Table: Order_Items
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_order_item_after_update`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_order_item_after_update` AFTER UPDATE ON `Order_Items` FOR EACH ROW BEGIN
|
||||
|
||||
UPDATE Stock_Reservations
|
||||
SET quantity = quantity - OLD.quantity + NEW.quantity
|
||||
WHERE orderId = NEW.orderId AND productId = NEW.productId;
|
||||
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 4
|
||||
-- Trigger: trg_order_item_after_delete
|
||||
-- Event: DELETE
|
||||
-- Table: Order_Items
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_order_item_after_delete`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_order_item_after_delete` AFTER DELETE ON `Order_Items` FOR EACH ROW BEGIN
|
||||
|
||||
DELETE From Stock_Reservations
|
||||
WHERE orderId = OLD.orderId AND productId = OLD.productId;
|
||||
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 5
|
||||
-- Trigger: trg_order_after_cancel
|
||||
-- Event: UPDATE
|
||||
-- Table: Orders
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_order_after_cancel`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_order_after_cancel` AFTER UPDATE ON `Orders` FOR EACH ROW BEGIN
|
||||
IF NEW.status = 'CANCELED' OR NEW.status = 'REJECTED' OR NEW.status = 'DONE' THEN
|
||||
UPDATE Stock_Reservations sr SET quantity = 0
|
||||
WHERE sr.orderId = NEW.id;
|
||||
END IF;
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 6
|
||||
-- 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 DECLARE latestQuantity DECIMAL(10, 2) DEFAULT 0;
|
||||
|
||||
DECLARE invId INT;
|
||||
DECLARE suppId INT;
|
||||
|
||||
-- Get inventory & supplier from
|
||||
SELECT inventoryId, supplierId
|
||||
INTO invId, suppId
|
||||
FROM Purchase_Receipts
|
||||
WHERE id = NEW.receiptId;
|
||||
|
||||
-- Get current stock quantity (if exists)
|
||||
SELECT COALESCE(quantity, 0)
|
||||
INTO latestQuantity
|
||||
FROM Stock_Balance sb
|
||||
WHERE sb.inventoryId = invId
|
||||
AND sb.productId = NEW.productId
|
||||
LIMIT 1;
|
||||
|
||||
-- Insert stock movement
|
||||
INSERT INTO Stock_Movements (
|
||||
type,
|
||||
quantity,
|
||||
unitPrice,
|
||||
totalCost,
|
||||
referenceType,
|
||||
referenceId,
|
||||
productId,
|
||||
inventoryId,
|
||||
avgCost,
|
||||
supplierId,
|
||||
remainedInStock,
|
||||
createdAt
|
||||
)
|
||||
VALUES (
|
||||
'IN',
|
||||
NEW.count,
|
||||
NEW.unitPrice,
|
||||
NEW.totalAmount,
|
||||
'PURCHASE',
|
||||
NEW.receiptId,
|
||||
NEW.productId,
|
||||
invId,
|
||||
CASE
|
||||
WHEN NEW.count = 0 THEN 0
|
||||
ELSE NEW.totalAmount / NEW.count
|
||||
END
|
||||
|
||||
,
|
||||
suppId,
|
||||
latestQuantity + NEW.count,
|
||||
NOW()
|
||||
);
|
||||
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 7
|
||||
-- Trigger: trg_pr_payment_after_delete
|
||||
-- Event: DELETE
|
||||
-- Table: Purchase_Receipt_Payments
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_pr_payment_after_delete`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_pr_payment_after_delete` AFTER DELETE ON `Purchase_Receipt_Payments` FOR EACH ROW BEGIN
|
||||
DECLARE receiptTotal DECIMAL(14,2);
|
||||
DECLARE newPaid DECIMAL(14,2);
|
||||
|
||||
SELECT totalAmount, paidAmount
|
||||
INTO receiptTotal, newPaid
|
||||
FROM Purchase_Receipts
|
||||
WHERE id = OLD.receiptId
|
||||
FOR UPDATE;
|
||||
|
||||
IF OLD.type = 'PAYMENT' THEN
|
||||
SET newPaid = newPaid - OLD.amount;
|
||||
ELSE
|
||||
SET newPaid = newPaid + OLD.amount;
|
||||
END IF;
|
||||
|
||||
UPDATE Purchase_Receipts
|
||||
SET
|
||||
paidAmount = newPaid,
|
||||
status =
|
||||
CASE
|
||||
WHEN newPaid = 0 THEN 'UNPAID'
|
||||
WHEN newPaid < receiptTotal THEN 'PARTIALLY_PAID'
|
||||
ELSE 'PAID'
|
||||
END
|
||||
WHERE id = OLD.receiptId;
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 8
|
||||
-- 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);
|
||||
DECLARE inventory_id INT;
|
||||
|
||||
|
||||
|
||||
SELECT pa.inventoryId INTO inventory_id
|
||||
FROM Pos_Accounts pa
|
||||
INNER JOIN Sales_Invoices si ON pa.id = si.posAccountId
|
||||
WHERE si.id = NEW.invoiceId;
|
||||
|
||||
|
||||
SELECT COALESCE(sav.availableQuantity, 0) INTO current_stock
|
||||
FROM Stock_Available_View sav
|
||||
WHERE productId = NEW.productId AND sav.inventoryId = inventory_id;
|
||||
|
||||
|
||||
|
||||
IF NEW.count > current_stock THEN
|
||||
SIGNAL SQLSTATE '45000'
|
||||
SET MESSAGE_TEXT = 'موجودی کالا در انبار کافی نیست.';
|
||||
END IF;
|
||||
end;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 9
|
||||
-- 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 DECLARE current_stock DECIMAL(10, 2);
|
||||
|
||||
DECLARE inventory_id INT;
|
||||
DECLARE customer_id INT;
|
||||
DECLARE pos_id INT;
|
||||
|
||||
|
||||
|
||||
SELECT posAccountId, customerId INTO pos_id, customer_id
|
||||
FROM Sales_Invoices si
|
||||
WHERE si.id = NEW.invoiceId
|
||||
LIMIT 1;
|
||||
INSERT INTO Trigger_Logs (name , message) VALUES ('pos_id', pos_id);
|
||||
INSERT INTO Trigger_Logs (name , message) VALUES ('customer_id', customer_id);
|
||||
|
||||
|
||||
SELECT pa.inventoryId INTO inventory_id
|
||||
FROM Pos_Accounts pa
|
||||
INNER JOIN Sales_Invoices si ON pa.id = si.posAccountId
|
||||
WHERE si.id = NEW.invoiceId;
|
||||
|
||||
|
||||
|
||||
SELECT COALESCE(quantity, 0) INTO current_stock
|
||||
FROM Stock_Balance sb
|
||||
WHERE productId = NEW.productId AND sb.inventoryId = inventory_id
|
||||
LIMIT 1;
|
||||
|
||||
|
||||
|
||||
INSERT INTO Stock_Movements (
|
||||
type,
|
||||
quantity,
|
||||
unitPrice,
|
||||
totalCost,
|
||||
referenceType,
|
||||
referenceId,
|
||||
productId,
|
||||
inventoryId,
|
||||
avgCost,
|
||||
remainedInStock,
|
||||
customerId,
|
||||
createdAt
|
||||
)
|
||||
VALUES (
|
||||
'OUT',
|
||||
NEW.count,
|
||||
NEW.unitPrice,
|
||||
NEW.totalAmount,
|
||||
'SALES',
|
||||
NEW.invoiceId,
|
||||
NEW.productId,
|
||||
inventory_id,
|
||||
|
||||
CASE
|
||||
WHEN NEW.count = 0 THEN 0
|
||||
ELSE NEW.totalAmount / NEW.count
|
||||
END,
|
||||
current_stock - NEW.count,
|
||||
customer_id,
|
||||
NOW()
|
||||
);
|
||||
|
||||
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 10
|
||||
-- Trigger: trg_pos_account_payment_after_insert
|
||||
-- Event: INSERT
|
||||
-- Table: Sales_Invoice_Payments
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_pos_account_payment_after_insert`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_pos_account_payment_after_insert` AFTER INSERT ON `Sales_Invoice_Payments` FOR EACH ROW BEGIN
|
||||
|
||||
DECLARE _bankAccountId INT;
|
||||
|
||||
IF(NEW.paymentMethod != 'CASH') THEN
|
||||
SELECT cashBankAccountId INTO _bankAccountId
|
||||
FROM Pos_Accounts pa
|
||||
INNER JOIN Sales_Invoices si ON pa.id = si.posAccountId
|
||||
WHERE si.id = NEW.invoiceId;
|
||||
End IF;
|
||||
|
||||
INSERT INTO Bank_Account_Transactions (
|
||||
bankAccountId,
|
||||
type,
|
||||
amount,
|
||||
balanceAfter,
|
||||
referenceType,
|
||||
referenceId
|
||||
)
|
||||
VALUES(
|
||||
_bankAccountId,
|
||||
'DEPOSIT',
|
||||
NEW.amount,
|
||||
0,
|
||||
'POS_SALE',
|
||||
NEW.id
|
||||
);
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 11
|
||||
-- Trigger: trg_sales_invoice_payment_after_insert
|
||||
-- Event: INSERT
|
||||
-- Table: Sales_Invoice_Payments
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_sales_invoice_payment_after_insert`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_sales_invoice_payment_after_insert` AFTER INSERT ON `Sales_Invoice_Payments` FOR EACH ROW BEGIN
|
||||
DECLARE currentBalance DECIMAL(15,2);
|
||||
DECLARE bankAccountId INT;
|
||||
|
||||
SELECT pa.bankAccountId INTO bankAccountId
|
||||
FROM Pos_Accounts pa
|
||||
INNER JOIN Sales_Invoices si ON pa.id = si.posAccountId
|
||||
WHERE si.id = NEW.invoiceId;
|
||||
|
||||
SELECT balance INTO currentBalance
|
||||
FROM Bank_Account_Balance
|
||||
WHERE bankAccountId = bankAccountId
|
||||
FOR UPDATE;
|
||||
|
||||
IF currentBalance IS NULL THEN
|
||||
SET currentBalance = 0;
|
||||
INSERT INTO Bank_Account_Balance (bankAccountId, balance)
|
||||
VALUES (bankAccountId, 0);
|
||||
END IF;
|
||||
|
||||
SET currentBalance = currentBalance + NEW.amount;
|
||||
|
||||
INSERT INTO Bank_Account_Transactions
|
||||
(bankAccountId, type, amount, balanceAfter, referenceType, referenceId)
|
||||
VALUES
|
||||
(bankAccountId, 'DEPOSIT', NEW.amount, currentBalance, 'POS_SALE', NEW.id);
|
||||
|
||||
UPDATE Bank_Account_Balance
|
||||
SET balance = currentBalance
|
||||
WHERE bankAccountId = bankAccountId;
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 12
|
||||
-- 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
|
||||
|
||||
INSERT INTO
|
||||
Stock_Balance (
|
||||
productId,
|
||||
quantity,
|
||||
avgCost,
|
||||
totalCost,
|
||||
inventoryId,
|
||||
updatedAt
|
||||
)
|
||||
VALUES (
|
||||
NEW.productId,
|
||||
NEW.quantity,
|
||||
NEW.unitPrice,
|
||||
NEW.totalCost,
|
||||
NEW.inventoryId,
|
||||
NOW()
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
quantity = quantity - NEW.quantity,
|
||||
totalCost = totalCost - NEW.totalCost,
|
||||
avgCost = totalCost / quantity;
|
||||
|
||||
END IF;
|
||||
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 13
|
||||
-- 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,
|
||||
inventoryId,
|
||||
updatedAt
|
||||
)
|
||||
VALUES (
|
||||
NEW.productId,
|
||||
NEW.quantity,
|
||||
NEW.unitPrice,
|
||||
NEW.totalCost,
|
||||
NEW.inventoryId,
|
||||
NOW()
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
quantity = quantity + NEW.quantity,
|
||||
totalCost = totalCost + NEW.totalCost,
|
||||
avgCost = totalCost / quantity;
|
||||
|
||||
END IF;
|
||||
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 14
|
||||
-- Trigger: trg_stock_transfer
|
||||
-- Event: INSERT
|
||||
-- Table: Stock_Movements
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_stock_transfer`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_stock_transfer` AFTER INSERT ON `Stock_Movements` FOR EACH ROW BEGIN IF NEW.referenceType = 'INVENTORY_TRANSFER' THEN IF NEW.type = 'IN' THEN
|
||||
INSERT INTO
|
||||
Stock_Balance (
|
||||
productId,
|
||||
inventoryId,
|
||||
quantity,
|
||||
totalCost,
|
||||
avgCost,
|
||||
updatedAt
|
||||
)
|
||||
VALUES (
|
||||
NEW.productId,
|
||||
NEW.inventoryId,
|
||||
NEW.quantity,
|
||||
NEW.totalCost,
|
||||
CASE
|
||||
WHEN NEW.quantity = 0 THEN 0
|
||||
ELSE NEW.totalCost / NEW.quantity
|
||||
END,
|
||||
NOW()
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
quantity = quantity + NEW.quantity,
|
||||
totalCost = totalCost + NEW.totalCost,
|
||||
avgCost = CASE
|
||||
WHEN (quantity + NEW.quantity) = 0 THEN 0
|
||||
ELSE (totalCost + NEW.totalCost) / (quantity + NEW.quantity)
|
||||
END,
|
||||
updatedAt = NOW();
|
||||
|
||||
END IF;
|
||||
|
||||
IF NEW.type = 'OUT' THEN IF EXISTS (
|
||||
SELECT 1
|
||||
FROM Stock_Balance sb
|
||||
WHERE
|
||||
sb.productId = NEW.productId
|
||||
AND sb.inventoryId = NEW.inventoryId
|
||||
) THEN
|
||||
|
||||
UPDATE Stock_Balance sb
|
||||
SET
|
||||
sb.quantity = sb.quantity - NEW.quantity,
|
||||
sb.totalCost = sb.totalCost - (sb.avgCost * NEW.quantity),
|
||||
sb.updatedAt = NOW()
|
||||
WHERE
|
||||
sb.productId = NEW.productId
|
||||
AND sb.inventoryId = NEW.inventoryId;
|
||||
|
||||
ELSE
|
||||
INSERT INTO
|
||||
Stock_Balance (
|
||||
productId,
|
||||
inventoryId,
|
||||
quantity,
|
||||
totalCost,
|
||||
avgCost,
|
||||
updatedAt
|
||||
)
|
||||
VALUES (
|
||||
NEW.productId,
|
||||
NEW.inventoryId,
|
||||
- NEW.quantity,
|
||||
- COALESCE(NEW.unitPrice, 0) * NEW.quantity,
|
||||
COALESCE(NEW.unitPrice, 0),
|
||||
NOW()
|
||||
);
|
||||
|
||||
END IF;
|
||||
|
||||
END IF;
|
||||
|
||||
END IF;
|
||||
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 15
|
||||
-- Trigger: trg_no_negative_available_stock
|
||||
-- Event: INSERT
|
||||
-- Table: Stock_Reservations
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_no_negative_available_stock`;
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_no_negative_available_stock` BEFORE INSERT ON `Stock_Reservations` FOR EACH ROW BEGIN
|
||||
DECLARE available DECIMAL(14,3);
|
||||
|
||||
SELECT availableQuantity
|
||||
INTO available
|
||||
FROM Stock_Available_View
|
||||
WHERE productId = NEW.productId
|
||||
AND inventoryId = NEW.inventoryId;
|
||||
|
||||
IF available < NEW.quantity THEN
|
||||
SIGNAL SQLSTATE '45000'
|
||||
SET MESSAGE_TEXT = 'موجودی کافی نیست';
|
||||
END IF;
|
||||
END;
|
||||
|
||||
@@ -1,825 +0,0 @@
|
||||
-- AUTO-GENERATED MYSQL TRIGGER DUMP
|
||||
-- Generated at: 2026-01-04T09:46:30.365Z
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 1
|
||||
-- Trigger: trg_bank_account_transaction_after_insert
|
||||
-- Event: INSERT
|
||||
-- Table: Bank_Account_Transactions
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_bank_account_transaction_after_insert`;
|
||||
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_bank_account_transaction_after_insert` AFTER INSERT ON `Bank_Account_Transactions` FOR EACH ROW BEGIN
|
||||
IF NEW.type = 'DEPOSIT' THEN
|
||||
UPDATE Bank_Account_Balance SET balance = balance + NEW.amount WHERE bankAccountId = NEW.bankAccountId;
|
||||
ELSEIF NEW.type = 'WITHDRAWAL' THEN
|
||||
UPDATE Bank_Account_Balance SET balance = balance - NEW.amount WHERE bankAccountId = NEW.bankAccountId;
|
||||
END IF;
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 2
|
||||
-- Trigger: trg_bank_account_transaction_after_delete
|
||||
-- Event: DELETE
|
||||
-- Table: Bank_Account_Transactions
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_bank_account_transaction_after_delete`;
|
||||
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_bank_account_transaction_after_delete` AFTER DELETE ON `Bank_Account_Transactions` FOR EACH ROW BEGIN
|
||||
UPDATE Bank_Accounts SET balance = balance - OLD.amount;
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 3
|
||||
-- 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;
|
||||
DECLARE _avgCost DECIMAL(10,2);
|
||||
DECLARE latestQuantityInOrigin DECIMAL(10,2);
|
||||
DECLARE latestQuantityInDestination DECIMAL(10,2);
|
||||
|
||||
SELECT fromInventoryId, toInventoryId INTO fromInv, toInv
|
||||
FROM Inventory_Transfers WHERE id = NEW.transferId;
|
||||
|
||||
SELECT COALESCE(avgCost, 0), COALESCE(quantity, 0) INTO _avgCost, latestQuantityInOrigin FROM Stock_Balance
|
||||
WHERE ProductId = NEW.productId AND inventoryId = fromInv LIMIT 1;
|
||||
|
||||
SELECT COALESCE(quantity, 0) INTO latestQuantityInDestination FROM Stock_Balance
|
||||
WHERE ProductId = NEW.productId AND inventoryId = toInv LIMIT 1;
|
||||
|
||||
|
||||
-- OUT from source
|
||||
INSERT INTO Stock_Movements
|
||||
(type, quantity, unitPrice, totalCost, avgCost, referenceType, referenceId, productId, inventoryId, counterInventoryId, createdAt, remainedInStock)
|
||||
VALUES
|
||||
('OUT', NEW.count, _avgCost, _avgCost*NEW.count, _avgCost, 'INVENTORY_TRANSFER', NEW.transferId, NEW.productId, fromInv, toInv, NOW(), latestQuantityInOrigin-NEW.count);
|
||||
|
||||
-- IN to destination
|
||||
INSERT INTO Stock_Movements
|
||||
(type, quantity, unitPrice, totalCost, avgCost, referenceType, referenceId, productId, inventoryId, counterInventoryId, createdAt, remainedInStock)
|
||||
VALUES
|
||||
('IN', NEW.count,_avgCost, _avgCost*NEW.count,_avgCost, 'INVENTORY_TRANSFER', NEW.transferId, NEW.productId, toInv, fromInv, NOW(), latestQuantityInOrigin-NEW.count);
|
||||
end;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 4
|
||||
-- Trigger: trg_order_item_after_insert
|
||||
-- Event: INSERT
|
||||
-- Table: Order_Items
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_order_item_after_insert`;
|
||||
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_order_item_after_insert` AFTER INSERT ON `Order_Items` FOR EACH ROW BEGIN
|
||||
UPDATE Stock_Reservations SET quantity = quantity + NEW.quantity
|
||||
WHERE orderId = NEW.orderId AND productId = NEW.productId;
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 5
|
||||
-- Trigger: trg_order_item_after_update
|
||||
-- Event: UPDATE
|
||||
-- Table: Order_Items
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_order_item_after_update`;
|
||||
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_order_item_after_update` AFTER UPDATE ON `Order_Items` FOR EACH ROW BEGIN
|
||||
UPDATE Stock_Reservations
|
||||
SET quantity = quantity - OLD.quantity + NEW.quantity
|
||||
WHERE orderId = NEW.orderId AND productId = NEW.productId;
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 6
|
||||
-- Trigger: trg_order_item_after_delete
|
||||
-- Event: DELETE
|
||||
-- Table: Order_Items
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_order_item_after_delete`;
|
||||
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_order_item_after_delete` AFTER DELETE ON `Order_Items` FOR EACH ROW BEGIN
|
||||
UPDATE Stock_Reservations SET quantity = quantity - OLD.quantity
|
||||
WHERE orderId = OLD.orderId AND productId = OLD.productId;
|
||||
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 7
|
||||
-- Trigger: trg_order_after_cancel
|
||||
-- Event: UPDATE
|
||||
-- Table: Orders
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_order_after_cancel`;
|
||||
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_order_after_cancel` AFTER UPDATE ON `Orders` FOR EACH ROW BEGIN
|
||||
IF NEW.status = 'CANCELED' OR NEW.status = 'REJECTED' OR NEW.status = 'DONE' THEN
|
||||
UPDATE Stock_Reservations sr SET quantity = 0
|
||||
WHERE sr.orderId = NEW.id;
|
||||
END IF;
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 8
|
||||
-- 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 DECLARE latestQuantity DECIMAL(10, 2) DEFAULT 0;
|
||||
|
||||
DECLARE invId INT;
|
||||
DECLARE suppId INT;
|
||||
|
||||
-- Get inventory & supplier from
|
||||
SELECT inventoryId, supplierId
|
||||
INTO invId, suppId
|
||||
FROM Purchase_Receipts
|
||||
WHERE id = NEW.receiptId;
|
||||
|
||||
-- Get current stock quantity (if exists)
|
||||
SELECT COALESCE(quantity, 0)
|
||||
INTO latestQuantity
|
||||
FROM Stock_Balance sb
|
||||
WHERE sb.inventoryId = invId
|
||||
AND sb.productId = NEW.productId
|
||||
LIMIT 1;
|
||||
|
||||
-- Insert stock movement
|
||||
INSERT INTO Stock_Movements (
|
||||
type,
|
||||
quantity,
|
||||
unitPrice,
|
||||
totalCost,
|
||||
referenceType,
|
||||
referenceId,
|
||||
productId,
|
||||
inventoryId,
|
||||
avgCost,
|
||||
supplierId,
|
||||
remainedInStock,
|
||||
createdAt
|
||||
)
|
||||
VALUES (
|
||||
'IN',
|
||||
NEW.count,
|
||||
NEW.unitPrice,
|
||||
NEW.totalAmount,
|
||||
'PURCHASE',
|
||||
NEW.receiptId,
|
||||
NEW.productId,
|
||||
invId,
|
||||
CASE
|
||||
WHEN NEW.count = 0 THEN 0
|
||||
ELSE NEW.totalAmount / NEW.count
|
||||
END
|
||||
|
||||
,
|
||||
suppId,
|
||||
latestQuantity + NEW.count,
|
||||
NOW()
|
||||
);
|
||||
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 9
|
||||
-- Trigger: trg_pr_payment_before_insert
|
||||
-- Event: INSERT
|
||||
-- Table: Purchase_Receipt_Payments
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_pr_payment_before_insert`;
|
||||
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_pr_payment_before_insert` BEFORE INSERT ON `Purchase_Receipt_Payments` FOR EACH ROW BEGIN
|
||||
|
||||
|
||||
DECLARE receiptTotal DECIMAL(14,2);
|
||||
DECLARE paid DECIMAL(14,2);
|
||||
|
||||
|
||||
SELECT totalAmount, paidAmount
|
||||
INTO receiptTotal, paid
|
||||
FROM Purchase_Receipts
|
||||
WHERE id = NEW.receiptId
|
||||
FOR UPDATE;
|
||||
|
||||
IF NEW.type = 'PAYMENT' AND paid + NEW.amount > receiptTotal THEN
|
||||
SIGNAL SQLSTATE '45000'
|
||||
SET MESSAGE_TEXT = 'مجموع مبلغ پرداختی بیشتر از مبلغ فاکتور است.';
|
||||
END IF;
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 10
|
||||
-- Trigger: trg_purchase_payment_update_receipt
|
||||
-- Event: INSERT
|
||||
-- Table: Purchase_Receipt_Payments
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_purchase_payment_update_receipt`;
|
||||
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_purchase_payment_update_receipt` AFTER INSERT ON `Purchase_Receipt_Payments` FOR EACH ROW BEGIN
|
||||
DECLARE paid DECIMAL(15,2);
|
||||
DECLARE total DECIMAL(15,2);
|
||||
|
||||
SELECT
|
||||
COALESCE(SUM(
|
||||
CASE WHEN type = 'PAYMENT' THEN amount ELSE -amount END
|
||||
),0)
|
||||
INTO paid
|
||||
FROM Purchase_Receipt_Payments
|
||||
WHERE receiptId = NEW.receiptId;
|
||||
|
||||
SELECT totalAmount INTO total
|
||||
FROM Purchase_Receipts
|
||||
WHERE id = NEW.receiptId;
|
||||
|
||||
UPDATE Purchase_Receipts
|
||||
SET
|
||||
paidAmount = paid,
|
||||
status = CASE
|
||||
WHEN paid = 0 THEN 'UNPAID'
|
||||
WHEN paid < total THEN 'PARTIALLY_PAID'
|
||||
ELSE 'PAID'
|
||||
END
|
||||
WHERE id = NEW.receiptId;
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 11
|
||||
-- Trigger: trg_purchase_payment_after_insert
|
||||
-- Event: INSERT
|
||||
-- Table: Purchase_Receipt_Payments
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_purchase_payment_after_insert`;
|
||||
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_purchase_payment_after_insert` AFTER INSERT ON `Purchase_Receipt_Payments` FOR EACH ROW BEGIN
|
||||
|
||||
DECLARE currentBalance DECIMAL(15, 2);
|
||||
|
||||
|
||||
SELECT balance INTO currentBalance
|
||||
FROM Bank_Account_Balance
|
||||
WHERE
|
||||
bankAccountId = NEW.bankAccountId FOR
|
||||
UPDATE;
|
||||
|
||||
|
||||
IF currentBalance IS NULL THEN SET currentBalance = 0;
|
||||
|
||||
|
||||
INSERT INTO
|
||||
Bank_Account_Balance (bankAccountId, balance, updatedAt)
|
||||
VALUES (NEW.bankAccountId, 0, NOW());
|
||||
|
||||
END IF;
|
||||
|
||||
IF NEW.type = 'PAYMENT' THEN
|
||||
SET
|
||||
currentBalance = currentBalance - NEW.amount;
|
||||
|
||||
INSERT INTO
|
||||
Bank_Account_Transactions (
|
||||
bankAccountId,
|
||||
type,
|
||||
amount,
|
||||
balanceAfter,
|
||||
referenceType,
|
||||
referenceId
|
||||
)
|
||||
VALUES (
|
||||
NEW.bankAccountId,
|
||||
'WITHDRAWAL',
|
||||
NEW.amount,
|
||||
currentBalance,
|
||||
'PURCHASE_PAYMENT',
|
||||
NEW.id
|
||||
);
|
||||
|
||||
ELSE SET currentBalance = currentBalance + NEW.amount;
|
||||
|
||||
INSERT INTO
|
||||
Bank_Account_Transactions (
|
||||
bankAccountId,
|
||||
type,
|
||||
amount,
|
||||
balanceAfter,
|
||||
referenceType,
|
||||
referenceId
|
||||
)
|
||||
VALUES (
|
||||
NEW.bankAccountId,
|
||||
'DEPOSIT',
|
||||
NEW.amount,
|
||||
currentBalance,
|
||||
'PURCHASE_REFUND',
|
||||
NEW.id
|
||||
);
|
||||
|
||||
END IF;
|
||||
|
||||
UPDATE Bank_Account_Balance
|
||||
SET
|
||||
balance = currentBalance
|
||||
WHERE
|
||||
bankAccountId = NEW.bankAccountId;
|
||||
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 12
|
||||
-- Trigger: trg_pr_payment_after_insert
|
||||
-- Event: INSERT
|
||||
-- Table: Purchase_Receipt_Payments
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_pr_payment_after_insert`;
|
||||
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_pr_payment_after_insert` AFTER INSERT ON `Purchase_Receipt_Payments` FOR EACH ROW BEGIN
|
||||
DECLARE receiptTotal DECIMAL(14,2) Default 0;
|
||||
DECLARE newPaid DECIMAL(14,2) Default 0;
|
||||
DECLARE _supplierId INT;
|
||||
DECLARE lastBalance DECIMAL(14,2) Default 0;
|
||||
|
||||
|
||||
-- Lock receipt row
|
||||
SELECT COALESCE(totalAmount, 0), COALESCE(paidAmount, 0), supplierId
|
||||
INTO receiptTotal, newPaid, _supplierId
|
||||
FROM Purchase_Receipts
|
||||
WHERE id = NEW.receiptId
|
||||
FOR UPDATE;
|
||||
|
||||
-- Apply payment or refund
|
||||
IF NEW.type = 'PAYMENT' THEN
|
||||
SET newPaid = newPaid + NEW.amount;
|
||||
ELSE
|
||||
SET newPaid = newPaid - NEW.amount;
|
||||
END IF;
|
||||
|
||||
-- Update receipt
|
||||
UPDATE Purchase_Receipts
|
||||
SET
|
||||
paidAmount = newPaid,
|
||||
status =
|
||||
CASE
|
||||
WHEN newPaid = 0 THEN 'UNPAID'
|
||||
WHEN newPaid < receiptTotal THEN 'PARTIALLY_PAID'
|
||||
ELSE 'PAID'
|
||||
END
|
||||
WHERE id = NEW.receiptId;
|
||||
|
||||
-- Get last supplier balance
|
||||
SELECT IFNULL(balance, 0)
|
||||
INTO lastBalance
|
||||
FROM Supplier_Ledger
|
||||
WHERE supplierId = _supplierId
|
||||
ORDER BY id DESC
|
||||
LIMIT 1;
|
||||
|
||||
|
||||
|
||||
-- Insert supplier ledger
|
||||
INSERT INTO Supplier_Ledger
|
||||
(
|
||||
supplierId,
|
||||
debit,
|
||||
credit,
|
||||
balance,
|
||||
sourceType,
|
||||
sourceId,
|
||||
createdAt
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
_supplierId,
|
||||
IF(NEW.type = 'REFUND', NEW.amount, 0),
|
||||
IF(NEW.type = 'PAYMENT', NEW.amount, 0),
|
||||
lastBalance
|
||||
+ IF(NEW.type = 'PAYMENT', NEW.amount, 0)
|
||||
- IF(NEW.type = 'REFUND', NEW.amount, 0),
|
||||
'PAYMENT',
|
||||
NEW.id,
|
||||
NOW()
|
||||
);
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 13
|
||||
-- Trigger: trg_pr_payment_after_delete
|
||||
-- Event: DELETE
|
||||
-- Table: Purchase_Receipt_Payments
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_pr_payment_after_delete`;
|
||||
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_pr_payment_after_delete` AFTER DELETE ON `Purchase_Receipt_Payments` FOR EACH ROW BEGIN
|
||||
DECLARE receiptTotal DECIMAL(14,2);
|
||||
DECLARE newPaid DECIMAL(14,2);
|
||||
|
||||
SELECT totalAmount, paidAmount
|
||||
INTO receiptTotal, newPaid
|
||||
FROM Purchase_Receipts
|
||||
WHERE id = OLD.receiptId
|
||||
FOR UPDATE;
|
||||
|
||||
IF OLD.type = 'PAYMENT' THEN
|
||||
SET newPaid = newPaid - OLD.amount;
|
||||
ELSE
|
||||
SET newPaid = newPaid + OLD.amount;
|
||||
END IF;
|
||||
|
||||
UPDATE Purchase_Receipts
|
||||
SET
|
||||
paidAmount = newPaid,
|
||||
status =
|
||||
CASE
|
||||
WHEN newPaid = 0 THEN 'UNPAID'
|
||||
WHEN newPaid < receiptTotal THEN 'PARTIALLY_PAID'
|
||||
ELSE 'PAID'
|
||||
END
|
||||
WHERE id = OLD.receiptId;
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 14
|
||||
-- Trigger: trg_purchase_receipt_after_insert
|
||||
-- Event: INSERT
|
||||
-- Table: Purchase_Receipts
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_purchase_receipt_after_insert`;
|
||||
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_purchase_receipt_after_insert` AFTER INSERT ON `Purchase_Receipts` FOR EACH ROW BEGIN
|
||||
DECLARE lastBalance DECIMAL(14,2) DEFAULT 0;
|
||||
|
||||
SELECT COALESCE(balance, 0)
|
||||
INTO lastBalance
|
||||
FROM Supplier_Ledger
|
||||
WHERE supplierId = NEW.supplierId
|
||||
ORDER BY id DESC
|
||||
LIMIT 1;
|
||||
|
||||
INSERT INTO Supplier_Ledger
|
||||
(
|
||||
supplierId,
|
||||
debit,
|
||||
credit,
|
||||
balance,
|
||||
sourceType,
|
||||
sourceId,
|
||||
createdAt
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
NEW.supplierId,
|
||||
NEW.totalAmount,
|
||||
0,
|
||||
lastBalance - NEW.totalAmount,
|
||||
'PURCHASE',
|
||||
NEW.id,
|
||||
NOW()
|
||||
);
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 15
|
||||
-- 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);
|
||||
DECLARE inventory_id INT;
|
||||
|
||||
|
||||
|
||||
SELECT pa.inventoryId INTO inventory_id
|
||||
FROM Pos_Accounts pa
|
||||
INNER JOIN Sales_Invoices si ON pa.id = si.posAccountId
|
||||
WHERE si.id = NEW.invoiceId;
|
||||
|
||||
|
||||
SELECT COALESCE(quantity, 0) INTO current_stock
|
||||
FROM Stock_Balance sb
|
||||
WHERE productId = NEW.productId AND sb.inventoryId = inventory_id
|
||||
LIMIT 1;
|
||||
|
||||
|
||||
|
||||
IF NEW.count > current_stock THEN
|
||||
SIGNAL SQLSTATE '45000'
|
||||
SET MESSAGE_TEXT = 'موجودی کالا در انبار کافی نیست.';
|
||||
END IF;
|
||||
end;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 16
|
||||
-- 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 DECLARE current_stock DECIMAL(10, 2);
|
||||
|
||||
DECLARE inventory_id INT;
|
||||
DECLARE customer_id INT;
|
||||
DECLARE pos_id INT;
|
||||
|
||||
|
||||
|
||||
SELECT posAccountId, customerId INTO pos_id, customer_id
|
||||
FROM Sales_Invoices si
|
||||
WHERE si.id = NEW.invoiceId
|
||||
LIMIT 1;
|
||||
INSERT INTO Trigger_Logs (name , message) VALUES ('pos_id', pos_id);
|
||||
INSERT INTO Trigger_Logs (name , message) VALUES ('customer_id', customer_id);
|
||||
|
||||
|
||||
SELECT pa.inventoryId INTO inventory_id
|
||||
FROM Pos_Accounts pa
|
||||
INNER JOIN Sales_Invoices si ON pa.id = si.posAccountId
|
||||
WHERE si.id = NEW.invoiceId;
|
||||
|
||||
|
||||
|
||||
SELECT COALESCE(quantity, 0) INTO current_stock
|
||||
FROM Stock_Balance sb
|
||||
WHERE productId = NEW.productId AND sb.inventoryId = inventory_id
|
||||
LIMIT 1;
|
||||
|
||||
|
||||
|
||||
INSERT INTO Stock_Movements (
|
||||
type,
|
||||
quantity,
|
||||
unitPrice,
|
||||
totalCost,
|
||||
referenceType,
|
||||
referenceId,
|
||||
productId,
|
||||
inventoryId,
|
||||
avgCost,
|
||||
remainedInStock,
|
||||
customerId,
|
||||
createdAt
|
||||
)
|
||||
VALUES (
|
||||
'OUT',
|
||||
NEW.count,
|
||||
NEW.unitPrice,
|
||||
NEW.totalAmount,
|
||||
'SALES',
|
||||
NEW.invoiceId,
|
||||
NEW.productId,
|
||||
inventory_id,
|
||||
|
||||
CASE
|
||||
WHEN NEW.count = 0 THEN 0
|
||||
ELSE NEW.totalAmount / NEW.count
|
||||
END,
|
||||
current_stock - NEW.count,
|
||||
customer_id,
|
||||
NOW()
|
||||
);
|
||||
|
||||
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 17
|
||||
-- Trigger: trg_sales_invoice_payment_after_insert
|
||||
-- Event: INSERT
|
||||
-- Table: Sales_Invoice_Payments
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_sales_invoice_payment_after_insert`;
|
||||
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_sales_invoice_payment_after_insert` AFTER INSERT ON `Sales_Invoice_Payments` FOR EACH ROW BEGIN
|
||||
DECLARE currentBalance DECIMAL(15,2);
|
||||
DECLARE bankAccountId INT;
|
||||
|
||||
SELECT pa.bankAccountId INTO bankAccountId
|
||||
FROM Pos_Accounts pa
|
||||
INNER JOIN Sales_Invoices si ON pa.id = si.posAccountId
|
||||
WHERE si.id = NEW.invoiceId;
|
||||
|
||||
SELECT balance INTO currentBalance
|
||||
FROM Bank_Account_Balance
|
||||
WHERE bankAccountId = bankAccountId
|
||||
FOR UPDATE;
|
||||
|
||||
IF currentBalance IS NULL THEN
|
||||
SET currentBalance = 0;
|
||||
INSERT INTO Bank_Account_Balance (bankAccountId, balance)
|
||||
VALUES (bankAccountId, 0);
|
||||
END IF;
|
||||
|
||||
SET currentBalance = currentBalance + NEW.amount;
|
||||
|
||||
INSERT INTO Bank_Account_Transactions
|
||||
(bankAccountId, type, amount, balanceAfter, referenceType, referenceId)
|
||||
VALUES
|
||||
(bankAccountId, 'DEPOSIT', NEW.amount, currentBalance, 'POS_SALE', NEW.id);
|
||||
|
||||
UPDATE Bank_Account_Balance
|
||||
SET balance = currentBalance
|
||||
WHERE bankAccountId = bankAccountId;
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 18
|
||||
-- Trigger: trg_pos_account_payment_after_insert
|
||||
-- Event: INSERT
|
||||
-- Table: Sales_Invoice_Payments
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_pos_account_payment_after_insert`;
|
||||
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_pos_account_payment_after_insert` AFTER INSERT ON `Sales_Invoice_Payments` FOR EACH ROW BEGIN
|
||||
|
||||
DECLARE _bankAccountId INT;
|
||||
|
||||
IF(NEW.paymentMethod != 'CASH') THEN
|
||||
SELECT cashBankAccountId INTO _bankAccountId
|
||||
FROM Pos_Accounts pa
|
||||
INNER JOIN Sales_Invoices si ON pa.id = si.posAccountId
|
||||
WHERE si.id = NEW.invoiceId;
|
||||
End IF;
|
||||
|
||||
INSERT INTO Bank_Account_Transactions (
|
||||
bankAccountId,
|
||||
type,
|
||||
amount,
|
||||
balanceAfter,
|
||||
referenceType,
|
||||
referenceId
|
||||
)
|
||||
VALUES(
|
||||
_bankAccountId,
|
||||
'DEPOSIT',
|
||||
NEW.amount,
|
||||
0,
|
||||
'POS_SALE',
|
||||
NEW.id
|
||||
);
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 19
|
||||
-- Trigger: trg_stock_transfer
|
||||
-- Event: INSERT
|
||||
-- Table: Stock_Movements
|
||||
-- ------------------------------------------
|
||||
DROP TRIGGER IF EXISTS `trg_stock_transfer`;
|
||||
|
||||
CREATE DEFINER=`pos`@`%` TRIGGER `trg_stock_transfer` AFTER INSERT ON `Stock_Movements` FOR EACH ROW BEGIN IF NEW.referenceType = 'INVENTORY_TRANSFER' THEN IF NEW.type = 'IN' THEN
|
||||
INSERT INTO
|
||||
Stock_Balance (
|
||||
productId,
|
||||
inventoryId,
|
||||
quantity,
|
||||
totalCost,
|
||||
avgCost,
|
||||
updatedAt
|
||||
)
|
||||
VALUES (
|
||||
NEW.productId,
|
||||
NEW.inventoryId,
|
||||
NEW.quantity,
|
||||
NEW.totalCost,
|
||||
CASE
|
||||
WHEN NEW.quantity = 0 THEN 0
|
||||
ELSE NEW.totalCost / NEW.quantity
|
||||
END,
|
||||
NOW()
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
quantity = quantity + NEW.quantity,
|
||||
totalCost = totalCost + NEW.totalCost,
|
||||
avgCost = CASE
|
||||
WHEN (quantity + NEW.quantity) = 0 THEN 0
|
||||
ELSE (totalCost + NEW.totalCost) / (quantity + NEW.quantity)
|
||||
END,
|
||||
updatedAt = NOW();
|
||||
|
||||
END IF;
|
||||
|
||||
IF NEW.type = 'OUT' THEN IF EXISTS (
|
||||
SELECT 1
|
||||
FROM Stock_Balance sb
|
||||
WHERE
|
||||
sb.productId = NEW.productId
|
||||
AND sb.inventoryId = NEW.inventoryId
|
||||
) THEN
|
||||
|
||||
UPDATE Stock_Balance sb
|
||||
SET
|
||||
sb.quantity = sb.quantity - NEW.quantity,
|
||||
sb.totalCost = sb.totalCost - (sb.avgCost * NEW.quantity),
|
||||
sb.updatedAt = NOW()
|
||||
WHERE
|
||||
sb.productId = NEW.productId
|
||||
AND sb.inventoryId = NEW.inventoryId;
|
||||
|
||||
ELSE
|
||||
INSERT INTO
|
||||
Stock_Balance (
|
||||
productId,
|
||||
inventoryId,
|
||||
quantity,
|
||||
totalCost,
|
||||
avgCost,
|
||||
updatedAt
|
||||
)
|
||||
VALUES (
|
||||
NEW.productId,
|
||||
NEW.inventoryId,
|
||||
- NEW.quantity,
|
||||
- COALESCE(NEW.unitPrice, 0) * NEW.quantity,
|
||||
COALESCE(NEW.unitPrice, 0),
|
||||
NOW()
|
||||
);
|
||||
|
||||
END IF;
|
||||
|
||||
END IF;
|
||||
|
||||
END IF;
|
||||
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 20
|
||||
-- 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,
|
||||
inventoryId,
|
||||
updatedAt
|
||||
)
|
||||
VALUES (
|
||||
NEW.productId,
|
||||
NEW.quantity,
|
||||
NEW.unitPrice,
|
||||
NEW.totalCost,
|
||||
NEW.inventoryId,
|
||||
NOW()
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
quantity = quantity + NEW.quantity,
|
||||
totalCost = totalCost + NEW.totalCost,
|
||||
avgCost = totalCost / quantity;
|
||||
|
||||
END IF;
|
||||
|
||||
END;
|
||||
|
||||
-- ------------------------------------------
|
||||
-- index: 21
|
||||
-- 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
|
||||
|
||||
INSERT INTO
|
||||
Stock_Balance (
|
||||
productId,
|
||||
quantity,
|
||||
avgCost,
|
||||
totalCost,
|
||||
inventoryId,
|
||||
updatedAt
|
||||
)
|
||||
VALUES (
|
||||
NEW.productId,
|
||||
NEW.quantity,
|
||||
NEW.unitPrice,
|
||||
NEW.totalCost,
|
||||
NEW.inventoryId,
|
||||
NOW()
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
quantity = quantity - NEW.quantity,
|
||||
totalCost = totalCost - NEW.totalCost,
|
||||
avgCost = totalCost / quantity;
|
||||
|
||||
END IF;
|
||||
|
||||
END;
|
||||
@@ -1,657 +0,0 @@
|
||||
-- Stored Procedures equivalent to triggers
|
||||
|
||||
DELIMITER / /
|
||||
|
||||
-- Procedure for trg_bank_account_transaction_after_insert
|
||||
CREATE PROCEDURE update_bank_balance(IN p_bankAccountId INT, IN p_type VARCHAR(20), IN p_amount DECIMAL(15,2))
|
||||
BEGIN
|
||||
START TRANSACTION;
|
||||
IF p_type = 'DEPOSIT' THEN
|
||||
UPDATE Bank_Account_Balance SET balance = balance + p_amount WHERE bankAccountId = p_bankAccountId;
|
||||
ELSEIF p_type = 'WITHDRAWAL' THEN
|
||||
UPDATE Bank_Account_Balance SET balance = balance - p_amount WHERE bankAccountId = p_bankAccountId;
|
||||
END IF;
|
||||
COMMIT;
|
||||
END //
|
||||
|
||||
-- Procedure for trg_bank_account_transaction_after_delete
|
||||
CREATE PROCEDURE update_bank_balance_on_delete(IN p_bankAccountId INT, IN p_amount DECIMAL(15,2))
|
||||
BEGIN
|
||||
START TRANSACTION;
|
||||
UPDATE Bank_Accounts SET balance = balance - p_amount WHERE id = p_bankAccountId;
|
||||
COMMIT;
|
||||
END //
|
||||
|
||||
-- Procedure for trg_transfer_item_after_insert
|
||||
CREATE PROCEDURE process_transfer_item(IN p_transferId INT, IN p_productId INT, IN p_count DECIMAL(10,2))
|
||||
BEGIN
|
||||
START TRANSACTION;
|
||||
DECLARE fromInv INT;
|
||||
DECLARE toInv INT;
|
||||
DECLARE _avgCost DECIMAL(10,2);
|
||||
DECLARE latestQuantityInOrigin DECIMAL(10,2);
|
||||
DECLARE latestQuantityInDestination DECIMAL(10,2);
|
||||
|
||||
SELECT fromInventoryId, toInventoryId INTO fromInv, toInv
|
||||
FROM Inventory_Transfers WHERE id = p_transferId;
|
||||
|
||||
SELECT COALESCE(avgCost, 0), COALESCE(quantity, 0) INTO _avgCost, latestQuantityInOrigin FROM Stock_Balance
|
||||
WHERE ProductId = p_productId AND inventoryId = fromInv LIMIT 1;
|
||||
|
||||
SELECT COALESCE(quantity, 0) INTO latestQuantityInDestination FROM Stock_Balance
|
||||
WHERE ProductId = p_productId AND inventoryId = toInv LIMIT 1;
|
||||
|
||||
-- OUT from source
|
||||
INSERT INTO Stock_Movements
|
||||
(type, quantity, unitPrice, totalCost, avgCost, referenceType, referenceId, productId, inventoryId, counterInventoryId, createdAt, remainedInStock)
|
||||
VALUES
|
||||
('OUT', p_count, _avgCost, _avgCost*p_count, _avgCost, 'INVENTORY_TRANSFER', p_transferId, p_productId, fromInv, toInv, NOW(), latestQuantityInOrigin-p_count);
|
||||
|
||||
-- IN to destination
|
||||
INSERT INTO Stock_Movements
|
||||
(type, quantity, unitPrice, totalCost, avgCost, referenceType, referenceId, productId, inventoryId, counterInventoryId, createdAt, remainedInStock)
|
||||
VALUES
|
||||
('IN', p_count, _avgCost, _avgCost*p_count, _avgCost, 'INVENTORY_TRANSFER', p_transferId, p_productId, toInv, fromInv, NOW(), latestQuantityInOrigin-p_count);
|
||||
COMMIT;
|
||||
END //
|
||||
|
||||
-- Procedure for trg_order_item_after_insert
|
||||
CREATE PROCEDURE update_stock_reservation_insert(IN p_orderId INT, IN p_productId INT, IN p_quantity DECIMAL(10,2))
|
||||
BEGIN
|
||||
START TRANSACTION;
|
||||
UPDATE Stock_Reservations SET quantity = quantity + p_quantity
|
||||
WHERE orderId = p_orderId AND productId = p_productId;
|
||||
COMMIT;
|
||||
END //
|
||||
|
||||
-- Procedure for trg_order_item_after_update
|
||||
CREATE PROCEDURE update_stock_reservation_update(IN p_orderId INT, IN p_productId INT, IN p_old_quantity DECIMAL(10,2), IN p_new_quantity DECIMAL(10,2))
|
||||
BEGIN
|
||||
START TRANSACTION;
|
||||
UPDATE Stock_Reservations
|
||||
SET quantity = quantity - p_old_quantity + p_new_quantity
|
||||
WHERE orderId = p_orderId AND productId = p_productId;
|
||||
COMMIT;
|
||||
END //
|
||||
|
||||
-- Procedure for trg_order_item_after_delete
|
||||
CREATE PROCEDURE update_stock_reservation_delete(IN p_orderId INT, IN p_productId INT, IN p_quantity DECIMAL(10,2))
|
||||
BEGIN
|
||||
START TRANSACTION;
|
||||
UPDATE Stock_Reservations SET quantity = quantity - p_quantity
|
||||
WHERE orderId = p_orderId AND productId = p_productId;
|
||||
COMMIT;
|
||||
END //
|
||||
|
||||
-- Procedure for trg_order_after_cancel
|
||||
CREATE PROCEDURE cancel_order_stock(IN p_orderId INT, IN p_status VARCHAR(20))
|
||||
BEGIN
|
||||
START TRANSACTION;
|
||||
IF p_status = 'CANCELED' OR p_status = 'REJECTED' OR p_status = 'DONE' THEN
|
||||
UPDATE Stock_Reservations sr SET quantity = 0
|
||||
WHERE sr.orderId = p_orderId;
|
||||
END IF;
|
||||
COMMIT;
|
||||
END //
|
||||
|
||||
-- Procedure for trg_purchase_receipt_item_after_insert
|
||||
CREATE PROCEDURE process_purchase_item(IN p_receiptId INT, IN p_productId INT, IN p_count DECIMAL(10,2), IN p_unitPrice DECIMAL(15,2), IN p_totalAmount DECIMAL(15,2))
|
||||
BEGIN
|
||||
START TRANSACTION;
|
||||
DECLARE latestQuantity DECIMAL(10, 2) DEFAULT 0;
|
||||
DECLARE invId INT;
|
||||
DECLARE suppId INT;
|
||||
|
||||
-- Get inventory & supplier from
|
||||
SELECT inventoryId, supplierId
|
||||
INTO invId, suppId
|
||||
FROM Purchase_Receipts
|
||||
WHERE id = p_receiptId;
|
||||
|
||||
-- Get current stock quantity (if exists)
|
||||
SELECT COALESCE(quantity, 0)
|
||||
INTO latestQuantity
|
||||
FROM Stock_Balance sb
|
||||
WHERE sb.inventoryId = invId
|
||||
AND sb.productId = p_productId
|
||||
LIMIT 1;
|
||||
|
||||
-- Insert stock movement
|
||||
INSERT INTO Stock_Movements (
|
||||
type,
|
||||
quantity,
|
||||
unitPrice,
|
||||
totalCost,
|
||||
referenceType,
|
||||
referenceId,
|
||||
productId,
|
||||
inventoryId,
|
||||
avgCost,
|
||||
supplierId,
|
||||
remainedInStock,
|
||||
createdAt
|
||||
)
|
||||
VALUES (
|
||||
'IN',
|
||||
p_count,
|
||||
p_unitPrice,
|
||||
p_totalAmount,
|
||||
'PURCHASE',
|
||||
p_receiptId,
|
||||
p_productId,
|
||||
invId,
|
||||
CASE
|
||||
WHEN p_count = 0 THEN 0
|
||||
ELSE p_totalAmount / p_count
|
||||
END,
|
||||
suppId,
|
||||
latestQuantity + p_count,
|
||||
NOW()
|
||||
);
|
||||
COMMIT;
|
||||
END //
|
||||
|
||||
-- Procedure for trg_pr_payment_before_insert
|
||||
CREATE PROCEDURE validate_payment_before_insert(IN p_receiptId INT, IN p_type VARCHAR(20), IN p_amount DECIMAL(15,2))
|
||||
BEGIN
|
||||
START TRANSACTION;
|
||||
DECLARE receiptTotal DECIMAL(14,2);
|
||||
DECLARE paid DECIMAL(14,2);
|
||||
|
||||
SELECT totalAmount, paidAmount
|
||||
INTO receiptTotal, paid
|
||||
FROM Purchase_Receipts
|
||||
WHERE id = p_receiptId
|
||||
FOR UPDATE;
|
||||
|
||||
IF p_type = 'PAYMENT' AND paid + p_amount > receiptTotal THEN
|
||||
SIGNAL SQLSTATE '45000'
|
||||
SET MESSAGE_TEXT = 'مجموع مبلغ پرداختی بیشتر از مبلغ فاکتور است.';
|
||||
END IF;
|
||||
COMMIT;
|
||||
END //
|
||||
|
||||
-- Procedure for trg_purchase_payment_update_receipt
|
||||
CREATE PROCEDURE update_receipt_payment(IN p_receiptId INT)
|
||||
BEGIN
|
||||
START TRANSACTION;
|
||||
DECLARE paid DECIMAL(15,2);
|
||||
DECLARE total DECIMAL(15,2);
|
||||
|
||||
SELECT
|
||||
COALESCE(SUM(
|
||||
CASE WHEN type = 'PAYMENT' THEN amount ELSE -amount END
|
||||
),0)
|
||||
INTO paid
|
||||
FROM Purchase_Receipt_Payments
|
||||
WHERE receiptId = p_receiptId;
|
||||
|
||||
SELECT totalAmount INTO total
|
||||
FROM Purchase_Receipts
|
||||
WHERE id = p_receiptId;
|
||||
|
||||
UPDATE Purchase_Receipts
|
||||
SET
|
||||
paidAmount = paid,
|
||||
status = CASE
|
||||
WHEN paid = 0 THEN 'UNPAID'
|
||||
WHEN paid < total THEN 'PARTIALLY_PAID'
|
||||
ELSE 'PAID'
|
||||
END
|
||||
WHERE id = p_receiptId;
|
||||
COMMIT;
|
||||
END //
|
||||
|
||||
-- Procedure for trg_purchase_payment_after_insert
|
||||
CREATE PROCEDURE process_purchase_payment(IN p_bankAccountId INT, IN p_type VARCHAR(20), IN p_amount DECIMAL(15,2), IN p_id INT)
|
||||
BEGIN
|
||||
START TRANSACTION;
|
||||
DECLARE currentBalance DECIMAL(15, 2);
|
||||
|
||||
SELECT balance INTO currentBalance
|
||||
FROM Bank_Account_Balance
|
||||
WHERE bankAccountId = p_bankAccountId FOR UPDATE;
|
||||
|
||||
IF currentBalance IS NULL THEN SET currentBalance = 0;
|
||||
INSERT INTO Bank_Account_Balance (bankAccountId, balance, updatedAt)
|
||||
VALUES (p_bankAccountId, 0, NOW());
|
||||
END IF;
|
||||
|
||||
IF p_type = 'PAYMENT' THEN
|
||||
SET currentBalance = currentBalance - p_amount;
|
||||
INSERT INTO Bank_Account_Transactions (
|
||||
bankAccountId,
|
||||
type,
|
||||
amount,
|
||||
balanceAfter,
|
||||
referenceType,
|
||||
referenceId
|
||||
)
|
||||
VALUES (
|
||||
p_bankAccountId,
|
||||
'WITHDRAWAL',
|
||||
p_amount,
|
||||
currentBalance,
|
||||
'PURCHASE_PAYMENT',
|
||||
p_id
|
||||
);
|
||||
ELSE
|
||||
SET currentBalance = currentBalance + p_amount;
|
||||
INSERT INTO Bank_Account_Transactions (
|
||||
bankAccountId,
|
||||
type,
|
||||
amount,
|
||||
balanceAfter,
|
||||
referenceType,
|
||||
referenceId
|
||||
)
|
||||
VALUES (
|
||||
p_bankAccountId,
|
||||
'DEPOSIT',
|
||||
p_amount,
|
||||
currentBalance,
|
||||
'PURCHASE_REFUND',
|
||||
p_id
|
||||
);
|
||||
END IF;
|
||||
|
||||
UPDATE Bank_Account_Balance
|
||||
SET balance = currentBalance
|
||||
WHERE bankAccountId = p_bankAccountId;
|
||||
COMMIT;
|
||||
END //
|
||||
|
||||
-- Procedure for trg_pr_payment_after_insert
|
||||
CREATE PROCEDURE update_supplier_ledger(IN p_receiptId INT, IN p_type VARCHAR(20), IN p_amount DECIMAL(15,2), IN p_id INT)
|
||||
BEGIN
|
||||
START TRANSACTION;
|
||||
DECLARE receiptTotal DECIMAL(14,2) DEFAULT 0;
|
||||
DECLARE newPaid DECIMAL(14,2) DEFAULT 0;
|
||||
DECLARE _supplierId INT;
|
||||
DECLARE lastBalance DECIMAL(14,2) DEFAULT 0;
|
||||
|
||||
-- Lock receipt row
|
||||
SELECT COALESCE(totalAmount, 0), COALESCE(paidAmount, 0), supplierId
|
||||
INTO receiptTotal, newPaid, _supplierId
|
||||
FROM Purchase_Receipts
|
||||
WHERE id = p_receiptId
|
||||
FOR UPDATE;
|
||||
|
||||
-- Apply payment or refund
|
||||
IF p_type = 'PAYMENT' THEN
|
||||
SET newPaid = newPaid + p_amount;
|
||||
ELSE
|
||||
SET newPaid = newPaid - p_amount;
|
||||
END IF;
|
||||
|
||||
-- Update receipt
|
||||
UPDATE Purchase_Receipts
|
||||
SET
|
||||
paidAmount = newPaid,
|
||||
status =
|
||||
CASE
|
||||
WHEN newPaid = 0 THEN 'UNPAID'
|
||||
WHEN newPaid < receiptTotal THEN 'PARTIALLY_PAID'
|
||||
ELSE 'PAID'
|
||||
END
|
||||
WHERE id = p_receiptId;
|
||||
|
||||
-- Get last supplier balance
|
||||
SELECT IFNULL(balance, 0)
|
||||
INTO lastBalance
|
||||
FROM Supplier_Ledger
|
||||
WHERE supplierId = _supplierId
|
||||
ORDER BY id DESC
|
||||
LIMIT 1;
|
||||
|
||||
-- Insert supplier ledger
|
||||
INSERT INTO Supplier_Ledger
|
||||
(
|
||||
supplierId,
|
||||
debit,
|
||||
credit,
|
||||
balance,
|
||||
sourceType,
|
||||
sourceId,
|
||||
createdAt
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
_supplierId,
|
||||
IF(p_type = 'REFUND', p_amount, 0),
|
||||
IF(p_type = 'PAYMENT', p_amount, 0),
|
||||
lastBalance
|
||||
+ IF(p_type = 'PAYMENT', p_amount, 0)
|
||||
- IF(p_type = 'REFUND', p_amount, 0),
|
||||
'PAYMENT',
|
||||
p_id,
|
||||
NOW()
|
||||
);
|
||||
COMMIT;
|
||||
END //
|
||||
|
||||
-- Procedure for trg_pr_payment_after_delete
|
||||
CREATE PROCEDURE update_receipt_on_payment_delete(IN p_receiptId INT, IN p_type VARCHAR(20), IN p_amount DECIMAL(15,2))
|
||||
BEGIN
|
||||
DECLARE receiptTotal DECIMAL(14,2);
|
||||
DECLARE newPaid DECIMAL(14,2);
|
||||
|
||||
SELECT totalAmount, paidAmount
|
||||
INTO receiptTotal, newPaid
|
||||
FROM Purchase_Receipts
|
||||
WHERE id = p_receiptId
|
||||
FOR UPDATE;
|
||||
|
||||
IF p_type = 'PAYMENT' THEN
|
||||
SET newPaid = newPaid - p_amount;
|
||||
ELSE
|
||||
SET newPaid = newPaid + p_amount;
|
||||
END IF;
|
||||
|
||||
UPDATE Purchase_Receipts
|
||||
SET
|
||||
paidAmount = newPaid,
|
||||
status =
|
||||
CASE
|
||||
WHEN newPaid = 0 THEN 'UNPAID'
|
||||
WHEN newPaid < receiptTotal THEN 'PARTIALLY_PAID'
|
||||
ELSE 'PAID'
|
||||
END
|
||||
WHERE id = p_receiptId;
|
||||
END //
|
||||
|
||||
-- Procedure for trg_purchase_receipt_after_insert
|
||||
CREATE PROCEDURE insert_supplier_ledger_purchase(IN p_supplierId INT, IN p_totalAmount DECIMAL(15,2), IN p_id INT)
|
||||
BEGIN
|
||||
DECLARE lastBalance DECIMAL(14,2) DEFAULT 0;
|
||||
|
||||
SELECT COALESCE(balance, 0)
|
||||
INTO lastBalance
|
||||
FROM Supplier_Ledger
|
||||
WHERE supplierId = p_supplierId
|
||||
ORDER BY id DESC
|
||||
LIMIT 1;
|
||||
|
||||
INSERT INTO Supplier_Ledger
|
||||
(
|
||||
supplierId,
|
||||
debit,
|
||||
credit,
|
||||
balance,
|
||||
sourceType,
|
||||
sourceId,
|
||||
createdAt
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
p_supplierId,
|
||||
p_totalAmount,
|
||||
0,
|
||||
lastBalance - p_totalAmount,
|
||||
'PURCHASE',
|
||||
p_id,
|
||||
NOW()
|
||||
);
|
||||
END //
|
||||
|
||||
-- Procedure for trg_sales_invoice_items_before_insert
|
||||
CREATE PROCEDURE validate_stock_before_sale(IN p_invoiceId INT, IN p_productId INT, IN p_count DECIMAL(10,2))
|
||||
BEGIN
|
||||
DECLARE current_stock DECIMAL(10, 2);
|
||||
DECLARE inventory_id INT;
|
||||
|
||||
SELECT pa.inventoryId INTO inventory_id
|
||||
FROM Pos_Accounts pa
|
||||
INNER JOIN Sales_Invoices si ON pa.id = si.posAccountId
|
||||
WHERE si.id = p_invoiceId;
|
||||
|
||||
SELECT COALESCE(quantity, 0) INTO current_stock
|
||||
FROM Stock_Balance sb
|
||||
WHERE productId = p_productId AND sb.inventoryId = inventory_id
|
||||
LIMIT 1;
|
||||
|
||||
IF p_count > current_stock THEN
|
||||
SIGNAL SQLSTATE '45000'
|
||||
SET MESSAGE_TEXT = 'موجودی کالا در انبار کافی نیست.';
|
||||
END IF;
|
||||
END //
|
||||
|
||||
-- Procedure for trg_sales_invoice_items_after_insert
|
||||
CREATE PROCEDURE process_sale_item(IN p_invoiceId INT, IN p_productId INT, IN p_count DECIMAL(10,2), IN p_unitPrice DECIMAL(15,2), IN p_totalAmount DECIMAL(15,2))
|
||||
BEGIN
|
||||
DECLARE current_stock DECIMAL(10, 2);
|
||||
DECLARE inventory_id INT;
|
||||
DECLARE customer_id INT;
|
||||
DECLARE pos_id INT;
|
||||
|
||||
SELECT posAccountId, customerId INTO pos_id, customer_id
|
||||
FROM Sales_Invoices si
|
||||
WHERE si.id = p_invoiceId
|
||||
LIMIT 1;
|
||||
|
||||
SELECT pa.inventoryId INTO inventory_id
|
||||
FROM Pos_Accounts pa
|
||||
INNER JOIN Sales_Invoices si ON pa.id = si.posAccountId
|
||||
WHERE si.id = p_invoiceId;
|
||||
|
||||
SELECT COALESCE(quantity, 0) INTO current_stock
|
||||
FROM Stock_Balance sb
|
||||
WHERE productId = p_productId AND sb.inventoryId = inventory_id
|
||||
LIMIT 1;
|
||||
|
||||
INSERT INTO Stock_Movements (
|
||||
type,
|
||||
quantity,
|
||||
unitPrice,
|
||||
totalCost,
|
||||
referenceType,
|
||||
referenceId,
|
||||
productId,
|
||||
inventoryId,
|
||||
avgCost,
|
||||
remainedInStock,
|
||||
customerId,
|
||||
createdAt
|
||||
)
|
||||
VALUES (
|
||||
'OUT',
|
||||
p_count,
|
||||
p_unitPrice,
|
||||
p_totalAmount,
|
||||
'SALES',
|
||||
p_invoiceId,
|
||||
p_productId,
|
||||
inventory_id,
|
||||
CASE
|
||||
WHEN p_count = 0 THEN 0
|
||||
ELSE p_totalAmount / p_count
|
||||
END,
|
||||
current_stock - p_count,
|
||||
customer_id,
|
||||
NOW()
|
||||
);
|
||||
END //
|
||||
|
||||
-- Procedure for trg_sales_invoice_payment_after_insert
|
||||
CREATE PROCEDURE process_sale_payment(IN p_invoiceId INT, IN p_amount DECIMAL(15,2), IN p_id INT)
|
||||
BEGIN
|
||||
DECLARE currentBalance DECIMAL(15,2);
|
||||
DECLARE bankAccountId INT;
|
||||
|
||||
SELECT pa.bankAccountId INTO bankAccountId
|
||||
FROM Pos_Accounts pa
|
||||
INNER JOIN Sales_Invoices si ON pa.id = si.posAccountId
|
||||
WHERE si.id = p_invoiceId;
|
||||
|
||||
SELECT balance INTO currentBalance
|
||||
FROM Bank_Account_Balance
|
||||
WHERE bankAccountId = bankAccountId
|
||||
FOR UPDATE;
|
||||
|
||||
IF currentBalance IS NULL THEN
|
||||
SET currentBalance = 0;
|
||||
INSERT INTO Bank_Account_Balance (bankAccountId, balance, updatedAt)
|
||||
VALUES (bankAccountId, 0, NOW());
|
||||
END IF;
|
||||
|
||||
SET currentBalance = currentBalance + p_amount;
|
||||
|
||||
INSERT INTO Bank_Account_Transactions
|
||||
(bankAccountId, type, amount, balanceAfter, referenceType, referenceId)
|
||||
VALUES
|
||||
(bankAccountId, 'DEPOSIT', p_amount, currentBalance, 'POS_SALE', p_id);
|
||||
|
||||
UPDATE Bank_Account_Balance
|
||||
SET balance = currentBalance
|
||||
WHERE bankAccountId = bankAccountId;
|
||||
END //
|
||||
|
||||
-- Procedure for trg_pos_account_payment_after_insert
|
||||
CREATE PROCEDURE process_pos_payment(IN p_invoiceId INT, IN p_paymentMethod VARCHAR(20), IN p_amount DECIMAL(15,2), IN p_id INT)
|
||||
BEGIN
|
||||
DECLARE _bankAccountId INT;
|
||||
|
||||
IF(p_paymentMethod != 'CASH') THEN
|
||||
SELECT cashBankAccountId INTO _bankAccountId
|
||||
FROM Pos_Accounts pa
|
||||
INNER JOIN Sales_Invoices si ON pa.id = si.posAccountId
|
||||
WHERE si.id = p_invoiceId;
|
||||
END IF;
|
||||
|
||||
INSERT INTO Bank_Account_Transactions (
|
||||
bankAccountId,
|
||||
type,
|
||||
amount,
|
||||
balanceAfter,
|
||||
referenceType,
|
||||
referenceId
|
||||
)
|
||||
VALUES(
|
||||
_bankAccountId,
|
||||
'DEPOSIT',
|
||||
p_amount,
|
||||
0,
|
||||
'POS_SALE',
|
||||
p_id
|
||||
);
|
||||
END //
|
||||
|
||||
-- Procedure for trg_stock_transfer
|
||||
CREATE PROCEDURE update_stock_balance_transfer(IN p_productId INT, IN p_inventoryId INT, IN p_quantity DECIMAL(10,2), IN p_unitPrice DECIMAL(15,2), IN p_totalCost DECIMAL(15,2), IN p_type VARCHAR(10))
|
||||
BEGIN
|
||||
IF p_type = 'IN' THEN
|
||||
INSERT INTO Stock_Balance (
|
||||
productId,
|
||||
inventoryId,
|
||||
quantity,
|
||||
totalCost,
|
||||
avgCost,
|
||||
updatedAt
|
||||
)
|
||||
VALUES (
|
||||
p_productId,
|
||||
p_inventoryId,
|
||||
p_quantity,
|
||||
p_totalCost,
|
||||
CASE
|
||||
WHEN p_quantity = 0 THEN 0
|
||||
ELSE p_totalCost / p_quantity
|
||||
END,
|
||||
NOW()
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
quantity = quantity + p_quantity,
|
||||
totalCost = totalCost + p_totalCost,
|
||||
avgCost = CASE
|
||||
WHEN (quantity + p_quantity) = 0 THEN 0
|
||||
ELSE (totalCost + p_totalCost) / (quantity + p_quantity)
|
||||
END,
|
||||
updatedAt = NOW();
|
||||
END IF;
|
||||
|
||||
IF p_type = 'OUT' THEN
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM Stock_Balance sb
|
||||
WHERE sb.productId = p_productId AND sb.inventoryId = p_inventoryId
|
||||
) THEN
|
||||
UPDATE Stock_Balance sb
|
||||
SET
|
||||
sb.quantity = sb.quantity - p_quantity,
|
||||
sb.totalCost = sb.totalCost - (sb.avgCost * p_quantity),
|
||||
sb.updatedAt = NOW()
|
||||
WHERE
|
||||
sb.productId = p_productId
|
||||
AND sb.inventoryId = p_inventoryId;
|
||||
ELSE
|
||||
INSERT INTO Stock_Balance (
|
||||
productId,
|
||||
inventoryId,
|
||||
quantity,
|
||||
totalCost,
|
||||
avgCost,
|
||||
updatedAt
|
||||
)
|
||||
VALUES (
|
||||
p_productId,
|
||||
p_inventoryId,
|
||||
- p_quantity,
|
||||
- COALESCE(p_unitPrice, 0) * p_quantity,
|
||||
COALESCE(p_unitPrice, 0),
|
||||
NOW()
|
||||
);
|
||||
END IF;
|
||||
END IF;
|
||||
END //
|
||||
|
||||
-- Procedure for trg_stock_purchase_insert
|
||||
CREATE PROCEDURE update_stock_balance_purchase(IN p_productId INT, IN p_quantity DECIMAL(10,2), IN p_unitPrice DECIMAL(15,2), IN p_totalCost DECIMAL(15,2), IN p_inventoryId INT)
|
||||
BEGIN
|
||||
INSERT INTO Stock_Balance (
|
||||
productId,
|
||||
quantity,
|
||||
avgCost,
|
||||
totalCost,
|
||||
inventoryId,
|
||||
updatedAt
|
||||
)
|
||||
VALUES (
|
||||
p_productId,
|
||||
p_quantity,
|
||||
p_unitPrice,
|
||||
p_totalCost,
|
||||
p_inventoryId,
|
||||
NOW()
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
quantity = quantity + p_quantity,
|
||||
totalCost = totalCost + p_totalCost,
|
||||
avgCost = totalCost / quantity;
|
||||
END //
|
||||
|
||||
-- Procedure for trg_stock_sale_insert
|
||||
CREATE PROCEDURE update_stock_balance_sale(IN p_productId INT, IN p_quantity DECIMAL(10,2), IN p_unitPrice DECIMAL(15,2), IN p_totalCost DECIMAL(15,2), IN p_inventoryId INT)
|
||||
BEGIN
|
||||
INSERT INTO Stock_Balance (
|
||||
productId,
|
||||
quantity,
|
||||
avgCost,
|
||||
totalCost,
|
||||
inventoryId,
|
||||
updatedAt
|
||||
)
|
||||
VALUES (
|
||||
p_productId,
|
||||
p_quantity,
|
||||
p_unitPrice,
|
||||
p_totalCost,
|
||||
p_inventoryId,
|
||||
NOW()
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
quantity = quantity - p_quantity,
|
||||
totalCost = totalCost - p_totalCost,
|
||||
avgCost = totalCost / quantity;
|
||||
END //
|
||||
|
||||
DELIMITER;
|
||||
@@ -1,66 +1,65 @@
|
||||
#!/usr/bin/env ts-node
|
||||
import * as fs from 'fs'
|
||||
import * as path from 'path'
|
||||
import { prisma } from '../src/lib/prisma'
|
||||
// #!/usr/bin/env ts-node
|
||||
// import * as fs from 'fs'
|
||||
// import * as path from 'path'
|
||||
|
||||
function findModules(dir: string): string[] {
|
||||
const results: string[] = []
|
||||
const entries = fs.readdirSync(dir, { withFileTypes: true })
|
||||
for (const e of entries) {
|
||||
const full = path.join(dir, e.name)
|
||||
if (e.isDirectory()) {
|
||||
results.push(...findModules(full))
|
||||
} else if (e.isFile() && e.name.endsWith('.module.ts')) {
|
||||
results.push(full)
|
||||
}
|
||||
}
|
||||
return results
|
||||
}
|
||||
// function findModules(dir: string): string[] {
|
||||
// const results: string[] = []
|
||||
// const entries = fs.readdirSync(dir, { withFileTypes: true })
|
||||
// for (const e of entries) {
|
||||
// const full = path.join(dir, e.name)
|
||||
// if (e.isDirectory()) {
|
||||
// results.push(...findModules(full))
|
||||
// } else if (e.isFile() && e.name.endsWith('.module.ts')) {
|
||||
// results.push(full)
|
||||
// }
|
||||
// }
|
||||
// return results
|
||||
// }
|
||||
|
||||
function moduleNameFromFile(filePath: string) {
|
||||
const name = path.basename(filePath).replace('.module.ts', '')
|
||||
return name.replace(/-module$|\.module$/i, '')
|
||||
}
|
||||
// function moduleNameFromFile(filePath: string) {
|
||||
// const name = path.basename(filePath).replace('.module.ts', '')
|
||||
// return name.replace(/-module$|\.module$/i, '')
|
||||
// }
|
||||
|
||||
function makePermissionsFor(moduleName: string) {
|
||||
const base = moduleName.replace(/\W+/g, '_').toLowerCase()
|
||||
return [`${base}:create`, `${base}:read`, `${base}:update`, `${base}:delete`]
|
||||
}
|
||||
// function makePermissionsFor(moduleName: string) {
|
||||
// const base = moduleName.replace(/\W+/g, '_').toLowerCase()
|
||||
// return [`${base}:create`, `${base}:read`, `${base}:update`, `${base}:delete`]
|
||||
// }
|
||||
|
||||
async function main() {
|
||||
// const srcDir = path.resolve(__dirname, '..', 'src')
|
||||
// const moduleFiles = findModules(srcDir)
|
||||
// const modules = moduleFiles.map(moduleNameFromFile)
|
||||
// async function main() {
|
||||
// // const srcDir = path.resolve(__dirname, '..', 'src')
|
||||
// // const moduleFiles = findModules(srcDir)
|
||||
// // const modules = moduleFiles.map(moduleNameFromFile)
|
||||
|
||||
// const permsMap: Record<string, boolean> = {}
|
||||
// for (const m of modules) {
|
||||
// for (const p of makePermissionsFor(m)) permsMap[p] = false
|
||||
// }
|
||||
// // const permsMap: Record<string, boolean> = {}
|
||||
// // for (const m of modules) {
|
||||
// // for (const p of makePermissionsFor(m)) permsMap[p] = false
|
||||
// // }
|
||||
|
||||
// // Upsert roles: ensure admin has full permissions, others get entries added
|
||||
// const roles = await prisma.role.findMany()
|
||||
// for (const r of roles) {
|
||||
// const current: Record<string, any> = (r.permissions as any) || {}
|
||||
// const merged = { ...permsMap, ...current }
|
||||
// // // Upsert roles: ensure admin has full permissions, others get entries added
|
||||
// // const roles = await prisma.role.findMany()
|
||||
// // for (const r of roles) {
|
||||
// // const current: Record<string, any> = (r.permissions as any) || {}
|
||||
// // const merged = { ...permsMap, ...current }
|
||||
|
||||
// // If role name is admin (case-insensitive), set all permissions to true
|
||||
// if (r.name && r.name.toLowerCase() === 'admin') {
|
||||
// for (const key of Object.keys(merged)) merged[key] = true
|
||||
// } else {
|
||||
// // keep existing truthy values, otherwise false
|
||||
// for (const key of Object.keys(merged)) merged[key] = merged[key] || false
|
||||
// }
|
||||
// // // If role name is admin (case-insensitive), set all permissions to true
|
||||
// // if (r.name && r.name.toLowerCase() === 'admin') {
|
||||
// // for (const key of Object.keys(merged)) merged[key] = true
|
||||
// // } else {
|
||||
// // // keep existing truthy values, otherwise false
|
||||
// // for (const key of Object.keys(merged)) merged[key] = merged[key] || false
|
||||
// // }
|
||||
|
||||
// await prisma.role.update({ where: { id: r.id }, data: { permissions: merged } })
|
||||
// console.log(
|
||||
// `Updated role ${r.name} (id=${r.id}) with ${Object.keys(merged).length} permissions`,
|
||||
// )
|
||||
// }
|
||||
// // await prisma.role.update({ where: { id: r.id }, data: { permissions: merged } })
|
||||
// // console.log(
|
||||
// // `Updated role ${r.name} (id=${r.id}) with ${Object.keys(merged).length} permissions`,
|
||||
// // )
|
||||
// // }
|
||||
|
||||
await prisma.$disconnect()
|
||||
}
|
||||
// await prisma.$disconnect()
|
||||
// }
|
||||
|
||||
main().catch(e => {
|
||||
console.error(e)
|
||||
process.exit(1)
|
||||
})
|
||||
// main().catch(e => {
|
||||
// console.error(e)
|
||||
// process.exit(1)
|
||||
// })
|
||||
|
||||
+121
-122
@@ -1,144 +1,143 @@
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import { prisma } from '../src/lib/prisma'
|
||||
// import fs from 'node:fs'
|
||||
// import path from 'node:path'
|
||||
|
||||
type CsvRow = {
|
||||
ID?: string
|
||||
DescriptionOfID?: string
|
||||
Vat?: string
|
||||
Type?: string
|
||||
}
|
||||
// type CsvRow = {
|
||||
// ID?: string
|
||||
// DescriptionOfID?: string
|
||||
// Vat?: string
|
||||
// Type?: string
|
||||
// }
|
||||
|
||||
function parseCsvLine(line: string): string[] {
|
||||
const result: string[] = []
|
||||
let current = ''
|
||||
let inQuotes = false
|
||||
// function parseCsvLine(line: string): string[] {
|
||||
// const result: string[] = []
|
||||
// let current = ''
|
||||
// let inQuotes = false
|
||||
|
||||
for (let index = 0; index < line.length; index++) {
|
||||
const char = line[index]
|
||||
// for (let index = 0; index < line.length; index++) {
|
||||
// const char = line[index]
|
||||
|
||||
if (char === '"') {
|
||||
if (inQuotes && line[index + 1] === '"') {
|
||||
current += '"'
|
||||
index++
|
||||
} else {
|
||||
inQuotes = !inQuotes
|
||||
}
|
||||
continue
|
||||
}
|
||||
// if (char === '"') {
|
||||
// if (inQuotes && line[index + 1] === '"') {
|
||||
// current += '"'
|
||||
// index++
|
||||
// } else {
|
||||
// inQuotes = !inQuotes
|
||||
// }
|
||||
// continue
|
||||
// }
|
||||
|
||||
if (char === ',' && !inQuotes) {
|
||||
result.push(current)
|
||||
current = ''
|
||||
continue
|
||||
}
|
||||
// if (char === ',' && !inQuotes) {
|
||||
// result.push(current)
|
||||
// current = ''
|
||||
// continue
|
||||
// }
|
||||
|
||||
current += char
|
||||
}
|
||||
// current += char
|
||||
// }
|
||||
|
||||
result.push(current)
|
||||
return result.map(value => value.trim())
|
||||
}
|
||||
// result.push(current)
|
||||
// return result.map(value => value.trim())
|
||||
// }
|
||||
|
||||
function parseCsv(content: string): CsvRow[] {
|
||||
const lines = content
|
||||
.split(/\r?\n/)
|
||||
.map(line => line.trim())
|
||||
.filter(Boolean)
|
||||
// function parseCsv(content: string): CsvRow[] {
|
||||
// const lines = content
|
||||
// .split(/\r?\n/)
|
||||
// .map(line => line.trim())
|
||||
// .filter(Boolean)
|
||||
|
||||
if (!lines.length) return []
|
||||
// if (!lines.length) return []
|
||||
|
||||
const headers = parseCsvLine(lines[0])
|
||||
return lines.slice(1).map(line => {
|
||||
const cols = parseCsvLine(line)
|
||||
const row: Record<string, string> = {}
|
||||
for (let index = 0; index < headers.length; index++) {
|
||||
row[headers[index]] = cols[index] || ''
|
||||
}
|
||||
return row
|
||||
})
|
||||
}
|
||||
// const headers = parseCsvLine(lines[0])
|
||||
// return lines.slice(1).map(line => {
|
||||
// const cols = parseCsvLine(line)
|
||||
// const row: Record<string, string> = {}
|
||||
// for (let index = 0; index < headers.length; index++) {
|
||||
// row[headers[index]] = cols[index] || ''
|
||||
// }
|
||||
// return row
|
||||
// })
|
||||
// }
|
||||
|
||||
function toBooleanFlags(typeValue: string) {
|
||||
const normalized = typeValue || ''
|
||||
const isPublic = normalized.includes('شناسه عمومی')
|
||||
const isImported = normalized.includes('وارداتی')
|
||||
const isDomestic = !isImported
|
||||
// function toBooleanFlags(typeValue: string) {
|
||||
// const normalized = typeValue || ''
|
||||
// const isPublic = normalized.includes('شناسه عمومی')
|
||||
// const isImported = normalized.includes('وارداتی')
|
||||
// const isDomestic = !isImported
|
||||
|
||||
return { isPublic, isDomestic }
|
||||
}
|
||||
// return { isPublic, isDomestic }
|
||||
// }
|
||||
|
||||
function parseVat(vatValue: string) {
|
||||
const parsed = Number(vatValue || '0')
|
||||
if (!Number.isFinite(parsed)) return 0
|
||||
return parsed
|
||||
}
|
||||
// function parseVat(vatValue: string) {
|
||||
// const parsed = Number(vatValue || '0')
|
||||
// if (!Number.isFinite(parsed)) return 0
|
||||
// return parsed
|
||||
// }
|
||||
|
||||
async function main() {
|
||||
const defaultPath =
|
||||
'/Users/ahasani/Desktop/product_good_2026-05-01T11-35-57_part_1_28812448-0dd9-411c-99e1-334c28d781fe.csv'
|
||||
const csvPath = process.argv[2] || defaultPath
|
||||
const absolutePath = path.resolve(csvPath)
|
||||
// async function main() {
|
||||
// const defaultPath =
|
||||
// '/Users/ahasani/Desktop/product_good_2026-05-01T11-35-57_part_1_28812448-0dd9-411c-99e1-334c28d781fe.csv'
|
||||
// const csvPath = process.argv[2] || defaultPath
|
||||
// const absolutePath = path.resolve(csvPath)
|
||||
|
||||
if (!fs.existsSync(absolutePath)) {
|
||||
throw new Error(`CSV file not found: ${absolutePath}`)
|
||||
}
|
||||
// if (!fs.existsSync(absolutePath)) {
|
||||
// throw new Error(`CSV file not found: ${absolutePath}`)
|
||||
// }
|
||||
|
||||
const raw = fs.readFileSync(absolutePath, 'utf8').replace(/^\uFEFF/, '')
|
||||
const rows = parseCsv(raw)
|
||||
// const raw = fs.readFileSync(absolutePath, 'utf8').replace(/^\uFEFF/, '')
|
||||
// const rows = parseCsv(raw)
|
||||
|
||||
let upserted = 0
|
||||
let skipped = 0
|
||||
// let upserted = 0
|
||||
// let skipped = 0
|
||||
|
||||
const guild = await prisma.guild.findFirst({})
|
||||
// const guild = await prisma.guild.findFirst({})
|
||||
|
||||
for (const row of rows) {
|
||||
const code = (row.ID || '').trim()
|
||||
const name = (row.DescriptionOfID || '').trim()
|
||||
const vat = parseVat((row.Vat || '').trim())
|
||||
const type = (row.Type || '').trim()
|
||||
const { isPublic, isDomestic } = toBooleanFlags(type)
|
||||
// for (const row of rows) {
|
||||
// const code = (row.ID || '').trim()
|
||||
// const name = (row.DescriptionOfID || '').trim()
|
||||
// const vat = parseVat((row.Vat || '').trim())
|
||||
// const type = (row.Type || '').trim()
|
||||
// const { isPublic, isDomestic } = toBooleanFlags(type)
|
||||
|
||||
if (!code || !name) {
|
||||
skipped++
|
||||
continue
|
||||
}
|
||||
// if (!code || !name) {
|
||||
// skipped++
|
||||
// continue
|
||||
// }
|
||||
|
||||
await prisma.stockKeepingUnits.upsert({
|
||||
where: { code },
|
||||
create: {
|
||||
code,
|
||||
name,
|
||||
VAT: vat,
|
||||
guild: {
|
||||
connect: {
|
||||
id: guild?.id,
|
||||
},
|
||||
},
|
||||
is_public: isPublic,
|
||||
is_domestic: isDomestic,
|
||||
},
|
||||
update: {
|
||||
name,
|
||||
VAT: vat,
|
||||
guild: {
|
||||
connect: {
|
||||
id: guild?.id,
|
||||
},
|
||||
},
|
||||
is_public: isPublic,
|
||||
is_domestic: isDomestic,
|
||||
},
|
||||
})
|
||||
upserted++
|
||||
}
|
||||
}
|
||||
// await prisma.stockKeepingUnits.upsert({
|
||||
// where: { code },
|
||||
// create: {
|
||||
// code,
|
||||
// name,
|
||||
// VAT: vat,
|
||||
// guild: {
|
||||
// connect: {
|
||||
// id: guild?.id,
|
||||
// },
|
||||
// },
|
||||
// is_public: isPublic,
|
||||
// is_domestic: isDomestic,
|
||||
// },
|
||||
// update: {
|
||||
// name,
|
||||
// VAT: vat,
|
||||
// guild: {
|
||||
// connect: {
|
||||
// id: guild?.id,
|
||||
// },
|
||||
// },
|
||||
// is_public: isPublic,
|
||||
// is_domestic: isDomestic,
|
||||
// },
|
||||
// })
|
||||
// upserted++
|
||||
// }
|
||||
// }
|
||||
|
||||
main()
|
||||
.catch(error => {
|
||||
console.error(error)
|
||||
process.exit(1)
|
||||
})
|
||||
.finally(async () => {
|
||||
await prisma.$disconnect()
|
||||
})
|
||||
// main()
|
||||
// .catch(error => {
|
||||
// console.error(error)
|
||||
// process.exit(1)
|
||||
// })
|
||||
// .finally(async () => {
|
||||
// await prisma.$disconnect()
|
||||
// })
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import { TspProviderResponseStatus } from '@/generated/prisma/enums'
|
||||
import {
|
||||
InvoiceSettlementType,
|
||||
TspProviderRequestType,
|
||||
TspProviderResponseStatus,
|
||||
} from '@/generated/prisma/enums'
|
||||
|
||||
export default {
|
||||
PaymentMethodType: {
|
||||
@@ -144,11 +148,16 @@ export default {
|
||||
[TspProviderResponseStatus.FISCAL_QUEUED]: 'در انتظار تایید سازمان',
|
||||
[TspProviderResponseStatus.SEND_FAILURE]: 'خطا در ارسال',
|
||||
},
|
||||
InvoiceSettlementType: {
|
||||
[InvoiceSettlementType.CASH]: 'نقدی',
|
||||
[InvoiceSettlementType.CREDIT]: 'نسیه',
|
||||
[InvoiceSettlementType.MIXED]: 'نقدی / نسیه',
|
||||
},
|
||||
TspProviderRequestType: {
|
||||
ORIGINAL: 'اصلی',
|
||||
CORRECTION: 'اصلاح',
|
||||
REVOKE: 'ابطال',
|
||||
REMOVE: 'حذف',
|
||||
[TspProviderRequestType.ORIGINAL]: 'اصلی',
|
||||
[TspProviderRequestType.CORRECTION]: 'اصلاح',
|
||||
[TspProviderRequestType.REVOKE]: 'ابطال',
|
||||
[TspProviderRequestType.RETURN]: 'برگشت از فروش',
|
||||
},
|
||||
TspProviderCustomerType: {
|
||||
Unknown: 'ناشناس',
|
||||
|
||||
@@ -24,9 +24,10 @@ export const summarySelect: BusinessActivitySelect = {
|
||||
select: {
|
||||
activation: {
|
||||
select: {
|
||||
_count: {
|
||||
account_allocations: {
|
||||
select: {
|
||||
account_allocations: true,
|
||||
id: true,
|
||||
account_id: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -44,13 +45,18 @@ export const select: BusinessActivitySelect = {
|
||||
export const mappedData = (businessActivity: any) => {
|
||||
const { license_activation, ...rest } = businessActivity
|
||||
const { license, ...license_activation_rest } = license_activation
|
||||
const { _count } = license.activation
|
||||
const { account_allocations } = license.activation
|
||||
|
||||
console.log('license_activation', license_activation)
|
||||
|
||||
return {
|
||||
...rest,
|
||||
license_info: {
|
||||
...license_activation_rest,
|
||||
accounts_limit: _count.account_allocations,
|
||||
accounts_limit: account_allocations.length,
|
||||
allocated_account_count: account_allocations.filter(
|
||||
allocation => allocation.account_id,
|
||||
).length,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,10 @@ export const summarySelect: SalesInvoiceSelect = {
|
||||
type: true,
|
||||
notes: true,
|
||||
created_at: true,
|
||||
settlement_type: true,
|
||||
unknown_customer: true,
|
||||
last_attempt_no: true,
|
||||
last_tsp_status: true,
|
||||
customer: {
|
||||
select: {
|
||||
type: true,
|
||||
@@ -20,6 +24,8 @@ export const summarySelect: SalesInvoiceSelect = {
|
||||
last_name: true,
|
||||
mobile_number: true,
|
||||
national_id: true,
|
||||
economic_code: true,
|
||||
postal_code: true,
|
||||
},
|
||||
},
|
||||
legal: {
|
||||
@@ -27,22 +33,18 @@ export const summarySelect: SalesInvoiceSelect = {
|
||||
name: true,
|
||||
economic_code: true,
|
||||
registration_number: true,
|
||||
postal_code: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
tsp_attempts: {
|
||||
orderBy: {
|
||||
created_at: 'desc',
|
||||
},
|
||||
take: 1,
|
||||
reference_invoice: {
|
||||
select: {
|
||||
status: true,
|
||||
sent_at: true,
|
||||
message: true,
|
||||
id: true,
|
||||
invoice_number: true,
|
||||
},
|
||||
},
|
||||
reference_invoice: {
|
||||
referenced_by: {
|
||||
select: {
|
||||
id: true,
|
||||
invoice_number: true,
|
||||
@@ -56,6 +58,7 @@ export const select: SalesInvoiceSelect = {
|
||||
tax_amount: true,
|
||||
updated_at: true,
|
||||
unknown_customer: true,
|
||||
|
||||
pos: {
|
||||
select: {
|
||||
id: true,
|
||||
@@ -68,6 +71,12 @@ export const select: SalesInvoiceSelect = {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
economic_code: true,
|
||||
guild: {
|
||||
select: {
|
||||
name: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -122,19 +131,4 @@ export const select: SalesInvoiceSelect = {
|
||||
},
|
||||
},
|
||||
},
|
||||
tsp_attempts: {
|
||||
orderBy: {
|
||||
created_at: 'desc',
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
attempt_no: true,
|
||||
status: true,
|
||||
message: true,
|
||||
sent_at: true,
|
||||
received_at: true,
|
||||
created_at: true,
|
||||
},
|
||||
take: 1,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ export class SharedSaleInvoiceAccessService {
|
||||
})
|
||||
|
||||
if (!consumer) {
|
||||
throw new BadRequestException('شما دسترسی لازم برای ارسال فاکتور را ندارید.')
|
||||
throw new BadRequestException('شما دسترسی لازم برای ارسال صورتحساب را ندارید.')
|
||||
}
|
||||
|
||||
return consumer.consumer_id
|
||||
|
||||
@@ -1,12 +1,25 @@
|
||||
import { SharedSaleInvoiceAccessService } from '@/common/services/saleInvoices/sale-invoice-access.service'
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import {
|
||||
PosCorrectionSalesInvoiceDto,
|
||||
PosReturnSalesInvoiceDto,
|
||||
} from '@/modules/pos/sales-invoices/dto/create-sales-invoice.dto'
|
||||
import { SalesInvoiceTspService } from '@/modules/tspProviders/sales-invoice-tsp.service'
|
||||
import { PrismaService } from '@/prisma/prisma.service'
|
||||
import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common'
|
||||
import {
|
||||
CustomerType,
|
||||
TspProviderRequestType,
|
||||
TspProviderResponseStatus,
|
||||
} from 'generated/prisma/enums'
|
||||
import { SharedSaleInvoiceCreateService } from './sale-invoice-create.service'
|
||||
|
||||
@Injectable()
|
||||
export class SharedSaleInvoiceActionsService {
|
||||
constructor(
|
||||
private prisma: PrismaService,
|
||||
private readonly salesInvoiceTspService: SalesInvoiceTspService,
|
||||
private readonly saleInvoiceAccessService: SharedSaleInvoiceAccessService,
|
||||
private sharedSaleInvoiceCreateService: SharedSaleInvoiceCreateService,
|
||||
) {}
|
||||
|
||||
async send(consumerAccountId: string, posId: string, invoiceId: string) {
|
||||
@@ -45,6 +58,478 @@ export class SharedSaleInvoiceActionsService {
|
||||
)
|
||||
}
|
||||
|
||||
async correction(
|
||||
data: PosCorrectionSalesInvoiceDto,
|
||||
consumerAccountId: string,
|
||||
posId: string,
|
||||
complexId: string,
|
||||
businessId: string,
|
||||
invoiceId: string,
|
||||
) {
|
||||
await this.saleInvoiceAccessService.getConsumerIdWithPosAccess(
|
||||
consumerAccountId,
|
||||
posId,
|
||||
)
|
||||
|
||||
const newInvoice = await this.prisma.$transaction(async tx => {
|
||||
const relatedInvoice = await tx.salesInvoice.findUnique({
|
||||
where: {
|
||||
id: invoiceId,
|
||||
pos_id: posId,
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
invoice_date: true,
|
||||
settlement_type: true,
|
||||
customer_id: true,
|
||||
main_id: true,
|
||||
last_tsp_status: true,
|
||||
referenced_by: {
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
},
|
||||
customer: {
|
||||
select: {
|
||||
type: true,
|
||||
},
|
||||
},
|
||||
total_amount: true,
|
||||
items: {
|
||||
select: {
|
||||
id: true,
|
||||
good_id: true,
|
||||
service_id: true,
|
||||
quantity: true,
|
||||
unit_price: true,
|
||||
total_amount: true,
|
||||
discount_amount: true,
|
||||
tax_amount: true,
|
||||
payload: true,
|
||||
notes: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
if (!relatedInvoice) {
|
||||
throw new NotFoundException('صورتحساب مورد نظر شما یافت نشد.')
|
||||
}
|
||||
|
||||
if (relatedInvoice.last_tsp_status !== TspProviderResponseStatus.SUCCESS) {
|
||||
throw new BadRequestException('امکان اصلاح این صورتحساب وجود ندارد.')
|
||||
}
|
||||
|
||||
if (relatedInvoice.referenced_by) {
|
||||
throw new BadRequestException(
|
||||
'این صورتحساب قبلا با یک صورتحساب دیگر جایگزین شده است.',
|
||||
)
|
||||
}
|
||||
|
||||
const normalizedInvoiceDate = this.normalizeInvoiceDate(data.invoice_date)
|
||||
const originalInvoiceDate = this.normalizeInvoiceDate(relatedInvoice.invoice_date)
|
||||
|
||||
const originalItemsByKey = new Map(
|
||||
relatedInvoice.items.map(item => [this.getItemKey(item), item]),
|
||||
)
|
||||
|
||||
const usedItemKeys = new Set<string>()
|
||||
const normalizedItems = data.items.map(item => {
|
||||
const itemKey = this.getItemKey(item)
|
||||
|
||||
if (!itemKey) {
|
||||
throw new BadRequestException('هر قلم باید شناسه کالا یا خدمت داشته باشد.')
|
||||
}
|
||||
|
||||
usedItemKeys.add(itemKey)
|
||||
|
||||
const originalItem = originalItemsByKey.get(itemKey)
|
||||
|
||||
if (!originalItem) {
|
||||
throw new BadRequestException(
|
||||
'فقط اقلام موجود در صورتحساب اصلی قابل اصلاح هستند.',
|
||||
)
|
||||
}
|
||||
|
||||
const originalQuantity = Number(originalItem.quantity)
|
||||
const requestedQuantity = Number(item.quantity)
|
||||
const originalUnitPrice = Number(originalItem.unit_price)
|
||||
const requestedUnitPrice = Number(item.unit_price)
|
||||
const originalTotalAmount = this.roundAmount(Number(originalItem.total_amount))
|
||||
const requestedTotalAmount = this.roundAmount(Number(item.total_amount))
|
||||
|
||||
if (requestedQuantity <= 0) {
|
||||
throw new BadRequestException(
|
||||
'تعداد/مقدار اقلام اصلاحی باید بیشتر از صفر باشد.',
|
||||
)
|
||||
}
|
||||
|
||||
// if (requestedUnitPrice < originalUnitPrice) {
|
||||
// throw new BadRequestException(
|
||||
// 'مبلغ واحد اقلام اصلاحی نمیتواند کمتر از صورتحساب اصلی باشد.',
|
||||
// )
|
||||
// }
|
||||
|
||||
return {
|
||||
invoice_id: originalItem.id,
|
||||
good_id: originalItem.good_id,
|
||||
service_id: originalItem.service_id || undefined,
|
||||
quantity: requestedQuantity,
|
||||
unit_price: requestedUnitPrice,
|
||||
total_amount: requestedTotalAmount,
|
||||
discount_amount: this.roundAmount(Number(item.discount_amount || 0)),
|
||||
tax_amount: this.roundAmount(Number(item.tax_amount || 0)),
|
||||
payload: item.payload ? JSON.parse(JSON.stringify(item.payload)) : undefined,
|
||||
notes: item.notes || undefined,
|
||||
}
|
||||
})
|
||||
|
||||
if (usedItemKeys.size !== relatedInvoice.items.length) {
|
||||
throw new BadRequestException(
|
||||
'فقط اقلام موجود در صورتحساب اصلی قابل اصلاح هستند.',
|
||||
)
|
||||
}
|
||||
|
||||
const hasChangedQuantity = normalizedItems.some(item => {
|
||||
const originalItem = relatedInvoice.items.find(
|
||||
relatedItem => this.getItemKey(relatedItem) === this.getItemKey(item),
|
||||
)
|
||||
|
||||
if (!originalItem) {
|
||||
return false
|
||||
}
|
||||
|
||||
return Number(originalItem.quantity) !== Number(item.quantity)
|
||||
})
|
||||
const hasChangedAmount = normalizedItems.some(item => {
|
||||
const originalItem = relatedInvoice.items.find(
|
||||
relatedItem => this.getItemKey(relatedItem) === this.getItemKey(item),
|
||||
)
|
||||
|
||||
if (!originalItem) {
|
||||
return false
|
||||
}
|
||||
|
||||
return (
|
||||
this.roundAmount(Number(originalItem.total_amount)) !==
|
||||
this.roundAmount(Number(item.total_amount))
|
||||
)
|
||||
})
|
||||
const hasChangedInvoiceDate = normalizedInvoiceDate !== originalInvoiceDate
|
||||
|
||||
if (!hasChangedQuantity && !hasChangedAmount && !hasChangedInvoiceDate) {
|
||||
throw new BadRequestException('مقداری تغییر نکرده است.')
|
||||
}
|
||||
|
||||
const requestedTotalAmount = this.roundAmount(Number(data.total_amount))
|
||||
const originalTotalAmount = this.roundAmount(Number(relatedInvoice.total_amount))
|
||||
const totalDiff = this.roundAmount(requestedTotalAmount - originalTotalAmount)
|
||||
const paymentsAmount = this.roundAmount(this.getPaymentsAmount(data.payments))
|
||||
|
||||
if (totalDiff > 0 && paymentsAmount !== totalDiff) {
|
||||
throw new BadRequestException(
|
||||
'جمع پرداختی باید برابر با اختلاف مبلغ صورتحساب اصلاحی و صورتحساب مرجع باشد.',
|
||||
)
|
||||
}
|
||||
|
||||
if (totalDiff === 0 && paymentsAmount !== 0) {
|
||||
throw new BadRequestException('در صورت عدم افزایش مبلغ، پرداختی نباید ثبت شود.')
|
||||
}
|
||||
|
||||
const newInvoice = await this.sharedSaleInvoiceCreateService.create({
|
||||
tx,
|
||||
data: {
|
||||
invoice_date: new Date(normalizedInvoiceDate),
|
||||
items: normalizedItems as any,
|
||||
total_amount: requestedTotalAmount,
|
||||
discount_amount: this.roundAmount(Number(data.discount_amount)),
|
||||
tax_amount: this.roundAmount(Number(data.tax_amount)),
|
||||
customer_id: relatedInvoice.customer_id || undefined,
|
||||
customer_type: relatedInvoice.customer?.type || CustomerType.UNKNOWN,
|
||||
settlement_type: relatedInvoice.settlement_type,
|
||||
payments: data.payments,
|
||||
} as any,
|
||||
businessId,
|
||||
complexId,
|
||||
posId,
|
||||
consumerAccountId,
|
||||
main_invoice_id: relatedInvoice.main_id || relatedInvoice.id,
|
||||
ref_invoice_id: relatedInvoice.id,
|
||||
type: TspProviderRequestType.CORRECTION,
|
||||
})
|
||||
|
||||
await tx.salesInvoice.update({
|
||||
where: {
|
||||
id: relatedInvoice.id,
|
||||
},
|
||||
data: {
|
||||
referenced_by: {
|
||||
connect: {
|
||||
id: newInvoice.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
return newInvoice
|
||||
})
|
||||
|
||||
return this.salesInvoiceTspService.correctionSend(posId, newInvoice.id)
|
||||
}
|
||||
|
||||
async return(
|
||||
data: PosReturnSalesInvoiceDto,
|
||||
consumerAccountId: string,
|
||||
pos_id: string,
|
||||
complex_id: string,
|
||||
business_id: string,
|
||||
invoiceId: string,
|
||||
) {
|
||||
await this.saleInvoiceAccessService.getConsumerIdWithPosAccess(
|
||||
consumerAccountId,
|
||||
pos_id,
|
||||
)
|
||||
|
||||
const newInvoice = await this.prisma.$transaction(async tx => {
|
||||
const relatedInvoice = await tx.salesInvoice.findUnique({
|
||||
where: {
|
||||
id: invoiceId,
|
||||
pos_id,
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
type: true,
|
||||
invoice_date: true,
|
||||
settlement_type: true,
|
||||
customer_id: true,
|
||||
main_id: true,
|
||||
last_tsp_status: true,
|
||||
referenced_by: {
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
},
|
||||
customer: {
|
||||
select: {
|
||||
type: true,
|
||||
},
|
||||
},
|
||||
items: {
|
||||
select: {
|
||||
id: true,
|
||||
good_id: true,
|
||||
service_id: true,
|
||||
quantity: true,
|
||||
unit_price: true,
|
||||
total_amount: true,
|
||||
discount_amount: true,
|
||||
tax_amount: true,
|
||||
payload: true,
|
||||
notes: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
if (!relatedInvoice) {
|
||||
throw new NotFoundException('صورتحساب مورد نظر شما یافت نشد.')
|
||||
}
|
||||
|
||||
if (relatedInvoice.last_tsp_status !== TspProviderResponseStatus.SUCCESS) {
|
||||
throw new BadRequestException('امکان برگشت از خرید روی این صورتحساب وجود ندارد.')
|
||||
}
|
||||
|
||||
if (relatedInvoice.referenced_by) {
|
||||
throw new BadRequestException(
|
||||
'این صورتحساب قبلا با یک صورتحساب دیگر جایگزین شده است.',
|
||||
)
|
||||
}
|
||||
|
||||
const normalizedInvoiceDate = this.normalizeInvoiceDate(data.invoice_date)
|
||||
const originalInvoiceDate = this.normalizeInvoiceDate(relatedInvoice.invoice_date)
|
||||
|
||||
const originalItemsByKey = new Map(
|
||||
relatedInvoice.items.map(item => [this.getReturnItemKey(item), item]),
|
||||
)
|
||||
|
||||
const usedItemKeys = new Set<string>()
|
||||
const normalizedItems = data.items.map(item => {
|
||||
const itemKey = this.getReturnItemKey(item)
|
||||
|
||||
if (!itemKey) {
|
||||
throw new BadRequestException('هر قلم باید شناسه کالا یا خدمت داشته باشد.')
|
||||
}
|
||||
|
||||
// if (usedItemKeys.has(itemKey)) {
|
||||
// throw new BadRequestException('اقلام تکراری در صورتحساب بازگشتی مجاز نیستند.')
|
||||
// }
|
||||
|
||||
usedItemKeys.add(itemKey)
|
||||
|
||||
const originalItem = originalItemsByKey.get(itemKey)
|
||||
|
||||
if (!originalItem) {
|
||||
throw new BadRequestException(
|
||||
'فقط اقلام موجود در صورتحساب اصلی قابل بازگشت هستند.',
|
||||
)
|
||||
}
|
||||
|
||||
const originalQuantity = Number(originalItem.quantity)
|
||||
const requestedQuantity = Number(item.quantity)
|
||||
|
||||
if (requestedQuantity <= 0) {
|
||||
throw new BadRequestException(
|
||||
'تعداد/مقدار اقلام بازگشتی باید بیشتر از صفر باشد.',
|
||||
)
|
||||
}
|
||||
|
||||
if (requestedQuantity > originalQuantity) {
|
||||
throw new BadRequestException(
|
||||
'تعداد/مقدار اقلام بازگشتی نمیتواند از مقدار صورتحساب اصلی بیشتر باشد.',
|
||||
)
|
||||
}
|
||||
|
||||
const quantityRatio = requestedQuantity / originalQuantity
|
||||
|
||||
return {
|
||||
invoice_id: originalItem.id,
|
||||
good_id: originalItem.good_id,
|
||||
service_id: originalItem.service_id || undefined,
|
||||
quantity: requestedQuantity,
|
||||
unit_price: Number(originalItem.unit_price),
|
||||
total_amount: this.roundAmount(
|
||||
Number(originalItem.total_amount) * quantityRatio,
|
||||
),
|
||||
discount_amount: this.roundAmount(
|
||||
Number(originalItem.discount_amount || 0) * quantityRatio,
|
||||
),
|
||||
tax_amount: this.roundAmount(
|
||||
Number(originalItem.tax_amount || 0) * quantityRatio,
|
||||
),
|
||||
payload: originalItem.payload
|
||||
? JSON.parse(JSON.stringify(originalItem.payload))
|
||||
: undefined,
|
||||
notes: originalItem.notes || undefined,
|
||||
}
|
||||
})
|
||||
|
||||
if (!normalizedItems.length) {
|
||||
throw new BadRequestException(
|
||||
'حداقل یک قلم باید در صورتحساب بازگشتی باقی بماند.',
|
||||
)
|
||||
}
|
||||
|
||||
const hasRemovedItem = relatedInvoice.items.some(
|
||||
item => !usedItemKeys.has(this.getReturnItemKey(item)),
|
||||
)
|
||||
const hasChangedQuantity = normalizedItems.some(item => {
|
||||
const originalItem = relatedInvoice.items.find(
|
||||
relatedItem =>
|
||||
this.getReturnItemKey(relatedItem) === this.getReturnItemKey(item),
|
||||
)
|
||||
|
||||
if (!originalItem) {
|
||||
return false
|
||||
}
|
||||
|
||||
return Number(originalItem.quantity) !== Number(item.quantity)
|
||||
})
|
||||
const hasChangedInvoiceDate = normalizedInvoiceDate !== originalInvoiceDate
|
||||
|
||||
if (!hasRemovedItem && !hasChangedQuantity && !hasChangedInvoiceDate) {
|
||||
throw new BadRequestException('مقداری تغییر نکرده است.')
|
||||
}
|
||||
|
||||
const totalAmount = normalizedItems.reduce(
|
||||
(sum, item) => sum + Number(item.total_amount),
|
||||
0,
|
||||
)
|
||||
const discountAmount = normalizedItems.reduce(
|
||||
(sum, item) => sum + Number(item.discount_amount || 0),
|
||||
0,
|
||||
)
|
||||
const taxAmount = normalizedItems.reduce(
|
||||
(sum, item) => sum + Number(item.tax_amount || 0),
|
||||
0,
|
||||
)
|
||||
|
||||
const newInvoice = await this.sharedSaleInvoiceCreateService.create({
|
||||
tx,
|
||||
data: {
|
||||
invoice_date: new Date(normalizedInvoiceDate),
|
||||
items: normalizedItems as any,
|
||||
total_amount: totalAmount,
|
||||
discount_amount: discountAmount,
|
||||
tax_amount: taxAmount,
|
||||
customer_id: relatedInvoice.customer_id || undefined,
|
||||
customer_type: relatedInvoice.customer?.type || CustomerType.UNKNOWN,
|
||||
settlement_type: relatedInvoice.settlement_type,
|
||||
payments: undefined,
|
||||
} as any,
|
||||
businessId: business_id,
|
||||
complexId: complex_id,
|
||||
posId: pos_id,
|
||||
consumerAccountId,
|
||||
main_invoice_id: relatedInvoice.main_id || relatedInvoice.id,
|
||||
ref_invoice_id: relatedInvoice.id,
|
||||
type: TspProviderRequestType.RETURN,
|
||||
})
|
||||
|
||||
await tx.salesInvoice.update({
|
||||
where: {
|
||||
id: relatedInvoice.id,
|
||||
},
|
||||
data: {
|
||||
referenced_by: {
|
||||
connect: {
|
||||
id: newInvoice.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
return newInvoice
|
||||
})
|
||||
|
||||
return this.salesInvoiceTspService.returnFromSaleSend(
|
||||
pos_id,
|
||||
business_id,
|
||||
newInvoice.id,
|
||||
)
|
||||
}
|
||||
|
||||
private normalizeInvoiceDate(invoiceDate: Date | string) {
|
||||
return new Date(invoiceDate).toISOString()
|
||||
}
|
||||
|
||||
private getItemKey(item: { good_id?: string | null; service_id?: string | null }) {
|
||||
return item.good_id || item.service_id || ''
|
||||
}
|
||||
|
||||
private getPaymentsAmount(payments?: {
|
||||
terminals?: { amount?: number }
|
||||
cash?: number
|
||||
set_off?: number
|
||||
card?: number
|
||||
bank?: number
|
||||
check?: number
|
||||
other?: number
|
||||
}) {
|
||||
return (
|
||||
Number(payments?.terminals?.amount || 0) +
|
||||
Number(payments?.cash || 0) +
|
||||
Number(payments?.set_off || 0) +
|
||||
Number(payments?.card || 0) +
|
||||
Number(payments?.bank || 0) +
|
||||
Number(payments?.check || 0) +
|
||||
Number(payments?.other || 0)
|
||||
)
|
||||
}
|
||||
|
||||
private roundAmount(amount: number) {
|
||||
return Number(amount.toFixed(2))
|
||||
}
|
||||
|
||||
async inquiry(consumerAccountId: string, posId: string, invoiceId: string) {
|
||||
const consumerId = await this.saleInvoiceAccessService.getConsumerIdWithPosAccess(
|
||||
consumerAccountId,
|
||||
@@ -52,4 +537,11 @@ export class SharedSaleInvoiceActionsService {
|
||||
)
|
||||
return this.salesInvoiceTspService.get(invoiceId, posId, consumerId)
|
||||
}
|
||||
|
||||
private getReturnItemKey(item: {
|
||||
good_id?: string | null
|
||||
service_id?: string | null
|
||||
}) {
|
||||
return item.good_id || item.service_id || ''
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { SaleInvoiceType } from '@/common/interfaces/sale-invoice-payload'
|
||||
import { ApiProperty } from '@nestjs/swagger'
|
||||
import { ApiProperty, OmitType } from '@nestjs/swagger'
|
||||
import { Type } from 'class-transformer'
|
||||
import {
|
||||
ArrayMinSize,
|
||||
@@ -83,7 +83,7 @@ export class SharedCreateTerminalPayment {
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
@ApiProperty({ required: true })
|
||||
terminalId: string
|
||||
terminal_id: string
|
||||
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
@@ -196,6 +196,11 @@ export class SharedCreateSalesInvoiceDto {
|
||||
@ValidateNested({ each: true })
|
||||
items: SharedCreateSalesInvoiceItemDto[]
|
||||
|
||||
@ApiProperty({ required: false })
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
ref_invoice_id?: string
|
||||
|
||||
@ApiProperty({ required: false })
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@@ -206,8 +211,6 @@ export class SharedCreateSalesInvoiceDto {
|
||||
@IsBoolean()
|
||||
send_to_tsp?: boolean
|
||||
|
||||
|
||||
|
||||
@ApiProperty({ required: true, default: CustomerType.UNKNOWN })
|
||||
@IsEnum(CustomerType)
|
||||
customer_type: CustomerType
|
||||
@@ -229,3 +232,16 @@ export class SharedCreateSalesInvoiceDto {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class SharedCorrectionSalesInvoiceDto extends OmitType(
|
||||
SharedCreateSalesInvoiceDto,
|
||||
['customer', 'customer_id', 'customer_type', 'settlement_type'],
|
||||
) {}
|
||||
|
||||
export class SharedReturnSalesInvoiceDto extends OmitType(SharedCreateSalesInvoiceDto, [
|
||||
'customer',
|
||||
'customer_id',
|
||||
'customer_type',
|
||||
'settlement_type',
|
||||
'payments',
|
||||
]) {}
|
||||
|
||||
@@ -23,6 +23,7 @@ interface TerminalPaymentInfo {
|
||||
interface NormalizedPayment {
|
||||
method: PaymentMethodType
|
||||
amount: number
|
||||
terminalInfo?: TerminalPaymentInfo
|
||||
}
|
||||
|
||||
interface CreateSharedSaleInvoiceInput {
|
||||
@@ -57,10 +58,10 @@ export class SharedSaleInvoiceCreateService {
|
||||
} = input
|
||||
|
||||
const normalizedInvoiceDate = this.normalizeInvoiceDate(data.invoice_date)
|
||||
const { payments, terminalInfo } = this.buildPaymentsData(
|
||||
data.payments,
|
||||
data.total_amount,
|
||||
)
|
||||
const payments =
|
||||
type === TspProviderRequestType.ORIGINAL || data.payments
|
||||
? this.buildPaymentsData(data.payments, data.total_amount)
|
||||
: []
|
||||
|
||||
for (let attempt = 1; attempt <= this.createInvoiceRetries; attempt++) {
|
||||
try {
|
||||
@@ -88,13 +89,14 @@ export class SharedSaleInvoiceCreateService {
|
||||
select: { ...QUERY_CONSTANTS.SALE_INVOICE.select },
|
||||
})
|
||||
|
||||
await this.createPayments(
|
||||
$tx,
|
||||
salesInvoice.id,
|
||||
payments,
|
||||
terminalInfo,
|
||||
normalizedInvoiceDate,
|
||||
)
|
||||
if (payments.length) {
|
||||
await this.createPayments(
|
||||
$tx,
|
||||
salesInvoice.id,
|
||||
payments,
|
||||
normalizedInvoiceDate,
|
||||
)
|
||||
}
|
||||
|
||||
return salesInvoice
|
||||
})
|
||||
@@ -109,7 +111,7 @@ export class SharedSaleInvoiceCreateService {
|
||||
}
|
||||
}
|
||||
|
||||
throw new BadRequestException('ایجاد فاکتور با خطا مواجه شد.')
|
||||
throw new BadRequestException('ایجاد صورتحساب با خطا مواجه شد.')
|
||||
}
|
||||
|
||||
private isRetryableInvoiceConflict(error: unknown) {
|
||||
@@ -148,7 +150,7 @@ export class SharedSaleInvoiceCreateService {
|
||||
}
|
||||
|
||||
const rawPayments = (paymentsData || {}) as Record<string, unknown>
|
||||
const terminalInfo = rawPayments.terminals as TerminalPaymentInfo | undefined
|
||||
const terminalPayments = rawPayments.terminals as TerminalPaymentInfo[] | undefined
|
||||
|
||||
const payments: NormalizedPayment[] = Object.entries(rawPayments)
|
||||
.filter(([key, value]) => key !== 'terminals' && value && Number(value) > 0)
|
||||
@@ -158,54 +160,31 @@ export class SharedSaleInvoiceCreateService {
|
||||
}))
|
||||
.filter(payment => payment.method && payment.amount > 0) as NormalizedPayment[]
|
||||
|
||||
const hasTerminalPayment = payments.some(
|
||||
payment => payment.method === PaymentMethodType.TERMINAL,
|
||||
)
|
||||
const nonTerminalTotal = payments
|
||||
.filter(payment => payment.method !== PaymentMethodType.TERMINAL)
|
||||
.reduce((sum, payment) => sum + payment.amount, 0)
|
||||
const hasTerminalPayment = terminalPayments && terminalPayments.length
|
||||
|
||||
if (!hasTerminalPayment && terminalInfo) {
|
||||
const terminalAmount =
|
||||
typeof terminalInfo.amount === 'number'
|
||||
? terminalInfo.amount
|
||||
: Math.max(0, Number(totalAmount) - nonTerminalTotal)
|
||||
|
||||
if (terminalAmount > 0) {
|
||||
if (hasTerminalPayment) {
|
||||
for (const terminal of terminalPayments) {
|
||||
payments.push({
|
||||
method: PaymentMethodType.TERMINAL,
|
||||
amount: terminalAmount,
|
||||
amount: terminal.amount,
|
||||
terminalInfo: terminal,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
this.validatePayments(payments, totalAmount, terminalInfo)
|
||||
//TODO: for correction i need to validate payments with diff of total amount and original invoice amount
|
||||
// this.validatePayments(payments, totalAmount)
|
||||
|
||||
return {
|
||||
payments,
|
||||
terminalInfo,
|
||||
}
|
||||
return payments
|
||||
}
|
||||
|
||||
private validatePayments(
|
||||
payments: NormalizedPayment[],
|
||||
totalAmount: number,
|
||||
terminalInfo?: TerminalPaymentInfo,
|
||||
) {
|
||||
private validatePayments(payments: NormalizedPayment[], totalAmount: number) {
|
||||
const totalPayments = payments.reduce((sum, payment) => sum + payment.amount, 0)
|
||||
const roundedTotalPayments = Number(totalPayments.toFixed(2))
|
||||
const roundedTotalAmount = Number(Number(totalAmount).toFixed(2))
|
||||
|
||||
if (roundedTotalPayments !== roundedTotalAmount) {
|
||||
throw new BadRequestException('مبلغ پرداختی باید برابر با مبلغ کل فاکتور باشد.')
|
||||
}
|
||||
|
||||
const terminalPayments = payments.filter(
|
||||
payment => payment.method === PaymentMethodType.TERMINAL,
|
||||
)
|
||||
|
||||
if (terminalPayments.length > 0 && !terminalInfo) {
|
||||
throw new BadRequestException('برای پرداخت ترمینال اطلاعات ترمینال الزامی است.')
|
||||
throw new BadRequestException('مبلغ پرداختی باید برابر با مبلغ کل صورتحساب باشد.')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,84 +193,124 @@ export class SharedSaleInvoiceCreateService {
|
||||
data: SharedCreateSalesInvoiceDto,
|
||||
businessId: string,
|
||||
) {
|
||||
if (data.customer_id) {
|
||||
return data.customer_id
|
||||
const { customer_id, customer_type, customer } = data
|
||||
|
||||
if (customer_id) {
|
||||
return customer_id
|
||||
}
|
||||
|
||||
if (
|
||||
data.customer_type === CustomerType.INDIVIDUAL &&
|
||||
data.customer?.customer_individual
|
||||
) {
|
||||
const { national_id, mobile_number, ...rest } = data.customer.customer_individual
|
||||
if (customer_type === CustomerType.INDIVIDUAL && customer?.customer_individual) {
|
||||
const { national_id, postal_code, economic_code, ...rest } =
|
||||
customer.customer_individual
|
||||
|
||||
const customerIndividual = await tx.customerIndividual.upsert({
|
||||
const foundedCustomer = await tx.customerIndividual.findFirst({
|
||||
where: {
|
||||
business_activity_id_national_id: {
|
||||
business_activity_id: businessId,
|
||||
national_id: data.customer.customer_individual.national_id,
|
||||
},
|
||||
},
|
||||
create: {
|
||||
...data.customer.customer_individual,
|
||||
customer: {
|
||||
create: {
|
||||
type: CustomerType.INDIVIDUAL,
|
||||
business_activity_id: businessId,
|
||||
OR: [
|
||||
{
|
||||
economic_code,
|
||||
},
|
||||
},
|
||||
business_activity: {
|
||||
connect: {
|
||||
id: businessId,
|
||||
{
|
||||
postal_code,
|
||||
national_id,
|
||||
},
|
||||
},
|
||||
},
|
||||
update: { ...rest },
|
||||
select: {
|
||||
customer_id: true,
|
||||
},
|
||||
})
|
||||
|
||||
if (!customerIndividual) {
|
||||
throw new BadRequestException('متاسفانه مشکلی در اطلاعات مشتری وجود دارد.')
|
||||
}
|
||||
|
||||
return customerIndividual.customer_id
|
||||
}
|
||||
|
||||
if (data.customer_type === CustomerType.LEGAL && data.customer?.customer_legal) {
|
||||
const { registration_number, ...rest } = data.customer.customer_legal
|
||||
const customerLegal = await tx.customerLegal.upsert({
|
||||
where: {
|
||||
business_activity_id_economic_code: {
|
||||
business_activity_id: businessId,
|
||||
economic_code: data.customer.customer_legal.economic_code,
|
||||
},
|
||||
},
|
||||
create: {
|
||||
...data.customer.customer_legal,
|
||||
customer: {
|
||||
create: {
|
||||
type: CustomerType.LEGAL,
|
||||
},
|
||||
},
|
||||
business_activity: {
|
||||
connect: {
|
||||
id: businessId,
|
||||
},
|
||||
},
|
||||
},
|
||||
update: {
|
||||
...rest,
|
||||
],
|
||||
},
|
||||
select: {
|
||||
customer_id: true,
|
||||
},
|
||||
})
|
||||
let customerIndividualId: string | undefined = foundedCustomer?.customer_id
|
||||
|
||||
if (!customerLegal) {
|
||||
if (foundedCustomer) {
|
||||
await tx.customerIndividual.update({
|
||||
where: {
|
||||
customer_id: foundedCustomer.customer_id,
|
||||
},
|
||||
data: {
|
||||
...customer.customer_individual,
|
||||
},
|
||||
})
|
||||
} else {
|
||||
const createdCustomer = await tx.customerIndividual.create({
|
||||
data: {
|
||||
...customer.customer_individual,
|
||||
customer: {
|
||||
create: {
|
||||
type: CustomerType.INDIVIDUAL,
|
||||
},
|
||||
},
|
||||
business_activity: {
|
||||
connect: {
|
||||
id: businessId,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
customerIndividualId = createdCustomer.customer_id
|
||||
}
|
||||
|
||||
if (!customerIndividualId) {
|
||||
throw new BadRequestException('متاسفانه مشکلی در اطلاعات مشتری وجود دارد.')
|
||||
}
|
||||
|
||||
return customerLegal.customer_id
|
||||
return customerIndividualId
|
||||
} else if (customer_type === CustomerType.LEGAL && customer?.customer_legal) {
|
||||
const { registration_number, economic_code, postal_code } = customer.customer_legal
|
||||
const foundedCustomer = await tx.customerLegal.findFirst({
|
||||
where: {
|
||||
business_activity_id: businessId,
|
||||
OR: [
|
||||
{
|
||||
economic_code,
|
||||
},
|
||||
{
|
||||
postal_code,
|
||||
registration_number,
|
||||
},
|
||||
],
|
||||
},
|
||||
select: {
|
||||
customer_id: true,
|
||||
},
|
||||
})
|
||||
let customerLegalId: string | undefined = foundedCustomer?.customer_id
|
||||
|
||||
if (foundedCustomer) {
|
||||
await tx.customerLegal.update({
|
||||
where: {
|
||||
customer_id: foundedCustomer.customer_id,
|
||||
},
|
||||
data: {
|
||||
...customer.customer_legal,
|
||||
},
|
||||
})
|
||||
} else {
|
||||
const createdCustomer = await tx.customerLegal.create({
|
||||
data: {
|
||||
...customer.customer_legal,
|
||||
customer: {
|
||||
create: {
|
||||
type: CustomerType.LEGAL,
|
||||
},
|
||||
},
|
||||
business_activity: {
|
||||
connect: {
|
||||
id: businessId,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
customerLegalId = createdCustomer.customer_id
|
||||
}
|
||||
|
||||
if (!customerLegalId) {
|
||||
throw new BadRequestException('متاسفانه مشکلی در اطلاعات مشتری وجود دارد.')
|
||||
}
|
||||
|
||||
return customerLegalId
|
||||
}
|
||||
|
||||
return null
|
||||
@@ -382,6 +401,7 @@ export class SharedSaleInvoiceCreateService {
|
||||
customer,
|
||||
payments,
|
||||
settlement_type,
|
||||
send_to_tsp,
|
||||
...invoiceData
|
||||
} = data
|
||||
|
||||
@@ -389,7 +409,7 @@ export class SharedSaleInvoiceCreateService {
|
||||
type !== TspProviderRequestType.ORIGINAL &&
|
||||
!(main_invoice_id || ref_invoice_id)
|
||||
) {
|
||||
throw new BadRequestException('متاسفانه مشکلی در اطلاعات فاکتور وجود دارد.')
|
||||
throw new BadRequestException('متاسفانه مشکلی در اطلاعات صورتحساب وجود دارد.')
|
||||
}
|
||||
|
||||
const salesInvoiceData: SalesInvoiceCreateInput = {
|
||||
@@ -444,6 +464,8 @@ export class SharedSaleInvoiceCreateService {
|
||||
id: customerId,
|
||||
},
|
||||
}
|
||||
} else if (data.customer?.customer_unknown) {
|
||||
salesInvoiceData.unknown_customer = data.customer.customer_unknown
|
||||
}
|
||||
|
||||
if (type !== TspProviderRequestType.ORIGINAL) {
|
||||
@@ -458,7 +480,7 @@ export class SharedSaleInvoiceCreateService {
|
||||
return salesInvoiceData
|
||||
}
|
||||
|
||||
private async getNextInvoiceNumber(tx: Prisma.TransactionClient, businessId: string) {
|
||||
async getNextInvoiceNumber(tx: Prisma.TransactionClient, businessId: string) {
|
||||
const latestInvoice = await tx.salesInvoice.findFirst({
|
||||
where: {
|
||||
pos: {
|
||||
@@ -499,7 +521,6 @@ export class SharedSaleInvoiceCreateService {
|
||||
tx: Prisma.TransactionClient,
|
||||
invoiceId: string,
|
||||
payments: NormalizedPayment[],
|
||||
terminalInfo: TerminalPaymentInfo | undefined,
|
||||
paidAt: Date,
|
||||
) {
|
||||
for (const payment of payments) {
|
||||
@@ -515,16 +536,27 @@ export class SharedSaleInvoiceCreateService {
|
||||
},
|
||||
})
|
||||
|
||||
if (payment.method === PaymentMethodType.TERMINAL && terminalInfo) {
|
||||
if (payment.method === PaymentMethodType.TERMINAL && payment.terminalInfo) {
|
||||
const {
|
||||
terminal_id,
|
||||
stan,
|
||||
rrn,
|
||||
transaction_date_time,
|
||||
customer_card_no,
|
||||
description,
|
||||
} = payment.terminalInfo
|
||||
await tx.salesInvoicePaymentTerminalInfo.create({
|
||||
data: {
|
||||
payment_id: createdPayment.id,
|
||||
terminal_id: terminalInfo.terminal_id,
|
||||
stan: terminalInfo.stan,
|
||||
rrn: terminalInfo.rrn,
|
||||
transaction_date_time: new Date(terminalInfo.transaction_date_time || ''),
|
||||
customer_card_no: terminalInfo.customer_card_no || null,
|
||||
description: terminalInfo.description || null,
|
||||
terminal_id,
|
||||
stan: stan,
|
||||
rrn: rrn,
|
||||
transaction_date_time: transaction_date_time
|
||||
? new Date(transaction_date_time)
|
||||
: new Date(),
|
||||
customer_card_no: '1234567890123456',
|
||||
// customer_card_no: customer_card_no || null,
|
||||
description: description || null,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
import { ApiPropertyOptional } from '@nestjs/swagger'
|
||||
import { Type } from 'class-transformer'
|
||||
import {
|
||||
IsDateString,
|
||||
IsEnum,
|
||||
IsNumber,
|
||||
IsOptional,
|
||||
IsString,
|
||||
Min,
|
||||
} from 'class-validator'
|
||||
import { TspProviderResponseStatus } from 'generated/prisma/enums'
|
||||
|
||||
export class SharedSaleInvoicesFilterDto {
|
||||
@ApiPropertyOptional({ default: 1 })
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
@IsNumber()
|
||||
@Min(1)
|
||||
page?: number
|
||||
|
||||
@ApiPropertyOptional({ default: 10 })
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
@IsNumber()
|
||||
@Min(1)
|
||||
perPage?: number
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsDateString()
|
||||
invoice_date_from?: string
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsDateString()
|
||||
invoice_date_to?: string
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsDateString()
|
||||
created_at_from?: string
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsDateString()
|
||||
created_at_to?: string
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
customer_name?: string
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
customer_mobile?: string
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
customer_national_id?: string
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
customer_economic_code?: string
|
||||
|
||||
@ApiPropertyOptional({ enum: TspProviderResponseStatus })
|
||||
@IsOptional()
|
||||
@IsEnum(TspProviderResponseStatus)
|
||||
status?: TspProviderResponseStatus
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
@IsNumber()
|
||||
total_amount?: number
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
@IsNumber()
|
||||
total_amount_from?: number
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
@IsNumber()
|
||||
total_amount_to?: number
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
import { TspProviderResponseStatus } from '@/generated/prisma/enums'
|
||||
import { SalesInvoiceWhereInput } from '@/generated/prisma/models'
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { SharedSaleInvoicesFilterDto } from './sale-invoice-filter.dto'
|
||||
|
||||
@Injectable()
|
||||
export class SharedSaleInvoiceFilterService {
|
||||
buildWhere(filter: SharedSaleInvoicesFilterDto): SalesInvoiceWhereInput {
|
||||
const where: SalesInvoiceWhereInput = {}
|
||||
|
||||
if (filter.invoice_date_from || filter.invoice_date_to) {
|
||||
where.invoice_date = {
|
||||
...(filter.invoice_date_from ? { gte: new Date(filter.invoice_date_from) } : {}),
|
||||
...(filter.invoice_date_to ? { lte: new Date(filter.invoice_date_to) } : {}),
|
||||
}
|
||||
}
|
||||
|
||||
if (filter.created_at_from || filter.created_at_to) {
|
||||
where.created_at = {
|
||||
...(filter.created_at_from ? { gte: new Date(filter.created_at_from) } : {}),
|
||||
...(filter.created_at_to ? { lte: new Date(filter.created_at_to) } : {}),
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
filter.total_amount !== undefined ||
|
||||
filter.total_amount_from !== undefined ||
|
||||
filter.total_amount_to !== undefined
|
||||
) {
|
||||
where.total_amount = {
|
||||
...(filter.total_amount !== undefined ? { equals: filter.total_amount } : {}),
|
||||
...(filter.total_amount_from !== undefined
|
||||
? { gte: filter.total_amount_from }
|
||||
: {}),
|
||||
...(filter.total_amount_to !== undefined ? { lte: filter.total_amount_to } : {}),
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
filter.customer_name?.trim() ||
|
||||
filter.customer_mobile?.trim() ||
|
||||
filter.customer_national_id?.trim() ||
|
||||
filter.customer_economic_code?.trim()
|
||||
) {
|
||||
where.customer = {
|
||||
is: {
|
||||
OR: [
|
||||
...(filter.customer_name?.trim()
|
||||
? [
|
||||
{
|
||||
individual: {
|
||||
is: {
|
||||
OR: [
|
||||
{ first_name: { contains: filter.customer_name.trim() } },
|
||||
{ last_name: { contains: filter.customer_name.trim() } },
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
legal: {
|
||||
is: {
|
||||
name: {
|
||||
contains: filter.customer_name.trim(),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...(filter.customer_mobile?.trim()
|
||||
? [
|
||||
{
|
||||
individual: {
|
||||
is: {
|
||||
mobile_number: { contains: filter.customer_mobile.trim() },
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...(filter.customer_national_id?.trim()
|
||||
? [
|
||||
{
|
||||
individual: {
|
||||
is: {
|
||||
national_id: { contains: filter.customer_national_id.trim() },
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...(filter.customer_economic_code?.trim()
|
||||
? [
|
||||
{
|
||||
legal: {
|
||||
is: {
|
||||
OR: [
|
||||
{
|
||||
economic_code: {
|
||||
contains: filter.customer_economic_code.trim(),
|
||||
},
|
||||
},
|
||||
{
|
||||
registration_number: {
|
||||
contains: filter.customer_economic_code.trim(),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
: []),
|
||||
],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if (filter.status) {
|
||||
if (filter.status === TspProviderResponseStatus.NOT_SEND) {
|
||||
where.OR = [
|
||||
{
|
||||
last_tsp_status: null,
|
||||
},
|
||||
{
|
||||
last_tsp_status: TspProviderResponseStatus.NOT_SEND,
|
||||
},
|
||||
]
|
||||
} else {
|
||||
where.last_tsp_status = filter.status
|
||||
}
|
||||
}
|
||||
|
||||
return where
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import { Injectable } from '@nestjs/common'
|
||||
|
||||
@Injectable()
|
||||
export class SharedSaleInvoicePaginationService {
|
||||
normalize(
|
||||
page: number = 1,
|
||||
perPage: number = 10,
|
||||
defaultPerPage: number = 10,
|
||||
maxPerPage: number = 50,
|
||||
) {
|
||||
const normalizedPageValue = Number(page ?? 1)
|
||||
const normalizedPage = Number.isFinite(normalizedPageValue)
|
||||
? Math.max(1, Math.floor(normalizedPageValue))
|
||||
: 1
|
||||
|
||||
const requestedPerPageValue = Number(perPage ?? defaultPerPage)
|
||||
const requestedPerPage = Number.isFinite(requestedPerPageValue)
|
||||
? Math.max(1, Math.floor(requestedPerPageValue))
|
||||
: defaultPerPage
|
||||
const normalizedPerPage = Math.min(requestedPerPage, maxPerPage)
|
||||
|
||||
return {
|
||||
page: normalizedPage,
|
||||
perPage: normalizedPerPage,
|
||||
skip: (normalizedPage - 1) * normalizedPerPage,
|
||||
take: normalizedPerPage,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,14 +20,18 @@ export function getCurrentJalaliSeasonStart(
|
||||
const date = dayjs(baseDate).calendar('jalali')
|
||||
const month = date.month() + 1
|
||||
const seasonStartMonth = Math.floor((month - 1) / 3) * 3 + 1
|
||||
return date.month(seasonStartMonth - 1).startOf('month').startOf('day').toDate()
|
||||
return date
|
||||
.month(seasonStartMonth - 1)
|
||||
.startOf('month')
|
||||
.startOf('day')
|
||||
.toDate()
|
||||
}
|
||||
|
||||
export function getCurrentJalaliSeasonEnd(
|
||||
baseDate: string | number | Date | Dayjs = dayjs(),
|
||||
): Date {
|
||||
return dayjs(getCurrentJalaliSeasonStart(baseDate))
|
||||
.add(2, 'month')
|
||||
.add(3, 'month')
|
||||
.endOf('month')
|
||||
.endOf('day')
|
||||
.toDate()
|
||||
@@ -39,7 +43,11 @@ export function getCurrentGregorianSeasonStart(
|
||||
const date = dayjs(baseDate).calendar('gregory')
|
||||
const month = date.month() + 1
|
||||
const seasonStartMonth = Math.floor((month - 1) / 3) * 3 + 1
|
||||
return date.month(seasonStartMonth - 1).startOf('month').startOf('day').toDate()
|
||||
return date
|
||||
.month(seasonStartMonth - 1)
|
||||
.startOf('month')
|
||||
.startOf('day')
|
||||
.toDate()
|
||||
}
|
||||
|
||||
export function getCurrentGregorianSeasonEnd(
|
||||
|
||||
@@ -18,13 +18,13 @@ export function checkAndDecodeJwtToken(
|
||||
token = authHeader.slice(7)
|
||||
}
|
||||
}
|
||||
if (!token) throw new UnauthorizedException('Missing accessToken cookie')
|
||||
if (!token) throw new UnauthorizedException('توکن احراز هویت ارسال نشده است')
|
||||
|
||||
try {
|
||||
const payload = jwtService.decode(token) as AccessTokenPayload
|
||||
|
||||
return payload as ITokenPayload
|
||||
} catch {
|
||||
return null
|
||||
throw new UnauthorizedException('توکن احراز هویت نامعتبر است')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
export class ConsumerKeyMaker {
|
||||
static middleware(token: string): string {
|
||||
return `consumer:middleware:${token}`
|
||||
}
|
||||
|
||||
static consumerInfo(consumerId: string): string {
|
||||
return `consumers:${consumerId}:info`
|
||||
}
|
||||
|
||||
@@ -14,12 +14,15 @@ export class RedisKeyMaker extends PartnerKeyMaker {
|
||||
static pos = PosKeyMaker
|
||||
|
||||
static consumerInfo = ConsumerKeyMaker.consumerInfo
|
||||
static consumerMiddleware = ConsumerKeyMaker.middleware
|
||||
static consumerBusinessActivitiesList = ConsumerKeyMaker.consumerBusinessActivitiesList
|
||||
static consumerBusinessActivityInfo = ConsumerKeyMaker.consumerBusinessActivityInfo
|
||||
|
||||
static guildStockKeepingUnitsList = GuildKeyMaker.guildStockKeepingUnitsList
|
||||
static guildGoodsList = GuildKeyMaker.guildGoodsList
|
||||
|
||||
static posMiddleware = PosKeyMaker.middleware
|
||||
static partnerMiddleware = PartnerKeyMaker.middleware
|
||||
static posInfo = PosKeyMaker.info
|
||||
static posMe = PosKeyMaker.me
|
||||
static posGoodsList = PosKeyMaker.goodList
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
export class PartnerKeyMaker {
|
||||
static middleware(token): string {
|
||||
return `partner:middleware:${token}`
|
||||
}
|
||||
|
||||
static partnersList(): string {
|
||||
return 'partners:list'
|
||||
}
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
export class PosKeyMaker {
|
||||
static middleware(token: string): string {
|
||||
return `pos:${token}:middleware`
|
||||
}
|
||||
|
||||
static info(posId: string): string {
|
||||
return `pos:${posId}:info`
|
||||
}
|
||||
|
||||
@@ -630,6 +630,24 @@ export type EnumInvoiceSettlementTypeFilter<$PrismaModel = never> = {
|
||||
not?: Prisma.NestedEnumInvoiceSettlementTypeFilter<$PrismaModel> | $Enums.InvoiceSettlementType
|
||||
}
|
||||
|
||||
export type EnumTspProviderResponseStatusNullableFilter<$PrismaModel = never> = {
|
||||
equals?: $Enums.TspProviderResponseStatus | Prisma.EnumTspProviderResponseStatusFieldRefInput<$PrismaModel> | null
|
||||
in?: $Enums.TspProviderResponseStatus[] | null
|
||||
notIn?: $Enums.TspProviderResponseStatus[] | null
|
||||
not?: Prisma.NestedEnumTspProviderResponseStatusNullableFilter<$PrismaModel> | $Enums.TspProviderResponseStatus | null
|
||||
}
|
||||
|
||||
export type IntNullableFilter<$PrismaModel = never> = {
|
||||
equals?: number | Prisma.IntFieldRefInput<$PrismaModel> | null
|
||||
in?: number[] | null
|
||||
notIn?: number[] | null
|
||||
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
gte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
not?: Prisma.NestedIntNullableFilter<$PrismaModel> | number | null
|
||||
}
|
||||
|
||||
export type EnumTspProviderRequestTypeWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: $Enums.TspProviderRequestType | Prisma.EnumTspProviderRequestTypeFieldRefInput<$PrismaModel>
|
||||
in?: $Enums.TspProviderRequestType[]
|
||||
@@ -650,6 +668,32 @@ export type EnumInvoiceSettlementTypeWithAggregatesFilter<$PrismaModel = never>
|
||||
_max?: Prisma.NestedEnumInvoiceSettlementTypeFilter<$PrismaModel>
|
||||
}
|
||||
|
||||
export type EnumTspProviderResponseStatusNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: $Enums.TspProviderResponseStatus | Prisma.EnumTspProviderResponseStatusFieldRefInput<$PrismaModel> | null
|
||||
in?: $Enums.TspProviderResponseStatus[] | null
|
||||
notIn?: $Enums.TspProviderResponseStatus[] | null
|
||||
not?: Prisma.NestedEnumTspProviderResponseStatusNullableWithAggregatesFilter<$PrismaModel> | $Enums.TspProviderResponseStatus | null
|
||||
_count?: Prisma.NestedIntNullableFilter<$PrismaModel>
|
||||
_min?: Prisma.NestedEnumTspProviderResponseStatusNullableFilter<$PrismaModel>
|
||||
_max?: Prisma.NestedEnumTspProviderResponseStatusNullableFilter<$PrismaModel>
|
||||
}
|
||||
|
||||
export type IntNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: number | Prisma.IntFieldRefInput<$PrismaModel> | null
|
||||
in?: number[] | null
|
||||
notIn?: number[] | null
|
||||
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
gte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
not?: Prisma.NestedIntNullableWithAggregatesFilter<$PrismaModel> | number | null
|
||||
_count?: Prisma.NestedIntNullableFilter<$PrismaModel>
|
||||
_avg?: Prisma.NestedFloatNullableFilter<$PrismaModel>
|
||||
_sum?: Prisma.NestedIntNullableFilter<$PrismaModel>
|
||||
_min?: Prisma.NestedIntNullableFilter<$PrismaModel>
|
||||
_max?: Prisma.NestedIntNullableFilter<$PrismaModel>
|
||||
}
|
||||
|
||||
export type JsonFilter<$PrismaModel = never> =
|
||||
| Prisma.PatchUndefined<
|
||||
Prisma.Either<Required<JsonFilterBase<$PrismaModel>>, Exclude<keyof Required<JsonFilterBase<$PrismaModel>>, 'path'>>,
|
||||
@@ -1341,6 +1385,13 @@ export type NestedEnumInvoiceSettlementTypeFilter<$PrismaModel = never> = {
|
||||
not?: Prisma.NestedEnumInvoiceSettlementTypeFilter<$PrismaModel> | $Enums.InvoiceSettlementType
|
||||
}
|
||||
|
||||
export type NestedEnumTspProviderResponseStatusNullableFilter<$PrismaModel = never> = {
|
||||
equals?: $Enums.TspProviderResponseStatus | Prisma.EnumTspProviderResponseStatusFieldRefInput<$PrismaModel> | null
|
||||
in?: $Enums.TspProviderResponseStatus[] | null
|
||||
notIn?: $Enums.TspProviderResponseStatus[] | null
|
||||
not?: Prisma.NestedEnumTspProviderResponseStatusNullableFilter<$PrismaModel> | $Enums.TspProviderResponseStatus | null
|
||||
}
|
||||
|
||||
export type NestedEnumTspProviderRequestTypeWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: $Enums.TspProviderRequestType | Prisma.EnumTspProviderRequestTypeFieldRefInput<$PrismaModel>
|
||||
in?: $Enums.TspProviderRequestType[]
|
||||
@@ -1361,6 +1412,43 @@ export type NestedEnumInvoiceSettlementTypeWithAggregatesFilter<$PrismaModel = n
|
||||
_max?: Prisma.NestedEnumInvoiceSettlementTypeFilter<$PrismaModel>
|
||||
}
|
||||
|
||||
export type NestedEnumTspProviderResponseStatusNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: $Enums.TspProviderResponseStatus | Prisma.EnumTspProviderResponseStatusFieldRefInput<$PrismaModel> | null
|
||||
in?: $Enums.TspProviderResponseStatus[] | null
|
||||
notIn?: $Enums.TspProviderResponseStatus[] | null
|
||||
not?: Prisma.NestedEnumTspProviderResponseStatusNullableWithAggregatesFilter<$PrismaModel> | $Enums.TspProviderResponseStatus | null
|
||||
_count?: Prisma.NestedIntNullableFilter<$PrismaModel>
|
||||
_min?: Prisma.NestedEnumTspProviderResponseStatusNullableFilter<$PrismaModel>
|
||||
_max?: Prisma.NestedEnumTspProviderResponseStatusNullableFilter<$PrismaModel>
|
||||
}
|
||||
|
||||
export type NestedIntNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: number | Prisma.IntFieldRefInput<$PrismaModel> | null
|
||||
in?: number[] | null
|
||||
notIn?: number[] | null
|
||||
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
gte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
not?: Prisma.NestedIntNullableWithAggregatesFilter<$PrismaModel> | number | null
|
||||
_count?: Prisma.NestedIntNullableFilter<$PrismaModel>
|
||||
_avg?: Prisma.NestedFloatNullableFilter<$PrismaModel>
|
||||
_sum?: Prisma.NestedIntNullableFilter<$PrismaModel>
|
||||
_min?: Prisma.NestedIntNullableFilter<$PrismaModel>
|
||||
_max?: Prisma.NestedIntNullableFilter<$PrismaModel>
|
||||
}
|
||||
|
||||
export type NestedFloatNullableFilter<$PrismaModel = never> = {
|
||||
equals?: number | Prisma.FloatFieldRefInput<$PrismaModel> | null
|
||||
in?: number[] | null
|
||||
notIn?: number[] | null
|
||||
lt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
lte?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
gt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
gte?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
not?: Prisma.NestedFloatNullableFilter<$PrismaModel> | number | null
|
||||
}
|
||||
|
||||
export type NestedJsonFilter<$PrismaModel = never> =
|
||||
| Prisma.PatchUndefined<
|
||||
Prisma.Either<Required<NestedJsonFilterBase<$PrismaModel>>, Exclude<keyof Required<NestedJsonFilterBase<$PrismaModel>>, 'path'>>,
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -4094,8 +4094,6 @@ export const SalesInvoiceScalarFieldEnum = {
|
||||
id: 'id',
|
||||
code: 'code',
|
||||
total_amount: 'total_amount',
|
||||
tax_amount: 'tax_amount',
|
||||
discount_amount: 'discount_amount',
|
||||
invoice_number: 'invoice_number',
|
||||
invoice_date: 'invoice_date',
|
||||
type: 'type',
|
||||
@@ -4109,7 +4107,11 @@ export const SalesInvoiceScalarFieldEnum = {
|
||||
customer_id: 'customer_id',
|
||||
consumer_account_id: 'consumer_account_id',
|
||||
pos_id: 'pos_id',
|
||||
settlement_type: 'settlement_type'
|
||||
settlement_type: 'settlement_type',
|
||||
discount_amount: 'discount_amount',
|
||||
tax_amount: 'tax_amount',
|
||||
last_tsp_status: 'last_tsp_status',
|
||||
last_attempt_no: 'last_attempt_no'
|
||||
} as const
|
||||
|
||||
export type SalesInvoiceScalarFieldEnum = (typeof SalesInvoiceScalarFieldEnum)[keyof typeof SalesInvoiceScalarFieldEnum]
|
||||
@@ -4125,14 +4127,15 @@ export const SalesInvoiceItemScalarFieldEnum = {
|
||||
unit_price: 'unit_price',
|
||||
total_amount: 'total_amount',
|
||||
created_at: 'created_at',
|
||||
discount_amount: 'discount_amount',
|
||||
tax_amount: 'tax_amount',
|
||||
discount: 'discount',
|
||||
notes: 'notes',
|
||||
payload: 'payload',
|
||||
good_snapshot: 'good_snapshot',
|
||||
invoice_id: 'invoice_id',
|
||||
good_id: 'good_id',
|
||||
service_id: 'service_id'
|
||||
service_id: 'service_id',
|
||||
discount_amount: 'discount_amount',
|
||||
tax_amount: 'tax_amount'
|
||||
} as const
|
||||
|
||||
export type SalesInvoiceItemScalarFieldEnum = (typeof SalesInvoiceItemScalarFieldEnum)[keyof typeof SalesInvoiceItemScalarFieldEnum]
|
||||
|
||||
@@ -619,8 +619,6 @@ export const SalesInvoiceScalarFieldEnum = {
|
||||
id: 'id',
|
||||
code: 'code',
|
||||
total_amount: 'total_amount',
|
||||
tax_amount: 'tax_amount',
|
||||
discount_amount: 'discount_amount',
|
||||
invoice_number: 'invoice_number',
|
||||
invoice_date: 'invoice_date',
|
||||
type: 'type',
|
||||
@@ -634,7 +632,11 @@ export const SalesInvoiceScalarFieldEnum = {
|
||||
customer_id: 'customer_id',
|
||||
consumer_account_id: 'consumer_account_id',
|
||||
pos_id: 'pos_id',
|
||||
settlement_type: 'settlement_type'
|
||||
settlement_type: 'settlement_type',
|
||||
discount_amount: 'discount_amount',
|
||||
tax_amount: 'tax_amount',
|
||||
last_tsp_status: 'last_tsp_status',
|
||||
last_attempt_no: 'last_attempt_no'
|
||||
} as const
|
||||
|
||||
export type SalesInvoiceScalarFieldEnum = (typeof SalesInvoiceScalarFieldEnum)[keyof typeof SalesInvoiceScalarFieldEnum]
|
||||
@@ -650,14 +652,15 @@ export const SalesInvoiceItemScalarFieldEnum = {
|
||||
unit_price: 'unit_price',
|
||||
total_amount: 'total_amount',
|
||||
created_at: 'created_at',
|
||||
discount_amount: 'discount_amount',
|
||||
tax_amount: 'tax_amount',
|
||||
discount: 'discount',
|
||||
notes: 'notes',
|
||||
payload: 'payload',
|
||||
good_snapshot: 'good_snapshot',
|
||||
invoice_id: 'invoice_id',
|
||||
good_id: 'good_id',
|
||||
service_id: 'service_id'
|
||||
service_id: 'service_id',
|
||||
discount_amount: 'discount_amount',
|
||||
tax_amount: 'tax_amount'
|
||||
} as const
|
||||
|
||||
export type SalesInvoiceItemScalarFieldEnum = (typeof SalesInvoiceItemScalarFieldEnum)[keyof typeof SalesInvoiceItemScalarFieldEnum]
|
||||
|
||||
@@ -166,11 +166,11 @@ export type CustomerIndividualGroupByArgs<ExtArgs extends runtime.Types.Extensio
|
||||
}
|
||||
|
||||
export type CustomerIndividualGroupByOutputType = {
|
||||
first_name: string
|
||||
last_name: string
|
||||
national_id: string
|
||||
mobile_number: string
|
||||
postal_code: string
|
||||
first_name: string | null
|
||||
last_name: string | null
|
||||
national_id: string | null
|
||||
mobile_number: string | null
|
||||
postal_code: string | null
|
||||
economic_code: string | null
|
||||
customer_id: string
|
||||
business_activity_id: string
|
||||
@@ -198,11 +198,11 @@ export type CustomerIndividualWhereInput = {
|
||||
AND?: Prisma.CustomerIndividualWhereInput | Prisma.CustomerIndividualWhereInput[]
|
||||
OR?: Prisma.CustomerIndividualWhereInput[]
|
||||
NOT?: Prisma.CustomerIndividualWhereInput | Prisma.CustomerIndividualWhereInput[]
|
||||
first_name?: Prisma.StringFilter<"CustomerIndividual"> | string
|
||||
last_name?: Prisma.StringFilter<"CustomerIndividual"> | string
|
||||
national_id?: Prisma.StringFilter<"CustomerIndividual"> | string
|
||||
mobile_number?: Prisma.StringFilter<"CustomerIndividual"> | string
|
||||
postal_code?: Prisma.StringFilter<"CustomerIndividual"> | string
|
||||
first_name?: Prisma.StringNullableFilter<"CustomerIndividual"> | string | null
|
||||
last_name?: Prisma.StringNullableFilter<"CustomerIndividual"> | string | null
|
||||
national_id?: Prisma.StringNullableFilter<"CustomerIndividual"> | string | null
|
||||
mobile_number?: Prisma.StringNullableFilter<"CustomerIndividual"> | string | null
|
||||
postal_code?: Prisma.StringNullableFilter<"CustomerIndividual"> | string | null
|
||||
economic_code?: Prisma.StringNullableFilter<"CustomerIndividual"> | string | null
|
||||
customer_id?: Prisma.StringFilter<"CustomerIndividual"> | string
|
||||
business_activity_id?: Prisma.StringFilter<"CustomerIndividual"> | string
|
||||
@@ -211,11 +211,11 @@ export type CustomerIndividualWhereInput = {
|
||||
}
|
||||
|
||||
export type CustomerIndividualOrderByWithRelationInput = {
|
||||
first_name?: Prisma.SortOrder
|
||||
last_name?: Prisma.SortOrder
|
||||
national_id?: Prisma.SortOrder
|
||||
mobile_number?: Prisma.SortOrder
|
||||
postal_code?: Prisma.SortOrder
|
||||
first_name?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
last_name?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
national_id?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
mobile_number?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
postal_code?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
economic_code?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
customer_id?: Prisma.SortOrder
|
||||
business_activity_id?: Prisma.SortOrder
|
||||
@@ -227,26 +227,27 @@ export type CustomerIndividualOrderByWithRelationInput = {
|
||||
export type CustomerIndividualWhereUniqueInput = Prisma.AtLeast<{
|
||||
customer_id?: string
|
||||
business_activity_id_national_id?: Prisma.CustomerIndividualBusiness_activity_idNational_idCompoundUniqueInput
|
||||
business_activity_id_postal_code_national_id?: Prisma.CustomerIndividualBusiness_activity_idPostal_codeNational_idCompoundUniqueInput
|
||||
AND?: Prisma.CustomerIndividualWhereInput | Prisma.CustomerIndividualWhereInput[]
|
||||
OR?: Prisma.CustomerIndividualWhereInput[]
|
||||
NOT?: Prisma.CustomerIndividualWhereInput | Prisma.CustomerIndividualWhereInput[]
|
||||
first_name?: Prisma.StringFilter<"CustomerIndividual"> | string
|
||||
last_name?: Prisma.StringFilter<"CustomerIndividual"> | string
|
||||
national_id?: Prisma.StringFilter<"CustomerIndividual"> | string
|
||||
mobile_number?: Prisma.StringFilter<"CustomerIndividual"> | string
|
||||
postal_code?: Prisma.StringFilter<"CustomerIndividual"> | string
|
||||
first_name?: Prisma.StringNullableFilter<"CustomerIndividual"> | string | null
|
||||
last_name?: Prisma.StringNullableFilter<"CustomerIndividual"> | string | null
|
||||
national_id?: Prisma.StringNullableFilter<"CustomerIndividual"> | string | null
|
||||
mobile_number?: Prisma.StringNullableFilter<"CustomerIndividual"> | string | null
|
||||
postal_code?: Prisma.StringNullableFilter<"CustomerIndividual"> | string | null
|
||||
economic_code?: Prisma.StringNullableFilter<"CustomerIndividual"> | string | null
|
||||
business_activity_id?: Prisma.StringFilter<"CustomerIndividual"> | string
|
||||
business_activity?: Prisma.XOR<Prisma.BusinessActivityScalarRelationFilter, Prisma.BusinessActivityWhereInput>
|
||||
customer?: Prisma.XOR<Prisma.CustomerScalarRelationFilter, Prisma.CustomerWhereInput>
|
||||
}, "customer_id" | "business_activity_id_national_id">
|
||||
}, "customer_id" | "business_activity_id_national_id" | "business_activity_id_postal_code_national_id">
|
||||
|
||||
export type CustomerIndividualOrderByWithAggregationInput = {
|
||||
first_name?: Prisma.SortOrder
|
||||
last_name?: Prisma.SortOrder
|
||||
national_id?: Prisma.SortOrder
|
||||
mobile_number?: Prisma.SortOrder
|
||||
postal_code?: Prisma.SortOrder
|
||||
first_name?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
last_name?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
national_id?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
mobile_number?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
postal_code?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
economic_code?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
customer_id?: Prisma.SortOrder
|
||||
business_activity_id?: Prisma.SortOrder
|
||||
@@ -259,86 +260,86 @@ export type CustomerIndividualScalarWhereWithAggregatesInput = {
|
||||
AND?: Prisma.CustomerIndividualScalarWhereWithAggregatesInput | Prisma.CustomerIndividualScalarWhereWithAggregatesInput[]
|
||||
OR?: Prisma.CustomerIndividualScalarWhereWithAggregatesInput[]
|
||||
NOT?: Prisma.CustomerIndividualScalarWhereWithAggregatesInput | Prisma.CustomerIndividualScalarWhereWithAggregatesInput[]
|
||||
first_name?: Prisma.StringWithAggregatesFilter<"CustomerIndividual"> | string
|
||||
last_name?: Prisma.StringWithAggregatesFilter<"CustomerIndividual"> | string
|
||||
national_id?: Prisma.StringWithAggregatesFilter<"CustomerIndividual"> | string
|
||||
mobile_number?: Prisma.StringWithAggregatesFilter<"CustomerIndividual"> | string
|
||||
postal_code?: Prisma.StringWithAggregatesFilter<"CustomerIndividual"> | string
|
||||
first_name?: Prisma.StringNullableWithAggregatesFilter<"CustomerIndividual"> | string | null
|
||||
last_name?: Prisma.StringNullableWithAggregatesFilter<"CustomerIndividual"> | string | null
|
||||
national_id?: Prisma.StringNullableWithAggregatesFilter<"CustomerIndividual"> | string | null
|
||||
mobile_number?: Prisma.StringNullableWithAggregatesFilter<"CustomerIndividual"> | string | null
|
||||
postal_code?: Prisma.StringNullableWithAggregatesFilter<"CustomerIndividual"> | string | null
|
||||
economic_code?: Prisma.StringNullableWithAggregatesFilter<"CustomerIndividual"> | string | null
|
||||
customer_id?: Prisma.StringWithAggregatesFilter<"CustomerIndividual"> | string
|
||||
business_activity_id?: Prisma.StringWithAggregatesFilter<"CustomerIndividual"> | string
|
||||
}
|
||||
|
||||
export type CustomerIndividualCreateInput = {
|
||||
first_name: string
|
||||
last_name: string
|
||||
national_id: string
|
||||
mobile_number: string
|
||||
postal_code: string
|
||||
first_name?: string | null
|
||||
last_name?: string | null
|
||||
national_id?: string | null
|
||||
mobile_number?: string | null
|
||||
postal_code?: string | null
|
||||
economic_code?: string | null
|
||||
business_activity: Prisma.BusinessActivityCreateNestedOneWithoutCustomer_individualsInput
|
||||
customer: Prisma.CustomerCreateNestedOneWithoutIndividualInput
|
||||
}
|
||||
|
||||
export type CustomerIndividualUncheckedCreateInput = {
|
||||
first_name: string
|
||||
last_name: string
|
||||
national_id: string
|
||||
mobile_number: string
|
||||
postal_code: string
|
||||
first_name?: string | null
|
||||
last_name?: string | null
|
||||
national_id?: string | null
|
||||
mobile_number?: string | null
|
||||
postal_code?: string | null
|
||||
economic_code?: string | null
|
||||
customer_id: string
|
||||
business_activity_id: string
|
||||
}
|
||||
|
||||
export type CustomerIndividualUpdateInput = {
|
||||
first_name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
last_name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
national_id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
mobile_number?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
postal_code?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
first_name?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
last_name?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
national_id?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
mobile_number?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
postal_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
economic_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
business_activity?: Prisma.BusinessActivityUpdateOneRequiredWithoutCustomer_individualsNestedInput
|
||||
customer?: Prisma.CustomerUpdateOneRequiredWithoutIndividualNestedInput
|
||||
}
|
||||
|
||||
export type CustomerIndividualUncheckedUpdateInput = {
|
||||
first_name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
last_name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
national_id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
mobile_number?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
postal_code?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
first_name?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
last_name?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
national_id?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
mobile_number?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
postal_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
economic_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
customer_id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
business_activity_id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
}
|
||||
|
||||
export type CustomerIndividualCreateManyInput = {
|
||||
first_name: string
|
||||
last_name: string
|
||||
national_id: string
|
||||
mobile_number: string
|
||||
postal_code: string
|
||||
first_name?: string | null
|
||||
last_name?: string | null
|
||||
national_id?: string | null
|
||||
mobile_number?: string | null
|
||||
postal_code?: string | null
|
||||
economic_code?: string | null
|
||||
customer_id: string
|
||||
business_activity_id: string
|
||||
}
|
||||
|
||||
export type CustomerIndividualUpdateManyMutationInput = {
|
||||
first_name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
last_name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
national_id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
mobile_number?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
postal_code?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
first_name?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
last_name?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
national_id?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
mobile_number?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
postal_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
economic_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
}
|
||||
|
||||
export type CustomerIndividualUncheckedUpdateManyInput = {
|
||||
first_name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
last_name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
national_id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
mobile_number?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
postal_code?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
first_name?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
last_name?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
national_id?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
mobile_number?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
postal_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
economic_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
customer_id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
business_activity_id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
@@ -370,6 +371,12 @@ export type CustomerIndividualBusiness_activity_idNational_idCompoundUniqueInput
|
||||
national_id: string
|
||||
}
|
||||
|
||||
export type CustomerIndividualBusiness_activity_idPostal_codeNational_idCompoundUniqueInput = {
|
||||
business_activity_id: string
|
||||
postal_code: string
|
||||
national_id: string
|
||||
}
|
||||
|
||||
export type CustomerIndividualCountOrderByAggregateInput = {
|
||||
first_name?: Prisma.SortOrder
|
||||
last_name?: Prisma.SortOrder
|
||||
@@ -478,21 +485,21 @@ export type CustomerIndividualUncheckedUpdateOneWithoutCustomerNestedInput = {
|
||||
}
|
||||
|
||||
export type CustomerIndividualCreateWithoutBusiness_activityInput = {
|
||||
first_name: string
|
||||
last_name: string
|
||||
national_id: string
|
||||
mobile_number: string
|
||||
postal_code: string
|
||||
first_name?: string | null
|
||||
last_name?: string | null
|
||||
national_id?: string | null
|
||||
mobile_number?: string | null
|
||||
postal_code?: string | null
|
||||
economic_code?: string | null
|
||||
customer: Prisma.CustomerCreateNestedOneWithoutIndividualInput
|
||||
}
|
||||
|
||||
export type CustomerIndividualUncheckedCreateWithoutBusiness_activityInput = {
|
||||
first_name: string
|
||||
last_name: string
|
||||
national_id: string
|
||||
mobile_number: string
|
||||
postal_code: string
|
||||
first_name?: string | null
|
||||
last_name?: string | null
|
||||
national_id?: string | null
|
||||
mobile_number?: string | null
|
||||
postal_code?: string | null
|
||||
economic_code?: string | null
|
||||
customer_id: string
|
||||
}
|
||||
@@ -527,32 +534,32 @@ export type CustomerIndividualScalarWhereInput = {
|
||||
AND?: Prisma.CustomerIndividualScalarWhereInput | Prisma.CustomerIndividualScalarWhereInput[]
|
||||
OR?: Prisma.CustomerIndividualScalarWhereInput[]
|
||||
NOT?: Prisma.CustomerIndividualScalarWhereInput | Prisma.CustomerIndividualScalarWhereInput[]
|
||||
first_name?: Prisma.StringFilter<"CustomerIndividual"> | string
|
||||
last_name?: Prisma.StringFilter<"CustomerIndividual"> | string
|
||||
national_id?: Prisma.StringFilter<"CustomerIndividual"> | string
|
||||
mobile_number?: Prisma.StringFilter<"CustomerIndividual"> | string
|
||||
postal_code?: Prisma.StringFilter<"CustomerIndividual"> | string
|
||||
first_name?: Prisma.StringNullableFilter<"CustomerIndividual"> | string | null
|
||||
last_name?: Prisma.StringNullableFilter<"CustomerIndividual"> | string | null
|
||||
national_id?: Prisma.StringNullableFilter<"CustomerIndividual"> | string | null
|
||||
mobile_number?: Prisma.StringNullableFilter<"CustomerIndividual"> | string | null
|
||||
postal_code?: Prisma.StringNullableFilter<"CustomerIndividual"> | string | null
|
||||
economic_code?: Prisma.StringNullableFilter<"CustomerIndividual"> | string | null
|
||||
customer_id?: Prisma.StringFilter<"CustomerIndividual"> | string
|
||||
business_activity_id?: Prisma.StringFilter<"CustomerIndividual"> | string
|
||||
}
|
||||
|
||||
export type CustomerIndividualCreateWithoutCustomerInput = {
|
||||
first_name: string
|
||||
last_name: string
|
||||
national_id: string
|
||||
mobile_number: string
|
||||
postal_code: string
|
||||
first_name?: string | null
|
||||
last_name?: string | null
|
||||
national_id?: string | null
|
||||
mobile_number?: string | null
|
||||
postal_code?: string | null
|
||||
economic_code?: string | null
|
||||
business_activity: Prisma.BusinessActivityCreateNestedOneWithoutCustomer_individualsInput
|
||||
}
|
||||
|
||||
export type CustomerIndividualUncheckedCreateWithoutCustomerInput = {
|
||||
first_name: string
|
||||
last_name: string
|
||||
national_id: string
|
||||
mobile_number: string
|
||||
postal_code: string
|
||||
first_name?: string | null
|
||||
last_name?: string | null
|
||||
national_id?: string | null
|
||||
mobile_number?: string | null
|
||||
postal_code?: string | null
|
||||
economic_code?: string | null
|
||||
business_activity_id: string
|
||||
}
|
||||
@@ -574,61 +581,61 @@ export type CustomerIndividualUpdateToOneWithWhereWithoutCustomerInput = {
|
||||
}
|
||||
|
||||
export type CustomerIndividualUpdateWithoutCustomerInput = {
|
||||
first_name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
last_name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
national_id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
mobile_number?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
postal_code?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
first_name?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
last_name?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
national_id?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
mobile_number?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
postal_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
economic_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
business_activity?: Prisma.BusinessActivityUpdateOneRequiredWithoutCustomer_individualsNestedInput
|
||||
}
|
||||
|
||||
export type CustomerIndividualUncheckedUpdateWithoutCustomerInput = {
|
||||
first_name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
last_name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
national_id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
mobile_number?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
postal_code?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
first_name?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
last_name?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
national_id?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
mobile_number?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
postal_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
economic_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
business_activity_id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
}
|
||||
|
||||
export type CustomerIndividualCreateManyBusiness_activityInput = {
|
||||
first_name: string
|
||||
last_name: string
|
||||
national_id: string
|
||||
mobile_number: string
|
||||
postal_code: string
|
||||
first_name?: string | null
|
||||
last_name?: string | null
|
||||
national_id?: string | null
|
||||
mobile_number?: string | null
|
||||
postal_code?: string | null
|
||||
economic_code?: string | null
|
||||
customer_id: string
|
||||
}
|
||||
|
||||
export type CustomerIndividualUpdateWithoutBusiness_activityInput = {
|
||||
first_name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
last_name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
national_id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
mobile_number?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
postal_code?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
first_name?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
last_name?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
national_id?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
mobile_number?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
postal_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
economic_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
customer?: Prisma.CustomerUpdateOneRequiredWithoutIndividualNestedInput
|
||||
}
|
||||
|
||||
export type CustomerIndividualUncheckedUpdateWithoutBusiness_activityInput = {
|
||||
first_name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
last_name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
national_id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
mobile_number?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
postal_code?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
first_name?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
last_name?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
national_id?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
mobile_number?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
postal_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
economic_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
customer_id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
}
|
||||
|
||||
export type CustomerIndividualUncheckedUpdateManyWithoutBusiness_activityInput = {
|
||||
first_name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
last_name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
national_id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
mobile_number?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
postal_code?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
first_name?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
last_name?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
national_id?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
mobile_number?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
postal_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
economic_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
customer_id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
}
|
||||
@@ -674,11 +681,11 @@ export type $CustomerIndividualPayload<ExtArgs extends runtime.Types.Extensions.
|
||||
customer: Prisma.$CustomerPayload<ExtArgs>
|
||||
}
|
||||
scalars: runtime.Types.Extensions.GetPayloadResult<{
|
||||
first_name: string
|
||||
last_name: string
|
||||
national_id: string
|
||||
mobile_number: string
|
||||
postal_code: string
|
||||
first_name: string | null
|
||||
last_name: string | null
|
||||
national_id: string | null
|
||||
mobile_number: string | null
|
||||
postal_code: string | null
|
||||
economic_code: string | null
|
||||
customer_id: string
|
||||
business_activity_id: string
|
||||
|
||||
@@ -154,10 +154,10 @@ export type CustomerLegalGroupByArgs<ExtArgs extends runtime.Types.Extensions.In
|
||||
}
|
||||
|
||||
export type CustomerLegalGroupByOutputType = {
|
||||
name: string
|
||||
economic_code: string
|
||||
name: string | null
|
||||
economic_code: string | null
|
||||
registration_number: string | null
|
||||
postal_code: string
|
||||
postal_code: string | null
|
||||
customer_id: string
|
||||
business_activity_id: string
|
||||
_count: CustomerLegalCountAggregateOutputType | null
|
||||
@@ -184,10 +184,10 @@ export type CustomerLegalWhereInput = {
|
||||
AND?: Prisma.CustomerLegalWhereInput | Prisma.CustomerLegalWhereInput[]
|
||||
OR?: Prisma.CustomerLegalWhereInput[]
|
||||
NOT?: Prisma.CustomerLegalWhereInput | Prisma.CustomerLegalWhereInput[]
|
||||
name?: Prisma.StringFilter<"CustomerLegal"> | string
|
||||
economic_code?: Prisma.StringFilter<"CustomerLegal"> | string
|
||||
name?: Prisma.StringNullableFilter<"CustomerLegal"> | string | null
|
||||
economic_code?: Prisma.StringNullableFilter<"CustomerLegal"> | string | null
|
||||
registration_number?: Prisma.StringNullableFilter<"CustomerLegal"> | string | null
|
||||
postal_code?: Prisma.StringFilter<"CustomerLegal"> | string
|
||||
postal_code?: Prisma.StringNullableFilter<"CustomerLegal"> | string | null
|
||||
customer_id?: Prisma.StringFilter<"CustomerLegal"> | string
|
||||
business_activity_id?: Prisma.StringFilter<"CustomerLegal"> | string
|
||||
business_activity?: Prisma.XOR<Prisma.BusinessActivityScalarRelationFilter, Prisma.BusinessActivityWhereInput>
|
||||
@@ -195,10 +195,10 @@ export type CustomerLegalWhereInput = {
|
||||
}
|
||||
|
||||
export type CustomerLegalOrderByWithRelationInput = {
|
||||
name?: Prisma.SortOrder
|
||||
economic_code?: Prisma.SortOrder
|
||||
name?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
economic_code?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
registration_number?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
postal_code?: Prisma.SortOrder
|
||||
postal_code?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
customer_id?: Prisma.SortOrder
|
||||
business_activity_id?: Prisma.SortOrder
|
||||
business_activity?: Prisma.BusinessActivityOrderByWithRelationInput
|
||||
@@ -209,23 +209,24 @@ export type CustomerLegalOrderByWithRelationInput = {
|
||||
export type CustomerLegalWhereUniqueInput = Prisma.AtLeast<{
|
||||
customer_id?: string
|
||||
business_activity_id_economic_code?: Prisma.CustomerLegalBusiness_activity_idEconomic_codeCompoundUniqueInput
|
||||
business_activity_id_postal_code_registration_number?: Prisma.CustomerLegalBusiness_activity_idPostal_codeRegistration_numberCompoundUniqueInput
|
||||
AND?: Prisma.CustomerLegalWhereInput | Prisma.CustomerLegalWhereInput[]
|
||||
OR?: Prisma.CustomerLegalWhereInput[]
|
||||
NOT?: Prisma.CustomerLegalWhereInput | Prisma.CustomerLegalWhereInput[]
|
||||
name?: Prisma.StringFilter<"CustomerLegal"> | string
|
||||
economic_code?: Prisma.StringFilter<"CustomerLegal"> | string
|
||||
name?: Prisma.StringNullableFilter<"CustomerLegal"> | string | null
|
||||
economic_code?: Prisma.StringNullableFilter<"CustomerLegal"> | string | null
|
||||
registration_number?: Prisma.StringNullableFilter<"CustomerLegal"> | string | null
|
||||
postal_code?: Prisma.StringFilter<"CustomerLegal"> | string
|
||||
postal_code?: Prisma.StringNullableFilter<"CustomerLegal"> | string | null
|
||||
business_activity_id?: Prisma.StringFilter<"CustomerLegal"> | string
|
||||
business_activity?: Prisma.XOR<Prisma.BusinessActivityScalarRelationFilter, Prisma.BusinessActivityWhereInput>
|
||||
customer?: Prisma.XOR<Prisma.CustomerScalarRelationFilter, Prisma.CustomerWhereInput>
|
||||
}, "customer_id" | "business_activity_id_economic_code">
|
||||
}, "customer_id" | "business_activity_id_economic_code" | "business_activity_id_postal_code_registration_number">
|
||||
|
||||
export type CustomerLegalOrderByWithAggregationInput = {
|
||||
name?: Prisma.SortOrder
|
||||
economic_code?: Prisma.SortOrder
|
||||
name?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
economic_code?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
registration_number?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
postal_code?: Prisma.SortOrder
|
||||
postal_code?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
customer_id?: Prisma.SortOrder
|
||||
business_activity_id?: Prisma.SortOrder
|
||||
_count?: Prisma.CustomerLegalCountOrderByAggregateInput
|
||||
@@ -237,71 +238,71 @@ export type CustomerLegalScalarWhereWithAggregatesInput = {
|
||||
AND?: Prisma.CustomerLegalScalarWhereWithAggregatesInput | Prisma.CustomerLegalScalarWhereWithAggregatesInput[]
|
||||
OR?: Prisma.CustomerLegalScalarWhereWithAggregatesInput[]
|
||||
NOT?: Prisma.CustomerLegalScalarWhereWithAggregatesInput | Prisma.CustomerLegalScalarWhereWithAggregatesInput[]
|
||||
name?: Prisma.StringWithAggregatesFilter<"CustomerLegal"> | string
|
||||
economic_code?: Prisma.StringWithAggregatesFilter<"CustomerLegal"> | string
|
||||
name?: Prisma.StringNullableWithAggregatesFilter<"CustomerLegal"> | string | null
|
||||
economic_code?: Prisma.StringNullableWithAggregatesFilter<"CustomerLegal"> | string | null
|
||||
registration_number?: Prisma.StringNullableWithAggregatesFilter<"CustomerLegal"> | string | null
|
||||
postal_code?: Prisma.StringWithAggregatesFilter<"CustomerLegal"> | string
|
||||
postal_code?: Prisma.StringNullableWithAggregatesFilter<"CustomerLegal"> | string | null
|
||||
customer_id?: Prisma.StringWithAggregatesFilter<"CustomerLegal"> | string
|
||||
business_activity_id?: Prisma.StringWithAggregatesFilter<"CustomerLegal"> | string
|
||||
}
|
||||
|
||||
export type CustomerLegalCreateInput = {
|
||||
name: string
|
||||
economic_code: string
|
||||
name?: string | null
|
||||
economic_code?: string | null
|
||||
registration_number?: string | null
|
||||
postal_code: string
|
||||
postal_code?: string | null
|
||||
business_activity: Prisma.BusinessActivityCreateNestedOneWithoutCustomer_legalsInput
|
||||
customer: Prisma.CustomerCreateNestedOneWithoutLegalInput
|
||||
}
|
||||
|
||||
export type CustomerLegalUncheckedCreateInput = {
|
||||
name: string
|
||||
economic_code: string
|
||||
name?: string | null
|
||||
economic_code?: string | null
|
||||
registration_number?: string | null
|
||||
postal_code: string
|
||||
postal_code?: string | null
|
||||
customer_id: string
|
||||
business_activity_id: string
|
||||
}
|
||||
|
||||
export type CustomerLegalUpdateInput = {
|
||||
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
economic_code?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
name?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
economic_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
registration_number?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
postal_code?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
postal_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
business_activity?: Prisma.BusinessActivityUpdateOneRequiredWithoutCustomer_legalsNestedInput
|
||||
customer?: Prisma.CustomerUpdateOneRequiredWithoutLegalNestedInput
|
||||
}
|
||||
|
||||
export type CustomerLegalUncheckedUpdateInput = {
|
||||
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
economic_code?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
name?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
economic_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
registration_number?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
postal_code?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
postal_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
customer_id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
business_activity_id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
}
|
||||
|
||||
export type CustomerLegalCreateManyInput = {
|
||||
name: string
|
||||
economic_code: string
|
||||
name?: string | null
|
||||
economic_code?: string | null
|
||||
registration_number?: string | null
|
||||
postal_code: string
|
||||
postal_code?: string | null
|
||||
customer_id: string
|
||||
business_activity_id: string
|
||||
}
|
||||
|
||||
export type CustomerLegalUpdateManyMutationInput = {
|
||||
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
economic_code?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
name?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
economic_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
registration_number?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
postal_code?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
postal_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
}
|
||||
|
||||
export type CustomerLegalUncheckedUpdateManyInput = {
|
||||
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
economic_code?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
name?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
economic_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
registration_number?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
postal_code?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
postal_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
customer_id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
business_activity_id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
}
|
||||
@@ -332,6 +333,12 @@ export type CustomerLegalBusiness_activity_idEconomic_codeCompoundUniqueInput =
|
||||
economic_code: string
|
||||
}
|
||||
|
||||
export type CustomerLegalBusiness_activity_idPostal_codeRegistration_numberCompoundUniqueInput = {
|
||||
business_activity_id: string
|
||||
postal_code: string
|
||||
registration_number: string
|
||||
}
|
||||
|
||||
export type CustomerLegalCountOrderByAggregateInput = {
|
||||
name?: Prisma.SortOrder
|
||||
economic_code?: Prisma.SortOrder
|
||||
@@ -434,18 +441,18 @@ export type CustomerLegalUncheckedUpdateOneWithoutCustomerNestedInput = {
|
||||
}
|
||||
|
||||
export type CustomerLegalCreateWithoutBusiness_activityInput = {
|
||||
name: string
|
||||
economic_code: string
|
||||
name?: string | null
|
||||
economic_code?: string | null
|
||||
registration_number?: string | null
|
||||
postal_code: string
|
||||
postal_code?: string | null
|
||||
customer: Prisma.CustomerCreateNestedOneWithoutLegalInput
|
||||
}
|
||||
|
||||
export type CustomerLegalUncheckedCreateWithoutBusiness_activityInput = {
|
||||
name: string
|
||||
economic_code: string
|
||||
name?: string | null
|
||||
economic_code?: string | null
|
||||
registration_number?: string | null
|
||||
postal_code: string
|
||||
postal_code?: string | null
|
||||
customer_id: string
|
||||
}
|
||||
|
||||
@@ -479,27 +486,27 @@ export type CustomerLegalScalarWhereInput = {
|
||||
AND?: Prisma.CustomerLegalScalarWhereInput | Prisma.CustomerLegalScalarWhereInput[]
|
||||
OR?: Prisma.CustomerLegalScalarWhereInput[]
|
||||
NOT?: Prisma.CustomerLegalScalarWhereInput | Prisma.CustomerLegalScalarWhereInput[]
|
||||
name?: Prisma.StringFilter<"CustomerLegal"> | string
|
||||
economic_code?: Prisma.StringFilter<"CustomerLegal"> | string
|
||||
name?: Prisma.StringNullableFilter<"CustomerLegal"> | string | null
|
||||
economic_code?: Prisma.StringNullableFilter<"CustomerLegal"> | string | null
|
||||
registration_number?: Prisma.StringNullableFilter<"CustomerLegal"> | string | null
|
||||
postal_code?: Prisma.StringFilter<"CustomerLegal"> | string
|
||||
postal_code?: Prisma.StringNullableFilter<"CustomerLegal"> | string | null
|
||||
customer_id?: Prisma.StringFilter<"CustomerLegal"> | string
|
||||
business_activity_id?: Prisma.StringFilter<"CustomerLegal"> | string
|
||||
}
|
||||
|
||||
export type CustomerLegalCreateWithoutCustomerInput = {
|
||||
name: string
|
||||
economic_code: string
|
||||
name?: string | null
|
||||
economic_code?: string | null
|
||||
registration_number?: string | null
|
||||
postal_code: string
|
||||
postal_code?: string | null
|
||||
business_activity: Prisma.BusinessActivityCreateNestedOneWithoutCustomer_legalsInput
|
||||
}
|
||||
|
||||
export type CustomerLegalUncheckedCreateWithoutCustomerInput = {
|
||||
name: string
|
||||
economic_code: string
|
||||
name?: string | null
|
||||
economic_code?: string | null
|
||||
registration_number?: string | null
|
||||
postal_code: string
|
||||
postal_code?: string | null
|
||||
business_activity_id: string
|
||||
}
|
||||
|
||||
@@ -520,50 +527,50 @@ export type CustomerLegalUpdateToOneWithWhereWithoutCustomerInput = {
|
||||
}
|
||||
|
||||
export type CustomerLegalUpdateWithoutCustomerInput = {
|
||||
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
economic_code?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
name?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
economic_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
registration_number?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
postal_code?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
postal_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
business_activity?: Prisma.BusinessActivityUpdateOneRequiredWithoutCustomer_legalsNestedInput
|
||||
}
|
||||
|
||||
export type CustomerLegalUncheckedUpdateWithoutCustomerInput = {
|
||||
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
economic_code?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
name?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
economic_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
registration_number?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
postal_code?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
postal_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
business_activity_id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
}
|
||||
|
||||
export type CustomerLegalCreateManyBusiness_activityInput = {
|
||||
name: string
|
||||
economic_code: string
|
||||
name?: string | null
|
||||
economic_code?: string | null
|
||||
registration_number?: string | null
|
||||
postal_code: string
|
||||
postal_code?: string | null
|
||||
customer_id: string
|
||||
}
|
||||
|
||||
export type CustomerLegalUpdateWithoutBusiness_activityInput = {
|
||||
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
economic_code?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
name?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
economic_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
registration_number?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
postal_code?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
postal_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
customer?: Prisma.CustomerUpdateOneRequiredWithoutLegalNestedInput
|
||||
}
|
||||
|
||||
export type CustomerLegalUncheckedUpdateWithoutBusiness_activityInput = {
|
||||
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
economic_code?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
name?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
economic_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
registration_number?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
postal_code?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
postal_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
customer_id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
}
|
||||
|
||||
export type CustomerLegalUncheckedUpdateManyWithoutBusiness_activityInput = {
|
||||
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
economic_code?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
name?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
economic_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
registration_number?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
postal_code?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
postal_code?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
customer_id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
}
|
||||
|
||||
@@ -604,10 +611,10 @@ export type $CustomerLegalPayload<ExtArgs extends runtime.Types.Extensions.Inter
|
||||
customer: Prisma.$CustomerPayload<ExtArgs>
|
||||
}
|
||||
scalars: runtime.Types.Extensions.GetPayloadResult<{
|
||||
name: string
|
||||
economic_code: string
|
||||
name: string | null
|
||||
economic_code: string | null
|
||||
registration_number: string | null
|
||||
postal_code: string
|
||||
postal_code: string | null
|
||||
customer_id: string
|
||||
business_activity_id: string
|
||||
}, ExtArgs["result"]["customerLegal"]>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -31,6 +31,7 @@ export type SalesInvoiceItemAvgAggregateOutputType = {
|
||||
sku_vat: runtime.Decimal | null
|
||||
unit_price: runtime.Decimal | null
|
||||
total_amount: runtime.Decimal | null
|
||||
discount: runtime.Decimal | null
|
||||
discount_amount: runtime.Decimal | null
|
||||
tax_amount: runtime.Decimal | null
|
||||
}
|
||||
@@ -40,6 +41,7 @@ export type SalesInvoiceItemSumAggregateOutputType = {
|
||||
sku_vat: runtime.Decimal | null
|
||||
unit_price: runtime.Decimal | null
|
||||
total_amount: runtime.Decimal | null
|
||||
discount: runtime.Decimal | null
|
||||
discount_amount: runtime.Decimal | null
|
||||
tax_amount: runtime.Decimal | null
|
||||
}
|
||||
@@ -54,12 +56,13 @@ export type SalesInvoiceItemMinAggregateOutputType = {
|
||||
unit_price: runtime.Decimal | null
|
||||
total_amount: runtime.Decimal | null
|
||||
created_at: Date | null
|
||||
discount_amount: runtime.Decimal | null
|
||||
tax_amount: runtime.Decimal | null
|
||||
discount: runtime.Decimal | null
|
||||
notes: string | null
|
||||
invoice_id: string | null
|
||||
good_id: string | null
|
||||
service_id: string | null
|
||||
discount_amount: runtime.Decimal | null
|
||||
tax_amount: runtime.Decimal | null
|
||||
}
|
||||
|
||||
export type SalesInvoiceItemMaxAggregateOutputType = {
|
||||
@@ -72,12 +75,13 @@ export type SalesInvoiceItemMaxAggregateOutputType = {
|
||||
unit_price: runtime.Decimal | null
|
||||
total_amount: runtime.Decimal | null
|
||||
created_at: Date | null
|
||||
discount_amount: runtime.Decimal | null
|
||||
tax_amount: runtime.Decimal | null
|
||||
discount: runtime.Decimal | null
|
||||
notes: string | null
|
||||
invoice_id: string | null
|
||||
good_id: string | null
|
||||
service_id: string | null
|
||||
discount_amount: runtime.Decimal | null
|
||||
tax_amount: runtime.Decimal | null
|
||||
}
|
||||
|
||||
export type SalesInvoiceItemCountAggregateOutputType = {
|
||||
@@ -90,14 +94,15 @@ export type SalesInvoiceItemCountAggregateOutputType = {
|
||||
unit_price: number
|
||||
total_amount: number
|
||||
created_at: number
|
||||
discount_amount: number
|
||||
tax_amount: number
|
||||
discount: number
|
||||
notes: number
|
||||
payload: number
|
||||
good_snapshot: number
|
||||
invoice_id: number
|
||||
good_id: number
|
||||
service_id: number
|
||||
discount_amount: number
|
||||
tax_amount: number
|
||||
_all: number
|
||||
}
|
||||
|
||||
@@ -107,6 +112,7 @@ export type SalesInvoiceItemAvgAggregateInputType = {
|
||||
sku_vat?: true
|
||||
unit_price?: true
|
||||
total_amount?: true
|
||||
discount?: true
|
||||
discount_amount?: true
|
||||
tax_amount?: true
|
||||
}
|
||||
@@ -116,6 +122,7 @@ export type SalesInvoiceItemSumAggregateInputType = {
|
||||
sku_vat?: true
|
||||
unit_price?: true
|
||||
total_amount?: true
|
||||
discount?: true
|
||||
discount_amount?: true
|
||||
tax_amount?: true
|
||||
}
|
||||
@@ -130,12 +137,13 @@ export type SalesInvoiceItemMinAggregateInputType = {
|
||||
unit_price?: true
|
||||
total_amount?: true
|
||||
created_at?: true
|
||||
discount_amount?: true
|
||||
tax_amount?: true
|
||||
discount?: true
|
||||
notes?: true
|
||||
invoice_id?: true
|
||||
good_id?: true
|
||||
service_id?: true
|
||||
discount_amount?: true
|
||||
tax_amount?: true
|
||||
}
|
||||
|
||||
export type SalesInvoiceItemMaxAggregateInputType = {
|
||||
@@ -148,12 +156,13 @@ export type SalesInvoiceItemMaxAggregateInputType = {
|
||||
unit_price?: true
|
||||
total_amount?: true
|
||||
created_at?: true
|
||||
discount_amount?: true
|
||||
tax_amount?: true
|
||||
discount?: true
|
||||
notes?: true
|
||||
invoice_id?: true
|
||||
good_id?: true
|
||||
service_id?: true
|
||||
discount_amount?: true
|
||||
tax_amount?: true
|
||||
}
|
||||
|
||||
export type SalesInvoiceItemCountAggregateInputType = {
|
||||
@@ -166,14 +175,15 @@ export type SalesInvoiceItemCountAggregateInputType = {
|
||||
unit_price?: true
|
||||
total_amount?: true
|
||||
created_at?: true
|
||||
discount_amount?: true
|
||||
tax_amount?: true
|
||||
discount?: true
|
||||
notes?: true
|
||||
payload?: true
|
||||
good_snapshot?: true
|
||||
invoice_id?: true
|
||||
good_id?: true
|
||||
service_id?: true
|
||||
discount_amount?: true
|
||||
tax_amount?: true
|
||||
_all?: true
|
||||
}
|
||||
|
||||
@@ -273,14 +283,15 @@ export type SalesInvoiceItemGroupByOutputType = {
|
||||
unit_price: runtime.Decimal
|
||||
total_amount: runtime.Decimal
|
||||
created_at: Date
|
||||
discount_amount: runtime.Decimal
|
||||
tax_amount: runtime.Decimal
|
||||
discount: runtime.Decimal
|
||||
notes: string | null
|
||||
payload: runtime.JsonValue | null
|
||||
good_snapshot: runtime.JsonValue
|
||||
invoice_id: string
|
||||
good_id: string
|
||||
service_id: string | null
|
||||
discount_amount: runtime.Decimal | null
|
||||
tax_amount: runtime.Decimal | null
|
||||
_count: SalesInvoiceItemCountAggregateOutputType | null
|
||||
_avg: SalesInvoiceItemAvgAggregateOutputType | null
|
||||
_sum: SalesInvoiceItemSumAggregateOutputType | null
|
||||
@@ -316,14 +327,15 @@ export type SalesInvoiceItemWhereInput = {
|
||||
unit_price?: Prisma.DecimalFilter<"SalesInvoiceItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total_amount?: Prisma.DecimalFilter<"SalesInvoiceItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
created_at?: Prisma.DateTimeFilter<"SalesInvoiceItem"> | Date | string
|
||||
discount_amount?: Prisma.DecimalFilter<"SalesInvoiceItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
tax_amount?: Prisma.DecimalFilter<"SalesInvoiceItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
discount?: Prisma.DecimalFilter<"SalesInvoiceItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
notes?: Prisma.StringNullableFilter<"SalesInvoiceItem"> | string | null
|
||||
payload?: Prisma.JsonNullableFilter<"SalesInvoiceItem">
|
||||
good_snapshot?: Prisma.JsonFilter<"SalesInvoiceItem">
|
||||
invoice_id?: Prisma.StringFilter<"SalesInvoiceItem"> | string
|
||||
good_id?: Prisma.StringFilter<"SalesInvoiceItem"> | string
|
||||
service_id?: Prisma.StringNullableFilter<"SalesInvoiceItem"> | string | null
|
||||
discount_amount?: Prisma.DecimalNullableFilter<"SalesInvoiceItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
tax_amount?: Prisma.DecimalNullableFilter<"SalesInvoiceItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
good?: Prisma.XOR<Prisma.GoodScalarRelationFilter, Prisma.GoodWhereInput>
|
||||
invoice?: Prisma.XOR<Prisma.SalesInvoiceScalarRelationFilter, Prisma.SalesInvoiceWhereInput>
|
||||
service?: Prisma.XOR<Prisma.ServiceNullableScalarRelationFilter, Prisma.ServiceWhereInput> | null
|
||||
@@ -339,14 +351,15 @@ export type SalesInvoiceItemOrderByWithRelationInput = {
|
||||
unit_price?: Prisma.SortOrder
|
||||
total_amount?: Prisma.SortOrder
|
||||
created_at?: Prisma.SortOrder
|
||||
discount_amount?: Prisma.SortOrder
|
||||
tax_amount?: Prisma.SortOrder
|
||||
discount?: Prisma.SortOrder
|
||||
notes?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
payload?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
good_snapshot?: Prisma.SortOrder
|
||||
invoice_id?: Prisma.SortOrder
|
||||
good_id?: Prisma.SortOrder
|
||||
service_id?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
discount_amount?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
tax_amount?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
good?: Prisma.GoodOrderByWithRelationInput
|
||||
invoice?: Prisma.SalesInvoiceOrderByWithRelationInput
|
||||
service?: Prisma.ServiceOrderByWithRelationInput
|
||||
@@ -366,14 +379,15 @@ export type SalesInvoiceItemWhereUniqueInput = Prisma.AtLeast<{
|
||||
unit_price?: Prisma.DecimalFilter<"SalesInvoiceItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total_amount?: Prisma.DecimalFilter<"SalesInvoiceItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
created_at?: Prisma.DateTimeFilter<"SalesInvoiceItem"> | Date | string
|
||||
discount_amount?: Prisma.DecimalFilter<"SalesInvoiceItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
tax_amount?: Prisma.DecimalFilter<"SalesInvoiceItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
discount?: Prisma.DecimalFilter<"SalesInvoiceItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
notes?: Prisma.StringNullableFilter<"SalesInvoiceItem"> | string | null
|
||||
payload?: Prisma.JsonNullableFilter<"SalesInvoiceItem">
|
||||
good_snapshot?: Prisma.JsonFilter<"SalesInvoiceItem">
|
||||
invoice_id?: Prisma.StringFilter<"SalesInvoiceItem"> | string
|
||||
good_id?: Prisma.StringFilter<"SalesInvoiceItem"> | string
|
||||
service_id?: Prisma.StringNullableFilter<"SalesInvoiceItem"> | string | null
|
||||
discount_amount?: Prisma.DecimalNullableFilter<"SalesInvoiceItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
tax_amount?: Prisma.DecimalNullableFilter<"SalesInvoiceItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
good?: Prisma.XOR<Prisma.GoodScalarRelationFilter, Prisma.GoodWhereInput>
|
||||
invoice?: Prisma.XOR<Prisma.SalesInvoiceScalarRelationFilter, Prisma.SalesInvoiceWhereInput>
|
||||
service?: Prisma.XOR<Prisma.ServiceNullableScalarRelationFilter, Prisma.ServiceWhereInput> | null
|
||||
@@ -389,14 +403,15 @@ export type SalesInvoiceItemOrderByWithAggregationInput = {
|
||||
unit_price?: Prisma.SortOrder
|
||||
total_amount?: Prisma.SortOrder
|
||||
created_at?: Prisma.SortOrder
|
||||
discount_amount?: Prisma.SortOrder
|
||||
tax_amount?: Prisma.SortOrder
|
||||
discount?: Prisma.SortOrder
|
||||
notes?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
payload?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
good_snapshot?: Prisma.SortOrder
|
||||
invoice_id?: Prisma.SortOrder
|
||||
good_id?: Prisma.SortOrder
|
||||
service_id?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
discount_amount?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
tax_amount?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
_count?: Prisma.SalesInvoiceItemCountOrderByAggregateInput
|
||||
_avg?: Prisma.SalesInvoiceItemAvgOrderByAggregateInput
|
||||
_max?: Prisma.SalesInvoiceItemMaxOrderByAggregateInput
|
||||
@@ -417,14 +432,15 @@ export type SalesInvoiceItemScalarWhereWithAggregatesInput = {
|
||||
unit_price?: Prisma.DecimalWithAggregatesFilter<"SalesInvoiceItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total_amount?: Prisma.DecimalWithAggregatesFilter<"SalesInvoiceItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
created_at?: Prisma.DateTimeWithAggregatesFilter<"SalesInvoiceItem"> | Date | string
|
||||
discount_amount?: Prisma.DecimalWithAggregatesFilter<"SalesInvoiceItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
tax_amount?: Prisma.DecimalWithAggregatesFilter<"SalesInvoiceItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
discount?: Prisma.DecimalWithAggregatesFilter<"SalesInvoiceItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
notes?: Prisma.StringNullableWithAggregatesFilter<"SalesInvoiceItem"> | string | null
|
||||
payload?: Prisma.JsonNullableWithAggregatesFilter<"SalesInvoiceItem">
|
||||
good_snapshot?: Prisma.JsonWithAggregatesFilter<"SalesInvoiceItem">
|
||||
invoice_id?: Prisma.StringWithAggregatesFilter<"SalesInvoiceItem"> | string
|
||||
good_id?: Prisma.StringWithAggregatesFilter<"SalesInvoiceItem"> | string
|
||||
service_id?: Prisma.StringNullableWithAggregatesFilter<"SalesInvoiceItem"> | string | null
|
||||
discount_amount?: Prisma.DecimalNullableWithAggregatesFilter<"SalesInvoiceItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
tax_amount?: Prisma.DecimalNullableWithAggregatesFilter<"SalesInvoiceItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
}
|
||||
|
||||
export type SalesInvoiceItemCreateInput = {
|
||||
@@ -437,11 +453,12 @@ export type SalesInvoiceItemCreateInput = {
|
||||
unit_price?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
created_at?: Date | string
|
||||
discount_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
tax_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
discount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
notes?: string | null
|
||||
payload?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue
|
||||
good_snapshot: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||
discount_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
tax_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
good: Prisma.GoodCreateNestedOneWithoutSales_invoice_itemsInput
|
||||
invoice: Prisma.SalesInvoiceCreateNestedOneWithoutItemsInput
|
||||
service?: Prisma.ServiceCreateNestedOneWithoutSales_invoice_itemsInput
|
||||
@@ -457,14 +474,15 @@ export type SalesInvoiceItemUncheckedCreateInput = {
|
||||
unit_price?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
created_at?: Date | string
|
||||
discount_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
tax_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
discount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
notes?: string | null
|
||||
payload?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue
|
||||
good_snapshot: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||
invoice_id: string
|
||||
good_id: string
|
||||
service_id?: string | null
|
||||
discount_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
tax_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
}
|
||||
|
||||
export type SalesInvoiceItemUpdateInput = {
|
||||
@@ -477,11 +495,12 @@ export type SalesInvoiceItemUpdateInput = {
|
||||
unit_price?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
created_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
discount_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
tax_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
discount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
notes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
payload?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue
|
||||
good_snapshot?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||
discount_amount?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
tax_amount?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
good?: Prisma.GoodUpdateOneRequiredWithoutSales_invoice_itemsNestedInput
|
||||
invoice?: Prisma.SalesInvoiceUpdateOneRequiredWithoutItemsNestedInput
|
||||
service?: Prisma.ServiceUpdateOneWithoutSales_invoice_itemsNestedInput
|
||||
@@ -497,14 +516,15 @@ export type SalesInvoiceItemUncheckedUpdateInput = {
|
||||
unit_price?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
created_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
discount_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
tax_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
discount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
notes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
payload?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue
|
||||
good_snapshot?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||
invoice_id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
good_id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
service_id?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
discount_amount?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
tax_amount?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
}
|
||||
|
||||
export type SalesInvoiceItemCreateManyInput = {
|
||||
@@ -517,14 +537,15 @@ export type SalesInvoiceItemCreateManyInput = {
|
||||
unit_price?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
created_at?: Date | string
|
||||
discount_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
tax_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
discount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
notes?: string | null
|
||||
payload?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue
|
||||
good_snapshot: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||
invoice_id: string
|
||||
good_id: string
|
||||
service_id?: string | null
|
||||
discount_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
tax_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
}
|
||||
|
||||
export type SalesInvoiceItemUpdateManyMutationInput = {
|
||||
@@ -537,11 +558,12 @@ export type SalesInvoiceItemUpdateManyMutationInput = {
|
||||
unit_price?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
created_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
discount_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
tax_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
discount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
notes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
payload?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue
|
||||
good_snapshot?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||
discount_amount?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
tax_amount?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
}
|
||||
|
||||
export type SalesInvoiceItemUncheckedUpdateManyInput = {
|
||||
@@ -554,14 +576,15 @@ export type SalesInvoiceItemUncheckedUpdateManyInput = {
|
||||
unit_price?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
created_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
discount_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
tax_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
discount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
notes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
payload?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue
|
||||
good_snapshot?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||
invoice_id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
good_id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
service_id?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
discount_amount?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
tax_amount?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
}
|
||||
|
||||
export type SalesInvoiceItemListRelationFilter = {
|
||||
@@ -590,14 +613,15 @@ export type SalesInvoiceItemCountOrderByAggregateInput = {
|
||||
unit_price?: Prisma.SortOrder
|
||||
total_amount?: Prisma.SortOrder
|
||||
created_at?: Prisma.SortOrder
|
||||
discount_amount?: Prisma.SortOrder
|
||||
tax_amount?: Prisma.SortOrder
|
||||
discount?: Prisma.SortOrder
|
||||
notes?: Prisma.SortOrder
|
||||
payload?: Prisma.SortOrder
|
||||
good_snapshot?: Prisma.SortOrder
|
||||
invoice_id?: Prisma.SortOrder
|
||||
good_id?: Prisma.SortOrder
|
||||
service_id?: Prisma.SortOrder
|
||||
discount_amount?: Prisma.SortOrder
|
||||
tax_amount?: Prisma.SortOrder
|
||||
}
|
||||
|
||||
export type SalesInvoiceItemAvgOrderByAggregateInput = {
|
||||
@@ -605,6 +629,7 @@ export type SalesInvoiceItemAvgOrderByAggregateInput = {
|
||||
sku_vat?: Prisma.SortOrder
|
||||
unit_price?: Prisma.SortOrder
|
||||
total_amount?: Prisma.SortOrder
|
||||
discount?: Prisma.SortOrder
|
||||
discount_amount?: Prisma.SortOrder
|
||||
tax_amount?: Prisma.SortOrder
|
||||
}
|
||||
@@ -619,12 +644,13 @@ export type SalesInvoiceItemMaxOrderByAggregateInput = {
|
||||
unit_price?: Prisma.SortOrder
|
||||
total_amount?: Prisma.SortOrder
|
||||
created_at?: Prisma.SortOrder
|
||||
discount_amount?: Prisma.SortOrder
|
||||
tax_amount?: Prisma.SortOrder
|
||||
discount?: Prisma.SortOrder
|
||||
notes?: Prisma.SortOrder
|
||||
invoice_id?: Prisma.SortOrder
|
||||
good_id?: Prisma.SortOrder
|
||||
service_id?: Prisma.SortOrder
|
||||
discount_amount?: Prisma.SortOrder
|
||||
tax_amount?: Prisma.SortOrder
|
||||
}
|
||||
|
||||
export type SalesInvoiceItemMinOrderByAggregateInput = {
|
||||
@@ -637,12 +663,13 @@ export type SalesInvoiceItemMinOrderByAggregateInput = {
|
||||
unit_price?: Prisma.SortOrder
|
||||
total_amount?: Prisma.SortOrder
|
||||
created_at?: Prisma.SortOrder
|
||||
discount_amount?: Prisma.SortOrder
|
||||
tax_amount?: Prisma.SortOrder
|
||||
discount?: Prisma.SortOrder
|
||||
notes?: Prisma.SortOrder
|
||||
invoice_id?: Prisma.SortOrder
|
||||
good_id?: Prisma.SortOrder
|
||||
service_id?: Prisma.SortOrder
|
||||
discount_amount?: Prisma.SortOrder
|
||||
tax_amount?: Prisma.SortOrder
|
||||
}
|
||||
|
||||
export type SalesInvoiceItemSumOrderByAggregateInput = {
|
||||
@@ -650,6 +677,7 @@ export type SalesInvoiceItemSumOrderByAggregateInput = {
|
||||
sku_vat?: Prisma.SortOrder
|
||||
unit_price?: Prisma.SortOrder
|
||||
total_amount?: Prisma.SortOrder
|
||||
discount?: Prisma.SortOrder
|
||||
discount_amount?: Prisma.SortOrder
|
||||
tax_amount?: Prisma.SortOrder
|
||||
}
|
||||
@@ -790,11 +818,12 @@ export type SalesInvoiceItemCreateWithoutGoodInput = {
|
||||
unit_price?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
created_at?: Date | string
|
||||
discount_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
tax_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
discount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
notes?: string | null
|
||||
payload?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue
|
||||
good_snapshot: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||
discount_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
tax_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
invoice: Prisma.SalesInvoiceCreateNestedOneWithoutItemsInput
|
||||
service?: Prisma.ServiceCreateNestedOneWithoutSales_invoice_itemsInput
|
||||
}
|
||||
@@ -809,13 +838,14 @@ export type SalesInvoiceItemUncheckedCreateWithoutGoodInput = {
|
||||
unit_price?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
created_at?: Date | string
|
||||
discount_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
tax_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
discount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
notes?: string | null
|
||||
payload?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue
|
||||
good_snapshot: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||
invoice_id: string
|
||||
service_id?: string | null
|
||||
discount_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
tax_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
}
|
||||
|
||||
export type SalesInvoiceItemCreateOrConnectWithoutGoodInput = {
|
||||
@@ -857,14 +887,15 @@ export type SalesInvoiceItemScalarWhereInput = {
|
||||
unit_price?: Prisma.DecimalFilter<"SalesInvoiceItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total_amount?: Prisma.DecimalFilter<"SalesInvoiceItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
created_at?: Prisma.DateTimeFilter<"SalesInvoiceItem"> | Date | string
|
||||
discount_amount?: Prisma.DecimalFilter<"SalesInvoiceItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
tax_amount?: Prisma.DecimalFilter<"SalesInvoiceItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
discount?: Prisma.DecimalFilter<"SalesInvoiceItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
notes?: Prisma.StringNullableFilter<"SalesInvoiceItem"> | string | null
|
||||
payload?: Prisma.JsonNullableFilter<"SalesInvoiceItem">
|
||||
good_snapshot?: Prisma.JsonFilter<"SalesInvoiceItem">
|
||||
invoice_id?: Prisma.StringFilter<"SalesInvoiceItem"> | string
|
||||
good_id?: Prisma.StringFilter<"SalesInvoiceItem"> | string
|
||||
service_id?: Prisma.StringNullableFilter<"SalesInvoiceItem"> | string | null
|
||||
discount_amount?: Prisma.DecimalNullableFilter<"SalesInvoiceItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
tax_amount?: Prisma.DecimalNullableFilter<"SalesInvoiceItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
}
|
||||
|
||||
export type SalesInvoiceItemCreateWithoutInvoiceInput = {
|
||||
@@ -877,11 +908,12 @@ export type SalesInvoiceItemCreateWithoutInvoiceInput = {
|
||||
unit_price?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
created_at?: Date | string
|
||||
discount_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
tax_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
discount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
notes?: string | null
|
||||
payload?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue
|
||||
good_snapshot: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||
discount_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
tax_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
good: Prisma.GoodCreateNestedOneWithoutSales_invoice_itemsInput
|
||||
service?: Prisma.ServiceCreateNestedOneWithoutSales_invoice_itemsInput
|
||||
}
|
||||
@@ -896,13 +928,14 @@ export type SalesInvoiceItemUncheckedCreateWithoutInvoiceInput = {
|
||||
unit_price?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
created_at?: Date | string
|
||||
discount_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
tax_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
discount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
notes?: string | null
|
||||
payload?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue
|
||||
good_snapshot: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||
good_id: string
|
||||
service_id?: string | null
|
||||
discount_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
tax_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
}
|
||||
|
||||
export type SalesInvoiceItemCreateOrConnectWithoutInvoiceInput = {
|
||||
@@ -941,11 +974,12 @@ export type SalesInvoiceItemCreateWithoutServiceInput = {
|
||||
unit_price?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
created_at?: Date | string
|
||||
discount_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
tax_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
discount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
notes?: string | null
|
||||
payload?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue
|
||||
good_snapshot: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||
discount_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
tax_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
good: Prisma.GoodCreateNestedOneWithoutSales_invoice_itemsInput
|
||||
invoice: Prisma.SalesInvoiceCreateNestedOneWithoutItemsInput
|
||||
}
|
||||
@@ -960,13 +994,14 @@ export type SalesInvoiceItemUncheckedCreateWithoutServiceInput = {
|
||||
unit_price?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
created_at?: Date | string
|
||||
discount_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
tax_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
discount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
notes?: string | null
|
||||
payload?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue
|
||||
good_snapshot: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||
invoice_id: string
|
||||
good_id: string
|
||||
discount_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
tax_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
}
|
||||
|
||||
export type SalesInvoiceItemCreateOrConnectWithoutServiceInput = {
|
||||
@@ -1005,13 +1040,14 @@ export type SalesInvoiceItemCreateManyGoodInput = {
|
||||
unit_price?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
created_at?: Date | string
|
||||
discount_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
tax_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
discount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
notes?: string | null
|
||||
payload?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue
|
||||
good_snapshot: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||
invoice_id: string
|
||||
service_id?: string | null
|
||||
discount_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
tax_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
}
|
||||
|
||||
export type SalesInvoiceItemUpdateWithoutGoodInput = {
|
||||
@@ -1024,11 +1060,12 @@ export type SalesInvoiceItemUpdateWithoutGoodInput = {
|
||||
unit_price?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
created_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
discount_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
tax_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
discount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
notes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
payload?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue
|
||||
good_snapshot?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||
discount_amount?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
tax_amount?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
invoice?: Prisma.SalesInvoiceUpdateOneRequiredWithoutItemsNestedInput
|
||||
service?: Prisma.ServiceUpdateOneWithoutSales_invoice_itemsNestedInput
|
||||
}
|
||||
@@ -1043,13 +1080,14 @@ export type SalesInvoiceItemUncheckedUpdateWithoutGoodInput = {
|
||||
unit_price?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
created_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
discount_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
tax_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
discount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
notes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
payload?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue
|
||||
good_snapshot?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||
invoice_id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
service_id?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
discount_amount?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
tax_amount?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
}
|
||||
|
||||
export type SalesInvoiceItemUncheckedUpdateManyWithoutGoodInput = {
|
||||
@@ -1062,13 +1100,14 @@ export type SalesInvoiceItemUncheckedUpdateManyWithoutGoodInput = {
|
||||
unit_price?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
created_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
discount_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
tax_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
discount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
notes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
payload?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue
|
||||
good_snapshot?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||
invoice_id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
service_id?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
discount_amount?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
tax_amount?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
}
|
||||
|
||||
export type SalesInvoiceItemCreateManyInvoiceInput = {
|
||||
@@ -1081,13 +1120,14 @@ export type SalesInvoiceItemCreateManyInvoiceInput = {
|
||||
unit_price?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
created_at?: Date | string
|
||||
discount_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
tax_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
discount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
notes?: string | null
|
||||
payload?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue
|
||||
good_snapshot: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||
good_id: string
|
||||
service_id?: string | null
|
||||
discount_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
tax_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
}
|
||||
|
||||
export type SalesInvoiceItemUpdateWithoutInvoiceInput = {
|
||||
@@ -1100,11 +1140,12 @@ export type SalesInvoiceItemUpdateWithoutInvoiceInput = {
|
||||
unit_price?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
created_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
discount_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
tax_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
discount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
notes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
payload?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue
|
||||
good_snapshot?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||
discount_amount?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
tax_amount?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
good?: Prisma.GoodUpdateOneRequiredWithoutSales_invoice_itemsNestedInput
|
||||
service?: Prisma.ServiceUpdateOneWithoutSales_invoice_itemsNestedInput
|
||||
}
|
||||
@@ -1119,13 +1160,14 @@ export type SalesInvoiceItemUncheckedUpdateWithoutInvoiceInput = {
|
||||
unit_price?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
created_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
discount_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
tax_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
discount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
notes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
payload?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue
|
||||
good_snapshot?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||
good_id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
service_id?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
discount_amount?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
tax_amount?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
}
|
||||
|
||||
export type SalesInvoiceItemUncheckedUpdateManyWithoutInvoiceInput = {
|
||||
@@ -1138,13 +1180,14 @@ export type SalesInvoiceItemUncheckedUpdateManyWithoutInvoiceInput = {
|
||||
unit_price?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
created_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
discount_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
tax_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
discount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
notes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
payload?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue
|
||||
good_snapshot?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||
good_id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
service_id?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
discount_amount?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
tax_amount?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
}
|
||||
|
||||
export type SalesInvoiceItemCreateManyServiceInput = {
|
||||
@@ -1157,13 +1200,14 @@ export type SalesInvoiceItemCreateManyServiceInput = {
|
||||
unit_price?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
created_at?: Date | string
|
||||
discount_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
tax_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
discount?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
notes?: string | null
|
||||
payload?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue
|
||||
good_snapshot: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||
invoice_id: string
|
||||
good_id: string
|
||||
discount_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
tax_amount?: runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
}
|
||||
|
||||
export type SalesInvoiceItemUpdateWithoutServiceInput = {
|
||||
@@ -1176,11 +1220,12 @@ export type SalesInvoiceItemUpdateWithoutServiceInput = {
|
||||
unit_price?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
created_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
discount_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
tax_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
discount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
notes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
payload?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue
|
||||
good_snapshot?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||
discount_amount?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
tax_amount?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
good?: Prisma.GoodUpdateOneRequiredWithoutSales_invoice_itemsNestedInput
|
||||
invoice?: Prisma.SalesInvoiceUpdateOneRequiredWithoutItemsNestedInput
|
||||
}
|
||||
@@ -1195,13 +1240,14 @@ export type SalesInvoiceItemUncheckedUpdateWithoutServiceInput = {
|
||||
unit_price?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
created_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
discount_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
tax_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
discount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
notes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
payload?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue
|
||||
good_snapshot?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||
invoice_id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
good_id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
discount_amount?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
tax_amount?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
}
|
||||
|
||||
export type SalesInvoiceItemUncheckedUpdateManyWithoutServiceInput = {
|
||||
@@ -1214,13 +1260,14 @@ export type SalesInvoiceItemUncheckedUpdateManyWithoutServiceInput = {
|
||||
unit_price?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
total_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
created_at?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
discount_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
tax_amount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
discount?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
notes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
payload?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue
|
||||
good_snapshot?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||
invoice_id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
good_id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
discount_amount?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
tax_amount?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
}
|
||||
|
||||
|
||||
@@ -1235,14 +1282,15 @@ export type SalesInvoiceItemSelect<ExtArgs extends runtime.Types.Extensions.Inte
|
||||
unit_price?: boolean
|
||||
total_amount?: boolean
|
||||
created_at?: boolean
|
||||
discount_amount?: boolean
|
||||
tax_amount?: boolean
|
||||
discount?: boolean
|
||||
notes?: boolean
|
||||
payload?: boolean
|
||||
good_snapshot?: boolean
|
||||
invoice_id?: boolean
|
||||
good_id?: boolean
|
||||
service_id?: boolean
|
||||
discount_amount?: boolean
|
||||
tax_amount?: boolean
|
||||
good?: boolean | Prisma.GoodDefaultArgs<ExtArgs>
|
||||
invoice?: boolean | Prisma.SalesInvoiceDefaultArgs<ExtArgs>
|
||||
service?: boolean | Prisma.SalesInvoiceItem$serviceArgs<ExtArgs>
|
||||
@@ -1260,17 +1308,18 @@ export type SalesInvoiceItemSelectScalar = {
|
||||
unit_price?: boolean
|
||||
total_amount?: boolean
|
||||
created_at?: boolean
|
||||
discount_amount?: boolean
|
||||
tax_amount?: boolean
|
||||
discount?: boolean
|
||||
notes?: boolean
|
||||
payload?: boolean
|
||||
good_snapshot?: boolean
|
||||
invoice_id?: boolean
|
||||
good_id?: boolean
|
||||
service_id?: boolean
|
||||
discount_amount?: boolean
|
||||
tax_amount?: boolean
|
||||
}
|
||||
|
||||
export type SalesInvoiceItemOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "quantity" | "measure_unit_text" | "measure_unit_code" | "sku_code" | "sku_vat" | "unit_price" | "total_amount" | "created_at" | "discount_amount" | "tax_amount" | "notes" | "payload" | "good_snapshot" | "invoice_id" | "good_id" | "service_id", ExtArgs["result"]["salesInvoiceItem"]>
|
||||
export type SalesInvoiceItemOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "quantity" | "measure_unit_text" | "measure_unit_code" | "sku_code" | "sku_vat" | "unit_price" | "total_amount" | "created_at" | "discount" | "notes" | "payload" | "good_snapshot" | "invoice_id" | "good_id" | "service_id" | "discount_amount" | "tax_amount", ExtArgs["result"]["salesInvoiceItem"]>
|
||||
export type SalesInvoiceItemInclude<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
good?: boolean | Prisma.GoodDefaultArgs<ExtArgs>
|
||||
invoice?: boolean | Prisma.SalesInvoiceDefaultArgs<ExtArgs>
|
||||
@@ -1294,14 +1343,15 @@ export type $SalesInvoiceItemPayload<ExtArgs extends runtime.Types.Extensions.In
|
||||
unit_price: runtime.Decimal
|
||||
total_amount: runtime.Decimal
|
||||
created_at: Date
|
||||
discount_amount: runtime.Decimal
|
||||
tax_amount: runtime.Decimal
|
||||
discount: runtime.Decimal
|
||||
notes: string | null
|
||||
payload: runtime.JsonValue | null
|
||||
good_snapshot: runtime.JsonValue
|
||||
invoice_id: string
|
||||
good_id: string
|
||||
service_id: string | null
|
||||
discount_amount: runtime.Decimal | null
|
||||
tax_amount: runtime.Decimal | null
|
||||
}, ExtArgs["result"]["salesInvoiceItem"]>
|
||||
composites: {}
|
||||
}
|
||||
@@ -1683,14 +1733,15 @@ export interface SalesInvoiceItemFieldRefs {
|
||||
readonly unit_price: Prisma.FieldRef<"SalesInvoiceItem", 'Decimal'>
|
||||
readonly total_amount: Prisma.FieldRef<"SalesInvoiceItem", 'Decimal'>
|
||||
readonly created_at: Prisma.FieldRef<"SalesInvoiceItem", 'DateTime'>
|
||||
readonly discount_amount: Prisma.FieldRef<"SalesInvoiceItem", 'Decimal'>
|
||||
readonly tax_amount: Prisma.FieldRef<"SalesInvoiceItem", 'Decimal'>
|
||||
readonly discount: Prisma.FieldRef<"SalesInvoiceItem", 'Decimal'>
|
||||
readonly notes: Prisma.FieldRef<"SalesInvoiceItem", 'String'>
|
||||
readonly payload: Prisma.FieldRef<"SalesInvoiceItem", 'Json'>
|
||||
readonly good_snapshot: Prisma.FieldRef<"SalesInvoiceItem", 'Json'>
|
||||
readonly invoice_id: Prisma.FieldRef<"SalesInvoiceItem", 'String'>
|
||||
readonly good_id: Prisma.FieldRef<"SalesInvoiceItem", 'String'>
|
||||
readonly service_id: Prisma.FieldRef<"SalesInvoiceItem", 'String'>
|
||||
readonly discount_amount: Prisma.FieldRef<"SalesInvoiceItem", 'Decimal'>
|
||||
readonly tax_amount: Prisma.FieldRef<"SalesInvoiceItem", 'Decimal'>
|
||||
}
|
||||
|
||||
|
||||
|
||||
+7
-5
@@ -2,18 +2,20 @@ import { PrismaMariaDb } from '@prisma/adapter-mariadb'
|
||||
import 'dotenv/config'
|
||||
import { env } from 'prisma/config'
|
||||
|
||||
import { PrismaClient } from '../generated/prisma/client'
|
||||
|
||||
const adapter = new PrismaMariaDb({
|
||||
host: env('DATABASE_HOST'),
|
||||
user: env('DATABASE_USER'),
|
||||
password: env('DATABASE_PASSWORD'),
|
||||
database: env('DATABASE_NAME'),
|
||||
ssl: false,
|
||||
connectionLimit: 5,
|
||||
port: Number(env('DATABASE_PORT')) || 3306,
|
||||
allowPublicKeyRetrieval: true,
|
||||
ssl: {
|
||||
rejectUnauthorized: false,
|
||||
},
|
||||
connectTimeout: 10000,
|
||||
})
|
||||
|
||||
const prisma = new PrismaClient({ adapter })
|
||||
// const prisma = new PrismaClient({ adapter })
|
||||
|
||||
export { prisma }
|
||||
export { adapter as prismaAdapter }
|
||||
|
||||
+3
-2
@@ -17,6 +17,8 @@ const cookieParser = require('cookie-parser')
|
||||
async function bootstrap() {
|
||||
const app = await NestFactory.create(AppModule)
|
||||
|
||||
app.enableShutdownHooks()
|
||||
|
||||
app.use(cookieParser())
|
||||
|
||||
const config = new DocumentBuilder()
|
||||
@@ -33,6 +35,7 @@ async function bootstrap() {
|
||||
in: 'header',
|
||||
})
|
||||
.build()
|
||||
|
||||
const documentFactory = () => SwaggerModule.createDocument(app, config)
|
||||
SwaggerModule.setup('swagger', app, documentFactory, {
|
||||
swaggerOptions: {
|
||||
@@ -47,14 +50,12 @@ async function bootstrap() {
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// Set API prefix and enable URI versioning so alls routes live under /api/v1/*
|
||||
app.setGlobalPrefix('api')
|
||||
app.enableVersioning({
|
||||
type: VersioningType.URI,
|
||||
defaultVersion: '1',
|
||||
})
|
||||
|
||||
// Enable CORS. You can set `CORS_ORIGINS` to a comma-separated list of allowed origins.
|
||||
// Defaults include common localhost origins used by front-end dev servers.
|
||||
const defaultOrigins: string[] = []
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
import { Body, Controller, Get, Param, Patch, Post } from '@nestjs/common'
|
||||
import { ApiTags } from '@nestjs/swagger'
|
||||
import { AccountsService } from './accounts.service'
|
||||
import { CreateConsumerAccountDto, UpdateAccountDto } from './dto/account.dto'
|
||||
import type { AccountsServiceCreateResponseDto, AccountsServiceFindAllResponseDto, AccountsServiceFindOneResponseDto, AccountsServiceUpdateResponseDto } from './dto/accounts-response.dto'
|
||||
import {
|
||||
CreateAdminConsumerAccountDto,
|
||||
UpdateAdminConsumerAccountDto,
|
||||
} from './dto/account.dto'
|
||||
import type {
|
||||
AccountsServiceCreateResponseDto,
|
||||
AccountsServiceFindAllResponseDto,
|
||||
AccountsServiceFindOneResponseDto,
|
||||
AccountsServiceUpdateResponseDto,
|
||||
} from './dto/accounts-response.dto'
|
||||
|
||||
@ApiTags('AdminConsumerAccounts')
|
||||
@Controller('admin/consumers/:consumerId/accounts')
|
||||
@@ -10,7 +18,9 @@ export class AccountsController {
|
||||
constructor(private readonly accountsService: AccountsService) {}
|
||||
|
||||
@Get()
|
||||
async findAll(@Param('consumerId') consumerId: string): Promise<AccountsServiceFindAllResponseDto> {
|
||||
async findAll(
|
||||
@Param('consumerId') consumerId: string,
|
||||
): Promise<AccountsServiceFindAllResponseDto> {
|
||||
return this.accountsService.findAll(consumerId)
|
||||
}
|
||||
|
||||
@@ -22,13 +32,16 @@ export class AccountsController {
|
||||
@Post()
|
||||
async create(
|
||||
@Param('consumerId') consumerId: string,
|
||||
@Body() data: CreateConsumerAccountDto,
|
||||
@Body() data: CreateAdminConsumerAccountDto,
|
||||
): Promise<AccountsServiceCreateResponseDto> {
|
||||
return this.accountsService.create(consumerId, data)
|
||||
}
|
||||
|
||||
@Patch(':id')
|
||||
async update(@Param('id') id: string, @Body() data: UpdateAccountDto): Promise<AccountsServiceUpdateResponseDto> {
|
||||
async update(
|
||||
@Param('id') id: string,
|
||||
@Body() data: UpdateAdminConsumerAccountDto,
|
||||
): Promise<AccountsServiceUpdateResponseDto> {
|
||||
return this.accountsService.update(id, data)
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,10 @@ import { AccountStatus, AccountType } from '@/generated/prisma/enums'
|
||||
import { PrismaService } from '@/prisma/prisma.service'
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { ResponseMapper } from 'common/response/response-mapper'
|
||||
import { CreateConsumerAccountDto, UpdateAccountDto } from './dto/account.dto'
|
||||
import {
|
||||
CreateAdminConsumerAccountDto,
|
||||
UpdateAdminConsumerAccountDto,
|
||||
} from './dto/account.dto'
|
||||
|
||||
@Injectable()
|
||||
export class AccountsService {
|
||||
@@ -70,7 +73,7 @@ export class AccountsService {
|
||||
return ResponseMapper.single(account)
|
||||
}
|
||||
|
||||
async create(consumerId: string, data: CreateConsumerAccountDto) {
|
||||
async create(consumerId: string, data: CreateAdminConsumerAccountDto) {
|
||||
const account = await this.prisma.consumerAccount.create({
|
||||
data: {
|
||||
role: data.role,
|
||||
@@ -95,7 +98,7 @@ export class AccountsService {
|
||||
return ResponseMapper.create(account)
|
||||
}
|
||||
|
||||
async update(id: string, data: UpdateAccountDto) {
|
||||
async update(id: string, data: UpdateAdminConsumerAccountDto) {
|
||||
const account = await this.prisma.account.update({ where: { id }, data })
|
||||
return ResponseMapper.update(account)
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { ApiProperty, PartialType } from '@nestjs/swagger'
|
||||
import { IsEnum, IsOptional, IsString } from 'class-validator'
|
||||
import { AccountStatus, ConsumerRole } from 'generated/prisma/enums'
|
||||
|
||||
export class CreateConsumerAccountDto {
|
||||
export class CreateAdminConsumerAccountDto {
|
||||
@IsString()
|
||||
@UsernameFieldValidator()
|
||||
@ApiProperty({ required: true })
|
||||
@@ -19,7 +19,9 @@ export class CreateConsumerAccountDto {
|
||||
role: ConsumerRole
|
||||
}
|
||||
|
||||
export class UpdateAccountDto extends PartialType(CreateConsumerAccountDto) {
|
||||
export class UpdateAdminConsumerAccountDto extends PartialType(
|
||||
CreateAdminConsumerAccountDto,
|
||||
) {
|
||||
@IsOptional()
|
||||
@IsEnum(AccountStatus)
|
||||
@ApiProperty({ enum: AccountStatus })
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { SKUGuildType } from '@/common/enums/enums'
|
||||
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'
|
||||
import { Type } from 'class-transformer'
|
||||
import { IsBoolean, IsEnum, IsNumber, IsString, Min } from 'class-validator'
|
||||
import { IsBoolean, IsNumber, IsString, Min } from 'class-validator'
|
||||
|
||||
export class CreateStockKeepingUnitDto {
|
||||
@ApiProperty()
|
||||
@@ -18,9 +17,9 @@ export class CreateStockKeepingUnitDto {
|
||||
@Min(0)
|
||||
VAT: number
|
||||
|
||||
@ApiPropertyOptional({ enum: SKUGuildType, default: SKUGuildType.GOLD })
|
||||
@IsEnum(SKUGuildType)
|
||||
type: SKUGuildType = SKUGuildType.GOLD
|
||||
// @ApiPropertyOptional({ enum: SKUGuildType, default: SKUGuildType.GOLD })
|
||||
// @IsEnum(SKUGuildType)
|
||||
// type: SKUGuildType = SKUGuildType.GOLD
|
||||
|
||||
@ApiPropertyOptional({ default: true })
|
||||
@IsBoolean()
|
||||
|
||||
+3
-1
@@ -105,7 +105,9 @@ export class PartnerAccountChargeTransactionService {
|
||||
try {
|
||||
createdTransaction = await tx.partnerAccountQuotaChargeTransaction.create({
|
||||
data: {
|
||||
activation_expires_at: data.activated_expires_at,
|
||||
activation_expires_at: data.activated_expires_at
|
||||
? new Date(data.activated_expires_at).toISOString()
|
||||
: new Date().toISOString(),
|
||||
tracking_code: generateTrackingCode('AQC', this.TRACKING_CODE_LENGTH),
|
||||
purchased_count: data.quantity,
|
||||
partner: { connect: { id: partner_id } },
|
||||
|
||||
+3
-1
@@ -121,7 +121,9 @@ export class PartnerLicenseChargeTransactionService {
|
||||
try {
|
||||
createdTransaction = await tx.licenseChargeTransaction.create({
|
||||
data: {
|
||||
activation_expires_at: data.activated_expires_at,
|
||||
activation_expires_at: data.activated_expires_at
|
||||
? new Date(data.activated_expires_at).toISOString()
|
||||
: new Date().toISOString(),
|
||||
tracking_code: generateTrackingCode('LIC', this.TRACKING_CODE_LENGTH),
|
||||
purchased_count: data.quantity,
|
||||
partner: { connect: { id: partner_id } },
|
||||
|
||||
@@ -1,14 +1,25 @@
|
||||
import { Body, Controller, Delete, Get, Param, Patch, Post } from '@nestjs/common'
|
||||
import { AccountsService } from './accounts.service'
|
||||
import { CreatePartnerAccountDto, UpdateAccountDto } from './dto/account.dto'
|
||||
import type { AccountsServiceCreateResponseDto, AccountsServiceDeleteResponseDto, AccountsServiceFindAllResponseDto, AccountsServiceFindOneResponseDto, AccountsServiceUpdateResponseDto } from './dto/accounts-response.dto'
|
||||
import {
|
||||
CreateAdminPartnerAccountDto,
|
||||
UpdateAdminPartnerAccountDto,
|
||||
} from './dto/account.dto'
|
||||
import type {
|
||||
AccountsServiceCreateResponseDto,
|
||||
AccountsServiceDeleteResponseDto,
|
||||
AccountsServiceFindAllResponseDto,
|
||||
AccountsServiceFindOneResponseDto,
|
||||
AccountsServiceUpdateResponseDto,
|
||||
} from './dto/accounts-response.dto'
|
||||
|
||||
@Controller('admin/partners/:partnerId/accounts')
|
||||
export class AccountsController {
|
||||
constructor(private readonly accountsService: AccountsService) {}
|
||||
|
||||
@Get()
|
||||
async findAll(@Param('partnerId') partnerId: string): Promise<AccountsServiceFindAllResponseDto> {
|
||||
async findAll(
|
||||
@Param('partnerId') partnerId: string,
|
||||
): Promise<AccountsServiceFindAllResponseDto> {
|
||||
return this.accountsService.findAll(partnerId)
|
||||
}
|
||||
|
||||
@@ -20,13 +31,16 @@ export class AccountsController {
|
||||
@Post()
|
||||
async create(
|
||||
@Param('partnerId') partnerId: string,
|
||||
@Body() data: CreatePartnerAccountDto,
|
||||
@Body() data: CreateAdminPartnerAccountDto,
|
||||
): Promise<AccountsServiceCreateResponseDto> {
|
||||
return this.accountsService.create(partnerId, data)
|
||||
}
|
||||
|
||||
@Patch(':id')
|
||||
async update(@Param('id') id: string, @Body() data: UpdateAccountDto): Promise<AccountsServiceUpdateResponseDto> {
|
||||
async update(
|
||||
@Param('id') id: string,
|
||||
@Body() data: UpdateAdminPartnerAccountDto,
|
||||
): Promise<AccountsServiceUpdateResponseDto> {
|
||||
return this.accountsService.update(id, data)
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,10 @@ import { Injectable } from '@nestjs/common'
|
||||
import { ResponseMapper } from 'common/response/response-mapper'
|
||||
import { PasswordUtil } from 'common/utils/password.util'
|
||||
import { AccountStatus, AccountType, PartnerRole } from 'generated/prisma/enums'
|
||||
import { CreatePartnerAccountDto, UpdateAccountDto } from './dto/account.dto'
|
||||
import {
|
||||
CreateAdminPartnerAccountDto,
|
||||
UpdateAdminPartnerAccountDto,
|
||||
} from './dto/account.dto'
|
||||
|
||||
@Injectable()
|
||||
export class AccountsService {
|
||||
@@ -38,7 +41,7 @@ export class AccountsService {
|
||||
return ResponseMapper.single(account)
|
||||
}
|
||||
|
||||
async create(partnerId: string, data: CreatePartnerAccountDto) {
|
||||
async create(partnerId: string, data: CreateAdminPartnerAccountDto) {
|
||||
const { username, password } = data
|
||||
|
||||
const result = await this.prisma.$transaction(async tx => {
|
||||
@@ -69,7 +72,7 @@ export class AccountsService {
|
||||
return ResponseMapper.create(result)
|
||||
}
|
||||
|
||||
async update(id: string, data: UpdateAccountDto) {
|
||||
async update(id: string, data: UpdateAdminPartnerAccountDto) {
|
||||
const account = await this.prisma.account.update({ where: { id }, data })
|
||||
return ResponseMapper.update(account)
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { ApiProperty, PartialType } from '@nestjs/swagger'
|
||||
import { IsEnum, IsOptional, IsString } from 'class-validator'
|
||||
import { PartnerRole } from 'generated/prisma/enums'
|
||||
|
||||
export class CreatePartnerAccountDto {
|
||||
export class CreateAdminPartnerAccountDto {
|
||||
@IsString()
|
||||
@ApiProperty({})
|
||||
@UsernameFieldValidator()
|
||||
@@ -15,7 +15,9 @@ export class CreatePartnerAccountDto {
|
||||
password: string
|
||||
}
|
||||
|
||||
export class UpdateAccountDto extends PartialType(CreatePartnerAccountDto) {
|
||||
export class UpdateAdminPartnerAccountDto extends PartialType(
|
||||
CreateAdminPartnerAccountDto,
|
||||
) {
|
||||
@IsOptional()
|
||||
@IsEnum(PartnerRole)
|
||||
@ApiProperty({ enum: PartnerRole })
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
import { Body, Controller, Get, Param, Patch, Post } from '@nestjs/common'
|
||||
import { ApiTags } from '@nestjs/swagger'
|
||||
import { AccountsService } from './accounts.service'
|
||||
import { CreateAccountDto, UpdateAccountDto } from './dto/account.dto'
|
||||
import type { AccountsServiceCreateResponseDto, AccountsServiceFindAllResponseDto, AccountsServiceFindOneResponseDto, AccountsServiceUpdateResponseDto } from './dto/accounts-response.dto'
|
||||
import { CreateAdminAccountDto, UpdateAdminAccountDto } from './dto/account.dto'
|
||||
import type {
|
||||
AccountsServiceCreateResponseDto,
|
||||
AccountsServiceFindAllResponseDto,
|
||||
AccountsServiceFindOneResponseDto,
|
||||
AccountsServiceUpdateResponseDto,
|
||||
} from './dto/accounts-response.dto'
|
||||
|
||||
@ApiTags('accounts')
|
||||
@Controller('admin/users/:userId/accounts')
|
||||
@@ -10,7 +15,9 @@ export class AccountsController {
|
||||
constructor(private readonly accountsService: AccountsService) {}
|
||||
|
||||
@Get()
|
||||
async findAll(@Param('userId') userId: string): Promise<AccountsServiceFindAllResponseDto> {
|
||||
async findAll(
|
||||
@Param('userId') userId: string,
|
||||
): Promise<AccountsServiceFindAllResponseDto> {
|
||||
return this.accountsService.findAll(userId)
|
||||
}
|
||||
|
||||
@@ -20,12 +27,18 @@ export class AccountsController {
|
||||
}
|
||||
|
||||
@Post()
|
||||
async create(@Param('userId') userId: string, @Body() data: CreateAccountDto): Promise<AccountsServiceCreateResponseDto> {
|
||||
async create(
|
||||
@Param('userId') userId: string,
|
||||
@Body() data: CreateAdminAccountDto,
|
||||
): Promise<AccountsServiceCreateResponseDto> {
|
||||
return this.accountsService.create(userId, data)
|
||||
}
|
||||
|
||||
@Patch(':id')
|
||||
async update(@Param('id') id: string, @Body() data: UpdateAccountDto): Promise<AccountsServiceUpdateResponseDto> {
|
||||
async update(
|
||||
@Param('id') id: string,
|
||||
@Body() data: UpdateAdminAccountDto,
|
||||
): Promise<AccountsServiceUpdateResponseDto> {
|
||||
return this.accountsService.update(id, data)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { PrismaService } from '@/prisma/prisma.service'
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { ResponseMapper } from 'common/response/response-mapper'
|
||||
import { CreateAccountDto, UpdateAccountDto } from './dto/account.dto'
|
||||
import { CreateAdminAccountDto, UpdateAdminAccountDto } from './dto/account.dto'
|
||||
|
||||
@Injectable()
|
||||
export class AccountsService {
|
||||
@@ -23,7 +23,7 @@ export class AccountsService {
|
||||
return ResponseMapper.single({})
|
||||
}
|
||||
|
||||
async create(userId: string, data: CreateAccountDto) {
|
||||
async create(userId: string, data: CreateAdminAccountDto) {
|
||||
// const account = await this.prisma.account.create({
|
||||
// data: {
|
||||
// ...data,
|
||||
@@ -39,7 +39,7 @@ export class AccountsService {
|
||||
return ResponseMapper.create({})
|
||||
}
|
||||
|
||||
async update(id: string, data: UpdateAccountDto) {
|
||||
async update(id: string, data: UpdateAdminAccountDto) {
|
||||
const account = await this.prisma.account.update({ where: { id }, data })
|
||||
return ResponseMapper.update(account)
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { ApiProperty, PartialType } from '@nestjs/swagger'
|
||||
import { IsEnum, IsOptional, IsString } from 'class-validator'
|
||||
import { AccountStatus, AccountType } from 'generated/prisma/enums'
|
||||
|
||||
export class CreateAccountDto {
|
||||
export class CreateAdminAccountDto {
|
||||
@IsString()
|
||||
@UsernameFieldValidator()
|
||||
@ApiProperty()
|
||||
@@ -19,7 +19,7 @@ export class CreateAccountDto {
|
||||
type: AccountType
|
||||
}
|
||||
|
||||
export class UpdateAccountDto extends PartialType(CreateAccountDto) {
|
||||
export class UpdateAdminAccountDto extends PartialType(CreateAdminAccountDto) {
|
||||
@IsOptional()
|
||||
@IsEnum(AccountStatus)
|
||||
@ApiProperty({ enum: AccountStatus })
|
||||
|
||||
@@ -2,8 +2,12 @@ import { TokenAccount } from '@/common/decorators/tokenInfo.decorator'
|
||||
import { Body, Controller, Get, Param, Patch } from '@nestjs/common'
|
||||
import { ApiTags } from '@nestjs/swagger'
|
||||
import { AccountsService } from './accounts.service'
|
||||
import { UpdateAccountDto } from './dto/account.dto'
|
||||
import type { AccountsServiceFindAllResponseDto, AccountsServiceFindOneResponseDto, AccountsServiceUpdateResponseDto } from './dto/accounts-response.dto'
|
||||
import { UpdateConsumerAccountDto } from './dto/account.dto'
|
||||
import type {
|
||||
AccountsServiceFindAllResponseDto,
|
||||
AccountsServiceFindOneResponseDto,
|
||||
AccountsServiceUpdateResponseDto,
|
||||
} from './dto/accounts-response.dto'
|
||||
|
||||
@ApiTags('ConsumerAccounts')
|
||||
@Controller('consumer/accounts')
|
||||
@@ -11,7 +15,9 @@ export class AccountsController {
|
||||
constructor(private readonly accountsService: AccountsService) {}
|
||||
|
||||
@Get()
|
||||
async findAll(@TokenAccount('userId') consumerId: string): Promise<AccountsServiceFindAllResponseDto> {
|
||||
async findAll(
|
||||
@TokenAccount('userId') consumerId: string,
|
||||
): Promise<AccountsServiceFindAllResponseDto> {
|
||||
return this.accountsService.findAll(consumerId)
|
||||
}
|
||||
|
||||
@@ -29,7 +35,10 @@ export class AccountsController {
|
||||
// }
|
||||
|
||||
@Patch(':id')
|
||||
async update(@Param('id') id: string, @Body() data: UpdateAccountDto): Promise<AccountsServiceUpdateResponseDto> {
|
||||
async update(
|
||||
@Param('id') id: string,
|
||||
@Body() data: UpdateConsumerAccountDto,
|
||||
): Promise<AccountsServiceUpdateResponseDto> {
|
||||
return this.accountsService.update(id, data)
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { ConsumerRole } from '@/generated/prisma/enums'
|
||||
import { PrismaService } from '@/prisma/prisma.service'
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { ResponseMapper } from 'common/response/response-mapper'
|
||||
import { UpdateAccountDto } from './dto/account.dto'
|
||||
import { UpdateConsumerAccountDto } from './dto/account.dto'
|
||||
|
||||
@Injectable()
|
||||
export class AccountsService {
|
||||
@@ -91,7 +91,7 @@ export class AccountsService {
|
||||
// return ResponseMapper.create(account)
|
||||
// }
|
||||
|
||||
async update(id: string, data: UpdateAccountDto) {
|
||||
async update(id: string, data: UpdateConsumerAccountDto) {
|
||||
const account = await this.prisma.account.update({ where: { id }, data })
|
||||
return ResponseMapper.update(account)
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ export class CreateConsumerAccountDto {
|
||||
// role: ConsumerRole
|
||||
}
|
||||
|
||||
export class UpdateAccountDto extends PartialType(CreateConsumerAccountDto) {
|
||||
export class UpdateConsumerAccountDto extends PartialType(CreateConsumerAccountDto) {
|
||||
@IsOptional()
|
||||
@IsEnum(AccountStatus)
|
||||
@ApiProperty({ enum: AccountStatus })
|
||||
|
||||
@@ -71,7 +71,7 @@ export class BusinessActivitiesService {
|
||||
|
||||
async findOne(consumer_id: string, id: string) {
|
||||
const cacheKey = RedisKeyMaker.consumerBusinessActivityInfo(consumer_id, id)
|
||||
return await this.redisService.getAndSet(cacheKey, 'list', async () => {
|
||||
return await this.redisService.getAndSet(cacheKey, 'single', async () => {
|
||||
return await this.businessActivitiesQueryService.findOneByConsumer(
|
||||
consumer_id,
|
||||
id,
|
||||
|
||||
+4
-2
@@ -1,4 +1,4 @@
|
||||
import { Controller, Get, Param, Post } from '@nestjs/common'
|
||||
import { Controller, Get, Param, Post, Query } from '@nestjs/common'
|
||||
|
||||
import { TokenAccount } from '@/common/decorators/tokenInfo.decorator'
|
||||
import { ApiTags } from '@nestjs/swagger'
|
||||
@@ -14,8 +14,10 @@ export class SalesInvoicesController {
|
||||
@TokenAccount('userId') userId: string,
|
||||
@Param('complexId') complexId: string,
|
||||
@Param('posId') posId: string,
|
||||
@Query('page') page: number,
|
||||
@Query('perPage') perPage: number,
|
||||
) {
|
||||
return this.salesInvoicesService.findAll(userId, complexId, posId)
|
||||
return this.salesInvoicesService.findAll(userId, complexId, posId, page, perPage)
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
|
||||
+3
-1
@@ -1,5 +1,6 @@
|
||||
import { SharedSaleInvoiceActionsService } from '@/common/services/saleInvoices/sale-invoice-actions.service'
|
||||
import { SharedSaleInvoiceAccessService } from '@/common/services/saleInvoices/sale-invoice-access.service'
|
||||
import { SharedSaleInvoiceActionsService } from '@/common/services/saleInvoices/sale-invoice-actions.service'
|
||||
import { SharedSaleInvoicePaginationService } from '@/common/services/saleInvoices/sale-invoice-pagination.service'
|
||||
import { SaleInvoiceTspModule } from '@/modules/tspProviders/sales-invoice-tsp.module'
|
||||
import { Module } from '@nestjs/common'
|
||||
import { SalesInvoicesController } from './sales-invoices.controller'
|
||||
@@ -12,6 +13,7 @@ import { SalesInvoicesService } from './sales-invoices.service'
|
||||
SalesInvoicesService,
|
||||
SharedSaleInvoiceActionsService,
|
||||
SharedSaleInvoiceAccessService,
|
||||
SharedSaleInvoicePaginationService,
|
||||
],
|
||||
})
|
||||
export class ConsumerPosSalesInvoicesModule {}
|
||||
|
||||
+37
-81
@@ -1,5 +1,8 @@
|
||||
import { QUERY_CONSTANTS } from '@/common/queryConstants'
|
||||
import { ResponseMapper } from '@/common/response/response-mapper'
|
||||
import { SharedSaleInvoiceActionsService } from '@/common/services/saleInvoices/sale-invoice-actions.service'
|
||||
import { SharedSaleInvoicePaginationService } from '@/common/services/saleInvoices/sale-invoice-pagination.service'
|
||||
import { translateEnumValue } from '@/common/utils'
|
||||
import { SalesInvoiceWhereInput } from '@/generated/prisma/models'
|
||||
import { PrismaService } from '@/prisma/prisma.service'
|
||||
import { Injectable, NotFoundException } from '@nestjs/common'
|
||||
@@ -9,9 +12,19 @@ export class SalesInvoicesService {
|
||||
constructor(
|
||||
private prisma: PrismaService,
|
||||
private readonly sharedSaleInvoiceActionsService: SharedSaleInvoiceActionsService,
|
||||
private readonly sharedSaleInvoicePaginationService: SharedSaleInvoicePaginationService,
|
||||
) {}
|
||||
|
||||
async findAll(consumer_id: string, complex_id: string, pos_id: string) {
|
||||
async findAll(
|
||||
consumer_id: string,
|
||||
complex_id: string,
|
||||
pos_id: string,
|
||||
requestedPage: number = 1,
|
||||
requestedPerPage: number = 10,
|
||||
) {
|
||||
const { page, perPage, skip, take } =
|
||||
this.sharedSaleInvoicePaginationService.normalize(requestedPage, requestedPerPage)
|
||||
|
||||
const defaultWhere: SalesInvoiceWhereInput = {
|
||||
pos_id,
|
||||
pos: {
|
||||
@@ -24,98 +37,41 @@ export class SalesInvoicesService {
|
||||
},
|
||||
}
|
||||
|
||||
const perPage = 10
|
||||
const page = 1
|
||||
|
||||
const [items, total] = await this.prisma.$transaction([
|
||||
const [saleInvoices, total] = await this.prisma.$transaction([
|
||||
this.prisma.salesInvoice.findMany({
|
||||
where: defaultWhere,
|
||||
select: {
|
||||
id: true,
|
||||
code: true,
|
||||
invoice_date: true,
|
||||
notes: true,
|
||||
total_amount: true,
|
||||
|
||||
items: {
|
||||
...QUERY_CONSTANTS.SALE_INVOICE.select,
|
||||
_count: {
|
||||
select: {
|
||||
measure_unit_code: true,
|
||||
measure_unit_text: true,
|
||||
sku_code: true,
|
||||
discount_amount: true,
|
||||
tax_amount: true,
|
||||
notes: true,
|
||||
quantity: true,
|
||||
total_amount: true,
|
||||
unit_price: true,
|
||||
payload: true,
|
||||
good: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
sku: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
},
|
||||
},
|
||||
barcode: true,
|
||||
local_sku: true,
|
||||
pricing_model: true,
|
||||
measure_unit: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
},
|
||||
},
|
||||
category: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
items: true,
|
||||
},
|
||||
},
|
||||
payments: {
|
||||
select: {
|
||||
amount: true,
|
||||
paid_at: true,
|
||||
payment_method: true,
|
||||
},
|
||||
},
|
||||
customer: {
|
||||
select: {
|
||||
type: true,
|
||||
individual: {
|
||||
select: {
|
||||
economic_code: true,
|
||||
first_name: true,
|
||||
last_name: true,
|
||||
postal_code: true,
|
||||
national_id: true,
|
||||
},
|
||||
},
|
||||
legal: {
|
||||
select: {
|
||||
economic_code: true,
|
||||
postal_code: true,
|
||||
registration_number: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
unknown_customer: true,
|
||||
},
|
||||
skip: (page - 1) * perPage,
|
||||
take: perPage,
|
||||
orderBy: {
|
||||
created_at: 'desc',
|
||||
},
|
||||
skip,
|
||||
take,
|
||||
}),
|
||||
this.prisma.salesInvoice.count({
|
||||
where: defaultWhere,
|
||||
}),
|
||||
])
|
||||
return ResponseMapper.paginate(items, { total, page, perPage })
|
||||
const mappedAccounts = saleInvoices.map(saleInvoice => {
|
||||
const { _count, consumer_account, last_tsp_status, ...rest } = saleInvoice
|
||||
return {
|
||||
...rest,
|
||||
items_count: _count.items,
|
||||
status: translateEnumValue('TspProviderResponseStatus', last_tsp_status),
|
||||
}
|
||||
})
|
||||
|
||||
return ResponseMapper.paginate(mappedAccounts, {
|
||||
total,
|
||||
page,
|
||||
perPage,
|
||||
})
|
||||
}
|
||||
|
||||
findOne(complex_id: string, pos_id: string, id: string) {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { RedisKeyMaker } from '@/common/utils'
|
||||
import { checkAndDecodeJwtToken } from '@/common/utils/jwt-user.util'
|
||||
import { PrismaService } from '@/prisma/prisma.service'
|
||||
import { RedisService } from '@/redis/redis.service'
|
||||
import {
|
||||
ForbiddenException,
|
||||
Injectable,
|
||||
@@ -14,6 +16,7 @@ export class ConsumerMiddleware implements NestMiddleware {
|
||||
constructor(
|
||||
private prisma: PrismaService,
|
||||
private jwtService: JwtService,
|
||||
private redisService: RedisService,
|
||||
) {}
|
||||
|
||||
async use(req: Request, _res: Response, next: NextFunction) {
|
||||
@@ -21,7 +24,15 @@ export class ConsumerMiddleware implements NestMiddleware {
|
||||
throw new ForbiddenException('شما دسترسی لازم را ندارید')
|
||||
}
|
||||
try {
|
||||
const token = req.cookies?.accessToken
|
||||
const cacheKey = RedisKeyMaker.consumerMiddleware(token)
|
||||
let cachedConsumerData: unknown
|
||||
try {
|
||||
cachedConsumerData = await this.redisService.getJson(cacheKey)
|
||||
} catch (_) {}
|
||||
|
||||
const tokenAccount = checkAndDecodeJwtToken(req, this.jwtService)
|
||||
req.decodedToken = tokenAccount!
|
||||
|
||||
if (
|
||||
tokenAccount?.type !== 'CONSUMER' ||
|
||||
@@ -30,6 +41,16 @@ export class ConsumerMiddleware implements NestMiddleware {
|
||||
throw new UnauthorizedException()
|
||||
}
|
||||
|
||||
if (
|
||||
cachedConsumerData &&
|
||||
typeof cachedConsumerData === 'object' &&
|
||||
'account_id' in cachedConsumerData &&
|
||||
'id' in cachedConsumerData
|
||||
) {
|
||||
req.consumerData = cachedConsumerData as any
|
||||
return next()
|
||||
}
|
||||
|
||||
const consumerAccount = await this.prisma.consumerAccount.findUnique({
|
||||
where: {
|
||||
id: tokenAccount.account_id,
|
||||
@@ -49,7 +70,9 @@ export class ConsumerMiddleware implements NestMiddleware {
|
||||
id: consumerAccount.consumer_id,
|
||||
}
|
||||
|
||||
req.decodedToken = tokenAccount
|
||||
try {
|
||||
await this.redisService.setJson(cacheKey, req.consumerData, 60 * 60)
|
||||
} catch (_) {}
|
||||
|
||||
return next()
|
||||
} catch (error) {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { SharedSaleInvoicePaginationService } from '@/common/services/saleInvoices/sale-invoice-pagination.service'
|
||||
import { PrismaModule } from '@/prisma/prisma.module'
|
||||
import { Module } from '@nestjs/common'
|
||||
import { consumerCustomersController } from './customers.controller'
|
||||
@@ -7,6 +8,6 @@ import { ConsumerSaleInvoicesModule } from './sale-invoices/sale-invoices.module
|
||||
@Module({
|
||||
imports: [PrismaModule, ConsumerSaleInvoicesModule],
|
||||
controllers: [consumerCustomersController],
|
||||
providers: [consumerCustomersService],
|
||||
providers: [consumerCustomersService, SharedSaleInvoicePaginationService],
|
||||
})
|
||||
export class ConsumerCustomersModule {}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { SharedSaleInvoicePaginationService } from '@/common/services/saleInvoices/sale-invoice-pagination.service'
|
||||
import { CustomerSelect, CustomerWhereInput } from '@/generated/prisma/models'
|
||||
import { PrismaService } from '@/prisma/prisma.service'
|
||||
import { Injectable } from '@nestjs/common'
|
||||
@@ -9,7 +10,10 @@ import {
|
||||
|
||||
@Injectable()
|
||||
export class consumerCustomersService {
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
constructor(
|
||||
private readonly prisma: PrismaService,
|
||||
private readonly sharedSaleInvoicePaginationService: SharedSaleInvoicePaginationService,
|
||||
) {}
|
||||
|
||||
defaultSelect: CustomerSelect = {
|
||||
id: true,
|
||||
@@ -56,13 +60,15 @@ export class consumerCustomersService {
|
||||
}
|
||||
}
|
||||
|
||||
async findAll(consumer_id: string, page = 1, perPage = 10) {
|
||||
async findAll(consumer_id: string, requestedPage = 1, requestedPerPage = 10) {
|
||||
const { page, perPage, skip, take } =
|
||||
this.sharedSaleInvoicePaginationService.normalize(requestedPage, requestedPerPage)
|
||||
const [customers, total] = await this.prisma.$transaction(async tx => [
|
||||
await tx.customer.findMany({
|
||||
where: this.defaultWhere(consumer_id),
|
||||
select: this.defaultSelect,
|
||||
skip: (page - 1) * perPage,
|
||||
take: 10,
|
||||
skip,
|
||||
take,
|
||||
}),
|
||||
await tx.customer.count({
|
||||
where: this.defaultWhere(consumer_id),
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { SharedSaleInvoicePaginationService } from '@/common/services/saleInvoices/sale-invoice-pagination.service'
|
||||
import { PrismaModule } from '@/prisma/prisma.module'
|
||||
import { Module } from '@nestjs/common'
|
||||
import { CustomerSaleInvoicesController } from './sale-invoices.controller'
|
||||
@@ -6,6 +7,6 @@ import { CustomerSaleInvoicesService } from './sale-invoices.service'
|
||||
@Module({
|
||||
imports: [PrismaModule],
|
||||
controllers: [CustomerSaleInvoicesController],
|
||||
providers: [CustomerSaleInvoicesService],
|
||||
providers: [CustomerSaleInvoicesService, SharedSaleInvoicePaginationService],
|
||||
})
|
||||
export class ConsumerSaleInvoicesModule {}
|
||||
|
||||
@@ -1,57 +1,28 @@
|
||||
import { QUERY_CONSTANTS } from '@/common/queryConstants'
|
||||
import consumer_mappersUtil from '@/common/utils/mappers/consumer_mappers.util'
|
||||
import { SalesInvoiceSelect, SalesInvoiceWhereInput } from '@/generated/prisma/models'
|
||||
import { SharedSaleInvoicePaginationService } from '@/common/services/saleInvoices/sale-invoice-pagination.service'
|
||||
import { translateEnumValue } from '@/common/utils'
|
||||
import { TspProviderResponseStatus } from '@/generated/prisma/enums'
|
||||
import { SalesInvoiceWhereInput } from '@/generated/prisma/models'
|
||||
import { PrismaService } from '@/prisma/prisma.service'
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { Injectable, NotFoundException } from '@nestjs/common'
|
||||
import { ResponseMapper } from 'common/response/response-mapper'
|
||||
|
||||
@Injectable()
|
||||
export class CustomerSaleInvoicesService {
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
constructor(
|
||||
private readonly prisma: PrismaService,
|
||||
private readonly sharedSaleInvoicePaginationService: SharedSaleInvoicePaginationService,
|
||||
) {}
|
||||
|
||||
private readonly defaultSelect: SalesInvoiceSelect = {
|
||||
id: true,
|
||||
code: true,
|
||||
invoice_date: true,
|
||||
notes: true,
|
||||
total_amount: true,
|
||||
pos: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
complex: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
business_activity: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
consumer_account: {
|
||||
select: {
|
||||
role: true,
|
||||
consumer: {
|
||||
select: {
|
||||
...QUERY_CONSTANTS.CONSUMER.infoSelect,
|
||||
},
|
||||
},
|
||||
account: {
|
||||
select: {
|
||||
username: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
created_at: true,
|
||||
}
|
||||
async findAll(
|
||||
consumer_id: string,
|
||||
customer_id: string,
|
||||
requestedPage = 1,
|
||||
requestedPerPage = 10,
|
||||
) {
|
||||
const { page, perPage, skip, take } =
|
||||
this.sharedSaleInvoicePaginationService.normalize(requestedPage, requestedPerPage)
|
||||
|
||||
async findAll(consumer_id: string, customer_id: string, page = 1, perPage = 10) {
|
||||
const salesWhere: SalesInvoiceWhereInput = {
|
||||
customer_id,
|
||||
pos: {
|
||||
@@ -67,15 +38,30 @@ export class CustomerSaleInvoicesService {
|
||||
await tx.salesInvoice.findMany({
|
||||
where: salesWhere,
|
||||
select: {
|
||||
...this.defaultSelect,
|
||||
...QUERY_CONSTANTS.SALE_INVOICE.summarySelect,
|
||||
pos: {
|
||||
select: {
|
||||
name: true,
|
||||
complex: {
|
||||
select: {
|
||||
name: true,
|
||||
business_activity: {
|
||||
select: {
|
||||
name: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
_count: {
|
||||
select: {
|
||||
items: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
skip: (page - 1) * perPage,
|
||||
take: 10,
|
||||
skip,
|
||||
take,
|
||||
}),
|
||||
await tx.salesInvoice.count({
|
||||
where: salesWhere,
|
||||
@@ -83,16 +69,11 @@ export class CustomerSaleInvoicesService {
|
||||
])
|
||||
|
||||
const mappedAccounts = saleInvoices.map(saleInvoice => {
|
||||
const { _count, consumer_account, ...rest } = saleInvoice
|
||||
const { consumer, ...restConsumerAccount } = consumer_account as any
|
||||
const mappedConsumer = consumer_mappersUtil(consumer)
|
||||
const { _count, consumer_account, last_tsp_status, ...rest } = saleInvoice
|
||||
return {
|
||||
...rest,
|
||||
items_count: _count.items,
|
||||
consumer_account: {
|
||||
...restConsumerAccount,
|
||||
consumer: mappedConsumer,
|
||||
},
|
||||
status: translateEnumValue('TspProviderResponseStatus', last_tsp_status),
|
||||
}
|
||||
})
|
||||
|
||||
@@ -104,7 +85,7 @@ export class CustomerSaleInvoicesService {
|
||||
}
|
||||
|
||||
async findOne(consumer_id: string, customer_id: string, id: string) {
|
||||
const saleInvoice = await this.prisma.salesInvoice.findUniqueOrThrow({
|
||||
const invoice = await this.prisma.salesInvoice.findUnique({
|
||||
where: {
|
||||
id,
|
||||
customer_id,
|
||||
@@ -117,59 +98,26 @@ export class CustomerSaleInvoicesService {
|
||||
},
|
||||
},
|
||||
select: {
|
||||
...this.defaultSelect,
|
||||
items: {
|
||||
select: {
|
||||
id: true,
|
||||
notes: true,
|
||||
unit_price: true,
|
||||
quantity: true,
|
||||
discount_amount: true,
|
||||
tax_amount: true,
|
||||
total_amount: true,
|
||||
payload: true,
|
||||
good: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
pricing_model: true,
|
||||
measure_unit: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
},
|
||||
},
|
||||
category: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
image_url: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
payments: {
|
||||
select: {
|
||||
amount: true,
|
||||
paid_at: true,
|
||||
payment_method: true,
|
||||
},
|
||||
},
|
||||
...QUERY_CONSTANTS.SALE_INVOICE.select,
|
||||
},
|
||||
})
|
||||
const { _count, consumer_account, ...rest } = saleInvoice
|
||||
const { consumer, ...restConsumerAccount } = consumer_account as any
|
||||
const mappedConsumer = consumer_mappersUtil(consumer)
|
||||
|
||||
return ResponseMapper.single({
|
||||
...rest,
|
||||
items_count: _count.items,
|
||||
consumer_account: {
|
||||
...restConsumerAccount,
|
||||
consumer: mappedConsumer,
|
||||
},
|
||||
})
|
||||
if (invoice) {
|
||||
const { type, ...rest } = invoice
|
||||
const mappedInvoice = {
|
||||
...rest,
|
||||
type: translateEnumValue('TspProviderRequestType', type),
|
||||
status: translateEnumValue(
|
||||
'TspProviderResponseStatus',
|
||||
invoice.last_tsp_status || TspProviderResponseStatus.NOT_SEND,
|
||||
),
|
||||
settlement_type: translateEnumValue(
|
||||
'InvoiceSettlementType',
|
||||
invoice.settlement_type,
|
||||
),
|
||||
}
|
||||
return ResponseMapper.single(mappedInvoice)
|
||||
}
|
||||
throw new NotFoundException('صورتحساب مورد نظر شما یافت نشد.')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import { QUERY_CONSTANTS } from '@/common/queryConstants'
|
||||
import { PrismaService } from '@/prisma/prisma.service'
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { ResponseMapper } from 'common/response/response-mapper'
|
||||
import { UpdateBusinessActivityDto } from './dto/poses.dto'
|
||||
|
||||
@Injectable()
|
||||
export class PosesService {
|
||||
@@ -43,7 +44,7 @@ export class PosesService {
|
||||
})
|
||||
}
|
||||
|
||||
async update(consumer_id: string, id: string, data: any) {
|
||||
async update(consumer_id: string, id: string, data: UpdateBusinessActivityDto) {
|
||||
const pos = await this.prisma.pos.update({
|
||||
where: { ...this.defaultWhere(consumer_id), id },
|
||||
data,
|
||||
|
||||
@@ -1,95 +1,12 @@
|
||||
import { SharedSaleInvoicesFilterDto } from '@/common/services/saleInvoices/sale-invoice-filter.dto'
|
||||
import { ApiPropertyOptional } from '@nestjs/swagger'
|
||||
import { Type } from 'class-transformer'
|
||||
import {
|
||||
IsDateString,
|
||||
IsEnum,
|
||||
IsNumber,
|
||||
IsOptional,
|
||||
IsString,
|
||||
Max,
|
||||
Min,
|
||||
} from 'class-validator'
|
||||
import { TspProviderResponseStatus } from 'generated/prisma/enums'
|
||||
|
||||
export class ConsumerSaleInvoicesFilterDto {
|
||||
@ApiPropertyOptional({ type: Number, example: 1 })
|
||||
@Type(() => Number)
|
||||
@Min(1)
|
||||
@IsOptional()
|
||||
page?: number
|
||||
import { Max } from 'class-validator'
|
||||
|
||||
export class ConsumerSaleInvoicesFilterDto extends SharedSaleInvoicesFilterDto {
|
||||
@ApiPropertyOptional({ type: Number, example: 10, description: 'Max value is 50.' })
|
||||
@Type(() => Number)
|
||||
@Min(1)
|
||||
@Max(50)
|
||||
@IsOptional()
|
||||
perPage?: number
|
||||
declare perPage?: number
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsDateString()
|
||||
invoice_date_from?: string
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsDateString()
|
||||
invoice_date_to?: string
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsDateString()
|
||||
created_at_from?: string
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsDateString()
|
||||
created_at_to?: string
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
code?: string
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
customer_name?: string
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
customer_mobile?: string
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
customer_national_id?: string
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
customer_economic_code?: string
|
||||
|
||||
@ApiPropertyOptional({ enum: TspProviderResponseStatus })
|
||||
@IsOptional()
|
||||
@IsEnum(TspProviderResponseStatus)
|
||||
status?: TspProviderResponseStatus
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
@IsNumber()
|
||||
total_amount?: number
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
@IsNumber()
|
||||
total_amount_from?: number
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
@IsNumber()
|
||||
total_amount_to?: number
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import type { IPosPayload } from '@/common/models'
|
||||
import { Body, Controller, Get, Param, Post, Query } from '@nestjs/common'
|
||||
import { ApiTags } from '@nestjs/swagger'
|
||||
import { ConsumerSaleInvoicesFilterDto } from './dto/saleInvoices-filter.dto'
|
||||
import { PosCorrectionSalesInvoiceDto } from '../../pos/sales-invoices/dto/create-sales-invoice.dto'
|
||||
import type {
|
||||
SaleInvoicesServiceFindAllResponseDto,
|
||||
SaleInvoicesServiceFindOneResponseDto,
|
||||
@@ -59,4 +60,18 @@ export class StatisticsController {
|
||||
revoke(@Param('id') id: string, @PosInfo() posInfo: IPosPayload) {
|
||||
return this.service.revoke(id, posInfo)
|
||||
}
|
||||
|
||||
@Post(':id/correction')
|
||||
correction(
|
||||
@Param('id') id: string,
|
||||
@PosInfo() posInfo: IPosPayload,
|
||||
@Body() data: PosCorrectionSalesInvoiceDto,
|
||||
) {
|
||||
return this.service.correction(id, posInfo, data)
|
||||
}
|
||||
|
||||
@Post(':id/return')
|
||||
return(@Param('id') id: string, @PosInfo() posInfo: IPosPayload) {
|
||||
return this.service.return(id, posInfo)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { SharedSaleInvoiceActionsService } from '@/common/services/saleInvoices/sale-invoice-actions.service'
|
||||
import { SharedSaleInvoiceAccessService } from '@/common/services/saleInvoices/sale-invoice-access.service'
|
||||
import { SharedSaleInvoiceFilterService } from '@/common/services/saleInvoices/sale-invoice-filter.service'
|
||||
import { SharedSaleInvoicePaginationService } from '@/common/services/saleInvoices/sale-invoice-pagination.service'
|
||||
import { SaleInvoiceTspModule } from '@/modules/tspProviders/sales-invoice-tsp.module'
|
||||
import { PrismaModule } from '@/prisma/prisma.module'
|
||||
import { Module } from '@nestjs/common'
|
||||
@@ -9,7 +11,13 @@ import { SaleInvoicesService } from './saleInvoices.service'
|
||||
@Module({
|
||||
imports: [PrismaModule, SaleInvoiceTspModule],
|
||||
controllers: [StatisticsController],
|
||||
providers: [SaleInvoicesService, SharedSaleInvoiceActionsService, SharedSaleInvoiceAccessService],
|
||||
providers: [
|
||||
SaleInvoicesService,
|
||||
SharedSaleInvoiceActionsService,
|
||||
SharedSaleInvoiceAccessService,
|
||||
SharedSaleInvoiceFilterService,
|
||||
SharedSaleInvoicePaginationService,
|
||||
],
|
||||
exports: [SaleInvoicesService],
|
||||
})
|
||||
export class ConsumerSaleInvoicesModule {}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { IPosPayload } from '@/common/models'
|
||||
import { QUERY_CONSTANTS } from '@/common/queryConstants'
|
||||
import { SharedSaleInvoiceActionsService } from '@/common/services/saleInvoices/sale-invoice-actions.service'
|
||||
import { SharedSaleInvoiceFilterService } from '@/common/services/saleInvoices/sale-invoice-filter.service'
|
||||
import { SharedSaleInvoicePaginationService } from '@/common/services/saleInvoices/sale-invoice-pagination.service'
|
||||
import { translateEnumValue } from '@/common/utils'
|
||||
import { TspProviderResponseStatus } from '@/generated/prisma/enums'
|
||||
import {
|
||||
@@ -11,6 +13,7 @@ import {
|
||||
import { PrismaService } from '@/prisma/prisma.service'
|
||||
import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common'
|
||||
import { ResponseMapper } from 'common/response/response-mapper'
|
||||
import { PosCorrectionSalesInvoiceDto } from '../../pos/sales-invoices/dto/create-sales-invoice.dto'
|
||||
import { SalesInvoiceTspService } from '../../tspProviders/sales-invoice-tsp.service'
|
||||
import { ConsumerSaleInvoicesFilterDto } from './dto/saleInvoices-filter.dto'
|
||||
|
||||
@@ -20,11 +23,10 @@ export class SaleInvoicesService {
|
||||
private readonly prisma: PrismaService,
|
||||
private salesInvoiceTaxService: SalesInvoiceTspService,
|
||||
private sharedSaleInvoiceActionsService: SharedSaleInvoiceActionsService,
|
||||
private sharedSaleInvoiceFilterService: SharedSaleInvoiceFilterService,
|
||||
private sharedSaleInvoicePaginationService: SharedSaleInvoicePaginationService,
|
||||
) {}
|
||||
|
||||
private readonly defaultPerPage = 10
|
||||
private readonly maxPerPage = 50
|
||||
|
||||
private readonly defaultSelect: SalesInvoiceSelect = {
|
||||
pos: {
|
||||
select: {
|
||||
@@ -47,29 +49,21 @@ export class SaleInvoicesService {
|
||||
}
|
||||
|
||||
private readonly invoiceMapper = (invoice: any) => {
|
||||
const { tsp_attempts, ...rest } = invoice || {}
|
||||
const { last_tsp_status, ...rest } = invoice || {}
|
||||
|
||||
return {
|
||||
...rest,
|
||||
status: translateEnumValue(
|
||||
'TspProviderResponseStatus',
|
||||
invoice.tsp_attempts?.[0]?.status || TspProviderResponseStatus.NOT_SEND,
|
||||
last_tsp_status || TspProviderResponseStatus.NOT_SEND,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async findAll(consumer_id: string, filter: ConsumerSaleInvoicesFilterDto) {
|
||||
const invoicesWhere = this.buildFindAllWhere(consumer_id, filter)
|
||||
const normalizedPageValue = Number(filter.page ?? 1)
|
||||
const normalizedPage = Number.isFinite(normalizedPageValue)
|
||||
? Math.max(1, Math.floor(normalizedPageValue))
|
||||
: 1
|
||||
|
||||
const requestedPerPageValue = Number(filter.perPage ?? this.defaultPerPage)
|
||||
const requestedPerPage = Number.isFinite(requestedPerPageValue)
|
||||
? Math.max(1, Math.floor(requestedPerPageValue))
|
||||
: this.defaultPerPage
|
||||
const normalizedPerPage = Math.min(requestedPerPage, this.maxPerPage)
|
||||
const { page, perPage, skip, take } =
|
||||
this.sharedSaleInvoicePaginationService.normalize(filter.page, filter.perPage)
|
||||
|
||||
const [invoices, total] = await this.prisma.$transaction(async tx => [
|
||||
await tx.salesInvoice.findMany({
|
||||
@@ -77,8 +71,8 @@ export class SaleInvoicesService {
|
||||
orderBy: {
|
||||
created_at: 'desc',
|
||||
},
|
||||
skip: (normalizedPage - 1) * normalizedPerPage,
|
||||
take: normalizedPerPage,
|
||||
skip,
|
||||
take,
|
||||
select: {
|
||||
...QUERY_CONSTANTS.SALE_INVOICE.summarySelect,
|
||||
...this.defaultSelect,
|
||||
@@ -89,8 +83,8 @@ export class SaleInvoicesService {
|
||||
|
||||
const mappedInvoices = invoices.map(this.invoiceMapper)
|
||||
return ResponseMapper.paginate(mappedInvoices, {
|
||||
page: normalizedPage,
|
||||
perPage: normalizedPerPage,
|
||||
page,
|
||||
perPage,
|
||||
total,
|
||||
})
|
||||
}
|
||||
@@ -100,9 +94,11 @@ export class SaleInvoicesService {
|
||||
filter: ConsumerSaleInvoicesFilterDto,
|
||||
): SalesInvoiceWhereInput {
|
||||
const where: SalesInvoiceWhereInput = {
|
||||
...this.sharedSaleInvoiceFilterService.buildWhere(filter),
|
||||
consumer_account: {
|
||||
consumer_id,
|
||||
},
|
||||
referenced_by: null,
|
||||
}
|
||||
|
||||
if (filter.code?.trim()) {
|
||||
@@ -111,127 +107,6 @@ export class SaleInvoicesService {
|
||||
}
|
||||
}
|
||||
|
||||
if (filter.invoice_date_from || filter.invoice_date_to) {
|
||||
where.invoice_date = {
|
||||
...(filter.invoice_date_from ? { gte: new Date(filter.invoice_date_from) } : {}),
|
||||
...(filter.invoice_date_to ? { lte: new Date(filter.invoice_date_to) } : {}),
|
||||
}
|
||||
}
|
||||
|
||||
if (filter.created_at_from || filter.created_at_to) {
|
||||
where.created_at = {
|
||||
...(filter.created_at_from ? { gte: new Date(filter.created_at_from) } : {}),
|
||||
...(filter.created_at_to ? { lte: new Date(filter.created_at_to) } : {}),
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
filter.total_amount !== undefined ||
|
||||
filter.total_amount_from !== undefined ||
|
||||
filter.total_amount_to !== undefined
|
||||
) {
|
||||
where.total_amount = {
|
||||
...(filter.total_amount !== undefined ? { equals: filter.total_amount } : {}),
|
||||
...(filter.total_amount_from !== undefined
|
||||
? { gte: filter.total_amount_from }
|
||||
: {}),
|
||||
...(filter.total_amount_to !== undefined ? { lte: filter.total_amount_to } : {}),
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
filter.customer_name?.trim() ||
|
||||
filter.customer_mobile?.trim() ||
|
||||
filter.customer_national_id?.trim() ||
|
||||
filter.customer_economic_code?.trim()
|
||||
) {
|
||||
where.customer = {
|
||||
is: {
|
||||
OR: [
|
||||
...(filter.customer_name?.trim()
|
||||
? [
|
||||
{
|
||||
individual: {
|
||||
is: {
|
||||
OR: [
|
||||
{ first_name: { contains: filter.customer_name.trim() } },
|
||||
{ last_name: { contains: filter.customer_name.trim() } },
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
legal: {
|
||||
is: {
|
||||
name: {
|
||||
contains: filter.customer_name.trim(),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...(filter.customer_mobile?.trim()
|
||||
? [
|
||||
{
|
||||
individual: {
|
||||
is: {
|
||||
mobile_number: { contains: filter.customer_mobile.trim() },
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...(filter.customer_national_id?.trim()
|
||||
? [
|
||||
{
|
||||
individual: {
|
||||
is: {
|
||||
national_id: { contains: filter.customer_national_id.trim() },
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...(filter.customer_economic_code?.trim()
|
||||
? [
|
||||
{
|
||||
legal: {
|
||||
is: {
|
||||
OR: [
|
||||
{
|
||||
economic_code: {
|
||||
contains: filter.customer_economic_code.trim(),
|
||||
},
|
||||
},
|
||||
{
|
||||
registration_number: {
|
||||
contains: filter.customer_economic_code.trim(),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
: []),
|
||||
],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if (filter.status) {
|
||||
if (filter.status === TspProviderResponseStatus.NOT_SEND) {
|
||||
where.tsp_attempts = undefined
|
||||
} else {
|
||||
where.tsp_attempts = {
|
||||
some: {
|
||||
status: filter.status,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return where
|
||||
}
|
||||
|
||||
@@ -242,7 +117,7 @@ export class SaleInvoicesService {
|
||||
consumer_id,
|
||||
},
|
||||
}
|
||||
const invoice = await this.prisma.salesInvoice.findUniqueOrThrow({
|
||||
const invoice = await this.prisma.salesInvoice.findUnique({
|
||||
where: invoicesWhere,
|
||||
select: {
|
||||
...QUERY_CONSTANTS.SALE_INVOICE.select,
|
||||
@@ -251,9 +126,22 @@ export class SaleInvoicesService {
|
||||
})
|
||||
|
||||
if (invoice) {
|
||||
return ResponseMapper.single(this.invoiceMapper(invoice))
|
||||
const { type, ...rest } = invoice
|
||||
const mappedInvoice = {
|
||||
...rest,
|
||||
type: translateEnumValue('TspProviderRequestType', type),
|
||||
status: translateEnumValue(
|
||||
'TspProviderResponseStatus',
|
||||
invoice.last_tsp_status || TspProviderResponseStatus.NOT_SEND,
|
||||
),
|
||||
settlement_type: translateEnumValue(
|
||||
'InvoiceSettlementType',
|
||||
invoice.settlement_type,
|
||||
),
|
||||
}
|
||||
return ResponseMapper.single(mappedInvoice)
|
||||
}
|
||||
throw new NotFoundException('فاکتور مورد نظر شما یافت نشد.')
|
||||
throw new NotFoundException('صورتحساب مورد نظر شما یافت نشد.')
|
||||
}
|
||||
|
||||
async send(invoiceId: string, posInfo: IPosPayload) {
|
||||
@@ -290,6 +178,39 @@ export class SaleInvoicesService {
|
||||
return ResponseMapper.single(invoice)
|
||||
}
|
||||
|
||||
async correction(
|
||||
invoiceId: string,
|
||||
posInfo: IPosPayload,
|
||||
data: PosCorrectionSalesInvoiceDto,
|
||||
) {
|
||||
const { consumer_account_id, pos_id, business_id, complex_id } = posInfo
|
||||
|
||||
const invoice = await this.sharedSaleInvoiceActionsService.correction(
|
||||
data,
|
||||
consumer_account_id,
|
||||
pos_id,
|
||||
complex_id,
|
||||
business_id,
|
||||
invoiceId,
|
||||
)
|
||||
|
||||
return ResponseMapper.single(invoice)
|
||||
}
|
||||
|
||||
async return(invoiceId: string, posInfo: IPosPayload) {
|
||||
const { consumer_account_id, pos_id, business_id, complex_id } = posInfo
|
||||
|
||||
const invoice = await this.sharedSaleInvoiceActionsService.revoke(
|
||||
consumer_account_id,
|
||||
pos_id,
|
||||
complex_id,
|
||||
business_id,
|
||||
invoiceId,
|
||||
)
|
||||
|
||||
return ResponseMapper.single(invoice)
|
||||
}
|
||||
|
||||
async inquiry(consumer_account_id: string, pos_id: string, invoiceId: string) {
|
||||
const invoice = await this.sharedSaleInvoiceActionsService.inquiry(
|
||||
consumer_account_id,
|
||||
@@ -301,7 +222,7 @@ export class SaleInvoicesService {
|
||||
|
||||
async sendBulk(consumer_id: string, invoiceIds: string[]) {
|
||||
if (!invoiceIds.length) {
|
||||
throw new BadRequestException('لیست شناسه فاکتورها نمیتواند خالی باشد.')
|
||||
throw new BadRequestException('لیست شناسه صورتحسابها نمیتواند خالی باشد.')
|
||||
}
|
||||
|
||||
await this.salesInvoiceTaxService.sendBulk(consumer_id, invoiceIds)
|
||||
|
||||
@@ -10,13 +10,13 @@ export class StatisticsService {
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
|
||||
private readonly invoiceMapper = (invoice: any) => {
|
||||
const { tsp_attempts, ...rest } = invoice || {}
|
||||
const { last_tsp_status, ...rest } = invoice || {}
|
||||
|
||||
return {
|
||||
...rest,
|
||||
status: translateEnumValue(
|
||||
'TspProviderResponseStatus',
|
||||
invoice.tsp_attempts?.[0]?.status || TspProviderResponseStatus.NOT_SEND,
|
||||
last_tsp_status || TspProviderResponseStatus.NOT_SEND,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import {
|
||||
TspProviderType,
|
||||
} from '@/generated/prisma/enums'
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { GoldKarat, SKUGuildType, TspProviderCustomerType } from 'common/enums/enums'
|
||||
import { GoldKarat, TspProviderCustomerType } from 'common/enums/enums'
|
||||
import { ResponseMapper } from 'common/response/response-mapper'
|
||||
|
||||
@Injectable()
|
||||
@@ -80,7 +80,7 @@ export class EnumsService {
|
||||
TspProviderCustomerType,
|
||||
'TspProviderCustomerType',
|
||||
),
|
||||
SKUGuildType: this.prepareData(SKUGuildType, 'SKUGuildType'),
|
||||
// SKUGuildType: this.prepareData(SKUGuildType, 'SKUGuildType'),
|
||||
InvoiceTemplateType: this.prepareData(InvoiceTemplateType, 'InvoiceTemplateType'),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ export class InvoicesService {
|
||||
tax_id: true,
|
||||
total_amount: true,
|
||||
type: true,
|
||||
settlement_type: true,
|
||||
pos: {
|
||||
select: {
|
||||
name: true,
|
||||
@@ -114,14 +115,14 @@ export class InvoicesService {
|
||||
private readonly where = () => ({})
|
||||
|
||||
private readonly invoiceMapper = (invoice: any) => {
|
||||
const { tsp_attempts, type, ...rest } = invoice || {}
|
||||
const { last_tsp_status, type, ...rest } = invoice || {}
|
||||
|
||||
return {
|
||||
...rest,
|
||||
type: translateEnumValue('TspProviderRequestType', type),
|
||||
status: translateEnumValue(
|
||||
'TspProviderResponseStatus',
|
||||
invoice.tsp_attempts?.[0]?.status || TspProviderResponseStatus.NOT_SEND,
|
||||
last_tsp_status || TspProviderResponseStatus.NOT_SEND,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,12 @@ import { TokenAccount } from '@/common/decorators/tokenInfo.decorator'
|
||||
import { Body, Controller, Get, Param, Patch } from '@nestjs/common'
|
||||
import { ApiTags } from '@nestjs/swagger'
|
||||
import { AccountsService } from './accounts.service'
|
||||
import { UpdateAccountDto } from './dto/account.dto'
|
||||
import type { AccountsServiceFindAllResponseDto, AccountsServiceFindOneResponseDto, AccountsServiceUpdateResponseDto } from './dto/accounts-response.dto'
|
||||
import { UpdatePartnerAccountDto } from './dto/account.dto'
|
||||
import type {
|
||||
AccountsServiceFindAllResponseDto,
|
||||
AccountsServiceFindOneResponseDto,
|
||||
AccountsServiceUpdateResponseDto,
|
||||
} from './dto/accounts-response.dto'
|
||||
|
||||
@ApiTags('PartnerAccounts')
|
||||
@Controller('partner/accounts')
|
||||
@@ -11,7 +15,9 @@ export class AccountsController {
|
||||
constructor(private readonly service: AccountsService) {}
|
||||
|
||||
@Get()
|
||||
async findAll(@TokenAccount('userId') consumerId: string): Promise<AccountsServiceFindAllResponseDto> {
|
||||
async findAll(
|
||||
@TokenAccount('userId') consumerId: string,
|
||||
): Promise<AccountsServiceFindAllResponseDto> {
|
||||
return this.service.findAll(consumerId)
|
||||
}
|
||||
|
||||
@@ -29,7 +35,10 @@ export class AccountsController {
|
||||
// }
|
||||
|
||||
@Patch(':id')
|
||||
async update(@Param('id') id: string, @Body() data: UpdateAccountDto): Promise<AccountsServiceUpdateResponseDto> {
|
||||
async update(
|
||||
@Param('id') id: string,
|
||||
@Body() data: UpdatePartnerAccountDto,
|
||||
): Promise<AccountsServiceUpdateResponseDto> {
|
||||
return this.service.update(id, data)
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { AccountStatus, AccountType } from '@/generated/prisma/enums'
|
||||
import { PrismaService } from '@/prisma/prisma.service'
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { ResponseMapper } from 'common/response/response-mapper'
|
||||
import { CreatePartnerAccountDto, UpdateAccountDto } from './dto/account.dto'
|
||||
import { CreatePartnerAccountDto, UpdatePartnerAccountDto } from './dto/account.dto'
|
||||
|
||||
@Injectable()
|
||||
export class AccountsService {
|
||||
@@ -73,7 +73,7 @@ export class AccountsService {
|
||||
return ResponseMapper.create(account)
|
||||
}
|
||||
|
||||
async update(id: string, data: UpdateAccountDto) {
|
||||
async update(id: string, data: UpdatePartnerAccountDto) {
|
||||
const account = await this.prisma.account.update({ where: { id }, data })
|
||||
return ResponseMapper.update(account)
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ export class CreatePartnerAccountDto {
|
||||
role: PartnerRole
|
||||
}
|
||||
|
||||
export class UpdateAccountDto extends PartialType(CreatePartnerAccountDto) {
|
||||
export class UpdatePartnerAccountDto extends PartialType(CreatePartnerAccountDto) {
|
||||
@IsOptional()
|
||||
@IsEnum(AccountStatus)
|
||||
@ApiProperty({ enum: AccountStatus })
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
import { RedisKeyMaker } from '@/common/utils'
|
||||
import { PosCacheInvalidationService } from '@/modules/pos/cache/pos-cache-invalidation.service'
|
||||
import { RedisService } from '@/redis/redis.service'
|
||||
import { Injectable } from '@nestjs/common'
|
||||
|
||||
@Injectable()
|
||||
export class PartnersCacheInvalidationService {
|
||||
constructor(private readonly redisService: RedisService) {}
|
||||
constructor(
|
||||
private readonly redisService: RedisService,
|
||||
private readonly PosCacheInvalidationService: PosCacheInvalidationService,
|
||||
) {}
|
||||
|
||||
async invalidatePartnerSummary(partnerId: string): Promise<void> {
|
||||
await this.invalidatePartnersList()
|
||||
|
||||
@@ -2,8 +2,12 @@ import { PartnerInfo } from '@/common/decorators/partnerInfo.decorator'
|
||||
import { Body, Controller, Get, Param, Patch } from '@nestjs/common'
|
||||
import { ApiTags } from '@nestjs/swagger'
|
||||
import { AccountsService } from './accounts.service'
|
||||
import { UpdateAccountDto } from './dto/account.dto'
|
||||
import type { AccountsServiceFindAllResponseDto, AccountsServiceFindOneResponseDto, AccountsServiceUpdateResponseDto } from './dto/accounts-response.dto'
|
||||
import { UpdatePartnerConsumerAccountDto } from './dto/account.dto'
|
||||
import type {
|
||||
AccountsServiceFindAllResponseDto,
|
||||
AccountsServiceFindOneResponseDto,
|
||||
AccountsServiceUpdateResponseDto,
|
||||
} from './dto/accounts-response.dto'
|
||||
|
||||
@ApiTags('PartnerConsumerAccounts')
|
||||
@Controller('partner/consumers/:consumerId/accounts')
|
||||
@@ -41,7 +45,7 @@ export class AccountsController {
|
||||
@PartnerInfo('id') partnerId: string,
|
||||
@Param('consumerId') consumerId: string,
|
||||
@Param('id') id: string,
|
||||
@Body() data: UpdateAccountDto,
|
||||
@Body() data: UpdatePartnerConsumerAccountDto,
|
||||
): Promise<AccountsServiceUpdateResponseDto> {
|
||||
return this.accountsService.update(partnerId, consumerId, id, data)
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { ConsumerAccountSelect } from '@/generated/prisma/models'
|
||||
import { PrismaService } from '@/prisma/prisma.service'
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { ResponseMapper } from 'common/response/response-mapper'
|
||||
import { UpdateAccountDto } from './dto/account.dto'
|
||||
import { UpdatePartnerConsumerAccountDto } from './dto/account.dto'
|
||||
|
||||
@Injectable()
|
||||
export class AccountsService {
|
||||
@@ -126,7 +126,7 @@ export class AccountsService {
|
||||
partner_id: string,
|
||||
consumer_id: string,
|
||||
id: string,
|
||||
data: UpdateAccountDto,
|
||||
data: UpdatePartnerConsumerAccountDto,
|
||||
) {
|
||||
const account = await this.prisma.account.update({
|
||||
where: {
|
||||
|
||||
@@ -3,7 +3,7 @@ import { ApiProperty, PartialType } from '@nestjs/swagger'
|
||||
import { IsEnum, IsOptional, IsString } from 'class-validator'
|
||||
import { AccountStatus, ConsumerRole } from 'generated/prisma/enums'
|
||||
|
||||
export class CreateConsumerAccountDto {
|
||||
export class CreatePartnerConsumerAccountDto {
|
||||
@IsString()
|
||||
@UsernameFieldValidator()
|
||||
@ApiProperty({ required: true })
|
||||
@@ -19,7 +19,9 @@ export class CreateConsumerAccountDto {
|
||||
role: ConsumerRole
|
||||
}
|
||||
|
||||
export class UpdateAccountDto extends PartialType(CreateConsumerAccountDto) {
|
||||
export class UpdatePartnerConsumerAccountDto extends PartialType(
|
||||
CreatePartnerConsumerAccountDto,
|
||||
) {
|
||||
@IsOptional()
|
||||
@IsEnum(AccountStatus)
|
||||
@ApiProperty({ enum: AccountStatus })
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { POSStatus, POSType } from '@/generated/prisma/enums'
|
||||
import { CreateConsumerAccountDto } from '@/modules/partners/consumers/accounts/dto/account.dto'
|
||||
import { CreatePartnerConsumerAccountDto } from '@/modules/partners/consumers/accounts/dto/account.dto'
|
||||
import { ApiProperty, OmitType, PartialType } from '@nestjs/swagger'
|
||||
import { IsEnum, IsOptional, IsString } from 'class-validator'
|
||||
|
||||
export class CreatePosDto extends OmitType(CreateConsumerAccountDto, ['role']) {
|
||||
export class CreatePosDto extends OmitType(CreatePartnerConsumerAccountDto, ['role']) {
|
||||
@IsString()
|
||||
@ApiProperty({})
|
||||
name: string
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { RedisKeyMaker } from '@/common/utils'
|
||||
import { checkAndDecodeJwtToken } from '@/common/utils/jwt-user.util'
|
||||
import { PrismaService } from '@/prisma/prisma.service'
|
||||
import { RedisService } from '@/redis/redis.service'
|
||||
import {
|
||||
ForbiddenException,
|
||||
Injectable,
|
||||
@@ -14,6 +16,7 @@ export class PartnerMiddleware implements NestMiddleware {
|
||||
constructor(
|
||||
private prisma: PrismaService,
|
||||
private jwtService: JwtService,
|
||||
private redisService: RedisService,
|
||||
) {}
|
||||
|
||||
async use(req: Request, _res: Response, next: NextFunction) {
|
||||
@@ -21,12 +24,30 @@ export class PartnerMiddleware implements NestMiddleware {
|
||||
throw new ForbiddenException('شما دسترسی لازم را ندارید')
|
||||
}
|
||||
try {
|
||||
const token = req.cookies?.accessToken
|
||||
const cacheKey = RedisKeyMaker.partnerMiddleware(token)
|
||||
let cachedPartnerData: unknown
|
||||
try {
|
||||
cachedPartnerData = await this.redisService.getJson(cacheKey)
|
||||
} catch (_) {}
|
||||
|
||||
const tokenAccount = checkAndDecodeJwtToken(req, this.jwtService)
|
||||
req.decodedToken = tokenAccount!
|
||||
|
||||
if (tokenAccount?.type !== 'PARTNER') {
|
||||
throw new UnauthorizedException()
|
||||
}
|
||||
|
||||
if (
|
||||
cachedPartnerData &&
|
||||
typeof cachedPartnerData === 'object' &&
|
||||
'account_id' in cachedPartnerData &&
|
||||
'id' in cachedPartnerData
|
||||
) {
|
||||
req.partnerData = cachedPartnerData as any
|
||||
return next()
|
||||
}
|
||||
|
||||
const partnerAccount = await this.prisma.partnerAccount.findUnique({
|
||||
where: {
|
||||
id: tokenAccount.account_id,
|
||||
@@ -46,7 +67,9 @@ export class PartnerMiddleware implements NestMiddleware {
|
||||
id: partnerAccount.partner_id,
|
||||
}
|
||||
|
||||
req.decodedToken = tokenAccount
|
||||
try {
|
||||
await this.redisService.setJson(cacheKey, req.partnerData, 60 * 60)
|
||||
} catch (_) {}
|
||||
|
||||
return next()
|
||||
} catch (error) {
|
||||
|
||||
@@ -6,6 +6,14 @@ import { Injectable } from '@nestjs/common'
|
||||
export class PosCacheInvalidationService {
|
||||
constructor(private readonly redisService: RedisService) {}
|
||||
|
||||
async invalidatePosInfo(posId: string): Promise<void> {
|
||||
this.redisService.delete(PosKeyMaker.info(posId))
|
||||
}
|
||||
|
||||
async invalidatePosMiddleware(token: string): Promise<void> {
|
||||
this.redisService.delete(PosKeyMaker.middleware(token))
|
||||
}
|
||||
|
||||
async invalidatePosGoodsList(
|
||||
guildId: string,
|
||||
businessActivityId: string,
|
||||
|
||||
@@ -1,22 +1,25 @@
|
||||
import { Body, Controller, Get, Param, Post } from '@nestjs/common'
|
||||
import { PosInfo } from '@/common/decorators/posInfo.decorator'
|
||||
import type { IPosPayload } from '@/common/models'
|
||||
import { Controller, Get, Query } from '@nestjs/common'
|
||||
import { CustomersService } from './customers.service'
|
||||
import { PosCustomerFilterDto } from './dto/customer-filter.dto'
|
||||
|
||||
@Controller('pos/customers')
|
||||
export class CustomersController {
|
||||
constructor(private readonly customerService: CustomersService) {}
|
||||
|
||||
@Get()
|
||||
findAll() {
|
||||
return this.customerService.findAll()
|
||||
findAll(@PosInfo() posInfo: IPosPayload, @Query() query: PosCustomerFilterDto) {
|
||||
return this.customerService.findAll(posInfo, query)
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
findOne(@Param('id') id: string) {
|
||||
return this.customerService.findOne(+id)
|
||||
}
|
||||
// @Get(':id')
|
||||
// findOne(@Param('id') id: string) {
|
||||
// return this.customerService.findOne(+id)
|
||||
// }
|
||||
|
||||
@Post()
|
||||
create(@Body() data: any) {
|
||||
return this.customerService.create(data)
|
||||
}
|
||||
// @Post()
|
||||
// create(@Body() data: any) {
|
||||
// return this.customerService.create(data)
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -1,10 +1,127 @@
|
||||
import { IPosPayload } from '@/common/models'
|
||||
import { ResponseMapper } from '@/common/response/response-mapper'
|
||||
import { CustomerType } from '@/generated/prisma/enums'
|
||||
import { CustomerSelect, CustomerWhereInput } from '@/generated/prisma/models'
|
||||
import { PrismaService } from '@/prisma/prisma.service'
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { PosCustomerFilterDto } from './dto/customer-filter.dto'
|
||||
|
||||
@Injectable()
|
||||
export class CustomersService {
|
||||
findAll() {
|
||||
// TODO: Implement fetching all customers
|
||||
return []
|
||||
constructor(private prisma: PrismaService) {}
|
||||
|
||||
async findAll(posInfo: IPosPayload, query: PosCustomerFilterDto) {
|
||||
const { type, q } = query
|
||||
const where: CustomerWhereInput = {
|
||||
type,
|
||||
}
|
||||
const select: CustomerSelect = {
|
||||
id: true,
|
||||
}
|
||||
|
||||
if (type === CustomerType.LEGAL) {
|
||||
where.legal = {
|
||||
business_activity_id: posInfo.business_id,
|
||||
}
|
||||
select.legal = {
|
||||
select: {
|
||||
name: true,
|
||||
economic_code: true,
|
||||
postal_code: true,
|
||||
registration_number: true,
|
||||
},
|
||||
}
|
||||
if (q) {
|
||||
where.legal = {
|
||||
...where.legal,
|
||||
OR: [
|
||||
{
|
||||
name: {
|
||||
contains: q,
|
||||
},
|
||||
},
|
||||
{
|
||||
economic_code: {
|
||||
contains: q,
|
||||
},
|
||||
},
|
||||
{
|
||||
postal_code: {
|
||||
contains: q,
|
||||
},
|
||||
},
|
||||
{
|
||||
registration_number: {
|
||||
contains: q,
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
} else if (type === CustomerType.INDIVIDUAL) {
|
||||
where.individual = {
|
||||
business_activity_id: posInfo.business_id,
|
||||
}
|
||||
select.individual = {
|
||||
select: {
|
||||
first_name: true,
|
||||
last_name: true,
|
||||
economic_code: true,
|
||||
postal_code: true,
|
||||
mobile_number: true,
|
||||
national_id: true,
|
||||
},
|
||||
}
|
||||
if (q) {
|
||||
where.individual = {
|
||||
...where.individual,
|
||||
OR: [
|
||||
{
|
||||
first_name: {
|
||||
contains: q,
|
||||
},
|
||||
},
|
||||
{
|
||||
last_name: {
|
||||
contains: q,
|
||||
},
|
||||
},
|
||||
{
|
||||
economic_code: {
|
||||
contains: q,
|
||||
},
|
||||
},
|
||||
{
|
||||
postal_code: {
|
||||
contains: q,
|
||||
},
|
||||
},
|
||||
{
|
||||
mobile_number: {
|
||||
contains: q,
|
||||
},
|
||||
},
|
||||
{
|
||||
national_id: {
|
||||
contains: q,
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
const customers = await this.prisma.customer.findMany({
|
||||
where,
|
||||
take: 20,
|
||||
orderBy: {
|
||||
created_at: 'desc',
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
...select,
|
||||
},
|
||||
})
|
||||
return ResponseMapper.list(customers)
|
||||
}
|
||||
|
||||
findOne(id: number) {
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import { ApiPropertyOptional } from '@nestjs/swagger'
|
||||
import { IsEnum, IsOptional, IsString } from 'class-validator'
|
||||
import { CustomerType } from 'generated/prisma/enums'
|
||||
|
||||
export class PosCustomerFilterDto {
|
||||
@ApiPropertyOptional({ enum: CustomerType })
|
||||
@IsOptional()
|
||||
@IsEnum(CustomerType)
|
||||
type: CustomerType
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
q?: string
|
||||
}
|
||||
@@ -1,8 +1,13 @@
|
||||
import { ApiProperty } from '@nestjs/swagger'
|
||||
import { IsString } from 'class-validator'
|
||||
import { IsString, Length } from 'class-validator'
|
||||
|
||||
export class UpdatePosAccountPasswordDto {
|
||||
@IsString()
|
||||
@ApiProperty({ required: true })
|
||||
@IsString()
|
||||
currentPassword: string
|
||||
|
||||
@ApiProperty({ required: true })
|
||||
@IsString()
|
||||
@Length(6, 32)
|
||||
password: string
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ export class OwnedGoodsService {
|
||||
return await tx.good.create({
|
||||
data: {
|
||||
...rest,
|
||||
is_default_guild_good: true,
|
||||
is_default_guild_good: false,
|
||||
image_url,
|
||||
sku: {
|
||||
connect: {
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { RedisKeyMaker } from '@/common/utils'
|
||||
import { checkAndDecodeJwtToken } from '@/common/utils/jwt-user.util'
|
||||
import { ConsumerRole, POSStatus } from '@/generated/prisma/enums'
|
||||
import { PosSelect, PosWhereInput } from '@/generated/prisma/models'
|
||||
import { PrismaService } from '@/prisma/prisma.service'
|
||||
import { RedisService } from '@/redis/redis.service'
|
||||
import {
|
||||
ForbiddenException,
|
||||
Injectable,
|
||||
@@ -16,15 +18,38 @@ export class PosMiddleware implements NestMiddleware {
|
||||
constructor(
|
||||
private prisma: PrismaService,
|
||||
private jwtService: JwtService,
|
||||
private redisService: RedisService,
|
||||
) {}
|
||||
|
||||
async use(req: Request, _res: Response, next: NextFunction) {
|
||||
const doForbidden = () => {
|
||||
throw new ForbiddenException('شما دسترسی لازم را ندارید')
|
||||
}
|
||||
|
||||
const token = req.cookies?.accessToken
|
||||
const cacheKey = RedisKeyMaker.posMiddleware(token)
|
||||
let cashedPosData: unknown
|
||||
try {
|
||||
cashedPosData = await this.redisService.getJson(cacheKey)
|
||||
} catch (_) {}
|
||||
const tokenAccount = checkAndDecodeJwtToken(req, this.jwtService)
|
||||
req.decodedToken = tokenAccount!
|
||||
|
||||
if (
|
||||
cashedPosData &&
|
||||
typeof cashedPosData === 'object' &&
|
||||
'pos_id' in cashedPosData &&
|
||||
'complex_id' in cashedPosData &&
|
||||
'business_id' in cashedPosData &&
|
||||
'guild_id' in cashedPosData &&
|
||||
'consumer_account_id' in cashedPosData
|
||||
) {
|
||||
req.posData = cashedPosData as any
|
||||
return next()
|
||||
}
|
||||
|
||||
return this.prisma.$transaction(async tx => {
|
||||
try {
|
||||
const tokenAccount = checkAndDecodeJwtToken(req, this.jwtService)
|
||||
const { type, role, account_id } = tokenAccount!
|
||||
const posSelect: PosSelect = {
|
||||
id: true,
|
||||
@@ -103,42 +128,19 @@ export class PosMiddleware implements NestMiddleware {
|
||||
return doForbidden()
|
||||
}
|
||||
|
||||
// if (role !== ConsumerRole.OWNER) {
|
||||
// const accountPermissions = await tx.permissionConsumer.findUnique({
|
||||
// where: {
|
||||
// consumer_account_id: account_id,
|
||||
// },
|
||||
// select: {
|
||||
// pos_permissions: {
|
||||
// select: {
|
||||
// pos_id: true,
|
||||
// },
|
||||
// },
|
||||
// business_permissions: {
|
||||
// select: {
|
||||
// business_id: true,
|
||||
// },
|
||||
// },
|
||||
// complex_permissions: {
|
||||
// select: {
|
||||
// complex_id: true,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
|
||||
// if (
|
||||
// !// accountPermissions?.business_permissions.some(
|
||||
// // permission => permission.id,
|
||||
// // ) ||
|
||||
// // accountPermissions?.complex_permissions.some(
|
||||
// // permission => permission.complex_id,
|
||||
// // ) ||
|
||||
// accountPermissions?.pos_permissions.some(permission => permission.pos_id)
|
||||
// ) {
|
||||
// return doForbidden()
|
||||
// }
|
||||
// }
|
||||
try {
|
||||
await this.redisService.setJson(
|
||||
cacheKey,
|
||||
{
|
||||
pos_id: posId,
|
||||
complex_id: pos.complex.id,
|
||||
business_id: pos.complex.business_activity.id,
|
||||
guild_id: pos.complex.business_activity.guild_id,
|
||||
consumer_account_id: account_id,
|
||||
},
|
||||
60 * 60,
|
||||
)
|
||||
} catch (_) {}
|
||||
|
||||
req.posData = {
|
||||
pos_id: posId,
|
||||
@@ -147,7 +149,6 @@ export class PosMiddleware implements NestMiddleware {
|
||||
guild_id: pos.complex.business_activity.guild_id,
|
||||
consumer_account_id: account_id,
|
||||
}
|
||||
req.decodedToken = tokenAccount!
|
||||
|
||||
return next()
|
||||
} catch (error) {
|
||||
|
||||
@@ -5,7 +5,7 @@ import { RedisKeyMaker } from '@/common/utils/redisKeyMaker'
|
||||
import { ConsumerStatus } from '@/generated/prisma/enums'
|
||||
import { PrismaService } from '@/prisma/prisma.service'
|
||||
import { RedisService } from '@/redis/redis.service'
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { BadRequestException, Injectable } from '@nestjs/common'
|
||||
import { ResponseMapper } from 'common/response/response-mapper'
|
||||
import { UpdatePosAccountPasswordDto } from './dto/update-password-request.dto'
|
||||
|
||||
@@ -218,7 +218,29 @@ export class PosService {
|
||||
accountId: string,
|
||||
data: UpdatePosAccountPasswordDto,
|
||||
) {
|
||||
const consumer = await this.prisma.consumerAccount.update({
|
||||
const currentCustomerAccount = await this.prisma.consumerAccount.findUniqueOrThrow({
|
||||
where: {
|
||||
id: accountId,
|
||||
consumer_id,
|
||||
},
|
||||
select: {
|
||||
account: {
|
||||
select: {
|
||||
password: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const isCurrentPasswordValid = await PasswordUtil.compare(
|
||||
data.currentPassword,
|
||||
currentCustomerAccount.account.password,
|
||||
)
|
||||
if (!isCurrentPasswordValid) {
|
||||
throw new BadRequestException('رمز عبور فعلی اشتباه است')
|
||||
}
|
||||
|
||||
const consumerAccount = await this.prisma.consumerAccount.update({
|
||||
where: {
|
||||
id: accountId,
|
||||
consumer_id,
|
||||
@@ -232,6 +254,6 @@ export class PosService {
|
||||
},
|
||||
})
|
||||
|
||||
return ResponseMapper.update(consumer)
|
||||
return ResponseMapper.update(consumerAccount)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,52 @@
|
||||
import { SharedCreateSalesInvoiceDto } from '@/common/services/saleInvoices/sale-invoice-create.dto'
|
||||
import { PartialType } from '@nestjs/swagger'
|
||||
import {
|
||||
SharedCorrectionSalesInvoiceDto,
|
||||
SharedCreateSalesInvoiceDto,
|
||||
} from '@/common/services/saleInvoices/sale-invoice-create.dto'
|
||||
import { ApiProperty } from '@nestjs/swagger'
|
||||
import { Type } from 'class-transformer'
|
||||
import {
|
||||
ArrayMinSize,
|
||||
IsArray,
|
||||
IsDateString,
|
||||
IsNumber,
|
||||
IsOptional,
|
||||
IsString,
|
||||
Min,
|
||||
ValidateNested,
|
||||
} from 'class-validator'
|
||||
|
||||
export class CreateSalesInvoiceDto extends SharedCreateSalesInvoiceDto {}
|
||||
export class PosCreateSalesInvoiceDto extends SharedCreateSalesInvoiceDto {}
|
||||
export class PosCorrectionSalesInvoiceDto extends SharedCorrectionSalesInvoiceDto {}
|
||||
|
||||
export class UpdateSalesInvoiceDto extends PartialType(CreateSalesInvoiceDto) {}
|
||||
export class PosReturnSalesInvoiceItemDto {
|
||||
@ApiProperty({ required: false })
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
good_id?: string
|
||||
|
||||
@ApiProperty({ required: false })
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
service_id?: string
|
||||
|
||||
@ApiProperty({ required: true, default: 1 })
|
||||
@IsNumber()
|
||||
@Min(1)
|
||||
quantity: number
|
||||
}
|
||||
|
||||
export class PosReturnSalesInvoiceDto {
|
||||
@ApiProperty({ required: true })
|
||||
@IsDateString(
|
||||
{ strict: true },
|
||||
{ message: 'invoice_date must be a valid ISO-8601 string' },
|
||||
)
|
||||
invoice_date: Date
|
||||
|
||||
@ApiProperty({ required: true, type: [PosReturnSalesInvoiceItemDto] })
|
||||
@IsArray()
|
||||
@ArrayMinSize(1)
|
||||
@ValidateNested({ each: true })
|
||||
@Type(() => PosReturnSalesInvoiceItemDto)
|
||||
items: PosReturnSalesInvoiceItemDto[]
|
||||
}
|
||||
|
||||
@@ -1,95 +1,10 @@
|
||||
import { SharedSaleInvoicesFilterDto } from '@/common/services/saleInvoices/sale-invoice-filter.dto'
|
||||
import { ApiPropertyOptional } from '@nestjs/swagger'
|
||||
import { Type } from 'class-transformer'
|
||||
import {
|
||||
IsDateString,
|
||||
IsEnum,
|
||||
IsNumber,
|
||||
IsOptional,
|
||||
IsString,
|
||||
Min,
|
||||
} from 'class-validator'
|
||||
import { TspProviderResponseStatus } from 'generated/prisma/enums'
|
||||
|
||||
export class SalesInvoicesFilterDto {
|
||||
@ApiPropertyOptional({ default: 1 })
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
@IsNumber()
|
||||
@Min(1)
|
||||
page?: number
|
||||
|
||||
@ApiPropertyOptional({ default: 10 })
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
@IsNumber()
|
||||
@Min(1)
|
||||
perPage?: number
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsDateString()
|
||||
invoice_date_from?: string
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsDateString()
|
||||
invoice_date_to?: string
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsDateString()
|
||||
created_at_from?: string
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsDateString()
|
||||
created_at_to?: string
|
||||
import { IsNumber, IsOptional } from 'class-validator'
|
||||
|
||||
export class SalesInvoicesFilterDto extends SharedSaleInvoicesFilterDto {
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
invoice_number?: number
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
customer_name?: string
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
customer_mobile?: string
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
customer_national_id?: string
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
customer_economic_code?: string
|
||||
|
||||
@ApiPropertyOptional({ enum: TspProviderResponseStatus })
|
||||
@IsOptional()
|
||||
@IsEnum(TspProviderResponseStatus)
|
||||
status?: TspProviderResponseStatus
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
@IsNumber()
|
||||
total_amount?: number
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
@IsNumber()
|
||||
total_amount_from?: number
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
@IsNumber()
|
||||
total_amount_to?: number
|
||||
}
|
||||
|
||||
@@ -2,7 +2,11 @@ import { Body, Controller, Get, Param, Post, Query } from '@nestjs/common'
|
||||
|
||||
import { PosInfo } from '@/common/decorators/posInfo.decorator'
|
||||
import type { IPosPayload } from '@/common/models/posPayload.model'
|
||||
import { CreateSalesInvoiceDto } from './dto/create-sales-invoice.dto'
|
||||
import {
|
||||
PosCorrectionSalesInvoiceDto,
|
||||
PosCreateSalesInvoiceDto,
|
||||
PosReturnSalesInvoiceDto,
|
||||
} from './dto/create-sales-invoice.dto'
|
||||
import { SalesInvoicesFilterDto } from './dto/sales-invoices-filter.dto'
|
||||
import { SalesInvoicesService } from './sales-invoices.service'
|
||||
|
||||
@@ -30,7 +34,7 @@ export class SalesInvoicesController {
|
||||
}
|
||||
|
||||
@Post()
|
||||
create(@Body() data: CreateSalesInvoiceDto, @PosInfo() posInfo: IPosPayload) {
|
||||
create(@Body() data: PosCreateSalesInvoiceDto, @PosInfo() posInfo: IPosPayload) {
|
||||
return this.salesInvoicesService.create(data, posInfo)
|
||||
}
|
||||
|
||||
@@ -49,6 +53,23 @@ export class SalesInvoicesController {
|
||||
return this.salesInvoicesService.revoke(id, posInfo)
|
||||
}
|
||||
|
||||
@Post(':id/correction')
|
||||
correction(
|
||||
@Param('id') id: string,
|
||||
@PosInfo() posInfo: IPosPayload,
|
||||
@Body() data: PosCorrectionSalesInvoiceDto,
|
||||
) {
|
||||
return this.salesInvoicesService.correction(id, posInfo, data)
|
||||
}
|
||||
@Post(':id/return_from_sale')
|
||||
return(
|
||||
@Param('id') id: string,
|
||||
@PosInfo() posInfo: IPosPayload,
|
||||
@Body() data: PosReturnSalesInvoiceDto,
|
||||
) {
|
||||
return this.salesInvoicesService.return(id, posInfo, data)
|
||||
}
|
||||
|
||||
// @Post('send/bulk')
|
||||
// sendBulk(@Body() data: SendBulkSalesInvoicesDto, @PosInfo() posInfo: IPosPayload) {
|
||||
// return this.salesInvoicesService.sendBulk(data.invoice_ids, posInfo)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { SharedSaleInvoiceCreateService } from '@/common/services/saleInvoices/sale-invoice-create.service'
|
||||
import { SharedSaleInvoiceActionsService } from '@/common/services/saleInvoices/sale-invoice-actions.service'
|
||||
import { SharedSaleInvoiceAccessService } from '@/common/services/saleInvoices/sale-invoice-access.service'
|
||||
import { SharedSaleInvoiceFilterService } from '@/common/services/saleInvoices/sale-invoice-filter.service'
|
||||
import { SaleInvoiceTspModule } from '@/modules/tspProviders/sales-invoice-tsp.module'
|
||||
import { Module } from '@nestjs/common'
|
||||
import { SalesInvoicesController } from './sales-invoices.controller'
|
||||
@@ -14,6 +15,7 @@ import { SalesInvoicesService } from './sales-invoices.service'
|
||||
SharedSaleInvoiceCreateService,
|
||||
SharedSaleInvoiceActionsService,
|
||||
SharedSaleInvoiceAccessService,
|
||||
SharedSaleInvoiceFilterService,
|
||||
],
|
||||
})
|
||||
export class PosSalesInvoicesModule {}
|
||||
|
||||
@@ -2,6 +2,7 @@ import { IPosPayload } from '@/common/models/posPayload.model'
|
||||
import { QUERY_CONSTANTS } from '@/common/queryConstants'
|
||||
import { SharedSaleInvoiceActionsService } from '@/common/services/saleInvoices/sale-invoice-actions.service'
|
||||
import { SharedSaleInvoiceCreateService } from '@/common/services/saleInvoices/sale-invoice-create.service'
|
||||
import { SharedSaleInvoiceFilterService } from '@/common/services/saleInvoices/sale-invoice-filter.service'
|
||||
import { translateEnumValue } from '@/common/utils'
|
||||
import { PrismaService } from '@/prisma/prisma.service'
|
||||
import { Injectable, NotFoundException } from '@nestjs/common'
|
||||
@@ -9,7 +10,11 @@ import { ResponseMapper } from 'common/response/response-mapper'
|
||||
import { Prisma } from 'generated/prisma/client'
|
||||
import { TspProviderRequestType, TspProviderResponseStatus } from 'generated/prisma/enums'
|
||||
import { SalesInvoiceTspService } from '../../tspProviders/sales-invoice-tsp.service'
|
||||
import { CreateSalesInvoiceDto } from './dto/create-sales-invoice.dto'
|
||||
import {
|
||||
PosCorrectionSalesInvoiceDto,
|
||||
PosCreateSalesInvoiceDto,
|
||||
PosReturnSalesInvoiceDto,
|
||||
} from './dto/create-sales-invoice.dto'
|
||||
import { SalesInvoicesFilterDto } from './dto/sales-invoices-filter.dto'
|
||||
|
||||
@Injectable()
|
||||
@@ -19,6 +24,7 @@ export class SalesInvoicesService {
|
||||
private salesInvoiceTaxService: SalesInvoiceTspService,
|
||||
private sharedSaleInvoiceCreateService: SharedSaleInvoiceCreateService,
|
||||
private sharedSaleInvoiceActionsService: SharedSaleInvoiceActionsService,
|
||||
private sharedSaleInvoiceFilterService: SharedSaleInvoiceFilterService,
|
||||
) {}
|
||||
|
||||
async findAll(posInfo: IPosPayload, query: SalesInvoicesFilterDto = {}) {
|
||||
@@ -42,13 +48,13 @@ export class SalesInvoicesService {
|
||||
])
|
||||
|
||||
const summaryItems = items.map(invoice => {
|
||||
const { tsp_attempts, type, ...rest } = invoice
|
||||
const { last_tsp_status, type, ...rest } = invoice
|
||||
return {
|
||||
...rest,
|
||||
type: translateEnumValue('TspProviderRequestType', type),
|
||||
status: translateEnumValue(
|
||||
'TspProviderResponseStatus',
|
||||
invoice.tsp_attempts?.[0]?.status || TspProviderResponseStatus.NOT_SEND,
|
||||
last_tsp_status || TspProviderResponseStatus.NOT_SEND,
|
||||
),
|
||||
}
|
||||
})
|
||||
@@ -73,21 +79,25 @@ export class SalesInvoicesService {
|
||||
})
|
||||
|
||||
if (invoice) {
|
||||
const { tsp_attempts, type, ...rest } = invoice
|
||||
const { last_tsp_status, type, ...rest } = invoice
|
||||
const mappedInvoice = {
|
||||
...rest,
|
||||
type: translateEnumValue('TspProviderRequestType', type),
|
||||
status: translateEnumValue(
|
||||
'TspProviderResponseStatus',
|
||||
invoice.tsp_attempts?.[0]?.status || TspProviderResponseStatus.NOT_SEND,
|
||||
last_tsp_status || TspProviderResponseStatus.NOT_SEND,
|
||||
),
|
||||
settlement_type: translateEnumValue(
|
||||
'InvoiceSettlementType',
|
||||
invoice.settlement_type,
|
||||
),
|
||||
}
|
||||
|
||||
return ResponseMapper.single(mappedInvoice)
|
||||
} else throw new NotFoundException('فاکتور مورد نظر شما یافت نشد.')
|
||||
} else throw new NotFoundException('صورتحساب مورد نظر شما یافت نشد.')
|
||||
}
|
||||
|
||||
async create(data: CreateSalesInvoiceDto, posInfo: IPosPayload) {
|
||||
async create(data: PosCreateSalesInvoiceDto, posInfo: IPosPayload) {
|
||||
let salesInvoice = await this.sharedSaleInvoiceCreateService.create({
|
||||
data,
|
||||
businessId: posInfo.business_id,
|
||||
@@ -144,6 +154,40 @@ export class SalesInvoicesService {
|
||||
return ResponseMapper.single(invoice)
|
||||
}
|
||||
|
||||
async correction(
|
||||
invoiceId: string,
|
||||
posInfo: IPosPayload,
|
||||
data: PosCorrectionSalesInvoiceDto,
|
||||
) {
|
||||
const { consumer_account_id, pos_id, business_id, complex_id } = posInfo
|
||||
|
||||
const invoice = await this.sharedSaleInvoiceActionsService.correction(
|
||||
data,
|
||||
consumer_account_id,
|
||||
pos_id,
|
||||
complex_id,
|
||||
business_id,
|
||||
invoiceId,
|
||||
)
|
||||
|
||||
return ResponseMapper.single(invoice)
|
||||
}
|
||||
|
||||
async return(invoiceId: string, posInfo: IPosPayload, data: PosReturnSalesInvoiceDto) {
|
||||
const { consumer_account_id, pos_id, business_id, complex_id } = posInfo
|
||||
|
||||
const invoice = await this.sharedSaleInvoiceActionsService.return(
|
||||
data,
|
||||
consumer_account_id,
|
||||
pos_id,
|
||||
complex_id,
|
||||
business_id,
|
||||
invoiceId,
|
||||
)
|
||||
|
||||
return ResponseMapper.create(invoice)
|
||||
}
|
||||
|
||||
async inquiry(consumer_account_id: string, pos_id: string, invoiceId: string) {
|
||||
const invoice = await this.sharedSaleInvoiceActionsService.inquiry(
|
||||
consumer_account_id,
|
||||
@@ -155,151 +199,20 @@ export class SalesInvoicesService {
|
||||
|
||||
private buildFindAllWhere(posInfo: IPosPayload, query: SalesInvoicesFilterDto) {
|
||||
const where: Prisma.SalesInvoiceWhereInput = {
|
||||
...this.sharedSaleInvoiceFilterService.buildWhere(query),
|
||||
pos: {
|
||||
id: posInfo.pos_id,
|
||||
complex: {
|
||||
business_activity_id: posInfo.business_id,
|
||||
},
|
||||
},
|
||||
referenced_by: null,
|
||||
}
|
||||
|
||||
if (query.invoice_number) {
|
||||
where.invoice_number = parseInt(query.invoice_number + '')
|
||||
}
|
||||
|
||||
if (query.invoice_date_from || query.invoice_date_to) {
|
||||
where.invoice_date = {
|
||||
...(query.invoice_date_from ? { gte: new Date(query.invoice_date_from) } : {}),
|
||||
...(query.invoice_date_to ? { lte: new Date(query.invoice_date_to) } : {}),
|
||||
}
|
||||
}
|
||||
|
||||
if (query.created_at_from || query.created_at_to) {
|
||||
where.created_at = {
|
||||
...(query.created_at_from ? { gte: new Date(query.created_at_from) } : {}),
|
||||
...(query.created_at_to ? { lte: new Date(query.created_at_to) } : {}),
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
query.total_amount !== undefined ||
|
||||
query.total_amount_from !== undefined ||
|
||||
query.total_amount_to !== undefined
|
||||
) {
|
||||
where.total_amount = {
|
||||
...(query.total_amount !== undefined ? { equals: query.total_amount } : {}),
|
||||
...(query.total_amount_from !== undefined
|
||||
? { gte: query.total_amount_from }
|
||||
: {}),
|
||||
...(query.total_amount_to !== undefined ? { lte: query.total_amount_to } : {}),
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
query.customer_name?.trim() ||
|
||||
query.customer_mobile?.trim() ||
|
||||
query.customer_national_id?.trim() ||
|
||||
query.customer_economic_code?.trim()
|
||||
) {
|
||||
where.customer = {
|
||||
is: {
|
||||
OR: [
|
||||
...(query.customer_name?.trim()
|
||||
? [
|
||||
{
|
||||
individual: {
|
||||
is: {
|
||||
OR: [
|
||||
{
|
||||
first_name: {
|
||||
contains: query.customer_name.trim(),
|
||||
},
|
||||
},
|
||||
{
|
||||
last_name: {
|
||||
contains: query.customer_name.trim(),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
legal: {
|
||||
is: {
|
||||
name: {
|
||||
contains: query.customer_name.trim(),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...(query.customer_mobile?.trim()
|
||||
? [
|
||||
{
|
||||
individual: {
|
||||
is: {
|
||||
mobile_number: {
|
||||
contains: query.customer_mobile.trim(),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...(query.customer_national_id?.trim()
|
||||
? [
|
||||
{
|
||||
individual: {
|
||||
is: {
|
||||
national_id: {
|
||||
contains: query.customer_national_id.trim(),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...(query.customer_economic_code?.trim()
|
||||
? [
|
||||
{
|
||||
legal: {
|
||||
is: {
|
||||
OR: [
|
||||
{
|
||||
economic_code: {
|
||||
contains: query.customer_economic_code.trim(),
|
||||
},
|
||||
},
|
||||
{
|
||||
registration_number: {
|
||||
contains: query.customer_economic_code.trim(),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
: []),
|
||||
],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if (query.status) {
|
||||
if (query.status === TspProviderResponseStatus.NOT_SEND) {
|
||||
where.tsp_attempts = undefined
|
||||
} else {
|
||||
where.tsp_attempts = {
|
||||
some: {
|
||||
status: query.status,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return where
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,105 +14,98 @@ export class StatisticsService {
|
||||
async findAll(posId: string, businessId: string, fromDate: Date = new Date()) {
|
||||
const seasonDate = getCurrentJalaliSeasonRange(fromDate)
|
||||
|
||||
const [item] = await this.prisma.$queryRaw<
|
||||
const rows = await this.prisma.$queryRaw<
|
||||
Array<{
|
||||
all_amount_sum: number | null
|
||||
all_tax_sum: number | null
|
||||
all_count: number | null
|
||||
success_amount_sum: number | null
|
||||
success_tax_sum: number | null
|
||||
success_count: number | null
|
||||
failure_amount_sum: number | null
|
||||
failure_tax_sum: number | null
|
||||
failure_count: number | null
|
||||
pending_amount_sum: number | null
|
||||
pending_tax_sum: number | null
|
||||
pending_count: number | null
|
||||
not_sended_amount_sum: number | null
|
||||
not_sended_tax_sum: number | null
|
||||
not_sended_count: number | null
|
||||
not_original_amount_sum: number | null
|
||||
not_original_tax_sum: number | null
|
||||
not_original_count: number | null
|
||||
all_amount_sum: number
|
||||
all_tax_sum: number
|
||||
all_count: number
|
||||
success_amount_sum: number
|
||||
success_tax_sum: number
|
||||
success_count: number
|
||||
failure_amount_sum: number
|
||||
failure_tax_sum: number
|
||||
failure_count: number
|
||||
pending_amount_sum: number
|
||||
pending_tax_sum: number
|
||||
pending_count: number
|
||||
not_sended_amount_sum: number
|
||||
not_sended_tax_sum: number
|
||||
not_sended_count: number
|
||||
not_original_amount_sum: number
|
||||
not_original_tax_sum: number
|
||||
not_original_count: number
|
||||
}>
|
||||
>`
|
||||
SELECT
|
||||
SUM(si.total_amount) AS all_amount_sum,
|
||||
SUM(si.tax_amount) AS all_tax_sum,
|
||||
si.type,
|
||||
COUNT(*) AS all_count,
|
||||
SUM(CASE WHEN la.status = ${TspProviderResponseStatus.SUCCESS} THEN si.total_amount ELSE 0 END) AS success_amount_sum,
|
||||
SUM(CASE WHEN la.status = ${TspProviderResponseStatus.SUCCESS} THEN si.tax_amount ELSE 0 END) AS success_tax_sum,
|
||||
SUM(CASE WHEN la.status = ${TspProviderResponseStatus.SUCCESS} THEN 1 ELSE 0 END) AS success_count,
|
||||
SUM(CASE WHEN la.status = ${TspProviderResponseStatus.FAILURE} THEN si.total_amount ELSE 0 END) AS failure_amount_sum,
|
||||
SUM(CASE WHEN la.status = ${TspProviderResponseStatus.FAILURE} THEN si.tax_amount ELSE 0 END) AS failure_tax_sum,
|
||||
SUM(CASE WHEN la.status = ${TspProviderResponseStatus.FAILURE} THEN 1 ELSE 0 END) AS failure_count,
|
||||
SUM(CASE WHEN la.status = ${TspProviderResponseStatus.QUEUED} THEN si.total_amount ELSE 0 END) AS pending_amount_sum,
|
||||
SUM(CASE WHEN la.status = ${TspProviderResponseStatus.QUEUED} THEN si.tax_amount ELSE 0 END) AS pending_tax_sum,
|
||||
SUM(CASE WHEN la.status = ${TspProviderResponseStatus.QUEUED} THEN 1 ELSE 0 END) AS pending_count,
|
||||
SUM(CASE WHEN la.status IS NULL THEN si.total_amount ELSE 0 END) AS not_sended_amount_sum,
|
||||
SUM(CASE WHEN la.status IS NULL THEN si.tax_amount ELSE 0 END) AS not_sended_tax_sum,
|
||||
SUM(CASE WHEN la.status IS NULL THEN 1 ELSE 0 END) AS not_sended_count,
|
||||
SUM(CASE WHEN si.type <> ${TspProviderRequestType.ORIGINAL} THEN si.total_amount ELSE 0 END) AS not_original_amount_sum,
|
||||
SUM(CASE WHEN si.type <> ${TspProviderRequestType.ORIGINAL} THEN si.tax_amount ELSE 0 END) AS not_original_tax_sum,
|
||||
SUM(CASE WHEN si.type <> ${TspProviderRequestType.ORIGINAL} THEN 1 ELSE 0 END) AS not_original_count
|
||||
COUNT(*) AS all_count,
|
||||
COALESCE(SUM(si.total_amount), 0) AS all_amount_sum,
|
||||
COALESCE(SUM(si.tax_amount), 0) AS all_tax_sum,
|
||||
|
||||
SUM(si.last_tsp_status = ${TspProviderResponseStatus.SUCCESS}) AS success_count,
|
||||
COALESCE(SUM(CASE WHEN si.last_tsp_status = ${TspProviderResponseStatus.SUCCESS} THEN si.total_amount ELSE 0 END), 0) AS success_amount_sum,
|
||||
COALESCE(SUM(CASE WHEN si.last_tsp_status = ${TspProviderResponseStatus.SUCCESS} THEN si.tax_amount ELSE 0 END), 0) AS success_tax_sum,
|
||||
|
||||
SUM(si.last_tsp_status = ${TspProviderResponseStatus.FAILURE}) AS failure_count,
|
||||
COALESCE(SUM(CASE WHEN si.last_tsp_status = ${TspProviderResponseStatus.FAILURE} THEN si.total_amount ELSE 0 END), 0) AS failure_amount_sum,
|
||||
COALESCE(SUM(CASE WHEN si.last_tsp_status = ${TspProviderResponseStatus.FAILURE} THEN si.tax_amount ELSE 0 END), 0) AS failure_tax_sum,
|
||||
|
||||
SUM(si.last_tsp_status = ${TspProviderResponseStatus.FISCAL_QUEUED}) AS pending_count,
|
||||
COALESCE(SUM(CASE WHEN si.last_tsp_status = ${TspProviderResponseStatus.FISCAL_QUEUED} THEN si.total_amount ELSE 0 END), 0) AS pending_amount_sum,
|
||||
COALESCE(SUM(CASE WHEN si.last_tsp_status = ${TspProviderResponseStatus.FISCAL_QUEUED} THEN si.tax_amount ELSE 0 END), 0) AS pending_tax_sum,
|
||||
|
||||
SUM(si.last_tsp_status = ${TspProviderResponseStatus.NOT_SEND}) AS not_sended_count,
|
||||
COALESCE(SUM(CASE WHEN si.last_tsp_status = ${TspProviderResponseStatus.NOT_SEND} THEN si.total_amount ELSE 0 END), 0) AS not_sended_amount_sum,
|
||||
COALESCE(SUM(CASE WHEN si.last_tsp_status = ${TspProviderResponseStatus.NOT_SEND} THEN si.tax_amount ELSE 0 END), 0) AS not_sended_tax_sum,
|
||||
|
||||
SUM(si.type <> ${TspProviderRequestType.ORIGINAL}) AS not_original_count,
|
||||
COALESCE(SUM(CASE WHEN si.type <> ${TspProviderRequestType.ORIGINAL} THEN si.total_amount ELSE 0 END), 0) AS not_original_amount_sum,
|
||||
COALESCE(SUM(CASE WHEN si.type <> ${TspProviderRequestType.ORIGINAL} THEN si.tax_amount ELSE 0 END), 0) AS not_original_tax_sum
|
||||
|
||||
FROM sales_invoices si
|
||||
INNER JOIN poses p ON p.id = si.pos_id
|
||||
LEFT JOIN (
|
||||
SELECT att.invoice_id, att.status
|
||||
FROM sale_invoice_tsp_attempts att
|
||||
INNER JOIN (
|
||||
SELECT invoice_id, MAX(attempt_no) AS max_attempt_no
|
||||
FROM sale_invoice_tsp_attempts
|
||||
GROUP BY invoice_id
|
||||
) latest
|
||||
ON latest.invoice_id = att.invoice_id
|
||||
AND latest.max_attempt_no = att.attempt_no
|
||||
) la ON la.invoice_id = si.id
|
||||
WHERE si.invoice_date >= ${seasonDate.start}
|
||||
AND si.invoice_date <= ${seasonDate.end}
|
||||
AND si.pos_id = ${posId}
|
||||
AND p.complex_id IN (
|
||||
SELECT c.id FROM complexes c WHERE c.business_activity_id = ${businessId}
|
||||
SELECT c.id FROM complexes c WHERE c.business_activity_id = ${businessId}
|
||||
)
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM sales_invoices child
|
||||
WHERE child.ref_id = si.id
|
||||
)
|
||||
GROUP BY si.type
|
||||
`
|
||||
SELECT 1
|
||||
FROM sales_invoices child
|
||||
WHERE child.ref_id = si.id
|
||||
);
|
||||
`
|
||||
|
||||
return ResponseMapper.single({
|
||||
all: {
|
||||
total_amount: Number(item?.all_amount_sum || 0),
|
||||
total_tax: Number(item?.all_tax_sum),
|
||||
count: Number(item?.all_count || 0),
|
||||
total_amount: Number(rows[0].all_amount_sum || 0),
|
||||
total_tax: Number(rows[0].all_tax_sum || 0),
|
||||
count: Number(rows[0].all_count || 0),
|
||||
},
|
||||
success: {
|
||||
total_amount: Number(item?.success_amount_sum || 0),
|
||||
tax_amount: Number(item?.success_tax_sum || 0),
|
||||
count: Number(item?.success_count || 0),
|
||||
total_amount: Number(rows[0].success_amount_sum || 0),
|
||||
total_tax: Number(rows[0].success_tax_sum || 0),
|
||||
count: Number(rows[0].success_count || 0),
|
||||
},
|
||||
failure: {
|
||||
total_amount: Number(item?.failure_amount_sum || 0),
|
||||
tax_amount: Number(item?.failure_tax_sum || 0),
|
||||
count: Number(item?.failure_count || 0),
|
||||
total_amount: Number(rows[0].failure_amount_sum || 0),
|
||||
total_tax: Number(rows[0].failure_tax_sum || 0),
|
||||
count: Number(rows[0].failure_count || 0),
|
||||
},
|
||||
pending: {
|
||||
total_amount: Number(item?.pending_amount_sum || 0),
|
||||
tax_amount: Number(item?.pending_tax_sum || 0),
|
||||
count: Number(item?.pending_count || 0),
|
||||
total_amount: Number(rows[0].pending_amount_sum || 0),
|
||||
total_tax: Number(rows[0].pending_tax_sum || 0),
|
||||
count: Number(rows[0].pending_count || 0),
|
||||
},
|
||||
not_sended: {
|
||||
total_amount: Number(item?.not_sended_amount_sum || 0),
|
||||
tax_amount: Number(item?.not_sended_tax_sum || 0),
|
||||
count: Number(item?.not_sended_count || 0),
|
||||
not_send: {
|
||||
total_amount: Number(rows[0].not_sended_amount_sum || 0),
|
||||
total_tax: Number(rows[0].not_sended_tax_sum || 0),
|
||||
count: Number(rows[0].not_sended_count || 0),
|
||||
},
|
||||
not_original: {
|
||||
total_amount: Number(item?.not_original_amount_sum || 0),
|
||||
tax_amount: Number(item?.not_original_tax_sum || 0),
|
||||
count: Number(item?.not_original_count || 0),
|
||||
total_amount: Number(rows[0].not_original_amount_sum || 0),
|
||||
total_tax: Number(rows[0].not_original_tax_sum || 0),
|
||||
count: Number(rows[0].not_original_count || 0),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -13,48 +13,77 @@ import {
|
||||
IsObject,
|
||||
IsOptional,
|
||||
IsString,
|
||||
Length,
|
||||
Min,
|
||||
ValidateNested,
|
||||
} from 'class-validator'
|
||||
|
||||
export class CustomerUnknownInfoDto {
|
||||
@ApiProperty({})
|
||||
@ApiProperty()
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
name: string
|
||||
name?: string
|
||||
|
||||
@ApiProperty({})
|
||||
@ApiProperty()
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
economic_code: string
|
||||
economic_code?: string
|
||||
}
|
||||
|
||||
export class CustomerLegalInfoDto {
|
||||
@ApiProperty({ required: true })
|
||||
@ApiProperty()
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
name: string
|
||||
name?: string
|
||||
|
||||
@ApiProperty({ required: true })
|
||||
@ApiProperty()
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
economic_code: string
|
||||
registration_number?: string
|
||||
|
||||
@ApiProperty()
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
postal_code?: string
|
||||
|
||||
@ApiProperty()
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@Length(11)
|
||||
economic_code?: string
|
||||
}
|
||||
|
||||
export class CustomerIndividualInfoDto {
|
||||
@ApiProperty({ required: true })
|
||||
@ApiProperty()
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
first_name: string
|
||||
first_name?: string
|
||||
|
||||
@ApiProperty({ required: true })
|
||||
@ApiProperty()
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
last_name: string
|
||||
last_name?: string
|
||||
|
||||
@ApiProperty({ required: true })
|
||||
@ApiProperty()
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
national_id: string
|
||||
national_id?: string
|
||||
|
||||
@ApiProperty({ required: true })
|
||||
@ApiProperty()
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
mobile_number: string
|
||||
mobile_number?: string
|
||||
|
||||
@ApiProperty()
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
postal_code?: string
|
||||
|
||||
@ApiProperty()
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@Length(14)
|
||||
economic_code?: string
|
||||
}
|
||||
|
||||
export class CustomerInfoDto {
|
||||
@@ -64,12 +93,10 @@ export class CustomerInfoDto {
|
||||
|
||||
@ApiProperty({})
|
||||
@Type(() => CustomerLegalInfoDto)
|
||||
@ValidateNested({ each: true })
|
||||
legal_info?: CustomerLegalInfoDto
|
||||
|
||||
@ApiProperty({})
|
||||
@Type(() => CustomerIndividualInfoDto)
|
||||
@ValidateNested({ each: true })
|
||||
individual_info?: CustomerIndividualInfoDto
|
||||
|
||||
@ApiProperty({})
|
||||
|
||||
@@ -7,14 +7,22 @@ import { Type } from 'class-transformer'
|
||||
import {
|
||||
ArrayMinSize,
|
||||
IsArray,
|
||||
IsDateString,
|
||||
IsNumber,
|
||||
IsObject,
|
||||
IsString,
|
||||
ValidateNested,
|
||||
} from 'class-validator'
|
||||
import { TspProviderOriginalSendPayloadDto } from './original.dto'
|
||||
import {
|
||||
TspProviderOriginalResponseDto,
|
||||
TspProviderOriginalSendPayloadDto,
|
||||
} from './original.dto'
|
||||
|
||||
export class TspProviderCorrectionInvoicePayloadDto {
|
||||
@ApiProperty({ required: true, nullable: true })
|
||||
@IsDateString()
|
||||
invoice_date: Date
|
||||
|
||||
@ApiProperty({ type: [SharedCreateSalesInvoiceItemDto] })
|
||||
@IsArray()
|
||||
@ValidateNested({ each: true })
|
||||
@@ -38,12 +46,13 @@ export class TspProviderCorrectionInvoicePayloadDto {
|
||||
@IsObject()
|
||||
@ValidateNested({ each: true })
|
||||
@Type(() => SharedCreateSalesInvoicePaymentsDto)
|
||||
payments: SharedCreateSalesInvoicePaymentsDto
|
||||
payments?: SharedCreateSalesInvoicePaymentsDto
|
||||
}
|
||||
|
||||
export class TspProviderCorrectionSendPayloadDto extends TspProviderOriginalSendPayloadDto {
|
||||
@ApiProperty({ required: true })
|
||||
@IsString()
|
||||
last_tax_id: string
|
||||
}
|
||||
|
||||
export class TspProviderCorrectionSendResponseDto {}
|
||||
export class TspProviderCorrectionSendResponseDto extends TspProviderOriginalResponseDto {}
|
||||
|
||||
@@ -3,4 +3,5 @@ export * from './correction.dto'
|
||||
export * from './get.dto'
|
||||
export * from './original.dto'
|
||||
export * from './provider-switch.dto'
|
||||
export * from './return.dto'
|
||||
export * from './revoke.dto'
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
IsOptional,
|
||||
IsString,
|
||||
Min,
|
||||
ValidateNested
|
||||
ValidateNested,
|
||||
} from 'class-validator'
|
||||
import {
|
||||
CustomerInfoDto,
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import { SharedCreateSalesInvoiceItemDto } from '@/common/services/saleInvoices/sale-invoice-create.dto'
|
||||
import { ApiProperty } from '@nestjs/swagger'
|
||||
import { Type } from 'class-transformer'
|
||||
import {
|
||||
ArrayMinSize,
|
||||
IsArray,
|
||||
IsDateString,
|
||||
IsNumber,
|
||||
IsString,
|
||||
ValidateNested,
|
||||
} from 'class-validator'
|
||||
import {
|
||||
TspProviderOriginalResponseDto,
|
||||
TspProviderOriginalSendPayloadDto,
|
||||
} from './original.dto'
|
||||
|
||||
export class TspProviderReturnInvoicePayloadDto {
|
||||
@ApiProperty({ required: true, nullable: true })
|
||||
@IsDateString()
|
||||
invoice_date: Date
|
||||
|
||||
@ApiProperty({ type: [SharedCreateSalesInvoiceItemDto] })
|
||||
@IsArray()
|
||||
@ValidateNested({ each: true })
|
||||
@Type(() => SharedCreateSalesInvoiceItemDto)
|
||||
@ArrayMinSize(1)
|
||||
items: SharedCreateSalesInvoiceItemDto[]
|
||||
|
||||
@ApiProperty()
|
||||
@IsNumber()
|
||||
total_amount: number
|
||||
|
||||
@ApiProperty()
|
||||
@IsNumber()
|
||||
discount_amount: number
|
||||
|
||||
@ApiProperty()
|
||||
@IsNumber()
|
||||
tax_amount: number
|
||||
}
|
||||
|
||||
export class TspProviderReturnSendPayloadDto extends TspProviderOriginalSendPayloadDto {
|
||||
@ApiProperty({ required: true })
|
||||
@IsString()
|
||||
last_tax_id: string
|
||||
}
|
||||
|
||||
export class TspProviderReturnSendResponseDto extends TspProviderOriginalResponseDto {}
|
||||
@@ -6,6 +6,8 @@ import {
|
||||
TspProviderGetResponseDto,
|
||||
TspProviderOriginalResponseDto,
|
||||
TspProviderOriginalSendPayloadDto,
|
||||
TspProviderReturnSendPayloadDto,
|
||||
TspProviderReturnSendResponseDto,
|
||||
TspProviderRevokePayloadDto,
|
||||
TspProviderRevokeResponseDto,
|
||||
} from './dto'
|
||||
@@ -48,6 +50,14 @@ export class SalesInvoiceTspSwitchService {
|
||||
return adapter.correctionSend(payload)
|
||||
}
|
||||
|
||||
async returnFromSale(
|
||||
payload: TspProviderReturnSendPayloadDto,
|
||||
): Promise<TspProviderReturnSendResponseDto> {
|
||||
const adapter = this.resolveSwitch(payload.tsp_provider)
|
||||
|
||||
return adapter.returnSend(payload)
|
||||
}
|
||||
|
||||
async sendBulk(
|
||||
payloads: TspProviderOriginalSendPayloadDto[],
|
||||
): Promise<TspProviderBulkSendResultDto[]> {
|
||||
|
||||
@@ -6,18 +6,15 @@ import {
|
||||
TspProviderRequestType,
|
||||
TspProviderResponseStatus,
|
||||
} from 'generated/prisma/client'
|
||||
import {
|
||||
TspProviderActionResponseDto,
|
||||
TspProviderCorrectionInvoicePayloadDto,
|
||||
} from './dto'
|
||||
import { TspProviderActionResponseDto } from './dto'
|
||||
import { SalesInvoiceTspSwitchService } from './sales-invoice-tsp-switch.service'
|
||||
import {
|
||||
buildCorrectionPayload,
|
||||
buildOriginalPayload,
|
||||
buildReturnFromSalePayload,
|
||||
buildRevokePayload,
|
||||
getOriginalResendAttemptNumber,
|
||||
onResult,
|
||||
trySend,
|
||||
} from './utils/sales-invoice-tsp.utils'
|
||||
|
||||
type ItemTspRow = {
|
||||
@@ -41,20 +38,28 @@ export class SalesInvoiceTspService {
|
||||
|
||||
const attemptNumber = await getOriginalResendAttemptNumber(this.prisma, invoice_id)
|
||||
|
||||
const attempt = await this.prisma.saleInvoiceTspAttempts.create({
|
||||
const invoice = await this.prisma.salesInvoice.update({
|
||||
where: {
|
||||
id: invoice_id,
|
||||
},
|
||||
data: {
|
||||
attempt_no: attemptNumber,
|
||||
invoice_id,
|
||||
provider_request_payload: {},
|
||||
status: TspProviderResponseStatus.QUEUED,
|
||||
raw_request_payload: JSON.parse(JSON.stringify(payload)),
|
||||
sent_at: new Date().toISOString(),
|
||||
message: 'در حال ارسال به سامانه مالیاتی...',
|
||||
last_tsp_status: TspProviderResponseStatus.QUEUED,
|
||||
last_attempt_no: attemptNumber,
|
||||
tsp_attempts: {
|
||||
create: {
|
||||
attempt_no: attemptNumber,
|
||||
provider_request_payload: {},
|
||||
status: TspProviderResponseStatus.QUEUED,
|
||||
raw_request_payload: JSON.parse(JSON.stringify(payload)),
|
||||
sent_at: new Date().toISOString(),
|
||||
message: 'در حال ارسال به سامانه مالیاتی...',
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const result = await this.tspSwitchService.send(payload)
|
||||
return await onResult(this.prisma, result, attempt.id)
|
||||
return await onResult(this.prisma, result, invoice.id)
|
||||
}
|
||||
|
||||
async sendBulk(consumer_id: string, invoice_ids: string[]): Promise<void> {
|
||||
@@ -74,18 +79,17 @@ export class SalesInvoiceTspService {
|
||||
pos_id: string,
|
||||
consumer_id: string,
|
||||
): Promise<TspProviderActionResponseDto> {
|
||||
const [attempt, pos] = await this.prisma.$transaction(async tx => [
|
||||
await tx.saleInvoiceTspAttempts.findFirst({
|
||||
const [invoice, pos] = await this.prisma.$transaction(async tx => [
|
||||
await tx.salesInvoice.findUnique({
|
||||
where: {
|
||||
invoice_id,
|
||||
invoice: {
|
||||
pos: {
|
||||
id: pos_id,
|
||||
},
|
||||
id: invoice_id,
|
||||
pos: {
|
||||
id: pos_id,
|
||||
},
|
||||
},
|
||||
orderBy: {
|
||||
attempt_no: 'desc',
|
||||
select: {
|
||||
last_tsp_status: true,
|
||||
id: true,
|
||||
},
|
||||
}),
|
||||
|
||||
@@ -134,12 +138,25 @@ export class SalesInvoiceTspService {
|
||||
}),
|
||||
])
|
||||
|
||||
if (!attempt) {
|
||||
throw new NotFoundException('صورتحساب ارسالی فاکتور شما به سامانه یافت نشد.')
|
||||
if (!invoice) {
|
||||
throw new NotFoundException('صورتحساب ارسالی صورتحساب شما به سامانه یافت نشد.')
|
||||
}
|
||||
if (!pos) {
|
||||
throw new NotFoundException('مشکلی در ساختار اطلاعات ورودی شما وجود دارد.')
|
||||
}
|
||||
if (
|
||||
!invoice.last_tsp_status ||
|
||||
invoice.last_tsp_status === TspProviderResponseStatus.NOT_SEND
|
||||
) {
|
||||
throw new BadRequestException(
|
||||
'صورتحساب شما هنوز به سامانه مالیاتی ارسال نشده است. لطفا چند لحظه دیگر مجددا تلاش کنید.',
|
||||
)
|
||||
}
|
||||
if (invoice.last_tsp_status === TspProviderResponseStatus.QUEUED) {
|
||||
throw new BadRequestException(
|
||||
'صورتحساب شما در صف ارسال به سامانه مالیاتی قرار دارد. لطفا چند لحظه دیگر مجددا تلاش کنید.',
|
||||
)
|
||||
}
|
||||
|
||||
const { business_activity } = pos.complex
|
||||
|
||||
@@ -152,130 +169,72 @@ export class SalesInvoiceTspService {
|
||||
business_activity.partner_token,
|
||||
)
|
||||
|
||||
return await onResult(this.prisma, result, attempt.id)
|
||||
return await onResult(this.prisma, result, invoice.id)
|
||||
}
|
||||
|
||||
async correctionSend(
|
||||
consumerAccountId: string,
|
||||
posId: string,
|
||||
complexId: string,
|
||||
businessId: string,
|
||||
ref_invoice_id: string,
|
||||
dataToUpdate: TspProviderCorrectionInvoicePayloadDto,
|
||||
invoice_id: string,
|
||||
): Promise<TspProviderActionResponseDto> {
|
||||
const [newInvoice, attempt, correctionPayload] = await this.prisma.$transaction(
|
||||
async tx => {
|
||||
const relatedInvoice = await tx.salesInvoice.findUnique({
|
||||
where: {
|
||||
id: ref_invoice_id,
|
||||
},
|
||||
include: {
|
||||
customer: {
|
||||
select: {
|
||||
type: true,
|
||||
},
|
||||
},
|
||||
tsp_attempts: {
|
||||
orderBy: {
|
||||
attempt_no: 'desc',
|
||||
},
|
||||
take: 1,
|
||||
},
|
||||
},
|
||||
})
|
||||
const payload = await buildCorrectionPayload(this.prisma, invoice_id, posId)
|
||||
|
||||
if (!relatedInvoice) {
|
||||
throw new NotFoundException('فاکتور مورد نظر یافت نشد.')
|
||||
}
|
||||
const attemptNumber = 1
|
||||
|
||||
if (relatedInvoice.type === TspProviderRequestType.REVOKE) {
|
||||
throw new BadRequestException(
|
||||
'فاکتور ارسالی قبلا ابطال شده است و امکان ویرایش آن وجود ندارد.',
|
||||
)
|
||||
}
|
||||
|
||||
if (!relatedInvoice.tax_id) {
|
||||
throw new BadRequestException(
|
||||
'فاکتور قبلی همچنان در حال بررسی است و امکان ویرایش آن وجود ندارد.',
|
||||
)
|
||||
}
|
||||
|
||||
const newInvoice = await this.sharedSaleInvoiceCreateService.create({
|
||||
data: {
|
||||
customer_type: relatedInvoice.customer?.type || CustomerType.UNKNOWN,
|
||||
invoice_date: new Date(),
|
||||
payments: dataToUpdate.payments,
|
||||
items: dataToUpdate.items,
|
||||
total_amount: dataToUpdate.total_amount,
|
||||
discount_amount: dataToUpdate.discount_amount,
|
||||
tax_amount: dataToUpdate.tax_amount,
|
||||
customer_id: relatedInvoice.customer_id || undefined,
|
||||
settlement_type: relatedInvoice.settlement_type,
|
||||
},
|
||||
businessId,
|
||||
complexId,
|
||||
posId,
|
||||
consumerAccountId,
|
||||
main_invoice_id: relatedInvoice.main_id || relatedInvoice.id,
|
||||
ref_invoice_id: relatedInvoice.id,
|
||||
type: TspProviderRequestType.CORRECTION,
|
||||
})
|
||||
|
||||
const correctionPayload = await buildCorrectionPayload(tx, newInvoice.id)
|
||||
|
||||
const attempt = await tx.saleInvoiceTspAttempts.create({
|
||||
data: {
|
||||
attempt_no: 1,
|
||||
invoice_id: newInvoice.id,
|
||||
message: 'در حال ارسال به سامانه مالیاتی...',
|
||||
status: TspProviderResponseStatus.QUEUED,
|
||||
sent_at: new Date().toISOString(),
|
||||
raw_request_payload: JSON.parse(JSON.stringify(correctionPayload)),
|
||||
provider_request_payload: {},
|
||||
},
|
||||
})
|
||||
|
||||
return [newInvoice, attempt, correctionPayload]
|
||||
const invoice = await this.prisma.salesInvoice.update({
|
||||
where: {
|
||||
id: invoice_id,
|
||||
},
|
||||
)
|
||||
data: {
|
||||
last_tsp_status: TspProviderResponseStatus.QUEUED,
|
||||
last_attempt_no: attemptNumber,
|
||||
type: TspProviderRequestType.CORRECTION,
|
||||
tsp_attempts: {
|
||||
create: {
|
||||
attempt_no: attemptNumber,
|
||||
provider_request_payload: {},
|
||||
status: TspProviderResponseStatus.QUEUED,
|
||||
raw_request_payload: JSON.parse(JSON.stringify(payload)),
|
||||
sent_at: new Date().toISOString(),
|
||||
message: 'در حال ارسال به سامانه مالیاتی...',
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const result = await this.runProviderCall(() =>
|
||||
trySend(this.tspSwitchService, correctionPayload),
|
||||
)
|
||||
if (result?.hasError) {
|
||||
result.provider_request_payload =
|
||||
result.provider_request_payload || JSON.parse(JSON.stringify(correctionPayload))
|
||||
result.sent_at = result.sent_at || new Date().toISOString()
|
||||
result.received_at = result.received_at || new Date().toISOString()
|
||||
}
|
||||
const result = await this.tspSwitchService.send(payload)
|
||||
return await onResult(this.prisma, result, invoice.id)
|
||||
}
|
||||
|
||||
return onResult(this.prisma, result, attempt.id)
|
||||
async returnFromSaleSend(
|
||||
pos_id: string,
|
||||
business_id: string,
|
||||
invoice_id: string,
|
||||
): Promise<TspProviderActionResponseDto> {
|
||||
const payload = await buildReturnFromSalePayload(this.prisma, invoice_id, pos_id)
|
||||
|
||||
// const countByGoodId = (goodIds: string[]): Map<string, number> => {
|
||||
// const counts = new Map<string, number>()
|
||||
// for (const goodId of goodIds) {
|
||||
// counts.set(goodId, (counts.get(goodId) ?? 0) + 1)
|
||||
// }
|
||||
// return counts
|
||||
// }
|
||||
const attemptNumber = 1
|
||||
|
||||
// const updatedGoodIds = dataToUpdate.items.map(item => item.good_id!)
|
||||
// const previousGoodIds = lastAttempt.invoice.items.map(item => item.good_id)
|
||||
|
||||
// const updatedCounts = countByGoodId(updatedGoodIds)
|
||||
// const previousCounts = countByGoodId(previousGoodIds)
|
||||
|
||||
// let isBackFromSale = false
|
||||
// if (updatedCounts.size !== previousCounts.size) {
|
||||
// isBackFromSale = true
|
||||
// } else {
|
||||
// for (const [goodId, count] of updatedCounts) {
|
||||
// if (previousCounts.get(goodId) !== count) {
|
||||
// isBackFromSale = true
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
const invoice = await this.prisma.salesInvoice.update({
|
||||
where: {
|
||||
id: invoice_id,
|
||||
},
|
||||
data: {
|
||||
last_tsp_status: TspProviderResponseStatus.QUEUED,
|
||||
last_attempt_no: attemptNumber,
|
||||
tsp_attempts: {
|
||||
create: {
|
||||
attempt_no: attemptNumber,
|
||||
provider_request_payload: {},
|
||||
status: TspProviderResponseStatus.QUEUED,
|
||||
raw_request_payload: JSON.parse(JSON.stringify(payload)),
|
||||
sent_at: new Date().toISOString(),
|
||||
message: 'در حال ارسال به سامانه مالیاتی...',
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
const result = await this.tspSwitchService.returnFromSale(payload)
|
||||
return await onResult(this.prisma, result, invoice.id)
|
||||
}
|
||||
|
||||
async revoke(
|
||||
@@ -313,86 +272,87 @@ export class SalesInvoiceTspService {
|
||||
})
|
||||
|
||||
if (!relatedInvoice) {
|
||||
throw new NotFoundException('فاکتور مورد نظر یافت نشد.')
|
||||
throw new NotFoundException('صورتحساب مورد نظر یافت نشد.')
|
||||
}
|
||||
|
||||
if (relatedInvoice.type === TspProviderRequestType.REVOKE) {
|
||||
throw new BadRequestException(
|
||||
'فاکتور ارسالی قبلا ابطال شده است و امکان ویرایش آن وجود ندارد.',
|
||||
'صورتحساب ارسالی قبلا ابطال شده است و امکان ویرایش آن وجود ندارد.',
|
||||
)
|
||||
}
|
||||
|
||||
if (!relatedInvoice.tax_id) {
|
||||
throw new BadRequestException(
|
||||
'فاکتور قبلی همچنان در حال بررسی است و امکان ویرایش آن وجود ندارد.',
|
||||
'صورتحساب قبلی همچنان در حال بررسی است و امکان ویرایش آن وجود ندارد.',
|
||||
)
|
||||
}
|
||||
|
||||
const payments = relatedInvoice.payments.reduce(
|
||||
(acc, payment) => {
|
||||
const amount = Number(payment.amount)
|
||||
switch (payment.payment_method) {
|
||||
case 'CASH':
|
||||
acc.cash = (acc.cash || 0) + amount
|
||||
break
|
||||
case 'SET_OFF':
|
||||
acc.set_off = (acc.set_off || 0) + amount
|
||||
break
|
||||
case 'CARD':
|
||||
acc.card = (acc.card || 0) + amount
|
||||
break
|
||||
case 'BANK':
|
||||
acc.bank = (acc.bank || 0) + amount
|
||||
break
|
||||
case 'CHEQUE':
|
||||
acc.check = (acc.check || 0) + amount
|
||||
break
|
||||
case 'OTHER':
|
||||
acc.other = (acc.other || 0) + amount
|
||||
break
|
||||
case 'TERMINAL':
|
||||
acc.terminals = payment.terminal_info
|
||||
? {
|
||||
amount,
|
||||
terminalId: payment.terminal_info.terminal_id,
|
||||
stan: payment.terminal_info.stan,
|
||||
rrn: payment.terminal_info.rrn,
|
||||
customer_card_no:
|
||||
payment.terminal_info.customer_card_no || undefined,
|
||||
transaction_date_time: payment.terminal_info.transaction_date_time,
|
||||
description: payment.terminal_info.description || undefined,
|
||||
}
|
||||
: acc.terminals
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
return acc
|
||||
},
|
||||
{} as {
|
||||
terminals?: {
|
||||
amount?: number
|
||||
terminalId: string
|
||||
stan: string
|
||||
rrn: string
|
||||
customer_card_no?: string
|
||||
transaction_date_time: Date
|
||||
description?: string
|
||||
}
|
||||
cash?: number
|
||||
set_off?: number
|
||||
card?: number
|
||||
bank?: number
|
||||
check?: number
|
||||
other?: number
|
||||
},
|
||||
)
|
||||
// const payments = relatedInvoice.payments.reduce(
|
||||
// (acc, payment) => {
|
||||
// const amount = Number(payment.amount)
|
||||
// switch (payment.payment_method) {
|
||||
// case 'CASH':
|
||||
// acc.cash = (acc.cash || 0) + amount
|
||||
// break
|
||||
// case 'SET_OFF':
|
||||
// acc.set_off = (acc.set_off || 0) + amount
|
||||
// break
|
||||
// case 'CARD':
|
||||
// acc.card = (acc.card || 0) + amount
|
||||
// break
|
||||
// case 'BANK':
|
||||
// acc.bank = (acc.bank || 0) + amount
|
||||
// break
|
||||
// case 'CHEQUE':
|
||||
// acc.check = (acc.check || 0) + amount
|
||||
// break
|
||||
// case 'OTHER':
|
||||
// acc.other = (acc.other || 0) + amount
|
||||
// break
|
||||
// case 'TERMINAL':
|
||||
// acc.terminals = payment.terminal_info
|
||||
// ? {
|
||||
// amount,
|
||||
// terminal_id: payment.terminal_info.terminal_id,
|
||||
// stan: payment.terminal_info.stan,
|
||||
// rrn: payment.terminal_info.rrn,
|
||||
// customer_card_no:
|
||||
// payment.terminal_info.customer_card_no || undefined,
|
||||
// transaction_date_time: payment.terminal_info.transaction_date_time,
|
||||
// description: payment.terminal_info.description || undefined,
|
||||
// }
|
||||
// : acc.terminals
|
||||
// break
|
||||
// default:
|
||||
// break
|
||||
// }
|
||||
// return acc
|
||||
// },
|
||||
// {} as {
|
||||
// terminals?: {
|
||||
// amount?: number
|
||||
// terminalId: string
|
||||
// stan: string
|
||||
// rrn: string
|
||||
// customer_card_no?: string
|
||||
// transaction_date_time: Date
|
||||
// description?: string
|
||||
// }
|
||||
// cash?: number
|
||||
// set_off?: number
|
||||
// card?: number
|
||||
// bank?: number
|
||||
// check?: number
|
||||
// other?: number
|
||||
// },
|
||||
// )
|
||||
|
||||
const newInvoice = await this.sharedSaleInvoiceCreateService.create({
|
||||
data: {
|
||||
customer_type: relatedInvoice.customer?.type || CustomerType.UNKNOWN,
|
||||
invoice_date: new Date(),
|
||||
payments,
|
||||
// @ts-ignore
|
||||
payments: undefined,
|
||||
settlement_type: relatedInvoice.settlement_type,
|
||||
items: relatedInvoice.items.map(item => ({
|
||||
unit_price: Number(item.unit_price),
|
||||
|
||||
@@ -226,7 +226,7 @@ export class NamaProviderValidationErrorDto {
|
||||
}
|
||||
|
||||
export class NamaProviderResponseDto {
|
||||
@ApiProperty({ description: 'شناسه پیگیری فاکتور' })
|
||||
@ApiProperty({ description: 'شناسه پیگیری صورتحساب' })
|
||||
@IsString()
|
||||
uuid: string
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user