<?php
/**
 * @copyright (c) Kufer Software GmbH, Oderstraße 7, D-84453 Mühldorf
 */



class DBWorkTeilnehmer extends DBWorkPersonen
{
  protected static $_cache_Teilnehmer = array();

  private $dbwTeilnehm2;

  public function __construct($pDBTyp = 1, $pNewInstance = false)
  {
    parent::__construct($pDBTyp, $pNewInstance);
    $this->dbkommoperations->perstyp = 'T';

    $this->select
            = 't.nr, t.guid, t.vorname, t.name, t.zusatz, t.zusatz2, t.zusatz3, t.ort, t.strasse, t.name_vorname, '
            . 't.pers_nr, t.anrede, t.suchbegriff, t.alterskl, t.firma_name, t.firma_ort, t.firma_tel, t.ansprache, '
            . 't.titel, t.gebdat, t.gebjahr, t.geburtsort, t.geschlecht, t.tel_anzeige, t.tel2_anzeige, t.fax_anzeige, '
            . 't.fax2_anzeige, t.mobil_anzeige, t.email_anzeige, t.last_erteilt, '
            . 't.zahlart, t.beruf, t.erm_grund, t.erm_proz, t.erm_ende, t.guthaben, t.bemerkung, t.info, t.info_intern, t.kinderbetr, '
            . 't.familienstand, t.rchg_adr_1, t.rchg_adr_2, t.rchg_adr_3, t.rchg_adr_4, t.rchg_adr_5, t.rchg_adr_6, '
            . 't.krit1, t.krit2, t.krit3, t.krit4, t.krit5, t.krit6, t.krit7, t.krit8, t.krit9, t.krit10, t.krit11, t.krit12, t.krit13, t.krit14, t.krit15, t.krit16, '
            . 't.sozarbeitgeber, bundesland, '
            . 't.kz_text, t.ausweisnr, t.mitgliednr, t.ausweisdat, t.arbamtnr, t.typ, t.bearbeiter, t.nation, t.staatsang, '
            . 't.nowerbung, t.verstorben, t.erstelltdatum, t.erstelltvon, t.eintritt, t.vip, t.konfession, t.krankenkasse, t.arbeit, t.ausbildung, t.sozposition, '
            . 't.krankenkassenr, t.name_titel, ' . $this->clob('t.dienstst') . ', t.zertifikat_druck_dat, t.wtmeldungam, t.wtemailam, '
            . 't.zertifikat_beauftragt_am, t.newsl_erlaubt, t.newsl_anlbearb, t.newsl_anldatum, t.newsl_erlart, t.abteilung, t.elearninguserid, t.elearninglogin, t.mitgl_bis, t.svnr, t.vorgesetztennr, '
            . 't.bearbdatum, t.ustid, ';

    $this->select .= $this->clob('t.newsl_bemerk') . ', ';
    $this->select .= $this->clob('t.info') . ', ';
    $this->select .= $this->clob('t.info_intern') . ', ';
    $this->select .= $this->clob('t.orgaeinh') . ', ';
    $this->select .= $this->dboperation->dbparser->cast2Text('bemerkung', 't', 'bemerkung') . ', ';
    $this->select .= $this->dboperation->dbparser->cast2Text('geburtsort', 't', 'geburtsort');

    $this->dbwTeilnehm2 = new DBWorkTeilnehmer2($this->dbtyp, true);
  }

  
  public function getNewObject()
  {
    $tmp = new Teilnehmer();

    return $this->getNewKommObjects($tmp);
  }

  public function getTableName(): string
  {
    return 'teilnehm t';
  }

  
  public function canupdate($varname)
  {
    switch ($varname) {
      default: return parent::canupdate($varname);
      case 'agb':
      case 'widerrufsbelehrung':
      case 'arykennzeichen':
      case 'ausbilderauswahl':
      case 'ausbildungsschablone':
      case 'ausbildung_ausbildungsschablone':
        
      case 'berufsgruppe':
      case 'berufsgruppe_html':
      case 'mandatam':
      case 'erm_grund_und_proz':
      case 'berufsgruppe_komma':
      case 'lms_ok':
      case 'firma':
      case 'arybranchen':
      case 'arybranchenJS':
      case 'arykennzeichenJS':
      case 'aryattachmentsJS':
      case 'uploadAttachments':
      case 'newsl_interessensgebiete':
      case 'keineDozenten': return false;
      case 'istanonym':
      case 'foto_1':
      case 'foto_2':
      case 'foto_3':
      case 'foto_4':
      case 'foto_5':
      case 'foto_6':
      case 'newsl_email':
        return false;

        
      case 'dse_unterschrieben_datum':
      case 'dse_unterschrieben_bearbeiter':
      case 'dse_unterschrieben_weg':
      case 'dse_widerrufen_datum':
      case 'dse_widerrufen_bearbeiter':
      case 'dse_widerrufen_weg':
      case 'acceptdat_tnb':
      case 'email_2':
      case 'mysqlid':
      case 'schul_nr':
      case 'zustimmung_hygiene':
      case 'zustimmung_indiv':
      case 'zustimmung_fuehrung':
      case 'kommprio':
      case 'dioezese':
      case 'nicht_auf_dioezesanliste':
      case 'ausbildungvon':
      case 'ausbildungbis':
        return false;
    }
  }

