<commit_before>/*!
 * Module dependencies
 */

var utils = require('./utils'), //this module is not publicly available
	assert = require('assert'); 

/*!
 * Export the module
 */

module.exports = ShoppingCart;


/*
 * This module is used to create an instance of a shopping cart. The shopping
 * cart provides methods for adding items and shipping options.
 * 
 * @param {Object} GoogleCheckout A GoogleCheckout instance object.
 * @return {Object} ShoppingCart Object
 * @api public 
 * 
 */

function ShoppingCart (objGoogleCheckout) {
	var self = this;
	
	//todo: check the constructor name
	assert.ok(objGoogleCheckout, "A GoogleCheckout object is the only required argument");
	
	self.gc = objGoogleCheckout;
	self.settings = self.gc.settings;
	
	self.items = [];
	self.shipMethods = [];
};

/*
 * The URL to POST requests to. 
 */

ShoppingCart.Url = 'https://{merchantNumber}:{merchantKey}@sandbox.google.com/checkout/api/checkout/v2/merchantCheckout/Merchant/{merchantNumber}';
//ShoppingCart.Url = 'https://{merchantNumber}:{merchantKey}@checkout.google.com/api/checkout/v2/merchantCheckout/Merchant/{merchantNumber}';

/*
 * Add an item to the list of items currently in the shopping cart.
 * 
 * You may optionally base an ItemObject in place of Name. The ItemObject should
 * contain all the properties in the example listed below, with the exception of
 * the currency property. If the currency property is omitted, then the default
 * currency will be used.
 * 
 * 		ItemObject = { 
 * 			name : '', 
 * 			description : '', 
 * 			unitPrice : 1.23, 
 * 			currency : '', 
 * 			quantity : 1, 
 * 			item_id : '' 
 * 		}
 * 
 * @param {Object,String} Name 
 * @param {String} Description
 * @param {String} UnitPrice
 * @param {String} Quantity
 * @param {String} Item_id
 * @param {String} Currency
 * @return {Object} ShoppingCart
 * @api public
 */

ShoppingCart.prototype.addItem = function (name, description, unitPrice, quantity, item_id, currency) {
	var self = this;
	
	if (arguments.length === 1 && typeof(name) === 'object') {
		//TODO: Validate the item has everything google requires
		
		self.items.push(name);
	}
	else {
		self.items.push({
			name : name,
			description : description,
			unitPrice : unitPrice,
			quantity : quantity,
			item_id : item_id,
			currency : currency || self.settings.currency
		});
	}
	
	return self;
};

/*
 * Add a shipping option to the shopping cart
 * 
 * 		ShipMethodObject = {
 * 			name : '',
 * 			price : 1.23,
 * 			currency : 'USD'
 * 		}
 * 
 * @param {Object} ShippingMethodObject
 * @return {Object} ShoppingCart
 * @api public
 */

ShoppingCart.prototype.addShipMethod = function (obj) {
	var self = this;

	self.shipMethods.push(obj);

	return self;
};

/*
 * Build and post the shopping cart to Google
 * 
 * TODO:
 *  * Tax Tables
 *  * Shipping Restrictions
 * 
 * Documentation:
 * 
 * http://code.google.com/apis/checkout/developer/Google_Checkout_XML_API.html#checkout_api
 * 
 * @param {Function} Callback
 * @param {Boolean} ReturnXML If specified, callback will be called with the XML that would be supplied to Google.
 * 					The request will not be sent to Google
 */

