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

class GebuehrenTest extends \PHPUnit\Framework\TestCase
{
  /**
   * @var \Kufer\Web\Classes\Gebuehren\KursgebuehrBerechnungsKontextWarenkorb
   */
  private $wkKontext;

  /**
   * @var \Kufer\Web\Classes\Gebuehren\KursgebuehrBerechnungsStateWarenkorb
   */
  private $wkState;

  /**
   * Sets up the fixture, for example, opens a network connection.
   * This method is called before a test is executed.
   */
  protected function setUp(): void
  {
    \DBWorkBASysSettings::$TestEnforceVsb = false;
    \DBWorkBASysSettings::$rundung = 0;
    \APIGebuehren::$ermaessigung = array(0 => null);
    if (!defined('DECIMAL_SEPARATOR')) {
      define('DECIMAL_SEPARATOR', ',');
    }
    $this->wkKontext = new Kufer\Web\Classes\Gebuehren\KursgebuehrBerechnungsKontextWarenkorb();
    $this->wkState = new Kufer\Web\Classes\Gebuehren\KursgebuehrBerechnungsStateWarenkorb();
  }

  /**
   * Tears down the fixture, for example, closes a network connection.
   * This method is called after a test is executed.
   */
  protected function tearDown(): void
  {
    $this->wkKontext->gutscheinBetrag = 0;
    $this->wkState->gutscheinBetragOffen = 0;
    $this->wkState->gutscheinBetragOffenSetFlag = false;
    PostOperations::setVarValue('gutschein_betrag', '0');
  }

  /**
   * @covers GebuehrenElementBase::setGebuehrenbestandteile
   * @test
   */
  public function betragIsConvertedToFloat()
  {
    $expected = '';
    $kg = $this->initKinderKursStdGebUndEineKindGeb();
    $parts = $kg->getGebuehrensaetze();

    $this->assertTrue(true, is_float($parts[0]->betrag));
    $this->assertTrue(true, is_float($parts[0]->betrag_ermaessigt));
  }

  /**
   * @covers GebuehrenElementVisitorFilterByZahlplan::accept
   * @test
   */
  public function filterNonZahlplan()
  {
    $expected = '';
    $kg = $this->initKinderKursStdGebUndEineKindGeb();
    $parts = $kg->getGebuehrensaetze();
    $this->assertEquals(2, count($parts));
    $visitKeinZp = new GebuehrenElementVisitorFilterByZahlplan();

    $kg->accept($visitKeinZp);
    $parts = $kg->getGebuehrensaetze();
    $this->assertEquals(1, count($parts));
    $this->assertEquals('201-10300', $parts[0]->knr);
  }

  /**
   * @covers GebuehrenElementVisitorFilterByZahlplan::accept
   * @test
   */
  public function filterSpecialZahlplan()
  {
    $expected = '';
    $kg = $this->initKinderKursStdGebUndEineKindGeb();
    $parts = $kg->getGebuehrensaetze();
    $this->assertEquals(2, count($parts));
    $this->assertEquals(150.06, $kg->getSum());//Summe über beide Zahlpläne

    $visitKeinZp = new GebuehrenElementVisitorFilterByZahlplan('1524');
    $kg->accept($visitKeinZp);
    $parts = $kg->getGebuehrensaetze();
    $this->assertEquals(1, count($parts));
    $this->assertEquals(50.05, $kg->getSum());
  }

  private function initKinderKursStdGebUndEineKindGeb()
  {
    $knr = '201-10300';
    $kg1 = new Kursgebuehr();
    $kg1->knr = $knr;
    $kg1->gebart = 1;
    $kg1->schluessel = 1;
    $kg1->text = 'Kerngebühr';
    $kg1->ermaessigbar = true;
    $kg1->geb_ermaess = 'F';
    $kg1->betrag = '100,01';
    $kg1->betrag_ermaessigt = '100,01';
    $kg2 = new Kursgebuehr();
    $kg2->knr = $knr . ' 1524';
    $kg2->gebart = 1;
    $kg2->schluessel = 1;
    $kg2->text = 'Kerngebühr';
    $kg2->ermaessigbar = true;
    $kg2->geb_ermaess = 'F';
    $kg2->betrag = '50,05';
    $kg2->betrag_ermaessigt = '33,01';
    $kg = new GebuehrenElementBase($knr);
    $kg->setGebuehrensaetze(array($kg1, $kg2));
    $kg->setKurstyp('K');
    $kg->setZahlplaene(array());
    $kg->setMwstSaetze(array(0 => 0));
    $kg->setTeilMin(10);

    return $kg;
  }

  /**
   * @covers GebuehrenElementVisitorFilterByZahlplan::accept
   * @test
   */
  public function filterZahlplan()
  {
    $expected = '';
    $kg = $this->initKinderKursStdGebUndEineKindGeb();

    $parts = $kg->getGebuehrensaetze();
    $this->assertEquals(2, count($parts));

    $zpId = 1524;
    $visitKeinZp = new GebuehrenElementVisitorFilterByZahlplan($zpId);
    $kg->accept($visitKeinZp);
    $parts = $kg->getGebuehrensaetze();
    $this->assertEquals(1, count($parts));
    $expectedZpKnr = Kufer\Web\Classes\Api\Helpers\ZahlplanHelper::computeKnr($kg->getKnr(), $zpId);
    $this->assertEquals($expectedZpKnr, $parts[0]->knr);
  }

  /**
   * @covers Kufer\Web\Classes\Api\Helpers\ZahlplanHelper::computeKnr
   * @test
   */
  public function computeKnrNoId()
  {
    $knr = '201-111';
    $expected = $knr;
    $result = \Kufer\Web\Classes\Api\Helpers\ZahlplanHelper::computeKnr($knr);
    $this->assertEquals($expected, $result);
  }

  /**
   * @covers Kufer\Web\Classes\Api\Helpers\ZahlplanHelper::computeKnr
   * @test
   */
  public function computeKnrWithId()
  {
    $knr = '201-2';
    $zp = '1530';
    $expected = '201-2     1530';
    $result = \Kufer\Web\Classes\Api\Helpers\ZahlplanHelper::computeKnr($knr, $zp);
    $this->assertEquals($expected, $result);
  }

  /**
   * Testet, dass von einem Kurs mit x Zahlplänen und Kursgebühren die Standardgebühr korrekt berechnet wird.
   * @covers GebuehrenElementVisitorFilterByZahlplan::accept
   * @test
   */
  public function berechneStandardTnGebuehr()
  {
    $kg = $this->initEKKursKomplex('201-103005');

    $parts = $kg->getGebuehrensaetze();
    $this->assertEquals(8, count($parts));

    $zpId = '';
    $visitKeinZp = new GebuehrenElementVisitorFilterByZahlplan($zpId);
    $kg->accept($visitKeinZp);
    $parts = $kg->getGebuehrensaetze();
    $this->assertEquals(2, count($parts));
    $expectedZpKnr = $kg->getKnr();
    $this->assertEquals($expectedZpKnr, $parts[0]->knr);
    $this->assertEquals($expectedZpKnr, $parts[1]->knr);
    $expectedSum = 60.06;
    $this->assertEquals($expectedSum, $kg->getSum());

    //$expectedZpKnr = Kufer\Web\Classes\Api\Helpers\ZahlplanHelper::computeKnr($kg->getKnr(), $zpId);
  }

  /**
   * @param string $knr
   * @return \GebuehrenElementBase
   */
  private function initEKKursKomplex($knr)
  {
    $kgs = array();

    //Standardgebuehr
    $kg = new Kursgebuehr();
    $kg->knr = $knr;
    $kg->gebart = 1;
    $kg->schluessel = 1;
    $kg->text = 'Kerngebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '50,05';
    $kg->betrag_ermaessigt = '50,05';
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;
    $kg = new Kursgebuehr();
    $kg->knr = $knr;
    $kg->gebart = 1;
    $kg->schluessel = 2;
    $kg->text = 'Kerngebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '10,01';
    $kg->betrag_ermaessigt = '10,01';
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;

    //ZP 2 - TN: Mitglieder A
    $kg = new Kursgebuehr();
    $kg->knr = \Kufer\Web\Classes\Api\Helpers\ZahlplanHelper::computeKnr($knr, '1525');
    $kg->gebart = 1;
    $kg->schluessel = 1;
    $kg->text = 'Kerngebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '40,04';
    $kg->betrag_ermaessigt = '40,04';
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;

    //ZP 2 - TN: Mitglieder B
    $kg = new Kursgebuehr();
    $kg->knr = \Kufer\Web\Classes\Api\Helpers\ZahlplanHelper::computeKnr($knr, '1526');
    $kg->gebart = 1;
    $kg->schluessel = 1;
    $kg->text = 'Kerngebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '30,03';
    $kg->betrag_ermaessigt = '30,03';
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;

    //ZP Kinder 1
    $kg = new Kursgebuehr();
    $kg->knr = \Kufer\Web\Classes\Api\Helpers\ZahlplanHelper::computeKnr($knr, '1527');
    $kg->gebart = 1;
    $kg->schluessel = 1;
    $kg->text = 'Kerngebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '5,55';
    $kg->betrag_ermaessigt = '5,55';
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;
    $kg = new Kursgebuehr();
    $kg->knr = $knr . '1527';
    $kg->gebart = 4;
    $kg->schluessel = 2;
    $kg->text = 'Sonstige Gebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '0,01';
    $kg->betrag_ermaessigt = '0,01';
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;

    //ZP Kinder 2
    $kg = new Kursgebuehr();
    $kg->knr = \Kufer\Web\Classes\Api\Helpers\ZahlplanHelper::computeKnr($knr, '1528');
    $kg->gebart = 1;
    $kg->schluessel = 1;
    $kg->text = 'Kerngebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '4,44';
    $kg->betrag_ermaessigt = '4,44';
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;

    //ZP Kinder weitere
    $kg = new Kursgebuehr();
    $kg->knr = \Kufer\Web\Classes\Api\Helpers\ZahlplanHelper::computeKnr($knr, '1529');
    $kg->gebart = 1;
    $kg->schluessel = 1;
    $kg->text = 'Kerngebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '3,33';
    $kg->betrag_ermaessigt = '3,33';
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;

    $kg = new GebuehrenElementBase($knr);
    $kg->setGebuehrensaetze($kgs);
    $zps = array();
    $kz = new Kurszahlplan();
    $kz->knr = $knr;
    $kz->beschreibung = 'Mitglieder A';
    $kz->webdarst = true;
    $kz->tn_von = 0;
    $kz->tn_bis = 0;
    $kz->id = 1525;
    $zps[] = $kz;
    $kz = new Kurszahlplan();
    $kz->knr = $knr;
    $kz->beschreibung = 'Mitglieder B';
    $kz->webdarst = true;
    $kz->tn_von = 0;
    $kz->tn_bis = 0;
    $kz->id = 1526;
    $zps[] = $kz;
    $kz = new Kurszahlplan();
    $kz->knr = $knr;
    $kz->beschreibung = 'Gebühren Kind 1';
    $kz->webdarst = true;
    $kz->tn_von = 1;
    $kz->tn_bis = 1;
    $kz->zusatz = 'K';
    $kz->id = 1527;
    $zps[] = $kz;
    $kz = new Kurszahlplan();
    $kz->knr = $knr;
    $kz->beschreibung = 'Gebühren Kind 2';
    $kz->webdarst = true;
    $kz->tn_von = 2;
    $kz->tn_bis = 2;
    $kz->zusatz = 'K';
    $kz->id = 1528;
    $zps[] = $kz;
    $kz = new Kurszahlplan();
    $kz->knr = $knr;
    $kz->beschreibung = 'Gebühren Kind 3 bis x';
    $kz->webdarst = true;
    $kz->tn_von = 3;
    $kz->tn_bis = 0;
    $kz->zusatz = 'K';
    $kz->id = 1529;
    $zps[] = $kz;
    $kg->setZahlplaene($zps);
    $kg->setMwstSaetze(array(0 => 0));
    $kg->setKurstyp('L');
    $kg->setTeilMin(10);

    return $kg;
  }

