active_shipping 0.9.13 → 0.9.14
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +20 -36
- data/lib/active_shipping.rb +2 -1
- data/lib/active_shipping/shipping/carriers/canada_post.rb +4 -11
- data/lib/active_shipping/shipping/carriers/fedex.rb +5 -6
- data/lib/active_shipping/shipping/carriers/new_zealand_post.rb +229 -99
- data/lib/active_shipping/shipping/carriers/shipwire.rb +23 -6
- data/lib/active_shipping/shipping/carriers/ups.rb +7 -3
- data/lib/active_shipping/shipping/location.rb +38 -10
- data/lib/active_shipping/shipping/package.rb +3 -3
- data/lib/active_shipping/shipping/rate_estimate.rb +11 -3
- data/lib/active_shipping/shipping/shipment_packer.rb +48 -0
- data/lib/active_shipping/version.rb +2 -2
- data/lib/vendor/quantified/lib/quantified.rb +1 -3
- data/lib/vendor/quantified/lib/quantified/attribute.rb +14 -14
- data/lib/vendor/quantified/test/test_helper.rb +9 -1
- data/lib/vendor/test_helper.rb +1 -7
- metadata +81 -16
- data/lib/active_merchant/common.rb +0 -14
- data/lib/active_merchant/common/connection.rb +0 -162
- data/lib/active_merchant/common/country.rb +0 -328
- data/lib/active_merchant/common/error.rb +0 -26
- data/lib/active_merchant/common/post_data.rb +0 -24
- data/lib/active_merchant/common/posts_data.rb +0 -61
- data/lib/active_merchant/common/requires_parameters.rb +0 -16
- data/lib/active_merchant/common/utils.rb +0 -18
- data/lib/active_merchant/common/validateable.rb +0 -76
- data/lib/certs/cacert.pem +0 -7815
data/README.markdown
CHANGED
@@ -1,14 +1,11 @@
|
|
1
1
|
# Active Shipping
|
2
2
|
|
3
|
-
This library
|
3
|
+
This library interfaces with the web services of various shipping carriers. The goal is to abstract the features that are most frequently used into a pleasant and consistent Ruby API. Active Shipping is an extension of [Active Merchant][], and as such, it borrows heavily from conventions used in the latter.
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
Active Shipping is currently being used and improved in a production environment for the e-commerce application [Shopify][]. Development is being done by [James MacAulay][] (<james@jadedpixel.com>). Discussion is welcome in the [Active Merchant Google Group][discuss].
|
5
|
+
Active Shipping is currently being used and improved in a production environment for [Shopify][]. Development is being done by the Shopify integrations team (<integrations-team@shopify.com>). Discussion is welcome in the [Active Merchant Google Group][discuss].
|
8
6
|
|
9
7
|
[Active Merchant]:http://www.activemerchant.org
|
10
8
|
[Shopify]:http://www.shopify.com
|
11
|
-
[James MacAulay]:http://jmacaulay.net
|
12
9
|
[discuss]:http://groups.google.com/group/activemerchant
|
13
10
|
|
14
11
|
## Supported Shipping Carriers
|
@@ -20,28 +17,11 @@ Active Shipping is currently being used and improved in a production environment
|
|
20
17
|
* [New Zealand Post](http://www.nzpost.co.nz)
|
21
18
|
* more soon!
|
22
19
|
|
23
|
-
##
|
24
|
-
|
25
|
-
* [active_support](http://github.com/rails/rails/tree/master/activesupport)
|
26
|
-
* [xml_node](http://github.com/tobi/xml_node/) (right now a version of it is actually included in this library, so you don't need to worry about it yet)
|
27
|
-
* [mocha](http://mocha.rubyforge.org/) for the tests
|
28
|
-
|
29
|
-
## Download & Installation
|
30
|
-
|
31
|
-
Currently this library is available on GitHub:
|
32
|
-
|
33
|
-
<http://github.com/Shopify/active_shipping>
|
34
|
-
|
35
|
-
You will need to get [Git][] if you don't have it. Then:
|
20
|
+
## Installation
|
36
21
|
|
37
|
-
|
22
|
+
gem install active_shipping
|
38
23
|
|
39
|
-
|
40
|
-
|
41
|
-
Active Shipping includes an init.rb file. This means that Rails will automatically load it on startup. Check out [git-archive][] for exporting the file tree from your repository to your vendor directory.
|
42
|
-
|
43
|
-
[Git]:http://git.or.cz/
|
44
|
-
[git-archive]:http://www.kernel.org/pub/software/scm/git/docs/git-archive.html
|
24
|
+
...or add it to your [Gemfile](http://gembundler.com/).
|
45
25
|
|
46
26
|
## Sample Usage
|
47
27
|
|
@@ -111,23 +91,27 @@ Active Shipping includes an init.rb file. This means that Rails will automatical
|
|
111
91
|
# Scanned at FedEx sort facility at KNOXVILLE, TN on Fri Oct 24 05:56:00 UTC 2008.
|
112
92
|
# Delivered at Knoxville, TN on Fri Oct 24 16:45:00 UTC 2008. Signed for by: T.BAKER
|
113
93
|
|
114
|
-
##
|
94
|
+
## Running the tests
|
115
95
|
|
116
|
-
|
117
|
-
* carrier code template generator
|
118
|
-
* more carriers
|
119
|
-
* support more features for existing carriers
|
120
|
-
* bin-packing algorithm (preferably implemented in ruby)
|
121
|
-
* order tracking
|
122
|
-
* label printing
|
96
|
+
After installing dependencies with `bundle install`, you can run the unit tests with `rake test:units` and the remote tests with `rake test:remote`. The unit tests mock out requests and responses so that everything runs locally, while the remote tests actually hit the carrier servers. For the remote tests, you'll need valid test credentials for any carriers' tests you want to run. The credentials should go in ~/.active_merchant/fixtures.yml, and the format of that file can be seen in the included [fixtures.yml](https://github.com/Shopify/active_shipping/blob/master/test/fixtures.yml).
|
123
97
|
|
124
98
|
## Contributing
|
125
99
|
|
126
100
|
Yes, please! Take a look at the tests and the implementation of the Carrier class to see how the basics work. At some point soon there will be a carrier template generator along the lines of the gateway generator included in Active Merchant, but carrier.rb outlines most of what's necessary. The other main classes that would be good to familiarize yourself with are Location, Package, and Response.
|
127
101
|
|
128
|
-
|
102
|
+
For the features you add, you should have both unit tests and remote tests. It's probably best to start with the remote tests, and then log those requests and responses and use them as the mocks for the unit tests. You can see how this works with the USPS tests right now:
|
103
|
+
|
104
|
+
https://github.com/Shopify/active_shipping/blob/master/test/remote/usps_test.rb
|
105
|
+
https://github.com/Shopify/active_shipping/blob/master/test/unit/carriers/usps_test.rb
|
106
|
+
https://github.com/Shopify/active_shipping/tree/master/test/fixtures/xml/usps
|
107
|
+
|
108
|
+
To log requests and responses, just set the `logger` on your carrier class to some kind of `Logger` object:
|
109
|
+
|
110
|
+
USPS.logger = Logger.new($stdout)
|
111
|
+
|
112
|
+
(This logging functionality is provided by the [`PostsData` module](https://github.com/Shopify/active_utils/blob/master/lib/active_utils/common/posts_data.rb) in the `active_utils` dependency.)
|
129
113
|
|
130
|
-
|
114
|
+
After you've pushed your well-tested changes to your github fork, make a pull request and we'll take it from there!
|
131
115
|
|
132
116
|
## Contributors
|
133
117
|
|
@@ -139,4 +123,4 @@ The nicest way to submit changes would be to set up a GitHub account and fork th
|
|
139
123
|
|
140
124
|
## Legal Mumbo Jumbo
|
141
125
|
|
142
|
-
Unless otherwise noted in specific files, all code in the Active Shipping project is under the copyright and license described in the included MIT-LICENSE file.
|
126
|
+
Unless otherwise noted in specific files, all code in the Active Shipping project is under the copyright and license described in the included MIT-LICENSE file.
|
data/lib/active_shipping.rb
CHANGED
@@ -35,7 +35,7 @@ autoload :XmlNode, 'vendor/xml_node/lib/xml_node'
|
|
35
35
|
autoload :Quantified, 'vendor/quantified/lib/quantified'
|
36
36
|
|
37
37
|
require 'net/https'
|
38
|
-
require '
|
38
|
+
require 'active_utils'
|
39
39
|
|
40
40
|
require 'active_shipping/shipping/base'
|
41
41
|
require 'active_shipping/shipping/response'
|
@@ -45,5 +45,6 @@ require 'active_shipping/shipping/package'
|
|
45
45
|
require 'active_shipping/shipping/location'
|
46
46
|
require 'active_shipping/shipping/rate_estimate'
|
47
47
|
require 'active_shipping/shipping/shipment_event'
|
48
|
+
require 'active_shipping/shipping/shipment_packer'
|
48
49
|
require 'active_shipping/shipping/carrier'
|
49
50
|
require 'active_shipping/shipping/carriers'
|
@@ -153,15 +153,14 @@ module ActiveMerchant
|
|
153
153
|
boxes = []
|
154
154
|
if success
|
155
155
|
xml.elements.each('eparcel/ratesAndServicesResponse/product') do |product|
|
156
|
-
service_name = (@options[:french] ? @@name_french : @@name) + product.get_text('name').to_s
|
156
|
+
service_name = (@options[:french] ? @@name_french : @@name) + " " + product.get_text('name').to_s
|
157
157
|
service_code = product.attribute('id').to_s
|
158
|
-
delivery_date = date_for(product.get_text('deliveryDate').to_s)
|
159
158
|
|
160
159
|
rate_estimates << RateEstimate.new(origin, destination, @@name, service_name,
|
161
160
|
:service_code => service_code,
|
162
161
|
:total_price => product.get_text('rate').to_s,
|
163
|
-
:
|
164
|
-
:
|
162
|
+
:currency => 'CAD',
|
163
|
+
:delivery_range => [product.get_text('deliveryDate').to_s] * 2
|
165
164
|
)
|
166
165
|
end
|
167
166
|
|
@@ -209,12 +208,6 @@ module ActiveMerchant
|
|
209
208
|
|
210
209
|
CanadaPostRateResponse.new(success, message, Hash.from_xml(response), :rates => rate_estimates, :xml => response, :boxes => boxes, :postal_outlets => postal_outlets)
|
211
210
|
end
|
212
|
-
|
213
|
-
def date_for(string)
|
214
|
-
string && Time.parse(string)
|
215
|
-
rescue ArgumentError
|
216
|
-
nil
|
217
|
-
end
|
218
211
|
|
219
212
|
def response_success?(xml)
|
220
213
|
value = xml.get_text('eparcel/ratesAndServicesResponse/statusCode').to_s
|
@@ -265,4 +258,4 @@ module ActiveMerchant
|
|
265
258
|
end
|
266
259
|
end
|
267
260
|
end
|
268
|
-
end
|
261
|
+
end
|
@@ -86,10 +86,7 @@ module ActiveMerchant
|
|
86
86
|
}
|
87
87
|
|
88
88
|
def self.service_name_for_code(service_code)
|
89
|
-
ServiceTypes[service_code] ||
|
90
|
-
name = service_code.downcase.split('_').collect{|word| word.capitalize }.join(' ')
|
91
|
-
"FedEx #{name.sub(/Fedex /, '')}"
|
92
|
-
end
|
89
|
+
ServiceTypes[service_code] || "FedEx #{service_code.titleize.sub(/Fedex /, '')}"
|
93
90
|
end
|
94
91
|
|
95
92
|
def requirements
|
@@ -218,6 +215,8 @@ module ActiveMerchant
|
|
218
215
|
xml_node << XmlNode.new('Address') do |address_node|
|
219
216
|
address_node << XmlNode.new('PostalCode', location.postal_code)
|
220
217
|
address_node << XmlNode.new("CountryCode", location.country_code(:alpha2))
|
218
|
+
|
219
|
+
address_node << XmlNode.new("Residential", true) unless location.commercial?
|
221
220
|
end
|
222
221
|
end
|
223
222
|
end
|
@@ -244,7 +243,7 @@ module ActiveMerchant
|
|
244
243
|
:total_price => rated_shipment.get_text('RatedShipmentDetails/ShipmentRateDetail/TotalNetCharge/Amount').to_s.to_f,
|
245
244
|
:currency => currency,
|
246
245
|
:packages => packages,
|
247
|
-
:
|
246
|
+
:delivery_range => [rated_shipment.get_text('DeliveryTimestamp').to_s] * 2)
|
248
247
|
end
|
249
248
|
|
250
249
|
if rate_estimates.empty?
|
@@ -316,7 +315,7 @@ module ActiveMerchant
|
|
316
315
|
|
317
316
|
def response_message(document)
|
318
317
|
response_node = response_status_node(document)
|
319
|
-
"#{response_status_node(document).get_text('Severity')
|
318
|
+
"#{response_status_node(document).get_text('Severity')} - #{response_node.get_text('Code')}: #{response_node.get_text('Message')}"
|
320
319
|
end
|
321
320
|
|
322
321
|
def commit(request, test = false)
|
@@ -2,138 +2,268 @@ module ActiveMerchant
|
|
2
2
|
module Shipping
|
3
3
|
class NewZealandPost < Carrier
|
4
4
|
|
5
|
-
# class NewZealandPostRateResponse < RateResponse
|
6
|
-
# end
|
7
|
-
|
8
5
|
cattr_reader :name
|
9
6
|
@@name = "New Zealand Post"
|
10
7
|
|
11
|
-
URL = "http://
|
8
|
+
URL = "http://api.nzpost.co.nz/ratefinder"
|
12
9
|
|
13
|
-
# Override to return required keys in options hash for initialize method.
|
14
10
|
def requirements
|
15
11
|
[:key]
|
16
12
|
end
|
17
13
|
|
18
|
-
# Override with whatever you need to get the rates
|
19
14
|
def find_rates(origin, destination, packages, options = {})
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
request_hash = build_tube_request_params(origin, destination, package, options)
|
25
|
-
else
|
26
|
-
request_hash = build_rectangular_request_params(origin, destination, package, options)
|
27
|
-
end
|
28
|
-
url = URL + '?' + request_hash.to_param
|
29
|
-
response = ssl_get(url)
|
30
|
-
rate_responses << parse_rate_response(origin, destination, package, response, options)
|
31
|
-
end
|
32
|
-
combine_rate_responses(rate_responses, packages)
|
33
|
-
end
|
34
|
-
|
35
|
-
def maximum_weight
|
36
|
-
Mass.new(20, :kilograms)
|
15
|
+
options = @options.merge(options)
|
16
|
+
request = RateRequest.from(origin, destination, packages, options)
|
17
|
+
request.raw_responses = commit(request.urls) if request.new_zealand_origin?
|
18
|
+
request.rate_response
|
37
19
|
end
|
38
20
|
|
39
21
|
protected
|
40
22
|
|
41
|
-
|
42
|
-
|
43
|
-
Location.new(:postal_code => '6011')
|
23
|
+
def commit(urls)
|
24
|
+
save_request(urls).map { |url| ssl_get(url) }
|
44
25
|
end
|
45
26
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
:
|
51
|
-
:
|
52
|
-
:
|
53
|
-
|
54
|
-
:thickness => "#{package.centimetres(:width) * 10}",
|
55
|
-
:length => "#{package.centimetres(:length) * 10}",
|
56
|
-
:weight =>"%.1f" % (package.weight.amount / 1000.0)
|
57
|
-
}
|
27
|
+
def self.default_location
|
28
|
+
Location.new({
|
29
|
+
:country => "NZ",
|
30
|
+
:city => "Wellington",
|
31
|
+
:address1 => "22 Waterloo Quay",
|
32
|
+
:address2 => "Pipitea",
|
33
|
+
:postal_code => "6011"
|
34
|
+
})
|
58
35
|
end
|
59
36
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
}
|
37
|
+
class NewZealandPostRateResponse < RateResponse
|
38
|
+
|
39
|
+
attr_reader :raw_responses
|
40
|
+
|
41
|
+
def initialize(success, message, params = {}, options = {})
|
42
|
+
@raw_responses = options[:raw_responses]
|
43
|
+
super
|
44
|
+
end
|
69
45
|
end
|
70
46
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
47
|
+
class RateRequest
|
48
|
+
|
49
|
+
attr_reader :urls
|
50
|
+
attr_writer :raw_responses
|
51
|
+
|
52
|
+
def self.from(*args)
|
53
|
+
return International.new(*args) unless domestic?(args[0..1])
|
54
|
+
Domestic.new(*args)
|
55
|
+
end
|
56
|
+
|
57
|
+
def initialize(origin, destination, packages, options)
|
58
|
+
@origin = Location.from(origin)
|
59
|
+
@destination = Location.from(destination)
|
60
|
+
@packages = Array(packages).map { |package| NewZealandPostPackage.new(package, api) }
|
61
|
+
@params = { :format => "json", :api_key => options[:key] }
|
62
|
+
@test = options[:test]
|
63
|
+
@rates = @responses = @raw_responses = []
|
64
|
+
@urls = @packages.map { |package| url(package) }
|
65
|
+
end
|
66
|
+
|
67
|
+
def rate_response
|
68
|
+
@rates = rates
|
69
|
+
NewZealandPostRateResponse.new(true, "success", response_params, response_options)
|
70
|
+
rescue => error
|
71
|
+
NewZealandPostRateResponse.new(false, error.message, response_params, response_options)
|
72
|
+
end
|
73
|
+
|
74
|
+
def new_zealand_origin?
|
75
|
+
self.class.new_zealand?(@origin)
|
76
|
+
end
|
77
|
+
|
78
|
+
protected
|
79
|
+
|
80
|
+
def self.new_zealand?(location)
|
81
|
+
[ 'NZ', nil ].include?(Location.from(location).country_code)
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.domestic?(locations)
|
85
|
+
locations.select { |location| new_zealand?(location) }.size == 2
|
86
|
+
end
|
87
|
+
|
88
|
+
def response_options
|
89
|
+
{
|
90
|
+
:rates => @rates,
|
91
|
+
:raw_responses => @raw_responses,
|
92
|
+
:request => @urls,
|
93
|
+
:test => @test
|
94
|
+
}
|
95
|
+
end
|
96
|
+
|
97
|
+
def response_params
|
98
|
+
{ :responses => @responses }
|
99
|
+
end
|
100
|
+
|
101
|
+
def rate_options(products)
|
102
|
+
{
|
103
|
+
:total_price => products.sum { |product| price(product) },
|
104
|
+
:currency => "NZD",
|
105
|
+
:service_code => products.first["code"]
|
106
|
+
}
|
107
|
+
end
|
108
|
+
|
109
|
+
def rates
|
110
|
+
rates_hash.map do |service, products|
|
111
|
+
RateEstimate.new(@origin, @destination, NewZealandPost.name, service, rate_options(products))
|
86
112
|
end
|
87
|
-
|
88
|
-
RateResponse.new(true, "Success", Hash.from_xml(response), :rates => rate_estimates, :xml => response)
|
89
|
-
else
|
90
|
-
error_message = response_message(xml)
|
91
|
-
RateResponse.new(false, error_message, Hash.from_xml(response), :rates => rate_estimates, :xml => response)
|
92
113
|
end
|
93
|
-
end
|
94
114
|
|
95
|
-
|
96
|
-
|
97
|
-
rate_responses.each do |r|
|
98
|
-
return r if !r.success?
|
115
|
+
def rates_hash
|
116
|
+
products_hash.select { |service, products| products.size == @packages.size }
|
99
117
|
end
|
100
118
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
119
|
+
def products_hash
|
120
|
+
product_arrays.flatten.group_by { |product| service_name(product) }
|
121
|
+
end
|
122
|
+
|
123
|
+
def product_arrays
|
124
|
+
responses.map do |response|
|
125
|
+
raise(response["message"]) unless response["status"] == "success"
|
126
|
+
response["products"]
|
106
127
|
end
|
107
128
|
end
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
129
|
+
|
130
|
+
def responses
|
131
|
+
@responses = @raw_responses.map { |response| parse_response(response) }
|
132
|
+
end
|
133
|
+
|
134
|
+
def parse_response(response)
|
135
|
+
JSON.parse(response)
|
136
|
+
end
|
137
|
+
|
138
|
+
def url(package)
|
139
|
+
"#{URL}/#{api}?#{params(package).to_query}"
|
140
|
+
end
|
141
|
+
|
142
|
+
def params(package)
|
143
|
+
@params.merge(api_params).merge(package.params)
|
144
|
+
end
|
145
|
+
|
123
146
|
end
|
124
147
|
|
125
|
-
|
126
|
-
|
148
|
+
class Domestic < RateRequest
|
149
|
+
def service_name(product)
|
150
|
+
[ product["service_group_description"], product["description"] ].join(" ")
|
151
|
+
end
|
152
|
+
|
153
|
+
def api
|
154
|
+
:domestic
|
155
|
+
end
|
156
|
+
|
157
|
+
def api_params
|
158
|
+
{
|
159
|
+
:postcode_src => @origin.postal_code,
|
160
|
+
:postcode_dest => @destination.postal_code,
|
161
|
+
:carrier => "all"
|
162
|
+
}
|
163
|
+
end
|
164
|
+
|
165
|
+
def price(product)
|
166
|
+
product["cost"].to_f
|
167
|
+
end
|
127
168
|
end
|
128
169
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
170
|
+
class International < RateRequest
|
171
|
+
|
172
|
+
def rates
|
173
|
+
raise "New Zealand Post packages must originate in New Zealand" unless new_zealand_origin?
|
174
|
+
super
|
175
|
+
end
|
176
|
+
|
177
|
+
def service_name(product)
|
178
|
+
[ product["group"], product["name"] ].join(" ")
|
179
|
+
end
|
180
|
+
|
181
|
+
def api
|
182
|
+
:international
|
183
|
+
end
|
184
|
+
|
185
|
+
def api_params
|
186
|
+
{ :country_code => @destination.country_code }
|
187
|
+
end
|
188
|
+
|
189
|
+
def price(product)
|
190
|
+
product["price"].to_f
|
134
191
|
end
|
135
192
|
end
|
136
193
|
|
194
|
+
class NewZealandPostPackage
|
195
|
+
|
196
|
+
def initialize(package, api)
|
197
|
+
@package = package
|
198
|
+
@api = api
|
199
|
+
@params = { :weight => weight, :length => length }
|
200
|
+
end
|
201
|
+
|
202
|
+
def params
|
203
|
+
@params.merge(api_params).merge(shape_params)
|
204
|
+
end
|
205
|
+
|
206
|
+
protected
|
207
|
+
|
208
|
+
def weight
|
209
|
+
@package.kg
|
210
|
+
end
|
211
|
+
|
212
|
+
def length
|
213
|
+
mm(:length)
|
214
|
+
end
|
215
|
+
|
216
|
+
def height
|
217
|
+
mm(:height)
|
218
|
+
end
|
219
|
+
|
220
|
+
def width
|
221
|
+
mm(:width)
|
222
|
+
end
|
223
|
+
|
224
|
+
def shape
|
225
|
+
return :cylinder if @package.cylinder?
|
226
|
+
:cuboid
|
227
|
+
end
|
228
|
+
|
229
|
+
def api_params
|
230
|
+
send("#{@api}_params")
|
231
|
+
end
|
232
|
+
|
233
|
+
def international_params
|
234
|
+
{ :value => value }
|
235
|
+
end
|
236
|
+
|
237
|
+
def domestic_params
|
238
|
+
{}
|
239
|
+
end
|
240
|
+
|
241
|
+
def shape_params
|
242
|
+
send("#{shape}_params")
|
243
|
+
end
|
244
|
+
|
245
|
+
def cuboid_params
|
246
|
+
{ :height => height, :thickness => width }
|
247
|
+
end
|
248
|
+
|
249
|
+
def cylinder_params
|
250
|
+
{ :diameter => width }
|
251
|
+
end
|
252
|
+
|
253
|
+
def mm(measurement)
|
254
|
+
@package.cm(measurement) * 10
|
255
|
+
end
|
256
|
+
|
257
|
+
def value
|
258
|
+
return 0 unless @package.value && currency == "NZD"
|
259
|
+
@package.value / 100
|
260
|
+
end
|
261
|
+
|
262
|
+
def currency
|
263
|
+
@package.currency || "NZD"
|
264
|
+
end
|
265
|
+
|
266
|
+
end
|
137
267
|
end
|
138
268
|
end
|
139
269
|
end
|