<?php
/**
 * <--- Copyright 2005-2013 de Solis - Cooperativa de Soluções Livres Ltda. e
 * Univates - Centro Universitário.
 *
 * Este arquivo é parte do programa Gnuteca.
 *
 * O Gnuteca é um software livre; você pode redistribuí-lo e/ou modificá-lo
 * dentro dos termos da Licença Pública Geral GNU como publicada pela Fundação
 * do Software Livre (FSF); na versão 2 da Licença.
 *
 * Este programa é distribuído na esperança que possa ser útil, mas SEM
 * NENHUMA GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO
 * ou APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/GPL em
 * português para maiores detalhes.
 *
 * Você deve ter recebido uma cópia da Licença Pública Geral GNU, sob o título
 * "LICENCA.txt", junto com este programa, se não, acesse o Portal do Software
 * Público Brasileiro no endereço www.softwarepublico.gov.br ou escreva para a
 * Fundação do Software Livre (FSF) Inc., 51 Franklin St, Fifth Floor, Boston,
 * MA 02110-1301, USA --->
 *
 * Classe WebService para GnutecaAutomação
 *
 * @author Tcharles Silva [tcharles@solis.coop.br]
 *
 * @version $Id$
 *
 * \b Maintainers: \n
 * Tcharles Silva [tcharles@solis.coop.br]
 * 
 * 
 *
 * @since
 * Class created on 04/11/2013
 * 
 **/

include("GnutecaWebServices.class.php");
$MIOLO->getClass('gnuteca3', 'GSession');
$MIOLO->getClass('gnuteca3', 'GSipCirculation');

class gnuteca3WebServicesAutomacao extends GWebServices 
{
    public $busSipEquipament;
    public $busSipEquipamentStatusHistory;
    public $busSessionOperation;
    public $busSession;
    public $busOperationLoanSip;
    public $busAuthenticate;
    public $busPerson;
    public $busMaterial;
    public $busMaterialControl;
    public $busSearchFormat;
    public $busOperationLoan;
    public $busOperationRenew;
    public $busReserve;
    public $busReserveComposition;
    public $busLoan;
    public $busReturnRegister;
    public $busReturnType;
    public $busFine;
    public $busPolicy;
    public $busBond;
    public $busRight;
    public $busPenalty;
    public $busLocationForMaterialMovement;
    public $busPersonConfig;
    
    
    public function __construct() {
        parent::__construct();
        
        $MIOLO = MIOLO::getInstance();
        $module = MIOLO::getCurrentModule();
        
        //Instancia os atributos com o objeto Bus$Parametro respectivamente
        $this->busSipEquipament = $MIOLO->getBusiness($module, 'BusSipEquipament');
        $this->busSipEquipamentStatusHistory = $MIOLO->getBusiness($module, 'BusSipEquipamentStatusHistory');
        $this->busSipCirculationStatus = $MIOLO->getBusiness($module, 'BusSipCirculationStatus');
        $this->busExemplaryStatusHistory = $MIOLO->getBusiness($module, 'BusExemplaryStatusHistory');
        $this->busExemplaryControl = $MIOLO->getBusiness($module, 'BusExemplaryControl');
        $this->busMaterial = $MIOLO->getBusiness($module, 'BusMaterial');
        $this->busMaterialControl = $MIOLO->getBusiness($module, 'BusMaterialControl');
        $this->busSearchFormat = $MIOLO->getBusiness($module, 'BusSearchFormat');
        $this->busSessionOperation = $MIOLO->getBusiness($module, 'BusSessionOperation');
        $this->busSession = $MIOLO->getBusiness($module, 'BusSession');
        $this->busOperationLoan = $MIOLO->getBusiness($module, 'BusOperationLoan');
        $this->busOperationLoanSip = $MIOLO->getBusiness($module, 'BusOperationLoanSip');
        $this->busOperationRenewSip = $MIOLO->getBusiness($module, 'BusOperationRenewSip');
        $this->busAuthenticate = $MIOLO->getBusiness($module, 'BusAuthenticate');
        $this->busPerson = $MIOLO->getBusiness($module, 'BusPerson');
        $this->busLoan = $MIOLO->getBusiness($module, 'BusLoan');
        $this->busRenew = $MIOLO->getBusiness($module, 'BusRenew');
        $this->busReturnRegister = $MIOLO->getBusiness($module, 'BusReturnRegister');
        $this->busReturnType = $MIOLO->getBusiness($module, 'BusReturnType');
        $this->busFine = $MIOLO->getBusiness($module, 'BusFine');
        $this->busReserve = $MIOLO->getBusiness($module, 'BusReserve');
        $this->busReserveComposition = $MIOLO->getBusiness($module, 'BusReserveComposition');
        $this->busPolicy = $MIOLO->getBusiness($module, 'BusPolicy');
        $this->busBond = $MIOLO->getBusiness($module, 'BusBond');
        $this->busRight = $MIOLO->getBusiness($module, 'BusRight');
        $this->busPenalty = $MIOLO->getBusiness($module, 'BusPenalty');
        $this->busLocationForMaterialMovement = $MIOLO->getBusiness($module, 'BusLocationForMaterialMovement');
        $this->busPersonConfig = $MIOLO->getBusiness($module, 'BusPersonConfig');
    }


