<?php

use Dompdf\Exception;

class Seguro_CotacaoController extends Agro_Controller_Action
{
    private $params;

    public $_columnList = array(
        'id' => array('label' => 'Id', 'align' => 'center'),
        'dt_criacao' => array('label' => 'Data criação', 'align' => 'center'),
        'ds_nome_proponente' => 'Proponente',
        'nome_municipio' => 'UF/Município',
        'ds_nome_produto' => 'Produto',
        'ds_nome_safra' => array('label' => 'Safra', 'align' => 'center')
    );

    public function init()
    {
        $this->view->title = 'Seguro » Cotação';

        $Auth = Zend_Auth::getInstance()->getIdentity();
        $this->view->tp_usuario = $Auth->tp_usuario;
    }

    public function getForm()
    {
        return new Seguro_Form_Cotacao();
    }

    public function viewAction()
    {
        $lmga = 0;
        $this->getHelper('layout')->setLayout('popup');
        $this->view->title .= ' » Visualização';
        $coberturasMultirrisco = array_keys(
            (new Produto_Model_Coberturas())->fetchPairs(
                'id',
                'id',
                false,
                false,
                1,
                "ds_chave_cobertura like 'COB_MULTIR%'",
                false,
                'ASC'
            )
        );

        $id = !Agro_Util::filterVariable($this->getRequest()->getParam('id'))
            ? 0
            : (int)$this->getRequest()->getParam('id');

        $model = $this->getModel();
        $where[] = array('field' => 'sc.id', 'operator' => '=', 'value' => $id);
        $this->view->cotacao = $model->fetchRow($model->getData($where))->toArray();

        $cotacoesCoberturas = new Seguro_Model_CotacoesCoberturas();
        $this->view->cobertura_principal = $cotacoesCoberturas->getCoberturas($id, true);
        $this->view->coberturas = $cotacoesCoberturas->getCoberturas($id, false);
        $this->view->unidades = (new Seguro_Model_CotacoesUnidades())->fetchAll("id_cotacao = {$id}")->toArray();

        foreach ($this->view->unidades as $unidades) {
            if (in_array($this->view->cobertura_principal[0]['id_cobertura'], $coberturasMultirrisco)) {
                $lmga += $unidades['vl_area'] * round($unidades['vl_produtividade'] * $this->view->cobertura_principal[0]['vl_franquia'] / 100 / 1000, 3) * $unidades['vl_tonelada'];
            } else {
                $lmga += $unidades['vl_area'] * ($unidades['vl_produtividade'] / 1000) * $unidades['vl_tonelada'];
            }
        }

        $this->view->lmga = $lmga;
        $this->view->produto = (new Produto_Model_Produtos())->get((int)$this->view->cotacao['id_produto'])->toArray();
        $this->view->seguradora = (new Sistema_Model_Empresas())->fetchRow(
            'id = ' . $this->view->produto['id_seguradora']
        )->toArray();

        $this->view->safra = (new Produto_Model_Safras())->fetchRow(
            'id = ' . $this->view->produto['id_safra']
        )->toArray();
    }

    public function formAction()
    {
        $User = Zend_Auth::getInstance()->getIdentity();
        $this->view->id_usuario = $User->id;

        if ($User->tp_usuario == 'C') {

            $Corretores = new Sistema_Model_Corretores();
            $corretor = $Corretores->findByUser($User->id);
            $this->view->id_corretor = $corretor->id;

        } elseif ($User->tp_usuario == 'P') {

            $this->view->id_preposto = $User->id;
        }

        if ($this->getRequest()->isPost()) {
            //todo
            // verificar se proponente existe, se não, cadastrar em seguro.proponentes
            // registrar em seguro.cotacoes
        }

        if ($this->getRequest()->getParam('id')) {
            $Model = $this->getModel();
            $where[] = array('field' => 'sc.id', 'operator' => '=', 'value' => $this->getRequest()->getParam('id'));
            $Rs = $Model->fetchAll($Model->getData($where))->toArray();
            $cotacao = $Rs[0];

            $Unidade = new Seguro_Model_CotacoesUnidades();
            $unidades = $Unidade->fetchAll("id_cotacao = " . $this->getRequest()->getParam('id'))->toArray();

            $Cobertura = new Seguro_Model_CotacoesCoberturas();
            $coberturas = $Cobertura->fetchAll("id_cotacao = " . $this->getRequest()->getParam('id'))->toArray();

            $cotacao['unidades'] = $unidades;
            $cotacao['coberturas'] = $coberturas;
            $this->view->cotacao = $cotacao;

        }

        parent::formAction();
    }

    public function getModel()
    {
        return new Seguro_Model_Cotacoes();
    }

    public function coberturasAction()
    {
        $this->isAjax();
        $this->params = $this->getRequest()->getParams();
        $modelCotacao = new Seguro_Model_Row_Cotacao();
        $fl_permite_alterar_comissao = $modelCotacao->permite_alterar_comissao($this->params['id_usuario']);

        if (empty($this->params['id_produto']) || $this->params['id_produto'] == "null") {
            $result = array('status' => false);
            $this->getResponse()->setBody(Zend_Json::encode($result));
            return false;
        }

        $Model = $this->getModel();

        $this->view->coberturas = $Model->coberturas($this->params['id_produto']);

        if ($this->view->coberturas) {
            $this->view->comercializacoes = $Model->comercializacoes($this->params);
        } else {
            return false;
        }

        if ($this->view->comercializacoes) {
            $this->view->agrupamento = $this->getGrupo();
        } else {
            return false;
        }

        if ($this->view->agrupamento) {
            $vl_produtividade = $this->view->agrupamento['vl_produtividade_estimada'] > 0 ? $this->view->agrupamento['vl_produtividade_estimada'] : null;
            $this->view->atributos = $this->getValorAtributos();
        }

        if ($this->view->atributos) {
            $this->view->taxas = $this->getTaxas();
        }

        if ($this->view->taxas) {
            $this->view->taxas_relacionadas = $this->getTaxasRelacionadas();
        }

        $this->view->params = $this->params['cpf_cnpj'];

        if ($this->view->taxas) {
            $isProducaoGarantida = $this->isProducaoGarantida();
            $produtividade = $isProducaoGarantida ? $vl_produtividade : 0;

            foreach ($this->view->taxas as &$taxa) {
                $taxa['vl_pg'] = $this->calcularProdutividadeGarantida($produtividade, $taxa['vl_franquia']);
            }

            $result = array(
                'html' => $this->view->render('cotacao/coberturas.phtml'),
                'status' => true,
                'vlProdutividade' => $produtividade,
                'isProducaoGarantida' => $isProducaoGarantida,
                'rangeComissao' => ($this->view->atributos['PROD_VALOR_MIN_MAX_RANGE_COMISSAO']) ? $this->view->atributos['PROD_VALOR_MIN_MAX_RANGE_COMISSAO'] : '',
                'fl_permite_alterar_comissao' => $fl_permite_alterar_comissao
            );

            $this->getResponse()->setBody(Zend_Json::encode($result));
        }

        return false;
    }

    private function getTaxasRelacionadas()
    {
        return $this->getModel()->getTaxasRelacionadas($this->view->agrupamento['id']);
    }

    private function getTaxas(array $campos = [])
    {
        return (new Comercializacao_Model_Taxas())->getTaxasProposta(
            $this->view->agrupamento['id'],
            $this->view->atributos['PROD_PRODUCAO_GARANTIDA'],
            false,
            $campos
        );
    }

    private function getGrupo()
    {
        $result = false;
        $Model = $this->getModel();

        if ($this->params) {
            $result = $Model->grupoProponenteUsuario($this->params);
            if ($result !== false) return $result;

            $result = $Model->grupoProponente($this->params);
            if ($result !== false) return $result;

            $result = $Model->grupoPreposto($this->params);
            if ($result !== false) return $result;

            $result = $Model->grupoCorretor($this->params);
            if ($result !== false) return $result;

            $result = $Model->grupoMunicipio($this->params);
            if ($result !== false) return $result;

            $result = $Model->grupoEstado($this->params);
            if ($result !== false) return $result;

            throw new Zend_Exception(
                'Taxas não configurada. Entre em contato com a AgroBrasil para melhor esclarecimento.', 404
            );
        }
    }

    private function getValorAtributos()
    {
        $atributos = $this->getAtributos();

        if (is_array($atributos)) {
            $att = array();
            foreach ($atributos as $atributo) {
                $att[$atributo['ds_chave_rn']] = $atributo['ds_valor'];
            }
        }

        return $att;
    }

    private function getAtributos()
    {
        $Proponentes = new Seguro_Model_Proponentes();
        $AtributosGrupos = new Produto_Model_Atributogrupos();

        $proponente = $Proponentes->getProponente($this->params['cpf_cnpj']);

        $Atributos = $AtributosGrupos->getAtributosProponente($this->params['id_produto'], $proponente['id'], 'PROPRIEDADE');
        if (count($Atributos) > 0) {
            return $Atributos;
        }

        $Atributos = $AtributosGrupos->getAtributosUsuario($this->params['id_produto'], $this->params['id_usuario'], 'PROPRIEDADE');
        if (count($Atributos) > 0) {
            return $Atributos;
        }

        $Atributos = $AtributosGrupos->getAtributosMunicipio($this->params['id_produto'], $this->params['id_municipio'], 'PROPRIEDADE');
        if (count($Atributos) > 0) {
            return $Atributos;
        }

        $Atributos = $AtributosGrupos->getAtributosPadrao($this->params['id_produto'], 'PROPRIEDADE');

        if (count($Atributos) > 0) {
            return $Atributos;
        }

        return false;
    }

    public function calcularAction()
    {
        $this->isAjax();
        $return = array();
        //Recupera parametros recebidos
        $this->params = $this->getRequest()->getParams();
        //Instancia models
        $ProdutoCoberturas = new Produto_Model_ProdutosCoberturas();
        $Tx = new Comercializacao_Model_Taxas();
        $model_estados = new Sistema_Model_Estados();
        $modelTipos = new Produto_Model_Tipos();
        $Proponentes = new Seguro_Model_Proponentes();
        //Acessa valores brutos da taxa
        $franquia = explode('#', $this->params['taxa']);
        //Acessa parametros recebidos
        $vlAcrescimoGeada = false;
        $taxa = $this->params['vl_taxa'];
        $unidades = $this->params['unidades'];
        $valorFranquiaSelecionada = $this->params['valorFranquiaSelecionada'];
        $id_estado = $this->params['id_estado'];
        //Recupera valores atributos, agrupamento e taxas
        $this->view->atributos = $this->getValorAtributos();
        $this->view->agrupamento = $this->getGrupo();
        $taxas = $this->getTaxas();
        //Formata valores taxa
        $this->params['taxa'] = $franquia[0];
        $this->params['id_taxa'] = $franquia[1];
        $vl_percentual_subvencao_federal = $franquia[2];
        //Recupera proponente da cotação
        $proponente = $Proponentes->getProponente($this->params['cpf_cnpj']);
        //Cria variavel com infos das coberturas adicionais
        $coberturas_adicionais = explode('--', $this->params['coberturas']);

        //Acessa e formata valores das informações de taxa e agrupamento de cada cobertura adicional
        if (is_array($coberturas_adicionais)) {
            $cobs = array();
            foreach ($coberturas_adicionais as $adicional) {
                $fadd = explode('#', $adicional);
                if ($fadd[0]) {
                    $cobs[$fadd[0]] = array($fadd[1], $fadd[2]);
                }
            }
        }

        $calculoCoberturasAdicionais = $this->calculacoberturasadicionais($vlAcrescimoGeada, $valorFranquiaSelecionada, number_format($this->params['lmga_parcial'], 2, ',', '.'));

        foreach ($calculoCoberturasAdicionais as $cobertura) {
            $return[] = $cobertura;
        }

        if (is_array($cobs) && count($cobs)) {
            $dados['comissao']['vl_comissao_original'] = $this->getRequest()->getParam('vl_comissao_original');
            $dados['comissao']['vl_nova_comissao'] = $this->getRequest()->getParam('vl_nova_comissao');

            $comissaoMaior = $dados['comissao']['vl_comissao_original'] < $dados['comissao']['vl_nova_comissao'];
            $comissaoMenor = $dados['comissao']['vl_comissao_original'] > $dados['comissao']['vl_nova_comissao'];

            if ($comissaoMaior || $comissaoMenor) {
                /**
                 * Aumento proporcional da AgroBrasil na comissão agravada pelo corretor
                 */
                if ($comissaoMaior) {
                    $rowComissaoAdicionalAgroBrasil = (new Produto_Model_ComissaoAdicionalAgroBrasil())->fetchAll()->current()->toArray();
                    $percentualComissaoAdicional = $rowComissaoAdicionalAgroBrasil['vl_percentual'];

                    $calculoTaxaParte1 = 1 + ($percentualComissaoAdicional / 100);
                    $calculoTaxaParte1 = $calculoTaxaParte1 * ($dados['comissao']['vl_comissao_original'] / 100);
                    $calculoTaxaParte1 = 1 - $calculoTaxaParte1;

                    $calculoTaxaParte2 = 1 + ($percentualComissaoAdicional / 100);
                    $calculoTaxaParte2 = $calculoTaxaParte2 * ($dados['comissao']['vl_nova_comissao'] / 100);
                    $calculoTaxaParte2 = 1 - $calculoTaxaParte2;

                    $taxa = ((($taxa / 100) * $calculoTaxaParte1) / $calculoTaxaParte2) * 100;

                } else {
                    $taxa = ($taxa * (1 - ($dados['comissao']['vl_comissao_original'] / 100))) / (1 - ($dados['comissao']['vl_nova_comissao'] / 100));
                }

                $taxa = Agro_Util::round($taxa, 2);
            }

            foreach ($return as $r) {
                $vl_taxa_geral += $r['vl_taxa'];
                $premio_tarifario_geral += $this->params['lmga_parcial'] * ($r['vl_taxa'] / 100);
            }

        }

        $vl_premio = Agro_Util::round($this->params['lmga_parcial'] * ($this->params['vl_taxa'] / 100));

        $this->params['vl_premio'] = number_format($vl_premio, 2, ',', '.');

        $this->params['return'] = $return;

        /*=========== CÁLCULO GERAL ====================*/
        $taxa_geral = $vl_taxa_geral + $franquia[0];
        //vl_premio é valor com infos da cob principal enquanto premio_tarifario_geral é calculo das coberturas adicionais
        $premio_geral = $premio_tarifario_geral + $vl_premio;

        /*=========== SUBVENÇÕES ============*/
        $valoresSubvencaoFederal = $this->calcularSubvencaoFederal($Proponentes, $proponente, $premio_geral);

        if (in_array($this->params['id_estado'], [16, 25])) {
            $valoresSubvencaoEstadual = $this->calcularSubvencaoEstadual(
                $premio_geral,
                $this->view->atributos['PROD_CUSTO_APOLICE'],
                $this->params['id_estado'],
                $modelTipos->getTipoViaIdProduto($this->params['id_produto']), $this->params['id_taxa'], $proponente,
                $Proponentes,
                $this->view->atributos
            );

            $valoresSubvencaoEstadual['vl_subvencao_estadual'] = str_replace('.', '', $valoresSubvencaoEstadual['vl_subvencao_estadual']);
            $valoresSubvencaoEstadual['vl_subvencao_estadual'] = str_replace(',', '.', $valoresSubvencaoEstadual['vl_subvencao_estadual']);
        } else {

            $valoresSubvencaoEstadual['vl_subvencao_estadual'] = 0;
            $valoresSubvencaoEstadual['vl_percentual_subvencao_estadual'] = 0;
        }

        $valoresSubvencaoFederal['vl_subvencao_federal'] = str_replace('.', '', $valoresSubvencaoFederal['vl_subvencao_federal']);
        $valoresSubvencaoFederal['vl_subvencao_federal'] = str_replace(',', '.', $valoresSubvencaoFederal['vl_subvencao_federal']);


        $this->params['vl_subvencao_federal'] = number_format($valoresSubvencaoFederal['vl_subvencao_federal'], 2, ',', '.');
        $this->params['vl_percentual_subvencao_federal'] = number_format($valoresSubvencaoFederal['vl_percentual_subvencao_federal'], 2, ',', '.') ?: '-';
        $this->params['vl_subvencao_estadual'] = number_format($valoresSubvencaoEstadual['vl_subvencao_estadual'], 2, ',', '.');
        $this->params['vl_percentual_subvencao_estadual'] = number_format($valoresSubvencaoEstadual['vl_percentual_subvencao_estadual'], 2, ',', '.') ?: '-';
        $this->params['lmga_parcial'] = number_format($this->params['lmga_parcial'], 2, ',', '.');
        $this->params['premio_geral'] = number_format($premio_geral, 2, ',', '.');
        $this->params['vl_produtor_geral'] = number_format($premio_geral - ((float)$valoresSubvencaoFederal['vl_subvencao_federal'] + (float)$valoresSubvencaoEstadual['vl_subvencao_estadual']), 2, ',', '.');
        $this->params['vl_produtor_federal'] = number_format(($premio_geral - (float)$valoresSubvencaoFederal['vl_subvencao_federal']), 2, ',', '.');
        $this->params['vl_produtor_estadual'] = number_format(($premio_geral - (float)$valoresSubvencaoEstadual['vl_subvencao_estadual']), 2, ',', '.');
        $this->params['vl_produtor'] = number_format($premio_geral, 2, ',', '.');

        /**
         * CUIDADO!!!!
         * Não remover $this->view->retornoCalculo, pois é utilizado no método apicorretorescalcularAction, método este
         * chamado pela API de Corretores
         */
        $return['message'] = $this->view->retornoCalculo = $this->params;
        $return['status'] = true;

        $this->getResponse()->setBody(Zend_Json::encode($return));
    }

    private function calcularSubvencaoFederal($Proponentes, $proponente, $premio_geral)
    {
        //Determinar o percentual de subvenção (padrão ou informado)
        //Aplicar o limite máximo absoluto de subvenção federal.
        //Arredondar o valor da subvenção para duas casas decimais.
        //Verificar o valor já utilizado pelo proponente no ano e ajustar se necessário.
        //Verificar o limite por grupo de produtos, se configurado.
        //Garantir que o valor final não seja negativo.
        // 1. Verifica se há percentual padrão de subvenção federal configurado
        if ($this->view->atributos['PROD_PERCENT_SUBVENCAO_FEDERAL'] > 0) {
            // Usa o percentual padrão para calcular a subvenção
            $vl_subvencao_federal = $premio_geral * ($this->view->atributos['PROD_PERCENT_SUBVENCAO_FEDERAL'] / 100);
            $vl_percentual_subvencao_federal = $this->view->atributos['PROD_PERCENT_SUBVENCAO_FEDERAL'];
        }
        // 2. Aplica o limite máximo absoluto de subvenção federal
        if ($vl_subvencao_federal >= $this->view->atributos['PROD_SUBVENCAO_FEDERAL_VALOR_MAX'] && !empty($this->view->atributos['PROD_SUBVENCAO_FEDERAL_VALOR_MAX'])) {

            $vl_subvencao_federal = $this->view->atributos['PROD_SUBVENCAO_FEDERAL_VALOR_MAX'];
            // Recalcula o percentual com base no valor ajustado
            $vl_percentual_subvencao_federal = ($vl_subvencao_federal * 100) / $premio_geral;
        }
        // 3. Arredonda o valor da subvenção para duas casas decimais
        $vl_subvencao_federal = Agro_Util::round($vl_subvencao_federal, 2);
        // 4. Verifica quanto o proponente já utilizou de subvenção federal no ano
        $VALOR_SUBVENCAO_FEDERAL_PROPONENTE_ANO = (!empty($proponente['cpf_cnpj'])) ? $Proponentes->getValorSubvencaoFederalAno($proponente['cpf_cnpj'], '', date('Y-m-d')) : 0;

        // 5. Ajusta o valor da subvenção se a soma ultrapassar o limite anual
        if (($vl_subvencao_federal + $VALOR_SUBVENCAO_FEDERAL_PROPONENTE_ANO) > $this->view->atributos['PROD_SUBVENCAO_FEDERAL_VALOR_MAX'] && !empty($this->view->atributos['PROD_SUBVENCAO_FEDERAL_VALOR_MAX'])) {
            $vl_subvencao_federal = $this->view->atributos['PROD_SUBVENCAO_FEDERAL_VALOR_MAX'] - $VALOR_SUBVENCAO_FEDERAL_PROPONENTE_ANO;
        }
        // 6. Verifica se há limite de subvenção por grupo de produtos
        if (!empty($this->view->atributos['PROD_SUBVENCAO_FEDERAL_VALOR_MAX_GRUPO'])) {
            $propriedadeSubvencaoFederalGrupo = explode(',', $this->view->atributos['PROD_SUBVENCAO_FEDERAL_VALOR_MAX_GRUPO']);
            $valorSubvencaoFederalGrupo = 0;
            $idsTipoProduto = [];

            foreach ($propriedadeSubvencaoFederalGrupo as $indice => $valorPropriedade) {
                if ($indice === 0) {
                    $valorSubvencaoFederalGrupo = $valorPropriedade;
                    continue;
                }
                $idsTipoProduto[] = $valorPropriedade;
            }

            if (empty($idsTipoProduto)) {
                return array(
                    'status' => false,
                    'msg' => 'Produto com Subvenção Federal Por Grupo configurado, porém sem tipo selecionado, impossibilitando o cálculo do Parcelamento.'
                );
            }

            $valorSubvencaoProponenteAnoGrupo = (!empty($proponente)) ? $Proponentes->getValorSubvencaoFederalAnoGrupo($proponente['cpf_cnpj'], '', date('Y-m-d'), $idsTipoProduto) : 0;

            if (($vl_subvencao_federal + $valorSubvencaoProponenteAnoGrupo) > $valorSubvencaoFederalGrupo) {
                $vl_subvencao_federal = $valorSubvencaoFederalGrupo - $valorSubvencaoProponenteAnoGrupo;
            }

            if ($vl_subvencao_federal < 0 && $valorSubvencaoProponenteAnoGrupo > $valorSubvencaoFederalGrupo) {
                $vl_subvencao_federal = 0;
            }
        }

        return [
            'vl_subvencao_federal' => number_format($vl_subvencao_federal, 2, ',', '.'),
            'vl_percentual_subvencao_federal' => $vl_percentual_subvencao_federal];
    }

