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:
parent
52d2c63271
commit
2bc6cd49a7
4 changed files with 138 additions and 3 deletions
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
84
t/Shop/Tax.t
84
t/Shop/Tax.t
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
8
t/supporting_collateral/taxTables/largeTaxTable.csv
Normal file
8
t/supporting_collateral/taxTables/largeTaxTable.csv
Normal 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
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue