deliveries 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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