mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 21:08:12 +00:00
UAT issues resolution
This commit is contained in:
@@ -3,6 +3,9 @@ import { Type } from 'class-transformer';
|
||||
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||
|
||||
export class CreatePriceTierDto {
|
||||
@ApiPropertyOptional({ description: 'SeatClass ID to link this tier to a specific seat class' })
|
||||
@IsOptional() @IsUUID() seatClassId?: string;
|
||||
|
||||
@ApiProperty({ example: 'HSC' })
|
||||
@IsString() seatType: string;
|
||||
|
||||
@@ -31,6 +34,7 @@ export class UpdateInquiryStatusDto {
|
||||
}
|
||||
|
||||
export class UpdatePriceTierDto {
|
||||
@ApiPropertyOptional() @IsOptional() @IsUUID() seatClassId?: string;
|
||||
@ApiPropertyOptional() @IsOptional() @IsString() seatType?: string;
|
||||
@ApiPropertyOptional() @IsOptional() @IsString() label?: string;
|
||||
@ApiPropertyOptional() @IsOptional() @IsInt() @Min(0) priceMinor?: number;
|
||||
|
||||
@@ -8,7 +8,7 @@ import { GuestBookingService } from '../bookings/guest-booking.service';
|
||||
|
||||
/** Package-specific fare rules */
|
||||
const PKG_MAX_ADULTS = 5;
|
||||
const PKG_MAX_CHILDREN = 2;
|
||||
const PKG_CHILDREN_PER_ADULT = 2; // 2 children allowed per adult
|
||||
const PKG_CHILD_FARE_RATIO = 0.1;
|
||||
|
||||
function calculatePackageFareBreakdown(
|
||||
@@ -68,7 +68,8 @@ export class PackagesService {
|
||||
|
||||
if (adultCount < 1) throw new BadRequestException('At least one adult passenger required');
|
||||
if (adultCount > PKG_MAX_ADULTS) throw new BadRequestException(`Maximum ${PKG_MAX_ADULTS} adults allowed per package booking`);
|
||||
if (childCount > PKG_MAX_CHILDREN) throw new BadRequestException(`Maximum ${PKG_MAX_CHILDREN} children allowed per package booking`);
|
||||
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`);
|
||||
|
||||
const passengerCount = adultCount + childCount;
|
||||
const remaining = tier.availableSeats - tier.bookedSeats;
|
||||
@@ -81,14 +82,17 @@ export class PackagesService {
|
||||
);
|
||||
|
||||
// Resolve the seatClassId and coachTypeId that matches this tier's seatType from the outbound schedule coaches
|
||||
let seatClassId: string | null = null;
|
||||
let seatClassId: string | null = tier.seatClassId ?? null;
|
||||
let seatClassName: string | null = null;
|
||||
let coachTypeId: string | null = null;
|
||||
for (const a of pkg.outboundSchedule.coachAssignments) {
|
||||
const sc = a.coach.coachType?.seatClasses?.find(
|
||||
(s: any) => s.name.toLowerCase().includes(tier.seatType.toLowerCase()) ||
|
||||
tier.seatType.toLowerCase().includes(s.name.toLowerCase()),
|
||||
);
|
||||
if (sc) { seatClassId = sc.id; coachTypeId = a.coach.coachTypeId ?? a.coach.coachType?.id ?? null; break; }
|
||||
const sc = seatClassId
|
||||
? a.coach.coachType?.seatClasses?.find((s: any) => s.id === seatClassId)
|
||||
: a.coach.coachType?.seatClasses?.find(
|
||||
(s: any) => s.name.toLowerCase().includes(tier.seatType.toLowerCase()) ||
|
||||
tier.seatType.toLowerCase().includes(s.name.toLowerCase()),
|
||||
);
|
||||
if (sc) { seatClassId = sc.id; seatClassName = sc.name; coachTypeId = a.coach.coachTypeId ?? a.coach.coachType?.id ?? null; break; }
|
||||
}
|
||||
if (!coachTypeId && pkg.outboundSchedule.coachAssignments.length > 0) {
|
||||
const first = pkg.outboundSchedule.coachAssignments[0];
|
||||
@@ -102,6 +106,7 @@ export class PackagesService {
|
||||
tierLabel: tier.label,
|
||||
seatType: tier.seatType,
|
||||
seatClassId,
|
||||
seatClassName,
|
||||
coachTypeId,
|
||||
adultCount,
|
||||
childCount,
|
||||
@@ -111,7 +116,7 @@ export class PackagesService {
|
||||
pricePerChildMinor: childFareMinor,
|
||||
childFareNote: `Children pay ${PKG_CHILD_FARE_RATIO * 100}% of adult fare`,
|
||||
maxAdults: PKG_MAX_ADULTS,
|
||||
maxChildren: PKG_MAX_CHILDREN,
|
||||
maxChildren: adultCount * PKG_CHILDREN_PER_ADULT,
|
||||
totalMinor,
|
||||
currency: tier.currency,
|
||||
remainingSeats: remaining,
|
||||
@@ -203,7 +208,7 @@ export class PackagesService {
|
||||
const pkg = await this.prisma.travelPackage.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
priceTiers: true,
|
||||
priceTiers: { include: { seatClass: { include: { coachType: true } } } },
|
||||
outboundSchedule: {
|
||||
include: {
|
||||
originStation: true,
|
||||
@@ -369,7 +374,8 @@ export class PackagesService {
|
||||
|
||||
if (adultCount < 1) throw new BadRequestException('At least one adult passenger required');
|
||||
if (adultCount > PKG_MAX_ADULTS) throw new BadRequestException(`Maximum ${PKG_MAX_ADULTS} adults allowed per package booking`);
|
||||
if (childCount > PKG_MAX_CHILDREN) throw new BadRequestException(`Maximum ${PKG_MAX_CHILDREN} children allowed per package booking`);
|
||||
const maxChildrenBook = adultCount * PKG_CHILDREN_PER_ADULT;
|
||||
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 remaining = tier.availableSeats - tier.bookedSeats;
|
||||
@@ -398,6 +404,8 @@ export class PackagesService {
|
||||
contactPhone: dto.contactPhone,
|
||||
promoCode: dto.promoCode,
|
||||
passengerCount,
|
||||
adultCount,
|
||||
childCount,
|
||||
totalMinor,
|
||||
currency: 'ETB',
|
||||
displayCurrency,
|
||||
|
||||
Reference in New Issue
Block a user