<?php
/**
 * @copyright (c) Kufer Software GmbH, Loisachstrasse 4, D-84453 Mühldorf
 */

namespace Kufer\KuferTools\Basis\KursDetails\KursausfallSetzen;

use Kufer\KuferTools\Utils\StatusMessages\StatusMessage;
use Kufer\KuferTools\Utils\StatusMessages\StatusMessageContainer;
use Kufer\Mail\Sender\Settings\Recipient\Einrichtung\EMailEinrichtungRecipientToolsKursSettings;


abstract class KursausfallSetzenAbsendenUseCase extends \Kufer\KuferTools\Basis\UseCase\EinzelKursUseCase
{
  public const KURSTAGE_LOESCHEN_ALLE = '';
  public const KURSTAGE_LOESCHEN_ALLE_BIS_AUF_ERSTEN = '1';
  public const KURSTAGE_LOESCHEN_KEINE = '2';

  protected $statusMessageContainer;

  public function __construct($request, $response = null)
  {
    parent::__construct($request, $response ?? new KursausfallSetzenAbsendenResponse());
    $this->statusMessageContainer = StatusMessageContainer::getSharedInstance();
  }

  public function hasAccess($pToolSectionId = null)
  {
    if (!parent::hasAccess()) {
      return false;
    }
    if ($this->isKursAusgefallen($this->request->knr) && !$this->request->isRefresh) {
      return false;
    }
    if (!$this->request->isXsrfOk && !$this->request->isRefresh) {
      return false;
    }

    return true;
  }

  public function action()
  {
    if (!$this->request->isRefresh) {
      if ($this->sindPflichtfelderGefuellt()) {
        $kurs = $this->getKurs($this->request->knr);
        $isDmzBetrieb = \SessionOperations::isDmzBetrieb();

        try {
          if ($isDmzBetrieb) {
            $this->setzeKursausfallDMZ($kurs->id);
          }
          $this->setzeKursausfallDirekt($kurs, $isDmzBetrieb);
          $this->sendeBenachrichtigung($kurs);
        } catch (\Exception $e) {
          if ($e->errorType == \AbgleichApiResult::KURSAUSFALL_ZAHLUNGEN_VORHANDEN) {
            $this->setMessageZahlungenVorhandenAndSendMail($kurs);
            \Logger::logg('Kursausfall setzen nicht möglich: ' . $e->getMessage(), 30);
          } else {
            $this->setStatusMessageKursausfallError();
            \Logger::logg('Kursausfall setzen - folgende Exception ist aufgetreten: ' . $e->getMessage(), 200);
          }
        }
      } else {
        
        $this->setStatusMessageAusfallgrund();
      }
    }

    return $this->getResponse();
  }

  
  protected function setzeKursausfallDirekt($pKurs, $pIsDmzBetrieb)
  {
    $user = static::getUser();
    $kursausfallMitUnterkursen = $this->sollKursausfallBeiUnterkursenGesetztWerden();

    $zahlungenVorhanden = false;
    if (!$pIsDmzBetrieb) {
      $zahlungenVorhanden = $this->sindZahlungenVorhanden($pKurs->id, $kursausfallMitUnterkursen);
    }

    if (!$zahlungenVorhanden) {
      $emailVersandtAry = $this->setzeKursausfall($pKurs, $user->id, $pIsDmzBetrieb);
      if ($kursausfallMitUnterkursen) {
        $emailVersandtAryUnterkurse = $this->setzeKursausfallBeiUnterkursen($pKurs->id, $user->id, $pIsDmzBetrieb);
        $emailVersandtAry = array_merge($emailVersandtAry, $emailVersandtAryUnterkurse);
      }
      $this->setStatusMessageKursausfallSuccess();
      
      
      $this->response->weiterZuKursuebersicht = $this->toolSettings->keineAusgefallenenKurse;
      if (!empty($emailVersandtAry)) {
        $this->setStatusMessageEmailBenachrichtigungAnTnSuccess($emailVersandtAry['success']);
        $this->setStatusMessageEmailBenachrichtigungAnTnError($emailVersandtAry['error']);
      }
    } else {
      $this->setMessageZahlungenVorhandenAndSendMail($pKurs);
    }
  }

  
  protected function setMessageZahlungenVorhandenAndSendMail($pKurs)
  {
    $this->setStatusMessageZahlungenVorhanden();
    if ($this->sendMailForKursausfallWunsch($pKurs)) {
      $this->setStatusMessageEmailKursausfallWunschSuccess($pKurs->id);
    } else {
      $this->setStatusMessageEmailKursausfallWunschError($pKurs->id);
    }
  }

