feat: add DTOs and services for tax switch integration

- Created SendBulkSaleInvoicesDto for handling bulk sale invoice requests.
- Implemented TaxSwitchSendPayloadDto and related DTOs for tax switch item payloads and results.
- Developed SalesInvoiceTaxSwitchService to manage tax switch operations, including sending and retrieving tax information.
- Added SalesInvoiceTaxService for handling sales invoice tax logic, including bulk sending and persistence of results.
- Introduced NamaTaxSwitchAdapter to interact with the tax switch service, simulating external API responses.
- Created SendBulkSalesInvoicesDto for POS module to handle bulk sales invoice requests.
This commit is contained in:
2026-04-27 22:11:05 +03:30
parent dee96b6e91
commit 58a7c359d8
68 changed files with 7896 additions and 3534 deletions
+2 -17
View File
@@ -3,6 +3,7 @@ import { ITokenPayload } from '@/modules/auth/auth.utils'
import { PrismaService } from '@/prisma/prisma.service'
import { ExecutionContext, ForbiddenException, Injectable } from '@nestjs/common'
import { Request as ExpressRequest } from 'express'
import { QUERY_CONSTANTS } from '../queryConstants'
@Injectable()
export class PosGuard {
@@ -18,7 +19,6 @@ export class PosGuard {
throw new ForbiddenException('شما دسترسی لازم را ندارید.')
}
const now = new Date()
const cookie = req.cookies
const { posId } = cookie
@@ -40,22 +40,7 @@ export class PosGuard {
},
],
license_activation: {
OR: [
{
expires_at: {
gte: now,
},
},
{
license_renews: {
some: {
expires_at: {
gte: now,
},
},
},
},
],
...QUERY_CONSTANTS.LICENSE_ACTIVATION.activeOnDate(),
},
},
})
@@ -85,7 +85,6 @@ export class ResponseMappingInterceptor implements NestInterceptor {
break
case 'paginate': {
const { items: a, ...rest } = wrapped
console.log(rest)
const items = Array.isArray(wrapped.items) ? wrapped.items : []
const total =
+51 -1
View File
@@ -1,4 +1,6 @@
import { ConsumerSelect } from '@/generated/prisma/models'
import { ConsumerSelect, ConsumerWhereInput } from '@/generated/prisma/models'
const now = new Date()
export const infoSelect: ConsumerSelect = {
legal: {
@@ -29,3 +31,51 @@ export const infoSelect: ConsumerSelect = {
},
},
}
export const activeBusinessCount: ConsumerSelect = {
_count: {
select: {
business_activities: {
where: {
license_activation: {
OR: [
{
expires_at: {
gt: now,
},
},
{
license_renews: {
some: {
expires_at: {
gt: now,
},
},
},
},
],
},
},
},
},
},
}
export const consumerRelatedPartner = (partner_id: string): ConsumerWhereInput => ({
OR: [
{
legal: {
is: {
partner_id,
},
},
},
{
individual: {
is: {
partner_id,
},
},
},
],
})
+2
View File
@@ -1,7 +1,9 @@
import * as CONSUMER from './consumer'
import * as LICENSE_ACTIVATION from './licenseActivation'
import * as POS from './pos'
export const QUERY_CONSTANTS = {
POS,
CONSUMER,
LICENSE_ACTIVATION,
}
@@ -0,0 +1,18 @@
export const activeOnDate = (expires_at: Date = new Date()) => ({
OR: [
{
expires_at: {
gte: expires_at,
},
},
{
license_renews: {
some: {
expires_at: {
gte: expires_at,
},
},
},
},
],
})
@@ -1,6 +1,7 @@
export default (consumer: any) => {
const { legal, individual, activation, ...rest } = consumer
const { legal, individual, activation, _count, ...rest } = consumer
const { business_activities: business_counts } = _count || { business_activities: 0 }
const partner = legal?.partner || individual?.partner
delete legal?.partner
delete individual?.partner
@@ -13,6 +14,7 @@ export default (consumer: any) => {
? { ...individual, fullname: `${rest?.first_name} ${rest?.last_name}` }
: null,
name: legal ? legal.name : `${individual?.first_name} ${individual?.last_name}`,
business_counts,
// license_info: prepareLicenseInfo(activation),
}
}