<?php


/**
 * Базов драйвер за новите справки
 *
 *
 * @category  bgerp
 * @package   frame2
 *
 * @author    Ivelin Dimov <ivelin_pdimov@abv.bg>
 * @copyright 2006 - 2020 Experta OOD
 * @license   GPL 3
 *
 * @since     v 0.1
 */
abstract class frame2_driver_Proto extends core_BaseClass
{
    /**
     * Интерфейси които имплементира
     */
    public $interfaces = 'frame2_ReportIntf';
    
    
    /**
     * Кои полета може да се променят от потребител споделен към справката, но нямащ права за нея
     */
    protected $changeableFields = '*';


    /**
     * Дали да се изпраща нотификация САМО ако са променени данните от справката
     */
    public $sendNotificationOnlyAfterDataIsChanged = true;


    /**
     * Лог на изчисленията
     */
    public $log = array();


    /**
     * Добавя полетата на драйвера към Fieldset
     *.
     * @param core_Fieldset $fieldset
     */
    public function addFields(core_Fieldset &$fieldset)
    {
    }

    /**
     * След полетата за добавяне
     *
     * @param frame2_driver_Proto $Driver   - драйвер
     * @param embed_Manager       $Embedder - ембедър
     * @param core_Fieldset       $fieldset - форма
     */
    protected static function on_AfterAddFields(frame2_driver_Proto $Driver, embed_Manager $Embedder, core_Fieldset &$fieldset)
    {
        $fieldset->FLD('showLetterHeadWhenSending', "enum(yes=Показване при печат/експорт,no=Скриване при печат/експорт)", "caption=Други настройки->Антетка,autohide");
    }


    /**
     * Кой може да избере драйвера
     */
    public function canSelectDriver($userId = null)
    {
        return core_Users::haveRole($this->canSelectDriver, $userId);
    }


    /**
     * Връща заглавието на отчета
     *
     * @param stdClass $rec - запис
     * @param bool $isPlain - дали заглавието да е чисто (без окрасяване)
     *
     * @return string|NULL - заглавието или NULL, ако няма
     */
    public function getTitle($rec, $isPlain = false)
    {
    }
    
    
    /**
     * Подготвя данните на справката от нулата, които се записват в модела
     *
     * @param stdClass $rec - запис на справката
     *
     * @return stdClass|NULL $data - подготвените данни
     */
    public function prepareData($rec)
    {
    }
    
    
    /**
     * Рендиране на данните на справката
     *
     * @param stdClass $rec - запис на справката
     *
     * @return core_ET - рендирания шаблон
     */
    public function renderData($rec)
    {
        return new core_ET('');
    }
    
    
    /**
     * Да се изпраща ли нова нотификация на споделените потребители, при опресняване на отчета
     *
     * @param stdClass $rec
     *
     * @return bool
     */
    public function canSendNotificationOnRefresh($rec)
    {
        return true;
    }
    
    
    /**
     * Връща параметрите, които ще бъдат заместени в текста на нотификацията
     *
     * @param stdClass $rec
     *
     * @return array
     */
    public function getNotificationParams($rec)
    {
        $params = array();
        $params['handle'] = '#' . frame2_Reports::getHandle($rec->id);
        $params['lastRefreshed'] = frame2_Reports::getVerbal($rec, 'lastRefreshed');
        
        return $params;
    }
    
    
    /**
     * Добавя допълнителни полетата в антетката
     *
     * @param frame2_driver_Proto $Driver
     * @param embed_Manager       $Embedder
     * @param NULL|array          $resArr
     * @param object              $rec
     * @param object              $row
     */
    public static function on_AfterGetFieldForLetterHead(frame2_driver_Proto $Driver, embed_Manager $Embedder, &$resArr, $rec, $row)
    {
        $form = cls::get('core_Form');
        $Driver->addFields($form);
        $fields = (is_array($form->fields)) ? $form->fields : array();
        
        foreach ($fields as $name => $fld) {
            if (isset($rec->{$name}) && $fld->single !== 'none') {
                if($fld->single == 'internal' && (Mode::is('text', 'xhtml') || Mode::is('printing'))) continue;
                $captionArr = explode('->', $fld->caption);
                $caption = (countR($captionArr) == 1) ? $captionArr[0] : $captionArr[1];
                $resArr[$name] = array('name' => tr($caption), 'val' => $row->{$name});
            }
        }

        if(Mode::is('text', 'xhtml') || Mode::is('printing')){
            if($rec->showLetterHeadWhenSending == 'no'){
                $resArr = array();
            }
        }
    }
    
    
    /**
     * Връща редовете на CSV файл-а
     *
     * @param stdClass $rec
     *
     * @return array
     */
    public function getCsvExportRows($rec)
    {
        return array();
    }
    
    
    /**
     * Връща полетата за експортиране във csv
     *
     * @param stdClass $rec
     *
     * @return array
     */
    public function getCsvExportFieldset($rec)
    {
        return new core_FieldSet();
    }
    
    
    /**
     * Връща следващите три дати, когато да се актуализира справката
     *
     * @param stdClass $rec - запис
     *
     * @return array|FALSE - масив с три дати или FALSE ако не може да се обновява
     */
    public function getNextRefreshDates($rec)
    {
        return array();
    }
    
    
    /**
     * Кои полета може да се променят от потребител споделен към справката, но нямащ права за нея
     *
     * @param stdClass $rec
     *
     * @return array
     */
    public function getChangeableFields($rec)
    {
        $changeableFields = $this->changeableFields;
        
        // Ако е зададено '*', значи са всички полета от драйвера
        if ($changeableFields === '*') {
            $fs = new core_FieldSet();
            $this->addFields($fs);
            $changeableFields = array_keys($fs->selectFields());
        }
        
        return arr::make($changeableFields, true);
    }
    
    
    /**
     * Какъв ще е езика с който ще се рендират данните на шаблона
     *
     * @param stdClass $rec
     *
     * @return string|null езика с който да се рендират данните
     */
    public function getRenderLang($rec)
    {
        return null;
    }


