webgui/lib/WebGUI/Shop/ShipDriver/FlatRate.pm
Colin Kuskie db290f91f9 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.
2009-04-29 16:52:16 +00:00

129 lines
3.9 KiB
Perl

package WebGUI::Shop::ShipDriver::FlatRate;
use strict;
use base qw/WebGUI::Shop::ShipDriver/;
use WebGUI::Exception;
=head1 NAME
Package WebGUI::Shop::ShipDriver::FlatRate
=head1 DESCRIPTION
This Shipping driver allows for calculating shipping costs without any
tie-ins to external shippers.
=head1 SYNOPSIS
=head1 METHODS
See the master class, WebGUI::Shop::ShipDriver for information about
base methods. These methods are customized in this class:
=cut
#-------------------------------------------------------------------
=head2 calculate ( $cart )
Returns a shipping price. Calculates the shipping price using the following formula:
total price of shippable items * percentageOfPrice
+ total weight of shippable items * pricePerWeight
+ total quantity of shippable items * pricePerItem
+ flatFee * numberOfSeparatelyShippedItems
=head3 $cart
A WebGUI::Shop::Cart object. The contents of the cart are analyzed to calculate
the shipping costs. If no items in the cart require shipping, then no shipping
costs are assessed.
=cut
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) {
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') * ($separatelyShipped + $looseBundle);
}
return $cost;
}
#-------------------------------------------------------------------
=head2 definition ( $session )
This subroutine returns an arrayref of hashrefs, used to validate data put into
the object by the user, and to automatically generate the edit form to show
the user.
=cut
sub definition {
my $class = shift;
my $session = shift;
WebGUI::Error::InvalidParam->throw(error => q{Must provide a session variable})
unless ref $session eq 'WebGUI::Session';
my $definition = shift || [];
my $i18n = WebGUI::International->new($session, 'ShipDriver_FlatRate');
tie my %fields, 'Tie::IxHash';
%fields = (
flatFee => {
fieldType => 'float',
label => $i18n->get('flatFee'),
hoverHelp => $i18n->get('flatFee help'),
defaultValue => 0,
},
percentageOfPrice => {
fieldType => 'float',
label => $i18n->get('percentageOfPrice'),
hoverHelp => $i18n->get('percentageOfPrice help'),
defaultValue => 0,
},
pricePerWeight => {
fieldType => 'float',
label => $i18n->get('percentageOfWeight'),
hoverHelp => $i18n->get('percentageOfWeight help'),
defaultValue => 0,
},
pricePerItem => {
fieldType => 'float',
label => $i18n->get('pricePerItem'),
hoverHelp => $i18n->get('pricePerItem help'),
defaultValue => 0,
},
);
my %properties = (
name => 'Flat Rate',
properties => \%fields,
);
push @{ $definition }, \%properties;
return $class->SUPER::definition($session, $definition);
}
1;