ShoppingCart.prototype.postCart = function (callback, returnXML) {
	var self = this
		, xml
		, doc = { '?xml version="1.0" encoding="UTF-8"?' : null }
		, checkout = {}
		, shippingTag = (self.settings.merchantCalculationsShipping) 
			? 'merchant-calculated-shipping'
			: 'flat-rate-shipping'
		, merchantCheckoutFlowSupport
	
	doc['checkout-shopping-cart'] = {
		'@' : {
			'xmlns' : 'http://checkout.google.com/schema/2'
		},
		'#' : {<commit_msg>ShoppingCart: documentation<commit_after>/*!
 * Module dependencies
 */

var utils = require('./utils'), //this module is not publicly available
	assert = require('assert'); 

/*!
 * Export the module
 */

module.exports = ShoppingCart;


/*
 * The `ShoppingCart` module provides methods for adding items, adding shipping options
 * and submitting a shopping cart to Google. After submitting the shopping cart to 
 * Google, you will receive a URL to redirect your user to.
 * 
 * There is no point in calling the constructor manually. You can get an
 * instance of `ShoppingCart` like this
 * 
 * 	var gc = new GoogleCheckout(settings);
 * 	
 * 	gc.createCart(function (err, cart) {
 * 		
 * 	});
 * 
 * Here is a complete example of building a cart and pushing it to Google
 * 
 * 	var gc = new GoogleCheckout(settings);
 * 	
 * 	gc.createCart(function (err, cart) {
 * 		cart.addItem({
 * 			name : 'Crayons', 
 * 			description : '42 Assorted Crayons', 
 * 			unitPrice : 3.99, 
 * 			currency : 'USD', 
 * 			quantity : 1, 
 * 			item_id : 'CRAY42'
 * 		});
 * 		
 * 		cart.addShipMethod({
 * 			name : 'FedEx Ground',
 * 			price : 3.00,
 * 			currency : 'USD'
 * 		});
 * 		
 * 		cart.postCart(function (err, redirectUrl) {
 * 			if (err) {
 *				//deal with the error
 * 				return;
 * 			}
 * 			
 * 			console.log(redirectUrl);
 * 		});
 * 	});
 * 
 * @param {Object} GoogleCheckout A GoogleCheckout instance object.
 * @return {Object} ShoppingCart Object
 * @api public 
 * 
 */

function ShoppingCart (objGoogleCheckout) {
	var self = this;
	
	//todo: check the constructor name
	assert.ok(objGoogleCheckout, "A GoogleCheckout object is the only required argument");
	
	self.gc = objGoogleCheckout;
	self.settings = self.gc.settings;
	
	self.items = [];
	self.shipMethods = [];
};

/*
 * The URL to POST requests to. 
 */

ShoppingCart.Url = 'https://{merchantNumber}:{merchantKey}@sandbox.google.com/checkout/api/checkout/v2/merchantCheckout/Merchant/{merchantNumber}';
//ShoppingCart.Url = 'https://{merchantNumber}:{merchantKey}@checkout.google.com/api/checkout/v2/merchantCheckout/Merchant/{merchantNumber}';

/*
 * Add an item to the list of items currently in the shopping cart.
 * 
 * You may optionally base an ItemObject in place of Name. The ItemObject should
 * contain all the properties in the example listed below, with the exception of
 * the currency property. If the currency property is omitted, then the default
 * currency will be used.
 * 
 * 		ItemObject = { 
 * 			name : '', 
 * 			description : '', 
 * 			unitPrice : 1.23, 
 * 			currency : '', 
 * 			quantity : 1, 
 * 			item_id : '' 
 * 		}
 * 
 * @param {Object,String} Name 
 * @param {String} Description
 * @param {String} UnitPrice
 * @param {String} Quantity
 * @param {String} Item_id
 * @param {String} Currency
 * @return {Object} ShoppingCart
 * @api public
 */

ShoppingCart.prototype.addItem = function (name, description, unitPrice, quantity, item_id, currency) {
	var self = this;
	
	if (arguments.length === 1 && typeof(name) === 'object') {
		//TODO: Validate the item has everything google requires
		
		self.items.push(name);
	}
	else {
		self.items.push({
			name : name,
			description : description,
			unitPrice : unitPrice,
			quantity : quantity,
			item_id : item_id,
			currency : currency || self.settings.currency
		});
	}
	
	return self;
};

/*
 * Add a shipping option to the shopping cart
 * 
 * 		ShipMethodObject = {
 * 			name : '',
 * 			price : 1.23,
 * 			currency : 'USD'
 * 		}
 * 
 * @param {Object} ShippingMethodObject
 * @return {Object} ShoppingCart
 * @api public
 */

ShoppingCart.prototype.addShipMethod = function (obj) {
	var self = this;

	self.shipMethods.push(obj);

	return self;
};

/*
 * Build and post the shopping cart to Google
 * 
 * TODO
 *  * Tax Tables
 *  * Shipping Restrictions
 * 
 * Documentation
 * 
 * http://code.google.com/apis/checkout/developer/Google_Checkout_XML_API.html#checkout_api
 * 
 * @param {Function} Callback
 * @param {Boolean} ReturnXML If specified, callback will be called with the XML that would be supplied to Google.
 * 					The request will not be sent to Google
 */

ShoppingCart.prototype.postCart = function (callback, returnXML) {
	var self = this
		, xml
		, doc = { '?xml version="1.0" encoding="UTF-8"?' : null }
		, checkout = {}
		, shippingTag = (self.settings.merchantCalculationsShipping) 
			? 'merchant-calculated-shipping'
			: 'flat-rate-shipping'
		, merchantCheckoutFlowSupport
	
	doc['checkout-shopping-cart'] = {
		'@' : {
			'xmlns' : 'http://checkout.google.com/schema/2'
		},
		'#' : {
{'fraction_non_alphanumeric': 0.128977203462148, 'fraction_numerical': 0.004754358161648178, 'mean_word_length': 3.2863113897596654, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 2, '>': 3, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 6}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '73291', 'n_tokens_mistral': 2901, 'n_tokens_neox': 2644, 'n_words': 727}