<?php
require_once(APPLICATION_PATH . "/../library/Agro/nusoap/nusoap.php");

class GerarboletoController extends Agro_Controller_Action {

	const CODE_ERROR_ABRIR_CHAMADO_PADRAO = 1;
	const CODE_ERROR_CONFIRM_CHAMADO_PADRAO = 2;
	const CODE_ERROR_CONFIRM_CHAMADO_COBERTURA = 3;
	const CODE_ERROR_APENAS_EXIBIR_MENSAGEM = 99;

	public function init() {
		$this->getHelper('ViewRenderer')->setNoRender();
		$this->getHelper('layout')->disableLayout();
	}

	public function baixarboletoAction($identificador=""){
		$config = Zend_Registry::get('config');
		$this->soapClient = new nusoap_client($config['webservice']['wsdl']);

		if(!$identificador){
			$identificador = $this->getRequest()->getParam('identificador');
		}
		//$nomeFile = "Boleto_".$this->getRequest()->getParam('identificador').".pdf";
		$nomeFile = "Boleto_".$identificador.".pdf";

		$xml = "
		    <BaixarBoletoCobranca xmlns=\"http://ws.nobre.com.br/\">
		      <identificador>
		        <descricao>".$identificador."</descricao>
		      </identificador>
		    </BaixarBoletoCobranca>";

		$soapaction = "http://ws.nobre.com.br/BaixarBoletoCobranca";
		$mysoapmsg = $this->soapClient->serializeEnvelope( $xml );
		$response = $this->soapClient->send( $mysoapmsg, $soapaction );

		if($response['BaixarBoletoCobrancaResult']){
		    $arConteudo = explode(";", $response['BaixarBoletoCobrancaResult']);
		    $count = 0;
		    $str = "";
		    while($count < count($arConteudo)){
		        $str .= chr($arConteudo[$count]);
		        $count++;
		    }
			$file = fopen(APPLICATION_PATH."/upload_files/boletos/{$nomeFile}", "w+");
		    fwrite($file, $str);
		    fclose($file);

		    if(file_exists(APPLICATION_PATH."/upload_files/boletos/{$nomeFile}")){
				$this->_redirect("/agronet/file/view/path/boletos/name/{$nomeFile}");
		    }
		}
	}

	public function removerboletoprorrogacaoAction()
	{
		$this->isAjax();
		$params = $this->getRequest()->getParams();
		$return = ['status' => true, 'message' => 'Boleto removido com sucesso'];

		try {
			if (empty($params['id_proposta'])) {
				throw new Exception("Proposta não informada.");
			}

			if (!filter_var($params['id_proposta'], FILTER_VALIDATE_INT)) {
				throw new Exception("ID da proposta inválido.");
			}

			if (empty($params['nr_parcela'])) {
				throw new Exception("Proposta não informada.");
			}

			if (!filter_var($params['nr_parcela'], FILTER_VALIDATE_INT)) {
				throw new Exception("Número da parcela inválido.");
			}

			if (!empty($params['id_versao']) && !filter_var($params['id_versao'], FILTER_VALIDATE_INT)) {
				throw new Exception("ID da versão inválido.");
			}

			$modelPropostasBoletosProrrogacoes = new Seguro_Model_PropostasBoletosProrrogacoes();
			$parcela = $modelPropostasBoletosProrrogacoes->getByPropostaParcela(
				(int) $params['id_proposta'],
				(int) $params['nr_parcela'],
				!empty($params['id_versao']) ? (int) $params['id_versao'] : null
			);

			if (empty($parcela)) {
				throw new Exception("Não foi possível buscar a parcela.");
			}

			if (empty($parcela['ds_nome_arquivo'])) {
				throw new Exception("Não há arquivo cadastrado para essa parcela.");
			}

			$arquivo = APPLICATION_PATH."/upload_files/boletos/{$parcela['ds_nome_arquivo']}";

			if (!unlink($arquivo)) {
				throw new Exception("Erro ao excluir o arquivo.");
			}

		} catch (\Throwable $th) {
			$return['status'] = false;
			$return['message'] = $th->getMessage();
		}

		$this->getResponse()->setBody(Zend_Json::encode($return));
	}

	// Remove boletos quando dá problema atendimento (lentidão ESSOR)
	public function removerboletoAction() {
		$return['status'] = false;
		$return['message'] = "Erro ao excluir boleto.";

		$sanitizedPath = APPLICATION_PATH."/upload_files/boletos/{$this->getRequest()->getParam('boleto')}";

		if (file_exists($sanitizedPath) && unlink($sanitizedPath)) {
			$return['status'] = true;
			$return['message'] = "Boleto removido com sucesso.";
		}

		$this->getResponse()->setBody(Zend_Json::encode($return));
	}

