Add employee-to-order assignments with FR-EM-3 conflict validation
Docker-Images bauen und veröffentlichen / build (, omsorgCore/Dockerfile, omsorgcore) (push) Successful in 17s
Docker-Images bauen und veröffentlichen / build (, omsorgWeb/Dockerfile, omsorgweb) (push) Successful in 6s
Docker-Images bauen und veröffentlichen / build (, omsorgapp/Dockerfile, omsorgapp) (push) Successful in 17s
Docker-Images bauen und veröffentlichen / build (, omsorgCore/Dockerfile, omsorgcore) (push) Successful in 17s
Docker-Images bauen und veröffentlichen / build (, omsorgWeb/Dockerfile, omsorgweb) (push) Successful in 6s
Docker-Images bauen und veröffentlichen / build (, omsorgapp/Dockerfile, omsorgapp) (push) Successful in 17s
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 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
fcbf27db3c
commit
dfeb37cf33
@@ -5,6 +5,8 @@ package.json
|
||||
src/apis/AbsencesApi.ts
|
||||
src/apis/AdminEmailApi.ts
|
||||
src/apis/AdminSessionsApi.ts
|
||||
src/apis/AssignmentValidationSettingsApi.ts
|
||||
src/apis/AssignmentsApi.ts
|
||||
src/apis/AuditLogApi.ts
|
||||
src/apis/AuthApi.ts
|
||||
src/apis/ContractsApi.ts
|
||||
@@ -28,6 +30,10 @@ src/models/AbsenceDecisionRequest.ts
|
||||
src/models/AbsenceResponse.ts
|
||||
src/models/AbsenceResponsePagedResponse.ts
|
||||
src/models/AddUserPermissionOverrideRequest.ts
|
||||
src/models/AssignmentConflictResponse.ts
|
||||
src/models/AssignmentResponse.ts
|
||||
src/models/AssignmentResponsePagedResponse.ts
|
||||
src/models/AssignmentValidationSettingsResponse.ts
|
||||
src/models/AuditEventCategory.ts
|
||||
src/models/AuditLogEntryResponse.ts
|
||||
src/models/AuditLogEntryResponsePagedResponse.ts
|
||||
@@ -35,6 +41,7 @@ src/models/ChangePasswordRequest.ts
|
||||
src/models/ContractResponse.ts
|
||||
src/models/ContractResponsePagedResponse.ts
|
||||
src/models/CreateAbsenceRequest.ts
|
||||
src/models/CreateAssignmentRequest.ts
|
||||
src/models/CreateContractRequest.ts
|
||||
src/models/CreateEmployeeFacilityDistanceRequest.ts
|
||||
src/models/CreateEmployeeRequest.ts
|
||||
@@ -85,6 +92,7 @@ src/models/TimeEntryDecisionRequest.ts
|
||||
src/models/TimeEntryResponse.ts
|
||||
src/models/TimeEntryResponsePagedResponse.ts
|
||||
src/models/TrashAbsenceResponse.ts
|
||||
src/models/TrashAssignmentResponse.ts
|
||||
src/models/TrashContractResponse.ts
|
||||
src/models/TrashEmployeeFacilityDistanceResponse.ts
|
||||
src/models/TrashEmployeeResponse.ts
|
||||
@@ -94,6 +102,8 @@ src/models/TrashFacilityResponse.ts
|
||||
src/models/TrashOrderResponse.ts
|
||||
src/models/TrashTimeEntryResponse.ts
|
||||
src/models/UpdateAbsenceRequest.ts
|
||||
src/models/UpdateAssignmentRequest.ts
|
||||
src/models/UpdateAssignmentValidationSettingsRequest.ts
|
||||
src/models/UpdateContractRequest.ts
|
||||
src/models/UpdateDocumentRequest.ts
|
||||
src/models/UpdateEmployeeFacilityDistanceRequest.ts
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/* 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 {
|
||||
AssignmentValidationSettingsResponse,
|
||||
UpdateAssignmentValidationSettingsRequest,
|
||||
} from '../models/index';
|
||||
import {
|
||||
AssignmentValidationSettingsResponseFromJSON,
|
||||
AssignmentValidationSettingsResponseToJSON,
|
||||
UpdateAssignmentValidationSettingsRequestFromJSON,
|
||||
UpdateAssignmentValidationSettingsRequestToJSON,
|
||||
} from '../models/index';
|
||||
|
||||
export interface ApiSettingsAssignmentValidationPutRequest {
|
||||
updateAssignmentValidationSettingsRequest?: UpdateAssignmentValidationSettingsRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export class AssignmentValidationSettingsApi extends runtime.BaseAPI {
|
||||
|
||||
/**
|
||||
*/
|
||||
async apiSettingsAssignmentValidationGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<AssignmentValidationSettingsResponse>> {
|
||||
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<AssignmentValidationSettingsResponse> {
|
||||
const response = await this.apiSettingsAssignmentValidationGetRaw(initOverrides);
|
||||
return await response.value();
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
async apiSettingsAssignmentValidationPutRaw(requestParameters: ApiSettingsAssignmentValidationPutRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<AssignmentValidationSettingsResponse>> {
|
||||
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<AssignmentValidationSettingsResponse> {
|
||||
const response = await this.apiSettingsAssignmentValidationPutRaw(requestParameters, initOverrides);
|
||||
return await response.value();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<runtime.ApiResponse<Array<AssignmentConflictResponse>>> {
|
||||
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<Array<AssignmentConflictResponse>> {
|
||||
const response = await this.apiAssignmentsCheckGetRaw(requestParameters, initOverrides);
|
||||
return await response.value();
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
async apiAssignmentsGetRaw(requestParameters: ApiAssignmentsGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<AssignmentResponsePagedResponse>> {
|
||||
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<AssignmentResponsePagedResponse> {
|
||||
const response = await this.apiAssignmentsGetRaw(requestParameters, initOverrides);
|
||||
return await response.value();
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
async apiAssignmentsIdDeleteRaw(requestParameters: ApiAssignmentsIdDeleteRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<void>> {
|
||||
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<void> {
|
||||
await this.apiAssignmentsIdDeleteRaw(requestParameters, initOverrides);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
async apiAssignmentsIdGetRaw(requestParameters: ApiAssignmentsIdGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<AssignmentResponse>> {
|
||||
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<AssignmentResponse> {
|
||||
const response = await this.apiAssignmentsIdGetRaw(requestParameters, initOverrides);
|
||||
return await response.value();
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
async apiAssignmentsIdPutRaw(requestParameters: ApiAssignmentsIdPutRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<AssignmentResponse>> {
|
||||
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<AssignmentResponse> {
|
||||
const response = await this.apiAssignmentsIdPutRaw(requestParameters, initOverrides);
|
||||
return await response.value();
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
async apiAssignmentsPostRaw(requestParameters: ApiAssignmentsPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<AssignmentResponse>> {
|
||||
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<AssignmentResponse> {
|
||||
const response = await this.apiAssignmentsPostRaw(requestParameters, initOverrides);
|
||||
return await response.value();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<runtime.ApiResponse<Array<TrashAssignmentResponse>>> {
|
||||
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<Array<TrashAssignmentResponse>> {
|
||||
const response = await this.apiTrashAssignmentsGetRaw(requestParameters, initOverrides);
|
||||
return await response.value();
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
async apiTrashAssignmentsIdRestorePostRaw(requestParameters: ApiTrashAssignmentsIdRestorePostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<void>> {
|
||||
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<void> {
|
||||
await this.apiTrashAssignmentsIdRestorePostRaw(requestParameters, initOverrides);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
async apiTrashContractsGetRaw(requestParameters: ApiTrashContractsGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<Array<TrashContractResponse>>> {
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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'],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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<AssignmentConflictResponse>}
|
||||
* @memberof AssignmentResponse
|
||||
*/
|
||||
conflicts?: Array<AssignmentConflictResponse> | 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<any>).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<any>).map(AssignmentConflictResponseToJSON)),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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<AssignmentResponse>}
|
||||
* @memberof AssignmentResponsePagedResponse
|
||||
*/
|
||||
items?: Array<AssignmentResponse> | 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<any>).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<any>).map(AssignmentResponseToJSON)),
|
||||
'totalCount': value['totalCount'],
|
||||
'page': value['page'],
|
||||
'pageSize': value['pageSize'],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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'],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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'],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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'],
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
@@ -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()),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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'],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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'],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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 }));
|
||||
}
|
||||
@@ -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
|
||||
}));
|
||||
}
|
||||
@@ -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),
|
||||
|
||||
@@ -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 }));
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 (
|
||||
<div className="assignments-section">
|
||||
<div className="assignments-header">
|
||||
<div>
|
||||
<h3>Zuweisungen</h3>
|
||||
<p className="assignments-count">
|
||||
{assignments.length} / {requiredHeadcount} Mitarbeiter zugewiesen
|
||||
</p>
|
||||
</div>
|
||||
{canCreate && (
|
||||
<OmsorgButton variant="primary" size="sm" icon={Plus} onClick={() => setIsCreateDialogOpen(true)}>
|
||||
Zuweisung hinzufügen
|
||||
</OmsorgButton>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{warnings.length > 0 && (
|
||||
<div className="assignments-warnings">
|
||||
{warnings.map((w, i) => (
|
||||
<p key={i}>⚠ {CONFLICT_LABELS[w.type] ?? w.type}: {w.message}</p>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{isLoading ? (
|
||||
<p>Lädt...</p>
|
||||
) : assignments.length === 0 ? (
|
||||
<p className="assignments-empty">Noch keine Zuweisungen. {canCreate && "Klicke oben, um einen Mitarbeiter zuzuweisen."}</p>
|
||||
) : (
|
||||
<div className="assignments-table">
|
||||
<div className="assignments-table-header">
|
||||
<div>Mitarbeiter</div>
|
||||
<div>Zeitraum</div>
|
||||
<div>Notiz</div>
|
||||
{canDelete && <div></div>}
|
||||
</div>
|
||||
{assignments.map((assignment) => (
|
||||
<div key={assignment.id} className="assignments-table-row">
|
||||
<div className="assignments-cell">
|
||||
{assignment.employeeFirstName} {assignment.employeeLastName}
|
||||
</div>
|
||||
<div className="assignments-cell">
|
||||
{formatDateRange(assignment.startDate, assignment.endDate)}
|
||||
</div>
|
||||
<div className="assignments-cell">{assignment.note ?? "—"}</div>
|
||||
{canDelete && (
|
||||
<div className="assignments-cell assignments-cell-action">
|
||||
<button
|
||||
className="assignments-delete-btn"
|
||||
onClick={() => handleDeleteAssignment(assignment.id)}
|
||||
disabled={deletingId === assignment.id}
|
||||
title="Zuweisung löschen"
|
||||
>
|
||||
<Trash2 size={16} />
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{isCreateDialogOpen && (
|
||||
<CreateAssignmentDialog
|
||||
orderId={orderId}
|
||||
order={order}
|
||||
onClose={() => setIsCreateDialogOpen(false)}
|
||||
onCreated={(conflicts) => {
|
||||
setIsCreateDialogOpen(false);
|
||||
setWarnings(conflicts ?? []);
|
||||
loadAssignments();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
<style>{`
|
||||
.assignments-section {
|
||||
margin-top: 2rem;
|
||||
padding-top: 2rem;
|
||||
border-top: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
.assignments-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.assignments-header h3 {
|
||||
margin: 0 0 0.25rem 0;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.assignments-count {
|
||||
margin: 0;
|
||||
font-size: 0.9rem;
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
.assignments-warnings {
|
||||
background-color: rgba(240, 195, 109, 0.12);
|
||||
border: 1px solid rgba(240, 195, 109, 0.45);
|
||||
color: #f0c36d;
|
||||
border-radius: 4px;
|
||||
padding: 0.75rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.assignments-warnings p {
|
||||
margin: 0.25rem 0;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.assignments-empty {
|
||||
color: var(--color-text-secondary);
|
||||
font-style: italic;
|
||||
margin: 1rem 0 0 0;
|
||||
}
|
||||
|
||||
.assignments-table {
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.assignments-table-header {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1.5fr 1.5fr ${canDelete ? "40px" : ""};
|
||||
background-color: var(--color-bg-secondary);
|
||||
padding: 0.75rem;
|
||||
font-weight: 600;
|
||||
font-size: 0.9rem;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.assignments-table-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1.5fr 1.5fr ${canDelete ? "40px" : ""};
|
||||
padding: 0.75rem;
|
||||
border-top: 1px solid var(--color-border);
|
||||
gap: 1rem;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.assignments-cell {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.assignments-cell-action {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.assignments-delete-btn {
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--color-text-secondary);
|
||||
cursor: pointer;
|
||||
padding: 0.25rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 3px;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.assignments-delete-btn:hover:not(:disabled) {
|
||||
background-color: var(--color-bg-secondary);
|
||||
color: var(--color-error);
|
||||
}
|
||||
|
||||
.assignments-delete-btn:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
`}</style>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -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 (
|
||||
<ModalPortal>
|
||||
<div className="modal-overlay" role="dialog" aria-modal="true" aria-label="Zuweisung hinzufügen">
|
||||
<div className="modal-panel">
|
||||
<h2>Zuweisung hinzufügen</h2>
|
||||
|
||||
<form onSubmit={handleSubmit}>
|
||||
{error && <p className="login-error form-error">{error}</p>}
|
||||
|
||||
<div className="form-group">
|
||||
<label htmlFor="employee-select">Mitarbeiter *</label>
|
||||
<select
|
||||
id="employee-select"
|
||||
value={selectedEmployeeId}
|
||||
onChange={(e) => setSelectedEmployeeId(e.target.value)}
|
||||
disabled={isLoadingEmployees || isSubmitting}
|
||||
required
|
||||
>
|
||||
<option value="">— Bitte wähle einen Mitarbeiter —</option>
|
||||
{employees.map((emp) => (
|
||||
<option key={emp.id} value={emp.id}>
|
||||
{emp.firstName} {emp.lastName}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "1rem" }}>
|
||||
<div className="form-group">
|
||||
<label htmlFor="start-date">Startdatum *</label>
|
||||
<input
|
||||
id="start-date"
|
||||
type="date"
|
||||
value={startDate}
|
||||
onChange={(e) => {
|
||||
setStartDate(e.target.value);
|
||||
if (endDate && e.target.value > endDate) {
|
||||
setEndDate(e.target.value);
|
||||
}
|
||||
}}
|
||||
min={orderStartDate}
|
||||
max={orderEndDate || undefined}
|
||||
disabled={isSubmitting}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label htmlFor="end-date">Enddatum *</label>
|
||||
<input
|
||||
id="end-date"
|
||||
type="date"
|
||||
value={endDate}
|
||||
onChange={(e) => setEndDate(e.target.value)}
|
||||
min={startDate || orderStartDate}
|
||||
max={orderEndDate || undefined}
|
||||
disabled={isSubmitting}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{isChecking && <p style={{ color: "var(--omsorg-text-secondary)", fontSize: "0.85rem" }}>Prüfe Konflikte...</p>}
|
||||
|
||||
{!isChecking && liveConflicts.length > 0 && (
|
||||
<div className={hasBlockingConflict ? "assignment-conflicts assignment-conflicts--error" : "assignment-conflicts assignment-conflicts--warning"}>
|
||||
{liveConflicts.map((c, i) => (
|
||||
<p key={i}>
|
||||
{c.severity === "Error" ? "⛔" : "⚠"} {CONFLICT_LABELS[c.type] ?? c.type}: {c.message}
|
||||
</p>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="form-group">
|
||||
<label htmlFor="note">Notiz (optional)</label>
|
||||
<textarea
|
||||
id="note"
|
||||
value={note}
|
||||
onChange={(e) => setNote(e.target.value)}
|
||||
placeholder="z.B. Springer, spezielle Anforderungen..."
|
||||
disabled={isSubmitting}
|
||||
rows={3}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div style={{ display: "flex", gap: "0.75rem", justifyContent: "flex-end", marginTop: "1.5rem" }}>
|
||||
<button
|
||||
type="button"
|
||||
onClick={onClose}
|
||||
disabled={isSubmitting}
|
||||
className="button-link"
|
||||
>
|
||||
Abbrechen
|
||||
</button>
|
||||
<OmsorgButton type="submit" variant="primary" disabled={isSubmitting || hasBlockingConflict}>
|
||||
{isSubmitting ? "Wird gespeichert..." : "Speichern"}
|
||||
</OmsorgButton>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<style>{`
|
||||
.assignment-conflicts {
|
||||
border-radius: 4px;
|
||||
padding: 0.75rem;
|
||||
margin: 0.5rem 0 1rem 0;
|
||||
}
|
||||
|
||||
.assignment-conflicts p {
|
||||
margin: 0.25rem 0;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.assignment-conflicts--warning {
|
||||
background-color: rgba(240, 195, 109, 0.12);
|
||||
border: 1px solid rgba(240, 195, 109, 0.45);
|
||||
color: #f0c36d;
|
||||
}
|
||||
|
||||
.assignment-conflicts--error {
|
||||
background-color: rgba(242, 139, 139, 0.12);
|
||||
border: 1px solid rgba(242, 139, 139, 0.45);
|
||||
color: #f28b8b;
|
||||
}
|
||||
`}</style>
|
||||
</div>
|
||||
</ModalPortal>
|
||||
);
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import OmsorgCard from "../../components/OmsorgCard";
|
||||
import OmsorgButton from "../../components/ui/OmsorgButton";
|
||||
import { useAuth } from "../../app/AuthContext";
|
||||
import EditOrderDialog from "./EditOrderDialog";
|
||||
import AssignmentsList from "./AssignmentsList";
|
||||
|
||||
function formatDate(value) {
|
||||
if (!value) {
|
||||
@@ -100,6 +101,8 @@ export default function OrderDetailPanel({ order, facilityName, facilities, onUp
|
||||
<p>{order.conditions ?? "—"}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<AssignmentsList orderId={order.id} order={order} requiredHeadcount={order.requiredHeadcount} />
|
||||
</div>
|
||||
|
||||
{isEditDialogOpen && (
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { Save } from "lucide-react";
|
||||
import OmsorgButton from "../../components/ui/OmsorgButton";
|
||||
import { useAuth } from "../../app/AuthContext";
|
||||
|
||||
const CHECKS = [
|
||||
{ key: "qualificationMode", label: "Qualifikation" },
|
||||
{ key: "absenceMode", label: "Abwesenheit (Verfügbarkeit)" },
|
||||
{ key: "workingHoursMode", label: "Arbeitszeit" },
|
||||
{ key: "overlapMode", label: "Überschneidung" },
|
||||
{ key: "contractMode", label: "Vertrag" }
|
||||
];
|
||||
|
||||
export default function AssignmentValidationSettingsPanel() {
|
||||
const { hasPermission } = useAuth();
|
||||
const canEdit = hasPermission("Configuration", "Edit");
|
||||
|
||||
const [settings, setSettings] = useState(null);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [isSaving, setIsSaving] = useState(false);
|
||||
const [error, setError] = useState(null);
|
||||
const [saved, setSaved] = useState(false);
|
||||
|
||||
const load = useCallback(async () => {
|
||||
setIsLoading(true);
|
||||
setError(null);
|
||||
const result = await window.omsorg.assignmentValidationSettings.get();
|
||||
if (result.ok) {
|
||||
setSettings(result.data);
|
||||
} else {
|
||||
setError("Einstellungen konnten nicht geladen werden.");
|
||||
}
|
||||
setIsLoading(false);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
load();
|
||||
}, [load]);
|
||||
|
||||
function handleChange(key, value) {
|
||||
setSaved(false);
|
||||
setSettings((current) => ({ ...current, [key]: value }));
|
||||
}
|
||||
|
||||
async function handleSave() {
|
||||
setIsSaving(true);
|
||||
setError(null);
|
||||
setSaved(false);
|
||||
const result = await window.omsorg.assignmentValidationSettings.update(settings);
|
||||
if (result.ok) {
|
||||
setSettings(result.data);
|
||||
setSaved(true);
|
||||
} else {
|
||||
setError("Speichern fehlgeschlagen.");
|
||||
}
|
||||
setIsSaving(false);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="settings-roles-panel">
|
||||
<div className="settings-panel-heading">
|
||||
<h4>Zuweisungsprüfung (FR-EM-3)</h4>
|
||||
</div>
|
||||
<p style={{ color: "var(--omsorg-text-secondary)", fontSize: "0.9rem", marginTop: 0 }}>
|
||||
Legt je Prüfung fest, ob eine Mitarbeiterzuweisung bei einem Konflikt blockiert wird
|
||||
("Error") oder nur ein Hinweis erscheint, die Zuweisung aber trotzdem angelegt wird
|
||||
("Warning").
|
||||
</p>
|
||||
|
||||
{isLoading && <p>Lädt...</p>}
|
||||
{error && <p className="login-error">{error}</p>}
|
||||
|
||||
{!isLoading && settings && (
|
||||
<>
|
||||
<div className="settings-permission-matrix settings-permission-matrix-scroll">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Prüfung</th>
|
||||
<th>Modus</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{CHECKS.map(({ key, label }) => (
|
||||
<tr key={key}>
|
||||
<td>{label}</td>
|
||||
<td>
|
||||
<select
|
||||
value={settings[key]}
|
||||
onChange={(e) => handleChange(key, e.target.value)}
|
||||
disabled={!canEdit || isSaving}
|
||||
>
|
||||
<option value="Warning">Warning (nur Hinweis)</option>
|
||||
<option value="Error">Error (blockiert)</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{canEdit && (
|
||||
<div style={{ marginTop: "1rem", display: "flex", alignItems: "center", gap: "0.75rem" }}>
|
||||
<OmsorgButton variant="primary" icon={Save} onClick={handleSave} disabled={isSaving}>
|
||||
{isSaving ? "Speichert..." : "Speichern"}
|
||||
</OmsorgButton>
|
||||
{saved && <span style={{ color: "var(--omsorg-turquoise)" }}>Gespeichert.</span>}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import OmsorgCard from "../../components/OmsorgCard";
|
||||
import RolesPanel from "./RolesPanel";
|
||||
import UserOverridesPanel from "./UserOverridesPanel";
|
||||
import StatusManagementPanel from "./StatusManagementPanel";
|
||||
import AssignmentValidationSettingsPanel from "./AssignmentValidationSettingsPanel";
|
||||
import UsersPanel from "./UsersPanel";
|
||||
import { useAuth } from "../../app/AuthContext";
|
||||
|
||||
@@ -11,6 +12,7 @@ const ALL_TABS = [
|
||||
{ id: "roles", label: "Rollen", module: "UserManagement" },
|
||||
{ id: "overrides", label: "Benutzerrechte", module: "UserManagement" },
|
||||
{ id: "statuses", label: "Status-Verwaltung", module: "Configuration" },
|
||||
{ id: "assignmentValidation", label: "Zuweisungsprüfung", module: "Configuration" },
|
||||
];
|
||||
|
||||
export default function SettingsPage() {
|
||||
@@ -42,6 +44,7 @@ export default function SettingsPage() {
|
||||
{currentTab === "roles" && <RolesPanel />}
|
||||
{currentTab === "overrides" && <UserOverridesPanel />}
|
||||
{currentTab === "statuses" && <StatusManagementPanel />}
|
||||
{currentTab === "assignmentValidation" && <AssignmentValidationSettingsPanel />}
|
||||
</>
|
||||
)}
|
||||
</OmsorgCard>
|
||||
|
||||
@@ -83,6 +83,14 @@ const TABS = [
|
||||
restore: (id) => window.omsorg.trash.restoreTimeEntry(id),
|
||||
displayName: (item) => new Date(item.date).toLocaleDateString("de-DE"),
|
||||
},
|
||||
{
|
||||
key: "assignments",
|
||||
label: "Zuweisungen",
|
||||
module: "Assignments",
|
||||
list: (search) => window.omsorg.trash.listAssignments(search),
|
||||
restore: (id) => window.omsorg.trash.restoreAssignment(id),
|
||||
displayName: (item) => `${item.employeeFirstName} ${item.employeeLastName}`.trim(),
|
||||
},
|
||||
];
|
||||
|
||||
export default function TrashPage() {
|
||||
|
||||
Reference in New Issue
Block a user