<?php
/**
 * Copyright 2005-2017 de Solis Soluções Livres Ltda.
 *
 * Este arquivo é parte do programa Gnuteca.
 *
 * O Gnuteca é um software de propriedade da SOLIS, sendo desenvolvido
 * e mantido exclusivamente por esta empresa.
 *
 * A licença de uso está disponível mediante aquisição exclusiva junto à
 * SOLIS. A licença é concedida sem caráter de exclusividade ao licenciado.
 * Os direitos de uso são perpétuos.
 *
 * Embora os códigos fontes sejam fornecidos, o software é de propriedade
 * da SOLIS, não sendo permitido ao adquirente da licença a sua revenda,
 * empréstimo ou cessão (onerosa ou não) à terceiros. Também não é permitido,
 * a qualquer título e tempo, promover no software qualquer tipo de alienação,
 * reprodução, distribuição, divulgação, registro, licenciamento, transferência
 * ou qualquer outro ato que prejudique ou comprometa os direitos de propriedade
 * de software, o nome e a imagem da sua proprietária e do próprio software,
 * além de configurar concorrência à SOLIS.
 *
 * O licenciado, com o acesso ao código fonte do software, terá o direito de
 * promover mudanças no respectivo código. No entanto, nas situações em que ele
 * contar com o suporte oficial prestado pela SOLIS, não poderá promover mudanças
 * no código fonte, sob pena de perda do referido suporte.
 *
 * Para conhecer em detalhes o Termo de Licenciamento do Software Gnuteca
 * leia o arquivo “LICENCA.txt” disponível junto ao código deste software.
 * 
 * 
 * This file handles the connection and actions for basPersonLink table
 *
 *
 *
 *
 *
 **/

/**
 * Class to manipulate the basConfig table
 **/
class BusinessGnuteca3BusBond extends GBusiness
{
    public $removeData;
    public $insertData;
    public $updateData;
    
    public $personId;
    public $linkId;
    public $dateValidate;
    public $oldDateValidate;
    public $oldLinkId;
    public $paymentMethod;
    public $paymentValue;
    
    public $personIdS;
    public $linkIdS;
    public $dateValidateS;
    public $beginDateValidateS;
    public $endDateValidateS;

    public $onlyWithEmail;
    public $byActive; //show only active bonds
    public $allActive; //Filtro que mostra todos ativos no GET
    public $activeLink; //Mostra links ativos

    protected $gridData;
    
    /**
     * Constantes de forma de pagamento para os vínculos da biblioteca
     */
    const PAYMENT_METHOD_CASH = 1;
    const PAYMENT_METHOD_PIX = 2;

    /**
     * Class constructor
     **/
    function __construct()
    {
        parent::__construct();
    }

    /**
     * List all records from the table handled by the class
     *
     * @param: None
     *
     * @returns (array): Return an array with the entire table
     *
     **/
    public function listBond($selection = false)
    {
        $this->clear();
        
        $columns = 'A.linkid,
                    A.description';
        $tables = 'baslink A';
        
        $data = array();
        $this->setColumns($columns);
        $this->setTables($tables);
        $this->setOrderBy('A.description');
        $sql = $this->select($data);
        $rs = $this->query($sql);
        
        if ( ($selection) && (is_array($rs)) )
        {
            foreach ( $rs as $i=> $value )
            {
                $rs[$i][1] = $value[1] ." [{$value[0]}]";
            }
        }
        
        return $rs;
    }

    /**
     * Return a specific record from the database
     *
     * @param $moduleConfig (integer): Primary key of the record to be retrieved
     * @param $parameter (integer): Primary key of the record to be retrieved
     *
     * @return (object): Return an object of the type handled by the class
     *
     **/
    public function getBond($personId, $linkId, $dateValidate=null)
    {
        $this->clear();
        
        $columns = 'A.personId, A.linkId, A.dateValidate';
        $tables = 'baspersonlink A';
        
        $where = 'A.personId = ? AND A.linkId = ?';
        $data = array($personId, $linkId);
        
        $this->setColumns($columns);
        $this->setTables($tables);
        $this->setWhere($where);

        if ( $dateValidate )
        {
            $this->setWhere('(A.dateValidate = ? OR A.dateValidate IS NULL)');
            $data[] = $dateValidate;
        }

        $sql = $this->select($data);
        $rs = $this->query($sql, TRUE);

        if ( $rs )
        {
            $this->setData($rs[0]);
            return $rs[0];
        }
        else
        {
            return false;
        }
    }

    /**
     * Do a search on the database table handled by the class
     *
     * @param $filters (object): Search filters
     *
     * @return (array): An array containing the search results
     **/
    public function searchBond($toObject = FALSE, $orderBy = NULL)
    {
        $this->clear();

        $columns = 'A.personId,
                    B.name,
                    A.linkId,
                    C.linkId,
                    C.description AS linkIdName,
                    A.dateValidate,
                    C.description AS description,
                    A.dateValidate as oldDateValidate,
                    B.email,
                    A.paymentmethod,
                    A.paymentvalue';
        $tables = ' baspersonlink   A
   INNER JOIN ONLY  basPerson       B
                ON  (A.personId = B.personId)
        INNER JOIN  basLink         C
                ON  (A.linkId = C.linkId)';
        
        //mostra somente ativo
        if ( $this->byActive )
        {
            $orderBy = 'C.level asc limit 1';
            $this->setWhere(' (A.datevalidate >= now()::date OR A.datevalidate IS NULL)');
        }

        if ( $this->allActive )
        {
            $orderBy = 'C.level asc';
            $this->setWhere('(A.datevalidate >= now()::date OR A.datevalidate IS NULL)');
        }
        
        //ordenação padrão
        if ( !$orderBy )
        {
            $orderBy = 'A.dateValidate';
	}

	if ( $this->onlyWithEmail )
        {
            $this->setWhere('B.email is not null');
            $this->setWhere('trim(B.email) <> trim(?)');
            $data[] = ' ';
        }
        
        if ( !empty($this->personIdS) )
        {
            $this->setWhere('A.personId = ?');
            $data[] = $this->personIdS;
        }
        if ( !empty($this->linkIdS) )
        {
            if ( !is_array($this->linkIdS))
            {
                $this->linkIdS = array($this->linkIdS);
            }

            $this->setWhere('A.linkId in ('.implode(',',$this->linkIdS).')');
        }
        if ( !empty($this->dateValidateS) )
        {
            $this->setWhere('date(A.dateValidate) = ?');
            $data[] = $this->dateValidateS;
        }
        if ( !empty($this->beginDateValidateS) )
        {
            $this->setWhere('date(A.dateValidate) >= ?');
            $data[] = $this->beginDateValidateS;
        }
        if ( !empty($this->endDateValidateS) )
        {
            $this->setWhere('date(A.dateValidate) <= ?');
            $data[] = $this->endDateValidateS;
        }
        
        //Se foi selecionado true ou false
        if ( strlen(trim($this->activeLink)) != 0 )
        {
            //Todos que são ativos tem vinculo que vence hoje ou além ou data de validade nula (permamente)
            $active = "A.datevalidate >= now()::date OR (A.dateValidate IS NULL AND A.personId = ?)";
            $data[] = $this->personIdS;
            
            if ( MUtil::getBooleanValue($this->activeLink) == TRUE )
            {
                $this->setWhere($active);
            }
            else
            {
                //Se for para listar os não ativos, nega o $active
                $this->setWhere("NOT (". $active . ")");
            }
        }
        
        $this->setColumns($columns);
        $this->setTables($tables);
        $this->setOrderBy($orderBy);
        $sql = $this->select($data);
        
        $rs = $this->query($sql, $toObject ? TRUE : FALSE);

        return $rs;
    }

