com.sfs.whichdoctor.dao.onlineapplication.BasicTrainingOnlineApplicationHandler.java Source code

Java tutorial

Introduction

Here is the source code for com.sfs.whichdoctor.dao.onlineapplication.BasicTrainingOnlineApplicationHandler.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.onlineapplication;

import com.sfs.DataFilter;
import com.sfs.beans.ObjectTypeBean;
import com.sfs.beans.PrivilegesBean;
import com.sfs.beans.UserBean;
import com.sfs.whichdoctor.beans.AddressBean;
import com.sfs.whichdoctor.beans.AccreditationBean;
import com.sfs.whichdoctor.beans.AssessmentBean;
import com.sfs.whichdoctor.beans.DebitBean;
import com.sfs.whichdoctor.beans.EmailBean;
import com.sfs.whichdoctor.beans.PersonBean;
import com.sfs.whichdoctor.beans.PhoneBean;
import com.sfs.whichdoctor.beans.PreferencesBean;
import com.sfs.whichdoctor.beans.MembershipBean;
import com.sfs.whichdoctor.beans.QualificationBean;
import com.sfs.whichdoctor.beans.RotationBean;
import com.sfs.whichdoctor.beans.SpecialtyBean;
import com.sfs.whichdoctor.beans.SupervisorBean;
import com.sfs.whichdoctor.beans.OnlineApplicationBean;
import com.sfs.whichdoctor.checker.PersonChecker;
import com.sfs.whichdoctor.dao.AddressDAO;
import com.sfs.whichdoctor.dao.MembershipDAO;
import com.sfs.whichdoctor.dao.PersonDAO;
import com.sfs.whichdoctor.dao.PhoneDAO;
import com.sfs.whichdoctor.dao.RelationshipDAO;
import com.sfs.whichdoctor.dao.RotationDAO;
import com.sfs.whichdoctor.dao.PreferencesDAO;
import com.sfs.whichdoctor.dao.WhichDoctorDaoException;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.WordUtils;
import org.apache.log4j.Logger;

import org.jdom.Document;
import org.jdom.Element;

/**
 * The Class BasicTrainingOnlineApplicationHandler.
 */
public class BasicTrainingOnlineApplicationHandler implements OnlineApplicationHandler {

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

    /** The person checker. */
    @Resource
    private PersonChecker personChecker;

    /** The address dao. */
    @Resource
    private AddressDAO addressDAO;

    /** The person dao. */
    @Resource
    private PersonDAO personDAO;

    /** The preferences dao. */
    @Resource
    private PreferencesDAO preferencesDAO;

    /** The membership dao. */
    @Resource
    private MembershipDAO membershipDAO;

    /** The phone dao. */
    @Resource
    private PhoneDAO phoneDAO;

    /** The relationship dao. */
    @Resource
    private RelationshipDAO relationshipDAO;

    /** The rotation dao. */
    @Resource
    private RotationDAO rotationDAO;

    /**
     * Validate the next step.
     *
     * @param nextStep the next step
     * @param xml the xml
     * @param recordId the record id
     * @return true, if successful
     */
    public final boolean validateNextStep(final String nextStep, final Document xml, final String recordId) {

        boolean validStep = true;

        Element root = new Element("root");
        if (xml.getRootElement() != null) {
            root = xml.getRootElement();
        }

        if (StringUtils.equalsIgnoreCase(nextStep, "Confirm email address") && loadEmailDetails(root, 0) == null) {
            validStep = false;
        }
        if (StringUtils.equalsIgnoreCase(nextStep, "Confirm work phone")
                && loadPhoneDetails(root, "work", 0) == null) {
            validStep = false;
        }
        if (StringUtils.equalsIgnoreCase(nextStep, "Confirm work fax")
                && loadPhoneDetails(root, "workfax", 0) == null) {
            validStep = false;
        }
        if (StringUtils.equalsIgnoreCase(nextStep, "Confirm home phone")
                && loadPhoneDetails(root, "home", 0) == null) {
            validStep = false;
        }
        if (StringUtils.equalsIgnoreCase(nextStep, "Confirm home fax")
                && loadPhoneDetails(root, "homefax", 0) == null) {
            validStep = false;
        }
        if (StringUtils.equalsIgnoreCase(nextStep, "Confirm mobile phone")
                && loadPhoneDetails(root, "mobile", 0) == null) {
            validStep = false;
        }
        if (StringUtils.equalsIgnoreCase(nextStep, "Confirm secondary qualifications")
                && loadQualificationDetails(root, 0, recordId) == null) {
            validStep = false;
        }
        if (StringUtils.equalsIgnoreCase(nextStep, "Confirm rotation details")
                && loadRotationDetails(root, 0, recordId) == null) {
            validStep = false;
        }
        if (StringUtils.equalsIgnoreCase(nextStep, "Issue invoice") && loadDebitDetails(root, 0) == null) {
            validStep = false;
        }
        return validStep;
    }

