<?php
/**
 * Copyright 2005-2019 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.
 * 
 * 
 * RemissiveDictionary business
 *
 *
 *
 *
 *
 **/
class BusinessGnuteca3BusDictionaryRemissive extends GBusiness
{
    public $busMaterialDictionaryRemissive;
    public $dictionaryRemissiveId;
    public $dictionaryRemissiveIdAux;
    public $dictionaryContentId;
    public $remissiveContent;
    public $line;

    public function __construct()
    {
        $MIOLO = MIOLO::getInstance();
        $table = 'gtcdictionaryremissive';
        $pkeys = 'dictionaryRemissiveId';
        $cols  = 'dictionaryContentId,
                  remissiveContent,
                  line';
        
        $this->busMaterialDictionaryRemissive = $MIOLO->getBusiness('gnuteca3', 'BusMaterialDictionaryRemissive');
        parent::__construct($table, $pkeys, $cols);
    }

    public function insertDictionaryRemissive()
    {
        return $this->autoInsert();
    }

    public function updateDictionaryRemissive()
    {
    	if (($this->removeData) || (!$this->dictionaryRemissiveId))
    	{
    		$this->insertDictionaryRemissive();
    		return TRUE;
    	}
        
        return $this->autoUpdate();
    }

    public function deleteDictionaryRemissive($dictionaryRemissiveId)
    {
        return $this->autoDelete($dictionaryRemissiveId);
    }

    public function getDictionaryRemissive($dictionaryRemissiveId)
    {
        $this->clear();
        return $this->autoGet($dictionaryRemissiveId);
    }

    public function searchDictionaryRemissive($toObject = false)
    {
        $this->clear();
        $filters = array(
            'dictionaryRemissiveId'=> 'equals',
            'dictionaryContentId' => 'equals',
            'remissiveContent' => 'ilike',
            'line' => 'equals'
        );
        
        return $this->autoSearch($filters, $toObject);
    }

    public function listDictionaryRemissive()
    {
        return $this->autoList();
    }
    
    public function updateMaterialContent($dictionaryId, $dictionaryContentId, $content, $dictionaryRemissives)
    {
        $MIOLO = MIOLO::getInstance();
        
        $businessMaterialDictionaryRemissive = $MIOLO->getBusiness($this->module, 'BusMaterialDictionaryRemissive');
        $busDictionary = $MIOLO->getBusiness($this->module, 'BusDictionary');
        $dic = $busDictionary->getDictionaryForRemissivesUpdate( $dictionaryId );
        
        $busMaterial = $MIOLO->getBusiness('gnuteca3', 'BusMaterial');
        
        $busMaterialDictionaryRemissive = $MIOLO->getBusiness('gnuteca3', 'BusMaterialDictionaryRemissive');
        
        // Remove os registros excluídos da repetitive field.
        if ( $dictionaryRemissives )
        {
            $dictionaryRemissivesAux = array();            
            foreach ( $dictionaryRemissives as $remissive )
            {
                if ( !isset($remissive->removeData) )
                {
                    $dictionaryRemissivesAux[] = $remissive;
                }
            }
            
            $dictionaryRemissives = $dictionaryRemissivesAux;
        }
        
        // Se o dicionário tiver destino de remissiva configurado, copia as remissivas do conteúdo para o campo destino.
        if ( $dic->remissiveTag )
        {
            $remissieveTagParts = explode('.', $dic->remissiveTag);
            
            $materialWithDicionaryContentControl = array();
            $tags = array();
            
            if ( is_array($dic->tags) )
            {
                foreach ( $dic->tags as $line => $tag )
                {
                    $busMaterial->clean();
                    $busMaterial->fieldid = $tag->fieldId;
                    $busMaterial->subfieldid = $tag->subfieldId;
                    $busMaterial->exactContent = $content;
                    $materialsWithDicionaryContent = $busMaterial->searchMaterial(true);
                    
                    foreach ( $materialsWithDicionaryContent as $material )
                    {
                        // Obtém os dados já armazenados de remissivas.
                        $businessMaterialDictionaryRemissive->clean();
                        $businessMaterialDictionaryRemissive->controlNumber = $material[0]; // Número de controle.
                        $businessMaterialDictionaryRemissive->fieldId = $remissieveTagParts[0]; // 400
                        $businessMaterialDictionaryRemissive->subfieldId = $remissieveTagParts[1]; //a
                        $materialDictionaryRemissive = $businessMaterialDictionaryRemissive->searchMaterialDictionaryRemissive(true);
                        $this->updateMaterial($material[0], $dictionaryRemissives, $materialDictionaryRemissive, $material[1], $material[2], $material[3], $remissieveTagParts[0], $remissieveTagParts[1]);
                    }
                }
            }
        }
    }
    
