diff --git a/apps/api/src/modules/admin/admin.billing.service.ts b/apps/api/src/modules/admin/admin.billing.service.ts index 47495b1..a05e0ea 100644 --- a/apps/api/src/modules/admin/admin.billing.service.ts +++ b/apps/api/src/modules/admin/admin.billing.service.ts @@ -850,7 +850,10 @@ export async function finalizeInvoice(invoiceId: string, adminId: string, ip?: s } const taxBase = Math.max(preTaxBase - autoCreditToApply, 0) - const { taxRate, taxAmount } = calculateTaxAmount(taxBase, account.taxExempt, platformBillingSettings.taxRate) + const shouldApplyTax = current.invoiceType !== 'MANUAL' + const { taxRate, taxAmount } = shouldApplyTax + ? calculateTaxAmount(taxBase, account.taxExempt, platformBillingSettings.taxRate) + : { taxRate: 0, taxAmount: 0 } if (taxAmount > 0) { await tx.billingInvoiceLineItem.create({ diff --git a/apps/api/src/modules/subscriptions/subscription.manual.service.ts b/apps/api/src/modules/subscriptions/subscription.manual.service.ts index 25d3aea..6784b53 100644 --- a/apps/api/src/modules/subscriptions/subscription.manual.service.ts +++ b/apps/api/src/modules/subscriptions/subscription.manual.service.ts @@ -950,16 +950,23 @@ function safeSubmission(submission: any) { } export async function getCanonicalInvoices(companyId: string) { - const invoices = await prisma.billingInvoice.findMany({ - where: { companyId, subscriptionId: { not: null }, status: 'PAID' }, - include: { - manualPaymentSubmissions: { orderBy: { createdAt: 'desc' }, include: { documents: { orderBy: { uploadedAt: 'asc' } } } }, - paymentAttempts: { where: { status: 'SUCCEEDED' }, orderBy: { attemptedAt: 'desc' }, take: 1 }, - }, - orderBy: { createdAt: 'desc' }, - take: 50, - }) - return invoices.map((invoice: any) => ({ + const [invoices, legacyInvoices] = await Promise.all([ + prisma.billingInvoice.findMany({ + where: { companyId, subscriptionId: { not: null } }, + include: { + manualPaymentSubmissions: { orderBy: { createdAt: 'desc' }, include: { documents: { orderBy: { uploadedAt: 'asc' } } } }, + paymentAttempts: { where: { status: 'SUCCEEDED' }, orderBy: { attemptedAt: 'desc' }, take: 1 }, + }, + orderBy: { createdAt: 'desc' }, + take: 50, + }), + prisma.subscriptionInvoice.findMany({ + where: { companyId, billingInvoiceId: null }, + orderBy: { createdAt: 'desc' }, + take: 50, + }), + ]) + const canonical = invoices.map((invoice: any) => ({ id: invoice.id, invoiceNumber: invoice.invoiceNumber, amount: invoice.totalAmount, @@ -981,6 +988,27 @@ export async function getCanonicalInvoices(companyId: string) { ? safeSubmission(invoice.manualPaymentSubmissions[0]) : null, })) + const legacy = legacyInvoices.map((invoice: any) => ({ + id: invoice.id, + invoiceNumber: null, + amount: invoice.amount, + amountPaid: invoice.status === 'PAID' ? invoice.amount : 0, + amountDue: invoice.status === 'PAID' ? 0 : invoice.amount, + currency: invoice.currency, + status: invoice.status, + paymentProvider: invoice.paymentProvider, + collectionMethod: invoice.paymentProvider === 'STRIPE' ? 'STRIPE' : 'BANK_TRANSFER', + requestedPlan: invoice.requestedPlan, + requestedBillingPeriod: invoice.requestedBillingPeriod, + dueAt: invoice.dueAt, + paidAt: invoice.paidAt, + createdAt: invoice.createdAt, + confirmedReference: null, + manualPaymentSubmission: null, + })) + return [...canonical, ...legacy] + .sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()) + .slice(0, 50) } export async function getPaidInvoicePdf(companyId: string, invoiceId: string) {