    /**
     * Insert a new record
     *
     * @param $data (object): An object of the type handled by the class
     *
     * @return True if succed, otherwise False
     *
     **/
    public function insertBond()
    {
        $this->clear();
        $data = array($this->personId, $this->linkId,$this->dateValidate, $this->paymentMethod, $this->paymentValue);
        
        $columns = 'personId,
                    linkId,
                    dateValidate';

        if (VALOR_INSCRICAO_BIBLIOTECA != 0)
        {
            $columns .= ', paymentmethod, paymentvalue';
        }

        $tables = 'baspersonlink';
        $this->setColumns($columns);
        $this->setTables($tables);
        $sql = $this->insert($data);
        $rs = $this->execute($sql);
        
        return $rs;
    }

    /**
     * Update data from a specific record
     *
     * @param $data (object): Data which will replace the old record data
     *
     * @return (boolean): True if succeed, otherwise False
     *
     **/
    public function updateBond()
    {
        if ( !$this->linkId || !$this->personId )
        {
            return false;
        }
        
        if ( $this->removeData )
        {
            return $this->deleteBond($this->personId, $this->linkId, $this->oldDateValidate);
        }
        elseif ( $this->insertData )
        {
            return $this->insertBond();
        }
       
        $columns = 'dateValidate, linkId';

        $this->clear();

        $date = new GDate($this->dateValidate);
        $data[] = $date->getDate(GDate::MASK_DATE_DB);
        $data[] = $this->linkId;

        if (VALOR_INSCRICAO_BIBLIOTECA != 0) 
        {
            $data[] = $this->paymentMethod;
            $data[] = $this->paymentValue;
            $columns .= ', paymentMethod, paymentValue';
        }

        $data[] = $this->personId;
        $data[] = $this->oldLinkId ? $this->oldLinkId : $this->linkId;

        $this->setColumns($columns);
        $this->setTables('baspersonlink');
        $this->setWhere('personId = ? AND linkId = ?');

        if ( $this->oldDateValidate )
        {
            $this->setWhere('dateValidate = ?');
            $data[] = $this->oldDateValidate;
        }
        else
        {
            //Se não tiver data de validade, altera a que não estiver definida.
            $this->setWhere('dateValidate IS NULL');
        }

        $sql = $this->update($data);
        $rs = $this->execute($sql);
        return $rs;
    }

    /**
     * Delete a record
     *
     * @param $moduleConfig (string): Primary key for deletion
     * @param $parameter (string): Primary key for deletion
     *
     * @return (boolean): True if succeed, otherwise False
     *
     **/
    public function deleteBond($personId = null, $linkId = null, $oldDateValidate = null)
    {
        $this->clear();

        $tables = 'baspersonlink';
        
        if ( !is_null($personId) )
        {
            $this->setWhere("personId = ?");
            $data[] = $personId;
        }
        if ( !is_null($linkId) )
        {
            $this->setWhere("linkId = ?");
            $data[] = $linkId;
        }

        if ( !empty($oldDateValidate) )
        {
            $this->setWhere("datevalidate = ?");
            $data[] = $oldDateValidate;
        }
        else
        {
            $this->setWhere("datevalidate IS NULL");
        }
        
        $this->setColumns($columns);
        $this->setTables($tables);
        
        $sql = $this->delete($data);
        
        $rs = $this->execute($sql);
        
        return $rs;
    }

    /**
     * Return the Active Link (Bond) of this Person id
     *
     * @param personId the code of person
     */
    public function getPersonLink($personId)
    {
        $this->clear();
        
        $this->byActive = true;
        $this->personIdS = $personId;
        $rs = $this->searchBond(true);
        
        return $rs[0]; //retorna só o primeiro, o ativo
    }