    /**
     * Gets the JSP key for the next step.
     * An error is thrown if the user does not have the privileges to access this step.
     *
     * @param application the online application
     * @param user the user
     * @param privileges the privileges
     * @return the next step
     * @throws WhichDoctorDaoException the which doctor dao exception
     */
    public final String getNextJSPKey(final OnlineApplicationBean application, final UserBean user,
            final PrivilegesBean privileges) throws WhichDoctorDaoException {

        if (user == null) {
            throw new WhichDoctorDaoException("The user cannot be null");
        }
        if (privileges == null) {
            throw new WhichDoctorDaoException("The privileges cannot be null");
        }

        String key = "";

        String status = application.getStatus();
        if (StringUtils.contains(status, " )")) {
            status = StringUtils.substringBefore(status, " (");
        }
        if (StringUtils.equalsIgnoreCase(status, "Unprocessed")) {
            if (privileges.getPrivilege(user, "people", "create")) {
                key = "PEOPLE_DATAENTRY";
            } else {
                throw new WhichDoctorDaoException("Insufficient permissions to confirm membership details");
            }
        }
        if (StringUtils.equalsIgnoreCase(status, "Confirm email address")) {
            if (privileges.getPrivilege(user, "emails", "create")) {
                key = "EMAIL_DATAENTRY";
            } else {
                throw new WhichDoctorDaoException("Insufficient permissions to confirm email details");
            }
        }
        if (StringUtils.equalsIgnoreCase(status, "Confirm address")) {
            if (privileges.getPrivilege(user, "addresses", "create")) {
                key = "ADDRESS_DATAENTRY";
            } else {
                throw new WhichDoctorDaoException("Insufficient permissions to confirm address details");
            }
        }
        if (StringUtils.containsIgnoreCase(status, " phone") || StringUtils.containsIgnoreCase(status, " fax")) {
            if (privileges.getPrivilege(user, "phones", "create")) {
                key = "PHONE_DATAENTRY";
            } else {
                throw new WhichDoctorDaoException("Insufficient permissions to confirm phone details");
            }
        }
        if (StringUtils.equalsIgnoreCase(status, "Confirm secondary qualifications")) {
            if (privileges.getPrivilege(user, "qualifications", "create")) {
                key = "QUALIFICATION_DATAENTRY";
            } else {
                throw new WhichDoctorDaoException("Insufficient permissions to confirm qualifications details");
            }
        }
        if (StringUtils.equalsIgnoreCase(status, "Confirm rotation details")) {
            if (privileges.getPrivilege(user, "rotations", "create")) {
                key = "ROTATIONS_DATAENTRY";
            } else {
                throw new WhichDoctorDaoException("Insufficient permissions to confirm rotation details");
            }
        }
        if (StringUtils.equalsIgnoreCase(status, "Issue invoice")) {
            if (privileges.getPrivilege(user, "invoices", "create")) {
                key = "DEBITS_DATAENTRY";
            } else {
                throw new WhichDoctorDaoException("Insufficient permissions to issue invoice");
            }
        }

        return key;
    }

    /**
     * Gets the next request.
     *
     * @param application the online application
     * @param xml the xml
     * @return the map of objects
     */
    public final Map<String, Object> getNextObjects(final OnlineApplicationBean application, final Document xml) {

        Map<String, Object> objects = new TreeMap<String, Object>();

        int guid = application.getPersonGUID();

        Element root = new Element("defaultRoot");
        if (xml != null && xml.getRootElement() != null) {
            root = xml.getRootElement();
        }

        if (StringUtils.equalsIgnoreCase(application.getStatus(), "Unprocessed")) {
            objects.put("Person", loadPersonDetails(root));
            objects.put("Membership", loadMembershipDetails(root));
            objects.put("Specialty", loadSpecialtyDetails(root, application));

            QualificationBean qlf = loadQualificationDetails(root, guid, "1");
            if (qlf == null) {
                qlf = new QualificationBean();
            }
            objects.put("Qualification", qlf);

        }

        if (StringUtils.equalsIgnoreCase(application.getStatus(), "Confirm email address")) {
            objects.put("Email", loadEmailDetails(root, guid));
        }

        if (StringUtils.equalsIgnoreCase(application.getStatus(), "Confirm address")) {
            objects.put("Address", loadAddressDetails(root, guid));
        }

        if (StringUtils.equalsIgnoreCase(application.getStatus(), "Confirm work phone")) {
            objects.put("Phone", loadPhoneDetails(root, "work", guid));
        }

        if (StringUtils.equalsIgnoreCase(application.getStatus(), "Confirm work fax")) {
            objects.put("Phone", loadPhoneDetails(root, "workfax", guid));
        }

        if (StringUtils.equalsIgnoreCase(application.getStatus(), "Confirm home phone")) {
            objects.put("Phone", loadPhoneDetails(root, "home", guid));
        }

        if (StringUtils.equalsIgnoreCase(application.getStatus(), "Confirm home fax")) {
            objects.put("Phone", loadPhoneDetails(root, "homefax", guid));
        }

        if (StringUtils.equalsIgnoreCase(application.getStatus(), "Confirm mobile phone")) {
            objects.put("Phone", loadPhoneDetails(root, "mobile", guid));
        }

        if (StringUtils.equalsIgnoreCase(application.getStatus(), "Confirm secondary qualifications")) {
            objects.put("Qualification", loadQualificationDetails(root, guid, application.getRecordNumber()));
        }

        if (StringUtils.equalsIgnoreCase(application.getStatus(), "Confirm rotation details")) {
            objects.put("Rotation", loadRotationDetails(root, guid, application.getRecordNumber()));
            objects.put("Person", loadPerson(guid));
            objects.put("SupervisorTypes", loadSupervisorTypes());
        }

        if (StringUtils.equalsIgnoreCase(application.getStatus(), "Issue invoice")) {
            objects.put("Invoice", loadDebitDetails(root, guid));
        }

        return objects;
    }

