class ConfirmarPrescricaoMedicaRN extends BaseBusiness {

	@SuppressWarnings({"PMD.ExcessiveMethodLength", "PMD.NPathComplexity"})
	public ConfirmacaoPrescricaoVO confirmarPrescricaoMedica(MpmPrescricaoMedica prescricao, String nomeMicrocomputador, final Date dataFimVinculoServidor)
			throws BaseException {
		
		Boolean prescricaoAmbulatorial = getAghuFacade().obterAtendimento(prescricao.getId().getAtdSeq(),null,
				DominioOrigemAtendimento.getOrigensDePrescricaoAmbulatorial()) != null;
		
		MpmPrescricaoMedica prescricaoOld = new MpmPrescricaoMedica();
		
		prescricaoOld.setSituacao(prescricao.getSituacao());
		prescricaoOld.setServidorValida(prescricao.getServidorValida());
		
		if(prescricao.getDthrInicioMvtoPendente() == null) {
			prescricaoOld.setDthrInicioMvtoPendente(prescricao.getDthrMovimento());
		}else { 	
			prescricaoOld.setDthrInicioMvtoPendente(prescricao.getDthrInicioMvtoPendente());
		}
		
		if (prescricao.getDthrMovimento() == null) {
			throw new ApplicationBusinessException(
					ConfirmarPrescricaoMedicaExceptionCode.DTHR_MOVIMENTO_NULO);
		}

		if (prescricao.getSituacao() != DominioSituacaoPrescricao.U) {
			throw new ApplicationBusinessException(
					ConfirmarPrescricaoMedicaExceptionCode.PRESCRICAO_LIVRE);
		}

		Date dataTrabalho = null;

		if (prescricao.getDthrInicioMvtoPendente() != null) {
			dataTrabalho = prescricao.getDthrInicioMvtoPendente();
		} else {
			dataTrabalho = prescricao.getDthrMovimento();
		}

		ConfirmacaoPrescricaoVO confirmacaoPrescricaoVO  = new ConfirmacaoPrescricaoVO();
		confirmacaoPrescricaoVO.setDataMovimento(dataTrabalho);
		confirmacaoPrescricaoVO.setServidorValido(prescricao.getServidorValida());
		
		//Incluida regra para nao testar previsao de alta para unidades com caracteristica Control prev alta (Incidente - AGHU #51238)
		boolean possuiCaracteristicaPrevAlta = aghuFacade.possuiCaracteristicaPorUnidadeEConstante(prescricao.getAtendimento().getUnidadeFuncional().getSeq(), 
				   ConstanteAghCaractUnidFuncionais.CONTROLA_PREVISAO_ALTA);

		
		Date dataPrevisaoAlta = null;
		if (prescricao.getAtendimento().getInternacao() != null) {
			dataPrevisaoAlta = prescricao.getAtendimento().getInternacao()
					.getDtPrevAlta();

			// Verifica previsão de alta
			if (!possuiCaracteristicaPrevAlta && dataPrevisaoAlta != null
					&& dataPrevisaoAlta.before(DateUtil.truncaData(new Date()))) {
				throw new ApplicationBusinessException(
						ConfirmarPrescricaoMedicaExceptionCode.PREVISAO_ALTA_ANTERIOR_DATA_ATUAL);
			}
		}

		validarQuantidadeItensPrescricao(prescricao.getId(), prescricao.getDthrFim(), false);
		
		if(!prescricaoAmbulatorial){
			// verifica diagnóstico do atendimento
			Long numDiagnosticosAtendimento = this.getCidAtendimentoDAO()
					.contarDiagnosticosAtendimento(prescricao.getAtendimento());
			if (numDiagnosticosAtendimento == 0) {
				throw new ApplicationBusinessException(
						ConfirmarPrescricaoMedicaExceptionCode.DIAGNOSTICOS_ATENDIMENTO);
	
			}
			
			// verifica quantidade de dietas.
			List<MpmPrescricaoDieta> dietas = this.getPrescricaoDietaDAO().buscaDietaPorPrescricaoMedica(prescricao.getId(),prescricao.getDthrFim(), false);

			boolean possuiCaracteristica = aghuFacade.possuiCaracteristicaPorUnidadeEConstante(prescricao.getAtendimento().getUnidadeFuncional().getSeq(), 
																							   ConstanteAghCaractUnidFuncionais.DIETA_OPCIONAL_ATEND_URGENCIA);
			
			if (prescricao.getAtendimento().getOrigem() == DominioOrigemAtendimento.U && possuiCaracteristica) {

				if ((dietas.size() > 1) && !permissionService.usuarioTemPermissao(obterLoginUsuarioLogado(), "altaPacientes_Enfermeiro_Obstetra", "pesquisar")) {
					throw new ApplicationBusinessException(
							ConfirmarPrescricaoMedicaExceptionCode.QUANTIDADE_DIETAS_OPCIONAL);
				}

			} else {
				if ((dietas.size() != 1) && !permissionService.usuarioTemPermissao(obterLoginUsuarioLogado(), "altaPacientes_Enfermeiro_Obstetra", "pesquisar") ) {
					throw new ApplicationBusinessException(
							ConfirmarPrescricaoMedicaExceptionCode.QUANTIDADE_DIETAS);
				}
			}
		}
		

		LOG.info("Chamando validação para bomba de infusão da prescrição: "
				+ prescricao.getId().getSeq());
		this.validarBombaDeInfusao(prescricao);
		
		LOG.info(
				"Calculando quantidade medicamentos para 24 horas para a prescrição: "
						+ prescricao.getId().getSeq());
		this.calcularQuantidade24Horas(prescricao,dataTrabalho);
		
		LOG.info(
				"Chamando confirmação itens da prescrição: "
						+ prescricao.getId().getSeq());
		this.confirmarItensPrescricao(prescricao, dataTrabalho, nomeMicrocomputador, confirmacaoPrescricaoVO);
		
		LOG.info(
				"Chamando atualização do atendimento paciente Cpa da prescrição: "
						+ prescricao.getId().getSeq());
		this.atualizarAtendimentoPacienteCpa(prescricao, nomeMicrocomputador, dataFimVinculoServidor);		
		

		LOG.info("Retirando de uso a prescrição: "
						+ prescricao.getId().getSeq());

		//Guarda atributos da prescrição que serão alterados quando ela for tirada de uso
		Date dthrMovimentoBackup = prescricao.getDthrMovimento();
		Date dthrInicioMvtoPendenteBackup = prescricao.getDthrInicioMvtoPendente();
		DominioSituacaoPrescricao situacaoBackup = prescricao.getSituacao();
		RapServidores servidorValidacaoBackup = prescricao.getServidorValida();
		String machineBackup = prescricao.getMachine();
		this.tirarPrescricaoDeUso(prescricao, nomeMicrocomputador);
		
			try{
				getPrescricaoMedicaRN().atualizarFaturamento( prescricao, prescricaoOld, DominioOperacaoBanco.UPD, nomeMicrocomputador, new Date());//DominioOperacaoBanco.INS
			}catch(ApplicationBusinessException e){
				//Retorna os valores antigos
				prescricao.setDthrMovimento(dthrMovimentoBackup);
				prescricao.setDthrInicioMvtoPendente(dthrInicioMvtoPendenteBackup);
				prescricao.setSituacao(situacaoBackup);
				prescricao.setServidorValida(servidorValidacaoBackup);
				prescricao.setMachine(machineBackup);
				throw e;
			}

		LOG.info(
				"Chamando confirmação da justificativa da prescrição: "
						+ prescricao.getId().getSeq());
		this.confirmarJustificativa(prescricao, dataTrabalho);

		LOG.info(
				"Chamando confirmação do diagnóstico da prescrição: "
						+ prescricao.getId().getSeq());
		this.confirmarDiagnostico(prescricao);
		
		//#43252
		confirmarPrescricaoNpt(prescricao, nomeMicrocomputador);
		LOG.info("Chamando confirmação do prescricao NPT da prescrição: " + prescricao.getId().getSeq());
		return confirmacaoPrescricaoVO;
	}

}