<?php
/**
 * @name Safra17_Model_Lf003ItensSeguradosAmostras
 * @desc Model das amostras do Laudo final Itens Segurados Tipo LF003 / Safra17
 * @author Vinicius Marconi Vasconcelos Berni
 * @since 27/04/2011 16:17
 * @see Agro_Db_Table_Abstract
 */
class Regulacao_Model_Lf003ItensSeguradosAmostras extends Agro_Db_Table_Abstract {
	protected $_rowClass = 'Regulacao_Model_Row_Lf003ItemSeguradoAmostras';
	protected $_schema 	= 'regulacao';
	protected $_name 	= 'lf003_itens_segurados_amostras';
	protected $_primary = 'id';
	public 	  $_order 	= 'id_laudo_final';

	const MAP_CULTURA_LIMITE_VALOR_UMIDADE = [
		'MILHO' => 26.5,
		'SORGO' => 26.5,
		'SOJA' => 20.5,
		'FEIJÃO' => 23,
		'TRIGO' => 20.5,
		'CEVADA' => 20.5
	];

	public function __beforeSave($dados){
		$params = $this->montaArray($dados);
		$params  = $this->__valida($params);
		
		if ($params){
			$params  = $this->__calcula($params);
		}
		
		return $params;
	}

	private function prepareColumnsWithNumericValues(array &$amostra): void
	{
		foreach ($amostra as $column => $value) {
			$aux = explode('_', $column);

			if ($aux[0] == 'vl' && !is_numeric($value)) {
				$amostra[$column] = null;
			}
		}
	}

	public function save($dados){

		$params = $this->__beforeSave($dados);

		if (is_array($params)){
		    $Model_Lf003ItensSegurados = new Regulacao_Model_Lf003ItensSegurados();

			$idLaudoFinalItemSegurado = $Model_Lf003ItensSegurados->save($params);
			
            if($idLaudoFinalItemSegurado){
                $alreadyInTransaction = false;
                try {
	    		    $this->getDefaultAdapter()->beginTransaction();
                } catch (Exception $e) { 
                    $alreadyInTransaction = true;
                }

		    	try {
	    		    $this->delete($idLaudoFinalItemSegurado, 'id_laudo_final_item_segurado');
					
	    		    foreach ($params["amostras"] as $amostra) {
						$values = $amostra;

						foreach ($amostra as $keyAmostra => $value) {
							$aux = explode('_', $keyAmostra);
							if ($aux[0] == 'vl' && !is_numeric($values[$keyAmostra])) {
								$values[$keyAmostra] = null;
							}
						}

	    		    	$values["id_laudo_final_item_segurado"] = $idLaudoFinalItemSegurado;

	    		    	$this->insert($values);
	    		    }

	    		    if (!$alreadyInTransaction) {
						$this->getDefaultAdapter()->commit();
					}
					
	    		    $this->setMessage("Operação realizada com sucesso.");

	    			return $idLaudoFinalItemSegurado;

	    		} catch (Exception $e) {
	    		    if (!$alreadyInTransaction) {
						$this->getDefaultAdapter()->commit();
					}

	    			$this->setMessage($e->getMessage().'<br><pre>'.$e->getTraceAsString().'</pre>');
	    		    return false;
	    		}
		    } else {
		    	$this->setMessage($Model_Lf003ItensSegurados->getMessages());
		        return false;
		    }
		} else {
			return false;
		}
	}

	public function montaArray($dados){

		$params = array(
			"id_laudo_final_item_segurado" 	=> $dados["id_laudo_final_item_segurado"],
			"id_laudo_final" 				=> $dados["id_laudo_final"],
			"id_item_segurado" 				=> $dados["id_item_segurado"],
		    "id_proposta" 					=> $dados["id_proposta"],
		    "id_processo" 					=> $dados["id_processo"],
		    "id_cobertura"					=> $dados["id_cobertura"],
		    "id_vistoria"					=> $dados["id_vistoria"],
		    "fl_vistoria_preliminar"        => $dados["fl_vistoria_preliminar"],
		    "dt_vistoria_data" 				=> $dados["dt_vistoria_data"],
		    "dt_vistoria_hora" 				=> $dados["dt_vistoria_hora"],
		    "dt_vistoria_minutos" 			=> $dados["dt_vistoria_minutos"],
		    "vl_area_sinistrada" 			=> $dados["vl_area_sinistrada"],
		    "vl_percent_colhido" 			=> $dados["vl_percent_colhido"],
		    "ds_coordenadas_geograficas" 	=> $dados["ds_coordenadas_geograficas"],
		    "dt_vistoria" 					=> Agro_Util::joinDtVistoria($dados["dt_vistoria_data"], $dados["dt_vistoria_hora"], $dados["dt_vistoria_minutos"]),
		    "fl_amostragem_maquina" 		=> $dados["fl_amostragem_maquina"],
		    "ds_observacao" 				=> $dados["ds_observacao"],
		    "fl_assinatura_segurado" 		=> $dados["fl_assinatura_segurado"],
		    "fl_assinatura_regulador" 		=> $dados["fl_assinatura_regulador"],
			"vistoriadores" 				=> $dados["vistoriadores"],
			"auxiliares"					=> $dados["auxiliares"],
			"vl_rendimento_final_lavoura" 	=> $dados["vl_rendimento_final_lavoura"],
			"vl_graos_podres"				=> $dados["vl_graos_podres"],
			"vl_graos_brotados"				=> $dados["vl_graos_brotados"],
			"vl_pragas_doencas_outros"		=> $dados["vl_pragas_doencas_outros"],
			"amostras"						=> array(),
			"vl_area_vistoriada" 			=> $dados["vl_area_vistoriada"],
			"vl_area" 			            => $dados["vl_area"],
			"fl_zoneamento_valido"          => $dados["fl_zoneamento_valido"],
		);

		if ($params["fl_amostragem_maquina"]){
			
			$params["amostras"]['maq'] = array(
				"id_laudo_final_item_segurado" 		=> 0,
				"nr_amostra" 						=> 1,
				"vl_espacamento_entre_linhas" 		=> 0,
				"vl_metros_linhas_colhidos" 		=> 0,
				"vl_producao_colhida_amostra" 		=> $dados["vl_producao_colhida_amostra"],
				"vl_producao_kilos_hectare" 		=> 0,
				"vl_perda_colheita" 				=> $dados["vl_perda_colheita"],
				"vl_umidade_graos" 					=> $dados["vl_umidade_graos"],
				"vl_desconto_umidade_graos" 		=> $dados["vl_desconto_umidade_graos"],
				"vl_producao_bruta" 				=> 0,
				"vl_desconto" 						=> 0,
				"vl_producao_liquida" 				=> 0,
				"vl_area_colhida" 					=> $dados['vl_area_colhida'],
				"vl_largura_plataforma" 			=> $dados["vl_largura_plataforma"],
				"vl_distancia_percorrida" 			=> $dados["vl_distancia_percorrida"],
				"vl_impurezas"						=> $dados["vl_impurezas"],
			);

			$params["fl_amostragem_maquina"] = 1;

		} else {
			for ($i=1;$i<=10;$i++){
				if ($dados["vl_espacamento_entre_linhas_$i"] > 0){
					$params["amostras"][$i] = array(
						"id_laudo_final_item_segurado" => 0,
						"nr_amostra" => $i,
						"vl_espacamento_entre_linhas" => $dados["vl_espacamento_entre_linhas_$i"],
						"vl_metros_linhas_colhidos" => $dados["vl_metros_linhas_colhidos_$i"],
						"vl_producao_colhida_amostra" => $dados["vl_producao_colhida_amostra_$i"],
						"vl_producao_kilos_hectare" => $dados["vl_producao_kilos_hectare_$i"],
						"vl_umidade_graos" => $dados["vl_umidade_graos_$i"],
						// "vl_perda_colheita" => 0.02,
						"vl_desconto_umidade_graos" => $dados["vl_desconto_umidade_graos_$i"],
						"vl_producao_bruta" => $dados["vl_producao_bruta_$i"],
						"vl_desconto" => $dados["vl_desconto_$i"],
						"vl_producao_liquida" => $dados["vl_producao_liquida_$i"],
						"vl_area_colhida" => null,
						"vl_producao_kilos_hectare_com_perda" => null,
						"vl_producao_bruta_kilos_hectare" => $dados["vl_producao_bruta_kilos_hectare_$i"],
						"vl_largura_plataforma" => $dados["vl_largura_plataforma"],
						"vl_distancia_percorrida" => $dados["vl_distancia_percorrida"],
						"vl_perda_colheita" => $dados["vl_perda_colheita"],
						"vl_impurezas" => $dados["vl_impurezas"]
					);
				}
			}

			$params["fl_amostragem_maquina"] = 0;
		}

		return $params;
	}

	public function __valida($dados){
		$result = $dados;
		
		$Model_Vistorias = new Sinistro_Model_VistoriasAvisos();
		$dtVistoria = new Zend_Date($dados['dt_vistoria_data'].' '.$dados['dt_vistoria_hora'].':'.$dados['dt_vistoria_minutos'], 'dd/MM/yyyy HH:mm');
		if (!$Model_Vistorias->verifyVistoriaFinalAvisos($dados['id_proposta'], $dados['id_vistoria'], $dtVistoria->toString('yyyy-MM-dd HH:mm'), $dados['id_cobertura'])) {
			$this->setMessage("Não existe sinistro disponível anterior a data de vistoria informada");
			$result = false;
		}

		// Caso o produto/cobertura possua vistoria preliminar, verifica se a data de vistoria informada está de acordo com o período da vistoria
        if ($dados['fl_vistoria_preliminar']) {
            $Model_LaudosFinaisItensSegurados = new Sinistro_Model_LaudosFinaisItensSegurados();
            $periodoVistoria = $Model_LaudosFinaisItensSegurados->getMinMaxDtVistoriaByIdLaudoFinal($dados['id_laudo_final'], $dados['id_laudo_final_item_segurado']);

            if ($periodoVistoria['min_dt_vistoria'] || $periodoVistoria['max_dt_vistoria']) {
                if ($periodoVistoria['min_dt_vistoria']) {

                    $min_dt_vistoria = new Zend_Date($periodoVistoria['min_dt_vistoria'], 'yyyy-MM-dd HH:mm');
                    if ($min_dt_vistoria->isEarlier($dtVistoria)) {
                        $diff = ($dtVistoria->getTimestamp() - $min_dt_vistoria->getTimestamp()) / (3600 * 24);
                        if ($diff > 4) {
                            $this->setMessage("Data de vistoria fora do período para esta vistoria. Insira uma nova vistoria para este item.");
                            $result = false;
                        }
                    }
                }

                if ($periodoVistoria['max_dt_vistoria']) {
                    $max_dt_vistoria = new Zend_Date($periodoVistoria['max_dt_vistoria'], 'yyyy-MM-dd HH:mm');
                    if ($max_dt_vistoria->isLater($dtVistoria)) {
                        $diff = ($max_dt_vistoria->getTimestamp() - $dtVistoria->getTimestamp()) / (3600 * 24);
                        if ($diff > 4) {
                            $this->setMessage("Data de vistoria fora do período para esta vistoria. Insira uma nova vistoria para este item.");
                            $result = false;
                        }
                    }
                }

            }
        }

		if (!isset($dados['fl_zoneamento_valido']) || $dados['fl_zoneamento_valido'] == "") {
			$this->setMessage("Zoneamento Válido é de preenchimento obrigatório.");
			$result = false;
		}

		if (!$dados["vl_percent_colhido"]){
			$this->setMessage("Percentual colhido é de preenchimento obrigatório");
			$result = false;
		}
        
		if (!$dados["ds_coordenadas_geograficas"]){
			$this->setMessage("Coordenadas geográficas são de preenchimento obrigatório");
			$result = false;
		}
        
		if (!$dados["fl_amostragem_maquina"]){

			$campos = array(
				"vl_espacamento_entre_linhas" => "Espaçamento entre linhas",
				"vl_metros_linhas_colhidos" => "Metros de linha colhidos",
				"vl_producao_colhida_amostra" => "Produção colhida na amostra",
				"vl_umidade_graos" => "Umidade dos grãos"
			);

			if (count($dados["amostras"]) > 0){
				foreach ($dados["amostras"] as $amostra){
					$campos_vazios = array();

					if ($amostra["vl_espacamento_entre_linhas"] > 0){
						foreach ($campos as $key => $label){
							if(!$amostra[$key]){
								$campos_vazios[] = $campos[$key];
							}
						}
					}

					if (count($campos_vazios)){
						$this->setMessage("Amostra {$amostra["nr_amostra"]}, campos não preenchidos:<ul><li>".implode("</li><li>", $campos_vazios)."</li></ul>");
						$result=false;
					}
				}
			} else {
				$this->setMessage("Preencher todos os campos de pelo menos uma amostra ou, caso seja ITEM NÃO VISTORIADO, marque esta opção e selecione o motivo.");
				$result=false;
			}
            
		} else {
			$campos = array(
				"vl_producao_colhida_amostra" => "Produção colhida na amostra",
				"vl_perda_colheita" => "Perda de colheita (%)",
				"vl_umidade_graos" => "Umidade dos Graos (%)",
				"vl_largura_plataforma" => "Largura da plataforma",
				"vl_distancia_percorrida" => "Distância percorrida"
			);

			foreach ($campos as $key => $label){
				if (!$dados["amostras"]['maq'][$key]){
					$this->setMessage("O campo '{$campos[$key]}' é de preenchimento obrigatório.");
					$result=false;
				}
			}
		}
        
		return $result;
	}

	public function __calcula($dados){
		$Cultura = new Seguro_Model_Propostas();
		$cultura = $Cultura->getCulturaProduto($dados['id_proposta']);
		
		if(!count($dados['amostras']['maq'])){
			for ($i=1; $i <= count($dados["amostras"]);$i++){
				$dados['amostras'][$i]['vl_desconto_umidade_graos'] = $this->calculaDescontoUmidade($dados['amostras'][$i]['vl_umidade_graos'], $cultura['ds_chave_cultura']);
			}
		}

		if ($dados["fl_amostragem_maquina"]){
			$dados['amostras']['maq']['vl_desconto_umidade_graos'] = $this->calculaDescontoUmidade($dados['amostras']['maq']['vl_umidade_graos'], $cultura['ds_chave_cultura']);

			$dados["amostras"]['maq']["vl_area_colhida"] = round((($dados['amostras']['maq']["vl_largura_plataforma"]*$dados['amostras']['maq']["vl_distancia_percorrida"]) / 10000), 3);
			
			if($dados['amostras']['maq']['vl_perda_colheita'] >= 2){
				$rendimento = (((($dados['amostras']['maq']['vl_producao_colhida_amostra'] / $dados["amostras"]['maq']["vl_area_colhida"]) + ($dados['amostras']['maq']['vl_producao_colhida_amostra'] / $dados["amostras"]['maq']["vl_area_colhida"]) * (($dados['amostras']['maq']['vl_perda_colheita'] / 100) - 0.02)) * (1 - ($dados['amostras']['maq']['vl_desconto_umidade_graos'] / 100)) * (1 - ($dados['amostras']['maq']['vl_impurezas']) / 100)) / 1000);
				
			}else{
				
				$rendimento = 0.0;

				if ($dados["amostras"]['maq']["vl_area_colhida"] > 0) {
					$rendimento = (($dados['amostras']['maq']['vl_producao_colhida_amostra'] / $dados["amostras"]['maq']["vl_area_colhida"]) * (1 - ($dados['amostras']['maq']['vl_desconto_umidade_graos'] / 100)) * (1 - ($dados['amostras']['maq']['vl_impurezas'] / 100)) / 1000);
				}
			}

			$dados["amostras"]['maq']["vl_area_colhida"] = Agro_Util::round($dados["amostras"]['maq']["vl_area_colhida"], 3);

			$dados["vl_rendimento_final_lavoura"] = Agro_Util::round($rendimento, 3);

		} else {

			//amostragens manuais
			for ($i=1;$i <= count($dados["amostras"]);$i++){

				//fixo
				$dados["amostras"][$i]["vl_perda_colheita"] = 0.02;
				//
				$dados["amostras"][$i]["vl_producao_liquida"] = (($dados["amostras"][$i]["vl_producao_colhida_amostra"] / $dados["amostras"][$i]["vl_metros_linhas_colhidos"]) * (10000 / $dados["amostras"][$i]["vl_espacamento_entre_linhas"])) * (1 - $dados["amostras"][$i]["vl_perda_colheita"]) * (1 - ($dados['amostras'][$i]['vl_desconto_umidade_graos']/100));

			}
			//dump($dados["amostras"]['maq']["vl_espacamento_entre_linhas"]);
			//if ($dados["amostras"]['maq']["vl_espacamento_entre_linhas"] > 0){
				$rendimento = 0.0;

				$total_producao_liquida = $this->__somaAmostra("vl_producao_liquida", $dados);

				if ($total_producao_liquida["valor"] > 0){
					$rendimento = ($total_producao_liquida["valor"] / $total_producao_liquida["count"]) / 1000;
				}

				$dados["vl_rendimento_final_lavoura"] = Agro_Util::round($rendimento, 3);
			//} else {
				//$dados["vl_rendimento_final_lavoura"] = null;
			//}
		}
		
		return $dados;
	}
	