    /**
     * Gets the existing record, returns null if none is found.
     *
     * @param application the application
     * @param xml the xml
     * @return the existing record
     */
    public final PersonBean getExistingRecord(final Document xml) {

        PersonBean existingPerson = null;

        Element root = new Element("defaultRoot");
        if (xml != null && xml.getRootElement() != null) {
            root = xml.getRootElement();
        }
        PersonBean person = loadPersonDetails(root);

        Collection<PersonBean> similarPeople = personChecker.similar(person);

        if (similarPeople.size() > 0) {
            existingPerson = similarPeople.iterator().next();
        }
        return existingPerson;
    }

    /**
     * The step to jump to if this is an existing record.
     *
     * @return the string
     */
    public final String[] stepIfExistingRecord() {
        return new String[] { "Confirm rotation details", "1" };
    }

    /**
     * Load person details from the XML application.
     *
     * @param root the root of the XML application
     * @return the person bean
     */
    private PersonBean loadPersonDetails(final Element root) {
        PersonBean person = new PersonBean();

        Element pd = root.getChild("personaldetails");
        try {
            String name = pd.getChildText("firstname").trim();
            person.setFirstName(name);
            if (StringUtils.contains(name, " ")) {
                // Split the first and middle names
                person.setFirstName(StringUtils.substringBefore(name, " "));
                person.setMiddleName(StringUtils.substringAfter(name, " "));
            }
        } catch (Exception e) {
            dataLogger.error("Error parsing firstname: " + e.getMessage());
        }
        try {
            person.setPreferredName(pd.getChildText("prefname").trim());
        } catch (Exception e) {
            dataLogger.error("Error parsing prefname: " + e.getMessage());
        }
        try {
            person.setLastName(pd.getChildText("lastname").trim());
        } catch (Exception e) {
            dataLogger.error("Error parsing lastname: " + e.getMessage());
        }
        try {
            String birthDate = pd.getChildText("dob").trim();
            person.setBirthDate(parseDate(birthDate));
        } catch (Exception e) {
            dataLogger.error("Error parsing dob: " + e.getMessage());
        }
        try {
            String gender = pd.getChildText("gender").trim();
            person.setGender(WordUtils.capitalizeFully(gender));
        } catch (Exception e) {
            dataLogger.error("Error parsing lastname: " + e.getMessage());
        }
        person.setTitle("Dr");

        return person;
    }

    /**
     * Load the membership details from the XML application.
     *
     * @param root the root of the XML application
     * @return the membership bean
     */
    private MembershipBean loadMembershipDetails(final Element root) {

        MembershipBean membership = membershipDAO.getDefaultInstance();

        // Set the joined date to today (default)
        membership.setJoinedDate(Calendar.getInstance().getTime());

        // Set the membership status
        ObjectTypeBean statusObject = new ObjectTypeBean();
        statusObject.setObject("Status");
        statusObject.setClassName("Active - within NZ");
        statusObject.setName("");
        membership.setField("Status", statusObject);

        // Set the membership type
        ObjectTypeBean membershipType = new ObjectTypeBean();
        membershipType.setObject("Membership Type");
        membershipType.setClassName("Member");
        membershipType.setName("Basic Trainee");
        membership.setField("Membership Type", membershipType);

        // Set the division
        String divisionValue = "Adult";
        try {
            String div = root.getChild("masterrecord").getChildText("Division").trim();
            if (StringUtils.startsWith(div, "P")) {
                divisionValue = "Paediatric";
            }
        } catch (Exception e) {
            dataLogger.error("Error parsing Division: " + e.getMessage());
        }

        ObjectTypeBean division = new ObjectTypeBean();
        division.setObject("Division");
        division.setClassName(divisionValue);
        division.setName("");
        membership.setField("Division", division);

        // Set the training type
        ObjectTypeBean trainingType = new ObjectTypeBean();
        trainingType.setObject("Training Type");
        trainingType.setClassName("Trainee");
        trainingType.setName("");
        membership.setField("Training Type", trainingType);

        return membership;
    }