  public function canupdateDmz($pVarname): bool
  {
    switch ($pVarname) {
      case 'zustimmung_hygiene':
      case 'zustimmung_indiv':
      case 'zustimmung_fuehrung':
      case 'kommprio':
      case 'ausbildungvon':
      case 'ausbildungbis':
      case 'ausbildungsschablone':
        return true; 
    }

    return $this->canupdate($pVarname) || $this->dbwTeilnehm2->canupdate($pVarname);
  }

  
  public function getCurrentRow($pRefreshCache = false)
  {
    $tmp = $this->getNewObject();
    $tmp->id = $this->getDatamodulValue('nr');
    $tmp->guid = $this->getDatamodulValue('guid');
    $tmp->vorname = $this->getDatamodulValue('vorname');
    $tmp->name = $this->getDatamodulValue('name');
    $tmp->zusatz = $this->getDatamodulValue('zusatz');
    $tmp->zusatz2 = $this->getDatamodulValue('zusatz2');
    $tmp->zusatz3 = $this->getDatamodulValue('zusatz3');
    $tmp->ort = $this->getDatamodulValue('ort');
    $tmp->strasse = $this->getDatamodulValue('strasse');
    $tmp->namevorname = $this->getDatamodulValue('name')
                        . ($this->getDatamodulValue('vorname') != '' ? ', ' . $this->getDatamodulValue('vorname') : '');
    $tmp->name_vorname = $this->getDatamodulValue('name_vorname');
    $tmp->pers_nr = $this->getDatamodulValue('pers_nr');
    $tmp->anrede = $this->getDatamodulValue('anrede');
    $tmp->suchbegriff = $this->getDatamodulValue('suchbegriff');
    $tmp->alterskl = $this->getDatamodulValue('alterskl');
    $tmp->firma_name = $this->getDatamodulValue('firma_name');
    $tmp->firma_ort = $this->getDatamodulValue('firma_ort');
    $tmp->firma_tel = $this->getDatamodulValue('firma_tel');
    $tmp->ansprache = $this->getDatamodulValue('ansprache');
    $tmp->titel = $this->getDatamodulValue('titel');
    $tmp->gebdat = $this->getDatamodulValue('gebdat');
    $tmp->gebjahr = $this->getDatamodulValue('gebjahr');
    $tmp->geburtsort = $this->getDatamodulValue('geburtsort');
    $tmp->geschlecht = $this->getDatamodulValue('geschlecht');
    $tmp->last_erteilt = $this->getDatamodulValue('last_erteilt');
    $tmp->zahlart = $this->getDatamodulValue('zahlart');
    $tmp->beruf = $this->getDatamodulValue('beruf');
    $tmp->erm_grund = $this->getDatamodulValue('erm_grund');
    $tmp->erm_proz = $this->getDatamodulValue('erm_proz');
    $tmp->erm_ende = $this->getDatamodulValue('erm_ende');
    $tmp->guthaben = $this->getDatamodulValue('guthaben');
    $tmp->bemerkung = $this->getDatamodulValue('bemerkung');
    $tmp->info = $this->getDatamodulValue('info');
    $tmp->info_intern = $this->getDatamodulValue('info_intern');
    $tmp->kinderbetr = $this->getDatamodulValue('kinderbetr');
    $tmp->familienstand = $this->getDatamodulValue('familienstand');
    $tmp->rechadr1 = $this->getDatamodulValue('rchg_adr_1');
    $tmp->rechadr2 = $this->getDatamodulValue('rchg_adr_2');
    $tmp->rechadr3 = $this->getDatamodulValue('rchg_adr_3');
    $tmp->rechadr4 = $this->getDatamodulValue('rchg_adr_4');
    $tmp->rechadr5 = $this->getDatamodulValue('rchg_adr_5');
    $tmp->rechadr6 = $this->getDatamodulValue('rchg_adr_6');
    $tmp->kz_text = $this->getDatamodulValue('kz_text');
    $tmp->ausweisnr = $this->getDatamodulValue('ausweisnr');
    $tmp->mitgliednr = $this->getDatamodulValue('mitgliednr');
    $tmp->ausweisdat = $this->getDatamodulValue('ausweisdat');
    $tmp->arbamtnr = $this->getDatamodulValue('arbamtnr');

    $tmp->typ = $this->getDatamodulValue('typ');
    $tmp->bearbeiter = $this->getDatamodulValue('bearbeiter');
    $tmp->bearbdatum = $this->getDatamodulValue('bearbdatum');
    $tmp->nation = $this->getDatamodulValue('nation');
    $tmp->staatsang = $this->getDatamodulValue('staatsang');
    $tmp->nowerbung = $this->getDatamodulValue('nowerbung');
    $tmp->verstorben = $this->getDatamodulValue('verstorben');
    $tmp->erstelltdatum = $this->getDatamodulValue('erstelltdatum');
    $tmp->erstelltvon = $this->getDatamodulValue('erstelltvon');
    $tmp->eintritt = $this->getDatamodulValue('eintritt');
    $tmp->vip = $this->getDatamodulValue('vip');
    $tmp->konfession = $this->getDatamodulValue('konfession');
    $tmp->krankenkasse = $this->getDatamodulValue('krankenkasse');
    $tmp->krankenkassenr = $this->getDatamodulValue('krankenkassenr');
    $tmp->name_titel = $this->getDatamodulValue('name_titel');
    $tmp->dienstst = $this->getDatamodulValue('dienstst');
    $tmp->zertifikat_druck_dat = $this->getDatamodulValue('zertifikat_druck_dat');
    $tmp->wtmeldungam = $this->getDatamodulValue('wtmeldungam');
    $tmp->wtemailam = $this->getDatamodulValue('wtemailam');
    $tmp->zertifikat_beauftragt_am = $this->getDatamodulValue('zertifikat_beauftragt_am');
    $tmp->ausbildung = $this->getDatamodulValue('ausbildung');
    $tmp->orgaeinh = $this->getDatamodulValue('orgaeinh');
    $tmp->abteilung = $this->getDatamodulValue('abteilung');

    $tmp->newsl_erlaubt = $this->getDatamodulValue('newsl_erlaubt');
    $tmp->newsl_bemerk = $this->getDatamodulValue('newsl_bemerk');
    $tmp->newsl_anlbearb = $this->getDatamodulValue('newsl_anlbearb');
    $tmp->newsl_anldatum = $this->getDatamodulValue('newsl_anldatum');
    $tmp->newsl_erlart = $this->getDatamodulValue('newsl_erlart');

    
    $tmp->tel_anzeige = $this->getDatamodulValue('tel_anzeige');
    $tmp->tel2_anzeige = $this->getDatamodulValue('tel2_anzeige');
    $tmp->fax_anzeige = $this->getDatamodulValue('fax_anzeige');
    $tmp->fax2_anzeige = $this->getDatamodulValue('fax2_anzeige');
    $tmp->mobil_anzeige = $this->getDatamodulValue('mobil_anzeige');
    $tmp->email_anzeige = $this->getDatamodulValue('email_anzeige');
    $tmp->elearninguserid = $this->getDatamodulValue('elearninguserid');
    $tmp->elearninglogin = $this->getDatamodulValue('elearninglogin');
    for ($i = 1; $i <= 16; $i++) {
      $fieldname = 'krit' . $i;
      $tmp->{$fieldname} = $this->getDatamodulValue('krit' . $i);
    }
    $tmp->sozarbeitgeber = $this->getDatamodulValue('sozarbeitgeber');
    $tmp->bundesland = $this->getDatamodulValue('bundesland');

    $tmp->mitgl_bis = $this->getDatamodulValue('mitgl_bis');
    $tmp->svnr = $this->getDatamodulValue('svnr');
    $tmp->vorgesetztennr = $this->getDatamodulValue('vorgesetztennr');
    $tmp->ustid = $this->getDatamodulValue('ustid');

    
    return $tmp;
  }

  
  protected function postGetAllRowsHook($pDatamodules, $pRefreshCache = false)
  {
    $datamodule = parent::postGetAllRowsHook($pDatamodules, $pRefreshCache);
    $datamodule = $this->setNewsletterInteressensgebieteToTeilnehmer($datamodule);
    $datamodule = $this->fillBankData2Persons($datamodule, $pRefreshCache);
    $tnrs = ArrayOperations::mapAttribut($datamodule, 'id');
    
    $datamodule = $this->dbwTeilnehm2->getByIds($tnrs, $datamodule, $pRefreshCache);

    return $this->fillKommBlock2Personen($datamodule, $pRefreshCache);
  }

  
  private function setNewsletterInteressensgebieteToTeilnehmer($datamodule)
  {
    $dbwNewslFb = new \DBWorkNewsletterFb(1, true);
    foreach ($datamodule as $datamodul) {
      $datamodul->newsl_interessensgebiete = $dbwNewslFb->getInteressensgebieteForNrUndTyp($datamodul->id, 'T');
    }

    return $datamodule;
  }

  
  public function getSearchSQL($pPraeffix)
  {
    $praeffix = $this->dboperation->getString4Sql($pPraeffix);
    
    $sql = '';
    if ((isset($this->fromobject)) and (isset($this->toobject))) {
      
      if ((trim($this->fromobject->name) != '') && (trim($this->toobject->name) != '')) {
        $sql .= ' AND ' . $this->dboperation->dbparser->caseInsensitiveCompOperation('>=', $praeffix, 'name', $this->fromobject->name) . " \n ";
        $sql .= ' AND ' . $this->dboperation->dbparser->caseInsensitiveCompOperation('<=', $praeffix, 'name', $this->toobject->name) . " \n ";
      } elseif (trim($this->fromobject->name) != '') {
        $sql .= ' AND ' . $this->dboperation->dbparser->caseInsensitiveLike($praeffix, 'name', $this->fromobject->name . '%') . " \n ";
      }
      if (trim($this->fromobject->vorname) != '') {
        $sql .= ' AND ' . $this->dboperation->dbparser->caseInsensitiveLike(
          $praeffix,
          'vorname',
          $this->fromobject->vorname . '%'
        ) . " \n ";
      }

      if (trim($this->fromobject->id) != '') {
        $sql .= ' AND ' . $praeffix . "nr LIKE '" . $this->fromobject->id . "' \n ";
      }
      if (trim($this->fromobject->pers_nr) != '') {
        $sql .= ' AND ' . $praeffix . "pers_nr LIKE '"
                . $this->fromobject->pers_nr . "%' \n ";
      }
      
      if (trim($this->fromobject->ausweisnr) != '') {
        $sql .= ' AND ' . $this->dboperation->dbparser->caseInsensitiveLike(
          $praeffix,
          'ausweisnr',
          $this->fromobject->ausweisnr . '%'
        ) . " \n";
      }
      
      if (trim($this->fromobject->ort) != '') {
        $sql .= ' AND ' . $this->dboperation->dbparser->caseInsensitiveLike(
          $praeffix,
          'ort',
          '%' . $this->fromobject->ort . '%'
        ) . " \n";
      }
      
      if (trim($this->fromobject->strasse != '')) {
        $sql .= ' AND ' . $this->dboperation->dbparser->caseInsensitiveLike(
          $praeffix,
          'strasse',
          $this->fromobject->strasse . '%'
        ) . " \n";
      }
      
      if (trim($this->fromobject->zusatz != '')) {
        $sql .= ' AND ' . $this->dboperation->dbparser->caseInsensitiveLike(
          $praeffix,
          'zusatz',
          $this->fromobject->zusatz . '%'
        ) . " \n";
      }

      if (!empty($this->fromobject->idary)) {
        $idary = $this->dboperation->getInts4Sql($this->fromobject->idary);
        $sql .= ' AND ' . $praeffix . 'nr IN (' . \StringOperations::convertArray2InList($idary) . ") \n";
      }

      if (!empty($this->toobject->idary)) {
        $idary = $this->dboperation->getInts4Sql($this->toobject->idary);
        $sql .= ' AND ' . $praeffix . 'nr NOT IN (' . \StringOperations::convertArray2InList($idary) . ") \n";
      }

      if (isset($this->fromobject->suche_kennzeichen)) {
        $kennzeichen = $this->dboperation->getStrings4Sql($this->fromobject->suche_kennzeichen);
        if (is_array($kennzeichen)) {
          $sql .= ' AND nr in (SELECT nr FROM kennz_ad WHERE kennz IN (' . $this->stringop->convertArray2InList($kennzeichen) . ') )';
        } else {
          $sql .= ' AND nr in (SELECT nr FROM kennz_ad WHERE kennz IN (' . ($kennzeichen) . ') )';
        }
      }
    }

    return $sql;
  }

  
  public function getSQLValue($fieldname, $datamodul)
  {
    
    if ($fieldname == 'suchbegriff') {
      return "'" . stripslashes(strtr(StringOperations::substr($datamodul->getVarValue($fieldname), 0, 16), "'", '`')) . "'";
    }

    return parent::getSQLValue($fieldname, $datamodul);
  }

  
  public function translateVarName($varname)
  {
    switch ($varname) {
      default:             return DBWorkPersonen::translateVarName($varname);
      case 'kontoinhaber': return 'kontoname';
      case 'rechadr1':     return 'rchg_adr_1';
      case 'rechadr2':     return 'rchg_adr_2';
      case 'rechadr3':     return 'rchg_adr_3';
      case 'rechadr4':     return 'rchg_adr_4';
      case 'rechadr5':     return 'rchg_adr_5';
      case 'rechadr6':     return 'rchg_adr_6';
      case 'nowerbbemerk': return 'nopostwerb_bem';
      case 'nowerbbearbeiter': return 'nopostwerb_bearb';
      case 'nowerbdatum':  return 'nopostwerb_datum';
      case 'nowerbvia':  return 'nopostwerb_via';
      case 'notelwerbungbemerk': return 'notelwerb_bem';
      case 'notelwerbungbearbeiter': return 'notelwerb_bearb';
      case 'notelwerbungdatum':  return 'notelwerb_datum';
      case 'notelwerbungvia':  return 'notelwerb_via';
      case 'notelwerbung':    return 'notelwerb';
      case 'nomailwerbungbemerk': return 'nomailwerb_bem';
      case 'nomailwerbungbearbeiter': return 'nomailwerb_bearb';
      case 'nomailwerbungdatum':  return 'nomailwerb_datum';
      case 'nomailwerbungvia':  return 'nomailwerb_via';
      case 'nomailwerbung': return 'nomailwerb';
    }

    
  }

