com.sfs.whichdoctor.webservice.RotationXmlOutputImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.sfs.whichdoctor.webservice.RotationXmlOutputImpl.java

Source

/*******************************************************************************
 * Copyright (c) 2012 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.webservice;

import java.util.ArrayList;

import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
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.log4j.Logger;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;

import com.sfs.Formatter;
import com.sfs.beans.BuilderBean;
import com.sfs.whichdoctor.beans.AccreditationBean;
import com.sfs.whichdoctor.beans.AssessmentBean;
import com.sfs.whichdoctor.beans.OrganisationBean;
import com.sfs.whichdoctor.beans.PersonBean;
import com.sfs.whichdoctor.beans.ProjectBean;
import com.sfs.whichdoctor.beans.RelationshipBean;
import com.sfs.whichdoctor.beans.ReportBean;
import com.sfs.whichdoctor.beans.RotationBean;
import com.sfs.whichdoctor.beans.SpecialtyBean;
import com.sfs.whichdoctor.dao.OrganisationDAO;
import com.sfs.whichdoctor.dao.RelationshipDAO;
import com.sfs.whichdoctor.dao.WhichDoctorDaoException;
import com.sfs.whichdoctor.webservice.helper.RotationXmlHelper;
import com.sfs.whichdoctor.webservice.helper.ToolCount;
import com.sfs.whichdoctor.webservice.helper.ToolCounts;
import com.sfs.whichdoctor.webservice.helper.TrainingRequirement;

/**
 * The Class RotationXmlOutputImpl.
 */
public class RotationXmlOutputImpl implements RotationXmlOutput {

    /** The logger. */
    private static Logger logger = Logger.getLogger(RotationXmlOutputImpl.class);

    /** The Constant PERCENTAGE_MULTIPLIER. */
    private static final int PERCENTAGE_MULTIPLIER = 100;

    /** The Constant WORKING_DAYS. */
    private static final double WORKING_DAYS = 5;

    /** The organisation dao. */
    @Resource
    private OrganisationDAO organisationDAO;

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

    /** The relationship mapping. */
    private Map<String, String> relationshipMapping = new TreeMap<String, String>();

    /**
     * Sets the relationship mapping.
     * This is of the form WhichDoctor relationship type -> Web Service type.
     * e.g. Education -> edu
     *
     * @param relationshipMap the relationship map
     */
    public final void setRelationshipMapping(final Map<String, String> relationshipMap) {
        this.relationshipMapping = relationshipMap;
    }

    /**
     * Builds a list of rotations in the first-gen XML format.
     *
     * @param rotations the rotation array
     * @param personIdentifier the person identifier
     * @param division the division
     *
     * @return the rotations in the legacy XML format
     */
    public final String getFirstGenRotations(final List<RotationBean> rotations, final int personIdentifier,
            final String division) {

        int totalApprovedCore = 0;
        int totalApprovedNonCore = 0;
        int totalCertifiedCore = 0;
        int totalCertifiedNonCore = 0;
        int totalEligibleUnits = 0;
        int rotationCount = 0;
        double trainingTime = 0;

        Collection<RotationBean> basicRotations = new ArrayList<RotationBean>();
        Collection<Element> rtnsXml = new ArrayList<Element>();

        // Only the basic training rotations are required for legacy output
        for (RotationBean rtn : rotations) {
            if (StringUtils.equalsIgnoreCase(rtn.getRotationType(), "Basic Training")) {
                basicRotations.add(rtn);
            }
        }

        for (RotationBean rtn : basicRotations) {

            int approvedCore = 0;
            int approvedNonCore = 0;
            int certifiedCore = 0;
            int certifiedNonCore = 0;

            int eligibleUnits = (int) Formatter.round((rtn.getTotalDays() / WORKING_DAYS), 0);

            totalEligibleUnits += eligibleUnits;

            if (rtn.getAccreditation() != null) {
                for (AccreditationBean acn : rtn.getAccreditation()) {
                    if (acn.getCore()) {
                        approvedCore += acn.getWeeksApproved();
                        certifiedCore += acn.getWeeksCertified();
                    } else {
                        approvedNonCore += acn.getWeeksApproved();
                        certifiedNonCore += acn.getWeeksCertified();
                    }
                }
            }
            rotationCount++;

            totalApprovedCore += approvedCore;
            totalApprovedNonCore += approvedNonCore;
            totalCertifiedCore += certifiedCore;
            totalCertifiedNonCore += certifiedNonCore;

            Calendar startDate = Calendar.getInstance();
            Calendar endDate = Calendar.getInstance();
            if (rtn.getStartDate() != null) {
                startDate.setTime(rtn.getStartDate());
            }
            if (rtn.getEndDate() != null) {
                endDate.setTime(rtn.getEndDate());
            }

            // Add to the total training time
            trainingTime += rtn.getTrainingTime();

            Map<Integer, RelationshipBean> supervisors = this.relationshipDAO.getSupervisorMap(rtn);

            rtnsXml.add(RotationXmlHelper.getFirstGenRotationInfo(rtn, division, startDate, endDate, approvedCore,
                    approvedNonCore, certifiedCore, certifiedNonCore, eligibleUnits, supervisors,
                    this.relationshipMapping));
        }

        if (rotationCount > 0) {
            trainingTime = Formatter.round(trainingTime / rotationCount * PERCENTAGE_MULTIPLIER, 2);
        }

        Element xml = new Element("rotations");
        xml.setAttribute("min", String.valueOf(personIdentifier));

        xml.addContent(new Element("timeperc").setText(String.valueOf(trainingTime)));
        String partfull = "Part-time";
        if (trainingTime >= PERCENTAGE_MULTIPLIER) {
            partfull = "Full-time";
        }
        xml.addContent(new Element("partfull").setText(partfull));

        xml.addContent(new Element("totalcoreunits").setText(String.valueOf(totalApprovedCore)));
        xml.addContent(new Element("totalnoncoreunits").setText(String.valueOf(totalApprovedNonCore)));

        xml.addContent(new Element("totalaccredcoreunits").setText(String.valueOf(totalCertifiedCore)));
        xml.addContent(new Element("totalaccrednoncoreunits").setText(String.valueOf(totalCertifiedNonCore)));

        xml.addContent(new Element("totaleligunits").setText(String.valueOf(totalEligibleUnits)));

        xml.addContent(new Element("unitmeasure").setText("weeks"));
        xml.addContent(rtnsXml);

        XMLOutputter outputter = new XMLOutputter();
        Format format = Format.getCompactFormat();
        format.setOmitDeclaration(true);

        outputter.setFormat(format);

        return outputter.outputString(new Document(xml));
    }

    /**
     * Builds a list of rotations in the second-gen XML format.
     *
     * @param rotations the rotation array
     * @param personIdentifier the person identifier
     * @param division the division
     * @param currentRotations the current rotations
     *
     * @return the rotations in XML format
     */
    public final String getSecondGenRotations(final List<RotationBean> rotations, final int personIdentifier,
            final String division, final Collection<RotationBean> currentRotations) {

        Element xml = new Element("trainee");
        xml.setAttribute("MIN", String.valueOf(personIdentifier));

        // Process the current organisations
        TreeMap<String, Element> siteMap = new TreeMap<String, Element>();

        for (RotationBean rtn : currentRotations) {
            if (StringUtils.isNotBlank(rtn.getOrganisation1Name())) {
                Element site = new Element("site");
                String type = "primary";
                if (!StringUtils.equalsIgnoreCase(type, rtn.getOrganisation1TypeMapping())) {
                    // If not primary set the type to training
                    type = "training";
                }
                site.setAttribute("type", "current_" + type);
                site.setAttribute("state", loadOrgCity(rtn.getOrganisation1Id()));
                site.setAttribute("name", rtn.getOrganisation1Name());

                siteMap.put(type, site);
            }
            if (StringUtils.isNotBlank(rtn.getOrganisation2Name())) {
                Element site = new Element("site");
                String type = "training";
                if (siteMap.containsKey(type)) {
                    // Set to primary if the training key exists
                    type = "primary";
                }
                site.setAttribute("type", "current_" + type);
                site.setAttribute("state", loadOrgCity(rtn.getOrganisation2Id()));
                site.setAttribute("name", rtn.getOrganisation2Name());

                siteMap.put(type, site);
            }
        }

        if (siteMap.size() == 1) {
            for (String type : siteMap.keySet()) {
                Element site = siteMap.get(type);
                Element site2 = (Element) site.clone();

                String secondType = "training";
                if (StringUtils.equalsIgnoreCase(type, "training")) {
                    secondType = "primary";
                }
                site2.setAttribute("type", "current_" + secondType);

                siteMap.put(secondType, site2);
            }
        }

        Element sitesElement = new Element("sites");

        for (String type : siteMap.keySet()) {
            Element site = siteMap.get(type);
            sitesElement.addContent(site);
        }
        xml.addContent(sitesElement);

        Element rtnsXml = new Element("rotations");
        rtnsXml.setAttribute("min", String.valueOf(personIdentifier));

        for (RotationBean rtn : rotations) {

            rtnsXml.addContent(RotationXmlHelper.getSecondGenRotationInfo(rtn, division,
                    loadOrgCity(rtn.getOrganisation1Id()), loadOrgCity(rtn.getOrganisation2Id())));
        }
        xml.addContent(rtnsXml);

        XMLOutputter outputter = new XMLOutputter();
        Format format = Format.getCompactFormat();
        format.setOmitDeclaration(true);

        outputter.setFormat(format);

        return outputter.outputString(new Document(xml));
    }

