einvoice 1.3 → 1.5.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/.coderabbit.yaml +14 -0
- data/.github/workflows/build.yml +10 -7
- data/.github/workflows/cron.yml +23 -10
- data/CHANGELOG.md +74 -0
- data/Gemfile +11 -4
- data/README.md +98 -10
- data/Rakefile +44 -6
- data/einvoice.gemspec +11 -6
- data/lib/einvoice/client.rb +9 -1
- data/lib/einvoice/configuration.rb +5 -2
- data/lib/einvoice/connection.rb +3 -2
- data/lib/einvoice/donation_unit_list.json +1313 -1078
- data/lib/einvoice/provider.rb +1 -2
- data/lib/einvoice/tradevan/model/issue_data.rb +2 -2
- data/lib/einvoice/tradevan/model/issue_item.rb +2 -2
- data/lib/einvoice/tradevan/model/void_data.rb +2 -2
- data/lib/einvoice/tradevan/provider.rb +9 -46
- data/lib/einvoice/tradevan/validator/issue_data_validator.rb +7 -7
- data/lib/einvoice/version.rb +1 -1
- data/lib/einvoice.rb +0 -1
- data/lib/faraday/response/decode_tradevan.rb +5 -6
- data/lib/faraday/response/parse_xml.rb +14 -0
- metadata +19 -45
- data/lib/einvoice/utils.rb +0 -13
data/lib/einvoice/provider.rb
CHANGED
|
@@ -52,7 +52,7 @@ module Einvoice
|
|
|
52
52
|
:itemList
|
|
53
53
|
].freeze
|
|
54
54
|
|
|
55
|
-
attr_accessor
|
|
55
|
+
attr_accessor(*VALID_OPTIONS_KEYS)
|
|
56
56
|
|
|
57
57
|
validates :companyUn, presence: true, length: { is: 8 }
|
|
58
58
|
validates :orgId, presence: true, length: { is: 5 }
|
|
@@ -121,7 +121,7 @@ module Einvoice
|
|
|
121
121
|
validates :invoiceType, allow_blank: true, length: { is: 2 }, inclusion: { in: %w(07 08) }, if: proc { self.type == 'G' }
|
|
122
122
|
|
|
123
123
|
def payload
|
|
124
|
-
serializable_hash(except: [:errors, :validation_context], include: [:itemList])
|
|
124
|
+
serializable_hash(except: [:errors, :validation_context, :context_for_validation], include: [:itemList])
|
|
125
125
|
end
|
|
126
126
|
end
|
|
127
127
|
end
|
|
@@ -19,13 +19,13 @@ module Einvoice
|
|
|
19
19
|
:description
|
|
20
20
|
]
|
|
21
21
|
|
|
22
|
-
attr_accessor
|
|
22
|
+
attr_accessor(*VALID_OPTIONS_KEYS)
|
|
23
23
|
|
|
24
24
|
validates :saleIdentifier, presence: true, length: { maximum: 100 }
|
|
25
25
|
validates :serialNumber, presence: true, length: { is: 4 }, numericality: true
|
|
26
26
|
validates :invoiceNumber, allow_blank: true, length: { is: 10 }
|
|
27
27
|
validates :invoiceDate, allow_blank: true, length: { is: 8 }, numericality: true
|
|
28
|
-
validates :invoiceTime, allow_blank: true, length: { is: 8 }, format: { with: /\
|
|
28
|
+
validates :invoiceTime, allow_blank: true, length: { is: 8 }, format: { with: /\A\d{2}\:\d{2}\:\d{2}\Z/ }
|
|
29
29
|
validates :productCode, allow_blank: true, length: { maximum: 30 }
|
|
30
30
|
validates :productName, presence: true, length: { maximum: 300 }
|
|
31
31
|
validates :qty, presence: true, length: { maximum: 20 }
|
|
@@ -12,7 +12,7 @@ module Einvoice
|
|
|
12
12
|
:companyUn
|
|
13
13
|
].freeze
|
|
14
14
|
|
|
15
|
-
attr_accessor
|
|
15
|
+
attr_accessor(*VALID_OPTIONS_KEYS)
|
|
16
16
|
|
|
17
17
|
validates :type, presence: true, length: { is: 1 }, inclusion: { in: %w(C I A) }
|
|
18
18
|
|
|
@@ -27,7 +27,7 @@ module Einvoice
|
|
|
27
27
|
validates :allowancePaperReturned, presence: true, length: { is: 1 }, inclusion: { in: %w(Y N) }, if: proc { self.type == 'A' }
|
|
28
28
|
|
|
29
29
|
def payload
|
|
30
|
-
serializable_hash(except: [:errors, :validation_context, :itemList])
|
|
30
|
+
serializable_hash(except: [:errors, :validation_context, :context_for_validation, :itemList])
|
|
31
31
|
end
|
|
32
32
|
end
|
|
33
33
|
end
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
require 'base64'
|
|
2
2
|
require 'openssl'
|
|
3
3
|
|
|
4
|
-
require "einvoice/utils"
|
|
5
4
|
|
|
6
5
|
require "einvoice/tradevan/model/base"
|
|
7
6
|
require "einvoice/tradevan/model/issue_data"
|
|
@@ -18,11 +17,7 @@ module Einvoice
|
|
|
18
17
|
issue_data.from_json(payload.to_json)
|
|
19
18
|
|
|
20
19
|
if issue_data.valid?
|
|
21
|
-
response = connection
|
|
22
|
-
ssl: {
|
|
23
|
-
verify: false
|
|
24
|
-
}
|
|
25
|
-
).post do |request|
|
|
20
|
+
response = connection.post do |request|
|
|
26
21
|
request.url endpoint_url || endpoint + "/DEFAULTAPI/post/issue"
|
|
27
22
|
request.params[:v] = encrypted_params(issueData: issue_data.payload)
|
|
28
23
|
end.body
|
|
@@ -38,11 +33,7 @@ module Einvoice
|
|
|
38
33
|
void_data.from_json(payload.to_json)
|
|
39
34
|
|
|
40
35
|
if void_data.valid?
|
|
41
|
-
response = connection
|
|
42
|
-
ssl: {
|
|
43
|
-
verify: false
|
|
44
|
-
}
|
|
45
|
-
).post do |request|
|
|
36
|
+
response = connection.post do |request|
|
|
46
37
|
request.url endpoint_url || endpoint + "/DEFAULTAPI/post/cancel"
|
|
47
38
|
request.params[:v] = encrypted_params(voidData: void_data.payload)
|
|
48
39
|
end.body
|
|
@@ -54,11 +45,7 @@ module Einvoice
|
|
|
54
45
|
end
|
|
55
46
|
|
|
56
47
|
def search_invoice_by_member_id(payload, options = {})
|
|
57
|
-
response = connection
|
|
58
|
-
ssl: {
|
|
59
|
-
verify: false
|
|
60
|
-
}
|
|
61
|
-
).get do |request|
|
|
48
|
+
response = connection.get do |request|
|
|
62
49
|
request.url endpoint_url || endpoint + "/DEFAULTAPI/get/searchInvoiceByMemberId"
|
|
63
50
|
request.params[:v] = encrypted_params(payload)
|
|
64
51
|
end.body
|
|
@@ -67,11 +54,7 @@ module Einvoice
|
|
|
67
54
|
end
|
|
68
55
|
|
|
69
56
|
def search_invoice_detail(invoice_number)
|
|
70
|
-
response = connection
|
|
71
|
-
ssl: {
|
|
72
|
-
verify: false
|
|
73
|
-
}
|
|
74
|
-
).get do |request|
|
|
57
|
+
response = connection.get do |request|
|
|
75
58
|
request.url endpoint_url || endpoint + "/DEFAULTAPI/get/searchInvoiceDetail"
|
|
76
59
|
request.params[:v] = encrypted_params(invoiceNumber: invoice_number)
|
|
77
60
|
end.body
|
|
@@ -80,11 +63,7 @@ module Einvoice
|
|
|
80
63
|
end
|
|
81
64
|
|
|
82
65
|
def search_invoice_by_transaction_number(payload, options = {})
|
|
83
|
-
response = connection
|
|
84
|
-
ssl: {
|
|
85
|
-
verify: false
|
|
86
|
-
}
|
|
87
|
-
).get do |request|
|
|
66
|
+
response = connection.get do |request|
|
|
88
67
|
request.url endpoint_url || endpoint + "/DEFAULTAPI/get/searchInvoiceInfoByTransactionnumber"
|
|
89
68
|
request.params[:v] = encrypted_params(payload.slice(:companyUn, :orgId, :transactionNumber))
|
|
90
69
|
end.body
|
|
@@ -93,11 +72,7 @@ module Einvoice
|
|
|
93
72
|
end
|
|
94
73
|
|
|
95
74
|
def send_card_info_to_cust(payload, options = {})
|
|
96
|
-
response = connection
|
|
97
|
-
ssl: {
|
|
98
|
-
verify: false
|
|
99
|
-
}
|
|
100
|
-
).get do |request|
|
|
75
|
+
response = connection.get do |request|
|
|
101
76
|
request.url endpoint_url || endpoint + "/DEFAULTAPI/get/sendCardInfotoCust"
|
|
102
77
|
request.params[:v] = encrypted_params(payload)
|
|
103
78
|
end.body
|
|
@@ -106,11 +81,7 @@ module Einvoice
|
|
|
106
81
|
end
|
|
107
82
|
|
|
108
83
|
def get_invoice_mark_info(payload, options = {})
|
|
109
|
-
response = connection
|
|
110
|
-
ssl: {
|
|
111
|
-
verify: false
|
|
112
|
-
}
|
|
113
|
-
).get do |request|
|
|
84
|
+
response = connection.get do |request|
|
|
114
85
|
request.url endpoint_url || endpoint + "/DEFAULTAPI/get/getInvoiceMarkInfo"
|
|
115
86
|
request.params[:v] = encrypted_params(payload)
|
|
116
87
|
end.body
|
|
@@ -119,11 +90,7 @@ module Einvoice
|
|
|
119
90
|
end
|
|
120
91
|
|
|
121
92
|
def get_donate_unit_list(companyUn, options = {})
|
|
122
|
-
response = connection
|
|
123
|
-
ssl: {
|
|
124
|
-
verify: false
|
|
125
|
-
}
|
|
126
|
-
).get do |request|
|
|
93
|
+
response = connection.get do |request|
|
|
127
94
|
request.url endpoint_url || endpoint + "/DEFAULTAPI/get/getDonateUnitList"
|
|
128
95
|
request.params[:v] = encrypted_params(companyUn: companyUn)
|
|
129
96
|
end.body
|
|
@@ -132,11 +99,7 @@ module Einvoice
|
|
|
132
99
|
end
|
|
133
100
|
|
|
134
101
|
def get_invoice_content(payload, options = {})
|
|
135
|
-
response = connection
|
|
136
|
-
ssl: {
|
|
137
|
-
verify: false
|
|
138
|
-
}
|
|
139
|
-
).get do |request|
|
|
102
|
+
response = connection.get do |request|
|
|
140
103
|
request.url endpoint_url || endpoint + "/DEFAULTAPI/get/getInvoiceContent"
|
|
141
104
|
request.params[:v] = encrypted_params(payload)
|
|
142
105
|
end.body
|
|
@@ -19,7 +19,7 @@ module Einvoice
|
|
|
19
19
|
|
|
20
20
|
class TotalValidator < ActiveModel::EachValidator
|
|
21
21
|
def validate_each(record, attribute, value)
|
|
22
|
-
|
|
22
|
+
if value.to_i != record.itemList.map(&:itemTotal).map(&:to_i).sum
|
|
23
23
|
record.errors.add attribute, options[:message] || :invalid
|
|
24
24
|
end
|
|
25
25
|
end
|
|
@@ -27,7 +27,7 @@ module Einvoice
|
|
|
27
27
|
|
|
28
28
|
class AllowanceNumberValidator < ActiveModel::EachValidator
|
|
29
29
|
def validate_each(record, attribute, value)
|
|
30
|
-
unless record.allowanceNumber =~ Regexp.new("
|
|
30
|
+
unless record.allowanceNumber =~ Regexp.new("\\A#{record.orgId}")
|
|
31
31
|
record.errors.add attribute, options[:message] || :invalid
|
|
32
32
|
end
|
|
33
33
|
end
|
|
@@ -55,20 +55,20 @@ module Einvoice
|
|
|
55
55
|
class ItemListValidator < ActiveModel::EachValidator
|
|
56
56
|
def validate_each(record, attribtue, value)
|
|
57
57
|
if record.itemList.map(&:itemTotal).map(&:blank?).reduce(&:|)
|
|
58
|
-
record.errors
|
|
58
|
+
record.errors.add :itemList, options[:message] || :invalid
|
|
59
59
|
elsif record.itemList.map(&:taxType).map(&:blank?).reduce(&:|)
|
|
60
|
-
record.errors
|
|
60
|
+
record.errors.add :itemList, options[:message] || :invalid
|
|
61
61
|
else
|
|
62
62
|
# none
|
|
63
63
|
end
|
|
64
64
|
|
|
65
65
|
if %w(A H).include?(record.type)
|
|
66
66
|
if record.itemList.map(&:invoiceNumber).map(&:blank?).reduce(&:|)
|
|
67
|
-
record.errors
|
|
67
|
+
record.errors.add :itemList, options[:message] || :invalid
|
|
68
68
|
elsif record.itemList.map(&:invoiceDate).map(&:blank?).reduce(&:|)
|
|
69
|
-
record.errors
|
|
69
|
+
record.errors.add :itemList, options[:message] || :invalid
|
|
70
70
|
elsif record.itemList.map(&:itemExclude).map(&:blank?).reduce(&:|)
|
|
71
|
-
record.errors
|
|
71
|
+
record.errors.add :itemList, options[:message] || :invalid
|
|
72
72
|
else
|
|
73
73
|
# none
|
|
74
74
|
end
|
data/lib/einvoice/version.rb
CHANGED
data/lib/einvoice.rb
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
+
require 'base64'
|
|
2
|
+
require 'json'
|
|
3
|
+
require 'openssl'
|
|
4
|
+
|
|
1
5
|
require 'faraday'
|
|
2
6
|
|
|
3
7
|
module Faraday
|
|
4
8
|
class Response::DecodeTradevan < Faraday::Middleware
|
|
5
|
-
dependency do
|
|
6
|
-
require 'base64' unless defined?(::Base64)
|
|
7
|
-
require 'openssl' unless defined?(::OpenSSL)
|
|
8
|
-
end
|
|
9
|
-
|
|
10
9
|
def initialize(app, key)
|
|
11
10
|
super(app)
|
|
12
11
|
@key = key
|
|
@@ -30,7 +29,7 @@ module Faraday
|
|
|
30
29
|
cipher.padding = 0
|
|
31
30
|
|
|
32
31
|
decrypted = cipher.update(Base64.decode64(content)) + cipher.final
|
|
33
|
-
JSON.
|
|
32
|
+
JSON.parse(decrypted.strip)
|
|
34
33
|
end
|
|
35
34
|
end
|
|
36
35
|
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
require 'faraday'
|
|
2
|
+
require 'multi_xml'
|
|
3
|
+
|
|
4
|
+
module Faraday
|
|
5
|
+
class Response::ParseXml < Faraday::Middleware
|
|
6
|
+
def on_complete(env)
|
|
7
|
+
return unless env[:body].is_a?(String) && !env[:body].strip.empty?
|
|
8
|
+
|
|
9
|
+
env[:body] = ::MultiXml.parse(env[:body])
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
Faraday::Response.register_middleware xml: Faraday::Response::ParseXml
|
metadata
CHANGED
|
@@ -1,43 +1,28 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: einvoice
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 1.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- David Yun
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: faraday
|
|
15
14
|
requirement: !ruby/object:Gem::Requirement
|
|
16
15
|
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: faraday_middleware
|
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
|
30
|
-
requirements:
|
|
31
|
-
- - ">="
|
|
16
|
+
- - "~>"
|
|
32
17
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '
|
|
18
|
+
version: '2.1'
|
|
34
19
|
type: :runtime
|
|
35
20
|
prerelease: false
|
|
36
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
22
|
requirements:
|
|
38
|
-
- - "
|
|
23
|
+
- - "~>"
|
|
39
24
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '
|
|
25
|
+
version: '2.1'
|
|
41
26
|
- !ruby/object:Gem::Dependency
|
|
42
27
|
name: multi_xml
|
|
43
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -80,20 +65,6 @@ dependencies:
|
|
|
80
65
|
- - ">="
|
|
81
66
|
- !ruby/object:Gem::Version
|
|
82
67
|
version: '0'
|
|
83
|
-
- !ruby/object:Gem::Dependency
|
|
84
|
-
name: gyoku
|
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
|
86
|
-
requirements:
|
|
87
|
-
- - ">="
|
|
88
|
-
- !ruby/object:Gem::Version
|
|
89
|
-
version: '0'
|
|
90
|
-
type: :runtime
|
|
91
|
-
prerelease: false
|
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
-
requirements:
|
|
94
|
-
- - ">="
|
|
95
|
-
- !ruby/object:Gem::Version
|
|
96
|
-
version: '0'
|
|
97
68
|
- !ruby/object:Gem::Dependency
|
|
98
69
|
name: bundler
|
|
99
70
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -114,14 +85,14 @@ dependencies:
|
|
|
114
85
|
requirements:
|
|
115
86
|
- - "~>"
|
|
116
87
|
- !ruby/object:Gem::Version
|
|
117
|
-
version: '
|
|
88
|
+
version: '13.0'
|
|
118
89
|
type: :development
|
|
119
90
|
prerelease: false
|
|
120
91
|
version_requirements: !ruby/object:Gem::Requirement
|
|
121
92
|
requirements:
|
|
122
93
|
- - "~>"
|
|
123
94
|
- !ruby/object:Gem::Version
|
|
124
|
-
version: '
|
|
95
|
+
version: '13.0'
|
|
125
96
|
- !ruby/object:Gem::Dependency
|
|
126
97
|
name: pry
|
|
127
98
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -206,17 +177,18 @@ dependencies:
|
|
|
206
177
|
- - ">="
|
|
207
178
|
- !ruby/object:Gem::Version
|
|
208
179
|
version: '0'
|
|
209
|
-
description:
|
|
210
180
|
email:
|
|
211
181
|
- abookyun@gmail.com
|
|
212
182
|
executables: []
|
|
213
183
|
extensions: []
|
|
214
184
|
extra_rdoc_files: []
|
|
215
185
|
files:
|
|
186
|
+
- ".coderabbit.yaml"
|
|
216
187
|
- ".github/workflows/build.yml"
|
|
217
188
|
- ".github/workflows/cron.yml"
|
|
218
189
|
- ".gitignore"
|
|
219
190
|
- ".rspec"
|
|
191
|
+
- CHANGELOG.md
|
|
220
192
|
- Gemfile
|
|
221
193
|
- LICENSE.txt
|
|
222
194
|
- README.md
|
|
@@ -240,14 +212,17 @@ files:
|
|
|
240
212
|
- lib/einvoice/tradevan/provider.rb
|
|
241
213
|
- lib/einvoice/tradevan/result.rb
|
|
242
214
|
- lib/einvoice/tradevan/validator/issue_data_validator.rb
|
|
243
|
-
- lib/einvoice/utils.rb
|
|
244
215
|
- lib/einvoice/version.rb
|
|
245
216
|
- lib/faraday/response/decode_tradevan.rb
|
|
217
|
+
- lib/faraday/response/parse_xml.rb
|
|
246
218
|
homepage: https://github.com/abookyun/einvoice
|
|
247
219
|
licenses:
|
|
248
220
|
- MIT
|
|
249
|
-
metadata:
|
|
250
|
-
|
|
221
|
+
metadata:
|
|
222
|
+
source_code_uri: https://github.com/abookyun/einvoice
|
|
223
|
+
changelog_uri: https://github.com/abookyun/einvoice/blob/main/CHANGELOG.md
|
|
224
|
+
bug_tracker_uri: https://github.com/abookyun/einvoice/issues
|
|
225
|
+
rubygems_mfa_required: 'true'
|
|
251
226
|
rdoc_options: []
|
|
252
227
|
require_paths:
|
|
253
228
|
- lib
|
|
@@ -255,15 +230,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
255
230
|
requirements:
|
|
256
231
|
- - ">="
|
|
257
232
|
- !ruby/object:Gem::Version
|
|
258
|
-
version:
|
|
233
|
+
version: '3.1'
|
|
259
234
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
260
235
|
requirements:
|
|
261
236
|
- - ">="
|
|
262
237
|
- !ruby/object:Gem::Version
|
|
263
238
|
version: '0'
|
|
264
239
|
requirements: []
|
|
265
|
-
rubygems_version:
|
|
266
|
-
signing_key:
|
|
240
|
+
rubygems_version: 4.0.20
|
|
267
241
|
specification_version: 4
|
|
268
|
-
summary:
|
|
242
|
+
summary: An API wrapper for Taiwan e-invoice services.
|
|
269
243
|
test_files: []
|