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

abstract class EPayBLZahlverfahren
{
  abstract protected function getZahlverfahren(): string;

  /**
   * Erzeugt die Buchungsliste, welche zum Start der Transaktion an ePayBL übergeben wird.
   * Darin enthalten sind alle relevanten Informationen für die Transaktion.
   * Darunter fallen beispielsweise:
   * - Buchungsinformationen (einzelne Positionen)
   * - Verwendungszweck (Beschreibung)
   * - Summe der Transaktion
   * - usw.
   * @param string $mtid Kufer-TransaktionsID (=Merchant Transaction ID)
   * @param float $betrag Entspricht der Gesamtsummer der Transaktion
   * @param array $buchungsinfos Die einzelnen Positionen zu dieser Transaktion
   * @param string $verwendungszweck Wird in das Feld "Beschreibung" übernommen. (ggf. auch als Kassenzeichennummer)
   * @param bool $kuferwebLiefertKassenzeichen Wenn true, wird der Verwendungszweck auch als Kassenzeichennummer gesetzt.
   * @return \EpayBL\Buchungsliste
   */
  public function createBuchungsliste(string $mtid, float $betrag, array $buchungsinfos, string $verwendungszweck, bool $kuferwebLiefertKassenzeichen = false): \EpayBL\Buchungsliste
  {
    $buchungsliste = new \EpayBL\Buchungsliste();
    $datetime = DateTimeOperations::getDateTimeNowExact();
    $buchungsliste->setFaelligkeitsdatum($datetime);
    $buchungsliste->setKennzeichenMahnverfahren('01'); // Default wert laut Fr. Olfert vom KRZ
    $buchungsliste->setZahlverfahrencodes(array($this->getZahlverfahren()));
    $buchungsliste->setBeschreibung($verwendungszweck);

    // Bisher nur für Aulendorf LAZBW programmiert!
    // Die Lieferung der Kassenzeichennummer durch das Fachverfahren (KuferWEB) muss am ePayBL-Mandanten konfiguriert sein!
    // Ansonsten kommt es zum Fehler beim übertragen der Buchungsliste.
    if (!empty($kuferwebLiefertKassenzeichen)) {
      $buchungsliste->setKassenzeichennummer($verwendungszweck);
    }

    $buchungen = array();
    foreach ($buchungsinfos as $buchungsinfo) {
      $buchungen[] = $this->createBuchung($buchungsinfo);
    }
    $buchungsliste->setBuchungen($buchungen);

    $kunde = new \EpayBL\Kunde();
    /* Auszug aus Mail von ePayBL (15.10.2020 11:32)
     * Kundennummer: Die ePayBL arbeitet nicht mit Kundendaten, diese werden direkt
     * zum Löschen markiert. Bei jeder Bestellung wird jedoch im Hintergrund eine
     * Art Kundennummer generiert.
     */
    $kunde->setKundennummer(\Kufer\Web\Classes\Addfunctions\Guid::generate()->__toString());
    $kunde->setTyp(\EpayBL\KundeTyp::TEMPORAER);
    $kunde->setName('Mustermann');
    $buchungsliste->setKunde($kunde);

    $fachverfahrendaten = $this->getFachverfahrenDaten($mtid);
    $buchungsliste->setFachverfahrendaten($fachverfahrendaten);

    $buchungsliste->setZahltyp(\EpayBL\Zahltyp::DIREKT);
    $buchungsliste->setBetrag($betrag);

    return $buchungsliste;
  }

  /**
   * Erstellt die sog. Fachverfahrendaten, welche in der Buchungsliste gesetzt werden müssen.
   * Die Fachverfahrendaten bestehen aus den URLs für die Fälle Success, Cancel und Error.
   * Erzeugt die URLs, zu welchen, je nach Fall, von ePayBL aus zurückgeleitet wird.
   * @param string $mtid
   * @return array
   */
  private function getFachverfahrenDaten(string $mtid): array
  {
    $fachverfahrendaten = array();
    $fachverfahrendaten[\EpayBL\BuchungslisteFvDatenKeys::SUCCESSURL]
      = ePaymentApi::provideRedirectUrl(array('mtid' => $mtid));
    $fachverfahrendaten[\EpayBL\BuchungslisteFvDatenKeys::CANCELURL]
      = ePaymentApi::provideRedirectUrl(array('action' => 'cancel', 'mtid' => $mtid));
    $fachverfahrendaten[\EpayBL\BuchungslisteFvDatenKeys::ERRORURL]
      = ePaymentApi::provideRedirectUrl(array('action' => 'error', 'mtid' => $mtid));

    return $fachverfahrendaten;
  }

  /**
   * Erstellt anhand der Buchungsinfos die einzelnen Buchungen (Positionen).
   * Hier wird auch die Haushaltstelle und die Objektnummer gesetzt.
   * @param EPayBlBuchungsInfos $buchungsinfo
   * @return \EpayBL\Buchung
   */
  private function createBuchung(EPayBlBuchungsInfos $buchungsinfo): \EpayBL\Buchung
  {
    $buchung = new \EpayBL\Buchung();
    $buchung->setBruttobetrag($buchungsinfo->betrag);
    $buchung->setBuchungstext($this->getBuchungsPrefix($buchungsinfo->typ) . ': ' . $buchungsinfo->nr);
    $kontierung = array();
    $kontierung[\EpayBL\BuchungKontierungKeys::HAUSHALTSTELLE] = $buchungsinfo->haushaltstelle;
    $kontierung[\EpayBL\BuchungKontierungKeys::OBJEKTNUMMER] = $buchungsinfo->objektnummer;
    $kontierung[\EpayBL\BuchungKontierungKeys::HREF] = 'HREF';
    $buchung->setKontierung($kontierung);

    return $buchung;
  }

  /**
   * Erstellt anhand des Warenkorbobjekt-Typs den Buchungsprefix für den Buchungstext.
   * Die Warenkorbobjekt-Typen finden sich in EPayBlBuchungsInfos (z. B. WARENKORBOBJEKT_TYP_KURS)
   * @param $typ
   * @return string
   */
  private function getBuchungsPrefix($typ): string
  {
    switch ($typ) {
      case EPayBlBuchungsInfos::WARENKORBOBJEKT_TYP_KURS:
        $buchungsPrefix = 'Kursnummer';
        break;
      case EPayBlBuchungsInfos::WARENKORBOBJEKT_TYP_ARTIKEL:
        $buchungsPrefix = 'Artikelnummer';
        break;
      case EPayBlBuchungsInfos::WARENKORBOBJEKT_TYP_SONST_POSTEN:
        $buchungsPrefix = 'Sonstiger Posten';
        break;
      default:
        $buchungsPrefix = '';
        break;
    }
    return $buchungsPrefix;
  }
}
