Updating shipping/tax info based on address
This commit is contained in:
parent
0f69d4fdf0
commit
9a827affc4
2 changed files with 163 additions and 52 deletions
|
|
@ -794,6 +794,57 @@ sub updateFromForm {
|
||||||
|
|
||||||
#-------------------------------------------------------------------
|
#-------------------------------------------------------------------
|
||||||
|
|
||||||
|
=head2 www_ajaxPrices
|
||||||
|
|
||||||
|
Input: shippingId (an addressId)
|
||||||
|
billingId (an addressId)
|
||||||
|
|
||||||
|
Output: {
|
||||||
|
tax : 1.25,
|
||||||
|
subtotal : 12.00,
|
||||||
|
shipping : {
|
||||||
|
slfjaldjfalfja: {
|
||||||
|
label : 'USPS',
|
||||||
|
price : 12.50,
|
||||||
|
hasPrice : 1 || 0
|
||||||
|
},
|
||||||
|
{ ... },
|
||||||
|
{ ... }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Takes an addressId and returns JSON shipping options for it, in the form .
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub www_ajaxPrices {
|
||||||
|
my $self = shift;
|
||||||
|
my $session = $self->session;
|
||||||
|
my $form = $session->form;
|
||||||
|
my $billing = $form->get('billingId');
|
||||||
|
my $shipping = $form->get('shippingId');
|
||||||
|
my $response = {
|
||||||
|
subtotal => $self->calculateSubtotal(),
|
||||||
|
|
||||||
|
tax => eval {
|
||||||
|
my $addr = $shipping || $billing or die;
|
||||||
|
$self->update({ shippingAddressId => $addr });
|
||||||
|
$self->calculateTaxes();
|
||||||
|
} || 0,
|
||||||
|
|
||||||
|
shipping => eval {
|
||||||
|
die unless $shipping;
|
||||||
|
$self->update({ shippingAddressId => $shipping });
|
||||||
|
my $ship = WebGUI::Shop::Ship->new($self->session);
|
||||||
|
$ship->getOptions($self);
|
||||||
|
} || [],
|
||||||
|
};
|
||||||
|
$session->http->setMimeType('text/plain');
|
||||||
|
return JSON->new->encode($response);
|
||||||
|
}
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------
|
||||||
|
|
||||||
=head2 www_continueShopping ( )
|
=head2 www_continueShopping ( )
|
||||||
|
|
||||||
Update the cart and the return the user back to the asset.
|
Update the cart and the return the user back to the asset.
|
||||||
|
|
@ -1160,6 +1211,9 @@ sub www_view {
|
||||||
my $yui = $url->extras('/yui/build');
|
my $yui = $url->extras('/yui/build');
|
||||||
$style->setScript("$yui/yahoo/yahoo-min.js");
|
$style->setScript("$yui/yahoo/yahoo-min.js");
|
||||||
$style->setScript("$yui/json/json-min.js");
|
$style->setScript("$yui/json/json-min.js");
|
||||||
|
$style->setScript("$yui/event/event-min.js");
|
||||||
|
$style->setScript("$yui/connection/connection-min.js");
|
||||||
|
$style->setScript($url->extras('underscore/underscore-min.js'));
|
||||||
$style->setScript($url->extras('shop/cart.js'), undef, 1);
|
$style->setScript($url->extras('shop/cart.js'), undef, 1);
|
||||||
return $session->style->userStyle($template->process(\%var));
|
return $session->style->userStyle($template->process(\%var));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,62 +1,120 @@
|
||||||
/*global window, document, YAHOO */
|
/*global _, window, document, YAHOO */
|
||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
var $event = YAHOO.util.Event,
|
var $event = YAHOO.util.Event,
|
||||||
$connect = YAHOO.util.Connect,
|
$connect = YAHOO.util.Connect,
|
||||||
$json = YAHOO.lang.JSON,
|
$json = YAHOO.lang.JSON,
|
||||||
|
prices = null,
|
||||||
addressCache = {},
|
addressCache = {},
|
||||||
elements = {
|
elements = {
|
||||||
dropdowns: {
|
shipper : 'shipperId_formId',
|
||||||
billing: 'billingAddressId_formId',
|
tax : 'taxWrap',
|
||||||
|
total : 'totalPriceWrap',
|
||||||
|
credit : {
|
||||||
|
available : 'inShopCreditAvailableWrap',
|
||||||
|
used : 'inShopCreditDeductionWrap'
|
||||||
|
},
|
||||||
|
dropdowns : {
|
||||||
|
billing : 'billingAddressId_formId',
|
||||||
shipping: 'shippingAddressId_formId'
|
shipping: 'shippingAddressId_formId'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
addressParts = [
|
addressParts = [
|
||||||
'label', 'firstName', 'lastName', 'organization', 'address1',
|
'label', 'firstName', 'lastName', 'organization', 'address1',
|
||||||
'address2', 'address3', 'city', 'state', 'code', 'country',
|
'address2', 'address3', 'city', 'state', 'code', 'country',
|
||||||
'phoneNumber', 'email'
|
'phoneNumber', 'email'
|
||||||
];
|
];
|
||||||
|
|
||||||
function omap(o, fn) {
|
function formatCurrency(n) {
|
||||||
var r = [], k;
|
return parseFloat(n.toString()).toFixed(2);
|
||||||
for (k in o) {
|
|
||||||
if (o.hasOwnProperty(k)) {
|
|
||||||
r.push(fn.call(o, k, o[k]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
function oeach(o, fn) {
|
|
||||||
omap(o, fn);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function addAddressKind(name) {
|
function addAddressKind(name) {
|
||||||
var i, key, obj = elements[name] = {};
|
var obj = elements[name] = {};
|
||||||
for (i = 0; i < addressParts.length; i += 1) {
|
_.each(addressParts, function (key) {
|
||||||
key = addressParts[i];
|
|
||||||
obj[key] = name + '_' + key + '_formId';
|
obj[key] = name + '_' + key + '_formId';
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDomElements(o) {
|
function getDomElements(o) {
|
||||||
oeach(o, function (k, v) {
|
_.each(o, function (v, k) {
|
||||||
if (typeof v === 'object') {
|
if (typeof v === 'object') {
|
||||||
getDomElements(v);
|
getDomElements(v);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this[k] = document.getElementById(v);
|
o[k] = document.getElementById(v);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function sameChange() {
|
function sameChange() {
|
||||||
var d = elements.same.checked;
|
var d = elements.same.checked;
|
||||||
oeach(elements.shipping, function (k, v) {
|
_.each(elements.shipping, function (v, k) {
|
||||||
v.disabled = d;
|
v.disabled = d;
|
||||||
});
|
});
|
||||||
elements.dropdowns.shipping.disabled = d;
|
elements.dropdowns.shipping.disabled = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateSummary() {
|
||||||
|
var shipping = prices.shipping[elements.shipper.value],
|
||||||
|
shipPrice = (shipping ?
|
||||||
|
(shipping.hasPrice ?
|
||||||
|
parseFloat(shipping.price) :
|
||||||
|
0)
|
||||||
|
: 0),
|
||||||
|
tax = parseFloat(prices.tax),
|
||||||
|
subtotal = parseFloat(prices.subtotal),
|
||||||
|
beforeCredit = tax + subtotal + shipPrice,
|
||||||
|
creditAvail = parseFloat(elements.credit.available.innerHTML),
|
||||||
|
creditUsed = Math.min(beforeCredit, creditAvail),
|
||||||
|
afterCredit = beforeCredit - creditUsed;
|
||||||
|
|
||||||
|
elements.credit.used.innerHTML = formatCurrency(creditUsed);
|
||||||
|
elements.total.innerHTML = formatCurrency(afterCredit);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updatePrices() {
|
||||||
|
var selectedShipper = elements.shipper.value,
|
||||||
|
shipping = elements.dropdowns.shipping.value,
|
||||||
|
billing = elements.dropdowns.billing.value,
|
||||||
|
shipper = elements.shipper,
|
||||||
|
url = window.location.pathname +
|
||||||
|
'?shop=cart;method=ajaxPrices;' +
|
||||||
|
( shipping === 'new_address' ?
|
||||||
|
'' : 'shippingId=' + shipping) +
|
||||||
|
( billing === 'new_address' ?
|
||||||
|
'' : 'billingId=' + billing);
|
||||||
|
cb = {
|
||||||
|
success: function (o) {
|
||||||
|
var response = $json.parse(o.responseText);
|
||||||
|
if (response.error) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
prices = response;
|
||||||
|
elements.tax.innerHTML = formatCurrency(response.tax);
|
||||||
|
_(shipper.options)
|
||||||
|
.chain()
|
||||||
|
.map(_.identity)
|
||||||
|
.each(function (o) {
|
||||||
|
if (o.value) {
|
||||||
|
o.parentNode.removeChild(o);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
_.each(response.shipping, function (o, id) {
|
||||||
|
var opt = document.createElement('option'),
|
||||||
|
label = o.label;
|
||||||
|
if (o.hasPrice) {
|
||||||
|
label += ' (' + formatCurrency(o.price) + ')';
|
||||||
|
}
|
||||||
|
opt.innerHTML = label;
|
||||||
|
opt.value = id;
|
||||||
|
shipper.appendChild(opt);
|
||||||
|
});
|
||||||
|
shipper.value = selectedShipper;
|
||||||
|
calculateSummary();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
$connect.asyncRequest('GET', url, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateAddressDropdowns(o) {
|
function updateAddressDropdowns(o) {
|
||||||
|
|
@ -64,24 +122,22 @@
|
||||||
id = o.responseText;
|
id = o.responseText;
|
||||||
|
|
||||||
function updateOne(dropdown) {
|
function updateOne(dropdown) {
|
||||||
var options = dropdown.options, i, opt;
|
var opt = _.detect(dropdown.options, function (o) {
|
||||||
for (i = 0; i < options.length; i += 1) {
|
return o.text === label;
|
||||||
opt = options[i];
|
});
|
||||||
if (opt.text === label) {
|
|
||||||
opt.value = id;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
opt = document.createElement('option');
|
if (!opt) {
|
||||||
|
opt = document.createElement('option');
|
||||||
|
opt.text = label;
|
||||||
|
dropdown.appendChild(opt);
|
||||||
|
}
|
||||||
opt.value = id;
|
opt.value = id;
|
||||||
opt.text = label;
|
|
||||||
dropdown.appendChild(opt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updateOne(elements.dropdowns.billing);
|
updateOne(elements.dropdowns.billing);
|
||||||
updateOne(elements.dropdowns.shipping);
|
updateOne(elements.dropdowns.shipping);
|
||||||
elements.dropdowns[o.argument.name].value = id;
|
elements.dropdowns[o.argument.name].value = id;
|
||||||
|
updatePrices();
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveAddress(a, name) {
|
function saveAddress(a, name) {
|
||||||
|
|
@ -89,7 +145,7 @@
|
||||||
success: updateAddressDropdowns,
|
success: updateAddressDropdowns,
|
||||||
argument: { address: a, name: name }
|
argument: { address: a, name: name }
|
||||||
},
|
},
|
||||||
post = 'shop=address;method=ajaxSave;address=' +
|
post = 'shop=address;method=ajaxSave;address=' +
|
||||||
$json.stringify(a),
|
$json.stringify(a),
|
||||||
url = window.location.pathname;
|
url = window.location.pathname;
|
||||||
|
|
||||||
|
|
@ -97,13 +153,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function validAddress(a) {
|
function validAddress(a) {
|
||||||
return a.label &&
|
return a.label &&
|
||||||
a.firstName &&
|
a.firstName &&
|
||||||
a.lastName &&
|
a.lastName &&
|
||||||
a.address1 &&
|
a.address1 &&
|
||||||
a.city &&
|
a.city &&
|
||||||
a.state &&
|
a.state &&
|
||||||
a.code &&
|
a.code &&
|
||||||
a.country;
|
a.country;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -122,7 +178,7 @@
|
||||||
cached = addressCache[label] = {};
|
cached = addressCache[label] = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
oeach(elements[name], function (k, v) {
|
_.each(elements[name], function (v, k) {
|
||||||
v = v.value;
|
v = v.value;
|
||||||
address[k] = v;
|
address[k] = v;
|
||||||
if (cached[k] !== v) {
|
if (cached[k] !== v) {
|
||||||
|
|
@ -142,12 +198,13 @@
|
||||||
function addressUpdater(name) {
|
function addressUpdater(name) {
|
||||||
var elems = elements[name];
|
var elems = elements[name];
|
||||||
function update(address) {
|
function update(address) {
|
||||||
oeach(address, function (k, v) {
|
_.each(address, function (v, k) {
|
||||||
var dom = elems[k];
|
var dom = elems[k];
|
||||||
if (dom) {
|
if (dom) {
|
||||||
dom.value = v;
|
dom.value = v;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
updatePrices();
|
||||||
}
|
}
|
||||||
return function () {
|
return function () {
|
||||||
var id = this.value,
|
var id = this.value,
|
||||||
|
|
@ -159,8 +216,8 @@
|
||||||
return update(cached);
|
return update(cached);
|
||||||
}
|
}
|
||||||
|
|
||||||
url = window.location.pathname +
|
url = window.location.pathname +
|
||||||
'?shop=address;method=ajaxGetAddress;addressId=' +
|
'?shop=address;method=ajaxGetAddress;addressId=' +
|
||||||
id;
|
id;
|
||||||
|
|
||||||
cb = {
|
cb = {
|
||||||
|
|
@ -175,10 +232,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleBlur(name) {
|
function handleBlur(name) {
|
||||||
var values = omap(elements[name], function (k, v) {
|
$event.on(_.values(elements[name]), 'focusout', addressChange(name));
|
||||||
return v;
|
|
||||||
});
|
|
||||||
$event.on(values, 'focusout', addressChange(name));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleDropdown(name) {
|
function handleDropdown(name) {
|
||||||
|
|
@ -207,6 +261,9 @@
|
||||||
else {
|
else {
|
||||||
delete elements.shipping;
|
delete elements.shipping;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$event.on(elements.shipper, 'change', calculateSummary);
|
||||||
|
updatePrices();
|
||||||
}
|
}
|
||||||
|
|
||||||
$event.onDOMReady(main);
|
$event.onDOMReady(main);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue