czech_post_b2b_client 1.0.3 → 1.1.0

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
  SHA1:
3
- metadata.gz: d7c296befdf3e8a0575b0855f80ddc0bfd730db4
4
- data.tar.gz: 2c9519c8d7e5a483c60cf356bafe5dd652149763
3
+ metadata.gz: 07426ba1b8f688f648faebda86173b514127a3b9
4
+ data.tar.gz: 8cfd179622eaa1aac8b0043acf01089a9d66e1b9
5
5
  SHA512:
6
- metadata.gz: a66d5f3d8160159490b7197cd0e1edf0107e7cb6610d019495a8ab02650118881f94d6c8deca7ef3bce55cdcfe3573392626e10220ec158876f807556f147b81
7
- data.tar.gz: f0cdc245a2c4f58432475e7cb3afe32acb707d0710e150977e823418142424f955ae3301748aeae072cf994db52654d0c544d02257bfd8bdc6e6dc7219e16a94
6
+ metadata.gz: 538d4a70a50d9b48d3740e67eadcdd82ea8965acd321cbb9bb690ed7cb987966bc03f757ccff7115d67287a581f6dd53a0e948ea14a70168a95e89bb1236c330
7
+ data.tar.gz: 5549ec8f20778309738add18ec827a4b20cb449a307e1825e7bd1b2891608129ef1f806e4e73eb101e700640a57d76e0f79f7c0275a291a993f9addcab80bb49
@@ -14,7 +14,7 @@ AllCops:
14
14
  - "bin/*"
15
15
  Documentation:
16
16
  Enabled: false
17
- Metrics/LineLength:
17
+ Layout/LineLength:
18
18
  Max: 120
19
19
  Metrics/AbcSize:
20
20
  Max: 20
data/README.md CHANGED
@@ -2,12 +2,15 @@
2
2
  Accessing B2B API of Czech Post for bulk processing of parcels ("B2B - WS PodáníOnline").
3
3
 
4
4
  There are these supported operations of API:
5
+ - *parcelServiceSync* - stores data of one parcel and return package_code and optional PDF adress sheet [HTTP POST - sync response]
6
+ Seems to me, that there are is no place extensive Cash On Delivery data, just `amount` and `currency`
5
7
  - *sendParcels* - stores data of parcels for async processing [HTTP POST - async response]
6
8
  - *getResultParcels* - return results of such processing [HTTP GET - sync response]
7
9
  - *getStats* - returns statistics of parcels sent in time period [HTTP GET - sync response]
8
10
  - *getParcelState* - returns all known states for listed parcels [HTTP GET - sync response]
9
11
  - *getParcelsPrinting* - returns PDF with address labels/stickers for listed parcels [HTTP GET - sync response]
10
12
 
13
+
11
14
  ## Installation
12
15
  ### 1) Registration at Czech Post (CP)
13
16
  The longterm and hardest part.
@@ -140,9 +143,9 @@ Or install it yourself as:
140
143
 
141
144
  1) Pack your parcel(s)
142
145
 
