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 ffd445339..076ae1713 100644 --- a/docs/upgrades/upgrade_7.5.2-7.5.3.pl +++ b/docs/upgrades/upgrade_7.5.2-7.5.3.pl @@ -36,9 +36,65 @@ addAddressBook($session); insertCommercePayDriverTable($session); addPaymentDrivers($session); convertTransactionLog($session); +upgradeEMS($session); finish($session); # this line required +#------------------------------------------------- +sub upgradeEMS { + my $session = shift; + print "\tUpgrading Event Manager\n" unless ($quiet); + my $db = $session->db; + $db->write("alter table EventManagementSystem add column timezone varchar(30) not null default value 'America/Chicago'"); + $db->write("alter table EventManagementSystem drop column globalMetadata"); + $db->write("alter table EventManagementSystem drop column globalPrerequisites"); + $db->write("create table EMSRegistrant ( + badgeId varchar(22) binary not null primary key, + userId varchar(22) binary, + badgeNumber int not null auto_increment unique, + badgeAssetId varchar(22) binary not null, + emsAssetId varchar(22) binary not null, + name varchar(35) binary not null, + address1 varchar(35), + address2 varchar(35), + address3 varchar(35), + city varchar(35), + state varchar(35), + zipcode varchar(35), + country varchar(35), + phoneNumber varchar(35), + organization varchar(35), + email varchar(255), + purchaseComplete boolean, + index badgeAssetId_purchaseComplete (badgeAssetId,purcahseComplete) + )"); + $db->write("create table EMSRegistrantTicket ( + badgeId varchar(22) binary not null primary key, + ticketAssetId varchar(22) binary not null, + purchaseComplete boolean, + index ticketAssetId_purchaseComplete (ticketAssetId,purchaseComplete) + )"); + $db->write("create table EMSBadge ( + assetId varchar(22) binary not null, + revisionDate bigint not null, + price float not null default 0.00, + seatsAvailable int not null default 100, + primary key (assetId, revisionDate) + )"); + $db->write("insert into incrementer values ('EMSBadgeNumber', 1)"); + $db->write("create table EMSTicket ( + assetId varchar(22) binary not null, + revisionDate bigint not null, + price float not null default 0.00, + seatsAvailable int not null default 100, + startDate datetime, + endDate datetTime, + eventNumber int, + relatedBadges mediumtext, + primary key (assetId, revisionDate) + )"); +} + #------------------------------------------------- sub convertTransactionLog { my $session = shift; diff --git a/lib/WebGUI/Asset/Sku.pm b/lib/WebGUI/Asset/Sku.pm index 7622cf389..fcd5484a7 100644 --- a/lib/WebGUI/Asset/Sku.pm +++ b/lib/WebGUI/Asset/Sku.pm @@ -66,25 +66,7 @@ A hash reference as generated by getOptions(). sub addToCart { my ($self, $options) = @_; $self->applyOptions($options); - my $cart = WebGUI::Shop::Cart->create($self->session); - $cart->addItem($self); -} - -#------------------------------------------------------------------- - -=head2 adjustQuantityAvailable ( amount ) - -Adjust the quantity of this product that is available. Send a negative number to decrease, or a positive number to increase. Returns getQuantityAvailable. - -=head3 amount - -A signed integer that represents the amount to adjust - -=cut - -sub adjustQuantityAvailable { - my ($self, $amount) = @_; - return $self->setQuantityAvailable($self->getQuantityAvailable + $amount); + $self->getCart->addItem($self); } #------------------------------------------------------------------- @@ -175,6 +157,13 @@ sub definition { } +#------------------------------------------------------------------- + +=head2 getCart ( ) { + my $self = shift; + return WebGUI::Shop::Cart->getCartBySession($self->session); +} + #------------------------------------------------------------------- =head2 getConfiguredTitle ( ) @@ -345,6 +334,61 @@ sub newBySku { return WebGUI::Asset->newByDynamicClass($session, $assetId); } +#------------------------------------------------------------------- + +=head2 onAdjustQuantityInCart ( item, amount ) + +Called just after the quantity is adjusted in the cart. Should be overridden by subclasses that need to account for inventory or other bookkeeping. + +=head3 item + +Receives a reference to the WebGUI::Shop::CartItem so it can determine things like itemId and quantity if it needs them for book keeping purposes. + +=head3 amount + +The amount to be adjusted for. Could be positive if more are being added to the cart or negative if more are being removed from the cart. + +=cut + +sub onAdjustQuantityInCart { + my ($self, $item, $amount) = @_; + return undef; +} + +#------------------------------------------------------------------- + +=head2 onCompletePurchase ( item ) + +Called just after payment has been made. It allows for privileges to be given, or bookkeeping +tasks to be performed. It should be overriden by subclasses that need to do special processing after the purchase. + +=head3 item + +Receives a reference to the WebGUI::Shop::CartItem so it can determine things like itemId and quantity if it needs them for book keeping purposes. + +=cut + +sub onCompletePurchase { + my ($self, $item) = @_; + return undef; +} + +#------------------------------------------------------------------- + +=head2 onRemoveFromCart ( item ) + +Called by the cart just B the item is removed from the cart. This allows for cleanup. Should be overridden by subclasses for inventory control or other housekeeping. + +=head3 item + +Receives a reference to the WebGUI::Shop::CartItem so it can determine things like itemId and quantity if it needs them for book keeping purposes. + +=cut + +sub onRemoveFromCart { + my ($self, $item) = @_; + return undef; +} #------------------------------------------------------------------- @@ -366,23 +410,6 @@ sub processStyle { #------------------------------------------------------------------- -=head2 setQuantityAvailable ( amount ) - -Set the quantity of this product that is available. Returns getQuantityAvailable(). Should be overridden by skus that keep track of quantity. - -=head3 amount - -A signed integer that represents the quantity to set it to. - -=cut - -sub setQuantityAvailable { - my ($self, $amount) = @_; - return $self->getQuantityAvailable; -} - -#------------------------------------------------------------------- - =head2 www_view ( ) Renders self->view based upon current style, subject to timeouts. Returns Privilege::noAccess() if canView is False. diff --git a/lib/WebGUI/Asset/Sku/EMSBadge.pm b/lib/WebGUI/Asset/Sku/EMSBadge.pm new file mode 100644 index 000000000..0cf6fbeb8 --- /dev/null +++ b/lib/WebGUI/Asset/Sku/EMSBadge.pm @@ -0,0 +1,271 @@ +package WebGUI::Asset::Sku::EMSBadge; + +=head1 LEGAL + + ------------------------------------------------------------------- + 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 + ------------------------------------------------------------------- + +=cut + +use strict; +use Tie::IxHash; +use base 'WebGUI::Asset::Sku'; +use JSON; +use WebGUI::HTMLForm; +use WebGUI::International; + + +=head1 NAME + +Package WebGUI::Asset::Sku::EMSBadge + +=head1 DESCRIPTION + +A badge for the Event Manager. + +=head1 SYNOPSIS + +use WebGUI::Asset::Sku::EMSBadge; + +=head1 METHODS + +These methods are available from this class: + +=cut + +#------------------------------------------------------------------- +sub addToCart { + my ($self, $badgeInfo) = @_; + $badgeInfo->{badgeId} = "new"; + $badgeInfo->{badgeAssetId} = $self->getId; + $badgeInfo->{emsAssetId} = $self->getParent->getId; + my $badgeId = $self->session->db->setRow("EMSRegistrant","badgeId", $badgeInfo); + $self->SUPER::addToCart({badgeId=>$badgeId, name=>$badgeInfo->{name}}); +} + +#------------------------------------------------------------------- +sub definition { + my $class = shift; + my $session = shift; + my $definition = shift; + my %properties; + tie %properties, 'Tie::IxHash'; + my $i18n = WebGUI::International->new($session, "Asset_EventManagementSystem"); + %properties = ( + price => { + tab => "commerce", + fieldType => "float", + defaultValue => 0.00, + label => $i18n->get("price"), + hoverHelp => $i18n->get("price help"), + }, + seatsAvailable => { + tab => "properties", + fieldType => "integer", + defaultValue => 100, + label => $i18n->get("seats available"), + hoverHelp => $i18n->get("seats available help"), + }, + ); + push(@{$definition}, { + assetName => $i18n->get('ems badge'), + icon => 'EMSBadge.gif', + autoGenerateForms => 1, + tableName => 'EMSBadge', + className => 'WebGUI::Asset::Sku::EMSBadge', + properties => \%properties + }); + return $class->SUPER::definition($session, $definition); +} + + +#------------------------------------------------------------------- +sub getConfiguredTitle { + my $self = shift; + return $self->getTitle." (".$self->getOptions->{name}.")"; +} + + +#------------------------------------------------------------------- +sub getMaxAllowedInCart { + return 1; +} + +#------------------------------------------------------------------- +sub getPrice { + my $self = shift; + return $self->get("price"); +} + +#------------------------------------------------------------------- +sub getQuantityAvailable { + my $self = shift; + my $seatsTaken = $self->session->db->quickScalar("select count(*) from EMSRegistrant where badgeAssetId=? and purchaseComplete=1",[$self->getId]); + return $self->get("seatsAvailable") - $seatsTaken; +} + +#------------------------------------------------------------------- +sub onCompletePurchase { + my ($self, $item) = @_; + my $badgeInfo = $self->getOptions; + $badgeInfo->{purchaseComplete} = 1; + $badgeInfo->{userId} = $self->session->user->userId; # they have to be logged in at this point + $self->session->db->setRow("EMSRegistrant","badgeId", $badgeInfo); + return undef; +} + +#------------------------------------------------------------------- +sub onRemoveFromCart { + my ($self, $item) = @_; + my $badgeId = $self->getOptions->{badgeId}; + foreach my $cartitem (@{$item->cart->getItems()}) { + if (isIn((ref $cartitem), qw(WebGUI::Asset::Sku::EMSTicket WebGUI::Asset::Sku::EMSRibbon WebGUI::Asset::Sku::EMSToken))) { + if ($cartitem->getSku->getOptions->{badgeId} eq $badgeId) { + $cartitem->remove; + } + } + } + $self->session->db->deleteRow('EMSRegistrant','badgeId',$badgeId); +} + +#------------------------------------------------------------------- +sub purge { + my $self = shift; + $self->session->db->write("delete from EMSRegistrant where badgeAssetId=?",[$self->getId]); + $self->SUPER::purge; +} + +#------------------------------------------------------------------- +sub view { + my ($self) = @_; + + my $error = $self->{_errorMessage}; + my $i18n = WebGUI::International->new($self->session, "Asset_EventManagementSystem"); + my $form = $self->session->form; + + # build the form to allow the user to choose from their address book + my $book = WebGUI::HTMLForm->new($self->session, action=>$self->getUrl); + $book->hidden(name=>"shop", value=>"address"); + $book->hidden(name=>"method", value=>"view"); + $book->hidden(name=>"callback", value=>JSON::to_json({ + url => $self->getUrl, + })); + $book->submit(value=>$i18n->get("populate from address book")); + + # instanciate address + my $address = WebGUI::Shop::Address->new($self->session, $form->get("addressId")) if ($form->get("addressId")); + + # build the form that the user needs to fill out with badge holder information + my $info = WebGUI::HTMLForm->new($self->session, action=>$self->getUrl); + $info->hidden(name=>"func", value=>"addToCart"); + $info->text( + name => 'name', + defaultValue => (defined $address) ? $address->get("name") : $form->get('name'), + label => $i18n->get('name','Shop'), + ); + $info->text( + name => 'organization', + defaultValue => $form->get("organization"), + label => $i18n->get('organization'), + ); + $info->text( + name => 'address1', + defaultValue => (defined $address) ? $address->get("address1") : $form->get('address1'), + label => $i18n->get('address','Shop'), + ); + $info->text( + name => 'address2', + defaultValue => (defined $address) ? $address->get("address2") : $form->get('address2'), + ); + $info->text( + name => 'address3', + defaultValue => (defined $address) ? $address->get("address3") : $form->get('address3'), + ); + $info->text( + name => 'city', + defaultValue => (defined $address) ? $address->get("city") : $form->get('city'), + label => $i18n->get('city','Shop'), + ); + $info->text( + name => 'state', + defaultValue => (defined $address) ? $address->get("state") : $form->get('state'), + label => $i18n->get('state','Shop'), + ); + $info->zipcode( + name => 'zipcode', + defaultValue => (defined $address) ? $address->get("code") : $form->get('zipcode','zipcode'), + label => $i18n->get('code','Shop'), + ); + $info->country( + name => 'country', + defaultValue => (defined $address) ? $address->get("country") : ($form->get('country') || 'United States'), + label => $i18n->get('country','Shop'), + ); + $info->phone( + name => 'phoneNumber', + defaultValue => (defined $address) ? $address->get("phoneNumber") : $form->get("phone","phone"), + label => $i18n->get('phone number','Shop'), + ); + $info->email( + name => 'email', + label => $i18n->get('email address'), + defaultValue => $form->get("email","email") + ); + $info->submit(value=>"add to cart"); + + # render the page; + my $output = '

