<?php

class Sistema_RotinasController extends Agro_Controller_Action {
	public function init() {

		$this->view->title = 'Sistema » Rotinas';
	}

	public function indexAction() {
		parent::indexAction();
		$this->view->title .= ' » Atualizar Agronet em Produção';
		$this->view->versoes = $this->getVersions();
	}

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

	private function getRelease() {
		$ponteiro  = opendir(VERSION_DIR);

		$itens = array();
		while ($item = readdir($ponteiro)) {
			if ($item != '.' && $item != '..') {
				$tmp = explode('.', $item);
				$ano = date('y');
				$mes = date('m');

				if ($ano == $tmp[0] && $mes == $tmp[1]) {
					$itens[] = $item;
				}
			}
		}

		return str_pad(count($itens)+1, 2, 0, STR_PAD_LEFT);
	}

	public function refreshversionsAction(){
		$this->isAjax();
		$this->getResponse()->setBody(Zend_Json::encode($this->getVersions()));
	}

	private function getVersions() {
		$ponteiro = opendir(VERSION_DIR);

		$itens = array();
		while ( $item = readdir($ponteiro) ){
			//if( !preg_match("/^(\.){1,2}$/", $item) ) {
			if( preg_match("/^[0-9]{2}\.[0-9]{2}\.[0-9]{2}/", $item)) {
				array_push($itens, $item);
				rsort($itens);
			}
		}
		return $itens;
	}

	public function baseatualizadaAction() {
		$this->view->title .= ' » Download de Base Atualizada';
	}

	public function validadorxmlAction() {
		$this->view->title .= ' » Validar Arquivo XML';
		
		$ModelFuncionario = new Sistema_Model_Funcionarios();
		$this->view->funcionarios = $ModelFuncionario->getComboVistoriadores();
		
		$ModelEmpresa = new Sistema_Model_Empresas();
		$this->view->empresas = $ModelEmpresa->getComboVistoriadoras();
	}

    /* função utilizada pelo webservice e pelo validador no AgroNet para validar o XML enviado */
    public function validateAction() {
    	$this->isAjax();

    	if (!$this->getRequest()->getParam('ds_acao')) {
    		$result = array('status' => 'false', 'message' => "Atenção!\n\nAção não pode ser vazia.\n\nPor favor, selecione uma ação.");
    	} else if (!$this->getRequest()->getParam('ds_xml')) {
    		$result = array('status' => 'false', 'message' => "Atenção!\n\nO conteúdo do arquivo XML não pode ser vazio.\n\nPor favor, adicione conteúdo.");
    	} else {
    		$action  = $this->getRequest()->getParam('ds_acao');
    		$content = utf8_decode($this->getRequest()->getParam('ds_xml'));

    		$result = $this->$action($content);
    	}

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

    /**
     * @tutorial Função utilizada pelo webservice synchronization.php
     * @param String $content
     * @return array
     */
    private function laudoFinal($content) {
        $result = array('status' => null, 'message' => null);

    	if ($content) {
            libxml_use_internal_errors(true);
            $xml = new DOMDocument();
            if ($xml->loadXML(utf8_encode($content)) ) {

                $arXML = Agro_Util::XMLObject_to_Array(new SimpleXMLElement(utf8_encode($content)));

                if (!$xml->schemaValidate($_SERVER['DOCUMENT_ROOT'].'/resources/xsd/laudos_finais.xsd')) {
                            $result = array('status' => 'true', 'message' => Agro_Util::checkXML());
                } else {
                            $result = array('status' => 'true', 'message' => "Arquivo XML validado<p/>");
                    }
            } else {
                    $result = array('status' => 'false', 'message' => 'Erro ao ler conteúdo XML.');
            }
        } else {
            $result = array('status' => 'false', 'message' => 'Erro desconhecido ao validar laudoFinal');
        }

        //$this->notify($result);
	    return $result;
    }

    /**
     * @tutorial Efetiva a importação de um laudo final através de arquivo XML
     */
    public function efetivateAction() {
        $this->isAjax();
	    $result = $this->laudoFinalSimulate(utf8_encode($this->getRequest()->getParam('ds_xml')), true);
        $this->notify($result);
        $this->getResponse()->setBody(Zend_Json::encode($result));
    }

    /**
     * @tutorial Simula a importação de um laudo final (executar em DEV) importação de XML
     */
    public function simulateAction() {
    	$this->isAjax();
    	$result = $this->laudoFinalSimulate(utf8_encode($this->getRequest()->getParam('ds_xml')));
        $this->notify($result);
    	$this->getResponse()->setBody(Zend_Json::encode($result));
    }

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

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

        if (!$Adapter->receive($file['arquivo']['name'])) {
            $result['status'] = 'Arquivo ('.$file['arquivo']['name'].')XML não encontrado!';
        } else {
            $f = file($file['arquivo']['destination'].'/'.$file['arquivo']['name']);

            if (count($f)>0) {

                $xml_header = explode('?>', $f[0]);
                $header = $xml_header[0].'?>';
                $footer = substr($f[count($f)-1],0,10);

                $content = $header;
                for ($i=1; $i<(count($f)-1); $i++) {
                    $content .= $f[$i];
                }
                $content .= $footer;

            } else {
                Agro_Util::zf_debug("Nao tem arquivo");
            }

        }
        $acao = $this->getRequest()->getParam('ds_tipo_acao');
        $result = $this->$acao($content);
        $this->notify($result);
        $this->getResponse()->setBody(Zend_Json::encode($result));
    }

    /**
     * Ajusta valores vindo da TAGH
     * @param String $coordenadas
     */
    private function resolveCoordenadas($coordenadas) {
    	$arCoords = explode(" ", $coordenadas);

    	$coord = str_pad(substr($arCoords[0],0,strlen($arCoords[0])-2),2,0,STR_PAD_LEFT).' '.
    		   str_pad(substr($arCoords[1],0,strlen($arCoords[1])-1),2,0,STR_PAD_LEFT).' '.
    		   str_pad(round(str_replace(',','.',substr($arCoords[2],0,strlen($arCoords[2])-3))),2,0,STR_PAD_LEFT).' , '.
    		   str_pad(substr($arCoords[3],0,strlen($arCoords[3])-2),2,0,STR_PAD_LEFT).' '.
    		   str_pad(substr($arCoords[4],0,strlen($arCoords[4])-1),2,0,STR_PAD_LEFT).' '.
    		   str_pad(round(str_replace(',','.',substr($arCoords[5],0,strlen($arCoords[5])-2))),2,0,STR_PAD_LEFT);

    	return $coord;
    }

