mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
Merge pull request #1124 from Tria-plc/freight/nati-2
Audit log and presistent cbe pnr
This commit is contained in:
@@ -24,7 +24,11 @@ describe("IntentsService CBE_BILL", () => {
|
||||
let repository: jest.Mocked<
|
||||
Pick<
|
||||
IntentsRepository,
|
||||
"create" | "findById" | "findByIdempotencyKey" | "update"
|
||||
| "create"
|
||||
| "findById"
|
||||
| "findByIdempotencyKey"
|
||||
| "findAllByReference"
|
||||
| "update"
|
||||
>
|
||||
>;
|
||||
let billReferenceService: { generate: jest.Mock };
|
||||
@@ -46,6 +50,7 @@ describe("IntentsService CBE_BILL", () => {
|
||||
create: jest.fn(async (data) => ({ id: "intent-1", ...data })),
|
||||
findById: jest.fn(),
|
||||
findByIdempotencyKey: jest.fn().mockResolvedValue(null),
|
||||
findAllByReference: jest.fn().mockResolvedValue([]),
|
||||
update: jest.fn(),
|
||||
} as never;
|
||||
billReferenceService = {
|
||||
@@ -79,6 +84,47 @@ describe("IntentsService CBE_BILL", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("reuses the open bill instead of minting a second reference", async () => {
|
||||
repository.findAllByReference.mockResolvedValue([
|
||||
{
|
||||
id: "intent-1",
|
||||
provider: ProviderMethod.CBE_BILL,
|
||||
status: ProviderPaymentStatus.REQUIRES_ACTION,
|
||||
billReference: "000100000015",
|
||||
amountMinor: 1500,
|
||||
currency: "ETB",
|
||||
clientAction: {
|
||||
type: "SHOW_BILL_REFERENCE",
|
||||
billReference: "000100000015",
|
||||
},
|
||||
},
|
||||
] as never);
|
||||
|
||||
const snapshot = await service.initiate(request);
|
||||
|
||||
expect(snapshot.billReference).toBe("000100000015");
|
||||
expect(billReferenceService.generate).not.toHaveBeenCalled();
|
||||
expect(repository.create).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("mints a new bill when the amount changed", async () => {
|
||||
repository.findAllByReference.mockResolvedValue([
|
||||
{
|
||||
id: "intent-1",
|
||||
provider: ProviderMethod.CBE_BILL,
|
||||
status: ProviderPaymentStatus.REQUIRES_ACTION,
|
||||
billReference: "000100000015",
|
||||
amountMinor: 900,
|
||||
currency: "ETB",
|
||||
},
|
||||
] as never);
|
||||
billReferenceService.generate.mockResolvedValue("000100000023");
|
||||
|
||||
const snapshot = await service.initiate(request);
|
||||
|
||||
expect(snapshot.billReference).toBe("000100000023");
|
||||
});
|
||||
|
||||
it("rejects non-ETB currency (plan D8)", async () => {
|
||||
await expect(
|
||||
service.initiate({ ...request, currency: "DJF" }),
|
||||
|
||||
@@ -163,6 +163,32 @@ export class IntentsService {
|
||||
);
|
||||
}
|
||||
|
||||
// The bill reference is issued ONCE per order: the domain app persists it (freight stores it
|
||||
// as the booking's PNR) and the payer may already have written it down, so re-initiating the
|
||||
// same open bill must hand back the same number. A different amount/currency means a
|
||||
// different debt — /cbe/payment verifies the debited amount against the intent — so that
|
||||
// case mints a fresh bill instead of silently repricing an outstanding one.
|
||||
const open = (
|
||||
await this.intentsRepository.findAllByReference(
|
||||
request.service,
|
||||
request.referenceType,
|
||||
request.referenceId,
|
||||
)
|
||||
).find(
|
||||
(i) =>
|
||||
i.provider === ProviderMethod.CBE_BILL &&
|
||||
i.status === ProviderPaymentStatus.REQUIRES_ACTION &&
|
||||
!!i.billReference &&
|
||||
i.amountMinor === request.amountMinor &&
|
||||
i.currency === request.currency,
|
||||
);
|
||||
if (open) {
|
||||
this.logger.log(
|
||||
`intent ${open.id} reused for ${request.service}/${request.referenceType}/${request.referenceId} via CBE_BILL (bill ${open.billReference})`,
|
||||
);
|
||||
return this.toSnapshot(open);
|
||||
}
|
||||
|
||||
const merchantOrderId = createMerchantOrderId();
|
||||
const billReference = await this.billReferenceService.generate();
|
||||
// expiresAt is the BOOKING's payment deadline passed by the domain app — never a provider
|
||||
|
||||
Reference in New Issue
Block a user