diff --git a/src/extractors/CSVClinicalTrialInformationExtractor.js b/src/extractors/CSVClinicalTrialInformationExtractor.js index 73b431f0..2ca44d58 100644 --- a/src/extractors/CSVClinicalTrialInformationExtractor.js +++ b/src/extractors/CSVClinicalTrialInformationExtractor.js @@ -4,6 +4,7 @@ const { firstEntryInBundle, getEmptyBundle } = require('../helpers/fhirUtils'); const { getPatientFromContext } = require('../helpers/contextUtils'); const { generateMcodeResources } = require('../templates'); const logger = require('../helpers/logger'); +const { formatDateTime } = require('../helpers/dateUtils'); const { CSVClinicalTrialInformationSchema } = require('../helpers/schemas/csv'); @@ -25,6 +26,8 @@ class CSVClinicalTrialInformationExtractor extends BaseCSVExtractor { trialresearchid: trialResearchID, trialstatus: trialStatus, trialresearchsystem: trialResearchSystem, + startdate: startDate, + enddate: endDate, } = clinicalTrialData; const { clinicalSiteID, clinicalSiteSystem } = this; @@ -40,6 +43,8 @@ class CSVClinicalTrialInformationExtractor extends BaseCSVExtractor { trialResearchID, patientId, trialResearchSystem, + startDate: !startDate ? null : formatDateTime(startDate), + endDate: !endDate ? null : formatDateTime(endDate), }, formattedDataStudy: { trialStatus, diff --git a/src/helpers/schemas/csv.js b/src/helpers/schemas/csv.js index 04f813a7..f0de3fef 100644 --- a/src/helpers/schemas/csv.js +++ b/src/helpers/schemas/csv.js @@ -54,6 +54,8 @@ const CSVClinicalTrialInformationSchema = { { name: 'trialResearchID', required: true }, { name: 'trialStatus', required: true }, { name: 'trialResearchSystem' }, + { name: 'startDate' }, + { name: 'endDate' }, ], }; diff --git a/src/templates/EncounterTemplate.js b/src/templates/EncounterTemplate.js index 08529212..76f69c41 100644 --- a/src/templates/EncounterTemplate.js +++ b/src/templates/EncounterTemplate.js @@ -1,14 +1,5 @@ -const { ifAllArgsObj } = require('../helpers/templateUtils'); -const { coding, reference } = require('./snippets'); - -function periodTemplate({ startDate, endDate }) { - return { - period: { - start: startDate, - end: endDate, - }, - }; -} +const { ifAllArgsObj, ifSomeArgsObj } = require('../helpers/templateUtils'); +const { coding, reference, periodTemplate } = require('./snippets'); function classTemplate({ classCode, classSystem }) { return { @@ -42,7 +33,7 @@ function encounterTemplate({ ...classTemplate({ classCode, classSystem }), ...subjectTemplate({ subject }), ...ifAllArgsObj(typeTemplate)({ typeCode, typeSystem }), - ...ifAllArgsObj(periodTemplate)({ startDate, endDate }), + ...ifSomeArgsObj(periodTemplate)({ startDate, endDate }), }; } diff --git a/src/templates/ResearchSubjectTemplate.js b/src/templates/ResearchSubjectTemplate.js index 3e980ffe..cd86a5a0 100644 --- a/src/templates/ResearchSubjectTemplate.js +++ b/src/templates/ResearchSubjectTemplate.js @@ -1,4 +1,5 @@ -const { reference, identifier, identifierArr } = require('./snippets'); +const { reference, identifier, identifierArr, periodTemplate } = require('./snippets'); +const { ifSomeArgsObj } = require('../helpers/templateUtils'); function studyTemplate(trialResearchID, trialResearchSystem) { return { @@ -38,6 +39,8 @@ function researchSubjectTemplate({ trialResearchID, patientId, trialResearchSystem, + startDate, + endDate, }) { if (!(id && enrollmentStatus && trialSubjectID && trialResearchID && patientId)) { throw Error('Trying to render a ResearchStudyTemplate, but a required argument is missing; ensure that id, trialStatus, trialResearchID, clinicalSiteID are all present'); @@ -50,6 +53,7 @@ function researchSubjectTemplate({ ...studyTemplate(trialResearchID, trialResearchSystem), ...individualTemplate(patientId), ...researchSubjectIdentifiersTemplate(trialSubjectID), + ...ifSomeArgsObj(periodTemplate)({ startDate, endDate }), }; } diff --git a/src/templates/snippets/index.js b/src/templates/snippets/index.js index f21199cb..b73fde20 100644 --- a/src/templates/snippets/index.js +++ b/src/templates/snippets/index.js @@ -10,6 +10,7 @@ const { stagingMethodTemplate } = require('./cancerStaging'); const { medicationTemplate } = require('./medication'); const { subjectTemplate } = require('./subject'); const { treatmentReasonTemplate } = require('./treatmentReason'); +const { periodTemplate } = require('./period'); module.exports = { bodySiteTemplate, @@ -22,6 +23,7 @@ module.exports = { medicationTemplate, meta, narrative, + periodTemplate, reference, stagingMethodTemplate, subjectTemplate, diff --git a/src/templates/snippets/period.js b/src/templates/snippets/period.js new file mode 100644 index 00000000..d9e62b20 --- /dev/null +++ b/src/templates/snippets/period.js @@ -0,0 +1,12 @@ +function periodTemplate({ startDate, endDate }) { + return { + period: { + ...(startDate && { start: startDate }), + ...(endDate && { end: endDate }), + }, + }; +} + +module.exports = { + periodTemplate, +}; diff --git a/test/extractors/CSVClinicalTrialInformationExtractor.test.js b/test/extractors/CSVClinicalTrialInformationExtractor.test.js index d8fee6b5..4f8a22d8 100644 --- a/test/extractors/CSVClinicalTrialInformationExtractor.test.js +++ b/test/extractors/CSVClinicalTrialInformationExtractor.test.js @@ -40,6 +40,8 @@ describe('CSVClinicalTrialInformationExtractor', () => { expect(csvClinicalTrialInformationExtractor.joinClinicalTrialData(clonedData, patientId)).toEqual(expect.anything()); if (key === 'patientId') return; // MRN is optional if (key === 'trialresearchsystem') return; // trialResearchSystem is optional + if (key === 'startdate') return; // startDate is optional + if (key === 'enddate') return; // endDate is optional delete clonedData[key]; expect(() => csvClinicalTrialInformationExtractor.joinClinicalTrialData(clonedData, patientId)).toThrow(new Error(expectedErrorString)); }); @@ -52,6 +54,8 @@ describe('CSVClinicalTrialInformationExtractor', () => { trialResearchID: firstClinicalTrialInfoResponse.trialresearchid, patientId, trialResearchSystem: firstClinicalTrialInfoResponse.trialresearchsystem, + startDate: firstClinicalTrialInfoResponse.startdate, + endDate: firstClinicalTrialInfoResponse.enddate, }, formattedDataStudy: { trialStatus: firstClinicalTrialInfoResponse.trialstatus, diff --git a/test/extractors/fixtures/csv-clinical-trial-information-bundle.json b/test/extractors/fixtures/csv-clinical-trial-information-bundle.json index f583d355..792b2caf 100644 --- a/test/extractors/fixtures/csv-clinical-trial-information-bundle.json +++ b/test/extractors/fixtures/csv-clinical-trial-information-bundle.json @@ -3,10 +3,10 @@ "type": "collection", "entry": [ { - "fullUrl": "urn:uuid:a9235b06dfe8c24b40b938c7a1265ed3087cf0fa43ef0f11375effbb25ecca25", + "fullUrl": "urn:uuid:aea78e13731d4b105b3a731a48ce77602f159d46299bb02aaaf80e49530115bd", "resource": { "resourceType": "ResearchSubject", - "id": "a9235b06dfe8c24b40b938c7a1265ed3087cf0fa43ef0f11375effbb25ecca25", + "id": "aea78e13731d4b105b3a731a48ce77602f159d46299bb02aaaf80e49530115bd", "identifier": [ { "system": "http://example.com/clinicaltrialsubjectids", @@ -26,6 +26,10 @@ "individual": { "reference": "urn:uuid:mrn-1", "type": "Patient" + }, + "period": { + "start": "2020-01-01", + "end": "2021-01-01" } } }, diff --git a/test/extractors/fixtures/csv-clinical-trial-information-module-response.json b/test/extractors/fixtures/csv-clinical-trial-information-module-response.json index f7317f26..591f8836 100644 --- a/test/extractors/fixtures/csv-clinical-trial-information-module-response.json +++ b/test/extractors/fixtures/csv-clinical-trial-information-module-response.json @@ -5,6 +5,8 @@ "enrollmentstatus": "example-enrollment-status", "trialresearchid": "example-researchId", "trialstatus": "example-trialStatus", - "trialresearchsystem":"example-system" + "trialresearchsystem":"example-system", + "startdate": "2020-01-01", + "enddate": "2021-01-01" } ] diff --git a/test/sample-client-data/clinical-trial-information.csv b/test/sample-client-data/clinical-trial-information.csv index be74ba37..c5b37081 100644 --- a/test/sample-client-data/clinical-trial-information.csv +++ b/test/sample-client-data/clinical-trial-information.csv @@ -1,4 +1,4 @@ -mrn,trialSubjectID,enrollmentStatus,trialResearchID,trialStatus,trialResearchSystem -123,subjectId-1,potential-candidate,researchId-1,approved,system-1 -456,subjectId-2,on-study-intervention,researchId-1,completed,system-2 -789,subjectId-3,on-study-observation,researchId-2,active, +mrn,trialSubjectID,enrollmentStatus,trialResearchID,trialStatus,trialResearchSystem,startDate,endDate +123,subjectId-1,potential-candidate,researchId-1,approved,system-1,2020-01-01,2021-01-03 +456,subjectId-2,on-study-intervention,researchId-1,completed,system-2,2023-05-03, +789,subjectId-3,on-study-observation,researchId-2,active,,, diff --git a/test/templates/fixtures/research-subject-resource.json b/test/templates/fixtures/research-subject-resource.json index 58c133e0..e4ec2245 100644 --- a/test/templates/fixtures/research-subject-resource.json +++ b/test/templates/fixtures/research-subject-resource.json @@ -16,5 +16,9 @@ }, "individual": { "reference": "urn:uuid:mCODEPatient1" + }, + "period": { + "start": "2020-01-01", + "end": "2021-01-01" } } diff --git a/test/templates/researchSubject.test.js b/test/templates/researchSubject.test.js index 172b87a2..dadd650e 100644 --- a/test/templates/researchSubject.test.js +++ b/test/templates/researchSubject.test.js @@ -8,6 +8,8 @@ const VALID_DATA = { trialSubjectID: 'trial-123', trialResearchID: 'rs1', patientId: 'mCODEPatient1', + startDate: '2020-01-01', + endDate: '2021-01-01', }; const INVALID_DATA = { @@ -16,6 +18,8 @@ const INVALID_DATA = { trialResearchID: 'rs1', patientId: 'mCODEPatient1', trialSubjectID: null, + startDate: '2020-01-01', + endDate: '2021-01-01', }; describe('test ResearchSubject template', () => { @@ -25,6 +29,8 @@ describe('test ResearchSubject template', () => { expect(generatedResearchSubject.id).toEqual(validResearchSubject.id); expect(generatedResearchSubject.trialStatus).toEqual(validResearchSubject.trialStatus); expect(generatedResearchSubject.trialResearchID).toEqual(validResearchSubject.trialResearchID); + expect(generatedResearchSubject.period.start).toEqual(validResearchSubject.period.start); + expect(generatedResearchSubject.period.end).toEqual(validResearchSubject.period.end); expect(isValidFHIR(generatedResearchSubject)).toBeTruthy(); });