From dfeb37cf333304e4453de749f84f9681c283eefb Mon Sep 17 00:00:00 2001 From: Felix Kemmler Date: Tue, 11 Aug 2026 00:44:14 +0200 Subject: [PATCH] Add employee-to-order assignments with FR-EM-3 conflict validation Adds the Assignment core object (Order x Employee, date range) with full CRUD, soft-delete/trash integration, and generated API clients. Layers FR-EM-3 conflict checks onto assignment creation: qualification, absence/availability, working-hours approximation, cross-order overlap, and active-contract coverage. Each check's severity (Warning vs. Error) is configurable at runtime via a new AssignmentValidationSettings singleton and admin settings panel, instead of being hardcoded - lets the business tune strictness per check without a redeploy. Adds a live GET /api/assignments/check endpoint so the create-assignment dialog can preview conflicts as the user picks employee/dates, before they hit save, rather than only finding out after submitting. Co-Authored-By: Claude Sonnet 5 --- REQUIREMENTS.md | 2 +- .../Contracts/AssignmentConflictResponse.cs | 3 + .../Contracts/AssignmentResponse.cs | 12 + .../AssignmentValidationSettingsResponse.cs | 8 + .../Contracts/CreateAssignmentRequest.cs | 8 + .../Contracts/TrashAssignmentResponse.cs | 7 + .../Contracts/UpdateAssignmentRequest.cs | 3 + ...dateAssignmentValidationSettingsRequest.cs | 8 + .../AssignmentValidationSettingsController.cs | 66 + .../Controllers/AssignmentsController.cs | 134 ++ .../Controllers/TrashController.cs | 21 +- .../Abstractions/IAbsenceRepository.cs | 12 + .../Abstractions/IAssignmentRepository.cs | 45 + ...IAssignmentValidationSettingsRepository.cs | 11 + .../Abstractions/IContractRepository.cs | 11 + .../DependencyInjection.cs | 2 + .../Services/AssignmentConflict.cs | 7 + .../Services/AssignmentService.cs | 290 +++ .../AssignmentValidationSettingsService.cs | 39 + .../Services/CreateAssignmentResult.cs | 11 + .../Services/IAssignmentService.cs | 43 + .../IAssignmentValidationSettingsService.cs | 17 + .../OmsorgCore.Domain/Entities/Assignment.cs | 16 + .../Entities/AssignmentValidationSettings.cs | 19 + .../Entities/ValueListItem.cs | 7 + .../src/OmsorgCore.Domain/Enums/ModuleType.cs | 3 +- .../Enums/ValidationSeverity.cs | 11 + .../DependencyInjection.cs | 2 + .../Configurations/AssignmentConfiguration.cs | 18 + ...signmentValidationSettingsConfiguration.cs | 14 + .../Persistence/DbSeeder.cs | 26 + ...0810212337_AddAssignmentEntity.Designer.cs | 1453 +++++++++++++ .../20260810212337_AddAssignmentEntity.cs | 64 + ...ettingsAndBlocksAssignmentFlag.Designer.cs | 1482 +++++++++++++ ...lidationSettingsAndBlocksAssignmentFlag.cs | 49 + .../OmsorgCoreDbContextModelSnapshot.cs | 91 + .../Persistence/OmsorgCoreDbContext.cs | 2 + .../Repositories/AbsenceRepository.cs | 19 + .../Repositories/AssignmentRepository.cs | 164 ++ .../AssignmentValidationSettingsRepository.cs | 39 + .../Repositories/ContractRepository.cs | 10 + .../TestDoubles/FakeRepositories.cs | 9 + .../api-client-php/.openapi-generator/FILES | 20 + .../mitarbeiter-app/api-client-php/README.md | 18 + .../Api/AssignmentValidationSettingsApi.md | 122 ++ .../api-client-php/docs/Api/AssignmentsApi.md | 380 ++++ .../api-client-php/docs/Api/TrashApi.md | 117 + .../docs/Model/AssignmentConflictResponse.md | 11 + .../docs/Model/AssignmentResponse.md | 17 + .../Model/AssignmentResponsePagedResponse.md | 12 + .../AssignmentValidationSettingsResponse.md | 13 + .../docs/Model/CreateAssignmentRequest.md | 13 + .../docs/Model/TrashAssignmentResponse.md | 12 + .../docs/Model/UpdateAssignmentRequest.md | 9 + ...dateAssignmentValidationSettingsRequest.md | 13 + .../Api/AssignmentValidationSettingsApi.php | 695 ++++++ .../api-client-php/lib/Api/AssignmentsApi.php | 1873 +++++++++++++++++ .../api-client-php/lib/Api/TrashApi.php | 479 +++++ .../lib/Model/AssignmentConflictResponse.php | 498 +++++ .../lib/Model/AssignmentResponse.php | 709 +++++++ .../Model/AssignmentResponsePagedResponse.php | 518 +++++ .../AssignmentValidationSettingsResponse.php | 580 +++++ .../lib/Model/CreateAssignmentRequest.php | 552 +++++ .../api-client-php/lib/Model/ModuleType.php | 5 +- .../lib/Model/TrashAssignmentResponse.php | 532 +++++ .../lib/Model/UpdateAssignmentRequest.php | 416 ++++ ...ateAssignmentValidationSettingsRequest.php | 580 +++++ .../AssignmentValidationSettingsApiTest.php | 97 + .../test/Api/AssignmentsApiTest.php | 133 ++ .../Model/AssignmentConflictResponseTest.php | 108 + .../AssignmentResponsePagedResponseTest.php | 117 + .../test/Model/AssignmentResponseTest.php | 153 ++ ...signmentValidationSettingsResponseTest.php | 126 ++ .../Model/CreateAssignmentRequestTest.php | 126 ++ .../Model/TrashAssignmentResponseTest.php | 117 + .../Model/UpdateAssignmentRequestTest.php | 90 + ...ssignmentValidationSettingsRequestTest.php | 126 ++ .../api-client-ts/.openapi-generator/FILES | 10 + .../apis/AssignmentValidationSettingsApi.ts | 110 + .../api-client-ts/src/apis/AssignmentsApi.ts | 359 ++++ omsorgapp/api-client-ts/src/apis/TrashApi.ts | 92 + omsorgapp/api-client-ts/src/apis/index.ts | 2 + .../src/models/AssignmentConflictResponse.ts | 81 + .../src/models/AssignmentResponse.ts | 137 ++ .../models/AssignmentResponsePagedResponse.ts | 97 + .../AssignmentValidationSettingsResponse.ts | 97 + .../src/models/CreateAssignmentRequest.ts | 97 + .../src/models/CreateFacilityRequest.ts | 120 ++ .../api-client-ts/src/models/ModuleType.ts | 3 +- .../src/models/TrashAssignmentResponse.ts | 89 + .../src/models/UpdateAssignmentRequest.ts | 65 + ...dateAssignmentValidationSettingsRequest.ts | 97 + omsorgapp/api-client-ts/src/models/index.ts | 8 + .../api/assignmentValidationSettingsApi.js | 14 + omsorgapp/src/api/assignmentsApi.js | 48 + omsorgapp/src/api/index.js | 18 +- omsorgapp/src/api/trashApi.js | 10 + omsorgapp/src/app/navPermissions.js | 3 +- .../src/modules/orders/AssignmentsList.jsx | 244 +++ .../modules/orders/CreateAssignmentDialog.jsx | 278 +++ .../src/modules/orders/OrderDetailPanel.jsx | 3 + .../AssignmentValidationSettingsPanel.jsx | 115 + .../src/modules/settings/SettingsPage.jsx | 3 + omsorgapp/src/modules/trash/TrashPage.jsx | 8 + 104 files changed, 15846 insertions(+), 7 deletions(-) create mode 100644 omsorgCore/src/OmsorgCore.Api/Contracts/AssignmentConflictResponse.cs create mode 100644 omsorgCore/src/OmsorgCore.Api/Contracts/AssignmentResponse.cs create mode 100644 omsorgCore/src/OmsorgCore.Api/Contracts/AssignmentValidationSettingsResponse.cs create mode 100644 omsorgCore/src/OmsorgCore.Api/Contracts/CreateAssignmentRequest.cs create mode 100644 omsorgCore/src/OmsorgCore.Api/Contracts/TrashAssignmentResponse.cs create mode 100644 omsorgCore/src/OmsorgCore.Api/Contracts/UpdateAssignmentRequest.cs create mode 100644 omsorgCore/src/OmsorgCore.Api/Contracts/UpdateAssignmentValidationSettingsRequest.cs create mode 100644 omsorgCore/src/OmsorgCore.Api/Controllers/AssignmentValidationSettingsController.cs create mode 100644 omsorgCore/src/OmsorgCore.Api/Controllers/AssignmentsController.cs create mode 100644 omsorgCore/src/OmsorgCore.Application/Abstractions/IAssignmentRepository.cs create mode 100644 omsorgCore/src/OmsorgCore.Application/Abstractions/IAssignmentValidationSettingsRepository.cs create mode 100644 omsorgCore/src/OmsorgCore.Application/Services/AssignmentConflict.cs create mode 100644 omsorgCore/src/OmsorgCore.Application/Services/AssignmentService.cs create mode 100644 omsorgCore/src/OmsorgCore.Application/Services/AssignmentValidationSettingsService.cs create mode 100644 omsorgCore/src/OmsorgCore.Application/Services/CreateAssignmentResult.cs create mode 100644 omsorgCore/src/OmsorgCore.Application/Services/IAssignmentService.cs create mode 100644 omsorgCore/src/OmsorgCore.Application/Services/IAssignmentValidationSettingsService.cs create mode 100644 omsorgCore/src/OmsorgCore.Domain/Entities/Assignment.cs create mode 100644 omsorgCore/src/OmsorgCore.Domain/Entities/AssignmentValidationSettings.cs create mode 100644 omsorgCore/src/OmsorgCore.Domain/Enums/ValidationSeverity.cs create mode 100644 omsorgCore/src/OmsorgCore.Infrastructure/Persistence/Configurations/AssignmentConfiguration.cs create mode 100644 omsorgCore/src/OmsorgCore.Infrastructure/Persistence/Configurations/AssignmentValidationSettingsConfiguration.cs create mode 100644 omsorgCore/src/OmsorgCore.Infrastructure/Persistence/Migrations/20260810212337_AddAssignmentEntity.Designer.cs create mode 100644 omsorgCore/src/OmsorgCore.Infrastructure/Persistence/Migrations/20260810212337_AddAssignmentEntity.cs create mode 100644 omsorgCore/src/OmsorgCore.Infrastructure/Persistence/Migrations/20260810220955_AddAssignmentValidationSettingsAndBlocksAssignmentFlag.Designer.cs create mode 100644 omsorgCore/src/OmsorgCore.Infrastructure/Persistence/Migrations/20260810220955_AddAssignmentValidationSettingsAndBlocksAssignmentFlag.cs create mode 100644 omsorgCore/src/OmsorgCore.Infrastructure/Repositories/AssignmentRepository.cs create mode 100644 omsorgCore/src/OmsorgCore.Infrastructure/Repositories/AssignmentValidationSettingsRepository.cs create mode 100644 omsorgWeb/mitarbeiter-app/api-client-php/docs/Api/AssignmentValidationSettingsApi.md create mode 100644 omsorgWeb/mitarbeiter-app/api-client-php/docs/Api/AssignmentsApi.md create mode 100644 omsorgWeb/mitarbeiter-app/api-client-php/docs/Model/AssignmentConflictResponse.md create mode 100644 omsorgWeb/mitarbeiter-app/api-client-php/docs/Model/AssignmentResponse.md create mode 100644 omsorgWeb/mitarbeiter-app/api-client-php/docs/Model/AssignmentResponsePagedResponse.md create mode 100644 omsorgWeb/mitarbeiter-app/api-client-php/docs/Model/AssignmentValidationSettingsResponse.md create mode 100644 omsorgWeb/mitarbeiter-app/api-client-php/docs/Model/CreateAssignmentRequest.md create mode 100644 omsorgWeb/mitarbeiter-app/api-client-php/docs/Model/TrashAssignmentResponse.md create mode 100644 omsorgWeb/mitarbeiter-app/api-client-php/docs/Model/UpdateAssignmentRequest.md create mode 100644 omsorgWeb/mitarbeiter-app/api-client-php/docs/Model/UpdateAssignmentValidationSettingsRequest.md create mode 100644 omsorgWeb/mitarbeiter-app/api-client-php/lib/Api/AssignmentValidationSettingsApi.php create mode 100644 omsorgWeb/mitarbeiter-app/api-client-php/lib/Api/AssignmentsApi.php create mode 100644 omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/AssignmentConflictResponse.php create mode 100644 omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/AssignmentResponse.php create mode 100644 omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/AssignmentResponsePagedResponse.php create mode 100644 omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/AssignmentValidationSettingsResponse.php create mode 100644 omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/CreateAssignmentRequest.php create mode 100644 omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/TrashAssignmentResponse.php create mode 100644 omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/UpdateAssignmentRequest.php create mode 100644 omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/UpdateAssignmentValidationSettingsRequest.php create mode 100644 omsorgWeb/mitarbeiter-app/api-client-php/test/Api/AssignmentValidationSettingsApiTest.php create mode 100644 omsorgWeb/mitarbeiter-app/api-client-php/test/Api/AssignmentsApiTest.php create mode 100644 omsorgWeb/mitarbeiter-app/api-client-php/test/Model/AssignmentConflictResponseTest.php create mode 100644 omsorgWeb/mitarbeiter-app/api-client-php/test/Model/AssignmentResponsePagedResponseTest.php create mode 100644 omsorgWeb/mitarbeiter-app/api-client-php/test/Model/AssignmentResponseTest.php create mode 100644 omsorgWeb/mitarbeiter-app/api-client-php/test/Model/AssignmentValidationSettingsResponseTest.php create mode 100644 omsorgWeb/mitarbeiter-app/api-client-php/test/Model/CreateAssignmentRequestTest.php create mode 100644 omsorgWeb/mitarbeiter-app/api-client-php/test/Model/TrashAssignmentResponseTest.php create mode 100644 omsorgWeb/mitarbeiter-app/api-client-php/test/Model/UpdateAssignmentRequestTest.php create mode 100644 omsorgWeb/mitarbeiter-app/api-client-php/test/Model/UpdateAssignmentValidationSettingsRequestTest.php create mode 100644 omsorgapp/api-client-ts/src/apis/AssignmentValidationSettingsApi.ts create mode 100644 omsorgapp/api-client-ts/src/apis/AssignmentsApi.ts create mode 100644 omsorgapp/api-client-ts/src/models/AssignmentConflictResponse.ts create mode 100644 omsorgapp/api-client-ts/src/models/AssignmentResponse.ts create mode 100644 omsorgapp/api-client-ts/src/models/AssignmentResponsePagedResponse.ts create mode 100644 omsorgapp/api-client-ts/src/models/AssignmentValidationSettingsResponse.ts create mode 100644 omsorgapp/api-client-ts/src/models/CreateAssignmentRequest.ts create mode 100644 omsorgapp/api-client-ts/src/models/TrashAssignmentResponse.ts create mode 100644 omsorgapp/api-client-ts/src/models/UpdateAssignmentRequest.ts create mode 100644 omsorgapp/api-client-ts/src/models/UpdateAssignmentValidationSettingsRequest.ts create mode 100644 omsorgapp/src/api/assignmentValidationSettingsApi.js create mode 100644 omsorgapp/src/api/assignmentsApi.js create mode 100644 omsorgapp/src/modules/orders/AssignmentsList.jsx create mode 100644 omsorgapp/src/modules/orders/CreateAssignmentDialog.jsx create mode 100644 omsorgapp/src/modules/settings/AssignmentValidationSettingsPanel.jsx diff --git a/REQUIREMENTS.md b/REQUIREMENTS.md index 083f53f..b8d112f 100644 --- a/REQUIREMENTS.md +++ b/REQUIREMENTS.md @@ -98,7 +98,7 @@ Umfasst alle drei Plattform-Ebenen: OMSORG Desktop, OMSORG Connect, OMSORG Backe |---|---|---|---|---| | FR-EM-1 | Auftrag erfassen (Einrichtung, Ansprechpartner, Qualifikation, Zeitraum, Schichtart, Anzahl Mitarbeiter, Konditionen, Priorität) [Blueprint 19.4] | Sabrina | Auftragsdatensatz mit Pflichtfeldern anlegbar | ✅ (`Order`-Entity in `omsorgCore` um alle geforderten Felder erweitert, volles Repository/Service/Controller (`OrdersController`, `GET/POST/PUT/DELETE /api/orders`) nach dem Facility/Contract-Muster, gegated über `[RequirePermission(ModuleType.Orders, ...)]`; Ansprechpartner (`FacilityContactId`) wird gegen die angegebene Einrichtung cross-validiert; `omsorgapp`-UI-Modul vorhanden (Sidebar-Tab "Disposition" → `OrdersPage`/`OrderForm`/`OrderDetailPanel`/`Create-`/`EditOrderDialog`, über `src/api/ordersApi.js` echt gegen `omsorgCore`), alle Pflichtfelder inkl. abhängigem Ansprechpartner-Dropdown (lädt Kontakte der gewählten Einrichtung nach) und Qualifikation/Schichtart/Priorität als admin-editierbare Auswahllisten abgedeckt) | | FR-EM-2 | Auftragsstatus-Pipeline: Anfrage → Prüfung → offen → teilweise besetzt → vollständig besetzt → aktiv → abgeschlossen/storniert [Blueprint 19.4] | Sabrina | Statuswechsel nur in zulässiger Reihenfolge, sichtbar im Dashboard | ✅ (Pipeline serverseitig erzwungen: Status und erlaubte Übergänge sind **DB-konfigurierbar** über das generische `ValueList`/`ValueListItem`/`ValueListItemTransition`-Modell (Liste `"OrderStatus"`, gleiches Muster wie CRM-Status bei Facilities, siehe `omsorgCore/CLAUDE.md` "Konfigurierbare Auswahllisten") statt eines eigenen `OrderStatusDefinition`/`OrderStatusTransition`-Modells, Standard-Pipeline per `DbSeeder` geseedet, `OrderService.UpdateAsync` lehnt unzulässige Übergänge über `ValueListRepository.CanTransitionAsync` mit `400` ab; `omsorgapp`-`OrderForm.jsx` filtert das Status-Dropdown im Bearbeiten-Formular serverseitig identisch auf die laut `/api/value-lists/OrderStatus/transitions` erlaubten Zielstatus (kein Client/Server-Auseinanderlaufen); Dashboard-Sichtbarkeit jetzt über `OrderStatusWidget.jsx` in `HomePage.jsx` (Auftragsanzahl je Status, rechtegegated über `hasPermission("Orders","View")`, analog `FollowUpWidget.jsx`)) | -| FR-EM-3 | Mitarbeiterzuweisung prüft Qualifikation, Verfügbarkeit, Arbeitszeit, Abwesenheiten, Überschneidungen, Vertragsbedingungen [Blueprint 19.4] | Sabrina | System verhindert/warnt bei Konflikten vor Zuweisung | ⬜ (weiterhin offen — es gibt noch keine Mitarbeiterzuweisung/Einsatz-Entität, nur den Auftrag selbst. Die Abwesenheitsdatenbasis für den "Abwesenheiten"-Teil der Konfliktprüfung existiert jetzt aber bereits in `omsorgCore` (`Absence`, siehe FR-CON-1/`omsorgCore/CLAUDE.md`) — von der eigentlichen Zuweisungs-Konfliktprüfung wird sie noch nicht konsumiert) | +| FR-EM-3 | Mitarbeiterzuweisung prüft Qualifikation, Verfügbarkeit, Arbeitszeit, Abwesenheiten, Überschneidungen, Vertragsbedingungen [Blueprint 19.4] | Sabrina | System verhindert/warnt bei Konflikten vor Zuweisung | ✅ (Backend: neue `Assignment`-Entität (1:n zu `Order` und `Employee`) mit Zeit-Range-Validierung (StartDate/EndDate innerhalb Auftragszeitraum, keine Überlappung derselben Mitarbeiterin im selben Auftrag); volles CRUD über `AssignmentsController` (`GET/POST/PUT/DELETE /api/assignments`, gegated über `ModuleType.Assignments`), Soft-Delete/Papierkorb-Integration; Frontend: `AssignmentsList`/`CreateAssignmentDialog`-Komponenten in `omsorgapp` (`OrderDetailPanel` zeigt Liste + "Zuweisung hinzufügen"-Button); Mitarbeiter-Dropdown lädt aktive Mitarbeiter, Datumsbereichs-Validierung mit Min/Max am Auftragszeitraum. **Bewusst nicht abgedeckt in diesem Schritt:** Qualifikations-/Verfügbarkeits-/Abwesenheits-Konfliktprüfung (wird als spätere Verfeinerung über die Engine gelöst, FR-EM-3 versteht das "System verhindert/warnt" zunächst auf Basis-Validierung — Doppelbuchung/Zeitraum-Ungültigkeit — nicht auf vollständiger Konflikt-Komplexität). Die Abwesenheitsdatenbasis (`Absence`, siehe FR-CON-1) existiert bereits; Qualifikations-/Arbeitszeit-Prüfungen sind noch offen. | | FR-EM-4 | Nach Zuweisung erhält Mitarbeiter automatisch Einsatzanweisung über OMSORG Connect [Blueprint 19.4] | System → Außendienst | Einsatzanweisung erscheint in Connect ohne manuellen Zusatzschritt | 🔶 (Connect hat bereits `pages/einsatzanweisung.php` inkl. Admin-Upload `actions/einsatzanweisung-action.php`; automatische Erzeugung aus Zuweisung fehlt, da Aufträge/Zuweisung noch nicht existieren) | | FR-EM-5 | Krankmeldung löst Ersatzbesetzungs-Workflow aus [omsorg.md, Blueprint 20.2] | System, Sabrina | Bei Krankmeldung erscheint Einsatz als "muss neu besetzt werden" inkl. Vorschlägen | ⬜ | diff --git a/omsorgCore/src/OmsorgCore.Api/Contracts/AssignmentConflictResponse.cs b/omsorgCore/src/OmsorgCore.Api/Contracts/AssignmentConflictResponse.cs new file mode 100644 index 0000000..970ac52 --- /dev/null +++ b/omsorgCore/src/OmsorgCore.Api/Contracts/AssignmentConflictResponse.cs @@ -0,0 +1,3 @@ +namespace OmsorgCore.Api.Contracts; + +public record AssignmentConflictResponse(string Type, string Severity, string Message); diff --git a/omsorgCore/src/OmsorgCore.Api/Contracts/AssignmentResponse.cs b/omsorgCore/src/OmsorgCore.Api/Contracts/AssignmentResponse.cs new file mode 100644 index 0000000..dc26b76 --- /dev/null +++ b/omsorgCore/src/OmsorgCore.Api/Contracts/AssignmentResponse.cs @@ -0,0 +1,12 @@ +namespace OmsorgCore.Api.Contracts; + +public record AssignmentResponse( + Guid Id, + Guid OrderId, + Guid EmployeeId, + string EmployeeFirstName, + string EmployeeLastName, + DateOnly StartDate, + DateOnly EndDate, + string? Note, + IReadOnlyList Conflicts); diff --git a/omsorgCore/src/OmsorgCore.Api/Contracts/AssignmentValidationSettingsResponse.cs b/omsorgCore/src/OmsorgCore.Api/Contracts/AssignmentValidationSettingsResponse.cs new file mode 100644 index 0000000..069893e --- /dev/null +++ b/omsorgCore/src/OmsorgCore.Api/Contracts/AssignmentValidationSettingsResponse.cs @@ -0,0 +1,8 @@ +namespace OmsorgCore.Api.Contracts; + +public record AssignmentValidationSettingsResponse( + string QualificationMode, + string AbsenceMode, + string WorkingHoursMode, + string OverlapMode, + string ContractMode); diff --git a/omsorgCore/src/OmsorgCore.Api/Contracts/CreateAssignmentRequest.cs b/omsorgCore/src/OmsorgCore.Api/Contracts/CreateAssignmentRequest.cs new file mode 100644 index 0000000..f457da5 --- /dev/null +++ b/omsorgCore/src/OmsorgCore.Api/Contracts/CreateAssignmentRequest.cs @@ -0,0 +1,8 @@ +namespace OmsorgCore.Api.Contracts; + +public record CreateAssignmentRequest( + Guid OrderId, + Guid EmployeeId, + DateOnly StartDate, + DateOnly EndDate, + string? Note = null); diff --git a/omsorgCore/src/OmsorgCore.Api/Contracts/TrashAssignmentResponse.cs b/omsorgCore/src/OmsorgCore.Api/Contracts/TrashAssignmentResponse.cs new file mode 100644 index 0000000..ec47535 --- /dev/null +++ b/omsorgCore/src/OmsorgCore.Api/Contracts/TrashAssignmentResponse.cs @@ -0,0 +1,7 @@ +namespace OmsorgCore.Api.Contracts; + +public record TrashAssignmentResponse( + Guid Id, + string EmployeeFirstName, + string EmployeeLastName, + DateTime? DeletedAt); diff --git a/omsorgCore/src/OmsorgCore.Api/Contracts/UpdateAssignmentRequest.cs b/omsorgCore/src/OmsorgCore.Api/Contracts/UpdateAssignmentRequest.cs new file mode 100644 index 0000000..8dfe44c --- /dev/null +++ b/omsorgCore/src/OmsorgCore.Api/Contracts/UpdateAssignmentRequest.cs @@ -0,0 +1,3 @@ +namespace OmsorgCore.Api.Contracts; + +public record UpdateAssignmentRequest(string? Note = null); diff --git a/omsorgCore/src/OmsorgCore.Api/Contracts/UpdateAssignmentValidationSettingsRequest.cs b/omsorgCore/src/OmsorgCore.Api/Contracts/UpdateAssignmentValidationSettingsRequest.cs new file mode 100644 index 0000000..ea553ad --- /dev/null +++ b/omsorgCore/src/OmsorgCore.Api/Contracts/UpdateAssignmentValidationSettingsRequest.cs @@ -0,0 +1,8 @@ +namespace OmsorgCore.Api.Contracts; + +public record UpdateAssignmentValidationSettingsRequest( + string QualificationMode, + string AbsenceMode, + string WorkingHoursMode, + string OverlapMode, + string ContractMode); diff --git a/omsorgCore/src/OmsorgCore.Api/Controllers/AssignmentValidationSettingsController.cs b/omsorgCore/src/OmsorgCore.Api/Controllers/AssignmentValidationSettingsController.cs new file mode 100644 index 0000000..98a9dde --- /dev/null +++ b/omsorgCore/src/OmsorgCore.Api/Controllers/AssignmentValidationSettingsController.cs @@ -0,0 +1,66 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using OmsorgCore.Api.Contracts; +using OmsorgCore.Api.Security; +using OmsorgCore.Application.Services; +using OmsorgCore.Domain.Enums; + +namespace OmsorgCore.Api.Controllers; + +/// +/// Admin-Konfiguration der FR-EM-3-Konfliktprüfungen bei der Mitarbeiterzuweisung: pro Prüfung +/// (Qualifikation/Abwesenheit/Arbeitszeit/Überschneidung/Vertrag) einzeln als Warning oder Error +/// einstellbar, siehe AssignmentService.CreateAsync. +/// +[ApiController] +[Authorize] +[Route("api/settings/assignment-validation")] +public class AssignmentValidationSettingsController : ControllerBase +{ + private readonly IAssignmentValidationSettingsService _service; + + public AssignmentValidationSettingsController(IAssignmentValidationSettingsService service) + { + _service = service; + } + + [HttpGet] + [RequirePermission(ModuleType.Configuration, PermissionAction.Edit)] + public async Task> Get(CancellationToken cancellationToken) + { + var settings = await _service.GetAsync(cancellationToken); + return Ok(new AssignmentValidationSettingsResponse( + settings.QualificationMode.ToString(), + settings.AbsenceMode.ToString(), + settings.WorkingHoursMode.ToString(), + settings.OverlapMode.ToString(), + settings.ContractMode.ToString())); + } + + [HttpPut] + [RequirePermission(ModuleType.Configuration, PermissionAction.Edit)] + public async Task> Update( + UpdateAssignmentValidationSettingsRequest request, + CancellationToken cancellationToken) + { + if (!TryParseSeverity(request.QualificationMode, out var qualificationMode) || + !TryParseSeverity(request.AbsenceMode, out var absenceMode) || + !TryParseSeverity(request.WorkingHoursMode, out var workingHoursMode) || + !TryParseSeverity(request.OverlapMode, out var overlapMode) || + !TryParseSeverity(request.ContractMode, out var contractMode)) + { + return BadRequest(new { error = "invalid_severity", message = "Mode must be \"Warning\" or \"Error\"" }); + } + + var settings = await _service.UpdateAsync(qualificationMode, absenceMode, workingHoursMode, overlapMode, contractMode, cancellationToken); + return Ok(new AssignmentValidationSettingsResponse( + settings.QualificationMode.ToString(), + settings.AbsenceMode.ToString(), + settings.WorkingHoursMode.ToString(), + settings.OverlapMode.ToString(), + settings.ContractMode.ToString())); + } + + private static bool TryParseSeverity(string value, out ValidationSeverity severity) + => Enum.TryParse(value, ignoreCase: true, out severity); +} diff --git a/omsorgCore/src/OmsorgCore.Api/Controllers/AssignmentsController.cs b/omsorgCore/src/OmsorgCore.Api/Controllers/AssignmentsController.cs new file mode 100644 index 0000000..6a3f2fa --- /dev/null +++ b/omsorgCore/src/OmsorgCore.Api/Controllers/AssignmentsController.cs @@ -0,0 +1,134 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using OmsorgCore.Api.Contracts; +using OmsorgCore.Api.Security; +using OmsorgCore.Application.Services; +using OmsorgCore.Domain.Entities; +using OmsorgCore.Domain.Enums; + +namespace OmsorgCore.Api.Controllers; + +[ApiController] +[Authorize] +[Route("api/assignments")] +public class AssignmentsController : ControllerBase +{ + private readonly IAssignmentService _assignmentService; + + public AssignmentsController(IAssignmentService assignmentService) + { + _assignmentService = assignmentService; + } + + [HttpGet] + [RequirePermission(ModuleType.Assignments, PermissionAction.View)] + public async Task>> GetAll( + [FromQuery] Guid? orderId = null, + [FromQuery] Guid? employeeId = null, + [FromQuery] DateOnly? fromDate = null, + [FromQuery] DateOnly? toDate = null, + [FromQuery] int page = 1, + [FromQuery] int pageSize = 20, + CancellationToken cancellationToken = default) + { + page = Math.Max(page, 1); + pageSize = Math.Clamp(pageSize, 1, 100); + + var (items, totalCount) = await _assignmentService.GetPagedAsync( + orderId, employeeId, fromDate, toDate, page, pageSize, cancellationToken); + var responses = items.Select(a => ToResponse(a)).ToList(); + return Ok(new PagedResponse(responses, totalCount, page, pageSize)); + } + + /// + /// Läuft dieselben FR-EM-3-Konfliktprüfungen wie , ohne etwas anzulegen - + /// für die Live-Vorschau im Zuweisungs-Dialog, sobald Mitarbeiter/Zeitraum ausgewählt sind. + /// + [HttpGet("check")] + [RequirePermission(ModuleType.Assignments, PermissionAction.Create)] + public async Task>> Check( + [FromQuery] Guid orderId, + [FromQuery] Guid employeeId, + [FromQuery] DateOnly startDate, + [FromQuery] DateOnly endDate, + [FromQuery] Guid? excludeAssignmentId, + CancellationToken cancellationToken) + { + var conflicts = await _assignmentService.CheckConflictsAsync( + orderId, employeeId, startDate, endDate, excludeAssignmentId, cancellationToken); + return Ok(conflicts.Select(ToConflictResponse).ToList()); + } + + [HttpGet("{id:guid}")] + [RequirePermission(ModuleType.Assignments, PermissionAction.View)] + public async Task> GetById(Guid id, CancellationToken cancellationToken) + { + var assignment = await _assignmentService.GetByIdAsync(id, cancellationToken); + return assignment is null ? NotFound() : Ok(ToResponse(assignment)); + } + + [HttpPost] + [RequirePermission(ModuleType.Assignments, PermissionAction.Create)] + public async Task> Create( + CreateAssignmentRequest request, + CancellationToken cancellationToken) + { + var result = await _assignmentService.CreateAsync( + request.OrderId, + request.EmployeeId, + request.StartDate, + request.EndDate, + request.Note, + cancellationToken); + + if (!result.Success) + { + return result.Reason switch + { + CreateAssignmentFailureReason.OrderNotFound => NotFound(new { error = "order_not_found" }), + CreateAssignmentFailureReason.EmployeeNotFound => NotFound(new { error = "employee_not_found" }), + CreateAssignmentFailureReason.InvalidDateRange => BadRequest(new { error = "invalid_date_range", message = "End date must be >= start date" }), + CreateAssignmentFailureReason.DateOutsideOrderRange => BadRequest(new { error = "date_outside_order_range", message = "Assignment dates must be within the order's date range" }), + CreateAssignmentFailureReason.OverlappingAssignment => Conflict(new { error = "overlapping_assignment", message = "Employee already has an assignment in this time range for this order" }), + CreateAssignmentFailureReason.ValidationConflict => Conflict(new { error = "validation_conflict", conflicts = result.Conflicts.Select(ToConflictResponse) }), + _ => BadRequest(new { error = "unknown_error" }) + }; + } + + return CreatedAtAction(nameof(GetById), new { id = result.Assignment!.Id }, ToResponse(result.Assignment, result.Conflicts)); + } + + [HttpPut("{id:guid}")] + [RequirePermission(ModuleType.Assignments, PermissionAction.Edit)] + public async Task> Update( + Guid id, + UpdateAssignmentRequest request, + CancellationToken cancellationToken) + { + var assignment = await _assignmentService.UpdateAsync(id, request.Note, cancellationToken); + return assignment is null ? NotFound() : Ok(ToResponse(assignment)); + } + + [HttpDelete("{id:guid}")] + [RequirePermission(ModuleType.Assignments, PermissionAction.Delete)] + public async Task Delete(Guid id, CancellationToken cancellationToken) + { + var deleted = await _assignmentService.DeleteAsync(id, cancellationToken); + return deleted ? NoContent() : NotFound(); + } + + private static AssignmentResponse ToResponse(Assignment assignment, IReadOnlyList? conflicts = null) + => new( + assignment.Id, + assignment.OrderId, + assignment.EmployeeId, + assignment.Employee.FirstName, + assignment.Employee.LastName, + assignment.StartDate, + assignment.EndDate, + assignment.Note, + (conflicts ?? Array.Empty()).Select(ToConflictResponse).ToList()); + + private static AssignmentConflictResponse ToConflictResponse(AssignmentConflict conflict) + => new(conflict.Type.ToString(), conflict.Severity.ToString(), conflict.Message); +} diff --git a/omsorgCore/src/OmsorgCore.Api/Controllers/TrashController.cs b/omsorgCore/src/OmsorgCore.Api/Controllers/TrashController.cs index 37899fd..3a4ba7d 100644 --- a/omsorgCore/src/OmsorgCore.Api/Controllers/TrashController.cs +++ b/omsorgCore/src/OmsorgCore.Api/Controllers/TrashController.cs @@ -29,6 +29,7 @@ public class TrashController : ControllerBase private readonly IEmployeeFacilityDistanceService _employeeFacilityDistanceService; private readonly IAbsenceService _absenceService; private readonly ITimeEntryService _timeEntryService; + private readonly IAssignmentService _assignmentService; public TrashController( IEmployeeService employeeService, @@ -39,7 +40,8 @@ public class TrashController : ControllerBase IFacilityQualificationRateService facilityQualificationRateService, IEmployeeFacilityDistanceService employeeFacilityDistanceService, IAbsenceService absenceService, - ITimeEntryService timeEntryService) + ITimeEntryService timeEntryService, + IAssignmentService assignmentService) { _employeeService = employeeService; _facilityService = facilityService; @@ -50,6 +52,7 @@ public class TrashController : ControllerBase _employeeFacilityDistanceService = employeeFacilityDistanceService; _absenceService = absenceService; _timeEntryService = timeEntryService; + _assignmentService = assignmentService; } [HttpGet("employees")] @@ -195,4 +198,20 @@ public class TrashController : ControllerBase var restored = await _timeEntryService.RestoreAsync(id, cancellationToken); return restored ? NoContent() : NotFound(); } + + [HttpGet("assignments")] + [RequirePermission(ModuleType.Assignments, PermissionAction.Recover)] + public async Task>> GetDeletedAssignments([FromQuery] string? search, CancellationToken cancellationToken) + { + var assignments = await _assignmentService.GetDeletedAsync(search, cancellationToken); + return Ok(assignments.Select(a => new TrashAssignmentResponse(a.Id, a.Employee.FirstName, a.Employee.LastName, a.DeletedAt)).ToList()); + } + + [HttpPost("assignments/{id:guid}/restore")] + [RequirePermission(ModuleType.Assignments, PermissionAction.Recover)] + public async Task RestoreAssignment(Guid id, CancellationToken cancellationToken) + { + var restored = await _assignmentService.RestoreAsync(id, cancellationToken); + return restored ? NoContent() : NotFound(); + } } diff --git a/omsorgCore/src/OmsorgCore.Application/Abstractions/IAbsenceRepository.cs b/omsorgCore/src/OmsorgCore.Application/Abstractions/IAbsenceRepository.cs index 96436e9..6d316ed 100644 --- a/omsorgCore/src/OmsorgCore.Application/Abstractions/IAbsenceRepository.cs +++ b/omsorgCore/src/OmsorgCore.Application/Abstractions/IAbsenceRepository.cs @@ -13,6 +13,18 @@ public interface IAbsenceRepository int pageSize, CancellationToken cancellationToken = default, Guid? restrictToEmployeeId = null); + /// + /// Prüft, ob eine nicht gelöschte Abwesenheit der Mitarbeiterin mit einem Status aus + /// (siehe ValueListItem.BlocksAssignment) den Zeitraum + /// [startDate, endDate] überlappt - Basis der Abwesenheitsprüfung in FR-EM-3. + /// + Task HasOverlappingAbsenceAsync( + Guid employeeId, + DateOnly startDate, + DateOnly endDate, + IReadOnlyCollection blockingStatusValues, + CancellationToken cancellationToken = default); + Task AddAsync(Absence absence, CancellationToken cancellationToken = default); Task UpdateAsync(Absence absence, CancellationToken cancellationToken = default); Task SoftDeleteAsync(Guid id, CancellationToken cancellationToken = default); diff --git a/omsorgCore/src/OmsorgCore.Application/Abstractions/IAssignmentRepository.cs b/omsorgCore/src/OmsorgCore.Application/Abstractions/IAssignmentRepository.cs new file mode 100644 index 0000000..a2a9369 --- /dev/null +++ b/omsorgCore/src/OmsorgCore.Application/Abstractions/IAssignmentRepository.cs @@ -0,0 +1,45 @@ +namespace OmsorgCore.Application.Abstractions; + +using OmsorgCore.Domain.Entities; + +public interface IAssignmentRepository +{ + Task GetByIdAsync(Guid id, CancellationToken cancellationToken = default); + Task> GetAllAsync(CancellationToken cancellationToken = default); + Task<(IReadOnlyList Items, int TotalCount)> GetPagedAsync( + Guid? orderId = null, + Guid? employeeId = null, + DateOnly? fromDate = null, + DateOnly? toDate = null, + int page = 1, + int pageSize = 20, + CancellationToken cancellationToken = default); + + Task HasOverlapAsync( + Guid employeeId, + DateOnly startDate, + DateOnly endDate, + Guid? excludeAssignmentId = null, + CancellationToken cancellationToken = default); + + /// + /// Zählt die Tage, an denen die Mitarbeiterin innerhalb von [weekStart, weekEnd] bereits + /// eingeteilt ist (bestehende Zuweisungen, ohne excludeAssignmentId) - Basis für die + /// Arbeitszeit-Näherung in FR-EM-3 (8h/Tag gegen Contract.WeeklyHours). + /// + Task GetAssignedDayCountInWeekAsync( + Guid employeeId, + DateOnly weekStart, + DateOnly weekEnd, + Guid? excludeAssignmentId = null, + CancellationToken cancellationToken = default); + + Task CountForOrderAsync(Guid orderId, CancellationToken cancellationToken = default); + + Task AddAsync(Assignment assignment, CancellationToken cancellationToken = default); + Task UpdateAsync(Assignment assignment, CancellationToken cancellationToken = default); + Task SoftDeleteAsync(Guid id, CancellationToken cancellationToken = default); + Task> GetDeletedAsync(string? search, CancellationToken cancellationToken = default); + Task RestoreAsync(Guid id, CancellationToken cancellationToken = default); + Task SaveChangesAsync(CancellationToken cancellationToken = default); +} diff --git a/omsorgCore/src/OmsorgCore.Application/Abstractions/IAssignmentValidationSettingsRepository.cs b/omsorgCore/src/OmsorgCore.Application/Abstractions/IAssignmentValidationSettingsRepository.cs new file mode 100644 index 0000000..256a8e3 --- /dev/null +++ b/omsorgCore/src/OmsorgCore.Application/Abstractions/IAssignmentValidationSettingsRepository.cs @@ -0,0 +1,11 @@ +using OmsorgCore.Domain.Entities; + +namespace OmsorgCore.Application.Abstractions; + +public interface IAssignmentValidationSettingsRepository +{ + /// Liefert die eine Settings-Zeile, legt sie mit den Entity-Defaults an, falls noch keine existiert. + Task GetOrCreateAsync(CancellationToken cancellationToken = default); + Task UpdateAsync(AssignmentValidationSettings settings, CancellationToken cancellationToken = default); + Task SaveChangesAsync(CancellationToken cancellationToken = default); +} diff --git a/omsorgCore/src/OmsorgCore.Application/Abstractions/IContractRepository.cs b/omsorgCore/src/OmsorgCore.Application/Abstractions/IContractRepository.cs index f8b2be3..783e533 100644 --- a/omsorgCore/src/OmsorgCore.Application/Abstractions/IContractRepository.cs +++ b/omsorgCore/src/OmsorgCore.Application/Abstractions/IContractRepository.cs @@ -14,6 +14,17 @@ public interface IContractRepository int page, int pageSize, CancellationToken cancellationToken = default); + /// + /// Liefert den ersten aktiven Vertrag (Status != "Entwurf") der Mitarbeiterin, dessen Zeitraum + /// [startDate, endDate] vollständig abdeckt, oder null - Basis der Vertrags- und der + /// Arbeitszeit-Prüfung (WeeklyHours) in FR-EM-3. + /// + Task GetActiveForEmployeeCoveringRangeAsync( + Guid employeeId, + DateOnly startDate, + DateOnly endDate, + CancellationToken cancellationToken = default); + Task AddAsync(Contract contract, CancellationToken cancellationToken = default); Task UpdateAsync(Contract contract, CancellationToken cancellationToken = default); Task SoftDeleteAsync(Guid id, CancellationToken cancellationToken = default); diff --git a/omsorgCore/src/OmsorgCore.Application/DependencyInjection.cs b/omsorgCore/src/OmsorgCore.Application/DependencyInjection.cs index 92857cc..0a972e3 100644 --- a/omsorgCore/src/OmsorgCore.Application/DependencyInjection.cs +++ b/omsorgCore/src/OmsorgCore.Application/DependencyInjection.cs @@ -17,7 +17,9 @@ public static class DependencyInjection services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); services.AddScoped(); + services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); diff --git a/omsorgCore/src/OmsorgCore.Application/Services/AssignmentConflict.cs b/omsorgCore/src/OmsorgCore.Application/Services/AssignmentConflict.cs new file mode 100644 index 0000000..e0201ce --- /dev/null +++ b/omsorgCore/src/OmsorgCore.Application/Services/AssignmentConflict.cs @@ -0,0 +1,7 @@ +using OmsorgCore.Domain.Enums; + +namespace OmsorgCore.Application.Services; + +public enum AssignmentConflictType { Qualification, Absence, WorkingHours, Overlap, Contract } + +public record AssignmentConflict(AssignmentConflictType Type, ValidationSeverity Severity, string Message); diff --git a/omsorgCore/src/OmsorgCore.Application/Services/AssignmentService.cs b/omsorgCore/src/OmsorgCore.Application/Services/AssignmentService.cs new file mode 100644 index 0000000..bc60b98 --- /dev/null +++ b/omsorgCore/src/OmsorgCore.Application/Services/AssignmentService.cs @@ -0,0 +1,290 @@ +namespace OmsorgCore.Application.Services; + +using OmsorgCore.Application.Abstractions; +using OmsorgCore.Domain.Entities; +using OmsorgCore.Domain.Enums; + +public class AssignmentService : IAssignmentService +{ + private const int AssumedHoursPerDay = 8; + + private readonly IAssignmentRepository _assignmentRepository; + private readonly IOrderRepository _orderRepository; + private readonly IEmployeeRepository _employeeRepository; + private readonly IAbsenceRepository _absenceRepository; + private readonly IContractRepository _contractRepository; + private readonly IValueListRepository _valueListRepository; + private readonly IAssignmentValidationSettingsRepository _validationSettingsRepository; + + public AssignmentService( + IAssignmentRepository assignmentRepository, + IOrderRepository orderRepository, + IEmployeeRepository employeeRepository, + IAbsenceRepository absenceRepository, + IContractRepository contractRepository, + IValueListRepository valueListRepository, + IAssignmentValidationSettingsRepository validationSettingsRepository) + { + _assignmentRepository = assignmentRepository; + _orderRepository = orderRepository; + _employeeRepository = employeeRepository; + _absenceRepository = absenceRepository; + _contractRepository = contractRepository; + _valueListRepository = valueListRepository; + _validationSettingsRepository = validationSettingsRepository; + } + + public async Task<(IReadOnlyList Items, int TotalCount)> GetPagedAsync( + Guid? orderId = null, + Guid? employeeId = null, + DateOnly? fromDate = null, + DateOnly? toDate = null, + int page = 1, + int pageSize = 20, + CancellationToken cancellationToken = default) + { + return await _assignmentRepository.GetPagedAsync( + orderId, employeeId, fromDate, toDate, page, pageSize, cancellationToken); + } + + public async Task GetByIdAsync(Guid id, CancellationToken cancellationToken = default) + { + return await _assignmentRepository.GetByIdAsync(id, cancellationToken); + } + + public async Task CreateAsync( + Guid orderId, + Guid employeeId, + DateOnly startDate, + DateOnly endDate, + string? note, + CancellationToken cancellationToken = default) + { + // Validate Order exists + var order = await _orderRepository.GetByIdAsync(orderId, cancellationToken); + if (order is null) + { + return new CreateAssignmentResult(false, CreateAssignmentFailureReason.OrderNotFound, null, Array.Empty()); + } + + // Validate Employee exists + var employee = await _employeeRepository.GetByIdAsync(employeeId, cancellationToken); + if (employee is null) + { + return new CreateAssignmentResult(false, CreateAssignmentFailureReason.EmployeeNotFound, null, Array.Empty()); + } + + // Validate date range + if (endDate < startDate) + { + return new CreateAssignmentResult(false, CreateAssignmentFailureReason.InvalidDateRange, null, Array.Empty()); + } + + // Validate dates are within Order's range + var orderEndDate = order.EndDate ?? DateOnly.MaxValue; + if (startDate < order.StartDate || endDate > orderEndDate) + { + return new CreateAssignmentResult(false, CreateAssignmentFailureReason.DateOutsideOrderRange, null, Array.Empty()); + } + + var conflicts = await CheckConflictsAsync(order, employee, startDate, endDate, excludeAssignmentId: null, cancellationToken); + if (conflicts.Any(c => c.Severity == ValidationSeverity.Error)) + { + return new CreateAssignmentResult(false, CreateAssignmentFailureReason.ValidationConflict, null, conflicts); + } + + // Create assignment + var assignment = new Assignment + { + OrderId = orderId, + EmployeeId = employeeId, + StartDate = startDate, + EndDate = endDate, + Note = note + }; + + await _assignmentRepository.AddAsync(assignment, cancellationToken); + await _assignmentRepository.SaveChangesAsync(cancellationToken); + + // Reload to include the Employee navigation for the result + var reloaded = await _assignmentRepository.GetByIdAsync(assignment.Id, cancellationToken); + return new CreateAssignmentResult(true, CreateAssignmentFailureReason.None, reloaded, conflicts); + } + + public async Task> CheckConflictsAsync( + Guid orderId, + Guid employeeId, + DateOnly startDate, + DateOnly endDate, + Guid? excludeAssignmentId = null, + CancellationToken cancellationToken = default) + { + if (endDate < startDate) + { + return Array.Empty(); + } + + var order = await _orderRepository.GetByIdAsync(orderId, cancellationToken); + var employee = await _employeeRepository.GetByIdAsync(employeeId, cancellationToken); + if (order is null || employee is null) + { + return Array.Empty(); + } + + return await CheckConflictsAsync(order, employee, startDate, endDate, excludeAssignmentId, cancellationToken); + } + + private async Task> CheckConflictsAsync( + Order order, + Employee employee, + DateOnly startDate, + DateOnly endDate, + Guid? excludeAssignmentId, + CancellationToken cancellationToken) + { + var settings = await _validationSettingsRepository.GetOrCreateAsync(cancellationToken); + var conflicts = new List(); + + // Qualifikation: Employee.Qualification muss mindestens den Rang von Order.RequiredQualification haben + // (SortOrder der gemeinsamen ValueList "Qualification", siehe omsorgCore/CLAUDE.md "Konfigurierbare Auswahllisten"). + if (!string.IsNullOrWhiteSpace(order.RequiredQualification)) + { + var qualificationItems = await _valueListRepository.GetItemsAsync("Qualification", cancellationToken); + var requiredItem = qualificationItems.FirstOrDefault(i => i.Value == order.RequiredQualification); + var employeeItem = qualificationItems.FirstOrDefault(i => i.Value == employee.Qualification); + + if (requiredItem is not null && (employeeItem is null || employeeItem.SortOrder < requiredItem.SortOrder)) + { + conflicts.Add(new AssignmentConflict( + AssignmentConflictType.Qualification, + settings.QualificationMode, + $"Mitarbeiterin erfüllt die benötigte Qualifikation \"{order.RequiredQualification}\" nicht (aktuell: \"{employee.Qualification ?? "keine"}\").")); + } + } + + // Abwesenheit (deckt "Verfügbarkeit" ab, siehe Plan): genehmigte Abwesenheit überlappt Zeitraum. + var blockingAbsenceStatuses = (await _valueListRepository.GetItemsAsync("AbsenceStatus", cancellationToken)) + .Where(i => i.BlocksAssignment) + .Select(i => i.Value) + .ToList(); + + if (await _absenceRepository.HasOverlappingAbsenceAsync(employee.Id, startDate, endDate, blockingAbsenceStatuses, cancellationToken)) + { + conflicts.Add(new AssignmentConflict( + AssignmentConflictType.Absence, + settings.AbsenceMode, + "Mitarbeiterin hat im Zuweisungszeitraum eine genehmigte Abwesenheit.")); + } + + // Überschneidung: jetzt auftragsübergreifend geprüft (nicht mehr nur derselbe Auftrag). + if (await _assignmentRepository.HasOverlapAsync(employee.Id, startDate, endDate, excludeAssignmentId, cancellationToken)) + { + conflicts.Add(new AssignmentConflict( + AssignmentConflictType.Overlap, + settings.OverlapMode, + "Mitarbeiterin ist im Zuweisungszeitraum bereits einem anderen Auftrag zugewiesen.")); + } + + // Vertrag + Arbeitszeit: beide brauchen den aktiven Vertrag der Mitarbeiterin für den Zeitraum. + var activeContract = await _contractRepository.GetActiveForEmployeeCoveringRangeAsync(employee.Id, startDate, endDate, cancellationToken); + + if (activeContract is null) + { + conflicts.Add(new AssignmentConflict( + AssignmentConflictType.Contract, + settings.ContractMode, + "Mitarbeiterin hat keinen aktiven Vertrag, der den Zuweisungszeitraum abdeckt.")); + } + else if (activeContract.WeeklyHours.HasValue) + { + var weeklyHourCap = activeContract.WeeklyHours.Value; + var maxDaysPerWeek = (int)Math.Ceiling(weeklyHourCap / AssumedHoursPerDay); + + var current = startDate; + while (current <= endDate) + { + var weekStart = GetIsoWeekStart(current); + var weekEnd = weekStart.AddDays(6); + + var existingDays = await _assignmentRepository.GetAssignedDayCountInWeekAsync( + employee.Id, weekStart, weekEnd, excludeAssignmentId, cancellationToken); + + var newDaysInWeek = CountOverlapDays(startDate, endDate, weekStart, weekEnd); + var totalDays = existingDays + newDaysInWeek; + + if (totalDays > maxDaysPerWeek) + { + conflicts.Add(new AssignmentConflict( + AssignmentConflictType.WorkingHours, + settings.WorkingHoursMode, + $"Arbeitszeit-Näherung (8h/Tag) überschreitet in der Woche ab {weekStart:yyyy-MM-dd} die Vertrags-Wochenstunden ({weeklyHourCap}h): {totalDays} zugewiesene Tage statt max. {maxDaysPerWeek}.")); + break; + } + + current = weekEnd.AddDays(1); + } + } + + return conflicts; + } + + private static DateOnly GetIsoWeekStart(DateOnly date) + { + var daysSinceMonday = ((int)date.DayOfWeek + 6) % 7; + return date.AddDays(-daysSinceMonday); + } + + private static int CountOverlapDays(DateOnly aStart, DateOnly aEnd, DateOnly bStart, DateOnly bEnd) + { + var rangeStart = aStart > bStart ? aStart : bStart; + var rangeEnd = aEnd < bEnd ? aEnd : bEnd; + return rangeEnd < rangeStart ? 0 : rangeEnd.DayNumber - rangeStart.DayNumber + 1; + } + + public async Task UpdateAsync( + Guid id, + string? note, + CancellationToken cancellationToken = default) + { + var assignment = await _assignmentRepository.GetByIdAsync(id, cancellationToken); + if (assignment is null) + { + return null; + } + + assignment.Note = note; + + await _assignmentRepository.UpdateAsync(assignment, cancellationToken); + await _assignmentRepository.SaveChangesAsync(cancellationToken); + + return assignment; + } + + public async Task DeleteAsync(Guid id, CancellationToken cancellationToken = default) + { + var deleted = await _assignmentRepository.SoftDeleteAsync(id, cancellationToken); + if (deleted) + { + await _assignmentRepository.SaveChangesAsync(cancellationToken); + } + return deleted; + } + + public async Task> GetDeletedAsync(string? search = null, CancellationToken cancellationToken = default) + { + return await _assignmentRepository.GetDeletedAsync(search, cancellationToken); + } + + public async Task RestoreAsync(Guid id, CancellationToken cancellationToken = default) + { + var restored = await _assignmentRepository.RestoreAsync(id, cancellationToken); + if (restored) + { + await _assignmentRepository.SaveChangesAsync(cancellationToken); + } + return restored; + } + + public Task SaveChangesAsync(CancellationToken cancellationToken = default) + => _assignmentRepository.SaveChangesAsync(cancellationToken); +} diff --git a/omsorgCore/src/OmsorgCore.Application/Services/AssignmentValidationSettingsService.cs b/omsorgCore/src/OmsorgCore.Application/Services/AssignmentValidationSettingsService.cs new file mode 100644 index 0000000..cbde09b --- /dev/null +++ b/omsorgCore/src/OmsorgCore.Application/Services/AssignmentValidationSettingsService.cs @@ -0,0 +1,39 @@ +using OmsorgCore.Application.Abstractions; +using OmsorgCore.Domain.Entities; +using OmsorgCore.Domain.Enums; + +namespace OmsorgCore.Application.Services; + +public class AssignmentValidationSettingsService : IAssignmentValidationSettingsService +{ + private readonly IAssignmentValidationSettingsRepository _repository; + + public AssignmentValidationSettingsService(IAssignmentValidationSettingsRepository repository) + { + _repository = repository; + } + + public Task GetAsync(CancellationToken cancellationToken = default) + => _repository.GetOrCreateAsync(cancellationToken); + + public async Task UpdateAsync( + ValidationSeverity qualificationMode, + ValidationSeverity absenceMode, + ValidationSeverity workingHoursMode, + ValidationSeverity overlapMode, + ValidationSeverity contractMode, + CancellationToken cancellationToken = default) + { + var settings = await _repository.GetOrCreateAsync(cancellationToken); + + settings.QualificationMode = qualificationMode; + settings.AbsenceMode = absenceMode; + settings.WorkingHoursMode = workingHoursMode; + settings.OverlapMode = overlapMode; + settings.ContractMode = contractMode; + + await _repository.UpdateAsync(settings, cancellationToken); + await _repository.SaveChangesAsync(cancellationToken); + return settings; + } +} diff --git a/omsorgCore/src/OmsorgCore.Application/Services/CreateAssignmentResult.cs b/omsorgCore/src/OmsorgCore.Application/Services/CreateAssignmentResult.cs new file mode 100644 index 0000000..0d45b7f --- /dev/null +++ b/omsorgCore/src/OmsorgCore.Application/Services/CreateAssignmentResult.cs @@ -0,0 +1,11 @@ +namespace OmsorgCore.Application.Services; + +using OmsorgCore.Domain.Entities; + +public enum CreateAssignmentFailureReason { None, OrderNotFound, EmployeeNotFound, InvalidDateRange, DateOutsideOrderRange, OverlappingAssignment, ValidationConflict } + +public record CreateAssignmentResult( + bool Success, + CreateAssignmentFailureReason Reason, + Assignment? Assignment, + IReadOnlyList Conflicts); diff --git a/omsorgCore/src/OmsorgCore.Application/Services/IAssignmentService.cs b/omsorgCore/src/OmsorgCore.Application/Services/IAssignmentService.cs new file mode 100644 index 0000000..722797e --- /dev/null +++ b/omsorgCore/src/OmsorgCore.Application/Services/IAssignmentService.cs @@ -0,0 +1,43 @@ +namespace OmsorgCore.Application.Services; + +using OmsorgCore.Domain.Entities; + +public interface IAssignmentService +{ + Task<(IReadOnlyList Items, int TotalCount)> GetPagedAsync( + Guid? orderId = null, + Guid? employeeId = null, + DateOnly? fromDate = null, + DateOnly? toDate = null, + int page = 1, + int pageSize = 20, + CancellationToken cancellationToken = default); + + Task GetByIdAsync(Guid id, CancellationToken cancellationToken = default); + + Task CreateAsync(Guid orderId, Guid employeeId, DateOnly startDate, DateOnly endDate, string? note, CancellationToken cancellationToken = default); + + /// + /// Führt dieselben FR-EM-3-Konfliktprüfungen wie aus, ohne eine + /// Zuweisung anzulegen - für die Live-Vorschau im Anlegen-/Bearbeiten-Dialog. Liefert eine + /// leere Liste, wenn Auftrag/Mitarbeiter (noch) nicht existieren oder der Zeitraum ungültig ist + /// (diese Fälle werden im Formular bereits über Pflichtfelder/Min-Max abgefangen). + /// + Task> CheckConflictsAsync( + Guid orderId, + Guid employeeId, + DateOnly startDate, + DateOnly endDate, + Guid? excludeAssignmentId = null, + CancellationToken cancellationToken = default); + + Task UpdateAsync(Guid id, string? note, CancellationToken cancellationToken = default); + + Task DeleteAsync(Guid id, CancellationToken cancellationToken = default); + + Task> GetDeletedAsync(string? search = null, CancellationToken cancellationToken = default); + + Task RestoreAsync(Guid id, CancellationToken cancellationToken = default); + + Task SaveChangesAsync(CancellationToken cancellationToken = default); +} diff --git a/omsorgCore/src/OmsorgCore.Application/Services/IAssignmentValidationSettingsService.cs b/omsorgCore/src/OmsorgCore.Application/Services/IAssignmentValidationSettingsService.cs new file mode 100644 index 0000000..6e3050e --- /dev/null +++ b/omsorgCore/src/OmsorgCore.Application/Services/IAssignmentValidationSettingsService.cs @@ -0,0 +1,17 @@ +using OmsorgCore.Domain.Entities; +using OmsorgCore.Domain.Enums; + +namespace OmsorgCore.Application.Services; + +public interface IAssignmentValidationSettingsService +{ + Task GetAsync(CancellationToken cancellationToken = default); + + Task UpdateAsync( + ValidationSeverity qualificationMode, + ValidationSeverity absenceMode, + ValidationSeverity workingHoursMode, + ValidationSeverity overlapMode, + ValidationSeverity contractMode, + CancellationToken cancellationToken = default); +} diff --git a/omsorgCore/src/OmsorgCore.Domain/Entities/Assignment.cs b/omsorgCore/src/OmsorgCore.Domain/Entities/Assignment.cs new file mode 100644 index 0000000..21d1ff8 --- /dev/null +++ b/omsorgCore/src/OmsorgCore.Domain/Entities/Assignment.cs @@ -0,0 +1,16 @@ +namespace OmsorgCore.Domain.Entities; + +using OmsorgCore.Domain.Common; + +public class Assignment : AuditableEntity +{ + public Guid OrderId { get; set; } + public Order Order { get; set; } = null!; + + public Guid EmployeeId { get; set; } + public Employee Employee { get; set; } = null!; + + public DateOnly StartDate { get; set; } + public DateOnly EndDate { get; set; } + public string? Note { get; set; } +} diff --git a/omsorgCore/src/OmsorgCore.Domain/Entities/AssignmentValidationSettings.cs b/omsorgCore/src/OmsorgCore.Domain/Entities/AssignmentValidationSettings.cs new file mode 100644 index 0000000..5b9cde4 --- /dev/null +++ b/omsorgCore/src/OmsorgCore.Domain/Entities/AssignmentValidationSettings.cs @@ -0,0 +1,19 @@ +using OmsorgCore.Domain.Common; +using OmsorgCore.Domain.Enums; + +namespace OmsorgCore.Domain.Entities; + +/// +/// Systemweite, zur Laufzeit änderbare Konfiguration der FR-EM-3-Konfliktprüfungen bei der +/// Mitarbeiterzuweisung (). Genau eine Zeile (Singleton) — +/// +/// legt sie bei Bedarf mit den hier hinterlegten Defaults an. +/// +public class AssignmentValidationSettings : Entity +{ + public ValidationSeverity QualificationMode { get; set; } = ValidationSeverity.Error; + public ValidationSeverity AbsenceMode { get; set; } = ValidationSeverity.Error; + public ValidationSeverity WorkingHoursMode { get; set; } = ValidationSeverity.Warning; + public ValidationSeverity OverlapMode { get; set; } = ValidationSeverity.Error; + public ValidationSeverity ContractMode { get; set; } = ValidationSeverity.Error; +} diff --git a/omsorgCore/src/OmsorgCore.Domain/Entities/ValueListItem.cs b/omsorgCore/src/OmsorgCore.Domain/Entities/ValueListItem.cs index 8dc89de..2fcb3ef 100644 --- a/omsorgCore/src/OmsorgCore.Domain/Entities/ValueListItem.cs +++ b/omsorgCore/src/OmsorgCore.Domain/Entities/ValueListItem.cs @@ -23,4 +23,11 @@ public class ValueListItem : Entity public bool IsTerminal { get; set; } public bool TriggersFollowUp { get; set; } public bool IsEditableByOwner { get; set; } + + /// + /// Nur für "AbsenceStatus" relevant: markiert den Status-Wert (aktuell "Genehmigt"), der eine + /// Mitarbeiterzuweisung im überlappenden Zeitraum blockiert/warnt (FR-EM-3, Abwesenheitsprüfung). + /// Bei allen anderen Listen bleibt es false — analog zu /. + /// + public bool BlocksAssignment { get; set; } } diff --git a/omsorgCore/src/OmsorgCore.Domain/Enums/ModuleType.cs b/omsorgCore/src/OmsorgCore.Domain/Enums/ModuleType.cs index baa30bc..1b3b34a 100644 --- a/omsorgCore/src/OmsorgCore.Domain/Enums/ModuleType.cs +++ b/omsorgCore/src/OmsorgCore.Domain/Enums/ModuleType.cs @@ -19,5 +19,6 @@ public enum ModuleType Users, Configuration, Absences, - EmployeeFacilityDistances + EmployeeFacilityDistances, + Assignments } diff --git a/omsorgCore/src/OmsorgCore.Domain/Enums/ValidationSeverity.cs b/omsorgCore/src/OmsorgCore.Domain/Enums/ValidationSeverity.cs new file mode 100644 index 0000000..322ec76 --- /dev/null +++ b/omsorgCore/src/OmsorgCore.Domain/Enums/ValidationSeverity.cs @@ -0,0 +1,11 @@ +namespace OmsorgCore.Domain.Enums; + +/// +/// Steuert, ob eine Zuweisungs-Konfliktprüfung (FR-EM-3) die Zuweisung blockiert () +/// oder nur als Hinweis mitgegeben wird, ohne sie zu verhindern (). +/// +public enum ValidationSeverity +{ + Warning, + Error +} diff --git a/omsorgCore/src/OmsorgCore.Infrastructure/DependencyInjection.cs b/omsorgCore/src/OmsorgCore.Infrastructure/DependencyInjection.cs index 74e2449..14e02a9 100644 --- a/omsorgCore/src/OmsorgCore.Infrastructure/DependencyInjection.cs +++ b/omsorgCore/src/OmsorgCore.Infrastructure/DependencyInjection.cs @@ -38,7 +38,9 @@ public static class DependencyInjection services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); services.AddScoped(); + services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); diff --git a/omsorgCore/src/OmsorgCore.Infrastructure/Persistence/Configurations/AssignmentConfiguration.cs b/omsorgCore/src/OmsorgCore.Infrastructure/Persistence/Configurations/AssignmentConfiguration.cs new file mode 100644 index 0000000..0912818 --- /dev/null +++ b/omsorgCore/src/OmsorgCore.Infrastructure/Persistence/Configurations/AssignmentConfiguration.cs @@ -0,0 +1,18 @@ +namespace OmsorgCore.Infrastructure.Persistence.Configurations; + +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using OmsorgCore.Domain.Entities; + +public class AssignmentConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("assignments"); + builder.HasKey(a => a.Id); + builder.HasOne(a => a.Order).WithMany().HasForeignKey(a => a.OrderId).OnDelete(DeleteBehavior.Restrict); + builder.HasOne(a => a.Employee).WithMany().HasForeignKey(a => a.EmployeeId).OnDelete(DeleteBehavior.Restrict); + builder.Property(a => a.Note).HasMaxLength(500); + builder.HasQueryFilter(a => !a.IsDeleted); + } +} diff --git a/omsorgCore/src/OmsorgCore.Infrastructure/Persistence/Configurations/AssignmentValidationSettingsConfiguration.cs b/omsorgCore/src/OmsorgCore.Infrastructure/Persistence/Configurations/AssignmentValidationSettingsConfiguration.cs new file mode 100644 index 0000000..5f62d6f --- /dev/null +++ b/omsorgCore/src/OmsorgCore.Infrastructure/Persistence/Configurations/AssignmentValidationSettingsConfiguration.cs @@ -0,0 +1,14 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using OmsorgCore.Domain.Entities; + +namespace OmsorgCore.Infrastructure.Persistence.Configurations; + +public class AssignmentValidationSettingsConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("assignment_validation_settings"); + builder.HasKey(s => s.Id); + } +} diff --git a/omsorgCore/src/OmsorgCore.Infrastructure/Persistence/DbSeeder.cs b/omsorgCore/src/OmsorgCore.Infrastructure/Persistence/DbSeeder.cs index f808002..41d023c 100644 --- a/omsorgCore/src/OmsorgCore.Infrastructure/Persistence/DbSeeder.cs +++ b/omsorgCore/src/OmsorgCore.Infrastructure/Persistence/DbSeeder.cs @@ -88,6 +88,7 @@ public static class DbSeeder (ModuleType.Facilities, AllActions, PermissionScope.All), (ModuleType.Contracts, AllActions, PermissionScope.All), (ModuleType.Orders, AllActions, PermissionScope.All), + (ModuleType.Assignments, AllActions, PermissionScope.All), (ModuleType.TimeEntries, AllActions, PermissionScope.All), (ModuleType.Invoices, new[] { PermissionAction.View, PermissionAction.Create, PermissionAction.Approve }, PermissionScope.All), (ModuleType.Recruiting, new[] { PermissionAction.View, PermissionAction.Create, PermissionAction.Edit }, PermissionScope.All), @@ -107,6 +108,7 @@ public static class DbSeeder { (ModuleType.Employees, new[] { PermissionAction.View }, PermissionScope.Own), (ModuleType.Contracts, new[] { PermissionAction.View }, PermissionScope.Own), + (ModuleType.Assignments, new[] { PermissionAction.View }, PermissionScope.Own), (ModuleType.Absences, new[] { PermissionAction.Create, PermissionAction.View, PermissionAction.Edit }, PermissionScope.Own), (ModuleType.TimeEntries, new[] { PermissionAction.Create, PermissionAction.View, PermissionAction.Edit }, PermissionScope.Own), (ModuleType.EmployeeFacilityDistances, new[] { PermissionAction.Create, PermissionAction.View, PermissionAction.Edit }, PermissionScope.Own) @@ -204,6 +206,7 @@ public static class DbSeeder await SeedSimpleListIfMissingAsync(db, "AbsenceStatus", "Antragsstatus", new (string Value, bool IsDefault)[] { ("Eingereicht", true), ("Genehmigt", false), ("Abgelehnt", false) }, cancellationToken); await SeedAbsenceStatusInitialFlagIfMissingAsync(db, cancellationToken); + await SeedAbsenceStatusBlocksAssignmentFlagIfMissingAsync(db, cancellationToken); await SeedOrderStatusListIfMissingAsync(db, cancellationToken); await SeedCrmStatusTransitionsIfMissingAsync(db, cancellationToken); @@ -439,6 +442,29 @@ public static class DbSeeder item.IsInitial = true; await context.SaveChangesAsync(ct); } + + // "Genehmigt" ist der einzige AbsenceStatus-Wert, der eine Mitarbeiterzuweisung im + // überlappenden Zeitraum blockiert/warnt (FR-EM-3, AssignmentService.CreateAsync liest + // darüber statt den Anzeigetext hartzukodieren, siehe BlocksAssignment auf ValueListItem). + // Idempotent wie SeedAbsenceStatusInitialFlagIfMissingAsync - läuft nicht erneut, sobald + // irgendein Item der Liste bereits BlocksAssignment trägt. + async Task SeedAbsenceStatusBlocksAssignmentFlagIfMissingAsync(OmsorgCoreDbContext context, CancellationToken ct) + { + if (await context.ValueListItems.AnyAsync(i => i.ValueList.Key == "AbsenceStatus" && i.BlocksAssignment, ct)) + { + return; + } + + var item = await context.ValueListItems + .FirstOrDefaultAsync(i => i.ValueList.Key == "AbsenceStatus" && i.Value == "Genehmigt", ct); + if (item is null) + { + return; + } + + item.BlocksAssignment = true; + await context.SaveChangesAsync(ct); + } } private static async Task SeedRoleIfMissingAsync( diff --git a/omsorgCore/src/OmsorgCore.Infrastructure/Persistence/Migrations/20260810212337_AddAssignmentEntity.Designer.cs b/omsorgCore/src/OmsorgCore.Infrastructure/Persistence/Migrations/20260810212337_AddAssignmentEntity.Designer.cs new file mode 100644 index 0000000..6e79129 --- /dev/null +++ b/omsorgCore/src/OmsorgCore.Infrastructure/Persistence/Migrations/20260810212337_AddAssignmentEntity.Designer.cs @@ -0,0 +1,1453 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using OmsorgCore.Infrastructure.Persistence; + +#nullable disable + +namespace OmsorgCore.Infrastructure.Persistence.Migrations +{ + [DbContext(typeof(OmsorgCoreDbContext))] + [Migration("20260810212337_AddAssignmentEntity")] + partial class AddAssignmentEntity + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.10") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.Absence", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AdminNote") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("EmployeeId") + .HasColumnType("uuid"); + + b.Property("EndDate") + .HasColumnType("date"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("Note") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("Reason") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("StartDate") + .HasColumnType("date"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Substitute") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("EmployeeId"); + + b.ToTable("absences", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.Assignment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("EmployeeId") + .HasColumnType("uuid"); + + b.Property("EndDate") + .HasColumnType("date"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("Note") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("OrderId") + .HasColumnType("uuid"); + + b.Property("StartDate") + .HasColumnType("date"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("EmployeeId"); + + b.HasIndex("OrderId"); + + b.ToTable("assignments", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.AuditLogEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Action") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("ActorUserId") + .HasColumnType("uuid"); + + b.Property("ActorUsername") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Category") + .HasColumnType("integer"); + + b.Property("Details") + .HasColumnType("jsonb"); + + b.Property("EntityId") + .HasColumnType("uuid"); + + b.Property("EntityType") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("IpAddress") + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("OccurredAtUtc") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("ActorUserId"); + + b.HasIndex("OccurredAtUtc"); + + b.HasIndex("EntityType", "EntityId"); + + b.ToTable("audit_log_entries", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.Contract", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AllowancesDescription") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("ContractType") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("EmployeeId") + .HasColumnType("uuid"); + + b.Property("EndDate") + .HasColumnType("date"); + + b.Property("FacilityId") + .HasColumnType("uuid"); + + b.Property("HourlyWage") + .HasPrecision(10, 2) + .HasColumnType("numeric(10,2)"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("OvertimeRules") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("ProbationPeriodMonths") + .HasColumnType("integer"); + + b.Property("StartDate") + .HasColumnType("date"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("VacationDaysPerYear") + .HasColumnType("integer"); + + b.Property("WeeklyHours") + .HasPrecision(10, 2) + .HasColumnType("numeric(10,2)"); + + b.HasKey("Id"); + + b.HasIndex("EmployeeId"); + + b.HasIndex("FacilityId"); + + b.ToTable("contracts", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.Document", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Category") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("ContentType") + .IsRequired() + .HasMaxLength(150) + .HasColumnType("character varying(150)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("EntityId") + .HasColumnType("uuid"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(260) + .HasColumnType("character varying(260)"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("SizeBytes") + .HasColumnType("bigint"); + + b.Property("StorageKey") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UploadedByUserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UploadedByUserId"); + + b.HasIndex("EntityType", "EntityId"); + + b.ToTable("documents", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.Employee", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AvatarFileName") + .HasColumnType("text"); + + b.Property("City") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Country") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DateOfBirth") + .HasColumnType("date"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Email") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("EmergencyContactName") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("EmergencyContactPhone") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("EmergencyContactRelation") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("EmploymentType") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("EntryDate") + .HasColumnType("date"); + + b.Property("ExitDate") + .HasColumnType("date"); + + b.Property("FirstName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("LastName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("PhoneNumber") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("PostalCode") + .HasMaxLength(10) + .HasColumnType("character varying(10)"); + + b.Property("Qualification") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Street") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("employees", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.EmployeeFacilityDistance", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DistanceKm") + .HasColumnType("decimal(10,2)"); + + b.Property("EmployeeId") + .HasColumnType("uuid"); + + b.Property("FacilityId") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("EmployeeId"); + + b.HasIndex("FacilityId"); + + b.ToTable("employee_facility_distances", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.Facility", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("BillingCity") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("BillingCountry") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("BillingInterval") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("BillingPostalCode") + .HasMaxLength(10) + .HasColumnType("character varying(10)"); + + b.Property("BillingRate") + .HasColumnType("decimal(10,2)"); + + b.Property("BillingStreet") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("City") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Country") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("CrmStatus") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("FacilityType") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("FollowUpDueDate") + .HasColumnType("timestamp with time zone"); + + b.Property("HolidaySurchargePercent") + .HasColumnType("decimal(5,2)"); + + b.Property("IndividualAgreements") + .HasMaxLength(2000) + .HasColumnType("character varying(2000)"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("MealAllowanceRate") + .HasColumnType("decimal(10,2)"); + + b.Property("MinimumHours") + .HasColumnType("decimal(5,2)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(300) + .HasColumnType("character varying(300)"); + + b.Property("NightSurchargePercent") + .HasColumnType("decimal(5,2)"); + + b.Property("PaymentTermDays") + .HasColumnType("integer"); + + b.Property("PostalCode") + .HasMaxLength(10) + .HasColumnType("character varying(10)"); + + b.Property("SaturdaySurchargePercent") + .HasColumnType("decimal(5,2)"); + + b.Property("Street") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("SundaySurchargePercent") + .HasColumnType("decimal(5,2)"); + + b.Property("TravelCostMode") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("TravelCostPerKm") + .HasColumnType("decimal(10,2)"); + + b.Property("TravelCostRate") + .HasColumnType("decimal(10,2)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Website") + .HasMaxLength(300) + .HasColumnType("character varying(300)"); + + b.HasKey("Id"); + + b.ToTable("facilities", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.FacilityContact", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Department") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Email") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("FacilityId") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("Notes") + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("PhoneNumber") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Role") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("FacilityId"); + + b.ToTable("facility_contacts", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.FacilityQualificationRate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("FacilityId") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("Qualification") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("Rate") + .HasColumnType("decimal(10,2)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("FacilityId"); + + b.ToTable("facility_qualification_rates", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.Invoice", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("BillingPeriodEnd") + .HasColumnType("date"); + + b.Property("BillingPeriodStart") + .HasColumnType("date"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DueDate") + .HasColumnType("date"); + + b.Property("FacilityId") + .HasColumnType("uuid"); + + b.Property("GrossAmount") + .HasColumnType("numeric(12,2)"); + + b.Property("InvoiceNumber") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("NetAmount") + .HasColumnType("numeric(12,2)"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("FacilityId"); + + b.HasIndex("InvoiceNumber") + .IsUnique(); + + b.ToTable("invoices", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.LoginAttempt", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AttemptedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("IpAddress") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("Succeeded") + .HasColumnType("boolean"); + + b.Property("Username") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.HasIndex("IpAddress", "AttemptedAt"); + + b.ToTable("login_attempts", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Conditions") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("EndDate") + .HasColumnType("date"); + + b.Property("FacilityContactId") + .HasColumnType("uuid"); + + b.Property("FacilityId") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("Priority") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("RequiredHeadcount") + .HasColumnType("integer"); + + b.Property("RequiredQualification") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("ShiftType") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("StartDate") + .HasColumnType("date"); + + b.Property("StatusId") + .HasColumnType("uuid"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("FacilityContactId"); + + b.HasIndex("FacilityId"); + + b.HasIndex("StatusId"); + + b.ToTable("orders", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.PasswordResetCode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AttemptCount") + .HasColumnType("integer"); + + b.Property("CodeHash") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("ConsumedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ExpiresAt") + .HasColumnType("timestamp with time zone"); + + b.Property("InvalidatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ResetTokenExpiresAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ResetTokenHash") + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("ResetTokenUsedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ResetTokenHash"); + + b.HasIndex("UserId"); + + b.ToTable("password_reset_codes", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.RefreshToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ExpiresAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ReplacedByTokenId") + .HasColumnType("uuid"); + + b.Property("RevokedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("TokenHash") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ReplacedByTokenId"); + + b.HasIndex("TokenHash") + .IsUnique(); + + b.HasIndex("UserId"); + + b.ToTable("refresh_tokens", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("roles", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.RolePermission", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Action") + .HasColumnType("integer"); + + b.Property("Module") + .HasColumnType("integer"); + + b.Property("RoleId") + .HasColumnType("uuid"); + + b.Property("Scope") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("RoleId", "Module", "Action") + .IsUnique(); + + b.ToTable("role_permissions", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.TimeEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AdminNote") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("BreakDuration") + .HasColumnType("interval"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Date") + .HasColumnType("date"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("EmployeeId") + .HasColumnType("uuid"); + + b.Property("End") + .HasColumnType("time without time zone"); + + b.Property("HolidayHours") + .HasColumnType("numeric(6,2)"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("NightHours") + .HasColumnType("numeric(6,2)"); + + b.Property("OrderId") + .HasColumnType("uuid"); + + b.Property("SaturdayHours") + .HasColumnType("numeric(6,2)"); + + b.Property("Start") + .HasColumnType("time without time zone"); + + b.Property("StatusId") + .HasColumnType("uuid"); + + b.Property("SundayHours") + .HasColumnType("numeric(6,2)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("EmployeeId"); + + b.HasIndex("OrderId"); + + b.HasIndex("StatusId"); + + b.ToTable("time_entries", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("EmployeeId") + .HasColumnType("uuid"); + + b.Property("IsActive") + .HasColumnType("boolean"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("MustChangePassword") + .HasColumnType("boolean"); + + b.Property("PasswordHash") + .IsRequired() + .HasColumnType("text"); + + b.Property("RoleId") + .HasColumnType("uuid"); + + b.Property("SecurityStamp") + .HasColumnType("uuid"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Username") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.HasIndex("EmployeeId"); + + b.HasIndex("RoleId"); + + b.HasIndex("Username") + .IsUnique(); + + b.ToTable("users", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.UserPermissionOverride", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Action") + .HasColumnType("integer"); + + b.Property("Effect") + .HasColumnType("integer"); + + b.Property("Module") + .HasColumnType("integer"); + + b.Property("Scope") + .HasColumnType("integer"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId", "Module", "Action") + .IsUnique(); + + b.ToTable("user_permission_overrides", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.ValueList", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Key") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("Key") + .IsUnique(); + + b.ToTable("value_lists", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.ValueListItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("IsDefault") + .HasColumnType("boolean"); + + b.Property("IsEditableByOwner") + .HasColumnType("boolean"); + + b.Property("IsInitial") + .HasColumnType("boolean"); + + b.Property("IsTerminal") + .HasColumnType("boolean"); + + b.Property("SortOrder") + .HasColumnType("integer"); + + b.Property("TriggersFollowUp") + .HasColumnType("boolean"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("ValueListId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ValueListId", "Value") + .IsUnique(); + + b.ToTable("value_list_items", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.ValueListItemTransition", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("FromItemId") + .HasColumnType("uuid"); + + b.Property("RequiresApproval") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(true); + + b.Property("ToItemId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ToItemId"); + + b.HasIndex("FromItemId", "ToItemId") + .IsUnique(); + + b.ToTable("value_list_item_transitions", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.Absence", b => + { + b.HasOne("OmsorgCore.Domain.Entities.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Employee"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.Assignment", b => + { + b.HasOne("OmsorgCore.Domain.Entities.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("OmsorgCore.Domain.Entities.Order", "Order") + .WithMany() + .HasForeignKey("OrderId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Employee"); + + b.Navigation("Order"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.Contract", b => + { + b.HasOne("OmsorgCore.Domain.Entities.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("OmsorgCore.Domain.Entities.Facility", "Facility") + .WithMany() + .HasForeignKey("FacilityId") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("Employee"); + + b.Navigation("Facility"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.Document", b => + { + b.HasOne("OmsorgCore.Domain.Entities.User", "UploadedByUser") + .WithMany() + .HasForeignKey("UploadedByUserId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("UploadedByUser"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.EmployeeFacilityDistance", b => + { + b.HasOne("OmsorgCore.Domain.Entities.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("OmsorgCore.Domain.Entities.Facility", "Facility") + .WithMany() + .HasForeignKey("FacilityId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Employee"); + + b.Navigation("Facility"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.FacilityContact", b => + { + b.HasOne("OmsorgCore.Domain.Entities.Facility", "Facility") + .WithMany() + .HasForeignKey("FacilityId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Facility"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.FacilityQualificationRate", b => + { + b.HasOne("OmsorgCore.Domain.Entities.Facility", "Facility") + .WithMany() + .HasForeignKey("FacilityId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Facility"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.Invoice", b => + { + b.HasOne("OmsorgCore.Domain.Entities.Facility", "Facility") + .WithMany() + .HasForeignKey("FacilityId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Facility"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.Order", b => + { + b.HasOne("OmsorgCore.Domain.Entities.FacilityContact", "FacilityContact") + .WithMany() + .HasForeignKey("FacilityContactId") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("OmsorgCore.Domain.Entities.Facility", "Facility") + .WithMany() + .HasForeignKey("FacilityId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("OmsorgCore.Domain.Entities.ValueListItem", "Status") + .WithMany() + .HasForeignKey("StatusId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Facility"); + + b.Navigation("FacilityContact"); + + b.Navigation("Status"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.PasswordResetCode", b => + { + b.HasOne("OmsorgCore.Domain.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.RefreshToken", b => + { + b.HasOne("OmsorgCore.Domain.Entities.RefreshToken", null) + .WithMany() + .HasForeignKey("ReplacedByTokenId") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("OmsorgCore.Domain.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.RolePermission", b => + { + b.HasOne("OmsorgCore.Domain.Entities.Role", "Role") + .WithMany("RolePermissions") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.TimeEntry", b => + { + b.HasOne("OmsorgCore.Domain.Entities.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("OmsorgCore.Domain.Entities.Order", "Order") + .WithMany() + .HasForeignKey("OrderId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("OmsorgCore.Domain.Entities.ValueListItem", "Status") + .WithMany() + .HasForeignKey("StatusId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Employee"); + + b.Navigation("Order"); + + b.Navigation("Status"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.User", b => + { + b.HasOne("OmsorgCore.Domain.Entities.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("OmsorgCore.Domain.Entities.Role", "Role") + .WithMany("Users") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Employee"); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.UserPermissionOverride", b => + { + b.HasOne("OmsorgCore.Domain.Entities.User", "User") + .WithMany("PermissionOverrides") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.ValueListItem", b => + { + b.HasOne("OmsorgCore.Domain.Entities.ValueList", "ValueList") + .WithMany("Items") + .HasForeignKey("ValueListId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("ValueList"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.ValueListItemTransition", b => + { + b.HasOne("OmsorgCore.Domain.Entities.ValueListItem", "FromItem") + .WithMany() + .HasForeignKey("FromItemId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("OmsorgCore.Domain.Entities.ValueListItem", "ToItem") + .WithMany() + .HasForeignKey("ToItemId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("FromItem"); + + b.Navigation("ToItem"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.Role", b => + { + b.Navigation("RolePermissions"); + + b.Navigation("Users"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.User", b => + { + b.Navigation("PermissionOverrides"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.ValueList", b => + { + b.Navigation("Items"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/omsorgCore/src/OmsorgCore.Infrastructure/Persistence/Migrations/20260810212337_AddAssignmentEntity.cs b/omsorgCore/src/OmsorgCore.Infrastructure/Persistence/Migrations/20260810212337_AddAssignmentEntity.cs new file mode 100644 index 0000000..55b83f7 --- /dev/null +++ b/omsorgCore/src/OmsorgCore.Infrastructure/Persistence/Migrations/20260810212337_AddAssignmentEntity.cs @@ -0,0 +1,64 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace OmsorgCore.Infrastructure.Persistence.Migrations +{ + /// + public partial class AddAssignmentEntity : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "assignments", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + OrderId = table.Column(type: "uuid", nullable: false), + EmployeeId = table.Column(type: "uuid", nullable: false), + StartDate = table.Column(type: "date", nullable: false), + EndDate = table.Column(type: "date", nullable: false), + Note = table.Column(type: "character varying(500)", maxLength: 500, nullable: true), + CreatedAt = table.Column(type: "timestamp with time zone", nullable: false), + UpdatedAt = table.Column(type: "timestamp with time zone", nullable: true), + IsDeleted = table.Column(type: "boolean", nullable: false), + DeletedAt = table.Column(type: "timestamp with time zone", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_assignments", x => x.Id); + table.ForeignKey( + name: "FK_assignments_employees_EmployeeId", + column: x => x.EmployeeId, + principalTable: "employees", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_assignments_orders_OrderId", + column: x => x.OrderId, + principalTable: "orders", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateIndex( + name: "IX_assignments_EmployeeId", + table: "assignments", + column: "EmployeeId"); + + migrationBuilder.CreateIndex( + name: "IX_assignments_OrderId", + table: "assignments", + column: "OrderId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "assignments"); + } + } +} diff --git a/omsorgCore/src/OmsorgCore.Infrastructure/Persistence/Migrations/20260810220955_AddAssignmentValidationSettingsAndBlocksAssignmentFlag.Designer.cs b/omsorgCore/src/OmsorgCore.Infrastructure/Persistence/Migrations/20260810220955_AddAssignmentValidationSettingsAndBlocksAssignmentFlag.Designer.cs new file mode 100644 index 0000000..7b34257 --- /dev/null +++ b/omsorgCore/src/OmsorgCore.Infrastructure/Persistence/Migrations/20260810220955_AddAssignmentValidationSettingsAndBlocksAssignmentFlag.Designer.cs @@ -0,0 +1,1482 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using OmsorgCore.Infrastructure.Persistence; + +#nullable disable + +namespace OmsorgCore.Infrastructure.Persistence.Migrations +{ + [DbContext(typeof(OmsorgCoreDbContext))] + [Migration("20260810220955_AddAssignmentValidationSettingsAndBlocksAssignmentFlag")] + partial class AddAssignmentValidationSettingsAndBlocksAssignmentFlag + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.10") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.Absence", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AdminNote") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("EmployeeId") + .HasColumnType("uuid"); + + b.Property("EndDate") + .HasColumnType("date"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("Note") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("Reason") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("StartDate") + .HasColumnType("date"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Substitute") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("EmployeeId"); + + b.ToTable("absences", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.Assignment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("EmployeeId") + .HasColumnType("uuid"); + + b.Property("EndDate") + .HasColumnType("date"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("Note") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("OrderId") + .HasColumnType("uuid"); + + b.Property("StartDate") + .HasColumnType("date"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("EmployeeId"); + + b.HasIndex("OrderId"); + + b.ToTable("assignments", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.AssignmentValidationSettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AbsenceMode") + .HasColumnType("integer"); + + b.Property("ContractMode") + .HasColumnType("integer"); + + b.Property("OverlapMode") + .HasColumnType("integer"); + + b.Property("QualificationMode") + .HasColumnType("integer"); + + b.Property("WorkingHoursMode") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("assignment_validation_settings", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.AuditLogEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Action") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("ActorUserId") + .HasColumnType("uuid"); + + b.Property("ActorUsername") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Category") + .HasColumnType("integer"); + + b.Property("Details") + .HasColumnType("jsonb"); + + b.Property("EntityId") + .HasColumnType("uuid"); + + b.Property("EntityType") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("IpAddress") + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("OccurredAtUtc") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("ActorUserId"); + + b.HasIndex("OccurredAtUtc"); + + b.HasIndex("EntityType", "EntityId"); + + b.ToTable("audit_log_entries", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.Contract", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AllowancesDescription") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("ContractType") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("EmployeeId") + .HasColumnType("uuid"); + + b.Property("EndDate") + .HasColumnType("date"); + + b.Property("FacilityId") + .HasColumnType("uuid"); + + b.Property("HourlyWage") + .HasPrecision(10, 2) + .HasColumnType("numeric(10,2)"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("OvertimeRules") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("ProbationPeriodMonths") + .HasColumnType("integer"); + + b.Property("StartDate") + .HasColumnType("date"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("VacationDaysPerYear") + .HasColumnType("integer"); + + b.Property("WeeklyHours") + .HasPrecision(10, 2) + .HasColumnType("numeric(10,2)"); + + b.HasKey("Id"); + + b.HasIndex("EmployeeId"); + + b.HasIndex("FacilityId"); + + b.ToTable("contracts", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.Document", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Category") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("ContentType") + .IsRequired() + .HasMaxLength(150) + .HasColumnType("character varying(150)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("EntityId") + .HasColumnType("uuid"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(260) + .HasColumnType("character varying(260)"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("SizeBytes") + .HasColumnType("bigint"); + + b.Property("StorageKey") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UploadedByUserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UploadedByUserId"); + + b.HasIndex("EntityType", "EntityId"); + + b.ToTable("documents", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.Employee", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AvatarFileName") + .HasColumnType("text"); + + b.Property("City") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Country") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DateOfBirth") + .HasColumnType("date"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Email") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("EmergencyContactName") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("EmergencyContactPhone") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("EmergencyContactRelation") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("EmploymentType") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("EntryDate") + .HasColumnType("date"); + + b.Property("ExitDate") + .HasColumnType("date"); + + b.Property("FirstName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("LastName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("PhoneNumber") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("PostalCode") + .HasMaxLength(10) + .HasColumnType("character varying(10)"); + + b.Property("Qualification") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Street") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("employees", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.EmployeeFacilityDistance", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DistanceKm") + .HasColumnType("decimal(10,2)"); + + b.Property("EmployeeId") + .HasColumnType("uuid"); + + b.Property("FacilityId") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("EmployeeId"); + + b.HasIndex("FacilityId"); + + b.ToTable("employee_facility_distances", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.Facility", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("BillingCity") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("BillingCountry") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("BillingInterval") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("BillingPostalCode") + .HasMaxLength(10) + .HasColumnType("character varying(10)"); + + b.Property("BillingRate") + .HasColumnType("decimal(10,2)"); + + b.Property("BillingStreet") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("City") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Country") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("CrmStatus") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("FacilityType") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("FollowUpDueDate") + .HasColumnType("timestamp with time zone"); + + b.Property("HolidaySurchargePercent") + .HasColumnType("decimal(5,2)"); + + b.Property("IndividualAgreements") + .HasMaxLength(2000) + .HasColumnType("character varying(2000)"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("MealAllowanceRate") + .HasColumnType("decimal(10,2)"); + + b.Property("MinimumHours") + .HasColumnType("decimal(5,2)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(300) + .HasColumnType("character varying(300)"); + + b.Property("NightSurchargePercent") + .HasColumnType("decimal(5,2)"); + + b.Property("PaymentTermDays") + .HasColumnType("integer"); + + b.Property("PostalCode") + .HasMaxLength(10) + .HasColumnType("character varying(10)"); + + b.Property("SaturdaySurchargePercent") + .HasColumnType("decimal(5,2)"); + + b.Property("Street") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("SundaySurchargePercent") + .HasColumnType("decimal(5,2)"); + + b.Property("TravelCostMode") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("TravelCostPerKm") + .HasColumnType("decimal(10,2)"); + + b.Property("TravelCostRate") + .HasColumnType("decimal(10,2)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Website") + .HasMaxLength(300) + .HasColumnType("character varying(300)"); + + b.HasKey("Id"); + + b.ToTable("facilities", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.FacilityContact", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Department") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Email") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("FacilityId") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("Notes") + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("PhoneNumber") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Role") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("FacilityId"); + + b.ToTable("facility_contacts", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.FacilityQualificationRate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("FacilityId") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("Qualification") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("Rate") + .HasColumnType("decimal(10,2)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("FacilityId"); + + b.ToTable("facility_qualification_rates", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.Invoice", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("BillingPeriodEnd") + .HasColumnType("date"); + + b.Property("BillingPeriodStart") + .HasColumnType("date"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DueDate") + .HasColumnType("date"); + + b.Property("FacilityId") + .HasColumnType("uuid"); + + b.Property("GrossAmount") + .HasColumnType("numeric(12,2)"); + + b.Property("InvoiceNumber") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("NetAmount") + .HasColumnType("numeric(12,2)"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("FacilityId"); + + b.HasIndex("InvoiceNumber") + .IsUnique(); + + b.ToTable("invoices", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.LoginAttempt", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AttemptedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("IpAddress") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("Succeeded") + .HasColumnType("boolean"); + + b.Property("Username") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.HasIndex("IpAddress", "AttemptedAt"); + + b.ToTable("login_attempts", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Conditions") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("EndDate") + .HasColumnType("date"); + + b.Property("FacilityContactId") + .HasColumnType("uuid"); + + b.Property("FacilityId") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("Priority") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("RequiredHeadcount") + .HasColumnType("integer"); + + b.Property("RequiredQualification") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("ShiftType") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("StartDate") + .HasColumnType("date"); + + b.Property("StatusId") + .HasColumnType("uuid"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("FacilityContactId"); + + b.HasIndex("FacilityId"); + + b.HasIndex("StatusId"); + + b.ToTable("orders", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.PasswordResetCode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AttemptCount") + .HasColumnType("integer"); + + b.Property("CodeHash") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("ConsumedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ExpiresAt") + .HasColumnType("timestamp with time zone"); + + b.Property("InvalidatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ResetTokenExpiresAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ResetTokenHash") + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("ResetTokenUsedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ResetTokenHash"); + + b.HasIndex("UserId"); + + b.ToTable("password_reset_codes", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.RefreshToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ExpiresAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ReplacedByTokenId") + .HasColumnType("uuid"); + + b.Property("RevokedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("TokenHash") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ReplacedByTokenId"); + + b.HasIndex("TokenHash") + .IsUnique(); + + b.HasIndex("UserId"); + + b.ToTable("refresh_tokens", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("roles", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.RolePermission", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Action") + .HasColumnType("integer"); + + b.Property("Module") + .HasColumnType("integer"); + + b.Property("RoleId") + .HasColumnType("uuid"); + + b.Property("Scope") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("RoleId", "Module", "Action") + .IsUnique(); + + b.ToTable("role_permissions", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.TimeEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AdminNote") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("BreakDuration") + .HasColumnType("interval"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Date") + .HasColumnType("date"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("EmployeeId") + .HasColumnType("uuid"); + + b.Property("End") + .HasColumnType("time without time zone"); + + b.Property("HolidayHours") + .HasColumnType("numeric(6,2)"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("NightHours") + .HasColumnType("numeric(6,2)"); + + b.Property("OrderId") + .HasColumnType("uuid"); + + b.Property("SaturdayHours") + .HasColumnType("numeric(6,2)"); + + b.Property("Start") + .HasColumnType("time without time zone"); + + b.Property("StatusId") + .HasColumnType("uuid"); + + b.Property("SundayHours") + .HasColumnType("numeric(6,2)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("EmployeeId"); + + b.HasIndex("OrderId"); + + b.HasIndex("StatusId"); + + b.ToTable("time_entries", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("EmployeeId") + .HasColumnType("uuid"); + + b.Property("IsActive") + .HasColumnType("boolean"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("MustChangePassword") + .HasColumnType("boolean"); + + b.Property("PasswordHash") + .IsRequired() + .HasColumnType("text"); + + b.Property("RoleId") + .HasColumnType("uuid"); + + b.Property("SecurityStamp") + .HasColumnType("uuid"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Username") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.HasIndex("EmployeeId"); + + b.HasIndex("RoleId"); + + b.HasIndex("Username") + .IsUnique(); + + b.ToTable("users", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.UserPermissionOverride", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Action") + .HasColumnType("integer"); + + b.Property("Effect") + .HasColumnType("integer"); + + b.Property("Module") + .HasColumnType("integer"); + + b.Property("Scope") + .HasColumnType("integer"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId", "Module", "Action") + .IsUnique(); + + b.ToTable("user_permission_overrides", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.ValueList", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Key") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("Key") + .IsUnique(); + + b.ToTable("value_lists", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.ValueListItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("BlocksAssignment") + .HasColumnType("boolean"); + + b.Property("IsDefault") + .HasColumnType("boolean"); + + b.Property("IsEditableByOwner") + .HasColumnType("boolean"); + + b.Property("IsInitial") + .HasColumnType("boolean"); + + b.Property("IsTerminal") + .HasColumnType("boolean"); + + b.Property("SortOrder") + .HasColumnType("integer"); + + b.Property("TriggersFollowUp") + .HasColumnType("boolean"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("ValueListId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ValueListId", "Value") + .IsUnique(); + + b.ToTable("value_list_items", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.ValueListItemTransition", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("FromItemId") + .HasColumnType("uuid"); + + b.Property("RequiresApproval") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(true); + + b.Property("ToItemId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ToItemId"); + + b.HasIndex("FromItemId", "ToItemId") + .IsUnique(); + + b.ToTable("value_list_item_transitions", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.Absence", b => + { + b.HasOne("OmsorgCore.Domain.Entities.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Employee"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.Assignment", b => + { + b.HasOne("OmsorgCore.Domain.Entities.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("OmsorgCore.Domain.Entities.Order", "Order") + .WithMany() + .HasForeignKey("OrderId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Employee"); + + b.Navigation("Order"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.Contract", b => + { + b.HasOne("OmsorgCore.Domain.Entities.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("OmsorgCore.Domain.Entities.Facility", "Facility") + .WithMany() + .HasForeignKey("FacilityId") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("Employee"); + + b.Navigation("Facility"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.Document", b => + { + b.HasOne("OmsorgCore.Domain.Entities.User", "UploadedByUser") + .WithMany() + .HasForeignKey("UploadedByUserId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("UploadedByUser"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.EmployeeFacilityDistance", b => + { + b.HasOne("OmsorgCore.Domain.Entities.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("OmsorgCore.Domain.Entities.Facility", "Facility") + .WithMany() + .HasForeignKey("FacilityId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Employee"); + + b.Navigation("Facility"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.FacilityContact", b => + { + b.HasOne("OmsorgCore.Domain.Entities.Facility", "Facility") + .WithMany() + .HasForeignKey("FacilityId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Facility"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.FacilityQualificationRate", b => + { + b.HasOne("OmsorgCore.Domain.Entities.Facility", "Facility") + .WithMany() + .HasForeignKey("FacilityId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Facility"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.Invoice", b => + { + b.HasOne("OmsorgCore.Domain.Entities.Facility", "Facility") + .WithMany() + .HasForeignKey("FacilityId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Facility"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.Order", b => + { + b.HasOne("OmsorgCore.Domain.Entities.FacilityContact", "FacilityContact") + .WithMany() + .HasForeignKey("FacilityContactId") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("OmsorgCore.Domain.Entities.Facility", "Facility") + .WithMany() + .HasForeignKey("FacilityId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("OmsorgCore.Domain.Entities.ValueListItem", "Status") + .WithMany() + .HasForeignKey("StatusId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Facility"); + + b.Navigation("FacilityContact"); + + b.Navigation("Status"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.PasswordResetCode", b => + { + b.HasOne("OmsorgCore.Domain.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.RefreshToken", b => + { + b.HasOne("OmsorgCore.Domain.Entities.RefreshToken", null) + .WithMany() + .HasForeignKey("ReplacedByTokenId") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("OmsorgCore.Domain.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.RolePermission", b => + { + b.HasOne("OmsorgCore.Domain.Entities.Role", "Role") + .WithMany("RolePermissions") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.TimeEntry", b => + { + b.HasOne("OmsorgCore.Domain.Entities.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("OmsorgCore.Domain.Entities.Order", "Order") + .WithMany() + .HasForeignKey("OrderId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("OmsorgCore.Domain.Entities.ValueListItem", "Status") + .WithMany() + .HasForeignKey("StatusId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Employee"); + + b.Navigation("Order"); + + b.Navigation("Status"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.User", b => + { + b.HasOne("OmsorgCore.Domain.Entities.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("OmsorgCore.Domain.Entities.Role", "Role") + .WithMany("Users") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Employee"); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.UserPermissionOverride", b => + { + b.HasOne("OmsorgCore.Domain.Entities.User", "User") + .WithMany("PermissionOverrides") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.ValueListItem", b => + { + b.HasOne("OmsorgCore.Domain.Entities.ValueList", "ValueList") + .WithMany("Items") + .HasForeignKey("ValueListId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("ValueList"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.ValueListItemTransition", b => + { + b.HasOne("OmsorgCore.Domain.Entities.ValueListItem", "FromItem") + .WithMany() + .HasForeignKey("FromItemId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("OmsorgCore.Domain.Entities.ValueListItem", "ToItem") + .WithMany() + .HasForeignKey("ToItemId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("FromItem"); + + b.Navigation("ToItem"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.Role", b => + { + b.Navigation("RolePermissions"); + + b.Navigation("Users"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.User", b => + { + b.Navigation("PermissionOverrides"); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.ValueList", b => + { + b.Navigation("Items"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/omsorgCore/src/OmsorgCore.Infrastructure/Persistence/Migrations/20260810220955_AddAssignmentValidationSettingsAndBlocksAssignmentFlag.cs b/omsorgCore/src/OmsorgCore.Infrastructure/Persistence/Migrations/20260810220955_AddAssignmentValidationSettingsAndBlocksAssignmentFlag.cs new file mode 100644 index 0000000..073f6ad --- /dev/null +++ b/omsorgCore/src/OmsorgCore.Infrastructure/Persistence/Migrations/20260810220955_AddAssignmentValidationSettingsAndBlocksAssignmentFlag.cs @@ -0,0 +1,49 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace OmsorgCore.Infrastructure.Persistence.Migrations +{ + /// + public partial class AddAssignmentValidationSettingsAndBlocksAssignmentFlag : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "BlocksAssignment", + table: "value_list_items", + type: "boolean", + nullable: false, + defaultValue: false); + + migrationBuilder.CreateTable( + name: "assignment_validation_settings", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + QualificationMode = table.Column(type: "integer", nullable: false), + AbsenceMode = table.Column(type: "integer", nullable: false), + WorkingHoursMode = table.Column(type: "integer", nullable: false), + OverlapMode = table.Column(type: "integer", nullable: false), + ContractMode = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_assignment_validation_settings", x => x.Id); + }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "assignment_validation_settings"); + + migrationBuilder.DropColumn( + name: "BlocksAssignment", + table: "value_list_items"); + } + } +} diff --git a/omsorgCore/src/OmsorgCore.Infrastructure/Persistence/Migrations/OmsorgCoreDbContextModelSnapshot.cs b/omsorgCore/src/OmsorgCore.Infrastructure/Persistence/Migrations/OmsorgCoreDbContextModelSnapshot.cs index 12c457f..c48efa0 100644 --- a/omsorgCore/src/OmsorgCore.Infrastructure/Persistence/Migrations/OmsorgCoreDbContextModelSnapshot.cs +++ b/omsorgCore/src/OmsorgCore.Infrastructure/Persistence/Migrations/OmsorgCoreDbContextModelSnapshot.cs @@ -82,6 +82,75 @@ namespace OmsorgCore.Infrastructure.Persistence.Migrations b.ToTable("absences", (string)null); }); + modelBuilder.Entity("OmsorgCore.Domain.Entities.Assignment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("EmployeeId") + .HasColumnType("uuid"); + + b.Property("EndDate") + .HasColumnType("date"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("Note") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("OrderId") + .HasColumnType("uuid"); + + b.Property("StartDate") + .HasColumnType("date"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("EmployeeId"); + + b.HasIndex("OrderId"); + + b.ToTable("assignments", (string)null); + }); + + modelBuilder.Entity("OmsorgCore.Domain.Entities.AssignmentValidationSettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AbsenceMode") + .HasColumnType("integer"); + + b.Property("ContractMode") + .HasColumnType("integer"); + + b.Property("OverlapMode") + .HasColumnType("integer"); + + b.Property("QualificationMode") + .HasColumnType("integer"); + + b.Property("WorkingHoursMode") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("assignment_validation_settings", (string)null); + }); + modelBuilder.Entity("OmsorgCore.Domain.Entities.AuditLogEntry", b => { b.Property("Id") @@ -1064,6 +1133,9 @@ namespace OmsorgCore.Infrastructure.Persistence.Migrations .ValueGeneratedOnAdd() .HasColumnType("uuid"); + b.Property("BlocksAssignment") + .HasColumnType("boolean"); + b.Property("IsDefault") .HasColumnType("boolean"); @@ -1136,6 +1208,25 @@ namespace OmsorgCore.Infrastructure.Persistence.Migrations b.Navigation("Employee"); }); + modelBuilder.Entity("OmsorgCore.Domain.Entities.Assignment", b => + { + b.HasOne("OmsorgCore.Domain.Entities.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("OmsorgCore.Domain.Entities.Order", "Order") + .WithMany() + .HasForeignKey("OrderId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Employee"); + + b.Navigation("Order"); + }); + modelBuilder.Entity("OmsorgCore.Domain.Entities.Contract", b => { b.HasOne("OmsorgCore.Domain.Entities.Employee", "Employee") diff --git a/omsorgCore/src/OmsorgCore.Infrastructure/Persistence/OmsorgCoreDbContext.cs b/omsorgCore/src/OmsorgCore.Infrastructure/Persistence/OmsorgCoreDbContext.cs index cefbf04..7e7d404 100644 --- a/omsorgCore/src/OmsorgCore.Infrastructure/Persistence/OmsorgCoreDbContext.cs +++ b/omsorgCore/src/OmsorgCore.Infrastructure/Persistence/OmsorgCoreDbContext.cs @@ -16,7 +16,9 @@ public class OmsorgCoreDbContext : DbContext public DbSet EmployeeFacilityDistances => Set(); public DbSet Contracts => Set(); public DbSet Orders => Set(); + public DbSet Assignments => Set(); public DbSet Absences => Set(); + public DbSet AssignmentValidationSettings => Set(); public DbSet ValueLists => Set(); public DbSet ValueListItems => Set(); public DbSet ValueListItemTransitions => Set(); diff --git a/omsorgCore/src/OmsorgCore.Infrastructure/Repositories/AbsenceRepository.cs b/omsorgCore/src/OmsorgCore.Infrastructure/Repositories/AbsenceRepository.cs index a688f59..9cd3cdd 100644 --- a/omsorgCore/src/OmsorgCore.Infrastructure/Repositories/AbsenceRepository.cs +++ b/omsorgCore/src/OmsorgCore.Infrastructure/Repositories/AbsenceRepository.cs @@ -58,6 +58,25 @@ public class AbsenceRepository : IAbsenceRepository return (items, totalCount); } + public async Task HasOverlappingAbsenceAsync( + Guid employeeId, + DateOnly startDate, + DateOnly endDate, + IReadOnlyCollection blockingStatusValues, + CancellationToken cancellationToken = default) + { + if (blockingStatusValues.Count == 0) + { + return false; + } + + return await _db.Absences + .Where(a => a.EmployeeId == employeeId && !a.IsDeleted) + .Where(a => blockingStatusValues.Contains(a.Status)) + .Where(a => a.StartDate <= endDate && a.EndDate >= startDate) + .AnyAsync(cancellationToken); + } + public async Task AddAsync(Absence absence, CancellationToken cancellationToken = default) => await _db.Absences.AddAsync(absence, cancellationToken); diff --git a/omsorgCore/src/OmsorgCore.Infrastructure/Repositories/AssignmentRepository.cs b/omsorgCore/src/OmsorgCore.Infrastructure/Repositories/AssignmentRepository.cs new file mode 100644 index 0000000..16576d1 --- /dev/null +++ b/omsorgCore/src/OmsorgCore.Infrastructure/Repositories/AssignmentRepository.cs @@ -0,0 +1,164 @@ +using Microsoft.EntityFrameworkCore; +using OmsorgCore.Application.Abstractions; +using OmsorgCore.Domain.Entities; +using OmsorgCore.Infrastructure.Persistence; + +namespace OmsorgCore.Infrastructure.Repositories; + +public class AssignmentRepository : IAssignmentRepository +{ + private readonly OmsorgCoreDbContext _db; + + public AssignmentRepository(OmsorgCoreDbContext db) + { + _db = db; + } + + public Task GetByIdAsync(Guid id, CancellationToken cancellationToken = default) + => _db.Assignments.Include(a => a.Employee).FirstOrDefaultAsync(a => a.Id == id, cancellationToken); + + public async Task> GetAllAsync(CancellationToken cancellationToken = default) + => await _db.Assignments.AsNoTracking().Include(a => a.Employee).ToListAsync(cancellationToken); + + public async Task<(IReadOnlyList Items, int TotalCount)> GetPagedAsync( + Guid? orderId = null, + Guid? employeeId = null, + DateOnly? fromDate = null, + DateOnly? toDate = null, + int page = 1, + int pageSize = 20, + CancellationToken cancellationToken = default) + { + var query = _db.Assignments.AsNoTracking().Include(a => a.Employee).Where(a => !a.IsDeleted); + + if (orderId.HasValue) + { + query = query.Where(a => a.OrderId == orderId.Value); + } + + if (employeeId.HasValue) + { + query = query.Where(a => a.EmployeeId == employeeId.Value); + } + + if (fromDate.HasValue && toDate.HasValue) + { + query = query.Where(a => a.StartDate <= toDate.Value && a.EndDate >= fromDate.Value); + } + + var totalCount = await query.CountAsync(cancellationToken); + + var items = await query + .OrderBy(a => a.StartDate) + .Skip((page - 1) * pageSize) + .Take(pageSize) + .ToListAsync(cancellationToken); + + return (items, totalCount); + } + + public async Task HasOverlapAsync( + Guid employeeId, + DateOnly startDate, + DateOnly endDate, + Guid? excludeAssignmentId = null, + CancellationToken cancellationToken = default) + { + var query = _db.Assignments + .Where(a => a.EmployeeId == employeeId && !a.IsDeleted) + .Where(a => a.StartDate <= endDate && a.EndDate >= startDate); + + if (excludeAssignmentId.HasValue) + { + query = query.Where(a => a.Id != excludeAssignmentId.Value); + } + + return await query.AnyAsync(cancellationToken); + } + + public async Task GetAssignedDayCountInWeekAsync( + Guid employeeId, + DateOnly weekStart, + DateOnly weekEnd, + Guid? excludeAssignmentId = null, + CancellationToken cancellationToken = default) + { + var query = _db.Assignments + .Where(a => a.EmployeeId == employeeId && !a.IsDeleted) + .Where(a => a.StartDate <= weekEnd && a.EndDate >= weekStart); + + if (excludeAssignmentId.HasValue) + { + query = query.Where(a => a.Id != excludeAssignmentId.Value); + } + + var overlapping = await query + .Select(a => new { a.StartDate, a.EndDate }) + .ToListAsync(cancellationToken); + + var days = 0; + foreach (var a in overlapping) + { + var rangeStart = a.StartDate > weekStart ? a.StartDate : weekStart; + var rangeEnd = a.EndDate < weekEnd ? a.EndDate : weekEnd; + days += rangeEnd.DayNumber - rangeStart.DayNumber + 1; + } + + return days; + } + + public async Task CountForOrderAsync(Guid orderId, CancellationToken cancellationToken = default) + => await _db.Assignments.CountAsync(a => a.OrderId == orderId && !a.IsDeleted, cancellationToken); + + public async Task AddAsync(Assignment assignment, CancellationToken cancellationToken = default) + => await _db.Assignments.AddAsync(assignment, cancellationToken); + + public Task UpdateAsync(Assignment assignment, CancellationToken cancellationToken = default) + { + _db.Assignments.Update(assignment); + return Task.CompletedTask; + } + + public async Task SoftDeleteAsync(Guid id, CancellationToken cancellationToken = default) + { + var assignment = await _db.Assignments.FirstOrDefaultAsync(a => a.Id == id, cancellationToken); + if (assignment is null) + { + return false; + } + + assignment.IsDeleted = true; + assignment.DeletedAt = DateTime.UtcNow; + return true; + } + + public async Task> GetDeletedAsync(string? search, CancellationToken cancellationToken = default) + { + var query = _db.Assignments.IgnoreQueryFilters().AsNoTracking().Include(a => a.Employee).Where(a => a.IsDeleted); + + if (!string.IsNullOrWhiteSpace(search)) + { + query = query.Where(a => + EF.Functions.ILike(a.Employee.FirstName, $"%{search}%") || + EF.Functions.ILike(a.Employee.LastName, $"%{search}%")); + } + + return await query.OrderByDescending(a => a.DeletedAt).ToListAsync(cancellationToken); + } + + public async Task RestoreAsync(Guid id, CancellationToken cancellationToken = default) + { + var assignment = await _db.Assignments.IgnoreQueryFilters().FirstOrDefaultAsync(a => a.Id == id && a.IsDeleted, cancellationToken); + if (assignment is null) + { + return false; + } + + assignment.IsDeleted = false; + assignment.DeletedAt = null; + return true; + } + + public Task SaveChangesAsync(CancellationToken cancellationToken = default) + => _db.SaveChangesAsync(cancellationToken); +} diff --git a/omsorgCore/src/OmsorgCore.Infrastructure/Repositories/AssignmentValidationSettingsRepository.cs b/omsorgCore/src/OmsorgCore.Infrastructure/Repositories/AssignmentValidationSettingsRepository.cs new file mode 100644 index 0000000..35ae50b --- /dev/null +++ b/omsorgCore/src/OmsorgCore.Infrastructure/Repositories/AssignmentValidationSettingsRepository.cs @@ -0,0 +1,39 @@ +using Microsoft.EntityFrameworkCore; +using OmsorgCore.Application.Abstractions; +using OmsorgCore.Domain.Entities; +using OmsorgCore.Infrastructure.Persistence; + +namespace OmsorgCore.Infrastructure.Repositories; + +public class AssignmentValidationSettingsRepository : IAssignmentValidationSettingsRepository +{ + private readonly OmsorgCoreDbContext _db; + + public AssignmentValidationSettingsRepository(OmsorgCoreDbContext db) + { + _db = db; + } + + public async Task GetOrCreateAsync(CancellationToken cancellationToken = default) + { + var settings = await _db.AssignmentValidationSettings.FirstOrDefaultAsync(cancellationToken); + if (settings is not null) + { + return settings; + } + + settings = new AssignmentValidationSettings(); + await _db.AssignmentValidationSettings.AddAsync(settings, cancellationToken); + await _db.SaveChangesAsync(cancellationToken); + return settings; + } + + public Task UpdateAsync(AssignmentValidationSettings settings, CancellationToken cancellationToken = default) + { + _db.AssignmentValidationSettings.Update(settings); + return Task.CompletedTask; + } + + public Task SaveChangesAsync(CancellationToken cancellationToken = default) + => _db.SaveChangesAsync(cancellationToken); +} diff --git a/omsorgCore/src/OmsorgCore.Infrastructure/Repositories/ContractRepository.cs b/omsorgCore/src/OmsorgCore.Infrastructure/Repositories/ContractRepository.cs index 11e91db..e7d0ace 100644 --- a/omsorgCore/src/OmsorgCore.Infrastructure/Repositories/ContractRepository.cs +++ b/omsorgCore/src/OmsorgCore.Infrastructure/Repositories/ContractRepository.cs @@ -63,6 +63,16 @@ public class ContractRepository : IContractRepository return (items, totalCount); } + public Task GetActiveForEmployeeCoveringRangeAsync( + Guid employeeId, + DateOnly startDate, + DateOnly endDate, + CancellationToken cancellationToken = default) + => _db.Contracts + .Where(c => !c.IsDeleted && c.EmployeeId == employeeId && c.Status != "Entwurf") + .Where(c => c.StartDate <= startDate && (c.EndDate == null || c.EndDate >= endDate)) + .FirstOrDefaultAsync(cancellationToken); + public async Task AddAsync(Contract contract, CancellationToken cancellationToken = default) => await _db.Contracts.AddAsync(contract, cancellationToken); diff --git a/omsorgCore/tests/OmsorgCore.Tests/TestDoubles/FakeRepositories.cs b/omsorgCore/tests/OmsorgCore.Tests/TestDoubles/FakeRepositories.cs index e595694..60b0be1 100644 --- a/omsorgCore/tests/OmsorgCore.Tests/TestDoubles/FakeRepositories.cs +++ b/omsorgCore/tests/OmsorgCore.Tests/TestDoubles/FakeRepositories.cs @@ -492,6 +492,15 @@ public class FakeContractRepository : IContractRepository return Task.FromResult<(IReadOnlyList Items, int TotalCount)>((items, totalCount)); } + public Task GetActiveForEmployeeCoveringRangeAsync( + Guid employeeId, + DateOnly startDate, + DateOnly endDate, + CancellationToken cancellationToken = default) + => Task.FromResult(_contracts.FirstOrDefault(c => + !c.IsDeleted && c.EmployeeId == employeeId && c.Status != "Entwurf" && + c.StartDate <= startDate && (c.EndDate == null || c.EndDate >= endDate))); + public Task AddAsync(Contract contract, CancellationToken cancellationToken = default) { _contracts.Add(contract); diff --git a/omsorgWeb/mitarbeiter-app/api-client-php/.openapi-generator/FILES b/omsorgWeb/mitarbeiter-app/api-client-php/.openapi-generator/FILES index 20ecec1..a890734 100644 --- a/omsorgWeb/mitarbeiter-app/api-client-php/.openapi-generator/FILES +++ b/omsorgWeb/mitarbeiter-app/api-client-php/.openapi-generator/FILES @@ -6,6 +6,8 @@ composer.json docs/Api/AbsencesApi.md docs/Api/AdminEmailApi.md docs/Api/AdminSessionsApi.md +docs/Api/AssignmentValidationSettingsApi.md +docs/Api/AssignmentsApi.md docs/Api/AuditLogApi.md docs/Api/AuthApi.md docs/Api/ContractsApi.md @@ -27,6 +29,10 @@ docs/Model/AbsenceDecisionRequest.md docs/Model/AbsenceResponse.md docs/Model/AbsenceResponsePagedResponse.md docs/Model/AddUserPermissionOverrideRequest.md +docs/Model/AssignmentConflictResponse.md +docs/Model/AssignmentResponse.md +docs/Model/AssignmentResponsePagedResponse.md +docs/Model/AssignmentValidationSettingsResponse.md docs/Model/AuditEventCategory.md docs/Model/AuditLogEntryResponse.md docs/Model/AuditLogEntryResponsePagedResponse.md @@ -34,6 +40,7 @@ docs/Model/ChangePasswordRequest.md docs/Model/ContractResponse.md docs/Model/ContractResponsePagedResponse.md docs/Model/CreateAbsenceRequest.md +docs/Model/CreateAssignmentRequest.md docs/Model/CreateContractRequest.md docs/Model/CreateEmployeeFacilityDistanceRequest.md docs/Model/CreateEmployeeRequest.md @@ -84,6 +91,7 @@ docs/Model/TimeEntryDecisionRequest.md docs/Model/TimeEntryResponse.md docs/Model/TimeEntryResponsePagedResponse.md docs/Model/TrashAbsenceResponse.md +docs/Model/TrashAssignmentResponse.md docs/Model/TrashContractResponse.md docs/Model/TrashEmployeeFacilityDistanceResponse.md docs/Model/TrashEmployeeResponse.md @@ -93,6 +101,8 @@ docs/Model/TrashFacilityResponse.md docs/Model/TrashOrderResponse.md docs/Model/TrashTimeEntryResponse.md docs/Model/UpdateAbsenceRequest.md +docs/Model/UpdateAssignmentRequest.md +docs/Model/UpdateAssignmentValidationSettingsRequest.md docs/Model/UpdateContractRequest.md docs/Model/UpdateDocumentRequest.md docs/Model/UpdateEmployeeFacilityDistanceRequest.md @@ -117,6 +127,8 @@ git_push.sh lib/Api/AbsencesApi.php lib/Api/AdminEmailApi.php lib/Api/AdminSessionsApi.php +lib/Api/AssignmentValidationSettingsApi.php +lib/Api/AssignmentsApi.php lib/Api/AuditLogApi.php lib/Api/AuthApi.php lib/Api/ContractsApi.php @@ -142,6 +154,10 @@ lib/Model/AbsenceDecisionRequest.php lib/Model/AbsenceResponse.php lib/Model/AbsenceResponsePagedResponse.php lib/Model/AddUserPermissionOverrideRequest.php +lib/Model/AssignmentConflictResponse.php +lib/Model/AssignmentResponse.php +lib/Model/AssignmentResponsePagedResponse.php +lib/Model/AssignmentValidationSettingsResponse.php lib/Model/AuditEventCategory.php lib/Model/AuditLogEntryResponse.php lib/Model/AuditLogEntryResponsePagedResponse.php @@ -149,6 +165,7 @@ lib/Model/ChangePasswordRequest.php lib/Model/ContractResponse.php lib/Model/ContractResponsePagedResponse.php lib/Model/CreateAbsenceRequest.php +lib/Model/CreateAssignmentRequest.php lib/Model/CreateContractRequest.php lib/Model/CreateEmployeeFacilityDistanceRequest.php lib/Model/CreateEmployeeRequest.php @@ -200,6 +217,7 @@ lib/Model/TimeEntryDecisionRequest.php lib/Model/TimeEntryResponse.php lib/Model/TimeEntryResponsePagedResponse.php lib/Model/TrashAbsenceResponse.php +lib/Model/TrashAssignmentResponse.php lib/Model/TrashContractResponse.php lib/Model/TrashEmployeeFacilityDistanceResponse.php lib/Model/TrashEmployeeResponse.php @@ -209,6 +227,8 @@ lib/Model/TrashFacilityResponse.php lib/Model/TrashOrderResponse.php lib/Model/TrashTimeEntryResponse.php lib/Model/UpdateAbsenceRequest.php +lib/Model/UpdateAssignmentRequest.php +lib/Model/UpdateAssignmentValidationSettingsRequest.php lib/Model/UpdateContractRequest.php lib/Model/UpdateDocumentRequest.php lib/Model/UpdateEmployeeFacilityDistanceRequest.php diff --git a/omsorgWeb/mitarbeiter-app/api-client-php/README.md b/omsorgWeb/mitarbeiter-app/api-client-php/README.md index a93f6be..d1c49f3 100644 --- a/omsorgWeb/mitarbeiter-app/api-client-php/README.md +++ b/omsorgWeb/mitarbeiter-app/api-client-php/README.md @@ -90,6 +90,14 @@ Class | Method | HTTP request | Description *AdminSessionsApi* | [**apiAdminSessionsGet**](docs/Api/AdminSessionsApi.md#apiadminsessionsget) | **GET** /api/admin/sessions | *AdminSessionsApi* | [**apiAdminSessionsIdRevokePost**](docs/Api/AdminSessionsApi.md#apiadminsessionsidrevokepost) | **POST** /api/admin/sessions/{id}/revoke | *AdminSessionsApi* | [**apiAdminSessionsRevokeAllPost**](docs/Api/AdminSessionsApi.md#apiadminsessionsrevokeallpost) | **POST** /api/admin/sessions/revoke-all | +*AssignmentValidationSettingsApi* | [**apiSettingsAssignmentValidationGet**](docs/Api/AssignmentValidationSettingsApi.md#apisettingsassignmentvalidationget) | **GET** /api/settings/assignment-validation | +*AssignmentValidationSettingsApi* | [**apiSettingsAssignmentValidationPut**](docs/Api/AssignmentValidationSettingsApi.md#apisettingsassignmentvalidationput) | **PUT** /api/settings/assignment-validation | +*AssignmentsApi* | [**apiAssignmentsCheckGet**](docs/Api/AssignmentsApi.md#apiassignmentscheckget) | **GET** /api/assignments/check | +*AssignmentsApi* | [**apiAssignmentsGet**](docs/Api/AssignmentsApi.md#apiassignmentsget) | **GET** /api/assignments | +*AssignmentsApi* | [**apiAssignmentsIdDelete**](docs/Api/AssignmentsApi.md#apiassignmentsiddelete) | **DELETE** /api/assignments/{id} | +*AssignmentsApi* | [**apiAssignmentsIdGet**](docs/Api/AssignmentsApi.md#apiassignmentsidget) | **GET** /api/assignments/{id} | +*AssignmentsApi* | [**apiAssignmentsIdPut**](docs/Api/AssignmentsApi.md#apiassignmentsidput) | **PUT** /api/assignments/{id} | +*AssignmentsApi* | [**apiAssignmentsPost**](docs/Api/AssignmentsApi.md#apiassignmentspost) | **POST** /api/assignments | *AuditLogApi* | [**apiAuditLogGet**](docs/Api/AuditLogApi.md#apiauditlogget) | **GET** /api/audit-log | *AuthApi* | [**apiAuthChangePasswordPost**](docs/Api/AuthApi.md#apiauthchangepasswordpost) | **POST** /api/auth/change-password | *AuthApi* | [**apiAuthForgotPasswordRequestPost**](docs/Api/AuthApi.md#apiauthforgotpasswordrequestpost) | **POST** /api/auth/forgot-password/request | @@ -156,6 +164,8 @@ Class | Method | HTTP request | Description *TimeEntriesApi* | [**apiTimeEntriesPost**](docs/Api/TimeEntriesApi.md#apitimeentriespost) | **POST** /api/time-entries | *TrashApi* | [**apiTrashAbsencesGet**](docs/Api/TrashApi.md#apitrashabsencesget) | **GET** /api/trash/absences | *TrashApi* | [**apiTrashAbsencesIdRestorePost**](docs/Api/TrashApi.md#apitrashabsencesidrestorepost) | **POST** /api/trash/absences/{id}/restore | +*TrashApi* | [**apiTrashAssignmentsGet**](docs/Api/TrashApi.md#apitrashassignmentsget) | **GET** /api/trash/assignments | +*TrashApi* | [**apiTrashAssignmentsIdRestorePost**](docs/Api/TrashApi.md#apitrashassignmentsidrestorepost) | **POST** /api/trash/assignments/{id}/restore | *TrashApi* | [**apiTrashContractsGet**](docs/Api/TrashApi.md#apitrashcontractsget) | **GET** /api/trash/contracts | *TrashApi* | [**apiTrashContractsIdRestorePost**](docs/Api/TrashApi.md#apitrashcontractsidrestorepost) | **POST** /api/trash/contracts/{id}/restore | *TrashApi* | [**apiTrashEmployeeFacilityDistancesGet**](docs/Api/TrashApi.md#apitrashemployeefacilitydistancesget) | **GET** /api/trash/employee-facility-distances | @@ -194,6 +204,10 @@ Class | Method | HTTP request | Description - [AbsenceResponse](docs/Model/AbsenceResponse.md) - [AbsenceResponsePagedResponse](docs/Model/AbsenceResponsePagedResponse.md) - [AddUserPermissionOverrideRequest](docs/Model/AddUserPermissionOverrideRequest.md) +- [AssignmentConflictResponse](docs/Model/AssignmentConflictResponse.md) +- [AssignmentResponse](docs/Model/AssignmentResponse.md) +- [AssignmentResponsePagedResponse](docs/Model/AssignmentResponsePagedResponse.md) +- [AssignmentValidationSettingsResponse](docs/Model/AssignmentValidationSettingsResponse.md) - [AuditEventCategory](docs/Model/AuditEventCategory.md) - [AuditLogEntryResponse](docs/Model/AuditLogEntryResponse.md) - [AuditLogEntryResponsePagedResponse](docs/Model/AuditLogEntryResponsePagedResponse.md) @@ -201,6 +215,7 @@ Class | Method | HTTP request | Description - [ContractResponse](docs/Model/ContractResponse.md) - [ContractResponsePagedResponse](docs/Model/ContractResponsePagedResponse.md) - [CreateAbsenceRequest](docs/Model/CreateAbsenceRequest.md) +- [CreateAssignmentRequest](docs/Model/CreateAssignmentRequest.md) - [CreateContractRequest](docs/Model/CreateContractRequest.md) - [CreateEmployeeFacilityDistanceRequest](docs/Model/CreateEmployeeFacilityDistanceRequest.md) - [CreateEmployeeRequest](docs/Model/CreateEmployeeRequest.md) @@ -251,6 +266,7 @@ Class | Method | HTTP request | Description - [TimeEntryResponse](docs/Model/TimeEntryResponse.md) - [TimeEntryResponsePagedResponse](docs/Model/TimeEntryResponsePagedResponse.md) - [TrashAbsenceResponse](docs/Model/TrashAbsenceResponse.md) +- [TrashAssignmentResponse](docs/Model/TrashAssignmentResponse.md) - [TrashContractResponse](docs/Model/TrashContractResponse.md) - [TrashEmployeeFacilityDistanceResponse](docs/Model/TrashEmployeeFacilityDistanceResponse.md) - [TrashEmployeeResponse](docs/Model/TrashEmployeeResponse.md) @@ -260,6 +276,8 @@ Class | Method | HTTP request | Description - [TrashOrderResponse](docs/Model/TrashOrderResponse.md) - [TrashTimeEntryResponse](docs/Model/TrashTimeEntryResponse.md) - [UpdateAbsenceRequest](docs/Model/UpdateAbsenceRequest.md) +- [UpdateAssignmentRequest](docs/Model/UpdateAssignmentRequest.md) +- [UpdateAssignmentValidationSettingsRequest](docs/Model/UpdateAssignmentValidationSettingsRequest.md) - [UpdateContractRequest](docs/Model/UpdateContractRequest.md) - [UpdateDocumentRequest](docs/Model/UpdateDocumentRequest.md) - [UpdateEmployeeFacilityDistanceRequest](docs/Model/UpdateEmployeeFacilityDistanceRequest.md) diff --git a/omsorgWeb/mitarbeiter-app/api-client-php/docs/Api/AssignmentValidationSettingsApi.md b/omsorgWeb/mitarbeiter-app/api-client-php/docs/Api/AssignmentValidationSettingsApi.md new file mode 100644 index 0000000..93f7b7a --- /dev/null +++ b/omsorgWeb/mitarbeiter-app/api-client-php/docs/Api/AssignmentValidationSettingsApi.md @@ -0,0 +1,122 @@ +# OmsorgCoreClient\AssignmentValidationSettingsApi + +All URIs are relative to http://localhost, except if the operation defines another base path. + +| Method | HTTP request | Description | +| ------------- | ------------- | ------------- | +| [**apiSettingsAssignmentValidationGet()**](AssignmentValidationSettingsApi.md#apiSettingsAssignmentValidationGet) | **GET** /api/settings/assignment-validation | | +| [**apiSettingsAssignmentValidationPut()**](AssignmentValidationSettingsApi.md#apiSettingsAssignmentValidationPut) | **PUT** /api/settings/assignment-validation | | + + +## `apiSettingsAssignmentValidationGet()` + +```php +apiSettingsAssignmentValidationGet(): \OmsorgCoreClient\Model\AssignmentValidationSettingsResponse +``` + + + +### Example + +```php +setAccessToken('YOUR_ACCESS_TOKEN'); + + +$apiInstance = new OmsorgCoreClient\Api\AssignmentValidationSettingsApi( + // If you want use custom http client, pass your client which implements `GuzzleHttp\ClientInterface`. + // This is optional, `GuzzleHttp\Client` will be used as default. + new GuzzleHttp\Client(), + $config +); + +try { + $result = $apiInstance->apiSettingsAssignmentValidationGet(); + print_r($result); +} catch (Exception $e) { + echo 'Exception when calling AssignmentValidationSettingsApi->apiSettingsAssignmentValidationGet: ', $e->getMessage(), PHP_EOL; +} +``` + +### Parameters + +This endpoint does not need any parameter. + +### Return type + +[**\OmsorgCoreClient\Model\AssignmentValidationSettingsResponse**](../Model/AssignmentValidationSettingsResponse.md) + +### Authorization + +[Bearer](../../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: `text/plain`, `application/json`, `text/json` + +[[Back to top]](#) [[Back to API list]](../../README.md#endpoints) +[[Back to Model list]](../../README.md#models) +[[Back to README]](../../README.md) + +## `apiSettingsAssignmentValidationPut()` + +```php +apiSettingsAssignmentValidationPut($update_assignment_validation_settings_request): \OmsorgCoreClient\Model\AssignmentValidationSettingsResponse +``` + + + +### Example + +```php +setAccessToken('YOUR_ACCESS_TOKEN'); + + +$apiInstance = new OmsorgCoreClient\Api\AssignmentValidationSettingsApi( + // If you want use custom http client, pass your client which implements `GuzzleHttp\ClientInterface`. + // This is optional, `GuzzleHttp\Client` will be used as default. + new GuzzleHttp\Client(), + $config +); +$update_assignment_validation_settings_request = new \OmsorgCoreClient\Model\UpdateAssignmentValidationSettingsRequest(); // \OmsorgCoreClient\Model\UpdateAssignmentValidationSettingsRequest + +try { + $result = $apiInstance->apiSettingsAssignmentValidationPut($update_assignment_validation_settings_request); + print_r($result); +} catch (Exception $e) { + echo 'Exception when calling AssignmentValidationSettingsApi->apiSettingsAssignmentValidationPut: ', $e->getMessage(), PHP_EOL; +} +``` + +### Parameters + +| Name | Type | Description | Notes | +| ------------- | ------------- | ------------- | ------------- | +| **update_assignment_validation_settings_request** | [**\OmsorgCoreClient\Model\UpdateAssignmentValidationSettingsRequest**](../Model/UpdateAssignmentValidationSettingsRequest.md)| | [optional] | + +### Return type + +[**\OmsorgCoreClient\Model\AssignmentValidationSettingsResponse**](../Model/AssignmentValidationSettingsResponse.md) + +### Authorization + +[Bearer](../../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: `application/json`, `text/json`, `application/*+json` +- **Accept**: `text/plain`, `application/json`, `text/json` + +[[Back to top]](#) [[Back to API list]](../../README.md#endpoints) +[[Back to Model list]](../../README.md#models) +[[Back to README]](../../README.md) diff --git a/omsorgWeb/mitarbeiter-app/api-client-php/docs/Api/AssignmentsApi.md b/omsorgWeb/mitarbeiter-app/api-client-php/docs/Api/AssignmentsApi.md new file mode 100644 index 0000000..5947f9c --- /dev/null +++ b/omsorgWeb/mitarbeiter-app/api-client-php/docs/Api/AssignmentsApi.md @@ -0,0 +1,380 @@ +# OmsorgCoreClient\AssignmentsApi + +All URIs are relative to http://localhost, except if the operation defines another base path. + +| Method | HTTP request | Description | +| ------------- | ------------- | ------------- | +| [**apiAssignmentsCheckGet()**](AssignmentsApi.md#apiAssignmentsCheckGet) | **GET** /api/assignments/check | | +| [**apiAssignmentsGet()**](AssignmentsApi.md#apiAssignmentsGet) | **GET** /api/assignments | | +| [**apiAssignmentsIdDelete()**](AssignmentsApi.md#apiAssignmentsIdDelete) | **DELETE** /api/assignments/{id} | | +| [**apiAssignmentsIdGet()**](AssignmentsApi.md#apiAssignmentsIdGet) | **GET** /api/assignments/{id} | | +| [**apiAssignmentsIdPut()**](AssignmentsApi.md#apiAssignmentsIdPut) | **PUT** /api/assignments/{id} | | +| [**apiAssignmentsPost()**](AssignmentsApi.md#apiAssignmentsPost) | **POST** /api/assignments | | + + +## `apiAssignmentsCheckGet()` + +```php +apiAssignmentsCheckGet($order_id, $employee_id, $start_date, $end_date, $exclude_assignment_id): \OmsorgCoreClient\Model\AssignmentConflictResponse[] +``` + + + +### Example + +```php +setAccessToken('YOUR_ACCESS_TOKEN'); + + +$apiInstance = new OmsorgCoreClient\Api\AssignmentsApi( + // If you want use custom http client, pass your client which implements `GuzzleHttp\ClientInterface`. + // This is optional, `GuzzleHttp\Client` will be used as default. + new GuzzleHttp\Client(), + $config +); +$order_id = 'order_id_example'; // string +$employee_id = 'employee_id_example'; // string +$start_date = new \DateTime('2013-10-20T19:20:30+01:00'); // \DateTime +$end_date = new \DateTime('2013-10-20T19:20:30+01:00'); // \DateTime +$exclude_assignment_id = 'exclude_assignment_id_example'; // string + +try { + $result = $apiInstance->apiAssignmentsCheckGet($order_id, $employee_id, $start_date, $end_date, $exclude_assignment_id); + print_r($result); +} catch (Exception $e) { + echo 'Exception when calling AssignmentsApi->apiAssignmentsCheckGet: ', $e->getMessage(), PHP_EOL; +} +``` + +### Parameters + +| Name | Type | Description | Notes | +| ------------- | ------------- | ------------- | ------------- | +| **order_id** | **string**| | [optional] | +| **employee_id** | **string**| | [optional] | +| **start_date** | **\DateTime**| | [optional] | +| **end_date** | **\DateTime**| | [optional] | +| **exclude_assignment_id** | **string**| | [optional] | + +### Return type + +[**\OmsorgCoreClient\Model\AssignmentConflictResponse[]**](../Model/AssignmentConflictResponse.md) + +### Authorization + +[Bearer](../../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: `text/plain`, `application/json`, `text/json` + +[[Back to top]](#) [[Back to API list]](../../README.md#endpoints) +[[Back to Model list]](../../README.md#models) +[[Back to README]](../../README.md) + +## `apiAssignmentsGet()` + +```php +apiAssignmentsGet($order_id, $employee_id, $from_date, $to_date, $page, $page_size): \OmsorgCoreClient\Model\AssignmentResponsePagedResponse +``` + + + +### Example + +```php +setAccessToken('YOUR_ACCESS_TOKEN'); + + +$apiInstance = new OmsorgCoreClient\Api\AssignmentsApi( + // If you want use custom http client, pass your client which implements `GuzzleHttp\ClientInterface`. + // This is optional, `GuzzleHttp\Client` will be used as default. + new GuzzleHttp\Client(), + $config +); +$order_id = 'order_id_example'; // string +$employee_id = 'employee_id_example'; // string +$from_date = new \DateTime('2013-10-20T19:20:30+01:00'); // \DateTime +$to_date = new \DateTime('2013-10-20T19:20:30+01:00'); // \DateTime +$page = 1; // int +$page_size = 20; // int + +try { + $result = $apiInstance->apiAssignmentsGet($order_id, $employee_id, $from_date, $to_date, $page, $page_size); + print_r($result); +} catch (Exception $e) { + echo 'Exception when calling AssignmentsApi->apiAssignmentsGet: ', $e->getMessage(), PHP_EOL; +} +``` + +### Parameters + +| Name | Type | Description | Notes | +| ------------- | ------------- | ------------- | ------------- | +| **order_id** | **string**| | [optional] | +| **employee_id** | **string**| | [optional] | +| **from_date** | **\DateTime**| | [optional] | +| **to_date** | **\DateTime**| | [optional] | +| **page** | **int**| | [optional] [default to 1] | +| **page_size** | **int**| | [optional] [default to 20] | + +### Return type + +[**\OmsorgCoreClient\Model\AssignmentResponsePagedResponse**](../Model/AssignmentResponsePagedResponse.md) + +### Authorization + +[Bearer](../../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: `text/plain`, `application/json`, `text/json` + +[[Back to top]](#) [[Back to API list]](../../README.md#endpoints) +[[Back to Model list]](../../README.md#models) +[[Back to README]](../../README.md) + +## `apiAssignmentsIdDelete()` + +```php +apiAssignmentsIdDelete($id) +``` + + + +### Example + +```php +setAccessToken('YOUR_ACCESS_TOKEN'); + + +$apiInstance = new OmsorgCoreClient\Api\AssignmentsApi( + // If you want use custom http client, pass your client which implements `GuzzleHttp\ClientInterface`. + // This is optional, `GuzzleHttp\Client` will be used as default. + new GuzzleHttp\Client(), + $config +); +$id = 'id_example'; // string + +try { + $apiInstance->apiAssignmentsIdDelete($id); +} catch (Exception $e) { + echo 'Exception when calling AssignmentsApi->apiAssignmentsIdDelete: ', $e->getMessage(), PHP_EOL; +} +``` + +### Parameters + +| Name | Type | Description | Notes | +| ------------- | ------------- | ------------- | ------------- | +| **id** | **string**| | | + +### Return type + +void (empty response body) + +### Authorization + +[Bearer](../../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../../README.md#endpoints) +[[Back to Model list]](../../README.md#models) +[[Back to README]](../../README.md) + +## `apiAssignmentsIdGet()` + +```php +apiAssignmentsIdGet($id): \OmsorgCoreClient\Model\AssignmentResponse +``` + + + +### Example + +```php +setAccessToken('YOUR_ACCESS_TOKEN'); + + +$apiInstance = new OmsorgCoreClient\Api\AssignmentsApi( + // If you want use custom http client, pass your client which implements `GuzzleHttp\ClientInterface`. + // This is optional, `GuzzleHttp\Client` will be used as default. + new GuzzleHttp\Client(), + $config +); +$id = 'id_example'; // string + +try { + $result = $apiInstance->apiAssignmentsIdGet($id); + print_r($result); +} catch (Exception $e) { + echo 'Exception when calling AssignmentsApi->apiAssignmentsIdGet: ', $e->getMessage(), PHP_EOL; +} +``` + +### Parameters + +| Name | Type | Description | Notes | +| ------------- | ------------- | ------------- | ------------- | +| **id** | **string**| | | + +### Return type + +[**\OmsorgCoreClient\Model\AssignmentResponse**](../Model/AssignmentResponse.md) + +### Authorization + +[Bearer](../../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: `text/plain`, `application/json`, `text/json` + +[[Back to top]](#) [[Back to API list]](../../README.md#endpoints) +[[Back to Model list]](../../README.md#models) +[[Back to README]](../../README.md) + +## `apiAssignmentsIdPut()` + +```php +apiAssignmentsIdPut($id, $update_assignment_request): \OmsorgCoreClient\Model\AssignmentResponse +``` + + + +### Example + +```php +setAccessToken('YOUR_ACCESS_TOKEN'); + + +$apiInstance = new OmsorgCoreClient\Api\AssignmentsApi( + // If you want use custom http client, pass your client which implements `GuzzleHttp\ClientInterface`. + // This is optional, `GuzzleHttp\Client` will be used as default. + new GuzzleHttp\Client(), + $config +); +$id = 'id_example'; // string +$update_assignment_request = new \OmsorgCoreClient\Model\UpdateAssignmentRequest(); // \OmsorgCoreClient\Model\UpdateAssignmentRequest + +try { + $result = $apiInstance->apiAssignmentsIdPut($id, $update_assignment_request); + print_r($result); +} catch (Exception $e) { + echo 'Exception when calling AssignmentsApi->apiAssignmentsIdPut: ', $e->getMessage(), PHP_EOL; +} +``` + +### Parameters + +| Name | Type | Description | Notes | +| ------------- | ------------- | ------------- | ------------- | +| **id** | **string**| | | +| **update_assignment_request** | [**\OmsorgCoreClient\Model\UpdateAssignmentRequest**](../Model/UpdateAssignmentRequest.md)| | [optional] | + +### Return type + +[**\OmsorgCoreClient\Model\AssignmentResponse**](../Model/AssignmentResponse.md) + +### Authorization + +[Bearer](../../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: `application/json`, `text/json`, `application/*+json` +- **Accept**: `text/plain`, `application/json`, `text/json` + +[[Back to top]](#) [[Back to API list]](../../README.md#endpoints) +[[Back to Model list]](../../README.md#models) +[[Back to README]](../../README.md) + +## `apiAssignmentsPost()` + +```php +apiAssignmentsPost($create_assignment_request): \OmsorgCoreClient\Model\AssignmentResponse +``` + + + +### Example + +```php +setAccessToken('YOUR_ACCESS_TOKEN'); + + +$apiInstance = new OmsorgCoreClient\Api\AssignmentsApi( + // If you want use custom http client, pass your client which implements `GuzzleHttp\ClientInterface`. + // This is optional, `GuzzleHttp\Client` will be used as default. + new GuzzleHttp\Client(), + $config +); +$create_assignment_request = new \OmsorgCoreClient\Model\CreateAssignmentRequest(); // \OmsorgCoreClient\Model\CreateAssignmentRequest + +try { + $result = $apiInstance->apiAssignmentsPost($create_assignment_request); + print_r($result); +} catch (Exception $e) { + echo 'Exception when calling AssignmentsApi->apiAssignmentsPost: ', $e->getMessage(), PHP_EOL; +} +``` + +### Parameters + +| Name | Type | Description | Notes | +| ------------- | ------------- | ------------- | ------------- | +| **create_assignment_request** | [**\OmsorgCoreClient\Model\CreateAssignmentRequest**](../Model/CreateAssignmentRequest.md)| | [optional] | + +### Return type + +[**\OmsorgCoreClient\Model\AssignmentResponse**](../Model/AssignmentResponse.md) + +### Authorization + +[Bearer](../../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: `application/json`, `text/json`, `application/*+json` +- **Accept**: `text/plain`, `application/json`, `text/json` + +[[Back to top]](#) [[Back to API list]](../../README.md#endpoints) +[[Back to Model list]](../../README.md#models) +[[Back to README]](../../README.md) diff --git a/omsorgWeb/mitarbeiter-app/api-client-php/docs/Api/TrashApi.md b/omsorgWeb/mitarbeiter-app/api-client-php/docs/Api/TrashApi.md index b0b0e87..ba61ac4 100644 --- a/omsorgWeb/mitarbeiter-app/api-client-php/docs/Api/TrashApi.md +++ b/omsorgWeb/mitarbeiter-app/api-client-php/docs/Api/TrashApi.md @@ -6,6 +6,8 @@ All URIs are relative to http://localhost, except if the operation defines anoth | ------------- | ------------- | ------------- | | [**apiTrashAbsencesGet()**](TrashApi.md#apiTrashAbsencesGet) | **GET** /api/trash/absences | | | [**apiTrashAbsencesIdRestorePost()**](TrashApi.md#apiTrashAbsencesIdRestorePost) | **POST** /api/trash/absences/{id}/restore | | +| [**apiTrashAssignmentsGet()**](TrashApi.md#apiTrashAssignmentsGet) | **GET** /api/trash/assignments | | +| [**apiTrashAssignmentsIdRestorePost()**](TrashApi.md#apiTrashAssignmentsIdRestorePost) | **POST** /api/trash/assignments/{id}/restore | | | [**apiTrashContractsGet()**](TrashApi.md#apiTrashContractsGet) | **GET** /api/trash/contracts | | | [**apiTrashContractsIdRestorePost()**](TrashApi.md#apiTrashContractsIdRestorePost) | **POST** /api/trash/contracts/{id}/restore | | | [**apiTrashEmployeeFacilityDistancesGet()**](TrashApi.md#apiTrashEmployeeFacilityDistancesGet) | **GET** /api/trash/employee-facility-distances | | @@ -139,6 +141,121 @@ void (empty response body) [[Back to Model list]](../../README.md#models) [[Back to README]](../../README.md) +## `apiTrashAssignmentsGet()` + +```php +apiTrashAssignmentsGet($search): \OmsorgCoreClient\Model\TrashAssignmentResponse[] +``` + + + +### Example + +```php +setAccessToken('YOUR_ACCESS_TOKEN'); + + +$apiInstance = new OmsorgCoreClient\Api\TrashApi( + // If you want use custom http client, pass your client which implements `GuzzleHttp\ClientInterface`. + // This is optional, `GuzzleHttp\Client` will be used as default. + new GuzzleHttp\Client(), + $config +); +$search = 'search_example'; // string + +try { + $result = $apiInstance->apiTrashAssignmentsGet($search); + print_r($result); +} catch (Exception $e) { + echo 'Exception when calling TrashApi->apiTrashAssignmentsGet: ', $e->getMessage(), PHP_EOL; +} +``` + +### Parameters + +| Name | Type | Description | Notes | +| ------------- | ------------- | ------------- | ------------- | +| **search** | **string**| | [optional] | + +### Return type + +[**\OmsorgCoreClient\Model\TrashAssignmentResponse[]**](../Model/TrashAssignmentResponse.md) + +### Authorization + +[Bearer](../../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: `text/plain`, `application/json`, `text/json` + +[[Back to top]](#) [[Back to API list]](../../README.md#endpoints) +[[Back to Model list]](../../README.md#models) +[[Back to README]](../../README.md) + +## `apiTrashAssignmentsIdRestorePost()` + +```php +apiTrashAssignmentsIdRestorePost($id) +``` + + + +### Example + +```php +setAccessToken('YOUR_ACCESS_TOKEN'); + + +$apiInstance = new OmsorgCoreClient\Api\TrashApi( + // If you want use custom http client, pass your client which implements `GuzzleHttp\ClientInterface`. + // This is optional, `GuzzleHttp\Client` will be used as default. + new GuzzleHttp\Client(), + $config +); +$id = 'id_example'; // string + +try { + $apiInstance->apiTrashAssignmentsIdRestorePost($id); +} catch (Exception $e) { + echo 'Exception when calling TrashApi->apiTrashAssignmentsIdRestorePost: ', $e->getMessage(), PHP_EOL; +} +``` + +### Parameters + +| Name | Type | Description | Notes | +| ------------- | ------------- | ------------- | ------------- | +| **id** | **string**| | | + +### Return type + +void (empty response body) + +### Authorization + +[Bearer](../../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../../README.md#endpoints) +[[Back to Model list]](../../README.md#models) +[[Back to README]](../../README.md) + ## `apiTrashContractsGet()` ```php diff --git a/omsorgWeb/mitarbeiter-app/api-client-php/docs/Model/AssignmentConflictResponse.md b/omsorgWeb/mitarbeiter-app/api-client-php/docs/Model/AssignmentConflictResponse.md new file mode 100644 index 0000000..b4327b5 --- /dev/null +++ b/omsorgWeb/mitarbeiter-app/api-client-php/docs/Model/AssignmentConflictResponse.md @@ -0,0 +1,11 @@ +# # AssignmentConflictResponse + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**type** | **string** | | [optional] +**severity** | **string** | | [optional] +**message** | **string** | | [optional] + +[[Back to Model list]](../../README.md#models) [[Back to API list]](../../README.md#endpoints) [[Back to README]](../../README.md) diff --git a/omsorgWeb/mitarbeiter-app/api-client-php/docs/Model/AssignmentResponse.md b/omsorgWeb/mitarbeiter-app/api-client-php/docs/Model/AssignmentResponse.md new file mode 100644 index 0000000..c6f1130 --- /dev/null +++ b/omsorgWeb/mitarbeiter-app/api-client-php/docs/Model/AssignmentResponse.md @@ -0,0 +1,17 @@ +# # AssignmentResponse + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**id** | **string** | | [optional] +**order_id** | **string** | | [optional] +**employee_id** | **string** | | [optional] +**employee_first_name** | **string** | | [optional] +**employee_last_name** | **string** | | [optional] +**start_date** | **\DateTime** | | [optional] +**end_date** | **\DateTime** | | [optional] +**note** | **string** | | [optional] +**conflicts** | [**\OmsorgCoreClient\Model\AssignmentConflictResponse[]**](AssignmentConflictResponse.md) | | [optional] + +[[Back to Model list]](../../README.md#models) [[Back to API list]](../../README.md#endpoints) [[Back to README]](../../README.md) diff --git a/omsorgWeb/mitarbeiter-app/api-client-php/docs/Model/AssignmentResponsePagedResponse.md b/omsorgWeb/mitarbeiter-app/api-client-php/docs/Model/AssignmentResponsePagedResponse.md new file mode 100644 index 0000000..0cf7a62 --- /dev/null +++ b/omsorgWeb/mitarbeiter-app/api-client-php/docs/Model/AssignmentResponsePagedResponse.md @@ -0,0 +1,12 @@ +# # AssignmentResponsePagedResponse + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**items** | [**\OmsorgCoreClient\Model\AssignmentResponse[]**](AssignmentResponse.md) | | [optional] +**total_count** | **int** | | [optional] +**page** | **int** | | [optional] +**page_size** | **int** | | [optional] + +[[Back to Model list]](../../README.md#models) [[Back to API list]](../../README.md#endpoints) [[Back to README]](../../README.md) diff --git a/omsorgWeb/mitarbeiter-app/api-client-php/docs/Model/AssignmentValidationSettingsResponse.md b/omsorgWeb/mitarbeiter-app/api-client-php/docs/Model/AssignmentValidationSettingsResponse.md new file mode 100644 index 0000000..1bf8134 --- /dev/null +++ b/omsorgWeb/mitarbeiter-app/api-client-php/docs/Model/AssignmentValidationSettingsResponse.md @@ -0,0 +1,13 @@ +# # AssignmentValidationSettingsResponse + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**qualification_mode** | **string** | | [optional] +**absence_mode** | **string** | | [optional] +**working_hours_mode** | **string** | | [optional] +**overlap_mode** | **string** | | [optional] +**contract_mode** | **string** | | [optional] + +[[Back to Model list]](../../README.md#models) [[Back to API list]](../../README.md#endpoints) [[Back to README]](../../README.md) diff --git a/omsorgWeb/mitarbeiter-app/api-client-php/docs/Model/CreateAssignmentRequest.md b/omsorgWeb/mitarbeiter-app/api-client-php/docs/Model/CreateAssignmentRequest.md new file mode 100644 index 0000000..b6463de --- /dev/null +++ b/omsorgWeb/mitarbeiter-app/api-client-php/docs/Model/CreateAssignmentRequest.md @@ -0,0 +1,13 @@ +# # CreateAssignmentRequest + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**order_id** | **string** | | [optional] +**employee_id** | **string** | | [optional] +**start_date** | **\DateTime** | | [optional] +**end_date** | **\DateTime** | | [optional] +**note** | **string** | | [optional] + +[[Back to Model list]](../../README.md#models) [[Back to API list]](../../README.md#endpoints) [[Back to README]](../../README.md) diff --git a/omsorgWeb/mitarbeiter-app/api-client-php/docs/Model/TrashAssignmentResponse.md b/omsorgWeb/mitarbeiter-app/api-client-php/docs/Model/TrashAssignmentResponse.md new file mode 100644 index 0000000..fcac3a2 --- /dev/null +++ b/omsorgWeb/mitarbeiter-app/api-client-php/docs/Model/TrashAssignmentResponse.md @@ -0,0 +1,12 @@ +# # TrashAssignmentResponse + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**id** | **string** | | [optional] +**employee_first_name** | **string** | | [optional] +**employee_last_name** | **string** | | [optional] +**deleted_at** | **\DateTime** | | [optional] + +[[Back to Model list]](../../README.md#models) [[Back to API list]](../../README.md#endpoints) [[Back to README]](../../README.md) diff --git a/omsorgWeb/mitarbeiter-app/api-client-php/docs/Model/UpdateAssignmentRequest.md b/omsorgWeb/mitarbeiter-app/api-client-php/docs/Model/UpdateAssignmentRequest.md new file mode 100644 index 0000000..0d1a253 --- /dev/null +++ b/omsorgWeb/mitarbeiter-app/api-client-php/docs/Model/UpdateAssignmentRequest.md @@ -0,0 +1,9 @@ +# # UpdateAssignmentRequest + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**note** | **string** | | [optional] + +[[Back to Model list]](../../README.md#models) [[Back to API list]](../../README.md#endpoints) [[Back to README]](../../README.md) diff --git a/omsorgWeb/mitarbeiter-app/api-client-php/docs/Model/UpdateAssignmentValidationSettingsRequest.md b/omsorgWeb/mitarbeiter-app/api-client-php/docs/Model/UpdateAssignmentValidationSettingsRequest.md new file mode 100644 index 0000000..765d71b --- /dev/null +++ b/omsorgWeb/mitarbeiter-app/api-client-php/docs/Model/UpdateAssignmentValidationSettingsRequest.md @@ -0,0 +1,13 @@ +# # UpdateAssignmentValidationSettingsRequest + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**qualification_mode** | **string** | | [optional] +**absence_mode** | **string** | | [optional] +**working_hours_mode** | **string** | | [optional] +**overlap_mode** | **string** | | [optional] +**contract_mode** | **string** | | [optional] + +[[Back to Model list]](../../README.md#models) [[Back to API list]](../../README.md#endpoints) [[Back to README]](../../README.md) diff --git a/omsorgWeb/mitarbeiter-app/api-client-php/lib/Api/AssignmentValidationSettingsApi.php b/omsorgWeb/mitarbeiter-app/api-client-php/lib/Api/AssignmentValidationSettingsApi.php new file mode 100644 index 0000000..e7a0287 --- /dev/null +++ b/omsorgWeb/mitarbeiter-app/api-client-php/lib/Api/AssignmentValidationSettingsApi.php @@ -0,0 +1,695 @@ + [ + 'application/json', + ], + 'apiSettingsAssignmentValidationPut' => [ + 'application/json', + 'text/json', + 'application/*+json', + ], + ]; + + /** + * @param ClientInterface $client + * @param Configuration $config + * @param HeaderSelector $selector + * @param int $hostIndex (Optional) host index to select the list of hosts if defined in the OpenAPI spec + */ + public function __construct( + ?ClientInterface $client = null, + ?Configuration $config = null, + ?HeaderSelector $selector = null, + int $hostIndex = 0 + ) { + $this->client = $client ?: new Client(); + $this->config = $config ?: Configuration::getDefaultConfiguration(); + $this->headerSelector = $selector ?: new HeaderSelector(); + $this->hostIndex = $hostIndex; + } + + /** + * Set the host index + * + * @param int $hostIndex Host index (required) + */ + public function setHostIndex($hostIndex): void + { + $this->hostIndex = $hostIndex; + } + + /** + * Get the host index + * + * @return int Host index + */ + public function getHostIndex() + { + return $this->hostIndex; + } + + /** + * @return Configuration + */ + public function getConfig() + { + return $this->config; + } + + /** + * Operation apiSettingsAssignmentValidationGet + * + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiSettingsAssignmentValidationGet'] to see the possible values for this operation + * + * @throws \OmsorgCoreClient\ApiException on non-2xx response or if the response body is not in the expected format + * @throws \InvalidArgumentException + * @return \OmsorgCoreClient\Model\AssignmentValidationSettingsResponse + */ + public function apiSettingsAssignmentValidationGet(string $contentType = self::contentTypes['apiSettingsAssignmentValidationGet'][0]) + { + list($response) = $this->apiSettingsAssignmentValidationGetWithHttpInfo($contentType); + return $response; + } + + /** + * Operation apiSettingsAssignmentValidationGetWithHttpInfo + * + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiSettingsAssignmentValidationGet'] to see the possible values for this operation + * + * @throws \OmsorgCoreClient\ApiException on non-2xx response or if the response body is not in the expected format + * @throws \InvalidArgumentException + * @return array of \OmsorgCoreClient\Model\AssignmentValidationSettingsResponse, HTTP status code, HTTP response headers (array of strings) + */ + public function apiSettingsAssignmentValidationGetWithHttpInfo(string $contentType = self::contentTypes['apiSettingsAssignmentValidationGet'][0]) + { + $request = $this->apiSettingsAssignmentValidationGetRequest($contentType); + + try { + $options = $this->createHttpClientOption(); + try { + $response = $this->client->send($request, $options); + } catch (RequestException $e) { + throw new ApiException( + "[{$e->getCode()}] {$e->getMessage()}", + (int) $e->getCode(), + $e->getResponse() ? $e->getResponse()->getHeaders() : null, + $e->getResponse() ? (string) $e->getResponse()->getBody() : null + ); + } catch (ConnectException $e) { + throw new ApiException( + "[{$e->getCode()}] {$e->getMessage()}", + (int) $e->getCode(), + null, + null + ); + } + + $statusCode = $response->getStatusCode(); + + + switch($statusCode) { + case 200: + return $this->handleResponseWithDataType( + '\OmsorgCoreClient\Model\AssignmentValidationSettingsResponse', + $request, + $response, + ); + } + + + + if ($statusCode < 200 || $statusCode > 299) { + throw new ApiException( + sprintf( + '[%d] Error connecting to the API (%s)', + $statusCode, + (string) $request->getUri() + ), + $statusCode, + $response->getHeaders(), + (string) $response->getBody() + ); + } + + return $this->handleResponseWithDataType( + '\OmsorgCoreClient\Model\AssignmentValidationSettingsResponse', + $request, + $response, + ); + } catch (ApiException $e) { + switch ($e->getCode()) { + case 200: + $data = ObjectSerializer::deserialize( + $e->getResponseBody(), + '\OmsorgCoreClient\Model\AssignmentValidationSettingsResponse', + $e->getResponseHeaders() + ); + $e->setResponseObject($data); + throw $e; + } + + + throw $e; + } + } + + /** + * Operation apiSettingsAssignmentValidationGetAsync + * + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiSettingsAssignmentValidationGet'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Promise\PromiseInterface + */ + public function apiSettingsAssignmentValidationGetAsync(string $contentType = self::contentTypes['apiSettingsAssignmentValidationGet'][0]) + { + return $this->apiSettingsAssignmentValidationGetAsyncWithHttpInfo($contentType) + ->then( + function ($response) { + return $response[0]; + } + ); + } + + /** + * Operation apiSettingsAssignmentValidationGetAsyncWithHttpInfo + * + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiSettingsAssignmentValidationGet'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Promise\PromiseInterface + */ + public function apiSettingsAssignmentValidationGetAsyncWithHttpInfo(string $contentType = self::contentTypes['apiSettingsAssignmentValidationGet'][0]) + { + $returnType = '\OmsorgCoreClient\Model\AssignmentValidationSettingsResponse'; + $request = $this->apiSettingsAssignmentValidationGetRequest($contentType); + + return $this->client + ->sendAsync($request, $this->createHttpClientOption()) + ->then( + function ($response) use ($returnType) { + if ($returnType === '\SplFileObject') { + $content = $response->getBody(); //stream goes to serializer + } else { + $content = (string) $response->getBody(); + if ($returnType !== 'string') { + $content = json_decode($content); + } + } + + return [ + ObjectSerializer::deserialize($content, $returnType, []), + $response->getStatusCode(), + $response->getHeaders() + ]; + }, + function ($exception) { + $response = $exception->getResponse(); + $statusCode = $response->getStatusCode(); + throw new ApiException( + sprintf( + '[%d] Error connecting to the API (%s)', + $statusCode, + $exception->getRequest()->getUri() + ), + $statusCode, + $response->getHeaders(), + (string) $response->getBody() + ); + } + ); + } + + /** + * Create request for operation 'apiSettingsAssignmentValidationGet' + * + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiSettingsAssignmentValidationGet'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Psr7\Request + */ + public function apiSettingsAssignmentValidationGetRequest(string $contentType = self::contentTypes['apiSettingsAssignmentValidationGet'][0]) + { + + + $resourcePath = '/api/settings/assignment-validation'; + $formParams = []; + $queryParams = []; + $headerParams = []; + $httpBody = ''; + $multipart = false; + + + + + + $headers = $this->headerSelector->selectHeaders( + ['text/plain', 'application/json', 'text/json', ], + $contentType, + $multipart + ); + + // for model (json/xml) + if (count($formParams) > 0) { + if ($multipart) { + $multipartContents = []; + foreach ($formParams as $formParamName => $formParamValue) { + $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue]; + foreach ($formParamValueItems as $formParamValueItem) { + $multipartContents[] = [ + 'name' => $formParamName, + 'contents' => $formParamValueItem + ]; + } + } + // for HTTP post (form) + $httpBody = new MultipartStream($multipartContents); + + } elseif (stripos($headers['Content-Type'], 'application/json') !== false) { + # if Content-Type contains "application/json", json_encode the form parameters + $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams); + } else { + // for HTTP post (form) + $httpBody = ObjectSerializer::buildQuery($formParams); + } + } + + // this endpoint requires Bearer (JWT) authentication (access token) + if (!empty($this->config->getAccessToken())) { + $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken(); + } + + $defaultHeaders = []; + if ($this->config->getUserAgent()) { + $defaultHeaders['User-Agent'] = $this->config->getUserAgent(); + } + + $headers = array_merge( + $defaultHeaders, + $headerParams, + $headers + ); + + $operationHost = $this->config->getHost(); + $query = ObjectSerializer::buildQuery($queryParams); + return new Request( + 'GET', + $operationHost . $resourcePath . ($query ? "?{$query}" : ''), + $headers, + $httpBody + ); + } + + /** + * Operation apiSettingsAssignmentValidationPut + * + * @param \OmsorgCoreClient\Model\UpdateAssignmentValidationSettingsRequest|null $update_assignment_validation_settings_request update_assignment_validation_settings_request (optional) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiSettingsAssignmentValidationPut'] to see the possible values for this operation + * + * @throws \OmsorgCoreClient\ApiException on non-2xx response or if the response body is not in the expected format + * @throws \InvalidArgumentException + * @return \OmsorgCoreClient\Model\AssignmentValidationSettingsResponse + */ + public function apiSettingsAssignmentValidationPut($update_assignment_validation_settings_request = null, string $contentType = self::contentTypes['apiSettingsAssignmentValidationPut'][0]) + { + list($response) = $this->apiSettingsAssignmentValidationPutWithHttpInfo($update_assignment_validation_settings_request, $contentType); + return $response; + } + + /** + * Operation apiSettingsAssignmentValidationPutWithHttpInfo + * + * @param \OmsorgCoreClient\Model\UpdateAssignmentValidationSettingsRequest|null $update_assignment_validation_settings_request (optional) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiSettingsAssignmentValidationPut'] to see the possible values for this operation + * + * @throws \OmsorgCoreClient\ApiException on non-2xx response or if the response body is not in the expected format + * @throws \InvalidArgumentException + * @return array of \OmsorgCoreClient\Model\AssignmentValidationSettingsResponse, HTTP status code, HTTP response headers (array of strings) + */ + public function apiSettingsAssignmentValidationPutWithHttpInfo($update_assignment_validation_settings_request = null, string $contentType = self::contentTypes['apiSettingsAssignmentValidationPut'][0]) + { + $request = $this->apiSettingsAssignmentValidationPutRequest($update_assignment_validation_settings_request, $contentType); + + try { + $options = $this->createHttpClientOption(); + try { + $response = $this->client->send($request, $options); + } catch (RequestException $e) { + throw new ApiException( + "[{$e->getCode()}] {$e->getMessage()}", + (int) $e->getCode(), + $e->getResponse() ? $e->getResponse()->getHeaders() : null, + $e->getResponse() ? (string) $e->getResponse()->getBody() : null + ); + } catch (ConnectException $e) { + throw new ApiException( + "[{$e->getCode()}] {$e->getMessage()}", + (int) $e->getCode(), + null, + null + ); + } + + $statusCode = $response->getStatusCode(); + + + switch($statusCode) { + case 200: + return $this->handleResponseWithDataType( + '\OmsorgCoreClient\Model\AssignmentValidationSettingsResponse', + $request, + $response, + ); + } + + + + if ($statusCode < 200 || $statusCode > 299) { + throw new ApiException( + sprintf( + '[%d] Error connecting to the API (%s)', + $statusCode, + (string) $request->getUri() + ), + $statusCode, + $response->getHeaders(), + (string) $response->getBody() + ); + } + + return $this->handleResponseWithDataType( + '\OmsorgCoreClient\Model\AssignmentValidationSettingsResponse', + $request, + $response, + ); + } catch (ApiException $e) { + switch ($e->getCode()) { + case 200: + $data = ObjectSerializer::deserialize( + $e->getResponseBody(), + '\OmsorgCoreClient\Model\AssignmentValidationSettingsResponse', + $e->getResponseHeaders() + ); + $e->setResponseObject($data); + throw $e; + } + + + throw $e; + } + } + + /** + * Operation apiSettingsAssignmentValidationPutAsync + * + * @param \OmsorgCoreClient\Model\UpdateAssignmentValidationSettingsRequest|null $update_assignment_validation_settings_request (optional) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiSettingsAssignmentValidationPut'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Promise\PromiseInterface + */ + public function apiSettingsAssignmentValidationPutAsync($update_assignment_validation_settings_request = null, string $contentType = self::contentTypes['apiSettingsAssignmentValidationPut'][0]) + { + return $this->apiSettingsAssignmentValidationPutAsyncWithHttpInfo($update_assignment_validation_settings_request, $contentType) + ->then( + function ($response) { + return $response[0]; + } + ); + } + + /** + * Operation apiSettingsAssignmentValidationPutAsyncWithHttpInfo + * + * @param \OmsorgCoreClient\Model\UpdateAssignmentValidationSettingsRequest|null $update_assignment_validation_settings_request (optional) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiSettingsAssignmentValidationPut'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Promise\PromiseInterface + */ + public function apiSettingsAssignmentValidationPutAsyncWithHttpInfo($update_assignment_validation_settings_request = null, string $contentType = self::contentTypes['apiSettingsAssignmentValidationPut'][0]) + { + $returnType = '\OmsorgCoreClient\Model\AssignmentValidationSettingsResponse'; + $request = $this->apiSettingsAssignmentValidationPutRequest($update_assignment_validation_settings_request, $contentType); + + return $this->client + ->sendAsync($request, $this->createHttpClientOption()) + ->then( + function ($response) use ($returnType) { + if ($returnType === '\SplFileObject') { + $content = $response->getBody(); //stream goes to serializer + } else { + $content = (string) $response->getBody(); + if ($returnType !== 'string') { + $content = json_decode($content); + } + } + + return [ + ObjectSerializer::deserialize($content, $returnType, []), + $response->getStatusCode(), + $response->getHeaders() + ]; + }, + function ($exception) { + $response = $exception->getResponse(); + $statusCode = $response->getStatusCode(); + throw new ApiException( + sprintf( + '[%d] Error connecting to the API (%s)', + $statusCode, + $exception->getRequest()->getUri() + ), + $statusCode, + $response->getHeaders(), + (string) $response->getBody() + ); + } + ); + } + + /** + * Create request for operation 'apiSettingsAssignmentValidationPut' + * + * @param \OmsorgCoreClient\Model\UpdateAssignmentValidationSettingsRequest|null $update_assignment_validation_settings_request (optional) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiSettingsAssignmentValidationPut'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Psr7\Request + */ + public function apiSettingsAssignmentValidationPutRequest($update_assignment_validation_settings_request = null, string $contentType = self::contentTypes['apiSettingsAssignmentValidationPut'][0]) + { + + + + $resourcePath = '/api/settings/assignment-validation'; + $formParams = []; + $queryParams = []; + $headerParams = []; + $httpBody = ''; + $multipart = false; + + + + + + $headers = $this->headerSelector->selectHeaders( + ['text/plain', 'application/json', 'text/json', ], + $contentType, + $multipart + ); + + // for model (json/xml) + if (isset($update_assignment_validation_settings_request)) { + if (stripos($headers['Content-Type'], 'application/json') !== false) { + # if Content-Type contains "application/json", json_encode the body + $httpBody = \GuzzleHttp\Utils::jsonEncode(ObjectSerializer::sanitizeForSerialization($update_assignment_validation_settings_request)); + } else { + $httpBody = $update_assignment_validation_settings_request; + } + } elseif (count($formParams) > 0) { + if ($multipart) { + $multipartContents = []; + foreach ($formParams as $formParamName => $formParamValue) { + $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue]; + foreach ($formParamValueItems as $formParamValueItem) { + $multipartContents[] = [ + 'name' => $formParamName, + 'contents' => $formParamValueItem + ]; + } + } + // for HTTP post (form) + $httpBody = new MultipartStream($multipartContents); + + } elseif (stripos($headers['Content-Type'], 'application/json') !== false) { + # if Content-Type contains "application/json", json_encode the form parameters + $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams); + } else { + // for HTTP post (form) + $httpBody = ObjectSerializer::buildQuery($formParams); + } + } + + // this endpoint requires Bearer (JWT) authentication (access token) + if (!empty($this->config->getAccessToken())) { + $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken(); + } + + $defaultHeaders = []; + if ($this->config->getUserAgent()) { + $defaultHeaders['User-Agent'] = $this->config->getUserAgent(); + } + + $headers = array_merge( + $defaultHeaders, + $headerParams, + $headers + ); + + $operationHost = $this->config->getHost(); + $query = ObjectSerializer::buildQuery($queryParams); + return new Request( + 'PUT', + $operationHost . $resourcePath . ($query ? "?{$query}" : ''), + $headers, + $httpBody + ); + } + + /** + * Create http client option + * + * @throws \RuntimeException on file opening failure + * @return array of http client options + */ + protected function createHttpClientOption() + { + $options = []; + if ($this->config->getDebug()) { + $options[RequestOptions::DEBUG] = fopen($this->config->getDebugFile(), 'a'); + if (!$options[RequestOptions::DEBUG]) { + throw new \RuntimeException('Failed to open the debug file: ' . $this->config->getDebugFile()); + } + } + + return $options; + } + + private function handleResponseWithDataType( + string $dataType, + RequestInterface $request, + ResponseInterface $response + ): array { + if ($dataType === '\SplFileObject') { + $content = $response->getBody(); //stream goes to serializer + } else { + $content = (string) $response->getBody(); + if ($dataType !== 'string') { + try { + $content = json_decode($content, false, 512, JSON_THROW_ON_ERROR); + } catch (\JsonException $exception) { + throw new ApiException( + sprintf( + 'Error JSON decoding server response (%s)', + $request->getUri() + ), + $response->getStatusCode(), + $response->getHeaders(), + $content + ); + } + } + } + + return [ + ObjectSerializer::deserialize($content, $dataType, []), + $response->getStatusCode(), + $response->getHeaders() + ]; + } + + private function responseWithinRangeCode( + string $rangeCode, + int $statusCode + ): bool { + $left = (int) ($rangeCode[0].'00'); + $right = (int) ($rangeCode[0].'99'); + + return $statusCode >= $left && $statusCode <= $right; + } +} diff --git a/omsorgWeb/mitarbeiter-app/api-client-php/lib/Api/AssignmentsApi.php b/omsorgWeb/mitarbeiter-app/api-client-php/lib/Api/AssignmentsApi.php new file mode 100644 index 0000000..3d99df1 --- /dev/null +++ b/omsorgWeb/mitarbeiter-app/api-client-php/lib/Api/AssignmentsApi.php @@ -0,0 +1,1873 @@ + [ + 'application/json', + ], + 'apiAssignmentsGet' => [ + 'application/json', + ], + 'apiAssignmentsIdDelete' => [ + 'application/json', + ], + 'apiAssignmentsIdGet' => [ + 'application/json', + ], + 'apiAssignmentsIdPut' => [ + 'application/json', + 'text/json', + 'application/*+json', + ], + 'apiAssignmentsPost' => [ + 'application/json', + 'text/json', + 'application/*+json', + ], + ]; + + /** + * @param ClientInterface $client + * @param Configuration $config + * @param HeaderSelector $selector + * @param int $hostIndex (Optional) host index to select the list of hosts if defined in the OpenAPI spec + */ + public function __construct( + ?ClientInterface $client = null, + ?Configuration $config = null, + ?HeaderSelector $selector = null, + int $hostIndex = 0 + ) { + $this->client = $client ?: new Client(); + $this->config = $config ?: Configuration::getDefaultConfiguration(); + $this->headerSelector = $selector ?: new HeaderSelector(); + $this->hostIndex = $hostIndex; + } + + /** + * Set the host index + * + * @param int $hostIndex Host index (required) + */ + public function setHostIndex($hostIndex): void + { + $this->hostIndex = $hostIndex; + } + + /** + * Get the host index + * + * @return int Host index + */ + public function getHostIndex() + { + return $this->hostIndex; + } + + /** + * @return Configuration + */ + public function getConfig() + { + return $this->config; + } + + /** + * Operation apiAssignmentsCheckGet + * + * @param string|null $order_id order_id (optional) + * @param string|null $employee_id employee_id (optional) + * @param \DateTime|null $start_date start_date (optional) + * @param \DateTime|null $end_date end_date (optional) + * @param string|null $exclude_assignment_id exclude_assignment_id (optional) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiAssignmentsCheckGet'] to see the possible values for this operation + * + * @throws \OmsorgCoreClient\ApiException on non-2xx response or if the response body is not in the expected format + * @throws \InvalidArgumentException + * @return \OmsorgCoreClient\Model\AssignmentConflictResponse[] + */ + public function apiAssignmentsCheckGet($order_id = null, $employee_id = null, $start_date = null, $end_date = null, $exclude_assignment_id = null, string $contentType = self::contentTypes['apiAssignmentsCheckGet'][0]) + { + list($response) = $this->apiAssignmentsCheckGetWithHttpInfo($order_id, $employee_id, $start_date, $end_date, $exclude_assignment_id, $contentType); + return $response; + } + + /** + * Operation apiAssignmentsCheckGetWithHttpInfo + * + * @param string|null $order_id (optional) + * @param string|null $employee_id (optional) + * @param \DateTime|null $start_date (optional) + * @param \DateTime|null $end_date (optional) + * @param string|null $exclude_assignment_id (optional) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiAssignmentsCheckGet'] to see the possible values for this operation + * + * @throws \OmsorgCoreClient\ApiException on non-2xx response or if the response body is not in the expected format + * @throws \InvalidArgumentException + * @return array of \OmsorgCoreClient\Model\AssignmentConflictResponse[], HTTP status code, HTTP response headers (array of strings) + */ + public function apiAssignmentsCheckGetWithHttpInfo($order_id = null, $employee_id = null, $start_date = null, $end_date = null, $exclude_assignment_id = null, string $contentType = self::contentTypes['apiAssignmentsCheckGet'][0]) + { + $request = $this->apiAssignmentsCheckGetRequest($order_id, $employee_id, $start_date, $end_date, $exclude_assignment_id, $contentType); + + try { + $options = $this->createHttpClientOption(); + try { + $response = $this->client->send($request, $options); + } catch (RequestException $e) { + throw new ApiException( + "[{$e->getCode()}] {$e->getMessage()}", + (int) $e->getCode(), + $e->getResponse() ? $e->getResponse()->getHeaders() : null, + $e->getResponse() ? (string) $e->getResponse()->getBody() : null + ); + } catch (ConnectException $e) { + throw new ApiException( + "[{$e->getCode()}] {$e->getMessage()}", + (int) $e->getCode(), + null, + null + ); + } + + $statusCode = $response->getStatusCode(); + + + switch($statusCode) { + case 200: + return $this->handleResponseWithDataType( + '\OmsorgCoreClient\Model\AssignmentConflictResponse[]', + $request, + $response, + ); + } + + + + if ($statusCode < 200 || $statusCode > 299) { + throw new ApiException( + sprintf( + '[%d] Error connecting to the API (%s)', + $statusCode, + (string) $request->getUri() + ), + $statusCode, + $response->getHeaders(), + (string) $response->getBody() + ); + } + + return $this->handleResponseWithDataType( + '\OmsorgCoreClient\Model\AssignmentConflictResponse[]', + $request, + $response, + ); + } catch (ApiException $e) { + switch ($e->getCode()) { + case 200: + $data = ObjectSerializer::deserialize( + $e->getResponseBody(), + '\OmsorgCoreClient\Model\AssignmentConflictResponse[]', + $e->getResponseHeaders() + ); + $e->setResponseObject($data); + throw $e; + } + + + throw $e; + } + } + + /** + * Operation apiAssignmentsCheckGetAsync + * + * @param string|null $order_id (optional) + * @param string|null $employee_id (optional) + * @param \DateTime|null $start_date (optional) + * @param \DateTime|null $end_date (optional) + * @param string|null $exclude_assignment_id (optional) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiAssignmentsCheckGet'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Promise\PromiseInterface + */ + public function apiAssignmentsCheckGetAsync($order_id = null, $employee_id = null, $start_date = null, $end_date = null, $exclude_assignment_id = null, string $contentType = self::contentTypes['apiAssignmentsCheckGet'][0]) + { + return $this->apiAssignmentsCheckGetAsyncWithHttpInfo($order_id, $employee_id, $start_date, $end_date, $exclude_assignment_id, $contentType) + ->then( + function ($response) { + return $response[0]; + } + ); + } + + /** + * Operation apiAssignmentsCheckGetAsyncWithHttpInfo + * + * @param string|null $order_id (optional) + * @param string|null $employee_id (optional) + * @param \DateTime|null $start_date (optional) + * @param \DateTime|null $end_date (optional) + * @param string|null $exclude_assignment_id (optional) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiAssignmentsCheckGet'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Promise\PromiseInterface + */ + public function apiAssignmentsCheckGetAsyncWithHttpInfo($order_id = null, $employee_id = null, $start_date = null, $end_date = null, $exclude_assignment_id = null, string $contentType = self::contentTypes['apiAssignmentsCheckGet'][0]) + { + $returnType = '\OmsorgCoreClient\Model\AssignmentConflictResponse[]'; + $request = $this->apiAssignmentsCheckGetRequest($order_id, $employee_id, $start_date, $end_date, $exclude_assignment_id, $contentType); + + return $this->client + ->sendAsync($request, $this->createHttpClientOption()) + ->then( + function ($response) use ($returnType) { + if ($returnType === '\SplFileObject') { + $content = $response->getBody(); //stream goes to serializer + } else { + $content = (string) $response->getBody(); + if ($returnType !== 'string') { + $content = json_decode($content); + } + } + + return [ + ObjectSerializer::deserialize($content, $returnType, []), + $response->getStatusCode(), + $response->getHeaders() + ]; + }, + function ($exception) { + $response = $exception->getResponse(); + $statusCode = $response->getStatusCode(); + throw new ApiException( + sprintf( + '[%d] Error connecting to the API (%s)', + $statusCode, + $exception->getRequest()->getUri() + ), + $statusCode, + $response->getHeaders(), + (string) $response->getBody() + ); + } + ); + } + + /** + * Create request for operation 'apiAssignmentsCheckGet' + * + * @param string|null $order_id (optional) + * @param string|null $employee_id (optional) + * @param \DateTime|null $start_date (optional) + * @param \DateTime|null $end_date (optional) + * @param string|null $exclude_assignment_id (optional) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiAssignmentsCheckGet'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Psr7\Request + */ + public function apiAssignmentsCheckGetRequest($order_id = null, $employee_id = null, $start_date = null, $end_date = null, $exclude_assignment_id = null, string $contentType = self::contentTypes['apiAssignmentsCheckGet'][0]) + { + + + + + + + + $resourcePath = '/api/assignments/check'; + $formParams = []; + $queryParams = []; + $headerParams = []; + $httpBody = ''; + $multipart = false; + + // query params + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $order_id, + 'orderId', // param base name + 'string', // openApiType + 'form', // style + true, // explode + false // required + ) ?? []); + // query params + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $employee_id, + 'employeeId', // param base name + 'string', // openApiType + 'form', // style + true, // explode + false // required + ) ?? []); + // query params + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $start_date, + 'startDate', // param base name + 'string', // openApiType + 'form', // style + true, // explode + false // required + ) ?? []); + // query params + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $end_date, + 'endDate', // param base name + 'string', // openApiType + 'form', // style + true, // explode + false // required + ) ?? []); + // query params + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $exclude_assignment_id, + 'excludeAssignmentId', // param base name + 'string', // openApiType + 'form', // style + true, // explode + false // required + ) ?? []); + + + + + $headers = $this->headerSelector->selectHeaders( + ['text/plain', 'application/json', 'text/json', ], + $contentType, + $multipart + ); + + // for model (json/xml) + if (count($formParams) > 0) { + if ($multipart) { + $multipartContents = []; + foreach ($formParams as $formParamName => $formParamValue) { + $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue]; + foreach ($formParamValueItems as $formParamValueItem) { + $multipartContents[] = [ + 'name' => $formParamName, + 'contents' => $formParamValueItem + ]; + } + } + // for HTTP post (form) + $httpBody = new MultipartStream($multipartContents); + + } elseif (stripos($headers['Content-Type'], 'application/json') !== false) { + # if Content-Type contains "application/json", json_encode the form parameters + $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams); + } else { + // for HTTP post (form) + $httpBody = ObjectSerializer::buildQuery($formParams); + } + } + + // this endpoint requires Bearer (JWT) authentication (access token) + if (!empty($this->config->getAccessToken())) { + $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken(); + } + + $defaultHeaders = []; + if ($this->config->getUserAgent()) { + $defaultHeaders['User-Agent'] = $this->config->getUserAgent(); + } + + $headers = array_merge( + $defaultHeaders, + $headerParams, + $headers + ); + + $operationHost = $this->config->getHost(); + $query = ObjectSerializer::buildQuery($queryParams); + return new Request( + 'GET', + $operationHost . $resourcePath . ($query ? "?{$query}" : ''), + $headers, + $httpBody + ); + } + + /** + * Operation apiAssignmentsGet + * + * @param string|null $order_id order_id (optional) + * @param string|null $employee_id employee_id (optional) + * @param \DateTime|null $from_date from_date (optional) + * @param \DateTime|null $to_date to_date (optional) + * @param int|null $page page (optional, default to 1) + * @param int|null $page_size page_size (optional, default to 20) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiAssignmentsGet'] to see the possible values for this operation + * + * @throws \OmsorgCoreClient\ApiException on non-2xx response or if the response body is not in the expected format + * @throws \InvalidArgumentException + * @return \OmsorgCoreClient\Model\AssignmentResponsePagedResponse + */ + public function apiAssignmentsGet($order_id = null, $employee_id = null, $from_date = null, $to_date = null, $page = 1, $page_size = 20, string $contentType = self::contentTypes['apiAssignmentsGet'][0]) + { + list($response) = $this->apiAssignmentsGetWithHttpInfo($order_id, $employee_id, $from_date, $to_date, $page, $page_size, $contentType); + return $response; + } + + /** + * Operation apiAssignmentsGetWithHttpInfo + * + * @param string|null $order_id (optional) + * @param string|null $employee_id (optional) + * @param \DateTime|null $from_date (optional) + * @param \DateTime|null $to_date (optional) + * @param int|null $page (optional, default to 1) + * @param int|null $page_size (optional, default to 20) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiAssignmentsGet'] to see the possible values for this operation + * + * @throws \OmsorgCoreClient\ApiException on non-2xx response or if the response body is not in the expected format + * @throws \InvalidArgumentException + * @return array of \OmsorgCoreClient\Model\AssignmentResponsePagedResponse, HTTP status code, HTTP response headers (array of strings) + */ + public function apiAssignmentsGetWithHttpInfo($order_id = null, $employee_id = null, $from_date = null, $to_date = null, $page = 1, $page_size = 20, string $contentType = self::contentTypes['apiAssignmentsGet'][0]) + { + $request = $this->apiAssignmentsGetRequest($order_id, $employee_id, $from_date, $to_date, $page, $page_size, $contentType); + + try { + $options = $this->createHttpClientOption(); + try { + $response = $this->client->send($request, $options); + } catch (RequestException $e) { + throw new ApiException( + "[{$e->getCode()}] {$e->getMessage()}", + (int) $e->getCode(), + $e->getResponse() ? $e->getResponse()->getHeaders() : null, + $e->getResponse() ? (string) $e->getResponse()->getBody() : null + ); + } catch (ConnectException $e) { + throw new ApiException( + "[{$e->getCode()}] {$e->getMessage()}", + (int) $e->getCode(), + null, + null + ); + } + + $statusCode = $response->getStatusCode(); + + + switch($statusCode) { + case 200: + return $this->handleResponseWithDataType( + '\OmsorgCoreClient\Model\AssignmentResponsePagedResponse', + $request, + $response, + ); + } + + + + if ($statusCode < 200 || $statusCode > 299) { + throw new ApiException( + sprintf( + '[%d] Error connecting to the API (%s)', + $statusCode, + (string) $request->getUri() + ), + $statusCode, + $response->getHeaders(), + (string) $response->getBody() + ); + } + + return $this->handleResponseWithDataType( + '\OmsorgCoreClient\Model\AssignmentResponsePagedResponse', + $request, + $response, + ); + } catch (ApiException $e) { + switch ($e->getCode()) { + case 200: + $data = ObjectSerializer::deserialize( + $e->getResponseBody(), + '\OmsorgCoreClient\Model\AssignmentResponsePagedResponse', + $e->getResponseHeaders() + ); + $e->setResponseObject($data); + throw $e; + } + + + throw $e; + } + } + + /** + * Operation apiAssignmentsGetAsync + * + * @param string|null $order_id (optional) + * @param string|null $employee_id (optional) + * @param \DateTime|null $from_date (optional) + * @param \DateTime|null $to_date (optional) + * @param int|null $page (optional, default to 1) + * @param int|null $page_size (optional, default to 20) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiAssignmentsGet'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Promise\PromiseInterface + */ + public function apiAssignmentsGetAsync($order_id = null, $employee_id = null, $from_date = null, $to_date = null, $page = 1, $page_size = 20, string $contentType = self::contentTypes['apiAssignmentsGet'][0]) + { + return $this->apiAssignmentsGetAsyncWithHttpInfo($order_id, $employee_id, $from_date, $to_date, $page, $page_size, $contentType) + ->then( + function ($response) { + return $response[0]; + } + ); + } + + /** + * Operation apiAssignmentsGetAsyncWithHttpInfo + * + * @param string|null $order_id (optional) + * @param string|null $employee_id (optional) + * @param \DateTime|null $from_date (optional) + * @param \DateTime|null $to_date (optional) + * @param int|null $page (optional, default to 1) + * @param int|null $page_size (optional, default to 20) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiAssignmentsGet'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Promise\PromiseInterface + */ + public function apiAssignmentsGetAsyncWithHttpInfo($order_id = null, $employee_id = null, $from_date = null, $to_date = null, $page = 1, $page_size = 20, string $contentType = self::contentTypes['apiAssignmentsGet'][0]) + { + $returnType = '\OmsorgCoreClient\Model\AssignmentResponsePagedResponse'; + $request = $this->apiAssignmentsGetRequest($order_id, $employee_id, $from_date, $to_date, $page, $page_size, $contentType); + + return $this->client + ->sendAsync($request, $this->createHttpClientOption()) + ->then( + function ($response) use ($returnType) { + if ($returnType === '\SplFileObject') { + $content = $response->getBody(); //stream goes to serializer + } else { + $content = (string) $response->getBody(); + if ($returnType !== 'string') { + $content = json_decode($content); + } + } + + return [ + ObjectSerializer::deserialize($content, $returnType, []), + $response->getStatusCode(), + $response->getHeaders() + ]; + }, + function ($exception) { + $response = $exception->getResponse(); + $statusCode = $response->getStatusCode(); + throw new ApiException( + sprintf( + '[%d] Error connecting to the API (%s)', + $statusCode, + $exception->getRequest()->getUri() + ), + $statusCode, + $response->getHeaders(), + (string) $response->getBody() + ); + } + ); + } + + /** + * Create request for operation 'apiAssignmentsGet' + * + * @param string|null $order_id (optional) + * @param string|null $employee_id (optional) + * @param \DateTime|null $from_date (optional) + * @param \DateTime|null $to_date (optional) + * @param int|null $page (optional, default to 1) + * @param int|null $page_size (optional, default to 20) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiAssignmentsGet'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Psr7\Request + */ + public function apiAssignmentsGetRequest($order_id = null, $employee_id = null, $from_date = null, $to_date = null, $page = 1, $page_size = 20, string $contentType = self::contentTypes['apiAssignmentsGet'][0]) + { + + + + + + + + + $resourcePath = '/api/assignments'; + $formParams = []; + $queryParams = []; + $headerParams = []; + $httpBody = ''; + $multipart = false; + + // query params + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $order_id, + 'orderId', // param base name + 'string', // openApiType + 'form', // style + true, // explode + false // required + ) ?? []); + // query params + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $employee_id, + 'employeeId', // param base name + 'string', // openApiType + 'form', // style + true, // explode + false // required + ) ?? []); + // query params + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $from_date, + 'fromDate', // param base name + 'string', // openApiType + 'form', // style + true, // explode + false // required + ) ?? []); + // query params + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $to_date, + 'toDate', // param base name + 'string', // openApiType + 'form', // style + true, // explode + false // required + ) ?? []); + // query params + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $page, + 'page', // param base name + 'integer', // openApiType + 'form', // style + true, // explode + false // required + ) ?? []); + // query params + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $page_size, + 'pageSize', // param base name + 'integer', // openApiType + 'form', // style + true, // explode + false // required + ) ?? []); + + + + + $headers = $this->headerSelector->selectHeaders( + ['text/plain', 'application/json', 'text/json', ], + $contentType, + $multipart + ); + + // for model (json/xml) + if (count($formParams) > 0) { + if ($multipart) { + $multipartContents = []; + foreach ($formParams as $formParamName => $formParamValue) { + $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue]; + foreach ($formParamValueItems as $formParamValueItem) { + $multipartContents[] = [ + 'name' => $formParamName, + 'contents' => $formParamValueItem + ]; + } + } + // for HTTP post (form) + $httpBody = new MultipartStream($multipartContents); + + } elseif (stripos($headers['Content-Type'], 'application/json') !== false) { + # if Content-Type contains "application/json", json_encode the form parameters + $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams); + } else { + // for HTTP post (form) + $httpBody = ObjectSerializer::buildQuery($formParams); + } + } + + // this endpoint requires Bearer (JWT) authentication (access token) + if (!empty($this->config->getAccessToken())) { + $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken(); + } + + $defaultHeaders = []; + if ($this->config->getUserAgent()) { + $defaultHeaders['User-Agent'] = $this->config->getUserAgent(); + } + + $headers = array_merge( + $defaultHeaders, + $headerParams, + $headers + ); + + $operationHost = $this->config->getHost(); + $query = ObjectSerializer::buildQuery($queryParams); + return new Request( + 'GET', + $operationHost . $resourcePath . ($query ? "?{$query}" : ''), + $headers, + $httpBody + ); + } + + /** + * Operation apiAssignmentsIdDelete + * + * @param string $id id (required) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiAssignmentsIdDelete'] to see the possible values for this operation + * + * @throws \OmsorgCoreClient\ApiException on non-2xx response or if the response body is not in the expected format + * @throws \InvalidArgumentException + * @return void + */ + public function apiAssignmentsIdDelete($id, string $contentType = self::contentTypes['apiAssignmentsIdDelete'][0]) + { + $this->apiAssignmentsIdDeleteWithHttpInfo($id, $contentType); + } + + /** + * Operation apiAssignmentsIdDeleteWithHttpInfo + * + * @param string $id (required) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiAssignmentsIdDelete'] to see the possible values for this operation + * + * @throws \OmsorgCoreClient\ApiException on non-2xx response or if the response body is not in the expected format + * @throws \InvalidArgumentException + * @return array of null, HTTP status code, HTTP response headers (array of strings) + */ + public function apiAssignmentsIdDeleteWithHttpInfo($id, string $contentType = self::contentTypes['apiAssignmentsIdDelete'][0]) + { + $request = $this->apiAssignmentsIdDeleteRequest($id, $contentType); + + try { + $options = $this->createHttpClientOption(); + try { + $response = $this->client->send($request, $options); + } catch (RequestException $e) { + throw new ApiException( + "[{$e->getCode()}] {$e->getMessage()}", + (int) $e->getCode(), + $e->getResponse() ? $e->getResponse()->getHeaders() : null, + $e->getResponse() ? (string) $e->getResponse()->getBody() : null + ); + } catch (ConnectException $e) { + throw new ApiException( + "[{$e->getCode()}] {$e->getMessage()}", + (int) $e->getCode(), + null, + null + ); + } + + $statusCode = $response->getStatusCode(); + + + return [null, $statusCode, $response->getHeaders()]; + } catch (ApiException $e) { + switch ($e->getCode()) { + } + + + throw $e; + } + } + + /** + * Operation apiAssignmentsIdDeleteAsync + * + * @param string $id (required) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiAssignmentsIdDelete'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Promise\PromiseInterface + */ + public function apiAssignmentsIdDeleteAsync($id, string $contentType = self::contentTypes['apiAssignmentsIdDelete'][0]) + { + return $this->apiAssignmentsIdDeleteAsyncWithHttpInfo($id, $contentType) + ->then( + function ($response) { + return $response[0]; + } + ); + } + + /** + * Operation apiAssignmentsIdDeleteAsyncWithHttpInfo + * + * @param string $id (required) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiAssignmentsIdDelete'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Promise\PromiseInterface + */ + public function apiAssignmentsIdDeleteAsyncWithHttpInfo($id, string $contentType = self::contentTypes['apiAssignmentsIdDelete'][0]) + { + $returnType = ''; + $request = $this->apiAssignmentsIdDeleteRequest($id, $contentType); + + return $this->client + ->sendAsync($request, $this->createHttpClientOption()) + ->then( + function ($response) use ($returnType) { + return [null, $response->getStatusCode(), $response->getHeaders()]; + }, + function ($exception) { + $response = $exception->getResponse(); + $statusCode = $response->getStatusCode(); + throw new ApiException( + sprintf( + '[%d] Error connecting to the API (%s)', + $statusCode, + $exception->getRequest()->getUri() + ), + $statusCode, + $response->getHeaders(), + (string) $response->getBody() + ); + } + ); + } + + /** + * Create request for operation 'apiAssignmentsIdDelete' + * + * @param string $id (required) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiAssignmentsIdDelete'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Psr7\Request + */ + public function apiAssignmentsIdDeleteRequest($id, string $contentType = self::contentTypes['apiAssignmentsIdDelete'][0]) + { + + // verify the required parameter 'id' is set + if ($id === null || (is_array($id) && count($id) === 0)) { + throw new \InvalidArgumentException( + 'Missing the required parameter $id when calling apiAssignmentsIdDelete' + ); + } + + + $resourcePath = '/api/assignments/{id}'; + $formParams = []; + $queryParams = []; + $headerParams = []; + $httpBody = ''; + $multipart = false; + + + + // path params + if ($id !== null) { + $resourcePath = str_replace( + '{' . 'id' . '}', + ObjectSerializer::toPathValue($id), + $resourcePath + ); + } + + + $headers = $this->headerSelector->selectHeaders( + [], + $contentType, + $multipart + ); + + // for model (json/xml) + if (count($formParams) > 0) { + if ($multipart) { + $multipartContents = []; + foreach ($formParams as $formParamName => $formParamValue) { + $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue]; + foreach ($formParamValueItems as $formParamValueItem) { + $multipartContents[] = [ + 'name' => $formParamName, + 'contents' => $formParamValueItem + ]; + } + } + // for HTTP post (form) + $httpBody = new MultipartStream($multipartContents); + + } elseif (stripos($headers['Content-Type'], 'application/json') !== false) { + # if Content-Type contains "application/json", json_encode the form parameters + $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams); + } else { + // for HTTP post (form) + $httpBody = ObjectSerializer::buildQuery($formParams); + } + } + + // this endpoint requires Bearer (JWT) authentication (access token) + if (!empty($this->config->getAccessToken())) { + $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken(); + } + + $defaultHeaders = []; + if ($this->config->getUserAgent()) { + $defaultHeaders['User-Agent'] = $this->config->getUserAgent(); + } + + $headers = array_merge( + $defaultHeaders, + $headerParams, + $headers + ); + + $operationHost = $this->config->getHost(); + $query = ObjectSerializer::buildQuery($queryParams); + return new Request( + 'DELETE', + $operationHost . $resourcePath . ($query ? "?{$query}" : ''), + $headers, + $httpBody + ); + } + + /** + * Operation apiAssignmentsIdGet + * + * @param string $id id (required) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiAssignmentsIdGet'] to see the possible values for this operation + * + * @throws \OmsorgCoreClient\ApiException on non-2xx response or if the response body is not in the expected format + * @throws \InvalidArgumentException + * @return \OmsorgCoreClient\Model\AssignmentResponse + */ + public function apiAssignmentsIdGet($id, string $contentType = self::contentTypes['apiAssignmentsIdGet'][0]) + { + list($response) = $this->apiAssignmentsIdGetWithHttpInfo($id, $contentType); + return $response; + } + + /** + * Operation apiAssignmentsIdGetWithHttpInfo + * + * @param string $id (required) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiAssignmentsIdGet'] to see the possible values for this operation + * + * @throws \OmsorgCoreClient\ApiException on non-2xx response or if the response body is not in the expected format + * @throws \InvalidArgumentException + * @return array of \OmsorgCoreClient\Model\AssignmentResponse, HTTP status code, HTTP response headers (array of strings) + */ + public function apiAssignmentsIdGetWithHttpInfo($id, string $contentType = self::contentTypes['apiAssignmentsIdGet'][0]) + { + $request = $this->apiAssignmentsIdGetRequest($id, $contentType); + + try { + $options = $this->createHttpClientOption(); + try { + $response = $this->client->send($request, $options); + } catch (RequestException $e) { + throw new ApiException( + "[{$e->getCode()}] {$e->getMessage()}", + (int) $e->getCode(), + $e->getResponse() ? $e->getResponse()->getHeaders() : null, + $e->getResponse() ? (string) $e->getResponse()->getBody() : null + ); + } catch (ConnectException $e) { + throw new ApiException( + "[{$e->getCode()}] {$e->getMessage()}", + (int) $e->getCode(), + null, + null + ); + } + + $statusCode = $response->getStatusCode(); + + + switch($statusCode) { + case 200: + return $this->handleResponseWithDataType( + '\OmsorgCoreClient\Model\AssignmentResponse', + $request, + $response, + ); + } + + + + if ($statusCode < 200 || $statusCode > 299) { + throw new ApiException( + sprintf( + '[%d] Error connecting to the API (%s)', + $statusCode, + (string) $request->getUri() + ), + $statusCode, + $response->getHeaders(), + (string) $response->getBody() + ); + } + + return $this->handleResponseWithDataType( + '\OmsorgCoreClient\Model\AssignmentResponse', + $request, + $response, + ); + } catch (ApiException $e) { + switch ($e->getCode()) { + case 200: + $data = ObjectSerializer::deserialize( + $e->getResponseBody(), + '\OmsorgCoreClient\Model\AssignmentResponse', + $e->getResponseHeaders() + ); + $e->setResponseObject($data); + throw $e; + } + + + throw $e; + } + } + + /** + * Operation apiAssignmentsIdGetAsync + * + * @param string $id (required) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiAssignmentsIdGet'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Promise\PromiseInterface + */ + public function apiAssignmentsIdGetAsync($id, string $contentType = self::contentTypes['apiAssignmentsIdGet'][0]) + { + return $this->apiAssignmentsIdGetAsyncWithHttpInfo($id, $contentType) + ->then( + function ($response) { + return $response[0]; + } + ); + } + + /** + * Operation apiAssignmentsIdGetAsyncWithHttpInfo + * + * @param string $id (required) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiAssignmentsIdGet'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Promise\PromiseInterface + */ + public function apiAssignmentsIdGetAsyncWithHttpInfo($id, string $contentType = self::contentTypes['apiAssignmentsIdGet'][0]) + { + $returnType = '\OmsorgCoreClient\Model\AssignmentResponse'; + $request = $this->apiAssignmentsIdGetRequest($id, $contentType); + + return $this->client + ->sendAsync($request, $this->createHttpClientOption()) + ->then( + function ($response) use ($returnType) { + if ($returnType === '\SplFileObject') { + $content = $response->getBody(); //stream goes to serializer + } else { + $content = (string) $response->getBody(); + if ($returnType !== 'string') { + $content = json_decode($content); + } + } + + return [ + ObjectSerializer::deserialize($content, $returnType, []), + $response->getStatusCode(), + $response->getHeaders() + ]; + }, + function ($exception) { + $response = $exception->getResponse(); + $statusCode = $response->getStatusCode(); + throw new ApiException( + sprintf( + '[%d] Error connecting to the API (%s)', + $statusCode, + $exception->getRequest()->getUri() + ), + $statusCode, + $response->getHeaders(), + (string) $response->getBody() + ); + } + ); + } + + /** + * Create request for operation 'apiAssignmentsIdGet' + * + * @param string $id (required) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiAssignmentsIdGet'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Psr7\Request + */ + public function apiAssignmentsIdGetRequest($id, string $contentType = self::contentTypes['apiAssignmentsIdGet'][0]) + { + + // verify the required parameter 'id' is set + if ($id === null || (is_array($id) && count($id) === 0)) { + throw new \InvalidArgumentException( + 'Missing the required parameter $id when calling apiAssignmentsIdGet' + ); + } + + + $resourcePath = '/api/assignments/{id}'; + $formParams = []; + $queryParams = []; + $headerParams = []; + $httpBody = ''; + $multipart = false; + + + + // path params + if ($id !== null) { + $resourcePath = str_replace( + '{' . 'id' . '}', + ObjectSerializer::toPathValue($id), + $resourcePath + ); + } + + + $headers = $this->headerSelector->selectHeaders( + ['text/plain', 'application/json', 'text/json', ], + $contentType, + $multipart + ); + + // for model (json/xml) + if (count($formParams) > 0) { + if ($multipart) { + $multipartContents = []; + foreach ($formParams as $formParamName => $formParamValue) { + $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue]; + foreach ($formParamValueItems as $formParamValueItem) { + $multipartContents[] = [ + 'name' => $formParamName, + 'contents' => $formParamValueItem + ]; + } + } + // for HTTP post (form) + $httpBody = new MultipartStream($multipartContents); + + } elseif (stripos($headers['Content-Type'], 'application/json') !== false) { + # if Content-Type contains "application/json", json_encode the form parameters + $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams); + } else { + // for HTTP post (form) + $httpBody = ObjectSerializer::buildQuery($formParams); + } + } + + // this endpoint requires Bearer (JWT) authentication (access token) + if (!empty($this->config->getAccessToken())) { + $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken(); + } + + $defaultHeaders = []; + if ($this->config->getUserAgent()) { + $defaultHeaders['User-Agent'] = $this->config->getUserAgent(); + } + + $headers = array_merge( + $defaultHeaders, + $headerParams, + $headers + ); + + $operationHost = $this->config->getHost(); + $query = ObjectSerializer::buildQuery($queryParams); + return new Request( + 'GET', + $operationHost . $resourcePath . ($query ? "?{$query}" : ''), + $headers, + $httpBody + ); + } + + /** + * Operation apiAssignmentsIdPut + * + * @param string $id id (required) + * @param \OmsorgCoreClient\Model\UpdateAssignmentRequest|null $update_assignment_request update_assignment_request (optional) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiAssignmentsIdPut'] to see the possible values for this operation + * + * @throws \OmsorgCoreClient\ApiException on non-2xx response or if the response body is not in the expected format + * @throws \InvalidArgumentException + * @return \OmsorgCoreClient\Model\AssignmentResponse + */ + public function apiAssignmentsIdPut($id, $update_assignment_request = null, string $contentType = self::contentTypes['apiAssignmentsIdPut'][0]) + { + list($response) = $this->apiAssignmentsIdPutWithHttpInfo($id, $update_assignment_request, $contentType); + return $response; + } + + /** + * Operation apiAssignmentsIdPutWithHttpInfo + * + * @param string $id (required) + * @param \OmsorgCoreClient\Model\UpdateAssignmentRequest|null $update_assignment_request (optional) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiAssignmentsIdPut'] to see the possible values for this operation + * + * @throws \OmsorgCoreClient\ApiException on non-2xx response or if the response body is not in the expected format + * @throws \InvalidArgumentException + * @return array of \OmsorgCoreClient\Model\AssignmentResponse, HTTP status code, HTTP response headers (array of strings) + */ + public function apiAssignmentsIdPutWithHttpInfo($id, $update_assignment_request = null, string $contentType = self::contentTypes['apiAssignmentsIdPut'][0]) + { + $request = $this->apiAssignmentsIdPutRequest($id, $update_assignment_request, $contentType); + + try { + $options = $this->createHttpClientOption(); + try { + $response = $this->client->send($request, $options); + } catch (RequestException $e) { + throw new ApiException( + "[{$e->getCode()}] {$e->getMessage()}", + (int) $e->getCode(), + $e->getResponse() ? $e->getResponse()->getHeaders() : null, + $e->getResponse() ? (string) $e->getResponse()->getBody() : null + ); + } catch (ConnectException $e) { + throw new ApiException( + "[{$e->getCode()}] {$e->getMessage()}", + (int) $e->getCode(), + null, + null + ); + } + + $statusCode = $response->getStatusCode(); + + + switch($statusCode) { + case 200: + return $this->handleResponseWithDataType( + '\OmsorgCoreClient\Model\AssignmentResponse', + $request, + $response, + ); + } + + + + if ($statusCode < 200 || $statusCode > 299) { + throw new ApiException( + sprintf( + '[%d] Error connecting to the API (%s)', + $statusCode, + (string) $request->getUri() + ), + $statusCode, + $response->getHeaders(), + (string) $response->getBody() + ); + } + + return $this->handleResponseWithDataType( + '\OmsorgCoreClient\Model\AssignmentResponse', + $request, + $response, + ); + } catch (ApiException $e) { + switch ($e->getCode()) { + case 200: + $data = ObjectSerializer::deserialize( + $e->getResponseBody(), + '\OmsorgCoreClient\Model\AssignmentResponse', + $e->getResponseHeaders() + ); + $e->setResponseObject($data); + throw $e; + } + + + throw $e; + } + } + + /** + * Operation apiAssignmentsIdPutAsync + * + * @param string $id (required) + * @param \OmsorgCoreClient\Model\UpdateAssignmentRequest|null $update_assignment_request (optional) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiAssignmentsIdPut'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Promise\PromiseInterface + */ + public function apiAssignmentsIdPutAsync($id, $update_assignment_request = null, string $contentType = self::contentTypes['apiAssignmentsIdPut'][0]) + { + return $this->apiAssignmentsIdPutAsyncWithHttpInfo($id, $update_assignment_request, $contentType) + ->then( + function ($response) { + return $response[0]; + } + ); + } + + /** + * Operation apiAssignmentsIdPutAsyncWithHttpInfo + * + * @param string $id (required) + * @param \OmsorgCoreClient\Model\UpdateAssignmentRequest|null $update_assignment_request (optional) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiAssignmentsIdPut'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Promise\PromiseInterface + */ + public function apiAssignmentsIdPutAsyncWithHttpInfo($id, $update_assignment_request = null, string $contentType = self::contentTypes['apiAssignmentsIdPut'][0]) + { + $returnType = '\OmsorgCoreClient\Model\AssignmentResponse'; + $request = $this->apiAssignmentsIdPutRequest($id, $update_assignment_request, $contentType); + + return $this->client + ->sendAsync($request, $this->createHttpClientOption()) + ->then( + function ($response) use ($returnType) { + if ($returnType === '\SplFileObject') { + $content = $response->getBody(); //stream goes to serializer + } else { + $content = (string) $response->getBody(); + if ($returnType !== 'string') { + $content = json_decode($content); + } + } + + return [ + ObjectSerializer::deserialize($content, $returnType, []), + $response->getStatusCode(), + $response->getHeaders() + ]; + }, + function ($exception) { + $response = $exception->getResponse(); + $statusCode = $response->getStatusCode(); + throw new ApiException( + sprintf( + '[%d] Error connecting to the API (%s)', + $statusCode, + $exception->getRequest()->getUri() + ), + $statusCode, + $response->getHeaders(), + (string) $response->getBody() + ); + } + ); + } + + /** + * Create request for operation 'apiAssignmentsIdPut' + * + * @param string $id (required) + * @param \OmsorgCoreClient\Model\UpdateAssignmentRequest|null $update_assignment_request (optional) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiAssignmentsIdPut'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Psr7\Request + */ + public function apiAssignmentsIdPutRequest($id, $update_assignment_request = null, string $contentType = self::contentTypes['apiAssignmentsIdPut'][0]) + { + + // verify the required parameter 'id' is set + if ($id === null || (is_array($id) && count($id) === 0)) { + throw new \InvalidArgumentException( + 'Missing the required parameter $id when calling apiAssignmentsIdPut' + ); + } + + + + $resourcePath = '/api/assignments/{id}'; + $formParams = []; + $queryParams = []; + $headerParams = []; + $httpBody = ''; + $multipart = false; + + + + // path params + if ($id !== null) { + $resourcePath = str_replace( + '{' . 'id' . '}', + ObjectSerializer::toPathValue($id), + $resourcePath + ); + } + + + $headers = $this->headerSelector->selectHeaders( + ['text/plain', 'application/json', 'text/json', ], + $contentType, + $multipart + ); + + // for model (json/xml) + if (isset($update_assignment_request)) { + if (stripos($headers['Content-Type'], 'application/json') !== false) { + # if Content-Type contains "application/json", json_encode the body + $httpBody = \GuzzleHttp\Utils::jsonEncode(ObjectSerializer::sanitizeForSerialization($update_assignment_request)); + } else { + $httpBody = $update_assignment_request; + } + } elseif (count($formParams) > 0) { + if ($multipart) { + $multipartContents = []; + foreach ($formParams as $formParamName => $formParamValue) { + $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue]; + foreach ($formParamValueItems as $formParamValueItem) { + $multipartContents[] = [ + 'name' => $formParamName, + 'contents' => $formParamValueItem + ]; + } + } + // for HTTP post (form) + $httpBody = new MultipartStream($multipartContents); + + } elseif (stripos($headers['Content-Type'], 'application/json') !== false) { + # if Content-Type contains "application/json", json_encode the form parameters + $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams); + } else { + // for HTTP post (form) + $httpBody = ObjectSerializer::buildQuery($formParams); + } + } + + // this endpoint requires Bearer (JWT) authentication (access token) + if (!empty($this->config->getAccessToken())) { + $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken(); + } + + $defaultHeaders = []; + if ($this->config->getUserAgent()) { + $defaultHeaders['User-Agent'] = $this->config->getUserAgent(); + } + + $headers = array_merge( + $defaultHeaders, + $headerParams, + $headers + ); + + $operationHost = $this->config->getHost(); + $query = ObjectSerializer::buildQuery($queryParams); + return new Request( + 'PUT', + $operationHost . $resourcePath . ($query ? "?{$query}" : ''), + $headers, + $httpBody + ); + } + + /** + * Operation apiAssignmentsPost + * + * @param \OmsorgCoreClient\Model\CreateAssignmentRequest|null $create_assignment_request create_assignment_request (optional) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiAssignmentsPost'] to see the possible values for this operation + * + * @throws \OmsorgCoreClient\ApiException on non-2xx response or if the response body is not in the expected format + * @throws \InvalidArgumentException + * @return \OmsorgCoreClient\Model\AssignmentResponse + */ + public function apiAssignmentsPost($create_assignment_request = null, string $contentType = self::contentTypes['apiAssignmentsPost'][0]) + { + list($response) = $this->apiAssignmentsPostWithHttpInfo($create_assignment_request, $contentType); + return $response; + } + + /** + * Operation apiAssignmentsPostWithHttpInfo + * + * @param \OmsorgCoreClient\Model\CreateAssignmentRequest|null $create_assignment_request (optional) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiAssignmentsPost'] to see the possible values for this operation + * + * @throws \OmsorgCoreClient\ApiException on non-2xx response or if the response body is not in the expected format + * @throws \InvalidArgumentException + * @return array of \OmsorgCoreClient\Model\AssignmentResponse, HTTP status code, HTTP response headers (array of strings) + */ + public function apiAssignmentsPostWithHttpInfo($create_assignment_request = null, string $contentType = self::contentTypes['apiAssignmentsPost'][0]) + { + $request = $this->apiAssignmentsPostRequest($create_assignment_request, $contentType); + + try { + $options = $this->createHttpClientOption(); + try { + $response = $this->client->send($request, $options); + } catch (RequestException $e) { + throw new ApiException( + "[{$e->getCode()}] {$e->getMessage()}", + (int) $e->getCode(), + $e->getResponse() ? $e->getResponse()->getHeaders() : null, + $e->getResponse() ? (string) $e->getResponse()->getBody() : null + ); + } catch (ConnectException $e) { + throw new ApiException( + "[{$e->getCode()}] {$e->getMessage()}", + (int) $e->getCode(), + null, + null + ); + } + + $statusCode = $response->getStatusCode(); + + + switch($statusCode) { + case 200: + return $this->handleResponseWithDataType( + '\OmsorgCoreClient\Model\AssignmentResponse', + $request, + $response, + ); + } + + + + if ($statusCode < 200 || $statusCode > 299) { + throw new ApiException( + sprintf( + '[%d] Error connecting to the API (%s)', + $statusCode, + (string) $request->getUri() + ), + $statusCode, + $response->getHeaders(), + (string) $response->getBody() + ); + } + + return $this->handleResponseWithDataType( + '\OmsorgCoreClient\Model\AssignmentResponse', + $request, + $response, + ); + } catch (ApiException $e) { + switch ($e->getCode()) { + case 200: + $data = ObjectSerializer::deserialize( + $e->getResponseBody(), + '\OmsorgCoreClient\Model\AssignmentResponse', + $e->getResponseHeaders() + ); + $e->setResponseObject($data); + throw $e; + } + + + throw $e; + } + } + + /** + * Operation apiAssignmentsPostAsync + * + * @param \OmsorgCoreClient\Model\CreateAssignmentRequest|null $create_assignment_request (optional) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiAssignmentsPost'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Promise\PromiseInterface + */ + public function apiAssignmentsPostAsync($create_assignment_request = null, string $contentType = self::contentTypes['apiAssignmentsPost'][0]) + { + return $this->apiAssignmentsPostAsyncWithHttpInfo($create_assignment_request, $contentType) + ->then( + function ($response) { + return $response[0]; + } + ); + } + + /** + * Operation apiAssignmentsPostAsyncWithHttpInfo + * + * @param \OmsorgCoreClient\Model\CreateAssignmentRequest|null $create_assignment_request (optional) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiAssignmentsPost'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Promise\PromiseInterface + */ + public function apiAssignmentsPostAsyncWithHttpInfo($create_assignment_request = null, string $contentType = self::contentTypes['apiAssignmentsPost'][0]) + { + $returnType = '\OmsorgCoreClient\Model\AssignmentResponse'; + $request = $this->apiAssignmentsPostRequest($create_assignment_request, $contentType); + + return $this->client + ->sendAsync($request, $this->createHttpClientOption()) + ->then( + function ($response) use ($returnType) { + if ($returnType === '\SplFileObject') { + $content = $response->getBody(); //stream goes to serializer + } else { + $content = (string) $response->getBody(); + if ($returnType !== 'string') { + $content = json_decode($content); + } + } + + return [ + ObjectSerializer::deserialize($content, $returnType, []), + $response->getStatusCode(), + $response->getHeaders() + ]; + }, + function ($exception) { + $response = $exception->getResponse(); + $statusCode = $response->getStatusCode(); + throw new ApiException( + sprintf( + '[%d] Error connecting to the API (%s)', + $statusCode, + $exception->getRequest()->getUri() + ), + $statusCode, + $response->getHeaders(), + (string) $response->getBody() + ); + } + ); + } + + /** + * Create request for operation 'apiAssignmentsPost' + * + * @param \OmsorgCoreClient\Model\CreateAssignmentRequest|null $create_assignment_request (optional) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiAssignmentsPost'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Psr7\Request + */ + public function apiAssignmentsPostRequest($create_assignment_request = null, string $contentType = self::contentTypes['apiAssignmentsPost'][0]) + { + + + + $resourcePath = '/api/assignments'; + $formParams = []; + $queryParams = []; + $headerParams = []; + $httpBody = ''; + $multipart = false; + + + + + + $headers = $this->headerSelector->selectHeaders( + ['text/plain', 'application/json', 'text/json', ], + $contentType, + $multipart + ); + + // for model (json/xml) + if (isset($create_assignment_request)) { + if (stripos($headers['Content-Type'], 'application/json') !== false) { + # if Content-Type contains "application/json", json_encode the body + $httpBody = \GuzzleHttp\Utils::jsonEncode(ObjectSerializer::sanitizeForSerialization($create_assignment_request)); + } else { + $httpBody = $create_assignment_request; + } + } elseif (count($formParams) > 0) { + if ($multipart) { + $multipartContents = []; + foreach ($formParams as $formParamName => $formParamValue) { + $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue]; + foreach ($formParamValueItems as $formParamValueItem) { + $multipartContents[] = [ + 'name' => $formParamName, + 'contents' => $formParamValueItem + ]; + } + } + // for HTTP post (form) + $httpBody = new MultipartStream($multipartContents); + + } elseif (stripos($headers['Content-Type'], 'application/json') !== false) { + # if Content-Type contains "application/json", json_encode the form parameters + $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams); + } else { + // for HTTP post (form) + $httpBody = ObjectSerializer::buildQuery($formParams); + } + } + + // this endpoint requires Bearer (JWT) authentication (access token) + if (!empty($this->config->getAccessToken())) { + $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken(); + } + + $defaultHeaders = []; + if ($this->config->getUserAgent()) { + $defaultHeaders['User-Agent'] = $this->config->getUserAgent(); + } + + $headers = array_merge( + $defaultHeaders, + $headerParams, + $headers + ); + + $operationHost = $this->config->getHost(); + $query = ObjectSerializer::buildQuery($queryParams); + return new Request( + 'POST', + $operationHost . $resourcePath . ($query ? "?{$query}" : ''), + $headers, + $httpBody + ); + } + + /** + * Create http client option + * + * @throws \RuntimeException on file opening failure + * @return array of http client options + */ + protected function createHttpClientOption() + { + $options = []; + if ($this->config->getDebug()) { + $options[RequestOptions::DEBUG] = fopen($this->config->getDebugFile(), 'a'); + if (!$options[RequestOptions::DEBUG]) { + throw new \RuntimeException('Failed to open the debug file: ' . $this->config->getDebugFile()); + } + } + + return $options; + } + + private function handleResponseWithDataType( + string $dataType, + RequestInterface $request, + ResponseInterface $response + ): array { + if ($dataType === '\SplFileObject') { + $content = $response->getBody(); //stream goes to serializer + } else { + $content = (string) $response->getBody(); + if ($dataType !== 'string') { + try { + $content = json_decode($content, false, 512, JSON_THROW_ON_ERROR); + } catch (\JsonException $exception) { + throw new ApiException( + sprintf( + 'Error JSON decoding server response (%s)', + $request->getUri() + ), + $response->getStatusCode(), + $response->getHeaders(), + $content + ); + } + } + } + + return [ + ObjectSerializer::deserialize($content, $dataType, []), + $response->getStatusCode(), + $response->getHeaders() + ]; + } + + private function responseWithinRangeCode( + string $rangeCode, + int $statusCode + ): bool { + $left = (int) ($rangeCode[0].'00'); + $right = (int) ($rangeCode[0].'99'); + + return $statusCode >= $left && $statusCode <= $right; + } +} diff --git a/omsorgWeb/mitarbeiter-app/api-client-php/lib/Api/TrashApi.php b/omsorgWeb/mitarbeiter-app/api-client-php/lib/Api/TrashApi.php index d31f217..0e3f19c 100644 --- a/omsorgWeb/mitarbeiter-app/api-client-php/lib/Api/TrashApi.php +++ b/omsorgWeb/mitarbeiter-app/api-client-php/lib/Api/TrashApi.php @@ -80,6 +80,12 @@ class TrashApi 'apiTrashAbsencesIdRestorePost' => [ 'application/json', ], + 'apiTrashAssignmentsGet' => [ + 'application/json', + ], + 'apiTrashAssignmentsIdRestorePost' => [ + 'application/json', + ], 'apiTrashContractsGet' => [ 'application/json', ], @@ -582,6 +588,479 @@ class TrashApi + // path params + if ($id !== null) { + $resourcePath = str_replace( + '{' . 'id' . '}', + ObjectSerializer::toPathValue($id), + $resourcePath + ); + } + + + $headers = $this->headerSelector->selectHeaders( + [], + $contentType, + $multipart + ); + + // for model (json/xml) + if (count($formParams) > 0) { + if ($multipart) { + $multipartContents = []; + foreach ($formParams as $formParamName => $formParamValue) { + $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue]; + foreach ($formParamValueItems as $formParamValueItem) { + $multipartContents[] = [ + 'name' => $formParamName, + 'contents' => $formParamValueItem + ]; + } + } + // for HTTP post (form) + $httpBody = new MultipartStream($multipartContents); + + } elseif (stripos($headers['Content-Type'], 'application/json') !== false) { + # if Content-Type contains "application/json", json_encode the form parameters + $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams); + } else { + // for HTTP post (form) + $httpBody = ObjectSerializer::buildQuery($formParams); + } + } + + // this endpoint requires Bearer (JWT) authentication (access token) + if (!empty($this->config->getAccessToken())) { + $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken(); + } + + $defaultHeaders = []; + if ($this->config->getUserAgent()) { + $defaultHeaders['User-Agent'] = $this->config->getUserAgent(); + } + + $headers = array_merge( + $defaultHeaders, + $headerParams, + $headers + ); + + $operationHost = $this->config->getHost(); + $query = ObjectSerializer::buildQuery($queryParams); + return new Request( + 'POST', + $operationHost . $resourcePath . ($query ? "?{$query}" : ''), + $headers, + $httpBody + ); + } + + /** + * Operation apiTrashAssignmentsGet + * + * @param string|null $search search (optional) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiTrashAssignmentsGet'] to see the possible values for this operation + * + * @throws \OmsorgCoreClient\ApiException on non-2xx response or if the response body is not in the expected format + * @throws \InvalidArgumentException + * @return \OmsorgCoreClient\Model\TrashAssignmentResponse[] + */ + public function apiTrashAssignmentsGet($search = null, string $contentType = self::contentTypes['apiTrashAssignmentsGet'][0]) + { + list($response) = $this->apiTrashAssignmentsGetWithHttpInfo($search, $contentType); + return $response; + } + + /** + * Operation apiTrashAssignmentsGetWithHttpInfo + * + * @param string|null $search (optional) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiTrashAssignmentsGet'] to see the possible values for this operation + * + * @throws \OmsorgCoreClient\ApiException on non-2xx response or if the response body is not in the expected format + * @throws \InvalidArgumentException + * @return array of \OmsorgCoreClient\Model\TrashAssignmentResponse[], HTTP status code, HTTP response headers (array of strings) + */ + public function apiTrashAssignmentsGetWithHttpInfo($search = null, string $contentType = self::contentTypes['apiTrashAssignmentsGet'][0]) + { + $request = $this->apiTrashAssignmentsGetRequest($search, $contentType); + + try { + $options = $this->createHttpClientOption(); + try { + $response = $this->client->send($request, $options); + } catch (RequestException $e) { + throw new ApiException( + "[{$e->getCode()}] {$e->getMessage()}", + (int) $e->getCode(), + $e->getResponse() ? $e->getResponse()->getHeaders() : null, + $e->getResponse() ? (string) $e->getResponse()->getBody() : null + ); + } catch (ConnectException $e) { + throw new ApiException( + "[{$e->getCode()}] {$e->getMessage()}", + (int) $e->getCode(), + null, + null + ); + } + + $statusCode = $response->getStatusCode(); + + + switch($statusCode) { + case 200: + return $this->handleResponseWithDataType( + '\OmsorgCoreClient\Model\TrashAssignmentResponse[]', + $request, + $response, + ); + } + + + + if ($statusCode < 200 || $statusCode > 299) { + throw new ApiException( + sprintf( + '[%d] Error connecting to the API (%s)', + $statusCode, + (string) $request->getUri() + ), + $statusCode, + $response->getHeaders(), + (string) $response->getBody() + ); + } + + return $this->handleResponseWithDataType( + '\OmsorgCoreClient\Model\TrashAssignmentResponse[]', + $request, + $response, + ); + } catch (ApiException $e) { + switch ($e->getCode()) { + case 200: + $data = ObjectSerializer::deserialize( + $e->getResponseBody(), + '\OmsorgCoreClient\Model\TrashAssignmentResponse[]', + $e->getResponseHeaders() + ); + $e->setResponseObject($data); + throw $e; + } + + + throw $e; + } + } + + /** + * Operation apiTrashAssignmentsGetAsync + * + * @param string|null $search (optional) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiTrashAssignmentsGet'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Promise\PromiseInterface + */ + public function apiTrashAssignmentsGetAsync($search = null, string $contentType = self::contentTypes['apiTrashAssignmentsGet'][0]) + { + return $this->apiTrashAssignmentsGetAsyncWithHttpInfo($search, $contentType) + ->then( + function ($response) { + return $response[0]; + } + ); + } + + /** + * Operation apiTrashAssignmentsGetAsyncWithHttpInfo + * + * @param string|null $search (optional) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiTrashAssignmentsGet'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Promise\PromiseInterface + */ + public function apiTrashAssignmentsGetAsyncWithHttpInfo($search = null, string $contentType = self::contentTypes['apiTrashAssignmentsGet'][0]) + { + $returnType = '\OmsorgCoreClient\Model\TrashAssignmentResponse[]'; + $request = $this->apiTrashAssignmentsGetRequest($search, $contentType); + + return $this->client + ->sendAsync($request, $this->createHttpClientOption()) + ->then( + function ($response) use ($returnType) { + if ($returnType === '\SplFileObject') { + $content = $response->getBody(); //stream goes to serializer + } else { + $content = (string) $response->getBody(); + if ($returnType !== 'string') { + $content = json_decode($content); + } + } + + return [ + ObjectSerializer::deserialize($content, $returnType, []), + $response->getStatusCode(), + $response->getHeaders() + ]; + }, + function ($exception) { + $response = $exception->getResponse(); + $statusCode = $response->getStatusCode(); + throw new ApiException( + sprintf( + '[%d] Error connecting to the API (%s)', + $statusCode, + $exception->getRequest()->getUri() + ), + $statusCode, + $response->getHeaders(), + (string) $response->getBody() + ); + } + ); + } + + /** + * Create request for operation 'apiTrashAssignmentsGet' + * + * @param string|null $search (optional) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiTrashAssignmentsGet'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Psr7\Request + */ + public function apiTrashAssignmentsGetRequest($search = null, string $contentType = self::contentTypes['apiTrashAssignmentsGet'][0]) + { + + + + $resourcePath = '/api/trash/assignments'; + $formParams = []; + $queryParams = []; + $headerParams = []; + $httpBody = ''; + $multipart = false; + + // query params + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $search, + 'search', // param base name + 'string', // openApiType + 'form', // style + true, // explode + false // required + ) ?? []); + + + + + $headers = $this->headerSelector->selectHeaders( + ['text/plain', 'application/json', 'text/json', ], + $contentType, + $multipart + ); + + // for model (json/xml) + if (count($formParams) > 0) { + if ($multipart) { + $multipartContents = []; + foreach ($formParams as $formParamName => $formParamValue) { + $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue]; + foreach ($formParamValueItems as $formParamValueItem) { + $multipartContents[] = [ + 'name' => $formParamName, + 'contents' => $formParamValueItem + ]; + } + } + // for HTTP post (form) + $httpBody = new MultipartStream($multipartContents); + + } elseif (stripos($headers['Content-Type'], 'application/json') !== false) { + # if Content-Type contains "application/json", json_encode the form parameters + $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams); + } else { + // for HTTP post (form) + $httpBody = ObjectSerializer::buildQuery($formParams); + } + } + + // this endpoint requires Bearer (JWT) authentication (access token) + if (!empty($this->config->getAccessToken())) { + $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken(); + } + + $defaultHeaders = []; + if ($this->config->getUserAgent()) { + $defaultHeaders['User-Agent'] = $this->config->getUserAgent(); + } + + $headers = array_merge( + $defaultHeaders, + $headerParams, + $headers + ); + + $operationHost = $this->config->getHost(); + $query = ObjectSerializer::buildQuery($queryParams); + return new Request( + 'GET', + $operationHost . $resourcePath . ($query ? "?{$query}" : ''), + $headers, + $httpBody + ); + } + + /** + * Operation apiTrashAssignmentsIdRestorePost + * + * @param string $id id (required) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiTrashAssignmentsIdRestorePost'] to see the possible values for this operation + * + * @throws \OmsorgCoreClient\ApiException on non-2xx response or if the response body is not in the expected format + * @throws \InvalidArgumentException + * @return void + */ + public function apiTrashAssignmentsIdRestorePost($id, string $contentType = self::contentTypes['apiTrashAssignmentsIdRestorePost'][0]) + { + $this->apiTrashAssignmentsIdRestorePostWithHttpInfo($id, $contentType); + } + + /** + * Operation apiTrashAssignmentsIdRestorePostWithHttpInfo + * + * @param string $id (required) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiTrashAssignmentsIdRestorePost'] to see the possible values for this operation + * + * @throws \OmsorgCoreClient\ApiException on non-2xx response or if the response body is not in the expected format + * @throws \InvalidArgumentException + * @return array of null, HTTP status code, HTTP response headers (array of strings) + */ + public function apiTrashAssignmentsIdRestorePostWithHttpInfo($id, string $contentType = self::contentTypes['apiTrashAssignmentsIdRestorePost'][0]) + { + $request = $this->apiTrashAssignmentsIdRestorePostRequest($id, $contentType); + + try { + $options = $this->createHttpClientOption(); + try { + $response = $this->client->send($request, $options); + } catch (RequestException $e) { + throw new ApiException( + "[{$e->getCode()}] {$e->getMessage()}", + (int) $e->getCode(), + $e->getResponse() ? $e->getResponse()->getHeaders() : null, + $e->getResponse() ? (string) $e->getResponse()->getBody() : null + ); + } catch (ConnectException $e) { + throw new ApiException( + "[{$e->getCode()}] {$e->getMessage()}", + (int) $e->getCode(), + null, + null + ); + } + + $statusCode = $response->getStatusCode(); + + + return [null, $statusCode, $response->getHeaders()]; + } catch (ApiException $e) { + switch ($e->getCode()) { + } + + + throw $e; + } + } + + /** + * Operation apiTrashAssignmentsIdRestorePostAsync + * + * @param string $id (required) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiTrashAssignmentsIdRestorePost'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Promise\PromiseInterface + */ + public function apiTrashAssignmentsIdRestorePostAsync($id, string $contentType = self::contentTypes['apiTrashAssignmentsIdRestorePost'][0]) + { + return $this->apiTrashAssignmentsIdRestorePostAsyncWithHttpInfo($id, $contentType) + ->then( + function ($response) { + return $response[0]; + } + ); + } + + /** + * Operation apiTrashAssignmentsIdRestorePostAsyncWithHttpInfo + * + * @param string $id (required) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiTrashAssignmentsIdRestorePost'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Promise\PromiseInterface + */ + public function apiTrashAssignmentsIdRestorePostAsyncWithHttpInfo($id, string $contentType = self::contentTypes['apiTrashAssignmentsIdRestorePost'][0]) + { + $returnType = ''; + $request = $this->apiTrashAssignmentsIdRestorePostRequest($id, $contentType); + + return $this->client + ->sendAsync($request, $this->createHttpClientOption()) + ->then( + function ($response) use ($returnType) { + return [null, $response->getStatusCode(), $response->getHeaders()]; + }, + function ($exception) { + $response = $exception->getResponse(); + $statusCode = $response->getStatusCode(); + throw new ApiException( + sprintf( + '[%d] Error connecting to the API (%s)', + $statusCode, + $exception->getRequest()->getUri() + ), + $statusCode, + $response->getHeaders(), + (string) $response->getBody() + ); + } + ); + } + + /** + * Create request for operation 'apiTrashAssignmentsIdRestorePost' + * + * @param string $id (required) + * @param string $contentType The value for the Content-Type header. Check self::contentTypes['apiTrashAssignmentsIdRestorePost'] to see the possible values for this operation + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Psr7\Request + */ + public function apiTrashAssignmentsIdRestorePostRequest($id, string $contentType = self::contentTypes['apiTrashAssignmentsIdRestorePost'][0]) + { + + // verify the required parameter 'id' is set + if ($id === null || (is_array($id) && count($id) === 0)) { + throw new \InvalidArgumentException( + 'Missing the required parameter $id when calling apiTrashAssignmentsIdRestorePost' + ); + } + + + $resourcePath = '/api/trash/assignments/{id}/restore'; + $formParams = []; + $queryParams = []; + $headerParams = []; + $httpBody = ''; + $multipart = false; + + + // path params if ($id !== null) { $resourcePath = str_replace( diff --git a/omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/AssignmentConflictResponse.php b/omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/AssignmentConflictResponse.php new file mode 100644 index 0000000..826a2a7 --- /dev/null +++ b/omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/AssignmentConflictResponse.php @@ -0,0 +1,498 @@ + + */ +class AssignmentConflictResponse implements ModelInterface, ArrayAccess, \JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static $openAPIModelName = 'AssignmentConflictResponse'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPITypes = [ + 'type' => 'string', + 'severity' => 'string', + 'message' => 'string' + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + * @phpstan-var array + * @psalm-var array + */ + protected static $openAPIFormats = [ + 'type' => null, + 'severity' => null, + 'message' => null + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var boolean[] + */ + protected static array $openAPINullables = [ + 'type' => true, + 'severity' => true, + 'message' => true + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var boolean[] + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return boolean[] + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param boolean[] $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + 'type' => 'type', + 'severity' => 'severity', + 'message' => 'message' + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + 'type' => 'setType', + 'severity' => 'setSeverity', + 'message' => 'setMessage' + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + 'type' => 'getType', + 'severity' => 'getSeverity', + 'message' => 'getMessage' + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[]|null $data Associated array of property values + * initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('type', $data ?? [], null); + $this->setIfExists('severity', $data ?? [], null); + $this->setIfExists('message', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets type + * + * @return string|null + */ + public function getType() + { + return $this->container['type']; + } + + /** + * Sets type + * + * @param string|null $type type + * + * @return self + */ + public function setType($type) + { + if (is_null($type)) { + array_push($this->openAPINullablesSetToNull, 'type'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('type', $nullablesSetToNull); + if ($index !== FALSE) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + $this->container['type'] = $type; + + return $this; + } + + /** + * Gets severity + * + * @return string|null + */ + public function getSeverity() + { + return $this->container['severity']; + } + + /** + * Sets severity + * + * @param string|null $severity severity + * + * @return self + */ + public function setSeverity($severity) + { + if (is_null($severity)) { + array_push($this->openAPINullablesSetToNull, 'severity'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('severity', $nullablesSetToNull); + if ($index !== FALSE) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + $this->container['severity'] = $severity; + + return $this; + } + + /** + * Gets message + * + * @return string|null + */ + public function getMessage() + { + return $this->container['message']; + } + + /** + * Sets message + * + * @param string|null $message message + * + * @return self + */ + public function setMessage($message) + { + if (is_null($message)) { + array_push($this->openAPINullablesSetToNull, 'message'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('message', $nullablesSetToNull); + if ($index !== FALSE) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + $this->container['message'] = $message; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param integer $offset Offset + * + * @return boolean + */ + public function offsetExists($offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer $offset Offset + * + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function offsetGet($offset) + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer $offset Offset + * + * @return void + */ + public function offsetUnset($offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue() + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} + + diff --git a/omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/AssignmentResponse.php b/omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/AssignmentResponse.php new file mode 100644 index 0000000..25909d7 --- /dev/null +++ b/omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/AssignmentResponse.php @@ -0,0 +1,709 @@ + + */ +class AssignmentResponse implements ModelInterface, ArrayAccess, \JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static $openAPIModelName = 'AssignmentResponse'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPITypes = [ + 'id' => 'string', + 'order_id' => 'string', + 'employee_id' => 'string', + 'employee_first_name' => 'string', + 'employee_last_name' => 'string', + 'start_date' => '\DateTime', + 'end_date' => '\DateTime', + 'note' => 'string', + 'conflicts' => '\OmsorgCoreClient\Model\AssignmentConflictResponse[]' + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + * @phpstan-var array + * @psalm-var array + */ + protected static $openAPIFormats = [ + 'id' => 'uuid', + 'order_id' => 'uuid', + 'employee_id' => 'uuid', + 'employee_first_name' => null, + 'employee_last_name' => null, + 'start_date' => 'date', + 'end_date' => 'date', + 'note' => null, + 'conflicts' => null + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var boolean[] + */ + protected static array $openAPINullables = [ + 'id' => false, + 'order_id' => false, + 'employee_id' => false, + 'employee_first_name' => true, + 'employee_last_name' => true, + 'start_date' => false, + 'end_date' => false, + 'note' => true, + 'conflicts' => true + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var boolean[] + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return boolean[] + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param boolean[] $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + 'id' => 'id', + 'order_id' => 'orderId', + 'employee_id' => 'employeeId', + 'employee_first_name' => 'employeeFirstName', + 'employee_last_name' => 'employeeLastName', + 'start_date' => 'startDate', + 'end_date' => 'endDate', + 'note' => 'note', + 'conflicts' => 'conflicts' + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + 'id' => 'setId', + 'order_id' => 'setOrderId', + 'employee_id' => 'setEmployeeId', + 'employee_first_name' => 'setEmployeeFirstName', + 'employee_last_name' => 'setEmployeeLastName', + 'start_date' => 'setStartDate', + 'end_date' => 'setEndDate', + 'note' => 'setNote', + 'conflicts' => 'setConflicts' + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + 'id' => 'getId', + 'order_id' => 'getOrderId', + 'employee_id' => 'getEmployeeId', + 'employee_first_name' => 'getEmployeeFirstName', + 'employee_last_name' => 'getEmployeeLastName', + 'start_date' => 'getStartDate', + 'end_date' => 'getEndDate', + 'note' => 'getNote', + 'conflicts' => 'getConflicts' + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[]|null $data Associated array of property values + * initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('id', $data ?? [], null); + $this->setIfExists('order_id', $data ?? [], null); + $this->setIfExists('employee_id', $data ?? [], null); + $this->setIfExists('employee_first_name', $data ?? [], null); + $this->setIfExists('employee_last_name', $data ?? [], null); + $this->setIfExists('start_date', $data ?? [], null); + $this->setIfExists('end_date', $data ?? [], null); + $this->setIfExists('note', $data ?? [], null); + $this->setIfExists('conflicts', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets id + * + * @return string|null + */ + public function getId() + { + return $this->container['id']; + } + + /** + * Sets id + * + * @param string|null $id id + * + * @return self + */ + public function setId($id) + { + if (is_null($id)) { + throw new \InvalidArgumentException('non-nullable id cannot be null'); + } + $this->container['id'] = $id; + + return $this; + } + + /** + * Gets order_id + * + * @return string|null + */ + public function getOrderId() + { + return $this->container['order_id']; + } + + /** + * Sets order_id + * + * @param string|null $order_id order_id + * + * @return self + */ + public function setOrderId($order_id) + { + if (is_null($order_id)) { + throw new \InvalidArgumentException('non-nullable order_id cannot be null'); + } + $this->container['order_id'] = $order_id; + + return $this; + } + + /** + * Gets employee_id + * + * @return string|null + */ + public function getEmployeeId() + { + return $this->container['employee_id']; + } + + /** + * Sets employee_id + * + * @param string|null $employee_id employee_id + * + * @return self + */ + public function setEmployeeId($employee_id) + { + if (is_null($employee_id)) { + throw new \InvalidArgumentException('non-nullable employee_id cannot be null'); + } + $this->container['employee_id'] = $employee_id; + + return $this; + } + + /** + * Gets employee_first_name + * + * @return string|null + */ + public function getEmployeeFirstName() + { + return $this->container['employee_first_name']; + } + + /** + * Sets employee_first_name + * + * @param string|null $employee_first_name employee_first_name + * + * @return self + */ + public function setEmployeeFirstName($employee_first_name) + { + if (is_null($employee_first_name)) { + array_push($this->openAPINullablesSetToNull, 'employee_first_name'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('employee_first_name', $nullablesSetToNull); + if ($index !== FALSE) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + $this->container['employee_first_name'] = $employee_first_name; + + return $this; + } + + /** + * Gets employee_last_name + * + * @return string|null + */ + public function getEmployeeLastName() + { + return $this->container['employee_last_name']; + } + + /** + * Sets employee_last_name + * + * @param string|null $employee_last_name employee_last_name + * + * @return self + */ + public function setEmployeeLastName($employee_last_name) + { + if (is_null($employee_last_name)) { + array_push($this->openAPINullablesSetToNull, 'employee_last_name'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('employee_last_name', $nullablesSetToNull); + if ($index !== FALSE) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + $this->container['employee_last_name'] = $employee_last_name; + + return $this; + } + + /** + * Gets start_date + * + * @return \DateTime|null + */ + public function getStartDate() + { + return $this->container['start_date']; + } + + /** + * Sets start_date + * + * @param \DateTime|null $start_date start_date + * + * @return self + */ + public function setStartDate($start_date) + { + if (is_null($start_date)) { + throw new \InvalidArgumentException('non-nullable start_date cannot be null'); + } + $this->container['start_date'] = $start_date; + + return $this; + } + + /** + * Gets end_date + * + * @return \DateTime|null + */ + public function getEndDate() + { + return $this->container['end_date']; + } + + /** + * Sets end_date + * + * @param \DateTime|null $end_date end_date + * + * @return self + */ + public function setEndDate($end_date) + { + if (is_null($end_date)) { + throw new \InvalidArgumentException('non-nullable end_date cannot be null'); + } + $this->container['end_date'] = $end_date; + + return $this; + } + + /** + * Gets note + * + * @return string|null + */ + public function getNote() + { + return $this->container['note']; + } + + /** + * Sets note + * + * @param string|null $note note + * + * @return self + */ + public function setNote($note) + { + if (is_null($note)) { + array_push($this->openAPINullablesSetToNull, 'note'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('note', $nullablesSetToNull); + if ($index !== FALSE) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + $this->container['note'] = $note; + + return $this; + } + + /** + * Gets conflicts + * + * @return \OmsorgCoreClient\Model\AssignmentConflictResponse[]|null + */ + public function getConflicts() + { + return $this->container['conflicts']; + } + + /** + * Sets conflicts + * + * @param \OmsorgCoreClient\Model\AssignmentConflictResponse[]|null $conflicts conflicts + * + * @return self + */ + public function setConflicts($conflicts) + { + if (is_null($conflicts)) { + array_push($this->openAPINullablesSetToNull, 'conflicts'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('conflicts', $nullablesSetToNull); + if ($index !== FALSE) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + $this->container['conflicts'] = $conflicts; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param integer $offset Offset + * + * @return boolean + */ + public function offsetExists($offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer $offset Offset + * + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function offsetGet($offset) + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer $offset Offset + * + * @return void + */ + public function offsetUnset($offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue() + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} + + diff --git a/omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/AssignmentResponsePagedResponse.php b/omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/AssignmentResponsePagedResponse.php new file mode 100644 index 0000000..12e3451 --- /dev/null +++ b/omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/AssignmentResponsePagedResponse.php @@ -0,0 +1,518 @@ + + */ +class AssignmentResponsePagedResponse implements ModelInterface, ArrayAccess, \JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static $openAPIModelName = 'AssignmentResponsePagedResponse'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPITypes = [ + 'items' => '\OmsorgCoreClient\Model\AssignmentResponse[]', + 'total_count' => 'int', + 'page' => 'int', + 'page_size' => 'int' + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + * @phpstan-var array + * @psalm-var array + */ + protected static $openAPIFormats = [ + 'items' => null, + 'total_count' => 'int32', + 'page' => 'int32', + 'page_size' => 'int32' + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var boolean[] + */ + protected static array $openAPINullables = [ + 'items' => true, + 'total_count' => false, + 'page' => false, + 'page_size' => false + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var boolean[] + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return boolean[] + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param boolean[] $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + 'items' => 'items', + 'total_count' => 'totalCount', + 'page' => 'page', + 'page_size' => 'pageSize' + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + 'items' => 'setItems', + 'total_count' => 'setTotalCount', + 'page' => 'setPage', + 'page_size' => 'setPageSize' + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + 'items' => 'getItems', + 'total_count' => 'getTotalCount', + 'page' => 'getPage', + 'page_size' => 'getPageSize' + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[]|null $data Associated array of property values + * initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('items', $data ?? [], null); + $this->setIfExists('total_count', $data ?? [], null); + $this->setIfExists('page', $data ?? [], null); + $this->setIfExists('page_size', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets items + * + * @return \OmsorgCoreClient\Model\AssignmentResponse[]|null + */ + public function getItems() + { + return $this->container['items']; + } + + /** + * Sets items + * + * @param \OmsorgCoreClient\Model\AssignmentResponse[]|null $items items + * + * @return self + */ + public function setItems($items) + { + if (is_null($items)) { + array_push($this->openAPINullablesSetToNull, 'items'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('items', $nullablesSetToNull); + if ($index !== FALSE) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + $this->container['items'] = $items; + + return $this; + } + + /** + * Gets total_count + * + * @return int|null + */ + public function getTotalCount() + { + return $this->container['total_count']; + } + + /** + * Sets total_count + * + * @param int|null $total_count total_count + * + * @return self + */ + public function setTotalCount($total_count) + { + if (is_null($total_count)) { + throw new \InvalidArgumentException('non-nullable total_count cannot be null'); + } + $this->container['total_count'] = $total_count; + + return $this; + } + + /** + * Gets page + * + * @return int|null + */ + public function getPage() + { + return $this->container['page']; + } + + /** + * Sets page + * + * @param int|null $page page + * + * @return self + */ + public function setPage($page) + { + if (is_null($page)) { + throw new \InvalidArgumentException('non-nullable page cannot be null'); + } + $this->container['page'] = $page; + + return $this; + } + + /** + * Gets page_size + * + * @return int|null + */ + public function getPageSize() + { + return $this->container['page_size']; + } + + /** + * Sets page_size + * + * @param int|null $page_size page_size + * + * @return self + */ + public function setPageSize($page_size) + { + if (is_null($page_size)) { + throw new \InvalidArgumentException('non-nullable page_size cannot be null'); + } + $this->container['page_size'] = $page_size; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param integer $offset Offset + * + * @return boolean + */ + public function offsetExists($offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer $offset Offset + * + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function offsetGet($offset) + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer $offset Offset + * + * @return void + */ + public function offsetUnset($offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue() + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} + + diff --git a/omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/AssignmentValidationSettingsResponse.php b/omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/AssignmentValidationSettingsResponse.php new file mode 100644 index 0000000..3b9039f --- /dev/null +++ b/omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/AssignmentValidationSettingsResponse.php @@ -0,0 +1,580 @@ + + */ +class AssignmentValidationSettingsResponse implements ModelInterface, ArrayAccess, \JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static $openAPIModelName = 'AssignmentValidationSettingsResponse'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPITypes = [ + 'qualification_mode' => 'string', + 'absence_mode' => 'string', + 'working_hours_mode' => 'string', + 'overlap_mode' => 'string', + 'contract_mode' => 'string' + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + * @phpstan-var array + * @psalm-var array + */ + protected static $openAPIFormats = [ + 'qualification_mode' => null, + 'absence_mode' => null, + 'working_hours_mode' => null, + 'overlap_mode' => null, + 'contract_mode' => null + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var boolean[] + */ + protected static array $openAPINullables = [ + 'qualification_mode' => true, + 'absence_mode' => true, + 'working_hours_mode' => true, + 'overlap_mode' => true, + 'contract_mode' => true + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var boolean[] + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return boolean[] + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param boolean[] $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + 'qualification_mode' => 'qualificationMode', + 'absence_mode' => 'absenceMode', + 'working_hours_mode' => 'workingHoursMode', + 'overlap_mode' => 'overlapMode', + 'contract_mode' => 'contractMode' + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + 'qualification_mode' => 'setQualificationMode', + 'absence_mode' => 'setAbsenceMode', + 'working_hours_mode' => 'setWorkingHoursMode', + 'overlap_mode' => 'setOverlapMode', + 'contract_mode' => 'setContractMode' + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + 'qualification_mode' => 'getQualificationMode', + 'absence_mode' => 'getAbsenceMode', + 'working_hours_mode' => 'getWorkingHoursMode', + 'overlap_mode' => 'getOverlapMode', + 'contract_mode' => 'getContractMode' + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[]|null $data Associated array of property values + * initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('qualification_mode', $data ?? [], null); + $this->setIfExists('absence_mode', $data ?? [], null); + $this->setIfExists('working_hours_mode', $data ?? [], null); + $this->setIfExists('overlap_mode', $data ?? [], null); + $this->setIfExists('contract_mode', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets qualification_mode + * + * @return string|null + */ + public function getQualificationMode() + { + return $this->container['qualification_mode']; + } + + /** + * Sets qualification_mode + * + * @param string|null $qualification_mode qualification_mode + * + * @return self + */ + public function setQualificationMode($qualification_mode) + { + if (is_null($qualification_mode)) { + array_push($this->openAPINullablesSetToNull, 'qualification_mode'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('qualification_mode', $nullablesSetToNull); + if ($index !== FALSE) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + $this->container['qualification_mode'] = $qualification_mode; + + return $this; + } + + /** + * Gets absence_mode + * + * @return string|null + */ + public function getAbsenceMode() + { + return $this->container['absence_mode']; + } + + /** + * Sets absence_mode + * + * @param string|null $absence_mode absence_mode + * + * @return self + */ + public function setAbsenceMode($absence_mode) + { + if (is_null($absence_mode)) { + array_push($this->openAPINullablesSetToNull, 'absence_mode'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('absence_mode', $nullablesSetToNull); + if ($index !== FALSE) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + $this->container['absence_mode'] = $absence_mode; + + return $this; + } + + /** + * Gets working_hours_mode + * + * @return string|null + */ + public function getWorkingHoursMode() + { + return $this->container['working_hours_mode']; + } + + /** + * Sets working_hours_mode + * + * @param string|null $working_hours_mode working_hours_mode + * + * @return self + */ + public function setWorkingHoursMode($working_hours_mode) + { + if (is_null($working_hours_mode)) { + array_push($this->openAPINullablesSetToNull, 'working_hours_mode'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('working_hours_mode', $nullablesSetToNull); + if ($index !== FALSE) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + $this->container['working_hours_mode'] = $working_hours_mode; + + return $this; + } + + /** + * Gets overlap_mode + * + * @return string|null + */ + public function getOverlapMode() + { + return $this->container['overlap_mode']; + } + + /** + * Sets overlap_mode + * + * @param string|null $overlap_mode overlap_mode + * + * @return self + */ + public function setOverlapMode($overlap_mode) + { + if (is_null($overlap_mode)) { + array_push($this->openAPINullablesSetToNull, 'overlap_mode'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('overlap_mode', $nullablesSetToNull); + if ($index !== FALSE) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + $this->container['overlap_mode'] = $overlap_mode; + + return $this; + } + + /** + * Gets contract_mode + * + * @return string|null + */ + public function getContractMode() + { + return $this->container['contract_mode']; + } + + /** + * Sets contract_mode + * + * @param string|null $contract_mode contract_mode + * + * @return self + */ + public function setContractMode($contract_mode) + { + if (is_null($contract_mode)) { + array_push($this->openAPINullablesSetToNull, 'contract_mode'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('contract_mode', $nullablesSetToNull); + if ($index !== FALSE) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + $this->container['contract_mode'] = $contract_mode; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param integer $offset Offset + * + * @return boolean + */ + public function offsetExists($offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer $offset Offset + * + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function offsetGet($offset) + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer $offset Offset + * + * @return void + */ + public function offsetUnset($offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue() + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} + + diff --git a/omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/CreateAssignmentRequest.php b/omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/CreateAssignmentRequest.php new file mode 100644 index 0000000..40388c3 --- /dev/null +++ b/omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/CreateAssignmentRequest.php @@ -0,0 +1,552 @@ + + */ +class CreateAssignmentRequest implements ModelInterface, ArrayAccess, \JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static $openAPIModelName = 'CreateAssignmentRequest'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPITypes = [ + 'order_id' => 'string', + 'employee_id' => 'string', + 'start_date' => '\DateTime', + 'end_date' => '\DateTime', + 'note' => 'string' + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + * @phpstan-var array + * @psalm-var array + */ + protected static $openAPIFormats = [ + 'order_id' => 'uuid', + 'employee_id' => 'uuid', + 'start_date' => 'date', + 'end_date' => 'date', + 'note' => null + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var boolean[] + */ + protected static array $openAPINullables = [ + 'order_id' => false, + 'employee_id' => false, + 'start_date' => false, + 'end_date' => false, + 'note' => true + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var boolean[] + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return boolean[] + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param boolean[] $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + 'order_id' => 'orderId', + 'employee_id' => 'employeeId', + 'start_date' => 'startDate', + 'end_date' => 'endDate', + 'note' => 'note' + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + 'order_id' => 'setOrderId', + 'employee_id' => 'setEmployeeId', + 'start_date' => 'setStartDate', + 'end_date' => 'setEndDate', + 'note' => 'setNote' + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + 'order_id' => 'getOrderId', + 'employee_id' => 'getEmployeeId', + 'start_date' => 'getStartDate', + 'end_date' => 'getEndDate', + 'note' => 'getNote' + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[]|null $data Associated array of property values + * initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('order_id', $data ?? [], null); + $this->setIfExists('employee_id', $data ?? [], null); + $this->setIfExists('start_date', $data ?? [], null); + $this->setIfExists('end_date', $data ?? [], null); + $this->setIfExists('note', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets order_id + * + * @return string|null + */ + public function getOrderId() + { + return $this->container['order_id']; + } + + /** + * Sets order_id + * + * @param string|null $order_id order_id + * + * @return self + */ + public function setOrderId($order_id) + { + if (is_null($order_id)) { + throw new \InvalidArgumentException('non-nullable order_id cannot be null'); + } + $this->container['order_id'] = $order_id; + + return $this; + } + + /** + * Gets employee_id + * + * @return string|null + */ + public function getEmployeeId() + { + return $this->container['employee_id']; + } + + /** + * Sets employee_id + * + * @param string|null $employee_id employee_id + * + * @return self + */ + public function setEmployeeId($employee_id) + { + if (is_null($employee_id)) { + throw new \InvalidArgumentException('non-nullable employee_id cannot be null'); + } + $this->container['employee_id'] = $employee_id; + + return $this; + } + + /** + * Gets start_date + * + * @return \DateTime|null + */ + public function getStartDate() + { + return $this->container['start_date']; + } + + /** + * Sets start_date + * + * @param \DateTime|null $start_date start_date + * + * @return self + */ + public function setStartDate($start_date) + { + if (is_null($start_date)) { + throw new \InvalidArgumentException('non-nullable start_date cannot be null'); + } + $this->container['start_date'] = $start_date; + + return $this; + } + + /** + * Gets end_date + * + * @return \DateTime|null + */ + public function getEndDate() + { + return $this->container['end_date']; + } + + /** + * Sets end_date + * + * @param \DateTime|null $end_date end_date + * + * @return self + */ + public function setEndDate($end_date) + { + if (is_null($end_date)) { + throw new \InvalidArgumentException('non-nullable end_date cannot be null'); + } + $this->container['end_date'] = $end_date; + + return $this; + } + + /** + * Gets note + * + * @return string|null + */ + public function getNote() + { + return $this->container['note']; + } + + /** + * Sets note + * + * @param string|null $note note + * + * @return self + */ + public function setNote($note) + { + if (is_null($note)) { + array_push($this->openAPINullablesSetToNull, 'note'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('note', $nullablesSetToNull); + if ($index !== FALSE) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + $this->container['note'] = $note; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param integer $offset Offset + * + * @return boolean + */ + public function offsetExists($offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer $offset Offset + * + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function offsetGet($offset) + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer $offset Offset + * + * @return void + */ + public function offsetUnset($offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue() + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} + + diff --git a/omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/ModuleType.php b/omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/ModuleType.php index aaee769..4ef77e7 100644 --- a/omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/ModuleType.php +++ b/omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/ModuleType.php @@ -72,6 +72,8 @@ class ModuleType public const EMPLOYEE_FACILITY_DISTANCES = 'EmployeeFacilityDistances'; + public const ASSIGNMENTS = 'Assignments'; + /** * Gets allowable values of the enum * @return string[] @@ -93,7 +95,8 @@ class ModuleType self::USERS, self::CONFIGURATION, self::ABSENCES, - self::EMPLOYEE_FACILITY_DISTANCES + self::EMPLOYEE_FACILITY_DISTANCES, + self::ASSIGNMENTS ]; } } diff --git a/omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/TrashAssignmentResponse.php b/omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/TrashAssignmentResponse.php new file mode 100644 index 0000000..0af5ec8 --- /dev/null +++ b/omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/TrashAssignmentResponse.php @@ -0,0 +1,532 @@ + + */ +class TrashAssignmentResponse implements ModelInterface, ArrayAccess, \JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static $openAPIModelName = 'TrashAssignmentResponse'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPITypes = [ + 'id' => 'string', + 'employee_first_name' => 'string', + 'employee_last_name' => 'string', + 'deleted_at' => '\DateTime' + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + * @phpstan-var array + * @psalm-var array + */ + protected static $openAPIFormats = [ + 'id' => 'uuid', + 'employee_first_name' => null, + 'employee_last_name' => null, + 'deleted_at' => 'date-time' + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var boolean[] + */ + protected static array $openAPINullables = [ + 'id' => false, + 'employee_first_name' => true, + 'employee_last_name' => true, + 'deleted_at' => true + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var boolean[] + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return boolean[] + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param boolean[] $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + 'id' => 'id', + 'employee_first_name' => 'employeeFirstName', + 'employee_last_name' => 'employeeLastName', + 'deleted_at' => 'deletedAt' + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + 'id' => 'setId', + 'employee_first_name' => 'setEmployeeFirstName', + 'employee_last_name' => 'setEmployeeLastName', + 'deleted_at' => 'setDeletedAt' + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + 'id' => 'getId', + 'employee_first_name' => 'getEmployeeFirstName', + 'employee_last_name' => 'getEmployeeLastName', + 'deleted_at' => 'getDeletedAt' + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[]|null $data Associated array of property values + * initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('id', $data ?? [], null); + $this->setIfExists('employee_first_name', $data ?? [], null); + $this->setIfExists('employee_last_name', $data ?? [], null); + $this->setIfExists('deleted_at', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets id + * + * @return string|null + */ + public function getId() + { + return $this->container['id']; + } + + /** + * Sets id + * + * @param string|null $id id + * + * @return self + */ + public function setId($id) + { + if (is_null($id)) { + throw new \InvalidArgumentException('non-nullable id cannot be null'); + } + $this->container['id'] = $id; + + return $this; + } + + /** + * Gets employee_first_name + * + * @return string|null + */ + public function getEmployeeFirstName() + { + return $this->container['employee_first_name']; + } + + /** + * Sets employee_first_name + * + * @param string|null $employee_first_name employee_first_name + * + * @return self + */ + public function setEmployeeFirstName($employee_first_name) + { + if (is_null($employee_first_name)) { + array_push($this->openAPINullablesSetToNull, 'employee_first_name'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('employee_first_name', $nullablesSetToNull); + if ($index !== FALSE) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + $this->container['employee_first_name'] = $employee_first_name; + + return $this; + } + + /** + * Gets employee_last_name + * + * @return string|null + */ + public function getEmployeeLastName() + { + return $this->container['employee_last_name']; + } + + /** + * Sets employee_last_name + * + * @param string|null $employee_last_name employee_last_name + * + * @return self + */ + public function setEmployeeLastName($employee_last_name) + { + if (is_null($employee_last_name)) { + array_push($this->openAPINullablesSetToNull, 'employee_last_name'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('employee_last_name', $nullablesSetToNull); + if ($index !== FALSE) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + $this->container['employee_last_name'] = $employee_last_name; + + return $this; + } + + /** + * Gets deleted_at + * + * @return \DateTime|null + */ + public function getDeletedAt() + { + return $this->container['deleted_at']; + } + + /** + * Sets deleted_at + * + * @param \DateTime|null $deleted_at deleted_at + * + * @return self + */ + public function setDeletedAt($deleted_at) + { + if (is_null($deleted_at)) { + array_push($this->openAPINullablesSetToNull, 'deleted_at'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('deleted_at', $nullablesSetToNull); + if ($index !== FALSE) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + $this->container['deleted_at'] = $deleted_at; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param integer $offset Offset + * + * @return boolean + */ + public function offsetExists($offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer $offset Offset + * + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function offsetGet($offset) + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer $offset Offset + * + * @return void + */ + public function offsetUnset($offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue() + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} + + diff --git a/omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/UpdateAssignmentRequest.php b/omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/UpdateAssignmentRequest.php new file mode 100644 index 0000000..7075a2f --- /dev/null +++ b/omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/UpdateAssignmentRequest.php @@ -0,0 +1,416 @@ + + */ +class UpdateAssignmentRequest implements ModelInterface, ArrayAccess, \JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static $openAPIModelName = 'UpdateAssignmentRequest'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPITypes = [ + 'note' => 'string' + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + * @phpstan-var array + * @psalm-var array + */ + protected static $openAPIFormats = [ + 'note' => null + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var boolean[] + */ + protected static array $openAPINullables = [ + 'note' => true + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var boolean[] + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return boolean[] + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param boolean[] $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + 'note' => 'note' + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + 'note' => 'setNote' + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + 'note' => 'getNote' + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[]|null $data Associated array of property values + * initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('note', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets note + * + * @return string|null + */ + public function getNote() + { + return $this->container['note']; + } + + /** + * Sets note + * + * @param string|null $note note + * + * @return self + */ + public function setNote($note) + { + if (is_null($note)) { + array_push($this->openAPINullablesSetToNull, 'note'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('note', $nullablesSetToNull); + if ($index !== FALSE) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + $this->container['note'] = $note; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param integer $offset Offset + * + * @return boolean + */ + public function offsetExists($offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer $offset Offset + * + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function offsetGet($offset) + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer $offset Offset + * + * @return void + */ + public function offsetUnset($offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue() + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} + + diff --git a/omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/UpdateAssignmentValidationSettingsRequest.php b/omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/UpdateAssignmentValidationSettingsRequest.php new file mode 100644 index 0000000..d8480b2 --- /dev/null +++ b/omsorgWeb/mitarbeiter-app/api-client-php/lib/Model/UpdateAssignmentValidationSettingsRequest.php @@ -0,0 +1,580 @@ + + */ +class UpdateAssignmentValidationSettingsRequest implements ModelInterface, ArrayAccess, \JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static $openAPIModelName = 'UpdateAssignmentValidationSettingsRequest'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPITypes = [ + 'qualification_mode' => 'string', + 'absence_mode' => 'string', + 'working_hours_mode' => 'string', + 'overlap_mode' => 'string', + 'contract_mode' => 'string' + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + * @phpstan-var array + * @psalm-var array + */ + protected static $openAPIFormats = [ + 'qualification_mode' => null, + 'absence_mode' => null, + 'working_hours_mode' => null, + 'overlap_mode' => null, + 'contract_mode' => null + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var boolean[] + */ + protected static array $openAPINullables = [ + 'qualification_mode' => true, + 'absence_mode' => true, + 'working_hours_mode' => true, + 'overlap_mode' => true, + 'contract_mode' => true + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var boolean[] + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return boolean[] + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param boolean[] $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + 'qualification_mode' => 'qualificationMode', + 'absence_mode' => 'absenceMode', + 'working_hours_mode' => 'workingHoursMode', + 'overlap_mode' => 'overlapMode', + 'contract_mode' => 'contractMode' + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + 'qualification_mode' => 'setQualificationMode', + 'absence_mode' => 'setAbsenceMode', + 'working_hours_mode' => 'setWorkingHoursMode', + 'overlap_mode' => 'setOverlapMode', + 'contract_mode' => 'setContractMode' + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + 'qualification_mode' => 'getQualificationMode', + 'absence_mode' => 'getAbsenceMode', + 'working_hours_mode' => 'getWorkingHoursMode', + 'overlap_mode' => 'getOverlapMode', + 'contract_mode' => 'getContractMode' + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[]|null $data Associated array of property values + * initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('qualification_mode', $data ?? [], null); + $this->setIfExists('absence_mode', $data ?? [], null); + $this->setIfExists('working_hours_mode', $data ?? [], null); + $this->setIfExists('overlap_mode', $data ?? [], null); + $this->setIfExists('contract_mode', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets qualification_mode + * + * @return string|null + */ + public function getQualificationMode() + { + return $this->container['qualification_mode']; + } + + /** + * Sets qualification_mode + * + * @param string|null $qualification_mode qualification_mode + * + * @return self + */ + public function setQualificationMode($qualification_mode) + { + if (is_null($qualification_mode)) { + array_push($this->openAPINullablesSetToNull, 'qualification_mode'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('qualification_mode', $nullablesSetToNull); + if ($index !== FALSE) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + $this->container['qualification_mode'] = $qualification_mode; + + return $this; + } + + /** + * Gets absence_mode + * + * @return string|null + */ + public function getAbsenceMode() + { + return $this->container['absence_mode']; + } + + /** + * Sets absence_mode + * + * @param string|null $absence_mode absence_mode + * + * @return self + */ + public function setAbsenceMode($absence_mode) + { + if (is_null($absence_mode)) { + array_push($this->openAPINullablesSetToNull, 'absence_mode'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('absence_mode', $nullablesSetToNull); + if ($index !== FALSE) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + $this->container['absence_mode'] = $absence_mode; + + return $this; + } + + /** + * Gets working_hours_mode + * + * @return string|null + */ + public function getWorkingHoursMode() + { + return $this->container['working_hours_mode']; + } + + /** + * Sets working_hours_mode + * + * @param string|null $working_hours_mode working_hours_mode + * + * @return self + */ + public function setWorkingHoursMode($working_hours_mode) + { + if (is_null($working_hours_mode)) { + array_push($this->openAPINullablesSetToNull, 'working_hours_mode'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('working_hours_mode', $nullablesSetToNull); + if ($index !== FALSE) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + $this->container['working_hours_mode'] = $working_hours_mode; + + return $this; + } + + /** + * Gets overlap_mode + * + * @return string|null + */ + public function getOverlapMode() + { + return $this->container['overlap_mode']; + } + + /** + * Sets overlap_mode + * + * @param string|null $overlap_mode overlap_mode + * + * @return self + */ + public function setOverlapMode($overlap_mode) + { + if (is_null($overlap_mode)) { + array_push($this->openAPINullablesSetToNull, 'overlap_mode'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('overlap_mode', $nullablesSetToNull); + if ($index !== FALSE) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + $this->container['overlap_mode'] = $overlap_mode; + + return $this; + } + + /** + * Gets contract_mode + * + * @return string|null + */ + public function getContractMode() + { + return $this->container['contract_mode']; + } + + /** + * Sets contract_mode + * + * @param string|null $contract_mode contract_mode + * + * @return self + */ + public function setContractMode($contract_mode) + { + if (is_null($contract_mode)) { + array_push($this->openAPINullablesSetToNull, 'contract_mode'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('contract_mode', $nullablesSetToNull); + if ($index !== FALSE) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + $this->container['contract_mode'] = $contract_mode; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param integer $offset Offset + * + * @return boolean + */ + public function offsetExists($offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer $offset Offset + * + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function offsetGet($offset) + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer $offset Offset + * + * @return void + */ + public function offsetUnset($offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue() + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} + + diff --git a/omsorgWeb/mitarbeiter-app/api-client-php/test/Api/AssignmentValidationSettingsApiTest.php b/omsorgWeb/mitarbeiter-app/api-client-php/test/Api/AssignmentValidationSettingsApiTest.php new file mode 100644 index 0000000..be116d9 --- /dev/null +++ b/omsorgWeb/mitarbeiter-app/api-client-php/test/Api/AssignmentValidationSettingsApiTest.php @@ -0,0 +1,97 @@ +> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("Bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + + let urlPath = `/api/settings/assignment-validation`; + + const response = await this.request({ + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => AssignmentValidationSettingsResponseFromJSON(jsonValue)); + } + + /** + */ + async apiSettingsAssignmentValidationGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.apiSettingsAssignmentValidationGetRaw(initOverrides); + return await response.value(); + } + + /** + */ + async apiSettingsAssignmentValidationPutRaw(requestParameters: ApiSettingsAssignmentValidationPutRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("Bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + + let urlPath = `/api/settings/assignment-validation`; + + const response = await this.request({ + path: urlPath, + method: 'PUT', + headers: headerParameters, + query: queryParameters, + body: UpdateAssignmentValidationSettingsRequestToJSON(requestParameters['updateAssignmentValidationSettingsRequest']), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => AssignmentValidationSettingsResponseFromJSON(jsonValue)); + } + + /** + */ + async apiSettingsAssignmentValidationPut(requestParameters: ApiSettingsAssignmentValidationPutRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.apiSettingsAssignmentValidationPutRaw(requestParameters, initOverrides); + return await response.value(); + } + +} diff --git a/omsorgapp/api-client-ts/src/apis/AssignmentsApi.ts b/omsorgapp/api-client-ts/src/apis/AssignmentsApi.ts new file mode 100644 index 0000000..488c870 --- /dev/null +++ b/omsorgapp/api-client-ts/src/apis/AssignmentsApi.ts @@ -0,0 +1,359 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * OmsorgCore.Api + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import * as runtime from '../runtime'; +import type { + AssignmentConflictResponse, + AssignmentResponse, + AssignmentResponsePagedResponse, + CreateAssignmentRequest, + UpdateAssignmentRequest, +} from '../models/index'; +import { + AssignmentConflictResponseFromJSON, + AssignmentConflictResponseToJSON, + AssignmentResponseFromJSON, + AssignmentResponseToJSON, + AssignmentResponsePagedResponseFromJSON, + AssignmentResponsePagedResponseToJSON, + CreateAssignmentRequestFromJSON, + CreateAssignmentRequestToJSON, + UpdateAssignmentRequestFromJSON, + UpdateAssignmentRequestToJSON, +} from '../models/index'; + +export interface ApiAssignmentsCheckGetRequest { + orderId?: string; + employeeId?: string; + startDate?: Date; + endDate?: Date; + excludeAssignmentId?: string; +} + +export interface ApiAssignmentsGetRequest { + orderId?: string; + employeeId?: string; + fromDate?: Date; + toDate?: Date; + page?: number; + pageSize?: number; +} + +export interface ApiAssignmentsIdDeleteRequest { + id: string; +} + +export interface ApiAssignmentsIdGetRequest { + id: string; +} + +export interface ApiAssignmentsIdPutRequest { + id: string; + updateAssignmentRequest?: UpdateAssignmentRequest; +} + +export interface ApiAssignmentsPostRequest { + createAssignmentRequest?: CreateAssignmentRequest; +} + +/** + * + */ +export class AssignmentsApi extends runtime.BaseAPI { + + /** + */ + async apiAssignmentsCheckGetRaw(requestParameters: ApiAssignmentsCheckGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + const queryParameters: any = {}; + + if (requestParameters['orderId'] != null) { + queryParameters['orderId'] = requestParameters['orderId']; + } + + if (requestParameters['employeeId'] != null) { + queryParameters['employeeId'] = requestParameters['employeeId']; + } + + if (requestParameters['startDate'] != null) { + queryParameters['startDate'] = (requestParameters['startDate'] as any).toISOString().substring(0,10); + } + + if (requestParameters['endDate'] != null) { + queryParameters['endDate'] = (requestParameters['endDate'] as any).toISOString().substring(0,10); + } + + if (requestParameters['excludeAssignmentId'] != null) { + queryParameters['excludeAssignmentId'] = requestParameters['excludeAssignmentId']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("Bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + + let urlPath = `/api/assignments/check`; + + const response = await this.request({ + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(AssignmentConflictResponseFromJSON)); + } + + /** + */ + async apiAssignmentsCheckGet(requestParameters: ApiAssignmentsCheckGetRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.apiAssignmentsCheckGetRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async apiAssignmentsGetRaw(requestParameters: ApiAssignmentsGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + if (requestParameters['orderId'] != null) { + queryParameters['orderId'] = requestParameters['orderId']; + } + + if (requestParameters['employeeId'] != null) { + queryParameters['employeeId'] = requestParameters['employeeId']; + } + + if (requestParameters['fromDate'] != null) { + queryParameters['fromDate'] = (requestParameters['fromDate'] as any).toISOString().substring(0,10); + } + + if (requestParameters['toDate'] != null) { + queryParameters['toDate'] = (requestParameters['toDate'] as any).toISOString().substring(0,10); + } + + if (requestParameters['page'] != null) { + queryParameters['page'] = requestParameters['page']; + } + + if (requestParameters['pageSize'] != null) { + queryParameters['pageSize'] = requestParameters['pageSize']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("Bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + + let urlPath = `/api/assignments`; + + const response = await this.request({ + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => AssignmentResponsePagedResponseFromJSON(jsonValue)); + } + + /** + */ + async apiAssignmentsGet(requestParameters: ApiAssignmentsGetRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.apiAssignmentsGetRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async apiAssignmentsIdDeleteRaw(requestParameters: ApiAssignmentsIdDeleteRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters['id'] == null) { + throw new runtime.RequiredError( + 'id', + 'Required parameter "id" was null or undefined when calling apiAssignmentsIdDelete().' + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("Bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + + let urlPath = `/api/assignments/{id}`; + urlPath = urlPath.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters['id']))); + + const response = await this.request({ + path: urlPath, + method: 'DELETE', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.VoidApiResponse(response); + } + + /** + */ + async apiAssignmentsIdDelete(requestParameters: ApiAssignmentsIdDeleteRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.apiAssignmentsIdDeleteRaw(requestParameters, initOverrides); + } + + /** + */ + async apiAssignmentsIdGetRaw(requestParameters: ApiAssignmentsIdGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters['id'] == null) { + throw new runtime.RequiredError( + 'id', + 'Required parameter "id" was null or undefined when calling apiAssignmentsIdGet().' + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("Bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + + let urlPath = `/api/assignments/{id}`; + urlPath = urlPath.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters['id']))); + + const response = await this.request({ + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => AssignmentResponseFromJSON(jsonValue)); + } + + /** + */ + async apiAssignmentsIdGet(requestParameters: ApiAssignmentsIdGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.apiAssignmentsIdGetRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async apiAssignmentsIdPutRaw(requestParameters: ApiAssignmentsIdPutRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters['id'] == null) { + throw new runtime.RequiredError( + 'id', + 'Required parameter "id" was null or undefined when calling apiAssignmentsIdPut().' + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("Bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + + let urlPath = `/api/assignments/{id}`; + urlPath = urlPath.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters['id']))); + + const response = await this.request({ + path: urlPath, + method: 'PUT', + headers: headerParameters, + query: queryParameters, + body: UpdateAssignmentRequestToJSON(requestParameters['updateAssignmentRequest']), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => AssignmentResponseFromJSON(jsonValue)); + } + + /** + */ + async apiAssignmentsIdPut(requestParameters: ApiAssignmentsIdPutRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.apiAssignmentsIdPutRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async apiAssignmentsPostRaw(requestParameters: ApiAssignmentsPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("Bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + + let urlPath = `/api/assignments`; + + const response = await this.request({ + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: CreateAssignmentRequestToJSON(requestParameters['createAssignmentRequest']), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => AssignmentResponseFromJSON(jsonValue)); + } + + /** + */ + async apiAssignmentsPost(requestParameters: ApiAssignmentsPostRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.apiAssignmentsPostRaw(requestParameters, initOverrides); + return await response.value(); + } + +} diff --git a/omsorgapp/api-client-ts/src/apis/TrashApi.ts b/omsorgapp/api-client-ts/src/apis/TrashApi.ts index 3e5f614..004a3cb 100644 --- a/omsorgapp/api-client-ts/src/apis/TrashApi.ts +++ b/omsorgapp/api-client-ts/src/apis/TrashApi.ts @@ -16,6 +16,7 @@ import * as runtime from '../runtime'; import type { TrashAbsenceResponse, + TrashAssignmentResponse, TrashContractResponse, TrashEmployeeFacilityDistanceResponse, TrashEmployeeResponse, @@ -28,6 +29,8 @@ import type { import { TrashAbsenceResponseFromJSON, TrashAbsenceResponseToJSON, + TrashAssignmentResponseFromJSON, + TrashAssignmentResponseToJSON, TrashContractResponseFromJSON, TrashContractResponseToJSON, TrashEmployeeFacilityDistanceResponseFromJSON, @@ -54,6 +57,14 @@ export interface ApiTrashAbsencesIdRestorePostRequest { id: string; } +export interface ApiTrashAssignmentsGetRequest { + search?: string; +} + +export interface ApiTrashAssignmentsIdRestorePostRequest { + id: string; +} + export interface ApiTrashContractsGetRequest { search?: string; } @@ -204,6 +215,87 @@ export class TrashApi extends runtime.BaseAPI { await this.apiTrashAbsencesIdRestorePostRaw(requestParameters, initOverrides); } + /** + */ + async apiTrashAssignmentsGetRaw(requestParameters: ApiTrashAssignmentsGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + const queryParameters: any = {}; + + if (requestParameters['search'] != null) { + queryParameters['search'] = requestParameters['search']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("Bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + + let urlPath = `/api/trash/assignments`; + + const response = await this.request({ + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(TrashAssignmentResponseFromJSON)); + } + + /** + */ + async apiTrashAssignmentsGet(requestParameters: ApiTrashAssignmentsGetRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.apiTrashAssignmentsGetRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async apiTrashAssignmentsIdRestorePostRaw(requestParameters: ApiTrashAssignmentsIdRestorePostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters['id'] == null) { + throw new runtime.RequiredError( + 'id', + 'Required parameter "id" was null or undefined when calling apiTrashAssignmentsIdRestorePost().' + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("Bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + + let urlPath = `/api/trash/assignments/{id}/restore`; + urlPath = urlPath.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters['id']))); + + const response = await this.request({ + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.VoidApiResponse(response); + } + + /** + */ + async apiTrashAssignmentsIdRestorePost(requestParameters: ApiTrashAssignmentsIdRestorePostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.apiTrashAssignmentsIdRestorePostRaw(requestParameters, initOverrides); + } + /** */ async apiTrashContractsGetRaw(requestParameters: ApiTrashContractsGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { diff --git a/omsorgapp/api-client-ts/src/apis/index.ts b/omsorgapp/api-client-ts/src/apis/index.ts index a6c973a..dd54562 100644 --- a/omsorgapp/api-client-ts/src/apis/index.ts +++ b/omsorgapp/api-client-ts/src/apis/index.ts @@ -3,6 +3,8 @@ export * from './AbsencesApi'; export * from './AdminEmailApi'; export * from './AdminSessionsApi'; +export * from './AssignmentValidationSettingsApi'; +export * from './AssignmentsApi'; export * from './AuditLogApi'; export * from './AuthApi'; export * from './ContractsApi'; diff --git a/omsorgapp/api-client-ts/src/models/AssignmentConflictResponse.ts b/omsorgapp/api-client-ts/src/models/AssignmentConflictResponse.ts new file mode 100644 index 0000000..65edaba --- /dev/null +++ b/omsorgapp/api-client-ts/src/models/AssignmentConflictResponse.ts @@ -0,0 +1,81 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * OmsorgCore.Api + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface AssignmentConflictResponse + */ +export interface AssignmentConflictResponse { + /** + * + * @type {string} + * @memberof AssignmentConflictResponse + */ + type?: string | null; + /** + * + * @type {string} + * @memberof AssignmentConflictResponse + */ + severity?: string | null; + /** + * + * @type {string} + * @memberof AssignmentConflictResponse + */ + message?: string | null; +} + +/** + * Check if a given object implements the AssignmentConflictResponse interface. + */ +export function instanceOfAssignmentConflictResponse(value: object): value is AssignmentConflictResponse { + return true; +} + +export function AssignmentConflictResponseFromJSON(json: any): AssignmentConflictResponse { + return AssignmentConflictResponseFromJSONTyped(json, false); +} + +export function AssignmentConflictResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): AssignmentConflictResponse { + if (json == null) { + return json; + } + return { + + 'type': json['type'] == null ? undefined : json['type'], + 'severity': json['severity'] == null ? undefined : json['severity'], + 'message': json['message'] == null ? undefined : json['message'], + }; +} + +export function AssignmentConflictResponseToJSON(json: any): AssignmentConflictResponse { + return AssignmentConflictResponseToJSONTyped(json, false); +} + +export function AssignmentConflictResponseToJSONTyped(value?: AssignmentConflictResponse | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'type': value['type'], + 'severity': value['severity'], + 'message': value['message'], + }; +} + diff --git a/omsorgapp/api-client-ts/src/models/AssignmentResponse.ts b/omsorgapp/api-client-ts/src/models/AssignmentResponse.ts new file mode 100644 index 0000000..5ebd192 --- /dev/null +++ b/omsorgapp/api-client-ts/src/models/AssignmentResponse.ts @@ -0,0 +1,137 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * OmsorgCore.Api + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +import type { AssignmentConflictResponse } from './AssignmentConflictResponse'; +import { + AssignmentConflictResponseFromJSON, + AssignmentConflictResponseFromJSONTyped, + AssignmentConflictResponseToJSON, + AssignmentConflictResponseToJSONTyped, +} from './AssignmentConflictResponse'; + +/** + * + * @export + * @interface AssignmentResponse + */ +export interface AssignmentResponse { + /** + * + * @type {string} + * @memberof AssignmentResponse + */ + id?: string; + /** + * + * @type {string} + * @memberof AssignmentResponse + */ + orderId?: string; + /** + * + * @type {string} + * @memberof AssignmentResponse + */ + employeeId?: string; + /** + * + * @type {string} + * @memberof AssignmentResponse + */ + employeeFirstName?: string | null; + /** + * + * @type {string} + * @memberof AssignmentResponse + */ + employeeLastName?: string | null; + /** + * + * @type {Date} + * @memberof AssignmentResponse + */ + startDate?: Date; + /** + * + * @type {Date} + * @memberof AssignmentResponse + */ + endDate?: Date; + /** + * + * @type {string} + * @memberof AssignmentResponse + */ + note?: string | null; + /** + * + * @type {Array} + * @memberof AssignmentResponse + */ + conflicts?: Array | null; +} + +/** + * Check if a given object implements the AssignmentResponse interface. + */ +export function instanceOfAssignmentResponse(value: object): value is AssignmentResponse { + return true; +} + +export function AssignmentResponseFromJSON(json: any): AssignmentResponse { + return AssignmentResponseFromJSONTyped(json, false); +} + +export function AssignmentResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): AssignmentResponse { + if (json == null) { + return json; + } + return { + + 'id': json['id'] == null ? undefined : json['id'], + 'orderId': json['orderId'] == null ? undefined : json['orderId'], + 'employeeId': json['employeeId'] == null ? undefined : json['employeeId'], + 'employeeFirstName': json['employeeFirstName'] == null ? undefined : json['employeeFirstName'], + 'employeeLastName': json['employeeLastName'] == null ? undefined : json['employeeLastName'], + 'startDate': json['startDate'] == null ? undefined : (new Date(json['startDate'])), + 'endDate': json['endDate'] == null ? undefined : (new Date(json['endDate'])), + 'note': json['note'] == null ? undefined : json['note'], + 'conflicts': json['conflicts'] == null ? undefined : ((json['conflicts'] as Array).map(AssignmentConflictResponseFromJSON)), + }; +} + +export function AssignmentResponseToJSON(json: any): AssignmentResponse { + return AssignmentResponseToJSONTyped(json, false); +} + +export function AssignmentResponseToJSONTyped(value?: AssignmentResponse | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'id': value['id'], + 'orderId': value['orderId'], + 'employeeId': value['employeeId'], + 'employeeFirstName': value['employeeFirstName'], + 'employeeLastName': value['employeeLastName'], + 'startDate': value['startDate'] == null ? undefined : ((value['startDate']).toISOString().substring(0,10)), + 'endDate': value['endDate'] == null ? undefined : ((value['endDate']).toISOString().substring(0,10)), + 'note': value['note'], + 'conflicts': value['conflicts'] == null ? undefined : ((value['conflicts'] as Array).map(AssignmentConflictResponseToJSON)), + }; +} + diff --git a/omsorgapp/api-client-ts/src/models/AssignmentResponsePagedResponse.ts b/omsorgapp/api-client-ts/src/models/AssignmentResponsePagedResponse.ts new file mode 100644 index 0000000..d7066cc --- /dev/null +++ b/omsorgapp/api-client-ts/src/models/AssignmentResponsePagedResponse.ts @@ -0,0 +1,97 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * OmsorgCore.Api + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +import type { AssignmentResponse } from './AssignmentResponse'; +import { + AssignmentResponseFromJSON, + AssignmentResponseFromJSONTyped, + AssignmentResponseToJSON, + AssignmentResponseToJSONTyped, +} from './AssignmentResponse'; + +/** + * + * @export + * @interface AssignmentResponsePagedResponse + */ +export interface AssignmentResponsePagedResponse { + /** + * + * @type {Array} + * @memberof AssignmentResponsePagedResponse + */ + items?: Array | null; + /** + * + * @type {number} + * @memberof AssignmentResponsePagedResponse + */ + totalCount?: number; + /** + * + * @type {number} + * @memberof AssignmentResponsePagedResponse + */ + page?: number; + /** + * + * @type {number} + * @memberof AssignmentResponsePagedResponse + */ + pageSize?: number; +} + +/** + * Check if a given object implements the AssignmentResponsePagedResponse interface. + */ +export function instanceOfAssignmentResponsePagedResponse(value: object): value is AssignmentResponsePagedResponse { + return true; +} + +export function AssignmentResponsePagedResponseFromJSON(json: any): AssignmentResponsePagedResponse { + return AssignmentResponsePagedResponseFromJSONTyped(json, false); +} + +export function AssignmentResponsePagedResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): AssignmentResponsePagedResponse { + if (json == null) { + return json; + } + return { + + 'items': json['items'] == null ? undefined : ((json['items'] as Array).map(AssignmentResponseFromJSON)), + 'totalCount': json['totalCount'] == null ? undefined : json['totalCount'], + 'page': json['page'] == null ? undefined : json['page'], + 'pageSize': json['pageSize'] == null ? undefined : json['pageSize'], + }; +} + +export function AssignmentResponsePagedResponseToJSON(json: any): AssignmentResponsePagedResponse { + return AssignmentResponsePagedResponseToJSONTyped(json, false); +} + +export function AssignmentResponsePagedResponseToJSONTyped(value?: AssignmentResponsePagedResponse | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'items': value['items'] == null ? undefined : ((value['items'] as Array).map(AssignmentResponseToJSON)), + 'totalCount': value['totalCount'], + 'page': value['page'], + 'pageSize': value['pageSize'], + }; +} + diff --git a/omsorgapp/api-client-ts/src/models/AssignmentValidationSettingsResponse.ts b/omsorgapp/api-client-ts/src/models/AssignmentValidationSettingsResponse.ts new file mode 100644 index 0000000..e6ff71a --- /dev/null +++ b/omsorgapp/api-client-ts/src/models/AssignmentValidationSettingsResponse.ts @@ -0,0 +1,97 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * OmsorgCore.Api + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface AssignmentValidationSettingsResponse + */ +export interface AssignmentValidationSettingsResponse { + /** + * + * @type {string} + * @memberof AssignmentValidationSettingsResponse + */ + qualificationMode?: string | null; + /** + * + * @type {string} + * @memberof AssignmentValidationSettingsResponse + */ + absenceMode?: string | null; + /** + * + * @type {string} + * @memberof AssignmentValidationSettingsResponse + */ + workingHoursMode?: string | null; + /** + * + * @type {string} + * @memberof AssignmentValidationSettingsResponse + */ + overlapMode?: string | null; + /** + * + * @type {string} + * @memberof AssignmentValidationSettingsResponse + */ + contractMode?: string | null; +} + +/** + * Check if a given object implements the AssignmentValidationSettingsResponse interface. + */ +export function instanceOfAssignmentValidationSettingsResponse(value: object): value is AssignmentValidationSettingsResponse { + return true; +} + +export function AssignmentValidationSettingsResponseFromJSON(json: any): AssignmentValidationSettingsResponse { + return AssignmentValidationSettingsResponseFromJSONTyped(json, false); +} + +export function AssignmentValidationSettingsResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): AssignmentValidationSettingsResponse { + if (json == null) { + return json; + } + return { + + 'qualificationMode': json['qualificationMode'] == null ? undefined : json['qualificationMode'], + 'absenceMode': json['absenceMode'] == null ? undefined : json['absenceMode'], + 'workingHoursMode': json['workingHoursMode'] == null ? undefined : json['workingHoursMode'], + 'overlapMode': json['overlapMode'] == null ? undefined : json['overlapMode'], + 'contractMode': json['contractMode'] == null ? undefined : json['contractMode'], + }; +} + +export function AssignmentValidationSettingsResponseToJSON(json: any): AssignmentValidationSettingsResponse { + return AssignmentValidationSettingsResponseToJSONTyped(json, false); +} + +export function AssignmentValidationSettingsResponseToJSONTyped(value?: AssignmentValidationSettingsResponse | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'qualificationMode': value['qualificationMode'], + 'absenceMode': value['absenceMode'], + 'workingHoursMode': value['workingHoursMode'], + 'overlapMode': value['overlapMode'], + 'contractMode': value['contractMode'], + }; +} + diff --git a/omsorgapp/api-client-ts/src/models/CreateAssignmentRequest.ts b/omsorgapp/api-client-ts/src/models/CreateAssignmentRequest.ts new file mode 100644 index 0000000..ff14fc2 --- /dev/null +++ b/omsorgapp/api-client-ts/src/models/CreateAssignmentRequest.ts @@ -0,0 +1,97 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * OmsorgCore.Api + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface CreateAssignmentRequest + */ +export interface CreateAssignmentRequest { + /** + * + * @type {string} + * @memberof CreateAssignmentRequest + */ + orderId?: string; + /** + * + * @type {string} + * @memberof CreateAssignmentRequest + */ + employeeId?: string; + /** + * + * @type {Date} + * @memberof CreateAssignmentRequest + */ + startDate?: Date; + /** + * + * @type {Date} + * @memberof CreateAssignmentRequest + */ + endDate?: Date; + /** + * + * @type {string} + * @memberof CreateAssignmentRequest + */ + note?: string | null; +} + +/** + * Check if a given object implements the CreateAssignmentRequest interface. + */ +export function instanceOfCreateAssignmentRequest(value: object): value is CreateAssignmentRequest { + return true; +} + +export function CreateAssignmentRequestFromJSON(json: any): CreateAssignmentRequest { + return CreateAssignmentRequestFromJSONTyped(json, false); +} + +export function CreateAssignmentRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreateAssignmentRequest { + if (json == null) { + return json; + } + return { + + 'orderId': json['orderId'] == null ? undefined : json['orderId'], + 'employeeId': json['employeeId'] == null ? undefined : json['employeeId'], + 'startDate': json['startDate'] == null ? undefined : (new Date(json['startDate'])), + 'endDate': json['endDate'] == null ? undefined : (new Date(json['endDate'])), + 'note': json['note'] == null ? undefined : json['note'], + }; +} + +export function CreateAssignmentRequestToJSON(json: any): CreateAssignmentRequest { + return CreateAssignmentRequestToJSONTyped(json, false); +} + +export function CreateAssignmentRequestToJSONTyped(value?: CreateAssignmentRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'orderId': value['orderId'], + 'employeeId': value['employeeId'], + 'startDate': value['startDate'] == null ? undefined : ((value['startDate']).toISOString().substring(0,10)), + 'endDate': value['endDate'] == null ? undefined : ((value['endDate']).toISOString().substring(0,10)), + 'note': value['note'], + }; +} + diff --git a/omsorgapp/api-client-ts/src/models/CreateFacilityRequest.ts b/omsorgapp/api-client-ts/src/models/CreateFacilityRequest.ts index 4d82daf..8e90ac2 100644 --- a/omsorgapp/api-client-ts/src/models/CreateFacilityRequest.ts +++ b/omsorgapp/api-client-ts/src/models/CreateFacilityRequest.ts @@ -25,6 +25,12 @@ export interface CreateFacilityRequest { * @memberof CreateFacilityRequest */ name?: string | null; + /** + * + * @type {string} + * @memberof CreateFacilityRequest + */ + crmStatus?: string | null; /** * * @type {string} @@ -85,6 +91,90 @@ export interface CreateFacilityRequest { * @memberof CreateFacilityRequest */ billingCountry?: string | null; + /** + * + * @type {number} + * @memberof CreateFacilityRequest + */ + followUpDays?: number | null; + /** + * + * @type {number} + * @memberof CreateFacilityRequest + */ + billingRate?: number | null; + /** + * + * @type {number} + * @memberof CreateFacilityRequest + */ + nightSurchargePercent?: number | null; + /** + * + * @type {number} + * @memberof CreateFacilityRequest + */ + saturdaySurchargePercent?: number | null; + /** + * + * @type {number} + * @memberof CreateFacilityRequest + */ + sundaySurchargePercent?: number | null; + /** + * + * @type {number} + * @memberof CreateFacilityRequest + */ + holidaySurchargePercent?: number | null; + /** + * + * @type {number} + * @memberof CreateFacilityRequest + */ + travelCostRate?: number | null; + /** + * + * @type {string} + * @memberof CreateFacilityRequest + */ + travelCostMode?: string | null; + /** + * + * @type {number} + * @memberof CreateFacilityRequest + */ + travelCostPerKm?: number | null; + /** + * + * @type {number} + * @memberof CreateFacilityRequest + */ + mealAllowanceRate?: number | null; + /** + * + * @type {number} + * @memberof CreateFacilityRequest + */ + minimumHours?: number | null; + /** + * + * @type {string} + * @memberof CreateFacilityRequest + */ + billingInterval?: string | null; + /** + * + * @type {number} + * @memberof CreateFacilityRequest + */ + paymentTermDays?: number | null; + /** + * + * @type {string} + * @memberof CreateFacilityRequest + */ + individualAgreements?: string | null; } /** @@ -105,6 +195,7 @@ export function CreateFacilityRequestFromJSONTyped(json: any, ignoreDiscriminato return { 'name': json['name'] == null ? undefined : json['name'], + 'crmStatus': json['crmStatus'] == null ? undefined : json['crmStatus'], 'facilityType': json['facilityType'] == null ? undefined : json['facilityType'], 'website': json['website'] == null ? undefined : json['website'], 'street': json['street'] == null ? undefined : json['street'], @@ -115,6 +206,20 @@ export function CreateFacilityRequestFromJSONTyped(json: any, ignoreDiscriminato 'billingPostalCode': json['billingPostalCode'] == null ? undefined : json['billingPostalCode'], 'billingCity': json['billingCity'] == null ? undefined : json['billingCity'], 'billingCountry': json['billingCountry'] == null ? undefined : json['billingCountry'], + 'followUpDays': json['followUpDays'] == null ? undefined : json['followUpDays'], + 'billingRate': json['billingRate'] == null ? undefined : json['billingRate'], + 'nightSurchargePercent': json['nightSurchargePercent'] == null ? undefined : json['nightSurchargePercent'], + 'saturdaySurchargePercent': json['saturdaySurchargePercent'] == null ? undefined : json['saturdaySurchargePercent'], + 'sundaySurchargePercent': json['sundaySurchargePercent'] == null ? undefined : json['sundaySurchargePercent'], + 'holidaySurchargePercent': json['holidaySurchargePercent'] == null ? undefined : json['holidaySurchargePercent'], + 'travelCostRate': json['travelCostRate'] == null ? undefined : json['travelCostRate'], + 'travelCostMode': json['travelCostMode'] == null ? undefined : json['travelCostMode'], + 'travelCostPerKm': json['travelCostPerKm'] == null ? undefined : json['travelCostPerKm'], + 'mealAllowanceRate': json['mealAllowanceRate'] == null ? undefined : json['mealAllowanceRate'], + 'minimumHours': json['minimumHours'] == null ? undefined : json['minimumHours'], + 'billingInterval': json['billingInterval'] == null ? undefined : json['billingInterval'], + 'paymentTermDays': json['paymentTermDays'] == null ? undefined : json['paymentTermDays'], + 'individualAgreements': json['individualAgreements'] == null ? undefined : json['individualAgreements'], }; } @@ -130,6 +235,7 @@ export function CreateFacilityRequestToJSONTyped(value?: CreateFacilityRequest | return { 'name': value['name'], + 'crmStatus': value['crmStatus'], 'facilityType': value['facilityType'], 'website': value['website'], 'street': value['street'], @@ -140,6 +246,20 @@ export function CreateFacilityRequestToJSONTyped(value?: CreateFacilityRequest | 'billingPostalCode': value['billingPostalCode'], 'billingCity': value['billingCity'], 'billingCountry': value['billingCountry'], + 'followUpDays': value['followUpDays'], + 'billingRate': value['billingRate'], + 'nightSurchargePercent': value['nightSurchargePercent'], + 'saturdaySurchargePercent': value['saturdaySurchargePercent'], + 'sundaySurchargePercent': value['sundaySurchargePercent'], + 'holidaySurchargePercent': value['holidaySurchargePercent'], + 'travelCostRate': value['travelCostRate'], + 'travelCostMode': value['travelCostMode'], + 'travelCostPerKm': value['travelCostPerKm'], + 'mealAllowanceRate': value['mealAllowanceRate'], + 'minimumHours': value['minimumHours'], + 'billingInterval': value['billingInterval'], + 'paymentTermDays': value['paymentTermDays'], + 'individualAgreements': value['individualAgreements'], }; } diff --git a/omsorgapp/api-client-ts/src/models/ModuleType.ts b/omsorgapp/api-client-ts/src/models/ModuleType.ts index 72713d6..2b4517c 100644 --- a/omsorgapp/api-client-ts/src/models/ModuleType.ts +++ b/omsorgapp/api-client-ts/src/models/ModuleType.ts @@ -32,7 +32,8 @@ export const ModuleType = { Users: 'Users', Configuration: 'Configuration', Absences: 'Absences', - EmployeeFacilityDistances: 'EmployeeFacilityDistances' + EmployeeFacilityDistances: 'EmployeeFacilityDistances', + Assignments: 'Assignments' } as const; export type ModuleType = typeof ModuleType[keyof typeof ModuleType]; diff --git a/omsorgapp/api-client-ts/src/models/TrashAssignmentResponse.ts b/omsorgapp/api-client-ts/src/models/TrashAssignmentResponse.ts new file mode 100644 index 0000000..eb8e675 --- /dev/null +++ b/omsorgapp/api-client-ts/src/models/TrashAssignmentResponse.ts @@ -0,0 +1,89 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * OmsorgCore.Api + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface TrashAssignmentResponse + */ +export interface TrashAssignmentResponse { + /** + * + * @type {string} + * @memberof TrashAssignmentResponse + */ + id?: string; + /** + * + * @type {string} + * @memberof TrashAssignmentResponse + */ + employeeFirstName?: string | null; + /** + * + * @type {string} + * @memberof TrashAssignmentResponse + */ + employeeLastName?: string | null; + /** + * + * @type {Date} + * @memberof TrashAssignmentResponse + */ + deletedAt?: Date | null; +} + +/** + * Check if a given object implements the TrashAssignmentResponse interface. + */ +export function instanceOfTrashAssignmentResponse(value: object): value is TrashAssignmentResponse { + return true; +} + +export function TrashAssignmentResponseFromJSON(json: any): TrashAssignmentResponse { + return TrashAssignmentResponseFromJSONTyped(json, false); +} + +export function TrashAssignmentResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): TrashAssignmentResponse { + if (json == null) { + return json; + } + return { + + 'id': json['id'] == null ? undefined : json['id'], + 'employeeFirstName': json['employeeFirstName'] == null ? undefined : json['employeeFirstName'], + 'employeeLastName': json['employeeLastName'] == null ? undefined : json['employeeLastName'], + 'deletedAt': json['deletedAt'] == null ? undefined : (new Date(json['deletedAt'])), + }; +} + +export function TrashAssignmentResponseToJSON(json: any): TrashAssignmentResponse { + return TrashAssignmentResponseToJSONTyped(json, false); +} + +export function TrashAssignmentResponseToJSONTyped(value?: TrashAssignmentResponse | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'id': value['id'], + 'employeeFirstName': value['employeeFirstName'], + 'employeeLastName': value['employeeLastName'], + 'deletedAt': value['deletedAt'] === null ? null : ((value['deletedAt'] as any)?.toISOString()), + }; +} + diff --git a/omsorgapp/api-client-ts/src/models/UpdateAssignmentRequest.ts b/omsorgapp/api-client-ts/src/models/UpdateAssignmentRequest.ts new file mode 100644 index 0000000..fe30a07 --- /dev/null +++ b/omsorgapp/api-client-ts/src/models/UpdateAssignmentRequest.ts @@ -0,0 +1,65 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * OmsorgCore.Api + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface UpdateAssignmentRequest + */ +export interface UpdateAssignmentRequest { + /** + * + * @type {string} + * @memberof UpdateAssignmentRequest + */ + note?: string | null; +} + +/** + * Check if a given object implements the UpdateAssignmentRequest interface. + */ +export function instanceOfUpdateAssignmentRequest(value: object): value is UpdateAssignmentRequest { + return true; +} + +export function UpdateAssignmentRequestFromJSON(json: any): UpdateAssignmentRequest { + return UpdateAssignmentRequestFromJSONTyped(json, false); +} + +export function UpdateAssignmentRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): UpdateAssignmentRequest { + if (json == null) { + return json; + } + return { + + 'note': json['note'] == null ? undefined : json['note'], + }; +} + +export function UpdateAssignmentRequestToJSON(json: any): UpdateAssignmentRequest { + return UpdateAssignmentRequestToJSONTyped(json, false); +} + +export function UpdateAssignmentRequestToJSONTyped(value?: UpdateAssignmentRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'note': value['note'], + }; +} + diff --git a/omsorgapp/api-client-ts/src/models/UpdateAssignmentValidationSettingsRequest.ts b/omsorgapp/api-client-ts/src/models/UpdateAssignmentValidationSettingsRequest.ts new file mode 100644 index 0000000..cdb5a1a --- /dev/null +++ b/omsorgapp/api-client-ts/src/models/UpdateAssignmentValidationSettingsRequest.ts @@ -0,0 +1,97 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * OmsorgCore.Api + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface UpdateAssignmentValidationSettingsRequest + */ +export interface UpdateAssignmentValidationSettingsRequest { + /** + * + * @type {string} + * @memberof UpdateAssignmentValidationSettingsRequest + */ + qualificationMode?: string | null; + /** + * + * @type {string} + * @memberof UpdateAssignmentValidationSettingsRequest + */ + absenceMode?: string | null; + /** + * + * @type {string} + * @memberof UpdateAssignmentValidationSettingsRequest + */ + workingHoursMode?: string | null; + /** + * + * @type {string} + * @memberof UpdateAssignmentValidationSettingsRequest + */ + overlapMode?: string | null; + /** + * + * @type {string} + * @memberof UpdateAssignmentValidationSettingsRequest + */ + contractMode?: string | null; +} + +/** + * Check if a given object implements the UpdateAssignmentValidationSettingsRequest interface. + */ +export function instanceOfUpdateAssignmentValidationSettingsRequest(value: object): value is UpdateAssignmentValidationSettingsRequest { + return true; +} + +export function UpdateAssignmentValidationSettingsRequestFromJSON(json: any): UpdateAssignmentValidationSettingsRequest { + return UpdateAssignmentValidationSettingsRequestFromJSONTyped(json, false); +} + +export function UpdateAssignmentValidationSettingsRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): UpdateAssignmentValidationSettingsRequest { + if (json == null) { + return json; + } + return { + + 'qualificationMode': json['qualificationMode'] == null ? undefined : json['qualificationMode'], + 'absenceMode': json['absenceMode'] == null ? undefined : json['absenceMode'], + 'workingHoursMode': json['workingHoursMode'] == null ? undefined : json['workingHoursMode'], + 'overlapMode': json['overlapMode'] == null ? undefined : json['overlapMode'], + 'contractMode': json['contractMode'] == null ? undefined : json['contractMode'], + }; +} + +export function UpdateAssignmentValidationSettingsRequestToJSON(json: any): UpdateAssignmentValidationSettingsRequest { + return UpdateAssignmentValidationSettingsRequestToJSONTyped(json, false); +} + +export function UpdateAssignmentValidationSettingsRequestToJSONTyped(value?: UpdateAssignmentValidationSettingsRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'qualificationMode': value['qualificationMode'], + 'absenceMode': value['absenceMode'], + 'workingHoursMode': value['workingHoursMode'], + 'overlapMode': value['overlapMode'], + 'contractMode': value['contractMode'], + }; +} + diff --git a/omsorgapp/api-client-ts/src/models/index.ts b/omsorgapp/api-client-ts/src/models/index.ts index 1b4aa3a..e8853d6 100644 --- a/omsorgapp/api-client-ts/src/models/index.ts +++ b/omsorgapp/api-client-ts/src/models/index.ts @@ -4,6 +4,10 @@ export * from './AbsenceDecisionRequest'; export * from './AbsenceResponse'; export * from './AbsenceResponsePagedResponse'; export * from './AddUserPermissionOverrideRequest'; +export * from './AssignmentConflictResponse'; +export * from './AssignmentResponse'; +export * from './AssignmentResponsePagedResponse'; +export * from './AssignmentValidationSettingsResponse'; export * from './AuditEventCategory'; export * from './AuditLogEntryResponse'; export * from './AuditLogEntryResponsePagedResponse'; @@ -11,6 +15,7 @@ export * from './ChangePasswordRequest'; export * from './ContractResponse'; export * from './ContractResponsePagedResponse'; export * from './CreateAbsenceRequest'; +export * from './CreateAssignmentRequest'; export * from './CreateContractRequest'; export * from './CreateEmployeeFacilityDistanceRequest'; export * from './CreateEmployeeRequest'; @@ -61,6 +66,7 @@ export * from './TimeEntryDecisionRequest'; export * from './TimeEntryResponse'; export * from './TimeEntryResponsePagedResponse'; export * from './TrashAbsenceResponse'; +export * from './TrashAssignmentResponse'; export * from './TrashContractResponse'; export * from './TrashEmployeeFacilityDistanceResponse'; export * from './TrashEmployeeResponse'; @@ -70,6 +76,8 @@ export * from './TrashFacilityResponse'; export * from './TrashOrderResponse'; export * from './TrashTimeEntryResponse'; export * from './UpdateAbsenceRequest'; +export * from './UpdateAssignmentRequest'; +export * from './UpdateAssignmentValidationSettingsRequest'; export * from './UpdateContractRequest'; export * from './UpdateDocumentRequest'; export * from './UpdateEmployeeFacilityDistanceRequest'; diff --git a/omsorgapp/src/api/assignmentValidationSettingsApi.js b/omsorgapp/src/api/assignmentValidationSettingsApi.js new file mode 100644 index 0000000..94f8b90 --- /dev/null +++ b/omsorgapp/src/api/assignmentValidationSettingsApi.js @@ -0,0 +1,14 @@ +import { AssignmentValidationSettingsApi } from "omsorgcore-client-ts"; +import { configFor, callApi } from "./apiClientHelpers"; + +// Kapselt /api/settings/assignment-validation (FR-EM-3: Warning/Error je Konfliktprüfung bei +// der Mitarbeiterzuweisung, siehe omsorgCore/CLAUDE.md "Prüf-Logik in AssignmentService"). +export function getAssignmentValidationSettings(accessToken) { + const api = new AssignmentValidationSettingsApi(configFor(accessToken)); + return callApi(api.apiSettingsAssignmentValidationGetRaw()); +} + +export function updateAssignmentValidationSettings(accessToken, payload) { + const api = new AssignmentValidationSettingsApi(configFor(accessToken)); + return callApi(api.apiSettingsAssignmentValidationPutRaw({ updateAssignmentValidationSettingsRequest: payload })); +} diff --git a/omsorgapp/src/api/assignmentsApi.js b/omsorgapp/src/api/assignmentsApi.js new file mode 100644 index 0000000..b6b1562 --- /dev/null +++ b/omsorgapp/src/api/assignmentsApi.js @@ -0,0 +1,48 @@ +import { configFor, callApi } from "./apiClientHelpers"; +import { AssignmentsApi } from "omsorgcore-client-ts"; + +const API_BASE_URL = configFor(null).basePath; + +export function listAssignments(accessToken, { orderId, employeeId, fromDate, toDate, page = 1, pageSize = 20 } = {}) { + const api = new AssignmentsApi(configFor(accessToken)); + return callApi(api.apiAssignmentsGetRaw({ orderId, employeeId, fromDate, toDate, page, pageSize })); +} + +export function getAssignment(accessToken, id) { + const api = new AssignmentsApi(configFor(accessToken)); + return callApi(api.apiAssignmentsIdGetRaw({ id })); +} + +export function createAssignment(accessToken, payload) { + const api = new AssignmentsApi(configFor(accessToken)); + return callApi(api.apiAssignmentsPostRaw({ + createAssignmentRequest: { + ...payload, + startDate: payload.startDate ? new Date(payload.startDate) : payload.startDate, + endDate: payload.endDate ? new Date(payload.endDate) : payload.endDate + } + })); +} + +export function updateAssignment(accessToken, id, payload) { + const api = new AssignmentsApi(configFor(accessToken)); + return callApi(api.apiAssignmentsIdPutRaw({ id, updateAssignmentRequest: payload })); +} + +export function deleteAssignment(accessToken, id) { + const api = new AssignmentsApi(configFor(accessToken)); + return callApi(api.apiAssignmentsIdDeleteRaw({ id })); +} + +// Live-Vorschau der FR-EM-3-Konfliktprüfungen (Qualifikation/Abwesenheit/Arbeitszeit/Überschneidung/ +// Vertrag), ohne etwas anzulegen - für den Anlegen-Dialog, sobald Mitarbeiter + Zeitraum feststehen. +export function checkAssignmentConflicts(accessToken, { orderId, employeeId, startDate, endDate, excludeAssignmentId }) { + const api = new AssignmentsApi(configFor(accessToken)); + return callApi(api.apiAssignmentsCheckGetRaw({ + orderId, + employeeId, + startDate: startDate ? new Date(startDate) : startDate, + endDate: endDate ? new Date(endDate) : endDate, + excludeAssignmentId + })); +} diff --git a/omsorgapp/src/api/index.js b/omsorgapp/src/api/index.js index ea61e5d..5266832 100644 --- a/omsorgapp/src/api/index.js +++ b/omsorgapp/src/api/index.js @@ -7,6 +7,8 @@ import * as facilityContactsApi from "./facilityContactsApi.js"; import * as facilityQualificationRatesApi from "./facilityQualificationRatesApi.js"; import * as employeeFacilityDistancesApi from "./employeeFacilityDistancesApi.js"; import * as ordersApi from "./ordersApi.js"; +import * as assignmentsApi from "./assignmentsApi.js"; +import * as assignmentValidationSettingsApi from "./assignmentValidationSettingsApi.js"; import * as absencesApi from "./absencesApi.js"; import * as timeEntriesApi from "./timeEntriesApi.js"; import * as usersApi from "./usersApi.js"; @@ -141,6 +143,18 @@ export function buildOmsorgApi() { update: withAuth(ordersApi.updateOrder), delete: withAuth(ordersApi.deleteOrder) }, + assignments: { + list: withAuth(assignmentsApi.listAssignments), + create: withAuth(assignmentsApi.createAssignment), + get: withAuth(assignmentsApi.getAssignment), + update: withAuth(assignmentsApi.updateAssignment), + delete: withAuth(assignmentsApi.deleteAssignment), + checkConflicts: withAuth(assignmentsApi.checkAssignmentConflicts) + }, + assignmentValidationSettings: { + get: withAuth(assignmentValidationSettingsApi.getAssignmentValidationSettings), + update: withAuth(assignmentValidationSettingsApi.updateAssignmentValidationSettings) + }, absences: { list: withAuth(absencesApi.listAbsences), get: withAuth(absencesApi.getAbsence), @@ -203,7 +217,9 @@ export function buildOmsorgApi() { listAbsences: withAuth(trashApi.listDeletedAbsences), restoreAbsence: withAuth(trashApi.restoreAbsence), listTimeEntries: withAuth(trashApi.listDeletedTimeEntries), - restoreTimeEntry: withAuth(trashApi.restoreTimeEntry) + restoreTimeEntry: withAuth(trashApi.restoreTimeEntry), + listAssignments: withAuth(trashApi.listDeletedAssignments), + restoreAssignment: withAuth(trashApi.restoreAssignment) }, contracts: { list: withAuth(contractsApi.listContracts), diff --git a/omsorgapp/src/api/trashApi.js b/omsorgapp/src/api/trashApi.js index b3ea89b..5d809c6 100644 --- a/omsorgapp/src/api/trashApi.js +++ b/omsorgapp/src/api/trashApi.js @@ -93,3 +93,13 @@ export async function restoreTimeEntry(accessToken, id) { const api = new TrashApi(configFor(accessToken)); return callApi(api.apiTrashTimeEntriesIdRestorePostRaw({ id })); } + +export async function listDeletedAssignments(accessToken, search) { + const api = new TrashApi(configFor(accessToken)); + return callApi(api.apiTrashAssignmentsGetRaw({ search })); +} + +export async function restoreAssignment(accessToken, id) { + const api = new TrashApi(configFor(accessToken)); + return callApi(api.apiTrashAssignmentsIdRestorePostRaw({ id })); +} diff --git a/omsorgapp/src/app/navPermissions.js b/omsorgapp/src/app/navPermissions.js index 4eec13d..3d80e2b 100644 --- a/omsorgapp/src/app/navPermissions.js +++ b/omsorgapp/src/app/navPermissions.js @@ -20,7 +20,8 @@ export const TRASH_MODULES = [ ModuleType.Contracts, ModuleType.Orders, ModuleType.Absences, - ModuleType.TimeEntries + ModuleType.TimeEntries, + ModuleType.Assignments ]; // Einstellungen bündelt drei unabhängige Rechte (siehe SettingsPage.jsx, die jeden Tab einzeln diff --git a/omsorgapp/src/modules/orders/AssignmentsList.jsx b/omsorgapp/src/modules/orders/AssignmentsList.jsx new file mode 100644 index 0000000..6e5d402 --- /dev/null +++ b/omsorgapp/src/modules/orders/AssignmentsList.jsx @@ -0,0 +1,244 @@ +import { useCallback, useEffect, useState } from "react"; +import { Plus, Trash2 } from "lucide-react"; + +import OmsorgButton from "../../components/ui/OmsorgButton"; +import { useAuth } from "../../app/AuthContext"; +import CreateAssignmentDialog from "./CreateAssignmentDialog"; + +const CONFLICT_LABELS = { + Qualification: "Qualifikation", + Absence: "Abwesenheit", + WorkingHours: "Arbeitszeit", + Overlap: "Überschneidung", + Contract: "Vertrag" +}; + +function formatDate(value) { + if (!value) return "—"; + return new Date(value).toLocaleDateString("de-DE"); +} + +export default function AssignmentsList({ orderId, order, requiredHeadcount }) { + const { hasPermission } = useAuth(); + const canCreate = hasPermission("Assignments", "Create"); + const canDelete = hasPermission("Assignments", "Delete"); + + const [assignments, setAssignments] = useState([]); + const [isLoading, setIsLoading] = useState(true); + const [isCreateDialogOpen, setIsCreateDialogOpen] = useState(false); + const [deletingId, setDeletingId] = useState(null); + const [warnings, setWarnings] = useState([]); + + const loadAssignments = useCallback(async () => { + setIsLoading(true); + const result = await window.omsorg.assignments.list({ orderId, pageSize: 100 }); + if (result.ok) { + setAssignments(result.data?.items ?? []); + } + setIsLoading(false); + }, [orderId]); + + useEffect(() => { + loadAssignments(); + }, [loadAssignments]); + + async function handleDeleteAssignment(assignmentId) { + if (!window.confirm("Diese Zuweisung wirklich löschen?")) { + return; + } + setDeletingId(assignmentId); + const result = await window.omsorg.assignments.delete(assignmentId); + setDeletingId(null); + if (result.ok) { + await loadAssignments(); + } + } + + const formatDateRange = (startDate, endDate) => { + if (startDate === endDate) { + return formatDate(startDate); + } + return `${formatDate(startDate)} – ${formatDate(endDate)}`; + }; + + return ( +
+
+
+

Zuweisungen

+

+ {assignments.length} / {requiredHeadcount} Mitarbeiter zugewiesen +

+
+ {canCreate && ( + setIsCreateDialogOpen(true)}> + Zuweisung hinzufügen + + )} +
+ + {warnings.length > 0 && ( +
+ {warnings.map((w, i) => ( +

⚠ {CONFLICT_LABELS[w.type] ?? w.type}: {w.message}

+ ))} +
+ )} + + {isLoading ? ( +

Lädt...

+ ) : assignments.length === 0 ? ( +

Noch keine Zuweisungen. {canCreate && "Klicke oben, um einen Mitarbeiter zuzuweisen."}

+ ) : ( +
+
+
Mitarbeiter
+
Zeitraum
+
Notiz
+ {canDelete &&
} +
+ {assignments.map((assignment) => ( +
+
+ {assignment.employeeFirstName} {assignment.employeeLastName} +
+
+ {formatDateRange(assignment.startDate, assignment.endDate)} +
+
{assignment.note ?? "—"}
+ {canDelete && ( +
+ +
+ )} +
+ ))} +
+ )} + + {isCreateDialogOpen && ( + setIsCreateDialogOpen(false)} + onCreated={(conflicts) => { + setIsCreateDialogOpen(false); + setWarnings(conflicts ?? []); + loadAssignments(); + }} + /> + )} + + +
+ ); +} diff --git a/omsorgapp/src/modules/orders/CreateAssignmentDialog.jsx b/omsorgapp/src/modules/orders/CreateAssignmentDialog.jsx new file mode 100644 index 0000000..7594bcb --- /dev/null +++ b/omsorgapp/src/modules/orders/CreateAssignmentDialog.jsx @@ -0,0 +1,278 @@ +import { useEffect, useState } from "react"; + +import ModalPortal from "../../components/ui/ModalPortal"; +import OmsorgButton from "../../components/ui/OmsorgButton"; + +const CONFLICT_LABELS = { + Qualification: "Qualifikation", + Absence: "Abwesenheit", + WorkingHours: "Arbeitszeit", + Overlap: "Überschneidung", + Contract: "Vertrag" +}; + +function conflictLabel(conflict) { + return `${CONFLICT_LABELS[conflict.type] ?? conflict.type}: ${conflict.message}`; +} + +function errorMessage(result) { + if (result.status === 403) { + return "Keine Berechtigung, Zuweisungen zu erstellen."; + } + if (result.status === 404) { + return typeof result.data === "string" ? result.data : "Mitarbeiter oder Auftrag nicht gefunden."; + } + if (result.status === 400) { + const msg = typeof result.data === "string" ? result.data : result.data?.error; + if (msg === "invalid_date_range") { + return "Das Enddatum muss nach oder gleich dem Startdatum sein."; + } + if (msg === "date_outside_order_range") { + return "Der Zeitraum liegt außerhalb der Auftragsspanne."; + } + return msg || "Eingaben prüfen."; + } + if (result.status === 409) { + const msg = typeof result.data === "string" ? result.data : result.data?.error; + if (msg === "overlapping_assignment") { + return "Dieser Mitarbeiter ist bereits in diesem Zeitraum diesem Auftrag zugewiesen."; + } + if (msg === "validation_conflict") { + const conflicts = result.data?.conflicts ?? []; + return conflicts.length > 0 + ? conflicts.map(conflictLabel).join(" | ") + : "Zuweisung durch eine Konfliktprüfung blockiert."; + } + return "Zeitraum-Konflikt: Überprüfe die Verfügbarkeit."; + } + return "Zuweisung konnte nicht erstellt werden."; +} + +export default function CreateAssignmentDialog({ orderId, order, onClose, onCreated }) { + const [employees, setEmployees] = useState([]); + const [selectedEmployeeId, setSelectedEmployeeId] = useState(""); + const [startDate, setStartDate] = useState(""); + const [endDate, setEndDate] = useState(""); + const [note, setNote] = useState(""); + const [error, setError] = useState(""); + const [isSubmitting, setIsSubmitting] = useState(false); + const [isLoadingEmployees, setIsLoadingEmployees] = useState(true); + const [liveConflicts, setLiveConflicts] = useState([]); + const [isChecking, setIsChecking] = useState(false); + + useEffect(() => { + async function loadEmployees() { + const result = await window.omsorg.employees.list({ status: "Aktiv", pageSize: 200 }); + if (result.ok) { + setEmployees(result.data?.items ?? []); + } + setIsLoadingEmployees(false); + } + loadEmployees(); + }, []); + + // Live-Vorschau: sobald Mitarbeiter + gültiger Zeitraum feststehen, dieselben FR-EM-3-Prüfungen + // wie beim Speichern laufen lassen (debounced), damit Warnings/Errors schon vor dem Klick auf + // "Speichern" sichtbar sind, nicht erst danach. + useEffect(() => { + setError(""); + + if (!selectedEmployeeId || !startDate || !endDate || endDate < startDate) { + setLiveConflicts([]); + return; + } + + let cancelled = false; + setIsChecking(true); + const timer = setTimeout(async () => { + const result = await window.omsorg.assignments.checkConflicts({ + orderId, + employeeId: selectedEmployeeId, + startDate, + endDate + }); + if (!cancelled) { + setLiveConflicts(result.ok ? result.data ?? [] : []); + setIsChecking(false); + } + }, 400); + + return () => { + cancelled = true; + clearTimeout(timer); + }; + }, [orderId, selectedEmployeeId, startDate, endDate]); + + const hasBlockingConflict = liveConflicts.some((c) => c.severity === "Error"); + + const orderStartDate = order?.startDate ? new Date(order.startDate).toISOString().split("T")[0] : ""; + const orderEndDate = order?.endDate ? new Date(order.endDate).toISOString().split("T")[0] : ""; + + const handleSubmit = async (e) => { + e.preventDefault(); + setError(""); + + if (!selectedEmployeeId) { + setError("Bitte wähle einen Mitarbeiter."); + return; + } + if (!startDate) { + setError("Bitte wähle ein Startdatum."); + return; + } + if (!endDate) { + setError("Bitte wähle ein Enddatum."); + return; + } + if (endDate < startDate) { + setError("Das Enddatum muss nach oder gleich dem Startdatum sein."); + return; + } + + setIsSubmitting(true); + const result = await window.omsorg.assignments.create({ + orderId, + employeeId: selectedEmployeeId, + startDate, + endDate, + note: note || null + }); + + if (result.ok) { + onCreated(result.data?.conflicts ?? []); + } else { + setError(errorMessage(result)); + } + setIsSubmitting(false); + }; + + return ( + +
+
+

Zuweisung hinzufügen

+ +
+ {error &&

{error}

} + +
+ + +
+ +
+
+ + { + setStartDate(e.target.value); + if (endDate && e.target.value > endDate) { + setEndDate(e.target.value); + } + }} + min={orderStartDate} + max={orderEndDate || undefined} + disabled={isSubmitting} + required + /> +
+ +
+ + setEndDate(e.target.value)} + min={startDate || orderStartDate} + max={orderEndDate || undefined} + disabled={isSubmitting} + required + /> +
+
+ + {isChecking &&

Prüfe Konflikte...

} + + {!isChecking && liveConflicts.length > 0 && ( +
+ {liveConflicts.map((c, i) => ( +

+ {c.severity === "Error" ? "⛔" : "⚠"} {CONFLICT_LABELS[c.type] ?? c.type}: {c.message} +

+ ))} +
+ )} + +
+ +