femr.business.services.system.MedicationService.java Source code

Java tutorial

Introduction

Here is the source code for femr.business.services.system.MedicationService.java

Source

/*
 fEMR - fast Electronic Medical Records
 Copyright (C) 2014  Team fEMR
    
 fEMR is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.
    
 fEMR is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
    
 You should have received a copy of the GNU General Public License
 along with fEMR.  If not, see <http://www.gnu.org/licenses/>. If
 you have any questions, contact <info@teamfemr.org>.
*/
package femr.business.services.system;

import com.avaje.ebean.*;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.inject.Inject;
import com.google.inject.name.Named;
import femr.business.helpers.QueryProvider;
import femr.business.services.core.IMedicationService;
import femr.common.IItemModelMapper;
import femr.common.dtos.ServiceResponse;
import femr.common.models.MedicationAdministrationItem;
import femr.common.models.MedicationItem;
import femr.common.models.PrescriptionItem;
import femr.data.IDataModelMapper;
import femr.data.daos.IRepository;
import femr.data.daos.core.*;
import femr.data.models.core.*;
import femr.data.models.mysql.*;
import femr.data.models.mysql.concepts.ConceptMedication;
import femr.data.models.mysql.concepts.ConceptMedicationForm;
import femr.data.models.mysql.concepts.ConceptMedicationUnit;
import femr.data.models.mysql.concepts.ConceptPrescriptionAdministration;
import femr.util.calculations.dateUtils;
import femr.util.stringhelpers.StringUtils;
import org.joda.time.DateTime;
import play.libs.Json;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class MedicationService implements IMedicationService {

    private final IMedicationRepository medicationRepository;
    private final IRepository<IMedicationGeneric> medicationGenericRepository;
    private final IRepository<IConceptMedicationForm> conceptMedicationFormRepository;
    private final IRepository<IMedicationInventory> medicationInventoryRepository;
    private final IRepository<IConceptMedicationUnit> conceptMedicationUnitRepository;
    private final IRepository<IConceptPrescriptionAdministration> conceptPrescriptionAdministrationRepository;
    private final IRepository<IPatientPrescription> patientPrescriptionRepository;
    private final IRepository<IPatientPrescriptionReplacement> patientPrescriptionReplacementRepository;
    private final IRepository<IPatientPrescriptionReplacementReason> patientPrescriptionReplacementReasonRepository;
    private final IDataModelMapper dataModelMapper;
    private final IItemModelMapper itemModelMapper;

    @Inject
    public MedicationService(IMedicationRepository medicationRepository,
            IRepository<IMedicationGeneric> medicationGenericRepository,
            IRepository<IConceptPrescriptionAdministration> conceptPrescriptionAdministrationRepository,
            IRepository<IConceptMedicationForm> conceptMedicationFormRepository,
            IRepository<IMedicationInventory> medicationInventoryRepository,
            IRepository<IConceptMedicationUnit> conceptMedicationUnitRepository,
            IRepository<IPatientPrescription> patientPrescriptionRepository,
            IRepository<IPatientPrescriptionReplacement> patientPrescriptionReplacementRepository,
            IRepository<IPatientPrescriptionReplacementReason> patientPrescriptionReplacementReasonRepository,
            IDataModelMapper dataModelMapper, @Named("identified") IItemModelMapper itemModelMapper) {

        this.medicationRepository = medicationRepository;
        this.medicationGenericRepository = medicationGenericRepository;
        this.conceptMedicationFormRepository = conceptMedicationFormRepository;
        this.medicationInventoryRepository = medicationInventoryRepository;
        this.conceptMedicationUnitRepository = conceptMedicationUnitRepository;
        this.conceptPrescriptionAdministrationRepository = conceptPrescriptionAdministrationRepository;
        this.patientPrescriptionRepository = patientPrescriptionRepository;
        this.patientPrescriptionReplacementRepository = patientPrescriptionReplacementRepository;
        this.patientPrescriptionReplacementReasonRepository = patientPrescriptionReplacementReasonRepository;
        this.dataModelMapper = dataModelMapper;
        this.itemModelMapper = itemModelMapper;
    }

    /**
     * {@inheritDoc}
     */
    public ServiceResponse<MedicationItem> createMedication(String name, String form,
            List<MedicationItem.ActiveIngredient> activeIngredients) {

        ServiceResponse<MedicationItem> response = new ServiceResponse<>();

        try {

            //set each generic drug
            List<IMedicationGenericStrength> medicationGenericStrengths = new ArrayList<>();

            if (activeIngredients != null) {

                for (MedicationItem.ActiveIngredient miac : activeIngredients) {
                    //get the measurement unit ID (they are concepts)
                    IConceptMedicationUnit conceptMedicationUnit = medicationRepository
                            .retrieveMedicationUnitByUnitName(miac.getUnit());
                    IMedicationGeneric medicationGeneric = medicationRepository
                            .retrieveMedicationGenericByName(miac.getName());

                    if (medicationGeneric == null) {
                        //it's a new active drug name, were going to cascade(save) the bean
                        medicationGeneric = dataModelMapper.createMedicationActiveDrugName(miac.getName());
                    }
                    if (conceptMedicationUnit != null) {
                        IMedicationGenericStrength medicationGenericStrength = dataModelMapper
                                .createMedicationGenericStrength(miac.getValue(), false,
                                        conceptMedicationUnit.getId(), medicationGeneric);
                        medicationGenericStrengths.add(medicationGenericStrength);
                    }

                }
            }

            IConceptMedicationForm conceptMedicationForm = medicationRepository
                    .retrieveConceptMedicationFormByFormName(form);
            if (conceptMedicationForm == null) {
                conceptMedicationForm = dataModelMapper.createConceptMedicationForm(form);
            }

            IMedication matchingMedication = null;
            List<? extends IMedication> medications;
            medications = medicationRepository.retrieveAllPreInventoryMedications();

            // Attempt to find a matching medication
            for (IMedication medication : medications) {
                // Check if the medications name match
                if (!medication.getName().equalsIgnoreCase(name))
                    continue;

                // Check if the medications form match
                if (medication.getConceptMedicationForm().getId() != conceptMedicationForm.getId())
                    continue;

                // Check if the medication ingredients match
                boolean allDrugsMatch = true;
                for (IMedicationGenericStrength newMedicationGenericDrug : medicationGenericStrengths) {
                    boolean drugMatch = false;
                    for (IMedicationGenericStrength drug : medication.getMedicationGenericStrengths()) {
                        if (newMedicationGenericDrug.getMedicationGeneric().getId() == drug.getMedicationGeneric()
                                .getId() //generic name match
                                && newMedicationGenericDrug.getConceptMedicationUnit().getId() == drug
                                        .getConceptMedicationUnit().getId() //unit match
                                && newMedicationGenericDrug.getValue().equals(drug.getValue())) { //value match
                            drugMatch = true;
                        }
                        if (!drugMatch)
                            allDrugsMatch = false;
                    }

                    // No match so break early.
                    if (!allDrugsMatch)
                        break;
                }
                if (!allDrugsMatch)
                    continue;

                // Everything matches so set matchingMedication and break out of loop
                matchingMedication = medication;
                break;
            }

            // There exist a matching medication in the database, so update that one rather then create new one
            if (matchingMedication != null) {
                medicationRepository.deleteMedication(matchingMedication.getId(), false);
                response.setResponseObject(
                        itemModelMapper.createMedicationItem(matchingMedication, null, null, null));

            } else {
                IMedication medication = medicationRepository.createNewMedication(name, medicationGenericStrengths,
                        conceptMedicationForm);
                //creates the medication item - quantities are null because the medication was just created.
                MedicationItem newMedicationItem = itemModelMapper.createMedicationItem(medication, null, null,
                        null);

                response.setResponseObject(newMedicationItem);
            }

        } catch (Exception ex) {

            response.addError("", "error creating medication");
        }

        return response;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ServiceResponse<List<PrescriptionItem>> replacePrescriptions(Map<Integer, Integer> prescriptionPairs) {

        ServiceResponse<List<PrescriptionItem>> response = new ServiceResponse<>();
        List<PrescriptionItem> prescriptionItems = new ArrayList<>();
        List<IPatientPrescriptionReplacement> patientPrescriptionReplacements = new ArrayList<>();

        //get the reason for replacing
        ExpressionList<PatientPrescriptionReplacementReason> replacementReasonExpressionList = QueryProvider
                .getPatientPrescriptionReasonQuery().where().eq("name", "pharmacist replacement");
        IPatientPrescriptionReplacementReason patientPrescriptionReplacementReason = patientPrescriptionReplacementReasonRepository
                .findOne(replacementReasonExpressionList);

        //iterate over each prescription and its replacement
        prescriptionPairs.forEach((newId, oldId) -> {

            ExpressionList<PatientPrescription> newPrescriptionExpressionList = QueryProvider
                    .getPatientPrescriptionQuery().where().eq("id", newId);

            ExpressionList<PatientPrescription> replacedPrescriptionExpressionList = QueryProvider
                    .getPatientPrescriptionQuery().where().eq("id", oldId);

            try {
                IPatientPrescription newPrescription = patientPrescriptionRepository
                        .findOne(newPrescriptionExpressionList);
                IPatientPrescription replacedPrescription = patientPrescriptionRepository
                        .findOne(replacedPrescriptionExpressionList);

                if (newPrescription == null) {

                    response.addError("not found", "new prescription with id: " + newId + " not found.");
                } else if (replacedPrescription == null) {

                    response.addError("not found", "old prescription with id: " + oldId + " not found.");
                } else {
                    patientPrescriptionReplacements
                            .add(dataModelMapper.createPatientPrescriptionReplacement(replacedPrescription.getId(),
                                    newPrescription.getId(), patientPrescriptionReplacementReason.getId()));

                }

            } catch (Exception ex) {

                response.addError("", ex.getMessage());
            }
        });

        try {

            List<? extends IPatientPrescriptionReplacement> replacements = patientPrescriptionReplacementRepository
                    .createAll(patientPrescriptionReplacements);
            for (IPatientPrescriptionReplacement prescriptionReplacement : replacements) {

                prescriptionItems.add(itemModelMapper.createPrescriptionItem(
                        prescriptionReplacement.getReplacementPrescription().getId(),
                        prescriptionReplacement.getReplacementPrescription().getMedication().getName(), null,
                        prescriptionReplacement.getReplacementPrescription().getPhysician().getFirstName(),
                        prescriptionReplacement.getReplacementPrescription().getPhysician().getLastName(),
                        prescriptionReplacement.getReplacementPrescription().getConceptPrescriptionAdministration(),
                        prescriptionReplacement.getReplacementPrescription().getAmount(),
                        prescriptionReplacement.getReplacementPrescription().getMedication(), null,
                        prescriptionReplacement.getReplacementPrescription().isCounseled()));
            }
        } catch (Exception ex) {

            response.addError("", ex.getMessage());
        }

        response.setResponseObject(prescriptionItems);

        return response;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ServiceResponse<List<PrescriptionItem>> dispensePrescriptions(
            Map<Integer, Boolean> prescriptionsToDispense) {

        ServiceResponse<List<PrescriptionItem>> response = new ServiceResponse<>();

        List<PrescriptionItem> prescriptionItems = new ArrayList<>();

        DateTime dateTime = dateUtils.getCurrentDateTime();

        prescriptionsToDispense.forEach((prescriptionId, isCounseled) -> {

            ExpressionList<PatientPrescription> prescriptionExpressionList = QueryProvider
                    .getPatientPrescriptionQuery().where().eq("id", prescriptionId);

            try {

                IPatientPrescription prescription = patientPrescriptionRepository
                        .findOne(prescriptionExpressionList);
                prescription.setDateDispensed(dateTime);
                prescription.setCounseled(isCounseled);
                prescription = patientPrescriptionRepository.update(prescription);

                prescriptionItems.add(itemModelMapper.createPrescriptionItem(prescription.getId(),
                        prescription.getMedication().getName(), null, prescription.getPhysician().getFirstName(),
                        prescription.getPhysician().getLastName(),
                        prescription.getConceptPrescriptionAdministration(), prescription.getAmount(),
                        prescription.getMedication(), null, prescription.isCounseled()));

            } catch (Exception ex) {

                response.addError("", ex.getMessage());
            }
        });

        response.setResponseObject(prescriptionItems);
        return response;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ServiceResponse<PrescriptionItem> createPrescription(int medicationId, Integer administrationId,
            int encounterId, int userId, int amount, String specialInstructions) {

        ServiceResponse<PrescriptionItem> response = new ServiceResponse<>();
        if (administrationId != null && administrationId <= 0)
            administrationId = null;

        try {
            IPatientPrescription patientPrescription = dataModelMapper.createPatientPrescription(amount,
                    medicationId, administrationId, userId, encounterId, null, false);

            patientPrescription = patientPrescriptionRepository.create(patientPrescription);

            PrescriptionItem prescriptionItem = itemModelMapper.createPrescriptionItem(patientPrescription.getId(),
                    patientPrescription.getMedication().getName(), null,
                    patientPrescription.getPhysician().getFirstName(),
                    patientPrescription.getPhysician().getLastName(),
                    patientPrescription.getConceptPrescriptionAdministration(), patientPrescription.getAmount(),
                    patientPrescription.getMedication(), null, patientPrescription.isCounseled());
            response.setResponseObject(prescriptionItem);
        } catch (Exception ex) {

            response.addError("", "there was an issue creating the prescription");
        }

        return response;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ServiceResponse<PrescriptionItem> createPrescriptionWithNewMedication(String medicationName,
            Integer administrationId, int encounterId, int userId, int amount, String specialInstructions) {

        ServiceResponse<PrescriptionItem> response = new ServiceResponse<>();

        if (StringUtils.isNullOrWhiteSpace(medicationName)) {

            response.addError("", "medicationName can't be null or empty");
            return response;
        }

        if (administrationId != null && administrationId <= 0)
            administrationId = null;

        try {

            IMedication medication = dataModelMapper.createMedication(medicationName);
            medication = medicationRepository.createNewMedication(medicationName, null, null);

            IPatientPrescription patientPrescription = dataModelMapper.createPatientPrescription(amount,
                    medication.getId(), administrationId, userId, encounterId, null, false);

            patientPrescription = patientPrescriptionRepository.create(patientPrescription);

            PrescriptionItem prescriptionItem = itemModelMapper.createPrescriptionItem(patientPrescription.getId(),
                    patientPrescription.getMedication().getName(), null,
                    patientPrescription.getPhysician().getFirstName(),
                    patientPrescription.getPhysician().getLastName(),
                    patientPrescription.getConceptPrescriptionAdministration(), patientPrescription.getAmount(),
                    patientPrescription.getMedication(), null, patientPrescription.isCounseled());
            response.setResponseObject(prescriptionItem);

        } catch (Exception ex) {

            response.addError("", ex.getMessage());
        }

        return response;
    }

    public ServiceResponse<MedicationItem> deleteMedication(int medicationID) {
        ServiceResponse<MedicationItem> response = new ServiceResponse<>();

        // Get the medication Item by it's ID
        IMedication medication;
        ExpressionList<Medication> medicationQuery = QueryProvider.getMedicationQuery().where().eq("id",
                medicationID);

        try {
            // Find one medication (should only be 1 with the ID) from the database
            medication = medicationRepository.deleteMedication(medicationID, true);
        } catch (Exception ex) {
            response.addError("exception", ex.getMessage());
            return response;
        }

        return response;
    }

    /**
     * {@inheritDoc}
     */
    public ServiceResponse<List<String>> retrieveAvailableMedicationForms() {
        ServiceResponse<List<String>> response = new ServiceResponse<>();
        try {
            List<? extends IConceptMedicationForm> conceptMedicationForms = conceptMedicationFormRepository
                    .findAll(ConceptMedicationForm.class);
            List<String> availableForms = new ArrayList<>();
            for (IConceptMedicationForm mf : conceptMedicationForms) {
                availableForms.add(mf.getName());
            }
            response.setResponseObject(availableForms);
        } catch (Exception ex) {
            response.addError("", ex.getMessage());
        }
        return response;
    }

    /**
     * {@inheritDoc}
     */
    public ServiceResponse<List<MedicationAdministrationItem>> retrieveAvailableMedicationAdministrations() {
        ServiceResponse<List<MedicationAdministrationItem>> response = new ServiceResponse<>();
        try {
            // Retrieve a list of all medicationAdministrations from the database
            List<? extends IConceptPrescriptionAdministration> medicationAdministrations = conceptPrescriptionAdministrationRepository
                    .findAll(ConceptPrescriptionAdministration.class);

            // Creates a list of MedicationAdministratItems (UI Model) to be passed back to the controller/view
            List<MedicationAdministrationItem> availableAdministrations = new ArrayList<>();
            for (IConceptPrescriptionAdministration ma : medicationAdministrations) {
                availableAdministrations.add(itemModelMapper.createMedicationAdministrationItem(ma));
            }

            // Set the response object to the list of MedicationAdministrationItem's. The Response is what is sent back to the controller
            response.setResponseObject(availableAdministrations);
        } catch (Exception ex) {
            response.addError("", ex.getMessage());
        }
        return response;
    }

    /**
     * {@inheritDoc}
     */
    public ServiceResponse<List<String>> retrieveAvailableMedicationUnits() {
        ServiceResponse<List<String>> response = new ServiceResponse<>();
        try {
            List<? extends IConceptMedicationUnit> conceptMedicationUnits = conceptMedicationUnitRepository
                    .findAll(ConceptMedicationUnit.class);
            List<String> availableUnits = new ArrayList<>();
            for (IConceptMedicationUnit mmu : conceptMedicationUnits) {
                availableUnits.add(mmu.getName());
            }
            response.setResponseObject(availableUnits);
        } catch (Exception ex) {
            response.addError("", ex.getMessage());
        }
        return response;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ServiceResponse<List<MedicationItem>> retrieveMedicationInventory(int tripId) {
        ServiceResponse<List<MedicationItem>> response = new ServiceResponse<>();

        //Querying based on the trip id.  Each trip will have its own inventory.
        ExpressionList<MedicationInventory> medicationInventoryExpressionList = QueryProvider
                .getMedicationInventoryQuery().where().eq("missionTrip.id", tripId);

        List<? extends IMedicationInventory> medicationsInventory;
        try {
            medicationsInventory = medicationInventoryRepository.find(medicationInventoryExpressionList);
        } catch (Exception ex) {
            response.addError("exception", ex.getMessage());
            return response;
        }

        List<MedicationItem> medicationItems = new ArrayList<>();

        for (IMedicationInventory m : medicationsInventory) {

            medicationItems.add(itemModelMapper.createMedicationItem(m.getMedication(), m.getQuantityCurrent(),
                    m.getQuantityInitial(), m.getIsDeleted()));
        }
        response.setResponseObject(medicationItems);

        return response;
    }

    public ServiceResponse<ObjectNode> retrieveAllMedicationsWithID(Integer tripId) {
        ServiceResponse<ObjectNode> response = new ServiceResponse<>();
        ObjectNode returnObject = Json.newObject();
        ArrayNode allMedications = returnObject.putArray("medication");

        try {
            List<? extends IMedication> medications = medicationRepository.retrieveAllMedicationByTripId(tripId);
            MedicationItem medicationItem;

            for (IMedication m : medications) {
                //use the item model mapper to generate the MedicationItem which contains
                //the standard full name for a medication everywhere
                medicationItem = itemModelMapper.createMedicationItem(m, null, null, null);
                ObjectNode medication = Json.newObject();

                medication.put("id", m.getId());
                medication.put("name", medicationItem.getFullName());

                allMedications.add(medication);
            }
            response.setResponseObject(returnObject);
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
            response.addError("exception", ex.getMessage());
        }

        return response;
    }

}