<?

//liquidação hortaliças - cebola(cura e granizo) e outras
class Safra15_Model_LIQ02 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();

        $ItemSegurado = $ModelItemSegurado->find($dados['id_item_segurado'])->current();

        $fl_cobertura_qualidade_I = $ModelPropostasCoberturas->hasCoberturaByIdPropostaDsChave($dados['id_proposta'], 'COB_QUALIDADE_I');

        $this->getAdapter()->beginTransaction();

        try {

            // 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 Qualidade I
            $CoberturaQualidade = $ModelCoberturas->getCobertura('COB_QUALIDADE_I', null);
            $idCoberturaQualidadeI = $CoberturaQualidade->id;
            
            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'];
                
          
                if ($laudo['ds_chave_cobertura'] == 'COB_CURA') {
                                        
                    /*
                     * Se a cobertura for Cura, recupera a área exposta informada no laudo ao invés do percentual colhido 
                     */
                    $vl_percent_recolhido = $this->getPercentProducaoRecolhida($dsSafra, $laudo['id_laudo_final_item_segurado']);
                    
                    $vlPercentDanoLaudo = (($laudo['vl_percent_colhido'] - $vl_percent_recolhido) * $vlPercentDanoLaudo / 100);
                    
                    
                } else {
                    // Se houver percentual colhido, ajusta o dano para a área remascente
                    if ($laudo['vl_percent_colhido'] > 0) {
                        $vlPercentDanoLaudo = ((100 - $laudo['vl_percent_colhido']) * $vlPercentDanoLaudo / 100);
                    }
                }

                // Desconta os danos dos laudos anteriores
                foreach ($arDanosAnteriores as $danoAnterior) {
                    $vlPercentDanoLaudo = $vlPercentDanoLaudo * ( 1 - ( $danoAnterior / 100 ) );
                }

                $params['id_laudo_final_item_segurado'] = $laudo['id_laudo_final_item_segurado'];
                $params['vl_prejuizo'] = round(( ( $ItemSegurado->vl_lmga * $vlPercentDanoLaudo / 100)), 2);


                $idLiquidacoesItensSeguradosCoberturasLF = $ModelLiquidacoesItensSeguradosCoberturasLF->save($params);

                $arCoberturas[$laudo['id_cobertura']]['vl_prejuizo_total'] += $params['vl_prejuizo'];

                // Se possui cobertura Qualidade I, verifica se correção deve ser aplicada com base no laudo (estádio da cultura)
                if ($laudo['ds_chave_cobertura'] == 'COB_GRANIZO' && $fl_cobertura_qualidade_I) {

                    // Se correção da Qualidade I deve ser aplicada, realiza o cálculo
                    if ($this->hasEstadioCoberturaQualidade($dsSafra, $laudo['id_laudo_final_item_segurado'])) {

                        $Row = $ModelLiquidacoesItensSeguradosCoberturas->find($dados['id_liquidacao'], $dados['id_item_segurado'], $idCoberturaQualidadeI)->current();

                        if (!$Row) {
                            $Row = $ModelLiquidacoesItensSeguradosCoberturas->save(array(
                                'id_liquidacao' => $dados['id_liquidacao'],
                                'id_item_segurado' => $dados['id_item_segurado'],
                                'id_cobertura' => $idCoberturaQualidadeI,
                                '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 da correção para o percentual de dano do laudo
                        $vlPercenDanoDependente = $this->getPercentCorrecaoQualidade($laudo['percentual_dano']);
                        $params_dependente['vl_percent_perdas'] = $vlPercenDanoDependente;

                        // Se houver percentual colhido, ajusta o dano para a área remascente
                        if ($laudo['vl_percent_colhido'] > 0) {
                            $vlPercenDanoDependente = ((100 - $laudo['vl_percent_colhido']) * $vlPercenDanoDependente / 100);
                        }

                        // Insere o percentual de dano da qualidade no array de danos
                        foreach ($arDanosAnteriores as $danoAnterior) {
                            $vlPercenDanoDependente = $vlPercenDanoDependente * ( 1 - ( $danoAnterior / 100 ) );
                        }

                        $arDanosAnteriores[] = $params_dependente['vl_percent_perdas'];

                        $params_dependente['vl_prejuizo'] = round(( ( ($ItemSegurado->vl_lmga - $params['vl_prejuizo']) * $vlPercenDanoDependente / 100)), 2);
                        $arCoberturas[$idCoberturaQualidadeI]['vl_prejuizo_total'] += $params_dependente['vl_prejuizo'];

                        $ModelLiquidacoesItensSeguradosCoberturasLFDependentes->save($params_dependente);
                    }
                }

                // Insere o percentual de dano do laudo atual no array de danos
                $arDanosAnteriores[] = $laudo['percentual_dano'];
            }

            // Busca percentual da franquia da cobertura principal (Granizo)
            $vl_percent_franquia_principal = $ModelPropostasCoberturas->getFranquiaByPropostaCobertura($dados['id_proposta'], 1);
            $vl_franquia_restante = round(($ItemSegurado->vl_lmga * $vl_percent_franquia_principal / 100), 2);

            $fl_aplicar_franquia = true;

            foreach ($arCoberturas as $id_cobertura => $cobertura) {
                $vl_percent_franquia = $ModelPropostasCoberturas->getFranquiaByPropostaCobertura($dados['id_proposta'], $id_cobertura);
                if (!$vl_percent_franquia) {
                    $vl_percent_franquia = 0;
                }

                if ($fl_aplicar_franquia && $vl_franquia_restante > 0) {
                    $vl_franquia = round(($ItemSegurado->vl_lmga * $vl_percent_franquia / 100), 2);

                    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'];
                }

                $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 getPercentProducaoRecolhida($dsSafra, $idLaudoFinalItemSegurado) {        
        $Select = $this->select()->setIntegrityCheck(false);
        $Select->from(array('lfis' => $dsSafra . '.lf008_itens_segurados'), "lfis.vl_percent_producao_recolhida");
        $Select->where('lfis.id_laudo_final_item_segurado = ?', $idLaudoFinalItemSegurado);

        
        return $this->_db->fetchOne($Select);
    }

    public function hasEstadioCoberturaQualidade($dsSafra, $idLaudoFinalItemSegurado) {
        /*
         * Calcula o percentual de amostras do laudo de granizo do item segurado em que o estádio é 
         * maior ou igual a 5, e retorna true se o percentual for de 70% ou maior, e false em caso contrário
         */

        // Contador de amostras
        $nr_amostras = 0;

        // Contador de amostras em que o estádio é 5 ou maior
        $nr_amostras_estadio_5 = 0;

        $Select = $this->select()->setIntegrityCheck(false);
        $Select->from(array('lfacis' => $dsSafra . '.lf007_itens_segurados_amostras'), 'lfacis.ds_estadio');
        $Select->where('lfacis.id_laudo_final_item_segurado = ?', $idLaudoFinalItemSegurado);

        $Rows = $this->_db->fetchAll($Select);
        foreach ($Rows as $row) {
            $nr_amostras++;
            if ($row['ds_estadio'] >= 5) {
                $nr_amostras_estadio_5++;
            }
        }

        if ($nr_amostras > 0 && $nr_amostras_estadio_5 > 0) {
            if (($nr_amostras_estadio_5 * 100 / $nr_amostras) >= 70) {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    public function getPercentCorrecaoQualidade($vlPercentPerdas) {
        /*
         * Busca o percentual de correção adequado na tabela sinistro.auxiliar_liquidacao_cebola_qualidade_i 
         * para o percentual de perda passado
         */
        $Select = $this->select()->setIntegrityCheck(false);
        $Select->from(array('aux' => 'sinistro.auxiliar_liquidacao_cebola_qualidade_i'), 'aux.vl_percent_correcao');
        $Select->where('? between aux.vl_percent_perdas_min and aux.vl_percent_perdas_max', $vlPercentPerdas);

        return $this->_db->fetchOne($Select);
    }

}
