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.
- data/CHANGES +93 -0
- data/LICENSE +22 -0
- data/README +58 -0
- data/Rakefile +13 -0
- data/VERSION +1 -0
- data/google4r-checkout-1.0.5-1.0.5.gem +0 -0
- data/google4r-checkout-1.0.5.gemspec +174 -0
- data/lib/google4r/checkout.rb +34 -0
- data/lib/google4r/checkout/commands.rb +567 -0
- data/lib/google4r/checkout/frontend.rb +210 -0
- data/lib/google4r/checkout/merchant_calculation.rb +321 -0
- data/lib/google4r/checkout/notifications.rb +708 -0
- data/lib/google4r/checkout/shared.rb +1086 -0
- data/lib/google4r/checkout/utils.rb +94 -0
- data/lib/google4r/checkout/xml_generation.rb +880 -0
- data/test/integration/checkout_command_test.rb +174 -0
- data/test/unit/add_merchant_order_number_command_test.rb +70 -0
- data/test/unit/add_tracking_data_command_test.rb +75 -0
- data/test/unit/address_test.rb +131 -0
- data/test/unit/anonymous_address_test.rb +75 -0
- data/test/unit/archive_order_command_test.rb +66 -0
- data/test/unit/area_test.rb +44 -0
- data/test/unit/authorization_amount_notification_test.rb +69 -0
- data/test/unit/authorize_order_command_test.rb +66 -0
- data/test/unit/backorder_items_command_test.rb +83 -0
- data/test/unit/callback_handler_test.rb +83 -0
- data/test/unit/cancel_items_command_test.rb +89 -0
- data/test/unit/cancel_order_command_test.rb +83 -0
- data/test/unit/carrier_calculated_shipping_test.rb +57 -0
- data/test/unit/charge_amount_notification_test.rb +64 -0
- data/test/unit/charge_order_command_test.rb +77 -0
- data/test/unit/chargeback_amount_notification_test.rb +65 -0
- data/test/unit/checkout_command_test.rb +125 -0
- data/test/unit/checkout_command_xml_generator_test.rb +218 -0
- data/test/unit/command_test.rb +116 -0
- data/test/unit/deliver_order_command_test.rb +70 -0
- data/test/unit/delivery_method_test.rb +42 -0
- data/test/unit/digital_content_test.rb +105 -0
- data/test/unit/flat_rate_shipping_test.rb +132 -0
- data/test/unit/frontend_test.rb +144 -0
- data/test/unit/item_info_test.rb +69 -0
- data/test/unit/item_test.rb +171 -0
- data/test/unit/marketing_preferences_test.rb +65 -0
- data/test/unit/merchant_calculated_shipping_test.rb +172 -0
- data/test/unit/merchant_calculation_callback_test.rb +137 -0
- data/test/unit/merchant_calculation_result_test.rb +78 -0
- data/test/unit/merchant_calculation_results_test.rb +178 -0
- data/test/unit/merchant_code_result_test.rb +51 -0
- data/test/unit/merchant_code_test.rb +122 -0
- data/test/unit/new_order_notification_test.rb +115 -0
- data/test/unit/notification_acknowledgement_test.rb +67 -0
- data/test/unit/notification_handler_test.rb +113 -0
- data/test/unit/order_adjustment_test.rb +119 -0
- data/test/unit/order_report_command_test.rb +111 -0
- data/test/unit/order_state_change_notification_test.rb +158 -0
- data/test/unit/pickup_shipping_test.rb +70 -0
- data/test/unit/postal_area_test.rb +71 -0
- data/test/unit/private_data_parser_test.rb +68 -0
- data/test/unit/refund_amount_notification_test.rb +65 -0
- data/test/unit/refund_order_command_test.rb +86 -0
- data/test/unit/reset_items_shipping_information_command_test.rb +83 -0
- data/test/unit/return_items_command_test.rb +83 -0
- data/test/unit/risk_information_notification_test.rb +98 -0
- data/test/unit/send_buyer_message_command_test.rb +73 -0
- data/test/unit/ship_items_command_test.rb +101 -0
- data/test/unit/shipping_adjustment_test.rb +100 -0
- data/test/unit/shopping_cart_test.rb +146 -0
- data/test/unit/tax_rule_test.rb +70 -0
- data/test/unit/tax_table_test.rb +82 -0
- data/test/unit/tracking_data_test.rb +54 -0
- data/test/unit/unarchive_order_command_test.rb +66 -0
- data/test/unit/us_country_area_test.rb +76 -0
- data/test/unit/us_state_area_test.rb +70 -0
- data/test/unit/us_zip_area_test.rb +66 -0
- data/test/unit/world_area_test.rb +48 -0
- data/var/cacert.pem +7815 -0
- 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
|