  /**
   * @param string $knr
   * @return GebuehrenElement
   */
  private function testDataGutscheinElternKindKurs1($knr)
  {
    $kgs = array();

    //Standardgebuehr
    $kg = new Kursgebuehr();
    $kg->knr = $knr;
    $kg->gebart = 1;
    $kg->schluessel = 1;
    $kg->text = 'Kerngebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '10,00';
    $kg->betrag_ermaessigt = '10,00';
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;

    $kg = new Kursgebuehr();
    $kg->knr = $knr;
    $kg->gebart = 2;
    $kg->schluessel = 2;
    $kg->text = 'Prüfungsgebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '5';
    $kg->betrag_ermaessigt = '0';
    $kg->geb_ermaess = 'W';
    $kgs[] = $kg;

    $kg = new Kursgebuehr();
    $kg->knr = $knr;
    $kg->gebart = 4;
    $kg->schluessel = 3;
    $kg->text = 'Sonstige Gebühr';
    $kg->ermaessigbar = false;
    $kg->betrag = '5';
    $kg->betrag_ermaessigt = '5';
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;


    $result = new GebuehrenElementBase($knr);
    $result->setGebuehrensaetze($kgs);

    $result->setMwstSaetze(array(0 => 0));
    $result->setKurstyp('L');

    return $result;
  }

  /**
   * @param string $knr
   * @return GebuehrenElement
   */
  private function testDataGutscheinKinderKurs1($knr)
  {
    $kgs = array();

    //Standardgebuehr
    $kg = new Kursgebuehr();
    $kg->knr = $knr;
    $kg->gebart = 1;
    $kg->schluessel = 1;
    $kg->text = 'Kerngebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '10,00';
    $kg->betrag_ermaessigt = '10,00';
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;

    $kg = new Kursgebuehr();
    $kg->knr = $knr;
    $kg->gebart = 2;
    $kg->schluessel = 2;
    $kg->text = 'Prüfungsgebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '5';
    $kg->betrag_ermaessigt = '0';
    $kg->geb_ermaess = 'W';
    $kgs[] = $kg;

    $kg = new Kursgebuehr();
    $kg->knr = $knr;
    $kg->gebart = 4;
    $kg->schluessel = 3;
    $kg->text = 'Sonstige Gebühr';
    $kg->ermaessigbar = false;
    $kg->betrag = '5';
    $kg->betrag_ermaessigt = '5';
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;

    $result = new GebuehrenElementBase($knr);
    $result->setGebuehrensaetze($kgs);

    $result->setMwstSaetze(array(0 => 0));
    $result->setKurstyp('K');

    return $result;
  }

  /**
   * @param string $knr
   * @return GebuehrenElement
   */
  private function testDataGutscheinKurs1($knr)
  {
    $kgs = array();

    //Standardgebuehr
    $kg = new Kursgebuehr();
    $kg->knr = $knr;
    $kg->gebart = 1;
    $kg->schluessel = 1;
    $kg->text = 'Kerngebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '10,00';
    $kg->betrag_ermaessigt = '10,00';
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;

    $kg = new Kursgebuehr();
    $kg->knr = $knr;
    $kg->gebart = 2;
    $kg->schluessel = 2;
    $kg->text = 'Prüfungsgebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '5';
    $kg->betrag_ermaessigt = '0';
    $kg->geb_ermaess = 'W';
    $kgs[] = $kg;

    $kg = new Kursgebuehr();
    $kg->knr = $knr;
    $kg->gebart = 4;
    $kg->schluessel = 3;
    $kg->text = 'Sonstige Gebühr';
    $kg->ermaessigbar = false;
    $kg->betrag = '5';
    $kg->betrag_ermaessigt = '5';
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;


    $result = new GebuehrenElementBase($knr);
    $result->setGebuehrensaetze($kgs);

    $result->setMwstSaetze(array(0 => 0));
    $result->setKurstyp('N');

    return $result;
  }

  /**
   * @param array $knrArray
   * @return GebuehrenElement
   */
  private function testDataGutscheinKurs2($knr)
  {
    $kgs = array();

    //Standardgebuehr
    $kg = new Kursgebuehr();
    $kg->knr = $knr;
    $kg->gebart = 1;
    $kg->schluessel = 1;
    $kg->text = 'Kerngebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '20,00';
    $kg->betrag_ermaessigt = '20,00';
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;

    $kg = new Kursgebuehr();
    $kg->knr = $knr;
    $kg->gebart = 4;
    $kg->schluessel = 2;
    $kg->text = 'Sonstige Gebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '20,00';
    $kg->betrag_ermaessigt = '20,00';
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;

    $result = new GebuehrenElementBase($knr);
    $result->setGebuehrensaetze($kgs);

    $result->setMwstSaetze(array(0 => 0));
    $result->setKurstyp('N');

    return $result;
  }

  /**
   * @param array $knrArray
   * @return GebuehrenElement
   */
  private function testDataGutscheinKurs3($knr)
  {
    $kgs = array();

    //Standardgebuehr
    $kg = new Kursgebuehr();
    $kg->knr = $knr;
    $kg->gebart = 1;
    $kg->schluessel = 1;
    $kg->text = 'Kerngebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '10,00';
    $kg->betrag_ermaessigt = '10,00';
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;

    $kg = new Kursgebuehr();
    $kg->knr = $knr;
    $kg->gebart = 4;
    $kg->schluessel = 2;
    $kg->text = 'Sonstige Gebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '10,00';
    $kg->betrag_ermaessigt = '10,00';
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;

    $result = new GebuehrenElementBase($knr);
    $result->setGebuehrensaetze($kgs);

    $result->setMwstSaetze(array(0 => 0));
    $result->setKurstyp('N');

    return $result;
  }

  /**
   * Testet, dass von einem Kurs mit x Zahlplänen und Kursgebühren die Gebühr für Zahlplan 1 korrekt berechnet wird.
   * @covers GebuehrenElementVisitorFilterByZahlplan::accept
   * @test
   */
  public function berechneZahlplan1TnGebuehrLangeKnr()
  {
    $expected = '';
    $kg = $this->initEKKursKomplex('201-103005');

    $parts = $kg->getGebuehrensaetze();
    $this->assertEquals(8, count($parts));

    $zpId = '1526';
    $visitKeinZp = new GebuehrenElementVisitorFilterByZahlplan($zpId);
    $kg->accept($visitKeinZp);
    $parts = $kg->getGebuehrensaetze();
    $this->assertEquals(1, count($parts));
    $expectedZpKnr = Kufer\Web\Classes\Api\Helpers\ZahlplanHelper::computeKnr($kg->getKnr(), $zpId);
    $this->assertEquals($expectedZpKnr, $parts[0]->knr);
    $expectedSum = 30.03;
    $this->assertEquals($expectedSum, $kg->getSum());
  }

  /**
   * Testet, dass von einem Kurs mit x Zahlplänen und Kursgebühren die Gebühr für Zahlplan 1 korrekt berechnet wird.
   * HIER MIT ANDERER LÄNGE DER KURSNUMMER
   * @covers GebuehrenElementVisitorFilterByZahlplan::accept
   * @test
   */
  public function berechneZahlplan1TnGebuehrKurzeKnr()
  {
    $expected = '';
    $kg = $this->initEKKursKomplex('201-103');

    $parts = $kg->getGebuehrensaetze();
    $this->assertEquals(8, count($parts));

    $zpId = '1526';
    $visitKeinZp = new GebuehrenElementVisitorFilterByZahlplan($zpId);
    $kg->accept($visitKeinZp);
    $parts = $kg->getGebuehrensaetze();
    $this->assertEquals(1, count($parts));
    $expectedZpKnr = Kufer\Web\Classes\Api\Helpers\ZahlplanHelper::computeKnr($kg->getKnr(), $zpId);
    $this->assertEquals($expectedZpKnr, $parts[0]->knr);
    $expectedSum = 30.03;
    $this->assertEquals($expectedSum, $kg->getSum());
  }

  /**
   * @covers GebuehrenElementRechnerFuenfNull::getKindGebuehrSumme
   * @test
   */
  public function fassadeFuenfNullBerechneKinderGebuehr()
  {
    //Kind 1
    $berechner = new GebuehrenElementRechnerFuenfNull();
    $kg = $this->initEKKursKomplex('201-103005');
    $berechner->setGebuehrenElement($kg);
    $expected = 5.56;
    $result = $berechner->getKindGebuehrSumme(1, '', $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);

    //Kind2
    $berechner = new GebuehrenElementRechnerFuenfNull();
    $kg = $this->initEKKursKomplex('201-103005');
    $berechner->setGebuehrenElement($kg);
    $expected = 4.44;
    $result = $berechner->getKindGebuehrSumme(2, '', $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);

    //Kind3
    $berechner = new GebuehrenElementRechnerFuenfNull();
    $kg = $this->initEKKursKomplex('201-103005');
    $berechner->setGebuehrenElement($kg);
    $expected = 3.33;
    $result = $berechner->getKindGebuehrSumme(3, '', $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);
  }

  /**
   * @covers GebuehrenElementRechnerFuenfNull::getKindGebuehrSumme
   * @test
   */
  public function getElternKindGebuehrSumme_fuenfNullMitGutscheinBetrag_MehrereKinder() //Eltern-Kind-Kurs
  {
    PostOperations::setVarValue('gutschein_betrag', 30); // wir stellen einen gutschein betrag von 30 euro ein
    $kGebBerKontext = new KursgebuehrBerechnungsKontext('221-TEST1', 3);
    $berechner = new GebuehrenElementRechnerFuenfNull();
    $kg = $this->testDataGutscheinElternKindKurs1('221-TEST1');
    $berechner->setGebuehrenElement($kg);

    //Kind 1
    $expected = 0; // das erste Kind zahlt nichts
    $result = $berechner->getKindGebuehrSumme(1, $kGebBerKontext, $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);

    //Kind 2
    $expected = 0; // das zweite Kind zahlt nichts
    $result = $berechner->getKindGebuehrSumme(2, $kGebBerKontext, $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);

    //Kind 3
    $expected = 0; // Das dritte Kind zahlt nichts
    $result = $berechner->getKindGebuehrSumme(3, $kGebBerKontext, $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);

    $expected = 0;
    $result = $berechner->getGebuehrenSummeErmaessigt(1, $kGebBerKontext, $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);
  }

  /**
   * @covers GebuehrenElementRechnerFuenfNull::getKindGebuehrSumme
   * @test
   */
  public function getKinderGebuehrSumme_fuenfNullMitGutscheinBetrag_Einzelkind() //Kinderkurs
  {
    // Test für 1 Kind

    PostOperations::setVarValue('gutschein_betrag', 5); // wir stellen einen gutschein betrag von 5 euro ein
    $kGebBerKontext = new KursgebuehrBerechnungsKontext('221-TEST1');
    $berechner = new GebuehrenElementRechnerFuenfNull();
    $kg = $this->testDataGutscheinKinderKurs1('221-TEST1');
    $berechner->setGebuehrenElement($kg);

    // kind 1
    $expected = 15; // das erste Kind zahlt nichts, also wird der Gutschein auf das Standardgebuehr angewendet
    $result = $berechner->getKindGebuehrSumme(1, $kGebBerKontext, $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);
  }

  /**
   * @covers GebuehrenElementRechnerFuenfNull::getKindGebuehrSumme
   * @test
   */
  public function getKinderGebuehrSumme_fuenfNullMitGutscheinBetrag_MehrereKinder() //Kinderkurs
  {
    // mehrere Kinder

    PostOperations::setVarValue('gutschein_betrag', 30); // wir stellen einen gutschein betrag von 30 euro ein
    $kGebBerKontext = new KursgebuehrBerechnungsKontext('221-TEST1', 3);
    $berechner = new GebuehrenElementRechnerFuenfNull();
    $kg = $this->testDataGutscheinKinderKurs1('221-TEST1');
    $berechner->setGebuehrenElement($kg);

    //kind 1
    $expected = 0; // das erste Kind zahlt nichts, also wird der Gutschein auf das Standardgebuehr angewendet
    $result = $berechner->getKindGebuehrSumme(1, $kGebBerKontext, $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);

    $expected = 10; // (30  - 20 => (Gutschein betrag - Kurs betrag))
    $result = $this->wkState->gutscheinBetragOffen;
    $this->assertEquals($expected, $result);

    //kind 2
    $expected = 10; // das zweite Kind zahlt 20 Euro und der gutschein betrag offen ist 10 Euro, also 20-10= 10
    $result = $berechner->getKindGebuehrSumme(2, $kGebBerKontext, $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);

    $expected = 0; // Gutschein ist zu diesem Zeitpunkt leer
    $result = $this->wkState->gutscheinBetragOffen;
    $this->assertEquals($expected, $result);

    //kind 3
    $expected = 20; // das dritte Kind zahlt den vollen Betrag, da der Gutschein leer ist
    $result = $berechner->getKindGebuehrSumme(3, $kGebBerKontext, $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);
  }

