Skip to content

Commit 3e9fda4

Browse files
authored
Submit-etasu-refactor (#175)
* change rems etasu url * run linting * endpoint path fix * return 201 status code * 201 status code
1 parent a46c443 commit 3e9fda4

3 files changed

Lines changed: 137 additions & 124 deletions

File tree

src/config.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,15 @@ export default {
112112
},
113113
questionnaireresponse: {
114114
service: './src/services/questionnaireresponse.service.ts',
115-
versions: [fhirConstants.VERSIONS['4_0_0']]
115+
versions: [fhirConstants.VERSIONS['4_0_0']],
116+
operation: [
117+
{
118+
name: 'submit',
119+
route: '/$submit',
120+
method: 'POST',
121+
reference: 'http://hl7.org/fhir/OperationDefinition/QuestionnaireResponse-submit'
122+
}
123+
]
116124
},
117125
valueset: {
118126
service: './src/services/valueset.service.ts',

src/lib/etasu.ts

Lines changed: 110 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,6 @@ const createMetRequirementAndNewCase = async (
207207
drug: Medication,
208208
requirement: Requirement,
209209
questionnaireResponse: QuestionnaireResponse,
210-
res: Response,
211210
reqStakeholderReference: string,
212211
practitionerReference: string,
213212
pharmacistReference: string,
@@ -257,11 +256,9 @@ const createMetRequirementAndNewCase = async (
257256
};
258257

259258
if (!(await createAndPushMetRequirements(metReq, remsRequest))) {
260-
res.status(200);
261-
message = 'ERROR: failed to create new met requirement for form initial to case';
259+
message = 'ERROR: failed to create new met requirement and initial case';
262260
console.log(message);
263-
res.send(message);
264-
return res;
261+
throw new Error(message);
265262
}
266263

267264
// iterate through all other requirements again to create corresponding false metRequirements / assign to existing
@@ -307,7 +304,7 @@ const createMetRequirementAndNewCase = async (
307304
remsRequestCompletedStatus = 'Pending';
308305

309306
if (!(await createAndPushMetRequirements(newMetReq, remsRequest))) {
310-
message = 'ERROR: failed to create new met requirement for form initial to case';
307+
message = 'ERROR: failed to create new met requirement for form and initial case';
311308
console.log(message);
312309
}
313310
}
@@ -316,17 +313,16 @@ const createMetRequirementAndNewCase = async (
316313

317314
remsRequest.status = remsRequestCompletedStatus;
318315
const returnedRemsRequestDoc = await remsCaseCollection.create(remsRequest);
319-
res.status(201);
320-
res.send(returnedRemsRequestDoc);
321316

322-
return res;
317+
return {
318+
returnedRemsRequestDoc
319+
};
323320
};
324321

325322
const createMetRequirementAndUpdateCase = async (
326323
drug: Medication,
327324
requirement: Requirement,
328325
questionnaireResponse: QuestionnaireResponse,
329-
res: Response,
330326
reqStakeholderReference: string
331327
) => {
332328
let returnedMetReqDoc;
@@ -403,17 +399,16 @@ const createMetRequirementAndUpdateCase = async (
403399
returnedMetReqDoc = await createMetRequirements(newMetReq);
404400
}
405401

406-
res.status(201);
407-
res.send(returnedMetReqDoc);
408-
return res;
402+
return {
403+
returnedMetReqDoc
404+
};
409405
};
410406

411407
const createMetRequirementAndUpdateCaseNotRequiredToDispense = async (
412408
patient: Patient,
413409
drug: Medication,
414410
requirement: Requirement,
415411
questionnaireResponse: QuestionnaireResponse,
416-
res: Response,
417412
reqStakeholderReference: string
418413
) => {
419414
// Find the specific case associated with an individual patient for the patient status form
@@ -473,120 +468,17 @@ const createMetRequirementAndUpdateCaseNotRequiredToDispense = async (
473468
console.log(message);
474469
}
475470

476-
res.status(201);
477471
if (returnRemsRequest) {
478-
res.send(remsRequestToUpdate);
472+
return {
473+
remsRequestToUpdate
474+
};
479475
} else {
480-
res.send(message);
476+
return {
477+
message
478+
};
481479
}
482-
return res;
483480
};
484481

485-
router.post('/met', async (req: Request, res: Response) => {
486-
try {
487-
const requestBody = req.body as Bundle;
488-
489-
// extract params and questionnaire response identifier
490-
const params = getResource(
491-
requestBody,
492-
(requestBody.entry?.[0]?.resource as MessageHeader)?.focus?.[0]?.reference || ''
493-
) as Parameters;
494-
const questionnaireResponse = getQuestionnaireResponse(requestBody) as QuestionnaireResponse;
495-
const questionnaireStringArray = questionnaireResponse?.questionnaire?.split('/');
496-
const requirementId = questionnaireStringArray?.[questionnaireStringArray.length - 1];
497-
498-
// stakeholder and medication references
499-
let prescriptionReference = '';
500-
let practitionerReference = '';
501-
let pharmacistReference = '';
502-
let patientReference = '';
503-
for (const param of params.parameter || []) {
504-
if (param.name === 'prescription') {
505-
prescriptionReference = param.valueReference?.reference || '';
506-
} else if (param.name === 'prescriber') {
507-
practitionerReference = param.valueReference?.reference || '';
508-
} else if (param.name === 'pharmacy') {
509-
pharmacistReference = param.valueReference?.reference || '';
510-
} else if (param.name === 'source-patient') {
511-
patientReference = param.valueReference?.reference || '';
512-
}
513-
}
514-
515-
// obtain drug information from database
516-
const prescription = getResource(requestBody, prescriptionReference) as MedicationRequest;
517-
const medicationCode = getDrugCodeFromMedicationRequest(prescription) as Coding;
518-
const prescriptionSystem = medicationCode?.system;
519-
const prescriptionCode = medicationCode?.code;
520-
const patient = getResource(requestBody, patientReference) as Patient;
521-
522-
const drug = await medicationCollection
523-
.findOne({
524-
code: prescriptionCode,
525-
codeSystem: prescriptionSystem
526-
})
527-
.exec();
528-
// iterate through each requirement of the drug
529-
if (drug) {
530-
for (const requirement of drug.requirements) {
531-
// figure out which stakeholder the req corresponds to
532-
const stakeholder = requirement.stakeholderType;
533-
const stakeholderReference =
534-
stakeholder === 'prescriber'
535-
? practitionerReference
536-
: stakeholder === 'pharmacist'
537-
? pharmacistReference
538-
: patientReference;
539-
540-
// if the requirement is the one submitted continue
541-
if (requirement.resourceId === requirementId) {
542-
// if the req submitted is a patient enrollment form and requires creating a new case
543-
if (requirement.createNewCase) {
544-
await createMetRequirementAndNewCase(
545-
patient,
546-
drug,
547-
requirement,
548-
questionnaireResponse,
549-
res,
550-
stakeholderReference,
551-
practitionerReference,
552-
pharmacistReference,
553-
patientReference
554-
);
555-
556-
return;
557-
} else {
558-
// If it's not the patient status requirement
559-
if (requirement.requiredToDispense) {
560-
await createMetRequirementAndUpdateCase(
561-
drug,
562-
requirement,
563-
questionnaireResponse,
564-
res,
565-
stakeholderReference
566-
);
567-
return;
568-
} else {
569-
await createMetRequirementAndUpdateCaseNotRequiredToDispense(
570-
patient,
571-
drug,
572-
requirement,
573-
questionnaireResponse,
574-
res,
575-
stakeholderReference
576-
);
577-
return;
578-
}
579-
}
580-
break;
581-
}
582-
}
583-
}
584-
} catch (error) {
585-
console.log(error);
586-
throw error;
587-
}
588-
});
589-
590482
const getResource = (bundle: Bundle, resourceReference: string) => {
591483
const temp = resourceReference.split('/');
592484
const _resourceType = temp[0];
@@ -618,4 +510,99 @@ const getQuestionnaireResponse = (bundle: Bundle) => {
618510
return null;
619511
};
620512

513+
export const processQuestionnaireResponseSubmission = async (requestBody: Bundle): Promise<any> => {
514+
// extract params and questionnaire response identifier
515+
const params = getResource(
516+
requestBody,
517+
(requestBody.entry?.[0]?.resource as MessageHeader)?.focus?.[0]?.reference || ''
518+
) as Parameters;
519+
const questionnaireResponse = getQuestionnaireResponse(requestBody) as QuestionnaireResponse;
520+
const questionnaireStringArray = questionnaireResponse?.questionnaire?.split('/');
521+
const requirementId = questionnaireStringArray?.[questionnaireStringArray.length - 1];
522+
523+
// stakeholder and medication references
524+
let prescriptionReference = '';
525+
let practitionerReference = '';
526+
let pharmacistReference = '';
527+
let patientReference = '';
528+
for (const param of params.parameter || []) {
529+
if (param.name === 'prescription') {
530+
prescriptionReference = param.valueReference?.reference || '';
531+
} else if (param.name === 'prescriber') {
532+
practitionerReference = param.valueReference?.reference || '';
533+
} else if (param.name === 'pharmacy') {
534+
pharmacistReference = param.valueReference?.reference || '';
535+
} else if (param.name === 'source-patient') {
536+
patientReference = param.valueReference?.reference || '';
537+
}
538+
}
539+
540+
// obtain drug information from database
541+
const prescription = getResource(requestBody, prescriptionReference) as MedicationRequest;
542+
const medicationCode = getDrugCodeFromMedicationRequest(prescription) as Coding;
543+
const prescriptionSystem = medicationCode?.system;
544+
const prescriptionCode = medicationCode?.code;
545+
const patient = getResource(requestBody, patientReference) as Patient;
546+
547+
const drug = await medicationCollection
548+
.findOne({
549+
code: prescriptionCode,
550+
codeSystem: prescriptionSystem
551+
})
552+
.exec();
553+
554+
// iterate through each requirement of the drug
555+
if (drug) {
556+
for (const requirement of drug.requirements) {
557+
// figure out which stakeholder the req corresponds to
558+
const stakeholder = requirement.stakeholderType;
559+
const stakeholderReference =
560+
stakeholder === 'prescriber'
561+
? practitionerReference
562+
: stakeholder === 'pharmacist'
563+
? pharmacistReference
564+
: patientReference;
565+
566+
// if the requirement is the one submitted continue
567+
if (requirement.resourceId === requirementId) {
568+
// if the req submitted is a patient enrollment form and requires creating a new case
569+
if (requirement.createNewCase) {
570+
return await createMetRequirementAndNewCase(
571+
patient,
572+
drug,
573+
requirement,
574+
questionnaireResponse,
575+
stakeholderReference,
576+
practitionerReference,
577+
pharmacistReference,
578+
patientReference
579+
);
580+
} else {
581+
// If it's not the patient status requirement
582+
if (requirement.requiredToDispense) {
583+
return await createMetRequirementAndUpdateCase(
584+
drug,
585+
requirement,
586+
questionnaireResponse,
587+
stakeholderReference
588+
);
589+
} else {
590+
return await createMetRequirementAndUpdateCaseNotRequiredToDispense(
591+
patient,
592+
drug,
593+
requirement,
594+
questionnaireResponse,
595+
stakeholderReference
596+
);
597+
}
598+
}
599+
}
600+
}
601+
}
602+
603+
throw new Error('No matching requirement found for the submitted questionnaire');
604+
};
605+
606+
export { getResource, getQuestionnaireResponse };
607+
621608
export default router;

src/services/questionnaireresponse.service.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { FhirUtilities } from '../fhir/utilities';
22
import QuestionnaireResponseModel from '../lib/schemas/resources/QuestionnaireResponse';
3+
import { Bundle } from 'fhir/r4';
4+
import { processQuestionnaireResponseSubmission } from '../lib/etasu';
35

46
module.exports.searchById = async (args: any) => {
57
const { id } = args;
@@ -13,3 +15,19 @@ module.exports.create = async (args: any, req: any) => {
1315
const { base_version } = args;
1416
return await FhirUtilities.store(resource, QuestionnaireResponseModel, base_version);
1517
};
18+
19+
module.exports.submit = async (args: any, context: any, logger: any) => {
20+
logger.info('Running QuestionnaireResponse $submit operation');
21+
22+
try {
23+
const requestBody = args?.resource as Bundle;
24+
const response = await processQuestionnaireResponseSubmission(requestBody);
25+
context.req.res.status(201);
26+
return {
27+
response
28+
};
29+
} catch (error) {
30+
logger.error('Error in QuestionnaireResponse $submit operation:', error);
31+
throw error;
32+
}
33+
};

0 commit comments

Comments
 (0)