    /*
     * Esqueleto do LOGIN, retorna booleano caso dados sejam válidos
     * Parametros:
     * 
     * String termID :: id do terminal
     * String pwd :: senha do terminal
     * String location :: localização, campo opcional
     * 
     * Descrição:
     *      Utiliza o método authenticate da BusSipEquipament para se authentificar
     *      Retorno: booleano se conseguiu authentificar
     * 
     * Criado por: Tcharles Silva
     * Em: 21/11/2013
     * Ultima Atualização por: 
     * Em: 
     * Motivo: 
     */
    public function login($termID, $pwd, $location = null) 
    {
        //MUtil::flog("---Entrando no método de Login-----");
        
        $ok = 'F';
        $startTime = microtime(true);
        
        $retorno = $this->busSipEquipament->authenticate($termID, $pwd);
        
        if($retorno)
        {
            $ok = 'Y';
        }
        
        $endTime = microtime(true);
        $time = $endTime - $startTime;
        //MUtil::flog("Operação realizada em : " . $time);
        return $ok;
    }
    
    
    /*
     * Esqueleto do STATUS, retorna uma String
     * Parametros:
     * 
     * String termID :: id do terminal
     * Integer status :: Pode ser: [0]: OK, [1]: SEM PAPEL, [2]: DESLIGANDO
     * Integer maxPtrWidth :: Tamanho de largura? ----> Ainda não implementado <<----
     * String protocol :: Opcional, não utilizamos
     * 
     * Descrição: WebService de STATUS irá retornar os dados do equipamento
     * Também irá gravar um registro do equipamento que o acessou, com o status atual do mesmo.
     * Registro pode ser visto na tabela gtcSipEquipamentLog
     * 
     * Criado por: Tcharles Silva
     * Em: 21/11/2013
     * Ultima Atualização por: 
     * Em: 
     * Motivo:
     */
    public function status($termID, $status, $maxPtrWidth, $protocol) 
    {
        //MUtil::flog("---Entrando no método de Status-----");
        
        $startTime = microtime(true);
        /* OBS:
         * Ainda não foi implementado a utilização do $maxPtrWidth.
         * Futuramente deverá ser implementado.
         */
        
        if(($status >= 0 ) && ($status < 3))
        {
            //Chama o mpetodo checkStatus para verificar o Status
            $retorno = $this->busSipEquipament->checkStatus($termID);

            //Verifica se esta em alguma biblioteca, caso nulo, não encontrou o $termID
            if($retorno['libraryName'])
            {
                //Seta os dados para inserir
                $this->busSipEquipamentStatusHistory->sipEquipamentId = $termID;
                $this->busSipEquipamentStatusHistory->status = $status;
                $this->busSipEquipamentStatusHistory->insertSipEquipamentStatusHistory();

                //Verifica se a ScreenMsg esta vazia
                if(is_null($retorno['screenMsg']))
                {
                    $retorno['screenMsg'] = 'Status retornado com sucesso.';
                }
                
                //Verifica se a printMsg esta vazia
                if(is_null($retorno['printMsg']))
                {
                    $retorno['printMsg'] = 'null';
                }
                
                //Pepara o retorno na variável $backInfo, usando o delimitador SIP_DELIMITER
                $backInfo = implode(SIP_DELIMITER, $retorno);
            }
            else
            {
                $msg = "Mas que barbaridade. Não encontrei informações desse terminal.";
                $invalido = true;
            }
        }else
        {
            $msg = "Opa, esse status não é válido. Você sabe o que esta fazendo?";
            $invalido = true;
        }
        
        if($invalido)
        {
            //Checagem para evitar campos em branco
            if(empty($retorno['timeoutPeriod']))
            {
                $retorno['timeoutPeriod'] = 'null';
            }
            if(empty($retorno['retriesAllowed']))
            {
                $retorno['retriesAllowed'] = 'null';
            }
            if(empty($retorno['institutionId']))
            {
                $retorno['institutionId'] = 'null';
            }
            if(empty($retorno['libraryName']))
            {
                $retorno['libraryName'] = 'null';
            }
            if(empty($retorno['terminalLocation']))
            {
                $retorno['terminalLocation'] = 'null';
            }
            
            if(is_null($retorno['screenMsg']))
            {
                if(is_null($msg))
                {
                    $retorno['screenMsg'] = 'null';
                }
                else
                {
                    $retorno['screenMsg'] = $msg;
                }
            }
            
            if(is_null($retorno['printMsg']))
            {
                $retorno['printMsg'] = 'null';
            }
            
            $backInfo = implode(SIP_DELIMITER, $retorno);
        }
        
        $endTime = microtime(true);
        $time = $endTime - $startTime;
        
        //MUtil::flog("Operação realizada em : " . $time);
        
        return $backInfo;
    }
    
    
    /*
     * Esqueleto endPatronSession, retorna uma String
     * Parametros:
     * 
     * String dateTime ::
     * String instID ::
     * String patronID ::
     * String termID ::
     * String termPwd ::
     * String patronPwd ::
     * 
     * Descrição:
     *      
     * 
     * Criado por: 
     * Em: 
     * Ultima Atualização por: 
     * Em: 
     * Motivo: 
     */
    public function endPatronSession($dateTime, $instID, $patronID, $termID, $termPwd, $patronPwd)
    {   
        //MUtil::flog("------ Entrando no endPatronSession---------");
        $startTime = microtime(true);
        
        $dadosSip = $this->busSipEquipament->getSipEquipament($termID);
        $locSip = $dadosSip->locationformaterialmovementid;
        
        //Arrays onde ficarão os IDs de empréstimo, devolução e renovação de cada sessão
        $loanIds = Array();
        $returnIds = Array();
        $renewIds = Array();
        
        $loanIds2 = Array();
        $returnIds2 = Array();
        $renewIds2 = Array();
        
        $salva = Gsession::getOpenSession($termID);        
        
        if($salva)
        {
            $this->busSessionOperation->sessionId = $salva->sessionId;
            $this->busSessionOperation->isClosed = DB_FALSE;
            $save = $this->busSessionOperation->searchSessionOperation(TRUE);
                    
            foreach ($save as $op)
            {
                $loanIds2[] = $op->loanId;
                $returnIds2[] = $op->returnRegisterId;
                $renewIds2[] = $op->renewId;

                if($op->operation == 1)  //Verifica se foi Empréstimo
                {
                    $loanIds[] = $op->loanId;
                }
                if($op->operation == 2) //Verifica se foi Devolução
                { 
                    $returnIds[] = $op->returnRegisterId;
                }
                if($op->operation == 3) //Verifica se é Renovação
                {
                    $renewIds[] = $op->renewId;
                }
            }
        }
        
        /*
         * Os numeros dos LoanIds, returnIds e renewIds estão salvos abaixo.
         * 
         * Em cima deles que serão gerados os recibos...
         * 
         * Necessário implementar os recibos.
         */
        
        //Instancia o recibo
        $receiptObject = new GnutecaReceipt();
        $defineReceiptConfigurations = false;
        
        //Define configurações da pessoa
        $pLoanRecibo = $this->busPersonConfig->getValuePersonConfig($patronID, "MARK_PRINT_RECEIPT_LOAN");
        $pLoanEmail = $this->busPersonConfig->getValuePersonConfig($patronID, "MARK_SEND_LOAN_MAIL_RECEIPT");
        $pReturnRecibo = $this->busPersonConfig->getValuePersonConfig($patronID, "MARK_PRINT_RECEIPT_RETURN");
        $pReturnEmail = $this->busPersonConfig->getValuePersonConfig($patronID, "MARK_SEND_RETURN_MAIL_RECEIPT");
        
        //Inicio do recibo de empréstimo
        foreach($loanIds as $loan)
        {
            $data = $this->busLoan->getLoan($loan, TRUE);
            $data->policy = $this->busPolicy->getPolicy($data->privilegeGroupId, $data->linkId, "1", TRUE);
            
            if ( ! $defineReceiptConfigurations )
            {
                //Faz a verfifição do local
                $location  = $this->busLocationForMaterialMovement->getLocationForMaterialMovement($locSip, TRUE);
                
                //Testa se no local, há configuração para imprimir recibo
                if( $location->sendLoanReceiptByEmail == 't')
                {
                    $sendReceipt = true;
                    
                    if($pLoanRecibo == 't')
                    {
                        $printReceipt = true;
                    }else
                    {
                        $printReceipt = false;
                    }
                } 
                else
                {
                    // Caso não tenha, verifica as configurações do usuário
                    //Verificação de recibo
                    if($pLoanRecibo == 't'){
                        $sendReceipt = true;
                    }else{
                        $sendReceipt = false;
                    }
                    
                    //Verificação de e-mail
                    if($pLoanEmail == 't')
                    {
                        $printReceipt = true;
                    }else
                    {
                        $printReceipt = false;
                    }
                }
                $defineReceiptConfigurations =  true;
            }
            //Adiciona o item
            $receiptObject->addItem(new LoanReceipt($data, $sendReceipt, $printReceipt));
        }
        
        //Reseta a variavel para testar
        //$defineReceiptConfigurations = false;
        
        //Inicio do recibo de devolução
        foreach($returnIds as $return)
        {
            //Definir o data
            $data = $this->busReturnRegister->getReturnRegister($return, TRUE);
            
            //Informações do exemplar
            $dados = $this->busExemplaryControl->getExemplaryControl($data->itemNumber);
            
            //Informações do Loan
            $this->busLoan->personId = $patronID;
            $this->busLoan->itemNumber = $data->itemNumber;
            $this->busLoan->loanoperator = $data->operator;
            $this->busLoan->returnDate = $data->date;
            
            $dadosLoan = $this->busLoan->searchLoan(TRUE);
            
            foreach($dadosLoan as $d)
            {
                if($d->returnDate == $data->date)
                {
                    //Informações do loan na variavel $d
                    $dadosR = $d;
                    
                    $dadosR->data = $dadosR->LoanDate;
                    
                    //campo privilegeGroupId
                    $priv = $this->busLoan->getLoan($d->loanId, True);
                    $dadosR->privilegeGroupId = $priv->privilegeGroupId;
                    
                    //campo personName
                    $this->busPerson->personIdS = $patronID;
                    $var = $this->busPerson->searchPerson(TRUE);
                    $dadosR->personName = $var[0]->personName;
                    
                    //campo email
                    $dadosR->email = $var[0]->email;
                }
            }
            
            //Coloca Informações do Loan no local
            $dados->loan = $dadosR;
            
            //campo searchData
            $dados->searchData = $searchData = $this->busSearchFormat->getFormatedString($dados->controlNumber, MATERIAL_MOVIMENT_SEARCH_FORMAT_ID, 'search');
            
            //campo operator
            $dados->operator = $data->operator;
            
            //campo returnDate
            $dados->returnDate = $data->date;
            
            //campo loanId
            $dados->loanId = $dadosR->loanId;
            
            //campo loanDate
            $dados->loanDate = $dadosR->LoanDate;
            
            //campo personId
            $dados->personId = $dadosR->personId;
            
            //Objeto Fine
            $this->busFine->loanId = $dadosR->loanId;
            $this->busFine->itemNumber = $data->itemNumber;
            $this->busFine->personId = $dadosR->personId;
            $this->busFine->libraryUnitId = $dadosR->libraryUnitId;
            $dadosF = $this->busFine->searchFine(TRUE);
            
            if($dadosF)
            {
                foreach($dadosF as $df)
                {
                    if($df->loanId == $dadosR->loanId)
                    {
                        //Define o valor de multa paga
                        $fine->value = $df->value;
                        
                        //Define lonaId
                        $fine->loanId = $df->loanId;
                        
                        //Define BeginDate
                        $fine->beginDate = $df->beginDate;
                        
                        //Define FineStatusId
                        $reF = $this->busFine->getFine($df->fineId, TRUE);
                        $fine->fineStatusId = $reF->fineStatusId;
                        
                        //Define FineId
                        $fine->fineId = $df->fineId;

                        //se tiver multa, irá habilitar no objeto
                        $haveM = true;
                    }
                }
            }
            //Se tiver multas
            if($haveM)
            {
                $dados->fine = $fine;
                $dados->date = $data->date;
                $dados->fineValue = $fine->value;
            }else
            {
                //campo date
                $dados->date = $data->date;

                //campo fineValue
                $dados->fineValue = '';
            }
            
            
            if ( ! $defineReceiptConfigurations )
            {
                //Faz a verfifição do local
                $location  = $this->busLocationForMaterialMovement->getLocationForMaterialMovement($locSip, TRUE);
                
                //Testa se no local, há configuração para imprimir recibo
                if( $location->sendReturnReceiptByEmail == 't')
                {
                    $sendReceipt = true;
                    
                    
                    if($pReturnRecibo == 't')
                    {
                        $printReceipt = true;
                    }else
                    {
                        $printReceipt = false;
                    }
                    
                } 
                else
                {
                    //Verificar o Tipo de Devolução
                    $rType = $this->busReturnType->getReturnType($data->returnTypeId);
                    if($rType->sendmailreturnreceipt == 't')
                    {
                        $sendReceipt = true;
                        $printReceipt = true;
                    
                    }else
                    {
                        // Caso não tenha, verifica as configurações do usuário
                        //Verificação de recibo
                        if($pReturnRecibo == 't'){
                            $sendReceipt = true;
                        }else{
                            $sendReceipt = false;
                        }

                        //Verificação de e-mail
                        if($pReturnEmail == 't')
                        {
                            $printReceipt = true;
                        }else
                        {
                            $printReceipt = false;
                        }
                    }
                }
                $defineReceiptConfigurations =  true;
            }
            //Adiciona o item
            $receiptObject->addItem(new ReturnReceipt($dados, $sendReceipt, $printReceipt));
        }

        //$defineReceiptConfigurations = false;
        
        //Inicio do recibo de renovação
        foreach($renewIds as $renew)
        {
            $dadosR = $this->busRenew->getRenew($renew);
            $data = $this->busLoan->getLoan($dadosR->loanId, TRUE);
            $data->policy = $this->busPolicy->getPolicy($data->privilegeGroupId, $data->linkId, "1", TRUE);

            if ( ! $defineReceiptConfigurations )
            {
                //Faz a verfifição do local
                $location  = $this->busLocationForMaterialMovement->getLocationForMaterialMovement($locSip, TRUE);
                
                //Testa se no local, há configuração para imprimir recibo
                if( $location->sendLoanReceiptByEmail == 't')
                {
                    $sendReceipt = true;
                    
                    if($pLoanRecibo == 't')
                    {
                        $printReceipt = true;
                    }else
                    {
                        $printReceipt = false;
                    }
                } 
                else
                {
                    // Caso não tenha, verifica as configurações do usuário

                    //Verificação de recibo
                    if($pLoanRecibo == 't'){
                        $sendReceipt = true;
                    }else{
                        $sendReceipt = false;
                    }
                    
                    //Verificação de e-mail
                    if($pLoanEmail == 't')
                    {
                        $printReceipt = true;
                    }else
                    {
                        $printReceipt = false;
                    }
                }
                $defineReceiptConfigurations =  true;
            }
            //Adiciona o item
            $receiptObject->addItem($r = new LoanReceipt($data, $sendReceipt, $printReceipt));
        }
        
        $receipt = $receiptObject->generate();
        $receipt = str_replace("\r\n", '#', $receipt);
        
        $var = GSession::closeSession($termID);
        $data = GDate::getYYYYMMDDHHMMSS($dateTime);
        
        if($var)
        {
            $retorno['endSession'] = 'Y';
            $msg = "Sessão encerrada.";
            
            $print = $receipt;
            
        }else
        {
            $retorno['endSession'] = 'N';
            $msg = "Não foi possível finalizar a sessão.";
        }
        
        if(empty($print))
        {
            $print = 'null';
        }
        
        $retorno['dateTime'] = $data;
        $retorno['instID'] = $instID;
        $retorno['screenMsg'] = $msg;
        $retorno['printMsg'] = $print;
        
        $backInfo = implode(SIP_DELIMITER, $retorno);
        
        $endTime = microtime(true);
        $time = $endTime - $startTime;
        //MUtil::flog("Operação realizada em : " . $time);
        
        return $backInfo;
    }

    
    
