feat: ( reschedule ) implement booking reschedule

This commit is contained in:
Abubeker
2026-08-21 08:18:03 +00:00
parent e174efb8e0
commit 80a7a2f702
27 changed files with 1450 additions and 51 deletions

View File

@@ -74,6 +74,6 @@ function rabbitMQImport(): DynamicModule[] {
PaymentSyncService,
ServiceAuthGuard,
],
exports: [PaymentClientService, PaymentsService],
exports: [PaymentClientService, PaymentsService, SupplementaryChargesService],
})
export class PaymentsModule {}

View File

@@ -1619,6 +1619,7 @@ export class PaymentsService {
settledCurrency: event.currency,
},
});
this.eventEmitter.emit("supplementary-charge.paid", { chargeId: charge.id });
}
return { processed: true, alreadyFinalized: count === 0 };
}
@@ -1996,7 +1997,7 @@ export class PaymentsService {
});
}
private async createJourneySegments(
async createJourneySegments(
booking: Prisma.BookingGetPayload<{ include: { seats: true } }>,
) {
const b = booking as any;

View File

@@ -52,7 +52,7 @@ describe('SupplementaryChargesService — audit', () => {
};
audit = { log: jest.fn().mockResolvedValue(undefined) };
// Constructor order: prisma, audit, sms, email, paymentClient, currency.
// Constructor order: prisma, audit, sms, email, paymentClient, currency, eventEmitter.
service = new SupplementaryChargesService(
prisma as any,
audit as any,
@@ -60,6 +60,7 @@ describe('SupplementaryChargesService — audit', () => {
{ sendEmail: jest.fn() } as any,
{} as any,
{} as any,
{ emit: jest.fn() } as any,
);
return row;
};

View File

@@ -14,6 +14,7 @@ import {
} from '@edr/types';
import { PaymentPlatformDto } from './payments.dto';
import { PaymentMethodType } from '@prisma/client';
import { EventEmitter2 } from '@nestjs/event-emitter';
const CHARGE_TTL_MS = 72 * 60 * 60 * 1000; // 72 hours
@@ -45,6 +46,7 @@ export class SupplementaryChargesService {
private emailClient: EmailClientService,
private paymentClient: PaymentClientService,
private currencyService: CurrencyService,
private eventEmitter: EventEmitter2,
) {}
async create(dto: {
@@ -53,6 +55,8 @@ export class SupplementaryChargesService {
reason: string;
notes?: string;
createdBy: string;
/** Overrides the default 72h link lifetime (a reschedule charge must die with its seat hold). */
expiresAt?: Date;
}) {
const booking = await this.prisma.booking.findUnique({
where: { bookingRef: dto.bookingRef },
@@ -64,7 +68,7 @@ export class SupplementaryChargesService {
}
if (dto.amountMinor <= 0) throw new BadRequestException('Amount must be positive');
const expiresAt = new Date(Date.now() + CHARGE_TTL_MS);
const expiresAt = dto.expiresAt ?? new Date(Date.now() + CHARGE_TTL_MS);
const charge = await this.prisma.supplementaryCharge.create({
data: {
bookingId: booking.id,
@@ -170,6 +174,7 @@ export class SupplementaryChargesService {
providerTxnId: providerTxnId ?? null,
},
});
this.eventEmitter.emit('supplementary-charge.paid', { chargeId: id });
}
return updated!;

View File

@@ -69,6 +69,7 @@ describe('SupplementaryChargesService — payment methods', () => {
{} as any,
paymentClient as any,
new CurrencyService(prisma as any),
{ emit: jest.fn() } as any,
);
};