<?php

class PlateAuthorizationController extends Controller
{

  public function filters()
  {
    return array (
        // 'postOnly + update',
        array (
            'application.filters.SyslogFilter' 
        ) 
    );
  }

  public static function getGateObjects()
  {
    $objs = array ();
    
    foreach ( Gate::getAllGates () as $g )
      $objs [PlateAuthorization::GATEID_TYPE_GATE . "_" . $g->ID] = "[" . t ( 'Gate' ) . "] " . $g->Descrizione;
    foreach ( GateGroup::getGateGroupList () as $grid => $grdescr )
      $objs [PlateAuthorization::GATEID_TYPE_GROUP . "_" . $grid] = "[" . t ( 'Group' ) . "] " . $grdescr;
    foreach ( GateSet::model ()->findAll () as $s )
      $objs [PlateAuthorization::GATEID_TYPE_SET . "_" . $s->id] = "[" . t ( 'Set' ) . "] " . $s->name;
    
    return $objs;
  }

  /**
   *
   * @param PlateAuthorization|SmartPlateAuth $permit          
   * @param
   *          boolean fullButton (default false)
   * @return boolean
   */
  protected function printPrintBtn($permit, $fullButton = false)
  {
    $selectedLayout = paramdeep ( 'plateAuthorizations', 'printLayout' );
    if (empty ( $selectedLayout ))
      return;
    
    if ($permit !== null)
    {
      $toBeConf = true;
      $url = null;
      
      if ($permit instanceof SmartPlateAuth)
      {
        $toBeConf = $permit->ToBeConfirmed;
        $url = $permit->url_print;
      }
      
      if ($permit instanceof PlateAuthorization)
      {
        $toBeConf = $permit->to_be_confirmed;
        $url = Yii::app ()->createUrl ( 'plateAuthorization/print', array (
            'id' => $permit->ID 
        ) );
      }
      
      if (! empty ( $url ) && ! $toBeConf && user ()->checkAccess ( 'plate_auth_print' ))
      {
        $buttonHtml = $fullButton ? '<div class="btn btn-small"><div class="icon-print">' . t ( 'Print' ) . '</div></div>' : '<div class="icon-print"></div>';
        $this->renderPartial ( '_printButton', array (
            'url' => $url,
            'buttonHtml' => $buttonHtml 
        ) );
        return true;
      }
    }
    return false;
  }

  /**
   *
   * @param int $id          
   * @param
   *          boolean fullButton (default false)
   * @return boolean
   */
  protected function printPrintBtnById($id, $fullButton = false)
  {
    $permit = $this->loadModel ( $permitId );
    return $this->printPrintBtn ( $permit, $fullButton );
  }

  /**
   *
   * @param int $id          
   * @param string $type
   *          of type PlateAuthInfoImportExportType
   * @throws CHttpException
   * @return PlateAuthInfoImportExportData
   */
  public static function export($id, $type)
  {
    $data = new PlateAuthInfoImportExportData ();
    switch ($type)
    {
      case PlateAuthInfoImportExportType::PLATE_AUTHORIZATION :
        
        $obj = PlateAuthorization::model ()->findByPk ( $id );
        
        if (! $data->add ( $obj ))
          throw new CHttpException ( 404, "PlateAuthorization not found" );
        if (! $data->add ( $obj->plate_list ))
          throw new CHttpException ( 404, "PlateList not found" );
        if (! $data->add ( $obj->vehicle ))
          throw new CHttpException ( 404, "Vehicle not found" );
        if (! $data->add ( $obj->user ))
          throw new CHttpException ( 404, "VehicleOwner not found" );
        if (! $data->add ( $obj->validityPeriod ))
          throw new CHttpException ( 404, "ValidityPeriod not found" );
        
        break;
      /*
       * case PlateAuthInfoImportExportType::VALIDITY_PERIOD:
       *
       * $obj = ValidityPeriod::model()->findByPk($id);
       *
       * if(!$data->add($obj))
       * throw new CHttpException(404,"PlateAuthorization not found");
       * if(!$data->add($obj->plate_list))
       * throw new CHttpException(404,"PlateList not found");
       * if(!$data->add($plateAuth->vehicle))
       * throw new CHttpException(404,"Vehicle not found");
       * if(!$data->add($plateAuth->user))
       * throw new CHttpException(404,"VehicleOwner not found");
       * if(!$data->add($plateAuth->validityPeriod))
       * throw new CHttpException(404,"ValidityPeriod not found");
       *
       * break;
       */
      default :
        throw new CHttpException ( 404, "PlateAuthInfoImportExportType not found" );
    }
    
    return $data;
  }

  public function actionScheduler()
  {
    access_denied_check ( 'plate_auth_scheduler' );
    
    if (array_get ( $_REQUEST, 'action', 'dontdoit' ) == 'doit')
    {
      $plateListId = array_get ( $_REQUEST, 'plateListId' );
      $plate = strtoupper ( array_get ( $_REQUEST, 'plate' ) );
      $nationality = strtoupper ( array_get ( $_REQUEST, 'nationality' ) );
      $name_surname = strtoupper ( array_get ( $_REQUEST, 'name_surname' ) );
      $start_date = array_get ( $_REQUEST, 'start_date' );
      $end_date = array_get ( $_REQUEST, 'end_date' );
      
      $plateList = PlateList::load ( $plateListId, false );
      
      $name_surname_chunks = explode ( ' ', $name_surname );
      $name_surname_chunks = array_trim_and_nonEmptyEntries ( $name_surname_chunks );
      
      $name = "";
      $surname = "";
      if (count ( $name_surname_chunks ) > 0)
      {
        if (count ( $name_surname_chunks ) == 1)
          $name = array_first ( $name_surname_chunks );
        else
        {
          $surname = array_last ( $name_surname_chunks );
          $name_surname_chunks = array_remove_values ( $name_surname_chunks, $surname );
          $name = implode ( ' ', $name_surname_chunks );
        }
      }
      
      $vehicleOwner = VehicleOwner::getOrCreate ( $name, $surname, $plateList->code );
      $vehicle = Vehicle::getOrCreate ( $plate, $nationality, $vehicleOwner->ID, $plateList->code );
      $validityPeriod = ValidityPeriod::getOrCreate ( DateTimeEx::parseDate ( $start_date ), DateTimeEx::parseDate ( $end_date, "23:59:59" ), $vehicleOwner->ID, $plateList->code );
      $validityPeriod->Abilitato = $plateList->isBlacklist () ? 0 : ($plateList->isWhitelist () ? 1 : - 1);
      $validityPeriod->update();
      
      $plateAuth = new PlateAuthorization ();
      $plateAuth->UserID = $vehicleOwner->ID;
      $plateAuth->VehicleID = $vehicle->ID;
      $plateAuth->AbbonamentoID = $validityPeriod->ID;
      $plateAuth->list_code = $plateList->code;
      $plateAuth->epoch = DateTimeEx::now ();
      $plateAuth->insertid = user ()->id;
      $plateAuth->Note = "";
      $plateAuth->action = "";
      $plateAuth->type = "";
      $plateAuth->GateID = - 1;
      $plateAuth->GateID_type = PlateAuthorization::GATEID_TYPE_GATE;
      $plateAuth->TimeID = - 1;
      if (user ()->checkAccess ( 'plate_auth_confirmed' ))
        $plateAuth->to_be_confirmed = 0;
      else
        $plateAuth->to_be_confirmed = 1;
      if (user ()->checkAccess ( 'plate_auth_enable' ))
        $plateAuth->enabled = 1;
      else
        $plateAuth->enabled = 0;
      $plateAuth->insert ();
      
      $this->redirectTo ( 'plateAuthorization/view', array (
          'id' => $plateAuth->ID 
      ) );
    }
    else
    {
      $this->render ( 'scheduler/calendar' );
    }
  }

  public function actionTransitSimulation()
  {
    access_denied_check ( 'plate_simulate_transit' );
    $gates = gate::getGateList ();
    $this->render ( 'transitSimulation', get_defined_vars () );
  }

  public function actionCheckWhitelistPlate($plate, $time, $nationality, $gate)
  {
    $plateAuths = PlateAuthorization::findSmartByPlate ( $plate, $nationality, PlateAuthorization::FIND_SMART_BY_PLATE_FILTERUSERLIST_WHITELIST );
    $plateAuths = array_sort ( $plateAuths, '$x->IDPermesso > $y->IDPermesso' );
    $this->render ( 'CheckWhitelistPlate', get_defined_vars () );
  }

  public function actionPlateAuthInfoExportAll()
  {
    access_denied_check ( 'plate_auth_export_all' );
    
    set_time_limit ( 0 );
    
    $where = array_get ( $_REQUEST, 'where', array () );
    
    $data = new PlateAuthInfoImportExportData ();
    $tablesObjectMapping = array (
        "plate_list" => "plateLists",
        "usertable" => "vehicleOwners",
        "vehicletable" => "vehicles",
        "abbonamentotable" => "validityPeriods",
        "whitelisttable" => "plateAuthorizations" 
    );
    
    foreach ( $tablesObjectMapping as $tableName => $fieldName )
    {
      $whereCode = array_get ( $where, $tableName );
      
      if (! isEmptyOrWhitespace ( $whereCode ))
        $whereCode = " WHERE $whereCode";
      
      $tableRows = query ( "SELECT *,ID as ITEM_PK FROM {$tableName}{$whereCode}", array (), false, false );
      $tableRowsFinal = array ();
      foreach ( $tableRows as $rowIndex => $row )
      {
        $pk = $row ['ITEM_PK'];
        unset ( $row ['ITEM_PK'] );
        $tableRowsFinal [$pk] = $row;
      }
      
      $data->$fieldName = $tableRowsFinal;
    }
    
    $dataString = $data->serialize ();
    prepare_download ( DateTimeEx::now ()->toFilesafeDateTimeString () . "_plate_auths_ALL.kpa", 'text/plain' );
    echo ($dataString);
    exit ();
  }

  public function actionPlateAuthInfoExportList($code)
  {
    access_denied_check ( "plate_auth_export_list_$code" );
    
    set_time_limit ( 0 );
    
    $where = array (
        "plate_list" => "code=$code",
        "usertable" => "list_code=$code",
        "vehicletable" => "list_code=$code",
        "abbonamentotable" => "list_code=$code",
        "whitelisttable" => "list_code=$code" 
    );
    
    $data = new PlateAuthInfoImportExportData ();
    $tablesObjectMapping = array (
        "plate_list" => "plateLists",
        "usertable" => "vehicleOwners",
        "vehicletable" => "vehicles",
        "abbonamentotable" => "validityPeriods",
        "whitelisttable" => "plateAuthorizations" 
    );
    
    foreach ( $tablesObjectMapping as $tableName => $fieldName )
    {
      $whereCode = array_get ( $where, $tableName );
      
      if (! isEmptyOrWhitespace ( $whereCode ))
        $whereCode = " WHERE $whereCode";
      
      $tableRows = query ( "SELECT *,ID as ITEM_PK FROM {$tableName}{$whereCode}", array (), false, false );
      $tableRowsFinal = array ();
      foreach ( $tableRows as $rowIndex => $row )
      {
        $pk = $row ['ITEM_PK'];
        unset ( $row ['ITEM_PK'] );
        $tableRowsFinal [$pk] = $row;
      }
      
      $data->$fieldName = $tableRowsFinal;
    }
    
    $dataString = $data->serialize ();
    prepare_download ( DateTimeEx::now ()->toFilesafeDateTimeString () . "_plate_auths_list_{$code}.kpa", 'text/plain' );
    echo ($dataString);
    exit ();
  }