    /*
     * Esqueleto CHECKOUT ( Empréstimo ), retorna uma String
     * Parametros:
     * 
     * Boolean renewalPolicy, 
     * Boolean noBlock,
     * String dateTime, 
     * String nbDueDate, 
     * String instID, 
     * String patronID, 
     * String itemID,
     * String termID,
     * String termPwd,
     * String itemProp, 
     * String patronPwd,  
     * Boolean cancel
     * 
     * Descrição:
     *      Método que irá realizar o empréstimo.
     * 
     * Criado por: Tcharles Silva
     * Em: 27/11/2013
     * Ultima Atualização por: 
     * Em: 
     * Motivo: 
     */
    public function checkout($renewalPolicy, $noBlock, $dateTime, $nbDueDate, $instID, $patronID, 
                              $itemID, $termID, $termPwd, $itemProp, $patronPwd, $cancel) 
    {
        //MUtil::flog("----- Entrando no checkOut-----");
        $startTime = microtime(true);
        
        //Faz renovacao
        $fazRen = $renewalPolicy;
        
        $titulo = $this->busMaterial->getMaterialTitleByItemNumber($itemID);
        if(empty($titulo))
        {
            $titulo = 'null';
        }
        
        //Define padrão DefaultSip de empréstimo
        $loanTypeId = ID_LOANTYPE_DEFAULTSIPEQUIPAMENT;
        
        //Caso seja marcado como offline, define o modo offline
        if($nbDueDate){
            $loanTypeId = ID_LOANTYPE_OFFLINE;
        }

        /* PADRÕES DE EMPRÉSTIMOS
           Utilizado em: $padraoLoan 
             1 | Empréstimo
             2 | Devolução
             3 | Renovação
        */
        $padraoLoan = '1';
        $retorno = GSipCirculation::doLoan($padraoLoan, $termID, $patronID, $itemID, $loanTypeId, NULL, $fazRen);
        
        if(empty($itemProp))
        {
            $itemProp = 'null';
        }
        
        if($retorno[ok] == 'Y')
        {
            //Decorrer do código aqui.... Caso tenha concluido a operação
            $ret["ok"] = 'Y';
            $ret["renewalOk"] = $retorno[renewalOk];
            $ret["desensitize"] = "Y";
            $ret["dateTime"] = $retorno[dateTime];
            $ret["instID"] = $retorno[instID];
            $ret["patronID"] = $retorno[patronID];
            $ret["itemID"] = $retorno[itemID];
            if(empty($retorno[titleID]))
            {
                $retorno[titleID] = 'null';
            }
            $ret["titleID"] = $titulo;
            $ret["dueDate"] = $retorno[dueDate];
            $ret["securityInhibit"] = 'N';
            $ret["itemProp"] = $itemProp;

            if(is_null($retorno[screenMsg]))
            {
                if($retorno[renewalOk] == 'N')
                {
                    $ret["screenMsg"] = "Sucesso! Empréstimo concluído.";
                }
                else
                {
                    $ret["screenMsg"] = "Sucesso! Renovação concluída.";
                }
            }else
            {
                $ret['screenMsg'] = $retorno[screenMsg];
            }
            
            $ret["printMsg"] = "null";
        }
        else //CASO OCORRA A FALHA
        {   
            $ret["ok"] = 'N';
            $ret["renewalOk"] = "N";
            $ret["desensitize"] = "N";
            
            //Colocar a data no formato abaixo
            $v4 = GDate::getYYYYMMDDHHMMSS($dateTime);
            
            $ret["dateTime"] = $v4;
            $ret["instID"] = $instID;
            $ret["patronID"] = $patronID;
            $ret["itemID"] = $itemID;
            if(empty($retorno[titleID]))
            {
                $retorno[titleID] = 'null';
            }
            $ret["titleID"] = $titulo;
            $ret["dueDate"] = $v4;
            $ret["securityInhibit"] = 'N';
            $ret["itemProp"] = $itemProp;
            
            if(is_null($retorno[screenMsg]))
            {
                if($retorno[renewalOk] == 'N')
                {
                    $ret["screenMsg"] = "Falhamos. Problema no empréstimo. Consulte informações no balcão de atendimento.";
                }
                else
                {
                    $ret["screenMsg"] = "Falhamos. Problema na renovação. Consulte informações no balcão de atendimento.";
                }
            }else
            {
                $ret['screenMsg'] = $retorno[screenMsg];
            }
            
            $ret["printMsg"] = "null";
        }
        
        //Monta a string de retorno com as informações        
        $backInfo = implode(SIP_DELIMITER, $ret);
        //MUtil::flog($backInfo);
        
        $endTime = microtime(true);
        $time = $endTime - $startTime;
        //MUtil::flog("Operação realizada em : " . $time);
        
        return $backInfo;
    }

    
    