  protected function setzeKursausfallDMZ($pKnr)
  {
    $user = $this->getUser();
    $dbwBasysUser = \DBWorkBASysUser::getDefaultInstance(1, true);
    $basysbenutzer = $dbwBasysUser->getBASysUser($user->ben);
    $abgleichAPI = new \AbgleichAPI();

    $kursNode = new \XMLNode('kurs');
    $kursNode->addChild(new \XMLNode('id', $pKnr));
    $kursNode->addChild(new \XMLNode('bearbeiter', $basysbenutzer->kennung));

    $optionsNode = new \XMLNode('options');
    if (\DBWorkBASysSettings::isSalzburgBildungswerk() && $this->getToolId() == \ToolsAPI::TOOL_KURSUEBERSICHT_VA) {
      $optionsNode->addChild(new \XMLNode('raumfreigeben', 'F'));
    } elseif ($this->toolSettings->raumfreigeben_bearbeitbar) {
      $raumFreigeben = $this->request->raumFreigeben ? 'W' : 'F';
      $optionsNode->addChild(new \XMLNode('raumfreigeben', $raumFreigeben));
    }
    if ($this->toolSettings->kurstageloeschen_bearbeitbar) {
      $medienLoeschen = $this->request->medienLoeschen ? 'W' : 'F';

      $ktLoeschenAttr = '';
      $ktLoeschenValue = $this->request->ktLoeschen;
      if ($ktLoeschenValue === '') {
        $ktLoeschenValue = '-';
        $ktLoeschenAttr = 'leer="true"';
      }
      $optionsNode->addChild(new \XMLNode('ktloeschen', $ktLoeschenValue, $ktLoeschenAttr));
      $optionsNode->addChild(new \XMLNode('medienloeschen', $medienLoeschen));
    }
    $optionsNode->addChild(new \XMLNode('ausfallgrund', $this->request->ausfallgrund));

    $kursNode->addChild($optionsNode);

    $abgleichAPI->sendeNachricht(
      \AbgleichAPI::ABGLEICH_KURSAUSFALL_SETZEN,
      new \Nutzlast($kursNode)
    );
  }

  
  protected function benachrichtigeTeilnehmer($pKnr)
  {
    $belegungen = $this->getBelegungen($pKnr, true);
    $emailVersandtAry = array('success' => array(), 'error' => array());

    $sender = \Kufer\Mail\Sender\EMailSenderFactory::create();
    foreach ($belegungen as $belegung) {
      $viewModel = new VorlageBenachrichtigungAnTnViewModel();
      $viewModel->belegung = $belegung;

      $email = $this->createVorlageBenachrichtungAnTnView($viewModel);
      $emailSentResult = $this->sendEMailToTeilnehmer($sender, $email, $belegung->teilnehmer);

      if ($emailSentResult->hasSentAllMails()) {
        $emailVersandtAry['success'][] = $belegung;
      } else {
        $emailVersandtAry['error'][] = $belegung;
      }
    }

    return $emailVersandtAry;
  }

  abstract protected function createVorlageBenachrichtungAnTnView(VorlageBenachrichtigungAnTnViewModel $viewModel): VorlageBenachrichtigungAnTnView;

  
  abstract protected function sendEMailToTeilnehmer(
    \Kufer\Mail\Sender\IEMailSender $sender,
    \Kufer\Mail\EMail\IEMail $email,
    \Teilnehmer $teilnehmer
  ): \Kufer\Mail\Sender\Result\EMailSentResult;

