Skip to content
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

Feature/964 report behavior can send radiograms on last patient of a category #982

Merged
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
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;

Nils1729 marked this conversation as resolved.
Show resolved Hide resolved
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