Skip to content

Commit

Permalink
Enforce a strict limit on the number of tickets available to a confer…
Browse files Browse the repository at this point in the history
…ence
  • Loading branch information
andrewcurioso committed Jun 13, 2012
1 parent 2e7977d commit f9712c5
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 22 deletions.
6 changes: 4 additions & 2 deletions Config/Schema/schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@ public function after($event = array()) {
'modified' => array('type' => 'datetime', 'null' => true, 'default' => NULL),
'venue_id' => array('type' => 'integer', 'null' => true, 'default' => NULL, 'length' => 10),
'start_date' => array('type' => 'date', 'null' => true, 'default' => NULL),
'available_tickets' => array('type' => 'integer', 'null' => true, 'default' => NULL, 'length' => 10),
'ticket_count' => array('type' => 'integer', 'null' => true, 'default' => '0', 'length' => 10),
'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)),
'tableParameters' => array('charset' => 'latin1', 'collate' => 'latin1_swedish_ci', 'engine' => 'InnoDB')
);
public $hotels = array(
'id' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'length' => 10, 'key' => 'primary'),
'name' => array('type' => 'string', 'null' => true, 'default' => NULL, 'length' => 64, 'collate' => 'latin1_swedish_ci', 'charset' => 'latin1'),
'website' => array('type' => 'string', 'null' => false, 'length' => 128, 'collate' => 'latin1_swedish_ci', 'charset' => 'latin1'),
'website' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 128, 'collate' => 'latin1_swedish_ci', 'charset' => 'latin1'),
'address' => array('type' => 'text', 'null' => false, 'default' => NULL, 'collate' => 'latin1_swedish_ci', 'charset' => 'latin1'),
'created' => array('type' => 'datetime', 'null' => true, 'default' => NULL),
'modified' => array('type' => 'datetime', 'null' => true, 'default' => NULL),
Expand Down Expand Up @@ -147,7 +149,7 @@ public function after($event = array()) {
public $venues = array(
'id' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'length' => 10, 'key' => 'primary'),
'name' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 128, 'collate' => 'latin1_swedish_ci', 'charset' => 'latin1'),
'website' => array('type' => 'string', 'null' => false, 'length' => 128, 'collate' => 'latin1_swedish_ci', 'charset' => 'latin1'),
'website' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 128, 'collate' => 'latin1_swedish_ci', 'charset' => 'latin1'),
'address' => array('type' => 'text', 'null' => false, 'default' => NULL, 'collate' => 'latin1_swedish_ci', 'charset' => 'latin1'),
'transportation_instructions' => array('type' => 'text', 'null' => false, 'default' => NULL, 'collate' => 'latin1_swedish_ci', 'charset' => 'latin1'),
'created' => array('type' => 'datetime', 'null' => true, 'default' => NULL),
Expand Down
32 changes: 16 additions & 16 deletions Controller/TicketsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,24 +51,24 @@ public function index() {
// Conditions to return TicketOptions that are within the specified start & end dates,
// or that have no start date, or no end date
$conditions = array(
array( 'OR' =>
array(
'TicketOption.sale_start < NOW()',
'TicketOption.sale_start IS NULL',
)
),
array( 'OR' =>
array(
'TicketOption.sale_end > NOW()',
'TicketOption.sale_end IS NULL'
)
)
);
array( 'OR' =>
array(
'TicketOption.sale_start < NOW()',
'TicketOption.sale_start IS NULL',
)
),
array( 'OR' =>
array(
'TicketOption.sale_end > NOW()',
'TicketOption.sale_end IS NULL'
)
)
);

$this->set('ticketOptions', $this->Ticket->TicketOption->find('all',
array('order'=>array('label'),
'conditions' => $conditions
)));
array('order'=>array('label'),
'conditions' => $conditions
)));