    /**
     * Load specialty details from the XML application.
     *
     * @param root the root of the XML application
     * @param onlineApplication the online application
     * @return the specialty bean
     */
    private SpecialtyBean loadSpecialtyDetails(final Element root, final OnlineApplicationBean onlineApplication) {

        SpecialtyBean specialty = new SpecialtyBean();

        String organisation = "RACP - Adult";
        try {
            String div = root.getChild("masterrecord").getChildText("Division").trim();
            if (StringUtils.startsWith(div, "P")) {
                organisation = "RACP - Paediatric";
            }
        } catch (Exception e) {
            dataLogger.error("Error parsing Division: " + e.getMessage());
        }

        Calendar date = Calendar.getInstance();

        if (onlineApplication.getCreatedDate() != null) {
            date.setTime(onlineApplication.getCreatedDate());
        }

        int year = date.get(Calendar.YEAR);
        // If December the curriculum year is the following year
        if (date.get(Calendar.MONTH) > 10) {
            year++;
        }

        specialty.setTrainingOrganisation(organisation);
        specialty.setTrainingProgram("Basic Training");
        specialty.setStatus("In training");
        specialty.setTrainingProgramYear(year);

        return specialty;
    }

    /**
     * Load the qualification details from the XML application.
     *
     * @param root the root of the XML application
     * @param guid the guid
     * @param recordId the record id
     * @return the qualification bean
     */
    private QualificationBean loadQualificationDetails(final Element root, final int guid, final String recordId) {

        QualificationBean qlf = new QualificationBean();

        qlf.setReferenceGUID(guid);
        qlf.setQualificationType("Undergraduate");
        qlf.setQualificationSubType("Basic Medical Qualification");

        List<?> records = root.getChildren("educationrecord");
        for (Object obj : records) {
            // Get the qualification record
            Element record = (Element) obj;

            String recordNumber = "";
            try {
                recordNumber = record.getChildText("recordnumber").trim();
            } catch (Exception e) {
                dataLogger.error("Error parsing recordnumber: " + e.getMessage());
            }

            if (StringUtils.equalsIgnoreCase(recordNumber, recordId)) {
                try {
                    qlf.setQualification(record.getChildText("qualifications").trim());
                } catch (Exception e) {
                    dataLogger.error("Error parsing qualifications: " + e.getMessage());
                }
                try {
                    qlf.setInstitution(record.getChildText("Institution").trim());
                } catch (Exception e) {
                    dataLogger.error("Error parsing Institution: " + e.getMessage());
                }
                try {
                    qlf.setCountry(WordUtils.capitalizeFully(record.getChildText("Country").trim()));
                } catch (Exception e) {
                    dataLogger.error("Error parsing Country: " + e.getMessage());
                    qlf.setCountry("New Zealand");
                }
                try {
                    qlf.setYear(Integer.parseInt(record.getChildText("year").trim()));
                } catch (Exception e) {
                    dataLogger.error("Error parsing year: " + e.getMessage());
                }
            }
        }

        if (StringUtils.isBlank(qlf.getQualification())) {
            // This is not a valid qualification
            qlf = null;
        }

        return qlf;
    }

    /**
     * Load the email details from the XML application.
     *
     * @param root the root of the XML application
     * @return the email bean
     */
    private EmailBean loadEmailDetails(final Element root, final int guid) {
        EmailBean email = new EmailBean();

        Element pd = root.getChild("personaldetails");

        email.setReferenceGUID(guid);
        email.setContactClass("Unsecured Email");
        email.setContactType("Work Email");
        email.setPrimary(true);
        email.setEmailQuestions(true);

        try {
            email.setEmail(pd.getChildText("email").trim());
        } catch (Exception e) {
            dataLogger.error("Error parsing email: " + e.getMessage());
        }

        if (StringUtils.isBlank(email.getEmail())) {
            // The email is not valid, return null
            email = null;
        }

        return email;
    }

