adding cash paydriver, paydriver management

This commit is contained in:
Martin Kamerbeek 2008-03-24 16:39:42 +00:00
parent 4b4f389586
commit fb77b80603
9 changed files with 461 additions and 57 deletions

View file

@ -345,7 +345,7 @@ Calls onCompletePurchase() on all the items in the cart. Then deletes all the it
sub onCompletePurchase {
my $self = shift;
foreach my $item (@{$self->getItems}) {
$item->getSku->completePurchase($item);
$item->getSku->onCompletePurchase($item);
$item->delete;
}
$self->delete;
@ -459,6 +459,12 @@ sub www_update {
}
}
}
my $cartProperties;
$cartProperties->{ shipperId } = $form->process( 'shipperId' ) if $form->process( 'shipperId' );
$cartProperties->{ couponId } = $form->process( 'couponId' ) if $form->process( 'couponId' );
$self->update( $cartProperties );
return $self->www_view;
}
@ -520,7 +526,7 @@ sub www_view {
formFooter => WebGUI::Form::formFooter($session),
updateButton => WebGUI::Form::submit($session, {value=>$i18n->get("update cart button")}),
checkoutButton => WebGUI::Form::submit($session, {value=>$i18n->get("checkout button"),
extras=>q|onclick="this.form.shop.value='pay';this.form.methodvalue='viewOptions';this.form.submit;"|}),
extras=>q|onclick="this.form.shop.value='pay';this.form.method.value='selectPaymentGateway';this.form.submit;"|}),
continueShoppingButton => WebGUI::Form::submit($session, {value=>$i18n->get("continue shopping button"),
extras=>q|onclick="this.form.method.value='continueShopping';this.form.submit;"|}),
chooseShippingButton => WebGUI::Form::submit($session, {value=>$i18n->get("choose shipping button"),

View file

@ -159,7 +159,9 @@ Returns the WebGUI::Shop::Address object that is attached to this item for shipp
sub getShippingAddress {
my $self = shift;
return $self->cart->getAddressBook->getAddress($self->get("shippingAddressId"));
my $addressId = $self->get("shippingAddressId") || $self->cart->get("shippingAddressId");
return $self->cart->getAddressBook->getAddress($addressId);
}
#-------------------------------------------------------------------

View file

@ -66,6 +66,7 @@ sub addPaymentGateway {
WebGUI::Error::InvalidParam->throw(error => q{You must pass a hashref of options to create a new PayDriver object})
unless defined($options) and ref $options eq 'HASH' and scalar keys %{ $options };
my $driver = eval { WebGUI::Pluggable::instanciate($requestedClass, 'create', [ $self->session, $label, $options ]) };
return $driver;
}
@ -103,13 +104,15 @@ A WebGUI::Shop::Cart object. A WebGUI::Error::InvalidParam exception will be th
sub getOptions {
my ($self, $cart) = @_;
WebGUI::Error::InvalidParam->throw(error => q{Need a cart.}) unless defined $cart and $cart->isa("WebGUI::Shop::Cart");
my $session = $cart->session;
my %options = ();
foreach my $gateway (@{$self->getPaymentGateways()}) {
foreach my $gateway (@{ $self->getPaymentGateways() }) {
$options{$gateway->getId} = {
label => $gateway->get("label"),
button => $gateway->getButton($cart),
};
label => $gateway->get("label"),
button => $gateway->getButton($cart),
};
}
return \%options;
}
@ -192,6 +195,39 @@ Returns a reference to the current session.
=cut
#-------------------------------------------------------------------
sub www_addPaymentGateway {
my $self = shift;
my $session = $self->session;
my $className = $session->form->process('className')
|| WebGUI::Error::InvalidParam->throw(error => 'No class name passed');
my $payDriver = $self->addPaymentGateway( $className, $className->getName( $session ), { enabled => 0 } );
return $payDriver->www_edit;
}
#-------------------------------------------------------------------
=head2 www_deletePaymentGateway ()
Deletes a payment gateway from the shop.
=cut
sub www_deletePaymentGateway {
my $self = shift;
my $session = $self->session;
my $paymentGatewayId = $session->form->process('paymentGatewayId')
|| WebGUI::Error::InvalidParam->throw(error => q{www_deletePaymentGateway requires a paymentGatewayId to be passed});
my $payDriver = $self->getPaymentGateway( $paymentGatewayId );
$payDriver->delete;
return $self->www_manage;
}
#-------------------------------------------------------------------
=head2 www_do ( )
@ -203,13 +239,18 @@ Let's payment gateway drivers do method calls. Requires a driver param in the po
sub www_do {
my ($self) = @_;
my $form = $self->session->form;
WebGUI::Error::InvalidParam->throw(error => q{must have a form var called driver with a driver id }) if ($form->get("driver") eq "");
WebGUI::Error::InvalidParam->throw(error => q{must have a form var called do with a www_ method to call }) if ($form->get("do") eq "");
my $driver = $self->getPaymentGateway($form->get("driver"));
my $paymentGatewayId = $form->get("paymentGatewayId")
|| WebGUI::Error::InvalidParam->throw(error => q{must have a form var called driver with a payment gateway id});
my $do = $form->get("do")
|| WebGUI::Error::InvalidParam->throw(error => q{must have a form var called do with a www_ method to call});
my $payDriver = $self->getPaymentGateway( $paymentGatewayId );
my $output = undef;
my $method = "www_". ( $form->get("do"));
if ($driver->can($method)) {
$output = $driver->$method();
my $method = "www_$do";
if ($payDriver->can($method)) {
$output = $payDriver->$method();
}
return $output;
}
@ -223,22 +264,76 @@ The main management screen for payment gateways.
=cut
sub www_manage {
my ($self) = @_;
my $self = shift;
my $session = $self->session;
my $admin = WebGUI::Shop::Admin->new($session);
my $i18n = WebGUI::International->new($session, "Pay");
return $session->privilege->adminOnly() unless ($session->user->isInGroup("3"));
my $admin = WebGUI::Shop::Admin->new($session);
my $i18n = WebGUI::International->new($session, "Shop");
# Button for adding a payment gateway
my $output = WebGUI::Form::formHeader($session)
.WebGUI::Form::hidden($session, {name=>"shop", value=>"pay"})
.WebGUI::Form::hidden($session, {name=>"method", value=>"addDriver"})
.WebGUI::Form::selectBox($session, {name=>"className", options=>$self->getDrivers})
.WebGUI::Form::submit($session, {value=>$i18n->get("add payment method")})
.WebGUI::Form::hidden($session, { name => "shop", value => "pay" })
.WebGUI::Form::hidden($session, { name => "method", value => "addPaymentGateway" })
.WebGUI::Form::selectBox($session, { name => "className", options => $self->getDrivers })
.WebGUI::Form::submit($session, { value => $i18n->echo("add payment method") })
.WebGUI::Form::formFooter($session);
foreach my $payer (@{$self->getPaymentGateways}) {
# Add a row with edit/delete buttons for each payment gateway.
foreach my $paymentGateway (@{$self->getPaymentGateways}) {
$output .= '<div style="clear: both;">'
# Delete button for the current payment gateway.
.WebGUI::Form::formHeader($session, {extras=>'style="float: left;"' })
.WebGUI::Form::hidden($session, { name => "shop", value => "pay" })
.WebGUI::Form::hidden($session, { name => "method", value => "deletePaymentGateway" })
.WebGUI::Form::hidden($session, { name => "paymentGatewayId", value => $paymentGateway->getId })
.WebGUI::Form::submit($session, { value => $i18n->echo("delete"), extras => 'class="backwardButton"' })
.WebGUI::Form::formFooter($session)
# Edit button for current payment gateway
.WebGUI::Form::formHeader($session, {extras=>'style="float: left;"' })
.WebGUI::Form::hidden($session, { name => "shop", value => "pay" })
.WebGUI::Form::hidden($session, { name => "method", value => "do" })
.WebGUI::Form::hidden($session, { name => "do", value => "edit" })
.WebGUI::Form::hidden($session, { name => "paymentGatewayId", value => $paymentGateway->getId })
.WebGUI::Form::submit($session, { value => $i18n->echo("edit"), extras => 'class="normalButton"' })
.WebGUI::Form::formFooter($session)
# Append payment gateway label
.' '. $paymentGateway->get("label")
.'</div>';
}
# Wrap in admin console
my $console = $admin->getAdminConsole;
return $console->render($output, $i18n->get("payment methods"));
return $console->render($output, $i18n->echo("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->getCartBySession( $session );
my $i18n = WebGUI::International->new( $session, 'Shop' );
# All the output stuff is just a placeholder until it's templated.
my $output .= $i18n->echo('Choose one of the following payment gateways to check out:');
$output .= '<table border="0">';
foreach my $payOption ( values %{$self->getOptions( $cart )} ) {
$output .= '<tr><td>' . $payOption->{label} . '</td><td>' . $payOption->{button} . '</td></tr>';
}
$output .= '</table>';
return $session->style->userStyle( $output );
}
1;

View file

@ -118,8 +118,8 @@ sub create {
$class,
]);
# Set the options via the set method because set() will automatically serialize the options hash
$self->set($options);
# Set the options via the update method because update() will automatically serialize the options hash
$self->update($options);
return $self;
}
@ -172,8 +172,8 @@ sub definition {
);
my %properties = (
name => 'Payment Driver',
fields => \%fields,
name => 'Payment Driver',
properties => \%fields,
);
push @{ $definition }, \%properties;
@ -254,6 +254,41 @@ sub getCart {
return $cart;
}
#-------------------------------------------------------------------
=head2 getDoFormTags ( $method, $htmlForm )
Returns a string containing the required form fields for doing a www_do method call. If an HTMLForm object is
passed the fields are automatically added to it. In that case no form tags a returned by this method.
=head3 $htmlForm
The HTMLForm object you want to add the fields to. This is optional.
=cut
sub getDoFormTags {
my $self = shift;
my $doMethod = shift;
my $htmlForm = shift;
my $session = $self->session;
if ($htmlForm) {
$htmlForm->hidden(name => 'shop', value => 'pay');
$htmlForm->hidden(name => 'method', value => 'do');
$htmlForm->hidden(name => 'do', value => $doMethod);
$htmlForm->hidden(name => 'paymentGatewayId', value => $self->getId);
return undef;
}
else {
return WebGUI::Form::hidden($session, { name => 'shop', value => 'pay' })
. WebGUI::Form::hidden($session, { name => 'method', value => 'do' })
. WebGUI::Form::hidden($session, { name => 'do', value => $doMethod })
. WebGUI::Form::hidden($session, { name => 'paymentGatewayId', value => $self->getId })
}
}
#-------------------------------------------------------------------
@ -269,15 +304,30 @@ sub getEditForm {
my $definition = $self->definition($self->session);
my $form = WebGUI::HTMLForm->new($self->session);
$form->submit;
$form->hidden(
name => 'paymentGatewayId',
value => $self->getId,
);
# $form->hidden(
# -name => 'shop',
# -value => 'pay',
# );
# $form->hidden(
# -name => 'method',
# -value => 'do',
# );
# $form->hidden(
# -name => 'do',
# -value => 'editSave',
# );
#
# $form->hidden(
# name => 'paymentGatewayId',
# value => $self->getId,
# );
$self->getDoFormTags('editSave', $form);
$form->hidden(
name => 'className',
value => $self->className,
);
$form->dynamicForm($definition, 'fields', $self);
$form->dynamicForm($definition, 'properties', $self);
return $form;
}
@ -362,6 +412,33 @@ the C<set> method.
=cut
#-------------------------------------------------------------------
=head2 processPropertiesFromFormPost ( )
Updates ship driver with data from Form.
=cut
sub processPropertiesFromFormPost {
my $self = shift;
my %properties;
my $fullDefinition = $self->definition($self->session);
foreach my $definition (@{$fullDefinition}) {
foreach my $property (keys %{$definition->{properties}}) {
$properties{$property} = $self->session->form->process(
$property,
$definition->{properties}{$property}{fieldType},
$definition->{properties}{$property}{defaultValue}
);
}
}
$properties{title} = $fullDefinition->[0]{name} if ($properties{title} eq "" || lc($properties{title}) eq "untitled");
$self->update(\%properties);
}
#-------------------------------------------------------------------
=head2 session ( )
@ -372,7 +449,7 @@ Accessor for the session object. Returns the session object.
#-------------------------------------------------------------------
=head2 set ( $options )
=head2 update ( $options )
Setter for user configurable options in the payment objects.
@ -383,10 +460,10 @@ flattened into JSON and stored in the database as text. There is no content che
=cut
sub set {
sub update {
my $self = shift;
my $properties = shift;
WebGUI::Error::InvalidParam->throw(error => 'set was not sent a hashref of options to store in the database')
WebGUI::Error::InvalidParam->throw(error => 'update was not sent a hashref of options to store in the database')
unless ref $properties eq 'HASH' and scalar keys %{ $properties };
my $jsonOptions = to_json($properties);
@ -407,4 +484,46 @@ a GUID.
=cut
#-------------------------------------------------------------------
=head2 www_edit ( )
Generates an edit form.
=cut
sub www_edit {
my $self = shift;
my $session = $self->session;
my $admin = WebGUI::Shop::Admin->new($session);
my $i18n = WebGUI::International->new($session, "Pay");
return $session->privilege->insufficient() unless $session->user->isInGroup(3);
my $form = $self->getEditForm;
$form->submit;
return $admin->getAdminConsole->render($form->print, $i18n->echo("payment methods"));
}
#-------------------------------------------------------------------
=head2 www_editSave ( )
Saves the data from the post.
=cut
sub www_editSave {
my $self = shift;
my $session = $self->session;
return $session->privilege->insufficient() unless $session->user->isInGroup(3);
$self->processPropertiesFromFormPost;
$session->http->setRedirect("/?shop=pay;method=manage");
return undef;
}
1;

View file

@ -20,30 +20,96 @@ sub definition {
%fields = (
sendReceipt => {
fieldType => 'yesNo',
label => $i18n->echo('sendReceipt'),
hoverHelp => $i18n->echo('sendReceipt help'),
label => $i18n->echo('send receipt'),
hoverHelp => $i18n->echo('send receipt help'),
defaultValue => 0,
},
receiptSubject => {
fieldType => 'text',
label => $i18n->echo('receipt subject'),
hoverHelp => $i18n->echo('receipt subject help'),
},
receiptTemplate => {
fieldType => 'template',
label => $i18n->echo('receipt template'),
hoverHelp => $i18n->echo('receipt template help'),
namespace => 'PayDriver/Cash/Receipt',
defaultValue => undef,
},
);
push @{ $definition }, {
name => $i18n->echo('Cash'),
fields => \%fields,
name => $i18n->echo('Cash'),
properties => \%fields,
};
return $class->SUPER::definition($session, $definition);
}
#-------------------------------------------------------------------
sub getBillingAddress {
my $self = shift;
my $session = $self->session;
sub getButton {
my $addressId = $session->scratch->get('ShopPayDriverCash_billingAddress');
if ($addressId) {
return $self->getCart->getAddressBook->getAddress( $addressId );
}
# No billing address selected yet so return undef.
return undef;
}
#-------------------------------------------------------------------
sub www_collectPaymentInfo {
sub getButton {
my $self = shift;
my $session = $self->session;
my $i18n = WebGUI::International->new($session, 'PayDriver_Cash');
my $payForm = WebGUI::Form::formHeader($session)
. $self->getDoFormTags('getCredentials')
. WebGUI::Form::submit($session, {value => $i18n->echo('Cash') })
. WebGUI::Form::formFooter($session);
return $payForm;
}
#-------------------------------------------------------------------
sub getCartTemplateVariables {
my $self = shift;
my $cart = $self->getCart;
my @itemLoop;
# Process items in cart
foreach my $item (@{ $cart->getItems }) {
my $sku = $item->getSku;
$sku->applyOptions( $item->get('options') );
my $itemProperties = $item->get;
$itemProperties->{ itemName } = $sku->get('title');
$itemProperties->{ itemUrl } = $sku->getUrl;
$itemProperties->{ itemPrice } = $cart->formatCurrency( $sku->getPrice );
$itemProperties->{ totalItemPrice } = $cart->formatCurrency( $sku->getPrice * $item->get('quantity') );
my $address = eval { $item->getShippingAddress };
$itemProperties->{ itemShippingAddres } = $address->getHtmlFormatted unless (WebGUI::Error->caught);
push @itemLoop, $itemProperties;
}
my $cartProperties = $cart->get;
$cartProperties->{ totalPrice } = $cart->calculateSubtotal;
$cartProperties->{ tax } = $cart->getTaxes;
# Include shipping address
my $address = eval { $cart->getShippingAddress };
$cartProperties->{ shippingAddress } = $address->getHtmlFormatted unless (WebGUI::Error->caught);
# $cartProperties->{ shippingPrice } =
$cartProperties->{ item_loop } = \@itemLoop;
return $cartProperties;
}
#-------------------------------------------------------------------
@ -52,5 +118,106 @@ sub www_displayStatus {
}
#-------------------------------------------------------------------
sub www_getCredentials {
my $self = shift;
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 => '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);
# Get billing address
my $billingAddress = eval { $self->getBillingAddress };
if ( WebGUI::Error->caught('WebGUI::Error::ObjectNotFound') ) {
# The stored address id is invalid, so remove it
$session->scratch->delete('ShopPayDriverCash_billingAddress');
}
my $billingAddressHtml;
if ($billingAddress) {
$billingAddressHtml = $billingAddress->getHtmlFormatted;
}
# Generate 'Proceed' button
my $proceedButton = WebGUI::Form::formHeader( $session )
. $self->getDoFormTags('pay')
. WebGUI::Form::submit( $session, { value => 'Pay' } )
. WebGUI::Form::formFooter( $session);
return $session->style->userStyle($addressButton.'<br />'.$billingAddressHtml.'<br />'.$proceedButton);
}
#-------------------------------------------------------------------
sub www_pay {
my $self = shift;
my $session = $self->session;
my $cart = $self->getCart;
my $i18n = WebGUI::International->new($session, 'PayDriver_Cash');
my $var;
my $billingAddress = $self->getBillingAddress( $session->scratch->get( 'ShopPayDriverCash_billingAddressId' ) );
# Create a transaction and complete the purchase
my $transaction = WebGUI::Shop::Transaction->create( $session, {
cart => $cart,
paymentAddress => $billingAddress,
paymentMethod => $self,
});
$transaction->completePurchase( $cart, 'CASH', 'OK', 'Cash payment' );
# Generate a receipt and send it if enabled.
if ( $self->get('sendReceipt') ) {
# Setup receipt tmpl_vars
my $var = $self->getCartTemplateVariables;
# Instanciate receipt template
my $template = WebGUI::Asset::Template->new( $session, $self->get('receiptTemplate') );
WebGUI::Error::ObjectNotFound->throw( id => $self->get('receiptTemplate') )
unless $template;
# Send receipt
my $receipt = WebGUI::Mail::Send->create( $session, {
to => $session->user->profileField('email'),
from => 'martin@oqapi.nl',
subject => $self->get('receiptSubject'),
});
$receipt->addText( $template->process( $var ) );
# $receipt->addText( 'Thank you for ordering' );
$receipt->queue;
}
return $session->style->userStyle('Thank you for ordering');
}
#-------------------------------------------------------------------
sub www_setBillingAddress {
my $self = shift;
my $session = $self->session;
$session->scratch->set( 'ShopPayDriverCash_billingAddress', $session->form->process('addressId') );
return $self->www_getCredentials;
}
1;

View file

@ -91,7 +91,8 @@ The extended status message that came back from the payment gateway when trying
sub completePurchase {
my ($self, $cart, $transactionCode, $statusCode, $statusMessage) = @_;
$cart->completePurchase;
$cart->onCompletePurchase;
#$cart->completePurchase;
$self->update({
transactionCode => $transactionCode,
isSuccessful => 1,
@ -372,7 +373,7 @@ sub update {
$newProperties->{couponId} = $cart->get('couponId');
$newProperties->{couponTitle} = '';
$newProperties->{couponDiscount} = '';
$newProperties->{amount} = $cart->getSubtotal + $newProperties->{couponDiscount} + $newProperties->{shippingPrice} + $newProperties->{taxes};
$newProperties->{amount} = $cart->calculateSubtotal + $newProperties->{couponDiscount} + $newProperties->{shippingPrice} + $newProperties->{taxes};
foreach my $item (@{$cart->getItems}) {
$self->addItem({item=>$item});
}