qqlib-node-boleto 1.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/.editorconfig +11 -0
  2. package/.eslintignore +1 -0
  3. package/.eslintrc +10 -0
  4. package/.idea/encodings.xml +4 -0
  5. package/.idea/modules.xml +8 -0
  6. package/.idea/node-boleto.git_master.iml +8 -0
  7. package/.idea/vcs.xml +7 -0
  8. package/LICENSE +20 -0
  9. package/README.md +92 -0
  10. package/assets/layout.ejs +433 -0
  11. package/banks/banco do brasil/index.js +172 -0
  12. package/banks/bradesco/index.js +154 -0
  13. package/banks/caixa/index.js +66 -0
  14. package/banks/santander/helper.js +3 -0
  15. package/banks/santander/index.js +145 -0
  16. package/examples/bradesco-edi.js +6 -0
  17. package/examples/bradesco-emission.js +35 -0
  18. package/examples/retorno.txt +8 -0
  19. package/examples/santander-edi.js +6 -0
  20. package/examples/santander-emission.js +32 -0
  21. package/index.js +12 -0
  22. package/lib/barcode.js +93 -0
  23. package/lib/boleto.js +105 -0
  24. package/lib/edi-helper.js +13 -0
  25. package/lib/edi-parser.js +7 -0
  26. package/lib/formatters.js +109 -0
  27. package/package.json +30 -0
  28. package/public/images/b.png +0 -0
  29. package/public/images/bb.png +0 -0
  30. package/public/images/bradesco.jpg +0 -0
  31. package/public/images/santander.png +0 -0
  32. package/public/images/w.png +0 -0
  33. package/readme.will.md +11 -0
  34. package/sonar-project.properties +9 -0
  35. package/test/e2e/boleto-output.js +420 -0
  36. package/test/e2e/boleto-render.spec.js +104 -0
  37. package/test/integration/bradesco/boleto.spec.js +216 -0
  38. package/test/integration/bradesco/edi.spec.js +113 -0
  39. package/test/integration/caixa/edi.spec.js +99 -0
  40. package/test/integration/santander/boleto.spec.js +45 -0
  41. package/test/integration/santander/edi.spec.js +73 -0
  42. package/test/mocks/banks.js +13 -0
  43. package/test/mocks/boleto-2018-10-31.js +25 -0
  44. package/test/mocks/boleto-2018-11-09.js +25 -0
  45. package/test/unit/boleto-object.spec.js +134 -0
  46. package/test/unit/boleto-render.spec.js +34 -0
  47. package/test/unit/formatters.spec.js +62 -0
