com.sfs.whichdoctor.dao.OrganisationDAOImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.sfs.whichdoctor.dao.OrganisationDAOImpl.java

Source

/*******************************************************************************
 * Copyright (c) 2009 David Harrison.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v3.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/gpl-3.0.html
 *
 * Contributors:
 *     David Harrison - initial API and implementation
 ******************************************************************************/
package com.sfs.whichdoctor.dao;

import com.sfs.DataFilter;
import com.sfs.beans.BuilderBean;
import com.sfs.beans.ObjectTypeBean;
import com.sfs.beans.PrivilegesBean;
import com.sfs.beans.UserBean;
import com.sfs.whichdoctor.analysis.FinancialSummaryAnalysisDAO;
import com.sfs.whichdoctor.beans.AddressBean;
import com.sfs.whichdoctor.beans.DebitBean;
import com.sfs.whichdoctor.beans.FinancialSummaryBean;
import com.sfs.whichdoctor.beans.GroupBean;
import com.sfs.whichdoctor.beans.ItemBean;
import com.sfs.whichdoctor.beans.OrganisationBean;
import com.sfs.whichdoctor.beans.ReimbursementBean;
import com.sfs.whichdoctor.beans.SearchBean;
import com.sfs.whichdoctor.beans.SearchResultsBean;
import com.sfs.whichdoctor.beans.SupervisorBean;
import com.sfs.whichdoctor.beans.TransactionSummaryBean;
import com.sfs.whichdoctor.search.WhichDoctorSearchDaoException;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.TreeMap;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;

/**
 * The Class OrganisationDAOImpl.
 */
public class OrganisationDAOImpl extends WhichDoctorCoreObjectDAOImpl implements OrganisationDAO {

    /** The data logger. */
    private static Logger dataLogger = Logger.getLogger(OrganisationDAOImpl.class);

    /** The supervisor dao. */
    @Resource
    private SupervisorDAO supervisorDAO;

    /** The financial summary analysis dao. */
    @Resource
    private FinancialSummaryAnalysisDAO financialSummaryAnalysisDAO;

    /**
     * Used to get a OrganisationBean for a specified organisationId.
     *
     * @param organisationId the organisation id
     *
     * @return the organisation bean
     *
     * @throws WhichDoctorDaoException the which doctor dao exception
     */
    public final OrganisationBean load(final int organisationId) throws WhichDoctorDaoException {
        return load(organisationId, new BuilderBean(), false);
    }

    /**
     * Used to get a OrganisationBean for a specified organisationId with the
     * load details provided.
     *
     * @param organisationId the organisation id
     * @param loadDetails the load details
     *
     * @return the organisation bean
     *
     * @throws WhichDoctorDaoException the which doctor dao exception
     */
    public final OrganisationBean load(final int organisationId, final BuilderBean loadDetails)
            throws WhichDoctorDaoException {
        return load(organisationId, loadDetails, false);
    }

    /**
     * Used to get a OrganisationBean for a specified organisationId with the
     * load details provided. A boolean parameter identifies whether to use the
     * default reader connection or optional writer connection datasource
     *
     * @param organisationId the organisation id
     * @param loadDetails the load details
     * @param useWriterConn the use writer conn
     *
     * @return the organisation bean
     *
     * @throws WhichDoctorDaoException the which doctor dao exception
     */
    private OrganisationBean load(final int organisationId, final BuilderBean loadDetails,
            final boolean useWriterConn) throws WhichDoctorDaoException {

        OrganisationBean organisation = null;

        final String loadOrganisationId = getSQL().getValue("organisation/load")
                + " AND organisation.OrganisationId = ?";

        JdbcTemplate jdbcTemplate = this.getJdbcTemplateReader();
        if (useWriterConn) {
            jdbcTemplate = this.getJdbcTemplateWriter();
        }

        try {
            organisation = (OrganisationBean) jdbcTemplate.queryForObject(loadOrganisationId,
                    new Object[] { organisationId }, new RowMapper() {
                        public Object mapRow(final ResultSet rs, final int rowNum) throws SQLException {
                            return loadOrganisation(rs, loadDetails);
                        }
                    });

        } catch (IncorrectResultSizeDataAccessException ie) {
            dataLogger.debug("No results found for this search: " + ie.getMessage());
        }
        return organisation;
    }

