UNPKG

@fcgs/filerr-nach

Version:

nACH is a highly customizable Node.js module exposing a high & low-level API for generating ACH files for use within the ACH network

153 lines (130 loc) 5.63 kB
//TODO: Maybe validate position with indexes var _ = require('lodash') , utils = require('./utils') , nACHError = require('./error') , ACHAddendaTypeCodes = ['02', '05', '98', '99'] , ACHTransactionCodes = ['22', '23', '24', '27', '28', '29', '32', '33', '34', '37', '38', '39'] , ACHServiceClassCodes = ['200', '220', '225'] , numericRegex = /^[0-9]+$/ , alphaRegex = /^[a-zA-Z]+$/ , alphanumericRegex = /^[0-9a-zA-Z!"#$%&'()*+,-.\/:;<>=?@\[\]\\^_`{}|~ ]+$/ , array , sum; // Validate required fields to make sure they have values function validateRequiredFields(object) { _.forEach(object, function(field) { // This check ensures a required field's value is not NaN, null, undefined or empty. Zero is valid, but the data type check will make sure any fields with 0 are numeric. if (field.required === true && (_.isNaN(field.value) || _.isNull(field.value) || _.isUndefined(field.value) || field.value.toString().length === 0)) { throw new nACHError({ name: 'Required Field Blank', message: field.name + ' is a required field but its value is: ' + field.value }); } }); return true; } // Validate the lengths of fields by using their `width` property function validateLengths(object) { _.forEach(object, function(field) { if (field.value.toString().length > field.width) { throw new nACHError({ name: 'Invalid Length', message: field.name + '\'s length is ' + field.value.length + ', but it should be no greater than ' + field.width + '.' }); } }); return true; } function getNextMultipleDiff(value, multiple) { return (value + (multiple - value % multiple)) - value; } // Validate the data given is of the correct ACH data type function validateDataTypes(object) { _.forEach(object, function(field) { if (field.blank !== true) { switch (field.type) { case 'numeric': utils.testRegex(numericRegex, field); break; case 'alpha': utils.testRegex(alphaRegex, field); break; case 'alphanumeric': utils.testRegex(alphanumericRegex, field); break; } } }); return true; } function validateACHAddendaTypeCode(addendaTypeCode) { if (addendaTypeCode.length !== 2 || !_.includes(ACHAddendaTypeCodes, addendaTypeCode)) { throw new nACHError({ name: 'ACH Addenda Type Code Error', message: 'The ACH addenda type code ' + addendaTypeCode + ' is invalid. Please pass a valid 2-digit addenda type code.' }); } return true; } // Insure a given transaction code is valid function validateACHCode(transactionCode) { if (transactionCode.length !== 2 || !_.includes(ACHTransactionCodes, transactionCode)) { throw new nACHError({ name: 'ACH Transaction Code Error', message: 'The ACH transaction code ' + transactionCode + ' is invalid. Please pass a valid 2-digit transaction code.' }); } return true; } // Insure a given transaction code is valid function validateACHAddendaCode(transactionCode) { // if (transactionCode.length !== 2 || !_.includes(ACHTransactionCodes, transactionCode)) { // throw new nACHError({ // name: 'ACH Transaction Code Error', // message: 'The ACH transaction code ' + transactionCode + ' is invalid for addenda records. Please pass a valid 2-digit transaction code.' // }); // } return true; } function validateACHServiceClassCode(serviceClassCode) { if (serviceClassCode.length !== 3 || !_.includes(ACHServiceClassCodes, serviceClassCode)) { throw new nACHError({ name: 'ACH Service Class Code Error', message: 'The ACH service class code ' + serviceClassCode + ' is invalid. Please pass a valid 3-digit service class code.' }); } return true; } function validateRoutingNumber(routing) { // Make sure the routing number is exactly 9-digits long if (routing.toString().length !== 9) { throw new nACHError({ name: 'Invalid ABA Number Length', message: 'The ABA routing number ' + routing + ' is ' + routing.toString().length + '-digits long, but it should be 9-digits long.' }); } // Split the routing number into an array of numbers. `array` will look like this: `[2,8,1,0,8,1,4,7,9]`. array = routing.split('').map(Number); // Validate the routing number (ABA). See here for more info: http://www.brainjar.com/js/validation/ sum = 3 * (array[0] + array[3] + array[6]) + 7 * (array[1] + array[4] + array[7]) + 1 * (array[2] + array[5] + array[8]); // Throw an error if the the result of `sum` modulo 10 is not zero. The value of `sum` must be a multiple of 10 to be a valid routing number. if (sum % 10 !== 0) { throw new nACHError({ name: 'Invalid ABA Number', message: 'The ABA routing number ' + routing + ' is invalid. Please ensure a valid 9-digit ABA routing number is passed.' }); } return true; } module.exports.validateRequiredFields = validateRequiredFields; module.exports.validateLengths = validateLengths; module.exports.validateDataTypes = validateDataTypes; module.exports.validateACHAddendaTypeCode = validateACHAddendaTypeCode; module.exports.validateACHCode = validateACHCode; module.exports.validateACHAddendaCode = validateACHAddendaCode; module.exports.validateACHServiceClassCode = validateACHServiceClassCode; module.exports.validateRoutingNumber = validateRoutingNumber; module.exports.getNextMultipleDiff = getNextMultipleDiff;