  protected function getResponse()
  {
    $this->handleResponseStrategies();
    $this->response->knr = $this->request->knr;
    $this->response->statusMessageContainer = $this->statusMessageContainer;

    return $this->response;
  }

  
  public function getBelegungen($pKnr, $pNurAngemeldete = false)
  {
    $key = $pKnr . '_' . ($pNurAngemeldete ? '1' : '0');
    static $cache = array();
    if (!isset($cache[$key])) {
      $dbwBelegung = \DBWorkBelegung::getDefaultInstance(1, true);
      $cache[$key] = $dbwBelegung->getBelegungenbyKursNR($pKnr, $pNurAngemeldete);
    }

    return $cache[$key];
  }

  
  public function getKurs($pKnr)
  {
    static $cache = array();
    if (!isset($cache[$pKnr])) {
      $dbwKurse = new \DBWorkKurseWT(1, true);
      $cache[$pKnr] = $dbwKurse->getKurs($pKnr);
    }

    return $cache[$pKnr];
  }

  
  protected function getKursnummernVonUnterkursen($pKnr)
  {
    static $cache = array();
    if (!isset($cache[$pKnr])) {
      $dbwKurse = $this->getDbwKurseWT();
      $cache[$pKnr] = $dbwKurse->getKursnummernVonUnterkursen($pKnr);
    }

    return $cache[$pKnr];
  }

  
  protected function getDbwKurseWT()
  {
    return \DBWorkKurseWT::getDefaultInstance(1, true);
  }

  
  protected function getBasysBenutzer()
  {
    $user = $this->getUser();
    $dbwBasysUser = \DBWorkBASysUser::getDefaultInstance(1, true);

    return $dbwBasysUser->getBASysUser($user->ben);
  }

  protected function isKursAusgefallen($pKnr)
  {
    $kurs = $this->getKurs($pKnr);

    return $kurs->ausfall;
  }

  
  protected function sindZahlungenVorhanden($pKnr, $pKursausfallMitUnterkursen)
  {
    $dbwZahlung = new \DBWorkZahlung(1, true);
    $keineZahlungenVorhanden = $dbwZahlung->isStornoBzglZahlungOkForKurs($pKnr);

    if ($keineZahlungenVorhanden && $pKursausfallMitUnterkursen) {
      $unterkursNummern = $this->getKursnummernVonUnterkursen($pKnr);
      foreach ($unterkursNummern as $unterkursNr) {
        $keineZahlungenVorhanden = $dbwZahlung->isStornoBzglZahlungOkForKurs($unterkursNr);
        if (!$keineZahlungenVorhanden) {
          break;
        }
      }
    }

    return !$keineZahlungenVorhanden;
  }

  
  protected function setzeKursausfall($pKurs, $pUserId, $pDmzBetrieb)
  {
    $emailVersandtAry = array();
    $this->schreibeNeutralenZahlungssatz($pKurs->id);

    $pKurs->ausfall = true;
    if (strpos($pKurs->kurzbez, 'Ausfall: ') === false) {
      $pKurs->kurzbez = 'Ausfall: ' . $pKurs->kurzbez;
    }
    $pKurs->zusatztexte->stornogrund = $this->request->ausfallgrund;

    $dbwKurse = $this->getDbwKurseWT();
    $dbwKurse->updateKurs($pKurs, $pDmzBetrieb);

    if ($this->sollRaumFreigegebenWerden()) {
      $this->gebeRaumFrei($pKurs->id);
    }

    if ($this->sollenForderungenAusgebuchtWerden()) {
      $this->bucheForderungenAus($pKurs->id);
    }

    if ($this->sollenBenachrichtigungenAnTnsVerschicktWerden()) {
      $emailVersandtAry = $this->benachrichtigeTeilnehmer($pKurs->id);
    }

    return $emailVersandtAry;
  }

