speedy-bg 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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +3 -0
- data/CODE_OF_CONDUCT.md +134 -0
- data/CONTRIBUTING.md +67 -0
- data/LICENSE.txt +21 -0
- data/README.md +150 -0
- data/SECURITY.md +29 -0
- data/docs/API.md +740 -0
- data/docs/RESPONSE_CONTRACTS.md +55 -0
- data/docs/VCR.md +161 -0
- data/docs/schema-notes.md +38 -0
- data/lib/speedy/camel_case_middleware.rb +71 -0
- data/lib/speedy/client.rb +100 -0
- data/lib/speedy/client_resources.rb +776 -0
- data/lib/speedy/collection.rb +58 -0
- data/lib/speedy/error.rb +29 -0
- data/lib/speedy/model.rb +92 -0
- data/lib/speedy/models/calculation/address_location.rb +16 -0
- data/lib/speedy/models/calculation/calculation_content.rb +15 -0
- data/lib/speedy/models/calculation/calculation_recipient.rb +15 -0
- data/lib/speedy/models/calculation/calculation_result.rb +19 -0
- data/lib/speedy/models/calculation/calculation_sender.rb +16 -0
- data/lib/speedy/models/calculation/calculation_service.rb +16 -0
- data/lib/speedy/models/clients/client.rb +21 -0
- data/lib/speedy/models/clients/cod_contract_info.rb +16 -0
- data/lib/speedy/models/clients/cod_international_annex.rb +12 -0
- data/lib/speedy/models/clients/contract_info.rb +16 -0
- data/lib/speedy/models/clients/requirement.rb +12 -0
- data/lib/speedy/models/clients/special_delivery_requirements.rb +12 -0
- data/lib/speedy/models/common/address.rb +36 -0
- data/lib/speedy/models/error.rb +37 -0
- data/lib/speedy/models/location/address_nomenclature_type.rb +12 -0
- data/lib/speedy/models/location/block.rb +15 -0
- data/lib/speedy/models/location/complex.rb +23 -0
- data/lib/speedy/models/location/country.rb +25 -0
- data/lib/speedy/models/location/find_office_response.rb +12 -0
- data/lib/speedy/models/location/find_site_response.rb +12 -0
- data/lib/speedy/models/location/get_office_response.rb +12 -0
- data/lib/speedy/models/location/get_site_response.rb +12 -0
- data/lib/speedy/models/location/office.rb +41 -0
- data/lib/speedy/models/location/office_result.rb +13 -0
- data/lib/speedy/models/location/office_working_time_schedule.rb +15 -0
- data/lib/speedy/models/location/point_of_interest.rb +22 -0
- data/lib/speedy/models/location/postcode.rb +12 -0
- data/lib/speedy/models/location/routing_information.rb +14 -0
- data/lib/speedy/models/location/site.rb +30 -0
- data/lib/speedy/models/location/state.rb +17 -0
- data/lib/speedy/models/location/street.rb +23 -0
- data/lib/speedy/models/location/tour.rb +14 -0
- data/lib/speedy/models/payments/payout.rb +20 -0
- data/lib/speedy/models/payments/payout_details.rb +23 -0
- data/lib/speedy/models/pickup/pickup_order.rb +16 -0
- data/lib/speedy/models/pickup/terms_response.rb +12 -0
- data/lib/speedy/models/print/extended_print_response.rb +13 -0
- data/lib/speedy/models/print/label_info.rb +19 -0
- data/lib/speedy/models/print/label_info_response.rb +12 -0
- data/lib/speedy/models/print/parcel_to_print_additional_barcode.rb +14 -0
- data/lib/speedy/models/print/print_response.rb +12 -0
- data/lib/speedy/models/response.rb +13 -0
- data/lib/speedy/models/services/additional_courier_service.rb +11 -0
- data/lib/speedy/models/services/additional_courier_services.rb +21 -0
- data/lib/speedy/models/services/courier_service.rb +19 -0
- data/lib/speedy/models/services/extended_courier_service.rb +13 -0
- data/lib/speedy/models/shipments/bank_account.rb +12 -0
- data/lib/speedy/models/shipments/barcode_information.rb +20 -0
- data/lib/speedy/models/shipments/cod_payment.rb +12 -0
- data/lib/speedy/models/shipments/content.rb +20 -0
- data/lib/speedy/models/shipments/create_shipment_response.rb +16 -0
- data/lib/speedy/models/shipments/created_shipment_parcel.rb +14 -0
- data/lib/speedy/models/shipments/external_carrier_parcel_number.rb +12 -0
- data/lib/speedy/models/shipments/goods_item.rb +16 -0
- data/lib/speedy/models/shipments/money_transfer_premium.rb +13 -0
- data/lib/speedy/models/shipments/parcel.rb +22 -0
- data/lib/speedy/models/shipments/payment.rb +16 -0
- data/lib/speedy/models/shipments/primary_shipment.rb +12 -0
- data/lib/speedy/models/shipments/recipient.rb +21 -0
- data/lib/speedy/models/shipments/return_amounts.rb +11 -0
- data/lib/speedy/models/shipments/secondary_shipment.rb +18 -0
- data/lib/speedy/models/shipments/sender.rb +21 -0
- data/lib/speedy/models/shipments/shipment.rb +28 -0
- data/lib/speedy/models/shipments/shipment_additional_services.rb +17 -0
- data/lib/speedy/models/shipments/shipment_address.rb +10 -0
- data/lib/speedy/models/shipments/shipment_cod_additional_service.rb +20 -0
- data/lib/speedy/models/shipments/shipment_cod_fiscal_receipt_item.rb +14 -0
- data/lib/speedy/models/shipments/shipment_content.rb +24 -0
- data/lib/speedy/models/shipments/shipment_declared_value_additional_service.rb +13 -0
- data/lib/speedy/models/shipments/shipment_delivery.rb +14 -0
- data/lib/speedy/models/shipments/shipment_discount_card_id.rb +12 -0
- data/lib/speedy/models/shipments/shipment_electronic_return_receipt_additional_service.rb +14 -0
- data/lib/speedy/models/shipments/shipment_obpd.rb +13 -0
- data/lib/speedy/models/shipments/shipment_parcel.rb +23 -0
- data/lib/speedy/models/shipments/shipment_parcel_number.rb +12 -0
- data/lib/speedy/models/shipments/shipment_parcel_ref.rb +13 -0
- data/lib/speedy/models/shipments/shipment_parcel_size.rb +13 -0
- data/lib/speedy/models/shipments/shipment_payment.rb +17 -0
- data/lib/speedy/models/shipments/shipment_phone_number.rb +12 -0
- data/lib/speedy/models/shipments/shipment_price.rb +23 -0
- data/lib/speedy/models/shipments/shipment_price_amount.rb +13 -0
- data/lib/speedy/models/shipments/shipment_recipient.rb +14 -0
- data/lib/speedy/models/shipments/shipment_return_additional_services.rb +20 -0
- data/lib/speedy/models/shipments/shipment_return_receipt_additional_service.rb +14 -0
- data/lib/speedy/models/shipments/shipment_return_voucher_additional_service.rb +14 -0
- data/lib/speedy/models/shipments/shipment_rod_additional_service.rb +15 -0
- data/lib/speedy/models/shipments/shipment_rop_additional_service.rb +12 -0
- data/lib/speedy/models/shipments/shipment_rop_additional_service_line.rb +12 -0
- data/lib/speedy/models/shipments/shipment_sender.rb +23 -0
- data/lib/speedy/models/shipments/shipment_service.rb +17 -0
- data/lib/speedy/models/shipments/shipment_swap_additional_service.rb +17 -0
- data/lib/speedy/models/shipments/update_shipment_response.rb +10 -0
- data/lib/speedy/models/tracking/bulk_tracking_data_file.rb +14 -0
- data/lib/speedy/models/tracking/external_carrier_parcel_number_details.rb +13 -0
- data/lib/speedy/models/tracking/tracked_parcel.rb +21 -0
- data/lib/speedy/models/tracking/tracked_parcel_operation.rb +22 -0
- data/lib/speedy/models/tracking/tracked_parcel_operation_additional_info.rb +17 -0
- data/lib/speedy/models/tracking/tracked_parcel_operation_additional_info_predict.rb +14 -0
- data/lib/speedy/models/tracking/tracked_parcel_operation_additional_info_recipient.rb +14 -0
- data/lib/speedy/models/validation/validation_response.rb +14 -0
- data/lib/speedy/resource_attributes.rb +87 -0
- data/lib/speedy/service_resource.rb +94 -0
- data/lib/speedy/services/calculation.rb +22 -0
- data/lib/speedy/services/clients.rb +40 -0
- data/lib/speedy/services/courier_services.rb +25 -0
- data/lib/speedy/services/location/block.rb +32 -0
- data/lib/speedy/services/location/complex.rb +39 -0
- data/lib/speedy/services/location/country.rb +70 -0
- data/lib/speedy/services/location/office.rb +50 -0
- data/lib/speedy/services/location/point_of_interest.rb +39 -0
- data/lib/speedy/services/location/postcode.rb +25 -0
- data/lib/speedy/services/location/site.rb +77 -0
- data/lib/speedy/services/location/state.rb +46 -0
- data/lib/speedy/services/location/street.rb +39 -0
- data/lib/speedy/services/location.rb +11 -0
- data/lib/speedy/services/payments.rb +19 -0
- data/lib/speedy/services/pickup.rb +38 -0
- data/lib/speedy/services/print.rb +58 -0
- data/lib/speedy/services/shipments/shipment.rb +120 -0
- data/lib/speedy/services/shipments.rb +11 -0
- data/lib/speedy/services/tracking.rb +26 -0
- data/lib/speedy/services/validation/address.rb +26 -0
- data/lib/speedy/services/validation/general.rb +37 -0
- data/lib/speedy/services/validation.rb +11 -0
- data/lib/speedy/transport_error.rb +17 -0
- data/lib/speedy/util.rb +67 -0
- data/lib/speedy/version.rb +5 -0
- data/lib/speedy-bg.rb +6 -0
- data/lib/speedy.rb +203 -0
- data/sig/speedy.rbs +374 -0
- metadata +227 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'date'
|
|
4
|
+
|
|
5
|
+
module Speedy
|
|
6
|
+
module ResourceAttributes
|
|
7
|
+
TYPE_CASTERS = {
|
|
8
|
+
integer: ->(value) { blank?(value) ? nil : value.to_i },
|
|
9
|
+
string: ->(value) { value&.to_s },
|
|
10
|
+
boolean: lambda do |value|
|
|
11
|
+
next nil if blank?(value)
|
|
12
|
+
next false if value == false || %w[false 0 no off].include?(value.to_s.downcase)
|
|
13
|
+
|
|
14
|
+
true
|
|
15
|
+
end,
|
|
16
|
+
float: ->(value) { blank?(value) ? nil : value.to_f }
|
|
17
|
+
}.freeze
|
|
18
|
+
|
|
19
|
+
def self.blank?(value)
|
|
20
|
+
value.nil? || (value.is_a?(String) && value.strip.empty?)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.included(base)
|
|
24
|
+
base.extend(ClassMethods)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
module ClassMethods
|
|
28
|
+
def fields
|
|
29
|
+
@fields ||= {}
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def field(name, opts = {})
|
|
33
|
+
fields[name] = opts
|
|
34
|
+
|
|
35
|
+
define_method(name) do
|
|
36
|
+
cast_attribute(@attributes[name], opts[:type], opts[:of])
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
define_method("#{name}=") do |value|
|
|
40
|
+
@attributes[name] = cast_attribute(value, opts[:type], opts[:of])
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def cast_attribute(value, type, collection_type = nil)
|
|
48
|
+
return cast_primitive(value, type) if TYPE_CASTERS.key?(type)
|
|
49
|
+
return cast_date(value) if type == :date
|
|
50
|
+
return cast_array(value, collection_type) if type == :array
|
|
51
|
+
return cast_hash(value, collection_type) if type == :hash
|
|
52
|
+
|
|
53
|
+
return cast_model(value, type) if type.is_a?(Class)
|
|
54
|
+
|
|
55
|
+
value
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def cast_primitive(value, type)
|
|
59
|
+
TYPE_CASTERS.fetch(type).call(value)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def cast_model(value, type)
|
|
63
|
+
value.nil? || value.is_a?(type) ? value : type.new(value)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def cast_date(value)
|
|
67
|
+
return value if value.nil? || value.is_a?(Date)
|
|
68
|
+
|
|
69
|
+
Date.parse(value.to_s)
|
|
70
|
+
rescue StandardError
|
|
71
|
+
value
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def cast_array(value, collection_type)
|
|
75
|
+
values = Array(value)
|
|
76
|
+
return values unless collection_type.is_a?(Class)
|
|
77
|
+
|
|
78
|
+
values.map { |item| item.is_a?(collection_type) ? item : collection_type.new(item) }
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def cast_hash(value, value_type)
|
|
82
|
+
return value unless value.is_a?(Hash) && value_type.is_a?(Class)
|
|
83
|
+
|
|
84
|
+
value.transform_values { |item| item.is_a?(value_type) ? item : value_type.new(item) }
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Speedy
|
|
4
|
+
class ServiceResource
|
|
5
|
+
attr_reader :client
|
|
6
|
+
|
|
7
|
+
class << self
|
|
8
|
+
def resource_path(value = nil)
|
|
9
|
+
return @resource_path unless value
|
|
10
|
+
|
|
11
|
+
@resource_path = value
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
ERROR_MESSAGES = {
|
|
16
|
+
400 => 'Your request was malformed.',
|
|
17
|
+
401 => 'You did not supply valid authentication credentials.',
|
|
18
|
+
403 => 'You are not allowed to perform that action.',
|
|
19
|
+
404 => 'No results were found for your request.',
|
|
20
|
+
429 => 'Your request exceeded the API rate limit.',
|
|
21
|
+
500 => 'We were unable to perform the request due to server-side problems.',
|
|
22
|
+
503 => 'The Speedy API is currently unavailable.'
|
|
23
|
+
}.freeze
|
|
24
|
+
|
|
25
|
+
def initialize(client: Speedy::Client.instance)
|
|
26
|
+
message = 'Speedy::Client is not configured. Call `Speedy::Client.configure` first.'
|
|
27
|
+
|
|
28
|
+
@client = client || raise(message)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def resource_url
|
|
32
|
+
self.class.resource_path
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def get(url = nil, params: {}, headers: {})
|
|
38
|
+
response_for(with_transport_errors { client.connection.get(url_for(url), params, headers) })
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def post(url = nil, body: nil, headers: {})
|
|
42
|
+
response_for(with_transport_errors { client.connection.post(url_for(url), request_body(body), headers) })
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def delete(url = nil, params: {}, headers: {})
|
|
46
|
+
response_for(with_transport_errors { client.connection.delete(url_for(url), params, headers) })
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def with_transport_errors
|
|
50
|
+
yield
|
|
51
|
+
rescue Faraday::TimeoutError => e
|
|
52
|
+
raise TimeoutError, 'Speedy API request timed out.', cause: e
|
|
53
|
+
rescue Faraday::ConnectionFailed => e
|
|
54
|
+
raise ConnectionError, 'Could not connect to the Speedy API.', cause: e
|
|
55
|
+
rescue Faraday::SSLError => e
|
|
56
|
+
raise SSLError, 'Speedy API TLS connection failed.', cause: e
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def url_for(url)
|
|
60
|
+
[resource_url, url].compact.reject(&:empty?).join('/')
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def request_body(body)
|
|
64
|
+
client.credentials.merge(body || {})
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def response_for(response)
|
|
68
|
+
error = error_from(response.body)
|
|
69
|
+
raise Error.new(error: error, status: response.status) if error && !successful_response?(response)
|
|
70
|
+
|
|
71
|
+
error_message = ERROR_MESSAGES[response.status]
|
|
72
|
+
raise Error.new(error_message, status: response.status) if error_message
|
|
73
|
+
raise Error.new(status: response.status) unless successful_response?(response)
|
|
74
|
+
|
|
75
|
+
response
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def collection(response, model)
|
|
79
|
+
model.collection(response.body)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def resource(response, model, key: nil)
|
|
83
|
+
model.build(response.body, key: key)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def error_from(body)
|
|
87
|
+
Speedy::Models::Error.build_from(body)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def successful_response?(response)
|
|
91
|
+
response.status.to_i.between?(200, 299)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Speedy
|
|
4
|
+
module Services
|
|
5
|
+
class Calculation < Speedy::ServiceResource
|
|
6
|
+
resource_path 'calculate'
|
|
7
|
+
|
|
8
|
+
# POST `/calculate`
|
|
9
|
+
def calculate(recipient:, service:, content:, payment:, sender: nil, **options)
|
|
10
|
+
response = post(body: {
|
|
11
|
+
sender: sender,
|
|
12
|
+
recipient: recipient,
|
|
13
|
+
service: service,
|
|
14
|
+
content: content,
|
|
15
|
+
payment: payment
|
|
16
|
+
}.merge(options).compact)
|
|
17
|
+
|
|
18
|
+
collection(response, Speedy::Models::Calculation::CalculationResult)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Speedy
|
|
4
|
+
module Services
|
|
5
|
+
class Clients < Speedy::ServiceResource
|
|
6
|
+
resource_path 'client'
|
|
7
|
+
|
|
8
|
+
def get(id)
|
|
9
|
+
response = post(id.to_s)
|
|
10
|
+
resource(response, Speedy::Models::Clients::Client, key: :client)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def own_id
|
|
14
|
+
response = post
|
|
15
|
+
response.body[:client_id] || response.body['client_id'] || response.body['clientId']
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def contract_clients
|
|
19
|
+
response = post('contract')
|
|
20
|
+
collection(response, Speedy::Models::Clients::Client)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def create_contact(**attributes)
|
|
24
|
+
response = post('contact', body: attributes.compact)
|
|
25
|
+
|
|
26
|
+
response.body[:client_id] || response.body['client_id'] || response.body['clientId']
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def contact_by_external_id(id:, secret_key:)
|
|
30
|
+
response = post("contact/external/#{id}", body: { secret_key: secret_key })
|
|
31
|
+
resource(response, Speedy::Models::Clients::Client, key: :client)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def contract_info
|
|
35
|
+
response = post('contract/info')
|
|
36
|
+
resource(response, Speedy::Models::Clients::ContractInfo)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Speedy
|
|
4
|
+
module Services
|
|
5
|
+
class CourierServices < Speedy::ServiceResource
|
|
6
|
+
resource_path 'services'
|
|
7
|
+
|
|
8
|
+
# POST `/services`
|
|
9
|
+
def all(date: nil)
|
|
10
|
+
response = post(body: { date: date }.compact)
|
|
11
|
+
|
|
12
|
+
collection(response, Speedy::Models::Services::CourierService)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# POST `/services/destination`
|
|
16
|
+
def for_destination(sender:, recipient:, date: nil)
|
|
17
|
+
response = post('destination', body: {
|
|
18
|
+
date: date, sender: sender, recipient: recipient
|
|
19
|
+
}.compact)
|
|
20
|
+
|
|
21
|
+
collection(response, Speedy::Models::Services::ExtendedCourierService)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'csv'
|
|
4
|
+
|
|
5
|
+
module Speedy
|
|
6
|
+
module Services
|
|
7
|
+
module Location
|
|
8
|
+
class Block < Speedy::ServiceResource
|
|
9
|
+
resource_path 'location/block'
|
|
10
|
+
|
|
11
|
+
# POST `/location/block`
|
|
12
|
+
def find(site_id:, name: nil)
|
|
13
|
+
response = post(body: { site_id: site_id, name: name }.compact)
|
|
14
|
+
|
|
15
|
+
collection(response, Speedy::Models::Location::Block)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# POST `/location/block/csv/{countryId}`
|
|
19
|
+
def all(country_id:)
|
|
20
|
+
response = post("csv/#{country_id}")
|
|
21
|
+
rows = CSV.parse(response.body.to_s).filter_map do |row|
|
|
22
|
+
next if row.compact.empty? || row.first.to_s == 'siteId'
|
|
23
|
+
|
|
24
|
+
%i[site_id name name_en].zip(row).to_h
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
Speedy::Models::Location::Block.collection(rows)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'csv'
|
|
4
|
+
|
|
5
|
+
module Speedy
|
|
6
|
+
module Services
|
|
7
|
+
module Location
|
|
8
|
+
class Complex < Speedy::ServiceResource
|
|
9
|
+
resource_path 'location/complex'
|
|
10
|
+
|
|
11
|
+
# POST `/location/complex/{id}`
|
|
12
|
+
def get(id)
|
|
13
|
+
response = post(id.to_s)
|
|
14
|
+
|
|
15
|
+
resource(response, Speedy::Models::Location::Complex, key: :complex)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# POST `/location/complex`
|
|
19
|
+
def find(site_id:, name: nil, type: nil)
|
|
20
|
+
response = post(body: { site_id: site_id, name: name, type: type }.compact)
|
|
21
|
+
|
|
22
|
+
collection(response, Speedy::Models::Location::Complex)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# POST `/location/complex/csv/{countryId}`
|
|
26
|
+
def all(country_id:)
|
|
27
|
+
response = post("csv/#{country_id}")
|
|
28
|
+
rows = CSV.parse(response.body.to_s).filter_map do |row|
|
|
29
|
+
next if row.compact.empty? || row.first.to_s == 'id'
|
|
30
|
+
|
|
31
|
+
%i[id site_id type type_en name name_en actual_id].zip(row).to_h
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
Speedy::Models::Location::Complex.collection(rows)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'csv'
|
|
4
|
+
|
|
5
|
+
module Speedy
|
|
6
|
+
module Services
|
|
7
|
+
module Location
|
|
8
|
+
class Country < Speedy::ServiceResource
|
|
9
|
+
resource_path 'location/country'
|
|
10
|
+
|
|
11
|
+
# POST `/location/country`
|
|
12
|
+
def find(name: nil, iso_alpha2: nil, iso_alpha3: nil)
|
|
13
|
+
response = post(body: {
|
|
14
|
+
name: name, iso_alpha2: iso_alpha2, iso_alpha3: iso_alpha3
|
|
15
|
+
}.compact)
|
|
16
|
+
|
|
17
|
+
collection(response, Speedy::Models::Location::Country)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# POST `/location/country/{id}`
|
|
21
|
+
def get(id)
|
|
22
|
+
response = post(id.to_s)
|
|
23
|
+
|
|
24
|
+
resource(response, Speedy::Models::Location::Country, key: :country)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# POST `/location/country/csv`
|
|
28
|
+
def all
|
|
29
|
+
response = post('csv')
|
|
30
|
+
Speedy::Models::Location::Country.collection(csv_countries(response.body))
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
CSV_FIELDS = %i[
|
|
34
|
+
id name name_en iso_alpha2 iso_alpha3 post_code_formats require_state address_type
|
|
35
|
+
currency_code default_office_id street_types street_types_en complex_types
|
|
36
|
+
complex_types_en site_nomen
|
|
37
|
+
].freeze
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def csv_countries(body)
|
|
42
|
+
CSV.parse(body.to_s).filter_map do |row|
|
|
43
|
+
next if row.compact.empty? || row.first.to_s == 'id'
|
|
44
|
+
|
|
45
|
+
country_attributes(row)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def country_attributes(row)
|
|
50
|
+
attributes = CSV_FIELDS.zip(row).to_h
|
|
51
|
+
attributes[:post_code_formats] = csv_list(attributes[:post_code_formats])
|
|
52
|
+
%i[street complex].each do |kind|
|
|
53
|
+
attributes[:"#{kind}_types"] = nomenclature(
|
|
54
|
+
attributes.delete(:"#{kind}_types"), attributes.delete(:"#{kind}_types_en")
|
|
55
|
+
)
|
|
56
|
+
end
|
|
57
|
+
attributes
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def csv_list(value)
|
|
61
|
+
value.to_s.split(',').map(&:strip).reject(&:empty?)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def nomenclature(names, english_names)
|
|
65
|
+
csv_list(names).zip(csv_list(english_names)).map { |name, name_en| { name: name, name_en: name_en } }
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Speedy
|
|
4
|
+
module Services
|
|
5
|
+
module Location
|
|
6
|
+
class Office < Speedy::ServiceResource
|
|
7
|
+
include Speedy::Services::Location
|
|
8
|
+
|
|
9
|
+
resource_path 'location/office'
|
|
10
|
+
|
|
11
|
+
# POST `/location/office`
|
|
12
|
+
def find(country_id: nil, site_id: nil, site_name: nil, name: nil, limit: nil)
|
|
13
|
+
response = post(body: {
|
|
14
|
+
country_id: country_id,
|
|
15
|
+
site_id: site_id,
|
|
16
|
+
site_name: site_name,
|
|
17
|
+
name: name,
|
|
18
|
+
limit: limit
|
|
19
|
+
}.compact)
|
|
20
|
+
|
|
21
|
+
collection(response, Speedy::Models::Location::Office)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# POST `/location/office/{id}`
|
|
25
|
+
def get(id)
|
|
26
|
+
response = post(id.to_s)
|
|
27
|
+
|
|
28
|
+
resource(response, Speedy::Models::Location::GetOfficeResponse)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# POST `/location/office/nearest-offices`
|
|
32
|
+
def nearest(address:, distance: nil, limit: nil, office_type: nil, office_features: nil)
|
|
33
|
+
response = post('nearest-offices', body: {
|
|
34
|
+
address: address,
|
|
35
|
+
distance: distance,
|
|
36
|
+
limit: limit,
|
|
37
|
+
office_type: office_type,
|
|
38
|
+
office_features: office_features
|
|
39
|
+
}.compact)
|
|
40
|
+
|
|
41
|
+
collection(response, Speedy::Models::Location::OfficeResult)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
alias find_offices find
|
|
45
|
+
alias get_office get
|
|
46
|
+
alias nearest_offices nearest
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'csv'
|
|
4
|
+
|
|
5
|
+
module Speedy
|
|
6
|
+
module Services
|
|
7
|
+
module Location
|
|
8
|
+
class PointOfInterest < Speedy::ServiceResource
|
|
9
|
+
resource_path 'location/poi'
|
|
10
|
+
|
|
11
|
+
# POST `/location/poi/{id}`
|
|
12
|
+
def get(id)
|
|
13
|
+
response = post(id.to_s)
|
|
14
|
+
|
|
15
|
+
resource(response, Speedy::Models::Location::PointOfInterest, key: :poi)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# POST `/location/poi`
|
|
19
|
+
def find(site_id:, name: nil)
|
|
20
|
+
response = post(body: { site_id: site_id, name: name }.compact)
|
|
21
|
+
|
|
22
|
+
collection(response, Speedy::Models::Location::PointOfInterest)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# POST `/location/poi/csv/{countryId}`
|
|
26
|
+
def all(country_id:)
|
|
27
|
+
response = post("csv/#{country_id}")
|
|
28
|
+
rows = CSV.parse(response.body.to_s).filter_map do |row|
|
|
29
|
+
next if row.compact.empty? || row.first.to_s == 'id'
|
|
30
|
+
|
|
31
|
+
%i[id site_id name name_en address address_en x y type type_en].zip(row).to_h
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
Speedy::Models::Location::PointOfInterest.collection(rows)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'csv'
|
|
4
|
+
|
|
5
|
+
module Speedy
|
|
6
|
+
module Services
|
|
7
|
+
module Location
|
|
8
|
+
class Postcode < Speedy::ServiceResource
|
|
9
|
+
resource_path 'location/postcode'
|
|
10
|
+
|
|
11
|
+
# POST `/location/postcode/csv/{countryId}`
|
|
12
|
+
def all(country_id:)
|
|
13
|
+
response = post("csv/#{country_id}")
|
|
14
|
+
rows = CSV.parse(response.body.to_s).filter_map do |row|
|
|
15
|
+
next if row.compact.empty? || row.first.to_s == 'postcode'
|
|
16
|
+
|
|
17
|
+
%i[postcode site_id].zip(row).to_h
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
Speedy::Models::Location::Postcode.collection(rows)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'csv'
|
|
4
|
+
|
|
5
|
+
module Speedy
|
|
6
|
+
module Services
|
|
7
|
+
module Location
|
|
8
|
+
class Site < Speedy::ServiceResource
|
|
9
|
+
include Speedy::Services::Location
|
|
10
|
+
|
|
11
|
+
resource_path 'location/site'
|
|
12
|
+
|
|
13
|
+
# POST `/location/site`
|
|
14
|
+
def find(country_id: nil, name: nil, post_code: nil, type: nil, municipality: nil, region: nil)
|
|
15
|
+
response = post(body: {
|
|
16
|
+
country_id: country_id,
|
|
17
|
+
name: name,
|
|
18
|
+
post_code: post_code,
|
|
19
|
+
type: type,
|
|
20
|
+
municipality: municipality,
|
|
21
|
+
region: region
|
|
22
|
+
}.compact)
|
|
23
|
+
|
|
24
|
+
collection(response, Speedy::Models::Location::Site)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# POST `/location/site/{id}`
|
|
28
|
+
def get(id)
|
|
29
|
+
response = post(id.to_s)
|
|
30
|
+
|
|
31
|
+
resource(response, Speedy::Models::Location::GetSiteResponse)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# POST `/location/site/csv/{countryId}`
|
|
35
|
+
def all(country_id:)
|
|
36
|
+
response = post("csv/#{country_id}")
|
|
37
|
+
|
|
38
|
+
Speedy::Models::Location::Site.collection(csv_sites(response.body))
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
alias find_sites find
|
|
42
|
+
alias get_site get
|
|
43
|
+
|
|
44
|
+
CSV_FIELDS = %i[
|
|
45
|
+
id
|
|
46
|
+
country_id
|
|
47
|
+
main_site_id
|
|
48
|
+
type
|
|
49
|
+
type_en
|
|
50
|
+
name
|
|
51
|
+
name_en
|
|
52
|
+
municipality
|
|
53
|
+
municipality_en
|
|
54
|
+
region
|
|
55
|
+
region_en
|
|
56
|
+
post_code
|
|
57
|
+
address_nomenclature
|
|
58
|
+
x
|
|
59
|
+
y
|
|
60
|
+
serving_days
|
|
61
|
+
serving_office_id
|
|
62
|
+
serving_hub_office_id
|
|
63
|
+
].freeze
|
|
64
|
+
|
|
65
|
+
private
|
|
66
|
+
|
|
67
|
+
def csv_sites(body)
|
|
68
|
+
CSV.parse(body.to_s).filter_map do |row|
|
|
69
|
+
next if row.compact.empty? || row.first.to_s == 'id'
|
|
70
|
+
|
|
71
|
+
CSV_FIELDS.zip(row).to_h
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'csv'
|
|
4
|
+
|
|
5
|
+
module Speedy
|
|
6
|
+
module Services
|
|
7
|
+
module Location
|
|
8
|
+
class State < Speedy::ServiceResource
|
|
9
|
+
include Speedy::Services::Location
|
|
10
|
+
|
|
11
|
+
resource_path 'location/state'
|
|
12
|
+
|
|
13
|
+
# POST `/location/state/{id}`
|
|
14
|
+
def get(id)
|
|
15
|
+
response = post(id.to_s)
|
|
16
|
+
|
|
17
|
+
resource(response, Speedy::Models::Location::State, key: :state)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# POST `/location/state`
|
|
21
|
+
def find(country_id: nil, name: nil)
|
|
22
|
+
response = post(body: {
|
|
23
|
+
country_id: country_id,
|
|
24
|
+
name: name
|
|
25
|
+
}.compact)
|
|
26
|
+
|
|
27
|
+
collection(response, Speedy::Models::Location::State)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# POST `/location/state/csv/{countryId}`
|
|
31
|
+
def all(country_id:)
|
|
32
|
+
response = post("csv/#{country_id}")
|
|
33
|
+
rows = CSV.parse(response.body.to_s).filter_map do |row|
|
|
34
|
+
next if row.compact.empty? || row.first.to_s == 'id'
|
|
35
|
+
|
|
36
|
+
%i[id name name_en state_alpha country_id].zip(row).to_h
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
Speedy::Models::Location::State.collection(rows)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
alias get_all_states all
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'csv'
|
|
4
|
+
|
|
5
|
+
module Speedy
|
|
6
|
+
module Services
|
|
7
|
+
module Location
|
|
8
|
+
class Street < Speedy::ServiceResource
|
|
9
|
+
resource_path 'location/street'
|
|
10
|
+
|
|
11
|
+
# POST `/location/street`
|
|
12
|
+
def find(site_id:, name: nil, type: nil)
|
|
13
|
+
response = post(body: { site_id: site_id, name: name, type: type }.compact)
|
|
14
|
+
|
|
15
|
+
collection(response, Speedy::Models::Location::Street)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# POST `/location/street/{id}`
|
|
19
|
+
def get(id)
|
|
20
|
+
response = post(id.to_s)
|
|
21
|
+
|
|
22
|
+
resource(response, Speedy::Models::Location::Street, key: :street)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# POST `/location/street/csv/{countryId}`
|
|
26
|
+
def all(country_id:)
|
|
27
|
+
response = post("csv/#{country_id}")
|
|
28
|
+
rows = CSV.parse(response.body.to_s).filter_map do |row|
|
|
29
|
+
next if row.compact.empty? || row.first.to_s == 'id'
|
|
30
|
+
|
|
31
|
+
%i[id site_id type type_en name name_en actual_id].zip(row).to_h
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
Speedy::Models::Location::Street.collection(rows)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|