deliveries 0.1.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.
Files changed (81) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/main.yml +19 -0
  3. data/.gitignore +12 -0
  4. data/.rspec +3 -0
  5. data/.rubocop.yml +34 -0
  6. data/CHANGELOG.md +13 -0
  7. data/Gemfile +12 -0
  8. data/Gemfile.lock +127 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.md +207 -0
  11. data/Rakefile +12 -0
  12. data/bin/console +15 -0
  13. data/bin/setup +8 -0
  14. data/deliveries.gemspec +36 -0
  15. data/lib/deliveries/address.rb +71 -0
  16. data/lib/deliveries/checkpoint.rb +12 -0
  17. data/lib/deliveries/collection_point.rb +45 -0
  18. data/lib/deliveries/courier.rb +69 -0
  19. data/lib/deliveries/couriers/correos_express/address.rb +31 -0
  20. data/lib/deliveries/couriers/correos_express/collection_points/search/format_response.rb +82 -0
  21. data/lib/deliveries/couriers/correos_express/collection_points/search.rb +56 -0
  22. data/lib/deliveries/couriers/correos_express/labels/generate.rb +68 -0
  23. data/lib/deliveries/couriers/correos_express/pickups/create/defaults.rb +60 -0
  24. data/lib/deliveries/couriers/correos_express/pickups/create/format_params.rb +95 -0
  25. data/lib/deliveries/couriers/correos_express/pickups/create.rb +66 -0
  26. data/lib/deliveries/couriers/correos_express/pickups/cutoff_time/format_params.rb +40 -0
  27. data/lib/deliveries/couriers/correos_express/pickups/cutoff_time.rb +61 -0
  28. data/lib/deliveries/couriers/correos_express/pickups/trace/correos.test.wsdl +163 -0
  29. data/lib/deliveries/couriers/correos_express/pickups/trace/correos.wsdl +163 -0
  30. data/lib/deliveries/couriers/correos_express/pickups/trace/format_response.rb +71 -0
  31. data/lib/deliveries/couriers/correos_express/pickups/trace.rb +49 -0
  32. data/lib/deliveries/couriers/correos_express/shipments/create/defaults.rb +80 -0
  33. data/lib/deliveries/couriers/correos_express/shipments/create/format_params.rb +99 -0
  34. data/lib/deliveries/couriers/correos_express/shipments/create.rb +101 -0
  35. data/lib/deliveries/couriers/correos_express/shipments/trace/format_response.rb +67 -0
  36. data/lib/deliveries/couriers/correos_express/shipments/trace.rb +65 -0
  37. data/lib/deliveries/couriers/correos_express.rb +162 -0
  38. data/lib/deliveries/couriers/dummy.rb +106 -0
  39. data/lib/deliveries/couriers/mondial_relay/address.rb +31 -0
  40. data/lib/deliveries/couriers/mondial_relay/collection_points/search/format_response.rb +103 -0
  41. data/lib/deliveries/couriers/mondial_relay/labels/generate.rb +40 -0
  42. data/lib/deliveries/couriers/mondial_relay/pickups/create/format_params.rb +57 -0
  43. data/lib/deliveries/couriers/mondial_relay/shipments/create/defaults.rb +96 -0
  44. data/lib/deliveries/couriers/mondial_relay/shipments/create/format_params.rb +68 -0
  45. data/lib/deliveries/couriers/mondial_relay/shipments/create.rb +36 -0
  46. data/lib/deliveries/couriers/mondial_relay/shipments/trace/format_response.rb +94 -0
  47. data/lib/deliveries/couriers/mondial_relay/shipments/trace.rb +47 -0
  48. data/lib/deliveries/couriers/mondial_relay/status_codes.rb +105 -0
  49. data/lib/deliveries/couriers/mondial_relay.rb +189 -0
  50. data/lib/deliveries/couriers/mondial_relay_dual/address.rb +31 -0
  51. data/lib/deliveries/couriers/mondial_relay_dual/pickups/create/format_params.rb +39 -0
  52. data/lib/deliveries/couriers/mondial_relay_dual/shipments/create/format_params.rb +101 -0
  53. data/lib/deliveries/couriers/mondial_relay_dual/shipments/create.rb +133 -0
  54. data/lib/deliveries/couriers/mondial_relay_dual.rb +105 -0
  55. data/lib/deliveries/couriers/spring/address.rb +23 -0
  56. data/lib/deliveries/couriers/spring/labels/generate.rb +33 -0
  57. data/lib/deliveries/couriers/spring/request.rb +43 -0
  58. data/lib/deliveries/couriers/spring/shipments/create/defaults.rb +73 -0
  59. data/lib/deliveries/couriers/spring/shipments/create/format_params.rb +77 -0
  60. data/lib/deliveries/couriers/spring/shipments/create.rb +45 -0
  61. data/lib/deliveries/couriers/spring/shipments/trace/format_response.rb +79 -0
  62. data/lib/deliveries/couriers/spring/shipments/trace.rb +29 -0
  63. data/lib/deliveries/couriers/spring.rb +84 -0
  64. data/lib/deliveries/couriers/ups/collection_points/search.rb +142 -0
  65. data/lib/deliveries/couriers/ups/json_request.rb +40 -0
  66. data/lib/deliveries/couriers/ups/labels/generate.rb +72 -0
  67. data/lib/deliveries/couriers/ups/shipments/create.rb +210 -0
  68. data/lib/deliveries/couriers/ups/shipments/trace.rb +79 -0
  69. data/lib/deliveries/couriers/ups.rb +122 -0
  70. data/lib/deliveries/couriers.rb +14 -0
  71. data/lib/deliveries/delivery.rb +20 -0
  72. data/lib/deliveries/errors.rb +22 -0
  73. data/lib/deliveries/label.rb +20 -0
  74. data/lib/deliveries/label_utils.rb +67 -0
  75. data/lib/deliveries/labels.rb +40 -0
  76. data/lib/deliveries/pickup.rb +15 -0
  77. data/lib/deliveries/shipment.rb +15 -0
  78. data/lib/deliveries/tracking_info.rb +29 -0
  79. data/lib/deliveries/version.rb +5 -0
  80. data/lib/deliveries.rb +63 -0
  81. metadata +240 -0
