Files
IRTH-2/server/src/routes/apartments.ts
T
2024-07-26 12:59:11 +05:00

268 lines
6.5 KiB
TypeScript

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;