    private function laudoFinalSimulate($content, $efetivar=false)
    {
        $result = array('status' => false, 'message' => null, 'EntityId' => null);

        if ((APPLICATION_ENV == 'production') && ($efetivar)) {
            return array(
                'status' => false,
                'message' => 'Ação só pode ser executada em ambiente de desenvolvimento.'
            );
        }

        $dados = $dadosItem = array();
        $laudoFinal = new Sinistro2_Model_LaudosFinais();
        $tipoLaudoFinal = new Sinistro2_Model_TipoLaudoFinal();
        $modelFuncionarios = new Sistema_Model_Funcionarios();

        /* Recupera dados do laudo que não são fornecidos via XML */
        $xml = Agro_Util::XMLObject_to_Array(new SimpleXMLElement(utf8_encode($content)));

        /* Nessa chave $xml['idLaudo'] tem o id_vistoria e não o id_laudo */
        $vistoria = (new Sistema_Model_VistoriasLaudosFinais())->fetchRow('id_vistoria = ' . $xml['idLaudo']);
        $id_vistoria = $xml['idLaudo'];
        $xml['idLaudo'] = $vistoria->id_laudo_final;

        $lf = $laudoFinal->getRow($xml['idLaudo']);

        if (($lf->id_status <> 109) && ($lf->id_status <> 211)) {
            $status = (new Sistema_Model_Status())->fetchRow('id = ' . $lf->id_status);
            $mensagem = "Erro ao sincronizar laudo. Vistoria encontra-se no status: " . $status->ds_status;
            $mensagem .= ".\n Vistoria: " . $vistoria->id_vistoria . " \n Processo: " . $lf->id_processo;

            return array(
                'status' => false,
                'message' => $mensagem
            );
        }

        /* Recupera ds_chave do laudo para saber qual tabela do schema regulacao pegar */
        $tabelaRegulacao = $tipoLaudoFinal->getChaveByLaudoProcessoCobertura(
            $xml['idLaudo'],
            $lf->id_processo,
            $lf->id_cobertura
        )->ds_chave;
        $classLaudo = 'Regulacao_Model_' . ucfirst($tabelaRegulacao);
        $laudo = new $classLaudo;

        /* Recupera id_proposta para colocar no nome do arquivo de laudo */
        $processsos = new Sinistro2_Model_Processos();
        $id_proposta = $processsos->getPropostaByProcesso($lf->id_processo);

        /* Recupera as coordenadas da sede na tabela seguro.propostas_propriedades */
        $rowPropriedades = (new Seguro_Model_PropostasPropriedades())->get($id_proposta);

        $dados['id_processo'] = $lf->id_processo;
        $dados['id_cobertura'] = $lf->id_cobertura;
        $dados['id_laudo_final'] = $xml['idLaudo'];
        $dados['fl_evento_nao_constatado'] = ($xml['flEventoNaoConstatado']
            ? Agro_Util::filterVariable($xml['flEventoNaoConstatado'], FILTER_VALIDATE_BOOLEAN)
            : null
        );
        $dados['ds_coordenadas'] = $rowPropriedades->ds_coordenadas;
        $dados['dt_vistoria_data'] = $xml['dtVistoria'];
        $dados['dt_vistoria_hora'] = (($xml['hrVistoria'] - 3) < 0)
            ? ($xml['hrVistoria'] - 3 + 12)
            : ($xml['hrVistoria'] - 3);
        $dados['dt_vistoria_minutos'] = $xml['mnVistoria'];
        $dados['ds_observacao_assinatura_segurado'] = (is_array($xml['dsObservacaoAssinaturaSegurado'])
            ? implode(" ", $xml['dsObservacaoAssinaturaSegurado'])
            : $xml['dsObservacaoAssinaturaSegurado']
        );
        $dados['ds_observacao_assinatura_regulador'] = (is_array($xml['dsObservacaoAssinaturaRegulador'])
            ? implode(" ", $xml['dsObservacaoAssinaturaRegulador'])
            : $xml['dsObservacaoAssinaturaRegulador']
        );

        ///tratamento para observacoes de laudo de uva
        $group_observacao = (is_array($xml['dsObservacao'])
            ? implode(" ", $xml['dsObservacao'])
            : $xml['dsObservacao']
        );

        $dados['fl_dt_evento_em_cobertura'] = Agro_Util::filterVariable($xml['flDataEventoEmCobertura'], FILTER_VALIDATE_BOOLEAN);

        //dados da regulação
        $dados['fl_danos_folhas'] = ($xml['dsCultura']['flDanosFolhas']
            ? Agro_Util::filterVariable($xml['dsCultura']['flDanosFolhas'], FILTER_VALIDATE_BOOLEAN)
            : null
        );
        $dados['fl_danos_ramos'] = ($xml['dsCultura']['flDanosRamos']
            ? Agro_Util::filterVariable($xml['dsCultura']['flDanosRamos'], FILTER_VALIDATE_BOOLEAN)
            : null
        );
        $dados['fl_danos_flores'] = ($xml['dsCultura']['flDanosFlores']
            ? Agro_Util::filterVariable($xml['dsCultura']['flDanosFlores'], FILTER_VALIDATE_BOOLEAN)
            : null
        );
        $dados['fl_danos_frutos'] = ($xml['dsCultura']['flDanosFrutos']
            ? Agro_Util::filterVariable($xml['dsCultura']['flDanosFrutos'], FILTER_VALIDATE_BOOLEAN)
            : null
        );
        $dados['fl_danos_benfeitorias'] = ($xml['dsCultura']['flDanosBenfeitorias']
            ? Agro_Util::filterVariable($xml['dsCultura']['flDanosBenfeitorias'], FILTER_VALIDATE_BOOLEAN)
            : null
        );
        $dados['fl_danos_vegetacao_adjacente'] = ($xml['dsCultura']['flDanosVegetacaoAdjacente']
            ? Agro_Util::filterVariable($xml['dsCultura']['flDanosVegetacaoAdjacente'], FILTER_VALIDATE_BOOLEAN)
            : null
        );
        $dados['fl_sem_danos'] = ($xml['dsCultura']['flSemDanos']
            ? Agro_Util::filterVariable($xml['dsCultura']['flSemDanos'], FILTER_VALIDATE_BOOLEAN)
            : null
        );
        $dados['fl_produtividade_menor_contratada'] = ($xml['dsCultura']['flProdutividadeMenorContratada']
            ? null
            : $xml['dsCultura']['flProdutividadeMenorContratada']
        );
        $dados['fl_areas_declaradas_conferem'] = ($xml['flAreaDeclaradaRepresentaAreaCultivada']
            ? Agro_Util::filterVariable($xml['flAreaDeclaradaRepresentaAreaCultivada'], FILTER_VALIDATE_BOOLEAN)
            : null
        );
        $dados['fl_area_declarada_representa_area_cultivada'] = ($xml['flAreaDeclaradaRepresentaAreaCultivada']
            ? Agro_Util::filterVariable($xml['flAreaDeclaradaRepresentaAreaCultivada'], FILTER_VALIDATE_BOOLEAN)
            : null
        );
        $dados['fl_pomar_condiz_proposta'] = ($xml['dsCultura']['flPomarCondizProposta']
            ? Agro_Util::filterVariable($xml['dsCultura']['flPomarCondizProposta'], FILTER_VALIDATE_BOOLEAN)
            : null
        );
        //UVA
        $dados['fl_pomar_condiz_proposta'] = ($xml['dsCultura']['flParreiralCondizProposta']
            ? Agro_Util::filterVariable($xml['dsCultura']['flParreiralCondizProposta'], FILTER_VALIDATE_BOOLEAN)
            : null
        );

        $funcionarios = array();
        if (count($xml['funcionarios']['funcionario']) == 1) {
            array_push(
                $funcionarios,
                $modelFuncionarios->getIdByTagh($xml['funcionarios']['funcionario']['id_funcionario'])
            );
        } else {
            foreach ($xml['funcionarios']['funcionario'] as $func) {
                array_push($funcionarios, $modelFuncionarios->getIdByTagh($func['id_funcionario']));
            }
        }
        $dados['vistoriadores'] = $funcionarios;

        //Esse teste deve-se pelo fato da função que converte XML em array não criar o índice [0] quando só existe um
        //item segurado.
        if (is_array($xml['itensSegurados']['item'][0])) {
            $arItens = $xml['itensSegurados']['item'];
        } else {
            $arItens[0] = $xml['itensSegurados']['item'];
        }

        $itensSegurados = new Seguro_Model_ItensSegurados();

        foreach ($arItens as $item) {
            $dadosItem[$item['idItemSegurado']]['id_laudo_final'] = $xml['idLaudo'];
            $dadosItem[$item['idItemSegurado']]['id_item_segurado'] = $item['idItemSegurado'];
            $dadosItem[$item['idItemSegurado']]['fl_nao_vistoriada'] = $item['flNaoVistoriada'] == 'true' ? 1 : 0;
            $dadosItem[$item['idItemSegurado']]['id_motivo_quadra_nao_vistoriada'] = $item['idMotivoNaoVistoriado'];
            $dadosItem[$item['idItemSegurado']]['dt_vistoria_data'] = $item['dtVistoria'];
            $dadosItem[$item['idItemSegurado']]['dt_vistoria_hora'] = (($xml['hrVistoria'] - 3) < 0)
                ? ($xml['hrVistoria'] - 3 + 12)
                : ($xml['hrVistoria'] - 3);
            $dadosItem[$item['idItemSegurado']]['dt_vistoria_minutos'] = $item['mnVistoria'] - ($item['mnVistoria'] % 5);
            $dadosItem[$item['idItemSegurado']]['fl_assinatura_regulador'] = Agro_Util::filterVariable(
                $item['flAssinadoRegulador'],
                FILTER_VALIDATE_BOOLEAN
            );
            $dadosItem[$item['idItemSegurado']]['fl_assinatura_segurado'] = Agro_Util::filterVariable(
                $item['flAssinadoSegurado'],
                FILTER_VALIDATE_BOOLEAN
            );

            //tratamento para observacoes de uva

            $its = $itensSegurados->getItemSeguradoById($item['idItemSegurado']);
            $group_observacao .= (!is_array($item['dsObservacao'])
                ? "\n" . $its['nr_item_segurado'] . ' - ' . preg_replace("/\r|\n/", " ", $item['dsObservacao'])
                : (count($item['dsObservacao']) > 0
                    ? "\n" . $its['nr_item_segurado'] . ' - ' . implode(' ', $item['dsObservacao'])
                    : '')
            );

            $dadosItem[$item['idItemSegurado']]['ds_aspectos_gerais_cultura'] = $item['dsAspectosGeraisCultura'];
            $dadosItem[$item['idItemSegurado']]['ds_coordenadas_geograficas'] = $this->resolveCoordenadas(
                $item['dsCoordenadasGeograficas']
            );
            $dadosItem[$item['idItemSegurado']]['fl_avalia_danos_anteriores'] = Agro_Util::filterVariable(
                $item['flAvaliaDanosAnteriores'],
                FILTER_VALIDATE_BOOLEAN
            );
            $dadosItem[$item['idItemSegurado']]['ds_observacao_assinatura_regulador'] = $item['dsObservacaoAssinaturaRegulador'];
            $dadosItem[$item['idItemSegurado']]['ds_observacao_assinatura_segurado'] = $item['dsObservacaoAssinaturaSegurado'];

            if (is_null($dados['fl_assinatura_segurado'])) {
                $dados['fl_assinatura_segurado'] = $item['flAssinadoRegulador'];
                $dados['fl_assinatura_regulador'] = $item['flAssinadoRegulador'];
            }

            //adaptado para não mexer no save do model Laudos_Finais_Itens_Segurados_Funcionarios
            $funcionarios = array();
            if (count($item['funcionarios']['funcionario']) == 1) {
                array_push(
                    $funcionarios,
                    $modelFuncionarios->getIdByTagh($item['funcionarios']['funcionario']['id_funcionario'])
                );
            } else {
                foreach ($item['funcionarios']['funcionario'] as $func) {
                    array_push($funcionarios, $modelFuncionarios->getIdByTagh($func['id_funcionario']));
                }
            }

            $dadosItem[$item['idItemSegurado']]['vistoriadores'] = $funcionarios;
            $dadosItem[$item['idItemSegurado']]['vl_percent_perdas'] = $item['vlPercentPerdas'];
            $dadosItem[$item['idItemSegurado']]['vl_percent_colhido'] = $item['vlPercentColhido'];
            $dadosItem[$item['idItemSegurado']]['vl_percent_area_afetada'] = $item['vlPercentAreaAfetada'];
            $dadosItem[$item['idItemSegurado']]['vl_ha_area_afetada'] = $item['vlHaAreaAfetada'];
            $dadosItem[$item['idItemSegurado']]['vl_ha_area_replantada'] = $item['vlHaAreaReplantada'];
            $dadosItem[$item['idItemSegurado']]['vl_area_sinistrada'] = $item['vlAreaSinistrada'];
            $dadosItem[$item['idItemSegurado']]['vl_rendimento_final_lavoura'] = $item['vlRendimentoFinalLavoura'];
            $dadosItem[$item['idItemSegurado']]['id_motivo_quadra_nao_vistoriada'] = $item['idMotivoQuadraNaoVistoriada'];
            $dadosItem[$item['idItemSegurado']]['fotos'] = $item['fotos']['foto'];
            $dadosItem[$item['idItemSegurado']]['fl_floracao'] = $item['flFloracao'] == 'true' ? 'pre' : 'pos';
            $dadosItem[$item['idItemSegurado']]['vl_tamanho_planta'] = $item['vlTamanhoPlanta'];
            $dadosItem[$item['idItemSegurado']]['fl_indenizacao_fitossanitaria'] = $item['flIndenizacaoFitossanitaria'] == 'true' ? 1 : 0;
            $dadosItem[$item['idItemSegurado']]['vl_percent_total_perda_final'] = $item['vlPercentTotalPerdaFinal'];
            $dadosItem[$item['idItemSegurado']]['dt_inicio_colheita'] = $item['dtInicioColheita'];
            $dadosItem[$item['idItemSegurado']]['dt_recolhimento_producao'] = $item['dtRecolhimentoProducao'];
            $dadosItem[$item['idItemSegurado']]['tp_plantio'] = $item['tpPlantio'];

            if (!is_null($dadosItem[$item['idItemSegurado']]['dt_vistoria_data'])) {
                $dados['dt_vistoria_data'] = $item['dtVistoria'];
                $dados['dt_vistoria_hora'] = (($xml['hrVistoria'] - 3) < 0) ? ($xml['hrVistoria'] - 3 + 12) : ($xml['hrVistoria'] - 3);
                $dados['dt_vistoria_minutos'] = $item['mnVistoria'] - ($item['mnVistoria'] % 5); //arredonta para multiplos de x
            }

            $dadosItem[$item['idItemSegurado']]['fl_amostragem_maquina'] = $item['flAmostragemMaquina'] == 'true' ? 1 : 0;
        }

        //seta essa flag para o método save do model (linha 89) utilizar o id_tagh ou invés do id_funcionario
        $dados['is_from_tagh'] = true;
        $dados['ds_observacao'] = $group_observacao;

        // salvando dados em laudo_final
        $id_laudo_final = $laudoFinal->save($dados);

        if ($id_laudo_final) {
            // salvando dados em regulacao.{nome_laudo}
            $id_laudo_final_especializacao = $laudo->save($dados);
            $laudo_itens_especializacao = get_class($laudo) . 'ItensSegurados';
            $laudoItens = new $laudo_itens_especializacao;

            if ($id_laudo_final_especializacao) {
                foreach ($dadosItem as $Item) {
                    // salvando dados em laudo_final_item

                    if ($laudo_itens_especializacao == 'Regulacao_Model_Lf005ItensSegurados') {
                        $id_item_segurado_especializacao = $laudoItens->saveTagh($Item);
                    } else {
                        $id_item_segurado_especializacao = $laudoItens->save($Item);
                    }

                    if (!$id_item_segurado_especializacao) {
                        $result = array('status' => false, 'message' => 'Erro ao salvar item do laudo (regulação).');
                        $this->undoSyncLaudo($laudoFinal, $id_laudo_final);

                        return $result;
                    }

                    /* Solução para quando existe apenas uma imagem nas amostras */
                    if (!is_array($Item['fotos'])) {
                        $fotos = array();
                        $fotos[0] = $Item['fotos'];
                    } else {
                        $fotos = $Item['fotos'];
                    }

                    /** Salvando imagens amostras */
                    if (!empty($fotos)) {
                        $i = 1;
                        $unidades = new Seguro_Model_ItensSegurados();
                        $arquivos = new Sinistro2_Model_LaudosFinaisArquivos();

                        foreach ($fotos as $foto) {
                            $rowItem = $unidades->getItemSeguradoById($Item['id_item_segurado']);
                            $arquivo_foto = 'IMG_AMOSTRA_' . $id_proposta . '_' . $dados['id_cobertura'] . '_';
                            $arquivo_foto .= $id_vistoria . '_' . $rowItem['nr_item_segurado'] . '_' . $i . '.jpg';

                            $cmd = "wget " . $foto . " -O " . APPLICATION_PATH . "/upload_files/laudofinal/";
                            $cmd .= $arquivo_foto . " &>/dev/null &";

                            exec($cmd);

                            if (
                                !$arquivos->save(
                                    array('id_laudo' => $id_laudo_final, 'ds_nome_arquivo' => $arquivo_foto)
                                )
                            ) {
                                $this->undoSyncLaudo($laudoFinal, $id_laudo_final);
                            }
                            $i++;
                        }
                    }
                }
            } else {
                $result = array('status' => false, 'message' => 'Erro ao salvar especialização do laudo');
                $this->undoSyncLaudo($laudoFinal, $id_laudo_final);
                return $result;
            }

            /* Turn around pra quando só tem um laudo */
            if (!is_array($xml['LaudosFisico']['laudo'])) {
                $laudos = array();
                $laudos[0] = $xml['LaudosFisico']['laudo'];
            } else {
                $laudos = $xml['LaudosFisico']['laudo'];
            }

            /* Salvando laudos fisico */
            $i = 1;
            $arquivos = new Sinistro2_Model_LaudosFinaisArquivos();

            foreach ($laudos as $laudo) {
                $nome = str_pad($id_proposta, 6, "0", STR_PAD_LEFT) . '_VF_';
                $nome .= str_pad($id_vistoria, 6, "0", STR_PAD_LEFT) . "_" . $i . ".jpg";

                $arquivo = strtoupper($nome);

                $file = @file_put_contents(realpath(APPLICATION_PATH . '/laudos/' . $arquivo), base64_decode($laudo));
                if (!$file) {
                    $result = array('status' => false, 'message' => 'Erro ao salvar laudo físico.');
                    $this->undoSyncLaudo($laudoFinal, $id_laudo_final);

                    return $result;
                } else {
                    if (!$arquivos->save(array('id_laudo' => $id_laudo_final, 'ds_nome_arquivo' => $arquivo))) {
                        $result = array('status' => false, 'message' => 'Erro ao salvar laudo físico.');
                        $this->undoSyncLaudo($laudoFinal, $id_laudo_final);

                        return $result;
                    }
                }
                $i++;
            }

            $out = $laudoFinal->getAdapter()->query(
                "update sinistro.laudos_finais set ds_nome_laudo_fisico = '$arquivo' where id = $id_laudo_final"
            );

            if (!$out) {
                $result = array('status' => false, 'message' => 'Erro ao atualizar laudo fisico.');
                $this->undoSyncLaudo($laudoFinal, $id_laudo_final);

                return $result;
            }

            return array(
                'status' => true,
                'message' => 'Laudo salvo com sucesso.',
                'EntityId' => (integer)$id_laudo_final,
                'id_proposta' => $id_proposta,
                'id_vistoria' => $id_vistoria
            );
        } else {
            $this->undoSyncLaudo($laudoFinal, $dados['id_laudo_final']);
            return array(
                'status' => false,
                'message' => 'Erro ao salvar laudo. (' . htmlspecialchars($laudoFinal->getMessages()) . ')',
                'id_proposta' => $id_proposta,
                'id_vistoria' => $id_vistoria
            );
        }

        return $result;
    }

