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


class DBWorkGutscheine extends DBWorkGenerated
{
  public function __construct($pDBTyp = 1, $pNewInstance = false)
  {
    parent::__construct($pDBTyp, $pNewInstance);
    $this->_dataModulFields = array('geloescht', 'nummer', 'code', 'bonus', 'name_empfaenger', 'zahlart', 'gueltig_von', 'gueltig_bis', 'gekauft_am', 'gesendet_am', 'gekauft_von', 'beleg_id', 'betrag', 'betrag_offen', 'web_offen', 'id');
    $this->select = implode(', ', $this->_dataModulFields);
  }

  
  public function getNewObject()
  {
    return new Gutschein();
  }

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

  
  public function getGutscheinByCode($pCode)
  {
    $gutscheinCode = $this->dboperation->getString4Sql($pCode);
    $this->dboperation->clear();
    $this->dboperation->query('SELECT ' . $this->select . ' FROM ' . $this->getTableName() . " WHERE code='" . $gutscheinCode . "'");

    return $this->getFirstRow();
  }

  
  public function getGutscheinById($pId)
  {
    $gutscheinId = $this->dboperation->getInt4Sql($pId);
    $this->dboperation->clear();
    $this->dboperation->query('SELECT ' . $this->select . ' FROM ' . $this->getTableName() . ' WHERE id=' . $gutscheinId);

    return $this->getFirstRow();
  }

  
  public function getHighestGutscheinNummer()
  {
    $sql = 'SELECT max(nummer) AS nummer'
           . ' FROM ' . $this->getTableName();
    $this->dboperation->clear();
    $this->dboperation->query($sql);
    $gutschein = $this->getFirstRow();

    return (int)$gutschein->nummer;
  }

  
  public function insertNewGutschein($pGutschein, $pDontProtocol = false, $pIsDmzBetrieb = false)
  {
    $gutscheinId = $this->insertRecord('gutscheine', 'id', 'code');
    if (!$pDontProtocol) {
      $this->saveChanging('gutscheine', '', '', $gutscheinId, 'id', 'I', $pIsDmzBetrieb);
    }
    $gutscheinOrig = $this->getGutscheinById($gutscheinId);
    $this->updateObject($pGutschein, $gutscheinOrig, 'gutscheine', 'id', 'A', $pDontProtocol, $pIsDmzBetrieb);
    $this->setActionIDs();

    return $gutscheinId;
  }

  
  public function updateGutschein($pGutschein, $pDontProtocol = false, $pIsDmzBetrieb = false)
  {
    $gutscheinOrig = $this->getGutscheinById($pGutschein->id);
    $this->updateObject($pGutschein, $gutscheinOrig, 'gutscheine', 'id', 'U', $pDontProtocol, $pIsDmzBetrieb);
    $this->setActionIDs();
  }

  
  public function getDefaultGutschein($pBetrag, $pEmpfaenger, $pZahlart, $pNummer = null, $pCode = null)
  {
    $zahlart = $pZahlart;
    if ($zahlart === 'bankeinzug' || empty($pZahlart)) {
      $zahlart = 'L';
    }

    $gutschein = $this->getNewObject();

    $isNichtReplikatbetrieb = !SessionOperations::isReplikat();
    $gutschein->nummer = !isset($pNummer) && $isNichtReplikatbetrieb ? $this->getNewGutscheinNummer() : $pNummer;
    $gutschein->code = !isset($pCode) && $isNichtReplikatbetrieb ? $this->getNewGutscheinCode() : $pCode;

    $gutschein->betrag = $pBetrag;
    $gutschein->betrag_offen = $pBetrag;
    $gutschein->web_offen = $pBetrag;

    $gutschein->gueltig_von = DateTimeOperations::getDateNow();
    $gutschein->gueltig_bis = $this->getNewGutscheinGueltigBis();
    $gutschein->gekauft_am = DateTimeOperations::getDateTimeNow();
    $gutschein->zahlart = $zahlart;
    $gutschein->bonus = 'F';
    $gutschein->name_empfaenger = $pEmpfaenger;
    $gutschein->geloescht = 'F';
    $gutschein->beleg_id = 0;

    return $gutschein;
  }

  private function getNewGutscheinNummer()
  {
    $dbwHlGrundSys = new DBWorkHLGrundSys();
    $felder = array('Gutschein_NummerLaenge', 'Gutschein_NummerStart');
    $settings = $dbwHlGrundSys->getSettingsAry($felder);

    $nummerLength = ($settings['Gutschein_NummerLaenge'] !== false ? $settings['Gutschein_NummerLaenge']->wert : 6);
    $nummerStart = ($settings['Gutschein_NummerStart'] !== false ? $settings['Gutschein_NummerStart']->wert : 0);
    $highestNummer = max(array($this->getHighestGutscheinNummer(), $nummerStart));

    return \StringOperations::pad($highestNummer + 1, $nummerLength, '0', STR_PAD_LEFT);
  }

  private function getNewGutscheinGueltigBis()
  {
    $dbwHlGrundSys = new DBWorkHLGrundSys();
    $gueltigMonate = $dbwHlGrundSys->getFeldWert('Gutschein_Gueltig', '0');

    return DateTimeOperations::changeMonth(DateTimeOperations::getDateNow(), $gueltigMonate);
  }

  
  private function getNewGutscheinCode()
  {
    do {
      $code = $this->generateGutscheinCode();
    } while (!$this->getGutscheinByCode($code)->isEmpty());

    return $code;
  }

  
  private function generateGutscheinCode()
  {
    $charactersAndLength = $this->getUsableCharactersAndLength();
    $characters = $charactersAndLength['characters'];
    $randomString = '';
    $length = $charactersAndLength['length'];
    for ($i = 0; $i < $length; $i++) {
      $randomString .= $characters[rand(0, StringOperations::strlen($characters) - 1)];
    }

    return $randomString;
  }

  private function getUsableCharactersAndLength()
  {
    $dbwHlGrundSys = new DBWorkHLGrundSys();
    $felder = array('Gutschein_CodeLaenge', 'Gutschein_CodeZiffern', 'Gutschein_CodeGrossbuchstaben', 'Gutschein_CodeKleinbuchstaben');
    $settings = $dbwHlGrundSys->getSettingsAry($felder);

    $result = array();
    $result['length'] = ($settings['Gutschein_CodeLaenge'] !== false ? $settings['Gutschein_CodeLaenge']->wert : 4);
    $result['characters'] = '';
    if ($settings['Gutschein_CodeZiffern'] !== false && $settings['Gutschein_CodeZiffern']->wert === 'W') {
      $result['characters'] .= '0123456789';
    }
    if ($settings['Gutschein_CodeGrossbuchstaben'] !== false && $settings['Gutschein_CodeGrossbuchstaben']->wert === 'W') {
      $result['characters'] .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    }
    if ($settings['Gutschein_CodeKleinbuchstaben'] !== false && $settings['Gutschein_CodeKleinbuchstaben']->wert === 'W') {
      $result['characters'] .= 'abcdefghijklmnopqrstuvwxyz';
    }

    
    if ($result['characters'] === '') {
      $result['characters'] = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    }

    return $result;
  }
}