194 lines
7.2 KiB
PHP
194 lines
7.2 KiB
PHP
<?php
|
|
namespace Espo\Custom\Hooks\CDokumente;
|
|
|
|
use Espo\ORM\Entity;
|
|
use Espo\Core\Hook\Hook\AfterRelate;
|
|
use Espo\Core\Hook\Hook\AfterUnrelate;
|
|
use Espo\ORM\Repository\Option\RelateOptions;
|
|
use Espo\ORM\Repository\Option\UnrelateOptions;
|
|
|
|
/**
|
|
* Hook: Sync-Status-Aktualisierung wenn ein Dokument über die CDokumente-Panels
|
|
* mit einer Räumungsklage oder einem Mietinkasso verknüpft oder entknüpft wird.
|
|
*
|
|
* Auslöser (von CDokumente-Seite aus):
|
|
* - afterRelate 'vmhRumungsklagesdokumente' → Räumungsklage verknüpft
|
|
* - afterRelate 'mietinkassosdokumente' → Mietinkasso verknüpft
|
|
* - afterUnrelate 'vmhRumungsklagesdokumente' → Räumungsklage entknüpft
|
|
* - afterUnrelate 'mietinkassosdokumente' → Mietinkasso entknüpft
|
|
*
|
|
* Wenn die Verknüpfung von der Räumungsklage/Mietinkasso-Seite kommt, feuern
|
|
* stattdessen CVmhRumungsklage/CMietinkasso::PropagateDocuments — dieses Hook
|
|
* feuert dann NICHT (EspoCRM feuert afterRelate nur auf der aufrufenden Seite).
|
|
*/
|
|
class SyncStatusOnRelate implements AfterRelate, AfterUnrelate
|
|
{
|
|
/** Relation → [parentEntityType, advowareAktenRelation, aiKnowledgeRelation] */
|
|
private const RELATION_MAP = [
|
|
'vmhRumungsklagesdokumente' => ['CVmhRumungsklage', 'advowareAkten', 'aIKnowledge'],
|
|
'mietinkassosdokumente' => ['CMietinkasso', 'advowareAkten', 'aIKnowledge'],
|
|
];
|
|
|
|
/** @var array<string, bool> */
|
|
private static array $processing = [];
|
|
|
|
public function __construct(
|
|
private \Espo\ORM\EntityManager $entityManager
|
|
) {}
|
|
|
|
// -------------------------------------------------------------------------
|
|
|
|
public function afterRelate(
|
|
Entity $entity,
|
|
string $relationName,
|
|
Entity $foreignEntity,
|
|
array $columnData,
|
|
RelateOptions $options
|
|
): void {
|
|
if (!isset(self::RELATION_MAP[$relationName])) {
|
|
return;
|
|
}
|
|
|
|
$key = $entity->getId() . '-' . $foreignEntity->getId() . '-' . $relationName . '-relate';
|
|
if (isset(self::$processing[$key])) {
|
|
return;
|
|
}
|
|
self::$processing[$key] = true;
|
|
|
|
try {
|
|
[, $aktenRelation, $aiKnowledgeRelation] = self::RELATION_MAP[$relationName];
|
|
|
|
// AdvowareAkten über die Parent-Entity ermitteln
|
|
$advowareAkten = $this->entityManager
|
|
->getRDBRepository($foreignEntity->getEntityType())
|
|
->getRelation($foreignEntity, $aktenRelation)
|
|
->findOne();
|
|
|
|
if ($advowareAkten) {
|
|
$entity->set('cAktenId', $advowareAkten->getId());
|
|
$entity->set('syncStatus', 'unclean');
|
|
$entity->set('aiSyncStatus', 'unclean');
|
|
$entity->set('aiParsingStatus', 'unknown');
|
|
$this->entityManager->saveEntity($entity, ['silent' => true, 'skipHooks' => true]);
|
|
|
|
$this->triggerAkteUpdate($advowareAkten->getId());
|
|
} else {
|
|
// Kein Akte-Link — trotzdem Sync-Status auf unclean setzen
|
|
$entity->set('syncStatus', 'unclean');
|
|
$entity->set('aiSyncStatus', 'unclean');
|
|
$entity->set('aiParsingStatus', 'unknown');
|
|
$this->entityManager->saveEntity($entity, ['silent' => true, 'skipHooks' => true]);
|
|
}
|
|
|
|
// AIKnowledge-Verknüpfung propagieren
|
|
$aiKnowledge = $this->entityManager
|
|
->getRDBRepository($foreignEntity->getEntityType())
|
|
->getRelation($foreignEntity, $aiKnowledgeRelation)
|
|
->findOne();
|
|
|
|
if ($aiKnowledge) {
|
|
$this->relateIfNotAlready($aiKnowledge, 'dokumentes', $entity);
|
|
}
|
|
|
|
} catch (\Exception $e) {
|
|
$GLOBALS['log']->error(
|
|
'CDokumente SyncStatusOnRelate afterRelate (' . $relationName . ') Error: ' . $e->getMessage()
|
|
);
|
|
} finally {
|
|
unset(self::$processing[$key]);
|
|
}
|
|
}
|
|
|
|
// -------------------------------------------------------------------------
|
|
|
|
public function afterUnrelate(
|
|
Entity $entity,
|
|
string $relationName,
|
|
Entity $foreignEntity,
|
|
UnrelateOptions $options
|
|
): void {
|
|
if (!isset(self::RELATION_MAP[$relationName])) {
|
|
return;
|
|
}
|
|
|
|
$key = $entity->getId() . '-' . $foreignEntity->getId() . '-' . $relationName . '-unrelate';
|
|
if (isset(self::$processing[$key])) {
|
|
return;
|
|
}
|
|
self::$processing[$key] = true;
|
|
|
|
try {
|
|
[, $aktenRelation, $aiKnowledgeRelation] = self::RELATION_MAP[$relationName];
|
|
|
|
// Alte Akte ermitteln
|
|
$advowareAkten = $this->entityManager
|
|
->getRDBRepository($foreignEntity->getEntityType())
|
|
->getRelation($foreignEntity, $aktenRelation)
|
|
->findOne();
|
|
|
|
$oldAkteId = null;
|
|
|
|
if ($advowareAkten && $entity->get('cAktenId') === $advowareAkten->getId()) {
|
|
$oldAkteId = $advowareAkten->getId();
|
|
$entity->set('cAktenId', null);
|
|
$entity->set('syncStatus', 'unclean');
|
|
$entity->set('aiSyncStatus', 'unclean');
|
|
$this->entityManager->saveEntity($entity, ['silent' => true, 'skipHooks' => true]);
|
|
}
|
|
|
|
if ($oldAkteId) {
|
|
$this->triggerAkteUpdate($oldAkteId);
|
|
}
|
|
|
|
// AIKnowledge-Verknüpfung entfernen
|
|
$aiKnowledge = $this->entityManager
|
|
->getRDBRepository($foreignEntity->getEntityType())
|
|
->getRelation($foreignEntity, $aiKnowledgeRelation)
|
|
->findOne();
|
|
|
|
if ($aiKnowledge) {
|
|
$this->unrelateIfExists($aiKnowledge, 'dokumentes', $entity);
|
|
}
|
|
|
|
} catch (\Exception $e) {
|
|
$GLOBALS['log']->error(
|
|
'CDokumente SyncStatusOnRelate afterUnrelate (' . $relationName . ') Error: ' . $e->getMessage()
|
|
);
|
|
} finally {
|
|
unset(self::$processing[$key]);
|
|
}
|
|
}
|
|
|
|
// -------------------------------------------------------------------------
|
|
|
|
private function triggerAkteUpdate(string $akteId): void
|
|
{
|
|
$akte = $this->entityManager->getEntityById('CAkten', $akteId);
|
|
if ($akte) {
|
|
$this->entityManager->saveEntity($akte, ['silent' => true]);
|
|
}
|
|
}
|
|
|
|
private function relateIfNotAlready(Entity $parentEntity, string $relationName, Entity $document): void
|
|
{
|
|
$repository = $this->entityManager->getRDBRepository($parentEntity->getEntityType());
|
|
$relation = $repository->getRelation($parentEntity, $relationName);
|
|
|
|
$isRelated = $relation->where(['id' => $document->getId()])->findOne();
|
|
if (!$isRelated) {
|
|
$relation->relate($document);
|
|
}
|
|
}
|
|
|
|
private function unrelateIfExists(Entity $parentEntity, string $relationName, Entity $document): void
|
|
{
|
|
$repository = $this->entityManager->getRDBRepository($parentEntity->getEntityType());
|
|
$relation = $repository->getRelation($parentEntity, $relationName);
|
|
|
|
$isRelated = $relation->where(['id' => $document->getId()])->findOne();
|
|
if ($isRelated) {
|
|
$relation->unrelate($document);
|
|
}
|
|
}
|
|
}
|