<?php

class Sinistro2_Model_VistoriasAvisos extends Agro_Db_Table_Abstract {
	protected $_schema = 'sinistro';
	protected $_name = 'vistorias_avisos';
	protected $_primary = array('id_vistoria','id_aviso');
	public $_order = 'id_vistoria';
	protected $_sequence = false;

	public function delete($idVistoria) {
		$this->_db->query("delete from sinistro.vistorias_avisos where id_vistoria = $idVistoria");
	}

	public function deleteAvisoVistoria($idAviso, $idVistoria) {
		$this->_db->query("delete from sinistro.vistorias_avisos where id_vistoria = $idVistoria and id_aviso= $idAviso");
	}

	public function save(array $data) {
		
		$Row = $this->find($data['id_vistoria'],$data['id_aviso'])->current();
		if (!$Row) {
			$Row = $this->createRow();
		}

		$Row->id_vistoria = $data[id_vistoria];
		$Row->id_aviso = $data[id_aviso];
		
		return $Row->save();
	}

	public function getIdentificadorEssorByIdsVistoria(string $idsVistoria)
	{
		$query = '
			SELECT
				va.id_vistoria,
				min(ats.cd_identificador_seguradora) as cd_identificador_seguradora
			FROM
				sinistro.vistorias_avisos va
			INNER JOIN sinistro.avisos_transmissao_seguradora ats
				ON ats.id_aviso = va.id_aviso
			WHERE va.id_vistoria IN ('. $idsVistoria .')
			GROUP BY va.id_vistoria
		';

		return $this->_db->fetchPairs($query);
		
	}

	/**
	 * Busca os avisos relacionados à vistoria $idVistoria.
	 * Se $arrayAvisos for passado como 2º parâmetro, retorna um
	 * array de elementos de $arrayAvisos que estão contidos em $data.
	 *
	 * @param int $idVistoria
	 * @param array $arrayAvisos
	 * @return array $data
	 */
	public function getAvisosByVistoria($idVistoria, $arrayAvisos=array()){
		$data = array();
		if($idVistoria){
			$select = $this->select();
			$select->setIntegrityCheck(false);
			$select->from(array('va'=>'sinistro.vistorias_avisos'), 'va.id_aviso');
			$select->where($this->getAdapter()->quoteInto('va.id_vistoria = ?',$idVistoria));

			$data = $this->_db->fetchCol($select);

			if(count($arrayAvisos) > 0){
				$aux = array();
				foreach ($arrayAvisos as $item){
					if (in_array($item,$data)) {
						$aux[] = $item;
					}
				}
				$data = $aux;
			}
		}
		return $data;
	}

	public function hasVistoriaFinal($idVistoriaPreliminar, $idCobertura) {

		$hasVistoriaFinal = false;
		if ($idVistoriaPreliminar && $idCobertura) {
			$select = "
				select
					count(v.id) as nr_avisos_vist_final
				from
					sinistro.vistorias_avisos va
					inner join sistema.vistorias_coberturas vc on vc.id_vistoria = va.id_vistoria
					inner join sistema.vistorias v on v.id = va.id_vistoria
					inner join sistema.tipos_vistoria tp on tp.id = v.id_tipo
				where
					tp.ds_chave_tipos_vistoria = 'FINAL' and
					vc.id_cobertura = $idCobertura and
					va.id_aviso  in(
							select
								va.id_aviso
							from
								sinistro.vistorias_avisos va
							where
								va.id_vistoria = $idVistoriaPreliminar
					)
			";

			$result = $this->_db->fetchOne($select);

			if ($result > 0) {
				$hasVistoriaFinal = true;
			}
		}

		return $hasVistoriaFinal;
	}

	public function getVistoriasSemLaudo($idProcesso){
		$result = array();
		if($idProcesso){
			$select ="
				select
					va.id_vistoria,
					tv.ds_tipo
				from
					sinistro.processos p
					inner join sinistro.avisos av on av.id_proposta = p.id_proposta
					inner join sinistro.vistorias_avisos va on va.id_aviso = av.id
					inner join sistema.vistorias v on v.id = va.id_vistoria
					inner join sistema.tipos_vistoria tv on tv.id = v.id_tipo
					inner join sistema.vistorias_empresas ve on ve.id_vistoria = va.id_vistoria
					left join sistema.vistorias_laudos_preliminares vlp on vlp.id_vistoria = ve.id_vistoria
				where
					p.id = $idProcesso and
					tv.ds_chave_tipos_vistoria = 'PRELIMINAR' and
					vlp.id_vistoria is null

				union

				select
					va.id_vistoria,
					tv.ds_tipo
				from
					sinistro.processos p
					inner join sinistro.avisos av on av.id_proposta = p.id_proposta
					inner join sinistro.vistorias_avisos va on va.id_aviso = av.id
					inner join sistema.vistorias v on v.id = va.id_vistoria
					inner join sistema.tipos_vistoria tv on tv.id = v.id_tipo
					inner join sistema.vistorias_empresas ve on ve.id_vistoria = va.id_vistoria
					left join sistema.vistorias_laudos_finais vlf on vlf.id_vistoria = ve.id_vistoria
				where
					p.id = $idProcesso and
					tv.ds_chave_tipos_vistoria = 'FINAL' and
					vlf.id_vistoria is null
			";

			$result = $this->_db->fetchAll($select);
		}

		return $result;
	}

	public function getAvisos($idVistoria){
		$result = '';

		if($idVistoria){
			$select = $this->select();
			$select->setIntegrityCheck(false);

			$select->from(array('va'=>'sinistro.vistorias_avisos'), 'va.id_aviso');
			$select->where('va.id_vistoria = ?', $idVistoria);

			$rs = $this->_db->fetchCol($select);

			if(count($rs) > 0){
				$aux = '';
				foreach ($rs as $item){
					$aux .= $item . ', ';
				}
				$result = substr($aux, 0, strlen($aux) - 2);
			}
		}
		return $result;
	}

	public function getAgendamentosByAviso($idProcesso) {
        $select = $this->select()->setIntegrityCheck(false);

		$select->from(array('ag' => 'sistema.agendamentos'));
        $select->join(array('vag' => 'sistema.vistorias_agendamentos'), "vag.id_agendamento = ag.id",false);
        $select->join(array('vp' => 'sinistro.vistorias_processos'), "vag.id_vistoria = vp.id_vistoria",false);
        $select->where("vp.id_processo=$idProcesso");

        return Zend_Db_Table::getDefaultAdapter()->fetchAll($select);
	}

	public function setVistoriaPreliminarAvisos($idProposta, $idVistoria, $dtVistoria, $idCobertura) {
		$subselect1 = $this->select()->setIntegrityCheck(false);
		$subselect1->from(array('a2'=>'sinistro.avisos'), "id");
		$subselect1->join(array('st'=>'sistema.status'), "st.id = a2.id_status and st.ds_chave = 'ACEITO'", null);
		$subselect1->join(array('va'=>'sinistro.vistorias_avisos'), 'va.id_aviso = a2.id and va.id_vistoria != '.$idVistoria, null);
		$subselect1->where('a.id_proposta = ?', $idProposta);

		$subselect2 = $this->select()->setIntegrityCheck(false);
		$subselect2->from(array('ae'=>'sinistro.avisos_eventos'), 'id_aviso');
		$subselect2->join(array('ce'=>'produto.coberturas_eventos'), 'ce.id_evento = ae.id_evento', null);
		$subselect2->where('ce.id_cobertura = ?', $idCobertura);

		$select = $this->select()->setIntegrityCheck(false);
		$select->from(array('a'=>'sinistro.avisos'), array('id as id_aviso', "fl_dispensa_preliminar"));
		$select->join(array('st'=>'sistema.status'), "st.id = a.id_status and st.ds_chave = 'ACEITO'", null);
		$select->where('a.id_proposta = '.$idProposta);
		$select->where('a.dt_sinistro < ?', $dtVistoria);
		$select->where('a.id not in (?)', $subselect1);
		$select->where('a.id in (?)', $subselect2);

		$arAvisos = $this->_db->fetchAll($select);

		if (count($arAvisos) > 0) {
			$this->delete($idVistoria);

			$avisos_liberados = array();
			$avisos_dispensados = array();

			foreach ($arAvisos as $Aviso) {
				if ($Aviso["fl_dispensa_preliminar"]){
					$avisos_dispensados[] = $Aviso['id_aviso'];
				} else {
					$avisos_liberados[] = $Aviso['id_aviso'];
				}
			}

			if (count($avisos_liberados) > 0){
				foreach ($avisos_liberados as $Aviso){
					$this->insert(array(
						'id_vistoria'=>$idVistoria,
						'id_aviso'=>$Aviso
					));
				}
				return true;

			} else {
				$this->setMessage("Informamos que não é possível salvar essa preliminar.<br>O dpto de sinistro dispensou a vistoria preliminar para o(s) Aviso(s) ".implode(", ", $avisos_dispensados).".<br>Favor entrar em contato com a AgroBrasil.");
				return false;
			}

		} else {
			return false;
		}
	}

	public function setVistoriaFinalAvisos($idProposta, $idVistoria, $dtVistoria, $idCobertura, $idProduto) {

	    $ProdutoCoberturas = new Produto_Model_ProdutosCoberturas();
	    $fl_vistoria_preliminar = $ProdutoCoberturas->getFlVistoriaPreliminar($idProduto, $idCobertura);

		// Chama o método para relacionamento de vistorias/avisos apropriado conforme a necessidade de preliminar do produto/cobertura
		if ($fl_vistoria_preliminar) {
			return $this->setVistoriaFinalAvisosComPreliminar($idProposta, $idVistoria, $dtVistoria, $idCobertura);
		} else {
			return $this->vinculaVistoriasAvisos($idProposta, $idVistoria, $dtVistoria, $idCobertura);
		}
	}

	public function vinculaVistoriasAvisos($idProposta, $idVistoria, $dtVistoria, $idCobertura, $tpVistoria="LF"){
		$VitoriasAvisos = array();
		$ModelAvisos 	= new Sinistro2_Model_AvisosSinistro();
		$ModelVistoria 	= new Sistema_Model_Vistorias();
		$ModelProposta 	= new Seguro_Model_Propostas();
		$ModelCobertura = new Produto_Model_Coberturas();

		try {
			$Proposta  = $ModelProposta->find($idProposta)->current();
			$Cobertura = $ModelCobertura->find($idCobertura)->current();

			$DtVistoria = new Zend_Date($dtVistoria);

			/**
			 * Existem avisos anteriores a data da vistoria?
			 */
			$subselect1 = $this->select()->setIntegrityCheck(false);
			$subselect1->from(array('ae'=>'sinistro.avisos_eventos'), 'id_aviso');
			$subselect1->join(array('ce'=>'produto.coberturas_eventos'), 'ce.id_evento = ae.id_evento', null);
			$subselect1->where('ce.id_cobertura = ?', $idCobertura);

			$select = $this->select()->setIntegrityCheck(false);
			$select->from(array('a'=>'sinistro.avisos'), 'id');
			$select->join(array('st'=>'sistema.status'), "st.id = a.id_status and st.ds_chave = 'ACEITO'", null);
			$select->where('a.id_proposta = '.$idProposta);
			$select->where('a.dt_sinistro < ?', $dtVistoria);
			//$select->where('a.id not in  (select id_aviso from sinistro.vistorias_avisos)');
			//$select->where('fl_ocorrencia_queda_parreiral is true or a.id in (?)', $subselect1);
			//$select->where('fl_ocorrencia_queda_parreiral is true or a.id not in (select id_aviso from sinistro.vistorias_avisos where id_vistoria <> '.$idVistoria.')');//
			$select->where('a.id in (?)', $subselect1);

			if($tpVistoria == 'LF'){
				$select->where('a.id not in (select id_aviso from sinistro.vistorias_avisos where id_vistoria <> '.$idVistoria.' and id_vistoria in (select id_vistoria from sistema.vistorias_laudos_finais))');
			} else {
				$select->where('a.id not in (select id_aviso from sinistro.vistorias_avisos where id_vistoria <> '.$idVistoria.' and id_vistoria in (select id_vistoria from sistema.vistorias_laudos_preliminares))');
			}

			$Avisos = $this->fetchAll($select)->toArray();

			if ($Avisos){

			    $this->delete($idVistoria);

				foreach ($Avisos as $aviso){
					$id = $this->insert(array(
						'id_vistoria' => $idVistoria,
						'id_aviso' => $aviso['id']
					));

					array_push($VitoriasAvisos, $id);
				}
				return $VitoriasAvisos;

			} else {
				//Recupera a ultima vistoria realizada
				$subselect2 = $this->select()->setIntegrityCheck(false);
				$subselect2->from(array('vlf'=>'sistema.vistorias_laudos_finais'), 'max(vlf.id_vistoria)');
				$subselect2->join(array('lf'=>'sinistro.laudos_finais'), 'lf.id = vlf.id_laudo_final', null);
				$subselect2->join(array('sp'=>'sinistro.processos'), 'sp.id = lf.id_processo', null);
				$subselect2->join(array('st'=>'sistema.status'), 'st.id = lf.id_status', null);
				$subselect2->where('lf.id_cobertura  = ?', $idCobertura);
				$subselect2->where('sp.id_proposta   = ?', $idProposta);
				$subselect2->where('vlf.id_vistoria <> ?', $idVistoria);
				$subselect2->where('st.ds_chave not in (\'PENDENTE_LAUDO_FINAL\', \'CANCELADO\', \'CANCELADO_CULPA_SEGURADO\')');

				$idMaxVistoriaCobertura = $this->_db->fetchOne($subselect2);

			    $select = $this->select()->setIntegrityCheck(false);
			    $select->from(array('a'=>'sinistro.avisos'), 'id');
			    $select->join(array('st'=>'sistema.status'), "st.id = a.id_status and st.ds_chave = 'ACEITO'", null);
			    $select->where('a.id_proposta = '.$idProposta);
			    $select->where('a.dt_sinistro < ?', $dtVistoria);
			    $select->where('a.id in (?)', $subselect1);

			    if($idMaxVistoriaCobertura){
			    	$select->where('a.id in (select id_aviso from sinistro.vistorias_avisos where id_vistoria = '.$idMaxVistoriaCobertura.')');
			    }

			    $Avisos = $this->fetchAll($select)->toArray();

			    if ($Avisos){

			        $this->delete($idVistoria);

			        foreach ($Avisos as $aviso){
			            $id = $this->insert(array(
			                    'id_vistoria'=>$idVistoria,
			                    'id_aviso'=>$aviso['id']
			            ));

			            array_push($VitoriasAvisos, $id);
			        }
			        return $VitoriasAvisos;

			    } else {
    				$this->setMessage("Não existem avisos disponíveis anteriores a esta vistoria");
    				return false;
			    }
			}


		} catch (Exception $e) {
			$this->setMessage($e->getMessage());
			return false;
		}
	}

	public function verifyVistoriaFinalAvisos($idProposta, $idVistoria, $dtVistoria, $idCobertura) {
		// Verifica se o produto cobertura possui vistoria preliminar
		$select = $this->select()->setIntegrityCheck(false);
		$select->from(array('pr'=>'seguro.propostas'), null);
		$select->join(array('pdc'=>'produto.produtos_coberturas'), 'pdc.id_produto = pr.id_produto and pdc.id_cobertura = '.$idCobertura, 'fl_vistoria_preliminar');
		$select->where('pr.id = ?', $idProposta);

		$fl_vistoria_preliminar = $this->_db->fetchOne($select);

		// Chama o método para relacionamento de vistorias/avisos apropriado conforme a necessidade de preliminar do produto/cobertura
		if ($fl_vistoria_preliminar) {
			return $this->verifyVistoriaFinalAvisosComPreliminar($idProposta, $idVistoria, $dtVistoria, $idCobertura);
		} else {
			return $this->verifyVistoriaFinalAvisosSemPreliminar($idProposta, $idVistoria, $dtVistoria, $idCobertura);
		}

	}

	public function verifyVistoriaFinalAvisosSemPreliminar($idProposta, $idVistoria, $dtVistoria, $idCobertura) {

		$select = $this->select()->setIntegrityCheck(false);
		$select->from(array('sp'=>'sinistro.processos'), null);
		$select->join(array('vp'=>'sinistro.vistorias_processos'), 'vp.id_processo = sp.id and vp.id_vistoria != '.$idVistoria, null);
		$select->join(array('vc'=>'sistema.vistorias_coberturas'), 'vc.id_vistoria = vp.id_vistoria and vc.id_cobertura = '.$idCobertura, null);
		$select->join(array('vlf'=>'sistema.vistorias_laudos_finais'), 'vlf.id_vistoria = vp.id_vistoria', null);
		$select->join(array('lf'=>'sinistro.laudos_finais'), 'vlf.id_laudo_final = lf.id', null);
		$select->join(array('lfis'=>'sinistro.laudos_finais_itens_segurados'), 'lfis.id_laudo_final = vlf.id_laudo_final', 'max(lfis.dt_vistoria)');
		$select->where('sp.id_proposta = ?', $idProposta);
		$select->where('lf.id_status not in (207,209)');

		$dtVistoriaAnterior = $this->_db->fetchOne($select);

		if ($dtVistoriaAnterior) {
			$date = new Zend_Date($dtVistoria);
			if ($date->isEarlier(new Zend_Date($dtVistoriaAnterior))) {
				$dtVistoriaAnterior = null;
			}
		} else {
			$dtVistoriaAnterior = null;
		}

		$subselect1 = $this->select()->setIntegrityCheck(false);
		$subselect1->from(array('ae'=>'sinistro.avisos_eventos'), 'id_aviso');
		$subselect1->join(array('ce'=>'produto.coberturas_eventos'), 'ce.id_evento = ae.id_evento', null);
		$subselect1->where('ce.id_cobertura = ?', $idCobertura);

		$select = $this->select()->setIntegrityCheck(false);
		$select->from(array('a'=>'sinistro.avisos'), 'count(a.id) as nr_aviso');
		$select->join(array('st'=>'sistema.status'), "st.id = a.id_status and st.ds_chave = 'ACEITO'", null);
		$select->where('a.id_proposta = ?', $idProposta);
		$select->where('a.dt_aceitacao < ?', $dtVistoria);
		$select->where('fl_ocorrencia_queda_parreiral is true or a.id in (?)', $subselect1);

		// Se exite vistoria anterior, filtra por sinistros ocorridos após a vistoria anterior
		if ($dtVistoriaAnterior) {
			//$select->where("a.dt_aceitacao > ?",$dtVistoriaAnterior);
		}

		$nrAvisos = $this->_db->fetchOne($select);

		if ($nrAvisos > 0) {
			return true;
		} else {
			return false;
		}
	}

	public function verifyVistoriaFinalAvisosComPreliminar($idProposta, $idVistoria, $dtVistoria, $idCobertura) {

		$subselect1 = $this->select()->setIntegrityCheck(false);
		$subselect1->from(array('ae'=>'sinistro.avisos_eventos'), 'id_aviso');
		$subselect1->join(array('ce'=>'produto.coberturas_eventos'), 'ce.id_evento = ae.id_evento', null);
		$subselect1->where('ce.id_cobertura = ?', $idCobertura);

		$select = $this->select()->setIntegrityCheck(false);
		$select->from(array('a'=>'sinistro.avisos'), 'count(a.id) as nr_aviso');
		$select->join(array('st'=>'sistema.status'), "st.id = a.id_status and st.ds_chave = 'ACEITO'", null);
		$select->where('a.id_proposta = '.$idProposta);
		$select->where('a.dt_aceitacao < ?', $dtVistoria);
		$select->where('a.id in (?)', $subselect1);

		$nrAvisos = $this->_db->fetchOne($select);

		if ($nrAvisos > 0) {
			return true;
		} else {
			return false;
		}
	}

	public function checkPreliminarDispensadaByIdVistoria($idVistoria) {

		$select = $this->select()->setIntegrityCheck(false);
		$select->from(array('va'=>'sinistro.vistorias_avisos'), false);
		$select->join(array('a'=>'sinistro.avisos'), "va.id_aviso = a.id", 'fl_dispensa_preliminar');
		$select->where('va.id_vistoria = ?', $idVistoria);
		$select->where('a.fl_dispensa_preliminar = ?', true);

		if($this->_db->fetchOne($select)){
			return true;
		} else {
			return false;
		}
	}

	public function temOutrosAvisosMesmaVistoriaPreliminarByAviso(int $idAviso)
    {
        $select = $this->select()->setIntegrityCheck(false);
        $select->from(['va1' => 'sinistro.vistorias_avisos'], false);
        $select->join(['va2' => 'sinistro.vistorias_avisos'], 'va2.id_vistoria = va1.id_vistoria', ['va2.id_aviso', 'va2.id_vistoria']);
        $select->join(['v' => 'sistema.vistorias'], 'v.id = va2.id_vistoria', ['v.id_tipo']);
        $select->where("va1.id_aviso = {$idAviso}");
        $select->where("va2.id_aviso <> {$idAviso}");
        $select->where("v.id_tipo = ? ", Sistema_Model_TipoVistoria::PRELIMINAR);

        return $this->_db->fetchAll($select);
    }
}
