<?php

abstract class Agro_Db_Table_Propostas extends Agro_Db_Table_Abstract {
	protected $_rowClass = 'Agro_Db_Table_Row_Proposta';
	protected $_schema = 'seguro';
	protected $_name = 'propostas';
	protected $_primary = 'id';
	public $_columnExcel = array(
		'id_proposta_mae' => 'Proposta',
		'id_proposta_mae_completo' => 'Proposta Completo',
		'nr_apolice' => 'Apolice',
		'ds_nome_proponente' => 'Proponente',
		'cpf_cnpj' => 'CPF/CNPJ',
		'ds_nome_safra' => 'Safra',
		'ds_nome_abreviado' => 'Produto',
		'dt_vigencia_inicio' => 'Inicio Vigencia',
		'ds_sigla' => 'UF',
		'ds_nome_municipio' => 'Município',
		'ds_nome_fantasia' => 'Corretor',
		'ds_nome_usuario' => 'Digitador',
		'cd_status' => 'Status',
		'dt_transmissao' => 'Dt Transmissão',
		'dt_aceitacao' => 'Prazo de Aceitação do Seguro',
		'id_secao' => 'Seção',
		'fl_restricao' => 'RT'
	);

    /**
     * Monta o SQL que sera usado na listagem de propostas
     * @param array $where
     * @return Zend_Db_Select|Zend_Db_Table_Select
     */
	public function getData(array $where)
    {
        $this->_db->query("SELECT seguro.sumario_parcelas(0);");

        $subselect = $this->select()->setIntegrityCheck(false);
        $subselect->from('seguro.propostas', "id as id_proposta, to_char(dt_transmissao, 'DD/MM/YYYY HH24:MI:SS') as dt_transmissao");

        $select = $this->select()->setIntegrityCheck(false);
        $select->from(array('spe' => 'seguro.propostas_endosso'), 'spe.fl_proposta_vigente');
        $select->join(array('spr' => 'seguro.propostas'), 'spr.id = spe.id_proposta', array('id', 'id_endosso'
        , 'id_status'
        , 'spr.dt_vigencia_inicio'
        , 'id_usuario_criacao'
        , 'id_produto'
        , 'ds_status_seguradora'
        , 'nr_digito_verificador'
        , 'nr_apolice'
        , 'ds_identificador_seguradora'
        , 'id_versao'
        , 'seguro.nr_endosso(spr.id, spr.id_endosso) as nr_endosso'
        , 'id_proposta_mae'
        , 'id_proposta_endossada'
        , 'pat.valor_subvencao_federal'
        , "to_char(spr.dt_transmissao + interval '25 day', 'DD/MM/YYYY') AS dt_aceitacao"
        , 'seguro.id_proposta_mae_completo(spr.id) as id_proposta_mae_completo'));
        $select->join(array('mae' => 'seguro.propostas'), 'mae.id = spr.id_proposta_mae', 'id_secao');
        $select->joinLeft(array('sps' => 'seguro.propostas_status'), 'sps.id_status = spr.id_status and sps.id_proposta = spr.id and sps.fl_ativo = true', false);
        $select->join(array('spt' => 'seguro.propostas_proponentes'), 'spr.id = spt.id_proposta', array('ds_nome_proponente', 'cpf_cnpj', 'ds_email_proponente'));
        $select->join(array('spro' => 'seguro.proponentes'), 'spro.cpf_cnpj = spt.cpf_cnpj', array('id as id_proponente', "case when spro.fl_restricao = true then 'Sim' else 'Não' end as fl_restricao"));
        $select->join(array('spc' => 'seguro.propostas_corretores'), 'spr.id = spc.id_proposta', false);
        $select->join(array('ppr' => 'produto.produtos'), 'ppr.id = spr.id_produto', array('ds_nome_abreviado', 'ds_nome_produto'));
        $select->join(array('sf' => 'produto.safras'), 'sf.id = ppr.id_safra', array('ds_nome_safra'));
        $select->join(array('spd' => 'seguro.propostas_propriedades'), 'spr.id = spd.id_proposta', array('id_municipio'));
        $select->join(array('smu' => 'sistema.municipios'), 'smu.id = spd.id_municipio', 'ds_nome_municipio');
        $select->join(array('suf' => 'sistema.estados'), 'suf.id = smu.id_estado', 'ds_sigla');
        $select->join(array('scr' => 'sistema.corretores'), 'spc.id_usuario = scr.id_usuario', array('id_usuario as usuario_corretor', 'ds_nome_fantasia'));
        $select->join(array('sst' => 'sistema.status'), 'sst.id = spr.id_status', array('ds_cor', 'ds_chave', 'ds_status', 'cd_status'));
        $select->join(array('pg' => 'produto.produtos_geral'), 'pg.id = ppr.id_produto_geral', false);
        $select->join(array('pcul' => 'produto.culturas'), 'pcul.id = pg.id_cultura', ['pcul.id as id_cultura']);
        $select->joinLeft(array('std' => 'seguro.propostas_status_doc_fisico'), 'std.id_proposta = spr.id and std.fl_ativo=true', false);
        $select->joinLeft(array('sst2' => 'sistema.status'), 'sst2.id = std.id_status', array('ds_status as ds_status_doc_fisico', 'cd_status as cd_status_doc_fisico', 'ds_cor as ds_cor_doc_fisico',));
        $select->join(array('sus' => 'sistema.usuarios'), 'sus.id = spr.id_usuario_criacao', 'ds_nome_usuario');
        $select->join(array('lpt' => $subselect), 'lpt.id_proposta = spr.id_proposta_mae', "dt_transmissao");
        $select->joinLeft(array('spb' => 'seguro.proposta_boletos'), 'spr.id = spb.id_proposta AND spb.nr_parcela=1 and spb.fl_ativo = true and spb.id_versao = spr.id_versao', array('ds_identificador'));
        $select->joinLeft(array('spv' => 'seguro.propostas_versoes'), 'spr.id_versao = spv.id', array('fl_pendente_transmissao', 'ds_nome_arquivo as digitalizacao'));
        $select->joinLeft(array('speo' => 'seguro.propostas_endosso_opcoes'), 'speo.id_proposta = spr.id', false);
        $select->joinLeft(array('ste' => 'seguro.tipo_endosso'), 'speo.id_endosso_opcao = ste.id', array('ds_tipo_endosso', 'ds_tipo'));
        $select->joinLeft(array('pat' => 'sumario_parcelas'), 'pat.id_endosso = spr.id_endosso', array('valor_subvencao_federal'));
        $select->joinLeft(array('sbda' => 'seguro.bloqueio_download_apolice'), 'sbda.id_proposta = spr.id_proposta_mae', ['id_proposta as id_proposta_bloqueio_download_apolice']);

        $select->where('sst.ds_chave <> ?', 'PROPOSTA_INCOMPLETA');
        $select->where('sst.ds_chave <> ?', 'ENDOSSO_INCOMPLETO');
        $select->where('sst.ds_chave <> ?', Seguro_Model_Propostas::DS_CHAVE_SOLICITACAO_ENDOSSO);
        $select->where('sst.ds_chave <> ?', Seguro_Model_Propostas::DS_CHAVE_SOLICITACAO_CANCELADA);

        if (Zend_Auth::getInstance()->getIdentity()->ds_chave === 'SEGURADORA_ESSOR') {
            $select->where('ppr.id_safra >= 16');
        }
        if (Zend_Auth::getInstance()->getIdentity()->ds_chave === 'SEGURADORA') {
            $select->where('ppr.id_safra < 16');
        }

        $this->getWhere($select, $where);

        if ($this->_order) {
            $select->order($this->_order);
        } else {
            $select->order('spr.id');
        }

        return $select;
    }

