Merge branch 'results-link' of gitlab.com:saburly/marketalarm/web into no-all-results-email
This commit is contained in:
@@ -2,7 +2,6 @@
|
||||
const db = require("../../models/index");
|
||||
const sequelize = require("sequelize");
|
||||
const Op = sequelize.Op;
|
||||
|
||||
const bulkUpsertRealEstates = async realEstateData => {
|
||||
try {
|
||||
const fieldsToUpdateIfDuplicate = [
|
||||
@@ -87,7 +86,20 @@ const findRealEstatesForSearchRequest = async (searchRequest, maxResults) => {
|
||||
sizeMax,
|
||||
adType,
|
||||
realEstateType,
|
||||
areaToSearch
|
||||
areaToSearch,
|
||||
gardenSizeMin,
|
||||
gardenSizeMax,
|
||||
numberOfRoomsMin,
|
||||
numberOfRoomsMax,
|
||||
numberOfFloorsMin,
|
||||
numberOfFloorsMax,
|
||||
floorMin,
|
||||
floorMax,
|
||||
includeIncompleteAds,
|
||||
balcony,
|
||||
elevator,
|
||||
newBuilding,
|
||||
accessRoadType
|
||||
} = searchRequest;
|
||||
|
||||
const longitudeColumn = sequelize.col("locationLong");
|
||||
@@ -116,12 +128,20 @@ const findRealEstatesForSearchRequest = async (searchRequest, maxResults) => {
|
||||
|
||||
const geoSearchQueryPart = sequelize.where(contains, true);
|
||||
|
||||
//General queries contain only attributes that are defined for every searchreq
|
||||
|
||||
//Query for case of complete ads
|
||||
const query = {
|
||||
adType,
|
||||
realEstateType,
|
||||
price: {
|
||||
[Op.lte]: priceMax,
|
||||
[Op.gte]: priceMin
|
||||
[Op.or]: {
|
||||
[Op.and]: {
|
||||
[Op.lte]: priceMax,
|
||||
[Op.gte]: priceMin
|
||||
},
|
||||
[Op.is]: null
|
||||
}
|
||||
},
|
||||
area: {
|
||||
[Op.lte]: sizeMax,
|
||||
@@ -130,10 +150,148 @@ const findRealEstatesForSearchRequest = async (searchRequest, maxResults) => {
|
||||
[Op.and]: geoSearchQueryPart
|
||||
};
|
||||
|
||||
//Query for case of incomplete ads
|
||||
const queryIncludeIncomplete = {
|
||||
adType,
|
||||
realEstateType,
|
||||
price: {
|
||||
[Op.or]: {
|
||||
[Op.and]: {
|
||||
[Op.lte]: priceMax,
|
||||
[Op.gte]: priceMin
|
||||
},
|
||||
[Op.is]: null
|
||||
}
|
||||
},
|
||||
area: {
|
||||
[Op.or]: {
|
||||
[Op.and]: {
|
||||
[Op.lte]: sizeMax,
|
||||
[Op.gte]: sizeMin
|
||||
},
|
||||
[Op.is]: null
|
||||
}
|
||||
},
|
||||
[Op.and]: geoSearchQueryPart
|
||||
};
|
||||
|
||||
//Every other attribute is checked separately and included in query only if it is defined
|
||||
if (gardenSizeMax && gardenSizeMin) {
|
||||
query.gardenSize = {
|
||||
[Op.lte]: gardenSizeMax,
|
||||
[Op.gte]: gardenSizeMin
|
||||
};
|
||||
queryIncludeIncomplete.gardenSize = {
|
||||
[Op.or]: {
|
||||
[Op.and]: {
|
||||
[Op.lte]: gardenSizeMax,
|
||||
[Op.gte]: gardenSizeMin
|
||||
},
|
||||
[Op.is]: null
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (numberOfRoomsMin && numberOfRoomsMax) {
|
||||
query.numberOfRooms = {
|
||||
[Op.lte]: numberOfRoomsMax,
|
||||
[Op.gte]: numberOfRoomsMin
|
||||
};
|
||||
queryIncludeIncomplete.numberOfRooms = {
|
||||
[Op.or]: {
|
||||
[Op.and]: {
|
||||
[Op.lte]: numberOfRoomsMax,
|
||||
[Op.gte]: numberOfRoomsMin
|
||||
},
|
||||
[Op.is]: null
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (numberOfFloorsMin && numberOfFloorsMax) {
|
||||
query.numberOfFloors = {
|
||||
[Op.lte]: numberOfFloorsMax,
|
||||
[Op.gte]: numberOfFloorsMin
|
||||
};
|
||||
queryIncludeIncomplete.numberOfFloors = {
|
||||
[Op.or]: {
|
||||
[Op.and]: {
|
||||
[Op.lte]: numberOfFloorsMax,
|
||||
[Op.gte]: numberOfFloorsMin
|
||||
},
|
||||
[Op.is]: null
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (floorMin && floorMax) {
|
||||
query.floor = {
|
||||
[Op.lte]: floorMax,
|
||||
[Op.gte]: floorMin
|
||||
};
|
||||
queryIncludeIncomplete.floor = {
|
||||
[Op.or]: {
|
||||
[Op.and]: {
|
||||
[Op.lte]: floorMax,
|
||||
[Op.gte]: floorMin
|
||||
},
|
||||
[Op.is]: null
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (balcony) {
|
||||
query.balcony = {
|
||||
[Op.eq]: balcony
|
||||
};
|
||||
queryIncludeIncomplete.balcony = {
|
||||
[Op.or]: {
|
||||
[Op.eq]: balcony,
|
||||
[Op.is]: null
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (newBuilding) {
|
||||
query.newBuilding = {
|
||||
[Op.eq]: newBuilding
|
||||
};
|
||||
queryIncludeIncomplete.newBuilding = {
|
||||
[Op.or]: {
|
||||
[Op.eq]: newBuilding,
|
||||
[Op.is]: null
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (elevator) {
|
||||
query.elevator = {
|
||||
[Op.eq]: elevator
|
||||
};
|
||||
queryIncludeIncomplete.elevator = {
|
||||
[Op.or]: {
|
||||
[Op.eq]: elevator,
|
||||
[Op.is]: null
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (accessRoadType !== "ANY") {
|
||||
query.accessRoadType = {
|
||||
[Op.eq]: accessRoadType
|
||||
};
|
||||
queryIncludeIncomplete.accessRoadType = {
|
||||
[Op.or]: {
|
||||
[Op.eq]: accessRoadType,
|
||||
[Op.is]: null
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const order = [["updatedAt", "desc"]];
|
||||
|
||||
return await db.RealEstate.findAll({
|
||||
where: query,
|
||||
return db.RealEstate.findAll({
|
||||
where: includeIncompleteAds ? queryIncludeIncomplete : query,
|
||||
limit: maxResults,
|
||||
order
|
||||
});
|
||||
|
||||
@@ -2,11 +2,13 @@
|
||||
const db = require("../../models/index");
|
||||
const sequelize = require("sequelize");
|
||||
const Op = sequelize.Op;
|
||||
const { AD_CATEGORY } = require("../../common/enums");
|
||||
|
||||
const getSearchRequest = async searchRequestId => {
|
||||
try {
|
||||
return await db.SearchRequest.findByPk(searchRequestId);
|
||||
} catch (error) {
|
||||
console.log("searchrequest.js", error);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
@@ -22,7 +24,15 @@ const findSearchRequestsForRealEstate = async realEstate => {
|
||||
adType,
|
||||
realEstateType,
|
||||
locationLat,
|
||||
locationLong
|
||||
locationLong,
|
||||
accessRoadType,
|
||||
balcony,
|
||||
newBuilding,
|
||||
elevator,
|
||||
gardenSize,
|
||||
numberOfRooms,
|
||||
numberOfFloors,
|
||||
floor
|
||||
} = realEstate;
|
||||
|
||||
if (!locationLat || !locationLong) {
|
||||
@@ -39,12 +49,20 @@ const findSearchRequestsForRealEstate = async realEstate => {
|
||||
|
||||
const geoSearchQueryPart = sequelize.where(contains, true);
|
||||
|
||||
//General query contains only attributes that are defined for every RealEstate - not null
|
||||
const query = {
|
||||
adType,
|
||||
realEstateType,
|
||||
subscribed: true,
|
||||
[Op.and]: geoSearchQueryPart
|
||||
};
|
||||
//Needed for defining which attribute should exist or not
|
||||
const realEstateTypeObject = AD_CATEGORY[realEstateType];
|
||||
//Needed to decide on including incomplete RealEstates data
|
||||
let checkForIncompleteWanted = false;
|
||||
|
||||
//Attributes are checked separately and included in query only if defined
|
||||
//Price and area should be defined for every property
|
||||
|
||||
if (price) {
|
||||
query.priceMin = {
|
||||
@@ -62,8 +80,96 @@ const findSearchRequestsForRealEstate = async realEstate => {
|
||||
query.sizeMax = {
|
||||
[Op.gte]: area
|
||||
};
|
||||
} else {
|
||||
checkForIncompleteWanted = true;
|
||||
}
|
||||
//Other attributes can be defined or not depending on RealEstate type
|
||||
if (gardenSize) {
|
||||
query.gardenSizeMin = {
|
||||
[Op.lte]: gardenSize
|
||||
};
|
||||
query.gardenSizeMax = {
|
||||
[Op.gte]: gardenSize
|
||||
};
|
||||
} else if (realEstateTypeObject.hasGardenSize) {
|
||||
checkForIncompleteWanted = true;
|
||||
}
|
||||
|
||||
if (numberOfRooms) {
|
||||
query.numberOfRoomsMin = {
|
||||
[Op.lte]: numberOfRooms
|
||||
};
|
||||
query.numberOfRoomsMax = {
|
||||
[Op.gte]: numberOfRooms
|
||||
};
|
||||
} else if (realEstateTypeObject.hasNumberOfRoom) {
|
||||
checkForIncompleteWanted = true;
|
||||
}
|
||||
|
||||
if (numberOfFloors) {
|
||||
query.numberOfFloorsMin = {
|
||||
[Op.lte]: numberOfFloors
|
||||
};
|
||||
query.numberOfFloorsMax = {
|
||||
[Op.gte]: numberOfFloors
|
||||
};
|
||||
} else if (realEstateTypeObject.hasNumberOfFloors) {
|
||||
checkForIncompleteWanted = true;
|
||||
}
|
||||
|
||||
if (floor) {
|
||||
query.floorMin = {
|
||||
[Op.lte]: floor
|
||||
};
|
||||
query.floorMax = {
|
||||
[Op.gte]: floor
|
||||
};
|
||||
} else if (realEstateTypeObject.hasFloorProp) {
|
||||
checkForIncompleteWanted = true;
|
||||
}
|
||||
|
||||
if (accessRoadType) {
|
||||
query.accessRoadType = {
|
||||
[Op.or]: {
|
||||
[Op.eq]: "ANY",
|
||||
[Op.eq]: accessRoadType
|
||||
}
|
||||
};
|
||||
} else if (realEstateTypeObject.hasAccesRoadType) {
|
||||
checkForIncompleteWanted = true;
|
||||
}
|
||||
|
||||
if (balcony) {
|
||||
query.balcony = {
|
||||
[Op.eq]: balcony
|
||||
};
|
||||
} else if (realEstateTypeObject.hasBalconyProp) {
|
||||
checkForIncompleteWanted = true;
|
||||
}
|
||||
|
||||
if (newBuilding) {
|
||||
query.newBuilding = {
|
||||
[Op.eq]: newBuilding
|
||||
};
|
||||
} else if (realEstateTypeObject.hasNewBuildingProp) {
|
||||
checkForIncompleteWanted = true;
|
||||
}
|
||||
|
||||
if (elevator) {
|
||||
query.elevator = {
|
||||
[Op.eq]: elevator
|
||||
};
|
||||
} else if (realEstateTypeObject.hasElevatorProp) {
|
||||
checkForIncompleteWanted = true;
|
||||
}
|
||||
|
||||
//If one of the attributes that exists for property type is null
|
||||
//we include in query to check if incomplete real estates are accepted
|
||||
if (checkForIncompleteWanted) {
|
||||
query.includeIncompleteAds = {
|
||||
[Op.eq]: true
|
||||
};
|
||||
}
|
||||
return await db.SearchRequest.findAll({ where: query });
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user