  public function getOnlyIds($dbwFunction, $params)
  {
    $select = $this->select;
    $this->select = 't.nr';
    $kurstage = call_user_func_array($dbwFunction, $params);
    $this->select = $select;

    return ArrayOperations::mapAttribut($kurstage, 'id');
  }

  
  public function getTeilnehmer()
  {
    $this->dboperation->clear();
    $this->dboperation->query('SELECT ' . $this->select . ' FROM teilnehm t WHERE 1=1 ' . $this->getSearchSQL('t.') . ' ORDER BY t.name, t.vorname');

    return $this->getAllRows();
  }

  
  public function getTeilnehmerQuery($praeffix = 't'): \SelectQueryBuilder
  {
    $builder = $this->getSelectQueryBuilder();

    return $builder->select($this->select)
                       ->from('teilnehm', $praeffix)
                       ->orderByAsc($praeffix . '.name')
                       ->orderByAsc($praeffix . '.vorname');
  }

  
  public function addFilterToQuery($builder, $praeffix = 't'): \SelectQueryBuilder
  {
    if ($builder->getCondition() === '') {
      $builder = $builder->and('1=1');
    }

    return $builder->addToWhere($this->getSearchSQL($praeffix . '.'));
  }

  
  public function getTeilnehm($pTeilnehmer_Id, $pRefreshCache = false)
  {
    if ((!is_numeric($pTeilnehmer_Id) && !($pTeilnehmer_Id instanceof \Kufer\Web\Classes\Identifier\Identifier)) || $pTeilnehmer_Id === -1) {
      return $this->getNewObject();
    }

    $pTeilnehmer_Id = \Kufer\Web\Classes\Identifier\IdentifierFactory::createFromIdIfNecessary($pTeilnehmer_Id);
    if ($pRefreshCache || !array_key_exists($pTeilnehmer_Id->getId(), self::$_cache_Teilnehmer)) {
      $builder = $this->getAllQuery()
        ->and(':tnr:')
        ->paramId('tnr', $pTeilnehmer_Id, 't.nr', 't.guid');
      $this->dboperation->clear();
      $this->dboperation->query($builder->getSQL());
      self::$_cache_Teilnehmer[$pTeilnehmer_Id->getId()] = $this->getFirstRow($pRefreshCache);
    }

    
    return unserialize(serialize(self::$_cache_Teilnehmer[$pTeilnehmer_Id->getId()]));
  }

  
  public function getTeilnehmerPauschalNeutral()
  {
    $this->dboperation->clear();
    $this->dboperation->query('SELECT ' . $this->select . ' FROM teilnehm t WHERE t.name = \'TN N\'');

    return $this->getFirstRow();
  }

  
  public function getTeilnehmerPauschalMaennlich()
  {
    $this->dboperation->clear();
    $this->dboperation->query('SELECT ' . $this->select . ' FROM teilnehm t WHERE t.name = \'TN M\'');

    return $this->getFirstRow();
  }

  
  public function getTeilnehmerPauschalWeiblich()
  {
    $this->dboperation->clear();
    $this->dboperation->query('SELECT ' . $this->select . ' FROM teilnehm t WHERE t.name = \'TN W\'');

    return $this->getFirstRow();
  }

  
  public function getTeilnehmByIdArray($pTeilnehmerNummern, $pRefreshCache = false)
  {
    if (!is_array($pTeilnehmerNummern) || empty($pTeilnehmerNummern)) {
      return array();
    }

    $pTeilnehmerNummern = \Kufer\Web\Classes\Identifier\IdentifierFactory::createFromIdsIfNecessary($pTeilnehmerNummern);

    static $cache = array();

    $retour = array();
    
    $tosearch = array();
    
    $tnrsInCache = array();
    foreach ($pTeilnehmerNummern as $ptnr) {
      if (!$pRefreshCache && isset($cache[$ptnr->getCacheKey()])) {
        
        $tnrsInCache[] = $ptnr;
      } else {
        $tosearch[] = $ptnr;
      }
    }

    if (empty($tosearch)) {
      foreach ($tnrsInCache as $tnr) {
        $retour[$tnr->getId()] = $cache[$tnr->getCacheKey()];
      }

      return $retour;
    }

    
    $builder = $this->getAllQuery()
      ->and(':idCondition:')
      ->paramIdArray('idCondition', $tosearch, 't.nr', 't.guid');

    $this->dboperation->clear();
    $this->dboperation->query($builder->getSQLForInnerQuery()); 
    $dbresult = $this->getAllRows(true);
    if (!is_null($dbresult)) {
      foreach ($dbresult as $tn) {
        $cache[$tn->getIdentifier()->getCacheKey()] = $tn;
      }

      foreach ($pTeilnehmerNummern as $tnr) {
        
        $retour[] = $cache[$tnr->getCacheKey()];
      }
    }

    return $retour;
  }

  
  public function getTeilnehmByIdArrayWithOrdering($pTeilnehmerNummern)
  {
    if (!is_array($pTeilnehmerNummern) || count($pTeilnehmerNummern) == 0) {
      return array();
    }

    $query = $this->getSelectQueryBuilder();
    $query->select($this->select)
          ->from('teilnehm', 't')
          ->where('t.nr IN (:tnrs:)')
          ->addToWhere($this->getCompleteOrderByDefault('name', 't'))
          ->paramIntArray('tnrs', $pTeilnehmerNummern);

    $this->dboperation->clear();
    $this->dboperation->query($query->getSQL());

    return $this->getAllRows();
  }

