qr-bills 1.0.6 → 1.0.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e42cdd23aaa75987946cb1b27226e4afd2f00208e4fef14f66c8902b8fb2f21d
4
- data.tar.gz: c233914960459d0c34945ac29785f210c65b6bdf4eabe2a0e0cf98fcd2a13d5b
3
+ metadata.gz: c2d737fda0dfd7323fadbb76cbc1fa33cbfc91f05b1410e26ea616092f68180c
4
+ data.tar.gz: 7f595ca806e98e6385412339cde55d4669e9fbd0a5d28381063f038f65b8642e
5
5
  SHA512:
6
- metadata.gz: 48028f52a989970df794f58a91c38611f30f3460fbe3b10067a4de778b7c211e75c890abda3bc5fea4b651ce294c65113d2ec26bc60bf6ab2e1974a616e22729
7
- data.tar.gz: 754babdd9ebac1262e68720b45e99c254fb2f83a8174134b9e6417593ba06b83ce61098cb6a2752434f1a05212ba63be52952aed4bba6c92ffb68511c4d08e79
6
+ metadata.gz: 891d5013c79f6b5a1651fd24092704e192640981ec2dc7197f4eedd33c43cd40cae3f6cf65c184828621d00731b38f713d5a0b1237d761f90994e3a5b7214892
7
+ data.tar.gz: ea6c560005eb23f7538ba63095331344263b1300a37f09a9951e28e2395733e95a6a7ac6e41fc5c3b6cc4dbcb901ce78a1f7c3f71f22d394ab7786fe87ed2fdd
@@ -1,6 +1,91 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rqrcode'
2
4
 
3
5
  module QRGenerator
6
+ def self.create(params, qrcode_path = nil)
7
+ format = params[:qrcode_format] || 'qrcode_png'
8
+
9
+ case format
10
+ when 'qrcode_png'
11
+ build_qrcode_png(params[:bill_params], qrcode_path)
12
+ when 'png'
13
+ build_png(params[:bill_params])
14
+ when 'svg'
15
+ build_svg(params[:bill_params])
16
+ else
17
+ raise ArgumentError, "#{QRExceptions::NOT_SUPPORTED}: #{format} is not yet supported"
18
+ end
19
+ end
20
+
21
+ def self.build_qrcode_png(bill_params, qrcode_path)
22
+ warn('DEPRECATION WARNING: The qrcode_png format and qrcode_filepath parameter are deprecated and will be removed from qr-bills 1.1 (use png or svg instead)')
23
+
24
+ final_qr = build_png(bill_params)
25
+ final_qr.save(qrcode_path)
26
+ final_qr
27
+ end
28
+
29
+ def self.build_png(bill_params)
30
+ payload = build_payload(bill_params)
31
+ qrcode = RQRCode::QRCode.new(payload, level: 'm')
32
+
33
+ png = qrcode.as_png(
34
+ bit_depth: 1,
35
+ border_modules: 0,
36
+ color_mode: ChunkyPNG::COLOR_GRAYSCALE,
37
+ color: 'black',
38
+ file: nil,
39
+ fill: 'white',
40
+ module_px_size: 10,
41
+ resize_exactly_to: false,
42
+ resize_gte_to: false,
43
+ size: 1024
44
+ )
45
+
46
+ swiss_cross = ChunkyPNG::Image.from_file(File.expand_path("#{File.dirname(__FILE__)}/../../web/assets/images/swiss_cross.png"))
47
+ png.compose!(swiss_cross, (png.width - swiss_cross.width) / 2, (png.height - swiss_cross.height) / 2)
48
+ end
49
+
50
+ def self.build_svg(bill_params)
51
+ payload = build_payload(bill_params)
52
+ qrcode = RQRCode::QRCode.new(payload, level: 'm')
53
+
54
+ # Generate qr code
55
+ svg_code = qrcode.as_svg(
56
+ standalone: true, # return a svg wrapper
57
+ viewbox: true, # return a viewBox so we can extract it
58
+ module_size: 10,
59
+ use_path: true
60
+ )
61
+
62
+ # Parse viewBox and calculate relative swiss cross size / center
63
+ viewbox = svg_code.match(/viewBox="([\s\d]*)"/)[1]
64
+ viewbox_size = viewbox.split(' ')[2].to_f
65
+ swiss_cross_size = viewbox_size / (46.0 / 7.0)
66
+ swiss_cross_center = (viewbox_size / 2.0) - (swiss_cross_size / 2.0)
67
+
68
+ # Parse swiss cross and update size and coordinates
69
+ svg_swiss_cross = File.open(File.expand_path("#{File.dirname(__FILE__)}/../../web/assets/images/swiss_cross.svg")).read
70
+ svg_swiss_cross.gsub!('SWISS_CROSS_SIZE', swiss_cross_size.to_s)
71
+ svg_swiss_cross.gsub!('SWISS_CROSS_CENTER', swiss_cross_center.to_s)
72
+
73
+ # Assemble svg
74
+ svg_code.gsub!(/<path/, '<g>\0')
75
+ svg_code.gsub!(/<\/svg>/, "#{svg_swiss_cross}</g></svg>")
76
+
77
+ # Optimize SVG for being URI-escaped
78
+ # Stolen from Sprockets: https://github.com/rails/sprockets/blob/master/lib/sprockets/context.rb#L277-L293
79
+ #
80
+ # This only performs these basic but crucial optimizations:
81
+ # * Removes comments, meta, doctype, and newlines.
82
+ # * Replaces " with ', because ' does not need escaping.
83
+ svg_code.gsub!(/<!--.*?-->|<\?.*?\?>|<!.*?>/m, '')
84
+ svg_code.gsub!(/([\w:])="(.*?)"/, "\\1='\\2'")
85
+
86
+ svg_code
87
+ end
88
+
4
89
  # payload:
