import type { Coding, HealthcareService } from 'fhir/r4'; import type { ServiceCategory } from './serviceCategories'; // The practice category (service taxonomy code) a service was added under. Not every category has a // verified standard category coding, so services are grouped under their category by this. export const SERVICE_PRACTICE_CATEGORY_EXTENSION_URL = 'https://akashichealthrecords.com/fhir/StructureDefinition/service-practice-category'; export const servicePracticeCategoryOf = (service: HealthcareService | null | undefined): string | undefined => service?.extension?.find((extension) => extension.url === SERVICE_PRACTICE_CATEGORY_EXTENSION_URL)?.valueCode; export const applyServicePracticeCategory = (service: HealthcareService, code: string | undefined): HealthcareService => { const others = (service.extension ?? []).filter((extension) => extension.url !== SERVICE_PRACTICE_CATEGORY_EXTENSION_URL); const extension = code ? [...others, { url: SERVICE_PRACTICE_CATEGORY_EXTENSION_URL, valueCode: code }] : others; const next: HealthcareService = { ...service, extension }; if (extension.length === 0) delete next.extension; return next; }; const codingKey = (coding: Coding) => `${coding.system}|${coding.code}`; // Swaps the taxonomy-managed standard category coding for another; codings the taxonomy does not manage stay. export const replaceStandardCategory = ( service: HealthcareService, categories: ServiceCategory[], next: Coding | undefined, ): HealthcareService => { const managed = new Set(categories.flatMap((category) => (category.standardCategory ? [codingKey(category.standardCategory)] : []))); const kept = (service.category ?? []).flatMap((concept) => { const coding = (concept.coding ?? []).filter((item) => !managed.has(codingKey(item))); if (coding.length === (concept.coding ?? []).length) return [concept]; return coding.length > 0 ? [{ ...concept, coding }] : []; }); const category = next ? [...kept, { coding: [next] }] : kept; const result: HealthcareService = { ...service, category }; if (category.length === 0) delete result.category; return result; };