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


class DozentenAPI
{
  
  public const ALGORITHM_DUBLETTE_SIMPEL = 1;

  
  private function __construct()
  {
  }

  
  public static function correctDozentenHonorar($pDozHonTuple, $pCorrectMode = 'update')
  {
    return self::correctDozentenHonorare(array($pDozHonTuple), $pCorrectMode);
  }

  
  public static function correctDozentenHonorare($pDozHonTupleAry, $pCorrectMode = 'update')
  {
    $abgleichAPI = new AbgleichAPI();
    if (!$abgleichAPI->isAktiviert()) {
      return 'nichtAktiviert';
    }

    $message = new XMLNode('dozentenhonorare');
    
    
    $dbworkWebReplikatSettings = new DBWorkWebReplikatSettings();
    $webreplikatsetting = $dbworkWebReplikatSettings->getMaxPk('doz_kurs');
    $childNode = new XMLNode('highestpk', '-', 'leer="true"');
    if (isset($webreplikatsetting) && $webreplikatsetting->value != '') {
      $childNode = new XMLNode('highestpk', $webreplikatsetting->value);
    }
    $message->addChild($childNode);

    $nothingToDo = true;
    foreach ($pDozHonTupleAry as $dozHonTuple) {
      $dozHonorar = $dozHonTuple->getFirst();
      $fields = $dozHonTuple->getSecond();
      $dozHonOriginal = $dozHonTuple->getThird();
      if ($pCorrectMode == 'update') {
        $oldobjectNode = new XMLNode('oldobject');
      }

      $dozhonNode = new XMLNode('dozentenhonorar');
      
      $dozhonid = $dozHonorar->id;

      
      $dozhonNode->addChild(new XMLNode('id', $dozhonid));
      $nothingToDo = self::addFieldsToDozentenHonorarNode($dozhonNode, $dozHonorar, $fields);
      if ($pCorrectMode == 'update') {
        $nothingToDo = self::addFieldsToDozentenHonorarNode($oldobjectNode, $dozHonOriginal, $fields) && $nothingToDo;
        $dozhonNode->addChild($oldobjectNode);
      }

      
      $message->addChild($dozhonNode);
    } 

    if (!$nothingToDo) {
      
      if ($pCorrectMode == 'update') { 
        $operation = AbgleichAPI::ABGLEICH_DOZKURSKORREKTUR;
      } 
      
      elseif ($pCorrectMode == 'insert') {
        $operation = AbgleichAPI::ABGLEICH_DOZKURS;
      } 
      else { 
        $operation = AbgleichAPI::ABGLEICH_DOZKURSDELETE;
      } 

      $abgleichAPI = new AbgleichAPI();
      
      $abgleichAPI->sendeNachricht($operation, new Nutzlast($message));

      return 'sendDone';
    } 
    
    return 'noCorrection';
  }

  
  private static function addFieldsToDozentenHonorarNode($pDozHonNode, $pDozHonorar, $fields)
  {
    $dbwDozHon = new DBWorkDozentenHonorar();
    $nothingToDo = true;
    
    foreach ($fields as $fieldName) {
      if ($dbwDozHon->canupdate($fieldName) || $fieldName == 'knr' || $fieldName == 'dnr') {
        $fieldValue = $pDozHonorar->getDMZValue($fieldName);
        $fieldAttr = '';
        if ($fieldValue === '') {
          $fieldValue = '-';
          $fieldAttr = 'leer="true"';
        }
        $fieldName = $dbwDozHon->translateVarName($fieldName);
        $childNode = new XMLNode($fieldName, $fieldValue, $fieldAttr);
        $pDozHonNode->addChild($childNode);
        $nothingToDo = false;
      }
    }

    return $nothingToDo;
  }

  
  public static function getXMLNode($pDozent, $fields, $pBezeichnung = 'dozent')
  {
    return AbgleichAPI::getXMLNode(new DBWorkDozenten(), $pDozent, $fields, $pBezeichnung);
  }

  
  public static function correctDozenten($pDozTuple, $pCorrectMode = 'insert')
  {
    return AbgleichAPI::correctDatamodul(
      new DBWorkDozenten(),
      $pDozTuple,
      $pCorrectMode,
      'dozent',
      'dozenten',
      'dozenten',
      AbgleichAPI::ABGLEICH_DOZENT,
      AbgleichAPI::ABGLEICH_DOZENTENDELETE,
      AbgleichAPI::ABGLEICH_DOZENTENKORREKTUR
    );
  }