    private function calcularSubvencaoEstadual($premio_geral, $custo_apolice, $id_estado, $id_produto, $id_taxa, $proponente, $Proponentes, $atributos)
    {
        //Coletar dados: prêmio a pagar, custo da apólice e sigla do estado.
        //Determinar o percentual de subvenção estadual (padrão ou específico para PR).
        //Calcular a subvenção estadual com base no estado e tipo de produto.
        //Aplicar limite máximo estadual por estado (PR ou SP).
        //Arredondar o valor da subvenção (com floor para SP, round para outros).
        //Verificar e aplicar limite por cultura (se configurado para PR).
        //Verificar e aplicar limite anual por proponente.
        //Zerar subvenções se o prêmio geral for menor ou igual a zero.

        $model_estados = new Sistema_Model_Estados();
        $dados = [
            'premio_pagar' => $premio_geral,
            'custo_apolice' => $custo_apolice,
            'ds_sigla' => $model_estados->getName($id_estado)
        ];

        $prod_subvencao_estadual = (float)$atributos['PROD_PERCENT_SUBVENCAO_ESTADUAL'];

        $valor_subvencao_federal_tmp = Agro_Util::round(($dados['premio_pagar'] - $dados['custo_apolice']) * ($prod_subvencao_estadual / 100), 2);

        if ($id_estado == 16) {
            $prod_subvencao_estadual = (float)($atributos['PROD_PERCENT_SUBVENCAO_ESTADUAL_PR']) ?: $atributos['PROD_PERCENT_SUBVENCAO_ESTADUAL'];
        }

        if (in_array($id_estado, [16, 25])) {
            $modelTipos = new Produto_Model_Tipos();
            $tipo_produto = $modelTipos->getTipoViaIdProduto($id_produto['id']);

            if ($tipo_produto['ds_chave_rn'] == 'MULTIRRISCO' && $id_estado == 16) {
                $vlFranquiaProposta = $dados['vlFranquiaProposta'] ?? null;
                if (is_null($vlFranquiaProposta)) {
                    $modelTaxaValores = new Comercializacao_Model_TaxasValores;
                    $taxa = $modelTaxaValores->find($id_taxa)->current();
                    $vlFranquiaProposta = $taxa->vl_franquia;
                }

                if ($vlFranquiaProposta >= $atributos['PROD_PERCENT_MIN_NC_SUBVENCAO_ESTADUAL_PR']) {
                    $vl_subvencao_estadual = ($dados['premio_pagar'] - $dados['custo_apolice']) * ($prod_subvencao_estadual / 100);
                } else {

                    $vl_subvencao_estadual = 0;
                }
            } else {
                $vl_subvencao_estadual = ($dados['premio_pagar'] - $dados['custo_apolice']) * ($prod_subvencao_estadual / 100);
            }
        } else {
            $vl_subvencao_estadual = ($dados['premio_pagar'] - $dados['custo_apolice'] - $valor_subvencao_federal_tmp) * ($prod_subvencao_estadual / 100);
        }

        if ($id_estado == 16 && $vl_subvencao_estadual >= $atributos['PROD_SUBVENCAO_ESTADUAL_VALOR_MAX_PR']) {

            $vl_subvencao_estadual = $atributos['PROD_SUBVENCAO_ESTADUAL_VALOR_MAX_PR'];
        }

        if ($id_estado == 25) {
            $vl_subvencao_estadual = floor($vl_subvencao_estadual * 100) / 100;
        } else {
            $vl_subvencao_estadual = round($vl_subvencao_estadual, 2);
        }

        if ($id_estado == 16 && isset($atributos['PROD_SUBVENCAO_ESTADUAL_CULTURA_PR'])) {
            $prod_subvencao_estadual_cultura_pr = explode(",", $atributos['PROD_SUBVENCAO_ESTADUAL_CULTURA_PR']);
            $VALOR_SUBVENCAO_ESTADUAL_PROPONENTE_ANO_CULTURA = (!empty($proponente)) ? $Proponentes->getValorSubvencaoEstadualAnoPorCulturaCotacao($proponente['cpf_cnpj'], date('Y-m-d'), '', $dados['ds_sigla'], $prod_subvencao_estadual_cultura_pr[1]) : 0;

            if (($vl_subvencao_estadual + $VALOR_SUBVENCAO_ESTADUAL_PROPONENTE_ANO_CULTURA) > $prod_subvencao_estadual_cultura_pr[0]) {
                $vl_subvencao_estadual = $prod_subvencao_estadual_cultura_pr[0] - $VALOR_SUBVENCAO_ESTADUAL_PROPONENTE_ANO_CULTURA;
            }
        }
        if (!empty($proponente)) {
            $VALOR_SUBVENCAO_ESTADUAL_PROPONENTE_ANO = $Proponentes->getValorSubvencaoEstadualAnoCotacao(
                $proponente['cpf_cnpj'],
                date('Y-m-d'),
                '',
                $dados['ds_sigla']);
        } else {
            $VALOR_SUBVENCAO_ESTADUAL_PROPONENTE_ANO = 0;
        }


        if (($vl_subvencao_estadual + $VALOR_SUBVENCAO_ESTADUAL_PROPONENTE_ANO) > $atributos['PROD_SUBVENCAO_ESTADUAL_VALOR_MAX']) {
            $vl_subvencao_estadual = $atributos['PROD_SUBVENCAO_ESTADUAL_VALOR_MAX'] - $VALOR_SUBVENCAO_ESTADUAL_PROPONENTE_ANO;
        }

        if ($premio_geral <= 0) {
            $prod_subvencao_estadual = 0;
            $vl_percentual_subvencao_federal = 0;
        }
        return [
            'vl_subvencao_estadual' => number_format($vl_subvencao_estadual, 2, ',', '.'),
            'vl_percentual_subvencao_estadual' => number_format($prod_subvencao_estadual, 2, ',', '.')
        ];
    }