    /**
     * Load the address details from the XML application.
     *
     * @param root the root of the XML application
     * @param guid the guid
     * @return the address bean
     */
    private AddressBean loadAddressDetails(final Element root, final int guid) {
        AddressBean address = new AddressBean();

        Element pd = root.getChild("personaldetails");

        address.setReferenceGUID(guid);
        address.setContactClass("Home");
        address.setContactType("Postal");
        address.setPrimary(true);

        try {
            address.setAddressField(pd.getChildText("streetaddress1").trim());
        } catch (Exception e) {
            dataLogger.error("Error parsing streetaddress1: " + e.getMessage());
        }
        try {
            address.setAddressField(pd.getChildText("streetaddress2").trim());
        } catch (Exception e) {
            dataLogger.error("Error parsing streetaddress2: " + e.getMessage());
        }
        try {
            address.setAddressField(pd.getChildText("streetaddress3").trim());
        } catch (Exception e) {
            dataLogger.error("Error parsing streetaddress3: " + e.getMessage());
        }
        try {
            address.setAddressField(pd.getChildText("streetaddress4").trim());
        } catch (Exception e) {
            dataLogger.error("Error parsing streetaddress4: " + e.getMessage());
        }
        try {
            address.setAddressField(pd.getChildText("suburb").trim());
        } catch (Exception e) {
            dataLogger.error("Error parsing suburb: " + e.getMessage());
        }
        try {
            address.setState(pd.getChildText("state").trim());
        } catch (Exception e) {
            dataLogger.error("Error parsing state: " + e.getMessage());
        }
        try {
            String country = pd.getChildText("countryid");
            address.setCountry(WordUtils.capitalizeFully(country).trim());
        } catch (Exception e) {
            dataLogger.error("Error parsing countryid: " + e.getMessage());
        }
        try {
            address.setPostCode(pd.getChildText("postcode").trim());
        } catch (Exception e) {
            dataLogger.error("Error parsing postcode: " + e.getMessage());
        }

        address.setState(this.addressDAO.getState(address.getCity(), address.getCountry()));

        if (StringUtils.isBlank(address.getAddressField(0))) {
            // The address is not valid, return null
            address = null;
        }

        return address;
    }

    /**
     * Load the phone details from the XML application.
     *
     * @param root the root of the XML application
     * @param type the type
     * @param guid the guid
     * @return the phone bean
     */
    private PhoneBean loadPhoneDetails(final Element root, final String type, final int guid) {
        PhoneBean phone = new PhoneBean();

        Element pd = root.getChild("personaldetails");

        phone.setReferenceGUID(guid);

        if (StringUtils.equalsIgnoreCase(type, "work")) {
            phone = loadWorkPhoneDetails(root, phone);
        }
        if (StringUtils.equalsIgnoreCase(type, "workfax")) {
            phone = loadWorkFaxDetails(root, phone);
        }
        if (StringUtils.equalsIgnoreCase(type, "home")) {
            phone = loadHomePhoneDetails(root, phone);
        }
        if (StringUtils.equalsIgnoreCase(type, "homefax")) {
            phone = loadHomeFaxDetails(root, phone);
        }
        if (StringUtils.equalsIgnoreCase(type, "mobile")) {
            phone = loadMobilePhoneDetails(root, phone);
        }

        if (StringUtils.isNotBlank(phone.getNumber())) {
            // Load the country code for the phone number
            try {
                String ctry = WordUtils.capitalize(pd.getChildText("countryid")).trim();
                phone.setCountryCode(this.phoneDAO.getCountryCode(ctry));
            } catch (Exception e) {
                dataLogger.error("Error getting country code: " + e.getMessage());
            }
        } else {
            // The phone number is not valid, return null
            phone = null;
        }

        return phone;
    }

    /**
     * Load the work phone details from the XML application.
     *
     * @param root the root of the XML application
     * @return the address bean
     */
    private PhoneBean loadWorkPhoneDetails(final Element root, final PhoneBean phone) {

        Element pd = root.getChild("personaldetails");

        phone.setPrimary(true);
        phone.setContactType("Work");
        try {
            phone.setNumber(pd.getChildText("phonework").trim());
        } catch (Exception e) {
            dataLogger.error("Error parsing phonework: " + e.getMessage());
        }
        try {
            phone.setAreaCode(Integer.parseInt(pd.getChildText("phoneworkac").trim()));
        } catch (Exception e) {
            dataLogger.error("Error parsing phoneworkac: " + e.getMessage());
        }
        return phone;
    }

    /**
     * Load the work fax details from the XML application.
     *
     * @param root the root of the XML application
     * @return the address bean
     */
    private PhoneBean loadWorkFaxDetails(final Element root, final PhoneBean phone) {

        Element pd = root.getChild("personaldetails");

        phone.setContactType("Work Fax");
        try {
            phone.setNumber(pd.getChildText("faxwork").trim());
        } catch (Exception e) {
            dataLogger.error("Error parsing faxwork: " + e.getMessage());
        }
        try {
            phone.setAreaCode(Integer.parseInt(pd.getChildText("faxworkac").trim()));
        } catch (Exception e) {
            dataLogger.error("Error parsing faxworkac: " + e.getMessage());
        }
        return phone;
    }

