brownie 0.1.1 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4f5bf4bff9ea80abaf061bd214b6647eac94c776
4
- data.tar.gz: 75255b947c46c07b5bf386f7bed90b6e716a2b6b
3
+ metadata.gz: 5272fa1331a8f96bfbb00999011a2434a37339f7
4
+ data.tar.gz: 640b647d7426a7b7c4c3f918badff18029e551bd
5
5
  SHA512:
6
- metadata.gz: 38f572c6733ce215f1c96d84a2c9551f76cb0b7006f8746ea70a26dfb955273ad87efcc919cd96d632b780d8ea9986556b6daf3f4fccab2b82aaaf5f7a6fe39e
7
- data.tar.gz: d65858f0951cb5b565795fa366c012be421668c8ee0595ef3097e46ee73379dd898d1de90df8de69cd58efdf6b0e5314f23c4e6281442573201486de89779eda
6
+ metadata.gz: 30875b266eef846deb71d47104a2afbedfd38c26c6afe355e58da5403d549f183f969cad03fdbe6660e1d90c0cafcbdc95a3442feb930fd0ab9bc99c587c1403
7
+ data.tar.gz: 888e25e2689fec4c31f8e557459802ae3881906d5802389c66a4060fb7766f88ca0a85f2c8ca8e06972875fac1cd533593e2043c74358879a21cabb3832bf612
data/Gemfile CHANGED
@@ -7,7 +7,7 @@ gem "rest_client", ">= 1.7"
7
7
  # Add dependencies to develop your gem here.
8
8
  # Include everything needed to run rake, tests, features, etc.
9
9
  group :development do
10
- gem "shoulda", ">= 0"
10
+ gem "rspec", "~> 2.8.0"
11
11
  gem "rdoc", "~> 3.12"
12
12
  gem "bundler", "~> 1.0"
13
13
  gem "jeweler", "~> 2.0.1"
data/Gemfile.lock CHANGED
@@ -12,6 +12,7 @@ GEM
12
12
  builder (3.2.2)
13
13
  descendants_tracker (0.0.4)
14
14
  thread_safe (~> 0.3, >= 0.3.1)
15
+ diff-lcs (1.1.3)
15
16
  docile (1.1.3)
16
17
  faraday (0.9.0)
17
18
  multipart-post (>= 1.2, < 3)
@@ -59,12 +60,14 @@ GEM
59
60
  json (~> 1.4)
60
61
  rest_client (1.7.3)
61
62
  netrc (~> 0.7.7)
62
- shoulda (3.5.0)
63
- shoulda-context (~> 1.0, >= 1.0.1)
64
- shoulda-matchers (>= 1.4.1, < 3.0)
65
- shoulda-context (1.1.6)
66
- shoulda-matchers (2.5.0)
67
- activesupport (>= 3.0.0)
63
+ rspec (2.8.0)
64
+ rspec-core (~> 2.8.0)
65
+ rspec-expectations (~> 2.8.0)
66
+ rspec-mocks (~> 2.8.0)
67
+ rspec-core (2.8.0)
68
+ rspec-expectations (2.8.0)
69
+ diff-lcs (~> 1.1.2)
70
+ rspec-mocks (2.8.0)
68
71
  simplecov (0.8.2)
69
72
  docile (~> 1.1.0)
70
73
  multi_json
@@ -83,5 +86,5 @@ DEPENDENCIES
83
86
  jeweler (~> 2.0.1)
84
87
  rdoc (~> 3.12)
85
88
  rest_client (>= 1.7)
86
- shoulda
89
+ rspec (~> 2.8.0)
87
90
  simplecov
data/README.markdown CHANGED
@@ -1,11 +1,11 @@
1
1
  # brownie
2
2
 
3
- Brownie helps you create shipments via UPS.com's developer api. You can create shipments, and labels.
3
+ Brownie helps you create shipments via UPS.com's developer api. This gem is a work in progress. You can create shipments, and labels.
4
4
 
5
5
  Future releasess will have address valdation, and tracking
6
6
 
7
7
  ## Install
