nbudin-google4r-checkout 1.0.6

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.
Files changed (79) hide show
  1. data/.gitignore +3 -0
  2. data/CHANGES +83 -0
  3. data/LICENSE +22 -0
  4. data/README +58 -0
  5. data/Rakefile +80 -0
  6. data/VERSION +1 -0
  7. data/lib/google4r/checkout/commands.rb +515 -0
  8. data/lib/google4r/checkout/frontend.rb +204 -0
  9. data/lib/google4r/checkout/merchant_calculation.rb +321 -0
  10. data/lib/google4r/checkout/notifications.rb +708 -0
  11. data/lib/google4r/checkout/shared.rb +1249 -0
  12. data/lib/google4r/checkout/utils.rb +94 -0
  13. data/lib/google4r/checkout/xml_generation.rb +920 -0
  14. data/lib/google4r/checkout.rb +34 -0
  15. data/test/frontend_configuration.rb +13 -0
  16. data/test/integration/checkout_command_test.rb +246 -0
  17. data/test/test_helper.rb +115 -0
  18. data/test/unit/add_merchant_order_number_command_test.rb +70 -0
  19. data/test/unit/add_tracking_data_command_test.rb +75 -0
  20. data/test/unit/address_test.rb +131 -0
  21. data/test/unit/anonymous_address_test.rb +75 -0
  22. data/test/unit/archive_order_command_test.rb +66 -0
  23. data/test/unit/area_test.rb +44 -0
  24. data/test/unit/authorization_amount_notification_test.rb +69 -0
  25. data/test/unit/authorize_order_command_test.rb +66 -0
  26. data/test/unit/backorder_items_command_test.rb +83 -0
  27. data/test/unit/callback_handler_test.rb +83 -0
  28. data/test/unit/cancel_items_command_test.rb +89 -0
  29. data/test/unit/cancel_order_command_test.rb +83 -0
  30. data/test/unit/carrier_calculated_shipping_test.rb +57 -0
  31. data/test/unit/charge_amount_notification_test.rb +64 -0
  32. data/test/unit/charge_order_command_test.rb +77 -0
  33. data/test/unit/chargeback_amount_notification_test.rb +65 -0
  34. data/test/unit/checkout_command_test.rb +125 -0
  35. data/test/unit/checkout_command_xml_generator_test.rb +218 -0
  36. data/test/unit/command_test.rb +116 -0
  37. data/test/unit/deliver_order_command_test.rb +70 -0
  38. data/test/unit/delivery_method_test.rb +42 -0
  39. data/test/unit/digital_content_test.rb +105 -0
  40. data/test/unit/flat_rate_shipping_test.rb +132 -0
  41. data/test/unit/frontend_test.rb +136 -0
  42. data/test/unit/item_info_test.rb +69 -0
  43. data/test/unit/item_test.rb +171 -0
  44. data/test/unit/marketing_preferences_test.rb +65 -0
  45. data/test/unit/merchant_calculated_shipping_test.rb +172 -0
  46. data/test/unit/merchant_calculation_callback_test.rb +137 -0
  47. data/test/unit/merchant_calculation_result_test.rb +78 -0
  48. data/test/unit/merchant_calculation_results_test.rb +178 -0
  49. data/test/unit/merchant_code_result_test.rb +51 -0
  50. data/test/unit/merchant_code_test.rb +122 -0
  51. data/test/unit/new_order_notification_test.rb +115 -0
  52. data/test/unit/notification_acknowledgement_test.rb +67 -0
  53. data/test/unit/notification_handler_test.rb +113 -0
  54. data/test/unit/order_adjustment_test.rb +119 -0
  55. data/test/unit/order_state_change_notification_test.rb +158 -0
  56. data/test/unit/pickup_shipping_test.rb +70 -0
  57. data/test/unit/postal_area_test.rb +71 -0
  58. data/test/unit/private_data_parser_test.rb +68 -0
  59. data/test/unit/refund_amount_notification_test.rb +65 -0
  60. data/test/unit/refund_order_command_test.rb +86 -0
  61. data/test/unit/reset_items_shipping_information_command_test.rb +83 -0
  62. data/test/unit/return_items_command_test.rb +83 -0
  63. data/test/unit/risk_information_notification_test.rb +98 -0
  64. data/test/unit/send_buyer_message_command_test.rb +73 -0
  65. data/test/unit/ship_items_command_test.rb +101 -0
  66. data/test/unit/shipping_adjustment_test.rb +100 -0
  67. data/test/unit/shopping_cart_test.rb +146 -0
  68. data/test/unit/tax_rule_test.rb +70 -0
  69. data/test/unit/tax_table_test.rb +82 -0
  70. data/test/unit/tracking_data_test.rb +54 -0
  71. data/test/unit/unarchive_order_command_test.rb +66 -0
  72. data/test/unit/us_country_area_test.rb +76 -0
  73. data/test/unit/us_state_area_test.rb +70 -0
  74. data/test/unit/us_zip_area_test.rb +66 -0
  75. data/test/unit/world_area_test.rb +48 -0
  76. data/test/xml/apiv2.xsd +997 -0
  77. data/test/xml/test_check_persisting_works_expected.xml +213 -0
  78. data/var/cacert.pem +7815 -0
  79. metadata +200 -0
