feat: enhance sales invoice processing with correction and return functionalities
This commit is contained in:
@@ -83,7 +83,7 @@ export class SharedCreateTerminalPayment {
|
|||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@ApiProperty({ required: true })
|
@ApiProperty({ required: true })
|
||||||
terminalId: string
|
terminal_id: string
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ interface TerminalPaymentInfo {
|
|||||||
interface NormalizedPayment {
|
interface NormalizedPayment {
|
||||||
method: PaymentMethodType
|
method: PaymentMethodType
|
||||||
amount: number
|
amount: number
|
||||||
|
terminalInfo?: TerminalPaymentInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CreateSharedSaleInvoiceInput {
|
interface CreateSharedSaleInvoiceInput {
|
||||||
@@ -57,10 +58,7 @@ export class SharedSaleInvoiceCreateService {
|
|||||||
} = input
|
} = input
|
||||||
|
|
||||||
const normalizedInvoiceDate = this.normalizeInvoiceDate(data.invoice_date)
|
const normalizedInvoiceDate = this.normalizeInvoiceDate(data.invoice_date)
|
||||||
const { payments, terminalInfo } = this.buildPaymentsData(
|
const payments = this.buildPaymentsData(data.payments, data.total_amount)
|
||||||
data.payments,
|
|
||||||
data.total_amount,
|
|
||||||
)
|
|
||||||
|
|
||||||
for (let attempt = 1; attempt <= this.createInvoiceRetries; attempt++) {
|
for (let attempt = 1; attempt <= this.createInvoiceRetries; attempt++) {
|
||||||
try {
|
try {
|
||||||
@@ -88,13 +86,7 @@ export class SharedSaleInvoiceCreateService {
|
|||||||
select: { ...QUERY_CONSTANTS.SALE_INVOICE.select },
|
select: { ...QUERY_CONSTANTS.SALE_INVOICE.select },
|
||||||
})
|
})
|
||||||
|
|
||||||
await this.createPayments(
|
await this.createPayments($tx, salesInvoice.id, payments, normalizedInvoiceDate)
|
||||||
$tx,
|
|
||||||
salesInvoice.id,
|
|
||||||
payments,
|
|
||||||
terminalInfo,
|
|
||||||
normalizedInvoiceDate,
|
|
||||||
)
|
|
||||||
|
|
||||||
return salesInvoice
|
return salesInvoice
|
||||||
})
|
})
|
||||||
@@ -148,7 +140,7 @@ export class SharedSaleInvoiceCreateService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const rawPayments = (paymentsData || {}) as Record<string, unknown>
|
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)
|
const payments: NormalizedPayment[] = Object.entries(rawPayments)
|
||||||
.filter(([key, value]) => key !== 'terminals' && value && Number(value) > 0)
|
.filter(([key, value]) => key !== 'terminals' && value && Number(value) > 0)
|
||||||
@@ -158,40 +150,24 @@ export class SharedSaleInvoiceCreateService {
|
|||||||
}))
|
}))
|
||||||
.filter(payment => payment.method && payment.amount > 0) as NormalizedPayment[]
|
.filter(payment => payment.method && payment.amount > 0) as NormalizedPayment[]
|
||||||
|
|
||||||
const hasTerminalPayment = payments.some(
|
const hasTerminalPayment = terminalPayments && terminalPayments.length
|
||||||
payment => payment.method === PaymentMethodType.TERMINAL,
|
|
||||||
)
|
|
||||||
const nonTerminalTotal = payments
|
|
||||||
.filter(payment => payment.method !== PaymentMethodType.TERMINAL)
|
|
||||||
.reduce((sum, payment) => sum + payment.amount, 0)
|
|
||||||
|
|
||||||
if (!hasTerminalPayment && terminalInfo) {
|
if (hasTerminalPayment) {
|
||||||
const terminalAmount =
|
for (const terminal of terminalPayments) {
|
||||||
typeof terminalInfo.amount === 'number'
|
|
||||||
? terminalInfo.amount
|
|
||||||
: Math.max(0, Number(totalAmount) - nonTerminalTotal)
|
|
||||||
|
|
||||||
if (terminalAmount > 0) {
|
|
||||||
payments.push({
|
payments.push({
|
||||||
method: PaymentMethodType.TERMINAL,
|
method: PaymentMethodType.TERMINAL,
|
||||||
amount: terminalAmount,
|
amount: terminal.amount,
|
||||||
|
terminalInfo: terminal,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.validatePayments(payments, totalAmount, terminalInfo)
|
this.validatePayments(payments, totalAmount)
|
||||||
|
|
||||||
return {
|
return payments
|
||||||
payments,
|
|
||||||
terminalInfo,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private validatePayments(
|
private validatePayments(payments: NormalizedPayment[], totalAmount: number) {
|
||||||
payments: NormalizedPayment[],
|
|
||||||
totalAmount: number,
|
|
||||||
terminalInfo?: TerminalPaymentInfo,
|
|
||||||
) {
|
|
||||||
const totalPayments = payments.reduce((sum, payment) => sum + payment.amount, 0)
|
const totalPayments = payments.reduce((sum, payment) => sum + payment.amount, 0)
|
||||||
const roundedTotalPayments = Number(totalPayments.toFixed(2))
|
const roundedTotalPayments = Number(totalPayments.toFixed(2))
|
||||||
const roundedTotalAmount = Number(Number(totalAmount).toFixed(2))
|
const roundedTotalAmount = Number(Number(totalAmount).toFixed(2))
|
||||||
@@ -199,14 +175,6 @@ export class SharedSaleInvoiceCreateService {
|
|||||||
if (roundedTotalPayments !== roundedTotalAmount) {
|
if (roundedTotalPayments !== roundedTotalAmount) {
|
||||||
throw new BadRequestException('مبلغ پرداختی باید برابر با مبلغ کل صورتحساب باشد.')
|
throw new BadRequestException('مبلغ پرداختی باید برابر با مبلغ کل صورتحساب باشد.')
|
||||||
}
|
}
|
||||||
|
|
||||||
const terminalPayments = payments.filter(
|
|
||||||
payment => payment.method === PaymentMethodType.TERMINAL,
|
|
||||||
)
|
|
||||||
|
|
||||||
if (terminalPayments.length > 0 && !terminalInfo) {
|
|
||||||
throw new BadRequestException('برای پرداخت ترمینال اطلاعات ترمینال الزامی است.')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async resolveCustomerId(
|
private async resolveCustomerId(
|
||||||
@@ -541,7 +509,6 @@ export class SharedSaleInvoiceCreateService {
|
|||||||
tx: Prisma.TransactionClient,
|
tx: Prisma.TransactionClient,
|
||||||
invoiceId: string,
|
invoiceId: string,
|
||||||
payments: NormalizedPayment[],
|
payments: NormalizedPayment[],
|
||||||
terminalInfo: TerminalPaymentInfo | undefined,
|
|
||||||
paidAt: Date,
|
paidAt: Date,
|
||||||
) {
|
) {
|
||||||
for (const payment of payments) {
|
for (const payment of payments) {
|
||||||
@@ -557,16 +524,18 @@ export class SharedSaleInvoiceCreateService {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
if (payment.method === PaymentMethodType.TERMINAL && terminalInfo) {
|
if (payment.method === PaymentMethodType.TERMINAL && payment.terminalInfo) {
|
||||||
await tx.salesInvoicePaymentTerminalInfo.create({
|
await tx.salesInvoicePaymentTerminalInfo.create({
|
||||||
data: {
|
data: {
|
||||||
payment_id: createdPayment.id,
|
payment_id: createdPayment.id,
|
||||||
terminal_id: terminalInfo.terminal_id,
|
terminal_id: payment.terminalInfo.terminal_id,
|
||||||
stan: terminalInfo.stan,
|
stan: payment.terminalInfo.stan,
|
||||||
rrn: terminalInfo.rrn,
|
rrn: payment.terminalInfo.rrn,
|
||||||
transaction_date_time: new Date(terminalInfo.transaction_date_time || ''),
|
transaction_date_time: new Date(
|
||||||
customer_card_no: terminalInfo.customer_card_no || null,
|
payment.terminalInfo.transaction_date_time || '',
|
||||||
description: terminalInfo.description || null,
|
),
|
||||||
|
customer_card_no: payment.terminalInfo.customer_card_no || null,
|
||||||
|
description: payment.terminalInfo.description || null,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import type { IPosPayload } from '@/common/models'
|
|||||||
import { Body, Controller, Get, Param, Post, Query } from '@nestjs/common'
|
import { Body, Controller, Get, Param, Post, Query } from '@nestjs/common'
|
||||||
import { ApiTags } from '@nestjs/swagger'
|
import { ApiTags } from '@nestjs/swagger'
|
||||||
import { ConsumerSaleInvoicesFilterDto } from './dto/saleInvoices-filter.dto'
|
import { ConsumerSaleInvoicesFilterDto } from './dto/saleInvoices-filter.dto'
|
||||||
|
import { PosCorrectionSalesInvoiceDto } from '../../pos/sales-invoices/dto/create-sales-invoice.dto'
|
||||||
import type {
|
import type {
|
||||||
SaleInvoicesServiceFindAllResponseDto,
|
SaleInvoicesServiceFindAllResponseDto,
|
||||||
SaleInvoicesServiceFindOneResponseDto,
|
SaleInvoicesServiceFindOneResponseDto,
|
||||||
@@ -59,4 +60,18 @@ export class StatisticsController {
|
|||||||
revoke(@Param('id') id: string, @PosInfo() posInfo: IPosPayload) {
|
revoke(@Param('id') id: string, @PosInfo() posInfo: IPosPayload) {
|
||||||
return this.service.revoke(id, posInfo)
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import {
|
|||||||
import { PrismaService } from '@/prisma/prisma.service'
|
import { PrismaService } from '@/prisma/prisma.service'
|
||||||
import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common'
|
import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common'
|
||||||
import { ResponseMapper } from 'common/response/response-mapper'
|
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 { SalesInvoiceTspService } from '../../tspProviders/sales-invoice-tsp.service'
|
||||||
import { ConsumerSaleInvoicesFilterDto } from './dto/saleInvoices-filter.dto'
|
import { ConsumerSaleInvoicesFilterDto } from './dto/saleInvoices-filter.dto'
|
||||||
|
|
||||||
@@ -177,6 +178,39 @@ export class SaleInvoicesService {
|
|||||||
return ResponseMapper.single(invoice)
|
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) {
|
async inquiry(consumer_account_id: string, pos_id: string, invoiceId: string) {
|
||||||
const invoice = await this.sharedSaleInvoiceActionsService.inquiry(
|
const invoice = await this.sharedSaleInvoiceActionsService.inquiry(
|
||||||
consumer_account_id,
|
consumer_account_id,
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ import {
|
|||||||
getOriginalResendAttemptNumber,
|
getOriginalResendAttemptNumber,
|
||||||
getRelatedInvoiceForCorrection,
|
getRelatedInvoiceForCorrection,
|
||||||
onResult,
|
onResult,
|
||||||
trySend,
|
|
||||||
} from './utils/sales-invoice-tsp.utils'
|
} from './utils/sales-invoice-tsp.utils'
|
||||||
|
|
||||||
type ItemTspRow = {
|
type ItemTspRow = {
|
||||||
@@ -228,43 +227,9 @@ export class SalesInvoiceTspService {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
const result = await this.runProviderCall(() =>
|
const result = await this.tspSwitchService.correction(correctionPayload)
|
||||||
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()
|
|
||||||
}
|
|
||||||
|
|
||||||
return onResult(this.prisma, result, attempt.id)
|
return await onResult(this.prisma, result, newInvoice.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 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
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async revoke(
|
async revoke(
|
||||||
@@ -317,71 +282,72 @@ export class SalesInvoiceTspService {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const payments = relatedInvoice.payments.reduce(
|
// const payments = relatedInvoice.payments.reduce(
|
||||||
(acc, payment) => {
|
// (acc, payment) => {
|
||||||
const amount = Number(payment.amount)
|
// const amount = Number(payment.amount)
|
||||||
switch (payment.payment_method) {
|
// switch (payment.payment_method) {
|
||||||
case 'CASH':
|
// case 'CASH':
|
||||||
acc.cash = (acc.cash || 0) + amount
|
// acc.cash = (acc.cash || 0) + amount
|
||||||
break
|
// break
|
||||||
case 'SET_OFF':
|
// case 'SET_OFF':
|
||||||
acc.set_off = (acc.set_off || 0) + amount
|
// acc.set_off = (acc.set_off || 0) + amount
|
||||||
break
|
// break
|
||||||
case 'CARD':
|
// case 'CARD':
|
||||||
acc.card = (acc.card || 0) + amount
|
// acc.card = (acc.card || 0) + amount
|
||||||
break
|
// break
|
||||||
case 'BANK':
|
// case 'BANK':
|
||||||
acc.bank = (acc.bank || 0) + amount
|
// acc.bank = (acc.bank || 0) + amount
|
||||||
break
|
// break
|
||||||
case 'CHEQUE':
|
// case 'CHEQUE':
|
||||||
acc.check = (acc.check || 0) + amount
|
// acc.check = (acc.check || 0) + amount
|
||||||
break
|
// break
|
||||||
case 'OTHER':
|
// case 'OTHER':
|
||||||
acc.other = (acc.other || 0) + amount
|
// acc.other = (acc.other || 0) + amount
|
||||||
break
|
// break
|
||||||
case 'TERMINAL':
|
// case 'TERMINAL':
|
||||||
acc.terminals = payment.terminal_info
|
// acc.terminals = payment.terminal_info
|
||||||
? {
|
// ? {
|
||||||
amount,
|
// amount,
|
||||||
terminalId: payment.terminal_info.terminal_id,
|
// terminal_id: payment.terminal_info.terminal_id,
|
||||||
stan: payment.terminal_info.stan,
|
// stan: payment.terminal_info.stan,
|
||||||
rrn: payment.terminal_info.rrn,
|
// rrn: payment.terminal_info.rrn,
|
||||||
customer_card_no:
|
// customer_card_no:
|
||||||
payment.terminal_info.customer_card_no || undefined,
|
// payment.terminal_info.customer_card_no || undefined,
|
||||||
transaction_date_time: payment.terminal_info.transaction_date_time,
|
// transaction_date_time: payment.terminal_info.transaction_date_time,
|
||||||
description: payment.terminal_info.description || undefined,
|
// description: payment.terminal_info.description || undefined,
|
||||||
}
|
// }
|
||||||
: acc.terminals
|
// : acc.terminals
|
||||||
break
|
// break
|
||||||
default:
|
// default:
|
||||||
break
|
// break
|
||||||
}
|
// }
|
||||||
return acc
|
// return acc
|
||||||
},
|
// },
|
||||||
{} as {
|
// {} as {
|
||||||
terminals?: {
|
// terminals?: {
|
||||||
amount?: number
|
// amount?: number
|
||||||
terminalId: string
|
// terminalId: string
|
||||||
stan: string
|
// stan: string
|
||||||
rrn: string
|
// rrn: string
|
||||||
customer_card_no?: string
|
// customer_card_no?: string
|
||||||
transaction_date_time: Date
|
// transaction_date_time: Date
|
||||||
description?: string
|
// description?: string
|
||||||
}
|
// }
|
||||||
cash?: number
|
// cash?: number
|
||||||
set_off?: number
|
// set_off?: number
|
||||||
card?: number
|
// card?: number
|
||||||
bank?: number
|
// bank?: number
|
||||||
check?: number
|
// check?: number
|
||||||
other?: number
|
// other?: number
|
||||||
},
|
// },
|
||||||
)
|
// )
|
||||||
|
|
||||||
const newInvoice = await this.sharedSaleInvoiceCreateService.create({
|
const newInvoice = await this.sharedSaleInvoiceCreateService.create({
|
||||||
data: {
|
data: {
|
||||||
customer_type: relatedInvoice.customer?.type || CustomerType.UNKNOWN,
|
customer_type: relatedInvoice.customer?.type || CustomerType.UNKNOWN,
|
||||||
invoice_date: new Date(),
|
invoice_date: new Date(),
|
||||||
payments,
|
// @ts-ignore
|
||||||
|
payments: undefined,
|
||||||
settlement_type: relatedInvoice.settlement_type,
|
settlement_type: relatedInvoice.settlement_type,
|
||||||
items: relatedInvoice.items.map(item => ({
|
items: relatedInvoice.items.map(item => ({
|
||||||
unit_price: Number(item.unit_price),
|
unit_price: Number(item.unit_price),
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ export class NamaProviderUtils {
|
|||||||
sstid: item.sku,
|
sstid: item.sku,
|
||||||
vra: item.sku_vat,
|
vra: item.sku_vat,
|
||||||
fee: String(item.unit_price),
|
fee: String(item.unit_price),
|
||||||
dis: String(item.discount_amount),
|
dis: String(parseInt(item.discount_amount + '')),
|
||||||
mu: item.measure_unit,
|
mu: item.measure_unit,
|
||||||
am: String(item.quantity),
|
am: String(item.quantity),
|
||||||
consfee: '0',
|
consfee: '0',
|
||||||
@@ -120,7 +120,7 @@ export class NamaProviderUtils {
|
|||||||
sstid: item.sku,
|
sstid: item.sku,
|
||||||
vra: item.sku_vat,
|
vra: item.sku_vat,
|
||||||
fee: String(item.unit_price),
|
fee: String(item.unit_price),
|
||||||
dis: String(item.discount_amount),
|
dis: String(parseInt(item.discount_amount + '')),
|
||||||
mu: item.measure_unit,
|
mu: item.measure_unit,
|
||||||
am: String(item.quantity),
|
am: String(item.quantity),
|
||||||
consfee: '0',
|
consfee: '0',
|
||||||
@@ -297,6 +297,9 @@ export class NamaProviderUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private mapPayments(payments: PaymentInfoDto[]): NamaProviderPaymentInfoDto[] {
|
private mapPayments(payments: PaymentInfoDto[]): NamaProviderPaymentInfoDto[] {
|
||||||
|
if (!payments) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
return payments.map(payment => ({
|
return payments.map(payment => ({
|
||||||
pmt: this.mapPaymentMethod(payment.payment_method),
|
pmt: this.mapPaymentMethod(payment.payment_method),
|
||||||
pv: payment.amount,
|
pv: payment.amount,
|
||||||
|
|||||||
@@ -653,6 +653,8 @@ export async function onResult(
|
|||||||
data: attemptUpdatedData,
|
data: attemptUpdatedData,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
console.log('attemptUpdatedData', attemptUpdatedData)
|
||||||
|
|
||||||
const updatedInvoice = await tx.salesInvoice.update({
|
const updatedInvoice = await tx.salesInvoice.update({
|
||||||
where: { id: invoice_id },
|
where: { id: invoice_id },
|
||||||
data: {
|
data: {
|
||||||
|
|||||||
Reference in New Issue
Block a user