8
- gem 'brownie', '~> 0.1.0'
8
+ gem 'brownie', '~> 0.1.1'
9
9
 
10
10
 
11
11
  ## Usage
@@ -48,6 +48,8 @@ Future releasess will have address valdation, and tracking
48
48
  b.package_type = Brownie::Package::BOX
49
49
  b.declared_value = 100
50
50
 
51
+ b.environment = "production" # defaulted to development
52
+
51
53
  # Confirm and Validate Shipment
52
54
  if b.confirm
53
55
  puts b.tracking_number
@@ -60,6 +62,13 @@ Future releasess will have address valdation, and tracking
60
62
  b.label(b.shipment_digest,"/path/to/save/label.gif")
61
63
 
62
64
 
65
+ ## TODO
66
+
67
+ * Spruce up Shipping class so population of xml fields is cleaner
68
+ * Add addresss validation
69
+ * Run rspec tests on shipping confirmation and shipping acceptance.
70
+ * Add more local validations and error checking
71
+
63
72
 
64
73
 
65
74
  ## Contributing to brownie
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.2.0
data/brownie.gemspec CHANGED
@@ -2,15 +2,15 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: brownie 0.1.1 ruby lib
5
+ # stub: brownie 0.2.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "brownie"
9
- s.version = "0.1.1"
9
+ s.version = "0.2.0"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.authors = ["Michael Jaffe"]
13
- s.date = "2014-03-29"
13
+ s.date = "2014-04-18"
14
14
  s.description = "Creates UPS shipments and labels via UPS.com's developer api."
15
15
  s.email = "mike@mikewritescode.com"
