archerfinley-google4r-checkout-1.0.5 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. data/CHANGES +93 -0
  2. data/LICENSE +22 -0
  3. data/README +58 -0
  4. data/Rakefile +13 -0
  5. data/VERSION +1 -0
  6. data/google4r-checkout-1.0.5-1.0.5.gem +0 -0
  7. data/google4r-checkout-1.0.5.gemspec +174 -0
  8. data/lib/google4r/checkout.rb +34 -0
  9. data/lib/google4r/checkout/commands.rb +567 -0
  10. data/lib/google4r/checkout/frontend.rb +210 -0
  11. data/lib/google4r/checkout/merchant_calculation.rb +321 -0
  12. data/lib/google4r/checkout/notifications.rb +708 -0
  13. data/lib/google4r/checkout/shared.rb +1086 -0
  14. data/lib/google4r/checkout/utils.rb +94 -0
  15. data/lib/google4r/checkout/xml_generation.rb +880 -0
  16. data/test/integration/checkout_command_test.rb +174 -0
  17. data/test/unit/add_merchant_order_number_command_test.rb +70 -0
  18. data/test/unit/add_tracking_data_command_test.rb +75 -0
  19. data/test/unit/address_test.rb +131 -0
  20. data/test/unit/anonymous_address_test.rb +75 -0
  21. data/test/unit/archive_order_command_test.rb +66 -0
  22. data/test/unit/area_test.rb +44 -0
  23. data/test/unit/authorization_amount_notification_test.rb +69 -0
  24. data/test/unit/authorize_order_command_test.rb +66 -0
  25. data/test/unit/backorder_items_command_test.rb +83 -0
  26. data/test/unit/callback_handler_test.rb +83 -0
  27. data/test/unit/cancel_items_command_test.rb +89 -0
  28. data/test/unit/cancel_order_command_test.rb +83 -0
  29. data/test/unit/carrier_calculated_shipping_test.rb +57 -0
  30. data/test/unit/charge_amount_notification_test.rb +64 -0
  31. data/test/unit/charge_order_command_test.rb +77 -0
  32. data/test/unit/chargeback_amount_notification_test.rb +65 -0
  33. data/test/unit/checkout_command_test.rb +125 -0
  34. data/test/unit/checkout_command_xml_generator_test.rb +218 -0
  35. data/test/unit/command_test.rb +116 -0
  36. data/test/unit/deliver_order_command_test.rb +70 -0
  37. data/test/unit/delivery_method_test.rb +42 -0
  38. data/test/unit/digital_content_test.rb +105 -0
  39. data/test/unit/flat_rate_shipping_test.rb +132 -0
  40. data/test/unit/frontend_test.rb +144 -0
  41. data/test/unit/item_info_test.rb +69 -0
  42. data/test/unit/item_test.rb +171 -0
  43. data/test/unit/marketing_preferences_test.rb +65 -0
  44. data/test/unit/merchant_calculated_shipping_test.rb +172 -0
  45. data/test/unit/merchant_calculation_callback_test.rb +137 -0
  46. data/test/unit/merchant_calculation_result_test.rb +78 -0
  47. data/test/unit/merchant_calculation_results_test.rb +178 -0
  48. data/test/unit/merchant_code_result_test.rb +51 -0
  49. data/test/unit/merchant_code_test.rb +122 -0
  50. data/test/unit/new_order_notification_test.rb +115 -0
  51. data/test/unit/notification_acknowledgement_test.rb +67 -0
  52. data/test/unit/notification_handler_test.rb +113 -0
  53. data/test/unit/order_adjustment_test.rb +119 -0
  54. data/test/unit/order_report_command_test.rb +111 -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/var/cacert.pem +7815 -0
  77. metadata +189 -0
@@ -0,0 +1,210 @@
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
+
203
+ # Factory method that creates a new OrderReportCommand object. Use this method to create
204
+ # your OrderReportCommand instances.
205
+ def create_order_report_command(start_date, end_date)
206
+ return OrderReportCommand.new(self, start_date, end_date)
207
+ end
208
+ end
209
+ end
210
+ 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