    /**
     * Връща шаблоните за етикети към драйвера
     *
     * @param mixed $id
     * @param string $series - серии
     * @param boolean $ignoreWithPeripheralDriver - да се избира ли периферния драйвер
     *
     * @return array - достъпни шаблони
     */
    public function getLabelTemplates($id, $series = 'label', $ignoreWithPeripheralDriver = true)
    {
        return label_Templates::getTemplatesByClass($this, $series, $ignoreWithPeripheralDriver);
    }


    /**
     * Връща достъпните серии за шаблони
     *
     * @param int|null $id - ид на запис
     * @return array  - достъпни шаблони
     */
    public function getLabelSeries($id = null)
    {
        return array('label' => cls::get('frame2_Reports')->printLabelCaptionPlural);
    }


    /**
     * Може ли справката да бъде изпращана по имейл
     *
     * @param mixed $rec
     *
     * @return boolean
     */
    public function canBeSendAsEmail($rec)
    {
        return false;
    }
    
    
    /**
     * Изборът на потребители които да бъдат нотифицирани при обновяване дали са задължителни
     *
     * @param mixed $rec
     *
     * @return boolean
     */
    public function requireUserForNotification($rec)
    {
        return true;
    }
    
    
    /**
     * Иконка на справката
     *
     * @param mixed $id
     *
     * @return string
     */
    public static function getIcon($id)
    {
        return 'img/16/report.png';
    }


    /**
     * Дали при автоматичното обновяване по крон да се обновява справката
     *
     * @param stdClass $rec
     * @return bool
     */
    public function tryToAutoRefresh($rec)
    {
        return true;
    }


    /**
     * Дали след обновяване на справката да се затвори автоматично
     *
     * @param stdClass $rec
     * @return bool
     */
    public function canCloseAfterRefresh($rec)
    {
        // Кога последно е видяна от потребител справката
        $lastSeen = log_Data::getLastSeenByUser(frame2_Reports::getClassId(), $rec);

        $lastSeen = !empty($lastSeen) ? $lastSeen : $rec->createdOn;
        $seenBeforeTime = frame2_Setup::get('CLOSE_LAST_SEEN_BEFORE');
        $seenBefore = dt::addSecs(-1 * $seenBeforeTime);

        return $lastSeen <= $seenBefore;
    }


    /**
     * Добавя в лога съобщения
     */
    protected function logWhilePreparing($msg)
    {
        $this->log[] = array('msg' => $msg, 'time' => dt::now());
    }


    /**
     * Връща кеширания лог
     *
     * @param stdClass $rec
     * @return array
     */
    public function getLog($rec)
    {
       return $this->log;
    }
}