5
90
  # "SPC\r\n" + # indicator for swiss qr code: SPC (swiss payments code)
6
91
  # "0200\r\n" + # version of the specifications, 0200 = v2.0
@@ -35,19 +120,18 @@ module QRGenerator
35
120
  # "EPD\r\n" + # fixed indicator for EPD (end payment data)
36
121
  # "//S1/10/10201409/11/181105/40/0:30\r\n" + # bill information coded for automated booking of payment, data is not forwarded with the payment
37
122
  # "eBill/B/41010560425610173"; # alternative scheme paramaters, max 100 chars
38
-
39
- def self.create(params, qrcode_path)
123
+ def self.build_payload(bill_params)
40
124
  payload = "SPC\r\n"
41
125
  payload += "0200\r\n"
42
126
  payload += "1\r\n"
43
- payload += "#{params[:bill_params][:creditor][:iban].delete(' ')}\r\n"
44
- payload += "#{params[:bill_params][:creditor][:address][:type]}\r\n"
45
- payload += "#{params[:bill_params][:creditor][:address][:name]}\r\n"
46
- payload += "#{params[:bill_params][:creditor][:address][:line1]}\r\n"
47
- payload += "#{params[:bill_params][:creditor][:address][:line2]}\r\n"
48
- payload += "#{params[:bill_params][:creditor][:address][:postal_code]}\r\n"
49
- payload += "#{params[:bill_params][:creditor][:address][:town]}\r\n"
50
- payload += "#{params[:bill_params][:creditor][:address][:country]}\r\n"
127
+ payload += "#{bill_params[:creditor][:iban].delete(' ')}\r\n"
128
+ payload += "#{bill_params[:creditor][:address][:type]}\r\n"
129
+ payload += "#{bill_params[:creditor][:address][:name]}\r\n"
130
+ payload += "#{bill_params[:creditor][:address][:line1]}\r\n"
131
+ payload += "#{bill_params[:creditor][:address][:line2]}\r\n"
132
+ payload += "#{bill_params[:creditor][:address][:postal_code]}\r\n"
133
+ payload += "#{bill_params[:creditor][:address][:town]}\r\n"
134
+ payload += "#{bill_params[:creditor][:address][:country]}\r\n"
51
135
  payload += "\r\n"
52
136
  payload += "\r\n"
53
137
  payload += "\r\n"
@@ -55,39 +139,20 @@ module QRGenerator
55
139
  payload += "\r\n"
56
140
  payload += "\r\n"
57
141
  payload += "\r\n"
58
- payload += "#{format('%.2f', params[:bill_params][:amount])}\r\n"
59
- payload += "#{params[:bill_params][:currency]}\r\n"
60
- payload += "#{params[:bill_params][:debtor][:address][:type]}\r\n"
61
- payload += "#{params[:bill_params][:debtor][:address][:name]}\r\n"
62
- payload += "#{params[:bill_params][:debtor][:address][:line1]}\r\n"
63
- payload += "#{params[:bill_params][:debtor][:address][:line2]}\r\n"
64
- payload += "#{params[:bill_params][:debtor][:address][:postal_code]}\r\n"
65
- payload += "#{params[:bill_params][:debtor][:address][:town]}\r\n"
66
- payload += "#{params[:bill_params][:debtor][:address][:country]}\r\n"
67
- payload += "#{params[:bill_params][:reference_type]}\r\n"
68
- payload += "#{params[:bill_params][:reference].delete(' ')}\r\n"
69
- payload += "#{params[:bill_params][:additionally_information]}\r\n"
142
+ payload += "#{format('%.2f', bill_params[:amount])}\r\n"
143
+ payload += "#{bill_params[:currency]}\r\n"
144
+ payload += "#{bill_params[:debtor][:address][:type]}\r\n"
145
+ payload += "#{bill_params[:debtor][:address][:name]}\r\n"
146
+ payload += "#{bill_params[:debtor][:address][:line1]}\r\n"
147
+ payload += "#{bill_params[:debtor][:address][:line2]}\r\n"
148
+ payload += "#{bill_params[:debtor][:address][:postal_code]}\r\n"
149
+ payload += "#{bill_params[:debtor][:address][:town]}\r\n"
150
+ payload += "#{bill_params[:debtor][:address][:country]}\r\n"
151
+ payload += "#{bill_params[:reference_type]}\r\n"
152
+ payload += "#{bill_params[:reference].delete(' ')}\r\n"
153
+ payload += "#{bill_params[:additionally_information]}\r\n"
70
154
  payload += "EPD\r\n"
71
- payload += "#{params[:bill_params][:bill_information_coded]}\r\n"
72
- payload += "#{params[:bill_params][:alternative_scheme_parameters]}\r\n"
73
-
74
- qrcode = RQRCode::QRCode.new(payload, level: 'm')
75
-
76
- png = qrcode.as_png(
77
- bit_depth: 1,
78
- border_modules: 0,
79
- color_mode: ChunkyPNG::COLOR_GRAYSCALE,
80
- color: 'black',
81
- file: nil,
82
- fill: 'white',
83
- module_px_size: 10,
84
- resize_exactly_to: false,
85
- resize_gte_to: false,
86
- size: 1024,
87
- )
88
-
89
- swiss_cross = ChunkyPNG::Image.from_file(File.expand_path("#{File.dirname(__FILE__)}/../../web/assets/images/swiss_cross.png"))
90
- final_qr = png.compose!(swiss_cross, (png.width - swiss_cross.width) / 2, (png.height - swiss_cross.height) / 2)
91
- final_qr.save(qrcode_path)
155
+ payload += "#{bill_params[:bill_information_coded]}\r\n"
156
+ payload += "#{bill_params[:alternative_scheme_parameters]}\r\n"
92
157
  end
