diff --git a/docs/upgrades/packages-7.5.11/root_import_default-donation-template.wgpkg b/docs/upgrades/packages-7.5.11/root_import_default-donation-template.wgpkg index 473f9b92e..9c3fc853f 100644 Binary files a/docs/upgrades/packages-7.5.11/root_import_default-donation-template.wgpkg and b/docs/upgrades/packages-7.5.11/root_import_default-donation-template.wgpkg differ diff --git a/docs/upgrades/packages-7.5.11/shopping-cart-collateral-items-1.wgpkg b/docs/upgrades/packages-7.5.11/shopping-cart-collateral-items-1.wgpkg index 25862fefa..ed495d051 100644 Binary files a/docs/upgrades/packages-7.5.11/shopping-cart-collateral-items-1.wgpkg and b/docs/upgrades/packages-7.5.11/shopping-cart-collateral-items-1.wgpkg differ diff --git a/docs/upgrades/upgrade_7.5.10-7.5.11.pl b/docs/upgrades/upgrade_7.5.10-7.5.11.pl index a67ab0881..a1d2000bf 100644 --- a/docs/upgrades/upgrade_7.5.10-7.5.11.pl +++ b/docs/upgrades/upgrade_7.5.10-7.5.11.pl @@ -396,6 +396,7 @@ sub convertTransactionLog { userId varchar(22) binary not null, username varchar(35) not null, amount float, + shopCreditDeduction float, shippingAddressId varchar(22) binary, shippingAddressName varchar(35), shippingAddress1 varchar(35), @@ -619,6 +620,8 @@ sub addPaymentDrivers { # and here's our code $session->config->delete('paymentPlugins'); $session->config->addToArray('paymentDrivers', 'WebGUI::Shop::PayDriver::Cash'); + $session->config->addToArray('paymentDrivers', 'WebGUI::Shop::PayDriver::ITransact'); + } #------------------------------------------------- diff --git a/etc/WebGUI.conf.original b/etc/WebGUI.conf.original index 7794579f4..8b0baa8d9 100644 --- a/etc/WebGUI.conf.original +++ b/etc/WebGUI.conf.original @@ -171,7 +171,7 @@ # List the merchant gateways you have installed and wish to be # available on this site. -"paymentDrivers" : ["WebGUI::Shop::PayDriver::Cash"], +"paymentDrivers" : ["WebGUI::Shop::PayDriver::Cash", "WebGUI::Shop::PayDriver::ITransact"], # List the shipping drivers you have installed and wish to be # available for configuration on the site. diff --git a/lib/WebGUI/Shop/Cart.pm b/lib/WebGUI/Shop/Cart.pm index 5556656dd..88dbeb738 100644 --- a/lib/WebGUI/Shop/Cart.pm +++ b/lib/WebGUI/Shop/Cart.pm @@ -10,6 +10,7 @@ use WebGUI::Form; use WebGUI::International; use WebGUI::Shop::AddressBook; use WebGUI::Shop::CartItem; +use WebGUI::Shop::Credit; use WebGUI::Shop::Ship; use WebGUI::Shop::Tax; @@ -62,6 +63,55 @@ sub addItem { #------------------------------------------------------------------- +=head2 calculateShopCreditDeduction ( [ total ] ) + +Returns the amount of the total that will be deducted by shop credit. + +=head3 total + +The amount to calculate the deduction against. Defaults to calculateTotal(). + +=cut + +sub calculateShopCreditDeduction { + my ($self, $total) = @_; + # cannot use in-shop credit on recurring items + foreach my $item (@{$self->getItems}) { + if ($item->getSku->isRecurring) { + return $self->formatCurrency(0); + } + } + unless (defined $total) { + $total = $self->calculateTotal + } + return $self->formatCurrency(WebGUI::Shop::Credit->new($self->session)->calculateDeduction($total)); +} + +#------------------------------------------------------------------- + +=head2 calculateShipping () + +Returns the cost of shipping for the cart. + +=cut + +sub calculateShipping { + my $self = shift; + + # get the shipper + my $shipper = eval { $self->getShipper }; + + # can't calculate shipping price without a valid shipper + if (WebGUI::Error->caught) { + return $self->formatCurrency(0); + } + + # do calculation + return $self->formatCurrency($shipper->calculate($self)); +} + +#------------------------------------------------------------------- + =head2 calculateSubtotal () Returns the subtotal of the items in the cart. @@ -79,6 +129,33 @@ sub calculateSubtotal { } +#------------------------------------------------------------------- + +=head2 calculateTaxes () + +Returns the tax amount on the items in the cart. + +=cut + +sub calculateTaxes { + my $self = shift; + my $tax = WebGUI::Shop::Tax->new($self->session); + return $self->formatCurrency($tax->calculate($self)); +} + +#------------------------------------------------------------------- + +=head2 calculateTotal ( ) + +Returns the total price of everything in the cart including tax, shipping, etc. + +=cut + +sub calculateTotal { + my ($self) = @_; + return $self->calculateSubtotal + $self->calculateShipping + $self->calculateTaxes; +} + #------------------------------------------------------------------- @@ -321,19 +398,6 @@ sub getShippingAddress { return $self->getAddressBook->getAddress($self->get("shippingAddressId")); } -#------------------------------------------------------------------- - -=head2 getTaxes () - -Returns the tax amount on the items in the cart. - -=cut - -sub getTaxes { - my $self = shift; - my $tax = WebGUI::Shop::Tax->new($self->session); - return $self->formatCurrency($tax->calculate($self)); -} #------------------------------------------------------------------- @@ -668,7 +732,7 @@ sub www_view { else { $var{hasShippingAddress} = 1; $var{shippingAddress} = $address->getHtmlFormatted; - $var{tax} = $self->getTaxes; + $var{tax} = $self->calculateTaxes; my $ship = WebGUI::Shop::Ship->new($self->session); my $options = $ship->getOptions($self); my %formOptions = (); @@ -680,8 +744,14 @@ sub www_view { $var{shippingOptions} = WebGUI::Form::selectBox($session, {name=>"shipperId", options=>\%formOptions, defaultValue=>$defaultOption, value=>$self->get("shipperId")}); $var{shippingPrice} = ($self->get("shipperId") ne "") ? $options->{$self->get("shipperId")}{price} : $options->{$defaultOption}{price}; $var{shippingPrice} = $self->formatCurrency($var{shippingPrice}); - } - $var{totalPrice} = $self->formatCurrency($var{subtotalPrice} + $var{shippingPrice} + $var{tax}); + } + + # calculate price adjusted for in-store credit + $var{totalPrice} = $var{subtotalPrice} + $var{shippingPrice} + $var{tax}; + my $credit = WebGUI::Shop::Credit->new($session); + $var{inShopCreditAvailable} = $credit->getSum; + $var{inShopCreditDeduction} = $credit->calculateDeduction($var{totalPrice}); + $var{totalPrice} = $self->formatCurrency($var{totalPrice} + $var{inShopCreditDeduction}); # render the cart my $template = WebGUI::Asset::Template->new($session, $session->setting->get("shopCartTemplateId")); diff --git a/lib/WebGUI/Shop/Credit.pm b/lib/WebGUI/Shop/Credit.pm index 90beb0059..84717f5a7 100644 --- a/lib/WebGUI/Shop/Credit.pm +++ b/lib/WebGUI/Shop/Credit.pm @@ -52,6 +52,27 @@ sub adjust { [$self->session->id->generate, $self->userId, $amount, $comment]); } +#------------------------------------------------------------------- + +=head2 calculateDeduction ( amount ) + +Returns the amount that a user's in-store credit could reduce a sale. Useful in calculating checkout prices. + +=head3 amount + +The amount of the sale before in-store credit is applied. + +=cut + +sub calculateDeduction { + my ($self, $amount) = @_; + my $credit = $self->getSum; + my $deduction = ($credit > $amount) ? $amount : $credit; + $deduction *= -1; + return sprintf("%.2f", $deduction); +} + + #------------------------------------------------------------------- =head2 getGeneralLedger ( session ) @@ -92,13 +113,13 @@ Returns the amount of credit that is owed to this user. sub getSum { my $self = shift; - my $credit = $self->session->db->getScalar("select sum(amount) from shopCredit where userId=? order by dateOfAdjustment",[$self->userId]); + my $credit = $self->session->db->quickScalar("select sum(amount) from shopCredit where userId=?",[$self->userId]); return sprintf("%.2f", $credit); } #------------------------------------------------------------------- -=head2 new ( session, userId ) +=head2 new ( session, [ userId ] ) Constructor. @@ -108,7 +129,7 @@ A reference to the current session. =head3 userId -A unique id for a user that you want to adjust the credit of. +A unique id for a user that you want to adjust the credit of. Defaults to the current user. =cut @@ -118,7 +139,7 @@ sub new { WebGUI::Error::InvalidObject->throw(expected=>"WebGUI::Session", got=>(ref $session), error=>"Need a session."); } unless (defined $userId) { - WebGUI::Error::InvalidParam->throw( param=>$userId, error=>"Need a userId."); + $userId = $session->user->userId; } my $self = register $class; my $id = id $self; diff --git a/lib/WebGUI/Shop/Pay.pm b/lib/WebGUI/Shop/Pay.pm index 6e04f57d5..b5d98f66d 100644 --- a/lib/WebGUI/Shop/Pay.pm +++ b/lib/WebGUI/Shop/Pay.pm @@ -347,6 +347,15 @@ sub www_selectPaymentGateway { $session->http->setRedirect( $session->url->page('shop=cart;method=view') ); return ''; } + + # Complete Transaction if it's a $0 transaction. + my $total = $cart->calculateTotal; + if (($total + $cart->calculateShopCreditDeduction($total)) == 0) { + my $transaction = WebGUI::Shop::Transaction->create($session, {cart => $cart}); + $transaction->completePurchase('zero', 'success', 'success'); + $cart->onCompletePurchase; + $transaction->www_thankYou($session); + } # All the output stuff below is just a placeholder until it's templated. my $output .= $i18n->echo('How would you like to pay?'); diff --git a/lib/WebGUI/Shop/PayDriver.pm b/lib/WebGUI/Shop/PayDriver.pm index 225c469a9..7e141fe96 100644 --- a/lib/WebGUI/Shop/PayDriver.pm +++ b/lib/WebGUI/Shop/PayDriver.pm @@ -161,7 +161,7 @@ sub definition { fieldType => 'group', label => $i18n->get('who can use'), hoverHelp => $i18n->get('who can use help'), - defaultValue => 1, + defaultValue => 7, }, receiptEmailTemplateId => { fieldType => 'template', diff --git a/lib/WebGUI/Shop/PayDriver/Cash.pm b/lib/WebGUI/Shop/PayDriver/Cash.pm index ccfcce9d6..2ac67ace1 100644 --- a/lib/WebGUI/Shop/PayDriver/Cash.pm +++ b/lib/WebGUI/Shop/PayDriver/Cash.pm @@ -128,7 +128,7 @@ sub getCartTemplateVariables { my $cartProperties = $cart->get; $cartProperties->{ totalPrice } = $cart->calculateSubtotal; - $cartProperties->{ tax } = $cart->getTaxes; + $cartProperties->{ tax } = $cart->calculateTaxes; # Include shipping address my $address = eval { $cart->getShippingAddress }; @@ -236,9 +236,9 @@ sub www_pay { my $billingAddress = $self->getBillingAddress( $session->scratch->get( 'ShopPayDriverCash_billingAddressId' ) ); # Complete the transaction - $self->processTransaction( $billingAddress ); + my $transaction = $self->processTransaction( $billingAddress ); - return $session->style->userStyle('Thank you for ordering'); + return $transaction->www_thankYou($session); } #------------------------------------------------------------------- diff --git a/lib/WebGUI/Shop/PayDriver/ITransact.pm b/lib/WebGUI/Shop/PayDriver/ITransact.pm index 808eeee58..1963b41d9 100644 --- a/lib/WebGUI/Shop/PayDriver/ITransact.pm +++ b/lib/WebGUI/Shop/PayDriver/ITransact.pm @@ -144,6 +144,30 @@ sub _generatePaymentRequestXML { } } + # taxes, shipping, etc + my $i18n = WebGUI::International->new($session, "Shop"); + if ($transaction->get('taxes') > 0) { + push @{ $orderItems->{ Item } }, { + Description => $i18n->get('taxes'), + Cost => $transaction->get('taxes'), + Qty => 1, + }; + } + if ($transaction->get('shippingPrice') > 0) { + push @{ $orderItems->{ Item } }, { + Description => $i18n->get('shipping'), + Cost => $transaction->get('shippingPrice'), + Qty => 1, + }; + } + if ($transaction->get('shopCreditDeduction') < 0) { + push @{ $orderItems->{ Item } }, { + Description => $i18n->get('in shop credit'), + Cost => $transaction->get('shopCreditDeduction'), + Qty => 1, + }; + } + my $vendorData; $vendorData->{ Element }->{ Name } = 'transactionId'; $vendorData->{ Element }->{ Value } = $transaction->getId; @@ -428,9 +452,9 @@ sub www_pay { return $self->www_getCredentials( $credentialsErrors ) if $credentialsErrors; # Payment time! - $self->processTransaction; + my $transaction = $self->processTransaction; - return $session->style->userStyle('Thank you for your order'); + return $transaction->www_thankYou($session); } 1; diff --git a/lib/WebGUI/Shop/Transaction.pm b/lib/WebGUI/Shop/Transaction.pm index 6927f367d..a2078cb32 100644 --- a/lib/WebGUI/Shop/Transaction.pm +++ b/lib/WebGUI/Shop/Transaction.pm @@ -88,6 +88,9 @@ The extended status message that came back from the payment gateway when trying sub completePurchase { my ($self, $transactionCode, $statusCode, $statusMessage) = @_; + if ($self->get('shopCreditDeduction') < 0) { + WebGUI::Shop::Credit->new($self->session)->adjust($self->get('shopCreditDeduction'), "Paid for transaction ".$self->getId); + } foreach my $item (@{$self->getItems}) { $item->getSku->onCompletePurchase($item); } @@ -313,7 +316,7 @@ A reference to a cart object. Will pull shipping method, shipping address, tax, it. Alternatively you can set manually any of the following properties that are set by cart automatically: amount shippingAddressId shippingAddressName shippingAddress1 shippingAddress2 shippingAddress3 shippingCity shippingState shippingCountry shippingCode shippingPhoneNumber shippingDriverId shippingDriverLabel shippingPrice -taxes +taxes shopCreditDeduction You can also use the addItem() method to manually add items to the transaction rather than passing a cart full of items. @@ -352,7 +355,7 @@ sub update { my $id = id $self; if (exists $newProperties->{cart}) { my $cart = $newProperties->{cart}; - $newProperties->{taxes} = $cart->getTaxes; + $newProperties->{taxes} = $cart->calculateTaxes; my $address = $cart->getShippingAddress; $newProperties->{shippingAddressId} = $address->getId; $newProperties->{shippingAddressName} = $address->get('name'); @@ -368,7 +371,9 @@ sub update { $newProperties->{shippingDriverId} = $shipper->getId; $newProperties->{shippingDriverLabel} = $shipper->get('label'); $newProperties->{shippingPrice} = $shipper->calculate($cart); - $newProperties->{amount} = $cart->calculateSubtotal + $newProperties->{shippingPrice} + $newProperties->{taxes}; + $newProperties->{amount} = $cart->calculateTotal + $newProperties->{shopCreditDeduction}; + $newProperties->{shopCreditDeduction} = $cart->calculateShopCreditDeduction($newProperties->{amount}); + $newProperties->{amount} += $newProperties->{shopCreditDeduction}; foreach my $item (@{$cart->getItems}) { $self->addItem({item=>$item}); } @@ -557,6 +562,20 @@ STOP return $admin->getAdminConsole->render($output, $i18n->get('transactions')); } + +#------------------------------------------------------------------- + +=head2 www_thankYou () + +Displays the default thank you page. + +=cut + +sub www_thankYou { + my ($class, $session) = @_; + return q{Thanks for your order. Need to template this.}; +} + #------------------------------------------------------------------- =head2 www_viewTransaction () diff --git a/lib/WebGUI/i18n/English/Shop.pm b/lib/WebGUI/i18n/English/Shop.pm index 75b125d32..0b7688ff0 100644 --- a/lib/WebGUI/i18n/English/Shop.pm +++ b/lib/WebGUI/i18n/English/Shop.pm @@ -195,6 +195,18 @@ our $I18N = { context => q|a label in the address editor| }, + 'available' => { + message => q|Available|, + lastUpdated => 0, + context => q|a label in the cart| + }, + + 'in shop credit' => { + message => q|In-Shop Credit|, + lastUpdated => 0, + context => q|a label in the cart| + }, + 'country' => { message => q|Country|, lastUpdated => 0,