185 lines
5.8 KiB
TypeScript
185 lines
5.8 KiB
TypeScript
import type { FlightSchedule } from "@/database/entities/flight-schedule.entity";
|
|
import type { PackageDetail } from "@/database/entities/package-detail.entity";
|
|
import type { PackageItineraryDay } from "@/database/entities/package-itinerary-day.entity";
|
|
import type {
|
|
PackageItineraryWidget,
|
|
PackageItineraryWidgetHotel,
|
|
PackageItineraryWidgetInformation,
|
|
PackageItineraryWidgetTransport,
|
|
} from "@/database/entities/package-itinerary-widget.entity";
|
|
import type { PackageItinerary } from "@/database/entities/package-itinerary.entity";
|
|
import type { Package } from "@/database/entities/package.entity";
|
|
import { PackageItineraryWidgetType } from "@/database/enums/package-itinerary-widget-type.enum";
|
|
import type { FlightMapper } from "@/modules/flight/flight.mapper";
|
|
import type { FlightClassResponse } from "@/modules/flight/flight.types";
|
|
import type { HotelMapper } from "@/modules/hotel/hotel.mapper";
|
|
import type {
|
|
PackageDetailResponse,
|
|
PackageItineraryDayResponse,
|
|
PackageItineraryResponse,
|
|
PackageItineraryWidgetResponse,
|
|
PackageResponse,
|
|
} from "@/modules/package/package.types";
|
|
import type { PartnerMapper } from "@/modules/partner/partner.mapper";
|
|
import type { TransportationMapper } from "@/modules/transportation/transportation.mapper";
|
|
import * as dateFns from "date-fns";
|
|
|
|
export class PackageMapper {
|
|
public constructor(
|
|
private readonly partnerMapper: PartnerMapper,
|
|
private readonly flightMapper: FlightMapper,
|
|
private readonly hotelMapper: HotelMapper,
|
|
private readonly transportationMapper: TransportationMapper,
|
|
) {}
|
|
|
|
public mapEntityToResponse(package_: Package): PackageResponse {
|
|
return {
|
|
id: package_.id,
|
|
slug: package_.slug,
|
|
name: package_.name,
|
|
type: package_.type,
|
|
class: package_.class,
|
|
thumbnail: package_.thumbnail,
|
|
use_fast_train: package_.useFastTrain,
|
|
partner: this.partnerMapper.mapEntityToResponse(package_.partner),
|
|
created_at: package_.createdAt,
|
|
updated_at: package_.updatedAt,
|
|
};
|
|
}
|
|
|
|
private mapFlightSchedule(
|
|
flightSchedule: FlightSchedule,
|
|
): FlightClassResponse[] {
|
|
const flightClassResponses: FlightClassResponse[] = [];
|
|
|
|
let currentFlightSchedule: FlightSchedule | null = flightSchedule;
|
|
while (currentFlightSchedule !== null) {
|
|
flightClassResponses.push(
|
|
this.flightMapper.mapClassEntityToResponse(
|
|
currentFlightSchedule.flight,
|
|
),
|
|
);
|
|
currentFlightSchedule = currentFlightSchedule.next;
|
|
}
|
|
|
|
return flightClassResponses;
|
|
}
|
|
|
|
private mapItineraryWidget(
|
|
packageItineraryWidget: PackageItineraryWidget,
|
|
): PackageItineraryWidgetResponse {
|
|
switch (packageItineraryWidget.type) {
|
|
case PackageItineraryWidgetType.transport:
|
|
const transportWidget =
|
|
packageItineraryWidget as PackageItineraryWidgetTransport;
|
|
|
|
return {
|
|
type: "transport",
|
|
transportation: transportWidget.transportation,
|
|
from: transportWidget.from,
|
|
to: transportWidget.to,
|
|
};
|
|
case PackageItineraryWidgetType.hotel:
|
|
const hotelWidget =
|
|
packageItineraryWidget as PackageItineraryWidgetHotel;
|
|
|
|
return {
|
|
type: "hotel",
|
|
hotel: this.hotelMapper.mapEntityToResponse(hotelWidget.hotel),
|
|
};
|
|
case PackageItineraryWidgetType.information:
|
|
const informationWidget =
|
|
packageItineraryWidget as PackageItineraryWidgetInformation;
|
|
|
|
return {
|
|
type: "information",
|
|
description: informationWidget.description,
|
|
};
|
|
}
|
|
}
|
|
|
|
private mapItineraryDay(
|
|
packageItineraryDay: PackageItineraryDay,
|
|
nth: number,
|
|
): PackageItineraryDayResponse {
|
|
return {
|
|
nth,
|
|
title: packageItineraryDay.title,
|
|
description: packageItineraryDay.description,
|
|
widgets: packageItineraryDay.widgets
|
|
.getItems()
|
|
.map((widget) => this.mapItineraryWidget(widget)),
|
|
};
|
|
}
|
|
|
|
private mapItinerary(
|
|
packageItinerary: PackageItinerary,
|
|
nthDay: number = 1,
|
|
): PackageItineraryResponse {
|
|
const days: PackageItineraryDayResponse[] = [];
|
|
for (
|
|
let currentItineraryDay: PackageItineraryDay | null =
|
|
packageItinerary.day,
|
|
index = 0;
|
|
currentItineraryDay !== null;
|
|
currentItineraryDay = currentItineraryDay.next, index++
|
|
) {
|
|
days.push(this.mapItineraryDay(currentItineraryDay, nthDay + index));
|
|
}
|
|
|
|
return {
|
|
location: packageItinerary.location,
|
|
images: packageItinerary.images
|
|
.getItems()
|
|
.map((packageItineraryImage) => packageItineraryImage.src),
|
|
days,
|
|
};
|
|
}
|
|
|
|
public mapDetailEntityToResponse(
|
|
packageDetail: PackageDetail,
|
|
): PackageDetailResponse {
|
|
const itineraries: PackageItineraryResponse[] = [];
|
|
for (
|
|
let currentItinerary: PackageItinerary | null = packageDetail.itinerary,
|
|
nthDay = 1;
|
|
currentItinerary !== null;
|
|
currentItinerary = currentItinerary.next
|
|
) {
|
|
const itineraryResponse = this.mapItinerary(currentItinerary, nthDay);
|
|
itineraries.push(itineraryResponse);
|
|
nthDay += itineraryResponse.days.length;
|
|
}
|
|
|
|
return {
|
|
id: packageDetail.id,
|
|
package: this.mapEntityToResponse(packageDetail.package),
|
|
departure_date: dateFns.format(packageDetail.departureDate, "yyyy-MM-dd"),
|
|
tour_flights: packageDetail.tourFlight
|
|
? this.mapFlightSchedule(packageDetail.tourFlight)
|
|
: null,
|
|
outbound_flights: this.mapFlightSchedule(packageDetail.outboundFlight),
|
|
inbound_flights: this.mapFlightSchedule(packageDetail.inboundFlight),
|
|
tour_hotels: packageDetail.tourHotels.map(
|
|
this.hotelMapper.mapEntityToResponse,
|
|
),
|
|
makkah_hotel: this.hotelMapper.mapEntityToResponse(
|
|
packageDetail.makkahHotel,
|
|
),
|
|
madinah_hotel: this.hotelMapper.mapEntityToResponse(
|
|
packageDetail.madinahHotel,
|
|
),
|
|
transportation: this.transportationMapper.mapClassEntityToResponse(
|
|
packageDetail.transportation,
|
|
),
|
|
quad_price: packageDetail.quadPrice,
|
|
triple_price: packageDetail.triplePrice,
|
|
double_price: packageDetail.doublePrice,
|
|
infant_price: packageDetail.infantPrice,
|
|
itineraries,
|
|
created_at: packageDetail.createdAt,
|
|
updated_at: packageDetail.updatedAt,
|
|
};
|
|
}
|
|
}
|