mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
Package passenger numbers and pricing updates
This commit is contained in:
@@ -341,8 +341,9 @@ export class BookingsService {
|
||||
totalMinor: b.totalMinor, currency: b.currency || 'ETB',
|
||||
displayCurrency: b.displayCurrency, displayTotalMinor: b.displayTotalMinor,
|
||||
contactEmail: b.contactEmail, contactPhone: b.contactPhone,
|
||||
bookingType: 'PACKAGE', packageId: b.packageId, isPackageBooking: true,
|
||||
packageName: b.package?.name, packageCode: b.package?.code,
|
||||
bookingType: 'PACKAGE', packageId: b.packageId, priceTierId: b.priceTierId,
|
||||
isPackageBooking: true, packageName: b.package?.name, packageCode: b.package?.code,
|
||||
tierLabel: b.priceTier?.label ?? null,
|
||||
returnLegStatus: null, adultCount: b.passengerCount, childCount: 0,
|
||||
createdAt: b.createdAt, passenger: null,
|
||||
passengerNames: b.passengers?.map((p: any) => p.passengerName) ?? [],
|
||||
@@ -372,6 +373,8 @@ export class BookingsService {
|
||||
schedule: { include: { originStation: true, destinationStation: true, train: true } },
|
||||
paymentIntent: true,
|
||||
seats: { include: { seat: true } },
|
||||
package: { select: { id: true, name: true, code: true } },
|
||||
priceTier: { select: { id: true, label: true } },
|
||||
},
|
||||
}),
|
||||
this.prisma.booking.count({ where }),
|
||||
@@ -415,6 +418,10 @@ export class BookingsService {
|
||||
contactPhone: booking.contactPhone,
|
||||
bookingType: booking.bookingType,
|
||||
packageId: booking.packageId ?? null,
|
||||
priceTierId: (booking as any).priceTierId ?? null,
|
||||
packageName: (booking as any).package?.name ?? null,
|
||||
packageCode: (booking as any).package?.code ?? null,
|
||||
tierLabel: (booking as any).priceTier?.label ?? null,
|
||||
isPackageBooking: !!booking.packageId,
|
||||
returnLegStatus: (booking as any).returnLegStatus ?? null,
|
||||
adultCount: booking.adultCount,
|
||||
@@ -446,9 +453,11 @@ export class BookingsService {
|
||||
contactPhone: b.contactPhone,
|
||||
bookingType: 'PACKAGE',
|
||||
packageId: b.packageId,
|
||||
priceTierId: b.priceTierId,
|
||||
isPackageBooking: true,
|
||||
packageName: b.package?.name,
|
||||
packageCode: b.package?.code,
|
||||
tierLabel: b.priceTier?.label ?? null,
|
||||
returnLegStatus: null,
|
||||
adultCount: b.passengerCount,
|
||||
childCount: 0,
|
||||
@@ -518,20 +527,18 @@ export class BookingsService {
|
||||
displayTotalMinor = await this.currencyService.convertAmount(fareCalculation.totalMinor, Currency.ETB, displayCurrency);
|
||||
}
|
||||
|
||||
// Track which child gets free fare (first child encountered)
|
||||
// Track per-seat fare. For package bookings children pay 10% of adult fare;
|
||||
// for regular bookings the first child is free.
|
||||
let freeChildUsed = false;
|
||||
const passengersWithFares = passengersData.map(p => {
|
||||
let fareMinor: number;
|
||||
if (p.category === PassengerCategory.ADULT) {
|
||||
fareMinor = fareCalculation.baseFareMinor;
|
||||
} else if (dto.packageId) {
|
||||
fareMinor = Math.round(fareCalculation.baseFareMinor * 0.1);
|
||||
} else {
|
||||
// Child: first child is free, subsequent children pay full fare
|
||||
if (!freeChildUsed) {
|
||||
fareMinor = 0;
|
||||
freeChildUsed = true;
|
||||
} else {
|
||||
fareMinor = fareCalculation.baseFareMinor;
|
||||
}
|
||||
if (!freeChildUsed) { fareMinor = 0; freeChildUsed = true; }
|
||||
else fareMinor = fareCalculation.baseFareMinor;
|
||||
}
|
||||
return { ...p, fareMinor };
|
||||
});
|
||||
@@ -661,34 +668,27 @@ export class BookingsService {
|
||||
displayTotalMinor = await this.currencyService.convertAmount(totalMinor, Currency.ETB, displayCurrency);
|
||||
}
|
||||
|
||||
// Track which child gets free fare for outbound and return legs
|
||||
// Track per-seat fare. For package bookings children pay 10% of adult fare;
|
||||
// for regular bookings the first child is free per leg.
|
||||
let outboundFreeChildUsed = false;
|
||||
let returnFreeChildUsed = false;
|
||||
const passengersWithFares = passengersData.map(p => {
|
||||
let outboundFareMinor: number;
|
||||
let returnFareMinor: number;
|
||||
|
||||
|
||||
if (p.category === PassengerCategory.ADULT) {
|
||||
outboundFareMinor = outboundFare.baseFareMinor;
|
||||
returnFareMinor = returnFare.baseFareMinor;
|
||||
} else if (dto.packageId) {
|
||||
outboundFareMinor = Math.round(outboundFare.baseFareMinor * 0.1);
|
||||
returnFareMinor = Math.round(returnFare.baseFareMinor * 0.1);
|
||||
} else {
|
||||
// Child fare for outbound
|
||||
if (!outboundFreeChildUsed) {
|
||||
outboundFareMinor = 0;
|
||||
outboundFreeChildUsed = true;
|
||||
} else {
|
||||
outboundFareMinor = outboundFare.baseFareMinor;
|
||||
}
|
||||
|
||||
// Child fare for return
|
||||
if (!returnFreeChildUsed) {
|
||||
returnFareMinor = 0;
|
||||
returnFreeChildUsed = true;
|
||||
} else {
|
||||
returnFareMinor = returnFare.baseFareMinor;
|
||||
}
|
||||
if (!outboundFreeChildUsed) { outboundFareMinor = 0; outboundFreeChildUsed = true; }
|
||||
else outboundFareMinor = outboundFare.baseFareMinor;
|
||||
if (!returnFreeChildUsed) { returnFareMinor = 0; returnFreeChildUsed = true; }
|
||||
else returnFareMinor = returnFare.baseFareMinor;
|
||||
}
|
||||
|
||||
|
||||
return { ...p, outboundFareMinor, returnFareMinor };
|
||||
});
|
||||
|
||||
@@ -1231,16 +1231,20 @@ export class BookingsService {
|
||||
childCount: number,
|
||||
) {
|
||||
const tier = await this.prisma.packagePriceTier.findUniqueOrThrow({ where: { id: priceTierId } });
|
||||
const passengerCount = adultCount + childCount;
|
||||
const totalBaseFareMinor = tier.priceMinor * passengerCount;
|
||||
// For round-trip packages the caller splits the tier price across legs, so
|
||||
// priceMinor here is already the per-leg amount. Children pay 10% of adult fare.
|
||||
const childFareMinor = Math.round(tier.priceMinor * 0.1);
|
||||
const adultFareMinor = tier.priceMinor * adultCount;
|
||||
const childTotalMinor = childFareMinor * childCount;
|
||||
const totalBaseFareMinor = adultFareMinor + childTotalMinor;
|
||||
return {
|
||||
baseFareMinor: tier.priceMinor,
|
||||
adultCount,
|
||||
adultFareMinor: tier.priceMinor * adultCount,
|
||||
adultFareMinor,
|
||||
childCount,
|
||||
freeChildrenCount: 0,
|
||||
paidChildrenCount: childCount,
|
||||
childFareMinor: tier.priceMinor * childCount,
|
||||
childFareMinor: childTotalMinor,
|
||||
totalBaseFareMinor,
|
||||
discountMinor: 0,
|
||||
loyaltyRedemptionMinor: 0,
|
||||
|
||||
Reference in New Issue
Block a user