newgistics 1.0.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/.codeclimate.yml +25 -0
- data/.env.sample +2 -0
- data/.gitignore +15 -0
- data/.rspec +2 -0
- data/.ruby-version +1 -0
- data/.simplecov +4 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +187 -0
- data/Rakefile +6 -0
- data/bin/console +16 -0
- data/bin/setup +8 -0
- data/lib/newgistics.rb +68 -0
- data/lib/newgistics/api.rb +26 -0
- data/lib/newgistics/configuration.rb +23 -0
- data/lib/newgistics/customer.rb +20 -0
- data/lib/newgistics/default_logger.rb +11 -0
- data/lib/newgistics/errors.rb +4 -0
- data/lib/newgistics/fee.rb +9 -0
- data/lib/newgistics/inbound_return.rb +29 -0
- data/lib/newgistics/inventory.rb +22 -0
- data/lib/newgistics/item.rb +19 -0
- data/lib/newgistics/order.rb +32 -0
- data/lib/newgistics/product.rb +30 -0
- data/lib/newgistics/query.rb +43 -0
- data/lib/newgistics/requests/cancel_shipment.rb +70 -0
- data/lib/newgistics/requests/post_inbound_return.rb +76 -0
- data/lib/newgistics/requests/post_shipment.rb +121 -0
- data/lib/newgistics/requests/search.rb +21 -0
- data/lib/newgistics/requests/update_shipment_contents.rb +74 -0
- data/lib/newgistics/response_handlers/cancel_shipment.rb +25 -0
- data/lib/newgistics/response_handlers/post_errors.rb +40 -0
- data/lib/newgistics/response_handlers/post_inbound_return.rb +25 -0
- data/lib/newgistics/response_handlers/post_shipment.rb +25 -0
- data/lib/newgistics/response_handlers/search.rb +57 -0
- data/lib/newgistics/response_handlers/update_shipment_contents.rb +25 -0
- data/lib/newgistics/return.rb +40 -0
- data/lib/newgistics/shipment.rb +79 -0
- data/lib/newgistics/shipment_cancellation.rb +24 -0
- data/lib/newgistics/shipment_update.rb +24 -0
- data/lib/newgistics/string_helper.rb +13 -0
- data/lib/newgistics/time_zone.rb +31 -0
- data/lib/newgistics/timestamp.rb +31 -0
- data/lib/newgistics/version.rb +3 -0
- data/lib/newgistics/warehouse.rb +14 -0
- data/lib/newgistics/xml_marshaller.rb +72 -0
- data/newgistics.gemspec +37 -0
- metadata +263 -0
@@ -0,0 +1,21 @@
|
|
1
|
+
module Newgistics
|
2
|
+
module Requests
|
3
|
+
class Search
|
4
|
+
attr_reader :path, :params
|
5
|
+
|
6
|
+
def initialize(path)
|
7
|
+
@path = path
|
8
|
+
end
|
9
|
+
|
10
|
+
def params=(params)
|
11
|
+
@params = params.merge(key: Newgistics.configuration.api_key)
|
12
|
+
end
|
13
|
+
|
14
|
+
def body
|
15
|
+
params.
|
16
|
+
map { |k,v| [StringHelper.camelize(k, upcase_first: false), v] }.
|
17
|
+
to_h
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module Newgistics
|
2
|
+
module Requests
|
3
|
+
class UpdateShipmentContents
|
4
|
+
attr_reader :shipment_update, :response_handler
|
5
|
+
|
6
|
+
def initialize(shipment_update, response_handler: nil)
|
7
|
+
@shipment_update = shipment_update
|
8
|
+
@response_handler = response_handler || default_response_handler
|
9
|
+
end
|
10
|
+
|
11
|
+
def path
|
12
|
+
'/update_shipment_contents.aspx'
|
13
|
+
end
|
14
|
+
|
15
|
+
def body
|
16
|
+
xml_builder.to_xml
|
17
|
+
end
|
18
|
+
|
19
|
+
def perform
|
20
|
+
Newgistics.api.post(self, response_handler)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def default_response_handler
|
26
|
+
ResponseHandlers::UpdateShipmentContents.new(shipment_update)
|
27
|
+
end
|
28
|
+
|
29
|
+
def xml_builder
|
30
|
+
Nokogiri::XML::Builder.new do |xml|
|
31
|
+
shipment_update_xml(xml)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def shipment_update_xml(xml)
|
36
|
+
xml.Shipment(shipment_update_attributes) do
|
37
|
+
add_items_xml(shipment_update.add_items, xml)
|
38
|
+
remove_items_xml(shipment_update.remove_items, xml)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def api_key
|
43
|
+
Newgistics.configuration.api_key
|
44
|
+
end
|
45
|
+
|
46
|
+
def shipment_update_attributes
|
47
|
+
{
|
48
|
+
apiKey: api_key,
|
49
|
+
id: shipment_update.id,
|
50
|
+
orderID: shipment_update.order_id
|
51
|
+
}.reject { |_k, v| v.nil? || v.empty? }
|
52
|
+
end
|
53
|
+
|
54
|
+
def add_items_xml(items, xml)
|
55
|
+
xml.AddItems do
|
56
|
+
items.each { |item| item_xml(item, xml) }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def remove_items_xml(items, xml)
|
61
|
+
xml.RemoveItems do
|
62
|
+
items.each { |item| item_xml(item, xml) }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def item_xml(item, xml)
|
67
|
+
xml.Item do
|
68
|
+
xml.SKU item.sku
|
69
|
+
xml.Qty item.qty
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Newgistics
|
2
|
+
module ResponseHandlers
|
3
|
+
class CancelShipment
|
4
|
+
attr_reader :shipment
|
5
|
+
|
6
|
+
def initialize(shipment)
|
7
|
+
@shipment = shipment
|
8
|
+
end
|
9
|
+
|
10
|
+
def handle(response)
|
11
|
+
PostErrors.new(shipment).handle(response)
|
12
|
+
if shipment.errors.empty?
|
13
|
+
handle_successful_response(response)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def handle_successful_response(response)
|
20
|
+
xml = Nokogiri::XML(response.body)
|
21
|
+
shipment.success = xml.at_css('success').text
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Newgistics
|
2
|
+
module ResponseHandlers
|
3
|
+
class PostErrors
|
4
|
+
attr_reader :model
|
5
|
+
|
6
|
+
def initialize(model)
|
7
|
+
@model = model
|
8
|
+
end
|
9
|
+
|
10
|
+
def handle(response)
|
11
|
+
if response.success?
|
12
|
+
handle_successful_response(response)
|
13
|
+
else
|
14
|
+
handle_failed_response(response)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def handle_successful_response(response)
|
21
|
+
xml = Nokogiri::XML(response.body)
|
22
|
+
model.errors = error_nodes(xml).map(&:text)
|
23
|
+
model.warnings = warning_nodes(xml).map(&:text)
|
24
|
+
end
|
25
|
+
|
26
|
+
def handle_failed_response(response)
|
27
|
+
message = "API Error: #{response.status}"
|
28
|
+
model.errors << message
|
29
|
+
end
|
30
|
+
|
31
|
+
def error_nodes(xml)
|
32
|
+
xml.css('errors error') + xml.css('Errors Error')
|
33
|
+
end
|
34
|
+
|
35
|
+
def warning_nodes(xml)
|
36
|
+
xml.css('warnings warning') + xml.css('Warnings warning')
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Newgistics
|
2
|
+
module ResponseHandlers
|
3
|
+
class PostInboundReturn
|
4
|
+
attr_reader :inbound_return
|
5
|
+
|
6
|
+
def initialize(inbound_return)
|
7
|
+
@inbound_return = inbound_return
|
8
|
+
end
|
9
|
+
|
10
|
+
def handle(response)
|
11
|
+
PostErrors.new(inbound_return).handle(response)
|
12
|
+
if inbound_return.errors.empty?
|
13
|
+
handle_successful_response(response)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def handle_successful_response(response)
|
20
|
+
xml = Nokogiri::XML(response.body)
|
21
|
+
inbound_return.id = xml.css('Return').first['ID']
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Newgistics
|
2
|
+
module ResponseHandlers
|
3
|
+
class PostShipment
|
4
|
+
attr_reader :order
|
5
|
+
|
6
|
+
def initialize(order)
|
7
|
+
@order = order
|
8
|
+
end
|
9
|
+
|
10
|
+
def handle(response)
|
11
|
+
PostErrors.new(order).handle(response)
|
12
|
+
if order.errors.empty?
|
13
|
+
handle_successful_response(response)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def handle_successful_response(response)
|
20
|
+
xml = Nokogiri::XML(response.body)
|
21
|
+
order.shipment_id = xml.css('shipment').first['id']
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Newgistics
|
2
|
+
module ResponseHandlers
|
3
|
+
class Search
|
4
|
+
attr_reader :element_selector, :model_class
|
5
|
+
|
6
|
+
def initialize(element_selector:, model_class:)
|
7
|
+
@element_selector = element_selector
|
8
|
+
@model_class = model_class
|
9
|
+
end
|
10
|
+
|
11
|
+
def handle(response)
|
12
|
+
if response.success?
|
13
|
+
handle_successful_response(response)
|
14
|
+
else
|
15
|
+
handle_failed_response(response)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def handle_successful_response(response)
|
22
|
+
xml = Nokogiri::XML(response.body)
|
23
|
+
errors = error_nodes(xml).map(&:text)
|
24
|
+
|
25
|
+
if errors.empty?
|
26
|
+
build_models(xml)
|
27
|
+
else
|
28
|
+
raise_error(errors.join(', '))
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def error_nodes(xml)
|
33
|
+
xml.css('errors error') + xml.css('Errors Error')
|
34
|
+
end
|
35
|
+
|
36
|
+
def build_models(xml)
|
37
|
+
xml.css(element_selector).map do |model_xml|
|
38
|
+
build_model(model_xml)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def build_model(model_xml)
|
43
|
+
model_class.new.tap do |model|
|
44
|
+
XmlMarshaller.new.assign_attributes(model, model_xml)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def handle_failed_response(response)
|
49
|
+
raise_error "API Error: #{response.status}"
|
50
|
+
end
|
51
|
+
|
52
|
+
def raise_error(message)
|
53
|
+
raise QueryError.new(message)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Newgistics
|
2
|
+
module ResponseHandlers
|
3
|
+
class UpdateShipmentContents
|
4
|
+
attr_reader :shipment
|
5
|
+
|
6
|
+
def initialize(shipment)
|
7
|
+
@shipment = shipment
|
8
|
+
end
|
9
|
+
|
10
|
+
def handle(response)
|
11
|
+
PostErrors.new(shipment).handle(response)
|
12
|
+
if shipment.errors.empty?
|
13
|
+
handle_successful_response(response)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def handle_successful_response(response)
|
20
|
+
xml = Nokogiri::XML(response.body)
|
21
|
+
shipment.success = xml.at_css('success').text
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Newgistics
|
2
|
+
class Return
|
3
|
+
include Virtus.model
|
4
|
+
|
5
|
+
attribute :warehouse_id, String
|
6
|
+
attribute :shipment_id, String
|
7
|
+
attribute :order_id, String
|
8
|
+
|
9
|
+
attribute :status, String
|
10
|
+
attribute :name, String
|
11
|
+
attribute :company, String
|
12
|
+
attribute :address1, String
|
13
|
+
attribute :address2, String
|
14
|
+
attribute :city, String
|
15
|
+
attribute :state, String
|
16
|
+
attribute :postal_code, String
|
17
|
+
attribute :country, String
|
18
|
+
attribute :email, String
|
19
|
+
attribute :phone, String
|
20
|
+
attribute :carrier, String
|
21
|
+
attribute :tracking_number, String
|
22
|
+
attribute :postage_due, Float
|
23
|
+
attribute :rma_present, Boolean
|
24
|
+
attribute :rma_number, String
|
25
|
+
attribute :reason, String
|
26
|
+
attribute :condition, String
|
27
|
+
attribute :notes, String
|
28
|
+
attribute :is_archived, Boolean
|
29
|
+
attribute :timestamp, Timestamp
|
30
|
+
attribute :items, Array[Item]
|
31
|
+
|
32
|
+
def self.where(conditions)
|
33
|
+
Query.build(
|
34
|
+
endpoint: '/returns.aspx',
|
35
|
+
element_selector: 'Returns Return',
|
36
|
+
model_class: self
|
37
|
+
).where(conditions)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module Newgistics
|
2
|
+
class Shipment
|
3
|
+
include Virtus.model
|
4
|
+
|
5
|
+
attribute :id, String
|
6
|
+
attribute :client_name, String
|
7
|
+
attribute :order_id, String
|
8
|
+
attribute :purchase_order, String
|
9
|
+
attribute :name, String
|
10
|
+
attribute :last_name, String
|
11
|
+
attribute :first_name, String
|
12
|
+
attribute :company, String
|
13
|
+
attribute :address1, String
|
14
|
+
attribute :address2, String
|
15
|
+
attribute :city, String
|
16
|
+
attribute :state, String
|
17
|
+
attribute :postal_code, String
|
18
|
+
attribute :country, String
|
19
|
+
attribute :email, String
|
20
|
+
attribute :phone, String
|
21
|
+
attribute :order_timestamp, Timestamp
|
22
|
+
attribute :received_timestamp, Timestamp
|
23
|
+
attribute :shipment_status, String
|
24
|
+
attribute :order_type, String
|
25
|
+
attribute :shipped_date, Timestamp
|
26
|
+
attribute :expected_delivery_date, Timestamp
|
27
|
+
attribute :delivered_timestamp, Timestamp
|
28
|
+
attribute :warehouse, Warehouse
|
29
|
+
attribute :ship_method, String
|
30
|
+
attribute :ship_method_code, String
|
31
|
+
attribute :tracking, String
|
32
|
+
attribute :tracking_url, String
|
33
|
+
attribute :items, Array[Item]
|
34
|
+
attribute :custom_fields, Hash
|
35
|
+
attribute :weight, Float
|
36
|
+
attribute :postage, Float
|
37
|
+
attribute :fees, Array[Fee]
|
38
|
+
|
39
|
+
def backordered?
|
40
|
+
shipment_status == 'BACKORDER'
|
41
|
+
end
|
42
|
+
|
43
|
+
def canceled?
|
44
|
+
shipment_status == 'CANCELED'
|
45
|
+
end
|
46
|
+
|
47
|
+
def on_hold?
|
48
|
+
%w(ONHOLD BADSKUHOLD BADADDRESS CNFHOLD INVHOLD).include? shipment_status
|
49
|
+
end
|
50
|
+
|
51
|
+
def received?
|
52
|
+
shipment_status == 'RECEIVED'
|
53
|
+
end
|
54
|
+
|
55
|
+
def printed?
|
56
|
+
shipment_status == 'PRINTED'
|
57
|
+
end
|
58
|
+
|
59
|
+
def shipped?
|
60
|
+
shipment_status == 'SHIPPED'
|
61
|
+
end
|
62
|
+
|
63
|
+
def returned?
|
64
|
+
shipment_status == 'RETURNED'
|
65
|
+
end
|
66
|
+
|
67
|
+
def verified?
|
68
|
+
shipment_status == 'VERIFIED'
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.where(conditions)
|
72
|
+
Query.build(
|
73
|
+
endpoint: '/shipments.aspx',
|
74
|
+
element_selector: 'Shipments Shipment',
|
75
|
+
model_class: self
|
76
|
+
).where(conditions)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Newgistics
|
2
|
+
class ShipmentCancellation
|
3
|
+
include Virtus.model
|
4
|
+
|
5
|
+
attribute :shipment_id, String
|
6
|
+
attribute :order_id, String
|
7
|
+
attribute :cancel_if_in_process, Boolean
|
8
|
+
attribute :cancel_if_backorder, Boolean
|
9
|
+
attribute :success, Boolean
|
10
|
+
|
11
|
+
attribute :errors, Array[String], default: []
|
12
|
+
attribute :warnings, Array[String], default: []
|
13
|
+
|
14
|
+
def success?
|
15
|
+
!!success
|
16
|
+
end
|
17
|
+
|
18
|
+
def save
|
19
|
+
Requests::CancelShipment.new(self).perform
|
20
|
+
|
21
|
+
errors.empty? && success?
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|