import { Router } from "express"; import { aparmentsApi, searchCurrentApartmentApi } from "../consts.js"; import { logger } from "../utils/logger.js"; import { IApartment } from "../types/apartment.js"; const router = Router(); async function getAllApartments( page: number, accessToken: string, apartments: IApartment[] ) { const response = await fetch(`${aparmentsApi}&page=${page}&per_page=200`, { headers: { Authorization: accessToken, }, }); const result = await response.json(); if (result?.code && result?.code === "INVALID_TOKEN") { throw new Error("INVALID_TOKEN"); } const updatedApartment = apartments.concat([...result.data]); const isMoreRecords = result.info.more_records; if (!isMoreRecords) { return updatedApartment; } return await getAllApartments(page + 1, accessToken, updatedApartment); } function filterApartments( apartments: IApartment[], roveHome?: string[], apartmentType?: string[], costBetween?: string[], totalAreaBetween?: string[], floorBetween?: string[], views?: string[] ) { const filteredApartments = apartments .filter((apart) => { // Rove home filter if (!roveHome || roveHome.length === 0) { return true; } if (roveHome.some((rove) => rove === apart.Project_Name)) { return true; } return false; }) .filter((apart) => { // Apartment type filter if (!apartmentType || apartmentType.length === 0) { return true; } if (apartmentType.some((rove) => rove === apart.Unit_Type)) { return true; } return false; }) .filter((apart) => { // Cost between filter еще не доступен тк нет цен if (!costBetween || costBetween.length === 0) { return true; } const leftCost = Number(costBetween[0]); const rightCost = Number(costBetween[1]); return true; // if (costBetween.some((rove) => rove === apart.Unit_Type)) { // return true; // } // return false; }) .filter((apart) => { // Total area filter if (!totalAreaBetween || totalAreaBetween.length === 0) { return true; } const leftArea = Number(totalAreaBetween[0]); const rightArea = Number(totalAreaBetween[1]); if ( (leftArea <= apart.Total_Area_Sqft && rightArea >= apart.Total_Area_Sqft) || (leftArea >= apart.Total_Area_Sqft && rightArea <= apart.Total_Area_Sqft) ) { return true; } return false; }) .filter((apart) => { // Views filter if (!views || views.length === 0) { return true; } //view "Canal" "Amenities" // Canal / Amenities // разделение по / с пробелом и без const apartViews = apart.Unit_View.split(" / ").join("/").split("/"); for (let i = 0; i < apartViews.length; i++) { // Удаление Corner- const withoutCorner = apartViews[i].split("-").length > 1 ? apartViews[i].split("-")[1] : apartViews[i]; //удаление View const withoutView = withoutCorner.replace(" View", ""); if (views.some((view) => view === withoutView)) { return true; } } return false; }) .filter((apart) => { // Floor filter if (!floorBetween || floorBetween.length === 0) { return true; } const leftFloor = Number(floorBetween[0]); const rightFloor = Number(floorBetween[1]); if ( (leftFloor <= apart.Floor && rightFloor >= apart.Floor) || (leftFloor >= apart.Floor && rightFloor <= apart.Floor) ) { return true; } return false; }); return filteredApartments; } router.get("/", async (req, res) => { const accessToken = req?.headers?.authorization; const { per_page = 1000, page = 1, rove_home = "", apartment_type = "", cost_between = "", total_area_between = "", floor_between = "", views = "", sort_by = "", } = req.query; try { const roveHomeFilter = (rove_home as string) .split(",") .filter((rove) => rove !== ""); const apartmentTypeFilter = (apartment_type as string) .split(",") .filter((rove) => rove !== ""); const costBetweenFilter = (cost_between as string) .split(",") .filter((cost) => cost !== ""); const totalAreaBetween = (total_area_between as string) .split(",") .filter((area) => area !== ""); const viewsFilter = (views as string) .split(",") .filter((view) => view !== ""); const floorBetweenFilter = (floor_between as string) .split(",") .filter((floor) => floor !== ""); if (!accessToken) return res .status(401) .json({ message: "Отсутсвует access token", code: 401 }); try { const allApartments = await getAllApartments(1, accessToken, []); const filteredApartments = filterApartments( allApartments, roveHomeFilter, apartmentTypeFilter, costBetweenFilter, totalAreaBetween, floorBetweenFilter, viewsFilter ); const sortedApartments = [...filteredApartments].sort((a, b) => { if (sort_by === "asc_price") { return 1; } if (sort_by === "decr_price") { return 1; } if (sort_by === "asc_sqr") { return a.Total_Area_Sqft - b.Total_Area_Sqft; } if (sort_by === "asc_floor") { return a.Floor - b.Floor; } return 1; }); const slicedApartments = sortedApartments.slice( ((page as number) - 1) * (per_page as number), (per_page as number) * (page as number) ); res.status(200).json({ message: "ok", apartments: slicedApartments, code: 200, }); return; } catch (error) { if ( (error as Error).message === "invalid oauth token" || (error as Error).message === "INVALID_TOKEN" ) { console.log("error", error); logger.error(error); return res .status(401) .json({ message: "Неправильный токен или токен устарел", code: 401 }); } console.log("error", error); logger.error(error); return res.status(500).json({ message: "Server Error", code: 500 }); } } catch (error) { logger.error(error); console.log("error", error); } }); const apartmentsRoute = router; export default apartmentsRoute;