  public function getAllQuery(): \SelectQueryBuilder
  {
    return $this->getSelectQueryBuilder()
      ->select($this->select)
      ->from('teilnehm', 't')
      ->orderBySrcCode($this->getCompleteOrderByDefault('name', 't'))
      ->paramRaw('table', 't');
  }

  
  public function getTeilnehmByIdArrayAndFilter($pTeilnehmerNummern)
  {
    if (!is_array($pTeilnehmerNummern) || count($pTeilnehmerNummern) == 0) {
      return array();
    }

    $tosearch = array();
    foreach ($pTeilnehmerNummern as $ptnr) {
      $tosearch[] = $this->dboperation->getInt4Sql($ptnr);
    }

    $sql = 'SELECT ' . $this->select . ' FROM teilnehm t where t.nr in (' . StringOperations::convertArray2InList($tosearch) . ') ' . $this->getSearchSQL('t.');

    $this->dboperation->clear();
    $this->dboperation->query($sql);

    return $this->getAllRows();
  }

  public function getTeilnehmByBelegung($pBelegID, $pRefreshCache = false)
  {
    $belegID = $this->dboperation->getInt4Sql($pBelegID);
    if ($pRefreshCache || !array_key_exists($belegID, self::$_cache_Teilnehmer)) {
      $sql = 'SELECT ' . $this->select . ' FROM teilnehm t left join belegung b on t.nr=b.tnr WHERE b.id=' . $belegID;
      $this->dboperation->clear();
      $this->dboperation->query($sql);
      self::$_cache_Teilnehmer[$belegID] = $this->getFirstRow($pRefreshCache);
    }
    
    return unserialize(serialize(self::$_cache_Teilnehmer[$belegID]));
  }

  
  public function getTeilnehmerByBelegAry($pBelegIds)
  {
    if (empty($pBelegIds)) {
      return array();
    }
    $cleanBelegIds = array_map(array($this->dboperation, 'getInt4Sql'), $pBelegIds);
    $inList = trim(implode(',', $cleanBelegIds), ',');
    $sql = 'SELECT ' . $this->select . ' FROM teilnehm t left join belegung b on t.nr=b.tnr WHERE b.id IN (' . $inList . ')';
    $this->dboperation->clear();
    $this->dboperation->query($sql);

    return $this->getAllRows();
  }

  
  public function getTeilnehmerByELearningId($pEid)
  {
    $eId = $this->dboperation->getInt4Sql($pEid);
    $sql = 'SELECT ' . $this->select . ' FROM teilnehm t WHERE t.elearninguserid=' . $eId;
    $this->dboperation->clear();
    $this->dboperation->query($sql);

    return $this->getFirstRow();
  }

  
  public function getTeilnehmerIDsByVorgesetztenNr($pTnr)
  {
    $tnr = $this->dboperation->getInt4Sql($pTnr);
    $sql = 'SELECT t.nr FROM teilnehm t WHERE t.vorgesetztennr=' . $tnr . "\n"
           . $this->getSearchSQL('t.') . ' ' . $this->getCompleteOrderByDefault('name', 't');

    $this->dboperation->clear();
    $this->dboperation->query($sql);

    return $this->getAllRowsSingleColumn('nr');
  }

  

  
  public function updateTeilnehmer($pTeilnehmer, $pNoProtocol = false, $pOrigTN = null, $pIsKommUpdNeeded = false)
  {
    $pTeilnehmer->updateKommAnzeige();
    if (!empty($pOrigTN)) {
      $orgtn = $pOrigTN;
    } else {
      $orgtn = $this->getTeilnehm($pTeilnehmer->id, true);
    }
    $pTeilnehmer = $this->fillCalculatedFields($orgtn, $pTeilnehmer);

    if (is_null($pTeilnehmer->guid)) {
      $pTeilnehmer->guid = $orgtn->guid;
    }

    $this->updateObject($pTeilnehmer, $orgtn, 'teilnehm', 'id', 'U', false, $pNoProtocol);
    
    if ($pIsKommUpdNeeded) {
      $this->updateKommBlock($pTeilnehmer, $pNoProtocol);
    }
    $this->setActionIDs();

    $this->dbwTeilnehm2->insertOrUpdateTeilnehm2($pTeilnehmer, $pNoProtocol);
  }

  

  
  public function insertTeilnehmer($teilnehmer, $pDontProtocol = false, $pIsKommInsNeeded = false, $pInsertMoreThanNr = true)
  {
    if (empty($teilnehmer->guid) || $teilnehmer->guid->isEmpty()) {
      $teilnehmer->guid = $this->generateUniqueGuid();
    }

    $teilnehmer = TeilnehmerAPI::fuelleSonstigeTeilnehmerDaten($teilnehmer, $this->dbtyp);
    $datamodulfields = $pInsertMoreThanNr ? $teilnehmer->getAttributeNames() : array('nr', 'guid');
    $dbInserter = new DBInserterMitGenTable($this, explode(' ', $this->getTableName())[0], $datamodulfields);
    $teilnehmer->id = $dbInserter->insert($teilnehmer, 'nr', $pDontProtocol);

    if ($pInsertMoreThanNr && $pIsKommInsNeeded) {
      $this->insertKommBlock($teilnehmer, $pDontProtocol);
    }
    $this->setActionIDs();

    $this->dbwTeilnehm2->insertOrUpdateTeilnehm2($teilnehmer, $pDontProtocol);

    return $teilnehmer->id;
  }

  
  public function hasTeilnehmerKurs($pTnr, $pKnr)
  {
    $tnId = \Kufer\Web\Classes\Identifier\IdentifierFactory::createFromIdIfNecessary($pTnr);
    $filter = \Kufer\Web\Classes\Dbfilter\BelegungenSQLFilter::create();
    $filter
      ->equalsKursnummer($pKnr)
      ->equalsTeilnehmerId((int)$tnId->getId());

    return \DBWorkBelegung::getDefaultInstance()->countByFilter($filter) > 0;
  }

  
  public function hasTeilnehmerAnmgemeldetKurs($pTnr, $pKnr)
  {
    $tnId = \Kufer\Web\Classes\Identifier\IdentifierFactory::createFromIdIfNecessary($pTnr);
    $filter = \Kufer\Web\Classes\Dbfilter\BelegungenSQLFilter::create();
    $filter
      ->equalsKursnummer($pKnr)
      ->equalsTeilnehmerId((int)$tnId->getId())
      ->inStatus(array('', ' ', 'A', 'T'));

    return \DBWorkBelegung::getDefaultInstance()->countByFilter($filter) > 0;
  }

  
  public function hasFirmaTeilnehmerAnmgemeldetKurs($pTnr, $pKnr)
  {
    $tnId = \Kufer\Web\Classes\Identifier\IdentifierFactory::createFromIdIfNecessary($pTnr);
    $filter = \Kufer\Web\Classes\Dbfilter\BelegungenSQLFilter::create();
    $filter
      ->equalsKursnummer($pKnr)
      ->equalsFirmaId((int)$tnId->getId())
      ->inStatus(array('', ' ', 'A', 'T'));

    return \DBWorkBelegung::getDefaultInstance()->countByFilter($filter) > 0;
  }

  
  public function getWebUsersQuery()
  {
    return $this->getSelectQueryBuilder()
        ->select($this->select)
        ->from('teilnehm', 't')
        ->innerJoin('web_users wu', 't.nr = wu.tnr');
  }

  
  public function hasLogin($pTnr)
  {
    $builder = $this->getWebUsersQuery()
        ->select('t.nr')
        ->and('t.nr = :tnr:')
        ->paramInt('tnr', $pTnr);

    $this->dboperation->clear();
    $this->dboperation->query($builder->getSQL());

    return ($this->dboperation->rowcount() > 0);
  }

  
  public function getMitarbeiterByBeziehungsTable4MDS($pFirmaTnr, $pRefreshCache = false)
  {
    
    
    return $this->getTeilnehmerByBeziehungsIdAndNr($pFirmaTnr, 4, true, $pRefreshCache);
  }

  
  public function getTeilnehmerByBeziehungsIdAndNr($pTnr, $pBezId, $pIsSelectKey1 = true, $pRefreshCache = false)
  {
    $tnr = $this->dboperation->getInt4Sql($pTnr);
    $bezid = $this->dboperation->getInt4Sql($pBezId);
    
    $nr1 = $pIsSelectKey1 ? 'nr1' : 'nr2';
    $nr2 = $pIsSelectKey1 ? 'nr2' : 'nr1';

    if ($tnr == 0) {
      return array();
    }

    $cacheKey = "$tnr#$bezid";
    static $cache = array();
    if (!$pRefreshCache && isset($cache[$cacheKey])) {
      return $cache[$cacheKey];
    }
    $sql = "select $nr1 from beziehung where $nr2=$tnr and typ1='T' and typ2='T' and bezid=$bezid";

    $this->dboperation->clear();
    $this->dboperation->query($sql);
    $rowCount = $this->dboperation->rowcount();
    if ($rowCount == 0) {
      $cache[$cacheKey] = array();

      return $cache[$cacheKey];
    } else {
      $ids = $this->getAllRowsSingleColumn($nr1);
      $sql = 'SELECT * FROM teilnehm WHERE nr IN (' . implode(',', $ids) . ') ORDER BY name';
      $this->dboperation->clear();
      $this->dboperation->query($sql);

      $cache[$cacheKey] = $this->getAllRows();

      return $cache[$cacheKey];
    }
  }

  
  public function getKinderAnhandBeziehung($pTnr)
  {
    $dbwBeziehung = new DBWorkBeziehung();

    $query = $dbwBeziehung->getSQLQuery4ArtZwischenTeilnehmern(2);
    $query->select('bz.nr2')
          ->addToWhere('AND bz.nr1 = :tnrElternteil:')
          ->paramInt('tnrElternteil', $pTnr);

    
    $sql = 'SELECT ' . $this->select . ' FROM teilnehm t WHERE t.nr IN(' . $query->getSQL() . ') ORDER BY name, vorname';

    $this->dboperation->clear();
    $this->dboperation->query($sql);

    return $this->getAllRows(true);
  }

  
  public function getTeilnehmerByFirmaKurs($pFirmaTnr, $pKursNr = '', $pRefreshCache = false, $pNurStatus = '')
  {
    $firmaTnr = $this->dboperation->getInt4Sql($pFirmaTnr);
    $kursNr = $this->dboperation->getString4Sql($pKursNr);

    if ($firmaTnr == 0) {
      return array();
    }

    $cacheKey = $firmaTnr . '#' . $kursNr . '#' . $pNurStatus;
    static $cache = array();
    if (isset($cache[$cacheKey]) && !$pRefreshCache) {
      return $cache[$cacheKey];
    }

    $tnrs = $this->getTnrByFirmaKurs($firmaTnr, $kursNr, $pNurStatus);

    if (count($tnrs) > 0) {
      $sql = 'SELECT ' . $this->select . ' FROM teilnehm t WHERE t.nr IN(' . implode(',', $tnrs) . ') ';
      $sql .= $this->getSearchSQL('t.');
      $sql .= ' ORDER BY ' . $this->dboperation->dbparser->orderby(
        $this->translateVarName($this->getOrderbyDefault('name, vorname')),
        $this->getInvertAsc('ASC')
      );

      $this->dboperation->clear();
      $this->dboperation->query($sql);
      $cache[$cacheKey] = $this->getAllRows();
    } else {
      $cache[$cacheKey] = array();
    }

    return $cache[$cacheKey];
  }

  
  private function getTnrByFirmaKurs($firmaTnr, $kursNr, $pNurStatus)
  {
    $sql = 'SELECT b.tnr FROM belegung b WHERE b.firma = ' . $firmaTnr;
    if (!empty($kursNr)) {
      $sql .= ' AND b.knr = \'' . $kursNr . '\'';
    }

    if (!empty($pNurStatus)) {
      $sql .= ' AND b.status_1 in (' . $pNurStatus . ')';
    }

    $this->dboperation->clear();
    $this->dboperation->query($sql);

    return $this->getAllRowsSingleColumn('tnr');
  }

  
  public function getTeilnehmerByFirmaBeziehung($pFirmaTnr, bool $mitarbeiterAnhandBeziehungIgnoreBegin = false, bool $inAusbildungBeiAusbildungsschablone = false, bool $pRefreshCache = false)
  {
    $firmaTnr = $this->dboperation->getInt4Sql($pFirmaTnr);

    if ($firmaTnr == 0) {
      return array();
    }

    $cacheKey = $firmaTnr;
    static $cache = array();
    if (isset($cache[$cacheKey]) && !$pRefreshCache) {
      return $cache[$cacheKey];
    }

    $dbwBeziehung = new DBWorkBeziehung(1, true);
    $mitarbeiterTnr = $dbwBeziehung->getMitarbeiterTnrZuFirma($firmaTnr, $mitarbeiterAnhandBeziehungIgnoreBegin);

    if (count($mitarbeiterTnr) == 0) {
      $cache[$cacheKey] = array();

      return $cache[$cacheKey];
    }

    $query = $this->getSelectQueryBuilder();
    $query->select($this->select)
          ->from('teilnehm', 't')
          ->leftOuterJoin('teilnehm2 t2', 't.nr = t2.nr')
          ->and('t.nr IN (:tnrs:)')
          ->addToWhere($this->getSearchSQL('t.'))
          ->paramIntArray('tnrs', $mitarbeiterTnr);

    if ($inAusbildungBeiAusbildungsschablone) {
      $query = $query->andExpr(static function(\SelectQueryBuilder $builder): \SelectQueryBuilder {
        return $builder
          ->or(':ifnull(t2.ausbildungsschablone, 0): = 0')
          ->or(':isdefaultdate(t2.ausbildungbis):')
          ->or('t2.ausbildungbis >= :datenow:');
      });
    }

    
    $sql = $query->getSQL();
    $sql .= ' ORDER BY ' . $this->dboperation->dbparser->orderby(
      $this->translateVarName($this->getOrderbyDefault('name, vorname')),
      $this->getInvertAsc('ASC')
    );

    $this->dboperation->clear();
    $this->dboperation->query($sql);
    $cache[$cacheKey] = $this->getAllRows();

    return $cache[$cacheKey];
  }

  
  public function getTeilnehmerPunkte4KurseBlak($pTnr, $pLastDate, $pStatus4Confirm, $pRefreshCache = false)
  {
    $cacheKey = "$pTnr#$pLastDate#$pStatus4Confirm";
    static $cache = array();
    if (!$pRefreshCache && isset($cache[$cacheKey])) {
      return $cache[$cacheKey];
    }

    $sql = 'SELECT sum(CASE ' . $this->dboperation->dbparser->isNull('b.punkte', '0') . ' '
           . ' WHEN 0 THEN k.punkte ELSE b.punkte END) as resultierendePunkte ';
    $sql .= $this->getBlakKennzStatementPart($pTnr, $pLastDate, $pStatus4Confirm);
    $this->dboperation->clear();
    $this->dboperation->query($sql);
    $this->dboperation->selectrow(0);
    $cache[$cacheKey] = $this->getDatamodulValue('resultierendePunkte');

    return $cache[$cacheKey];
  }

  
  public function getBlakKennzStatementPart($pTnr, $pLastDate, $pStatus4Confirm)
  {
    $tnr = $this->dboperation->getInt4Sql($pTnr);
    if ($pStatus4Confirm) {
      $statusPart4Punkte = " = 'W'";
    } else {
      $statusPart4Punkte = ' not in (\'W\',\'F\')';
    }

    $lastDateSql = $this->datetimeop->getFormatDate4Server($pLastDate);
    $defaultDatum = $this->datetimeop->getFormatDate4Server(DEFAULTDATE);

    $sql = ' from belegung b join kurse k on k.nr = b.knr where b.tnr=' . $tnr . ' '
           . ' and (select min(kennztn.kennz) from kennz_ad kennztn where kennztn.typ = \'T\' and '
           . ' kennztn.kennz in (' . StringOperations::convertArray2InList(ConstantOperations::getBlakBerufsgruppenKennz()) . ') and '
           . ' kennztn.nr = b.tnr) in (select kennzk.kennz from kennz_ad kennzk where kennzk.typ = \'K\' and '
           . ' kennzk.kennz in (' . StringOperations::convertArray2InList(ConstantOperations::getBlakBerufsgruppenKennz()) . ') '
           . ' and kennzk.nr = b.knr) and ' . $this->dboperation->dbparser->isNull('b.pkt_ok_stat', '\'-\'') . $statusPart4Punkte;

    
    $sql .= ' and k.nr not like \'BYA__47\' and k.nr not like \'BYA__48\' ';

    
    $sql .= ' and ((' . $this->dboperation->dbparser->isNull('b.pkt_ok_am', $defaultDatum) . ' >= ' . $lastDateSql
            . ' and ' . $this->dboperation->dbparser->isNull('k.ende_dat', $defaultDatum) . ' >= ' . $lastDateSql . ') '
            . ' or ((b.pkt_ok_am = ' . $defaultDatum . ' or b.pkt_ok_am IS NULL ) '
            . ' and (' . $this->dboperation->dbparser->isNull('k.ende_dat', 'k.beginn_dat') . ' >= ' . $lastDateSql
            . ' or (k.ende_dat = ' . $defaultDatum . ' and k.beginn_dat >= ' . $lastDateSql . '))))';

    
    $sql .= ' and (b.status_1 in (' . ConstantOperations::getStatusangemeldetSQLStr() . ') or b.status_1 is null)';
    
    $sql .= ' and ' . $this->dboperation->dbparser->isNull('k.ausfall', "'N'") . " <> 'J'";

    return $sql;
  }

  
  public function isTeilnehmerPunkteVeranstaltungsartenBlakOk($pTnr, $pLastDate, $pMinPunkte): bool
  {
    $tnr = $this->dboperation->getInt4Sql($pTnr);

    static $cache = array();
    $key = $tnr . '_' . $pLastDate . '_' . $pMinPunkte;
    if (!isset($cache[$key])) {
      $cache[$key] = false;

      $sql = 'SELECT k.kart_key, ';
      $sql .= 'sum(CASE ' . $this->dboperation->dbparser->isNull('b.punkte', '0') . ' '
             . ' WHEN 0 THEN k.punkte ELSE b.punkte END) as resultierendePunkte ';
      $sql .= $this->getBlakKennzStatementPart($tnr, $pLastDate, true);
      $sql .= 'and k.kart_key in (1,2,3,4,5,6,7)';
      $sql .= 'GROUP BY k.kart_key';
      $this->dboperation->clear();
      $this->dboperation->query($sql);

      
      

      $zeilen = $this->dboperation->rowcount();

      
      if ($zeilen >= 2) {
        
        $punkteSumme = 0;
        for ($i = 0; $i < $zeilen; $i++) {
          $this->dboperation->selectrow($i);
          $punkteSumme += $this->getDatamodulValue('resultierendePunkte');
        }

        
        $cache[$key] = $punkteSumme >= $pMinPunkte;
      }
    }

    return $cache[$key];
  }

  
  public function getEmailZielBlakNachPunkten($pBerufsgruppe, $pLetztePunkteDatum, $pLetzteRueckmeldung, $pUnterePunkteGrenze, $pOberePunkteGrenze)
  {
    $unterePunkteGrenze = $this->dboperation->getInt4Sql($pUnterePunkteGrenze);
    $oberePunkteGrenze = $this->dboperation->getInt4Sql($pOberePunkteGrenze);
    $defaultDateAsString = $this->datetimeop->getFormatDate4Server(DEFAULTDATE);
    $letztesPunkteDatum = $this->datetimeop->getFormatDate4Server($pLetztePunkteDatum);
    $letzteRueckmeldung = $this->datetimeop->getFormatDate4Server($pLetzteRueckmeldung);
    $sql = 'SELECT b.tnr, t.name, t.vorname, t.zertifikat_druck_dat, t.wtemailam, sum(CASE ifnull(b.punkte, 0) WHEN 0 THEN k.punkte ELSE b.punkte END) as punkte'
      . ' from belegung b join kurse k on k.nr = b.knr '
      . ' join kennz_ad tnkennz on b.tnr = tnkennz.nr and tnkennz.typ = \'T\''
      . ' join kennz_ad kurskennz on b.knr = kurskennz.nr and kurskennz.typ = \'K\''
      . ' join teilnehm t on b.tnr = t.nr where '
      . ' k.nr not like \'BYA__47\' and k.nr not like \'BYA__48\' ' 
      . ' and ' . $this->dboperation->dbparser->isNull('b.pkt_ok_stat', "'-'") . ' = \'W\'' 
      . ' and ((' . $this->dboperation->dbparser->isNull('b.pkt_ok_am', $defaultDateAsString) . ' >= ' . $letztesPunkteDatum
            . ' and ' . $this->dboperation->dbparser->isNull('k.ende_dat', $defaultDateAsString) . ' >= ' . $letztesPunkteDatum . ' ) '
            . ' or ((b.pkt_ok_am = ' . $defaultDateAsString . ' or b.pkt_ok_am IS NULL ) '
            . ' and (' . $this->dboperation->dbparser->isNull('k.ende_dat', 'k.beginn_dat') . ' >= ' . $letztesPunkteDatum
            . ' or (k.ende_dat = ' . $defaultDateAsString . ' and k.beginn_dat >= ' . $letztesPunkteDatum . '))))' 
      . ' and (b.status_1 in (' . ConstantOperations::getStatusangemeldetSQLStr() . ') or b.status_1 is null) ' 
      . ' and ' . $this->dboperation->dbparser->isNull('k.ausfall', "'N'") . " <> 'J'" 
      . ' and tnkennz.kennz = \'' . $pBerufsgruppe . "'" 
      . ' and kurskennz.kennz = \'' . $pBerufsgruppe . "'" 
      . ' and ' . $this->dboperation->dbparser->isNull('t.zertifikat_druck_dat', $defaultDateAsString) . ' < ' . $letztesPunkteDatum 
      . ' and ' . $this->dboperation->dbparser->isNull('t.wtemailam', $defaultDateAsString) . " < $letzteRueckmeldung" 
      . ' group by b.tnr, t.vorname, t.zertifikat_druck_dat, t.wtemailam'
      . ' having sum(CASE ifnull(b.punkte, 0) WHEN 0 THEN k.punkte ELSE b.punkte END) >= ' . $unterePunkteGrenze 
      . ' and sum(CASE ifnull(b.punkte, 0) WHEN 0 THEN k.punkte ELSE b.punkte END) <= ' . $oberePunkteGrenze 
      . ' order by t.zertifikat_druck_dat desc';

    $this->dboperation->clear();
    $this->dboperation->query($sql);
    $rowCount = $this->dboperation->rowcount();
    if ($rowCount > 0) {
      $tnrs = array();
      for ($i = 0; $i < $rowCount; $i++) {
        $this->dboperation->selectrow($i);
        $tn = array();
        $tn['nr'] = $this->getDatamodulValue('tnr');
        $tn['name'] = $this->getDatamodulValue('name');
        $tn['vorname'] = $this->getDatamodulValue('vorname');
        $tn['letztesZertifikat'] = $this->getDatamodulValue('zertifikat_druck_dat');
        $tn['punkte'] = $this->getDatamodulValue('punkte');
        $tnrs[] = $tn;
      }

      return $tnrs;
    }

    return false;
  }

  
  public function getEmailZielBlakNachAblauf($pBerufsgruppe, $pLetztesZertifikatDatum, $pLetzteRueckmeldung)
  {
    $letzteRueckmeldung = $this->datetimeop->getFormatDate4Server($pLetzteRueckmeldung);
    $letztesZertifikatDatum = $this->datetimeop->getFormatDate4Server($pLetztesZertifikatDatum);
    $defaultDateAsString = $this->datetimeop->getFormatDate4Server(DEFAULTDATE);
    $berufsgruppe = $this->dboperation->getInt4Sql($pBerufsgruppe);

    $sql = 'SELECT b.tnr, t.name, t.vorname, t.zertifikat_druck_dat, t.wtemailam '
      . ' from belegung b join kurse k on k.nr = b.knr '
      . ' join kennz_ad tnkennz on b.tnr = tnkennz.nr and tnkennz.typ = \'T\''
      . ' join teilnehm t on b.tnr = t.nr where '
      . ' tnkennz.kennz = \'' . $berufsgruppe . "'" 
      . ' and ' . $this->dboperation->dbparser->isNull('t.wtemailam', $defaultDateAsString) . " < $letzteRueckmeldung" 
      . ' and ' . $this->dboperation->dbparser->isNull('t.zertifikat_druck_dat', $defaultDateAsString) . ' < ' . $letztesZertifikatDatum 
      . ' group by b.tnr'
      . ' order by t.zertifikat_druck_dat desc';
    $this->dboperation->clear();
    $this->dboperation->query($sql);
    $rowCount = $this->dboperation->rowcount();
    if ($rowCount > 0) {
      $tnrs = array();
      for ($i = 0; $i < $rowCount; $i++) {
        $this->dboperation->selectrow($i);
        $tn = array();
        $tn['nr'] = $this->getDatamodulValue('tnr');
        $tn['name'] = $this->getDatamodulValue('name');
        $tn['vorname'] = $this->getDatamodulValue('vorname');
        $tn['letztesZertifikat'] = $this->getDatamodulValue('zertifikat_druck_dat');
        $tnrs[] = $tn;
      }

      return $tnrs;
    }

    return false;
  }

  

