<?
class Safra12_Model_LIQ02 extends Agro_Db_Table_Abstract {
	protected $_schema = 'sinistro';
	protected $_name = 'tipo_liquidacao';
	protected $_primary = 'id';
	public $_order = 'ds_nome_tipo_liquidacao';
	
	
	public function liquidar($dados){
	    
		$result = array("status"=>true, "message"=>"", "execute"=>"");
		
		$ModelSafras = new Produto_Model_Safras();
		$dsSafra = $ModelSafras->getSafraModel($dados['id_proposta']);
		
		$ModelLiquidacoes = new Sinistro_Model_Liquidacoes();
		$ModelItemSegurado = new Seguro_Model_ItensSegurados();
		$ModelCoberturas = new Produto_Model_Coberturas();
		$ModelPropostasCoberturas = new Seguro_Model_PropostasCoberturas();
		$ModelLiquidacoesItensSeguradosCoberturas = new Sinistro_Model_LiquidacoesItensSeguradosCoberturas();
		$ModelLiquidacoesItensSeguradosCoberturasLF = new Sinistro_Model_LiquidacoesItensSeguradosCoberturasLF();
		$ModelLiquidacoesItensSeguradosCoberturasLFDependentes = new Sinistro_Model_LiquidacoesItensSeguradosCoberturasLFDependentes();
				
		$ItemSegurado = $ModelItemSegurado->find($dados['id_item_segurado'])->current();
		
		$fl_cobertura_qualidade_I = $ModelPropostasCoberturas->hasCoberturaByIdPropostaDsChave($dados['id_proposta'], 'COB_QUALIDADE_I');
		
		$this->getAdapter()->beginTransaction();
		
		try {
            
		    // Array de danos utilizado para abater danos anteriores durante o cálculo
			$arDanosAnteriores = array();	
			
			// Array que acumulará o prejuizo calculado por cobertura, para posterior aplicação da franquia
			$arCoberturas = array();
			
			// Recupera identificador da cobertura Qualidade I
			$CoberturaQualidade = $ModelCoberturas->getCobertura('COB_QUALIDADE_I',null);
			$idCoberturaQualidadeI = $CoberturaQualidade->id;
			
			foreach($dados['laudos'] as $laudo) {
			    
			    $Row = $ModelLiquidacoesItensSeguradosCoberturas->find($dados['id_liquidacao'], $dados['id_item_segurado'], $laudo['id_cobertura'])->current();
			    
			    if(!$Row) {
			        $Row = $ModelLiquidacoesItensSeguradosCoberturas->save(array(
                     'id_liquidacao'     => $dados['id_liquidacao'],
                     'id_item_segurado'  => $dados['id_item_segurado'],
                     'id_cobertura'      => $laudo['id_cobertura']
                    ));
			    }
			    
			    $params = array();
			    $params['id_liquidacoes_itens_segurados_coberturas'] = $Row['id'];
			    
				$vlPercentDanoLaudo = $laudo['percentual_dano'];
				
				if($laudo['ds_chave_cobertura'] == 'COB_CURA') {
				    /*
				     * Se a cobertura for Cura, recupera a área exposta informada no laudo ao invés do percentual colhido 
				     */
				    $vl_percent_recolhido = $this->getPercentProducaoRecolhida($dsSafra, $laudo['id_laudo_final_item_segurado']);
				    
				    $vlPercentDanoLaudo = (($laudo['vl_percent_colhido'] - $vl_percent_recolhido) * $vlPercentDanoLaudo / 100);
				    
				} else {
				    // Se houver percentual colhido, ajusta o dano para a área remascente
				    if ($laudo['vl_percent_colhido'] > 0) {
				        $vlPercentDanoLaudo = ((100 - $laudo['vl_percent_colhido']) * $vlPercentDanoLaudo / 100);
				    }
				}
				
				// Desconta os danos dos laudos anteriores
				foreach ($arDanosAnteriores as $danoAnterior) {
				    $vlPercentDanoLaudo = $vlPercentDanoLaudo * ( 1 - ( $danoAnterior / 100 ) );
				}
								
				$params['id_laudo_final_item_segurado'] = $laudo['id_laudo_final_item_segurado'];
				$params['vl_prejuizo'] = round( ( ( $ItemSegurado->vl_lmga * $vlPercentDanoLaudo / 100) ), 2 );
				
			
				$idLiquidacoesItensSeguradosCoberturasLF = $ModelLiquidacoesItensSeguradosCoberturasLF->save($params);
				
				$arCoberturas[$laudo['id_cobertura']]['vl_prejuizo_total'] += $params['vl_prejuizo'];

			    // Se possui cobertura Qualidade I, verifica se correção deve ser aplicada com base no laudo (estádio da cultura)
				if ($laudo['ds_chave_cobertura'] == 'COB_GRANIZO' && $fl_cobertura_qualidade_I) {

			        // Se correção da Qualidade I deve ser aplicada, realiza o cálculo
				    if ($this->hasEstadioCoberturaQualidade($dsSafra, $laudo['id_laudo_final_item_segurado'])) {
						
        			    $Row = $ModelLiquidacoesItensSeguradosCoberturas->find($dados['id_liquidacao'], $dados['id_item_segurado'], $idCoberturaQualidadeI)->current();
        			    
        			    if(!$Row) {
        			        $Row = $ModelLiquidacoesItensSeguradosCoberturas->save(array(
                             'id_liquidacao'     => $dados['id_liquidacao'],
                             'id_item_segurado'  => $dados['id_item_segurado'],
                             'id_cobertura'      => $idCoberturaQualidadeI,
        			         'fl_dependente'     => true 
                            ));
        			    }
        			    
    				    $params_dependente = array();
    				    $params_dependente['id_liquidacoes_itens_segurados_coberturas'] = $Row['id'];
    				    $params_dependente['id_liquidacoes_itens_segurados_coberturas_lf'] = $idLiquidacoesItensSeguradosCoberturasLF;
    				    $params_dependente['nr_prioridade'] = 1;

    				    // Busca o valor da correção para o percentual de dano do laudo
				        $vlPercenDanoDependente = $this->getPercentCorrecaoQualidade($laudo['percentual_dano']);
				        $params_dependente['vl_percent_perdas'] = $vlPercenDanoDependente;
			
				        // Se houver percentual colhido, ajusta o dano para a área remascente
    				    if ($laudo['vl_percent_colhido'] > 0) {
    				        $vlPercenDanoDependente = ((100 - $laudo['vl_percent_colhido']) * $vlPercenDanoDependente / 100);
    				    }
    				    
    				    // Insere o percentual de dano da qualidade no array de danos
        				foreach ($arDanosAnteriores as $danoAnterior) {
        				    $vlPercenDanoDependente = $vlPercenDanoDependente * ( 1 - ( $danoAnterior / 100 ) );
        				}
        				
        				$arDanosAnteriores[] = $params_dependente['vl_percent_perdas'];
        				
				        $params_dependente['vl_prejuizo'] = round( ( ( $ItemSegurado->vl_lmga * $vlPercenDanoDependente / 100) ), 2 );
				        $arCoberturas[$idCoberturaQualidadeI]['vl_prejuizo_total'] += $params_dependente['vl_prejuizo']; 
				        
				        $ModelLiquidacoesItensSeguradosCoberturasLFDependentes->save($params_dependente);
				    }
				}
				
				// Insere o percentual de dano do laudo atual no array de danos
				$arDanosAnteriores[] = $laudo['percentual_dano'];
				
			}
			
			$fl_aplicar_franquia = true;
			
		    foreach ($arCoberturas as $id_cobertura=>$cobertura) {
		        $vl_percent_franquia = $ModelPropostasCoberturas->getFranquiaByPropostaCobertura($dados['id_proposta'], $id_cobertura);
		        
		        if(!$vl_percent_franquia) {
		            $vl_percent_franquia = 0;
		        }
		        
		        if($fl_aplicar_franquia) {
    		        $vl_franquia = round( ($ItemSegurado->vl_lmga * $vl_percent_franquia / 100) ,2);
    		        
    		        if ($vl_franquia > $cobertura['vl_prejuizo_total']) {
    		            $vl_indenizacao = 0;
    		        } else {
    		            $vl_indenizacao = $cobertura['vl_prejuizo_total'] - $vl_franquia;
    		        }
    		        
    		        $fl_aplicar_franquia = false;
		        } else {
		            $vl_percent_franquia = 0;
		            $vl_franquia = 0;
		            $vl_indenizacao = $cobertura['vl_prejuizo_total'];
		        }
		        
                $ModelLiquidacoesItensSeguradosCoberturas->save(array(
                 'id_liquidacao'        => $dados['id_liquidacao'],
                 'id_item_segurado'     => $dados['id_item_segurado'],
                 'id_cobertura'         => $id_cobertura,
                 'vl_percent_franquia'  => $vl_percent_franquia,
                 'vl_franquia'          => $vl_franquia,
                 'vl_indenizacao'       => $vl_indenizacao,
                 'vl_prejuizo_total'	=> $cobertura['vl_prejuizo_total']
                ));
		    }
			
			$result['message'] = 'Liquidação realizada com sucesso.';
			//$result['message'] = $teste;
			
			$this->getAdapter()->commit();
		} catch (Exception $e) {
			$this->getAdapter()->rollBack();
			$result['status'] = false;
			$result['message'] = "Não foi possível realizar a liquidação. \n {$e->getMessage()} \n {$e->getTraceAsString()}";
			
		}
		
		return $result; 
	}
	