  protected function setzeKursausfallBeiUnterkursen($pHauptKnr, $pUserId, $pIsDmzBetrieb)
  {
    $emailVersandtAry = array();
    $dbwKurse = $this->getDbwKurseWT();

    $unterkursNummern = $this->getKursnummernVonUnterkursen($pHauptKnr);
    $unterkurse = $dbwKurse->getKurseByKursnummern($unterkursNummern);
    foreach ($unterkurse as $unterkurs) {
      $emailVersandtAryUnterkurs = $this->setzeKursausfall($unterkurs, $pUserId, $pIsDmzBetrieb);
      $emailVersandtAry = array_merge_recursive($emailVersandtAry, $emailVersandtAryUnterkurs);
    }

    return $emailVersandtAry;
  }

  
  protected function schreibeNeutralenZahlungssatz($pKnr, $pTnr = 0, $pBelid = 0, $pText = 'Kursausfall', $pArt = '14', $pTyp = 'K')
  {
    $basysBenutzer = $this->getBasysBenutzer();
    $dbwZahlung = \DBWorkZahlung::getDefaultInstance(1, true);

    $dbwZahlung->neutralerZahlungssatz($pKnr, $pTnr, $pBelid, $basysBenutzer, $pText, $pArt, '', '', '', 0, $pTyp);
  }

  
  protected function gebeRaumFrei($pKnr)
  {
    $dbwKurseTage = new \DBWorkKurseTage(1, true);
    $dbwKurstagMedien = \DBWorkKurstagMedien::getDefaultInstance(1, true);
    $kurstage = $dbwKurseTage->getKurstagebyKursNR($pKnr); 

    if ($this->sollenAlleKurstageGeloeschtWerden()) {
      foreach ($kurstage as $kurstag) {
        $dbwKurseTage->deleteKurstag($kurstag->id); 
      }
    } elseif ($this->sollenAlleKurstageBisAufDenErstenGeloeschtWerden()) {
      if (count($kurstage) > 0) {
        $kurstag = array_shift($kurstage);
        $kurstag->ausfall = 'A';
        $dbwKurseTage->updateKurstag($kurstag);
        if ($this->sollenMedienGeloeschtWerden()) {
          $dbwKurstagMedien->deleteKurstagMedienByKurstagID($kurstag->id);
        }
        foreach ($kurstage as $kurstag) {
          $dbwKurseTage->deleteKurstag($kurstag->id);
        }
      }
    } elseif ($this->sollenKeineKurstageGeloeschtWerden()) {
      foreach ($kurstage as $kurstag) {
        $kurstag->ort = 'Ausfall';
        $kurstag->ausfall = 'A';
        if ($this->sollenMedienGeloeschtWerden()) {
          $dbwKurstagMedien->deleteKurstagMedienByKurstagID($kurstag->id);
        }
        $dbwKurseTage->updateKurstag($kurstag);
      }
    }
  }

  protected function bucheForderungenAus($pKnr)
  {
    $dbwBelegung = \DBWorkBelegung::getDefaultInstance(1, true);
    $dbwZahlung = \DBWorkZahlung::getDefaultInstance(1, true);
    $dbwBasysUser = \DBWorkBASysUser::getDefaultInstance(1, true);
    $user = $this->getUser();
    $basysbenutzer = $dbwBasysUser->getBASysUser($user->ben);

    $belegungen = $this->getBelegungen($pKnr);

    foreach ($belegungen as $belegung) {
      $text = 'Kursausfall';
      $art = '14';
      $typ = 'T';
      $this->schreibeNeutralenZahlungssatz($belegung->knr, $belegung->tnr, $belegung->id, $text, $art, $typ);

      if (in_array($belegung->status, array('A', 'T', 'F', 'Z'))) {
        $zahlungenKursaktivierung = $dbwZahlung->getZahlungenByKnrAndBelegIdForKursaktivierung($pKnr, $belegung->id);
        $isErstAusfall = true;
        $datum = '';
        $uhrzeit = '';
        $zahlungId = '';
        if (count($zahlungenKursaktivierung) > 0) {
          $isErstAusfall = false;
          $datum = $zahlungenKursaktivierung[0]->datum;
          $uhrzeit = $zahlungenKursaktivierung[0]->uhrzeit;
          $zahlungId = $zahlungenKursaktivierung[0]->id;
        }

        $stornoGebuehrenAusbuchen = $this->sollenStornoGebuehrenAusgebuchtWerden();
        $zahlungen = \ZahlungAPI::getZahlungen4Kursausfall($belegung->id, $stornoGebuehrenAusbuchen, $isErstAusfall, $datum, $uhrzeit, $zahlungId, $basysbenutzer->kennung);
        $zahlungenToUpdate = $zahlungen['update'];
        $zahlungenToInsert = $zahlungen['insert'];

        foreach ($zahlungenToUpdate as $zahlung) {
          $dbwZahlung->updateZahlung($zahlung, true);
        }

        foreach ($zahlungenToInsert as $zahlung) {
          $dbwZahlung->insertZahlung($zahlung, true);

          $belegung->entgelt = \MathOperations::floatToString(\MathOperations::stringToFloat($belegung->entgelt) + \MathOperations::stringToFloat($zahlung->betrag));
          $belegung->bet_offen = \MathOperations::floatToString(\MathOperations::stringToFloat($belegung->bet_offen) + \MathOperations::stringToFloat($zahlung->betrag));
        }

        $dbwBelegung->updateBelegung($belegung, true);
      }
    }
  }

  
  protected function sindPflichtfelderGefuellt()
  {
    if ($this->isAusfallgrundPflichtfeld()) {
      return $this->request->ausfallgrund !== '';
    }

    return true;
  }

  
  protected function getSettingsHLGrundsys()
  {
    $dbwHlGrundSys = \DBWorkHLGrundSys::getDefaultInstance(1, true);

    return $dbwHlGrundSys->getSettingsAry(array('AusfallgrundSetzen', 'ReiheAusfall', 'KursausfallStornoGeb'));
  }

  
  protected function getSettings()
  {
    $dbwBASysSettings = \DBWorkBASysSettings::getDefaultInstance(1, true);

    return $dbwBASysSettings->getSettings();
  }

  
  protected function sollKursausfallBeiUnterkursenGesetztWerden()
  {
    $settings = $this->getSettingsHLGrundsys();

    return $settings['ReiheAusfall'] !== false && $settings['ReiheAusfall']->wert === 'W';
  }

  
  protected function isAusfallgrundPflichtfeld()
  {
    $settings = $this->getSettingsHLGrundsys();

    return $settings['AusfallgrundSetzen'] !== false && $settings['AusfallgrundSetzen']->wert === 'W';
  }

  
  protected function sollenStornoGebuehrenAusgebuchtWerden()
  {
    $settings = $this->getSettingsHLGrundsys();

    return $settings['KursausfallStornoGeb'] !== false && $settings['KursausfallStornoGeb']->wert === 'W';
  }

