added address book management system, no ui

This commit is contained in:
JT Smith 2008-02-29 22:17:02 +00:00
parent 7e6cfad2be
commit cebb684536
6 changed files with 563 additions and 9 deletions

View file

@ -31,10 +31,40 @@ createSkuAsset($session);
createDonationAsset($session);
addShippingDrivers($session);
addShoppingHandler($session);
addAddressBook($session);
finish($session); # this line required
#-------------------------------------------------
sub addAddressBook {
my $session = shift;
print "\tInstalling address book.\n" unless ($quiet);
$session->db->write("create table addressBook (
addressBookId varchar(22) binary not null primary key,
sessionId varchar(22) binary,
userId varchar(22) binary,
lastPayId varchar(22) binary,
lastShipId varchar(22) binary,
index userId (sessionId),
index sessionId (sessionId)
)");
$session->db->write("create table address (
addressId varchar(22) binary not null primary key,
addressBookId varchar(22) binary not null,
label varchar(35),
name varchar(35),
address1 varchar(35),
address2 varchar(35),
address3 varchar(35),
state varchar(35),
country varchar(35),
code varchar(35),
phoneNumber varchar(35),
index addressBookId_addressId (addressBookId,addressId)
)");
}
#-------------------------------------------------
sub addShoppingHandler {
my $session = shift;

View file

@ -16,6 +16,7 @@ package WebGUI::Content::Shop;
use strict;
use WebGUI::AdminConsole;
use WebGUI::Shop::AddressBook;
use WebGUI::Shop::Cart;
#use WebGUI::Shop::Pay;
use WebGUI::Shop::Ship;
@ -79,6 +80,25 @@ sub www_cart {
#-------------------------------------------------------------------
=head2 www_address ()
Hand off to the address book.
=cut
sub www_address {
my $session = shift;
my $output = undef;
my $method = "www_". ( $session->form->get("method") || "view");
my $cart = WebGUI::Shop::AddressBook->create($session);
if ($cart->can($method)) {
$output = $cart->$method();
}
return $output;
}
#-------------------------------------------------------------------
=head2 www_manageSettings ()
Display the commerce settings page.

231
lib/WebGUI/Shop/Address.pm Normal file
View file

@ -0,0 +1,231 @@
package WebGUI::Shop::Address;
use strict;
use Class::InsideOut qw{ :std };
use WebGUI::Exception::Shop;
=head1 NAME
Package WebGUI::Shop::Address
=head1 DESCRIPTION
An address is used to track shipping or payment addresses in the commerce system.
=head1 SYNOPSIS
use WebGUI::Shop::Address;
my $address = WebGUI::Shop::Address->new($addressBook, $addressId);
=head1 METHODS
These subroutines are available from this package:
=cut
readonly addressBook => my %addressBook;
private properties => my %properties;
#-------------------------------------------------------------------
=head2 addressBook ( )
Returns a reference to the Address Book.
=cut
#-------------------------------------------------------------------
=head2 create ( addressBook, address)
Constructor. Adds an address to an address book. Returns a reference to the address.
=head3 addressBook
A reference to a WebGUI::Shop::AddressBook object.
=head3 address
A hash reference containing the properties to set in the address.
=cut
sub create {
my ($class, $book, $addressData) = @_;
unless (defined $book && $book->isa("WebGUI::Shop::AddressBook")) {
WebGUI::Error::InvalidObject->throw(expected=>"WebGUI::Shop::AddressBook", got=>(ref $book), error=>"Need an address book.", param=>$book);
}
unless (defined $addressData && ref $addressData eq "HASH") {
WebGUI::Error::InvalidParam->throw(param=>$addressData, error=>"Need a hash reference.");
}
my $id = $book->session->db->setRow("addressBook","addressBookId", {addressId=>"new"});
my $address = $class->new($book, $id);
$address->update($addressData);
return $address;
}
#-------------------------------------------------------------------
=head2 delete ( )
Removes this address from the book.
=cut
sub delete {
my $self = shift;
$self->addressBook->session->db->deleteRow("address","addressId",$self->getId);
undef $self;
return undef;
}
#-------------------------------------------------------------------
=head2 get ( [ property ] )
Returns a duplicated hash reference of this objects 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 of this item.
=cut
sub getId {
my $self = shift;
return $self->get("addressId");
}
#-------------------------------------------------------------------
=head2 new ( addressBook, addressId )
Constructor. Instanciates an address based upon addressId.
=head3 addressBook
A reference to a WebGUI::Shop::AdressBook object.
=head3 addressId
The unique id of the address to instanciate.
=cut
sub new {
my ($class, $book, $addressId) = @_;
unless (defined $book && $book->isa("WebGUI::Shop::AddressBook")) {
WebGUI::Error::InvalidObject->throw(expected=>"WebGUI::Shop::AddressBook", got=>(ref $book), error=>"Need an address book.");
}
unless (defined $addressId) {
WebGUI::Error::InvalidParam->throw(error=>"Need an addressId.", param=>$addressId);
}
my $address = $book->session->db->quickHashRef('select * from address where addressId=?', [$addressId]);
if ($address->{addressId} eq "") {
WebGUI::Error::ObjectNotFound->throw(error=>"Address not found.", id=>$addressId);
}
if ($address->{addressBookId} ne $book->getId) {
WebGUI::Error::ObjectNotFound->throw(error=>"Address not in this address book.", id=>$addressId);
}
my $self = register $class;
my $id = id $self;
$addressBook{ $id } = $book;
$properties{ $id } = $address;
return $self;
}
#-------------------------------------------------------------------
=head2 update ( properties )
Sets properties of the address.
=head3 properties
A hash reference that contains one or more of the following:
=head4 label
A human readable label like "home" or "work".
=head4 name
The name of the company or person to address this to.
=head4 address1
The street name and number.
=head4 address2
Suite number or other addressing information.
=head4 address3
Care of info or other addressing information.
=head4 city
The city that this address is in.
=head4 state
The state or province that this address is in.
=head4 code
The postal code or zip code that this address is in.
=head4 country
The country that this address is in.
=head4 phoneNumber
A telephone number for this address. It is required by some shippers.
=head4 addressBookId
The address book that this address belongs to.
=cut
sub update {
my ($self, $newProperties) = @_;
my $id = id $self;
$properties{$id}{address2} = (exists $newProperties->{address2}) ? $newProperties->{address2} : $properties{$id}{address2};
$properties{$id}{address3} = (exists $newProperties->{address3}) ? $newProperties->{address3} : $properties{$id}{address3};
$properties{$id}{state} = (exists $newProperties->{state}) ? $newProperties->{state} : $properties{$id}{state};
$properties{$id}{code} = $newProperties->{code} || $properties{$id}{code};
$properties{$id}{city} = $newProperties->{city} || $properties{$id}{city};
$properties{$id}{label} = $newProperties->{label} || $properties{$id}{label};
$properties{$id}{name} = $newProperties->{name} || $properties{$id}{name};
$properties{$id}{country} = $newProperties->{country} || $properties{$id}{country};
$properties{$id}{address1} = $newProperties->{address1} || $properties{$id}{address1};
$properties{$id}{phoneNumber} = $newProperties->{phoneNumber} || $properties{$id}{phoneNumber};
$properties{$id}{addressBookId} = $self->addressBook->getId;
$self->addressBook->session->db->setRow("address","addressId",$properties{$id});
}
1;

View file

@ -0,0 +1,276 @@
package WebGUI::Shop::AddressBook;
use strict;
use Class::InsideOut qw{ :std };
use WebGUI::Asset::Template;
use WebGUI::Exception::Shop;
use WebGUI::International;
use WebGUI::Shop::Address;
=head1 NAME
Package WebGUI::Shop::AddressBook;
=head1 DESCRIPTION
Managing addresses for commerce.
=head1 SYNOPSIS
use WebGUI::Shop::AddressBook;
my $book = WebGUI::Shop::AddressBook->new($session);
=head1 METHODS
These subroutines are available from this package:
=cut
readonly session => my %session;
private properties => my %properties;
private error => my %error;
#-------------------------------------------------------------------
=head2 addAddress ( address )
Adds an address to the address book.
=head2 address
A hash reference containing address information.
=cut
sub addAddress {
my ($self, $address) = @_;
my $addressObj = WebGUI::Shop::Address->create( $self, $address);
return $addressObj;
}
#-------------------------------------------------------------------
=head2 convertToUser ( userId )
Converts a session based address book to be owned by a user. If the user already has an address book then the address book will be merged with this one.
=head3 userId
The userId to own this address book.
=cut
sub convertToUser {
my ($self, $userId) = @_;
$self->update({userId=>$userId});
my $other = $self->session->db->read("select addressBookId from addressBook where addressBookId<>? and userId=?", [$self->getId, $userId]);
while (my ($id) = $other->array) {
my $book = __PACKAGE__->new($self->session, $id);
foreach my $address (@{$book->getAddresses}) {
$address->update({addressBookId=>$self->getId});
}
$book->delete;
}
}
#-------------------------------------------------------------------
=head2 create ( session )
Constructor. Creates a new address book for this user if they don't have one. If the user is not logged in creates an address book attached to the session if there isn't one for the session. In any case returns a reference to the address book.
=head3 session
A reference to the current session.
=cut
sub create {
my ($class, $session) = @_;
unless (defined $session && $session->isa("WebGUI::Session")) {
WebGUI::Error::InvalidObject->throw(expected=>"WebGUI::Session", got=>(ref $session), error=>"Need a session.");
}
# check to see if we're dealing with a registered user or just a visitor
if ($session->user->userId ne "1") {
# check to see if this user or his session already has an address book
my $addressBookId = "";
my @ids = $session->db->buildArray("select addressBookId from addressBook where userId=? or sessionId=?",[$session->user->userId, $session->getId]);
if (scalar(@ids) > 0) {
# how are we looking
my $book = $class->new($session, $ids[0]);
if ($book->get("userId") eq "" || scalar(@ids) > 1) {
# it's attached to the session or we have too many
$book->convertToUser($session->user->userId);
}
# it's ours
return $book;
}
else {
# nope create one for the user
my $id = $session->db->setRow("addressBook", "addressBookId", {addressBookId=>"new", userId=>$session->user->userId});
return $class->new($session, $id);
}
}
else {
# check to see if this session already has an address book
my $addressBookId = $session->db->quickScalar("select addressBookId from addressBook where sessionId=?",[$session->getId]);
if ($addressBookId eq "") {
# nope, create one for the session
$addressBookId = $session->db->setRow("addressBook", "addressBookId", {addressBookId=>"new", sessionId=>$session->getId});
}
return $class->new($session, $addressBookId);
}
}
#-------------------------------------------------------------------
=head2 delete ()
Deletes this address book and all addresses contained in it.
=cut
sub delete {
my ($self) = @_;
foreach my $address (@{$self->addresses}) {
$address->delete;
}
$self->session->db->write("delete from addressBook where addressBookId=?",[$self->getId]);
undef $self;
return undef;
}
#-------------------------------------------------------------------
=head2 get ( [ property ] )
Returns a duplicated hash reference of this objects 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 cart.
=cut
sub getId {
my ($self) = @_;
return $self->get("addressBookId");
}
#-------------------------------------------------------------------
=head2 getAddresses ( )
Returns an array reference of address objects that are in this book.
=cut
sub getAddresses {
my ($self) = @_;
my @addressObjects = ();
my $addresses = $self->session->db->read("select addressId from addresses where addressBookId=?",[$self->getId]);
while (my ($addressId) = $addresses->array) {
push(@addressObjects, WebGUI::Shop::Address->new($self, $addressId));
}
return \@addressObjects;
}
#-------------------------------------------------------------------
=head2 new ( session, addressBookId )
Constructor. Instanciates a cart based upon a addressBookId.
=head3 session
A reference to the current session.
=head3 addressBookId
The unique id of an address book to instanciate.
=cut
sub new {
my ($class, $session, $addressBookId) = @_;
unless (defined $session && $session->isa("WebGUI::Session")) {
WebGUI::Error::InvalidObject->throw(expected=>"WebGUI::Session", got=>(ref $session), error=>"Need a session.");
}
unless (defined $addressBookId) {
WebGUI::Error::InvalidParam->throw(error=>"Need an addressBookId.");
}
my $addressBook = $session->db->quickHashRef('select * from addressBook where addressBookId=?', [$addressBookId]);
if ($addressBook->{addressBookId} eq "") {
WebGUI::Error::ObjectNotFound->throw(error=>"No such address book.", id=>$addressBookId);
}
my $self = register $class;
my $id = id $self;
$session{ $id } = $session;
$properties{ $id } = $addressBook;
return $self;
}
#-------------------------------------------------------------------
=head2 update ( properties )
Sets properties in the addressBook
=head3 properties
A hash reference that contains one of the following:
=head4 lastShipId
The last addressId used for shipping.
=head4 lastPayId
The last addressId used for payment.
=head4 userId
Assign the user that owns this address book.
=head4
Assign the session that owns this adress book. Will automatically be set to "" if a user owns it.
=cut
sub update {
my ($self, $newProperties) = @_;
my $id = id $self;
$properties{$id}{lastShipId} = $newProperties->{lastShipId} || $properties{$id}{lastShipId};
$properties{$id}{lastPayId} = $newProperties->{lastPayId} || $properties{$id}{lastPayId};
$properties{$id}{userId} = (exists $newProperties->{userId}) ? $newProperties->{userId} : $properties{$id}{userId};
$properties{$id}{sessionId} = (exists $newProperties->{sessionId}) ? $newProperties->{sessionId} : $properties{$id}{sessionId};
if ($properties{$id}{userId} ne "") {
$properties{$id}{sessionId} = "";
}
$self->session->db->setRow("addressBook","addressBookId",$properties{$id});
}
1;

View file

@ -49,9 +49,6 @@ A reference to a subclass of WebGUI::Asset::Sku.
sub addItem {
my ($self, $sku) = @_;
unless (defined $sku && $sku->isa("WebGUI::Asset::Sku")) {
WebGUI::Error::InvalidObject->throw(expected=>"WebGUI::Asset::Sku", got=>(ref $sku), error=>"Need a SKU item.");
}
my $item = WebGUI::Shop::CartItem->create( $self, $sku);
return $item;
}
@ -306,7 +303,7 @@ sub www_view {
extras=>q|onclick="this.form.method.value='removeItem';this.form.itemId.value='|.$item->getId.q|';this.form.submit;"|}),
shippingAddress => "todo",
shipToButton => WebGUI::Form::submit($session, {value=>$i18n->get("ship to button"),
extras=>q|onclick="this.form.shop.value='ship';this.form.method.value='viewAddressbook';this.form.itemId.value='|.$item->getId.q|';this.form.submit;"|}),
extras=>q|onclick="this.form.shop.value='address';this.form.method.value='view';this.form.itemId.value='|.$item->getId.q|';this.form.submit;"|}),
);
push(@items, \%properties);
}
@ -325,11 +322,11 @@ sub www_view {
continueShoppingButton => WebGUI::Form::submit($session, {value=>$i18n->get("continue shopping button"),
extras=>q|onclick="this.form.method.value='continueShopping';this.form.submit;"|}),
chooseShippingButton => WebGUI::Form::submit($session, {value=>$i18n->get("choose shipping button"),
extras=>q|onclick="this.form.shop.value='ship';this.form.method.value='viewAddressbook';this.form.submit;"|}),
extras=>q|onclick="this.form.shop.value='address';this.form.method.value='view';this.form.submit;"|}),
shipppingAddress => "todo",
shippingOptions => "todo",
shipToButton => WebGUI::Form::submit($session, {value=>$i18n->get("ship to button"),
extras=>q|onclick="this.form.shop.value='ship';this.form.method.value='viewAddressbook';this.form.submit;"|}),
extras=>q|onclick="this.form.shop.value='address';this.form.method.value='view';this.form.submit;"|}),
hasShippingAddress => "todo",
couponField => WebGUI::Form::text($session, {name=>"couponCode", value=>"", size=>20}),
couponDiscount => "todo",

View file

@ -150,9 +150,9 @@ sub incrementQuantity {
#-------------------------------------------------------------------
=head2 new ( session, cart, itemId )
=head2 new ( cart, itemId )
Constructor. Instanciates a cart based upon a cartId.
Constructor. Instanciates a cart item based upon itemId.
=head3 cart
@ -174,7 +174,7 @@ sub new {
}
my $item = $cart->session->db->quickHashRef('select * from cartItems where itemId=?', [$itemId]);
if ($item->{itemId} eq "") {
WebGUI::Error::ObjectNotFound->throw(error=>"Item not in cart.", id=>$itemId);
WebGUI::Error::ObjectNotFound->throw(error=>"Item not found.", id=>$itemId);
}
if ($item->{cartId} ne $cart->getId) {
WebGUI::Error::ObjectNotFound->throw(error=>"Item not in this cart.", id=>$itemId);