package/lib/barcode.js ADDED
@@ -0,0 +1,93 @@
1
+ exports.binaryRepresentationForBarcodeData = function (barcodeData) {
2
+ const digits = {
3
+ 0: '00110',
4
+ 1: '10001',
5
+ 2: '01001',
6
+ 3: '11000',
7
+ 4: '00101',
8
+ 5: '10100',
9
+ 6: '01100',
10
+ 7: '00011',
11
+ 8: '10010',
12
+ 9: '01010'
13
+ }
14
+
15
+ if (barcodeData.length % 2 !== 0) {
16
+ barcodeData = '0' + barcodeData
17
+ }
18
+
19
+ let binaryDigits = '0000'
20
+ // Start of barcode
21
+ for (let i = 0; i < barcodeData.length; i += 2) {
22
+ const digit1 = digits[parseInt(barcodeData[i])]
23
+ const digit2 = digits[parseInt(barcodeData[i + 1])]
24
+
25
+ for (let j = 0; j < digit1.length; j++) {
26
+ binaryDigits += digit1[j] + digit2[j]
27
+ }
28
+ }
29
+
30
+ // End of barcode
31
+ binaryDigits += '1000'
32
+
33
+ return binaryDigits
34
+ }
35
+
36
+ // Convert a value to a little endian hexadecimal value
37
+ exports._getLittleEndianHex = function (value) {
38
+ const result = []
39
+
40
+ for (let bytes = 4; bytes > 0; bytes--) {
41
+ result.push(String.fromCharCode(value & 0xff))
42
+ value >>= 0x8
43
+ }
44
+
45
+ return result.join('')
46
+ }
47
+
48
+ exports._bmpHeader = function (width, height) {
49
+ const numFileBytes = exports._getLittleEndianHex(width * height)
50
+ width = exports._getLittleEndianHex(width)
51
+ height = exports._getLittleEndianHex(height)
52
+
53
+ return 'BM' + // Signature
54
+ numFileBytes + // size of the file (bytes)*
55
+ '\x00\x00' + // reserved
56
+ '\x00\x00' + // reserved
57
+ '\x36\x00\x00\x00' + // offset of where BMP data lives (54 bytes)
58
+ '\x28\x00\x00\x00' + // number of remaining bytes in header from here (40 bytes)
59
+ width + // the width of the bitmap in pixels*
60
+ height + // the height of the bitmap in pixels*
61
+ '\x01\x00' + // the number of color planes (1)
62
+ '\x20\x00' + // 32 bits / pixel
63
+ '\x00\x00\x00\x00' + // No compression (0)
64
+ '\x00\x00\x00\x00' + // size of the BMP data (bytes)*
65
+ '\x13\x0B\x00\x00' + // 2835 pixels/meter - horizontal resolution
66
+ '\x13\x0B\x00\x00' + // 2835 pixels/meter - the vertical resolution
67
+ '\x00\x00\x00\x00' + // Number of colors in the palette (keep 0 for 32-bit)
68
+ '\x00\x00\x00\x00' // 0 important colors (means all colors are important)
69
+ }
70
+
71
+ exports.bmpLineForBarcodeData = function (barcodeData) {
72
+ const binaryRepresentation = exports.binaryRepresentationForBarcodeData(barcodeData)
73
+
74
+ let bmpData = []
75
+ let black = true
76
+ let offset = 0
77
+
78
+ for (let i = 0; i < binaryRepresentation.length; i++) {
79
+ const digit = binaryRepresentation[i]
80
+ const color = black ? String.fromCharCode(0, 0, 0, 0) : String.fromCharCode(255, 255, 255, 0)
81
+ let pixelsToDraw = (digit === '0') ? 1 : 3
82
+
83
+ for (let j = 0; j < pixelsToDraw; j++) {
84
+ bmpData[offset++] = color
85
+ }
86
+
87
+ black = !black
88
+ }
89
+
90
+ const bmpHeader = exports._bmpHeader(offset - 1, 1)
91
+ const bmpBuffer = new Buffer(bmpHeader + bmpData.join(''), 'binary')
92
+ return bmpBuffer.toString('base64')
93
+ }
package/lib/boleto.js ADDED
@@ -0,0 +1,105 @@
1
+ const ejs = require('ejs')
2
+ const formatters = require('./formatters')
3
+ const barcode = require('./barcode')
4
+ const path = require('path')
5
+ const moment = require('moment')
6
+
7
+ var banks = null
8
+
9
+ var hashString = function (string) {
10
+ var hash = 0
11
+ var i
12
+ var chr
13
+ var len
14
+
15
+ if (string.length == 0) return hash
16
+ for (i = 0, len = string.length; i < len; i++) {
17
+ chr = string.charCodeAt(i)
18
+ hash = ((hash << 5) - hash) + chr
19
+ hash |= 0 // Convert to 32bit integer
20
+ }
21
+ return hash
22
+ }
23
+
24
+ var Boleto = function (options) {
25
+ if (!options) {
26
+ throw 'No options provided initializing Boleto.'
27
+ }
28
+
29
+ this.bank = banks[options['banco']]
30
+ if (!this.bank) {
31
+ throw 'Invalid bank.'
32
+ }
33
+
34
+ if (!options['data_emissao']) {
35
+ options['data_emissao'] = moment().utc()
36
+ } else {
37
+ options['data_emissao'] = moment(moment(options['data_emissao']).utc().format('YYYY-MM-DD'))
38
+ }
39
+
40
+ if (!options['data_vencimento']) {
41
+ options['data_vencimento'] = moment().utc().add('5', 'days')
42
+ } else {
43
+ options['data_vencimento'] = moment(moment(options['data_vencimento']).utc().format('YYYY-MM-DD'))
44
+ }
45
+
46
+ for (var key in options) {
47
+ this[key] = options[key]
48
+ }
49
+
50
+ this['pagador'] = formatters.htmlString(this['pagador'])
51
+ this['instrucoes'] = formatters.htmlString(this['instrucoes'])
52
+
53
+ if (!this['local_de_pagamento']) {
54
+ this['local_de_pagamento'] = 'Até o vencimento, preferencialmente no Banco ' + formatters.capitalize(this['banco'])
55
+ }
56
+
57
+ this._calculate()
58
+ }
59
+
60
+ Boleto.barcodeRenderEngine = 'img'
61
+
62
+ Boleto.prototype._calculate = function () {
63
+ this['codigo_banco'] = this.bank.options.codigo + '-' + formatters.mod11(this.bank.options.codigo)
64
+ this['nosso_numero_dv'] = formatters.mod11(this['nosso_numero'].toString())
65
+ this['barcode_data'] = this.bank.barcodeData(this)
66
+ this['linha_digitavel'] = this.bank.linhaDigitavel(this['barcode_data'])
67
+ }
68
+
69
+ Boleto.prototype.renderHTML = function (callback) {
70
+ var self = this
71
+
72
+ var renderOptions = self.bank.options
73
+ renderOptions.boleto = self
74
+
75
+ // Copy renderHelper's methods to renderOptions
76
+ for (var key in formatters) {
77
+ renderOptions[key] = formatters[key]
78
+ }
79
+
80
+ renderOptions['barcode_render_engine'] = Boleto.barcodeRenderEngine
81
+ renderOptions['barcode_height'] = '50'
82
+
83
+ if (Boleto.barcodeRenderEngine == 'bmp') {
84
+ renderOptions['barcode_data'] = barcode.bmpLineForBarcodeData(self['barcode_data'])
85
+ } else if (Boleto.barcodeRenderEngine == 'img') {
86
+ renderOptions['barcode_data'] = barcode.binaryRepresentationForBarcodeData(self['barcode_data'])
87
+ }
88
+
89
+ renderOptions['boleto']['linha_digitavel_hash'] = hashString(renderOptions['boleto']['linha_digitavel']).toString()
90
+
91
+ ejs.renderFile(path.join(__dirname, '/../assets/layout.ejs'), renderOptions, {
92
+ cache: true
93
+ }, function (err, html) {
94
+ if (err) {
95
+ throw new Error(err)
96
+ }
97
+
98
+ callback(html)
99
+ })
100
+ }
101
+
102
+ module.exports = function (_banks) {
103
+ banks = _banks
104
+ return Boleto
105
+ }
@@ -0,0 +1,13 @@
1
+ var crypto = require('crypto')
2
+
3
+ exports.calculateLineChecksum = function (line) {
4
+ return crypto.createHash('sha1').update(line).digest('hex')
5
+ }
6
+
7
+ exports.dateFromEdiDate = function (ediDate) {
8
+ const year = ediDate.substring(4, 8)
9
+ const month = ediDate.substring(2, 4)
10
+ const day = ediDate.substring(0, 2)
11
+
12
+ return new Date(parseInt('20' + year), parseInt(month) - 1, parseInt(day))
13
+ }
@@ -0,0 +1,7 @@
1
+ module.exports = function (banks) {
2
+ return {
3
+ parse: function (bankName, fileContent) {
4
+ return banks[bankName].parseEDIFile(fileContent)
5
+ }
6
+ }
7
+ }
@@ -0,0 +1,109 @@
1
+ const escapeXML = require('ejs').escapeXML
2
+ const moment = require('moment')
3
+
4
+ exports.capitalize = function (string) {
5
+ return string.charAt(0).toUpperCase() + string.slice(1)
6
+ }
7
+
8
+ exports.addTrailingZeros = function (string, length) {
9
+ string = string.toString()
10
+
11
+ while (string.length < length) {
12
+ string = '0' + string
13
+ }
14
+
15
+ return string
16
+ }
17
+
18
+ exports.formatAmount = function (amount) {
19
+ amount = amount.toString()
20
+ var cents = exports.addTrailingZeros(amount.substring(amount.length - 2, amount.length), 2)
21
+ var integers = exports.addTrailingZeros(amount.substring(0, amount.length - 2), 1)
22
+
23
+ var newIntegers = ''
24
+
25
+ for (var i = 0; i < integers.length; i++) {
26
+ if (i > 0 && (integers.length - i) % 3 == 0) newIntegers += '.'
27
+ newIntegers += integers[i]
28
+ }
29
+
30
+ return 'R$ ' + newIntegers + ',' + cents
31
+ }
32
+
33
+ exports.formatDate = function (date) {
34
+ return moment(date).format('DD/MM/YYYY')
35
+ }
36
+
37
+ exports.mod11 = function (num, base, r) {
38
+ if (!base) base = 9
39
+ if (!r) r = 0
40
+
41
+ var soma = 0
42
+ var fator = 2
43
+
44
+ for (var i = num.length - 1; i >= 0; i--) {
45
+ var parcial = parseInt(num[i]) * fator
46
+ soma += parcial
47
+
48
+ if (fator == base) {
49
+ fator = 1
50
+ }
51
+
52
+ fator++
53
+ }
54
+
55
+ if (r == 0) {
56
+ soma *= 10
57
+ var digito = soma % 11
58
+ return digito == 10 ? 0 : digito
59
+ } else if (r == 1) {
60
+ return soma % 11
61
+ }
62
+ }
63
+
64
+ exports.mod10 = function (num) {
65
+ var total = 0
66
+ var fator = 2
67
+
68
+ for (var i = num.length - 1; i >= 0; i--) {
69
+ var temp = (parseInt(num[i]) * fator).toString()
70
+ var tempSum = 0
71
+ for (var j = 0; j < temp.length; j++) {
72
+ tempSum += parseInt(temp[j])
73
+ }
74
+ total += tempSum
75
+ fator = (fator == 2) ? 1 : 2
76
+ }
77
+
78
+ var resto = total % 10
79
+ return (resto == 0) ? 0 : (10 - resto)
80
+ }
81
+
82
+ exports.fatorVencimento = function (date) {
83
+ const parsedDate = moment(date).utc().format('YYYY-MM-DD')
84
+ const startDate = moment('1997-10-07').utc().format('YYYY-MM-DD')
85
+
86
+ let factor = moment(parsedDate).diff(startDate, 'days')
87
+
88
+ if (factor >= 10000) {
89
+ factor = (factor % 10000) + 1000
90
+ }
91
+
92
+ return exports.addTrailingZeros(factor, 4)
93
+ }
94
+
95
+ exports.dateFromEdiDate = function (ediDate) {
96
+ return new Date(parseInt(ediDate.substring(4, 8)), parseInt(ediDate.substring(2, 4)) - 1, parseInt(ediDate.substring(0, 2)))
97
+ }
98
+
99
+ exports.removeTrailingZeros = function (string) {
100
+ while (string.charAt(0) == '0') {
101
+ string = string.substring(1, string.length)
102
+ }
103
+
104
+ return string
105
+ }
106
+
107
+ exports.htmlString = function (str) {
108
+ return str ? escapeXML(str).replace(/\n/g, '<br/>') : str
109
+ }
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "qqlib-node-boleto",
3
+ "version": "1.0.11",
4
+ "description": "Boleto generator in Node.js",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "lint": "eslint .",
8
+ "test": "nyc --silent --all mocha \"./test/unit/**/*.spec.js\" && nyc --silent --all mocha \"./test/integration/**/*.spec.js\" && nyc --silent --all mocha \"./test/e2e/**/*.spec.js\"",
9
+ "cover-report": "nyc report --reporter=html --reporter=lcov --report-dir=./coverage"
10
+ },
11
+ "dependencies": {
12
+ "ejs": "2.5.5"
13
+ },
14
+ "devDependencies": {
15
+ "chai": "^3.5.0",
16
+ "chai-datetime": "^1.4.1",
17
+ "chai-string": "^1.3.0",
18
+ "chai-subset": "^1.4.0",
19
+ "eslint": "^3.12.2",
20
+ "eslint-config-standard": "^6.2.1",
21
+ "eslint-plugin-promise": "^3.3.0",
22
+ "eslint-plugin-standard": "^2.0.1",
23
+ "mocha": "^3.2.0",
24
+ "moment": "https://github.com/pagarme/moment/archive/0.0.5.tar.gz",
25
+ "nyc": "15.1.0",
26
+ "ramda": "^0.23.0"
27
+ },
28
+ "license": "MIT"
29
+
30
+ }
Binary file
Binary file
Binary file
Binary file
Binary file
package/readme.will.md ADDED
@@ -0,0 +1,11 @@
1
+ npm publish --registry http://ip:porta
2
+ npm unpublish qq-node-boleto@1.0.9
3
+
4
+ npm set registry http://ip:porta
5
+ npm get registry
6
+
7
+
8
+ λ npm get registry
9
+ https://registry.npmjs.org/
10
+
11
+
@@ -0,0 +1,9 @@
1
+ sonar.organization=pagarme
2
+ sonar.projectKey=node-boleto
3
+ sonar.projectName=node-boleto
4
+ sonar.projectVersion=1.0
5
+ sonar.sources=.
6
+ sonar.sourceEncoding=UTF-8
7
+ sonar.javascript.lcov.reportPaths=lcov.info
8
+ sonar.tests=test
9
+ sonar.exclusions=**/node_modules/**,test/**