    /**
     * Used to get a OrganisationBean for a specified name.
     *
     * @param strOrganisation the str organisation
     *
     * @return the organisation bean
     *
     * @throws WhichDoctorDaoException the which doctor dao exception
     */
    public final OrganisationBean load(final String strOrganisation) throws WhichDoctorDaoException {
        return load(strOrganisation, new BuilderBean());
    }

    /**
     * Used to get a OrganisationBean for a specified name with the load details
     * provided.
     *
     * @param strOrganisation the str organisation
     * @param loadDetails the load details
     *
     * @return the organisation bean
     *
     * @throws WhichDoctorDaoException the which doctor dao exception
     */
    public final OrganisationBean load(final String strOrganisation, final BuilderBean loadDetails)
            throws WhichDoctorDaoException {

        dataLogger.info("Organisation Name: " + strOrganisation + " requested");

        int organisationGUID = 0;

        final String loadSQL = getSQL().getValue("organisation/loadName");

        try {
            organisationGUID = this.getJdbcTemplateReader().queryForInt(loadSQL, new Object[] { strOrganisation });
        } catch (DataAccessException de) {
            dataLogger.error("Error getting guid for supplied organisation: " + de.getMessage());
        }
        if (organisationGUID > 0) {
            return loadGUID(organisationGUID, loadDetails);
        } else {
            throw new WhichDoctorDaoException(
                    "Sorry no organisation matching " + "those details could be identified");
        }
    }

    /**
     * Used to get a OrganisationBean for a specified guid.
     *
     * @param guid the guid
     *
     * @return the organisation bean
     *
     * @throws WhichDoctorDaoException the which doctor dao exception
     */
    public final OrganisationBean loadGUID(final int guid) throws WhichDoctorDaoException {
        return loadGUID(guid, new BuilderBean());
    }

    /**
     * Used to get a OrganisationBean for a specified guid with the load details
     * provided.
     *
     * @param guid the guid
     * @param loadDetails the load details
     *
     * @return the organisation bean
     *
     * @throws WhichDoctorDaoException the which doctor dao exception
     */
    public final OrganisationBean loadGUID(final int guid, final BuilderBean loadDetails)
            throws WhichDoctorDaoException {

        final String loadGUID = getSQL().getValue("organisation/load")
                + " AND organisation.Active = true AND organisation.GUID = ?";

        OrganisationBean organisation = null;

        try {
            organisation = (OrganisationBean) this.getJdbcTemplateReader().queryForObject(loadGUID,
                    new Object[] { guid }, new RowMapper() {
                        public Object mapRow(final ResultSet rs, final int rowNum) throws SQLException {
                            return loadOrganisation(rs, loadDetails);
                        }
                    });

        } catch (IncorrectResultSizeDataAccessException ie) {
            dataLogger.debug("No results found for this search: " + ie.getMessage());
        }
        return organisation;
    }

    /**
     * Creates the OrganisationBean.
     *
     * @param organisation the organisation
     * @param checkUser the check user
     * @param privileges the privileges
     *
     * @return the organisation bean
     *
     * @throws WhichDoctorDaoException the which doctor dao exception
     */
    public final OrganisationBean create(final OrganisationBean organisation, final UserBean checkUser,
            final PrivilegesBean privileges) throws WhichDoctorDaoException {
        organisation.setActive(true);
        int organisationId = save(organisation, checkUser, privileges, "create");

        return load(organisationId, new BuilderBean(), true);
    }

    /**
     * Modify the OrganisationBean.
     *
     * @param organisation the organisation
     * @param checkUser the check user
     * @param privileges the privileges
     *
     * @return the organisation bean
     *
     * @throws WhichDoctorDaoException the which doctor dao exception
     */
    public final OrganisationBean modify(final OrganisationBean organisation, final UserBean checkUser,
            final PrivilegesBean privileges) throws WhichDoctorDaoException {
        organisation.setActive(true);
        int organisationId = save(organisation, checkUser, privileges, "modify");

        return load(organisationId, new BuilderBean(), true);
    }

    /**
     * Delete the OrganisationBean.
     *
     * @param organisation the organisation
     * @param checkUser the check user
     * @param privileges the privileges
     *
     * @return true, if successful
     *
     * @throws WhichDoctorDaoException the which doctor dao exception
     */
    public final boolean delete(final OrganisationBean organisation, final UserBean checkUser,
            final PrivilegesBean privileges) throws WhichDoctorDaoException {

        boolean success = false;

        if (privileges.getPrivilege(checkUser, "organisations", "delete")) {
            // Before deleting the organisation remove its child objects
            final BuilderBean loadDetails = new BuilderBean();
            loadDetails.setParameter("LOAD_ALL", true);
            try {
                final OrganisationBean deleteObj = this.loadGUID(organisation.getGUID(), loadDetails);
                deleteAssociatedObjects(deleteObj, checkUser, privileges);

            } catch (WhichDoctorDaoException wde) {
                dataLogger.error("Error deleting children: " + wde.getMessage(), wde);
                throw new WhichDoctorDaoException("Error deleting children objects: " + wde.getMessage());
            }
        }

        organisation.setActive(false);
        int organisationId = save(organisation, checkUser, privileges, "delete");
        if (organisationId > 0) {
            success = true;
        }
        return success;
    }

    /**
     * Save the OrganisationBean changes.
     *
     * @param organisation the organisation
     * @param checkUser the check user
     * @param privileges the privileges
     * @param action the action
     *
     * @return the int
     *
     * @throws WhichDoctorDaoException the which doctor dao exception
     */
    private int save(final OrganisationBean organisation, final UserBean checkUser, final PrivilegesBean privileges,
            final String action) throws WhichDoctorDaoException {

        /* Check required information within Organisation bean is present */
        if (StringUtils.isBlank(organisation.getName())) {
            throw new WhichDoctorDaoException("Organisation name field cannot be an empty string");
        }
        if (StringUtils.isBlank(organisation.getType())) {
            throw new WhichDoctorDaoException("Organisation type field cannot be an empty string");
        }
        if (!privileges.getPrivilege(checkUser, "organisations", action)) {
            throw new WhichDoctorDaoException("Insufficient user credentials " + "to create new organisation");
        }

        /* Get Organisation TypeId */
        int typeId = 0;
        try {
            ObjectTypeBean object = this.getObjectTypeDAO().load("Organisation Type", "", organisation.getType());
            typeId = object.getObjectTypeId();
        } catch (Exception e) {
            dataLogger.error("Error loading objecttype for organisation type: " + e.getMessage());
        }

        int organisationId = 0;

        Timestamp sqlTimeStamp = new Timestamp(Calendar.getInstance().getTimeInMillis());

        ArrayList<Object> parameters = new ArrayList<Object>();
        parameters.add(organisation.getName());
        parameters.add(typeId);
        parameters.add(organisation.getActive());
        parameters.add(sqlTimeStamp);
        parameters.add(checkUser.getDN());
        parameters.add(organisation.getLogMessage(action));

        try {
            Integer[] result = this.performUpdate("organisation", organisation.getGUID(), parameters,
                    "Organisation", checkUser, action);
            /* Set the returned guid and id values */
            organisation.setGUID(result[0]);
            organisationId = result[1];
        } catch (Exception e) {
            dataLogger.error("Error processing organisation record: " + e.getMessage());
            throw new WhichDoctorDaoException("Error processing " + "organisation record: " + e.getMessage());
        }

        if (organisationId > 0) {

            dataLogger.info(checkUser.getDN() + " created organisationId: " + String.valueOf(organisationId));

            /* Update the region and city indexes */
            updateIndexes(organisation.getGUID(), action);
        }

        return organisationId;
    }