    /*
     * Esqueleto CHECKIN, retorna uma String
     * Parametros:
     * 
     * Boolean noBlock,
     * String dateTime, 
     * String returnDate, 
     * String currentLocation, 
     * String instID, 
     * String itemID, 
     * String termID, 
     * String termPwd,
     * String itemProp, 
     * Boolean cancel
     * 
     * Descrição:
     *      Método que realiza a devolução.
     *      
     * 
     * Criado por: Tcharles Silva
     * Em: 04/12/2013
     * Ultima Atualização por:  Tcharles Silva
     * Em: 04/12/2013
     * Motivo: 
     *      Correções.
     */
    public function checkin($noBlock, $dateTime, $returnDate, $currentLocation, $instID, 
                             $itemID, $termID, $termPwd, $itemProp, $cancel)
    {
        //MUtil::flog("------ ENTRANDO NO CHECKIN -------");
        $startTime = microtime(true);
        
        //Chama metodo doReturn com o sipId, e o ItemNumber do livro.
        $retorno = GSipCirculation::doReturn($termID, $itemID);
        
        //MUtil::flog($retorno);
        
        if(empty($itemProp))
        {
            $itemProp = 'null';
        }

        if($retorno[ok] == '1')
        {
            $ret['ok'] = 'Y';
            $ret['resensitize'] = $retorno[resensitize];
            $ret['alert'] = $retorno[alert];
            $ret['dateTime'] = $retorno[dateTime];
            $ret['instID'] = $retorno[instID];
            $ret['itemID'] = $retorno[itemID];
            $ret['permanentLoc'] = '0';
            $ret['titleID'] = $retorno[titleID];
            $ret['sortBin'] = $retorno[sortBin];
            $ret['patronID'] = $retorno[patronID];
            $ret['itemProp'] = $itemProp;

            if(is_null($retorno[screenMsg])){
                $ret['screenMsg'] = 'Sucesso! Exemplar devolvido: '. $itemID;
            }else{
                $msg = implode('#', $retorno[screenMsg]);
                $ret['screenMsg'] = $msg;
            }
            
            $ret['printMsg'] = 'null';
        }
        else //CASO OCORRA A FALHA
        {
            $ret['ok'] = 'N';
            $ret['resensitize'] = 'N';
            $ret['alert'] = 'Y';
            $ret['dateTime'] = GDate::getYYYYMMDDHHMMSS($dateTime);
            $ret['instID'] = $instID;
            $ret['itemID'] = $itemID;
            
            $ret['permanentLoc'] = '0';
            $ret['titleID'] = 'null';
            $ret['sortBin'] = 'null';
            $ret['patronID'] = 'null';
            
            $ret['itemProp'] = $itemProp;

            if(is_null($retorno[screenMsg])){
                $ret['screenMsg'] = 'Desculpe, não consegui fazer a devolução do exemplar: '. $itemID . '. Consulte informações no balcão de atendimento.';
            }else{
                $msg = implode('#', $retorno[screenMsg]);
                $ret['screenMsg'] = $msg;
            }
            
            $ret['printMsg'] = 'null';
        }
        
        //Monta a string de retorno com as informações        
        $backInfo = implode(SIP_DELIMITER, $ret);
        //MUtil::flog($backInfo);
        
        
        $endTime = microtime(true);
        $time = $endTime - $startTime;
        //MUtil::flog("Operação realizada em : " . $time);
        
        return $backInfo;
    }

    
    