    /**
     * Load the home phone details from the XML application.
     *
     * @param root the root of the XML application
     * @return the address bean
     */
    private PhoneBean loadHomePhoneDetails(final Element root, final PhoneBean phone) {

        Element pd = root.getChild("personaldetails");

        phone.setContactType("Home");
        try {
            phone.setNumber(pd.getChildText("phonehome").trim());
        } catch (Exception e) {
            dataLogger.error("Error parsing phonehome: " + e.getMessage());
        }
        try {
            phone.setAreaCode(Integer.parseInt(pd.getChildText("phonehomeac").trim()));
        } catch (Exception e) {
            dataLogger.error("Error parsing phonehomeac: " + e.getMessage());
        }
        return phone;
    }

    /**
     * Load the home fax details from the XML application.
     *
     * @param root the root of the XML application
     * @return the address bean
     */
    private PhoneBean loadHomeFaxDetails(final Element root, final PhoneBean phone) {

        Element pd = root.getChild("personaldetails");

        phone.setContactType("Home Fax");
        try {
            phone.setNumber(pd.getChildText("faxhome").trim());
        } catch (Exception e) {
            dataLogger.error("Error parsing faxhome: " + e.getMessage());
        }
        try {
            phone.setAreaCode(Integer.parseInt(pd.getChildText("faxhomeac").trim()));
        } catch (Exception e) {
            dataLogger.error("Error parsing faxhomeac: " + e.getMessage());
        }
        return phone;
    }

    /**
     * Load the mobile phone details from the XML application.
     *
     * @param root the root of the XML application
     * @return the address bean
     */
    private PhoneBean loadMobilePhoneDetails(final Element root, final PhoneBean phone) {

        Element pd = root.getChild("personaldetails");

        phone.setContactType("Mobile");
        try {
            phone.setNumber(pd.getChildText("phonemobile").trim());
        } catch (Exception e) {
            dataLogger.error("Error parsing phonemobile: " + e.getMessage());
        }
        return phone;
    }

    /**
     * Load the rotation details from the XML application.
     *
     * @param root the root of the XML application
     * @param guid the guid
     * @param recordId the record id
     * @return the rotation bean
     */
    private RotationBean loadRotationDetails(final Element root, final int guid, final String recordId) {

        RotationBean rtn = new RotationBean();

        PreferencesBean pref = loadPreferences();

        rtn.setPersonId(guid);
        rtn.setRotationType("Basic Training");
        rtn.setCommitteeName(rotationDAO.getCommitteeName());

        List<?> records = root.getChildren("rotation");
        for (Object obj : records) {
            // Get the rotation record
            Element record = (Element) obj;

            String recordNumber = "";
            try {
                recordNumber = record.getChildText("recordnumber").trim();
            } catch (Exception e) {
                dataLogger.error("Error parsing recordnumber: " + e.getMessage());
            }

            if (StringUtils.equalsIgnoreCase(recordNumber, recordId)) {
                try {
                    rtn.setDescription(record.getChildText("SubSpecialty").trim());
                } catch (Exception e) {
                    dataLogger.error("Error parsing StartDate: " + e.getMessage());
                }
                try {
                    rtn.setStartDate(parseDate(record.getChildText("StartDate").trim()));
                } catch (Exception e) {
                    dataLogger.error("Error parsing StartDate: " + e.getMessage());
                }
                try {
                    rtn.setEndDate(parseDate(record.getChildText("FinishDate").trim()));
                } catch (Exception e) {
                    dataLogger.error("Error parsing FinishDate: " + e.getMessage());
                }

                double trainingTime = 100;
                try {
                    trainingTime = Double.parseDouble(record.getChildText("Perc").trim());
                } catch (Exception e) {
                    dataLogger.error("Error parsing Perc: " + e.getMessage());
                }
                rtn.setTrainingTime(trainingTime / 100);

                // Set the organisation details
                try {
                    rtn.setOrganisation1Name(record.getChildText("PrimHospital").trim());
                } catch (Exception e) {
                    dataLogger.error("Error parsing PrimHospital: " + e.getMessage());
                }
                rtn.setOrganisation1Type("Primary");

                try {
                    String secOrg = record.getChildText("SecHospital").trim();
                    if (!StringUtils.equalsIgnoreCase(rtn.getOrganisation1Name(), secOrg)) {
                        rtn.setOrganisation2Name(secOrg);
                    }
                } catch (Exception e) {
                    dataLogger.error("Error parsing SecHospital: " + e.getMessage());
                }
                rtn.setOrganisation2Type("Training");

                // Identify the division of the rotation
                String division = "A";
                try {
                    division = record.getChildText("AdultPaed").trim();
                } catch (Exception e) {
                    dataLogger.error("Error parsing AdultPaed: " + e.getMessage());
                }

                rtn.setSupervisors(loadSupervisors(record, division));

                rtn.setAssessment(loadAssessment(record, division, pref));

                rtn.setAccreditation(loadAccreditation(record));
            }
        }

        if (StringUtils.isBlank(rtn.getDescription())) {
            // This is not a valid rotation
            rtn = null;
        }

        return rtn;
    }

