baiwang-sdk 0.0.1

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.
@@ -0,0 +1,273 @@
1
+ module Baiwang
2
+ module Apis
3
+ module Output
4
+ def output_blankinvoice_next(payload = {})
5
+ post 'baiwang.output.blankinvoice.next', payload
6
+ end
7
+
8
+ def output_blankinvoice_cancel(payload = {})
9
+ post 'baiwang.output.blankinvoice.cancel', payload
10
+ end
11
+
12
+ def output_device_query_apply_info(payload = {})
13
+ post 'baiwang.output.device.queryApplyInfo', payload
14
+ end
15
+
16
+ def output_device_apply_invoice(payload = {})
17
+ post 'baiwang.output.device.applyInvoice', payload
18
+ end
19
+
20
+ def output_device_invoice_confirm(payload = {})
21
+ post 'baiwang.output.device.invoiceConfirm', payload
22
+ end
23
+
24
+ def output_device_revoke_apply(payload = {})
25
+ post 'baiwang.output.device.revokeApply', payload
26
+ end
27
+
28
+ def output_device_query_apply_status(payload = {})
29
+ post 'baiwang.output.device.queryApplyStatus', payload
30
+ end
31
+
32
+ def output_device_query_buy_invoice_info_standard(payload = {})
33
+ post 'baiwang.output.device.queryBuyInvoiceInfoStandard', payload
34
+ end
35
+
36
+ def output_device_buy_invoice_standard(payload = {})
37
+ post 'baiwang.output.device.buyInvoiceStandard', payload
38
+ end
39
+
40
+ def output_invoice_usedcarissue(payload = {})
41
+ post 'baiwang.output.invoice.usedcarissue', payload
42
+ end
43
+
44
+ def output_invoice_vehicleissue(payload = {})
45
+ post 'baiwang.output.invoice.vehicleissue', payload
46
+ end
47
+
48
+ def output_invoice_print(payload = {})
49
+ post 'baiwang.output.invoice.print', payload
50
+ end
51
+
52
+ def output_invoice_query(payload = {})
53
+ post 'baiwang.output.invoice.query', payload
54
+ end
55
+
56
+ def output_invoice_upload(payload = {})
57
+ post 'baiwang.output.invoice.upload', payload
58
+ end
59
+
60
+ def output_invoice_cancel(payload = {})
61
+ post 'baiwang.output.invoice.cancel', payload
62
+ end
63
+
64
+ def output_invoice_issue(payload = {})
65
+ post 'baiwang.output.invoice.issue', payload
66
+ end
67
+
68
+ def output_preinvoice_issue(payload = {})
69
+ post 'baiwang.output.preinvoice.issue', payload
70
+ end
71
+
72
+ def output_preinvoice_query(payload = {})
73
+ post 'baiwang.output.preinvoice.query', payload
74
+ end
75
+
76
+ def output_preinvoice_batchimport(payload = {})
77
+ post 'baiwang.output.preinvoice.batchimport', payload
78
+ end
79
+
80
+ def output_preinvoice_restore(payload = {})
81
+ post 'baiwang.output.preinvoice.restore', payload
82
+ end
83
+
84
+ def output_preinvoice_scanadd(payload = {})
85
+ post 'baiwang.output.preinvoice.scanadd', payload
86
+ end
87
+
88
+ def output_preinvoice_cancel(payload = {})
89
+ post 'baiwang.output.preinvoice.cancel', payload
90
+ end
91
+
92
+ def output_format_create(payload = {})
93
+ post 'baiwang.output.format.create', payload
94
+ end
95
+
96
+ def output_format_query(payload = {})
97
+ post 'baiwang.output.format.query', payload
98
+ end
99
+
100
+ def output_redinfo_standardapply(payload = {})
101
+ post 'baiwang.output.redinfo.standardapply', payload
102
+ end
103
+
104
+ def output_redinfo_standardquery(payload = {})
105
+ post 'baiwang.output.redinfo.standardquery', payload
106
+ end
107
+
108
+ def output_invoice_revoke_red_info(payload = {})
109
+ post 'baiwang.output.invoice.revokeRedInfo', payload
110
+ end
111
+
112
+ def output_terminal_query(payload = {})
113
+ post 'baiwang.output.terminal.query', payload
114
+ end
115
+
116
+ def output_device_monitor(payload = {})
117
+ post 'baiwang.output.device.monitor', payload
118
+ end
119
+
120
+ def output_terminal_queryinventory(payload = {})
121
+ post 'baiwang.output.terminal.queryinventory', payload
122
+ end
123
+
124
+ def output_terminal_update(payload = {})
125
+ post 'baiwang.output.terminal.update', payload
126
+ end
127
+
128
+ def output_terminal_delete(payload = {})
129
+ post 'baiwang.output.terminal.delete', payload
130
+ end
131
+
132
+ def output_terminal_add(payload = {})
133
+ post 'baiwang.output.terminal.add', payload
134
+ end
135
+
136
+ def output_device_edit_device(payload = {})
137
+ post 'baiwang.output.device.editDevice', payload
138
+ end
139
+
140
+ def output_device_query_devices(payload = {})
141
+ post 'baiwang.output.device.queryDevices', payload
142
+ end
143
+
144
+ def output_device_add_device(payload = {})
145
+ post 'baiwang.output.device.addDevice', payload
146
+ end
147
+
148
+ def output_device_sync_devices(payload = {})
149
+ post 'baiwang.output.device.syncDevices', payload
150
+ end
151
+
152
+ def output_device_onekeyreport(payload = {})
153
+ post 'baiwang.output.device.onekeyreport', payload
154
+ end
155
+
156
+ def output_device_onekeywriteback(payload = {})
157
+ post 'baiwang.output.device.onekeywriteback', payload
158
+ end
159
+
160
+ def output_device_reportonline(payload = {})
161
+ post 'baiwang.output.device.reportonline', payload
162
+ end
163
+
164
+ def output_device_writebackonline(payload = {})
165
+ post 'baiwang.output.device.writebackonline', payload
166
+ end
167
+
168
+ def output_device_querycertificateno(payload = {})
169
+ post 'baiwang.output.device.querycertificateno', payload
170
+ end
171
+
172
+ def tax_device_connected(payload = {})
173
+ post 'baiwang.tax.device.connected', payload
174
+ end
175
+
176
+ def output_transaction_upload(payload = {})
177
+ post 'baiwang.output.transaction.upload', payload
178
+ end
179
+
180
+ def output_transaction_pushTransaction(payload = {})
181
+ post 'baiwang.output.transaction.pushTransaction', payload
182
+ end
183
+
184
+ def invoice_flow_single_query(payload = {})
185
+ post 'baiwang.invoice.FlowSingleQuery', payload
186
+ end
187
+
188
+ def output_transaction_erpbatchimport(payload = {})
189
+ post 'baiwang.output.transaction.erpbatchimport', payload
190
+ end
191
+
192
+ def output_transaction_generatepreinvoice(payload = {})
193
+ post 'baiwang.output.transaction.generatepreinvoice', payload
194
+ end
195
+
196
+ def output_transaction_querytree(payload = {})
197
+ post 'baiwang.output.transaction.querytree', payload
198
+ end
199
+
200
+ def output_transaction_querylist(payload = {})
201
+ post 'baiwang.output.transaction.querylist', payload
202
+ end
203
+
204
+ def output_transaction_delete(payload = {})
205
+ post 'baiwang.output.transaction.delete', payload
206
+ end
207
+
208
+ def output_transaction_cancel(payload = {})
209
+ post 'baiwang.output.transaction.cancel', payload
210
+ end
211
+
212
+ def output_customer_delete(payload = {})
213
+ post 'baiwang.output.customer.delete', payload
214
+ end
215
+
216
+ def output_customer_query(payload = {})
217
+ post 'baiwang.output.customer.query', payload
218
+ end
219
+
220
+ def output_customer_update(payload = {})
221
+ post 'baiwang.output.customer.update', payload
222
+ end
223
+
224
+ def output_customer_add(payload = {})
225
+ post 'baiwang.output.customer.add', payload
226
+ end
227
+
228
+ def bizinfo_search(payload = {})
229
+ post 'baiwang.bizinfo.search', payload
230
+ end
231
+
232
+ def bizinfo_company_search(payload = {})
233
+ post 'baiwang.bizinfo.companySearch', payload
234
+ end
235
+
236
+ def output_configure_manager_batchimportconfig(payload = {})
237
+ post 'baiwang.output.configureManager.batchimportconfig', payload
238
+ end
239
+
240
+ def output_configure_manager_queryconfig(payload = {})
241
+ post 'baiwang.output.configureManager.queryconfig', payload
242
+ end
243
+
244
+ def output_configure_manager_querywarnitem(payload = {})
245
+ post 'baiwang.output.configureManager.querywarnitem', payload
246
+ end
247
+
248
+ def output_configure_manager_setearlywarn(payload = {})
249
+ post 'baiwang.output.configureManager.setearlywarn', payload
250
+ end
251
+
252
+ def output_configure_manager_querywarnrecord(payload = {})
253
+ post 'baiwang.output.configureManager.querywarnrecord', payload
254
+ end
255
+
256
+ def output_productcode_add(payload = {})
257
+ post 'baiwang.output.productcode.add', payload
258
+ end
259
+
260
+ def output_productcode_update(payload = {})
261
+ post 'baiwang.output.productcode.update', payload
262
+ end
263
+
264
+ def output_productcode_delete(payload = {})
265
+ post 'baiwang.output.productcode.delete', payload
266
+ end
267
+
268
+ def output_productcode_query(payload = {})
269
+ post 'baiwang.output.productcode.query', payload
270
+ end
271
+ end
272
+ end
273
+ end
@@ -0,0 +1,109 @@
1
+ module Baiwang
2
+ module Apis
3
+ module Scc
4
+ def scc_paymentcollaboration_paymentadd(payload = {})
5
+ post 'baiwang.scc.paymentcollaboration.paymentadd', payload
6
+ end
7
+
8
+ def scc_paymentcollaboration_paymentupdate(payload = {})
9
+ post 'baiwang.scc.paymentcollaboration.paymentupdate', payload
10
+ end
11
+
12
+ def scc_paymentcollaboration_paymentdelete(payload = {})
13
+ post 'baiwang.scc.paymentcollaboration.paymentdelete', payload
14
+ end
15
+
16
+ def scc_documentscollaboration_receiptimport(payload = {})
17
+ post 'baiwang.scc.documentscollaboration.receiptimport', payload
18
+ end
19
+
20
+ def scc_documentscollaboration_receiptupdate(payload = {})
21
+ post 'baiwang.scc.documentscollaboration.receiptupdate', payload
22
+ end
23
+
24
+ def scc_documentscollaboration_receiptquery(payload = {})
25
+ post 'baiwang.scc.documentscollaboration.receiptquery', payload
26
+ end
27
+
28
+ def scc_documentscollaboration_settlementquery(payload = {})
29
+ post 'baiwang.scc.documentscollaboration.settlementquery', payload
30
+ end
31
+
32
+ def scc_documentscollaboration_settlementquerybyid(payload = {})
33
+ post 'baiwang.scc.documentscollaboration.settlementquerybyid', payload
34
+ end
35
+
36
+ def scc_documentscollaboration_orderimport(payload = {})
37
+ post 'baiwang.scc.documentscollaboration.orderimport', payload
38
+ end
39
+
40
+ def scc_inputcollaboration_importsettlement(payload = {})
41
+ post 'baiwang.scc.inputcollaboration.importsettlement', payload
42
+ end
43
+
44
+ def scc_inputcollaboration_updatestatementinfo(payload = {})
45
+ post 'baiwang.scc.inputcollaboration.updatestatementinfo', payload
46
+ end
47
+
48
+ def scc_inputcollaboration_deleteinputstatementinfo(payload = {})
49
+ post 'baiwang.scc.inputcollaboration.deleteinputstatementinfo', payload
50
+ end
51
+
52
+ def scc_inputcollaboration_inputfindstatement(payload = {})
53
+ post 'baiwang.scc.inputcollaboration.inputfindstatement', payload
54
+ end
55
+
56
+ def scc_inputcollaboration_querybystatement(payload = {})
57
+ post 'baiwang.scc.inputcollaboration.querybystatement', payload
58
+ end
59
+
60
+ def scc_inputcollaboration_query(payload = {})
61
+ post 'baiwang.scc.inputcollaboration.query', payload
62
+ end
63
+
64
+ def scc_inputcollaboration_updatematchstatus(payload = {})
65
+ post 'baiwang.scc.inputcollaboration.updatematchstatus', payload
66
+ end
67
+
68
+ def scc_inputcollaboration_inputfindmatchstatus(payload = {})
69
+ post 'baiwang.scc.inputcollaboration.inputfindmatchstatus', payload
70
+ end
71
+
72
+ def scc_inputcollaboration_queryinvoiceinfo(payload = {})
73
+ post 'baiwang.scc.inputcollaboration.queryinvoiceinfo', payload
74
+ end
75
+
76
+ def scc_collaborationconsole_supplieradd(payload = {})
77
+ post 'baiwang.scc.collaborationconsole.supplieradd', payload
78
+ end
79
+
80
+ def scc_collaborationconsole_supplierdelete(payload = {})
81
+ post 'baiwang.scc.collaborationconsole.supplierdelete', payload
82
+ end
83
+
84
+ def scc_collaborationconsole_supplierupdate(payload = {})
85
+ post 'baiwang.scc.collaborationconsole.supplierupdate', payload
86
+ end
87
+
88
+ def scc_collaborationconsole_supplierquery(payload = {})
89
+ post 'baiwang.scc.collaborationconsole.supplierquery', payload
90
+ end
91
+
92
+ def scc_collaborationconsole_goodsmanageradd(payload = {})
93
+ post 'baiwang.scc.collaborationconsole.goodsmanageradd', payload
94
+ end
95
+
96
+ def scc_collaborationconsole_goodsmanagerdelete(payload = {})
97
+ post 'baiwang.scc.collaborationconsole.goodsmanagerdelete', payload
98
+ end
99
+
100
+ def scc_collaborationconsole_goodsmanagerupdate(payload = {})
101
+ post 'baiwang.scc.collaborationconsole.goodsmanagerupdate', payload
102
+ end
103
+
104
+ def scc_collaborationconsole_goodsmanagerquery(payload = {})
105
+ post 'baiwang.scc.collaborationconsole.goodsmanagerquery', payload
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,41 @@
1
+ module Baiwang
2
+ module Apis
3
+ module UserCenter
4
+ def common_company_verify_query(payload={})
5
+ post 'baiwang.common.company.verify.query', payload
6
+ end
7
+
8
+ def usercenter_tenant_add_tenant(payload={})
9
+ post 'baiwang.usercenter.tenant.addTenant', payload
10
+ end
11
+
12
+ def invoice_admin_update_apply_for(payload = {})
13
+ post 'baiwang.invoice.admin.update.applyFor', payload
14
+ end
15
+
16
+ def invoice_admin_get_tax_no_info(payload = {})
17
+ post 'baiwang.invoice.admin.getTaxNoInfo', payload
18
+ end
19
+
20
+ def usercenter_user_add_user(payload = {})
21
+ post 'baiwang.usercenter.user.addUser', payload
22
+ end
23
+
24
+ def usercenter_user_update_user(payload = {})
25
+ post 'baiwang.usercenter.user.updateUser', payload
26
+ end
27
+
28
+ def usercenter_org_add_org(payload = {})
29
+ post 'baiwang.usercenter.org.addOrg', payload
30
+ end
31
+
32
+ def usercenter_org_get_org_by_condition(payload = {})
33
+ post 'baiwang.usercenter.org.getOrgByCondition', payload
34
+ end
35
+
36
+ def usercenter_org_update_org(payload = {})
37
+ post 'baiwang.usercenter.org.updateOrg', payload
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,39 @@
1
+ require 'logger'
2
+
3
+ module Baiwang
4
+ class << self
5
+ def configure
6
+ yield config
7
+ end
8
+
9
+ def config
10
+ @config ||= Config.new
11
+ end
12
+
13
+ def redis
14
+ config.redis
15
+ end
16
+
17
+ def logger
18
+ @logger ||= if config.logger.nil?
19
+ defined?(Rails) && Rails.logger ? Rails.logger : Logger.new(STDOUT)
20
+ else
21
+ config.logger
22
+ end
23
+ end
24
+
25
+ def http_timeout_options
26
+ config.http_timeout_options || { write: 2, connect: 5, read: 10 }
27
+ end
28
+
29
+ def api_base_url
30
+ return @api_base_url if defined?(@api_base_url)
31
+
32
+ @api_base_url = config.api_base_url
33
+ end
34
+ end
35
+
36
+ class Config
37
+ attr_accessor :default_app_key, :default_app_secret, :redis, :http_timeout_options, :logger, :api_base_url, :default_admin_username, :default_admin_password, :default_admin_salt
38
+ end
39
+ end
@@ -0,0 +1,17 @@
1
+ module Baiwang
2
+ module Helper
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ def api_mount(name)
7
+ class_eval <<-CODE, __FILE__, __LINE__ + 1
8
+ def #{name.to_s.gsub('/', '_')}
9
+ @#{name.to_s.gsub('/', '_')} ||= Class.new(SimpleDelegator) do
10
+ include ::Baiwang::Apis::#{name.to_s.classify}
11
+ end.new(self)
12
+ end
13
+ CODE
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,85 @@
1
+ require 'http'
2
+ require 'base64'
3
+ require 'json'
4
+ require 'digest'
5
+ require 'securerandom'
6
+
7
+ module Baiwang
8
+ class Request
9
+ attr_reader :ssl_context, :http
10
+
11
+ def initialize(skip_verify_ssl = true)
12
+ @http = HTTP.timeout(**Baiwang.http_timeout_options)
13
+ @ssl_context = OpenSSL::SSL::SSLContext.new
14
+ @ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE if skip_verify_ssl
15
+ end
16
+
17
+ def post(method, token, post_body, post_header = {})
18
+ par = basic_params(method, token)
19
+ par.merge!({sign: sign_pb(par, post_body)})
20
+ path = "/router/rest?#{build_sorted_params(par)}"
21
+
22
+ request(path, post_header) do |url, header|
23
+ params = header.delete(:params)
24
+ header['Content-Type'] = 'application/json'
25
+ http.headers(header).post(url, params: params, json: post_body, ssl_context: ssl_context)
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def request(path, header = {}, &_block)
32
+ url = URI.join(Baiwang.api_base_url, path)
33
+ response = yield(url, header)
34
+ unless response.status.success?
35
+ Baiwang.logger.error "request #{url} happen error: #{response.body}"
36
+ raise ResponseError.new(response.status, response.body)
37
+ end
38
+ parse_as_json(response.body)
39
+ end
40
+
41
+ def parse_as_json(body)
42
+ data = JSON.parse body.to_s
43
+ Result.new(data)
44
+ end
45
+
46
+ # sign with params and body
47
+ def sign_pb(par, body)
48
+ q = par.sort.map { |k, v| "#{k}#{v}" unless k.start_with?("sign") }.join
49
+ text = "#{Baiwang.config.default_app_secret}#{q}#{body.to_json}#{Baiwang.config.default_app_secret}"
50
+ Digest::MD5.hexdigest(text).upcase
51
+ end
52
+
53
+ def basic_params(method, token)
54
+ {
55
+ "method": method,
56
+ "appKey": Baiwang.config.default_app_key,
57
+ "token": token,
58
+ "timestamp": "#{(Time.now.to_f.round(3)*1000).to_i}",
59
+ "format": "json",
60
+ "version": "3.0",
61
+ "type": "sync",
62
+ "requestId": SecureRandom.uuid
63
+ }
64
+ end
65
+
66
+ def build_sorted_params(par)
67
+ q = par.sort.map { |k, v| "#{k}=#{v}&" }.join
68
+ q.chop if q.end_with?('&')
69
+ end
70
+ end
71
+
72
+ class Result
73
+ attr_reader :code, :data, :error
74
+
75
+ def initialize(data)
76
+ @code = data['code'].to_i
77
+ @data = data['response']
78
+ @error = data['errorResponse']
79
+ end
80
+
81
+ def success?
82
+ code.zero? && error.empty?
83
+ end
84
+ end
85
+ end
@@ -0,0 +1 @@
1
+ require 'baiwang'
@@ -0,0 +1,44 @@
1
+ require 'baiwang/token_store/base'
2
+ require 'http'
3
+
4
+ module Baiwang
5
+ module TokenStore
6
+ class AppToken < Base
7
+ def token_key
8
+ 'access_token'
9
+ end
10
+
11
+ def fetch_token
12
+ q = build_sorted_params(
13
+ {
14
+ method: 'baiwang.oauth.token',
15
+ grant_type: 'password',
16
+ client_id: client.app_key,
17
+ client_secret: client.app_secret,
18
+ username: client.admin_username,
19
+ password: digest_password,
20
+ version: '3.0',
21
+ timestamp: Time.now.to_i
22
+ }
23
+ )
24
+ http = HTTP.timeout(**Baiwang.http_timeout_options)
25
+ header = { 'Content-Type': 'application/x-www-form-urlencoded' }
26
+ response = http.headers(header).post("#{Baiwang.api_base_url}/router/rest?#{q}")
27
+ Baiwang::Result.new JSON.parse(response.body.to_s)
28
+ end
29
+
30
+ private
31
+
32
+ def digest_password
33
+ Digest::SHA1.hexdigest(
34
+ Digest::MD5.new.hexdigest(@client.admin_password + @client.admin_salt)
35
+ )
36
+ end
37
+
38
+ def build_sorted_params(par)
39
+ q = par.sort.map { |k, v| "#{k}=#{v}&" }.join
40
+ q.chop if q.end_with?('&')
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,53 @@
1
+ module Baiwang
2
+ module TokenStore
3
+ class Base
4
+ attr_accessor :client
5
+
6
+ def initialize(client)
7
+ @client = client
8
+ raise RedisNotConfigException if redis.nil?
9
+ end
10
+
11
+ def token
12
+ update_token if expired?
13
+ redis.hget(redis_key, token_key)
14
+ end
15
+
16
+ def valid?
17
+ token.present?
18
+ end
19
+
20
+ def update_token
21
+ data = fetch_token.data
22
+ value = data[token_key]
23
+ if value.nil?
24
+ Baiwang.logger.error "#{self.class.name} fetch token error: #{data.inspect}"
25
+ else
26
+ expires_at = Time.now.to_i + data['expires_in'].to_i - 120
27
+ redis.hmset(
28
+ redis_key,
29
+ token_key, value,
30
+ 'expires_at', expires_at
31
+ )
32
+ redis.expireat(redis_key, expires_at)
33
+ end
34
+
35
+ value
36
+ end
37
+
38
+ private
39
+
40
+ def redis
41
+ Baiwang.redis
42
+ end
43
+
44
+ def redis_key
45
+ @redis_key ||= Digest::MD5.hexdigest "#{self.class.name}_#{client.app_key}_#{client.app_secret}"
46
+ end
47
+
48
+ def expired?
49
+ redis.hvals(redis_key).empty? || redis.hget(redis_key, 'expires_at').to_i <= Time.now.to_i
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Baiwang
4
+ VERSION = "0.0.1"
5
+ end
data/lib/baiwang.rb ADDED
@@ -0,0 +1,25 @@
1
+ require 'baiwang/version'
2
+ require 'active_support/all'
3
+ require 'redis'
4
+ require 'baiwang/config'
5
+ require 'baiwang/helper'
6
+ require 'baiwang/request'
7
+
8
+ lib_path = "#{File.dirname(__FILE__)}/baiwang"
9
+ Dir["#{lib_path}/apis/**/*.rb", "#{lib_path}/token_store/*.rb"].each { |path| require path }
10
+
11
+ require 'baiwang/api'
12
+
13
+ module Baiwang
14
+ class RedisNotConfigException < RuntimeError; end
15
+ class AppNotConfigException < RuntimeError; end
16
+ class AccessTokenExpiredError < RuntimeError; end
17
+ class ResultErrorException < RuntimeError; end
18
+ class ResponseError < StandardError
19
+ attr_reader :error_code
20
+ def initialize(errcode, errmsg = '')
21
+ @error_code = errcode
22
+ super "(#{error_code}) #{errmsg}"
23
+ end
24
+ end
25
+ end