Merge commit '41575d24bb' into webgui8. Some tests still failing.

Conflicts:
	docs/gotcha.txt
	lib/WebGUI.pm
	lib/WebGUI/Asset.pm
	lib/WebGUI/Asset/File/GalleryFile/Photo.pm
	lib/WebGUI/Asset/Post.pm
	lib/WebGUI/Asset/Template.pm
	lib/WebGUI/Asset/WikiPage.pm
	lib/WebGUI/Asset/Wobject/WikiMaster.pm
	lib/WebGUI/Cache.pm
	lib/WebGUI/Content/Setup.pm
	lib/WebGUI/Role/Asset/Subscribable.pm
	lib/WebGUI/Shop/Cart.pm
	lib/WebGUI/Shop/Pay.pm
	lib/WebGUI/Shop/PayDriver/ITransact.pm
	sbin/testEnvironment.pl
	t/Asset/WikiPage.t
	t/Shop/PayDriver.t
	t/Shop/PayDriver/ITransact.t
	t/Shop/PayDriver/Ogone.t
	t/Shop/TaxDriver/EU.t
	t/Shop/TaxDriver/Generic.t
	t/Workflow/Activity/RemoveOldCarts.t
	t/lib/WebGUI/Test.pm
This commit is contained in:
Colin Kuskie 2010-06-25 23:25:26 -07:00
commit 5febc0ebbc
258 changed files with 5528 additions and 2230 deletions

View file