@@ -0,0 +1,189 @@
1
+ require_relative 'mondial_relay/collection_points/search/format_response'
2
+ require_relative 'mondial_relay/shipments/create'
3
+ require_relative 'mondial_relay/shipments/create/defaults'
4
+ require_relative 'mondial_relay/shipments/create/format_params'
5
+ require_relative 'mondial_relay/shipments/trace'
6
+ require_relative 'mondial_relay/shipments/trace/format_response'
7
+ require_relative 'mondial_relay/pickups/create/format_params'
8
+ require_relative 'mondial_relay/labels/generate'
9
+ require_relative 'mondial_relay/status_codes'
10
+ require_relative 'mondial_relay/address'
11
+ require 'savon'
12
+
13
+ module Deliveries
14
+ module Couriers
15
+ module MondialRelay
16
+ extend Courier
17
+
18
+ Config = Struct.new(
19
+ :mondial_relay_merchant,
20
+ :mondial_relay_key
21
+ )
22
+
23
+ WSDL_ENDPOINT = 'http://api.mondialrelay.com/Web_Services.asmx?WSDL'.freeze
24
+
25
+ module_function
26
+
27
+ def api_client
28
+ Savon.client wsdl: WSDL_ENDPOINT,
29
+ logger: Deliveries.logger,
30
+ log: Deliveries.debug
31
+ end
32
+
33
+ def get_collection_points(country:, postcode:)
34
+ # Build params needed by web service.
35
+ params = { 'Enseigne' => Deliveries::Couriers::MondialRelay.config(:mondial_relay_merchant),
36
+ 'Pays' => country, 'NumPointRelais' => '', 'Ville' => '',
37
+ 'CP' => postcode, 'Latitude' => '', 'Longitude' => '',
38
+ 'Taille' => '', 'Poids' => '', 'Action' => '',
39
+ 'DelaiEnvoi' => '0', 'RayonRecherche' => '', 'TypeActivite' => '', 'NACE' => '' }
40
+ # Calculate security parameters.
41
+ params['Security'] = calculate_security_param params
42
+
43
+ response = api_client.call :wsi3_point_relais_recherche, message: params
44
+ # If response returns OK stat code.
45
+ if (response_result = response.body[:wsi3_point_relais_recherche_response][:wsi3_point_relais_recherche_result]) &&
46
+ response_result[:stat] == '0'
47
+
48
+ collection_points = []
49
+ [response_result.dig(:points_relais, :point_relais_details)].flatten.compact.each do |point_params|
50
+ collection_point_params = CollectionPoints::Search::FormatResponse.new(response: point_params).execute
51
+ collection_points << Deliveries::CollectionPoint.new(collection_point_params)
52
+ end
53
+
54
+ collection_points
55
+ else
56
+ raise Deliveries::APIError.new(
57
+ StatusCodes.message_for(response_result[:stat].to_i),
58
+ response_result[:stat]
59
+ )
60
+ end
61
+ end
62
+
63
+ def get_collection_point(global_point_id:)
64
+ global_point = Deliveries::CollectionPoint.parse_global_point_id(global_point_id: global_point_id)
65
+
66
+ params = { 'Enseigne' => Deliveries::Couriers::MondialRelay.config(:mondial_relay_merchant),
67
+ 'Pays' => global_point.country, 'NumPointRelais' => global_point.point_id, 'Ville' => '',
68
+ 'CP' => '', 'Latitude' => '', 'Longitude' => '',
69
+ 'Taille' => '', 'Poids' => '', 'Action' => '',
70
+ 'DelaiEnvoi' => '0', 'RayonRecherche' => '', 'TypeActivite' => '', 'NACE' => '' }
71
+
72
+ # Calculate security parameters.
73
+ params['Security'] = calculate_security_param params
74
+
75
+ response = api_client.call :wsi3_point_relais_recherche, message: params
76
+
77
+ response_result = response.body.dig(:wsi3_point_relais_recherche_response,
78
+ :wsi3_point_relais_recherche_result)
79
+
80
+ point_relais_details = response_result.dig(:points_relais, :point_relais_details)
81
+
82
+ if response_result[:stat] == '0' && point_relais_details.present?
83
+ collection_point_params = CollectionPoints::Search::FormatResponse.new(response: point_relais_details).execute
84
+ Deliveries::CollectionPoint.new(collection_point_params)
85
+ else
86
+ raise Deliveries::APIError.new(
87
+ StatusCodes.message_for(response_result[:stat].to_i),
88
+ response_result[:stat]
89
+ )
90
+ end
91
+ end
92
+
93
+ def create_shipment(sender:, receiver:, parcels:, reference_code:, collection_point: nil, shipment_date: nil, remarks: nil, language: 'FR')
94
+ params = Shipments::Create::FormatParams.new(
95
+ sender: sender.courierize(:mondial_relay),
96
+ receiver: receiver.courierize(:mondial_relay),
97
+ parcels: parcels,
98
+ collection_point: collection_point,
99
+ reference_code: reference_code,
100
+ remarks: remarks,
101
+ language: language
102
+ ).execute
103
+
104
+ tracking_code, label_url = Shipments::Create.new(
105
+ params: params
106
+ ).execute.values_at(:tracking_code, :label_url)
107
+
108
+ Deliveries::Shipment.new(
109
+ courier_id: 'mondial_relay',
110
+ sender: sender,
111
+ receiver: receiver,
112
+ parcels: parcels,
113
+ reference_code: reference_code,
114
+ tracking_code: tracking_code,
115
+ shipment_date: shipment_date,
116
+ label: Label.new(url: label_url)
117
+ )
118
+ end
119
+
120
+ def create_pickup(sender:, receiver:, parcels:, reference_code:,
121
+ pickup_date: nil, remarks: nil, language: 'FR')
122
+ params = Pickups::Create::FormatParams.new(
123
+ sender: sender.courierize(:mondial_relay),
124
+ receiver: receiver.courierize(:mondial_relay),
125
+ parcels: parcels,
126
+ reference_code: reference_code,
127
+ pickup_date: pickup_date,
128
+ remarks: remarks,
129
+ language: language
130
+ ).execute
131
+
132
+ tracking_code, label_url = Shipments::Create.new(
133
+ params: params
134
+ ).execute.values_at(:tracking_code, :label_url)
135
+
136
+ Deliveries::Pickup.new(
137
+ courier_id: 'mondial_relay',
138
+ sender: sender,
139
+ receiver: receiver,
140
+ parcels: parcels,
141
+ reference_code: reference_code,
142
+ tracking_code: tracking_code,
143
+ pickup_date: pickup_date,
144
+ label: Label.new(url: label_url)
145
+ )
146
+ end
147
+
148
+ def shipment_info(tracking_code:, language: 'FR')
149
+ response = Shipments::Trace.new(
150
+ tracking_code: tracking_code,
151
+ language: language
152
+ ).execute
153
+
154
+ tracking_info_params = Shipments::Trace::FormatResponse.new(response: response).execute
155
+
156
+ tracking_info_params = tracking_info_params.merge(tracking_code: tracking_code)
157
+ Deliveries::TrackingInfo.new(tracking_info_params)
158
+ end
159
+
160
+ def pickup_info(tracking_code:, language: 'FR')
161
+ shipment_info(tracking_code: tracking_code, language: language)
162
+ end
163
+
164
+ def get_label(tracking_code:, language: 'FR')
165
+ label_url = Labels::Generate.new(
166
+ tracking_codes: tracking_code,
167
+ language: language
168
+ ).execute
169
+
170
+ Deliveries::Label.new(url: label_url)
171
+ end
172
+
173
+ def get_labels(tracking_codes:, language: 'FR')
174
+ labels_url = Labels::Generate.new(
175
+ tracking_codes: tracking_codes,
176
+ language: language
177
+ ).execute
178
+
179
+ Deliveries::Labels.new(url: labels_url)
180
+ end
181
+
182
+ def calculate_security_param(params)
183
+ Digest::MD5.hexdigest(params.map do |_, v|
184
+ v
185
+ end.join + Deliveries::Couriers::MondialRelay.config(:mondial_relay_key)).upcase
186
+ end
187
+ end
188
+ end
189
+ end
@@ -0,0 +1,31 @@
1
+ module Deliveries
2
+ module Couriers
3
+ module MondialRelayDual
4
+ class Address < Deliveries::Address
5
+ def name
6
+ I18n.transliterate(@name.to_s).gsub(%r{[^0-9A-Z_\-'., /]}i, '').upcase.truncate(30, omission: '')
7
+ end
8
+
9
+ def street
10
+ I18n.transliterate(@street.to_s).gsub(%r{[^0-9A-Z_\-'., /]}i, '').upcase.truncate(30, omission: '')
11
+ end
12
+
13
+ def city
14
+ I18n.transliterate(@city.to_s).gsub(/[^A-Z_\-' ]/i, '').upcase.truncate(30, omission: '')
15
+ end
16
+
17
+ def country
18
+ @country.to_s.upcase
19
+ end
20
+
21
+ def phone
22
+ format_international_phone
23
+ end
24
+
25
+ def email
26
+ format_email
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,39 @@
1
+ module Deliveries
2
+ module Couriers
3
+ module MondialRelayDual
4
+ module Pickups
5
+ class Create
6
+ class FormatParams < Shipments::Create::FormatParams
7
+ def initialize(sender:, receiver:, parcels:, reference_code:, remarks:, language:)
8
+ super(
9
+ sender: sender,
10
+ receiver: receiver,
11
+ parcels: parcels,
12
+ reference_code: reference_code,
13
+ remarks: remarks,
14
+ language: language,
15
+ collection_point: nil
16
+ )
17
+ end
18
+
19
+ private
20
+
21
+ def delivery_mode
22
+ {
23
+ mode: 'LCC',
24
+ location: ''
25
+ }
26
+ end
27
+
28
+ def collection_mode
29
+ {
30
+ mode: 'REL',
31
+ location: ''
32
+ }
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,101 @@
1
+ module Deliveries
2
+ module Couriers
3
+ module MondialRelayDual
4
+ module Shipments
5
+ class Create
6
+ class FormatParams
7
+ attr_accessor :sender, :receiver, :parcels, :reference_code, :collection_point, :remarks, :language
8
+
9
+ def initialize(sender:, receiver:, parcels:, reference_code:, collection_point:, remarks:, language:)
10
+ self.sender = sender.courierize(:mondial_relay_dual)
11
+ self.receiver = receiver.courierize(:mondial_relay_dual)
12
+ self.parcels = parcels
13
+ self.reference_code = reference_code
14
+ self.collection_point = collection_point
15
+ self.remarks = remarks
16
+ self.language = language
17
+ end
18
+
19
+ def execute
20
+ {
21
+ culture: culture,
22
+ order_no: reference_code,
23
+ parcel_count: parcels.to_i,
24
+ delivery_mode: delivery_mode,
25
+ collection_mode: collection_mode,
26
+ deliver_instruction: remarks,
27
+ parcels: parcel_list,
28
+ sender: {
29
+ streetname: sender.street,
30
+ country_code: sender.country,
31
+ post_code: sender.postcode,
32
+ city: sender.city,
33
+ address_add_1: sender.name,
34
+ phone_no: sender.phone,
35
+ email: sender.email
36
+ },
37
+ recipient: {
38
+ streetname: receiver.street,
39
+ country_code: receiver.country,
40
+ post_code: receiver.postcode,
41
+ city: receiver.city,
42
+ address_add_1: receiver.name,
43
+ phone_no: receiver.phone,
44
+ email: receiver.email
45
+ }
46
+ }
47
+ end
48
+
49
+ private
50
+
51
+ def culture
52
+ case language.to_s.downcase
53
+ when 'es' then 'es-ES'
54
+ when 'de' then 'de-DE'
55
+ when 'en' then 'en-GB'
56
+ else 'fr-FR'
57
+ end
58
+ end
59
+
60
+ def delivery_mode
61
+ if collection_point
62
+ {
63
+ mode: '24R',
64
+ location: collection_point.point_id
65
+ }
66
+ else
67
+ home_delivery_mode = MondialRelayDual.config("countries.#{receiver.country.downcase}.home_delivery_mode") || 'HOM'
68
+ {
69
+ mode: home_delivery_mode,
70
+ location: ''
71
+ }
72
+ end
73
+ end
74
+
75
+ def collection_mode
76
+ {
77
+ mode: 'CCC',
78
+ location: ''
79
+ }
80
+ end
81
+
82
+ def parcel_list
83
+ list = []
84
+ parcels.times do
85
+ list << {
86
+ content: 'Vêtements',
87
+ weight: {
88
+ value: '1000',
89
+ unit: 'gr'
90
+ }
91
+ }
92
+ end
93
+
94
+ list
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,133 @@
1
+ require 'nokogiri'
2
+
3
+ module Deliveries
4
+ module Couriers
5
+ module MondialRelayDual
6
+ module Shipments
7
+ class Create
8
+ attr_accessor :params
9
+
10
+ def initialize(params:)
11
+ self.params = params
12
+ end
13
+
14
+ def execute
15
+ builder = Nokogiri::XML::Builder.new(encoding: 'utf-8') do |xml|
16
+ xml.ShipmentCreationRequest('xmlns:xsi0' => 'http://www.w3.org/2001/XMLSchema-instance',
17
+ 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema', 'xmlns' => 'http://www.example.org/Request') do
18
+ xml.Context do
19
+ xml.Login Deliveries::Couriers::MondialRelayDual.config(:dual_carrier_login)
20
+ xml.Password Deliveries::Couriers::MondialRelayDual.config(:dual_carrier_password)
21
+ xml.CustomerId Deliveries::Couriers::MondialRelayDual.config(:dual_carrier_customer_id)
22
+ xml.Culture params[:culture]
23
+ xml.VersionAPI '1.0'
24
+ end
25
+
26
+ xml.OutputOptions do
27
+ xml.OutputFormat '10x15'
28
+ xml.OutputType 'PdfUrl'
29
+ end
30
+
31
+ xml.ShipmentsList do
32
+ xml.Shipment do
33
+ xml.OrderNo params[:order_no]
34
+ xml.CustomerNo
35
+ xml.ParcelCount params[:parcel_count]
36
+ xml.DeliveryMode(Mode: params.dig(:delivery_mode, :mode),
37
+ Location: params.dig(:delivery_mode,
38
+ :location))
39
+ xml.CollectionMode(Mode: params.dig(:collection_mode, :mode),
40
+ Location: params.dig(:collection_mode,
41
+ :location))
42
+ xml.Parcels do
43
+ params[:parcels].each do |parcel|
44
+ xml.Parcel do
45
+ xml.Content parcel[:content]
46
+ xml.Weight(Value: parcel.dig(:weight, :value), Unit: parcel.dig(:weight, :unit))
47
+ end
48
+ end
49
+ end
50
+ xml.DeliveryInstruction params[:deliver_instruction]
51
+ xml.Sender do
52
+ xml.Address do
53
+ xml.Title
54
+ xml.Firstname
55
+ xml.Lastname
56
+ xml.Streetname params.dig(:sender, :streetname)
57
+ xml.HouseNo
58
+ xml.CountryCode params.dig(:sender, :country_code)
59
+ xml.PostCode params.dig(:sender, :post_code)
60
+ xml.City params.dig(:sender, :city)
61
+ xml.AddressAdd1 params.dig(:sender, :address_add_1)
62
+ xml.AddressAdd2
63
+ xml.AddressAdd3
64
+ xml.PhoneNo params.dig(:sender, :phone_no)
65
+ xml.MobileNo
66
+ xml.Email params.dig(:sender, :email)
67
+ end
68
+ end
69
+ xml.Recipient do
70
+ xml.Address do
71
+ xml.Title
72
+ xml.Firstname
73
+ xml.Lastname
74
+ xml.Streetname params.dig(:recipient, :streetname)
75
+ xml.HouseNo
76
+ xml.CountryCode params.dig(:recipient, :country_code)
77
+ xml.PostCode params.dig(:recipient, :post_code)
78
+ xml.City params.dig(:recipient, :city)
79
+ xml.AddressAdd1 params.dig(:recipient, :address_add_1)
80
+ xml.AddressAdd2
81
+ xml.AddressAdd3
82
+ xml.PhoneNo params.dig(:recipient, :phone_no)
83
+ xml.MobileNo
84
+ xml.Email params.dig(:recipient, :email)
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+ response = HTTParty.post(
93
+ api_endpoint,
94
+ body: builder.to_xml,
95
+ headers: { 'Content-Type': 'application/xml', Accept: 'application/xml' },
96
+ debug_output: Deliveries.debug ? Deliveries.logger : nil
97
+ )
98
+
99
+ xml_doc = Nokogiri::XML(response.body, &:strict)
100
+ xml_doc.remove_namespaces!
101
+
102
+ shipment_number = xml_doc.xpath('//ShipmentCreationResponse/ShipmentsList/Shipment/@ShipmentNumber').first&.content
103
+ pdf_url = xml_doc.xpath('//ShipmentCreationResponse/ShipmentsList/Shipment/LabelList/Label/Output').first&.content
104
+
105
+ unless shipment_number && pdf_url
106
+ error_node = xml_doc.xpath('//ShipmentCreationResponse/StatusList/Status').find do |n|
107
+ %w[Critical\ Error Error].include?(n[:Level])
108
+ end
109
+ raise Deliveries::APIError.new(error_node[:Message], error_node[:Code]) if error_node
110
+
111
+ raise Deliveries::ClientError, 'Cannot obtain error code from the API response'
112
+ end
113
+
114
+ {
115
+ tracking_code: shipment_number,
116
+ pdf_url: pdf_url
117
+ }
118
+ end
119
+
120
+ private
121
+
122
+ def api_endpoint
123
+ if MondialRelayDual.live?
124
+ MondialRelayDual::API_ENDPOINT_LIVE
125
+ else
126
+ MondialRelayDual::API_ENDPOINT_TEST
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,105 @@
1
+ require_relative 'mondial_relay_dual/shipments/create'
2
+ require_relative 'mondial_relay_dual/shipments/create/format_params'
3
+ require_relative 'mondial_relay_dual/pickups/create/format_params'
4
+ require_relative 'mondial_relay_dual/address'
5
+
6
+ module Deliveries
7
+ module Couriers
8
+ module MondialRelayDual
9
+ extend Courier
10
+
11
+ Config = Struct.new(
12
+ :dual_carrier_login,
13
+ :dual_carrier_password,
14
+ :dual_carrier_customer_id,
15
+ :countries
16
+ )
17
+
18
+ API_ENDPOINT_LIVE = 'https://connect-api.mondialrelay.com/api/shipment'.freeze
19
+ API_ENDPOINT_TEST = 'https://connect-api-sandbox.mondialrelay.com/api/shipment'.freeze
20
+
21
+ module_function
22
+
23
+ def get_collection_points(country:, postcode:)
24
+ MondialRelay.get_collection_points(
25
+ country: country,
26
+ postcode: postcode
27
+ )
28
+ end
29
+
30
+ def get_collection_point(global_point_id:)
31
+ MondialRelay.get_collection_point(global_point_id: global_point_id)
32
+ end
33
+
34
+ def create_shipment(sender:, receiver:, parcels:, reference_code:, collection_point: nil, shipment_date: nil, remarks: nil, language: nil)
35
+ params = Shipments::Create::FormatParams.new(
36
+ sender: sender,
37
+ receiver: receiver,
38
+ parcels: parcels,
39
+ collection_point: collection_point,
40
+ reference_code: reference_code,
41
+ remarks: remarks,
42
+ language: language
43
+ ).execute
44
+
45
+ tracking_code, pdf_url = Shipments::Create.new(
46
+ params: params
47
+ ).execute.values_at(:tracking_code, :pdf_url)
48
+
49
+ Deliveries::Shipment.new(
50
+ courier_id: 'mondial_relay_dual',
51
+ sender: sender,
52
+ receiver: receiver,
53
+ parcels: parcels,
54
+ reference_code: reference_code,
55
+ tracking_code: tracking_code,
56
+ shipment_date: shipment_date,
57
+ label: Label.new(url: pdf_url)
58
+ )
59
+ end
60
+
61
+ def create_pickup(sender:, receiver:, parcels:, reference_code:,
62
+ pickup_date: nil, remarks: nil, language: nil)
63
+ params = Pickups::Create::FormatParams.new(
64
+ sender: sender,
65
+ receiver: receiver,
66
+ parcels: parcels,
67
+ reference_code: reference_code,
68
+ remarks: remarks,
69
+ language: language
70
+ ).execute
71
+
72
+ tracking_code, pdf_url = Shipments::Create.new(
73
+ params: params
74
+ ).execute.values_at(:tracking_code, :pdf_url)
75
+
76
+ Deliveries::Pickup.new(
77
+ courier_id: 'mondial_relay_dual',
78
+ sender: sender,
79
+ receiver: receiver,
80
+ parcels: parcels,
81
+ reference_code: reference_code,
82
+ tracking_code: tracking_code,
83
+ pickup_date: pickup_date,
84
+ label: Label.new(url: pdf_url)
85
+ )
86
+ end
87
+
88
+ def shipment_info(tracking_code:, language: nil)
89
+ MondialRelay.shipment_info(tracking_code: tracking_code, language: language)
90
+ end
91
+
92
+ def pickup_info(tracking_code:, language: nil)
93
+ MondialRelay.pickup_info(tracking_code: tracking_code, language: language)
94
+ end
95
+
96
+ def get_label(**)
97
+ raise NotImplementedError, 'This courier does not support get_label operation'
98
+ end
99
+
100
+ def get_labels(**)
101
+ raise NotImplementedError, 'This courier does not support get_labels operation'
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,23 @@
1
+ module Deliveries
2
+ module Couriers
3
+ module Spring
4
+ class Address < Deliveries::Address
5
+ def name
6
+ @name.to_s[0, 35]
7
+ end
8
+
9
+ def street
10
+ @street.to_s[0, 35]
11
+ end
12
+
13
+ def street2
14
+ @street.to_s[35, 35].to_s
15
+ end
16
+
17
+ def street3
18
+ @street.to_s[70, 35].to_s
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,33 @@
1
+ module Deliveries
2
+ module Couriers
3
+ module Spring
4
+ module Labels
5
+ class Generate
6
+ attr_accessor :tracking_code
7
+
8
+ def initialize(tracking_code:)
9
+ self.tracking_code = tracking_code
10
+ end
11
+
12
+ def execute
13
+ params = {
14
+ Apikey: Deliveries::Couriers::Spring.config(:api_key),
15
+ Command: 'GetShipmentLabel',
16
+ Shipment: {
17
+ LabelFormat: 'PDF',
18
+ TrackingNumber: tracking_code
19
+ }
20
+ }
21
+
22
+ response = Deliveries::Couriers::Spring::Request.execute(params: params)
23
+
24
+ {
25
+ url: response[:Shipment][:CarrierTrackingUrl],
26
+ decoded_label: Base64.decode64(response[:Shipment][:LabelImage]).force_encoding('binary')
27
+ }
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end