  public static function correctDozentenVertrag($pDozTupel, $pCorrectMode = 'insert')
  {
    
    
    
  }

  

  
  public static function saveDozent($builder, $pModeUpdate = false)
  {
    $statusMessage = '';
    
    $dozent = $builder->getData();
    $dbwDoz = new DBWorkDozenten(1, true);
    $origDozent = null;
    $changedFields = array();
    if ($pModeUpdate) {
      $origDozent = $dbwDoz->getDozent($dozent->id, true);
      $dbwBASysUser = \DBWorkBASysUser::getDefaultInstance();
      $benutzerKuerzel = $dbwBASysUser->getBASysUser(\SessionOperations::getCurrentWebToolsUser()->ben)->kennung;
      $dozAndChangedFields = self::aktualisiereBerechneteDozentenDaten($origDozent, $dozent, $benutzerKuerzel);
      $dozent = $dozAndChangedFields['dozent'];
      $changedFields = $dozAndChangedFields['changedFields'];
    }

    $allgsettings = AllgSettingsAPI::getAllgSettings();
    
    $changedFields = array_merge($changedFields, $builder->getFieldNamesOfChangedFields($origDozent), $dozent->getKommAnzeigeAry($origDozent));

    if (count($changedFields) == 0) {
      $statusMessage .= HTMLOperations::getInfoBox('<div class="infobox_text">' . CleanOperations::cleanStringForHtml($allgsettings->failMsgChangeDozent) . '</div>', 'Hinweis', 'in_background');

      return array('statusMessage' => $statusMessage, 'dozId' => -1);
    } 

    $insertedDozId = -1;
    try {
      if (SessionOperations::isReplikat() && $allgsettings->dmzEnabled) {
        
        if ($pModeUpdate) {
          
          $correctMode = 'update';
          
          
          $dozent->updateKommAnzeige();
          $dozentTuple = new Tuple($dozent, $changedFields, $origDozent);
          self::correctDozenten($dozentTuple, $correctMode);
          


          
          
          $origKommAry = KommunikationsAPI::getOrigKommunikation($dozent);

          
          
          $dozent = $dbwDoz->updateDozent($dozent, true);
          
          
          KommunikationsAPI::buildAndSendKommunikation($dozent, $origKommAry);
        } else { 
          $correctMode = 'insert';
          
          $insertedDozId = $dbwDoz->insertDozent($dozent);
          
          
          

          $origKommAry = null; 
          $dozentTuple = new Tuple($dozent, $changedFields, null);
          self::correctDozenten($dozentTuple, $correctMode);
          
          
          

          KommunikationsAPI::buildAndSendKommunikation($dozent, $origKommAry);
        } 
      } 

      
      else {
        
        if ($pModeUpdate) {   
          
          $dbwDoz->updateDozent($dozent, false);
        } else { 
          $insertedDozId = $dbwDoz->insertDozent($dozent, false);
        }
      }
      $statusMessage .= HTMLOperations::getSuccessBox('<div class="successbox_text">' . CleanOperations::cleanStringForHtml($allgsettings->successMsgDozentNeu) . '</div>' . "\n", 'Übermittlung erfolgreich', 'in_background');
    } 
    catch (AbgleichApiException $aae) {
      
      if ($insertedDozId != -1 && !$pModeUpdate) {
        $dbwDoz->deleteDozent($insertedDozId);
        
        $insertedDozId = -1;
      }
      Logger::logg('Dozentenkorrektur - folgende Exception ist aufgetreten: ' . $aae->getMessage() . "\n" . ' [' . $aae->getTraceAsString() . ']', 200);

      if ($aae->errorType == AbgleichApiResult::CONFLICT) {
        $statusMessage .= HTMLOperations::getAlertBox('<div class="alertbox_text">' . CleanOperations::cleanStringForHtml($allgsettings->failSubmitMsgConflict) . '</div>', 'Fehler', 'in_background');
      } else {
        $statusMessage .= HTMLOperations::getAlertBox('<div class="alertbox_text">' . CleanOperations::cleanStringForHtml($allgsettings->failSubmitMsgDozent) . '</div>', 'Fehler', 'in_background');
      }
    }
    
    
    catch (Exception $e) {
      
      if ($insertedDozId != -1 && !$pModeUpdate) {
        $dbwDoz->deleteDozent($insertedDozId);
        
        $insertedDozId = -1;
      }
      if ($pModeUpdate) {
        $statusMessage .= HTMLOperations::getInfoBox('<div class="infobox_text">' . CleanOperations::cleanStringForHtml($allgsettings->failMsgChangeDozent) . '</div>', 'Hinweis', 'in_background');
      } else {
        $statusMessage .= HTMLOperations::getAlertBox('<div class="alertbox_text">' . CleanOperations::cleanStringForHtml($allgsettings->failMsgDozentNeu) . '</div>', 'Fehler', 'in_background');
      }
      Logger::logg('Dozentenkorrektur - folgende Exception ist aufgetreten: ' . $e->getMessage() . "\n" . ' [' . $e->getTraceAsString() . ']', 200);
    }

    return array('statusMessage' => $statusMessage, 'dozId' => $insertedDozId);
  }

  
  public static function aktualisiereBerechneteDozentenDaten(\Dozent $pOrigDozent, \Dozent $pDozent, string $pBenutzerKuerzel): array
  {
    $changedFields = array();
    if (StringOperations::substr(StringOperations::strtoupper($pOrigDozent->name), 0, 16) == $pDozent->suchbegriff) {
      $pDozent->suchbegriff = StringOperations::substr(StringOperations::strtoupper($pDozent->name), 0, 16); 
      $changedFields[] = 'suchbegriff';
    }

    if ($pOrigDozent->ansprache !== '' && $pOrigDozent->ansprache == $pDozent->ansprache) {
      $pDozent->ansprache = str_replace($pOrigDozent->name, $pDozent->name, $pDozent->ansprache);
      $pDozent->ansprache = str_replace($pOrigDozent->vorname, $pDozent->vorname, $pDozent->ansprache);
      $changedFields[] = 'ansprache';
    }

    if ($pOrigDozent->dse_unterschrieben_datum !== $pDozent->dse_unterschrieben_datum
            || $pOrigDozent->dse_unterschrieben_weg !== $pDozent->dse_unterschrieben_weg) {
      $pDozent->dse_unterschrieben_bearbeiter = $pBenutzerKuerzel;
      $changedFields[] = 'dse_unterschrieben_bearbeiter';
      if ($pDozent->dse_unterschrieben_datum === '' && $pDozent->dse_unterschrieben_weg !== '') {
        $pDozent->dse_unterschrieben_datum = DateTimeOperations::getDateTimeNow();
        $changedFields[] = 'dse_unterschrieben_datum'; 
      }
    }

    if ($pOrigDozent->dse_widerrufen_datum !== $pDozent->dse_widerrufen_datum
            || $pOrigDozent->dse_widerrufen_weg !== $pDozent->dse_widerrufen_weg) {
      $pDozent->dse_widerrufen_bearbeiter = $pBenutzerKuerzel;
      $changedFields[] = 'dse_widerrufen_bearbeiter';
      if ($pDozent->dse_widerrufen_datum === '' && $pDozent->dse_widerrufen_weg !== '') {
        $pDozent->dse_widerrufen_datum = DateTimeOperations::getDateTimeNow();
        $changedFields[] = 'dse_widerrufen_datum'; 
      }
    }

    return array('dozent' => $pDozent, 'changedFields' => $changedFields);
  }