@ -9,6 +9,7 @@ use WebGUI::Exception::Shop;
use WebGUI::Form;
use WebGUI::International;
use WebGUI::Shop::Address;
use Scalar::Util qw/blessed/;
=head1 NAME
@ -56,22 +57,87 @@ sub addAddress {
#-------------------------------------------------------------------
=head2 create ( session )
=head2 appendAddressFormVars ( $var, $properties, $prefix )
Constructor. Creates a new address book for this user or session if no user is logged in.
Add template variables for building a form to edit an address to an existing set of template variables.
=head3 $var
A hash ref of template variables.
=head3 $properties
A hash ref of properties to assign to as default to the form variables.
=head3 $prefix
An optional prefix to add to each variable name, and form name.
=cut
sub appendAddressFormVars {
my ($self, $var, $prefix, $properties ) = @_;
my $session = $self->session;
my $form = $session->form;
$properties ||= {};
$prefix ||= '';
$var ||= {};
for ( qw{ address1 address2 address3 label firstName lastName city state organization } ) {
$var->{ $prefix . $_ . 'Field' } = WebGUI::Form::text( $session, {
name => $prefix . $_,
maxlength => 35,
defaultValue => $properties->{ $_ } || $form->get($prefix . $_),
} );
}
$var->{ $prefix . 'countryField' } =
WebGUI::Form::country( $session,{
name => $prefix . 'country',
defaultValue => $properties->{ country } || $form->get($prefix . 'country' ),
} );
$var->{ $prefix . 'codeField' } =
WebGUI::Form::zipcode( $session, {
name => $prefix . 'code',
defaultValue => $properties->{ code } || $form->get($prefix . 'code' ),
} );
$var->{ $prefix . 'phoneNumberField' } =
WebGUI::Form::phone( $session, {
name => $prefix . 'phoneNumber',
defaultValue => $properties->{ phoneNumber } || $form->get($prefix . 'phoneNumber' ),
} );
$var->{ $prefix . 'emailField' } =
WebGUI::Form::email( $session, {
name => $prefix . 'email',
defaultValue => $properties->{ email } || $form->get($prefix . 'email' ),
} );
}
#-------------------------------------------------------------------
=head2 create ( session, userId )
Constructor. Creates a new address book for this user.
=head3 session
A reference to the current session.
=head3 userId
The userId for the user. Throws an exception if it is Visitor. Defaults to the session
user if omitted.
=cut
sub create {
my ($class, $session) = @_;
my ($class, $session, $userId) = @_;
unless (defined $session && $session->isa("WebGUI::Session")) {
WebGUI::Error::InvalidObject->throw(expected=>"WebGUI::Session", got=>(ref $session), error=>"Need a session.");
}
my $id = $session->db->setRow("addressBook", "addressBookId", {addressBookId=>"new", userId=>$session->user->userId, sessionId=>$session->getId});
$userId ||= $session->user->userId;
if ($userId eq '1') {
WebGUI::Error::InvalidParam->throw(error=>"Visitor cannot have an address book.");
}
my $id = $session->db->setRow("addressBook", "addressBookId", {addressBookId=>"new", userId=>$userId});
return $class->new($session, $id);
}
@ -157,6 +223,30 @@ sub getAddress {
#-------------------------------------------------------------------
=head2 getAddressByLabel ( label )
Returns an address object.
=head3 id
An address object's label, e.g. 'Home', 'Work'
=cut
sub getAddressByLabel {
my ($self, $label) = @_;
my $sql = q{
SELECT addressId
FROM address
WHERE addressBookId = ?
AND label = ?
};
my $id = $self->session->db->quickScalar($sql, [$self->getId, $label]);
return $id && $self->getAddress($id);
}
#-------------------------------------------------------------------
=head2 getAddresses ( )
Returns an array reference of address objects that are in this book.
@ -216,6 +306,36 @@ sub getId {
#-------------------------------------------------------------------
=head2 missingFields ( $address )
Returns a list of missing, required fields in this address.
=head3 $address
An address. If it's an WebGUI::Shop::Address object, it will use the data
from it. Otherwise, it will assume that $address is just a hashref.
=cut
sub missingFields {
my $self = shift;
my $address = shift;
my $addressData;
if (blessed $address && $address->isa('WebGUI::Shop::Address')) {
$addressData = $address->get();
}
else {
$addressData = $address;
}
my @missingFields = ();
FIELD: foreach my $field (qw/label firstName lastName address1 city code country phoneNumber/) {
push @missingFields, $field if $addressData->{$field} eq '';
}
return @missingFields;
}
#-------------------------------------------------------------------
=head2 new ( session, addressBookId )
Constructor. Instanciates an addressBook based upon a addressBookId.
@ -251,33 +371,36 @@ sub new {
#-------------------------------------------------------------------
=head2 newBySession ( session )
=head2 newByUserId ( session, userId )
Constructor. Creates a new address book for this user if they don't have one. If the user is not logged in creates an address book attached to the session if there isn't one for the session. In any case returns a reference to the address book.
Constructor. Creates a new address book for this user if they don't have one. In any case returns a reference to the address book.
=head3 session
A reference to the current session.
=head3 userId
The userId for the user. Throws an exception if it is Visitor. Defaults to the session
user if omitted.
=cut
sub newBySession {
my ($class, $session) = @_;
sub newByUserId {
my ($class, $session, $userId) = @_;
unless (defined $session && $session->isa("WebGUI::Session")) {
WebGUI::Error::InvalidObject->throw(expected=>"WebGUI::Session", got=>(ref $session), error=>"Need a session.");
}
my $userId = $session->user->userId;
$userId ||= $session->user->userId;
if ($userId eq '1') {
WebGUI::Error::InvalidParam->throw(error=>"Visitor cannot have an address book.");
}
# check to see if this user or his session already has an address book
my @ids = $session->db->buildArray("select addressBookId from addressBook where (userId<>'1' and userId=?) or sessionId=?",[$session->user->userId, $session->getId]);
my @ids = $session->db->buildArray("select addressBookId from addressBook where userId=?",[$userId]);
if (scalar(@ids) > 0) {
my $book = $class->new($session, $ids[0]);
# convert it to a specific user if we can
if ($userId ne '1') {
$book->update({userId => $userId, sessionId => ''});
}
# merge others if needed
if (scalar(@ids) > 1) {
# it's attached to the session or we have too many so lets merge them
@ -299,6 +422,46 @@ sub newBySession {
}
#-------------------------------------------------------------------
=head2 processAddressForm ( $prefix )
Process the current set of form variables for any belonging to the address book. Returns
a hash ref of address information.
=head3 $prefix
An optional prefix to be added to each form variable.
=cut
sub processAddressForm {
my ($self, $prefix) = @_;
$prefix ||= '';
my $form = $self->session->form;
my %addressData = (
label => $form->get($prefix . "label"),
firstName => $form->get($prefix . "firstName"),
lastName => $form->get($prefix . "lastName"),
address1 => $form->get($prefix . "address1"),
address2 => $form->get($prefix . "address2"),
address3 => $form->get($prefix . "address3"),
city => $form->get($prefix . "city"),
state => $form->get($prefix . "state"),
code => $form->get($prefix . "code", "zipcode"),
country => $form->get($prefix . "country", "country"),
phoneNumber => $form->get($prefix . "phoneNumber", "phone"),
email => $form->get($prefix . "email", "email"),
organization => $form->get($prefix . "organization"),
);
#my $label = $field eq 'address1' ? 'address'
# : $field eq 'phoneNumber' ? 'phone number'
# : $field
# ;
return %addressData;
}
#-------------------------------------------------------------------
=head2 update ( properties )
@ -313,10 +476,6 @@ A hash reference that contains one of the following:
Assign the user that owns this address book.
=head4 sessionId
Assign the session, by id, that owns this address book. Will automatically be set to "" if a user owns it.
=head4 defaultAddressId
The id of the address to be made the default for this address book.
@ -326,18 +485,56 @@ The id of the address to be made the default for this address book.
sub update {
my ($self, $newProperties) = @_;
my $id = id $self;
foreach my $field (qw(userId sessionId defaultAddressId)) {
foreach my $field (qw(userId defaultAddressId)) {
$properties{$id}{$field} = (exists $newProperties->{$field}) ? $newProperties->{$field} : $properties{$id}{$field};
}
##Having both a userId and sessionId will confuse create.
if ($properties{$id}{userId} ne "") {
$properties{$id}{sessionId} = "";
}
$self->session->db->setRow("addressBook","addressBookId",$properties{$id});
}
#-------------------------------------------------------------------
=head2 www_ajaxGetAddress ( )
Gets a JSON object representing the address given by the addressId form
parameter
=cut
sub www_ajaxGetAddress {
my $self = shift;
my $session = $self->session;
$session->http->setMimeType('text/plain');
my $addressId = $session->form->get('addressId');
my $address = $self->getAddress($addressId) or return;
return JSON->new->encode($address->get);
}
#-------------------------------------------------------------------
=head2 www_ajaxSave ( )
Saves an address book entry
=cut
sub www_ajaxSave {
my $self = shift;
my $session = $self->session;
my $address = JSON->new->decode($session->form->get('address'));
my $obj = $self->getAddressByLabel($address->{label});
if ($obj) {
$obj->update($address);
}
else {
$obj = $self->addAddress($address);
}
$session->http->setMimeType('text/plain');
return $obj->getId;
}
#-------------------------------------------------------------------
=head2 www_deleteAddress ( )
Deletes an address from the book.
@ -483,46 +680,11 @@ Saves the address. If there is a problem generates www_editAddress() with an err
sub www_editAddressSave {
my $self = shift;
my $form = $self->session->form;
my $i18n = WebGUI::International->new($self->session,"Shop");
if ($form->get("label") eq "") {
return $self->www_editAddress(sprintf($i18n->get('is a required field'), $i18n->get('label')));
}
if ($form->get("firstName") eq "") {
return $self->www_editAddress(sprintf($i18n->get('is a required field'), $i18n->get('firstName')));
}
if ($form->get("lastName") eq "") {
return $self->www_editAddress(sprintf($i18n->get('is a required field'), $i18n->get('lastName')));
}
if ($form->get("address1") eq "") {
return $self->www_editAddress(sprintf($i18n->get('is a required field'), $i18n->get('address')));
}
if ($form->get("city") eq "") {
return $self->www_editAddress(sprintf($i18n->get('is a required field'), $i18n->get('city')));
}
if ($form->get("code") eq "") {
return $self->www_editAddress(sprintf($i18n->get('is a required field'), $i18n->get('code')));
}
if ($form->get("country") eq "") {
return $self->www_editAddress(sprintf($i18n->get('is a required field'), $i18n->get('country')));
}
if ($form->get("phoneNumber") eq "") {
return $self->www_editAddress(sprintf($i18n->get('is a required field'), $i18n->get('phone number')));
}
my %addressData = (
label => $form->get("label"),
firstName => $form->get("firstName"),
lastName => $form->get("lastName"),
address1 => $form->get("address1"),
address2 => $form->get("address2"),
address3 => $form->get("address3"),
city => $form->get("city"),
state => $form->get("state"),
code => $form->get("code","zipcode"),
country => $form->get("country","country"),
phoneNumber => $form->get("phoneNumber","phone"),
email => $form->get("email","email"),
organization => $form->get("organization"),
);
my %addressData = $self->processAddressForm();
my @missingFields = $self->missingFields(\%addressData);
if (@missingFields) {
return $self->www_editAddress(pop @missingFields);
}
if ($form->get('addressId') eq '') {
$self->addAddress(\%addressData);
}

View file

@ -12,9 +12,11 @@ use WebGUI::Shop::AddressBook;
use WebGUI::Shop::CartItem;
use WebGUI::Shop::Credit;
use WebGUI::Shop::Ship;
use WebGUI::Shop::Pay;
use WebGUI::Shop::Tax;
use WebGUI::User;
use Tie::IxHash;
use Data::Dumper;
=head1 NAME
@ -38,7 +40,7 @@ These subroutines are available from this package:
readonly session => my %session;
private properties => my %properties;
private error => my %error;
public error => my %error;
private addressBookCache => my %addressBookCache;
#-------------------------------------------------------------------
@ -76,15 +78,11 @@ The amount to calculate the deduction against. Defaults to calculateTotal().
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
}
# cannot use in-shop credit on recurring items
return $self->formatCurrency(0) if $self->requiresRecurringPayment;
return $self->formatCurrency(WebGUI::Shop::Credit->new($self->session, $self->get('posUserId'))->calculateDeduction($total));
}
@ -263,13 +261,45 @@ sub getAddressBook {
my $self = shift;
my $id = id $self;
unless (exists $addressBookCache{$id}) {
$addressBookCache{$id} = WebGUI::Shop::AddressBook->newBySession($self->session);
$addressBookCache{$id} = WebGUI::Shop::AddressBook->newByUserId($self->session);
}
return $addressBookCache{$id};
}
#-------------------------------------------------------------------
=head2 getBillingAddress ()
Returns the WebGUI::Shop::Address object that is attached to this cart for billing.
=cut
sub getBillingAddress {
my $self = shift;
my $book = $self->getAddressBook;
if (my $addressId = $self->get("billingAddressId")) {
return $book->getAddress($addressId);
}
my $address = $book->getDefaultAddress;
$self->update({billingAddressId=>$address->getId});
return $address;
}
#-------------------------------------------------------------------
=head2 getPaymentGateway ()
Returns the WebGUI::Shop::PayDriver object that is attached to this cart for payment.
=cut
sub getPaymentGateway {
my $self = shift;
return WebGUI::Shop::Pay->new($self->session)->getPaymentGateway($self->get("gatewayId"));
}
#-------------------------------------------------------------------
=head2 getId ()
Returns the unique id for this cart.
@ -285,7 +315,9 @@ sub getId {
=head2 getItem ( itemId )
Returns a reference to a WebGUI::Shop::CartItem object.
Returns a reference to a WebGUI::Shop::CartItem object. Throws an WebGUI::Error::InvalidParam
exception if no itemId is passed, or if an invalid itemId is passed. It will not catch any
exceptions thrown by actually creating the CartItem, the caller of this method should do that.
=head3 itemId
@ -295,7 +327,7 @@ The id of the item to retrieve.
sub getItem {
my ($self, $itemId) = @_;
unless (defined $itemId && $itemId =~ m/^[A-Za-z0-9_-]{22}$/) {
unless (defined $itemId && $self->session->id->valid($itemId)) {
WebGUI::Error::InvalidParam->throw(error=>"Need an itemId.");
}
my $item = WebGUI::Shop::CartItem->new($self, $itemId);
@ -499,30 +531,76 @@ Returns whether all the required properties of the the cart are set.
sub readyForCheckout {
my $self = shift;
my $session = $self->session;
my $book = $self->getAddressBook;
# Check if the billing address is set and correct
my $address = eval{$self->getBillingAddress};
if (WebGUI::Error->caught) {
$self->error('no billing address');
return 0;
}
if (my @missingFields = $book->missingFields($address->get)) {
$self->error($missingFields[0]);
return 0;
}
# Check if the shipping address is set and correct
my $address = eval{$self->getShippingAddress};
return 0 if WebGUI::Error->caught;
my $shipAddress = eval{$self->getShippingAddress};
if (WebGUI::Error->caught) {
$self->error('no shipping address');
return 0;
}
if (my @missingFields = $book->missingFields($shipAddress->get)) {
$self->error($missingFields[0]);
return 0;
}
if ($self->requiresShipping) {
##Must have a configured shipping id.
if (! $self->get('shipperId')) {
$self->error('no shipping method set');
return 0;
}
my $shipper = eval { WebGUI::Shop::ShipDriver->new($session, $self->get('shipperId'))};
if (my $e = WebGUI::Error->caught) {
$self->error($e->error);
return 0;
}
}
# Check if the cart has items
return 0 unless scalar @{ $self->getItems };
# fail if there are multiple recurring items or if
# fail if there are multiple recurring items
return 0 if ($self->hasMixedItems);
# Check minimum cart checkout requirement
my $total = eval { $self->calculateTotal };
if (my $e = WebGUI::Error->caught) {
$error{id $self} = $e->error;
$self->error($e->error);
return 0;
}
my $requiredAmount = $self->session->setting->get( 'shopCartCheckoutMinimum' );
if ( $requiredAmount > 0 ) {
return 0 if $total < $requiredAmount;
if ( $requiredAmount > 0 && $total < $requiredAmount) {
$self->error('required amount not met in cart');
return 0;
}
##Must have a configured shipping id.
return 0 if ! $self->get('shipperId');
##Must have a configured payment method.
if (! $self->get('gatewayId')) {
$self->error('no payment gateway set');
return 0;
}
my $gateway = eval { WebGUI::Shop::PayDriver->new($session, $self->get('gatewayId'))};
if (my $e = WebGUI::Error->caught) {
$self->error($e->error);
return 0;
}
##Check for any other logged errors
return 0 if $error{ id $self };
@ -553,6 +631,26 @@ sub requiresRecurringPayment {
#-------------------------------------------------------------------
=head2 requiresShipping ( )
Returns whether any item in this cart requires shipping.
=cut
sub requiresShipping {
my $self = shift;
# Look for recurring items in the cart
foreach my $item (@{ $self->getItems }) {
return 1 if $item->getSku->isShippingRequired;
}
# No recurring items in cart so return false
return 0;
}
#-------------------------------------------------------------------
=head2 update ( properties )
Sets properties in the cart.
@ -565,6 +663,10 @@ A hash reference that contains one of the following:
The unique id for a shipping address attached to this cart.
=head4 billingAddressId
The unique id for a billing address attached to this cart.
=head4 shipperId
The unique id of the configured shipping driver that will be used to ship these goods.
@ -585,7 +687,7 @@ sub update {
WebGUI::Error::InvalidParam->throw(error=>"Need a properties hash ref.");
}
my $id = id $self;
foreach my $field (qw(shippingAddressId posUserId shipperId creationDate)) {
foreach my $field (qw(billingAddressId shippingAddressId posUserId gatewayId shipperId creationDate)) {
$properties{$id}{$field} = (exists $newProperties->{$field}) ? $newProperties->{$field} : $properties{$id}{$field};
}
$self->session->db->setRow("cart","cartId",$properties{$id});
@ -595,7 +697,7 @@ sub update {
=head2 updateFromForm ( )
Updates the cart totals.
Updates the cart totals, the address fields and the shipping and billing options from form data.
=cut
@ -613,49 +715,154 @@ sub updateFromForm {
$error{id $self} = "An unknown error has occured: ".$e->message;
}
}
if (my $itemAddressId = $form->get("itemAddress_".$item->getId)) {
$item->update({shippingAddressId => $itemAddressId});
}
}
if ($self->hasMixedItems) {
my $i18n = WebGUI::International->new($self->session, "Shop");
$error{id $self} = $i18n->get('mixed items warning');
}
my $book = $self->getAddressBook;
my $cartProperties = {};
$cartProperties->{ shipperId } = $form->process( 'shipperId' ) if $form->process( 'shipperId' );
my %billingData = $book->processAddressForm('billing_');
my @missingBillingFields = $book->missingFields(\%billingData);
my $billingAddressId = $form->process('billingAddressId');
if ($billingAddressId eq 'new_address' && ! @missingBillingFields) {
##Add a new address
my $newAddress = $book->addAddress(\%billingData);
$cartProperties->{billingAddressId} = $newAddress->get('addressId');
}
elsif ($billingAddressId eq 'update_address' && $self->get('billingAddressId') && ! @missingBillingFields) {
##User updated the current address
my $address = $self->getBillingAddress();
$address->update(\%billingData);
}
elsif ($billingAddressId ne 'new_address' && $billingAddressId) {
##User changed the address selector to another address field
$cartProperties->{billingAddressId} = $billingAddressId;
}
elsif (@missingBillingFields) {
$self->error('missing billing '.$missingBillingFields[0]);
}
else {
$self->session->log->warn('billing address: something else: ');
}
##Update now, so that you can add an address AND set the shipping address to be the same at the same time.
$self->update($cartProperties);
if ($self->requiresShipping) {
if ($form->process('sameShippingAsBilling', 'yesNo')) {
$cartProperties->{shippingAddressId} = $self->get('billingAddressId');
}
else {
my %shippingData = $book->processAddressForm('shipping_');
my @missingShippingFields = $book->missingFields(\%shippingData);
my $shippingAddressId = $form->process('shippingAddressId');
##No missing shipping fields, if we set to the same as the billing fields
if (@missingShippingFields) {
$self->error('missing shipping '.$missingShippingFields[0]);
}
if ($shippingAddressId eq 'new_address' && ! @missingShippingFields) {
##Add a new address
my $newAddress = $book->addAddress(\%shippingData);
$cartProperties->{shippingAddressId} = $newAddress->get('addressId');
}
elsif ($shippingAddressId eq 'update_address' && $self->get('shippingAddressId') && ! @missingShippingFields) {
##User changed the address selector
my $address = $self->getBillingAddress();
$address->update(\%shippingData);
}
elsif ($shippingAddressId ne 'new_address' && $shippingAddressId) {
$cartProperties->{shippingAddressId} = $shippingAddressId;
}
else {
$self->session->log->warn('shipping address: something else: ');
}
}
}
$cartProperties->{ shipperId } = $form->process( 'shipperId' ) if $form->process( 'shipperId' );
$cartProperties->{ gatewayId } = $form->process( 'gatewayId' ) if $form->process( 'gatewayId' );
$self->update( $cartProperties );
my @cartItemIds = $form->process('remove_item', 'checkList');
foreach my $cartItemId (@cartItemIds) {
my $item = eval { $self->getItem($cartItemId); };
$item->remove if ! Exception::Class->caught();
}
}
#-------------------------------------------------------------------
=head2 www_checkout ( )
=head2 www_ajaxPrices
Update the cart and then redirect the user to the payment gateway screen.
Input: shippingId (an addressId)
billingId (an addressId)
Output: {
tax : 1.25,
subtotal : 12.00,
shipping : {
slfjaldjfalfja: {
label : 'USPS',
price : 12.50,
hasPrice : 1 || 0
},
{ ... },
{ ... }
}
}
Takes an addressId and returns JSON shipping options for it, in the form .
=cut
sub www_checkout {
my $self = shift;
$self->updateFromForm;
if ($error{id $self} ne "") {
return $self->www_view;
}
$self->session->http->setRedirect($self->session->url->page('shop=pay;method=selectPaymentGateway'));
return undef;
sub www_ajaxPrices {
my $self = shift;
my $session = $self->session;
my $form = $session->form;
my $billing = $form->get('billingId');
my $shipping = $form->get('shippingId');
my $response = {
subtotal => $self->calculateSubtotal(),
tax => eval {
my $addr = $shipping || $billing or die;
$self->update({ shippingAddressId => $addr });
$self->calculateTaxes();
} || 0,
shipping => eval {
die unless $shipping;
$self->update({ shippingAddressId => $shipping });
my $ship = WebGUI::Shop::Ship->new($self->session);
$ship->getOptions($self);
} || [],
};
$session->http->setMimeType('text/plain');
return JSON->new->encode($response);
}
#-------------------------------------------------------------------
=head2 www_continueShopping ( )
=head2 www_ajaxSetCartItemShippingId
Update the cart and the return the user back to the asset.
Sets the shippingAddressId for a particular cartItem
=cut
sub www_continueShopping {
my $self = shift;
$self->updateFromForm;
if ($error{id $self} ne "") {
return $self->www_view;
}
return undef;
sub www_ajaxSetCartItemShippingId {
my $self = shift;
my $session = $self->session;
my $form = $session->form;
my $item = $self->getItem($form->get('itemId'));
my $address = $form->get('addressId') || undef;
$item && $item->update({ shippingAddressId => $address });
$session->http->setMimeType('text/plain');
return 'ok';
}
#-------------------------------------------------------------------
@ -683,53 +890,47 @@ sub www_lookupPosUser {
return $self->www_view;
}
#-------------------------------------------------------------------
=head2 www_removeItem ( )
Remove an item from the cart and then display the cart again.
=cut
sub www_removeItem {
my $self = shift;
my $item = $self->getItem($self->session->form->get("itemId"));
$item->remove;
return $self->www_view;
}
#-------------------------------------------------------------------
=head2 www_setShippingAddress ()
Sets the shipping address for the cart or for a cart item if itemId is one of the form params.
=cut
sub www_setShippingAddress {
my $self = shift;
my $form = $self->session->form;
if ($form->get("itemId") ne "") {
$self->getItem($form->get("itemId"))->update({shippingAddressId=>$form->get('addressId')});
}
else {
$self->update({shippingAddressId=>$form->get('addressId')});
}
return $self->www_view;
}
#-------------------------------------------------------------------
=head2 www_update ( )
Updates the cart totals and then displays the cart again.
Updates the cart totals, addresses, shipping driver and payment gateway. If requested, and the
cart is ready, calls the www_getCredentials method from the selected payment gateway.
If the cart total, after taxes, shipping, coupons and shop credit is zero, does the checkout
immediately without calling a payment gateway.
Otherwise, returns the user back to the cart.
=cut
sub www_update {
my $self = shift;
my $self = shift;
my $session = $self->session;
$self->updateFromForm;
if ($session->form->get('continue_shopping')) {
return undef;
}
elsif ($session->form->get('checkout')) {
##Setting a shipping address greatly simplifies the Transaction
if (! $self->requiresShipping && ! $self->get('shippingAddressId')) {
$self->update({shippingAddressId => $self->get('billingAddressId')});
}
if ($self->readyForCheckout()) {
my $total = $self->calculateTotal;
##Handle rounding errors, and checkout immediately if the amount is 0 since
##at least the ITransact driver won't accept $0 checkout.
if (sprintf('%.2f', $total + $self->calculateShopCreditDeduction($total)) eq '0.00') {
my $transaction = WebGUI::Shop::Transaction->create($session, {self => $self});
$transaction->completePurchase('zero', 'success', 'success');
$self->onCompletePurchase;
$transaction->sendNotifications();
return $transaction->thankYou();
}
my $gateway = $self->getPaymentGateway;
return $gateway->www_getCredentials;
}
}
return $self->www_view;
}
@ -742,28 +943,16 @@ Displays the shopping cart.
=cut
sub www_view {
my $self = shift;
my $self = shift;
my $session = $self->session;
my $url = $session->url;
my $i18n = WebGUI::International->new($session, "Shop");
my @items = ();
my $url = $session->url;
my $form = $session->form;
my $i18n = WebGUI::International->new($session, "Shop");
my $taxDriver = WebGUI::Shop::Tax->getDriver( $session );
if($url->forceSecureConnection()){
return "redirect";
}
# set up html header
$session->style->setRawHeadTags(q|
<script type="text/javascript">
function setCallbackForAddressChooser (form, itemId) {
form.shop.value='address';
form.method.value='view';
itemId = (itemId == undefined) ? 'null' : "'" + itemId + "'";
form.callback.value='{"url":"|.$url->page.q|","params":[{"name":"shop","value":"cart"},{"name":"method","value":"setShippingAddress"},{"name":"itemId","value":'+itemId+'}]}';
form.submit();
}
</script>
|);
my @cartItems = @{$self->getItems};
if(scalar(@cartItems) < 1) {
@ -776,133 +965,242 @@ sub www_view {
my $template = WebGUI::Asset::Template->newById($session, $session->setting->get("shopCartTemplateId"));
return $session->style->userStyle($template->process(\%var));
}
my %var = (
%{$self->get},
formHeader => WebGUI::Form::formHeader($session)
. WebGUI::Form::hidden($session, {name=>"shop", value=>"cart"})
. WebGUI::Form::hidden($session, {name=>"method", value=>"update"})
. WebGUI::Form::hidden($session, {name=>"itemId", value=>""})
,
formFooter => WebGUI::Form::formFooter($session),
updateButton => WebGUI::Form::submit($session, {value=>$i18n->get("update cart button"), id=>"updateCartButton"}),
checkoutButton => WebGUI::Form::submit($session, {name => 'checkout', value=>$i18n->get("checkout button"), id=>"checkoutButton"}),
continueShoppingButton => WebGUI::Form::submit($session, {
name => 'continue_shopping',
value => $i18n->get("continue shopping button"),
id => 'continueShoppingButton',
}),
minimumCartAmount => $session->setting->get( 'shopCartCheckoutMinimum' ) > 0
? sprintf( '%.2f', $session->setting->get( 'shopCartCheckoutMinimum' ) )
: 0
,
userIsVisitor => $session->user->isVisitor,
shippableItemsInCart => $self->requiresShipping,
);
# get the shipping address
my $address = eval { $self->getShippingAddress };
if (my $e = WebGUI::Error->caught("WebGUI::Error::ObjectNotFound") && $self->get('shippingAddressId')) {
# choose another address cuz we've got a problem
$self->update({shippingAddressId=>''});
}
# generate template variables for the items in the cart
my @items = ();
tie my %addressOptions, 'Tie::IxHash';
if (! $var{userIsVisitor}) {
my $addressBook = $self->getAddressBook;
my $addresses = $addressBook->getAddresses;
foreach my $address (@{ $addresses }) {
$addressOptions{$address->get('addressId')} = $address->get('label');
}
}
tie my %specialAddressOptions, 'Tie::IxHash';
$specialAddressOptions{''} = $i18n->get("Special shipping");
%specialAddressOptions = (%specialAddressOptions, %addressOptions);
foreach my $item (@cartItems) {
my $sku = $item->getSku;
$sku->applyOptions($item->get("options"));
my %properties = (
%{$item->get},
url => $sku->getUrl("shop=cart;method=viewItem;itemId=".$item->getId),
quantityField => WebGUI::Form::integer($session, {name=>"quantity-".$item->getId, value=>$item->get("quantity")}),
isUnique => ($sku->getMaxAllowedInCart == 1),
isShippable => $sku->isShippingRequired,
extendedPrice => $self->formatCurrency($sku->getPrice * $item->get("quantity")),
price => $self->formatCurrency($sku->getPrice),
removeButton => WebGUI::Form::submit($session, {value=>$i18n->get("remove button"),
extras=>q|onclick="this.form.method.value='removeItem';this.form.itemId.value='|.$item->getId.q|';this.form.submit;"|}),
shipToButton => WebGUI::Form::submit($session, {value=>$i18n->get("ship to button"),
extras=>q|onclick="setCallbackForAddressChooser(this.form,'|.$item->getId.q|');"|}),
);
my $address = eval {$item->getShippingAddress};
unless (WebGUI::Error->caught) {
$properties{shippingAddress} = $address->getHtmlFormatted;
url => $sku->getUrl("shop=cart;method=viewItem;itemId=".$item->getId),
quantityField => WebGUI::Form::integer($session, {name=>"quantity-".$item->getId, value=>$item->get("quantity"), size=>5,}),
isUnique => ($sku->getMaxAllowedInCart == 1),
isShippable => $sku->isShippingRequired,
extendedPrice => $self->formatCurrency($sku->getPrice * $item->get("quantity")),
price => $self->formatCurrency($sku->getPrice),
removeBox => WebGUI::Form::checkbox($session, {name => 'remove_item', value => $item->get('itemId')}),
);
my $itemAddress = eval {$item->getShippingAddress};
my $itemAddressId;
if ((!WebGUI::Error->caught) && $itemAddress && $address && $itemAddress->getId ne $address->getId) {
$properties{shippingAddress} = $itemAddress->getHtmlFormatted;
$itemAddressId = $itemAddress->getId;
}
else {
$properties{shippingAddress} = '';
$itemAddressId = '';
}
if (! $var{userIsVisitor} && @cartItems > 1) {
$properties{itemAddressChooser} = WebGUI::Form::selectBox($session, {
name => "itemAddress_".$item->getId,
value => $itemAddressId,
options => \%specialAddressOptions,
extras => q|class="itemAddressMenu"|,
});
}
$taxDriver->appendCartItemVars( \%properties, $item );
push(@items, \%properties);
}
my %var = (
%{$self->get},
items => \@items,
formHeader => WebGUI::Form::formHeader($session)
. WebGUI::Form::hidden($session, {name=>"shop", value=>"cart"})
. WebGUI::Form::hidden($session, {name=>"method", value=>"update"})
. WebGUI::Form::hidden($session, {name=>"itemId", value=>""})
. WebGUI::Form::hidden($session, {name=>"callback", value=>""}),
formFooter => WebGUI::Form::formFooter($session),
updateButton => WebGUI::Form::submit($session, {value=>$i18n->get("update cart button"), extras=>q|id="updateCartButton"|}),
checkoutButton => WebGUI::Form::submit($session, {value=>$i18n->get("checkout button"),
extras=>q|onclick="this.form.method.value='checkout';this.form.submit;" id="checkoutButton"|}),
continueShoppingButton => WebGUI::Form::submit($session, {value=>$i18n->get("continue shopping button"),
extras=>q|onclick="this.form.method.value='continueShopping';this.form.submit;" id="continueShoppingButton"|}),
chooseShippingButton => WebGUI::Form::submit($session, {value=>$i18n->get("choose shipping button"),
extras=>q|onclick="setCallbackForAddressChooser(this.form);" id="chooseAddressButton"|}),
shipToButton => WebGUI::Form::submit($session, {value=>$i18n->get("ship to button"),
extras=>q|onclick="setCallbackForAddressChooser(this.form);"|}),
subtotalPrice => $self->formatCurrency($self->calculateSubtotal()),
minimumCartAmount => $session->setting->get( 'shopCartCheckoutMinimum' ) > 0
? sprintf( '%.2f', $session->setting->get( 'shopCartCheckoutMinimum' ) )
: 0
,
);
# get the shipping address
my $address = eval { $self->getShippingAddress };
if (my $e = WebGUI::Error->caught("WebGUI::Error::ObjectNotFound")) {
# choose another address cuz we've got a problem
$self->update({shippingAddressId=>''});
}
# if there is no shipping address we can't check out
if (WebGUI::Error->caught) {
$var{shippingPrice} = $var{tax} = $self->formatCurrency(0);
}
# if there is a shipping address calculate tax and shipping options
else {
$var{hasShippingAddress} = 1;
$var{shippingAddress} = $address->getHtmlFormatted;
my $ship = WebGUI::Shop::Ship->new(session => $self->session);
$var{items} = \@items;
if ($var{shippableItemsInCart}) {
my $ship = WebGUI::Shop::Ship->new($self->session);
my $options = $ship->getOptions($self);
my $numberOfOptions = scalar keys %{ $options };
if ($numberOfOptions < 1) {
if (! $numberOfOptions) {
$var{shippingOptions} = '';
$var{shippingPrice} = 0;
$error{id $self} = $i18n->get("No shipping plugins configured");
}
elsif ($numberOfOptions == 1) {
my ($option) = keys %{ $options };
$self->update({ shipperId => $option });
$var{shippingPrice} = $options->{$self->get("shipperId")}->{price};
$var{shippingPrice} = $self->formatCurrency($var{shippingPrice});
$self->error($i18n->get("No shipping plugins configured"));
}
else {
tie my %formOptions, 'Tie::IxHash';
$formOptions{''} = $i18n->get('Choose a shipping method');
foreach my $option (keys %{$options}) {
$formOptions{$option} = $options->{$option}{label}." (".$self->formatCurrency($options->{$option}{price}).")";
foreach my $optionId (keys %{$options}) {
$formOptions{$optionId} = $options->{$optionId}{label};
if ($options->{$optionId}->{hasPrice}) {
$formOptions{$optionId} .= ' ('.$self->formatCurrency($options->{$optionId}{price}).')';
}
}
$var{shippingOptions} = WebGUI::Form::selectBox($session, {name=>"shipperId", options=>\%formOptions, value=>$self->get("shipperId")});
if (!exists $options->{$self->get('shipperId')}) {
my $shipperId = $self->get('shipperId');
if (!$shipperId && $numberOfOptions == 1) {
my ($option) = keys %{ $options };
$self->update({shipperId => $option});
$shipperId = $option;
}
$var{shippingOptions} = WebGUI::Form::selectBox($session, {name=>"shipperId", options=>\%formOptions, value=>$shipperId || ''});
if (!exists $options->{$shipperId}) {
$self->update({shipperId => ''});
$shipperId = '';
}
if (my $shipperId = $self->get('shipperId')) {
if ($shipperId) {
$var{shippingPrice} = $options->{$shipperId}->{price};
}
else {
$var{shippingPrice} = 0;
$error{id $self} = ($i18n->get('Choose a shipping method and update the cart to checkout'));
$self->error($i18n->get('Choose a shipping method and update the cart to checkout'));
}
$var{shippingPrice} = $self->formatCurrency($var{shippingPrice});
$var{shippingPrice} = $shipperId && $options->{$shipperId}->{hasPrice} ? $self->formatCurrency($var{shippingPrice}) : '';
$var{tax} = $self->calculateTaxes;
}
}
else {
$var{shippingPrice} = $var{tax} = $self->formatCurrency(0);
}
# Tax variables
$var{tax} = $self->calculateTaxes;
#Address form variables
if ($var{userIsVisitor}) {
$var{loginFormHeader} = WebGUI::Form::formHeader($session, {action => $session->url->page})
. WebGUI::Form::hidden($session,{ name => 'op', value => 'auth'})
. WebGUI::Form::hidden($session,{ name => 'method', value => 'login'})
;
$var{loginFormUsername} = WebGUI::Form::text($session, { name => 'username', size => 12, });
$var{loginFormPassword} = WebGUI::Form::password($session, { name => 'identifier', size => 12, });
$var{loginFormButton} = WebGUI::Form::submit($session, { value => $i18n->get(52,'WebGUI'), });
$var{registerLink} = $session->url->page('op=auth;method=createAccount');
$session->scratch->set('redirectAfterLogin', $session->url->page('shop=cart'));
$var{loginFormFooter} = WebGUI::Form::formFooter($session)
}
else {
##Address form variables
tie my %billingAddressOptions, 'Tie::IxHash';
$billingAddressOptions{'new_address'} = $i18n->get('Add new address');
my $billingAddressId = $self->get('billingAddressId');
if ($billingAddressId) {
$billingAddressOptions{'update_address'} = $i18n->get('Update this address');
}
%billingAddressOptions = (%billingAddressOptions, %addressOptions);
$var{'billingAddressChooser'} = WebGUI::Form::selectBox($session, {
name => 'billingAddressId',
options => \%billingAddressOptions,
value => $billingAddressId ? $billingAddressId : 'new_address',
});
tie my %shippingAddressOptions, 'Tie::IxHash';
$shippingAddressOptions{'new_address'} = $i18n->get('Add new address');
my $shippingAddressId = $self->get('shippingAddressId');
if ($shippingAddressId) {
$shippingAddressOptions{'update_address'} = $i18n->get('Update this address');
}
%shippingAddressOptions = (%shippingAddressOptions, %addressOptions);
$var{'shippingAddressChooser'} = WebGUI::Form::selectBox($session, {
name => 'shippingAddressId',
options => \%shippingAddressOptions,
value => $shippingAddressId ? $shippingAddressId : 'new_address',
});
my $shippingAddressData = $self->get('shippingAddressId') ? $self->getShippingAddress->get() : {};
my $billingAddressData = $self->get('billingAddressId') ? $self->getBillingAddress->get() : {};
my $addressBook = $self->getAddressBook;
$addressBook->appendAddressFormVars(\%var, 'shipping_', $shippingAddressData);
$addressBook->appendAddressFormVars(\%var, 'billing_', $billingAddressData);
$var{sameShippingAsBilling} = WebGUI::Form::yesNo($session, {
name => 'sameShippingAsBilling',
value => $self->get('billingAddressId') && $self->get('billingAddressId') eq $self->get('shippingAddressId'),
});
}
# Payment methods
my $pay = WebGUI::Shop::Pay->new($session);
tie my %paymentOptions, 'Tie::IxHash';
$paymentOptions{''} = $i18n->get('Choose a payment method');
my $gateways = $pay->getOptions($self);
while (my ($gatewayId, $label) = each %{ $gateways }) {
$paymentOptions{$gatewayId} = $label;
}
$var{paymentOptions} = WebGUI::Form::selectBox($session, {
name => 'gatewayId',
options => \%paymentOptions,
value => $self->get('gatewayId') || $form->get('gatewayId') || '',
});
# POS variables
$var{isCashier} = WebGUI::Shop::Admin->new($session)->isCashier;
$var{isCashier} = WebGUI::Shop::Admin->new($session)->isCashier;
$var{posLookupForm} = WebGUI::Form::email($session, {name=>"posEmail"})
.WebGUI::Form::submit($session, {value=>$i18n->get('search for email'),
extras=>q|onclick="this.form.method.value='lookupPosUser';this.form.submit;"|});
my $posUser = $self->getPosUser;
my $posUser = $self->getPosUser;
$var{posUsername} = $posUser->username;
$var{posUserId} = $posUser->userId;
$var{posUserId} = $posUser->userId;
# calculate price adjusted for in-store credit
$var{totalPrice} = $var{subtotalPrice} + $var{shippingPrice} + $var{tax};
$var{subtotalPrice} = $self->formatCurrency($self->calculateSubtotal());
$var{totalPrice} = $var{subtotalPrice} + $var{shippingPrice} + $var{tax};
my $credit = WebGUI::Shop::Credit->new($session, $posUser->userId);
$var{ inShopCreditAvailable } = $credit->getSum;
$var{ inShopCreditDeduction } = $credit->calculateDeduction($var{totalPrice});
$var{ totalPrice } = $self->formatCurrency($var{totalPrice} + $var{inShopCreditDeduction});
$var{ readyForCheckout } = $self->readyForCheckout;
$var{ error } = $error{id $self};
foreach my $field (qw/subtotalPrice inShopCreditAvailable inShopCreditDeduction totalPrice shippingPrice tax/) {
$var{$field} = sprintf q|<span id="%sWrap">%s</span>|, $field, $var{$field};
}
$var{ error } = $self->error;
# render the cart
my $template = WebGUI::Asset::Template->newById($session, $session->setting->get("shopCartTemplateId"));
my $template = WebGUI::Asset->newById($session, $session->setting->get("shopCartTemplateId"));
my $style = $session->style;
my $yui = $url->extras('/yui/build');
$style->setScript("$yui/yahoo/yahoo-min.js");
$style->setScript("$yui/json/json-min.js");
$style->setScript("$yui/event/event-min.js");
$style->setScript("$yui/connection/connection-min.js");
$style->setScript($url->extras('underscore/underscore-min.js'));
$style->setScript($url->extras('shop/cart.js'), undef, 1);
return $session->style->userStyle($template->process(\%var));
}

View file

@ -130,9 +130,9 @@ sub getDrivers {
=head2 getOptions ( $cart )
Returns a set of options for the user to pay to. It is a hash of
hashrefs, with the key of the primary hash being the paymentGatewayId
of the driver, and sub keys of label and button. The hash will only
contain payment gateways that this user is allowed to use.
gatewayIds and labels.
The hash will only contain payment gateways that this user is allowed to use.
=head3 $cart
@ -146,17 +146,13 @@ sub getOptions {
WebGUI::Error::InvalidParam->throw(error => q{Need a cart.}) unless defined $cart and $cart->isa("WebGUI::Shop::Cart");
my $session = $cart->session;
my $recurringRequired = $cart->requiresRecurringPayment;
my %options = ();
foreach my $gateway (@{ $self->getPaymentGateways() }) {
next unless $gateway->canUse;
if (!$recurringRequired || $gateway->handlesRecurring) {
$options{$gateway->getId} = {
label => $gateway->get("label"),
button => $gateway->getButton( $cart ),
};
$options{$gateway->getId} = $gateway->get("label");
}
}
return \%options;
@ -366,68 +362,4 @@ sub www_manage {
return $console->render($output, $i18n->get("payment methods"));
}
#-------------------------------------------------------------------
=head2 www_selectPaymentGateway ( )
The screen in which a customer chooses a payment gateway.
TODO: Template this screen.
=cut
sub www_selectPaymentGateway {
my $self = shift;
my $session = $self->session;
my $cart = WebGUI::Shop::Cart->newBySession( $session );
my $i18n = WebGUI::International->new( $session, 'Shop' );
# Make sure the user is logged in.
if ($session->user->isVisitor) {
$session->scratch->set( 'redirectAfterLogin', $session->url->page('shop=pay;method=selectPaymentGateway') );
# We cannot use WebGUI::Operation::execute( $session, 'auth'); because the method form param used by the
# Shop contenthandler overrides the method param used by WG::Op::Auth
$session->http->setRedirect( $session->url->page('op=auth;method=init') );
# If the redirect fails make sure people can still go to the login screen by giving them a link
return $session->style->userStyle(
sprintf $i18n->get('login message'), $session->url->page('op=auth;method=init')
);
}
# Check if the cart is ready for checkout
unless ($cart->readyForCheckout) {
$session->http->setRedirect( $session->url->page('shop=cart;method=view') );
return '';
}
# Complete Transaction if it's a $0 transaction.
my $total = $cart->calculateTotal;
if (sprintf('%.2f', $total + $cart->calculateShopCreditDeduction($total)) eq '0.00') {
my $transaction = WebGUI::Shop::Transaction->create($session, {cart => $cart});
$transaction->completePurchase('zero', 'success', 'success');
$cart->onCompletePurchase;
$transaction->sendNotifications();
return $transaction->thankYou();
}
# All the output stuff below is just a placeholder until it's templated.
my $payOptions = $self->getOptions( $cart );
# TODO: If only one payOption exists, just send us there
# In order to do this, the PayDriver must give us a direct URL to go to
my $var;
my @paymentGateways;
foreach my $payOption ( values %{$payOptions} ) {
push @paymentGateways, $payOption;
}
$var->{ paymentGateways } = \@paymentGateways;
$var->{ choose } = $i18n->get('choose payment gateway message');
my $template = WebGUI::Asset::Template->newById($session, $session->setting->get("selectGatewayTemplateId"));
return $session->style->userStyle($template->process($var));
}
1;

View file

@ -80,6 +80,33 @@ sub _buildObj {
}
#-------------------------------------------------------------------
=head2 appendCartVariables ( $var )
Append the subtotal, shipping, tax, and shop credeductions to a set of template
variables.
=cut
sub appendCartVariables {
my ($self, $var) = @_;
$var ||= {};
my $cart = $self->getCart;
$var->{shippableItemsInCart} = $cart->requiresShipping;
$var->{subtotal} = $cart->calculateSubtotal;
$var->{shipping} = $cart->calculateShipping;
$var->{taxes} = $cart->calculateTaxes;
my $totalPrice = $var->{subtotal} + $var->{shipping} + $var->{taxes};
my $session = $self->session;
my $credit = WebGUI::Shop::Credit->new($session, $cart->getPosUser->userId);
$var->{inShopCreditAvailable} = $credit->getSum;
$var->{inShopCreditDeduction} = $credit->calculateDeduction($var->{totalPrice});
$var->{totalPrice } = $cart->formatCurrency($totalPrice + $var->{inShopCreditDeduction});
return $self;
}
#-------------------------------------------------------------------
=head2 cancelRecurringPayment ( transaction )
@ -340,12 +367,13 @@ sub getAddress {
=head2 getButton ( )
Returns the form that will take the user to check out.
Used for the generic, vanilla checkout form. Must be overridden by any methods that
use the default www_getCredentials.
=cut
sub getButton {
my $self = shift;
return '';
}
#-------------------------------------------------------------------
@ -358,9 +386,7 @@ Returns the WebGUI::Shop::Cart object for the current session.
sub getCart {
my $self = shift;
my $cart = WebGUI::Shop::Cart->newBySession( $self->session );
return $cart;
}
@ -463,51 +489,6 @@ sub getName {
#-------------------------------------------------------------------
=head2 getSelectAddressButton ( returnMethod, [ buttonLabel ] )
Generates a button for selecting an address.
=head3 returnMethod
The name of the www_ method the selected addressId should be returned to. Without the 'www_' part.
=head3 buttonLabel
The label for the button, defaults to the internationalized version of 'Choose billing address'.
=cut
sub getSelectAddressButton {
my $self = shift;
my $returnMethod = shift;
my $buttonLabel = shift || 'Choose billing address';
my $session = $self->session;
# Generate the json string that defines where the address book posts the selected address
my $callbackParams = {
url => $session->url->page,
params => [
{ name => 'shop', value => 'pay' },
{ name => 'method', value => 'do' },
{ name => 'do', value => $returnMethod },
{ name => 'paymentGatewayId', value => $self->getId },
],
};
my $callbackJson = JSON::to_json( $callbackParams );
# Generate 'Choose billing address' button
my $addressButton = WebGUI::Form::formHeader( $session )
. WebGUI::Form::hidden( $session, { name => 'shop', value => 'address' } )
. WebGUI::Form::hidden( $session, { name => 'method', value => 'view' } )
. WebGUI::Form::hidden( $session, { name => 'callback', value => $callbackJson } )
. WebGUI::Form::submit( $session, { value => $buttonLabel } )
. WebGUI::Form::formFooter( $session );
return $addressButton;
}
#-------------------------------------------------------------------
=head2 handlesRecurring ()
Returns 0. Should be overridden to return 1 by any subclasses that can handle recurring payments.
@ -581,6 +562,35 @@ sub processPayment {
=head2 processPropertiesFromFormPost ( )
Updates pay driver with data from Form.
=cut
sub processTemplate {
my $self = shift;
my $session = $self->session;
my $templateId = shift;
my $var = shift;
my $i18n = WebGUI::International->new($session, 'PayDriver');
my $template = eval { WebGUI::Asset->newById($session, $templateId); };
my $output;
if (!Exception::Class->caught) {
$template->prepare;
$output = $template->process($var);
}
else {
$output = $i18n->get('template gone');
}
return $output;
}
#-------------------------------------------------------------------
=head2 processPropertiesFromFormPost ( )
Updates ship driver with data from Form.
=cut
@ -637,7 +647,6 @@ sub processTransaction {
my $transactionProperties;
$transactionProperties->{ paymentMethod } = $self;
$transactionProperties->{ cart } = $cart;
$transactionProperties->{ paymentAddress } = $paymentAddress if defined $paymentAddress;
$transactionProperties->{ isRecurring } = $cart->requiresRecurringPayment;
# Create a transaction...
@ -708,6 +717,31 @@ a GUID.
#-------------------------------------------------------------------
=head2 www_getCredentials ( )
Displays a summary of the cart, and a button to checkout. Plugins that need to get additional
information, or perform additional checks, should override this method. Uses the getButton
method to create the checkout button.
=cut
sub www_getCredentials {
my ($self) = @_;
my $session = $self->session;
# Generate 'Proceed' button
my $i18n = WebGUI::International->new($session, 'PayDriver_Cash');
my $var = {
proceedButton => $self->getButton,
};
$self->appendCartVariables($var);
my $output = $self->processTemplate($self->get("summaryTemplateId"), $var);
return $session->style->userStyle($output);
}
#-------------------------------------------------------------------
=head2 www_edit ( )
Generates an edit form.

View file

@ -56,6 +56,15 @@ sub definition {
my $i18n = WebGUI::International->new($session, 'PayDriver_Cash');
tie my %fields, 'Tie::IxHash';
%fields = (
summaryTemplateId => {
fieldType => 'template',
label => $i18n->get('summary template'),
hoverHelp => $i18n->get('summary template help'),
namespace => 'Shop/Credentials',
defaultValue => '30h5rHxzE_Q0CyI3Gg7EJw',
},
);
push @{ $definition }, {
name => $i18n->get('label'),
@ -69,21 +78,21 @@ sub definition {
=head2 getButton ( )
Returns the HTML for a form containing a button that, when clicked, will take the user to the checkout screen of
this plugin.
Return a form with button to finalize checkout from the Shop.
=cut
sub getButton {
my $self = shift;
my ($self) = @_;
my $session = $self->session;
my $payForm = WebGUI::Form::formHeader($session)
. $self->getDoFormTags('getCredentials')
. WebGUI::Form::submit($session, {value => $self->get('label') })
. WebGUI::Form::formFooter($session);
return $payForm;
# Generate 'Proceed' button
my $i18n = WebGUI::International->new($session, 'PayDriver_Cash');
return WebGUI::Form::formHeader( $session )
. $self->getDoFormTags('pay')
. WebGUI::Form::submit( $session, { value => $i18n->get('Pay') } )
. WebGUI::Form::formFooter( $session)
;
}
#-------------------------------------------------------------------
@ -100,64 +109,6 @@ sub processPayment {
#-------------------------------------------------------------------
=head2 www_getCredentials ( [ addressId ] )
Displays the checkout form for this plugin.
=head3 addressId
Optionally supply this variable which will set the payment address to this addressId.
=cut
sub www_getCredentials {
my ($self, $addressId) = @_;
my $session = $self->session;
# Process address from address book if passed
$addressId = $session->form->process( 'addressId' );
my $address;
if ( $addressId ) {
$address = eval{ $self->getAddress( $addressId ) };
}
else {
$address = $self->getCart->getShippingAddress;
}
my $billingAddressHtml = $address->getHtmlFormatted;
# Generate the json string that defines where the address book posts the selected address
my $callbackParams = {
url => $session->url->page,
params => [
{ name => 'shop', value => 'pay' },
{ name => 'method', value => 'do' },
{ name => 'do', value => 'setBillingAddress' },
{ name => 'paymentGatewayId', value => $self->getId },
],
};
my $callbackJson = JSON::to_json( $callbackParams );
# Generate 'Choose billing address' button
my $addressButton = WebGUI::Form::formHeader( $session )
. WebGUI::Form::hidden( $session, { name => 'shop', value => 'address' } )
. WebGUI::Form::hidden( $session, { name => 'method', value => 'view' } )
. WebGUI::Form::hidden( $session, { name => 'callback', value => $callbackJson } )
. WebGUI::Form::submit( $session, { value => 'Choose billing address' } )
. WebGUI::Form::formFooter( $session);
# Generate 'Proceed' button
my $proceedButton = WebGUI::Form::formHeader( $session )
. $self->getDoFormTags('pay')
. WebGUI::Form::hidden($session, {name=>"addressId", value=>$address->getId})
. WebGUI::Form::submit( $session, { value => 'Pay' } )
. WebGUI::Form::formFooter( $session);
return $session->style->userStyle($addressButton.'<br />'.$billingAddressHtml.'<br />'.$proceedButton);
}
#-------------------------------------------------------------------
=head2 www_pay ( )
Checks credentials, and completes the transaction if those are correct.
@ -166,36 +117,14 @@ Checks credentials, and completes the transaction if those are correct.
sub www_pay {
my $self = shift;
my $session = $self->session;
my $cart = $self->getCart;
my $i18n = WebGUI::International->new($session, 'PayDriver_Cash');
my $var;
# Make sure we can checkout the cart
return "" unless $self->canCheckoutCart;
# Make sure all required credentials have been supplied
my $billingAddress = $self->getAddress( $session->form->process('addressId') );
return $self->www_getCredentials unless $billingAddress;
# Complete the transaction
my $transaction = $self->processTransaction( $billingAddress );
my $transaction = $self->processTransaction( );
return $transaction->thankYou();
}
#-------------------------------------------------------------------
=head2 www_setBillingAddress {
Stores the selected billing address in this instance.
=cut
sub www_setBillingAddress {
my $self = shift;
my $session = $self->session;
return $self->www_getCredentials($session->form->process('addressId'));
}
1;

View file

@ -61,7 +61,7 @@ sub _generatePaymentRequestXML {
my $self = shift;
my $transaction = shift;
my $session = $self->session;
my $paymentAddress = $self->{ _billingAddress };
my $paymentAddress = $self->getCart->getBillingAddress->get();
my $cardData = $self->{ _cardData };
# Set up the XML.
@ -472,27 +472,6 @@ sub doXmlRequest {
#-------------------------------------------------------------------
=head2 getButton
Return a form to select this payment driver and to accept credentials from those
who wish to use it.
=cut
sub getButton {
my $self = shift;
my $session = $self->session;
my $payForm = WebGUI::Form::formHeader($session)
. $self->getDoFormTags('getCredentials')
. WebGUI::Form::submit($session, {value => $self->get('label') })
. WebGUI::Form::formFooter($session);
return $payForm;
}
#-------------------------------------------------------------------
=head2 handlesRecurring
Tells the commerce system that this payment plugin can handle recurring payments.
@ -519,19 +498,6 @@ sub processCredentials {
my $i18n = WebGUI::International->new($session,'PayDriver_ITransact');
my @error;
# Check address data
push @error, $i18n->get( 'invalid firstName' ) unless $form->process( 'firstName' );
push @error, $i18n->get( 'invalid lastName' ) unless $form->process( 'lastName' );
push @error, $i18n->get( 'invalid address' ) unless $form->process( 'address' );
push @error, $i18n->get( 'invalid city' ) unless $form->process( 'city' );
push @error, $i18n->get( 'invalid email' ) unless $form->email ( 'email' );
push @error, $i18n->get( 'invalid zip' )
if ( !$form->zipcode( 'zipcode' ) && $form->process( 'country' ) eq 'United States' );
# Check credit card data
push @error, $i18n->get( 'invalid card number' ) unless $form->integer('cardNumber');
push @error, $i18n->get( 'invalid cvv2' ) if ($self->get('useCVV2') && !$form->integer('cvv2'));
# Check if expDate and expYear have sane values
my ($currentYear, $currentMonth) = $self->session->datetime->localtime;
my $expires = $form->integer( 'expYear' ) . sprintf '%02d', $form->integer( 'expMonth' );
@ -549,66 +515,11 @@ sub processCredentials {
cvv2 => $form->integer( 'cvv2' ),
};
$self->{ _billingAddress } = {
address1 => $form->process( 'address' ),
code => $form->zipcode( 'zipcode' ),
city => $form->process( 'city' ),
firstName => $form->process( 'firstName' ),
lastName => $form->process( 'lastName' ),
email => $form->email ( 'email' ),
state => $form->process( 'state' ),
country => $form->process( 'country' ),
phoneNumber => $form->process( 'phone' ),
};
return;
}
#-------------------------------------------------------------------
=head2 getBillingAddress ( $addressId )
The billing address is not handled by WebGUI::Shop::Address, it comes from
www_getCredentials. However, WebGUI::Shop::Transaction requires an
WebGUI::Shop::Address object. The billing address is seeded with information
from the shipping address. If this address info is different, then create
a new address to hand to Transaction.
=head3 $addressId
The id of a WebGUI::Shop::Address. If not present, then use the shipping
address instead.
=cut
sub getBillingAddress {
my ($self, $addressId) = @_;
my $address = $addressId
? $self->getAddress( $addressId )
: $self->getCart->getShippingAddress
;
##If the user made any changes to the default address, create a new billing address
##and use it instead
if( $address->get('firstName' ) ne $self->{_billingAddress}->{ 'firstName' }
|| $address->get('lastName' ) ne $self->{_billingAddress}->{ 'lastName' }
|| $address->get('address1' ) ne $self->{_billingAddress}->{ 'address1' }
|| $address->get('city' ) ne $self->{_billingAddress}->{ 'city' }
|| $address->get('state' ) ne $self->{_billingAddress}->{ 'state' }
|| $address->get('code' ) ne $self->{_billingAddress}->{ 'code' }
|| $address->get('country' ) ne $self->{_billingAddress}->{ 'country' }
|| $address->get('phoneNumber' ) ne $self->{_billingAddress}->{ 'phoneNumber' }
|| $address->get('email' ) ne $self->{_billingAddress}->{ 'email' }
) {
my $billingAddress = $self->getCart->getAddressBook->addAddress( $self->{_billingAddress} );
return $billingAddress;
}
return $address;
}
#-------------------------------------------------------------------
=head2 processPayment ($transaction)
Contact ITransact and submit the payment data to them for processing.
@ -725,18 +636,7 @@ sub www_getCredentials {
my $session = $self->session;
my $form = $session->form;
my $i18n = WebGUI::International->new($self->session, 'PayDriver_ITransact');
my $u = WebGUI::User->new($self->session,$self->session->user->userId);
# Process address from address book if passed
my $addressId = $session->form->process( 'addressId' );
my $addressData;
if ( $addressId ) {
$addressData = eval{ $self->getAddress( $addressId )->get() } || {};
}
else {
$addressData = $self->getCart->getShippingAddress->get;
}
my $var = {};
# Process form errors
@ -748,55 +648,11 @@ sub www_getCredentials {
}
}
$var->{getSelectAddressButton} = $self->getSelectAddressButton( 'getCredentials' );
$var->{formHeader} = WebGUI::Form::formHeader($session)
. $self->getDoFormTags('pay');
if ($var->{formHeader}) {
$var->{formHeader} .= WebGUI::Form::hidden($session, {name => 'addressId', value => $addressId});
}
$var->{formFooter} = WebGUI::Form::formFooter();
# Address data form
$var->{firstNameField} = WebGUI::Form::text($session, {
name => 'firstName',
value => $form->process("firstName") || $addressData->{ "firstName" } || $u->profileField('firstName'),
});
$var->{lastNameField} = WebGUI::Form::text($session, {
name => 'lastName',
value => $form->process("lastName") || $addressData->{ "lastName" } || $u->profileField('lastName'),
});
$var->{addressField} = WebGUI::Form::text($session, {
name => 'address',
value => $form->process("address") || $addressData->{ address1 } || $u->profileField('homeAddress'),
});
$var->{cityField} = WebGUI::Form::text($session, {
name => 'city',
value => $form->process("city") || $addressData->{ city } || $u->profileField('homeCity'),
});
$var->{stateField} = WebGUI::Form::text($session, {
name => 'state',
value => $form->process("state") || $addressData->{ state } || $u->profileField('homeState'),
});
$var->{codeField} = WebGUI::Form::zipcode($session, {
name => 'zipcode',
value => $form->process("zipcode") || $addressData->{ code } || $u->profileField('homeZip'),
});
$var->{countryField} = WebGUI::Form::country($session, {
name => 'country',
value => ($form->process("country",'country', '') || $addressData->{ country } || $u->profileField("homeCountry") || 'United States of A'),
});
$var->{phoneField} = WebGUI::Form::phone($session, {
name => 'phone',
value => $form->process("phone",'phone') || $addressData->{ phoneNumber } || $u->profileField("homePhone"),
});
$var->{emailField} = WebGUI::Form::email($session, {
name => 'email',
value => $form->process('email', 'email') || $addressData->{ email } || $u->profileField('email'),
});
# Credit card information
$var->{cardNumberField} = WebGUI::Form::text($session, {
name => 'cardNumber',
@ -814,17 +670,9 @@ sub www_getCredentials {
value => $i18n->get('checkout button', 'Shop'),
extras => 'onclick="this.disabled=true;this.form.submit(); return false;"',
});
$self->appendCartVariables($var);
my $template = eval { WebGUI::Asset::Template->newById($session, $self->get("credentialsTemplateId")); };
my $output;
if (! Exception::Class->caught()) {
$template->prepare;
$output = $template->process($var);
}
else {
$output = $i18n->get('template gone');
}
my $output = $self->processTemplate($self->get("credentialsTemplateId"), $var);
return $session->style->userStyle($output);
}
@ -847,16 +695,8 @@ sub www_pay {
# Go back to checkout form if credentials are not ok
return $self->www_getCredentials( $credentialsErrors ) if $credentialsErrors;
my $addressId = $session->form->process( 'addressId' );
my $billingAddress = $self->getBillingAddress($addressId);
# Payment time!
my $transaction = $self->processTransaction( $billingAddress );
## The billing address object is temporary, just to send to the transaction.
## Delete it if we don't need it.
if ($billingAddress->getId ne $addressId) {
$billingAddress->delete;
}
my $transaction = $self->processTransaction( );
if ($transaction->get('isSuccessful')) {
return $transaction->thankYou();
}

View file

@ -102,6 +102,13 @@ sub definition {
hoverHelp => $i18n->get('use test mode help'),
defaultValue => 1,
},
summaryTemplateId => {
fieldType => 'template',
label => $i18n->get('summary template'),
hoverHelp => $i18n->get('summary template help'),
namespace => 'Shop/Credentials',
defaultValue => 'jysVZeUR0Bx2NfrKs5sulg',
},
);
push @{ $definition }, {
@ -114,28 +121,6 @@ sub definition {
#-------------------------------------------------------------------
=head2 getButton ( )
Returns the HTML for a form containing a button that, when clicked, will take the user to the checkout screen of
this plugin.
=cut
sub getButton {
my $self = shift;
my $session = $self->session;
my $i18n = WebGUI::International->new($session, 'PayDriver_Ogone');
my $payForm = WebGUI::Form::formHeader($session)
. $self->getDoFormTags('getCredentials')
. WebGUI::Form::submit($session, {value => $i18n->get('Ogone') })
. WebGUI::Form::formFooter($session);
return $payForm;
}
#-------------------------------------------------------------------
=head2 getCart
Returns the cart for either the current user or the transaction passed back by Ogone.
@ -273,80 +258,6 @@ sub ogoneCheckoutButton {
#-------------------------------------------------------------------
=head2 www_getCredentials ( [ addressId ] )
Displays the checkout form for this plugin.
=head3 addressId
Optionally supply this variable which will set the payment address to this addressId.
=cut
sub www_getCredentials {
my ($self, $addressId) = @_;
my $session = $self->session;
my $i18n = WebGUI::International->new( $session, 'PayDriver_Ogone' );
# Process address from address book if passed
$addressId = $session->form->process( 'addressId' );
my $address;
if ( $addressId ) {
$address = eval{ $self->getAddress( $addressId ) };
}
else {
$address = $self->getCart->getShippingAddress;
}
my $billingAddressHtml = $address->getHtmlFormatted;
# Fetch transaction
my $transactionId = $session->form->process('transactionId');
my $transaction;
if ($transactionId) {
$transaction = WebGUI::Shop::Transaction->new( $session, $transactionId );
}
# Or generate a new one
unless ($transaction) {
$transaction = $self->processTransaction( $address );
}
# Set the billing address
$transaction->update( {
paymentAddress => $address,
} );
# Generate the json string that defines where the address book posts the selected address
my $callbackParams = {
url => $session->url->page,
params => [
{ name => 'shop', value => 'pay' },
{ name => 'method', value => 'do' },
{ name => 'do', value => 'getCredentials' },
{ name => 'paymentGatewayId', value => $self->getId },
],
};
my $callbackJson = JSON::to_json( $callbackParams );
# Generate 'Choose billing address' button
my $addressButton = WebGUI::Form::formHeader( $session )
. WebGUI::Form::hidden( $session, { name => 'shop', value => 'address' } )
. WebGUI::Form::hidden( $session, { name => 'method', value => 'view' } )
. WebGUI::Form::hidden( $session, { name => 'callback', value => $callbackJson } )
. WebGUI::Form::submit( $session, { value => $i18n->get('choose billing address') } )
. WebGUI::Form::formFooter( $session);
# Generate 'Proceed' button
my $proceedButton = $address
? $self->ogoneCheckoutButton( $transaction, $address )
: $i18n->get('please choose a billing address')
;
return $session->style->userStyle($addressButton.'<br />'.$billingAddressHtml.'<br />'.$proceedButton);
}
#-------------------------------------------------------------------
=head2 checkPostbackSHA ( )
Processes the postback data Ogone sends after a payment/cancelation. Figures out which transaction the data belongs
@ -547,6 +458,40 @@ sub www_edit {
#-------------------------------------------------------------------
=head2 www_getCredentials ( )
Displays the checkout form for this plugin.
=cut
sub www_getCredentials {
my ($self) = @_;
my $session = $self->session;
# Fetch transaction
my $transactionId = $session->form->process('transactionId');
my $transaction;
if ($transactionId) {
$transaction = WebGUI::Shop::Transaction->new( $session, $transactionId );
}
# Or generate a new one
unless ($transaction) {
$transaction = $self->processTransaction( );
}
# Generate 'Proceed' button
my $var = {
proceedButton => $self->ogoneCheckoutButton,
};
$self->appendCartVariables($var);
my $output = $self->processTemplate($self->get("summaryTemplateId"), $var);
return $session->style->userStyle($output);
}
#-------------------------------------------------------------------
=head2 www_processTransaction ( )
This method is called by the post sale notfication.

View file

@ -339,4 +339,3 @@ sub getPaypalCountry {
}
1;

View file

@ -106,6 +106,14 @@ sub definition {
$fields{paypal}{defaultValue} = 'https://www.paypal.com/webscr';
$fields{api}{defaultValue} = 'https://api-3t.payPal.com/nvp';
$fields{summaryTemplateId} = {
fieldType => 'template',
label => $i18n->get('summary template'),
hoverHelp => $i18n->get('summary template help'),
namespace => 'Shop/Credentials',
defaultValue => 'GqnZPB0gLoZmqQzYFaq7bg',
},
push @{$definition}, {
name => $i18n->get('name'),
properties => \%fields,

View file

@ -123,6 +123,13 @@ sub definition {
hoverHelp => $i18n->get('button image help'),
defaultValue => '',
},
summaryTemplateId => {
fieldType => 'template',
label => $i18n->get('summary template'),
hoverHelp => $i18n->get('summary template help'),
namespace => 'Shop/Credentials',
defaultValue => '',
},
);
push @{$definition},
@ -164,7 +171,7 @@ sub getButton {
# do a submit button with i18n'd paypal text. If they did, we'll use an
# image submit.
my $button;
my $i18n = WebGUI::International->new( $session, 'PayDriver_PayPalStd' );
my $i18n = WebGUI::International->new( $session, 'PayDriver_PayPalStd' );
my $text = $i18n->get('PayPal');
if ( $self->get('buttonImage') ) {
my $raw = $self->get('buttonImage');
@ -329,5 +336,5 @@ sub www_completeTransaction {
: $self->displayPaymentError($transaction);
}
1;
1;

View file

@ -100,7 +100,14 @@ sub getDrivers {
=head2 getOptions ( $cart )
Returns a list of options for the user to ship, along with the cost of using each one. It is a hash of hashrefs,
with the key of the primary hash being the shipperId of the driver, and sub keys of label and price.
with the key of the primary hash being the shipperId of the driver, and sub keys of label, price, and whether the
price actually exists, to tell the difference between 0 and unknown.
{
label => 'ShipDriver label',
price => \d+,
hasPrice => 1 || 0,
}
=head3 $cart
@ -115,15 +122,24 @@ sub getOptions {
my %options = ();
SHIPPER: foreach my $shipper (@{$self->getShippers()}) {
next SHIPPER unless $shipper->get('enabled');
my $price = eval { $shipper->calculate($cart) };
if (my $e = WebGUI::Error->caught()) {
$self->session->log->warn($e->error);
next SHIPPER;
}
next SHIPPER unless $shipper->canUse;
my ($price, $hasPrice);
if ($cart->get('shippingAddressId')) {
$price = eval { $shipper->calculate($cart) };
if (my $e = WebGUI::Error->caught()) {
$self->session->log->warn($e->error);
next SHIPPER;
}
$hasPrice = 1;
}
else {
$price = 0;
$hasPrice = 0;
}
$options{$shipper->getId} = {
label => $shipper->get("label"),
price => $price,
label => $shipper->get("label"),
price => $price,
hasPrice => $hasPrice,
};
}
return \%options;

View file

@ -104,33 +104,6 @@ sub appendCartItemVars {
#-----------------------------------------------------------
=head2 appendCartVars ( var, cart )
Extend this method to add tax driver specific template variables to those supplied to the cart template.
=head3 var
The hash ref to add the template variables to.
=head3 cart
The instance of WebGUI::Shop::Cart to add the template variables for.
=cut
sub appendCartVars {
my $self = shift;
my $var = shift;
my $cart = shift;
WebGUI::Error::InvalidParam->throw( 'Must supply a hash ref' )
unless $var && ref $var eq 'HASH';
WebGUI::Error::InvalidObject->throw( expected => 'WebGUI::Shop::Cart', got => ref $cart, error => 'Must pass a cart' )
unless $cart && $cart->isa( 'WebGUI::Shop::Cart' );
}
#-----------------------------------------------------------
=head2 canManage ( )
Returns true if the current user can manage taxes.
@ -155,9 +128,9 @@ Returns the class name of your plugin. You must overload this method in you own
sub className {
my $self = shift;
$self->session->log->fatal( "Tax plugin ($self) is required to overload the className method" );
$self->session->log->fatal( "Tax plugin (".$self->className.") is required to overload the className method" );
return 'WebGUI::Shop:TaxDriver';
return 'WebGUI::Shop::TaxDriver';
}
#-----------------------------------------------------------

View file

@ -32,7 +32,7 @@ This package keeps records of every puchase made.
my $transaction = WebGUI::Shop::Transaction->new($session, $id);
# typical transaction goes like this:
my $transaction = WebGUI::Shop::Transaction->create({ cart=>$cart, paymentMethod=>$paymentMethod, paymentAddress=>$address});
my $transaction = WebGUI::Shop::Transaction->create({ cart=>$cart });
my ($transactionNumber, $status, $message) = $paymentMethod->tryTransaction;
if ($status eq "somekindofsuccess") {
$transaction->completePurchase($cart, $transactionNumber, $status, $message);
@ -744,44 +744,57 @@ sub update {
if (exists $newProperties->{cart}) {
my $cart = $newProperties->{cart};
$newProperties->{taxes} = $cart->calculateTaxes;
my $address = $cart->getShippingAddress;
$newProperties->{shippingAddressId} = $address->getId;
$newProperties->{shippingAddressName} = $address->get('firstName') . " " .$address->get('lastName');
$newProperties->{shippingAddress1} = $address->get('address1');
$newProperties->{shippingAddress2} = $address->get('address2');
$newProperties->{shippingAddress3} = $address->get('address3');
$newProperties->{shippingCity} = $address->get('city');
$newProperties->{shippingState} = $address->get('state');
$newProperties->{shippingCountry} = $address->get('country');
$newProperties->{shippingCode} = $address->get('code');
$newProperties->{shippingPhoneNumber} = $address->get('phoneNumber');
my $shipper = $cart->getShipper;
$newProperties->{shippingDriverId} = $shipper->getId;
$newProperties->{shippingDriverLabel} = $shipper->get('label');
$newProperties->{shippingPrice} = $shipper->calculate($cart);
$newProperties->{amount} = $cart->calculateTotal + $newProperties->{shopCreditDeduction};
my $billingAddress = $cart->getBillingAddress;
$newProperties->{paymentAddressId} = $billingAddress->getId;
$newProperties->{paymentAddressName} = $billingAddress->get('firstName') . " " . $billingAddress->get('lastName');
$newProperties->{paymentAddress1} = $billingAddress->get('address1');
$newProperties->{paymentAddress2} = $billingAddress->get('address2');
$newProperties->{paymentAddress3} = $billingAddress->get('address3');
$newProperties->{paymentCity} = $billingAddress->get('city');
$newProperties->{paymentState} = $billingAddress->get('state');
$newProperties->{paymentCountry} = $billingAddress->get('country');
$newProperties->{paymentCode} = $billingAddress->get('code');
$newProperties->{paymentPhoneNumber} = $billingAddress->get('phoneNumber');
my $shippingAddress = $cart->getShippingAddress;
$newProperties->{shippingAddressId} = $shippingAddress->getId;
$newProperties->{shippingAddressName} = $shippingAddress->get('firstName') . " " . $shippingAddress->get('lastName');
$newProperties->{shippingAddress1} = $shippingAddress->get('address1');
$newProperties->{shippingAddress2} = $shippingAddress->get('address2');
$newProperties->{shippingAddress3} = $shippingAddress->get('address3');
$newProperties->{shippingCity} = $shippingAddress->get('city');
$newProperties->{shippingState} = $shippingAddress->get('state');
$newProperties->{shippingCountry} = $shippingAddress->get('country');
$newProperties->{shippingCode} = $shippingAddress->get('code');
$newProperties->{shippingPhoneNumber} = $shippingAddress->get('phoneNumber');
if ($cart->requiresShipping) {
my $shipper = $cart->getShipper;
$newProperties->{shippingDriverId} = $shipper->getId;
$newProperties->{shippingDriverLabel} = $shipper->get('label');
$newProperties->{shippingPrice} = $shipper->calculate($cart);
}
else {
$newProperties->{shippingDriverLabel} = "NO SHIPPING";
$newProperties->{shippingPrice} = 0;
}
$newProperties->{amount} = $cart->calculateTotal + $newProperties->{shopCreditDeduction};
$newProperties->{shopCreditDeduction} = $cart->calculateShopCreditDeduction($newProperties->{amount});
$newProperties->{amount} += $newProperties->{shopCreditDeduction};
$newProperties->{amount} += $newProperties->{shopCreditDeduction};
my $pay = $cart->getPaymentGateway;
$newProperties->{paymentDriverId} = $pay->getId;
$newProperties->{paymentDriverLabel} = $pay->get('label');
foreach my $item (@{$cart->getItems}) {
$self->addItem({item=>$item});
}
}
if (exists $newProperties->{paymentAddress}) {
my $address = $newProperties->{paymentAddress};
$newProperties->{paymentAddressId} = $address->getId;
$newProperties->{paymentAddressName} = $address->get('firstName') ." ". $address->get('lastName');
$newProperties->{paymentAddress1} = $address->get('address1');
$newProperties->{paymentAddress2} = $address->get('address2');
$newProperties->{paymentAddress3} = $address->get('address3');
$newProperties->{paymentCity} = $address->get('city');
$newProperties->{paymentState} = $address->get('state');
$newProperties->{paymentCountry} = $address->get('country');
$newProperties->{paymentCode} = $address->get('code');
$newProperties->{paymentPhoneNumber} = $address->get('phoneNumber');
}
if (exists $newProperties->{paymentMethod}) {
my $pay = $newProperties->{paymentMethod};
$newProperties->{paymentDriverId} = $pay->getId;
$newProperties->{paymentDriverId} = $pay->getId;
$newProperties->{paymentDriverLabel} = $pay->get('label');
}
my @fields = (qw( isSuccessful transactionCode statusCode statusMessage amount shippingAddressId