    /**
     * Delete the objects associated with the supplied OrganisationBean.
     *
     * @param deleteObjects the delete objects
     * @param checkUser the check user
     * @param privileges the privileges
     */
    private void deleteAssociatedObjects(final OrganisationBean deleteObjects, final UserBean checkUser,
            final PrivilegesBean privileges) {

        // Delete the associated employees
        if (deleteObjects.getEmployees() != null) {
            for (ItemBean employee : deleteObjects.getEmployees().values()) {
                try {
                    employee.setLogMessage(employee.getLogMessage("delete"));
                    this.getItemDAO().delete(employee, checkUser, privileges, null);
                } catch (WhichDoctorDaoException wde) {
                    dataLogger.error("Error deleting employee: " + wde.getMessage());
                }
            }
        }

        // Delete the associated supervisors
        if (deleteObjects.getSupervisors() != null) {
            for (SupervisorBean supervisor : deleteObjects.getSupervisors()) {
                try {
                    supervisor.setLogMessage(supervisor.getLogMessage("delete"));
                    supervisorDAO.delete(supervisor, checkUser, privileges);
                } catch (WhichDoctorDaoException wde) {
                    dataLogger.error("Error deleting supervisor: " + wde.getMessage());
                }
            }
        }

        // Delete the core objects associated to this organisation
        deleteAddresses(deleteObjects, checkUser, privileges);
        deleteEmailAddresses(deleteObjects, checkUser, privileges);
        deletePhoneNumbers(deleteObjects, checkUser, privileges);
        deleteSpecialties(deleteObjects, checkUser, privileges);
        deleteFinancialRecords(deleteObjects, checkUser, privileges);
        deleteMemos(deleteObjects, checkUser, privileges);
        deleteGroups(deleteObjects, checkUser, privileges);
    }

