feat: Refactor CPuls entity and related resources; enhance localization, update layouts, and improve validation logic
This commit is contained in:
@@ -1,121 +1,90 @@
|
||||
<?php
|
||||
|
||||
namespace Espo\Custom\Api\CPuls;
|
||||
|
||||
use Espo\Core\Api\Action;
|
||||
use Espo\Core\Api\Request;
|
||||
use Espo\Core\Api\Response;
|
||||
use Espo\Core\Api\ResponseComposer;
|
||||
use Espo\Core\Exceptions\BadRequest;
|
||||
use Espo\Core\Exceptions\Forbidden;
|
||||
use Espo\Core\Exceptions\NotFound;
|
||||
use Espo\ORM\EntityManager;
|
||||
|
||||
class AbschliessenFuerTeam implements Action
|
||||
{
|
||||
public function __construct(
|
||||
private \Espo\ORM\EntityManager $entityManager,
|
||||
private \Espo\Core\Acl\Table $acl,
|
||||
private \Espo\Entities\User $user,
|
||||
private \Espo\Core\Utils\Log $log
|
||||
private EntityManager $entityManager
|
||||
) {}
|
||||
|
||||
|
||||
public function process(Request $request): Response
|
||||
{
|
||||
$pulsId = $request->getRouteParam('id');
|
||||
$data = $request->getParsedBody();
|
||||
$teamId = $data->teamId ?? null;
|
||||
|
||||
if (!$pulsId || !$teamId) {
|
||||
throw new BadRequest('pulsId oder teamId fehlt');
|
||||
$id = $request->getRouteParam('id');
|
||||
if (!$id) {
|
||||
throw new BadRequest('ID fehlt.');
|
||||
}
|
||||
|
||||
// 1. Validierung: Ist User in diesem Team?
|
||||
$userTeams = $this->user->getLinkMultipleIdList('teams');
|
||||
|
||||
if (!in_array($teamId, $userTeams)) {
|
||||
throw new Forbidden('User nicht in angegebenem Team');
|
||||
}
|
||||
|
||||
// 2. Lade Puls
|
||||
$puls = $this->entityManager->getEntity('CPuls', $pulsId);
|
||||
|
||||
|
||||
$puls = $this->entityManager->getEntityById('CPuls', $id);
|
||||
if (!$puls) {
|
||||
throw new NotFound('Puls nicht gefunden');
|
||||
throw new NotFound('Puls nicht gefunden.');
|
||||
}
|
||||
|
||||
// 3. Validierung: syncStatus = clean?
|
||||
if ($puls->get('syncStatus') !== 'clean') {
|
||||
throw new BadRequest('Puls hat neue Dokumente (unclean) - bitte warten Sie auf die KI-Analyse');
|
||||
|
||||
// Prüfe, ob bereits finalisiert
|
||||
if ($puls->get('status') === 'Finalisiert') {
|
||||
throw new Forbidden('Puls wurde bereits finalisiert.');
|
||||
}
|
||||
|
||||
// 4. Finde Zuordnung
|
||||
$zuordnung = $this->entityManager
|
||||
->getRDBRepository('CPulsTeamZuordnung')
|
||||
|
||||
// Prüfe syncStatus
|
||||
if ($puls->get('syncStatus') === 'unclean') {
|
||||
throw new BadRequest('Neue Dokumente vorhanden. Bitte warten Sie auf die KI-Analyse.');
|
||||
}
|
||||
|
||||
// Hole aktuelle Team-ID des Benutzers
|
||||
$user = $this->entityManager->getEntityById('User', $request->getServerParam('ESPO_USER_ID'));
|
||||
if (!$user) {
|
||||
throw new Forbidden('Benutzer nicht gefunden.');
|
||||
}
|
||||
|
||||
$teamIds = $user->getLinkMultipleIdList('teams');
|
||||
if (empty($teamIds)) {
|
||||
throw new Forbidden('Sie sind keinem Team zugeordnet.');
|
||||
}
|
||||
|
||||
// Finde Zuordnung für erstes Team des Benutzers
|
||||
$zuordnung = $this->entityManager->getRDBRepositoryByClass('CPulsTeamZuordnung')
|
||||
->where([
|
||||
'pulsId' => $pulsId,
|
||||
'teamId' => $teamId,
|
||||
'pulsId' => $id,
|
||||
'teamId' => $teamIds,
|
||||
'aktiv' => true
|
||||
])
|
||||
->findOne();
|
||||
|
||||
|
||||
if (!$zuordnung) {
|
||||
throw new NotFound('Team-Zuordnung nicht gefunden oder nicht aktiv');
|
||||
throw new Forbidden('Sie sind diesem Puls nicht zugeordnet oder nicht aktiv.');
|
||||
}
|
||||
|
||||
// 5. Bereits abgeschlossen?
|
||||
if ($zuordnung->get('abgeschlossen')) {
|
||||
return Response::json([
|
||||
'success' => true,
|
||||
'message' => 'Bereits abgeschlossen',
|
||||
'alreadyCompleted' => true
|
||||
]);
|
||||
}
|
||||
|
||||
// 6. Abschluss setzen
|
||||
|
||||
// Markiere Zuordnung als abgeschlossen
|
||||
$zuordnung->set([
|
||||
'abgeschlossen' => true,
|
||||
'abgeschlossenAm' => date('Y-m-d H:i:s'),
|
||||
'abgeschlossenVonId' => $this->user->getId()
|
||||
'abgeschlossenVon' => $user->getId()
|
||||
]);
|
||||
|
||||
$this->entityManager->saveEntity($zuordnung);
|
||||
|
||||
// 6.5. FIRST-READ-CLOSES: Finalisiere Block bei erstem Abschluss
|
||||
if (!$puls->get('finalisiert')) {
|
||||
$puls->set([
|
||||
'finalisiert' => true,
|
||||
'finalisierungsGrund' => 'Erstes Team',
|
||||
'finalisiertAm' => date('Y-m-d H:i:s'),
|
||||
'finalisiertVonId' => $this->user->getId()
|
||||
]);
|
||||
|
||||
$this->log->info("Block finalisiert durch erstes Team (Team {$teamId}, User {$this->user->getId()})");
|
||||
}
|
||||
|
||||
// 7. Prüfe: Alle Teams abgeschlossen?
|
||||
$offeneTeams = $this->entityManager
|
||||
->getRDBRepository('CPulsTeamZuordnung')
|
||||
->where([
|
||||
'pulsId' => $pulsId,
|
||||
'aktiv' => true,
|
||||
'abgeschlossen' => false
|
||||
])
|
||||
->count();
|
||||
|
||||
// 8. Update Puls-Status
|
||||
if ($offeneTeams === 0) {
|
||||
$puls->set('status', 'Abgeschlossen');
|
||||
} else {
|
||||
$puls->set('status', 'Teilweise abgeschlossen');
|
||||
}
|
||||
|
||||
|
||||
// FIRST-READ-CLOSES: Finalisiere den Puls sofort
|
||||
$puls->set([
|
||||
'status' => 'Finalisiert',
|
||||
'finalisiertAm' => date('Y-m-d H:i:s'),
|
||||
'finalisiertVon' => $user->getId()
|
||||
]);
|
||||
$this->entityManager->saveEntity($puls);
|
||||
|
||||
$this->log->info("Team {$teamId} hat Puls {$pulsId} abgeschlossen");
|
||||
|
||||
return Response::json([
|
||||
|
||||
$GLOBALS['log']->info("Puls {$id} durch Team {$zuordnung->get('teamId')} finalisiert (First-Read-Closes).");
|
||||
|
||||
return ResponseComposer::json([
|
||||
'success' => true,
|
||||
'status' => $puls->get('status'),
|
||||
'finalisiert' => $puls->get('finalisiert'),
|
||||
'offeneTeams' => $offeneTeams
|
||||
'finalized' => true,
|
||||
'message' => 'Puls wurde finalisiert (First-Read-Closes).'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
namespace Espo\Custom\Hooks\CPuls;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
use Espo\ORM\Repository\Option\SaveOptions;
|
||||
use Espo\Core\Hook\Hook\BeforeSave;
|
||||
|
||||
class UpdateTeamStats implements BeforeSave
|
||||
@@ -10,7 +11,7 @@ class UpdateTeamStats implements BeforeSave
|
||||
private \Espo\ORM\EntityManager $entityManager
|
||||
) {}
|
||||
|
||||
public function beforeSave(Entity $entity, array $options): void
|
||||
public function beforeSave(Entity $entity, SaveOptions $options): void
|
||||
{
|
||||
// Zähle Dokumente
|
||||
if ($entity->isNew() || $entity->isAttributeChanged('id')) {
|
||||
|
||||
@@ -1,37 +1,35 @@
|
||||
{
|
||||
"labels": {
|
||||
"Create CPuls": "Puls erstellen",
|
||||
"CPuls": "Puls",
|
||||
"cPuls": "Pulse"
|
||||
},
|
||||
"fields": {
|
||||
"name": "Bezeichnung",
|
||||
"CPulse": "Pulse",
|
||||
"Create CPuls": "Puls erstellen",
|
||||
"name": "Name",
|
||||
"status": "Status",
|
||||
"syncStatus": "Synchronisations-Status",
|
||||
"syncStatus": "Synchronisierungs-Status",
|
||||
"kiAnalyse": "KI-Analyse",
|
||||
"zusammenfassung": "Zusammenfassung",
|
||||
"anzahlDokumente": "Anzahl Dokumente",
|
||||
"anzahlTeamsAktiv": "Teams (aktiv)",
|
||||
"anzahlTeamsAbgeschlossen": "Teams (abgeschlossen)",
|
||||
"finalisiert": "Finalisiert",
|
||||
"finalisierungsGrund": "Finalisierungsgrund",
|
||||
"anzahlTeamsAktiv": "Teams aktiv",
|
||||
"anzahlTeamsAbgeschlossen": "Teams abgeschlossen",
|
||||
"finalisiertAm": "Finalisiert am",
|
||||
"finalisiertVon": "Finalisiert von",
|
||||
"mandantMitteilung": "Mitteilung an Mandant",
|
||||
"mandantMitteilungText": "Mitteilungstext",
|
||||
"parent": "Vorgang",
|
||||
"dokumente": "Dokumente",
|
||||
"teamZuordnungen": "Team-Zuordnungen"
|
||||
"assignedUser": "Zugewiesen"
|
||||
},
|
||||
"links": {
|
||||
"parent": "Vorgang",
|
||||
"dokumente": "Dokumente",
|
||||
"teamZuordnungen": "Team-Zuordnungen"
|
||||
},
|
||||
"tooltips": {
|
||||
"syncStatus": "clean = KI-Analyse aktuell | unclean = Neue Dokumente, Analyse ausstehend",
|
||||
"kiAnalyse": "Automatisch generierte Zusammenfassung durch KI-Middleware",
|
||||
"zusammenfassung": "Kurze Zusammenfassung für Listen-Ansicht",
|
||||
"finalisiert": "Block wurde geschlossen - neue Dokumente erzeugen automatisch einen neuen Block (First-Read-Closes Prinzip)",
|
||||
"finalisierungsGrund": "Grund der Finalisierung: Erstes Team = Team hat abgeschlossen | Manuell = Admin-Aktion | Automatisch = System-Regel"
|
||||
"syncStatus": "Status der KI-Analyse für neue Dokumente",
|
||||
"kiAnalyse": "Vollständige Analyse der KI zu den Dokumenten",
|
||||
"zusammenfassung": "Kurze Zusammenfassung der KI-Analyse",
|
||||
"finalisiertAm": "Zeitpunkt, zu dem dieser Puls finalisiert wurde",
|
||||
"finalisiertVon": "Benutzer, der den Puls durch Abschluss finalisiert hat",
|
||||
"mandantMitteilung": "Soll eine Mitteilung an den Mandanten versendet werden?",
|
||||
"mandantMitteilungText": "Text der Mitteilung an den Mandanten"
|
||||
},
|
||||
"options": {
|
||||
"status": {
|
||||
@@ -40,19 +38,12 @@
|
||||
"Bereit": "Bereit",
|
||||
"In Review": "In Review",
|
||||
"Teilweise abgeschlossen": "Teilweise abgeschlossen",
|
||||
"Abgeschlossen": "Abgeschlossen"
|
||||
"Abgeschlossen": "Abgeschlossen",
|
||||
"Finalisiert": "Finalisiert"
|
||||
},
|
||||
"syncStatus": {
|
||||
"clean": "Aktuell",
|
||||
"clean": "Synchron",
|
||||
"unclean": "Ausstehend"
|
||||
},
|
||||
"finalisierungsGrund": {
|
||||
"Erstes Team": "Erstes Team",
|
||||
"Manuell": "Manuell",
|
||||
"Automatisch": "Automatisch"
|
||||
}
|
||||
},
|
||||
"presetFilters": {
|
||||
"meineOffenen": "Meine offenen Pulse"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,58 +1,49 @@
|
||||
{
|
||||
"labels": {
|
||||
"Create CPuls": "Create Pulse",
|
||||
"CPuls": "Pulse",
|
||||
"cPuls": "Pulses"
|
||||
},
|
||||
"fields": {
|
||||
"CPulse": "Pulses",
|
||||
"Create CPuls": "Create Pulse",
|
||||
"name": "Name",
|
||||
"status": "Status",
|
||||
"syncStatus": "Sync Status",
|
||||
"kiAnalyse": "AI Analysis",
|
||||
"zusammenfassung": "Summary",
|
||||
"anzahlDokumente": "Number of Documents",
|
||||
"anzahlTeamsAktiv": "Teams (active)",
|
||||
"anzahlTeamsAbgeschlossen": "Teams (completed)",
|
||||
"finalisiert": "Finalized",
|
||||
"finalisierungsGrund": "Finalization Reason",
|
||||
"anzahlDokumente": "Document Count",
|
||||
"anzahlTeamsAktiv": "Active Teams",
|
||||
"anzahlTeamsAbgeschlossen": "Completed Teams",
|
||||
"finalisiertAm": "Finalized At",
|
||||
"finalisiertVon": "Finalized By",
|
||||
"parent": "Parent Record",
|
||||
"dokumente": "Documents",
|
||||
"teamZuordnungen": "Team Assignments"
|
||||
"mandantMitteilung": "Client Notification",
|
||||
"mandantMitteilungText": "Notification Text",
|
||||
"parent": "Case",
|
||||
"assignedUser": "Assigned To"
|
||||
},
|
||||
"links": {
|
||||
"parent": "Parent Record",
|
||||
"dokumente": "Documents",
|
||||
"teamZuordnungen": "Team Assignments"
|
||||
},
|
||||
"tooltips": {
|
||||
"syncStatus": "clean = AI analysis up-to-date | unclean = New documents, analysis pending",
|
||||
"kiAnalyse": "Automatically generated summary by AI middleware",
|
||||
"zusammenfassung": "Short summary for list views",
|
||||
"finalisiert": "Block has been closed - new documents will automatically create a new block (First-Read-Closes principle)",
|
||||
"finalisierungsGrund": "Reason for finalization: First Team = Team completed | Manual = Admin action | Automatic = System rule"
|
||||
"syncStatus": "AI analysis status for new documents",
|
||||
"kiAnalyse": "Complete AI analysis of the documents",
|
||||
"zusammenfassung": "Brief summary of the AI analysis",
|
||||
"finalisiertAm": "Date and time when this pulse was finalized",
|
||||
"finalisiertVon": "User who finalized the pulse by completion",
|
||||
"mandantMitteilung": "Should a notification be sent to the client?",
|
||||
"mandantMitteilungText": "Text of the notification to the client"
|
||||
},
|
||||
"options": {
|
||||
"status": {
|
||||
"Neu": "New",
|
||||
"In Verarbeitung": "Processing",
|
||||
"In Verarbeitung": "In Progress",
|
||||
"Bereit": "Ready",
|
||||
"In Review": "In Review",
|
||||
"Teilweise abgeschlossen": "Partially Completed",
|
||||
"Abgeschlossen": "Completed"
|
||||
"Abgeschlossen": "Completed",
|
||||
"Finalisiert": "Finalized"
|
||||
},
|
||||
"syncStatus": {
|
||||
"clean": "Up-to-date",
|
||||
"clean": "Synchronized",
|
||||
"unclean": "Pending"
|
||||
},
|
||||
"finalisierungsGrund": {
|
||||
"Erstes Team": "First Team",
|
||||
"Manuell": "Manual",
|
||||
"Automatisch": "Automatic"
|
||||
}
|
||||
},
|
||||
"presetFilters": {
|
||||
"meineOffenen": "My Open Pulses"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,27 @@
|
||||
{
|
||||
"teamZuordnungen": {
|
||||
"_delimiter_": {
|
||||
"disabled": true
|
||||
},
|
||||
"activities": {
|
||||
"disabled": true
|
||||
},
|
||||
"history": {
|
||||
"disabled": true
|
||||
},
|
||||
"_tabBreak_0": {
|
||||
"index": 0,
|
||||
"sticked": true,
|
||||
"style": "info",
|
||||
"label": "Team-Zuordnungen"
|
||||
"tabBreak": true,
|
||||
"tabLabel": "Dokumente"
|
||||
},
|
||||
"dokumente": {
|
||||
"index": 1,
|
||||
"sticked": false,
|
||||
"label": "Dokumente"
|
||||
"index": 1
|
||||
},
|
||||
"_tabBreak_1": {
|
||||
"index": 2,
|
||||
"tabBreak": true,
|
||||
"tabLabel": "Aktivitäten"
|
||||
},
|
||||
"stream": {
|
||||
"index": 2,
|
||||
"sticked": false
|
||||
"index": 3
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
[
|
||||
{
|
||||
"name": ":assignedUser"
|
||||
},
|
||||
{
|
||||
"name": "teams"
|
||||
},
|
||||
{
|
||||
"name": "teamZuordnungen"
|
||||
}
|
||||
]
|
||||
@@ -1,6 +1,8 @@
|
||||
[
|
||||
{
|
||||
"label": "Übersicht",
|
||||
"style": "default",
|
||||
"tabBreak": false,
|
||||
"rows": [
|
||||
[
|
||||
{"name": "name"},
|
||||
@@ -14,10 +16,6 @@
|
||||
{"name": "anzahlDokumente"},
|
||||
{"name": "anzahlTeamsAktiv"}
|
||||
],
|
||||
[
|
||||
{"name": "finalisiert"},
|
||||
{"name": "finalisierungsGrund"}
|
||||
],
|
||||
[
|
||||
{"name": "zusammenfassung", "span": 2}
|
||||
]
|
||||
@@ -25,6 +23,8 @@
|
||||
},
|
||||
{
|
||||
"label": "KI-Analyse",
|
||||
"style": "default",
|
||||
"tabBreak": false,
|
||||
"rows": [
|
||||
[
|
||||
{"name": "kiAnalyse", "span": 2}
|
||||
@@ -32,7 +32,24 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "System",
|
||||
"label": "Mandant",
|
||||
"style": "default",
|
||||
"tabBreak": false,
|
||||
"rows": [
|
||||
[
|
||||
{"name": "mandantMitteilung"},
|
||||
{}
|
||||
],
|
||||
[
|
||||
{"name": "mandantMitteilungText", "span": 2}
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Metadaten",
|
||||
"style": "default",
|
||||
"tabBreak": true,
|
||||
"tabLabel": "Erweitert",
|
||||
"rows": [
|
||||
[
|
||||
{"name": "createdAt"},
|
||||
@@ -41,6 +58,10 @@
|
||||
[
|
||||
{"name": "createdBy"},
|
||||
{"name": "modifiedBy"}
|
||||
],
|
||||
[
|
||||
{"name": "finalisiertAm"},
|
||||
{"name": "finalisiertVon"}
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
"Bereit",
|
||||
"In Review",
|
||||
"Teilweise abgeschlossen",
|
||||
"Abgeschlossen"
|
||||
"Abgeschlossen",
|
||||
"Finalisiert"
|
||||
],
|
||||
"default": "Neu",
|
||||
"required": true,
|
||||
@@ -26,7 +27,8 @@
|
||||
"Bereit": "success",
|
||||
"In Review": "warning",
|
||||
"Teilweise abgeschlossen": "info",
|
||||
"Abgeschlossen": "success"
|
||||
"Abgeschlossen": "success",
|
||||
"Finalisiert": "danger"
|
||||
}
|
||||
},
|
||||
"syncStatus": {
|
||||
@@ -66,24 +68,6 @@
|
||||
"notStorable": false,
|
||||
"isCustom": true
|
||||
},
|
||||
"finalisiert": {
|
||||
"type": "bool",
|
||||
"default": false,
|
||||
"readOnly": true,
|
||||
"isCustom": true,
|
||||
"tooltip": true
|
||||
},
|
||||
"finalisierungsGrund": {
|
||||
"type": "enum",
|
||||
"options": [
|
||||
"Erstes Team",
|
||||
"Manuell",
|
||||
"Automatisch"
|
||||
],
|
||||
"readOnly": true,
|
||||
"isCustom": true,
|
||||
"tooltip": true
|
||||
},
|
||||
"finalisiertAm": {
|
||||
"type": "datetime",
|
||||
"readOnly": true,
|
||||
@@ -95,6 +79,17 @@
|
||||
"readOnly": true,
|
||||
"isCustom": true
|
||||
},
|
||||
"mandantMitteilung": {
|
||||
"type": "bool",
|
||||
"default": false,
|
||||
"isCustom": true,
|
||||
"tooltip": true
|
||||
},
|
||||
"mandantMitteilungText": {
|
||||
"type": "text",
|
||||
"isCustom": true,
|
||||
"tooltip": true
|
||||
},
|
||||
"createdAt": {
|
||||
"type": "datetime",
|
||||
"readOnly": true
|
||||
@@ -117,10 +112,6 @@
|
||||
"type": "link",
|
||||
"entity": "User",
|
||||
"isCustom": true
|
||||
},
|
||||
"teams": {
|
||||
"type": "linkMultiple",
|
||||
"isCustom": true
|
||||
}
|
||||
},
|
||||
"links": {
|
||||
@@ -180,11 +171,8 @@
|
||||
"syncStatus": {
|
||||
"columns": ["syncStatus"]
|
||||
},
|
||||
"finalisiert": {
|
||||
"columns": ["finalisiert"]
|
||||
},
|
||||
"createdAt": {
|
||||
"columns": ["createdAt"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,12 +4,14 @@
|
||||
"type": "varchar",
|
||||
"notStorable": true,
|
||||
"select": {
|
||||
"select": "CONCAT:(team.name, ' - ', puls.name)"
|
||||
"select": "CONCAT:(team.name, ' - ', puls.name)",
|
||||
"leftJoins": ["team", "puls"]
|
||||
},
|
||||
"orderBy": {
|
||||
"order": [
|
||||
["team.name", "{direction}"]
|
||||
]
|
||||
],
|
||||
"leftJoins": ["team"]
|
||||
}
|
||||
},
|
||||
"puls": {
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"beforeSaveApiScript": "// Verhindere Abschluss bei unclean Status\nif (\n (status == 'Abgeschlossen' || entity\\isAttributeChanged('status'))\n && syncStatus == 'unclean'\n) {\n recordService\\throwBadRequest('Puls kann nicht abgeschlossen werden: Neue Dokumente vorhanden (Status: unclean). Bitte warten Sie auf die KI-Analyse.');\n}\n\n// Verhindere Änderungen an finalisiertem Puls\nif (\n finalisiert == true\n && entity\\isAttributeChanged('finalisiert') == false\n && (entity\\isAttributeChanged('status') || entity\\isAttributeChanged('syncStatus'))\n) {\n recordService\\throwBadRequest('Puls ist finalisiert. Neue Dokumente erzeugen automatisch einen neuen Block.');\n}"
|
||||
"beforeSaveApiScript": "// Verhindere Abschluss bei unclean Status\nif (\n entity\\isAttributeChanged('status') &&\n status == 'Abgeschlossen' &&\n syncStatus == 'unclean'\n) {\n recordService\\throwBadRequest('Puls kann nicht abgeschlossen werden: Neue Dokumente vorhanden (Status: unclean). Bitte warten Sie auf die KI-Analyse.');\n}\n\n// Verhindere Änderungen an finalisiertem Puls\nif (\n status == 'Finalisiert' &&\n !entity\\isAttributeChanged('status') &&\n (entity\\isAttributeChanged('syncStatus'))\n) {\n recordService\\throwBadRequest('Puls ist finalisiert. Neue Dokumente erzeugen automatisch einen neuen Block.');\n}"
|
||||
}
|
||||
|
||||
@@ -358,7 +358,7 @@ return [
|
||||
0 => 'youtube.com',
|
||||
1 => 'google.com'
|
||||
],
|
||||
'microtime' => 1770973606.273594,
|
||||
'microtime' => 1770974863.576723,
|
||||
'siteUrl' => 'https://crm.bitbylaw.com',
|
||||
'fullTextSearchMinLength' => 4,
|
||||
'webSocketUrl' => 'ws://api.bitbylaw.com:5000/espocrm/ws',
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
return [
|
||||
'cacheTimestamp' => 1770973606,
|
||||
'microtimeState' => 1770973606.458758,
|
||||
'cacheTimestamp' => 1770974863,
|
||||
'microtimeState' => 1770974863.697017,
|
||||
'currencyRates' => [
|
||||
'EUR' => 1.0
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user