deliveries 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/workflows/main.yml +19 -0
- data/.gitignore +12 -0
- data/.rspec +3 -0
- data/.rubocop.yml +34 -0
- data/CHANGELOG.md +13 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +127 -0
- data/LICENSE.txt +21 -0
- data/README.md +207 -0
- data/Rakefile +12 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/deliveries.gemspec +36 -0
- data/lib/deliveries/address.rb +71 -0
- data/lib/deliveries/checkpoint.rb +12 -0
- data/lib/deliveries/collection_point.rb +45 -0
- data/lib/deliveries/courier.rb +69 -0
- data/lib/deliveries/couriers/correos_express/address.rb +31 -0
- data/lib/deliveries/couriers/correos_express/collection_points/search/format_response.rb +82 -0
- data/lib/deliveries/couriers/correos_express/collection_points/search.rb +56 -0
- data/lib/deliveries/couriers/correos_express/labels/generate.rb +68 -0
- data/lib/deliveries/couriers/correos_express/pickups/create/defaults.rb +60 -0
- data/lib/deliveries/couriers/correos_express/pickups/create/format_params.rb +95 -0
- data/lib/deliveries/couriers/correos_express/pickups/create.rb +66 -0
- data/lib/deliveries/couriers/correos_express/pickups/cutoff_time/format_params.rb +40 -0
- data/lib/deliveries/couriers/correos_express/pickups/cutoff_time.rb +61 -0
- data/lib/deliveries/couriers/correos_express/pickups/trace/correos.test.wsdl +163 -0
- data/lib/deliveries/couriers/correos_express/pickups/trace/correos.wsdl +163 -0
- data/lib/deliveries/couriers/correos_express/pickups/trace/format_response.rb +71 -0
- data/lib/deliveries/couriers/correos_express/pickups/trace.rb +49 -0
- data/lib/deliveries/couriers/correos_express/shipments/create/defaults.rb +80 -0
- data/lib/deliveries/couriers/correos_express/shipments/create/format_params.rb +99 -0
- data/lib/deliveries/couriers/correos_express/shipments/create.rb +101 -0
- data/lib/deliveries/couriers/correos_express/shipments/trace/format_response.rb +67 -0
- data/lib/deliveries/couriers/correos_express/shipments/trace.rb +65 -0
- data/lib/deliveries/couriers/correos_express.rb +162 -0
- data/lib/deliveries/couriers/dummy.rb +106 -0
- data/lib/deliveries/couriers/mondial_relay/address.rb +31 -0
- data/lib/deliveries/couriers/mondial_relay/collection_points/search/format_response.rb +103 -0
- data/lib/deliveries/couriers/mondial_relay/labels/generate.rb +40 -0
- data/lib/deliveries/couriers/mondial_relay/pickups/create/format_params.rb +57 -0
- data/lib/deliveries/couriers/mondial_relay/shipments/create/defaults.rb +96 -0
- data/lib/deliveries/couriers/mondial_relay/shipments/create/format_params.rb +68 -0
- data/lib/deliveries/couriers/mondial_relay/shipments/create.rb +36 -0
- data/lib/deliveries/couriers/mondial_relay/shipments/trace/format_response.rb +94 -0
- data/lib/deliveries/couriers/mondial_relay/shipments/trace.rb +47 -0
- data/lib/deliveries/couriers/mondial_relay/status_codes.rb +105 -0
- data/lib/deliveries/couriers/mondial_relay.rb +189 -0
- data/lib/deliveries/couriers/mondial_relay_dual/address.rb +31 -0
- data/lib/deliveries/couriers/mondial_relay_dual/pickups/create/format_params.rb +39 -0
- data/lib/deliveries/couriers/mondial_relay_dual/shipments/create/format_params.rb +101 -0
- data/lib/deliveries/couriers/mondial_relay_dual/shipments/create.rb +133 -0
- data/lib/deliveries/couriers/mondial_relay_dual.rb +105 -0
- data/lib/deliveries/couriers/spring/address.rb +23 -0
- data/lib/deliveries/couriers/spring/labels/generate.rb +33 -0
- data/lib/deliveries/couriers/spring/request.rb +43 -0
- data/lib/deliveries/couriers/spring/shipments/create/defaults.rb +73 -0
- data/lib/deliveries/couriers/spring/shipments/create/format_params.rb +77 -0
- data/lib/deliveries/couriers/spring/shipments/create.rb +45 -0
- data/lib/deliveries/couriers/spring/shipments/trace/format_response.rb +79 -0
- data/lib/deliveries/couriers/spring/shipments/trace.rb +29 -0
- data/lib/deliveries/couriers/spring.rb +84 -0
- data/lib/deliveries/couriers/ups/collection_points/search.rb +142 -0
- data/lib/deliveries/couriers/ups/json_request.rb +40 -0
- data/lib/deliveries/couriers/ups/labels/generate.rb +72 -0
- data/lib/deliveries/couriers/ups/shipments/create.rb +210 -0
- data/lib/deliveries/couriers/ups/shipments/trace.rb +79 -0
- data/lib/deliveries/couriers/ups.rb +122 -0
- data/lib/deliveries/couriers.rb +14 -0
- data/lib/deliveries/delivery.rb +20 -0
- data/lib/deliveries/errors.rb +22 -0
- data/lib/deliveries/label.rb +20 -0
- data/lib/deliveries/label_utils.rb +67 -0
- data/lib/deliveries/labels.rb +40 -0
- data/lib/deliveries/pickup.rb +15 -0
- data/lib/deliveries/shipment.rb +15 -0
- data/lib/deliveries/tracking_info.rb +29 -0
- data/lib/deliveries/version.rb +5 -0
- data/lib/deliveries.rb +63 -0
- metadata +240 -0
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
3
|
+
module Deliveries
|
4
|
+
module Courier
|
5
|
+
@config = nil
|
6
|
+
|
7
|
+
def configure
|
8
|
+
@config ||= ancestors.first::Config.new
|
9
|
+
yield @config
|
10
|
+
end
|
11
|
+
|
12
|
+
def configured?
|
13
|
+
@config.present?
|
14
|
+
end
|
15
|
+
|
16
|
+
# Get configuration value by key.
|
17
|
+
#
|
18
|
+
# @param key [String, Symbol[]] Dot notation string or array of symbols.
|
19
|
+
# @param default [Mixed]
|
20
|
+
#
|
21
|
+
# @return [Mixed]
|
22
|
+
def config(key, default: nil)
|
23
|
+
raise 'Courier not configured' unless configured?
|
24
|
+
|
25
|
+
key = key.split('.').map(&:to_sym) if key.is_a? String
|
26
|
+
@config.dig(*key) || default
|
27
|
+
end
|
28
|
+
|
29
|
+
def test?
|
30
|
+
Deliveries.test?
|
31
|
+
end
|
32
|
+
|
33
|
+
def live?
|
34
|
+
Deliveries.live?
|
35
|
+
end
|
36
|
+
|
37
|
+
def get_collection_point(global_point_id:)
|
38
|
+
raise NotImplementedError
|
39
|
+
end
|
40
|
+
|
41
|
+
def get_collection_points(country:, postcode:)
|
42
|
+
raise NotImplementedError
|
43
|
+
end
|
44
|
+
|
45
|
+
def create_shipment(sender:, receiver:, collection_point:, parcels:, reference_code:, shipment_date: nil, remarks: nil, language: nil)
|
46
|
+
raise NotImplementedError
|
47
|
+
end
|
48
|
+
|
49
|
+
def create_pickup(sender:, receiver:, parcels:, reference_code:, pickup_date: nil, remarks: nil, language: nil)
|
50
|
+
raise NotImplementedError
|
51
|
+
end
|
52
|
+
|
53
|
+
def get_label(tracking_code:, language: nil)
|
54
|
+
raise NotImplementedError
|
55
|
+
end
|
56
|
+
|
57
|
+
def get_labels(tracking_codes:, language: nil)
|
58
|
+
raise NotImplementedError
|
59
|
+
end
|
60
|
+
|
61
|
+
def shipment_info(tracking_code:, language: nil)
|
62
|
+
raise NotImplementedError
|
63
|
+
end
|
64
|
+
|
65
|
+
def pickup_info(tracking_code:, language: nil)
|
66
|
+
raise NotImplementedError
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Deliveries
|
2
|
+
module Couriers
|
3
|
+
module CorreosExpress
|
4
|
+
class Address < Deliveries::Address
|
5
|
+
def name
|
6
|
+
@name.to_s[0, 40]
|
7
|
+
end
|
8
|
+
|
9
|
+
def street
|
10
|
+
@street.to_s[0, 300]
|
11
|
+
end
|
12
|
+
|
13
|
+
def city
|
14
|
+
@city.to_s[0, 40]
|
15
|
+
end
|
16
|
+
|
17
|
+
def phone
|
18
|
+
@phone.to_s[0, 15]
|
19
|
+
end
|
20
|
+
|
21
|
+
def email
|
22
|
+
@email.gsub(/\+.+@/, '@').to_s[0, 75]
|
23
|
+
end
|
24
|
+
|
25
|
+
def country
|
26
|
+
@country.to_s.upcase
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# "codigoOficina"=>"4894006",
|
2
|
+
# "nombreOficina"=>"OF.CORREOS: LAMIAKO - 4894006",
|
3
|
+
# "direccionOficina"=>"LANGILERIA 88",
|
4
|
+
# "codigoPostalOficina"=>"48940",
|
5
|
+
# "poblacionOficina"=>"LAMIAKO",
|
6
|
+
# "horarioOficina"=>"L-V:DE 08:30 A 14:30/S:DE 09:30 A 13:00/Festivos:SIN SERVICIO",
|
7
|
+
# "horarioOficinaVerano"=>"L-V:08:30-14:30/S:09:30-13:00/Festivos:SIN SERVICIO",
|
8
|
+
# "geoposicionOficina"=>"43.32142,-3.00031"
|
9
|
+
|
10
|
+
module Deliveries
|
11
|
+
module Couriers
|
12
|
+
module CorreosExpress
|
13
|
+
module CollectionPoints
|
14
|
+
class Search
|
15
|
+
class FormatResponse
|
16
|
+
SATURDAY_HOUR_KEY = 'S:'.freeze
|
17
|
+
WORKDAY_HOUR_KEY = 'L-V:'.freeze
|
18
|
+
HOLIDAY_HOUR_KEY = 'Festivos:'.freeze
|
19
|
+
|
20
|
+
attr_accessor :response
|
21
|
+
|
22
|
+
def initialize(response:)
|
23
|
+
self.response = response
|
24
|
+
end
|
25
|
+
|
26
|
+
def execute
|
27
|
+
collection_point = {}
|
28
|
+
collection_point[:courier_id] = 'correos_express'
|
29
|
+
collection_point[:name] = response['nombreOficina']
|
30
|
+
collection_point[:point_id] = response['codigoOficina']
|
31
|
+
collection_point[:street] = response['direccionOficina']
|
32
|
+
collection_point[:city] = response['poblacionOficina']
|
33
|
+
collection_point[:postcode] = response['codigoPostalOficina']
|
34
|
+
latitude, longitude = response['geoposicionOficina'].split(',')
|
35
|
+
collection_point[:latitude] = latitude.to_f
|
36
|
+
collection_point[:longitude] = longitude.to_f
|
37
|
+
collection_point[:timetable] = formatted_timetable(response['horarioOficina'])
|
38
|
+
|
39
|
+
collection_point
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def formatted_timetable(params)
|
45
|
+
workday_hour, saturday_hour, holiday_hour = get_week_hours_from_result(params)
|
46
|
+
|
47
|
+
timetable = {}
|
48
|
+
|
49
|
+
if workday_hour.present?
|
50
|
+
1.upto(5) do |weekday|
|
51
|
+
timetable[weekday] = [formatted_slot(workday_hour, WORKDAY_HOUR_KEY)]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
timetable[6] = [formatted_slot(saturday_hour, SATURDAY_HOUR_KEY)] if saturday_hour.present?
|
56
|
+
|
57
|
+
timetable[0] = nil if holiday_hour.present?
|
58
|
+
|
59
|
+
timetable
|
60
|
+
end
|
61
|
+
|
62
|
+
def get_week_hours_from_result(params)
|
63
|
+
week_hours = params.split('/')
|
64
|
+
|
65
|
+
workday_hour = week_hours.select { |o| o.start_with?(WORKDAY_HOUR_KEY) }.first
|
66
|
+
saturday_hour = week_hours.select { |o| o.start_with?(SATURDAY_HOUR_KEY) }.first
|
67
|
+
holiday_hour = week_hours.select { |o| o.start_with?(HOLIDAY_HOUR_KEY) }.first
|
68
|
+
|
69
|
+
[workday_hour, saturday_hour, holiday_hour]
|
70
|
+
end
|
71
|
+
|
72
|
+
def formatted_slot(hour, key)
|
73
|
+
open, close = hour.sub(key, '').sub('DE ', '').split(' A ')
|
74
|
+
|
75
|
+
OpenStruct.new(open: open, close: close)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
|
3
|
+
module Deliveries
|
4
|
+
module Couriers
|
5
|
+
module CorreosExpress
|
6
|
+
module CollectionPoints
|
7
|
+
class Search
|
8
|
+
include HTTParty
|
9
|
+
|
10
|
+
attr_accessor :postcode
|
11
|
+
|
12
|
+
def initialize(postcode:)
|
13
|
+
self.postcode = postcode
|
14
|
+
end
|
15
|
+
|
16
|
+
def execute
|
17
|
+
auth = {
|
18
|
+
username: CorreosExpress.config(:username),
|
19
|
+
password: CorreosExpress.config(:password)
|
20
|
+
}
|
21
|
+
|
22
|
+
headers = { 'Content-Type' => 'application/json;charset=UTF-8', 'Accept' => 'application/json' }
|
23
|
+
|
24
|
+
response = self.class.post(
|
25
|
+
api_endpoint,
|
26
|
+
basic_auth: auth,
|
27
|
+
body: { cod_postal: postcode }.to_json,
|
28
|
+
headers: headers,
|
29
|
+
debug_output: Deliveries.debug ? Deliveries.logger : nil
|
30
|
+
)
|
31
|
+
parsed_response = JSON.parse(response.body)
|
32
|
+
|
33
|
+
if parsed_response['tipoRespuesta'] == 'KO'
|
34
|
+
raise Deliveries::APIError.new(
|
35
|
+
parsed_response['listaErrores'].first['descError'],
|
36
|
+
parsed_response['listaErrores'].first['codError']
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
parsed_response['oficinas']
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def api_endpoint
|
46
|
+
if CorreosExpress.live?
|
47
|
+
CorreosExpress::COLLECTION_POINTS_ENDPOINT_LIVE
|
48
|
+
else
|
49
|
+
CorreosExpress::COLLECTION_POINTS_ENDPOINT_TEST
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
|
3
|
+
module Deliveries
|
4
|
+
module Couriers
|
5
|
+
module CorreosExpress
|
6
|
+
module Labels
|
7
|
+
class Generate
|
8
|
+
include HTTParty
|
9
|
+
|
10
|
+
attr_accessor :tracking_codes
|
11
|
+
|
12
|
+
def initialize(tracking_codes:)
|
13
|
+
self.tracking_codes = tracking_codes.respond_to?(:each) ? tracking_codes : [tracking_codes]
|
14
|
+
end
|
15
|
+
|
16
|
+
def execute
|
17
|
+
auth = {
|
18
|
+
username: CorreosExpress.config(:username),
|
19
|
+
password: CorreosExpress.config(:password)
|
20
|
+
}
|
21
|
+
decoded_labels = []
|
22
|
+
tracking_codes.each do |tracking_code|
|
23
|
+
params = {
|
24
|
+
keyCli: CorreosExpress.config(:shipment_sender_code),
|
25
|
+
nenvio: tracking_code,
|
26
|
+
tipo: '1' # "1" - pdf, "2" - zpl image
|
27
|
+
}.to_json
|
28
|
+
|
29
|
+
headers = { 'Content-Type' => 'application/json' }
|
30
|
+
response = self.class.post(
|
31
|
+
api_endpoint,
|
32
|
+
basic_auth: auth,
|
33
|
+
body: params,
|
34
|
+
headers: headers,
|
35
|
+
debug_output: Deliveries.debug ? Deliveries.logger : nil
|
36
|
+
)
|
37
|
+
parsed_response = JSON.parse(response.body)
|
38
|
+
if (parsed_response['codErr']).zero?
|
39
|
+
if parsed_response['listaEtiquetas'].any?
|
40
|
+
parsed_response['listaEtiquetas'].each do |encoded_label|
|
41
|
+
decoded_labels << Base64.decode64(encoded_label).force_encoding('binary')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
else
|
45
|
+
raise Deliveries::APIError.new(
|
46
|
+
parsed_response['desErr'],
|
47
|
+
parsed_response['codErr']
|
48
|
+
)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
decoded_labels
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def api_endpoint
|
58
|
+
if CorreosExpress.live?
|
59
|
+
CorreosExpress::LABELS_ENDPOINT_LIVE
|
60
|
+
else
|
61
|
+
CorreosExpress::LABELS_ENDPOINT_TEST
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Deliveries
|
2
|
+
module Couriers
|
3
|
+
module CorreosExpress
|
4
|
+
module Pickups
|
5
|
+
class Create
|
6
|
+
module Defaults
|
7
|
+
PARAMS = {
|
8
|
+
solicitante: '',
|
9
|
+
password: '',
|
10
|
+
canalEntrada: '',
|
11
|
+
refRecogida: '',
|
12
|
+
fechaRecogida: '', # ddmmyyyy
|
13
|
+
horaDesde1: '09:00',
|
14
|
+
horaDesde2: '',
|
15
|
+
horaHasta1: '17:00',
|
16
|
+
horaHasta2: '',
|
17
|
+
clienteRecogida: '',
|
18
|
+
codRemit: '',
|
19
|
+
nomRemit: '',
|
20
|
+
nifRemit: '',
|
21
|
+
dirRecog: '',
|
22
|
+
poblRecog: '',
|
23
|
+
cpRecog: '',
|
24
|
+
contRecog: '',
|
25
|
+
tlfnoRecog: '',
|
26
|
+
oTlfnRecog: '',
|
27
|
+
emailRecog: '',
|
28
|
+
observ: '',
|
29
|
+
tipoServ: '',
|
30
|
+
codDest: '',
|
31
|
+
nomDest: '',
|
32
|
+
nifDest: '',
|
33
|
+
dirDest: '',
|
34
|
+
pobDest: '',
|
35
|
+
cpDest: '',
|
36
|
+
paisDest: '',
|
37
|
+
cpiDest: '',
|
38
|
+
contactoDest: '',
|
39
|
+
tlfnoDest: '',
|
40
|
+
emailDest: '',
|
41
|
+
nEnvio: '',
|
42
|
+
refEnvio: '',
|
43
|
+
producto: '63',
|
44
|
+
kilos: '',
|
45
|
+
bultos: '',
|
46
|
+
volumen: '',
|
47
|
+
tipoPortes: '',
|
48
|
+
importReembol: '',
|
49
|
+
valDeclMerc: '',
|
50
|
+
infTec: '',
|
51
|
+
nSerie: '',
|
52
|
+
modelo: '',
|
53
|
+
latente: '0'
|
54
|
+
}.freeze
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
module Deliveries
|
2
|
+
module Couriers
|
3
|
+
module CorreosExpress
|
4
|
+
module Pickups
|
5
|
+
class Create
|
6
|
+
class FormatParams
|
7
|
+
attr_accessor :sender, :receiver, :parcels, :reference_code,
|
8
|
+
:pickup_date, :remarks, :time_interval
|
9
|
+
|
10
|
+
def initialize(sender:, receiver:, parcels:, reference_code:,
|
11
|
+
pickup_date:, remarks:, time_interval: nil)
|
12
|
+
self.sender = sender
|
13
|
+
self.receiver = receiver
|
14
|
+
self.parcels = parcels
|
15
|
+
self.reference_code = reference_code
|
16
|
+
self.pickup_date = pickup_date
|
17
|
+
self.remarks = remarks
|
18
|
+
self.time_interval = time_interval
|
19
|
+
end
|
20
|
+
|
21
|
+
def execute
|
22
|
+
postcode = format_postcode(sender.postcode, sender.country)
|
23
|
+
params = {
|
24
|
+
solicitante: CorreosExpress.config(:client_code),
|
25
|
+
refRecogida: reference_code,
|
26
|
+
fechaRecogida: pickup_date&.strftime('%d%m%Y') || '',
|
27
|
+
clienteRecogida: CorreosExpress.config(:pickup_receiver_code),
|
28
|
+
codRemit: '',
|
29
|
+
nomRemit: sender.name,
|
30
|
+
nifRemit: '',
|
31
|
+
dirRecog: sender.street,
|
32
|
+
poblRecog: sender.city,
|
33
|
+
cpRecog: postcode,
|
34
|
+
contRecog: sender.name,
|
35
|
+
tlfnoRecog: sender.phone,
|
36
|
+
emailRecog: sender.email,
|
37
|
+
codDest: CorreosExpress.config(:pickup_receiver_code),
|
38
|
+
nomDest: receiver.name,
|
39
|
+
dirDest: receiver.street,
|
40
|
+
pobDest: receiver.city,
|
41
|
+
cpDest: receiver.postcode,
|
42
|
+
paisDest: receiver.country,
|
43
|
+
contactoDest: receiver.name,
|
44
|
+
tlfnoDest: receiver.phone,
|
45
|
+
emailDest: receiver.email,
|
46
|
+
bultos: parcels.to_s
|
47
|
+
}
|
48
|
+
|
49
|
+
unless CorreosExpress.test?
|
50
|
+
custom_product = CorreosExpress.config("countries.#{sender.country.to_s.downcase}.product")
|
51
|
+
params[:producto] = custom_product if custom_product
|
52
|
+
end
|
53
|
+
|
54
|
+
defaults = Defaults::PARAMS
|
55
|
+
|
56
|
+
defaults = defaults.merge(params)
|
57
|
+
|
58
|
+
if time_interval
|
59
|
+
defaults[:horaDesde1] = format '%02d:00', time_interval.first
|
60
|
+
defaults[:horaHasta1] = format '%02d:00', time_interval.last
|
61
|
+
else
|
62
|
+
# Try to set cutoff time for the sender postal code.
|
63
|
+
begin
|
64
|
+
cutoff_time = CutoffTime.new(country: sender.country, postcode: postcode).execute
|
65
|
+
# Set only when cuttoff time is less than 19:00 (the default cutoff time in correos express)
|
66
|
+
if cutoff_time.to_i < 19
|
67
|
+
defaults[:horaHasta1] = cutoff_time
|
68
|
+
|
69
|
+
# Update start hour if the period if smaller than 2 hours
|
70
|
+
min_start_hour = cutoff_time.to_i - 2
|
71
|
+
defaults[:horaDesde1] = format('%02d:00', min_start_hour) if defaults[:horaDesde1].to_i > min_start_hour
|
72
|
+
end
|
73
|
+
rescue Deliveries::Error => e
|
74
|
+
Deliveries.logger&.error "Cannot obtain cutoff time: #{e.message}"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
defaults.to_json
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def format_postcode(postcode, country)
|
84
|
+
if country.to_sym.downcase == :pt
|
85
|
+
postcode&.split('-')&.first
|
86
|
+
else
|
87
|
+
postcode
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
|
3
|
+
module Deliveries
|
4
|
+
module Couriers
|
5
|
+
module CorreosExpress
|
6
|
+
module Pickups
|
7
|
+
class Create
|
8
|
+
include HTTParty
|
9
|
+
|
10
|
+
attr_accessor :params
|
11
|
+
|
12
|
+
def initialize(params:)
|
13
|
+
self.params = params
|
14
|
+
end
|
15
|
+
|
16
|
+
def execute
|
17
|
+
auth = {
|
18
|
+
username: CorreosExpress.config(:username),
|
19
|
+
password: CorreosExpress.config(:password)
|
20
|
+
}
|
21
|
+
|
22
|
+
response = self.class.post(
|
23
|
+
api_endpoint,
|
24
|
+
basic_auth: auth,
|
25
|
+
body: params,
|
26
|
+
headers: headers,
|
27
|
+
debug_output: Deliveries.debug ? Deliveries.logger : nil
|
28
|
+
)
|
29
|
+
raise ClientError, "Failed with status code #{response.code}" unless response.success?
|
30
|
+
|
31
|
+
parsed_response = JSON.parse(response.body, symbolize_names: true)
|
32
|
+
if parsed_response[:codigoRetorno]&.zero? && parsed_response[:numRecogida].present?
|
33
|
+
parsed_response[:numRecogida]
|
34
|
+
else
|
35
|
+
exception_class =
|
36
|
+
case parsed_response[:codigoRetorno]
|
37
|
+
when 105 then InvalidDateError
|
38
|
+
when 154 then InvalidTimeIntervalError
|
39
|
+
else APIError
|
40
|
+
end
|
41
|
+
|
42
|
+
raise exception_class.new(
|
43
|
+
parsed_response[:mensajeRetorno],
|
44
|
+
parsed_response[:codigoRetorno]
|
45
|
+
)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def api_endpoint
|
52
|
+
if CorreosExpress.live?
|
53
|
+
CorreosExpress::PICKUPS_ENDPOINT_LIVE
|
54
|
+
else
|
55
|
+
CorreosExpress::PICKUPS_ENDPOINT_TEST
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def headers
|
60
|
+
{ 'Content-Type' => 'application/json' }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Deliveries
|
2
|
+
module Couriers
|
3
|
+
module CorreosExpress
|
4
|
+
module Pickups
|
5
|
+
class CutoffTime
|
6
|
+
class FormatParams
|
7
|
+
attr_accessor :country, :postcode
|
8
|
+
|
9
|
+
def initialize(country:, postcode:)
|
10
|
+
self.country = country
|
11
|
+
self.postcode = postcode
|
12
|
+
end
|
13
|
+
|
14
|
+
def execute
|
15
|
+
params = {
|
16
|
+
strCP: postcode,
|
17
|
+
strPais: country_code_to_id(country)
|
18
|
+
}
|
19
|
+
|
20
|
+
params.to_json
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def country_code_to_id(country_code)
|
26
|
+
case country_code.to_sym.downcase
|
27
|
+
when :es
|
28
|
+
'34'
|
29
|
+
when :pt
|
30
|
+
'35'
|
31
|
+
else
|
32
|
+
raise Deliveries::Error, "Invalid country #{country_code}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
|
3
|
+
module Deliveries
|
4
|
+
module Couriers
|
5
|
+
module CorreosExpress
|
6
|
+
module Pickups
|
7
|
+
class CutoffTime
|
8
|
+
include HTTParty
|
9
|
+
|
10
|
+
attr_accessor :country, :postcode
|
11
|
+
|
12
|
+
def initialize(country:, postcode:)
|
13
|
+
self.country = country
|
14
|
+
self.postcode = postcode
|
15
|
+
end
|
16
|
+
|
17
|
+
def execute
|
18
|
+
auth = {
|
19
|
+
username: CorreosExpress.config(:username),
|
20
|
+
password: CorreosExpress.config(:password)
|
21
|
+
}
|
22
|
+
|
23
|
+
params = FormatParams.new(
|
24
|
+
country: country,
|
25
|
+
postcode: postcode
|
26
|
+
).execute
|
27
|
+
|
28
|
+
response = self.class.post(
|
29
|
+
api_endpoint,
|
30
|
+
basic_auth: auth,
|
31
|
+
body: params,
|
32
|
+
headers: headers,
|
33
|
+
debug_output: Deliveries.debug ? Deliveries.logger : nil
|
34
|
+
)
|
35
|
+
raise Deliveries::Error unless response.success?
|
36
|
+
|
37
|
+
parsed_response = JSON.parse(response.body, symbolize_names: true)
|
38
|
+
if (parsed_response[:codError]).zero? && parsed_response[:horaCorte].present?
|
39
|
+
parsed_response[:horaCorte]
|
40
|
+
else
|
41
|
+
raise Deliveries::APIError.new(
|
42
|
+
parsed_response[:mensError],
|
43
|
+
parsed_response[:codError]
|
44
|
+
)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def api_endpoint
|
51
|
+
CorreosExpress::CUTOFF_TIME_ENDPOINT_LIVE
|
52
|
+
end
|
53
|
+
|
54
|
+
def headers
|
55
|
+
{ 'Content-Type' => 'application/json' }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|