Package uk.nhs.interoperability.payloads.helpers

Source Code of uk.nhs.interoperability.payloads.helpers.EndOfLifeCareDocumentCreationHelper

/*
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
package uk.nhs.interoperability.payloads.helpers;

import java.util.Date;
import java.util.List;

import uk.nhs.interoperability.payloads.CodedValue;
import uk.nhs.interoperability.payloads.DateValue;
import uk.nhs.interoperability.payloads.endoflifecarev1.*;
import uk.nhs.interoperability.payloads.templates.*;
import uk.nhs.interoperability.payloads.commontypes.*;
import uk.nhs.interoperability.payloads.exceptions.MissingMandatoryFieldException;
import uk.nhs.interoperability.payloads.util.CDAUUID;
import uk.nhs.interoperability.payloads.util.Logger;
import uk.nhs.interoperability.payloads.vocabularies.generated.*;
import uk.nhs.interoperability.payloads.vocabularies.internal.*;

public class EndOfLifeCareDocumentCreationHelper {

  public static ClinicalDocument createDocument(EndOfLifeCareISBFields isbFields) throws MissingMandatoryFieldException {
    ClinicalDocument template = new ClinicalDocument();
    MissingMandatoryFieldException missingFields = new MissingMandatoryFieldException();
    DateValue currentDateTime = new DateValue(new Date(), DatePrecision.Minutes);
   
    // ==== We will assume some things and set them accordingly ====
    template.setDocumentId(CDAUUID.generateUUIDString());
    template.setDocumentTitle("End of Life Care Coordination Summary");
    template.setConfidentialityCode(x_BasicConfidentialityKind._N);
   
    // If no record effective date/time specified, assume the current date/time
    if (isbFields.getDocumentCreationDate() == null) {
      template.setEffectiveTime(currentDateTime);
    } else {
      template.setEffectiveTime(isbFields.getDocumentCreationDate());
    }
   
    // If no document set ID provided, generate a new one
    if (isbFields.getDocumentSetId() != null) {
      template.setDocumentSetId(isbFields.getDocumentSetId());
    } else {
      template.setDocumentSetId(CDAUUID.generateUUIDString());
    }
   
    // Version defaults to 1 unless set to a different integer value
    template.setDocumentVersionNumber(String.valueOf(isbFields.getDocumentVersionNumber()));
   
    // Patient
    try {
      PatientUniversal patient = createPatient(isbFields);
      template.setPatient(patient);
    } catch (MissingMandatoryFieldException e) {
      missingFields.addMissingFields(e);
    }
   
    // Author
    if (isbFields.getDocumentAuthoredTime() == null) {
      template.setTimeAuthored(currentDateTime);
    } else {
      template.setTimeAuthored(isbFields.getDocumentAuthoredTime());
    }
   
    try {
      AuthorPersonUniversal author = createAuthor(isbFields);
      template.setAuthor(author);
    } catch (MissingMandatoryFieldException e) {
      missingFields.addMissingFields(e);
    }
   
    // Custodian (Organisation hosting the EPaCCS)
    try {
      CustodianOrganizationUniversal custodian = createCustodian(isbFields);
      template.setCustodianOrganisation(custodian);
    } catch (MissingMandatoryFieldException e) {
      missingFields.addMissingFields(e);
    }
   
    // Recipients - this is not part of the core ISB data set, and may not be
    // relevant depending on how the EPaCCS works (e.g. send document on-demand), so
    // we won't do anything with recipients in this helper. These can easily be added
    // to the document afterwards by calling the relevant methods.

    // ==== Now create the coded sections ====
    EoLCarePlan carePlan;
    AdvanceDecisionToRefuseTreatment adrt;
    AnticipatoryMedicineBoxIssueProcedure ambox;
    DNACPRDecisionbySeniorResponsibleClinician dnacpr;
    PrognosisAwareness prognosis;
    AuthoritytoLastingPowerofAttorney lpa;
   
    // End of Life Care Plan
    try {
      carePlan = createEoLCarePlan(isbFields);
      template.addCodedSections(new CodedSections(carePlan));
    } catch (MissingMandatoryFieldException e) {
      missingFields.addMissingFields(e);
    }

    // Advance decision to refuse treatment
    try {
      adrt = createADRT(isbFields);
      if (adrt != null) {
        template.addCodedSections(new CodedSections(adrt));
      }
    } catch (MissingMandatoryFieldException e) {
      missingFields.addMissingFields(e);
    }

    // Anticipatory medicine box
    try {
      ambox = createAMBox(isbFields);
      if (ambox != null) {
        template.addCodedSections(new CodedSections(ambox));
      }
    } catch (MissingMandatoryFieldException e) {
      missingFields.addMissingFields(e);
    }
   
    // DNACPR Decision
    try {
      dnacpr = createDNACPR(isbFields);
      if (dnacpr != null) {
        template.addCodedSections(new CodedSections(dnacpr));
      }
    } catch (MissingMandatoryFieldException e) {
      missingFields.addMissingFields(e);
    }
   
    // Main informal carer awareness of prognosis
    try {
      prognosis = createPrognosisAwareness(isbFields);
      if (prognosis != null) {
        template.addCodedSections(new CodedSections(prognosis));
      }
    } catch (MissingMandatoryFieldException e) {
      missingFields.addMissingFields(e);
    }
   
    // Authority to Lasting Power of Attorney
    try {
      lpa = createLPA(isbFields);
      if (lpa != null) {
        template.addCodedSections(new CodedSections(lpa));
      }
    } catch (MissingMandatoryFieldException e) {
      missingFields.addMissingFields(e);
    }
   
    // Additional mandatory field checks for text sections
    if (isbFields.getPrimaryEOLCDiagnosis() == null) {
      missingFields.addMissingField("PrimaryEOLCDiagnosis", "A primary EOLC Diagnosis must be provided");
    }

    // We have done all the checks on mandatory fields, so if there are any
    // errors, throw them up to the caller
    if (missingFields.hasEntries()) {
      throw missingFields;
    }
   
    // ==== Now create the text sections ====
    template.setMainDocumentSectionID(CDAUUID.generateUUIDString());
   
    template.addTextSections(new TextSections(createTextSection1_GeneralDocumentInformation(isbFields)));
    template.addTextSections(new TextSections(createTextSection2_PatientRelationships(isbFields)));

    TextSection ts3 = createTextSection_EOLToolUsed(isbFields);
    if (ts3 != null) template.addTextSections(new TextSections(ts3));
   
    TextSection ts4 = createTextSection4_PatientChoices(isbFields);
    if (ts4 != null) template.addTextSections(new TextSections(ts4));
   
    TextSection ts5 = createTextSection5_AdvanceStatements(isbFields);
    if (ts5 != null) template.addTextSections(new TextSections(ts5));
   
    TextSection ts6 = createTextSection6_DNACPR(isbFields);
    if (ts6 != null) template.addTextSections(new TextSections(ts6));
   
    TextSection ts7 = createTextSection7_Observations(isbFields);
    if (ts7 != null) template.addTextSections(new TextSections(ts7));
   
    TextSection ts8 = createTextSection8_AnticipatoryMedication(isbFields);
    if (ts8 != null) template.addTextSections(new TextSections(ts8));
   
    TextSection ts9 = createTextSection9_EPaCCSLink(isbFields);
    if (ts9 != null) template.addTextSections(new TextSections(ts9));
   
    return template;
  }
 
  public static PatientUniversal createPatient(EndOfLifeCareISBFields isbFields) throws MissingMandatoryFieldException {
    MissingMandatoryFieldException missingFields = new MissingMandatoryFieldException();
   
    // Null checks for mandatory fields
    if (isbFields.getPatientNHSNoIsTraced() == null) {
      missingFields.addMissingField("PatientNHSNoIsTraced", "The tracing status for the NHS number must be provided");
    }
    if (isbFields.getPatientNHSNo() == null) {
      missingFields.addMissingField("PatientNHSNo", "The patient's NHS number must be provided");
    }
    if (isbFields.getPatientAddress() == null) {
      missingFields.addMissingField("PatientAddress", "The patient's address must be provided");
    }
    if (isbFields.getPatientName() == null) {
      missingFields.addMissingField("PatientName", "The patient's name must be provided");
    }
    if (isbFields.getPatientGender() == null) {
      missingFields.addMissingField("PatientGender", "The patient's gender must be provided");
    }
    if (isbFields.getPatientBirthDate() == null) {
      missingFields.addMissingField("PatientBirthDate", "The patient's date of birth must be provided");
    }
    if (isbFields.getUsualGPODSCode() == null) {
      missingFields.addMissingField("UsualGPODSCode", "The usual GP's ODS Code must be provided");
    }
    if (isbFields.getUsualGPOrgName() == null) {
      missingFields.addMissingField("UsualGPOrgName", "The usual GP's organisation name must be provided");
    }
    if (isbFields.getUsualGPName() == null) {
      missingFields.addMissingField("UsualGPName", "The usual GP's name must be provided");
    }
    if (missingFields.hasEntries()) {
      throw missingFields;
    }
   
    PatientUniversal template = new PatientUniversal();
    // NHS Number and trace status
    if (isbFields.getPatientNHSNoIsTraced().booleanValue()) {
      template.addPatientID(new PatientID().setPatientID(isbFields.getPatientNHSNo())
                    .setPatientIDType(PatientIDType.VerifiedNHSNumber.code));
    } else {
      template.addPatientID(new PatientID().setPatientID(isbFields.getPatientNHSNo())
          .setPatientIDType(PatientIDType.UnverifiedNHSNumber.code));
    }
   
    // Address
    template.addAddress(isbFields.getPatientAddress());
   
    // Telephone
    if (isbFields.getPatientTelephone() != null) {
      template.addTelephoneNumber(new Telecom()
                  .setTelecom("tel:" + isbFields.getPatientTelephone()));
    }
   
    // Mobile
    if (isbFields.getPatientMobile() != null) {
      template.addTelephoneNumber(new Telecom()
                  .setTelecom("tel:" + isbFields.getPatientMobile())
                  .setTelecomType(TelecomUseType.MobileContact.code));
    }
   
    // Name
    template.addPatientName(isbFields.getPatientName());

    // Preferred name
    if (isbFields.getPatientPreferredName() != null) {
      PersonName preferred = isbFields.getPatientPreferredName();
      preferred.setNameType(PersonNameType.Preferred.code);
      template.addPatientName(preferred);
    }
   
    // Gender (actually sex)
    if (isbFields.getPatientGender() != null) {
      template.setSex(isbFields.getPatientGender());
    }

    // Date of birth
    template.setBirthTime(isbFields.getPatientBirthDate());
   
    // Preferred Spoken Language
    if (isbFields.getPatientPreferredSpokenLanguage() != null) {
      LanguageCommunication language = new LanguageCommunication();
      language.setLanguage(isbFields.getPatientPreferredSpokenLanguage().code);
      language.setPreferenceInd("true");
     
      // Interpreter required
      if (isbFields.isPatientInterpreterNeeded()) {
        if (isbFields.getPatientPreferredSpokenLanguage().code.equals(HumanLanguage._en.code)) {
          // Preferred language is English, but interpreter is required
          language.setProficiencyLevel(LanguageAbilityProficiency._1);
        } else {
          // Preferred langage is not English, and an interpreter is needed for
          // English, so we need a second language entry for English
          LanguageCommunication english = new LanguageCommunication();
          english.setLanguage(HumanLanguage._en.code);
          english.setProficiencyLevel(LanguageAbilityProficiency._1);
          template.addLanguages(english);
        }
      }
      template.addLanguages(language);
    } else {
      if (isbFields.isPatientInterpreterNeeded()) {
        // Interpreter required (no preferred language specified)
        LanguageCommunication english = new LanguageCommunication();
        english.setLanguage(HumanLanguage._en.code);
        english.setProficiencyLevel(LanguageAbilityProficiency._1);
        template.addLanguages(english);
      }
    }
   
    // Usual GP ODS Code:
    template.setRegisteredGPOrgId(new OrgID()
                  .setID(isbFields.getUsualGPODSCode())
                  .setType(OrgIDType.ODSOrgID.code));
   
    // Usual GP Org Name
    template.setRegisteredGPOrgName(isbFields.getUsualGPOrgName());
   
    // Usual GP Telephone
    if (isbFields.getUsualGPTelephone() != null) {
      template.addRegisteredGPTelephone(new Telecom()
                  .setTelecom("tel:" + isbFields.getUsualGPTelephone())
                  .setTelecomType(TelecomUseType.WorkPlace.code));
    }
   
    // Usual GP Fax
    if (isbFields.getUsualGPFax() != null) {
      template.addRegisteredGPTelephone(new Telecom()
                  .setTelecom("fax:" + isbFields.getUsualGPFax())
                  .setTelecomType(TelecomUseType.WorkPlace.code));
    }
   
    // Usual GP Address
    if (isbFields.getUsualGPAddress() != null) {
      Address add = isbFields.getUsualGPAddress();
      add.setAddressUse(AddressType.WorkPlace.code);
      template.setRegisteredGPAddress(add);
    }
   
    return template;
  }
 
  public static AuthorPersonUniversal createAuthor(EndOfLifeCareISBFields isbFields) throws MissingMandatoryFieldException {
    MissingMandatoryFieldException missingFields = new MissingMandatoryFieldException();
   
    // Null checks for mandatory fields
    if (isbFields.getDocumentAuthorSDSID() == null) {
      missingFields.addMissingField("DocumentAuthorSDSID", "The SDS ID of the document author must be provided");
    }
    if (isbFields.getDocumentAuthorRole() == null) {
      missingFields.addMissingField("DocumentAuthorRole", "The job role of the document author must be provided");
    }
    if (isbFields.getDocumentAuthorName() == null) {
      missingFields.addMissingField("DocumentAuthorName", "The name of the document author must be provided");
    }
    if (isbFields.getDocumentAuthorOrganisationODSID() == null) {
      missingFields.addMissingField("DocumentAuthorOrganisationODSID", "The ID of the organisation the document author belongs to must be provided");
    }
    if (isbFields.getDocumentAuthorOrganisationName() == null) {
      missingFields.addMissingField("DocumentAuthorOrganisationName", "The name of the organisation the document author belongs to must be provided");
    }
    if (missingFields.hasEntries()) {
      throw missingFields;
    }
   
    AuthorPersonUniversal template = new AuthorPersonUniversal();
     // Author SID ID
    template.addId(new PersonID()
             .setType(PersonIDType.SDSID.code)
             .setID(isbFields.getDocumentAuthorSDSID()));
   
    // Author Job Role
     template.setJobRoleName(isbFields.getDocumentAuthorRole());
    
     // Author Address
     if (isbFields.getDocumentAuthorAddress() != null) {
       Address add = isbFields.getDocumentAuthorAddress();
       add.setAddressUse(AddressType.WorkPlace.code);
       template.addAddress(add);
     }
    
     // Author telephone number
     if (isbFields.getDocumentAuthorTelephone() != null) {
       template.addTelephoneNumber(new Telecom("tel:" + isbFields.getDocumentAuthorTelephone()));
     }
    
     // Author Name
     template.setName(isbFields.getDocumentAuthorName());
    
     // Author ORG ID
    template.setOrganisationId(new OrgID()
                  .setID(isbFields.getDocumentAuthorOrganisationODSID())
                  .setType(OrgIDType.ODSOrgID.code));
   
    // Author ORG Name
    template.setOrganisationName(isbFields.getDocumentAuthorOrganisationName());
   
    return template;
  }
 
  public static CustodianOrganizationUniversal createCustodian(EndOfLifeCareISBFields isbFields) throws MissingMandatoryFieldException {
    MissingMandatoryFieldException missingFields = new MissingMandatoryFieldException();
    // Null checks for mandatory fields
    if (isbFields.getEPACCSOrganisationODSID() == null) {
      missingFields.addMissingField("EPACCSOrganisationODSID", "The ODS ID of the organisation hosting the EOL record must be provided");
    }
    if (isbFields.getEPACCSOrganisation() == null) {
      missingFields.addMissingField("EPACCSOrganisation", "The name of the organisation hosting the EOL record must be provided");
    }
    if (missingFields.hasEntries()) {
      throw missingFields;
    }
   
    CustodianOrganizationUniversal template = new CustodianOrganizationUniversal();
   
    // EPaCCS Hosting Org ID
    template.setId(new OrgID(OrgIDType.ODSOrgID.code, isbFields.getEPACCSOrganisationODSID()));
   
    // EPaCCS Hosting Org Name
    template.setName(isbFields.getEPACCSOrganisation());
   
    return template;
  }
 
  public static EoLCarePlan createEoLCarePlan(EndOfLifeCareISBFields isbFields) throws MissingMandatoryFieldException {
    MissingMandatoryFieldException missingFields = new MissingMandatoryFieldException();
    EoLCarePlan template = new EoLCarePlan();
   
    // Null checks for mandatory fields
    if (isbFields.getEpaccsRecordCreationDate() == null) {
      missingFields.addMissingField("EpaccsRecordCreationDate", "The creation date of the EPaCCS record must be provided");
    }
    // This may be an error in the DMS, so may not be mandatory in a later release
    if (isbFields.getEolcTool() == null) {
      missingFields.addMissingField("EolcTool", "The EOLC tool that is in use must be provided (e.g. LCP, PPC, GSF)");
    }
   
    // If any of the original EPaCCS author fields exist, check the mandatory author fields also exist
    boolean time = (isbFields.getEpaccsRecordAuthoredDate() != null);
    boolean add = (isbFields.getEpaccsRecordAuthorAddress() != null);
    boolean role = (isbFields.getEpaccsRecordAuthorRole() != null);
    boolean id = (isbFields.getEpaccsRecordAuthorSDSID() != null);
    boolean tel = (isbFields.getEpaccsRecordAuthorTelephone() != null);
    boolean name = (isbFields.getEpaccsRecordAuthorName() != null);
    boolean orgid = (isbFields.getEpaccsRecordAuthorOrganisationODSID() != null);
    boolean org = (isbFields.getEpaccsRecordAuthorOrganisationName() != null);
    boolean originalEPaCCSAuthorProvided = (time || add || role || id || tel || name || orgid || org);
    if (originalEPaCCSAuthorProvided) {
      if (!time) {
        missingFields.addMissingField("EpaccsRecordAuthoredDate", "If specifying the original EPaCCS author, the original authoring date must be provided");
      }
      if (!id) {
        missingFields.addMissingField("EpaccsRecordAuthorSDSID", "If specifying the original EPaCCS author, the original author's SDS ID must be provided");
      }
      if (!name) {
        missingFields.addMissingField("EpaccsRecordAuthorName", "If specifying the original EPaCCS author, the original author's name must be provided");
      }
      if (!orgid) {
        missingFields.addMissingField("EpaccsRecordAuthorOrganisationODSID", "If specifying the original EPaCCS author, the original author's organisation ODS ID must be provided");
      }
      if (!org) {
        missingFields.addMissingField("EpaccsRecordAuthorOrganisationName", "If specifying the original EPaCCS author, the original author's organisation name must be provided");
      }
    }
   
    // If any of the EPaCCS last amending author fields exist, check the mandatory author fields also exist
    boolean latime = (isbFields.getEpaccsRecordUpdatedDate() != null);
    boolean laadd = (isbFields.getEpaccsRecordUpdateAuthorAddress() != null);
    boolean larole = (isbFields.getEpaccsRecordUpdateAuthorRole() != null);
    boolean laid = (isbFields.getEpaccsRecordUpdateAuthorSDSID() != null);
    boolean latel = (isbFields.getEpaccsRecordUpdateAuthorTelephone() != null);
    boolean laname = (isbFields.getEpaccsRecordUpdateAuthorName() != null);
    boolean laorgid = (isbFields.getEpaccsRecordUpdateAuthorOrganisationODSID() != null);
    boolean laorg = (isbFields.getEpaccsRecordUpdateAuthorOrganisationName() != null);
    boolean laEPaCCSAuthorProvided = (latime || laadd || larole || laid || latel || laname || laorgid || laorg);
    if (laEPaCCSAuthorProvided) {
      if (!latime) {
        missingFields.addMissingField("EpaccsRecordUpdatedDate", "If specifying the last updating EPaCCS author, the last updated date must be provided");
      }
      if (!laid) {
        missingFields.addMissingField("EpaccsRecordUpdateAuthorSDSID", "If specifying the last updating EPaCCS author, the last updating author's SDS ID must be provided");
      }
      if (!laname) {
        missingFields.addMissingField("EpaccsRecordUpdateAuthorName", "If specifying the last updating EPaCCS author, the last updating author's name must be provided");
      }
      if (!laorgid) {
        missingFields.addMissingField("EpaccsRecordUpdateAuthorOrganisationODSID", "If specifying the last updating EPaCCS author, the last updating author's organisation ODS ID must be provided");
      }
      if (!laorg) {
        missingFields.addMissingField("EpaccsRecordUpdateAuthorOrganisationName", "If specifying the last updating EPaCCS author, the last updating author's organisation name must be provided");
      }
    }

    // Related persons - call this first so we can collate any other missing mandatory fields
    try {
      template.addPatientRelationships(new EOLPatientRelationships(createRelatedPersons(isbFields)));
    } catch (MissingMandatoryFieldException e) {
      missingFields.addMissingFields(e);
    }
     
    if (missingFields.hasEntries()) {
      throw missingFields;
    }

    // ================== Now set the values ==================
   
    template.setID(CDAUUID.generateUUIDString());
   
    // EPaCCS Record Creation Date
    template.setEffectiveFrom(isbFields.getEpaccsRecordCreationDate());
   
    // EPaCCS Record original author
    if (originalEPaCCSAuthorProvided) {
      // Authored date
      template.setOriginalTimeAuthored(isbFields.getEpaccsRecordAuthoredDate());
   
      AuthorPersonUniversal originalAuthor = new AuthorPersonUniversal();
     
      // Author SDS ID
      originalAuthor.addId(new PersonID()
                    .setID(isbFields.getEpaccsRecordAuthorSDSID())
                    .setType(PersonIDType.SDSID.code));
     
      // Author Role
      if (role) {
        originalAuthor.setJobRoleName(isbFields.getEpaccsRecordAuthorRole());
      }
     
      // Author Name
      originalAuthor.setName(isbFields.getEpaccsRecordAuthorName());
     
      // Author Telephone
      if (tel) {
        originalAuthor.addTelephoneNumber(new Telecom("tel:" + isbFields.getEpaccsRecordAuthorTelephone()));
      }
     
      if (add) {
        originalAuthor.addAddress(isbFields.getEpaccsRecordAuthorAddress());
      }
     
      // Author Org ID
      originalAuthor.setOrganisationId(new OrgID()
                    .setID(isbFields.getEpaccsRecordAuthorOrganisationODSID())
                    .setType(OrgIDType.ODSOrgID.code));
     
      // Author Org Name
      originalAuthor.setOrganisationName(isbFields.getEpaccsRecordAuthorOrganisationName());
     
      template.setOriginalAuthor(originalAuthor);
    }
   
    // EPaCCS Record Last Amending Author
    if (laEPaCCSAuthorProvided) {
      // Last amended date
      template.setLastAmendedTimeAuthored(isbFields.getEpaccsRecordUpdatedDate());
   
      AuthorPersonUniversal lastAmendingAuthor = new AuthorPersonUniversal();
     
      // Author SDS ID
      lastAmendingAuthor.addId(new PersonID()
                    .setID(isbFields.getEpaccsRecordUpdateAuthorSDSID())
                    .setType(PersonIDType.SDSID.code));
     
      // Author Role
      if (larole) {
        lastAmendingAuthor.setJobRoleName(isbFields.getEpaccsRecordUpdateAuthorRole());
      }
     
      // Author Name
      lastAmendingAuthor.setName(isbFields.getEpaccsRecordUpdateAuthorName());
     
      // Author Telephone
      if (latel) {
        lastAmendingAuthor.addTelephoneNumber(new Telecom("tel:" + isbFields.getEpaccsRecordUpdateAuthorTelephone()));
      }
     
      if (laadd) {
        lastAmendingAuthor.addAddress(isbFields.getEpaccsRecordUpdateAuthorAddress());
      }
     
      // Author Org ID
      lastAmendingAuthor.setOrganisationId(new OrgID()
                    .setID(isbFields.getEpaccsRecordUpdateAuthorOrganisationODSID())
                    .setType(OrgIDType.ODSOrgID.code));
     
      // Author Org Name
      lastAmendingAuthor.setOrganisationName(isbFields.getEpaccsRecordUpdateAuthorOrganisationName());
     
      template.setLastAmendedAuthor(lastAmendingAuthor);
    }
   
    // EOL Tool used
    if (isbFields.getEolcTool() != null) {
      template.setEoLToolSnCT(new CodedValue(isbFields.getEolcTool(), "#eolcTool"));
    }
   
    // EOLC Tool Pathway Stage
    if (isbFields.getEolcPathwayStageNONISB() != null) {
      template.setEOLToolStage(isbFields.getEolcPathwayStageNONISB());
    }
   
    // Planned Review Date
    if (isbFields.getEpaccsRecordReviewDate() != null) {
      template.setPlannedReviewDate(isbFields.getEpaccsRecordReviewDate());
    }
   
    return template;
  }
 
  /**
   * The main related persons listed in the ISB standard (with a few additional attributes to satisfy CDA spec) are:
   * <br>Main informal carer (name, tel)
   * <br>Usual GP (name, practice id, practice name, address, tel, fax)
   * <br>Key Worker (id, name, role, org id, org name, address, tel)
   * <br>Senior Responsible Clinician (name, id, role, org name, org id, add, tel)
   * <br>Formal Carers 0..N (name, role, tel)
   * <br>Lasting power of attorney (name, tel)
   * <br>First additional person to involve in decisions (name, tel)
   * <br>Second additional person to involve in decisions (name, tel)
   *
   * @param isbFields Fields to set in document
   * @return PatientRelationships
   * @throws MissingMandatoryFieldException Thrown if mandatory fields have not been provided, contains a list of missing fields.
   */
  public static PatientRelationships createRelatedPersons(EndOfLifeCareISBFields isbFields) throws MissingMandatoryFieldException {
    MissingMandatoryFieldException missingFields = new MissingMandatoryFieldException();
    // Null checks for mandatory fields
    // Check any formal carers provided at least have names
     List<EndOfLifeCareDocumentFormalCarer> carerlist = isbFields.getFormalCarers();
     if (carerlist != null) {
       for (EndOfLifeCareDocumentFormalCarer carerentry : carerlist) {
         if (carerentry.getName() == null) {
           missingFields.addMissingField("FormalCarers", "If specifying a formal carer, the name of the carer must be provided");
         }
       }
     }
   
    if (missingFields.hasEntries()) {
      throw missingFields;
   
   
    PatientRelationships template = new PatientRelationships();
   
     template.setID(CDAUUID.generateUUIDString());

     // Main informal carer (name, tel)
     if (isbFields.getMainInformalCarerName() != null) {
       PatientRelationshipParticipantRole mic = new PatientRelationshipParticipantRole();
       mic.setPersonRole(JobRoleName._NR1980);
       mic.setPersonName(isbFields.getMainInformalCarerName());
      
       if (isbFields.getMainInformalCarerTel() != null) {
         mic.addTelephoneNumber(new Telecom("tel:" + isbFields.getMainInformalCarerTel()));
       }
       template.addRelatedPerson(new RelatedPersonDetails().setParticipant(mic));
     }
    
     // Usual GP (name, practice id, practice name, address, tel, fax)
     if (isbFields.getUsualGPName() != null) {
       PatientRelationshipParticipantRole gp = new PatientRelationshipParticipantRole();
       gp.setPersonRole(JobRoleName._NR0260);
       // Name
       gp.setPersonName(isbFields.getUsualGPName());
       // Tel
       if (isbFields.getUsualGPTelephone() != null) {
         gp.addTelephoneNumber(new Telecom("tel:" + isbFields.getUsualGPTelephone()));
       }
       // Fax
       if (isbFields.getUsualGPFax() != null) {
         gp.addTelephoneNumber(new Telecom("fax:" + isbFields.getUsualGPFax()));
       }
       // Add
       if (isbFields.getUsualGPAddress() != null) {
         gp.setAddress(isbFields.getUsualGPAddress());
       }
       // ODS Code
       if (isbFields.getUsualGPODSCode() != null) {
         gp.setOrgId(new OrgID()
              .setID(isbFields.getUsualGPODSCode())
              .setType(OrgIDType.ODSOrgID.code));
       }
       // Practice Name
       if (isbFields.getUsualGPOrgName() != null) {
         gp.setOrgDescription(isbFields.getUsualGPOrgName());
       }
       template.addRelatedPerson(new RelatedPersonDetails().setParticipant(gp));
     }
    
     // Key Worker (id, name, role, org id, org name, address, tel)
     if (isbFields.getKeyWorkerName() != null) {
       PatientRelationshipParticipantRole kw = new PatientRelationshipParticipantRole();
       kw.setPersonRole(JobRoleName._NR2020);
       // Name
       kw.setPersonName(isbFields.getKeyWorkerName());
       // Job Role
       if (isbFields.getKeyWorkerJobRole() != null) {
         kw.setAssociatedJobRole(isbFields.getKeyWorkerJobRole());
       }
       // ID
       if (isbFields.getKeyWorkerSDSID() != null) {
         kw.addID(new PersonID()
                .setID(isbFields.getKeyWorkerSDSID())
                .setType(PersonIDType.SDSID.code));
       }
       // Tel
       if (isbFields.getKeyWorkerTelephone() != null) {
         kw.addTelephoneNumber(new Telecom("tel:" + isbFields.getKeyWorkerTelephone()));
       }
       // Address
       if (isbFields.getKeyWorkerAddress() != null) {
         kw.setAddress(isbFields.getKeyWorkerAddress());
       }
       // Org ID
      if (isbFields.getKeyWorkerOrgID() != null) {
        kw.setOrgId(new OrgID()
              .setID(isbFields.getKeyWorkerOrgID())
              .setType(OrgIDType.ODSOrgID.code));
      }
      // Org Name
      if (isbFields.getKeyWorkerOrgName() != null) {
        kw.setOrgDescription(isbFields.getKeyWorkerOrgName());
      }
     
       template.addRelatedPerson(new RelatedPersonDetails().setParticipant(kw));
     }
    
     // Formal Carers 0..N (name, role, tel)
     if (carerlist != null) {
       for (EndOfLifeCareDocumentFormalCarer carerentry : carerlist) {
         PatientRelationshipParticipantRole fc = new PatientRelationshipParticipantRole();
         fc.setPersonRole(JobRoleName._NR1990);
          // Name
         fc.setPersonName(carerentry.getName());
          // Tel
          if (carerentry.getTelephone() != null) {
            fc.addTelephoneNumber(new Telecom("tel:" + carerentry.getTelephone()));
          }
          // Job Role
          if (carerentry.getRole() != null) {
            fc.setAssociatedJobRole(carerentry.getRole());
          }
          template.addRelatedPerson(new RelatedPersonDetails().setParticipant(fc));
       }
     }
    
     // Lasting power of attorney (name, tel)
     if (isbFields.getLPAName() != null) {
       PatientRelationshipParticipantRole lpa = new PatientRelationshipParticipantRole();
       lpa.setPersonRole(JobRoleName._NR2010);
       // Name
       lpa.setPersonName(isbFields.getLPAName());
       // Tel
       if (isbFields.getLPATelephone() != null) {
         lpa.addTelephoneNumber(new Telecom("tel:" + isbFields.getLPATelephone()));
       }
       template.addRelatedPerson(new RelatedPersonDetails().setParticipant(lpa));
     }
    
     // First additional person to involve in decisions (name, tel)
     if (isbFields.getAdditionalPersonToInvolve() != null) {
       PatientRelationshipParticipantRole ap1 = new PatientRelationshipParticipantRole();
       ap1.setPersonRole(JobRoleName._NR2000);
       // Name
       ap1.setPersonName(isbFields.getAdditionalPersonToInvolve());
       // Tel
       if (isbFields.getAdditionalPersonToInvolveTel() != null) {
         ap1.addTelephoneNumber(new Telecom("tel:" + isbFields.getAdditionalPersonToInvolveTel()));
       }
       template.addRelatedPerson(new RelatedPersonDetails().setParticipant(ap1));
     }
    
     // Second additional person to involve in decisions (name, tel)
     if (isbFields.getAdditionalPersonToInvolve2() != null) {
       PatientRelationshipParticipantRole ap2 = new PatientRelationshipParticipantRole();
       ap2.setPersonRole(JobRoleName._NR2000);
       // Name
       ap2.setPersonName(isbFields.getAdditionalPersonToInvolve2());
       // Tel
       if (isbFields.getAdditionalPersonToInvolve2Tel() != null) {
         ap2.addTelephoneNumber(new Telecom("tel:" + isbFields.getAdditionalPersonToInvolve2Tel()));
       }
       template.addRelatedPerson(new RelatedPersonDetails().setParticipant(ap2));
     }
    
     // Senior Responsible Clinician (name, id, role, org name, org id, add, tel)
     if (isbFields.getSeniorResponsibleClinicianName() != null) {
       PatientRelationshipParticipantRole src = new PatientRelationshipParticipantRole();
       src.setPersonRole(JobRoleName._NR2030);
       // Name
       src.setPersonName(isbFields.getSeniorResponsibleClinicianName());
       // Job Role
       if (isbFields.getSeniorResponsibleClinicianJobRole() != null) {
         src.setAssociatedJobRole(isbFields.getSeniorResponsibleClinicianJobRole());
       }
       // ID
       if (isbFields.getSeniorResponsibleClinicianSDSID() != null) {
         src.addID(new PersonID()
                .setID(isbFields.getSeniorResponsibleClinicianSDSID())
                .setType(PersonIDType.SDSID.code));
       }
       // Tel
       if (isbFields.getSeniorResponsibleClinicianTelephone() != null) {
         src.addTelephoneNumber(new Telecom("tel:" + isbFields.getSeniorResponsibleClinicianTelephone()));
       }
       // Address
       if (isbFields.getSeniorResponsibleClinicianAddress() != null) {
         src.setAddress(isbFields.getSeniorResponsibleClinicianAddress());
       }
       // Org ID
      if (isbFields.getSeniorResponsibleClinicianORGID() != null) {
        src.setOrgId(new OrgID()
              .setID(isbFields.getSeniorResponsibleClinicianORGID())
              .setType(OrgIDType.ODSOrgID.code));
      }
      // Org Name
      if (isbFields.getSeniorResponsibleClinicianORGName() != null) {
        src.setOrgDescription(isbFields.getSeniorResponsibleClinicianORGName());
      }
     
       template.addRelatedPerson(new RelatedPersonDetails().setParticipant(src));
     }
    
    return template;
  }
 
  public static PrognosisAwareness createPrognosisAwareness(EndOfLifeCareISBFields isbFields) throws MissingMandatoryFieldException {
    // If no prognosis awareness has been given, exit
    if (isbFields.getMainInformalCarerAwareOfPrognosis() == null) {
      return null;
    }
   
    MissingMandatoryFieldException missingFields = new MissingMandatoryFieldException();
    // Null checks for mandatory fields
    // If we have a prognosis awareness for the main informal carer, we need to know who the main informal carer is (name)
    if (isbFields.getMainInformalCarerName() == null) {
      missingFields.addMissingField("MainInformalCarerName", "In order to indicate the main informal carer's awareness of the prognosis, you must also include the name of the main informal carer");
    }
    // We also need to know when the prognosis awareness was recorded
    if (isbFields.getPrognosisAwarenessRecordedDate() == null) {
      missingFields.addMissingField("PrognosisAwarenessRecordedDate", "In order to indicate the main informal carer's awareness of the prognosis, you must also include the date this awareness was recorded");
    }
   
    if (missingFields.hasEntries()) {
      throw missingFields;
    }
   
    PrognosisAwareness template = new PrognosisAwareness();
   
    template.setID(CDAUUID.generateUUIDString());

    // Date when made aware of prognosis
    template.setEffectiveTime(isbFields.getPrognosisAwarenessRecordedDate());
   
    // Awareness of prognosis
    template.setPrognosisAwareness(new CodedValue(isbFields.getMainInformalCarerAwareOfPrognosis(), "#prognosisawareness"));
   
    // Main informal carer (name, tel)
     if (isbFields.getMainInformalCarerName() != null) {
       PatientRelationshipParticipantRole mic = new PatientRelationshipParticipantRole();
       mic.setPersonRole(JobRoleName._NR1980);
       mic.setPersonName(isbFields.getMainInformalCarerName());
      
       if (isbFields.getMainInformalCarerTel() != null) {
         mic.addTelephoneNumber(new Telecom("tel:" + isbFields.getMainInformalCarerTel()));
       }
       template.setMainInformalCarer(mic);
     }
    return template;
  }

  public static AdvanceDecisionToRefuseTreatment createADRT(EndOfLifeCareISBFields isbFields) throws MissingMandatoryFieldException {
    // If there is no ADRT decision specified, exit
    if (isbFields.getADRT() == null) {
      return null;
    }

    AdvanceDecisionToRefuseTreatment template = new AdvanceDecisionToRefuseTreatment();
    template.setID(CDAUUID.generateUUIDString());
   
    MissingMandatoryFieldException missingFields = new MissingMandatoryFieldException();
    // Null checks for mandatory fields
    // If we have an ADRT, we need an effective time
    if (isbFields.getADRTRecordedDate() == null) {
      missingFields.addMissingField("ADRTRecordedDate", "If an ADRT is provided, the date this was recorded is also required");
    }
    // We also need to know where the ADRT documents are held
    if (isbFields.getADRTDocumentLocation() == null) {
      missingFields.addMissingField("ADRTDocumentLocation", "If an ADRT is provided, the location of the ADRT documentation is also required");
    }
   
    if (missingFields.hasEntries()) {
      throw missingFields;
    }
   
    // Time recorded
    template.setEffectiveTime(isbFields.getADRTRecordedDate());
    // Preference
    template.setADRTPreference(new CodedValue(isbFields.getADRT(), "#adrt"));
    // Document location
    template.setADRTDocumentLocation(isbFields.getADRTDocumentLocation());
    // Discussed with clinician
    if (isbFields.isADRTDiscussedWithClinicianNONISB()) {
      template.setADRTDiscussed(new CodedValue(ADRTDiscussedSnCT._820621000000107, "#adrtDiscussed"));
    }
    return template;
  }
 
  public static AnticipatoryMedicineBoxIssueProcedure createAMBox(EndOfLifeCareISBFields isbFields) throws MissingMandatoryFieldException {
    // If no anticipatory medication issued, skip this
    if (!isbFields.isAnticipatoryMedicinesIssued()) {
      return null;
    }
    MissingMandatoryFieldException missingFields = new MissingMandatoryFieldException();
    // Null checks for mandatory fields
    // If we have an anticipatory medicine box, we need a time issued
    if (isbFields.getAnticipatoryMedicinesDateIssued() == null) {
      missingFields.addMissingField("AnticipatoryMedicinesDateIssued", "If an anticipatory medicine box has been issued, the date it was issued is required");
    }
    // We also need to know where the ADRT documents are held
    if (isbFields.getAnticipatoryMedicinesLocation() == null) {
      missingFields.addMissingField("AnticipatoryMedicinesLocation", "If an anticipatory medicine box has been issued, the location of the box is required");
    }
    if (missingFields.hasEntries()) {
      throw missingFields;
    }
   
    AnticipatoryMedicineBoxIssueProcedure template = new AnticipatoryMedicineBoxIssueProcedure();
    template.setID(CDAUUID.generateUUIDString());
    // There is only one code in this vocab, so if the below is omitted, that code will still be used - however
    // we need to set it explicitly if we also want the code to include a cross-reference to a text section, which we do..
    template.setAnticipatoryMedicineBoxIssueCode(
          new CodedValue(EoLAnticipatoryMedicineBoxIssueSnCT._376201000000102, "#ambox"));
    // Date issued
    template.setTimeIssued(isbFields.getAnticipatoryMedicinesDateIssued());
    // Location
    template.setLocationOfBox(isbFields.getAnticipatoryMedicinesLocation());
    return template;
  }
 
  public static DNACPRDecisionbySeniorResponsibleClinician createDNACPR(EndOfLifeCareISBFields isbFields) throws MissingMandatoryFieldException {
    // If no DNACPR Decision included, skip this
    if (isbFields.getDNACPR() == null) {
      return null;
    }
    MissingMandatoryFieldException missingFields = new MissingMandatoryFieldException();
    // Null checks for mandatory fields
    // If we have a DNACPR Decision, we also need a senior responsible clinician name
    if (isbFields.getSeniorResponsibleClinicianName() == null) {
      missingFields.addMissingField("SeniorResponsibleClinicianName", "If a DNACPR decision is included, the senior responsible clinician name is also required");
    }
    // We also need the senior responsible clinician org id
    if (isbFields.getSeniorResponsibleClinicianORGID() == null) {
      missingFields.addMissingField("SeniorResponsibleClinicianORGID", "If a DNACPR decision is included, the senior responsible clinician's organisation (ODS) ID is also required");
    }
    // We also need the senior responsible clinician org name
    if (isbFields.getSeniorResponsibleClinicianORGName() == null) {
      missingFields.addMissingField("SeniorResponsibleClinicianORGName", "If a DNACPR decision is included, the senior responsible clinician's organisation name is also required");
    }
    // We also need the date of the decision
    if (isbFields.getDNACPRDate() == null) {
      missingFields.addMissingField("DNACPRDate", "If a DNACPR decision is included, the date the decision was made is also required");
    }
    // We also need the date the decision was recorded
    if (isbFields.getDNACPRCreatedDate() == null) {
      missingFields.addMissingField("DNACPRCreatedDate", "If a DNACPR decision is included, the date the decision was originally recorded is also required");
    }
    if (missingFields.hasEntries()) {
      throw missingFields;
    }
   
    DNACPRDecisionbySeniorResponsibleClinician template = new DNACPRDecisionbySeniorResponsibleClinician();

    template.setID(CDAUUID.generateUUIDString());
    // DNACPR Decision date
    template.setEffectiveTime(isbFields.getDNACPRDate());
    // DNACPR Preference
    template.setDNACPRPreference(new CodedValue(isbFields.getDNACPR(), "#dnacprdecision"));
    // DNACPR Decision Originally Recorded Date
    template.setSeniorResponsibleClinicianTimeAuthored(isbFields.getDNACPRCreatedDate());
    // Document Location
    template.setDNACPRDocsLocation(isbFields.getDNACPRLocation());
    // Review date
    if (isbFields.getDNACPRReviewDate() != null) {
      template.setReviewDate(isbFields.getDNACPRReviewDate());
    }
   
    // Author: Senior Responsible Clinician
    template.setSeniorResponsibleClinicianAuthor(createSeniorResponsibleClinicianAuthor(isbFields));

    return template;
  }
 
  public static AuthorPersonUniversal createSeniorResponsibleClinicianAuthor(EndOfLifeCareISBFields isbFields) {
    // Senior Responsible Clinician
    AuthorPersonUniversal src = new AuthorPersonUniversal();
     // Name
     src.setName(isbFields.getSeniorResponsibleClinicianName());
     // Job Role
     if (isbFields.getSeniorResponsibleClinicianJobRole() != null) {
       src.setJobRoleName(isbFields.getSeniorResponsibleClinicianJobRole());
     }
     // ID
     if (isbFields.getSeniorResponsibleClinicianSDSID() != null) {
       src.addId(new PersonID()
              .setID(isbFields.getSeniorResponsibleClinicianSDSID())
              .setType(PersonIDType.SDSID.code));
     }
     // Tel
     if (isbFields.getSeniorResponsibleClinicianTelephone() != null) {
       src.addTelephoneNumber(new Telecom("tel:" + isbFields.getSeniorResponsibleClinicianTelephone()));
     }
     // Address
     if (isbFields.getSeniorResponsibleClinicianAddress() != null) {
       src.addAddress(isbFields.getSeniorResponsibleClinicianAddress());
     }
     // Org ID
    src.setOrganisationId(new OrgID()
          .setID(isbFields.getSeniorResponsibleClinicianORGID())
          .setType(OrgIDType.ODSOrgID.code));
    // Org Name
    src.setOrganisationName(isbFields.getSeniorResponsibleClinicianORGName());
    return src;
  }

  public static AuthoritytoLastingPowerofAttorney createLPA(EndOfLifeCareISBFields isbFields) throws MissingMandatoryFieldException {
    // If no DNACPR Decision included, skip this
    if (isbFields.getLPAAuthority() == null) {
      return null;
    }
    MissingMandatoryFieldException missingFields = new MissingMandatoryFieldException();
    // Null checks for mandatory fields
    // If we have an LPA authority we also need a name for the LPA
    if (isbFields.getLPAName() == null) {
      missingFields.addMissingField("LPAName", "If an LPA authority is included, the name of the LPA is also required");
    }
    if (isbFields.getLPADate() == null) {
      missingFields.addMissingField("LPADate", "If an LPA authority is included, the date the LPA was granted is also required");
    }
    if (missingFields.hasEntries()) {
      throw missingFields;
    }
   
    AuthoritytoLastingPowerofAttorney template = new AuthoritytoLastingPowerofAttorney();
    template.setID(CDAUUID.generateUUIDString());
    // Date granted
    template.setEffectiveTime(isbFields.getLPADate());
    // LPA Authority
    template.setAuthoritytoLPA(new CodedValue(isbFields.getLPAAuthority(), "#lpaauthority"));
   
    // LPA Person details
    PatientRelationshipParticipantRole person = new PatientRelationshipParticipantRole();
    person.setPersonRole(JobRoleName._NR2010);
    person.setAddress(new Address().setNullFlavour(NullFlavour.NI.code));
    // LPA Telephone
    if (isbFields.getLPATelephone() != null) {
      person.addTelephoneNumber(new Telecom("tel:" + isbFields.getLPATelephone()));
    }
    // LPA Name
    person.setPersonName(isbFields.getLPAName());
    template.setLPADetails(person);
   
    return template;
  }
 
  public static TextSection createTextSection1_GeneralDocumentInformation(EndOfLifeCareISBFields isbFields) {
    TextSection template = new TextSection();
    template.setSectionId(CDAUUID.generateUUIDString());
    template.setTitle("End of Life Record Details");
   
    Section2 s2 = new Section2();
    s2.setSectionId(CDAUUID.generateUUIDString());
    s2.setTitle("Record Created By");
   
    // We need to turn the structured author information into some nice human readable text
    s2.setText(HumanReadableFormatter.makeHumanReadablePersonDetails(
                        isbFields.getDocumentAuthorName(),
                        isbFields.getDocumentAuthorRole(),
                        isbFields.getDocumentAuthorOrganisationName()));
    template.addSection2(s2);
   
    Section3 s3 = new Section3();
    s3.setSectionId(CDAUUID.generateUUIDString());
    s3.setTitle("Record Creation Date");
    s3.setText(isbFields.getEpaccsRecordCreationDate().getDisplayString());
    s2.addSection3(s3);
   
    if (isbFields.getEpaccsRecordUpdatedDate() != null) {
      Section3 s3b = new Section3();
      s3b.setSectionId(CDAUUID.generateUUIDString());
      s3b.setTitle("Record Amended Date");
      s3b.setText(isbFields.getEpaccsRecordUpdatedDate().getDisplayString());
      s2.addSection3(s3b);
    }
   
    if (isbFields.getEpaccsRecordReviewDate() != null) {
      Section3 s3c = new Section3();
      s3c.setSectionId(CDAUUID.generateUUIDString());
      s3c.setTitle("Record Review Date");
      s3c.setText(isbFields.getEpaccsRecordReviewDate().getDisplayString());
      s2.addSection3(s3c);
    }
   
    return template;
  }
 
  public static TextSection createTextSection2_PatientRelationships(EndOfLifeCareISBFields isbFields) {
    TextSection template = new TextSection();
    template.setSectionId(CDAUUID.generateUUIDString());
    template.setTitle("Patient Relationships");
   
    // Now we need to make a HTML table containing the related person details
    StringBuilder table = new StringBuilder("<table width=\"100%\"><tbody><tr align=\"left\" valign=\"top\"><th>Relationship with patient</th><th>Carer Details</th></tr>");
    // Main informal carer (name, tel)
    if (isbFields.getMainInformalCarerName() != null) {
      table.append("<tr align=\"left\" valign=\"top\"><td>Main Informal Carer</td><td>");
      table.append(HumanReadableFormatter.makeHumanReadablePersonName(isbFields.getMainInformalCarerName()));
      if (isbFields.getMainInformalCarerTel() != null) {
        table.append("<br/>").append(isbFields.getMainInformalCarerTel());
      }
      table.append("</td></tr>");
    }
    // Usual GP (name, practice name, address, tel, fax)
    if (isbFields.getUsualGPName() != null) {
      table.append("<tr align=\"left\" valign=\"top\"><td>Usual GP</td><td>");
      // Name
      table.append(HumanReadableFormatter.makeHumanReadablePersonName(isbFields.getUsualGPName()));
      // Practice name
      if (isbFields.getUsualGPOrgName() != null) {
        table.append("<br/>").append(isbFields.getUsualGPOrgName());
      }
      // Practice Address
      if (isbFields.getUsualGPAddress() != null) {
        table.append("<br/>").append(HumanReadableFormatter.makeHumanReadableAddress(isbFields.getUsualGPAddress(), "<br/>"));
      }
      // Tel
      if (isbFields.getUsualGPTelephone() != null) {
        table.append("<br/>").append(isbFields.getUsualGPTelephone());
      }
      // Fax
      if (isbFields.getUsualGPFax() != null) {
        table.append("<br/>").append(isbFields.getUsualGPFax()).append(" (fax)");
      }
      table.append("</td></tr>");
    }
    // Key Worker (name, role, org name, address, tel)
    if (isbFields.getKeyWorkerName() != null) {
      table.append("<tr align=\"left\" valign=\"top\"><td>Key Worker</td><td>");
      // Name
      table.append(HumanReadableFormatter.makeHumanReadablePersonName(isbFields.getKeyWorkerName()));
      // Role
      if (isbFields.getKeyWorkerJobRole() != null) {
        table.append("<br/>").append(isbFields.getKeyWorkerJobRole().getDisplayName());
      }
      // Org name
      if (isbFields.getKeyWorkerOrgName() != null) {
        table.append("<br/>").append(isbFields.getKeyWorkerOrgName());
      }
      // Address
      if (isbFields.getKeyWorkerAddress() != null) {
        table.append("<br/>").append(HumanReadableFormatter.makeHumanReadableAddress(isbFields.getKeyWorkerAddress(), "<br/>"));
      }
      // Tel
      if (isbFields.getKeyWorkerTelephone() != null) {
        table.append("<br/>").append(isbFields.getKeyWorkerTelephone());
      }
      table.append("</td></tr>");
    }
    // Senior Responsible Clinician (name, role, org name, add, tel)
    if (isbFields.getSeniorResponsibleClinicianName() != null) {
      table.append("<tr align=\"left\" valign=\"top\"><td>Senior Responsible Clinician</td><td>");
      // Name
      table.append(HumanReadableFormatter.makeHumanReadablePersonName(isbFields.getSeniorResponsibleClinicianName()));
      // Role
      if (isbFields.getSeniorResponsibleClinicianJobRole() != null) {
        table.append("<br/>").append(isbFields.getSeniorResponsibleClinicianJobRole().getDisplayName());
      }
      // Org name
      if (isbFields.getSeniorResponsibleClinicianORGName() != null) {
        table.append("<br/>").append(isbFields.getSeniorResponsibleClinicianORGName());
      }
      // Address
      if (isbFields.getSeniorResponsibleClinicianAddress() != null) {
        table.append("<br/>").append(HumanReadableFormatter.makeHumanReadableAddress(isbFields.getSeniorResponsibleClinicianAddress(), "<br/>"));
      }
      // Tel
      if (isbFields.getSeniorResponsibleClinicianTelephone() != null) {
        table.append("<br/>").append(isbFields.getSeniorResponsibleClinicianTelephone());
      }
      table.append("</td></tr>");
    }
    // Formal Carers 0..N (name, role, tel)
    List<EndOfLifeCareDocumentFormalCarer> carerlist = isbFields.getFormalCarers();
    if (carerlist != null) {
       for (EndOfLifeCareDocumentFormalCarer carerentry : carerlist) {
         table.append("<tr align=\"left\" valign=\"top\"><td>Formal Carer</td><td>");
         // Name
         table.append(HumanReadableFormatter.makeHumanReadablePersonName(carerentry.getName()));
         // Role
         if (carerentry.getRole() != null) {
           table.append("<br/>").append(carerentry.getRole().getDisplayName());
         }
         // Tel
         if (carerentry.getTelephone() != null) {
           table.append("<br/>").append(carerentry.getTelephone());
         }
         table.append("</td></tr>");
       }
    }
    // Lasting power of attorney (name, tel)
    if (isbFields.getLPAName() != null) {
      table.append("<tr align=\"left\" valign=\"top\"><td>Formal Carer</td><td>");
      // Name
      table.append(HumanReadableFormatter.makeHumanReadablePersonName(isbFields.getLPAName()));
      // Tel
      if (isbFields.getLPATelephone() != null) {
        table.append("<br/>").append(isbFields.getLPATelephone());
      }
      table.append("</td></tr>");
    }
    // First additional person to involve in decisions (name, tel)
    if (isbFields.getAdditionalPersonToInvolve() != null) {
      table.append("<tr align=\"left\" valign=\"top\"><td>Additional Person to be Involved in Decisions</td><td>");
      // Name
      table.append(HumanReadableFormatter.makeHumanReadablePersonName(isbFields.getAdditionalPersonToInvolve()));
      // Tel
      if (isbFields.getAdditionalPersonToInvolveTel() != null) {
        table.append("<br/>").append(isbFields.getAdditionalPersonToInvolveTel());
      }
      table.append("</td></tr>");
    }
    // Second additional person to involve in decisions (name, tel)
    if (isbFields.getAdditionalPersonToInvolve2() != null) {
      table.append("<tr align=\"left\" valign=\"top\"><td>Additional Person to be Involved in Decisions</td><td>");
      // Name
      table.append(HumanReadableFormatter.makeHumanReadablePersonName(isbFields.getAdditionalPersonToInvolve2()));
      // Tel
      if (isbFields.getAdditionalPersonToInvolve2Tel() != null) {
        table.append("<br/>").append(isbFields.getAdditionalPersonToInvolve2Tel());
      }
      table.append("</td></tr>");
    }
   
    table.append("</tbody></table>");
    template.setText(table.toString());
   
    if (isbFields.getLPAAuthority() != null) {
      Section2 s2 = new Section2();
      s2.setSectionId(CDAUUID.generateUUIDString());
      s2.setTitle("Authority to LPA");
      s2.setText("<content ID=\"lpaauthority\">" + isbFields.getLPAAuthority().getDisplayName() + "</content>");
      template.addSection2(s2);
    }
   
    if (isbFields.getMainInformalCarerAwareOfPrognosis() != null) {
      Section2 s2b = new Section2();
      s2b.setSectionId(CDAUUID.generateUUIDString());
      s2b.setTitle("Prognosis Awareness (Main Informal Carer)");
      s2b.setText("<content ID=\"prognosisawareness\">" + isbFields.getMainInformalCarerAwareOfPrognosis().getDisplayName() + "</content>");
      template.addSection2(s2b);
    }
   
    return template;
  }
 
  public static TextSection createTextSection_EOLToolUsed(EndOfLifeCareISBFields isbFields) {
    if (isbFields.getEolcTool() == null) {
      return null;
    }
    TextSection template = new TextSection();
    template.setSectionId(CDAUUID.generateUUIDString());
    template.setTitle("End of Life Tool Used");
    template.setText("<content ID=\"eolcTool\">" + isbFields.getEolcTool().getDisplayName() + "</content>");
   
    if (isbFields.getEolcPathwayStageNONISB() != null) {
      Section2 s2 = new Section2();
      s2.setSectionId(CDAUUID.generateUUIDString());
      s2.setTitle("Current Stage");
      s2.setText(isbFields.getEolcPathwayStageNONISB());
      template.addSection2(s2);
    }
   
    return template;
  }

  public static TextSection createTextSection4_PatientChoices(EndOfLifeCareISBFields isbFields) {
    if ((isbFields.getPreferredPlaceOfDeath() == null) &&
      (isbFields.getPreferredPlaceOfDeath2() == null) &&
      (isbFields.getOtherRelevantInformation() == null)) {
      return null;
    }
    TextSection template = new TextSection();
    template.setSectionId(CDAUUID.generateUUIDString());
    template.setTitle("Patient Choices");
   
    // PPD
    StringBuilder ppd = new StringBuilder();
    if (isbFields.getPreferredPlaceOfDeath() != null) {
      ppd.append(isbFields.getPreferredPlaceOfDeath());
      // PPD Organisation
      if (isbFields.getPreferredPlaceOfDeathOrganisation() != null) {
        ppd.append(", ").append(isbFields.getPreferredPlaceOfDeathOrganisation());
      }
      // Usual place of residence
      if (isbFields.getPreferredPlaceOfDeathIsUPR() != null) {
        ppd.append(" (Usual place of residence)");
      }
      // PPD Address
      if (isbFields.getPreferredPlaceOfDeathAddress() != null) {
        ppd.append("<br/>" + HumanReadableFormatter.makeHumanReadableAddress(isbFields.getPreferredPlaceOfDeathAddress(), ", "));
      }
      Section2 s2 = new Section2();
      s2.setSectionId(CDAUUID.generateUUIDString());
      s2.setTitle("First preferred place of death");
      s2.setText(ppd.toString());
      template.addSection2(s2);
    }

    // PPD2
    StringBuilder ppd2 = new StringBuilder();
    if (isbFields.getPreferredPlaceOfDeath2() != null) {
      ppd2.append(isbFields.getPreferredPlaceOfDeath2());
      // PPD Organisation
      if (isbFields.getPreferredPlaceOfDeath2Organisation() != null) {
        ppd2.append(", ").append(isbFields.getPreferredPlaceOfDeath2Organisation());
      }
      // Usual place of residence
      if (isbFields.getPreferredPlaceOfDeath2IsUPR() != null) {
        ppd2.append(" (Usual place of residence)");
      }
      // PPD Address
      if (isbFields.getPreferredPlaceOfDeath2Address() != null) {
        ppd2.append("<br/>" + HumanReadableFormatter.makeHumanReadableAddress(isbFields.getPreferredPlaceOfDeath2Address(), ", "));
      }
      Section2 s2 = new Section2();
      s2.setSectionId(CDAUUID.generateUUIDString());
      s2.setTitle("Second preferred place of death");
      s2.setText(ppd2.toString());
      template.addSection2(s2);
    }
   
    // Other relevant information
    if (isbFields.getOtherRelevantInformation() != null) {
      Section2 s2c = new Section2();
      s2c.setSectionId(CDAUUID.generateUUIDString());
      s2c.setTitle("Other Relevant Issues or Preferences about Provision of Care");
      s2c.setText(isbFields.getOtherRelevantInformation());
      template.addSection2(s2c);
    }
   
    return template;
  }

  public static TextSection createTextSection5_AdvanceStatements(EndOfLifeCareISBFields isbFields) {
    if ((isbFields.getADRT() == null) && (isbFields.getAdvanceStatements() == null)) {
      return null;
    }
   
    // Advance Statements
    TextSection template = new TextSection();
    template.setSectionId(CDAUUID.generateUUIDString());
    template.setTitle("Advance Statements");
    if (isbFields.getAdvanceStatements() != null) {
      template.setText(isbFields.getAdvanceStatements());
    }
   
    // ADRT
    if (isbFields.getADRT() != null) {
      Section2 s2 = new Section2();
      s2.setSectionId(CDAUUID.generateUUIDString());
      s2.setTitle("Advance Decision to Refuse Treatment (ADRT)");
      s2.setText("<content ID=\"adrt\">" + isbFields.getADRT().getDisplayName() + "</content>");
      template.addSection2(s2);
     
      // Discussed with professional
      if (isbFields.isADRTDiscussedWithClinicianNONISB()) {
        Section3 s3 = new Section3();
        s3.setSectionId(CDAUUID.generateUUIDString());
        s3.setTitle("Discussion about ADRT");
        s3.setText("<content ID=\"adrtDiscussed\">Has involved healthcare professional in discussion about advance decision to refuse treatment (Mental Capacity Act 2005) (finding)</content>");
        s2.addSection3(s3);
      }
     
      // ADRT Document Location
      if (isbFields.getADRTDocumentLocation() != null) {
        Section3 s3b = new Section3();
        s3b.setSectionId(CDAUUID.generateUUIDString());
        s3b.setTitle("Location of ADRT documentation");
        s3b.setText(isbFields.getADRTDocumentLocation());
        s2.addSection3(s3b);
      }
    }
   
    return template;
  }
 
  public static TextSection createTextSection6_DNACPR(EndOfLifeCareISBFields isbFields) {
    if (isbFields.getDNACPR() == null) {
      return null;
    }
   
    TextSection template = new TextSection();
    template.setSectionId(CDAUUID.generateUUIDString());
    template.setTitle("DNACPR Decision");
   
    // Senior responsible clinician has made DNACPR decision:
    //     Not for attempted cardiopulmonary resuscitation
    //     <br/>This record is created on 11/09/2012 and will be reviewed on 11/10/2012

    // DNACPR
    StringBuilder dnacpr = new StringBuilder("<content ID=\"dnacprdecision\">Senior responsible clinician has made DNACPR decision: ");
    dnacpr.append(isbFields.getDNACPR().getDisplayName());
   
    // Created Date
    if (isbFields.getDNACPRCreatedDate() != null) {
      dnacpr.append("<br/>This decision was originally recorded on ");
      dnacpr.append(isbFields.getDNACPRCreatedDate().getDisplayString());
    }
   
    // Review Date
    if (isbFields.getDNACPRReviewDate() != null) {
      if (isbFields.getDNACPRCreatedDate() != null) {
        dnacpr.append(" and will be reviewed on ");
      } else {
        dnacpr.append("<br/>This decision will be reviewed on ");
      }
      dnacpr.append(isbFields.getDNACPRReviewDate().getDisplayString());
    }
   
    dnacpr.append("</content>");
    template.setText(dnacpr.toString());
   
    // Creation date
    template.setTimeAuthored(isbFields.getDNACPRCreatedDate());
    // Author: Senior Responsible Clinician
    template.setAuthor(createSeniorResponsibleClinicianAuthor(isbFields));
   
    if (isbFields.getDNACPRLocation() != null) {
      Section2 s2 = new Section2();
      s2.setSectionId(CDAUUID.generateUUIDString());
      template.addSection2(s2);
     
      Section3 s3 = new Section3();
      s3.setSectionId(CDAUUID.generateUUIDString());
      s3.setTitle("Location of DNACPR documentation");
      s3.setText(isbFields.getDNACPRLocation());
      s2.addSection3(s3);
    }
   
    return template;
  }
 
  public static TextSection createTextSection7_Observations(EndOfLifeCareISBFields isbFields) {
    String primary = isbFields.getPrimaryEOLCDiagnosis();
    String other = isbFields.getOtherRelevantDiagnoses();
    String disabilities = isbFields.getPatientDisability();
    String allergies = isbFields.getAllergiesAndAdverseReactions();
   
    if (other == null && disabilities == null && allergies == null && primary == null) {
      return null;
    }
   
    TextSection template = new TextSection();
    template.setSectionId(CDAUUID.generateUUIDString());
    template.setTitle("End of Life Care Observations");
   
    if (primary != null) {
      Section2 s2 = new Section2();
      s2.setSectionId(CDAUUID.generateUUIDString());
      s2.setTitle("Primary EoLC Diagnosis");
      s2.setText(primary);
      template.addSection2(s2);
    }
    if (other != null) {
      Section2 s2b = new Section2();
      s2b.setSectionId(CDAUUID.generateUUIDString());
      s2b.setTitle("Other EoLC Diagnosis");
      s2b.setText(other);
      template.addSection2(s2b);
    }
    if (disabilities != null) {
      Section2 s2c = new Section2();
      s2c.setSectionId(CDAUUID.generateUUIDString());
      s2c.setTitle("Disabilities");
      s2c.setText(disabilities);
      template.addSection2(s2c);
    }
    if (allergies != null) {
      Section2 s2d = new Section2();
      s2d.setSectionId(CDAUUID.generateUUIDString());
      s2d.setTitle("Allergies and Adverse Reaction Summary");
      s2d.setText(allergies);
      template.addSection2(s2d);
    }
   
    return template;
  }
 
  public static TextSection createTextSection8_AnticipatoryMedication(EndOfLifeCareISBFields isbFields) {
    if (!isbFields.isAnticipatoryMedicinesIssued()) {
      return null;
    }
   
    TextSection template = new TextSection();
    template.setSectionId(CDAUUID.generateUUIDString());
    template.setTitle("End of Life Care Artefacts");
   
    // Anticipatory Medicine Box
    Section2 s2 = new Section2();
    s2.setSectionId(CDAUUID.generateUUIDString());
    s2.setTitle("Anticipatory Medicine Box");
    StringBuilder ambox = new StringBuilder("<content ID=\"ambox\">Issue of palliative care anticipatory medication box (procedure)");
   
    // AMBox Issue Date
    if (isbFields.getAnticipatoryMedicinesDateIssued() != null) {
      ambox.append("<br/>The box was issued on ");
      ambox.append(isbFields.getAnticipatoryMedicinesDateIssued());
    }
   
    // AMBox Location
    if (isbFields.getAnticipatoryMedicinesLocation() != null) {
      if (isbFields.getAnticipatoryMedicinesDateIssued() != null) {
        ambox.append(" and is located: ");
      } else {
        ambox.append("<br/>The box is located: ");
      }
      ambox.append(isbFields.getAnticipatoryMedicinesLocation());
    }
   
    ambox.append("</content>");
    s2.setText(ambox.toString());
    template.addSection2(s2);
   
    return template;
  }
 
  public static TextSection createTextSection9_EPaCCSLink(EndOfLifeCareISBFields isbFields) {
    if (isbFields.getEPaCCSURL() == null) {
      return null;
    }
    TextSection template = new TextSection();
    template.setSectionId(CDAUUID.generateUUIDString());
    template.setTitle("EPaCCS Record Location");
    template.setText("URL of record: <linkHtml>" + isbFields.getEPaCCSURL() + "</linkHtml>");
    return template;
  }
}
TOP

Related Classes of uk.nhs.interoperability.payloads.helpers.EndOfLifeCareDocumentCreationHelper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.