/*
this library is designed to receive,
maintain and transfer a punchout session
through punchout2go.
*/
var po2goExt_enabled = true; //False if you don't have the file.
/**
* used to test we can access the cookies.
* @return bool
*/
function cookieTest ()
{
document.cookie = "__test";
if (document.cookie.length >= 1 &&
document.cookie.indexOf("__test") > -1){
return true;
}
return false;
}
/**
* Po2go object.
* Must be initialized.
*
* @param p
* @constructor
*/
var Po2go = function (p) {
// extension object for customizations
this.extension = p.extension ? p.extension : 0;
// default po2go connection information
this.gateway = p.gateway ? p.gateway : 'connect.punchout2go.com';
if (p.secure !== undefined) {
this.secure = p.secure;
} else this.secure = 1;
this.transfer_url = p.transfer_url ? p.transfer_url : '/gateway/link/punchin/id/';
this.return_url = p.return_url ? p.return_url : '';
// catalog/session options
this.account = p.account ? p.account : ''; // customer apikey
this.catalog = p.catalog ? p.catalog : ''; // catalog key
this.session_id = p.session_id ? p.session_id : ''; // current session id
// use control options
this.punchout_only = parseInt(p.punchout_only ? p.punchout_only : 0);
this.punchout_only_text = p.punchout_only_text ? p.punchout_only_text : 'This site must be accessed through a valid PunchOut Session.';
this.skip_cookie_test = p.skip_cookie_test ? p.skip_cookie_test : true; // set to false to ALWAYS require cookies regardless of punchout.
this.default_unspsc = p.default_unspsc ? p.default_unspsc : '';
this.default_uom = p.default_uom ? p.default_uom : '';
// session cookie options?
this.cookie_lifetime = p.cookie_lifetime ? p.cookie_lifetime : 0; // session
this.cookie_domain = p.cookie_domain ? p.cookie_domain : ''; // uses current
this.cookie_path = p.cookie_path ? p.cookie_path : '/';
this.cookie_name = p.cookie_name ? p.cookie_name : 'pos_id';
this.query_param = p.query_param ? p.query_param : 'pos_id';
this.cookie_message = p.cookie_message ? p.cookie_message : 'Cookies must be permitted to access this website.<br>In order to allow cookies, please <a id="cookieLaunch">Click Here</a>.';
this.cookie_message_ie = p.cookie_message_ie ? p.cookie_message_ie : 'Cookies are required to maintain your session. You many need to set this site as a TRUSTED SITE. If you would like to view this site in a new window, please <a id="cookieLaunch">Click Here</a>.';
this.logging = p.logging ? p.logging : 0;
this.confirm_transfer = p.confirm_transfer ? p.confirm_transfer : 0;
// the cart.
this.cart = {
// standard data
edit_mode:0,
total:0,
currency:'USD',
// items
items:[],
// other non-standard values
discount:0,
discount_title:'',
shipping:0,
shipping_method:'',
tax:0,
tax_description:''
};
}
/**
* This is a prototype for the Po2go object. It contains static information (e.g., methods).
*/
Po2go.prototype = {
/**
* identifies the how the Po2go object is loaded
* 0 = not a punchout
* 1 = punchout ready
* 2 = remote start
* -1 = punchout only locked
* -2 = cookies blocked
*/
status : 0,
// start up stuff to be run every time a page loads.
init : function ()
{
// check for a cookie setup instruction. if true, break out of init.
// cookie setup is done in front of any other logic.
if (this.checkCookieSetup()) {
return;
}
// run the preInit
this._preInit();
// cookies are required. check before bothering with anything else.
if (this.skip_cookie_test == true
|| cookieTest()) {
// load the session
if (this.loadSession()) {
this.status = 1;
} else {
// punchout session is not loaded.
if (this.punchout_only) {
// lock out the session
this.punchoutOnlyLockout(); //Redirect somewhere.
this.status = -1;
this._cleanUp(); // cleanup anything that might be left over.
}
}
} else {
// this means cookies are not working
this.cookieMessage();
this.status = -2;
}
this._postInit();
},
// remote start..
startSession : function ()
{
this._postInit();
},
/**
* checks for cookie setup param and launches
* extra setup modals. possibly no longer used.
*
* @return {Boolean}
*/
checkCookieSetup : function ()
{
var csetup = jQuery.url().param('csetup');
if (typeof csetup == 'string'
&& csetup != '') {
this.status = -2;
switch (csetup) {
case "step1" :
this.cookieSetup1();
return true;
case "step2" :
this.cookieSetup2();
return true;
}
}
return false;
},
/**
* test for extension object and method within that object
*
* @param method
* @return {Boolean}
*/
hasExtension : function (method)
{
if (typeof this.extension == 'object') {
if (typeof this.extension[method] == 'function') {
return true;
}
}
return false;
},
/**
* called before init begins
*
* @private
*/
_preInit : function ()
{
if (this.hasExtension('_preInit')) {
this.extension._preInit(this);
}
},
/**
* called after init has completed
*
* @private
*/
_postInit : function ()
{
if (this.hasExtension('_postInit')) {
this.extension._postInit(this);
}
if (this.status == 1) {
jQuery('body').addClass('punchout');
}
},
/**
* called when closing transferring or navigating away
* clean up must return TRUE to automatically transfer.
* return false if you need to wait for something else
* to happen then trigger transfer manually.
*
* @return {*}
* @private
*/
_cleanUp : function ()
{
this.log('_cleanUp()');
if (this.hasExtension('_cleanUp')) {
this.log('extension._cleanUp()');
if (!this.extension._cleanUp(this)) {
return false;
}
}
this.deleteCookie(this.cookie_name);
this.deleteCookie('return_url');
return true;
},
/**
* Load the session. First check the query string for the pos_id,
* if not found, check the cookie.
* @returns {boolean} True if successful, False if this.cookie_name fails to be found
*/
loadSession : function ()
{
if (!this.session_id) {
//Check the query string
var session_id = jQuery.url().param(this.query_param);
var return_url = jQuery.url().param('return_url');
if (!session_id) {
//Not in query string. Check the cookie.
session_id = this.getCookie(this.cookie_name);
return_url = this.getCookie('return_url');
}
if (session_id){
//Found it somewhere. Save it.
this.setSessionId(session_id);
if (return_url) this.setReturnUrl(return_url);
return true;
}
//Never found it.
return false;
}
return true;
},
/**
* validates that the session cookie is readable.
* if it is not, then we probably are unable to read cookies
*
* @return {Boolean}
*/
checkSession : function ()
{
return (this.getCookie(this.cookie_name) == this.session_id);
},
/**
* Set the session attribute, then set the cookie.
*
* @param session_id
*/
setSessionId : function (session_id)
{
this.session_id = session_id;
this.setCookie(this.cookie_name, this.session_id);
},
/**
* Set the session attribute, then set the cookie.
*
* @param session_id
*/
setReturnUrl : function (return_url)
{
this.return_url = return_url;
this.setCookie('return_url', this.return_url);
},
/**
* Add an Item to the Cart
* @param item - an array, defined as:
item {
"quantity": "" ,
"supplierid": "",
"supplierauxid": "",
"unitprice": "",
"totalprice": "",
"currency": "USD",
"description": "", //The name
"language": "en",
"classification": "",
"classdomain": "",
"uom": "EA",
//Non-Standard
discount_percent: 0,
total_discount_amount: 0,
tax_percent: 0,
total_tax_amount: 0
}
**/
addItemToCart : function (item)
{
// price format clean up done with _prepare
// maybe some login with default values
// not entirely sure this is legit.
this.cart.items[this.cart.items.length] = item;
},
addItemsToCart : function(items)
{
jQuery(items).each(function (index,item) {
POSession.addItemToCart(item);
});
},
collectAndTransfer : function (selector)
{
Basic.Modal.show('Collecting items..');
jQuery(selector).each(jQuery.proxy(this.collectItem,this));
if (this.cart.items.length == 0) {
Basic.Modal.show('no items were added.');
return;
}
return this.transferCart();
},
collectItem : function (idx,elm) {
var data_string = jQuery(elm).html();
var item = eval('('+ data_string +')');
this.addItemToCart(item);
},
// external submit use
transferCart : function ()
{
this.log('transferCart()');
Basic.Modal.show('Preparing transfer..');
// somebody could override this to inject some
// additional logic.
//for(var i = 0; i < this.cart.items.length; i++){
// var fixed = this.cart.items[i].totalprice.replace(",", ""); //USD only
// this.cart.total += Number(fixed);
//}
this._prepareCart();
// run clean up.
if (this._cleanUp()) {
this._transferCart(); // transfer will cause the browser to navigate aways.
}
},
/**
* cancels the current punchout session; redirects/returns user to to the return_url
* @return {*}
*/
cancel : function ()
{
var returnURL = this.getTransferAction() + "?redirect=1";
window.location = returnURL;
},
/**
* normalize and prepare cart data.
*
* @private
*/
_prepareCart : function ()
{
this.log('_prepareCart()');
this.cart.tax = this._cleanPrice(this.cart.tax);
this.cart.discount = this._cleanPrice(this.cart.discount);
this.cart.shipping = this._cleanPrice(this.cart.shipping);
this.cart.total = this._cleanPrice(this.cart.total);
for(var i = 0; i < this.cart.items.length; i++){
this.cart.items[i].unitprice = this._cleanPrice(this.cart.items[i].unitprice);
this.cart.items[i].totalprice = this._cleanPrice(this.cart.items[i].totalprice);
this.cart.items[i].total_discount_amount = this._cleanPrice(this.cart.items[i].total_discount_amount);
this.cart.items[i].total_tax_amount = this._cleanPrice(this.cart.items[i].total_tax_amount);
this.cart.items[i].description = this._cleanDescription(this.cart.items[i].description);
}
},
/**
* clean description string, removes HTML entity encoding
*
* @param description
* @return {*}
* @private
*/
_cleanDescription : function(description){
var tmpTextArea = document.createElement("textarea");
tmpTextArea.innerHTML = description;
return tmpTextArea.value;
},
/**
* clean price string
*
* @param price
* @return {*}
* @private
*/
_cleanPrice : function (price)
{
if (typeof(price) === "string") {
price = price.replace("$", ""); // remove any currency ids
price = price.replace(",", ""); // remove "," from price string - not currency safe.
}
// price = price.replace(',',"");
return price;
},
/**
* actual building of the cart form and transferring the data.
*
* @private
*/
_transferCart : function ()
{
this.log('_transferCart()');
if (self.name == 'external_punchout'
&& window.opener) {
window.opener.jQuery('body').append("<form action='"+ this.getTransferAction() +"' method=POST id='transferCartForm'></form>");
window.opener.jQuery('#transferCartForm').append("<input type='hidden' name='apikey' value='"+ this.account +"' />");
window.opener.jQuery('#transferCartForm').append("<input type='hidden' name='version' value='1.0' />");
window.opener.jQuery('#transferCartForm').append("<input type='hidden' name='params' value='"+ this.getSerializedCart() +"' />");
window.opener.jQuery('#transferCartForm').submit();
self.close();
} else {
this.log('standard output.');
jQuery('body').append("<form action='"+ this.getTransferAction() +"' method=POST id='transferCartForm'></form>");
jQuery('#transferCartForm').append("<input type='hidden' name='apikey' value='"+ this.account +"' />");
jQuery('#transferCartForm').append("<input type='hidden' name='version' value='1.0' />");
jQuery('#transferCartForm').append("<input type='hidden' name='params' value='"+ this.getSerializedCart() +"' />");
this.log('form completed.');
if (this.confirm_transfer) {
if (self.confirm(this.confirm_transfer)) {
jQuery('#transferCartForm').submit();
} else {
jQuery('#transferCartForm').append("<input type='submit' name='submit' value='Transfer Items' />");
}
} else {
jQuery('#transferCartForm').submit();
}
}
},
/**
* get the required serialized cart
*
* @return {*}
*/
getSerializedCart : function ()
{
this.log('getSerializedCart()');
var cartString = '{"body":'+ this.getCartAsJson() +'}';
cartString = cartString.replace("$", "");
this.log('string // pre-b64 '+ cartString);
return Base64.encode(cartString);
},
/**
* get the json string
*
* @return {*}
*/
getCartAsJson : function ()
{
return JSON.stringify(this.cart);
},
/**
* get the url where orders should be sent back to
*
* @return {String}
*/
getTransferAction : function ()
{
var returnURL = (this.secure ? 'https://' : 'http://') + this.gateway + this.transfer_url + this.session_id;
if (this.return_url != '') {
//return this.return_url;
returnURL = this.return_url;
}
//return (this.secure ? 'https://' : 'http://') + this.gateway + this.transfer_url + this.session_id;
return returnURL;
},
/**
*
* @return {*}
*/
getInstance : function()
{
return this;
},
/**
* basic debugging info sent out to a log screen
*/
debug : function ()
{
if (this.logging == 0) {
this.logging = 1; // turn logging on
}
this.log('Session ID :'+ this.session_id);
this.log('Account : '+ this.account);
this.log('Catalog : '+ this.catalog);
this.log('POST : '+ this.getTransferAction());
this.log('Cart : '+ this.getCartAsJson());
},
/**
* write out to a log screen.
*
* @param line
*/
log : function (line)
{
if (this.logging != 0) {
if (this.logging == 'console') {
if (console) {
console.log(line);
}
} else {
if (jQuery('#logwindow').length == 0) {
jQuery('body').append('<div id="logwindow" style="top:0px;left:0px;position:absolute;width:20px;height:20px;overflow:hidden;border:1px solid black;background-color:gray;color:#adff2f;padding:10px;line-height:1.2;font-family:courier;font-size:10px;z-index:99999999"></div>');
jQuery('#logwindow').bind('click',function () {
if (jQuery('#logwindow').hasClass('open')) {
jQuery('#logwindow').width(20);
jQuery('#logwindow').height(20);
jQuery('#logwindow').css('overflow','hidden');
jQuery('#logwindow').removeClass('open')
} else {
var size = Basic.Placer.getWindowSize();
jQuery('#logwindow').width((size.width/2 > 400) ? size.width/2 : 400);
jQuery('#logwindow').height((size.height/2 > 300) ? size.height/2 : 300);
jQuery('#logwindow').css('overflow','auto');
jQuery('#logwindow').addClass('open')
}
});
}
jQuery('#logwindow').append('<div>'+ line +'</div>');
}
}
},
punchoutOnlyLockout : function ()
{
if (typeof this.punchout_only_text == 'object') {
Basic.Modal.open(this.punchout_only_text.url);
} else {
Basic.Modal.show('');
Basic.Modal.updateContent(this.punchout_only_text);
}
jQuery('.basicModalClose').hide();
},
browserIsIe : function ()
{
if (navigator.userAgent.indexOf('MSIE') > 0) {
return true;
}
return false;
},
cookieMessage : function ()
{
if (this.browserIsIe()) {
if (typeof this.cookie_message_ie == 'object') {
Basic.Modal.open(this.cookie_message_ie.url);
} else {
Basic.Modal.show('');
Basic.Modal.updateContent(this.cookie_message_ie);
jQuery("a#cookieLaunch").bind('click',jQuery.proxy(this.cookieAccept,this));
}
} else {
if (typeof this.cookie_message == 'object') {
Basic.Modal.open(this.cookie_message.url);
} else {
Basic.Modal.show('');
Basic.Modal.updateContent(this.cookie_message);
jQuery("a#cookieLaunch").bind('click',jQuery.proxy(this.cookieAccept,this));
}
}
jQuery('.basicModalClose').remove();
},
cookieSetup1 : function ()
{
Basic.Modal.show('');
if (this.loadSession()) {
/*
if (this.checkSession()) {
Basic.Modal.updateContent('Session cookies should now be enabled.');
if (opener) {
opener.location.reload();
}
if (self.name == 'cookieaccept') {
self.close();
}
return;
}
*/
}
Basic.Modal.updateContent('This site requires cookies to maintain your session.<br>' +
'If cookies are enabled, they may be blocked by your browser.<br>' +
'<a href="?'+ this.query_param +'='+ jQuery.url().param(this.query_param) +'&csetup=step2">Click here</a> to ' +
'launch the step2 accepting the session cookies.');
jQuery('.basicModalClose').remove();
},
/**
* set a cookie
*/
setCookie : function (name, value, args)
{
var info = [];
if (typeof args == 'undefined') {
info = { path: this.cookie_path }
} else {
info = args
}
jQuery.cookie(name, value, info);
},
/**
* read a cookie
*/
getCookie : function (name)
{
return jQuery.cookie(name);
},
/**
* delete a cookie
*/
deleteCookie : function (name)
{
return jQuery.cookie(name, null, { expires: -1 , path : this.cookie_path });
},
cookieSetup2 : function ()
{
Basic.Modal.show('');
if (this.loadSession()) {
if (opener) {
opener.location.reload();
}
Basic.Modal.updateContent('Your session cookies should now be accepted.');
setTimeout(function () {
self.close()
},5000);
}
jQuery('.basicModalClose').remove();
},
cookieAccept : function ()
{
this.setCookie(this.cookie_name, this.session_id);
if (this.setCookie(this.cookie_name) != this.session_id) {
if (this.browserIsIe()) {
this.cookieSetIE();
} else {
this.cookieSetWindow();
}
} else {
Basic.Modal.show('');
Basic.Modal.updateContent('If this window does not automatically refresh, please <a href="'+ self.location.href +'">click here</a>.');
self.location.reload();
}
},
cookieSetIE : function ()
{
var windowSize = Basic.Placer.getWindowSize();
var w = windowSize.width;
var h = windowSize.height;
var l = (screen.width - w)/2;
var t = (screen.height - h)/2;
var args = 'resizable=1,menubar=0,location=0,scrollbars=1,status=0,toolbar=0';
window.external_punchout = window.open(self.location.href,'external_punchout','width='+ w +',height='+ h +',top='+ t +',left='+ l +','+ args);
Basic.Modal.show('');
Basic.Modal.updateContent('Please leave this window open.');
},
cookieSetWindow : function ()
{
var w = 10;
var h = 10;
var args = 'resizable=0,menubar=0,location=0,scrollbars=0,status=0,toolbar=0';
window.cookieaccept = window.open(self.location.href,'cookieaccept','width='+ w +',height='+ h +',top='+ w +',left='+ h +','+ args);
Basic.Modal.show('');
Basic.Modal.updateContent('Please wait...');
cookieaccept.onload = function () {
self.focus();
Basic.Modal.updateContent('If this window does not automatically refresh, please <a href="'+ self.location.href +'">click here</a>.');
window.cookieaccept.close();
self.location.reload();
}
setTimeout(function () {
Basic.Modal.updateContent('If this window does not automatically refresh, please <a href="'+ self.location.href +'">click here</a>.');
window.cookieaccept.close();
},5000);
}
} //End prototype