mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
Excess baggage payment link changes
This commit is contained in:
@@ -2,7 +2,10 @@ import { IsString, IsInt, IsOptional, IsPositive } from 'class-validator';
|
||||
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||
|
||||
export class LogExcessBaggageDto {
|
||||
@ApiProperty({ example: 'booking-uuid' }) @IsString() bookingId: string;
|
||||
@ApiPropertyOptional({ example: 'booking-uuid', description: 'Booking UUID for the passenger booking' })
|
||||
@IsOptional() @IsString() bookingId?: string;
|
||||
@ApiPropertyOptional({ example: 'JS6MJ9', description: 'Booking reference for the passenger booking' })
|
||||
@IsOptional() @IsString() bookingReference?: string;
|
||||
@ApiPropertyOptional({ example: 'agent-uuid', description: 'Injected from IAM token; optional override' })
|
||||
@IsOptional() @IsString() agentId?: string;
|
||||
@ApiProperty({ example: 7, description: 'Excess weight in kg above the free allowance' })
|
||||
|
||||
@@ -39,12 +39,25 @@ export class ExcessBaggageService {
|
||||
) {}
|
||||
|
||||
async logCharge(dto: LogExcessBaggageDto) {
|
||||
const booking = await this.prisma.booking.findUnique({
|
||||
where: { id: dto.bookingId },
|
||||
include: {
|
||||
passenger: { include: { user: true } },
|
||||
},
|
||||
});
|
||||
const bookingRef = dto.bookingReference?.trim();
|
||||
const bookingId = dto.bookingId?.trim();
|
||||
|
||||
const booking = bookingRef
|
||||
? await this.prisma.booking.findFirst({
|
||||
where: { bookingRef: { equals: bookingRef, mode: 'insensitive' } },
|
||||
include: {
|
||||
passenger: { include: { user: true } },
|
||||
},
|
||||
})
|
||||
: bookingId
|
||||
? await this.prisma.booking.findUnique({
|
||||
where: { id: bookingId },
|
||||
include: {
|
||||
passenger: { include: { user: true } },
|
||||
},
|
||||
})
|
||||
: null;
|
||||
|
||||
if (!booking) throw new NotFoundException('Booking not found');
|
||||
if (!['CONFIRMED', 'BOARDED'].includes(booking.status)) {
|
||||
throw new BadRequestException('Booking must be CONFIRMED or BOARDED to log excess baggage');
|
||||
@@ -64,7 +77,7 @@ export class ExcessBaggageService {
|
||||
|
||||
const charge = await this.prisma.excessBaggageCharge.create({
|
||||
data: {
|
||||
bookingId: dto.bookingId,
|
||||
bookingId: booking.id,
|
||||
agentId: dto.agentId ?? '',
|
||||
excessWeightKg: dto.excessWeightKg,
|
||||
feePerKgMinor,
|
||||
@@ -81,7 +94,7 @@ export class ExcessBaggageService {
|
||||
await this.sendPaymentLink(charge, booking, contactPhone, contactEmail);
|
||||
}
|
||||
|
||||
await this.auditService.log({ action: 'CREATE', entityType: 'ExcessBaggageCharge', entityId: charge.id, newData: { bookingId: dto.bookingId, excessWeightKg: dto.excessWeightKg, totalMinor, status } });
|
||||
await this.auditService.log({ action: 'CREATE', entityType: 'ExcessBaggageCharge', entityId: charge.id, newData: { bookingId: booking.id, excessWeightKg: dto.excessWeightKg, totalMinor, status } });
|
||||
return charge;
|
||||
}
|
||||
|
||||
|
||||
@@ -110,6 +110,43 @@ describe("Money integrity (Tier-2 direct instantiation)", () => {
|
||||
expect(walletAfter?.balanceMinor).toBe(0);
|
||||
});
|
||||
|
||||
it("accepts a booking reference when logging an excess baggage charge", async () => {
|
||||
const passenger = await prisma.passenger.create({ data: {} });
|
||||
const schedule = await makeSchedule(prisma, passenger.id);
|
||||
const booking = await prisma.booking.create({
|
||||
data: {
|
||||
bookingRef: "BAG-REF-001",
|
||||
passengerId: passenger.id,
|
||||
scheduleId: schedule.id,
|
||||
totalMinor: 30_000,
|
||||
status: "CONFIRMED",
|
||||
},
|
||||
});
|
||||
|
||||
await prisma.baggageAllowance.create({
|
||||
data: { seatClassId: IDS.seatClassLocal, maxWeightKg: 20, maxPiecesCount: 2, excessFeePerKg: 80 },
|
||||
});
|
||||
|
||||
const service = new ExcessBaggageService(
|
||||
prisma as any,
|
||||
asyncStub(),
|
||||
asyncStub(),
|
||||
asyncStub(),
|
||||
asyncStub(),
|
||||
asyncStub(),
|
||||
);
|
||||
|
||||
const charge: any = await service.logCharge({
|
||||
bookingReference: booking.bookingRef,
|
||||
excessWeightKg: 2,
|
||||
collectCash: true,
|
||||
} as any);
|
||||
|
||||
expect(charge.bookingId).toBe(booking.id);
|
||||
expect(charge.feePerKgMinor).toBe(80);
|
||||
expect(charge.totalMinor).toBe(160);
|
||||
});
|
||||
|
||||
// ── E1 / E2 ────────────────────────────────────────────────────────────────
|
||||
it("E1/E2 🔴 excess-baggage uses the OLDEST allowance globally (ignores seat class); fee = rate×kg", async () => {
|
||||
const passenger = await prisma.passenger.create({ data: {} });
|
||||
|
||||
Reference in New Issue
Block a user