diff --git a/docs/upgrades/upgrade_7.10.18-7.10.19.pl b/docs/upgrades/upgrade_7.10.18-7.10.19.pl
index bb52cc93c..1ef1a5fa6 100644
--- a/docs/upgrades/upgrade_7.10.18-7.10.19.pl
+++ b/docs/upgrades/upgrade_7.10.18-7.10.19.pl
@@ -31,6 +31,7 @@ my $quiet; # this line required
my $session = start(); # this line required
# upgrade functions go here
+addTicketLimitToBadgeGroup( $session );
finish($session); # this line required
@@ -44,6 +45,21 @@ finish($session); # this line required
# print "DONE!\n" unless $quiet;
#}
+#----------------------------------------------------------------------------
+# Add a ticket limit to badges in a badge group
+sub addTicketLimitToBadgeGroup {
+ my $session = shift;
+ print "\tAdd ticket limit to badge groups... " unless $quiet;
+ # Make sure it hasn't been done already...
+ my $columns = $session->db->buildHashRef('describe EMSBadgeGroup');
+ use List::MoreUtils qw(any);
+ if(!any { $_ eq 'ticketsPerBadge' } keys %{$columns}) {
+ $session->db->write(q{
+ ALTER TABLE EMSBadgeGroup ADD COLUMN `ticketsPerBadge` INTEGER
+ });
+ }
+ print "DONE!\n" unless $quiet;
+}
# -------------- DO NOT EDIT BELOW THIS LINE --------------------------------
diff --git a/lib/WebGUI/Asset/Wobject/EventManagementSystem.pm b/lib/WebGUI/Asset/Wobject/EventManagementSystem.pm
index a47d10ba7..c5c1911fe 100644
--- a/lib/WebGUI/Asset/Wobject/EventManagementSystem.pm
+++ b/lib/WebGUI/Asset/Wobject/EventManagementSystem.pm
@@ -861,15 +861,75 @@ sub www_addTicketsToBadge {
my $self = shift;
my $session = $self->session;
return $session->privilege->insufficient() unless $self->canView;
- my $form = $session->form;
+ my ( $form, $db ) = $session->quick(qw{ form db });
+ my $i18n = WebGUI::International->new($self->session,'Asset_EventManagementSystem');
+
+ # get badge's badge groups
+ my $badgeId = $form->get('badgeId');
+ my %badgeGroups = (); # Hash of badgeGroupId => ticketsPerBadge
+ if (defined $badgeId) {
+ my $assetId = $db->quickScalar("select badgeAssetId from EMSRegistrant where badgeId=?",[$badgeId]);
+ my $badge = WebGUI::Asset->new($session, $assetId, 'WebGUI::Asset::Sku::EMSBadge');
+ if ( defined $badge ) {
+ my @badgeGroups = split("\n",$badge->get('relatedBadgeGroups'));
+ %badgeGroups = $db->buildHash(
+ "SELECT badgeGroupId, ticketsPerBadge FROM EMSBadgeGroup WHERE badgeGroupId IN (" . $db->quoteAndJoin(\@badgeGroups) . ")",
+ );
+ }
+ }
+
+ # get a list of tickets already associated with the badge
+ my @existingTickets = $db->buildArray("select ticketAssetId from EMSRegistrantTicket where badgeId=?",[$badgeId]);
+
+ # Determine the ticket limits per badge group
+ my %fullBadgeGroups = ();
+ for my $ticketId ( @existingTickets ) {
+ my $ticket = WebGUI::Asset->new( $session, $ticketId, 'WebGUI::Asset::Sku::EMSTicket' );
+ next unless $ticket;
+ # Every ticket takes one spot from every related badge group
+ # So a badge can never have more than the limit defined in any related badge group
+ # Badge groups that start at 0 are not limited
+ for my $badgeGroupId ( split "\n", $ticket->get('relatedBadgeGroups') ) {
+ if ( $badgeGroups{ $badgeGroupId } ) {
+ $badgeGroups{ $badgeGroupId }--;
+ # If we're reduced to 0 now, keep track
+ if ( $badgeGroups{ $badgeGroupId } == 0 ) {
+ $fullBadgeGroups{ $badgeGroupId } = 1;
+ }
+ }
+ }
+ }
+
+ # Add the tickets
my @ids = $form->param('assetId');
- foreach my $id (@ids) {
+ my @errors = (); # Error messages
+ TICKET: foreach my $id (@ids) {
my $ticket = WebGUI::Asset->new($session, $id, 'WebGUI::Asset::Sku::EMSTicket');
if (defined $ticket) {
- $ticket->addToCart({badgeId=>$form->get('badgeId')});
+ # Make sure we're allowed to add this ticket
+ my @ticketBadgeGroups = ( split "\n", $ticket->get('relatedBadgeGroups') );
+ for my $badgeGroupId ( @ticketBadgeGroups ) {
+ if ( $fullBadgeGroups{ $badgeGroupId } ) {
+ push @errors, sprintf( $i18n->get('error badge group ticket limit'), $ticket->getTitle );
+ next TICKET;
+ }
+ }
+
+ # Reduce our numbers
+ for my $badgeGroupId ( @ticketBadgeGroups ) {
+ if ( $badgeGroups{ $badgeGroupId } ) {
+ $badgeGroups{ $badgeGroupId }--;
+ # If we're reduced to 0 now, keep track
+ if ( $badgeGroups{ $badgeGroupId } == 0 ) {
+ $fullBadgeGroups{ $badgeGroupId } = 1;
+ }
+ }
+ }
+
+ $ticket->addToCart({badgeId=>$badgeId});
}
}
- return $self->www_getRegistrantAsJson();
+ return $self->www_getRegistrantAsJson( { errors => \@errors } );
}
#-------------------------------------------------------------------
@@ -1000,6 +1060,12 @@ sub www_editBadgeGroup {
label => $i18n->get('badge group name'),
hoverHelp => $i18n->get('badge group name help'),
);
+ $f->integer(
+ name => 'ticketsPerBadge',
+ value => $badgeGroup->{ticketsPerBadge} || 0,
+ label => $i18n->get('badge group ticketsPerBadge'),
+ hoverHelp => $i18n->get('badge group ticketsPerBadge help'),
+ );
$f->submit;
return $self->processStyle('
'.$i18n->get('badge groups').'
'.$f->print);
}
@@ -1022,6 +1088,7 @@ sub www_editBadgeGroupSave {
badgeGroupId => $id,
emsAssetId => $self->getId,
name => $form->get('name'),
+ ticketsPerBadge => $form->get('ticketsPerBadge','Integer'),
});
return $self->www_manageBadgeGroups;
}
@@ -1450,7 +1517,7 @@ Retrieves the properties of a specific badge and the items attached to it. Expec
=cut
sub www_getRegistrantAsJson {
- my ($self) = @_;
+ my ($self, $opt) = @_;
my $session = $self->session;
my $db = $session->db;
return $session->privilege->insufficient() unless $self->canView;
@@ -1468,6 +1535,11 @@ sub www_getRegistrantAsJson {
$badgeInfo->{sku} = $badge->get('sku');
$badgeInfo->{assetId} = $badge->getId;
$badgeInfo->{hasPurchased} = ($badgeInfo->{purchaseComplete}) ? 1 : 0;
+
+ # Add errors, if any
+ if ( $opt->{errors} && @{ $opt->{errors} } ) {
+ $badgeInfo->{errors} = $opt->{errors};
+ }
# get existing tickets
my $existingTickets = $db->read("select ticketAssetId from EMSRegistrantTicket where badgeId=? and purchaseComplete=1",[$badgeId]);
@@ -1830,16 +1902,39 @@ className='WebGUI::Asset::Sku::EMSTicket' and state='published' and revisionDate
# get badge's badge groups
my $badgeId = $form->get('badgeId');
- my @badgeGroups = ();
+ my %badgeGroups = (); # Hash of badgeGroupId => ticketsPerBadge
if (defined $badgeId) {
my $assetId = $db->quickScalar("select badgeAssetId from EMSRegistrant where badgeId=?",[$badgeId]);
my $badge = WebGUI::Asset->new($session, $assetId, 'WebGUI::Asset::Sku::EMSBadge');
- @badgeGroups = split("\n",$badge->get('relatedBadgeGroups')) if (defined $badge);
+ if ( defined $badge ) {
+ my @badgeGroups = split("\n",$badge->get('relatedBadgeGroups'));
+ %badgeGroups = $db->buildHash(
+ "SELECT badgeGroupId, ticketsPerBadge FROM EMSBadgeGroup WHERE badgeGroupId IN (" . $db->quoteAndJoin(\@badgeGroups) . ")",
+ );
+ }
}
-
+
# get a list of tickets already associated with the badge
my @existingTickets = $db->buildArray("select ticketAssetId from EMSRegistrantTicket where badgeId=?",[$badgeId]);
+ # Determine the ticket limits per badge group
+ my %fullBadgeGroups = ();
+ for my $ticketId ( @existingTickets ) {
+ my $ticket = WebGUI::Asset->new( $session, $ticketId, 'WebGUI::Asset::Sku::EMSTicket' );
+ next unless $ticket;
+ # Every ticket takes one spot from every related badge group
+ # So a badge can never have more than the limit defined in any related badge group
+ for my $badgeGroupId ( split "\n", $ticket->get('relatedBadgeGroups') ) {
+ if ( $badgeGroups{ $badgeGroupId } ) {
+ $badgeGroups{ $badgeGroupId }--;
+ # If we're reduced to 0 now, keep track
+ if ( $badgeGroups{ $badgeGroupId } == 0 ) {
+ $fullBadgeGroups{ $badgeGroupId } = 1;
+ }
+ }
+ }
+ }
+
# get assets
my $counter = 0;
my $totalTickets = scalar(@ids);
@@ -1868,19 +1963,18 @@ className='WebGUI::Asset::Sku::EMSTicket' and state='published' and revisionDate
}
# skip tickets not in our badge's badge groups
- if ($badgeId ne "" && scalar(@badgeGroups) > 0 && $ticket->get('relatedBadgeGroups') ne '') { # skip check if it has no badge groups
- my @groups = split("\n",$ticket->get('relatedBadgeGroups'));
+ if ($badgeId ne "" && keys %badgeGroups > 0 && $ticket->get('relatedBadgeGroups') ne '') { # skip check if it has no badge groups
+ my @badgeGroupIds = split("\n",$ticket->get('relatedBadgeGroups'));
my $found = 0;
- BADGE: {
- foreach my $a (@badgeGroups) {
- foreach my $b (@groups) {
- if ($a eq $b) {
- $found = 1;
- last BADGE;
- }
- }
- }
- }
+
+ for my $badgeGroupId ( @badgeGroupIds ) {
+ # Hash lookup is faster than array lookup
+ if ( exists $badgeGroups{ $badgeGroupId } ) {
+ $found = 1;
+ last;
+ }
+ }
+
unless ($found) {
$totalTickets--;
next;
@@ -1905,7 +1999,8 @@ className='WebGUI::Asset::Sku::EMSTicket' and state='published' and revisionDate
my $date = WebGUI::DateTime->new($session, mysql => $ticket->get('startDate'))
->set_time_zone($self->get("timezone"))
->webguiDate("%W %z %Z");
- push(@records, {
+
+ my $properties = {
title => $ticket->getTitle,
description => $description,
price => $ticket->getPrice+0,
@@ -1918,7 +2013,16 @@ className='WebGUI::Asset::Sku::EMSTicket' and state='published' and revisionDate
location => $ticket->get('location'),
startDate => $date,
duration => $ticket->get('duration'),
- });
+ };
+
+ # Determine if we're able to add this ticket due to Badge Group limits
+ for my $badgeGroupId ( split /\n/, $ticket->get('relatedBadgeGroups') ) {
+ if ( $fullBadgeGroups{ $badgeGroupId } ) {
+ $properties->{ limitReached } = 1;
+ }
+ }
+
+ push(@records, $properties);
last unless (scalar(@records) < $numberOfResults);
}
@@ -2493,6 +2597,13 @@ sub www_printBadge {
my $registrant = $self->getRegistrant($form->get('badgeId'));
my $badge = WebGUI::Asset::Sku::EMSBadge->new($session, $registrant->{badgeAssetId});
$registrant->{badgeTitle} = $badge->getTitle;
+
+ # Add badge metadata
+ my $meta = $badge->getMetaDataAsTemplateVariables;
+ for my $key ( keys %{$meta} ) {
+ $registrant->{ "badgeMeta_" . $key } = $meta->{ $key };
+ }
+
return $self->processTemplate($registrant,$self->get('printBadgeTemplateId'));
}
@@ -2586,6 +2697,13 @@ sub www_printTicket {
$registrant->{ticketDuration} = $ticket->get('duration');
$registrant->{ticketLocation} = $ticket->get('location');
$registrant->{ticketEventNumber} = $ticket->get('eventNumber');
+
+ # Add ticket metadata
+ my $meta = $ticket->getEventMetaData;
+ for my $key ( keys %{$meta} ) {
+ $registrant->{ "ticketMeta_" . $key } = $meta->{ $key };
+ }
+
return $self->processTemplate($registrant,$self->get('printTicketTemplateId'));
}
diff --git a/lib/WebGUI/Help/Asset_EventManagementSystem.pm b/lib/WebGUI/Help/Asset_EventManagementSystem.pm
index 16c9a3780..a38cf00ca 100644
--- a/lib/WebGUI/Help/Asset_EventManagementSystem.pm
+++ b/lib/WebGUI/Help/Asset_EventManagementSystem.pm
@@ -127,6 +127,7 @@ our $HELP = {
{ 'name' => 'purchaseComplete'},
{ 'name' => 'hasCheckedIn'},
{ 'name' => 'transactionItemId'},
+ { 'name' => 'badgeMeta_', description => 'help badgeMeta' },
],
isa => [
{ namespace => "Asset_Template",
@@ -217,6 +218,7 @@ our $HELP = {
{ 'name' => 'purchaseComplete'},
{ 'name' => 'hasCheckedIn'},
{ 'name' => 'transactionItemId'},
+ { 'name' => 'ticketMeta_', description => 'help ticketMeta' },
],
isa => [
{ namespace => "Asset_Template",
diff --git a/lib/WebGUI/i18n/English/Asset_EventManagementSystem.pm b/lib/WebGUI/i18n/English/Asset_EventManagementSystem.pm
index 20f8c2bbd..5c1426ece 100644
--- a/lib/WebGUI/i18n/English/Asset_EventManagementSystem.pm
+++ b/lib/WebGUI/i18n/English/Asset_EventManagementSystem.pm
@@ -2277,6 +2277,36 @@ normal templates.|,
# },
+ 'help badgeMeta' => {
+ message => 'Add a metadata value to the template by adding the name after "badgeMeta_". ex: badgeMeta_department',
+ lastUpdated => 0,
+ context => 'help text for template variable',
+ },
+
+ 'help ticketMeta' => {
+ message => 'Add a metadata value to the template by adding the name after "ticketMeta_". ex: ticketMeta_department',
+ lastUpdated => 0,
+ context => 'help text for template variable',
+ },
+
+ 'badge group ticketsPerBadge' => {
+ message => 'Tickets Per Badge',
+ lastUpdated => 0,
+ context => 'Label for badge group property',
+ },
+
+ 'badge group ticketsPerBadge help' => {
+ message => "The number of tickets each badge in this group is allowed to purchase",
+ lastUpdated => 0,
+ context => 'Help text for badge group property',
+ },
+
+ 'error badge group ticket limit' => {
+ message => q{Cannot add %s because ticket limit reached},
+ lastUpdated => 0,
+ context => q{Error message when trying to add too many tickets to a badge},
+ },
+
};
1;