    /**
     * Altera o status da proposta
     * @param $data
     * @param $chave
     * @param $id_endosso
     * @param $fl_atualiza_versao
     * @return false|string|void
     * @throws Zend_Db_Adapter_Exception
     * @throws Zend_Db_Table_Exception
     */
	public function changeStatus($data, $chave, $id_endosso=false, $fl_atualiza_versao=false)
    {
        $row = $this->find($data['id_proposta'])->current();
		$idUsuario = !empty($data['id_usuario']) ? $data['id_usuario'] : $this->_user->id;

        if (empty($row)) {
            return false;
        }

        // se o novo status for igual ao atual, nao insere novo registro (somente para orcamento de endosso)
        if ($row->id_status == 162 && ($row->id_status == $this->getIdStatus($chave))) {
            $this->_db->update(
                'seguro.propostas_status',
                array('fl_ativo' => 0, 'id_usuario_alteracao' => $idUsuario),
                "id_proposta = {$data['id_proposta']}"
            );
        } else {
            $row->id_status = $this->getIdStatus($chave);

            //insere novo historico na tabela propostas_status
            $this->_db->update(
                'seguro.propostas_status',
                array('fl_ativo' => 0, 'id_usuario_alteracao' => $idUsuario),
                "id_proposta = {$data['id_proposta']}"
            );
            $this->_db->insert('seguro.propostas_status', array(
                'id_status' => $row->id_status,
                'id_proposta' => $data['id_proposta'],
                'ds_observacao' => $data['ds_observacao'],
                'id_usuario_criacao' => $idUsuario,
                'fl_ativo' => '1'
            ));

            if (!$row->save()) {
                return false;
            }

			//Vincula o contrato de resseguro com a proposta
			if (in_array($chave, [Seguro_Model_Propostas::DS_CHAVE_APOLICE_EMITIDA, Seguro_Model_Propostas::DS_CHAVE_APOLICE_CANCELADA])) {
				(new Seguro_Model_PropostasContratosResseguro())->vincularContrato($data['id_proposta']);
			}

            //atualiza status da proposta
            if ($fl_atualiza_versao) {
                $this->_db->update(
                    'seguro.propostas_versoes',
                    array(
                        'fl_pendente_transmissao' => 0,
                        'id_usuario_alteracao' => $this->_user->id,
                        'dt_alteracao' => 'now()'
                    ),
                    "id_proposta = {$data['id_proposta']}"
                );
            }

            return $this->getLastStatus($data['id_proposta']);
        }
    }

    /**
     * Grava log com o resultado da transmissao para seguradora
     * @param array $data
     * @return bool
     * @throws Zend_Db_Adapter_Exception
     * @throws Zend_Db_Table_Exception
     */
	public function gravaLogTransmissao(array $data) {
	    $Row = $this->find($data['id_proposta'])->current();

		if($this->_db->insert('log.propostas_transmissao', array(
			'id_proposta'         => $data['id_proposta'],
			'ds_retorno'          => $data['ds_retorno'],
			'fl_sucesso'          => $data['fl_sucesso'],
			'ds_xml_transmissao'  => $data['ds_xml_transmissao'],
			'ds_tipo_transmissao' => $data['ds_tipo_transmissao'],
			'id_versao'           => $Row->id_versao,
			'id_status'           => $Row->id_status,
			'id_usuario_criacao'  => $this->_user->id,
			'dt_envio'            => $data['dt_envio'],
			'dt_retorno'          => $data['dt_retorno']
		))){
			return true;
		}

		return false;
	}

	/**
	 * Grava solicitação de consulta ao CADIN
	 * @param unknown_type $data
	 * @param unknown_type $chave
	 */
	public function gravaConsultaCadin($idProposta, $fl_informacoes_modificadas=false) {

	    $ModelPropostas = new Seguro_Model_Propostas();
	    $Proposta       = $ModelPropostas->find($idProposta)->current();

	    // Para cada versão gerada, verifica se a proposta possui subvencao.
	    // Se possuir, grava a solicitação de uma nova consulta ao cadin
        if($Proposta->subvencao_federal() > 0 || $Proposta->subvencao_estadual() > 0){

            $fl_solicita_consulta = false;

            // Se informaçoes chave da proposta foram modificadas, uma nova consulta deve ser consultada
            if($fl_informacoes_modificadas){
                $fl_solicita_consulta = true;
            } else {
                // verifica se já existe uma solicitação de consulta pendente, senão, insere uma nova
                $consultaPendente = $this->getDefaultAdapter()->fetchRow("select count(*) as count_consulta from seguro.propostas_consulta_cadin where fl_solicitacao_pendente='t' and fl_ativo='t' and id_proposta = {$idProposta}");
                if($consultaPendente['count_consulta'] <= 0){
                    $fl_solicita_consulta = true;
                }

                // verifica se já existe uma consulta aprovada. Se sim, cancela a inserção de uma nova
                $consultaPendente = $this->getDefaultAdapter()->fetchRow("select count(*) as count_consulta from seguro.propostas_consulta_cadin where fl_sucesso='t' and fl_solicitacao_pendente='f' and id_proposta = {$idProposta}");
                if($consultaPendente['count_consulta'] > 0){
                	$fl_solicita_consulta = false;
                }

            }

        } else {
            $this->cancelaConsultaCadin($idProposta);
        }

	    // Se não existe, cria uma consulta nova
	    if($fl_solicita_consulta){

	        $this->_db->update('seguro.propostas_consulta_cadin', array('id_usuario_alteracao' => $this->_user->id, 'dt_alteracao' => 'now()', 'fl_ativo' => 'f', 'fl_retorno_pendente' => 'f'), "id_proposta = {$idProposta}");
	        $this->_db->update('seguro.propostas_versoes', array('id_usuario_alteracao' => $this->_user->id, 'dt_alteracao' => 'now()', 'fl_pendente_transmissao' => 'f'), "id = {$Proposta->id_versao}");

    	    $this->_db->insert('seguro.propostas_consulta_cadin', array(
    	            'id_proposta'             => $idProposta,
    	            'ds_retorno'              => '',
    	            'fl_sucesso'              => 'f',
    	            'fl_solicitacao_pendente' => 't',
    	            'ds_xml_transmissao'      => '',
    	            'id_versao'               => $Proposta->id_versao,
    	            'id_status'               => $Proposta->id_status,
    	            'id_usuario_criacao'      => $this->_user->id
    	    ));
	    }
	    return true;
	}

