Skip to content

Commit

Permalink
Removed per-field validation (we will handle this in our app), correc…
Browse files Browse the repository at this point in the history
…ted typos, made some fields conditional.
  • Loading branch information
JamesLefrere committed Aug 19, 2016
1 parent d428c67 commit 075025b
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 146 deletions.
157 changes: 14 additions & 143 deletions lib/sepa.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
* SEPA.validateCreditorID -- function to validate a creditor id
* SEPA.checksumCreditorID -- function to calculate the creditor id checksum
* SEPA.setIDSeparator -- function to customize the ID separator when needed (defaults to '.')
* SEPA.enableValidations -- function to enable/disable fields validation
*/
(function(exports) {
var XSI_NAMESPACE = 'http://www.w3.org/2001/XMLSchema-instance';
Expand All @@ -25,11 +24,6 @@
ID_SEPARATOR = seperator;
}

var VALIDATIONS_ENABLED = true;
function enableValidations(enabled) {
VALIDATIONS_ENABLED = !!enabled;
}

var SEPATypes = {
'pain.001.001.02': 'pain.001.001.02',
'pain.001.003.02': 'pain.001.003.02',
Expand Down Expand Up @@ -66,6 +60,7 @@
/** Payment Info array */
_paymentInfo: [],

/** SEPA Document type setting, contains the root element */
/** SEPA Document type setting, contains the root element */
_type: null,

Expand Down Expand Up @@ -123,9 +118,8 @@
var doc = createDocument(docNS, 'Document');
var body = doc.documentElement;

body.setAttributeNS(XSI_NAMESPACE, 'xmlns', XSI_NS + this._painFormat);
body.setAttributeNS(XSI_NAMESPACE, 'xmlns:xsi', XSI_NAMESPACE);
body.setAttributeNS(XSI_NAMESPACE, 'xsi:schemaLocation', XSI_NS + this._painFormat + ' ' + this._painFormat + '.xsd');
body.setAttributeNS(XSI_NAMESPACE, 'xsi:schemaLocation', XSI_NS +
this._painFormat + ' ' + this._painFormat + '.xsd');
var rootElement = doc.createElementNS(docNS, this._type);

rootElement.appendChild(this.grpHdr.toXML(doc));
Expand Down Expand Up @@ -247,7 +241,7 @@
* 'COR1' - Expedited Transfer
* 'B2B' - Business Transfer
*/
localInstrumentation: 'CORE',
localInstrumentation: null,

/**
* 'FRST' - First transfer
Expand Down Expand Up @@ -328,44 +322,12 @@
return new SepaTransaction(this._painFormat);
},

validate: function() {
// TODO consider using getters/setters instead
var pullFrom = this.method === PaymentInfoTypes.DirectDebit ? 'creditor' : 'debtor';

assert_fixed(this.localInstrumentation, ['CORE', 'COR1', 'B2B'], 'localInstrumentation');
assert_fixed(this.sequenceType, ['FRST', 'RCUR', 'OOFF', 'FNAL'], 'sequenceType');

if (this.method === PaymentInfoTypes.DirectDebit) {
assert_date(this.collectionDate, 'collectionDate');
}
else {
assert_date(this.requestedExecutionDate, 'requestedExecutionDate');
}

assert_cid(this[pullFrom + 'Id'], pullFrom + 'Id');

assert_length(this[pullFrom + 'Name'], null, 70, pullFrom + 'Name');
assert_length(this[pullFrom + 'Street'], null, 70, pullFrom + 'Street');
assert_length(this[pullFrom + 'City'], null, 70, pullFrom + 'City');
assert_length(this[pullFrom + 'Country'], null, 2, pullFrom + 'Country');
assert_iban(this[pullFrom + 'IBAN'], pullFrom + 'IBAN');
assert_length(this[pullFrom + 'BIC'], [0,8,11], pullFrom + 'BIC');
var countryMatches = (this[pullFrom + 'BIC'].length === 0 || this[pullFrom + 'BIC'].substr(4, 2) === this[pullFrom + 'IBAN'].substr(0, 2));
assert(countryMatches, 'country mismatch in BIC/IBAN');

assert_length(this._payments.length, 1, null, '_payments');
},

/*
* Serialize this document to a DOM Element.
*
* @return The DOM <PmtInf> Element.
*/
toXML: function(doc) {
if (VALIDATIONS_ENABLED) {
this.validate();
}

var n = createXMLHelper(doc, true, false);
//var o = createXMLHelper(doc, false, true);
var r = createXMLHelper(doc, true, true);
Expand All @@ -382,7 +344,9 @@

var pmtTpInf = n(pmtInf, 'PmtTpInf');
r(pmtTpInf, 'SvcLvl', 'Cd', 'SEPA');
r(pmtTpInf, 'LclInstrm', 'Cd', this.localInstrumentation);
if (this.localInstrumentation) {
r(pmtTpInf, 'LclInstrm', 'Cd', this.localInstrumentation);
}

if (this.method === PaymentInfoTypes.DirectDebit) {
r(pmtTpInf, 'SeqTp', this.sequenceType);
Expand Down Expand Up @@ -495,35 +459,9 @@
creditorIBAN: '',
creditorBIC: '',

validate: function() {
var pullFrom = this._type === TransactionTypes.Transfer ? 'creditor' : 'debtor';

assert_sepa_id_set1(this.end2endId, 'end2endId');
assert_range(this.amount, 0.01, 999999999.99, 'amount');
assert(this.amount == this.amount.toFixed(2), 'amount has too many fractional digits');
assert_length(this.purposeCode, 1, 4, 'purposeCode');
assert_sepa_id_set2(this.mandateId, 'mandateId');
assert_date(this.mandateSignatureDate, 'mandateSignatureDate');

assert_length(this[pullFrom + 'Name'], null, 70, pullFrom + 'Name');
assert_length(this[pullFrom + 'Street'], null, 70, pullFrom + 'Street');
assert_length(this[pullFrom + 'City'], null, 70, pullFrom + 'City');
assert_length(this[pullFrom + 'Country'], null, 2, pullFrom + 'Country');
assert_iban(this[pullFrom + 'IBAN'], pullFrom + 'IBAN');
assert_fixed(this[pullFrom + 'BIC'].length, [0, 8, 11], pullFrom + 'BIC');
var countryMatches = (this[pullFrom + 'BIC'].length === 0 || this[pullFrom + 'BIC'].substr(4, 2) === this[pullFrom + 'IBAN'].substr(0, 2));
assert(countryMatches, 'country mismatch in BIC/IBAN');

assert_length(this.remittanceInfo, null, 140, 'remittanceInfo');
},

toXML: function(doc) {
if (VALIDATIONS_ENABLED) {
this.validate();
}

var pullFrom = this._type === TransactionTypes.Transfer ? 'creditor' : 'debtor';
var recieverNodeName = this._type === TransactionTypes.Transfer ? 'Cdtr' : 'Dbtr';
var receiverNodeName = this._type === TransactionTypes.Transfer ? 'Cdtr' : 'Dbtr';

var n = createXMLHelper(doc, true, false);
var o = createXMLHelper(doc, false, true);
Expand Down Expand Up @@ -554,22 +492,22 @@
}

if (this[pullFrom + 'BIC']) {
r(txInf, recieverNodeName + 'Agt', 'FinInstnId', 'BIC', this[pullFrom + 'BIC']);
r(txInf, receiverNodeName + 'Agt', 'FinInstnId', 'BIC', this[pullFrom + 'BIC']);
} else {
r(txInf, recieverNodeName + 'Agt', 'FinInstnId', 'Othr', 'Id', 'NOTPROVIDED');
r(txInf, receiverNodeName + 'Agt', 'FinInstnId', 'Othr', 'Id', 'NOTPROVIDED');
}

var reciever = n(txInf, recieverNodeName);
r(reciever, 'Nm', this[pullFrom + 'Name']);
var receiver = n(txInf, receiverNodeName);
r(receiver, 'Nm', this[pullFrom + 'Name']);

if (this[pullFrom + 'Street'] && this[pullFrom + 'City'] && this[pullFrom + 'Country']) {
var pstl = n(reciever, 'PstlAdr');
var pstl = n(receiver, 'PstlAdr');
r(pstl, 'Ctry', this.debtorCountry);
r(pstl, 'AdrLine', this.debtorStreet);
r(pstl, 'AdrLine', this.debtorCity);
}

r(txInf, recieverNodeName + 'Acct', 'Id', 'IBAN', this[pullFrom + 'IBAN']);
r(txInf, receiverNodeName + 'Acct', 'Id', 'IBAN', this[pullFrom + 'IBAN']);

r(txInf, 'RmtInf', 'Ustrd', this.remittanceInfo);
o(txInf, 'Purp', 'Cd', this.purposeCode);
Expand Down Expand Up @@ -668,72 +606,6 @@
return cid.substr(0, 2) + ('0' + (98 - mod)).substr(-2,2) + cid.substr(4);
}

// --- Various private functions follow --- //

/** Assert that |cond| is true, otherwise throw an error with |msg| */
function assert(cond, msg) {
if (!cond) {
throw new Error(msg);
}
}

/** Assert that |val| is one of |choices| */
function assert_fixed(val, choices, member) {
if (choices.indexOf(val) < 0) {
throw new Error(member + ' must have any value of: ' + choices.join(' ') + '(found: ' + val + ')');
}
}

/** assert that |str| has a length between min and max (either may be null) */
function assert_length(str, min, max, member) {
if ((min !== null && str && str.length < min) ||
(max !== null && str && str.length > max)) {
throw new Error(member + ' has invalid string length, expected ' + min + ' < ' + str + ' < ' + max);
}
}

/** assert that |num| is in the range between |min| and |max| */
function assert_range(num, min, max, member) {
if (num < min || num > max) {
throw new Error(member + ' does not match range ' + min + ' < ' + num + ' < ' + max);
}
}

/** assert that |str| is an IBAN */
function assert_iban(str, member) {
if (!validateIBAN(str)) {
throw new Error(member + ' has invalid IBAN "' + str + '"');
}
}

/** assert that |str| is a creditor id */
function assert_cid(str, member) {
if (!validateCreditorID(str)) {
throw new Error(member + ' is invalid "' + str + '"');
}
}

/** assert an iso date */
function assert_date(dt, member) {
if (!dt || isNaN(dt.getTime())) {
throw new Error(member + ' has invalid date ' + dt);
}
}

/** assert that the str uses characters from the first sepa id charset */
function assert_sepa_id_set1(str, member) {
if (str && !str.match(/([A-Za-z0-9]|[\+|\?|\/|\-|:|\(|\)|\.|,|'| ]){1,35}/)) {
throw new Error(member + ' doesn\'t match sepa id charset type 1 (found: ' + '"' + str + '")');
}
}

/** assert that the str uses characters from the second sepa id charset */
function assert_sepa_id_set2(str, member) {
if (str && !str.match(/([A-Za-z0-9]|[\+|\?|\/|\-|:|\(|\)|\.|,|']){1,35}/)) {
throw new Error(member + ' doesn\'t match sepa id charset type 2 (found: ' + '"' + str + '")');
}
}

/**
* Creates a DOM Document, either using the browser document, or node.js xmldom.
*
Expand Down Expand Up @@ -824,6 +696,5 @@
exports.validateCreditorID = validateCreditorID;
exports.checksumCreditorID = checksumCreditorID;
exports.setIDSeparator = setIDSeparator;
exports.enableValidations = enableValidations;

})(typeof exports === 'undefined' ? this.SEPA = {} : exports);
Loading

0 comments on commit 075025b

Please sign in to comment.