Package gchecky :: Module model
[hide private]
[frames] | no frames]

Source Code for Module gchecky.model

  1  """ 
  2  gchecky.model module describes the mapping between Google Checkout API (GC API) 
  3  XML messages (GC API XML Schema) and data classes. 
  4   
  5  This module uses L{gchecky.gxml} to automate much of the work so that 
  6  the actual logic is not cluttered with machinery. 
  7   
  8  The module code is simple and self-documenting. Please read the source code for 
  9  simple description of the data-structures. Note that it tries to follow exactly 
 10  the official GC API XML Schema. 
 11   
 12  All the comments for the GC API are at U{Google Chackout API documentation 
 13  <http://code.google.com/apis/checkout/developer/>}. Please consult it for any 
 14  questions about GC API functioning. 
 15   
 16  @author: etarassov 
 17  @version: $Revision: 129 $ 
 18  @contact: gchecky at gmail 
 19  """ 
 20   
 21  from gchecky import gxml 
 22  from gchecky.data import CountryCode, PresentOrNot 
 23   
24 -def test_document(doc, xml_text=None):
25 """ 26 Method used in doctests: ensures that a document is properly serialized. 27 """ 28 29 def normalize_xml(xml_text): 30 """ 31 Normalize the xml text to canonical form, so that two xml text chunks 32 could be compared directly as strings. 33 """ 34 # If xml misses header, then add it. 35 if len(xml_text) < 2 or xml_text[0:2] != "<?": 36 xml_text = "<?xml version='1.0' encoding='UTF-8'?>\n" + xml_text 37 from xml.dom.minidom import parseString 38 doc = parseString(xml_text) 39 40 text = doc.toprettyxml('') 41 # To avoid formatting problems we just strip all the line returns and 42 # spaces (while it breaks XML into a text string it still makes 43 # this form a 'canonical' one). 44 return text.replace('\n', '').replace(' ', '')
45 46 expected_xml = ((xml_text is not None) and normalize_xml(xml_text)) or None 47 obtained_xml = normalize_xml(doc.toxml(pretty=' ')) 48 49 if expected_xml is not None and expected_xml != obtained_xml: 50 print "Expected:\n\n%s\n\nGot:\n\n%s\n" % (xml_text, doc.toxml(' ')) 51 52 doc2 = gxml.Document.fromxml(doc.toxml()) 53 if not (doc == doc2): 54 print ''' 55 Failed to correctly interpret the generated XML for this document: 56 Original: 57 %s 58 Parsed: 59 %s 60 ''' % (doc.toxml(pretty=True), doc2.toxml()) 61
62 -def test_node(node, xml_text=None):
63 """ 64 Method used in doctests. Ensure that a node is properly serialized. 65 """ 66 class Dummy(gxml.Document): 67 tag_name='dummy' 68 data=gxml.Complex('node', node.__class__, required=True)
69 if xml_text is not None: 70 xml_text = xml_text.replace('<', ' <') 71 # TODO ...just ugly (below) 72 xml_text = "<dummy xmlns='http://checkout.google.com/schema/2'>%s</dummy>" % (xml_text,) 73 test_document(Dummy(data=node), xml_text) 74 75 CURRENCIES = ('USD', 'GBP') 76
77 -class price_t(gxml.Node):
78 value = gxml.Double('', default=0) 79 currency = gxml.String('@currency', values=CURRENCIES)
80 81 DISPLAY_DISPOSITION = ('OPTIMISTIC', 'PESSIMISTIC')
82 -class digital_content_t(gxml.Node):
83 description = gxml.Html('description', max_length=1024, required=False) 84 email_delivery = gxml.Boolean('email-delivery', required=False) 85 key = gxml.String('key', required=False) 86 url = gxml.String('url', required=False) 87 display_disposition = gxml.String('display-disposition', required=False, 88 values=DISPLAY_DISPOSITION)
89
90 -class item_weight_t(gxml.Node):
91 value = gxml.Double('@value') # , negative=False 92 unit = gxml.String('@unit', values=('LB',))
93
94 -class item_t(gxml.Node):
95 """ 96 >>> test_node(item_t(name='Peter', description='The Great', unit_price=price_t(value=1, currency='GBP'), quantity=1, merchant_item_id='custom_merchant_item_id', 97 ... merchant_private_item_data=['some', {'private':'data', 'to':['test','the'],'thing':None}, '!! Numbers: ', None, False, True, [11, 12., [13.4]]]) 98 ... ) 99 >>> test_node(item_t(name='Name with empty description', description='', unit_price=price_t(value=1, currency='GBP'), quantity=1)) 100 """ 101 name = gxml.String('item-name') 102 description = gxml.String('item-description') 103 unit_price = gxml.Complex('unit-price', price_t) 104 quantity = gxml.Decimal('quantity') 105 item_weight = gxml.Complex('item-weight', item_weight_t, required=False) 106 merchant_item_id = gxml.String('merchant-item-id', required=False) 107 tax_table_selector = gxml.String('tax-table-selector', required=False) 108 digital_content = gxml.Complex('digital-content', digital_content_t, required=False) 109 merchant_private_item_data = gxml.Any('merchant-private-item-data', 110 save_node_and_xml=True, 111 required=False)
112
113 -class postal_area_t(gxml.Node):
114 """ 115 >>> test_node(postal_area_t(country_code = 'VU'), 116 ... ''' 117 ... <node><country-code>VU</country-code></node> 118 ... ''' 119 ... ) 120 """ 121 country_code = CountryCode('country-code') 122 postal_code_pattern = gxml.String('postal-code-pattern', required=False)
123
124 -class tax_area_t(gxml.Node):
125 world_area = PresentOrNot('world-area', required=False) 126 postal_area = gxml.Complex('postal-area', postal_area_t, required=False) 127 us_state = gxml.String('us-state-area/state', required=False) 128 us_zip_pattern = gxml.String('us-zip-area/zip-pattern', required=False) # regex: [a-zA-Z0-9_]+\*? Note the optional asterisk 129 us_country_area = gxml.String('us-country-area/country-area', values=('CONTINENTAL_48', 'FULL_50_STATES', 'ALL'), required=False) # enum('CONTINENTAL_48', 'FULL_50_STATES', 'ALL')
130
131 -class areas_t(gxml.Node):
132 """ 133 Represents a list of regions. 134 135 >>> test_node( 136 ... areas_t( 137 ... states = ['LA', 'NY'], 138 ... country_areas = ['ALL', 'CONTINENTAL_48'] 139 ... ) 140 ... , 141 ... ''' 142 ... <node> 143 ... <us-state-area> 144 ... <state>LA</state> 145 ... </us-state-area> 146 ... <us-state-area> 147 ... <state>NY</state> 148 ... </us-state-area> 149 ... <us-country-area> 150 ... <country-area>ALL</country-area> 151 ... </us-country-area> 152 ... <us-country-area> 153 ... <country-area>CONTINENTAL_48</country-area> 154 ... </us-country-area> 155 ... </node> 156 ... ''' 157 ... ) 158 """ 159 states = gxml.List('', gxml.String('us-state-area/state'), required=False) 160 zip_patterns = gxml.List('', gxml.String('us-zip-area/zip-pattern'), required=False) # regex: [a-zA-Z0-9_]+\*? Note the optional asterisk 161 country_areas = gxml.List('', gxml.String('us-country-area/country-area'), values=('CONTINENTAL_48', 'FULL_50_STATES', 'ALL'), required=False) # enum('CONTINENTAL_48', 'FULL_50_STATES', 'ALL')
162
163 -class allowed_areas_t(areas_t):
164 postal_areas = gxml.List('', gxml.Complex('postal-area', postal_area_t), required=False) 165 world_area = PresentOrNot('world-area', required=False)
166
167 -class excluded_areas_t(areas_t):
168 postal_areas = gxml.List('', gxml.Complex('postal-area', postal_area_t), required=False)
169
170 -class tax_rule_t(gxml.Node):
171 rate = gxml.Double('rate', default=0.) 172 tax_area = gxml.Complex('tax-area', tax_area_t, required=False) 173 tax_areas = gxml.List('tax-areas', gxml.Complex('', tax_area_t), required=False)
174
175 -class default_tax_rule_t(tax_rule_t):
176 shipping_taxed = gxml.Boolean('shipping-taxed', required=False)
177
178 -class alternate_tax_rule_t(tax_rule_t):
179 pass
180
181 -class default_tax_table_t(gxml.Node):
182 tax_rules = gxml.List('tax-rules', gxml.Complex('default-tax-rule', default_tax_rule_t))
183
184 -class alternate_tax_table_t(gxml.Node):
185 name = gxml.String('@name') 186 standalone = gxml.Boolean('@standalone') 187 alternate_tax_rules = gxml.List('alternate-tax-rules', gxml.Complex('alternate-tax-rule', alternate_tax_rule_t))
188
189 -class tax_tables_t(gxml.Node):
190 merchant_calculated = gxml.Boolean('@merchant-calculated', default=False) 191 default = gxml.Complex('default-tax-table', default_tax_table_t) 192 alternates = gxml.List('alternate-tax-tables', gxml.Complex('alternate-tax-table', alternate_tax_table_t), required=False)
193
194 -class merchant_calculations_t(gxml.Node):
195 merchant_calculations_url = gxml.Url('merchant-calculations-url') 196 accept_merchant_coupons = gxml.Boolean('accept-merchant-coupons', required=False) 197 accept_gift_certificates = gxml.Boolean('accept-gift-certificates', required=False)
198
199 -class shipping_option_t(gxml.Node):
200 """ 201 Represents information about shipping costs. 202 203 >>> test_node( 204 ... shipping_option_t( 205 ... name = 'Testing', 206 ... price = price_t( 207 ... currency = 'GBP', 208 ... value = 9.99, 209 ... ), 210 ... allowed_areas = allowed_areas_t( 211 ... world_area = True, 212 ... ), 213 ... excluded_areas = excluded_areas_t( 214 ... postal_areas = [postal_area_t( 215 ... country_code = 'US', 216 ... )], 217 ... ), 218 ... ) 219 ... , ''' 220 ... <node name='Testing'> 221 ... <price currency='GBP'>9.990</price> 222 ... <shipping-restrictions> 223 ... <allowed-areas> 224 ... <world-area/> 225 ... </allowed-areas> 226 ... <excluded-areas> 227 ... <postal-area> 228 ... <country-code>US</country-code> 229 ... </postal-area> 230 ... </excluded-areas> 231 ... </shipping-restrictions> 232 ... </node> 233 ... ''') 234 """ 235 name = gxml.String('@name') # Attribute, len <= 255, not-empty 236 price = gxml.Complex('price', price_t) 237 allowed_areas = gxml.Complex('shipping-restrictions/allowed-areas', allowed_areas_t, required=False) 238 excluded_areas = gxml.Complex('shipping-restrictions/excluded-areas', excluded_areas_t, required=False)
239
240 -class address_filters_t(gxml.Node):
241 allowed_areas = gxml.Complex('allowed-areas', allowed_areas_t, required=False) 242 excluded_areas = gxml.Complex('excluded-areas', excluded_areas_t, required=False) 243 allow_us_po_box = gxml.Boolean('allow-us-po-box', required=False)
244
245 -class flat_rate_shipping_t(shipping_option_t):
246 pass
247 -class merchant_calculated_shipping_t(shipping_option_t):
248 address_filters = gxml.Complex('address-filters', 249 address_filters_t, required=False)
250 251 # TODO: Add some special type of validation to: 252 # shipping_company and shipping_type fields. See: 253 # http://code.google.com/apis/checkout/developer/Google_Checkout_XML_API_Tag_Reference.html#tag_shipping-type
254 -class carrier_calculated_shipping_option_t(gxml.Node):
255 price = gxml.Complex('price', price_t) 256 shipping_company = gxml.String('shipping-company', values=('FedEx', 'UPS', 'USPS')) 257 carrier_pickup = gxml.String('carrier-pickup', values=('REGULAR_PICKUP', 258 'SPECIAL_PICKUP', 259 'DROP_OFF'), 260 default='DROP_OFF', 261 required=False) 262 shipping_type = gxml.String('shipping-type') 263 additional_fixed_charge = gxml.Complex('additional-fixed-charge', price_t, required=False) 264 additional_variable_charge_percent = gxml.Double('additional-variable-charge-percent', required=False)
265
266 -class measure_t(gxml.Node):
267 unit = gxml.String('@unit', values=('IN',), default='IN') 268 value = gxml.Decimal('@value')
269
270 -class ship_from_t(gxml.Node):
271 id = gxml.String('id') 272 city = gxml.String('city') 273 region = gxml.String('region', empty=True) 274 postal_code = gxml.Zip('postal-code') 275 country_code = CountryCode('country-code')
276
277 -class shipping_package_t(gxml.Node):
278 delivery_address_category = gxml.String('delivery-address-category', 279 values=('RESIDENTIAL', 280 'COMMERCIAL'), required=False) 281 height = gxml.Complex('height', measure_t) 282 length = gxml.Complex('length', measure_t) 283 ship_from = gxml.Complex('ship-from', ship_from_t) 284 width = gxml.Complex('width', measure_t)
285
286 -class carrier_calculated_shipping_t(gxml.Node):
287 carrier_calculated_shipping_options = gxml.List('carrier-calculated-shipping-options', 288 gxml.Complex('carrier-calculated-shipping-option', 289 carrier_calculated_shipping_option_t)) 290 shipping_packages = gxml.List('shipping-packages', 291 gxml.Complex('shipping-package', 292 shipping_package_t))
293
294 -class pickup_t(gxml.Node):
295 name = gxml.String('@name') 296 price = gxml.Complex('price', price_t)
297
298 -class shipping_methods_t(gxml.Node):
299 carrier_calculated_shippings = gxml.List('', gxml.Complex('carrier-calculated-shipping', carrier_calculated_shipping_t), required=False) # list of carrier_calculated_shipping_t 300 flat_rate_shippings = gxml.List('', gxml.Complex('flat-rate-shipping', flat_rate_shipping_t), required=False) # list of flat_rate_shipping_t 301 merchant_calculated_shippings = gxml.List('', gxml.Complex('merchant-calculated-shipping', merchant_calculated_shipping_t), required=False) # list of merchant_calculated_shipping_t 302 pickups = gxml.List('', gxml.Complex('pickup', pickup_t), required=False) # list of pickup_t
303 304 URL_PARAMETER_TYPES=( 305 'buyer-id', # A Google-assigned value that uniquely identifies a customer email address. 306 'order-id', # A Google-assigned value that uniquely identifies an order. This value is displayed in the Merchant Center for each order. If you have implemented the Notification API, you will also see this value in all Google Checkout notifications. 307 'order-subtotal', # The total cost for all of the items in the order including coupons and discounts but excluding taxes and shipping charges. 308 'order-subtotal-plus-tax', # The total cost for all of the items in the order, including taxes, coupons and discounts, but excluding shipping charges. 309 'order-subtotal-plus-shipping', # The total cost for all of the items in the order, including shipping charges, coupons and discounts, but excluding taxes. 310 'order-total', # The total cost for all of the items in the order, including taxes, shipping charges, coupons and discounts. 311 'tax-amount', # The total amount of taxes charged for an order. 312 'shipping-amount', # The shipping cost associated with an order. 313 'coupon-amount', # The total amount of all coupons factored into the order total. 314 'billing-city', # The city associated with the order's billing address. 315 'billing-region', # The U.S. state associated with the order's billing address. 316 'billing-postal-code', # The five-digit U.S. zip code associated with the order's billing address. 317 'billing-country-code', # The two-letter ISO 3166 country code associated with the order's billing address. 318 'shipping-city', # The city associated with the order's shipping address. 319 'shipping-region', # The U.S. state associated with the order's shipping address. 320 'shipping-postal-code', # The five-digit U.S. zip code associated with the order's shipping address. 321 'shipping-country-code', # The two-letter ISO 3166 country code associated with the order's shipping address.', 322 ) 323
324 -class url_parameter_t(gxml.Node):
325 name = gxml.String('@name') 326 type = gxml.String('@type', values=URL_PARAMETER_TYPES)
327
328 -class parameterized_url_t(gxml.Node):
329 url = gxml.Url('@url', required=True) 330 parameters = gxml.List('parameters', gxml.Complex('url-parameter', url_parameter_t), required=True)
331 332
333 -class rounding_policy_t(gxml.Node):
334 mode = gxml.String('mode', choices=('UP', 335 'DOWN', 336 'CEILING', 337 'FLOOR', 338 'HALF_UP', 339 'HALF_DOWN', 340 'HALF_EVEN', 341 'UNNECESSARY')) 342 rule = gxml.String('rule', choices=('PER_LINE', 343 'TOTAL'))
344
345 -class checkout_flow_support_t(gxml.Node):
346 """ 347 >>> test_node( 348 ... checkout_flow_support_t( 349 ... parameterized_urls = [ 350 ... parameterized_url_t( 351 ... url='http://google.com/', 352 ... parameters=[url_parameter_t(name='a', type='buyer-id')] 353 ... ), 354 ... parameterized_url_t( 355 ... url='http://yahoo.com/', 356 ... parameters=[url_parameter_t(name='a', type='shipping-city'), 357 ... url_parameter_t(name='b', type='tax-amount')] 358 ... ), 359 ... parameterized_url_t( 360 ... url='http://mozilla.com/', 361 ... parameters=[url_parameter_t(name='a', type='order-total'), 362 ... url_parameter_t(name='b', type='shipping-region'), 363 ... url_parameter_t(name='c', type='shipping-country-code')] 364 ... ) 365 ... ], 366 ... ) 367 ... , 368 ... ''' 369 ... <node> 370 ... <parameterized-urls> 371 ... <parameterized-url url="http://google.com/"> 372 ... <parameters> 373 ... <url-parameter name="a" type="buyer-id"/> 374 ... </parameters> 375 ... </parameterized-url> 376 ... <parameterized-url url="http://yahoo.com/"> 377 ... <parameters> 378 ... <url-parameter name="a" type="shipping-city"/> 379 ... <url-parameter name="b" type="tax-amount"/> 380 ... </parameters> 381 ... </parameterized-url> 382 ... <parameterized-url url="http://mozilla.com/"> 383 ... <parameters> 384 ... <url-parameter name="a" type="order-total"/> 385 ... <url-parameter name="b" type="shipping-region"/> 386 ... <url-parameter name="c" type="shipping-country-code"/> 387 ... </parameters> 388 ... </parameterized-url> 389 ... </parameterized-urls> 390 ... </node> 391 ... ''' 392 ... ) 393 """ 394 edit_cart_url = gxml.Url('edit-cart-url', required=False) # optional, URL 395 continue_shopping_url = gxml.Url('continue-shopping-url', required=False) # optional, URL 396 tax_tables = gxml.Complex('tax-tables', tax_tables_t, required=False) # optional, tax_tables_t 397 shipping_methods = gxml.Complex('shipping-methods', shipping_methods_t, required=False) # optional, shipping_methods_t 398 parameterized_urls = gxml.List('parameterized-urls', gxml.Complex('parameterized-url', parameterized_url_t), required=False) 399 merchant_calculations = gxml.Complex('merchant-calculations', merchant_calculations_t, required=False) # optional, merchant_calculations_t 400 request_buyer_phone_number = gxml.Boolean('request-buyer-phone-number', required=False) # optional, Boolean 401 analytics_data = gxml.String('analytics-data', required=False) 402 platform_id = gxml.Long('platform-id', required=False) 403 rounding_policy = gxml.Complex('rounding-policy', rounding_policy_t, required=False)
404
405 -class shopping_cart_t(gxml.Node):
406 expiration = gxml.Timestamp('cart-expiration/good-until-date', required=False) 407 items = gxml.List('items', gxml.Complex('item', item_t)) 408 merchant_private_data = gxml.Any('merchant-private-data', 409 save_node_and_xml=True, 410 required=False)
411
412 -class hello_t(gxml.Document):
413 """ 414 Represents a simple test that verifies that your server communicates 415 properly with Google Checkout. The fourth step of 416 the U{Getting Started with Google Checkout<http://code.google.com/apis/checkout/developer/index.html#integration_overview>} 417 section of the Developer's Guide explains how to execute this test. 418 419 >>> test_document(hello_t(), 420 ... "<hello xmlns='http://checkout.google.com/schema/2'/>" 421 ... ) 422 """ 423 tag_name='hello'
424
425 -class bye_t(gxml.Document):
426 """ 427 Represents a response that indicates that Google correctly received 428 a <hello> request. 429 430 >>> test_document( 431 ... bye_t(serial_number="7315dacf-3a2e-80d5-aa36-8345cb54c143") 432 ... , 433 ... ''' 434 ... <bye xmlns="http://checkout.google.com/schema/2" 435 ... serial-number="7315dacf-3a2e-80d5-aa36-8345cb54c143" /> 436 ... ''' 437 ... ) 438 """ 439 tag_name = 'bye' 440 serial_number = gxml.ID('@serial-number')
441
442 -class checkout_shopping_cart_t(gxml.Document):
443 tag_name = 'checkout-shopping-cart' 444 shopping_cart = gxml.Complex('shopping-cart', shopping_cart_t) 445 checkout_flow_support = gxml.Complex('checkout-flow-support/merchant-checkout-flow-support', checkout_flow_support_t) 446 request_initial_auth_details = gxml.Boolean('order-processing-support/request-initial-auth-details', required=False)
447
448 -class coupon_gift_adjustment_t(gxml.Node):
449 code = gxml.String('code') 450 calculated_amount = gxml.Complex('calculated-amount', price_t, required=False) 451 applied_amount = gxml.Complex('applied-amount', price_t) 452 message = gxml.String('message', required=False)
453
454 -class merchant_codes_t(gxml.Node):
455 gift_certificate_adjustment = gxml.List('', gxml.Complex('gift-certificate-adjustment', coupon_gift_adjustment_t)) 456 coupon_adjustment = gxml.List('', gxml.Complex('coupon-adjustment', coupon_gift_adjustment_t))
457
458 -class shipping_adjustment_t(gxml.Node):
459 shipping_name = gxml.String('shipping-name') 460 shipping_cost = gxml.Complex('shipping-cost', price_t)
461
462 -class carrier_calculated_shipping_adjustment_t(gxml.Node):
463 shipping_name = gxml.String('shipping-name') 464 shipping_cost = gxml.Complex('shipping-cost', price_t)
465 466 # Two classes below represent the single 'shipping' tag, which content 467 # depends on the context the XML Node is present. 468 # http://code.google.com/apis/checkout/developer/index.html#tag_shipping
469 -class shipping_in_order_adjustment_t(gxml.Node):
470 carrier_calculated_shipping_adjustment = gxml.Complex('carrier-calculated-shipping-adjustment', 471 carrier_calculated_shipping_adjustment_t, 472 required=False) 473 flat_rate_shipping_adjustment = gxml.Complex('flat-rate-shipping-adjustment', 474 shipping_adjustment_t, 475 required=False) 476 merchant_calculated_shipping_adjustment = gxml.Complex('merchant-calculated-shipping-adjustment', 477 shipping_adjustment_t, 478 required=False) 479 pickup_shipping_adjustment = gxml.Complex('pickup-shipping-adjustment', 480 shipping_adjustment_t, 481 required=False) 482 methods = gxml.List('', gxml.String('method/@name'))
483
484 -class shipping_in_calculate_t(gxml.Node):
485 methods = gxml.List('', gxml.String('method/@name'))
486
487 -class order_adjustment_t(gxml.Node):
488 adjustment_total = gxml.Complex('adjustment-total', price_t, required=False) 489 merchant_calculation_successful = gxml.Boolean('merchant-calculation-successful', required=False) 490 merchant_codes = gxml.Complex('merchant-codes', merchant_codes_t, required=False) 491 shipping = gxml.Complex('shipping', shipping_in_order_adjustment_t, required=False) 492 total_tax = gxml.Complex('total-tax', price_t, required=False)
493
494 -class structured_name_t(gxml.Node):
495 first_name = gxml.String('first-name') 496 last_name = gxml.String('last-name')
497
498 -class address_t(gxml.Node):
499 address1 = gxml.String('address1') 500 address2 = gxml.String('address2', required=False) 501 city = gxml.String('city') 502 company_name = gxml.String('company-name', required=False) 503 contact_name = gxml.String('contact-name', required=False) 504 country_code = gxml.String('country-code') 505 email = gxml.Email('email', required=False) 506 fax = gxml.Phone('fax', required=False, empty=True) 507 phone = gxml.Phone('phone', required=False, empty=True) 508 postal_code = gxml.Zip('postal-code') 509 region = gxml.String('region', empty=True) 510 structured_name = gxml.Complex('structured-name', 511 structured_name_t, required=False)
512
513 -class buyer_billing_address_t(address_t):
514 pass
515 -class buyer_shipping_address_t(address_t):
516 pass
517 -class billing_address_t(address_t):
518 # google docs do not say address_id is optional, but sandbox omits it.. :S bug? 519 # address_id = gxml.ID('@address-id', required=False) 520 pass
521
522 -class buyer_marketing_preferences_t(gxml.Node):
523 email_allowed = gxml.Boolean('email-allowed')
524 - def read(self, node):
525 return gxml.Node.read(self, node)
526 -class abstract_notification_t(gxml.Document):
527 tag_name = '-notification' 528 serial_number = gxml.ID('@serial-number') 529 google_order_number = gxml.ID('google-order-number') 530 timestamp = gxml.Timestamp('timestamp')
531
532 -class promotion_t(gxml.Node):
533 description = gxml.String('description', required=False, max_length=1024) 534 id = gxml.Long('id') 535 name = gxml.String('name') 536 total_amount = gxml.Complex('total-amount', price_t)
537 538 FINANCIAL_ORDER_STATE=('REVIEWING', 'CHARGEABLE', 'CHARGING', 'CHARGED', 'PAYMENT_DECLINED', 'CANCELLED', 'CANCELLED_BY_GOOGLE') 539 FULFILLMENT_ORDER_STATE=('NEW', 'PROCESSING', 'DELIVERED', 'WILL_NOT_DELIVER') 540
541 -class new_order_notification_t(abstract_notification_t):
542 tag_name = 'new-order-notification' 543 buyer_billing_address = gxml.Complex('buyer-billing-address', buyer_billing_address_t) 544 buyer_id = gxml.Long('buyer-id') 545 buyer_marketing_preferences = gxml.Complex('buyer-marketing-preferences', buyer_marketing_preferences_t) 546 buyer_shipping_address = gxml.Complex('buyer-shipping-address', buyer_shipping_address_t) 547 financial_order_state = gxml.String('financial-order-state', values=FINANCIAL_ORDER_STATE) 548 fulfillment_order_state = gxml.String('fulfillment-order-state', values=FULFILLMENT_ORDER_STATE) 549 order_adjustment = gxml.Complex('order-adjustment', order_adjustment_t) 550 order_total = gxml.Complex('order-total', price_t) 551 shopping_cart = gxml.Complex('shopping-cart', shopping_cart_t) 552 promotions = gxml.List('promotions', 553 gxml.Complex('promotion', promotion_t), 554 required=False)
555
556 -class checkout_redirect_t(gxml.Document):
557 """ 558 Try doctests: 559 >>> a = checkout_redirect_t(serial_number='blabla12345', 560 ... redirect_url='http://www.somewhere.com') 561 >>> b = gxml.Document.fromxml(a.toxml()) 562 >>> a == b 563 True 564 """ 565 tag_name = 'checkout-redirect' 566 serial_number = gxml.ID('@serial-number') 567 redirect_url = gxml.Url('redirect-url')
568
569 -class notification_acknowledgment_t(gxml.Document):
570 tag_name = 'notification-acknowledgment' 571 serial_number = gxml.ID('@serial-number')
572
573 -class order_state_change_notification_t(abstract_notification_t):
574 tag_name = 'order-state-change-notification' 575 new_fulfillment_order_state = gxml.String('new-fulfillment-order-state', values=FINANCIAL_ORDER_STATE) 576 new_financial_order_state = gxml.String('new-financial-order-state', values=FULFILLMENT_ORDER_STATE) 577 previous_financial_order_state = gxml.String('previous-financial-order-state', values=FINANCIAL_ORDER_STATE) 578 previous_fulfillment_order_state = gxml.String('previous-fulfillment-order-state', values=FULFILLMENT_ORDER_STATE) 579 reason = gxml.String('reason', required=False)
580 581 AVS_VALUES=('Y', 'P', 'A', 'N', 'U') 582 CVN_VALUES=('M', 'N', 'U', 'E') 583
584 -class risk_information_t(gxml.Node):
585 avs_response = gxml.String('avs-response', values=AVS_VALUES) 586 billing_address = gxml.Complex('billing-address', billing_address_t) 587 buyer_account_age = gxml.Integer('buyer-account-age') 588 cvn_response = gxml.String('cvn-response', values=CVN_VALUES) 589 eligible_for_protection = gxml.Boolean('eligible-for-protection') 590 ip_address = gxml.IP('ip-address') 591 partial_cc_number = gxml.String('partial-cc-number') # partial CC Number
592
593 -class risk_information_notification_t(abstract_notification_t):
594 tag_name = 'risk-information-notification' 595 risk_information = gxml.Complex('risk-information', risk_information_t)
596
597 -class abstract_order_t(gxml.Document):
598 tag_name='-order' 599 google_order_number = gxml.ID('@google-order-number')
600
601 -class charge_order_t(abstract_order_t):
602 tag_name = 'charge-order' 603 amount = gxml.Complex('amount', price_t, required=False)
604
605 -class refund_order_t(abstract_order_t):
606 tag_name = 'refund-order' 607 amount = gxml.Complex('amount', price_t, required=False) 608 comment = gxml.String('comment', max_length=140, required=False) 609 reason = gxml.String('reason', max_length=140)
610
611 -class cancel_order_t(abstract_order_t):
612 """ 613 Represents an order that should be canceled. A <cancel-order> command 614 sets the financial-order-state and the fulfillment-order-state to canceled. 615 616 >>> test_document( 617 ... cancel_order_t(google_order_number = "841171949013218", 618 ... comment = 'Buyer found a better deal.', 619 ... reason = 'Buyer cancelled the order.' 620 ... ) 621 ... , 622 ... ''' 623 ... <cancel-order xmlns="http://checkout.google.com/schema/2" google-order-number="841171949013218"> 624 ... <comment>Buyer found a better deal.</comment> 625 ... <reason>Buyer cancelled the order.</reason> 626 ... </cancel-order> 627 ... ''' 628 ... ) 629 """ 630 tag_name = 'cancel-order' 631 comment = gxml.String('comment', max_length=140, required=False) 632 reason = gxml.String('reason', max_length=140)
633
634 -class authorize_order_t(abstract_order_t):
635 tag_name = 'authorize-order'
636
637 -class process_order_t(abstract_order_t):
638 tag_name = 'process-order'
639
640 -class add_merchant_order_number_t(abstract_order_t):
641 tag_name = 'add-merchant-order-number' 642 merchant_order_number = gxml.String('merchant-order-number')
643 644 CARRIER_VALUES=('DHL', 'FedEx', 'UPS', 'USPS', 'Other') 645
646 -class tracking_data_t(gxml.Node):
647 carrier = gxml.String('carrier', values=CARRIER_VALUES) 648 tracking_number = gxml.String('tracking-number')
649
650 -class deliver_order_t(abstract_order_t):
651 tag_name='deliver-order' 652 tracking_data = gxml.Complex('tracking-data', tracking_data_t, required=False) 653 send_email = gxml.Boolean('send-email', required=False)
654
655 -class add_tracking_data_t(abstract_order_t):
656 """ 657 Represents a tag containing a request to add a shipper's tracking number 658 to an order. 659 660 >>> test_document( 661 ... add_tracking_data_t( 662 ... google_order_number = '841171949013218', 663 ... tracking_data = tracking_data_t( 664 ... carrier = 'UPS', 665 ... tracking_number = 'Z9842W69871281267' 666 ... ) 667 ... ) 668 ... , 669 ... ''' 670 ... <add-tracking-data xmlns="http://checkout.google.com/schema/2" 671 ... google-order-number="841171949013218"> 672 ... <tracking-data> 673 ... <tracking-number>Z9842W69871281267</tracking-number> 674 ... <carrier>UPS</carrier> 675 ... </tracking-data> 676 ... </add-tracking-data> 677 ... ''' 678 ... ) 679 """ 680 tag_name='add-tracking-data' 681 tracking_data = gxml.Complex('tracking-data', tracking_data_t)
682
683 -class send_buyer_message_t(abstract_order_t):
684 tag_name='send-buyer-message' 685 send_email = gxml.Boolean('send-email', required=False) 686 message = gxml.String('message')
687
688 -class archive_order_t(abstract_order_t):
689 """ 690 Represents a request to archive a particular order. You would archive 691 an order to remove it from your Merchant Center Inbox, indicating that 692 the order has been delivered. 693 694 >>> test_document(archive_order_t(google_order_number = '841171949013218'), 695 ... '''<archive-order xmlns="http://checkout.google.com/schema/2" 696 ... google-order-number="841171949013218" />''' 697 ... ) 698 """ 699 tag_name='archive-order'
700
701 -class unarchive_order_t(abstract_order_t):
702 tag_name='unarchive-order'
703
704 -class charge_amount_notification_t(abstract_notification_t):
705 """ 706 Represents information about a successful charge for an order. 707 708 >>> from datetime import datetime 709 >>> import iso8601 710 >>> test_document( 711 ... charge_amount_notification_t( 712 ... serial_number='95d44287-12b1-4722-bc56-cfaa73f4c0d1', 713 ... google_order_number = '841171949013218', 714 ... timestamp = iso8601.parse_date('2006-03-18T18:25:31.593Z'), 715 ... latest_charge_amount = price_t(currency='USD', value=2226.06), 716 ... total_charge_amount = price_t(currency='USD', value=2226.06) 717 ... ) 718 ... , 719 ... ''' 720 ... <charge-amount-notification xmlns="http://checkout.google.com/schema/2" serial-number="95d44287-12b1-4722-bc56-cfaa73f4c0d1"> 721 ... <latest-charge-amount currency="USD">2226.060</latest-charge-amount> 722 ... <google-order-number>841171949013218</google-order-number> 723 ... <total-charge-amount currency="USD">2226.060</total-charge-amount> 724 ... <timestamp>2006-03-18T18:25:31.593000+00:00</timestamp> 725 ... </charge-amount-notification> 726 ... ''' 727 ... ) 728 """ 729 tag_name='charge-amount-notification' 730 latest_charge_amount = gxml.Complex('latest-charge-amount', 731 price_t) 732 latest_promotion_charge_amount = gxml.Complex('latest-promotion-charge-amount', 733 price_t, required=False) 734 total_charge_amount = gxml.Complex('total-charge-amount', price_t)
735
736 -class refund_amount_notification_t(abstract_notification_t):
737 tag_name='refund-amount-notification' 738 latest_refund_amount = gxml.Complex('latest-refund-amount', price_t) 739 latest_promotion_refund_amount = gxml.Complex('latest-promotion-refund-amount', 740 price_t, required=False) 741 total_refund_amount = gxml.Complex('total-refund-amount', price_t)
742
743 -class chargeback_amount_notification_t(abstract_notification_t):
744 tag_name='chargeback-amount-notification' 745 latest_chargeback_amount = gxml.Complex('latest-chargeback-amount', price_t) 746 latest_promotion_chargeback_amount = gxml.Complex('latest-promotion-chargeback-amount', 747 price_t, required=False) 748 total_chargeback_amount = gxml.Complex('total-chargeback-amount', price_t)
749
750 -class authorization_amount_notification_t(abstract_notification_t):
751 tag_name='authorization-amount-notification' 752 authorization_amount = gxml.Complex('authorization-amount', price_t) 753 authorization_expiration_date = gxml.Timestamp('authorization-expiration-date') 754 avs_response = gxml.String('avs-response', values=AVS_VALUES) 755 cvn_response = gxml.String('cvn-response', values=CVN_VALUES)
756
757 -class anonymous_address_t(gxml.Node):
758 id = gxml.String('@id') 759 city = gxml.String('city') 760 region = gxml.String('region', empty=True) 761 postal_code = gxml.Zip('postal-code') 762 country_code = gxml.String('country-code')
763
764 -class merchant_code_string_t(gxml.Node):
765 code = gxml.String('@code')
766
767 -class calculate_t(gxml.Node):
768 addresses = gxml.List('addresses', 769 gxml.Complex('anonymous-address', anonymous_address_t), 770 required=False) 771 merchant_code_strings = gxml.Complex('merchant-code-strings/merchant-code-string', 772 merchant_code_string_t, 773 required=False) 774 shipping = gxml.Complex('shipping', shipping_in_calculate_t, required=False) 775 tax = gxml.Boolean('tax')
776
777 -class merchant_calculation_callback_t(gxml.Document):
778 tag_name = 'merchant-calculation-callback' 779 serial_number = gxml.ID('@serial-number') 780 buyer_id = gxml.Long('buyer-id', required=False) 781 buyer_language = gxml.LanguageCode('buyer-language') 782 calculate = gxml.Complex('calculate', calculate_t) 783 shopping_cart = gxml.Complex('shopping-cart', shopping_cart_t)
784
785 -class discount_result_t(gxml.Node):
786 valid = gxml.Boolean('valid') 787 calculated_amount = gxml.Complex('calculated-amount', price_t) 788 code = gxml.String('code') 789 message = gxml.String('message', max_length=255)
790
791 -class merchant_code_results_t(gxml.Node):
792 coupon_result = gxml.List('', gxml.Complex('coupon-result', discount_result_t)) 793 gift_certificate_result = gxml.List('', gxml.Complex('gift-certificate-result', discount_result_t))
794
795 -class result_t(gxml.Node):
796 shipping_name = gxml.String('@shipping-name') 797 address_id = gxml.String('@address-id') 798 total_tax = gxml.Complex('total-tax', price_t, required=False) 799 shipping_rate = gxml.Complex('shipping-rate', price_t, required=False) 800 shippable = gxml.Boolean('shippable', required=False) 801 merchant_code_results = gxml.Complex('merchant-code-results', 802 merchant_code_results_t, 803 required=False)
804
805 -class merchant_calculation_results_t(gxml.Document):
806 tag_name = 'merchant-calculation-results' 807 results = gxml.List('results', gxml.Complex('result', result_t))
808
809 -class request_received_t(gxml.Document):
810 tag_name = 'request-received' 811 serial_number = gxml.ID('@serial-number')
812 813 # This is custom message type which is only suitable for returning to google 814 # the 'Ok' response.
815 -class ok_t(gxml.Document):
816 tag_name = 'ok'
817
818 -class error_t(gxml.Document):
819 """ 820 Represents a response containing information about an invalid API request. 821 The information is intended to help you debug the problem causing the error. 822 823 >>> test_document( 824 ... error_t(serial_number = '3c394432-8270-411b-9239-98c2c499f87f', 825 ... error_message='Bad username and/or password for API Access.', 826 ... warning_messages = ['IP address is suspicious.', 827 ... 'MAC address is shadowed.'] 828 ... ) 829 ... , 830 ... ''' 831 ... <error xmlns="http://checkout.google.com/schema/2" serial-number="3c394432-8270-411b-9239-98c2c499f87f"> 832 ... <error-message>Bad username and/or password for API Access.</error-message> 833 ... <warning-messages> 834 ... <string>IP address is suspicious.</string> 835 ... <string>MAC address is shadowed.</string> 836 ... </warning-messages> 837 ... </error> 838 ... ''' 839 ... ) 840 """ 841 tag_name = 'error' 842 serial_number = gxml.ID('@serial-number') 843 error_message = gxml.String('error-message') 844 warning_messages = gxml.List('warning-messages', 845 gxml.String('string'), 846 required=False)
847
848 -class diagnosis_t(gxml.Document):
849 """ 850 Represents a diagnostic response to an API request. The diagnostic 851 response contains the parsed XML in your request as well as any warnings 852 generated by your request. 853 Please see the U{Validating XML Messages to Google Checkout 854 <http://code.google.com/apis/checkout/developer/index.html#validating_xml_messages>} 855 section for more information about diagnostic requests and responses. 856 """ 857 tag_name = 'diagnosis' 858 input_xml = gxml.Any('input-xml') 859 warnings = gxml.List('warnings', 860 gxml.String('string'), 861 required=False) 862 serial_number = gxml.ID('@serial-number')
863
864 -class demo_failure_t(gxml.Document):
865 """ 866 >>> test_document( 867 ... demo_failure_t(message='Demo Failure Message') 868 ... , 869 ... '''<demo-failure xmlns="http://checkout.google.com/schema/2" 870 ... message="Demo Failure Message" />''' 871 ... ) 872 """ 873 tag_name = 'demo-failure' 874 message = gxml.String('@message', max_length=25)
875
876 -class item_id_t(gxml.Node):
877 merchant_item_id = gxml.String('merchant-item-id')
878
879 -class backorder_items_t(abstract_order_t):
880 tag_name = 'backorder-items' 881 item_ids = gxml.List('item-ids', gxml.Complex('item-id', item_id_t)) 882 send_email = gxml.Boolean('send-email', required=False)
883
884 -class cancel_items_t(abstract_order_t):
885 tag_name = 'cancel-items' 886 reason = gxml.String('comment') 887 comment = gxml.String('comment') 888 item_ids = gxml.List('item-ids', gxml.Complex('item-id', item_id_t)) 889 send_email = gxml.Boolean('send-email', required=False)
890
891 -class reset_items_shipping_information_t(abstract_order_t):
892 tag_name = 'reset-items-shipping-information' 893 item_ids = gxml.List('item-ids', gxml.Complex('item-id', item_id_t)) 894 send_email = gxml.Boolean('send-email', required=False)
895
896 -class return_items_t(abstract_order_t):
897 tag_name = 'return-items' 898 item_ids = gxml.List('item-ids', gxml.Complex('item-id', item_id_t)) 899 send_email = gxml.Boolean('send-email', required=False)
900
901 -class item_shipping_information_t(gxml.Node):
902 item_id = gxml.Complex('item-id', item_id_t) 903 tracking_data_list = gxml.List('tracking-data-list', 904 gxml.Complex('tracking-data', tracking_data_t))
905
906 -class ship_items_t(abstract_order_t):
907 tag_name = 'ship-items' 908 item_shipping_information_list = gxml.List('item-shipping-information-list', 909 gxml.Complex('item-shipping-information', 910 item_shipping_information_t)) 911 send_email = gxml.Boolean('send-email')
912 913 if __name__ == "__main__":
914 - def run_doctests():
915 import doctest 916 doctest.testmod()
917 run_doctests() 918