    public function saveAction()
    {
        $this->isAjax();

        $params = $this->getRequest()->getParams();
        $Model = $this->getModel();


        $vl_comissao = $vl_comissao[1]; // pega comissao selecionada

        $Prepostos = new Sistema_Model_Prepostos();

        $produtoGeral = (new Produto_Model_Produtos())->find($params['cotacao']['id_produto'])->current()->produto_geral();

        if ($params['cotacao']['id_preposto']) {
            $preposto = $Prepostos->findByUser($params['cotacao']['id_preposto']);
            $params['cotacao']['id_preposto'] = $preposto->id;
        }

        if ($params['cotacao']['id_corretor']) {
            $Corretores = new Sistema_Model_Corretores();
            $corretor = $Corretores->findByUser($params['cotacao']['id_corretor']);
            $params['cotacao']['id_corretor'] = $corretor->id;
        } else {
            $params['cotacao']['id_corretor'] = $preposto->id_corretor;
            $corretor = $Prepostos->getCorretor($preposto->id);
        }

        $limitesTon = $Model->getIsMinMax($params['cotacao']['id_produto']);

        if (count($limitesTon) > 0) {
            $i = 0;
            foreach ($params['cotacao']['unidades'] as $unid) {
                $i++;
                $tonl = str_replace(',', '.', str_replace('.', '', $unid['tonelada']));
                if (($tonl > $limitesTon['is_max']) || ($tonl < $limitesTon['is_min'])) {
                    $result['message'] = 'ERRO! O valor tonelada (R$ ' . $unid['tonelada'] .
                        ') da unidade ' . $i . ' não está entre o intervalo R$ ' . number_format($limitesTon['is_min'], 2, ',', '.') .
                        ' e R$ ' . number_format($limitesTon['is_max'], 2, ',', '.') . ') por unidade.';
                    $result['status'] = false;
                    return $this->getResponse()->setBody(Zend_Json::encode($result));
                }
            }
        } elseif ((int)$produtoGeral['id_tipo_produto'] === Produto_Model_Tipos::MULTIRRISCO) {
            foreach ($params['cotacao']['unidades'] as $indice => $unid) {
                $between = (new Produto_Model_ProdutosVariedades())->checkBetweenVariedadeCotacao($params, $indice, true);

                if (is_array($between)) {
                    $valor = Agro_Util::formatCurrencyDb($between[2]);
                    $min = Agro_Util::formatCurrencyDb($between[0]);
                    $max = Agro_Util::formatCurrencyDb($between[1]);

                    if ($valor < $min || $valor > $max) {
                        $result['message'] = "O Valor (R$ " . Agro_Util::formatDbCurrency($valor) . ") da LMGA por hectare (ha) não está entre " . Agro_Util::formatDbCurrency($min) . " e " . Agro_Util::formatDbCurrency($max);
                        $result['status'] = false;

                        return $this->getResponse()->setBody(Zend_Json::encode($result));
                    }
                }
            }
        } else {
            $modelProdutosVariedades = new Produto_Model_ProdutosVariedades();
            $validacoes = (new Produto_Model_Validacoes())->getValidacaoProduto($params['cotacao']['id_produto']);

            if ($validacoes->count()) {
                foreach ($validacoes as $validacao) {
                    if ($validacao->ds_chave == 'VALIDACAO_VARIEDADE_LIMITE') {
                        foreach ($params['cotacao']['unidades'] as $indice => $unid) {
                            $between = $modelProdutosVariedades->checkBetweenVariedadeCotacao($params, $indice);

                            if (is_array($between)) {
                                $valor = Agro_Util::formatCurrencyDb($between[2]);
                                $min = Agro_Util::formatCurrencyDb($between[0]);
                                $max = Agro_Util::formatCurrencyDb($between[1]);

                                if ($valor < $min || $valor > $max) {
                                    $result['message'] = "O Valor (R$ " . Agro_Util::formatDbCurrency($valor) . ") da LMGA por hectare (ha) não está entre " . Agro_Util::formatDbCurrency($min) . " e " . Agro_Util::formatDbCurrency($max);
                                    $result['status'] = false;

                                    return $this->getResponse()->setBody(Zend_Json::encode($result));
                                }
                            }
                        }
                    }
                }
            }
        }

        Agro_Db_Table_Abstract::getDefaultAdapter()->beginTransaction();

        if (is_array($params['proponente'])) {
            $Proponente = new Seguro_Model_Proponentes();
            $params['proponente']['id_municipio_proponente'] = $params['cotacao']['id_municipio'];
            $prop = $Proponente->save($params['proponente']);
            if (!$prop) {
                $result = array('status' => false, 'message' => 'ATENÇÃO: Erro ao adicionar novo proponente.');
                return $this->getResponse()->setBody(Zend_Json::encode($result));
            }
        }

        //Validando subvençáo cultura
        $subvencao = $Model->getSubvencaoCultura($corretor != '' ? $corretor->id_usuario : $preposto->id_usuario, $params['cotacao']['id_produto']);

        if (($subvencao['usado'] + $params['cotacao']['calculo']['sub_federal']) > $subvencao['liberado']) {
            $result['message'] = 'O Valor da Subvenção Federal atingiu o limite liberado para esta Cultura / Corretor.';
            $result['status'] = false;
            Agro_Db_Table_Abstract::getDefaultAdapter()->rollBack();
            return $this->getResponse()->setBody(Zend_Json::encode($result));
        }

        //Validando subvenção grupo corretores
        $subvencao = $Model->subvencaoCulturaGrupoCorretores($corretor != '' ? $corretor->id_usuario : $preposto->id_usuario, $params['cotacao']['id_produto']);
        if ($subvencao['liberado'] != '') {
            if (($subvencao['usado'] + $params['cotacao']['calculo']['sub_federal']) > $subvencao['liberado']) {
                $result['message'] = 'O Valor da Subvenção Federal atingiu o limite liberado para esta Cultura / Grupo de Corretores.';
                $result['status'] = false;
                Agro_Db_Table_Abstract::getDefaultAdapter()->rollBack();
                return $this->getResponse()->setBody(Zend_Json::encode($result));
            }
        }

        $id_cotacao = $Model->save($params['cotacao']);

        if ((integer)$id_cotacao > 0) {
            if (count($params['cotacao']['unidades']) <= 0) {
                $result = array('status' => false, 'message' => 'ATENÇÃO: Adicione ao menos uma Unidade Segurada.');
                Agro_Db_Table_Abstract::getDefaultAdapter()->rollBack();
                return $this->getResponse()->setBody(Zend_Json::encode($result));
            }

            $CotacoesUnidades = new Seguro_Model_CotacoesUnidades();
            $CotacoesUnidades->getDefaultAdapter()->query("DELETE FROM seguro.cotacoes_unidades WHERE id_cotacao = " . $id_cotacao);
            foreach ($params['cotacao']['unidades'] as $unidades) {
                $unidades['id_cotacao'] = $id_cotacao;
                $unidade = $CotacoesUnidades->save($unidades);
                if ((integer)$unidade == 0) {
                    $result = array('status' => false, 'message' => $unidade);
                    Agro_Db_Table_Abstract::getDefaultAdapter()->rollBack();
                    return $this->getResponse()->setBody(Zend_Json::encode($result));
                }
            }

            if (count($params['cotacao']['cob_principal']) > 0) {
                $CotacoesCoberturas = new Seguro_Model_CotacoesCoberturas();
                $CotacoesCoberturas->getDefaultAdapter()->query("DELETE FROM seguro.cotacoes_coberturas WHERE id_cotacao = " . $id_cotacao);

                $params['cotacao']['cob_principal']['id_cotacao'] = $id_cotacao;
                $cob_principal = $CotacoesCoberturas->save($params['cotacao']['cob_principal']);

                if ((integer)$cob_principal == 0) {
                    $result = array('status' => false, 'message' => $cob_principal);
                    Agro_Db_Table_Abstract::getDefaultAdapter()->rollBack();
                    return $this->getResponse()->setBody(Zend_Json::encode($result));
                }

                if (count($params['cotacao']['cob_adicionais']) > 0) {
                    foreach ($params['cotacao']['cob_adicionais'] as $coberturas) {
                        $coberturas['id_cotacao'] = $id_cotacao;
                        $cobertura = $CotacoesCoberturas->save($coberturas);
                        if ((integer)$cobertura == 0) {
                            $result = array('status' => false, 'message' => $cobertura);
                            Agro_Db_Table_Abstract::getDefaultAdapter()->rollBack();
                            return $this->getResponse()->setBody(Zend_Json::encode($result));
                        }
                    }
                }
            } else {
                $result = array('status' => false, 'message' => 'Selecione ao menos a cobertura principal.');
                Agro_Db_Table_Abstract::getDefaultAdapter()->rollBack();
                return $this->getResponse()->setBody(Zend_Json::encode($result));
            }

            $result = array('status' => true, 'message' => 'Cotação salva com sucesso!');
            Agro_Db_Table_Abstract::getDefaultAdapter()->commit();
            return $this->getResponse()->setBody(Zend_Json::encode($result));
        } else {
            $result = array('status' => false, 'message' => $id_cotacao);
            Agro_Db_Table_Abstract::getDefaultAdapter()->rollBack();
            return $this->getResponse()->setBody(Zend_Json::encode($result));
        }
    }

    public function getFilter()
    {
        $User = Zend_Auth::getInstance()->getIdentity();

        $where = array();

        if ($this->getRequest()->getParam('id_safra')) {
            $where[] = array(
                'field' => 'id_safra',
                'operator' => '=',
                'value' => $this->getRequest()->getParam('id_safra')
            );
        }

        if ($this->getRequest()->getParam('id_produto')) {
            $where[] = array(
                'field' => 'id_produto',
                'operator' => '=',
                'value' => $this->getRequest()->getParam('id_produto')
            );
        }

        if ($this->getRequest()->getParam('id_safra_search')) {
            $where[] = array(
                'field' => 'id_safra',
                'operator' => '=',
                'value' => $this->getRequest()->getParam('id_safra_search')
            );
        }

        if ($this->getRequest()->getParam('id_produto_search')) {
            $where[] = array(
                'field' => 'id_produto',
                'operator' => '=',
                'value' => $this->getRequest()->getParam('id_produto_search')
            );
        }

        if ($this->getRequest()->getParam('id_estado')) {
            $where[] = array(
                'field' => 'id_estado',
                'operator' => '=',
                'value' => $this->getRequest()->getParam('id_estado')
            );
        }

        if ($this->getRequest()->getParam('id_municipio')) {
            $where[] = array(
                'field' => 'id_municipio',
                'operator' => '=',
                'value' => $this->getRequest()->getParam('id_municipio')
            );
        }

        if ($this->getRequest()->getParam('id_estado_search')) {
            $where[] = array(
                'field' => 'sc.id_estado',
                'operator' => '=',
                'value' => $this->getRequest()->getParam('id_estado_search')
            );
        }

        if ($this->getRequest()->getParam('id_municipio_search')) {
            $where[] = array(
                'field' => 'sc.id_municipio',
                'operator' => '=',
                'value' => $this->getRequest()->getParam('id_municipio_search')
            );
        }

        if ($this->getRequest()->getParam('ds_nome_proponente')) {
            $where[] = array(
                'field' => 'ds_nome_proponente',
                'operator' => 'ilike',
                'value' => '%' . $this->getRequest()->getParam('ds_nome_proponente') . '%'
            );
        }

        if ($this->getRequest()->getParam('numero_cotacao_search')) {
            $where[] = array(
                'field' => 'sc.id',
                'operator' => '=',
                'value' => $this->getRequest()->getParam('numero_cotacao_search')
            );
        }

        if ($this->getRequest()->getParam('cpf_cnpj_search')) {
            $where[] = array(
                'field' => 'sc.cpf_cnpj',
                'operator' => '=',
                'value' => $this->getRequest()->getParam('cpf_cnpj_search')
            );
        }

        if ($this->getRequest()->getParam('data_cadastro_inicio')) {
            $where[] = array(
                'field' => "sc.dt_criacao::date",
                'operator' => '>=',
                'value' => Agro_Util::formatDate($this->getRequest()->getParam('data_cadastro_inicio'), 'YYYY-MM-dd')
            );
        }

        if ($this->getRequest()->getParam('data_cadastro_fim')) {
            $where[] = array(
                'field' => "sc.dt_criacao::date",
                'operator' => '<=',
                'value' => Agro_Util::formatDate($this->getRequest()->getParam('data_cadastro_fim'), 'YYYY-MM-dd')
            );
        }

        switch ($User->tp_usuario) {
            case 'C':
                $Corretores = new Sistema_Model_Corretores();
                $corretor = $Corretores->findByUser($User->id);

                $where[] = array(
                    'field' => 'sc.id_corretor',
                    'operator' => '=',
                    'value' => $corretor->id
                );

                if ($this->getRequest()->getParam('id_preposto')) {
                    $Prepostos = new Sistema_Model_Prepostos();
                    $preposto = $Prepostos->findByUser($this->getRequest()->getParam('id_preposto'));
                    $where[] = array(
                        'field' => 'id_preposto',
                        'operator' => '=',
                        'value' => $preposto->id
                    );
                }

                if ($this->getRequest()->getParam('id_preposto_search')) {
                    $Prepostos = new Sistema_Model_Prepostos();
                    $preposto = $Prepostos->findByUser($this->getRequest()->getParam('id_preposto_search'));
                    $where[] = array(
                        'field' => 'id_preposto',
                        'operator' => '=',
                        'value' => $preposto->id
                    );
                }
                break;

            case 'P':
                $Prepostos = new Sistema_Model_Prepostos();
                $preposto = $Prepostos->findByUser($User->id);
                $where[] = array(
                    'field' => 'sc.id_preposto',
                    'operator' => '=',
                    'value' => $preposto->id
                );
                break;

            default:
                if ($this->getRequest()->getParam('id_corretor')) {
                    $Corretores = new Sistema_Model_Corretores();
                    $corretor = $Corretores->findByUser($this->getRequest()->getParam('id_corretor'));

                    $where[] = array(
                        'field' => 'sc.id_corretor',
                        'operator' => '=',
                        'value' => $corretor->id
                    );
                }

                if ($this->getRequest()->getParam('id_preposto')) {
                    $preposto = $Prepostos->findByUser($this->getRequest()->getParam('id_preposto'));
                    $Prepostos = new Sistema_Model_Prepostos();
                    $where[] = array(
                        'field' => 'id_preposto',
                        'operator' => '=',
                        'value' => $preposto->id
                    );
                }

                if ($this->getRequest()->getParam('id_corretor_search')) {
                    $Corretores = new Sistema_Model_Corretores();
                    $corretor = $Corretores->findByUser($this->getRequest()->getParam('id_corretor_search'));

                    $where[] = array(
                        'field' => 'sc.id_corretor',
                        'operator' => '=',
                        'value' => $corretor->id
                    );
                }

                if ($this->getRequest()->getParam('id_preposto_search')) {
                    $Prepostos = new Sistema_Model_Prepostos();
                    $preposto = $Prepostos->findByUser($this->getRequest()->getParam('id_preposto_search'));
                    $Prepostos = new Sistema_Model_Prepostos();
                    $where[] = array(
                        'field' => 'id_preposto',
                        'operator' => '=',
                        'value' => $preposto->id
                    );
                }
        }

        return $where;
    }

