Files
psp_api/src/modules/pos/sales-invoices/sales-invoices.service.ts
T

198 lines
5.8 KiB
TypeScript
Raw Normal View History

2026-03-29 18:06:41 +03:30
import { IPosPayload } from '@/common/models/posPayload.model'
import { SalesInvoiceCreateInput } from '@/generated/prisma/models'
import { PrismaService } from '@/prisma/prisma.service'
import { BadRequestException, Injectable } from '@nestjs/common'
import { ResponseMapper } from 'common/response/response-mapper'
import type { CustomerIndividual, CustomerLegal } from 'generated/prisma/client'
import { CustomerType, PaymentMethodType } from 'generated/prisma/enums'
import { CreateSalesInvoiceDto } from './dto/create-sales-invoice.dto'
// Define type guard for CustomerIndividual
function isCustomerIndividual(customer: any): customer is CustomerIndividual {
return (
customer &&
typeof customer.first_name === 'string' &&
typeof customer.last_name === 'string'
)
}
// Define type guard for CustomerLegal
function isCustomerLegal(customer: any): customer is CustomerLegal {
return (
customer &&
typeof customer.company_name === 'string' &&
typeof customer.registration_number === 'string'
)
}
2026-01-07 15:25:59 +03:30
@Injectable()
export class SalesInvoicesService {
constructor(private prisma: PrismaService) {}
findAll() {
// TODO: Implement fetching all sales invoices
return []
2026-01-07 15:25:59 +03:30
}
findOne(id: number) {
// TODO: Implement fetching a single sales invoice
return {}
2026-01-07 15:25:59 +03:30
}
2026-03-29 18:06:41 +03:30
async create(data: CreateSalesInvoiceDto, posInfo: IPosPayload) {
data.invoice_date = new Date(data.invoice_date).toISOString() as any
2026-03-29 18:06:41 +03:30
const { complex_id, pos_id, consumer_account_id } = posInfo
const salesInvoice = await this.prisma.$transaction(async $tx => {
const payments = Object.entries(data.payments)
.filter(([_, value]) => value > 0 && PaymentMethodType[_.toUpperCase()])
.map(([key, value]) => {
return {
amount: value,
payment_method: key.toLocaleUpperCase() as PaymentMethodType,
paid_at: data.invoice_date,
}
})
const totalPayments = payments.reduce((sum, payment) => sum + payment.amount, 0)
2026-03-29 18:06:41 +03:30
if (totalPayments !== data.total_amount) {
throw new Error('مبلغ پرداختی باید برابر با مبلغ کل فاکتور باشد.')
}
const { customer_id, customer_type, customer, ...invoiceData } = data
let newCustomerId: string | null = customer_id || null
if (customer_id) {
} else if (
customer_type === CustomerType.INDIVIDUAL &&
customer?.customer_individual
) {
const customer_individual = customer.customer_individual
const customerIndividual = await $tx.customerIndividual.upsert({
where: {
complex_id_national_id: {
2026-03-29 18:06:41 +03:30
complex_id,
national_id: customer_individual.national_id,
},
},
create: {
...customer_individual,
customer: {
create: {
type: CustomerType.INDIVIDUAL,
},
},
complex: {
connect: {
id: complex_id,
},
},
},
update: {},
select: {
customer_id: true,
},
})
if (!customerIndividual) {
throw new BadRequestException('متاسفانه مشکلی در اطلاعات مشتری وجود دارد.')
}
newCustomerId = customerIndividual.customer_id
} else if (data.customer_type === CustomerType.LEGAL && customer?.customer_legal) {
const customer_legal = customer.customer_legal
const customerLegal = await $tx.customerLegal.upsert({
where: {
complex_id_registration_number: {
2026-03-29 18:06:41 +03:30
complex_id,
registration_number: customer_legal.registration_number,
},
},
create: {
...customer_legal,
customer: {
create: {
type: CustomerType.LEGAL,
},
},
complex: {
connect: {
id: complex_id,
},
},
},
update: {},
select: {
customer_id: true,
},
})
if (!customerLegal) {
throw new BadRequestException('متاسفانه مشکلی در اطلاعات مشتری وجود دارد.')
}
newCustomerId = customerLegal.customer_id
2026-03-29 18:06:41 +03:30
} else if (data.customer_type === CustomerType.UNKNOWN) {
}
const salesInvoiceData: SalesInvoiceCreateInput = {
...invoiceData,
total_amount: data.total_amount,
code: 'INV-' + Date.now(),
items: {
createMany: {
data: data.items.map(item => ({
good_id: item.good_id,
quantity: item.quantity,
unit_price: item.unit_price,
total_amount: item.total_amount,
payload: item.payload
? JSON.parse(JSON.stringify(item.payload))
: undefined,
unit_type: item.unit_type,
// pricing_model: item.pricingModel,
})),
},
},
unknown_customer: {},
payments: {
createMany: {
data: payments,
},
},
// customer: {
// connect: {
// id: newCustomerId || undefined,
// },
// },
consumer_account: {
connect: {
id: consumer_account_id,
2026-03-29 18:06:41 +03:30
},
},
pos: {
connect: {
id: pos_id,
2026-03-29 18:06:41 +03:30
},
},
}
if (newCustomerId) {
salesInvoiceData.customer = {
connect: {
id: newCustomerId || undefined,
},
}
}
const salesInvoice = await $tx.salesInvoice.create({
data: salesInvoiceData,
})
return salesInvoice
})
return ResponseMapper.create(salesInvoice)
2026-01-07 15:25:59 +03:30
}
}