  public function nullAllowedFor($varname)
  {
    if ($varname == 'erm_ende' || $varname == 'last_erteilt') {
      return true;
    }

    return false;
  }

  
  public function getFirstWartelistenTN($pKnr)
  {
    $knr = $this->dboperation->getString4Sql($pKnr);
    $sql = 'SELECT ' . $this->select . " FROM teilnehm t join belegung b on b.tnr = t.nr where b.knr = '$knr' order by b.id asc;";
    $this->dboperation->clear();
    $this->dboperation->query($sql);

    return $this->getFirstRow();
  }

  
  public function deleteTeilnehmer($pTnId)
  {
    $tnId = $this->dboperation->getInt4Sql($pTnId);
    $this->dboperation->clear();
    $this->dboperation->execute('DELETE FROM teilnehm WHERE nr=' . $tnId);

    $this->saveChanging('teilnehmer', '', '', "'" . $tnId . "'", '', 'D');
    $this->setActionIDs();
  }

  
  public function getTeilnehmerIdsQuery(?\Kufer\Web\Classes\Identifier\Identifier $pUserId = null)
  {
    $builder = $this->getTeilnehmerQuery();
    $builder->select('nr');

    if (($pUserId instanceof \Kufer\Web\Classes\Identifier\Identifier) && !$pUserId->isIdEmpty(false)) {
      $builder = $builder->and('(' . BereichsrechteAPITeilnehmer::buildBereichsRechteSQLStrBase($pUserId, 't.', $this->dboperation->dbparser) . ')');
    }

    return $builder->orderBySrcCode($this->getCompleteOrderByDefault('nr', 't'));
  }