93
- end
158
+ end
@@ -1,236 +1,256 @@
1
1
  require 'qr-bills/qr-generator'
2
2
 
3
3
  module QRHTMLLayout
4
-
5
4
  def self.create(params)
6
- QRGenerator.create(params, params[:qrcode_filepath])
7
- return html_layout(params)
5
+ qrcode = QRGenerator.create(params, params[:qrcode_filepath])
6
+ params[:qrcode_filepath] = convert_qrcode_to_data_url(qrcode)
7
+ html_layout(params)
8
8
  end
9
9
 
10
- def self.html_layout(params)
11
- I18n.locale = params[:bill_params][:language]
12
- layout = "<div class=\"bill_container\">\n"
13
- layout += " <div class=\"receipt_section\">\n"
14
- layout += " <div class=\"title\">#{I18n.t("qrbills.receipt").capitalize}</div>\n"
15
- layout += " <div class=\"subtitle payable_to\">#{I18n.t("qrbills.account").capitalize} / #{I18n.t("qrbills.payable_to").capitalize}</div>\n"
16
- layout += " <div class=\"qrcontent\">\n"
17
- layout += " #{params[:bill_params][:creditor][:iban]}<br/>\n"
18
- layout += " #{params[:bill_params][:creditor][:address][:name]}<br/>\n"
19
- layout += " #{params[:bill_params][:creditor][:address][:line1]} #{params[:bill_params][:creditor][:address][:line2]}<br/>\n"
20
- layout += " #{params[:bill_params][:creditor][:address][:postal_code]} #{params[:bill_params][:creditor][:address][:town]}<br/>\n"
21
- layout += " </div>\n"
22
- layout += " <div><br/></div>\n"
23
-
24
- if !params[:bill_params][:reference].nil? && !params[:bill_params][:reference].empty?
25
- layout += " <div class=\"subtitle reference\">#{I18n.t("qrbills.reference").capitalize}</div>\n"
26
- layout += " <div class=\"reference\">\n"
27
- layout += " #{params[:bill_params][:reference]}<br/>\n"
28
- layout += " </div>\n"
29
- layout += " <div><br/></div>\n"
30
- end
10
+ def self.convert_qrcode_to_data_url(qrcode)
11
+ case qrcode
12
+ when ChunkyPNG::Image
13
+ qrcode.to_data_url
14
+ else
15
+ # Stolen from sprockets
16
+ # https://github.com/rails/sprockets/blob/0f3e0e93dabafa8f3027e8036e40fd08902688c8/lib/sprockets/context.rb#L295-L303
17
+ data = CGI.escape(qrcode)
18
+ data.gsub!('%3D', '=')
19
+ data.gsub!('%3A', ':')
20
+ data.gsub!('%2F', '/')
21
+ data.gsub!('%27', "'")
22
+ data.tr!('+', ' ')
31
23
 
32
- layout += " <div class=\"subtitle payable_by\">#{I18n.t("qrbills.payable_by").capitalize}</div>\n"
33
- layout += " <div class=\"payable_by\">\n"
34
- layout += " #{params[:bill_params][:debtor][:address][:name]}<br/>\n"
35
- layout += " #{params[:bill_params][:debtor][:address][:line1]} #{params[:bill_params][:debtor][:address][:line2]}<br/>\n"
36
- layout += " #{params[:bill_params][:debtor][:address][:postal_code]} #{params[:bill_params][:debtor][:address][:town]}<br/>\n"
37
- layout += " </div>\n"
38
-
39
- layout += " <div class=\"amount\">\n"
40
- layout += " <div class=\"currency\">\n"
41
- layout += " <span class=\"amount_header subtitle\">#{I18n.t("qrbills.currency").capitalize}</span><br/>\n"
42
- layout += " #{params[:bill_params][:currency]}<br/>\n"
43
- layout += " </div>\n"
44
-
45
- layout += " <div class=\"amount_value\">\n"
46
- layout += " <span class=\"amount_header subtitle\">#{I18n.t("qrbills.amount").capitalize}</span><br/>\n"
47
- layout += " #{format('%.2f', params[:bill_params][:amount])}<br/>\n"
48
- layout += " </div>\n"
49
- layout += " </div>\n"
50
-
51
- layout += " <div class=\"acceptance_point\">\n"
52
- layout += " #{I18n.t("qrbills.acceptance_point").capitalize}<br/>\n"
53
- layout += " </div>\n"
54
-
55
- layout += " </div>\n"
56
- layout += " <div class=\"payment_section\">\n"
57
- layout += " <div class=\"left_column\">\n"
58
- layout += " <div class=\"title\">#{I18n.t("qrbills.payment_part").capitalize}</div>\n"
59
- layout += " <div class=\"qr_code\"><img src=\"#{params[:qrcode_filepath]}\" /></div>\n"
60
- layout += " <div class=\"amount\">\n"
61
- layout += " <div class=\"currency\">\n"
62
- layout += " <span class=\"amount_header subtitle\">#{I18n.t("qrbills.currency").capitalize}</span><br/>\n"
63
- layout += " #{params[:bill_params][:currency]}<br/>\n"
64
- layout += " </div>\n"
65
-
66
- layout += " <div class=\"amount_value\">\n"
67
- layout += " <span class=\"amount_header subtitle\">#{I18n.t("qrbills.amount").capitalize}</span><br/>\n"
68
- layout += " #{format('%.2f',params[:bill_params][:amount])}<br/>\n"
69
- layout += " </div>\n"
70
- layout += " </div>\n"
71
-
72
- layout += " <div class=\"further_information\">\n"
73
-
74
- if !params[:bill_params][:bill_information_coded].nil? && !params[:bill_params][:bill_information_coded].empty?
75
- layout += " <span class=\"finfo_header\">#{I18n.t("qrbills.name").capitalize} AV1:</span> #{params[:bill_params][:bill_information_coded]}\n"
76
- end
77
-
78
- if !params[:bill_params][:alternative_scheme_parameters].nil? && !params[:bill_params][:alternative_scheme_parameters].empty?
79
- layout += " <span class=\"finfo_header\">#{I18n.t("qrbills.name").capitalize} AV2:</span> #{params[:bill_params][:alternative_scheme_parameters]}\n"
24
+ "data:image/svg+xml;charset=utf-8,#{data}"
80
25
  end
