diff --git a/lib/WebGUI/Shop/Cart.pm b/lib/WebGUI/Shop/Cart.pm index f5f4b0bec..3a30ec7fd 100644 --- a/lib/WebGUI/Shop/Cart.pm +++ b/lib/WebGUI/Shop/Cart.pm @@ -4,7 +4,7 @@ use strict; use Class::InsideOut qw{ :std }; use Carp qw(croak); -use WebGUI::Shop::CartItems; +use WebGUI::Shop::CartItem; =head1 NAME @@ -27,35 +27,24 @@ These subroutines are available from this package: =cut readonly session => my %session; -public properties => my %properties; +private properties => my %properties; #------------------------------------------------------------------- -=head2 addItem ( item, [ quantity ]) +=head2 addItem ( sku ) Adds an item to the cart. Returns the number of items now in the cart. -=head3 item +=head3 sku A reference to a subclass of WebGUI::Asset::Sku. -=head3 quantity - -The number of items configured this way. Defaults to 1. - =cut sub addItem { - my ($self, $item, $quantity) = @_; + my ($self, $sku) = @_; croak "Need a SKU item." unless (defined $item && $item->isa("WebGUI::Asset::Sku")); - $quantity ||= 1; - croak "Too many items of that type in cart." if ($quantity > $item->getMaxAlowedInCart); - my $item = WebGUI::Shop::CartItem->create( - $self->session, - $self->getId, - $item, - $quantity, - ); + my $item = WebGUI::Shop::CartItem->create( $self, $sku); return $item; } @@ -111,7 +100,7 @@ Removes all items from this cart. sub empty { my ($self) = @_; foreach my $item = (@{$self->getItems}) { - $item->delete; + $item->remove; } } @@ -128,9 +117,9 @@ Any field − returns the value of a field rather than the hash reference. =cut sub get { - my ($self, $property) = @_; - if (defined $property) { - return $self->{_properties}{$propertyName}; + my ($self, $name) = @_; + if (defined $name) { + return $self->properties->{$name}; } my %copyOfHashRef = $properties{id $self}; return \%copyOfHashRef; @@ -218,10 +207,10 @@ The unique id for a shipping address attached to this cart. =cut sub update { - my ($self, $properties) = @_; + my ($self, $newProperties) = @_; my $id = id $self; - $properties{$id}{couponId} = $properties->{couponId} || $self->properties->{couponId}; - $properties{$id}{shippingAddressId} = $properties->{shippingAddressId} || $self->properties->{shippingAddressId}; + $properties{$id}{couponId} = $newProperties->{couponId} || $self->properties->{couponId}; + $properties{$id}{shippingAddressId} = $newProperties->{shippingAddressId} || $self->properties->{shippingAddressId}; $self->session->db->setRow("cart","cartId",$self->properties); } diff --git a/lib/WebGUI/Shop/CartItems.pm b/lib/WebGUI/Shop/CartItems.pm new file mode 100644 index 000000000..dd7b27f7f --- /dev/null +++ b/lib/WebGUI/Shop/CartItems.pm @@ -0,0 +1,217 @@ +package WebGUI::Shop::CartItem; + +use strict; + +use Class::InsideOut qw{ :std }; +use Carp qw(croak); +use JSON; +use WebGUI::Asset; + +=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($session, $cartId, $assetId); + +=head1 METHODS + +These subroutines are available from this package: + +=cut + +readonly cart => my %cart; +private properties => my %properties; + +#------------------------------------------------------------------- + +=head2 cart ( ) + +Returns a reference to the cart. + +=cut + +#------------------------------------------------------------------- + +=head2 create ( cart, item) + +Constructor. Adds an item to the cart. Returns a reference to the item. + +=head3 cart + +A reference to WebGUI::Shop::Cart object. + +=head3 item + +A reference to a subclass of WebGUI::Asset::Sku. + +=cut + +sub create { + my ($class, $cart, $sku) = @_; + croak "Need a cart." unless (defined $cart && $cart->isa("WebGUI::Shop::Cart")); + croak "Need a SKU item." unless (defined $sku && $sku->isa("WebGUI::Asset::Sku")); + my $itemId = $cart->session->id->generate; + $cart->session->db->write('insert into cartItems (quantity, cartId, assetId, itemId) values (1,?,?,?)', [$cart->getId, $sku->getId, $itemId]); + my $self = $class->new($cart, $itemId); + $self->update({asset=>$sku}); + return $self; +} + +#------------------------------------------------------------------- + +=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") { + return JSON::from_json($self->properties->{$name}); + } + return $self->properties->{$name}; + } + my %copyOfHashRef = $properties{id $self}; + return \%copyOfHashRef; +} + +#------------------------------------------------------------------- + +=head2 getSku ( ) + +Returns an instanciated WebGUI::Asset::Sku object for this cart item. + +=cut + +sub getSku { + my ($self) = @_; + my $asset = WebGUI::Asset->newByDynamicClass($self->session, $self->get("assetId")); + $asset->applyOptions($self->get("options")); + return $asset; +} + + +#------------------------------------------------------------------- + +=head2 incrementQuantity ( [ quantity ] ) + +Increments quantity of item by one. + +=head3 quantity + +If specified may increment quantity by more than one. + +=cut + +sub incrementQuantity { + my ($self, $quantity) = @_; + $quantity ||= 1; + my $id = $self; + $properties{$id}{quantity} += $quantity; + $cart->session->db->setRow("cartItems","itemId", $properties{$id}); +} + + +#------------------------------------------------------------------- + +=head2 isAtMaxQuantity ( ) + +Returns a boolean indicating whether the item is already at max quantity in the cart. + +=cut + +sub isAtMaxQuantity { + my ($self) = @_; +} + + +#------------------------------------------------------------------- + +=head2 new ( session, cart, itemId ) + +Constructor. Instanciates a cart based upon a cartId. + +=head3 cart + +A reference to the current cart we're working with. + +=head3 itemId + +The unique id of the item to instanciate. + +=cut + +sub new { + my ($class, $cart, $itemId) = @_; + croak "Need a cart" unless (defined $cart && $session->isa("WebGUI::Shop::Cart"); + croak "Need an itemId" unless defined $itemId; + my $item = $cart->session->db->quickHashRef('select * from cart where itemId=?', [$itemId]); + croak "No item with id of $itemId" if ($item->{itemId} eq ""); + croak "Item $itemId is not in this cart." if ($item->{cartId} ne $cart->getId); + bless my $self, $class; + register $self; + my $id = id $self; + $cart{ $id } = $cart; + $properties{ $id } = $item; + return $self; +} + +#------------------------------------------------------------------- + +=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 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 shippingAddressId + +The unique id for a shipping address attached to this cart. + +=cut + +sub update { + my ($self, $newProperties) = @_; + my $id = id $self; + if (exists $newProperties->{asset}) { + $newProperties->{options} = $newProperties->{asset}->getOptions; + $newProperties->{assetId} = $newProperties->{asset}->getId; + } + $properties{$id}{assetId} = $newProperties->{assetId} || $self->properties->{assetId}; + if (exists $newProperties->{options} && ref($newProperties->{options}) eq "HASH") { + $properties{$id}{options} = JSON::to_json($newProperties->{options}); + } + $properties{$id}{shippingAddressId} = $newProperties->{shippingAddressId} || $self->properties->{shippingAddressId}; + $self->session->db->setRow("cart","cartId",$self->properties); +} + + +1;