var App_ECommerce_Checkout = {
_rateAction: 'getShippingRate',
_rateTimeout: null,
_shippingElementId: 'serviceShipping-type-element',
_paymentElementId: 'servicePayment-type-element',
_rateElementId: 'serviceShipping-rate-element',
_form: null,
_cardTipClass: 'cardCode-tip',
_shippingAjaxRequest: undefined,
_paymentSectionSelector: '#servicePayment-element fieldset dl',
_paymentIsNotApplicableId: 'paymentIsNotApplicable',
_orderTotalElementId: 'orderTotal-element',
_cartSummaryElementId: 'cartSummary',
_cartSummaryContainer: null,
_cartSummarySubtotalFields: ['subtotal', 'shippingRate', 'shippingHandling', 'tax', 'promo', 'giftCard'],
_cartSummaryTotalElementId: 'subtotal-price-container',
_options: {
noPaymentMessage: '',
isErrors: null,
orderTotal: 0,
response: {
elementsErrors: {
length: 0
}
}
},
init: function(formId, options)
{
if (!formId) {
return;
}
this._form = $('#' + formId);
this._options = $.extend({}, options);
var obj = this;
this.initTaxCloudDestinationAddress();
this._cartSummaryContainer = $('#' + this._cartSummaryElementId);
if (!$(this._cartSummaryContainer).size()) {
this._cartSummaryContainer = null;
}
var shippingElements = $('#' + this._shippingElementId + ' input[type=radio]');
if ($(shippingElements).size()) {
this._updateShippingRate();
shippingElements.change(function() {
obj._onShippingClick(this);
});
var shippingChecked = undefined;
if (1 == $(shippingElements).size()) {
shippingChecked = shippingElements.find('input');
} else {
shippingChecked = shippingElements.filter('input:checked');
}
obj._onShippingClick(shippingChecked);
this._initFedexAddressType();
this._updateFedexAddressType();
$('.shipping, #' + this._shippingElementId).find('input').bind('click', function() { obj._updateShippingRate(); });
$('[name*="[state]"], [name*="[zip]"]').change(function(){
obj._updateShippingRate();
});
}
var paymentElements = $('#' + this._paymentElementId);
if ($(paymentElements).size()) {
var cvvTip = $('.' + obj._cardTipClass);
if (!qs.constant('IS_TOUCHSCREEN')) {
$(cvvTip).tooltip({html: true, trigger: 'hover'});
} else {
$(cvvTip).tooltip({html: true, trigger: 'click'});
var hitEvent = ('ontouchstart' in document.documentElement ? 'touchstart' : 'click') + '.cvvTip';
$(document).bind(hitEvent, function (e) {
if (!$(e.target).closest('.' + obj._cardTipClass).size()) {
var tooltipElement = $('.' + obj._cardTipClass);
if ($(tooltipElement).size() && $(tooltipElement).next('.tooltip').size()) {
$(cvvTip).tooltip('hide');
}
}
});
}
paymentElements.find('input').change(function() { obj._onPaymentClick(this); });
var paymentChecked = paymentElements.find('input:checked');
obj._onPaymentClick(paymentChecked);
}
app.user.form.prototype.onAsBillingClick = obj.onAsBillingClick;
$('[name^="billing["]', this._form).each(function () {
$(this).blur(function () { obj._populateShippingInfo(obj._form); });
});
if (this._options.isErrors) {
this.displayErrorsAlert();
}
if (0 == this._options.orderTotal) {
this._hidePaymentSection();
}
},
getTaxCloudDestinationAddressType: function ()
{
var data = qs.Array.expand(Qs_Form.toObject(this._form.get(0)));
return (typeof data.shipping == 'undefined' || 'y' == data.shipping.asBilling) ? 'billing' : 'shipping';
},
initTaxCloudDestinationAddress: function ()
{
$('#' + this.getTaxCloudDestinationAddressType() + '-element').find(
'[name*=address], [name*=city], [name*=state], [name*=zip]'
).change(
_.bind(this.destinationAddressOnChange, this)
);
},
destinationAddressOnChange: function () {
console.log('destinationAddressOnChange');
if (!this.isDestinationAddressFilled()) {
return;
}
var request = Qs_Form.toObject(this._form.get(0));
request.action = 'validateTaxCloudDestinationAddress';
Qs_Form.removeElementsErrors(this._form.get(0));
qs.ajax(qs.constant('BASE_URL') + '/' + qs.constant('CURRENT_PAGE'), request).success(
_.bind(this.destinationAddressChangeOnSuccess, this)
);
},
isDestinationAddressFilled: function ()
{
var data = qs.Array.expand(Qs_Form.toObject(this._form.get(0)));
var address = _.pick(data[this.getTaxCloudDestinationAddressType()], 'address', 'city', 'state', 'zip');
for (var field in address) {
if (!address.hasOwnProperty(field)) {
continue;
}
var value = _.str.trim(address[field]);
if (!value.length) {
return false;
}
}
return true;
},
destinationAddressChangeOnSuccess: function (response) {
var fieldset = this._form.find('#fieldset-billing').get(0);
if (!response.isValid) {
if (response.formErrors && response.formErrors.length) {
Qs_Form.displayFromErrorsHtml(fieldset, response.formErrors, 'append');
}
if (response.elementsErrors && response.elementsErrors.length) {
Qs_Form.displayErrorsHtml(fieldset, response.elementsErrors);
}
}
$('#' + this._orderTotalElementId).html(response.cartSummaryHtml);
},
_hidePaymentSection: function()
{
var obj = this;
$(obj._paymentSectionSelector).hide();
$('#' + obj._paymentIsNotApplicableId).remove();
$('
- ' + obj._options.noPaymentMessage + '
').insertAfter($(obj._paymentSectionSelector + ':first'));
},
_showPaymentSection: function()
{
var obj = this;
$('#' + obj._paymentIsNotApplicableId).remove();
$(obj._paymentSectionSelector).show();
},
displayErrorsAlert: function ()
{
var message = 'Please review the comments marked in red and make appropriate corrections.';
alert(_.str.trim(message));
if (typeof this._options.response.elementsErrors.length) {
var focusKey = null;
var scrollToKey = null;
var element = null;
for (var i in this._options.response.elementsErrors) {
element = this._options.response.elementsErrors[i];
if (0 == $('#' + element.id, this._form).size()) {
/* check if it is radio button */
var radio = $('#' + element.id + '-element input[id^=' + element.id + '][type=radio]', this._form).first();
if ($(radio).size()) {
scrollToKey = element.id;
}
} else {
if ($('#' + element.id, this._form).prop('focus')) {
focusKey = element.id;
scrollToKey = element.id;
}
}
if (!scrollToKey) {
continue; /* якщо не знайшли куди скролити, то переходимо до наступного елементу */
}
if (focusKey && $('#' + focusKey + ':visible', this._form).size()) {
$('#' + focusKey, this._form).focus();
}
if (scrollToKey && $.scrollTo) {
var labelKey = scrollToKey + '-label';
var elementKey = scrollToKey + '-element';
if ($('#' + labelKey + ':visible').size()) {
$.scrollTo('#' + labelKey);
} else if ($('#' + elementKey + ':visible').size()) {
$.scrollTo('#' + elementKey);
} else {
scrollToKey = $('#' + elementKey).closest('fieldset').attr('id');
$.scrollTo('#' + scrollToKey);
}
}
break; /* якщо виконання дойшло сюди, то сторінка проскролена до потрібного елементу, перериваємо цикл */
}
}
},
_parsePrice: function(str)
{
str = '' + str;
if ('$' == str.charAt(0)) {
str = str.substr(1);
}
str = str.replace(/[, ]+/, '');
str = parseFloat(str);
if (isNaN(str)) {
str = 0.0;
}
return str
},
_ucfirst: function(str)
{
var f = str.charAt(0).toUpperCase();
return f + str.substr(1, str.length - 1);
},
_cartSummarySetPrice: function(field, value)
{
value = this._parsePrice(value);
field = this._ucfirst(field);
var container = $('.cart' + field, this._cartSummaryContainer);
var html = '$' + _.num.format(value, 2);
if ('Promo' == field || 'GiftCard' == field) {
html = '-' + html;
}
$(container).html(html);
if (value > 0) {
$(container).closest('div').removeClass('hidden');
} else {
$(container).closest('div').addClass('hidden');
}
},
_cartSummaryUpdate: function(summary)
{
if (!this._cartSummaryContainer) {
return;
}
for (var i in this._cartSummarySubtotalFields) {
var field = this._cartSummarySubtotalFields[i];
this._cartSummarySetPrice(field, summary[field]);
}
var total = this._parsePrice(summary.total);
$('#' + this._cartSummaryTotalElementId).html('$' + _.num.format(total, 2));
if (0 == total) {
this._hidePaymentSection()
} else {
this._showPaymentSection();
}
},
_initFedexAddressType: function()
{
var obj = this;
$('#serviceShipping-fedExAddressType-residential').bind('change', function() { obj._updateFedexAddressType() });
$('#serviceShipping-fedExAddressType-commercial').bind('change', function() { obj._updateFedexAddressType() });
},
_updateFedexAddressType: function()
{
var residential = $('#serviceShipping-fedExAddressType-residential');
var commercial = $('#serviceShipping-fedExAddressType-commercial');
if (residential.size() && commercial.size()) {
var ground = $('label[for="serviceShipping-fedExMethod-FEDEXGROUND"]');
var home = $('label[for="serviceShipping-fedExMethod-GROUNDHOMEDELIVERY"]');
if (residential.is(':checked')) {
ground.hide();
ground.next('br').hide();
home.next('br').show();
home.show();
if ($('input', ground).is(':checked')) {
$('input', home).prop('checked', 'checked');
}
} else if (commercial.is(':checked')) {
home.next('br').hide();
home.hide();
ground.next('br').show();
ground.show();
if ($('input', home).is(':checked')) {
$('input', ground).prop('checked', 'checked');
}
}
}
},
_populateShippingInfo: function(_form)
{
var asBilling = $('#shipping-asBilling', _form);
if ($(asBilling).is(':checked')) {
$('[name^="billing["]', this._form).each(function () {
var shippingFieldName = $(this).attr('name').replace('billing[', 'shipping[');
var shippingField = $('[name="' + shippingFieldName + '"]');
if ($(shippingField).size()) {
$(shippingField).val($(this).val());
}
});
}
},
_onShippingClick: function(element)
{
$('.shipping').closest('dd' ).hide();
if ($(element).size()) {
$('#serviceShipping-' + $(element).val() + 'Methods-element').show();
}
},
_onPaymentClick: function(element)
{
$('.payment').closest('dd').hide();
$('#servicePayment-' + $(element).val() + 'Methods-element').show();
},
_updateShippingRate: function()
{
var obj = this;
if (obj._rateTimeout) {
clearTimeout(obj._rateTimeout);
}
obj._rateTimeout = setTimeout(function() { obj._getShippingRate(); }, 300);
},
_getShippingRate: function()
{
var request = {};
$.each(this._form.serializeArray(), function(i, field) {
request[field.name] = field.value;
});
request.action = this._rateAction;
var obj = this;
if (typeof this._shippingAjaxRequest != 'undefined') {
this._shippingAjaxRequest.abort();
this._shippingAjaxRequest = undefined;
}
this._shippingAjaxRequest = qs.ajax(
qs.constant('BASE_URL') + '/' + qs.constant('CURRENT_PAGE'),
request,
{ qsDefaultCallbacks: false }
);
this._shippingAjaxRequest.done(function (response) {
qs.hideLoading();
if (!response || response.isError) {
var errorCallback = (response && response.errorCallback)
? response.errorCallback
: {fn: qs.errorCallback, args: [response]};
qs.call(errorCallback);
return this;
}
if (response && response.callbacks) {
qs.call(response.callbacks);
}
var html = '$' + parseFloat(response.total).toFixed(2);
if (response.message != '' && response.message) {
html += '' + response.message + '
';
}
$('#' + obj._rateElementId).html(html);
if (_.isObject(response.cartSummary)) {
obj._cartSummaryUpdate(response.cartSummary);
}
return this;
});
this._shippingAjaxRequest.fail(function (xhr, textStatus, errorThrown) {
qs.hideLoading();
if ('abort' == textStatus) {
return this;
}
/*if (xhr.status = 0 && xhr.statusText == 'error') {
// retry
}*/
qs.debug.debug('qs.ajax: Ajax request failed: ', textStatus, xhr);
var message = (qs.constant('DEBUG'))
? xhr.responseText
: textStatus + ' ' + errorThrown;
alert(message);
return this;
});
this._shippingAjaxRequest.always(function () {
obj._shippingAjaxRequest = undefined;
})
},
onAsBillingClick: function (asBilling, type)
{
for (var i = 0; i < this.options.addressFields.length; i++) {
var name = this.options.addressFields[i];
var selector = '#' + type + '-' + name;
if ($(asBilling).is(':checked')) {
$(selector).attr('disabled', 'disabled');
this.setElementValue(type, name, this.getElementValue(this.options.inheritedAddress, name));
} else {
if ($(selector).attr('disabled') == 'disabled') {
$(selector).removeAttr('disabled');
/*this.setElementValue(type, name, '');*/
}
}
}
if ($('#' + App_ECommerce_Checkout._shippingElementId).size()) {
App_ECommerce_Checkout._updateShippingRate();
}
return true;
}
};
var App_ECommerce_Checkout_OtherServices = {
_containerId: null,
_tooltipTimeout: 3000,
init: function(id)
{
this._containerId = id;
$('#' + this._containerId).find('input[type=checkbox]').click(function() {
var valueFieldId = $(this).attr('id') + 'Value-element' ;
var valueField = $('#' + valueFieldId);
if ($(this).is(':checked')) {
valueField.show();
} else {
valueField.hide();
}
});
},
_removeErrors: function()
{
$('#' + this._containerId).find('ul.errors').remove();
},
_addErrors: function(message, afterContainer)
{
afterContainer.after('');
},
applyDiscount: function(requestAction, element, postCallback)
{
this._removeErrors();
var obj = this;
var request = {
code: $(element).parent().children('input').val(),
action: requestAction
};
qs.ajax(qs.constant('BASE_URL') + '/' + qs.constant('CURRENT_PAGE'), request).done(function(data) {
if (!data.success) {
obj._addErrors(data.message, $(element));
} else {
var inputId = $(element).parent().children('input').attr('id');
var checkboxId = inputId.replace('Value', '');
var staticId = checkboxId + 'Static';
$('#' + checkboxId + '-label').hide();
$('#' + checkboxId + '-element').hide();
$('#' + checkboxId + '-element input[type=checkbox]').attr('checked', false);
$('#' + inputId + '-label').hide();
$('#' + inputId + '-element').hide();
$('#' + inputId + '-element input[type=text]').val('');
$('#' + staticId + '-element').html(data.elementValue).show();
if (_.isObject(data.cartSummary)) {
App_ECommerce_Checkout._cartSummaryUpdate(data.cartSummary);
}
if (_.isFunction(postCallback)) {
postCallback.call(obj, data)
}
}
}).fail(function(status) {
alert(status.responseText);
});
},
removeDiscount: function (requestAction, element, postCallback)
{
this._removeErrors();
var obj = this;
var request = {
action: requestAction
};
qs.ajax(qs.constant('BASE_URL') + '/' + qs.constant('CURRENT_PAGE'), request).done(function(data) {
if (!data.success) {
obj._addErrors(data.message, $(element));
} else {
var staticElementId = $(element).closest('dd').attr('id');
var checkboxElementId = staticElementId.replace(/Static-element$/, '-element');
$('#' + staticElementId).html('').hide();
$('#' + checkboxElementId).show();
if (_.isObject(data.cartSummary)) {
App_ECommerce_Checkout._cartSummaryUpdate(data.cartSummary);
}
if (_.isFunction(postCallback)) {
postCallback.call(obj, data)
}
}
}).fail(function(status) {
alert(status.responseText);
});
},
applyPromoCode: function(element)
{
this.applyDiscount('applyPromoCode', element);
},
removePromoCode: function(element)
{
this.removeDiscount('removePromoCode', element);
},
applyGiftCard: function(element)
{
this.applyDiscount('applyGiftCard', element);
},
removeGiftCard: function(element)
{
this.removeDiscount('removeGiftCard', element);
}
};