26
+ end
81
27
 
82
- layout += " </div>\n"
83
- layout += " </div>\n"
84
- layout += " <div class=\"right_column\">\n"
85
- layout += " <div class=\"subtitle payable_to\">#{I18n.t("qrbills.account").capitalize} / #{I18n.t("qrbills.payable_to").capitalize}</div>\n"
86
- layout += " <div class=\"qrcontent\">\n"
87
- layout += " #{params[:bill_params][:creditor][:iban]}<br/>\n"
88
- layout += " #{params[:bill_params][:creditor][:address][:name]}<br/>\n"
89
- layout += " #{params[:bill_params][:creditor][:address][:line1]} #{params[:bill_params][:creditor][:address][:line2]}<br/>\n"
90
- layout += " #{params[:bill_params][:creditor][:address][:postal_code]} #{params[:bill_params][:creditor][:address][:town]}<br/>\n"
91
- layout += " </div>\n"
92
- layout += " <div><br/></div>\n"
93
-
94
- if !params[:bill_params][:reference].nil? && !params[:bill_params][:reference].empty?
95
- layout += " <div class=\"subtitle reference\">#{I18n.t("qrbills.reference").capitalize}</div>\n"
96
- layout += " <div class=\"reference\">\n"
97
- layout += " #{params[:bill_params][:reference]}<br/>\n"
98
- layout += " </div>\n"
99
- layout += " <div><br/></div>\n"
100
- end
28
+ def self.html_layout(params)
29
+ I18n.with_locale(params[:bill_params][:language]) do
30
+ layout = "<div class=\"bill_container\">\n"
31
+ layout += " <div class=\"receipt_section\">\n"
32
+ layout += " <div class=\"title\">#{I18n.t("qrbills.receipt").capitalize}</div>\n"
33
+ layout += " <div class=\"subtitle payable_to\">#{I18n.t("qrbills.account").capitalize} / #{I18n.t("qrbills.payable_to").capitalize}</div>\n"
34
+ layout += " <div class=\"qrcontent\">\n"
35
+ layout += " #{params[:bill_params][:creditor][:iban]}<br/>\n"
36
+ layout += render_address(params[:bill_params][:creditor][:address])
37
+ layout += " </div>\n"
38
+ layout += " <div><br/></div>\n"
39
+
40
+ if !params[:bill_params][:reference].nil? && !params[:bill_params][:reference].empty?
41
+ layout += " <div class=\"subtitle reference\">#{I18n.t("qrbills.reference").capitalize}</div>\n"
42
+ layout += " <div class=\"reference\">\n"
43
+ layout += " #{params[:bill_params][:reference]}<br/>\n"
44
+ layout += " </div>\n"
45
+ layout += " <div><br/></div>\n"
46
+ end
47
+
48
+ layout += " <div class=\"subtitle payable_by\">#{I18n.t("qrbills.payable_by").capitalize}</div>\n"
49
+ layout += " <div class=\"payable_by\">\n"
50
+ layout += render_address(params[:bill_params][:debtor][:address])
51
+ layout += " </div>\n"
52
+
53
+ layout += " <div class=\"amount\">\n"
54
+ layout += " <div class=\"currency\">\n"
55
+ layout += " <span class=\"amount_header subtitle\">#{I18n.t("qrbills.currency").capitalize}</span><br/>\n"
56
+ layout += " #{params[:bill_params][:currency]}<br/>\n"
57
+ layout += " </div>\n"
58
+
59
+ layout += " <div class=\"amount_value\">\n"
60
+ layout += " <span class=\"amount_header subtitle\">#{I18n.t("qrbills.amount").capitalize}</span><br/>\n"
61
+ layout += " #{format('%.2f', params[:bill_params][:amount])}<br/>\n"
62
+ layout += " </div>\n"
63
+ layout += " </div>\n"
64
+
65
+ layout += " <div class=\"acceptance_point\">\n"
66
+ layout += " #{I18n.t("qrbills.acceptance_point").capitalize}<br/>\n"
67
+ layout += " </div>\n"
68
+
69
+ layout += " </div>\n"
70
+ layout += " <div class=\"payment_section\">\n"
71
+ layout += " <div class=\"left_column\">\n"
72
+ layout += " <div class=\"title\">#{I18n.t("qrbills.payment_part").capitalize}</div>\n"
73
+ layout += " <div class=\"qr_code\"><img src=\"#{params[:qrcode_filepath]}\" /></div>\n"
74
+ layout += " <div class=\"amount\">\n"
75
+ layout += " <div class=\"currency\">\n"
76
+ layout += " <span class=\"amount_header subtitle\">#{I18n.t("qrbills.currency").capitalize}</span><br/>\n"
77
+ layout += " #{params[:bill_params][:currency]}<br/>\n"
78
+ layout += " </div>\n"
79
+
80
+ layout += " <div class=\"amount_value\">\n"
81
+ layout += " <span class=\"amount_header subtitle\">#{I18n.t("qrbills.amount").capitalize}</span><br/>\n"
82
+ layout += " #{format('%.2f',params[:bill_params][:amount])}<br/>\n"
83
+ layout += " </div>\n"
84
+ layout += " </div>\n"
85
+
86
+ layout += " <div class=\"further_information\">\n"
87
+
88
+ if !params[:bill_params][:bill_information_coded].nil? && !params[:bill_params][:bill_information_coded].empty?
89
+ layout += " <span class=\"finfo_header\">#{I18n.t("qrbills.name").capitalize} AV1:</span> #{params[:bill_params][:bill_information_coded]}\n"
90
+ end
91
+
92
+ if !params[:bill_params][:alternative_scheme_parameters].nil? && !params[:bill_params][:alternative_scheme_parameters].empty?
93
+ layout += " <span class=\"finfo_header\">#{I18n.t("qrbills.name").capitalize} AV2:</span> #{params[:bill_params][:alternative_scheme_parameters]}\n"
94
+ end
95
+
96
+ layout += " </div>\n"
97
+ layout += " </div>\n"
98
+ layout += " <div class=\"right_column\">\n"
99
+ layout += " <div class=\"subtitle payable_to\">#{I18n.t("qrbills.account").capitalize} / #{I18n.t("qrbills.payable_to").capitalize}</div>\n"
100
+ layout += " <div class=\"qrcontent\">\n"
101
+ layout += " #{params[:bill_params][:creditor][:iban]}<br/>\n"
102
+ layout += render_address(params[:bill_params][:creditor][:address])
103
+ layout += " </div>\n"
104
+ layout += " <div><br/></div>\n"
105
+
106
+ if !params[:bill_params][:reference].nil? && !params[:bill_params][:reference].empty?
107
+ layout += " <div class=\"subtitle reference\">#{I18n.t("qrbills.reference").capitalize}</div>\n"
108
+ layout += " <div class=\"reference\">\n"
109
+ layout += " #{params[:bill_params][:reference]}<br/>\n"
110
+ layout += " </div>\n"
111
+ layout += " <div><br/></div>\n"
112
+ end
113
+
114
+ if !params[:bill_params][:additionally_information].nil? && !params[:bill_params][:additionally_information].empty?
115
+ layout += " <div class=\"subtitle additional_information\">#{I18n.t("qrbills.additional_information").capitalize}</div>\n"
116
+ layout += " <div class=\"additional_information\">\n"
117
+ layout += " #{params[:bill_params][:additionally_information]}<br/>\n"
118
+ layout += " </div>\n"
119
+ layout += " <div><br/></div>\n"
120
+ end
121
+
122
+ layout += " <div class=\"subtitle payable_by\">#{I18n.t("qrbills.payable_by").capitalize}</div>\n"
123
+ layout += " <div class=\"payable_by\">\n"
124
+ layout += render_address(params[:bill_params][:debtor][:address])
125
+ layout += " </div>\n"
126
+ layout += " </div>\n"
127
+ layout += " </div>\n"
128
+ layout += "</div>\n"
101
129
 
