From 9d90b92629a90dfc57d6dfb11ec9b81bb2ba818e Mon Sep 17 00:00:00 2001 From: Martin Kamerbeek Date: Fri, 8 May 2009 10:03:25 +0000 Subject: [PATCH] Tax details are now stored with the transaction items they belong to. --- docs/upgrades/upgrade_7.7.5-7.7.6.pl | 14 ++++++++++ lib/WebGUI/Account/Shop.pm | 10 ++++++- lib/WebGUI/Shop/TaxDriver.pm | 26 +++++++++++++++++++ lib/WebGUI/Shop/TaxDriver/EU.pm | 31 ++++++++++++++++++++++ lib/WebGUI/Shop/TransactionItem.pm | 16 +++++++++--- t/Shop/TaxDriver/EU.t | 39 ++++++++++++++++++++++++++-- t/Shop/Transaction.t | 4 ++- 7 files changed, 133 insertions(+), 7 deletions(-) diff --git a/docs/upgrades/upgrade_7.7.5-7.7.6.pl b/docs/upgrades/upgrade_7.7.5-7.7.6.pl index 8a5a7815e..598ba5f2b 100644 --- a/docs/upgrades/upgrade_7.7.5-7.7.6.pl +++ b/docs/upgrades/upgrade_7.7.5-7.7.6.pl @@ -33,6 +33,7 @@ addTemplateAttachmentsTable($session); revertUsePacked( $session ); fixDefaultPostReceived($session); addEuVatDbColumns( $session ); +addTransactionTaxColumns( $session ); finish($session); @@ -100,6 +101,19 @@ sub addEuVatDbColumns { print "Done\n" unless $quiet; } +#---------------------------------------------------------------------------- +sub addTransactionTaxColumns { + my $session = shift; + print "\tAdding columns for storing tax data in the transaction log..." unless $quiet; + + $session->db->write( 'alter table transactionItem add column taxRate decimal(6,3)' ); + $session->db->write( 'alter table transactionItem add column taxConfiguration mediumtext' ); + $session->db->write( 'alter table transactionItem change vendorPayoutAmount vendorPayoutAmount decimal (8,2) default 0.00' ); + + print "Done\n" unless $quiet; + +} + # -------------- DO NOT EDIT BELOW THIS LINE -------------------------------- #---------------------------------------------------------------------------- diff --git a/lib/WebGUI/Account/Shop.pm b/lib/WebGUI/Account/Shop.pm index d14b8b214..e4155ae8b 100644 --- a/lib/WebGUI/Account/Shop.pm +++ b/lib/WebGUI/Account/Shop.pm @@ -6,6 +6,8 @@ use WebGUI::Exception; use WebGUI::International; use WebGUI::Pluggable; use WebGUI::Utility; +use JSON qw{ from_json }; + use base qw/WebGUI::Account/; =head1 NAME @@ -348,9 +350,15 @@ sub www_viewTransaction { url => $actions->{$label}, } } + + my %taxConfiguration = %{ from_json( $item->get( 'taxConfiguration' ) || '{}' ) }; + my %taxVars = + map { ( "tax_$_" => $taxConfiguration{ $_ } ) } + keys %taxConfiguration; push @items, { - %{$item->get}, + %{ $item->get }, + %taxVars, viewItemUrl => $url->page('shop=transaction;method=viewItem;transactionId='.$transaction->getId.';itemId='.$item->getId), price => sprintf("%.2f", $item->get('price')), itemShippingAddress => $address, diff --git a/lib/WebGUI/Shop/TaxDriver.pm b/lib/WebGUI/Shop/TaxDriver.pm index cc9b3242b..24893dd70 100644 --- a/lib/WebGUI/Shop/TaxDriver.pm +++ b/lib/WebGUI/Shop/TaxDriver.pm @@ -178,6 +178,32 @@ sub getTaxRate { #----------------------------------------------------------- +=head2 getTransactionTaxData ( sku, address ) + +Returns a hashref containing tax information that should be stored along with transaction items. + +=head3 sku + +The sku belonging to the transaction item. + +=head3 address + +The address belonging to the transaction item. + +=cut + +sub getTransactionTaxData { + my $self = shift; + + my $config = { + className => $self->className, + }; + + return $config; +} + +#----------------------------------------------------------- + =head2 getUserScreen ( ) Returns the screen for entering per user configuration for this tax driver. diff --git a/lib/WebGUI/Shop/TaxDriver/EU.pm b/lib/WebGUI/Shop/TaxDriver/EU.pm index eae3d45fb..8b415dd8b 100644 --- a/lib/WebGUI/Shop/TaxDriver/EU.pm +++ b/lib/WebGUI/Shop/TaxDriver/EU.pm @@ -507,6 +507,37 @@ sub getTaxRate { return $taxRate; } +#------------------------------------------------------------------- + +=head2 getTransactionTaxData ( sku, address ) + +See WebGUI::Shop::TaxDriver->getTransactionTaxData. + +=cut + +sub getTransactionTaxData { + my $self = shift; + my $sku = shift; + my $address = shift; + my $countryCode = $self->getCountryCode( $address->get( 'country' ) ); + + my $config = $self->SUPER::getTransactionTaxData( $sku, $address ); + + if ( ! $countryCode ) { + $config->{ outsideEU } = 1; + } + elsif ( $self->hasVATNumber( $countryCode ) ) { + $config->{ useVATNumber } = 1; + $config->{ VATNumber } = $self->getVATNumbers( $countryCode )->[0]->{ vatNumber }; + } + else { + $config->{ useVATNumber } = 0; + } + + return $config; +} + + #------------------------------------------------------------------- =head2 getVATNumbers ( $countryCode ) diff --git a/lib/WebGUI/Shop/TransactionItem.pm b/lib/WebGUI/Shop/TransactionItem.pm index 61287c932..da0a4b321 100644 --- a/lib/WebGUI/Shop/TransactionItem.pm +++ b/lib/WebGUI/Shop/TransactionItem.pm @@ -2,10 +2,11 @@ package WebGUI::Shop::TransactionItem; use strict; use Class::InsideOut qw{ :std }; -use JSON; +use JSON qw{ to_json }; use WebGUI::DateTime; use WebGUI::Exception::Shop; use WebGUI::Shop::Transaction; +use WebGUI::Shop::Tax; =head1 NAME @@ -263,7 +264,10 @@ The status of this item. The default is 'NotShipped'. Other statuses include: Ca sub update { my ($self, $newProperties) = @_; - my $id = id $self; + my $id = id $self; + my $session = $self->transaction->session; + my $taxDriver = WebGUI::Shop::Tax->getDriver( $session ); + if (exists $newProperties->{item}) { my $item = $newProperties->{ item }; my $sku = $item->getSku; @@ -286,6 +290,12 @@ sub update { $newProperties->{ shippingCountry } = $address->get('country'); $newProperties->{ shippingCode } = $address->get('code'); $newProperties->{ shippingPhoneNumber } = $address->get('phoneNumber'); + + # Store tax rate for product + $newProperties->{ taxRate } = $taxDriver->getTaxRate( $sku, $address ); + $newProperties->{ taxConfiguration } = + to_json( $taxDriver->getTransactionTaxData( $sku, $address ) || '{}' ); + unless ($sku->isShippingRequired) { $newProperties->{orderStatus} = 'Shipped'; } @@ -293,7 +303,7 @@ sub update { my @fields = (qw(assetId configuredTitle options shippingAddressId shippingTrackingNumber orderStatus shippingName shippingAddress1 shippingAddress2 shippingAddress3 shippingCity shippingState shippingCountry shippingCode shippingPhoneNumber quantity price vendorId - vendorPayoutStatus vendorPayoutAmount)); + vendorPayoutStatus vendorPayoutAmount taxRate taxConfiguration)); foreach my $field (@fields) { $properties{$id}{$field} = (exists $newProperties->{$field}) ? $newProperties->{$field} : $properties{$id}{$field}; } diff --git a/t/Shop/TaxDriver/EU.t b/t/Shop/TaxDriver/EU.t index 0d4b2085f..936842e14 100644 --- a/t/Shop/TaxDriver/EU.t +++ b/t/Shop/TaxDriver/EU.t @@ -38,7 +38,7 @@ $taxUser->username( 'MrEvasion' ); #---------------------------------------------------------------------------- # Tests -my $tests = 44; +my $tests = 48; plan tests => 1 + $tests; #---------------------------------------------------------------------------- @@ -312,6 +312,40 @@ SKIP: { ); is( $taxer->getTaxRate( $sku, $nlAddress ), 100, 'getTaxRate: shipping addresses in country of merchant w/ VAT number pay tax' ); + ####################################################################### + # + # getTransactionTaxData + # + ####################################################################### + + my $details = $taxer->getTransactionTaxData( $sku, $usAddress ); + cmp_deeply( $details, { + className => 'WebGUI::Shop::TaxDriver::EU', + outsideEU => 1, + }, 'getTransactionTaxData returns correct hashref for addresses outside EU' ); + + $details = $taxer->getTransactionTaxData( $sku, $beAddress ); + cmp_deeply( $details, { + className => 'WebGUI::Shop::TaxDriver::EU', + useVATNumber => 1, + VATNumber => $testVAT_BE, + }, 'getTransactionTaxData returns correct hashref for addresses inside EU but not shop country w/ VAT number' ); + + $details = $taxer->getTransactionTaxData( $sku, $nlAddress ); + cmp_deeply( $details, { + className => 'WebGUI::Shop::TaxDriver::EU', + useVATNumber => 1, + VATNumber => $testVAT_NL, + }, 'getTransactionTaxData returns correct hashref for addresses in shop country w/ VAT number' ); + + $taxer->deleteVATNumber( $testVAT_NL ); + + $details = $taxer->getTransactionTaxData( $sku, $nlAddress ); + cmp_deeply( $details, { + className => 'WebGUI::Shop::TaxDriver::EU', + useVATNumber => 0, + }, 'getTransactionTaxData returns correct hashref for addresses in EU w/o VAT number' ); + ####################################################################### # # deleteGroup @@ -350,6 +384,7 @@ END { $session->db->write('delete from cart'); $session->db->write('delete from addressBook'); $session->db->write('delete from address'); - + $session->db->write('delete from taxDriver where className=?', [ 'WebGUI::Shop::TaxDriver::EU' ]); + $taxUser->delete; } diff --git a/t/Shop/Transaction.t b/t/Shop/Transaction.t index 47e9ffc24..b2153a4d6 100644 --- a/t/Shop/Transaction.t +++ b/t/Shop/Transaction.t @@ -30,7 +30,7 @@ my $session = WebGUI::Test->session; #---------------------------------------------------------------------------- # Tests -plan tests => 67; # Increment this number for each test you create +plan tests => 68; # Increment this number for each test you create #---------------------------------------------------------------------------- # put your tests here @@ -137,6 +137,7 @@ my $item = $transaction->addItem({ shippingPhoneNumber => 'l', quantity => 5, price => 33, + taxRate => 19, }); isa_ok($item, "WebGUI::Shop::TransactionItem"); @@ -157,6 +158,7 @@ is($item->get("shippingCode"), 'k', "set and get shipping code"); is($item->get("shippingPhoneNumber"), 'l', "set and get shipping phone number"); is($item->get("quantity"), 5, "set and get quantity"); is($item->get("price"), 33, "set and get price"); +is($item->get('taxRate'), 19, 'set and get taxRate' ); $item->update({ shippingTrackingNumber => 'adfs',