@vidal-community/vidal-web-components
Version:
Vidal Web Components
411 lines • 20.2 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { html, LitElement } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { DrugPresent } from '../enums/drug-present';
import { ErrorLabels } from '../error-labels';
import { formStyle } from './vidal-equivalent-form-styles';
import { useConversionService } from '../services/conversion-service';
import { Dose } from '../model/dose';
import { useDosesCombinationsService } from '../services/doses-combinations-service';
import { DrugWithDose } from '../model/drug-with-dose';
import { OutputDrugWithDose } from '../model/output/output-drug-with-dose';
import { displayCombinations, notAvailable } from './template';
let VidalEquivalentForm = class VidalEquivalentForm extends LitElement {
constructor() {
super(...arguments);
this.equivalentUcds = [];
this.displayMoreCombinations = false;
this.displayEquivalentsWithImpossibleDoses = false;
this.conversionService = useConversionService();
this.dosesCombinationsService = useDosesCombinationsService();
this.MAX_COMBINATIONS_DISPLAYED = 10;
this.selectedEquivalentCombinationForm = [];
this.filteredEquivalentUcd = [];
this.drugCombinationsWithAllDoses = [];
}
firstUpdated() {
var _a;
if (!this.validatePrescriptionLine(this.prescriptionLine)) {
this.handleNoCombinations(this.equivalentUcds);
return;
}
let equivalentDrugCombinations;
if ((_a = this.prescriptionLine.multiComposableDrugData) === null || _a === void 0 ? void 0 : _a.isMultiComposable()) {
equivalentDrugCombinations =
this.dosesCombinationsService.buildCombinationsForMultiComposables(this.prescriptionLine, this.equivalentUcds);
}
else {
this.convertAllPrescriptionDoses(this.prescriptionLine);
equivalentDrugCombinations = this.buildDosesCombinations();
}
if (!equivalentDrugCombinations ||
equivalentDrugCombinations.length === 0) {
this.handleNoCombinationsFound(this.prescriptionLine, this.equivalentUcds);
return;
}
const sortedDrugCombinations = this.sortEquivalentDrugCombinations(equivalentDrugCombinations);
this.drugCombinationsWithAllDoses = this.buildDrugCombinationsWithAllDoses(sortedDrugCombinations);
if (this.drugCombinationsWithAllDoses.length !== 0) {
this.selectDispensingUnitCombination(this.drugCombinationsWithAllDoses[0]);
}
}
validatePrescriptionLine(prescriptionLine) {
if (!prescriptionLine.isDoseValid() || prescriptionLine.error) {
return false;
}
return true;
}
handleNoCombinations(equivalentUcds) {
this.drugCombinationsWithAllDoses =
this.buildUnitaryCombination(equivalentUcds);
this.sortCombinationsWithAllDosesByAscendingDose(this.drugCombinationsWithAllDoses);
if (this.drugCombinationsWithAllDoses.length !== 0) {
this.selectDispensingUnitCombination(this.drugCombinationsWithAllDoses[0]);
}
}
buildDosesCombinations() {
var _a;
if (this.prescriptionLine.error || !this.prescriptionLine.dispensingUnit) {
return [];
}
const prescriptionDoseInDispensingUnit = this.conversionService.convertDose(new Dose(this.prescriptionLine.dose, this.prescriptionLine.unit), this.prescriptionLine.dispensingUnit.uri, (_a = this.prescriptionLine.unit) === null || _a === void 0 ? void 0 : _a.conversionRates);
if (!prescriptionDoseInDispensingUnit) {
return [];
}
return this.dosesCombinationsService.buildDosesCombinations(this.getDispensingUnits(this.equivalentUcds), this.equivalentUcds, prescriptionDoseInDispensingUnit);
}
handleNoCombinationsFound(prescriptionLine, equivalentUcds) {
var _a;
if ((_a = prescriptionLine.multiComposableDrugData) === null || _a === void 0 ? void 0 : _a.isMultiComposable()) {
return;
}
this.handleNoCombinations(this.filterEquivalentsWithImpossibleDosages(equivalentUcds));
}
render() {
return html `
<div class="equivalent-container">
<div class="prescription column" data-test="prescription-${this.prescriptionLine.drug.safeDrugUri()}">
<div class="prescription-drug-name">
${this.prescriptionLine.drug.name}
</div>
<div class="dose">${this.getDoseOrError(this.prescriptionLine)}
</div>
</div>
<div class="formulary column" data-test="substitution-${dataTest(this.prescriptionLine.drug, this.substitutionLevel())}">
${this.displayEquivalent(this.drugCombinationsWithAllDoses, this.prescriptionLine)}
</div>
</div>
</div>`;
}
filterEquivalentsWithImpossibleDosages(equivalentDrugs) {
return equivalentDrugs.filter((equivalentDrug) => {
const dispensingUnit = equivalentDrug.units.find((unit) => unit.isDispensingUnit);
if (dispensingUnit) {
const doseInDispensingUnit = equivalentDrug.dose.find((d) => d.unit.uri === dispensingUnit.uri);
if (equivalentDrug.divisibility &&
equivalentDrug.divisibility >= 1 &&
!Number.isInteger(Number(doseInDispensingUnit === null || doseInDispensingUnit === void 0 ? void 0 : doseInDispensingUnit.value) /
(1 / equivalentDrug.divisibility))) {
return false;
}
}
return true;
});
}
switchDisplay() {
this.displayMoreCombinations = !this.displayMoreCombinations;
if (!this.displayMoreCombinations) {
this.selectDispensingUnitCombination(this.drugCombinationsWithAllDoses[0]);
}
}
displayCheckbox() {
if (this.displayEquivalentsWithImpossibleDoses) {
return true;
}
if (this.prescriptionLine.multiComposableDrugData &&
this.prescriptionLine.multiComposableDrugData.isMultiComposable()) {
return false;
}
if (!this.prescriptionLine.isDoseValid() || this.prescriptionLine.error) {
return false;
}
if (this.drugCombinationsWithAllDoses.length === 0 &&
this.equivalentUcds.length !== this.filteredEquivalentUcd.length) {
return true;
}
return false;
}
switchDisplayEquivalentsWithImpossibleDoses(event) {
const checkbox = event.target;
let equivalentUsed = [];
if (checkbox.checked) {
this.displayEquivalentsWithImpossibleDoses = true;
equivalentUsed = this.equivalentUcds;
}
else {
this.displayEquivalentsWithImpossibleDoses = false;
equivalentUsed = this.filterEquivalentsWithImpossibleDosages(this.equivalentUcds);
}
this.handleNoCombinations(equivalentUsed);
}
buildUnitaryCombination(equivalentDrugs) {
const drugCombinations = [];
equivalentDrugs.forEach((equivalentUcds) => drugCombinations.push({
[equivalentUcds.uri]: {
dose: equivalentUcds.dose,
equivalentDrug: equivalentUcds,
},
}));
return drugCombinations;
}
getDispensingUnits(equivalentDrugs) {
const dispensingUnits = [];
equivalentDrugs.forEach((equivalentDrug) => {
const equivalentDrugDispensingUnit = equivalentDrug.units.find((unit) => unit.isDispensingUnit);
if (equivalentDrugDispensingUnit &&
!this.isUnitAlreadyPresent(equivalentDrugDispensingUnit, dispensingUnits)) {
dispensingUnits.push(equivalentDrugDispensingUnit);
}
});
return dispensingUnits;
}
isUnitAlreadyPresent(unit, units) {
return !!units.find((u) => u.uri === unit.uri);
}
convertAllPrescriptionDoses(prescriptionLine) {
var _a;
(_a = this.equivalentUcds) === null || _a === void 0 ? void 0 : _a.forEach((equivalentDrug) => {
var _a, _b;
const doseToConvert = this.findDoseToConvert(equivalentDrug, prescriptionLine);
if (doseToConvert) {
for (const unit of (_a = equivalentDrug.units) !== null && _a !== void 0 ? _a : []) {
const convertedDose = this.conversionService.convertDose(doseToConvert, unit.uri, unit.conversionRates);
if (convertedDose) {
convertedDose.unit.isDispensingUnit = unit.isDispensingUnit;
(_b = equivalentDrug.dose) === null || _b === void 0 ? void 0 : _b.push(convertedDose);
}
}
}
else {
prescriptionLine.error = true;
}
});
}
findDoseToConvert(equivalentDrug, prescriptionLine) {
var _a;
if (prescriptionLine.drug.isPrescribable()) {
return this.convertPrescriptionDoseInPrescribableRefUnit(prescriptionLine);
}
const matchingUnit = this.conversionService.findMatchingUnitUri(equivalentDrug.units, prescriptionLine.unit);
return matchingUnit
? this.conversionService.convertDose(new Dose(prescriptionLine.dose, prescriptionLine.unit), matchingUnit, (_a = prescriptionLine.unit) === null || _a === void 0 ? void 0 : _a.conversionRates)
: undefined;
}
convertPrescriptionDoseInPrescribableRefUnit(prescriptionLine) {
return this.conversionService.convertDose(new Dose(prescriptionLine.dose, prescriptionLine.unit), prescriptionLine.drug.prescribable.refUnit.uri, prescriptionLine.unit.conversionRates);
}
sortEquivalentDrugCombinations(equivalentDrugCombinations) {
equivalentDrugCombinations.sort((combinationA, combinationB) => this.ascendingNumberOfTakeComparator(combinationA, combinationB) ||
this.ascendingNumberOfEquivalentsComparator(combinationA, combinationB) ||
this.descendingNumberOfDivisionsComparator(combinationA, combinationB));
return equivalentDrugCombinations.slice(0, this.MAX_COMBINATIONS_DISPLAYED);
}
descendingNumberOfDivisionsComparator(combinationA, combinationB) {
const countA = this.countNumberOfDecimalDoses(combinationA);
const countB = this.countNumberOfDecimalDoses(combinationB);
if (countA < countB) {
return -1;
}
if (countA > countB) {
return 1;
}
return 0;
}
countNumberOfDecimalDoses(combination) {
return Object.values(combination).filter((value) => !Number.isInteger(value.dose)).length;
}
ascendingNumberOfEquivalentsComparator(combinationA, combinationB) {
return Object.keys(combinationA).length - Object.keys(combinationB).length;
}
ascendingNumberOfTakeComparator(combinationA, combinationB) {
return (Object.values(combinationA).reduce((sum, equivalentDrugWithDose) => sum + Math.ceil(equivalentDrugWithDose.dose), 0) -
Object.values(combinationB).reduce((sum, equivalentDrugWithDose) => sum + Math.ceil(equivalentDrugWithDose.dose), 0));
}
ascendingDose(combinationA, combinationB) {
const dosesA = combinationA[Object.keys(combinationA)[0]].dose;
const dosesB = combinationB[Object.keys(combinationB)[0]].dose;
const hasDispensingDoseA = dosesA.some((dose) => dose.unit.isDispensingUnit);
const hasDispensingDoseB = dosesB.some((dose) => dose.unit.isDispensingUnit);
if (!hasDispensingDoseA && !hasDispensingDoseB) {
return 0;
}
const totalDoseA = dosesA.reduce((total, dose) => total + dose.value, 0);
const totalDoseB = dosesB.reduce((total, dose) => total + dose.value, 0);
return totalDoseA - totalDoseB;
}
buildDrugCombinationsWithAllDoses(drugCombinations) {
return drugCombinations.map((drugCombination) => {
let result = {};
const drugCombinationEntries = Object.entries(drugCombination);
drugCombinationEntries.forEach((drugCombinationEntry) => {
const equivalentDrugUri = drugCombinationEntry[0];
const equivalentDrug = drugCombinationEntry[1].equivalentDrug;
const doses = [];
const equivalentDrugDispensingUnit = equivalentDrug === null || equivalentDrug === void 0 ? void 0 : equivalentDrug.units.find((equivalentDrugUri) => equivalentDrugUri.isDispensingUnit);
const initialDose = new Dose(drugCombinationEntry[1].dose, equivalentDrugDispensingUnit);
equivalentDrug === null || equivalentDrug === void 0 ? void 0 : equivalentDrug.units.forEach((unit) => {
const convertedDose = this.conversionService.convertDose(initialDose, unit.uri, unit.conversionRates);
if (convertedDose) {
doses.push(convertedDose);
}
});
result = {
...result,
[equivalentDrugUri]: { dose: doses, equivalentDrug: equivalentDrug },
};
});
return result;
});
}
selectDispensingUnitCombination(combination) {
Object.values(combination).forEach((el) => {
const doseInDispensingUnit = el.dose.find((dose) => dose.unit.isDispensingUnit);
const uri = el.equivalentDrug.uri;
if (!this.selectedEquivalentCombinationForm.some((outputDrugWithDose) => outputDrugWithDose.drugUri === uri)) {
if (!doseInDispensingUnit && el.dose[0] && el.dose[0].unit) {
this.selectedEquivalentCombinationForm.push(new DrugWithDose(uri, el.dose[0].unit.uri, el.dose[0].value));
return;
}
this.selectedEquivalentCombinationForm.push(new DrugWithDose(uri, doseInDispensingUnit === null || doseInDispensingUnit === void 0 ? void 0 : doseInDispensingUnit.unit.uri, doseInDispensingUnit === null || doseInDispensingUnit === void 0 ? void 0 : doseInDispensingUnit.value));
}
});
}
displayEquivalent(drugCombinationsWithAllDoses, prescriptionLine) {
if (this.displayCheckbox() && drugCombinationsWithAllDoses.length === 0) {
return notAvailable(DrugPresent.PRESENT_BUT_INCOMPATIBLE_DUE_TO_DIVISIBILITY, this);
}
if (drugCombinationsWithAllDoses.length === 0) {
return notAvailable(DrugPresent.ABSENT, this);
}
return displayCombinations(prescriptionLine, drugCombinationsWithAllDoses, this);
}
getDoseOrError(prescriptionLine) {
var _a;
if (prescriptionLine.error) {
return ErrorLabels.UNKNOWN_UNIT;
}
if (prescriptionLine.dose && ((_a = prescriptionLine.unit) === null || _a === void 0 ? void 0 : _a.name)) {
return prescriptionLine.dose + ' ' + prescriptionLine.unit.name;
}
return '';
}
substitutionLevel() {
if (this.drugCombinationsWithAllDoses.length > 0) {
return this.prescriptionLine.drug.isPrescribable()
? DrugPresent.PRESENT_LEVEL_2_PHARMACEUTICEUTICAL_EQUIVALENT
: DrugPresent.PRESENT_LEVEL_1_DIRECT_EQUIVALENCE;
}
else {
return DrugPresent.ABSENT;
}
}
buildSelectedEquivalentCombinationForm(event, index, prescriptionLine) {
var _a, _b;
let error = false;
const ucds = [];
const combinaison = [];
const inputElement = event.target;
const inputParentElement = inputElement.parentElement;
if ((_b = (_a = inputParentElement.parentElement) === null || _a === void 0 ? void 0 : _a.parentElement) === null || _b === void 0 ? void 0 : _b.parentElement) {
const tableElement = inputParentElement.parentElement.parentElement.parentElement;
const rows = tableElement.querySelectorAll('tr');
rows.forEach((row) => {
var _a;
const firstColumn = row.querySelector('.equivalent-drug-name');
if (firstColumn) {
ucds.push((_a = firstColumn.getAttribute('data-value')) !== null && _a !== void 0 ? _a : '');
}
});
rows.forEach((row) => {
var _a;
const columns = row.querySelectorAll('td');
if (columns.length >= index && !error) {
const column = columns[index];
combinaison.push((_a = column.getAttribute('data-value')) !== null && _a !== void 0 ? _a : '');
}
});
}
else {
error = true;
}
this.populateSelectedEquivalentCombinationForm(error, combinaison, ucds, prescriptionLine);
}
populateSelectedEquivalentCombinationForm(error, combinations, ucds, prescriptionLine) {
if (!error || combinations.length === 0 || ucds.length === 0) {
this.selectedEquivalentCombinationForm = [];
for (let i = 0; i < ucds.length; i++) {
const split = combinations[i].split(' ');
const combinationUri = split[1];
const combinaisonDose = split[0];
const currentEquivalentDrug = new DrugWithDose(ucds[i], combinationUri, isNaN(+combinaisonDose) ? undefined : +combinaisonDose);
this.selectedEquivalentCombinationForm.push(currentEquivalentDrug);
}
}
else {
console.error('There was an error when attempting to select this dose: ' +
prescriptionLine.dose +
' for the following drug: ' +
prescriptionLine.drug.uri);
}
}
buildSelectedEquivalentForm(equivalentDrug) {
this.selectedEquivalentCombinationForm = [
new OutputDrugWithDose(equivalentDrug.uri),
];
}
sortCombinationsWithAllDosesByAscendingDose(drugCombinationsWithAllDoses) {
drugCombinationsWithAllDoses.sort((combinationA, combinationB) => this.ascendingDose(combinationA, combinationB));
return drugCombinationsWithAllDoses.slice(0, this.MAX_COMBINATIONS_DISPLAYED);
}
};
VidalEquivalentForm.styles = formStyle;
__decorate([
property({ attribute: false })
], VidalEquivalentForm.prototype, "prescriptionLine", void 0);
__decorate([
property({ attribute: false })
], VidalEquivalentForm.prototype, "equivalentUcds", void 0);
__decorate([
state()
], VidalEquivalentForm.prototype, "displayMoreCombinations", void 0);
__decorate([
state()
], VidalEquivalentForm.prototype, "displayEquivalentsWithImpossibleDoses", void 0);
__decorate([
state()
], VidalEquivalentForm.prototype, "drugCombinationsWithAllDoses", void 0);
VidalEquivalentForm = __decorate([
customElement('vidal-equivalent-form')
], VidalEquivalentForm);
export { VidalEquivalentForm };
const dataTest = (drug, drugPresent) => {
let number;
switch (drugPresent) {
case DrugPresent.PRESENT_LEVEL_1_DIRECT_EQUIVALENCE:
number = 1;
break;
case DrugPresent.PRESENT_LEVEL_2_PHARMACEUTICEUTICAL_EQUIVALENT:
number = 2;
break;
case DrugPresent.ABSENT:
number = 0;
break;
}
return `${drug.safeDrugUri()}-level-${number}`;
};
//# sourceMappingURL=vidal-equivalent-form.js.map