    /**
     * Return All Active Link (Bond) of this Person id
     *
     * @param personId the code of person
     */
    public function getAllPersonLink($personId)
    {
        $this->clear();
        $columns = 'a.linkId as linkId,
                       a.description,
                       B.dateValidate';
        $tables = 'basLink A
                       INNER JOIN basPersonLink B on (A.linkId = B.linkId)';
        $where = '    (B.datevalidate >= now()::date OR B.datevalidate IS NULL)
                       and B.personId = ?';
        $orderBy = 'A.level asc';
        $data = array($personId);
        
        $this->setColumns($columns);
        $this->setTables($tables);
        $this->setWhere($where);
        $this->setOrderBy($orderBy);
        $sql = $this->select($data);
        
        $rs = $this->query($sql, TRUE);
        
        return $rs;
    }

    /**
     * Retorna os grupos e validade dos grupos de determinadas pessoas
     *
     * @param integer or simple array $personId
     * @return  object
     */
    public function getLinksByPersonId($personId)
    {
        $this->clear();
        
        $columns = 'linkId,
                       personId,
                       dateValidate';
        
        $tables = 'basPersonLink';
        
        $personId = is_array($personId) ? $personId : array($personId);
        $personId = implode("', '", $personId);
        $where = "personId IN ('{$personId}')";
        
        $this->setColumns($columns);
        $this->setTables($tables);
        $this->setWhere($where);
        $this->setOrderBy($orderBy);
        $sql = $this->select();
        
        $rs = $this->query($sql, TRUE);
        
        if ( !$rs )
        {
            return false;
        }
        
        $result = array();
        foreach ( $rs as $content )
        {
            $result[$content->personId][$content->linkId]->personId = $content->personId;
            $result[$content->personId][$content->linkId]->linkId = $content->linkId;
            $result[$content->personId][$content->linkId]->dateValidate = $content->dateValidate;
        }
        
        return $result;
    }
    
