remove hotel schedule

This commit is contained in:
ItsMalma
2025-11-30 10:12:56 +07:00
parent c07d09c4e9
commit 66c8d9681a
6 changed files with 58 additions and 188 deletions

View File

@@ -1,36 +0,0 @@
import { Hotel } from "@/database/entities/hotel.entity";
import {
Entity,
ManyToOne,
PrimaryKey,
Property,
type Rel,
} from "@mikro-orm/core";
@Entity()
export class HotelSchedule {
@PrimaryKey({ type: "varchar", length: 30 })
id!: string;
@ManyToOne(() => Hotel)
hotel!: Rel<Hotel>;
@Property({ type: "time" })
checkIn!: string;
@Property({ type: "time" })
checkOut!: string;
@Property({
type: "timestamp",
onCreate: () => new Date(),
})
createdAt!: Date;
@Property({
type: "timestamp",
onCreate: () => new Date(),
onUpdate: () => new Date(),
})
updatedAt!: Date;
}

View File

@@ -1,5 +1,5 @@
import { FlightSchedule } from "@/database/entities/flight-schedule.entity";
import { HotelSchedule } from "@/database/entities/hotel-schedule.entity";
import { Hotel } from "@/database/entities/hotel.entity";
import { PackageItinerary } from "@/database/entities/package-itinerary.entity";
import { Package } from "@/database/entities/package.entity";
import { TransportationClass } from "@/database/entities/transportation-class.entity";
@@ -43,21 +43,21 @@ export class PackageDetail {
})
inboundFlight!: Rel<FlightSchedule>;
@ManyToMany(() => HotelSchedule, undefined, {
@ManyToMany(() => Hotel, undefined, {
owner: true,
cascade: [Cascade.REMOVE],
})
tourHotels = new Collection<HotelSchedule>(this);
tourHotels = new Collection<Hotel>(this);
@ManyToOne(() => HotelSchedule, {
@ManyToOne(() => Hotel, {
cascade: [Cascade.REMOVE],
})
makkahHotel!: Rel<HotelSchedule>;
makkahHotel!: Rel<Hotel>;
@ManyToOne(() => HotelSchedule, {
@ManyToOne(() => Hotel, {
cascade: [Cascade.REMOVE],
})
madinahHotel!: Rel<HotelSchedule>;
madinahHotel!: Rel<Hotel>;
@ManyToOne(() => TransportationClass)
transportation!: Rel<TransportationClass>;

View File

@@ -11,7 +11,6 @@ import type {
} from "@/common/types";
import { FlightClass } from "@/database/entities/flight-class.entity";
import { FlightSchedule } from "@/database/entities/flight-schedule.entity";
import { HotelSchedule } from "@/database/entities/hotel-schedule.entity";
import { Hotel } from "@/database/entities/hotel.entity";
import { PackageDetail } from "@/database/entities/package-detail.entity";
import { PackageItineraryDay } from "@/database/entities/package-itinerary-day.entity";
@@ -382,7 +381,7 @@ export class PackageController extends Controller {
const makkahHotel = await orm.em.findOne(
Hotel,
{
id: body.makkah_hotel.hotel_id,
id: body.makkah_hotel_id,
},
{
populate: ["*"],
@@ -393,26 +392,18 @@ export class PackageController extends Controller {
data: null,
errors: [
{
path: "makkah_hotel.hotel_id",
path: "makkah_hotel_id",
location: "body",
message: "Hotel not found.",
},
],
});
}
const makkahHotelSchedule = orm.em.create(HotelSchedule, {
id: ulid(),
hotel: makkahHotel,
checkIn: `${body.makkah_hotel.check_in.getHours()}:${body.makkah_hotel.check_in.getMinutes()}:00`,
checkOut: `${body.makkah_hotel.check_out.getHours()}:${body.makkah_hotel.check_out.getMinutes()}:00`,
createdAt: new Date(),
updatedAt: new Date(),
});
const madinahHotel = await orm.em.findOne(
Hotel,
{
id: body.madinah_hotel.hotel_id,
id: body.madinah_hotel_id,
},
{
populate: ["*"],
@@ -423,21 +414,13 @@ export class PackageController extends Controller {
data: null,
errors: [
{
path: "madinah_hotel.hotel_id",
path: "madinah_hotel_id",
location: "body",
message: "Hotel not found.",
},
],
});
}
const madinahHotelSchedule = orm.em.create(HotelSchedule, {
id: ulid(),
hotel: madinahHotel,
checkIn: `${body.madinah_hotel.check_in.getHours()}:${body.madinah_hotel.check_in.getMinutes()}:00`,
checkOut: `${body.madinah_hotel.check_out.getHours()}:${body.madinah_hotel.check_out.getMinutes()}:00`,
createdAt: new Date(),
updatedAt: new Date(),
});
const transportationClass = await orm.em.findOne(
TransportationClass,
@@ -604,8 +587,8 @@ export class PackageController extends Controller {
tourFlight: tourFlightSchedule,
outboundFlight: outboundFlightSchedule,
inboundFlight: inboundFlightSchedule,
makkahHotel: makkahHotelSchedule,
madinahHotel: madinahHotelSchedule,
makkahHotel: makkahHotel,
madinahHotel: madinahHotel,
transportation: transportationClass,
quadPrice: body.quad_price,
triplePrice: body.triple_price,
@@ -616,22 +599,22 @@ export class PackageController extends Controller {
updatedAt: new Date(),
});
for (const [index, tourHotel] of (body.tour_hotels ?? []).entries()) {
const tourHotelEntity = await orm.em.findOne(
for (const [index, tourHotelId] of (body.tour_hotel_ids ?? []).entries()) {
const tourHotel = await orm.em.findOne(
Hotel,
{
id: tourHotel.hotel_id,
id: tourHotelId,
},
{
populate: ["*"],
},
);
if (!tourHotelEntity) {
if (!tourHotel) {
return res.status(404).json({
data: null,
errors: [
{
path: `tour_hotels.${index}.hotel_id`,
path: `tour_hotel_ids.${index}`,
location: "body",
message: "Hotel not found.",
},
@@ -639,16 +622,7 @@ export class PackageController extends Controller {
});
}
const tourHotelSchedule = orm.em.create(HotelSchedule, {
id: ulid(),
hotel: tourHotelEntity,
checkIn: `${tourHotel.check_in.getHours()}:${tourHotel.check_in.getMinutes()}:00`,
checkOut: `${tourHotel.check_out.getHours()}:${tourHotel.check_out.getMinutes()}:00`,
createdAt: new Date(),
updatedAt: new Date(),
});
packageDetail.tourHotels.add(tourHotelSchedule);
packageDetail.tourHotels.add(tourHotel);
}
await orm.em.flush();
@@ -964,11 +938,10 @@ export class PackageController extends Controller {
});
}
orm.em.remove(packageDetail.makkahHotel);
const makkahHotel = await orm.em.findOne(
Hotel,
{
id: body.makkah_hotel.hotel_id,
id: body.makkah_hotel_id,
},
{
populate: ["*"],
@@ -979,27 +952,18 @@ export class PackageController extends Controller {
data: null,
errors: [
{
path: "makkah_hotel.hotel_id",
path: "makkah_hotel_id",
location: "body",
message: "Hotel not found.",
},
],
});
}
const makkahHotelSchedule = orm.em.create(HotelSchedule, {
id: ulid(),
hotel: makkahHotel,
checkIn: `${body.makkah_hotel.check_in.getHours()}:${body.makkah_hotel.check_in.getMinutes()}:00`,
checkOut: `${body.makkah_hotel.check_out.getHours()}:${body.makkah_hotel.check_out.getMinutes()}:00`,
createdAt: new Date(),
updatedAt: new Date(),
});
orm.em.remove(packageDetail.madinahHotel);
const madinahHotel = await orm.em.findOne(
Hotel,
{
id: body.madinah_hotel.hotel_id,
id: body.madinah_hotel_id,
},
{
populate: ["*"],
@@ -1010,21 +974,13 @@ export class PackageController extends Controller {
data: null,
errors: [
{
path: "madinah_hotel.hotel_id",
path: "madinah_hotel_id",
location: "body",
message: "Hotel not found.",
},
],
});
}
const madinahHotelSchedule = orm.em.create(HotelSchedule, {
id: ulid(),
hotel: madinahHotel,
checkIn: `${body.madinah_hotel.check_in.getHours()}:${body.madinah_hotel.check_in.getMinutes()}:00`,
checkOut: `${body.madinah_hotel.check_out.getHours()}:${body.madinah_hotel.check_out.getMinutes()}:00`,
createdAt: new Date(),
updatedAt: new Date(),
});
const transportationClass = await orm.em.findOne(
TransportationClass,
@@ -1214,8 +1170,8 @@ export class PackageController extends Controller {
tourFlight: tourFlightSchedule,
outboundFlight: outboundFlightSchedule,
inboundFlight: inboundFlightSchedule,
makkahHotel: makkahHotelSchedule,
madinahHotel: madinahHotelSchedule,
makkahHotel: makkahHotel,
madinahHotel: madinahHotel,
transportation: transportationClass,
quadPrice: body.quad_price,
triplePrice: body.triple_price,
@@ -1225,25 +1181,23 @@ export class PackageController extends Controller {
updatedAt: new Date(),
});
for (const tourHotel of packageDetail.tourHotels) {
orm.em.remove(tourHotel);
}
for (const [index, tourHotel] of (body.tour_hotels ?? []).entries()) {
const tourHotelEntity = await orm.em.findOne(
packageDetail.tourHotels.set([]);
for (const [index, tourHotelId] of (body.tour_hotel_ids ?? []).entries()) {
const tourHotel = await orm.em.findOne(
Hotel,
{
id: tourHotel.hotel_id,
id: tourHotelId,
},
{
populate: ["*"],
},
);
if (!tourHotelEntity) {
if (!tourHotel) {
return res.status(404).json({
data: null,
errors: [
{
path: `tour_hotels.${index}.hotel_id`,
path: `tour_hotel_ids.${index}`,
location: "body",
message: "Hotel not found.",
},
@@ -1251,16 +1205,7 @@ export class PackageController extends Controller {
});
}
const tourHotelSchedule = orm.em.create(HotelSchedule, {
id: ulid(),
hotel: tourHotelEntity,
checkIn: `${tourHotel.check_in.getHours()}:${tourHotel.check_in.getMinutes()}:00`,
checkOut: `${tourHotel.check_out.getHours()}:${tourHotel.check_out.getMinutes()}:00`,
createdAt: new Date(),
updatedAt: new Date(),
});
packageDetail.tourHotels.add(tourHotelSchedule);
packageDetail.tourHotels.add(tourHotel);
}
await orm.em.flush();

View File

@@ -1,5 +1,4 @@
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 {
@@ -16,7 +15,6 @@ import type { FlightClassResponse } from "@/modules/flight/flight.types";
import type { HotelMapper } from "@/modules/hotel/hotel.mapper";
import type {
PackageDetailResponse,
PackageHotelResponse,
PackageItineraryDayResponse,
PackageItineraryResponse,
PackageItineraryWidgetResponse,
@@ -63,22 +61,6 @@ export class PackageMapper {
return flightClassResponses;
}
private mapHotelSchedule(hotelSchedule: HotelSchedule): PackageHotelResponse {
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 {
@@ -174,9 +156,15 @@ export class PackageMapper {
: 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),
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,
),

View File

@@ -1,4 +1,4 @@
import { dateSchema, timeSchema } from "@/common/schemas";
import { dateSchema } from "@/common/schemas";
import { PackageClass } from "@/database/enums/package-class.enum";
import { PackageType } from "@/database/enums/package-type.enum";
import z from "zod";
@@ -47,45 +47,24 @@ export const packageDetailRequestSchema = z.object({
"Must be array.",
)
.nonempty("Must not empty."),
tour_hotels: z
tour_hotel_ids: z
.array(
z.object(
{
hotel_id: z
z
.ulid("Must be ulid string.")
.nonempty("Must not empty.")
.max(30, "Max 30 characters."),
check_in: timeSchema,
check_out: timeSchema,
},
"Must be object.",
),
"Must be array.",
)
.nonempty("Must not empty.")
.nullable(),
makkah_hotel: z.object(
{
hotel_id: z
makkah_hotel_id: z
.ulid("Must be ulid string.")
.nonempty("Must not empty.")
.max(30, "Max 30 characters."),
check_in: timeSchema,
check_out: timeSchema,
},
"Must be object.",
),
madinah_hotel: z.object(
{
hotel_id: z
madinah_hotel_id: z
.ulid("Must be ulid string.")
.nonempty("Must not empty.")
.max(30, "Max 30 characters."),
check_in: timeSchema,
check_out: timeSchema,
},
"Must be object.",
),
transportation_id: z
.ulid("Must be ulid string.")
.nonempty("Must not empty.")

View File

@@ -30,12 +30,6 @@ export type PackageResponse = {
updated_at: Date;
};
export type PackageHotelResponse = {
hotel: HotelResponse;
check_in: string;
check_out: string;
};
export type PackageItineraryWidgetResponse =
| {
type: "transport";
@@ -72,9 +66,9 @@ export type PackageDetailResponse = {
tour_flights: FlightClassResponse[] | null;
outbound_flights: FlightClassResponse[];
inbound_flights: FlightClassResponse[];
tour_hotels: PackageHotelResponse[] | null;
makkah_hotel: PackageHotelResponse;
madinah_hotel: PackageHotelResponse;
tour_hotels: HotelResponse[] | null;
makkah_hotel: HotelResponse;
madinah_hotel: HotelResponse;
transportation: TransportationClassResponse;
quad_price: number;
triple_price: number;