    //Método chamado para voltar o status do laudo para 'Nao Enviado' pois ocorreu algum erro ao
    //importá-lo via TAGH
    private function undoSyncLaudo($laudoFinal, $idLaudoFinal) {
        if ($idLaudoFinal) {
            $laudoFinal->getAdapter()->query('update sinistro.laudos_finais set id_status = ' . $laudoFinal->getIdStatus('PENDENTE_LAUDO_FINAL', 'LF') . ' where id = ' . $idLaudoFinal);
        }
    }

    public function calltaghAction() {
//        $this->getHelper('ViewRenderer')->setNoRender();
//        $this->getHelper('layout')->disableLayout();
        $this->isAjax();
        $dados = array();
        $tagh = new Agro_Tagh();
        
        $call = $this->getRequest()->getParam('ds_chamada_tagh');
        
        if ($call == 'createOrUpdateInspector') {
            
            $Funcionario = new Sistema_Model_Funcionarios();
            $Row = $Funcionario->getRow($this->getRequest()->getParam('id_funcionario'));
            
            $Usuario = new Sistema_Model_Usuarios();
            $RowUsuario = $Usuario->fetchRow("id = $Row->id_usuario and tp_usuario = 'V'")->toArray();
            
            $Municipio = new Sistema_Model_Municipios();
            $RowMunicipio = $Municipio->getRow($Row->id_municipio);
            
            $dados['inspectorid'] = ($Row['id_tagh'] ? $Row['id_tagh'] : 0);
            $dados['inspectorname'] = $Row->ds_nome_funcionario;
            $dados['username'] = $RowUsuario['ds_nome_usuario'];
            $dados['userpassword'] = $RowUsuario['ds_senha'];
            $dados['identificador'] = null;
            $dados['identificador2'] = null;
            $dados['maxarea'] = 0;
            $dados['maxinspections'] = 0;
            //$dados['headid'] = 0;
            $dados['districtid'] = $RowMunicipio->id_estado;
            $dados['addesss'] = $Row->ds_endereco_rua.' '.$Row->ds_endereco_nro;
            $dados['townid'] = $Row->id_municipio;
            $dados['zipcode'] = $Row->ds_endereco_cep;
            $dados['email'] = $Row->ds_email;
            $dados['email1'] = null;
            
            $Fone = new Sistema_Model_Telefones();
            $RowFone = $Fone->fetchAll("id_usuario = ". $RowUsuario['id'])->toArray();
            
            foreach ($RowFone as $fone) {
                switch ($fone['id_tipo_telefone']) {
                    case 2:
                        if (is_null($dados['mobile'])) {
                            $dados['mobile'] = $fone['ds_numero'];
                        }
                        break;
                    case 3:
                        if (is_null($dados['phone'])) {
                            $dados['phone'] = $fone['ds_numero'];
                        }
                        break;
                    case 5:
                        if (is_null($dados['fax'])) {
                            $dados['fax'] = $fone['ds_numero'];
                        }
                        break;
                }
            }
            
            //dados não existentes no AgroNet
            $dados['bankaccountbank'] = null;
            $dados['bankaccountbranch'] = null;
            $dados['bankaccountcode'] = null;
            $dados['bankaccountname'] = null;
            $dados['bankaccountnumber'] = null;
            $dados['bankaccounttype'] = null;
            
            //busca id_tagh da empresa
            $ModelEmpresa = new Sistema_Model_Empresas();
            $Empresa = $ModelEmpresa->find($Row['id_empresa'])->current()->toArray();
            
            if ($Empresa['id_tagh']) {
                $dados['firmid'] = $Empresa['id_tagh'];
                
                $id_tagh = $tagh->createOrUpdateInspector($dados);
            }
            
            if ($id_tagh) {
                $Funcionario->update(array('id_tagh' => $id_tagh), 'id = '.$this->getRequest()->getParam('id_funcionario'));
                $result['status'] = true;
                $result['message'] = 'Vistoriador atualizado com sucesso (id_tagh:'.$id_tagh.').';
            } else {
                $result['status'] = false;
                $result['message'] = 'Erro ao atualizar vistoriador (id_tagh:'.$id_tagh.').';
            }
            
        } elseif ($call == 'createOrUpdateFirm') {
            
            $ModelEmpresa = new Sistema_Model_Empresas();
            $Row = $ModelEmpresa->find($this->getRequest()->getParam('id_empresa'))->current()->toArray();
            
            $dados['username'] = str_replace(' ','.',strtolower($Row['ds_nome_fantasia']));
            $dados['userpassword'] = 'TestPassword';
            $dados['firmid'] = ($Row['id_tagh'] ? $Row['id_tagh'] : 0);
            $dados['identificador'] = 'IdentificatorTest';
            $dados['identificador2'] = 'Identificator2Test';
            $dados['firmname'] = $Row['ds_nome_fantasia'];
            $dados['addesss'] = $Row['ds_endereco_rua'].' '.$Row['ds_endereco_nro'];
            $dados['zipcode'] = $Row['ds_endereco_cep'];
            $dados['email'] = strtolower($Row['ds_email']);
            $dados['email1'] = null;
            $dados['fax'] = $Row['ds_telefone_fax'];
            $dados['mobile'] = 'MobileTest';
            $dados['phone'] = $Row['ds_telefone'];
            $dados['phone1'] = 'Phone1Test';
            
            $id = $tagh->createOrUpdateFirm($dados);
            
            //Se atualização com TAGH ocorreu atualiza id_tagh na tabela sistema.empresas
            if ($id) {
                $ModelEmpresa->update(array('id_tagh' => $id), "id = ".$this->getRequest()->getParam('id_empresa'));
            }

            $result['status'] = is_null($id) ? false : true;
            $result['message'] = is_null($id) ? 'Erro ao atualizar empresa (id_tagh:'.$id.').' : 'Empresa atualizada com sucesso (id_tagh:'.$id.').';
                
        } else {

            $Adapter = new Zend_File_Transfer_Adapter_Http();
            $Adapter->setDestination(APPLICATION_PATH.'/upload_files/temp/');
            $file = $Adapter->getFileInfo();
    
            if (!$Adapter->receive($file['arquivo_tagh']['name'])) {
                $result['status'] = 'Arquivo ('.$file['arquivo_tagh']['name'].') XML não encontrado!';
            } else {
                $f = file($file['arquivo_tagh']['destination'].'/'.$file['arquivo_tagh']['name']);
    
                if (count($f)>0) {
                    for($i=0; $i<count($f); $i++){
                        $content .= $f[$i];
                    }
                }
            }
    
            $res = $tagh->testXML($content, ucfirst($call));
            $result['status'] = true;
            $result['message'] = 'Tudo ok!';
        }
        
        $this->getResponse()->setBody(Zend_Json::encode($result));
    }