  /**
   * @covers GebuehrenElementRechnerFuenfNull::getGebuehrenSummeErmaessigt
   * @test
   */
  public function getGebuehrSumme_fuenfNullMitGutscheinBetrag_MehrereKurse() //Mehrere (normale) Kurse im Warenkorb
  {
    PostOperations::setVarValue('gutschein_betrag', 100);  //wir stellen einen gutschein betrag von 100 euro ein
    $kGebBerKontext1 = new KursgebuehrBerechnungsKontext('221-TEST1');
    $berechner = new GebuehrenElementRechnerFuenfNull();
    $kg = $this->testDataGutscheinKurs1('221-TEST1');
    $berechner->setGebuehrenElement($kg);
    $expected = 0; // Kurs 1 betrag = 20, Gutscheinbetrag = 100, erwarteter Kurs 1 gutschein betrag = 0 (20 - 100 = -80 => => ein negativer Betrag würde bedeuten,
    // dass der Kursbetrag leer ist => d.h. 0 )
    $result = $berechner->getGebuehrenSummeErmaessigt(1, $kGebBerKontext1, $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);

    $expected = 80; // Nach Anwendung des Gutscheins auf den ersten Kurs sollte der wkState gutscheinBetragOffen auf 80 gesetzt werden (100 - 20)
    $result = $this->wkState->gutscheinBetragOffen;
    $this->assertEquals($expected, $result);

    $kGebBerKontext2 = new KursgebuehrBerechnungsKontext('221-TEST2');
    $berechner = new GebuehrenElementRechnerFuenfNull();
    $kg = $this->testDataGutscheinKurs2('221-TEST2');
    $berechner->setGebuehrenElement($kg);
    $expected = 0; // Kurs 2 betrag = 40, Gutscheinbetrag = 80 (offener Betrag), erwarteter Gutscheinbetrag für Kurs 2 = 0 (40 - 80 = -40 => d.h. 0)
    $result = $berechner->getGebuehrenSummeErmaessigt(2, $kGebBerKontext2, $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);

    $expected = 40; //Nach der Anwendung des Gutscheins auf den zweiten Kurs sollte der wkState gutscheinBetragOffen 40 sein
    $result = $this->wkState->gutscheinBetragOffen;
    $this->assertEquals($expected, $result);

    $kGebBerKontext2 = new KursgebuehrBerechnungsKontext('221-TEST3');
    $berechner = new GebuehrenElementRechnerFuenfNull();
    $kg = $this->testDataGutscheinKurs3('221-TEST3');
    $berechner->setGebuehrenElement($kg);
    $expected = 0; // Kurs 3 betrag = 20, Gutscheinbetrag = 40 (offener Betrag), erwarteter Gutscheinbetrag für Kurs 3 = 0 (20 - 40 = -20 => d.h. 0)
    $result = $berechner->getGebuehrenSummeErmaessigt(3, $kGebBerKontext2, $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);

    $expected = 20; //Nach der Anwendung des Gutscheins auf den dritten Kurs sollte der wkState gutscheinBetragOffen 20 sein (40 - 20)
    $result = $this->wkState->gutscheinBetragOffen;
    $this->assertEquals($expected, $result);
  }

  /**
   * @covers GebuehrenElementRechnerFuenfNull::getGebuehrenSummeErmaessigt
   * @test
   */
  public function getGebuehrSumme_fuenfNullMitGutscheinBetrag_HigherGutscheinBetrag() //Normaler Kurs mit einem höheren Gutscheinbetrag als der Kurs;
  {
    PostOperations::setVarValue('gutschein_betrag', 30); //wir stellen einen gutschein betrag von 30 euro ein

    $this->wkState->gutscheinBetragOffen = 0.00;
    $kGebBerKontext = new KursgebuehrBerechnungsKontext('221-TEST1');
    $berechner = new GebuehrenElementRechnerFuenfNull();
    $kg = $this->testDataGutscheinKurs1('221-TEST1', 0);
    $berechner->setGebuehrenElement($kg);

    $expected = 0; //kurs betrag = 20, gutschein betrag = 30, erwarteter kurs betrag = 0 (20-30 = -10 => ein negativer Betrag würde bedeuten, dass der Kursbetrag leer ist => d.h. 0 )
    $result = $berechner->getGebuehrenSummeErmaessigt(1, $kGebBerKontext, $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);

    $expected = 10; // nachdem der gutschein angewendet wurde, sollte der gutscheinBetragOffen auf 10 Euro gesetzt werden (30 (gutschein) - 20 (Kurs) = 10)
    $result = $this->wkState->gutscheinBetragOffen;
    $this->assertEquals($expected, $result);
  }

  /**
   * @covers GebuehrenElementRechnerFuenfNull::getGebuehrenSummeErmaessigt
   * @test
   */
  public function getGebuehrSumme_fuenfNullMitGutscheinBetrag_EqualGutscheinBetrag() //Normaler Kurs mit gutschein betrag gleich dem Kurs betrag
  {
    PostOperations::setVarValue('gutschein_betrag', 20);  //wir stellen einen gutschein betrag von 20 euro ein
    $kGebBerKontext = new KursgebuehrBerechnungsKontext('221-TEST1');
    $berechner = new GebuehrenElementRechnerFuenfNull();
    $kg = $this->testDataGutscheinKurs1('221-TEST1', 0);
    $berechner->setGebuehrenElement($kg);
    $expected = 0; //kurs betrag = 20, gutschein betrag = 20, erwarteter kurs betrag = 0 (20-20)
    $result = $berechner->getGebuehrenSummeErmaessigt(1, $kGebBerKontext, $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);
  }

  /**
   * @covers GebuehrenElementRechnerFuenfNull::getGebuehrenSummeErmaessigt
   * @test
   */
  public function getGebuehrSumme_fuenfNullMitGutscheinBetrag_LowerGutscheinBetrag() //Normaler Kurs mit weniger Gutscheinbetrag als der Kursbetrag
  {
    PostOperations::setVarValue('gutschein_betrag', 5); //wir stellen einen gutschein betrag von 5 euro ein
    $kGebBerKontext = new KursgebuehrBerechnungsKontext('221-TEST1');
    $berechner = new GebuehrenElementRechnerFuenfNull();
    $kg = $this->testDataGutscheinKurs1('221-TEST1', 0);
    $berechner->setGebuehrenElement($kg);

    $expected = 15; //kurs betrag = 20, gutschein betrag = 5, erwarteter kurs betrag = 15 (20-5)
    $result = $berechner->getGebuehrenSummeErmaessigt(1, $kGebBerKontext, $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);
  }

  /**
   * @covers GebuehrenElementRechnerFuenfNull::getKindGebuehrSumme
   * @test
   */
  public function getKinderGebuehrSumme_fuenfNullFuerStaffelgebuehr_KinderKurse()
  {
    $berechner = new GebuehrenElementRechnerFuenfNull();
    $kg = $this->testKursDataFuerStaffelGebuehr('221-1234', 5);
    $berechner->setGebuehrenElement($kg);
    $expected = 61.20; //Standardgebuehr (0-6) TN: 61,20 (Standardgebühr) TeilMin5
    $result = $berechner->getKindGebuehrSumme(1, '', $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);
  }

  /**
   * @covers GebuehrenElementRechnerFuenfNull::getKindGebuehrSumme
   * @test
   */
  public function getKinderGebuehrSumme_fuenfNullFuerStaffelgebuehr_staffelgebuehrTeilMinForSecondStaffel_returnsStandardgebuehrAndSecondStaffel()
  {
    $berechner = new GebuehrenElementRechnerFuenfNull();
    $kg = $this->testKursDataFuerStaffelGebuehr('221-1234', 7);
    $berechner->setGebuehrenElement($kg);
    $expected = 43.20; //Staffelgebühr 7-8 TN: 43,20 (61,20 + -18 (Staffel 7-8)) TeilMin7
    $result = $berechner->getKindGebuehrSumme(1, '', $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);
  }

  /**
   * @covers GebuehrenElementRechnerFuenfNull::getKindGebuehrSumme
   * @test
   */
  public function getKinderGebuehrSumme_fuenfNullFuerStaffelgebuehr_staffelgebuehrTeilMinForThirdStaffel_returnsThirdStaffel()
  {
    $berechner = new GebuehrenElementRechnerFuenfNull();
    $kg = $this->testKursDataFuerStaffelGebuehr('221-1234', 10);
    $berechner->setGebuehrenElement($kg);
    $expected = 36; //Staffelgebühr 9-0 TN: 36 (61,20 + -25,20 (Staffel 9-0)) TeilMin10
    $result = $berechner->getKindGebuehrSumme(1, '1829', $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);
  }

  /**
   * @covers GebuehrenElementRechnerFuenfNull::getKindGebuehrSumme
   * @test
   */
  public function getKindGebuehrSumme_fuenfNullFuerStaffelGebuehrUndKinderZahlplanKombi_StaffelTriggered()
  {
    $berechner = new GebuehrenElementRechnerFuenfNull();

    $minTnTriggersStaffel = 7;
    $kg = $this->testKursDataKombiStaffelUndKinderZahlplaene('221-1234', $minTnTriggersStaffel);
    $berechner->setGebuehrenElement($kg);

    $noZahlplan = '';
    $expected = 60; // 60 + 10 (Kind 1-2) + -10 (Staffel 7-8)
    $result = $berechner->getKindGebuehrSumme(1, $noZahlplan, $this->wkKontext, $this->wkState);//Kind 1
    $this->assertEquals($expected, $result);

    $expected = 50;// 60 + -10 (Staffel 7-8)
    $result = $berechner->getKindGebuehrSumme(4, $noZahlplan, $this->wkKontext, $this->wkState);//Kind 4
    $this->assertEquals($expected, $result);

    $expected = 50;// 60 + -10 (Staffel 7-8)
    $result = $berechner->getKindGebuehrSumme(7, $noZahlplan, $this->wkKontext, $this->wkState);//Kind 7
    $this->assertEquals($expected, $result);
  }

  /**
   * @covers GebuehrenElementRechnerFuenfNull::getKindGebuehrSumme
   * @test
   */
  public function getKinderGebuehrSumme_fuenfNullFuerStaffelGebuehrUndKinderZahlplanKombi_BelowStaffel()
  {
    $berechner = new GebuehrenElementRechnerFuenfNull();

    $kg = $this->testKursDataKombiStaffelUndKinderZahlplaene('221-1234', 3);
    $berechner->setGebuehrenElement($kg);

    $noZahlplan = '';
    $expected = 70; //60 + 10 (Kinder 1-2)
    $result = $berechner->getKindGebuehrSumme(1, $noZahlplan, $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);

    $expected = 70; //60 + 10 (Kinder 1-2)
    $result = $berechner->getKindGebuehrSumme(2, $noZahlplan, $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);

    $expected = 60; //60
    $result = $berechner->getKindGebuehrSumme(4, $noZahlplan, $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);
  }

  /**
   * @covers GebuehrenElementRechnerFuenfNull::getKindGebuehrSumme
   * @test
   */
  public function getKinderGebuehrSumme_fuenfNullFuerStaffelGebuehrUndKinderZahlplanKombi_AboveStaffel()
  {
    $berechner = new GebuehrenElementRechnerFuenfNull();

    $kg = $this->testKursDataKombiStaffelUndKinderZahlplaene('221-1234', 9);
    $berechner->setGebuehrenElement($kg);

    $expected = 70; //60 + 10 (Kinder 1-2)
    $result = $berechner->getKindGebuehrSumme(1, '', $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);

    $expected = 70; //60 + 10 (Kinder 1-2)
    $result = $berechner->getKindGebuehrSumme(2, '', $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);

    $expected = 60; //60
    $result = $berechner->getKindGebuehrSumme(4, '', $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);
  }

  /**
   * @covers GebuehrenElementRechnerFuenfNull::getKindGebuehrSumme
   * @test
   */
  public function getKinderGebuehrSumme_fuenfNullFuerWeitereKinder_mitNegativGebuehr()
  {
    //kinderzahlplan mit negative gebuehr
    $berechner = new GebuehrenElementRechnerFuenfNull();
    $kg = $this->testKursDataFuerweitereKinderMitNegativGebuehr('221-1234', 7);
    $berechner->setGebuehrenElement($kg);
    $expected = 50;//50 (Standardgebühr)
    $result = $berechner->getKindGebuehrSumme(1, '', $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);

    $expected = 30;//50 + -20 (Kinder 2-0)
    $result = $berechner->getKindGebuehrSumme(2, '', $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);

    $expected = 30;//50 + -20 (Kinder 2-0)
    $result = $berechner->getKindGebuehrSumme(3, '', $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);
  }

