Created
July 20, 2023 14:11
-
-
Save maximilianfixl/b2b8896ea614dc1d049504782cdfb5a5 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| '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