einvoice-qr-encryptor 0.1.0 → 0.2.0
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 +41 -3
- data/lib/einvoice-qr-encryptor/client.rb +95 -6
- data/lib/einvoice-qr-encryptor/core_ext/string.rb +12 -0
- data/lib/einvoice-qr-encryptor/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cb56739fbd067cdb9ff79936fc41bb8f901e2db0
|
4
|
+
data.tar.gz: 34147b30d3376681b2273593d03bb9b792a23dc3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2c4ba6cf5d26caa75611792d3309e139d87466461018c0097175613ae6430c58f52c13909f186a2011c90c09d8c1b91c01ecc878768c2e80427746ad8b24b1e5
|
7
|
+
data.tar.gz: ba7b9c9bbafbe0d2b5391e610dcbe4c32457ec9dadf3970292baaba501e8347eec8b0b9f4168b0d41e3c4b20e91d7b8c3abc1ea131f35c644c70bd867175dbc7
|
data/README.md
CHANGED
@@ -3,9 +3,9 @@
|
|
3
3
|

|
4
4
|
# EInvoice-QR-Encryptor
|
5
5
|
|
6
|
-
Encrypt, decrypt and generate QR code information for
|
6
|
+
Encrypt, decrypt and generate QR code information for EInvoice(Taiwan)
|
7
7
|
|
8
|
-
_Compatible with 2D barcode specification version 1.
|
8
|
+
_Compatible with 1D and 2D barcode specification version 1.6(20161115)_
|
9
9
|
|
10
10
|
## Installation
|
11
11
|
|
@@ -47,7 +47,7 @@ cipher.decrypt('73UqXrAk5DsVNv2VEvIFkQ==')
|
|
47
47
|
#=> 'AA123456781234'
|
48
48
|
```
|
49
49
|
|
50
|
-
#### Generate QR Code information for
|
50
|
+
#### Generate QR Code information for EInvoice
|
51
51
|
|
52
52
|
```ruby
|
53
53
|
cipher.gen_qrcode_information(
|
@@ -67,6 +67,44 @@ cipher.gen_qrcode_information(
|
|
67
67
|
#=> 'AA12345678104051112340000006400000064000000000000000073UqXrAk5DsVNv2VEvIFkQ=='
|
68
68
|
```
|
69
69
|
|
70
|
+
#### Generate Barcode and QR Code information for EInvoice
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
cipher.gen_barcode_qrcode_information(
|
74
|
+
invoice_number: 'AA12345678',
|
75
|
+
invoice_date: '1040511',
|
76
|
+
invoice_time: '090000',
|
77
|
+
random_number: '1234',
|
78
|
+
sales_amount: 100,
|
79
|
+
tax_amount: 0,
|
80
|
+
total_amount: 100,
|
81
|
+
buyer_identifier: '00000000',
|
82
|
+
represent_identifier: '00000000',
|
83
|
+
seller_identifier: '00000000',
|
84
|
+
business_identifier: '00000000',
|
85
|
+
product_array: [{
|
86
|
+
product_code: '4713546575601',
|
87
|
+
product_name: 'Product 1',
|
88
|
+
product_qty: '1',
|
89
|
+
product_sale_amount: '60',
|
90
|
+
product_tax_amount: '0',
|
91
|
+
product_amount: '60'
|
92
|
+
}, {
|
93
|
+
product_code: '4713546575602',
|
94
|
+
product_name: 'Product 2',
|
95
|
+
product_qty: '2',
|
96
|
+
product_sale_amount: '20',
|
97
|
+
product_tax_amount: '0',
|
98
|
+
product_amount: '20'
|
99
|
+
}]
|
100
|
+
)
|
101
|
+
#=> {
|
102
|
+
# :barcode=>"10405AA123456781234",
|
103
|
+
# :qrcode_left=>"AA12345678104051112340000006400000064000000000000000073UqXrAk5DsVNv2VEvIFkQ==:**********:0:2:1",
|
104
|
+
# :qrcode_right=>"**"
|
105
|
+
# }
|
106
|
+
```
|
107
|
+
|
70
108
|
## Development
|
71
109
|
|
72
110
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -2,6 +2,7 @@ require 'openssl'
|
|
2
2
|
require 'base64'
|
3
3
|
require 'einvoice-qr-encryptor/error_message'
|
4
4
|
require 'einvoice-qr-encryptor/core_ext/integer'
|
5
|
+
require 'einvoice-qr-encryptor/core_ext/string'
|
5
6
|
|
6
7
|
module EInvoiceQREncryptor
|
7
8
|
class Cipher # :nodoc:
|
@@ -35,7 +36,7 @@ module EInvoiceQREncryptor
|
|
35
36
|
@cipher.update(Base64.decode64(cipher_text)) + @cipher.final
|
36
37
|
end
|
37
38
|
|
38
|
-
# Generate QR code information for
|
39
|
+
# Generate QR code information for EInvoice
|
39
40
|
#
|
40
41
|
# @param invoice_number [String]
|
41
42
|
# @param invoice_date [String]
|
@@ -49,7 +50,7 @@ module EInvoiceQREncryptor
|
|
49
50
|
# @param seller_identifier [String]
|
50
51
|
# @param business_identifier [String]
|
51
52
|
# @param product_arrays [Array]
|
52
|
-
# @return [String] QR code information for
|
53
|
+
# @return [String] QR code information for EInvoice
|
53
54
|
# @example
|
54
55
|
# gen_qrcode_information(
|
55
56
|
# invoice_number: 'AA12345678',
|
@@ -75,7 +76,7 @@ module EInvoiceQREncryptor
|
|
75
76
|
raise ErrorMessage.generate(msg: :field_should_be, field: :invoice_date, data: String) unless invoice_date.is_a? String
|
76
77
|
raise ErrorMessage.generate(msg: :fixed_length, field: :invoice_date, length: 7) if invoice_date.length != 7
|
77
78
|
|
78
|
-
/\d{3}(?<month>\d{2})(?<day>\d{2})/ =~ invoice_date
|
79
|
+
/\A\d{3}(?<month>\d{2})(?<day>\d{2})\Z/ =~ invoice_date
|
79
80
|
raise ErrorMessage.generate(msg: :field_should_be, field: 'month of invoice_date', data: 'between 01 ~ 12') unless ('01'..'12').cover? month
|
80
81
|
raise ErrorMessage.generate(msg: :field_should_be, field: 'day of invoice_date', data: 'between 01 ~ 31') unless ('01'..'31').cover? day
|
81
82
|
|
@@ -93,11 +94,11 @@ module EInvoiceQREncryptor
|
|
93
94
|
|
94
95
|
# 稅額
|
95
96
|
raise ErrorMessage.generate(msg: :field_should_be, field: :tax_amount, data: Integer) unless tax_amount.is_a? Integer
|
96
|
-
raise ErrorMessage.generate(msg: :field_should_be, field: :tax_amount, data: 'greater than or equal to 0') if tax_amount
|
97
|
+
raise ErrorMessage.generate(msg: :field_should_be, field: :tax_amount, data: 'greater than or equal to 0') if tax_amount < 0
|
97
98
|
|
98
99
|
# 總計金額(含稅)
|
99
100
|
raise ErrorMessage.generate(msg: :field_should_be, field: :total_amount, data: Integer) unless total_amount.is_a? Integer
|
100
|
-
raise ErrorMessage.generate(msg: :field_should_be, field: :total_amount, data: 'greater than or equal to 0') if total_amount
|
101
|
+
raise ErrorMessage.generate(msg: :field_should_be, field: :total_amount, data: 'greater than or equal to 0') if total_amount < 0
|
101
102
|
|
102
103
|
# 買受人統一編號
|
103
104
|
raise ErrorMessage.generate(msg: :field_should_be, field: :buyer_identifier, data: String) unless buyer_identifier.is_a? String
|
@@ -130,29 +131,117 @@ module EInvoiceQREncryptor
|
|
130
131
|
# 商品數量
|
131
132
|
raise ErrorMessage.generate(msg: :field_should_be, field: 'product_array.product_qty', data: String) unless product[:product_qty].is_a? String
|
132
133
|
raise ErrorMessage.generate(msg: :cannot_be_empty, field: 'product_array.product_qty') if product[:product_qty].empty?
|
134
|
+
raise ErrorMessage.generate(msg: :field_should_be, field: 'product_array.product_qty', data: 'number string') unless product[:product_qty].numeric?
|
133
135
|
|
134
136
|
# 商品銷售額(整數未稅),若無法分離稅項則記載為字串 0
|
135
137
|
raise ErrorMessage.generate(msg: :field_should_be, field: 'product_array.product_sale_amount', data: String) unless product[:product_sale_amount].is_a? String
|
136
138
|
raise ErrorMessage.generate(msg: :cannot_be_empty, field: 'product_array.product_sale_amount') if product[:product_sale_amount].empty?
|
139
|
+
raise ErrorMessage.generate(msg: :field_should_be, field: 'product_array.product_sale_amount', data: 'number string') unless product[:product_sale_amount].numeric?
|
137
140
|
|
138
141
|
# 商品稅額(整數),若無法分離稅項則記載為字串 0
|
139
142
|
raise ErrorMessage.generate(msg: :field_should_be, field: 'product_array.product_tax_amount', data: String) unless product[:product_tax_amount].is_a? String
|
140
143
|
raise ErrorMessage.generate(msg: :cannot_be_empty, field: 'product_array.product_tax_amount') if product[:product_tax_amount].empty?
|
144
|
+
raise ErrorMessage.generate(msg: :field_should_be, field: 'product_array.product_tax_amount', data: 'number string') unless product[:product_tax_amount].numeric?
|
141
145
|
|
142
146
|
# 商品金額(整數含稅)
|
143
147
|
raise ErrorMessage.generate(msg: :field_should_be, field: 'product_array.product_amount', data: String) unless product[:product_amount].is_a? String
|
144
148
|
raise ErrorMessage.generate(msg: :cannot_be_empty, field: 'product_array.product_amount') if product[:product_amount].empty?
|
149
|
+
raise ErrorMessage.generate(msg: :field_should_be, field: 'product_array.product_amount', data: 'number string') unless product[:product_amount].numeric?
|
145
150
|
end
|
146
151
|
|
147
152
|
# generate cipher text
|
148
153
|
cipher_text = encrypt("#{invoice_number}#{random_number}")
|
149
154
|
|
150
|
-
# return QR Code
|
155
|
+
# return QR Code information for EInvoice
|
151
156
|
"#{invoice_number}#{invoice_date}#{random_number}" \
|
152
157
|
"#{sales_amount.to_8bit_hex_string}#{total_amount.to_8bit_hex_string}" \
|
153
158
|
"#{buyer_identifier}#{seller_identifier}#{cipher_text}"
|
154
159
|
end
|
155
160
|
|
161
|
+
# Generate Barcode and QR code information for EInvoice
|
162
|
+
#
|
163
|
+
# @param invoice_number [String]
|
164
|
+
# @param invoice_date [String]
|
165
|
+
# @param invoice_time [String]
|
166
|
+
# @param random_number [String]
|
167
|
+
# @param sales_amount [Integer]
|
168
|
+
# @param tax_amount [Integer]
|
169
|
+
# @param total_amount [Integer]
|
170
|
+
# @param buyer_identifier [String]
|
171
|
+
# @param represent_identifier [String]
|
172
|
+
# @param seller_identifier [String]
|
173
|
+
# @param business_identifier [String]
|
174
|
+
# @param product_arrays [Array]
|
175
|
+
# @return [Hash] Barcode and QR code information for EInvoice
|
176
|
+
# @example
|
177
|
+
# gen_barcode_qrcode_information(
|
178
|
+
# invoice_number: 'AA12345678',
|
179
|
+
# invoice_date: '1040511',
|
180
|
+
# invoice_time: '090000',
|
181
|
+
# random_number: '1234',
|
182
|
+
# sales_amount: 100,
|
183
|
+
# tax_amount: 0,
|
184
|
+
# total_amount: 100,
|
185
|
+
# buyer_identifier: '00000000',
|
186
|
+
# represent_identifier: '00000000',
|
187
|
+
# seller_identifier: '00000000',
|
188
|
+
# business_identifier: '00000000',
|
189
|
+
# product_array: [{
|
190
|
+
# product_code: '4713546575601',
|
191
|
+
# product_name: 'Product 1',
|
192
|
+
# product_qty: '1',
|
193
|
+
# product_sale_amount: '60',
|
194
|
+
# product_tax_amount: '0',
|
195
|
+
# product_amount: '60'
|
196
|
+
# }, {
|
197
|
+
# product_code: '4713546575602',
|
198
|
+
# product_name: 'Product 2',
|
199
|
+
# product_qty: '2',
|
200
|
+
# product_sale_amount: '20',
|
201
|
+
# product_tax_amount: '0',
|
202
|
+
# product_amount: '20'
|
203
|
+
# }]
|
204
|
+
# )
|
205
|
+
#=> {
|
206
|
+
# :barcode=>"10405AA123456781234",
|
207
|
+
# :qrcode_left=>"AA12345678104051112340000006400000064000000000000000073UqXrAk5DsVNv2VEvIFkQ==:**********:0:2:1",
|
208
|
+
# :qrcode_right=>"**"
|
209
|
+
# }
|
210
|
+
def gen_barcode_qrcode_information(invoice_number:, invoice_date:, invoice_time:, random_number:, sales_amount:, tax_amount:, total_amount:, buyer_identifier:, represent_identifier:, seller_identifier:, business_identifier:, product_array:)
|
211
|
+
first_77_bits_qrcode_info = gen_qrcode_information(
|
212
|
+
invoice_number: invoice_number,
|
213
|
+
invoice_date: invoice_date,
|
214
|
+
invoice_time: invoice_time,
|
215
|
+
random_number: random_number,
|
216
|
+
sales_amount: sales_amount,
|
217
|
+
tax_amount: tax_amount,
|
218
|
+
total_amount: total_amount,
|
219
|
+
buyer_identifier: buyer_identifier,
|
220
|
+
represent_identifier: represent_identifier,
|
221
|
+
seller_identifier: seller_identifier,
|
222
|
+
business_identifier: business_identifier,
|
223
|
+
product_array: product_array
|
224
|
+
)
|
225
|
+
|
226
|
+
# 營業人自行使用區
|
227
|
+
bussiness_custom_block = '*' * 10
|
228
|
+
|
229
|
+
# 二維條碼記載完整品目筆數
|
230
|
+
product_count_in_qrcode = 0
|
231
|
+
|
232
|
+
# 該張發票交易品目總筆數
|
233
|
+
product_count_in_einvoice = product_array.length
|
234
|
+
|
235
|
+
# 中文編碼參數
|
236
|
+
chinese_encoding = 1
|
237
|
+
|
238
|
+
{
|
239
|
+
barcode: "#{invoice_date[0..4]}#{invoice_number}#{random_number}",
|
240
|
+
qrcode_left: "#{first_77_bits_qrcode_info}:#{bussiness_custom_block}:#{product_count_in_qrcode}:#{product_count_in_einvoice}:#{chinese_encoding}",
|
241
|
+
qrcode_right: '**'
|
242
|
+
}
|
243
|
+
end
|
244
|
+
|
156
245
|
private
|
157
246
|
|
158
247
|
def init_cipher(type)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: einvoice-qr-encryptor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Calvert
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-03-
|
11
|
+
date: 2017-03-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -102,6 +102,7 @@ files:
|
|
102
102
|
- lib/einvoice-qr-encryptor.rb
|
103
103
|
- lib/einvoice-qr-encryptor/client.rb
|
104
104
|
- lib/einvoice-qr-encryptor/core_ext/integer.rb
|
105
|
+
- lib/einvoice-qr-encryptor/core_ext/string.rb
|
105
106
|
- lib/einvoice-qr-encryptor/error_message.rb
|
106
107
|
- lib/einvoice-qr-encryptor/version.rb
|
107
108
|
homepage: https://github.com/calvertyang/EInvoice-QR-Encryptor
|