  public function getTeilnehmerIdsByFilterQuery(?\Kufer\Web\Classes\Identifier\Identifier $pUserId = null)
  {
    $builder = $this->getTeilnehmerIdsQuery($pUserId);

    return $this->addFilterToQuery($builder);
  }

  
  public function getTeilnehmerIdsbyFilter(?\Kufer\Web\Classes\Identifier\Identifier $pUser_Id = null)
  {
    $builder = $this->getTeilnehmerIdsByFilterQuery($pUser_Id);
    $this->dboperation->clear();
    $this->dboperation->query($builder->getSQL());

    return $this->getAllRowsSingleColumn('nr');
  }

  
  protected function _fillAdditionalBankData($pPerson, $pStammBv)
  {
    $pPerson->mandatam = $pStammBv->mandatam;

    return $pPerson;
  }

  
  protected function fillCalculatedFields($pOrigPerson, $pPerson)
  {
    $pPerson = parent::fillCalculatedFields($pOrigPerson, $pPerson);
    $pPerson->name_vorname = StringOperations::strtoupper($pPerson->name) . '  ' . StringOperations::strtoupper($pPerson->vorname) . '_' . $pPerson->id; 

    return $pPerson;
  }

  public function findByFilterQuery(\Kufer\Web\Classes\Dbfilter\TeilnehmerSQLFilter $filter): \SelectQueryBuilder
  {
    $condition = $filter->createSql($this->dboperation);

    return $this->getAllQuery()
      ->and($condition)
      ->and('nr >= 0');
  }

  
  public function existsByFilter(\Kufer\Web\Classes\Dbfilter\TeilnehmerSQLFilter $filter): bool
  {
    return $this->countByFilter($filter) > 0;
  }

  
  public function findByFilter(\Kufer\Web\Classes\Dbfilter\TeilnehmerSQLFilter $filter): array
  {
    $builder = $this->findByFilterQuery($filter);

    $this->dboperation->clear();
    $this->dboperation->query($builder->getSQL());

    return $this->getAllRows();
  }

  
  public function findIdsByFilter(\Kufer\Web\Classes\Dbfilter\TeilnehmerSQLFilter $filter): array
  {
    $builder = $this->findByFilterQuery($filter)
      ->select(':table:.nr');

    $this->dboperation->clear();
    $this->dboperation->query($builder->getSQL());

    return $this->getAllRowsSingleColumn('nr');
  }

  
  public function countByFilter(\Kufer\Web\Classes\Dbfilter\TeilnehmerSQLFilter $filter): int
  {
    $builder = $this->findByFilterQuery($filter)
      ->select('COUNT(*) AS anzahl');

    $this->dboperation->clear();
    $this->dboperation->query($builder->getSQLForInnerQuery());

    $this->dboperation->selectrow(0);

    return (int)$this->getValue('anzahl', \DatamodulVarType::TYPE_INT);
  }
}