  protected function sollRaumFreigegebenWerden()
  {
    if ($this->toolSettings->raumfreigeben_bearbeitbar) {
      $result = $this->request->raumFreigeben;
    } else {
      $settings = $this->getSettings();
      $result = $settings->kursausfallRaumFreigeben;
    }

    return $result;
  }

  protected function sollenAlleKurstageGeloeschtWerden()
  {
    if ($this->toolSettings->kurstageloeschen_bearbeitbar) {
      $value = $this->request->ktLoeschen;
    } else {
      $settings = $this->getSettings();
      $value = $settings->kursausfallKurstageLoeschen;
    }

    return $value === self::KURSTAGE_LOESCHEN_ALLE;
  }

  protected function sollenAlleKurstageBisAufDenErstenGeloeschtWerden()
  {
    if ($this->toolSettings->kurstageloeschen_bearbeitbar) {
      $value = $this->request->ktLoeschen;
    } else {
      $settings = $this->getSettings();
      $value = $settings->kursausfallKurstageLoeschen;
    }

    return $value === self::KURSTAGE_LOESCHEN_ALLE_BIS_AUF_ERSTEN;
  }

  protected function sollenKeineKurstageGeloeschtWerden()
  {
    if ($this->toolSettings->kurstageloeschen_bearbeitbar) {
      $value = $this->request->ktLoeschen;
    } else {
      $settings = $this->getSettings();
      $value = $settings->kursausfallKurstageLoeschen;
    }

    return $value === self::KURSTAGE_LOESCHEN_KEINE;
  }

  protected function sollenMedienGeloeschtWerden()
  {
    if ($this->toolSettings->kurstageloeschen_bearbeitbar) {
      $result = $this->request->medienLoeschen;
    } else {
      $settings = $this->getSettings();
      $result = $settings->kursausfallMedienLoeschen;
    }

    return $result;
  }

  protected function sollenForderungenAusgebuchtWerden()
  {
    $settings = $this->getSettings();

    return $settings->kursausfallForderungenAusbuchen;
  }

  protected function sollenBenachrichtigungenAnTnsVerschicktWerden()
  {
    if (\DBWorkBASysSettings::isSalzburgBildungswerk() && $this->getToolId() == \ToolsAPI::TOOL_KURSUEBERSICHT_VA) {
      return false;
    }

    if ($this->toolSettings->benachrichtigungTn_bearbeitbar) {
      $result = $this->request->benachrichtigungTn;
    } else {
      $settings = $this->getSettings();
      $result = $settings->kursausfallBenachrichtigungAnTns;
    }

    return $result;
  }

  
  protected function shouldSendToVerwaltendemMitarbeiterAuto(): bool
  {
    return $this->toolSettings->kursausfallErfolgreichMailAnVerwMa;
  }

  
  protected function shouldSendToPlanendemMitarbeiterAuto(): bool
  {
    return $this->toolSettings->kursausfallErfolgreichMailAnPlanMa;
  }