'.$self->getTitle.'

' + .'

'.$self->get('description').'

' + .'

'.$i18n->get("badge holder information").'

' + .$book->print; + if ($error ne "") { + $output .= '

'.$error.'

'; + } + $output .= $info->print; + return $output; +} + + +#------------------------------------------------------------------- +sub www_addToCart { + my ($self) = @_; + return $self->session->privilege->noAccess() unless $self->getParent->canView; + + # gather badge info + my $form = $self->session->form; + my %badgeInfo = (); + foreach my $field (qw(name address1 address2 address3 city state organization)) { + $badgeInfo{$field} = $form->get($field, "text"); + } + $badgeInfo{'phoneNumber'} = $form->get('phoneNumber', 'phone'); + $badgeInfo{'email'} = $form->get('email', 'email'); + $badgeInfo{'country'} = $form->get('country', 'country'); + $badgeInfo{'zipcode'} = $form->get('zipcode', 'zipcode'); + + + # check for required fields + my $error = ""; + my $i18n = WebGUI::International->new($self->session, 'Asset_EventManagementSystem'); + if ($badgeInfo{name} eq "") { + $error = sprintf $i18n->get('is required'), $i18n->get('name','Shop'); + } + + # return them back to the previous screen if they messed up + if ($error) { + $self->{_errorMessage} = $error; + return $self->www_view($error); + } + + # add it to the cart + $self->addToCart(\%badgeInfo); + return $self->getParent->www_view; +} + +1; diff --git a/lib/WebGUI/Asset/Sku/EMSTicket.pm b/lib/WebGUI/Asset/Sku/EMSTicket.pm new file mode 100644 index 000000000..8a9c108ac --- /dev/null +++ b/lib/WebGUI/Asset/Sku/EMSTicket.pm @@ -0,0 +1,169 @@ +package WebGUI::Asset::Sku::EMSTicket; + +=head1 LEGAL + + ------------------------------------------------------------------- + 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 + ------------------------------------------------------------------- + +=cut + +use strict; +use Tie::IxHash; +use base 'WebGUI::Asset::Sku'; + + + +=head1 NAME + +Package WebGUI::Asset::Sku::EMSBadge + +=head1 DESCRIPTION + +A badge for the Event Manager. + +=head1 SYNOPSIS + +use WebGUI::Asset::Sku::EMSBadge; + +=head1 METHODS + +These methods are available from this class: + +=cut + +#------------------------------------------------------------------- +sub addToCart { + my ($self, $badgeInfo) = @_; + $self->session->db->write("insert into EMSRegistrantTicket (badgeId, ticketAssetId) values (?,?)", + [$badgeInfo->{badgeId},$self->getId]); + $self->addToCart($badgeInfo); +} + +#------------------------------------------------------------------- +sub definition { + my $class = shift; + my $session = shift; + my $definition = shift; + my %properties; + tie %properties, 'Tie::IxHash'; + my $i18n = WebGUI::International->new($session, "Asset_EventManagementSystem"); + my $date = WebGUI::DateTime->new($session, time()); + %properties = ( + price => { + tab => "commerce", + fieldType => "float", + defaultValue => 0.00, + label => $i18n->get("price"), + hoverHelp => $i18n->get("price help"), + }, + seatsAvailable => { + tab => "properties", + fieldType => "integer", + defaultValue => 25, + label => $i18n->get("seats available"), + hoverHelp => $i18n->get("seats available help"), + }, + eventNumber => { + tab => "properties", + fieldType => "integer", + defaultValue => $session->db->quickScalar("select max(eventNumber)+1 from EMSTicket"), + label => $i18n->get("seats available"), + hoverHelp => $i18n->get("seats available help"), + }, + startDate => { + tab => "properties", + fieldType => "dateTime", + defaultValue => $date->toDatabase, + label => $i18n->get("add/edit event start date"), + hoverHelp => $i18n->get("add/edit event start date description"), + }, + endDate => { + tab => "properties", + fieldType => "dateTime", + defaultValue => $date->toDatabase, + label => $i18n->get("add/edit event end date"), + hoverHelp => $i18n->get("add/edit event end date description"), + }, + relatedBadges => { + tab => "properties", + fieldType => "checkList", + options => {}, + defaultValue => undef, + label => $i18n->get("related badges"), + hoverHelp => $i18n->get("related badges help"), + }, + ); + push(@{$definition}, { + assetName => $i18n->get('ems ticket'), + icon => 'EMSTicket.gif', + autoGenerateForms => 1, + tableName => 'EMSTicket', + className => 'WebGUI::Asset::Sku::EMSTicket', + properties => \%properties + }); + return $class->SUPER::definition($session, $definition); +} + + +#------------------------------------------------------------------- +sub getConfiguredTitle { + my $self = shift; + return $self->getTitle." (".$self->getOptions->{name}.")"; +} + +#------------------------------------------------------------------- +sub getMaxAllowedInCart { + return 1; +} + +#------------------------------------------------------------------- +sub getPrice { + my $self = shift; + return $self->get("price"); +} + +#------------------------------------------------------------------- +sub getQuantityAvailable { + my $self = shift; + my $seatsTaken = $self->session->db->quickScalar("select count(*) from EMSRegistrantTicket where ticketAssetId=? and purchaseComplete=1",[$self->getId]); + return $self->get("seatsAvailable") - $seatsTaken; +} + +#------------------------------------------------------------------- +sub onCompletePurchase { + my ($self, $item) = @_; + $self->session->db->write("update EMSRegistrantTicket set purchaseComplete=1 where ticketAssetId=? and badgeId=?", + [$self->getId, $self->getOptions->{badgeId}]); + return undef; +} + +#------------------------------------------------------------------- +sub onRemoveFromCart { + my ($self, $item) = @_; + $self->session->db->write("delete from EMSRegistrantTicket where ticketAssetId=? and badgeId=?", + [$self->getId, $self->getOptions->{badgeId}]); +} + +#------------------------------------------------------------------- +sub purge { + my $self = shift; + $self->session->db->write("delete from EMSRegistrantTicket where ticketAssetId=?",[$self->getId]); + $self->SUPER::purge; +} + +#------------------------------------------------------------------- +sub view { + my ($self) = @_; + my $session = $self->session; + return "Don't know what it is to view this thing."; +} + + +1; diff --git a/lib/WebGUI/Asset/Wobject/EventManagementSystem.pm b/lib/WebGUI/Asset/Wobject/EventManagementSystem.pm index fa73eab01..727236994 100644 --- a/lib/WebGUI/Asset/Wobject/EventManagementSystem.pm +++ b/lib/WebGUI/Asset/Wobject/EventManagementSystem.pm @@ -454,95 +454,88 @@ sub definition { tie %properties, 'Tie::IxHash'; my $i18n = WebGUI::International->new($session,'Asset_EventManagementSystem'); %properties = ( - displayTemplateId =>{ - fieldType=>"template", - defaultValue=>'EventManagerTmpl000001', - tab=>"display", - namespace=>"EventManagementSystem", - hoverHelp=>$i18n->get('display template description'), - label=>$i18n->get('display template') - }, - checkoutTemplateId =>{ - fieldType=>"template", - defaultValue=>'EventManagerTmpl000003', - tab=>"display", - namespace=>"EventManagementSystem_checkout", - hoverHelp=>$i18n->get('checkout template description'), - label=>$i18n->get('checkout template') - }, - managePurchasesTemplateId =>{ - fieldType=>"template", - defaultValue=>'EventManagerTmpl000004', - tab=>"display", - namespace=>"EventManagementSystem_managePurchas", - hoverHelp=>$i18n->get('manage purchases template description'), - label=>$i18n->get('manage purchases template') - }, - viewPurchaseTemplateId =>{ - fieldType=>"template", - defaultValue=>'EventManagerTmpl000005', - tab=>"display", - namespace=>"EventManagementSystem_viewPurchase", - hoverHelp=>$i18n->get('view purchase template description'), - label=>$i18n->get('view purchase template') - }, - searchTemplateId =>{ - fieldType=>"template", - defaultValue=>'EventManagerTmpl000006', - tab=>"display", - namespace=>"EventManagementSystem_search", - hoverHelp=>$i18n->get('search template description'), - label=>$i18n->get('search template') - }, - badgePrinterTemplateId => { - fieldType => "template", - defaultValue => "emsbadgeprintout000000", - tab => "display", - namespace => "emsbadgeprint", - lable => "Badge Printer Template", - }, - ticketPrinterTemplateId => { - fieldType => "template", - defaultValue => "emsticketprintout00000", - tab => "display", - namespace => "emsticketprint", - lable => "Ticket Printer Template", - }, - paginateAfter =>{ - fieldType=>"integer", - defaultValue=>10, - tab=>"display", - hoverHelp=>$i18n->get('paginate after description'), - label=>$i18n->get('paginate after') - }, - groupToAddEvents =>{ - fieldType=>"group", - defaultValue=>3, - tab=>"security", - hoverHelp=>$i18n->get('group to add events description'), - label=>$i18n->get('group to add events') - }, - groupToApproveEvents =>{ - fieldType=>"group", - defaultValue=>3, - tab=>"security", - hoverHelp=>$i18n->get('group to approve events description'), - label=>$i18n->get('group to approve events') - }, - globalPrerequisites =>{ - fieldType=>"yesNo", - defaultValue=>1, - tab=>"properties", - label=>$i18n->get('global prerequisite'), - hoverHelp=>$i18n->get('global prerequisite description') - }, - globalMetadata =>{ - fieldType=>"yesNo", - defaultValue=>1, - tab=>"properties", - label=>$i18n->get('global metadata'), - hoverHelp=>$i18n->get('global metadata description') - }, + timezone => { + fieldType => 'TimeZone', + defaultValue => 'America/Chicago', + tab => 'properties', + label => $i18n->get('time zone'), + hoverHelp => $i18n->get('time zone help'), + }, + displayTemplateId =>{ + fieldType=>"template", + defaultValue=>'EventManagerTmpl000001', + tab=>"display", + namespace=>"EventManagementSystem", + hoverHelp=>$i18n->get('display template description'), + label=>$i18n->get('display template') + }, + checkoutTemplateId =>{ + fieldType=>"template", + defaultValue=>'EventManagerTmpl000003', + tab=>"display", + namespace=>"EventManagementSystem_checkout", + hoverHelp=>$i18n->get('checkout template description'), + label=>$i18n->get('checkout template') + }, + managePurchasesTemplateId =>{ + fieldType=>"template", + defaultValue=>'EventManagerTmpl000004', + tab=>"display", + namespace=>"EventManagementSystem_managePurchas", + hoverHelp=>$i18n->get('manage purchases template description'), + label=>$i18n->get('manage purchases template') + }, + viewPurchaseTemplateId =>{ + fieldType=>"template", + defaultValue=>'EventManagerTmpl000005', + tab=>"display", + namespace=>"EventManagementSystem_viewPurchase", + hoverHelp=>$i18n->get('view purchase template description'), + label=>$i18n->get('view purchase template') + }, + searchTemplateId =>{ + fieldType=>"template", + defaultValue=>'EventManagerTmpl000006', + tab=>"display", + namespace=>"EventManagementSystem_search", + hoverHelp=>$i18n->get('search template description'), + label=>$i18n->get('search template') + }, + badgePrinterTemplateId => { + fieldType => "template", + defaultValue => "emsbadgeprintout000000", + tab => "display", + namespace => "emsbadgeprint", + lable => "Badge Printer Template", + }, + ticketPrinterTemplateId => { + fieldType => "template", + defaultValue => "emsticketprintout00000", + tab => "display", + namespace => "emsticketprint", + lable => "Ticket Printer Template", + }, + paginateAfter =>{ + fieldType=>"integer", + defaultValue=>10, + tab=>"display", + hoverHelp=>$i18n->get('paginate after description'), + label=>$i18n->get('paginate after') + }, + groupToAddEvents =>{ + fieldType=>"group", + defaultValue=>3, + tab=>"security", + hoverHelp=>$i18n->get('group to add events description'), + label=>$i18n->get('group to add events') + }, + groupToApproveEvents =>{ + fieldType=>"group", + defaultValue=>3, + tab=>"security", + hoverHelp=>$i18n->get('group to approve events description'), + label=>$i18n->get('group to approve events') + }, ); push(@{$definition}, { assetName=>$i18n->get('assetName'), @@ -4114,8 +4107,29 @@ $self->getUrl('func=addToScratchCart;pid='.$event->{'productId'}.";mid=".$master return $self->processStyle($self->processTemplate(\%var,$self->getValue("searchTemplateId"))); } + #------------------------------------------------------------------- sub view { + my ($self) = @_; + my $session = $self->session; + return $session->privilege->noAccess() unless $self->canView; + + # set up objects we'll need + my $i18n = WebGUI::International->new($session, "Asset_EventManagementSystem"); + my %var = (); + + # get our badges + foreach my $badge (@{$self->getLineage(["children"],{returnObjects=>1, includeOnlyClasses=>["WebGUI::Asset::Sku::EMSBadge"]})}) { + push(@{$var{availableBadges}}, $self->get); + $var{availableBadges}[-1]{isFull} = $badge->getQuantityAvailable; + $var{availableBadges}[-1]{url} = $badge->getUrl; + } + + +} + +#------------------------------------------------------------------- +sub viewOLD { my $self = shift; my %var; return $self->session->privilege->noAccess() unless $self->canView; diff --git a/lib/WebGUI/Shop/Cart.pm b/lib/WebGUI/Shop/Cart.pm index 5ed45ad38..243bfa661 100644 --- a/lib/WebGUI/Shop/Cart.pm +++ b/lib/WebGUI/Shop/Cart.pm @@ -101,7 +101,7 @@ sub create { =head2 delete () -Deletes this cart and all cartItems contained in it. +Deletes this cart and removes all cartItems contained in it. Also see onCompletePurchase() and empty(). =cut @@ -117,7 +117,7 @@ sub delete { =head2 empty () -Removes all items from this cart. +Removes all items from this cart. Also see onCompletePurchase() and delete(). =cut @@ -322,6 +322,23 @@ sub new { #------------------------------------------------------------------- +=head2 onCompletePurchase () + +Calls onCompletePurchase() on all the items in the cart. Then deletes all the items in the cart without calling $item->remove() on them which would affect inventory levels. See also delete() and empty(). + +=cut + +sub onCompletePurchase { + my $self = shift; + foreach my $item (@{$self->getItems}) { + $item->getSku->completePurchase($item); + $item->delete; + } + $self->delete; +} + +#------------------------------------------------------------------- + =head2 update ( properties ) Sets properties in the cart. diff --git a/lib/WebGUI/Shop/CartItem.pm b/lib/WebGUI/Shop/CartItem.pm index 4bf10fd6b..47232abcb 100644 --- a/lib/WebGUI/Shop/CartItem.pm +++ b/lib/WebGUI/Shop/CartItem.pm @@ -65,12 +65,27 @@ sub create { $cart->session->db->write('insert into cartItem (quantity, cartId, assetId, itemId, dateAdded) values (1,?,?,?,now())', [$cart->getId, $sku->getId, $itemId]); my $self = $class->new($cart, $itemId); $self->update({asset=>$sku}); - $sku->adjustQuantityAvailable(-1); + $sku->onAdjustQuantityInCart($self, 1); return $self; } #------------------------------------------------------------------- +=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); + undef $self; + return undef; +} + +#------------------------------------------------------------------- + =head2 get ( [ property ] ) Returns a duplicated hash reference of this object’s data. @@ -204,15 +219,14 @@ sub new { =head2 remove ( ) -Removes this item from the cart. +Removes this item from the cart and calls $sku->onRemoveFromCart. See also delete(). =cut sub remove { my $self = shift; - $self->cart->session->db->deleteRow("cartItem","itemId",$self->getId); - undef $self; - return undef; + $self->getSku->onRemoveFromCart($self); + return $self->delete; } @@ -229,18 +243,18 @@ The number to set the quantity to. Zero or less will remove the item from cart. =cut sub setQuantity { - my ($self, $quantity) = @_; + my ($self, $newQuantity) = @_; my $id = id $self; my $currentQuantity = $self->get("quantity"); - if ($quantity > $self->getSku->getMaxAllowedInCart) { + if ($newQuantity > $self->getSku->getMaxAllowedInCart) { WebGUI::Error::Shop::MaxOfItemInCartReached->throw(error=>"Cannot have that many of this item in cart."); } - if ($quantity <= 0) { + if ($newQuantity <= 0) { return $self->remove; } - $properties{$id}{quantity} = $quantity; - $self->getSku->adjustQuantityAvailable($currentQuantity + $quantity); + $properties{$id}{quantity} = $newQuantity; $self->cart->session->db->setRow("cartItem","itemId", $properties{$id}); + $self->getSku->onAdjustQuantityInCart($self, $newQuantity - $currentQuantity); } #------------------------------------------------------------------- diff --git a/lib/WebGUI/Shop/Transaction.pm b/lib/WebGUI/Shop/Transaction.pm index 422233a32..b191f5ee3 100644 --- a/lib/WebGUI/Shop/Transaction.pm +++ b/lib/WebGUI/Shop/Transaction.pm @@ -26,6 +26,17 @@ This package keeps records of every puchase made. use WebGUI::Shop::Transaction; my $transaction = WebGUI::Shop::Transaction->new($session, $id); + + # typical transaction goes like this: + my $transaction = WebGUI::Shop::Transaction->create({ cart=>$cart, paymentMethod=>$paymentMethod, paymentAddress=>$address}); + my ($transactionNumber, $status, $message) = $paymentMethod->tryTransaction; + if ($status eq "somekindofsuccess") { + $transaction->completePurchase($cart, $transactionNumber, $status, $message); + } + else { + $transaction->denyPurchase($transactionNumber, $status, $message); + } + =head1 METHODS @@ -56,6 +67,41 @@ sub addItem { #------------------------------------------------------------------- +=head2 completePurchase ( cart, transactionCode, statusCode, statusMessage ) + +See also denyPurchase(). Completes a purchase by updating the transaction as a success, and clearing the cart of it's items. + +=head3 cart + +A reference to the current cart that's full of items just purchased. + +=head3 transactionCode + +The transaction id or code given by the payment gateway. + +=head3 statusCode + +The status code that came back from the payment gateway when trying to process the payment. + +=head3 statusMessage + +The extended status message that came back from the payment gateway when trying to process the payment. + +=cut + +sub completePurchase { + my ($self, $cart, $transactionCode, $statusCode, $statusMessage) = @_; + $cart->completePurchase; + $self->update({ + transactionCode => $transactionCode, + isSuccessful => 1, + statusCode => $statusCode, + statusMessage => $statusMessage, + }); +} + +#------------------------------------------------------------------- + =head2 create ( session, properties ) Constructor. Creates a new transaction object. Returns a reference to the object. @@ -103,6 +149,36 @@ sub delete { #------------------------------------------------------------------- +=head2 denyPurchase ( transactionCode, statusCode, statusMessage ) + +Completes a purchase as a failure. It could be that the user didn't enter their credit cart correctly, or they may have insufficient funds. + +=head3 transactionCode + +The transaction id or code given by the payment gateway. + +=head3 statusCode + +The status code that came back from the payment gateway when trying to process the payment. + +=head3 statusMessage + +The extended status message that came back from the payment gateway when trying to process the payment. + +=cut + +sub denyPurchase { + my ($self, $transactionCode, $statusCode, $statusMessage) = @_; + $self->update({ + isSuccessful => 0, + transactionCode => $transactionCode, + statusCode => $statusCode, + statusMessage => $statusMessage + }); +} + +#------------------------------------------------------------------- + =head2 formatCurrency ( amount ) Formats a number as a float with two digits after the decimal like 0.00. diff --git a/lib/WebGUI/i18n/English/Asset_EventManagementSystem.pm b/lib/WebGUI/i18n/English/Asset_EventManagementSystem.pm index 2fe7fb906..57aff7259 100644 --- a/lib/WebGUI/i18n/English/Asset_EventManagementSystem.pm +++ b/lib/WebGUI/i18n/English/Asset_EventManagementSystem.pm @@ -2,13 +2,86 @@ package WebGUI::i18n::English::Asset_EventManagementSystem; use strict; our $I18N = { ##hashref of hashes + + 'is required' => { + message => q|%s is required.|, + lastUpdated => 0, + context => q|used in an error message|, + }, + + 'email address' => { + message => q|Email Address|, + lastUpdated => 0, + context => q|form label|, + }, + + 'organization' => { + message => q|Organization|, + lastUpdated => 0, + context => q|form label for company/school/etc|, + }, + + 'badge holder information' => { + message => q|Badge Holder Information|, + lastUpdated => 0, + context => q|heading on add badge to cart screen|, + }, + + 'add to cart' => { + message => q|Add To Cart|, + lastUpdated => 0, + context => q|a button on the add badge to cart screen|, + }, + + 'populate from address book' => { + message => q|Populate From Address Book|, + lastUpdated => 0, + context => q|a button on the add badge to cart screen|, + }, + + 'related badges' => { + message => q|Related Badges|, + lastUpdated => 0, + context => q|a property label|, + }, + + 'related badges help' => { + message => q|Check the badges that can act as a prerequisite to being able to attend this event.|, + lastUpdated => 0, + context => q|help for a property label|, + }, + + 'event number' => { + message => q|Event Number|, + lastUpdated => 0, + context => q|a property label|, + }, + + 'event number help' => { + message => q|A number that represents the event, which is easily referenceable for things like event catalogs.|, + lastUpdated => 0, + context => q|help for a property label|, + }, + + 'time zone' => { + message => q|Time Zone|, + lastUpdated => 0, + context => q|a property label|, + }, + + 'time zone help' => { + message => q|Select the time zone that this event will be taking place in.|, + lastUpdated => 0, + context => q|help for a property label|, + }, + 'cancel registration' => { message => q|Cancel Registration|, lastUpdated => 0, context => q|Label for hyperlink asking user if they wish to cancel the registration process during checkout.|, }, - 'search template' => { + 'search template' => { message => q|Search Template|, lastUpdated => 1131394070, context => q|Field label for template selector| @@ -172,8 +245,15 @@ our $I18N = { ##hashref of hashes }, 'price' => { - message => q|Price|, + message => q|Price|, lastUpdated => 1138312761, + context => q|field label|, + }, + + 'price help' => { + message => q|How much do you want to charge for this item?|, + lastUpdated => 0, + context => q|field label help|, }, 'add/edit event price description' => { @@ -191,22 +271,12 @@ our $I18N = { ##hashref of hashes lastUpdated => 1160109886, }, - 'add/edit event maximum attendees' => { - message => q|Maximum Attendees|, - lastUpdated => 1138312761, - }, - 'add/edit approve event' => { message => q|Approve Event|, lastUpdated => 1138312761, context => q|URL to approve an event in the Add/Edit Event form|, }, - 'add/edit event maximum attendees description' => { - message => q|Based on room size, chairs, staffing and other requirements, the number of people who can attend the event.|, - lastUpdated => 1138899055, - }, - 'add/edit event required events' => { message => q|Required Events|, lastUpdated => 1138902214, @@ -284,16 +354,6 @@ our $I18N = { ##hashref of hashes lastUpdated => 1138904660, }, - 'global prerequisite' => { - message => q|Global Prerequisites|, - lastUpdated => 1138312761, - }, - - 'global prerequisite description' => { - message => q|When set to yes, you may assign events belonging to another instance of an Event Management System Asset as a prerequisite event for one of the events defined in this instance of the asset. When set to no, only events defined within this instance of the asset may be used as prerequisites.|, - lastUpdated => 1165364300, - }, - 'price must be greater than zero' => { message => q|Price must be greater than zero.|, lastUpdated => 1138312761, @@ -510,7 +570,7 @@ our $I18N = { ##hashref of hashes context => q|When a required field is empty/blank, then this message is used in sprintf to tell the user which field it is and that it cannot be blank|, }, - 'add to cart' => { + 'add to badge' => { message => q|Add To Badge|, lastUpdated => 1140466438, context => q|Label to invite the user to purchase this event and add it to their shopping cart.|, @@ -987,18 +1047,21 @@ by setting the "hide" form variable.|, }, 'assetName' => { - message => q|Event Manager (beta)|, + message => q|Event Manager (beta)|, lastUpdated => 1131394072, + context => q|name of asset|, }, - 'global metadata' => { - message => q|Use Global Event Metadata|, - lastUpdated => 1140469381, + 'ems badge' => { + message => q|Event Manager Badge|, + lastUpdated => 0, + context => q|name of asset|, }, - 'global metadata description' => { - message => q|Whether or not to use all other Event Management Systems Metadata Fields when assigning metadata to events and searching for events.

The management screen list of metadata fields for this asset will still remain limited to those created by this EMS asset.
|, - lastUpdated => 1140469381, + 'ems ticket' => { + message => q|Event Manager Ticket|, + lastUpdated => 0, + context => q|name of asset|, }, 'type name here' => { @@ -1017,8 +1080,8 @@ by setting the "hide" form variable.|, }, 'confirm delete event metadata' => { - message => q|Are you certain you want to delete this metadata field? The metadata values for this field will be deleted from all events, including events in other EMS wobjects that are set to use global metadata.|, - lastUpdated => 1140469381, + message => q|Are you certain you want to delete this metadata field? The metadata values for this field will be deleted from all events.|, + lastUpdated => 1205860492, }, 'manage purchases' => { @@ -1105,8 +1168,15 @@ by setting the "hide" form variable.|, }, 'seats available' => { - message => q|Seats Available|, + message => q|Seats Available|, lastUpdated => 1145400186, + context => q|field label|, + }, + + 'seats available help' => { + message => q|How many people may purchase this item before you run out of room?|, + lastUpdated => 0, + context => q|field label help|, }, 'missing prerequisites message' => {