<?

// Liquidação do produto Uva de Vinho (Granizo + Geada + Ajuste de Dano + Qualidade)
class Safra15_Model_LIQ01 extends Agro_Db_Table_Abstract {

    protected $_schema = 'sinistro';
    protected $_name = 'tipo_liquidacao';
    protected $_primary = 'id';
    public $_order = 'ds_nome_tipo_liquidacao';

    public function liquidar($dados) {

        $result = array("status" => true, "message" => "", "execute" => "");

        $ModelSafras = new Produto_Model_Safras();
        $dsSafra = $ModelSafras->getSafraModel($dados['id_proposta']);

        $ModelLiquidacoes = new Sinistro_Model_Liquidacoes();
        $ModelItemSegurado = new Seguro_Model_ItensSegurados();
        $ModelCoberturas = new Produto_Model_Coberturas();
        $ModelPropostasCoberturas = new Seguro_Model_PropostasCoberturas();
        $ModelLiquidacoesItensSeguradosCoberturas = new Sinistro_Model_LiquidacoesItensSeguradosCoberturas();
        $ModelLiquidacoesItensSeguradosCoberturasLF = new Sinistro_Model_LiquidacoesItensSeguradosCoberturasLF();
        $ModelLiquidacoesItensSeguradosCoberturasLFDependentes = new Sinistro_Model_LiquidacoesItensSeguradosCoberturasLFDependentes();

        try {

            $ItemSegurado = $ModelItemSegurado->find($dados['id_item_segurado'])->current();
            
            // Verifica se a proposta possui cobertura de Ajuste de dano contratada
            $fl_cobertura_ajuste_dano = $ModelPropostasCoberturas->hasCoberturaByIdPropostaDsChave($dados['id_proposta'], 'COB_AJUSTE_DANO');

            // Verifica se a proposta poussui cobertura de Qualidade contratada
            $fl_cobertura_qualidade = $ModelPropostasCoberturas->hasCoberturaByIdPropostaDsChave($dados['id_proposta'], 'COB_QUALIDADE');

            // Verifica se munícipio da propriedade pertence a região de Sarandi
            $fl_regiao_sarandi = $this->isRegiaoSarandi($dados['id_proposta']);

            $this->getAdapter()->beginTransaction();

            // Array de danos utilizado para abater danos anteriores durante o cálculo
            $arDanosAnteriores = array();

            // Array que acumulará o prejuizo calculado por cobertura, para posterior aplicação da franquia
            $arCoberturas = array();

            // Recupera identificador da cobertura Ajuste de Dano
            $CoberturaAjusteDano = $ModelCoberturas->getCobertura('COB_AJUSTE_DANO', null);
            $idCoberturaAjusteDano = $CoberturaAjusteDano->id;

            // Recupera identificador da cobertura de Qualidade
            $CoberturaQualidade = $ModelCoberturas->getCobertura('COB_QUALIDADE', null);
            $idCoberturaQualidade = $CoberturaQualidade->id;

            $danoAplicado = array();

            foreach ($dados['laudos'] as $laudo) {

                $Row = $ModelLiquidacoesItensSeguradosCoberturas->find($dados['id_liquidacao'], $dados['id_item_segurado'], $laudo['id_cobertura'])->current();

                if (!$Row) {
                    $Row = $ModelLiquidacoesItensSeguradosCoberturas->save(
                        array(
                            'id_liquidacao' => $dados['id_liquidacao'],
                            'id_item_segurado' => $dados['id_item_segurado'],
                            'id_cobertura' => $laudo['id_cobertura']
                        ));
                }

                $params = array();
                $params['id_liquidacoes_itens_segurados_coberturas'] = $Row['id'];

                $vlPercentDanoLaudo = $laudo['percentual_dano'];
                
                $vlPercentDanoCalculo = $vlPercentDanoLaudo;
                
                $params['vl_percent_dano'] = $vlPercentDanoLaudo;

                // Se houver percentual colhido, ajusta o dano para a área remanescente
                if ($laudo['vl_percent_colhido'] > 0) {
                    $vlPercentDanoCalculo = $vlPercentDanoCalculo * ( 1 - ($laudo['vl_percent_colhido'] / 100));
                }

                // Desconta os danos dos laudos anteriores
                foreach ($arDanosAnteriores as $danoAnterior) {
                    $vlPercentDanoCalculo = $vlPercentDanoCalculo * (1 - ($danoAnterior / 100));
                }

                $params['id_laudo_final_item_segurado'] = $laudo['id_laudo_final_item_segurado'];
                
                $params['vl_prejuizo'] = ( ( $ItemSegurado->vl_lmga * $vlPercentDanoCalculo / 100));

                $idLiquidacoesItensSeguradosCoberturasLF = $ModelLiquidacoesItensSeguradosCoberturasLF->save($params);

                $arCoberturas[$laudo['id_cobertura']]['vl_prejuizo_total'] += $params['vl_prejuizo'];

                $vlPercenDanoCalculoDependentes = $vlPercentDanoLaudo;

                $vl_percent_ajuste_dano = 0;
                $vl_percent_qualidade = 0;

                // Se cobertura do laudo atual for Granizo e possuir cobertura de Ajuste de Dano, verifica percentual do ajuste e aplica
                if ($laudo['ds_chave_cobertura'] == 'COB_GRANIZO' && $fl_cobertura_ajuste_dano) {

                    $Row = $ModelLiquidacoesItensSeguradosCoberturas->find($dados['id_liquidacao'], $dados['id_item_segurado'], $idCoberturaAjusteDano)->current();

                    if (!$Row) {
                        $Row = $ModelLiquidacoesItensSeguradosCoberturas->save(array(
                            'id_liquidacao' => $dados['id_liquidacao'],
                            'id_item_segurado' => $dados['id_item_segurado'],
                            'id_cobertura' => $idCoberturaAjusteDano,
                            'fl_dependente' => true
                                ));
                    }

                    $params_dependente = array();
                    $params_dependente['id_liquidacoes_itens_segurados_coberturas'] = $Row['id'];
                    $params_dependente['id_liquidacoes_itens_segurados_coberturas_lf'] = $idLiquidacoesItensSeguradosCoberturasLF;
                    $params_dependente['nr_prioridade'] = 1;

                    // Busca o valor do ajuste para o percentual de dano do laudo
                    $vlPercenDanoAjusteDanoCalculo = $this->getPercentAjusteDano($vlPercenDanoCalculoDependentes);
                    $params_dependente['vl_percent_perdas'] = $vlPercenDanoAjusteDanoCalculo;
                    $vl_percent_ajuste_dano = $vlPercenDanoAjusteDanoCalculo;
                    $vlPercenDanoCalculoDependentes += $vlPercenDanoAjusteDanoCalculo;

                    // Se houver percentual colhido, ajusta o dano para a área remascente
                    if ($laudo['vl_percent_colhido'] > 0) {
                        $vlPercenDanoAjusteDanoCalculo = ((100 - $laudo['vl_percent_colhido']) * $vlPercenDanoAjusteDanoCalculo / 100);
                    }

                    // Insere o percentual de dano da qualidade no array de danos
                    foreach ($arDanosAnteriores as $danoAnterior) {
                        $vlPercenDanoAjusteDanoCalculo = $vlPercenDanoAjusteDanoCalculo * ( 1 - ( $danoAnterior / 100 ) );
                    }

                    $params_dependente['vl_prejuizo'] = round(( ( $ItemSegurado->vl_lmga * $vlPercenDanoAjusteDanoCalculo / 100)), 2);
                    
                    $arCoberturas[$idCoberturaAjusteDano]['vl_prejuizo_total'] += $params_dependente['vl_prejuizo'];

                    $ModelLiquidacoesItensSeguradosCoberturasLFDependentes->save($params_dependente);
                }

                // Se cobertura do laudo atual for Granizo e possuir cobertura de Qualidade, verifica percentual do ajuste e aplica
                if ($laudo['ds_chave_cobertura'] == 'COB_GRANIZO' && $fl_cobertura_qualidade) {

                    $Row = $ModelLiquidacoesItensSeguradosCoberturas->find($dados['id_liquidacao'], $dados['id_item_segurado'], $idCoberturaQualidade)->current();

                    if (!$Row) {
                        $Row = $ModelLiquidacoesItensSeguradosCoberturas->save(array(
                            'id_liquidacao' => $dados['id_liquidacao'],
                            'id_item_segurado' => $dados['id_item_segurado'],
                            'id_cobertura' => $idCoberturaQualidade,
                            'fl_dependente' => true
                                ));
                    }

                    $params_dependente = array();
                    $params_dependente['id_liquidacoes_itens_segurados_coberturas'] = $Row['id'];
                    $params_dependente['id_liquidacoes_itens_segurados_coberturas_lf'] = $idLiquidacoesItensSeguradosCoberturasLF;
                    $params_dependente['nr_prioridade'] = 1;

                    // Busca no de início da safra da proposta
                    $dt_final_carencia_qualidade = $this->getAnoSafraProposta($dados['id_proposta']);
                    // Configura data de final da carência para 01/12 se a propriedade for da região de Sarandi, e para 15/12 caso contrário
                    if ($fl_regiao_sarandi) {
                        $dt_final_carencia_qualidade .= '1201';
                    } else {
                        $dt_final_carencia_qualidade .= '1215';
                    }

                    $dt_sinistro_laudo = $this->getMaiorDtSinistroByLaudo($laudo['id_laudo_final_item_segurado']);

                    if ($dt_sinistro_laudo > $dt_final_carencia_qualidade) {
                        // Busca o valor da correção para o percentual de dano do laudo
                        $vlPercenDanoQualidadeCalculo = $this->getPercentCorrecaoQualidade($vlPercenDanoCalculoDependentes);
                        $params_dependente['vl_percent_perdas'] = $vlPercenDanoQualidadeCalculo;
                        $vl_percent_qualidade = $vlPercenDanoQualidadeCalculo;

                        // Se houver percentual colhido, ajusta o dano para a área remascente
                        if ($laudo['vl_percent_colhido'] > 0) {
                            $vlPercenDanoQualidadeCalculo = ((100 - $laudo['vl_percent_colhido']) * $vlPercenDanoQualidadeCalculo / 100);
                        }

                        // Insere o percentual de dano da qualidade no array de danos
                        foreach ($arDanosAnteriores as $danoAnterior) {
                            $vlPercenDanoQualidadeCalculo = $vlPercenDanoQualidadeCalculo * ( 1 - ( $danoAnterior / 100 ) );
                        }

                        $params_dependente['vl_prejuizo'] = ( ( $ItemSegurado->vl_lmga * $vlPercenDanoQualidadeCalculo / 100));
                        
                        $arCoberturas[$idCoberturaQualidade]['vl_prejuizo_total'] += $params_dependente['vl_prejuizo'];

                        $ModelLiquidacoesItensSeguradosCoberturasLFDependentes->save($params_dependente);
                    }
                }

                // Se há percentual de Ajuste de Dano, insere o percentual de dano do laudo atual no array de danos
                if ($vl_percent_ajuste_dano > 0) {
                    $vlPercentDanoLaudo += $vl_percent_ajuste_dano;
                }

                // Se há percentual de Qualidade, insere o percentual de dano do laudo atual no array de danos
                if ($vl_percent_qualidade > 0) {
                    $vlPercentDanoLaudo += $vl_percent_qualidade;
                }

                // Insere o percentual de dano do laudo atual no array de danos
                $arDanosAnteriores[] = $vlPercentDanoLaudo;
            }

            // Busca percentual da franquia da cobertura principal (Granizo)
            $vl_percent_franquia_principal = $ModelPropostasCoberturas->getFranquiaByPropostaCobertura($dados['id_proposta'], 1);
            $vl_franquia_restante = Agro_Util::round(($ItemSegurado->vl_lmga * $vl_percent_franquia_principal / 100), 2);

            $fl_aplicar_franquia = true;

            $count = 1;

            foreach ($arCoberturas as $id_cobertura => $cobertura) {

                if ($id_cobertura == 1 || $id_cobertura == 3) {
                    $vl_percent_franquia = $ModelPropostasCoberturas->getFranquiaByPropostaCobertura($dados['id_proposta'], $id_cobertura);
                } else {
                    $vl_percent_franquia = 0;
                }

                if ($fl_aplicar_franquia && $vl_franquia_restante > 0) {

                    if ($count == 1) {
                        $vl_franquia = round(($ItemSegurado->vl_lmga * $vl_percent_franquia / 100), 2);
                    } else {
                        $vl_franquia = 0;
                        $vl_percent_franquia = 0;
                    }

                    if ($vl_franquia_restante > $cobertura['vl_prejuizo_total']) {
                        $vl_franquia_restante -= $cobertura['vl_prejuizo_total'];
                    } else {
                    	
                        $vl_indenizacao = $cobertura['vl_prejuizo_total'] - $vl_franquia_restante;
                        $fl_aplicar_franquia = false;
                    }
                } else {
                    $vl_percent_franquia = 0;
                    $vl_franquia = 0;
                    $vl_indenizacao = $cobertura['vl_prejuizo_total'];
                }
                
                $count++;

                //Se a cobertura for GEADA a indenização máxima será 50% da LMGA, caso contrário até 100%.
                $vl_max_indenizacao = Agro_Util::round(($id_cobertura == 3 ? ($ItemSegurado->vl_lmga * 0.5) : $ItemSegurado->vl_lmga));
                
				if($vl_indenizacao > $vl_max_indenizacao){
                	$vl_indenizacao = $vl_max_indenizacao;
                }

                $ModelLiquidacoesItensSeguradosCoberturas->save(array(
                    'id_liquidacao' => $dados['id_liquidacao'],
                    'id_item_segurado' => $dados['id_item_segurado'],
                    'id_cobertura' => $id_cobertura,
                    'vl_percent_franquia' => $vl_percent_franquia,
                    'vl_franquia' => $vl_franquia,
                    'vl_indenizacao' => $vl_indenizacao,
                    'vl_prejuizo_total' => $cobertura['vl_prejuizo_total']
                ));

            }

            $result['message'] = 'Liquidação realizada com sucesso.';

            $this->getAdapter()->commit();
        } catch (Exception $e) {
            $this->getAdapter()->rollBack();
            $result['status'] = false;
            $result['message'] = "Não foi possível realizar a liquidação. \n {$e->getMessage()} \n {$e->getTraceAsString()}";
        }
        return $result;
    }

