Files
old-web/app/helpers/db/realEstate.js
2019-12-18 21:49:12 +01:00

305 lines
6.2 KiB
JavaScript

"use strict";
const db = require("../../models/index");
const sequelize = require("sequelize");
const Op = sequelize.Op;
const bulkUpsertRealEstates = async realEstateData => {
try {
const fieldsToUpdateIfDuplicate = [
"realEstateType",
"adType",
"price",
"area",
"streetNumber",
"streetName",
"locality",
"municipality",
"city",
"region",
"entity",
"country",
"locationLat",
"locationLong",
"title",
"shortDescription",
"longDescription",
"gardenSize",
"adStatus",
"updatedAt",
"renewedDate",
"numberOfRooms",
"numberOfFloors",
"floor",
"accessRoadType",
"heatingType",
"furnishingType",
"balcony",
"newBuilding",
"elevator",
"water",
"electricity",
"drainageSystem",
"registeredInZkBooks",
"recentlyAdapted",
"parking",
"garage",
"gas",
"antiTheftDoor",
"airCondition",
"phoneConnection",
"cableTV",
"internet",
"basementAttic",
"storeRoom",
"videoSurveillance",
"alarm",
"suitableForStudents",
"includingBills",
"animalsAllowed",
"pool",
"urbanPlanPermit",
"buildingPermit",
"utilityConnection",
"distanceToRiver",
"numberOfViewsAgency"
];
const order = [["updatedAt", "desc"]];
return await db.RealEstate.bulkCreate(realEstateData, {
updateOnDuplicate: fieldsToUpdateIfDuplicate,
returning: true,
order
});
} catch (e) {
console.log("Error bulk upserting realEstates : ", e);
}
};
const getRealEstateById = async id => {
return db.RealEstate.findByPk(id);
};
const findRealEstatesForSearchRequest = async (searchRequest, maxResults) => {
const {
priceMin,
priceMax,
sizeMin,
sizeMax,
adType,
realEstateType,
areaToSearch,
gardenSizeMin,
gardenSizeMax,
numberOfRoomsMin,
numberOfRoomsMax,
numberOfFloorsMin,
numberOfFloorsMax,
floorMin,
floorMax,
includeIncompleteAds,
balcony,
elevator,
newBuilding,
accessRoadType
} = searchRequest;
const longitudeColumn = sequelize.col("locationLong");
const latitudeColumn = sequelize.col("locationLat");
const pointGeometry = sequelize.fn(
"ST_Point",
longitudeColumn,
latitudeColumn
);
const pointWithSRID = sequelize.fn("ST_SetSRID", pointGeometry, 4326);
const areaToSearchAsGeometry = sequelize.fn(
"ST_GeomFromGeoJSON",
JSON.stringify(areaToSearch)
);
const areaToSearchWithSRID = sequelize.fn(
"ST_SetSRID",
areaToSearchAsGeometry,
4326
);
const contains = sequelize.fn(
"ST_Contains",
areaToSearchWithSRID,
pointWithSRID
);
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.or]: {
[Op.and]: {
[Op.lte]: priceMax,
[Op.gte]: priceMin
},
[Op.is]: null
}
},
area: {
[Op.lte]: sizeMax,
[Op.gte]: sizeMin
},
[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 db.RealEstate.findAll({
where: includeIncompleteAds ? queryIncludeIncomplete : query,
limit: maxResults,
order
});
};
module.exports = {
bulkUpsertRealEstates,
getRealEstateById,
findRealEstatesForSearchRequest
};