trebbianno-ruby-api 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3ea0a271b3835e209e2621735a56135df19f9507
4
+ data.tar.gz: 6f601985731d3053297abfd19b9e585a75580091
5
+ SHA512:
6
+ metadata.gz: b3f993f5ccbad5ff8429de38fa879cb25f117368217ffbbadc1744c2300b7b7c2deaf31625ebf6b8ed09da3c61f917e0b4bf5d762c3e7668acd89b1efc38028e
7
+ data.tar.gz: 8c1c1137ab9034c3c475566b06539b3e4558c1963e1830f1cb2dd7c1321f3df7254e1ee57f7eb96212e707f74bd527586e4459bd6651beb0d5a3b07e255ae6dd
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/.travis.yml ADDED
@@ -0,0 +1,26 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+
5
+ matrix:
6
+ allow_failures:
7
+ - rvm: rbx-19mode
8
+
9
+ services:
10
+ - redis
11
+
12
+ script:
13
+ - bundle exec rake
14
+
15
+ # addons:
16
+ # code_climate:
17
+ # repo_token: f0884115cadbe82b33756e38a9cd32d5129304746a17126d6c7da02e7a69910a
18
+
19
+ notifications:
20
+ email:
21
+ - justin@jgrubbs.net
22
+
23
+ gemfile:
24
+ - Gemfile
25
+
26
+
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in trebbianno.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Justin Grubbs
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,84 @@
1
+ # Trebbianno
2
+
3
+ [![Build Status](https://travis-ci.org/jGRUBBS/trebbianno-ruby-api.svg?branch=master)](https://travis-ci.org/jGRUBBS/trebbianno-ruby-api)
4
+ [![Code Climate](https://codeclimate.com/github/jGRUBBS/trebbianno-ruby-api.png)](https://codeclimate.com/github/jGRUBBS/trebbianno-ruby-api)
5
+
6
+ Ruby library for interfacing with the Trebbianno Fulfillment API
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ gem 'trebbianno-ruby-api'
13
+
14
+ And then execute:
15
+
16
+ $ bundle
17
+
18
+ Or install it yourself as:
19
+
20
+ $ gem install trebbianno-ruby-api
21
+
22
+ ## Usage
23
+
24
+ Send order request
25
+
26
+ ```ruby
27
+
28
+ order = {
29
+ shipping_address: {
30
+ first_name: "John",
31
+ last_name: "Smith",
32
+ address1: "123 Here Now",
33
+ address2: "2nd Floor",
34
+ city: "New York",
35
+ state: "NY",
36
+ country: "US",
37
+ zipcode: "10012",
38
+ phone: "123-123-1234"
39
+ },
40
+ number: "R123123123",
41
+ orderdate: "2014-06-16",
42
+ line_items: [
43
+ {
44
+ price: "127.23",
45
+ quantity: "1",
46
+ sku: "123332211"
47
+ }
48
+ ],
49
+ shipping_method: "UPS 1-Day",
50
+ shipping_cost: "20.00",
51
+ invoice_url: "http://example.com/R123123123/invoice"
52
+ }
53
+
54
+ client = Trebbianno::Client.new("username", "password")
55
+ response = client.send_order_request(order)
56
+
57
+ if response.success?
58
+ # DO SOMETHING
59
+ else
60
+ # QUEUE REQUEST, STORE AND RAISE ERRORS
61
+ end
62
+
63
+ ```
64
+
65
+ Get inventory
66
+
67
+ ```ruby
68
+
69
+ client = Trebbianno::Client.new("username", "password")
70
+ inventory = client.get_inventory
71
+
72
+ inventory.each do |stock|
73
+ ...
74
+ end
75
+
76
+ ```
77
+
78
+ ## Contributing
79
+
80
+ 1. Fork it
81
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
82
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
83
+ 4. Push to the branch (`git push origin my-new-feature`)
84
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+ task :default => :spec
@@ -0,0 +1,103 @@
1
+ require 'net/http'
2
+ require 'xmlsimple'
3
+
4
+ module Trebbianno
5
+ class Client
6
+
7
+ TEST_HOST = "54.235.241.72"
8
+ LIVE_HOST = "54.235.241.72"
9
+ PORT = 4081
10
+
11
+ attr_accessor :username, :password, :response, :type, :request_uri, :path
12
+
13
+ def initialize(username, password, options = {})
14
+ raise "Username is required" unless username
15
+ raise "Password is required" unless password
16
+
17
+ @username = username
18
+ @password = password
19
+ @options = default_options.merge!(options)
20
+ end
21
+
22
+ def send_order_request(order)
23
+ request = order_request(order)
24
+ @path = Order::PATH
25
+ post(request)
26
+ end
27
+
28
+ def get_inventory
29
+ request = Inventory.new(self).build_inventory_request
30
+ @path = Inventory::PATH
31
+ post(request).response['stock']
32
+ end
33
+
34
+ def order_request(order)
35
+ @path = Order::PATH
36
+ Order.new(self).build_order_request(order)
37
+ end
38
+
39
+ def upcs(inventory)
40
+ inventory.collect { |s| s["stockid"][0] }
41
+ end
42
+
43
+ def mapped_inventory(upcs, inventory)
44
+ inventory.collect do |stock|
45
+ if upcs.include?(stock["stockid"][0])
46
+ { quantity: stock["qty"][0].to_i }
47
+ end
48
+ end.compact
49
+ end
50
+
51
+ def request_uri
52
+ "http://#{host}:#{PORT}#{@path}"
53
+ end
54
+
55
+ private
56
+ def default_options
57
+ {
58
+ verbose: true,
59
+ test_mode: false
60
+ }
61
+ end
62
+
63
+ def testing?
64
+ @options[:test_mode]
65
+ end
66
+
67
+ def verbose?
68
+ @options[:verbose]
69
+ end
70
+
71
+ def host
72
+ testing? ? TEST_HOST : LIVE_HOST
73
+ end
74
+
75
+ def log(message)
76
+ return unless verbose?
77
+ puts message
78
+ end
79
+
80
+ def http
81
+ Net::HTTP.new(host, PORT)
82
+ end
83
+
84
+ def request(xml_request)
85
+ request = Net::HTTP::Post.new(@path)
86
+ request.body = xml_request
87
+ request.content_type = 'text/xml'
88
+ request.basic_auth(@username, @password)
89
+ http.request(request)
90
+ end
91
+
92
+ def post(xml_request)
93
+ response = request(xml_request)
94
+ parse_response(response.body)
95
+ end
96
+
97
+ def parse_response(xml_response)
98
+ log(xml_response)
99
+ @response = Response.new(xml_response, @type)
100
+ end
101
+
102
+ end
103
+ end
@@ -0,0 +1,115 @@
1
+ module Trebbianno
2
+ class Country
3
+
4
+ COUNTRY_MAP = {
5
+ 'MQ' => 'MQ', # MARTINIQUE
6
+ 'ES' => 'SP', # SPAIN
7
+ 'UA' => 'UA', # UKRAINE
8
+ 'MN' => 'MO', # MONGOLIA
9
+ 'AI' => 'AN', # ANGUILLA
10
+ 'AU' => 'AU', # AUSTRALIA
11
+ 'BS' => 'BH', # BAHAMAS
12
+ 'BB' => 'BB', # BARBADOS
13
+ 'BM' => 'BE', # BERMUDA
14
+ 'BE' => 'BG', # BELGIUM
15
+ 'BZ' => 'BL', # BELIZE
16
+ 'BO' => 'BO', # BOLIVIA
17
+ 'CL' => 'CH', # CHILE
18
+ 'CR' => 'CR', # COSTA RICA
19
+ 'EE' => 'ES', # ESTONIA
20
+ 'DE' => 'GE', # GERMANY
21
+ 'GT' => 'GM', # GUATEMALA
22
+ 'GD' => 'GR', # GRENADA
23
+ 'HT' => 'HA', # HAITI
24
+ 'IS' => 'IC', # ICELAND
25
+ 'IL' => 'IS', # ISRAEL
26
+ 'JM' => 'JM', # JAMAICA
27
+ 'US' => 'US', # UNITED STATES
28
+ 'AE' => 'AE', # UNITED ARAB EMIRATES
29
+ 'BD' => 'BD', # BANGLADESH
30
+ 'EG' => 'EG', # EGYPT
31
+ 'HK' => 'HK', # HONG KONG
32
+ 'ID' => 'ID', # INDONESIA
33
+ 'IN' => 'IN', # INDIA
34
+ 'LK' => 'LK', # SRI LANKA
35
+ 'OM' => 'OM', # OMAN
36
+ 'PH' => 'PH', # PHILIPPINES
37
+ 'PK' => 'PK', # PAKISTAN
38
+ 'ZA' => 'SA', # SOUTH AFRICA
39
+ 'SZ' => 'SW', # SWAZILAND
40
+ 'TH' => 'TH', # THAILAND
41
+ 'TW' => 'TW', # TAIWAN
42
+ 'KH' => 'CB', # CAMBODIA
43
+ 'LS' => 'LE', # LESOTHO
44
+ 'QA' => 'QT', # QATAR
45
+ 'SA' => 'SD', # SAUDI ARABIA
46
+ 'BH' => 'BA', # BAHRAIN
47
+ 'HN' => 'HO', # HONDURAS
48
+ 'CA' => 'CA', # CANADA
49
+ 'JP' => 'JP', # JAPAN
50
+ 'KW' => 'KU', # KUWAIT
51
+ 'LB' => 'LB', # LEBANON
52
+ 'MH' => 'MH', # MARSHALL ISLANDS
53
+ 'MX' => 'MX', # MEXICO
54
+ 'AN' => 'NA', # NETHERLANDS ANTILLES
55
+ 'NG' => 'NI', # NIGERIA
56
+ 'NI' => 'NR', # NICARAGUA
57
+ 'PA' => 'PN', # PANAMA
58
+ 'PR' => 'PR', # PUERTO RICO
59
+ 'PE' => 'PU', # PERU
60
+ 'RO' => 'RO', # ROMANIA
61
+ 'VE' => 'VZ', # VENEZUELA
62
+ 'GU' => 'GU', # GUAM
63
+ 'PW' => 'PW', # PALAU
64
+ 'BW' => 'BW', # BOTSWANA
65
+ 'GH' => 'GH', # GHANA
66
+ 'IT' => 'IT', # ITALY
67
+ 'BG' => 'BU', # BULGARIA
68
+ 'HU' => 'HU', # HUNGARY
69
+ 'PL' => 'PO', # POLAND
70
+ 'TR' => 'TR', # TURKEY
71
+ 'MU' => 'MT', # MAURITIUS
72
+ 'MV' => 'MV', # MALDIVES
73
+ 'MY' => 'MY', # MALAYSIA
74
+ 'SG' => 'SG', # SINGAPORE
75
+ 'UY' => 'UR', # URUGUAY
76
+ 'GR' => 'GC', # GREECE
77
+ 'MW' => 'MA', # MALAWI
78
+ 'FI' => 'FN', # FINLAND
79
+ 'TM' => 'TM', # TURKMENISTAN
80
+ 'CH' => 'ST', # SWITZERLAND
81
+ 'KZ' => 'KZ', # KAZAKHSTAN
82
+ 'PY' => 'PY', # PARAGUAY
83
+ 'FR' => 'FR', # FRANCE
84
+ 'GB' => 'UK', # UNITED KINGDOM
85
+ 'AR' => 'AR', # ARGENTINA
86
+ 'GT' => 'GT', # GUATEMALA
87
+ 'SV' => 'EL', # EL SALVADOR
88
+ 'KR' => 'SK', # SOUTH KOREA - REPUBLIC OF KOREA
89
+ 'IE' => 'IRL', # IRELAND
90
+ 'GY' => 'GY', # GUYANA
91
+ 'BR' => 'BR', # BRAZIL
92
+ 'CN' => 'CN', # CHINA
93
+ 'VN' => 'VN', # VIETNAM
94
+ 'MO' => 'MC', # MACAU
95
+ 'KP' => 'KR', # NORTH KOREA - DEMOCRATIC PEOPLE'S REPUBLIC OF KOREA
96
+ 'AG' => 'AT', # ANTIGUA,
97
+ 'CO' => 'CO', # COLOMBIA
98
+ 'DO' => 'DR', # DOMINICAN REPUBLIC
99
+ 'EC' => 'EQ', # ECUADOR
100
+ 'SY' => 'SY', # SYRIAN ARAB REPUBLIC
101
+ 'MP' => 'MP', # MARIANA ISLANDS
102
+ 'RU' => 'RU', # RUSSIA
103
+ 'SR' => 'SR', # SURINAME
104
+ 'TT' => 'TD', # TRINIDAD AND TOBAGO
105
+ 'VI' => 'VI', # U.S. VIRGIN ISLANDS
106
+ 'CZ' => 'CZ', # CZECH REPUBLIC
107
+ 'CY' => 'CP' # CYPRUS
108
+ }
109
+
110
+ def self.map(code)
111
+ COUNTRY_MAP[code] || code
112
+ end
113
+
114
+ end
115
+ end
@@ -0,0 +1,11 @@
1
+ module Trebbianno
2
+ class Inventory < Request
3
+
4
+ PATH = "/Inventory"
5
+
6
+ def build_inventory_request
7
+ construct_xml "stock"
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,53 @@
1
+ module Trebbianno
2
+ class Order < Request
3
+
4
+ PATH = "/Order"
5
+
6
+ def build_order_request(order)
7
+ construct_xml "orders" do |xml|
8
+
9
+ xml.order do
10
+
11
+ build_user xml
12
+
13
+ address = order[:shipping_address]
14
+ xml.name "#{address[:first_name]} #{address[:last_name]}"
15
+ build_address xml, address
16
+ xml.customerref order[:number]
17
+ xml.orderdate order[:date]
18
+ xml.freightcharge order[:shipping_cost]
19
+ xml.ordernumber order[:number]
20
+ xml.shipping_method order[:shipping_method]
21
+
22
+ build_line_items xml, order
23
+
24
+ end
25
+
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def build_address(xml, address)
32
+ xml.addressline1 address[:address1]
33
+ xml.addressline2 address[:address2]
34
+ xml.towncity address[:city]
35
+ xml.state State.map(address[:state])
36
+ xml.postcode address[:zipcode]
37
+ xml.country Country.map(address[:country])
38
+ xml.contactphone address[:phone]
39
+ end
40
+
41
+ def build_line_items(xml, order)
42
+ order[:line_items].each do |line_item|
43
+ xml.orderline do
44
+ xml.ordernumber order[:number]
45
+ xml.sku line_item[:sku]
46
+ xml.qty line_item[:quantity]
47
+ xml.unitprice line_item[:price]
48
+ end
49
+ end
50
+ end
51
+
52
+ end
53
+ end
@@ -0,0 +1,27 @@
1
+ require 'builder'
2
+
3
+ module Trebbianno
4
+ class Request
5
+
6
+ def initialize(client)
7
+ @client = client
8
+ end
9
+
10
+ def construct_xml(type)
11
+ @client.type = type
12
+ xml = ::Builder::XmlMarkup.new :indent => 2
13
+ xml.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"
14
+ xml.tag! type do
15
+ yield(xml) if block_given?
16
+ end
17
+ xml.target!
18
+ end
19
+
20
+
21
+ def build_user(xml)
22
+ xml.user @client.username
23
+ xml.password @client.password
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ module Trebbianno
2
+ class Response
3
+
4
+ attr_accessor :response
5
+
6
+ def initialize(raw_response, type)
7
+ @raw_response = raw_response
8
+ @response = parse_response(raw_response)
9
+ @type = type
10
+ end
11
+
12
+ def failure?
13
+ !success?
14
+ end
15
+
16
+ def success?
17
+ # @response.parsed["#{@type}_response"]["#{@type}_result"][:status] == '0001'
18
+ true
19
+ end
20
+
21
+ def parse_response(xml_response)
22
+ return nil if xml_response.blank?
23
+ XmlSimple.xml_in(xml_response)
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,63 @@
1
+ module Trebbianno
2
+ class State
3
+
4
+ STATE_MAP = {
5
+ "Alabama" => "AL",
6
+ "Alaska" => "AK",
7
+ "Arizona" => "AZ",
8
+ "Arkansas" => "AR",
9
+ "California" => "CA",
10
+ "Colorado" => "CO",
11
+ "Connecticut" => "CT",
12
+ "Delaware" => "DE",
13
+ "District of Columbia" => "DC",
14
+ "Florida" => "FL",
15
+ "Georgia" => "GA",
16
+ "Hawaii" => "HI",
17
+ "Idaho" => "ID",
18
+ "Illinois" => "IL",
19
+ "Indiana" => "IN",
20
+ "Iowa" => "IA",
21
+ "Kansas" => "KS",
22
+ "Kentucky" => "KY",
23
+ "Louisiana" => "LA",
24
+ "Maine" => "ME",
25
+ "Montana" => "MT",
26
+ "Nebraska" => "NE",
27
+ "Nevada" => "NV",
28
+ "New Hampshire" => "NH",
29
+ "New Jersey" => "NJ",
30
+ "New Mexico" => "NM",
31
+ "New York" => "NY",
32
+ "North Carolina" => "NC",
33
+ "North Dakota" => "ND",
34
+ "Ohio" => "OH",
35
+ "Oklahoma" => "OK",
36
+ "Oregon" => "OR",
37
+ "Maryland" => "MD",
38
+ "Massachusetts" => "MA",
39
+ "Michigan" => "MI",
40
+ "Minnesota" => "MN",
41
+ "Mississippi" => "MS",
42
+ "Missouri" => "MO",
43
+ "Pennsylvania" => "PA",
44
+ "Rhode Island" => "RI",
45
+ "South Carolina" => "SC",
46
+ "South Dakota" => "SD",
47
+ "Tennessee" => "TN",
48
+ "Texas" => "TX",
49
+ "Utah" => "UT",
50
+ "Vermont" => "VT",
51
+ "Virginia" => "VA",
52
+ "Washington" => "WA",
53
+ "West Virginia" => "WV",
54
+ "Wisconsin" => "WI",
55
+ "Wyoming" => "WY"
56
+ }
57
+
58
+ def self.map(code)
59
+ STATE_MAP[code] || code
60
+ end
61
+
62
+ end
63
+ end
@@ -0,0 +1,24 @@
1
+ module Trebbianno
2
+ class Tracking
3
+
4
+ attr_accessor :carrier
5
+
6
+ FEDEX = "http://printtracking.fedex.com/trackOrder.do?gtns=:tracking_number"
7
+ USPS = "https://tools.usps.com/go/TrackConfirmAction.action?tLabels=:tracking_number"
8
+ UPS = "http://wwwapps.ups.com/WebTracking/track?trackNums=123412341234&track.x=Track"
9
+
10
+ def initialize(carrier, tracking_number)
11
+ @carrier = carrier
12
+ @tracking_number = tracking_number
13
+ end
14
+
15
+ def carrier_destination
16
+ self.class.const_get(carrier.upcase)
17
+ end
18
+
19
+ def url
20
+ carrier_destination.gsub(':tracking_number', @tracking_number)
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,3 @@
1
+ module Trebbianno
2
+ VERSION = "0.0.1"
3
+ end
data/lib/trebbianno.rb ADDED
@@ -0,0 +1,9 @@
1
+ require "trebbianno/version"
2
+ require "trebbianno/response"
3
+ require "trebbianno/client"
4
+ require "trebbianno/request"
5
+ require "trebbianno/order"
6
+ require "trebbianno/inventory"
7
+ require "trebbianno/country"
8
+ require "trebbianno/state"
9
+ require "trebbianno/tracking"
@@ -0,0 +1,95 @@
1
+ require 'spec_helper'
2
+
3
+ describe Trebbianno::Client do
4
+ before do
5
+ @client = Trebbianno::Client.new("the_username", "the_password")
6
+ end
7
+
8
+ describe '#send_order_request' do
9
+ it 'should send order request and return parsed respose' do
10
+ Trebbianno::Order.any_instance.should_receive(:build_order_request).with(order_hash)
11
+ @client.should_receive(:post)
12
+ @client.send_order_request(order_hash)
13
+ end
14
+ end
15
+
16
+ describe 'private#default_options' do
17
+ it 'should return a hash' do
18
+ @client.send(:default_options).should be_a Hash
19
+ end
20
+ end
21
+
22
+ describe 'private#testing?' do
23
+ it 'should return boolean for test mode' do
24
+ @client.send(:testing?).should be_false
25
+ @client.instance_variable_set(:@options, { test_mode: true })
26
+ @client.send(:testing?).should be_true
27
+ end
28
+ end
29
+
30
+ describe 'private#verbose?' do
31
+ it 'should return boolean for verbose mode' do
32
+ @client.send(:verbose?).should be_true
33
+ @client.instance_variable_set(:@options, { verbose: false })
34
+ @client.send(:verbose?).should be_false
35
+ end
36
+ end
37
+
38
+ describe 'private#host' do
39
+ it 'should' do
40
+ @client.stub(:testing?).and_return(false)
41
+ @client.send(:host).should == Trebbianno::Client::LIVE_HOST
42
+ @client.stub(:testing?).and_return(true)
43
+ @client.send(:host).should == Trebbianno::Client::TEST_HOST
44
+ end
45
+ end
46
+
47
+ describe 'private#path' do
48
+ it 'should' do
49
+ @client.stub(:testing?).and_return(false)
50
+ @client.send(:path).should == Trebbianno::Client::LIVE_PATH
51
+ @client.stub(:testing?).and_return(true)
52
+ @client.send(:path).should == Trebbianno::Client::TEST_PATH
53
+ end
54
+ end
55
+
56
+ describe 'private#log' do
57
+ context 'not in verbose mode' do
58
+ it 'should not log message' do
59
+ @client.stub(:verbose?).and_return(false)
60
+ @client.should_not_receive(:puts)
61
+ @client.send(:log, "message")
62
+ end
63
+ end
64
+ context 'in verbose mode' do
65
+ it 'should' do
66
+ @client.stub(:verbose?).and_return(true)
67
+ @client.should_receive(:puts).with("message")
68
+ @client.send(:log, "message")
69
+ end
70
+ end
71
+ end
72
+
73
+ describe 'private#post' do
74
+ it 'should use net http to post xml request' do
75
+ path = @client.send(:path)
76
+ xml_request = "xml_request"
77
+ response = Trebbianno::Response.new("<xml>body</xml>", "new_request")
78
+ header = {'Content-Type' => 'text/xml'}
79
+ Net::HTTP.any_instance.should_receive(:post).with(path, xml_request, header).and_return(response)
80
+ @client.should_receive(:parse_response).with(response, nil)
81
+ @client.should_receive(:log).with(response)
82
+ @client.send(:post, xml_request)
83
+ end
84
+ end
85
+
86
+ describe 'private#parse_response' do
87
+ it 'should use xml simple to parse the response' do
88
+ xml_response = "xml_response"
89
+ XmlSimple.should_receive(:xml_in).with(xml_response)
90
+ response = @client.send(:parse_response, xml_response)
91
+ response.should be_a Trebbianno::Response
92
+ end
93
+ end
94
+
95
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ describe Trebbianno::Order do
4
+
5
+ before do
6
+ @client = Trebbianno::Client.new("the_username", "the_password")
7
+ @order_client = Trebbianno::Order.new(@client)
8
+ @xml = Builder::XmlMarkup.new
9
+ end
10
+
11
+ describe '#build_order_request' do
12
+ it 'should' do
13
+ response = @order_client.build_order_request(order_hash)
14
+ @client.type.should == "new_order_entry"
15
+ request_body = xml_order_request_string(order_hash)
16
+ response.should == xml_string("new_order_entry", request_body)
17
+ end
18
+ end
19
+
20
+ describe 'private#build_address' do
21
+ it 'should build the proper address xml' do
22
+ type = "CUSTOMER"
23
+ request = @order_client.send(:build_address, @xml, type, order_hash[:shipping_address])
24
+ request.should == xml_address_string(type, order_hash[:shipping_address])
25
+ end
26
+ end
27
+
28
+ describe 'private#build_line_items' do
29
+ it 'should build the proper line items xml' do
30
+ request = @order_client.send(:build_line_items, @xml, order_hash)
31
+ request.should == xml_line_items_string(order_hash)
32
+ end
33
+ end
34
+
35
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe Trebbianno::Request do
4
+
5
+ before do
6
+ @client = Trebbianno::Client.new("the_username", "the_password")
7
+ end
8
+
9
+ describe '#construct_xml' do
10
+ it 'should build the main xml with header, user, and supplied body' do
11
+ request_type = "new_order_request"
12
+ soap_client = Trebbianno::Request.new(@client)
13
+ soap_request = soap_client.construct_xml request_type do |xml|
14
+ xml.test "test"
15
+ end
16
+ soap_request.should == xml_string(request_type, "<test>test</test>")
17
+ end
18
+ end
19
+
20
+ describe '#build_header' do
21
+ it 'should build xml header' do
22
+ request_type = "new_order_request"
23
+ soap_client = Trebbianno::Request.new(@client)
24
+ xml = Builder::XmlMarkup.new
25
+ soap_request = soap_client.build_header(xml, request_type)
26
+ soap_request.should == xml_header_string(request_type)
27
+ end
28
+ end
29
+
30
+ describe '#build_user' do
31
+ it 'should' do
32
+ soap_client = Trebbianno::Request.new(@client)
33
+ xml = Builder::XmlMarkup.new
34
+ soap_request = soap_client.build_user(xml)
35
+ soap_request.should == xml_user_string
36
+ end
37
+ end
38
+
39
+ end
@@ -0,0 +1,129 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+
6
+ require 'rubygems'
7
+ require 'bundler/setup'
8
+ Bundler.require(:default, :development)
9
+ require 'hashie'
10
+ require 'trebbianno'
11
+
12
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
13
+ RSpec.configure do |config|
14
+ config.treat_symbols_as_metadata_keys_with_true_values = true
15
+ config.run_all_when_everything_filtered = true
16
+ config.filter_run :focus
17
+ config.order = 'random'
18
+ end
19
+
20
+ def xml_string(type, body)
21
+ xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
22
+ xml += "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://www.w3.org/2005/08/addressing\">"
23
+ xml += xml_header_string(type)
24
+ xml += "<s:Body><#{type} xmlns=\"SII\">"
25
+ xml += xml_user_string
26
+ xml += body
27
+ xml += "</#{type}></s:Body></s:Envelope>"
28
+ end
29
+
30
+ def xml_header_string(type)
31
+ xml = "<s:Header><a:Action s:mustUnderstand=\"1\">SII/ISIIService/#{type}</a:Action>"
32
+ xml += "<a:MessageID>urn:uuid:56b55a70-8bbc-471d-94bb-9ca060bcf99f</a:MessageID>"
33
+ xml += "<a:ReplyTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></a:ReplyTo>"
34
+ xml += "<a:To s:mustUnderstand=\"1\">https://www.trebbianno.us/webservices/SIIService.svc</a:To></s:Header>"
35
+ end
36
+
37
+ def xml_user_string
38
+ xml = "<user xmlns:b=\"http://schemas.datacontract.org/2004/07/\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">"
39
+ xml += "<b:user_name>&lt;![CDATA[the_username]]&gt;</b:user_name><b:user_password>&lt;![CDATA[the_password]]&gt;</b:user_password></user>"
40
+ end
41
+
42
+ def xml_address_string(type, address)
43
+ full_name = "#{address[:first_name]} #{address[:last_name]}"
44
+ xml = "<b:#{type}_NAME>&lt;![CDATA[#{full_name}]]&gt;</b:#{type}_NAME>"
45
+ xml += "<b:#{type}_ADDRESS_1>&lt;![CDATA[#{address[:address1]}]]&gt;</b:#{type}_ADDRESS_1>"
46
+ xml += "<b:#{type}_ADDRESS_2>&lt;![CDATA[#{address[:address2]}]]&gt;</b:#{type}_ADDRESS_2>"
47
+ xml += "<b:#{type}_ADDRESS_3>&lt;![CDATA[#{address[:address3]}]]&gt;</b:#{type}_ADDRESS_3>"
48
+ xml += "<b:#{type}_ADDRESS_CITY>#{address[:city]}</b:#{type}_ADDRESS_CITY>"
49
+ xml += "<b:#{type}_ADDRESS_COUNTRY>#{address[:country]}</b:#{type}_ADDRESS_COUNTRY>"
50
+ xml += "<b:#{type}_ADDRESS_STATE>#{address[:state]}</b:#{type}_ADDRESS_STATE>"
51
+ xml += "<b:#{type}_ADDRESS_ZIP>#{address[:zipcode]}</b:#{type}_ADDRESS_ZIP>"
52
+ xml += "<b:#{type}_TELEPHONE>#{address[:phone]}</b:#{type}_TELEPHONE>"
53
+ end
54
+
55
+ def xml_line_items_string(order)
56
+ xml = "<b:Order_Details>"
57
+ order[:line_items].each do |line_item|
58
+ xml += "<b:Order_Detail_New>"
59
+ xml += "<b:PRICE>#{line_item[:price]}</b:PRICE>"
60
+ xml += "<b:QUANTITY>#{line_item[:quantity]}</b:QUANTITY>"
61
+ xml += "<b:SIZE>#{line_item[:size]}</b:SIZE>"
62
+ xml += "<b:sku>#{line_item[:sku]}</b:sku>"
63
+ xml += "</b:Order_Detail_New>"
64
+ end
65
+ xml += "</b:Order_Details>"
66
+ end
67
+
68
+ def xml_order_request_string(order)
69
+ xml = "<ohn xmlns:b=\"http://schemas.datacontract.org/2004/07/\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">"
70
+ xml += "<b:SERVICE>90</b:SERVICE>"
71
+ xml += "<b:USER1>&lt;![CDATA[http://example.com/R123123123/invoice]]&gt;</b:USER1>"
72
+ xml += "<b:CARRIER>FEDEX</b:CARRIER>"
73
+ xml += "<b:CUSTOMER_CODE/><b:DELIVERY_GIFT_WRAP/>"
74
+ xml += "<b:DELIVERY_MESSAGE>&lt;![CDATA[Happy Birthday!]]&gt;</b:DELIVERY_MESSAGE>"
75
+ xml += "<b:EMAIL>someone@somehwere.com</b:EMAIL>"
76
+ xml += "<b:ORDER_ID>R123123123</b:ORDER_ID>"
77
+ xml += "<b:ORDER_TYPE>OO</b:ORDER_TYPE>"
78
+ xml += "<b:DELIVERY_FROM i:nil=\"true\"/><b:DELIVERY_TO i:nil=\"true\"/>"
79
+ xml += "<b:DELIVERY_ID i:nil=\"true\"/><b:FREIGHT_ACCOUNT i:nil=\"true\"/>"
80
+ xml += xml_address_string("CUSTOMER", order[:billing_address])
81
+ xml += xml_address_string("DELIVERY", order[:shipping_address])
82
+ xml += xml_line_items_string(order)
83
+ xml += "</ohn>"
84
+ end
85
+
86
+ def order_hash
87
+ {
88
+ carrier: "FEDEX",
89
+ billing_address: {
90
+ first_name: "John",
91
+ last_name: "Smith",
92
+ address1: "123 Here Now",
93
+ address2: "2nd Floor",
94
+ address3: "",
95
+ city: "New York",
96
+ state: "New York",
97
+ country: "US",
98
+ zipcode: "10012",
99
+ phone: "123-123-1234"
100
+ },
101
+ shipping_address: {
102
+ first_name: "John",
103
+ last_name: "Smith",
104
+ address1: "123 Here Now",
105
+ address2: "2nd Floor",
106
+ address3: "",
107
+ city: "New York",
108
+ state: "New York",
109
+ country: "US",
110
+ zipcode: "10012",
111
+ phone: "123-123-1234"
112
+ },
113
+ gift_wrap: "true",
114
+ gift_message: "Happy Birthday!",
115
+ email: "someone@somehwere.com",
116
+ number: "R123123123",
117
+ type: "OO",
118
+ line_items: [
119
+ {
120
+ price: "127.23",
121
+ quantity: "1",
122
+ sku: "123332211",
123
+ size: "XS"
124
+ }
125
+ ],
126
+ shipping_code: "90",
127
+ invoice_url: "http://example.com/R123123123/invoice"
128
+ }
129
+ end
@@ -0,0 +1,26 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+ require 'trebbianno/version'
3
+
4
+ Gem::Specification.new do |spec|
5
+ spec.name = "trebbianno-ruby-api"
6
+ spec.version = Trebbianno::VERSION
7
+ spec.authors = ["Justin Grubbs"]
8
+ spec.email = ["justin@sellect.com"]
9
+ spec.description = %q{Ruby Library for Trebbianno Fulfillment API}
10
+ spec.summary = %q{This is a library for interfacing with the Trebbianno Fulfillment API}
11
+ spec.homepage = "http://sellect.com"
12
+ spec.license = "MIT"
13
+
14
+ spec.files = `git ls-files`.split($/)
15
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
16
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
+ spec.require_paths = ["lib"]
18
+
19
+ spec.add_dependency "builder"
20
+ spec.add_dependency "xml-simple"
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.3"
23
+ spec.add_development_dependency "rake"
24
+ spec.add_development_dependency "rspec"
25
+ spec.add_development_dependency "debugger"
26
+ end
metadata ADDED
@@ -0,0 +1,154 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: trebbianno-ruby-api
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Justin Grubbs
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-07-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: builder
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: xml-simple
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '1.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '1.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: debugger
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Ruby Library for Trebbianno Fulfillment API
98
+ email:
99
+ - justin@sellect.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - .gitignore
105
+ - .rspec
106
+ - .travis.yml
107
+ - Gemfile
108
+ - LICENSE.txt
109
+ - README.md
110
+ - Rakefile
111
+ - lib/trebbianno.rb
112
+ - lib/trebbianno/client.rb
113
+ - lib/trebbianno/country.rb
114
+ - lib/trebbianno/inventory.rb
115
+ - lib/trebbianno/order.rb
116
+ - lib/trebbianno/request.rb
117
+ - lib/trebbianno/response.rb
118
+ - lib/trebbianno/state.rb
119
+ - lib/trebbianno/tracking.rb
120
+ - lib/trebbianno/version.rb
121
+ - spec/lib/client_spec.rb
122
+ - spec/lib/order_spec.rb
123
+ - spec/lib/soap_spec.rb
124
+ - spec/spec_helper.rb
125
+ - trebbianno.gemspec
126
+ homepage: http://sellect.com
127
+ licenses:
128
+ - MIT
129
+ metadata: {}
130
+ post_install_message:
131
+ rdoc_options: []
132
+ require_paths:
133
+ - lib
134
+ required_ruby_version: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - '>='
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ required_rubygems_version: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - '>='
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ requirements: []
145
+ rubyforge_project:
146
+ rubygems_version: 2.0.6
147
+ signing_key:
148
+ specification_version: 4
149
+ summary: This is a library for interfacing with the Trebbianno Fulfillment API
150
+ test_files:
151
+ - spec/lib/client_spec.rb
152
+ - spec/lib/order_spec.rb
153
+ - spec/lib/soap_spec.rb
154
+ - spec/spec_helper.rb