    public function getPercentAjusteDano($vlPercentPerdas) {
        /*
         * Busca o percentual de Ajuste de Dano adequado na tabela sinistro.auxiliar_liquidacao_uva_vinho_ajuste_dano
         * para o percentual de perda passado
         */
        $Select = $this->select()->setIntegrityCheck(false);
        $Select->from(array('aux' => 'sinistro.auxiliar_liquidacao_uva_vinho_ajuste_dano'), 'aux.vl_percent_ajuste_dano');
        $Select->where('? between aux.vl_percent_perdas_min and aux.vl_percent_perdas_max', $vlPercentPerdas);

        return $this->_db->fetchOne($Select);
    }

    public function getPercentCorrecaoQualidade($vlPercentPerdas) {
        /*
         * Busca o percentual de correção de qualidade adequado na tabela sinistro.auxiliar_liquidacao_uva_vinho_qualidade
         * para o percentual de perda passado
         */
        $Select = $this->select()->setIntegrityCheck(false);
        $Select->from(array('aux' => 'sinistro.auxiliar_liquidacao_uva_vinho_qualidade'), 'aux.vl_percent_correcao');
        $Select->where('? between aux.vl_percent_perdas_min and aux.vl_percent_perdas_max', $vlPercentPerdas);

        return $this->_db->fetchOne($Select);
    }