  protected function shouldSendToEinrichtung(): bool
  {
    return $this->toolSettings->kursausfallErfolgreichMailAnEinrichtung;
  }

  
  protected function sendeBenachrichtigung($pKurs)
  {
    if (!$this->shouldSendToEinrichtung()
        && !$this->shouldSendToPlanendemMitarbeiterAuto()
        && !$this->shouldSendToVerwaltendemMitarbeiterAuto()) {
      return;
    }

    $viewModel = new VorlageBenachrichtigungAnEinrichtungViewModel();
    $viewModel->kurs = $pKurs;
    $viewModel->raumFreigabe = $this->sollRaumFreigegebenWerden();
    $viewModel->alleKtLoeschen = $this->sollenAlleKurstageGeloeschtWerden();
    $viewModel->alleKtBisAufErstenLoeschen = $this->sollenAlleKurstageBisAufDenErstenGeloeschtWerden();
    $viewModel->keineKtLoeschen = $this->sollenKeineKurstageGeloeschtWerden();
    $viewModel->medienLoeschen = $this->sollenMedienGeloeschtWerden();
    $viewModel->benachrichtigungTn = $this->sollenBenachrichtigungenAnTnsVerschicktWerden();
    $viewModel->ausfallgrund = $this->request->ausfallgrund;

    $email = $this->createVorlageBenachrichtigungAnEinrichtungView($viewModel);
    $sender = \Kufer\Mail\Sender\EMailSenderFactory::createForToolsWithCustomAddress($this->getAlternativeEinrichtungAddress());
    $recipientSender = new EMailEinrichtungRecipientToolsKursSettings($pKurs);
    $recipientSender
      ->setSettingMailToVerwaltendenMitarbeiter($this->shouldSendToVerwaltendemMitarbeiterAuto())
      ->setSettingMailToPlanendenMitarbeiter($this->shouldSendToPlanendemMitarbeiterAuto())
      ->setSettingMailToEinrichtung($this->shouldSendToEinrichtung())
      ->setSettingsVhsEMail($this->getAlternativeEinrichtungAddress());

    $emailSentResult = $this->sendEMailToEinrichtung($sender, $email, $recipientSender);

    if ($emailSentResult->hasSentAnyMails()) {
      $this->setStatusMessageEmailBenachrichtigungAnEinrichtungSuccess();
    } else {
      $this->setStatusMessageEmailBenachrichtigungAnEinrichtungError();
    }
  }

  abstract protected function createVorlageBenachrichtigungAnEinrichtungView(VorlageBenachrichtigungAnEinrichtungViewModel $viewModel): VorlageBenachrichtigungAnEinrichtungView;

  
  abstract protected function getAlternativeEinrichtungAddress(): ?string;

  
  abstract protected function sendEMailToEinrichtung(
    \Kufer\Mail\Sender\IEMailSender $sender,
    \Kufer\Mail\EMail\IEMail $email,
    \Kufer\Mail\Sender\Settings\Recipient\Einrichtung\IEMailEinrichtungRecipientSettings $recipientSettings
  ): \Kufer\Mail\Sender\Result\EMailSentResult;

  
  abstract protected function getPositionNameWithArticle(): string;

  protected function getEinrichtungEMailFromSettings(): ?string
  {
    return $this->toolSettings->{'vhsEmailTool' . $this->getToolId() . 'Section' . $this->getToolSectionId() . '_kursausfall'} ?? null;
  }

  protected function shouldSendToVerwaltendemMitarbeiter(): bool
  {
    return $this->toolSettings->kursausfallMailAnVerwMa ?? false;
  }

