Skip to content

Instantly share code, notes, and snippets.

@maximilianfixl
Created July 20, 2023 14:11
Show Gist options
  • Select an option

  • Save maximilianfixl/b2b8896ea614dc1d049504782cdfb5a5 to your computer and use it in GitHub Desktop.

Select an option

Save maximilianfixl/b2b8896ea614dc1d049504782cdfb5a5 to your computer and use it in GitHub Desktop.
'use strict'
function createTimelinesObject(switchline, anabreisemoeglichline, availableline, checkinoutline, availablelinewithswitch, rowsPreise, priceDetailsOnTimeline) {
return {
switchline: switchline,
anabreisemoeglichline: anabreisemoeglichline,
availableline: availableline,
checkinoutline: checkinoutline,
availablelinewithswitch: availablelinewithswitch,
rowsSeasonalPrices: rowsPreise,
priceDetailsOnTimeline: priceDetailsOnTimeline,
}
}
function logThis(message, task, modulename = 'timeline2', force = false) {
if (task.memberid !== -1 && force !== false)
return
g.logger.info(message, task, modulename)
}
const wederAnNochAbreiseMoeglich_X = 'X'
const allesMoeglich_C = 'C'
const nurAnreiseMoeglich_I = 'I'
const nurKommenMoeglich_K = 'K'
const nurAbreiseMoeglich_O = 'O'
const nurGehenMoeglich_G = 'G'
function erzeuegePreiseFuerTests(rowsPreise) {
const preiseFuerTests = []
rowsPreise.forEach(rowPreis => {
preiseFuerTests.push({
preis_von: `getDate('${new Date(rowPreis['preis_von']).dateUs()}')`,
preis_bis: `getDate('${new Date(rowPreis['preis_bis']).dateUs()}')`,
preis_preis: rowPreis['preis_preis'],
preis_anreise: rowPreis['preis_anreise'].toString(),
preis_abreise: rowPreis['preis_abreise'].toString(),
preis_lueckenbuchungok: rowPreis['preis_lueckenbuchungok'],
preis_mintage: rowPreis['preis_mintage'],
preis_mintagefuerluecke: rowPreis['preis_mintagefuerluecke'],
preis_pausentage: rowPreis['preis_pausentage'],
preis_personen: rowPreis['preis_personen'],
preis_weitere: rowPreis['preis_weitere'],
obj_personen: rowPreis['obj_personen'],
})
})
return preiseFuerTests
}
function erzeugeBelegungenFuerTests(filteredRowsBelegungen) {
const belegungenFuerTests = []
filteredRowsBelegungen.forEach(filteredRowBelegung => {
belegungenFuerTests.push({
reihenfolge: filteredRowBelegung['reihenfolge'],
art: filteredRowBelegung['art'],
vorg_anreise: `getDate('${new Date(filteredRowBelegung['vorg_anreise']).dateUs()}')`,
vorg_abreise: `getDate('${new Date(filteredRowBelegung['vorg_abreise']).dateUs()}')`,
vorg_id: filteredRowBelegung['vorg_id'],
vorg_art: filteredRowBelegung['vorg_art'],
id: filteredRowBelegung['id'],
})
})
return belegungenFuerTests
}
/**
*
* @param {Object} g
*/
function Timeline2(g) {
return {
/**
*
* @param {Object} task
* @param {number} memberid
* @param {number} objid
* @param {number} msid
* @param {*} start
* @param {string} moduleNamePrevious
* @param {boolean} [withDetails = false]
* @return {Promise<any>}
*/
async create(task, memberid, objid, msid, start, moduleNamePrevious, withDetails = false) {
try {
const moduleName = `${moduleNamePrevious}_timelineCreate`
let dateStart = new Date(start)
let preisVorherigeSaison = 1
const rowsPreise = await g.db.query(task, `select preis_von, preis_bis, preis_preis, preis_anreise, preis_abreise, preis_lueckenbuchungok, preis_mintage, preis_mintagefuerluecke, preis_pausentage, preis_personen, preis_weitere, obj_personen from tl_fewo_preise0 inner join tl_fewo_objekte on (obj_memberid = preis_memberid and obj_id = preis_objid) where preis_memberid = ${memberid} and preis_objid = ${objid} and preis_bis > '${dateStart.dateUs()}' order by preis_von`, moduleName)
let priceDetailsOnTimeline = {
maxPersonArr: [],
minStayArr: [],
minStayForGapArr: [],
gapBookingArr: [],
bookingIds: [],
}
if (rowsPreise.length === 0)
return createTimelinesObject('', '', '', '', '', rowsPreise, priceDetailsOnTimeline)
const maxPreisBis = rowsPreise[rowsPreise.length - 1]['preis_bis']
const startUs = new Date(dateStart).dateUs()
const endUs = new Date(maxPreisBis).dateUs()
const rowsBelegungen = await getBelegungen(startUs, endUs, objid, memberid, task, moduleName)
return this.erzeugeZeitleisteVonPreisenUndBelegungen(task, rowsPreise, rowsBelegungen, dateStart, start, preisVorherigeSaison, priceDetailsOnTimeline, moduleName, withDetails, memberid === 813 && objid === 8)
}
catch (e) {
task.error = e.message
task.error_stacktrace = e.stack
g.error.catchError(task)
}
},
/**
* @param task
* @param rowsPreise
* @param rowsBelegungen
* @param dateStart
* @param start
* @param preisVorherigeSaison
* @param priceDetailsOnTimeline
* @param moduleName
* @param withDetails
* @param forceLog
* @returns {Promise<{rowsSeasonalPrices, availableline, checkinoutline, availablelinewithswitch, priceDetailsOnTimeline, switchline}>}
*/
async erzeugeZeitleisteVonPreisenUndBelegungen(task, rowsPreise, rowsBelegungen, dateStart, start, preisVorherigeSaison, priceDetailsOnTimeline, moduleName, withDetails, forceLog = false) {
let timelineSegments = {}
const timelineTimestamps = []
let preisVorherigeSaisonFuerZeitleistenabschnitt = preisVorherigeSaison
const preiseFuerTests = erzeuegePreiseFuerTests(rowsPreise)
const belegungenFuerTests = erzeugeBelegungenFuerTests(rowsBelegungen)
logThis(`now_starting_erzeugeZeitleisteVonPreisenUndBelegungen_with rowsPreise ${g.logger.inspect(rowsPreise)} and preiseFuerTests ${g.logger.inspect(preiseFuerTests)} and rowsBelegungen ${g.logger.inspect(rowsBelegungen)} and belegungenFuerTests ${g.logger.inspect(belegungenFuerTests)}`, task, moduleName, forceLog)
rowsPreise.forEach((rowPreis, preisIndex) => {
let preisVon = new Date(start)
if (preisIndex > 0)
preisVon = new Date(rowPreis['preis_von'])
const preisBis = new Date(rowPreis['preis_bis'])
const preisPreis = parseFloat(rowPreis['preis_preis'])
const preisAnreise = rowPreis['preis_anreise'].toString()
const preisAbreise = rowPreis['preis_abreise'].toString()
const lueckenbuchungOk = rowPreis['preis_lueckenbuchungok'] === 1
const preisMintage = rowPreis['preis_mintage']
const preisMintageFuerLuecke = rowPreis['preis_mintagefuerluecke']
const preisPausentage = rowPreis['preis_pausentage']
const filteredRowsBelegungen = rowsBelegungen.filter(rowBelegung => {
const anreise = new Date(rowBelegung['vorg_anreise'])
const abreise = new Date(rowBelegung['vorg_abreise'])
const preisVonKleinerGleichAnreise = preisVon <= anreise
const anreiseKleinerGleichPreisBis = anreise <= preisBis
const preisVonKleinerGleichAbreise = preisVon <= abreise
const abreiseKleinerGleichPreisBis = abreise <= preisBis
const anreiseKleinerGleichPreisVon = anreise <= preisVon
const preisBisKleinerGleichAbreise = preisBis <= abreise
const preisVonKleinerGleichAnreiseUndAnreiseKleinerGleichPreisBis = preisVonKleinerGleichAnreise && anreiseKleinerGleichPreisBis
const preisVonKleinerGleichAbreiseUndAbreiseKleinerGleichPreisBis = preisVonKleinerGleichAbreise && abreiseKleinerGleichPreisBis
const anreiseKleinerGleichPreisVonUndPreisBisKleinerGleichAbreise = anreiseKleinerGleichPreisVon && preisBisKleinerGleichAbreise
return preisVonKleinerGleichAnreiseUndAnreiseKleinerGleichPreisBis ||
preisVonKleinerGleichAbreiseUndAbreiseKleinerGleichPreisBis ||
anreiseKleinerGleichPreisVonUndPreisBisKleinerGleichAbreise
})
logThis(`this_is_filteredRowsBelegungen, preisvon ${preisVon.dateUs()}, preisbis ${preisBis.dateUs()}, filteredTransferRows ${g.logger.inspect(filteredRowsBelegungen)}`, task, moduleName)
const resultTimelineConsiderPrice = this.createTimelineSeasonalSection(task, preisVon, preisBis, preisAnreise, preisAbreise, preisPreis, preisVorherigeSaisonFuerZeitleistenabschnitt, preisMintage, lueckenbuchungOk, preisMintageFuerLuecke, preisPausentage, filteredRowsBelegungen, withDetails)
timelineSegments[resultTimelineConsiderPrice['timestamp']] = resultTimelineConsiderPrice['timelines']
timelineTimestamps.push(resultTimelineConsiderPrice['timestamp'])
let preisPersonen = rowPreis['preis_personen']
if (preisPersonen === 0)
preisPersonen = rowPreis['obj_personen']
let priceMinDays = rowPreis['preis_mintage']
if (priceMinDays === 0)
priceMinDays = 1
preisVorherigeSaisonFuerZeitleistenabschnitt = preisPreis
for (let day = 0; day < resultTimelineConsiderPrice['timelines']['availableline'].length; day++) {
priceDetailsOnTimeline.maxPersonArr.push(preisPersonen)
priceDetailsOnTimeline.minStayArr.push(priceMinDays)
priceDetailsOnTimeline.minStayForGapArr.push(rowPreis['preis_mintagefuerluecke'])
priceDetailsOnTimeline.gapBookingArr.push(rowPreis['preis_lueckenbuchungok'])
priceDetailsOnTimeline.bookingIds = [...resultTimelineConsiderPrice['timelines']['bookingIds']]
}
})
let switchline = ''
let anabreisemoeglichline = ''
let availableline = ''
let checkinoutline = ''
let availablelinewithswitch = ''
const neueSaisonAbDieserPosition = []
let vorherigerSaisonwechsel = 0
for (let i = 0; i < timelineTimestamps.length; i++) {
switchline += timelineSegments[timelineTimestamps[i]].switchline
anabreisemoeglichline += timelineSegments[timelineTimestamps[i]].anabreisemoeglichline
availableline += timelineSegments[timelineTimestamps[i]].availableline
checkinoutline += timelineSegments[timelineTimestamps[i]].checkinoutline
availablelinewithswitch += timelineSegments[timelineTimestamps[i]].availablelinewithswitch
if (i < timelineTimestamps.length - 1)
neueSaisonAbDieserPosition.push(vorherigerSaisonwechsel + timelineSegments[timelineTimestamps[i]].switchline.length)
vorherigerSaisonwechsel += timelineSegments[timelineTimestamps[i]].switchline.length
}
logThis(`this_is_switchline vor_lueckenbuchung_5: ${switchline}`, task)
switchline = setzeNaechsteMoeglicheAnAbreiseAufAnreiseWennBelegungAufNichtAnAbreisbaremTagEndet(switchline)
logThis(`this_is_switchline vor_lueckenbuchung_6: ${switchline}`, task)
switchline = setzeLetzteMoeglicheAnAbreiseAufAbreiseWennBelegungAufNichtAnAbreisbaremTagBeginnt(switchline)
logThis(`this_is_switchline vor_lueckenbuchung_7: ${switchline}`, task)
switchline = ersetzeAlleGUndKDurchX(switchline)
neueSaisonAbDieserPosition.forEach(positionSaisonbeginn => {
const positionSaisonende = positionSaisonbeginn - 1
const mintageInDerBetrachtetenSaison = priceDetailsOnTimeline.minStayArr[positionSaisonende]
let mintageInDerFolgendenSaison = priceDetailsOnTimeline.minStayArr[positionSaisonbeginn]
if (!mintageInDerFolgendenSaison)
mintageInDerFolgendenSaison = 1
if (mintageInDerBetrachtetenSaison > 1) {
const lueckenbuchungErlaubtInDerBetrachtetenSaison = priceDetailsOnTimeline.gapBookingArr[positionSaisonende] === 1
let positionSaisonendeAbzglMintage = positionSaisonende - mintageInDerBetrachtetenSaison
if (positionSaisonendeAbzglMintage < 0)
positionSaisonendeAbzglMintage = 0
const switchlineVorTeilstueck = switchline.substring(0, positionSaisonendeAbzglMintage)
const switchlineTeilstueck = switchline.substring(positionSaisonendeAbzglMintage, positionSaisonende + mintageInDerBetrachtetenSaison)
const switchlineNachTeilstueck = switchline.substring(positionSaisonende + mintageInDerBetrachtetenSaison)
let switchlineTeilstueckBearbeitet = switchlineTeilstueck
if (lueckenbuchungErlaubtInDerBetrachtetenSaison === false) {
logThis(`this_is_switchline_lueckenbuchungErlaubtInDerBetrachtetenSaison vor fuer positionSaisonbeginn ${positionSaisonbeginn}, mintageInDerBetrachtetenSaison ${mintageInDerBetrachtetenSaison}: ${switchlineTeilstueck}`, task, moduleName)
switchlineTeilstueckBearbeitet = deaktiviereAnAbreiseInnerhalbBereichenDieMintageLangSindAnSaisonuebergaengenVorAnreisen(mintageInDerBetrachtetenSaison, switchlineTeilstueck)
}
logThis(`this_is_switchline_lueckenbuchungErlaubtInDerBetrachtetenSaison nach fuer positionSaisonbeginn ${positionSaisonbeginn}: ${switchlineTeilstueckBearbeitet}`, task, moduleName)
const lueckenDieMindestlaengeErfuellen = new RegExp('I[IOC]{0,' + (mintageInDerBetrachtetenSaison - 2) + '}OX', 'g')
switchlineTeilstueckBearbeitet = switchlineTeilstueckBearbeitet.replace(lueckenDieMindestlaengeErfuellen, match => {
if (match.length === 3)
return match
if (lueckenbuchungErlaubtInDerBetrachtetenSaison)
return 'I' + 'X'.repeat(match.length - 3) + 'OX'
return 'X'.repeat(match.length)
})
switchline = switchlineVorTeilstueck + switchlineTeilstueckBearbeitet + switchlineNachTeilstueck
logThis(`this_is_switchline nach_lueckenbuchung_gesamt fuer positionSaisonbeginn ${positionSaisonbeginn}: ${switchline}`, task, moduleName)
const switchlineVorTeilstueckMintageVorSaisonende = switchline.substring(0, positionSaisonendeAbzglMintage)
const switchlineTeilstueckMintageVorSaisonende = switchline.substring(positionSaisonendeAbzglMintage, positionSaisonbeginn + mintageInDerFolgendenSaison + 1)
const switchlineNachTeilstueckMintageVorSaisonende = switchline.substring(positionSaisonbeginn + mintageInDerFolgendenSaison + 1)
logThis(`teilstueck_vor_saisonende ${positionSaisonendeAbzglMintage},${positionSaisonbeginn},${mintageInDerFolgendenSaison}: ${switchlineTeilstueckMintageVorSaisonende}`, task)
const switchlineTeilstueckBearbeitetVorSaisonende = setzeMindestnaechteNachAbreiseAufNurAnreiseOderNichtsAmSaisonuebergang(mintageInDerBetrachtetenSaison, switchlineTeilstueckMintageVorSaisonende)
switchline = switchlineVorTeilstueckMintageVorSaisonende + switchlineTeilstueckBearbeitetVorSaisonende + switchlineNachTeilstueckMintageVorSaisonende
}
})
const resultCreateTimelinesObject = createTimelinesObject(switchline, anabreisemoeglichline, availableline, checkinoutline, availablelinewithswitch, rowsPreise, priceDetailsOnTimeline)
logThis(`das_ist_resultCreateTimelinesObject: ${g.logger.inspect(resultCreateTimelinesObject)}`, task, moduleName)
return resultCreateTimelinesObject
},
/**
*
* @param {Object} task
* @param {Date} start
* @param {Date} end
* @param {string} anreisetage
* @param {string} abreisetage
* @param {number} preis
* @param {number} preisVorherigeSaison
* @param {number} mintage
* @param {boolean} lueckenbuchungOk
* @param {number} anzahlNaechteAbDenenLueckenbuchungErlaubtIst
* @param {number} pausentage
* @param {Array} filteredRowsBelegungen
* @param {boolean} withDetails
* @returns {{timelines: {availableline: string, checkinoutline: string, availablelinewithswitch: string, switchline: string}, timestamp: number}}
*/
createTimelineSeasonalSection(task, start, end, anreisetage, abreisetage, preis, preisVorherigeSaison, mintage, lueckenbuchungOk, anzahlNaechteAbDenenLueckenbuchungErlaubtIst, pausentage, filteredRowsBelegungen, withDetails) {
let timelineSection = {}
let laengeDerZeitleiste = Math.round(g.date.diff(start, end))
let tsStart = start.getTime()
let tsEnd = end.getTime()
let aktuellesDatum = new Date(start)
for (let i = 0; i <= laengeDerZeitleiste; i++) {
const aktuellesDatumAlsTimestamp = aktuellesDatum.getTime()
const aktuellerWochentag = aktuellesDatum.getDay()
const istAnreiseAnDiesemWochentagZulaessig = preis > 0 && (anreisetage.includes('9') || anreisetage.includes(aktuellerWochentag.toString()))
const istAbreiseAnDiesemWochentagZulaessig = abreisetage.includes('9') || abreisetage.includes(aktuellerWochentag.toString())
const ersterTagInErsterSaisonzeit = preisVorherigeSaison === 0 && i === 0
let wechselleistenwert = wederAnNochAbreiseMoeglich_X
if (istAnreiseAnDiesemWochentagZulaessig) {
wechselleistenwert = allesMoeglich_C
if (istAbreiseAnDiesemWochentagZulaessig === false || ersterTagInErsterSaisonzeit)
wechselleistenwert = nurAnreiseMoeglich_I
}
else if (istAbreiseAnDiesemWochentagZulaessig)
wechselleistenwert = nurAbreiseMoeglich_O
let verfuegbarleistenwert = 'Y'
if (i === 0) {
if (preis === 0 || preisVorherigeSaison === 0)
verfuegbarleistenwert = 'N'
}
else if (preis === 0)
verfuegbarleistenwert = 'N'
timelineSection[aktuellesDatumAlsTimestamp] = {
wechsel: wechselleistenwert,
anabreisemoeglich: wechselleistenwert,
verfuegbarmitwechsel: verfuegbarleistenwert,
vorgart: [{
anreise: 'U',
abreise: 'U',
}],
mintage: mintage,
anreisezulaessig: istAnreiseAnDiesemWochentagZulaessig,
abreisezulaessig: istAbreiseAnDiesemWochentagZulaessig,
lbok: lueckenbuchungOk,
wochentag: aktuellerWochentag,
anreisetage: anreisetage,
abreisetage: abreisetage,
datumLesbar: aktuellesDatum.dateDe(),
datum: aktuellesDatum.dateTimeDe(),
bookingId: '',
}
aktuellesDatum.addDays(1)
}
filteredRowsBelegungen.forEach(filteredRowBelegung => {
let anreise = new Date(String(filteredRowBelegung.vorg_anreise))
let abreise = new Date(String(filteredRowBelegung.vorg_abreise))
if (filteredRowBelegung.vorg_naechtepausevoranreise)
anreise.subDays(filteredRowBelegung.vorg_naechtepausevoranreise)
if (filteredRowBelegung.vorg_naechtepausenachabreise)
abreise.addDays(filteredRowBelegung.vorg_naechtepausenachabreise)
let anreiseAlsTimestamp = anreise.getTime()
let abreiseAlsTimestamp = abreise.getTime()
let bookingLength = Math.round(g.date.diff(anreise, abreise))
const vorgangArt = String(filteredRowBelegung['vorg_art'])
aktuellesDatum = anreise
for (let t = 0; t <= bookingLength; t++) {
const tsDay = aktuellesDatum.getTime()
aktuellesDatum.addDays(1)
if (tsDay < tsStart || tsDay > tsEnd)
continue
const timelineSectionElement = timelineSection[tsDay]
if (!timelineSectionElement)
throw new Error(`error_while_creating_timeline: ${tsDay} does not exist in ${g.logger.inspect(timelineSection)}`)
if (withDetails)
timelineSectionElement.bookingId = vorgangArt + '-' + filteredRowBelegung.vorg_id
if (tsDay === anreiseAlsTimestamp) {
if (timelineSectionElement.wechsel === allesMoeglich_C)
timelineSectionElement.wechsel = nurAbreiseMoeglich_O
else if (timelineSectionElement.wechsel === nurAnreiseMoeglich_I)
timelineSectionElement.wechsel = wederAnNochAbreiseMoeglich_X
else if (timelineSectionElement.wechsel === wederAnNochAbreiseMoeglich_X)
timelineSectionElement.wechsel = nurGehenMoeglich_G
if (timelineSectionElement.verfuegbarmitwechsel === 'Y')
timelineSectionElement.verfuegbarmitwechsel = nurAbreiseMoeglich_O
else if (timelineSectionElement.verfuegbarmitwechsel === nurAnreiseMoeglich_I)
timelineSectionElement.verfuegbarmitwechsel = 'W'
timelineSectionElement.vorgart.anreise = vorgangArt
}
else if (tsDay === abreiseAlsTimestamp) {
if (timelineSectionElement.wechsel === allesMoeglich_C)
timelineSectionElement.wechsel = nurAnreiseMoeglich_I
else if (timelineSectionElement.wechsel === nurAbreiseMoeglich_O)
timelineSectionElement.wechsel = nurKommenMoeglich_K
else if (timelineSectionElement.wechsel === wederAnNochAbreiseMoeglich_X)
timelineSectionElement.wechsel = nurKommenMoeglich_K
if (timelineSectionElement.verfuegbarmitwechsel === 'Y')
timelineSectionElement.verfuegbarmitwechsel = nurAnreiseMoeglich_I
else if (timelineSectionElement.verfuegbarmitwechsel === nurAbreiseMoeglich_O)
timelineSectionElement.verfuegbarmitwechsel = 'W'
timelineSectionElement.vorgart.abreise = vorgangArt
}
else {
timelineSectionElement.wechsel = wederAnNochAbreiseMoeglich_X
timelineSectionElement.verfuegbarmitwechsel = 'N'
timelineSectionElement.vorgart.anreise = vorgangArt
timelineSectionElement.vorgart.abreise = vorgangArt
}
}
})
let switchline = ''
let anabreisemoeglichline = ''
let checkinoutline = ''
let availablelinewithswitch = ''
let bookingIds = []
Object.keys(timelineSection).forEach(timelineSegmentKey => {
const timelineSegmentElement = timelineSection[timelineSegmentKey]
switchline += timelineSegmentElement.wechsel
anabreisemoeglichline += timelineSegmentElement.anabreisemoeglich
checkinoutline += timelineSegmentElement.verfuegbarmitwechsel === 'W' ? 'N' : timelineSegmentElement.verfuegbarmitwechsel
availablelinewithswitch += timelineSegmentElement.verfuegbarmitwechsel
bookingIds.push(timelineSegmentElement.bookingId)
})
logThis(`this_is_switchline vor_lueckenbuchung_0: start: ${start.dateDe()} ${switchline}, mintage: ${mintage}, lueckenbuchungOk: ${lueckenbuchungOk} - ${switchline}`, task)
if (mintage > 1) {
let valideAnzahlNaechteAbDenenLueckenbuchungErlaubtIst = anzahlNaechteAbDenenLueckenbuchungErlaubtIst
if (valideAnzahlNaechteAbDenenLueckenbuchungErlaubtIst > mintage)
valideAnzahlNaechteAbDenenLueckenbuchungErlaubtIst = mintage
if (lueckenbuchungOk) {
switchline = schliesseLueckenDieKuerzerSindAlsMindestnaechteLuecke(valideAnzahlNaechteAbDenenLueckenbuchungErlaubtIst, switchline)
switchline = erlaubeNurAnAbreiseWennVollstaendigeLueckeGebuchtWird(mintage, switchline)
}
else {
switchline = deaktiviereAnAbreiseInnerhalbBereichenDieMintageLangSind(mintage, switchline)
const schliesseAlleLueckenDieKuerzerSindAlsMintage = mintage - 1
logThis(`this_is_switchline vor_lueckenbuchung_0b1: start: ${start.dateDe()}, mintage: ${mintage}, schliesseAlleLueckenDieKuerzerSindAlsMintage: ${schliesseAlleLueckenDieKuerzerSindAlsMintage}, length switchline: ${switchline.length} ${switchline}`, task)
switchline = schliesseLueckenDieKuerzerSindAlsMindestnaechte(schliesseAlleLueckenDieKuerzerSindAlsMintage, switchline)
}
logThis(`this_is_switchline vor_lueckenbuchung_1: start: ${start.dateDe()},${mintage} ${switchline}`, task)
switchline = setzeNaechsteMoeglicheAnAbreiseAufAnreiseWennBelegungAufNichtAnAbreisbaremTagEndet(switchline)
switchline = setzeLetzteMoeglicheAnAbreiseAufAbreiseWennBelegungAufNichtAnAbreisbaremTagBeginntInnerhalbSection(switchline)
logThis(`this_is_switchline vor_lueckenbuchung_2: start: ${start.dateDe()},${mintage} ${switchline}`, task)
switchline = setzeMindestnaechteNachAbreiseAufNurAnreiseOderNichtsAmSaisonuebergang(mintage, switchline)
logThis(`this_is_switchline vor_lueckenbuchung_3: start: ${start.dateDe()},${mintage} ${switchline}`, task)
switchline = setzeMindestnaechteVorAnreiseAufNurAbreiseOderNichtsAmSaisonuebergang(mintage, switchline)
}
logThis(`this_is_switchline vor_lueckenbuchung_4: start: ${start.dateDe()} ${switchline}`, task)
return {
timestamp: tsStart,
timelines: {
switchline: switchline,
anabreisemoeglichline: anabreisemoeglichline,
checkinoutline: checkinoutline,
availableline: checkinoutline.replace(/I/g, 'Y').replace(/O/g, 'N'),
availablelinewithswitch: availablelinewithswitch,
bookingIds,
},
}
},
erstelleBelegteZeitleisteMitBestimmterLaenge(length) {
return {
switchline: 'X'.repeat(length),
anabreisemoeglichline: 'X'.repeat(length),
checkinoutline: 'N'.repeat(length),
availableline: 'N'.repeat(length),
availablelinewithswitch: 'N'.repeat(length),
priceDetailsOnTimeline: {
maxPersonArr: [...Array(length).keys()].map(() => 1),
minStayArr: [...Array(length).keys()].map(() => 1),
minStayForGapArr: [...Array(length).keys()].map(() => 1),
gapBookingArr: [...Array(length).keys()].map(() => 0),
bookingIds: [...Array(length).keys()].map(() => ''),
},
}
},
}
}
function schliesseLueckenDieKuerzerSindAlsMindestnaechteLuecke(anzahlNaechteAbDenenLueckenbuchungErlaubtIst, switchline) {
if (anzahlNaechteAbDenenLueckenbuchungErlaubtIst <= 1)
return switchline
const anzahlNaechteAbDenenLueckenbuchungErlaubtIstOhneNachtZwischenIUndO = anzahlNaechteAbDenenLueckenbuchungErlaubtIst - 1
return schliesseLueckeWelcheKuerzerIstAlsNaechte(anzahlNaechteAbDenenLueckenbuchungErlaubtIstOhneNachtZwischenIUndO, switchline)
}
function schliesseLueckenDieKuerzerSindAlsMindestnaechte(anzahlMindestnaechteFuerAufenthalt, switchline) {
if (anzahlMindestnaechteFuerAufenthalt <= 1)
return switchline
return schliesseLueckeWelcheKuerzerIstAlsNaechte(anzahlMindestnaechteFuerAufenthalt, switchline)
}
function schliesseLueckeWelcheKuerzerIstAlsNaechte(anzahlMindestnaechteFuerAufenthalt, switchline) {
let anzahlMindestnaechteFuerAufenthaltOhneNachtZwischenIUndO = anzahlMindestnaechteFuerAufenthalt - 1
if (anzahlMindestnaechteFuerAufenthaltOhneNachtZwischenIUndO < 0)
anzahlMindestnaechteFuerAufenthaltOhneNachtZwischenIUndO = 0
const lueckenKuerzerAlsAnzahlNaechteAbDenenLueckenbuchungErlaubtIst = new RegExp(`IC{0,${anzahlMindestnaechteFuerAufenthaltOhneNachtZwischenIUndO}}O[IX]`, 'g')
return switchline.replace(lueckenKuerzerAlsAnzahlNaechteAbDenenLueckenbuchungErlaubtIst, match => {
let letztesZeichenVonMatch = match.substring(match.length - 1, match.length)
let restVonMatch = match.substring(0, match.length - 1)
return restVonMatch.replace(/[ICO]/g, wederAnNochAbreiseMoeglich_X) + letztesZeichenVonMatch
})
}
function erlaubeNurAnAbreiseWennVollstaendigeLueckeGebuchtWird(mintage, switchline) {
const lueckenDieMindestlaengeErfuellen = new RegExp('IC{1,' + (mintage - 1) + '}O', 'g')
return switchline.replace(lueckenDieMindestlaengeErfuellen, match => match.replace(/C/g, wederAnNochAbreiseMoeglich_X))
}
function deaktiviereAnAbreiseInnerhalbBereichenDieMintageLangSind(mintage, switchline) {
const lueckenDieMindestlaengeErfuellen = new RegExp('I[IC]{' + (mintage - 1) + '}O', 'g')
return switchline.replace(lueckenDieMindestlaengeErfuellen, match => {
let erstesZeichenVonMatch = match.substring(0, 1)
let restVonMatch = match.substring(1, match.length - 1)
let letztesZeichenVonMatch = match.substring(match.length - 1, match.length)
return erstesZeichenVonMatch + restVonMatch.replace(/[IC]/g, wederAnNochAbreiseMoeglich_X) + letztesZeichenVonMatch
})
}
function deaktiviereAnAbreiseInnerhalbBereichenDieMintageLangSindAnSaisonuebergaengenVorAnreisen(mintage, switchline) {
const pattern = 'I[ICO]{' + (mintage - 1) + '}O[IX]'
const lueckenDieMindestlaengeErfuellen = new RegExp(pattern, 'g')
return switchline.replace(lueckenDieMindestlaengeErfuellen, match => {
let erstesZeichenVonMatch = match.substring(0, 1)
let restVonMatch = match.substring(1, match.length - 2)
let letztesZeichenVonMatch = match.substring(match.length - 2, match.length)
return erstesZeichenVonMatch + restVonMatch.replace(/I/g, wederAnNochAbreiseMoeglich_X).replace(/C/g, nurAbreiseMoeglich_O) + letztesZeichenVonMatch
})
}
function setzeLetzteMoeglicheAnAbreiseAufAbreiseWennBelegungAufNichtAnAbreisbaremTagBeginnt(switchline) {
const lueckenDieMindestlaengeErfuellen = new RegExp('C[IX]*G', 'g')
return switchline.replace(lueckenDieMindestlaengeErfuellen, match => match.replace(/C/g, nurAbreiseMoeglich_O).replace(/[GI]/g, wederAnNochAbreiseMoeglich_X))
}
function setzeLetzteMoeglicheAnAbreiseAufAbreiseWennBelegungAufNichtAnAbreisbaremTagBeginntInnerhalbSection(switchline) {
const lueckenDieMindestlaengeErfuellen = new RegExp('C[IX]*G', 'g')
return switchline.replace(lueckenDieMindestlaengeErfuellen, match => match.replace(/C/g, nurAbreiseMoeglich_O).replace(/[GI]/g, wederAnNochAbreiseMoeglich_X))
}
function setzeNaechsteMoeglicheAnAbreiseAufAnreiseWennBelegungAufNichtAnAbreisbaremTagEndet(switchline) {
const lueckenDieMindestlaengeErfuellen = new RegExp('K[XO]*C', 'g')
return switchline.replace(lueckenDieMindestlaengeErfuellen, match => match.replace(/C/g, nurAnreiseMoeglich_I).replace(/[KO]/g, wederAnNochAbreiseMoeglich_X))
}
function ersetzeAlleGUndKDurchX(switchline) {
return switchline.replace(/[GK]/g, 'X')
}
function setzeMindestnaechteNachAbreiseAufNurAnreiseOderNichtsAmSaisonuebergang(mintage, switchline) {
const pattern = 'XI[XCOI]{1,' + (mintage - 1) + '}[IOC]'
const nachAbreise = new RegExp(pattern, 'g')
return switchline.replace(nachAbreise, match => {
const letztesZeichenVonMatch = match.substring(match.length - 1)
let restVonMatch = match.substring(0, match.length - 1)
restVonMatch = restVonMatch.replace(/C/g, nurAnreiseMoeglich_I).replace(/O/g, wederAnNochAbreiseMoeglich_X)
return restVonMatch + letztesZeichenVonMatch
})
}
function setzeMindestnaechteVorAnreiseAufNurAbreiseOderNichts(mintage, switchline) {
const checkInOutMoeglichVorAnreise = new RegExp('[ICO]{1,' + (mintage - 1) + '}OX', 'g')
return switchline.replace(checkInOutMoeglichVorAnreise, match => match.replace(/C/g, nurAbreiseMoeglich_O).replace(/I/g, wederAnNochAbreiseMoeglich_X))
}
function setzeMindestnaechteVorAnreiseAufNurAbreiseOderNichtsAmSaisonuebergang(mintage, switchline) {
const checkInOutMoeglichVorAnreise = new RegExp('[CO]{1,' + (mintage - 1) + '}OX', 'g')
return switchline.replace(checkInOutMoeglichVorAnreise, match => {
let restVonMatch = match.substring(0, match.length - 2)
const letzteZeichenVonMatch = match.substring(match.length - 2)
restVonMatch = restVonMatch.replace(/C/g, nurAbreiseMoeglich_O)
return restVonMatch + letzteZeichenVonMatch
})
}
async function getBelegungen(startUs, endUs, objid, memberid, task, moduleName) {
let sql = `(select 1 as reihenfolge, 'vorgang' as art, vorg_anreise, vorg_abreise, vorg_id, vorg_art, tl_fewo_vorgaenge.id from tl_fewo_vorgaenge where ((vorg_anreise between '${startUs}' and '${endUs}') or (vorg_abreise between '${startUs}' and '${endUs}') or (vorg_anreise <= '${startUs}' and vorg_abreise >= '${endUs}')) and vorg_ist_a_b_bl_e_o = 1 and vorg_objid = ${objid} and vorg_memberid = ${memberid})`
if (!task.memberdata || !task.memberdata.fewoversionmajor || task.memberdata.fewoversionmajor <= 20)
sql += ` union all (select 0 as reihenfolge, 'buchung' as art, ifnull(vorg_anreise, buch_anreise), ifnull(vorg_abreise, buch_abreise), tl_fewo_buchung.id, buch_vtyp, tl_fewo_buchung.id from tl_fewo_buchung left join tl_member on tl_member.id = buch_memberid left join tl_fewo_vorgaenge on tl_fewo_buchung.id = vorg_feondibuchid and buch_memberid = vorg_memberid where ((buch_anreise between '${startUs}' and '${endUs}') or (buch_abreise between '${startUs}' and '${endUs}') or (buch_anreise <= '${startUs}' and buch_abreise >= '${endUs}')) and buch_vtyp = 'B' and member_fewoversionmajor <= 20 and buch_fewostatus = -1 and buch_ssid != 10 and buch_objektid = ${objid} and buch_memberid = ${memberid})`
sql += ` union all (select 0 as reihenfolge, 'sofortbuchung' as art, ifnull(vorg_anreise, sbuch_anreise), ifnull(vorg_abreise, sbuch_abreise), sbuch_vorgid, sbuch_vtyp, t_sofortbuchung.id from t_sofortbuchung left join tl_fewo_vorgaenge on t_sofortbuchung.id = vorg_feondisofortbuchungsid and sbuch_memberid = vorg_memberid where ((sbuch_anreise between '${startUs}' and '${endUs}') or (sbuch_abreise between '${startUs}' and '${endUs}') or (sbuch_anreise <= '${startUs}' and sbuch_abreise >= '${endUs}')) and sbuch_vtyp = 'B' and sbuch_objektid = ${objid} and sbuch_memberid = ${memberid} and ((not exists (select tl_fewo_vorgaenge.id from tl_fewo_vorgaenge where vorg_feondisofortbuchungsid = t_sofortbuchung.id and vorg_memberid = sbuch_memberid)) or (not exists (select tl_fewo_vorgaenge.id from tl_fewo_vorgaenge where vorg_fremdid = sbuch_externebuchungsid and vorg_fremdid != '' and vorg_fremdid is not null and vorg_memberid = sbuch_memberid)) or (select max(coalesce(vorg_ist_a_b_bl_e_o, 0)) from tl_fewo_buchung left join tl_fewo_vorgaenge on vorg_feondibuchid = tl_fewo_buchung.id where buch_memberid = sbuch_memberid and buch_externebuchungsid = sbuch_externebuchungsid and buch_parameter1 = sbuch_parameter1 and buch_parameter2 = sbuch_parameter2 and vorg_objid = sbuch_objektid) = 1 or (select coalesce(max(vorg_ist_a_b_bl_e_o), 0) from tl_fewo_vorgaenge where vorg_feondisofortbuchungsid = t_sofortbuchung.id and vorg_memberid = sbuch_memberid and vorg_objid = sbuch_objektid) = 1))`
sql += ` order by vorg_anreise, reihenfolge`
return g.db.query(task, sql, moduleName)
}
module.exports = Timeline2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment