<?php
require_once 'Zend/Loader/Autoloader.php';
require_once 'SeventapException.php';
$loader = Zend_Loader_Autoloader::getInstance();

class Seventap {
	private $exceptionUser = 'fabio.bertoldi';

	private $config = null;
	private $Auth = null;
	private $db = null;
	private $error = array(
		'Token inválido ou expirado.',
		'Usuário ou senha inválido(s).',
		'Arquivo inexistente.',
		'Erro ao atualizar o status.',
        'Houve um problema ao salvar a vistoria!', // erro ao salvar vistoria
        'Vistoria salva com sucesso!',
        "Não foi possível gerar Laudo da Vistoria Prévia!",
		'Erro ao buscar as informações do banco do zoneamento!',
		'Este usuário já está vinculado a outro dispositivo. Entre em contato com atendimento.',
        'Usuário não habilitado.',
        'Erro ao informar vistoria limpa no tablet'
	);

	private $email = null;

	public function __construct() {
		$this->config = new Zend_Config_Ini('../application/config/application.ini', getenv('APPLICATION_ENV'));
	}

	/**
	* Retorna a mensagem de erro do array de erros.
	*/
	private function getError($idx) {
		return $this->error[$idx];
	}

	private function setDb() {
		$Adapter = Zend_Db::factory('PDO_PGSQL', $this->config->resources->db->params);
		Zend_Db_Table_Abstract::setDefaultAdapter($Adapter);
		$this->db = Zend_Db_Table::getDefaultAdapter();		
	}

	/**
	* Valida usuário e senha e devolve token
	*/
	private function checkIdentity($usuario, $senha) {
		$filter = new Zend_Filter_StripTags();
		$f_usuario = $filter->filter($usuario);
		$f_senha = $filter->filter($senha);

		$this->setDb();
		$this->Auth = Zend_Auth::getInstance();

		$AuthAdapter = new Zend_Auth_Adapter_DbTable($this->db);
		$AuthAdapter->setTablename('sistema.v_login');
		$AuthAdapter->setIdentityColumn('ds_nome_usuario');
		$AuthAdapter->setCredentialColumn('ds_senha');
		$AuthAdapter->setIdentity($f_usuario);
		$AuthAdapter->setCredential(crypt($f_senha,$f_usuario));

		if ($this->Auth->authenticate($AuthAdapter)->isValid()) {
			$data = $AuthAdapter->getResultRowObject(null, 'ds_senha'); 
			$this->Auth->getStorage()->write($data);

			return true;
		} else {
			return false;
		}
	}

	/**
	* Verifica se existe o token informado para um usuário
	*/
	private function checkToken($token) {
		try {
			$this->setDb();
			$Usuario = $this->db->select();
			$Usuario->from(array('u' => 'sistema.usuarios'), array('id','ds_nome_usuario','token'));
			$Usuario->where('u.token = ?', $token);

			$Row = $this->db->fetchRow($Usuario);

			if (is_array($Row)) {

				if ($Row['token'] === $this->getToken($Row['ds_nome_usuario'])) { 
					return $Row;
				} else {
					return false;
				}
			} else {
				return false;
			}
		} catch (Exception $e) {
			return $e->getMessage();
		}
	}