    /**
     * Load organisation.
     *
     * @param rs the rs
     * @param loadDetails the load details
     *
     * @return the organisation bean
     *
     * @throws SQLException the SQL exception
     */
    private OrganisationBean loadOrganisation(final ResultSet rs, final BuilderBean loadDetails)
            throws SQLException {

        OrganisationBean organisation = new OrganisationBean();

        /* Create resource bean and fill with dataset info. */
        organisation.setId(rs.getInt("OrganisationId"));
        organisation.setGUID(rs.getInt("GUID"));
        organisation.setName(rs.getString("Name"));
        organisation.setType(rs.getString("Type"));
        organisation.setRegion(rs.getString("Region"));
        organisation.setResidentCountry(rs.getString("ResidentCountry"));

        if (loadDetails.getBoolean("TAGS")) {
            try {
                organisation.setTags(
                        this.getTagDAO().load(organisation.getGUID(), loadDetails.getString("USERDN"), true));
            } catch (Exception e) {
                dataLogger.error("Error loading tags for organisation: " + e.getMessage());
            }
        }

        if (loadDetails.getBoolean("ADDRESS")) {
            try {
                organisation.setAddress(
                        this.getAddressDAO().load(organisation.getGUID(), loadDetails.getBoolean("ADDRESS_FULL"),
                                loadDetails.getString("ADDRESS_CLASS"), loadDetails.getString("ADDRESS_TYPE")));
            } catch (Exception e) {
                dataLogger.error("Error loading addresses for organisation: " + e.getMessage());
            }
        }
        if (loadDetails.getBoolean("PHONE")) {
            try {
                organisation.setPhone(
                        this.getPhoneDAO().load(organisation.getGUID(), loadDetails.getBoolean("PHONE_FULL")));
            } catch (Exception e) {
                dataLogger.error("Error loading phone numbers for organisation: " + e.getMessage());
            }
        }
        if (loadDetails.getBoolean("EMAIL")) {
            try {
                organisation.setEmail(
                        this.getEmailDAO().load(organisation.getGUID(), loadDetails.getBoolean("EMAIL_FULL"),
                                loadDetails.getString("EMAIL_CLASS"), loadDetails.getString("EMAIL_TYPE")));
            } catch (Exception e) {
                dataLogger.error("Error loading email addresses for organisation: " + e.getMessage());
            }
        }

        organisation.setActive(rs.getBoolean("Active"));
        if (loadDetails.getBoolean("HISTORY")) {
            try {
                organisation.setCreatedDate(rs.getTimestamp("CreatedDate"));
            } catch (SQLException sqe) {
                dataLogger.debug("Error reading CreatedDate: " + sqe.getMessage());
            }
            organisation.setCreatedBy(rs.getString("CreatedBy"));
            try {
                organisation.setModifiedDate(rs.getTimestamp("ModifiedDate"));
            } catch (SQLException sqe) {
                dataLogger.debug("Error reading ModifiedDate: " + sqe.getMessage());
            }
            organisation.setModifiedBy(rs.getString("ModifiedBy"));
            try {
                organisation.setExportedDate(rs.getTimestamp("ExportedDate"));
            } catch (SQLException sqe) {
                dataLogger.debug("Error reading ExportedDate: " + sqe.getMessage());
            }
            organisation.setExportedBy(rs.getString("ExportedBy"));
        }

        if (loadDetails.getBoolean("MEMO")) {
            try {
                organisation.setMemo(this.getMemoDAO().load(organisation.getGUID(), true));
            } catch (Exception e) {
                dataLogger.error("Error loading memos for organisation: " + e.getMessage());
            }
        }

        if (loadDetails.getBoolean("SPECIALTY")) {
            try {
                organisation.setSpecialtyList(this.getSpecialtyDAO().load(organisation.getGUID(), true));
            } catch (Exception e) {
                dataLogger.error("Error loading specialties for organisation: " + e.getMessage());
            }
        }

        if (loadDetails.getBoolean("EMPLOYEES")) {
            try {
                organisation.setEmployees(this.getItemDAO().load(organisation.getGUID(), true, "Employee",
                        "Employees", 0, loadDetails.getString("EMPLOYEES_STARTDATE"),
                        loadDetails.getString("EMPLOYEES_ENDDATE")));
            } catch (Exception e) {
                dataLogger.info("Error loading employees for organisation: " + e.getMessage());
            }
        }

        // Load the supervisors for this organisation
        if (loadDetails.getBoolean("SUPERVISORS")) {
            organisation.setSupervisors(loadSupervisors(organisation.getGUID(), loadDetails));
        }

        if (loadDetails.getBoolean("REIMBURSEMENTS")) {
            organisation.setReimbursements(loadReimbursements(organisation.getGUID()));
        }

        if (loadDetails.getBoolean("FINANCIAL_SUMMARY")) {
            FinancialSummaryBean search = new FinancialSummaryBean();
            search.setLimit(0);
            search.setRequestedPage(1);
            search.addOrganisation(organisation);
            search.setSecurity("Standard");

            search.setOpeningDate(DataFilter.parseDate(loadDetails.getString("FINANCIAL_SUMMARY_OPENING"), false));
            search.setClosingDate(DataFilter.parseDate(loadDetails.getString("FINANCIAL_SUMMARY_CLOSING"), true));

            BuilderBean summaryDetails = new BuilderBean();
            summaryDetails.setParameter("LOAD_DETAILS", loadDetails.getBoolean("FINANCIAL_SUMMARY_TRANSACTIONS"));
            summaryDetails.setParameter("SHOW_CANCELLED", loadDetails.getBoolean("FINANCIAL_SUMMARY_USER"));
            summaryDetails.setParameter("RESULT_COUNT", true);

            FinancialSummaryBean results = null;

            try {
                results = this.financialSummaryAnalysisDAO.search(search, summaryDetails);
            } catch (Exception e) {
                dataLogger.error("Error loading financial summary results: " + e.getMessage());
            }

            if (results != null && loadDetails.getBoolean("FINANCIAL_SUMMARY_LASTTEN")) {
                /* Limit to the last 10 results */
                if (results.getTotalResults() > 10) {
                    ArrayList<TransactionSummaryBean> limitedResults = new ArrayList<TransactionSummaryBean>();
                    ArrayList<TransactionSummaryBean> transactions = new ArrayList<TransactionSummaryBean>();

                    for (TransactionSummaryBean transaction : results.getTransactions()) {
                        transactions.add(transaction);
                    }

                    for (int i = transactions.size() - 11; i < transactions.size(); i++) {
                        try {
                            TransactionSummaryBean transaction = (TransactionSummaryBean) transactions.get(i);
                            if (i == transactions.size() - 11) {
                                /* Get total and set as opening balance */
                                results.setBalanceBroughtForward(transaction.getTotal());
                            } else {
                                limitedResults.add(transaction);
                            }
                        } catch (Exception e) {
                            dataLogger.error("Error getting last ten financial entries:" + e.getMessage());
                        }
                    }
                    results.setTransactions(limitedResults);
                }
            }
            organisation.setFinancialSummary(results);

            if (loadDetails.getBoolean("FINANCIAL_SUMMARY_USER")) {
                FinancialSummaryBean securedFinancialSearch = search;
                securedFinancialSearch.setSecurity("Restricted");

                try {
                    organisation.setRestrictedFinancialSummary(
                            this.financialSummaryAnalysisDAO.search(securedFinancialSearch, summaryDetails));
                    dataLogger.info("Successfully loaded restricted " + "financial summary information");

                } catch (Exception e) {
                    dataLogger.error("Error loading restricted financial " + "summary results: " + e.getMessage());
                }
            }

            if (loadDetails.getBoolean("FINANCIAL_SUMMARY_OUTSTANDING")) {
                double balance = 0;
                if (organisation.getFinancialSummary() != null) {
                    balance += organisation.getFinancialSummary().getClosingBalance();
                }
                if (organisation.getRestrictedFinancialSummary() != null) {
                    balance += organisation.getRestrictedFinancialSummary().getClosingBalance();
                }
                if (balance > 0) {
                    // Perform a search for outstanding debits associated with org.
                    SearchBean dbSearch = this.getSearchDAO().initiate("debit", null);
                    DebitBean dbCriteria = (DebitBean) dbSearch.getSearchCriteria();
                    DebitBean dbConstraints = (DebitBean) dbSearch.getSearchConstraints();
                    dbCriteria.setOrganisationId(organisation.getGUID());
                    dbCriteria.setOutstandingValue(0.01);
                    dbConstraints.setOutstandingValue(10000000);

                    dbSearch.setSearchCriteria(dbCriteria);
                    dbSearch.setSearchConstraints(dbConstraints);
                    dbSearch.setLimit(0);

                    SearchResultsBean dbResults = new SearchResultsBean();
                    try {
                        dbResults = this.getSearchDAO().search(dbSearch);
                    } catch (WhichDoctorSearchDaoException wde) {
                        dataLogger.error("Error searching for outstanding debits: " + wde.getMessage());
                    }

                    Collection<DebitBean> debits = new ArrayList<DebitBean>();
                    for (Object debit : dbResults.getSearchResults()) {
                        debits.add((DebitBean) debit);
                    }
                    organisation.setDebits(debits);
                }
            }
        }

        if (loadDetails.getBoolean("GROUPS")) {
            organisation.setGroups(loadGroups(organisation.getGUID()));
        }

        /* Load user details */
        if (loadDetails.getBoolean("CREATED")) {
            UserBean user = new UserBean();
            user.setDN(rs.getString("CreatedBy"));
            user.setPreferredName(rs.getString("CreatedFirstName"));
            user.setLastName(rs.getString("CreatedLastName"));
            organisation.setCreatedUser(user);
        }
        if (loadDetails.getBoolean("MODIFIED")) {
            UserBean user = new UserBean();
            user.setDN(rs.getString("ModifiedBy"));
            user.setPreferredName(rs.getString("ModifiedFirstName"));
            user.setLastName(rs.getString("ModifiedLastName"));
            organisation.setModifiedUser(user);
        }
        if (loadDetails.getBoolean("EXPORTED")) {
            UserBean user = new UserBean();
            user.setDN(rs.getString("ExportedBy"));
            user.setPreferredName(rs.getString("ExportedFirstName"));
            user.setLastName(rs.getString("ExportedLastName"));
            organisation.setExportedUser(user);
        }
        return organisation;
    }

