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

435 lines (393 loc) 13.9 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('../timeStream'), streamForward = _require4.streamForward, streamBackward = _require4.streamBackward; var _require5 = require('../core/eventGeneration'), redefineTimeStartAndTimeSpan = _require5.redefineTimeStartAndTimeSpan; var _require6 = require('../core/dateUtility'), getRelevantDateSegmentByFrequency = _require6.getRelevantDateSegmentByFrequency; var _require7 = require('../constants'), DATE_FORMAT_STRING = _require7.DATE_FORMAT_STRING, WEEKLY = _require7.WEEKLY, ONCE = _require7.ONCE, EXECUTING_RULE_ADJUSTMENT = _require7.EXECUTING_RULE_ADJUSTMENT, MODIFIED = _require7.MODIFIED, EVENT_SOURCE = _require7.EVENT_SOURCE, OBSERVER_SOURCE = _require7.OBSERVER_SOURCE, BOTH = _require7.BOTH; var reusableLogicForDateMovements = function reusableLogicForDateMovements(_ref) { var danielSan = _ref.danielSan, event = _ref.event, specialAdjustment = _ref.specialAdjustment, streamForwardOrBackWard = _ref.streamForwardOrBackWard, date = _ref.date, dateArray = _ref.dateArray, frequency = _ref.frequency, skipTimeTravel = _ref.skipTimeTravel; var processPhase = EXECUTING_RULE_ADJUSTMENT; if (dateArray) { // note: timezone for "OBSERVER_SOURCE" is actually coming from the danielSan config. // Because that will be the final assigned timezone for the event. // even though the timezones for "EVENT_SOURCE" are coming from the event object, // their below dates are calcluated via the rule timezone data (which is still the original data as it hasn't changed to the converted timezone yet) var ruleContextLooperDate = date; var ruleContextLooperDateString = getRelevantDateSegmentByFrequency({ frequency: frequency, date: ruleContextLooperDate }); // note: the following 2 variables would only be used in OBSERVER_SOURCE or BOTH var observerContextLooperDate = convertTimeZone({ timeZone: danielSan.config.timeZone, timeZoneType: danielSan.config.timeZoneType, date: ruleContextLooperDate }); var observerContextLooperDateString = getRelevantDateSegmentByFrequency({ frequency: frequency, date: observerContextLooperDate.date }); /* conditions: EVENT_SOURCE / OBSERVER_SOURCE / BOTH */ if (isUndefinedOrNull(specialAdjustment.context) || specialAdjustment.context === EVENT_SOURCE) { while (dateArray.includes(ruleContextLooperDateString)) { ruleContextLooperDate = streamForwardOrBackWard(ruleContextLooperDate); event.dateStart = ruleContextLooperDate.format(DATE_FORMAT_STRING); redefineTimeStartAndTimeSpan({ event: event, skipTimeTravel: skipTimeTravel }); processPhase = MODIFIED; ruleContextLooperDate = createTimeZone({ timeZone: event.timeZone, timeZoneType: event.timeZoneType, dateString: event.dateStart, timeString: event.timeStart }); ruleContextLooperDateString = getRelevantDateSegmentByFrequency({ frequency: frequency, date: ruleContextLooperDate }); } } else if (specialAdjustment.context === OBSERVER_SOURCE) { while (dateArray.includes(observerContextLooperDateString)) { ruleContextLooperDate = streamForwardOrBackWard(ruleContextLooperDate); event.dateStart = ruleContextLooperDate.format(DATE_FORMAT_STRING); processPhase = MODIFIED; redefineTimeStartAndTimeSpan({ event: event, skipTimeTravel: skipTimeTravel }); ruleContextLooperDate = createTimeZone({ timeZone: event.timeZone, timeZoneType: event.timeZoneType, dateString: event.dateStart, timeString: event.timeStart }); observerContextLooperDate = convertTimeZone({ timeZone: danielSan.config.timeZone, timeZoneType: danielSan.config.timeZoneType, date: ruleContextLooperDate }); observerContextLooperDateString = getRelevantDateSegmentByFrequency({ frequency: frequency, date: observerContextLooperDate.date }); } } else if (specialAdjustment.context === BOTH) { while (dateArray.includes(observerContextLooperDateString) || dateArray.includes(ruleContextLooperDateString)) { ruleContextLooperDate = streamForwardOrBackWard(ruleContextLooperDate); event.dateStart = ruleContextLooperDate.format(DATE_FORMAT_STRING); processPhase = MODIFIED; redefineTimeStartAndTimeSpan({ event: event, skipTimeTravel: skipTimeTravel }); ruleContextLooperDate = createTimeZone({ timeZone: event.timeZone, timeZoneType: event.timeZoneType, dateString: event.dateStart, timeString: event.timeStart }); ruleContextLooperDateString = getRelevantDateSegmentByFrequency({ frequency: frequency, date: ruleContextLooperDate }); observerContextLooperDate = convertTimeZone({ timeZone: danielSan.config.timeZone, timeZoneType: danielSan.config.timeZoneType, date: ruleContextLooperDate }); observerContextLooperDateString = getRelevantDateSegmentByFrequency({ frequency: frequency, date: observerContextLooperDate.date }); } } } return processPhase; }; /* specialAdjustments: [ { type: MOVE_THIS_PROCESS_DATE_BEFORE_THESE_WEEKDAYS weekdays: [SATURDAY, SUNDAY] } ]; */ var moveThisProcessDateBeforeTheseWeekdays = function moveThisProcessDateBeforeTheseWeekdays(_ref2) { var danielSan = _ref2.danielSan, event = _ref2.event, specialAdjustment = _ref2.specialAdjustment, date = _ref2.date, skipTimeTravel = _ref2.skipTimeTravel; var processPhase; try { processPhase = reusableLogicForDateMovements({ danielSan: danielSan, event: event, specialAdjustment: specialAdjustment, streamForwardOrBackWard: streamBackward, date: date, dateArray: specialAdjustment.weekdays, frequency: WEEKLY, skipTimeTravel: skipTimeTravel }); return processPhase; } catch (err) { throw errorDisc({ err: err, data: { specialAdjustment: specialAdjustment, event: event, processPhase: processPhase, skipTimeTravel: skipTimeTravel } }); } }; /* specialAdjustments: [ { type: MOVE_THIS_PROCESS_DATE_AFTER_THESE_WEEKDAYS weekdays: [SATURDAY, SUNDAY] } ]; */ var moveThisProcessDateAfterTheseWeekdays = function moveThisProcessDateAfterTheseWeekdays(_ref3) { var danielSan = _ref3.danielSan, event = _ref3.event, specialAdjustment = _ref3.specialAdjustment, date = _ref3.date, skipTimeTravel = _ref3.skipTimeTravel; var processPhase; try { processPhase = reusableLogicForDateMovements({ danielSan: danielSan, event: event, specialAdjustment: specialAdjustment, streamForwardOrBackWard: streamForward, date: date, dateArray: specialAdjustment.weekdays, frequency: WEEKLY, skipTimeTravel: skipTimeTravel }); } catch (err) { throw errorDisc({ err: err, data: { specialAdjustment: specialAdjustment, event: event, processPhase: processPhase, skipTimeTravel: skipTimeTravel } }); } }; /* specialAdjustments: [ { type: MOVE_THIS_PROCESS_DATE_BEFORE_THESE_DATES, dates: ['2019-07-04', '2019-12-25'], weekdays: [SATURDAY, SUNDAY] // weekdays are optional } ] */ var moveThisProcessDateBeforeTheseDates = function moveThisProcessDateBeforeTheseDates(_ref4) { var danielSan = _ref4.danielSan, event = _ref4.event, specialAdjustment = _ref4.specialAdjustment, date = _ref4.date, skipTimeTravel = _ref4.skipTimeTravel; var processPhase; try { processPhase = EXECUTING_RULE_ADJUSTMENT; if (specialAdjustment.dates) { processPhase = reusableLogicForDateMovements({ danielSan: danielSan, event: event, specialAdjustment: specialAdjustment, streamForwardOrBackWard: streamBackward, date: date, dateArray: specialAdjustment.dates, frequency: ONCE, skipTimeTravel: skipTimeTravel }); } if (specialAdjustment.weekdays) { processPhase = moveThisProcessDateBeforeTheseWeekdays({ danielSan: danielSan, event: event, specialAdjustment: specialAdjustment, date: date, skipTimeTravel: skipTimeTravel }); if (processPhase === MODIFIED) { processPhase = moveThisProcessDateBeforeTheseDates({ danielSan: danielSan, event: event, specialAdjustment: specialAdjustment, date: date, skipTimeTravel: skipTimeTravel }); } } return processPhase; } catch (err) { throw errorDisc({ err: err, data: { specialAdjustment: specialAdjustment, event: event, processPhase: processPhase, skipTimeTravel: skipTimeTravel } }); } }; /* specialAdjustments: [ { type: MOVE_THIS_PROCESS_DATE_AFTER_THESE_DATES, dates: ['2019-07-04', '2019-12-25'], weekdays: [SATURDAY, SUNDAY] // weekdays are optional } ] */ var moveThisProcessDateAfterTheseDates = function moveThisProcessDateAfterTheseDates(_ref5) { var danielSan = _ref5.danielSan, event = _ref5.event, specialAdjustment = _ref5.specialAdjustment, date = _ref5.date, skipTimeTravel = _ref5.skipTimeTravel; var processPhase; try { processPhase = EXECUTING_RULE_ADJUSTMENT; if (specialAdjustment.dates) { processPhase = reusableLogicForDateMovements({ danielSan: danielSan, event: event, specialAdjustment: specialAdjustment, streamForwardOrBackWard: streamForward, date: date, dateArray: specialAdjustment.dates, frequency: ONCE, skipTimeTravel: skipTimeTravel }); } if (specialAdjustment.weekdays) { processPhase = moveThisProcessDateAfterTheseWeekdays({ danielSan: danielSan, event: event, specialAdjustment: specialAdjustment, date: date, skipTimeTravel: skipTimeTravel }); if (processPhase === MODIFIED) { processPhase = moveThisProcessDateAfterTheseDates({ danielSan: danielSan, event: event, specialAdjustment: specialAdjustment, date: date, skipTimeTravel: skipTimeTravel }); } } return processPhase; } catch (err) { throw errorDisc({ err: err, data: { specialAdjustment: specialAdjustment, event: event, processPhase: processPhase, skipTimeTravel: skipTimeTravel } }); } }; /* dates & amounts are parallel arrays specialAdjustments: [ { type: ADJUST_AMOUNT_ON_THESE_DATES, dates: [ '2019-06-01', '2019-09-01' ], amounts: [ 500000, 250000 ] } ] */ var adjustAmountOnTheseDates = function adjustAmountOnTheseDates(_ref6) { var danielSan = _ref6.danielSan, event = _ref6.event, specialAdjustment = _ref6.specialAdjustment; var processPhase = EXECUTING_RULE_ADJUSTMENT; var ruleContextLooperDateTracker; var looperDateIndexTracker; try { specialAdjustment.dates.forEach(function (ruleContextLooperDate, looperDateIndex) { ruleContextLooperDateTracker = ruleContextLooperDate; looperDateIndexTracker = looperDateIndex; if (ruleContextLooperDate === event.dateStart) { if (isUndefinedOrNull(specialAdjustment.context) || specialAdjustment.context === EVENT_SOURCE) { event.amount += specialAdjustment.amounts[looperDateIndex]; } else if (specialAdjustment.context === OBSERVER_SOURCE) { var adjustmentConverted = danielSan.config.currencySymbol && event.currencySymbol && danielSan.config.currencySymbol !== event.currencySymbol ? danielSan.config.currencyConversion({ amount: specialAdjustment.amounts[looperDateIndex], inputSymbol: danielSan.config.currencySymbol, outputSymbol: event.currencySymbol }) : specialAdjustment.amounts[looperDateIndex]; event.amount += adjustmentConverted; } processPhase = MODIFIED; } }); return processPhase; } catch (err) { throw errorDisc({ err: err, data: { specialAdjustment: specialAdjustment, event: event, processPhase: processPhase, ruleContextLooperDateTracker: ruleContextLooperDateTracker, looperDateIndexTracker: looperDateIndexTracker } }); } }; module.exports = { moveThisProcessDateAfterTheseWeekdays: moveThisProcessDateAfterTheseWeekdays, moveThisProcessDateAfterTheseDates: moveThisProcessDateAfterTheseDates, moveThisProcessDateBeforeTheseWeekdays: moveThisProcessDateBeforeTheseWeekdays, moveThisProcessDateBeforeTheseDates: moveThisProcessDateBeforeTheseDates, adjustAmountOnTheseDates: adjustAmountOnTheseDates };