	public function gerarboletoAction($id_proposta_seguradora="", $id_versao="")
  {
      $idProposta = !Agro_Util::filterVariable($this->getRequest()->getParam('id_proposta'))
          ? 0
          : (int)$this->getRequest()->getParam('id_proposta');
    
      $modelProposta = new Seguro_Model_Propostas();
      $proposta = $modelProposta->find($idProposta)->current();

      $id_proposta_seguradora = $proposta->ds_identificador_seguradora;
      $arrParcelas = $proposta->parcelas();

      $nomeFile = "Boleto_" . $idProposta . "_" . $id_proposta_seguradora . ".pdf";

      if (file_exists(APPLICATION_PATH . "/upload_files/boletos/{$nomeFile}")) {
          $this->_redirect("/agronet/file/view/path/boletos/name/{$nomeFile}");
      }

      $xml = "<i4proerp>";
      $xml .= "<obter_relatorio_pdf id_relatorio='20' id_endosso='{$id_proposta_seguradora}'></obter_relatorio_pdf>";
      $xml .= "</i4proerp>";

      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);
      }

      $mysoapmsg = $client->serializeEnvelope($xml);
      $params = array('Servico' => 'ObterRelatorioPDF', 'conteudoXML' => $mysoapmsg);

      $dtEnvio = date('Y-m-d H:i:s');
      $result = $client->call('Executar', array($params));
      $dtRetorno = date('Y-m-d H:i:s');

      if ($client->getError()) {
          $return['status'] = false;

          $modelProposta->gravaLogTransmissao(
              array(
                  'id_proposta' => $idProposta,
                  'ds_retorno' => utf8_encode($client->getError()),
                  'fl_sucesso' => 'F',
                  'ds_tipo_transmissao' => 'ObterRelatorioPDF (Boletos)',
                  'ds_xml_transmissao' => $mysoapmsg,
                  'dt_envio' => $dtEnvio,
                  'dt_retorno' => $dtRetorno
              )
          );
      } else {
          if ($result['ExecutarResult']) {
              //ATUALIZA INFORMACOES DOS BOLETOS
              $xml = "<i4proerp>";
              $xml .= "<consulta_parcela id_endosso='" . $id_proposta_seguradora . "'></consulta_parcela>";
              $xml .= "</i4proerp>";
              $mysoapmsg = $client->serializeEnvelope($xml);
              $params = array('Servico' => 'ConsultarParcela', 'conteudoXML' => $mysoapmsg);

              $dtEnvio = date('Y-m-d H:i:s');
              $resultConstula = $client->call('Executar', array($params));
              $dtRetorno = date('Y-m-d H:i:s');

              $result_xml = simplexml_load_string(
                  utf8_encode($resultConstula['ExecutarResult']),
                  'SimpleXMLElement',
                  LIBXML_NOCDATA
              );

              if ($resultConstula['ExecutarResult']) {
                  $return['status'] = true;

                  $boleto = new Default_Model_Boleto();
                  $boleto->removeBoletos($idProposta, $proposta->id_versao);

                  if (is_object($result_xml->proposta->parcela)) {
                      file_put_contents(
                          APPLICATION_PATH . "/upload_files/boletos/{$nomeFile}",
                          base64_decode($result['ExecutarResult'])
                      );

                      foreach ($result_xml->proposta->parcela as $parcela) {
                          if ($boleto->atualizaBoletos(array(
                              'id_proposta' => $idProposta,
                              'nu_boleto' => $parcela->Titulo,
                              'nr_parcela' => $parcela->nr_parcela,
                              'id_versao' => $proposta->id_versao,
                              'vl_total' => $arrParcelas[$parcela->nr_parcela - 1]['vl_total'],
                              'vl_segurado' => $arrParcelas[$parcela->nr_parcela - 1]['vl_segurado'],
                              'vl_subvencao_federal' => $arrParcelas[$parcela->nr_parcela - 1]['vl_subvencao_federal'],
                              'vl_subvencao_estadual' => $arrParcelas[$parcela->nr_parcela - 1]['vl_subvencao_estadual'],
                              'dt_vencimento' => $arrParcelas[$parcela->nr_parcela - 1]['dt_vencimento'],
                              'fl_pago' => ((!$parcela->Pago || $parcela->Pago == 'Não') ? 0 : 1),
                              'vl_pago' => $parcela->Valor_recebido
                          ))) {
                              $return['status'] = true;

                              $modelProposta->gravaLogTransmissao(
                                  array(
                                      'id_proposta' => $idProposta,
                                      'ds_retorno' => 'Boleto gerado com sucesso.',
                                      'fl_sucesso' => 't',
                                      'ds_tipo_transmissao' => 'ObterRelatorioPDF (Boletos)',
                                      'ds_xml_transmissao' => $mysoapmsg,
                                      'dt_envio' => $dtEnvio,
                                      'dt_retorno' => $dtRetorno
                                  )
                              );
                          } else {
                              $return['status'] = false;
                          }
                      }
                  } else {
                      $return['status'] = false;

                      $modelProposta->gravaLogTransmissao(
                          array(
                              'id_proposta' => $idProposta,
                              'ds_retorno' => 'Erro ao gerar boletos (lote)',
                              'fl_sucesso' => 'f',
                              'ds_tipo_transmissao' => 'ObterRelatorioPDF (Boletos)',
                              'ds_xml_transmissao' => $mysoapmsg,
                              'dt_envio' => $dtEnvio,
                              'dt_retorno' => $dtRetorno
                          )
                      );
                  }
              } else {
                  $return['status'] = false;
              }
          }
      }

      $this->getResponse()->setBody(Zend_Json::encode($return));
  }

	public function gerarboletoindividualAction()
  {
      $idProposta = !Agro_Util::filterVariable($this->getRequest()->getParam('id_proposta'))
          ? 0
          : (int)$this->getRequest()->getParam('id_proposta');

      $numeroParcela = !Agro_Util::filterVariable($this->getRequest()->getParam('nr_parcela'))
          ? 0
          : (int)$this->getRequest()->getParam('nr_parcela');

      $modelProposta = new Seguro_Model_Propostas();
      $proposta = $modelProposta->find($idProposta)->current();

      $id_proposta_seguradora = $proposta->ds_identificador_seguradora;
      $id_versao = $proposta->id_versao;

      $xml = "<i4proerp>";
      $xml .= "<obter_relatorio_pdf id_relatorio='20' nr_parcela='{$numeroParcela}'";
      $xml .= "                     id_endosso='{$id_proposta_seguradora}'>";
      $xml .= "</obter_relatorio_pdf>";
      $xml .= "</i4proerp>";

      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);
      }

      $mysoapmsg = $client->serializeEnvelope($xml);
      $params = array('Servico' => 'ObterRelatorioPDF', 'conteudoXML' => $mysoapmsg);

      $dtEnvio = date('Y-m-d H:i:s');
      $result = $client->call('Executar', array($params));
      $dtRetorno = date('Y-m-d H:i:s');

      if ($result['ExecutarResult']) {
          $nomeFile = "Boleto_" . $id_versao . "_" . $numeroParcela . ".pdf";
          file_put_contents(
              APPLICATION_PATH . "/upload_files/boletos/{$nomeFile}",
              base64_decode($result['ExecutarResult'])
          );
          $return['status'] = true;

          $modelProposta->gravaLogTransmissao(
              array(
                  'id_proposta' => $idProposta,
                  'ds_retorno' => 'Boleto gerado com sucesso.',
                  'fl_sucesso' => 't',
                  'ds_tipo_transmissao' => 'ObterRelatorioPDF (Boletos)',
                  'ds_xml_transmissao' => $mysoapmsg,
                  'dt_envio' => $dtEnvio,
                  'dt_retorno' => $dtRetorno
              )
          );
      }

      $this->getResponse()->setBody(Zend_Json::encode($return));
  }
	
	public function reapresentarboletoAction()
  {
      $this->isAjax();
      $return = [
          'status' => true,
          'message' => 'Prorrogação de parcela efetuada com sucesso!',
          'confirm' => false,
          'id_proposta' => '',
          'nr_parcela' => '',
      ];

      try {
          $requestParams = $this->getRequest()->getParams();
          $this->validarRequestReapresentarBoleto($requestParams);

          $return['id_proposta'] = $requestParams['id_proposta'];
          $return['nr_parcela'] = $requestParams['nr_parcela'];

          $modelProposta = new Seguro_Model_Propostas();
          $proposta = $modelProposta->find($requestParams['id_proposta'])->current();

          if (Sistema_Model_Usuarios::usuarioLogadoFuncionarioAgro()) {
              $this->validacoesUsuariosAgro($requestParams, $proposta);
          } elseif (Sistema_Model_Usuarios::isUsuarioLogadoCorretorPreposto()) {
              $parcela = $this->getParcelaAtualizada($requestParams['nr_parcela'], $proposta);

              $requestParams['dt_vencimento'] = $this->calcularDataVencimento($parcela['nr_parcela']);
              $requestParams['vl_multa'] = $this->calcularMulta($parcela['vl_segurado']);
              $requestParams['vl_juros'] = $this->calcularJuros(
                  $parcela['vl_segurado'],
                  $parcela['dt_vencimento'],
                  $requestParams['dt_vencimento']
              );
              $requestParams['vl_total'] = $this->calcularTotal(
                  $parcela['vl_segurado'],
                  $requestParams['vl_multa'],
                  $requestParams['vl_juros']
              );

              $requestParams['numero_endosso'] = $proposta->nr_endosso();

              $this->validacoesUsuariosCorretoresPrepostos($requestParams, $proposta, $parcela);
          } else {
              throw new Exception("Ação não permitida para este usuário.", 99);
          }

          $return = $this->reapresentaParcela($requestParams, $proposta);

      } catch (\Throwable $th) {

          //$errorCode 0 e 1    - Abrem chamado
          //$errorCode 2, 3 e 4 - Perguntam se deseja abrir chamado
          //$errorCode 3 e 4    - Se respondido sim na confirm, abre um chamado diferente dos demais
          //$errorCode 99       - Só exibe a mensagem pro usuário
          $errorCode = $th->getCode();
          $return['status'] = false;
          $return['message'] = $th->getMessage();
          $return['confirm'] = in_array($errorCode, [2, 3, 4]);
          $return['error_code'] = $errorCode;

          if ($errorCode != 99) {

              $modelChamado = new Atendimento_Model_Chamado();
              $rs = $modelChamado->fetchAll([
                  "id_parent is null",
                  "id_proposta = {$requestParams['id_proposta']}",
                  "id_tipo_chamado = " . Atendimento_Model_TipoChamado::TECNICA_PROR_PARC,
                  "id_status <> " . Atendimento_Model_Chamado::ID_STATUS_RESOLVIDO
              ])->toArray();

              if (!empty($rs)) {
                  $return['error_code'] = 99;
                  $return['message'] = "Seu pedido de prorrogação será analisado pela Seguradora, um chamado já foi aberto, favor acompanhar o retorno no chamado.";
              }
          }
      }

      $this->getResponse()->setBody(Zend_Json::encode($return));
  }

	/**
	 * Atualiza todas as parcelas da propostas(e seus endossos) e retorna a parcela atualizada
	 *
	 * @param int $nrParcela
	 * @param Seguro_Model_Row_Proposta $proposta
	 * @return array
	 */
	private function getParcelaAtualizada(int $nrParcela, Seguro_Model_Row_Proposta $proposta): array
	{
		$this->consultarTodasParcelasPendentes($proposta);
		$parcela = $proposta->parcelas($nrParcela);

		if (empty($parcela)) {
			throw new Exception("Erro ao buscar a parcela.", 99);
		}

		return $parcela[0];
	}

	/**
	 * Calcula a data de vencimento de acordo com a parcela informada
	 *
	 * @param int $nrParcela
	 * @return string
	 */
	private function calcularDataVencimento(int $nrParcela): string
	{
		$quantidadeDias = $nrParcela === 1 ? 5 : 7;
		$dtHoje = date('Y-m-d');
		return date('d/m/Y', strtotime($dtHoje. " + {$quantidadeDias} days"));
	}

	/**
	 * Calcula o valor da multa que deve ser aplicado
	 *
	 * @param string $vlSegurado
	 * @return string
	 */
	private function calcularMulta(string $vlSegurado): string
	{
		$vlSeguradoFormatado = Agro_Util::formatCurrencyDb($vlSegurado) * 0.02;
		return $vlSeguradoFormatado > 11 ? '11,00' : Agro_Util::formatDbCurrency($vlSeguradoFormatado);
	}

	/**
	 * Retorna o valor do juros calculado
	 * Cálculo: 1% * ((Novo Vencimento - Vencimento original)/30) * Parcela
	 *
	 * @param string $vlSegurado
	 * @param string $dtVencimentoOriginal
	 * @param string $dtVencimentoNovo
	 * @return string
	 */
	private function calcularJuros(string $vlSegurado, string $dtVencimentoOriginal, string $dtVencimentoNovo): string
	{
		$vlSegurado = Agro_Util::formatCurrencyDb($vlSegurado);
		$dtVencimentoOriginal = new DateTime(Agro_Util::formatDate($dtVencimentoOriginal, Zend_Date::W3C));
		$dtVencimentoNovo = new DateTime(Agro_Util::formatDate($dtVencimentoNovo, Zend_Date::W3C));
		$intervalo = $dtVencimentoNovo->diff($dtVencimentoOriginal);

		$calculo = (($intervalo->days/30) * $vlSegurado) * 0.01;
		return Agro_Util::formatDbCurrency($calculo);
	}

	/**
	 * Retorna o total da soma do valor do segurado + multa + juros
	 *
	 * @param string $vlSegurado
	 * @param string $vlMulta
	 * @param string $vlMulta
	 * @return string
	 */
	private function calcularTotal(string $vlSegurado, string $vlMulta, string $vlJuros): string
	{
		$vlSegurado = Agro_Util::formatCurrencyDb($vlSegurado);
		$vlMulta = Agro_Util::formatCurrencyDb($vlMulta);
		$vlJuros = Agro_Util::formatCurrencyDb($vlJuros);

		$total = $vlSegurado + $vlMulta + $vlJuros;
		return Agro_Util::formatDbCurrency($total);
	}

	/**
	 * Valida se os dados da request estão corretos
	 */
	private function validarRequestReapresentarBoleto(array &$requestParams): void
	{
		if (empty($requestParams['id_proposta'])) {
			throw new Exception("Proposta não informada.", 99);
		}

		if (!filter_var($requestParams['id_proposta'], FILTER_VALIDATE_INT)) {
			throw new Exception("ID da proposta inválido.", 99);
		}

		if (empty($requestParams['nr_parcela'])) {
			throw new Exception("Parcela não informada.", 99);
		}

		if (!filter_var($requestParams['nr_parcela'], FILTER_VALIDATE_INT)) {
			throw new Exception("Número da parcela da proposta inválido.", 99);
		}

		if (Sistema_Model_Usuarios::usuarioLogadoFuncionarioAgro() && empty($requestParams['dt_vencimento'])) {
			throw new Exception("Data de vencimento não informada.", 99);
		}

		$requestParams['id_proposta'] = (int) $requestParams['id_proposta'];
		$requestParams['nr_parcela'] = (int) $requestParams['nr_parcela'];
	}

	/**
	 * Aplica as validações para o usuário Agro para permitir ou não a prorrogação da parcela
	 *
	 * @param array $params
	 * @param Seguro_Model_Row_Proposta $proposta
	 */
	private function validacoesUsuariosAgro(array $requestParams, Seguro_Model_Row_Proposta $proposta): void
	{
		$dtVigenciaFim = Agro_Util::formatDate($proposta->dt_vigencia_fim, 'dd/MM/Y');

		if (!Agro_Util::validaDataInicioFim($requestParams['dt_vencimento'], $dtVigenciaFim)) {
			throw new Exception("Atenção! A data de vencimento ({$requestParams['dt_vencimento']}) informada é superior a data de vigência final ({$dtVigenciaFim}) da apólice.", 99);
		}
	}

	/**
	 * Aplica as validações para os usuários Corretores e Prepostos para permitir ou não a prorrogação da parcela
	 *
	 * @param array $params
	 * @param Seguro_Model_Row_Proposta $proposta
	 */
	private function validacoesUsuariosCorretoresPrepostos(array $requestParams, Seguro_Model_Row_Proposta $proposta, array $parcela): void
	{
		$this->validarParcelaPaga($parcela);
		$this->validarDataVencimentoAtual($parcela);
		$this->validarCoberturaTecnica($requestParams);
		$this->validarTentativaPrimeiraParcela($proposta, $requestParams['nr_parcela']);
		$this->validarAvisoSinistro($requestParams['id_proposta']);
	}

	/**
	 * Consulta e atualiza todas as parcelas pendentes de todos os endossos
	 *
	 * @param Seguro_Model_Row_Proposta $idProposta
	 */
	private function consultarTodasParcelasPendentes(Seguro_Model_Row_Proposta $proposta): void
	{
		$modelPropostaParcelas = new Seguro_Model_PropostasParcelas();
		$modelPropostaParcelas->consultarTodasParcelasEssor($proposta, true);
	}

	/**
	 * Valida se a parcela ainda possui um vencimento possível de efeturar o pagamento
	 * Se a data de vencimento + 5 dias >= data de hoje = erro
	 *
	 * @param array $parcela
	 */
	private function validarDataVencimentoAtual(array $parcela): void
	{
		$dtHoje = date("d/m/Y");
		$dtVencimentoAtual = Agro_Util::somarData($parcela['dt_vencimento'], 0, 0, 5);
		$dtVencimentoAtual = Agro_Util::formatDate($dtVencimentoAtual, 'dd/MM/Y');

		if (Agro_Util::validaDataInicioFim($dtHoje, $dtVencimentoAtual)) {
			throw new Exception("Não é possível atualizar o boleto, pois ainda é possível efetuar o pagamento do boleto original desta parcela.", 99);
		}
	}

	/**
	 * Valida se possui cobertura técnica
	 * (considera o cálculo utilizado para gerar o relatório da 2027 - coluna "Final de Cobertura Técnica")
	 * Se a data de "hoje" for maior que a data calculada = erro
	 *
	 * @param $requestParams
	 */
	private function validarCoberturaTecnica(array $requestParams): void
  {
      $dtHoje = date("d/m/Y");
      $dataInicioEstimadoCobertura = $dtFinalCoberturaTecnica = null;

      $rs = (new Relatorio_Model_Tecnica())->inicioCobertura([
          'id_proposta' => $requestParams['id_proposta'],
          'nr_parcela' => $requestParams['nr_parcela']
      ]);

      if (!empty($rs)) {
          $parametrosCalculoCoberturaTecnica = new Agro_ParameterObject_CalculoCoberturaTecnica(
              new Zend_Date($rs[0]['inicio_cobertura'], 'dd/MM/Y'),
              new Zend_Date($rs[0]['dt_vigencia_inicio_original'], 'dd/MM/Y'),
              new Zend_Date($rs[0]['dt_vigencia_fim'], 'dd/MM/Y'),
              new Zend_Date($rs[0]['dt_vencimento'], 'dd/MM/Y'),
              (float)$rs[0]['valor_segurado'],
              (float)$rs[0]['premio_pago_segurado']
          );

          $resultado = Agro_CalculoCoberturaTecnica::calcula($parametrosCalculoCoberturaTecnica);

          if (!empty($resultado['dataFinalCoberturaTecnica'])) {
              $dtFinalCoberturaTecnica = ($resultado['dataFinalCoberturaTecnica'])->get('dd/MM/Y');
          }

          if (!empty($resultado['dataInicioEstimadoCobertura'])) {
              $dataInicioEstimadoCobertura = ($resultado['dataInicioEstimadoCobertura'])->get('dd/MM/Y');
          }
      }

      if (
          	(int) $requestParams['numero_endosso'] === 0
			&& $requestParams['nr_parcela'] == 1
        	&& Agro_Util::contarDiasEntreDatas($dtHoje, $dataInicioEstimadoCobertura) >= 0
      ) {
          $mensagem = "Não foi possível a prorrogação, pois esta proposta está em lista de cancelamento por falta de";
          $mensagem .= " pagamento da 1ª parcela. Deseja solicitar a análise desta prorrogação?";
          throw new Exception($mensagem, 4);
      }

      if (!Agro_Util::validaDataInicioFim($dtHoje, $dtFinalCoberturaTecnica)) {
          throw new Exception("Não foi possível prorrogação da parcela devido ao Término da Cobertura Técnica, deseja solicitar análise desta prorrogação?", 3);
      }
  }

	/**
	 * Valida se a parcela já consta como paga
	 *
	 * @param array $parcela
	 */
	private function validarParcelaPaga(array $parcela): void
	{
		if ($parcela['fl_pago']) {
			throw new Exception("Não é possível prorrogar a parcela {$parcela['nr_parcela']} pois a mesma já consta como paga.", 99);
		}
	}

	/**
	 * Valida se já houve prorrogação da primeira parcela do endosso 0
	 *
	 * @param Seguro_Model_Row_Proposta $proposta
	 * @param int $nrParcela
	 */
	private function validarTentativaPrimeiraParcela(Seguro_Model_Row_Proposta $proposta, int $nrParcela): void
	{
		//Se for a primeira parcela do endosso 0
		if ($nrParcela == 1 && $proposta['id'] == $proposta['id_proposta_mae']) {

			$modelPropostasBoletosProrrogacoes = new Seguro_Model_PropostasBoletosProrrogacoes();
			$query = $modelPropostasBoletosProrrogacoes->getData("id_proposta = {$proposta['id']} AND nr_parcela = {$nrParcela}");
			$rs = $modelPropostasBoletosProrrogacoes->fetchAll($query)->toArray();

			if (!empty($rs)) {
				throw new Exception("Não foi possível prorrogação pois esta proposta está em lista de cancelamento por falta de pagamento da 1ª parcela, deseja solicitar análise desta prorrogação?", 2);
			}
		}
	}

	/**
	 * Valida se há aviso de sinistro para a proposta
	 *
	 * @param int $idProposta
	 */
	private function validarAvisoSinistro(int $idProposta): void
	{
		$modelAvisoSinistro = new Sinistro2_Model_AvisosSinistro();
		$avisos = $modelAvisoSinistro->getAvisosByProposta($idProposta);

		if (!empty($avisos)) {
			throw new Exception("Não foi possível gerar o boleto solicitado, mas seu pedido de prorrogação já está em análise pela Seguradora, um chamado foi aberto, favor acompanhar o retorno no chamado.", 1);
		}
	}

	/**
	 * Executa a chamada ReapresentaParcela(prorrogação de parcelas) para Essor
	 *
	 * @param array $requestParams
	 * @param Seguro_Model_Row_Proposta $proposta
	 * @return array
	 */
	private function reapresentaParcela(array $requestParams, Seguro_Model_Row_Proposta $proposta): array
	{
		$return = [
			'status' => false,
			'message' => 'Erro transmissão Seguradora 1.',
			'confirm' => false,
			'id_proposta' => $requestParams['id_proposta'],
			'nr_parcela' => $requestParams['nr_parcela'],
			'error_code' => 99
		];
		$modelProposta = new Seguro_Model_Propostas();
		$modelPropostaBoleto = new Seguro_Model_PropostaBoleto();
		$nu_boleto_reapresentado = $modelPropostaBoleto->getNumeroBoletoReapresentado($requestParams['id_proposta'], $requestParams['nr_parcela']);
		$nu_boleto = (!$nu_boleto_reapresentado) ? $requestParams['nu_boleto'] : $nu_boleto_reapresentado;
	        
		if($proposta->nr_apolice){
			$registraDataEnvio = "0";
		} else {
			$registraDataEnvio = "1";
		}
	        
		$xml = "
		<ReapresentaParcela>
			<reapresentar>
				<idEndosso>".$proposta->ds_identificador_seguradora."</idEndosso>
				<cdApolice>".$proposta->nr_apolice."</cdApolice>
				<cdFormaRecebimento>16</cdFormaRecebimento>
				<nrParcela>".$requestParams['nr_parcela']."</nrParcela>
				<nrTitulo>".$nu_boleto."</nrTitulo>
				<dtVencimento>".$this->formataData($requestParams['dt_vencimento'])."</dtVencimento>
				<vlTarifario>".Agro_Util::formatCurrencyDb($requestParams['vl_segurado'])."</vlTarifario>
				<vlIof>0</vlIof>
				<vlCusto>0</vlCusto>
				<vlMulta>".Agro_Util::formatCurrencyDb($requestParams['vl_multa'])."</vlMulta>
				<vlJuros>".Agro_Util::formatCurrencyDb($requestParams['vl_juros'])."</vlJuros>
				<vlTotal>".Agro_Util::formatCurrencyDb($requestParams['vl_total'])."</vlTotal>
				<instrucaoBancaria></instrucaoBancaria>
				<Pagador>0</Pagador>
				<GerarNovoNrCobranca>1</GerarNovoNrCobranca>
				<EnviarValorRemessa>1</EnviarValorRemessa>
				<RegistraDataEnvio>".$registraDataEnvio."</RegistraDataEnvio>
			</reapresentar>
		</ReapresentaParcela>
		";

		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);
		}
	        
		$mysoapmsg  = $client->serializeEnvelope($xml);
		$params     = array('Servico' => 'ReapresentacaoParcelas', 'conteudoXML' => $mysoapmsg);

		$dtEnvio = date('Y-m-d H:i:s');
		$result     = $client->call('ExecutarRow', array($params));
		$dtRetorno = date('Y-m-d H:i:s');
		 
		if ($client->getError()) {
			$return['status'] = false;
			$modelProposta->gravaLogTransmissao(
				array(
					'id_proposta'         => $requestParams['id_proposta'],
					'ds_retorno'          => $client->getError(),
					'fl_sucesso'          => 'f',
					'ds_tipo_transmissao' => 'ReapresentacaoParcelas',
					'ds_xml_transmissao'  => $mysoapmsg,
					'dt_envio'            => $dtEnvio,
					'dt_retorno'          => $dtRetorno
				)
				);
			
		} else {
			$result_xml = simplexml_load_string(utf8_encode($result['ExecutarRowResult']), 'SimpleXMLElement', LIBXML_NOCDATA);
		        
			if(($result_xml->cd_retorno > 0) || ($result_xml->erro->attributes()->cd_retorno > 0)) {
				$modelProposta->gravaLogTransmissao(
					array(
						'id_proposta'        => $requestParams['id_proposta'],
						'ds_retorno'         => $result_xml->nm_retorno != '' ? $result_xml->nm_retorno : $result_xml->erro->attributes()->nm_retorno,
						'fl_sucesso'         => 'f',
						'ds_tipo_transmissao' => 'ReapresentacaoParcelas',
						'ds_xml_transmissao' => $mysoapmsg,
						'dt_envio'            => $dtEnvio,
						'dt_retorno'          => $dtRetorno
					)
				);

				$return['status'] = false;
			} else {
				$return['status'] = true;
				$return['message'] = "Prorrogação de parcela efetuada com sucesso!";
				
				$modelProposta->gravaLogTransmissao(
					array(
						'id_proposta'         => $requestParams['id_proposta'],
						'ds_retorno'          => 'Boleto reapresentado com sucesso.',
						'fl_sucesso'          => 't',
						'ds_tipo_transmissao' => 'ReapresentacaoParcelas (Boletos)',
						'ds_xml_transmissao'  => $mysoapmsg,
						'dt_envio'            => $dtEnvio,
						'dt_retorno'          => $dtRetorno
					)
					);
				
				$xml = "<i4proerp><obter_relatorio_pdf id_relatorio='20' nr_parcela='".$requestParams['nr_parcela']."' id_endosso='".$proposta->ds_identificador_seguradora."'></obter_relatorio_pdf></i4proerp>";
				
				$mysoapmsg  = $client->serializeEnvelope($xml);
				$params     = array('Servico' => 'ObterRelatorioPDF', 'conteudoXML' => $mysoapmsg);

				$dtEnvio = date('Y-m-d H:i:s');
				$result     = $client->call('Executar', array($params));
				$dtRetorno = date('Y-m-d H:i:s');
	                
				if($result['ExecutarResult']) {
					$nomeFile = "Boleto_".$proposta->id_versao."_".$requestParams['nr_parcela']."_REAPRESENTACAO_".time().".pdf";
					
					$modelBoleto = new Default_Model_Boleto();
					if($modelBoleto->insereProrrogacao(array(
						'id_proposta'           => $requestParams['id_proposta'],
						'nu_boleto'             => $result_xml->nr_cobranca,
						'nr_parcela'            => $requestParams['nr_parcela'],
						'id_versao'             => $proposta->id_versao,
						'vl_total'              => Agro_Util::formatCurrencyDb($requestParams['vl_total']),
						'vl_segurado'           => Agro_Util::formatCurrencyDb($requestParams['vl_segurado']),
						'vl_juros'              => Agro_Util::formatCurrencyDb($requestParams['vl_juros']),
						'vl_multa'              => Agro_Util::formatCurrencyDb($requestParams['vl_multa']),
						'dt_vencimento'         => $requestParams['dt_vencimento'],
						'ds_nome_arquivo'       => $nomeFile
					))){
						
						file_put_contents(APPLICATION_PATH."/upload_files/boletos/{$nomeFile}", base64_decode($result['ExecutarResult']));
						$return['status'] = true;
						
						$modelProposta->gravaLogTransmissao(
							array(
								'id_proposta'         => $requestParams['id_proposta'],
								'ds_retorno'          => 'Boleto gerado com sucesso.',
								'fl_sucesso'          => 't',
								'ds_tipo_transmissao' => 'ObterRelatorioPDF (Boletos)',
								'ds_xml_transmissao'  => $mysoapmsg,
								'dt_envio'            => $dtEnvio,
								'dt_retorno'          => $dtRetorno
							)
						);
						
						$return['redirect'] = "/agronet/file/view/path/boletos/name/{$nomeFile}";
					}
				}
			}
		}

		return $return;
	}
	
	public function propostaAction()
  {
      $model = new Seguro_Model_PropostaPrint();
      $config = Zend_Registry::get('config');

      $idProposta = !Agro_Util::filterVariable($this->getRequest()->getParam('id_proposta'))
          ? 0
          : (int)$this->getRequest()->getParam('id_proposta');

      try {
          $proposta = (new Seguro_Model_Propostas())->find($idProposta)->current();
          $produto = $proposta->produto();

          if ($produto['ds_nome_fantasia'] == 'ESSOR SEGUROS') {
              $this->gerarboletoAction($proposta->ds_identificador_seguradora);
          } else {
              $this->soapClient = new nusoap_client($config['webservice']['wsdl']);

              // Monta o XML que vai ser enviado pelo SOAP
              $xml = $this->getXml($model->getProposta($idProposta));
              $xml = $this->soapClient->serializeEnvelope(utf8_decode($xml));

              $response = $this->soapClient->send($xml, $config['webservice']['soapaction']);
          }

          if ($response['boletoPA']['identificador']['descricao']) {
              $saveBoleto = (new Default_Model_Boleto())->save(array(
                  'ds_identificador' => $response['boletoPA']['identificador']['descricao'],
                  'id_proposta' => $idProposta,
                  'nu_boleto' => $response['boletoPA']['numeroDocumento'],
                  'nr_parcela' => 1,
                  'id_versao' => $proposta->id_versao
              ));

              if ($saveBoleto) {
                  $url = "/default/gerarboleto/baixarBoleto/identificador/";
                  $url .= $response['boletoPA']['identificador']['descricao'];

                  $return = array(
                      'numero' => $response['boletoPA']['identificador']['descricao'],
                      'url' => $url,
                      'status' => true
                  );
              } else {
                  $this->geraSalvaXml($idProposta, $this->soapClient);
                  $return = array('status' => false);
              }
          } else {
              $this->geraSalvaXml($idProposta, $xml);
              $return = array('status' => false);
          }
      } catch (Exception $e) {
          $this->geraSalvaXml($idProposta, $this->soapClient);
          die($e);
      }

      $this->getResponse()->setBody(Zend_Json::encode($return));
  }

	public function geraSalvaXml(int $idProposta, $soap)
  {
      $file = fopen(APPLICATION_PATH . "/upload_files/xml_transmissao_error/{$idProposta}_soap.txt", "w");
      fwrite($file, $soap);
  }

	private function getXml($dados) {
		ob_start();

		$subProduto = $dados['produto']['cd_produto_seguradora'];

		// Subproduto específico para AURORA (pasq.aurora e agrorural.aurora)
		if($dados['id_usuario_criacao'] == 780 || $dados['id_usuario_criacao'] == 1298){
			switch($dados['produto']['id_produto_geral']){
				//Ameixa
				case 4:	$subProduto = 44; break;
				//Caqui
				case 13: $subProduto = 45; break;
				//Pêssego
				case 36: $subProduto = 50; break;
				default:  $subProduto = 51;
			}
		}

		// Subproduto específico para FISCHER (coalizao.fischer)
		if($dados['id_usuario_criacao'] == 1449){
			$subProduto = 37;
		}

        $numeroDocumento = $dados['proponente']['ds_documento_numero'];
        $orgaoExpedidor = 'SSP';
        $dataOrgaoExpedicao = $dados['proponente']['dt_documento_exp'];
        $tipoDocumento = 'RG';
        $estadoExpedicaoDocumento = 'RS';
        
        if ($dados['proponente']['ds_documento_numero'] == '') {
            $numeroDocumento = '';
            $orgaoExpedidor = '';
            $dataOrgaoExpedicao = '';
            $tipoDocumento = '';
            $estadoExpedicaoDocumento = '';
        }

		$dataAux = !empty($dados['dt_transmissao']) ? $dados['dt_transmissao'] : $dados['dt_criacao'];

		$aplicarNovaLeiSeguro = strtotime($dataAux) >= strtotime(DATA_INICIO_NOVA_LEI_SEGURO)
			|| $dados['id_status'] == Seguro_Enum_PropostaStatus::ID_NAO_ENVIADA;

		?>
		<EmitirBoletoHsbcPA xmlns="http://ws.nobre.com.br/">
			<boletoPA xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
				<dataVencimento><?=$dados['cobranca']['parcelamento'][1]['dt_vencimento'];?></dataVencimento>
				<vigencia>
					<dataInicio><?=$dados['dt_vigencia_inicio'];?></dataInicio>
					<dataFim><?=$dados['dt_vigencia_fim'];?></dataFim>
				</vigencia>
				<valorCobrado><?=$dados['cobranca']['parcelamento'][1]['vl_segurado'];?></valorCobrado>
				<valorMoraMulta>0</valorMoraMulta>
				<dataDocumento><?=date('Y-m-d');?></dataDocumento>
				<dataProcessamento><?=date('Y-m-d');?></dataProcessamento>
				<valorDocumento><?=$dados['cobranca']['parcelamento'][1]['vl_segurado'];?></valorDocumento>
				<sacado>
					<tipo><?=($dados['proponente']['tp_pessoa'] == 'F' ? 'Fisica' : 'Juridica');?></tipo>
					<nome><?=$dados['proponente']['ds_nome_proponente'];?></nome>

					<? if ($dados['proponente']['tp_pessoa'] == 'F') { ?>
						<detalhe xsi:type="DetalhePessoaFisica">
							<cpf><?=preg_replace('([^0-9])', '', $dados['proponente']['cpf_cnpj']);?></cpf>
							<IsCPFProprio>true</IsCPFProprio>
							<dataNascimento><?=$dados['proponente']['dt_nascimento'];?></dataNascimento>
							<genero></genero>
							<estadoCivil><? echo $aplicarNovaLeiSeguro
								? 'Não informado'
								: ucfirst(strtolower($dados['proponente']['ds_nome_estado_civil']));?>
							</estadoCivil>
							<documentoIdentificacao>
								<orgaoExpedidor>
									<sigla><?php echo $orgaoExpedidor; ?></sigla>
								</orgaoExpedidor>
								<numero><?php echo $numeroDocumento; ?></numero>
								<dataExpedicao><?php echo $dataOrgaoExpedicao; ?></dataExpedicao>
								<estado>
									<uf><?php echo $estadoExpedicaoDocumento; ?></uf>
								</estado>
								<tipo><?php echo $tipoDocumento; ?></tipo>
							</documentoIdentificacao>
						</detalhe>
					<? } else { ?>
						<detalhe xsi:type="DetalhePessoaJuridica">
							<cnpj><?=preg_replace('([^0-9])', '', $dados['proponente']['cpf_cnpj']);?></cnpj>
							<nomeFantasia><?=$dados['proponente']['ds_nome_proponente'];?></nomeFantasia>
						</detalhe>
					<? } ?>

					<enderecos>
						<endereco>
							<numero><?=$dados['proponente']['ds_endereco_nro'];?></numero>
							<complemento />
							<logradouro>
								<nome><?=$dados['proponente']['ds_endereco_rua'];?></nome>
								<cep><?=preg_replace('([^0-9])', '', $dados['proponente']['ds_endereco_cep']);?></cep>
								<bairro>
									<localidade>
										<codigo>0</codigo>
										<nome><?=$dados['proponente']['ds_nome_municipio'];?></nome>
										<estado>
											<codigo>0</codigo>
											<nome><?=$dados['proponente']['ds_nome_estado'];?></nome>
											<uf><?=$dados['proponente']['ds_sigla'];?></uf>
										</estado>
									</localidade>
								</bairro>
								<complemento />
							</logradouro>
							<utilizacoes>
								<utilizacao>Correspondencia</utilizacao>
							</utilizacoes>
						</endereco>
					</enderecos>
					<? if(strlen($dados['corretor']['cpf_cnpj']) == 14) { ?>
						<corretor>
							<tipo>Fisica</tipo>
							<nome />
							<inspetor>
								<codigo>1854</codigo>
							</inspetor>
							<detalhe xsi:type="DetalhePessoaFisica">
								<cpf><?=str_replace('.', '', str_replace('-', '', $dados['corretor']['cpf_cnpj']));?></cpf>
							</detalhe>
						</corretor>
					<? } else { ?>
						<corretor>
							<tipo>Juridica</tipo>
							<nome />
							<inspetor>
								<codigo>1854</codigo>
							</inspetor>
							<detalhe xsi:type="DetalhePessoaJuridica">
								<cnpj><?=str_replace('.', '', str_replace('-', '', str_replace('/', '', $dados['corretor']['cpf_cnpj'])));?></cnpj>
							</detalhe>
						</corretor>
					<? } ?>
				</sacado>
				<valorDescontoAbatimento>0</valorDescontoAbatimento>
				<valorDeducoes>0</valorDeducoes>
				<produto>
					<codigo><?=$dados['produto']['cd_produto_geral_seguradora'];?></codigo>
					<subProduto>
						<codigo><?=$subProduto;?></codigo>
					</subProduto>
				</produto>
			</boletoPA>
		</EmitirBoletoHsbcPA>
		<?
		$xml = ob_get_contents();
		ob_clean();
		return $xml;
	}

	public function formataData( $dtData ){

		$arData = explode( "/", $dtData );

		$ano = $arData[2];
		$mes = $arData[1];
		$dia = $arData[0];
		$dtDataFormatada = $ano.$mes.$dia;

		return $dtDataFormatada;
	}

	public function formataData2( $dtData ){
	
		$arData = explode( "-", $dtData );
	
		$ano = $arData[2];
		$mes = $arData[1];
		$dia = $arData[0];
		$dtDataFormatada = $ano.$mes.$dia;
	
		return $dtDataFormatada;
	}
		
	public function reapresentarboletoloteAction()
  {
      $idProposta = !Agro_Util::filterVariable($this->getRequest()->getParam('id_proposta'))
          ? 0
          : (int)$this->getRequest()->getParam('id_proposta');

      $numeroParcela = !Agro_Util::filterVariable($this->getRequest()->getParam('nr_parcela'))
          ? 0
          : (int)$this->getRequest()->getParam('nr_parcela');
    
      $modelProposta = new Seguro_Model_Propostas();
      $proposta = $modelProposta->find($idProposta)->current();

      $modelPropostaBoleto = new Seguro_Model_PropostaBoleto();
      $boleto = $modelPropostaBoleto->fetchRow("id_proposta = {$idProposta} and  nr_parcela = {$numeroParcela}");

      $this->getRequest()->setParam('nr_parcela', $numeroParcela);
      $this->getRequest()->setParam('vl_segurado', $boleto->vl_segurado);
      $this->getRequest()->setParam('vl_juros', null);
      $this->getRequest()->setParam('vl_multa', null);
      $this->getRequest()->setParam('vl_total', $boleto->vl_segurado);
      $this->getRequest()->setParam('dt_vencimento', $this->getRequest()->getParam('dt_vencimento'));
      $this->getRequest()->setParam('nu_boleto', $boleto->nu_boleto);

      if (1 == 1) {

          $xml = "
			<ReapresentaParcela>
				<reapresentar>
					<idEndosso>" . $proposta->ds_identificador_seguradora . "</idEndosso>
					<cdApolice>" . $proposta->nr_apolice . "</cdApolice>
					<cdFormaRecebimento>16</cdFormaRecebimento>
					<nrParcela>" . $numeroParcela . "</nrParcela>
					<nrTitulo>" . $this->getRequest()->getParam('nu_boleto') . "</nrTitulo>
					<dtVencimento>" . $this->getRequest()->getParam('dt_vencimento') . "</dtVencimento>
					<vlTarifario>" . Agro_Util::formatCurrencyDb($this->getRequest()->getParam('vl_segurado')) . "</vlTarifario>
					<vlIof>0</vlIof>
					<vlCusto>0</vlCusto>
					<vlMulta>" . Agro_Util::formatCurrencyDb($this->getRequest()->getParam('vl_multa')) . "</vlMulta>
					<vlJuros>" . Agro_Util::formatCurrencyDb($this->getRequest()->getParam('vl_juros')) . "</vlJuros>
					<vlTotal>" . Agro_Util::formatCurrencyDb($this->getRequest()->getParam('vl_total')) . "</vlTotal>
					<instrucaoBancaria></instrucaoBancaria>
				</reapresentar>
			</ReapresentaParcela>
			";

          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);
          }

          $mysoapmsg = $client->serializeEnvelope($xml);
          $params = array('Servico' => 'ReapresentacaoParcelas', 'conteudoXML' => $mysoapmsg);

          $dtEnvio = date('Y-m-d H:i:s');
          $result = $client->call('ExecutarRow', array($params));
          $dtRetorno = date('Y-m-d H:i:s');

          if ($client->getError()) {
              $return['status'] = false;
              $modelProposta->gravaLogTransmissao(
                  array(
                      'id_proposta' => $idProposta,
                      'ds_retorno' => $client->getError(),
                      'fl_sucesso' => 'f',
                      'ds_tipo_transmissao' => 'ReapresentacaoParcelas',
                      'ds_xml_transmissao' => $mysoapmsg,
                      'dt_envio' => $dtEnvio,
                      'dt_retorno' => $dtRetorno
                  )
              );
          } else {
              $result_xml = simplexml_load_string(
                  utf8_encode($result['ExecutarRowResult']),
                  'SimpleXMLElement',
                  LIBXML_NOCDATA
              );

              if ($result_xml->erro) {
                  $modelProposta->gravaLogTransmissao(
                      array(
                          'id_proposta' => $idProposta,
                          'ds_retorno' => $result_xml->erro->attributes()->nm_retorno,
                          'fl_sucesso' => 'f',
                          'ds_tipo_transmissao' => 'ReapresentacaoParcelas',
                          'ds_xml_transmissao' => $mysoapmsg,
                          'dt_envio' => $dtEnvio,
                          'dt_retorno' => $dtRetorno
                      )
                  );
                  die('Erro ao prorrogar boleto: ' . $result_xml->erro->attributes()->nm_retorno);
              } else {
                  $return['status'] = true;

                  $modelProposta->gravaLogTransmissao(
                      array(
                          'id_proposta' => $idProposta,
                          'ds_retorno' => 'Boleto reapresentado com sucesso.',
                          'fl_sucesso' => 't',
                          'ds_tipo_transmissao' => 'ReapresentacaoParcelas (Boletos)',
                          'ds_xml_transmissao' => $mysoapmsg,
                          'dt_envio' => $dtEnvio,
                          'dt_retorno' => $dtRetorno
                      )
                  );

                  $xml = "<i4proerp>";
                  $xml .= "<obter_relatorio_pdf id_relatorio='20' nr_parcela='{$numeroParcela}' ";
                  $xml .= "                     id_endosso='{$proposta->ds_identificador_seguradora}'>";
                  $xml .= "</obter_relatorio_pdf>";
                  $xml .= "</i4proerp>";

                  $mysoapmsg = $client->serializeEnvelope($xml);
                  $params = array('Servico' => 'ObterRelatorioPDF', 'conteudoXML' => $mysoapmsg);

                  $dtEnvio = date('Y-m-d H:i:s');
                  $result = $client->call('Executar', array($params));
                  $dtRetorno = date('Y-m-d H:i:s');

                  if ($result['ExecutarResult']) {
                      $produto = $proposta->produto();
                      $mae = $proposta->id_proposta_mae($idProposta);
                      $segurado = $this->clean($proposta->proponente('ds_nome_proponente'));
                      $nomeFile = "{$produto['ds_nome_cultura']}_{$mae}_{$segurado}_{$numeroParcela}.pdf";

                      $boleto = new Default_Model_Boleto();
                      if ($boleto->insereProrrogacao(array(
                          'id_proposta' => $idProposta,
                          'nu_boleto' => $this->getRequest()->getParam('nu_boleto'),
                          'nr_parcela' => $numeroParcela,
                          'id_versao' => $proposta->id_versao,
                          'vl_total' => Agro_Util::formatCurrencyDb($this->getRequest()->getParam('vl_total')),
                          'vl_segurado' => Agro_Util::formatCurrencyDb($this->getRequest()->getParam('vl_segurado')),
                          'vl_juros' => Agro_Util::formatCurrencyDb($this->getRequest()->getParam('vl_juros')),
                          'vl_multa' => Agro_Util::formatCurrencyDb($this->getRequest()->getParam('vl_multa')),
                          'dt_vencimento' => $this->getRequest()->getParam('dt_vencimento'),
                          'ds_nome_arquivo' => $nomeFile
                      ))) {
                          $corretor = $proposta->corretor();
                          $preposto = $proposta->preposto();
                          $usuario = new Sistema_Model_Usuarios();
                          $nome_corretor = str_replace('.', '_', $usuario->getUsuarioById($corretor['id_usuario']));
                          $nome_preposto = null;
                          if ($preposto) {
                              $nome_preposto = str_replace('.', '_', $usuario->getUsuarioById($preposto['id_usuario']));
                          }

                          $destination_folder = APPLICATION_PATH . "/upload_files/boletos_lote/{$nome_corretor}";
                          $destination_folder .= "/{$nome_preposto}";

                          if (!file_exists($destination_folder)) {
                              mkdir($destination_folder, 0777, true);
                          }

                          file_put_contents(
                              "{$destination_folder}/{$nomeFile}",
                              base64_decode($result['ExecutarResult'])
                          );
                          $return['status'] = true;

                          $modelProposta->gravaLogTransmissao(
                              array(
                                  'id_proposta' => $idProposta,
                                  'ds_retorno' => 'Boleto gerado com sucesso.',
                                  'fl_sucesso' => 't',
                                  'ds_tipo_transmissao' => 'ObterRelatorioPDF (Boletos)',
                                  'ds_xml_transmissao' => $mysoapmsg,
                                  'dt_envio' => $dtEnvio,
                                  'dt_retorno' => $dtRetorno
                              )
                          );

                          $return['message'] = "Boleto {$nomeFile} da proposta nro:{$idProposta} gerado com sucesso.";
                      }
                  }
              }
          }
      } else {
          die('Atenção! A data de vencimento (' . $this->getRequest()->getParam('dt_vencimento') . ') informada é superior a data de vigência final (' . Agro_Util::formatDate($proposta->dt_vigencia_fim, 'dd/MM/Y') . ') da apólice.');
      }
      $this->getResponse()->setBody(Zend_Json::encode($return));
  }

	private function clean($string) {
    	$string = str_replace(' ', '-', trim($string)); // Replaces all spaces with hyphens.
		return preg_replace('/[^A-Za-z0-9\-]/', '', $string); // Removes special chars.
	}
}