    /*
     * Esqueleto itemInformation, retorna uma String
     * Parametros:
     * 
     * String dateTime, 
     * String instID, 
     * String itemID,
     * String termID, 
     * String termPwd
     * 
     * Descrição: Função criada para retornar as informações de um exemplar
     *      
     * 
     * Criado por: Lucas Rodrigo Gerhardt
     * Em: 25/11/2013
     * Ultima Atualização por: 
     * Em: 
     * Motivo: 
     */
    public function itemInformation($dateTime, $instID, $itemID, $termID, $termPwd) 
    {
        try
        {
            $circulationStatus = $this->busExemplaryControl->getExemplaryStatus($itemID);
            
            if(!empty($circulationStatus))
            {
                $retorno['circulationStatus'] = $this->busSipCirculationStatus->getSipCirculationStatusId($circulationStatus);
            }
            else
            {
                $retorno['circulationStatus'] = 'NULL';
            }
            
            $retorno['securityMarker'] = 0;
            $retorno['dateTime'] = GDate::now()->getDate(GDate::MASK_DATE_STRING);

            $dataC = $this->busExemplaryStatusHistory->getDateOfLastReturn($itemID);
            $dataC = explode(" ", $dataC);
            $date = explode("/", $dataC[0]);
            $dateT = str_replace(":", "", $dataC[1]);
            $date = $date[2] . $date[1] . $date[0] . $dateT;

            $retorno['dueDate'] = $date;
           
            if (empty($retorno['dueDate']))
            {
                $retorno['dueDate'] = 'NULL';
            }
            
            $retorno['recallDate'] = $retorno['dateTime'];
            $retorno['itemId'] = $itemID;
            
            if (empty($retorno['itemId']))
            {
                $retorno['itemId'] = 'NULL';
            }
            
            $retorno['titleID'] = $this->busMaterial->getMaterialTitleByItemNumber($itemID);
            
            if (empty($retorno['titleID']))
            {
                $retorno['titleID'] = 'NULL';
            }
            
            $retorno['owner'] = $this->busExemplaryStatusHistory->getLibraryOfItemNumber($itemID);
            
            if (empty($retorno['owner']))
            {
                $retorno['owner'] = 'NULL';
            }
            
            $retorno['permanentLoc'] = 'NULL';
            $retorno['currentLoc'] = 'NULL';
            
            $retorno['itemProp'] = $retorno['titleID'];
            
            if (empty($retorno['itemProp']))
            {
                $retorno['itemProp'] = 'NULL';
            }
            if( $retorno['circulationStatus'] != 'NULL' &&  $retorno['itemId'] != 'NULL')
            {
                $retorno['screenMsg'] = 'Item conferido com sucesso!';
            }
            else
            {
                $retorno['screenMsg'] = 'Não foi encontrado o item informado!';
            }
            
            $retorno['printMsg'] = 'NULL';
        }
        catch ( Exception $e )
        {
            $retorno['screenMsg'] = $e->getMessage();
        }
        
        $itemInformation = implode(SIP_DELIMITER, $retorno);
        
        return $itemInformation;
    }

    /*
     * Esqueleton renew, retorna uma String
     * Parametros:
     * 
     * Boolean thdAllowed, 
     * Boolean noBlock, 
     * String dateTime, 
     * String nbDueDate, 
     * String instID, 
     * String patronID, 
     * String patronPwd, 
     * String itemID, 
     * String titleID, 
     * String termID, 
     * String termPwd, 
     * String itemProp
     * 
     * Descrição:
     *      Método que realiza a renovação.
     * 
     * Criado por: Tcharles Silva
     * Em: 02/12/2013
     * Ultima Atualização por: 
     * Em: 
     * Motivo: 
     */
    public function renew( $thdAllowed, $noBlock, $dateTime, $nbDueDate, $instID, $patronID,
                          $patronPwd, $itemID, $titleID, $termID, $termPwd, $itemProp ) 
    {
        
        //MUtil::flog("------ Operação RENEW -------");
        $startTime = microtime(true);
        
        $titulo = $this->busMaterial->getMaterialTitleByItemNumber($itemID);
        if(empty($titulo))
        {
            $titulo = 'null';
        }
        
        /* - Método doLoan que realiza empréstimo/renovação --
        GSipCirculation::doLoan($padraoLoan, $termId, $personId, $itemNumber, $loanTypeId )
         - padraoLoan = '1'
         - termId = ""
         - personId = ""
         - itemNumber = ""
         - loanTypeId = "4"
         */
        $retorno = GSipCirculation::doLoan('1', $termID, $patronID, $itemID, '4');
        
        if($retorno[ok] == 'Y')
        {
            //Decorrer do código aqui.... Caso tenha concluido a operação
            $ret["ok"] = 'Y';
            $ret["renewalOk"] = $retorno[renewalOk];
            $ret["desensitize"] = "Y";
            $ret["dateTime"] = $retorno[dateTime];
            $ret["instID"] = $retorno[instID];
            $ret["patronID"] = $retorno[patronID];
            $ret["itemID"] = $retorno[itemID];
            $ret["titleID"] = $titulo;
            $ret["dueDate"] = $retorno[dueDate];
            $ret["securityInhibit"] = "N";
            
            if(empty($itemProp))
            {
                $itemProp = 'null';
            }
            $ret["itemProp"] = $itemProp;

            if(is_null($retorno[screenMsg]))
            {
                if($retorno[renewalOk] == 'Y')
                {
                    $ret["screenMsg"] = "Sucesso! Renovação do item " . $itemID . " concluída.";
                }
                else
                {
                    $ret["screenMsg"] = "Sucesso! Empréstimo concluído.";
                }
            }else
            {
                $ret['screenMsg'] = $retorno[screenMsg];
            }
            
            $ret["printMsg"] = "null";
        }
        else //CASO OCORRA A FALHA
        {
            $ret["ok"] = 'N';
            $ret["renewalOk"] = "N";
            $ret["desensitize"] = "N";
            //Colocar a data no formato abaixo
            $v4 = GDate::getYYYYMMDDHHMMSS($dateTime);
            if(empty($v4))
            {
                $v4 = 'null';
            }
            $ret["dateTime"] = $v4;
            
            if(empty($instID))
            {
                $instID = 'null';
            }
            $ret["instID"] = $instID;
            
            if(empty($patronID))
            {
                $patronID = 'null';
            }
            $ret["patronID"] = $patronID;
            
            if(empty($itemID))
            {
                $itemID = 'null';
            }
            $ret["itemID"] = $itemID;
            
            if(empty($retorno[titleID]))
            {
                $retorno[titleID] = 'null';
            }
            $ret["titleID"] = $titulo;
            
            if(empty($retorno[dueDate]))
            {
                $dataRet = GDate::getYYYYMMDDHHMMSS($dateTime);
                $retorno[dueDate] = $dataRet;
            }
            $ret["dueDate"] = $retorno[dueDate];
            $ret["securityInhibit"] = "N";
            
            if(empty($itemProp))
            {
                $itemProp = 'null';
            }
            $ret["itemProp"] = $itemProp;

            if(empty($retorno[screenMsg]))
            {
                $retorno[screenMsg] = 'Desculpe, mas não concluí a renovação. Consulte mais informações no balcão de atendimento.';
            }
            $ret['screenMsg'] = $retorno[screenMsg];
            
            $ret["printMsg"] = "null";
        }
        
        //Monta a string de retorno com as informações        
        $backInfo = implode(SIP_DELIMITER, $ret);
        //MUtil::flog($backInfo);
        
        $endTime = microtime(true);
        $time = $endTime - $startTime;
        //MUtil::flog("Operação realizada em : " . $time);

        return $backInfo;
    }

    
    