    public function endossoloteAction() {
        $this->view->title = 'Sistema » Rotinas » Agendar Endosso Lote';
        $this->view->listagem = $this->listarCron();
    }

    public function endossarloteAction() {

        $this->isAjax();

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

        if (!$Adapter->isValid()) {
            $result['status'] = 'Formato de arquivo inválido (formato aceito: .csv).';
        } elseif (!$Adapter->receive($file['input_file']['name'])) {
            $result['status'] = 'Problema ao enviar arquivo';
        } else {
            if ($this->checktime($this->getRequest()->getParam('time_task'))) {
                //salvar cron.
                $cronExecutada = $this->createCron(
                    $file['input_file']['name'],
                    $this->getRequest()->getParam('time_task')
                );

                if (!$cronExecutada) {
                    $result['message'] = "Atenção!\nHora informada não é uma hora futura ou é inválida. (formato: hh:mm)";
                    $result['status'] = false;
                } else {
                    $this->view->listagem = $this->listarCron();
                    $result['message'] = 'Agendamento efetuado com sucesso';
                    $result['status'] = true;
                }
            } else {
                $result['message'] = "Atenção!\nHora informada não é uma hora futura ou é inválida. (formato: hh:mm)";
                $result['status'] = false;
            }
        }
        $this->getResponse()->setBody(Zend_Json::encode($result));
    }

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

