Adding POD to the commerce system, as well as objectifying everything.

This commit is contained in:
Martin Kamerbeek 2005-01-10 16:06:11 +00:00
parent 702905c9db
commit 61d74619c5
4 changed files with 827 additions and 1 deletions

View file

@ -1,6 +1,135 @@
package WebGUI::Commerce::Item;
=head1 NAME
Package WebGUI::Commerce::Item
=head1 DESCRIPTION
This is the SUPER class off all Item plugins. Item plugins are an abstraction layer to connect
arbitrary types of products and other stuff you might want to sell to the commerce system.
The SUPER class new method provides an easy way to load Item plugins: WebGUI::Item->new('1234', 'MyItem')
is equivalent to WebGUI::Item::MyItem->new('1234'). The SUPER class new has the benefit of added
error checking, so you should use this.
=head1 SYNOPSIS
use WebGUI::Item;
$item = WebGUI::Item->new($itemId, $itemType);
$description = $item->description;
$duration = $item->duration;
$item->handler;
$id = $item->id
$isRecurring = $item->isRecurring;
$name = $item->name;
$price = $item->price;
$type = $item->type;
=head1 METHODS
These methods are available from this class:
=cut
#-------------------------------------------------------------------
=head2 description ( )
This returns the description of the item. This must be implemented by an item plugin.
=cut
sub description {
return WebGUI::ErrorHandler::fatalError('The description method of WebGUI::Commerce::Item must be overridden.');
}
#-------------------------------------------------------------------
=head2 duration ( )
This returns the duration of a term when the item is recurring. If your item isn't
recurring you don't need to override this method. If you do however, you should return
undef if it's not recurring.
=cut
sub duration {
return undef;
}
#-------------------------------------------------------------------
=head2 handler ( )
This will execute the handler that's tied to this item. If you don't have a handler for
your item you don't have to override this method or if you do, you can just return undef.
=cut
sub handler {
return undef;
}
#-------------------------------------------------------------------
=head2 id ( )
This returns the item ID. This must be implemented by an item plugin. This must be implemented
by an item plugin.
=cut
sub id {
return WebGUI::ErrorHandler::fatalError('The id method of WebGUI::Commerce::Item must be overridden.');
}
#-------------------------------------------------------------------
=head2 isRecurring ( )
A boolean identifying wheter the item is recurring (like, for instance, a subscription) or not.
You must override this method if your item is recurring.
=cut
sub isRecurring {
return 0;
}
#-------------------------------------------------------------------
=head2 name ( )
Returns the name of the item. This must be implemented by an item plugin.
=cut
sub name {
return WebGUI::ErrorHandler::fatalError('The name method of WebGUI::Commerce::Item must be overridden.');
}
#-------------------------------------------------------------------
=head2 new ( itemdId, itemType )
Returns an item object of type itemType and with id itemId. Note that this is an easy way to load
item plugins. Your custom plugin should also have a new method that returns the actual item object.
The new method of the plugin won't overload this method, since there's no inheritance.
=head3 itemId
The id of the item you want to load.
=head3 itemType
The type (namespace) of the item you want.
=cut
sub new {
my ($class, $namespace, $load, $cmd, $plugin);
$class = shift;
@ -16,5 +145,30 @@ sub new {
return $plugin;
}
#-------------------------------------------------------------------
=head2 price ( )
This method should return the price of the item. If the item is recurring this should be the per
term price. This must be implemented by an item plugin.
=cut
sub price {
return WebGUI::ErrorHandler::fatalError('The price method of WebGUI::Commerce::Item must be overridden.');
}
#-------------------------------------------------------------------
=head2 type ( )
Returns the type (namespace) of the item.
=cut
sub type {
return WebGUI::ErrorHandler::fatalError('The type method of WebGUI::Commerce::Item must be overridden.');
}
1;

View file

@ -6,7 +6,76 @@ use WebGUI::International;
use Tie::IxHash;
use WebGUI::HTMLForm;
=head1 NAME
Package WebGUI::Commerce::Payment
=head1 DESCRIPTION
An abstract class for all payment plugins to extend.
=head1 SYNOPSIS
use WebGUI::CommercePayment;
our @ISA = qw(WebGUI::Commerce::Payment);
Invoking goes as follows:
$plugin = WebGUI::Commerce::Payment->new('MyPlugin');
=head1 METHODS
These methods are available from this class:
=cut
#-------------------------------------------------------------------
=head2 cancelRecurringPayment ( data )
This method takes care of canceling a recurring transaction. You must override this
method if your plugin can handle recurring payments.
=head3 data
A hashref containing:
id => the gateway ID of the transaction,
transaction => the instanciated WebGUI::Commerce::Transaction object
=cut
sub cancelRecurringPayment {
return "";
}
#-------------------------------------------------------------------
=head2 checkoutForm
This must return a printRowsOnly'ed WebGUI::HTMLForm containing the fields for the checkout
dat you want to collect. Do not include submit buttons. You probably want to override this
method.
=cut
sub checkoutForm {
return "";
}
#-------------------------------------------------------------------
=head2 configurationForm
This generates the configuration form that's displayed in the admin console. You must
extend this method to include parameters specific to this payment module. To do so return
the SUPER::configurationForm method with a printRowsOnly'ed WebGUI::HTMLForm as the argument.
Also be sure to prepend all formfield names with the prepend method. See propend for more info.
=cut
sub configurationForm {
my ($self, $form, $f);
$self = shift;
@ -23,18 +92,86 @@ sub configurationForm {
return $f->printRowsOnly;
}
#-------------------------------------------------------------------
=head2 confirmRecurringTransaction
This method is called if your gateway signals you (ie. posts data to some URL) to confirm a
recurring payment term has been processed. If this is the case, you probably want to store
the result in some table so it can be processed by the Schedualer plugin through the
getRecurringPaymentStatus method.
You only need to override this method if your gateway uses a webbased contacting scheme.
=cut
sub confirmRecurringTransaction {
return undef;
}
#-------------------------------------------------------------------
=head2 confirmTransaction
This method is called when your gateway contacts a specific URL to notify you of the result of a
transaction. You should override this method only if your gateway uses this kind of notification
(ie. like PayPal APN). Returns a boolean indicating whether the transaction was successful or not.
=cut
sub confirmTransaction {
return 0;
}
#-------------------------------------------------------------------
=head2 connectionError
Returns an error message if there was a connection error. You must override this method.
=cut
sub connectionError {
return "The connetionError method must be overridden.";
}
#-------------------------------------------------------------------
=head2 enabled
Returns a boolean indicating whether the plugin is enabled or not.
=cut
sub enabled {
return $_[0]->{_enabled};
}
#-------------------------------------------------------------------
=head2 get ( property )
Returns property of the plugin.
=head3 property
The name of the property you want.
=cut
sub get {
return $_[0]->{_properties}{$_[1]};
}
#-------------------------------------------------------------------
=head2 getEnabledPlugins
Returns a reference to an array of all enabled instanciated payment plugins.
=cut
sub getEnabledPlugins {
my (@enabledPlugins, $plugin, @plugins);
@enabledPlugins = WebGUI::SQL->buildArray("select namespace from commerceSettings where type='Payment' and fieldName='enabled' and fieldValue='1'");
@ -48,6 +185,17 @@ sub getEnabledPlugins {
}
#-------------------------------------------------------------------
=head2 init ( namespace )
Constructor for the plugin. You should extend this method.
=head3 namespace
The namespace of the plugin.
=cut
sub init {
my ($class, $namespace, $properties);
$class = shift;
@ -59,6 +207,68 @@ sub init {
}
#-------------------------------------------------------------------
=head2 gatewayId
Returns the gatewayId of the transaction. You must override this method.
=cut
sub gatewayId {
return WebGUI::ErrorHandler::fatalError("You must override the gatewayId method in your Payment plugin.");
}
#-------------------------------------------------------------------
=head2 getRecurringPaymentStatus ( recurringId, term )
This should return a hashref containing the payment status of the specified term. If
the term has not been processed yet this method should return undef. Override only if
your plugin is capable of recurring transactions.
The hashref should contain:
resultCode => the result of the payment
=head3 recurringId
The ID the gateway has assigned to the recurring transaction.
=head3 term
The term number you want the status of.
=cut
sub getRecurringPaymentStatus {
return undef;
}
#-------------------------------------------------------------------
=head2 errorCode
Returns the error code of the last submission.
=cut
sub errorCode {
return WebGUI::ErrorHandler::fatalError("You must override thie errorCode method in the payment plugin.");
}
#-------------------------------------------------------------------
=head2 load ( namespace )
A convienient method to load a plugin. It handles all error checking and stuff for you.
This is a SUPER class method only and shoud NOT be overridden.
=head3 namespace
The namespace of the plugin.
=cut
sub load {
my ($class, $namespace, $load, $cmd, $plugin);
$class = shift;
@ -74,11 +284,121 @@ sub load {
}
#-------------------------------------------------------------------
=head2 name
Returns the (display) name of the plugin. You must override this method.
=cut
sub name {
return WebGUI::ErrorHandler::fatalError("You must override the name method in the payment plugin.");
}
#-------------------------------------------------------------------
=head2 namespace
Returns the namespace of the plugin.
=cut
sub namespace {
return $_[0]->{_namespace};
}
#-------------------------------------------------------------------
=head2 normalTransaction ( transactionData )
This method submits a normal (non-recurring) transaction to the payment gateway. You probably
should override this method.
=head3 transactionData
A hashref containing:
amount => the total amount of the transaction
description => the transaction description
invoiceNumber => the invoice number of the transaction
id => the webgui transaction ID
=cut
sub normalTransaction {
return undef;
}
#-------------------------------------------------------------------
=head2 recurringTransaction ( transactionData )
This method submits a recurring transaction to the payment gateway. You must override
this method if your plugin supports recurring payments.
=head3 transactionData
A hashref containing:
amount => the total amount of the transaction,
term => the number of terms of the subscription should last.
If none is given your plugin should use an infinite number of terms,
payPeriod => the billing interval,
description => the transaction description,
invoiceNumber => the invoice number of the transaction,
id => the webgui transaction ID,
=cut
sub recurringTransaction {
return undef;
}
#-------------------------------------------------------------------
=head2 resultCode
Returns the result code of the transaction. You must override this method.
=cut
sub resultCode {
return WebGUI::ErrorHandler::fatalError("You must override the resultCode method in the payment plugin.");
}
#-------------------------------------------------------------------
=head2 resultMessage
Returns the result message of the transaction. You must override this method.
=cut
sub resultMessage {
return WebGUI::ErrorHandler::fatalError("You must override the resultMessage method in the payment plugin.");
}
#-------------------------------------------------------------------
=head2 prepend ( fieldName )
A utility method that prepends fieldName with a string that's used to save configuration data to
the database. Use it on all fields in the configurationForm method.
For instance:
$f = WebGUI::HTMLForm->new;
$f->text(
-name => $self->prepend('MyField');
-label => 'MyField'
);
=head3 fieldName
The string to prepend.
=cut
sub prepend {
my ($self, $name);
$self = shift;
@ -88,6 +408,17 @@ sub prepend {
}
#-------------------------------------------------------------------
=head2 recurringPeriodValues ( period )
A utility method that returns the internationalized name for period.
=head3 period
The period you want the name for.
=cut
sub recurringPeriodValues {
my ($i18n, %periods);
$i18n = WebGUI::International->new('Commerce');
@ -105,5 +436,72 @@ sub recurringPeriodValues {
return \%periods;
}
#-------------------------------------------------------------------
=head2 supports
Returns a hashref containg the types of payment the plugin supports. The hashref may contain:
single => 1 if the plugin supports normal transactions,
recurring => 1 if the plugin supports recurring transactions
You must override this method.
=cut
sub supports {
return WebGUI::ErrorHandler::fatalError("You must override the supports method in the payment plugin.");
}
#-------------------------------------------------------------------
=head2 transactionCompleted {
A boolean indicating whether the payment has been finished or not. You must override this method.
=cut
sub transactionCompleted {
return WebGUI::ErrorHandler::fatalError("You must override the transactionCompleted method in the payment plugin.");
}
#-------------------------------------------------------------------
=head2 transactionError
Returns an error message if a transaction error has occurred. You must override this method.
=cut
sub transactionError {
return WebGUI::ErrorHandler::fatalError("You must override the transactionError method in the payment plugin.");
}
#-------------------------------------------------------------------
=head2 transactionPending
A boolean indicating whether the payment is pending or not. You must override this method.
=cut
sub transactionPending {
return WebGUI::ErrorHandler::fatalError("You must override the transactionPending method in the payment plugin.");
}
#-------------------------------------------------------------------
=head2 validateFormData
This method checks the data entered in the checkoutForm. If an error has occurred this method must
return an arrayref containing the errormessages tied to the errors. If everything's ok it will return
undef. You must override this method.
=cut
sub validateFormData {
return WebGUI::ErrorHandler::fatalError("You must override the validateFormData method in the payment plugin.");
}
1;

View file

@ -6,7 +6,53 @@ use WebGUI::SQL;
use WebGUI::Commerce::Item;
use WebGUI::Commerce::Payment;
=head1 NAME
Package WebGUI::Commerce::ShoppingCart
=head1 DESCRIPTION
This package implements a shopping cart for the E-Commerce system of WebGUI. This
shopping cart is tied to the sessionId and, thus, expires when the sessionId expires.
=head1 SYNOPSIS
$shoppingCart = WebGUI::Commerce::ShoppingCart->new;
$shoppingCart->add('myItemId', 'myItem', 3);
$shoppingCart->empty;
($normal, $recurring) = $shoppingCart->getItems;
$normal->[0]->{quantity} # quantity of first normal item
$recurring->[2]->{period} # period of third recurring item
$normal->[0]->{item}->id # the id of the first normal item
=head1 METHODS
This package provides the following methods:
=cut
#-------------------------------------------------------------------
=head2 add ( itemId, itemType, quantity )
This will add qunatity items of type itemType and with id itemId to the shopping cart.
=head3 itemId
The id of the item to add.
=head3 itemType
The type (namespace) of the item that's to be added to the cart.
=head3 quantity
The number of items to add. Defaults to 1 if quantity is not given.
=cut
sub add {
my ($self, $itemId, $itemType, $quantity);
$self = shift;
@ -27,6 +73,13 @@ sub add {
}
#-------------------------------------------------------------------
=head2 empty ( )
Invoking this method will putrge all content from the shopping cart.
=cut
sub empty {
my ($self);
$self = shift;
@ -35,6 +88,43 @@ sub empty {
}
#-------------------------------------------------------------------
=head2 getItems ( )
This method will return two arrayrefs repectively containing the normal items and the recurring
items in the shoppingcart.
Items are returned as a hashref with the following properties:
=head3 quantity
The quantity of this item.
=head3 period
The duration of a billingperiod if this this is a recurring transaction.
=head3 name
The name of this item.
=head3 price
The price of a single item.
=head3 totalPrice
The total price of this item. Ie. totalPrice = quantity * price.
=head3 item
The instanciated plugin of this item. See WebGUI::Commerce::Item for a detailed API.
For example:
=cut
sub getItems {
my ($self, $periodResolve, %cartContent, $item, $properties, @recurring, @normal);
$self = shift;
@ -63,6 +153,18 @@ sub getItems {
}
#-------------------------------------------------------------------
=head2 new ( sessionId )
Returns a shopping cart object tied to session id sessionId or the current session.
=head3 sessionId
The session id this cart should be tied to. If omitted this will default to the session id
of the current user.
=cut
sub new {
my ($class, $sessionId, $sth, $row, %items);
$class = shift;

View file

@ -7,6 +7,21 @@ use WebGUI::SQL;
use WebGUI::Commerce::Payment;
#-------------------------------------------------------------------
=head2 addItem ( item, quantity )
Add's an item to the transaction.
=head3 item
An WebGUI::Commerce::Item object of the item you want to add.
=head3 quantity
The number of items that are tobe added.
=cut
sub addItem {
my ($self, $item, $quantity);
$self = shift;
@ -31,6 +46,14 @@ sub addItem {
}
#-------------------------------------------------------------------
=head2 cancelTransaction
Cancels a recurring transaction. This is done by trying to cancel the subscription at the gateway
using a Payment plugin. If this is succesfull the transaction is marked as canceled.
=cut
sub cancelTransaction {
my ($self, $item, $plugin);
$self = shift;
@ -53,6 +76,14 @@ sub cancelTransaction {
}
#-------------------------------------------------------------------
=head2 completeTransaction
Sets the status of a transaction to 'Completed' and executes the handler for every item attached to
the transction.
=cut
sub completeTransaction {
my ($self, $item);
$self = shift;
@ -66,6 +97,13 @@ sub completeTransaction {
}
#-------------------------------------------------------------------
=head2 delete
Deletes the transaction from the database;
=cut
sub delete {
my ($self) = shift;
@ -76,6 +114,17 @@ sub delete {
}
#-------------------------------------------------------------------
=head2 gateway ( gatewayName )
Returns the gateway connected to the transaction. If gatewayName is given the gateway property is set to that.
=head3 gatewayName
The name to which to set the gateway.
=cut
sub gateway {
my ($self, $gateway);
$self = shift;
@ -90,6 +139,17 @@ sub gateway {
}
#-------------------------------------------------------------------
=head2 gatewayId ( id )
Returns the gateway ID of the transaction. If id is given the gateway ID is set to it.
=head3 id
The ID which to set the gatewayId to.
=cut
sub gatewayId {
my ($self, $gatewayId);
$self = shift;
@ -104,6 +164,18 @@ sub gatewayId {
}
#-------------------------------------------------------------------
=head2 get ( property )
Returns the property requested. If no property is specified this method returns a hashref
containing all properties.
=head3 property
The name of the property you want.
=cut
sub get {
my ($self, $key);
$self = shift;
@ -114,6 +186,22 @@ sub get {
}
#-------------------------------------------------------------------
=head2 getByGatewayId ( id, gateway )
Constructor. Return a transaction object that is identified by the given id and payment gateway.
Returns undef if no match is found.
=head3 id
The gateway ID of the transaction.
=head3 gateway
The payment gateway which the transaction is tied to.
=cut
sub getByGatewayId {
my ($self, $gatewayId, $paymentGateway, $transactionId);
$self = shift;
@ -128,6 +216,11 @@ sub getByGatewayId {
}
#-------------------------------------------------------------------
=head2 getItems
=cut
sub getItems {
my ($self);
$self = shift;
@ -136,6 +229,18 @@ sub getItems {
}
#-------------------------------------------------------------------
=head2 isRecurring ( recurring )
Returns a boolean indcating whether the transaction is recurring. If recurring is given, the isRecurring flag
will be set to it.
=head3 recurring
A boolean which sets the transaction as recurring if true.
=cut
sub isRecurring {
my ($self, $recurring);
$self = shift;
@ -150,6 +255,17 @@ sub isRecurring {
}
#-------------------------------------------------------------------
=head2 lastPayedTerm ( term )
Returns the last term number that has been paid. If term is given this number will be set to it.
-head3 term
The number which to set tha last payed term to.
=cut
sub lastPayedTerm {
my ($self, $lastPayedTerm);
$self = shift;
@ -164,6 +280,26 @@ sub lastPayedTerm {
}
#-------------------------------------------------------------------
=head2 new ( transactionId, [ gateway, [ userId ] ] )
Constructor. Returns a transaction object. If transactionId is set to 'new' a new transaction is created.
=head3 transactionId
The transaction ID of the transaction you want. Set to 'new' for a new transaction.
=head3 gateway
The payment gateway to use for this transaction. Only needed for new transactions.
=head3 userId
The userId of the user for whom to create this transaction. Defaults to the current user. Only optional for
new transactions.
=cut
sub new {
my ($class, $transactionId, $gatewayId, $userId, $properties, $sth, $row, @items);
@ -190,6 +326,13 @@ sub new {
}
#-------------------------------------------------------------------
=head2 pendingTransactions
Returns a reference to an array which contains transaction objects of all pending transactions.
=cut
sub pendingTransactions {
my (@transactionIds, @transactions);
@transactionIds = WebGUI::SQL->buildArray("select transactionId from transaction where status = 'Pending'");
@ -202,6 +345,17 @@ sub pendingTransactions {
}
#-------------------------------------------------------------------
=head2 status ( status )
Returns the status of the transaction. If status is given the transaction status will be set to it.
=head3 status
The value to set the transaction status to.
=cut
sub status {
my ($self, $status);
$self = shift;
@ -216,12 +370,30 @@ sub status {
}
#-------------------------------------------------------------------
=head2 transactionId
Returns the transactionId of the transaction.
=cut
sub transactionId {
my $self = shift;
return $self->{_transactionId};
}
#-------------------------------------------------------------------
=head2 transactionsByUser ( userId )
Returns a reference to an array containing transaction objects of all tranactions by the user corresponding to userId.
=head3 userId
The ID of the user you want the transaction of.
=cut
sub transactionsByUser {
my ($self, @transactionIds, @transactions, $userId);
my $self = shift;