	/**
	 * Cancelas consultas pendentes ao cadin
	 * @param unknown_type $data
	 * @param unknown_type $chave
	 */
	public function cancelaConsultaCadin($idProposta) {
	    $this->_db->update('seguro.propostas_consulta_cadin', array('id_usuario_alteracao' => $this->_user->id, 'dt_alteracao' => 'now()', 'fl_ativo' => 'f', 'fl_solicitacao_pendente' => 'f', 'fl_retorno_pendente' => 'f'), "id_proposta = {$idProposta}");
	    return true;
	}

	/**
	 * Re-solicita consulta ao Cadin de proposta que já está na lista de retorno
	 * @param unknown_type $data
	 * @param unknown_type $chave
	 */
	public function novaConsultaCadin($idProposta) {
		$ultimaConsulta = $this->getDefaultAdapter()->fetchRow("select max(id) as id_consulta from seguro.propostas_consulta_cadin where fl_ativo='t' and id_proposta = {$idProposta}");
		$this->_db->update('seguro.propostas_consulta_cadin', array('id_usuario_alteracao' => $this->_user->id, 'dt_alteracao' => 'now()', 'fl_solicitacao_pendente' => 't', 'fl_retorno_pendente' => 'f', 'ds_retorno' => ''), "id = {$ultimaConsulta['id_consulta']}");
		return true;
	}

