diff --git a/lib/WebGUI/Asset/Wobject/EventManagementSystem.pm b/lib/WebGUI/Asset/Wobject/EventManagementSystem.pm index f1f4d3ad0..453441583 100644 --- a/lib/WebGUI/Asset/Wobject/EventManagementSystem.pm +++ b/lib/WebGUI/Asset/Wobject/EventManagementSystem.pm @@ -107,6 +107,14 @@ sub definition { hoverHelp => $i18n->get('print ticket template help'), namespace => 'EMS/PrintTicket', }, + printRemainingTicketsTemplateId => { + fieldType => 'template', + defaultValue => 'hreA_bgxiTX-EzWCSZCZJw', + tab => 'display', + label => $i18n->get('print remaining ticket template'), + hoverHelp => $i18n->get('print remaining ticket template help'), + namespace => 'EMS/PrintRemainingTickets', + }, badgeInstructions => { fieldType => 'HTMLArea', defaultValue => $i18n->get('default badge instructions'), @@ -553,6 +561,7 @@ sub www_buildBadge { importTicketsUrl => $self->getUrl('func=importEvents'), exportTicketsUrl => $self->getUrl('func=exportEvents'), getTicketsUrl => $self->getUrl('func=getTicketsAsJson;badgeId='.$badgeId), + printRemainingTicketsUrl => $self->getUrl('func=printRemainingTickets'), canEdit => $self->canEdit, hasBadge => ($badgeId ne ""), badgeId => $badgeId, @@ -1957,6 +1966,62 @@ sub www_printBadge { #------------------------------------------------------------------- +=head2 www_printRemainingTickets () + +Displays all of the remaining tickets for this EMS + +=cut + +sub www_printRemainingTickets { + my $self = shift; + my $session = $self->session; + return $session->privilege->insufficient() unless ($self->isRegistrationStaff); + + my $var = $self->get; + my $sth = $session->db->read(qq{ + SELECT + asset.creationDate, + assetData.*, + assetData.title as ticketTitle, + EMSTicket.price, + EMSTicket.seatsAvailable, + EMSTicket.startDate as ticketStart, + EMSTicket.duration as ticketDuration, + EMSTicket.eventNumber as ticketEventNumber, + EMSTicket.location as ticketLocation, + EMSTicket.relatedBadgeGroups, + EMSTicket.relatedRibbons, + EMSTicket.eventMetaData, + (seatsAvailable - (select count(*) from EMSRegistrantTicket where ticketAssetId = asset.assetId)) as seatsRemaining + FROM + asset + join assetData using (assetId) + left join EMSTicket using (assetId) + WHERE + parentId=? + and className='WebGUI::Asset::Sku::EMSTicket' + and state='published' + and EMSTicket.revisionDate=(select max(revisionDate) from EMSTicket where assetId=asset.assetId) + and (seatsAvailable - (select count(*) from EMSRegistrantTicket where ticketAssetId = asset.assetId)) > 0 + GROUP BY + asset.assetId + ORDER BY + title desc + },[$self->getId]); + + $var->{'tickets_loop'} = []; + while (my $hash = $sth->hashRef) { + my $seatsRemaining = $hash->{seatsRemaining}; + for (my $i = 0; $i < $seatsRemaining; $i++ ) { + push(@{$var->{'tickets_loop'}},$hash); + } + } + + return $self->processTemplate($var,$self->get('printRemainingTicketsTemplateId')); +} + +#------------------------------------------------------------------- + =head2 www_printTicket ( ) Prints a ticket using a template. @@ -2037,7 +2102,7 @@ Toggles the registrant checked in flag. sub www_toggleRegistrantCheckedIn { my $self = shift; - return $self->session->privilege->insfufficient() unless ($self->isRegistrationStaff); + return $self->session->privilege->insufficient() unless ($self->isRegistrationStaff); my $db = $self->session->db; my $badgeId = $self->session->form->param('badgeId'); my $flag = $db->quickScalar("select hasCheckedIn from EMSRegistrant where badgeId=?",[$badgeId]); @@ -2046,7 +2111,6 @@ sub www_toggleRegistrantCheckedIn { return $self->www_manageRegistrant; } - #------------------------------------------------------------------- =head2 www_viewSchedule () diff --git a/lib/WebGUI/Help/Asset_EventManagementSystem.pm b/lib/WebGUI/Help/Asset_EventManagementSystem.pm index eacf27f93..3cbc8891b 100644 --- a/lib/WebGUI/Help/Asset_EventManagementSystem.pm +++ b/lib/WebGUI/Help/Asset_EventManagementSystem.pm @@ -42,6 +42,7 @@ our $HELP = { { 'name' => 'addTokenUrl'}, { 'name' => 'importTicketsUrl'}, { 'name' => 'exportTicketsUrl'}, + { 'name' => 'printRemainingTicketsUrl'}, { 'name' => 'canEdit'}, { 'name' => 'hasBadge'}, { 'name' => 'badgeId'}, @@ -226,6 +227,67 @@ our $HELP = { related => [], }, + 'ems print remaining ticket template' => { + source => 'sub www_printRemainingTickets', + title => 'print remaining ticket template help', + body => '', + variables => [ + { 'name' => 'tickets_loop', + 'variables' => [ + { 'name' => 'ticketTitle'}, + { 'name' => 'ticketStart'}, + { 'name' => 'ticketDuration'}, + { 'name' => 'ticketLocation'}, + { 'name' => 'ticketEventNumber'}, + { 'name' => 'seatsRemaining'}, + { 'name' => 'seatsAvailable'}, + { 'name' => 'price'}, + { 'name' => 'relatedRibbons'}, + { 'name' => 'relatedBadgeGroups'}, + { 'name' => 'eventMetaData'}, + { 'name' => 'title'}, + { 'name' => 'menuTitle'}, + { 'name' => 'url'}, + { 'name' => 'synopsis'}, + { 'name' => 'assetId'}, + { 'name' => 'assetSize'}, + { 'name' => 'creationDate'}, + { 'name' => 'encryptPage'}, + { 'name' => 'extraHeadTags'}, + { 'name' => 'extraHeadTagsPacked'}, + { 'name' => 'groupIdEdit'}, + { 'name' => 'groupIdView'}, + { 'name' => 'inheritUrlFromParent'}, + { 'name' => 'isExportable'}, + { 'name' => 'isHidden'}, + { 'name' => 'isPrototype'}, + { 'name' => 'isPackage'}, + { 'name' => 'lastModified'}, + { 'name' => 'newWindow'}, + { 'name' => 'ownerUserId'}, + { 'name' => 'revisedBy'}, + { 'name' => 'revisionDate'}, + { 'name' => 'skipNotification'}, + { 'name' => 'tagId'}, + { 'name' => 'usePackedHeadTags'}, + ], + }, + ], + isa => [ + { namespace => "Asset_EventManagementSystem", + tag => "ems asset template variables" + }, + { namespace => "Asset_Template", + tag => "template variables" + }, + { namespace => "Asset_Wobject", + tag => "wobject template variables" + }, + ], + fields => [], + related => [], + }, + 'ems asset template variables' => { source => 'sub definition', title => 'ems asset template variables', diff --git a/lib/WebGUI/i18n/English/Asset_EventManagementSystem.pm b/lib/WebGUI/i18n/English/Asset_EventManagementSystem.pm index c8145bf3a..2327fb730 100644 --- a/lib/WebGUI/i18n/English/Asset_EventManagementSystem.pm +++ b/lib/WebGUI/i18n/English/Asset_EventManagementSystem.pm @@ -560,6 +560,25 @@ our $I18N = { context => q|help for a property label|, }, + + 'print remaining ticket template' => { + message => q|Print Remaining Tickets Template|, + lastUpdated => 0, + context => q|a property label|, + }, + + 'print remaining ticket template help' => { + message => q|Which template would you like to use for printing remaining tickets?|, + lastUpdated => 0, + context => q|help for a property label|, + }, + + 'print remaining tickets' => { + message => q|Print Remaining Tickets|, + lastUpdated => 0, + context => q|a link label on the builder page|, + }, + 'badge builder template' => { message => q|Badge Builder Template|, lastUpdated => 0, @@ -1878,6 +1897,195 @@ normal templates.|, context => q|help text for the columns per page field|, }, + + 'print remaining ticket template help' => { + message => q|EMS Print Remaining Ticket Template|, + lastUpdated => 1147050475, + context => q|help text label|, + }, + + 'tickets_loop' => { + message => q|A loop containing all of the remaining tickets and their associated data|, + lastUpdated => 1147050475, + context => q|help text label|, + }, + + 'seatsRemaining' => { + message => q|Total number of seats remaining for the ticket|, + lastUpdated => 1147050475, + context => q|help text label|, + }, + + 'seatsAvailable' => { + message => q|Total number of seats available for the ticket|, + lastUpdated => 1147050475, + context => q|help text label|, + }, + + 'relatedRibbons' => { + message => q|Ribbons related to the ticket|, + lastUpdated => 1147050475, + context => q|help text label|, + }, + + 'relatedBadgeGroups' => { + message => q|Badge groups related to the ticket|, + lastUpdated => 1147050475, + context => q|help text label|, + }, + + 'title' => { + message => q|The title of the ticket to be printed.|, + lastUpdated => 1147050475, + context => q|help text label|, + }, + + 'menuTitle' => { + message => q|The title of the ticket to be displayed in the menu.|, + lastUpdated => 1147050475, + context => q|help text label|, + }, + + 'synopsis' => { + message => q|Synopsis of the description for the ticket.|, + lastUpdated => 1147050475, + context => q|help text label|, + }, + + 'assetId' => { + message => q|Asset Id of the ticket.|, + lastUpdated => 1147050475, + context => q|help text label|, + }, + + 'assetSize' => { + message => q|Size of this ticket asset|, + lastUpdated => 1147050475, + context => q|help text label|, + }, + + 'creationDate' => { + message => q|Epoch value date for when the asset was created|, + lastUpdated => 1147050475, + context => q|help text label|, + }, + + 'encryptPage' => { + message => q|Whether or not to encrypt the page that the ticket is dipslayed on|, + lastUpdated => 1147050475, + context => q|help text label|, + }, + + 'extraHeadTags' => { + message => q|Extra tags that should be displayed in the header that this ticket is displayed on|, + lastUpdated => 1147050475, + context => q|help text label|, + }, + + 'extraHeadTagsPacked' => { + message => q|Extra tags that should be displayed in the header that this tikcet is displayed on minimized so no whitespace exists|, + lastUpdated => 1147050475, + context => q|help text label|, + }, + + 'groupIdEdit' => { + message => q|The id of the group that can edit this ticket.|, + lastUpdated => 1147050475, + context => q|help text label|, + }, + + 'groupIdView' => { + message => q|The id of the group that can view this ticket.|, + lastUpdated => 1147050475, + context => q|help text label|, + }, + + 'inheritUrlFromParent' => { + message => q|Whether or not to inherit the url from the parent|, + lastUpdated => 1147050475, + context => q|help text label|, + }, + + 'isExportable' => { + message => q|Whether or not this ticket is exportable|, + lastUpdated => 1147050475, + context => q|help text label|, + }, + + 'isHidden' => { + message => q|Whether or not this ticket should be hidden from the menu.|, + lastUpdated => 1147050475, + context => q|help text label|, + }, + + 'isPrototype' => { + message => q|Whether or not this ticket asset is a prototype|, + lastUpdated => 1147050475, + context => q|help text label|, + }, + + 'isPackage' => { + message => q|Whether or not this ticket asset is a package|, + lastUpdated => 1147050475, + context => q|help text label|, + }, + + 'lastModified' => { + message => q|Epoch date for when this ticket was last modified|, + lastUpdated => 1147050475, + context => q|help text label|, + }, + + 'newWindow' => { + message => q|Whether this ticket should be displayed in a new window|, + lastUpdated => 1147050475, + context => q|help text label|, + }, + + 'ownerUserId' => { + message => q|User Id of the owner of this ticket|, + lastUpdated => 1147050475, + context => q|help text label|, + }, + + 'revisedBy' => { + message => q|Id of the user who last modified this ticket|, + lastUpdated => 1147050475, + context => q|help text label|, + }, + + 'revisionDate' => { + message => q|Epoch date for when this ticket was last revised|, + lastUpdated => 1147050475, + context => q|help text label|, + }, + + 'skipNotification' => { + message => q|Whether or not notifications for this ticket should be skipped.|, + lastUpdated => 1147050475, + context => q|help text label|, + }, + + 'tagId' => { + message => q|Tag Id for this asset|, + lastUpdated => 1147050475, + context => q|help text label|, + }, + + 'usePackedHeadTags' => { + message => q|Whether or not packed head tags should be used for this ticket|, + lastUpdated => 1147050475, + context => q|help text label|, + }, + + 'printRemainingTicketsUrl' => { + message => q|URL to the print remaining tickets page|, + lastUpdated => 1147050475, + context => q|Field Label|, + }, + + + }; 1; diff --git a/t/Asset/Wobject/EventManagementSystem.t b/t/Asset/Wobject/EventManagementSystem.t index 9796a6d91..f52a620bc 100644 --- a/t/Asset/Wobject/EventManagementSystem.t +++ b/t/Asset/Wobject/EventManagementSystem.t @@ -49,7 +49,7 @@ $versionTag->set({name=>"EventManagementSystem Test"}); #---------------------------------------------------------------------------- # Tests -plan tests => 35 ; # Increment this number for each test you create +plan tests => 41; # Increment this number for each test you create #---------------------------------------------------------------------------- @@ -128,16 +128,26 @@ ok(scalar(@$badges) == 2, 'Two Badges exist'); # Add tickets my @tickets; push(@tickets, $ems->addChild({ - className => 'WebGUI::Asset::Sku::EMSTicket', - startDate => '2009-01-01 14:00:00', - eventNumber => 1, - location => 'qq', + className => 'WebGUI::Asset::Sku::EMSTicket', + title => 'Test Ticket 1', + url => 'test-ems/ticket-1', + startDate => '2009-01-01 14:00:00', + eventNumber => 1, + location => 'qq', + seatsAvailable => 5, + price => 5, + duration => 1, })); push(@tickets, $ems->addChild({ - className => 'WebGUI::Asset::Sku::EMSTicket', - startDate => '2009-01-01 14:00:00', - eventNumber => 2, - location => 'qq', + className => 'WebGUI::Asset::Sku::EMSTicket', + title => 'Test Ticket 2', + url => 'test-ems/ticket-2', + startDate => '2009-01-01 14:00:00', + eventNumber => 2, + location => 'qq', + seatsAvailable => 3, + price => 10, + duration => 2, })); foreach my $ticket(@tickets) { @@ -163,17 +173,200 @@ ok(scalar(@$ribbons) == 2, 'Two ribbons exist'); ok( $ems->can('www_getScheduleDataJSON'), 'Can call get Schedule data' ); ok( $ems->can('www_viewSchedule'), 'Can call view Schedule' ); +ok( $ems->can('www_printRemainingTickets'), 'Can call print remaining tickets' ); + +#Test that the default template is correct +my $printRemainingTicketsTemplateId = $ems->get('printRemainingTicketsTemplateId'); +ok($printRemainingTicketsTemplateId eq "hreA_bgxiTX-EzWCSZCZJw", 'Default print remaining tickets template id ok'); + +#Make sure printRemainingTickets template returns the right data +my $templateMock = Test::MockObject->new({}); +$templateMock->set_isa('WebGUI::Asset::Template'); +$templateMock->set_always('getId', $printRemainingTicketsTemplateId); +my $templateVars; +$templateMock->mock('process', sub { $templateVars = $_[1]; } ); + +{ + WebGUI::Test->mockAssetId($printRemainingTicketsTemplateId, $templateMock); + $ems->www_printRemainingTickets(); + + my $ticket1 = { + 'seatsRemaining' => '5', + 'ticketTitle' => 'Test Ticket 1', + 'newWindow' => ignore(), + 'extraHeadTagsPacked' => ignore(), + 'synopsis' => ignore(), + 'extraHeadTags' => ignore(), + 'ownerUserId' => ignore(), + 'url' => 'test-ems/ticket-1', + 'assetId' => ignore(), + 'isPrototype' => ignore(), + 'isHidden' => ignore(), + 'groupIdEdit' => ignore(), + 'inheritUrlFromParent' => ignore(), + 'ticketEventNumber' => '1', + 'lastModified' => ignore(), + 'price' => '5', + 'title' => 'Test Ticket 1', + 'groupIdView' => ignore(), + 'ticketLocation' => 'qq', + 'skipNotification' => ignore(), + 'status' => ignore(), + 'menuTitle' => 'Test Ticket 1', + 'assetSize' => ignore(), + 'ticketDuration' => '1', + 'relatedRibbons' => ignore(), + 'revisionDate' => ignore(), + 'relatedBadgeGroups' => ignore(), + 'isPackage' => ignore(), + 'eventMetaData' => ignore(), + 'usePackedHeadTags' => ignore(), + 'encryptPage' => ignore(), + 'tagId' => ignore(), + 'seatsAvailable' => '5', + 'revisedBy' => ignore(), + 'isExportable' => ignore(), + 'creationDate' => ignore(), + 'ticketStart' => '2009-01-01 14:00:00' + }; + + my $ticket2 = { + 'seatsRemaining' => '3', + 'ticketTitle' => 'Test Ticket 2', + 'newWindow' => ignore(), + 'extraHeadTagsPacked' => ignore(), + 'synopsis' => ignore(), + 'extraHeadTags' => ignore(), + 'ownerUserId' => ignore(), + 'url' => 'test-ems/ticket-2', + 'assetId' => ignore(), + 'isPrototype' => ignore(), + 'isHidden' => ignore(), + 'groupIdEdit' => ignore(), + 'inheritUrlFromParent' => ignore(), + 'ticketEventNumber' => '2', + 'lastModified' => ignore(), + 'price' => '10', + 'title' => 'Test Ticket 2', + 'groupIdView' => ignore(), + 'ticketLocation' => 'qq', + 'skipNotification' => ignore(), + 'status' => ignore(), + 'menuTitle' => 'Test Ticket 2', + 'assetSize' => ignore(), + 'ticketDuration' => '2', + 'relatedRibbons' => ignore(), + 'revisionDate' => ignore(), + 'relatedBadgeGroups' => ignore(), + 'isPackage' => ignore(), + 'eventMetaData' => ignore(), + 'usePackedHeadTags' => ignore(), + 'encryptPage' => ignore(), + 'tagId' => ignore(), + 'seatsAvailable' => '3', + 'revisedBy' => ignore(), + 'isExportable' => ignore(), + 'creationDate' => ignore(), + 'ticketStart' => '2009-01-01 14:00:00' + }; + + my @ticketArray = (); + for(1..3) { + push(@ticketArray,$ticket2); + } + for(1..5) { + push(@ticketArray,$ticket1); + } + + cmp_deeply( + $templateVars, + { + 'badgeInstructions' => ignore(), + 'displayTitle' => ignore(), + 'createdBy' => ignore(), + 'lastExportedAs' => ignore(), + 'printRemainingTicketsTemplateId' => ignore(), + 'state' => ignore(), + 'printTicketTemplateId' => ignore(), + 'newWindow' => ignore(), + 'scheduleColumnsPerPage' => ignore(), + 'synopsis' => ignore(), + 'extraHeadTagsPacked' => ignore(), + 'ownerUserId' => ignore(), + 'extraHeadTags' => ignore(), + 'assetId' => ignore(), + 'url' => 'test-ems', + 'isHidden' => ignore(), + 'isPrototype' => ignore(), + 'groupIdEdit' => ignore(), + 'timezone' => ignore(), + 'styleTemplateId' => ignore(), + 'inheritUrlFromParent' => ignore(), + 'description' => 'This is a test ems', + 'stateChangedBy' => ignore(), + 'lineage' => ignore(), + 'className' => 'WebGUI::Asset::Wobject::EventManagementSystem', + 'groupToApproveEvents' => ignore(), + 'lastModified' => ignore(), + 'title' => 'Test EMS', + 'groupIdView' => ignore(), + 'mobileStyleTemplateId' => ignore(), + 'skipNotification' => ignore(), + 'scheduleTemplateId' => ignore(), + 'status' => ignore(), + 'menuTitle' => 'Test EMS', + 'assetSize' => ignore(), + 'lookupRegistrantTemplateId' => ignore(), + 'isLockedBy' => ignore(), + 'stateChanged' => ignore(), + 'revisionDate' => ignore(), + 'ribbonInstructions' => ignore(), + 'isPackage' => ignore(), + 'usePackedHeadTags' => ignore(), + 'templateId' => ignore(), + 'badgeBuilderTemplateId' => ignore(), + 'printBadgeTemplateId' => ignore(), + 'encryptPage' => ignore(), + 'tagId' => ignore(), + 'isSystem' => ignore(), + 'revisedBy' => ignore(), + 'isExportable' => ignore(), + 'creationDate' => ignore(), + 'registrationStaffGroupId' => ignore(), + 'parentId' => ignore(), + 'tokenInstructions' => ignore(), + 'printableStyleTemplateId' => ignore(), + 'ticketInstructions' => ignore(), + 'tickets_loop' => \@ticketArray, + }, + "www_printRemainingTickets: template variables valid" + ); + + WebGUI::Test->unmockAssetId($printRemainingTicketsTemplateId); +} + +#Make sure permissions work on pages my $data; $session->user({userId => $crasher->getId}); $session->http->setStatus(201); $data = $ems->www_viewSchedule(); is($session->http->getStatus, 401, 'www_viewSchedule: visitor may not see the schedule'); +$data = $ems->www_printRemainingTickets(); +is($session->http->getStatus, 401, 'www_printRemainingTickets: visitor may not print the remaining tickets'); $session->http->setStatus(201); $session->user({userId => $attender->getId}); $data = $ems->www_viewSchedule(); is($session->http->getStatus, 201, '... attender user can see the schedule'); +$data = $ems->www_printRemainingTickets(); +is($session->http->getStatus, 401, 'www_printRemainingTickets: attender may not print the remaining tickets'); + +$session->http->setStatus(201); +$session->user({userId => $registrar->getId}); +$data = $ems->www_printRemainingTickets(); +is($session->http->getStatus, 201, 'www_printRemainingTickets: registration staff may print the remaining tickets'); + $session->http->setStatus(201); $session->user({userId => $crasher->getId});