UNPKG

@vidal-community/vidal-web-components

Version:

Vidal Web Components

208 lines 11.6 kB
import { EquivalentDrugWithDose } from '../model/equivalentDrugWithDose'; import { useConversionService } from './conversion-service'; import { Dose } from '../model/dose'; export function useDosesCombinationsService() { return dosesCombinationsServiceInstance; } class DosesCombinationsService { constructor() { this.MAX_DECIMALS = 12; } buildDosesCombinations(equivalentDrugsDispensingUnits, equivalentDrugs, prescriptionDoseInDispensingUnit) { if (!prescriptionDoseInDispensingUnit) { return []; } const equivalentDrugCombinations = []; equivalentDrugsDispensingUnits.forEach((dispensingUnit) => { const equivalentDrugWithDoses = []; const allEquivalentDrugUnitaryDoseFractions = []; equivalentDrugs.forEach((equivalentDrug) => { var _a; const equivalentDrugDoseValueInDispensingUnit = (_a = equivalentDrug.dose.find((dose) => dose.unit.uri === dispensingUnit.uri)) === null || _a === void 0 ? void 0 : _a.value; if (equivalentDrugDoseValueInDispensingUnit) { allEquivalentDrugUnitaryDoseFractions.push((prescriptionDoseInDispensingUnit === null || prescriptionDoseInDispensingUnit === void 0 ? void 0 : prescriptionDoseInDispensingUnit.value) + '/' + equivalentDrugDoseValueInDispensingUnit); const equivalentDrugUnitaryDose = (prescriptionDoseInDispensingUnit === null || prescriptionDoseInDispensingUnit === void 0 ? void 0 : prescriptionDoseInDispensingUnit.value) / equivalentDrugDoseValueInDispensingUnit; equivalentDrugWithDoses.push({ equivalentDrug: equivalentDrug, dose: equivalentDrugUnitaryDose / equivalentDrug.getDivisibilityForCombinations(), }); } }); const commonDenominator = this.findCommonDenominator(allEquivalentDrugUnitaryDoseFractions); equivalentDrugWithDoses.forEach((eqDrugWithDose) => { eqDrugWithDose.dose = eqDrugWithDose.dose * commonDenominator; }); this.generateDoseCombinations(prescriptionDoseInDispensingUnit.value * commonDenominator, equivalentDrugWithDoses.filter((eqDrugWithDose) => this.countDecimals(eqDrugWithDose.dose) < this.MAX_DECIMALS), equivalentDrugCombinations); }); const combinationsWithoutDoseEqualToZero = this.removeKeysEqualToZero(equivalentDrugCombinations); this.addMonoUcdCombinationsWhenPossible(equivalentDrugs, combinationsWithoutDoseEqualToZero); return this.filterPossibleDoseEquivalentDrugCombinations(combinationsWithoutDoseEqualToZero); } addMonoUcdCombinationsWhenPossible(equivalentDrugs, combinationsWithoutDoseEqualToZero) { equivalentDrugs.forEach((equivalentDrug) => { var _a, _b; const existingIndex = combinationsWithoutDoseEqualToZero.findIndex((combination) => { if (Object.keys(combination).length === 1) { return combination[equivalentDrug.uri]; } return 0; }); if (existingIndex === -1) { combinationsWithoutDoseEqualToZero.push({ [equivalentDrug.uri]: new EquivalentDrugWithDose(equivalentDrug, (_b = (_a = equivalentDrug.dose.find((dose) => dose.unit.isDispensingUnit)) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : equivalentDrug.dose[0].value), }); } }); } removeKeysEqualToZero(equivalentDrugCombinations) { return equivalentDrugCombinations.map((combination) => { const filteredEquivalentDrugCombinations = Object.entries(combination).filter(([_, dose]) => dose.dose !== 0); return Object.fromEntries(filteredEquivalentDrugCombinations); }); } filterPossibleDoseEquivalentDrugCombinations(equivalentDrugCombinations) { const filteredEquivalentDrugCombinations = []; equivalentDrugCombinations.forEach((equivalentDrugCombination) => { let isDosePossible = true; Object.values(equivalentDrugCombination).forEach((equivalentWithDose) => { if (equivalentWithDose.equivalentDrug.divisibility && !Number.isInteger(equivalentWithDose.dose / (1 / equivalentWithDose.equivalentDrug.divisibility))) { isDosePossible = false; } }); if (isDosePossible) { filteredEquivalentDrugCombinations.push(equivalentDrugCombination); } }); return filteredEquivalentDrugCombinations; } countDecimals(value) { var _a; if (Math.floor(value) === value) { return 0; } return ((_a = value.toString().split('.')[1]) === null || _a === void 0 ? void 0 : _a.length) || 0; } generateDoseCombinations(dosePrescrite, equivalentDrugs, combinations, combination = {}, index = 0) { if (dosePrescrite === 0) { combinations.push(combination); return; } if (index === equivalentDrugs.length) { return; } const currentDrug = equivalentDrugs[index]; const currentDose = currentDrug.dose; const maxDoseCount = Math.floor(dosePrescrite / currentDose); for (let i = maxDoseCount; i >= 0; i--) { const newDosePrescrite = dosePrescrite - i * currentDose; const newCombination = { ...combination, [currentDrug.equivalentDrug.uri]: new EquivalentDrugWithDose(currentDrug.equivalentDrug, i / currentDrug.equivalentDrug.getDivisibilityForCombinations()), }; this.generateDoseCombinations(newDosePrescrite, equivalentDrugs, combinations, newCombination, index + 1); } } buildCombinationsForMultiComposables(prescriptionLine, equivalentDrugs) { var _a; const combinationsForMultiComposable = []; const activePrinciplesAndEquivalents = []; const ucdvDispensingUnit = (_a = prescriptionLine.multiComposableDrugData) === null || _a === void 0 ? void 0 : _a.ucdvDispensingUnit; if (!prescriptionLine.error && prescriptionLine.dose && prescriptionLine.unit && prescriptionLine.multiComposableDrugData && ucdvDispensingUnit) { const prescribedDoseInUcdvDispensingUnit = useConversionService().convertDose(new Dose(prescriptionLine.dose, prescriptionLine.unit), ucdvDispensingUnit.uri, prescriptionLine.unit.conversionRates); if (!prescribedDoseInUcdvDispensingUnit) { return []; } for (const prescriptionLineActivePrinciple of prescriptionLine .multiComposableDrugData.activePrinciples) { const prescribedActivePrincipleDose = prescribedDoseInUcdvDispensingUnit.value * prescriptionLineActivePrinciple.totalQuantityValue; const equivalentDrugsWithCurrentActivePrinciple = equivalentDrugs.filter((equivalentDrug) => { var _a; return (_a = equivalentDrug.multiComposableDrugData) === null || _a === void 0 ? void 0 : _a.activePrinciples.some((equivalentDrugActivePrinciple) => equivalentDrugActivePrinciple.id === prescriptionLineActivePrinciple.id); }); const equivalentDrugsWithCurrentActivePrincipleAndPossibleDosage = []; equivalentDrugsWithCurrentActivePrinciple.forEach((equivalentDrug) => { var _a; const equivalentActivePrinciple = (_a = equivalentDrug.multiComposableDrugData) === null || _a === void 0 ? void 0 : _a.activePrinciples[0]; if (!equivalentActivePrinciple) { return; } const equivalentActivePrincipleDose = prescribedActivePrincipleDose / equivalentActivePrinciple.totalQuantityValue; if (this.isDosagePossible(equivalentActivePrincipleDose, equivalentDrug.divisibility)) { equivalentDrug.dose = [ new Dose(equivalentActivePrincipleDose, equivalentDrug.units.find((unit) => unit.uri === ucdvDispensingUnit.uri)), ]; equivalentDrugsWithCurrentActivePrincipleAndPossibleDosage.push(equivalentDrug); } }); if (equivalentDrugsWithCurrentActivePrinciple.length === 0) { return []; } activePrinciplesAndEquivalents.push(equivalentDrugsWithCurrentActivePrincipleAndPossibleDosage); } } this.generateCombinationsForMultiComposable(combinationsForMultiComposable, activePrinciplesAndEquivalents); return combinationsForMultiComposable; } isDosagePossible(equivalentDrugDose, divisibility) { if (divisibility) { return Number.isInteger(equivalentDrugDose / (1 / divisibility)); } return true; } generateCombinationsForMultiComposable(combinationsForMultiComposable, activePrinciplesAndEquivalents, currentCombination = {}, index = 0) { if (index === activePrinciplesAndEquivalents.length) { combinationsForMultiComposable.push({ ...currentCombination }); return; } const currentActivePrincipleEquivalents = activePrinciplesAndEquivalents[index]; for (const equivalentDrug of currentActivePrincipleEquivalents) { currentCombination[equivalentDrug.uri] = new EquivalentDrugWithDose(equivalentDrug, equivalentDrug.dose[0].value); this.generateCombinationsForMultiComposable(combinationsForMultiComposable, activePrinciplesAndEquivalents, { ...currentCombination }, index + 1); delete currentCombination[equivalentDrug.uri]; } } greatestCommonDivisor(a, b) { if (b === 0) { return a; } return this.greatestCommonDivisor(b, a % b); } leastCommonMultiple(a, b) { return (a * b) / this.greatestCommonDivisor(a, b); } findCommonDenominator(fractions) { const denominators = fractions.map((fraction) => { const [, denominatorStr] = fraction.split('/'); return parseInt(denominatorStr, 10); }); let commonDenominator = denominators[0]; for (let i = 1; i < denominators.length; i++) { commonDenominator = this.leastCommonMultiple(commonDenominator, denominators[i]); } if (commonDenominator === 0) { const fractionsWithDenominatorMultipliedBy10 = []; fractions.forEach((value) => { const [numeratorStr, denominatorStr] = value.split('/'); const denominator = Number(denominatorStr) * 10; fractionsWithDenominatorMultipliedBy10.push(numeratorStr + '/' + denominator); }); return (this.findCommonDenominator(fractionsWithDenominatorMultipliedBy10) / 10); } return isNaN(commonDenominator) ? 1 : commonDenominator; } } const dosesCombinationsServiceInstance = new DosesCombinationsService(); //# sourceMappingURL=doses-combinations-service.js.map