Skip to content

new capacity model proposal #548

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions shared/src/data/default-state/material-templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const standardMaterialTemplate = MaterialTemplate.create(
height: 40,
aspectRatio: 1,
},
CanCaterFor.create(2, 0, 0, 'and'),
CanCaterFor.create(2),
defaultOverrideTreatmentRange,
defaultTreatmentRange
);
Expand All @@ -26,7 +26,7 @@ const bigMaterialTemplate = MaterialTemplate.create(
height: 56,
aspectRatio: 1,
},
CanCaterFor.create(2, 2, 0, 'and'),
CanCaterFor.create(4),
defaultOverrideTreatmentRange,
10
);
Expand Down
10 changes: 5 additions & 5 deletions shared/src/data/default-state/personnel-templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const sanPersonnelTemplate = PersonnelTemplate.create(
height: 80,
aspectRatio: 1,
},
CanCaterFor.create(0, 0, 5, 'and'),
CanCaterFor.create(0.3),
defaultOverrideTreatmentRange,
defaultTreatmentRange
);
Expand All @@ -25,7 +25,7 @@ const rettSanPersonnelTemplate = PersonnelTemplate.create(
height: 80,
aspectRatio: 1,
},
CanCaterFor.create(1, 2, 0, 'and'),
CanCaterFor.create(0.8),
defaultOverrideTreatmentRange,
defaultTreatmentRange
);
Expand All @@ -37,7 +37,7 @@ const notSanPersonnelTemplate = PersonnelTemplate.create(
height: 80,
aspectRatio: 1,
},
CanCaterFor.create(2, 1, 0, 'and'),
CanCaterFor.create(1),
defaultOverrideTreatmentRange,
defaultTreatmentRange
);
Expand All @@ -49,7 +49,7 @@ const notarztPersonnelTemplate = PersonnelTemplate.create(
height: 80,
aspectRatio: 1,
},
CanCaterFor.create(2, 2, 2, 'and'),
CanCaterFor.create(1.2),
defaultOverrideTreatmentRange,
15
);
Expand All @@ -61,7 +61,7 @@ const gfPersonnelTemplate = PersonnelTemplate.create(
height: 80,
aspectRatio: 1,
},
CanCaterFor.create(0, 0, 0, 'and'),
CanCaterFor.create(0),
0,
0
);
Expand Down
43 changes: 5 additions & 38 deletions shared/src/models/utils/cater-for.ts
Original file line number Diff line number Diff line change
@@ -1,52 +1,19 @@
import { IsNumber, IsString, Min } from 'class-validator';
import { IsNumber, Min } from 'class-validator';
import { getCreate } from './get-create';

export class CanCaterFor {
/**
* if {@link logicalOperator} `=== 'and'` it is cumulative,
* how many red patients can the catering treat
* also affects the number of possible {@link yellow} and {@link green} patients
* that can be treated.
*
*/
@IsNumber()
@Min(0)
public readonly red: number;

/**
* if {@link logicalOperator} `=== 'and'` it is cumulative,
* how many extra {@link yellow} and {@link green} patients can the catering treat
* to the number already written in the {@link red} value
*/
@IsNumber()
@Min(0)
public readonly yellow: number;

/**
* if {@link logicalOperator} `=== 'and'` it is cumulative,
* how many {@link green} patients can the catering treat
* to the number already written in the {@link yellow} and {@link red} value
*/
@IsNumber()
@Min(0)
public readonly green: number;

// TODO: Use a better validator
@IsString()
public readonly logicalOperator: 'and' | 'or';
public readonly capacity: number;

/**
* @deprecated Use {@link create} instead
*/
constructor(
red: number,
yellow: number,
green: number,
logicalOperator: 'and' | 'or'
) {
this.red = red;
this.yellow = yellow;
this.green = green;
this.logicalOperator = logicalOperator;
constructor(capacity: number) {
this.capacity = capacity;
}

static readonly create = getCreate(this);
Expand Down
42 changes: 16 additions & 26 deletions shared/src/store/action-reducers/utils/calculate-treatments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ interface CatersFor {
green: number;
}

const catersCost = {
red: 1,
yellow: 0.6,
green: 0.3,
};

/**
* @returns whether a material or personnel could treat a patient with {@link status} if it already {@link catersFor} patients
*/
Expand All @@ -31,33 +37,19 @@ function couldCaterFor(
if (status === 'black' || status === 'blue') {
return false;
}
if (cateringElement.canCaterFor.logicalOperator === 'or') {
const numberOfTreatedCategories = Object.entries(catersFor).filter(
([category, catersForInCategory]) =>
// Will be treated
status === category ||
// Is already treated
catersForInCategory > 0
).length;
return (
// Only one category can be treated
numberOfTreatedCategories <= 1 &&
// + 1 for the patient that will be treated
catersFor[status] + 1 <= cateringElement.canCaterFor[status]
);
}

let availableCapacity = 0;
let cateredCapacity = 0;
for (const category of ['red', 'yellow', 'green'] as const) {
// The catering capacity is calculated cumulatively - a red slot can also treat a yellow or green one instead
availableCapacity +=
cateringElement.canCaterFor[category] -
catersFor[category] -
(status === category ? 1 : 0);
if (availableCapacity < 0) {
return false;
}
cateredCapacity += catersFor[category] * catersCost[category];
}
if (
cateredCapacity + catersCost[status] >
cateringElement.canCaterFor.capacity
) {
return false;
}

return true;
}

Expand Down Expand Up @@ -240,9 +232,7 @@ function updateCatering(
// Doing this behind removeTreatmentsOfElement to catch the case someone changed via export import
// the canCaterFor to 0 while an Element is treating something in the exported state
if (
(cateringElement.canCaterFor.red === 0 &&
cateringElement.canCaterFor.yellow === 0 &&
cateringElement.canCaterFor.green === 0) ||
cateringElement.canCaterFor.capacity === 0 ||
// The element is no longer in a position to treat a patient
cateringElement.position === undefined
) {
Expand Down