102
- if !params[:bill_params][:additionally_information].nil? && !params[:bill_params][:additionally_information].empty?
103
- layout += " <div class=\"subtitle additional_information\">#{I18n.t("qrbills.additional_information").capitalize}</div>\n"
104
- layout += " <div class=\"additional_information\">\n"
105
- layout += " #{params[:bill_params][:additionally_information]}<br/>\n"
106
- layout += " </div>\n"
107
- layout += " <div><br/></div>\n"
130
+ layout += "<style>\n"
131
+ layout += " @font-face{ \n"
132
+ layout += " font-family: \"liberation_sansregular\";\n"
133
+ layout += " src: url(\"#{params[:fonts][:eot]}\");\n"
134
+ layout += " src: url(\"#{params[:fonts][:eot]}?#iefix\") format(\"embedded-opentype\"),\n"
135
+ layout += " url(\"#{params[:fonts][:woff]}\") format(\"woff\"),\n"
136
+ layout += " url(\"#{params[:fonts][:ttf]}\") format(\"truetype\"),\n"
137
+ layout += " url(\"#{params[:fonts][:svg]}#liberation_sansregular\") format(\"svg\");\n"
138
+ layout += " font-weight: normal;\n"
139
+ layout += " font-style: normal;\n"
140
+ layout += " }\n"
141
+
142
+ layout += " .bill_container {\n"
143
+ layout += " width: 210mm;\n"
144
+ layout += " height: 105mm;\n"
145
+ layout += " font-family: \"liberation_sansregular\";\n"
146
+ layout += " border: 1px solid #ccc;\n"
147
+ layout += " }\n"
148
+
149
+ layout += " .bill_container:after {\n"
150
+ layout += " content: \"\";\n"
151
+ layout += " display: table;\n"
152
+ layout += " clear: both;\n"
153
+ layout += " }\n"
154
+
155
+ layout += " .receipt_section {\n"
156
+ layout += " width: 52mm;\n"
157
+ layout += " height: 95mm;\n"
158
+ layout += " padding: 5mm;\n"
159
+ layout += " float: left;\n"
160
+ layout += " font-size: 8pt;\n"
161
+ layout += " border-right: 1px dotted #ccc;\n"
162
+ layout += " }\n"
163
+
164
+ layout += " .payment_section {\n"
165
+ layout += " width: 137mm;\n"
166
+ layout += " height: 95mm;\n"
167
+ layout += " float: left;\n"
168
+ layout += " padding: 5mm;\n"
169
+ layout += " font-size: 10pt;\n"
170
+ layout += " }\n"
171
+
172
+ layout += " .payment_section .left_column {\n"
173
+ layout += " height: 95mm;\n"
174
+ layout += " width: 46mm;\n"
175
+ layout += " float: left;\n"
176
+ layout += " margin-right: 5mm;\n"
177
+ layout += " }\n"
178
+
179
+ layout += " .payment_section .right_column {\n"
180
+ layout += " height: 95mm;\n"
181
+ layout += " width: 86mm;\n"
182
+ layout += " float: left;\n"
183
+ layout += " }\n"
184
+
185
+ layout += " .qr_code {\n"
186
+ layout += " padding: 5mm 0mm 5mm 0mm;\n"
187
+ layout += " height: 46mm;\n"
188
+ layout += " width: 46mm;\n"
189
+ layout += " }\n"
190
+
191
+ layout += " .qr_code img {\n"
192
+ layout += " height: 46mm;\n"
193
+ layout += " width: 46mm;\n"
194
+ layout += " }\n"
195
+
196
+ layout += " .amount {\n"
197
+ layout += " margin-top: 15px;\n"
198
+ layout += " }\n"
199
+
200
+ layout += " .amount .currency {\n"
201
+ layout += " float: left;\n"
202
+ layout += " margin-right: 15px;\n"
203
+ layout += " }\n"
204
+
205
+ layout += " .title {\n"
206
+ layout += " font-weight: bold;\n"
207
+ layout += " font-size: 11pt;\n"
208
+ layout += " }\n"
209
+
210
+ layout += " .receipt_section .subtitle {\n"
211
+ layout += " font-weight: bold;\n"
212
+ layout += " font-size: 6pt;\n"
213
+ layout += " line-height: 9pt;\n"
214
+ layout += " }\n"
215
+
216
+ layout += " .receipt_section .acceptance_point {\n"
217
+ layout += " font-weight: bold;\n"
218
+ layout += " text-align: right;\n"
219
+ layout += " font-size: 6pt;\n"
220
+ layout += " line-height: 8pt;\n"
221
+ layout += " padding-top: 5mm;\n"
222
+ layout += " }\n"
223
+
224
+ layout += " .payment_section .subtitle {\n"
225
+ layout += " font-weight: bold;\n"
226
+ layout += " font-size: 8pt;\n"
227
+ layout += " line-height: 11pt;\n"
228
+ layout += " }\n"
229
+
230
+ layout += " .payment_section .amount {\n"
231
+ layout += " height: 22mm;\n"
232
+ layout += " margin-top: 40px;\n"
233
+ layout += " }\n"
234
+
235
+ layout += " .payment_section .further_information {\n"
236
+ layout += " font-size: 7pt;\n"
237
+ layout += " }\n"
238
+
239
+ layout += " .payment_section .finfo_header {\n"
240
+ layout += " font-weight: bold;\n"
241
+ layout += " } \n"
242
+ layout += "</style>\n"
243
+
244
+ layout
108
245
  end
