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
301 lines (261 loc) • 8.6 kB
JavaScript
"use strict";
var _require = require('../utility/errorHandling'),
errorDisc = _require.errorDisc;
var _require2 = require('../timeZone'),
createTimeZone = _require2.createTimeZone;
var _require3 = require('../timeStream'),
streamForward = _require3.streamForward;
var _require4 = require('../core/eventGeneration'),
generateEvent = _require4.generateEvent;
var _require5 = require('../modulusCycle'),
modulusPhase = _require5.modulusPhase;
var _require6 = require('../core/obliterate'),
exclusionsPhase = _require6.exclusionsPhase;
var _require7 = require('../core/dateUtility'),
getRelevantDateSegmentByFrequency = _require7.getRelevantDateSegmentByFrequency;
var _require8 = require('../constants'),
EVALUATING_RULE_INSERTION = _require8.EVALUATING_RULE_INSERTION,
EXECUTING_RULE_INSERTION = _require8.EXECUTING_RULE_INSERTION,
DATE_FORMAT_STRING = _require8.DATE_FORMAT_STRING,
WEEKLY = _require8.WEEKLY,
MONTHLY = _require8.MONTHLY,
SUNDAY = _require8.SUNDAY,
MONDAY = _require8.MONDAY,
TUESDAY = _require8.TUESDAY,
WEDNESDAY = _require8.WEDNESDAY,
THURSDAY = _require8.THURSDAY,
FRIDAY = _require8.FRIDAY,
SATURDAY = _require8.SATURDAY;
/*
0 = Sunday
6 = Saturday
*/
var findAllWeekdaysInTheMonth = function findAllWeekdaysInTheMonth(_ref) {
var date = _ref.date,
timeZone = _ref.timeZone,
timeZoneType = _ref.timeZoneType;
try {
var monthlyWeekdayConstruct = {
0: [],
1: [],
2: [],
3: [],
4: [],
5: [],
6: []
};
var startOfMonth = createTimeZone({
timeZone: timeZone,
timeZoneType: timeZoneType,
date: date
}).startOf('month');
var endOfMonth = createTimeZone({
timeZone: timeZone,
timeZoneType: timeZoneType,
date: date
}).endOf('month');
var processThisLooperDate = function processThisLooperDate(thisLooperDate) {
try {
var thisWeekday = getRelevantDateSegmentByFrequency({
frequency: WEEKLY,
date: thisLooperDate
});
switch (thisWeekday) {
case SUNDAY:
monthlyWeekdayConstruct[SUNDAY].push(thisLooperDate.format(DATE_FORMAT_STRING));
break;
case MONDAY:
monthlyWeekdayConstruct[MONDAY].push(thisLooperDate.format(DATE_FORMAT_STRING));
break;
case TUESDAY:
monthlyWeekdayConstruct[TUESDAY].push(thisLooperDate.format(DATE_FORMAT_STRING));
break;
case WEDNESDAY:
monthlyWeekdayConstruct[WEDNESDAY].push(thisLooperDate.format(DATE_FORMAT_STRING));
break;
case THURSDAY:
monthlyWeekdayConstruct[THURSDAY].push(thisLooperDate.format(DATE_FORMAT_STRING));
break;
case FRIDAY:
monthlyWeekdayConstruct[FRIDAY].push(thisLooperDate.format(DATE_FORMAT_STRING));
break;
case SATURDAY:
monthlyWeekdayConstruct[SATURDAY].push(thisLooperDate.format(DATE_FORMAT_STRING));
break;
default:
break;
}
} catch (err) {
throw errorDisc({
err: err,
data: {
thisLooperDate: thisLooperDate
}
});
}
};
var looperDate = startOfMonth;
do {
processThisLooperDate(looperDate);
looperDate = streamForward(looperDate);
} while (looperDate.format(DATE_FORMAT_STRING) !== endOfMonth.format(DATE_FORMAT_STRING));
processThisLooperDate(looperDate); // this execution is for the last day of the month
return monthlyWeekdayConstruct;
} catch (err) {
throw errorDisc({
err: err,
data: {
date: date,
timeZone: timeZone,
timeZoneType: timeZoneType
}
});
}
};
/*
frequency = [
{ rank: 1, weekday: FRIDAY },
{ rank: 3, weekday: FRIDAY }
{ rank: -1, weekday: SUNDAY } // a negative rank means the last occurence of the month
];
*/
var nthWeekdaysOfMonth = function nthWeekdaysOfMonth(_ref2) {
var danielSan = _ref2.danielSan,
rule = _ref2.rule,
date = _ref2.date,
skipTimeTravel = _ref2.skipTimeTravel,
_ref2$eventGen = _ref2.eventGen,
eventGen = _ref2$eventGen === void 0 ? true : _ref2$eventGen;
var processPhase = EVALUATING_RULE_INSERTION;
var nthProcessDayTracker;
var looperDateTracker;
var looperDateIndexTracker;
try {
var nthProcessDays = Array.isArray(rule.frequency) ? rule.frequency : [];
var weekdaysInMonth = findAllWeekdaysInTheMonth({
date: date,
timeZone: rule.timeZone,
timeZoneType: rule.timeZoneType
});
nthProcessDays.some(function (nthProcessDay) {
nthProcessDayTracker = nthProcessDay;
var objectKey = nthProcessDay.weekday;
var sizeOfObjectKeyArray = weekdaysInMonth[objectKey].length;
weekdaysInMonth[objectKey].forEach(function (looperDate, looperDateIndex) {
looperDateTracker = looperDate;
looperDateIndexTracker = looperDateIndex;
processPhase = EVALUATING_RULE_INSERTION;
if (date.format(DATE_FORMAT_STRING) === looperDate && (nthProcessDay.rank === looperDateIndex + 1 || nthProcessDay.rank === 0 || nthProcessDay.rank < 0 && looperDateIndex === sizeOfObjectKeyArray - 1)) {
processPhase = exclusionsPhase({
danielSan: danielSan,
rule: rule,
date: date,
processPhase: processPhase
});
processPhase = modulusPhase({
rule: rule,
processPhase: processPhase
});
if (processPhase === EXECUTING_RULE_INSERTION) {
// when we are pre-modulating the cycle during validation, we do not want to generate an event
if (eventGen) {
processPhase = generateEvent({
danielSan: danielSan,
rule: rule,
date: date,
skipTimeTravel: skipTimeTravel
});
}
return true;
}
} else {
return false;
}
});
});
return processPhase;
} catch (err) {
throw errorDisc({
err: err,
data: {
rule: rule,
date: date,
processPhase: processPhase,
nthProcessDayTracker: nthProcessDayTracker,
looperDateTracker: looperDateTracker,
looperDateIndexTracker: looperDateIndexTracker,
skipTimeTravel: skipTimeTravel,
eventGen: eventGen
}
});
}
};
/*
frequency: FRIDAY,
processDate: '13',
*/
var weekdayOnDate = function weekdayOnDate(_ref3) {
var danielSan = _ref3.danielSan,
rule = _ref3.rule,
date = _ref3.date,
skipTimeTravel = _ref3.skipTimeTravel,
_ref3$eventGen = _ref3.eventGen,
eventGen = _ref3$eventGen === void 0 ? true : _ref3$eventGen;
var processPhase = EVALUATING_RULE_INSERTION;
try {
var thisProcessDate = getRelevantDateSegmentByFrequency({
frequency: MONTHLY,
date: date
});
var thisWeekday = getRelevantDateSegmentByFrequency({
frequency: WEEKLY,
date: date
});
if (Array.isArray(rule.frequency)) {
rule.frequency.some(function (element) {
if (element.processDate === thisProcessDate && element.weekday === thisWeekday) {
processPhase = exclusionsPhase({
danielSan: danielSan,
rule: rule,
date: date,
processPhase: processPhase
});
processPhase = modulusPhase({
rule: rule,
processPhase: processPhase
});
if (processPhase === EXECUTING_RULE_INSERTION) {
// when we are pre-modulating the cycle during validation, we do not want to generate an event
if (eventGen) {
processPhase = generateEvent({
danielSan: danielSan,
rule: rule,
date: date,
skipTimeTravel: skipTimeTravel
});
}
return true; // eslint-disable-next-line no-else-return
} else {
return false;
}
}
});
}
return processPhase;
} catch (err) {
throw errorDisc({
err: err,
data: {
rule: rule,
date: date,
processPhase: processPhase,
skipTimeTravel: skipTimeTravel,
eventGen: eventGen
}
});
}
};
module.exports = {
nthWeekdaysOfMonth: nthWeekdaysOfMonth,
weekdayOnDate: weekdayOnDate
};