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

194 lines (156 loc) 6.26 kB
"use strict"; var _require = require('../utility/errorHandling'), errorDisc = _require.errorDisc; var _require2 = require('../utility/validation'), isUndefinedOrNull = _require2.isUndefinedOrNull; var _require3 = require('../timeZone'), initializeTimeZoneData = _require3.initializeTimeZoneData, convertTimeZone = _require3.convertTimeZone; var _require4 = require('../core/dateUtility'), getRelevantDateSegmentByFrequency = _require4.getRelevantDateSegmentByFrequency; var _require5 = require('../modulusCycle/modulateCycleToDate'), modulateCycleUpToDate = _require5.modulateCycleUpToDate; var _require6 = require('../constants'), EVENT_SOURCE = _require6.EVENT_SOURCE, DAILY = _require6.DAILY, ONCE = _require6.ONCE, CURRENCY_DEFAULT = _require6.CURRENCY_DEFAULT, RULE = _require6.RULE; var validateConfig = function validateConfig(danielSan) { var errorMessage = null; if (isUndefinedOrNull(danielSan) || !Array.isArray(danielSan.rules) || danielSan.rules.length === 0) { errorMessage = 'expected a danielSan object with an array of rules'; } if (isUndefinedOrNull(danielSan.config.effectiveDateStart) || isUndefinedOrNull(danielSan.config.effectiveDateEnd)) { errorMessage = 'there is a problem with an effective date'; } if (danielSan.config.effectiveDateStart > danielSan.config.effectiveDateEnd) { errorMessage = 'effectiveDateStart cannot be greater than effectiveDateEnd'; } // to avoid unnecessary future checks to see if certain properties exist, we will add them with default values if (!danielSan.events) { danielSan.events = []; } if (!danielSan.discardedEvents) { danielSan.discardedEvents = []; } if (!danielSan.irrelevantRules) { danielSan.irrelevantRules = []; } if (!danielSan.retiredRuleIndices) { danielSan.retiredRuleIndices = []; } if (!danielSan.config.balanceBeginning) { danielSan.config.balanceBeginning = 0; } if (!danielSan.config) { danielSan.config = {}; } if (isUndefinedOrNull(danielSan.config.timeZoneType) || isUndefinedOrNull(danielSan.config.timeZone)) { var initialTimeZoneData = initializeTimeZoneData(danielSan); danielSan.config.timeZoneType = initialTimeZoneData.timeZoneType; danielSan.config.timeZone = initialTimeZoneData.timeZone; } if (isUndefinedOrNull(danielSan.config.currencyConversion)) { danielSan.config.currencyConversion = function (_ref) { var amount = _ref.amount; return amount; }; } if (isUndefinedOrNull(danielSan.config.currencySymbol)) { danielSan.config.currencySymbol = CURRENCY_DEFAULT; } else { danielSan.config.currencySymbol = danielSan.config.currencySymbol.toUpperCase(); } if (errorMessage) { throw errorDisc({ err: {}, errorMessage: errorMessage }); } }; var validateRules = function validateRules(_ref2) { var danielSan = _ref2.danielSan, date = _ref2.date, _ref2$skipTimeTravel = _ref2.skipTimeTravel, skipTimeTravel = _ref2$skipTimeTravel === void 0 ? null : _ref2$skipTimeTravel; var ruleTracker; // for errorDisc var indexTracker; // for errorDisc danielSan.rules.forEach(function (rule, index) { ruleTracker = rule; indexTracker = index; rule.context = EVENT_SOURCE; if (isUndefinedOrNull(rule.entityType)) { rule.entityType = RULE; // can be used to categorize if an object is a rule, event, or an aggregate } if (isUndefinedOrNull(rule.currencySymbol)) { rule.currencySymbol = CURRENCY_DEFAULT; } else { rule.currencySymbol = rule.currencySymbol.toUpperCase(); } // initialize timezone data if (isUndefinedOrNull(rule.timeZoneType) || isUndefinedOrNull(rule.timeZone)) { var initialTimeZoneData = initializeTimeZoneData(rule); rule.timeZoneType = danielSan.config.timeZoneType; // assign the danielSan config timeZoneType value to each rule rule.timeZone = initialTimeZoneData.timeZone; } try { if (!rule.modulus || !rule.cycle || rule.frequency === ONCE && !Array.isArray(rule.processDate)) { rule.modulus = null; rule.cycle = null; } else { // if we made it to this block of code then at least a modulus or cycle attribute is present // check for input errors to modulus/cycle attributes if (!rule.modulus) { rule.modulus = 1; } if (!rule.cycle) { rule.cycle = 1; } // if there is an effectiveDateStart without an anchorSyncDate, then just assign it to the anchorSyncDate if (!rule.anchorSyncDate && rule.effectiveDateStart) { rule.anchorSyncDate = rule.effectiveDateStart; } var convertedDate = convertTimeZone({ timeZone: rule.timeZone, timeZoneType: rule.timeZoneType, date: date }).date; var effectiveDateStartString = getRelevantDateSegmentByFrequency({ frequency: ONCE, date: convertedDate }); // if the following condition is not true, there is no reason to modify the modulus cycle // eslint-disable-next-line no-lonely-if if (rule.anchorSyncDate && rule.anchorSyncDate !== effectiveDateStartString) { if (rule.anchorSyncDate > effectiveDateStartString) { // pre-modulation is not necessary here since we will simply start the cycle in the future rule.effectiveDateStart = rule.anchorSyncDate; // future date rule.anchorSyncDate = null; } else { rule.effectiveDateStart = null; modulateCycleUpToDate({ danielSan: danielSan, rule: rule, effectiveDateStartString: effectiveDateStartString, skipTimeTravel: skipTimeTravel }); } } } if (rule.frequency === DAILY) { rule.processDate = null; } } catch (err) { throw errorDisc({ err: err, data: { date: date, rule: ruleTracker, indexTracker: indexTracker, skipTimeTravel: skipTimeTravel } }); } }); }; module.exports = { validateConfig: validateConfig, validateRules: validateRules };