google4r-checkout 1.0.1 → 1.0.2
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 +9 -0
- data/lib/google4r/checkout.rb +1 -0
- data/lib/google4r/checkout/commands.rb +13 -1
- data/lib/google4r/checkout/frontend.rb +14 -8
- data/lib/google4r/checkout/merchant_calculation.rb +317 -0
- data/lib/google4r/checkout/notifications.rb +0 -56
- data/lib/google4r/checkout/shared.rb +172 -32
- data/lib/google4r/checkout/xml_generation.rb +140 -24
- data/test/unit/anonymous_address_test.rb +75 -0
- data/test/unit/callback_handler_test.rb +83 -0
- data/test/unit/checkout_command_test.rb +7 -3
- data/test/unit/checkout_command_xml_generator_test.rb +7 -1
- data/test/unit/{shipping_method_test.rb → delivery_method_test.rb} +4 -3
- data/test/unit/flat_rate_shipping_test.rb +28 -10
- data/test/unit/merchant_calculated_shipping_test.rb +136 -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
- metadata +11 -3
data/CHANGES
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
=google4r-checkout Changelog
|
2
2
|
|
3
|
+
== 1.0.2 (2007-08-18)
|
4
|
+
|
5
|
+
* Moved Address from notifications.rb to shared.rb
|
6
|
+
* Added AnonymousAddress class, now Address is extended from it
|
7
|
+
* Added merchant calcuations callback and result support
|
8
|
+
* Added unit tests for merchant calculation callback and result
|
9
|
+
* Added merchant calculations tag support in Shopping Cart XML
|
10
|
+
* Updated checkout_command_test.rb and checkout_command_xml_generator_test.rb after for testing merchant calculations tag support
|
11
|
+
|
3
12
|
== 1.0.1 (2007-08-16)
|
4
13
|
|
5
14
|
* Fixed text.to_s.gsub(/[^0-9]/, '') to (...text.to_f*100).to_i so dollar amount is now handled correctly
|
data/lib/google4r/checkout.rb
CHANGED
@@ -208,6 +208,18 @@ module Google4R #:nodoc:
|
|
208
208
|
# A boolean flag; true iff the customer HAS to provide his phone number (optional).
|
209
209
|
attr_accessor :request_buyer_phone_number
|
210
210
|
|
211
|
+
# The URL of the merchant calculation callback (optional).
|
212
|
+
attr_accessor :merchant_calculations_url
|
213
|
+
|
214
|
+
# A boolean flag to indicate whether merchant coupon is supported or not (optional).
|
215
|
+
attr_accessor :accept_merchant_coupons
|
216
|
+
|
217
|
+
# A boolean flag to indicate whether gift certificate is supported or not (optional).
|
218
|
+
attr_accessor :accept_gift_certificates
|
219
|
+
|
220
|
+
# A Google Checkout merchant ID that identifies the eCommerce provider.
|
221
|
+
attr_accessor :platform_id
|
222
|
+
|
211
223
|
# Generates the XML for this CheckoutCommand.
|
212
224
|
def to_xml
|
213
225
|
CheckoutCommandXmlGenerator.new(self).generate
|
@@ -237,7 +249,7 @@ module Google4R #:nodoc:
|
|
237
249
|
#
|
238
250
|
# Raises a ArgumentError if the parameter clazz is invalid.
|
239
251
|
def create_shipping_method(clazz, &block)
|
240
|
-
if not [ PickupShipping, FlatRateShipping ].include?(clazz) then
|
252
|
+
if not [ PickupShipping, FlatRateShipping, MerchantCalculatedShipping ].include?(clazz) then
|
241
253
|
raise ArgumentError, "Unknown shipping method: #{clazz.inspect}."
|
242
254
|
end
|
243
255
|
|
@@ -29,8 +29,8 @@
|
|
29
29
|
|
30
30
|
module Google4R #:nodoc:
|
31
31
|
module Checkout #:nodoc:
|
32
|
-
# The Frontend class is the factory that is to be used to create the Command
|
33
|
-
# NotificationHandler
|
32
|
+
# The Frontend class is the factory that is to be used to create the Command,
|
33
|
+
# NotificationHandler and CallbackHandler objects.
|
34
34
|
#
|
35
35
|
# === Example
|
36
36
|
#
|
@@ -91,6 +91,18 @@ module Google4R #:nodoc:
|
|
91
91
|
|
92
92
|
@configuration = configuration.dup.freeze
|
93
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
|
94
106
|
|
95
107
|
# Factory method to create a new DeliverOrderCommand object. Use this method to create
|
96
108
|
# your DeliverOrderCommand instances.
|
@@ -109,12 +121,6 @@ module Google4R #:nodoc:
|
|
109
121
|
def create_checkout_command
|
110
122
|
return CheckoutCommand.new(self)
|
111
123
|
end
|
112
|
-
|
113
|
-
# Factory method that creates a new NotificationHandler object. Use this method to
|
114
|
-
# create your NotificationHandler instances.
|
115
|
-
def create_notification_handler
|
116
|
-
return NotificationHandler.new(self)
|
117
|
-
end
|
118
124
|
|
119
125
|
# Factory method to create a new CancelOrderCommand object. Use this method to create
|
120
126
|
# your CancelOrderCommand instances.
|
@@ -0,0 +1,317 @@
|
|
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
|
+
# Sets the frontend attribute to the value of the frontend parameter.
|
127
|
+
def initialize(frontend)
|
128
|
+
@frontend = frontend
|
129
|
+
@anonymous_addresses = Array.new
|
130
|
+
@shipping_methods = Array.new
|
131
|
+
@merchant_code_strings = Array.new
|
132
|
+
end
|
133
|
+
|
134
|
+
# Factory method to create a new MerchantCalculationCallback object from
|
135
|
+
# the REXML:Element object
|
136
|
+
#
|
137
|
+
# Raises NoMethodError and RuntimeError exceptions if the given element misses required
|
138
|
+
# elements.
|
139
|
+
#
|
140
|
+
# You have to pass in the Frontend class this callback belongs to.
|
141
|
+
def self.create_from_element(element, frontend)
|
142
|
+
result = MerchantCalculationCallback.new(frontend)
|
143
|
+
|
144
|
+
result.shopping_cart = ShoppingCart.create_from_element(element.elements['shopping-cart'], result)
|
145
|
+
result.buyer_language = element.elements['buyer-language'].text
|
146
|
+
element.elements.each('calculate/addresses/anonymous-address') do |address_element|
|
147
|
+
result.anonymous_addresses << AnonymousAddress.create_from_element(address_element)
|
148
|
+
end
|
149
|
+
result.tax = element.elements['calculate/tax'].text
|
150
|
+
element.elements.each('calculate/shipping/method') do |shipping_method_element|
|
151
|
+
result.shipping_methods << shipping_method_element.attributes['name']
|
152
|
+
end
|
153
|
+
element.elements.each('calculate/merchant-code-strings/merchant-code-string') do |merchant_code_string_element|
|
154
|
+
result.merchant_code_strings << merchant_code_string_element.attributes['code']
|
155
|
+
end
|
156
|
+
|
157
|
+
return result
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
# This class represents a merchant-calculation-results XML
|
162
|
+
#
|
163
|
+
# === Usage Sample
|
164
|
+
#
|
165
|
+
# results = MerchantCalculationResults.new
|
166
|
+
# coupon_result = CouponResult.new(true, 'FirstVisitCoupon', Money.new(500, 'USD'), 'Congratulations! You saved $5.00 on your first visit!')
|
167
|
+
# gift_certificate_result = GiftCertificateResult.new(true, 'GiftCert012345', Money.new(1000, 'USD'), 'You used your Gift Certificate!')
|
168
|
+
#
|
169
|
+
# results.create_merchant_calculation_result do |result|
|
170
|
+
# result.shipping_name = 'SuperShip'
|
171
|
+
# result.address_id = '739030698069958'
|
172
|
+
# result.shipping_rate = Money.new(703, 'USD')
|
173
|
+
# result.shippable = true
|
174
|
+
# result.total_tax = Money.new(1467, 'USD')
|
175
|
+
# result.create_merchant_code_result(@coupon_result)
|
176
|
+
# result.create_merchant_code_result(@gift_certificate_result)
|
177
|
+
# end
|
178
|
+
#
|
179
|
+
# results.create_merchant_calculation_result do |result|
|
180
|
+
# result.shipping_name = 'UPS Ground'
|
181
|
+
# result.address_id = '739030698069958'
|
182
|
+
# result.shipping_rate = Money.new(556, 'USD')
|
183
|
+
# result.shippable = true
|
184
|
+
# result.total_tax = Money.new(1467, 'USD')
|
185
|
+
# result.create_merchant_code_result(@coupon_result)
|
186
|
+
# result.create_merchant_code_result(@gift_certificate_result)
|
187
|
+
# end
|
188
|
+
#
|
189
|
+
# results.to_xml # To create the XML to return to Google
|
190
|
+
#
|
191
|
+
class MerchantCalculationResults
|
192
|
+
# An array of merchant calcuation results
|
193
|
+
attr_reader :merchant_calculation_results
|
194
|
+
|
195
|
+
def initialize()
|
196
|
+
@merchant_calculation_results = Array.new
|
197
|
+
end
|
198
|
+
|
199
|
+
# This method takes a MerchantCalculationResult object and add it to the
|
200
|
+
# merchant_calculation_results array. If the object is not provided, it will
|
201
|
+
# instantiate one and add it to the array. An optional code block can be
|
202
|
+
# supplied to set the attributes of the new MerchantCalculationResult object.
|
203
|
+
#
|
204
|
+
# Raises RuntimeError exceptions if the given object is not of type
|
205
|
+
# MerchantCalculationResult.
|
206
|
+
def create_merchant_calculation_result(result=nil, &block)
|
207
|
+
if result.nil?
|
208
|
+
result = MerchantCalculationResult.new
|
209
|
+
# Pass the newly generated item to the given block to set its attributes.
|
210
|
+
yield(result) if block_given?
|
211
|
+
else
|
212
|
+
raise "Not a MerchantCalculationResult!" unless result.kind_of?(MerchantCalculationResult)
|
213
|
+
end
|
214
|
+
@merchant_calculation_results << result
|
215
|
+
end
|
216
|
+
|
217
|
+
def to_xml()
|
218
|
+
return MerchantCalculationResultsXmlGenerator.new(self).generate()
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
# The class represnts a merchant-calculation-result in the merchant-calculation-results XML
|
223
|
+
class MerchantCalculationResult
|
224
|
+
# The shipping name (string)
|
225
|
+
attr_accessor :shipping_name
|
226
|
+
|
227
|
+
# The address id (string)
|
228
|
+
attr_accessor :address_id
|
229
|
+
|
230
|
+
# The shipping rate (Money)
|
231
|
+
attr_accessor :shipping_rate
|
232
|
+
|
233
|
+
# Is it this applicable to this order (boolean)
|
234
|
+
attr_accessor :shippable
|
235
|
+
|
236
|
+
# The total tax (Money)
|
237
|
+
attr_accessor :total_tax
|
238
|
+
|
239
|
+
# An array of merchant code results
|
240
|
+
attr_reader :merchant_code_results
|
241
|
+
|
242
|
+
def initialize(shipping_name='', address_id='', shipping_rate=nil, shippable=false, total_tax=nil)
|
243
|
+
@shipping_name = shipping_name
|
244
|
+
@address_id = address_id
|
245
|
+
@shipping_rate = shipping_rate
|
246
|
+
@shippable = shippable
|
247
|
+
@total_tax = total_tax
|
248
|
+
@merchant_code_results = Array.new
|
249
|
+
end
|
250
|
+
|
251
|
+
# This method takes either a CouponResult or GiftCertificateResult object and
|
252
|
+
# add it to the merchant_code_results array. If the Class object of either
|
253
|
+
# the two types is provided, it will create an instance from the Class object.
|
254
|
+
# An optional code block can be supplied to set the attributes of the new
|
255
|
+
# object.
|
256
|
+
#
|
257
|
+
# Raises RuntimeError exceptions if there is no argument or a wrong class
|
258
|
+
# type is provided.
|
259
|
+
def create_merchant_code_result(result=nil, &block)
|
260
|
+
if !result.nil?
|
261
|
+
if [ CouponResult, GiftCertificateResult ].include?(result) # is a Class object
|
262
|
+
result = result.new
|
263
|
+
else
|
264
|
+
raise "Invalid Merchant Code Result class type: #{result.class}!" unless
|
265
|
+
(result.kind_of?(CouponResult) || result.kind_of?(GiftCertificateResult))
|
266
|
+
end
|
267
|
+
else
|
268
|
+
raise "You must either provide a MerchantCodeResult Class type or a CoupleResult or GiftCertificateResult instance."
|
269
|
+
end
|
270
|
+
@merchant_code_results << result
|
271
|
+
|
272
|
+
# Pass the newly generated item to the given block to set its attributes.
|
273
|
+
yield(result) if block_given?
|
274
|
+
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
# Base class for merchant code (coupon and gift certificate)
|
279
|
+
class CodeResult
|
280
|
+
# Is this valid (boolean)
|
281
|
+
attr_accessor :valid
|
282
|
+
|
283
|
+
# The code (string)
|
284
|
+
attr_accessor :code
|
285
|
+
|
286
|
+
# The calculated amount (Money)
|
287
|
+
attr_accessor :calculated_amount
|
288
|
+
|
289
|
+
# The message (string)
|
290
|
+
attr_accessor :message
|
291
|
+
|
292
|
+
def initialize()
|
293
|
+
raise "Do not use the abstract class Google::Checkout::CodeReslt"
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
# This class represents a coupon-result in the merchant-calculation-results XML
|
298
|
+
class CouponResult < CodeResult
|
299
|
+
def initialize(valid=false, code='', calculated_amount=nil, message='')
|
300
|
+
@valid = valid
|
301
|
+
@code = code
|
302
|
+
@calculated_amount = calculated_amount
|
303
|
+
@message = message
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
# This class represents a gift-certificate-result in the merchant-calculation-results XML
|
308
|
+
class GiftCertificateResult < CodeResult
|
309
|
+
def initialize(valid=false, code='', calculated_amount=nil, message='')
|
310
|
+
@valid = valid
|
311
|
+
@code = code
|
312
|
+
@calculated_amount = calculated_amount
|
313
|
+
@message = message
|
314
|
+
end
|
315
|
+
end
|
316
|
+
end
|
317
|
+
end
|
@@ -583,62 +583,6 @@ module Google4R #:nodoc:
|
|
583
583
|
DELIVERED = "DELIVERED".freeze
|
584
584
|
WILL_NOT_DELIVER = "WILL_NOT_DELIVER".freeze
|
585
585
|
end
|
586
|
-
|
587
|
-
# Address instances are used in NewOrderNotification objects for the buyer's billing
|
588
|
-
# and buyer's shipping address.
|
589
|
-
class Address
|
590
|
-
# Contact name (String, optional).
|
591
|
-
attr_accessor :contact_name
|
592
|
-
|
593
|
-
# Second Address line (String).
|
594
|
-
attr_accessor :address1
|
595
|
-
|
596
|
-
# Second Address line (String optional).
|
597
|
-
attr_accessor :address2
|
598
|
-
|
599
|
-
# The buyer's city name (String).
|
600
|
-
attr_accessor :city
|
601
|
-
|
602
|
-
# The buyer's company name (String; optional).
|
603
|
-
attr_accessor :company_name
|
604
|
-
|
605
|
-
# The buyer's country code (String, 2 chars, ISO 3166).
|
606
|
-
attr_accessor :country_code
|
607
|
-
|
608
|
-
# The buyer's email address (String; optional).
|
609
|
-
attr_accessor :email
|
610
|
-
|
611
|
-
# The buyer's phone number (String; optional).
|
612
|
-
attr_accessor :fax
|
613
|
-
|
614
|
-
# The buyer's phone number (String; Optional, can be enforced in CheckoutCommand).)
|
615
|
-
attr_accessor :phone
|
616
|
-
|
617
|
-
# The buyers postal/zip code (String).
|
618
|
-
attr_accessor :postal_code
|
619
|
-
|
620
|
-
# The buyer's geographical region (String).
|
621
|
-
attr_accessor :region
|
622
|
-
|
623
|
-
# Creates a new Address from the given REXML::Element instance.
|
624
|
-
def self.create_from_element(element)
|
625
|
-
result = Address.new
|
626
|
-
|
627
|
-
result.address1 = element.elements['address1'].text
|
628
|
-
result.address2 = element.elements['address2'].text rescue nil
|
629
|
-
result.city = element.elements['city'].text
|
630
|
-
result.company_name = element.elements['company-name'].text rescue nil
|
631
|
-
result.contact_name = element.elements['contact-name'].text rescue nil
|
632
|
-
result.country_code = element.elements['country-code'].text
|
633
|
-
result.email = element.elements['email'].text rescue nil
|
634
|
-
result.fax = element.elements['fax'].text rescue nil
|
635
|
-
result.phone = element.elements['phone'].text rescue nil
|
636
|
-
result.postal_code = element.elements['postal-code'].text
|
637
|
-
result.region = element.elements['region'].text
|
638
|
-
|
639
|
-
return result
|
640
|
-
end
|
641
|
-
end
|
642
586
|
|
643
587
|
# The marketing preferences of a customer.
|
644
588
|
class MarketingPreferences
|