    private function calcularProdutividadeGarantida($produtividade, $franquia)
    {
        return number_format($produtividade * ($franquia / 100), 3, ',', '.');
    }

    private function isProducaoGarantida()
    {
        if (!$this->view->atributos) {
            $this->view->atributos = $this->getValorAtributos();
        }

        return $this->view->atributos['PROD_PRODUCAO_GARANTIDA'] && $this->view->atributos['PROD_PRODUCAO_GARANTIDA'] == "1";
    }

    function coberturascotacaoAction()
    {
        $this->isAjax();
        $lmga = null;
        $atributos = (new Produto_Model_ProdutosAtributos())->getAtributosFromProduto($this->getRequest()->getParam('id_produto'));

        $ModelCotacoes = $this->getModel();
        $cotacao = $ModelCotacoes->fetchRow('id = ' . $this->getRequest()->getParam('id_cotacao'))->toArray();

        $ModelCoberturas = new Seguro_Model_CotacoesCoberturas();
        $coberturas = $ModelCoberturas->fetchAll('id_cotacao = ' . $this->getRequest()->getParam('id_cotacao'))->toArray();

        foreach ($coberturas as $cobertura) {
            if ($cobertura['fl_principal']) {
                $franquia = $cobertura['vl_franquia'];
            }
        }

        $ModelUnidades = new Seguro_Model_CotacoesUnidades();
        $unidades = $ModelUnidades->fetchAll('id_cotacao = ' . $this->getRequest()->getParam('id_cotacao'))->toArray();

        foreach ($unidades as $unidade) {
            $lmga += $unidade['vl_area'] * round(($unidade['vl_produtividade'] * $franquia) / 100 / 1000, 3) * $unidade['vl_tonelada'];
        }

        $cotacao['lmga'] = number_format($lmga, 2, ',', '.');
        $cotacao['comissao'] = ($atributos[178]) ? $atributos[178] : '';
        if (count($coberturas) > 0) {
            $this->params = $this->getRequest()->getParams();

            if (empty($this->params['id_produto']) || $this->params['id_produto'] == "null") {
                $result = array('status' => false, 'message' => 'Não foi possível buscar as cotações das coberturas. Informe o produto.');
                $this->getResponse()->setBody(Zend_Json::encode($result));
                return false;
            }

            $isProducaoGarantida = $this->isProducaoGarantida();
            $produtividade = 0;

            if ($isProducaoGarantida) {
                $argumento = $this->getGrupo();
                $produtividade = $argumento['vl_produtividade_estimada'] > 0 ? $argumento['vl_produtividade_estimada'] : null;
            }

            foreach ($coberturas as &$cobertura) {
                $cobertura['vl_pg'] = $this->calcularProdutividadeGarantida($produtividade, $cobertura['vl_franquia']);
            }

            $result = array('status' => true, 'message' => $coberturas, 'cotacao' => $cotacao, 'isProducaoGarantida' => $isProducaoGarantida);
        } else {
            $result = array('status' => false, 'message' => 'Nenhuma cobertura encontrada para cotação.');
        }

        return $this->getResponse()->setBody(Zend_Json::encode($result));
    }

    function deleteAction()
    {
        $this->isAjax();
        $result = array('status' => false, 'message' => 'ATENÇÂO: Erro ao excluir cotação.');

        if ($this->getRequest()->getParam('id')) {
            $CotacoesCoberturas = new Seguro_Model_CotacoesCoberturas();
            $CotacoesUnidades = new Seguro_Model_CotacoesUnidades();
            $Model = $this->getModel();

            try {
                Agro_Db_Table_Abstract::getDefaultAdapter()->beginTransaction();

                Agro_Db_Table_Abstract::getDefaultAdapter()->query(
                    'DELETE FROM seguro.cotacoes_coberturas WHERE id_cotacao = ' . $this->getRequest()->getParam('id'));

                Agro_Db_Table_Abstract::getDefaultAdapter()->query(
                    'DELETE FROM seguro.cotacoes_unidades WHERE id_cotacao = ' . $this->getRequest()->getParam('id'));

                $Model->delete($this->getRequest()->getParam('id'));

                $result = array('status' => true, 'message' => 'Cotação excluída.');
                Agro_Db_Table_Abstract::getDefaultAdapter()->commit();

            } catch (Exception $e) {
                $result = array('status' => false, 'message' => $e->getMessage());
                Agro_Db_Table_Abstract::getDefaultAdapter()->rollBack();
            }
        }

        return $this->getResponse()->setBody(Zend_Json::encode($result));
    }

    function gerarorcamentoAction()
    {
        $this->isAjax();
        $result = array('status' => false, 'message' => 'Nada foi feito.');
        $post = array();
        $User = Zend_Auth::getInstance()->getIdentity();

        $ModelCotacoes = $this->getModel();
        $cotacao = $ModelCotacoes->fetchRow('id = ' . $this->getRequest()->getParam('id'))->toArray();

        $Corretores = new Sistema_Model_Corretores();
        $corretor = $Corretores->fetchRow('id = ' . $cotacao['id_corretor'])->toArray();

        if ($cotacao['id_preposto'] > 0) {
            $Prepostos = new Sistema_Model_Prepostos();
            $preposto = $Prepostos->fetchRow('id = ' . $cotacao['id_preposto'])->toArray();
        } else {
            $preposto['id_usuario'] = null;
        }

        $ModelCotacaoCoberturas = new Seguro_Model_CotacoesCoberturas();
        $coberturas = $ModelCotacaoCoberturas->fetchAll('id_cotacao = ' . $this->getRequest()->getParam('id'))->toArray();

        $ModelCotacaoUnidades = new Seguro_Model_CotacoesUnidades();
        $unidades = $ModelCotacaoUnidades->fetchAll('id_cotacao = ' . $this->getRequest()->getParam('id'))->toArray();

        $Propostas = new Seguro_Model_Propostas();
        $id_proposta = $Propostas->iniciaProposta($cotacao['id_produto'], $corretor['id_usuario'], $preposto['id_usuario']);

        if ($id_proposta) {

            //atualiza valor comissao da proposta através da model de proposta
            $Propostas->atualizarComissao($id_proposta, $cotacao['vl_comissao']);

            $post['usuario_logado'] = $User->id;
            $post['id_produto'] = $cotacao['id_produto'];
            $post['id_corretor'] = $cotacao['id_corretor'];
            $post['id_preposto'] = $cotacao['id_preposto'];
            $post['id_proposta'] = $id_proposta;

            $post['proponente']['tp_pessoa'] = strlen($cotacao['cpf_cnpj']) == 14 ? 'F' : 'J';
            $post['proponente']['cpf_cnpj'] = $cotacao['cpf_cnpj'];

            //buscar endereço do proponente, caso existe
            $ModelProponentes = new Seguro_Model_Proponentes();
            $where[] = array('field' => 'cpf_cnpj', 'operator' => '=', 'value' => $cotacao['cpf_cnpj']);
            $proponente = $ModelProponentes->fetchRow($ModelProponentes->getData($where))->toArray();

            if (count($proponente) > 0) {
                $post['proponente']['ds_nome_proponente'] = $proponente['ds_nome_proponente'];
                $post['proponente']['ds_sexo'] = $proponente['ds_sexo'];
                $post['proponente']['ds_documento_natureza'] = $proponente['ds_documento_natureza'];
                $post['proponente']['ds_documento_numero'] = $proponente['ds_documento_numero'];
                $post['proponente']['id_orgao_expedidor'] = $proponente['id_orgao_expedidor'];
                $post['proponente']['id_estado_civil'] = $proponente['id_estado_civil'];
                $post['proponente']['dt_nascimento'] = $proponente['dt_nascimento'];
                $post['proponente']['ds_tel_residencia'] = $proponente['ds_tel_residencia'];
                $post['proponente']['ds_tel_celular'] = $proponente['ds_tel_celular'];
                $post['proponente']['ds_tel_propriedade'] = $proponente['ds_tel_propriedade'];
                $post['proponente']['ds_endereco_cep'] = $proponente['ds_endereco_cep'];
                $post['proponente']['ds_endereco_rua'] = $proponente['ds_endereco_rua'];
                $post['proponente']['ds_endereco_nro'] = $proponente['ds_endereco_nro'];
                $post['proponente']['ds_endereco_complem'] = $proponente['ds_endereco_complem'];
                $post['proponente']['ds_endereco_bairro'] = $proponente['ds_endereco_bairro'];
                $post['proponente']['id_municipio'] = $proponente['id_municipio'];
                $post['proponente']['id_estado'] = $proponente['id_estado'];
            }


            $post['propriedade']['ds_endereco_cep'] = substr($cotacao['cep'], 0, 5) . '-' . substr($cotacao['cep'], 5, 3);
            $post['propriedade']['id_estado'] = $cotacao['id_estado'];
            $post['propriedade']['id_municipio'] = $cotacao['id_municipio'];
            $post['propriedade']['ds_endereco'] = 'preencher';
            $post['propriedade']['ds_nome_propriedade'] = $post['proponente']['ds_nome_proponente'];

            $nro = 1;
            foreach ($unidades as $un) {
                $post['unidades'][$nro]['IS_AREA'] = $un['vl_area'];
                $post['unidades'][$nro]['IS_PRODUTIVIDADE'] = $un['vl_produtividade'];
                $post['unidades'][$nro]['IS_VALOR_TONELADA'] = $un['vl_tonelada'];
                $post['unidades'][$nro]['IS_VARIEDADES'] = 1185;
                $post['unidades'][$nro]['IS_DESCRICAO_ITEM'] = 'COTACAO_QUADRA_' . $nro;
                $nro++;
            }

            foreach ($coberturas as $cob) {
                $post['coberturas'][$cob['id_cobertura']]['fl_principal'] = $cob['fl_principal'];
                $post['coberturas'][$cob['id_cobertura']]['vl_taxa'] = $cob['vl_taxa'];
                $post['coberturas'][$cob['id_cobertura']]['vl_premio'] = $cob['vl_premio'];
                $post['coberturas'][$cob['id_cobertura']]['id_cobertura'] = $cob['id_cobertura'];
                $post['coberturas'][$cob['id_cobertura']]['vl_franquia'] = $cob['vl_franquia'];
            }

            $post['parcela']['federal'] = $cotacao['vl_subvencao_federal'];
            $post['parcela']['estadual'] = $cotacao['vl_subvencao_estadual'];
            $post['parcela']['segurado'] = $cotacao['vl_premio'] - $cotacao['vl_subvencao_federal'] - $cotacao['vl_subvencao_estadual'];
            $post['parcela']['vencimento'] = date('d/m/Y');

            Agro_Db_Table_Abstract::getDefaultAdapter()->beginTransaction();

            try {
                $ModelCotacoes->saveProponenteData($post['proponente'], $id_proposta);
                $ModelCotacoes->savePropriedadeData($post['propriedade'], $id_proposta);
                $ModelCotacoes->saveUnidadesData($post['unidades'], $id_proposta);
                $ModelCotacoes->saveCoberturasData($post['coberturas'], $id_proposta, $cotacao['id_produto']);
                $ModelCotacoes->saveParcelaData($post['parcela'], $id_proposta);

                //coloca a proposta no status 2
                $Status = new Seguro_Model_PropostaStatus();
                $Status->save(array(
                    'ds_observacao' => 'Gerado a partir de cotação',
                    'id_proposta' => $id_proposta,
                    'id_status' => 2
                ));
                Agro_Db_Table_Abstract::getDefaultAdapter()->query('update seguro.propostas set id_status = 2 where id = ' . $id_proposta);

                //seta a proposta para vigente
                Agro_Db_Table_Abstract::getDefaultAdapter()->query('update seguro.propostas_endosso set fl_proposta_vigente = true where id_proposta = ' . $id_proposta);

                //atualiza codigo da proposta que a cotação gerou
                Agro_Db_Table_Abstract::getDefaultAdapter()->query('update seguro.cotacoes set id_proposta = ' . $id_proposta . ' where id = ' . $cotacao['id']);

                $result = array('status' => true, 'message' => 'Orçamento ' . $id_proposta . ' gerado com sucesso.');
                Agro_Db_Table_Abstract::getDefaultAdapter()->commit();
            } catch (Exception $e) {
                Agro_Db_Table_Abstract::getDefaultAdapter()->rollBack();
                $result = array('status' => false, 'message' => $e->getMessage());
            }
        }

        return $this->getResponse()->setBody(Zend_Json::encode($result));
    }