	public function getPercentProducaoRecolhida($dsSafra, $idLaudoFinalItemSegurado) {
	    
        $Select = $this->select()->setIntegrityCheck(false);
        $Select->from(array('lfis'=>$dsSafra.'.laudos_finais_cebola_cura_itens_segurados'), "lfis.vl_percent_producao_recolhida"); 
        $Select->where('lfis.id_laudo_final_item_segurado = ?', $idLaudoFinalItemSegurado);
        
        return $this->_db->fetchOne($Select);
	}
	
	public function hasEstadioCoberturaQualidade($dsSafra,$idLaudoFinalItemSegurado) {
	    /*
	     * Calcula o percentual de amostras do laudo de granizo do item segurado em que o estádio é 
	     * maior ou igual a 5, e retorna true se o percentual for de 70% ou maior, e false em caso contrário
	     */
	    
	    // Contador de amostras
	    $nr_amostras = 0;
	    
	    // Contador de amostras em que o estádio é 5 ou maior
	    $nr_amostras_estadio_5 = 0; 
	    
	    $Select = $this->select()->setIntegrityCheck(false);
	    $Select->from(array('lfacis'=>$dsSafra.'.laudos_finais_alho_cebola_granizo_itens_segurados_amostras'), 'lfacis.ds_estadio');
	    $Select->where('lfacis.id_laudo_final_item_segurado = ?', $idLaudoFinalItemSegurado);
	    
	    $Rows = $this->_db->fetchAll($Select);
	    foreach ($Rows as $row) {
	        $nr_amostras++;
	        if($row['ds_estadio'] >= 5) {
	            $nr_amostras_estadio_5++;
	        }
	    }
	    
	    if ($nr_amostras > 0 && $nr_amostras_estadio_5 > 0) {
	        if (($nr_amostras_estadio_5 * 100 / $nr_amostras) >= 70) {
	            return true;
	        } else {
	            return false;
	        }
	    } else {
	        return false;
	    }
	}
	
	public function getPercentCorrecaoQualidade($vlPercentPerdas) {
	    /*
	     * Busca o percentual de correção adequado na tabela sinistro.auxiliar_liquidacao_cebola_qualidade_i 
	     * para o percentual de perda passado
	     */
	    $Select = $this->select()->setIntegrityCheck(false);
	    $Select->from(array('aux'=>'sinistro.auxiliar_liquidacao_cebola_qualidade_i'), 'aux.vl_percent_correcao');
	    $Select->where('? between aux.vl_percent_perdas_min and aux.vl_percent_perdas_max', $vlPercentPerdas);
	    
	    return $this->_db->fetchOne($Select);
	}
}
