shipping_connector 0.1.0 → 0.2.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
  SHA256:
3
- metadata.gz: b5dc5dd88edc69471c3d50e15f9e84e59cc604fbd4a7a33f6f37310a67e7060e
4
- data.tar.gz: 86629918a4474ab6abb378ddd6f8b3c9500eaa86a7f8d343de498edc97cf23e1
3
+ metadata.gz: 513d12edb9b1d0272c2881b3e026b5a33e8f389f99596a8421b89c898e77d07c
4
+ data.tar.gz: 15f454b5b931284bb24671cf92e40dca5215ccc4a27a72e5034b2933042c0e2a
5
5
  SHA512:
6
- metadata.gz: 6b591b23947cd52b0783bd376e3137fcadc996ba59e85cc76b3af86fa34b416f988fe3547eb790bdf67c71f24cb9f9b9c118f46407107b08b4f7b4be59bae4be
7
- data.tar.gz: '094dbffaabfc78dfd8086614e1c40e4274f0c317cde2467ddaccf9e372b15c7b4cb1b30675473c18347678f699c1427fe669ec5c97145cc3dacfb3e21bec9963'
6
+ metadata.gz: 870b5d463ebaf3877f5461736278b922869311e7617a1b2b5ce1c099a7a3f39f16c48403c54bf0ec0d3af50fd1106fba74f96aa687f4a29dbae7dc0bfd2180d5
7
+ data.tar.gz: 4521d98d28d6699082f1e85fd6963cb73254469f944c5669a005d3843f1c6bfa19017502ddaa74fd5bc12f2af0ba581612e3e5b717ec0da2a9a904aee7fb4336
@@ -46,25 +46,56 @@ module ShippingConnector
46
46
  end
47
47
  end
48
48
 
49
+ # Returns a shipment with a list of events
50
+ # @param id [String] the shipment id
51
+ # @param locale [Symbol] two-letter language code, e.g. :da or :en
52
+ # @return [Shipment] the shipment for the given id
53
+ def shipment(id, locale: :en)
54
+ # Ugh... Why is Postnord not consistent in their API...
55
+ data = get('/rest/shipment/v5/trackandtrace/ids.json',
56
+ { id: id, locale: locale })
57
+
58
+ shipment = data['shipments'].first { |s| s['shipmentId'] == id.to_s }
59
+ raise "Shipment with ID #{id} not found" unless shipment
60
+
61
+ item = shipment['items'].first { |i| i['itemId'] == id.to_s }
62
+ raise "The shipment returned no items with ID #{id}" unless item
63
+
64
+ generate_shipment(shipment['status'], item)
65
+ end
66
+
49
67
  private
50
68
 
69
+ def generate_shipment(status, item)
70
+ events = generate_events(item['events'])
71
+ Shipment.new(
72
+ id: item['itemId'],
73
+ events: events, status: convert_status(status),
74
+ status_description: item['statusText']['header']
75
+ )
76
+ end
77
+
51
78
  def auth_params
52
79
  { apikey: @options[:api_key], returnType: 'json' }
53
80
  end
54
81
 
55
82
  def get(path, params)
56
83
  response = super(path, params.merge(auth_params))
57
- JSON.parse response.body
84
+ body = JSON.parse(response.body)
85
+ return body.values.first if body.keys.first =~ /Response$/
86
+
87
+ body
58
88
  rescue Faraday::ClientError => e
59
89
  body = JSON.parse e.response[:body]
60
- raise StandardError, "Postnord error: #{body['message']}"
90
+ message = body.values.first['compositeFault']['faults'][0]
91
+ raise StandardError, "Postnord error #{message['faultCode']}: #{message['explanationText']}"
61
92
  end
62
93
 
63
94
  def find_service_point(id, arguments)
64
95
  service_point = get('/rest/businesslocation/v5/servicepoints/ids',
65
96
  {
66
97
  ids: id, countryCode: arguments[:country]
67
- })['servicePointInformationResponse']['servicePoints'].first
98
+ })['servicePoints'].first
68
99
 
