From 2bc6cd49a794daa932e644ab82b8001c97bda75c Mon Sep 17 00:00:00 2001 From: Colin Kuskie Date: Wed, 5 Mar 2008 00:22:40 +0000 Subject: [PATCH] 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. --- lib/WebGUI/Shop/Cart.pm | 2 +- lib/WebGUI/Shop/Tax.pm | 47 ++++++++++- t/Shop/Tax.t | 84 ++++++++++++++++++- .../taxTables/largeTaxTable.csv | 8 ++ 4 files changed, 138 insertions(+), 3 deletions(-) create mode 100644 t/supporting_collateral/taxTables/largeTaxTable.csv diff --git a/lib/WebGUI/Shop/Cart.pm b/lib/WebGUI/Shop/Cart.pm index 484fa6362..18923c4b0 100644 --- a/lib/WebGUI/Shop/Cart.pm +++ b/lib/WebGUI/Shop/Cart.pm @@ -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); } diff --git a/lib/WebGUI/Shop/Tax.pm b/lib/WebGUI/Shop/Tax.pm index 64b4fcd46..9917b97c9 100644 --- a/lib/WebGUI/Shop/Tax.pm +++ b/lib/WebGUI/Shop/Tax.pm @@ -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 diff --git a/t/Shop/Tax.t b/t/Shop/Tax.t index e264462ec..4cd28b5b9 100644 --- a/t/Shop/Tax.t +++ b/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; } diff --git a/t/supporting_collateral/taxTables/largeTaxTable.csv b/t/supporting_collateral/taxTables/largeTaxTable.csv new file mode 100644 index 000000000..468747574 --- /dev/null +++ b/t/supporting_collateral/taxTables/largeTaxTable.csv @@ -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