mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-30 08:48:11 +00:00
Build issues resolution
This commit is contained in:
@@ -64,7 +64,6 @@ import { TasksModule } from './modules/tasks/tasks.module';
|
|||||||
import { AppReleasesModule } from './modules/app-releases/app-releases.module';
|
import { AppReleasesModule } from './modules/app-releases/app-releases.module';
|
||||||
import { ConfigurableFareModule } from './modules/configurable-fare/configurable-fare.module';
|
import { ConfigurableFareModule } from './modules/configurable-fare/configurable-fare.module';
|
||||||
import { SegmentFareSeeder } from './seed/segment-fare.seeder';
|
import { SegmentFareSeeder } from './seed/segment-fare.seeder';
|
||||||
import { EOtpType } from "@tria-plc/iamapi-common";
|
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -98,16 +97,6 @@ import { EOtpType } from "@tria-plc/iamapi-common";
|
|||||||
TriaIamModule.forRoot({
|
TriaIamModule.forRoot({
|
||||||
applications: [EDR_PASSENGER_APPLICATION],
|
applications: [EDR_PASSENGER_APPLICATION],
|
||||||
permissions: EDR_PASSENGER_PERMISSIONS,
|
permissions: EDR_PASSENGER_PERMISSIONS,
|
||||||
otpMessages: {
|
|
||||||
[EOtpType.MFA_LOGIN]: ({ otp }) =>
|
|
||||||
`Your EDR Passenger login code is ${otp}. It will expire in 5 minutes.`,
|
|
||||||
[EOtpType.VERIFY_PHONE_NUMBER]: ({ otp }) =>
|
|
||||||
`Your EDR Passenger phone verification code is ${otp}. It will expire in 5 minutes.`,
|
|
||||||
[EOtpType.RESET_PASSWORD]: ({ route }) =>
|
|
||||||
`Reset your EDR Passenger password using this link: ${route}`,
|
|
||||||
[EOtpType.SET_PASSWORD]: ({ route }) =>
|
|
||||||
`Set your EDR Passenger password using this link: ${route}`,
|
|
||||||
},
|
|
||||||
}),
|
}),
|
||||||
SharedAuthModule,
|
SharedAuthModule,
|
||||||
PrismaModule,
|
PrismaModule,
|
||||||
|
|||||||
@@ -75,7 +75,6 @@ export class PackagesService {
|
|||||||
const maxChildren = adultCount * PKG_CHILDREN_PER_ADULT;
|
const maxChildren = adultCount * PKG_CHILDREN_PER_ADULT;
|
||||||
if (childCount > maxChildren) throw new BadRequestException(`Maximum ${PKG_CHILDREN_PER_ADULT} children per adult (${maxChildren} for ${adultCount} adult${adultCount !== 1 ? 's' : ''}) allowed per package booking`);
|
if (childCount > maxChildren) throw new BadRequestException(`Maximum ${PKG_CHILDREN_PER_ADULT} children per adult (${maxChildren} for ${adultCount} adult${adultCount !== 1 ? 's' : ''}) allowed per package booking`);
|
||||||
|
|
||||||
const remaining = tier.availableSeats - tier.bookedSeats;
|
|
||||||
const isRoundTrip = !!pkg.returnScheduleId;
|
const isRoundTrip = !!pkg.returnScheduleId;
|
||||||
const { adultFareMinor, freeChildren, paidChildren, totalMinor } = calculatePackageFareBreakdown(
|
const { adultFareMinor, freeChildren, paidChildren, totalMinor } = calculatePackageFareBreakdown(
|
||||||
tier.priceMinor, isRoundTrip, adultCount, childCount,
|
tier.priceMinor, isRoundTrip, adultCount, childCount,
|
||||||
@@ -84,6 +83,10 @@ export class PackagesService {
|
|||||||
// Only adults and paid children need seats; free children travel without a seat
|
// Only adults and paid children need seats; free children travel without a seat
|
||||||
const seatsNeeded = adultCount + paidChildren;
|
const seatsNeeded = adultCount + paidChildren;
|
||||||
const passengerCount = adultCount + childCount;
|
const passengerCount = adultCount + childCount;
|
||||||
|
// Re-fetch tier from DB to get accurate live counts
|
||||||
|
const liveTier = await this.prisma.packagePriceTier.findUnique({ where: { id: tierId } });
|
||||||
|
if (!liveTier) throw new NotFoundException('Price tier not found');
|
||||||
|
const remaining = liveTier.availableSeats - liveTier.bookedSeats;
|
||||||
if (seatsNeeded > remaining)
|
if (seatsNeeded > remaining)
|
||||||
throw new BadRequestException(`Only ${remaining} seat(s) remaining in the ${tier.label} tier`);
|
throw new BadRequestException(`Only ${remaining} seat(s) remaining in the ${tier.label} tier`);
|
||||||
|
|
||||||
@@ -392,25 +395,29 @@ export class PackagesService {
|
|||||||
if (childCount > maxChildrenBook) throw new BadRequestException(`Maximum ${PKG_CHILDREN_PER_ADULT} children per adult (${maxChildrenBook} for ${adultCount} adult${adultCount !== 1 ? 's' : ''}) allowed per package booking`);
|
if (childCount > maxChildrenBook) throw new BadRequestException(`Maximum ${PKG_CHILDREN_PER_ADULT} children per adult (${maxChildrenBook} for ${adultCount} adult${adultCount !== 1 ? 's' : ''}) allowed per package booking`);
|
||||||
|
|
||||||
const passengerCount = adultCount + childCount;
|
const passengerCount = adultCount + childCount;
|
||||||
const remaining = tier.availableSeats - tier.bookedSeats;
|
|
||||||
|
|
||||||
const isRoundTrip = !!pkg.returnScheduleId;
|
const isRoundTrip = !!pkg.returnScheduleId;
|
||||||
const { adultFareMinor, freeChildren, paidChildren, totalMinor } = calculatePackageFareBreakdown(
|
const { adultFareMinor, freeChildren, paidChildren, totalMinor } = calculatePackageFareBreakdown(
|
||||||
tier.priceMinor, isRoundTrip, adultCount, childCount,
|
tier.priceMinor, isRoundTrip, adultCount, childCount,
|
||||||
);
|
);
|
||||||
// Only adults and paid children need seats; free children travel without a seat
|
// Only adults and paid children need seats; free children travel without a seat
|
||||||
const seatsNeeded = adultCount + paidChildren;
|
const seatsNeeded = adultCount + paidChildren;
|
||||||
if (seatsNeeded > remaining) {
|
|
||||||
throw new BadRequestException(`Only ${remaining} seats remaining in the ${tier.label} tier`);
|
|
||||||
}
|
|
||||||
const displayCurrency = (dto.displayCurrency as Currency) ?? Currency.ETB;
|
const displayCurrency = (dto.displayCurrency as Currency) ?? Currency.ETB;
|
||||||
const displayTotalMinor =
|
const displayTotalMinor =
|
||||||
displayCurrency !== Currency.ETB
|
displayCurrency !== Currency.ETB
|
||||||
? await this.currencyService.convertAmount(totalMinor, Currency.ETB, displayCurrency)
|
? await this.currencyService.convertAmount(totalMinor, Currency.ETB, displayCurrency)
|
||||||
: totalMinor;
|
: totalMinor;
|
||||||
|
|
||||||
const [booking] = await this.prisma.$transaction([
|
const [booking] = await this.prisma.$transaction(async (tx) => {
|
||||||
this.prisma.packageBooking.create({
|
// Re-fetch tier inside transaction for race-condition-safe availability check
|
||||||
|
const freshTier = await tx.packagePriceTier.findUnique({ where: { id: dto.priceTierId } });
|
||||||
|
if (!freshTier) throw new NotFoundException('Price tier not found');
|
||||||
|
const remaining = freshTier.availableSeats - freshTier.bookedSeats;
|
||||||
|
if (seatsNeeded > remaining) {
|
||||||
|
throw new BadRequestException(`Only ${remaining} seats remaining in the ${tier.label} tier`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.all([
|
||||||
|
tx.packageBooking.create({
|
||||||
data: {
|
data: {
|
||||||
bookingRef: generateRef(),
|
bookingRef: generateRef(),
|
||||||
packageId: dto.packageId,
|
packageId: dto.packageId,
|
||||||
@@ -448,12 +455,16 @@ export class PackagesService {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
this.prisma.packagePriceTier.update({
|
tx.packagePriceTier.update({
|
||||||
where: { id: dto.priceTierId },
|
where: { id: dto.priceTierId },
|
||||||
data: { bookedSeats: { increment: seatsNeeded } },
|
data: {
|
||||||
}),
|
bookedSeats: { increment: seatsNeeded },
|
||||||
]);
|
availableSeats: { decrement: seatsNeeded },
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...booking,
|
...booking,
|
||||||
|
|||||||
Reference in New Issue
Block a user