    public function isRegiaoSarandi($idProposta) {
        // Verifica se o município pertence a região de Sarandi
        $Select = $this->select()->setIntegrityCheck(false);
        $Select->from(array('pp' => 'seguro.propostas_propriedades'), 'pp.id_municipio');
        $Select->join(array('m' => 'sistema.municipios'), "m.id = pp.id_municipio and ds_nome_municipio in (
                'ALPESTRE',
                'AMETISTA DO SUL',
                'NONOAI',
                'BARÃO DE COTEGIPE',
                'NOVO BARREIRO',
                'BARRA FUNDA',
                'PALMEIRA DAS MISSÕES',
                'BENJAMIN CONSTANT DO SUL',
                'PLANALTO',
                'CAMPINAS DO SUL',
                'QUATRO IRMÃOS',
                'CONSTANTINA',
                'RIO DOS ÍNDIOS',
                'ENTRE RIOS DO SUL',
                'RODEIO BONITO',
                'ERECHIM',
                'RONDA ALTA',
                'ERVAL GRANDE',
                'RONDINHA',
                'FAXINALZINHO',
                'SAGRADA FAMÍLIA',
                'GRAMADO DOS LOUREIROS',
                'SÃO JOSÉ DAS MISSÕES',
                'IPIRANGA DO SUL',
                'SÃO VALENTIM',
                'JACUTINGA',
                'SARANDI',
                'LAJEADO DO BUGRE',
                'TRÊS PALMEIRAS',
                'LIBERATO SALZANO',
                'TRINDADE DO SUL'
        )", null);
        $Select->where('pp.id_proposta = ?', $idProposta);

        $Rs = $this->fetchRow($Select);
        if ($Rs) {
            return true;
        } else {
            return false;
        }
    }

