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:
Colin Kuskie 2009-04-29 16:52:16 +00:00
parent e98fc02e9b
commit db290f91f9
8 changed files with 141 additions and 14 deletions

View file

@ -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)

View file

@ -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 --------------------------------
#----------------------------------------------------------------------------

View file

@ -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 ( )

View file

@ -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 => []
},

View file

@ -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;
}

View file

@ -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,

View file

@ -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;

View file

@ -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;
}