143
- 2) Call `ParcelsSender`, this will store in `result` `transmission_id` and expected time to ask for results.
146
+ 2) Call `ParcelsAsyncSender`, this will store in `result` `transmission_id` and expected time to ask for results.
144
147
  ```
145
- psender = CzechPostB2bClient::Services::ParcelsSender.call(sending_data: sending_data, parcels: parcels)
148
+ psender = CzechPostB2bClient::Services::ParcelsAsyncSender.call(sending_data: sending_data, parcels: parcels)
146
149
 
147
150
  if psender.success?
148
151
  result = psender.result
@@ -21,8 +21,8 @@ module CzechPostB2bClient
21
21
 
22
22
  # ours, accessible, but maybe out of date, for test usage
23
23
  @namespaces = {
24
- 'xmlns' => 'https://raw.githubusercontent.com/foton/czech_post_b2b_client/master/doc/20181023/B2BCommon-v1.1.xsd',
25
- 'xmlns:ns2' => 'https://raw.githubusercontent.com/foton/czech_post_b2b_client/master/doc/20181023/B2B-POLServices-v1.6.xsd'
24
+ 'xmlns' => 'https://raw.githubusercontent.com/foton/czech_post_b2b_client/master/documents/B2B_CP_POL_2020-05-21/B2BCommon-v1.1.xsd',
25
+ 'xmlns:ns2' => 'https://raw.githubusercontent.com/foton/czech_post_b2b_client/master/documents/B2B_CP_POL_2020-05-21/B2B-POLServices-v1.8.xsd'
26
26
  }
27
27
  # original, accessible only with setup certificates
28
28
  @namespaces = {
@@ -22,6 +22,7 @@ module CzechPostB2bClient
22
22
  @id = 8
23
23
  @description = 'adresní štítek (alonž) + dobírková poukázka A'
24
24
  end
25
+
25
26
  class Blank4OnPage < Base
26
27
  @id = 20
27
28
  @description = 'adresní štítek bianco - 4x (A4)'
@@ -40,22 +41,22 @@ module CzechPostB2bClient
40
41
  module ForeignPackage
41
42
  class Standard < Base
42
43
  @id = 58
43
- @description = ' - samostatný Standardní balík do zahraničí'
44
+ @description = 'CP72 - standardní balík do zahraničí'
44
45
  end
45
46
 
46
- class Standard4OnPage < Base
47
+ class Standard2OnPage < Base
47
48
  @id = 59
48
- @description = ' - 4xA4 Standardní balík do zahraničí'
49
+ @description = 'CP72 - standardní balík do zahraničí (2x A4 )'
49
50
  end
50
51
 
51
52
  class Valuable < Base
52
53
  @id = 60
53
- @description = ' - samostatný Cenný balík do zahraničí'
54
+ @description = 'CP72 - cenný balík do zahraničí'
54
55
  end
55
56
 
56
57
  class Valuable4OnPage < Base
57
58
  @id = 61
58
- @description = '4xA4 Cenný balík do zahraničí'
59
+ @description = 'CP72 - cenný balík do zahraničí (2x A4)'
59
60
  end
60
61
 
61
62
  class EMS < Base
@@ -67,6 +68,18 @@ module CzechPostB2bClient
67
68
  @id = 63
68
69
  @description = 'AŠ - 2xA4 EMS do zahraničí'
69
70
  end
71
+
72
+ # Formulare ID 72 a 73 je mozno pouzit pouze pro zasilky s prefixem CE
73
+ # do zemi AT, DE, FR, GR, HR, CH, IS, LU, LV, NO, PL, SK
74
+ class HarmonizedLabel < Base
75
+ @id = 72
76
+ @description = 'Obchodní balík do zahraničí – samostatný'
77
+ end
78
+
79
+ class HarmonizedLabel4OnPage < Base
80
+ @id = 73
81
+ @description = 'Obchodní balík do zahraničí – 4x (A4)'
82
+ end
70
83
  end
71
84
  end
72
85
 
@@ -132,28 +145,32 @@ module CzechPostB2bClient
132
145
  @description = 'Dodejka'
133
146
  end
134
147
 
135
- class CustomDeclarationCN22 < Base
136
- @id = 56
137
- @description = 'Celní prohlášení CN22'
138
- end
148
+ module CustomDeclaration
149
+ class CN22 < Base
150
+ @id = 56
151
+ @description = 'Celní prohlášení CN22 - 1x (A4)'
152
+ end
139
153
 
140
- class CustomDeclarationCN23 < Base
141
- @id = 57
142
- @description = 'Celní prohlášení CN23'
143
- end
154
+ class CN23 < Base
155
+ @id = 57
156
+ @description = 'Celní prohlášení CN23 - 1x (A4)'
157
+ end
144
158
 
145
- # Formulare ID 72 a 73 je mozno pouzit pouze pro zasilky s prefixem CE
146
- # do zemi AT, DE, FR, GR, HR, CH, IS, LU, LV, NO, PL, SK
147
- class HarmonizedLabel < Base
148
- @id = 72
149
- @description = 'Harmonizovaný štítek pro MZ produkty – samostatný'
150
- end
159
+ class CN224OnPage < Base
160
+ @id = 74
161
+ @description = 'Celní prohlášení CN22 - 4x (A4)'
162
+ end
151
163
 
152
- class HarmonizedLabel4OnPage < Base
153
- @id = 73
154
- @description = 'Harmonizovaný štítek pro MZ produkty – 4x (A4)'
155
- end
164
+ class CN22WithCK < Base
165
+ @id = 75
166
+ @description = 'Celní prohlášení CN22 s ČK - 1x (A4)'
167
+ end
156
168
 
169
+ class CN22WithCK4OnPage < Base
170
+ @id = 76
171
+ @description = 'Celní prohlášení CN22 s ČK - 4x (A4)'
172
+ end
173
+ end
157
174
  # has to be at the end, to load all subcasses before
158
175
  def self.all_classes
159
176
  ObjectSpace.each_object(CzechPostB2bClient::PrintingTemplates::Base.singleton_class)
@@ -6,3 +6,4 @@ require 'czech_post_b2b_client/request_builders/get_parcels_printing_builder'
6
6
  require 'czech_post_b2b_client/request_builders/get_parcel_state_builder'
7
7
  require 'czech_post_b2b_client/request_builders/get_result_parcels_builder'
8
8
  require 'czech_post_b2b_client/request_builders/send_parcels_builder'
9
+ require 'czech_post_b2b_client/request_builders/parcel_service_sync_builder'
@@ -0,0 +1,312 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rubocop:disable Layout/LineLength, Style/AsciiComments
4
+
5
+ module CzechPostB2bClient
6
+ module RequestBuilders
7
+ class ParcelServiceSyncBuilder < BaseBuilder # rubocop:disable Metrics/ClassLength
8
+ attr_reader :common_data, :parcel
9
+
10
+ def initialize(common_data:, parcel:, request_id: 1)
11
+ @common_data = common_data
12
+ @parcel = parcel
13
+ @request_id = request_id
14
+ end
15
+
16
+ private
17
+
18
+ def validate_data
19
+ validate_common_data_required_fields
20
+
21
+ if parcel.empty?
22
+ errors.add(:parcel, 'One parcel is needed!')
23
+ else
24
+ validate_parcel_required_fields
25
+ end
26
+
27
+ fail! unless errors.empty?
28
+ end
29
+
30
+ def service_data_struct
31
+ new_element('serviceData').tap do |srv_data|
32
+ add_element_to(srv_data, send_parcels)
33
+ end
34
+ end
35
+
36
+ def validate_common_data_required_fields
37
+ [[:parcels_sending_date],
38
+ [:customer_id],
39
+ [:sending_post_office_code]].each do |key_chain|
40
+ value = common_data.dig(*key_chain)
41
+ if value.nil? || value == ''
42
+ errors.add(:common_data, "Missing value for key { :#{key_chain.join(' => :')} }!")
43
+ end
44
+ end
45
+ end
46
+
47
+ def validate_parcel_required_fields
48
+ rq_fields = [
49
+ %i[params parcel_id],
50
+ %i[params parcel_code_prefix],
51
+ %i[addressee address last_name],
52
+ %i[addressee address street],
53
+ %i[addressee address house_number],
54
+ %i[addressee address city],
55
+ %i[addressee address post_code]
56
+ ]
57
+
58
+ parcel_id = parcel.dig(:params, :parcel_id)
59
+ rq_fields.each do |key_chain|
60
+ value = parcel.dig(*key_chain)
61
+
62
+ if value.nil? || value == ''
63
+ errors.add(:parcel, "Missing value for key { :#{key_chain.join(' => :')} } for parcel (parcel_id: '#{parcel_id}')!")
64
+ end
65
+ end
66
+ end
67
+
68
+ def send_parcels
69
+ new_element('ns2:parcelServiceSyncRequest').tap do |ps_sync_request|
70
+ add_element_to(ps_sync_request, do_parcel_header) # REQUIRED
71
+ add_element_to(ps_sync_request, do_parcel_data) # optional
72
+ end
73
+ end
74
+
75
+ def do_parcel_header # rubocop:disable Metrics/AbcSize
76
+ new_element('ns2:doPOLSyncParcelHeader').tap do |parcel_header|
77
+ add_element_to(parcel_header, 'ns2:transmissionDate', value: common_data[:parcels_sending_date].strftime('%d.%m.%Y')) # Predpokladane datum podani (format DD.MM.YYYY !)
78
+ add_element_to(parcel_header, 'ns2:customerID', value: common_data[:customer_id]) # Technologicke cislo podavatele
79
+ add_element_to(parcel_header, 'ns2:postCode', value: common_data[:sending_post_office_code]) # PSC podaci posty
80
+ add_element_to(parcel_header, 'ns2:contractNumber', value: common_data[:contract_number]) # Nepovinne: Cislo zakazky
81
+ add_element_to(parcel_header, 'ns2:frankingNumber', value: common_data[:franking_machine_number]) # Nepovinne: Cislo vyplatniho stroje
82
+ add_element_to(parcel_header, 'ns2:transmissionEnd', value: common_data[:close_requests_batch]) # Nepovinna, default true: Indikace zda uzavrit podani, nebo budou jeste nasledovat dalsi requesty pro stejne podani
83
+ add_element_to(parcel_header, 'ns2:locationNumber', value: common_data[:sending_post_office_location_number]) # Nepovinne: cislo podaciho mista (z nastaveni v Podani Online)
84
+ add_element_to(parcel_header, 'ns2:senderCustCardNum', value: sender_data[:custom_card_number]) # Nepovinne: cislo zakaznicke karty odesilatele
85
+ add_element_to(parcel_header, print_params)
86
+ end
87
+ end
88
+
89
+ def do_parcel_data
90
+ new_element('ns2:doPOLSyncParcelData').tap do |do_parcel_data|
91
+ add_element_to(do_parcel_data, do_parcel_params)
92
+ add_element_to(do_parcel_data, do_parcel_address)
93
+ add_element_to(do_parcel_data, do_parcel_address_document)
94
+ add_element_to(do_parcel_data, do_parcel_customs_declaration)
95
+ add_customs_documents_to(do_parcel_data)
96
+ end
97
+ end
98
+
99
+ def print_params
100
+ return nil unless (pp = common_data[:print_params])
101
+
102
+ new_element('ns2:printParams').tap do |print_params|
103
+ add_element_to(print_params, 'ns2:idForm', value: pp[:template_id]) # Nepovine[0-20x]: ID formulare
104
+ add_element_to(print_params, 'ns2:shiftHorizontal', value: pp[:margin_in_mm][:left]) # Hodnota posunu doprava v mm
105
+ add_element_to(print_params, 'ns2:shiftVertical', value: pp[:margin_in_mm][:top]) # Hodnota posunu dolu v mm
106
+ add_element_to(print_params, 'ns2:position', value: pp[:position_order]) # Nepovinna: Hodnota pozice
107
+ end
108
+ end
109
+
110
+ def cache_on_delivery_address
111
+ adr_data = common_data.dig(:cash_on_delivery, :address)
112
+ return nil unless adr_data
113
+
114
+ new_element('ns2:codAddress').tap do |cod_address|
115
+ add_address_elements(cod_address, adr_data, without: ['ns2:firstName', 'ns2:surname'])
116
+ end
117
+ end
118
+
119
+ def cache_on_delivery_bank
120
+ data = common_data.dig(:cash_on_delivery, :bank_account)
121
+ return nil unless data
122
+
123
+ new_element('ns2:codBank').tap do |cod_bank|
124
+ add_bank_elements(cod_bank, data)
125
+ end
126
+ end
127
+
128
+ def sender_contacts
129
+ return nil unless sender_data
130
+
131
+ new_element('ns2:senderContacts').tap do |element|
132
+ add_contact_elements(element, sender_data) # Nepovinne. Telefon, Mobil a Email
133
+ end
134
+ end
135
+
136
+ def do_parcel_params # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
137
+ params = parcel[:params]
138
+ cod = parcel[:cash_on_delivery] || {}
139
+ new_element('ns2:doPOLSyncParcelParams').tap do |parcel_params|
140
+ add_element_to(parcel_params, 'ns2:recordID', value: params[:parcel_id]) # Unikatni ID zaznamu
141
+ add_element_to(parcel_params, 'ns2:parcelCode', value: params[:parcel_code]) # Nepovinne: ID zasilky
142
+ add_element_to(parcel_params, 'ns2:prefixParcelCode', value: params[:parcel_code_prefix]) # Typ zasilky (prefix)
143
+ add_element_to(parcel_params, 'ns2:weight', value: params[:weight_in_kg]) # Nepovinne: Hmotnost
144
+ add_element_to(parcel_params, 'ns2:insuredValue', value: params[:insured_value]) # Nepovinne: Udana cena
145
+ add_element_to(parcel_params, 'ns2:amount', value: cod[:amount]) # Nepovinne: Dobirka
146
+ add_element_to(parcel_params, 'ns2:currency', value: cod[:currency_iso_code]) # Nepovinne, default CZK: ISO kod meny dobirky
147
+ add_element_to(parcel_params, 'ns2:vsVoucher', value: params[:voucher_variable_symbol]) # Nepovinne: Variabilni symbol - poukazka
148
+ add_element_to(parcel_params, 'ns2:vsParcel', value: params[:parcel_variable_symbol]) # Nepovinne: Variabilni symbol - zasilka
149
+ add_element_to(parcel_params, 'ns2:sequenceParcel', value: params[:parcel_order]) # Nepovinne: Poradi v ramci vicekusove zasilky
150
+ add_element_to(parcel_params, 'ns2:quantityParcel', value: params[:parcels_count]) # Nepovinne: Celkovy pocet zasilek vicekusove zasilky
151
+ add_element_to(parcel_params, 'ns2:note', value: params[:note]) # Nepovinne: Poznamka
152
+ add_element_to(parcel_params, 'ns2:notePrint', value: params[:note_for_print]) # Nepovinne: Poznamka pro tisk
153
+ add_element_to(parcel_params, 'ns2:length', value: params[:length]) # Nepovinne: Delka
154
+ add_element_to(parcel_params, 'ns2:width', value: params[:width]) # Nepovinne: Sirka
155
+ add_element_to(parcel_params, 'ns2:height', value: params[:height]) # Nepovinne: Vyska
156
+ add_element_to(parcel_params, 'ns2:mrn', value: params[:mrn_code]) # Nepovinne: Kod MRN
157
+ add_element_to(parcel_params, 'ns2:referenceNumber', value: params[:reference_number]) # Nepovinne: Cislo jednaci
158
+ add_element_to(parcel_params, 'ns2:pallets', value: params[:pallets_count]) # Nepovinne: Pocet palet
159
+ add_element_to(parcel_params, 'ns2:specSym', value: params[:specific_symbol]) # Nepovinne: Specificky symbol
160
+ add_element_to(parcel_params, 'ns2:note2', value: params[:note2]) # Nepovinne: Poznamka 2
161
+ add_element_to(parcel_params, 'ns2:numSign', value: params[:documents_to_sign_count]) # Nepovinne: Počet dokumentů
162
+ add_element_to(parcel_params, 'ns2:score', value: params[:score]) # Nepovinne: Napocet ceny sluzby
163
+ add_element_to(parcel_params, 'ns2:orderNumberZPRO', value: params[:zpro_order_number]) # Nepovinne: Cislo objednavky ZPRO
164
+ add_element_to(parcel_params, 'ns2:returnNumDays', value: params[:days_to_deposit]) # Nepovinne: Pocet dni pro vraceni zasilky
165
+ add_parcel_services(parcel_params)
166
+ end
167
+ end
168
+
169
+ def add_parcel_services(parent_element)
170
+ (parcel[:services] || []).each do |p_service|
171
+ srv_element = new_element('ns2:doPOLParcelServices').tap do |dps|
172
+ add_element_to(dps, 'ns2:service', value: p_service)
173
+ end
174
+
175
+ add_element_to(parent_element, srv_element)
176
+ end
177
+ end
178
+
179
+ def do_parcel_address
180
+ add_parcel_adress_element('ns2:doPOLParcelAddress', parcel[:addressee])
181
+ end
182
+
183
+ def do_parcel_address_document
184
+ add_parcel_adress_element('ns2:doPOLParcelAddressDocument', parcel[:document_addressee])
185
+ end
186
+
187
+ def add_parcel_adress_element(element_name, addressee_data) # rubocop:disable Metrics/AbcSize
188
+ return nil if addressee_data.nil?
189
+
190
+ address_data = addressee_data[:address]
191
+ new_element(element_name).tap do |do_parcel_address|
192
+ add_element_to(do_parcel_address, 'ns2:recordID', value: addressee_data[:addressee_id]) # Nepovinne: Interni oznaceni adresata
193
+
194
+ add_address_elements(do_parcel_address, address_data) # Nepovinne: Adresa
195
+
196
+ add_element_to(do_parcel_address, 'ns2:subject', value: addressee_data[:addressee_type]) # Nepovinne: Typ adresata
197
+ add_element_to(do_parcel_address, 'ns2:ic', value: addressee_data[:ic]) # Nepovinne: ICO
198
+ add_element_to(do_parcel_address, 'ns2:dic', value: addressee_data[:dic]) # Nepovinne: DIC
199
+ add_element_to(do_parcel_address, 'ns2:specification', value: addressee_data[:addressee_specification]) # Nepovinne: Specifikace napr. datum narozeni
200
+
201
+ add_bank_elements(do_parcel_address, addressee_data[:bank_account]) # Nepovinne. Kod banky, cislo a predcisli uctu
202
+ add_contact_elements(do_parcel_address, addressee_data) # Nepovinne. Telefon, Mobil a Email
203
+
204
+ add_element_to(do_parcel_address, 'ns2:custCardNum', value: addressee_data[:custom_card_number]) # Nepovinne: cislo zakaznicke karty
205
+
206
+ (addressee_data[:advice_informations] || []).each_with_index do |adv_info, index|
207
+ add_element_to(do_parcel_address, 'ns2:adviceInformation' + (index + 1).to_s, value: adv_info) # Nepovinne: Informace 1- 6 k dodejce
208
+ end
209
+
210
+ add_element_to(do_parcel_address, 'ns2:adviceNote', value: addressee_data[:advice_note]) # Nepovinne: Poznamka k dodejce
211
+ end
212
+ end
213
+
214
+ def do_parcel_customs_declaration
215
+ declaration_data = parcel[:custom_declaration]
216
+ return nil if declaration_data.nil?
217
+
218
+ new_element('ns2:doPOLParcelCustomsDeclaration').tap do |do_p_customs_declaration|
219
+ add_element_to(do_p_customs_declaration, 'ns2:category', value: declaration_data[:category]) # Kategorie zasilky
220
+ add_element_to(do_p_customs_declaration, 'ns2:note', value: declaration_data[:note]) # Nepovinne: Poznamka
221
+ add_element_to(do_p_customs_declaration, 'ns2:customValCur', value: declaration_data[:value_currency_iso_code]) # ISO kod meny celni hodnoty
222
+ add_element_to(do_p_customs_declaration, 'ns2:importerRefNum', value: declaration_data[:importer_reference_number]) # Nepovinne: Cislo dovozce
223
+
224
+ (declaration_data[:content_descriptions] || []).each do |dsc|
225
+ do_p_customs_declaration << custom_goods_for(dsc)
226
+ end
227
+ end
228
+ end
229
+
230
+ def add_customs_documents_to(parent_element)
231
+ (parcel[:customs_documents] || []).each do |doc_data| # 0-3 documents
232
+ doc_element = new_element('ns2:doPOLParcelCustomsDocument').tap do |do_p_customs_document| # VVD dokument
233
+ add_element_to(do_p_customs_document, 'ns2:recordID', value: doc_data[:record_id]) # ID Záznamu
234
+ add_element_to(do_p_customs_document, 'ns2:code', value: doc_data[:code]) # Typ
235
+ add_element_to(do_p_customs_document, 'ns2:name', value: doc_data[:name]) # Název
236
+ add_element_to(do_p_customs_document, 'ns2:id', value: doc_data[:id]) # Id
237
+ end
238
+
239
+ add_element_to(parent_element, doc_element)
240
+ end
241
+ end
242
+
243
+ def custom_goods_for(description_data)
244
+ new_element('ns2:doPOLParcelCustomsGoods').tap do |do_p_customs_goods|
245
+ add_element_to(do_p_customs_goods, 'ns2:sequence', value: description_data[:order]) # Nepovinne: Poradi
246
+ add_element_to(do_p_customs_goods, 'ns2:customCont', value: description_data[:description]) # Nepovinne: Popis zbozi
247
+ add_element_to(do_p_customs_goods, 'ns2:quantity', value: description_data[:quantity]) # Nepovinne: Mnozstvi
248
+ add_element_to(do_p_customs_goods, 'ns2:weight', value: description_data[:weight_in_kg]) # Nepovinne: Hmotnost
249
+ add_element_to(do_p_customs_goods, 'ns2:customVal', value: description_data[:value]) # Nepovinne: Celni hodnota
250
+ add_element_to(do_p_customs_goods, 'ns2:hsCode', value: description_data[:hs_code]) # Nepovinne: HS kod
251
+ add_element_to(do_p_customs_goods, 'ns2:iso', value: description_data[:origin_country_iso_code]) # Nepovinne: Zeme puvodu zbozi
252
+ end
253
+ end
254
+
255
+ # Nepovinne. Adresa
256
+ def add_address_elements(parent_element, address_data, without: [])
257
+ return if address_data.nil?
258
+
259
+ address_tags_and_values(address_data).each_pair do |xml_tag, value|
260
+ unless without.include?(xml_tag)
261
+ add_element_to(parent_element, xml_tag, value: value) unless value.nil?
262
+ end
263
+ end
264
+ end
265
+
266
+ def address_tags_and_values(address_data)
267
+ {
268
+ 'ns2:firstName' => address_data[:first_name], # Nepovinne: Jmeno
269
+ 'ns2:surname' => address_data[:last_name], # Nepovinne: Prijmeni
270
+ 'ns2:companyName' => address_data[:company_name], # Nepovinne: Nazev spolecnosti
271
+ 'ns2:aditionAddress' => address_data[:addition_to_name], # Nepovinne: Doplnujici iformace k nazvu podavatele
272
+ 'ns2:street' => address_data[:street], # Nepovinne: Ulice
273
+ 'ns2:houseNumber' => address_data[:house_number], # Nepovinne: Cislo popisne
274
+ 'ns2:sequenceNumber' => address_data[:sequence_number], # Nepovinne: Cislo orientacni
275
+ 'ns2:partCity' => address_data[:city_part], # Nepovinne: Cast obce
276
+ 'ns2:city' => address_data[:city], # Nepovinne: Obec
277
+ 'ns2:zipCode' => address_data[:post_code], # Nepovinne: PSC
278
+ 'ns2:isoCountry' => address_data[:country_iso_code], # Nepovinne, default 'CZ': ISO kod zeme
279
+ 'ns2:subIsoCountry' => address_data[:subcountry_iso_code] # Nepovinne: ISO kod uzemi
280
+ }
281
+ end
282
+
283
+ def add_bank_elements(parent_element, bank_account)
284
+ return if bank_account.to_s == ''
285
+
286
+ if (m = bank_account.match(%r{(?:(\d+)-)?(\d+)\/(\d+)}))
287
+ prefix = m[1]
288
+ account = m[2]
289
+ bank = m[3]
290
+ else
291
+ prefix, account, bank = nil
292
+ end
293
+
294
+ add_element_to(parent_element, 'ns2:prefixAccount', value: prefix) # Nepovinne: Predcisli k uctu
295
+ add_element_to(parent_element, 'ns2:account', value: account) # Nepovinne: cislo uctu
296
+ add_element_to(parent_element, 'ns2:bank', value: bank) # Nepovinne: kod banky
297
+ end
298
+
299
+ def add_contact_elements(parent_element, data_hash)
300
+ add_element_to(parent_element, 'ns2:mobileNumber', value: data_hash[:mobile_phone]) # Nepovinne: Mobil
301
+ add_element_to(parent_element, 'ns2:phoneNumber', value: data_hash[:phone]) # Nepovinne: Telefon
302
+ add_element_to(parent_element, 'ns2:emailAddress', value: data_hash[:email]) # Nepovinne: Email
303
+ end
304
+
305
+ def sender_data
306
+ common_data[:sender]
307
+ end
308
+ end
309
+ end
310
+ end
311
+
312
+ # rubocop:enable Layout/LineLength, Style/AsciiComments
@@ -6,3 +6,4 @@ require 'czech_post_b2b_client/response_parsers/get_parcels_printing_parser'
6
6
  require 'czech_post_b2b_client/response_parsers/get_parcel_state_parser'
7
7
  require 'czech_post_b2b_client/response_parsers/get_result_parcels_parser'
8
8
  require 'czech_post_b2b_client/response_parsers/send_parcels_parser'
9
+ require 'czech_post_b2b_client/response_parsers/parcel_service_sync_parser'
@@ -37,7 +37,7 @@ module CzechPostB2bClient
37
37
  request: { created_at: request_data.time_stamp,
38
38
  contract_id: request_data.id_contract,
39
39
  request_id: request_data.id_ext_transaction },
40
- response: { created_at: Time.parse(response_header.dig('timeStamp')) }
40
+ response: { created_at: response_time }
41
41
  }
42
42
  end
43
43
 
@@ -69,6 +69,12 @@ module CzechPostB2bClient
69
69
  id_contract: b2b_request_hash.dig('idContract').to_s)
70
70
  end
71
71
 
72
+ def response_time
73
+ Time.parse(response_header.dig('timeStamp'))
74
+ rescue TypeError
75
+ Time.now.utc
76
+ end
77
+
72
78
  def state_hash_from(hash)
73
79
  state_hash = hash || { 'responseCode' => '999', 'responseText' => 'Unknown' }
74
80
  state_hash = state_hash.first if state_hash.is_a?(Array) # more <doParcelStateResponse> elements
@@ -42,11 +42,12 @@ module CzechPostB2bClient
42
42
 
43
43
  return pd_hash if value.nil?
44
44
 
45
- # more doParcelParamsResult nodes for one parcel_id => probably errors
45
+ # merging states
46
+ value[:states] = (value[:states] + pd_hash[:states]).sort { |a, b| a[:code] <=> b[:code] }
47
+
48
+ # more parcel_codes for one parcel_id => probably errors
46
49
  old_p_code = value[:parcel_code]
47
50
  new_p_code = pd_hash[:parcel_code]
48
-
49
- value[:states] = (value[:states] + pd_hash[:states]).sort { |a, b| a[:code] <=> b[:code] }
50
51
  if old_p_code != new_p_code
51
52
  raise "Two different parcel_codes [#{old_p_code}, #{new_p_code}] for parcel_id:'#{parcel_id}'"
52
53
  end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'base64'
4
+
5
+ module CzechPostB2bClient
6
+ module ResponseParsers
7
+ class ParcelServiceSyncParser < BaseParser
8
+ def build_result
9
+ super
10
+ @result[:response][:state] = state_hash_from(response_state_response)
11
+ @result[:parcel] = parcel_data_hash
12
+ end
13
+
14
+ def parcel_data_hash
15
+ parcel_id = nil
16
+ pdh = response_parcel_hashes.each_with_object({}) do |rp_hash, result|
17
+ parcel_id = parcel_parcel_id_from(rp_hash)
18
+ result[parcel_id] = updated_result_value_for(result[parcel_id], rp_hash)
19
+ end
20
+ pdh[parcel_id].merge!(print: print_data_from(response_print_hash))
21
+
22
+ pdh
23
+ end
24
+
25
+ def response_root_node_name
26
+ 'parcelServiceSyncResponse'
27
+ end
28
+
29
+ def response_state_response
30
+ response_root_node.dig('responseHeader', 'resultHeader')
31
+ end
32
+
33
+ def response_parcel_hashes
34
+ [response_root_node.dig('responseHeader', 'resultParcelData')].flatten.compact # to always get array of hash(es)
35
+ end
36
+
37
+ def response_print_hash
38
+ response_root_node.dig('responsePrintParams')
39
+ end
40
+
41
+ def parcel_parcel_id_from(rp_hash)
42
+ rp_hash['recordNumber'].to_s
43
+ end
44
+
45
+ def parcel_data_from(rp_hash)
46
+ { parcel_code: rp_hash['parcelCode'],
47
+ states: [state_hash_from(rp_hash.dig('parcelDataResponse'))] }
48
+ end
49
+
50
+ def print_data_from(print_hash)
51
+ return nil if print_hash.nil? || print_hash.empty?
52
+
53
+ { pdf_content: pdf_content_from(print_hash.dig('file')),
54
+ state: state_hash_from(print_hash.dig('printParamsResponse')) }
55
+ end
56
+
57
+ def pdf_content_from(pdf_content_encoded)
58
+ return nil if pdf_content_encoded.nil?
59
+
60
+ ::Base64.decode64(pdf_content_encoded)
61
+ end
62
+
63
+ def updated_result_value_for(value, parcel_params_result_hash)
64
+ pd_hash = parcel_data_from(parcel_params_result_hash)
65
+
66
+ return pd_hash if value.nil?
67
+
68
+ # merging states
69
+ value[:states] = (value[:states] + pd_hash[:states]).sort { |a, b| a[:code] <=> b[:code] }
70
+
71
+ # more parcel_codes for one parcel_id => probably errors
72
+ old_p_code = value[:parcel_code]
73
+ new_p_code = pd_hash[:parcel_code]
74
+ if old_p_code != new_p_code
75
+ raise "Two different parcel_codes [#{old_p_code}, #{new_p_code}] for parcel_id:'#{parcel_id}'"
76
+ end
77
+
78
+ value
79
+ end
80
+ end
81
+ end
82
+ end
@@ -3,8 +3,9 @@
3
3
  require 'czech_post_b2b_client/services/orchestrator'
4
4
  require 'czech_post_b2b_client/services/communicator'
5
5
  require 'czech_post_b2b_client/services/api_caller'
6
- require 'czech_post_b2b_client/services/parcels_sender'
7
- require 'czech_post_b2b_client/services/parcels_immediate_sender'
6
+ require 'czech_post_b2b_client/services/parcels_async_sender'
7
+ require 'czech_post_b2b_client/services/parcels_sync_sender'
8
+ require 'czech_post_b2b_client/services/parcels_sender' # deprecated
8
9
  require 'czech_post_b2b_client/services/parcels_send_process_updater'
9
10
  require 'czech_post_b2b_client/services/address_sheets_generator'
10
11
  require 'czech_post_b2b_client/services/parcels_submission_closer'
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CzechPostB2bClient
4
+ module Services
5
+ class ParcelsAsyncSender < CzechPostB2bClient::Services::Communicator
6
+ attr_reader :sending_data, :parcels
7
+
8
+ def initialize(sending_data:, parcels:)
9
+ @sending_data = sending_data
10
+ @parcels = parcels
11
+ end
12
+
13
+ private
14
+
15
+ def request_builder_args
16
+ { common_data: common_data, parcels: parcels }
17
+ end
18
+
19
+ def request_builder_class
20
+ CzechPostB2bClient::RequestBuilders::SendParcelsBuilder
21
+ end
22
+
23
+ def api_caller_class
24
+ CzechPostB2bClient::Services::ApiCaller
25
+ end
26
+
27
+ def response_parser_class
28
+ CzechPostB2bClient::ResponseParsers::SendParcelsParser
29
+ end
30
+
31
+ def common_data
32
+ data_from_config.merge(sending_data)
33
+ end
34
+
35
+ def data_from_config
36
+ {
37
+ contract_id: configuration.contract_id,
38
+ customer_id: configuration.customer_id,
39
+ sending_post_office_code: configuration.sending_post_office_code
40
+ }
41
+ end
42
+
43
+ def endpoint_path
44
+ '/sendParcels'
45
+ end
46
+
47
+ def build_result_from(response_hash)
48
+ OpenStruct.new(transaction_id: response_hash.dig(:async_result, :transaction_id),
49
+ processing_end_expected_at: response_hash.dig(:async_result, :processing_end_expected_at))
50
+ end
51
+ end
52
+ end
53
+ end
@@ -2,51 +2,10 @@
2
2
 
3
3
  module CzechPostB2bClient
4
4
  module Services
5
- class ParcelsSender < CzechPostB2bClient::Services::Communicator
6
- attr_reader :sending_data, :parcels
7
-
8
- def initialize(sending_data:, parcels:)
9
- @sending_data = sending_data
10
- @parcels = parcels
11
- end
12
-
13
- private
14
-
15
- def request_builder_args
16
- { common_data: common_data, parcels: parcels }
17
- end
18
-
19
- def request_builder_class
20
- CzechPostB2bClient::RequestBuilders::SendParcelsBuilder
21
- end
22
-
23
- def api_caller_class
24
- CzechPostB2bClient::Services::ApiCaller
25
- end
26
-
27
- def response_parser_class
28
- CzechPostB2bClient::ResponseParsers::SendParcelsParser
29
- end
30
-
31
- def common_data
32
- data_from_config.merge(sending_data)
33
- end
34
-
35
- def data_from_config
36
- {
37
- contract_id: configuration.contract_id,
38
- customer_id: configuration.customer_id,
39
- sending_post_office_code: configuration.sending_post_office_code
40
- }
41
- end
42
-
43
- def endpoint_path
44
- '/sendParcels'
45
- end
46
-
47
- def build_result_from(response_hash)
48
- OpenStruct.new(transaction_id: response_hash.dig(:async_result, :transaction_id),
49
- processing_end_expected_at: response_hash.dig(:async_result, :processing_end_expected_at))
5
+ class ParcelsSender < CzechPostB2bClient::Services::ParcelsAsyncSender
6
+ class << self
7
+ extend Gem::Deprecate
8
+ deprecate :call, 'CzechPostB2bClient::Services::ParcelsAsyncSender.call', 2020, 8
50
9
  end
51
10
  end
52
11
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module CzechPostB2bClient
4
4
  module Services
5
- class ParcelsSubmissionCloser < CzechPostB2bClient::Services::ParcelsSender
5
+ class ParcelsSubmissionCloser < CzechPostB2bClient::Services::ParcelsAsyncSender
6
6
  attr_reader :sending_data
7
7
 
8
8
  def initialize(sending_data:)
@@ -2,10 +2,10 @@
2
2
 
3
3
  module CzechPostB2bClient
4
4
  module Services
5
- # Combination of ParcelsSender + ParcelsSendProcessUpdater for fast SYNC registering parcel at CPOST
6
- # It accept all parcels or none!
5
+ # Combination of ParcelsAsyncSender + ParcelsSendProcessUpdater for fast SYNC registering parcel at CPOST
6
+ # It accept only one parcel!
7
7
  # It should be used for instant one parcel registration.
8
- class ParcelsImmediateSender < CzechPostB2bClient::Services::Communicator
8
+ class ParcelsSyncSender < CzechPostB2bClient::Services::Communicator
9
9
  attr_reader :sending_data, :parcels
10
10
 
11
11
  def initialize(sending_data:, parcels:)
@@ -20,11 +20,11 @@ module CzechPostB2bClient
20
20
  private
21
21
 
22
22
  def request_builder_args
23
- { common_data: common_data, parcels: parcels }
23
+ { common_data: common_data, parcel: parcels.first }
24
24
  end
25
25
 
26
26
  def request_builder_class
27
- CzechPostB2bClient::RequestBuilders::SendParcelsBuilder
27
+ CzechPostB2bClient::RequestBuilders::ParcelServiceSyncBuilder
28
28
  end
29
29
 
30
30
  def api_caller_class
@@ -32,7 +32,7 @@ module CzechPostB2bClient
32
32
  end
33
33
 
34
34
  def response_parser_class
35
- CzechPostB2bClient::ResponseParsers::GetResultParcelsParser
35
+ CzechPostB2bClient::ResponseParsers::ParcelServiceSyncParser
36
36
  end
37
37
 
38
38
  def common_data
@@ -48,11 +48,11 @@ module CzechPostB2bClient
48
48
  end
49
49
 
50
50
  def endpoint_path
51
- '/sendParcelsSync'
51
+ '/parcelServiceSync'
52
52
  end
53
53
 
54
54
  def build_result_from(response_hash)
55
- OpenStruct.new(parcels_hash: response_hash[:parcels],
55
+ OpenStruct.new(parcels_hash: response_hash[:parcel],
56
56
  state_text: response_hash.dig(:response, :state, :text),
57
57
  state_code: response_hash.dig(:response, :state, :code))
58
58
  end
@@ -48,6 +48,8 @@ module CzechPostB2bClient
48
48
 
49
49
  def save_response_to_file
50
50
  filename = xsd_uri.request_uri.split('/').last
51
+ filename += '.xsd' if filename.split('.').last.downcase != 'xsd'
52
+
51
53
  File.write(filename, response.body)
52
54
  end
53
55
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CzechPostB2bClient
4
- VERSION = '1.0.3'
4
+ VERSION = '1.1.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: czech_post_b2b_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Petr Mlčoch
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-05-20 00:00:00.000000000 Z
11
+ date: 2020-05-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ox
@@ -516,6 +516,7 @@ files:
516
516
  - lib/czech_post_b2b_client/request_builders/get_parcels_printing_builder.rb
517
517
  - lib/czech_post_b2b_client/request_builders/get_result_parcels_builder.rb
518
518
  - lib/czech_post_b2b_client/request_builders/get_stats_builder.rb
519
+ - lib/czech_post_b2b_client/request_builders/parcel_service_sync_builder.rb
519
520
  - lib/czech_post_b2b_client/request_builders/send_parcels_builder.rb
520
521
  - lib/czech_post_b2b_client/response_codes.rb
521
522
  - lib/czech_post_b2b_client/response_parsers.rb
@@ -524,6 +525,7 @@ files:
524
525
  - lib/czech_post_b2b_client/response_parsers/get_parcels_printing_parser.rb
525
526
  - lib/czech_post_b2b_client/response_parsers/get_result_parcels_parser.rb
526
527
  - lib/czech_post_b2b_client/response_parsers/get_stats_parser.rb
528
+ - lib/czech_post_b2b_client/response_parsers/parcel_service_sync_parser.rb
527
529
  - lib/czech_post_b2b_client/response_parsers/send_parcels_parser.rb
528
530
  - lib/czech_post_b2b_client/services.rb
529
531
  - lib/czech_post_b2b_client/services/address_sheets_generator.rb
@@ -531,10 +533,11 @@ files:
531
533
  - lib/czech_post_b2b_client/services/communicator.rb
532
534
  - lib/czech_post_b2b_client/services/delivering_inspector.rb
533
535
  - lib/czech_post_b2b_client/services/orchestrator.rb
534
- - lib/czech_post_b2b_client/services/parcels_immediate_sender.rb
536
+ - lib/czech_post_b2b_client/services/parcels_async_sender.rb
535
537
  - lib/czech_post_b2b_client/services/parcels_send_process_updater.rb
536
538
  - lib/czech_post_b2b_client/services/parcels_sender.rb
537
539
  - lib/czech_post_b2b_client/services/parcels_submission_closer.rb
540
+ - lib/czech_post_b2b_client/services/parcels_sync_sender.rb
538
541
  - lib/czech_post_b2b_client/services/time_period_statisticator.rb
539
542
  - lib/czech_post_b2b_client/services/xsds_downloader.rb
540
543
  - lib/czech_post_b2b_client/version.rb