	/**
	 * Atualiza consulta ao CADIN
	 * @param unknown_type $data
	 * @param unknown_type $chave
	 */
	public function atualizaConsultaCadin($data) {
	    $ultimaConsulta = $this->getDefaultAdapter()->fetchRow("select max(id) as id_consulta from seguro.propostas_consulta_cadin where fl_ativo='t' and fl_solicitacao_pendente='t' and id_proposta = {$data['id_proposta']}");
	    $this->_db->update('seguro.propostas_consulta_cadin', array('id_usuario_alteracao' => $this->_user->id, 'dt_alteracao' => 'now()', 'fl_solicitacao_pendente' => 'f', 'fl_retorno_pendente' => 't', 'ds_retorno' => ''), "id = {$ultimaConsulta['id_consulta']}");
	    return true;
	}

	/**
	 * Atualiza retorno consulta ao CADIN
	 * @param unknown_type $data
	 * @param unknown_type $chave
	 */
	public function atualizaRetornoConsultaCadin($data) {

	    $ModelPropostas = new Seguro_Model_Propostas();
	    $Proposta       = $ModelPropostas->get($data['id_proposta']);

	    // Busca a ultima solicitação de consulta cadastrada
	    $ultimaConsulta = $this->getDefaultAdapter()->fetchRow("select max(id) as id_consulta from seguro.propostas_consulta_cadin where fl_ativo='t' and id_proposta = {$data['id_proposta']}");

	    $this->_db->update('seguro.propostas_consulta_cadin', array('id_usuario_alteracao' => $this->_user->id, 'dt_alteracao' => 'now()', 'fl_ativo' => 'f'), "id_proposta = {$data['id_proposta']}");

	    if($data['fl_sucesso'] == 't'){
	        $this->_db->update('seguro.propostas_consulta_cadin', array('id_usuario_alteracao' => $this->_user->id, 'fl_ativo' => 't', 'dt_alteracao' => date('Y-m-d H:i:s'), 'fl_retorno_pendente' => 'f', 'fl_solicitacao_pendente' => 'f', 'fl_sucesso' => 't', 'ds_xml_transmissao' => $data['ds_xml_transmissao'], 'ds_retorno' => $data['ds_retorno'], 'vl_subvencao_federal' => $Proposta->subvencao_federal(), 'vl_subvencao_estadual' => $Proposta->subvencao_estadual()), "id = {$ultimaConsulta['id_consulta']}");
	    } else {
	        $this->_db->update('seguro.propostas_consulta_cadin', array('id_usuario_alteracao' => $this->_user->id, 'fl_ativo' => 't', 'dt_alteracao' => date('Y-m-d H:i:s'), 'fl_retorno_pendente' => 't', 'fl_solicitacao_pendente' => 'f', 'fl_sucesso' => 'f', 'ds_xml_transmissao' => $data['ds_xml_transmissao'], 'ds_retorno' => $data['ds_retorno']), "id = {$ultimaConsulta['id_consulta']}");
	    }

	    return true;
	}

	/**
	 * Busca os valores de subvenção concedidos na ultima consulta feita ao Cadin
	 * @param unknown_type $data
	 * @param unknown_type $chave
	 */
	public function subvencaoConcedida($idProposta) {
	    $subvencaoConcedida = $this->getDefaultAdapter()->fetchRow("select vl_subvencao_estadual, vl_subvencao_federal from seguro.propostas_consulta_cadin where fl_ativo='t' and fl_retorno_pendente='f' and fl_sucesso='t' and id_proposta = {$idProposta}");
	    return $subvencaoConcedida;
	}


	/**
	 * Altera o status da proposta
	 * @param unknown_type $data
	 * @param unknown_type $chave
	 */
	public function getLastStatus($idProposta) {
		return Agro_Db_Table_Abstract::getDefaultAdapter()->fetchOne("select id from seguro.propostas_status where id_proposta = $idProposta and fl_ativo=true limit 1");
	}