	public function calculaDescontoUmidade($valorUmidadeGraos, $cultura){
		if (empty($valorUmidadeGraos) || $valorUmidadeGraos <= 13) {
			return 0;
		}

		$limite = -1;
		
		foreach (self::MAP_CULTURA_LIMITE_VALOR_UMIDADE as $key => $value) {
			if (strpos($cultura, $key) !== false) {
				$limite = self::MAP_CULTURA_LIMITE_VALOR_UMIDADE[$key];
				break;
			}
		}

		if ($limite > 0 && $valorUmidadeGraos > $limite) {
			$valorUmidadeGraos = $limite;
		}

		$descontoUmidade = (($valorUmidadeGraos - 13) / 87) * 100;
		
		return number_format($descontoUmidade, 2);
	}

	public function __somaAmostra($nomeAmostra, $dados){
		$somatorio = array(
			"valor" => 0.0,
			"count" => 0
		);

		for($i=1;$i<=10;$i++){
			if ($dados["amostras"][$i][$nomeAmostra] >= '0'){
				$somatorio["valor"] += $dados["amostras"][$i][$nomeAmostra];
				$somatorio["count"] += 1;
			}
		}

		return $somatorio;
	}

	public function get($idLaudoFinalItemSegurado) {
        $ModelLfIS = new Sinistro_Model_LaudosFinaisItensSegurados();
		$modelLaudosFinais = new Sinistro2_Model_LaudosFinais();
		/*
		 * Busca dados globais
		 */
		$dados = $ModelLfIS->getDataLaudoFinalItemSegurado($idLaudoFinalItemSegurado);
		$rowLaudoFinal = $modelLaudosFinais->getRow($dados['id_laudo_final']);

		/*
		 * Busca dados especialização
		 */
		if (!$dados['fl_nao_vistoriada'] || $rowLaudoFinal['fl_transmitido_tablet']) {
    		$select = $this->select()->setIntegrityCheck(false);
            $select->from(array("lfisX" => "$this->_schema.lf003_itens_segurados") , array('fl_amostragem_maquina', 'fl_danos_nao_cobertos_pragas', 'fl_danos_nao_cobertos_doencas', 'fl_danos_nao_cobertos_outros', 'vl_danos_nao_cobertos', 'vl_graos_podres', 'vl_graos_brotados', 'vl_pragas_doencas_outros'));
            $select->where('id_laudo_final_item_segurado = ?', $idLaudoFinalItemSegurado);

            $new = $this->fetchRow($select);

            if ($new){
            	$new = $new->toArray();

            } else {
            	$new = array();
            }

            $dados = array_merge($dados, $new);
        }

        /*
         * Busca Amostras
         */
        $dados["amostras"] = array();

        if (!$dados['fl_nao_vistoriada'] || $rowLaudoFinal['fl_transmitido_tablet']) {
			$amostras = $this->fetchAll("id_laudo_final_item_segurado = $idLaudoFinalItemSegurado")->toArray();

			foreach ($amostras as $amostra){

				if($dados['fl_amostragem_maquina'] == 1){
					$dados["amostras"]['maq'] = $amostra;
				}else{
					$dados["amostras"][$amostra["nr_amostra"]] = $amostra;
				}
			}
		}

        return $dados;
    }
}
