stashing code

This commit is contained in:
user
2025-10-20 17:07:41 +03:00
commit f5b99afc8f
890 changed files with 54823 additions and 0 deletions

View File

@@ -0,0 +1,179 @@
import { AirportsRepository } from "$lib/domains/airport/data/repository";
import type {
FlightPriceDetails,
FlightTicket,
TicketSearchPayload,
} from "../data/entities";
import { TicketRepository } from "../data/repository";
import { getError, Logger } from "@pkg/logger";
import { env } from "$env/dynamic/private";
import { ScrapedTicketsDataSource } from "../data/scrape.data.source";
import { db } from "@pkg/db";
import { airportsDb } from "@pkg/airports-db";
import { ERROR_CODES, type Result } from "@pkg/result";
import { DiscountType, type CouponModel } from "@pkg/logic/domains/coupon/data";
import { convertAndFormatCurrency } from "$lib/domains/currency/view/currency.vm.svelte";
import { AmadeusTicketsAPIDataSource } from "../data/amadeusapi.data.source";
import { getRedisInstance } from "$lib/server/redis";
export class TicketController {
private repo: TicketRepository;
private airportsRepo: AirportsRepository;
private TICKET_SCRAPERS = ["kiwi"];
constructor(repo: TicketRepository, airportsRepo: AirportsRepository) {
this.repo = repo;
this.airportsRepo = airportsRepo;
}
async searchAirports(query: string) {
return this.airportsRepo.searchAirports(query);
}
async getAirportByCode(query: string) {
return this.airportsRepo.getAirportByCode(query);
}
async searchForTickets(
payload: TicketSearchPayload,
coupon: CouponModel | undefined,
): Promise<Result<FlightTicket[]>> {
const result = await this.repo.searchForTickets({
sessionId: payload.sessionId,
ticketSearchPayload: payload,
providers: this.TICKET_SCRAPERS,
});
if (result.error || !result.data) {
return result;
}
if (!coupon) {
return result;
}
Logger.info(`Auto-applying coupon ${coupon.code} to all search results`);
return {
data: result.data.map((ticket) => {
return this.applyDiscountToTicket(ticket, coupon);
}),
};
}
private applyDiscountToTicket(
ticket: FlightTicket,
coupon: CouponModel,
): FlightTicket {
// Calculate discount amount
let discountAmount = 0;
if (coupon.discountType === DiscountType.PERCENTAGE) {
discountAmount =
(ticket.priceDetails.displayPrice *
Number(coupon.discountValue)) /
100;
} else {
discountAmount = Number(coupon.discountValue);
}
// Apply maximum discount limit if specified
if (
coupon.maxDiscountAmount &&
discountAmount > Number(coupon.maxDiscountAmount)
) {
discountAmount = Number(coupon.maxDiscountAmount);
}
// Skip if minimum order value is not met
if (
coupon.minOrderValue &&
ticket.priceDetails.displayPrice < Number(coupon.minOrderValue)
) {
return ticket;
}
// Create a copy of the ticket with the discount applied
const discountedTicket = { ...ticket };
discountedTicket.priceDetails = {
...ticket.priceDetails,
discountAmount:
(ticket.priceDetails.discountAmount || 0) + discountAmount,
displayPrice: ticket.priceDetails.displayPrice - discountAmount,
appliedCoupon: coupon.code,
couponDescription:
coupon.description ||
`Coupon discount of ${coupon.discountType === DiscountType.PERCENTAGE ? coupon.discountValue + "%" : convertAndFormatCurrency(parseFloat(coupon.discountValue.toString()))}`,
};
return discountedTicket;
}
async cacheTicket(sid: string, payload: FlightTicket) {
Logger.info(
`Caching ticket for ${sid} | ${payload.departure}:${payload.arrival}`,
);
const refOIds = payload.refOIds;
if (!refOIds) {
// In this case we're not going for any of our fancy checkout jazz
return this.repo.createTicket(payload, true);
}
const areAnyLive =
await this.repo.areCheckoutAlreadyLiveForOrder(refOIds);
Logger.info(`Any of the OIds has checkout session live ?? ${areAnyLive}`);
if (areAnyLive) {
return {
error: getError({
code: ERROR_CODES.INTERNAL_SERVER_ERROR,
message: "This ticket offer has expired",
userHint:
"Please select another one or perform search again to fetch latest offers",
actionable: false,
detail: "Failed to ticket",
}),
};
}
Logger.info("nu'uh seems greenlight to make a ticket");
return this.repo.createTicket(payload, true);
}
async updateTicketPrices(tid: number, payload: FlightPriceDetails) {
return this.repo.updateTicketPrices(tid, payload);
}
async uncacheAndSaveTicket(tid: number) {
return this.repo.uncacheAndSaveTicket(tid);
}
async getCheckoutUrlByRefOId(id: number) {
return this.repo.getCheckoutUrlByRefOId(id);
}
async setRefOIdsForTicket(tid: number, oids: number[]) {
return this.repo.setRefOIdsForTicket(tid, oids);
}
async getTicketById(id: number) {
return this.repo.getTicketById(id);
}
}
export function getTC() {
const ds = new ScrapedTicketsDataSource(
env.TICKET_SCRAPER_API_URL,
env.API_KEY,
);
const amadeusApi = new AmadeusTicketsAPIDataSource(
env.AMADEUS_API_BASE_URL,
env.AMADEUS_API_KEY,
env.AMADEUS_API_SECRET,
getRedisInstance(),
);
return new TicketController(
new TicketRepository(db, ds, amadeusApi),
new AirportsRepository(airportsDb),
);
}