<?php

use Cake\Database\Exception\MissingExtensionException;
use Symfony\Component\Config\Exception\FileLocatorFileNotFoundException;
use Symfony\Component\Filesystem\Exception\FileNotFoundException;

require_once 'regulacao/controllers/Lvp001Controller.php';

class Seguro_RotinasController extends Agro_Controller_Action{
	private $update_file_agritask = array();

	public function init() {
		$this->view->title = 'Seguro» Rotinas';

		require_once(APPLICATION_PATH . "/../library/Agro/nusoap/nusoap.php");
		$this->wsdl = "http://ws.nobre.com.br/Emissao.asmx?WSDL";
		$this->client = new nusoap_client($this->wsdl);
	}

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

	public function indexAction(){
		parent::indexAction();
		$this->view->title = 'Seguro» Rotinas» Importar Apólices';
	}

	public function importarboletosAction(){
		$this->view->title = 'Seguro » Rotinas » Consultar Boletos';
		$Model = $this->getModel();
		$rsPropostas = $Model->getBoletosEssor(true);
		$this->view->parcelas_pendentes = count($rsPropostas);
	}

	public function listarboletosAction(){
	    $this->getHelper('ViewRenderer')->setNoRender();
	    $this->getHelper('layout')->disableLayout();
	    $Model = $this->getModel();
	    $boletos = $Model->listarBoletos($this->getRequest()->getParam('mensal'));

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

	public function importarchamadosAction(){
		$this->view->title = 'Seguro » Rotinas » Importar Chamados';

		$responsaveis = (new Sistema_Model_Funcionarios())->getComboAgroBrasil();
		unset($responsaveis[0]);
		$this->view->responsaveis = $responsaveis;
	}

	public function importarparcelasAction(): void
	{
		$this->view->title = 'Seguro » Rotinas » Importar Parcelas';
	}

	public function salvarparcelasAction(): void
	{
		$this->isAjax();

		$retorno = ['mensagem' => 'Parcelas importadas com sucesso!', 'erros' => []];

		try {
			$service = new Seguro_Service_ImportarParcelas();
			$service->executar($_FILES['arquivo']);

			if (!empty($service->getErros())) {
				throw new Exception('Erros encontrados.');
			}

		} catch (Exception $e) {
			$retorno['erros'] = $service->getErros();
			$retorno['mensagem'] = $e->getMessage();
		}

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

	public function subvencaoAction(){
		parent::indexAction();
		$this->view->title = 'Seguro » Rotinas » Importar Confirmação de Subvenção';
	}

	public function secaoAction(){
		parent::indexAction();
		$this->view->title = 'Seguro » Rotinas » Importar Seção';
	}
	
	public function gerakmlAction() {
		$this->view->title .= ' » Gerar Arquivo KML de Propostas';
		$this->view->form = new Seguro_Form_Rotinas();
	}

	public function gerakmlavisoAction() {
		$this->view->title .= ' » Gerar Arquivo KML de Avisos';
		$this->view->form = new Seguro_Form_Rotinas();
	}

	public function geraarquivokmlavisoAction() {
		$this->getHelper('layout')->disableLayout();

		if ($this->getRequest()->isPost()) {
			$this->view->gerar = true;
			$Propostas = new Seguro_Model_Propostas();
			$this->view->dados = $Propostas->getArquivoKMLAviso($this->getRequest()->getParams());
			if (count($this->view->dados) > 0) {
	 			$this->getResponse()->setHeader('Content-Type', 'application/octetstream', true);
				$this->getResponse()->setHeader('Content-Disposition', 'attachment; filename=coordenadas_aviso.kml', true);
				$this->getResponse()->setHeader('Pragma', 'no-cache', true);
				$this->getResponse()->sendResponse();
			} else {
				$this->_redirect('/seguro/rotinas/gerakmlaviso');
			}
		}
	}

	public function geraarquivokmlgeralAction() {
		$this->getHelper('layout')->disableLayout();

		if ($this->getRequest()->isPost()) {
			$this->view->gerar = true;
			$Propostas = new Seguro_Model_Propostas();
			$this->view->dados = $Propostas->getArquivoKMLGeral($this->getRequest()->getParams());
			if ($this->view->dados->count() > 0) {
	 			$this->getResponse()->setHeader('Content-Type', 'application/octetstream', true);
				$this->getResponse()->setHeader('Content-Disposition', 'attachment; filename=coordenadas_geral.kml', true);
				$this->getResponse()->setHeader('Pragma', 'no-cache', true);
				$this->getResponse()->sendResponse();
			} else {
				$this->_redirect('/seguro/rotinas/gerakml');
			}
 		}

	}

	public function geraSalvaXml($msg, $arquivo) {
		$file = fopen(APPLICATION_PATH."/upload_files/xml_transmissao_error/{$arquivo}", "a+");
	    fwrite($file, $msg);
	    fclose($file);
	}

	public function relacionaapolicesAction() {
		$this->getHelper('layout')->disableLayout();
		$this->getHelper('ViewRenderer')->setNoRender();
	
		Agro_Db_Table_Abstract::getDefaultAdapter()->beginTransaction();
		
		$result = array();
		$Adapter = new Zend_File_Transfer_Adapter_Http();
		$Adapter->setDestination(APPLICATION_PATH.'/upload_files/temp/');
		$Adapter->addValidator('Extension', false, array('csv', 'case' => true));
		$file = $Adapter->getFileInfo();
	
		if(!$Adapter->receive($file['apolices']['name'])) {
			$result['status'] = 'Erro a atualizar Propostas!';
		} else {
			$extensao = explode('.',$file['apolices']['name']);
			if($extensao[1] == 'csv'){
				
				//abre o arquivo
				$arquivo = fopen(APPLICATION_PATH.'/upload_files/temp/' . $file['apolices']['name'],"r");
				$linha = 0;
				$Model = $this->getModel();
				
				
				//processa o csv
				while(($dados = fgetcsv($arquivo, 0, ";")) != false){
					//pula a primeira linha pois ã© cabeã§alho
					if($linha != 0){
						$Model->save($dados[0], $dados[1]);
					}
					$linha++;
				}
				
				Agro_Db_Table_Abstract::getDefaultAdapter()->commit();
				$result['status'] = 'Propostas atualizadas com sucesso!';
				
			}else{
				Agro_Db_Table_Abstract::getDefaultAdapter()->rollBack();
				$result['status'] = 'Formato de arquivo inválido!';
			}
		}
	
		$this->getResponse()->setBody(Zend_Json::encode($result));
	}
	
	public function marcarpagoAction(){
		$this->getHelper('ViewRenderer')->setNoRender();
		$this->getHelper('layout')->disableLayout();

		$Model = $this->getModel();

		$identificador = $Model->getIdentificadorBoleto($this->getRequest()->getParam('num_boleto'));
		if($Model->atualizaBoleto($identificador,true)){
		    $result['status'] = 'Boleto atualizado com sucesso!';
		} else {
			$result['status'] = 'Erro ao atualizar boleto';
		}

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

	public function importaboletosarquivoAction(){

		$this->getHelper('ViewRenderer')->setNoRender();
		$this->getHelper('layout')->disableLayout();
		$Model = $this->getModel();

		$soapaction = "http://ws.nobre.com.br/ConsultarPagamentoBoletos";
		$nomeArquivo = time()."_consulta_boletos.txt";

		$Adapter = new Zend_File_Transfer_Adapter_Http();
		$Adapter->setDestination(APPLICATION_PATH.'/upload_files/temp/');
		$file = $Adapter->getFileInfo();

		if(!$Adapter->receive($file['boleto']['name'])) {
			$message['status'] = 'Erro a atualizar boletos!';
		} else {

			$extensao = explode('.',$file['boleto']['name']);
			if($extensao[1] == 'csv'){

				//abre o arquivo
				$arquivo = fopen(APPLICATION_PATH.'/upload_files/temp/' . $file['boleto']['name'],"r");
				$linha = 0;

				while(($dados = fgetcsv($arquivo, 0, ";")) != false){
					if($linha != 0){
						for($i = 0; $i < count($dados); $i++){
							$result[$linha]['id'] = $dados[0];
						}
					}
					$linha++;
				}
	  			fclose($arquivo);

				while(count($result) > 0){
			        $xml = '
			        	<ConsultarPagamentoBoletos xmlns="http://ws.nobre.com.br/">
			              <colecaoIdentificador>';
							foreach($result as $boleto){
								$identificador = $Model->getIdentificadorBoleto($boleto['id']);
								if($identificador){
						        	$xml .= '
						              <Identificador>
						                <descricao>'.$identificador.'</descricao>
						              </Identificador>';
								}
							}
			        $xml .= '
			        	  </colecaoIdentificador>
				        </ConsultarPagamentoBoletos>';

					$mysoapmsg = $this->client->serializeEnvelope($xml);
					$response = $this->client->send($mysoapmsg, $soapaction);

					foreach($response['ConsultarPagamentoBoletosResult']['boletos'] as $key => $identificador){
			        	foreach($identificador as $key => $verificador){
			        		if($verificador['pago'] == 'True'){
			        			$Model->atualizaBoleto($verificador['identificador'],true);
			        		} else {
								$Model->atualizaBoleto($verificador['identificador'],false);
			        		}
			        		$msg = $verificador['identificador']." -> ".$verificador['pago'].chr(13).chr(10);
			        		$message['status'] = 'Consulta a boletos executada com sucesso!';
			        	}
					}
			        $this->geraSalvaXml($mysoapmsg, $nomeArquivo);
			        $this->geraSalvaXml($this->soapClient, 'retorno.txt');
					unset($result);
				}

			}else{
				$message['status'] = 'Somente são aceitos arquivos .csv!';
			}
		}
		$this->getResponse()->setBody(Zend_Json::encode($message));
	}

	public function importachamadosarquivoAction(){
		$this->getHelper('ViewRenderer')->setNoRender();
		$this->getHelper('layout')->disableLayout();
		$Model = new Atendimento_Model_Chamado();

		$Adapter = new Zend_File_Transfer_Adapter_Http();
		$Adapter->setDestination(APPLICATION_PATH.'/upload_files/temp/');
		$file = $Adapter->getFileInfo();

		if(!$Adapter->receive($file['chamados']['name'])) {
			$message['status'] = 'Erro a atualizar boletos!';
		} else {

			$extensao = explode('.',$file['chamados']['name']);
			if($extensao[1] == 'csv'){

				//abre o arquivo
				$arquivo = fopen(APPLICATION_PATH.'/upload_files/temp/' . $file['chamados']['name'],"r");
				$linha = 0;

                $data['id_prioridade']            = 2;
                $data['tp_usuario']               = 'S';
                $data['fl_importacao_automatica'] = true;

                $Model->getAdapter()->beginTransaction();

				while(($dados = fgetcsv($arquivo, 0, ";")) != false){

					if($linha > 0){
						$tipoChamado = explode(" ", $dados[1]);
						$idTipoChamado = $tipoChamado[0];

						$data['id_proposta']     = $dados[0];
						$data['id_tipo_chamado'] = $idTipoChamado;
						$data['ds_descricao']    = mb_detect_encoding($dados[2]) == 'UTF-8' ? $dados[2] : utf8_encode($dados[2]);
                        $data['id_usuario']      = $dados[3];

                        //busca o departamento do tipo de chamado
                        $modelTC = new Atendimento_Model_TipoChamado;
                        $tipoChamado = $modelTC->find($idTipoChamado)->current();
                        $data['id_departamento'] = $tipoChamado->id_departamento;

						if (!$Model->save($data)) {
							$message['status'] = $Model->getMessages();
							$Model->getAdapter()->rollBack();
							break;
						}
					}
					$linha++;
				}
	  			fclose($arquivo);
	  			if (!isset($message['status']) || empty($message['status'])) {
	  				$message['status'] = 'Importação de Chamados executada com sucesso!';
	  				$Model->getAdapter()->commit();
	  			}

			}else{
				$message['status'] = 'Somente são aceitos arquivos .csv!';
			}
		}
		$this->getResponse()->setBody(Zend_Json::encode($message));
	}

	public function consultaparcelasessorAction(){

	    $this->getHelper('ViewRenderer')->setNoRender();
	    $this->getHelper('layout')->disableLayout();

		$params = $this->getRequest()->getParams();
		$ret = ['status' => false, 'message' => 'Proposta não encontrada.'];

	    $modelProposta = new Seguro_Model_Propostas();
	    $proposta = $modelProposta->find($params['id_proposta'])->current();

	    //Se o ds_identificador_seguradora da versão foi passado por parametro, utiliza ele
	    //Senão, usa o ds_identificador_seguradora atual da proposta
	    $dsIdentificadorSeguradora = ($params['ds_identificador_seguradora']) ? $params['ds_identificador_seguradora'] : $proposta->ds_identificador_seguradora;
	    $idVersao = ($params['id_versao']) ? $params['id_versao'] : $proposta->id_versao;
		$nrParcela = ($params['nr_parcela']) ? $params['nr_parcela'] : null;

	    if ($dsIdentificadorSeguradora) {
			$modelPropostaParcelas = new Seguro_Model_PropostasParcelas();
			$ret = $modelPropostaParcelas->consultaParcelasEssor(
				(int) $params['id_proposta'],
				$dsIdentificadorSeguradora,
				(int) $idVersao,
				(int) $nrParcela
			);
	    }

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

	public function removeboletosAction(){

		$this->getHelper('ViewRenderer')->setNoRender();
		$this->getHelper('layout')->disableLayout();

		$ModelProposta = new Seguro_Model_Propostas();
		$Proposta      = $ModelProposta->find($this->getRequest()->getParam('id_proposta'))->current();

		if($this->getRequest()->getParam('id_proposta')){

			$Proposta = new Atendimento_Model_Proposta();
			$rsBoletos = $Proposta->getBoleto($this->getRequest()->getParam('id_proposta'), $this->getRequest()->getParam('id_versao'));

			$retExclusao = false;

			foreach($rsBoletos as $key => $boleto){
                if (file_exists(APPLICATION_PATH . "/upload_files/boletos/{$boleto['documento']}")) {
                    if (!unlink(APPLICATION_PATH . "/upload_files/boletos/{$boleto['documento']}")) {
                        $retExclusao = true;
                    }
                }

                if (file_exists(APPLICATION_PATH . "/upload_files/boletos/{$boleto['documento_parcela']}")) {
                    if (!unlink(APPLICATION_PATH . "/upload_files/boletos/{$boleto['documento_parcela']}")) {
                        $retExclusao = true;
                    }
                }
			}

			if($retExclusao == false){
				$Boleto = new Default_Model_Boleto();
				$Boleto->removeBoletos($this->getRequest()->getParam('id_proposta'), $this->getRequest()->getParam('id_versao'));

				$ret['message'] = 'Boletos excluídos com sucesso.';
				$ret['status'] = true;
			} else {
				$ret['message'] = 'Falha ao excluir boletos. (1)';
				$ret['status'] = false;
			}

		} else {
			$ret['message'] = 'Falha ao excluir boletos. (2)';
			$ret['status'] = false;
		}

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

	//criado para simular o clique da consulta de 3 em 3 min para executar pausadamente
	public function consultaparcelasscriptessorAction() {
		$this->getHelper('ViewRenderer')->setNoRender();
		$this->getHelper('layout')->disableLayout();

		$result['status'] = true;

	    if (APPLICATION_ENV != 'production') {
	    	$client = new nusoap_client(WSDL_DEV, true, false, false, false, false, 3600, 3600);
	    } else {
	    	$client = new nusoap_client(WSDL_PROD, true, false, false, false, false, 3600, 3600);
	    }

	    $Model = $this->getModel();

    	$rsPropostas = $Model->getBoletosEssor(true, $this->getRequest()->getParam('mensal'));

	    if(is_array($rsPropostas) && count($rsPropostas) > 0){

	    	$boletos = array_chunk($rsPropostas, 6000, true); 
	
	    	foreach($boletos as $rs) {

		        foreach($rs as $proposta){ 

		        	$nrParcela = ($proposta['nr_parcela']) ? " nr_parcela = '".$proposta['nr_parcela']."'" : '';

		            if($proposta[id]){

		                //ATUALIZA INFORMACOES DOS BOLETOS
		                $xml        = "<i4proerp><consulta_parcela id_endosso='".$proposta[ds_identificador_seguradora]."' $nrParcela></consulta_parcela></i4proerp>";

		                $mysoapmsg  = $client->serializeEnvelope($xml);
		                $params     = array('Servico' => 'ConsultarParcela', 'conteudoXML' => $mysoapmsg);
		                $result     = $client->call('Executar', array($params));
		                $result_xml = simplexml_load_string(utf8_encode($result['ExecutarResult']), 'SimpleXMLElement', LIBXML_NOCDATA);

		                $Boleto = new Default_Model_Boleto();
		                foreach($result_xml->proposta->parcela as $chave => $parcela){
		                     
		                    $valor_pago = str_replace('.', '', $parcela->Valor_recebido);
		                    $valor_pago = str_replace(',', '.', $valor_pago);
		                    $data_pagamento = (string)$parcela->Data_pagamento;

		                    $Boleto->atualizaPagamentoBoleto(array(
		                            'id_proposta'           => $proposta[id],
		                            'id_versao'             => $proposta[id_versao],
		                            'nu_boleto'             => $parcela->Titulo,
		                            'nr_parcela'            => $parcela->nr_parcela,
		                            'fl_pago'               => $parcela->Pago,
		                            'vl_pago'               => $valor_pago,
		                            'dt_pagamento'          => ($data_pagamento ? $data_pagamento : null)
		                    ));
		                }
		            }
		        }

		        //aguarda 3 minutos para não engasgar servidor Essor.
		        sleep(180);
		    }

	        $ret['message'] = 'Consulta realizada com sucesso!';
	    } else {
	        $ret['message'] = 'Apólices não encontradas!';
	    }

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

	public function consultaparcelasgeralessorAction(){

	    $this->getHelper('ViewRenderer')->setNoRender();
	    $this->getHelper('layout')->disableLayout();

	    $result['status'] = true;

	    if (APPLICATION_ENV != 'production') {
	    	$client = new nusoap_client(WSDL_DEV, true, false, false, false, false, 3600, 3600);
	    } else {
	    	$client = new nusoap_client(WSDL_PROD, true, false, false, false, false, 3600, 3600);
	    }

	    $Model = $this->getModel();

    	$rsPropostas = $Model->getBoletosEssor();

	    if(is_array($rsPropostas) && count($rsPropostas) > 0){

	        foreach($rsPropostas as $proposta){

	        	$nrParcela = ($proposta['nr_parcela']) ? " nr_parcela = '".$proposta['nr_parcela']."'" : '';

	            if($proposta[id]){

	                //ATUALIZA INFORMACOES DOS BOLETOS
	                $xml        = "<i4proerp><consulta_parcela id_endosso='".$proposta[ds_identificador_seguradora]."' $nrParcela></consulta_parcela></i4proerp>";

	                $mysoapmsg  = $client->serializeEnvelope($xml);
	                $params     = array('Servico' => 'ConsultarParcela', 'conteudoXML' => $mysoapmsg);
	                $result     = $client->call('Executar', array($params));
	                $result_xml = simplexml_load_string(utf8_encode($result['ExecutarResult']), 'SimpleXMLElement', LIBXML_NOCDATA);
	                
	                $Boleto = new Default_Model_Boleto();
	                foreach($result_xml->proposta->parcela as $chave => $parcela){
	                     
	                    $valor_pago = str_replace('.', '', $parcela->Valor_recebido);
	                    $valor_pago = str_replace(',', '.', $valor_pago);
	                    $data_pagamento = (string)$parcela->Data_pagamento;

	                    $Boleto->atualizaPagamentoBoleto(array(
	                            'id_proposta'           => $proposta[id],
	                            'id_versao'             => $proposta[id_versao],
	                            'nu_boleto'             => $parcela->Titulo,
	                            'nr_parcela'            => $parcela->nr_parcela,
	                            'fl_pago'               => $parcela->Pago,
	                            'vl_pago'               => $valor_pago,
	                            'dt_pagamento'          => ($data_pagamento ? $data_pagamento : null)
	                    ));
	                }
	            }
	        }
	        $ret['message'] = 'Consulta realizada com sucesso!';
	    } else {
	        $ret['message'] = 'Apólices não encontradas!';
	    }

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

	public function countconsultapendenteAction(){
	    $this->getHelper('ViewRenderer')->setNoRender();
	    $this->getHelper('layout')->disableLayout();

		$Model = $this->getModel();
		$rsPropostas = $Model->getBoletosEssor(true, $this->getRequest()->getParam('mensal'));
		$count = (count($rsPropostas) > 0) ? count($rsPropostas) : '0';

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

	public function vencimentosparcelasAction(){
		$this->view->title = 'Seguro » Rotinas » Alterar Vencimentos Parcelas';
	}

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

		$Adapter = new Zend_File_Transfer_Adapter_Http();
		$Adapter->setDestination(APPLICATION_PATH.'/upload_files/temp/');
		$file = $Adapter->getFileInfo();

		if(!$Adapter->receive($file['file_vencimentos']['name'])) {
			$result['status'] = 'Erro ao atualizar Parcelas!';
		} else {

			$extensao = explode('.',$file['file_vencimentos']['name']);
			if($extensao[1] == 'csv'){
				//abre o arquivo

				$arquivo = fopen(APPLICATION_PATH.'/upload_files/temp/' . $file['file_vencimentos']['name'],"r");
				$linha = 0;
				$Model = $this->getModel();
				//processa o csv
				while(($dados = fgetcsv($arquivo, 0, ";")) != false){
					for($i = 0; $i < count($dados); $i++){
						$result['data'][$linha] = $dados[0];
						$result['parcela'][$linha] = $dados[1];
						$result['proposta'][$linha] = $dados[2];
					}

					if($linha != 0){
						$result['data'][$linha] = Agro_Util::formatDate($result['data'][$linha],Zend_Date::W3C);
						$Model->alteraVencimentosParcelas($result['data'][$linha],$result['parcela'][$linha],$result['proposta'][$linha]);
					}
					$linha++;
				}
				$result['status'] = 'Parcelas atualizadas com sucesso!';
	  			fclose($arquivo);
			}else{
				$result['status'] = 'Formato de arquivo inválido!';
			}
		}

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

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

		$Adapter = new Zend_File_Transfer_Adapter_Http();
		$Adapter->setDestination(APPLICATION_PATH.'/upload_files/temp/');
		$file = $Adapter->getFileInfo();

		if(!$Adapter->receive($file['file_parcelas']['name'])) {
			$result['status'] = 'Erro ao atualizar Parcelas!';
		} else {

			$extensao = explode('.',$file['file_parcelas']['name']);
			if($extensao[1] == 'csv'){
				//abre o arquivo

				$arquivo = fopen(APPLICATION_PATH.'/upload_files/temp/' . $file['file_parcelas']['name'],"r");
				$linha = 0;
				$Model = $this->getModel();
				//processa o csv
				while(($dados = fgetcsv($arquivo, 0, ";")) != false){
					for($i = 0; $i < count($dados); $i++){
						$result['parcela'][$linha] = $dados[0];
						$result['proposta'][$linha] = $dados[1];
					}

					if($linha != 0){
						$result['data'][$linha] = Agro_Util::formatDate($result['data'][$linha],Zend_Date::W3C);
						$Model->marcaParcelasPagas($result['parcela'][$linha],$result['proposta'][$linha]);
					}
					$linha++;
				}
				$result['status'] = 'Parcelas atualizadas com sucesso!';
	  			fclose($arquivo);
			}else{
				$result['status'] = 'Formato de arquivo inválido!';
			}
		}

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

	public function arquivospreviaAction(){}

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

		$Adapter = new Zend_File_Transfer_Adapter_Http();
		$Adapter->setDestination(APPLICATION_PATH.'/upload_files/temp/');
		$file = $Adapter->getFileInfo();

		if(!$Adapter->receive($file['file_arquivos']['name'])) {
			$result['status'] = 'Erro!';
		} else {

			//lê o arquivo csv
			$arquivo = fopen (APPLICATION_PATH.'/upload_files/temp/' . $file['file_arquivos']['name'],"r");
			$propostas = array();
			$count = 0;
			while (($data = fgetcsv ($arquivo, 0, ';')) != false) {
				$num = count($data);

				//organiza o array das propostas, de acordo com o csv
				for ($c=0; $c < $num; $c++) {
					$linha = $data[0];
					$divide = explode(';', $linha);
					$propostas[] = $divide[0];
				}
			}

			//lê o diretório dos arquivos recursivamente
			$listar = new RecursiveDirectoryIterator(APPLICATION_PATH.'/upload_files/laudoprevia/');
			$recursivo = new RecursiveIteratorIterator($listar);
			$arquivos = array();

			//pega o nome dos arquivos
			foreach ($recursivo as $obj) {
				$arquivos[] = $obj->getFileName();
			}

			//percorre pra poder comparar com as propostas do csv e retirar o registro do array de arquivos
			foreach($arquivos as $key => $arquivo){
				$fileName = explode('_', $arquivo);
				foreach($propostas as $proposta){
					if($fileName[0] == $proposta){
						if(copy(APPLICATION_PATH.'/upload_files/laudoprevia/'.$arquivo, PATH_LAUDOS.'/'.$arquivo)){
							$ModelPrevia = new Seguro_Model_Vistoriapreviaempresaarquivos();
							$ModelPrevia->atualizaFlagArquivo($arquivo);
						}
					}
				}
			}

			//depois de montado o array de arquivos, basta copiá-lo e atualizar a flag no banco
			/*foreach($arquivos as $key => $arquivo){
				if(!copy(APPLICATION_PATH.'/upload_files/laudoprevia/'.$arquivo, PATH_LAUDOS.'/'.$arquivo)){
					die('Erro!!');
				}else{
					$ModelPrevia = new Seguro_Model_Vistoriapreviaempresaarquivos();
					$ModelPrevia->atualizaFlagArquivo($arquivo);
				}
			}*/

			//fecha o arquivo
			fclose($arquivo);
			$this->getResponse()->setBody(Zend_Json::encode('Feito!!'));
		}
	}

    /**
     * Lê o arquivo de importação, aplica as validações necessárias e retorna um array com os erros e com os registros
     * válidos.
     * @param string $nomeIndex
     * @return array|Zend_Controller_Response_Abstract|null
     * @throws Zend_File_Transfer_Exception
     */
	private function preparaRegistrosSubvencao(string $nomeIndex)
	{
        $retorno = [
            'erro' => false,
            'mensagem' => 'Importação realizada com sucesso.',
            'erros' => [],
            'total_linhas' => 0,
            'total_registros_importados' => 0,
            'total_registros_erro' => 0
        ];
        $adapter = new Zend_File_Transfer_Adapter_Http();
        $adapter->setDestination(APPLICATION_PATH . '/upload_files/temp/');
        $file = $adapter->getFileInfo();

        if (!$adapter->receive($file[$nomeIndex]['name'])) {
            $retorno['erro'] = true;
            $retorno['mensagem'] = 'Erro ao receber o arquivo de confirmação de Subvenção!';

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

        $extensao = explode('.', $file[$nomeIndex]['name']);

        if (end($extensao) != 'csv') {
            $retorno['erro'] = true;
            $retorno['mensagem'] = 'Formato de arquivo inválido (formato aceito: .csv).';

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

        //abre o arquivo
        $arquivo = fopen(APPLICATION_PATH . '/upload_files/temp/' . $file[$nomeIndex]['name'], "r");
        $totalLinhas = 0;
        $expressao = '/[^0-9]/';

        //processa o csv
        while (($dados = fgetcsv($arquivo, 0, ";")) != false) {
            $totalLinhas++;

            // Valida o cabeçalho
            if ($totalLinhas == 1) {
                if (count($dados) !== 4) {
                    $retorno['erro'] = true;
                    $retorno['mensagem'] = "Importação inválida. O arquivo deve conter 4 colunas com os";
                    $retorno['mensagem'] .= " cabeçalhos/dados.";

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

                $cabecalhoProposta = trim(strtolower($dados[0])) === 'proposta';
                $cabecalhoData = trim(strtolower($dados[1])) === 'data';
                $cabecalhoValor = trim(strtolower($dados[2])) === 'valor';
                $cabecalhoStatus = trim(strtolower(utf8_encode($dados[3]))) === 'status concessão';

                if (!$cabecalhoProposta || !$cabecalhoData || !$cabecalhoValor || !$cabecalhoStatus) {

                    $retorno['erro'] = true;
                    $retorno['mensagem'] = "Cabeçalho do arquivo inválido. A primeira linha deve conter colunas com as";
                    $retorno['mensagem'] .= " seguintes descrições: Proposta, Data, Valor e Status concessão.";

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

                continue;
            }

            $idProposta = trim($dados[0]);
            $dataConcessao = trim($dados[1]);
            $valorSubvencao = trim($dados[2]);
            $statusConcessao = strtoupper(Agro_Util::removeAcentos(trim($dados[3])));

            $stdErro = (object)[
                'id_proposta' => $idProposta,
                'dt_concessao' => $dataConcessao,
                'vl_subvencao' => $valorSubvencao,
                'status_concessao' => $statusConcessao,
                'erro' => '',
                'linha' => $totalLinhas
            ];

            if (empty($idProposta) || empty($statusConcessao)) {
                $retorno['erro'] = true;
                $stdErro->erro = 'Proposta e/ou Status Concessão não informado(s).';
                $retorno['erros'][] = $stdErro;
                continue;
            }

            if (preg_match($expressao, $idProposta)) {
                $retorno['erro'] = true;
                $stdErro->erro = 'Proposta deve conter somente valores numéricos.';
                $retorno['erros'][] = $stdErro;
                continue;
            }

            if (!in_array($statusConcessao, Seguro_Model_PropostasSubvencao::getChavesStatus())) {
                $retorno['erro'] = true;
                $stdErro->erro = 'Valor inválido para o Status de Concessão. Valores permitidos: EM_FILA_ENVIO';
                $stdErro->erro .= ', RESERVADA, CONCEDIDA, NAO_CONCEDIDA, SEM_SUBVENCAO.';
                $retorno['erros'][] = $stdErro;
                continue;
            }

            if (
                !in_array($statusConcessao, Seguro_Model_PropostasSubvencao::getChavesStatusPodemObrigarDataValor())
                && (!empty($dataConcessao) || !empty($valorSubvencao))
            ) {
                $retorno['erro'] = true;
                $stdErro->erro = 'Data e Valor devem estar em branco quando o Status de Concessão for';
                $stdErro->erro .= " {$statusConcessao}.";
                $retorno['erros'][] = $stdErro;
                continue;
            }

            if (!empty($dataConcessao)) {
                if (!preg_match('/^([0-2][0-9]|(3)[0-1])(\/)(((0)[0-9])|((1)[0-2]))(\/)\d{4}$/', $dataConcessao)
                    && !preg_match('/^([0-2][0-9]|(3)[0-1])(\-)(((0)[0-9])|((1)[0-2]))(\-)\d{4}$/', $dataConcessao)) {
                    $retorno['erro'] = true;
                    $stdErro->erro = 'Data está no formato errado. A data deve estar conforme os exemplos: 10/01/2021';
                    $stdErro->erro .= ' ou 10-01-2021.';
                    $retorno['erros'][] = $stdErro;
                    continue;
                }
            }

            if (!empty($valorSubvencao) && !is_numeric($valorSubvencao)) {
                $retorno['erro'] = true;
                $stdErro->erro = 'Valor está no formato errado. O valor deve estar conforme o exemplo: 800.00';
                $retorno['erros'][] = $stdErro;
                continue;
            }

            $registros[] = [
                'id_proposta' => $idProposta,
                'dt_concessao' => $dataConcessao,
                'vl_subvencao' => $valorSubvencao,
                'status_concessao' => $statusConcessao,
                'linha' => $totalLinhas
            ];
        }

        fclose($arquivo);
        $retorno['total_linhas'] = $totalLinhas - 1;
        $retorno['total_registros_importados'] = $retorno['total_linhas'];
        $retorno['registros'] = $registros;
        return $retorno;
    }

	public function importarsubvencaofederalAction()
    {
        $this->isAjax();
        $retorno = $this->preparaRegistrosSubvencao('file_federal');

        //No caso de ter ocorrido algum erro que deva parar o processamento.
        if ($retorno instanceof Zend_Controller_Response_Http) {
            return $retorno;
        }

        $registros = $retorno['registros'];
        unset($retorno['registros']);

        $user = Zend_Auth::getInstance()->getIdentity();
        $modelCadin = new Seguro_Model_PropostasConsultaCadin();
        $modelPropostasSubvencao = new Seguro_Model_PropostasSubvencao();
        $modelStatus = new Sistema_Model_Status();
        $status = $modelPropostasSubvencao->getStatusIndiceChave();

        foreach ($registros as $registro) {
            Agro_Db_Table_Abstract::getDefaultAdapter()->beginTransaction();

            $flSucesso = $registro['status_concessao'] === Seguro_Model_PropostasSubvencao::DS_CHAVE_CONCEDIDA;
            $dtConcessao = !empty($registro['dt_concessao'])
                ? Agro_Util::formatDate($registro['dt_concessao'], Zend_Date::W3C)
                : null;

            try {
                $this->salvarPropostaSubvencao(
                    $registro,
                    $modelPropostasSubvencao,
                    $status,
                    Seguro_Model_PropostasSubvencao::TIPO_SUBVENCAO_FEDERAL
                );

                $dados = array("id_usuario_alteracao" => $user->id,
                    "dt_alteracao" => "now()",
                    "fl_sucesso" => $flSucesso ? "true" : "false",
                    "fl_solicitacao_pendente" => "false",
                    "fl_retorno_pendente" => "false",
                    "fl_ativo" => "true",
                    "vl_subvencao_federal" => (!empty($registro['vl_subvencao'])) ? $registro['vl_subvencao'] : null,
                    "dt_concessao" => $dtConcessao,
                    "id_proposta" => $registro['id_proposta']);

                $row = $modelCadin->fetchAll("id_proposta = {$registro['id_proposta']}");
                $count = $row->count();
                if ($count > 0) {
                    if (
                        in_array(
                            $registro['status_concessao'],
                            Seguro_Model_PropostasSubvencao::getChavesStatusPodemObrigarDataValor()
                        )
                    ) {
                        $rowPropostaSubvencao = $modelPropostasSubvencao->fetchAll(
                            ["id_proposta = {$registro['id_proposta']}"]
                        )->toArray();

                        if (!empty($rowPropostaSubvencao)) {
                            $chaveStatus = $modelStatus->getChave(
                                $rowPropostaSubvencao[0]['id_status_subvencao_federal']
                            );

                            if (
                                !empty($chaveStatus)
                                && $chaveStatus === Seguro_Model_PropostasSubvencao::DS_CHAVE_CONCEDIDA
                            ) {
                                $row = $row->current();
                                $dados['vl_subvencao_federal'] = !empty($dados['vl_subvencao_federal'])
                                    ? $dados['vl_subvencao_federal']
                                    : $row['vl_subvencao_federal'];
                                $dados['dt_concessao'] = !empty($dados['dt_concessao'])
                                    ? $dados['dt_concessao']
                                    : $row['dt_concessao'];
                            }
                        }
                    }

                    $modelCadin->update($dados, "fl_ativo = true and id_proposta = " . $registro['id_proposta']);
                } else {
                    $modelCadin->insert($dados);
                }

                Agro_Db_Table_Abstract::getDefaultAdapter()->commit();
            } catch (\Throwable $th) {
                $registro['erro'] = "Erro ao incluir/alterar o registro.";

                if ($th->getCode() === 1) {
                    $registro['erro'] = $th->getMessage();
                }

                $retorno['erro'] = true;
                $retorno['erros'][] = $registro;
                Agro_Db_Table_Abstract::getDefaultAdapter()->rollback();
            }
        }

        if ($retorno['erro'] === true) {
            $retorno['mensagem'] = 'Importação realizada com sucesso. Algumas linhas não foram importadas, sendo o';
            $retorno['mensagem'] .= ' motivo apresentado na tela.';
            $retorno['total_registros_erro'] = count($retorno['erros']);
            $retorno['total_registros_importados'] = $retorno['total_linhas'] - $retorno['total_registros_erro'];
        }

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

	public function importarsubvencaoestadualAction()
    {
        $this->isAjax();
        $retorno = $this->preparaRegistrosSubvencao('file_estadual');

        //No caso de ter ocorrido algum erro que deva parar o processamento.
        if ($retorno instanceof Zend_Controller_Response_Http) {
            return $retorno;
        }

        $registros = $retorno['registros'];
        unset($retorno['registros']);

        $propostasConsultaSubvencaoEstadual = new Seguro_Model_PropostasConsultaSubvencaoEstadual();
        $modelPropostasSubvencao = new Seguro_Model_PropostasSubvencao();
        $modelStatus = new Sistema_Model_Status();
        $status = $modelPropostasSubvencao->getStatusIndiceChave();

        foreach ($registros as $registro) {
            Agro_Db_Table_Abstract::getDefaultAdapter()->beginTransaction();

            try {
                $this->salvarPropostaSubvencao(
                    $registro,
                    $modelPropostasSubvencao,
                    $status,
                    Seguro_Model_PropostasSubvencao::TIPO_SUBVENCAO_ESTADUAL
                );

                if (
                    in_array(
                        $registro['status_concessao'],
                        Seguro_Model_PropostasSubvencao::getChavesStatusPodemObrigarDataValor()
                    )
                ) {
                    $rowPropostaSubvencao = $modelPropostasSubvencao->fetchAll(
                        ["id_proposta = {$registro['id_proposta']}"]
                    )->toArray();

                    if (!empty($rowPropostaSubvencao)) {
                        $chaveStatus = $modelStatus->getChave(
                            $rowPropostaSubvencao[0]['id_status_subvencao_estadual']
                        );

                        if (
                            !empty($chaveStatus)
                            && $chaveStatus === Seguro_Model_PropostasSubvencao::DS_CHAVE_CONCEDIDA
                        ) {
                            $row = $propostasConsultaSubvencaoEstadual->fetchRow(
                                ["id_proposta = {$registro['id_proposta']}"]
                            );

                            $registro['vl_subvencao'] = !empty($registro['vl_subvencao'])
                                ? $registro['vl_subvencao']
                                : (!empty($row) ? $row['vl_subvencao_estadual'] : null);
                            $registro['dt_concessao'] = !empty($registro['dt_concessao'])
                                ? $registro['dt_concessao']
                                : (!empty($row) ? $row['dt_concessao'] : '');
                        }
                    }
                }

                $propostasConsultaSubvencaoEstadual->add($registro);

                Agro_Db_Table_Abstract::getDefaultAdapter()->commit();
            } catch (\Throwable $th) {
                $registro['erro'] = "Erro ao incluir/alterar o registro.";
                $retorno['erro'] = true;
                $retorno['erros'][] = $registro;
                Agro_Db_Table_Abstract::getDefaultAdapter()->rollback();
            }
        }

        if ($retorno['erro'] === true) {
            $retorno['mensagem'] = 'Importação realizada com sucesso. Algumas linhas não foram importadas, sendo o';
            $retorno['mensagem'] .= ' motivo apresentado na tela.';
            $retorno['total_registros_erro'] = count($retorno['erros']);
            $retorno['total_registros_importados'] = $retorno['total_linhas'] - $retorno['total_registros_erro'];
        }

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

	public function importarsecaoAction() {
	
		$this->isAjax();
		Agro_Db_Table_Abstract::getDefaultAdapter()->beginTransaction();
	
		$Adapter = new Zend_File_Transfer_Adapter_Http();
		$Adapter->setDestination(APPLICATION_PATH.'/upload_files/temp/');
		$file = $Adapter->getFileInfo();
	
		$Propostas = new Seguro_Model_Propostas();
		$User      = Zend_Auth::getInstance()->getIdentity();
	
		if(!$Adapter->receive($file['file_secao']['name'])) {
			$alert = 'Erro ao atualizar Seção!';
	
			$return = 0;
		} else {
	
			$extensao = explode('.',$file['file_secao']['name']);
	
			if(end($extensao) == 'csv'){
				//abre o arquivo
				$arquivo = fopen(APPLICATION_PATH.'/upload_files/temp/' . $file['file_secao']['name'],"r");
				$linha   = 0;
				$return  = 1;
	
				//processa o csv
				while(($dados = fgetcsv($arquivo, 0, ";")) != false && $return != 0){
	
					$data[$linha]['id_proposta'] = utf8_encode($dados[0]);
					$data[$linha]['id_secao']    = utf8_encode($dados[1]);
	
					try{
						//pula a primeira linha pois é cabeçalho
						if($linha != 0){
							$Row = $Propostas->find($data[$linha]['id_proposta'])->current();
							$Row->id_secao = $data[$linha]['id_secao']; 
							$Row->save();
						}
					}catch(Exception $e){
						Agro_Db_Table_Abstract::getDefaultAdapter()->rollback();
	
						$linha++;
						$alert  = "Erro ao atualizar Seção! Informações da linha $linha inválidas!";
						$return = 0;
					}
					$linha++;
	
				}
	
				fclose($arquivo);
	
				if($return == 1){
					$alert = 'Seção atualizada com sucesso!';
					Agro_Db_Table_Abstract::getDefaultAdapter()->commit();
				}
	
			}else{
				$alert  = 'Formato de arquivo inválido!';
				$return = 0;
			}
		}
	
		$this->getResponse()->setBody(Zend_Json::encode($alert));
	}
	
	public function inadimplentesAction() {
		$this->view->title = 'Seguro » Rotinas » Atualizar Inadimplentes';
	}
	
	public function atualizarinadimplentesAction() {
		$this->getHelper('layout')->disableLayout();
		$this->getHelper('ViewRenderer')->setNoRender();
	
		$Proponentes = new Seguro_Model_Proponentes();
	
		$result = array();
		$Adapter = new Zend_File_Transfer_Adapter_Http();
		$Adapter->setDestination(APPLICATION_PATH.'/upload_files/temp/');
		$Adapter->addValidator('Extension', false, array('csv', 'case' => true));
		$file = $Adapter->getFileInfo();
	
		if(!$Adapter->receive($file['inadimplentes_csv']['name'])) {
			$message['status'] = 'Erro ao atualizar inadimplentes.';
		} else {
	
			if($Adapter->isValid($file['inadimplentes_csv']['name'])){
				$arquivo = fopen(APPLICATION_PATH.'/upload_files/temp/' . $file['inadimplentes_csv']['name'], 'r');
				
				while(($dados = fgetcsv($arquivo, 0, ';')) != false) {
					if($dados[0] > 0){
						array_push($result, array('id' => $dados[0], 'fl_inadimplente' => $dados[1]));
					}
				}
	
				fclose($arquivo);
	
				if($Proponentes->atualizarInadimplentes($result)) {
					$message['status'] = "Atualização efetuada com sucesso!";
				} else {
					$message['status'] = "Erro ao atualizar inadimplentes!";
				}
	
			} else {
				$message['status'] = "Somente são aceitos arquivos .csv!";
			}
		}
	
		$this->getResponse()->setBody(Zend_Json::encode($message));
	}

	/** Recupera as cotações com status NOVO na Agritask 
	* Levando em consideração a estrutura terrível do json recebido
	* este foi o que melhor se conseguiu fazer.
	* Esse cara monta um array de objetos cotações para na função saveagritask percorrer 
	* o array e salvar as cotações setadas com os valores da forma correta
	*/
    private function preparaCotacaoAgritask() : array {
		$cotacoes = array();
       
		$this->getHelper('layout')->disableLayout();
		$this->getHelper('ViewRenderer')->setNoRender();
        
        $Proposta = new Seguro_Model_Propostas();
		$PropostasCotacaoAgritask = new Seguro_Model_PropostasCotacaoAgritask();
		$Produto = (new Produto_Model_Produtos())->fetchRow("ds_nome_produto ilike 'Pastagem Protegida -%' and id_safra = 25");

		/*
		// Comentado temporariamente enquanto a safra não é migrada para todos os produtos
		$Produto = (new Produto_Model_Produtos())->fetchRow(
			"ds_nome_produto = 'Pastagem Protegida - Índice' and id_safra = ". 
			(new Produto_Model_Safras())->getSafraAtual()['id'])->toArray();
		*/

		$url = AGRITASK_BASE_URL_DEV . '/t/rest/v4/view/72165396434780161?wskey=' . AGRITASK_WSKEY_DEV . '&embedDefinition=true&lang=PT';
		
		if (APPLICATION_ENV == 'production') {
			$url = AGRITASK_BASE_URL_PROD . '/i/rest/v4/view/72165396434780161?wskey=' . AGRITASK_WSKEY_PROD . '&embedDefinition=true&lang=PT';
		}

		$curl = curl_init();
		curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
		curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);

		$response = curl_exec($curl);

		$items = (array) json_decode($response, true)['items']; 

		foreach ($items as $it) {
			$talhoes = array();
			$nr_item_segurado = $ds_nome = '';

			if ($it['produtor'] != "'Iniciar uma nova cotação"){

				if (!array_key_exists($it['quotationn'], $cotacoes)) {
					$agritask = new Agro_AgritaskCotacao();
					/*inicia a proposta com o corretor teste porque,
					 * graças ao maravilhoso JSON da AgriTask,
					 * neste ponto já preciso do id_proposta mas 
					 * pode ser que nome do corretor ainda não esteja nessa "linha" do JSON
					
					//$idProposta = $PropostasCotacaoAgritask->getPropostaByCotacao($it['quotationn']);
					//$agritask->setIdProposta($idProposta ? $idProposta : $Proposta->iniciaProposta($Produto['id'], 487, ''));
					*/
					$agritask->setIdProposta($Proposta->iniciaProposta($Produto['id'], 487, ''));

					$PropostaRow = $Proposta->find($agritask->getIdProposta())->current();
					$PropostaRow->nr_digito_verificador = Agro_Util::verificador($agritask->getIdProposta());
					$PropostaRow->save();
					
					$agritask->setIdPropostaExtenso($PropostaRow->doc());

					$agritask->setIdCotacao($it['quotationn']);
					$cotacoes[$it['quotationn']] = $agritask;
					$cotacoes[$it['quotationn']]->setIdProduto((int)$Produto['id']);
				}

				if ($it['statusdaapólice']) {
					$cotacoes[$it['quotationn']]->setStatus((integer)$it['statusdaapólice']);

					$txd = array(
						'vl_taxa_10' => $it['prêmio%-franquia10%'],
						'vl_premio_10' => $it['prêmio_-franquia10%'],
						'vl_taxa_20' => $it['prêmio%-franquia20%'],
						'vl_premio_20' => $it['prêmio_-franquia20%'],
						'vl_taxa_30' => $it['prêmio%-franquia30%'],
						'vl_premio_30' => $it['prêmio_-franquia30%']
					);
					$cotacoes[$it['quotationn']]->setTaxasDisponiveis($txd);
				}

				if ($it['nomedocorretor'] != '') {
					$usuario = (new Sistema_Model_Usuarios())->fetchRow("ds_nome_usuario = '".$it['nomedocorretor']."'");
					if ($usuario) {
						$cotacoes[$it['quotationn']]->setIdUsuario((int)$usuario->id);
						
						if ($usuario->tp_usuario == 'C') {
							$corretor = (new Sistema_Model_Corretores())->fetchRow('id_usuario = '.$usuario->id)->toArray();
							$cotacoes[$it['quotationn']]->setIdCorretor((int)$corretor['id']);
						} elseif ($usuario->tp_usuario == 'P') { 
							$preposto = (new Sistema_Model_Prepostos())->fetchRow('id_usuario = '.$usuario->id)->toArray();
							$corretor = (new Sistema_Model_Corretores())->fetchRow('id = '. $preposto['id_corretor'])->toArray();
							$cotacoes[$it['quotationn']]->setIdUsuarioCorretor((int)$corretor['id_usuario']);
						} else { /*não altera o corretor teste */ }
					}
				}

				if ($it['talhão/apolice'] == $it['quotationn']) {
					for ($i=1; $i<=5; $i++) {
						$cotacoes[$it['quotationn']]->setIndices(array('id_proposta' => $cotacoes[$it['quotationn']]->getIdProposta(), 'ano' => $it['ano'.$i], 'indice' => $it['ano'.$i.'-índice'], 'fl_status' => $it['ano'.$i.'-status'], 'indice_esperado' => $it['gatilhosdoíndice(talhões)']));
					}

					$cotacoes[$it['quotationn']]->setCodigoSegurado($it['códigosegurado']);
					$cotacoes[$it['quotationn']]->setCodigoItemPrincipal($it['códigoitem']);
					$cotacoes[$it['quotationn']]->setVlFranquia((float)str_replace(',','.',$it['franquia(%)']));
					$cotacoes[$it['quotationn']]->setVlTaxa(round((float)str_replace(',','.',$it['prêmio(%)']), 2));	
					$cotacoes[$it['quotationn']]->setVlPremio((float)str_replace(',','.',$it['prêmio(_)']));
					$cotacoes[$it['quotationn']]->setVlLmga((float)str_replace(',','.',$it['montanteassegurado']));
				}
				
				$cotacoes[$it['quotationn']]->addCodigoItem($it['códigoitem']);

				$atributos['QUEST_PASTAGEM_TIPO_REBANHO'] = $it['tipoderebanho'];
				$atributos['QUEST_PASTAGEM_TIPO_PASTO'] = $it['idcultivo'];
				$atributos['QUEST_PASTAGEM_TIPO_FINALIDADE_REBANHO'] = $it['finalidade'];
				$atributos['QUEST_PASTAGEM_LOTACAO_HA'] = $it['valordalotação'];

				$cotacoes[$it['quotationn']]->setAtributos($atributos);

				//salvando dados do proponente
				$cpf_cnpj = !empty($it['cpf']) ? $it['cpf'] : $it['cnpj'];
				$cotacoes[$it['quotationn']]->setDocumento($cpf_cnpj);
				$cotacoes[$it['quotationn']]->setNomeProponente($it['produtor']);
				$cotacoes[$it['quotationn']]->setTipoPessoa(strlen($cpf_cnpj) == 18 ? 'J' : 'F') ;

				$croqui['id_proposta'] = $cotacoes[$it['quotationn']]->getIdProposta();
				$croqui['ds_nome_arquivo'] = 'CROQUI_' . $cotacoes[$it['quotationn']]->getIdProposta() . '_' . date('His') . '.png';
				$croqui['fl_vigente'] = 'true';

				$cotacoes[$it['quotationn']]->setCroqui($croqui);
								
				for($i=1; $i<=4; $i++) {
					$is = array();
					
					if (!empty($it['grideassociado'.$i.'(talhões)']) && !empty($it['grideassociadoareatalhão'.$i])) {

						$is['IS_DESCRICAO_ITEM'] = ($i > 1) ? trim($it['talhão/apolice']). '.' . ($i-1) : trim($it['talhão/apolice']);
						$is['IS_AREA'] = str_replace(',','.',$it['grideassociadoareatalhão'.$i]);
						$is['IS_VARIEDADES'] = 6838; //variedade GERAL PASTAGEM
						$is['DS_PAF'] = $it['grideassociado'.$i.'(talhões)'];
						$is['IS_COORDENADAS_GEOGRAFICAS'] = $this->getDms(str_replace(',','.',$it['latitude'])) . ' , ' . $this->getDms(str_replace(',','.',$it['longitude']));
						$is['IS_LMGA_PARCIAL'] = round(str_replace(',','.',$it['valorseguradoporha']) * str_replace(',','.',$it['grideassociadoareatalhão'.$i]), 2);
						$is['IS_VALOR_CUSTEIO'] = round(str_replace(',', '.', $it['valorseguradoporha']));

						$cotacoes[$it['quotationn']]->setItems($is);

						$coordenadas = explode(',', substr($it['[object_location_locationpolygon_multipolygon]'], 15, -3));
						$str_coord = array();
						foreach ($coordenadas as $coord) {
							$latlon = explode(' ', $coord);
							array_push($str_coord, '{"latitude":'.$latlon[1].',"longitude":'.$latlon[0].'}');
						}

						$coordenadas = '[' . implode(',', $str_coord) . ']';
						
						$ds_nome .= $is['IS_DESCRICAO_ITEM'].'; ';
						$nr_item_segurado .= count($cotacoes[$it['quotationn']]->getItems()).', ';

						$cotacoes[$it['quotationn']]->setTalhoes($talhoes);

						if ($i == 1) {
							$cotacoes[$it['quotationn']]->setCoordenadaSede($is['IS_COORDENADAS_GEOGRAFICAS']);
							$cotacoes[$it['quotationn']]->setDtVigenciaInicio($it['iníciodecobertura']);
							$cotacoes[$it['quotationn']]->setDtVigenciaFim($it['fimdecobertura']);
							$cotacoes[$it['quotationn']]->setEmailProponente($it['emailprodutor']);
							$cotacoes[$it['quotationn']]->setTelefone($it['telefoneprodutor']);
						}
					}
				}

				if ($ds_nome) {
					$talhoes['id_croqui'] = 0;
					$talhoes['ds_nome'] = substr($ds_nome, 0, -2);
					$talhoes['ds_coordenadas'] = $coordenadas;
					$talhoes['nr_item_segurado'] = substr($nr_item_segurado, 0, -2);
					$cotacoes[$it['quotationn']]->setTalhoes($talhoes);
				}
			}
		}

		return $cotacoes;
	}

	public function savecotacaoagritaskAction() {

		$result = array();
		$proposta = array();
        $Proposta = new Seguro_Model_Propostas();
        $PropostaCotacaoAgritask = new Seguro_Model_PropostasCotacaoAgritask();
        $Indice = new Seguro_Model_PropostasIndiceProducaoForrageira();
        $PropostasQuestionario = new Seguro_Model_PropostasQuestionarios();
        $PropostasProponente = new Seguro_Model_PropostasProponentes();
        $PropostasPropriedade = new Seguro_Model_PropostasPropriedades();
        $PropostasCroqui = new Seguro_Model_PropostasCroquis();
        $PropostasCroquiTalhao = new Seguro_Model_PropostasCroquisTalhoes();
		$Itens = new Seguro_Model_ItensSegurados();
		$Proponentes = new Seguro_Model_Proponentes();

		$cotacoes = $this->preparaCotacaoAgritask();
		foreach ($cotacoes as $cotacao) {
			
			if ($cotacao->getStatus() == Agro_AgritaskCotacao::STATUS_COTACAO_NOVA_COM_FRANQUIA) {
				$proponente = array();

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

					/**
					$old_cotacoes = $PropostaCotacaoAgritask->getPropostaByCotacao($cotacao->getIdCotacao());
					if (count($old_cotacoes)>0) {
						foreach($old_cotacoes as $c) {
							$Proposta->atualizaStatusProposta($c['id_proposta'], 4);
						}
					}**/

					$dadosPropostaCotacaoAgritask = [
						'id_proposta' => $cotacao->getIdProposta(),
						'id_cotacao' => $cotacao->getIdCotacao(),
						'vl_premio_10' => null,
						'vl_premio_20' => null,
						'vl_premio_30' => null,
						'ds_codigo_segurado' => $cotacao->getCodigoSegurado(),
						'ds_codigo_item' => $cotacao->getCodigoItemPrincipal()
					];

					$Proposta->atualizaStatusProposta($cotacao->getIdProposta(), 2);

					//indices 
					foreach($cotacao->getIndices() as $ind) {
						$Indice->save($ind);
					}
					
					//questionario
					$PropostasQuestionario->save($cotacao->getAtributos(), $cotacao->getIdProposta());
					
					//proponente
					$Proponente = $Proponentes->getProponente($cotacao->getDocumento());
					if ($Proponente['id']) {	
						$proponente['cpf_cnpj'] = $Proponente['cpf_cnpj'];
						$proponente['tp_pessoa'] = $Proponente['tp_pessoa'];
						$proponente['ds_email_proponente'] = $Proponente['ds_email_proponente'];
						$proponente['ds_nome_proponente'] = $Proponente['ds_nome_proponente'];
						$proponente['ds_tel_residencia'] = $Proponente['ds_tel_residencia'];
						$proponente['ds_tel_propriedade'] = $Proponente['ds_tel_propriedade'];
						$proponente['ds_tel_celular'] = $Proponente['ds_tel_celular'];
						$proponente['id_estado_civil'] = $Proponente['id_estado_civil'];
						$proponente['ds_endereco_rua'] = $Proponente['ds_endereco_rua'];
						$proponente['ds_endereco_nro'] = $Proponente['ds_endereco_nro'];
						$proponente['ds_endereco_complem'] = $Proponente['ds_endereco_complem'];
						$proponente['ds_endereco_bairro'] = $Proponente['ds_endereco_bairro'];
						$proponente['ds_endereco_cep'] = $Proponente['ds_endereco_cep'];
						$proponente['ds_sexo'] = $Proponente['ds_sexo'];
						$proponente['dt_nascimento'] = $Proponente['dt_nascimento'];
						$proponente['ds_documento_natureza'] = $Proponente['ds_documento_natureza'];
						$proponente['ds_documento_numero'] = $Proponente['ds_documento_numero'];
						$proponente['id_orgao_expedidor'] = $Proponente['id_orgao_expedidor'];
						$proponente['dt_documento_exp'] = $Proponente['dt_documento_exp'];										
						$proponente['ds_profissao'] = $Proponente['ds_profissao'];
						$proponente['id_atividade_economica'] = $Proponente['id_atividade_economica'];
						$proponente['id_municipio'] = $Proponente['id_municipio'];
						$proponente['tp_segurado'] = $Proponente['tp_segurado'];
					} else {
						$proponente['tp_pessoa'] = $cotacao->getTipoPessoa();
						$proponente['ds_nome_proponente'] = $cotacao->getNomeProponente();
						$proponente['ds_email_proponente'] = $cotacao->getEmailProponente();
						$proponente['ds_tel_residencia'] = $cotacao->getTelefone();
						$proponente['cpf_cnpj'] = $cotacao->getDocumento();
						$proponente['id_municipio'] = 5578; //municipio nulo
					}

					$PropostasProponente->save($proponente, $cotacao->getIdProposta());

					//items
					$nro_item = 0;
					foreach ($cotacao->getItems() as $item) {
						if ($nro_item == 0) { 
							$diff_lmga = $cotacao->getLmgaParcial() - $cotacao->getVlLmga();
							$diff_premio = $cotacao->getPremioParcial() - $cotacao->getVlPremio();

							if ($diff_lmga != 0) {
								$item['IS_LMGA_PARCIAL'] -= $diff_lmga;
							}

							//if ($diff_premio != 0) {
							//	$item['IS_VALOR_CUSTEIO'] -= $diff_premio;
							//}
						}
						$Itens->save(++$nro_item, $item, $cotacao->getIdProposta());
					}

					//croqui
					$cotacao->setIdCroqui($PropostasCroqui->save($cotacao->getCroqui()));

					//talhoes
					$nro_item = 0;
					foreach ($cotacao->getTalhoes() as $talhao) {
						$talhao['ds_item_segurado'] = $Itens->getIdByPropostaNroItemSegurado($cotacao->getIdProposta(), $talhao['nr_item_segurado']);
						$PropostasCroquiTalhao->save($talhao);
					}

					//datas de início e final de vigência
					if ($cotacao->getDtVigenciaInicio() && $cotacao->getDtVigenciaFim()) {
						Agro_Db_Table_Abstract::getDefaultAdapter()->query(
							"update seguro.propostas set 
							dt_vigencia_inicio = to_date('{$cotacao->getDtVigenciaInicio()}', 'dd/mm/yyyy'), 
							dt_vigencia_fim = to_date('{$cotacao->getDtVigenciaFim()}', 'dd/mm/yyyy') 
							where id = ".$cotacao->getIdProposta()
						);
					}

					$dadosPropostaCotacaoAgritask['vl_premio_' . $cotacao->getVlFranquia()] = $cotacao->getVlPremio();
					$idTaxaAgrupamento = $this->addTaxas($cotacao->getIdProposta(), $cotacao->getIdProduto(), $cotacao->getVlFranquia(), $cotacao->getVlTaxa());

					// Vincula a proposta com a cobertura para já vir selecionada na aba Prêmio do orçamento.
					Agro_Db_Table_Abstract::getDefaultAdapter()->query("
						INSERT INTO seguro.propostas_coberturas(id_proposta, id_cobertura, fl_principal, vl_franquia, vl_taxa, vl_premio) VALUES (
							{$cotacao->getIdProposta()},
							42,
							't',
							{$cotacao->getVlFranquia()}, 
							{$cotacao->getVlTaxa()},
							{$cotacao->getVlPremio()}
						);
					");

					// Buscas todas as taxas que estão disponíveis as salva com o idTaxaAgrupamento gerado anteriormente
					$taxasDisponiveis = $cotacao->getTaxasDisponiveis();
					foreach([10,20,30] as $percentualFranquia) {

						// Caso seja a taxa princial incluída anteriormente ou os valores estejam vazios, passamos para o próximo registro
						if ($percentualFranquia == $cotacao->getVlFranquia() || empty($taxasDisponiveis["vl_taxa_{$percentualFranquia}"]) || empty($taxasDisponiveis["vl_premio_{$percentualFranquia}"]))  {
							continue;
						}

						//Pra ficar correto eu preciso multiplicar por 100
						$taxaDisponivel = (float)str_replace(',','.',$taxasDisponiveis["vl_taxa_{$percentualFranquia}"]) * 100;
						$taxaDisponivel = round($taxaDisponivel, 2);
						$premioDisponivel = (float)str_replace(',','.',$taxasDisponiveis["vl_premio_{$percentualFranquia}"]);
						
						$dadosPropostaCotacaoAgritask['vl_premio_' . $percentualFranquia] = $premioDisponivel;
						$this->addTaxas($cotacao->getIdProposta(), $cotacao->getIdProduto(), $percentualFranquia, $taxaDisponivel, $idTaxaAgrupamento);
					}

					$PropostaCotacaoAgritask->save($dadosPropostaCotacaoAgritask);

					Agro_Db_Table_Abstract::getDefaultAdapter()->query("update seguro.propostas_endosso set fl_proposta_vigente=true where id_proposta = ".$cotacao->getIdProposta());
		
					//atualiza o corretor e o usuário 
					if ($cotacao->getIdUsuario() !== null) {
						(new Seguro_Model_PropostasCorretores())->save($cotacao->getIdProposta(), $cotacao->getIdUsuarioCorretor() ? $cotacao->getIdUsuarioCorretor() : $cotacao->getIdUsuario());
						Agro_Db_Table_Abstract::getDefaultAdapter()->query("update seguro.propostas set id_usuario_criacao = ".$cotacao->getIdUsuario()." where id = ".$cotacao->getIdProposta());
					}

					//array para atualizar status na AgriTask
					foreach($cotacao->getCodigosItens() as $codigoItem) {
						array_push(
							$this->update_file_agritask, array(
								'codigo_segurado' => $cotacao->getCodigoSegurado(),
								'codigo_item' => $codigoItem,
								'id_proposta_extenso' => $cotacao->getIdPropostaExtenso()
							)
						);
					}

					$return['message'] = 'Orçamento ('.$cotacao->getIdProposta().':'.$cotacao->getIdCotacao().') criado';
					$return['status'] = true;
					$return['error'] = null;
					Agro_Db_Table_Abstract::getDefaultAdapter()->commit();
					array_push($result, $return);

				} catch (Exception $e) {
					$return['error'] = $e->getMessage();
					$return['message'] = 'Problema ao importar o orçamento ('.$cotacao->getIdCotacao().')'; 
					$return['status'] = false;
					Agro_Db_Table_Abstract::getDefaultAdapter()->rollback();
					array_push($result, $return);
				}
			}
		}
		
		if ((count($this->update_file_agritask) > 0)) {
			$output = $this->updateCotacaoStatusAgritask();

			$messageAgritask = ($output['status']) ? 'Status das cotações atualizada com sucesso na Agritask.' : 'Problema as atualizar status das cotações na AgriTask.';
			$return['error'] = $output['response'];
			$return['message'] = $messageAgritask;
			$return['status'] = $output['status'];
			array_push($result, $return);
		}

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

	/**
	 * Cria o agrupamento de orçamento, caso não seja informado o id do agrupamento ($idTaxaAgrupamento),
	 * adiciona os valores das taxas e as relaciona.
	 * 
	 * @param int $idProposta
	 * @param int $idProduto
	 * @param int $vlFranquia
	 * @param float $vlTaxa
	 * @param int|null $idTaxaAgrupamento
	 * 
	 * @return int $idTaxaAgrupamento
	 */
	private function addTaxas($idProposta, $idProduto, $vlFranquia, $vlTaxa, $idTaxaAgrupamento = null) {
		$taxa = array(
			'fl_franquia_disponivel' => 'S',
			'vl_franquia' => $vlFranquia,
			'vl_taxa' => $vlTaxa,
			'vl_taxa_renovacao' => $vlTaxa,
			'vl_taxa_inadimplente' => $vlTaxa,
			'vl_taxa_reduzida' => $vlTaxa,
			'tp_taxa_agrupamento' => Comercializacao_Model_TaxasAgrupamentos::TIPO_ORCAMENTO,
			'id_proposta' => $idProposta,
			'id_produto' => $idProduto,
			'id_cobertura' => Produto_Model_Coberturas::BAIXA_INDICE,
			'vl_comissao' => 10.00,
			'fl_ativo' => true,
			'ds_nome_agrupamento_taxas' => $idProposta
		);

		if (empty($idTaxaAgrupamento)) {
			$taxa = $this->salvarTaxaAgrupamentoOrcamento($taxa);
			$idTaxaAgrupamento = $taxa['id_taxa_agrupamento'];
			
			if (!empty($taxa['id_taxa'])) {
				$taxa['id'] = $taxa['id_taxa'];
			}
		} else {
			$taxa['id_taxa_agrupamento'] = $idTaxaAgrupamento;
		}
		
		$modelTaxasValores = new Comercializacao_Model_TaxasValores();
		$idTaxasValores = $modelTaxasValores->save($taxa);
		$modelTaxasValores->relacionarTaxas($taxa, $idTaxasValores);

		return $idTaxaAgrupamento;
	}

	//cria o arquivo csv com cotações para atualizar o status 
	//na plataforma Agritask. ESTE CSV DEVE SER SEPARADO POR VÍRGULAS E NÃO PONTO E VÍRGULAS
	private function createUpdateCsvAgristaskFile() : ?string {
		$filename = APPLICATION_PATH . '/upload_files/log/agritask/update_status_agritask_'.date('Ymdhis').'.csv';
	
		file_put_contents($filename, "Grower name,Plot name/Policy number,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,integrated_by_agronet,agronet_proposal_number\n");
		
		foreach($this->update_file_agritask as $cotacao) {
			$linha = $cotacao['codigo_segurado'] . ','. $cotacao['codigo_item'] .",,,,,,,,,,,,3,". $cotacao['id_proposta_extenso'] ."\n";
			file_put_contents($filename, $linha, FILE_APPEND);
		}
	
		if (file_exists($filename)) return $filename;
	
		return null;
	}

	//gera taxa por orcamento
	private function salvarTaxaAgrupamentoOrcamento(array $parametros) : array {
        $modelTaxasAgrupamentos = new Comercializacao_Model_TaxasAgrupamentos();
        $rowTaxasAgrupamento = $modelTaxasAgrupamentos->salvar($parametros);

        $rowTaxasAgrupamento->ds_nome_agrupamento_taxas = "{$parametros['id_proposta']}_{$rowTaxasAgrupamento->id}";
        $rowTaxasAgrupamento->save();

        $parametros['id_taxa_agrupamento'] = $rowTaxasAgrupamento->id;

        $modelTaxasAgrupamentosOrcamentos = new Comercializacao_Model_TaxasAgrupamentoOrcamentos();
        $modelTaxasAgrupamentosOrcamentos->save($parametros);

        return $parametros;
    }

	//atualiza o status das cotações na plataforma Agritask
	private function updateCotacaoStatusAgritask() : array {
		$curl = curl_init();
		$filename = $this->createUpdateCsvAgristaskFile();
		$retorno = [
			'status' => true,
			'response' => ''
		];

		if ($filename) {

			$url = (APPLICATION_ENV == 'production') ? AGRITASK_BASE_URL_PROD : AGRITASK_BASE_URL_DEV;
			$url .= (APPLICATION_ENV == 'production') ? '/i/import/do' : '/t/import/do';

			curl_setopt_array($curl, array(
			CURLOPT_URL => $url,
			CURLOPT_RETURNTRANSFER => true,
			CURLOPT_SSL_VERIFYHOST => false,
			CURLOPT_SSL_VERIFYPEER => false,
			CURLOPT_CUSTOMREQUEST => 'POST',
			CURLOPT_POSTFIELDS => array(
				'file'=> new CURLFILE($filename),
				'wskey' => (APPLICATION_ENV == 'production') ? AGRITASK_WSKEY_PROD : AGRITASK_WSKEY_DEV,
				'class' => 'com.scantask.tms.importdata.ScriptImportUpdatePlots',
				'project' => AGRITASK_PROJECT_PROD
				),
			));

			$resp = curl_exec($curl);

			if (curl_errno($curl) > 0) {
				$retorno['status'] = false;
				$retorno['response'] = curl_error($curl);
				return $retorno; 
			}

			$retorno['response'] = $resp;

			if (strpos($resp, 'error')) {
				$retorno['status'] = false;	
			}

			curl_close($curl);
			
			return $retorno;
		}

		$retorno['status'] = false;
		$retorno['response'] = 'Arquivo CSV não encontrado.';
		return $retorno;
	}

	private function getDms(float $coord) : string {
		$coord = abs($coord);

		$deg = floor($coord);
		$min = floor(($coord - $deg) * 60);
		$sec = round((($coord - $deg - $min / 60) * 3600 * 1000) / 1000, 2);

		return '-'.$deg.' '.$min.' '.intval($sec);		
	}

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

        $modelChamado = new Atendimento_Model_Chamado();
        $retorno = ['erro' => false, 'mensagem' => 'Chamados importados com sucesso.'];
        $registros = [];
        $usuarioLogado = Zend_Auth::getInstance()->getIdentity();

        $adapter = new Zend_File_Transfer_Adapter_Http();
        $adapter->setDestination(APPLICATION_PATH . '/upload_files/temp/');
        $adapter->addValidator('Extension', false, ['csv']);
        $file = $adapter->getFileInfo();

        try {
            $modelChamado->getAdapter()->beginTransaction();

            if (!$adapter->isValid()) {
                throw new Exception('Formato de arquivo inválido (formato aceito: .csv).');
            }

            if (!$adapter->receive($file['arquivo_chamados_resolvidos']['name'])) {
                throw new Exception('Erro ao importar o arquivo.');
            }

            $contador = 1;
            $arquivo = fopen(APPLICATION_PATH . '/upload_files/temp/' . $file['arquivo_chamados_resolvidos']['name'],
              "r");

            while (($dados = fgetcsv($arquivo, 0, ";")) != false) {

                if (count($dados) != 3) {
                    throw new Exception("Importação não realizada! O arquivo não atende às especificações de Cabeçalho. Clique no ponto de interrogação abaixo para obter orientação.");
                }

				if($contador == 1){
				//Valida rótulo das colunas
					if (mb_stristr($dados[0], 'Proposta') === true) {
						throw new Exception('Importação inválida. O arquivo deve conter a coluna Proposta.');
					}
					if (mb_stristr($dados[1], 'Chamado') === true) {
						throw new Exception('Importação inválida. O arquivo deve conter a coluna Chamado.');
					}
					if (mb_stristr($dados[2], 'Descrição') === true) {
						throw new Exception('Importação inválida. O arquivo deve conter a coluna Descrição.');
                    }
                }

                $contador++;

                array_push(
                  $registros,
                  [
                    'id_proposta' => $dados[0],
                    'id_parent' => $dados[1],
                    'ds_descricao' => mb_detect_encoding($dados[2]) == 'UTF-8' ? $dados[2] : utf8_encode($dados[2]),
                    'id_status' => Sistema_Model_Status::CH_RESOLVIDO,
                    'id_responsavel' => $usuarioLogado->id,
                  ]
                );
            }

			//Valida de arquivo atende às orientações Cabeçaçho X Conteúdo
			if($contador < 2) {
				throw new Exception("Importação não realizada! O arquivo não atende às especificações de Cabeçalho e/ou Dados dos Chamados. Clique no ponto de interrogação abaixo para obter orientação.");
			}

            array_shift($registros);

            foreach ($registros as $registro) {
                $rowChamado = $modelChamado->getRow($registro['id_parent']);

                $registro['id_prioridade'] = $rowChamado['id_prioridade'];
                $registro['id_tipo_chamado'] = $rowChamado['id_tipo_chamado'];
                $registro['id_departamento'] = $rowChamado['id_departamento'];
                $registro['dt_prazo_agendamento'] = $rowChamado['dt_prazo_agendamento'];
                $registro['dt_agendamento'] = $rowChamado['dt_agendamento'];
                $registro['dt_prazo_retorno'] = $rowChamado['dt_prazo_retorno'];
                $registro['id'] = null;

                $modelChamado->save($registro);
            }

            unlink($arquivo);

            $modelChamado->getAdapter()->commit();
        } catch (Exception $erro) {
            $modelChamado->getAdapter()->rollback();

            $retorno['erro'] = true;
            $retorno['mensagem'] = $erro->getMessage();
        }

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

	public function programaabcAction() {
		$this->view->title = 'Seguro » Rotinas » Importar Proponentes do Programa RENOVAGRO';
	}

    public function importarabcAction() {
		$this->isAjax();
	
		$Adapter = new Zend_File_Transfer_Adapter_Http();
		$Adapter->setDestination(APPLICATION_PATH.'/upload_files/temp/');
		$Adapter->addValidator('Extension', false, ['csv']);
		$file = $Adapter->getFileInfo();
	
		$result = [
			'status' => 'true',
			'errors' => [],
			'message' => 'Proponentes cadastrados com sucesso.',
		];

		try {
			if (!$Adapter->isValid()) {
				throw new Exception('Formato de arquivo inválido (formatos aceitos: .csv).');
			}

			if(!$Adapter->receive($file['file_proponente']['name'])) {
				throw new Exception('Erro ao receber arquivo.');
			}

			if (!file_exists(APPLICATION_PATH.'/upload_files/temp/' . $file['file_proponente']['name'])) {
				throw new Exception('Arquivo não encontrado.');
			}
		} catch (\Throwable $th) {
			$result['status'] = false;
			$result['message'] = $th->getMessage();
			return $this->getResponse()->setBody(Zend_Json::encode($result));
		}

		$modelProponentesAbc = new Seguro_Model_ProponentesAbc();
		$nomeColunaCPF = 'CD_MUT';
		$nomeColunaDataVencimento = 'DT_VENCIMENTO';
		$indexColunaCPF = null;
		$indexColunaDataVencimento = null;
		$linha = 0;

		$arquivo = fopen(APPLICATION_PATH . '/upload_files/temp/' . $file['file_proponente']['name'], 'r');
		while (($dados = fgetcsv($arquivo, 0, ';')) != false) {

			$linha++;

			if ($linha == 1) {
				try {
					//Remove caracter invisível do início da string
					foreach ($dados as &$coluna) {
						$coluna = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $coluna);
					}

					$indexColunaCPF = array_search($nomeColunaCPF, $dados);
					$indexColunaDataVencimento = array_search($nomeColunaDataVencimento, $dados);

					if ($indexColunaCPF === false) {
						throw new Exception("Coluna {$nomeColunaCPF} não informada.");
					}

					if ($indexColunaDataVencimento === false) {
						throw new Exception("Coluna {$nomeColunaDataVencimento} não informada.");
					}

					if (!$modelProponentesAbc->deleteAll()) {
						throw new Exception("Erro ao limpar os registros anteriores.");
					}

					continue;
				} catch (\Throwable $th) {
					$result['status'] = false;
					$result['message'] = $th->getMessage();
					return $this->getResponse()->setBody(Zend_Json::encode($result));
				}
			}

			if (empty($dados[$indexColunaCPF])) {
				$result['errors'][$linha][] = "Coluna {$nomeColunaCPF} não informada na linha {$linha}.";
			}

			if (!Agro_Util::validarCpfCnpj($dados[$indexColunaCPF])) {
				$result['errors'][$linha][] = "Coluna {$nomeColunaCPF} possui o valor $dados[$indexColunaCPF] inválido na linha {$linha}.";
			}

			if (empty($dados[$indexColunaDataVencimento])) {
				$result['errors'][$linha][] = "Coluna {$nomeColunaDataVencimento} não informada na linha {$linha}.";
			}

			$validador = new Zend_Validate_Date(['format' => 'dd/MM/yy']);
			if (!$validador->isValid($dados[$indexColunaDataVencimento])) {
				$result['errors'][$linha][] = "Formato da data de vencimento inválida na linha {$linha}.";
			}

			if (empty($result['errors'][$linha])) {

				$id = null;
				$cpf = trim($dados[$indexColunaCPF]);
				$dataVencimento = new Zend_Date($dados[$indexColunaDataVencimento], 'dd/MM/yy');
				$dataVencimentoFormatada = $dataVencimento->toString('YYYY-MM-dd');

				$proponenteAbc = $modelProponentesAbc->getByCpfCnpj($cpf);
				if (!empty($proponenteAbc)) {
					if ($dataVencimentoFormatada <= $proponenteAbc->dt_vencimento) {
						continue;
					}

					$id = $proponenteAbc->id;
				}

				$dados = [
					'id' => $id,
					'cpf_cnpj' => $cpf,
					'dt_vencimento' => $dataVencimentoFormatada,
				];

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

				if ($modelProponentesAbc->save($dados) <= 0) {
					$result['errors'][$linha][] = "Erro ao salvar proponente ({$dados[$indexColunaCPF]}) da linha {$linha}.";
					Agro_Db_Table_Abstract::getDefaultAdapter()->rollback();
				} else {
					Agro_Db_Table_Abstract::getDefaultAdapter()->commit();
				}
			}
		}

		fclose($arquivo);

		if (!empty($result['errors'])) {
			$result['message'] = 'Importação parcialmente realizada. Algumas linhas não foram importadas.';
		}

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

    public function importaranotacoesAction()
    {
        $this->view->title = 'Seguro » Rotinas » Importar Observações da Proposta';

        if ($this->getRequest()->isPost()) {
            $this->isAjax();

            $this->_return['registros'] = [];
            $adapter = new Zend_File_Transfer_Adapter_Http();
            $adapter->setDestination(APPLICATION_PATH . '/upload_files/temp/');
            $adapter->addValidator('Extension', false, ['csv']);

            $file = $adapter->getFileInfo();
            $nomeArquivo = $file['arquivo']['name'];

            if (!$adapter->isValid()) {
                $retorno['erro'] = true;
                $retorno['mensagem'] = 'Formato de arquivo inválido (formato aceito: .csv).';

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

                return false;
            }

            if (!$adapter->receive($nomeArquivo)) {
                $retorno['erro'] = true;
                $retorno['mensagem'] = 'Erro ao receber o arquivo de importação das observações.';

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

                return false;
            }

            $arquivo = fopen(APPLICATION_PATH . '/upload_files/temp/' . $nomeArquivo, 'r');
            $contador = 0;
            $registros = [];
            $valoresInvalidos = [];

            while (($dados = fgetcsv($arquivo, 0, ';')) != false) {
                $contador++;
                if ($contador === 1) {
                    $colunas = [];

                    foreach ($dados as $valor) {
                        if (!empty(trim($valor))) {
                            $colunas[] = $valor;
                        }
                    }

                    if (count($colunas) !== 5) {
                        $mensagem = "Importação inválida. O arquivo deve conter 5 colunas.";

                        $retorno['erro'] = true;
                        $retorno['mensagem'] = $mensagem;

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

                        return false;
                    }
                }

                if ($contador === 1) {
                    continue;
                }

                $mostrarVistoriador = Agro_Util::removeAcentos(strtolower(trim($dados[2])));
                $ocultarItens = Agro_Util::removeAcentos(strtolower(trim($dados[3])));

                if (!in_array($mostrarVistoriador, ['sim', 'nao'])) {
                    $valoresInvalidos[$contador] = $contador;
                }

                if (!in_array($ocultarItens, ['sim', 'nao'])) {
                    $valoresInvalidos[$contador] = $contador;
                }

                $registros[] = [
                    'id_proposta' => $dados[0],
                    'descricao' => $dados[1],
                    'mostrar_vistoriador' => $mostrarVistoriador === 'sim',
                    'ocultar_itens' => $ocultarItens === 'sim',
                    'nome_arquivo' => $dados[4],
                ];
            }

            if (!empty($valoresInvalidos)) {
                $mensagem = "Importação inválida. As seguintes linhas possuem valores inválidos na coluna 'Mostrar Vistoriador'";
                $mensagem .= " e/ou 'Ocultar Itens' (valores válidos: Sim ou Não):\n";
                $mensagem .= implode(', ', $valoresInvalidos);

                $retorno['erro'] = true;
                $retorno['mensagem'] = $mensagem;

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

                return false;
            }

            fclose($arquivo);

            $this->_return['registros'] = $registros;

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

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

        $retorno = ['erro' => false, 'mensagem' => 'Importação realizada com sucesso.', 'tipo' => ''];

		try {

			if (empty($this->getRequest()->getParam('tipo'))) {
				throw new Exception("Tipo de arquivo não informado.");
			}

			$retorno['tipo'] = $this->getRequest()->getParam('tipo');

			$adapter = new Zend_File_Transfer_Adapter_Http();
			$adapter->setDestination(APPLICATION_PATH . '/upload_files/chamados/');
			$adapter->addValidator('Extension', false, ['xlsx']);
	
			$file = $adapter->getFileInfo();
			$nomeArquivo = $file['arquivo']['name'];
	
			if (!$adapter->isValid()) {
				throw new Exception('Formato de arquivo inválido (formato aceito: .xlsx).');
			}
	
			if (!$adapter->receive($nomeArquivo)) {
				throw new Exception('Erro ao receber o arquivo.');
			}
	
			$novoNome = $this->getRequest()->getParam('tipo') == 'tecnica' ? 'MODELO_ARQUIVO_TECNICA.xlsx' : 'MODELO_ARQUIVO_SINISTRO.xlsx';
			rename(APPLICATION_PATH . '/upload_files/chamados/' . $nomeArquivo, APPLICATION_PATH . "/upload_files/chamados/{$novoNome}");
	
		} catch (\Throwable $th) {
			$retorno['erro'] = true;
			$retorno['mensagem'] = $th->getMessage();
		}

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

	public function pesquisarchamadosAction()
	{
		$this->isAjax();
		$retorno = ['erro' => false, 'mensagem' => '', 'resultados' => []];

		try {
			$parametros = $this->getRequest()->getParams();
			$where = $this->montarWherePesquisaChamados($parametros);

			$sql =  " SELECT spr.id_proposta_mae as id_proposta, ";
			$sql .= "   	 usuario.ds_nome_usuario, ";
			$sql .= "   	 ch.id, ";
			$sql .= "   	 ch.id_parent, ";
			$sql .= "   	 ch.id_prioridade, ";
			$sql .= "   	 ch.id_tipo_chamado, ";
			$sql .= "   	 ch.id_departamento, ";
			$sql .= "   	 ch.id_status, ";
			$sql .= "   	 st.ds_status, ";
			$sql .= "   	 ch.ds_descricao, ";
			$sql .= "   	 tc.ds_tipo_chamado, ";
			$sql .= "   	 CASE WHEN ch.id_parent IS NULL THEN ch.id_responsavel ELSE chi.id_responsavel END AS id_responsavel ";
			$sql .= "   FROM atendimento.chamados ch  ";
			$sql .= "   JOIN ( ";
			$sql .= "   	SELECT ch_aux.id AS id_chamado ";
			$sql .= "   		  ,CASE WHEN sua.ds_nome_usuario IS NULL THEN su.ds_nome_usuario  ELSE sua.ds_nome_usuario END AS ds_nome_usuario ";
	 		$sql .= "   	  FROM atendimento.chamados ch_aux ";
	 		$sql .= "   	  JOIN sistema.usuarios su ON su.id = ch_aux.id_usuario_criacao ";
	 		$sql .= "   	  LEFT JOIN sistema.usuarios sua ON sua.id = ch_aux.id_usuario_alteracao ";
			$sql .= "   ) AS usuario ON usuario.id_chamado = ch.id ";
			$sql .= "   JOIN sistema.status st ON st.id = ch.id_status ";
			$sql .= "   JOIN atendimento.tipo_chamado tc ON tc.id = ch.id_tipo_chamado ";
			$sql .= "   JOIN seguro.propostas spr ON spr.id = ch.id_proposta ";
			$sql .= "   JOIN produto.produtos sprod ON sprod.id = spr.id_produto ";
			$sql .= "   JOIN seguro.propostas_endosso spe ON spr.id = spe.id_proposta ";
			$sql .= "   JOIN ( ";
			$sql .= "           SELECT MAX(chamados.id) AS id_chamado, ";
			$sql .= "           	   coalesce(chamados.id_parent, chamados.id) AS chamado, ";
			$sql .= "           	   propostas_endosso.id_endosso ";
			$sql .= "           FROM atendimento.chamados ";
			$sql .= "           JOIN seguro.propostas_endosso ON chamados.id_proposta = propostas_endosso.id_proposta ";
			$sql .= "           WHERE propostas_endosso.id_endosso IN (SELECT id_endosso FROM seguro.propostas WHERE id IN (chamados.id_proposta)) ";
			$sql .= "           GROUP BY propostas_endosso.id_endosso, chamado ";
			$sql .= "   ) as x ON x.id_chamado = ch.id ";
			$sql .= "   LEFT JOIN ( ";
			$sql .= "   	SELECT id, id_responsavel FROM atendimento.chamados  ";
			$sql .= "   ) AS chi ON chi.id = ch.id_parent ";
			$sql .= "  WHERE " . implode(" AND ", $where);
			$sql .= "  ORDER BY ch.dt_criacao DESC ";

			$retorno['resultados'] =  Zend_Db_Table::getDefaultAdapter()->fetchAll($sql);

		} catch (\Throwable $th) {
			$retorno['erro'] = true;
			$retorno['mensagem'] = $th->getMessage();
			$retorno['resultados'] = [];
		}

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

	/**
	 * Monta o where para a pesquisa dos chamados
	 *
	 * @param array $parametros
	 * @return array
	 */
	private function montarWherePesquisaChamados(array $parametros): array
	{
		$modelSafra = new Produto_Model_Safras();
		$idSafraAtual = $modelSafra->getSafraAtual('id');

		$where[] = "ch.id_status in (". Atendimento_Model_Chamado::ID_STATUS_NOVO .",". Atendimento_Model_Chamado::ID_STATUS_ABERTO .")";
		$where[] = "EXISTS(SELECT * FROM atendimento.chamados WHERE chamados.id = x.chamado AND chamados.id_status <> ". Atendimento_Model_Chamado::ID_STATUS_RESOLVIDO .")";
		$where[] = "sprod.id_safra >= " . ($idSafraAtual - 2);

		if (!empty($parametros['vlPesquisa']) && in_array($parametros['tpPesquisa'], [1,2])) {

            if (!filter_var($parametros['vlPesquisa'], FILTER_VALIDATE_INT)) {
                throw new Exception("Campo 'valor da Pesquisa' deve ser um inteiro quando o 'Tipo de Pesquisa' for 'Proposta' ou 'Chamado'.");
            }

			$valoresPesquisa = explode(" ", $parametros['vlPesquisa']);
			//Limpa as posições em branco (quando houver mais de um espaço separando as propostas/chamados)
			$valoresPesquisa = array_filter($valoresPesquisa, function ($valor) {
				return !empty(trim($valor));
			});
			$valores = implode(', ', $valoresPesquisa);

			if ($parametros['tpPesquisa'] == 1) {
				$where[] = "spe.id_endosso IN (SELECT id_endosso FROM seguro.propostas WHERE id IN ($valores))";
			} else {
				$where[] = "(ch.id_parent IN ({$valores}) OR (ch.id_parent is NULL AND ch.id IN ({$valores})))";
			}
		} else {

			if (!empty($parametros['vlPesquisa']) && $parametros['tpPesquisa'] == 3) {
				$where[] = "usuario.ds_nome_usuario ilike '%{$parametros['vlPesquisa']}%'";
			}

			if (!empty($parametros['idDepartamento'])) {
				$where[] = "ch.id_departamento = " . $parametros['idDepartamento'];
			}

			if (!empty($parametros['idTipoChamado'])) {
				$where[] = "EXISTS(SELECT * FROM atendimento.chamados WHERE chamados.id = x.chamado AND chamados.id_tipo_chamado = ". $parametros['idTipoChamado'] .")";
			}

			if (!empty($parametros['idResponsavel'])) {
				$where[] = "(
					(ch.id_parent IS NOT NULL AND (chi.id_responsavel = {$parametros['idResponsavel']}) OR
					(ch.id_parent IS NULL AND ch.id_responsavel = {$parametros['idResponsavel']}))
				)";
			}

			if (!empty($parametros['situacao'])) {
				$situacao = $parametros['situacao'] == '1' ? 'true' : 'false';
				$where[] = "ch.fl_pendencia_agrobrasil = " . $situacao;
			}
		}

		return $where;
	}

	public function salvarrespostaschamadosAction()
	{
		$this->isAjax();
		$retorno = ['erro' => false, 'mensagem' => 'Respostas salvas com sucesso.'];

		try {
			$modelChamado = new Atendimento_Model_Chamado();
			$modelChamadoArquivos = new Atendimento_Model_Chamadoarquivos();
			$parametros = $this->getRequest()->getParams();
			$chamados = json_decode($parametros['chamados']);

			//Para incluir apenas um arquivo no caso de resposta única
			$nomeArquivoUnico = '';
			if (!empty($_FILES['arquivo_resposta_unica'])) {
				$nomeArquivoUnico = "resposta_unica_" . time() . "_1." . end(explode('.', $_FILES['arquivo_resposta_unica']['name']));
				$novoArquivo = PATH_CHAMADOS."/".$nomeArquivoUnico;
				if (!copy($_FILES['arquivo_resposta_unica']['tmp_name'], $novoArquivo)) {
					throw new Exception("Erro ao salvar o arquivo.");
				}
			}

			foreach ($chamados as $chamado) {

				$idChamado = $modelChamado->save((array) $chamado);
				if (!$idChamado) {
					throw new Exception("Erro ao salvar as respostas dos chamados.");
				}

				if (!empty($_FILES['arquivo_resposta_unica'])) {
					$modelChamadoArquivos->save(array(
						'id_chamado' => $idChamado,
						'ds_nome_arquivo' => $nomeArquivoUnico,
						'ds_nome_original_arquivo' => $_FILES['arquivo_resposta_unica']['name']
					));

					continue;
				}

				if (!empty($_FILES["arquivo_{$chamado->id_parent}"])) {

					$file = $_FILES["arquivo_{$chamado->id_parent}"];
					$novoNome = $idChamado . "_1." . end(explode('.', $file['name']));
					$novoArquivo = PATH_CHAMADOS."/" . $novoNome;

					if (copy($file['tmp_name'], $novoArquivo)) {
						$modelChamadoArquivos->save(array(
							'id_chamado' => $idChamado,
							'ds_nome_arquivo' => $novoNome,
							'ds_nome_original_arquivo' => $file['name']
						));
					} else {
						throw new Exception("Erro ao salvar o arquivo do chamado {$chamado->id_parent}.");
					}
				}
			}

		} catch (\Throwable $th) {
			$retorno['erro'] = true;
			$retorno['mensagem'] = $th->getMessage();
		}

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

	public function concluirvistoriaAction()
    {
        $this->view->title = 'Seguro » Rotinas » Concluir Vistoria';

        if ($this->getRequest()->isPost()) {
            $this->isAjax();
			$this->_return['erros'] = [];

			try {
				Agro_Db_Table_Abstract::getDefaultAdapter()->beginTransaction();
				$adapter = new Zend_File_Transfer_Adapter_Http();
				$adapter->setDestination(APPLICATION_PATH . '/upload_files/temp/');
				$adapter->addValidator('Extension', false, ['csv']);

				$file = $adapter->getFileInfo();
				$nomeArquivo = $file['arquivo']['name'];

				if (!$adapter->isValid()) {
					throw new Exception("Formato de arquivo inválido (formato aceito: .csv)");
				}

				if (!$adapter->receive($nomeArquivo)) {
					throw new Exception("Erro ao receber o arquivo.");
				}

				$registrosValidos = $this->validarRegistrosConcluirVistoria($nomeArquivo);

				if (!empty($this->_return['erros'])) {
					throw new Exception("Erro a realizar a importação. Há inconsistências no arquivo importado.");
				}

				$this->atualizarStatusVistorias($registrosValidos);
				Agro_Db_Table_Abstract::getDefaultAdapter()->commit();
			} catch (\Throwable $th) {
				Agro_Db_Table_Abstract::getDefaultAdapter()->rollback();
				$this->_return['erro'] = true;
				$this->_return['mensagem'] = $th->getMessage();
			}

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

	/**
	 * Percorre os registros do arquivo csv de concluir vistorias e atualiza o status de análise para
	 * "Concluída - sem alterações", inclui o histórico de alteração do status, libera os documentos
	 * que estão como "Aguardando Liberação" e cadastra uma observação pra proposta.
	 *
	 * @param array $registros
	 */
	private function atualizarStatusVistorias(array $registros): void
	{
		$modelVistoriaPrevia = new Seguro_Model_VistoriaPrevia();

		foreach ($registros as $registro) {
			$this->criarPDFLaudoPrevia($registro['id_proposta_vistoria'], $registro['id_vistoria']);
			$modelVistoriaPrevia->concluirAnalise($registro['id_vistoria']);
		}
	}

	/**
	 * Criamos automaticamente o PDF da prévia caso não exista nenhum documento
	 * do tipo TIPO_LAUDO(id 2) para a vistoria
	 *
	 * @param int $idPropostaVistoria
	 * @param int $idVistoria
	 */
	private function criarPDFLaudoPrevia(int $idPropostaVistoria, int $idVistoria): void
	{
		$modelVistoriaPreviaArquivos = new Seguro_Model_Vistoriapreviaempresaarquivos();
		$totalLaudos = $modelVistoriaPreviaArquivos->getCountArquivo(
			$idPropostaVistoria,
			Sistema_Model_TipoArquivoLaudoPrevia::TIPO_LAUDO
		);

		if (empty($totalLaudos)) {
			$pathLvp001 = "/regulacao/lvp001/pdflaudo/id_proposta_vistoria/{$idPropostaVistoria}";

			$requestLvp001 = $this->getRequest();
			$requestLvp001->setModuleName('regulacao');
			$requestLvp001->setControllerName('lvp001');
			$requestLvp001->setActionName('pdflaudo');
			$requestLvp001->setRequestUri($pathLvp001);
			$requestLvp001->setPathInfo($pathLvp001);
			$requestLvp001->setParams([
				'module' => 'regulacao',
				'controller' => 'lvp001',
				'action' => 'pdflaudo',
				'id_proposta_vistoria' => $idPropostaVistoria,
				'transacao' => 1
			]);

			$controllerLvp001 = new Regulacao_Lvp001Controller($requestLvp001, $this->getResponse());
			$controllerLvp001->pdflaudoAction();
			$retornoPDFLaudo = json_decode($controllerLvp001->getResponse()->getBody());

			if ($retornoPDFLaudo->error) {
				throw new Exception("Erro na vistoria {$idVistoria}: " .  $retornoPDFLaudo->message);
			}
		}
	}

	/**
	 * Percorre o arquivo csv informado, valida as informações e retorna os registros
	 *
	 * @param string $nomeArquivo
	 * @return array
	 */
	private function validarRegistrosConcluirVistoria(string $nomeArquivo): array
	{
		$linha = 0;
		$registros = [];
		$indexVistoria = 0;

		$arquivo = fopen(APPLICATION_PATH . '/upload_files/temp/' . $nomeArquivo, 'r');
		while (($dados = fgetcsv($arquivo, 0, ';')) != false) {
			$linha++;

			if ($linha === 1) {
				if (count($dados) !== 1) {
					$this->addErroConcluirVistoria($linha, 'Importação inválida. O arquivo deve conter 1 colunas.');
					break;
				}

				$dados[$indexVistoria] = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $dados[$indexVistoria]); //Remove caracter invisível do início da string
				$dados[$indexVistoria] = trim(strtolower($dados[$indexVistoria]));

				if (!str_contains($dados[$indexVistoria], 'vistoria')) {
					$this->addErroConcluirVistoria($linha, 'Cabeçalho incorreto. A primeira coluna deve conter a palavra "vistoria".');
				}

				if (!empty($this->_return['erros'])) {
					break;
				}

				continue;
			}

			if (empty($dados[$indexVistoria])) {
				$this->addErroConcluirVistoria($linha, 'Vistoria não informada.');
				continue;
			}

			if (!filter_var($dados[$indexVistoria], FILTER_VALIDATE_INT)) {
				$this->addErroConcluirVistoria($linha, 'Número da vistoria deve ser um inteiro.');
				continue;
			}

			$idVistoria = (int) $dados[$indexVistoria];
			$modelVistoriaPrevia = new Seguro_Model_VistoriaPrevia();
			$dadosVistoria = $modelVistoriaPrevia->getByIdVistoria($idVistoria);

			if (empty($dadosVistoria)) {
				$this->addErroConcluirVistoria($linha, 'Não foi possível encontrar a vistoria.');
				continue;
			}

			$statusVistoriaValidos = [
				Seguro_Model_VistoriaPrevia::ID_STATUS_VP_TRANSMITIDA,
				Seguro_Model_VistoriaPrevia::ID_STATUS_VP_TRANSMITIDA_SEM_FOTOS
			];

			if (!in_array($dadosVistoria['id_status'], $statusVistoriaValidos)) {
				$this->addErroConcluirVistoria($linha, 'Status da vistoria inválido.');
				continue;
			}

			if ($dadosVistoria['id_status_analise'] != Seguro_Model_VistoriaPrevia::ID_STATUS_VP_ANALISE_NAO_ANALISADO) {
				$this->addErroConcluirVistoria($linha, 'Status da análise inválido.');
				continue;
			}

			$registros[] = [
				'id_vistoria' => $idVistoria,
				'id_proposta_vistoria' => $dadosVistoria['id']
			];
		}

		return $registros;
	}

	/**
	 * Adiciona qual erro aconteceu em qual linha do arquivo de conclusão de vistorias
	 *
	 * @param int $linha
	 * @param string $mensagem
	 */
	private function addErroConcluirVistoria(int $linha, string $mensagem): void
	{
		$this->_return['erros'][] = ['linha' => $linha, 'mensagem' => $mensagem];
	}

    public function aceitarpropostasAction()
    {
        $this->view->title = 'Seguro » Rotinas » Aceitar Propostas';

        if ($this->getRequest()->isPost()) {
            $this->isAjax();

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

                $adapter = new Zend_File_Transfer_Adapter_Http();
                $adapter->setDestination(APPLICATION_PATH . '/upload_files/temp/');
                $adapter->addValidator('Extension', false, ['csv']);

                $file = $adapter->getFileInfo();
                $nomeArquivo = $file['arquivo']['name'];

                if (!$adapter->isValid()) {
                    throw new Exception('Formato de arquivo inválido (formato aceito: .csv).');
                }

                if (!$adapter->receive($nomeArquivo)) {
                    throw new Exception('Erro ao receber o arquivo de propostas a serem aceitas.');
                }

                $arquivo = fopen(APPLICATION_PATH . '/upload_files/temp/' . $nomeArquivo, 'r');
                $cabecalho = true;
                $mensagemPadrao = "Importação inválida. O arquivo deve conter somente a coluna Propostas.";
                $propostas = [];

                while (($dados = fgetcsv($arquivo, 0, ';')) != false) {
                    if ($cabecalho) {
                        $totalColunas = count($dados);
                        $dados[0] = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $dados[0]);

                        if ($totalColunas !== 1 || (isset($dados[0]) && trim($dados[0]) !== 'Propostas')) {
                            throw new Exception($mensagemPadrao);
                        }

                        $cabecalho = false;
                        continue;
                    }

					$proposta = trim($dados[0]);
					if (!empty($proposta)) {
						$propostas[] = $proposta;
					}
                }

                fclose($arquivo);

                if ($cabecalho && empty($propostas)) {
                    throw new Exception($mensagemPadrao);
                }

                $modelPropostas = new Seguro_Model_Propostas();
                $whereStatusInvalidos = "id in (" . implode(', ', $propostas) . ") ";
                $whereStatusInvalidos .= " AND id_status <> " . Seguro_Model_Propostas::ID_STATUS_ENVIADA_AGUARDANDO_CONF;
                $whereStatusInvalidos .= " AND id_status <> " . Seguro_Model_Propostas::ID_STATUS_CONF_PENDENCIAS;
                $rowsPropostasStatusInvalidos = $modelPropostas->fetchAll($whereStatusInvalidos)->toArray();

                if (!empty($rowsPropostasStatusInvalidos)) {
                    $propostasInvalidas = array_map(function($row) {
                       return $row['id'];
                    }, $rowsPropostasStatusInvalidos);

                    $mensagem = "Importação não concluída. As seguintes propostas encontram-se com status";
                    $mensagem .= " diferente de '3 - Proposta Enviada - Aguardando Conf.' e '4 - Conferência de Pendência.':\n";
                    $mensagem .= implode(', ', $propostasInvalidas);

                    throw new Exception($mensagem);
                }

                $propostasErro = [];

                foreach ($propostas as $proposta) {
                    if (!$modelPropostas->changeStatus(
                        ['id_proposta' => $proposta],
                        Seguro_Model_Propostas::DS_CHAVE_AGUARDANDO_ENVIO_SEG
                    )) {
                        $propostasErro[] = $proposta;
                    }
                }

                if (!empty($propostasErro)) {
                    $mensagem = "Erro ao aceitar as seguintes propostas:\n";
                    $mensagem .= implode(", ", $propostasErro);
                    $mensagem .= "\nLote não processado.";

                    throw new Exception($mensagem);
                }

                Agro_Db_Table_Abstract::getDefaultAdapter()->commit();
            } catch (Exception $erro) {
                Agro_Db_Table_Abstract::getDefaultAdapter()->rollBack();

                $this->_return['erro'] = true;
                $this->_return['mensagem'] = $erro->getMessage();
            }

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

	public function programaabclistAction()
	{
		$this->isAjax(true);
        $response['status'] = true;

        try {
            $this->view->paginator = (new Seguro_Model_ProponentesAbc())->fetchAllPaginator(
                false, $this->getRequest()->getParam('page'), 20, 'paginator'
            );
        } catch (Exception $e) {
            $this->view->error = $e;
        }

	}

	public function removerabcAction()
	{
		$this->isAjax();
		$retorno = ['erro' => false, 'mensagem' => 'Registro(s) excluído(s) com sucesso.'];
		$params = $this->getRequest()->getParams();

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

			if (empty($params['ids'])) {
				throw new Exception("Parâmetro 'ids' não informado.");
			}

			$modelProponentesAbc = new Seguro_Model_ProponentesAbc();
			$ids = explode(",", $params['ids']);

			foreach ($ids as $id) {
				if (!$modelProponentesAbc->delete($id)) {
					throw new Exception("Erro ao excluir o registro {$id}.");
				}
			}
			Agro_Db_Table_Abstract::getDefaultAdapter()->commit();

		} catch (\Throwable $th) {
			Agro_Db_Table_Abstract::getDefaultAdapter()->rollBack();
			$retorno['erro'] = true;
			$retorno['mensagem'] = $th->getMessage();
		}

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

	public function removervencidosprogramaabcAction()
	{
		$this->isAjax();
		$retorno = ['erro' => false, 'mensagem' => 'Registro(s) excluído(s) com sucesso.'];

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

			if (!(new Seguro_Model_ProponentesAbc())->deleteVencidos()) {
				throw new Exception("Erro ao remover os proponentes que estão vencidos no programa.");
			}

			Agro_Db_Table_Abstract::getDefaultAdapter()->commit();
		} catch (\Throwable $th) {
			Agro_Db_Table_Abstract::getDefaultAdapter()->rollBack();
			$retorno['erro'] = true;
			$retorno['mensagem'] = $th->getMessage();
		}

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


    /**
     * @param array $registro
     * @param Seguro_Model_PropostasSubvencao $model
     * @param array $status
     * @param string $tipoSubvencao
     * @return void
     * @throws Exception
     */
    private function salvarPropostaSubvencao(
        array $registro,
        Seguro_Model_PropostasSubvencao $model,
        array $status,
        string $tipoSubvencao
    ) : void
    {
        $propostaSubvencao = $model
            ->getPropostaSubvencao((int) $registro['id_proposta']);
        $statusEstadual = $statusFederal = $status[Seguro_Model_PropostasSubvencao::DS_CHAVE_SEM_SUBVENCAO];

        if (!empty($propostaSubvencao)) {
            $propostaSubvencao = $propostaSubvencao->toArray();
            $deParaChaves = Seguro_Model_PropostasSubvencao::getDeParaChavesStatusDataValorObrigatorio();
            $colunaSubvencaoValidar = '';

            if ($tipoSubvencao === Seguro_Model_PropostasSubvencao::TIPO_SUBVENCAO_ESTADUAL) {
                $colunaSubvencaoValidar = 'status_chave_estadual';
                $statusEstadual = $status[$registro['status_concessao']];
                $statusFederal = $propostaSubvencao['id_status_subvencao_federal'];
            }

            if ($tipoSubvencao === Seguro_Model_PropostasSubvencao::TIPO_SUBVENCAO_FEDERAL) {
                $colunaSubvencaoValidar = 'status_chave_federal';
                $statusEstadual = $propostaSubvencao['id_status_subvencao_estadual'];
                $statusFederal = $status[$registro['status_concessao']];
            }

            if (
                array_key_exists($propostaSubvencao[$colunaSubvencaoValidar], $deParaChaves)
                && in_array($registro['status_concessao'], $deParaChaves[$propostaSubvencao[$colunaSubvencaoValidar]])
                && (empty($registro['dt_concessao']) || empty($registro['vl_subvencao']))
            ) {
                throw new Exception('Data e/ou Valor não informado(s).', 1);
            }
        }

        if (
            !$model->save([
                'id' => !empty($propostaSubvencao) ? $propostaSubvencao['id'] : null,
                'id_proposta' => $registro['id_proposta'],
                'id_status_subvencao_estadual' => $statusEstadual,
                'id_status_subvencao_federal' => $statusFederal,
            ])
        ) {
            throw new Exception('Erro ao salvar o status da subvenção.', 1);
        }
    }

	public function coordenadascarAction()
	{
		$this->view->title = 'Seguro » Rotinas » Coordenadas CAR';
		$this->view->dados = [];

		$modelCAR = new Seguro_Model_CAR();
		$dados = $modelCAR->coordinatesFileInfo();
		if (!empty($dados['resultado'])) {
			$this->view->dados = $dados['resultado'][0];
		}
		
		if ($this->getRequest()->isPost()) {
			try {
				$modelCAR->downloadCoordinates();
				
			} catch (\Throwable $th) {
				$this->_return['erro'] = true;
				$this->_return['mensagem'] = $th->getMessage();
			}
		}
	}
}