246
+ end
109
247
 
110
- layout += " <div class=\"subtitle payable_by\">#{I18n.t("qrbills.payable_by").capitalize}</div>\n"
111
- layout += " <div class=\"payable_by\">\n"
112
- layout += " #{params[:bill_params][:debtor][:address][:name]}<br/>\n"
113
- layout += " #{params[:bill_params][:debtor][:address][:line1]} #{params[:bill_params][:debtor][:address][:line2]}<br/>\n"
114
- layout += " #{params[:bill_params][:debtor][:address][:postal_code]} #{params[:bill_params][:debtor][:address][:town]}<br/>\n"
115
- layout += " </div>\n"
116
- layout += " </div>\n"
117
- layout += " </div>\n"
118
- layout += "</div>\n"
119
-
120
- layout += "<style>\n"
121
- layout += " @font-face{ \n"
122
- layout += " font-family: \"liberation_sansregular\";\n"
123
- layout += " src: url(\"#{params[:fonts][:eot]}\");\n"
124
- layout += " src: url(\"#{params[:fonts][:eot]}?#iefix\") format(\"embedded-opentype\"),\n"
125
- layout += " url(\"#{params[:fonts][:woff]}\") format(\"woff\"),\n"
126
- layout += " url(\"#{params[:fonts][:ttf]}\") format(\"truetype\"),\n"
127
- layout += " url(\"#{params[:fonts][:svg]}#liberation_sansregular\") format(\"svg\");\n"
128
- layout += " font-weight: normal;\n"
129
- layout += " font-style: normal;\n"
130
- layout += " }\n"
131
-
132
- layout += " .bill_container {\n"
133
- layout += " width: 210mm;\n"
134
- layout += " height: 105mm;\n"
135
- layout += " font-family: \"liberation_sansregular\";\n"
136
- layout += " border: 1px solid #ccc;\n"
137
- layout += " }\n"
138
-
139
- layout += " .bill_container:after {\n"
140
- layout += " content: \"\";\n"
141
- layout += " display: table;\n"
142
- layout += " clear: both;\n"
143
- layout += " }\n"
144
-
145
- layout += " .receipt_section {\n"
146
- layout += " width: 52mm;\n"
147
- layout += " height: 95mm;\n"
148
- layout += " padding: 5mm;\n"
149
- layout += " float: left;\n"
150
- layout += " font-size: 8pt;\n"
151
- layout += " border-right: 1px dotted #ccc;\n"
152
- layout += " }\n"
153
-
154
- layout += " .payment_section {\n"
155
- layout += " width: 137mm;\n"
156
- layout += " height: 95mm;\n"
157
- layout += " float: left;\n"
158
- layout += " padding: 5mm;\n"
159
- layout += " font-size: 10pt;\n"
160
- layout += " }\n"
161
-
162
- layout += " .payment_section .left_column {\n"
163
- layout += " height: 95mm;\n"
164
- layout += " width: 46mm;\n"
165
- layout += " float: left;\n"
166
- layout += " margin-right: 5mm;\n"
167
- layout += " }\n"
168
-
169
- layout += " .payment_section .right_column {\n"
170
- layout += " height: 95mm;\n"
171
- layout += " width: 86mm;\n"
172
- layout += " float: left;\n"
173
- layout += " }\n"
174
-
175
- layout += " .qr_code {\n"
176
- layout += " padding: 5mm 0mm 5mm 0mm;\n"
177
- layout += " height: 46mm;\n"
178
- layout += " width: 46mm;\n"
179
- layout += " }\n"
180
-
181
- layout += " .qr_code img {\n"
182
- layout += " height: 46mm;\n"
183
- layout += " width: 46mm;\n"
184
- layout += " }\n"
185
-
186
- layout += " .amount {\n"
187
- layout += " margin-top: 15px;\n"
188
- layout += " }\n"
189
-
190
- layout += " .amount .currency {\n"
191
- layout += " float: left;\n"
192
- layout += " margin-right: 15px;\n"
193
- layout += " }\n"
194
-
195
- layout += " .title {\n"
196
- layout += " font-weight: bold;\n"
197
- layout += " font-size: 11pt;\n"
198
- layout += " }\n"
199
-
200
- layout += " .receipt_section .subtitle {\n"
201
- layout += " font-weight: bold;\n"
202
- layout += " font-size: 6pt;\n"
203
- layout += " line-height: 9pt;\n"
204
- layout += " }\n"
205
-
206
- layout += " .receipt_section .acceptance_point {\n"
207
- layout += " font-weight: bold;\n"
208
- layout += " text-align: right;\n"
209
- layout += " font-size: 6pt;\n"
210
- layout += " line-height: 8pt;\n"
211
- layout += " padding-top: 5mm;\n"
212
- layout += " }\n"
213
-
214
- layout += " .payment_section .subtitle {\n"
215
- layout += " font-weight: bold;\n"
216
- layout += " font-size: 8pt;\n"
217
- layout += " line-height: 11pt;\n"
218
- layout += " }\n"
219
-
220
- layout += " .payment_section .amount {\n"
221
- layout += " height: 22mm;\n"
222
- layout += " margin-top: 40px;\n"
223
- layout += " }\n"
224
-
225
- layout += " .payment_section .further_information {\n"
226
- layout += " font-size: 7pt;\n"
227
- layout += " }\n"
228
-
229
- layout += " .payment_section .finfo_header {\n"
230
- layout += " font-weight: bold;\n"
231
- layout += " } \n"
232
- layout += "</style>\n"
233
-
234
- return layout
248
+ def self.render_address(address)
249
+ case address[:type]
250
+ when 'S'
251
+ format("%s<br>\n%s %s<br>\n%s %s<br>\n", address[:name], address[:line1], address[:line2], address[:postal_code], address[:town])
252
+ when 'K'
253
+ format("%s<br>\n%s<br>\n%s<br>\n", address[:name], address[:line1], address[:line2])
254
+ end
235
255
  end