16
16
  s.extra_rdoc_files = [
@@ -27,9 +27,12 @@ Gem::Specification.new do |s|
27
27
  "VERSION",
28
28
  "brownie.gemspec",
29
29
  "lib/brownie.rb",
30
+ "lib/brownie/common.rb",
30
31
  "lib/brownie/credentials.rb",
32
+ "lib/brownie/package.rb",
31
33
  "lib/brownie/ship_from.rb",
32
34
  "lib/brownie/ship_to.rb",
35
+ "lib/brownie/shipment.rb",
33
36
  "lib/brownie/shipper.rb",
34
37
  "test/helper.rb",
35
38
  "test/test_brownie.rb",
@@ -47,7 +50,7 @@ Gem::Specification.new do |s|
47
50
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
48
51
  s.add_runtime_dependency(%q<activesupport>, [">= 3.2.2"])
49
52
  s.add_runtime_dependency(%q<rest_client>, [">= 1.7"])
50
- s.add_development_dependency(%q<shoulda>, [">= 0"])
53
+ s.add_development_dependency(%q<rspec>, ["~> 2.8.0"])
51
54
  s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
52
55
  s.add_development_dependency(%q<bundler>, ["~> 1.0"])
53
56
  s.add_development_dependency(%q<jeweler>, ["~> 2.0.1"])
@@ -55,7 +58,7 @@ Gem::Specification.new do |s|
55
58
  else
56
59
  s.add_dependency(%q<activesupport>, [">= 3.2.2"])
57
60
  s.add_dependency(%q<rest_client>, [">= 1.7"])
58
- s.add_dependency(%q<shoulda>, [">= 0"])
61
+ s.add_dependency(%q<rspec>, ["~> 2.8.0"])
59
62
  s.add_dependency(%q<rdoc>, ["~> 3.12"])
60
63
  s.add_dependency(%q<bundler>, ["~> 1.0"])
61
64
  s.add_dependency(%q<jeweler>, ["~> 2.0.1"])
@@ -64,7 +67,7 @@ Gem::Specification.new do |s|
64
67
  else
65
68
  s.add_dependency(%q<activesupport>, [">= 3.2.2"])
66
69
  s.add_dependency(%q<rest_client>, [">= 1.7"])
67
- s.add_dependency(%q<shoulda>, [">= 0"])
70
+ s.add_dependency(%q<rspec>, ["~> 2.8.0"])
68
71
  s.add_dependency(%q<rdoc>, ["~> 3.12"])
69
72
  s.add_dependency(%q<bundler>, ["~> 1.0"])
70
73
  s.add_dependency(%q<jeweler>, ["~> 2.0.1"])
@@ -0,0 +1,25 @@
1
+ module Brownie
2
+ class Common
3
+ def self.domain
4
+ staging = "wwwcie.ups.com"
5
+ production = "onlinetools.ups.com"
6
+ return staging if ENV["RAILS_ENV"]
7
+
8
+ if self.environment.nil?
9
+ staging
10
+ elsif self.environment == "production"
11
+ production
12
+ else
13
+ staging
14
+ end
15
+ end
16
+
17
+ def self.template_to_hash(template,root="ShipmentConfirmRequest")
18
+ xml_path = File.join(File.dirname(File.expand_path(__FILE__)), "../../xml/#{template}.xml")
19
+ digest_xml_file = File.open(xml_path, "rb")
20
+ xml = digest_xml_file.read
21
+ hash = Hash.from_xml(xml)
22
+ hash[root]
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,64 @@
1
+ module Brownie
2
+ class Package
3
+
4
+ LETTER = "01"
5
+ CUSTOMER_SUPPLIED_PACKAGE = "02"
6
+ TUBE = "03"
7
+ PAK = "04"
8
+ UPS_EXPRESS_BOX = "21"
9
+ UPS_25KG_BOX = "24"
10
+ UPS_10KG_BOX = "25"
11
+ PALLET = "30"
12
+ SMALL_EXPRESS_BOX = "2a"
13
+ MEDIUM_EXPRESS_BOX = "2b"
14
+ LARGE_EXPRESS_BOX = "2c"
15
+ FLATS = "56"
16
+ PARCELS = "57"
17
+ BPM = "58"
18
+ FIRST_CLASS = "59"
19
+ PRIORITY = "60"
20
+ MACHINABLES = "61"
21
+ IRREGULARS = "62"
22
+ PARCEL_POST = "63"
23
+ BPM_PARCEL = "64"
24
+ MEDIA_MAIL = "65"
25
+ BPM_FLAT = "66"
26
+ STANDARD_FLAT = "67"
27
+
28
+
29
+ attr_accessor :package_type,:unit_of_measurement,:length,:width,:height,:weight,:declared_value
30
+
31
+
32
+ def create
33
+ data = Hash.from_xml(template)["Package"]
34
+ data["PackagingType"]["Code"] = self.package_type
35
+ data["PackageServiceOptions"]["InsuredValue"]["MonetaryValue"] = self.declared_value.to_s
36
+ data["PackageWeight"]["Weight"] = self.weight.nil? ? 1.0.to_s : self.weight.to_s
37
+ data["Dimensions"]["UnitOfMeasurement"]["Code"] = self.unit_of_measurement
38
+ data["Dimensions"]["Length"] = self.length
39
+ data["Dimensions"]["Width"] = self.width
40
+ data["Dimensions"]["Height"] = self.height
41
+ return data
42
+ end
43
+
44
+ private
45
+ def template
46
+ '<Package>
47
+ <PackagingType>
48
+ <Code></Code>
49
+ </PackagingType>
50
+ <Dimensions>
51
+ <UnitOfMeasurement> <Code></Code> </UnitOfMeasurement>
52
+ <Length></Length> <Width></Width> <Height></Height>
53
+ </Dimensions>
54
+ <PackageWeight>
55
+ <Weight></Weight>
56
+ </PackageWeight>
57
+ <PackageServiceOptions>
58
+ <InsuredValue> <MonetaryValue></MonetaryValue>
59
+ </InsuredValue>
60
+ </PackageServiceOptions>
61
+ </Package>'
62
+ end
63
+ end
64
+ end
@@ -1,8 +1,39 @@
1
1
  module Brownie
2
- class ShipFrom < ShipTo
2
+ class ShipFrom
3
3
  attr_accessor :company_name,:attention_name,:phone_number,:attention_name,:address_line1,:address_line2,:city,:state_province_code,:postal_code,:country_code
4
4
 
5
5
 
6
+ def create
7
+ data = Hash.from_xml(template)["ShipFrom"]
8
+ data["CompanyName"] = self.company_name
9
+ data["AttentionName"] = self.attention_name
10
+ data["PhoneNumber"] = self.phone_number
11
+ data["AttentionName"] = self.attention_name
12
+ data["Address"]["AddressLine1"] = self.address_line1
13
+ data["Address"]["AddressLine2"] = self.address_line2 if !self.address_line2.nil?
14
+ data["Address"]["City"] = self.city
15
+ data["Address"]["StateProvinceCode"] = self.state_province_code
16
+ data["Address"]["PostalCode"] = self.postal_code
17
+ data["Address"]["CountryCode"] = self.country_code
18
+ return data
19
+ end
6
20
 
21
+ private
22
+ def template
23
+ '<ShipFrom>
24
+ <CompanyName></CompanyName>
25
+ <AttentionName></AttentionName>
26
+ <PhoneNumber></PhoneNumber>
27
+ <TaxIdentificationNumber></TaxIdentificationNumber>
28
+ <Address>
29
+ <AddressLine1></AddressLine1>
30
+ <City></City>
31
+ <StateProvinceCode></StateProvinceCode>
32
+ <PostalCode></PostalCode>
33
+ <CountryCode></CountryCode>
34
+ </Address>
35
+ </ShipFrom>'
36
+ end
7
37
  end
38
+
8
39
  end
@@ -2,6 +2,35 @@ module Brownie
2
2
  class ShipTo
3
3
  attr_accessor :company_name,:attention_name,:phone_number,:attention_name,:address_line1,:address_line2,:city,:state_province_code,:postal_code,:country_code
4
4
 
5
+ def create
6
+ data = Hash.from_xml(template)["ShipTo"]
7
+ data["CompanyName"] = self.company_name
8
+ data["AttentionName"] = self.attention_name
9
+ data["PhoneNumber"] = self.phone_number
10
+ data["AttentionName"] = self.attention_name
11
+ data["Address"]["AddressLine1"] = self.address_line1
12
+ data["Address"]["AddressLine2"] = self.address_line2 if !self.address_line2.nil?
13
+ data["Address"]["City"] = self.city
14
+ data["Address"]["StateProvinceCode"] = self.state_province_code
15
+ data["Address"]["PostalCode"] = self.postal_code
16
+ data["Address"]["CountryCode"] = self.country_code
17
+ return data
18
+ end
5
19
 
20
+ private
21
+ def template
22
+ '<ShipTo>
23
+ <CompanyName></CompanyName>
24
+ <AttentionName></AttentionName>
25
+ <PhoneNumber></PhoneNumber>
26
+ <Address>
27
+ <AddressLine1></AddressLine1>
28
+ <City></City>
29
+ <StateProvinceCode></StateProvinceCode>
30
+ <PostalCode></PostalCode>
31
+ <CountryCode></CountryCode>
32
+ </Address>
33
+ </ShipTo>'
34
+ end
6
35
  end
7
36
  end
@@ -0,0 +1,98 @@
1
+ require 'active_support/all'
2
+ require 'rest_client'
3
+ module Brownie
4
+
5
+
6
+
7
+ class Shipment
8
+ attr_accessor :request,:errors,:account_number,:tracking_number,:shipment_digest,:credentials,:shipper,:ship_to,
9
+ :ship_from,:response,:service_code,:label_binary,:api_domain,
10
+ :environment,:data,:shipment_xml,:template,:package
11
+
12
+
13
+ def initialize(shipment=nil)
14
+ self.shipment_data = shipment if !shipment.nil?
15
+ self.credentials = Credentials.new
16
+ self.shipper = Shipper.new
17
+ self.ship_to = ShipTo.new
18
+ self.ship_from = ShipFrom.new
19
+ self.package = Package.new
20
+ self.template = Common::template_to_hash(:ship_confirm)
21
+
22
+ end
23
+
24
+
25
+
26
+ def confirm
27
+
28
+ data = self.template["Shipment"]
29
+ data["PaymentInformation"]["Prepaid"]["BillShipper"]["AccountNumber"] = self.account_number
30
+ data["Service"]["Code"] = self.service_code
31
+ data["Package"] = self.package.create
32
+ data["Shipper"] = self.shipper.create
33
+ data["ShipTo"] = self.ship_to.create
34
+ data["ShipFrom"] = self.ship_from.create
35
+
36
+ self.template["Shipment"] = data
37
+ request_template = {"ShipmentConfirmRequest" => self.template}
38
+ shipment_xml_str = request_template["ShipmentConfirmRequest"].to_xml(:root => "ShipmentConfirmRequest")
39
+
40
+ self.response = RestClient.post("https://#{Common::domain}/ups.app/xml/ShipConfirm","#{access_request_header}#{shipment_xml_str}")
41
+ if self.response.code.eql?(200)
42
+ response_hash = Hash.from_xml(response)
43
+ if response_hash["ShipmentConfirmResponse"]["Response"]["ResponseStatusCode"].eql?("0")
44
+ self.errors = response_hash["ShipmentConfirmResponse"]["Response"]["Error"]
45
+ return false
46
+ end
47
+
48
+ self.tracking_number = response_hash["ShipmentConfirmResponse"]["ShipmentIdentificationNumber"]
49
+ self.shipment_digest = response_hash["ShipmentConfirmResponse"]["ShipmentDigest"]
50
+ return true
51
+
52
+ else
53
+ raise "In-valid request #{response}"
54
+ end
55
+ end
56
+
57
+ def label(_shipment_digest,path)
58
+ shipment_digest = _shipment_digest.nil? ? @shipment_digest : _shipment_digest
59
+ label_xml = '<?xml version="1.0" encoding="ISO-8859-1"?>
60
+ <ShipmentAcceptRequest>
61
+ <Request>
62
+ <TransactionReference>
63
+ <CustomerContext></CustomerContext>
64
+ </TransactionReference>
65
+ <RequestAction>ShipAccept</RequestAction>
66
+ <RequestOption>1</RequestOption>
67
+ </Request>
68
+ <ShipmentDigest>' + shipment_digest + '</ShipmentDigest>
69
+ </ShipmentAcceptRequest>'
70
+
71
+
72
+
73
+
74
+ label_response = RestClient.post("https://#{Common::domain}/ups.app/xml/ShipAccept","#{access_request_header}#{label_xml}")
75
+ label_hash = Hash.from_xml(label_response)
76
+ self.label_binary = label_hash["ShipmentAcceptResponse"]["ShipmentResults"]["PackageResults"]["LabelImage"]["GraphicImage"]
77
+ File.open(path, 'wb') do|f|
78
+ f.write(Base64.decode64(self.label_binary))
79
+ end
80
+
81
+ end
82
+
83
+
84
+ private
85
+ def access_request_header
86
+ '<?xml version="1.0"?>
87
+ <AccessRequest xml:lang="en-US">
88
+ <AccessLicenseNumber>' + self.credentials.license_number + '</AccessLicenseNumber>
89
+ <UserId>' + self.credentials.user_id + '</UserId>
90
+ <Password>' + self.credentials.password + '</Password>
91
+ </AccessRequest>'
92
+ end
93
+
94
+ end
95
+
96
+
97
+
98
+ end
@@ -5,5 +5,38 @@ module Brownie
5
5
  :address_line1,:address_line2,:city,:state_province_code,:postal_code,:country_code
6
6
 
7
7
 
8
+
9
+ def create
10
+ data = Hash.from_xml(template)["Shipper"]
11
+ data["Name"] = self.name
12
+ data["PhoneNumber"] = self.phone_number
13
+ data["ShipperNumber"] = self.account_number
14
+ data["TaxIdentificationNumber"] = self.tax_identification_number
15
+ data["Address"]["AddressLine1"] = self.address_line1
16
+ data["Address"]["AddressLine2"] = self.address_line2 if !self.address_line2.nil?
17
+ data["Address"]["City"] = self.city
18
+ data["Address"]["StateProvinceCode"] = self.state_province_code
19
+ data["Address"]["PostalCode"] = self.postal_code
20
+ data["Address"]["CountryCode"] = self.country_code
21
+ return data
22
+ end
23
+
24
+ private
25
+ def template
26
+ ' <Shipper>
27
+ <Name></Name>
28
+ <PhoneNumber></PhoneNumber>
29
+ <ShipperNumber></ShipperNumber>
30
+ <TaxIdentificationNumber></TaxIdentificationNumber>
31
+ <Address>
32
+ <AddressLine1></AddressLine1>
33
+ <City></City>
34
+ <StateProvinceCode></StateProvinceCode>
35
+ <PostalCode></PostalCode>
36
+ <PostcodeExtendedLow />
37
+ <CountryCode></CountryCode>
38
+ </Address>
39
+ </Shipper>'
40
+ end
8
41
  end
9
42
  end
data/lib/brownie.rb CHANGED
@@ -1,180 +1,40 @@
1
1
  require 'active_support/all'
2
2
  require 'rest_client'
3
+ require 'brownie/common'
3
4
  require 'brownie/credentials'
4
5
  require 'brownie/shipper'
5
6
  require 'brownie/ship_to'
6
7
  require 'brownie/ship_from'
8
+ require 'brownie/package'
9
+ require 'brownie/shipment'
7
10
  module Brownie
8
-
9
-
10
-
11
- class Shipment
12
- attr_accessor :request,:errors,:account_number,:tracking_number,:shipment_digest,:credentials,:shipper,:ship_to,
13
- :ship_from,:response,:service_code,:package_type,:declared_value,:package_weight,:label_binary,:api_domain,:environment
14
-
15
- attr_writer :shipment_data,:shipment_xml
16
-
17
11
 
18
- def initialize(shipment=nil)
19
- self.shipment_data = shipment if !shipment.nil?
20
- self.credentials = Credentials.new
21
- self.shipper = Shipper.new
22
- self.ship_to = ShipTo.new
23
- self.ship_from = ShipFrom.new
24
-
25
- end
26
-
27
-
28
-
29
- def confirm
30
- test = template_hash
31
- shipment = test["ShipmentConfirmRequest"]["Shipment"]
32
-
33
- shipment["PaymentInformation"]["Prepaid"]["BillShipper"]["AccountNumber"] = self.account_number
34
- shipment["Service"]["Code"] = self.service_code
35
- shipment["Package"]["PackagingType"]["Code"] = self.package_type
36
- shipment["Package"]["PackageServiceOptions"]["InsuredValue"]["MonetaryValue"] = self.declared_value.to_s
37
- shipment["Package"]["PackageWeight"]["Weight"] = self.package_weight.nil? ? 1.0.to_s : self.package_weight.to_s
38
-
39
- shipment["Shipper"]["Name"] = self.shipper.name
40
- shipment["Shipper"]["PhoneNumber"] = self.shipper.phone_number
41
- shipment["Shipper"]["ShipperNumber"] = self.account_number
42
- shipment["Shipper"]["TaxIdentificationNumber"] = self.shipper.tax_identification_number
43
- shipment["Shipper"]["Address"]["AddressLine1"] = self.shipper.address_line1
44
- shipment["Shipper"]["Address"]["AddressLine2"] = self.shipper.address_line2 if !self.shipper.address_line2.nil?
45
- shipment["Shipper"]["Address"]["City"] = self.shipper.city
46
- shipment["Shipper"]["Address"]["StateProvinceCode"] = self.shipper.state_province_code
47
- shipment["Shipper"]["Address"]["PostalCode"] = self.shipper.postal_code
48
- shipment["Shipper"]["Address"]["CountryCode"] = self.shipper.country_code
49
-
50
-
51
- shipto = shipment["ShipTo"]
52
- shipto["CompanyName"] = self.ship_to.company_name
53
- shipto["AttentionName"] = self.ship_to.attention_name
54
- shipto["PhoneNumber"] = self.ship_to.phone_number
55
- shipto["AttentionName"] = self.ship_to.attention_name
56
- shipto["Address"]["AddressLine1"] = self.ship_to.address_line1
57
- shipto["Address"]["AddressLine2"] = self.ship_to.address_line2 if !self.ship_to.address_line2.nil?
58
- shipto["Address"]["City"] = self.ship_to.city
59
- shipto["Address"]["StateProvinceCode"] = self.ship_to.state_province_code
60
- shipto["Address"]["PostalCode"] = self.ship_to.postal_code
61
- shipto["Address"]["CountryCode"] = self.ship_to.country_code
62
-
63
-
64
- shipfrom = shipment["ShipFrom"]
65
- shipfrom["CompanyName"] = self.ship_from.company_name
66
- shipfrom["AttentionName"] = self.ship_from.attention_name
67
- shipfrom["PhoneNumber"] = self.ship_from.phone_number
68
- shipfrom["AttentionName"] = self.ship_from.attention_name
69
- shipfrom["Address"]["AddressLine1"] = self.ship_from.address_line1
70
- shipfrom["Address"]["AddressLine2"] = self.ship_from.address_line2 if !self.ship_from.address_line2.nil?
71
- shipfrom["Address"]["City"] = self.ship_from.city
72
- shipfrom["Address"]["StateProvinceCode"] = self.ship_from.state_province_code
73
- shipfrom["Address"]["PostalCode"] = self.ship_from.postal_code
74
- shipfrom["Address"]["CountryCode"] = self.ship_from.country_code
75
-
76
-
77
- shipment_xml_str = test["ShipmentConfirmRequest"].to_xml(:root => "ShipmentConfirmRequest")
78
-
79
- self.response = RestClient.post("https://#{domain}/ups.app/xml/ShipConfirm","#{access_request_header}#{shipment_xml_str}")
80
- if self.response.code.eql?(200)
81
- response_hash = Hash.from_xml(response)
82
- if response_hash["ShipmentConfirmResponse"]["Response"]["ResponseStatusCode"].eql?("0")
83
- self.errors = response_hash["ShipmentConfirmResponse"]["Response"]["Error"]
84
- return false
85
- end
86
-
87
- self.tracking_number = response_hash["ShipmentConfirmResponse"]["ShipmentIdentificationNumber"]
88
- self.shipment_digest = response_hash["ShipmentConfirmResponse"]["ShipmentDigest"]
89
- return true
90
-
91
- else
92
- raise "In-valid request #{response}"
93
- end
94
- end
95
-
96
- def label(_shipment_digest,path)
97
- shipment_digest = _shipment_digest.nil? ? @shipment_digest : _shipment_digest
98
- label_xml = '<?xml version="1.0" encoding="ISO-8859-1"?>
99
- <ShipmentAcceptRequest>
100
- <Request>
101
- <TransactionReference>
102
- <CustomerContext></CustomerContext>
103
- </TransactionReference>
104
- <RequestAction>ShipAccept</RequestAction>
105
- <RequestOption>1</RequestOption>
106
- </Request>
107
- <ShipmentDigest>' + shipment_digest + '</ShipmentDigest>
108
- </ShipmentAcceptRequest>'
109
-
110
-
111
-
112
-
113
- label_response = RestClient.post("https://#{domain}/ups.app/xml/ShipAccept","#{access_request_header}#{label_xml}")
114
- label_hash = Hash.from_xml(label_response)
115
- self.label_binary = label_hash["ShipmentAcceptResponse"]["ShipmentResults"]["PackageResults"]["LabelImage"]["GraphicImage"]
116
- File.open(path, 'wb') do|f|
117
- f.write(Base64.decode64(self.label_binary))
118
- end
119
-
120
- end
121
-
122
-
123
- private
124
- def domain
125
- if self.environment.nil?
126
- "wwwcie.ups.com"
127
- elsif self.environment == "production"
128
- "onlinetools.ups.com"
129
- else
130
- "wwwcie.ups.com"
131
- end
132
- end
133
-
134
- def template_hash
135
- xml_path = File.join(File.dirname(File.expand_path(__FILE__)), "../xml/ship_confirm.xml")
136
- digest_xml_file = File.open(xml_path, "rb")
137
- @shipment_xml = digest_xml_file.read
138
- Hash.from_xml(@shipment_xml)
139
- end
140
-
141
- def access_request_header
142
- '<?xml version="1.0"?>
143
- <AccessRequest xml:lang="en-US">
144
- <AccessLicenseNumber>' + self.credentials.license_number + '</AccessLicenseNumber>
145
- <UserId>' + self.credentials.user_id + '</UserId>
146
- <Password>' + self.credentials.password + '</Password>
147
- </AccessRequest>'
148
- end
149
12
 
13
+ class Dimensions
14
+ INCHES = "IN"
15
+ CENTIMETERS = "CM"
16
+ METRIC_UNITS_OF_MEASUREMENT = "00"
17
+ ENGLISH_UNITS_OF_MEASUREMENT = "01"
150
18
  end
151
19
 
152
-
153
- class Package
154
- BAG = "01"
155
- BOX = "02"
156
- CARTON = "03"
157
- CRATE = "04"
158
- DRUM = "05"
159
- PALLET = "06"
160
- ROLL = "07"
161
- TUBE = "08"
20
+ class Weight
21
+ POUNDS = "LBS"
22
+ KILOGRAMS = "KGS"
23
+ METRIC_UNITS_OF_MEASUREMENT = "00"
24
+ ENGLISH_UNITS_OF_MEASUREMENT = "01"
162
25
  end
163
26
 
164
27
  class ServiceCodes
165
- STANDARD = "11"
28
+ NEXT_DAY_AIR = "01"
29
+ SECOND_DAY_AIR = "02"
166
30
  GROUND = "03"
167
- E3DAYSELECT = "12"
168
- E2NDDAYAIR = "02"
169
- E2NDDAYAIRAM = "59"
170
- NEXTDAYAIRSAVER = "13"
171
- NEXTDAYAIR = "01"
172
- NEXTDAYAIREARLYAM = "14"
173
- UPSWORLDWIDEEXPRESS = "07"
174
- WORLDWIDEEXPRESSPLUS = "54"
175
- UPSWORDWIDESAVER = "65"
176
- UPSWORLDWIDEEXPEDITED = "08"
177
-
31
+ EXPRESS = "07"
32
+ Expedited = "08"
33
+ Ups_Standard = "11"
34
+ THREE_DAY_SELECT = "12"
35
+ NEXT_DAY_AIR_SAVER = "13"
36
+ NEXT_DAY_AIR_EARLY_AM = "14"
37
+ EXPRESS_PLUS = "54"
178
38
  end
179
39
 
180
40
 
data/xml/ship_confirm.xml CHANGED
@@ -77,10 +77,13 @@
77
77
  <PackagingType>
78
78
  <Code></Code>
79
79
  </PackagingType>
80
+ <Dimensions>
81
+ <UnitOfMeasurement> <Code></Code> </UnitOfMeasurement>
82
+ <Length></Length> <Width></Width> <Height></Height>
83
+ </Dimensions>
80
84
  <PackageWeight>
81
- <Weight></Weight>
82
- </PackageWeight>
83
-
85
+ <Weight></Weight>
86
+ </PackageWeight>
84
87
  <PackageServiceOptions>
85
88
  <InsuredValue> <MonetaryValue></MonetaryValue>
86
89
  </InsuredValue>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brownie
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Jaffe
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-29 00:00:00.000000000 Z
11
+ date: 2014-04-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -39,19 +39,19 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.7'
41
41
  - !ruby/object:Gem::Dependency
42
- name: shoulda
42
+ name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ~>
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: 2.8.0
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ~>
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: 2.8.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rdoc
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -125,9 +125,12 @@ files:
125
125
  - VERSION
126
126
  - brownie.gemspec
127
127
  - lib/brownie.rb
128
+ - lib/brownie/common.rb
128
129
  - lib/brownie/credentials.rb
130
+ - lib/brownie/package.rb
129
131
  - lib/brownie/ship_from.rb
130
132
  - lib/brownie/ship_to.rb
133
+ - lib/brownie/shipment.rb
131
134
  - lib/brownie/shipper.rb
132
135
  - test/helper.rb
133
136
  - test/test_brownie.rb