girocode 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +30 -0
- data/Rakefile +10 -0
- data/lib/girocode.rb +12 -0
- data/lib/girocode/code.rb +119 -0
- data/lib/girocode/version.rb +3 -0
- metadata +133 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: f2713f1afa65bd13d77e0253324b6cfb8bde9a7044e02e2f6c79b3403c61787a
|
4
|
+
data.tar.gz: 2743e4c121c12c3b14e4950f06027323971124de410e4588809ed685d3ff1155
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ea6017284805b9beb507ea6b936ca4dd6665ecd63fdae69f5f6855c25000fe5ffb1bf4f3b05adae42ac2bc02abafab5b65e77023a8de60425858b26f6531aa62
|
7
|
+
data.tar.gz: a68821b07b92b04789bdb8d02db165b90315b12222d41de1b5b11dda43bdf3174f8e6333b40fe5e08c6c8f9e969602a9fe62d29f0ec521a97aed946c9be1640a
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2019 Matthias Grosser
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
[![Gem Version](https://badge.fury.io/rb/girocode.svg)](http://badge.fury.io/rb/girocode) [![Build Status](https://travis-ci.org/mtgrosser/girocode.svg)](https://travis-ci.org/mtgrosser/girocode)
|
2
|
+
# Girocode - create EPC QR codes for SEPA bank transfers
|
3
|
+
|
4
|
+
Pure Ruby library to generate QR codes in SVG, PNG, HTML or ASCII format
|
5
|
+
|
6
|
+
![Girocode](https://raw.githubusercontent.com/mtgrosser/girocode/master/test/demo.png)
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile:
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
gem 'girocode'
|
14
|
+
```
|
15
|
+
|
16
|
+
## Usage
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
code = Girocode.new(iban: 'DE02100500000054540402',
|
20
|
+
name: 'Beispiel AG',
|
21
|
+
currency: 'EUR', amount: 123.45,
|
22
|
+
reference: 'RE 2019/05/445 744507')
|
23
|
+
code.to_svg
|
24
|
+
code.to_png
|
25
|
+
code.to_html
|
26
|
+
code.to_ascii
|
27
|
+
|
28
|
+
# in your console
|
29
|
+
puts code.to_ansi
|
30
|
+
```
|
data/Rakefile
ADDED
data/lib/girocode.rb
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
module Girocode
|
2
|
+
class Error < StandardError; end
|
3
|
+
|
4
|
+
class Code
|
5
|
+
ATTRIBUTES = %i[bic name iban currency amount purpose creditor_reference reference bto_info]
|
6
|
+
attr_reader *ATTRIBUTES
|
7
|
+
|
8
|
+
MAX_PAYLOAD_BYTES = 331
|
9
|
+
AMOUNT_RANGE = BigDecimal('0.01')..BigDecimal('999999999.99')
|
10
|
+
|
11
|
+
def initialize(**attrs)
|
12
|
+
if keys = attrs.keys - ATTRIBUTES and not keys.empty?
|
13
|
+
raise ArgumentError, "Illegal attributes #{keys.inspect}"
|
14
|
+
end
|
15
|
+
attrs.each { |attr, value| send("#{attr}=", value) }
|
16
|
+
raise ArgumentError, "iban is required" unless iban?
|
17
|
+
raise ArgumentError, "name is required" unless name?
|
18
|
+
raise ArgumentError, 'currency is required for amount' if amount && !currency?
|
19
|
+
raise ArgumentError, "either creditor reference or reference may be set" if creditor_reference? && reference?
|
20
|
+
raise ArgumentError, "payload too long" if payload.bytesize > MAX_PAYLOAD_BYTES
|
21
|
+
end
|
22
|
+
|
23
|
+
def bic=(value)
|
24
|
+
if value.nil?
|
25
|
+
@bic = nil
|
26
|
+
else
|
27
|
+
bic = Bank::BIC.new(value)
|
28
|
+
raise ArgumentError, "Invalid BIC #{value.inspect}" unless bic.valid?
|
29
|
+
@bic = bic.to_s
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def name=(value)
|
34
|
+
value = value.strip
|
35
|
+
raise ArgumentError, 'name is required' unless value
|
36
|
+
raise ArgumentError, 'name too long' if value.size > 70
|
37
|
+
raise ArgumentError, 'Illegal name' if value.include?("\n") || value.include?("\r")
|
38
|
+
@name = value
|
39
|
+
end
|
40
|
+
|
41
|
+
def iban=(value)
|
42
|
+
iban = Bank::IBAN.new(value)
|
43
|
+
raise ArgumentError, "Invalid IBAN #{value.inspect}" unless iban.valid?
|
44
|
+
@iban = iban.to_s
|
45
|
+
end
|
46
|
+
|
47
|
+
def currency=(value)
|
48
|
+
value = value.to_s.upcase
|
49
|
+
raise ArgumentError, "Invalid currency" unless value.match?(/\A[A-Z]{3}\z/)
|
50
|
+
@currency = value
|
51
|
+
end
|
52
|
+
|
53
|
+
def amount=(value)
|
54
|
+
raise ArgumentError, 'amount is required' unless value
|
55
|
+
value = BigDecimal(value, Float::DIG + 1)
|
56
|
+
raise ArgumentError, "invalid amount #{value.inspect}" unless AMOUNT_RANGE.cover?(value)
|
57
|
+
@amount = value
|
58
|
+
end
|
59
|
+
|
60
|
+
def purpose=(value)
|
61
|
+
unless value.nil?
|
62
|
+
raise ArgumentError, "invalid purpose #{value.inspect}" unless value.match?(/\A[A-z0-9]{0,4}\z/)
|
63
|
+
end
|
64
|
+
@purpose = value
|
65
|
+
end
|
66
|
+
|
67
|
+
def creditor_reference=(value)
|
68
|
+
unless value.nil?
|
69
|
+
raise ArgumentError, "invalid creditor reference #{value.inspect}" if value.include?("\n") || value.include?("\r") || value.size > 35
|
70
|
+
end
|
71
|
+
@creditor_reference = value
|
72
|
+
end
|
73
|
+
|
74
|
+
def reference=(value)
|
75
|
+
unless value.nil?
|
76
|
+
raise ArgumentError, "invalid reference #{value.inspect}" if value.include?("\n") || value.include?("\r") || value.size > 140
|
77
|
+
end
|
78
|
+
@reference = value
|
79
|
+
end
|
80
|
+
|
81
|
+
def bto_info=(value)
|
82
|
+
unless value.nil?
|
83
|
+
raise ArgumentError, "invalid bto_info #{value.inspect}" if value.include?("\n") || value.include?("\r") || value.size > 70
|
84
|
+
end
|
85
|
+
@bto_info = value
|
86
|
+
end
|
87
|
+
|
88
|
+
ATTRIBUTES.each do |attr|
|
89
|
+
define_method("#{attr}?") do
|
90
|
+
value = instance_variable_get("@#{attr}")
|
91
|
+
value.respond_to?(:empty?) ? !value.empty? : !!value
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def payload
|
96
|
+
['BCD', '002', '1', 'SCT',
|
97
|
+
bic, name, iban,formatted_amount, purpose,
|
98
|
+
creditor_reference || reference, bto_info].map(&:to_s).join("\n")
|
99
|
+
end
|
100
|
+
|
101
|
+
def to_qrcode
|
102
|
+
RQRCode::QRCode.new(payload, level: :m, mode: :byte_8bit)
|
103
|
+
end
|
104
|
+
|
105
|
+
def to_ascii
|
106
|
+
to_qrcode.to_s
|
107
|
+
end
|
108
|
+
|
109
|
+
%i[png svg html ansi].each do |format|
|
110
|
+
define_method("to_#{format}") { |*args| to_qrcode.public_send("as_#{format}", *args) }
|
111
|
+
end
|
112
|
+
|
113
|
+
private
|
114
|
+
|
115
|
+
def formatted_amount
|
116
|
+
"#{currency}#{amount.round(2).to_s('F')}" if currency? && amount
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
metadata
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: girocode
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Matthias Grosser
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-05-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rqrcode
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bank-contact
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.17'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.17'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: minitest
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '5.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '5.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: simplecov
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: EPC QR code for SEPA payments in any format
|
98
|
+
email:
|
99
|
+
- mtgrosser@gmx.net
|
100
|
+
executables: []
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- LICENSE
|
105
|
+
- README.md
|
106
|
+
- Rakefile
|
107
|
+
- lib/girocode.rb
|
108
|
+
- lib/girocode/code.rb
|
109
|
+
- lib/girocode/version.rb
|
110
|
+
homepage: https://github.com/mtgrosser/girocode
|
111
|
+
licenses:
|
112
|
+
- MIT
|
113
|
+
metadata: {}
|
114
|
+
post_install_message:
|
115
|
+
rdoc_options: []
|
116
|
+
require_paths:
|
117
|
+
- lib
|
118
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '0'
|
123
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
124
|
+
requirements:
|
125
|
+
- - ">="
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
requirements: []
|
129
|
+
rubygems_version: 3.0.3
|
130
|
+
signing_key:
|
131
|
+
specification_version: 4
|
132
|
+
summary: Generate QR codes for SEPA credit transfers
|
133
|
+
test_files: []
|