    public function getAnoSafraProposta($idProposta) {
        // Retorna o ano de início da safra em que a proposta foi contratada
        $Select = $this->select()->setIntegrityCheck(false);
        $Select->from(array('pr' => 'seguro.propostas'), "to_char(pr.dt_vigencia_inicio, 'YYYY') as ano_safra");
        $Select->where('pr.id = ?', $idProposta);

        return $this->_db->fetchOne($Select);
    }

    public function getMaiorDtSinistroByLaudo($idLaudoFinalItemSegurado) {
        // Retorna a maior data de sinistro dos avisos relacionados ao laudo final

        $Select = $this->select()->setIntegrityCheck(false);
        $Select->from(array('lfis' => 'sinistro.laudos_finais_itens_segurados'), null);
        $Select->join(array('vlf' => 'sistema.vistorias_laudos_finais'), 'vlf.id_laudo_final = lfis.id_laudo_final', null);
        $Select->join(array('va' => 'sinistro.vistorias_avisos'), 'va.id_vistoria = vlf.id_vistoria', null);
        $Select->join(array('a' => 'sinistro.avisos'), 'a.id = va.id_aviso', "to_char(a.dt_sinistro, 'YYYYmmdd') as dt_sinistro");
        $Select->where('lfis.id = ?', $idLaudoFinalItemSegurado);
        $Select->order('a.dt_sinistro desc');
        $Select->limit(1);

        return $this->_db->fetchOne($Select);
    }

}
