public function validate()
 {
     $result = parent::validate();
     $promocode_repository = new SapphireSummitRegistrationPromoCodeRepository();
     if ($this->SpeakerID) {
         $has_code_assigned = $promocode_repository->getBySpeaker($this->Summit()->getIdentifier(), $this->Speaker()->getIdentifier());
         foreach ($has_code_assigned as $code_taken) {
             if ($code_taken->ID != $this->ID) {
                 $result->error(sprintf('Speaker already assigned to another promo code: %s', $code_taken->Code));
             }
         }
     }
     return $result;
 }
 public function promocodes_bulk(SS_HTTPRequest $request)
 {
     $summit_id = intval($request->param('SummitID'));
     $summit = Summit::get()->byID($summit_id);
     $promocode_types = SummitRegistrationPromoCode::getTypes();
     Requirements::css('summit/css/simple-sidebar.css');
     Requirements::css('summit/css/summit-admin-promocodes-bulk.css');
     Requirements::css('themes/openstack/bower_assets/chosen/chosen.min.css');
     Requirements::css('themes/openstack/bower_assets/sweetalert/dist/sweetalert.css');
     Requirements::css('themes/openstack/bower_assets/awesome-bootstrap-checkbox/awesome-bootstrap-checkbox.css');
     // tag input
     Requirements::css('themes/openstack/bower_assets/bootstrap-tagsinput/dist/bootstrap-tagsinput.css');
     Requirements::css('themes/openstack/bower_assets/bootstrap-tagsinput/dist/bootstrap-tagsinput-typeahead.css');
     Requirements::javascript('themes/openstack/bower_assets/sweetalert/dist/sweetalert.min.js');
     Requirements::javascript('themes/openstack/bower_assets/jquery-validate/dist/jquery.validate.min.js');
     Requirements::javascript('themes/openstack/bower_assets/jquery-validate/dist/additional-methods.min.js');
     Requirements::javascript('themes/openstack/bower_assets/chosen/chosen.jquery.min.js');
     Requirements::javascript('summit/javascript/simple-sidebar.js');
     Requirements::javascript('//tinymce.cachefly.net/4.3/tinymce.min.js');
     Requirements::javascript('themes/openstack/bower_assets/typeahead.js/dist/typeahead.bundle.min.js');
     Requirements::javascript('themes/openstack/bower_assets/bootstrap-tagsinput/dist/bootstrap-tagsinput.min.js');
     Requirements::javascript('summit/javascript/summitapp-promocodes-bulk.js');
     return $this->getViewer('promocodes_bulk')->process($this->customise(array('Summit' => $summit, 'CodeTypes' => $promocode_types)));
 }