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
JavaScript
"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
};