    /**
     * Load the person for the supplied guid.
     *
     * @param guid the guid
     * @return the person bean
     */
    private PersonBean loadPerson(final int guid) {

        PersonBean person = new PersonBean();
        try {
            person = this.personDAO.loadGUID(guid);
        } catch (WhichDoctorDaoException wde) {
            dataLogger.error("Error loading person: " + wde.getMessage());
        }
        return person;
    }

    /**
     * Load the supervisor for the supplied personal identifier (MIN) number.
     *
     * @param personalIdentifier the personal identifier (MIN)
     * @return the person bean
     */
    private PersonBean loadSupervisor(final int personalIdentifier) {

        PersonBean person = new PersonBean();
        try {
            person = this.personDAO.loadIdentifier(personalIdentifier);
        } catch (WhichDoctorDaoException wde) {
            dataLogger.error("Error loading supervisor: " + wde.getMessage());
        }
        return person;
    }

    /**
     * Load preferences.
     *
     * @return the preferences bean
     */
    private PreferencesBean loadPreferences() {
        PreferencesBean preferences = new PreferencesBean();
        try {
            preferences = this.preferencesDAO.load();
        } catch (WhichDoctorDaoException wde) {
            dataLogger.error("Error loading preferences: " + wde.getMessage());
        }
        return preferences;
    }

    /**
     * Load supervisor types.
     *
     * @return the tree map
     */
    private TreeMap<String, TreeMap<String, Integer>> loadSupervisorTypes() {
        TreeMap<String, TreeMap<String, Integer>> supervisorTypes = new TreeMap<String, TreeMap<String, Integer>>();

        try {
            supervisorTypes = relationshipDAO.loadRelationships("Basic Training Supervisor", 2);
        } catch (WhichDoctorDaoException wde) {
            dataLogger.error("Error loading supervisors: " + wde.getMessage());
        }
        return supervisorTypes;
    }

    /**
     * Load the supervisors.
     *
     * @param record the record
     * @param division the division
     * @return the collection
     */
    private Collection<SupervisorBean> loadSupervisors(final Element record, final String division) {

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

        // Set the supervisor details
        int supervisorMIN = 0;
        int educationalSupervisorMIN = 0;
        int pdaSupervisorMIN = 0;

        try {
            supervisorMIN = Integer.parseInt(record.getChild("Supervisor").getAttributeValue("id"));
        } catch (Exception e) {
            dataLogger.error("Error parsing Supervisor: " + e.getMessage());
        }

        try {
            educationalSupervisorMIN = Integer
                    .parseInt(record.getChild("EducationalSupervisor").getAttributeValue("id"));
        } catch (Exception e) {
            dataLogger.error("Error parsing EducationalSupervisor: " + e.getMessage());
        }

        try {
            pdaSupervisorMIN = Integer.parseInt(record.getChild("PDASupervisor").getAttributeValue("id"));
        } catch (Exception e) {
            dataLogger.error("Error parsing PDASupervisor: " + e.getMessage());
        }

        if (supervisorMIN > 0) {
            PersonBean person = loadSupervisor(supervisorMIN);

            if (person != null && person.getGUID() > 0) {
                SupervisorBean supervisor = new SupervisorBean();
                supervisor.setRelationshipClass("Basic Training Supervisor");
                supervisor.setRelationshipType("DPE (" + division + ")");
                supervisor.setSupervisorClass("rotation");
                supervisor.setOrderId(1);
                supervisor.setPerson(person);

                supervisors.add(supervisor);
            }
        }

        if (educationalSupervisorMIN > 0) {
            PersonBean person = loadSupervisor(educationalSupervisorMIN);

            if (person != null && person.getGUID() > 0) {
                SupervisorBean supervisor = new SupervisorBean();
                supervisor.setRelationshipClass("Basic Training Supervisor");
                supervisor.setRelationshipType("Education");
                supervisor.setSupervisorClass("rotation");
                supervisor.setOrderId(2);
                supervisor.setPerson(person);

                supervisors.add(supervisor);
            }
        }

        if (pdaSupervisorMIN > 0) {
            PersonBean person = loadSupervisor(pdaSupervisorMIN);

            if (person != null && person.getGUID() > 0) {
                SupervisorBean supervisor = new SupervisorBean();
                supervisor.setRelationshipClass("Basic Training Supervisor");
                supervisor.setRelationshipType("PDA");
                supervisor.setSupervisorClass("rotation");
                supervisor.setOrderId(3);
                supervisor.setPerson(person);

                supervisors.add(supervisor);
            }
        }

        return supervisors;
    }