    public function listAction()
    {
        $this->getHelper('layout')->disableLayout();
        $where = $this->getFilter();
        $Model = $this->getModel();
        $recordsPerPage = ($this->recordsPerPage ? $this->recordsPerPage : RECORDS_PER_PAGE);
        $Rs = $Model->fetchAllPaginator($where, $this->getRequest()->getParam('page'), $recordsPerPage, $this->_paginator);
        $this->view->paginator = $Rs;
    }

    public function getproponenteAction()
    {
        $this->isAjax();
        $Proponentes = new Seguro_Model_Proponentes();
        $Row = $Proponentes->fetchRow("cpf_cnpj = '" . $this->getRequest()->getParam('cpf_cnpj') . "'");
        $Row = ($Row ? $Row->toArray() : null);
        $this->getResponse()->setBody(Zend_Json::encode($Row));
    }

    public function recalcularAction()
    {
        $this->isAjax();
        //Instancia model tipos
        $modelTipos = new Produto_Model_Tipos();
        //Acessa parametros recebidos
        $this->params = $this->getRequest()->getParams();
        //Instancia model proponentes
        $Proponentes = new Seguro_Model_Proponentes();
        //Acessa proponente da proposta
        $proponente = $Proponentes->getProponente($this->params['cpf_cnpj']);
        //Acessa id da taxa
        $franquia = $this->params['taxa'];
        $franquia = explode("#", $franquia);
        $this->params['id_taxa'] = $franquia[1];
        //Injeta atributos na view
        $this->view->atributos = $this->getValorAtributos();
        //Formata lmga
        $lmga = number_format($this->params['lmga'], 2, ',', '.');

        $vl_percentual_subvencao_federal = $franquia[2];

        $idCotacao = $this->params['id_cotacao'];
        $idProduto = $this->params['id_produto'];
        $unidades = $this->params['unidades'];

        $comissao = [
            'vl_nova_comissao' => $this->params['vl_nova_comissao'],
            'vl_comissao_original' => $this->params['vl_comissao_original'],
            'valorComissaoAdicional' => $this->params['valorComissaoAdicional']
        ];
        //faz o cálculo do premio levando em consideração taxa e comissão selecionada
		$return = Agro_Regras::RN_CALC_07($lmga, $franquia[0], $comissao, $idProduto, $this->params['id_estado'], $this->params['id_usuario']);
        $taxa = $return['taxa'];
        $premio = $return['premio'];
        $valorFranquiaSelecionada = $this->params['valorFranquiaSelecionada'];
        $vlAcrescimoGeada = false;

        $return['coberturas_adicionais'] = $this->calculacoberturasadicionais(
            $vlAcrescimoGeada,
            $valorFranquiaSelecionada,
            $lmga
        );

        $premio_tarifario_geral = floatval(str_replace(',', '.', str_replace('.', '', $premio))) + $return['coberturas_adicionais']['premio_tarifario_geral_coberturas_adicionais'];

        $valoresSubvencaoFederal = $this->calcularSubvencaoFederal($Proponentes, $proponente, $premio_tarifario_geral);

        if (in_array($this->params['id_estado'], [16, 25])) {
            $valoresSubvencaoEstadual = $this->calcularSubvencaoEstadual(
                $premio_tarifario_geral,
                $this->view->atributos['PROD_CUSTO_APOLICE'],
                $this->params['id_estado'],
                $modelTipos->getTipoViaIdProduto($this->params['id_produto']), $this->params['id_taxa'], $proponente,
                $Proponentes,
                $this->view->atributos
            );
            $return['valores_subvencao_estadual'] = $valoresSubvencaoEstadual;
            $valoresSubvencaoEstadual['vl_subvencao_estadual'] = str_replace('.', '', $valoresSubvencaoEstadual['vl_subvencao_estadual']);
            $valoresSubvencaoEstadual['vl_subvencao_estadual'] = str_replace(',', '.', $valoresSubvencaoEstadual['vl_subvencao_estadual']);
        } else {
            $return['valores_subvencao_estadual'] = ['vl_subvencao_estadual' => 0, 'vl_percentual_subvencao_estadual' => 0];
            $valoresSubvencaoEstadual['vl_subvencao_estadual'] = 0;
            $valoresSubvencaoEstadual['vl_percentual_subvencao_estadual'] = 0;
        }

        $return['valores_subvencao_federal'] = $valoresSubvencaoFederal;
        $valoresSubvencaoFederal['vl_subvencao_federal'] = str_replace('.', '', $valoresSubvencaoFederal['vl_subvencao_federal']);
        $valoresSubvencaoFederal['vl_subvencao_federal'] = str_replace(',', '.', $valoresSubvencaoFederal['vl_subvencao_federal']);

        $return['lmga'] = $lmga;
        $return['premio_tarifario_geral'] = number_format($premio_tarifario_geral, 2, ',', '.');
        $return['premio_produtor_geral'] = number_format($premio_tarifario_geral - ((float)$valoresSubvencaoFederal['vl_subvencao_federal'] + (float)$valoresSubvencaoEstadual['vl_subvencao_estadual']), 2, ',', '.');

        $this->getResponse()->setBody(Zend_Json::encode($return));
    }

    public function calculacoberturasadicionais(
        $vlAcrescimoGeada = 0,
        $valorFranquiaSelecionada = null,
        $lmga
    )
    {
        $User = Zend_Auth::getInstance()->getIdentity();
        $modelCoberturas = new Produto_Model_Coberturas();
		$idUsuario = (!empty($this->params['id_usuario'])) ? $this->params['id_usuario'] : $User->id;
        $ProdCoberturas = new Produto_Model_ProdutosCoberturas();
        $Taxas = new Comercializacao_Model_Taxas();
        $id_municipio = $this->getRequest()->getParam('id_municipio');
        $id_produto = $this->getRequest()->getParam('id_produto');

        $premio_tarifario_geral_coberturas_adicionais = 0;
        try {

            $arrCoberturas = explode('--', $this->getRequest()->getParam('coberturas'));
            if (is_array($arrCoberturas)) {
                $coberturas = array();
                foreach ($arrCoberturas as $Cobertura) {
                    $arrTemp = explode('#', $Cobertura);
                    // Index 0 = id_cobertura
                    // Index 1 = franquina
                    // Index 2 = id_taxa

                    if ($arrTemp[0]) {
                        $coberturas[$arrTemp[0]] = array($arrTemp[1], $arrTemp[2]);
                    }
                }
            }

            $return = array();

            if (is_array($coberturas) && count($coberturas)) {
                $mapTaxaCarToCobertura = [];

                foreach ($coberturas as $cobertura => $franquia) {

                    if ($cobertura) {
                        $ProdCobertura = $ProdCoberturas->find($this->getRequest()->getParam('id_produto'), $cobertura)->current();
                        $rowCobertura = $modelCoberturas->find($ProdCobertura['id_cobertura'])->current();
                        $valorFranquia = null;

                        if (!empty($mapTaxaCarToCobertura[$cobertura])) {
                            $taxaRelacionada = (object)$mapTaxaCarToCobertura[$cobertura][(int)$valorFranquiaSelecionada];
                            $fl_independente = false;
                            $valorFranquia = $taxaRelacionada->vl_franquia;
                        } elseif ($ProdCobertura->fl_taxa_relacionada) {
                            $taxaRelacionada = $Taxas->getTaxaRelacionada($franquia[1], $cobertura);
                            $fl_independente = false;
                        } else {
                            $taxaRelacionada = $Taxas->getTaxaNaoRelacionada($franquia[1], $propostaRenovada);
                            $fl_independente = true;
                        }

                        $TaxasValores = new Comercializacao_Model_TaxasValores();

                        if (is_null($valorFranquia)) {
                            $Valores = $TaxasValores->find($franquia[1])->current();
                            $valorFranquia = $Valores->vl_franquia;
                        }

                        $dados = array();

                        $dados['taxa'] = ($taxaRelacionada->vl_taxa ? $taxaRelacionada->vl_taxa : $franquia[0]);

                        if (in_array($cobertura, array(5, 30, 31, 36))) {
                            $ProdutosAtributos = new Produto_Model_ProdutosAtributos();

                            $taxaReplantio = $ProdutosAtributos->getTaxaReplantio(
                                $id_produto,
								$idUsuario,
                                $id_municipio,
                                null,
                                false
                            );
                            $dados['taxa'] = is_null($taxaReplantio) ? $dados['taxa'] : $taxaReplantio;
                        }

                        $dados['comissao']['vl_comissao_original'] = $this->getRequest()->getParam('vl_comissao_original');
                        $dados['comissao']['vl_nova_comissao'] = $this->getRequest()->getParam('vl_nova_comissao');

                        $dados['lmga'] = Agro_Util::formatCurrencyDb($lmga);

                        if ($cobertura == 3 && $vlAcrescimoGeada > 0) {
                            $dados['taxa'] = round($vlAcrescimoGeada * $dados['taxa'], 2);
                        }

						$calc = Agro_Regras::RN_CALC_08($dados['taxa'], $dados['comissao'], $id_produto, $lmga, $id_municipio, $idUsuario);

                        $premio_tarifario_geral_coberturas_adicionais += floatval(str_replace(',', '.', str_replace('.', '', $calc['premio'])));

                        $return[] = array(
                            'mostra_franquia' => Agro_Util::formatDbCurrency($valorFranquia, 2, '.', ''),
                            'premio_tarifario' => $calc['premio'],
                            'id_cobertura' => $cobertura,
                            'nome_cobertura' => $rowCobertura['ds_nome_cobertura'],
                            'vl_franquia' => $franquia[0],
                            'id_taxa' => $franquia[1],
                            'vl_taxa' => $calc['taxa'],
                            'fl_independente' => $fl_independente,
                            'lmga' => $calc['lmga_parcial']
                        );
                    }
                }
                $return['premio_tarifario_geral_coberturas_adicionais'] = $premio_tarifario_geral_coberturas_adicionais;
            }

            return $return;
        } catch (Exception $e) {
            return $e->getMessage();
        }
    }