  /**
   * @covers GebuehrenElementRechnerFuenfNull::getKindGebuehrSumme
   * @test
   */
  public function getKinderGebuehrSumme_fuenfNullFuerMindestensStandardgebuehrUndZusatsgebuehr_fuerEinzelkind()
  {
    //mindestgebuehr für standard gebuehr und zusatzgebühr für einzelkind
    $berechner = new GebuehrenElementRechnerFuenfNull();
    $kg = $this->testKursDataMindestensStandardGebuehrUndZusatzGebuehr('221-1234', 7);
    $berechner->setGebuehrenElement($kg);
    $expected = 30; // 30 (Standardgebühr)
    $result = $berechner->getKindGebuehrSumme(4, '', $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);

    $expected = 50; // 30 + 20 (Kind 1-1)
    $result = $berechner->getKindGebuehrSumme(1, '', $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);
  }

  /**
   * @covers GebuehrenElementRechnerFuenfNull::getKindGebuehrSumme
   * @test
   */
  public function getKinderGebuehrSumme_fuenfNullFuerLeerStandardGebuehrUndZusatzGebuehr_fuerEinzelKindUndWeitereKinder()
  {
    //leer für standard gebuehr und zusatzgebühr für einzelkind und weitere kinder
    $berechner = new GebuehrenElementRechnerFuenfNull();
    $kg = $this->testKursDataLeerStandardGebuehrUndZusatzGebuehr('221-1234', 7);
    $berechner->setGebuehrenElement($kg);
    $expected = 0; // 0
    $result = $berechner->getKindGebuehrSumme(0, '', $this->wkKontext, $this->wkState); //kein Kind
    $this->assertEquals($expected, $result);

    $expected = 50; // 0 (Standardgebühr)+ 50 (Kinder 1-1)
    $result = $berechner->getKindGebuehrSumme(1, '', $this->wkKontext, $this->wkState);// Kind 1
    $this->assertEquals($expected, $result);

    $expected = 30; // 0 (Standardgebühr) + 30 (Kinder 2-0)
    $result = $berechner->getKindGebuehrSumme(2, '', $this->wkKontext, $this->wkState); // Kind 2
    $this->assertEquals($expected, $result);
  }

  /**
   * @covers GebuehrenElementRechnerFuenfNull::getKindGebuehrSumme
   * @test
   */
  public function getKinderGebuehrSumme_fuenfNullFuerKindGeschwister()
  {
    $berechner = new GebuehrenElementRechnerFuenfNull();
    $kg = $this->testKursDataMitKindGeschwister('221-1234', 1);
    $berechner->setGebuehrenElement($kg);
    $expected = 20; // 20 (Standardgebühr)
    $result = $berechner->getKindGebuehrSumme(1, '', $this->wkKontext, $this->wkState); // für kind 1
    $this->assertEquals($expected, $result);

    $berechner = new GebuehrenElementRechnerFuenfNull();
    $kg = $this->testKursDataMitKindGeschwister('221-1234', 1);
    $berechner->setGebuehrenElement($kg);
    $expected = 36; // 20 (Standardgebühr) + 16 (Kind 2-0)
    $result = $berechner->getKindGebuehrSumme(2, '', $this->wkKontext, $this->wkState); // für kind 2
    $this->assertEquals($expected, $result);
  }

  /**
   * Liefert eine GebuehrenElementBase für einen Kinderkurs mit Staffelgebuehr und Kinderzahlplan
   * Standardgebühr (Kind) 60
   * Kinderzahlplan (Kind 1 - 2) 70 => (60 + 10)
   * Staffelgebühr (7 to 8 Tn) 50 => (60 + -10)
   */
  private function testKursDataKombiStaffelUndKinderZahlplaene($knr, $teilMin)
  {
    $kgs = array();

    $zps = array();
    $kz = new Kurszahlplan();
    $kz->knr = $knr;
    $kz->beschreibung = 'Staffel( 7 bis 8 TN)';
    $kz->webdarst = true;
    $kz->tn_von = 7;
    $kz->tn_bis = 8;
    $kz->id = 1828;
    $kz->zusatz = 'W';
    $zps[] = $kz;
    $kz = new Kurszahlplan();
    $kz->knr = $knr;
    $kz->beschreibung = 'Kinder Zahlplan';
    $kz->webdarst = true;
    $kz->tn_von = 1;
    $kz->tn_bis = 2;
    $kz->id = 1829;
    $kz->zusatz = 'K';
    $zps[] = $kz;

    //Standardgebuehr
    $kg = new Kursgebuehr();
    $kg->knr = $knr;
    $kg->gebart = 1;
    $kg->schluessel = 1;
    $kg->text = 'Kerngebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '60,00';
    $kg->betrag_ermaessigt = '18,00';
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;

    //ZP Staffel( 7 bis 8 TN)
    $kg = new Kursgebuehr();
    $kg->knr = \Kufer\Web\Classes\Api\Helpers\ZahlplanHelper::computeKnr($knr, '1828');
    $kg->gebart = 1;
    $kg->schluessel = 1;
    $kg->text = 'Kerngebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '-10,00';
    $kg->betrag_ermaessigt = '-10,00';
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;

    //ZP kind
    $kg = new Kursgebuehr();
    $kg->knr = \Kufer\Web\Classes\Api\Helpers\ZahlplanHelper::computeKnr($knr, '1829');
    $kg->gebart = 1;
    $kg->schluessel = 1;
    $kg->text = 'Kerngebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '10,00';
    $kg->betrag_ermaessigt = '10,00';
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;


    $result = new GebuehrenElementBase($knr);
    $result->setGebuehrensaetze($kgs);

    $result->setZahlplaene($zps);
    $result->setMwstSaetze(array(0 => 0));
    $result->setKurstyp('K');
    $result->setTeilMin($teilMin);

    return $result;
  }

  /**
   * Liefert eine GebuehrenElementBase für einen Kinderkurs mit Staffelgebuehr
   * Standardgebühr (Kind) 61,20 => (60 + 1,20)
   * Staffelgebühr (7 to 8 Tn) 43,20 => (61,20 + -18)
   * Staffelgebühr (9 to 0 Tn) 36 => (61,20 + -25.20)
   */
  private function testKursDataFuerStaffelGebuehr($knr, $teilMin)
  {
    $kgs = array();

    $zps = array();
    $kz = new Kurszahlplan();
    $kz->knr = $knr;
    $kz->beschreibung = 'Staffel( 7 bis 8 TN)';
    $kz->webdarst = true;
    $kz->tn_von = 7;
    $kz->tn_bis = 8;
    $kz->id = 1828;
    $kz->zusatz = 'W';
    $zps[] = $kz;
    $kz = new Kurszahlplan();
    $kz->knr = $knr;
    $kz->beschreibung = 'Staffel(ab 9 TN)';
    $kz->webdarst = true;
    $kz->tn_von = 9;
    $kz->tn_bis = 0;
    $kz->id = 1829;
    $kz->zusatz = 'W';
    $zps[] = $kz;

    //Standardgebuehr
    $kg = new Kursgebuehr();
    $kg->knr = $knr;
    $kg->gebart = 1;
    $kg->schluessel = 1;
    $kg->text = 'Kerngebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '60,00';
    $kg->betrag_ermaessigt = '18,00';
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;
    $kg = new Kursgebuehr();
    $kg->knr = $knr;
    $kg->gebart = 2;
    $kg->schluessel = 2;
    $kg->text = 'Prüfungsgebühr';
    $kg->ermaessigbar = false;
    $kg->betrag = '1,20';
    $kg->betrag_ermaessigt = '0';
    $kg->geb_ermaess = 'W';
    $kgs[] = $kg;

    //ZP Staffel( 7 bis 8 TN)
    $kg = new Kursgebuehr();
    $kg->knr = \Kufer\Web\Classes\Api\Helpers\ZahlplanHelper::computeKnr($knr, '1828');
    $kg->gebart = 1;
    $kg->schluessel = 1;
    $kg->text = 'Kerngebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '-18,00';
    $kg->betrag_ermaessigt = '-18,00';
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;

    //ZP Staffel(ab 9 TN)
    $kg = new Kursgebuehr();
    $kg->knr = \Kufer\Web\Classes\Api\Helpers\ZahlplanHelper::computeKnr($knr, '1829');
    $kg->gebart = 1;
    $kg->schluessel = 1;
    $kg->text = 'Kerngebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '-25,20';
    $kg->betrag_ermaessigt = '-25,20';
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;

    $result = new GebuehrenElementBase($knr);
    $result->setGebuehrensaetze($kgs);

    $result->setZahlplaene($zps);
    $result->setMwstSaetze(array(0 => 0));
    $result->setKurstyp('K');
    $result->setTeilMin($teilMin);

    return $result;
  }

  /**
   * Liefert eine GebuehrenElementBase für einen Kinderkurs mit einem Kinderzahlplan mit einem negativen gebuehr
   * Standardgebühr (Erste Kind) 50
   * Kinderzahlplangebühr (Kinder 2-0) 30 => (50 + -20)
   */
  private function testKursDataFuerWeitereKinderMitNegativGebuehr($knr, $teilMin)
  {
    $kgs = array();

    $zps = array();
    $kz = new Kurszahlplan();
    $kz->knr = $knr;
    $kz->beschreibung = 'KinderZahlplan';
    $kz->webdarst = true;
    $kz->tn_von = 2;
    $kz->tn_bis = 0;
    $kz->id = 1828;
    $kz->zusatz = 'K';
    $zps[] = $kz;

    //Standardgebuehr
    $kg = new Kursgebuehr();
    $kg->knr = $knr;
    $kg->gebart = 1;
    $kg->schluessel = 1;
    $kg->text = 'Kerngebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '50';
    $kg->betrag_ermaessigt = false;
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;

    //Negativ Betrag für KinderZahlplan
    $kg = new Kursgebuehr();
    $kg->knr = \Kufer\Web\Classes\Api\Helpers\ZahlplanHelper::computeKnr($knr, '1828');
    $kg->gebart = 1;
    $kg->schluessel = 1;
    $kg->text = 'Kerngebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '-20,00';
    $kg->betrag_ermaessigt = '-20,00';
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;

    $result = new GebuehrenElementBase($knr);
    $result->setGebuehrensaetze($kgs);

    $result->setZahlplaene($zps);
    $result->setMwstSaetze(array(0 => 0));
    $result->setKurstyp('K');
    $result->setTeilMin($teilMin);

    return $result;
  }

  /**
   * Liefert eine GebuehrenElementBase für einen Kinderkurs mit einem Kinderzahlplan für einzelkind
   * Standardgebühr 30
   * Kinderzahlplangebühr (Kinder 1-1) 50 => (30 + 20)
   */
  private function testKursDataMindestensStandardGebuehrUndZusatzGebuehr($knr, $teilMin)
  {
    $kgs = array();

    $zps = array();
    $kz = new Kurszahlplan();
    $kz->knr = $knr;
    $kz->beschreibung = 'Einzelkind';
    $kz->webdarst = true;
    $kz->tn_von = 1;
    $kz->tn_bis = 1;
    $kz->id = 1828;
    $kz->zusatz = 'K';
    $zps[] = $kz;

    //Standardgebuehr
    $kg = new Kursgebuehr();
    $kg->knr = $knr;
    $kg->gebart = 1;
    $kg->schluessel = 1;
    $kg->text = 'Kerngebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '30,00';
    $kg->betrag_ermaessigt = false;
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;

    //einzelkind
    $kg = new Kursgebuehr();
    $kg->knr = \Kufer\Web\Classes\Api\Helpers\ZahlplanHelper::computeKnr($knr, '1828');
    $kg->gebart = 1;
    $kg->schluessel = 1;
    $kg->text = 'Kerngebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '20,00';
    $kg->betrag_ermaessigt = false;
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;

    $result = new GebuehrenElementBase($knr);
    $result->setGebuehrensaetze($kgs);

    $result->setZahlplaene($zps);
    $result->setMwstSaetze(array(0 => 0));
    $result->setKurstyp('K');
    $result->setTeilMin($teilMin);

    return $result;
  }