    /**
     * Obtém vínculo ativo do usuário e de maior nível.
     * 
     * @param int $personId Código do usuário.
     * @return stdClass Vínculo ativo de maior prioridade.
     */
    public function getActivePersonLink($personId)
    {
        if ( !$personId )
        {
            return NULL;
        }
        
        $sql = new MSQL();
        $sql->setColumns('P.personId, 
                          P.name, 
                          min( L.level),
                          L.linkid as activelink,
                          login');
        $sql->setTables('  ONLY basPerson P 
                     INNER JOIN basPersonLink PL 
                             ON P.personId = PL.personId 
                     INNER JOIN basLink L 
                             ON L.linkId = PL.linkId 
                            AND (PL.dateValidate >= now()::date OR PL.dateValidate IS NULL)');
        $sql->setGroupBy('1,2,4,5');
        $sql->setOrderBy('1');
        
        $sqlInterno = $sql->select();
        
        $this->clear();
        $this->setColumns('name,
                           activelink, 
                           L.description,
                           level');
        $this->setTables('(' . $sqlInterno . ') as temp
               LEFT JOIN basLink L 
                      ON activelink = L.linkId');
        $this->setWhere('personid = ?');
        
        $this->setOrderBy('level LIMIT 1');
        $sql = $this->select(array($personId));
        $result = $this->query($sql, TRUE);
        
        $personLink = NULL;
        
        if ( is_array($result) )
        {
            $personLink = $result[0];
        }
        
        return $personLink;
    }

    /**
     * Delete a record
     *
     * @param $moduleConfig (string): Primary key for deletion
     * @param $parameter (string): Primary key for deletion
     *
     * @return (boolean): True if succeed, otherwise False
     *
     **/
    public function deletePersonLink($personId)
    {
        $this->clear();
        
        $personId = is_array($personId) ? $personId : array($personId);
        $personId = implode("', '", $personId);
        
        $tables = 'basPersonLink';
        $where = "personId in ('{$personId}')";
        
        $this->setColumns($columns);
        $this->setTables($tables);
        $this->setWhere($where);
        $sql = $this->delete();
        $rs = $this->execute($sql);
        
        return $rs;
    }

    /**
     * Enter description here...
     *
     * @param unknown_type $data
     */
    public function setData($data)
    {
        $this->removeData = NULL;
        $this->insertData = NULL;
        $this->updateData = NULL;
        $this->personId = NULL;
        $this->linkId = NULL;
        $this->dateValidate = NULL;
        $this->oldDateValidate = NULL;
        $this->oldLinkId = NULL;
        $this->paymentMethod = NULL;
        $this->paymentValue = NULL;
        
        parent::setData($data);
    }

    /**
     * 
     * 
     * 
     * 
     */
    public function notifyPersonLinkEnd($days = DAYS_BEFORE_NOTIFY_PERSON_LINK_END)
    {
        $sendMail = new GSendMail();
        $days = explode(';',$days);
        $persons = array();
        foreach($days as $d)
        {
            //pegar data final
            // se valor de days não for passado como parametro ele vai pegar o valor default de days
            $dataFinal = new GDate(date("Y-m-d H:i:s"));        
            $dataFinal->addDay($d);

            // Array com dados dos clientes que estão com vinculo prestes a vencer
            $persons[] = $this->getDatevalidate($dataFinal);
        }

        // Faz envio de email para o usuario que estiver com seu vinculo prestes a terminar
        $adminArray = array();

        foreach($persons as $Persons)
        {
            foreach ($Persons as $p)
            {
                $content = EMAIL_NOTIFY_PERSON_LINK_CONTENT;
                $subject = EMAIL_NOTIFY_PERSON_LINK_SUBJECT;

                $vinculo = $p[3];
                if ($vinculo == 'ALUNOS') { $vinculo = 'ALUNO'; };
                $gf = new GFunction();
                $gf->setVariable('$USER_NAME', $p[1]);
                $gf->setVariable('$LINK_NAME', $vinculo);
                $gf->setVariable('$PERSON_LINK_END_DATE', $p[4]);
                $content = $gf->interpret( $content );
                    
                $email = trim($p[2]);
                if ($email != null)
                {
                    $param = $sendMail->sendMailNotifyPersonLinkEnd($email, $subject, $content);
                    if($param == 1)
                    {
                        $array = array($p[0], $p[1], DB_TRUE, 'Sucesso!', $p[3], $p[4], $p[2]);
                        $adminArray[] = $array;
                    }
                    else
                    {
                        $array = array($p[0], $p[1], DB_FALSE, 'Erro ao enviar o e-mail!', $p[3], $p[4], $p[2]);
                        $adminArray[] = $array;
                    }
                }
                else
                {
                    $array = array($p[0], $p[1], DB_FALSE, 'E-mail da pessoa está em branco!', $p[3], $p[4], $p[2]);
                    $adminArray[] = $array;
                }   
            }
        }
        // Faz o envio de email para o administrador
        if (!empty( $adminArray )){ $sendMail->sendAdminNotifyPersonsLinkEnd( $adminArray ); }
    
        // MONTA GRID COM OS DADOS DOS ENVIOS DE EMAIL.
        foreach ( $adminArray as $content )
        {
            ksort($content);
            $this->addGridData($content);
        }
    }

    /**
     *  Retorna um Array com os dados das pessoas que estão com seu vinculo prestes a vencer
     * 
     */
    public function getDatevalidate($dataFinal)
    {
        $this->clear();
        $this->setColumns('pl.personid, bp.name, bp.email, bl.description, pl.datevalidate');
        $this->setTables('baspersonlink pl 
                        JOIN basperson bp ON bp.personid = pl.personid
                        JOIN baslink bl ON bl.linkid = pl.linkid');
        $this->setWhere('datevalidate = ? ');
            
        $args[] = $dataFinal->generateToDB();

        $sql = $this->select($args);
        $Persons = $this->query($sql);
        return $Persons;
    }

    public function addGridData($gridData)
    {
        $this->gridData[] = $gridData;
    }

    public function getGridData()
    {
        return $this->gridData;
    }

    public static function listPaymentMethods()
    {
        return [
            self::PAYMENT_METHOD_CASH => 'Dinheiro',
            self::PAYMENT_METHOD_PIX => 'Pix',
        ];
    }
}
?>
