docparse-supplier-nge
Version:
process ngrid electric utility bill data for use in the docparse system
104 lines (95 loc) • 2.63 kB
JavaScript
var num = require('num');
var _ = require('underscore');
var inspect = require('eyespect').inspector({maxLength:20000000});
module.exports = function(text, cb) {
var lines = text.split(/[\r\n]+/);
var skipPattern = /Other Charges\/Adjustments/;
var totalPattern = /Total Other (?:(?:Charges)|(?:Credits)|(?:Adjustments))/i;
var totalLine = null;
lines = _.filter(lines, function(line) {
if (totalPattern.test(line)) {
totalLine = line;
return false;
}
if (skipPattern.test(line)) {
return false;
}
return true;
});
var costs = [];
var total = num(0);
_.each(lines, function(line) {
var cost = processLine(line);
if (cost) {
costs.push(cost);
total = total.add(cost.value);
}
});
if (!totalLine) {
return cb('total other charges line not found in other charges text');
}
var printedTotal = getCostOtherTotal(totalLine);
if (printedTotal === null) {
return cb('printed total other charges value not found in total other charges line text: ' + totalLine);
}
var match = doesPrintedTotalMatchCalculated(printedTotal, total);
if (!match) {
var errData = {
printedTotal: printedTotal,
calcTotal: total.toString(),
costs: costs
};
inspect(errData, 'printed total other cost does not match calculated total');
// use the printed charges
costs = [
{ description: 'Unabled to parse cost description',
value: printedTotal
}
]
total = num(printedTotal);
}
var output = {
costs: costs,
total: total.toString()
};
return cb(null, output);
};
function processLine(text) {
text = text.trim();
var pattern = /(.*?)(-?\d+\.?\d+)\s*$/;
var matches = text.match(pattern);
if (!matches || matches.length !== 3) {
inspect('wrong number of matches');
return null;
}
var description = matches[1].trim();
description = description.replace(/\s{2,}/, ' ');
var value = matches[2];
var output = {
description: description,
value: value
};
return output;
}
function getCostOtherTotal(text) {
text = text.replace(/\s/g, '');
var pattern = /.*?(-?\d+\.?\d+)$/;
var matches = text.match(pattern);
if (matches.length !== 2) {
inspect('wrong number of matches when gettting printed total other charges');
return null;
}
return matches[1];
}
function doesPrintedTotalMatchCalculated(printed, calc) {
if (calc.eq(printed)) {
return true;
}
var diff = calc.sub(printed);
var absoluteDiff = diff.abs();
var epsilon = num('0.1');
if (absoluteDiff.lte(epsilon)) {
return true;
}
return false;
}