  /**
   * Liefert eine GebuehrenElementBase für einen Kinderkurs mit leeren Standardgebühr und
   * zusätzlichen Gebuehren für das einzelne Kind und weitere Kinder
   * Standardgebühr 0
   * Kinderzahlplangebühr (Kind 1-1) 50 => (0 + 50)
   * Kinderzahlplangebühr (Kinder 2-0) 30 => (0 + 30)
   */
  private function testKursDataLeerStandardGebuehrUndZusatzGebuehr($knr, $teilMin)
  {
    $kgs = array();

    $zps = array();
    $kz = new Kurszahlplan();
    $kz->knr = $knr;
    $kz->beschreibung = 'EinzelKind';
    $kz->webdarst = true;
    $kz->tn_von = 1;
    $kz->tn_bis = 1;
    $kz->id = 1828;
    $kz->zusatz = 'K';
    $zps[] = $kz;
    $kz = new Kurszahlplan();
    $kz->knr = $knr;
    $kz->beschreibung = 'weitere Kinder';
    $kz->webdarst = true;
    $kz->tn_von = 2;
    $kz->tn_bis = 0;
    $kz->id = 1829;
    $kz->zusatz = 'K';
    $zps[] = $kz;

    //Standardgebuehr
    $kg = new Kursgebuehr();
    $kg->knr = $knr;
    $kg->gebart = 1;
    $kg->schluessel = 1;
    $kg->text = 'Kerngebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '0,00';
    $kg->betrag_ermaessigt = false;
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;

    //ZP einzelkind
    $kg = new Kursgebuehr();
    $kg->knr = \Kufer\Web\Classes\Api\Helpers\ZahlplanHelper::computeKnr($knr, '1828');
    $kg->gebart = 1;
    $kg->schluessel = 1;
    $kg->text = 'Kerngebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '50,00';
    $kg->betrag_ermaessigt = false;
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;

    //ZP weitere teilnehmer
    $kg = new Kursgebuehr();
    $kg->knr = \Kufer\Web\Classes\Api\Helpers\ZahlplanHelper::computeKnr($knr, '1829');
    $kg->gebart = 1;
    $kg->schluessel = 1;
    $kg->text = 'Kerngebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '30';
    $kg->betrag_ermaessigt = false;
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;


    $result = new GebuehrenElementBase($knr);
    $result->setGebuehrensaetze($kgs);

    $result->setZahlplaene($zps);
    $result->setMwstSaetze(array(0 => 0));
    $result->setKurstyp('K');
    $result->setTeilMin($teilMin);

    return $result;
  }

  /**
   * Liefert eine GebuehrenElementBase für einen Kinderkurs mit Geschwister kinderzahlplan
   * Standardgebühr 20 (das erste Kind muss die Standardgebühr bezahlen)
   * Kinderzahlplangebühr (Kind 2-0) 36 => (20 + 16)
   */
  private function testKursDataMitKindGeschwister($knr, $teilMin)
  {
    $kgs = array();

    $zps = array();
    $kz = new Kurszahlplan();
    $kz->knr = $knr;
    $kz->beschreibung = 'Erste Kind Gebuehr';
    $kz->webdarst = true;
    $kz->tn_von = 1;
    $kz->tn_bis = 1;
    $kz->id = 1828;
    $kz->zusatz = 'K';
    $zps[] = $kz;

    $zps = array();
    $kz = new Kurszahlplan();
    $kz->knr = $knr;
    $kz->beschreibung = 'Geschwister Gebuehr';
    $kz->webdarst = true;
    $kz->tn_von = 2;
    $kz->tn_bis = 0;
    $kz->id = 1829;
    $kz->zusatz = 'K';
    $zps[] = $kz;

    //Standardgebuehr
    $kg = new Kursgebuehr();
    $kg->knr = $knr;
    $kg->gebart = 1;
    $kg->schluessel = 1;
    $kg->text = 'Kerngebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '20,00';
    $kg->betrag_ermaessigt = false;
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;


    //ZP geschwister
    $kg = new Kursgebuehr();
    $kg->knr = \Kufer\Web\Classes\Api\Helpers\ZahlplanHelper::computeKnr($knr, '1829');
    $kg->gebart = 1;
    $kg->schluessel = 1;
    $kg->text = 'Kerngebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '16,00';
    $kg->betrag_ermaessigt = false;
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;

    $result = new GebuehrenElementBase($knr);
    $result->setGebuehrensaetze($kgs);

    $result->setZahlplaene($zps);
    $result->setMwstSaetze(array(0 => 0));
    $result->setKurstyp('K');
    $result->setTeilMin($teilMin);

    return $result;
  }

  /**
   * @covers GebuehrenElementRechnerFuenfNull::getKindGebuehrErmaessigtSumme
   * @test
   */
  public function fassadeFuenfNullBerechneKinderGebuehrErmaessigt()
  {
    //Kind 1
    $berechner = new GebuehrenElementRechnerFuenfNull();
    $kg = $this->initEKKursKomplex('201-103005');
    $berechner->setGebuehrenElement($kg);
    $expected = 4.45;
    $kind = new KursgebuehrBerechnungsKontextTeilnehmer(20, -1, false, 2);
    $result = $berechner->getKindGebuehrErmaessigtSumme(1, $kind, $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);

    //Kind2
    $expected = 3.33;
    $kind = new KursgebuehrBerechnungsKontextTeilnehmer(25, -1, false, 2);
    $result = $berechner->getKindGebuehrErmaessigtSumme(2, $kind, $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);

    //Kind3
    $expected = 3.33;
    $kind = new KursgebuehrBerechnungsKontextTeilnehmer(0, -1, false, 2);
    $result = $berechner->getKindGebuehrErmaessigtSumme(3, $kind, $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);
  }

  /**
   * @covers GebuehrenElementRechnerFuenfNull::getKindGebuehrSumme
   * @test
   */
  public function fassadeFuenfNullBerechneKinderGebuehr_sameInstance()
  {
    //Kind 1
    $berechner = new GebuehrenElementRechnerFuenfNull();
    $kg = $this->initEKKursKomplex('201-103005');
    $berechner->setGebuehrenElement($kg);
    $expected = 5.56;
    $result = $berechner->getKindGebuehrSumme(1, '', $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);

    //Kind2
    $expected = 4.44;
    $result = $berechner->getKindGebuehrSumme(2, '', $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);

    //Kind3
    $expected = 3.33;
    $result = $berechner->getKindGebuehrSumme(3, '', $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);
  }

  //////////////////////// 4.20 ///////////////////////////////////////////

  /**
   * Testet, dass von einem Kurs mit x Zahlplänen und Kursgebühren die Standardgebühr korrekt berechnet wird.
   * @covers GebuehrenElementVisitorFilterByZahlplan::accept
   * @test
   */
  public function berechneStandardTnGebuehr_420()
  {
    System::$enforceKuferSqlVersion = 400;
    $kg = $this->initKinderKursStdGebUndKindGeb_420();

    $parts = $kg->getGebuehrensaetze();
    $this->assertEquals(2, count($parts));

    $zpId = '';
    $visitKeinZp = new GebuehrenElementVisitorFilterByZahlplan($zpId);
    $kg->accept($visitKeinZp);
    $parts = $kg->getGebuehrensaetze();
    $this->assertEquals(2, count($parts));
    $expectedZpKnr = $kg->getKnr();
    $this->assertEquals($expectedZpKnr, $parts[0]->knr);
    $this->assertEquals($expectedZpKnr, $parts[1]->knr);
    $expectedSum = 125.26;
    $this->assertEquals($expectedSum, $kg->getSum());
  }

  /**
   * Testet, dass von einem Kurs mit Standardgebühr die Gebühr fürs erste Kind korrekt berechnet wird.
   * @covers GebuehrenElementVisitorVierZwanzigSelectKind::accept
   * @test
   */
  public function berechneStandardKinderGebuehr_Kind1_420()
  {
    System::$enforceKuferSqlVersion = 400;
    $kg = $this->initKinderKursStdGebUndKindGeb_420();

    $parts = $kg->getGebuehrensaetze();
    $this->assertEquals(2, count($parts));

    $visitKind1 = new GebuehrenElementVisitorVierZwanzigSelectKind(1);
    $kg->accept($visitKind1);
    $parts = $kg->getGebuehrensaetze();
    $this->assertEquals(0, count($parts));
    $expectedSum = 5.05;
    $this->assertEqualsWithDelta($expectedSum, $kg->getSum(), 0.001);
  }

  /**
   * Testet, dass von einem Kurs die Gebühr für die weiteren Kinder korrekt berechnet werden.
   * @covers GebuehrenElementVisitorVierZwanzigSelectKind::accept
   * @test
   */
  public function berechneStandardKinderGebuehr_weitereKinder_420()
  {
    System::$enforceKuferSqlVersion = 400;
    $kg = $this->initKinderKursStdGebUndKindGeb_420();

    $parts = $kg->getGebuehrensaetze();
    $this->assertEquals(2, count($parts));

    $visitKind1 = new GebuehrenElementVisitorVierZwanzigSelectKind(2);
    $kg->accept($visitKind1);
    $parts = $kg->getGebuehrensaetze();
    $this->assertEquals(0, count($parts));
    $expectedSum = 1.01;
    $this->assertEqualsWithDelta($expectedSum, $kg->getSum(), 0.001);


    $visitKind1 = new GebuehrenElementVisitorVierZwanzigSelectKind(3);
    $kg->accept($visitKind1);
    $parts = $kg->getGebuehrensaetze();
    $this->assertEquals(0, count($parts));
    $expectedSum = 1.01;
    $this->assertEqualsWithDelta($expectedSum, $kg->getSum(), 0.001);
  }

  private function initKinderKursStdGebUndKindGeb_420()
  {
    $knr = '201-10300';
    $kg1 = new Kursgebuehr();
    $kg1->knr = $knr;
    $kg1->gebart = 1;
    $kg1->schluessel = 1;
    $kg1->text = 'Kerngebühr';
    $kg1->ermaessigbar = true;
    $kg1->geb_ermaess = 'F';
    $kg1->betrag = '100,01';
    $kg1->betrag_ermaessigt = '100,01';
    $kg2 = new Kursgebuehr();
    $kg2->knr = $knr;
    $kg2->gebart = 1;
    $kg2->schluessel = 1;
    $kg2->text = 'Kerngebühr';
    $kg2->ermaessigbar = true;
    $kg2->geb_ermaess = 'F';
    $kg2->betrag = '25,25';
    $kg2->betrag_ermaessigt = '25,25';
    $kg = new GebuehrenElementVierZwanzig($knr);
    $kg->setGebuehrensaetze(array($kg1, $kg2));
    $kg->setZahlplaene(array());
    $kg->setMwstSaetze(array(0 => 0));
    $kg->setKurstyp('K');
    $kg->setTeilMin(10);
    $k = new Kurs();
    $k->id = $knr;
    $k->geb_kind = '5,05';
    $k->geb_zuskind = '1,01';
    $kg->setKurs($k);

    return $kg;
  }

  /**
   * @covers GebuehrenElementRechnerFuenfNull::getKindGebuehrSumme
   * @test
   */
  public function fassadeVierZwanzigBerechneKinderGebuehr_sameInstance()
  {
    System::$enforceKuferSqlVersion = 400;
    //Kind 1
    $berechner = new GebuehrenElementRechnerVierZwanzig();
    $kg = $this->initEKKursKomplex_420('201-103005');
    $berechner->setGebuehrenElement($kg);
    $expected = 3.03;
    $result = $berechner->getKindGebuehrSumme(1, '', $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);

    //Kind2
    $expected = 5.55;
    $result = $berechner->getKindGebuehrSumme(2, '', $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);

    //Kind3
    $expected = 5.55;
    $result = $berechner->getKindGebuehrSumme(3, '', $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);
  }

  /**
   * @covers GebuehrenElementRechnerFuenfNull::getKindGebuehrSummeErmaessigt
   * @test
   */
  public function fassadeVierZwanzigBerechneKinderGebuehrErmaessigt()
  {
    //aktueller Stand: Kindergebühren werden nicht ermäßigt
    System::$enforceKuferSqlVersion = 400;
    //Kind 1
    $berechner = new GebuehrenElementRechnerVierZwanzig();
    $kg = $this->initEKKursKomplex_420('201-103005');
    $berechner->setGebuehrenElement($kg);
    $expected = 3.03;

    $kind = new KursgebuehrBerechnungsKontextTeilnehmer(33, -1, false, 2);
    $result = $berechner->getKindGebuehrErmaessigtSumme(1, $kind, $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);

    //Kind2
    $expected = 5.55;
    $kind = new KursgebuehrBerechnungsKontextTeilnehmer(10, -1, false, 2);
    $result = $berechner->getKindGebuehrErmaessigtSumme(2, $kind, $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);

    //Kind3
    $expected = 5.55;
    $kind = new KursgebuehrBerechnungsKontextTeilnehmer(0, -1, false, 2);
    $result = $berechner->getKindGebuehrErmaessigtSumme(3, $kind, $this->wkKontext, $this->wkState);
    $this->assertEquals($expected, $result);
  }

