Package uk.nhs.interoperability.payloads.helpers

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

/*
   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 EndOfLifeCareDocumentCreationCDGRSHelper {

  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());
   
   
    // We will structure everything under the headings defined here:
    // https://www.rcplondon.ac.uk/sites/default/files/standards-for-the-clinical-structure-and-content-of-patient-records.pdf
   
    template.addTextSections(new TextSections(createTextSection1_GeneralDocumentInformation(isbFields)));
    template.addTextSections(new TextSections(createTextSection2_PatientDemographics(isbFields)));
    template.addTextSections(new TextSections(createTextSection3_GPPractice(isbFields)));
    template.addTextSections(new TextSections(createTextSection4_Allergies(isbFields)));
    template.addTextSections(new TextSections(createTextSection5_AssessmentScales(isbFields)));
    template.addTextSections(new TextSections(createTextSection6_Diagnoses(isbFields)));
    template.addTextSections(new TextSections(createTextSection7_InformationGiven(isbFields)));
    template.addTextSections(new TextSections(createTextSection8_LegalInformation(isbFields)));
    template.addTextSections(new TextSections(createTextSection9_Medications(isbFields)));
    template.addTextSections(new TextSections(createTextSection10_Concerns(isbFields)));
    template.addTextSections(new TextSections(createTextSection11_PersonCompletingRecord(isbFields)));
    template.addTextSections(new TextSections(createTextSection12_Plan(isbFields)));
    template.addTextSections(new TextSections(createTextSection13_Social(isbFields)));
    template.addTextSections(new TextSections(createTextSection14_SpecialRequirements(isbFields)));
    template.addTextSections(new TextSections(createTextSection_EOLToolUsed(isbFields)));
    template.addTextSections(new TextSections(createTextSection_EPaCCSLink(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;
  }
 
  /*******************************************  TEXT SECTIONS ********************************************/
 
  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);
    }
   
    return template;
  }
 
  public static TextSection createTextSection2_PatientDemographics(EndOfLifeCareISBFields isbFields) {
    TextSection template = new TextSection();
    template.setSectionId(CDAUUID.generateUUIDString());
    template.setTitle("Patient demographics");
   
   
    Section2 s2 = new Section2();
    s2.setSectionId(CDAUUID.generateUUIDString());
    s2.setTitle("Relevant Contacts");
   
    // 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>");
    }
    // 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>");
    }
    table.append("</tbody></table>");
    s2.setText(table.toString());
    template.addSection2(s2);
   
    return template;
  }
 
  public static TextSection createTextSection3_GPPractice(EndOfLifeCareISBFields isbFields) {
    TextSection template = new TextSection();
    template.setSectionId(CDAUUID.generateUUIDString());
    template.setTitle("GP practice");
   
    if (isbFields.getUsualGPName() != null) {
      Section2 s2 = new Section2();
      s2.setSectionId(CDAUUID.generateUUIDString());
      s2.setTitle("GP name");
      s2.setText(HumanReadableFormatter.makeHumanReadablePersonName(isbFields.getUsualGPName()));
      template.addSection2(s2);
    }
   
    if (isbFields.getUsualGPOrgName() != null) {
      Section2 s2 = new Section2();
      s2.setSectionId(CDAUUID.generateUUIDString());
      s2.setTitle("GP practice details");
      String text = isbFields.getUsualGPOrgName();
      if (isbFields.getUsualGPAddress() != null) {
        text = text + "<br/>" + isbFields.getUsualGPAddress();
      }
      if (isbFields.getUsualGPTelephone() != null) {
        text = text + "<br/>" + isbFields.getUsualGPTelephone();
      }
      if (isbFields.getUsualGPFax() != null) {
        text = text + "<br/>" + isbFields.getUsualGPFax() + " (fax)";
      }
      s2.setText(isbFields.getUsualGPOrgName());
      template.addSection2(s2);
    }
   
    if (isbFields.getUsualGPODSCode() != null) {
      Section2 s2 = new Section2();
      s2.setSectionId(CDAUUID.generateUUIDString());
      s2.setTitle("GP practice identifier");
      s2.setText(isbFields.getUsualGPODSCode());
      template.addSection2(s2);
    }
   
    return template;
  }
 
  public static TextSection createTextSection4_Allergies(EndOfLifeCareISBFields isbFields) {
    TextSection template = new TextSection();
    template.setSectionId(CDAUUID.generateUUIDString());
    template.setTitle("Allergies and adverse reaction");
    String allergies = isbFields.getAllergiesAndAdverseReactions();
    if (allergies != null) {
      template.setText(allergies);
    }
    return template;
  }
  public static TextSection createTextSection5_AssessmentScales(EndOfLifeCareISBFields isbFields) {
    TextSection template = new TextSection();
    template.setSectionId(CDAUUID.generateUUIDString());
    template.setTitle("Assessment scales");
    template.setText("");
    return template;
  }
  public static TextSection createTextSection6_Diagnoses(EndOfLifeCareISBFields isbFields) {
    TextSection template = new TextSection();
    template.setSectionId(CDAUUID.generateUUIDString());
    template.setTitle("Diagnoses");
    boolean primary = isbFields.getPrimaryEOLCDiagnosis() != null;
    boolean other = isbFields.getOtherRelevantDiagnoses() != null;
    if (primary || other) {
      Section2 s2 = new Section2();
      s2.setSectionId(CDAUUID.generateUUIDString());
      s2.setTitle("Diagnosis");
     
      String text = "";
      if (primary) {
        text = text + "Primary End of Life Care Diagnosis: " + isbFields.getPrimaryEOLCDiagnosis();
      }
      if (other) {
        if (primary) {
          text = text + "<br/>";
        }
        text = text + "Other Relevant End of Life Care Diagnoses and Clinical Issues: " + isbFields.getOtherRelevantDiagnoses();
      }
      s2.setText(text);
      template.addSection2(s2);
    }
    return template;
  }
 
  public static TextSection createTextSection7_InformationGiven(EndOfLifeCareISBFields isbFields) {
    TextSection template = new TextSection();
    template.setSectionId(CDAUUID.generateUUIDString());
    template.setTitle("Information given");
   
    if (isbFields.getMainInformalCarerAwareOfPrognosis() != null) {
      Section2 s2b = new Section2();
      s2b.setSectionId(CDAUUID.generateUUIDString());
      s2b.setTitle("Information and advice given");
      String text = "<content ID=\"prognosisawareness\">" + isbFields.getMainInformalCarerAwareOfPrognosis().getDisplayName() + "</content>";
      if (isbFields.getPrognosisAwarenessRecordedDate() != null) {
        text = text + " (recorded: " + isbFields.getPrognosisAwarenessRecordedDate().getDisplayString() + ")";
      }
      s2b.setText(text);
      template.addSection2(s2b);
    }
    return template;
  }
 
  public static TextSection createTextSection8_LegalInformation(EndOfLifeCareISBFields isbFields) {
    TextSection template = new TextSection();
    template.setSectionId(CDAUUID.generateUUIDString());
    template.setTitle("Legal information");
   
    Section2 s2 = new Section2();
    s2.setSectionId(CDAUUID.generateUUIDString());
    s2.setTitle("Advance decisions about treatment");
   
    if (isbFields.getAdvanceStatements() != null) {
      Section3 s3 = new Section3();
      s3.setSectionId(CDAUUID.generateUUIDString());
      s3.setTitle("Advance Statement Requests and Preferences");
      s3.setText(isbFields.getAdvanceStatements());
      s2.addSection3(s3);
    }
   
    // ADRT
    if (isbFields.getADRT() != null) {
      Section3 s3 = new Section3();
      s3.setSectionId(CDAUUID.generateUUIDString());
      s3.setTitle("Person has made an Advance Decision to Refuse Treatment");
      String text = "<content ID=\"adrt\">" + isbFields.getADRT().getDisplayName() + "</content>";
      if (isbFields.getADRTRecordedDate() != null) {
        text = text + " (recorded: " + isbFields.getADRTRecordedDate().getDisplayString() + ")";
      }
      s3.setText(text);
      s2.addSection3(s3);
     
      // Discussed with professional
      if (isbFields.isADRTDiscussedWithClinicianNONISB()) {
        Section3 s3b = new Section3();
        s3b.setSectionId(CDAUUID.generateUUIDString());
        s3b.setTitle("ADRT discussed with clinical professional");
        s3b.setText("<content ID=\"adrtDiscussed\">Has involved healthcare professional in discussion about advance decision to refuse treatment (Mental Capacity Act 2005) (finding)</content>");
        s2.addSection3(s3b);
      }
     
      // ADRT Document Location
      if (isbFields.getADRTDocumentLocation() != null) {
        Section3 s3c = new Section3();
        s3c.setSectionId(CDAUUID.generateUUIDString());
        s3c.setTitle("Location of Advance Decision to Refuse Treatment Documentation");
        s3c.setText(isbFields.getADRTDocumentLocation());
        s2.addSection3(s3c);
      }
    }
    template.addSection2(s2);
   
    Section2 s2b = new Section2();
    s2b.setSectionId(CDAUUID.generateUUIDString());
    s2b.setTitle("Lasting or enduring power of attorney or similar");
   
    // Lasting power of attorney (name, tel)
    if (isbFields.getLPAName() != null) {
      StringBuilder text = new StringBuilder();
      // Name
      text.append(HumanReadableFormatter.makeHumanReadablePersonName(isbFields.getLPAName()));
      // Tel
      if (isbFields.getLPATelephone() != null) {
        text.append("<br/>").append(isbFields.getLPATelephone());
      }
      // Date LPA Granted
      if (isbFields.getLPATelephone() != null) {
        text.append("<br/>LPA Granted: ").append(isbFields.getLPADate());
      }
      // LPA Authority
      if (isbFields.getLPAAuthority() != null) {
        text.append("<br/><content ID=\"lpaauthority\">" + isbFields.getLPAAuthority().getDisplayName() + "</content>");
      }
      s2b.setText(text.toString());
    }
    template.addSection2(s2b);
   
    return template;
  }
 
  public static TextSection createTextSection9_Medications(EndOfLifeCareISBFields isbFields) {
    if (!isbFields.isAnticipatoryMedicinesIssued()) {
      return null;
    }
   
    TextSection template = new TextSection();
    template.setSectionId(CDAUUID.generateUUIDString());
    template.setTitle("Medications and medical devices");
   
    // 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 createTextSection10_Concerns(EndOfLifeCareISBFields isbFields) {
    TextSection template = new TextSection();
    template.setSectionId(CDAUUID.generateUUIDString());
    template.setTitle("Patient and carer concerns");
   
    Section2 s2 = new Section2();
    s2.setSectionId(CDAUUID.generateUUIDString());
    s2.setTitle("Patient�s and carer�s concerns, expectations and wishes");
   
    // PPD
    if (isbFields.getPreferredPlaceOfDeath() != null) {
      StringBuilder ppd = new StringBuilder();
      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(), ", "));
      }
      Section3 s3 = new Section3();
      s3.setSectionId(CDAUUID.generateUUIDString());
      s3.setTitle("Preferred Place of Death 1st Choice");
      s3.setText(ppd.toString());
      s2.addSection3(s3);
    }

    // PPD2
    if (isbFields.getPreferredPlaceOfDeath2() != null) {
      StringBuilder ppd2 = new StringBuilder();
      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(), ", "));
      }
      Section3 s3 = new Section3();
      s3.setSectionId(CDAUUID.generateUUIDString());
      s3.setTitle("Preferred Place of Death 2nd Choice");
      s3.setText(ppd2.toString());
      s2.addSection3(s3);
    }
   
    if (isbFields.getAdditionalPersonToInvolve() != null || isbFields.getAdditionalPersonToInvolve2() != null) {
      StringBuilder text = new StringBuilder();
      // First additional person to involve in decisions (name, tel)
      if (isbFields.getAdditionalPersonToInvolve() != null) {
        // Name
        text.append(HumanReadableFormatter.makeHumanReadablePersonName(isbFields.getAdditionalPersonToInvolve()));
        // Tel
        if (isbFields.getAdditionalPersonToInvolveTel() != null) {
          text.append("<br/>").append(isbFields.getAdditionalPersonToInvolveTel());
        }
      }
      // Second additional person to involve in decisions (name, tel)
      if (isbFields.getAdditionalPersonToInvolve2() != null) {
        // Name
        text.append("<br/>").append(HumanReadableFormatter.makeHumanReadablePersonName(isbFields.getAdditionalPersonToInvolve2()));
        // Tel
        if (isbFields.getAdditionalPersonToInvolve2Tel() != null) {
          text.append("<br/>").append(isbFields.getAdditionalPersonToInvolve2Tel());
        }
      }
      Section3 s3 = new Section3();
      s3.setSectionId(CDAUUID.generateUUIDString());
      s3.setTitle("Additional Persons to be Involved in Decisions");
      s3.setText(text.toString());
      s2.addSection3(s3);
    }
   
   
    // Other relevant information
    if (isbFields.getOtherRelevantInformation() != null) {
      Section3 s3 = new Section3();
      s3.setSectionId(CDAUUID.generateUUIDString());
      s3.setTitle("Other Relevant Issues or Preferences about Provision of Care");
      s3.setText(isbFields.getOtherRelevantInformation());
      s2.addSection3(s3);
    }
   
    template.addSection2(s2);
   
    return template;
  }
 
 
  public static TextSection createTextSection11_PersonCompletingRecord(EndOfLifeCareISBFields isbFields) {
    TextSection template = new TextSection();
    template.setSectionId(CDAUUID.generateUUIDString());
    template.setTitle("");
   
    Section2 s2 = new Section2();
    s2.setSectionId(CDAUUID.generateUUIDString());
    s2.setTitle("Person completing record");
   
    if (isbFields.getEpaccsRecordAuthorName() != null) {
      StringBuilder text = new StringBuilder();
      // We need to turn the structured last amending author information into some nice human readable text
      text.append(HumanReadableFormatter.makeHumanReadablePersonDetails(
                          isbFields.getEpaccsRecordAuthorName(),
                          isbFields.getEpaccsRecordAuthorRole(),
                          isbFields.getEpaccsRecordAuthorOrganisationName()));
      if (isbFields.getEpaccsRecordAuthorTelephone() != null) {
        text.append("<br>").append(isbFields.getEpaccsRecordAuthorTelephone());
      }
      Section3 s3 = new Section3();
      s3.setSectionId(CDAUUID.generateUUIDString());
      s3.setTitle("Original EPaCCS Record Created By");
      s3.setText(text.toString());
      s2.addSection3(s3);
    }
   
    if (isbFields.getEpaccsRecordUpdateAuthorName() != null) {
      StringBuilder text = new StringBuilder();
      // We need to turn the structured last amending author information into some nice human readable text
      text.append(HumanReadableFormatter.makeHumanReadablePersonDetails(
                          isbFields.getEpaccsRecordUpdateAuthorName(),
                          isbFields.getEpaccsRecordUpdateAuthorRole(),
                          isbFields.getEpaccsRecordUpdateAuthorOrganisationName()));
      if (isbFields.getEpaccsRecordUpdateAuthorTelephone() != null) {
        text.append("<br>").append(isbFields.getEpaccsRecordUpdateAuthorTelephone());
      }
      Section3 s3 = new Section3();
      s3.setSectionId(CDAUUID.generateUUIDString());
      s3.setTitle("EPaCCS Record Last Amended By");
      s3.setText(text.toString());
      s2.addSection3(s3);
    }
   
    return template;
  }
 
  public static TextSection createTextSection12_Plan(EndOfLifeCareISBFields isbFields) {
    TextSection template = new TextSection();
    template.setSectionId(CDAUUID.generateUUIDString());
    template.setTitle("Plan and requested actions");
   
    // Record Review Date
    if (isbFields.getEpaccsRecordReviewDate() != null) {
      Section2 s2 = new Section2();
      s2.setSectionId(CDAUUID.generateUUIDString());
      s2.setTitle("Actions");
      Section3 s3c = new Section3();
      s3c.setSectionId(CDAUUID.generateUUIDString());
      s3c.setTitle("Record Review Date");
      s3c.setText(isbFields.getEpaccsRecordReviewDate().getDisplayString());
      s2.addSection3(s3c);
      template.addSection2(s2);
    }
   
    // DNACPR
    if (isbFields.getDNACPR() != null) {
      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>");
     
      Section2 s2 = new Section2();
      s2.setSectionId(CDAUUID.generateUUIDString());
      s2.setTitle("DNACPR");
      s2.setText(dnacpr.toString());
     
      // Creation date
      template.setTimeAuthored(isbFields.getDNACPRCreatedDate());
      // Author: Senior Responsible Clinician
      template.setAuthor(createSeniorResponsibleClinicianAuthor(isbFields));
     
      if (isbFields.getDNACPRLocation() != null) {
        Section3 s3 = new Section3();
        s3.setSectionId(CDAUUID.generateUUIDString());
        s3.setTitle("Location of DNACPR documentation");
        s3.setText(isbFields.getDNACPRLocation());
        s2.addSection3(s3);
      }
      template.addSection2(s2);
    }
    return template;
  }
 
  public static TextSection createTextSection13_Social(EndOfLifeCareISBFields isbFields) {
    TextSection template = new TextSection();
    template.setSectionId(CDAUUID.generateUUIDString());
    template.setTitle("Social context");
   
    Section2 s2 = new Section2();
    s2.setSectionId(CDAUUID.generateUUIDString());
    s2.setTitle("Services and care");
   
    StringBuilder table = new StringBuilder("<table width=\"100%\"><tbody><tr align=\"left\" valign=\"top\"><th>Relationship with patient</th><th>Carer Details</th></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>");
       }
    }
    // 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>");
    }
   
    table.append("</tbody></table>");
    s2.setText(table.toString());
    template.addSection2(s2);
   
    return template;
  }
  public static TextSection createTextSection14_SpecialRequirements(EndOfLifeCareISBFields isbFields) {
    if (isbFields.getPatientDisability() == null) {
      return null;
    }
    TextSection template = new TextSection();
    template.setSectionId(CDAUUID.generateUUIDString());
    template.setTitle("Special requirements");
    Section2 s2c = new Section2();
    s2c.setSectionId(CDAUUID.generateUUIDString());
    s2c.setTitle("Disability");
    s2c.setText(isbFields.getPatientDisability());
    template.addSection2(s2c);   
    return template;
  }
 
  // ************** Non-Standard Headings - TBC *******************
  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 createTextSection_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.EndOfLifeCareDocumentCreationCDGRSHelper

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.