swissqrbill
Advanced tools
Comparing version 1.0.5 to 1.0.6
@@ -234,2 +234,11 @@ /// <reference types="pdfkit" /> | ||
/** | ||
* Checks if the provided reference matches a QR reference | ||
* | ||
* @private | ||
* @param {string} reference string containing the reference number | ||
* @returns {boolean} boolean if the reference is a QR reference | ||
* @memberof PDF | ||
*/ | ||
private _isQRReference; | ||
/** | ||
* Draws a rectangle which is used when data is to be filled in by hand. | ||
@@ -236,0 +245,0 @@ * |
313
lib/index.js
@@ -32,3 +32,9 @@ "use strict"; | ||
this._data = data; | ||
//-- Validate data | ||
//-- Validate IBAN | ||
if (this._data.creditor.account === undefined) { | ||
throw new Error("You must provide an IBAN or QR-IBAN number."); | ||
} | ||
if (this._data.creditor.account.replace(/ /g, "").length !== 21) { | ||
throw new Error("The provided IBAN number '" + this._data.creditor.account + "' is either too long or too short."); | ||
} | ||
if (iban_1.default.isValid(this._data.creditor.account) === false) { | ||
@@ -38,9 +44,15 @@ throw new Error("The provided IBAN number '" + this._data.creditor.account + "' is not valid."); | ||
if (this._data.creditor.account.substr(0, 2) !== "CH" && this._data.creditor.account.substr(0, 2) !== "LI") { | ||
throw new Error("Only CH and LI IBAN numbers are allowed"); | ||
throw new Error("Only CH and LI IBAN numbers are allowed."); | ||
} | ||
//-- Validate reference | ||
if (this._isQRIBAN(this._data.creditor.account)) { | ||
this._referenceType = "QRR"; | ||
if (this._data.reference === undefined) { | ||
throw new Error("QR-IBAN numbers must have a reference"); | ||
throw new Error("If there is no reference, a conventional IBAN must be used."); | ||
} | ||
if (this._isQRReference(this._data.reference)) { | ||
this._referenceType = "QRR"; | ||
} | ||
else { | ||
throw new Error("QR reference requires the use of a QR-IBAN (and vice versa)."); | ||
} | ||
} | ||
@@ -52,8 +64,10 @@ else { | ||
else { | ||
this._referenceType = "SCOR"; | ||
if (this._isQRReference(this._data.reference)) { | ||
throw new Error("Creditor Reference requires the use of a conventional IBAN."); | ||
} | ||
else { | ||
this._referenceType = "SCOR"; | ||
} | ||
} | ||
} | ||
if (this._data.creditor.name.length > 70) { | ||
throw new Error("Creditor name can be a maximum of 70 characters"); | ||
} | ||
if (options !== undefined) { | ||
@@ -391,48 +405,89 @@ if (options.language !== undefined) { | ||
var qrString = ""; | ||
qrString += "SPC\n"; // Swiss Payments Code | ||
qrString += "0200\n"; // Version | ||
qrString += "1\n"; // Coding Type UTF-8 | ||
qrString += (_a = this._formatIBAN(this._data.creditor.account)) !== null && _a !== void 0 ? _a : this._data.creditor.account + "\n"; // IBAN | ||
//-- Swiss Payments Code | ||
qrString += "SPC\n"; | ||
//-- Version | ||
qrString += "0200\n"; | ||
//-- Coding Type UTF-8 | ||
qrString += "1\n"; | ||
//-- IBAN | ||
qrString += (_a = this._data.creditor.account.replace(/ /g, "") + "\n") !== null && _a !== void 0 ? _a : "\n"; | ||
if (this._data.creditor.houseNumber !== undefined) { | ||
qrString += "S\n"; // Adress Type | ||
//-- Adress Type | ||
qrString += "S\n"; | ||
//-- Name | ||
if (this._data.creditor.name === undefined) { | ||
throw new Error("Creditor name cannot be undefined."); | ||
} | ||
if (this._data.creditor.name.length > 70) { | ||
throw new Error("Creditor name must be a maximum of 70 characters"); | ||
throw new Error("Creditor name must be a maximum of 70 characters."); | ||
} | ||
qrString += this._data.creditor.name + "\n"; // Name | ||
qrString += this._data.creditor.name + "\n"; | ||
//-- Address | ||
if (this._data.creditor.address === undefined) { | ||
throw new Error("Creditor address cannot be undefined."); | ||
} | ||
if (this._data.creditor.address.length > 70) { | ||
throw new Error("Creditor address must be a maximum of 70 characters"); | ||
throw new Error("Creditor address must be a maximum of 70 characters."); | ||
} | ||
qrString += this._data.creditor.address + "\n"; // Address | ||
if (this._data.creditor.address.length > 16) { | ||
throw new Error("Creditor house number can be a maximum of 16 characters"); | ||
qrString += this._data.creditor.address + "\n"; | ||
//-- House number | ||
if (this._data.creditor.houseNumber.length > 16) { | ||
throw new Error("Creditor house number can be a maximum of 16 characters."); | ||
} | ||
qrString += this._data.creditor.houseNumber + "\n"; // House number | ||
if (this._data.creditor.address.length > 16) { | ||
throw new Error("Creditor zip must be a maximum of 16 characters"); | ||
qrString += this._data.creditor.houseNumber + "\n"; | ||
//-- Zip | ||
if (this._data.creditor.zip === undefined) { | ||
throw new Error("Creditor zip cannot be undefined."); | ||
} | ||
qrString += this._data.creditor.zip + "\n"; // Zip code | ||
if (this._data.creditor.address.length > 35) { | ||
throw new Error("Creditor city must be a maximum of 35 characters"); | ||
if (this._data.creditor.zip.toString().length > 16) { | ||
throw new Error("Creditor zip must be a maximum of 16 characters."); | ||
} | ||
qrString += this._data.creditor.city + "\n"; // City | ||
qrString += this._data.creditor.zip + "\n"; | ||
if (this._data.creditor.city === undefined) { | ||
throw new Error("Creditor city cannot be undefined."); | ||
} | ||
if (this._data.creditor.city.length > 35) { | ||
throw new Error("Creditor city must be a maximum of 35 characters."); | ||
} | ||
qrString += this._data.creditor.city + "\n"; | ||
} | ||
else { | ||
qrString += "K\n"; // Adress Type | ||
//-- Adress Type | ||
qrString += "K\n"; | ||
//-- Name | ||
if (this._data.creditor.name === undefined) { | ||
throw new Error("Creditor name cannot be undefined."); | ||
} | ||
if (this._data.creditor.name.length > 70) { | ||
throw new Error("Creditor name must be a maximum of 70 characters"); | ||
throw new Error("Creditor name must be a maximum of 70 characters."); | ||
} | ||
qrString += this._data.creditor.name + "\n"; // Name | ||
qrString += this._data.creditor.name + "\n"; | ||
//-- Address | ||
if (this._data.creditor.address === undefined) { | ||
throw new Error("Creditor address cannot be undefined."); | ||
} | ||
if (this._data.creditor.address.length > 70) { | ||
throw new Error("Creditor address must be a maximum of 70 characters"); | ||
throw new Error("Creditor address must be a maximum of 70 characters."); | ||
} | ||
qrString += this._data.creditor.address + "\n"; // Address | ||
qrString += this._data.creditor.address + "\n"; | ||
//-- Zip + city | ||
if (this._data.creditor.zip === undefined || this._data.creditor.city === undefined) { | ||
throw new Error("Creditor zip and city cannot be undefined."); | ||
} | ||
if ((this._data.creditor.zip + " " + this._data.creditor.city).length > 70) { | ||
throw new Error("Creditor zip plus city must be a maximum of 70 characters"); | ||
throw new Error("Creditor zip plus city must be a maximum of 70 characters."); | ||
} | ||
qrString += this._data.creditor.zip + " " + this._data.creditor.city + "\n"; // Zip code + city | ||
qrString += this._data.creditor.zip + " " + this._data.creditor.city + "\n"; | ||
//-- Empty zip field | ||
qrString += "\n"; | ||
//-- Empty city field | ||
qrString += "\n"; | ||
} | ||
if (this._data.creditor.country === undefined) { | ||
throw new Error("Creditor country cannot be undefined."); | ||
} | ||
if (this._data.creditor.country.length !== 2) { | ||
throw new Error("Creditor country must be 2 characters"); | ||
throw new Error("Creditor country must be 2 characters."); | ||
} | ||
qrString += this._data.creditor.country + "\n"; // Country | ||
qrString += this._data.creditor.country + "\n"; | ||
//-- 7 x empty | ||
@@ -446,84 +501,162 @@ qrString += "\n"; // 1 | ||
qrString += "\n"; // 7 | ||
//-- Amount | ||
if (this._data.amount !== undefined) { | ||
if (this._data.amount.toString().length > 12) { | ||
throw new Error("Creditor country must be 2 characters"); | ||
throw new Error("Creditor country must be 2 characters."); | ||
} | ||
} | ||
qrString += ((_b = this._data.amount) !== null && _b !== void 0 ? _b : "") + "\n"; // Amount | ||
qrString += this._data.currency + "\n"; // Currency | ||
qrString += ((_b = this._data.amount) !== null && _b !== void 0 ? _b : "") + "\n"; | ||
//-- Currency | ||
if (this._data.currency === undefined) { | ||
throw new Error("Currency cannot be undefined."); | ||
} | ||
qrString += this._data.currency + "\n"; | ||
//-- Debitor | ||
if (this._data.debitor !== undefined) { | ||
if (this._data.debitor.houseNumber !== undefined) { | ||
qrString += "S\n"; // Adress Type | ||
//-- Address type | ||
qrString += "S\n"; | ||
//-- Name | ||
if (this._data.debitor.name === undefined) { | ||
throw new Error("Debitor name cannot be undefined if the debitor object is available."); | ||
} | ||
if (this._data.debitor.name.length > 70) { | ||
throw new Error("Debitor name must be a maximum of 70 characters"); | ||
throw new Error("Debitor name must be a maximum of 70 characters."); | ||
} | ||
qrString += this._data.debitor.name + "\n"; // Name | ||
qrString += this._data.debitor.name + "\n"; | ||
//-- Address | ||
if (this._data.debitor.address === undefined) { | ||
throw new Error("Debitor address cannot be undefined if the debitor object is available."); | ||
} | ||
if (this._data.debitor.address.length > 70) { | ||
throw new Error("Debitor address must be a maximum of 70 characters"); | ||
throw new Error("Debitor address must be a maximum of 70 characters."); | ||
} | ||
qrString += this._data.debitor.address + "\n"; // Address | ||
if (this._data.debitor.address.length > 16) { | ||
throw new Error("Debitor house number can be a maximum of 16 characters"); | ||
qrString += this._data.debitor.address + "\n"; | ||
//-- House number | ||
if (this._data.debitor.houseNumber.length > 16) { | ||
throw new Error("Debitor house number can be a maximum of 16 characters."); | ||
} | ||
qrString += this._data.debitor.houseNumber + "\n"; // House number | ||
if (this._data.debitor.address.length > 16) { | ||
throw new Error("Debitor zip must be a maximum of 16 characters"); | ||
qrString += this._data.debitor.houseNumber + "\n"; | ||
//-- Zip | ||
if (this._data.debitor.zip === undefined) { | ||
throw new Error("Debitor zip cannot be undefined if the debitor object is available."); | ||
} | ||
qrString += this._data.debitor.zip + "\n"; // Zip code | ||
if (this._data.debitor.address.length > 35) { | ||
throw new Error("Debitor city must be a maximum of 35 characters"); | ||
if (this._data.debitor.zip.toString().length > 16) { | ||
throw new Error("Debitor zip must be a maximum of 16 characters."); | ||
} | ||
qrString += this._data.debitor.city + "\n"; // City | ||
qrString += this._data.debitor.zip + "\n"; | ||
//-- City | ||
if (this._data.debitor.city === undefined) { | ||
throw new Error("Debitor city cannot be undefined if the debitor object is available."); | ||
} | ||
if (this._data.debitor.city.length > 35) { | ||
throw new Error("Debitor city must be a maximum of 35 characters."); | ||
} | ||
qrString += this._data.debitor.city + "\n"; | ||
} | ||
else { | ||
qrString += "K\n"; // Adress Type | ||
//-- Address type | ||
qrString += "K\n"; | ||
//-- Name | ||
if (this._data.debitor.name === undefined) { | ||
throw new Error("Debitor name cannot be undefined if the debitor object is available."); | ||
} | ||
if (this._data.debitor.name.length > 70) { | ||
throw new Error("Debitor name must be a maximum of 70 characters"); | ||
throw new Error("Debitor name must be a maximum of 70 characters."); | ||
} | ||
qrString += this._data.debitor.name + "\n"; // Name | ||
qrString += this._data.debitor.name + "\n"; | ||
//-- Address | ||
if (this._data.debitor.address === undefined) { | ||
throw new Error("Debitor address cannot be undefined if the debitor object is available."); | ||
} | ||
if (this._data.debitor.address.length > 70) { | ||
throw new Error("Debitor address must be a maximum of 70 characters"); | ||
throw new Error("Debitor address must be a maximum of 70 characters."); | ||
} | ||
qrString += this._data.debitor.address + "\n"; // Address | ||
qrString += this._data.debitor.address + "\n"; | ||
//-- Zip + city | ||
if (this._data.debitor.zip === undefined || this._data.debitor.city === undefined) { | ||
throw new Error("Debitor zip and city cannot be undefined if the debitor object is available."); | ||
} | ||
if ((this._data.debitor.zip + " " + this._data.debitor.city).length > 70) { | ||
throw new Error("Debitor zip plus city must be a maximum of 70 characters"); | ||
throw new Error("Debitor zip plus city must be a maximum of 70 characters."); | ||
} | ||
qrString += this._data.debitor.zip + " " + this._data.debitor.city + "\n"; // Zip code + city | ||
qrString += this._data.debitor.zip + " " + this._data.debitor.city + "\n"; | ||
//-- Empty field zip | ||
qrString += "\n"; | ||
//-- Empty field city | ||
qrString += "\n"; | ||
} | ||
qrString += this._data.debitor.country + "\n"; // Country | ||
if (this._data.debitor.country === undefined) { | ||
throw new Error("Debitor country cannot be undefined if the debitor object is available."); | ||
} | ||
if ((this._data.debitor.country).length !== 2) { | ||
throw new Error("Debitor country must be 2 characters."); | ||
} | ||
qrString += this._data.debitor.country + "\n"; | ||
} | ||
qrString += this._referenceType + "\n"; // Referencetype | ||
else { | ||
//-- Empty field type | ||
qrString += "\n"; | ||
//-- Empty field name | ||
qrString += "\n"; | ||
//-- Empty field address | ||
qrString += "\n"; | ||
//-- Empty field house number | ||
qrString += "\n"; | ||
//-- Empty field zip | ||
qrString += "\n"; | ||
//-- Empty field city | ||
qrString += "\n"; | ||
//-- Empty field country | ||
qrString += "\n"; | ||
} | ||
//-- Reference type | ||
qrString += this._referenceType + "\n"; | ||
//-- Reference | ||
if (this._data.reference !== undefined) { | ||
if (this._data.reference.replace(/ /g, "").length > 27) { | ||
throw new Error("Reference must be a maximum of 27 characters"); | ||
} | ||
qrString += this._data.reference + "\n"; // Reference | ||
qrString += this._data.reference.replace(/ /g, "") + "\n"; | ||
} | ||
else { | ||
qrString += "" + "\n"; // Reference | ||
qrString += "\n"; | ||
} | ||
//-- Unstructured message | ||
if (this._data.message !== undefined) { | ||
if (this._data.message.length > 140) { | ||
throw new Error("Message must be a maximum of 140 characters"); | ||
throw new Error("Message must be a maximum of 140 characters."); | ||
} | ||
qrString += this._data.message + "\n"; // Unstructured message | ||
qrString += this._data.message + "\n"; | ||
} | ||
qrString += "EPD" + "\n"; // End Payment Data | ||
else { | ||
qrString += "\n"; | ||
} | ||
//-- End Payment Data | ||
qrString += "EPD" + "\n"; | ||
//-- Additional information | ||
if (this._data.additionalInformation !== undefined) { | ||
if (this._data.additionalInformation.length > 140) { | ||
throw new Error("AdditionalInfromation must be a maximum of 27 characters"); | ||
throw new Error("AdditionalInfromation must be a maximum of 140 characters."); | ||
} | ||
qrString += this._data.additionalInformation + "\n"; // Bill infromation | ||
qrString += this._data.additionalInformation + "\n"; | ||
} | ||
else { | ||
qrString += "\n"; | ||
} | ||
//-- AV1 | ||
if (this._data.av1 !== undefined) { | ||
if (this._data.av1.length > 100) { | ||
throw new Error("AV1 must be a maximum of 27 characters"); | ||
throw new Error("AV1 must be a maximum of 100 characters."); | ||
} | ||
qrString += this._data.av1 + "\n"; // AV1 | ||
if (this._data.av1.substr(0, 5) !== "eBill") { | ||
throw new Error("AV1 must begin with eBill"); | ||
} | ||
qrString += this._data.av1 + "\n"; | ||
} | ||
if (this._data.av2 !== undefined) { | ||
if (this._data.av2.length > 100) { | ||
throw new Error("AV2 must be a maximum of 27 characters"); | ||
throw new Error("AV2 must be a maximum of 100 characters."); | ||
} | ||
qrString += this._data.av2 + "\n"; // AV2 | ||
if (this._data.av2.substr(0, 5) !== "eBill") { | ||
throw new Error("AV2 must begin with eBill"); | ||
} | ||
qrString += this._data.av2; | ||
} | ||
@@ -535,3 +668,4 @@ var qrcodeString = new qrcode_svg_1.default({ | ||
height: this.mmToPoints(46), | ||
padding: 0 | ||
padding: 0, | ||
ecl: "M" | ||
}).svg(); | ||
@@ -692,5 +826,6 @@ var svgPath = this._getSVGPathFromQRCodeString(qrcodeString); | ||
reference = this._removeLinebreaks(reference); | ||
reference = reference.replace(/ /g, ""); | ||
var referenceArray = []; | ||
if (this._referenceType === "QRR") { | ||
var match = reference.replace(/ /g, "").split("").reverse().join("").match(/.{1,5}/g); | ||
var match = reference.split("").reverse().join("").match(/.{1,5}/g); | ||
if (match !== null) { | ||
@@ -701,3 +836,3 @@ referenceArray = match.reverse(); | ||
else if (this._referenceType === "SCOR") { | ||
var match = reference.replace(/ /g, "").match(/.{1,4}/g); | ||
var match = reference.match(/.{1,4}/g); | ||
if (match !== null) { | ||
@@ -722,2 +857,3 @@ referenceArray = match; | ||
iban = this._removeLinebreaks(iban); | ||
iban = iban.replace(/ /g, ""); | ||
var ibanArray = iban.replace(/ /g, "").match(/.{1,4}/g); | ||
@@ -742,2 +878,23 @@ if (ibanArray === null) { | ||
/** | ||
* Checks if the provided reference matches a QR reference | ||
* | ||
* @private | ||
* @param {string} reference string containing the reference number | ||
* @returns {boolean} boolean if the reference is a QR reference | ||
* @memberof PDF | ||
*/ | ||
PDF.prototype._isQRReference = function (reference) { | ||
reference = this._removeLinebreaks(reference); | ||
reference = reference.replace(/ /g, ""); | ||
if (reference.length === 27) { | ||
if (!isNaN(+reference)) { | ||
return true; | ||
} | ||
} | ||
if (reference.replace(/ /g, "").length <= 25) { | ||
return false; | ||
} | ||
throw new Error("Reference is not valid."); | ||
}; | ||
/** | ||
* Draws a rectangle which is used when data is to be filled in by hand. | ||
@@ -744,0 +901,0 @@ * |
{ | ||
"name": "swissqrbill", | ||
"version": "1.0.5", | ||
"version": "1.0.6", | ||
"description": "Swiss QR Bill generation in node.js ", | ||
@@ -5,0 +5,0 @@ "main": "./index.js", |
@@ -7,2 +7,5 @@ # SwissQRBill | ||
[<img src="https://raw.githubusercontent.com/Rogerrrrrrrs/SwissQRBill/development/assets/qrbill.png">](https://github.com/Rogerrrrrrrs/SwissQRBill/blob/master/assets/qrbill.pdf) | ||
## Contents | ||
@@ -15,2 +18,3 @@ | ||
## Features | ||
@@ -20,3 +24,3 @@ - Generates PDF with scalable vector graphics | ||
- Supports A4 invoices as well as A6/5 (QR Bill only) | ||
- Supports empty fields as defined in the [specifications](https://www.paymentstandards.ch/dam/downloads/ig-qr-bill-de.pdf) | ||
- Supports empty fields as defined in the [specifications](https://www.paymentstandards.ch/dam/downloads/ig-qr-bill-en.pdf) | ||
- Allows you to add other content above the invoice using [PDFKit](https://github.com/foliojs/pdfkit) | ||
@@ -26,2 +30,3 @@ - Easy to use | ||
## Installation | ||
@@ -33,2 +38,3 @@ | ||
## Usage | ||
@@ -42,3 +48,3 @@ | ||
amount: 1199.95, | ||
reference: "21 00000 00003 13947 14300 09017", | ||
reference: "210000000003139471430009017", | ||
creditor: { | ||
@@ -64,9 +70,10 @@ name: "Robert Schneider AG", | ||
This will generate the following PDF file | ||
This will generate the above PDF. | ||
[<img src="https://raw.githubusercontent.com/Rogerrrrrrrs/SwissQRBill/development/assets/qrbill.png">](https://github.com/Rogerrrrrrrs/SwissQRBill/blob/master/assets/qrbill.pdf) | ||
## API | ||
### Methods | ||
- Constructor | ||
@@ -80,9 +87,12 @@ - [SwissQRBill.PDF(data, outputPath[, options])](#swissqrbillpdfdata-outputpath-options) | ||
#### SwissQRBill.PDF(data, outputPath[, options]) | ||
- data - object containing all relevant billing data. | ||
- outputPath - string output path for the generated PDF file. | ||
- options - object containing settings, optional. | ||
Returns a new instance of SwissQRBill.PDF. | ||
Returns a new instance of SwissQRBill.PDF | ||
Available options: | ||
@@ -92,16 +102,24 @@ - language - string: Either `"DE" | "EN" | "IT" | "FR"`. Default `"DE"`. | ||
- scissors - boolean: Whether you want to show the scissor icons or the text `Separate before paying in`. Default `true`. | ||
- autoGenerate - boolean: Whether you want to atomatically finalize the PDF. When set to false you are able to add your own content to the PDF using PDFKit. Default `true`. | ||
- autoGenerate - boolean: Whether you want to automatically finalize the PDF. When set to false you are able to add your own content to the PDF using PDFKit. Default `true`. | ||
#### addPage() | ||
Adds a new page to the PDF. | ||
#### end() | ||
Finalizes the PDF document, after this command you are no longer able to edit the PDF. | ||
Note: This function is automatically called when the option autoGenerate is set to true. | ||
#### addQRBill() | ||
Adds the QR Bill to the bottom of the current page. | ||
Note: This function is automatically called when the option autoGenerate is set to true. | ||
#### mmToPoints(mm) | ||
- mm - number containg the millimeters you want to convert to points. | ||
@@ -113,4 +131,5 @@ Converts milimeters to points which are used in the PDF file. | ||
## PDFKit | ||
This module uses [PDFKit](https://github.com/foliojs/pdfkit) to generate PDF files. You are able to generate a comlete bill using PDFKit methods and then add the QR Bill to the bottom using `addQRBill()` when the option `autoGenerate` is set to `false`. | ||
This module uses [PDFKit](https://github.com/foliojs/pdfkit) to generate PDF files. You are able to generate a complete bill using PDFKit methods and then add the QR Bill to the bottom using `addQRBill()` when the option `autoGenerate` is set to `false`. | ||
The documentation for PDFKit can be found [here](http://pdfkit.org/docs/getting_started.html). | ||
@@ -126,3 +145,3 @@ | ||
amount: 1199.95, | ||
reference: "21 00000 00003 13947 14300 09017", | ||
reference: "210000000003139471430009017", | ||
creditor: { | ||
@@ -129,0 +148,0 @@ name: "Robert Schneider AG", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
62424
1243
180