  public static function insertDmzMappingAnhandGuid($dozent)
  {
    $dozentNode = new XMLNode('dozent');
    $dozentNode->addChild(new XMLNode('mysqlid', $dozent->getDMZValue('id')));
    $dozentNode->addChild(new XMLNode('guid', $dozent->getDMZValue('guid')));

    
    $message = new XMLNode('dozentenContainer');
    $message->addChild($dozentNode);

    $abgleichAPI = new AbgleichAPI();
    
    $abgleichAPI->sendeNachricht(AbgleichAPI::ABGLEICH_INSERT_DOZENTEN_MAPPING_ANHAND_GUID, new Nutzlast($message));
  }

  
  private static function isDubletteBasicEqual(\Dozent $dozOrig, \Dozent $dozDublette): bool
  {
    $mailDoz = $dozDublette->getVarValueEx('email', 'Kommunikation');

    $origEmails = array();
    if (!empty($dozOrig->id) && $dozOrig->id > 0) {
      $dbwKomms = \DBWorkKommunikation::getDefaultInstance();
      $emails = $dbwKomms->getKommunikationByNrTypArt($dozOrig->id, $dozOrig->getDbTyp(), 'E');
      $origEmails = \array_filter(\ArrayOperations::mapAttribut($emails, 'wert'));
      if (!empty($origEmails)) {
        $origEmails[] = '';
      }
    }

    return $dozOrig->name == $dozDublette->name
      && $dozOrig->vorname == $dozDublette->vorname
      && in_array($mailDoz, $origEmails);
  }

  
  public static function isDublette(\Dozent $pDozent, $pAlgorithmus = false)
  {
    $abgleichAPI = new \AbgleichAPI();
    if (!$abgleichAPI->isAktiviert()) {
      return 'nichtAktiviert';
    }

    $message = new \XMLNode('dozenten');

    $datamodulNode = $pDozent->ToXml(array('aryattachments', 'arykennzeichenJS', 'aryattachmentsJS', 'uploadAttachments'), true, array(), 'dozent');

    
    $message->addChild($datamodulNode);

    $nutzlast = new \Nutzlast($message);

    if (false !== $pAlgorithmus) {
      $algoNode = new \XMLNode('algorithm', $pAlgorithmus);
      $nutzlast->addNode($algoNode);
    }

    
    $result = $abgleichAPI->sendeNachricht(
      \AbgleichAPI::ABGLEICH_DOZENT_IS_DUBLETTE,
      $nutzlast
    );

    if ($result->code == \AbgleichApiResult::CODE_DUPLICATE) {
      $matches = array();
      if (preg_match_all('/\\d+/', $result->reason, $matches)) {
        $idResult = array('sqlid' => $matches[0][0], 'replikatid' => $matches[0][1]);
        if ($idResult['sqlid'] == $idResult['replikatid']) {
          $dbwRepSettings = \DBWorkWebReplikatSettings::getDefaultInstance();
          if (!$dbwRepSettings->isOldDoz($idResult['replikatid'])) {
            
            
            
            $dbwtn = \DBWorkDozenten::getDefaultInstance();
            $doz = $dbwtn->getDozent($idResult['replikatid']);
            if (!static::isDubletteBasicEqual($doz, $pDozent)) {
              $idResult['replikatid'] = 0;
            }
          }
        }

        return $idResult;
      }
    }
    if ($result->code == \AbgleichApiResult::CODE_SUCCESS) {
      if ($result->errorType == \AbgleichApiResult::DOZENT_NICHT_VORHANDEN) {
        return array('sqlid' => false, 'replikatid' => false);
      }
    }
    $reason = print_r($result, true);
    \Logger::logg('unvorgesehener Fall bei DozentenAPI::isDublette() ' . $reason, 600);

    throw new \Exception('Invalid State: unvorgesehener Fall bei DozentenAPI::isDublette() - ' . $reason);
  }
}