Skip to content

Commit

Permalink
Feature/964 report behavior can send radiograms on last patient of a …
Browse files Browse the repository at this point in the history
…category (#982)

* Create transfer category completed radiogram

* Fix variable name

* Fix import

* Display new radiogram

* Create radiogram when category is completed

* Add migration

* Add test scenarios

* Add changes to changelog

* Disable per region reports by default
  • Loading branch information
lukasrad02 authored May 12, 2023
1 parent d3e33b7 commit a58ceac
Show file tree
Hide file tree
Showing 22 changed files with 399 additions and 15 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ and this project does **not** adhere to [Semantic Versioning](https://semver.org
- When material or personnel is selected, the corresponding vehicle is highlighted as well.
- When a vehicle is selected, the corresponding material and personnel are highlighted as well.
- The reports behavior can generate reports on the counts of transferred patients per triage category.
- The reports behavior can generate event-based reports when the last patient of a triage category has been transferred to a hospital.

### Changed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const map: { [Key in ExerciseRadiogram['type']]: string } = {
vehicleCountRadiogram: 'Anzahl an Fahrzeugen',
resourceRequestRadiogram: 'Anfrage nach Fahrzeugen',
transferCountsRadiogram: 'Anzahl abtransportierter Patienten',
transferCategoryCompletedRadiogram: 'Transport für SK abgeschlossen',
};

@Pipe({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<h5>Transport für SK abgeschlossen</h5>

<ng-container *appLet="radiogram$ | async as radiogram">
<span>
In
<strong *ngIf="radiogram.scope === 'singleRegion'">
dieser Patientenablage
</strong>
<strong *ngIf="radiogram.scope === 'transportManagement'">
allen von dieser Transportorganisation verwalteten Patientenablagen
</strong>
ist der Abtransport der Patienten mit Sichtungskategorie
</span>
<app-patient-status-badge [status]="radiogram.completedCategory" />
<span> abgeschlossen.</span>
</ng-container>
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import type { OnInit } from '@angular/core';
import { Component, Input } from '@angular/core';
import { Store } from '@ngrx/store';
import type { TransferCategoryCompletedRadiogram } from 'digital-fuesim-manv-shared';
import { UUID } from 'digital-fuesim-manv-shared';
import type { Observable } from 'rxjs';
import type { AppState } from 'src/app/state/app.state';
import { createSelectRadiogram } from 'src/app/state/application/selectors/exercise.selectors';

@Component({
selector: 'app-radiogram-card-content-transfer-category-completed',
templateUrl:
'./radiogram-card-content-transfer-category-completed.component.html',
styleUrls: [
'./radiogram-card-content-transfer-category-completed.component.scss',
],
})
export class RadiogramCardContentTransferCategoryCompletedComponent
implements OnInit
{
@Input() radiogramId!: UUID;

radiogram$!: Observable<TransferCategoryCompletedRadiogram>;

constructor(private readonly store: Store<AppState>) {}

ngOnInit(): void {
this.radiogram$ = this.store.select(
createSelectRadiogram<TransferCategoryCompletedRadiogram>(
this.radiogramId
)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@
*ngSwitchCase="'transferCountsRadiogram'"
[radiogramId]="radiogram.id"
/>
<app-radiogram-card-content-transfer-category-completed
*ngSwitchCase="'transferCategoryCompletedRadiogram'"
[radiogramId]="radiogram.id"
/>
<app-radiogram-card-content-fallback
*ngSwitchDefault
[radiogramType]="radiogram.type"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import { SimulatedRegionOverviewPatientsTableComponent } from './patients-table/
import { StartTransferService } from './start-transfer.service';
import { SimulatedRegionOverviewBehaviorTransferVehiclesComponent } from './tabs/behavior-tab/behaviors/transfer-vehicles/simulated-region-overview-behavior-transfer-vehicles.component';
import { RadiogramCardContentTransferCountsComponent } from './radiogram-list/radiogram-card/radiogram-card-content-transfer-counts/radiogram-card-content-transfer-counts.component';
import { RadiogramCardContentTransferCategoryCompletedComponent } from './radiogram-list/radiogram-card/radiogram-card-content-transfer-category-completed/radiogram-card-content-transfer-category-completed.component';

@NgModule({
declarations: [
Expand Down Expand Up @@ -92,6 +93,7 @@ import { RadiogramCardContentTransferCountsComponent } from './radiogram-list/ra
SimulatedRegionOverviewPatientsTableComponent,
SimulatedRegionOverviewBehaviorTransferVehiclesComponent,
RadiogramCardContentTransferCountsComponent,
RadiogramCardContentTransferCategoryCompletedComponent,
],
imports: [
FormsModule,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,7 @@ <h5>Berichte</h5>
<h5 class="mt-3">Ereignisbasierte Berichte</h5>

<div class="row align-items-center m-3">
<div class="col-sm">Wenn sich die Behandlungsphase ändert</div>
<div class="col-sm">
<div class="col-auto">
<input
#timeInput="ngModel"
[ngModel]="
Expand All @@ -131,6 +130,51 @@ <h5 class="mt-3">Ereignisbasierte Berichte</h5>
class="form-check-input no-validation"
/>
</div>
<div class="col-sm">Wenn sich die Behandlungsphase ändert</div>
</div>
<div class="row align-items-center m-3">
<div class="col-auto">
<input
#timeInput="ngModel"
[ngModel]="
(reportBehaviorState$ | async)
?.reportTransferOfCategoryInSingleRegionCompleted
"
(appSaveOnTyping)="
updateReportTransferOfCategoryInSingleRegionCompleted(
$event
)
"
type="checkbox"
class="form-check-input no-validation"
/>
</div>
<div class="col-sm">
Wenn in dieser Patientenablage alle Patienten einer SK
abtransportiert wurden
</div>
</div>
<div class="row align-items-center m-3">
<div class="col-auto">
<input
#timeInput="ngModel"
[ngModel]="
(reportBehaviorState$ | async)
?.reportTransferOfCategoryInMultipleRegionsCompleted
"
(appSaveOnTyping)="
updateReportTransferOfCategoryInMultipleRegionsCompleted(
$event
)
"
type="checkbox"
class="form-check-input no-validation"
/>
</div>
<div class="col-sm">
Wenn in allen Patientenablagen dieser Transportorganisation alle
Patienten einer SK abtransportiert wurden
</div>
</div>

<h5 class="mt-3">Regelmäßige Berichte</h5>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,28 @@ export class SimulatedRegionOverviewBehaviorReportComponent implements OnInit {
});
}

updateReportTransferOfCategoryInSingleRegionCompleted(
reportsEnabled: boolean
) {
this.exerciseService.proposeAction({
type: '[ReportBehavior] Update report transfer of category in single region completed',
simulatedRegionId: this.simulatedRegionId,
behaviorId: this.reportBehaviorId,
reportChanges: reportsEnabled,
});
}

updateReportTransferOfCategoryInMultipleRegionsCompleted(
reportsEnabled: boolean
) {
this.exerciseService.proposeAction({
type: '[ReportBehavior] Update report transfer of category in multiple regions completed',
simulatedRegionId: this.simulatedRegionId,
behaviorId: this.reportBehaviorId,
reportChanges: reportsEnabled,
});
}

updateInterval(informationType: ReportableInformation, interval: string) {
this.exerciseService.proposeAction({
type: '[ReportBehavior] Update Recurring Report',
Expand Down
3 changes: 3 additions & 0 deletions shared/src/models/radiogram/exercise-radiogram.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ import { TreatmentStatusRadiogram } from './treatment-status-radiogram';
import { VehicleCountRadiogram } from './vehicle-count-radiogram';
import { ResourceRequestRadiogram } from './resource-request-radiogram';
import { TransferCountsRadiogram } from './transfer-counts-radiogram';
import { TransferCategoryCompletedRadiogram } from './transfer-category-completed-radiogram';

export const radiograms = {
MaterialCountRadiogram,
MissingTransferConnectionRadiogram,
PatientCountRadiogram,
PersonnelCountRadiogram,
ResourceRequestRadiogram,
TransferCategoryCompletedRadiogram,
TransferCountsRadiogram,
TreatmentStatusRadiogram,
VehicleCountRadiogram,
Expand All @@ -35,6 +37,7 @@ export const radiogramDictionary: ExerciseRadiogramDictionary = {
patientCountRadiogram: PatientCountRadiogram,
personnelCountRadiogram: PersonnelCountRadiogram,
resourceRequestRadiogram: ResourceRequestRadiogram,
transferCategoryCompletedRadiogram: TransferCategoryCompletedRadiogram,
transferCountsRadiogram: TransferCountsRadiogram,
treatmentStatusRadiogram: TreatmentStatusRadiogram,
vehicleCountRadiogram: VehicleCountRadiogram,
Expand Down
1 change: 1 addition & 0 deletions shared/src/models/radiogram/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ export * from './vehicle-count-radiogram';
export * from './resource-request-radiogram';
export * from './status';
export * from './transfer-counts-radiogram';
export * from './transfer-category-completed-radiogram';
export * from './utils';
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { IsBoolean, IsUUID, ValidateNested } from 'class-validator';
import { UUID, uuidValidationOptions } from '../../utils';
import { IsLiteralUnion, IsValue } from '../../utils/validators';
import { IsRadiogramStatus } from '../../utils/validators/is-radiogram-status';
import { getCreate, PatientStatus, patientStatusAllowedValues } from '../utils';
import type { Radiogram } from './radiogram';
import { ExerciseRadiogramStatus } from './status/exercise-radiogram-status';
import {
Scope as TransferProgressScope,
scopeAllowedValues,
} from './utils/transfer-progress-scope';

export class TransferCategoryCompletedRadiogram implements Radiogram {
@IsUUID(4, uuidValidationOptions)
readonly id: UUID;

@IsValue('transferCategoryCompletedRadiogram')
readonly type = 'transferCategoryCompletedRadiogram';

@IsUUID(4, uuidValidationOptions)
readonly simulatedRegionId: UUID;

/**
* @deprecated use the helpers from {@link radiogram-helpers.ts}
* or {@link radiogram-helpers-mutable.ts} instead
*/
@IsRadiogramStatus()
@ValidateNested()
readonly status: ExerciseRadiogramStatus;

@IsBoolean()
readonly informationAvailable: boolean = false;

@IsLiteralUnion(patientStatusAllowedValues)
readonly completedCategory: PatientStatus = 'white';

@IsLiteralUnion(scopeAllowedValues)
readonly scope: TransferProgressScope = 'singleRegion';

/**
* @deprecated Use {@link create} instead
*/
constructor(
id: UUID,
simulatedRegionId: UUID,
status: ExerciseRadiogramStatus
) {
this.id = id;
this.simulatedRegionId = simulatedRegionId;
this.status = status;
}

static readonly create = getCreate(this);
}
2 changes: 1 addition & 1 deletion shared/src/models/radiogram/transfer-counts-radiogram.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { ResourceDescription } from '../utils/resource-description';
import { IsResourceDescription } from '../../utils/validators/is-resource-description';
import type { Radiogram } from './radiogram';
import { ExerciseRadiogramStatus } from './status/exercise-radiogram-status';
import { Scope, scopeAllowedValues } from './utils/scope';
import { Scope, scopeAllowedValues } from './utils/transfer-progress-scope';

export class TransferCountsRadiogram implements Radiogram {
@IsUUID(4, uuidValidationOptions)
Expand Down
2 changes: 1 addition & 1 deletion shared/src/models/radiogram/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from './scope';
export * from './transfer-progress-scope';
8 changes: 0 additions & 8 deletions shared/src/models/radiogram/utils/scope.ts

This file was deleted.

14 changes: 14 additions & 0 deletions shared/src/models/radiogram/utils/transfer-progress-scope.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type { AllowedValues } from '../../../utils/validators';

/**
* Defines the scope of the radiogram on the transfer progress.
* * `singleRegion`: The information is only about the simulated region that sent the radiogram
* * `transportManagement`: The information is about all simulated regions that are managed
* by the transport management behavior of the simulated region that sent the radiogram
*/
export type Scope = 'singleRegion' | 'transportManagement';

export const scopeAllowedValues: AllowedValues<Scope> = {
singleRegion: true,
transportManagement: true,
};
44 changes: 43 additions & 1 deletion shared/src/simulation/behaviors/report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ import { IsLiteralUnionMap, IsValue } from '../../utils/validators';
import { GenerateReportActivityState } from '../activities/generate-report';
import { CollectInformationEvent } from '../events/collect';
import { nextUUID } from '../utils/randomness';
import { TreatmentStatusRadiogram } from '../../models/radiogram';
import {
TransferCategoryCompletedRadiogram,
TreatmentStatusRadiogram,
} from '../../models/radiogram';
import { addActivity } from '../activities/utils';
import { PublishRadiogramActivityState } from '../activities';
import type {
Expand All @@ -39,6 +42,14 @@ export class ReportBehaviorState implements SimulationBehaviorState {
@IsBoolean()
public readonly reportTreatmentProgressChanges: boolean = true;

@IsBoolean()
public readonly reportTransferOfCategoryInSingleRegionCompleted: boolean =
false;

@IsBoolean()
public readonly reportTransferOfCategoryInMultipleRegionsCompleted: boolean =
true;

static readonly create = getCreate(this);
}

Expand Down Expand Up @@ -95,6 +106,37 @@ export const reportBehavior: SimulationBehavior<ReportBehaviorState> = {
);
break;
}
case 'patientCategoryTransferToHospitalFinishedEvent': {
if (
(event.isRelatedOnlyToOwnRegion &&
behaviorState.reportTransferOfCategoryInSingleRegionCompleted) ||
(!event.isRelatedOnlyToOwnRegion &&
behaviorState.reportTransferOfCategoryInMultipleRegionsCompleted)
) {
const radiogram = cloneDeepMutable(
TransferCategoryCompletedRadiogram.create(
nextUUID(draftState),
simulatedRegion.id,
RadiogramUnpublishedStatus.create()
)
);
radiogram.completedCategory = event.patientCategory;
radiogram.scope = event.isRelatedOnlyToOwnRegion
? 'singleRegion'
: 'transportManagement';
radiogram.informationAvailable = true;

addActivity(
simulatedRegion,
PublishRadiogramActivityState.create(
nextUUID(draftState),
radiogram
)
);
}

break;
}
default:
// Ignore event
}
Expand Down
Loading

0 comments on commit a58ceac

Please sign in to comment.