prawn-swiss_qr_bill 0.4.2 → 0.5.2
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.
- checksums.yaml +4 -4
- data/README.md +37 -7
- data/lib/prawn/swiss_qr_bill/bill.rb +3 -2
- data/lib/prawn/swiss_qr_bill/corner_box.rb +2 -0
- data/lib/prawn/swiss_qr_bill/extension.rb +2 -2
- data/lib/prawn/swiss_qr_bill/qr/data.rb +76 -16
- data/lib/prawn/swiss_qr_bill/reference.rb +98 -0
- data/lib/prawn/swiss_qr_bill/sections/payment_information.rb +2 -2
- data/lib/prawn/swiss_qr_bill/sections/qr_code.rb +9 -7
- data/lib/prawn/swiss_qr_bill/sections/section.rb +2 -1
- data/lib/prawn/swiss_qr_bill/sections.rb +2 -2
- data/lib/prawn/swiss_qr_bill/specifications.rb +1 -0
- data/lib/prawn/swiss_qr_bill/version.rb +1 -1
- data/lib/prawn/swiss_qr_bill.rb +1 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 38df96b8ac1e36c19b8e887a1704dc3af8494bec29fa2cbd99f4e7d536079b09
|
4
|
+
data.tar.gz: a996978e775f4a7cbbdefce2ebec4b2e6fc1ba12d3916da6b6ee9eed22b4a754
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b5f1530805035de0d2a744f1ac3ed83520710dfc4de4bb3b0b01fcaf430f41fbe3fb86720c0f1dcb41cfbdfeedf9be6bdf9d28bf9bb7fe2a4c90ed32f982d48a
|
7
|
+
data.tar.gz: d2b5985d953531ad271585cdd6f7bc8f4a223a764254c5b558c87de7f9adb2035e64450410d9d100a7ed0056eb3ef676e9db22c3e7fad79ba968502b56b93828
|
data/README.md
CHANGED
@@ -30,7 +30,7 @@ Define the relevant information for the Swiss QR-bill and render it inside the P
|
|
30
30
|
require 'prawn'
|
31
31
|
require 'prawn/swiss_qr_bill'
|
32
32
|
|
33
|
-
@
|
33
|
+
@bill_data = {
|
34
34
|
creditor: {
|
35
35
|
iban: 'CH08 3080 8004 1110 4136 9',
|
36
36
|
address: {
|
@@ -43,13 +43,15 @@ require 'prawn/swiss_qr_bill'
|
|
43
43
|
amount: 9.90,
|
44
44
|
currency: 'CHF',
|
45
45
|
reference: '00 00000 00000 02202 20202 99991',
|
46
|
-
reference_type: 'QRR'
|
46
|
+
reference_type: 'QRR',
|
47
|
+
unstructured_message: 'Bill number 2202.20202.9999',
|
48
|
+
bill_information: '//S1/10/2202202029999/11/220819'
|
47
49
|
}
|
48
50
|
|
49
51
|
Prawn::Document.generate('output.pdf', page_size: 'A4') do
|
50
52
|
text 'A Swiss QR bill'
|
51
53
|
|
52
|
-
swiss_qr_bill(@
|
54
|
+
swiss_qr_bill(@bill_data)
|
53
55
|
end
|
54
56
|
```
|
55
57
|
|
@@ -57,13 +59,13 @@ This will render the Swiss QR-bill at the bottom of the page:
|
|
57
59
|
|
58
60
|

|
59
61
|
|
60
|
-
###
|
62
|
+
### Bill data structure
|
61
63
|
|
62
|
-
The following
|
64
|
+
The following data structure for the bill can be specified:
|
63
65
|
|
64
66
|
```ruby
|
65
67
|
# *: mandatory
|
66
|
-
@
|
68
|
+
@bill_data = {
|
67
69
|
creditor: {
|
68
70
|
iban: '<iban>', # *
|
69
71
|
address: { # *
|
@@ -96,9 +98,37 @@ The following options are available:
|
|
96
98
|
|
97
99
|
If `debtor` or `amount` amount is not given, a box will be printed.
|
98
100
|
|
101
|
+
### Options
|
102
|
+
|
103
|
+
Calling `swiss_qr_bill()` method with options:
|
104
|
+
|
105
|
+
```ruby
|
106
|
+
# ...
|
107
|
+
Prawn::Document.generate('output.pdf', page_size: 'A4') do
|
108
|
+
# ...
|
109
|
+
|
110
|
+
# raises InvalidIBANError when @bill_data[:creditor][:iban] is invalid
|
111
|
+
swiss_qr_bill(@bill_data, validate: true)
|
112
|
+
end
|
113
|
+
```
|
114
|
+
|
115
|
+
Available options:
|
116
|
+
|
117
|
+
| Option | Data type | Description | Default |
|
118
|
+
| --- | --- | --- | --- |
|
119
|
+
| `validate` | boolean | Validates IBAN and Reference Number and raises several errors | `false` |
|
120
|
+
|
121
|
+
Errors which can be raised during validation:
|
122
|
+
|
123
|
+
* `MissingIBANError`: When IBAN is missing.
|
124
|
+
* `InvalidIBANError`: When IBAN is invalid. It checks for CH-IBAN only.
|
125
|
+
* `InvalidReferenceError`: When reference is invalid. It checks for a valid QRR or SCOR reference
|
126
|
+
|
99
127
|
## Important
|
100
128
|
|
101
|
-
This library
|
129
|
+
This library can validate IBAN (switzerland only) and reference number (types QRR and SCOR).
|
130
|
+
It does not however validate, if the given data is fully valid according to the implementation guidelines.
|
131
|
+
|
102
132
|
Please refer to the implementation guidelines and the Swiss QR-bill validaton
|
103
133
|
portal by SIX below.
|
104
134
|
|
@@ -6,16 +6,17 @@ module Prawn
|
|
6
6
|
class Bill
|
7
7
|
FONT_DIR = File.expand_path("#{__dir__}/../../../assets/fonts")
|
8
8
|
|
9
|
-
def initialize(document, data)
|
9
|
+
def initialize(document, data, options = {})
|
10
10
|
@doc = document
|
11
11
|
@data = data
|
12
|
+
@options = options || {}
|
12
13
|
end
|
13
14
|
|
14
15
|
def draw
|
15
16
|
set_font
|
16
17
|
|
17
18
|
@doc.canvas do
|
18
|
-
Sections.draw_all(@doc, @data)
|
19
|
+
Sections.draw_all(@doc, @data, @options)
|
19
20
|
CuttingLines.new(@doc).draw
|
20
21
|
end
|
21
22
|
end
|
@@ -4,8 +4,8 @@ module Prawn
|
|
4
4
|
module SwissQRBill
|
5
5
|
# Extend prawn with *swiss_qr_bill* methods
|
6
6
|
module Extension
|
7
|
-
def swiss_qr_bill(data)
|
8
|
-
Prawn::SwissQRBill::Bill.new(self, data).draw
|
7
|
+
def swiss_qr_bill(data, options = {})
|
8
|
+
Prawn::SwissQRBill::Bill.new(self, data, options).draw
|
9
9
|
end
|
10
10
|
|
11
11
|
def swiss_qr_bill_sections
|
@@ -3,21 +3,24 @@
|
|
3
3
|
module Prawn
|
4
4
|
module SwissQRBill
|
5
5
|
module QR
|
6
|
+
class MissingIBANError < StandardError; end
|
7
|
+
class InvalidIBANError < StandardError; end
|
8
|
+
class InvalidReferenceError < StandardError; end
|
9
|
+
|
6
10
|
# The data of the Swiss QR-bill
|
7
11
|
#
|
8
12
|
# References:
|
9
13
|
# https://www.paymentstandards.ch/dam/downloads/ig-qr-bill-en.pdf
|
10
14
|
# * Chapter 4, Page 25
|
11
|
-
#
|
12
|
-
# TODO: implement skippable (alt schemas, bill info. fields after trailer)
|
13
|
-
# TODO: check if addr-type has to be mentioned if not given?
|
14
|
-
# OPTIMIZE: implement non-changable?
|
15
15
|
class Data
|
16
|
-
#
|
16
|
+
# Field structure:
|
17
17
|
# * :default => default value to be set, if key is not given
|
18
18
|
# * :format => Proc to call when generating output
|
19
19
|
# * :skippable => Do not output in QR data if not given
|
20
|
-
|
20
|
+
# * :validation => Proc or symbol for validation
|
21
|
+
# * if Proc given: will be called with value as argument
|
22
|
+
# * if symbol given: method "#{:symbol}_validator" will be called with value as argument
|
23
|
+
Field = Struct.new(:default, :format, :skippable, :validation)
|
21
24
|
|
22
25
|
# Available fields of the QR code data, ordered.
|
23
26
|
FIELDS = {
|
@@ -26,9 +29,7 @@ module Prawn
|
|
26
29
|
version: Field.new('0200'),
|
27
30
|
# fixed: 1
|
28
31
|
coding: Field.new('1'),
|
29
|
-
|
30
|
-
# iban: Field.new(nil, ->(value) { value.delete(' ') }),
|
31
|
-
iban: Field.new,
|
32
|
+
iban: Field.new(nil, nil, false, :iban),
|
32
33
|
# enum: S, K
|
33
34
|
creditor_address_type: Field.new('K'),
|
34
35
|
creditor_address_name: Field.new,
|
@@ -59,22 +60,20 @@ module Prawn
|
|
59
60
|
debtor_address_country: Field.new,
|
60
61
|
# enum: QRR, SCOR, NON
|
61
62
|
reference_type: Field.new('NON'),
|
62
|
-
reference: Field.new(nil, ->(
|
63
|
+
reference: Field.new(nil, ->(v) { v && v.delete(' ') }, false, :reference),
|
63
64
|
unstructured_message: Field.new,
|
64
65
|
# fixed: EPD
|
65
66
|
trailer: Field.new('EPD'),
|
66
|
-
|
67
|
-
# additional:
|
68
|
-
|
69
67
|
bill_information: Field.new(nil, nil, true),
|
70
68
|
# key-value pairs:
|
71
69
|
alternative_parameters: Field.new(nil, nil, true)
|
72
70
|
}.freeze
|
73
71
|
|
74
|
-
# TODO: check if all fields can be changed by user?
|
75
72
|
attr_accessor(*FIELDS.keys)
|
76
73
|
|
77
|
-
def initialize(fields = {})
|
74
|
+
def initialize(fields = {}, options = {})
|
75
|
+
@options = options || {}
|
76
|
+
|
78
77
|
# set defaults
|
79
78
|
FIELDS.each_key do |field|
|
80
79
|
instance_variable_set("@#{field}", FIELDS[field].default)
|
@@ -87,18 +86,79 @@ module Prawn
|
|
87
86
|
end
|
88
87
|
|
89
88
|
def generate
|
89
|
+
validate if @options[:validate]
|
90
|
+
|
90
91
|
stack = []
|
91
|
-
FIELDS.
|
92
|
+
FIELDS.each_key do |k|
|
92
93
|
var = instance_variable_get("@#{k}")
|
93
94
|
|
95
|
+
# TODO: fix possible wrong format if alt parameters (last one) is given
|
94
96
|
next if FIELDS[k][:skippable] && var.nil?
|
95
97
|
|
98
|
+
# TODO: use #process; generate method should only call validate, then process, then render as string
|
96
99
|
var = FIELDS[k][:format].call(var) if FIELDS[k][:format].is_a?(Proc)
|
97
100
|
|
98
101
|
stack << var
|
99
102
|
end
|
100
103
|
stack.join("\r\n")
|
101
104
|
end
|
105
|
+
|
106
|
+
def process
|
107
|
+
FIELDS.each_key do |k|
|
108
|
+
var = instance_variable_get("@#{k}")
|
109
|
+
|
110
|
+
instance_variable_set("@#{k}", FIELDS[k][:format].call(var)) if FIELDS[k][:format].is_a?(Proc)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def validate
|
115
|
+
FIELDS.each_key do |k|
|
116
|
+
next unless FIELDS[k][:validation]
|
117
|
+
|
118
|
+
var = instance_variable_get("@#{k}")
|
119
|
+
|
120
|
+
call_validator(FIELDS[k][:validation], var)
|
121
|
+
end
|
122
|
+
|
123
|
+
true
|
124
|
+
end
|
125
|
+
|
126
|
+
private
|
127
|
+
|
128
|
+
def call_validator(validator, value)
|
129
|
+
case validator
|
130
|
+
when Proc
|
131
|
+
# NOTE: currently not in use
|
132
|
+
# :nocov:
|
133
|
+
validator.call(value)
|
134
|
+
# :nocov:
|
135
|
+
when Symbol
|
136
|
+
send("#{validator}_validator", value)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def iban_validator(value)
|
141
|
+
# IBAN must be given
|
142
|
+
raise MissingIBANError, 'IBAN is missing' if value.nil? || value.empty?
|
143
|
+
|
144
|
+
# IBAN must be valid
|
145
|
+
iban = IBAN.new(value)
|
146
|
+
raise InvalidIBANError, "IBAN #{iban.prettify} is invalid" unless iban.valid?
|
147
|
+
|
148
|
+
true
|
149
|
+
end
|
150
|
+
|
151
|
+
def reference_validator(value)
|
152
|
+
reference = Reference.new(value, reference_type)
|
153
|
+
|
154
|
+
unless %w[QRR SCOR].include?(reference_type)
|
155
|
+
raise InvalidReferenceError, "Reference Type #{reference_type} invalid. Allowed: QRR, SCOR"
|
156
|
+
end
|
157
|
+
|
158
|
+
raise InvalidReferenceError, "Reference #{value} is invalid" unless reference.valid?
|
159
|
+
|
160
|
+
true
|
161
|
+
end
|
102
162
|
end
|
103
163
|
end
|
104
164
|
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Prawn
|
4
|
+
module SwissQRBill
|
5
|
+
# Check validity of reference number
|
6
|
+
#
|
7
|
+
# QRR reference:
|
8
|
+
# Refer to the implementation guides of SIX: https://www.paymentstandards.ch/dam/downloads/ig-qr-bill-en.pdf
|
9
|
+
class Reference
|
10
|
+
MODULO_TABLE = [
|
11
|
+
[0, 9, 4, 6, 8, 2, 7, 1, 3, 5],
|
12
|
+
[9, 4, 6, 8, 2, 7, 1, 3, 5, 0],
|
13
|
+
[4, 6, 8, 2, 7, 1, 3, 5, 0, 9],
|
14
|
+
[6, 8, 2, 7, 1, 3, 5, 0, 9, 4],
|
15
|
+
[8, 2, 7, 1, 3, 5, 0, 9, 4, 6],
|
16
|
+
[2, 7, 1, 3, 5, 0, 9, 4, 6, 8],
|
17
|
+
[7, 1, 3, 5, 0, 9, 4, 6, 8, 2],
|
18
|
+
[1, 3, 5, 0, 9, 4, 6, 8, 2, 7],
|
19
|
+
[3, 5, 0, 9, 4, 6, 8, 2, 7, 1],
|
20
|
+
[5, 0, 9, 4, 6, 8, 2, 7, 1, 3]
|
21
|
+
].freeze
|
22
|
+
|
23
|
+
def initialize(reference, type = 'QRR')
|
24
|
+
@type = type
|
25
|
+
@reference = standardize(reference)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Number without check digit
|
29
|
+
def number
|
30
|
+
case @type
|
31
|
+
when 'QRR'
|
32
|
+
@reference[0...-1]
|
33
|
+
when 'SCOR'
|
34
|
+
@reference[4..-1]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# QRR: Last number, the check digit
|
39
|
+
# SCOR: 2 numbers after RF
|
40
|
+
def check_digits
|
41
|
+
case @type
|
42
|
+
when 'QRR'
|
43
|
+
@reference[-1].to_i
|
44
|
+
when 'SCOR'
|
45
|
+
@reference[2..3]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def valid?
|
50
|
+
valid_check_digits? && valid_length?
|
51
|
+
end
|
52
|
+
|
53
|
+
def valid_check_digits?
|
54
|
+
case @type
|
55
|
+
when 'QRR'
|
56
|
+
check_digits == Reference.modulo10_recursive(number)
|
57
|
+
when 'SCOR'
|
58
|
+
scor_to_i % 97 == 1
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# NOTE: for SCOR only
|
63
|
+
def scor_to_i
|
64
|
+
"#{number}RF#{check_digits}".gsub(/[A-Z]/) { |c| c.ord - 55 }.to_i
|
65
|
+
end
|
66
|
+
|
67
|
+
# According to the payment standards (PDF, Annex B):
|
68
|
+
# The QR reference consists of 27 positions and is numerical.
|
69
|
+
def valid_length?
|
70
|
+
case @type
|
71
|
+
when 'QRR'
|
72
|
+
@reference.length <= 27
|
73
|
+
when 'SCOR'
|
74
|
+
@reference.length <= 25
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Generate a check digit with modulo 10 recursive:
|
79
|
+
#
|
80
|
+
# Can be used as an instance method:
|
81
|
+
#
|
82
|
+
# Prawn::SwissQRBill::Reference.modulo10_recursive("2202202029999")
|
83
|
+
# # will return 1
|
84
|
+
def self.modulo10_recursive(reference)
|
85
|
+
numbers = reference.to_s.chars.map(&:to_i)
|
86
|
+
report = numbers.inject(0) { |memo, c| MODULO_TABLE[memo][c] }
|
87
|
+
|
88
|
+
(10 - report) % 10
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def standardize(reference)
|
94
|
+
reference.to_s.strip.gsub(/\s+/, '').upcase
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -13,7 +13,7 @@ module Prawn
|
|
13
13
|
box do
|
14
14
|
draw_payable_to
|
15
15
|
draw_reference if @data.key?(:reference)
|
16
|
-
draw_additional_information if @data.key?(:
|
16
|
+
draw_additional_information if @data.key?(:unstructured_message) || @data.key?(:bill_information)
|
17
17
|
draw_payable_by
|
18
18
|
end
|
19
19
|
end
|
@@ -37,7 +37,7 @@ module Prawn
|
|
37
37
|
|
38
38
|
def draw_additional_information
|
39
39
|
label I18n.t('additional_info', scope: i18n_scope)
|
40
|
-
content @data[:
|
40
|
+
content [@data[:unstructured_message], @data[:bill_information]].join(' ')
|
41
41
|
|
42
42
|
line_spacing
|
43
43
|
end
|
@@ -11,8 +11,6 @@ module Prawn
|
|
11
11
|
#
|
12
12
|
# swiss_cross.png => 166px ~> 7.mm
|
13
13
|
# QR-code: 1090px <~ 46.mm
|
14
|
-
#
|
15
|
-
# TODO: iban check -> raise exception if configured
|
16
14
|
class QRCode < Section
|
17
15
|
KEY = 'payment.qr_code'
|
18
16
|
|
@@ -26,6 +24,7 @@ module Prawn
|
|
26
24
|
creditor_address_line1: %i[creditor address line1],
|
27
25
|
creditor_address_line2: %i[creditor address line2],
|
28
26
|
creditor_address_postal_code: %i[creditor address postal_code],
|
27
|
+
creditor_address_city: %i[creditor address city],
|
29
28
|
creditor_address_country: %i[creditor address country],
|
30
29
|
debtor_address_type: %i[debtor address type],
|
31
30
|
debtor_address_name: %i[debtor address name],
|
@@ -37,7 +36,9 @@ module Prawn
|
|
37
36
|
amount: [:amount],
|
38
37
|
currency: [:currency],
|
39
38
|
reference: [:reference],
|
40
|
-
reference_type: [:reference_type]
|
39
|
+
reference_type: [:reference_type],
|
40
|
+
unstructured_message: [:unstructured_message],
|
41
|
+
bill_information: [:bill_information]
|
41
42
|
}.freeze
|
42
43
|
|
43
44
|
def draw
|
@@ -71,16 +72,17 @@ module Prawn
|
|
71
72
|
end
|
72
73
|
|
73
74
|
def generate_qr_data(data)
|
74
|
-
|
75
|
+
flat_data = {}
|
75
76
|
MAPPING.each_key do |key|
|
76
|
-
# check if the exists
|
77
|
+
# check if the key exists
|
77
78
|
next unless deep_key?(data, MAPPING[key])
|
78
79
|
|
79
|
-
|
80
|
+
flat_data[key] = data.dig(*MAPPING[key])
|
80
81
|
end
|
81
82
|
|
82
83
|
iban = IBAN.new(data[:creditor][:iban])
|
83
|
-
|
84
|
+
|
85
|
+
qr_data = QR::Data.new(flat_data.merge(iban: iban.code), validate: @options[:validate])
|
84
86
|
qr_data.generate
|
85
87
|
end
|
86
88
|
|
@@ -19,13 +19,14 @@ module Prawn
|
|
19
19
|
# specifications for subclass' section, @see Specification for details
|
20
20
|
attr_accessor :specs
|
21
21
|
|
22
|
-
def initialize(document, data)
|
22
|
+
def initialize(document, data, options = {})
|
23
23
|
unless self.class.const_defined?(:KEY)
|
24
24
|
raise NotImplementedError, "constant KEY not defined in class #{self.class}"
|
25
25
|
end
|
26
26
|
|
27
27
|
@doc = document
|
28
28
|
@data = data
|
29
|
+
@options = options || {}
|
29
30
|
|
30
31
|
load_specs
|
31
32
|
end
|
@@ -19,9 +19,9 @@ module Prawn
|
|
19
19
|
].freeze
|
20
20
|
|
21
21
|
# Draw all sections in the right order.
|
22
|
-
def self.draw_all(document, data)
|
22
|
+
def self.draw_all(document, data, options = {})
|
23
23
|
SECTION_CLASSES.each do |klass|
|
24
|
-
klass.new(document, data).draw
|
24
|
+
klass.new(document, data, options).draw
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
data/lib/prawn/swiss_qr_bill.rb
CHANGED
@@ -17,6 +17,7 @@ require 'prawn/swiss_qr_bill/helpers/box_helper'
|
|
17
17
|
|
18
18
|
require 'prawn/swiss_qr_bill/qr/data'
|
19
19
|
require 'prawn/swiss_qr_bill/iban'
|
20
|
+
require 'prawn/swiss_qr_bill/reference'
|
20
21
|
require 'prawn/swiss_qr_bill/padded_box'
|
21
22
|
require 'prawn/swiss_qr_bill/corner_box'
|
22
23
|
require 'prawn/swiss_qr_bill/cutting_lines'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prawn-swiss_qr_bill
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mischa Schindowski
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-08-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: i18n
|
@@ -179,6 +179,7 @@ files:
|
|
179
179
|
- lib/prawn/swiss_qr_bill/iban.rb
|
180
180
|
- lib/prawn/swiss_qr_bill/padded_box.rb
|
181
181
|
- lib/prawn/swiss_qr_bill/qr/data.rb
|
182
|
+
- lib/prawn/swiss_qr_bill/reference.rb
|
182
183
|
- lib/prawn/swiss_qr_bill/sections.rb
|
183
184
|
- lib/prawn/swiss_qr_bill/sections/payment_amount.rb
|
184
185
|
- lib/prawn/swiss_qr_bill/sections/payment_further_information.rb
|
@@ -214,7 +215,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
214
215
|
- !ruby/object:Gem::Version
|
215
216
|
version: '0'
|
216
217
|
requirements: []
|
217
|
-
rubygems_version: 3.
|
218
|
+
rubygems_version: 3.2.32
|
218
219
|
signing_key:
|
219
220
|
specification_version: 4
|
220
221
|
summary: Swiss QR-Bill PDFs in Ruby with Prawn
|