236
256
  end
@@ -6,7 +6,8 @@ module QRParams
6
6
  def self.get_qr_params
7
7
  {
8
8
  bill_type: "", # see global variables / README
9
- qrcode_filepath: "", # where to store the qrcode, i.e. : /tmp/qrcode_1234.png
9
+ qrcode_format: nil, # png or svg, overwrites qrcode_filepath
10
+ qrcode_filepath: "", # deprecated, where to store the qrcode, i.e. : /tmp/qrcode_1234.png
10
11
  fonts: {
11
12
  eot: File.expand_path("#{File.dirname(__FILE__)}/../../web/assets/fonts/LiberationSans-Regular.eot"),
12
13
  woff: File.expand_path("#{File.dirname(__FILE__)}/../../web/assets/fonts/LiberationSans-Regular.woff"),
@@ -17,7 +18,7 @@ module QRParams
17
18
  path: File.expand_path("#{File.dirname(__FILE__)}/../../config/locales")
18
19
  },
19
20
  bill_params: {
20
- language: "it",
21
+ language: I18n.locale,
21
22
  amount: 0.0,
22
23
  currency: "CHF",
23
24
  reference_type: "", # QRR = QR reference, SCOR = Creditor reference, NON = without reference
@@ -67,7 +68,7 @@ module QRParams
67
68
  when QRParams::QR_BILL_WITHOUT_REFERENCE
68
69
  QRParams.qr_bill_without_reference_valid?(params)
69
70
  else
70
- false
71
+ raise ArgumentError, "#{QRExceptions::INVALID_PARAMETERS}: bill type is not supported"
71
72
  end
72
73
  end
73
74
 
@@ -76,11 +77,7 @@ module QRParams
76
77
  raise ArgumentError, "#{QRExceptions::INVALID_PARAMETERS}: bill type cannot be blank"
77
78
  end
78
79
 
79
- if params[:qrcode_filepath] == "" || params[:qrcode_filepath] == nil
80
- raise ArgumentError, "#{QRExceptions::INVALID_PARAMETERS}: qrcode_filepath cannot be blank"
81
- end
82
-
83
- if params[:bill_params][:currency] == "" || params[:bill_params][:currency] == nil
80
+ if params.dig(:bill_params, :currency) == "" || params.dig(:bill_params, :currency) == nil
84
81
  raise ArgumentError, "#{QRExceptions::INVALID_PARAMETERS}: currency cannot be blank"
85
82
  end
86
83
 
@@ -122,4 +119,4 @@ module QRParams
122
119
 
123
120
  true
124
121
  end
125
- end
122
+ end
data/lib/qr-bills.rb CHANGED
@@ -17,13 +17,11 @@ module QRBills
17
17
  end
18
18
 
19
19
  output = case qr_params[:output_params][:format]
20
- when 'html'
21
- QRHTMLLayout.create(qr_params)
22
- when 'qrcode_png'
23
- QRGenerator.create(qr_params, qr_params[:qrcode_filepath])
24
- else
25
- raise ArgumentError, "#{QRExceptions::NOT_SUPPORTED}: #{qr_params[:output_params][:format]} is not yet supported"
26
- end
20
+ when 'html'
21
+ QRHTMLLayout.create(qr_params)
22
+ else
23
+ QRGenerator.create(qr_params, qr_params[:qrcode_filepath])
24
+ end
27
25
 
28
26
  { params: qr_params, output: output }
29
27
  end
@@ -0,0 +1 @@
1
+ <svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='SWISS_CROSS_CENTER' y='SWISS_CROSS_CENTER' width='SWISS_CROSS_SIZE' height='SWISS_CROSS_SIZE' viewBox='0 0 19.8 19.8' style='enable-background:new 0 0 19.8 19.8;' xml:space='preserve'><style type='text/css'>.st0{fill:#FFFFFF;}.st1{fill:none;stroke:#FFFFFF;stroke-width:1.4357;stroke-miterlimit:10;}</style><polygon points='18.3,0.7 1.6,0.7 0.7,0.7 0.7,1.6 0.7,18.3 0.7,19.1 1.6,19.1 18.3,19.1 19.1,19.1 19.1,18.3 19.1,1.6 19.1,0.7'/><rect x='8.3' y='4' class='st0' width='3.3' height='11'/><rect x='4.4' y='7.9' class='st0' width='11' height='3.3'/><polygon class='st1' points='0.7,1.6 0.7,18.3 0.7,19.1 1.6,19.1 18.3,19.1 19.1,19.1 19.1,18.3 19.1,1.6 19.1,0.7 18.3,0.7 1.6,0.7 0.7,0.7'/></svg>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qr-bills
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.6
4
+ version: 1.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Damiano Radice
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-02-04 00:00:00.000000000 Z
11
+ date: 2022-05-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: i18n
@@ -36,20 +36,20 @@ dependencies:
36
36
  requirements:
37
37
  - - ">="
38
38
  - !ruby/object:Gem::Version
39
- version: 1.1.2
39
+ version: '2.1'
40
40
  - - "<"
41
41
  - !ruby/object:Gem::Version
42
- version: '2'
42
+ version: '3'
43
43
  type: :runtime
44
44
  prerelease: false
45
45
  version_requirements: !ruby/object:Gem::Requirement
46
46
  requirements:
47
47
  - - ">="
48
48
  - !ruby/object:Gem::Version
49
- version: 1.1.2
49
+ version: '2.1'
50
50
  - - "<"
51
51
  - !ruby/object:Gem::Version
52
- version: '2'
52
+ version: '3'
53
53
  - !ruby/object:Gem::Dependency
54
54
  name: rspec
55
55
  requirement: !ruby/object:Gem::Requirement
@@ -78,6 +78,34 @@ dependencies:
78
78
  - - "~>"
79
79
  - !ruby/object:Gem::Version
80
80
  version: '13.0'
81
+ - !ruby/object:Gem::Dependency
82
+ name: pry
83
+ requirement: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ - !ruby/object:Gem::Dependency
96
+ name: byebug
97
+ requirement: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
81
109
  description: 'QR-bills support for swiss payments, for full documentation please refer
82
110
  to github repo: https://github.com/damoiser/qr-bills'
83
111
  email: dam.radice@gmail.com
@@ -103,6 +131,7 @@ files:
103
131
  - web/assets/images/payable_by_65x25mm.png
104
132
  - web/assets/images/scissors_symbol.png
105
133
  - web/assets/images/swiss_cross.png
134
+ - web/assets/images/swiss_cross.svg
106
135
  homepage: https://github.com/damoiser/qr-bills
107
136
  licenses:
108
137
  - MIT