This commit is contained in:
Marshal
2026-07-16 20:03:35 +00:00
parent 7fb5a58ab0
commit 35c53e3f36
5 changed files with 99 additions and 30 deletions

View File

@@ -16,6 +16,7 @@ import {
InvoiceLineInput,
} from "../billing/billing.service";
import { Invoice } from "../billing/entities/invoice.entity";
import { CLEARANCE_BOOKING_INVOICE_TYPE } from "../contracts/clearance-fee.service";
import { FirstMileService } from "../first-mile/first-mile.service";
import { BookingBatchService } from "../train-scheduling/booking-batch.service";
import { PriceLineItemDto } from "./dto/generate-price-response.dto";
@@ -120,17 +121,27 @@ export class BookingInvoiceService {
}
/**
* Expire the booking's currently-open prepaid invoice when the booking is
* Expire the booking's currently-open invoices (freight PREPAID and the
* per-shipment clearance fee) when the booking is
* cancelled or rejected — the counterpart to the pay-window-expiry path
* (which also calls {@link BillingService.expirePayable}). Stops a terminated
* booking from leaving a payable invoice open. No-op when the booking has no
* open invoice (never invoiced, already paid/cancelled/expired). Pass a
* caller `manager` to enlist in its transaction.
*/
expireOpenInvoices(
async expireOpenInvoices(
bookingId: string,
manager?: EntityManager,
): Promise<Invoice | null> {
// The per-shipment clearance fee (GENERAL contracts) bills this same booking
// id under its own source/type — retire it alongside the freight invoice, or
// a cancelled shipment keeps a payable clearance invoice open.
await this.billing.expirePayable(
Freight.InvoiceSource.Clearance,
bookingId,
CLEARANCE_BOOKING_INVOICE_TYPE,
manager,
);
return this.billing.expirePayable(
Freight.InvoiceSource.Booking,
bookingId,