feat: enhance CustomerIndividual and CustomerLegal models with new unique input types

feat: add cache invalidation method for POS middleware

feat: implement Redis caching in POS middleware for improved performance

feat: refactor sales invoice DTOs for POS to include correction functionality

feat: extend SalesInvoicesController to handle invoice corrections and returns

feat: update SalesInvoicesService to support invoice correction and return operations

feat: enhance TSP provider correction functionality with new DTOs and utility methods

fix: improve error handling and logging in Nama provider switch adapter

refactor: streamline invoice payload building in TSP provider utilities
This commit is contained in:
2026-06-06 19:53:00 +03:30
parent 25e589551b
commit f61100bf25
21 changed files with 302 additions and 113 deletions
@@ -1,9 +1,7 @@
import { CustomerType } from '@/generated/prisma/enums'
import { SaleInvoiceTspAttemptsUpdateInput } from '@/generated/prisma/models'
import { PrismaService } from '@/prisma/prisma.service'
import { BadRequestException, NotFoundException } from '@nestjs/common'
import {
CustomerType,
} from '@/generated/prisma/enums'
import {
Prisma,
TspProviderRequestType,
@@ -172,7 +170,6 @@ export async function buildCorrectionPayload(
invoice_date: true,
invoice_number: true,
settlement_type: true,
tax_id: true,
discount_amount: true,
tax_amount: true,
items: true,
@@ -226,16 +223,17 @@ export async function buildCorrectionPayload(
legal: true,
},
},
reference_invoice: {
select: {
tax_id: true,
},
},
payments: {
include: {
terminal_info: true,
},
},
reference_invoice: {
select: {
tax_id: true,
id: true,
},
},
},
})
@@ -284,7 +282,9 @@ export async function buildCorrectionPayload(
token: invoice.pos.complex.business_activity.partner_token,
tsp_provider: partner.tsp_provider!,
template: invoice.pos.complex.business_activity.guild.invoice_template,
invoice_date: new Date(),
invoice_date: invoice?.invoice_date
? new Date(invoice.invoice_date)
: invoice.invoice_date,
settlement_type: invoice.settlement_type,
customer:
@@ -305,11 +305,9 @@ export async function buildCorrectionPayload(
first_name: invoice.customer.individual.first_name ?? undefined,
last_name: invoice.customer.individual.last_name ?? undefined,
national_id: invoice.customer.individual.national_id ?? undefined,
mobile_number:
invoice.customer.individual.mobile_number ?? undefined,
mobile_number: invoice.customer.individual.mobile_number ?? undefined,
postal_code: invoice.customer.individual.postal_code ?? undefined,
economic_code:
invoice.customer.individual.economic_code ?? undefined,
economic_code: invoice.customer.individual.economic_code ?? undefined,
}
: undefined,
}
@@ -487,11 +485,9 @@ export async function buildOriginalPayload(
first_name: invoice.customer.individual.first_name ?? undefined,
last_name: invoice.customer.individual.last_name ?? undefined,
national_id: invoice.customer.individual.national_id ?? undefined,
mobile_number:
invoice.customer.individual.mobile_number ?? undefined,
mobile_number: invoice.customer.individual.mobile_number ?? undefined,
postal_code: invoice.customer.individual.postal_code ?? undefined,
economic_code:
invoice.customer.individual.economic_code ?? undefined,
economic_code: invoice.customer.individual.economic_code ?? undefined,
}
: undefined,
}
@@ -521,6 +517,62 @@ export async function buildOriginalPayload(
}
}
export async function getRelatedInvoiceForCorrection(
tx: Prisma.TransactionClient,
ref_invoice_id: string,
) {
const relatedInvoice = await getRelatedInvoiceForModification(tx, ref_invoice_id)
return relatedInvoice
}
export async function getRelatedInvoiceForModification(
tx: Prisma.TransactionClient,
ref_invoice_id: string,
) {
const relatedInvoice = await tx.salesInvoice.findUnique({
where: {
id: ref_invoice_id,
},
include: {
customer: {
select: {
type: true,
},
},
payments: {
select: {},
},
tsp_attempts: {
orderBy: {
attempt_no: 'desc',
},
take: 1,
},
},
})
if (!relatedInvoice) {
throw new NotFoundException('فاکتور مورد نظر یافت نشد.')
}
if (relatedInvoice.type === TspProviderRequestType.REVOKE) {
throw new BadRequestException(
'فاکتور ارسالی قبلا ابطال شده است و امکان ویرایش آن وجود ندارد.',
)
}
if (
!relatedInvoice.tax_id ||
relatedInvoice.tsp_attempts?.[0].status !== TspProviderResponseStatus.SUCCESS
) {
throw new BadRequestException(
'فاکتور قبلی همچنان در حال بررسی است و امکان اصلاح آن وجود ندارد.',
)
}
return relatedInvoice
}
export async function trySend(
tspSwitchService: {
send(