$this->set('tickets', $this->Ticket->find('all',array(
Expand Down
14 changes: 14 additions & 0 deletions Model/Event.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,20 @@ class Event extends BostonConferenceAppModel {
'allowEmpty' => false,
'required' => true
),
),
'available_tickets' => array(
'numeric' => array(
'rule' => array('numeric'),
'message' => 'Available tickets must be a number',
'allowEmpty' => true,
'required' => false
),
'comparison' => array(
'rule' => array('comparison','>',-1),
'message' => 'Available tickets must be a positive integer',
'allowEmpty' => true,
'required' => false
),
)
);
/**
Expand Down
33 changes: 30 additions & 3 deletions Model/Ticket.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class Ticket extends BostonConferenceAppModel {
'foreignKey' => 'user_id',
),
'TicketOption' => array(
'className' => 'TicketOption',
'className' => 'BostonConference.TicketOption',
'foreignKey' => 'ticket_option_id',
'counterCache' => true,
)
Expand Down Expand Up @@ -109,20 +109,23 @@ public function completeRegistration( $userId, $data, $callback = null ) {
return false;
}

$this->query('LOCK TABLES ticket_options as TicketOption WRITE, tickets as Ticket WRITE');
$this->query('LOCK TABLES events as Event WRITE, ticket_options as TicketOption WRITE, tickets as Ticket WRITE');

$this->TicketOption->recursive = -1;
$options = $this->TicketOption->find(
'all',
array(
'order'=>array('label'),
'conditions' => array( 'id' => array_keys($data['quantity']) )
'conditions' => array( 'TicketOption.id' => array_keys($data['quantity']) )
)
);

if ( count($options) != count($data['quantity']) ) {
return false;
}

$eventQuantities = array();

foreach( $options as $ticketOption ) {
$id = $ticketOption['TicketOption']['id'];

Expand All @@ -135,6 +138,13 @@ public function completeRegistration( $userId, $data, $callback = null ) {
$this->query('UNLOCK TABLES');
return false;
}

$eventId = $ticketOption['TicketOption']['event_id'];

if ( !array_key_exists($eventId,$eventQuantities) )
$eventQuantities[$eventId] = $data['quantity'][$id];
else
$eventQuantities[$eventId] += $data['quantity'][$id];
}

$organization = $data['organization'];
Expand All @@ -161,6 +171,23 @@ public function completeRegistration( $userId, $data, $callback = null ) {
}
}

$events = $this->TicketOption->Event->find('all',array('conditions'=>array('Event.id' => array_keys($eventQuantities))));

foreach( $events as $event ) {
$newTotal = $event['Event']['ticket_count'] + $eventQuantities[$event['Event']['id']];

if ( $event['Event']['available_tickets'] !== null ) {
if ( $event['Event']['available_tickets'] < $newTotal ) {
$this->rollback();
$this->query('UNLOCK TABLES');
return false;
}
}

$this->TicketOption->Event->id = $event['Event']['id'];
$this->TicketOption->Event->saveField('ticket_count',$newTotal);
}

if ( $callback && !call_user_func($callback) ) {
$this->rollback();
$this->query('UNLOCK TABLES');
Expand Down
2 changes: 1 addition & 1 deletion Model/TicketOption.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class TicketOption extends BostonConferenceAppModel {
*/
public $belongsTo = array(
'Event' => array(
'className' => 'Event',
'className' => 'BostonConference.Event',
'foreignKey' => 'event_id',
)
);
Expand Down
1 change: 1 addition & 0 deletions View/Events/admin_add.ctp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<?php
echo $this->Form->input('name');
echo $this->Form->input('description');
echo $this->Form->input('available_tickets');
echo $this->Form->input('venue_id',array('empty' => true));
?>
</fieldset>
Expand Down
1 change: 1 addition & 0 deletions View/Events/admin_edit.ctp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
echo $this->Form->input('id');
echo $this->Form->input('name');
echo $this->Form->input('description');
echo $this->Form->input('available_tickets');
echo $this->Form->input('venue_id',array('empty' => true));
?>
</fieldset>
Expand Down
3 changes: 3 additions & 0 deletions View/Tickets/index.ctp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ if ( count( $ticketOptions ) > 0 )
else
$canBuy = 999;

if ( $ticketOption['Event']['available_tickets'] !== null )
$canBuy = min($ticketOption['Event']['available_tickets']-$ticketOption['Event']['ticket_count'],$canBuy);

if ( $canBuy <= 0 )
echo __('Sold Out');
else {
Expand Down

0 comments on commit f9712c5

Please sign in to comment.