    public function apicorretorescoberturastaxasAction()
    {
        $this->isAjax();

        try {
            $cotacao = (new Seguro_Service_Cotacao())->getById((int)$this->getRequest()->getParam('id_cotacao'));

            if (empty($cotacao)) {
                throw new Zend_Controller_Action_Exception('Cotação não encontrada.', 204);
            }

            $this->params = $cotacao->toArray();
            $this->view->coberturas = (new Seguro_Model_Cotacoes())->coberturas($this->params['id_produto']);
            $this->view->agrupamento = $this->getGrupo();
            $this->view->atributos = $this->getValorAtributos();

            $coberturasIndexadas = [];
            $taxas = $this->getTaxas([
                'tv.id as id_taxa', 'tv.vl_taxa', 'tv.vl_franquia', 'tv.id_cobertura'
                , 'pc.ds_nome_cobertura as nome_cobertura'
            ]);
            $taxasAgrupadasCobertura = [];

            foreach ($this->view->coberturas as $cobertura) {
                $coberturasIndexadas[$cobertura['id_cobertura']] = $cobertura;
            }

            foreach ($taxas as $taxa) {
                $indicePrimario = $coberturasIndexadas[$taxa['id_cobertura']]['fl_cobertura_principal']
                    ? 'principal'
                    : 'adicional';
                $taxasAgrupadasCobertura[$indicePrimario][$taxa['id_cobertura']][] = $taxa;
            }

            $comissoesProduto = !empty($this->view->atributos['PROD_VALOR_MIN_MAX_RANGE_COMISSAO'])
                ? explode(':', $this->view->atributos['PROD_VALOR_MIN_MAX_RANGE_COMISSAO'])
                : [];

            foreach ($comissoesProduto as $comissao) {
                $this->_return['comissao'][] = $comissao;
            }

            $this->_return['comissao'] = array_unique($this->_return['comissao']);
            $this->_return['coberturas'] = $taxasAgrupadasCobertura;

            unset($this->_return['erro'], $this->_return['mensagem']);
        } catch (Exception $erro) {
            $this->_return['erro'] = true;
            $this->_return['mensagem'] = $erro->getMessage();
        }

        $this->getResponse()->setBody(Zend_Json::encode($this->_return));
    }

    public function apicorretorescalcularAction()
    {
        $this->isAjax();

        try {
            /**
             * Esta foi a forma encontrada para receber os dados da API dos corretores, pois via getParams
             * ficava incorreto o array de taxas
             */
            $parametros = json_decode($this->getRequest()->getRawBody(), true);
            // Comentar a linha acima e descomentar abaixo, caso queira debuggar pelo AgroNet
//            $parametros = $this->getRequest()->getParams();
            $serviceCotacao = new Seguro_Service_Cotacao();
            $idCotacao = (int)$parametros['id_cotacao'];
            $cotacao = $serviceCotacao->getById($idCotacao);

            if (empty($cotacao)) {
                throw new Zend_Controller_Action_Exception('Cotação não encontrada.', 204);
            }

            $this->getRequest()->setParams([
                'module' => 'seguro',
                'controller' => 'cotacao',
                'action' => 'calcular',
                'cpf_cnpj' => $cotacao['cpf_cnpj'],
                'id_municipio' => $cotacao['id_municipio'],
                'id_estado' => $cotacao['id_estado'],
                'id_produto' => $cotacao['id_produto'],
                'id_usuario' => $cotacao['id_usuario_criacao'],
                'vl_nova_comissao' => $parametros['comissao'],
                'vl_comissao_original' => $parametros['comissao'],
            ]);

            /**
             * Chamada action que preenche as informações necessárias para utilização aqui, armazenando as propriedades
             * em $this->view
             */
            $this->coberturasAction();

            $coberturasIndexadas = $taxasIndexadas = [];
            $coberturasAdicionais = $valorTaxaPrincipal = "";
            $franquia = $lmga = null;
            $isPg = $this->atributos['PROD_PRODUCAO_GARANTIDA'];

            foreach ($this->view->coberturas as $cobertura) {
                $coberturasIndexadas[$cobertura['id_cobertura']] = $cobertura;
            }

            foreach ($this->view->taxas as $taxa) {
                $taxasIndexadas[$taxa['id']] = $taxa;
            }

            foreach ($parametros['taxas'] as $taxa) {
                $taxaAtual = $taxasIndexadas[$taxa['id_taxa']];

                if (!$coberturasIndexadas[$taxaAtual['id_cobertura']]['fl_cobertura_principal']) {
                    continue;
                }

                $franquia = $taxaAtual['vl_franquia'];

                $valorTaxaPrincipal = "{$taxaAtual['vl_taxa']}#{$taxa['id_taxa']}";
                $valorTaxaPrincipal .= "#{$taxaAtual['vl_percentual_subvencao_federal']}#{$taxaAtual['vl_pg']}";
                $this->getRequest()->setParam('taxa', $valorTaxaPrincipal);
                $this->getRequest()->setParam('vl_taxa', $taxaAtual['vl_taxa']);
            }

            /**
             * Foi separada a lógica entre cobertura principal e adicional, neste primeiro momento, pois quando a
             * cobertura adicional é relacionada, ela deve enviar os valores igual a da principal. Como não há garantia
             * da ordem que as taxas serão enviadas, foi feita essa lógica de percorrer 2x as taxa
             * Me perdoem ;( (e depois de perdoar, façam melhor :D)
             */
            foreach ($parametros['taxas'] as $taxa) {
                $taxaAtual = $taxasIndexadas[$taxa['id_taxa']];

                if ($coberturasIndexadas[$taxaAtual['id_cobertura']]['fl_cobertura_principal']) {
                    continue;
                }

                $valorCoberturaAdicional = "{$taxaAtual['id_cobertura']}#{$taxaAtual['vl_taxa']}#{$taxa['id_taxa']}";
                $valorCoberturaAdicional .= "#{$taxaAtual['vl_percentual_subvencao_federal']}#{$taxaAtual['vl_pg']}--";

                if ($coberturasIndexadas[$taxaAtual['id_cobertura']]['fl_taxa_relacionada']) {
                    $valorCoberturaAdicional = "{$taxaAtual['id_cobertura']}#{$valorTaxaPrincipal}--";
                }

                $coberturasAdicionais .= $valorCoberturaAdicional;
            }

            $this->getRequest()->setParam('coberturas', $coberturasAdicionais);

            $unidadesCotacao = $serviceCotacao->getUnidades($idCotacao);
            $this->getRequest()->setParam('unidades', $unidadesCotacao);

            foreach ($unidadesCotacao as $unidade) {
                $produtividade = $isPg ? $franquia * ($unidade['produtividade'] / 100) : $unidade['produtividade'];
                $lmga = ($unidade['area'] * $produtividade * $unidade['tonelada']) + $lmga;
            }

            $this->getRequest()->setParam('lmga_parcial', $lmga);

            $this->calcularAction();

            $this->_return['premio_tarifario'] = $this->view->retornoCalculo['vl_premio'];
            $this->_return['calculo_com_subsidio'] = [
                'lmga' => $this->view->retornoCalculo['lmga_parcial'],
                'premio_liquido' => $this->view->retornoCalculo['premio_geral'],
                'valor_subvencao_federal' => $this->view->retornoCalculo['vl_subvencao_federal'],
                'percentual_subvencao_federal' => $this->view->retornoCalculo['vl_percentual_subvencao_federal'],
                'valor_subvencao_estadual' => $this->view->retornoCalculo['vl_subvencao_estadual'],
                'percentual_subvencao_estadual' => $this->view->retornoCalculo['vl_percentual_subvencao_estadual'],
                'valor_produtor' => $this->view->retornoCalculo['vl_produtor_geral'],
            ];
            $this->_return['calculo_sem_subsidio'] = [
                'lmga' => $this->view->retornoCalculo['lmga_parcial'],
                'premio_liquido' => $this->view->retornoCalculo['premio_geral'],
                'valor_produtor' => $this->view->retornoCalculo['premio_geral'],
            ];

            //Coberturas adicionais
            foreach ($this->view->retornoCalculo['return'] as $retornoCoberturaAdicional) {
                if (!isset($retornoCoberturaAdicional['id_cobertura'])) {
                    continue;
                }

                $this->_return['calculo_coberturas_adicionais'][$retornoCoberturaAdicional['id_cobertura']] = [
                    'cobertura' => $retornoCoberturaAdicional['nome_cobertura'],
                    'valor_franquia' => $retornoCoberturaAdicional['mostra_franquia'],
                    'valor_taxa' => $retornoCoberturaAdicional['vl_taxa'],
                    'valor_premio' => $retornoCoberturaAdicional['premio_tarifario'],
                ];
            }

            unset($this->_return['erro'], $this->_return['mensagem']);
        } catch (\Exception $erro) {
            $this->_return['erro'] = true;
            $this->_return['mensagem'] = $erro->getMessage();
        }

        $this->getResponse()->setBody(Zend_Json::encode($this->_return));
    }

