update revoke
This commit is contained in:
@@ -3,6 +3,7 @@ import { ConsumerSelect, ConsumerWhereInput } from '@/generated/prisma/models'
|
|||||||
const now = new Date()
|
const now = new Date()
|
||||||
|
|
||||||
export const infoSelect: ConsumerSelect = {
|
export const infoSelect: ConsumerSelect = {
|
||||||
|
type: true,
|
||||||
legal: {
|
legal: {
|
||||||
select: {
|
select: {
|
||||||
name: true,
|
name: true,
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export default (consumer: any) => {
|
|||||||
return {
|
return {
|
||||||
...rest,
|
...rest,
|
||||||
partner,
|
partner,
|
||||||
type: translateEnumValue('ConsumerType', consumer.type),
|
type: translateEnumValue('ConsumerType', type),
|
||||||
status: translateEnumValue('ConsumerStatus', consumer.status),
|
status: translateEnumValue('ConsumerStatus', consumer.status),
|
||||||
legal: legal ? { ...legal } : null,
|
legal: legal ? { ...legal } : null,
|
||||||
individual: individual
|
individual: individual
|
||||||
|
|||||||
+1
-8
@@ -57,14 +57,7 @@ async function bootstrap() {
|
|||||||
|
|
||||||
// Enable CORS. You can set `CORS_ORIGINS` to a comma-separated list of allowed origins.
|
// 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.
|
// Defaults include common localhost origins used by front-end dev servers.
|
||||||
const defaultOrigins = [
|
const defaultOrigins = []
|
||||||
'http://localhost:5000',
|
|
||||||
'http://127.0.0.1:5000',
|
|
||||||
'http://192.168.128.73:5000',
|
|
||||||
'http://localhost:5005',
|
|
||||||
'http://127.0.0.1:5005',
|
|
||||||
'http://192.168.128.73:5005',
|
|
||||||
]
|
|
||||||
const envOrigins = process.env.CORS_ORIGINS
|
const envOrigins = process.env.CORS_ORIGINS
|
||||||
? process.env.CORS_ORIGINS.split(',')
|
? process.env.CORS_ORIGINS.split(',')
|
||||||
.map(s => s.trim())
|
.map(s => s.trim())
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { translateEnumValue } from '@/common/utils'
|
||||||
import { ConsumerAccountSelect } from '@/generated/prisma/models'
|
import { ConsumerAccountSelect } from '@/generated/prisma/models'
|
||||||
import { PrismaService } from '@/prisma/prisma.service'
|
import { PrismaService } from '@/prisma/prisma.service'
|
||||||
import { Injectable } from '@nestjs/common'
|
import { Injectable } from '@nestjs/common'
|
||||||
@@ -62,7 +63,21 @@ export class AccountsService {
|
|||||||
where: this.defaultWhere(partner_id, consumer_id),
|
where: this.defaultWhere(partner_id, consumer_id),
|
||||||
select: this.default_select,
|
select: this.default_select,
|
||||||
})
|
})
|
||||||
return ResponseMapper.list(accounts)
|
|
||||||
|
const mappedAccounts = accounts.map(account => {
|
||||||
|
const { account: mainAccount, role, ...rest } = account
|
||||||
|
|
||||||
|
return {
|
||||||
|
...rest,
|
||||||
|
account: {
|
||||||
|
...mainAccount,
|
||||||
|
status: translateEnumValue('AccountStatus', mainAccount.status),
|
||||||
|
},
|
||||||
|
role: translateEnumValue('ConsumerRole', role),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return ResponseMapper.list(mappedAccounts)
|
||||||
}
|
}
|
||||||
|
|
||||||
async findOne(partner_id: string, consumer_id: string, id: string) {
|
async findOne(partner_id: string, consumer_id: string, id: string) {
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ export class PartnerConsumersService {
|
|||||||
id: true,
|
id: true,
|
||||||
status: true,
|
status: true,
|
||||||
created_at: true,
|
created_at: true,
|
||||||
|
type: true,
|
||||||
...QUERY_CONSTANTS.CONSUMER.infoSelect,
|
...QUERY_CONSTANTS.CONSUMER.infoSelect,
|
||||||
...QUERY_CONSTANTS.CONSUMER.activeBusinessCount,
|
...QUERY_CONSTANTS.CONSUMER.activeBusinessCount,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -258,48 +258,14 @@ export class SalesInvoicesService {
|
|||||||
|
|
||||||
return ResponseMapper.single({
|
return ResponseMapper.single({
|
||||||
...rest,
|
...rest,
|
||||||
status: tsp_attempts?.[0]?.status || TspProviderResponseStatus.NOT_SEND,
|
status: translateEnumValue(
|
||||||
|
'TspProviderResponseStatus',
|
||||||
|
invoice.tsp_attempts?.[0]?.status || TspProviderResponseStatus.NOT_SEND,
|
||||||
|
),
|
||||||
})
|
})
|
||||||
} else throw new NotFoundException('فاکتور مورد نظر شما یافت نشد.')
|
} else throw new NotFoundException('فاکتور مورد نظر شما یافت نشد.')
|
||||||
}
|
}
|
||||||
|
|
||||||
async send(invoiceId: string, posInfo: IPosPayload) {
|
|
||||||
const consumer_id = await this.checkAccessToInvoice(
|
|
||||||
posInfo.consumer_account_id,
|
|
||||||
posInfo.pos_id,
|
|
||||||
)
|
|
||||||
const invoice = await this.salesInvoiceTaxService.send(consumer_id, invoiceId)
|
|
||||||
|
|
||||||
return ResponseMapper.single(invoice)
|
|
||||||
}
|
|
||||||
|
|
||||||
async revoke(invoiceId: string, posInfo: IPosPayload) {
|
|
||||||
await this.checkAccessToInvoice(posInfo.consumer_account_id, posInfo.pos_id)
|
|
||||||
|
|
||||||
const invoice = await this.salesInvoiceTaxService.revoke(posInfo.pos_id, invoiceId)
|
|
||||||
|
|
||||||
return ResponseMapper.single(invoice)
|
|
||||||
}
|
|
||||||
|
|
||||||
async inquiry(consumer_account_id: string, pos_id: string, invoiceId: string) {
|
|
||||||
const consumer_id = await this.checkAccessToInvoice(consumer_account_id, pos_id)
|
|
||||||
const invoice = await this.salesInvoiceTaxService.get(invoiceId, pos_id, consumer_id)
|
|
||||||
return ResponseMapper.single(invoice)
|
|
||||||
}
|
|
||||||
|
|
||||||
// async sendBulk(invoiceIds: string[], posInfo: IPosPayload) {
|
|
||||||
// if (!invoiceIds.length) {
|
|
||||||
// throw new BadRequestException('invoice_ids is required and cannot be empty.')
|
|
||||||
// }
|
|
||||||
|
|
||||||
// await this.salesInvoiceTaxService.sendBulk(invoiceIds, posInfo.pos_id)
|
|
||||||
|
|
||||||
// return ResponseMapper.single({
|
|
||||||
// invoice_ids: invoiceIds,
|
|
||||||
// sent_to_tax: true,
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
|
|
||||||
async create(data: CreateSalesInvoiceDto, posInfo: IPosPayload) {
|
async create(data: CreateSalesInvoiceDto, posInfo: IPosPayload) {
|
||||||
const { business_id, pos_id, consumer_account_id, complex_id } = posInfo
|
const { business_id, pos_id, consumer_account_id, complex_id } = posInfo
|
||||||
const normalizedInvoiceDate = this.normalizeInvoiceDate(data.invoice_date)
|
const normalizedInvoiceDate = this.normalizeInvoiceDate(data.invoice_date)
|
||||||
@@ -360,6 +326,43 @@ export class SalesInvoicesService {
|
|||||||
throw new BadRequestException('ایجاد فاکتور با خطا مواجه شد.')
|
throw new BadRequestException('ایجاد فاکتور با خطا مواجه شد.')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async send(invoiceId: string, posInfo: IPosPayload) {
|
||||||
|
const consumer_id = await this.checkAccessToInvoice(
|
||||||
|
posInfo.consumer_account_id,
|
||||||
|
posInfo.pos_id,
|
||||||
|
)
|
||||||
|
const invoice = await this.salesInvoiceTaxService.send(consumer_id, invoiceId)
|
||||||
|
|
||||||
|
return ResponseMapper.single(invoice)
|
||||||
|
}
|
||||||
|
|
||||||
|
async revoke(invoiceId: string, posInfo: IPosPayload) {
|
||||||
|
await this.checkAccessToInvoice(posInfo.consumer_account_id, posInfo.pos_id)
|
||||||
|
|
||||||
|
const invoice = await this.salesInvoiceTaxService.revoke(posInfo.pos_id, invoiceId)
|
||||||
|
|
||||||
|
return ResponseMapper.single(invoice)
|
||||||
|
}
|
||||||
|
|
||||||
|
async inquiry(consumer_account_id: string, pos_id: string, invoiceId: string) {
|
||||||
|
const consumer_id = await this.checkAccessToInvoice(consumer_account_id, pos_id)
|
||||||
|
const invoice = await this.salesInvoiceTaxService.get(invoiceId, pos_id, consumer_id)
|
||||||
|
return ResponseMapper.single(invoice)
|
||||||
|
}
|
||||||
|
|
||||||
|
// async sendBulk(invoiceIds: string[], posInfo: IPosPayload) {
|
||||||
|
// if (!invoiceIds.length) {
|
||||||
|
// throw new BadRequestException('invoice_ids is required and cannot be empty.')
|
||||||
|
// }
|
||||||
|
|
||||||
|
// await this.salesInvoiceTaxService.sendBulk(invoiceIds, posInfo.pos_id)
|
||||||
|
|
||||||
|
// return ResponseMapper.single({
|
||||||
|
// invoice_ids: invoiceIds,
|
||||||
|
// sent_to_tax: true,
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
|
||||||
private isRetryableInvoiceConflict(error: unknown) {
|
private isRetryableInvoiceConflict(error: unknown) {
|
||||||
if (!(error instanceof Prisma.PrismaClientKnownRequestError)) {
|
if (!(error instanceof Prisma.PrismaClientKnownRequestError)) {
|
||||||
return false
|
return false
|
||||||
|
|||||||
@@ -470,6 +470,7 @@ export class SalesInvoiceTspService {
|
|||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
status: true,
|
status: true,
|
||||||
|
tax_id: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
pos: {
|
pos: {
|
||||||
@@ -531,7 +532,7 @@ export class SalesInvoiceTspService {
|
|||||||
fiscal_id: invoice.pos.complex.business_activity.fiscal_id,
|
fiscal_id: invoice.pos.complex.business_activity.fiscal_id,
|
||||||
tsp_token: invoice.pos.complex.business_activity.partner_token,
|
tsp_token: invoice.pos.complex.business_activity.partner_token,
|
||||||
tsp_provider: partner.tsp_provider!,
|
tsp_provider: partner.tsp_provider!,
|
||||||
last_attempt_tax_id: invoice.tsp_attempts[0].id,
|
last_attempt_tax_id: invoice.tsp_attempts[0].tax_id!,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -180,6 +180,8 @@ export class NamaProviderSwitchAdapter implements IProviderSwitchAdapter {
|
|||||||
const mappedRequest: NamaProviderRevokeRequestDto =
|
const mappedRequest: NamaProviderRevokeRequestDto =
|
||||||
this.namaProviderUtils.mapRevokeToNamaRequestDto(payload)
|
this.namaProviderUtils.mapRevokeToNamaRequestDto(payload)
|
||||||
|
|
||||||
|
this.logger.debug('NAMA provider response', mappedRequest)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await this.httpClient.request(
|
const response = await this.httpClient.request(
|
||||||
this.buildSendUrl(),
|
this.buildSendUrl(),
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import {
|
|||||||
IsArray,
|
IsArray,
|
||||||
IsEnum,
|
IsEnum,
|
||||||
IsNumber,
|
IsNumber,
|
||||||
IsObject,
|
|
||||||
IsOptional,
|
IsOptional,
|
||||||
IsString,
|
IsString,
|
||||||
Min,
|
Min,
|
||||||
@@ -145,7 +144,11 @@ export class NamaProviderHeaderDto {
|
|||||||
@IsString()
|
@IsString()
|
||||||
name: string
|
name: string
|
||||||
|
|
||||||
@ApiProperty({ required: true, description: 'نوع شخصیت خریدار' })
|
@ApiProperty({
|
||||||
|
required: false,
|
||||||
|
description:
|
||||||
|
'نوع شخصیت خریدار (در صورتیکه خریدار نوع ۲ باشه باید ۱ یا ۲ گذاشته بشه)',
|
||||||
|
})
|
||||||
@IsString()
|
@IsString()
|
||||||
tob: string
|
tob: string
|
||||||
|
|
||||||
@@ -296,6 +299,13 @@ export class NamaProviderRevokeHeaderDto {
|
|||||||
@IsString()
|
@IsString()
|
||||||
inno: string
|
inno: string
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
required: true,
|
||||||
|
description: 'تاریخ و زمان صدور صورتحساب به صورت timestamp',
|
||||||
|
})
|
||||||
|
@IsString()
|
||||||
|
indatim: string
|
||||||
|
|
||||||
@ApiProperty({
|
@ApiProperty({
|
||||||
required: true,
|
required: true,
|
||||||
description: 'آخرین شماره مالیاتی دریافت شده مربوط به فاکتور',
|
description: 'آخرین شماره مالیاتی دریافت شده مربوط به فاکتور',
|
||||||
@@ -315,9 +325,9 @@ export class NamaProviderRevokeRequestDto {
|
|||||||
// @ValidateNested({ each: true })
|
// @ValidateNested({ each: true })
|
||||||
// @Type(() => NamaProviderPaymentInfoDto)
|
// @Type(() => NamaProviderPaymentInfoDto)
|
||||||
// payment: NamaProviderPaymentInfoDto[]
|
// payment: NamaProviderPaymentInfoDto[]
|
||||||
@ApiProperty({ type: Object, required: true })
|
// @ApiProperty({ type: Object, required: true })
|
||||||
@IsObject()
|
// @IsObject()
|
||||||
body: {}
|
// body: {}
|
||||||
|
|
||||||
@ApiProperty({ type: NamaProviderRevokeHeaderDto })
|
@ApiProperty({ type: NamaProviderRevokeHeaderDto })
|
||||||
@ValidateNested()
|
@ValidateNested()
|
||||||
|
|||||||
@@ -77,8 +77,8 @@ export class NamaProviderUtils {
|
|||||||
inno: payload.invoice_number.toString(),
|
inno: payload.invoice_number.toString(),
|
||||||
ins: this.mapTspProviderRequestType(TspProviderRequestType.REVOKE),
|
ins: this.mapTspProviderRequestType(TspProviderRequestType.REVOKE),
|
||||||
irtaxid: payload.last_attempt_tax_id,
|
irtaxid: payload.last_attempt_tax_id,
|
||||||
|
indatim: new Date().getTime() + '',
|
||||||
},
|
},
|
||||||
body: {},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,17 +140,17 @@ export class NamaProviderUtils {
|
|||||||
case CustomerType.LEGAL:
|
case CustomerType.LEGAL:
|
||||||
return '2'
|
return '2'
|
||||||
default:
|
default:
|
||||||
return '5'
|
return ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private mapCustomerInfo(customer?: CustomerInfoDto) {
|
private mapCustomerInfo(customer?: CustomerInfoDto) {
|
||||||
const info = {} as any
|
const info = {} as any
|
||||||
info.tob = this.mapCustomerType(customer?.type)
|
|
||||||
if (customer?.type === CustomerType.LEGAL && customer.legal_info) {
|
if (customer?.type === CustomerType.LEGAL && customer.legal_info) {
|
||||||
info.name = customer.legal_info.name
|
info.name = customer.legal_info.name
|
||||||
info.bid = customer.legal_info.economic_code
|
info.bid = customer.legal_info.economic_code
|
||||||
info.address = ''
|
info.address = ''
|
||||||
|
info.tob = '2'
|
||||||
} else if (customer?.type === CustomerType.INDIVIDUAL && customer.individual_info) {
|
} else if (customer?.type === CustomerType.INDIVIDUAL && customer.individual_info) {
|
||||||
info.name = `${customer.individual_info?.first_name || ''} ${
|
info.name = `${customer.individual_info?.first_name || ''} ${
|
||||||
customer.individual_info?.last_name || ''
|
customer.individual_info?.last_name || ''
|
||||||
@@ -158,6 +158,7 @@ export class NamaProviderUtils {
|
|||||||
info.bid = customer.individual_info.national_id
|
info.bid = customer.individual_info.national_id
|
||||||
info.mobile = customer.individual_info.mobile_number
|
info.mobile = customer.individual_info.mobile_number
|
||||||
info.address = ''
|
info.address = ''
|
||||||
|
info.tob = '1'
|
||||||
}
|
}
|
||||||
return info
|
return info
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user