    /*
     * Esqueleto de RENEWALL, retorna uma String
     * Parametros:
     * 
     * String dateTime, 
     * String instID, 
     * String patronID, 
     * String patronPwd, 
     * String termID, 
     * String termPwd
     * 
     * Descrição:
     *      
     * 
     * Criado por: 
     * Em: 
     * Ultima Atualização por: 
     * Em: 
     * Motivo: 
     */
    public function renewAll($dateTime, $instID, $patronID, $patronPwd, $termID, $termPwd) 
    { 
        //MUtil::flog("----- Operação RENEWALL ------");
        $startTime = microtime(true);
        
        //Formata a data
        $data = GDate::getYYYYMMDDHHMMSS($dateTime);
        
        $this->busLoan->personId = $patronID;
        $this->busLoan->orderByLibraryUnit = TRUE;
        $var = $this->busLoan->getLoansOpen();
        
        //Mensagens de screen
        $sMsg = array();
        
        //Contadores
        $renewalCount = 0;
        $unRenewalCount = 0;
        $numOp = 0;
        
        $renDone = array();
        $renNotDone = array();
        
        ////////////////////////////////////////////////////
        //Recebe informações do equipamento
        $dadosSip = $this->busSipEquipament->getSipEquipament($termID);

        //Setar libraryUnitId e Setar Location
        $this->busOperationLoanSip->setLibraryUnit($dadosSip->libraryUnitId);
        $this->busOperationLoanSip->setLocation($dadosSip->locationformaterialmovementid);
        
        //Setando pessoa para otimizar a renovação de todos os itens
        $pessoa = $this->busOperationLoanSip->setPerson($patronID, $dadosSip->libraryUnitId, $dadosSip->locationformaterialmovementid);
        
        ///////////////////////////////////////////////

        foreach($var as $loan)
        {
            //MUtil::flog("--------------------------------------------");
            //MUtil::flog("Numero da operação: " . $numOp);
                 
            $emp[$numOp] = GSipCirculation::doLoan('1', $termID, $patronID, $loan->itemNumber, '4', $pessoa);
            
            if($emp[$numOp][ok] == 'Y'){
                
                $renewalCount++;
                $renDone[] = $loan->itemNumber;
                
                if(!$emp[$numOp][screenMsg]){
                    $sMsg[] = "Exemplar " . $loan->itemNumber . " [Renovado]";
                    //MUtil::flog("Exemplar " . $loan->itemNumber . " [Renovado]");
                }
                else{
                    $sMsg[] = $emp[$numOp][screenMsg];
                    //MUtil::flog($emp[$numOp][screenMsg]);
                }
            }
            else
            {
                if(!$emp[$numOp][screenMsg]){
                    $sMsg[] = "Exemplar " . $loan->itemNumber . " [Falha]";
                }
                else{
                    $sMsg[] = $emp[$numOp][screenMsg];
                }
                
                $unRenewalCount++;
                $renNotDone[] = $loan->itemNumber;
            }
            $numOp++;
        }
        
        //Verifica se todas as operações foram renovadas
        if($numOp == 0)
        {
            $retorno['ok'] = 'N';
            $sMsg[] = "Usuário não possui empréstimos.";
        }
        else{
            if($numOp == $renewalCount){
                $retorno['ok'] = 'Y';
            }else{
                $retorno['ok'] = 'N';
            }
        }

        $retorno['renewalCount'] = $renewalCount;
        $retorno['unRenewalCount'] = $unRenewalCount;
        $retorno['dateTime'] = $data;
        $retorno['instID'] = $instID;
        
        //Verifica se foi feita alguma renovação
        if(count($renDone) < 1)
        {
            $retorno['renewedItens'] = 'null';
        }
        else
        {
            $retorno['renewedItens'] = implode(',', $renDone);
        }
        
        //Verifica se NAO foi feita renovação
        if(count($renNotDone) < 1)
        {
            $retorno['unRenewedItens'] = 'null';
        }
        else
        {
            $retorno['unRenewedItens'] = implode(',', $renNotDone);
        }

        $retorno['screenMsg'] = implode('#', $sMsg);
        $retorno['printMsg'] = 'null';
        
        $backInfo = implode(SIP_DELIMITER, $retorno);
        
        $endTime = microtime(true);
        $time = $endTime - $startTime;
        //MUtil::flog("Operação realizada em : " . $time);
        
        return $backInfo;
    }
    
