feat(billing): USD offline bank-transfer payments

This commit is contained in:
Marshal
2026-08-08 13:37:05 +00:00
parent 83b9e32670
commit a42d32c27c
31 changed files with 923 additions and 11 deletions

View File

@@ -1,19 +1,31 @@
import {
Body,
Controller,
Get,
Param,
ParseUUIDPipe,
Post,
Query,
Res,
UploadedFile,
UseInterceptors,
} from "@nestjs/common";
import { ApiBearerAuth, ApiOperation, ApiTags } from "@nestjs/swagger";
import { FileInterceptor } from "@nestjs/platform-express";
import {
ApiBearerAuth,
ApiConsumes,
ApiOperation,
ApiTags,
} from "@nestjs/swagger";
import type { Response } from "express";
import { CurrentUser } from "@edr/api-common";
import type { TCurrentUser } from "@tria-plc/api-common/modules/auth/types/current-user.type";
import { BookingStaff } from "../../common/booking-guards";
import { resolveAuthUserId } from "../../common/resolve-auth-user-id";
import { FREIGHT_PERMS } from "../../seed/freight-permissions.registry";
import { actorLabel } from "../warehouses/current-actor.util";
import { UserTradeAccessService } from "../user-trade-access/user-trade-access.service";
import { BillingService } from "./billing.service";
import { FilterInvoiceDto } from "./dto/filter-invoice.dto";
@@ -25,6 +37,7 @@ import { FilterInvoiceDto } from "./dto/filter-invoice.dto";
@BookingStaff([
FREIGHT_PERMS.invoices.view,
FREIGHT_PERMS.invoices.export,
FREIGHT_PERMS.invoices.confirmOffline,
])
@ApiBearerAuth()
export class BillingController {
@@ -56,6 +69,36 @@ export class BillingController {
return this.billingService.findById(id);
}
@Get("offline-usd")
@ApiOperation({
summary:
"Finance worklist: USD invoices settled offline by bank transfer, with booking pay-window context",
})
findOfflineUsd(@Query() query: FilterInvoiceDto) {
return this.billingService.findOfflineUsdPaginated(query);
}
@Post("invoices/:id/confirm-offline")
@BookingStaff(FREIGHT_PERMS.invoices.confirmOffline)
@UseInterceptors(FileInterceptor("file"))
@ApiConsumes("multipart/form-data")
@ApiOperation({
summary:
"Finance confirms a USD invoice paid by bank transfer — slip file required, settles the full balance",
})
confirmOffline(
@Param("id", ParseUUIDPipe) id: string,
@UploadedFile() file: Express.Multer.File | undefined,
@Body("reference") reference: string | undefined,
@CurrentUser() user: TCurrentUser,
) {
return this.billingService.confirmOfflinePayment(id, file, {
reference: reference?.trim() || null,
userId: resolveAuthUserId(user),
userName: actorLabel(user) ?? null,
});
}
@Get("invoices/:id/document")
@BookingStaff(FREIGHT_PERMS.invoices.export)
@ApiOperation({ summary: "Download the sealed invoice PDF" })