feat: implement SalesInvoiceTspSwitchService and SalesInvoiceTspService for handling TSP provider interactions
- Add SalesInvoiceTspSwitchService to manage TSP provider selection and sending invoices. - Introduce SalesInvoiceTspService for creating, sending, and retrieving sales invoices. - Implement NamaProviderSwitchAdapter for communication with the NAMA TSP provider API. - Define DTOs for request and response structures specific to the NAMA provider. - Enhance error handling and logging for TSP provider interactions.
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
-- DropForeignKey
|
||||
ALTER TABLE `admin_accounts` DROP FOREIGN KEY `admin_accounts_account_id_fkey`;
|
||||
|
||||
-- DropForeignKey
|
||||
ALTER TABLE `partner_accounts` DROP FOREIGN KEY `partner_accounts_account_id_fkey`;
|
||||
|
||||
-- DropForeignKey
|
||||
ALTER TABLE `provider_accounts` DROP FOREIGN KEY `provider_accounts_account_id_fkey`;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE `guilds` ADD COLUMN `invoice_template` ENUM('SALE', 'FX_SALE', 'GOLD_JEWELRY', 'CONTRACT', 'UTILITY', 'AIR_TICKET', 'EXPORT', 'BILL_OF_LADING', 'PETROCHEMICAL', 'COMMODITY_EXCHANGE', 'INSURANCE') NOT NULL DEFAULT 'GOLD_JEWELRY';
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `admin_accounts` ADD CONSTRAINT `admin_accounts_account_id_fkey` FOREIGN KEY (`account_id`) REFERENCES `accounts`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `partner_accounts` ADD CONSTRAINT `partner_accounts_account_id_fkey` FOREIGN KEY (`account_id`) REFERENCES `accounts`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `provider_accounts` ADD CONSTRAINT `provider_accounts_account_id_fkey` FOREIGN KEY (`account_id`) REFERENCES `accounts`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `fiscal_switch_type` on the `partners` table. All the data in the column will be lost.
|
||||
- The values [CHECK] on the enum `sales_invoice_payments_payment_method` will be removed. If these variants are still used in the database, this will fail.
|
||||
- You are about to drop the `sale_invoice_fiscal_attempts` table. If the table is not empty, all the data it contains will be lost.
|
||||
- You are about to drop the `sale_invoice_fiscals` table. If the table is not empty, all the data it contains will be lost.
|
||||
- Made the column `good_snapshot` on table `sales_invoice_items` required. This step will fail if there are existing NULL values in that column.
|
||||
- Made the column `good_id` on table `sales_invoice_items` required. This step will fail if there are existing NULL values in that column.
|
||||
|
||||
*/
|
||||
-- DropForeignKey
|
||||
ALTER TABLE `sale_invoice_fiscal_attempts` DROP FOREIGN KEY `sale_invoice_fiscal_attempts_fiscal_id_fkey`;
|
||||
|
||||
-- DropForeignKey
|
||||
ALTER TABLE `sale_invoice_fiscals` DROP FOREIGN KEY `sale_invoice_fiscals_invoice_id_fkey`;
|
||||
|
||||
-- DropForeignKey
|
||||
ALTER TABLE `sales_invoice_items` DROP FOREIGN KEY `sales_invoice_items_good_id_fkey`;
|
||||
|
||||
-- DropIndex
|
||||
DROP INDEX `sales_invoice_items_good_id_fkey` ON `sales_invoice_items`;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE `business_activities` ADD COLUMN `invoice_number_sequence` VARCHAR(191) NOT NULL DEFAULT '1';
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE `partners` DROP COLUMN `fiscal_switch_type`,
|
||||
ADD COLUMN `tsp_provider` ENUM('NAMA', 'SUN') NOT NULL DEFAULT 'NAMA';
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE `sales_invoice_items` MODIFY `good_snapshot` JSON NOT NULL,
|
||||
MODIFY `good_id` VARCHAR(191) NOT NULL;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE `sales_invoice_payments` MODIFY `payment_method` ENUM('CHEQUE', 'SET_OFF', 'CASH', 'TERMINAL', 'PAYMENT_GATEWAY', 'CARD', 'BANK', 'OTHER') NOT NULL;
|
||||
|
||||
-- DropTable
|
||||
DROP TABLE `sale_invoice_fiscal_attempts`;
|
||||
|
||||
-- DropTable
|
||||
DROP TABLE `sale_invoice_fiscals`;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `sale_invoice_tsp_attempts` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`attempt_no` INTEGER NOT NULL,
|
||||
`status` ENUM('SUCCESS', 'FAILURE', 'NOT_SEND', 'QUEUED') NOT NULL,
|
||||
`tax_id` VARCHAR(191) NULL,
|
||||
`type` ENUM('MAIN', 'UPDATE', 'REVOKE', 'REMOVE') NOT NULL,
|
||||
`request_payload` JSON NULL,
|
||||
`response_payload` JSON NULL,
|
||||
`error_message` TEXT NULL,
|
||||
`sent_at` TIMESTAMP(0) NULL,
|
||||
`received_at` TIMESTAMP(0) NULL,
|
||||
`created_at` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`invoice_id` VARCHAR(191) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `sale_invoice_tsp_attempts_tax_id_key`(`tax_id`),
|
||||
UNIQUE INDEX `sale_invoice_tsp_attempts_invoice_id_key`(`invoice_id`),
|
||||
INDEX `sale_invoice_tsp_attempts_status_idx`(`status`),
|
||||
INDEX `sale_invoice_tsp_attempts_tax_id_idx`(`tax_id`),
|
||||
INDEX `sale_invoice_tsp_attempts_invoice_id_idx`(`invoice_id`),
|
||||
UNIQUE INDEX `sale_invoice_tsp_attempts_invoice_id_attempt_no_key`(`invoice_id`, `attempt_no`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `sales_invoice_items` ADD CONSTRAINT `sales_invoice_items_good_id_fkey` FOREIGN KEY (`good_id`) REFERENCES `goods`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `sale_invoice_tsp_attempts` ADD CONSTRAINT `sale_invoice_tsp_attempts_invoice_id_fkey` FOREIGN KEY (`invoice_id`) REFERENCES `sales_invoices`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to alter the column `invoice_number_sequence` on the `business_activities` table. The data in that column could be lost. The data in that column will be cast from `VarChar(191)` to `Decimal(20,0)`.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE `business_activities` MODIFY `invoice_number_sequence` DECIMAL(20, 0) NOT NULL DEFAULT 1;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE `guilds` ALTER COLUMN `invoice_template` DROP DEFAULT;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE `stock_keeping_units` ALTER COLUMN `type` DROP DEFAULT;
|
||||
@@ -15,12 +15,12 @@ model PartnerAccount {
|
||||
}
|
||||
|
||||
model Partner {
|
||||
id String @id @default(ulid())
|
||||
name String
|
||||
code String @unique()
|
||||
status PartnerStatus @default(ACTIVE)
|
||||
fiscal_switch_type PartnerFiscalSwitchType
|
||||
logo_url String?
|
||||
id String @id @default(ulid())
|
||||
name String
|
||||
code String @unique()
|
||||
status PartnerStatus @default(ACTIVE)
|
||||
tsp_provider TspProviderType @default(NAMA)
|
||||
logo_url String?
|
||||
|
||||
created_at DateTime @default(now()) @db.Timestamp(0)
|
||||
updated_at DateTime @default(now()) @updatedAt @db.Timestamp(0)
|
||||
|
||||
@@ -74,11 +74,12 @@ model ConsumerLegal {
|
||||
}
|
||||
|
||||
model BusinessActivity {
|
||||
id String @id @default(ulid())
|
||||
economic_code String
|
||||
name String
|
||||
fiscal_id String
|
||||
partner_token String
|
||||
id String @id @default(ulid())
|
||||
economic_code String
|
||||
name String
|
||||
fiscal_id String
|
||||
partner_token String
|
||||
invoice_number_sequence Decimal @default(1) @db.Decimal(20, 0)
|
||||
|
||||
created_at DateTime @default(now()) @db.Timestamp(0)
|
||||
updated_at DateTime @updatedAt() @db.Timestamp(0)
|
||||
|
||||
@@ -3,7 +3,7 @@ model StockKeepingUnits {
|
||||
code String @unique
|
||||
name String
|
||||
VAT Decimal @db.Decimal(5, 2)
|
||||
type SKUGuildType @default(GOLD)
|
||||
type SKUGuildType
|
||||
is_public Boolean @default(true)
|
||||
is_domestic Boolean @default(false)
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
enum PaymentMethodType {
|
||||
TERMINAL
|
||||
CASH
|
||||
CHEQUE
|
||||
SET_OFF
|
||||
CASH
|
||||
TERMINAL
|
||||
PAYMENT_GATEWAY
|
||||
CARD
|
||||
BANK
|
||||
CHECK
|
||||
OTHER
|
||||
}
|
||||
|
||||
@@ -156,26 +157,26 @@ enum ConsumerType {
|
||||
LEGAL
|
||||
}
|
||||
|
||||
enum PartnerFiscalSwitchType {
|
||||
enum TspProviderType {
|
||||
NAMA
|
||||
SUN
|
||||
}
|
||||
|
||||
enum FiscalResponseStatus {
|
||||
enum TspProviderResponseStatus {
|
||||
SUCCESS
|
||||
FAILURE
|
||||
NOT_SEND
|
||||
QUEUED
|
||||
}
|
||||
|
||||
enum FiscalRequestType {
|
||||
enum TspProviderRequestType {
|
||||
MAIN
|
||||
UPDATE
|
||||
REVOKE
|
||||
REMOVE
|
||||
}
|
||||
|
||||
enum FiscalInvoiceCustomerType {
|
||||
enum TspProviderCustomerType {
|
||||
Unknown
|
||||
Known
|
||||
}
|
||||
@@ -183,3 +184,17 @@ enum FiscalInvoiceCustomerType {
|
||||
enum SKUGuildType {
|
||||
GOLD
|
||||
}
|
||||
|
||||
enum InvoiceTemplateType {
|
||||
SALE
|
||||
FX_SALE
|
||||
GOLD_JEWELRY
|
||||
CONTRACT
|
||||
UTILITY
|
||||
AIR_TICKET
|
||||
EXPORT
|
||||
BILL_OF_LADING
|
||||
PETROCHEMICAL
|
||||
COMMODITY_EXCHANGE
|
||||
INSURANCE
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
model Guild {
|
||||
id String @id @default(ulid())
|
||||
name String
|
||||
code String?
|
||||
id String @id @default(ulid())
|
||||
name String
|
||||
invoice_template InvoiceTemplateType
|
||||
code String?
|
||||
|
||||
created_at DateTime @default(now()) @db.Timestamp(0)
|
||||
updated_at DateTime @updatedAt() @db.Timestamp(0)
|
||||
|
||||
@@ -20,10 +20,9 @@ model SalesInvoice {
|
||||
pos_id String
|
||||
pos Pos @relation(fields: [pos_id], references: [id])
|
||||
|
||||
fiscal SaleInvoiceFiscals?
|
||||
|
||||
items SalesInvoiceItem[]
|
||||
payments SalesInvoicePayment[]
|
||||
items SalesInvoiceItem[]
|
||||
payments SalesInvoicePayment[]
|
||||
tsp_attempts SaleInvoiceTspAttempts[]
|
||||
|
||||
@@unique([invoice_number, pos_id])
|
||||
@@map("sales_invoices")
|
||||
@@ -43,13 +42,13 @@ model SalesInvoiceItem {
|
||||
notes String? @db.Text
|
||||
|
||||
payload Json?
|
||||
good_snapshot Json?
|
||||
good_snapshot Json
|
||||
|
||||
invoice_id String
|
||||
invoice SalesInvoice @relation(fields: [invoice_id], references: [id])
|
||||
|
||||
good_id String?
|
||||
good Good? @relation(fields: [good_id], references: [id])
|
||||
good_id String
|
||||
good Good @relation(fields: [good_id], references: [id])
|
||||
|
||||
service_id String?
|
||||
service Service? @relation(fields: [service_id], references: [id])
|
||||
@@ -58,30 +57,13 @@ model SalesInvoiceItem {
|
||||
@@map("sales_invoice_items")
|
||||
}
|
||||
|
||||
model SaleInvoiceFiscals {
|
||||
id String @id @default(ulid())
|
||||
|
||||
retry_count Int @default(0)
|
||||
last_attempt_at DateTime? @db.Timestamp(0)
|
||||
|
||||
created_at DateTime @default(now()) @db.Timestamp(0)
|
||||
updated_at DateTime @updatedAt() @db.Timestamp(0)
|
||||
|
||||
invoice_id String @unique
|
||||
invoice SalesInvoice @relation(fields: [invoice_id], references: [id], onDelete: Cascade)
|
||||
|
||||
attempts SaleInvoiceFiscalAttempts[]
|
||||
|
||||
@@map("sale_invoice_fiscals")
|
||||
}
|
||||
|
||||
model SaleInvoiceFiscalAttempts {
|
||||
model SaleInvoiceTspAttempts {
|
||||
id String @id @default(ulid())
|
||||
|
||||
attempt_no Int
|
||||
status FiscalResponseStatus
|
||||
tax_id String? @unique @db.VarChar(191)
|
||||
type FiscalRequestType
|
||||
status TspProviderResponseStatus
|
||||
tax_id String? @unique @db.VarChar(191)
|
||||
type TspProviderRequestType
|
||||
|
||||
request_payload Json?
|
||||
response_payload Json?
|
||||
@@ -91,13 +73,14 @@ model SaleInvoiceFiscalAttempts {
|
||||
received_at DateTime? @db.Timestamp(0)
|
||||
created_at DateTime @default(now()) @db.Timestamp(0)
|
||||
|
||||
fiscal_id String
|
||||
fiscal SaleInvoiceFiscals @relation(fields: [fiscal_id], references: [id], onDelete: Cascade)
|
||||
invoice_id String @unique
|
||||
invoice SalesInvoice @relation(fields: [invoice_id], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([fiscal_id, attempt_no])
|
||||
@@unique([invoice_id, attempt_no])
|
||||
@@index([status])
|
||||
@@index([tax_id])
|
||||
@@map("sale_invoice_fiscal_attempts")
|
||||
@@index([invoice_id])
|
||||
@@map("sale_invoice_tsp_attempts")
|
||||
}
|
||||
|
||||
model SalesInvoicePayment {
|
||||
|
||||
+4
-6
@@ -1,10 +1,6 @@
|
||||
import { PasswordUtil } from '@/common/utils/password.util'
|
||||
import { generateTrackingCode } from '@/common/utils/tracking-code-generator.util'
|
||||
import {
|
||||
ConsumerType,
|
||||
GoodPricingModel,
|
||||
PartnerFiscalSwitchType,
|
||||
} from '@/generated/prisma/enums'
|
||||
import { ConsumerType, GoodPricingModel, TspProviderType } from '@/generated/prisma/enums'
|
||||
import { GoodCreateManyInput } from '@/generated/prisma/models'
|
||||
import { prisma } from '../src/lib/prisma'
|
||||
|
||||
@@ -135,10 +131,12 @@ async function main() {
|
||||
{
|
||||
name: 'طلا',
|
||||
code: 'Gold',
|
||||
invoice_template: 'GOLD_JEWELRY',
|
||||
},
|
||||
{
|
||||
name: 'میوه و ترهبار',
|
||||
code: 'Fruit',
|
||||
invoice_template: 'SALE',
|
||||
},
|
||||
],
|
||||
})
|
||||
@@ -405,7 +403,7 @@ async function main() {
|
||||
name: 'تیس',
|
||||
code: 'TIS',
|
||||
status: 'ACTIVE',
|
||||
fiscal_switch_type: PartnerFiscalSwitchType.NAMA,
|
||||
tsp_provider: TspProviderType.NAMA,
|
||||
accounts: {
|
||||
create: {
|
||||
role: 'OWNER',
|
||||
|
||||
Reference in New Issue
Block a user