    /*
     * Esqueleto de PATRONINFO, retorno String
     * Parametros:
     * 
     * String dateTime, 
     * String summary, 
     * String instID, 
     * String patronID, 
     * String patronPwd, 
     * String termID, 
     * String termPwd, 
     * int startItem, 
     * int endItem
     * 
     * Descrição:
     *      
     * 
     * Criado por: 
     * Em: 
     * Ultima Atualização por: 
     * Em: 
     * Motivo: 
     */
    public function patronInfo($language, $dateTime, $summary, $instID, $patronID, $patronPwd, $termID, $termPwd, $startItem, $endItem ) 
    {        
        $startTime = microtime(true);
        
        $isPerson = $this->busAuthenticate->authenticate($patronID, $patronPwd);
        //$isPerson = $this->busPerson->authenticate($patronID, $patronPwd);
        $data = GDate::getYYYYMMDDHHMMSS($dateTime);        
        
        $patronStatus = Array();
        
        $hItens = Array();
        $oItens = Array();
        $cItens = Array();
        $fItens = Array();
        $rItens = Array();
        $uItens = Array();
        
        //Variáveis para contadores
        $holdItensCount = 0; //Reservas Solicitadas
        $overdueItensCount = 0; //Emprestimos atrasados
        $chargedItensCount = 0; //Itens com o usuário
        $fineItensCount = 0; //Multas para o usuario
        $recallItensCount = 0; //Itens que a biblioteca quer devolta
        //* Este campo abaixo não será utilizado no Gnuteca. *//
        $uHoldItensCount = 0; //Indisponíveis na biblioteca
        
        //Tenta se logar, verifica se o usuário existe
        
        if($isPerson)
        {
            $person = $this->busPerson->getPerson($patronID);
            if($person)
            {
                $nome = $person->personName;
                $local = $person->cityName;
                $phone = $person->phone;
                foreach($phone as $ph)
                {
                    $fone[] = $ph->phone;
                }
                $phone = implode(',', $fone);
            }
            
            //Define o grupo de maior prioridade do usuário
            $link = $this->busBond->getActivePersonLink($patronID);
            //Realiza pesquisa para obter as politicas
            $policy = $this->busPolicy->getUserPolicy($instID, $patronID, $link->activelink);
            //Define os valores
            $holdItensLimit = $policy[0]->reserveLimit;
            $chargedItensLimit = $policy[0]->loanLimit;
            
            //Instanciando o objeto busRight para realizar a pesquisa
            $this->busRight->linkId = $link->activelink;
            //Atribui valor 1, pois é refente à livro
            $this->busRight->materialGenderId = 1;
            $this->busRight->operationId = ID_OPERATION_LOAN;
            
            //Verifica se encontra direito de empréstimo ao usuário
            $right = $this->busRight->verifyRightSip();
            
            //Se tiver direito, seta o valor de limite de atraso
            if($right)
            {
                $overdueItensLimit = $policy[0]->loanLimit;
            }
            else
            {
                $overdueItensLimit = 0;
            }
            
            //Variaveis para serem utilizadas nos métodos Staticos
            $linkPessoa = $link->activelink; //LINK
            
            
            //Valores no retorno Patron Status
            //
            //0- Direito de empréstimo negado e 
            //1- Renovação negado
            
            $rightLoan = $comPenal = GSipCirculation::getRightWith('l', $patronID, $linkPessoa, ID_OPERATION_LOAN, NULL );
            
            if(!rightLoan)
            {
                //Não tem direito a empréstimo
                $patronStatus[] = '0';
                $patronStatus[] = '1';
                
            }else
            {
                //verificar se tem penalidade
                $comPenal = GSipCirculation::getRightWith('p', $patronID, $linkPessoa, ID_OPERATION_LOAN_PENALTY, NULL );
                if($comPenal)
                {
                    $patronStatus[] = '0';
                    $patronStatus[] = '1';
                }
                else{
                    //verificando se tem multa ( verifica apenas com status: aberta )
                    
                    $comMulta = GSipCirculation::getRightWith('f', $patronID, $linkPessoa, ID_OPERATION_LOAN_FINE, $instID);
                    if($comMulta)
                    {
                        $patronStatus[] = '0';
                        $patronStatus[] = '1';
                    }
                }
            }
            
            //2- Direito de pedir o item devolta negado
                //Não existe atualmente no Gnuteca
            
            
            //3- Direito de reserva negado
            $fazRen = GSipCirculation::getRightWith('l', $patronID, $linkPessoa, ID_OPERATION_LOCAL_RESERVE, NULL);
            if(!$fazRen)
            {
                $patronStatus[] = '3';
            }
            
            //4- Cartão dado como perdido
                //Ainda não disponivel no Gnuteca, não será implementado.
            
            
            //5- Estorou limite de empréstimos
            $this->busLoan->personId = $patronID;
            $this->busLoan->orderByLibraryUnit = TRUE;
            $emp = $this->busLoan->getLoansOpen();
            //Contador para ver numero de emprestimos atuais
            $empN = 0;
            foreach($emp as $c)
            {
                $empN++;
            }
            if($chargedItensLimit <= $empN)
            {
                $patronStatus[] = '5';
            }
            
            
            //6- Estorou limite de atrasos
            if($overdueItensLimit > $policy[0]->loanLimit)
            {
                $patronStatus[] = '6';
            }
            
            
            //7- Estorou limite de renovações
                //Usuario nao possui limite de renovações
            
            
            //8- Muitas reclamações de itens devolvidos
            $comRecl = GSipCirculation::getRightWith('p',  $patronID, $linkPessoa, ID_OPERATION_LOAN_PENALTY, NULL );
            if($comRecl)
            {
                $patronStatus[] = '8';
            }
            
            
            //9- Estorou limite de itens perdidos
                //Gnuteca não tem essa funcionalidade
            

            //10- Multas excessivas em circulação (Mostrará apenas as com status : Aberta
            $comFine = GSipCirculation::getRightWith('f',  $patronID, $linkPessoa, ID_OPERATION_LOAN_FINE, $instID);
            if($comFine)
            {
                $patronStatus[] = '10';
            }
            
            
            //11- Penalidades excessivas em circulação
            $comPenal = GSipCirculation::getRightWith('p',  $patronID, $linkPessoa, ID_OPERATION_LOAN_PENALTY, NULL);
            if($comPenal)
            {
                $patronStatus[] = '11';
            }
            
            //12- Devolver para a biblioteca com atraso
            
            
            //13- Muitas faturas
            $patronStatus = implode('.', $patronStatus);
            
            //Verificar as operações que irá fazerM
            $hold = stripos($summary, 'H');
            $overdue = stripos($summary, 'O');
            $charged = stripos($summary, 'C');
            $fine = stripos($summary, 'F');
            $recall = stripos($summary, 'R');
            $unavailable = stripos($summary, 'U');

            //Reservas feitas pelo usuário
            if($hold !== FALSE)
            {
                //Define a pessoa
                $this->busReserve->personId = $person->personId;
                //Apenas irá trazer as reservas solicitadas
                $this->busReserve->reserveTypeIdS = ID_RESERVESTATUS_REQUESTED;
                //Pegando as reservas para a variavel
                $reservas = $this->busReserve->searchReserve();

                foreach($reservas as $r)
                {
                    $this->busReserveComposition->reserveId = $r[0];
                    $this->busReserveComposition->reserveIdS = $r[0];
                    $var = $this->busReserveComposition->searchReserveComposition(TRUE);

                    foreach($var as $v)
                    {
                        if($v->isConfirmed == 'f')
                        {
                           //$this->busReserve->reserveId = $v->reserveId;
                           
                           $reserv = $this->busReserve->getReserve($v->reserveId, TRUE);
                           if($reserv->reserveStatusId == '1' || $reserv->reserveStatusId == '2' || $reserv->reserveStatusId == '3')
                           {
                                //Poe na lista
                                $hItens[] = $v->itemNumber;
                                //Incrementa contador
                                $holdItensCount++;
                           }
                        }
                    }
                }
                $holdItens = implode(',', $hItens);
            }

            //Itens que já passaram da data de entrega
            if($overdue !== FALSE)
            {
                //seta User
                $this->busLoan->personId = $patronID;
                //seta Data
                $now = GDate::now();
                $now->setHour('00');
                $now->setMinute('00');
                $now->setSecond('00');
                $now = $now->getDate(GDate::MASK_TIMESTAMP_USER);
                $this->busLoan->returnForecastDate = $now;

                //Busca todos os empréstimos atrasados
                $loans = $this->busLoan->getDelayedLoanByUser();         

                //Se não tiver nenhum material atrasado neste período
                if ( $loans )
                {
                    foreach($loans as $l)
                    {
                        $overdueItensCount++;
                        $oItens[] = $l->itemNumber;
                    }
                }
                $overdueItens = implode(',', $oItens);
            }
            
            //Itens que estão com o usuário
            if($charged !== FALSE)
            {
                $this->busLoan->personId = $patronID;
                $this->busLoan->orderByLibraryUnit = TRUE;
                $var = $this->busLoan->getLoansOpen();
                foreach($var as $loan)
                {
                    $chargedItensCount++;
                    $cItens[] = $loan->itemNumber;
                }
                $chargedItens = implode(',', $cItens);
            }
            
            //Itens que serão cobrados multa
            if($fine !== FALSE)
            {
                $this->busFine->personId = $patronID;
                $this->busFine->personIdS = $patronID;
                
                $fAberta = $this->busFine->searchFine(TRUE);
                
                if($fAberta)
                {
                    foreach($fAberta as $f)
                    {
                        if($f->endDate == NULL)
                        {
                            $loan = $this->busLoan->getLoan($f->loanId, TRUE);
                            $fItens[] = $loan->itemNumber;
                            $fineItensCount++;
                        }
                    }
                    $fineItens = implode(',', $fItens);
                }
            }
            
            //Livros que estão com o usuario e a biblioteca solicita devolta
            if($recall !== FALSE)
            {
                $this->busLoan->personId = $patronID;
                $this->busLoan->orderByLibraryUnit = TRUE;
                $var = $this->busLoan->getLoansOpen();

                foreach($var as $loan)
                {
                    //Apenas irá contabilizar as reservas requeridas
                    if($this->busReserve->hasReserve($loan->itemNumber, ID_RESERVESTATUS_REQUESTED))
                    {
                        $rItens[] = $loan->itemNumber;
                        $recallItensCount++;
                    }
                }
                $recallItens = implode(',', $rItens);
            }
            
            //Livros reservados que não estão disponíveis na biblioteca
            if($unavailable !== FALSE)
            {
                //Não acontece no Gnuteca, e não será utilizado
            }
            
            //Verificações para ver se não estão vazias
            if(empty($patronStatus))
            {
                $patronStatus = ' ';
            }
            if(empty($holdItens))
            {
                $holdItens = 'null';
            }
            if(empty($overdueItens))
            {
                $overdueItens = 'null';
            }
            if(empty($chargedItens))
            {
                $chargedItens = 'null';
            }
            if(empty($fineItens))
            {
                $fineItens = 'null';
            }
            if(empty($recallItens))
            {
                $recallItens = 'null';
            }
            if(empty($phone))
            {
                $phone = 'null';
            }
            
            //Montagem do retorno
            
            $retorno['patronStatus'] = $patronStatus;
            $retorno['language'] = '10';
            $retorno['dateTime'] = $data;
            $retorno['holdItensCount'] = $holdItensCount;
            $retorno['overdueItensCount'] = $overdueItensCount;
            $retorno['chargedItensCount'] = $chargedItensCount;
            $retorno['fineItensCount'] = $fineItensCount;
            $retorno['recallItensCount'] = $recallItensCount;
            $retorno['uHoldsItensCount'] = $uHoldItensCount;
            
            $retorno['instID'] = $instID;
            $retorno['patronID'] = $patronID;
            $retorno['personalName'] = $nome;

            $retorno['holdItensLimit'] = $holdItensLimit;
            $retorno['overdueItensLimit'] = $overdueItensLimit;
            $retorno['chargedItensLimit'] = $chargedItensLimit;
            
            $retorno['validPatron'] = 'Y';
            $retorno['validPatronPwd'] = 'Y';
            
            $retorno['holdItens'] = $holdItens;
            $retorno['overdueItens'] = $overdueItens;
            $retorno['chargedItens'] = $chargedItens;
            $retorno['fineItens'] = $fineItens;
            $retorno['recallItens'] = $recallItens;
            $retorno['uHoldItens'] = 'null';
            $retorno['homeAdress'] = $local;
            $retorno['homePhone'] = $phone;
            $retorno['screenMsg'] = 'Usuário encontrado.';
            $retorno['printMsg'] = 'null';
        }
        else
        {
            $retorno['patronStatus'] = ' ';
            $retorno['language'] = '10';
            $retorno['dateTime'] = $data;
            $retorno['holdItensCount'] = $holdItensCount;
            $retorno['overdueItensCount'] = $overdueItensCount;
            $retorno['chargedItensCount'] = $chargedItensCount;
            $retorno['fineItensCount'] = $fineItensCount;
            $retorno['recallItensCount'] = $recallItensCount;
            $retorno['uHoldsItensCount'] = $uHoldItensCount;
            
            $retorno['instID'] = $instID;
            $retorno['patronID'] = $patronID;
            $retorno['personalName'] = 'null';
            
            $retorno['holdItensLimit'] = 'NULL';
            $retorno['overdueItensLimit'] = 'NULL';
            $retorno['chargedItensLimit'] = 'NULL';
            
            $retorno['validPatron'] = 'N';
            $retorno['validPatronPwd'] = 'NULL';
            
            if(empty($holdItens))
            {
                $holdItens = 'null';
            }
            $retorno['holdItens'] = $holdItens;
            
            if(empty($overdueItens))
            {
                $overdueItens = "null";
            }
            $retorno['overdueItens'] = $overdueItens;
            
            if(empty($chargedItens)){
                $chargedItens = 'null';
            }
            $retorno['chargedItens'] = $chargedItens;
            
            if(empty($fineItens))
            {
                $fineItens = "null";
            }
            $retorno['fineItens'] = $fineItens;
            
            if(empty($recallItens))
            {
                $recallItens = "null";
            }
            $retorno['recallItens'] = $recallItens;
            
            $retorno['uHoldItens'] = 'null';
            $retorno['homeAdress'] = 'null';
            $retorno['homePhone'] = 'null';
            
            $retorno['screenMsg'] = 'Sem informações desse usuário.';
            $retorno['printMsg'] = 'null';
        }
        $backInfo = implode(SIP_DELIMITER, $retorno);
        
        $endTime = microtime(true);
        $time = $endTime - $startTime;
        //MUtil::flog("Operação realizada em : " . $time);
        
        return $backInfo;
    }
    