    /**
     * Load the assessment.
     *
     * @param record the record
     * @param division the division
     * @param preferences the preferences
     * @return the collection
     */
    private Collection<AssessmentBean> loadAssessment(final Element record, final String division,
            final PreferencesBean preferences) {

        Collection<AssessmentBean> assessments = new ArrayList<AssessmentBean>();

        // A basic rotation has one set of assessments associated to it
        AssessmentBean assessment = new AssessmentBean();
        assessment.setAssessmentType("Standard");
        assessment.setApproved("Not reviewed");
        assessment.setStatus("Not accredited");

        // Build the notes
        StringBuffer sb = new StringBuffer();
        sb.append(processNote(record, "StaffNotes", "Staff notes"));
        sb.append(processNote(record, "DPTNotes", "DPT notes"));
        sb.append(processNote(record, "StaffTraineeNotes", "Trainee notes"));

        assessment.setAccreditationComment(sb.toString());

        if (preferences != null) {
            assessment.setCommitteeSpecialty(preferences.getOption("specialty", "adult"));

            if (StringUtils.startsWithIgnoreCase(division, "P")) {
                assessment.setCommitteeSpecialty(preferences.getOption("specialty", "paediatric"));
            }
        }
        assessments.add(assessment);

        return assessments;
    }

    /**
     * Load the accreditation.
     *
     * @param record the record
     * @return the collection
     */
    private Collection<AccreditationBean> loadAccreditation(final Element record) {
        Collection<AccreditationBean> accreditations = new ArrayList<AccreditationBean>();

        AccreditationBean core = new AccreditationBean();
        core.setCore(true);

        AccreditationBean nonCore = new AccreditationBean();
        nonCore.setCore(false);

        try {
            int weeks = Integer.parseInt(record.getChildText("CoreWks"));
            core.setWeeksApproved(weeks);
        } catch (Exception e) {
            dataLogger.error("Error parsing CoreWks: " + e.getMessage());
        }
        try {
            int weeks = Integer.parseInt(record.getChildText("NonCoreWks"));
            nonCore.setWeeksApproved(weeks);
        } catch (Exception e) {
            dataLogger.error("Error parsing NonCoreWks: " + e.getMessage());
        }

        accreditations.add(core);
        accreditations.add(nonCore);

        return accreditations;
    }

    /**
     * Process note.
     *
     * @param record the record
     * @param key the key
     * @param title the title
     * @return the string
     */
    private String processNote(final Element record, final String key, final String title) {
        StringBuffer note = new StringBuffer();

        String noteText = record.getChildText(key);
        if (StringUtils.isNotBlank(noteText)) {
            note.append("<h3>");
            note.append(title);
            note.append(":</h3><p>");
            note.append(DataFilter.getHtml(noteText));
            note.append("</p>");
        }
        return note.toString();
    }

    /**
     * Load the debit details.
     *
     * @param record the record
     * @param guid the guid
     * @return the debit bean
     */
    private DebitBean loadDebitDetails(final Element record, final int guid) {
        DebitBean debit = new DebitBean();

        PreferencesBean preferences = loadPreferences();

        debit.setPersonId(guid);
        try {
            debit.setPerson(this.personDAO.loadGUID(guid));
        } catch (WhichDoctorDaoException wde) {
            dataLogger.error("Error loading person: " + wde.getMessage());
        }

        final Calendar calendar = Calendar.getInstance();
        final Date currentDate = new Date(calendar.getTimeInMillis());
        calendar.add(Calendar.DATE, preferences.getOptionAsInt("finance", "paymentdue"));
        final Date paymentDue = new Date(calendar.getTimeInMillis());

        debit.setIssued(currentDate);
        debit.setPaymentDue(paymentDue);
        debit.setGSTRate(preferences.getOptionAsDouble("finance", "gst"));
        debit.setCancelled(false);

        return debit;
    }

    /**
     * Parses the date.
     *
     * @param dateString the date string
     * @return the date
     */
    private Date parseDate(final String dateString) {

        Date date = null;
        try {
            final SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");
            date = df.parse(dateString);
        } catch (ParseException e) {
            // Error parsing date - catch but don't do anything
            date = null;
        }
        return date;
    }
}