trebbianno-ruby-api 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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