  /**
   * @param string $knr
   * @return \GebuehrenElementBase
   */
  private function initEKKursKomplex_420($knr)
  {
    $kgs = array();

    //Standardgebuehr
    $kg = new Kursgebuehr();
    $kg->knr = $knr;
    $kg->gebart = 1;
    $kg->schluessel = 1;
    $kg->text = 'Kerngebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '50,05';
    $kg->betrag_ermaessigt = '50,05';
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;
    $kg = new Kursgebuehr();
    $kg->knr = $knr;
    $kg->gebart = 1;
    $kg->schluessel = 2;
    $kg->text = 'Kerngebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '10,01';
    $kg->betrag_ermaessigt = '10,01';
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;

    //ZP 1 - TN: Mitglieder A
    $kg = new Kursgebuehr();
    $kg->knr = \Kufer\Web\Classes\Api\Helpers\ZahlplanHelper::computeKnr($knr, '1525');
    $kg->gebart = 1;
    $kg->schluessel = 1;
    $kg->text = 'Kerngebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '40,04';
    $kg->betrag_ermaessigt = '40,04';
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;

    //ZP 2 - TN: Mitglieder B
    $kg = new Kursgebuehr();
    $kg->knr = \Kufer\Web\Classes\Api\Helpers\ZahlplanHelper::computeKnr($knr, '1526');
    $kg->gebart = 1;
    $kg->schluessel = 1;
    $kg->text = 'Kerngebühr';
    $kg->ermaessigbar = true;
    $kg->betrag = '30,03';
    $kg->betrag_ermaessigt = '30,03';
    $kg->geb_ermaess = 'F';
    $kgs[] = $kg;

    $result = new GebuehrenElementVierZwanzig($knr);
    $result->setGebuehrensaetze($kgs);
    $result->setZahlplaene(array());
    $result->setMwstSaetze(array(0 => 0));
    $result->setKurstyp('L');
    $result->setTeilMin(10);

    $kurs = new Kurs();
    $kurs->id = $knr;
    $kurs->geb_kind = '3,03';
    $kurs->geb_zuskind = '5,55';
    $result->setKurs($kurs);

    return $result;
  }

  /**
   * @covers GebuehrenElementVisitorFilterByZahlplan::accept
   * @test
   */
  public function filterKollegenrabatt()
  {
    $kg = $this->initKollegenrabatt();
    $parts = $kg->getGebuehrensaetze();
    $this->assertEquals(2, count($parts));
    $this->assertEquals(110.00, $kg->getSum());//Summe über beide Zahlpläne

    $visitKeinZp = new GebuehrenElementVisitorApplyKollegenrabatt();
    $kg->accept($visitKeinZp);
    $parts = $kg->getGebuehrensaetze();
    $this->assertEquals(2, count($parts));
    $this->assertEquals(100.00, $kg->getSum());
  }

  /**
   * @covers GebuehrenElementVisitorApplyErmaessigungProz::accept
   * @test
   */
  public function visitorKursbezogeneErm()
  {
    $kg = $this->initKollegenrabatt();
    $visitErm = new GebuehrenElementVisitorApplyErmaessigungProz(0, true, 2);
    $kg->accept($visitErm);
    $this->assertEquals(99.00, $kg->getSum());
  }

  private function initKollegenrabatt()
  {
    $knr = '191-100110';
    $kg1 = new Kursgebuehr();
    $kg1->knr = $knr;
    $kg1->gebart = 1;
    $kg1->schluessel = 1;
    $kg1->text = 'Kerngebühr';
    $kg1->ermaessigbar = true;
    $kg1->geb_ermaess = 'F';
    $kg1->betrag = '10,00';
    $kg1->betrag_ermaessigt = '9,00';
    $kg1->mit_faktor = 'F';
    $kg2 = new Kursgebuehr();
    $kg2->knr = $knr;
    $kg2->gebart = 100;
    $kg2->schluessel = 2;
    $kg2->text = 'Kollegenrabatt standard';
    $kg2->ermaessigbar = true;
    $kg2->geb_ermaess = 'F';
    $kg2->betrag = '100,00';
    $kg2->betrag_ermaessigt = '90,00';
    $kg2->mit_faktor = 'K';
    $kg = new GebuehrenElementBase($knr);
    $kg->setGebuehrensaetze(array($kg1, $kg2));
    $kg->setZahlplaene(array());
    $kg->setMwstSaetze(array(0 => 0));
    $kg->setKurstyp('');
    $kg->setTeilMin(10);

    return $kg;
  }

  /**
   * @covers GebuehrenBerechnung::berechneGebuehrenSumme
   * @test
   */
  public function GebuehrenBerechnung_basic()
  {
    $berechnung = new GebuehrenBerechnung(true);
    $knr = '191-100110';

    $kGebBerKontext = new KursgebuehrBerechnungsKontext($knr, 0, true);
    $loader = new KursgebuehrBerechnungsKontextLaderInjected(array($kGebBerKontext));
    $berechnung->setBerechnungsKontexte($loader->load());

    $gebElement = $this->initKollegenrabatt();
    $gebuehrenLoader = new KursgebuehrElementeLaderInjected();
    $gebuehrenLoader->addGebuehrenElement($knr, $gebElement);
    $berechnung->loadKursgebuehrenElemente($gebuehrenLoader);

    $sum = $berechnung->berechneGebuehrenSumme();
    $expected = 110;
    $this->assertEquals($expected, $sum);
  }

  /**
   * @covers GebuehrenBerechnung::berechneGebuehrenSumme
   * @test
   */
  public function GebuehrenBerechnung_basic_mitGutschein() //basic GebuehrenBerechnung wenn ein gutschein angewendet wird
  {
    PostOperations::setVarValue('gutschein_betrag', 40); //wir stellen einen gutschein betrag von 40 euro ein

    $berechnung = new GebuehrenBerechnung(true);
    $knr = '221-TEST1';

    $kGebBerKontext = new KursgebuehrBerechnungsKontext($knr, 0, true);
    $loader = new KursgebuehrBerechnungsKontextLaderInjected(array($kGebBerKontext));
    $berechnung->setBerechnungsKontexte($loader->load());

    $gebElement = $this->initKollegenrabatt();
    $gebuehrenLoader = new KursgebuehrElementeLaderInjected();
    $gebuehrenLoader->addGebuehrenElement($knr, $gebElement);
    $berechnung->loadKursgebuehrenElemente($gebuehrenLoader);

    $sum = $berechnung->berechneGebuehrenSumme();
    $expected = 70; // 110 - 40
    $this->assertEquals($expected, $sum);
  }

  /**
   * @covers GebuehrenBerechnung::berechneGebuehrenSumme
   * @test
   */
  public function GebuehrenBerechnung_kursbezogeneErm()
  {
    $berechnung = new GebuehrenBerechnung(true);
    $knr = '191-100110';

    $tns = array(new KursgebuehrBerechnungsKontextTeilnehmer(0, -1, true));
    $kGebBerKontext = new KursgebuehrBerechnungsKontext($knr);
    $kGebBerKontext->tns = $tns;
    $loader = new KursgebuehrBerechnungsKontextLaderInjected(array($kGebBerKontext));
    $berechnung->setBerechnungsKontexte($loader->load());

    $gebElement = $this->initKollegenrabatt();
    $gebuehrenLoader = new KursgebuehrElementeLaderInjected();
    $gebuehrenLoader->addGebuehrenElement($knr, $gebElement);
    $berechnung->loadKursgebuehrenElemente($gebuehrenLoader);

    $sum = $berechnung->berechneGebuehrenSumme();
    $expected = 99;
    $this->assertEquals($expected, $sum);
  }

  /**
   * @covers GebuehrenBerechnung::berechneGebuehrenSumme
   * @test
   */
  public function GebuehrenBerechnung_kursbezogeneErm_MitGutschein() //Ermäßigung zusammen mit dem Gutscheinbetrag
  {
    PostOperations::setVarValue('gutschein_betrag', 40); //wir stellen einen gutschein betrag von 40 euro ein
    $berechnung = new GebuehrenBerechnung(true);
    $knr = '221-TEST1';

    $tns = array(new KursgebuehrBerechnungsKontextTeilnehmer(0, -1, true));
    $kGebBerKontext = new KursgebuehrBerechnungsKontext($knr);
    $kGebBerKontext->tns = $tns;
    $loader = new KursgebuehrBerechnungsKontextLaderInjected(array($kGebBerKontext));
    $berechnung->setBerechnungsKontexte($loader->load());

    $gebElement = $this->initKollegenrabatt();
    $gebuehrenLoader = new KursgebuehrElementeLaderInjected();
    $gebuehrenLoader->addGebuehrenElement($knr, $gebElement);
    $berechnung->loadKursgebuehrenElemente($gebuehrenLoader);

    $sum = $berechnung->berechneGebuehrenSumme();
    $expected = 59; //Kerngebühr ermässigte betrag = 9,  Kollegenrabatt standard ermässigte betrag = 90, gutschein betrag = 40 => 9 + 90 -40 = 59
    $this->assertEquals($expected, $sum);
  }

  /**
   * Prüft ab ob die Ermäßigung verworfen wird wenn der Kollegenrabatt zutrifft
   * @covers GebuehrenBerechnung::berechneGebuehrenSumme
   * @test
   */
  public function GebuehrenBerechnung_kollegenrabattErmaessigung()
  {
    $berechnung = new GebuehrenBerechnung(true);
    $knr = '191-100110';

    $tns = array(
      new KursgebuehrBerechnungsKontextTeilnehmer(50),
      new KursgebuehrBerechnungsKontextTeilnehmer(0)
    );
    $kGebBerKontext = new KursgebuehrBerechnungsKontext($knr, 0, true);
    $kGebBerKontext->tns = $tns;
    $loader = new KursgebuehrBerechnungsKontextLaderInjected(array($kGebBerKontext));
    $berechnung->setBerechnungsKontexte($loader->load());

    $gebElement = $this->initKollegenrabatt();
    $gebuehrenLoader = new KursgebuehrElementeLaderInjected();
    $gebuehrenLoader->addGebuehrenElement($knr, $gebElement);
    $berechnung->loadKursgebuehrenElemente($gebuehrenLoader);

    $sum = $berechnung->berechneGebuehrenSumme();
    $expected = 210;
    $this->assertEquals($expected, $sum);
  }

  /**
   * Prüft ab ob die Ermäßigung verworfen wird wenn der Kollegenrabatt zutrifft
   * @covers GebuehrenBerechnung::berechneGebuehrenSumme
   * @test
   */
  public function GebuehrenBerechnung_kollegenrabattErmaessigung_MitGutschein() //Gutscheinbetrag mit Ermäßigung (Kollegenrabatt)
  {
    PostOperations::setVarValue('gutschein_betrag', 20); //wir stellen einen gutschein betrag von 20 euro ein
    $this->wkState->gutscheinBetragOffen = 0.00;

    $berechnung = new GebuehrenBerechnung(true);
    $knr = '221-TEST1';

    $tns = array(
      new KursgebuehrBerechnungsKontextTeilnehmer(50),
      new KursgebuehrBerechnungsKontextTeilnehmer(0)
    );
    $kGebBerKontext = new KursgebuehrBerechnungsKontext($knr, 0, true);
    $kGebBerKontext->tns = $tns;
    $loader = new KursgebuehrBerechnungsKontextLaderInjected(array($kGebBerKontext));
    $berechnung->setBerechnungsKontexte($loader->load());

    $gebElement = $this->initKollegenrabatt();
    $gebuehrenLoader = new KursgebuehrElementeLaderInjected();
    $gebuehrenLoader->addGebuehrenElement($knr, $gebElement);
    $berechnung->loadKursgebuehrenElemente($gebuehrenLoader);

    $sum = $berechnung->berechneGebuehrenSumme();
    $expected = 190; //210 - 20
    $this->assertEquals($expected, $sum);
  }

  private function initKursgebuehr_simple(string $knr, string $betrag, bool $isKuferSql5)
  {
    $kg = $this->getKursgebuehrSimple($knr, $betrag);
    if ($isKuferSql5) {
      $gebElem = new GebuehrenElementBase($knr);
    } else {
      $gebElem = new GebuehrenElementVierZwanzig($knr);
      $kurs = new Kurs();
      $kurs->id = $knr;
      $kurs->geb_kind = '10,00';
      $kurs->geb_zuskind = '2,00';
      $gebElem->setKurs($kurs);
    }
    $gebElem->setGebuehrensaetze(array($kg));
    $gebElem->setZahlplaene(array());
    $gebElem->setMwstSaetze(array(0 => 0));
    $gebElem->setKurstyp('');
    $gebElem->setTeilMin(10);

    return $gebElem;
  }

