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,57 @@
1
+ module Deliveries
2
+ module Couriers
3
+ module MondialRelay
4
+ module Pickups
5
+ class Create
6
+ class FormatParams
7
+ attr_accessor :sender, :receiver, :parcels, :reference_code, :pickup_date, :remarks, :language
8
+
9
+ def initialize(sender:, receiver:, parcels:, reference_code:, pickup_date:, remarks:, language:)
10
+ self.sender = sender
11
+ self.receiver = receiver
12
+ self.parcels = parcels
13
+ self.reference_code = reference_code
14
+ self.pickup_date = pickup_date
15
+ self.remarks = remarks
16
+ self.language = language
17
+ end
18
+
19
+ def execute
20
+ params = {
21
+ 'Enseigne' => Deliveries::Couriers::MondialRelay.config(:mondial_relay_merchant),
22
+ 'ModeCol' => 'REL',
23
+ 'ModeLiv' => 'LCC',
24
+ 'COL_Rel_Pays' => 'XX',
25
+ 'COL_Rel' => 'AUTO',
26
+ 'NDossier' => reference_code,
27
+ 'Expe_Langage' => language.to_s.upcase,
28
+ 'Expe_Ad1' => sender.name,
29
+ 'Expe_Ad3' => sender.street,
30
+ 'Expe_Ville' => sender.city,
31
+ 'Expe_CP' => sender.postcode,
32
+ 'Expe_Pays' => sender.country,
33
+ 'Expe_Tel1' => sender.phone,
34
+ 'Expe_Mail' => sender.email,
35
+ 'Dest_Langage' => language.to_s.upcase,
36
+ 'Dest_Ad1' => receiver.name,
37
+ 'Dest_Ad3' => receiver.street,
38
+ 'Dest_Ville' => receiver.city,
39
+ 'Dest_CP' => receiver.postcode,
40
+ 'Dest_Pays' => receiver.country,
41
+ 'Dest_Tel1' => receiver.phone,
42
+ 'Dest_Mail' => receiver.email,
43
+ 'NbColis' => parcels,
44
+ 'Instructions' => I18n.transliterate(remarks.to_s).gsub(%r{[^0-9A-Z_\-'., /]}i, '').upcase.truncate(30,
45
+ omission: '')
46
+ }
47
+
48
+ defaults = Shipments::Create::Defaults::PARAMS
49
+
50
+ defaults.merge(params)
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,96 @@
1
+ # COLLECTION MODES:
2
+ # CCC: Merchant collection
3
+ # CDR: Home collection standard shipments
4
+ # CDS: Home collection heavy shipments
5
+ # REL: Point relais collection
6
+
7
+ # DELIVERY MODES:
8
+ # 24R: Point relais delivery
9
+ # 24L: POint relais XL delivery
10
+ # 24X: Point relais XXL delivery
11
+ # DRI: Colis drive delivery
12
+ # LD1: Home delivery(1 delivery man)
13
+ # LDS: Home delivery(2 delivery men)
14
+ # HOM: Home delivery < 30kg
15
+ # HOC: Home delivery (specific for Spain)
16
+ # LCC: Reverse
17
+
18
+ module Deliveries
19
+ module Couriers
20
+ module MondialRelay
21
+ module Shipments
22
+ class Create
23
+ module Defaults
24
+ COLLECTION_MODES = {
25
+ home_collection_standard: 'CDR',
26
+ point_relais_collection: 'REL'
27
+ }.freeze
28
+
29
+ DELIVERY_MODES = {
30
+ home_delivery_standard: 'LD1',
31
+ point_relais_delivery: '24R'
32
+ }.freeze
33
+
34
+ PARAMS = {
35
+ 'Enseigne' => '',
36
+ 'ModeCol' => 'CCC', # Collection mode
37
+ 'ModeLiv' => '', # Delivery mode
38
+ 'NDossier' => '', # Reference code
39
+
40
+ 'NClient' => '', # sender reference
41
+ 'Expe_Langage' => '',
42
+ 'Expe_Ad1' => '',
43
+ 'Expe_Ad2' => '',
44
+ 'Expe_Ad3' => '',
45
+ 'Expe_Ad4' => '',
46
+ 'Expe_Ville' => '',
47
+ 'Expe_CP' => '',
48
+ 'Expe_Pays' => '',
49
+ 'Expe_Tel1' => '',
50
+ 'Expe_Tel2' => '',
51
+ 'Expe_Mail' => '',
52
+
53
+ 'Dest_Langage' => '',
54
+ 'Dest_Ad1' => '',
55
+ 'Dest_Ad2' => '',
56
+ 'Dest_Ad3' => '',
57
+ 'Dest_Ad4' => '',
58
+ 'Dest_Ville' => '',
59
+ 'Dest_CP' => '',
60
+ 'Dest_Pays' => '',
61
+ 'Dest_Tel1' => '',
62
+ 'Dest_Tel2' => '',
63
+ 'Dest_Mail' => '',
64
+
65
+ 'Poids' => '1000', # weight in grams
66
+ 'Longueur' => '', # length
67
+ 'Taille' => '', # size
68
+ 'NbColis' => '1', # Number of parcels
69
+
70
+ # TODO: COD shipment value in cents?
71
+ 'CRT_Valeur' => '0',
72
+ 'CRT_Devise' => '',
73
+ 'Exp_Valeur' => '', # Price
74
+ 'Exp_Devise' => '', # Currency
75
+
76
+ # Collection point info
77
+ 'COL_Rel_Pays' => '',
78
+ 'COL_Rel' => '',
79
+
80
+ # Delivery point info
81
+ 'LIV_Rel_Pays' => '',
82
+ 'LIV_Rel' => '',
83
+
84
+ 'TAvisage' => '', # notify
85
+ 'TReprise' => '',
86
+ 'Montage' => '', # assembly time
87
+ 'TRDV' => '', # request for delivery appointment
88
+ 'Assurance' => '',
89
+ 'Instructions' => ''
90
+ }.freeze
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,68 @@
1
+ module Deliveries
2
+ module Couriers
3
+ module MondialRelay
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
11
+ self.receiver = receiver
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
+ params = {
21
+ 'Enseigne' => Deliveries::Couriers::MondialRelay.config(:mondial_relay_merchant),
22
+ 'NDossier' => reference_code,
23
+ 'Expe_Langage' => language.to_s.upcase,
24
+ 'Expe_Ad1' => sender.name,
25
+ 'Expe_Ad3' => sender.street,
26
+ 'Expe_Ville' => sender.city,
27
+ 'Expe_CP' => sender.postcode,
28
+ 'Expe_Pays' => sender.country,
29
+ 'Expe_Tel1' => sender.phone,
30
+ 'Expe_Mail' => sender.email,
31
+ 'Dest_Langage' => language.to_s.upcase,
32
+ 'Dest_Ad1' => receiver.name,
33
+ 'Dest_Ad3' => receiver.street,
34
+ 'Dest_Ville' => receiver.city,
35
+ 'Dest_CP' => receiver.postcode,
36
+ 'Dest_Pays' => receiver.country.to_s.upcase,
37
+ 'Dest_Tel1' => receiver.phone,
38
+ 'Dest_Mail' => receiver.email,
39
+ 'NbColis' => parcels,
40
+ 'Instructions' => I18n.transliterate(remarks.to_s).gsub(%r{[^0-9A-Z_\-'., /]}i, '').upcase.truncate(30,
41
+ omission: '')
42
+ }
43
+
44
+ # Receiving in a collection point
45
+ receive_mode_params = if collection_point.present?
46
+ {
47
+ 'ModeLiv' => '24R',
48
+ 'LIV_Rel_Pays' => receiver.country,
49
+ 'LIV_Rel' => collection_point.point_id,
50
+ 'COL_Rel_Pays' => receiver.country,
51
+ 'COL_Rel' => collection_point.point_id
52
+ }
53
+ else
54
+ {
55
+ 'ModeLiv' => 'HOM'
56
+ }
57
+ end
58
+
59
+ defaults = Defaults::PARAMS
60
+
61
+ defaults.merge(params).merge(receive_mode_params)
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,36 @@
1
+ module Deliveries
2
+ module Couriers
3
+ module MondialRelay
4
+ module Shipments
5
+ class Create
6
+ attr_accessor :params
7
+
8
+ def initialize(params:)
9
+ self.params = params
10
+ end
11
+
12
+ def execute
13
+ params['Security'] = Deliveries::Couriers::MondialRelay.calculate_security_param params
14
+
15
+ # Call web service.
16
+ response = MondialRelay.api_client.call :wsi2_creation_etiquette, message: params
17
+ # If response returns OK stat code.
18
+ response_result = response.body[:wsi2_creation_etiquette_response][:wsi2_creation_etiquette_result]
19
+ if response_result && response_result[:stat] == '0'
20
+ {
21
+ tracking_code: response_result[:expedition_num],
22
+ label_url: "http://www.mondialrelay.com#{response_result[:url_etiquette].gsub('format=A4',
23
+ 'format=10x15')}"
24
+ }
25
+ else
26
+ raise Deliveries::APIError.new(
27
+ StatusCodes.message_for(response_result[:stat].to_i),
28
+ response_result[:stat]
29
+ )
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,94 @@
1
+ require 'active_support/time'
2
+
3
+ module Deliveries
4
+ module Couriers
5
+ module MondialRelay
6
+ module Shipments
7
+ class Trace
8
+ class FormatResponse
9
+ attr_accessor :response
10
+
11
+ def initialize(response:)
12
+ self.response = response
13
+ end
14
+
15
+ def execute
16
+ statuses = response[:tracing][:ret_wsi2_sub_tracing_colis_detaille].delete_if do |key, _value|
17
+ key[:libelle].blank?
18
+ end
19
+
20
+ tracking_info_params = {}
21
+ tracking_info_params[:courier_id] = 'mondial_relay'
22
+ tracking_info_params[:status] = shipment_status(response[:stat].to_i, last_status(statuses))
23
+ tracking_info_params[:checkpoints] = formatted_checkpoints(statuses)
24
+
25
+ tracking_info_params
26
+ end
27
+
28
+ private
29
+
30
+ def last_status(statuses)
31
+ statuses.map { |s| s[:libelle] }
32
+ .compact
33
+ .last
34
+ end
35
+
36
+ def formatted_checkpoints(statuses)
37
+ checkpoints = []
38
+ statuses.each do |status|
39
+ checkpoints << formatted_checkpoint(status)
40
+ end
41
+
42
+ checkpoints
43
+ end
44
+
45
+ def formatted_checkpoint(status)
46
+ Deliveries::Checkpoint.new(
47
+ status: checkpoint_status(status[:libelle]),
48
+ location: status[:emplacement],
49
+ tracked_at: Time.zone.strptime("#{status[:date]} #{status[:heure]}", '%d/%m/%y %H:%M'),
50
+ description: status[:libelle]
51
+ )
52
+ end
53
+
54
+ def shipment_status(stat, last_checkpoint_status)
55
+ case stat
56
+ when 80
57
+ :registered
58
+ when 82
59
+ :delivered
60
+ when 81
61
+ if ['Disponible en el Punto Pack', 'DISPONIBLE AU POINT RELAIS'].include?(last_checkpoint_status)
62
+ :in_collection_point
63
+ else
64
+ :in_transit
65
+ end
66
+ else
67
+ :unknown_status
68
+ end
69
+ end
70
+
71
+ def checkpoint_status(message)
72
+ case message
73
+ when 'Disponible en el Punto Pack', 'Recepcionado en el Punto Pack',
74
+ 'DISPONIBLE AU POINT RELAIS', 'PRISE EN CHARGE POINT RELAIS'
75
+ :in_collection_point
76
+ when 'Recogido en agencia Punto Pack',
77
+ 'RÉCEPTION DES DONNÉES'
78
+ :registered
79
+ when 'Recogido en el hub', 'En reparto',
80
+ 'PRISE EN CHARGE EN AGENCE', 'COLIS REMIS AU LIVREUR'
81
+ :in_transit
82
+ when 'Paquete entregado al Destinata', 'Liquidado en Ensena',
83
+ 'COLIS LIVRÉ'
84
+ :delivered
85
+ else
86
+ :unknown_status
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,47 @@
1
+ module Deliveries
2
+ module Couriers
3
+ module MondialRelay
4
+ module Shipments
5
+ class Trace
6
+ SUPPORTED_LANGUAGES = %i[fr es nl en].freeze
7
+
8
+ attr_accessor :tracking_code, :language
9
+
10
+ def initialize(tracking_code:, language:)
11
+ self.tracking_code = tracking_code
12
+ self.language =
13
+ if SUPPORTED_LANGUAGES.include? language&.to_sym&.downcase
14
+ language
15
+ else
16
+ 'en'
17
+ end
18
+ end
19
+
20
+ def execute
21
+ params = { 'Enseigne' => Deliveries::Couriers::MondialRelay.config(:mondial_relay_merchant),
22
+ 'Expedition' => tracking_code,
23
+ 'Langue' => language }
24
+
25
+ params['Security'] = Deliveries::Couriers::MondialRelay.calculate_security_param params
26
+
27
+ # Call web service.
28
+ response = MondialRelay.api_client.call :wsi2_tracing_colis_detaille, message: params
29
+
30
+ response_result = response.body.dig(:wsi2_tracing_colis_detaille_response,
31
+ :wsi2_tracing_colis_detaille_result)
32
+ if response_result.present? &&
33
+ StatusCodes.tracking_info_success?(response_result[:stat].to_i)
34
+
35
+ response_result
36
+ else
37
+ raise Deliveries::APIError.new(
38
+ StatusCodes.message_for(response_result[:stat].to_i),
39
+ response_result[:stat]
40
+ )
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,105 @@
1
+ module Deliveries
2
+ module Couriers
3
+ module MondialRelay
4
+ STATUS_CODES = {
5
+ 0 => 'Successful operation',
6
+ 1 => 'Incorrect merchant',
7
+ 2 => 'Merchant number empty',
8
+ 3 => 'Incorrect merchant account number',
9
+
10
+ 5 => 'Incorrect Merchant shipment reference',
11
+
12
+ 7 => 'Incorrect Consignee reference',
13
+ 8 => 'Incorrect password or hash',
14
+ 9 => 'Unknown or not unique city',
15
+ 10 => 'Incorrect type of collection',
16
+ 11 => 'Point Relais collection number incorrect',
17
+ 12 => 'Point Relais collection country incorrect',
18
+ 13 => 'Incorrect type of delivery',
19
+ 14 => 'Incorrect delivery Point Relais number',
20
+ 15 => 'Point Relais delivery country incorrect',
21
+
22
+ 20 => 'Incorrect parcel weight',
23
+ 21 => 'Incorrect developped lenght (length + height)',
24
+ 22 => 'Incorrect parcel size',
25
+
26
+ 24 => 'Incorrect shipment number',
27
+
28
+ 26 => 'Incorrect assembly time',
29
+ 27 => 'Incorrect mode of collection or delivery',
30
+ 28 => 'Incorrect mode of collection',
31
+ 29 => 'Incorrect mode of delivery',
32
+ 30 => 'Incorrect address (L1)',
33
+ 31 => 'Incorrect address (L2)',
34
+
35
+ 33 => 'Incorrect address (L3)',
36
+ 34 => 'Incorrect address (L4)',
37
+
38
+ 35 => 'Incorrect city',
39
+ 36 => 'Incorrect zip code',
40
+ 37 => 'Incorrect country',
41
+ 38 => 'Incorrect phone number',
42
+ 39 => 'Incorrect e-mail',
43
+ 40 => 'Missing parameters',
44
+
45
+ 42 => 'Incorrect COD value',
46
+ 43 => 'Incorrect COD currency',
47
+ 44 => 'Incorrect shipment value',
48
+ 45 => 'Incorrect shipment value currency',
49
+ 46 => 'End of shipments number range reached',
50
+ 47 => 'Incorrect number of parcels',
51
+ 48 => 'Multi-Parcel not permitted at Point Relais',
52
+ 49 => 'Incorrect action',
53
+
54
+ 60 => 'Incorrect text field (this error code has no impact)',
55
+ 61 => 'Incorrect notification request',
56
+ 62 => 'Incorrect extra delivery information',
57
+ 63 => 'Incorrect insurance',
58
+ 64 => 'Incorrect assembly time',
59
+ 65 => 'Incorrect appointement',
60
+ 66 => 'Incorrect take back',
61
+ 67 => 'Incorrect latitude',
62
+ 68 => 'Incorrect longitude',
63
+ 69 => 'Incorrect merchant code',
64
+ 70 => 'Incorrect Point Relais number',
65
+ 71 => 'Incorrect Nature de point de vente non valide',
66
+ 74 => 'Incorrect language',
67
+ 78 => 'Incorrect country of collection',
68
+ 79 => 'Incorrect country of delivery',
69
+ 80 => 'Tracking code : Recorded parcel',
70
+ 81 => 'Tracking code : Parcel in process at Mondial Relay',
71
+ 82 => 'Tracking code : Delivered parcel',
72
+ 83 => 'Tracking code : Anomaly',
73
+ 84 => '(Reserved tracking code)',
74
+ 85 => '(Reserved tracking code)',
75
+ 86 => '(Reserved tracking code)',
76
+ 87 => '(Reserved tracking code)',
77
+ 88 => '(Reserved tracking code)',
78
+ 89 => '(Reserved tracking code)',
79
+ 92 => 'The Point Relais country code and the consignee’s country code are different',
80
+ 93 => 'No information given by the sorting plan',
81
+ 94 => 'Unknown parcel',
82
+ 95 => 'Merchant account not activated',
83
+ 97 => 'Incorrect security key',
84
+ 98 => 'Generic error (Incorrect parameters)',
85
+ 99 => 'Generic error of service system (technical). Contact MR'
86
+ }.freeze
87
+
88
+ module StatusCodes
89
+ module_function
90
+
91
+ def success?(status)
92
+ status&.zero? || (80..83).cover?(status)
93
+ end
94
+
95
+ def tracking_info_success?(status)
96
+ status&.zero? || (80..89).cover?(status)
97
+ end
98
+
99
+ def message_for(status)
100
+ STATUS_CODES[status] || 'Unknown status'
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end