mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
feat: ( payment ) specific CBE query descriptions + Payment_Reason
This commit is contained in:
@@ -61,9 +61,13 @@ export class MarkPaidResponseDto {
|
||||
* "is this order still payable, by whom, for how much" while a CBE teller/app is on the line.
|
||||
*/
|
||||
export class BillQueryRequestDto {
|
||||
// Typed `string`, not the enum: the @nestjs/swagger CLI plugin resolves an enum-typed
|
||||
// property to a relative require() into packages/types, which does not exist inside the
|
||||
// Docker image (only /app is copied) and crashes at boot with MODULE_NOT_FOUND. The
|
||||
// decorators below still give us enum docs + runtime validation.
|
||||
@ApiProperty({ enum: PaymentReferenceType })
|
||||
@IsEnum(PaymentReferenceType)
|
||||
referenceType!: PaymentReferenceType;
|
||||
referenceType!: string;
|
||||
|
||||
@ApiProperty() @IsString() referenceId!: string;
|
||||
}
|
||||
@@ -73,6 +77,8 @@ export class BillQueryResponseDto {
|
||||
@ApiPropertyOptional() payerName?: string | null;
|
||||
@ApiPropertyOptional() currentAmountMinor?: number | null;
|
||||
@ApiPropertyOptional() currency?: string | null;
|
||||
/** When stillPayable=false: "CANCELLED" | "ALREADY_PAID" | "EXPIRED". */
|
||||
/** When stillPayable=false: "ALREADY_PAID" | "CANCELLED" | "REFUNDED" | "EXPIRED" | "NOT_FOUND" | "NOT_PAYABLE". */
|
||||
@ApiPropertyOptional() reason?: string | null;
|
||||
/** What the payer is paying for — CBE renders it beside the amount (Payment_Reason). */
|
||||
@ApiPropertyOptional() paymentReason?: string | null;
|
||||
}
|
||||
|
||||
@@ -400,7 +400,9 @@ export class PaymentsService {
|
||||
where: { id: bookingId },
|
||||
include: { seats: true, passenger: { include: { user: true } } },
|
||||
});
|
||||
if (!booking) return { stillPayable: false, reason: "CANCELLED" };
|
||||
// Distinct from CANCELLED: the payment service issued a bill reference for a booking that
|
||||
// no longer exists at all, which is a data problem, not a customer-facing cancellation.
|
||||
if (!booking) return { stillPayable: false, reason: "NOT_FOUND" };
|
||||
|
||||
const base = {
|
||||
// Full_Name is mandatory in CBE's envelope: lead passenger first, then account holder.
|
||||
@@ -414,14 +416,26 @@ export class PaymentsService {
|
||||
"ETB",
|
||||
),
|
||||
currency: "ETB",
|
||||
// CBE shows this beside the amount on the confirmation screen. bookingRef is the same
|
||||
// code on the customer's ticket, so they can match the two before confirming.
|
||||
paymentReason: `Train ticket booking ${booking.bookingRef}`,
|
||||
};
|
||||
|
||||
// Paid first: a booking that was paid and then boarded/refunded must never be reported as
|
||||
// merely "not payable" — the payer needs to hear that their money already went through.
|
||||
if (booking.status === "CONFIRMED" || booking.paidAt) {
|
||||
return { ...base, stillPayable: false, reason: "ALREADY_PAID" };
|
||||
}
|
||||
if (booking.status !== "PENDING_PAYMENT") {
|
||||
if (booking.status === "REFUNDED") {
|
||||
return { ...base, stillPayable: false, reason: "REFUNDED" };
|
||||
}
|
||||
if (booking.status === "CANCELLED") {
|
||||
return { ...base, stillPayable: false, reason: "CANCELLED" };
|
||||
}
|
||||
// DRAFT / BOARDED / NO_SHOW without a payment: no honest specific wording exists.
|
||||
if (booking.status !== "PENDING_PAYMENT") {
|
||||
return { ...base, stillPayable: false, reason: "NOT_PAYABLE" };
|
||||
}
|
||||
const deadline = await this.computeBookingPaymentDeadline(booking.id);
|
||||
if (deadline && deadline.getTime() < Date.now()) {
|
||||
return { ...base, stillPayable: false, reason: "EXPIRED" };
|
||||
|
||||
Reference in New Issue
Block a user