Skip to content

Commit a2dac7a

Browse files
authored
add pharmacy details to cds hooks details (#178)
* add pharmacy details to cds hooks details * run lint * update pharmacy resource to healthcare service * run prettier/lint * put pharmacy info in its own card * lint * add markdown bolding to pharmacy status
1 parent 2b86909 commit a2dac7a

File tree

2 files changed

+111
-11
lines changed

2 files changed

+111
-11
lines changed

src/fhir/utilities.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -311,31 +311,31 @@ export class FhirUtilities {
311311

312312
const medicationRequirements = [
313313
{
314-
stakeholderId: 'Organization/pharm0111',
314+
stakeholderId: 'HealthcareService/pharm0111',
315315
completed: true,
316316
requirementName: 'Pharmacist Enrollment',
317317
drugName: 'Turalio',
318318
completedQuestionnaire: null,
319319
case_numbers: []
320320
},
321321
{
322-
stakeholderId: 'Organization/pharm0111',
322+
stakeholderId: 'HealthcareService/pharm0111',
323323
completed: true,
324324
requirementName: 'Pharmacist Enrollment',
325325
drugName: 'TIRF',
326326
completedQuestionnaire: null,
327327
case_numbers: []
328328
},
329329
{
330-
stakeholderId: 'Organization/pharm0111',
330+
stakeholderId: 'HealthcareService/pharm0111',
331331
completed: true,
332332
requirementName: 'Pharmacist Knowledge Assessment',
333333
drugName: 'TIRF',
334334
completedQuestionnaire: null,
335335
case_numbers: []
336336
},
337337
{
338-
stakeholderId: 'Organization/pharm0111',
338+
stakeholderId: 'HealthcareService/pharm0111',
339339
completed: true,
340340
requirementName: 'Pharmacist Enrollment',
341341
drugName: 'Isotretinoin',

src/hooks/hookResources.ts

Lines changed: 107 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import {
66
Patient,
77
Bundle,
88
Medication,
9-
BundleEntry
9+
BundleEntry,
10+
HealthcareService
1011
} from 'fhir/r4';
1112
import Card, { Link, Suggestion, Action } from '../cards/Card';
1213
import { HookPrefetch, TypedRequestBody } from '../rems-cds-hooks/resources/HookTypes';
@@ -16,7 +17,8 @@ import {
1617
Requirement,
1718
medicationCollection,
1819
remsCaseCollection,
19-
Medication as MongooseMedication
20+
Medication as MongooseMedication,
21+
metRequirementsCollection
2022
} from '../fhir/models';
2123

2224
import axios from 'axios';
@@ -368,6 +370,12 @@ export const handleCardOrder = async (
368370
): Promise<void> => {
369371
const patient = resource?.resourceType === 'Patient' ? resource : undefined;
370372

373+
console.log('hydratedPrefetch: ' + JSON.stringify(hydratedPrefetch));
374+
375+
const pharmacy = hydratedPrefetch?.pharmacy as HealthcareService;
376+
377+
console.log(' Pharmacy: ' + pharmacy);
378+
371379
const errorCard = getErrorCard(hydratedPrefetch, contextRequest);
372380
if (errorCard) {
373381
res.json(errorCard);
@@ -397,11 +405,56 @@ export const handleCardOrder = async (
397405

398406
const codeRule = (code && codeMap[code]) || [];
399407

400-
const cards: Card[] = codeRule
401-
.map(getCardOrEmptyArrayFromRules(display, drug, remsCase, request, patient))
402-
.flat();
408+
const cardPromises = codeRule.map(
409+
getCardOrEmptyArrayFromRules(display, drug, remsCase, request, patient)
410+
);
403411

404-
res.json({ cards });
412+
const remsCards: Card[] = (await Promise.all(cardPromises)).flat();
413+
414+
// Create pharmacy status card once (if pharmacy exists)
415+
const allCards: Card[] = [];
416+
if (pharmacy) {
417+
const pharmacyStatusCard = await createPharmacyStatusCard(pharmacy, drug, display);
418+
if (pharmacyStatusCard) {
419+
allCards.push(pharmacyStatusCard);
420+
}
421+
}
422+
423+
// Add all REMS cards after the pharmacy card
424+
allCards.push(...remsCards);
425+
426+
res.json({ cards: allCards });
427+
};
428+
429+
const createPharmacyStatusCard = async (
430+
pharmacy: HealthcareService,
431+
drug: MongooseMedication | null,
432+
display: string | undefined
433+
): Promise<Card | null> => {
434+
if (!pharmacy) {
435+
return null;
436+
}
437+
438+
const isCertified = await checkPharmacyCertification(pharmacy, drug?.code);
439+
const pharmacyName = pharmacy.name || 'Selected pharmacy';
440+
const locationInfo = pharmacy.location?.[0]?.display;
441+
const fullPharmacyName = `${pharmacyName} (${locationInfo})`;
442+
443+
const statusText = `${fullPharmacyName} **is ${
444+
isCertified ? 'certified' : 'not yet certified'
445+
}** for ${display || 'this medication'} REMS dispensing. This medication **${
446+
isCertified ? 'can' : 'cannot yet'
447+
}** be dispensed at this location.`;
448+
449+
const pharmacyStatusCard = new Card(
450+
'Pharmacy Certification Status',
451+
statusText,
452+
source,
453+
isCertified ? 'info' : 'warning'
454+
);
455+
456+
// No links or suggestions for this card - it's informational only
457+
return pharmacyStatusCard;
405458
};
406459

407460
const getCardOrEmptyArrayFromRules =
@@ -412,7 +465,7 @@ const getCardOrEmptyArrayFromRules =
412465
request: MedicationRequest,
413466
patient: Patient | undefined
414467
) =>
415-
(rule: CardRule): Card | never[] => {
468+
async (rule: CardRule): Promise<Card | never[]> => {
416469
const card = new Card(
417470
rule.summary || display || 'Rems',
418471
rule.cardDetails || CARD_DETAILS,
@@ -462,6 +515,53 @@ const getCardOrEmptyArrayFromRules =
462515
return [];
463516
};
464517

518+
const checkPharmacyCertification = async (
519+
pharmacy: HealthcareService | undefined,
520+
drugCode: string | undefined
521+
) => {
522+
if (!pharmacy?.id || !drugCode) {
523+
return false;
524+
}
525+
526+
const drug = await medicationCollection
527+
.findOne({
528+
code: drugCode,
529+
codeSystem: 'http://www.nlm.nih.gov/research/umls/rxnorm'
530+
})
531+
.exec();
532+
533+
if (!drug) {
534+
return false;
535+
}
536+
537+
const requiredPharmacistRequirements = drug.requirements.filter(
538+
requirement => requirement.stakeholderType === 'pharmacist' && requirement.requiredToDispense
539+
);
540+
541+
if (requiredPharmacistRequirements.length === 0) {
542+
return true;
543+
}
544+
545+
const pharmacyId = `HealthcareService/${pharmacy.id}`;
546+
547+
for (const requirement of requiredPharmacistRequirements) {
548+
const metRequirement = await metRequirementsCollection
549+
.findOne({
550+
stakeholderId: pharmacyId,
551+
requirementName: requirement.name,
552+
drugName: drug.name,
553+
completed: true
554+
})
555+
.exec();
556+
557+
if (!metRequirement) {
558+
return false;
559+
}
560+
}
561+
562+
return true;
563+
};
564+
465565
const getSmartLinks = (
466566
requirements: Requirement[],
467567
request: MedicationRequest,

0 commit comments

Comments
 (0)