import { Injectable } from '@nestjs/common';
import { DatabaseService } from '../../../infrastructure/database/database.service';
import { SaaSBillingProviderRegistry } from '../providers/saas-billing-provider.registry';
@Injectable()
export class BillingHistoryService {
constructor(
private readonly database:DatabaseService,
private readonly providers:SaaSBillingProviderRegistry,
) {}
async list(organizationId:string) {
return this.database.query<any>(
`select provider_invoice_id,invoice_number,period_start,period_end,
amount_due_minor,amount_paid_minor,currency_code,status,
hosted_invoice_url,invoice_pdf_url,provider_created_at
from billing_invoice_cache
where organization_id=$1 order by provider_created_at desc nulls last limit 100`,
[organizationId],
);
}
async refresh(organizationId:string) {
const account=(await this.database.query<any>(
`select * from billing_accounts where organization_id=$1`,
[organizationId],
))[0];
if(!account?.provider_customer_id) return {synced:0};
const provider=this.providers.get(account.provider);
const invoices=await provider.listInvoices({
organizationId,billingAccountId:account.id,providerCustomerId:account.provider_customer_id,
credentialReference:String(process.env.SAAS_BILLING_CREDENTIAL_REFERENCE??'env:STRIPE_SECRET_KEY'),
config:{},
});
for(const i of invoices as any[]) {
await this.database.query(
`insert into billing_invoice_cache(
id,organization_id,billing_account_id,provider,provider_invoice_id,invoice_number,
period_start,period_end,amount_due_minor,amount_paid_minor,currency_code,status,
hosted_invoice_url,invoice_pdf_url,provider_created_at
) values(gen_random_uuid(),$1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14)
on conflict(provider,provider_invoice_id)
do update set invoice_number=excluded.invoice_number,amount_due_minor=excluded.amount_due_minor,
amount_paid_minor=excluded.amount_paid_minor,status=excluded.status,
hosted_invoice_url=excluded.hosted_invoice_url,invoice_pdf_url=excluded.invoice_pdf_url,
updated_at=now()`,
[
organizationId,account.id,account.provider,i.providerInvoiceId,i.invoiceNumber,
i.periodStart,i.periodEnd,i.amountDueMinor,i.amountPaidMinor,i.currencyCode,
i.status,i.hostedInvoiceUrl,i.invoicePdfUrl,i.providerCreatedAt,
],
);
}
return {synced:invoices.length};
}
}