    /**
     * Update indexes.
     *
     * @param guid the guid
     * @param action the action
     */
    private void updateIndexes(final int guid, final String action) {
        try {
            updateRegion(guid);
        } catch (Exception e) {
            dataLogger.error("Error updating organisation region: " + e.getMessage());
        }
        try {
            updateResidentCountry(guid);
        } catch (Exception e) {
            dataLogger.error("Error updating organisation resident country: " + e.getMessage());
        }
        try {
            updateAddressIndex(guid, action);
        } catch (Exception e) {
            dataLogger.error("Error updating organisation city index: " + e.getMessage());
        }
    }

    /**
     * Update the address index for the specified organisation GUID.
     *
     * @param guid the guid
     * @param action the action
     *
     * @throws WhichDoctorDaoException the which doctor dao exception
     */
    private void updateAddressIndex(final int guid, final String action) throws WhichDoctorDaoException {

        /* Load primary address for organisation */
        BuilderBean loadDetails = new BuilderBean();
        loadDetails.setParameter("ADDRESS", true);
        OrganisationBean organisation = loadGUID(guid, loadDetails);
        if (organisation != null) {
            if (organisation.getFirstAddress() != null) {
                AddressBean address = organisation.getFirstAddress();
                this.getAddressDAO().updateAddressIndexes(address, action);
            }
        }
    }

