diff --git a/docs/upgrades/upgrade_7.5.2-7.5.3.pl b/docs/upgrades/upgrade_7.5.2-7.5.3.pl index d31e26106..555916307 100644 --- a/docs/upgrades/upgrade_7.5.2-7.5.3.pl +++ b/docs/upgrades/upgrade_7.5.2-7.5.3.pl @@ -35,9 +35,82 @@ addShoppingHandler($session); addAddressBook($session); insertCommercePayDriverTable($session); addPaymentDrivers($session); +convertTransactionLog($session); finish($session); # this line required +#------------------------------------------------- +sub convertTransactionLog { + my $session = shift; + print "\tInstalling transaction log.\n" unless ($quiet); + $session->db->write("alter table transaction rename oldtransaction"); + $session->db->write("alter table transactionItem rename oldtransactionitem"); + $session->db->write("create table transaction ( + transactionId varchar(22) binary not null primary key, + isSuccessful bool not null default 0, + transactionCode varchar(100), + statusCode varchar(35), + statusMessage varchar(100), + userId varchar(22) binary not null, + username varchar(35) not null, + amount float, + shippingAddressId varchar(22) binary, + shippingAddressName varchar(35), + shippingAddress1 varchar(35), + shippingAddress2 varchar(35), + shippingAddress3 varchar(35), + shippingCity varchar(35), + shippingState varchar(35), + shippingCountry varchar(35), + shippingCode varchar(35), + shippingPhoneNumber varchar(35), + shippingDriverId varchar(22) binary, + shippingDriverLabel varchar(35), + shippingPrice float, + paymentAddressId varchar(22) binary, + paymentAddressName varchar(35), + paymentAddress1 varchar(35), + paymentAddress2 varchar(35), + paymentAddress3 varchar(35), + paymentCity varchar(35), + paymentState varchar(35), + paymentCountry varchar(35), + paymentCode varchar(35), + paymentPhoneNumber varchar(35), + paymentDriverId varchar(22) binary, + paymentDriverLabel varchar(35), + couponId varchar(22), + couponTitle varchar(35), + couponDiscount float, + taxes float, + dateOfPurchase datetime + )"); + $session->db->write("create table transactionItem ( + itemId varchar(22) binary not null primary key, + transactionId varchar(22) binary not null, + assetId varchar(22), + configuredTitle varchar(255), + options mediumText, + shippingAddressId varchar(22) binary, + shippingName varchar(35), + shippingAddress1 varchar(35), + shippingAddress2 varchar(35), + shippingAddress3 varchar(35), + shippingCity varchar(35), + shippingState varchar(35), + shippingCountry varchar(35), + shippingCode varchar(35), + shippingPhoneNumber varchar(35), + shippingTrackingNumber varchar(255), + shippingStatus varchar(35) not null default 'NotShipped', + shippingDate datetime, + quantity int not null default 1, + price float, + index transactionId (transactionId) + )"); + $session->setting->add('shopMyPurchasesTemplateId',''); + $session->setting->add('shopMyPurchaseDetailTemplateId',''); +} #------------------------------------------------- sub addAddressBook { diff --git a/lib/WebGUI/Shop/CartItem.pm b/lib/WebGUI/Shop/CartItem.pm index 2568a45bc..66262eaf5 100644 --- a/lib/WebGUI/Shop/CartItem.pm +++ b/lib/WebGUI/Shop/CartItem.pm @@ -18,7 +18,7 @@ A cart item is a manager of a WebGUI::Asset::Sku class that is put into a user's use WebGUI::Shop::CartItem; - my $item = WebGUI::Shop::CartItem->new($session, $cartId, $assetId); + my $item = WebGUI::Shop::CartItem->new($cart); =head1 METHODS diff --git a/lib/WebGUI/Shop/Transaction.pm b/lib/WebGUI/Shop/Transaction.pm new file mode 100644 index 000000000..98ab60aa3 --- /dev/null +++ b/lib/WebGUI/Shop/Transaction.pm @@ -0,0 +1,334 @@ +package WebGUI::Shop::Transaction; + +use strict; + +use Class::InsideOut qw{ :std }; +use WebGUI::Asset::Template; +use WebGUI::Exception::Shop; +use WebGUI::Form; +use WebGUI::International; +use WebGUI::Shop::AddressBook; +use WebGUI::Shop::TransactionItem; + +=head1 NAME + +Package WebGUI::Shop::Transaction + +=head1 DESCRIPTION + +This package keeps records of every puchase made. + +=head1 SYNOPSIS + + use WebGUI::Shop::Transaction; + + my $transaction = WebGUI::Shop::Transaction->new($session, $id); + +=head1 METHODS + +These subroutines are available from this package: + +=cut + +readonly session => my %session; +private properties => my %properties; + +#------------------------------------------------------------------- + +=head2 addItem ( cartitem ) + +Adds an item to the transaction. Returns a reference to the newly added item. + +=head3 cartitem + +A reference to a subclass of WebGUI::Shop::CartItem. + +=cut + +sub addItem { + my ($self, $cartItem) = @_; + my $item = WebGUI::Shop::TransactionItem->create( $self, $cartItem); + return $item; +} + +#------------------------------------------------------------------- + +=head2 create ( session, properties ) + +Constructor. Creates a new transaction object. Returns a reference to the object. + +=head3 session + +A reference to the current session. + +=head3 properties + +See update(). + +=cut + +sub create { + my ($class, $session, $properties) = @_; + unless (defined $session && $session->isa("WebGUI::Session")) { + WebGUI::Error::InvalidObject->throw(expected=>"WebGUI::Session", got=>(ref $session), error=>"Need a session."); + } + my $transactionId = $session->id->generate; + $session->db->write('insert into transaction (transactionId, userId, username, dateOfPurchase) values (?,?,?,now())', + [$transactionId, $session->user->userId, $session->user->username]); + my $self = $class->new($session, $transactionId); + $self->update($properties); + return $self; +} + +#------------------------------------------------------------------- + +=head2 delete () + +Deletes this transaction and all transactionItems contained in it. + +=cut + +sub delete { + my ($self) = @_; + foreach my $item (@{$self->getItems}) { + $item->delete; + } + $self->session->db->write("delete from transaction where transactionId=?",[$self->getId]); + undef $self; + return undef; +} + +#------------------------------------------------------------------- + +=head2 formatCurrency ( amount ) + +Formats a number as a float with two digits after the decimal like 0.00. + +=head3 amount + +The number to format. + +=cut + +sub formatCurrency { + my ($self, $amount) = @_; + return sprintf("%.2f", $amount); +} + +#------------------------------------------------------------------- + +=head2 get ( [ property ] ) + +Returns a duplicated hash reference of this objectÕs data. + +=head3 property + +Any field ? returns the value of a field rather than the hash reference. + +=cut + +sub get { + my ($self, $name) = @_; + if (defined $name) { + return $properties{id $self}{$name}; + } + my %copyOfHashRef = %{$properties{id $self}}; + return \%copyOfHashRef; +} + +#------------------------------------------------------------------- + +=head2 getId () + +Returns the unique id for this transaction. + +=cut + +sub getId { + my ($self) = @_; + return $self->get("transactionId"); +} + +#------------------------------------------------------------------- + +=head2 getItem ( itemId ) + +Returns a reference to a WebGUI::Shop::TransactionItem object. + +=head3 itemId + +The id of the item to retrieve. + +=cut + +sub getItem { + my ($self, $itemId) = @_; + return WebGUI::Shop::TransactionItem->new($self, $itemId); +} + +#------------------------------------------------------------------- + +=head2 getItems ( ) + +Returns an array reference of WebGUI::Shop::TransactionItem objects that are in the transaction. + +=cut + +sub getItems { + my ($self) = @_; + my @itemsObjects = (); + my $items = $self->session->db->read("select itemId from transactionItem where transactionId=?",[$self->getId]); + while (my ($itemId) = $items->array) { + push(@itemsObjects, $self->getItem($itemId)); + } + return \@itemsObjects; +} + +#------------------------------------------------------------------- + +=head2 new ( session, transactionId ) + +Constructor. Instanciates a transaction based upon a transactionId. + +=head3 session + +A reference to the current session. + +=head3 transactionId + +The unique id of a transaction to instanciate. + +=cut + +sub new { + my ($class, $session, $transactionId) = @_; + unless (defined $session && $session->isa("WebGUI::Session")) { + WebGUI::Error::InvalidObject->throw(expected=>"WebGUI::Session", got=>(ref $session), error=>"Need a session."); + } + unless (defined $transactionId) { + WebGUI::Error::InvalidParam->throw(error=>"Need a transactionId."); + } + my $transaction = $session->db->quickHashRef('select * from transaction where transactionId=?', [$transactionId]); + if ($transaction->{transactionId} eq "") { + WebGUI::Error::ObjectNotFound->throw(error=>"No such transaction.", id=>$transactionId); + } + my $self = register $class; + my $id = id $self; + $session{ $id } = $session; + $properties{ $id } = $transaction; + return $self; +} + +#------------------------------------------------------------------- + +=head2 update ( properties ) + +Sets properties in the transaction. + +=head3 properties + +A hash reference that contains one of the following: + +=head4 cart + +A reference to a cart object. Will pull shipping method, shipping address, tax, items, total, and coupon from +it. Alternatively you can set manually any of the following properties that are set by cart automatically: +amount shippingAddressId shippingAddressName shippingAddress1 shippingAddress2 shippingAddress3 shippingCity +shippingState shippingCountry shippingCode shippingPhoneNumber shippingDriverId shippingDriverLabel shippingPrice +couponId couponTitle couponDiscount taxes + +You can also use the addItem() method to manually add items to the transaction rather than passing a cart full of items. + +=head4 paymentAddress + +A reference to a WebGUI::Shop::Address that contains the payment address. Alternatively you can set manually +any of the properties that are set by payment address automatically: paymentAddressId paymentAddressName +paymentAddress1 paymentAddress2 paymentAddress3 paymentCity paymentState paymentCountry paymentCode +paymentPhoneNumber + +=head4 paymentMethod + +A reference to a WebGUI::Shop::PayDriver subclass that is used to make payment. Alternatively you can set +manually any of the properties that are set by payment method automatically: paymentDriverId paymentDriverLabel + +=head4 isSuccessful + +A boolean indicating whether the transaction was completed successfully. + +=head4 transactionCode + +The transaction id or code given by the payment gateway. + +=head4 statusCode + +The status code that came back from the payment gateway when trying to process the payment. + +=head4 statusMessage + +The extended status message that came back from the payment gateway when trying to process the payment. + +=cut + +sub update { + my ($self, $newProperties) = @_; + my $id = id $self; + if (exists $newProperties->{cart}) { + my $cart = $newProperties->{cart}; + $newProperties->{taxes} = $cart->getTaxes; + my $address = $cart->getShippingAddress; + $newProperties->{shippingAddressId} = $address->getId; + $newProperties->{shippingAddressName} = $address->get('name'); + $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->{couponId} = $cart->get('couponId'); + $newProperties->{couponTitle} = ''; + $newProperties->{couponDiscount} = ''; + $newProperties->{amount} = $cart->getSubtotal + $newProperties->{couponDiscount} + $newProperties->{shippingPrice} + $newProperties->{taxes}; + 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('name'); + $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->{paymentDriverLabel} = $pay->get('label'); + } + my @fields = (qw( isSuccessful transactionCode statusCode statusMessage amount shippingAddressId + shippingAddressName shippingAddress1 shippingAddress2 shippingAddress3 shippingCity shippingState + shippingCountry shippingCode shippingPhoneNumber shippingDriverId shippingDriverLabel + shippingPrice paymentAddressId paymentAddressName + paymentAddress1 paymentAddress2 paymentAddress3 paymentCity paymentState paymentCountry paymentCode + paymentPhoneNumber paymentDriverId paymentDriverLabel couponId couponTitle couponDiscount taxes )); + foreach my $field (@fields) { + $properties{$id}{$field} = (exists $newProperties->{$field}) ? $newProperties->{$field} : $properties{$id}{$field}; + } + $self->session->db->setRow("transaction","transactionId",$properties{$id}); +} + + + + +1; diff --git a/lib/WebGUI/Shop/TransactionItem.pm b/lib/WebGUI/Shop/TransactionItem.pm new file mode 100644 index 000000000..ec0448996 --- /dev/null +++ b/lib/WebGUI/Shop/TransactionItem.pm @@ -0,0 +1,252 @@ +package WebGUI::Shop::TransactionItem; + +use strict; +use Class::InsideOut qw{ :std }; +use JSON; +use WebGUI::DateTime; +use WebGUI::Exception::Shop; + +=head1 NAME + +Package WebGUI::Shop::TransactionItem + +=head1 DESCRIPTION + +Each transaction item represents a sku that was purchased or attempted to be purchased. + +=head1 SYNOPSIS + + use WebGUI::Shop::TransactionItem; + + my $item = WebGUI::Shop::TransactionItem->new($transaction); + +=head1 METHODS + +These subroutines are available from this package: + +=cut + +readonly transaction => my %transaction; +private properties => my %properties; + +#------------------------------------------------------------------- + +=head2 create ( transaction, properties) + +Constructor. Adds an item to the transaction. Returns a reference to the item. + +=head3 transaction + +A reference to WebGUI::Shop::Transaction object. + +=head3 properties + +See update() for details. + +=cut + +sub create { + my ($class, $transaction, $properties) = @_; + unless (defined $transaction && $transaction->isa("WebGUI::Shop::Transaction")) { + WebGUI::Error::InvalidObject->throw(expected=>"WebGUI::Shop::Transaction", got=>(ref $transaction), error=>"Need a transaction."); + } + unless (defined $properties && ref $properties eq "HASH") { + WebGUI::Error::InvalidParam->throw(param=>$properties, error=>"Need a properties hash reference."); + } + my $itemId = $transaction->session->id->generate; + $transaction->session->db->write('insert into transactionItem (itemId, transactionId) values (?,?)', [$itemId, $transaction->getId]); + my $self = $class->new($transaction, $itemId); + $self->update($properties); + return $self; +} + +#------------------------------------------------------------------- + +=head2 delete ( ) + +Removes this item from the transaction. + +=cut + +sub delete { + my $self = shift; + $self->transaction->session->db->deleteRow("transactionItem","itemId",$self->getId); + undef $self; + return undef; +} + +#------------------------------------------------------------------- + +=head2 get ( [ property ] ) + +Returns a duplicated hash reference of this object’s data. + +=head3 property + +Any field − returns the value of a field rather than the hash reference. + +=cut + +sub get { + my ($self, $name) = @_; + if (defined $name) { + if ($name eq "options") { + my $options = $properties{id $self}{$name}; + if ($options eq "") { + return {}; + } + else { + return JSON::from_json($properties{id $self}{$name}); + } + } + return $properties{id $self}{$name}; + } + my %copyOfHashRef = %{$properties{id $self}}; + return \%copyOfHashRef; +} + +#------------------------------------------------------------------- + +=head2 getId () + +Returns the unique id of this item. + +=cut + +sub getId { + my $self = shift; + return $self->get("itemId"); +} + + +#------------------------------------------------------------------- + +=head2 getSku ( ) + +Returns an instanciated WebGUI::Asset::Sku object for this item. + +=cut + +sub getSku { + my ($self) = @_; + my $asset = WebGUI::Asset->newByDynamicClass($self->transaction->session, $self->get("assetId")); + $asset->applyOptions($self->get("options")); + return $asset; +} + + +#------------------------------------------------------------------- + +=head2 new ( transaction, itemId ) + +Constructor. Instanciates a transaction item based upon itemId. + +=head3 transaction + +A reference to the current transaction + +=head3 itemId + +The unique id of the item to instanciate. + +=cut + +sub new { + my ($class, $transaction, $itemId) = @_; + unless (defined $transaction && $transaction->isa("WebGUI::Shop::Transaction")) { + WebGUI::Error::InvalidObject->throw(expected=>"WebGUI::Shop::Transaction", got=>(ref $transaction), error=>"Need a transaction."); + } + unless (defined $itemId) { + WebGUI::Error::InvalidParam->throw(error=>"Need an itemId."); + } + my $item = $transaction->session->db->quickHashRef('select * from transactionItem where itemId=?', [$itemId]); + if ($item->{itemId} eq "") { + WebGUI::Error::ObjectNotFound->throw(error=>"Item not found.", id=>$itemId); + } + if ($item->{transactionId} ne $transaction->getId) { + WebGUI::Error::ObjectNotFound->throw(error=>"Item not in this transaction.", id=>$itemId); + } + my $self = register $class; + my $id = id $self; + $transaction{ $id } = $transaction; + $properties{ $id } = $item; + return $self; +} + + +#------------------------------------------------------------------- + +=head2 transaction ( ) + +Returns a reference to the transaction object. + +=cut + + +#------------------------------------------------------------------- + +=head2 update ( properties ) + +Sets properties of the transaction item. + +=head3 properties + +A hash reference that contains one of the following: + +=head4 item + +A reference to a WebGUI::Shop::CartItem. Alternatively you can manually pass in any of the following +fields that would be created automatically by this object: assetId configuredTitle options shippingAddressId +shippingName shippingAddress1 shippingAddress2 shippingAddress3 shippingCity shippingState shippingCountry +shippingCode shippingPhoneNumber quantity price + +=head4 shippingTrackingNumber + +A tracking number that is used by the shipping method for this transaction. + +=head4 shippingStatus + +The status of this item. The default is 'NotShipped'. Other statuses include: Cancelled, BackOrdered, Shipped + +=cut + +sub update { + my ($self, $newProperties) = @_; + my $id = id $self; + if (exists $newProperties->{item}) { + my $item = $newProperties->{item}; + my $sku = $item->getSku; + $newProperties->{options} = $sku->getOptions; + $newProperties->{assetId} = $sku->getId; + $newProperties->{price} = $sku->getPrice; + $newProperties->{configuredTitle} = $sku->getConfiguredTitle; + my $address = $item->getShippingAddress; + $newProperties->{shippingAddressId} = $address->getId; + $newProperties->{shippingAddressName} = $address->get('name'); + $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'); + $newProperties->{quantity} = $item->get('quantity'); + } + my @fields = (qw(assetId configuredTitle options shippingAddressId shippingTrackingNumber shippingStatus + shippingName shippingAddress1 shippingAddress2 shippingAddress3 shippingCity shippingState + shippingCountry shippingCode shippingPhoneNumber quantity price)); + foreach my $field (@fields) { + $properties{$id}{$field} = (exists $newProperties->{$field}) ? $newProperties->{$field} : $properties{$id}{$field}; + } + if (exists $newProperties->{options} && ref($newProperties->{options}) eq "HASH") { + $properties{$id}{options} = JSON::to_json($newProperties->{options}); + } + if (exists $newProperties->{shippingStatus}) { + $properties{$id}{shippingDate} = WebGUI::DateTime->new($self->transaction->session,time())->toDatabase; + } + $self->transaction->session->db->setRow("transactionItem","itemId",$properties{$id}); +} + + +1; diff --git a/t/Shop/Transaction.t b/t/Shop/Transaction.t new file mode 100644 index 000000000..933e1e984 --- /dev/null +++ b/t/Shop/Transaction.t @@ -0,0 +1,202 @@ +# vim:syntax=perl +#------------------------------------------------------------------- +# WebGUI is Copyright 2001-2008 Plain Black Corporation. +#------------------------------------------------------------------- +# Please read the legal notices (docs/legal.txt) and the license +# (docs/license.txt) that came with this distribution before using +# this software. +#------------------------------------------------------------------ +# http://www.plainblack.com info@plainblack.com +#------------------------------------------------------------------ + +# Tests the transaction backend for the shop. +# +# + +use FindBin; +use strict; +use lib "$FindBin::Bin/../lib"; +use Test::More; +use Test::Deep; +use WebGUI::Test; # Must use this before any other WebGUI modules +use WebGUI::Session; +use WebGUI::Shop::Transaction; + +#---------------------------------------------------------------------------- +# Init +my $session = WebGUI::Test->session; + + +#---------------------------------------------------------------------------- +# Tests + +plan tests => 64; # Increment this number for each test you create + +#---------------------------------------------------------------------------- +# put your tests here + +my $transaction = WebGUI::Shop::Transaction->create($session,{ + amount => 40, + shippingAddressId => 'xxx1', + shippingAddressName => 'abc', + shippingAddress1 => 'def', + shippingAddress2 => 'hij', + shippingAddress3 => 'lmn', + shippingCity => 'opq', + shippingState => 'wxy', + shippingCountry => 'z', + shippingCode => '53333', + shippingPhoneNumber => '123456', + shippingDriverId => 'xxx2', + shippingDriverLabel => 'foo', + shippingPrice => 5, + paymentAddressId => 'xxx3', + paymentAddressName => 'abc1', + paymentAddress1 => 'def1', + paymentAddress2 => 'hij1', + paymentAddress3 => 'lmn1', + paymentCity => 'opq1', + paymentState => 'wxy1', + paymentCountry => 'z1', + paymentCode => '66666', + paymentPhoneNumber => '908765', + paymentDriverId => 'xxx4', + paymentDriverLabel => 'kkk', + couponId => 'xxx5', + couponTitle => 'title1', + couponDiscount => -5, + taxes => 7, + }); + +# objects work +isa_ok($transaction, "WebGUI::Shop::Transaction"); +isa_ok($transaction->session, "WebGUI::Session"); + + +# basic transaction properties +is($transaction->get("amount"), 40, "set and get amount"); +is($transaction->get("shippingAddressId"), 'xxx1', "set and get shipping address id"); +is($transaction->get("shippingAddressName"), 'abc', "set and get shipping address name"); +is($transaction->get("shippingAddress1"), 'def', "set and get shipping address 1"); +is($transaction->get("shippingAddress2"), 'hij', "set and get shipping address 2"); +is($transaction->get("shippingAddress3"), 'lmn', "set and get shipping address 3"); +is($transaction->get("shippingCity"), 'opq', "set and get shipping city"); +is($transaction->get("shippingState"), 'wxy', "set and get shipping state"); +is($transaction->get("shippingCountry"), 'z', "set and get shipping country"); +is($transaction->get("shippingCode"), '53333', "set and get shipping code"); +is($transaction->get("shippingPhoneNumber"), '123456', "set and get shipping phone number"); +is($transaction->get("shippingDriverId"), 'xxx2', "set and get shipping driver id"); +is($transaction->get("shippingDriverLabel"), 'foo', "set and get shipping driver label"); +is($transaction->get("shippingPrice"), 5, "set and get shipping price"); +is($transaction->get("paymentAddressId"), 'xxx3', "set and get payment address id"); +is($transaction->get("paymentAddressName"), 'abc1', "set and get payment address name"); +is($transaction->get("paymentAddress1"), 'def1', "set and get payment address 1"); +is($transaction->get("paymentAddress2"), 'hij1', "set and get payment address 2"); +is($transaction->get("paymentAddress3"), 'lmn1', "set and get payment address 3"); +is($transaction->get("paymentCity"), 'opq1', "set and get payment city"); +is($transaction->get("paymentState"), 'wxy1', "set and get payment state"); +is($transaction->get("paymentCountry"), 'z1', "set and get payment country"); +is($transaction->get("paymentCode"), '66666', "set and get payment code"); +is($transaction->get("paymentPhoneNumber"), '908765', "set and get payment phone number"); +is($transaction->get("paymentDriverId"), 'xxx4', "set and get payment driver id"); +is($transaction->get("paymentDriverLabel"), 'kkk', "set and get payment driver label"); +is($transaction->get("couponId"), 'xxx5', "set and get coupon id"); +is($transaction->get("couponTitle"), 'title1', "set and get coupon title"); +is($transaction->get("couponDiscount"), -5, "set and get coupon discount"); +is($transaction->get("taxes"), 7, "set and get taxes"); + + +$transaction->update({ + isSuccessful => 1, + transactionCode => 'yyy', + statusCode => 'jd31', + statusMessage => 'was a success', +}); + +is($transaction->get("isSuccessful"), 1,"update and get isSuccessful"); +is($transaction->get("transactionCode"), 'yyy',"update and get transaction code"); +is($transaction->get("statusCode"), 'jd31',"update and get status code"); +is($transaction->get("statusMessage"), 'was a success',"update and get status message"); + +# make sure new() works +my $tcopy = WebGUI::Shop::Transaction->new($session, $transaction->getId); + +isa_ok($tcopy, "WebGUI::Shop::Transaction"); +is($tcopy->getId, $transaction->getId, "is it the same object"); + + +# basic item properties +my $item = $transaction->addItem({ + assetId => 'a', + configuredTitle => 'b', + options => {color=>'blue'}, + shippingAddressId => 'c', + shippingName => 'd', + shippingAddress1 => 'e', + shippingAddress2 => 'f', + shippingAddress3 => 'g', + shippingCity => 'h', + shippingState => 'i', + shippingCountry => 'j', + shippingCode => 'k', + shippingPhoneNumber => 'l', + quantity => 5, + price => 33, +}); + +isa_ok($item, "WebGUI::Shop::TransactionItem"); +isa_ok($item->transaction, "WebGUI::Shop::Transaction"); + +is($item->get("assetId"), 'a', "set and get asset id"); +is($item->get("configuredTitle"), 'b', "set and get configured title"); +cmp_deeply($item->get("options"), {color=>'blue'}, "set and get options"); +is($item->get("shippingAddressId"), 'c', "set and get shipping address id"); +is($item->get("shippingName"), 'd', "set and get shipping name"); +is($item->get("shippingAddress1"), 'e', "set and get shipping address 1"); +is($item->get("shippingAddress2"), 'f', "set and get shipping address 2"); +is($item->get("shippingAddress3"), 'g', "set and get shipping address 3"); +is($item->get("shippingCity"), 'h', "set and get shipping city"); +is($item->get("shippingState"), 'i', "set and get shipping state"); +is($item->get("shippingCountry"), 'j', "set and get shipping country"); +is($item->get("shippingCode"), 'k', "set and get shipping code"); +is($item->get("shippingPhoneNumber"), 'l', "set and get shipping phone number"); +is($item->get("quantity"), 5, "set and get quantity"); +is($item->get("price"), 33, "set and get price"); + +$item->update({ + shippingTrackingNumber => 'adfs', + shippingStatus => 'BackOrdered', +}); + +is($item->get("shippingTrackingNumber"), 'adfs', "update and get shipping tracking number"); +is($item->get("shippingStatus"), 'BackOrdered', "update and get shipping status"); + +# make sure shipping date is updated when shipping status is changed +like($item->get("shippingDate"), qr/\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d/, "shipping date is set"); +my $dateNow = $item->get('shippingDate'); +sleep(1); +$item->update({shippingStatus=>'Cancelled'}); +isnt($item->get('shippingDate'), $dateNow, 'shipping date is updated'); + +# make sure new() works +my $icopy = $transaction->getItem($item->getId); +isa_ok($icopy, "WebGUI::Shop::TransactionItem"); +is($icopy->getId, $item->getId, "items are the same"); + +# get itmes +is(scalar @{$transaction->getItems}, 1, "can retrieve items"); + +# delete +$item->delete; +is(scalar @{$transaction->getItems}, 0, "can delete items"); + +$transaction->delete; +is($session->db->quickScalar("select transactionId from transaction where transactionId=?",[$transaction->getId]), undef, "can delete transactions"); + + + +#---------------------------------------------------------------------------- +# Cleanup +END { + +}