add core api

This commit is contained in:
ItsMalma
2025-11-15 22:28:58 +07:00
parent e6386648be
commit 8f91994f29
78 changed files with 6701 additions and 904 deletions

View File

@@ -0,0 +1,216 @@
import type { FlightSchedule } from "@/database/entities/flight-schedule.entity";
import type { HotelSchedule } from "@/database/entities/hotel-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 { PackageClass } from "@/database/enums/package-class.enum";
import { PackageItineraryWidgetType } from "@/database/enums/package-itinerary-widget-type.enum";
import { PackageType } from "@/database/enums/package-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,
PackageHotelResponse,
PackageItineraryDayResponse,
PackageItineraryResponse,
PackageItineraryWidgetResponse,
PackageRequest,
PackageResponse,
} from "@/modules/package/package.types";
import type { TransportationMapper } from "@/modules/transportation/transportation.mapper";
import * as dateFns from "date-fns";
export class PackageMapper {
public constructor(
private readonly flightMapper: FlightMapper,
private readonly hotelMapper: HotelMapper,
private readonly transportationMapper: TransportationMapper,
) {}
public mapPackageType(packageType: PackageRequest["type"]): PackageType {
switch (packageType) {
case "reguler":
return PackageType.reguler;
case "plus":
return PackageType.plus;
}
}
public mapPackageClass(packageClass: PackageRequest["class"]): PackageClass {
switch (packageClass) {
case "silver":
return PackageClass.silver;
case "gold":
return PackageClass.gold;
case "platinum":
return PackageClass.platinum;
}
}
public mapEntityToResponse(package_: Package): PackageResponse {
return {
id: package_.id,
name: package_.name,
type: package_.type,
class: package_.class,
thumbnail: package_.thumbnail,
use_fast_train: package_.useFastTrain,
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 mapHotelSchedule(hotelSchedule: HotelSchedule): PackageHotelResponse {
console.log(hotelSchedule.checkIn);
const checkIn = dateFns.parse(hotelSchedule.checkIn, "H:mm:ss", new Date());
const checkOut = dateFns.parse(
hotelSchedule.checkOut,
"H:mm:ss",
new Date(),
);
return {
hotel: this.hotelMapper.mapEntityToResponse(hotelSchedule.hotel),
check_in: dateFns.format(checkIn, "HH:mm"),
check_out: dateFns.format(checkOut, "HH:mm"),
};
}
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.mapHotelSchedule),
makkah_hotel: this.mapHotelSchedule(packageDetail.makkahHotel),
madinah_hotel: this.mapHotelSchedule(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,
};
}
}