  private function getKursgebuehrSimple(string $knr, string $betrag, ?int $ermaessigtVon = null)
  {
    $kg = new Kursgebuehr();
    $kg->knr = $knr;
    $kg->gebart = 1;
    $kg->bearbeiter = null;
    $kg->bearbdatum = null;
    $kg->faelligkeit = '';
    $kg->mwst = 0;
    $kg->fortlaufend = '';
    $kg->mit_faktor = 'F';
    $kg->schluessel = 1;
    $kg->text = 'Kerngebuehr';
    $kg->ermaessigbar = true;
    $kg->betrag = $betrag;
    $kg->betrag_ermaessigt = '10,00';
    $kg->konto = '4301';
    $kg->kostenst = '10';
    $kg->dp = 'F';
    $kg->id = '15731';
    $kg->geb_ermaess = 'F';
    $kg->ermaessigtVon = $ermaessigtVon;

    return $kg;
  }

  /**
   * @covers GebuehrenBerechnung::getGebuehrenSaetze
   * @test
   */
  public function GebuehrenBerechnung_GebuehrenSaetzeNoErm()
  {
    $knr = '201-0001';
    $gebuehrenSaetze = $this->GebuehrenBerechnung_GetGebuehrenSaetze($knr, 0);
    $expected = array(
      'tnSaetze' => array($this->getKursgebuehrSimple($knr, '39,99')),
      'kinderSaetze' => array()
    );
    $this->assertEquals($expected, $gebuehrenSaetze);
  }

  /**
   * @covers GebuehrenBerechnung::getGebuehrenSaetze
   * @test
   */
  public function GebuehrenBerechnung_GebuehrenSaetzeErm()
  {
    $knr = '201-0001';
    $gebuehrenSaetze = $this->GebuehrenBerechnung_GetGebuehrenSaetze($knr, 50);
    $expected = array(
      'tnSaetze' => array($this->getKursgebuehrSimple($knr, '19,99')),
      'kinderSaetze' => array()
    );
    $this->assertEquals($expected, $gebuehrenSaetze);
  }

  /**
   * @covers GebuehrenBerechnung::getGebuehrenSaetze
   * @test
   */
  public function GebuehrenBerechnung_GebuehrenSaetzeSpenden()
  {
    $knr = '201-0001';
    $isKuferSql5 = true;
    $berechnung = new GebuehrenBerechnung($isKuferSql5);
    $kGebBerKontext = new KursgebuehrBerechnungsKontext($knr);

    $gebart = new GebuehrArt();
    $gebart->schluessel = 5;
    $gebart->text = 'Spende';
    $gebart->ermaessigbar = false;
    $gebart->konto = '4200';
    $gebart->kostenst = '11';
    $gebart->dp = 'F';
    $gebart->mwst = '';
    $kGebBerKontext->spendeninfos = new SpendenFondInfos($gebart, 10.00);
    $loader = new KursgebuehrBerechnungsKontextLaderInjected(array($kGebBerKontext));
    $berechnung->setBerechnungsKontexte($loader->load());

    $gebElement = $this->initKursgebuehr_simple($knr, '39,99', $isKuferSql5);
    $gebuehrenLoader = new KursgebuehrElementeLaderInjected();
    $gebuehrenLoader->addGebuehrenElement($knr, $gebElement);
    $berechnung->loadKursgebuehrenElemente($gebuehrenLoader);

    $gebuehrenSaetze = $berechnung->getGebuehrenSaetze($knr);
    $spendenkg = new Kursgebuehr();
    $spendenkg->knr = $knr;
    $spendenkg->gebart = 5;
    $spendenkg->bearbeiter = null;
    $spendenkg->bearbdatum = null;
    $spendenkg->text = 'Spende';
    $spendenkg->ermaessigbar = false;
    $spendenkg->betrag = '10,00';
    $spendenkg->betrag_ermaessigt = '10,00';
    $spendenkg->konto = '4200';
    $spendenkg->kostenst = '11';
    $spendenkg->dp = 'F';
    $expected = array(
      'tnSaetze' => array(
        $this->getKursgebuehrSimple($knr, '39,99'),
        $spendenkg
      ),
      'kinderSaetze' => array()
    );
    $this->assertEquals($expected, $gebuehrenSaetze);
  }

  /**
   * @covers GebuehrenBerechnung::getGebuehrenSaetze
   * @test
   */
  public function GebuehrenBerechnung_GebuehrenSaetzeErmMehrereTn()
  {
    $knr = '201-0001';
    $isKuferSql5 = true;
    $berechnung = new GebuehrenBerechnung($isKuferSql5);
    $tns = array(
      new KursgebuehrBerechnungsKontextTeilnehmer(50, -1, false, 2),
      new KursgebuehrBerechnungsKontextTeilnehmer(0, -1, false, 0)
    );
    $kGebBerKontext = new KursgebuehrBerechnungsKontext($knr);
    $kGebBerKontext->tns = $tns;
    $loader = new KursgebuehrBerechnungsKontextLaderInjected(array($kGebBerKontext));
    $berechnung->setBerechnungsKontexte($loader->load());

    $gebElement = $this->initKursgebuehr_simple($knr, '39,99', $isKuferSql5);
    $gebuehrenLoader = new KursgebuehrElementeLaderInjected();
    $gebuehrenLoader->addGebuehrenElement($knr, $gebElement);
    $berechnung->loadKursgebuehrenElemente($gebuehrenLoader);

    $gebuehrenSaetze = $berechnung->getGebuehrenSaetze($knr);
    $expected = array(
      'tnSaetze' => array(
        $this->getKursgebuehrSimple($knr, '19,99', 2),
        $this->getKursgebuehrSimple($knr, '39,99')
      ),
      'kinderSaetze' => array()
    );
    $this->assertEquals($expected, $gebuehrenSaetze);
  }

  /**
   * @covers GebuehrenBerechnung::getGebuehrenSaetze
   * @test
   */
  public function GebuehrenBerechnung_GebuehrenSaetzeErmMehrereTnKinder_420()
  {
    System::$enforceKuferSqlVersion = 400;
    $knr = '201-0001';
    $isKuferSql5 = false;
    $berechnung = new GebuehrenBerechnung($isKuferSql5);
    $tns = array(
      new KursgebuehrBerechnungsKontextTeilnehmer(50, -1, false),
      new KursgebuehrBerechnungsKontextTeilnehmer(0, -1, false),
      new KursgebuehrBerechnungsKontextTeilnehmer(0, -1, false)
    );
    // 1 Hauptteilnehmer und 2 Kinder
    $kGebBerKontext = new KursgebuehrBerechnungsKontext($knr, 2);
    $kGebBerKontext->tns = $tns;
    $loader = new KursgebuehrBerechnungsKontextLaderInjected(array($kGebBerKontext));
    $berechnung->setBerechnungsKontexte($loader->load());

    $gebElement = $this->initKursgebuehr_simple($knr, '39,99', $isKuferSql5);
    $gebuehrenLoader = new KursgebuehrElementeLaderInjected();
    $gebuehrenLoader->addGebuehrenElement($knr, $gebElement);
    $berechnung->loadKursgebuehrenElemente($gebuehrenLoader);

    $gebuehrenSaetze = $berechnung->getGebuehrenSaetze($knr);
    $kg1 = new Kursgebuehr();
    $kg1->knr = $knr;
    $kg1->betrag = '10,00'; // siehe initKursgebuehr_simple im KursObjekt geb_kind
    $kg1->text = 'Aufschlag Kind';
    $kg2 = new Kursgebuehr();
    $kg2->knr = $knr;
    $kg2->betrag = '2,00'; // siehe initKursgebuehr_simple im KursObjekt geb_zuskind
    $kg2->text = 'Aufschlag Kind';
    $expected = array(
      'tnSaetze' => array(
        $this->getKursgebuehrSimple($knr, '19,99'),
        $this->getKursgebuehrSimple($knr, '39,99'),
        $this->getKursgebuehrSimple($knr, '39,99')
      ),
      'kinderSaetze' => array(
        $kg1,
        $kg2
      )
    );
    $this->assertEquals($expected, $gebuehrenSaetze);
  }

  /**
   * @covers GebuehrenBerechnung::berechneGebuehrenSumme
   * @test
   */
  public function GebuehrenBerechnung_basic_netto()
  {
    $berechnung = new GebuehrenBerechnung(true);
    $knr = '191-100110';

    $kGebBerKontext = new KursgebuehrBerechnungsKontext($knr);
    $kGebBerKontext->brutto = false;
    $loader = new KursgebuehrBerechnungsKontextLaderInjected(array($kGebBerKontext));
    $berechnung->setBerechnungsKontexte($loader->load());

    $gebElement = $this->initKursgebuehr_simple_mwst($knr, 120);
    $gebuehrenLoader = new KursgebuehrElementeLaderInjected();
    $gebuehrenLoader->addGebuehrenElement($knr, $gebElement);
    $berechnung->loadKursgebuehrenElemente($gebuehrenLoader);

    $sum = $berechnung->berechneGebuehrenSumme();
    $expected = 100;
    $this->assertEquals($expected, $sum);
  }

  /**
   * @covers GebuehrenBerechnung::berechneGebuehrenSumme
   * @test
   */
  public function GebuehrenBerechnung_pauschal_simple()
  {
    $berechnung = new GebuehrenBerechnung(true);
    $knr = '191-100110';

    $kGebBerKontext = new KursgebuehrBerechnungsKontext($knr);
    $loader = new KursgebuehrBerechnungsKontextLaderInjected(array($kGebBerKontext));
    $berechnung->setBerechnungsKontexte($loader->load());

    $gebElement = $this->initKursgebuehr_pauschal($knr);
    $gebuehrenLoader = new KursgebuehrElementeLaderInjected();
    $gebuehrenLoader->addGebuehrenElement($knr, $gebElement);
    $berechnung->loadKursgebuehrenElemente($gebuehrenLoader);

    $sum = $berechnung->berechneGebuehrenSumme();
    $expected = 110;
    $this->assertEquals($expected, $sum);
  }

  /**
   * @covers GebuehrenBerechnung::berechneGebuehrenSumme
   * @test
   */
  public function GebuehrenBerechnung_pauschal_mehrfach()
  {
    $berechnung = new GebuehrenBerechnung(true);
    $knr = '191-100110';

    $tns = array(
      new KursgebuehrBerechnungsKontextTeilnehmer(),
      new KursgebuehrBerechnungsKontextTeilnehmer()
    );
    $kGebBerKontext = new KursgebuehrBerechnungsKontext($knr);
    $kGebBerKontext->tns = $tns;
    $loader = new KursgebuehrBerechnungsKontextLaderInjected(array($kGebBerKontext));
    $berechnung->setBerechnungsKontexte($loader->load());

    $gebElement = $this->initKursgebuehr_pauschal($knr);
    $gebuehrenLoader = new KursgebuehrElementeLaderInjected();
    $gebuehrenLoader->addGebuehrenElement($knr, $gebElement);
    $berechnung->loadKursgebuehrenElemente($gebuehrenLoader);

    $sum = $berechnung->berechneGebuehrenSumme();
    $expected = 120;
    $this->assertEquals($expected, $sum);
  }

  /**
   * @covers GebuehrenBerechnung::berechneGebuehrenSumme
   * @test
   */
  public function GebuehrenBerechnung_pauschal_ohne_haupttn()
  {
    $berechnung = new GebuehrenBerechnung(true);
    $knr = '191-100110';

    $tns = array(
      new KursgebuehrBerechnungsKontextTeilnehmer(),
      new KursgebuehrBerechnungsKontextTeilnehmer()
    );
    $kGebBerKontext = new KursgebuehrBerechnungsKontext($knr);
    $kGebBerKontext->hauptTnAuch = false;
    $kGebBerKontext->tns = $tns;
    $loader = new KursgebuehrBerechnungsKontextLaderInjected(array($kGebBerKontext));
    $berechnung->setBerechnungsKontexte($loader->load());

    $gebElement = $this->initKursgebuehr_pauschal($knr);
    $gebuehrenLoader = new KursgebuehrElementeLaderInjected();
    $gebuehrenLoader->addGebuehrenElement($knr, $gebElement);
    $berechnung->loadKursgebuehrenElemente($gebuehrenLoader);

    $sum = $berechnung->berechneGebuehrenSumme();
    $expected = 220;
    $this->assertEquals($expected, $sum);
  }

