UNPKG

daniel-san

Version:

a node-based budget-projection engine that helps your routines and finances find balance. The program features aggregates, terminal and file-based reporting output, multi-currency conversion capability and multi-frequency accounting triggers, including: o

246 lines (212 loc) 8.39 kB
"use strict"; var _require = require('../utility/errorHandling'), errorDisc = _require.errorDisc; var _require2 = require('../utility/validation'), isUndefinedOrNull = _require2.isUndefinedOrNull; var _require3 = require('../timeZone'), createTimeZone = _require3.createTimeZone, convertTimeZone = _require3.convertTimeZone; var _require4 = require('./dateUtility'), getRelevantDateSegmentByFrequency = _require4.getRelevantDateSegmentByFrequency; var _require5 = require('../analytics'), findIrrelevantRules = _require5.findIrrelevantRules; var _require6 = require('../constants'), EVENT_SOURCE = _require6.EVENT_SOURCE, OBSERVER_SOURCE = _require6.OBSERVER_SOURCE, BOTH = _require6.BOTH, DATE_FORMAT_STRING = _require6.DATE_FORMAT_STRING, EXECUTION_REJECTED = _require6.EXECUTION_REJECTED, ONCE = _require6.ONCE; // flags a rule that is no longer relevant for active budget-projection calculations var flagRuleForRetirement = function flagRuleForRetirement(_ref) { var danielSan = _ref.danielSan, rule = _ref.rule, date = _ref.date, index = _ref.index; try { // if effectiveDateEnd has been reached, flag the rule for retirement var dateString = date.format(DATE_FORMAT_STRING); if (!isUndefinedOrNull(rule.effectiveDateEnd) && dateString >= rule.effectiveDateEnd || rule.frequency === ONCE && typeof rule.processDate === 'string' && dateString >= rule.processDate) { danielSan.retiredRuleIndices.push(index); } } catch (err) { throw errorDisc({ err: err, data: { rule: rule, date: date, index: index } }); } }; // retires rules that were flagged in flagRuleForRetirement() var retireRules = function retireRules(danielSan) { var looper; try { // retire obsolete rules if (danielSan.retiredRuleIndices.length > 0) { // optimize later - but this works var newRules = []; danielSan.rules.forEach(function (rule, index) { if (!danielSan.retiredRuleIndices.includes(index)) { newRules.push(rule); } }); danielSan.rules = [].concat(newRules); danielSan.retiredRuleIndices = []; // reset retiredRuleIndices } } catch (err) { throw errorDisc({ err: err, data: { retiredRuleIndices: danielSan.retiredRuleIndices, looper: looper } }); } }; // returns/removes rules that have no chance ot being included into a projected event var seekAndDestroyIrrelevantRules = function seekAndDestroyIrrelevantRules(danielSan) { var _findIrrelevantRules = findIrrelevantRules(danielSan), relevantRules = _findIrrelevantRules.relevantRules, irrelevantRules = _findIrrelevantRules.irrelevantRules; danielSan.rules = relevantRules; // remove irrelevantRules from the danielSan reference return irrelevantRules; // return irrelevantRules if needed }; var deleteIrrelevantRules = function deleteIrrelevantRules(danielSan) { try { var irrelevantRules = seekAndDestroyIrrelevantRules(danielSan); danielSan.irrelevantRules = irrelevantRules; } catch (err) { throw errorDisc({ err: err }); } }; var discardEventsOutsideDateRange = function discardEventsOutsideDateRange(danielSan) { var _danielSan$config = danielSan.config, effectiveDateStart = _danielSan$config.effectiveDateStart, timeStart = _danielSan$config.timeStart, effectiveDateEnd = _danielSan$config.effectiveDateEnd, timeEnd = _danielSan$config.timeEnd, timeZone = _danielSan$config.timeZone, timeZoneType = _danielSan$config.timeZoneType; var eventsToDiscard = []; var newEventList = []; danielSan.events.forEach(function (event) { var dateToStart = createTimeZone({ timeZone: timeZone, timeZoneType: timeZoneType, dateString: effectiveDateStart, timeString: timeStart }); var eventDateStart = createTimeZone({ timeZone: timeZone, timeZoneType: timeZoneType, dateString: event.dateStart, timeString: event.timeStart }); var dateToEnd = createTimeZone({ timeZone: timeZone, timeZoneType: timeZoneType, dateString: effectiveDateEnd, timeString: timeEnd || timeStart }); if (eventDateStart.isBefore(dateToStart) || eventDateStart.isAfter(dateToEnd)) { eventsToDiscard.push(event); } else { newEventList.push(event); } }); danielSan.discardedEvents = eventsToDiscard; // we only need to re-reference danielSan.events if we are discarding anything if (eventsToDiscard.length > 0) { danielSan.events = newEventList; } }; /* exclusions: { weekdays: [SATURDAY, SUNDAY], dates: ['2019-07-04', '2019-09-17', '2019-10-31'] } */ var exclusionsPhase = function exclusionsPhase(_ref2) { var danielSan = _ref2.danielSan, rule = _ref2.rule, date = _ref2.date, processPhase = _ref2.processPhase; var transientProcessPhase; try { transientProcessPhase = processPhase || ''; if (rule.exclusions) { // eslint-disable-next-line no-unused-vars var relevantDateSegmentForExclusion; var dynamicDateSegmentForExclusion; var anyMatch = false; if (rule.exclusions.weekdays) { if (isUndefinedOrNull(rule.exclusions.context) || rule.exclusions.context === EVENT_SOURCE || rule.exclusions.context === BOTH) { relevantDateSegmentForExclusion = date.day(); anyMatch = rule.exclusions.weekdays.some(function (eventDate) { dynamicDateSegmentForExclusion = eventDate; // eslint-disable-next-line eqeqeq return dynamicDateSegmentForExclusion === relevantDateSegmentForExclusion; }); } else if (rule.exclusions.context === OBSERVER_SOURCE || rule.exclusions.context === BOTH) { var convertedDate = convertTimeZone({ timeZone: danielSan.config.timeZone, timeZoneType: danielSan.config.timeZoneType, date: date }); relevantDateSegmentForExclusion = convertedDate.day(); anyMatch = rule.exclusions.weekdays.some(function (eventDate) { dynamicDateSegmentForExclusion = eventDate; // eslint-disable-next-line eqeqeq return dynamicDateSegmentForExclusion === relevantDateSegmentForExclusion; }); } if (anyMatch) transientProcessPhase = EXECUTION_REJECTED; } if (rule.exclusions.dates && transientProcessPhase !== EXECUTION_REJECTED) { if (isUndefinedOrNull(rule.exclusions.context) || rule.exclusions.context === EVENT_SOURCE || rule.exclusions.context === BOTH) { relevantDateSegmentForExclusion = getRelevantDateSegmentByFrequency({ frequency: ONCE, date: date }); anyMatch = rule.exclusions.dates.some(function (eventDate) { dynamicDateSegmentForExclusion = eventDate; return dynamicDateSegmentForExclusion === relevantDateSegmentForExclusion; }); } else if (rule.exclusions.context === OBSERVER_SOURCE || rule.exclusions.context === BOTH) { var _convertedDate = convertTimeZone({ timeZone: danielSan.config.timeZone, timeZoneType: danielSan.config.timeZoneType, date: date }); relevantDateSegmentForExclusion = getRelevantDateSegmentByFrequency({ frequency: ONCE, date: _convertedDate }); anyMatch = rule.exclusions.dates.some(function (eventDate) { dynamicDateSegmentForExclusion = eventDate; return dynamicDateSegmentForExclusion === relevantDateSegmentForExclusion; }); } if (anyMatch) transientProcessPhase = EXECUTION_REJECTED; } } return transientProcessPhase; } catch (err) { throw errorDisc({ err: err, data: { rule: rule, date: date, processPhase: processPhase, transientProcessPhase: transientProcessPhase } }); } }; module.exports = { flagRuleForRetirement: flagRuleForRetirement, retireRules: retireRules, seekAndDestroyIrrelevantRules: seekAndDestroyIrrelevantRules, deleteIrrelevantRules: deleteIrrelevantRules, discardEventsOutsideDateRange: discardEventsOutsideDateRange, exclusionsPhase: exclusionsPhase };