69
100
  ServicePoint.new(
70
101
  id: service_point['servicePointId'], zip_code: service_point['visitingAddress']['postalCode'],
@@ -87,7 +118,7 @@ module ShippingConnector
87
118
  params[:numberOfServicePoints] = options[:limit] || 10
88
119
 
89
120
  array = get('/rest/businesslocation/v5/servicepoints/nearest/byaddress',
90
- params)['servicePointInformationResponse']['servicePoints']
121
+ params)['servicePoints']
91
122
 
92
123
  generate_service_points array
93
124
  end
@@ -99,7 +130,7 @@ module ShippingConnector
99
130
  northing: options[:latitude],
100
131
  easting: options[:longitude],
101
132
  numberOfServicePoints: options[:limit] || 10
102
- })['servicePointInformationResponse']['servicePoints']
133
+ })['servicePoints']
103
134
 
104
135
  generate_service_points array
105
136
  end
@@ -112,7 +143,7 @@ module ShippingConnector
112
143
  name: service_point['name'], city: service_point['visitingAddress']['city'],
113
144
  address: "#{service_point['visitingAddress']['streetName']} #{service_point['visitingAddress']['streetName']}",
114
145
  distance: service_point['routeDistance'], opening_hours: opening_hours(service_point['openingHours'])
115
- )
146
+ )
116
147
  end
117
148
  result
118
149
  end
@@ -126,5 +157,35 @@ module ShippingConnector
126
157
 
127
158
  ServicePoint::OpeningHours.new(hash)
128
159
  end
160
+
161
+ def generate_events(events)
162
+ array = []
163
+ events.each do |event|
164
+ array << Shipment::Event.new(
165
+ type: convert_status(event['status']),
166
+ time: convert_time(event['eventTime']),
167
+ description: event['eventDescription'],
168
+ location: event['location']['displayName']
169
+ )
170
+ end
171
+ array
172
+ end
173
+
174
+ def convert_status(status)
175
+ # FIXME: Find a good status category for 'OTHER'
176
+ hash = {
177
+ 'DELIVERED' => :delivered,
178
+ 'EN_ROUTE' => :en_route,
179
+ 'AVAILABLE_FOR_DELIVERY' => :available_for_delivery
180
+ }
181
+ return hash[status] if hash[status]
182
+
183
+ warn "Unknown status: #{status}"
184
+ :unknown
185
+ end
186
+
187
+ def convert_time(time_string)
188
+ TZInfo::Timezone.get('Europe/Copenhagen').to_local(Time.parse(time_string))
189
+ end
129
190
  end
130
191
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ShippingConnector
4
+ class Shipment
5
+ attr_reader :id, :receiver, :sender, :events, :status, :status_description
6
+
7
+ def initialize(params = {})
8
+ params.each { |key, value| instance_variable_set("@#{key}", value) }
9
+ end
10
+
11
+ class Event
12
+ attr_reader :type, :time, :description, :location
13
+
14
+ def initialize(params = {})
15
+ params.each { |key, value| instance_variable_set("@#{key}", value) }
16
+ end
17
+ end
18
+ end
19
+ end
@@ -1,9 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'faraday'
4
- require 'json'
5
- require 'active_support/core_ext/class/attribute'
6
-
7
3
  require 'shipping_connector/carrier'
8
4
  require 'shipping_connector/carriers'
9
5
  require 'shipping_connector/service_point'
6
+ require 'shipping_connector/shipment'
metadata CHANGED
@@ -1,15 +1,85 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shipping_connector
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simon Thyregod Kristensen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-25 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2021-10-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '6.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '6.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: json
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: tzinfo
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: tzinfo-data
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.0'
13
83
  description: |2
14
84
  ShippingConnector is an abstraction library that makes connecting to various shipping
15
85
  carriers' APIs easier. As with everything Ruby, the goal is to make writing code that
@@ -25,6 +95,7 @@ files:
25
95
  - lib/shipping_connector/carrier/postnord.rb
26
96
  - lib/shipping_connector/carriers.rb
27
97
  - lib/shipping_connector/service_point.rb
98
+ - lib/shipping_connector/shipment.rb
28
99
  homepage: https://github.com/sthyregod/shipping_connector
29
100
  licenses:
30
101
  - MIT