Add an option to the Sku to require individual shipping of this sku, separate
from other items in the cart. Update the FlatRate driver to support calculating that.
This commit is contained in:
parent
e98fc02e9b
commit
db290f91f9
8 changed files with 141 additions and 14 deletions
|
|
@ -12,6 +12,7 @@
|
|||
- Fixed a bug in the YUI simple editor for survey editing which was leaking memory. Also improved the object edit templates.
|
||||
- fixed #10184: Matrix 2.0 - Version Tag Duplicate Type
|
||||
- fixed #10182: Matrix 2.0 - Comparison view broken in IE 6 & 7
|
||||
- Added individual shipping requirements to the Sku.
|
||||
|
||||
7.7.4
|
||||
- rfe: Extend DateTime for Week-Nrs (#9151)
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@ turnOffAdmin($session);
|
|||
|
||||
correctEventTemplateVariables($session);
|
||||
|
||||
addShipsSeparateToSku($session);
|
||||
|
||||
finish($session); # this line required
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
|
@ -159,7 +161,6 @@ sub correctEventTemplateVariables {
|
|||
});
|
||||
|
||||
TEMPLATE: while (my $templateAsset = $getATemplate->()) {
|
||||
print("\t\t Correcting ". $templateAsset->getTitle. "\n") unless $quiet;
|
||||
my $template = $templateAsset->get('template');
|
||||
$template =~ s{<tmpl_var url>\?func=edit}{<tmpl_var urlEdit>}isg;
|
||||
$template =~ s{<tmpl_var url>\?func=delete}{<tmpl_var urlDelete>}isg;
|
||||
|
|
@ -172,6 +173,15 @@ sub correctEventTemplateVariables {
|
|||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
sub addShipsSeparateToSku {
|
||||
my ($session) = @_;
|
||||
print "\tAdd shipsSeparate property to Sku... " unless $quiet;
|
||||
$session->db->write(<<EOSQL);
|
||||
ALTER TABLE sku ADD COLUMN shipsSeparately tinyint(1) NOT NULL
|
||||
EOSQL
|
||||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
# -------------- DO NOT EDIT BELOW THIS LINE --------------------------------
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -56,7 +56,8 @@ These methods are available from this class:
|
|||
|
||||
=head2 addToCart ( options )
|
||||
|
||||
Adds this sku to the current session's cart.
|
||||
Adds this sku to the current session's cart. Returns a copy of the Shop::Cart::Item
|
||||
object added to the cart.
|
||||
|
||||
=head3 options
|
||||
|
||||
|
|
@ -137,6 +138,13 @@ sub definition {
|
|||
fieldType => 'hidden',
|
||||
defaultValue => '{}',
|
||||
},
|
||||
shipsSeparately => {
|
||||
tab => 'shop',
|
||||
fieldType => 'yesNo',
|
||||
defaultValue => 0,
|
||||
label => $i18n->get('shipsSeparate'),
|
||||
hoverHelp => $i18n->get('shipsSeparate help'),
|
||||
},
|
||||
);
|
||||
push(@{$definition}, {
|
||||
assetName=>$i18n->get('assetName'),
|
||||
|
|
@ -594,6 +602,15 @@ sub processStyle {
|
|||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 setTaxConfiguration ($namespace, $configuration)
|
||||
|
||||
=head3 $namespace
|
||||
|
||||
=head3 $configuration
|
||||
|
||||
=cut
|
||||
|
||||
sub setTaxConfiguration {
|
||||
my $self = shift;
|
||||
my $namespace = shift;
|
||||
|
|
@ -615,6 +632,19 @@ sub setTaxConfiguration {
|
|||
} );
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 shipsSeparately
|
||||
|
||||
Returns a boolean indicating whether this item must be shipped separately from other items.
|
||||
|
||||
=cut
|
||||
|
||||
sub shipsSeparately {
|
||||
return shift->get('shipsSeparately');
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_view ( )
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ our $HELP = {
|
|||
{ 'name' => 'description', description=>'description help' },
|
||||
{ 'name' => 'displayTitle', description=>'display title help' },
|
||||
{ 'name' => 'vendorId', description=>'vendor help' },
|
||||
{ 'name' => 'shipsSeparately', description=>'shipsSeparately help' },
|
||||
],
|
||||
related => []
|
||||
},
|
||||
|
|
|
|||
|
|
@ -29,9 +29,9 @@ base methods. These methods are customized in this class:
|
|||
Returns a shipping price. Calculates the shipping price using the following formula:
|
||||
|
||||
total price of shippable items * percentageOfPrice
|
||||
+ flatFee
|
||||
+ total weight of shippable items * pricePerWeight
|
||||
+ total quantity of shippable items * pricePerItem
|
||||
+ flatFee * numberOfSeparatelyShippedItems
|
||||
|
||||
=head3 $cart
|
||||
|
||||
|
|
@ -45,17 +45,31 @@ sub calculate {
|
|||
my ($self, $cart) = @_;
|
||||
my $cost = 0;
|
||||
my $anyShippable = 0;
|
||||
my $separatelyShipped = 0;
|
||||
my $looseBundle = 0;
|
||||
foreach my $item (@{$cart->getItems}) {
|
||||
my $sku = $item->getSku;
|
||||
if ($sku->isShippingRequired) {
|
||||
$cost += ($item->get("quantity") * $sku->getPrice * $self->get("percentageOfPrice") / 100) # cost by price
|
||||
+ ($item->get("quantity") * $sku->getWeight * $self->get("pricePerWeight") / 100) # cost by weight
|
||||
+ ($item->get("quantity") * $self->get("pricePerItem")); # cost by item
|
||||
my $quantity = $item->get('quantity');
|
||||
$cost += ($quantity * $sku->getPrice * $self->get("percentageOfPrice") / 100) # cost by price
|
||||
+ ($quantity * $sku->getWeight * $self->get("pricePerWeight") / 100) # cost by weight
|
||||
+ ($quantity * $self->get("pricePerItem")); # cost by item
|
||||
$anyShippable = 1;
|
||||
##Account for items which must be shipped separately, and with those that can be shipped
|
||||
##together.
|
||||
## Two items shipped separately = two bundles
|
||||
## 1 shipped separately plus 1 not = two bundles
|
||||
## two items shipped together = one bundle
|
||||
if ($sku->shipsSeparately) {
|
||||
$separatelyShipped += $quantity;
|
||||
}
|
||||
else {
|
||||
$looseBundle = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($anyShippable) {
|
||||
$cost += $self->get('flatFee');
|
||||
$cost += $self->get('flatFee') * ($separatelyShipped + $looseBundle);
|
||||
}
|
||||
return $cost;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,6 +69,18 @@ our $I18N = {
|
|||
context => q|help for vendor field|
|
||||
},
|
||||
|
||||
'shipsSeparately' => {
|
||||
message => q|Ships Separately?|,
|
||||
lastUpdated => 0,
|
||||
context => q|label in the edit form. Ships, as in ships via post or mail or shipping. Separately, independently of other items in the cart.|,
|
||||
},
|
||||
|
||||
'shipsSeparately help' => {
|
||||
message => q|If set to yes, then this Sku will incur additional, independent shipping costs, rather than sharing costs with other items in a cart.|,
|
||||
lastUpdated => 0,
|
||||
context => q|help for shipsSeparate field in the edit form|
|
||||
},
|
||||
|
||||
'add to cart' => {
|
||||
message => q|Add To Cart|,
|
||||
lastUpdated => 0,
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ my $session = WebGUI::Test->session;
|
|||
#----------------------------------------------------------------------------
|
||||
# Tests
|
||||
|
||||
plan tests => 17; # Increment this number for each test you create
|
||||
plan tests => 19; # Increment this number for each test you create
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# put your tests here
|
||||
|
|
@ -63,6 +63,10 @@ is($sku->onRemoveFromCart, undef, "onRemoveFromCart should exist and return unde
|
|||
is($sku->isRecurring, 0, "skus are not recurring by default");
|
||||
is($sku->isShippingRequired, 0, "skus are not shippable by default");
|
||||
is($sku->getConfiguredTitle, $sku->getTitle, "configured title and title should be the same by default");
|
||||
is($sku->shipsSeparately, 0, 'shipsSeparately return 0 by default');
|
||||
|
||||
$sku->update({shipsSeparately => 1,});
|
||||
is($sku->shipsSeparately, 1, '... tracks shipsSepartely sku property');
|
||||
|
||||
isa_ok($sku->getCart, "WebGUI::Shop::Cart", "can get a cart object");
|
||||
my $item = $sku->addToCart;
|
||||
|
|
@ -72,12 +76,12 @@ $item->cart->delete;
|
|||
my $loadSku = WebGUI::Asset::Sku->newBySku($session, $sku->get("sku"));
|
||||
is($loadSku->getId, $sku->getId, "newBySku() works.");
|
||||
|
||||
$sku->purge;
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Cleanup
|
||||
END {
|
||||
|
||||
$sku->purge;
|
||||
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ my $session = WebGUI::Test->session;
|
|||
#----------------------------------------------------------------------------
|
||||
# Tests
|
||||
|
||||
my $tests = 14;
|
||||
my $tests = 19;
|
||||
plan tests => 1 + $tests;
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
|
@ -40,7 +40,7 @@ plan tests => 1 + $tests;
|
|||
my $loaded = use_ok('WebGUI::Shop::ShipDriver::FlatRate');
|
||||
|
||||
my $storage;
|
||||
my ($driver, $cart, $car);
|
||||
my ($driver, $cart, $car, $key);
|
||||
my $versionTag;
|
||||
|
||||
SKIP: {
|
||||
|
|
@ -127,8 +127,6 @@ cmp_deeply(
|
|||
#
|
||||
#######################################################################
|
||||
|
||||
$driver;
|
||||
|
||||
my $options = {
|
||||
label => 'flat rate, ship weight, items in the cart',
|
||||
enabled => 1,
|
||||
|
|
@ -319,6 +317,60 @@ $options = {
|
|||
$driver->update($options);
|
||||
is($driver->calculate($cart), 30_200, 'calculate by percentage of price');
|
||||
|
||||
$cart->empty();
|
||||
$driver->update({
|
||||
label => 'flat fee for shipsSeparately test',
|
||||
enabled => 1,
|
||||
flatFee => 1,
|
||||
percentageOfPrice => 0,
|
||||
pricePerWeight => 0,
|
||||
pricePerItem => 0,
|
||||
});
|
||||
|
||||
$key = WebGUI::Asset->getImportNode($session)->addChild({
|
||||
className => 'WebGUI::Asset::Sku::Product',
|
||||
title => 'Key',
|
||||
isShippingRequired => 1,
|
||||
shipsSeparately => 1,
|
||||
});
|
||||
|
||||
my $metalKey = $key->setCollateral('variantsJSON', 'variantId', 'new',
|
||||
{
|
||||
shortdesc => 'metal key',
|
||||
varSku => 'metal-key',
|
||||
price => 1.00,
|
||||
weight => 1.00,
|
||||
quantity => 1e9,
|
||||
}
|
||||
);
|
||||
|
||||
my $bioKey = $key->setCollateral('variantsJSON', 'variantId', 'new',
|
||||
{
|
||||
shortdesc => 'biometric key',
|
||||
varSku => 'bio-key',
|
||||
price => 5.00,
|
||||
weight => 1.00,
|
||||
quantity => 1e9,
|
||||
}
|
||||
);
|
||||
|
||||
my $boughtCar = $car->addToCart($car->getCollateral('variantsJSON', 'variantId', $reallyNiceCar));
|
||||
my $firstKey = $key->addToCart($key->getCollateral('variantsJSON', 'variantId', $metalKey));
|
||||
is($driver->calculate($cart), 2, 'shipsSeparately: returns two, one for ships separately, one for ships bundled');
|
||||
|
||||
$boughtCar->adjustQuantity();
|
||||
is($driver->calculate($cart), 2, '... returns two, one for ships separately, one for ships bundled, even for two items');
|
||||
|
||||
$firstKey->adjustQuantity();
|
||||
is($driver->calculate($cart), 3, '... returns three, two for ships separately, one for ships bundled, even for two items');
|
||||
|
||||
$key->update({shipsSeparately => 0});
|
||||
is($driver->calculate($cart), 1, '... returns one, since all can be bundled together now');
|
||||
|
||||
$car->update({shipsSeparately => 1});
|
||||
$key->update({shipsSeparately => 1});
|
||||
is($driver->calculate($cart), 4, '... returns four, since all must be shipped separately now');
|
||||
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
|
@ -333,6 +385,9 @@ END {
|
|||
if (defined $car && (ref($car) eq 'WebGUI::Asset::Sku::Product')) {
|
||||
$car->purge;
|
||||
}
|
||||
if (defined $key && (ref($key) eq 'WebGUI::Asset::Sku::Product')) {
|
||||
$key->purge;
|
||||
}
|
||||
if (defined $versionTag) {
|
||||
$versionTag->rollback;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue