const { currentSearchRequest } = require("../helpers/url"); const { AD_CATEGORY, AD_TYPE, ACCESS_ROAD_TYPE } = require("../common/enums"); const { ADVANCED_BOOLEAN_FILTERS, ADVANCED_SEGMENT_SELECT_FILTERS, ADVANCED_RANGE_FILTERS } = require("../common/filterEnums"); const getFilters = async (req, res) => { const searchRequest = await currentSearchRequest(req); if (!searchRequest || !searchRequest.dataValues) { res.render("notFound", { title: " " }); return; } const title = "Filteri za pretraživanje"; const { adType, realEstateType, priceMin, priceMax, sizeMin, sizeMax, gardenSizeMin, gardenSizeMax, numberOfRoomsMin, numberOfRoomsMax, numberOfFloorsMin, numberOfFloorsMax, floorMin, floorMax, includeIncompleteAds, balcony, elevator, newBuilding, accessRoadType } = searchRequest; const category = AD_CATEGORY[realEstateType] || AD_CATEGORY.FLAT; const { hasGardenSize, priceSliderOptionsSale, priceSliderOptionsRent, sizeSliderOptions, gardenSizeSliderOptions } = category; let priceSliderOptions; if (adType === AD_TYPE.AD_TYPE_SALE.stringId) { priceSliderOptions = Object.assign({}, priceSliderOptionsSale); } else if (adType === AD_TYPE.AD_TYPE_RENT.stringId) { priceSliderOptions = Object.assign({}, priceSliderOptionsRent); } else { res.render("notFound", { title: " " }); return; } // TODO: Maybe this is slow, pay attention to this const filterFilters = filterObject => { const filterCategories = filterObject.categoriesToShow; return filterCategories.indexOf(category) !== -1; }; const advancedBooleanFilterObjects = ADVANCED_BOOLEAN_FILTERS.filter( filterFilters ); const advancedSegmentSelectFilterObjects = ADVANCED_SEGMENT_SELECT_FILTERS.filter( filterFilters ); const advancedRangeFilterObjects = ADVANCED_RANGE_FILTERS.filter( filterFilters ); const advancedBooleanFilterValues = { includeIncompleteAds, balcony, elevator, newBuilding }; const advancedSegmentSelectFilterValues = { accessRoadType }; const advancedRangeFilterValues = { numberOfFloorsMin, numberOfFloorsMax, numberOfRoomsMin, numberOfRoomsMax, floorMin, floorMax }; if (priceMin || priceMax) { priceSliderOptions.start = [priceMin, priceMax]; } if (sizeMin || sizeMax) { sizeSliderOptions.start = [sizeMin, sizeMax]; } if (gardenSizeSliderOptions && (gardenSizeMin || gardenSizeMax)) { gardenSizeSliderOptions.start = [gardenSizeMin, gardenSizeMax]; } res.render("realEstateFilters", { title, hasGardenSize, priceSliderOptions: JSON.stringify(priceSliderOptions), sizeSliderOptions: JSON.stringify(sizeSliderOptions), gardenSizeSliderOptions: JSON.stringify(gardenSizeSliderOptions), advancedBooleanFilterObjects, advancedBooleanFilterValues, advancedSegmentSelectFilterObjects, advancedSegmentSelectFilterValues, advancedRangeFilterObjects, advancedRangeFilterValues, includeIncompleteAds }); }; const postFilters = async (req, res) => { const searchRequest = await currentSearchRequest(req); if (!searchRequest || !searchRequest.dataValues) { res.render("notFound", { title: " " }); return; } const nextStepPage = req.query.nextStep || "pregled"; const nextStepUrl = `/${nextStepPage}/${searchRequest.id}`; const priceMin = parseInt(req.body.priceMin) || 0; const priceMax = parseInt(req.body.priceMax) || 0; const sizeMin = parseInt(req.body.sizeMin) || 0; const sizeMax = parseInt(req.body.sizeMax) || 0; const advancedRangeFilters = {}; ADVANCED_RANGE_FILTERS.forEach(filter => { let parsingFunction = parseInt; if (filter.decimalPlaces) { parsingFunction = parseFloat; } advancedRangeFilters[filter.dbFieldMin] = parsingFunction( req.body[filter.dbFieldMin] ); advancedRangeFilters[filter.dbFieldMax] = parsingFunction( req.body[filter.dbFieldMax] ); advancedRangeFilters[filter.dbFieldMin] = isNaN( advancedRangeFilters[filter.dbFieldMin] ) ? null : advancedRangeFilters[filter.dbFieldMin]; advancedRangeFilters[filter.dbFieldMax] = isNaN( advancedRangeFilters[filter.dbFieldMax] ) ? null : advancedRangeFilters[filter.dbFieldMax]; try { if (filter.decimalPlaces) { advancedRangeFilters[filter.dbFieldMin] = advancedRangeFilters[ filter.dbFieldMin ].toFixed(filter.decimalPlaces); advancedRangeFilters[filter.dbFieldMax] = advancedRangeFilters[ filter.dbFieldMax ].toFixed(filter.decimalPlaces); } } catch (e) { advancedRangeFilters[filter.dbFieldMin] = null; advancedRangeFilters[filter.dbFieldMax] = null; } if ( advancedRangeFilters[filter.dbFieldMin] < filter.validValueMin || advancedRangeFilters[filter.dbFieldMin] > filter.validValueMax ) { advancedRangeFilters[filter.dbFieldMin] = filter.validValueMin; } if ( advancedRangeFilters[filter.dbFieldMax] < filter.validValueMin || advancedRangeFilters[filter.dbFieldMax] > filter.validValueMax ) { advancedRangeFilters[filter.dbFieldMax] = filter.validValueMax; } }); const includeIncompleteAds = req.body.includeIncompleteAds === "on"; const balcony = req.body.balcony === "on"; const elevator = req.body.elevator === "on"; const newBuilding = req.body.newBuilding === "on"; const accessRoadType = req.body.accessRoadType; if (!ACCESS_ROAD_TYPE[accessRoadType]) { res.render("notFound", { title: " Greška !" }); return; } //TODO: Filter validation searchRequest.priceMin = priceMin; searchRequest.priceMax = priceMax; searchRequest.sizeMin = sizeMin; searchRequest.sizeMax = sizeMax; for (const filter of Object.keys(advancedRangeFilters)) { searchRequest[filter] = advancedRangeFilters[filter]; } searchRequest.balcony = balcony; searchRequest.elevator = elevator; searchRequest.newBuilding = newBuilding; searchRequest.includeIncompleteAds = includeIncompleteAds; searchRequest.accessRoadType = accessRoadType; if ( req.body.gardenSizeMin !== undefined && req.body.gardenSizeMax !== undefined ) { const gardenSizeMin = parseInt(req.body.gardenSizeMin); const gardenSizeMax = parseInt(req.body.gardenSizeMax); //TODO: Filter validation searchRequest.gardenSizeMin = gardenSizeMin; searchRequest.gardenSizeMax = gardenSizeMax; } await searchRequest.save(); res.redirect(nextStepUrl); }; module.exports = { getFilters, postFilters };