@@ -0,0 +1,204 @@
1
+ #--
2
+ # Project: google4r
3
+ # File: lib/google4r/checkout/frontend.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 provides the Google4R::Checkout::Frontend class that is a factory for the commands
28
+ # to be sent to Google Checkout.
29
+
30
+ module Google4R #:nodoc:
31
+ module Checkout #:nodoc:
32
+ # The Frontend class is the factory that is to be used to create the Command,
33
+ # NotificationHandler and CallbackHandler objects.
34
+ #
35
+ # === Example
36
+ #
37
+ # configuration = { :merchant_id => '123456789', :merchant_key => '12345abcd' }
38
+ #
39
+ # frontend = Google4R::Checkout::Frontend.new(configuration)
40
+ #
41
+ # == Tax Table Factory
42
+ #
43
+ # You have to set the tax_table_factory attribute of every Frontend object before you
44
+ # can call #create_checkout_command or #create_notification_handler because the
45
+ # objects created by those methods require tax tables.
46
+ #
47
+ # The Tax Table Factory must provide the method "effective_tax_tables_at" accept a Time
48
+ # object and provide a method that returns an Array of TaxTable object that describe the
49
+ # effective tax rules at the given point of time.
50
+ #
51
+ # Effectively, this means you have to implement the Temporal Property pattern as described
52
+ # here: http://www.martinfowler.com/ap2/temporalProperty.html.
53
+ #
54
+ # == Example
55
+ #
56
+ # class TaxTableFactory
57
+ # def effective_tax_tables_at(time)
58
+ # if time < Time.parse("Wed Apr 09 08:56:03 CDT 2003") then
59
+ # table1, table2 = TaxTable.new, TaxTable.new
60
+ # # ... set rules
61
+ # [ table1, table 2]
62
+ # else
63
+ # table3, table4 = TaxTable.new, TaxTable.new
64
+ # # ... set rules
65
+ # [ table3, table 4]
66
+ # end
67
+ # end
68
+ # end
69
+ #
70
+ # frontend = Google4R::Checkout::Frontend.new(configuration)
71
+ # frontend.tax_table_factory = TaxTableFactory.new
72
+ #
73
+ # checkout_command = frontend.create_checkout_command
74
+ # # ...
75
+ # handler = frontend.create_notification_handler
76
+ class Frontend
77
+ # The configuration for this Frontend class. It will be used by all classes created
78
+ # by this Frontend instance (Hash).
79
+ attr_reader :configuration
80
+
81
+ # An object with a factory method that can create the effective TaxTable objects
82
+ # that were valid at a given point of time.
83
+ attr_accessor :tax_table_factory
84
+
85
+ # Creates a new Frontend instance and sets the configuration attribute to the parameter
86
+ # configuration.
87
+ def initialize(configuration)
88
+ raise "Missing configuration setting: merchant_id" if configuration[:merchant_id].nil?
89
+ raise "Missing configuration setting: merchant_key" if configuration[:merchant_key].nil?
90
+ raise "Missing configuration setting: use_sandbox" if configuration[:use_sandbox].nil?
91
+
92
+ @configuration = configuration.dup.freeze
93
+ end
94
+
95
+ # Factory method that creates a new NotificationHandler object. Use this method to
96
+ # create your NotificationHandler instances.
97
+ def create_notification_handler
98
+ return NotificationHandler.new(self)
99
+ end
100
+
101
+ # Factory method that creates a new CallbackHandler object. Use this method to
102
+ # create your CallbackHandler instances.
103
+ def create_callback_handler
104
+ return CallbackHandler.new(self)
105
+ end
106
+
107
+ # Factory method to create a new DeliverOrderCommand object. Use this method to create
108
+ # your DeliverOrderCommand instances.
109
+ def create_deliver_order_command
110
+ return DeliverOrderCommand.new(self)
111
+ end
112
+
113
+ # Factory method to create a new ChargeOrderCommand object. Use this method to create
114
+ # your ChargeOrderCommand instances.
115
+ def create_charge_order_command
116
+ return ChargeOrderCommand.new(self)
117
+ end
118
+
119
+ # Factory method that creates a new CheckoutCommand object. Use this method to create
120
+ # your CheckoutCommand instances.
121
+ def create_checkout_command
122
+ return CheckoutCommand.new(self)
123
+ end
124
+
125
+ # Factory method to create a new CancelOrderCommand object. Use this method to create
126
+ # your CancelOrderCommand instances.
127
+ def create_cancel_order_command
128
+ return CancelOrderCommand.new(self)
129
+ end
130
+
131
+ # Factory method to create a new RefundOrderCommand object. Use this method to create
132
+ # your RefundOrderCommand instances.
133
+ def create_refund_order_command
134
+ return RefundOrderCommand.new(self)
135
+ end
136
+
137
+ # Factory method to create a new SendBuyerMessageCommand object. Use this method to create
138
+ # your SendBuyerMessageCommand instances.
139
+ def create_send_buyer_message_command
140
+ return SendBuyerMessageCommand.new(self)
141
+ end
142
+
143
+ # Factory method to create a new AuthorizeOrderCommand object. Use this method to create
144
+ # your AuthorizeOrderCommand instances.
145
+ def create_authorize_order_command
146
+ return AuthorizeOrderCommand.new(self)
147
+ end
148
+
149
+ # Factory method to create a new AddMerchantOrderNumberCommand object. Use this method to create
150
+ # your AddMerchantOrderNumberCommand instances.
151
+ def create_add_merchant_order_number_command
152
+ return AddMerchantOrderNumberCommand.new(self)
153
+ end
154
+
155
+ # Factory method to create a new AddTrackingDataCommand object. Use this method to create
156
+ # your AddTrackingDataCommand instances.
157
+ def create_add_tracking_data_command
158
+ return AddTrackingDataCommand.new(self)
159
+ end
160
+
161
+ # Factory method to create a new ArchiveOrderCommand object. Use this method to create
162
+ # your ArchiveOrderCommand instances.
163
+ def create_archive_order_command
164
+ return ArchiveOrderCommand.new(self)
165
+ end
166
+
167
+ # Factory method to create a new UnarchiveOrderCommand object. Use this method to create
168
+ # your UnarchiveOrderCommand instances.
169
+ def create_unarchive_order_command
170
+ return UnarchiveOrderCommand.new(self)
171
+ end
172
+
173
+ # Factory method to create a new ShipItemsCommand object. Use this method to create
174
+ # your ShipItemsCommand instances.
175
+ def create_ship_items_command
176
+ return ShipItemsCommand.new(self)
177
+ end
178
+
179
+ # Factory method to create a new BackorderItemsCommand object. Use this method to create
180
+ # your BackorderItemsCommand instances.
181
+ def create_backorder_items_command
182
+ return BackorderItemsCommand.new(self)
183
+ end
184
+
185
+ # Factory method to create a new ReturnItemsCommand object. Use this method to create
186
+ # your ReturnItemsCommand instances.
187
+ def create_return_items_command
188
+ return ReturnItemsCommand.new(self)
189
+ end
190
+
191
+ # Factory method to create a new CancelItemsCommand object. Use this method to create
192
+ # your CancelItemsCommand instances.
193
+ def create_cancel_items_command
194
+ return CancelItemsCommand.new(self)
195
+ end
196
+
197
+ # Factory method to create a new ResetItemsShippingInformationCommand object. Use this method to create
198
+ # your ResetItemsShippingInformationCommand instances.
199
+ def create_reset_items_shipping_information_command
200
+ return ResetItemsShippingInformationCommand.new(self)
201
+ end
202
+ end
203
+ end
204
+ end
@@ -0,0 +1,321 @@
1
+ #--
2
+ # Project: google4r
3
+ # File: lib/google4r/checkout/merchant_calculation.rb
4
+ # Author: Tony Chan <api dot htchan at gmail dot com>
5
+ # Copyright: (c) 2007 by Tony Chan
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 used in the callback
28
+ # handling code.
29
+
30
+ require 'rexml/document'
31
+
32
+ module Google4R #:nodoc:
33
+ module Checkout #:nodoc:
34
+ # Thrown by Callback on unimplemented and unknown callbacks from Google.
35
+ class UnknownCallbackType < Exception
36
+ end
37
+
38
+ # This class expects the message sent by Google. It parses the XMl document and returns
39
+ # the appropriate callback. If the callback sent by Google is invalid then a
40
+ # UnknownCallbackType is raised that you should catch and then send a 404 to Google
41
+ # to indicate that the callback handler has not been implemented yet.
42
+ #
43
+ # See http://code.google.com/apis/checkout/developer/index.html#merchant_calculations_api for
44
+ # details.
45
+ #
46
+ # Note that you must protect the HTTPS request to the piece of code using a
47
+ # CallbackHandler by HTTP Auth Basic. If you are using Ruby On Rails then you can
48
+ # use the great "simple_http_auth" plugin you can find here:
49
+ # http://blog.codahale.com/2006/05/11/basic-http-authentication-with-rails-simple_http_auth/
50
+ #
51
+ # === Usage Example
52
+ #
53
+ # When you use a Rails controller to handle the calbacks by Google then your action to handle
54
+ # the callbacks could use a CallbackHandler as follows:
55
+ #
56
+ # def google_checkout_api
57
+ # frontend = Google4R::Checkout::Frontend.new(FRONTEND_CONFIGURATION)
58
+ # frontend.tax_table_factory = TaxTableFactory.new
59
+ # handler = frontend.create_callback_handler
60
+ #
61
+ # begin
62
+ # callback = handler.handle(request.raw_post) # raw_post contains the XML
63
+ # rescue Google4R::Checkout::UnknownCallbackType => e
64
+ # # This can happen if Google adds new commands and Google4R has not been
65
+ # # upgraded yet. It is not fatal.
66
+ # render :text => 'ignoring unknown callback type', :status => 200
67
+ # return
68
+ # end
69
+ #
70
+ # # ...
71
+ # end
72
+ class CallbackHandler
73
+ # The Frontend object that created this CallbackHandler
74
+ attr_accessor :frontend
75
+
76
+ # Create a new CallbackHandler and assign value of the parameter frontend to
77
+ # the frontend attribute.
78
+ def initialize(frontend)
79
+ @frontend = frontend
80
+ end
81
+
82
+ # Parses the given xml_str and returns the appropriate *Callback class. At the
83
+ # moment, only MerchantCalculationCallback objects can be returned.
84
+ def handle(xml_str)
85
+ root = REXML::Document.new(xml_str).root
86
+
87
+ case root.name
88
+ when 'merchant-calculation-callback' then
89
+ MerchantCalculationCallback.create_from_element(root, frontend)
90
+ else
91
+ raise UnknownCallbackType, "Unknown callback type: #{root.name}"
92
+ end
93
+ end
94
+ end
95
+
96
+ # Google Checkout send a <merchant-calculation-callback> message to you when any of the
97
+ # events occur:
98
+ # The customer signs in to Google Checkout.
99
+ # The customer enters a new shipping address on the Place Order page.
100
+ # The customer enters a coupon or gift certificate code.
101
+ #
102
+ # The message will be parsed into a MerchantCalculationCallback instance.
103
+ #
104
+ class MerchantCalculationCallback
105
+ # The frontend this callback belongs to.
106
+ attr_accessor :frontend
107
+
108
+ # The order's shopping cart (ShoppingCart)
109
+ attr_accessor :shopping_cart
110
+
111
+ # The buyer's language
112
+ attr_accessor :buyer_language
113
+
114
+ # An array of AnonymousAddress objects of this callback.
115
+ attr_reader :anonymous_addresses
116
+
117
+ # This indicates whether the merchant needs to calculate taxes for the order.
118
+ attr_accessor :tax
119
+
120
+ # An array of shipping method names
121
+ attr_reader :shipping_methods
122
+
123
+ # An array of merchant codes
124
+ attr_reader :merchant_code_strings
125
+
126
+ # The tax tables for the items in the order notification.
127
+ attr_reader :tax_tables
128
+
129
+ # Sets the frontend attribute to the value of the frontend parameter.
130
+ def initialize(frontend)
131
+ @frontend = frontend
132
+ @anonymous_addresses = Array.new
133
+ @shipping_methods = Array.new
134
+ @merchant_code_strings = Array.new
135
+ @tax_tables = frontend.tax_table_factory.effective_tax_tables_at(Time.now)
136
+ end
137
+
138
+ # Factory method to create a new MerchantCalculationCallback object from
139
+ # the REXML:Element object
140
+ #
141
+ # Raises NoMethodError and RuntimeError exceptions if the given element misses required
142
+ # elements.
143
+ #
144
+ # You have to pass in the Frontend class this callback belongs to.
145
+ def self.create_from_element(element, frontend)
146
+ result = MerchantCalculationCallback.new(frontend)
147
+
148
+ result.shopping_cart = ShoppingCart.create_from_element(element.elements['shopping-cart'], result)
149
+ result.buyer_language = element.elements['buyer-language'].text
150
+ element.elements.each('calculate/addresses/anonymous-address') do |address_element|
151
+ result.anonymous_addresses << AnonymousAddress.create_from_element(address_element)
152
+ end
153
+ result.tax = element.elements['calculate/tax'].text
154
+ element.elements.each('calculate/shipping/method') do |shipping_method_element|
155
+ result.shipping_methods << shipping_method_element.attributes['name']
156
+ end
157
+ element.elements.each('calculate/merchant-code-strings/merchant-code-string') do |merchant_code_string_element|
158
+ result.merchant_code_strings << merchant_code_string_element.attributes['code']
159
+ end
160
+
161
+ return result
162
+ end
163
+ end
164
+
165
+ # This class represents a merchant-calculation-results XML
166
+ #
167
+ # === Usage Sample
168
+ #
169
+ # results = MerchantCalculationResults.new
170
+ # coupon_result = CouponResult.new(true, 'FirstVisitCoupon', Money.new(500, 'USD'), 'Congratulations! You saved $5.00 on your first visit!')
171
+ # gift_certificate_result = GiftCertificateResult.new(true, 'GiftCert012345', Money.new(1000, 'USD'), 'You used your Gift Certificate!')
172
+ #
173
+ # results.create_merchant_calculation_result do |result|
174
+ # result.shipping_name = 'SuperShip'
175
+ # result.address_id = '739030698069958'
176
+ # result.shipping_rate = Money.new(703, 'USD')
177
+ # result.shippable = true
178
+ # result.total_tax = Money.new(1467, 'USD')
179
+ # result.create_merchant_code_result(@coupon_result)
180
+ # result.create_merchant_code_result(@gift_certificate_result)
181
+ # end
182
+ #
183
+ # results.create_merchant_calculation_result do |result|
184
+ # result.shipping_name = 'UPS Ground'
185
+ # result.address_id = '739030698069958'
186
+ # result.shipping_rate = Money.new(556, 'USD')
187
+ # result.shippable = true
188
+ # result.total_tax = Money.new(1467, 'USD')
189
+ # result.create_merchant_code_result(@coupon_result)
190
+ # result.create_merchant_code_result(@gift_certificate_result)
191
+ # end
192
+ #
193
+ # results.to_xml # To create the XML to return to Google
194
+ #
195
+ class MerchantCalculationResults
196
+ # An array of merchant calcuation results
197
+ attr_reader :merchant_calculation_results
198
+
199
+ def initialize()
200
+ @merchant_calculation_results = Array.new
201
+ end
202
+
203
+ # This method takes a MerchantCalculationResult object and add it to the
204
+ # merchant_calculation_results array. If the object is not provided, it will
205
+ # instantiate one and add it to the array. An optional code block can be
206
+ # supplied to set the attributes of the new MerchantCalculationResult object.
207
+ #
208
+ # Raises RuntimeError exceptions if the given object is not of type
209
+ # MerchantCalculationResult.
210
+ def create_merchant_calculation_result(result=nil, &block)
211
+ if result.nil?
212
+ result = MerchantCalculationResult.new
213
+ # Pass the newly generated item to the given block to set its attributes.
214
+ yield(result) if block_given?
215
+ else
216
+ raise "Not a MerchantCalculationResult!" unless result.kind_of?(MerchantCalculationResult)
217
+ end
218
+ @merchant_calculation_results << result
219
+ end
220
+
221
+ def to_xml()
222
+ return MerchantCalculationResultsXmlGenerator.new(self).generate()
223
+ end
224
+ end
225
+
226
+ # The class represnts a merchant-calculation-result in the merchant-calculation-results XML
227
+ class MerchantCalculationResult
228
+ # The shipping name (string)
229
+ attr_accessor :shipping_name
230
+
231
+ # The address id (string)
232
+ attr_accessor :address_id
233
+
234
+ # The shipping rate (Money)
235
+ attr_accessor :shipping_rate
236
+
237
+ # Is it this applicable to this order (boolean)
238
+ attr_accessor :shippable
239
+
240
+ # The total tax (Money)
241
+ attr_accessor :total_tax
242
+
243
+ # An array of merchant code results
244
+ attr_reader :merchant_code_results
245
+
246
+ def initialize(shipping_name='', address_id='', shipping_rate=nil, shippable=false, total_tax=nil)
247
+ @shipping_name = shipping_name
248
+ @address_id = address_id
249
+ @shipping_rate = shipping_rate
250
+ @shippable = shippable
251
+ @total_tax = total_tax
252
+ @merchant_code_results = Array.new
253
+ end
254
+
255
+ # This method takes either a CouponResult or GiftCertificateResult object and
256
+ # add it to the merchant_code_results array. If the Class object of either
257
+ # the two types is provided, it will create an instance from the Class object.
258
+ # An optional code block can be supplied to set the attributes of the new
259
+ # object.
260
+ #
261
+ # Raises RuntimeError exceptions if there is no argument or a wrong class
262
+ # type is provided.
263
+ def create_merchant_code_result(result=nil, &block)
264
+ if !result.nil?
265
+ if [ CouponResult, GiftCertificateResult ].include?(result) # is a Class object
266
+ result = result.new
267
+ else
268
+ raise "Invalid Merchant Code Result class type: #{result.class}!" unless
269
+ (result.kind_of?(CouponResult) || result.kind_of?(GiftCertificateResult))
270
+ end
271
+ else
272
+ raise "You must either provide a MerchantCodeResult Class type or a CoupleResult or GiftCertificateResult instance."
273
+ end
274
+ @merchant_code_results << result
275
+
276
+ # Pass the newly generated item to the given block to set its attributes.
277
+ yield(result) if block_given?
278
+
279
+ end
280
+ end
281
+
282
+ # Base class for merchant code (coupon and gift certificate)
283
+ class CodeResult
284
+ # Is this valid (boolean)
285
+ attr_accessor :valid
286
+
287
+ # The code (string)
288
+ attr_accessor :code
289
+
290
+ # The calculated amount (Money)
291
+ attr_accessor :calculated_amount
292
+
293
+ # The message (string)
294
+ attr_accessor :message
295
+
296
+ def initialize()
297
+ raise "Do not use the abstract class Google::Checkout::CodeReslt"
298
+ end
299
+ end
300
+
301
+ # This class represents a coupon-result in the merchant-calculation-results XML
302
+ class CouponResult < CodeResult
303
+ def initialize(valid=false, code='', calculated_amount=nil, message='')
304
+ @valid = valid
305
+ @code = code
306
+ @calculated_amount = calculated_amount
307
+ @message = message
308
+ end
309
+ end
310
+
311
+ # This class represents a gift-certificate-result in the merchant-calculation-results XML
312
+ class GiftCertificateResult < CodeResult
313
+ def initialize(valid=false, code='', calculated_amount=nil, message='')
314
+ @valid = valid
315
+ @code = code
316
+ @calculated_amount = calculated_amount
317
+ @message = message
318
+ end
319
+ end
320
+ end
321
+ end