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:
commit
5febc0ebbc
258 changed files with 5528 additions and 2230 deletions
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -339,4 +339,3 @@ sub getPaypalCountry {
|
|||
}
|
||||
|
||||
1;
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue