Add kilometer-based Fahrtkosten billing, self-service distance entry, role deletion
Docker-Images bauen und veröffentlichen / build (, omsorgCore/Dockerfile, omsorgcore) (push) Successful in 16s
Docker-Images bauen und veröffentlichen / build (, omsorgWeb/Dockerfile, omsorgweb) (push) Successful in 5s
Docker-Images bauen und veröffentlichen / build (, omsorgapp/Dockerfile, omsorgapp) (push) Successful in 19s

- Facility: TravelCostMode (Pauschale/ProKilometer) + TravelCostPerKm, alongside
  the existing flat rate; fixes FacilityService.UpdateAsync silently dropping all
  Konditionen fields on update.
- New EmployeeFacilityDistance (Mitarbeiter x Einrichtung -> km) with full
  office-side CRUD in omsorgapp, plus a self-service endpoint/UI so field staff
  can maintain their own commute distance via OMSORG Connect (new
  ModuleType.EmployeeFacilityDistances, Own-scope, no Facilities access needed).
- Roles can now be deleted (blocked with a 409 while still assigned to a user).
- Fix employeesApi.js missing the Date-object conversion for dateOfBirth/entryDate/
  exitDate that crashed employee creation whenever a date was filled in; add a
  clear/remove control for those date fields.
- Requirements: flesh out FR-REC-3 with a staged Akquise cadence, add FR-REC-5/6
  for CRM feature scope and success metrics.
- Regenerate api-client-ts and api-client-php for all of the above.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Felix Kemmler
2026-08-10 20:15:42 +02:00
co-authored by Claude Sonnet 5
parent 09dce2ab98
commit ffa2c4a9e7
120 changed files with 13433 additions and 36 deletions
@@ -17,6 +17,7 @@ import * as runtime from '../runtime';
import type {
TrashAbsenceResponse,
TrashContractResponse,
TrashEmployeeFacilityDistanceResponse,
TrashEmployeeResponse,
TrashFacilityContactResponse,
TrashFacilityQualificationRateResponse,
@@ -29,6 +30,8 @@ import {
TrashAbsenceResponseToJSON,
TrashContractResponseFromJSON,
TrashContractResponseToJSON,
TrashEmployeeFacilityDistanceResponseFromJSON,
TrashEmployeeFacilityDistanceResponseToJSON,
TrashEmployeeResponseFromJSON,
TrashEmployeeResponseToJSON,
TrashFacilityContactResponseFromJSON,
@@ -59,6 +62,14 @@ export interface ApiTrashContractsIdRestorePostRequest {
id: string;
}
export interface ApiTrashEmployeeFacilityDistancesGetRequest {
search?: string;
}
export interface ApiTrashEmployeeFacilityDistancesIdRestorePostRequest {
id: string;
}
export interface ApiTrashEmployeesGetRequest {
search?: string;
}
@@ -274,6 +285,87 @@ export class TrashApi extends runtime.BaseAPI {
await this.apiTrashContractsIdRestorePostRaw(requestParameters, initOverrides);
}
/**
*/
async apiTrashEmployeeFacilityDistancesGetRaw(requestParameters: ApiTrashEmployeeFacilityDistancesGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<Array<TrashEmployeeFacilityDistanceResponse>>> {
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/employee-facility-distances`;
const response = await this.request({
path: urlPath,
method: 'GET',
headers: headerParameters,
query: queryParameters,
}, initOverrides);
return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(TrashEmployeeFacilityDistanceResponseFromJSON));
}
/**
*/
async apiTrashEmployeeFacilityDistancesGet(requestParameters: ApiTrashEmployeeFacilityDistancesGetRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<Array<TrashEmployeeFacilityDistanceResponse>> {
const response = await this.apiTrashEmployeeFacilityDistancesGetRaw(requestParameters, initOverrides);
return await response.value();
}
/**
*/
async apiTrashEmployeeFacilityDistancesIdRestorePostRaw(requestParameters: ApiTrashEmployeeFacilityDistancesIdRestorePostRequest, 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 apiTrashEmployeeFacilityDistancesIdRestorePost().'
);
}
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/employee-facility-distances/{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 apiTrashEmployeeFacilityDistancesIdRestorePost(requestParameters: ApiTrashEmployeeFacilityDistancesIdRestorePostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<void> {
await this.apiTrashEmployeeFacilityDistancesIdRestorePostRaw(requestParameters, initOverrides);
}
/**
*/
async apiTrashEmployeesGetRaw(requestParameters: ApiTrashEmployeesGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<Array<TrashEmployeeResponse>>> {