  protected function shouldSendToPlanendemMitarbeiter(): bool
  {
    return $this->toolSettings->kursausfallMailAnPlanMa ?? false;
  }

  
  protected function sendMailForKursausfallWunsch($pKurs)
  {
    $user = $this->getUser();

    $betreff = 'Der Kurs ' . $pKurs->id . ' soll auf Ausfall gesetzt werden';

    $mailTextUnterkurse = $this->getMailTextUnterkurse();

    $mailBodyText = \CleanOperations::cleanStringForHtml($this->getPositionNameWithArticle())
      . ' <b>' . \CleanOperations::cleanStringForHtml($user->name . ' ' . $user->vorname) . '</b>'
      . \CleanOperations::cleanStringForHtml(' möchte den Kurs ')
      . '<b>' . \CleanOperations::cleanStringForHtml($pKurs->id . $mailTextUnterkurse) . '</b>'
      . \CleanOperations::cleanStringForHtml(' auf Ausfall setzen.') . '<br>';

    $mailBodyText .= '<ul><li>' . \CleanOperations::cleanStringForHtml($this->getMailTextRaumfreigabe()) . '</li></ul><br>';

    $mailTextAusfallgrund = $this->getMailTextAusfallgrund();
    if ($mailTextAusfallgrund != '') {
      $mailBodyText .= \CleanOperations::cleanStringForHtml($mailTextAusfallgrund) . '<br>';
    }

    $mailBodyText .= '<br>' . \CleanOperations::cleanStringForHtml('Das automatische Setzen des Kursausfalls war aus folgendem Grund nicht möglich:') . '<br>';
    $mailBodyText .= '<ul><li>' . \CleanOperations::cleanStringForHtml('Es sind bereits Zahlungen von Teilnehmern vorhanden.') . '</li></ul>';

    $email = new \Kufer\Mail\EMail\EMailHTML($betreff, $mailBodyText);
    $email->addKuferToolsFooter('Setzen eines Kursausfalls', $user, $pKurs);

    $sender = \Kufer\Mail\Sender\EMailSenderFactory::create();

    $recipientSettings = new \Kufer\Mail\Sender\Settings\Recipient\Einrichtung\EMailEinrichtungRecipientToolsKursSettings($pKurs);
    $recipientSettings
      ->setSettingMailToVerwaltendenMitarbeiter($this->shouldSendToVerwaltendemMitarbeiter())
      ->setSettingMailToPlanendenMitarbeiter($this->shouldSendToPlanendemMitarbeiter())
      ->setSettingsVhsEMail($this->getEinrichtungEMailFromSettings());

    $result = $sender->sendFromPersonToEinrichtung($email, \SessionOperations::getCurrentWebToolsPerson(), $recipientSettings);
    $mailVersandt = $result->hasSentAnyMails();
    if (!$mailVersandt) {
      \Logger::logg('Kursausfall setzen: Die Benachrichtigungs-E-Mail konnte an die Einrichtung nicht versendet werden.', 80);
    }

    return $mailVersandt;
  }

  protected function getMailTextUnterkurse()
  {
    if ($this->sollKursausfallBeiUnterkursenGesetztWerden()) {
      return ' und ggf. dessen Unterkurse';
    }

    return '';
  }

  protected function getMailTextRaumfreigabe()
  {
    if ($this->sollRaumFreigegebenWerden()) {
      $text = 'Es soll der Raum freigegeben und ';
      if ($this->sollenAlleKurstageGeloeschtWerden()) {
        $text .= 'alle Kurstage gelöscht werden.';
      } elseif ($this->sollenAlleKurstageBisAufDenErstenGeloeschtWerden()) {
        $text .= 'alle Kurstage außer dem ersten gelöscht werden. Der erste Kurstage soll auf "Ausfall" gesetzt werden.';
        if ($this->sollenMedienGeloeschtWerden()) {
          $text .= ' Es sollen außerdem alle Medien gelöscht werden.';
        }
      } else {
        $text .= 'alle Kurstage auf einen Pseudoraum gebucht werden.';
        if ($this->sollenMedienGeloeschtWerden()) {
          $text .= ' Es sollen außerdem alle Medien gelöscht werden.';
        }
      }
    } else {
      $text = 'Der Raum soll nicht freigegeben werden.';
    }

    return $text;
  }

  protected function getMailTextAusfallgrund()
  {
    if ($this->request->ausfallgrund != '') {
      return '- Als Ausfallgrund wurde angegeben: ' . $this->request->ausfallgrund;
    }

    return '';
  }

  protected function setStatusMessageKursausfallSuccess()
  {
    $textPart = 'wurde';
    if ($this->sollKursausfallBeiUnterkursenGesetztWerden()) {
      $textPart = 'und ggf. dessen Unterkurse wurden';
    }
    $statusMeldung = 'Der Kurs ' . $textPart . ' erfolgreich auf Ausfall gesetzt.';
    $this->statusMessageContainer->addStatusMessageObj(StatusMessage::getSuccessMessageObj($statusMeldung));
  }

  protected function setStatusMessageKursausfallError()
  {
    $statusMeldung = 'Bei der Übertragung ist ein Fehler aufgetreten!';
    $this->statusMessageContainer->addStatusMessageObj(StatusMessage::getErrorMessageObj($statusMeldung));
  }