    public function updateMaterial($controlNumber, $dicionaryRemissives, $materialRemissives, $sourceFieldId, $sourceSubfieldId, $sourceLine, $remissiveFieldId, $remissiveSubfieldId, $revisionNumber=NULL)
    {
        $MIOLO = MIOLO::getInstance();
        
        $busMaterialHistory = $MIOLO->getBusiness('gnuteca3', 'BusMaterialHistory');
        
        // Prepara objeto do histórico.
        $historyObj= new stdClass();
        $historyObj->controlNumber = $controlNumber;
        // $historyObj->revisionNumber = $busMaterialHistory->getNextRevision($controlNumber);
        $historyObj->operator = GOperator::getOperatorId();
        $historyObj->data = GDate::now()->getDate(GDate::MASK_TIMESTAMP_DB);
        $historyObj->fieldId = $remissiveFieldId;
        $historyObj->subFieldId = $remissiveSubfieldId;

        if ( !$revisionNumber )
        {
            $revisionNumber = $busMaterialHistory->getNextRevision($controlNumber);
        }
        
        $historyObj->revisionNumber = $revisionNumber;

        //adiciona os indicadores
        $historyObj->previousIndicator1 = null;
        $historyObj->currentIndicator1 = null;
        $historyObj->previousIndicator2 = null;
        $historyObj->currentIndicator2 = null;
        $historyObj->previousprefixid = null;
        $historyObj->currentprefixid = null;
        $historyObj->previoussuffixid = null;
        $historyObj->currentsuffixid = null;
        $historyObj->previousseparatorid = null;
        $historyObj->currentseparatorid = null;   
        
        $busMaterialDictionaryRemissive = $MIOLO->getBusiness($this->module, 'BusMaterialDictionaryRemissive');
        $busMaterial = $MIOLO->getBusiness('gnuteca3', 'BusMaterial');
        
        $allMaterialRemissivesOrder = array();
        $newArrayRemissives = array();
        
        $allMaterialRemissivesOrder = array();
        // Fatia em campos e subcampos para poder ordenar.
        foreach ( $materialRemissives as $materialRemissive )
        {        
            $allMaterialRemissivesOrder[$materialRemissive->sourceFieldId . '.' . $materialRemissive->sourceSubfieldId . '.' . $materialRemissive->sourceLine][] = $materialRemissive;
        }
        
        $allMaterialRemissivesOrder[$sourceFieldId . '.' . $sourceSubfieldId . '.' . $sourceLine] = $dicionaryRemissives;
        
        // Ordena por campo.subcampo.linha de origem.
        ksort($allMaterialRemissivesOrder);
        
        // Converte remissivas ordenadas e agrupadas por origem em um vetor simples.
        foreach ( $allMaterialRemissivesOrder as $remissive )
        {
            $newArrayRemissives = array_merge($newArrayRemissives, $remissive);
        }
        // Itera para inserir//editar.
        foreach ( $newArrayRemissives as $line => $remissive )
        {
            // Inserir.
            if ( !$materialRemissives[$line] )
            {
                // Histórico do material .
                $historyInsert = $historyObj;
                $historyInsert->chancesType  = BusinessGnuteca3BusMaterialHistory::CHANGETYPE_INSERT;

                $historyInsert->previousLine = $line;
                $historyInsert->currentLine = $line;

                $historyInsert->previousContent = '';
                $historyInsert->currentContent = $remissive->remissiveContent;

                $busMaterialHistory->clean();
                $busMaterialHistory->setData($historyInsert);
                $busMaterialHistory->insertMaterialHistory();
                
                $busMaterialDictionaryRemissive->clean();
                $busMaterialDictionaryRemissive->dictionaryContentId = $remissive->dictionaryContentId;
                $busMaterialDictionaryRemissive->remissiveContent = $remissive->remissiveContent;
                $busMaterialDictionaryRemissive->controlNumber = $controlNumber;
                $busMaterialDictionaryRemissive->line = $line;
                $busMaterialDictionaryRemissive->fieldId = $remissiveFieldId;
                $busMaterialDictionaryRemissive->subfieldId = $remissiveSubfieldId;
                
                // Novo
                if ( !isset($remissive->materialDictionaryRemissiveId) )
                {
                    $busMaterialDictionaryRemissive->sourceLine = $sourceLine;
                    $busMaterialDictionaryRemissive->sourceFieldId = $sourceFieldId;
                    $busMaterialDictionaryRemissive->sourceSubfieldId = $sourceSubfieldId;
                }
                else // Deslocamento de linha.
                {
                    $busMaterialDictionaryRemissive->sourceLine = $remissive->sourceLine;
                    $busMaterialDictionaryRemissive->sourceFieldId = $remissive->sourceFieldId;
                    $busMaterialDictionaryRemissive->sourceSubfieldId = $remissive->sourceSubfieldId;
                }
                
                $busMaterialDictionaryRemissive->insertMaterialDictionaryRemissive();
                
                // Insere na gtcmaterial.
                $materialObj = new stdClass();
                $materialObj->controlNumber = $controlNumber;
                $materialObj->fieldid = $remissiveFieldId;
                $materialObj->subfieldid = $remissiveSubfieldId;
                $materialObj->line = $line;

                // Faz uma busca por registros para definir a linha, ticket #143386
                // Busca todos os valores com base no fieldid e subfieldid
                $array = $busMaterial->getContent($controlNumber, $remissiveFieldId, $remissiveSubfieldId, null, false,  true);
                if (is_array($array))
                {    
                    // valor do count vai representar o numero da linha
                    $materialObj->line = count($array); 
                }

                $materialObj->content = $remissive->remissiveContent;
                
                // Caso a remessiva e o campo principal sejam da mesma tag (fieldid) e repetitivos, um precisa ficar do lado do outro na tabela.
                // Ambos precisam ter o mesmo valor em line
                $busTag = $MIOLO->getBusiness('gnuteca3', 'BusTag');
                if (
                    $remissiveFieldId == $sourceFieldId
                    && $busTag->isRepetitive($sourceFieldId, $sourceSubfieldId)
                    && $busTag->isRepetitive($remissiveFieldId, $remissiveSubfieldId)
                ) {
                    $materialObj->line = $sourceLine;
                    $materialObj->content = $dicionaryRemissives[0]->remissiveContent;
                }
                
                $busMaterial->clean();
                $busMaterial->setData($materialObj);
                $busMaterial->insertMaterial();
            }
            
            // Edição.
            else if ( $remissive->remissiveContent != $materialRemissives[$line]->remissiveContent || (isset($remissive->sourceFieldId) && $remissive->sourceFieldId . '.' . $remissive->sourceSubfieldId != $materialRemissives[$line]->sourceFieldId  . '.' . $materialRemissives[$line]->sourceSubfieldId) )
            {
                // Atualização histórico.
                $historyUpdate = $historyObj;
                $historyUpdate->chancesType  = BusinessGnuteca3BusMaterialHistory::CHANGETYPE_UPDATE;

                $historyUpdate->previousLine = $line;
                $historyUpdate->currentLine = $line;

                $historyUpdate->previousContent = $materialRemissives[$line]->remissiveContent;
                $historyUpdate->currentContent = $remissive->remissiveContent;

                $busMaterialHistory->clean();
                $busMaterialHistory->setData($historyUpdate);
                $busMaterialHistory->insertMaterialHistory();
                
                $busMaterialDictionaryRemissive->clean();
                $busMaterialDictionaryRemissive->setData($materialRemissives[$line]);
                
                if ( !isset($remissive->materialDictionaryRemissiveId) )
                {
                    $busMaterialDictionaryRemissive->remissiveContent = $remissive->remissiveContent;
                    $busMaterialDictionaryRemissive->line = $line;
                    $busMaterialDictionaryRemissive->sourceFieldId = $sourceFieldId;
                    $busMaterialDictionaryRemissive->sourceSubfieldId = $sourceSubfieldId;
                    $busMaterialDictionaryRemissive->sourceLine= $sourceLine;
                }
                else 
                {
                    $busMaterialDictionaryRemissive->remissiveContent = $remissive->remissiveContent;
                    $busMaterialDictionaryRemissive->line = $line;
                    $busMaterialDictionaryRemissive->sourceFieldId = $remissive->sourceFieldId;
                    $busMaterialDictionaryRemissive->sourceSubfieldId = $remissive->sourceSubfieldId;
                    $busMaterialDictionaryRemissive->sourceLine= $remissive->sourceLine;
                }
                
                $busMaterialDictionaryRemissive->updateMaterialDictionaryRemissive();
                
                $materialObj = new stdClass();
                $materialObj->controlNumber = $controlNumber;
                $materialObj->fieldid = $remissiveFieldId;
                $materialObj->subfieldid = $remissiveSubfieldId;
                $materialObj->line = $line;

                $materialObj->content = $remissive->remissiveContent;
                
                // Caso a remessiva e o campo principal sejam da mesma tag (fieldid) e repetitivos, um precisa ficar do lado do outro na tabela.
                // Ambos precisam ter o mesmo valor em line
                $busTag = $MIOLO->getBusiness('gnuteca3', 'BusTag');
                if (
                    $remissiveFieldId == $sourceFieldId
                    && $busTag->isRepetitive($sourceFieldId, $sourceSubfieldId)
                    && $busTag->isRepetitive($remissiveFieldId, $remissiveSubfieldId)
                ) {
                    $materialObj->line = $sourceLine;
                    $materialObj->content = $dicionaryRemissives[0]->remissiveContent;
                }
                                
                $busMaterial->clean();
                $busMaterial->setData($materialObj);
                $busMaterial->updateMaterialContent();
            }
        }
        
        // Itera para remover itens.
        foreach ( $materialRemissives as $line => $remissive )
        {
            if ( !$newArrayRemissives[$line] )
            {
                // Histórico do material.
                $historyDelete = $historyObj;
                $historyDelete->chancesType  = BusinessGnuteca3BusMaterialHistory::CHANGETYPE_DELETE;

                $historyDelete->previousLine = $line;
                $historyDelete->currentLine = $line;

                $historyDelete->previousContent = $remissive->remissiveContent;
                $historyDelete->currentContent = '';

                $busMaterialHistory->clean();
                $busMaterialHistory->setData($historyDelete);
                $busMaterialHistory->insertMaterialHistory();
                
                $busMaterialDictionaryRemissive->clean();
                $busMaterialDictionaryRemissive->deleteMaterialDictionaryRemissive($remissive->materialDictionaryRemissiveId);
                
                // Apaga da gtcmaterial.
                $materialObj->controlNumber = $controlNumber;
                $materialObj->fieldid = $remissive->fieldId;
                $materialObj->subfieldid = $remissive->subfieldId;
                $materialObj->line = $remissive->line;
                
                // Caso a remessiva e o campo principal sejam da mesma tag (fieldid) e repetitivos, um precisa ficar do lado do outro na tabela.
                // Ambos precisam ter o mesmo valor em line
                $busTag = $MIOLO->getBusiness('gnuteca3', 'BusTag');
                if (
                    $remissiveFieldId == $sourceFieldId
                    && $busTag->isRepetitive($sourceFieldId, $sourceSubfieldId)
                    && $busTag->isRepetitive($remissiveFieldId, $remissiveSubfieldId)
                ) {
                    $materialObj->line = $sourceLine;
                }

                $busMaterial->clean();
                $busMaterial->setData($materialObj);
                $busMaterial->deleteMaterial();
            }
        }
    }
    
    public function clean()
    {
        $this->dictionaryRemissiveId = null;
        $this->dictionaryContentId = null;
        $this->remissiveContent = null;
        $this->line = null;
    }
}
?>