Skip to content
Snippets Groups Projects
EditPrescriptionsAction.java 11.9 KiB
Newer Older
  • Learn to ignore specific revisions
  • HMoss's avatar
    HMoss committed
    package edu.ncsu.csc.itrust.action;
    
    import java.text.SimpleDateFormat;
    //import java.util.Date;
    import java.util.ArrayList;
    import java.util.List;
    import edu.ncsu.csc.itrust.EmailUtil;
    import edu.ncsu.csc.itrust.action.base.EditOfficeVisitBaseAction;
    import edu.ncsu.csc.itrust.beans.*;
    import edu.ncsu.csc.itrust.beans.forms.EditPrescriptionsForm;
    import edu.ncsu.csc.itrust.dao.DAOFactory;
    import edu.ncsu.csc.itrust.dao.mysql.*;
    import edu.ncsu.csc.itrust.enums.TransactionType;
    import edu.ncsu.csc.itrust.exception.DBException;
    import edu.ncsu.csc.itrust.exception.PrescriptionFieldException;
    import edu.ncsu.csc.itrust.exception.PrescriptionWarningException;
    import edu.ncsu.csc.itrust.exception.FormValidationException;
    import edu.ncsu.csc.itrust.exception.ITrustException;
    import edu.ncsu.csc.itrust.validate.EditPrescriptionsValidator;
    
    
    /**
     * Edits a patient's prescription information.  Used by hcp-uap/editPrescription.jsp
     */
    public class EditPrescriptionsAction extends EditOfficeVisitBaseAction {
    
    	private PrescriptionsDAO psDAO;
    	private NDCodesDAO medDAO;
    	private DrugInteractionDAO interactionsDAO;
    	private PrescriptionReportDAO rptDAO;
    	private AllergyDAO allergyDAO;
    	private PatientDAO patientDAO;
    	private EmailUtil emailUtil;
    	private PersonnelDAO personnelDAO;
    	private PrescriptionOverrideDAO prescriptionOverrideDAO;
    
    	private EventLoggingAction loggingAction;
    	/**
    	 * Creates a new action by initializing the office visit
    	 * database access object.
    	 * 
    	 * @param factory
    	 * @throws ITrustException
    	 */
    	public EditPrescriptionsAction(DAOFactory factory, long hcpid, 
    								   String pidString, String ovIDString) 
    		throws ITrustException {
    		super(factory, hcpid, pidString, ovIDString);
    
    		init(factory);
    	}
    	
    	/**
    	 * A prescription action that is part of an office visit that is not yet 
    	 * saved.  All attempts to modify this action will throw exceptions.  Once 
    	 * the office visit is saved, obtain a new EditPrescriptionsAction using 
    	 * the four-argument constructor.  (This is done automatically by the 
    	 * EditOfficeVisitAction class.)
    	 * @param factory
    	 * @param hcpid
    	 * @param pidString
    	 * @throws ITrustException
    	 */
    	public EditPrescriptionsAction(DAOFactory factory, long hcpid, 
    			   String pidString) 
    		throws ITrustException {
    		super(factory, hcpid, pidString);
    		init(factory);
    		
    	}
    	
    	private void init(DAOFactory factory){		
    		psDAO = factory.getPrescriptionsDAO();
    		medDAO = factory.getNDCodesDAO();
    		interactionsDAO = factory.getDrugInteractionDAO();
    		allergyDAO = factory.getAllergyDAO();
    		rptDAO = factory.getPrescriptionReportDAO();
    		patientDAO = factory.getPatientDAO();
    		emailUtil = new EmailUtil(factory);
    		personnelDAO = new PersonnelDAO(factory);
    		prescriptionOverrideDAO = new PrescriptionOverrideDAO(factory);
    		loggingAction = new EventLoggingAction(factory);
    	}
    	/**
    	 * Checks the prescription bean for interactions, allergies, and legal 
    	 * values.
    	 * @param pres The prescription bean.
    	 * @throws ITrustException
    	 */
    	private void checkForAllergiesAndInteractions(PrescriptionBean pres) throws ITrustException {
    		List<String> warnings = checkInteraction(pres);
    		warnings.addAll(checkAllergy(pres));
    		if (!warnings.isEmpty()) {
    			PatientBean patient = patientDAO.getPatient(getPid());
    			PersonnelBean hcp = personnelDAO.getPersonnel(getHcpid());
    			loggingAction.logEvent(TransactionType.OVERRIDE_INTERACTION_WARNING, hcp.getMID(), patient.getMID(), pres.getMedication().getNDCode()+
    					" Override: "+pres.getReasons().toString());
    			if(validOverride(pres)){
    				emailUtil.sendEmail(makeEmail(pres, warnings));
    			}else{
    				throw new PrescriptionWarningException(warnings);
    			}
    		}
    		
    		if ("".equals(pres.getInstructions())) {
    			throw new PrescriptionFieldException("Instructions are required.");
    		}
    	}
    	
    	/**
    	 * Indicates if the prescription bean has a valid allergy/interaction 
    	 * override.
    	 */
    	private boolean validOverride(PrescriptionBean pres) {
    		return pres.getReasons() != null && pres.getReasons().size()>0;
    	}
    	
    	/**
    	 * Returns a string suitable for a user warning message that a 
    	 * drug-interaction was detected.
    	 */
    	private String formatInteractionWarning(PrescriptionBean newPrescription, 
    									  PrescriptionBean oldPrescription, 
    									  DrugInteractionBean bean) 
    	{
    		String startDate = new SimpleDateFormat("MM/dd/yyyy").format(oldPrescription.getStartDate());
    		String endDate = new SimpleDateFormat("MM/dd/yyyy").format(oldPrescription.getEndDate());
    		return String.format("Currently Prescribed: %s. Start Date: %s, End Date: %s. Interactions: %s - %s. Description: %s", 
    							 oldPrescription.getMedication().getDescription(),
    							 startDate, endDate,
    							 oldPrescription.getMedication().getDescription(),
    							 newPrescription.getMedication().getDescription(),
    							 bean.getDescription()
    							 );
    	}
    	
    	/**
    	 * Returns a string suitable for a user warning message that a 
    	 * drug-allergy warning was detected.
    	 */
    	private String formatAllergyWarning(AllergyBean bean) throws DBException {
    		return "Allergy: " + bean.getDescription() + ". First Found: " + 
    			new SimpleDateFormat("MM/dd/yyyy").format(bean.getFirstFound());
    	}
        
    	/**
    	 * Checks to see if the given prescription has an interaction with any 
    	 * other previously prescribed prescriptions.
    	 * @param newPrescription
    	 * @return A list of interaction warning messages.  The list is empty if no 
    	 * 	interactions were detected.
    	 * @throws ITrustException
    	 */
    	private List<String> checkInteraction(PrescriptionBean newPrescription) throws ITrustException {
    		ArrayList<String> warnings = new ArrayList<String>();
    		try {
    
    			SimpleDateFormat needed = new SimpleDateFormat("yyyy/MM/dd");
    			
    			String startdate = needed.format(newPrescription.getStartDate());
    			String enddate = needed.format(newPrescription.getEndDate());
    			String drug = newPrescription.getMedication().getNDCode();
    			
    			startdate = startdate.replaceAll("/", "-");
    			enddate = enddate.replaceAll("/", "-");
    			List<PrescriptionReportBean> prBeanList = rptDAO.byDate(getPid(), startdate, enddate);
    			List<DrugInteractionBean> dBeanList = interactionsDAO.getInteractions(drug);
    		
    			for (PrescriptionReportBean prBean : prBeanList) {
    				String oldDrug = prBean.getPrescription().getMedication().getNDCode();
    				PrescriptionBean oldPrescription = prBean.getPrescription();
    				for (DrugInteractionBean dBean : dBeanList) {
    					String intDrug1 = dBean.getFirstDrug();
    					String intDrug2 = dBean.getSecondDrug();
    					
    					if (oldDrug.equals(intDrug1) && drug.equals(intDrug2)) {
    						warnings.add(formatInteractionWarning(newPrescription, oldPrescription, dBean));
    					} else if (oldDrug.equals(intDrug2) && drug.equals(intDrug1)) {
    						warnings.add(formatInteractionWarning(newPrescription, oldPrescription, dBean));
    					}
    				}
    			}
    		} catch (DBException e) {
    			
    			throw new ITrustException(e.getMessage());
    		}
    		return warnings;
    	}
    	
    	/**
    	 * Checks to see if the patient is allergic to the given prescription.
    	 * @return A list of allergy warnings.  The list is empty if no allergies 
    	 * were detected.
    	 * @throws ITrustException
    	 * @throws PrescriptionWarningException
    	 */
    	private List<String> checkAllergy(PrescriptionBean pres) throws ITrustException, PrescriptionWarningException {
    		ArrayList<String> warnings = new ArrayList<String>();
    		try {
    			List<AllergyBean> allergyList = allergyDAO.getAllergies(getPid());
    			MedicationBean medBean = pres.getMedication();
    			if (medBean != null) {
    				String newDrug = medBean.getNDCode();
    				for (AllergyBean allergyBean : allergyList) {
    					//Allergy: Aspirin. First Found: 12/20/2008. 
    					if (newDrug.equals(allergyBean.getNDCode())) {
    						warnings.add(formatAllergyWarning(allergyBean));
    					}
    				}
    			}
    		} catch (DBException e){
    			
    			throw new ITrustException(e.getMessage());
    		}
    		return warnings;
    	}
    	
    
    	/**
    	 * Edits an existing prescription in the database.  If the office visit is 
    	 * unsaved, this will throw an exception.
    	 * 
    	 * @param pres The prescription bean that has been changed.
    	 * @throws ITrustException 
    	 */
    	public void editPrescription(PrescriptionBean pres) throws ITrustException {
    		verifySaved();
    		checkForAllergiesAndInteractions(pres);
    		psDAO.edit(pres);
    	}
    	/**
    	 * @return A list of all prescriptions for this office visit.  (If the 
    	 * 	office visit is unsaved, this returns an empty list.)
    	 * @throws DBException
    	 */
    	public List<PrescriptionBean> getPrescriptions() throws DBException {
    		if (isUnsaved()) {
    			return new ArrayList<PrescriptionBean>();
    		} else {
    			return psDAO.getList(getOvID());
    		}
    	}
    	/**
    	 * Add a prescription to this office visit.  If the office visit is 
    	 * unsaved, this will throw an exception.
    	 * @param pres
    	 * @throws ITrustException
    	 */
    	public void addPrescription(PrescriptionBean pres) throws ITrustException {
    		verifySaved();
    		checkForAllergiesAndInteractions(pres);
    		long medID = psDAO.add(pres);
    		for(OverrideReasonBean reason : pres.getReasons()){
    			reason.setPresID(medID);
    			prescriptionOverrideDAO.add(reason);
    		}
    	}
    	/**
    	 * Delete a prescription from this office visit.  If the office visit is 
    	 * unsaved, this will throw an exception.
    	 * @param pres
    	 * @throws DBException
    	 * @throws ITrustException
    	 */
    	public void deletePrescription(PrescriptionBean pres) throws DBException, ITrustException {
    		verifySaved();
    		psDAO.remove(pres.getId());
    		prescriptionOverrideDAO.remove(pres.getId());
    	}
    	/**
    	 * Returns a list of known medications.  This can be called even if the 
    	 * office visit is unsaved. 
    	 * @throws DBException
    	 * @throws ITrustException
    	 */
    	public List<MedicationBean> getMedications() throws DBException, ITrustException {
    		return medDAO.getAllNDCodes();
    	}
    	/**
    	 * Validates a prescription form, converts it into a bean, and returns that bean.
    	 * @param form  The form to convert.
    	 * @param defaultInstructions  The default value given in the instructions 
    	 * 	field.  If the field equals this value, the validation will fail.
    	 * @return
    	 * @throws FormValidationException
    	 * @throws DBException
    	 */
    	public PrescriptionBean formToBean(EditPrescriptionsForm form, String defaultInstructions) throws FormValidationException, DBException {
    		EditPrescriptionsValidator validator = new EditPrescriptionsValidator(defaultInstructions);
    		validator.validate(form);
    		PrescriptionBean bean = new PrescriptionBean();
    		bean.setVisitID(getOvID());
    		MedicationBean med = medDAO.getNDCode(form.getMedID());
    		bean.setMedication(med);
    		bean.setDosage(Integer.valueOf(form.getDosage()));
    		bean.setStartDateStr(form.getStartDate());
    		bean.setEndDateStr(form.getEndDate());
    		bean.setInstructions(form.getInstructions());
    		ArrayList<OverrideReasonBean> reasons = new ArrayList<OverrideReasonBean>();
    		for(String reason : form.getOverrideCodes()){
    			OverrideReasonBean override = new OverrideReasonBean();
    			override.setORCode(reason);
    			reasons.add(override);
    		}
    		bean.setReasons(reasons);
    		bean.setOverrideReasonOther(form.getOverrideOther());
    		return bean;
    	}
    	
    	/**
    	 * Creates a fake e-mail to notify the user that their records have been altered.
    	 * 
    	 * @return the e-mail to be sent
    	 * @throws DBException
    	 */
    	private Email makeEmail(PrescriptionBean pres, List<String> warnings) throws DBException{
    
    		Email email = new Email();
    		PatientBean patient = patientDAO.getPatient(getPid());
    		PersonnelBean hcp = personnelDAO.getPersonnel(getHcpid());
    
    		
    		List<String> toAddrs = new ArrayList<String>();
    		toAddrs.add(patient.getEmail());
    		
    		StringBuffer buf = new StringBuffer();
    		for(String warning : warnings){
    			buf.append(warning);
    			buf.append("\n");
    		}
    		String message = "Health care professional " + hcp.getFullName() + " has prescribed " +
        			pres.getMedication().getDescription() + ". However, the following warning(s) were found:" +
    				buf.toString();
    		
    		email.setFrom("no-reply@itrust.com");
        	email.setToList(toAddrs); // patient and personal representative
        	email.setSubject(String.format("Prescription warning"));
        	email.setBody(message);
    		return email;
    	}
    }