import type { Organization } from 'fhir/r4'; /** * /611 - WHETHER THIS PRACTICE CAN ACTUALLY SEND A FAX. * * THE FAX TAB'S WHOLE DESIGN TURNS ON THIS ANSWER, and states the control: *"the fax option * must be VISIBLY UNAVAILABLE rather than broken. A button that silently does nothing is worse than one * that says why - a coordinator will click it, believe the referral was sent, and stop chasing it. That * is a patient not getting to a specialist."* The button exists only when this returns settings that * can actually send. * * IT MIRRORS THE SERVER'S `getFaxVendorPublic` DELIBERATELY, INCLUDING THE VENDOR ALLOW-LIST. A stored * id we no longer have an adapter for is not "some vendor" - it is a practice whose fax button would * resolve to nothing at the far end, and it must read as unconfigured here so they are told to choose * again rather than shown a button the server will refuse. * * THE TWO COPIES CAN DRIFT, and that is the honest cost of the client knowing this at all. The * alternative - a read endpoint - is a round trip for a fact the Organization already carries, and the * server refuses independently either way: this decides whether to OFFER the button, never whether the * send is allowed. */ export const ORGANIZATION_FAX_VENDOR_EXTENSION_URL = 'https://akashichealthrecords.com/fhir/StructureDefinition/organization-fax-vendor'; /** Kept in step with `FAX_VENDORS` in the api's `faxVendor.ts`. */ export const FAX_VENDOR_IDS = ['phaxio', 'documo', 'sinch'] as const; export type FaxVendorId = (typeof FAX_VENDOR_IDS)[number]; export interface OrganizationFaxSettings { vendorId: FaxVendorId; fromNumber?: string; credentialsConfigured: boolean; } const isFaxVendorId = (value: unknown): value is FaxVendorId => typeof value === 'string' && (FAX_VENDOR_IDS as readonly string[]).includes(value); export const readOrganizationFaxSettings = ( organization?: Organization | null, ): OrganizationFaxSettings | undefined => { const extension = organization?.extension?.find( (entry) => entry.url === ORGANIZATION_FAX_VENDOR_EXTENSION_URL, ); if (!extension) return undefined; const vendorId = extension.extension?.find((entry) => entry.url === 'vendorId')?.valueString; if (!isFaxVendorId(vendorId)) return undefined; return { vendorId, fromNumber: extension.extension?.find((entry) => entry.url === 'fromNumber')?.valueString, credentialsConfigured: extension.extension?.find((entry) => entry.url === 'credentialsConfigured')?.valueBoolean ?? false, }; }; /** * CHOSEN IS NOT THE SAME AS READY, and conflating them is how the "visibly unavailable" control gets * broken by accident. A practice can pick a vendor and never save the account details - the settings * screen writes those in two steps - and the server refuses that case by name. Offering a send button * to a half-configured practice produces exactly the click-and-stop-chasing this design forbids. */ export const canSendFax = (organization?: Organization | null): boolean => readOrganizationFaxSettings(organization)?.credentialsConfigured === true;