  private function GebuehrenBerechnung_GetGebuehrenSaetze($knr, $ermProzent)
  {
    $isKuferSql5 = true;
    $berechnung = new GebuehrenBerechnung($isKuferSql5);

    $tns = array(new KursgebuehrBerechnungsKontextTeilnehmer($ermProzent, -1, false));
    $kGebBerKontext = new KursgebuehrBerechnungsKontext($knr);
    $kGebBerKontext->tns = $tns;
    $loader = new KursgebuehrBerechnungsKontextLaderInjected(array($kGebBerKontext));
    $berechnung->setBerechnungsKontexte($loader->load());

    $gebElement = $this->initKursgebuehr_simple($knr, '39,99', $isKuferSql5);
    $gebuehrenLoader = new KursgebuehrElementeLaderInjected();
    $gebuehrenLoader->addGebuehrenElement($knr, $gebElement);
    $berechnung->loadKursgebuehrenElemente($gebuehrenLoader);

    return $berechnung->getGebuehrenSaetze($knr);
  }

  private function initKursgebuehr_simple_mwst(string $knr, string $betrag)
  {
    $kg = $this->getKursgebuehrSimple($knr, $betrag);
    $kg->mwst = 1;
    $gebElem = new GebuehrenElementBase($knr);
    $gebElem->setGebuehrensaetze(array($kg));
    $gebElem->setZahlplaene(array());
    $gebElem->setMwstSaetze(array(1 => 20));
    $gebElem->setKurstyp('');
    $gebElem->setTeilMin(10);

    return $gebElem;
  }

  private function initKursgebuehr_pauschal(string $knr)
  {
    $kg1 = $this->getKursgebuehrSimple($knr, 100);
    $kg1->pauschalgebuehr = true;
    $kg2 = $this->getKursgebuehrSimple($knr, 10);
    $gebElem = new GebuehrenElementBase($knr);
    $gebElem->setGebuehrensaetze(array($kg1, $kg2));
    $gebElem->setZahlplaene(array());
    $gebElem->setMwstSaetze(array(0 => 0));
    $gebElem->setKurstyp('');
    $gebElem->setTeilMin(10);

    return $gebElem;
  }

  /**
   * @covers GebuehrenBerechnung::berechneGebuehrenSumme
   * @test
   */
  public function GebuehrenBerechnung_50_KinderKurs_2Kinder()
  {
    System::$enforceKuferSqlVersion = 500;
    $berechnung = new GebuehrenBerechnung(true);
    $knr = '192-2001';

    $tns = array(
      new KursgebuehrBerechnungsKontextTeilnehmer()
    );
    $kGebBerKontext = new KursgebuehrBerechnungsKontext($knr);
    $kGebBerKontext->hauptTnAuch = true;
    $kGebBerKontext->tns = $tns;
    $kGebBerKontext->kinderanzahl = 2;
    $loader = new KursgebuehrBerechnungsKontextLaderInjected(array($kGebBerKontext));
    $berechnung->setBerechnungsKontexte($loader->load());

    $gebElement = $this->init50KinderKurs($knr);
    $gebuehrenLoader = new KursgebuehrElementeLaderInjected();
    $gebuehrenLoader->addGebuehrenElement($knr, $gebElement);
    $berechnung->loadKursgebuehrenElemente($gebuehrenLoader);

    $sum = $berechnung->berechneGebuehrenSumme();
    $expected = 1030;
    $this->assertEquals($expected, $sum);
  }

  /**
   * @covers GebuehrenBerechnung::berechneGebuehrenSumme
   * @test
   */
  public function GebuehrenBerechnung_50_KinderKursMitKinderZahlplaenen_2Kinder()
  {
    System::$enforceKuferSqlVersion = 500;
    $berechnung = new GebuehrenBerechnung(true);
    $knr = '192-2001';

    $tns = array(
      new KursgebuehrBerechnungsKontextTeilnehmer()
    );
    $kGebBerKontext = new KursgebuehrBerechnungsKontext($knr);
    $kGebBerKontext->hauptTnAuch = true;
    $kGebBerKontext->tns = $tns;
    $kGebBerKontext->kinderanzahl = 2;
    $loader = new KursgebuehrBerechnungsKontextLaderInjected(array($kGebBerKontext));
    $berechnung->setBerechnungsKontexte($loader->load());

    $gebElement = $this->init50KinderKurs($knr, true);
    $gebuehrenLoader = new KursgebuehrElementeLaderInjected();
    $gebuehrenLoader->addGebuehrenElement($knr, $gebElement);
    $berechnung->loadKursgebuehrenElemente($gebuehrenLoader);

    $sum = $berechnung->berechneGebuehrenSumme();
    $expected = 1039.99;
    $this->assertEquals($expected, $sum);
  }

  private function init50KinderKurs($knr, $mitKinderZahlplaenen = false)
  {
    $kgs = array();

    //Standardgebuehr
    $kg = new Kursgebuehr();
    $kg->knr = $knr;
    $kg->gebart = 11;
    $kg->schluessel = 1;
    $kg->text = 'einmalige Anzahlung';
    $kg->geb_ermaess = 'W';//$this->getDatamodulValue('ermaessigbar');
    $kg->ermaessigbar = false;//$this->getDatamodulValue('ermaessigbar')=="F")
    $kg->betrag = '75,00';//$this->getDatamodulValue('gebuehr');
    $kg->betrag_ermaessigt = '0';//$this->getDatamodulValue('erm_geb');
    $kgs[] = $kg;
    $kg = new Kursgebuehr();
    $kg->knr = $knr;
    $kg->gebart = 13;
    $kg->schluessel = 2;
    $kg->text = 'Restzahlung';
    $kg->geb_ermaess = 'W';//$this->getDatamodulValue('ermaessigbar');
    $kg->ermaessigbar = false;//$this->getDatamodulValue('ermaessigbar')=="F")
    $kg->betrag = '430,00';//$this->getDatamodulValue('gebuehr');
    $kg->betrag_ermaessigt = '0';//$this->getDatamodulValue('erm_geb');
    $kgs[] = $kg;
    $kg = new Kursgebuehr();
    $kg->knr = $knr;
    $kg->gebart = 27;
    $kg->schluessel = 3;
    $kg->text = 'Kindergebühr';
    $kg->geb_ermaess = 'F';//$this->getDatamodulValue('ermaessigbar');
    $kg->ermaessigbar = true;//$this->getDatamodulValue('ermaessigbar')=="F")
    $kg->betrag = '10,00';//$this->getDatamodulValue('gebuehr');
    $kg->betrag_ermaessigt = '0';//$this->getDatamodulValue('erm_geb');
    $kgs[] = $kg;

    $zps = array();
    if ($mitKinderZahlplaenen) {
      $kz = new Kurszahlplan();
      $kz->knr = $knr;
      $kz->beschreibung = 'Gebühren Kind 1';
      $kz->webdarst = true;
      $kz->tn_von = 1;
      $kz->tn_bis = 1;
      $kz->zusatz = 'K';
      $kz->id = 1527;
      $zps[] = $kz;
      $kz = new Kurszahlplan();
      $kz->knr = $knr;
      $kz->beschreibung = 'Gebühren ab Kind 2';
      $kz->webdarst = true;
      $kz->tn_von = 2;
      $kz->tn_bis = 0;
      $kz->zusatz = 'K';
      $kz->id = 1528;
      $zps[] = $kz;

      //ZP Kinder 1
      $kg = new Kursgebuehr();
      $kg->knr = \Kufer\Web\Classes\Api\Helpers\ZahlplanHelper::computeKnr($knr, '1527');
      $kg->gebart = 1;
      $kg->schluessel = 1;
      $kg->text = 'Kerngebühr';
      $kg->ermaessigbar = true;
      $kg->betrag = '5,55';
      $kg->betrag_ermaessigt = '5,55';
      $kg->geb_ermaess = 'F';
      $kgs[] = $kg;

      //ZP Kinder 2
      $kg = new Kursgebuehr();
      $kg->knr = \Kufer\Web\Classes\Api\Helpers\ZahlplanHelper::computeKnr($knr, '1528');
      $kg->gebart = 1;
      $kg->schluessel = 1;
      $kg->text = 'Kerngebühr';
      $kg->ermaessigbar = true;
      $kg->betrag = '4,44';
      $kg->betrag_ermaessigt = '4,44';
      $kg->geb_ermaess = 'F';
      $kgs[] = $kg;
    }

    $ge = new GebuehrenElementBase($knr);
    $ge->setGebuehrensaetze($kgs);
    $ge->setMwstSaetze(array(0 => 0));
    $ge->setKurstyp('K');
    $ge->setZahlplaene($zps);
    $ge->setTeilMin(10);

    return $ge;
  }

  //?? Normale Mehrfachanmeldung bei Kinderkurs?
  //normaler Zahlplan + Kinderzahlplan für 1., 2. Kind

  /**
   * @covers GebuehrenBerechnung::berechneGebuehrenSumme
   * @test
   */
  public function berechneGebuehrenSumme_50_PersonalNrGegebenVsb_Rabatt()
  {
    \DBWorkBASysSettings::$TestEnforceVsb = true;
    $berechnung = new GebuehrenBerechnung(true);
    $knr = '191-100110';

    $kGebBerKontext = new KursgebuehrBerechnungsKontext($knr, 0, false, true, true, false, '25897');
    $loader = new KursgebuehrBerechnungsKontextLaderInjected(array($kGebBerKontext));
    $berechnung->setBerechnungsKontexte($loader->load());

    $gebElement = $this->initKursgebuehr_simple($knr, '39,99', true);
    $gebuehrenLoader = new KursgebuehrElementeLaderInjected();
    $gebuehrenLoader->addGebuehrenElement($knr, $gebElement);
    $berechnung->loadKursgebuehrenElemente($gebuehrenLoader);

    $sum = $berechnung->berechneGebuehrenSumme();
    $expected = 37.99;
    $this->assertEquals($expected, $sum);
  }

  /**
   * @covers GebuehrenBerechnung::berechneGebuehrenSumme
   * @test
   */
  public function berechneGebuehrenSumme_50_PersonalNrGegebenNichtVsb_KeinRabatt()
  {
    $berechnung = new GebuehrenBerechnung(true);
    $knr = '191-100110';

    $kGebBerKontext = new KursgebuehrBerechnungsKontext($knr, 0, false, true, true, false, '25897');
    $loader = new KursgebuehrBerechnungsKontextLaderInjected(array($kGebBerKontext));
    $berechnung->setBerechnungsKontexte($loader->load());

    $gebElement = $this->initKursgebuehr_simple($knr, '39,99', true);
    $gebuehrenLoader = new KursgebuehrElementeLaderInjected();
    $gebuehrenLoader->addGebuehrenElement($knr, $gebElement);
    $berechnung->loadKursgebuehrenElemente($gebuehrenLoader);

    $sum = $berechnung->berechneGebuehrenSumme();
    $expected = 39.99;
    $this->assertEquals($expected, $sum);
  }

  /**
   * @covers KursgebuehrBerechnungsKontext::isVsbMitgliederRabattApplicable
   * @test
   */
  public function isVsbMitgliederRabattApplicable_noVsbPersNrOkHauptTn_isNotApplicable()
  {
    $knr = '201-111';
    $sut = new \KursgebuehrBerechnungsKontext($knr);
    $sut->pers_nr = '123123123';
    $result = $sut->isVsbMitgliederRabattApplicable(0);
    $this->assertFalse($result);
  }

  /**
   * @covers KursgebuehrBerechnungsKontext::isVsbMitgliederRabattApplicable
   * @test
   */
  public function isVsbMitgliederRabattApplicable_VsbPersNrOkHauptTn_isApplicable()
  {
    \DBWorkBASysSettings::$TestEnforceVsb = true;
    $knr = '201-111';
    $sut = new \KursgebuehrBerechnungsKontext($knr);
    $sut->pers_nr = '123123123';
    $result = $sut->isVsbMitgliederRabattApplicable(0);
    $this->assertTrue($result);
  }

  /**
   * @covers KursgebuehrBerechnungsKontext::isVsbMitgliederRabattApplicable
   * @test
   */
  public function isVsbMitgliederRabattApplicable_VsbPersNrOkWeiterTn_isNotApplicable()
  {
    \DBWorkBASysSettings::$TestEnforceVsb = true;
    $knr = '201-111';
    $sut = new \KursgebuehrBerechnungsKontext($knr);
    $sut->pers_nr = '123123123';
    $result = $sut->isVsbMitgliederRabattApplicable(1);
    $this->assertFalse($result);
  }
}
