webgui/lib/WebGUI/Commerce/Transaction.pm

411 lines
9.9 KiB
Perl

package WebGUI::Commerce::Transaction;
use strict;
use WebGUI::Session;
use WebGUI::Id;
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;
$item = shift;
$quantity = shift;
WebGUI::SQL->write("insert into transactionItem ".
"(transactionId, itemName, amount, quantity, itemId, itemType) values ".
"(".quote($self->{_transactionId}).",".quote($item->name).",".quote($item->price).",".quote($quantity).",".
quote($item->id).",".quote($item->type).")");
# Adjust total amount in the transaction table.
WebGUI::SQL->write("update transaction set amount=amount+".($item->price * $quantity)." where transactionId=".quote($self->{_transactionId}));
$self->{_properties}{amount} += ($item->price * $quantity);
push @{$self->{_items}}, {
transactionId => $self->{_transactionId},
itemName => $item->name,
amount => $item->price,
quantity => $quantity,
itemId => $item->id,
itemType => $item->type,
}
}
#-------------------------------------------------------------------
=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;
return "Not a recurring transaction" unless ($self->isRecurring);
# Recurring transactions can only have one item, so our items must be the first
$item = $self->getItems->[0];
$plugin = WebGUI::Commerce::Payment->load($self->gateway);
$plugin->cancelRecurringPayment({
id => $self->gatewayId,
transaction => $self,
});
return $plugin->resultMessage.' (code: '.$plugin->errorCode.')' if ($plugin->errorCode);
$self->status('Canceled');
return undef;
}
#-------------------------------------------------------------------
=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;
foreach (@{$self->getItems}) {
$item = WebGUI::Commerce::Item->new($_->{itemId}, $_->{itemType});
$item->handler;
}
$self->status('Completed');
}
#-------------------------------------------------------------------
=head2 delete
Deletes the transaction from the database;
=cut
sub delete {
my ($self) = shift;
WebGUI::SQL->write("delete from transaction where transactionId=".quote($self->{_transactionId}));
WebGUI::SQL->write("delete from transactionItem where transactionId=".quote($self->{_transactionId}));
undef $self;
}
#-------------------------------------------------------------------
=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;
$gateway = shift;
if ($gateway) {
$self->{_properties}{gateway} = $gateway;
WebGUI::SQL->write("update transaction set gateway=".quote($gateway)." where transactionId=".quote($self->{_transactionId}));
}
return $self->{_properties}{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;
$gatewayId = shift;
if ($gatewayId) {
$self->{_properties}{gatewayId} = $gatewayId;
WebGUI::SQL->write("update transaction set gatewayId=".quote($gatewayId)." where transactionId=".quote($self->{_transactionId}));
}
return $self->{_properties}{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;
$key = shift;
return $self->{_properties}{$key} if ($key);
return $self->{_properties};
}
#-------------------------------------------------------------------
=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;
$gatewayId = shift;
$paymentGateway = shift;
($transactionId) = WebGUI::SQL->quickArray("select transaction Id from transaction where gatewayId=".quote($gatewayId).
" and gateway=".quote($paymentGateway));
return WebGUI::Commerce::Transaction->new($transactionId) if $transactionId;
return undef;
}
#-------------------------------------------------------------------
=head2 getItems
=cut
sub getItems {
my ($self);
$self = shift;
return $self->{_items};
}
#-------------------------------------------------------------------
=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;
$recurring = shift;
if (defined $recurring) {
$self->{_properties}{recurring} = $recurring;
WebGUI::SQL->write("update transaction set recurring=".quote($recurring)." where transactionId=".quote($self->{_transactionId}));
}
return $self->{_properties}{recurring};
}
#-------------------------------------------------------------------
=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;
$lastPayedTerm = shift;
if (defined $lastPayedTerm) {
$self->{_properties}{lastPayedTerm} = $lastPayedTerm;
WebGUI::SQL->write("update transaction set lastPayedTerm=".quote($lastPayedTerm)." where transactionId=".quote($self->{_transactionId}));
}
return $self->{_properties}{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);
$class = shift;
$transactionId = shift;
$gatewayId = shift;
$userId = shift || $session{user}{userId};
if ($transactionId eq 'new') {
$transactionId = WebGUI::Id::generate;
WebGUI::SQL->write("insert into transaction ".
"(transactionId, userId, amount, gatewayId, initDate, completionDate, status) values ".
"(".quote($transactionId).",".quote($userId).",0,".quote($gatewayId).",".quote(time).",NULL,'Pending')");
}
$properties = WebGUI::SQL->quickHashRef("select * from transaction where transactionId=".quote($transactionId));
$sth = WebGUI::SQL->read("select * from transactionItem where transactionId=".quote($transactionId));
while ($row = $sth->hashRef) {
push(@items, $row);
}
bless {_transactionId => $transactionId, _properties => $properties, _items => \@items}, $class;
}
#-------------------------------------------------------------------
=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'");
foreach (@transactionIds) {
push(@transactions, WebGUI::Commerce::Transaction->new($_));
}
return \@transactions;
}
#-------------------------------------------------------------------
=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;
$status = shift;
if ($status) {
$self->{_properties}{status} = $status;
WebGUI::SQL->write("update transaction set status=".quote($status)." where transactionId=".quote($self->{_transactionId}));
}
return $self->{_properties}{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;
my $userId = shift;
@transactionIds = WebGUI::SQL->buildArray("select transactionId from transaction where userId =".quote($userId));
foreach (@transactionIds) {
push (@transactions, WebGUI::Commerce::Transaction->new($_));
}
return \@transactions;
}
1;