@vidal-community/vidal-web-components
Version:
Vidal Web Components
208 lines • 11.6 kB
JavaScript
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