	/*
	* Verifica se já não existe um dispositivo vinculado ao usuário. 
	* Se não existir, vincula.
	* Se existir, verifcar se é o mesmo enviado
	**/
	private function checkDevice($usuario, $deviceId) {

		// PARA TESTAR EM MAIS DE UM DISPOSITIVO
		if ($usuario == 'fabio.bertoldi') return true;

		if (!empty($usuario) && !empty($deviceId)) {

			$db_deviceid = $this->db->fetchOne("select deviceid from sistema.usuarios 
				where ds_nome_usuario = '{$usuario}'");

			if (empty($db_deviceid)) {
				try {
					$this->db->update('sistema.usuarios', array('deviceid' => $deviceId), "ds_nome_usuario = '{$usuario}'");
					return true;
				} catch (Exception $e) {
					return $e->getMessage();
				}
			} elseif ($deviceId == $db_deviceid) {
				return true;
			} else {
				return false;
			}
		}
	}

	/*
	* Cria um token para acesso com expiração até o próximo dia
	**/
	private function getToken($usuario) {
		$token = crypt($usuario.'$1$'.base64_encode('$1$#1th0uGHt14M4h4cker$2oi6').date('Ymd'), '$1$'.base64_encode('$1$#1th0uGHt14M4h4cker$2oi6'));
		return base64_encode($token);
	}

	/**
	* @param string usuario
	* @param string senha
	* @return string
	*/
	public function login($usuario, $senha, $deviceId = "") {

		$usuario = trim($usuario); 
		$senha = trim($senha);

		if ($this->checkIdentity($usuario, $senha)) {
			//valida se o usuário está habilitádo
			if (!$this->isUserAble($usuario)) {
				return array('status' => false, 'message' => $this->getError(9));
			}

			$token = $this->getToken($usuario, $senha);
			if(!is_array($this->checkToken($token))) {
				//insere token para o usuario
				try {
					$this->db->update('sistema.usuarios', array('token' => $token), "ds_nome_usuario = '$usuario'");
				} catch (Exception $e) {
					return $e->getMessage();
				}
			}

             if (!$this->checkDevice($usuario, $deviceId)) {
             	return array('status' => false, 'message' => $this->getError(8));
             }

			$vistoriador = $this->getVistoriador($usuario);
			$vistoriador['token'] = $token;

			//buscando data e nome de arquivo de base zoneamento atualizado
			$db_zoneamento = $this->db->fetchRow("select to_char(dt_criacao, 'DD/MM/YYYY HH24:MM:SS') as dt_alteracao, ds_nome_arquivo, md5 from sistema.versao_zoneamento where fl_ativo = true");
			$vistoriador['zoneamento']['dt_alteracao'] = $db_zoneamento['dt_alteracao'];
            $vistoriador['zoneamento']['md5_arquivo'] = $db_zoneamento['md5'];
            
			if (getenv('APPLICATION_ENV') != 'production') {
                $http = @$_SERVER['HTTPS'] ? 'https://' : 'http://';
				$arUrl = explode(':', $_SERVER['HTTP_HOST']);
                if (count($arUrl)>1) {
				    $port = substr($arUrl[1],1,strlen($arUrl[1]));
    				$vistoriador['zoneamento']['link'] = $http.$arUrl[0].':5'.$port.'/db_zoneamento/'.$db_zoneamento['ds_nome_arquivo'];
                } else {
                    $vistoriador['zoneamento']['link'] = $http.str_replace('previadigital','agronet',$_SERVER['HTTP_HOST']).'/db_zoneamento/'.$db_zoneamento['ds_nome_arquivo'];
                }
			} else {
				$vistoriador['zoneamento']['link'] = "https://agronet.agrobrasilseguros.com.br/db_zoneamento/".$db_zoneamento['ds_nome_arquivo'];
			}

			return array('status' => true, 'vistoriador' => $vistoriador);
		} else {
			return array('status' => false, 'message' => $this->getError(1));
		}
	}

	private function isUserAble($usuario) {
		//usuário de exceção
		if ($usuario == $this->exceptionUser) {
			return true;
		}

        $this->setDb();
        $Usuario = $this->db->select();
        $Usuario->from(array('u' => 'sistema.usuarios'), array('id','ds_nome_usuario','token'));
        $Usuario->where('u.ds_nome_usuario = ?', $usuario);
        $Usuario->where('u.fl_liberado_tablet_previa = ?', true);

        $Row = $this->db->fetchRow($Usuario);

		if (is_array($Row)) {
			return true;
		}

		return false;
	}

    /**
     * @param $token
     * @return array
     */
	public function getZoneamentoDbInfo($token) {

		try {
            $user = $this->checkToken($token);
			if (!is_array($user)) {
				return array('status' => false, 'message' => $this->getError(0));
			}

            //buscando data e nome de arquivo de base zoneamento atualizado
            $db_zoneamento = $this->db->fetchRow("select to_char(dt_criacao, 'DD/MM/YYYY HH24:MM:SS') as dt_alteracao, ds_nome_arquivo, md5 from sistema.versao_zoneamento where fl_ativo = true");
            $zoneamento['dt_alteracao'] = $db_zoneamento['dt_alteracao'];
            $zoneamento['md5_arquivo'] = $db_zoneamento['md5'];

    	    if (getenv('APPLICATION_ENV') != 'production') {
                $http = @$_SERVER['HTTPS'] ? 'https://' : 'http://';
	    	    $arUrl = explode(':', $_SERVER['HTTP_HOST']);
                if (count($arUrl)>1) {
		            $port = substr($arUrl[1],1,strlen($arUrl[1]));
                    $zoneamento['link'] = $http.$arUrl[0].':5'.$port."/db_zoneamento/".$db_zoneamento['ds_nome_arquivo'];
                } else {
                    $zoneamento['link'] = $http.str_replace('previadigital','agronet',$_SERVER['HTTP_HOST'])."/db_zoneamento/".$db_zoneamento['ds_nome_arquivo'];
                }
            } else {
                $zoneamento['link'] = "https://agronet.agrobrasilseguros.com.br/db_zoneamento/".$db_zoneamento['ds_nome_arquivo'];
            }

			return array('status' => true, 'zoneamento' => $zoneamento);
		} catch (Exception $e) {
            return array('status' => false, 'message' => $this->getError(7));
        }
	}

	/**
	* @param string usuario
	* @return array
	* Busca dados do vistoriador.
	*/
	private function getVistoriador($usuario) {
		try {
			$this->setDb();
			$Vistoriador = $this->db->select();
			$Vistoriador->from(array('usuarios' => 'sistema.usuarios'), false);
			$Vistoriador->join(array('funcionarios' => 'sistema.funcionarios'), 'usuarios.id = funcionarios.id_usuario', array('trim(ds_nome_funcionario) as ds_nome_vistoriador','id as id_vistoriador'));
			$Vistoriador->join(array('empresas' => 'sistema.empresas'), 'empresas.id = funcionarios.id_empresa', 'trim(ds_nome_fantasia) as ds_nome_empresa');
			$Vistoriador->where('usuarios.ds_nome_usuario = ?', $usuario);

			return $this->db->fetchRow($Vistoriador);
		} catch (Exception $e) {
			return false;
		}
	}

    /**
	* @param string token
	* @param integer id_chamado
	* @return object
	*/
	private function getChamados($token,$id_chamado) {

		if (is_array($this->checkToken($token))) {
			$this->setDb();
			$Chamado = $this->db->select()->distinct(true);
			$Chamado->from(array('c' => 'atendimento.v_chamados'), array('id_usuario_criacao', 'id_usuario_alteracao', 'fl_ativo', 'fl_del', 'id', 'id_prioridade', 'id_tipo_chamado', 'id_status', 'id_departamento', 'id_proposta', 'ds_descricao', 'id_responsavel', "c.dt_criacao as data_criacao"));
			$Chamado->where('c.id = '.$id_chamado);

			$Row = $this->db->fetchRow($Chamado);
		} else {
			return array('status' => false, 'message' => $this->getError(0));
		}

		return (is_array($Row) ? array('status' => false, 'chamado' => $Row) : array('status' => false, 'message' => $this->getError(0)));
	}

	/**
	* @param string token
	* @return string
	*/
	private function whoAmI($token) {
		$ami = $this->checkToken($token);

		if ($ami) {
			return $ami['ds_nome_usuario'];
		}
		return array('status' => false, 'message' => $this->getError(0));
	}

	/**
	* @param int id_proposta
	* @param int id_vistoria
	* @param int id_status_tablet
	* @param string token
	* @return String json
	*/
	public function setStatusVistoria($id_proposta, $id_vistoria, $id_status_tablet, $token) {
		try {

			if ($this->checkToken($token)) {
				$this->setDb();
				$this->db->update('seguro.propostas_vistorias_previas', 
					array('id_status_tablet' => $id_status_tablet), 
					'id_proposta = ' . $id_proposta . ' AND id_vistoria = ' . $id_vistoria);
				return array('status' => true, 'message' => 'Status atualizado com sucesso.');
			} else {
				return array('status' => false, 'message' => $this->getError(0));
			}
			
		} catch (Exception $e) {
			return array('status' => false, 'message' => $this->getError(3) . "\n" . $e->getMessage());
		}
    }
    
    /**
     * 
     */
    private function setCleaned($id_prposta, $id_vistoria, $was_cleaned, $token) {
        try {
            if ($this->checkToken($token)) {
                $this->setDb();
                $this->db->update('seguro.propostas_vistorias_previas',
                    array('fl_was_cleaned_in_tablet' => $was_cleaned),
                    'id_proposta = ' . $id_prposta . ' AND id_vistoria = ' . $id_vistoria);
                return array('status' => true, 'message' => 'Status atualizado com sucesso.');
            } else {
                return array('status' => false, 'message' => $this->getError(0));
            }
        } catch (Exception $e) {
            return array('status' => false, 'message' => $this->getError(10) . "\n" . $e->getMessage());
        }
    }

	/**
	* @param integer id_proposta
	* @return array
	*/
	private function getQuestionario($id_proposta) {
		$i = 1;
		$qst = array('QUEST_OUTRO_SEGURO','QUEST_OUTRA_LAVOURA','QUEST_AREA_DECLARADA');
		$opc = array('QUEST_AREA_DECLARADA_PROP_COMPLEMENTAR','QUEST_AREA_DECLARADA_OUTRO');

		$Select = $this->db->select();
		$Select->from(array('pa' => 'produto.atributos_rn'), array('ds_descricao_atributo', "CASE WHEN pa.id_tipo_atributo <> 1 THEN split_part(split_part(ds_valores_opcoes,'|'::text,(ds_resposta::integer+1)::integer),':'::text,2) ELSE ds_resposta END as resposta", 'ds_chave_rn'));
		$Select->join(array('pq' => 'seguro.propostas_questionario'), 'pa.id = pq.id_atributo_rn', false);
		$Select->where("ds_chave_rn in ('QUEST_AREA_DECLARADA_PROP_COMPLEMENTAR','QUEST_AREA_DECLARADA_OUTRO','QUEST_OUTRO_SEGURO','QUEST_OUTRA_LAVOURA','QUEST_AREA_DECLARADA')");
		$Select->where('pq.id_proposta = ?', $id_proposta);
		$Select->order('pa.id');

		$questions = $this->db->fetchAll($Select);

		foreach ($questions as $quest) {

			if ($quest['ds_chave_rn'] == 'QUEST_AREA_DECLARADA') {
				$add =  $quest['resposta'];
			}

			if (in_array($quest['ds_chave_rn'], $qst)) {
				$return[]['os_quest_'.$i] = $quest['ds_descricao_atributo'].' '.$quest['resposta'];
				$i++;
				continue;
			}

			if (in_array($quest['ds_chave_rn'], $opc) && $add == 'Não') {
				$return[]['os_quest_'.$i] = $quest['ds_descricao_atributo'].' '.$quest['resposta'];
				$i++;
			}
		}

		return $return;

	}

	/**
	* @param integer id_proposta
	* @param integer id_produto
	* @return
	*/
	private function getCarencia($id_proposta,$id_produto) {
		$Select = $this->db->select();
		$Select->from(array('pc' => 'produto.produtos_coberturas'), false);
		$Select->join(array('pce' => 'produto.produtos_coberturas_condicoes_especiais'), 'pc.id_cobertura = pc.id_cobertura and pc.id_produto = pce.id_produto',null);
		$Select->join(array('ce' => 'produto.condicoes_especiais'), 'pce.id_condicao_especial = ce.id', "string_agg(ds_condicao_especial,' ') as os_condicao_especial");
		$Select->join(array('sc' => 'seguro.propostas_coberturas'), 'sc.id_cobertura = pc.id_cobertura and sc.id_cobertura = pce.id_cobertura', null);
		$Select->where('pc.fl_contratacao_automatica = false');
		$Select->where('pc.id_produto = ?', $id_produto);
		$Select->where('sc.id_proposta = ?', $id_proposta);

		$carencia = $this->db->fetchAll($Select);
		return $carencia[0]['os_condicao_especial'];
	}

	/**
	* @param integer id_proposta
	* @return
	*/
	private function getInformacoesAdicionais($id_proposta) {
		$Select = $this->db->select();
		$Select->from(array('po' => 'seguro.propostas_observacoes'), array("to_char(dt_criacao, 'DD/MM/YYYY') as data", 'ds_observacao'));
		$Select->where('po.id_proposta = ?', $id_proposta);
		$Select->where('po.fl_principal is false');
		$Select->where('po.fl_observacao_endosso is true');
		$Select->order('dt_criacao DESC');

		return $this->db->fetchAll($Select);
    }
    
    /**
     * Busca no banco de dados as propostas que estão com exceção para salvar
     * 
     * @return array Propostas que estão na exceção e não serão salvas
     */

     private function getPropostasExcecao() {
        $select = $this->db->select();
        $select->from(array('st' => 'sistema.propostas_excecao_vistoria_previa'));
        $propostas = $this->db->fetchAll($select);

        $propostas = array_map(function($i) {
            return $i['id_proposta'];
        }, $propostas);

        return $propostas;
     }

	/**
	 * @param array $vistoria Dados da vistoria para serem salvos nos laudo
	 * @param string $token Token de validação do usuário logado
	 */
	public function setVistoria($vistoria, $token) {
		$user = $this->checkToken($token);
		error_reporting(error_reporting() ^ E_NOTICE);
		if (!$user) {
			return array('status' => 'error', 'message' => $this->getError(0));
        }

        $propostasExcecao = $this->getPropostasExcecao();
		if (in_array($vistoria['idProposta'], $propostasExcecao)) {
            $this->logSuccess('Vistoria já transmitida e liberada na exceção!', $vistoria);
            return array('status' => 'success', 'message' => $this->getError(5));
		}

		try {
			$this->db->beginTransaction();
			$nextIdLVP001 = $this->db->nextSequenceId('regulacao.lvp001_id_seq');

			$errorMessages = $this->validateVistoriaData($vistoria);
			if (!empty($errorMessages)) {
			    throw new SeventapException($this->logErrorVistoria($errorMessages, $vistoria['idProposta']));
            }

            $this->saveVistoriaPrevia($vistoria, $user);
            $message  = "Proposta: ".$vistoria['idProposta'].PHP_EOL;
            $message .= "Vistoria: ".$vistoria['idVistoria'].PHP_EOL;
            $message .= "Data e Hora da recepção: ".date('d/m/Y H:i').PHP_EOL;
            $message .= "Usuário: ".$user['ds_nome_usuario'].PHP_EOL;
            $this->logSuccess($message, $vistoria);

            $this->db->commit();
        } catch (SeventapException $se) {
            $this->db->rollback();
            if ($se->getCode() == 200) {
                $message  = "Info: ".$se->getMessage(). PHP_EOL;
                $message .= "Proposta: ".$vistoria['idProposta'].PHP_EOL;
                $message .= "Vistoria: ".$vistoria['idVistoria'].PHP_EOL;
                $message .= "Data e Hora da recepção: ".date('d/m/Y H:i').PHP_EOL;
                $message .= "Usuário: ".$user['ds_nome_usuario'].PHP_EOL;
                $this->logSuccess($message, $vistoria);
                return array('status' => 'success', 'message' => 'Vistoria já existe');
            } else {
                $message  = "Erro: ".$se->getMessage(). PHP_EOL;
                $message .= "Proposta: ".$vistoria['idProposta'].PHP_EOL;
                $message .= "Vistoria: ".$vistoria['idVistoria'].PHP_EOL;
                $message .= "Data e Hora da recepção: ".date('d/m/Y H:i').PHP_EOL;
                $message .= "Usuário: ".$user['ds_nome_usuario'].PHP_EOL;
                $this->logError($message, $vistoria);
                return array('status' => 'error', 'message' => $this->getError(4));
			}
        } catch (Exception $e) {
            $this->db->rollback();
            $message  = "Erro: ".$e->getMessage(). PHP_EOL;
            $message .= "Proposta: ".$vistoria['idProposta'].PHP_EOL;
            $message .= "Vistoria: ".$vistoria['idVistoria'].PHP_EOL;
            $message .= "Data e Hora da recepção: ".date('d/m/Y H:i').PHP_EOL;
            $message .= "Usuário: ".$user['ds_nome_usuario'].PHP_EOL;
			$this->logError($message, $vistoria);
			return array('status' => 'error', 'message' => $this->getError(4));
        }

		//feito separadamente para não atrapalhar a transação, pois necessita que ela esteja concluida
		try {
            $this->generateLaudoPdf($vistoria);
		} catch (Exception $e) {
            $message  = "Erro Geração de Laudo: ".$e->getMessage(). PHP_EOL;
            $message .= "Proposta: ".$vistoria['idProposta'].PHP_EOL;
            $message .= "Vistoria: ".$vistoria['idVistoria'].PHP_EOL;
            $message .= "Data e Hora da recepção: ".date('d/m/Y H:i').PHP_EOL;
            $message .= "Usuário: ".$user['ds_nome_usuario'].PHP_EOL;
			$this->logError($message, $vistoria);
		}
        return array('status' => 'success', 'message' => $this->getError(5));
	}

	private function saveDeviceInfo($vistoria) {
	    if ($vistoria['idVistoria']) {
            $this->db->query("INSERT INTO sistema.vistoria_dispositivo (id_vistoria, dispositivo_info) VALUES ('{$vistoria['idVistoria']}', '{$vistoria['deviceId']}')");
        }
    }

    /**
     * Loga as informações da transmissão 
     */
    private function logTransmission($vistoria, $stateof) {
        $t = microtime(true);
        $micro = sprintf("%06d",($t - floor($t)) * 1000000);
        $d = new DateTime( date("Y-m-d H:i:s.".$micro, $t) );
    
        $filename = $d->format("YmdHisu") . "_request_data_".$stateof.".json";
        $path = realpath(dirname(__FILE__) . '/../../application').'/upload_files/log_transmissao_vp/'.$filename;
        file_put_contents($path, json_encode($vistoria));

        //guarda as informações do modelo do device utilizado
        $this->saveDeviceInfo($vistoria);

        return $path;
    }

	 /**
     * Gera o laudo pdf da vistoria
     */
    private function generateLaudoPdf($vistoria) {
        $queryVistoriaPrevia = $this->db->select();
        $queryVistoriaPrevia->from('seguro.propostas_vistorias_previas', '*');
//        $queryVistoriaPrevia->where('id_proposta = ?', $vistoria['idProposta']);
        $queryVistoriaPrevia->where('id_vistoria = ?', $vistoria['idVistoria']);

        $vistoriaPrevia = $this->db->fetchRow($queryVistoriaPrevia);

        //envia a geração do laudo para uma fila
        // if (getenv('APPLICATION_ENV') != 'production') {
        	$command = "python3 ..".DIRECTORY_SEPARATOR."rabbitmq".DIRECTORY_SEPARATOR."send.py ".$vistoriaPrevia['id'];
        // } else {
        // 	$cmd = "php ..".DIRECTORY_SEPARATOR."Curl".DIRECTORY_SEPARATOR."geralaudoprevia.php ".$vistoriaPrevia['id'];	
        // 	$command = 'nohup '.$cmd.' > /dev/null 2>&1 & echo $!';
        // }
        
        exec($command ,$op);
        $return = (int)$op[0];

		return null;
	}

    /**
     * Busca os corretores pela proposta
     */
	private function buscaCorretorProposta($idProposta) {
		if ($idProposta) {
            $Select = $this->db->select();
            $Select->from(array('pc' => 'seguro.propostas_corretores'), false);
            $Select->join(array('c' => 'sistema.corretores'), 'pc.id_usuario = c.id_usuario', array('*'));
            $Select->where('id_proposta = ?', $idProposta);
            $corretor = $this->db->fetchRow($Select);

            return $corretor;
        }

        return false;
	}

    /**
	 * Monta o título e a mensagem do Email que é enviado para o corretor ou segurado
	 *
     * @param $vistoria Valores da vistoria
     */
	private function montaEmailLaudo($vistoria) {
		$this->registryEmail();

        $Select = $this->db->select();
        $Select->from(array('pc' => 'seguro.v_id_proposta_mae_completo'), array('id_proposta', 'chave_mae'));
        $Select->where('id_proposta = ?', $vistoria['idProposta']);
        $propostaCompleto = $this->db->fetchRow($Select);

        $selectProponente = $this->db->select();
        $selectProponente->from(array('pc' => 'seguro.propostas_proponentes'), '*');
        $selectProponente->where('id_proposta = ?', $vistoria['idProposta']);
        $proponente = $this->db->fetchRow($selectProponente);

		$titulo = "VISTORIA - ".$vistoria['idVistoria'].": Proposta ".$propostaCompleto['chave_mae']." / ".$proponente['ds_nome_proponente'];

		$filename = realpath(dirname(__FILE__)) . "/../../agronet/resources/imagens/assinatura_email_tecnica.png";
        $at = $this->email->createAttachment(file_get_contents($filename));
        $at->type = $this->mimeByExtension($filename);
        $at->disposition = Zend_Mime::DISPOSITION_INLINE;
        $at->encoding = Zend_Mime::ENCODING_BASE64;
        $at->id = 'cid_' . md5_file($filename);

        $dataConclusaoVistoria = new DateTime($vistoria['dataConclusaoVistoria']);

		$mensagem = "
<p style=\"margin-bottom: 15px\">Prezado Corretor,</p>

<p style=\"margin-bottom: 15px\">
Informamos que a vistoria foi realizada conforme documento em anexo.
</p>

<p style=\"margin-bottom: 15px\">
Data da realização: {$dataConclusaoVistoria->format('d/m/Y')}
</p>

<p style=\"margin-bottom: 45px\">
Status da Vistoria: Em análise pela Seguradora. 
</p>

<img src=\"cid:".$at->id."\" height=\"120\" width=\"467\" />
<br />
<span style=\"color: grey; margin: 0!important;  font-family: Verdana; font-size: .5em; text-align: left; display: block;\">
<font face='webdings' style=\"color: darkgreen\">i</font> 
<span style=\"color: darkblue\"> Este e-mail, inclusive anexos, podem conter informações confidenciais de propriedade exclusiva da AgroBrasil Seguros,
<br />não devendo ser utilizado, copiado ou revelado sem prévia autorização.</span> This e-mail, including attachments, is intended<br /> for
the person(s) or company named and may contain confidential and/or legally privileged information. Unauthorized<br /> disclosure,
copying or use of this information may be unlawful and is prohibited. If you are not the intended recipient,<br /> please delete this
message and notify the sender.
</span>
<br />
<span style=\"color: grey; margin: 0!important; font-family: Verdana; font-size: .5em; text-align: left; display: block\">
<font face='webdings'  style=\"color: darkgreen\">P</font> <span style=\"font-weight: bold\">Antes de imprimir, pense em seu compromisso com o Meio Ambiente.</span> Before printing, think about your<br /> commitment
to the environment.
</div>
";

		return array('titulo' => $titulo, 'mensagem' => $mensagem);
	}

    private function mimeByExtension($filename)
    {
        if (is_readable($filename) ) {
            $extension = pathinfo($filename, PATHINFO_EXTENSION);
            switch ($extension) {
                case 'gif':
                    $type = 'image/gif';
                    break;
                case 'jpg':
                case 'jpeg':
                    $type = 'image/jpg';
                    break;
                case 'png':
                    $type = 'image/png';
                    break;
                default:
                    $type = 'application/octet-stream';
            }
        }

        return $type;
    }

    /**
     * Salva a vistoria prévia
     *
     * @param array $vistoria
     */
    private function saveVistoriaPrevia($vistoria, $user) {
        $queryStatusTransmitidaSemFotos = $this->db->select();
        $queryStatusTransmitidaSemFotos->from('sistema.status', 'status.id');
        $queryStatusTransmitidaSemFotos->join('sistema.tipo_status', 'status.id_tipo_status = tipo_status.id', null);
        $queryStatusTransmitidaSemFotos->where('status.ds_chave = ?', 'TRANSMITIDA_SEM_FOTOS');
        $queryStatusTransmitidaSemFotos->where('tipo_status.ds_chave = ?', 'VP');
        
        $statusTransmitidaSemFotos = $this->db->fetchRow($queryStatusTransmitidaSemFotos);
        
        $queryStatusAnalise = $this->db->select();
        $queryStatusAnalise->from('sistema.status', 'status.id');
        $queryStatusAnalise->join('sistema.tipo_status', 'status.id_tipo_status = tipo_status.id', null);
        $queryStatusAnalise->where('status.ds_chave = ?', 'NAO_ANALISADO');
        $queryStatusAnalise->where('tipo_status.ds_chave = ?', 'VP_ANALISE');

        $statusAnalise = $this->db->fetchRow($queryStatusAnalise);

        $queryVistoriaPrevia = $this->db->select();
        $queryVistoriaPrevia->from('seguro.propostas_vistorias_previas', '*');
        $queryVistoriaPrevia->join('seguro.propostas', 'propostas_vistorias_previas.id_proposta = propostas.id', null);
        $queryVistoriaPrevia->join('seguro.propostas_endosso', 'propostas_endosso.id_endosso = propostas.id_endosso and propostas_endosso.fl_proposta_vigente = true', null);
        // $queryVistoriaPrevia->where('propostas_endosso.id_proposta = propostas_vistorias_previas.id_proposta');
        // $queryVistoriaPrevia->where('id_proposta = ?', $vistoria['idProposta']);
        $queryVistoriaPrevia->where('id_vistoria = ?', $vistoria['idVistoria']);

        $vistoriaPrevia = $this->db->fetchRow($queryVistoriaPrevia);

        if (empty($vistoriaPrevia)) {
            throw new SeventapException('Vistoria Prévia inválida! idProposta:'.$vistoria['idProposta'].' idVistoria: '.$vistoria['idVistoria']);
        }

        $vistoria['idProposta'] = $vistoriaPrevia['id_proposta'];

        $deviceId = explode('|', $vistoria['deviceId']);
        $dtLaudo = new \DateTime($vistoria['dataConclusaoVistoria']);

        //caso esteja cancelada(227), mantém  cancelada
        /* $idStatusVistoriaPrevia = $vistoriaPrevia['id_status'] == 227 ? $vistoriaPrevia['id_status'] : $status['id']; */

        //monta os valores para salvar a vistoria
        $values = array(
            'id_proposta' => $vistoria['idProposta'],
            'id_vistoria' => $vistoria['idVistoria'],
            'id_status' => $statusTransmitidaSemFotos['id'],
            'id_status_analise' => $statusAnalise['id'],
            'id_usuario_alteracao' => $user['id'],
            'dt_alteracao' => date('Y-m-d H:i:s'),
            'id_tablet' => $deviceId[0],
            'dt_transmitido_tablet' => date('Y-m-d H:i:s'),
            'fl_transmitido_tablet' => 'true',
            'fl_transmitido' => 'true',
            'dt_laudo' => $dtLaudo->format('Y-m-d')
        );

        //atualiza a vistoria
        $result = $this->db->update('seguro.propostas_vistorias_previas', $values, "id = '{$vistoriaPrevia['id']}'");

        if (empty($result)) {
            throw new SeventapException('Erro ao atualizar a vistoria prévia! idProposta:'.$vistoria['idProposta'].' idVistoria: '.$vistoria['idVistoria']);
        }

		$idStatusResolvido = 74;
		$idTipoChamadoConfirmarContato = 92;

		$queryChamadosConfirmarContato = $this->db->select();
		$queryChamadosConfirmarContato->from('atendimento.chamados', '*');
		$queryChamadosConfirmarContato->where('id_proposta = ?', $vistoria['idProposta']);
		$queryChamadosConfirmarContato->where('id_tipo_chamado = ?', $idTipoChamadoConfirmarContato);
		$queryChamadosConfirmarContato->where('id_status <> ?', $idStatusResolvido);
		$queryChamadosConfirmarContato->where('id_parent is null');

		$chamadosConfirmarContato = $this->db->fetchAll($queryChamadosConfirmarContato);

		$dadosFinalizarChamado = [
			'id_tipo_chamado' => $idTipoChamadoConfirmarContato,
			'id_proposta' => $vistoria['idProposta'],
			'id_status' => $idStatusResolvido,
			'ds_descricao' => 'Finalização automática devido a transmissão da vistoria',
		];

		foreach ($chamadosConfirmarContato as $chamado) {
			$dadosFinalizarChamado['id_prioridade'] = $chamado['id_prioridade'];
			$dadosFinalizarChamado['id_departamento'] = $chamado['id_departamento'];
			$dadosFinalizarChamado['id_parent'] = $chamado['id'];
			$dadosFinalizarChamado['id_usuario_criacao'] = $dadosFinalizarChamado['id_responsavel'] = $chamado['id_responsavel'];

			$result = $this->db->insert('atendimento.chamados', $dadosFinalizarChamado);

			if (empty($result)) {
				throw new SeventapException('Erro ao finalizar o chamado do tipo Confirmar Contato! idProposta:'.$vistoria['idProposta'].' idVistoria: '.$vistoria['idVistoria']);
			}

			$result = $this->db->update('atendimento.chamados', ['id_status' => $idStatusResolvido], "id = {$chamado['id']}");

			if (empty($result)) {
				throw new SeventapException('Erro ao atualizar o status do chamado de tipo Confirmar Contato! idProposta:'.$vistoria['idProposta'].' idVistoria: '.$vistoria['idVistoria']);
			}
		}

        $queryFuncionarioLogado = $this->db->select();
        $queryFuncionarioLogado->from('sistema.funcionarios', '*');
        $queryFuncionarioLogado->where('id_usuario = ?', $user['id']);

        $funcionario = $this->db->fetchRow($queryFuncionarioLogado);

        $valuesHistorico = array(
            'id_status_analise' => $statusAnalise['id'],
            'id_status' => $statusTransmitidaSemFotos['id'],
            'id_proposta_vistoria' => $vistoriaPrevia['id'],
            'ds_motivo' => 'Transmissão Laudo - Tablet.',
            'id_usuario_criacao' => $user['id'],
            'dt_criacao' => date('Y-m-d H:i:s'),
            'id_empresa' => $funcionario['id_empresa'],
            'fl_ativo' => 'true',
            'fl_del' => 'false',
            'fl_necessario_endosso' => 'false'
        );

        $affectedRows = $this->db->insert('seguro.propostas_vistorias_previas_historico', $valuesHistorico);
        $idVistoriaPreviaHistorico = $this->db->lastInsertId();

        if (empty($affectedRows)) {
            throw new SeventapException('Erro ao inserir histórico da vistoria prévia! idProposta:'.$vistoria['idProposta'].' idVistoria: '.$vistoria['idVistoria'].' idPropostaVistoria: '.$vistoriaPrevia['id']);
        }

        //valida se já possui um laudo
        $select = $this->db->select();
        $select->from('regulacao.lvp001', '*');
        $select->where('id_proposta_vistoria = ?', $vistoriaPrevia['id']);

        $result = $this->db->fetchRow($select);

        if (!empty($result)) {
			$code = 0;
			if ($vistoriaPrevia['fl_transmitido'] && !empty($vistoriaPrevia['dt_laudo'])) {
				$code = 200;
			}
            throw new SeventapException('Esta vistoria já possui um laudo digitado! idProposta:'.$vistoria['idProposta'].' idVistoria: '.$vistoria['idVistoria'].' idPropostaVistoria: '.$vistoriaPrevia['id'], $code);
        }

        //insere as informações do laudo
        $dtLaudo = new \DateTime($vistoria['dataConclusaoVistoria']);
        $queryMunicipio = $this->db->select();
        $queryMunicipio->from('sistema.municipios', '*');
        $queryMunicipio->where('id = ?', $vistoria['municipioId']);
        $local = $this->db->fetchRow($queryMunicipio);

        $queryPropostaPropriedade = $this->db->select();
        $queryPropostaPropriedade->from(array('p' => 'seguro.propostas_propriedades'), '*');
        $queryPropostaPropriedade->join(array('m' => 'sistema.municipios'), 'p.id_municipio = m.id', array('id_estado'));
        $queryPropostaPropriedade->where('id_proposta = ?', $vistoria['idProposta']);
        $propriedade = $this->db->fetchRow($queryPropostaPropriedade);
        
        $houveTrocaMunicipio = $propriedade['id_municipio'] != $vistoria['municipioId'];
        $idMunicipio = $houveTrocaMunicipio ? $vistoria['municipioId'] : null;

        $necessarioNovaVistoriaQuadras = false;
        foreach ($vistoria['vistoriaQuadras'] as $quadra) {
        	if ($quadra['novaVistoriaNecessaria']) {
        		$necessarioNovaVistoriaQuadras = true;
        	}
        }

        $valuesLaudo = array(
            'id_proposta_vistoria' => $vistoriaPrevia['id'],
            'id_usuario_criacao' => $user['id'],
            'ds_local' => $local['ds_nome_municipio'],
            'dt_laudo' => $dtLaudo->format('Y-m-d'),
            'hr_laudo' => $dtLaudo->format('H:i'),
            'ds_observacao' => $vistoria['observacoes'],
            'ds_vistoriador' => $funcionario['ds_nome_funcionario'],
            'id_vistoriador' => $funcionario['id'],
            'fl_necessario_vistoria' => (isset($vistoria['dataNovaVistoria']) && !empty($vistoria['dataNovaVistoria'])) || $necessarioNovaVistoriaQuadras ? 'true' : 'false',
            'dt_agendada_vistoria' => $vistoria['dataNovaVistoria'],
            'fl_reavaliacao' => (isset($vistoria['dataNovaVistoria']) && !empty($vistoria['dataNovaVistoria'])) || $necessarioNovaVistoriaQuadras ? 'true' : 'false',
            'dt_reavaliacao' => $vistoria['dataNovaVistoria'],
            'chk_acompanhante' => isset($vistoria['infoSegurado']) && !empty($vistoria['infoSegurado']) ? $vistoria['infoSegurado']['tipo'] : 'sem_assinatura',
            'cpf_acompanhante' => isset($vistoria['infoSegurado']) && !empty($vistoria['infoSegurado']) ? $vistoria['infoSegurado']['cpf'] : null,
            'ds_acompanhante' => isset($vistoria['infoSegurado']) && !empty($vistoria['infoSegurado']) ? $vistoria['infoSegurado']['nome'] : null,
            'fl_acompanhante' => isset($vistoria['infoSegurado']) && !empty($vistoria['infoSegurado']) && in_array($vistoria['infoSegurado']['tipo'], array('autorizado', 'outro')) ? 1 : 0, //TODO
            'ds_nivel_tecnologico' => $vistoria['nivelTecnologico'],
            'troca_estado_municipio' => (int)$houveTrocaMunicipio,
            'ds_email' => isset($vistoria['infoSegurado']) && !empty($vistoria['infoSegurado']) ? $vistoria['infoSegurado']['email'] : null,
            'id_municipio' => $idMunicipio,
            'svg_assinatura_perito' => $vistoria['assinaturaVistoriador'],
            'svg_assinatura_segurado' => $vistoria['infoSegurado']['assinatura'],
            'fl_transmitido' => 'true',
            'dt_transmissao' => date('Y-m-d'),
        );

        $valuesLaudo['prioridade_conferencia'] = $this->getPrioridadeConferencia($vistoria);

        $result = $this->db->insert('regulacao.lvp001', $valuesLaudo);

        if (empty($result)) {
            throw new SeventapException('Erro ao inserir o laudo da vistoria prévia! idProposta:'.$vistoria['idProposta'].' idVistoria: '.$vistoria['idVistoria'].' idPropostaVistoria: '.$vistoriaPrevia['id']);
        }

        $select = $this->db->select();
        $select->from('regulacao.lvp001', '*');
        $select->where('id_proposta_vistoria = ?', $vistoriaPrevia['id']);
        $laudo = $this->db->fetchRow($select);

        //Informações do CROQUI
        foreach ($vistoria['quadrasDesenhadas'] as $key => $quadra) {
            $valuesCroqui = array(
                'id_usuario_criacao' => $user['id'],
                'dt_criacao' => date('Y-m-d H:i:s'),
                'id_laudo' => $laudo['id'],
                'ds_coordenadas_poligono' => json_encode($quadra['poligono']),
                'area' => round($quadra['area'], 4),
                'nome' => str_replace("\n", '', $quadra['nome']),
            );

            $result = $this->db->insert('regulacao.lvp001_croqui', $valuesCroqui);

            if (empty($result)) {
                throw new SeventapException('Erro ao inserir as coordenadas do croqui! idProposta:'.$vistoria['idProposta'].' idVistoria: '.$vistoria['idVistoria'].' idPropostaVistoria: '.$vistoriaPrevia['id']);
            }
        }

        //FOTOS da proposta
        $valuesArquivos = array();
        foreach ($vistoria['imagensAdicionais'] as $key => $imagem) {
        	$arNameImage = explode('/', $imagem['uri']);

        	$valuesArquivos = array(
        		'ds_nome_arquivo' => end($arNameImage),
        		'id_tipo_arquivo_laudo_previa' => 3, //FOTO
        		'id_proposta_vistoria' => $vistoriaPrevia['id'],
        		'id_usuario_criacao' => $user['id'],
            	'dt_criacao' => date('Y-m-d H:i:s'),
        	);

        	$result = $this->db->insert('seguro.propostas_vistorias_previas_arquivos', $valuesArquivos);

        	if (empty($result)) {
                throw new SeventapException('Erro ao inserir as fotos da vistoria! idProposta:'.$vistoria['idProposta'].' idVistoria: '.$vistoria['idVistoria'].' idPropostaVistoria: '.$vistoriaPrevia['id']);
            }
        }

        $selectVunidades = $this->db->select()->from('seguro.v_unidades_seguradas')->where('id_proposta = ?', $vistoria['idProposta']);
        $vUnidades = $this->db->fetchAll($selectVunidades);

        $rendimentoProposta = 0;
        foreach ($vUnidades as $keyUnidade => $unidade) {
            if ($rendimentoProposta < $unidade['is_produtividade']) {
                $rendimentoProposta = $unidade['is_produtividade'];
            }
        }

		$selectItensMae = $this->db->select();
		$selectItensMae->from(array('spe' => 'seguro.propostas_endosso'), null);
		$selectItensMae->join(array('sp' => 'seguro.propostas'), 'spe.id_endosso = sp.id_endosso', null);
        $selectItensMae->join(array('sis' => 'seguro.itens_segurados'), 'spe.id_proposta = sis.id_proposta');
        $selectItensMae->where('spe.fl_proposta_vigente = true');
		$selectItensMae->where('sp.id = (
            SELECT vp.id_proposta
              FROM seguro.propostas_vistorias_previas vp
             WHERE id_vistoria = '.$vistoria['idVistoria'].')');
        $selectItensMae->order('sis.id');

		$itensVistoria = $this->db->fetchAll($selectItensMae);

		$selectPropostaVigente = $this->db->select();
		$selectPropostaVigente->from(['spe' => 'seguro.propostas_endosso'], false);
		$selectPropostaVigente->join(['spe2' => 'seguro.propostas_endosso'], 'spe2.id_endosso = spe.id_endosso', false);
		$selectPropostaVigente->join(['sp' => 'seguro.propostas'], 'sp.id = spe2.id_proposta and spe2.fl_proposta_vigente is true', false);
		$selectPropostaVigente->join(['spp' => 'seguro.propostas_propriedades'], ' spp.id_proposta = sp.id', ['ds_coordenadas']);
		$selectPropostaVigente->where('spe.id_proposta = ?', $vistoria['idProposta']);
		$rsPropostaVigente = $this->db->fetchRow($selectPropostaVigente);
            
		$countRetornoItemNovo = 0;
        //insere as informações das quadras do laudo
        
        foreach ($vistoria['vistoriaQuadras'] as $key => $quadra) {
            $select = $this->db->select();
            $select->from('seguro.itens_segurados', '*');
            $select->where('id = ?', $quadra['idTalhao']);
            $itemSegurado = $this->db->fetchRow($select);
            
            if (!$quadra['houvePlantio'] || !$quadra['areaDoSegurado']) {
            	$idCiclo = 16;
            } else {
            	$idCiclo = $this->getCiclo($vistoria['idProposta'], ($houveTrocaMunicipio ? $idMunicipio : $propriedade['id_municipio']), ($houveTrocaMunicipio ? $vistoria['ufId'] : $propriedade['id_estado']), $quadra['variedade'], $quadra['idProduto']);
            }

            // Para definir o número do ítem no retorno de uma vistoria,
            // pois, quando errado, impacta no endosso gerando confusão nos itens importados da vistoria prévia
            $nroItem = null;
            if (!empty($itensVistoria) && is_array($itensVistoria)) {
	            foreach ($itensVistoria as $key => $item) {
	            	if ($item['id'] == $quadra['idTalhao']) {     
                        $nroItem = $item['nr_item_segurado'];
                        break;
                    } else {
                        $nroItem = $quadra['numTalhao'];
                    }
	            }
                if (is_null($nroItem)) {
                    $nroItem = count($itensVistoria) + (++$countRetornoItemNovo);
                }
	        }

            if (is_null($nroItem)) {
                $nroItem = $key + 1;
            }
            
            //correção de um indice vindo errado do tablet
            $quadra['motivoNegacaoCultivoCicloAnterior'] = $quadra['motivoRendimentoInferior'];

            $valuesItemLaudo = array(
                'fl_area_plantada' => isset($quadra['houvePlantio']) ? ($quadra['houvePlantio']?'true':'false') : null,
                'fl_area_segurado' => $quadra['areaDoSegurado'] ? $quadra['areaDoSegurado'] : 'false',
                'fl_plantio_futuro' => isset($quadra['pretendePlantar']) ? ($quadra['pretendePlantar']?'true':'false') : null,
                'id_laudo_previa' => $laudo['id'],
                'nr_quadra' => $quadra['nome'],
                'ds_coordenadas' => $quadra['areaDoSegurado'] ? $quadra['latitude'].', '.$quadra['longitude'] : $rsPropostaVigente['ds_coordenadas'],
                'tipo_solo' => $quadra['tipoSolo'],
                'vl_altitude' => (int)$quadra['altitude'],
                'id_variedade' => ($quadra['variedade'] > 0 ? $quadra['variedade'] : 6971), //id variedade "Não está na lista (Inserir nas OBS)"
                'dt_final_semeadura' => $quadra['terminoPlantio'],
                'dt_inicio_semeadura' => $quadra['inicioPlantio'],
                'vl_area_declarada' => $quadra['areaDeclarada'],
                // 'vl_area_vistoriada' => $quadra['houvePlantio'] ? $quadra['areaVistoriada'] : $quadra['areaDeclarada'],
                'vl_area_vistoriada' => $quadra['areaVistoriada'] ? $quadra['areaVistoriada'] : (($quadra['areaDeclarada'] > 0 && $quadra['areaDeclarada'] == $quadra['areaExcluida'] && isset($quadra['houvePlantio'])) ? $quadra['areaDeclarada'] : 0),
                'vl_area_asseguravel' => $quadra['areaSeguravel'] ? $quadra['areaSeguravel'] : 0,
                'vl_area_excluida' => $quadra['areaExcluida'],
                'vl_rendimento_proposta' => (float)($itemSegurado['id'] ? $itemSegurado['vl_rendimento_tonelada'] : $rendimentoProposta),
                'fl_rendimento_inferior' => $quadra['rendimentoInferiorProposta'] ? $quadra['rendimentoInferiorProposta'] : 'false',
                'vl_rendimento_estimado' => $quadra['rendimentoReal'],
                'tipo_semeadura' => $quadra['sistemaPlantio'],
                'id_item_segurado' => $itemSegurado['id'],
                'nro_item' => $nroItem,
                'negar_ciclo_anterior' => isset($quadra['negarPorCultivoCicloAnterior']) && (!empty($quadra['negarPorCultivoCicloAnterior']) || $quadra['negarPorCultivoCicloAnterior'] === false) ? ($quadra['negarPorCultivoCicloAnterior'] ? $quadra['negarPorCultivoCicloAnterior'] : 'false') : null,
                'cultivo_anterior' => isset($quadra['motivoNegacaoCultivoCicloAnterior']) && (!empty($quadra['motivoNegacaoCultivoCicloAnterior']) || $quadra['motivoNegacaoCultivoCicloAnterior'] === 0) ? $quadra['motivoNegacaoCultivoCicloAnterior'] : null,
                'motivos_negacao' => !empty($quadra['motivosNegacao']) ? serialize($quadra['motivosNegacao']) : null,
                'negar_nro_safra' => isset($quadra['negarPorNumeroSafras']) && (!empty($quadra['negarPorNumeroSafras']) || $quadra['negarPorNumeroSafras'] === false) ? ($quadra['negarPorNumeroSafras'] ? $quadra['negarPorNumeroSafras'] : 'false') : null,
                'nro_safra' => isset($quadra['quantidadeCultivos']) && !empty($quadra['quantidadeCultivos']) ? ((int)preg_replace('/[^0-9]/', '', $quadra['quantidadeCultivos'])) : null, // busca o valor numérico dentro da string
                'tamanho_planta' => $quadra['tamanhoPlanta'],
                'estadio_fenologico' => $quadra['estadioFenologico'],
                'unid_medida_stand_plantas' => isset($quadra['unidadeMedidaStand']) && !empty($quadra['unidadeMedidaStand']) ? ($quadra['unidadeMedidaStand'] == 'ML' ? 'linear' : 'quadrado') : null,
                'espacamento_linhas' => $quadra['espacoEntreLinhas'] ? $quadra['espacoEntreLinhas'] : null,
                'amostra_1' => $quadra['amostra1'],
                'amostra_2' => $quadra['amostra2'],
                'amostra_3' => $quadra['amostra3'],
                'amostra_4' => $quadra['amostra4'],
                'media_amostras' => $quadra['mediaAmostras'],
                'populacao_ha' => $quadra['populacaoHectare'],
                'baixo_stand' => $quadra['riscoBaixoStand'] ? $quadra['riscoBaixoStand'] : 'false',
                'incidencia_doencas' => $quadra['riscoIncidenciaDoencas'] ? $quadra['riscoIncidenciaDoencas'] : 'false',
                'incidencia_pragas' => $quadra['riscoIncidenciaPragas'] ? $quadra['riscoIncidenciaPragas'] : 'false',
                'incidencia_invasores' => $quadra['riscoIncidenciaInvasoras'] ? $quadra['riscoIncidenciaInvasoras'] : 'false',
                'desuniformidade_plantio' => $quadra['riscoDesuniformidadePlantio'] ? $quadra['riscoDesuniformidadePlantio'] : 'false',
                'inundacao' => $quadra['riscoInundacao'] ? $quadra['riscoInundacao'] : 'false',
                'geada' => $quadra['riscoGeada'] ? $quadra['riscoGeada'] : 'false',
                'erosao' => $quadra['riscoErosao'] ? $quadra['riscoErosao'] : 'false',
                'toxidez' => $quadra['riscoToxidez'] ? $quadra['riscoToxidez'] : 'false',
                'outros' => $quadra['riscoOutros'] ? $quadra['riscoOutros'] : 'false',
                'fl_habilitar_nova_vistoria' => $quadra['novaVistoriaNecessaria'] ? $quadra['novaVistoriaNecessaria'] : 'false',
                'vistoriado' => 'true',
                'id_ciclo' => $idCiclo,
            );
            
            $result = $this->db->insert('regulacao.lvp001_itens_segurados', $valuesItemLaudo);
            
            if (empty($result)) {
                throw new SeventapException('Erro ao inserir o item do laudo da vistoria prévia! idProposta:'.$vistoria['idProposta'].' idVistoria: '.$vistoria['idVistoria'].' idPropostaVistoria: '.$vistoriaPrevia['id']);
            }
            
            $valuesArquivos = array();
            $flagRecebeuTodosArquivos = true;
            
            foreach ($quadra['imagens'] as $key => $imagem) {
            	$arNameImage = explode('/', $imagem['uri']);
                $nomeImagem = end($arNameImage);
            	
                $valuesArquivos = array(
            		'ds_nome_arquivo' => $nomeImagem,
            		'id_tipo_arquivo_laudo_previa' => 3, //FOTO
            		'id_proposta_vistoria' => $vistoriaPrevia['id'],
            		'id_usuario_criacao' => $user['id'],
                	'dt_criacao' => date('Y-m-d H:i:s'),
                    'fl_transmitido_seguradora' => 'true'
            	);

                if (!file_exists('../application/upload_files/laudoprevia/' . $nomeImagem)) {
                    $flagRecebeuTodosArquivos = false;
                    $valuesArquivos['fl_transmitido_seguradora'] = 'false';
                }

            	$result = $this->db->insert('seguro.propostas_vistorias_previas_arquivos', $valuesArquivos);

            	if (empty($result)) {
	                throw new SeventapException('Erro ao inserir as fotos da vistoria! idProposta:'.$vistoria['idProposta'].' idVistoria: '.$vistoria['idVistoria'].' idPropostaVistoria: '.$vistoriaPrevia['id']);
	            }
            }

            if ($flagRecebeuTodosArquivos && !empty($quadra['imagens'])) {
                $affectedRowsVistoriaPrevia = $this->db->update(
                    'seguro.propostas_vistorias_previas',
                    [
                        'id_status' => 71
                    ],
                    "id = '{$vistoriaPrevia['id']}'"
                );

                $affectedRowsVistoriaPreviaHistorico = $this->db->update(
                    'seguro.propostas_vistorias_previas_historico',
                    [
                        'id_status' => 71
                    ],
                    "id = '{$idVistoriaPreviaHistorico}'"
                );

                if (empty($affectedRowsVistoriaPrevia) || empty($affectedRowsVistoriaPreviaHistorico)) {
                    throw new SeventapException('Erro ao atualizar status da vistoria prévia! idProposta:'.$vistoria['idProposta'].' idVistoria: '.$vistoria['idVistoria']);
                }
            }
        }
    }

    /**
     * Busca o ciclo da proposta de acordo com a região, variedade e produto
     * 
     * @param type $idProposta 
     * @param type $idMunicipio 
     * @param type $idEstado 
     * @param type $idVariedade 
     * @param type $idProduto 
     * @return type
     */
    private function getCiclo($idProposta, $idMunicipio, $idEstado, $idVariedade, $idProduto) {
    	//busca se é zoneamento por região
    	$select = $this->db->select()->distinct(true);
		$select->from(array('g' => 'produto.produtos_grupos_atributos_rn'), false);
		$select->join(array('p' => 'produto.produtos_atributos_rn'), 'g.id = p.id_grupo_atributo_rn', 'ds_valor');
		$select->join(array('a' => 'produto.atributos_rn'), 'a.id = p.id_atributo_rn', false);
		$select->join(array('t' => 'produto.tipo_atributo'), 't.id = a.id_tipo_atributo', false);
		$select->join(array('m' => 'produto.atributos_modulos'), 'm.id = a.id_atributo_modulo', false);
		$select->where('m.ds_chave_atributo_modulo = ?', 'PROPRIEDADE');
		$select->where('g.id_produto = ?', $idProduto);
		$select->where('a.ds_chave_rn = ?', 'PROD_ZONEAMENTO_REGIAO');
		$select->where('p.fl_del is false');

		$zoneamentoRegiao = $this->db->fetchOne($select);

		$select = $this->db->select();
		$select->from('produto.variedades_ciclos_estados', 'id_ciclo');
		$select->where('id_produto = ?', $idProduto);
		$select->where('id_variedade = ?', $idVariedade);
		$select->where('id_estado = ?', $idEstado);
		if ($zoneamentoRegiao) {
			$select2 = $this->db->select();
			$select2->from('produto.produtos', array('id AS id_produto'));
			$select2->join('produto.produtos_geral', 'produtos_geral.id = produtos.id_produto_geral', null);
			$select2->join('produto.culturas', 'culturas.id = produtos_geral.id_cultura', null);
			$select2->join('sistema.municipios_culturas_regioes', 'municipios_culturas_regioes.id_cultura = culturas.id', 'id_regiao');
			$select2->join('sistema.municipios', 'municipios.id = municipios_culturas_regioes.id_municipio', array('id as id_municipio', 'id_estado'));
			$select2->where('municipios.id = ?', $idMunicipio);
			$select2->where('produtos.id = ?', $idProduto);

			$regiao = $this->db->fetchRow($select2);

            $select->where('id_regiao = ?', $regiao['id_regiao']);
		}
		
		$ciclo = $this->db->fetchRow($select);
		
		return isset($ciclo['id_ciclo']) && !empty($ciclo['id_ciclo']) ? $ciclo['id_ciclo'] : null;
    }

    private function getPrioridadeConferencia($values) {
        //se existe algum aviso(independente do status), retorna 1

        // COMENTADO NA SOLICITAÇÃO
/*         $select = $this->db->select();
        $select->from(array('av' => 'sinistro.avisos'), array('id', "to_char(av.dt_sinistro, 'dd/MM/yyyy HH24:MI') as dt_sinistro", "id"));
        $select->join(array('s' => 'sistema.status'),'s.id = av.id_status');
        $select->join(array('u' => 'sistema.usuarios'),'u.id = av.id_usuario_criacao');
        $select->joinLeft(array('u2' => 'sistema.usuarios'),'u2.id = av.id_usuario_alteracao');
        $select->joinLeft(array('ar' => 'sinistro.avisos_recusas'), 'av.id = ar.id_aviso');
        $select->joinLeft(array('trs' => 'atendimento.tipo_recusa_sinistro'), 'ar.id_tipo_recusa = trs.id');
        $select->where('seguro.id_proposta_mae(av.id_proposta) = seguro.id_proposta_mae('.$values['idProposta'].')');
        $select->order('av.id');

        $rs = $this->db->fetchAll($select);
        if ($rs) {
            $data = $rs;
        	if (!is_array($data)) {
                $data = $data->toArray();
			}

        }

        if (count($data) > 0) {
            //Sinistro
            return 1;
        }
 */
        //se a vistoria ficou sem assinatura de quem acompanhou, retorna 2
        if (!isset($values['infoSegurado']) || !isset($values['infoSegurado']['assinatura']) || empty($values['infoSegurado']['assinatura'])) {
            //Vistoria sem assinatura
            return 1;
        }

        //se o somatório da área assegurável for zero, retorna 3
        $sumAreaSeguravel = 0;
        foreach ($values['vistoriaQuadras'] as $quadras) {
            $sumAreaSeguravel = bcadd($sumAreaSeguravel, $quadras['areaSeguravel'], 2);
        }

        if ($sumAreaSeguravel == 0) {
            //Cancelamento
            return 2;
        }

        //validação para ver se o zoneamento está de acorto
        $select = $this->db->select();
        $select->from(array('p' => 'seguro.propostas'), '*');
        $select->where('id = ?', $values['idProposta']);
        $proposta = $this->db->fetchRow($select);

        //busca se é zoneamento por região
        $Select = $this->db->select()->distinct(true);
        $Select->from(array('g' => 'produto.produtos_grupos_atributos_rn'), false);
        $Select->join(array('p' => 'produto.produtos_atributos_rn'), 'g.id = p.id_grupo_atributo_rn', 'ds_valor');
        $Select->join(array('a' => 'produto.atributos_rn'), 'a.id = p.id_atributo_rn', false);
        $Select->join(array('t' => 'produto.tipo_atributo'), 't.id = a.id_tipo_atributo', false);
        $Select->join(array('m' => 'produto.atributos_modulos'), 'm.id = a.id_atributo_modulo', false);
        $Select->where('m.ds_chave_atributo_modulo = ?', 'PROPRIEDADE');
        $Select->where('g.id_produto = ?', $proposta['id_produto']);
        $Select->where('a.ds_chave_rn = ?', 'PROD_ZONEAMENTO_REGIAO');
        $Select->where('p.fl_del is false');
        $flZoneamentoRegiao = $this->db->fetchOne($Select);

        //busca  propriedade
        $Select = $this->db->select();
        $Select->from(array('p' => 'seguro.propostas_propriedades'));
        $Select->join(array('m' => 'sistema.municipios'), 'p.id_municipio = m.id', array('id_estado', 'ds_nome_municipio', 'ds_latitude', 'ds_longitude', 'vl_altitude', 'vl_area', 'ds_ano_instalacao', 'cd_bacen', 'nr_ibge', 'nr_cep'));
        $Select->join(array('e' => 'sistema.estados'), 'm.id_estado = e.id', array('ds_nome_estado', 'ds_sigla', 'nr_ibge', 'id_pais'));
        $Select->join(array('c' => 'sistema.paises'), 'e.id_pais = c.id', array('ds_nome_pais'));

        $Select->join(array('pr' => 'seguro.propostas'), 'pr.id = p.id_proposta',null);
        $Select->join(array('pd' => 'produto.produtos'), 'pd.id = pr.id_produto',null);
        $Select->join(array('pg' => 'produto.produtos_geral'), 'pg.id = pd.id_produto_geral',null);
        $Select->joinLeft(array('mr' => 'sistema.municipios_culturas_regioes'), 'pg.id_cultura = mr.id_cultura and p.id_municipio = mr.id_municipio', array('id_regiao'));
        $Select->where('p.id_proposta = ?', $proposta['id']);
        $propriedade = $this->db->fetchRow($Select);

        //caso tenha sido informado que houve troca de município, informa o novo municipio para o zoneamento
        $idMunicipio = $values['municipioId'] != $propriedade['id_municipio'] ? $values['municipioId'] : $propriedade['id_municipio'];
        foreach ($values['vistoriaQuadras'] as $quadras) {
            if ( !$quadras['variedade']
              || !$quadras['tipoSolo']
              || !$quadras['altitude']
              || !$quadras['sistemaPlantio']
              || !$quadras['inicioPlantio']
              || !$quadras['terminoPlantio']) {
        		continue;
			}

            // verifica se está configurado para zonemanto por região para buscar o ciclo
            if(!$flZoneamentoRegiao){
                $Select = $this->db->select();
                $Select->from('produto.variedades_ciclos_estados', 'id_ciclo');
                $Select->where('id_produto = ?', $proposta['id_produto']);
                $Select->where('id_variedade = ?', $quadras['variedade']);
                $Select->where('id_estado = ?', $propriedade['id_estado']);

                $Row = $this->db->fetchRow($Select);
                $idCiclo = $Row['id_ciclo'];
//                $idCiclo = $modelCiclos->getCicloEstado($proposta['id_produto'], $quadras['variedade'], $propriedade['id_estado']);
            } else {
                if(!$propriedade['id_regiao']){
                    continue;
                }
                $Select = $this->db->select();
                $Select->from('produto.variedades_ciclos_estados', 'id_ciclo');
                $Select->where('id_produto = ?', $proposta['id_produto']);
                $Select->where('id_variedade = ?', $quadras['variedade']);
                $Select->where('id_estado = ?', $propriedade['id_estado']);
                $Select->where('id_regiao = ?', $propriedade['id_regiao']);

                $Row = $this->db->fetchRow($Select);
                $idCiclo = $Row['id_ciclo'];
//                $idCiclo = $modelCiclos->getCicloRegiao($proposta['id_produto'], $quadras['variedade'], $propriedade['id_estado'], $propriedade['id_regiao']);
            }

            //validação necessária para as duas datas da semeadura, inicio e fim
            $resultado  = $this->verificaZoneamento(
                $quadras['tipoSolo'],
                $proposta['id_produto'],
                $idCiclo,
                $idMunicipio,
                $quadras['inicioPlantio'],
                $quadras['altitude'],
                $quadras['sistemaPlantio']
            );
            if (!$resultado['status']) {
                //Se pelo menos um dos itens possuir zoneamento incorreto, retorna 4
                return 3;
            }
            $resultado  = $this->verificaZoneamento(
                $quadras['tipoSolo'],
                $proposta['id_produto'],
                $idCiclo,
                $idMunicipio,
                $quadras['terminoPlantio'],
                $quadras['altitude'],
                $quadras['sistemaPlantio']
            );
            //repetido para não precisar abrir conexão a banco desnecessáriamente
            if (!$resultado['status']) {
                //Se pelo menos um dos itens possuir zoneamento incorreto, retorna 4
                return 3;
            }
        }

        //se houve redução ou aumento da área assegurada em relação à proposta, retorna 5
        $select = $this->db->select();
        $select->from(array('i' => 'seguro.itens_segurados'), array('id', 'id_proposta', 'vl_area'));
        $select->joinLeft(array('ic' => 'seguro.itens_segurados_complemento'), 'i.id = ic.id_item_segurado', array('dt_plantio', 'dt_semeadura', 'ds_coordenadas_geograficas'));
        $select->where('i.id_proposta = ?', $values['idProposta']);

        $itensSeguradosProposta = $this->db->fetchAll($select);
        $sumAreaSeguravelItensProposta = 0;
        foreach ($itensSeguradosProposta as $item) {
            $sumAreaSeguravelItensProposta = bcadd($sumAreaSeguravelItensProposta, $item['vl_area'], 2);
        }

        if ($sumAreaSeguravel > $sumAreaSeguravelItensProposta && $sumAreaSeguravel > 0 && $sumAreaSeguravelItensProposta > 0) {
            //Se houve aumento da área assegurada
            return 4;
        }

        if ($sumAreaSeguravel < $sumAreaSeguravelItensProposta && $sumAreaSeguravel > 0 && $sumAreaSeguravelItensProposta > 0) {
            //Se houve redução da área assegurada
            return 5;
        }

        //se uma quadra possui rendimento inferior
        foreach ($values['vistoriaQuadras'] as $quadra) {
            if ($quadra['rendimentoInferiorProposta']) {
                //redução de rendimento
                return 6;
            }
        }

        $unificacao = false;
        foreach ($values['vistoriaQuadras'] as $quadra) {
        	if ($quadra['motivosNegacao']) {
                foreach ($quadra['motivosNegacao'] as $motivo) {
                    if (strpos(strtolower($motivo), 'unificação') !== false) $unificacao = true;
                }
            }
        }

        // se a quantidade de quadras difere da quantidade de quadras da proposta retorna 6
        if ($unificacao == true || count($values['vistoriaQuadras']) != count($itensSeguradosProposta)) {
            //Unificação/Distribuição
            return 7;
        }

        // se uma das quadras possuir distância maior que 3 KM na amostra comparado com o item da proposta, retorna prioridade 8
        foreach ($values['vistoriaQuadras'] as $quadra) {
            foreach ($itensSeguradosProposta as $item) {
            	if ($quadra['idTalhao'] == $item['id']) {
                    $coordenadasQuadra = $this->coordenadas($quadra['latitude'], $quadra['longitude']);
                    $coordenadasItem = explode(',', $item['ds_coordenadas_geograficas']);
                    $coordenadasItem = $this->coordenadas(trim($coordenadasItem[0]), trim($coordenadasItem[1]));

                    $distancia = $this->distancia($coordenadasQuadra['lat'], $coordenadasQuadra['lon'], $coordenadasItem['lat'], $coordenadasItem['lon']);

                    if ($distancia > 3) {
                        //alteração de coordenadas
                        return 8;
                    }
                }
            }
        }

        //caso não entre em nenhuma das condições anteriores
        return 9;
    }

    /**
	 * Validação do zoneamento
	 * Referencia o algoritmo do método verificaZoneamento da classe Produto_Model_Validacoes
	 *
     * @param $idTipoSolo
     * @param $idProduto
     * @param $idCiclo
     * @param $idMunicipio
     * @param $dtSemeadura
     * @param int $vlAltitude
     * @param null $idSistemaPlantio
     * @return mixed
     */
    private function verificaZoneamento($idTipoSolo, $idProduto, $idCiclo, $idMunicipio, $dtSemeadura, $vlAltitude=0, $idSistemaPlantio=null) {
        $return['status'] = true;

        if(!$idCiclo){
            $return['status'] = false;
            $return['msg'] = 'Ciclo não informado.';
            return $return;
        }

        if(!$dtSemeadura){
            $return['status'] = false;
            $return['msg'] = 'Data de Semeadura não informada.';
            return $return;
        }

        //busca o cadastro de zoneamento conforme criterio informado
        $Select = $this->db->select();
        $Select->from(array('z'=>'produto.validacoes_zoneamento_graos'));
        $Select->join(array('m'=>'produto.validacoes_zoneamento_graos_municipios'), 'z.id = m.id_validacao_zoneamento_graos', array('vl_altitude', 'id_sistema_plantio'));
        $Select->where('? between (dt_inicial) and (dt_final)', $this->formataData($dtSemeadura, Zend_Date::W3C));
        $Select->where('m.id_municipio = ?', $idMunicipio);
        $Select->where('z.id_produto = ?', $idProduto);

        if ($idTipoSolo) {
            $idTipoSolo = (int) $idTipoSolo;
            $Select->where('z.id_tipo_solo = ?', $idTipoSolo);
        }
        if($idCiclo <> 16){
            $Select->where('z.id_ciclo = ?', $idCiclo);
        }

        $rsZoneamento = $this->db->fetchAll($Select);

        if(empty($rsZoneamento)) {
            $return['status'] = false;
            $return['msg'] = 'Data de plantio está em desacordo com o Zoneamento Agrícola e, em virtude disso, o valor segurado deve ser zerado';
            return $return;
        } else {
            foreach($rsZoneamento as $zoneamento){

                if($zoneamento['vl_altitude'] > 0 && $vlAltitude > 0  && ($vlAltitude > $zoneamento['vl_altitude'])){
                    $return['status'] = false;
                    $return['msg'] = 'Altitude está em desacordo com o Zoneamento Agrícola e, em virtude disso, o valor segurado deve ser zerado';
                    return $return;
                }

                if($zoneamento['id_sistema_plantio'] > 0 && $idSistemaPlantio > 0 && ($idSistemaPlantio <> $zoneamento['id_sistema_plantio'])){
                    $return['status'] = false;
                    $return['msg'] = 'Sistema de plantio está em desacordo com o Zoneamento Agrícola e, em virtude disso, o valor segurado deve ser zerado';
                    return $return;
                }

            }

            $return['status'] = true;
            return $return;
        }
    }

    /**
     * Calcula a distância entre pontos geográficos
     *
     * @param float $lat1 Latitude do ponto inicial em decimal
     * @param float $lon1 Longitude do ponto inicial em decimal
     * @param float $lat2 Latitude do ponto final em decimal
     * @param float $lon2 Longitude do ponto final em decimal
     * @return float Resultado do cálculo em KM
     */
    private function distancia($lat1, $lon1, $lat2, $lon2) {
        $lat1 = deg2rad($lat1);
        $lat2 = deg2rad($lat2);
        $lon1 = deg2rad($lon1);
        $lon2 = deg2rad($lon2);

        $dist = (6371 * acos( cos( $lat1 ) * cos( $lat2 ) * cos( $lon2 - $lon1 ) + sin( $lat1 ) * sin($lat2) ) );
        $dist = number_format($dist, 2, '.', '');
        return $dist;
    }

    /**
	 * Formata a data conforme formato passado
	 *
     * @param $dt
     * @param string $format
     * @return string|null
     */
    private function formataData($dt, $format='') {

        if (!$format) {
            $format = Zend_Date::DATES;
        }

        //load config to get locale
        $config = new Zend_Config_Ini(
            dirname(__FILE__).'/../../application/config/application.ini',
            getenv('APPLICATION_ENV')
        );
        $config = $config->toArray();

        if ($dt) {
            $Date = new Zend_Date(1234567890, false, $config['locale']);
            $Date->set($dt);

            return $Date->toString($format);
        } else {
            return null;
        }
    }

    /**
     * Função para calcular as coordenadas em UTM Decimais
     *
     * @param $latitude
     * @param $longitude
     * @return array
     */
    private function coordenadas($latitude, $longitude) {
        $return = array();

        $return['lat'] = $this->calcula_coordenadas($latitude);
        $return['lon'] = $this->calcula_coordenadas($longitude);

        return $return;
    }

    /**
     * Calcula a coordedana para UTM Decimal de um valor
     *
     * @param $coordenada
     * @return float
     */
    private function calcula_coordenadas($coordenada) {
        $cordsign = 1;
        $absdcord = 0;
        $absmcord = 0;
        $absscord = 0;

        $tmp = explode(' ', $coordenada);
        if ($tmp[0] < 0) {
            $cordsign = -1;
        }
        $precision = 2;
        $tmp[1] = abs(round($tmp[1] * 1000000., $precision) / 1000000);
        $tmp[2] = abs(round($tmp[2] * 1000000., $precision) / 1000000);

        $absdcord = abs(round($tmp[0] * 1000000., $precision));
        $absmcord = abs(round($tmp[1] * 1000000., $precision));
        $absscord = abs(round($tmp[2] * 1000000., $precision));

        return round($absdcord + ($absmcord / 60.) + ($absscord / 3600.), 2) * $cordsign / 1000000;
    }

    /**
     * Trata as mensagens e dispara a chamada de log
     *
     * @param array $errorMessages
     * @param $idProposta
     */
	private function logErrorVistoria(array $errorMessages, $idProposta) {
        $result = "";
        foreach ($errorMessages['vistoriaQuadras'] as $key => $quadras) {
            $result = "Quadra: " . $key . " -> " . implode("\n    ", $quadras) . "\n";
        }

        unset($errorMessages['vistoriaQuadras']);
        $result = "Proposta: " . $idProposta . " -> " . implode("\n    ", $errorMessages) . "\n" . $result;

        return $result;
    }

    /**
     * Loga o erro no arquivo configurado
     *
     * @param $errorMessage
     */
    private function logSuccess($message, $vistoria = null) {
        $this->registryLog();

        $logger = Zend_Registry::get('logger');
        $logger->log($message, Zend_Log::INFO);
        $logger->log(json_encode($vistoria), Zend_Log::INFO);

        $pathJson = $this->logTransmission($vistoria, 'success');

        $subject = "AgroNet 2.0 - SINCRONIA DO TABLET REALIZADA COM SUCESSO - Proposta ".$vistoria['idProposta']."/Vistoria ".$vistoria['idVistoria'];
        $this->sendEmail($message, $vistoria, $subject, $pathJson, null, array('log_json' => true));
    }

    /**
     * Loga o erro no arquivo configurado
     *
     * @param $errorMessage
     */
	private function logError($errorMessage, $vistoria = null) {
	    $this->registryLog();

        $logger = Zend_Registry::get('logger');
        $logger->log($errorMessage, Zend_Log::ERR);
        $logger->log(json_encode($vistoria), Zend_Log::ERR);

        $pathJson = $this->logTransmission($vistoria, 'error');

        $subject = "AgroNet 2.0 - ERRO DE SINCRONIA DO TABLET - Proposta ".$vistoria['idProposta']."/Vistoria ".$vistoria['idVistoria'];
        $this->sendEmail($errorMessage, $vistoria, $subject, $pathJson, null, array('log_json' => true));
    }

    /**
     * Configura o logger para o arquivo correto
     */
    private function registryLog() {
    	if (!Zend_Registry::isRegistered('logger')) {
	        $logger = new Zend_Log();

	        $writer = new Zend_Log_Writer_Stream('/tmp/log_error_seventaps_'.date('Ymd').'.log');

	        $logger->addWriter($writer);
	        Zend_Registry::set('logger',$logger);
	   	}
    }

    //método teste
	public function sendEmailPublic() {
//		if (getenv('APPLICATION_ENV') != 'production') {
    		$this->sendEmail('Testando email', null, "Teste de email");
//    	}
    	return array('status' => 'success', 'message' => 'Teste de email!');
    }

    /**
     * Realiza o envio de email para notificar os erros da sincronia
     *
     * @param $message Mensagem de erro para enviar por email
     */
    private function sendEmail($message, $vistoria = null, $subject = "AgroNet 2.0 - ERRO DE SINCRONIA DO TABLET", $filePath = null, $cc = null, array $opt = null) {
        $this->registryEmail();

        if (getenv('APPLICATION_ENV') != 'production') {
		// $this->email->addTo('joao@7taps.com.br', 'João Rutkoski');
            $this->email->clearFrom();
            $this->email->setFrom('testes@agrobrasilseguros.com.br');
            $this->email->addTo('tonismar.bernardo@agrobrasilseguros.com.br', 'Tonismar Bernardo');
            $this->email->addTo('fabio.bertoldi@agrobrasilseguros.com.br', 'Fábio Bertoldi');
            //para evitar o envio dos logs para fora da ti
            if (!isset($opt['log_json']) || (isset($opt['log_json']) && !$opt['log_json'])) {
                $this->email->addBcc('luana.beck@agrobrasilseguros.com.br', 'Luana Beck');
                $this->email->addBcc('karina.silva@agrobrasilseguros.com.br', 'Karina Silva');
            }

            $subject .= " - HOMOLOG";
        } else {
            $this->email->addTo('ti@agrobrasilseguros.com.br', 'TI - Agrobrasil');
            //para evitar o envio dos logs para fora da ti
            if (!isset($opt['log_json']) || (isset($opt['log_json']) && !$opt['log_json'])) {
                $this->email->addBcc('luana.beck@agrobrasilseguros.com.br', 'Luana Beck');
                $this->email->addBcc('karina.silva@agrobrasilseguros.com.br', 'Karina Silva');
            }

            //para evitar que o corretor receba os emails quando não for em produção
            // if ($cc && is_array($cc)) {
            //     if (isset($cc['email'])) {
            //         $this->email->addTo($cc['email'], $cc['nome']);
            //     } else {
            //         foreach ($cc as $emailCC) {
            //             $this->email->addTo($emailCC['email'], $emailCC['nome']);
            //         }
            //     }
            // }
        }

        $this->email->setSubject($subject);

        if ($opt['html']) {
            $this->email->setBodyHtml($message);
		} else {
            $this->email->setBodyText($message);
        }

        if (!is_null($filePath)) {
        	$content = file_get_contents($filePath);
			$attachment = new Zend_Mime_Part($content);
			$attachment->type = mime_content_type($filePath);
			$attachment->disposition = Zend_Mime::DISPOSITION_ATTACHMENT;
			$attachment->encoding = Zend_Mime::ENCODING_BASE64;
			$attachment->filename = basename($filePath);

			$this->email->addAttachment($attachment);
        }

        $this->email->send();

        unset($this->email);
    }

    /**
     * Configura o cliente de email
     */
    private function registryEmail() {
    	if (empty($this->email)) {
            $applicationIni = parse_ini_file(dirname(__FILE__).'/../../application/config/application.ini', true)['production'];
            $this->email = new Zend_Mail('UTF-8');

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

            $transport = new Zend_Mail_Transport_Smtp($applicationIni['constants.MAIL_SMTP'], $config);

            $this->email->setDefaultTransport($transport);

            $this->email->setFrom('vp@agrobrasilseguros.com.br', 'AgroBrasil - Agronet 2.0');
        }
    }

    /**
     * Método valida os dados da vistoria
     *
     * @param array $data Dados da vistoria para validar
     * @throws SeventapException
     */
	private function validateVistoriaData(array $data) {
        $msgs = array();

	    if (!isset($data['nivelTecnologico']) || empty($data['nivelTecnologico'])) {
            $msgs['nivelTecnologico'] = 'Campo Nível Tecnológico inválido!';
        }

        if (!isset($data['status']) || empty($data['status'])) {
            $msgs['status'] = 'Campo Status inválido!';
        }



        if (!isset($data['idProposta']) || empty($data['idProposta'])) {
            $msgs['idProposta'] = 'Campo Proposta inválido!';
        }

        if (!isset($data['assinaturaVistoriador']) || empty($data['assinaturaVistoriador'])) {
            $msgs['assinaturaVistoriador'] = 'Campo Assinatura do Vistoriador inválido!';
        }

//        TODO Assinatura Segurado
//        if (!isset($data['assinaturaVistoriador']) || empty($data['assinaturaVistoriador'])) {
//            $msgs['status'] = 'Campo Assinatura Vistoriador inválido!';
//        }

        //TODO Validar as informações do segurado

        if ((!isset($data['municipioId']) || empty($data['municipioId'])) or (!isset($data['ufId']) || empty($data['ufId']))) {
            if (empty($data['municipioId'])) {
                $msgs['municipioId'] = 'Campo Município inválido!';
            } else {
                $msgs['ufId'] = 'Campo UF inválido!';
            }
        }

        $dataVistoria = explode(' ', $data['dataConclusaoVistoria']);
        if (!isset($dataVistoria[0]) || empty($dataVistoria[0])) {
            $msgs['dataVistoria'] = 'Campo Data da Vistoria inválido!';
        }
        if (!isset($dataVistoria[1]) || empty($dataVistoria[1])) {
            $msgs['horaVistoria'] = 'Campo Hora da Vistoria inválido!';
        }

        //valida as quadras
        foreach ($data['vistoriaQuadras'] as $key => $quadra) {
            $resultQuadra = $this->validateQuadraData($quadra);

            if (!empty($resultQuadra)) {
                $msgs['vistoriaQuadras'][($quadra['nome'] ? $quadra['nome'] : $key)] = $resultQuadra;
            }
        }

        return $msgs;
    }

    /**
     * Método valida os dados da quadra da vistoria
     *
     * @param array $data Dados da quadra da vistoria para validar
     * @return array
     */
    private function validateQuadraData($data) {
        $msgs = array();

        if (!isset($data['nome']) || empty($data['nome'])) {
            $msgs['nome'] = 'Campo Quadra/Talhão inválido!';
        }

        //caso não venha as coordenadas, a quadra foi unificada e não pode validar as informações
        if (isset($data['latitude']) && !empty($data['latitude'])) {
            if (!isset($data['areaDoSegurado']) || (empty($data['areaDoSegurado']) && $data['areaDoSegurado'] !== false)) {
                $msgs['areaDoSegurado'] = 'Campo Área do Segurado inválido!';
            }

            if (!isset($data['areaDeclarada']) || (empty($data['areaDeclarada']) && $data['areaDeclarada'] !== 0)) {
                $msgs['areaDeclarada'] = 'Campo Área Declarada inválido!';
            }

            if ($data['areaDoSegurado']) {
                if (!isset($data['houvePlantio']) || (empty($data['houvePlantio']) && $data['houvePlantio'] !== false)) {
                    $msgs['houvePlantio'] = 'Campo Houve Plantio inválido!';
                }

                if ($data['houvePlantio']) {
                    if (!isset($data['areaSeguravel']) || (empty($data['areaSeguravel']) && $data['areaSeguravel'] !== 0)) {
                    	if (!($data['areaDeclarada'] > 0 && $data['areaDeclarada'] == $data['areaExcluida'])) {
                            $msgs['areaSeguravel'] = 'Campo Área Assegurável inválido!';
						}
                    }

                    if (!isset($data['areaVistoriada']) || (empty($data['areaVistoriada']) && $data['areaVistoriada'] !== 0)) {
                        if (!($data['areaDeclarada'] > 0 && $data['areaDeclarada'] == $data['areaExcluida'])) {
                            $msgs['areaVistoriada'] = 'Campo Área Vistoriada inválido!';
                        }
                    }

//                    if (!isset($data['areaSeguravel']) || (empty($data['areaSeguravel']) && $data['areaSeguravel'] !== 0)) {
//						$msgs['areaSeguravel'] = 'Campo Área Assegurável inválido!';
//                    }
//
//                    if (!isset($data['areaVistoriada']) || (empty($data['areaVistoriada']) && $data['areaVistoriada'] !== 0)) {
//                        $msgs['areaVistoriada'] = 'Campo Área Vistoriada inválido!';
//                    }
                }
            }

            if (!isset($data['areaExcluida']) || (empty($data['areaExcluida']) && $data['areaExcluida'] !== 0)) {
                $msgs['areaExcluida'] = 'Campo Área Excluída inválido!';
            }

            if (empty($data['motivosNegacao'])
                && $data['houvePlantio'] !== false
                && (isset($data['pretendePlantar'])
                    && $data['pretendePlantar'] !== true)) {
                if (!isset($data['altitude']) || (empty($data['altitude']) && $data['altitude'] !== 0)) {
                    $msgs['altitude'] = 'Campo Altitude inválido!';
                }

                if (!isset($data['amostra1']) || (empty($data['amostra1']) && $data['amostra1'] !== 0)) {
                    $msgs['amostra1'] = 'Campo Amostra 1 inválido!';
                }

                if (!isset($data['amostra2']) || (empty($data['amostra2']) && $data['amostra2'] !== 0)) {
                    $msgs['amostra2'] = 'Campo Amostra 2 inválido!';
                }

                if (!isset($data['amostra3']) || (empty($data['amostra3']) && $data['amostra3'] !== 0)) {
                    $msgs['amostra3'] = 'Campo Amostra 3 inválido!';
                }

                if (!isset($data['amostra4']) || (empty($data['amostra4']) && $data['amostra4'] !== 0)) {
                    $msgs['amostra4'] = 'Campo Amostra 4 inválido!';
                }

                if (!isset($data['mediaAmostras']) || (empty($data['mediaAmostras']) && $data['mediaAmostras'] !== 0)) {
                    $msgs['mediaAmostras'] = 'Campo Média das Amostras inválido!';
                }

                if (!isset($data['unidadeMedidaStand']) || empty($data['unidadeMedidaStand']) || !in_array($data['unidadeMedidaStand'], array('ML', 'M²'))) {
                    $msgs['unidadeMedidaStand'] = 'Campo Unidade de Medida inválido!';
                }

                if ((!isset($data['espacoEntreLinhas']) || empty($data['espacoEntreLinhas'])) && strtoupper($data['unidadeMedidaStand']) === 'ML') {
                    $msgs['espacoEntreLinhas'] = 'Campo Espaço entre Linhas inválido!';
                }

                if (!isset($data['estadioFenologico']) || empty($data['estadioFenologico'])) {
                    $msgs['estadioFenologico'] = 'Campo Estádio Fenológico inválido!';
                }

                if (!isset($data['latitude']) || empty($data['latitude']) || !isset($data['longitude']) || empty($data['longitude'])) {
                    $msgs['nome'] = 'Campos Latitude e Longitude inválido!';
                }

                if (!isset($data['sistemaPlantio']) || empty($data['sistemaPlantio']) || !in_array($data['sistemaPlantio'], array('C', 'D', 'AL'))) {
                    $msgs['sistemaPlantio'] = 'Campo Sistema de Plantio inválido!';
                }

                if (!isset($data['tipoSolo']) || empty($data['tipoSolo']) || !in_array($data['tipoSolo'], array(1, 2, 3))) {
                    $msgs['tipoSolo'] = 'Campo Tipo Solo inválido!';
                }

                if (!isset($data['variedade']) || empty($data['variedade'])) {
                    $msgs['variedade'] = 'Campo Variedade inválido!';
                }

                if (!isset($data['inicioPlantio']) || empty($data['inicioPlantio'])) {
                    $msgs['inicioPlantio'] = 'Campo Inicio Plantio inválido!';
                }

                if (!isset($data['terminoPlantio']) || empty($data['terminoPlantio'])) {
                    $msgs['inicioPlantio'] = 'Campo Inicio Plantio inválido!';
                }

                if (!isset($data['negarPorCultivoCicloAnterior']) || (empty($data['negarPorCultivoCicloAnterior']) && $data['negarPorCultivoCicloAnterior'] !== false)) {
                    $msgs['negarPorCultivoCicloAnterior'] = 'Campo Negar por Cultivo no Ciclo Anterior inválido!';
                }

                if ((!isset($data['motivoNegacaoCultivoCicloAnterior']) || empty($data['motivoNegacaoCultivoCicloAnterior'])) && $data['negarPorCultivoCicloAnterior'] === true) {
                    $msgs['cultivo'] = 'Campo Cultivo inválido!';
                }

                if (!isset($data['negarPorNumeroSafras']) || (empty($data['negarPorNumeroSafras']) && $data['negarPorNumeroSafras'] !== false)) {
                    $msgs['negarPorNumeroSafras'] = 'Campo Negar por Nº de Safras Cultivadas inválido!';
                }

                if ((!isset($data['quantidadeCultivos']) || empty($data['quantidadeCultivos'])) && $data['negarPorNumeroSafras'] === true) {
                    $msgs['quantidadeCultivos'] = 'Campo Nº de Safras inválido!';
                }

                if (!isset($data['tamanhoPlanta']) || empty($data['tamanhoPlanta'])) {
                    $msgs['tamanhoPlanta'] = 'Campo Tamanho da Planta inválido!';
                }

                if (!isset($data['populacaoHectare']) || (empty($data['populacaoHectare']) && $data['populacaoHectare'] !== 0)) {
                    $msgs['populacaoHectare'] = 'Campo População por ha inválido!';
                }

                if (!isset($data['novaVistoriaNecessaria']) || (empty($data['novaVistoriaNecessaria']) && $data['novaVistoriaNecessaria'] !== false)) {
                    $msgs['novaVistoriaNecessaria'] = 'Campo Necessário Nova Vistoria inválido!';
                }
            }
        }

        return $msgs;
    }

    /**
     * @param string token
     * @return string
     */
    public function getVistorias($token) {

        $usuario = $this->whoAmI($token);

        if (is_array($this->checkToken($token))) {

            try {
                //recupera a safra atual 
                $safra_atual = $this->db->fetchOne(
                        $this->db->select()
                        ->from('produto.safras', 'id')
                        ->where('fl_vigente = true')
                );
                $safra_anterior = $safra_atual - 1;

                $this->setDb();

                //sub consulta que verifica se qualquer propostas (ativa ou não) está no status AGUARDANDO_VISTORIA
                $subPropostas = $this->db->select();
                $subPropostas->from('seguro.propostas_endosso', 'propostas_endosso.id_endosso');
                $subPropostas->join('seguro.propostas', 'propostas.id = propostas_endosso.id_proposta', 'array_agg(propostas.id) AS ar_propostas');
                $subPropostas->join('seguro.propostas_vistorias_previas', 'propostas_vistorias_previas.id_proposta = propostas.id', null);
                $subPropostas->join('sistema.status', 'status.id = propostas_vistorias_previas.id_status', array('id as id_status', 'ds_chave'));
                $subPropostas->join('sistema.vistorias_funcionarios', 'vistorias_funcionarios.id_vistoria = propostas_vistorias_previas.id_vistoria', 'propostas_vistorias_previas.id_vistoria');
                $subPropostas->join('sistema.funcionarios', 'funcionarios.id = vistorias_funcionarios.id_funcionario', null);
                $subPropostas->join('sistema.usuarios', 'usuarios.id = funcionarios.id_usuario', 'ds_nome_usuario');
                $subPropostas->join(array('vistorias' => 'sistema.vistorias'), 'vistorias.id = propostas_vistorias_previas.id_vistoria', null);
                $subPropostas->join(array('vistorias_agendamentos' => 'sistema.vistorias_agendamentos'), 'vistorias.id = vistorias_agendamentos.id_vistoria', null);
                $subPropostas->join(array('agendamentos' => 'sistema.agendamentos'), 'vistorias_agendamentos.id_agendamento = agendamentos.id', null);
                $subPropostas->where('status.ds_chave IN (\'AGUARDANDO_VISTORIA\', \'CANCELADA\')', null);
                $subPropostas->where('usuarios.ds_nome_usuario = ?', $usuario);
                $subPropostas->where('propostas_vistorias_previas.fl_was_cleaned_in_tablet = false');
                $subPropostas->group(array('propostas_endosso.id_endosso', 'ds_nome_usuario', 'status.id', 'status.ds_chave', 'propostas_vistorias_previas.id_vistoria'));

                //propostas, propriedade e proponente
                $Propostas = $this->db->select();
                $Propostas->from(array('propostas' => 'seguro.propostas'), array('id as id_proposta_ref','id_proposta_mae as id_proposta','dt_vigencia_inicio','dt_vigencia_fim','seguro.id_proposta_mae_completo(propostas.id) as os_id_proposta_completo'));
                $Propostas->join(array('endossos' => 'seguro.propostas_endosso'), 'propostas.id = endossos.id_proposta', array('endossos.id_endosso as id_endosso'));
                $Propostas->join(array('proponentes' => 'seguro.propostas_proponentes'), 'propostas.id = proponentes.id_proposta', array('ds_nome_proponente','cpf_cnpj','ds_tel_residencia','ds_tel_propriedade','ds_tel_celular', 'ds_documento_natureza||\' \'||ds_documento_numero as os_documento_proponente','ds_endereco_rua as os_ds_endereco_rua','ds_endereco_nro as os_ds_endereco_nro','ds_endereco_complem as os_ds_endereco_complem','ds_endereco_bairro as os_ds_endereco_bairro','ds_endereco_cep as os_ds_endereco_cep'));
                $Propostas->join(array('propriedades' => 'seguro.propostas_propriedades'), 'propostas.id = propriedades.id_proposta', array('ds_nome_propriedade','ds_endereco','ds_endereco_cep','ds_endereco_bairro','ds_endereco_nro','ds_endereco_complemento','ds_referencia_localizacao','ds_coordenadas'));
                $Propostas->join(array('produtos' => 'produto.produtos'), 'propostas.id_produto = produtos.id', array('id as id_produto','ds_nome_produto','ds_nome_abreviado'));
                $Propostas->join(array('produtos_gerais' => 'produto.produtos_geral'), 'produtos.id_produto_geral = produtos_gerais.id', null);
                $Propostas->join(array('culturas' => 'produto.culturas'), 'produtos_gerais.id_cultura = culturas.id', array('id as id_cultura','ds_nome_cultura'));
                $Propostas->join(array('municipios' => 'sistema.municipios'), 'propriedades.id_municipio = municipios.id', array('ds_nome_municipio','id as id_municipio'));
                $Propostas->join(array('validacoes_zoneamento_graos_municipios' => 'produto.validacoes_zoneamento_graos_municipios'), 'validacoes_zoneamento_graos_municipios.id_municipio = municipios.id', null);
                $Propostas->join(array('validacoes_zoneamento_graos' => 'produto.validacoes_zoneamento_graos'), 'validacoes_zoneamento_graos.id = validacoes_zoneamento_graos_municipios.id_validacao_zoneamento_graos AND validacoes_zoneamento_graos.id_produto = produtos.id', null);
                $Propostas->join(array('produtos_validacoes' => 'produto.produtos_validacoes'), 'produtos_validacoes.id_produto = produtos.id', null);
                $Propostas->join(array('municipios_os' => 'sistema.municipios'), 'proponentes.id_municipio = municipios_os.id', array('ds_nome_municipio as os_nome_municipio','id as os_id_municipio'));
                $Propostas->join(array('estados' => 'sistema.estados'), 'municipios.id_estado = estados.id', array('ds_sigla','id as id_estado'));
                $Propostas->join(array('sub_propostas' => new Zend_Db_Expr("($subPropostas)")), 'sub_propostas.id_endosso = endossos.id_endosso', array('id_status','ds_chave', 'id_vistoria'));
                $Propostas->join(array('observacoes' => 'seguro.propostas_observacoes'), 'observacoes.id_proposta = propostas.id and observacoes.fl_principal is true', 'ds_observacao as os_ds_observacao');
                $Propostas->join(array('pc_principal' => 'seguro.propostas_coberturas'), 'propostas.id = pc_principal.id_proposta and pc_principal.fl_principal is true', false);
                $Propostas->join(array('coberturas_principal' => 'produto.coberturas'), 'coberturas_principal.id = pc_principal.id_cobertura', 'ds_nome_cobertura as os_cobertura_principal');
                $Propostas->joinLeft(array('pc_adicional' => 'seguro.propostas_coberturas'), 'propostas.id = pc_adicional.id_proposta and pc_adicional.fl_principal is false', false);
                $Propostas->joinLeft(array('coberturas_adicional' => 'produto.coberturas'), 'coberturas_adicional.id = pc_adicional.id_cobertura', "string_agg(coberturas_adicional.ds_nome_cobertura, ', ') as os_cobertura_adicional");
                $Propostas->joinLeft(array('processos' => 'sinistro.processos'),'propostas.id = processos.id_proposta', array('sinistrada' => new Zend_Db_Expr('CASE WHEN processos.id IS NOT NULL THEN true ELSE false END')));
                $Propostas->joinLeft(array('status_processos' => 'sistema.status'), 'processos.id_status = status_processos.id AND status_processos.ds_chave IN (\'FECHADO\',\'CANCELADO\',\'LIQUIDADO\')', null);
                $Propostas->joinLeft(array('regioes' => 'sistema.municipios_culturas_regioes'), 'produtos_gerais.id_cultura = regioes.id_cultura AND municipios.id = regioes.id_municipio', 'id_regiao');
                $Propostas->where('endossos.fl_proposta_vigente IS true');
                $Propostas->where('produtos.id_safra in ('.$safra_anterior.','.$safra_atual.')');
                $Propostas->where('produtos.fl_importar_zoneamento_tablet = TRUE');
                $Propostas->where('produtos_validacoes.id_validacao = 4');

                $Propostas->group('propostas.id, 
									propostas.id_proposta_mae, 
									propostas.dt_vigencia_inicio, 
									propostas.dt_vigencia_fim, 
									seguro.id_proposta_mae_completo(propostas.id), 
									proponentes.ds_nome_proponente, 
									proponentes.cpf_cnpj, 
									proponentes.ds_tel_residencia, 
									proponentes.ds_tel_propriedade, 
									proponentes.ds_tel_celular, 
									proponentes.ds_documento_natureza, 
									proponentes.ds_documento_numero,
									proponentes.ds_endereco_rua, 
									proponentes.ds_endereco_nro, 
									proponentes.ds_endereco_complem, 
									proponentes.ds_endereco_bairro, 
									proponentes.ds_endereco_cep, 
									propriedades.ds_nome_propriedade, 
									propriedades.ds_endereco, 
									propriedades.ds_endereco_cep, 
									propriedades.ds_endereco_bairro, 
									propriedades.ds_endereco_nro, 
									propriedades.ds_endereco_complemento, 
									propriedades.ds_referencia_localizacao, 
									propriedades.ds_coordenadas, 
									produtos.id, 
									produtos.ds_nome_produto, 
									produtos.ds_nome_abreviado, 
									culturas.id, 
									culturas.ds_nome_cultura, 
									municipios.ds_nome_municipio, 
									municipios.id, 
									municipios_os.ds_nome_municipio, 
									municipios_os.id, 
									estados.ds_sigla, 
									estados.id, 
									sub_propostas.id_status, 
									sub_propostas.ds_chave,
									sub_propostas.id_vistoria,
									observacoes.ds_observacao, 
									coberturas_principal.ds_nome_cobertura, 
									processos.id, 
									regioes.id_regiao,
									endossos.id_endosso');
                $Propostas->order('propostas.id DESC');

                $Row = $this->db->fetchAll($Propostas);

                if (is_array($Row)) { $p=0;
                    foreach ($Row as $proposta) {

                        $Row[$p]['os_questoes'] = $this->getQuestionario($proposta['id_proposta']);

                        $Row[$p]['os_condicao_especial'] = $this->getCarencia($proposta['id_proposta'],$proposta['id_produto']);

                        $Row[$p]['os_informacoes_adicionais'] = $this->getInformacoesAdicionais($proposta['id_proposta']);

                        //turn around apenas pra popular as novas informações que virão do zoneamento
                        //$tipo_semeadura = array('C','D','AL');
                        //$campos = rand(90,2000).".00::integer as vl_altitude , ".rand(1,3)." as tipo_solo, '".$tipo_semeadura[rand(0,(count($tipo_semeadura)-1))]."' as tipo_semeadura";

						$subUnidades1 = $this->db->select();
						$subUnidades1->from('seguro.propostas_vistorias_previas', array('id','fl_vistoria_replantio', 'id_vistoria_mae'));
                        $subUnidades1->join('regulacao.lvp001', 'propostas_vistorias_previas.id = lvp001.id_proposta_vistoria', null);
                        $subUnidades1->join('regulacao.lvp001_itens_segurados', 'lvp001.id = lvp001_itens_segurados.id_laudo_previa', array('fl_habilitar_nova_vistoria', 'id_item_segurado', 'vl_area_declarada', 'id_laudo_previa'));
                        $subUnidades1->join('seguro.itens_segurados', 'itens_segurados.id = lvp001_itens_segurados.id_item_segurado', array('itens_segurados.nr_item_segurado'));
                        $subUnidades1->join('seguro.propostas_endosso', 'propostas_vistorias_previas.id_proposta = propostas_endosso.id_proposta', array('propostas_endosso.id_endosso'));
                        $subUnidades1->where('propostas_endosso.id_endosso = ?', $proposta['id_endosso']);
                        $subUnidades1->group('lvp001.id_proposta_vistoria,
                                              propostas_vistorias_previas.id,
                                              lvp001_itens_segurados.fl_habilitar_nova_vistoria,
                                              lvp001_itens_segurados.id_item_segurado,
                                              lvp001_itens_segurados.id_laudo_previa,
                                              lvp001_itens_segurados.vl_area_declarada,
                                              propostas_endosso.id_endosso,
                                              itens_segurados.nr_item_segurado,
                                              propostas_vistorias_previas.fl_vistoria_replantio,
                                              propostas_vistorias_previas.id_vistoria_mae');

						$subRetorno = $this->db->select();
						$subRetorno->from('regulacao.lvp001_itens_segurados', ['id_laudo_previa']);
						$subRetorno->where('fl_habilitar_nova_vistoria IS TRUE');

						$whereUnidades1 = "( ";
						$whereUnidades1 .= "    (retorno.id_laudo_previa IS NULL AND laudo_itens.fl_vistoria_replantio = TRUE) ";
						$whereUnidades1 .= "    OR ";
						$whereUnidades1 .= "    (retorno.id_laudo_previa IS NOT NULL AND laudo_itens.fl_vistoria_replantio = TRUE AND (laudo_itens.fl_habilitar_nova_vistoria IS TRUE OR laudo_itens.fl_habilitar_nova_vistoria IS NULL)) ";
						$whereUnidades1 .= "    OR ";
						$whereUnidades1 .= "    (retorno.id_laudo_previa IS NOT NULL AND laudo_itens.fl_vistoria_replantio = FALSE AND (laudo_itens.fl_habilitar_nova_vistoria IS TRUE OR laudo_itens.fl_habilitar_nova_vistoria IS NULL)) ";
						$whereUnidades1 .= "    OR laudo_itens.fl_vistoria_replantio IS NULL ";
//						$whereUnidades1 .= "    OR (retorno.id_laudo_previa IS NULL AND laudo_itens.id_vistoria_mae IS NULL AND laudo_itens.fl_vistoria_replantio IS FALSE) ";
						$whereUnidades1 .= ")";

                        $Unidades1 = $this->db->select();
                        $Unidades1->from(array('unidades' => 'seguro.itens_segurados'), array('id as id_item_segurado','nr_item_segurado','ds_item_segurado','CASE WHEN laudo_itens.vl_area_declarada IS NOT NULL THEN laudo_itens.vl_area_declarada ELSE unidades.vl_area END AS vl_area','round(vl_rendimento_tonelada,3) as vl_rendimento_tonelada'));
                        $Unidades1->join(array('p' => 'seguro.propostas'), 'unidades.id_proposta = p.id', null);
                        $Unidades1->join(array('complemento' => 'seguro.itens_segurados_complemento'), 'unidades.id = complemento.id_item_segurado', array('ds_coordenadas_geograficas','CASE WHEN complemento.dt_plantio IS NULL THEN dt_semeadura ELSE dt_plantio END AS dt_plantio','vl_altitude',"CASE WHEN complemento.id_sistema_plantio = 1 THEN 'Direto'::text WHEN complemento.id_sistema_plantio = 2 THEN 'Convencional'::text WHEN complemento.id_sistema_plantio = 3 THEN 'A Lanço' ELSE NULL::text END AS tipo_semeadura",'id_tipo_solo as tipo_solo'));
                        $Unidades1->join(array('variedades' => 'produto.variedades'), 'unidades.id_variedade = variedades.id', array('ds_nome_variedade'));
                        $Unidades1->joinLeft(array('laudo_itens' => new Zend_Db_Expr('('.$subUnidades1.')')), 'laudo_itens.id_endosso = p.id_endosso AND laudo_itens.nr_item_segurado = unidades.nr_item_segurado', false);
                        $Unidades1->joinLeft(array('retorno' => new Zend_Db_Expr('('.$subRetorno.')')), 'retorno.id_laudo_previa = laudo_itens.id_laudo_previa', false);
                        $Unidades1->where($whereUnidades1);
                        $Unidades1->where('unidades.id_proposta = ?', $proposta['id_proposta_ref']);

                        $subUnidades2 = $this->db->select();
                        $subUnidades2->from('seguro.propostas_vistorias_previas', array('id_vistoria_mae' => 'propostas_vistorias_previas.id', 'propostas_vistorias_previas.id_proposta', 'propostas_vistorias_previas.fl_vistoria_replantio'));
                        $subUnidades2->join('seguro.propostas_endosso', 'propostas_vistorias_previas.id_proposta = propostas_endosso.id_proposta', null);
                        $subUnidades2->where('propostas_endosso.id_endosso = '.$proposta['id_endosso']);
                        $subUnidades2->group('propostas_vistorias_previas.id, propostas_vistorias_previas.id_proposta, propostas_vistorias_previas.fl_vistoria_replantio');

                        $Unidades2 = $this->db->select();
                        $Unidades2->from('regulacao.lvp001_itens_segurados', array(
                            'lvp001_itens_segurados.id_item_segurado',
                            'lvp001_itens_segurados.nro_item',
                            'lvp001_itens_segurados.nr_quadra',
                            'lvp001_itens_segurados.vl_area_declarada',
                            'CASE WHEN lvp001_itens_segurados.vl_rendimento_estimado IS NOT NULL THEN ROUND(lvp001_itens_segurados.vl_rendimento_estimado,3) ELSE ROUND(lvp001_itens_segurados.vl_rendimento_proposta,3) END AS vl_rendimento_estimado',
                            'lvp001_itens_segurados.ds_coordenadas',
                            'lvp001_itens_segurados.dt_inicio_semeadura::DATE',
                            'lvp001_itens_segurados.vl_altitude',
                            'tipo_semeadura' => new Zend_Db_Expr("CASE
                                 WHEN TRIM(lvp001_itens_segurados.tipo_semeadura) = 'D'  THEN 'Direto'::text
                                 WHEN TRIM(lvp001_itens_segurados.tipo_semeadura) = 'C'  THEN 'Convencional'::text
                                 WHEN TRIM(lvp001_itens_segurados.tipo_semeadura) = 'AL' THEN 'A Lanço'
                                 ELSE NULL::text
                             END"),
                            'tipo_solo' => 'CAST(lvp001_itens_segurados.tipo_solo AS INTEGER)'
                        ));
                        $Unidades2->join('regulacao.lvp001', 'lvp001.id = lvp001_itens_segurados.id_laudo_previa', null);
                        $Unidades2->join(array('pvp' => new Zend_Db_Expr('('.$subUnidades2.')')), 'pvp.id_vistoria_mae = lvp001.id_proposta_vistoria', null);
						$Unidades2->joinLeft(array('retorno' => new Zend_Db_Expr('('.$subRetorno.')')), 'retorno.id_laudo_previa = lvp001_itens_segurados.id_laudo_previa', false);
                        $Unidades2->joinLeft('produto.variedades', 'variedades.id = lvp001_itens_segurados.id_variedade', array('variedades.ds_nome_variedade'));

						$whereUnidades2 = "lvp001_itens_segurados.id_item_segurado IS NULL";
						$whereUnidades2 .= " AND ( ";
						$whereUnidades2 .= "       (retorno.id_laudo_previa IS NULL AND pvp.fl_vistoria_replantio = TRUE) ";
						$whereUnidades2 .= "       OR (retorno.id_laudo_previa IS NOT NULL AND pvp.fl_vistoria_replantio = TRUE AND (lvp001_itens_segurados.fl_habilitar_nova_vistoria IS TRUE OR lvp001_itens_segurados.fl_habilitar_nova_vistoria IS NULL)) ";
						$whereUnidades2 .= "       OR (retorno.id_laudo_previa IS NOT NULL AND pvp.fl_vistoria_replantio = FALSE AND (lvp001_itens_segurados.fl_habilitar_nova_vistoria IS TRUE OR lvp001_itens_segurados.fl_habilitar_nova_vistoria IS NULL)) ";
						$whereUnidades2 .= "       OR pvp.fl_vistoria_replantio IS NULL ";
						$whereUnidades2 .= " ) ";

                        $Unidades2->where($whereUnidades2);

                        $unionUnidades = $this->db->select();
                        $unionUnidades->union(array($Unidades1, $Unidades2));
                        $unionUnidades->order('id_item_segurado');

                        $arUnidades = $this->db->fetchAll($unionUnidades);

                        //pega o maior rendimento dos itens da proposta como media
                        $queryRendimentoTonelada = $this->db->select();
                        $queryRendimentoTonelada->from('seguro.itens_segurados', array('vl_rendimento_tonelada'));
                        $queryRendimentoTonelada->where('id_proposta = ?', $proposta['id_proposta_ref']);
                        $arUnidadesRendimento = $this->db->fetchAll($queryRendimentoTonelada);

                        $sum_vl_rendimento_tonelada = 0;
                        foreach ($arUnidadesRendimento as $und) {
                            if ($und['vl_rendimento_tonelada'] > $sum_vl_rendimento_tonelada) {
                                $sum_vl_rendimento_tonelada += $und['vl_rendimento_tonelada'];
                            }
                        }

                        $Row[$p]['media_rendimento_tonelada'] = round($sum_vl_rendimento_tonelada, 4);
                        
                        $Row[$p]['unidades'] = $arUnidades;


                        //vistorias
                        $Vistorias = $this->db->select();
                        $Vistorias->from(array('vistorias' => 'sistema.vistorias'), 'id as id_vistoria');
                        $Vistorias->join(array('propostas_vistorias_previas' => 'seguro.propostas_vistorias_previas'), 'vistorias.id = propostas_vistorias_previas.id_vistoria', array('id_vistoria_mae'));
                        $Vistorias->join(array('propostas_endosso' => 'seguro.propostas_endosso'), 'propostas_vistorias_previas.id_proposta = propostas_endosso.id_proposta', null);
                        $Vistorias->join(array('vistorias_empresas' => 'sistema.vistorias_empresas'), 'vistorias.id = vistorias_empresas.id_vistoria', null);
                        $Vistorias->join(array('empresas' => 'sistema.empresas'), 'vistorias_empresas.id_empresa = empresas.id', array('ds_nome_fantasia', 'ds_razao_social'));
                        $Vistorias->join(array('vistorias_funcionarios' => 'sistema.vistorias_funcionarios'), 'vistorias.id = vistorias_funcionarios.id_vistoria', null);
                        $Vistorias->join(array('funcionarios' => 'sistema.funcionarios'), 'vistorias_funcionarios.id_funcionario = funcionarios.id', 'ds_nome_funcionario');
                        $Vistorias->join(array('vistorias_agendamentos' => 'sistema.vistorias_agendamentos'), 'vistorias.id = vistorias_agendamentos.id_vistoria', null);
                        $Vistorias->join(array('agendamentos' => 'sistema.agendamentos'), 'vistorias_agendamentos.id_agendamento = agendamentos.id', 'dt_agendamento');
                        $Vistorias->join(array('status' => 'sistema.status'), 'status.id = propostas_vistorias_previas.id_status', null);
                        $Vistorias->join(array('usuarios' => 'sistema.usuarios'), 'usuarios.id = funcionarios.id_usuario', null);
//                        $Vistorias->where('status.ds_chave = ?', 'AGUARDANDO_VISTORIA');
                        $Vistorias->where('status.ds_chave IN (\'AGUARDANDO_VISTORIA\', \'CANCELADA\')', null);
                        $Vistorias->where('propostas_endosso.id_endosso = ?', $proposta['id_endosso']);
                        $Vistorias->where('vistorias.id = ?', $proposta['id_vistoria']);
                        $Vistorias->where('usuarios.ds_nome_usuario = ?', $usuario);


                        $RowVistorias = $this->db->fetchAll($Vistorias);


                        //busca a data da última vistoria, caso haja, para inserir na data do plantio das unidades que não possuem
                        $vist = reset($RowVistorias);
						$dtVistoriaMae = null;
						if ($vist['id_vistoria_mae']) {
                            $vistoriaMae = $this->db->select();
                            $vistoriaMae->from(array('propostas_vistorias_previas' => 'seguro.propostas_vistorias_previas'), '*');
                            $vistoriaMae->where('propostas_vistorias_previas.id = ?', $vist['id_vistoria_mae']);
                            $rowVistoriaMae = $this->db->fetchRow($vistoriaMae);

                            if ($rowVistoriaMae['dt_laudo']) {
                                $dtVistoriaMae = new DateTime($rowVistoriaMae['dt_laudo']);
                                $dtVistoriaMae->modify('+1 day');
                                $dtVistoriaMae = $dtVistoriaMae->format('Y-m-d');
                            }
						}

						if ($dtVistoriaMae) {
                            //verifica se a dt_plantio dos itens vieram, caso contrario busca a data da realização da vsitoria anterior
                            foreach ($Row[$p]['unidades'] as $keyUnd => $und) {
                                if (!$und['dt_plantio']) {
                                    $Row[$p]['unidades'][$keyUnd]['dt_plantio'] = $dtVistoriaMae;
                                }
                            }
                        }

                        $v=0;
                        foreach ($RowVistorias as $vistoria) {
                            //autorizado
                            $Autorizado = $this->db->select();
                            $Autorizado->from(array('pessoa_autorizada' => 'seguro.propostas_pessoa_autorizada_vistoria'), array('ds_pessoa_autorizada','cpf_cnpj','ds_telefone'));
                            $Autorizado->where('pessoa_autorizada.id_proposta = ?', $proposta['id_proposta_ref']);

                            $RowVistorias[$v]['autorizado'] = $this->db->fetchAll($Autorizado);
                            $v++;
                        }

                        $Row[$p]['vistorias'] = $RowVistorias;

                        unset($Row[$p]['id_proposta_ref']);

                        if ($proposta['ds_chave'] == 'CANCELADA') {
                            $this->setCleaned($proposta['id_proposta_ref'], $proposta['id_vistoria'], true, $token);
                        }

                        $p++;
                    }
                }
            } catch (Exception $e) {
                return array('status' => false, 'message' => $e->getMessage());
            }
        } else {
            return array('status' => false, 'message' => $this->getError(0));
        }

        unset($Row['id_proposta_ref']);
        return (is_array($Row) ? array('status' => true, 'propostas' => $Row) : array('status' => false, 'message' => $this->getError(0)));
    }

    //retorna um array de croquis em base64 da proposta
    public function getCroqui($id_proposta, $token) {
		try {
			if ($this->checkToken($token)) {
				$croquis = array();
				$output = array('id_proposta' => $id_proposta, 'croquis' => $croquis);
				$Croqui = $this->db->select();
				$Croqui->from(array('propostas' => 'seguro.propostas'), false);
				$Croqui->join(array('propostas_endosso' => 'seguro.propostas_endosso'), 'propostas_endosso.id_endosso = propostas.id_endosso', false);
				$Croqui->join(array('croquis' => 'seguro.propostas_croquis'), 'croquis.id_proposta = propostas_endosso.id_proposta', 'ds_nome_arquivo');
				$Croqui->where('croquis.fl_vigente = TRUE');
				$Croqui->where('propostas_endosso.fl_proposta_vigente IS true');
				$Croqui->where('propostas.id = ?', $id_proposta);
				$RowCroqui = $this->db->fetchAll($Croqui);

				foreach ($RowCroqui as $croqui) {
					$file = '../application/upload_files/croqui/' . $croqui['ds_nome_arquivo'];
					$type = pathinfo($file, PATHINFO_EXTENSION);
					if (is_readable($file)){
						$data = file_get_contents($file);
						$b64 = 'data:image/' . $type . ':base64,' . base64_encode($data);
						array_push($croquis, $b64);
					} else {
						array_push($croquis, $this->getError(2));
					}
				}

				$output = array('id_proposta' => $id_proposta, 'croquis' => $croquis);
				
				return array('status' => true, 'croquis' => $output);
			} else {
				return array('status' => false, 'message' => $this->getError(0));			
			}
		} catch (Exception $e) {
			return array('status' => false, 'message' => $this->getError(3) . "\n" . $e->getMessage());
		}	
	}

	/**
	* Função para debug que gera um arquivo de log em /tmp
	*/
    private function zf_debug($debug, $style='') {

 		$logger = new Zend_Log();
		//$writer = new Zend_Log_Writer_Firebug();
		
		//verifica o sistema operacional
		if (strtoupper(substr(PHP_OS, 0, 3)) == 'LIN') {
			$writer = new Zend_Log_Writer_Stream('/tmp/log_seventaps_'.date('Ymd').'.log');
		} else {
			$writer = new Zend_Log_Writer_Stream('c:\null');
		}
		
		$logger->addWriter($writer);
		Zend_Registry::set('logger',$logger);

        //if (ENABLE_DEBUG) {
		if (1 == 1) {
        	ob_start();
        	print_r($debug);
        	$debug = ob_get_clean();
 	       	$logger = Zend_Registry::get('logger');
 	       	return $logger->log($debug, ($style ? Zend_Log::$style : Zend_Log::INFO));
        }
        return true;
    }
}
?>
