google4r 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.
- data/CHANGES +5 -0
- data/LICENSE +22 -0
- data/README +75 -0
- data/lib/google4r/checkout.rb +36 -0
- data/lib/google4r/checkout/commands.rb +267 -0
- data/lib/google4r/checkout/frontend.rb +100 -0
- data/lib/google4r/checkout/notifications.rb +533 -0
- data/lib/google4r/checkout/shared.rb +501 -0
- data/lib/google4r/checkout/xml_generation.rb +271 -0
- data/lib/google4r/maps.rb +174 -0
- data/test/checkout/integration/checkout_command_test.rb +103 -0
- data/test/checkout/unit/address_test.rb +131 -0
- data/test/checkout/unit/area_test.rb +41 -0
- data/test/checkout/unit/checkout_command_test.rb +112 -0
- data/test/checkout/unit/checkout_command_xml_generator_test.rb +187 -0
- data/test/checkout/unit/command_test.rb +126 -0
- data/test/checkout/unit/flat_rate_shipping_test.rb +114 -0
- data/test/checkout/unit/frontend_test.rb +63 -0
- data/test/checkout/unit/item_test.rb +159 -0
- data/test/checkout/unit/marketing_preferences_test.rb +65 -0
- data/test/checkout/unit/merchant_code_test.rb +122 -0
- data/test/checkout/unit/new_order_notification_test.rb +115 -0
- data/test/checkout/unit/notification_acknowledgement_test.rb +43 -0
- data/test/checkout/unit/notification_handler_test.rb +93 -0
- data/test/checkout/unit/order_adjustment_test.rb +95 -0
- data/test/checkout/unit/order_state_change_notification_test.rb +159 -0
- data/test/checkout/unit/pickup_shipping_test.rb +70 -0
- data/test/checkout/unit/private_data_parser_test.rb +68 -0
- data/test/checkout/unit/shipping_adjustment_test.rb +100 -0
- data/test/checkout/unit/shipping_method_test.rb +41 -0
- data/test/checkout/unit/shopping_cart_test.rb +146 -0
- data/test/checkout/unit/tax_rule_test.rb +65 -0
- data/test/checkout/unit/tax_table_test.rb +82 -0
- data/test/checkout/unit/us_country_area_test.rb +76 -0
- data/test/checkout/unit/us_state_area_test.rb +70 -0
- data/test/checkout/unit/us_zip_area_test.rb +66 -0
- data/test/maps/geocoder_test.rb +143 -0
- data/var/cacert.pem +7815 -0
- metadata +100 -0
@@ -0,0 +1,501 @@
|
|
1
|
+
#--
|
2
|
+
# Project: google4r
|
3
|
+
# File: lib/google4r/checkout/shared.rb
|
4
|
+
# Author: Manuel Holtgrewe <purestorm at ggnore dot net>
|
5
|
+
# Copyright: (c) 2007 by Manuel Holtgrewe
|
6
|
+
# License: MIT License as follows:
|
7
|
+
#
|
8
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
9
|
+
# a copy of this software and associated documentation files (the
|
10
|
+
# "Software"), to deal in the Software without restriction, including
|
11
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
12
|
+
# distribute, sublicense, and/or sell copies of the Software, and to permit
|
13
|
+
# persons to whom the Software is furnished to do so, subject to the
|
14
|
+
# following conditions:
|
15
|
+
#
|
16
|
+
# The above copyright notice and this permission notice shall be included
|
17
|
+
# in all copies or substantial portions of the Software.
|
18
|
+
#
|
19
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
20
|
+
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
21
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
22
|
+
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
23
|
+
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
24
|
+
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
25
|
+
# OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
26
|
+
#++
|
27
|
+
# This file contains the classes and modules that are shared by the notification
|
28
|
+
# handling and parsing as well as the command generating code.
|
29
|
+
|
30
|
+
#--
|
31
|
+
# TODO
|
32
|
+
#
|
33
|
+
# * Make the optional attributes return defaults that make sense, i.e. Money.new(0)
|
34
|
+
# * Make the "main" API really pretty Ruby code and provide aliases so people can
|
35
|
+
# also just use the Google Docs.
|
36
|
+
#++
|
37
|
+
module Google4R #:nodoc:
|
38
|
+
module Checkout #:nodoc:
|
39
|
+
# This exception is thrown by Command#send_to_google_checkout when an error occured.
|
40
|
+
class GoogleCheckoutError < Exception
|
41
|
+
# The serial number of the error returned by Google.
|
42
|
+
attr_reader :serial_number
|
43
|
+
|
44
|
+
# The HTTP response code of Google's response.
|
45
|
+
attr_reader :response_code
|
46
|
+
|
47
|
+
# The parameter is a hash with the entries :serial_number, :message and :response_code.
|
48
|
+
# The attributes serial_number, message and response_code are set to the values in the
|
49
|
+
# Hash.
|
50
|
+
def initialize(hash)
|
51
|
+
@response_code = hash[:response_code]
|
52
|
+
@message = hash[:message]
|
53
|
+
@serial_number = hash[:serial_number]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# ShoppingCart instances are containers for Item instances. You can add
|
58
|
+
# Items to the class using #create_item (see the documentation of this
|
59
|
+
# method for an example).
|
60
|
+
class ShoppingCart
|
61
|
+
# The onwer of this cart. At the moment, this always is the CheckoutCartCommand.
|
62
|
+
attr_reader :owner
|
63
|
+
|
64
|
+
# The items in the cart. Do not modify this array directly but use
|
65
|
+
# #create_item to add items.
|
66
|
+
attr_reader :items
|
67
|
+
|
68
|
+
# You can set the <cart-expiration> time with this property. If left
|
69
|
+
# unset then the tag will not be generated and the cart will never
|
70
|
+
# expire.
|
71
|
+
attr_accessor :expires_at
|
72
|
+
|
73
|
+
# You can set almost arbitrary data into the cart using this method.
|
74
|
+
#
|
75
|
+
# The data will be converted to XML in the following way: The keys are converted
|
76
|
+
# to tag names (whitespace becomes "-", all chars not matching /[a-zA-Z0-9\-_])/
|
77
|
+
# will be removed.
|
78
|
+
#
|
79
|
+
# If a value is an array then the key for this value will be used as the tag
|
80
|
+
# name for each of the arrays's entries.
|
81
|
+
#
|
82
|
+
# Arrays will be flattened before it is processed.
|
83
|
+
#
|
84
|
+
# === Example
|
85
|
+
#
|
86
|
+
# cart.private_data = { 'foo' => { 'bar' => 'baz' } })
|
87
|
+
#
|
88
|
+
# # will produce the following XML
|
89
|
+
#
|
90
|
+
# <foo>
|
91
|
+
# <bar>baz</bar>
|
92
|
+
# </foo>
|
93
|
+
#
|
94
|
+
#
|
95
|
+
# cart.private_data = { 'foo' => [ { 'bar' => 'baz' }, "d'oh", 2 ] }
|
96
|
+
#
|
97
|
+
# # will produce the following XML
|
98
|
+
#
|
99
|
+
# <foo>
|
100
|
+
# <bar>baz</bar>
|
101
|
+
# </foo>
|
102
|
+
# <foo>d&</foo>
|
103
|
+
# <foo>2</foo>
|
104
|
+
attr_reader :private_data
|
105
|
+
|
106
|
+
# Sets the value of the private_data attribute.
|
107
|
+
def private_data=(value)
|
108
|
+
raise "The given value #{value.inspect} is not a Hash!" unless value.kind_of?(Hash)
|
109
|
+
@private_data = value
|
110
|
+
end
|
111
|
+
|
112
|
+
# Initialize a new ShoppingCart with an empty Array for the items.
|
113
|
+
def initialize(owner)
|
114
|
+
@owner = owner
|
115
|
+
@items = Array.new
|
116
|
+
end
|
117
|
+
|
118
|
+
# Use this method to add a new item to the cart. If you use a block with
|
119
|
+
# this method then the block will be given the new item. The new item
|
120
|
+
# will be returned in any case.
|
121
|
+
#
|
122
|
+
# Passing a block is the preferred way of using this method.
|
123
|
+
#
|
124
|
+
# === Example
|
125
|
+
#
|
126
|
+
# # Using a block (preferred).
|
127
|
+
# cart = ShoppingCart.new
|
128
|
+
#
|
129
|
+
# cart.create_item do |item|
|
130
|
+
# item.name = "Dry Food Pack"
|
131
|
+
# item.description = "A pack of highly nutritious..."
|
132
|
+
# item.unit_price = Money.new(3500, "USD") # $35.00
|
133
|
+
# item.quantity = 1
|
134
|
+
# end
|
135
|
+
#
|
136
|
+
# # Not using a block.
|
137
|
+
# cart = ShoppingCart.new
|
138
|
+
#
|
139
|
+
# item = cart.create_item
|
140
|
+
# item.name = "Dry Food Pack"
|
141
|
+
# item.description = "A pack of highly nutritious..."
|
142
|
+
# item.unit_price = Money.new(3500, "USD") # $35.00
|
143
|
+
# item.quantity = 1
|
144
|
+
def create_item(&block)
|
145
|
+
item = Item.new(self)
|
146
|
+
@items << item
|
147
|
+
|
148
|
+
# Pass the newly generated item to the given block to set its attributes.
|
149
|
+
yield(item) if block_given?
|
150
|
+
|
151
|
+
return item
|
152
|
+
end
|
153
|
+
|
154
|
+
# Creates a new ShoppingCart object from a REXML::Element object.
|
155
|
+
def self.create_from_element(element, owner)
|
156
|
+
result = ShoppingCart.new(owner)
|
157
|
+
|
158
|
+
text = element.elements['cart-expiration/good-until-date'].text rescue nil
|
159
|
+
result.expires_at = Time.parse(text) unless text.nil?
|
160
|
+
|
161
|
+
data_element = element.elements['merchant-private-data']
|
162
|
+
value = PrivateDataParser.element_to_value(data_element) unless data_element.nil?
|
163
|
+
|
164
|
+
result.private_data = value unless value.nil?
|
165
|
+
|
166
|
+
element.elements.each('items/item') do |item_element|
|
167
|
+
result.items << Item.create_from_element(item_element, result)
|
168
|
+
end
|
169
|
+
|
170
|
+
return result
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
# An Item object represents a line of goods in the shopping cart/reciep.
|
175
|
+
#
|
176
|
+
# You should never initialize them directly but use ShoppingCart#create_item instead.
|
177
|
+
#
|
178
|
+
# Note that you have to create/set the tax tables for the owner of the cart in which
|
179
|
+
# the item is before you can set the tax_table attribute.
|
180
|
+
class Item
|
181
|
+
# The cart that this item belongs to.
|
182
|
+
attr_reader :cart
|
183
|
+
|
184
|
+
# The name of the cart item (string, required).
|
185
|
+
attr_accessor :name
|
186
|
+
|
187
|
+
# The description of the cart item (string, required).
|
188
|
+
attr_accessor :description
|
189
|
+
|
190
|
+
# The price for one unit of the given good (Money instance, required).
|
191
|
+
attr_reader :unit_price
|
192
|
+
|
193
|
+
# Sets the price for one unit of goods described by this item. money must respond to
|
194
|
+
# :cents and :currency as the Money class does.
|
195
|
+
def unit_price=(money)
|
196
|
+
if not (money.respond_to?(:cents) and money.respond_to?(:currency)) then
|
197
|
+
raise "Invalid price - does not respond to :cents and :currency - #{money.inspect}."
|
198
|
+
end
|
199
|
+
|
200
|
+
@unit_price = money
|
201
|
+
end
|
202
|
+
|
203
|
+
# Number of units that this item represents (integer, required).
|
204
|
+
attr_accessor :quantity
|
205
|
+
|
206
|
+
# Optional string value that is used to store the item's id (defined by the merchant)
|
207
|
+
# in the cart. Serialized to <merchant-item-id> in XML. Displayed by Google Checkout.
|
208
|
+
attr_accessor :id
|
209
|
+
|
210
|
+
# Optional hash value that is used to store the item's id (defined by the merchant)
|
211
|
+
# in the cart. Serialized to <merchant-private-item-data> in XML. Not displayed by
|
212
|
+
# Google Checkout.
|
213
|
+
#
|
214
|
+
# Must be a Hash. See ShoppingCart#private_data on how the serialization to XML is
|
215
|
+
# done.
|
216
|
+
attr_reader :private_data
|
217
|
+
|
218
|
+
# Sets the private data for this item.
|
219
|
+
def private_data=(value)
|
220
|
+
raise "The given value #{value.inspect} is not a Hash!" unless value.kind_of?(Hash)
|
221
|
+
@private_data = value
|
222
|
+
end
|
223
|
+
|
224
|
+
# The tax table to use for this item. Optional.
|
225
|
+
attr_reader :tax_table
|
226
|
+
|
227
|
+
# Sets the tax table to use for this item. When you set this attribute using this
|
228
|
+
# method then the used table must already be added to the cart. Otherwise, a
|
229
|
+
# RuntimeError will be raised.
|
230
|
+
def tax_table=(table)
|
231
|
+
raise "The table #{table.inspect} is not in the item's cart yet!" unless cart.owner.tax_tables.include?(table)
|
232
|
+
|
233
|
+
@tax_table = table
|
234
|
+
end
|
235
|
+
|
236
|
+
# Create a new Item in the given Cart. You should not instantize this class directly
|
237
|
+
# but use Cart#create_item instead.
|
238
|
+
def initialize(cart)
|
239
|
+
@cart = cart
|
240
|
+
end
|
241
|
+
|
242
|
+
# Creates a new Item object from a REXML::Element object.
|
243
|
+
def self.create_from_element(element, cart)
|
244
|
+
result = Item.new(cart)
|
245
|
+
|
246
|
+
result.name = element.elements['item-name'].text
|
247
|
+
result.description = element.elements['item-description'].text
|
248
|
+
result.quantity = element.elements['quantity'].text.to_i
|
249
|
+
result.id = element.elements['merchant-item-id'].text rescue nil
|
250
|
+
|
251
|
+
data_element = element.elements['merchant-private-item-data']
|
252
|
+
if not data_element.nil? then
|
253
|
+
value = PrivateDataParser.element_to_value(data_element)
|
254
|
+
result.private_data = value unless value.nil?
|
255
|
+
end
|
256
|
+
|
257
|
+
table_selector = element.elements['tax-table-selector'].text rescue nil
|
258
|
+
if not table_selector.nil? then
|
259
|
+
result.tax_table = cart.owner.tax_tables.find {|table| table.name == table_selector }
|
260
|
+
end
|
261
|
+
|
262
|
+
unit_price = (element.elements['unit-price'].text.to_f * 100).to_i
|
263
|
+
unit_price_currency = element.elements['unit-price/@currency'].value
|
264
|
+
result.unit_price = Money.new(unit_price, unit_price_currency)
|
265
|
+
|
266
|
+
return result
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
# A TaxTable is an ordered array of TaxRule objects. You should create the TaxRule
|
271
|
+
# instances using #create_rule
|
272
|
+
#
|
273
|
+
# You must set up a tax table factory and should only create tax tables from within
|
274
|
+
# its temporal factory method as described in the class documentation of Frontend.
|
275
|
+
#
|
276
|
+
# Each tax table must have one or more tax rules.
|
277
|
+
#
|
278
|
+
# === Example
|
279
|
+
#
|
280
|
+
# include Google4R::Checkout
|
281
|
+
#
|
282
|
+
# tax_free_table = TaxTable.new(false)
|
283
|
+
# tax_free_table.name = "default table"
|
284
|
+
# tax_free_table.create_rule do |rule|
|
285
|
+
# rule.area = UsCountryArea.new(UsCountryArea::ALL)
|
286
|
+
# rule.rate = 0.0
|
287
|
+
# end
|
288
|
+
class TaxTable
|
289
|
+
# The name of this tax table (string, required).
|
290
|
+
attr_accessor :name
|
291
|
+
|
292
|
+
# An Array of the TaxRule objects that this TaxTable contains. Use #create_rule do
|
293
|
+
# add to this Array but do not change it directly.
|
294
|
+
attr_reader :rules
|
295
|
+
|
296
|
+
# Boolean, true iff the table's standalone attribute is to be set to "true".
|
297
|
+
attr_reader :standalone
|
298
|
+
|
299
|
+
def initialize(standalone)
|
300
|
+
@rules = Array.new
|
301
|
+
|
302
|
+
@standalone = standalone
|
303
|
+
end
|
304
|
+
|
305
|
+
# Use this method to add a new TaxRule to the table. If you use a block with
|
306
|
+
# this method then the block will called with the newly created rule for the
|
307
|
+
# parameter. The method will return the new rule in any case.
|
308
|
+
def create_rule(&block)
|
309
|
+
rule = TaxRule.new(self)
|
310
|
+
@rules << rule
|
311
|
+
|
312
|
+
# Pass the newly generated rule to the given block to set its attributes.
|
313
|
+
yield(rule) if block_given?
|
314
|
+
|
315
|
+
return rule
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
# A TaxRule specifies which taxes to apply in which area. Have a look at the "Google
|
320
|
+
# Checkout documentation" [http://code.google.com/apis/checkout/developer/index.html#specifying_tax_info]
|
321
|
+
# for more information.
|
322
|
+
class TaxRule
|
323
|
+
# The table this rule belongs to.
|
324
|
+
attr_reader :table
|
325
|
+
|
326
|
+
# The tax rate for this rule (double, required).
|
327
|
+
attr_accessor :rate
|
328
|
+
|
329
|
+
# The area where this tax rule applies (Area subclass instance, required). Serialized
|
330
|
+
# to <tax-area> in XML.
|
331
|
+
attr_accessor :area
|
332
|
+
|
333
|
+
# Creates a new TaxRule in the given TaxTable. Do no call this method yourself
|
334
|
+
# but use TaxTable#create_rule instead!
|
335
|
+
def initialize(table)
|
336
|
+
@table = table
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
# Abstract class for areas that are used to specify a tax area. Do not use this class
|
341
|
+
# but only its subclasses.
|
342
|
+
class Area
|
343
|
+
# Mark this class as abstract by throwing a RuntimeError on initialization.
|
344
|
+
def initialize #:nodoc:
|
345
|
+
raise "Do not use the abstract class Google::Checkout::Area!"
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
# Instances of UsZipArea represent areas specified by US ZIPs and ZIP patterns.
|
350
|
+
class UsZipArea < Area
|
351
|
+
# The pattern for this ZIP area.
|
352
|
+
attr_accessor :pattern
|
353
|
+
|
354
|
+
# You can optionally initialize the Area with its value.
|
355
|
+
def initialize(pattern=nil)
|
356
|
+
self.pattern = pattern unless pattern.nil?
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
# Instances of UsStateArea represent states in the US.
|
361
|
+
class UsStateArea < Area
|
362
|
+
# The two-letter code of the US state.
|
363
|
+
attr_reader :state
|
364
|
+
|
365
|
+
# You can optionally initialize the Area with its value.
|
366
|
+
def initialize(state=nil)
|
367
|
+
self.state = state unless state.nil?
|
368
|
+
end
|
369
|
+
|
370
|
+
# Writer for the state attribute. value must match /^[A-Z]{2,2}$/.
|
371
|
+
def state=(value)
|
372
|
+
raise "Invalid US state: #{value}" unless value =~ /^[A-Z]{2,2}$/
|
373
|
+
@state = value
|
374
|
+
end
|
375
|
+
end
|
376
|
+
|
377
|
+
# Instances of UsCountryArea identify a region within the US.
|
378
|
+
class UsCountryArea < Area
|
379
|
+
CONTINENTAL_48 = "CONTINENTAL_48".freeze
|
380
|
+
FULL_50_STATES = "FULL_50_STATES".freeze
|
381
|
+
ALL = "ALL".freeze
|
382
|
+
|
383
|
+
# The area that is specified with this UsCountryArea (required). Can be
|
384
|
+
# one of UsCountryArea::CONTINENTAL_48, UsCountryArea::FULL_50_STATES
|
385
|
+
# and UsCountryArea::ALL.
|
386
|
+
# See the Google Checkout API for information on these values.
|
387
|
+
attr_reader :area
|
388
|
+
|
389
|
+
# You can optionally initialize the Area with its value.
|
390
|
+
def initialize(area=nil)
|
391
|
+
self.area = area unless area.nil?
|
392
|
+
end
|
393
|
+
|
394
|
+
# Writer for the area attribute. value must be one of CONTINENTAL_48,
|
395
|
+
# FULL_50_STATES and ALL
|
396
|
+
def area=(value)
|
397
|
+
raise "Invalid area :#{value}!" unless [ CONTINENTAL_48, FULL_50_STATES, ALL ].include?(value)
|
398
|
+
@area = value
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
# Abstract class for shipping methods. Do not use this class directly but only
|
403
|
+
# one of its subclasses.
|
404
|
+
class ShippingMethod
|
405
|
+
# The name of the shipping method (string, required).
|
406
|
+
attr_accessor :name
|
407
|
+
|
408
|
+
# The price of the shipping method (Money instance, required).
|
409
|
+
attr_reader :price
|
410
|
+
|
411
|
+
# Sets the cost for this shipping method. money must respond to :cents and :currency
|
412
|
+
# as Money objects would.
|
413
|
+
def price=(money)
|
414
|
+
if not (money.respond_to?(:cents) and money.respond_to?(:currency)) then
|
415
|
+
raise "Invalid cost - does not respond to :cents and :currency - #{money.inspect}."
|
416
|
+
end
|
417
|
+
|
418
|
+
@price = money
|
419
|
+
end
|
420
|
+
|
421
|
+
# Mark this class as abstract by throwing a RuntimeError on initialization.
|
422
|
+
def initialize
|
423
|
+
raise "Do not use the abstract class Google::Checkout::ShippingMethod!"
|
424
|
+
end
|
425
|
+
end
|
426
|
+
|
427
|
+
# A class that represents the "pickup" shipping method.
|
428
|
+
class PickupShipping < ShippingMethod
|
429
|
+
def initialize
|
430
|
+
end
|
431
|
+
end
|
432
|
+
|
433
|
+
# A class that represents the "flat_rate" shipping method.
|
434
|
+
class FlatRateShipping < ShippingMethod
|
435
|
+
# An Array of allowed areas for this flat_rate shipping instance. Use
|
436
|
+
# #create_allowed_area to add to this area but do not change it directly.
|
437
|
+
attr_reader :allowed_areas
|
438
|
+
|
439
|
+
# An Array of excluded areas for this flat_rate shipping instance. Use
|
440
|
+
# #create_excluded_area to add to this area but do not change it directly.
|
441
|
+
attr_reader :excluded_areas
|
442
|
+
|
443
|
+
def initialize
|
444
|
+
@allowed_areas = Array.new
|
445
|
+
@excluded_areas = Array.new
|
446
|
+
end
|
447
|
+
|
448
|
+
# Creates a new Area, adds it to the internal list of allowed areas for this
|
449
|
+
# shipping types. If you passed a block (preferred) then the block is called
|
450
|
+
# with the Area as the only parameter.c
|
451
|
+
#
|
452
|
+
# The area to be created depends on the given parameter clazz. It can be one
|
453
|
+
# of { UsCountryArea, UsStateArea, UsZipArea }.
|
454
|
+
#
|
455
|
+
# Raises a RuntimeError if the parameter clazz is invalid.
|
456
|
+
#
|
457
|
+
# === Example
|
458
|
+
#
|
459
|
+
# method = FlatRateShipping.new
|
460
|
+
# method.create_allowed_area(UsCountryArea) do |area|
|
461
|
+
# area.area = UsCountryArea::ALL
|
462
|
+
# end
|
463
|
+
def create_allowed_area(clazz, &block)
|
464
|
+
raise "Invalid Area class: #{clazz}!" unless [ UsCountryArea, UsStateArea, UsZipArea ].include?(clazz)
|
465
|
+
|
466
|
+
area = clazz.new
|
467
|
+
@allowed_areas << area
|
468
|
+
|
469
|
+
yield(area) if block_given?
|
470
|
+
|
471
|
+
return area
|
472
|
+
end
|
473
|
+
|
474
|
+
# Creates a new Area, adds it to the internal list of excluded areas for this
|
475
|
+
# shipping types. If you passed a block (preferred) then the block is called
|
476
|
+
# with the Area as the only parameter. The created area is returned in any case.
|
477
|
+
#
|
478
|
+
# The area to be created depends on the given parameter clazz. It can be one
|
479
|
+
# of { UsCountryArea, UsStateArea, UsZipArea }.
|
480
|
+
#
|
481
|
+
# Raises a RuntimeError if the parameter clazz is invalid.
|
482
|
+
#
|
483
|
+
# === Example
|
484
|
+
#
|
485
|
+
# method = FlatRateShipping.new
|
486
|
+
# method.create_excluded_area(UsCountryArea) do |area|
|
487
|
+
# area.area = UsCountryArea::ALL
|
488
|
+
# end
|
489
|
+
def create_excluded_area(clazz, &block)
|
490
|
+
raise "Invalid Area class: #{clazz}!" unless [ UsCountryArea, UsStateArea, UsZipArea ].include?(clazz)
|
491
|
+
|
492
|
+
area = clazz.new
|
493
|
+
@excluded_areas << area
|
494
|
+
|
495
|
+
yield(area) if block_given?
|
496
|
+
|
497
|
+
return area
|
498
|
+
end
|
499
|
+
end
|
500
|
+
end
|
501
|
+
end
|