  public function actionPlateAuthInfoExport($id, $type)
  {
    access_denied_check ( 'plate_auth_export' );
    $data = self::export ( $id, $type );
    $dataString = $data->serialize ();
    prepare_download ( DateTimeEx::now ()->toFilesafeDateTimeString () . "_plate_auth_{$id}.kpa", 'text/plain' );
    echo ($dataString);
    exit ();
  }

  public function actionPlateAuthInfoImport()
  {
    access_denied_check ( 'plate_auth_import' );
    
    $test_passkey = t ( 'IMPORT' );
    
    $test = array_get ( $_REQUEST, 'test' );
    $uploadFile = $this->getUploadedFile ();
    
    if ($uploadFile != null && $this->checkError ( $uploadFile->success, t ( "Upload failed, error {error}", array (
        '{error}' => $uploadFile->errorString 
    ) ) ) && $this->checkError ( $test == $test_passkey, t ( "Validation keyword missed or incorrect" ) ))
    {
      $data = $uploadFile->read ();
      $log = new StringWriter ();
      $info = PlateAuthInfoImportExportData::deserialize ( $data );
      
      foreach ( $info->plateLists as $pk => $objAttributes )
      {
        $obj = new PlateList ();
        foreach ( $objAttributes as $ak => $av )
          $obj->$ak = $av;
        $objExists = count ( PlateList::model ()->findAllByPk ( $pk ) ) > 0;
        $obj->setIsNewRecord ( ! $objExists );
        $saveMethod = $objExists ? "update" : "insert";
        if ($obj->$saveMethod ())
          $log->html_writeline ( "PlateList[$obj->id] {$obj->getListTitle()} ({$obj->code}) saved ($saveMethod)" );
        else
          $log->html_writeline ( "PlateList[$obj->id] {$obj->getListTitle()} ({$obj->code}) NOT saved ($saveMethod), errors: {$obj->getErrorsHtml()}" );
      }
      
      foreach ( $info->vehicleOwners as $pk => $objAttributes )
      {
        $obj = new VehicleOwner ();
        foreach ( $objAttributes as $ak => $av )
          $obj->$ak = $av;
        $objExists = count ( PlateList::model ()->findAllByPk ( $pk ) ) > 0;
        $obj->setIsNewRecord ( ! $objExists );
        $saveMethod = $objExists ? "update" : "insert";
        if ($obj->$saveMethod ())
          $log->html_writeline ( "VehicleOwner[$obj->ID] $obj->Nome $obj->Cognome saved ($saveMethod)" );
        else
          $log->html_writeline ( "VehicleOwner[$obj->ID] $obj->Nome $obj->Cognome NOT saved ($saveMethod), errors: {$obj->getErrorsHtml()}" );
      }
      
      foreach ( $info->vehicles as $pk => $objAttributes )
      {
        $obj = new Vehicle ();
        foreach ( $objAttributes as $ak => $av )
          $obj->$ak = $av;
        $objExists = count ( PlateList::model ()->findAllByPk ( $pk ) ) > 0;
        $obj->setIsNewRecord ( ! $objExists );
        $saveMethod = $objExists ? "update" : "insert";
        if ($obj->$saveMethod ())
          $log->html_writeline ( "Vehicle[$obj->ID] $obj->Targa saved ($saveMethod)" );
        else
          $log->html_writeline ( "Vehicle[$obj->ID] $obj->Targa NOT saved ($saveMethod), errors: {
              $obj->getErrorsHtml()}" );
      }
      
      foreach ( $info->validityPeriods as $pk => $objAttributes )
      {
        $obj = new ValidityPeriod ();
        foreach ( $objAttributes as $ak => $av )
          $obj->$ak = $av;
        $objExists = count ( PlateList::model ()->findAllByPk ( $pk ) ) > 0;
        $obj->setIsNewRecord ( ! $objExists );
        $saveMethod = $objExists ? "update" : "insert";
        if ($obj->$saveMethod ())
          $log->html_writeline ( "ValidityPeriod[$obj->ID] " . DateHelper::ensureObjectEx ( $obj->DataInizio ) . " --- " . DateHelper::ensureObjectEx ( $obj->DataFine ) . " saved ($saveMethod)" );
        else
          $log->html_writeline ( "ValidityPeriod[$obj->ID] " . DateHelper::ensureObjectEx ( $obj->DataInizio ) . " --- " . DateHelper::ensureObjectEx ( $obj->DataFine ) . " NOT saved ($saveMethod), errors: {
              $obj->getErrorsHtml()}" );
      }
      
      foreach ( $info->plateAuthorizations as $pk => $objAttributes )
      {
        $obj = new PlateAuthorization ();
        foreach ( $objAttributes as $ak => $av )
          $obj->$ak = $av;
        $objExists = count ( PlateList::model ()->findAllByPk ( $pk ) ) > 0;
        $obj->setIsNewRecord ( ! $objExists );
        $saveMethod = $objExists ? "update" : "insert";
        if ($obj->$saveMethod ())
          $log->html_writeline ( "PlateAuthorization[$obj->ID] saved ($saveMethod)" );
        else
          $log->html_writeline ( "PlateAuthorization[$obj->ID] NOT saved ($saveMethod), errors: {
              $obj->getErrorsHtml()}" );
      }
      
      $this->renderText ( $log ); // "<pre>"._2str($info)."</pre>");
    }
    else
    {
      $this->renderText ( '
          <form method="POST" enctype="multipart/form-data">
          <input type="hidden" name="MAX_FILE_SIZE" value="1000000000" />
          <input type="file" name="data" accept=".kpa" /><br />
          ' . t ( 'Write "{word}" to confirm', array (
          '{word}' => $test_passkey 
      ) ) . ':
          <input type="text" name="test" /><br />
          <input type="submit" />
          </form>' );
    }
  }

  public function actionTabulaRasa()
  {
    access_denied_check ( 'plate_auth_tabula_rasa' );
    if (! paramdeep ( 'plateAuthorizations', 'tabularasa', 'allowed' ))
      access_denied_check ( null, true, t ( "Operation TABULA RASA is not allowed on this server" ) );
    
    $password = array_get ( $_REQUEST, 'tabularasapassword' );
    if (! isEmpty ( $password ))
    {
      $targets = array_get ( $_REQUEST, 'targets', array () );
      if (kria_password ( $password ) == paramdeep ( 'plateAuthorizations', 'tabularasa', 'password' ))
      {
        if (array_get ( $targets, 'lists', 0 ) == 1)
        {
          PlateList::model ()->deleteAll ();
          user ()->setFlash ( 'warning', t ( 'Plate lists deleted' ) );
        }
        if (array_get ( $targets, 'owners', 0 ) == 1)
        {
          VehicleOwner::model ()->deleteAll ();
          user ()->setFlash ( 'warning', t ( 'Vehcile owners deleted' ) );
        }
        if (array_get ( $targets, 'vehicles', 0 ) == 1)
        {
          Vehicle::model ()->deleteAll ();
          user ()->setFlash ( 'warning', t ( 'Vehicles deleted' ) );
        }
        if (array_get ( $targets, 'periods', 0 ) == 1)
        {
          ValidityPeriod::model ()->deleteAll ();
          user ()->setFlash ( 'warning', t ( 'Validity periods deleted' ) );
        }
        if (array_get ( $targets, 'plateauths', 0 ) == 1)
        {
          PlateAuthorization::model ()->deleteAll ();
          user ()->setFlash ( 'warning', t ( 'Plate authorizations deleted' ) );
        }
        user ()->setFlash ( 'success', t ( 'Done' ) );
        $this->redirectTo ( 'PlateAuthorization' );
      }
      else
      {
        user ()->setFlash ( 'error', t ( 'Wrong password' ) );
      }
    }
    else
    {
      user ()->setFlash ( 'warning', t ( 'Ready' ) );
    }
    
    $this->renderText ( '
        <h1>Tabula Rasa</h1>
        <form method="post">
        <div style="border: 1px solid green; background-color: lightgreen; margin: 10px 10px 10px 10px; padding: 10px 10px 10px 10px;">
        <table>
        <tr><td>' . t ( 'Plate lists' ) . '</td><td><input name="targets[lists]" type="checkbox" value="1" /></td></tr>
        <tr><td>' . t ( 'Vehicles' ) . '</td><td><input name="targets[vehicles]" type="checkbox" value="1" /></td></tr>
        <tr><td>' . t ( 'Vehicle owners' ) . '</td><td><input name="targets[owners]" type="checkbox" value="1" /></td></tr>
        <tr><td>' . t ( 'Validity periods' ) . '</td><td><input name="targets[periods]" type="checkbox" value="1" /></td></tr>
        <tr><td>' . t ( 'Plate authorizations' ) . '</td><td><input name="targets[plateauths]" type="checkbox" value="1" /></td></tr>
        </table>
        </div>
        Password: <input type="password" name="tabularasapassword" /><br />
        <input type="submit" />
        </form>
        ' );
    
    // var_dump_html($_REQUEST);
  }

  public function actionNewPlateAuthProfile($plateListId, $profileId)
  {
    access_denied_check ( 'plate_auth_insert' );
    access_denied_check ( 'plate_auth_insert_profile' );
    access_denied_check ( "plate_auth_insert_profile_{$profileId}" );
    
    $profile = PlateAuthInsertProfile::model ()->findByPk ( $profileId );
    if ($profile === null)
      throw new CHttpException ( 404, t ( 'The requested profile does not exist.' ) );
    $list = PlateList::load ( $plateListId, true );
    $fields = $profile->getNamedField ();
    
    Yii::import ( "bootstrap.widgets.TbActiveForm" );
    $form = new TbActiveForm ();
    
    $model = new NewPlateAuthProfileForm ();
    $model->fields = $fields;
    
    // ho fatto submit?
    if (isset ( $_POST ['NewPlateAuthProfileForm'] ))
    {
      // aggiorno i valori da form
      $fieldsData = $_POST ['NewPlateAuthProfileForm'];
      foreach ( $fieldsData as $key => $value )
        $model->$key = $value;
      
      $model->vehicle_plate = implode ( PHP_EOL, plate_list_normalization ( $model->vehicle_plate ) );
      
      // $model->validate();
      // var_dump_html($fieldsData);
      
      if ($model->validate ())
      {
        // ///////////////
        // !!inserisco!!//
        // ///////////////
        
        $messagesLog = array ();
        
        $epoch = new DateTimeEx ();
        $epochString = "$epoch";
        
        // creo/sovrascrivo utente
        $userOk = false;
        $user = VehicleOwner::model ()->find ( 'list_code=:lst AND Nome=:nm AND Cognome=:srnm', array (
            ':lst' => $list->code,
            ':nm' => $model->owner_name,
            ':srnm' => $model->owner_surname 
        ) );
        if ($user == null || ($user != null && ! $model->owner_overwrite))
        {
          $user = new VehicleOwner ();
          
          $user->Nome = $model->owner_name;
          $user->Cognome = $model->owner_surname;
          
          $user->email = $model->owner_email;
          $user->phone = $model->owner_phone;
          $user->address = $model->owner_address;
          $user->city = $model->owner_city;
          
          $user->list_code = $list->code;
          $user->epoch = $epochString;
          if (! $user->save ())
          {
            $messagesLog [] = t ( 'Unable to save user data.' );
          }
          else
          {
            $userOk = true;
          }
        }
        else
        {
          $changed = false;
          if (! isEmpty ( $model->owner_email ))
          {
            $user->email = $model->owner_email;
            $changed = true;
          }
          if (! isEmpty ( $model->owner_phone ))
          {
            $user->phone = $model->owner_phone;
            $changed = true;
          }
          if (! isEmpty ( $model->owner_address ))
          {
            $user->address = $model->owner_address;
            $changed = true;
          }
          if (! isEmpty ( $model->owner_city ))
          {
            $user->city = $model->owner_city;
            $changed = true;
          }
          if ($changed)
          {
            if (! $user->save ())
            {
              $messagesLog [] = t ( 'Unable to save user data.' );
            }
            else
            {
              $userOk = true;
            }
          }
          else
          {
            $userOk = true;
          }
        }
        // utente salvato con successo
        if ($userOk)
        {
          
          // creo periodo di validità
          $validityPeriod = new ValidityPeriod ();
          $validityPeriod->UserID = $user->ID;
          $validityPeriod->DataInizio = $model->getStartDateTime ()
            ->toDateTime ();
          $validityPeriod->DataFine = $model->getEndDateTime ()
            ->toDateTime ();
          $validityPeriod->Abilitato = $list->isBlacklist () ? 0 : ($list->isWhitelist () ? 1 : - 1);
          $validityPeriod->list_code = $list->code;
          $validityPeriod->Descrizione = implode ( ' ', array_trim_and_nonEmptyEntries ( array (
              $list->getListTitle (),
              $user->Nome,
              $user->Cognome 
          ) ) );
          $validityPeriod->epoch = $epochString;
          
          if (! $this->checkMinMaxValidityPeriod ( $validityPeriod, $list ))
          {
            $user->delete ();
            $messagesLog [] = t ( 'Invalid period length!' );
          }
          elseif (! $validityPeriod->save ())
          {
            $user->delete ();
            $messagesLog [] = t ( 'Unable to save validity period data.' );
          }
          else // periodo di validità salvato con successo
          {
            // creo veicoli
            $vehicles = array ();
            $vehiclesForRollback = array ();
            $vehicleFailure = false;
            foreach ( $model->getPlates () as $plate )
            {
              $vehicle = Vehicle::model ()->find ( 'list_code=:lc AND UserID=:ui AND Targa=:tg AND Nationality=:nt', array (
                  ':lc' => $list->code,
                  ':ui' => $user->ID,
                  ':nt' => $model->vehicle_nationality,
                  ':tg' => $plate 
              ) );
              if ($vehicle == null)
              {
                $vehicle = new Vehicle ();
                $vehicle->UserID = $user->ID;
                $vehicle->list_code = $list->code;
                $vehicle->Classe = $model->vehicle_type;
                $vehicle->Nationality = $model->vehicle_nationality;
                $vehicle->category = ''; // solo blacklist
                $vehicle->Targa = $plate;
                $vehicle->Abilitato = 1;
                $vehicle->source = $model->other_source;
                $vehicle->epoch = $epochString;
                $vehicle->Descrizione = implode ( ' ', array_trim_and_nonEmptyEntries ( array (
                    $list->getListTitle (),
                    $user->Nome,
                    $user->Cognome,
                    $plate 
                ) ) );
                if ($vehicle->save ())
                {
                  $vehicles [] = $vehicle;
                  $vehiclesForRollback [] = $vehicle;
                }
                else
                {
                  $vehicleFailure = true;
                  break;
                }
              }
              else
              {
                $vehicles [] = $vehicle; // NON SONO DA INCLUDERE NELLA ROLLBACK!
              }
            }
            // check for success or errors
            if (! $vehicleFailure) // success
            {
              // get gate data
              $gateChunks = explode ( '_', $model->plateauth_gate );
              if (count ( $gateChunks ) == 1)
              {
                $gateType = PlateAuthorization::GATEID_TYPE_GATE;
                $gateID = $gateChunks [0];
              }
              else
              {
                $gateType = $gateChunks [0];
                $gateID = $gateChunks [1];
              }
              // create permits
              $permits = array ();
              $permitsFailure = false;
              foreach ( $vehicles as $vehicle )
              {
                $plateAuth = new PlateAuthorization ();
                $plateAuth->UserID = $user->ID;
                $plateAuth->VehicleID = $vehicle->ID;
                $plateAuth->AbbonamentoID = $validityPeriod->ID;
                $plateAuth->list_code = $list->code;
                $plateAuth->epoch = $epochString;
                $plateAuth->insertid = user ()->id;
                $plateAuth->Note = $model->other_note;
                $plateAuth->action = $model->other_action;
                $plateAuth->type = $model->plateauth_type;
                $plateAuth->GateID = $gateID;
                $plateAuth->GateID_type = $gateType;
                $plateAuth->TimeID = $model->plateauth_time;
                if (user ()->checkAccess ( 'plate_auth_confirmed' ))
                  $plateAuth->to_be_confirmed = 0;
                else
                  $plateAuth->to_be_confirmed = 1;
                if (user ()->checkAccess ( 'plate_auth_enable' ))
                  $plateAuth->enabled = 1;
                else
                  $plateAuth->enabled = 0;
                $plateAuth->Descrizione = implode ( ' ', array_trim_and_nonEmptyEntries ( array (
                    $list->getListTitle (),
                    $user->Nome,
                    $user->Cognome,
                    $plate,
                    DateHelper::ensureObjectEx ( $validityPeriod->DataInizio )->toString (),
                    DateHelper::ensureObjectEx ( $validityPeriod->DataFine )->toString () 
                ) ) );
                if ($plateAuth->save ())
                {
                  $permits [] = $plateAuth;
                }
                else
                {
                  $permitsFailure = true;
                  break;
                }
              }
              // check for success or errors
              if (! $permitsFailure)
              {
                // single or multi?
                // redirect/render
                if (count ( $permits ) > 1)
                {
                  // multi, render
                  $this->render ( 'insertProfile/results', get_defined_vars () );
                }
                else
                {
                  // single redirect
                  $this->redirectTo ( 'PlateAuthorization/view', array (
                      'id' => $permits [0]->ID 
                  ) );
                }
                return;
              }
              else
              {
                // rollback
                foreach ( $permits as $p )
                  $p->delete ();
                foreach ( $vehicles as $v )
                  $v->delete ();
                $validityPeriod->delete ();
                $user->delete ();
                $messagesLog [] = t ( 'Unable to save vehicles data.' );
              }
            }
            else
            {
              // rollback
              foreach ( $vehicles as $v )
                $v->delete ();
              $validityPeriod->delete ();
              $user->delete ();
              $messagesLog [] = t ( 'Unable to save vehicles data.' );
            }
          }
        }
        
        // error
        foreach ( $messagesLog as $logmsg )
          user ()->setFlash ( 'error', $logmsg );
      }
    }
    else
    {
      foreach ( $model->fields as $f )
        $model->{$f->name} = $f->defaultVar;
    }
    
    $this->render ( 'insertProfile/index', get_defined_vars () );
  }

  public function actionUpdate($id)
  {
    access_denied_check ( 'plate_auth_update' );
    
    $model = $this->loadModel ( $id );
    
    // Uncomment the following line if AJAX validation is needed
    // $this->performAjaxValidation($model);
    
    if (isset ( $_POST ['PlateAuthorization'] ))
    {
      $model->attributes = $_POST ['PlateAuthorization'];
      if ($model->save ())
        
        $this->redirect ( array (
            'viewwhitelist',
            'id' => $model->ID 
        ) );
    }
    
    $this->render ( 'update', array (
        'model' => $model 
    ) );
  }

  public function actionList($plateListId, $idIsCode = false)
  {
    $plateList = PlateList::load ( $plateListId, $idIsCode );
    
    $item = $plateList->getPlateAuthsStats ();
    
    $stats = array ();
    
    $stats [t ( 'To be confirmed' )] = $item ['to_be_confirmed'];
    $stats [t ( 'Active' )] = $item ['enabled'];
    $stats [t ( 'Disabled' )] = $item ['disabled'];
    $stats [t ( 'Total' )] = $item ['total'];
    
    $this->render ( 'list', array (
        'plateList' => $plateList,
        'stats' => $stats 
    ) );
  }

  public function actionPrint($id)
  {
    access_denied_check ( 'plate_auth_print' );
    
    $model = $this->loadModel ( $id );
    
    $this->layout = '//layouts/print';
    
    $this->render ( 'print', array (
        'permit' => $model 
    ) );
  }

  public function actionIndex()
  {
    $plateLists = PlateList::getCurrentUserLists ();
    
    $plateAuthorizations = new Vehicle ( 'search' );
    $plateAuthorizations->unsetAttributes (); // clear any default values
    
    if (isset ( $_GET ['Vehicle'] ))
      $plateAuthorizations->attributes = $_GET ['Vehicle'];
    
    $this->render ( 'index', array (
        'plateLists' => $plateLists,
        'plateAuthorizations' => $plateAuthorizations 
    ) );
  }

  public function actionView($id)
  {
    $plateAuthorization = $this->loadModel ( $id );
    $isBlack = $plateAuthorization->plate_list->mode == PlateList::MODE_BLACK_LIST;
    
    $this->render ( $isBlack ? 'viewBlacklist' : 'viewWhitelist', array (
        'plateAuthorization' => $plateAuthorization 
    ) );
  }

  /**
   *
   * @param integer $id
   *          vehicle id
   */
  public function actionViewByVehicle($id)
  {
    $results = PlateAuthorization::model ()->byVehicleID ( $id )
      ->findAll ();
    
    $count = count ( $results );
    
    if ($count == 0)
      throw new CHttpException ( 404, 'The requested page does not exist.' );
    
    if ($count == 1)
    {
      $plateAuthorization = array_first ( $results );
      $this->redirectTo ( 'plateAuthorization/view', array (
          'id' => $plateAuthorization->ID 
      ) );
      return;
    }
    
    $this->render ( 'viewByVehicle', array (
        'plateAuths' => $results 
    ) );
  }

  public function actionNewAuthorization()
  {
    $gates = Gate::getAllGates ();
    
    $plateAuthorization = new NewPlateAuthorizationForm ();
    
    $this->render ( 'new', array (
        'plateAuthorization' => $plateAuthorization,
        'gates' => $gates 
    ) );
  }

  /**
   *
   * @param Array $row          
   * @param string $returnUrl          
   * @return SmartPlateAuth
   */
  public function createPermessoFromRow($row, $returnUrl = null)
  {
    return PlateAuthorization::createPermessoFromRowStatic ( $row, $returnUrl );
  }

  /**
   *
   * @return string[]
   */
  public static function getCustomValidityPeriods()
  {
    $today = new DateTimeEx ();
    $daysInCurrentMonth = $today->daysInMonth ();
    
    $buttons = array ();
    if (is_array_ex ( paramdeep ( 'plateAuthorizations', 'customValidityPeriods' ) ))
      foreach ( paramdeep ( 'plateAuthorizations', 'customValidityPeriods' ) as $cvp_label => $cvp_date )
      {
        $dateChunks = explode ( '-', $cvp_date );
        
        $dateChunksCount = count ( $dateChunks );
        if ($dateChunksCount <= 0 || $dateChunksCount > 3)
        {
          // $buttons["$cvp_date"] = "NO";
          continue;
        }
        
        $dateChunks = to_int_array ( $dateChunks );
        
        $date = clone $today;
        // $date->setTime(0,0,0);
        switch ($dateChunksCount)
        {
          case 1 :
            
            $day = $dateChunks [0];
            
            if ($day >= $today->day)
            {
              // current month
              $date->day = $day;
            }
            else
            {
              // next month
              $date->incMonth ();
              $date->day = $day;
            }
            
            break;
          case 2 :
            
            $month = $dateChunks [0];
            $day = $dateChunks [1];
            
            $date->month = $month;
            $date->day = $day;
            if ($date->isBeforeNow ())
              $date->year ++;
            
            break;
          case 3 :
            
            $year = $dateChunks [0];
            $month = $dateChunks [1];
            $day = $dateChunks [2];
            
            $date->year = $year;
            $date->month = $month;
            $date->day = $day;
            
            break;
        }
        
        if (! is_string ( $cvp_label ))
          $cvp_label = $date->toDateString ();
        
        if ($date->isValid () && $date->isAfterNow ( $today ))
          $buttons [$cvp_label] = $date->format ( "d/m/Y" );
        // else $buttons["$cvp_date"] = "NO $date";
      }
    
    return $buttons;
  }

  public function actionRenew($plateAuthId, $returnUrl = null)
  {
    access_denied_check ( 'plate_auth_renew' );
    
    $item = PlateAuthorization::findSmartObjectFromId ( $plateAuthId );
    if ($item === null)
      throw new CHttpException ( 400, t ( 'Plate authorization not found.' ) );
    
    $item = $this->createPermessoFromRow ( $item, $returnUrl );
    
    $request = new CArray ( $_REQUEST );
    
    if (isEmpty ( $request->renew_type ))
      $request->renew_type = 'from_duration';
    
    $renew_options = array ();
    $renew_options [1] = '1 ' . t ( 'day' );
    $renew_options [2] = '2 ' . t ( 'days' );
    $renew_options [3] = '3 ' . t ( 'days' );
    $renew_options [4] = '4 ' . t ( 'days' );
    $renew_options [5] = '5 ' . t ( 'days' );
    $renew_options [6] = '6 ' . t ( 'days' );
    $renew_options [7] = '1 ' . t ( 'week' );
    $renew_options [14] = '2 ' . t ( 'weeks' );
    $renew_options [21] = '3 ' . t ( 'weeks' );
    $renew_options [30] = '1 ' . t ( 'month' );
    $renew_options [60] = '2 ' . t ( 'months' );
    $renew_options [90] = '3 ' . t ( 'months' );
    $renew_options [365] = '1 ' . t ( 'year' );
    
    $item->renew_options = $renew_options;
    
    $newEndDate = DateTimeEx::now ();
    $newEndDate->addFromString ( "1 day" );
    $newEndDate = $newEndDate->format ( getFormat_Date () );
    
    $newEndTime = "23:59";
    
    if ($request->renew_pick !== null)
    {
      $newValidityPeriod = ValidityPeriod::model ()->findByPk ( $item->IDAbbonamento )->attributes;
      
      unset ( $newValidityPeriod ['ID'] );
      
      $now = new DateTime ();
      $endDate = $newValidityPeriod ['DataFine'];
      
      $renew_suffix = ' - ' . t ( 'Renewed' ) . ' ' . $now->format ( DateHelper::ISO9075_DATETIME );
      
      $startDate = DateTime::createFromFormat ( DateHelper::ISO9075_DATETIME, $request->newStartDate );
      $endDate = clone $startDate;
      
      if ($request->renew_type == 'from_duration')
      {
        $endDate->add ( date_interval_create_from_date_string ( "$request->renew_pick days" ) );
      }
      else if ($request->renew_type == 'from_date')
      {
        $endDateString = "{$request->renew_date} {$request->renew_time}";
        $endDate = DateTime::createFromFormat ( getFormat_DateTime () . ':s', $endDateString . ':59' );
      }
      else
      {
        user ()->setFlash ( 'error', t ( 'Please select a renewal type' ) );
        $endDate = null;
      }
      
      if ($endDate != null)
      {
        if ($startDate < $endDate)
        {
          $newValidityPeriod ['DataInizio'] = $startDate->format ( DateHelper::ISO9075_DATETIME );
          $newValidityPeriod ['DataFine'] = $endDate->format ( DateHelper::ISO9075_DATETIME );
          $newValidityPeriod ['epoch'] = $now->format ( DateHelper::ISO9075_DATETIME );
          $newValidityPeriod ['Descrizione'] .= $renew_suffix;
          
          $newPeriod = new ValidityPeriod ();
          $newPeriod->attributes = $newValidityPeriod;
          
          if ($newPeriod->save ())
          {
            $newPlateAuth = PlateAuthorization::model ()->findByPk ( $plateAuthId )->attributes;
            
            unset ( $newPlateAuth ['ID'] );
            
            $newPlateAuth ['epoch'] = $now->format ( DateHelper::ISO9075_DATETIME );
            $newPlateAuth ['Descrizione'] .= $renew_suffix;
            $newPlateAuth ['AbbonamentoID'] = $newPeriod->ID;
            
            $newPA = new PlateAuthorization ();
            $newPA->attributes = $newPlateAuth;
            
            if (Yii::app ()->user->checkAccess ( 'plate_auth_confirmed' ))
              $newPA->to_be_confirmed = 0;
            else
              $newPA->to_be_confirmed = 1;
            
            if (Yii::app ()->user->checkAccess ( 'plate_auth_enable' ))
              $newPA->enabled = 1;
            else
              $newPA->enabled = 0;
            
            if ($newPA->save ())
            {
              $this->redirect ( $item->url_return );
            }
            else
            {
              $valPer->delete ();
              throw new CHttpException ( 500, t ( 'Plate authorization creation failed.' ) );
            }
          }
          else
            throw new CHttpException ( 500, t ( 'Validity period creation failed.' ) );
        }
        else
          user ()->setFlash ( 'error', 'Start time must me less or equal than end time' );
      }
      else
        user ()->setFlash ( 'error', 'Please select a valid end time' );
    }
    
    $this->render ( 'renew', get_defined_vars () );
  }

  public function actionRevoke($plateAuthId, $returnUrl = null)
  {
    access_denied_check ( 'plate_auth_enable' );
    
    $item = $this->loadModel ( $plateAuthId );
    
    if ($returnUrl == null)
      if ($permesso->IDLista != null)
        $returnUrl = Yii::app ()->createUrl ( 'plateAuthorization/whiteListStatus', array (
            'plateListId' => $plateAuthId 
        ) );
      else
        $returnUrl = Yii::app ()->createUrl ( 'plateAuthorization' );
    
    $item->enabled = 0;
    
    $item->save ();
    
    $this->redirect ( $returnUrl );
  }

  public function actionActivate($plateAuthId, $returnUrl = null)
  {
    access_denied_check ( 'plate_auth_enable' );
    
    $item = $this->loadModel ( $plateAuthId );
    
    if ($returnUrl == null)
      if ($permesso->IDLista != null)
        $returnUrl = Yii::app ()->createUrl ( 'plateAuthorization/whiteListStatus', array (
            'plateListId' => $plateAuthId 
        ) );
      else
        $returnUrl = Yii::app ()->createUrl ( 'plateAuthorization' );
    
    $item->enabled = 1;
    
    $item->save ();
    
    $this->redirect ( $returnUrl );
  }

  public function actionConfirm($plateAuthId, $returnUrl = null)
  {
    access_denied_check ( 'plate_auth_confirmed' );
    
    $item = $this->loadModel ( $plateAuthId );
    
    if ($returnUrl == null)
      if ($permesso->IDLista != null)
        $returnUrl = Yii::app ()->createUrl ( 'plateAuthorization/whiteListStatus', array (
            'plateListId' => $plateAuthId 
        ) );
      else
        $returnUrl = Yii::app ()->createUrl ( 'plateAuthorization' );
    
    $item->to_be_confirmed = 0;
    
    $item->save ();
    
    $this->redirect ( $returnUrl );
  }

  public function actionWhitelistStatus($plateListId, $search = null, $timeRange = PlateAuthorization::FIND_EXPIRING_TIMERANGE_ALL, $status = PlateAuthorization::FIND_EXPIRING_STATUS_ALL, $sort = PlateAuthorization::FIND_EXPIRING_SORT_NONE)
  {
    // AUTHs and VARs
    access_denied_check ( 'plate_auth_status' );
    
    $list = null;
    $doGlobal = $plateListId == - 1;
    $doExport = isset ( $_REQUEST ['submit_export'] );
    $search = trim ( $search );
    $searchParam = $search;
    $pagination = intval ( array_get ( $_REQUEST, 'pagination', 20 ) );
    $pagination = $pagination < 1 ? 20 : $pagination;
    
    if ($doGlobal)
    {
      access_denied_check ( 'plate_auth_status_global' );
      $list = null;
    }
    else
    {
      $list = PlateList::load ( $plateListId, true );
    }
    
    if ($doExport)
      access_denied_check ( 'plate_auth_status_export' );
      
      // DATA
    $cmd = PlateAuthorization::findExpiring ( $plateListId, $searchParam, $timeRange, $status, $sort );
    
    if ($doExport)
    {
      $labelGate = t ( "All gates" );
      $labelTime = t ( "Always" );
      $cmd->select ( array (
          "wlt.ID as ID",
          
          "pl.name as " . t ( "List" ) . "",
          
          "ut.Nome as " . t ( "Name" ) . "",
          "ut.Cognome as " . t ( "Surname" ) . "",
          "ut.address as " . t ( "Address" ) . "",
          "ut.city as " . t ( "City" ) . "",
          "ut.phone as " . t ( "Phone" ) . "",
          "ut.email as " . t ( "Email" ) . "",
          
          "vt.Targa as " . t ( "Plate" ) . "",
          "vt.Nationality as " . t ( "Nationality" ) . "",
          
          "at.DataInizio as " . t ( "Start Date" ) . "",
          "at.DataFine as " . t ( "End Date" ) . "",
          
          "
          (CASE WHEN wlt.GateID=-1
          THEN '$labelGate'
          ELSE
          (CASE wlt.GateID_type
          WHEN '" . PlateAuthorization::GATEID_TYPE_GATE . "' THEN CONCAT('[" . t ( 'Gate' ) . "] ', gt.Descrizione)
          WHEN '" . PlateAuthorization::GATEID_TYPE_GROUP . "' THEN CONCAT('[" . t ( 'Group' ) . "] ', gp.name)          
          WHEN '" . PlateAuthorization::GATEID_TYPE_SET . "' THEN CONCAT('[" . t ( 'Set' ) . "] ', gs.name)          
          ELSE 'ERROR'
          END)
          END) as `" . t ( "Gate" ) . "`",
          
          "(CASE WHEN wlt.TimeID=-1 THEN '" . $labelTime . "' ELSE tt.Descrizione END) as `" . t ( "Time Schedule" ) . "`",
          
          "wlt.type as " . t ( "Type" ) . "",
          "wlt.enabled as " . t ( "Enabled" ) . "",
          "wlt.to_be_confirmed as " . t ( "To be confirmed" ) . "",
          "wlt.Note as " . t ( "Note" ) . "",
          
          /*
          'wlt.list_code as IDLista',
          'wlt.ID as IDPermesso',
          'at.ID as IDAbbonamento',
          'vt.ID as IDVeicolo',
          'ut.ID as IDUtente',
          'wlt.enabled as Enabled',
          'wlt.to_be_confirmed as ToBeConfirmed',
          'wlt.GateID as IDGate',
          'wlt.GateID_type as IDGate_type',
          'wlt.TimeID as IDTime',
          'gt.Descrizione as GateDescr',
          'pl.mode as ModeLista',
          'wlt.Descrizione as DescrizionePermesso',
          'vt.Descrizione as DescrizioneVeicolo',
          'at.Descrizione as DescrizionePeriodo',*/
      ) );
      
      $nowDateTime = new DateTime ();
      $listDescr = $doGlobal ? "ALL" : "$list->code";
      $filename = "PlateAuthExport_{$listDescr}_" . $nowDateTime->format ( "Y_m_d_H_i_s" ) . ".xlsx";
      
      $reader = $cmd->query ();
      
      SessionVars::instance ()->rowIndex = 0;
      SessionVars::instance ()->plateAuthTypes = paramdeep ( 'plateAuthorizations', 'types' );
      SessionVars::instance ()->plateAuthTypeKey = t ( "Type" );
      outputXlsx ( $filename, $reader, function ($row)
      {
        $svi = SessionVars::instance ();
        if ($svi->rowIndex > 0)
        {
          $row [$svi->plateAuthTypeKey] = array_get ( $svi->plateAuthTypes, $row [$svi->plateAuthTypeKey] );
        }
        $svi->rowIndex ++;
        return $row;
      } );
      
      exit ();
    }
    
    $cmd_cnt = clone $cmd;
    $cnt = $cmd_cnt->select ( 'COUNT(*)' )
      ->queryScalar ();
    $dataProvider = new CSqlDataProvider ( $cmd, array (
        'id' => 'whitelistStatusDataProvider',
        'totalItemCount' => $cnt,
        'pagination' => array (
            'pageSize' => $pagination 
        ) 
    ) );
    
    // GRAPHICs
    $statuses = array ();
    $statuses [PlateAuthorization::FIND_EXPIRING_STATUS_ALL] = t ( 'All' );
    $statuses [PlateAuthorization::FIND_EXPIRING_STATUS_EXPIRED] = t ( 'Expired' );
    $statuses [PlateAuthorization::FIND_EXPIRING_STATUS_VALID] = t ( 'Valid now' );
    $statuses [PlateAuthorization::FIND_EXPIRING_STATUS_EXPIRING] = t ( 'Expiring' );
    $statuses [PlateAuthorization::FIND_EXPIRING_STATUS_TOBECONFIRMED] = t ( 'To be confirmed' );
    $statuses [PlateAuthorization::FIND_EXPIRING_STATUS_CONFIRMED] = t ( 'Confirmed' );
    $statuses [PlateAuthorization::FIND_EXPIRING_STATUS_ENABLED] = t ( 'Activated' );
    $statuses [PlateAuthorization::FIND_EXPIRING_STATUS_DISABLED] = t ( 'Disabled' );
    
    $timeRanges = array ();
    $timeRanges [PlateAuthorization::FIND_EXPIRING_TIMERANGE_ALL] = t ( 'All' );
    $timeRanges [1] = '1 ' . t ( 'day' );
    $timeRanges [3] = '3 ' . t ( 'days' );
    $timeRanges [7] = '1 ' . t ( 'week' );
    $timeRanges [30] = '30 ' . t ( 'days' );
    $timeRanges [60] = '60 ' . t ( 'days' );
    $timeRanges [365] = '1 ' . t ( 'year' );
    
    $sortList = array ();
    $sortList [PlateAuthorization::FIND_EXPIRING_SORT_NONE] = t ( 'None' );
    $sortList [PlateAuthorization::FIND_EXPIRING_SORT_NAME_ASC] = t ( 'Name' ) . ' ASC';
    $sortList [PlateAuthorization::FIND_EXPIRING_SORT_NAME_DESC] = t ( 'Name' ) . ' DESC';
    $sortList [PlateAuthorization::FIND_EXPIRING_SORT_SURNAME_ASC] = t ( 'Surname' ) . ' ASC';
    $sortList [PlateAuthorization::FIND_EXPIRING_SORT_SURNAME_DESC] = t ( 'Surname' ) . ' DESC';
    $sortList [PlateAuthorization::FIND_EXPIRING_SORT_PLATE_ASC] = t ( 'Plate' ) . ' ASC';
    $sortList [PlateAuthorization::FIND_EXPIRING_SORT_PLATE_DESC] = t ( 'Plate' ) . ' DESC';
    $sortList [PlateAuthorization::FIND_EXPIRING_SORT_GATE_ASC] = t ( 'Gate' ) . ' ASC';
    $sortList [PlateAuthorization::FIND_EXPIRING_SORT_GATE_DESC] = t ( 'Gate' ) . ' DESC';
    $sortList [PlateAuthorization::FIND_EXPIRING_SORT_IDTIME_ASC] = t ( 'Time Schedule' ) . ' ASC';
    $sortList [PlateAuthorization::FIND_EXPIRING_SORT_IDTIME_DESC] = t ( 'Time Schedule' ) . ' DESC';
    $sortList [PlateAuthorization::FIND_EXPIRING_SORT_STARTTIME_ASC] = t ( 'Start time' ) . ' ASC';
    $sortList [PlateAuthorization::FIND_EXPIRING_SORT_STARTTIME_DESC] = t ( 'Start time' ) . ' DESC';
    $sortList [PlateAuthorization::FIND_EXPIRING_SORT_ENDTIME_ASC] = t ( 'End time' ) . ' ASC';
    $sortList [PlateAuthorization::FIND_EXPIRING_SORT_ENDTIME_DESC] = t ( 'End time' ) . ' DESC';
    $sortList [PlateAuthorization::FIND_EXPIRING_SORT_CREATETIME_ASC] = t ( 'Creation time' ) . ' ASC';
    $sortList [PlateAuthorization::FIND_EXPIRING_SORT_CREATETIME_DESC] = t ( 'Creation time' ) . ' DESC';
    
    // RENDER
    $this->render ( 'authorizations_status/plateAuthStatus', array (
        'plateList' => $list,
        'plateListId' => $plateListId,
        'dataProvider' => $dataProvider,
        'timeRanges' => $timeRanges,
        'timeRange' => $timeRange,
        'statuses' => $statuses,
        'status' => $status,
        'search' => $search,
        'sortList' => $sortList,
        'sort' => $sort,
        'totalResults' => $cnt,
        'pagination' => $pagination 
    ) );
  }

  public function actionNewBlacklist($plateListId, $idIsCode = false, $plate = null, $refTimestamp = null, $nationality = null)
  {
    $this->newBlackWhiteList ( $plateListId, true, $idIsCode, $plate, $refTimestamp, $nationality );
  }

  public function actionNewWhitelist($plateListId, $idIsCode = false, $plate = null, $refTimestamp = null, $nationality = null)
  {
    $this->newBlackWhiteList ( $plateListId, false, $idIsCode, $plate, $refTimestamp, $nationality );
  }
  
  // quando si aggiungono params qui vanno aggiunti anche nei caller
  protected function newBlackWhiteList($plateListId, $isBlacklist, $idIsCode = false, $plate = null, $refTimestamp = null, $nationality = null)
  {
    access_denied_check ( 'plate_auth_insert' );
    access_denied_check ( 'plate_auth_insert_fast' );
    
    $plateList = PlateList::load ( $plateListId, $idIsCode );
    
    $plateAuthorization = new NewBlacklistForm ();
    
    /*
     * $ANONYMOUS = t("ANONYMOUS");
     * $plateAuthorization->name = $ANONYMOUS;
     * $plateAuthorization->surname = $ANONYMOUS;
     */
    
    if (! empty ( $plate ))
      $plateAuthorization->plate = implode ( PHP_EOL, plate_list_normalization ( $plate ) );
    
    if ($refTimestamp != null)
    {
      $refTimestamp = tts ( $refTimestamp );
      
      $startTimestamp = clone $refTimestamp;
      $startTimestamp->subFromString ( '1 hour' );
      
      $endTimestamp = clone $refTimestamp;
      $endTimestamp->addFromString ( '1 hour' );
      
      $plateAuthorization->startDate = $startTimestamp->format ( getFormat_Date () );
      $plateAuthorization->startTime = $startTimestamp->format ( getFormat_Time () );
      
      $plateAuthorization->endDate = $endTimestamp->format ( getFormat_Date () );
      $plateAuthorization->endTime = $endTimestamp->format ( getFormat_Time () );
    }
    
    if (! empty ( $nationality ))
    {
      $plateAuthorization->vehicleNationality = $nationality;
    }
    
    // Uncomment the following line if AJAX validation is needed
    // $this->performAjaxValidation($model);
    
    if (isset ( $_POST ['NewBlacklistForm'] ))
    {
      // var_dump($_POST['NewBlacklistForm']);
      // throw new CHttpException(400, Yii::app('t', 'plateListId is required.'));
      $plateAuthorization->setAttributes ( $_POST ['NewBlacklistForm'], false );
      $plateAuthorization->list_code = $plateList->code;
      
      $plateAuthorization->normalizePlates ();
      
      if (! $plateAuthorization->validate ())
      {
        $this->render ( 'new_authorizations/new_blacklist', array (
            'plateAuthorization' => $plateAuthorization,
            'plateList' => $plateList,
            'isBlacklist' => $isBlacklist 
        ) );
        return;
      }
      
      $epoch = new DateTime ();
      $epochString = DateHelper::formatISO9075DateTime ( $epoch );
      
      $user = VehicleOwner::model ()->find ( 'list_code=:lst AND Nome=:nm AND Cognome=:srnm', array (
          ':lst' => $plateList->code,
          ':nm' => $plateAuthorization->name,
          ':srnm' => $plateAuthorization->surname 
      ) );
      
      if ($user == null || ($user != null && ! $plateAuthorization->overwriteVehicleOwner))
      {
        $user = new VehicleOwner ();
        
        $user->Nome = $plateAuthorization->name;
        $user->Cognome = $plateAuthorization->surname;
        
        $user->email = $plateAuthorization->email;
        $user->phone = $plateAuthorization->phone;
        $user->address = $plateAuthorization->address;
        $user->city = $plateAuthorization->city;
        
        $user->list_code = $plateList->code;
        $user->epoch = $epochString;
        if (! $user->save ())
        {
          Yii::app ()->user->setFlash ( 'error', Yii::t ( 'app', 'Unable to save ' . ($isBlacklist ? 'blacklist' : 'whitelist') . ' user data.' ) );
          $this->render ( 'new_authorizations/new_blacklist', array (
              'plateAuthorization' => $plateAuthorization,
              'plateList' => $plateList,
              'isBlacklist' => $isBlacklist 
          ) );
          return;
        }
      }
      else
      {
        $changed = false;
        
        if (! empty ( $plateAuthorization->email ))
        {
          $user->email = $plateAuthorization->email;
          $changed = true;
        }
        
        if (! empty ( $plateAuthorization->phone ))
        {
          $user->phone = $plateAuthorization->phone;
          $changed = true;
        }
        if (! empty ( $plateAuthorization->address ))
        {
          $user->address = $plateAuthorization->address;
          $changed = true;
        }
        if (! empty ( $plateAuthorization->city ))
        {
          $user->city = $plateAuthorization->city;
          $changed = true;
        }
        
        if ($changed)
        {
          if (! $user->save ())
          {
            Yii::app ()->user->setFlash ( 'error', Yii::t ( 'app', 'Unable to save ' . ($isBlacklist ? 'blacklist' : 'whitelist') . ' user data.' ) );
            $this->render ( 'new_authorizations/new_blacklist', array (
                'plateAuthorization' => $plateAuthorization,
                'plateList' => $plateList,
                'isBlacklist' => $isBlacklist 
            ) );
            return;
          }
        }
      }
      
      $validityPeriod = new ValidityPeriod ();
      $validityPeriod->UserID = $user->ID;
      $validityPeriod->DataInizio = $plateAuthorization->getStartDateTime ()
        ->toDateTime ();
      $validityPeriod->DataFine = $plateAuthorization->getEndDateTime ()
        ->toDateTime ();
      $validityPeriod->Abilitato = $isBlacklist ? ValidityPeriod::ENABLE_BLACK : ValidityPeriod::ENABLE_WHITE;
      $validityPeriod->list_code = $plateList->code;
      $validityPeriod->Descrizione = $user->Nome;
      $validityPeriod->epoch = $epochString;
      
      if (! $this->checkMinMaxValidityPeriod ( $validityPeriod, $plateList ))
      {
        $user->delete ();
        
        user ()->setFlash ( 'error', t ( 'Invalid period length!' ) );
        $this->render ( 'new_authorizations/new_blacklist', array (
            'plateAuthorization' => $plateAuthorization,
            'plateList' => $plateList,
            'isBlacklist' => $isBlacklist 
        ) );
        
        return;
      }
      elseif (! $validityPeriod->save ())
      {
        $user->delete ();
        
        Yii::app ()->user->setFlash ( 'error', Yii::t ( 'app', 'Unable to save ' . ($isBlacklist ? 'blacklist' : 'whitelist') . ' validity period data.' ) );
        $this->render ( 'new_authorizations/new_blacklist', array (
            'plateAuthorization' => $plateAuthorization,
            'plateList' => $plateList,
            'isBlacklist' => $isBlacklist 
        ) );
        return;
      }
      
      // //// INIZIO INSERIMENTO MULTI PLATE
      $messages = array ();
      $plates = $plateAuthorization->getPlates ();
      $isMultiPlateInsert = count ( $plates ) > 1;
      foreach ( $plates as $thePlate )
      {
        
        $vehicle = Vehicle::model ()->find ( 'list_code=:lst AND UserID=:usr AND Targa=:trg AND Nationality=:nat', array (
            ':lst' => $plateList->code,
            ':usr' => $user->ID,
            ':nat' => $plateAuthorization->vehicleNationality,
            ':trg' => $thePlate 
        ) );
        
        if ($vehicle == null)
        {
          $vehicle = new Vehicle ();
          $vehicle->UserID = $user->ID;
          $vehicle->list_code = $plateList->code;
          $vehicle->Classe = $plateAuthorization->vehicleType;
          $vehicle->Nationality = $plateAuthorization->vehicleNationality;
          $vehicle->category = $plateAuthorization->vehicleCategory;
          $vehicle->Targa = $thePlate;
          $vehicle->Abilitato = 1;
          $vehicle->source = $plateAuthorization->source;
          $vehicle->epoch = $epochString;
          $vehicle->Descrizione = $plateAuthorization->vehicleModel;
          
          if (! $vehicle->save ())
          {
            if (! $isMultiPlateInsert)
            {
              $user->delete ();
              $validityPeriod->delete ();
              
              Yii::app ()->user->setFlash ( 'error', Yii::t ( 'app', 'Unable to save ' . ($isBlacklist ? 'blacklist' : 'whitelist') . ' vehicle data.' ) );
              $this->render ( 'new_authorizations/new_blacklist', array (
                  'plateAuthorization' => $plateAuthorization,
                  'plateList' => $plateList,
                  'isBlacklist' => $isBlacklist 
              ) );
              return;
            }
            else
            {
              $messages [] = array (
                  'result' => true,
                  'plate' => $thePlate,
                  'color' => 'red',
                  'message' => Yii::t ( 'app', 'Unable to save ' . ($isBlacklist ? 'blacklist' : 'whitelist') . ' vehicle data.' ) 
              );
              continue;
            }
          }
        }
        
        $gateChunks = explode ( '_', $plateAuthorization->filterGate );
        if (count ( $gateChunks ) == 1)
        {
          $gateType = PlateAuthorization::GATEID_TYPE_GATE;
          $gateID = $gateChunks [0];
        }
        else
        {
          $gateType = $gateChunks [0];
          $gateID = $gateChunks [1];
        }
        
        $plateAuth = new PlateAuthorization ();
        $plateAuth->UserID = $user->ID;
        $plateAuth->VehicleID = $vehicle->ID;
        $plateAuth->AbbonamentoID = $validityPeriod->ID;
        $plateAuth->list_code = $plateList->code;
        $plateAuth->Descrizione = "$plateAuth->list_code $user->Nome $user->Cognome $vehicle->Targa";
        $plateAuth->epoch = $epochString;
        $plateAuth->insertid = Yii::app ()->user->id;
        $plateAuth->Note = $plateAuthorization->note;
        $plateAuth->action = $plateAuthorization->action;
        $plateAuth->type = $plateAuthorization->type;
        $plateAuth->GateID = $gateID;
        $plateAuth->GateID_type = $gateType;
        $plateAuth->TimeID = $plateAuthorization->filterTime;
        
        if (Yii::app ()->user->checkAccess ( 'plate_auth_confirmed' ))
          $plateAuth->to_be_confirmed = 0;
        else
          $plateAuth->to_be_confirmed = 1;
        
        if (Yii::app ()->user->checkAccess ( 'plate_auth_enable' ))
          $plateAuth->enabled = 1;
        else
          $plateAuth->enabled = 0;
        
        if ($plateAuth->save ())
        {
          if (! $isMultiPlateInsert)
          {
            Yii::app ()->user->setFlash ( 'success', Yii::t ( 'app', 'Vehicle {plate} successfully saved in ' . ($isBlacklist ? 'blacklist' : 'whitelist') . '.', array (
                '{plate}' => $vehicle->Targa 
            ) ) );
            $this->redirect ( array (
                'view',
                'id' => $plateAuth->ID 
            ) );
            return;
          }
          else
          {
            $messages [] = array (
                'result' => true,
                'plate' => $thePlate,
                'color' => 'green',
                'message' => Yii::t ( 'app', 'Vehicle {plate} successfully saved in ' . ($isBlacklist ? 'blacklist' : 'whitelist') . '.', array (
                    '{plate}' => $vehicle->Targa 
                ) ) 
            );
          }
        }
        else
        {
          if (! $isMultiPlateInsert)
          {
            $user->delete ();
            $validityPeriod->delete ();
            $vehicle->delete ();
            Yii::app ()->user->setFlash ( 'error', Yii::t ( 'app', 'Unable to save data.' ) );
            $this->render ( 'new_authorizations/new_blacklist', array (
                'plateAuthorization' => $plateAuthorization,
                'plateList' => $plateList,
                'isBlacklist' => $isBlacklist 
            ) );
            return;
          }
          else
          {
            $messages [] = array (
                'plate' => $thePlate,
                'color' => 'red',
                'message' => Yii::t ( 'app', 'Vehicle {plate} not saved in ' . ($isBlacklist ? 'blacklist' : 'whitelist') . '.', array (
                    '{plate}' => $vehicle->Targa 
                ) ) 
            );
          }
        }
      } // //// FINE INSERIMENTO MULTI PLATE
      if (count ( $plates ) > 1)
      {
        $this->render ( 'new_authorizations/bulkInsertResult', array (
            'plateList' => $plateList,
            'messages' => $messages,
            'startDateTime' => $plateAuthorization->getStartDateTime (),
            'endDateTime' => $plateAuthorization->getEndDateTime (),
            'gate' => $plateAuthorization->filterGate,
            'time' => $plateAuthorization->filterTime 
        ) );
        return;
      }
    }
    else
    {
      // nuovo inserimento
      $plateAuthorization->name = paramdeep ( 'plateAuthorizations', 'default', 'name' );
      $plateAuthorization->surname = paramdeep ( 'plateAuthorizations', 'default', 'surname' );
      $plateAuthorization->filterGate = paramdeep ( 'plateAuthorizations', 'default', 'gate' );
      $plateAuthorization->filterTime = paramdeep ( 'plateAuthorizations', 'default', 'time' );
      $plateAuthorization->type = paramdeep ( 'plateAuthorizations', 'default', 'plateAuthType' );
      if (empty ( $plateAuthorization->vehicleNationality ))
      {
        $plateAuthorization->vehicleNationality = CountryList::getGuiLang ();
      }
    }
    
    $this->render ( 'new_authorizations/new_blacklist', array (
        'plateAuthorization' => $plateAuthorization,
        'plateList' => $plateList,
        'isBlacklist' => $isBlacklist 
    ) );
  }

  protected function checkMinMaxValidityPeriod(ValidityPeriod $validityPeriod, PlateList $plateList)
  {
    $from = new DateTimeEx ( $validityPeriod->DataInizio );
    $to = new DateTimeEx ( $validityPeriod->DataFine );
    
    $periodLength = $to->subDate ( $from );
    
    $lowerBoundDiff = date_interval_compare ( $plateList->getMinimumDuration (), $periodLength );
    $upperBoundDiff = date_interval_compare ( $periodLength, $plateList->getMaximumDuration () );
    
    $durmin = $plateList->getMinimumDuration ()
      ->format ( '%D %H:%I:%S' );
    $durmax = $plateList->getMaximumDuration ()
      ->format ( '%D %H:%I:%S' );
    $dur = $periodLength->format ( '%D %H:%I:%S' );
    
    return $lowerBoundDiff != 1 && $upperBoundDiff != 1;
  }

  public function actionWhiteListWizardDelete($listId, $objType, $objId, $returnUrl = null)
  {
    access_denied_check ( 'plate_auth_delete' );
    switch ($objType)
    {
      case 'owner' :
        $model = VehicleOwner::model ()->findByPk ( $objId );
        if ($model !== null)
        {
          Vehicle::model ()->deleteAll ( 'list_code=:lst AND UserID=:usr', array (
              ':lst' => $listId,
              ':usr' => $objId 
          ) );
          ValidityPeriod::model ()->deleteAll ( 'list_code=:lst AND UserID=:usr', array (
              ':lst' => $listId,
              ':usr' => $objId 
          ) );
          PlateAuthorization::model ()->deleteAll ( 'list_code=:lst AND UserID=:usr', array (
              ':lst' => $listId,
              ':usr' => $objId 
          ) );
          $model->delete ();
        }
        break;
      case 'vehicle' :
        $model = Vehicle::model ()->findByPk ( $objId );
        if ($model !== null)
        {
          ValidityPeriod::model ()->deleteAll ( 'list_code=:lst AND UserID=:usr', array (
              ':lst' => $listId,
              ':usr' => $objId 
          ) );
          PlateAuthorization::model ()->deleteAll ( 'list_code=:lst AND VehicleID=:usr', array (
              ':lst' => $listId,
              ':usr' => $objId 
          ) );
          $model->delete ();
        }
        break;
      case 'period' :
        $model = ValidityPeriod::model ()->findByPk ( $objId );
        if ($model !== null)
        {
          PlateAuthorization::model ()->deleteAll ( 'list_code=:lst AND AbbonamentoID=:usr', array (
              ':lst' => $listId,
              ':usr' => $objId 
          ) );
          $model->delete ();
        }
        break;
      case 'auth' :
        $model = PlateAuthorization::model ()->findByPk ( $objId );
        if ($model !== null)
        {
          $model->delete ();
        }
        break;
      default :
        throw new CHttpException ( 404, 'The requested $type does not exist.' );
    }
    
    if ($returnUrl != null)
      $this->redirect ( $returnUrl );
    else
      $this->renderText ( t ( "Operation complete" ) );
  }

  public function actionWhiteListWizard() // $plateListId, $step="1", $action=null, $ownerId=null, $vehicleId=null, $validityPeriodId = null
  {
    access_denied_check ( 'plate_auth_insert' );
    access_denied_check ( 'plate_auth_insert_wizard' );
    
    $plateListId = $_REQUEST [plateListId];
    $step = $_REQUEST [step];
    $action = $_REQUEST [action];
    $ownerId = $_REQUEST [ownerId];
    $vehicleId = $_REQUEST [vehicleId];
    $validityPeriodId = $_REQUEST [validityPeriodId];
    
    $properties = array ();
    
    // la validazione della lista ci deve essere sempre
    $list = PlateList::findByCode ( $plateListId );
    if ($list === null)
      throw new CHttpException ( 400, Yii::app ( 't', 'plateListId is required.' ) );
      
      // step 1 - scelta/creazione utente
    if (empty ( $step ) || $step == "1")
    {
      $what = $_REQUEST ['what'];
      
      // il model VehicleOwner serve sempre allo step1
      $model = new VehicleOwner ();
      $model->list_code = $plateListId;
      
      $context = array (
          'step' => $step,
          'plateListId' => $plateListId 
      );
      
      // se default o ricerca
      if (empty ( $action ) || $action == 'search')
      {
        // includo filtro
        if (! empty ( $what ))
        {
          $model->byDescription ( $what );
        }
        
        // renderizzo
        $this->render ( 'whiteListWizard/step1', array (
            'owners' => $model->search (),
            'plateListId' => $plateListId,
            'objList' => $list,
            'context' => $context,
            'properties' => $properties,
            'what' => $what 
        ) );
      }
      // se voglio creare un utente nuovo
      else if ($action == 'create')
      {
        $properties ['owner_confirmation_name'] = strtoupper ( $_REQUEST ['name'] );
        $properties ['owner_confirmation_surname'] = strtoupper ( $_REQUEST ['surname'] );
        
        // imposto nome e cognome
        if (empty ( $_REQUEST ['name'] ))
          Yii::app ()->user->setFlash ( 'error', Yii::t ( 'app', 'Name cannot be empty' ) );
        elseif (empty ( $_REQUEST ['surname'] ))
          Yii::app ()->user->setFlash ( 'error', Yii::t ( 'app', 'Surname cannot be empty' ) );
        else
        {
          $model->Nome = strtoupper ( $_REQUEST ['name'] );
          $model->Cognome = strtoupper ( $_REQUEST ['surname'] );
          
          if ($_REQUEST [create_confirmed] == 'yes' || VehicleOwner::model ()->count ( 'Nome=:nm AND Cognome=:cgnm', array (
              ':nm' => $_REQUEST ['name'],
              ':cgnm' => $_REQUEST ['surname'] 
          ) ) <= 0)
          {
            $model->epoch = DateHelper::formatISO9075DateTime ();
            
            // salvo e mostro flash error in caso di errore
            if (! $model->save ())
              Yii::app ()->user->setFlash ( 'error', Yii::t ( 'app', 'Unable to save whitelist user data.' ) );
            else
              $this->redirectTo ( 'PlateAuthorization/WhiteListWizard', array (
                  'step' => 2,
                  'plateListId' => $plateListId,
                  'ownerId' => $model->ID 
              ) );
          }
          else
          {
            // confirmation required
            $properties ['create_confirmed'] = 'yes';
            Yii::app ()->user->setFlash ( 'notice', Yii::t ( 'app', "Another user with the same name and surname already exists. Press 'Create' again to confirm the operation." ) );
          }
        }
        
        // renderizzo
        $this->render ( 'whiteListWizard/step1', array (
            'owners' => $model->search (),
            'plateListId' => $plateListId,
            'objList' => $list,
            'context' => $context,
            'properties' => $properties,
            'what' => "$_REQUEST[name] $_REQUEST[surname]" 
        ) );
      }
      // action ha un valore sbagliato
      else
        throw new CHttpException ( 404, 'The requested page does not exist.' );
    }
    // step 2 - scelta/creazione veicolo
    else if ($step == "2")
    {
      $owner = VehicleOwner::model ()->findByPk ( $ownerId );
      if ($owner === null)
        throw new CHttpException ( 404, 'The requested vehicle owner does not exist.' );
      
      $what = $_REQUEST ['what'];
      
      $context = array (
          'step' => $step,
          'plateListId' => $plateListId,
          'ownerId' => $ownerId 
      );
      
      // il model Vehicle serve sempre allo step2
      $model = new Vehicle ();
      $model->list_code = $plateListId;
      $model->UserID = $ownerId;
      
      // se default o ricerca
      if (empty ( $action ) || $action == 'search')
      {
        // includo filtro
        if (! empty ( $what ))
        {
          $model->byDescription ( $what );
        }
        
        // renderizzo
        $this->render ( 'whiteListWizard/step2', array (
            'vehicles' => $model->search (),
            'plateListId' => $plateListId,
            'ownerId' => $ownerId,
            'objOwner' => $owner,
            'objList' => $list,
            'context' => $context,
            'properties' => $properties,
            'what' => $what 
        ) );
      }
      // se voglio creare un veicolo nuovo
      else if ($action == 'create')
      {
        // imposto dati veicolo
        if (empty ( $_REQUEST ['v_plate'] ))
          Yii::app ()->user->setFlash ( 'error', Yii::t ( 'app', 'Plate cannot be empty' ) );
        else
        {
          
          // just warn the user
          if (Vehicle::model ()->count ( 'Targa=:plate AND list_code=:lst AND Nationality=:nat', array (
              ':plate' => $_REQUEST ['v_plate'],
              ':nat' => $_REQUEST ['v_nationality'],
              ':lst' => $plateListId 
          ) ) > 0)
            Yii::app ()->user->setFlash ( 'warning', Yii::t ( 'app', 'The specified plate already exists in the current list' ) );
          
          $model->Descrizione = $_REQUEST ['v_description'];
          $model->Classe = $_REQUEST ['v_class'];
          $model->Nationality = $_REQUEST ['v_nationality'];
          $model->category = $_REQUEST ['v_category'];
          $model->Targa = strtoupper ( $_REQUEST ['v_plate'] );
          $model->Abilitato = 1;
          $model->source = $_REQUEST ['v_source'];
          $model->action = $_REQUEST ['v_action'];
          $model->note = $_REQUEST ['v_note'];
          $model->epoch = DateHelper::formatISO9075DateTime ();
          
          // salvo e mostro flash error in caso di errore
          if (! $model->save ())
            Yii::app ()->user->setFlash ( 'error', Yii::t ( 'app', 'Unable to save whitelist vehicle data.' ) . $model->getErrorsHtml () );
          else
            $this->redirectTo ( 'PlateAuthorization/WhiteListWizard', array (
                'step' => 3,
                'plateListId' => $plateListId,
                'ownerId' => $ownerId,
                'vehicleId' => $model->ID 
            ) );
        }
        
        // renderizzo
        $this->render ( 'whiteListWizard/step2', array (
            'vehicles' => $model->search (),
            'plateListId' => $plateListId,
            'ownerId' => $ownerId,
            'objOwner' => $owner,
            'objList' => $list,
            'context' => $context,
            'properties' => $properties,
            'what' => '' 
        ) );
      }
      // action ha un valore sbagliato
      else
        throw new CHttpException ( 404, 'The requested page does not exist.' );
    }
    // step 3 - scelta/creazione abbonamento
    else if ($step == "3")
    {
      $owner = VehicleOwner::model ()->findByPk ( $ownerId );
      if ($owner === null)
        throw new CHttpException ( 404, 'The requested vehicle owner does not exist.' );
      
      $vehicle = Vehicle::model ()->findByPk ( $vehicleId );
      if ($vehicle === null)
        throw new CHttpException ( 404, 'The requested vehicle does not exist.' );
      
      $what = $_REQUEST ['what'];
      
      $context = array (
          'step' => $step,
          'plateListId' => $plateListId,
          'ownerId' => $ownerId,
          'vehicleId' => $vehicleId 
      );
      
      // il model ValidityPeriod serve sempre allo step3
      $model = new ValidityPeriod ();
      $model->list_code = $plateListId;
      $model->UserID = $ownerId;
      $model->Abilitato = ValidityPeriod::ENABLE_WHITE;
      
      // se default o ricerca
      if (empty ( $action ) || $action == 'search')
      {
        // includo filtro
        if (! empty ( $what ))
        {
          $model->byDescription ( $what );
        }
        
        // renderizzo
        $this->render ( 'whiteListWizard/step3', array (
            'periods' => $model->search (),
            'plateListId' => $plateListId,
            'ownerId' => $ownerId,
            'vehicleId' => $vehicleId,
            'objOwner' => $owner,
            'objVehicle' => $vehicle,
            'objList' => $list,
            'context' => $context,
            'properties' => $properties,
            'what' => $what 
        ) );
      }
      // se voglio creare un abbonamento nuovo
      else if ($action == 'create')
      {
        // imposto dati abbonamento
        $startDateTimeString = $_REQUEST ['a_startDate'] . ' ' . $_REQUEST ['a_startTime'];
        $endDateTimeString = $_REQUEST ['a_endDate'] . ' ' . $_REQUEST ['a_endTime'];
        
        $fromTime = DateTime::createFromFormat ( getFormat_DateTime () . ':s', $startDateTimeString . ':00' );
        $toTime = DateTime::createFromFormat ( getFormat_DateTime () . ':s', $endDateTimeString . ':59' );
        
        if ($fromTime <= $toTime)
        {
          $model->Descrizione = $_REQUEST ['a_description'];
          $model->Tipo = $_REQUEST ['a_type'];
          $model->DataInizio = DateHelper::formatISO9075DateTime ( $fromTime );
          $model->DataFine = DateHelper::formatISO9075DateTime ( $toTime );
          $model->epoch = DateHelper::formatISO9075DateTime ();
          // salvo e mostro flash error in caso di errore
          if (! $this->checkMinMaxValidityPeriod ( $validityPeriod, $list ))
            user ()->setFlash ( 'error', 'Invalid period length!' );
          elseif (! $model->save ())
            Yii::app ()->user->setFlash ( 'error', Yii::t ( 'app', 'Unable to save validity period vehicle data.' ) );
          else
            $this->redirectTo ( 'PlateAuthorization/WhiteListWizard', array (
                'step' => 4,
                'plateListId' => $plateListId,
                'ownerId' => $ownerId,
                'vehicleId' => $vehicleId,
                'validityPeriodId' => $model->ID 
            ) );
        }
        else
        {
          Yii::app ()->user->setFlash ( 'error', Yii::t ( 'app', 'Start date must be less or equals of end date' ) );
        }
        
        // renderizzo
        $this->render ( 'whiteListWizard/step3', array (
            'periods' => $model->searchForWizard (),
            'plateListId' => $plateListId,
            'ownerId' => $ownerId,
            'vehicleId' => $vehicleId,
            'objOwner' => $owner,
            'objVehicle' => $vehicle,
            'objList' => $list,
            'context' => $context,
            'properties' => $properties,
            'what' => $_REQUEST ['a_description'] 
        ) );
      }
      // action ha un valore sbagliato
      else
        throw new CHttpException ( 404, 'The requested page does not exist.' );
    }
    // step 4 - scelta/creazione permesso (whitelisttable)
    else if ($step == "4")
    {
      $owner = VehicleOwner::model ()->findByPk ( $ownerId );
      if ($owner === null)
        throw new CHttpException ( 404, 'The requested vehicle owner does not exist.' );
      
      $vehicle = Vehicle::model ()->findByPk ( $vehicleId );
      if ($vehicle === null)
        throw new CHttpException ( 404, 'The requested vehicle does not exist.' );
      
      $period = ValidityPeriod::model ()->findByPk ( $validityPeriodId );
      if ($period === null)
        throw new CHttpException ( 404, 'The requested validity period does not exist.' );
      
      $what = $_REQUEST ['what'];
      
      $context = array (
          'step' => $step,
          'plateListId' => $plateListId,
          'ownerId' => $ownerId,
          'vehicleId' => $vehicleId,
          'validityPeriodId' => $validityPeriodId 
      );
      
      // il model PlateAuthorization serve sempre allo step4
      $model = new PlateAuthorization ();
      $model->list_code = $plateListId;
      $model->UserID = $ownerId;
      $model->AbbonamentoID = $validityPeriodId;
      $model->VehicleID = $vehicleId;
      
      // se default o ricerca
      if (empty ( $action ) || $action == 'search')
      {
        // includo filtro
        if (! empty ( $what ))
        {
          $model->byDescription ( $what );
        }
        
        // renderizzo
        $this->render ( 'whiteListWizard/step4', array (
            'auths' => $model->searchForWizard (),
            'plateListId' => $plateListId,
            'ownerId' => $ownerId,
            'vehicleId' => $vehicleId,
            'validityPeriodId' => $validityPeriodId,
            'objOwner' => $owner,
            'objVehicle' => $vehicle,
            'objPeriod' => $period,
            'objList' => $list,
            'context' => $context,
            'properties' => $properties,
            'what' => $what 
        ) );
      }
      // se voglio creare un permesso nuovo
      else if ($action == 'create')
      {
        // imposto dati permesso
        if (empty ( $_REQUEST ['p_type'] ))
          Yii::app ()->user->setFlash ( 'error', Yii::t ( 'app', 'Type cannot be empty' ) );
        elseif (empty ( $_REQUEST ['p_gate'] ))
          Yii::app ()->user->setFlash ( 'error', Yii::t ( 'app', 'Gate cannot be empty' ) );
        elseif (empty ( $_REQUEST ['p_time'] ))
          Yii::app ()->user->setFlash ( 'error', Yii::t ( 'app', 'Time cannot be empty' ) );
        else
        {
          
          $gateChunks = explode ( '_', $_REQUEST ['p_gate'] );
          if (count ( $gateChunks ) == 1)
          {
            $gateType = PlateAuthorization::GATEID_TYPE_GATE;
            $gateID = $gateChunks [0];
          }
          else
          {
            $gateType = $gateChunks [0];
            $gateID = $gateChunks [1];
          }
          
          $model->insertid = Yii::app ()->user->id;
          $model->Descrizione = $_REQUEST ['p_description'];
          $model->GateID = $gateID;
          $model->GateID_type = $gateType;
          $model->TimeID = $_REQUEST ['p_time'];
          $model->type = $_REQUEST ['p_type'];
          $model->action = $_REQUEST ['p_action'];
          $model->Note = $_REQUEST ['p_note'];
          $model->epoch = DateHelper::formatISO9075DateTime ();
          
          if (Yii::app ()->user->checkAccess ( 'plate_auth_confirmed' ))
            $model->to_be_confirmed = 0;
          else
            $model->to_be_confirmed = 1;
          
          if (Yii::app ()->user->checkAccess ( 'plate_auth_enable' ))
            $model->enabled = 1;
          else
            $model->enabled = 0;
            
            // salvo e mostro flash error in caso di errore
          if (! $model->save ())
            Yii::app ()->user->setFlash ( 'error', Yii::t ( 'app', 'Unable to save validity period vehicle data.' ) );
          else
          {
            Yii::app ()->user->setFlash ( 'success', Yii::t ( 'app', 'Vehicle {plate} successfully saved in whitelist.', array (
                '{plate}' => $vehicle->Targa 
            ) ) );
            $this->redirect ( array (
                'view',
                'id' => $model->ID,
                'fromWizard' => true 
            ) );
            return;
          }
        }
        
        // renderizzo
        $model = new PlateAuthorization ();
        $model->list_code = $plateListId;
        $model->UserID = $ownerId;
        $model->AbbonamentoID = $validityPeriodId;
        $model->VehicleID = $vehicleId;
        
        $this->render ( 'whiteListWizard/step4', array (
            'auths' => $model->searchForWizard (),
            'plateListId' => $plateListId,
            'ownerId' => $ownerId,
            'vehicleId' => $vehicleId,
            'validityPeriodId' => $validityPeriodId,
            'objOwner' => $owner,
            'objVehicle' => $vehicle,
            'objPeriod' => $period,
            'objList' => $list,
            'context' => $context,
            'properties' => $properties,
            'what' => $_REQUEST ['p_description'] 
        ) );
      }
      // action ha un valore sbagliato
      else
        throw new CHttpException ( 404, 'The requested page does not exist.' );
    }
    else
      throw new CHttpException ( 404, 'The requested page does not exist.' );
  }

  public function actionDiagnostic($plateListId)
  {
    access_denied_check ( 'plate_auth_diagnostic' );
    
    $list = PlateList::findByCode ( $plateListId );
    if ($list === null)
      throw new CHttpException ( 404, 'The requested plate list does not exist.' );
    
    $messages = array ();
    $testRun = false;
    
    if (isset ( $_REQUEST [analyze] ))
    {
      $testRun = true;
      
      // SELECT wlt.id ,vt.id ,ut.id ,at.id ,gt.id ,tt.id ,wlt.list_code ,vt.list_code ,ut.list_code ,at.list_code FROM whitelisttable wlt LEFT JOIN abbonamentotable at ON wlt.abbonamentoid=at.id LEFT JOIN vehicletable vt ON wlt.vehicleid=vt.id LEFT JOIN usertable ut ON wlt.userid=ut.id LEFT JOIN gatetable gt ON wlt.gateid=gt.id LEFT JOIN timetable tt ON wlt.gateid=tt.id where vt.id is null or at.id is null or ut.id is null or gt.id is null or tt.id is null OR wlt.list_code<>vt.list_code OR wlt.list_code<>ut.list_code OR wlt.list_code<>at.list_code OR vt.list_code<>ut.list_code OR vt.list_code<>at.list_code OR ut.list_code<>at.list_code OR wlt.list_code is null OR vt.list_code is null OR ut.list_code is null OR at.list_code is null
      $cnt = query ( "SELECT count(*) as cnt FROM whitelisttable wlt LEFT JOIN abbonamentotable at ON wlt.abbonamentoid=at.id LEFT JOIN vehicletable vt ON wlt.vehicleid=vt.id LEFT JOIN usertable ut ON wlt.userid=ut.id LEFT JOIN gatetable gt ON wlt.gateid=gt.id LEFT JOIN timetable tt ON wlt.gateid=tt.id where vt.id is null or at.id is null or ut.id is null or gt.id is null or tt.id is null" )->cnt;
      
      $item = new CArray ();
      
      $item->type = "Bad Auth";
      $item->message = "Found $cnt inconsistent plate authorizations";
      
      $messages [] = $item;
    }
    
    $this->render ( 'diagnostic', array (
        'plateListId' => $plateListId,
        'messages' => $messages,
        'testRun' => $testRun 
    ) );
  }

  public function actionDeleteByVehicle($id, $keepNonSharedObjects = null)
  {
    $plateAuthorizations = PlateAuthorization::model ()->byVehicleID ( $id )
      ->findAll ();
    
    foreach ( $plateAuthorizations as $plateAuthorization )
      $this->loadModel ( $plateAuthorization->ID )
        ->delete ();
    
    if (! isset ( $_GET ['ajax'] ))
      $this->redirect ( isset ( $_POST ['returnUrl'] ) ? $_POST ['returnUrl'] : array (
          'admin' 
      ) );
  }

  /**
   *
   * @param unknown $id          
   * @throws CHttpException
   */
  public function actionDelete($id)
  {
    access_denied_check ( 'plate_auth_delete' );
    
    // we only allow deletion via POST request
    if (Yii::app ()->request->isPostRequest)
    {
      $this->loadModel ( $id )
        ->delete ();
      
      // if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser
      if (! isset ( $_GET ['ajax'] ))
        $this->redirect ( isset ( $_POST ['returnUrl'] ) ? $_POST ['returnUrl'] : array (
            'admin' 
        ) );
    }
    else
      throw new CHttpException ( 400, 'Invalid request. Please do not repeat this request again.' );
  }

  public function actionAddAuthorization()
  {
    $plateAuthorization = new NewPlateAuthorizationForm ();
    
    // var_dump($_POST);
    // var_dump($plateAuthorization);
    
    if (isset ( $_POST ['NewPlateAuthorizationForm'] ))
    {
      // $_POST['NewPlateAuthorizationForm']['startDateTime'] = DateHelper::composeDateTime($_POST['NewPlateAuthorizationForm']['startDateTime'], $_POST['hourStart'], $_POST['minuteStart']);
      
      $plateAuthorization->attributes = $_POST ['NewPlateAuthorizationForm'];
      
      // var_dump($plateAuthorization);
      
      if ($plateAuthorization->validate ())
        $this->render ( 'show', array (
            'data' => $data 
        ) );
      else
      {
        $gates = Gate::getAllGates ();
        $this->render ( 'new', array (
            'plateAuthorization' => $plateAuthorization,
            'gates' => $gates 
        ) );
      }
    }
    else
    {
      $gates = Gate::getAllGates ();
      $this->render ( 'new', array (
          'plateAuthorization' => $plateAuthorization,
          'gates' => $gates 
      ) );
    }
  }

  /**
   *
   * @param mixed $id          
   * @return PlateAuthorization
   *
   */
  public function loadModel($id)
  {
    $model = PlateAuthorization::model ()->findByPk ( $id );
    if ($model === null)
      throw new CHttpException ( 404, 'The requested page does not exist.' );
    return $model;
  }
  
  // Uncomment the following methods and override them if needed
  /*
   * public function filters()
   * {
   * // return the filter configuration for this controller, e.g.:
   * return array(
   * 'inlineFilterName',
   * array(
   * 'class'=>'path.to.FilterClass',
   * 'propertyName'=>'propertyValue',
   * ),
   * );
   * }
   *
   * public function actions()
   * {
   * // return external action classes, e.g.:
   * return array(
   * 'action1'=>'path.to.ActionClass',
   * 'action2'=>array(
   * 'class'=>'path.to.AnotherActionClass',
   * 'propertyName'=>'propertyValue',
   * ),
   * );
   * }
   */
  protected function getSuggestionsForWLT($field, $list_code = null)
  {
    $params = new CArray ( paramdeep ( 'plateAuthorizations', 'autocomplete', $field ) );
    // logObj(func_get_args());
    if ($params != null && $params->enabled)
    {
      $suggestions = array ();
      
      if ($params->table)
      {
        $query = "SELECT DISTINCT $field FROM whitelisttable WHERE ($field <> '' AND $field IS NOT NULL)";
        $queryParams = array ();
        if (! isEmpty ( $list_code ))
        {
          $query .= " AND (list_code=:list_code)";
          $queryParams [':list_code'] = $list_code;
        }
        foreach ( query ( $query, $queryParams, false, false ) as $comment )
        {
          $suggestions [] = $comment [$field];
        }
      }
      
      foreach ( $params->custom as $c )
      {
        $suggestions [] = $c;
      }
      
      $suggestions = array_remove_dup ( $suggestions );
      
      return $suggestions;
    }
    else
      return null;
  }

  protected function getSuggestionsJSForWLT($field, $list_code = null)
  {
    $items = $this->getSuggestionsForWLT ( $field, $list_code );
    if ($items == null)
      return null;
    return $this->addSuggestionsScript ( ".auto_$field", $items, true );
  }
}