334 lines
8.4 KiB
Perl
334 lines
8.4 KiB
Perl
package WebGUI::Shop::CartItem;
|
|
|
|
use strict;
|
|
|
|
use Scalar::Util qw/blessed/;
|
|
use Moose;
|
|
use WebGUI::Definition;
|
|
property assetId => (
|
|
is => 'rw',
|
|
noFormPost => 1,
|
|
default => '',
|
|
);
|
|
property configuredTitle => (
|
|
is => 'rw',
|
|
noFormPost => 1,
|
|
default => '',
|
|
);
|
|
property options => (
|
|
is => 'rw',
|
|
noFormPost => 1,
|
|
default => sub { return {}; },
|
|
traits => ['Hash', 'WebGUI::Definition::Meta::Property::Serialize',],
|
|
isa => 'WebGUI::Type::JSONHash',
|
|
coerce => 1,
|
|
);
|
|
property shippingAddressId => (
|
|
is => 'rw',
|
|
noFormPost => 1,
|
|
default => '',
|
|
);
|
|
property quantity => (
|
|
is => 'rw',
|
|
noFormPost => 1,
|
|
default => '1',
|
|
trigger => \&_call_sku,
|
|
);
|
|
sub _call_sku {
|
|
my ($self, $newQuantity) = @_;
|
|
}
|
|
property dateAdded => (
|
|
is => 'ro',
|
|
noFormPost => 1,
|
|
default => '',
|
|
);
|
|
|
|
has [ qw/cart itemId/ ] => (
|
|
is => 'ro',
|
|
required => 1,
|
|
);
|
|
|
|
has asset => (
|
|
is => 'rw',
|
|
trigger => \&_mine_asset,
|
|
);
|
|
|
|
sub _mine_asset {
|
|
my ($self, $asset) = @_;
|
|
$self->options($asset->getOptions);
|
|
$self->assetId($asset->getId);
|
|
$self->configuredTitle($asset->getConfiguredTitle);
|
|
}
|
|
|
|
use JSON;
|
|
use WebGUI::Asset;
|
|
use WebGUI::Exception::Shop;
|
|
|
|
=head1 NAME
|
|
|
|
Package WebGUI::Shop::CartItem
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
A cart item is a manager of a WebGUI::Asset::Sku class that is put into a user's cart.
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
use WebGUI::Shop::CartItem;
|
|
|
|
my $item = WebGUI::Shop::CartItem->new($cart);
|
|
|
|
=head1 METHODS
|
|
|
|
These subroutines are available from this package:
|
|
|
|
=cut
|
|
|
|
around BUILDARGS => sub {
|
|
my $orig = shift;
|
|
my $class = shift;
|
|
if (ref $_[0] eq 'HASH') {
|
|
my $properties = $_[0];
|
|
my $cart = $properties->{cart};
|
|
if (! (blessed $cart && $cart->isa("WebGUI::Shop::Cart"))) {
|
|
WebGUI::Error::InvalidObject->throw(expected=>"WebGUI::Shop::Cart", got=>(ref $cart), error=>"Need a cart.");
|
|
}
|
|
my $sku = $properties->{sku};
|
|
if (! (blessed $sku && $sku->isa("WebGUI::Asset::Sku"))) {
|
|
WebGUI::Error::InvalidObject->throw(expected=>"WebGUI::Asset::Sku", got=>(ref $sku), error=>"Need a SKU item.");
|
|
}
|
|
my ($itemId, $dateAdded) = $class->_init($cart);
|
|
$properties->{itemId} = $itemId;
|
|
$properties->{cartId} = $cart->getId;
|
|
$properties->{dateAdded} = $dateAdded;
|
|
return $class->$orig($properties);
|
|
}
|
|
my $cart = shift;
|
|
if (! (blessed $cart && $cart->isa("WebGUI::Shop::Cart"))) {
|
|
WebGUI::Error::InvalidObject->throw(expected=>"WebGUI::Shop::Cart", got=>(ref $cart), error=>"Need a cart.");
|
|
}
|
|
my $argument2 = shift;
|
|
if (!defined $argument2) {
|
|
WebGUI::Error::InvalidParam->throw( param=>$argument2, error=>"Need a itemId.");
|
|
}
|
|
if (blessed $argument2 && $argument2->isa('WebGUI::Asset::Sku')) {
|
|
##Build a new one
|
|
my ($itemId, $dateAdded) = $class->_init($cart);
|
|
my $properties = {};
|
|
$properties->{itemId} = $itemId;
|
|
$properties->{cartId} = $cart->getId;
|
|
$properties->{dateAdded} = $dateAdded;
|
|
$properties->{asset} = $argument2;
|
|
$properties->{cart} = $cart;
|
|
return $class->$orig($properties);
|
|
}
|
|
else {
|
|
##Look up one in the db
|
|
my $item = $cart->session->db->quickHashRef("select * from cartItem where itemId=?", [$argument2]);
|
|
if ($item->{itemId} eq "") {
|
|
WebGUI::Error::ObjectNotFound->throw(error=>"Item not found", id=>$argument2);
|
|
}
|
|
if ($item->{cartId} ne $cart->getId) {
|
|
WebGUI::Error::ObjectNotFound->throw(error=>"Item not in this cart.", id=>$argument2);
|
|
}
|
|
$item->{cart} = $cart;
|
|
return $class->$orig($item);
|
|
}
|
|
};
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 _init ( cart )
|
|
|
|
Builds a stub of object information in the database, and returns the newly created
|
|
itemId, and the dateAdded fields so the object can be initialized correctly.
|
|
|
|
=head3 cart
|
|
|
|
A Cart object, to tag the item and to provide a session object.
|
|
|
|
=cut
|
|
|
|
sub _init {
|
|
my $class = shift;
|
|
my $cart = shift;
|
|
my $session = $cart->session;
|
|
my $itemId = $session->id->generate;
|
|
my $dateAdded = WebGUI::DateTime->new($session)->toDatabase;
|
|
$session->db->write("insert into cartItem (itemId, dateAdded, cartId) values (?,?,?)",[$itemId, $dateAdded, $cart->getId]);
|
|
return ($itemId, $dateAdded);
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 adjustQuantity ( [ quantity ] )
|
|
|
|
Increments quantity of item by one. Returns the quantity of this item in the cart.
|
|
|
|
=head3 quantity
|
|
|
|
If specified may increment quantity by more than one. Specify a negative number to decrement quantity. If the quantity ever reaches 0 or lower, the item will be removed from the cart.
|
|
|
|
=cut
|
|
|
|
sub adjustQuantity {
|
|
my ($self, $quantity) = @_;
|
|
$quantity ||= 1;
|
|
$self->setQuantity($quantity + $self->quantity);
|
|
return $self->quantity;
|
|
}
|
|
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 cart ( )
|
|
|
|
Returns a reference to the cart.
|
|
|
|
=cut
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 delete ( )
|
|
|
|
Removes this item from the cart without calling $sku->onRemoveFromCart which would adjust inventory levels. See also remove().
|
|
|
|
=cut
|
|
|
|
sub delete {
|
|
my $self = shift;
|
|
$self->cart->session->db->deleteRow("cartItem","itemId",$self->getId);
|
|
return undef;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getId ()
|
|
|
|
Returns the unique id of this item.
|
|
|
|
=cut
|
|
|
|
sub getId {
|
|
my $self = shift;
|
|
return $self->itemId;
|
|
}
|
|
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getShippingAddress ()
|
|
|
|
Returns the WebGUI::Shop::Address object that is attached to this item for shipping.
|
|
|
|
=cut
|
|
|
|
sub getShippingAddress {
|
|
my $self = shift;
|
|
my $addressId = $self->shippingAddressId || $self->cart->shippingAddressId;
|
|
return $self->cart->getAddressBook->getAddress($addressId);
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getSku ( )
|
|
|
|
Returns an instanciated WebGUI::Asset::Sku object for this cart item.
|
|
|
|
=cut
|
|
|
|
sub getSku {
|
|
my ($self) = @_;
|
|
my $asset = eval { WebGUI::Asset->newById($self->cart->session, $self->assetId); };
|
|
if (!Exception::Class->caught) {
|
|
$asset->applyOptions($self->options);
|
|
}
|
|
return $asset;
|
|
}
|
|
|
|
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 remove ( )
|
|
|
|
Removes this item from the cart and calls $sku->onRemoveFromCart. See also delete().
|
|
|
|
=cut
|
|
|
|
sub remove {
|
|
my $self = shift;
|
|
my $sku = eval { $self->getSku; };
|
|
$sku->onRemoveFromCart($self) if $sku;
|
|
return $self->delete;
|
|
}
|
|
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 setQuantity ( quantity )
|
|
|
|
Sets quantity of this item in the cart.
|
|
|
|
=head3 quantity
|
|
|
|
The number to set the quantity to. Zero or less will remove the item from cart.
|
|
|
|
=cut
|
|
|
|
sub setQuantity {
|
|
my ($self, $newQuantity) = @_;
|
|
my $currentQuantity = $self->quantity;
|
|
if ($newQuantity > $self->getSku->getMaxAllowedInCart) {
|
|
WebGUI::Error::Shop::MaxOfItemInCartReached->throw(error=>"Cannot have that many of this item in cart.");
|
|
}
|
|
if ($newQuantity <= 0) {
|
|
return $self->remove;
|
|
}
|
|
$self->quantity($newQuantity);
|
|
$self->write();
|
|
$self->getSku->onAdjustQuantityInCart($self, $newQuantity - $currentQuantity);
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 update ( properties )
|
|
|
|
Sets properties of the cart item.
|
|
|
|
=head3 properties
|
|
|
|
A hash reference that contains one of the following:
|
|
|
|
=head4 asset
|
|
|
|
This is a special meta property. It is a reference to a WebGUI::Asset::Sku subclass object. If you pass this reference it will acquire the assetId, configuredTitle, and options properties automatically.
|
|
|
|
=head4 assetId
|
|
|
|
The assetId of the asset to add to the cart.
|
|
|
|
=head4 options
|
|
|
|
The configuration options for this asset.
|
|
|
|
=head4 configuredTitle
|
|
|
|
The title of this product as configured.
|
|
|
|
=head4 shippingAddressId
|
|
|
|
The unique id for a shipping address attached to this cart.
|
|
|
|
=cut
|
|
|
|
sub write {
|
|
my ($self) = @_;
|
|
my %properties = %{ $self->get() };
|
|
$properties{options} = JSON->new->encode($properties{options});
|
|
delete @properties{qw/cart asset/};
|
|
$self->cart->session->db->setRow("cartItem","itemId",\%properties);
|
|
}
|
|
|
|
|
|
1;
|