  protected function setStatusMessageAusfallgrund()
  {
    $statusMeldung = 'Der Kurs wurde nicht auf Ausfall gesetzt. Bitte geben Sie einen Ausfallgrund an!';
    $this->statusMessageContainer->addStatusMessageObj(StatusMessage::getErrorMessageObj($statusMeldung));
  }

  protected function setStatusMessageZahlungenVorhanden()
  {
    $textPart = 'kann';
    if ($this->sollKursausfallBeiUnterkursenGesetztWerden()) {
      $textPart = 'und ggf. dessen Unterkurse können';
    }
    $statusMeldung = 'Der Kurs ' . $textPart . ' nicht auf Ausfall gesetzt werden, da bereits Zahlungen vorhanden sind.';
    $this->statusMessageContainer->addStatusMessageObj(StatusMessage::getErrorMessageObj($statusMeldung));
  }

  protected function setStatusMessageEmailKursausfallWunschSuccess($pKnr)
  {
    $statusMeldung = 'Es wurde eine E-Mail mit dem Wunsch, den Kurs ' . $pKnr . ' auf Ausfall zu setzen, an die Schulungseinrichtung versandt.';
    $this->statusMessageContainer->addStatusMessageObj(StatusMessage::getInfoMessageObj($statusMeldung));
  }

  protected function setStatusMessageEmailKursausfallWunschError($pKnr)
  {
    $statusMeldung = 'Beim Versand der E-Mail mit dem Wunsch, den Kurs ' . $pKnr . ' auf Ausfall zu setzen, ist ein Fehler aufgetreten. Falls das Problem weiterhin bestehen sollte, wenden Sie sich bitte an die Schulungseinrichtung.';
    $this->statusMessageContainer->addStatusMessageObj(StatusMessage::getErrorMessageObj($statusMeldung));
  }

  
  protected function setStatusMessageEmailBenachrichtigungAnTnSuccess($belegungen)
  {
    if (empty($belegungen)) {
      return;
    }

    $statusMeldung = 'Es wurde eine Benachrichtigung an folgende Teilnehmer erfolgreich versendet:';
    $statusMeldung .= $this->getTeilnehmerAuflistung($belegungen);
    $this->statusMessageContainer->addStatusMessageObj(StatusMessage::getSuccessMessageObj($statusMeldung));
  }

  
  protected function setStatusMessageEmailBenachrichtigungAnTnError($belegungen)
  {
    if (empty($belegungen)) {
      return;
    }

    $statusMeldung = 'Es konnte keine Benachrichtigung an folgende Teilnehmer gesendet werden:';
    $statusMeldung .= $this->getTeilnehmerAuflistung($belegungen);
    $this->statusMessageContainer->addStatusMessageObj(StatusMessage::getErrorMessageObj($statusMeldung));
  }

  
  protected function getTeilnehmerAuflistung($belegungen)
  {
    $result = '<ul>';
    foreach ($belegungen as $belegung) {
      $result .= '<li>' . $belegung->teilnehmer->namevorname . '</li>';
    }
    $result .= '</ul>';

    return $result;
  }

  protected function setStatusMessageEmailBenachrichtigungAnEinrichtungSuccess()
  {
    $statusMeldung = 'Es wurde eine Benachrichtigung an die Schulungseinrichtung versendet.';
    $this->statusMessageContainer->addStatusMessageObj(StatusMessage::getSuccessMessageObj($statusMeldung));
  }

  protected function setStatusMessageEmailBenachrichtigungAnEinrichtungError()
  {
    $statusMeldung = 'Es konnte keine Benachrichtigung an die Schulungseinrichtung gesendet werden. Bitte informieren Sie die Schulungseinrichtung über den Kursausfall.';
    $this->statusMessageContainer->addStatusMessageObj(StatusMessage::getErrorMessageObj($statusMeldung));
  }
}

class KursausfallSetzenAbsendenRequest
{
  public $isRefresh;
  public $isXsrfOk;
  public $knr;
  public $raumFreigeben;
  public $ktLoeschen;
  public $ausfallgrund;
  public $medienLoeschen;
  public $benachrichtigungTn;
}

class KursausfallSetzenAbsendenResponse extends \Kufer\KuferTools\Basis\UseCase\ToolResponse
{
  public $knr;
  public $statusMessageContainer;
  
  public $weiterZuKursuebersicht = false;
}