shipvine 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,129 @@
1
+ module Shipvine
2
+ class InboundShipment < Base
3
+
4
+ attr_reader :attributes
5
+
6
+ def initialize(attributes)
7
+ @attributes = attributes
8
+ end
9
+
10
+ def self.list(since, state = 'Complete')
11
+ request = self.client.request(
12
+ :get,
13
+ '/inbound-shipments/' + ERB::Util.url_encode(Shipvine.merchant_code),
14
+ {
15
+ 'changed-since' => since,
16
+ 'state' => state
17
+ }
18
+ )
19
+
20
+ response = self.xml_to_hash(request.body)
21
+
22
+ # the GET response only returns the identifiers, we have to make another call
23
+ # to pull all of the actual inbound shipments
24
+ merchant_identifiers = Array.wrap(response.dig(:inbound_shipments, :inbound_shipment)).map do |shipment_hash|
25
+ shipment_hash[:merchant_identifier]
26
+ end
27
+
28
+ merchant_identifiers.map do |identifier|
29
+ self.get(identifier)
30
+ end
31
+ end
32
+
33
+ def self.get(merchant_identifier)
34
+ request = self.client.request(
35
+ :get,
36
+ '/inbound-shipments/' + ERB::Util.url_encode(Shipvine.merchant_code) + '/' + ERB::Util.url_encode(merchant_identifier)
37
+ )
38
+
39
+ self.new(self.xml_to_hash(request.body))
40
+ end
41
+
42
+ def create
43
+ translated_payload = @attributes.deep_dup
44
+ merchant_identifier = translated_payload.delete(:merchant_identifier)
45
+
46
+ # `The /InboundShipment/ExpectedAt date is not in the expected format of yyyy-MM-dd (e.g., '2014-02-28')`
47
+ if translated_payload[:expected_at] !=~ /[0-9]{4}-[0-2]{2}-[0-9]{2}/
48
+ translated_payload[:expected_at] = DateTime.parse(translated_payload[:expected_at]).strftime('%Y-%m-%d')
49
+ end
50
+
51
+ preprocess_lines(translated_payload)
52
+ preprocess_metadata(translated_payload)
53
+
54
+ client.request(
55
+ :put,
56
+ '/inbound-shipments/' + ERB::Util.url_encode(Shipvine.merchant_code) + '/' + ERB::Util.url_encode(merchant_identifier),
57
+ request_body('InboundShipment', translated_payload)
58
+ )
59
+ end
60
+
61
+ def metadata
62
+ metadata_entries = self.attributes.dig(:inbound_shipment, :shipment_metadata, :metadata)
63
+
64
+ if metadata_entries.nil? || metadata_entries.empty?
65
+ return {}
66
+ end
67
+
68
+ # TODO cache the resulting hash here
69
+
70
+ metadata_entries = Array.wrap(metadata_entries)
71
+
72
+ metadata_entries.inject({}) do |h, sv_metadata_entry|
73
+ h[sv_metadata_entry[:name]] = sv_metadata_entry[:value]
74
+ h
75
+ end
76
+ end
77
+
78
+ protected
79
+
80
+ def preprocess_metadata(shipment_hash)
81
+ metadata = shipment_hash.delete(:metadata)
82
+
83
+ if metadata
84
+ shipment_hash[:shipment_metadata] = {
85
+ :metadata => metadata.map do |k, v|
86
+ {
87
+ name: k,
88
+ value: v
89
+ }
90
+ end
91
+ }
92
+ end
93
+ end
94
+
95
+ def preprocess_lines(order_hash)
96
+ items = order_hash.delete(:items)
97
+
98
+ order_hash[:lines] = {
99
+ :line => items.map do |item|
100
+ {
101
+ item: {
102
+ # TODO support other item keys, `sku`, `id`, etc
103
+ merchant_identifier: item[:product_id]
104
+ },
105
+ quantity_expected: item[:quantity],
106
+ }
107
+ end
108
+ }
109
+
110
+ order_hash
111
+ end
112
+
113
+ def build_sanitized_hash(resource_name, hash)
114
+ sanitized = hash.deep_compact!
115
+
116
+ # NOTE inbound shipments do not have a XSD!
117
+ # also, the merchant code is specified in the URL in XML
118
+
119
+ {
120
+ resource_name => sanitized
121
+ }
122
+ end
123
+
124
+ def validate_xml!(xml)
125
+ # NOTE there is no XSD for inbound shipments!
126
+ end
127
+
128
+ end
129
+ end
@@ -0,0 +1,74 @@
1
+ module Shipvine
2
+ class Item < Base
3
+ def self.get(item_group_merchant_identifier, item_merchant_identifier)
4
+ request = self.client.request(
5
+ :get,
6
+ # escape SKU?
7
+
8
+ '/item-groups/' +
9
+ Shipvine.merchant_code + '/' +
10
+ item_group_merchant_identifier + '/' +
11
+ 'items/' +
12
+ item_merchant_identifier,
13
+ {},
14
+ exclude_merchant_code: true
15
+ )
16
+
17
+ self.new(self.xml_to_hash(request.body))
18
+ rescue Shipvine::Error => e
19
+ nil
20
+ end
21
+
22
+ def initialize(attributes)
23
+ @attributes = attributes
24
+ end
25
+
26
+ def create
27
+ translated_payload = @attributes.deep_dup
28
+
29
+ merchant_identifier = translated_payload.delete(:merchant_identifier)
30
+ group_merchant_identifier = translated_payload.delete(:group_merchant_identifier)
31
+
32
+ preprocess_metadata(translated_payload)
33
+
34
+ client.request(
35
+ :put,
36
+ '/item-groups/' +
37
+ Shipvine.merchant_code + '/' +
38
+ group_merchant_identifier + '/' +
39
+ 'items/' +
40
+ merchant_identifier,
41
+ request_body('Item', translated_payload),
42
+ exclude_merchant_code: true
43
+ )
44
+ end
45
+
46
+ private
47
+
48
+ # NOTE there are no sequence limitations on the item API
49
+
50
+ # there is no XSD, and the merchant code is included the URL; simple strip nils
51
+ def build_sanitized_hash(resource_name, hash)
52
+ { resource_name => hash.deep_compact! }
53
+ end
54
+
55
+ def validate_xml!(xml)
56
+ # NOTE there is no XSD for item group!
57
+ end
58
+
59
+ def preprocess_metadata(item_hash)
60
+ metadata = item_hash.delete(:metadata)
61
+
62
+ if metadata
63
+ item_hash[:metadata] = {
64
+ :metadata => metadata.map do |k, v|
65
+ {
66
+ name: k,
67
+ value: v
68
+ }
69
+ end
70
+ }
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,53 @@
1
+ module Shipvine
2
+ class ItemGroup < Base
3
+
4
+ def self.get(item_merchant_identifier)
5
+ request = self.client.request(
6
+ :get,
7
+
8
+ # TODO escape SKU?
9
+
10
+ '/item-groups/' +
11
+ Shipvine.merchant_code + '/' +
12
+ item_merchant_identifier
13
+ )
14
+
15
+ self.new(self.xml_to_hash(request.body))
16
+ rescue Shipvine::Error => e
17
+ nil
18
+ end
19
+
20
+ attr_accessor :attributes
21
+
22
+ def initialize(attributes)
23
+ @attributes = attributes
24
+ end
25
+
26
+ def create
27
+ translated_payload = @attributes.deep_dup
28
+
29
+ merchant_identifier = translated_payload.delete(:merchant_identifier)
30
+
31
+ client.request(
32
+ :put,
33
+ '/item-groups/' +
34
+ Shipvine.merchant_code + '/' + merchant_identifier,
35
+ request_body('ItemGroup', translated_payload)
36
+ )
37
+ end
38
+
39
+ private
40
+
41
+ # NOTE there are no sequence limitations on the item API
42
+
43
+ # there is no XSD, and the merchant code is included the URL; simple strip nils
44
+ def build_sanitized_hash(resource_name, hash)
45
+ { resource_name => hash.deep_compact! }
46
+ end
47
+
48
+ def validate_xml!(xml)
49
+ # NOTE there is no XSD for item group!
50
+ end
51
+
52
+ end
53
+ end
@@ -0,0 +1,30 @@
1
+ module Shipvine
2
+ class OutboundShipment < Base
3
+
4
+ def self.list(since)
5
+ request = self.client.request(:get, '/outbound-shipments', { 'created-since' => since })
6
+ response = self.xml_to_hash(request.body)
7
+
8
+ Array.wrap(response[:outbound_shipments][:outbound_shipment]).map do |shipment_hash|
9
+ self.new(shipment_hash)
10
+ end
11
+ end
12
+
13
+ attr_accessor :attributes
14
+
15
+ def initialize(shipment_hash)
16
+ @attributes = shipment_hash
17
+ end
18
+
19
+ def merchant_identifier
20
+ @attributes[:fulfillment_request][:merchant_identifier]
21
+ end
22
+
23
+ def wfs_identifier
24
+ @attributes[:fulfillment_request][:wfs_identifier]
25
+ end
26
+
27
+ alias_method :shipvine_identifier, :wfs_identifier
28
+
29
+ end
30
+ end
@@ -0,0 +1,3 @@
1
+ module Shipvine
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'shipvine/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "shipvine"
8
+ spec.version = Shipvine::VERSION
9
+ spec.authors = ["Michael Bianco"]
10
+ spec.email = ["mike@cliffsidemedia.com"]
11
+
12
+ spec.summary = %q{Shipvine API bindings}
13
+ # spec.description = %q{TODO: Write a longer description or delete this line.}
14
+ spec.homepage = "https://github.com/iloveitaly/shipvine-ruby"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = "exe"
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency 'httparty', '~> 0.13.7'
22
+ spec.add_dependency 'gyoku', '~> 1.3.1'
23
+ spec.add_dependency 'nori', '~> 2.6.0'
24
+
25
+ spec.add_development_dependency "bundler", "~> 1.11"
26
+ spec.add_development_dependency "rake", "~> 10.0"
27
+ spec.add_development_dependency "minitest", "~> 5.0"
28
+ end
metadata ADDED
@@ -0,0 +1,147 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: shipvine
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Michael Bianco
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-12-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: httparty
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.13.7
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.13.7
27
+ - !ruby/object:Gem::Dependency
28
+ name: gyoku
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.3.1
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.3.1
41
+ - !ruby/object:Gem::Dependency
42
+ name: nori
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 2.6.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.6.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.11'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.11'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '10.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '10.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: minitest
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '5.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '5.0'
97
+ description:
98
+ email:
99
+ - mike@cliffsidemedia.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - ".gitignore"
105
+ - Gemfile
106
+ - README.md
107
+ - Rakefile
108
+ - bin/console
109
+ - bin/setup
110
+ - data/WarehouseFS-1.0.xsd
111
+ - lib/shipvine.rb
112
+ - lib/shipvine/base.rb
113
+ - lib/shipvine/bill_of_lading.rb
114
+ - lib/shipvine/client.rb
115
+ - lib/shipvine/deep_compact.rb
116
+ - lib/shipvine/error.rb
117
+ - lib/shipvine/fulfillment_request.rb
118
+ - lib/shipvine/inbound_shipment.rb
119
+ - lib/shipvine/item.rb
120
+ - lib/shipvine/item_group.rb
121
+ - lib/shipvine/outbound_shipment.rb
122
+ - lib/shipvine/version.rb
123
+ - shipvine.gemspec
124
+ homepage: https://github.com/iloveitaly/shipvine-ruby
125
+ licenses: []
126
+ metadata: {}
127
+ post_install_message:
128
+ rdoc_options: []
129
+ require_paths:
130
+ - lib
131
+ required_ruby_version: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - ">="
134
+ - !ruby/object:Gem::Version
135
+ version: '0'
136
+ required_rubygems_version: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ requirements: []
142
+ rubyforge_project:
143
+ rubygems_version: 2.6.4
144
+ signing_key:
145
+ specification_version: 4
146
+ summary: Shipvine API bindings
147
+ test_files: []