        $this->deleteCron($this->getRequest()->getParam('patern'));
        $result['message'] = 'Cron removido da lista.';
        $result['status'] = true;
        $this->getResponse()->setBody(Zend_Json::encode($result));
    }

    private function createCron($input_file, $time_task)
    {
        $dia = date('d');
        $mes = date('m');
        $week = date('w');
        list($hora, $min) = explode(':', $time_task);

        if (!Agro_Util::filterVariable($min) || !Agro_Util::filterVariable($hora)) {
            return false;
        }

        $min = (int)$min;
        $hora = (int)$hora;
        $input_file = Agro_Util::clearFileName($input_file);

        $comando = "echo \"{$min} {$hora} {$dia} {$mes} {$week} /usr/bin/php ";
        $comando .= APPLICATION_PATH . "/../Curl/endossolote_onelogin.php ";
        $comando .= APPLICATION_PATH . "/upload_files/endosso_lote/{$input_file} > /tmp/output.cronlog\" >>";
        $comando .= "   /tmp/mycron";

        $agroCron = new Agro_Cron();
        $agroCron->execute([$comando]);

        return true;
    }

    private function listarCron() {
        $output = shell_exec("crontab -l | grep endossolote");
        return str_replace("\n", "<br>", $output);
    }

    /* Remove linhas no arquivo cron referente ao funcionário em questão */
    private function deleteCron($patern)
    {
        $agroCron = new Agro_Cron();
        $agroCron->execute(["sed -i '/".$patern." /d' /tmp/mycron"]);

        return true;
    }

    /* Valida a hora informada */
    private function checktime($time) {
        list($hora, $min) = explode(':',$time);
        list($hora_atual, $min_atual) = explode(':',date('H:i'));

        if (count(explode(':',$time))<>2) {
            return false;
        }

        if (($hora>23) || ($hora<$hora_atual)) {
            return false;
        }

        if (($min>59) || ($min<$min_atual)) {
            return false;
        }

        return true;
    }

    /* Envia um aviso quando chega uma nova sincronização da TAGH com arquivo XML em anexo */
    private function notify($result) {

        if(is_array($result)) {

            $attachment = APPLICATION_PATH.'/upload_files/xml_recepcao_tagh/'.date('YmdHi').'_post_data.xml';

            $mail = new Zend_Mail('UTF-8');
            $mail->setFrom("ti@agrobrasilseguros.com.br", "Agronet 2.0 - Sistema de notificação");

            $config = array(
                'ssl'      => MAIL_SSL,
                'port'     => MAIL_PORT,
                'auth'     => MAIL_AUTH,
                'username' => MAIL_USERNAME,
                'password' => MAIL_PASSWORD
            );

            $transport = new Zend_Mail_Transport_Smtp(MAIL_SMTP, $config);
            $mail->setDefaultTransport($transport);

            $to = array('Tonismar R. Bernardo' => 'tonismar.bernardo@agrobrasilseguros.com.br');

            $file_content = file_get_contents($attachment);
            $att = new Zend_Mime_Part($file_content);
            $att->type = Zend_Mime::TYPE_TEXT;
            $att->disposition = Zend_Mime::DISPOSITION_ATTACHMENT;
            $att->encoding = Zend_Mime::ENCODING_8BIT;
            $att->filename = date('YmdHis').'_post_data.xml';

            $content = "Nova sincronização de laudo enviada pela TAGH.<br>";

            foreach ($result as $key => $value) {

            	switch($key) {
            		case 'status': $content .= $value ? 'Sincronização bem sucedida<br>' : 'Erro na sincronização<br>';
            		break;

            		case 'message': $content .= 'Retorno: ' . $value . '<br>';
            		break;

            		case 'id_proposta': $content .= 'Proposta: ' . $value . '<br>';
            		break;

            		case 'id_vistoria': $content .= 'Vistoria: ' . $value . '<br>';
            		break;
            	}

            }

            $content .= '<br>E-mail envidado automaticamente.';

            try {
                $mail->addTo($to);
                $mail->addAttachment($att);
                $mail->setBodyHtml($content);
                $mail->setSubject('Notificação de sincronia TAGH->Agronet realizada (proposta:'.$result['id_proposta'].').');
                $mail->send();

                return true;
            } catch (Exception $e) {
                return true;
            }
        }
    }

    /**
     * Método criado para demonstrar o formulário de criação do banco e para realizar a chamada da rotina de criação
     * 
     * @return json
     */
    public function criadbzoneamentoAction()
    {
        $this->view->title .= ' » Cria Banco Zoneamento Grãos';

        if ($this->getRequest()->getMethod() == 'POST') {
            $this->isAjax();
            try {
                $user = Zend_Auth::getInstance()->getIdentity();
                $modelFuncionarios = new Sistema_Model_Funcionarios;
                $infoUser  = $modelFuncionarios->getFuncionarioByIdUsuario($user->id);

                $cmd = "php ".APPLICATION."/../Curl/criabancozoneamento.php ".$infoUser['ds_email'];
                $command = 'nohup '.$cmd.' > /dev/null 2>&1 & echo $!';
                exec($command ,$op);
                $return = (int)$op[0];
                $this->getResponse()->setBody(Zend_Json::encode(array('status' => 'success', 'message' => 'A rotina está rodando! Você receberá um e-mail quando ela estiver pronta!')));
            } catch (Exception $e) {
                $this->getResponse()->setBody(Zend_Json::encode(array('status' => 'error', 'message' => MSG_ERROR . '<br />' . $e->getMessage())));
            }
        }
    }

    /**
     * Recepe a requisição POST e efetiva  criação do banco de dados de zoneamento de grãos
     * 
     * @return json
     */
    public function docriadbzoneamentoAction()
    {
        ini_set('memory_limit', -1);
        set_time_limit(0);

        $this->isAjax();

        if ($this->getRequest()->getMethod() == 'POST') {
            $ddlPathZoneamento = DDL_PATH . DIRECTORY_SEPARATOR .
                'sistema' . DIRECTORY_SEPARATOR .
                'banco_zoneamento_graos' . DIRECTORY_SEPARATOR;
            $dbFullNameSqlite = APPLICATION . DIRECTORY_SEPARATOR . 'db_zoneamento' . DIRECTORY_SEPARATOR;
            $dbName = 'db_zoneamento_graos_' . date('YmdHis') . '.db';
            $dbFullNameSqlite .= $dbName;

            set_error_handler(function ($errno, $errstr, $errfile, $errline) {
                if ($errno === E_ERROR || $errno === E_CORE_ERROR || $errno === E_USER_ERROR) {
                    Sistema_RotinasController::sendEmailT(
                        'ti@agrobrasilseguros.com.br',
                        'Ocorreu um erro ao criar a base de dados do zoneamento de grãos!<br />' . $errstr,
                        'Agronet 2.0 - Base Zoneamento Grãos'
                    );
                }
                return false;
            });

            try {
                if ($this->verificaModificacaoDadosZoneamento()) {
                    //busca as safras atual e anterior para persistir os dados no banco de zonemento
                    $modelSafra = new Produto_Model_Safras;
                    $safraAtual = $modelSafra->getSafraAtual();
                    $safraAnterior = $modelSafra->getSafra($safraAtual['id'] - 1);
                    $arSafras = array(
                        array(
                            'id' => $safraAtual['id'],
                            'nome' => $safraAtual['ds_nome_safra']
                        ),
                        array(
                            'id' => $safraAnterior['id'],
                            'nome' => $safraAnterior['ds_nome_safra']
                        )
                    );

                    // cria o banco de dados e as tabelas
                    $this->createDbZoneamento($dbFullNameSqlite, $ddlPathZoneamento . 'dml_criacao.sql');

                    //insere os dados conforme as consultas do arquivo
                    $this->persistDbZoneamento(
                        $dbFullNameSqlite,
                        $ddlPathZoneamento . 'consultas_persistencia.sql',
                        $arSafras
                    );

                    //atualiza a versão do zoneamento passando o arquivo e a safra
                    $this->updateVersionZoneamento($safraAtual['id'], $dbName, md5_file($dbFullNameSqlite));

                    $content = 'Base de dados do zoneamento de grãos <b>' . $dbName . '</b> criada para a safra <b>';
                    $content .= $safraAtual['id'] . '</b>!';

                    $this->sendEmail(
                        $this->getRequest()->getParam('email', null),
                        $content,
                        'Agronet 2.0 - Base Zoneamento Grãos'
                    );

                    $this->getResponse()->setBody(
                        Zend_Json::encode(array('status' => 'success', 'message' => MSG_SUCCESS))
                    );
                } else {
                    $content = 'Tentativa de criação de banco de dados do zoneamento. Não foi criado devido a não';
                    $content .= ' haver diferença nos registros da base de dados!';

                    $this->sendEmail(
                        $this->getRequest()->getParam('email', null),
                        $content,
                        'Agronet 2.0 - Base Zoneamento Grãos'
                    );

                    $this->getResponse()->setBody(
                        Zend_Json::encode(array('status' => 'success', 'message' => $content))
                    );
                }
            } catch (Exception $e) {
                unlink($dbFullNameSqlite);

                $this->sendEmail(
                    $this->getRequest()->getParam('email', null),
                    'Ocorreu um erro ao criar a base de dados do zoneamento de grãos!',
                    'Agronet 2.0 - Base Zoneamento Grãos'
                );

                $this->getResponse()->setBody(
                    Zend_Json::encode(array('status' => 'error', 'message' => MSG_ERROR . ': ' . $e->getMessage()))
                );
            }
        } else {
            $this->getResponse()->setBody(
                Zend_Json::encode(
                    array(
                        'status' => 'error',
                        'message' => 'Esse serviço só pode ser executado através do método POST!'
                    )
                )
            );
        }
    }

    /**
     * 
     * @return boolean
     */
    private function verificaModificacaoDadosZoneamento() {
        $adp = Zend_Db_Table_Abstract::getDefaultAdapter();
        $user = Zend_Auth::getInstance()->getIdentity();

        $stat = $adp->query('SELECT id FROM sistema.versao_zoneamento WHERE fl_importado_zoneamento = TRUE AND fl_exportado_tablet = FALSE');
        $result = $stat->fetchColumn();

        return !empty($result);
    }

    /**
     * Envia email de notificação
     * 
     * @param string $to    Quem vai receber a notificação 
     * @param string $content    Conteúdo da notificação 
     * @param string $subject    Título da notificação 
     * @return boolean
     */
    private function sendEmail($to, $content, $subject) {
        $mail = new Agro_Mail();
        $cc = array('TI' => 'ti@agrobrasilseguros.com.br');
        try {
            if ($to) {
                $mail->addTo(array($to));
                $mail->addCc($cc);
            } else {
                $mail->addTo($cc);
            }
            $mail->setBodyHtml($content);
            $mail->setSubject($subject);
            $mail->send();

            return true;
        } catch (Exception $e) {
            return false;
        }
    }

    /**
     * Envia email de notificação
     * 
     * @param string $to    Quem vai receber a notificação 
     * @param string $content    Conteúdo da notificação 
     * @param string $subject    Título da notificação 
     * @return boolean
     */
    public static function sendEmailT($to, $content, $subject) {
        $mail = new Agro_Mail();
        $cc = array('Tonismar Bernardo' => 'tonismar.bernardo@agrobrasilseguros.com.br');
        try {
            if ($to) {
                $mail->addTo(array($to));
                $mail->addCc($cc);
            } else {
                $mail->addTo($cc);
            }
            $mail->setBodyHtml($content);
            $mail->setSubject($subject);
            $mail->send();

            return true;
        } catch (Exception $e) {
            return false;
        }
    }

    /**
     * Atualiza versão do banco do zoneamento
     * 
     * @param integer $idSafra    Identificador da safra
     * @param string $fileNameDb    Nome do banco de dados do zoneamento
     * @return void
     */
    private function updateVersionZoneamento($idSafra, $fileNameDb, $md5FileDb) {
        $adp = Zend_Db_Table_Abstract::getDefaultAdapter();
        $user = Zend_Auth::getInstance()->getIdentity();

        $stat = $adp->query('SELECT id FROM sistema.versao_zoneamento WHERE fl_importado_zoneamento = TRUE AND fl_exportado_tablet = FALSE');
        $result = $stat->fetchColumn();

        $adp->query('UPDATE sistema.versao_zoneamento SET fl_ativo = false;');
        if (!empty($result)) {
            $adp->query('
                UPDATE sistema.versao_zoneamento
                   SET fl_importado_zoneamento = TRUE
                     , fl_exportado_tablet = TRUE
                     , ds_nome_arquivo = \'' . $fileNameDb . '\'
                     , md5 = \'' . $md5FileDb . '\'
                     , fl_ativo = TRUE
                 WHERE id = '.$result.';
                 ');
        } else {
            $adp->query('INSERT INTO sistema.versao_zoneamento (
                    id_usuario_criacao,
                    id_usuario_alteracao,
                    dt_criacao,
                    dt_alteracao,
                    fl_ativo,
                    fl_del,
                    id,
                    id_safra,
                    ds_nome_arquivo,
                    md5,
                    fl_exportado_tablet,
                    fl_importado_zoneamento
                ) VALUES (
                    ' . $user->id . ',
                    NULL,
                    NOW(),
                    NULL,
                    TRUE,
                    FALSE,
                    NEXTVAL(\'sistema.versao_zoneamento_id_seq\'),
                    ' . $idSafra . ',
                    \'' . $fileNameDb . '\',
                    \'' . $md5FileDb . '\',
                    TRUE,
                    TRUE
                );');
        }
    }

    /**
     * Roda os scripts de criação do banco
     * @param string $dbname 
     * @param string $dmlFile 
     * @return void
     */
    private function createDbZoneamento($dbname, $dmlFile) {
        $dmlDb = file_get_contents($dmlFile);
        $adpSqlite = new Sqlite3($dbname);

        $adpSqlite->query($dmlDb);
    }

    /**
     * Insere os dados do banco de zoneamento realizando buscas no bando do agronet
     * @param type $dbname    Nome do banco do zoneamento
     * @param type $fileScript    Arquivo com as consultas para buscar os dados
     * @param type $safras    Safras que serão buscadas as informações
     * @return void
     */
    private function persistDbZoneamento($dbname, $fileScript, $safras) {
        $result = $this->getValuesForZoneamento($fileScript, $safras);

        $adpSqlite = Zend_Db::factory('Pdo_Sqlite', array(
            'dbname' => $dbname
         ));
        //montar para buscar as safras corretas
        foreach ($safras as $safra) {
            $adpSqlite->query("INSERT INTO safra VALUES ({$safra['id']}, '{$safra['nome']}');");
        }

        foreach ($result as $table => $results) {
            foreach ($results as $values) {
                $adpSqlite->insert($table, $values);
            }
        }
    }

    /**
     * Busca os dados conforme estrutura do arquivo de consultas
     *
     * @param type $fileScript    Arquivo com as consultas para buscar os dados
     * @param type $safras    Safras que serão buscadas as informações
     * @return void
     */
    private function getValuesForZoneamento($fileScript, $safras) {
        $result = array();

        $safraIds = array_map(function ($ar) {return $ar['id'];}, $safras);
        
        $queriesDb = file_get_contents($fileScript);
        $queriesDb = str_replace('{ids_safra}', implode(',', $safraIds), $queriesDb);
        $db = Zend_Db_Table::getDefaultAdapter();
        foreach (explode(';', $queriesDb) as $key => $value) {
            //retira a quebra de linha e os espaços em branco
            $value = trim($value);
            if (!empty($value)) {
                //busco o nome da tabela da primeira linha comentada
                $tableName = strtok($value, "\n\t");
                $tableName = str_replace('--', '', $tableName);
                $tableName = trim($tableName);
                $tableName = strtolower($tableName);

                $result[$tableName] = $db->fetchAll($value);
            }
        }

        return $result;
    }

    /**
     * Consulta todas as views materializadas para executar o refresh
     */
    public function refreshmaterializedviewsAction()
    {
        $this->isAjax();

        $response = [
            'message' => 'Refresh materialized view executado com sucesso!',
            'status' => true
        ];

        $erros = [];

        $adapter = Agro_Db_Table_Abstract::getDefaultAdapter();
        $sql = " SELECT id, schemaname || '.' || matviewname AS matview ";
        $sql .= "  FROM manutencao.materialized_views ";
        $sql .= "  ORDER BY ordem ";
        
        $query = $adapter->query($sql);
        $rs = $query->fetchAll();
        
        foreach($rs as $row) {

            try {
                $adapter->beginTransaction();
                
                $sqlRefresh = "REFRESH MATERIALIZED VIEW {$row['matview']}";
                $rsRefresh = $adapter->query($sqlRefresh);

                if (!$rsRefresh) {
                    throw new Exception("Erro ao executar o refresh da view {$row['matview']}.");
                }

                $dtAtualizacao = date('Y-m-d H:i:s');
                $updateRefresh = "UPDATE manutencao.materialized_views SET dt_ultima_atualizacao = '{$dtAtualizacao}' WHERE id = {$row['id']}";
                $rsUpdateRefresh = $adapter->query($updateRefresh);

                if (!$rsUpdateRefresh) {
                    throw new Exception("Erro ao modificar a data de atulização da view {$row['matview']}.");
                }

                $adapter->commit();

            } catch (\Throwable $th) {

                $adapter->rollback();
                $erros[] = $th->getMessage();
                $response['status'] = false;
            }
        }

        if (!$response['status']) {
            $response['message'] = implode("\n", $erros);
        }

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

    public function forcartrocarsenhaAction() {
        $this->view->title .= ' » Forçar Troca de Senha de Usuário';    
    }

    public function adoforcartrocarsenhaAction() {
        $this->isAjax();
        $this->getResponse()->setBody(Zend_Json::encode(
            [
                'status' => true,
                'message' => 'Here works!'
            ]
        ));
    }

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

        //cleaning dangerous
        $nome_usuario = trim(filter_var($this->getRequest()->getParam('nome_usuario'), FILTER_SANITIZE_SPECIAL_CHARS) ?? '');
        $justificativa = trim(filter_var($this->getRequest()->getParam('justificativa'), FILTER_SANITIZE_SPECIAL_CHARS) ?? '');

        try {
            //double check validation
            if (!$nome_usuario || !$justificativa) {
                throw new DomainException('Informe todo os valores obrigatórios.');    
            }

            $Usuarios = new Sistema_Model_Usuarios();
            $query = $Usuarios
                ->select()->setIntegrityCheck(false)
                ->where('fl_ativo = ?', true)
                ->where('ds_nome_usuario = ?', $nome_usuario)
                ->forUpdate(true);
            
            $user = $Usuarios->fetchRow($query);

            if (!$user) {
                throw new DomainException('Usuário inexistente.');
            }

            $user->fl_bloqueio_inatividade = true;
            $user->dt_expiracao_senha = '1975-01-29';
            $user->nr_tentativas_acesso = 3;
            $user->save();
            
            if ($user->save()) {
                (new Log_Model_TrocaSenhaForcada())->save(
                    [
                        'id_usuario' => $user->id,
                        'ds_justificativa' => $justificativa
                    ]
                );
            }
            
            $result = ['status' => true, 'message' => 'Usuário será forçado a trocar a senha no próximo login.'];
        } catch (DomainException $e) {
            $result = ['status' => false, 'message' => $e->getMessage()];
        } catch (Exception $e) {
            $result = ['status' => false, 'message' => 'Erro ao forçar troca de senha do usuário.'.(APPLICATION_ENV != 'production' ? $e->getMessage() : '')];
        }
        $this->getResponse()->setBody(Zend_Json::encode($result));
    }
}