107 lines
3.9 KiB
JavaScript
107 lines
3.9 KiB
JavaScript
const _ = require('lodash')
|
|
const getClimateMinMax = require("./getClimateMinMax.js")
|
|
const oldToNewQuerySyntax = require("./oldToNewQuerySyntax.js")
|
|
const moment = require("moment")
|
|
|
|
exports.scoreAndSearch = async function (from, to, queries, dbConn) {
|
|
// TODO break funtion into parts when implementing non-climate queries and modularize (new file)
|
|
|
|
console.log('search')
|
|
|
|
// get Min and Max values for each Parameter
|
|
const minMax = await getClimateMinMax.getClimateMinMax(dbConn)
|
|
|
|
// randomize if empty queries
|
|
// TODO: WHY
|
|
if (_.isEmpty(queries)) {
|
|
let t = _.round(_.random(minMax.min.temperature_mean_max, minMax.max.temperature_mean_max-5),0)
|
|
let p = _.round(_.random(minMax.min.percipitation, minMax.max.percipitation - 50), 0)
|
|
let r = _.round(_.random(minMax.min.raindays, minMax.max.raindays - 5), 0)
|
|
let s = _.round(_.random(minMax.min.sunhours, minMax.max.sunhours - 50), 0)
|
|
queries.temperature_mean_max = `${t},${t + 5}`
|
|
queries.percipitation = `${p},${p + 50}`
|
|
queries.raindays = `${r},${r + 5}`
|
|
queries.sunhours = `${s},${s + 50}`
|
|
}
|
|
queries = oldToNewQuerySyntax.oldToNewQuerySyntax(queries)
|
|
console.log(queries)
|
|
|
|
// TODO simplify and remove support for old query syntaax
|
|
let monthFrom = 0
|
|
let monthTo = 0
|
|
let dayFrom = 0
|
|
let dayTo = 0
|
|
|
|
if (_.isNumber(from) && _.isNumber(to)) {
|
|
let dateFrom = moment(from).toDate()
|
|
let dateTo = moment(to).toDate()
|
|
monthFrom = dateFrom.getMonth()
|
|
monthTo = dateTo.getMonth()
|
|
dayFrom = dateFrom.getDay()
|
|
dayTo = dateTo.getDay()
|
|
if (moment(dateFrom).add(23, 'hours').isAfter(moment(dateTo))) throw new Error("ERR: 'to' must be at least one day after 'from'.")
|
|
} else {
|
|
// to still support old query syntax
|
|
let re = /([12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01]))/i;
|
|
monthFrom = Number(from.split("-")[1])
|
|
monthTo = Number(to.split("-")[1])
|
|
dayFrom = Number(from.split("-")[2])
|
|
dayTo = Number(to.split("-")[2])
|
|
if (!from.match(re) || !to.match(re)) throw new Error("ERR: invalid parameter:",from,to)
|
|
if (moment(from, 'YYYY-MM-DD').add(23, 'hours').isAfter(moment(to, 'YYYY-MM-DD'))) throw new Error("ERR: 'to' must be at least one day after 'from'.")
|
|
}
|
|
|
|
// -- Prepare search --
|
|
// to calculate average if traveldates are in more than one month
|
|
let travelPeriods = []
|
|
if (monthFrom === monthTo) {
|
|
let element = {
|
|
month: monthFrom,
|
|
days: dayTo - dayFrom
|
|
}
|
|
travelPeriods.push(element)
|
|
} else {
|
|
for (let index = monthFrom; index <= monthTo; index++) {
|
|
let element = {}
|
|
if (index === monthFrom) {
|
|
element = {
|
|
month: index,
|
|
days: 32 - dayFrom
|
|
}
|
|
} else if (index === monthTo) {
|
|
element = {
|
|
month: index,
|
|
days: dayTo
|
|
}
|
|
} else {
|
|
element = {
|
|
month: index,
|
|
days: 30
|
|
}
|
|
}
|
|
travelPeriods.push(element)
|
|
}
|
|
}
|
|
|
|
// calculate detail scores
|
|
let detailScores = await Promise.all(travelPeriods.map(async period => {
|
|
period.climate = await getAllRegionsWithClimatePerMonth(period.month)
|
|
period.scores = {}
|
|
Object.entries(queries).forEach(([key, value]) => {
|
|
// console.log('key',key)
|
|
// console.log('val', value)
|
|
period.scores[key] = calculateScores(key, period.climate, value[0], value[1], minMax)
|
|
});
|
|
return period
|
|
}));
|
|
|
|
|
|
// calculate ratio and transform into target object
|
|
return {
|
|
results: transformer.transform(detailScores),
|
|
debug: {
|
|
detailScores: detailScores,
|
|
minMax: minMax
|
|
}
|
|
}
|
|
} |