    public function patronStatus($termID, $language, $dateTime, $instID, $patronID, $termPwd, $patronPwd)
    {
        $isPerson = $this->busAuthenticate->authenticate($patronID, $patronPwd);
        $data = GDate::getYYYYMMDDHHMMSS($dateTime); 

        if($isPerson)
        {
            
            $person = $this->busPerson->getPerson($patronID);
            //MUtil::flog($person);
            
            //Define o grupo de maior prioridade do usuário
            $link = $this->busBond->getActivePersonLink($patronID);
            //Realiza pesquisa para obter as politicas
            $policy = $this->busPolicy->getUserPolicy($instID, $patronID, $link->activelink);
            //Define os valores
            $chargedItensLimit = $policy[0]->loanLimit;
            
            //Instanciando o objeto busRight para realizar a pesquisa
            $this->busRight->linkId = $link->activelink;
            //Atribui valor 1, pois é refente à livro
            $this->busRight->materialGenderId = 1;
            $this->busRight->operationId = ID_OPERATION_LOAN;
            
            //Verifica se encontra direito de empréstimo ao usuário
            $right = $this->busRight->verifyRightSip();
            
            //Se tiver direito, seta o valor de limite de atraso
            if($right)
            {
                $overdueItensLimit = $policy[0]->loanLimit;
            }
            else
            {
                $overdueItensLimit = 0;
            }
            
            //Variaveis para serem utilizadas nos métodos Staticos
            $linkPessoa = $link->activelink; //LINK
            
            $rightLoan = $comPenal = GSipCirculation::getRightWith('l', $patronID, $linkPessoa, ID_OPERATION_LOAN, NULL );

            if(!rightLoan)
            {
                //Não tem direito a empréstimo
                $patronStatus[] = '0';
                $patronStatus[] = '1';
            }else
            {
                //verificar se tem penalidade
                $comPenal = GSipCirculation::getRightWith('p', $patronID, $linkPessoa, ID_OPERATION_LOAN_PENALTY, NULL );
                if($comPenal)
                {
                    $patronStatus[] = '0';
                    $patronStatus[] = '1';
                }else
                {
                    //verificando se tem multa ( verifica apenas com status: aberta )
                    $comMulta = GSipCirculation::getRightWith('f', $patronID, $linkPessoa, ID_OPERATION_LOAN_FINE, $instID);
                    if($comMulta)
                    {
                        $patronStatus[] = '0';
                        $patronStatus[] = '1';
                    }
                }
            }

            //2- Direito de pedir o item devolta negado
            //Não existe atualmente no Gnuteca

            //3- Direito de reserva negado
            $fazRen = GSipCirculation::getRightWith('l', $patronID, $linkPessoa, ID_OPERATION_LOCAL_RESERVE, NULL);
            if(!$fazRen)
            {
                $patronStatus[] = '3';
            }

            //4- Cartão dado como perdido
            //Ainda não disponivel no Gnuteca, não será implementado.


            //5- Estorou limite de empréstimos
            $this->busLoan->personId = $patronID;
            $this->busLoan->orderByLibraryUnit = TRUE;
            $emp = $this->busLoan->getLoansOpen();
            //Contador para ver numero de emprestimos atuais
            $empN = 0;
            foreach($emp as $c)
            {
                $empN++;
            }
            if($chargedItensLimit <= $empN)
            {
                $patronStatus[] = '5';
            }

            //6- Estorou limite de atrasos
            if($overdueItensLimit > $policy[0]->loanLimit)
            {
                $patronStatus[] = '6';
            }

            //7- Estorou limite de renovações
            //Usuario nao possui limite de renovações

            //8- Muitas reclamações de itens devolvidos
            $comRecl = GSipCirculation::getRightWith('p',  $patronID, $linkPessoa, ID_OPERATION_LOAN_PENALTY, NULL );
            if($comRecl)
            {
                $patronStatus[] = '8';
            }

            //9- Estorou limite de itens perdidos
            //Gnuteca não tem essa funcionalidade

            //10- Multas excessivas em circulação (Mostrará apenas as com status : Aberta
            $comFine = GSipCirculation::getRightWith('f',  $patronID, $linkPessoa, ID_OPERATION_LOAN_FINE, $instID);
            if($comFine)
            {
                $patronStatus[] = '10';
            }

            //11- Penalidades excessivas em circulação
            $comPenal = GSipCirculation::getRightWith('p',  $patronID, $linkPessoa, ID_OPERATION_LOAN_PENALTY, NULL);
            if($comPenal)
            {
                $patronStatus[] = '11';
            }

            //12- Devolver para a biblioteca com atraso

            //13- Muitas faturas
            $patronStatus = implode('.', $patronStatus);
            
            $retorno['patronStatus'] = $patronStatus;
            $retorno['language'] = $language;
            $retorno['dateTime'] = $data;
            $retorno['instID'] = $instID;
            $retorno['patronID'] = $patronID;
            $retorno['personalName'] = $person->personName;
            $retorno['validPatron'] = "Y";
            $retorno['validPatronPwd'] = "Y";
            $retorno['screenMsg'] = "Seja bem-vindo $person->personName";
            $retorno['printMsg'] = "";
            
            $ret = implode(SIP_DELIMITER, $retorno);
            return $ret;
        }
        else
        {
            $retorno['patronStatus'] = "NULL";
            $retorno['language'] = $language;
            $retorno['dateTime'] = $data;
            $retorno['instID'] = $instID;
            $retorno['patronID'] = $patronID;
            $retorno['personalName'] = "";
            $retorno['validPatron'] = "N";
            $retorno['validPatronPwd'] = "N";
            $retorno['screenMsg'] = "Ainda não cadastraram você.";
            $retorno['printMsg'] = "";
            
            $ret = implode(SIP_DELIMITER, $retorno);
            return $ret;
        }
    }
}
?>