    /**
     * Update the region for the organisation.
     *
     * @param guid the guid
     *
     * @throws WhichDoctorDaoException the which doctor dao exception
     */
    public final void updateRegion(final int guid) throws WhichDoctorDaoException {

        int regionId = this.getAddressDAO().getRegionId(guid);

        try {
            this.getSearchIndexDAO().update(guid, "Region", 0, 0, regionId);
        } catch (Exception e) {
            dataLogger.error("Error updating region index: " + e.getMessage());
        }
    }

    /**
     * Update the resident country index for this organisation.
     *
     * @param guid the guid
     *
     * @throws WhichDoctorDaoException the which doctor dao exception
     */
    public final void updateResidentCountry(final int guid) throws WhichDoctorDaoException {

        int stateCountryId = this.getAddressDAO().getStateCountryId(guid);

        try {
            this.getSearchIndexDAO().update(guid, "Resident Country", 0, 0, stateCountryId);
        } catch (Exception e) {
            dataLogger.error("Error updating resident country index: " + e.getMessage());
        }
    }

    /**
     * Recalculate all location search indexes.
     *
     * @throws WhichDoctorDaoException the which doctor dao exception
     */
    public final void recalculateAllLocationIndexes() throws WhichDoctorDaoException {

        dataLogger.info("Rebuilding search indexes for locations");

        Collection<OrganisationBean> organisations = this.loadActiveOrganisations();

        for (Object organisationObj : organisations) {
            OrganisationBean organisation = (OrganisationBean) organisationObj;
            try {
                updateAddressIndex(organisation.getGUID(), "update");
                updateRegion(organisation.getGUID());
                updateResidentCountry(organisation.getGUID());
                dataLogger.error("Refreshed location index for guid: " + organisation.getGUID());
            } catch (WhichDoctorDaoException wde) {
                dataLogger.error("Error rebuilding organisation index for GUID: " + organisation.getGUID() + ", "
                        + wde.getMessage());
            }
        }
    }

    /**
     * Recalculate all financial search indexes.
     *
     * @throws WhichDoctorDaoException the which doctor dao exception
     */
    public final void recalculateAllFinancialIndexes() throws WhichDoctorDaoException {

        dataLogger.info("Rebuilding search indexes for finance");

        Collection<OrganisationBean> organisations = this.loadActiveOrganisations();

        for (OrganisationBean organisation : organisations) {
            try {
                this.getSearchIndexDAO().updateCurrentBalanceIndex(organisation.getGUID(), "organisation");
                dataLogger.error("Refreshed current balance index for guid: " + organisation.getGUID());
            } catch (WhichDoctorDaoException wde) {
                dataLogger.error("Error rebuilding current balance index for " + "organisation: "
                        + organisation.getGUID() + ", " + wde.getMessage());
            }
        }
    }

