import type { Appointment, Location, Organization, Reference } from "fhir/r4"; import type { PractitionerWithRoles } from "../services/PractitionerService.tsx"; import { appointmentOrgRef } from "./patientOrganizations"; import { appointmentLocationId } from "./appointmentDirections"; import { isVirtualLocation } from "./roomLocation"; import { locationTimeZoneOf } from "./practiceTimezone"; import { ORGANIZATION_TAG_SYSTEM } from "./carePlanAuthorship"; // A patient can book at several practices, so each appointment names its own; the portal's // practice is never a stand-in for one the record does not prove. const organizationIdOf = (reference?: string): string | undefined => reference?.startsWith("Organization/") ? reference.slice("Organization/".length) || undefined : undefined; /** The appointment's site from the loaded Locations, or undefined when it names none we hold. */ const siteOf = (appointment: Appointment, locations: readonly Location[]): Location | undefined => { const locationId = appointmentLocationId(appointment); return locationId ? locations.find((candidate) => candidate.id === locationId) : undefined; }; /** Its Location's managing organization, else its Organization participant or its clinician's role. */ export const appointmentPracticeRef = ( appointment: Appointment, practitioners: readonly PractitionerWithRoles[], locations: readonly Location[], ): Reference | undefined => { const managing = siteOf(appointment, locations)?.managingOrganization; if (organizationIdOf(managing?.reference)) return managing; const named = appointmentOrgRef(appointment, practitioners); if (named) return named; // The server stamps every booking with its practice; this is the answer when neither the site nor // the clinician belongs to the practice the patient is signed in at. const tagged = appointment.meta?.tag?.find((tag) => tag.system === ORGANIZATION_TAG_SYSTEM)?.code; return tagged ? { reference: `Organization/${tagged}` } : undefined; }; export const appointmentPracticeId = ( appointment: Appointment, practitioners: readonly PractitionerWithRoles[], locations: readonly Location[], ): string | undefined => organizationIdOf(appointmentPracticeRef(appointment, practitioners, locations)?.reference); export type AppointmentPractice = { organization?: Organization; zone: string | null }; /** * The practice and clock one appointment is proven to belong to. The clock is its physical site's, * else its practice's (primary location, then organization); a virtual room has no clock of its own. * Anything unproven or still being read comes back empty. */ export const appointmentPractice = ( appointment: Appointment, known: { practitioners: readonly PractitionerWithRoles[]; locations: readonly Location[]; organizations: readonly Organization[]; zoneOf: (organizationId: string) => string | null; }, ): AppointmentPractice => { const reference = appointmentPracticeRef(appointment, known.practitioners, known.locations); const id = organizationIdOf(reference?.reference); const display = reference?.display?.trim(); const loaded = id ? known.organizations.find((candidate) => candidate.id === id) : undefined; const organization: Organization | undefined = loaded ?? (display ? { resourceType: "Organization", ...(id ? { id } : {}), name: display } : undefined); const site = siteOf(appointment, known.locations); const siteZone = site && !isVirtualLocation(site) ? locationTimeZoneOf(site) : null; return { organization, zone: siteZone ?? (id ? known.zoneOf(id) : null) }; }; /** * The practice that owns the visit, for a WRITE: the one practice tag the server stamped on the booking. * Never the site's manager, a participant or the portal's practice, which can name another. Missing, or two * different stamps, is no owner. */ export const appointmentOwningPracticeId = (appointment: Appointment): string | undefined => { const owners = new Set((appointment.meta?.tag ?? []) .filter((tag) => tag.system === ORGANIZATION_TAG_SYSTEM && tag.code) .map((tag) => tag.code as string)); return owners.size === 1 ? [...owners][0] : undefined; };