Remove an extra my from Shop::Cart.

Add the getTaxRates method to Tax, with tests.
Add some calculate code to Tax, with tests, which don't pass yet.
This commit is contained in:
Colin Kuskie 2008-03-05 00:22:40 +00:00
parent 52d2c63271
commit 2bc6cd49a7
4 changed files with 138 additions and 3 deletions

View file

@ -72,7 +72,7 @@ sub create {
}
my $cartId = $session->db->quickScalar("select cartId from cart where sessionId=?",[$session->getId]);
return $class->new($session, $cartId) if (defined $cartId);
my $cartId = $session->id->generate;
$cartId = $session->id->generate;
$session->db->write('insert into cart (cartId, sessionId) values (?,?)', [$cartId, $session->getId]);
return $class->new($session, $cartId);
}

View file

@ -6,6 +6,11 @@ use Class::InsideOut qw{ :std };
use WebGUI::Text;
use WebGUI::Storage;
use WebGUI::Exception::Shop;
use WebGUI::Shop::Cart;
use WebGUI::Shop::CartItem;
use WebGUI::Shop::AddressBook;
use WebGUI::Shop::Address;
use List::Util qw{sum};
=head1 NAME
@ -89,7 +94,23 @@ sub calculate {
my $cart = shift;
WebGUI::Error::InvalidParam->throw(error => 'Must pass in a WebGUI::Shop::Cart object')
unless ref($cart) eq 'WebGUI::Shop::Cart';
return;
my $book = WebGUI::Shop::AddressBook->create($self->session);
my $address = WebGUI::Shop::Address->new($book, $cart->get('shippingAddressId'));
my $tax = 0;
foreach my $item (@{ $cart->getItems }) {
my $sku = $item->getSku;
my $unitPrice = $sku->getPrice;
my $quantity = $item->get('quantity');
my $taxables = $self->getTaxRates($address);
use Data::Dumper;
warn Dumper $taxables;
my $itemTax = sum(@{$taxables}) / 100; ##Form a percentage
warn "unitPrice: $unitPrice\n";
warn "quantity : $quantity\n";
warn "itemTax : $itemTax\n";
$tax += $unitPrice * $quantity * $itemTax;
}
return $tax;
}
#-------------------------------------------------------------------
@ -160,6 +181,30 @@ sub getItems {
#-------------------------------------------------------------------
=head2 getTaxRates ( $address )
Given a WebGUI::Shop::Address object, return all rates associated with the address as an arrayRef.
=cut
sub getTaxRates {
my $self = shift;
my $address = shift;
WebGUI::Error::InvalidObject->throw(error => 'Need an address.', expected=>'WebGUI::Shop::Address', got=>(ref $address))
unless ref($address) eq 'WebGUI::Shop::Address';
my $result = $self->session->db->buildArrayRef(
q{
select taxRate from tax where
(field='state' and value=?)
OR (field='country' and value=?)
OR (field='code' and value=?)
},
[$address->get('state'), $address->get('country'), $address->get('code')]);
return $result;
}
#-------------------------------------------------------------------
=head2 importTaxData ( $filePath )
Import tax information from the specified file in CSV format. The

View file

@ -23,6 +23,8 @@ use Exception::Class;
use WebGUI::Test; # Must use this before any other WebGUI modules
use WebGUI::Session;
use WebGUI::Text;
use WebGUI::Shop::Cart;
use WebGUI::Shop::AddressBook;
#----------------------------------------------------------------------------
# Init
@ -31,7 +33,7 @@ my $session = WebGUI::Test->session;
#----------------------------------------------------------------------------
# Tests
my $tests = 64;
my $tests = 68;
plan tests => 1 + $tests;
#----------------------------------------------------------------------------
@ -366,6 +368,57 @@ cmp_deeply(
'importTaxData: error handling for file that that cannot be read',
);
#######################################################################
#
# getTaxRates
#
#######################################################################
##Set up the tax information
$taxer->importTaxData(
WebGUI::Test->getTestCollateralPath('taxTables/largeTaxTable.csv')
),
my $book = WebGUI::Shop::AddressBook->create($session);
my $taxingAddress = $book->addAddress({
label => 'taxing',
city => 'Madison',
state => 'WI',
code => '53701',
country => 'USA',
});
my $taxFreeAddress = $book->addAddress({
label => 'no tax',
city => 'Portland',
state => 'OR',
code => '97123',
country => 'USA',
});
eval { $taxer->getTaxRates(); };
$e = Exception::Class->caught();
isa_ok($e, 'WebGUI::Error::InvalidObject', 'calculate: error handling for not sending a cart');
cmp_deeply(
$e,
methods(
error => 'Need an address.',
got => '',
expected => 'WebGUI::Shop::Address',
),
'importTaxData: error handling for file that does not exist in the filesystem',
);
cmp_deeply(
$taxer->getTaxRates($taxingAddress),
[5, 0.5],
'getTaxRates: return correct data for a state with tax data'
);
cmp_deeply(
$taxer->getTaxRates($taxFreeAddress),
[0.0],
'getTaxRates: return correct data for a state with no tax data'
);
#######################################################################
#
# calculate
@ -379,6 +432,32 @@ is($e->error, 'Must pass in a WebGUI::Shop::Cart object', 'calculate: error hand
##Build a cart, add some Donation SKUs to it. Set one to be taxable.
my $cart = WebGUI::Shop::Cart->create($session);
$cart->update({ shippingAddressId => $taxingAddress->getId});
##Set up the tax information
$taxer->importTaxData(
WebGUI::Test->getTestCollateralPath('taxTables/goodTaxTable.csv')
),
my $taxableDonation = WebGUI::Asset->getRoot($session)->addChild({
className => 'WebGUI::Asset::Sku::Donation',
title => 'Taxable donation',
defaultPrice => 100.00,
});
$cart->addItem($taxableDonation);
foreach my $item (@{ $cart->getItems }) {
$item->setQuantity(1);
}
my $tax = $taxer->calculate($cart);
is($tax, 5.5, 'calculate: simple tax calculation on 1 item in the cart');
$taxableDonation->purge;
$cart->delete;
$book->delete;
}
sub _grabTaxData {
@ -395,5 +474,8 @@ sub _grabTaxData {
# Cleanup
END {
$session->db->write('delete from tax');
$session->db->write('delete from cart');
$session->db->write('delete from addressBook');
$session->db->write('delete from address');
$storage->delete;
}

View file

@ -0,0 +1,8 @@
field,value,taxRate
state,WI,5.0
code,53701,0.5
code,53702,0.5
code,53703,0.5
code,53704,0.5
state,CA,7.25
code,97123,0.0
1 field value taxRate
2 state WI 5.0
3 code 53701 0.5
4 code 53702 0.5
5 code 53703 0.5
6 code 53704 0.5
7 state CA 7.25
8 code 97123 0.0