	/**
	 * Gera uma versao da proposta
	 *
	 * @param integer $idProposta
	 * @return boolean
	 */
	public function gera_versao($idProposta, $fl_pendente_transmissao='t', $fl_gravar_consulta_cadin='t', $idSeguradora=null) {

	    // Atualiza as versoes anteriores para tirar a pendencia de transmissao
        $this->getDefaultAdapter()->update('seguro.propostas_versoes', array('id_usuario_alteracao' => $this->_user->id, 'dt_alteracao' => 'now()', 'fl_pendente_transmissao' => 'f'), "id_proposta = $idProposta");

		// Busca a ultima versao cadastrada
		$lastVersion = $this->getDefaultAdapter()->fetchRow("select * from seguro.propostas_versoes where id_proposta = $idProposta order by dt_criacao desc limit 1");

		// Insere a Versão
		$this->getDefaultAdapter()->insert('seguro.propostas_versoes', array(
			'id_proposta' => $idProposta,
			'ds_nome_arquivo_subvencao_estadual' => $lastVersion['ds_nome_arquivo_subvencao_estadual'],
			'ds_nome_arquivo_subvencao_federal'  => $lastVersion['ds_nome_arquivo_subvencao_federal'],
		    'fl_pendente_transmissao'            => $fl_pendente_transmissao,
		    'ds_identificador_seguradora'        => $idSeguradora,
			'id_usuario_criacao'                 => Zend_Auth::getInstance()->getIdentity()->id
		));

		// Busca a ultima versao
		$versao = $this->getDefaultAdapter()->fetchOne("select max(id) from seguro.propostas_versoes where id_proposta = $idProposta");

		// Atualiza a proposta
		if ($versao) {
			$this->getDefaultAdapter()->update('seguro.propostas', array('id_usuario_alteracao' => $this->_user->id, 'dt_alteracao' => 'now()', 'id_versao' => $versao), "id = $idProposta");
			return $versao;
		}

		return false;
	}

	/**
	 * Atualiza flag de transmissao para seguradora da versão para true (transmitida)
	 *
	 * @param integer $idProposta
	 * @return boolean
	 */
	public function atualiza_versao($idVersao,$idSeguradora='') {
	    // Atualiza as versoes anteriores para tirar a pendencia de transmissao
	    if($this->getDefaultAdapter()->update('seguro.propostas_versoes', array('fl_pendente_transmissao' => 'f', 'ds_identificador_seguradora' => $idSeguradora), "id = $idVersao")){
	        return true;
	    }

	    return false;
	}

	/**
	 * Atribuiu o identificador da Seguradora à Versao
	 *
	 * @param integer $idProposta
	 * @return boolean
	 */
	public function atualiza_identificador_versao($idVersao,$idIdentificador) {

	    // Atualiza as versoes anteriores para tirar a pendencia de transmissao
	    if($this->getDefaultAdapter()->update('seguro.propostas_versoes', array('id_usuario_alteracao' => $this->_user->id, 'dt_alteracao' => 'now()', 'ds_identificador_seguradora' => $idIdentificador), "id = $idVersao")){
	        return true;
	    }

	    return false;
	}

	/**
	 * Verifica o limite da LMGA
	 *
	 * @param integer $idProposta
	 * @param float $value
	 * @return boolean
	 */
	public function _limiteLmga($idProposta, $value) {
		$total = $value + $this->getDefaultAdapter()->fetchOne("select sum(vl_limite_beneficio) from seguro.propostas_beneficiarios where id_proposta = $idProposta and fl_del = false");
		$lmga = $this->getLmgaProposta((int) $idProposta);

		if ($lmga >= $total) {
			return true;
		} else {
			return false;
		}
	}

        /**
	 * Conta dias entre vigencia fim e vigencia inicio 
	 */
	public function getVigenciaDays($idProposta) {
		$select = $this->select()->setIntegrityCheck(false)->distinct(true)
			->from(array('pr' => 'seguro.propostas'), 'dt_vigencia_fim - dt_vigencia_inicio as total_days')
			->where('pr.id = ?', $idProposta);

		return $this->fetchRow($select);
	}

    public function getLmgaProposta(int $idProposta)
    {
        return $this->getDefaultAdapter()->fetchOne("select vl_lmga from sumario.itens_segurados where id_proposta = {$idProposta}");
    }
}
