feat: setup pagination to find all invoice api

This commit is contained in:
Nathnael
2026-07-03 06:20:05 +00:00
parent 635d674bbe
commit 53fed882be
3 changed files with 109 additions and 10 deletions

View File

@@ -125,7 +125,7 @@ export class BillingService {
private readonly payment: PaymentService,
private readonly companies: CompaniesService,
private readonly invoiceDocuments: InvoiceDocumentService,
) { }
) {}
// ── Reads ──────────────────────────────────────────────────────────────────
@@ -134,9 +134,56 @@ export class BillingService {
return this.invoices.findAll({ order: { issuedAt: "DESC" } });
}
/**
* Paginated invoice list for the backoffice — optionally narrowed to a
* company (customer detail "Invoices" tab) and/or status/search (global
* invoices page).
*/
async findAllPaginated(
filter: {
companyId?: string;
status?: Freight.InvoiceStatus;
search?: string;
page?: number;
pageSize?: number;
} = {},
): Promise<{ items: Invoice[]; total: number }> {
const page = filter.page && filter.page > 0 ? filter.page : 1;
const pageSize =
filter.pageSize && filter.pageSize > 0 ? filter.pageSize : 20;
const qb = this.dataSource
.getRepository(Invoice)
.createQueryBuilder("invoice")
.leftJoinAndSelect("invoice.company", "company")
.orderBy("invoice.issuedAt", "DESC")
.skip((page - 1) * pageSize)
.take(pageSize);
if (filter.companyId) {
qb.andWhere("invoice.companyId = :companyId", {
companyId: filter.companyId,
});
}
if (filter.status) {
qb.andWhere("invoice.status = :status", { status: filter.status });
}
if (filter.search) {
qb.andWhere(
"(invoice.invoiceNumber ILIKE :search OR invoice.sourceId ILIKE :search)",
{ search: `%${filter.search}%` },
);
}
const [items, total] = await qb.getManyAndCount();
return { items, total };
}
/** Invoice header plus its line items. */
async findById(id: string): Promise<Invoice & { lines: InvoiceLine[] }> {
const invoice = await this.invoices.findById(id);
const invoice = await this.invoices.findById(id, {
relations: { company: true, companyProfile: true },
});
if (!invoice) throw new NotFoundException(`Invoice ${id} not found`);
const lines = await this.invoiceLines.findAll({
where: { invoiceId: id },
@@ -375,7 +422,7 @@ export class BillingService {
input.dueAt ??
new Date(
Date.now() +
(input.dueInDays ?? DEFAULT_DUE_DAYS) * 24 * 60 * 60 * 1000,
(input.dueInDays ?? DEFAULT_DUE_DAYS) * 24 * 60 * 60 * 1000,
);
const invoiceNumber = await this.nextInvoiceNumber(mg);