    /**
     * Builds a list of rotations in the third-gen (PE1) XML format.
     *
     * @param rotations the rotation array
     * @param personIdentifier the person identifier
     * @param division the division
     * @param trainingType the training type
     * @return the rotations in XML format
     */
    public final String getThirdGenRotations(final List<RotationBean> rotations, final int personIdentifier,
            final String division, final String trainingType) {

        List<RotationBean> selectedRotations = new ArrayList<RotationBean>();

        if (rotations != null) {
            for (RotationBean rotation : rotations) {
                if (StringUtils.equalsIgnoreCase(trainingType, "BT")) {
                    // Only include basic training rotations
                    if (StringUtils.equalsIgnoreCase(rotation.getRotationType(), "Basic Training")) {
                        selectedRotations.add(rotation);
                    }
                } else {
                    // Exclude basic training rotations
                    if (!StringUtils.equalsIgnoreCase(rotation.getRotationType(), "Basic Training")) {
                        selectedRotations.add(rotation);
                    }
                }
            }
        }

        Element tnXml = new Element("Trainee");
        tnXml.setAttribute("min", String.valueOf(personIdentifier));

        Element rtnsXml = new Element("Rotations");

        for (RotationBean rtn : selectedRotations) {

            if (rtn.getAssessment() != null && rtn.getAssessment().size() > 0) {

                Map<Integer, Collection<AccreditationBean>> accreditationMap = getAccreditationMap(rtn);

                int i = 0;

                for (AssessmentBean assessment : rtn.getAssessment()) {

                    rtnsXml.addContent(RotationXmlHelper.getThirdGenRotationInfo(rtn, assessment,
                            accreditationMap.get(i), division, loadOrgCity(rtn.getOrganisation1Id()),
                            loadOrgCity(rtn.getOrganisation2Id())));

                    i++;
                }
            } else {
                rtnsXml.addContent(RotationXmlHelper.getThirdGenRotationInfo(rtn, new AssessmentBean(),
                        new ArrayList<AccreditationBean>(), division, loadOrgCity(rtn.getOrganisation1Id()),
                        loadOrgCity(rtn.getOrganisation2Id())));
            }
        }
        tnXml.addContent(rtnsXml);

        XMLOutputter outputter = new XMLOutputter();
        Format format = Format.getCompactFormat();
        format.setOmitDeclaration(true);

        outputter.setFormat(format);

        return outputter.outputString(new Document(tnXml));
    }

    /**
     * Builds the XML output for the training tool count.
     *
     * @param person the person
     * @param trainingType the training type
     * @return the tool count
     */
    public final String getToolCount(final PersonBean person, final String trainingType) {

        Map<String, ToolCounts> toolCounts = new TreeMap<String, ToolCounts>(Collections.reverseOrder());

        if (person != null) {
            if (person.getProjects() != null) {
                for (ProjectBean project : person.getProjects()) {
                    ToolCount tool = getToolCount(project, trainingType);
                    if (tool != null) {
                        ToolCounts tc = new ToolCounts();
                        tc.setMeasure("program");

                        if (project.getYear() > 0) {
                            tc.setMeasure("year");
                            tc.setYear(project.getYear());
                        }

                        if (toolCounts.containsKey(tc.getOrderKey())) {
                            tc = toolCounts.get(tc.getOrderKey());
                        }
                        tc.addManualToolCount(tool);

                        toolCounts.put(tc.getOrderKey(), tc);
                    }
                }
            }
            if (person.getRotations() != null) {
                for (RotationBean rotation : person.getRotations()) {
                    List<ToolCount> tools = getToolCounts(rotation, trainingType);

                    for (ToolCount tool : tools) {
                        // Need to check whether a manual or report
                        ToolCounts tc = new ToolCounts();
                        tc.setMeasure("year");
                        tc.setYear(rotation.getYear());

                        if (toolCounts.containsKey(tc.getOrderKey())) {
                            tc = toolCounts.get(tc.getOrderKey());
                        }
                        if (tool.isManualToolCount()) {
                            tc.addManualToolCount(tool);
                        } else {
                            tc.addReportToolCount(tool);
                        }
                        toolCounts.put(tc.getOrderKey(), tc);
                    }
                }
            }
        }

        Element xml = new Element("ToolCountsInfo");

        for (String key : toolCounts.keySet()) {
            ToolCounts tcs = toolCounts.get(key);

            Element tcsXml = new Element("ToolCounts");

            String measure = "program";
            String year = "";

            if (!StringUtils.equalsIgnoreCase(tcs.getMeasure(), "program")) {
                measure = "year";
                if (tcs.getYear() > 0) {
                    year = String.valueOf(tcs.getYear());
                }
            }
            tcsXml.setAttribute("measure", measure);
            tcsXml.setAttribute("year", year);

            if (tcs.getManualToolCounts().size() > 0) {
                tcsXml.addContent(getToolCountXml("manual", tcs.getManualToolCounts()));
            }
            if (tcs.getReportToolCounts().size() > 0) {
                tcsXml.addContent(getToolCountXml("report", tcs.getReportToolCounts()));
            }
            xml.addContent(tcsXml);
        }

        XMLOutputter outputter = new XMLOutputter();
        Format format = Format.getCompactFormat();
        format.setOmitDeclaration(true);

        outputter.setFormat(format);

        return outputter.outputString(new Document(xml));
    }

    /**
     * Gets the XML output for the training requirement years.
     *
     * @param person the person
     * @param trainingType the training type
     * @return the training requirement years
     */
    public final String getTrainingRequirementYears(final PersonBean person, final String trainingType) {

        Map<String, TrainingRequirement> requirements = new TreeMap<String, TrainingRequirement>();

        if (person != null) {
            if (person.getSpecialtyList() != null) {
                for (SpecialtyBean sp : person.getSpecialtyList()) {
                    TrainingRequirement requirement = getTrainingRequirement(person, sp, trainingType);
                    if (requirement != null) {
                        String key = "D:" + requirement.getDivision() + "-S:" + requirement.getTrainingProgram();

                        if (!requirements.containsKey(key)) {
                            requirements.put(key, requirement);
                        }
                    }
                }
            }

            // Iterate through the rotations to see what years are applicable
            // for the identified specialties.
            if (person.getRotations() != null) {
                for (String key : requirements.keySet()) {
                    TrainingRequirement requirement = requirements.get(key);

                    for (RotationBean rotation : person.getRotations()) {
                        int year = getTrainingRequirementYear(requirement, rotation);
                        requirement.addYearToList(year);
                    }
                }
            }
        }

        Element xml = new Element("Trainings");
        xml.setAttribute("type", trainingType);

        for (String key : requirements.keySet()) {
            TrainingRequirement requirement = requirements.get(key);

            Element req = new Element("RequirementYears");
            req.setAttribute("division", requirement.getDivision());
            req.setAttribute("country", requirement.getCountryAbbreviation());
            req.setAttribute("STP", requirement.getTrainingProgramShortName());

            String curriculumYear = "";
            if (requirement.getYear() > 0) {
                curriculumYear = String.valueOf(requirement.getYear());
            }
            req.setAttribute("curriculumYear", curriculumYear);

            for (Integer year : requirement.getYearList()) {
                if (year > 0) {
                    Element yr = new Element("Year").addContent(String.valueOf(year));
                    req.addContent(yr);
                }
            }
            xml.addContent(req);
        }

        XMLOutputter outputter = new XMLOutputter();
        Format format = Format.getCompactFormat();
        format.setOmitDeclaration(true);

        outputter.setFormat(format);

        return outputter.outputString(new Document(xml));
    }

    /**
     * Gets the training requirement. Returns null if not applicable.
     *
     * @param person the person
     * @param specialty the specialty
     * @param trainingType the training type
     * @return the training requirement
     */
    private TrainingRequirement getTrainingRequirement(final PersonBean person, final SpecialtyBean specialty,
            final String trainingType) {

        TrainingRequirement requirement = null;

        boolean includeSpecialty = false;
        String division = "", country = "", isbRole = "";

        if (StringUtils.equalsIgnoreCase(trainingType, "BT")) {
            // Basic training requirements
            if (StringUtils.equalsIgnoreCase(specialty.getTrainingProgram(), "Basic Training")) {

                division = "A";
                country = "NZ";
                includeSpecialty = true;

                if (StringUtils.equalsIgnoreCase(specialty.getTrainingOrganisation(), "RACP - Paediatric")) {
                    division = "P";
                }

                if (StringUtils.equalsIgnoreCase(person.getMembershipField("Status"),
                        "Active - within Australia")) {
                    country = "AU";
                }
            }
        } else {
            // Assume AT/Post-FRACP requirements
            if (!StringUtils.equalsIgnoreCase(specialty.getTrainingProgram(), "Basic Training")) {
                includeSpecialty = true;
                isbRole = specialty.getIsbRole(2);
            }
        }

        if (includeSpecialty) {
            requirement = new TrainingRequirement();
            requirement.setDivision(division);
            requirement.setTrainingType(trainingType);
            requirement.setTrainingOrganisation(specialty.getTrainingOrganisation());
            requirement.setTrainingProgram(specialty.getTrainingProgram());
            requirement.setTrainingProgramISBMapping(isbRole);
            requirement.setYear(specialty.getTrainingProgramYear());
            requirement.setCountryAbbreviation(country);
        }
        return requirement;
    }

    /**
     * Gets the training requirement year.
     *
     * @param requirement the requirement
     * @param rotation the rotation
     * @return the training requirement year
     */
    private int getTrainingRequirementYear(final TrainingRequirement requirement, final RotationBean rotation) {

        int year = 0;

        if (rotation.getAssessment() != null) {
            for (AssessmentBean assessment : rotation.getAssessment()) {
                if (StringUtils.equalsIgnoreCase(requirement.getTrainingOrganisation(),
                        assessment.getTrainingOrganisation())
                        && StringUtils.equalsIgnoreCase(requirement.getTrainingProgram(),
                                assessment.getTrainingProgram())) {
                    // Organisation and training programs match - set year.
                    year = rotation.getYear();
                }
            }
        }
        return year;
    }

    /**
     * Gets the tool count. Returns null if not valid for the training type.
     *
     * @param project the project
     * @param trainingType the training type
     * @return the tool count
     */
    private ToolCount getToolCount(final ProjectBean project, final String trainingType) {

        ToolCount tool = null;

        if (!StringUtils.equalsIgnoreCase(trainingType, "BT")) {
            tool = new ToolCount();

            tool.setManualToolCount(true);
            tool.setName(project.getAssessmentType());
            tool.setSubName(project.getProjectType());
            tool.setTrainingType(trainingType);
            tool.setTrainingProgramISBMapping(project.getTrainingProgramISBMapping());
        }
        return tool;
    }

    /**
     * Gets the tool counts for a rotation.
     *
     * @param rt the rt
     * @param trainingType the training type
     * @return the tool counts
     */
    private List<ToolCount> getToolCounts(final RotationBean rt, final String trainingType) {

        List<ToolCount> tools = new ArrayList<ToolCount>();
        Map<String, ToolCount> toolHits = new TreeMap<String, ToolCount>();
        boolean processReports = false;

        if (rt != null) {
            if (StringUtils.equalsIgnoreCase(rt.getRotationType(), "Basic Training")
                    && StringUtils.equalsIgnoreCase(trainingType, "BT")) {
                // This is a basic training rotation and BT has been requested
                processReports = true;
            }
            if (!StringUtils.equalsIgnoreCase(rt.getRotationType(), "Basic Training")
                    && !StringUtils.equalsIgnoreCase(trainingType, "BT")) {
                // This is not a basic training rotation an BT has not been requested
                processReports = true;
            }
        }

        if (processReports && rt.getReports() != null) {
            for (ReportBean report : rt.getReports()) {
                if (report.getReportPublish()) {

                    ToolCount tc = new ToolCount();

                    tc.setName(report.getReportType());

                    if (StringUtils.equalsIgnoreCase(report.getReportGrouping(), "Manual")) {
                        tc.setManualToolCount(true);
                    }

                    String key = report.getReportOrder() + "_" + report.getReportType();
                    toolHits.put(key, tc);
                }
            }
        }

        for (String key : toolHits.keySet()) {
            ToolCount tc = toolHits.get(key);
            tools.add(tc);
        }
        return tools;
    }

    /**
     * Gets the accreditation map.
     *
     * @param rotation the rotation
     * @return the accreditation map
     */
    private Map<Integer, Collection<AccreditationBean>> getAccreditationMap(final RotationBean rotation) {

        Map<Integer, Collection<AccreditationBean>> accreditationMap = new HashMap<Integer, Collection<AccreditationBean>>();

        if (rotation != null && rotation.getAccreditation() != null) {

            if (rotation.getAssessment().size() > 1) {

                Map<String, Collection<AccreditationBean>> accreditedSpecialties = new HashMap<String, Collection<AccreditationBean>>();

                for (AccreditationBean accreditation : rotation.getAccreditation()) {

                    String key = accreditation.getSpecialtyType();

                    Collection<AccreditationBean> accreditations = new ArrayList<AccreditationBean>();

                    if (accreditedSpecialties.containsKey(key)) {
                        accreditations = accreditedSpecialties.get(key);
                    }
                    accreditations.add(accreditation);

                    accreditedSpecialties.put(key, accreditations);
                }

                int i = 0;

                for (AssessmentBean asmt : rotation.getAssessment()) {

                    String key = asmt.getCommitteeSpecialty();

                    Collection<AccreditationBean> accreditations = new ArrayList<AccreditationBean>();

                    if (accreditedSpecialties.containsKey(key)) {
                        accreditations = accreditedSpecialties.get(key);
                    }
                    accreditationMap.put(i, accreditations);
                    accreditedSpecialties.remove(key);

                    i++;
                }

                // Any accreditation left in the map is added to the first assessment
                Collection<AccreditationBean> firstAccreds = accreditationMap.get(0);

                for (String key : accreditedSpecialties.keySet()) {
                    Collection<AccreditationBean> accred = accreditedSpecialties.get(key);

                    for (AccreditationBean accreditation : accred) {
                        firstAccreds.add(accreditation);
                    }
                }
                accreditationMap.put(0, firstAccreds);

            } else {
                accreditationMap.put(0, rotation.getAccreditation());
            }
        }

        return accreditationMap;
    }

    /**
     * Gets the tool count xml.
     *
     * @param type the type
     * @param toolCounts the tool counts
     * @return the tool count xml
     */
    private Element getToolCountXml(final String type, final TreeMap<String, ToolCount> toolCounts) {

        Element tctXml = new Element("ToolCountType");
        tctXml.setAttribute("name", type);

        for (String id : toolCounts.keySet()) {
            ToolCount tc = toolCounts.get(id);

            Element tcXml = new Element("ToolCount");
            tcXml.setAttribute("name", tc.getName());
            tcXml.setAttribute("subName", tc.getSubName());
            tcXml.setAttribute("STP", tc.getTrainingProgramShortName());
            tcXml.addContent(String.valueOf(tc.getCount()));

            tctXml.addContent(tcXml);
        }
        return tctXml;
    }

    /**
     * Load the city associated with the organisation.
     *
     * @param organisationGUID the organisation guid
     * @return the string
     */
    private String loadOrgCity(final int organisationGUID) {

        String city = "";

        if (organisationGUID > 0) {
            // Load the organisation in order to get its city
            try {
                BuilderBean loadDetails = new BuilderBean();
                loadDetails.setParameter("ADDRESS", true);
                OrganisationBean org = this.organisationDAO.loadGUID(organisationGUID, loadDetails);
                if (org.getFirstAddress() != null) {
                    city = org.getFirstAddress().getCity();
                }
            } catch (WhichDoctorDaoException wde) {
                logger.error("Error loading organisation: " + wde.getMessage());
            }
        }
        return city;
    }
}