    public function cotacaocompletaAction()
    {
        $this->isAjax();

        try {
            if (!Agro_Util::checkPermission('seguro:cotacao:cotacaocompleta')) {
                throw new Zend_Exception('Sem permissão de acesso a ação.', 403);
            }

            $this->params = $this->getRequest()->getParams();

            if (!isset($this->params['id_produto'])) {
                $this->params = json_decode($this->getRequest()->getRawBody(), true);
            }

            Seguro_Validator_CotacaoCompleta::temParametrosObrigatorios($this->params);

            $produto = (new Produto_Model_Produtos())->find($this->params['id_produto'])->current();

            if (empty($produto)) {
                throw new Zend_Controller_Action_Exception('Produto não encontrado.', 204);
            }

            $cep = new Agro_Cep();
            $cep->setUF($this->params['estado']);
            $cep->setLocalidade($this->params['municipio']);
            $cep->setSize(1);
            $cep->getCepInfo();

            $dadosMunicipio = $cep->currentItem();

            if (empty($dadosMunicipio)) {
                throw new Zend_Exception('Município não encontrado.', 404);
            }

            $this->_return['parametros'] = $this->params;
            $this->_return['nome_produto'] = $produto['ds_nome_produto'];
            $this->_return['id_usuario'] = $this->_return['parametros']['id_usuario'];
            unset(
                $this->_return['parametros']['id_usuario'],
                $this->_return['parametros']['calcular_somente_condicao_todas_coberturas']
            );

            $this->params['id_corretor'] = $this->params['id_usuario'];

            if (Sistema_Service_Preposto::isPreposto()) {
                $this->params['id_preposto'] = $this->params['id_usuario'];
            }

            $habilitado = (new Produto_Model_Habilitacoes())->getHabilitacoesEstados(
                $this->params, $dadosMunicipio['id_estado']
            );

            if (
                empty($habilitado)
                || (
                    !in_array($dadosMunicipio['id_municipio'], $habilitado[$dadosMunicipio['id_estado']]['municipios'])
                    && !empty($habilitado[$dadosMunicipio['id_estado']]['municipios'])
                )
            ) {
                throw new Zend_Exception("Usuário sem habilitação para o Município/Estado informado.", 404);
            }

            if (
                !(new Comercializacao_Model_Comercializacoes())->checkComercializacao(
                    (int)$this->params['id_produto'],
                    $dadosMunicipio['id_estado'],
                    $dadosMunicipio['id_municipio'],
                    $this->params['cpf_cnpj']
                )
            ) {
                throw new Zend_Exception(
                    "Não há uma comercialização cadastrada para o Município/Estado informado.",
                    404
                );
            }

            $this->params['id_municipio'] = $dadosMunicipio['id_municipio'];
            $this->params['id_estado'] = $dadosMunicipio['id_estado'];
            $this->getRequest()->setParam('id_municipio', $this->params['id_municipio']);
            $this->getRequest()->setParam('id_produto', $this->params['id_produto']);

            $this->view->atributos = $this->getValorAtributos();
            $this->view->agrupamento = $this->getGrupo();
            $this->view->taxas = $this->getTaxas([
                'tv.vl_taxa ', 'tv.vl_franquia', 'tv.id_cobertura', 'tv.vl_percentual_subvencao_federal'
                , 'pc.ds_nome_cobertura', 'ppc.fl_cobertura_principal', 'tv.id as id_taxa', 'cta.vl_comissao'
            ]);
            $this->view->coberturas = $this->getModel()->coberturas($this->params['id_produto']);
            $coberturasIndexadas = [];

            foreach ($this->view->coberturas as $cobertura) {
                $coberturasIndexadas[$cobertura['id_cobertura']] = $cobertura;
            }

            $cotacaoService = new Seguro_Service_Cotacao();
            $taxasOrganizadasCalculo = $cotacaoService->organizarTaxasCoberturas(
                $this->view->taxas,
                $this->params['calcular_somente_condicao_todas_coberturas']
            );

            $modelTipos = new Produto_Model_Tipos();
            $modelProponentes = new Seguro_Model_Proponentes();
            $proponente = $modelProponentes->getProponente($this->params['cpf_cnpj']);
            $produtividadeGarantida = $this->view->atributos['PROD_PRODUCAO_GARANTIDA'];
            $valorProdutividadeBase = 0;
            $comissaoOriginal = !empty($this->view->atributos['PROD_VALOR_MIN_MAX_RANGE_COMISSAO'])
                ? current(explode(':', $this->view->atributos['PROD_VALOR_MIN_MAX_RANGE_COMISSAO']))
                : 5;
            $comissaoAlterada = (float)$comissaoOriginal !== (float)$this->params['comissao'];

            foreach ($taxasOrganizadasCalculo as $taxaCalculo) {
                $coberturasAdicionais = '';
                $retornoCalculos = [];
                $taxaCoberturaPrincipal = $taxaCalculo['cobertura_principal'];
                $valorPremioTarifarioGeral = $valorSubvencaoEstadual = $valorPercentualSubvencaoEstadual = $lmga = 0;
                $franquia = $taxaCoberturaPrincipal['vl_franquia'];
                $retornoCalculoLmga = $cotacaoService->calcularLmga(
                    $this->params['unidades'],
                    $produtividadeGarantida,
                    $this->view->agrupamento['vl_produtividade_estimada'],
                    $franquia
                );
                $lmga += $retornoCalculoLmga['lmga'];
                $valorProdutividadeBase = $retornoCalculoLmga['valor_produtividade_base'];

                /**
                 * Gambiarra necessária para utilização do método calculacoberturasadicionais
                 */
                foreach ($taxaCalculo['coberturas_adicionais'] as $taxa) {
                    $valorCoberturaAdicional = "{$taxa['id_cobertura']}#{$taxa['vl_taxa']}#{$taxa['id_taxa']}";
                    $valorCoberturaAdicional .= "#{$taxa['vl_percentual_subvencao_federal']}#{$taxa['vl_pg']}--";

                    if ($coberturasIndexadas[$taxa['id_cobertura']]['fl_taxa_relacionada']) {
                        $valorCoberturaAdicional = "{$taxa['id_cobertura']}#{$taxaCoberturaPrincipal['vl_taxa']}";
                        $valorCoberturaAdicional .= "#{$taxaCoberturaPrincipal['id_taxa']}";
                        $valorCoberturaAdicional .= "#{$taxaCoberturaPrincipal['vl_percentual_subvencao_federal']}";
                        $valorCoberturaAdicional .= "#{$taxaCoberturaPrincipal['vl_pg']}--";
                    }

                    $coberturasAdicionais .= $valorCoberturaAdicional;
                }

                $this->getRequest()->setParam('coberturas', $coberturasAdicionais);
                $this->getRequest()->setParam('vl_nova_comissao', $this->params['comissao']);
                $this->getRequest()->setParam('vl_comissao_original', $comissaoOriginal);

                $calculoCoberturasAdicionais = $this->calculacoberturasadicionais(
                    false,
                    $comissaoAlterada ? $this->params['franquia_nivel_cobertura'] : null,
                    number_format($lmga, 2, ',', '.')
                );

                foreach ($calculoCoberturasAdicionais as $cobertura) {
                    if (empty($cobertura['id_cobertura'])) {
                        continue;
                    }

                    $valorPremioTarifarioGeral += $lmga * ($cobertura['vl_taxa'] / 100);
                    $retornoCalculos['coberturas_adicionais'][] = [
                        'nome_cobertura' => $cobertura['nome_cobertura'],
                        'premio_adicional' => $cobertura['premio_tarifario'],
                        'taxa' => $cobertura['vl_taxa'],
                    ];
                }

                $valorPremio = Agro_Util::round($lmga * ($taxaCoberturaPrincipal['vl_taxa'] / 100));
                $valoresComissao = [
                    'vl_nova_comissao' => $this->params['comissao'],
                    'vl_comissao_original' => $comissaoOriginal,
                    'valorComissaoAdicional' => null
                ];

                /**
                 * Quando a comissão é diferente da original, é necessário recalcular o valor do prêmio e taxa
                 */
                if ($comissaoAlterada) {
                    $retornoCalculo = Agro_Regras::RN_CALC_07(
                        $lmga,
                        $taxaCalculo['cobertura_principal']['vl_taxa'],
                        $valoresComissao,
                        $this->params['id_produto']
                    );

                    $valorPremio = Agro_Util::formatCurrencyDb($retornoCalculo['premio']);
                    $taxaCalculo['cobertura_principal']['vl_taxa'] = $retornoCalculo['taxa'];
                }

                $valorPremioLiquido = $valorPremioTarifarioGeral + $valorPremio;
                $valoresSubvencaoFederal = $this->calcularSubvencaoFederal(
                    $modelProponentes,
                    $proponente,
                    $valorPremioLiquido
                );

                $valorSubvencaoFederal = str_replace(
                    array('.', ','),
                    array('', '.'),
                    $valoresSubvencaoFederal['vl_subvencao_federal']
                );
                $valorPercentualSubvencaoFederal = $valoresSubvencaoFederal['vl_percentual_subvencao_federal'];

                if (in_array((int)$this->params['id_estado'], Sistema_Enum_Estado::idsEstadosSubvencaoEstadual())) {
                    $valoresSubvencaoEstadual = $this->calcularSubvencaoEstadual(
                        $valorPremioLiquido,
                        $this->view->atributos['PROD_CUSTO_APOLICE'],
                        $this->params['id_estado'],
                        $modelTipos->getTipoViaIdProduto($this->params['id_produto']),
                        $taxaCalculo['id_taxa'],
                        $proponente,
                        $modelProponentes,
                        $this->view->atributos
                    );

                    $valorSubvencaoEstadual = str_replace(
                        array('.', ','),
                        array('', '.'),
                        $valoresSubvencaoEstadual['vl_subvencao_estadual']
                    );

                    $valorPercentualSubvencaoEstadual = $valoresSubvencaoEstadual['vl_percentual_subvencao_estadual'];
                }

                $retornoCalculos['cobertura_principal'] = [
                    'nome_cobertura' => $taxaCalculo['cobertura_principal']['ds_nome_cobertura'],
                    'premio_tarifario' => number_format($valorPremio, 2, ',', '.'),
                    'taxa' => $taxaCalculo['cobertura_principal']['vl_taxa'],
                ];

                $valorComSubsidio = $valorPremioLiquido - $valorSubvencaoEstadual - $valorSubvencaoFederal;

                $retornoCalculos['comissao'] = $taxaCalculo['cobertura_principal']['vl_comissao'];
                $retornoCalculos['lmga'] = number_format($lmga, 2, ',', '.');
                $retornoCalculos['valor_premio_liquido'] = number_format($valorPremioLiquido, 2, ',', '.');
                $retornoCalculos['percentual_subvencao_estadual'] = number_format($valorPercentualSubvencaoEstadual, 2);
                $retornoCalculos['valor_subvencao_estadual'] = number_format($valorSubvencaoEstadual, 2, ',', '.');
                $retornoCalculos['percentual_subvencao_federal'] = number_format($valorPercentualSubvencaoFederal, 2);
                $retornoCalculos['valor_subvencao_federal'] = number_format($valorSubvencaoFederal, 2, ',', '.');
                $retornoCalculos['valor_com_subsidio'] = number_format($valorComSubsidio, 2, ',', '.');

                $this->_return['calculo'][] = $retornoCalculos;
            }

            if ($produtividadeGarantida) {
                $this->_return['produtividadeBaseCalculo'] = $valorProdutividadeBase;
            }

            $row = (new Seguro_Model_CotacoesApi())->save(
                ['ds_calculos' => json_encode(['calculo' => $this->_return])]
            );

            if (!$row) {
                throw new Zend_Exception('Erro ao salvar a cotação.', 422);
            }

            $this->_return['id'] = $row->id;
        } catch (Throwable $erro) {
            $this->_return['erro'] = true;
            $this->_return['code'] = !empty($erro->getCode()) ? $erro->getCode() : 400;
            $this->_return['mensagem'] = $erro->getMessage();
        }

        $this->getResponse()->setBody(Zend_Json::encode($this->_return));
    }
}

?>