    /**
     * Load all active organisations.
     *
     * @return the collection< organisation bean>
     *
     * @throws WhichDoctorDaoException the which doctor dao exception
     */
    private Collection<OrganisationBean> loadActiveOrganisations() throws WhichDoctorDaoException {

        Collection<OrganisationBean> organisations = new ArrayList<OrganisationBean>();

        SearchBean search = this.getSearchDAO().initiate("organisation", null);
        search.setLimit(0);

        Collection<Object> results = null;
        try {
            results = this.getSearchDAO().search(search).getSearchResults();
        } catch (Exception e) {
            dataLogger.error("Error searching for active organisations: " + e.getMessage());
            throw new WhichDoctorDaoException("Error searching for active organisations: " + e.getMessage());
        }

        if (results != null) {
            for (Object objOrganisation : results) {
                if (objOrganisation != null) {
                    organisations.add((OrganisationBean) objOrganisation);
                }
            }
        }
        return organisations;
    }

    /**
     * Load groups.
     *
     * @param guid the guid
     *
     * @return the collection< group bean>
     */
    private Collection<GroupBean> loadGroups(final int guid) {

        // Create new SearchBean of type Organisation and default values
        SearchResultsBean results = new SearchResultsBean();
        SearchBean groupSearch = this.getSearchDAO().initiate("group", null);
        groupSearch.setLimit(0);

        GroupBean searchCriteria = (GroupBean) groupSearch.getSearchCriteria();
        searchCriteria.setObjectType("Organisations");
        ItemBean item = new ItemBean();
        item.setObject2GUID(guid);
        TreeMap<String, ItemBean> items = new TreeMap<String, ItemBean>();
        items.put("Organisation", item);
        searchCriteria.setItems(items);

        groupSearch.setSearchCriteria(searchCriteria);

        try {
            BuilderBean loadGroup = new BuilderBean();
            loadGroup.setParameter("ITEMS", true);
            loadGroup.setParameter("REFERENCEID", String.valueOf(guid));
            results = this.getSearchDAO().search(groupSearch, loadGroup);
        } catch (Exception e) {
            dataLogger.error("Error loading groups for organisation: " + e.getMessage());
        }

        ArrayList<GroupBean> groups = new ArrayList<GroupBean>();
        for (Object group : results.getSearchResults()) {
            groups.add((GroupBean) group);
        }
        return groups;
    }

    /**
     * Load reimbursements.
     *
     * @param guid the guid
     *
     * @return the collection< reimbursement bean>
     */
    private Collection<ReimbursementBean> loadReimbursements(final int guid) {

        Collection<ReimbursementBean> reimbursements = new ArrayList<ReimbursementBean>();

        SearchBean search = this.getSearchDAO().initiate("reimbursement", null);
        ReimbursementBean searchCriteria = (ReimbursementBean) search.getSearchCriteria();
        searchCriteria.setOrganisationId(guid);

        search.setLimit(0);
        search.setSearchCriteria(searchCriteria);

        /* Perform search */
        try {
            final Collection<Object> results = this.getSearchDAO().search(search).getSearchResults();

            if (results != null) {
                for (Object reimbursementObj : results) {
                    reimbursements.add((ReimbursementBean) reimbursementObj);
                }
            }
            dataLogger.info("Successfully searched database for " + "Reimbursement information");
        } catch (Exception e) {
            dataLogger.error("ERROR searching database: " + e.getMessage());
        }
        return reimbursements;
    }

    /**
     * Load supervisors.
     *
     * @param guid the guid
     * @param loadDetails the load details
     *
     * @return the collection< supervisor bean>
     */
    private Collection<SupervisorBean> loadSupervisors(final int guid, final BuilderBean loadDetails) {

        Collection<SupervisorBean> supervisors = new ArrayList<SupervisorBean>();

        try {
            BuilderBean supervisorDetails = new BuilderBean();

            supervisorDetails.setParameter("SUPERVISOR_PERSONOBJ", true);
            supervisorDetails.setParameter("EMAIL", loadDetails.getBoolean("SUPERVISORS_EMAIL"));

            supervisors = this.supervisorDAO.load(guid, supervisorDetails);
        } catch (Exception e) {
            dataLogger.info("Error loading supervisors for organisation: " + e.getMessage());
        }
        return supervisors;
    }
}