Refactor eviction and rent collection features; migrate logic from Mietobjekt to Mietverhältnis; update localization and UI handlers
This commit is contained in:
@@ -1,57 +0,0 @@
|
|||||||
define('custom:handlers/mietobjekt/eviction-action', [], function () {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handler for initiating eviction lawsuit from Mietobjekt
|
|
||||||
*/
|
|
||||||
return class {
|
|
||||||
|
|
||||||
constructor(view) {
|
|
||||||
this.view = view;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the handler
|
|
||||||
*/
|
|
||||||
initEvictionAction() {
|
|
||||||
// Initialization if needed
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Action to initiate eviction (Räumungsklage)
|
|
||||||
*/
|
|
||||||
initiateEviction() {
|
|
||||||
const model = this.view.model;
|
|
||||||
|
|
||||||
// Confirm dialog
|
|
||||||
this.view.confirm(
|
|
||||||
this.view.translate('initiateEvictionConfirmation', 'messages', 'CMietobjekt'),
|
|
||||||
() => {
|
|
||||||
Espo.Ui.notify(this.view.translate('pleaseWait', 'messages'));
|
|
||||||
|
|
||||||
// POST request to backend
|
|
||||||
Espo.Ajax.postRequest('CMietobjekt/action/initiateEviction', {
|
|
||||||
id: model.id
|
|
||||||
}).then(response => {
|
|
||||||
Espo.Ui.success(
|
|
||||||
this.view.translate('evictionCreatedSuccess', 'messages', 'CMietobjekt')
|
|
||||||
);
|
|
||||||
|
|
||||||
// Navigate to the newly created Räumungsklage
|
|
||||||
this.view.getRouter().navigate(
|
|
||||||
'#CVmhRumungsklage/view/' + response.id,
|
|
||||||
{trigger: true}
|
|
||||||
);
|
|
||||||
}).catch(xhr => {
|
|
||||||
let message = this.view.translate('evictionCreatedError', 'messages', 'CMietobjekt');
|
|
||||||
|
|
||||||
if (xhr.responseJSON && xhr.responseJSON.message) {
|
|
||||||
message = xhr.responseJSON.message;
|
|
||||||
}
|
|
||||||
|
|
||||||
Espo.Ui.error(message);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
define('custom:handlers/mietverhaeltnis/eviction-action', [], function () {
|
||||||
|
|
||||||
|
class EvictionActionHandler {
|
||||||
|
|
||||||
|
constructor(view) {
|
||||||
|
this.view = view;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup-Methode wird automatisch aufgerufen
|
||||||
|
*/
|
||||||
|
initInitiateEviction() {
|
||||||
|
// Optional: Button-Logik nach Render
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action-Handler (wird bei Button-Click aufgerufen)
|
||||||
|
*/
|
||||||
|
actionInitiateEviction() {
|
||||||
|
console.log('actionInitiateEviction called');
|
||||||
|
const model = this.view.model;
|
||||||
|
|
||||||
|
// Confirmation Dialog
|
||||||
|
this.view.confirm(
|
||||||
|
this.view.translate('confirmEviction', 'messages', 'CVmhMietverhltnis'),
|
||||||
|
() => {
|
||||||
|
console.log('Confirmation accepted, initiating eviction');
|
||||||
|
this.initiateEviction(model.id);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AJAX Request zum Backend
|
||||||
|
*/
|
||||||
|
initiateEviction(mietverhaeltnisId) {
|
||||||
|
Espo.Ui.notify(this.view.translate('pleaseWait', 'messages'));
|
||||||
|
|
||||||
|
Espo.Ajax.postRequest('CVmhMietverhltnis/action/initiateEviction', {
|
||||||
|
id: mietverhaeltnisId
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
Espo.Ui.success(
|
||||||
|
this.view.translate('evictionCreated', 'messages', 'CVmhMietverhltnis')
|
||||||
|
);
|
||||||
|
|
||||||
|
// Navigation zur erstellten Räumungsklage
|
||||||
|
this.view.getRouter().navigate(
|
||||||
|
'#CVmhRumungsklage/view/' + response.id,
|
||||||
|
{trigger: true}
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.catch(xhr => {
|
||||||
|
console.error('Eviction initiation failed:', xhr);
|
||||||
|
|
||||||
|
let errorMessage = this.view.translate('evictionError', 'messages', 'CVmhMietverhltnis');
|
||||||
|
|
||||||
|
if (xhr.status === 403) {
|
||||||
|
errorMessage = this.view.translate('Access denied', 'messages');
|
||||||
|
} else if (xhr.status === 404) {
|
||||||
|
errorMessage = this.view.translate('Not found', 'messages');
|
||||||
|
}
|
||||||
|
|
||||||
|
Espo.Ui.error(errorMessage);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return EvictionActionHandler;
|
||||||
|
});
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
define('custom:handlers/mietverhaeltnis/rent-collection-action', [], function () {
|
||||||
|
|
||||||
|
class RentCollectionActionHandler {
|
||||||
|
|
||||||
|
constructor(view) {
|
||||||
|
this.view = view;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup-Methode wird automatisch aufgerufen
|
||||||
|
*/
|
||||||
|
initInitiateRentCollection() {
|
||||||
|
// Optional: Button-Logik nach Render
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action-Handler (wird bei Button-Click aufgerufen)
|
||||||
|
*/
|
||||||
|
actionInitiateRentCollection() {
|
||||||
|
console.log('actionInitiateRentCollection called');
|
||||||
|
const model = this.view.model;
|
||||||
|
|
||||||
|
// Confirmation Dialog
|
||||||
|
this.view.confirm(
|
||||||
|
this.view.translate('confirmRentCollection', 'messages', 'CVmhMietverhltnis'),
|
||||||
|
() => {
|
||||||
|
console.log('Confirmation accepted, initiating rent collection');
|
||||||
|
this.initiateRentCollection(model.id);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AJAX Request zum Backend
|
||||||
|
*/
|
||||||
|
initiateRentCollection(mietverhaeltnisId) {
|
||||||
|
Espo.Ui.notify(this.view.translate('pleaseWait', 'messages'));
|
||||||
|
|
||||||
|
Espo.Ajax.postRequest('CVmhMietverhltnis/action/initiateRentCollection', {
|
||||||
|
id: mietverhaeltnisId
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
Espo.Ui.success(
|
||||||
|
this.view.translate('rentCollectionCreated', 'messages', 'CVmhMietverhltnis')
|
||||||
|
);
|
||||||
|
|
||||||
|
// Navigation zum erstellten Mietinkasso
|
||||||
|
this.view.getRouter().navigate(
|
||||||
|
'#CMietinkasso/view/' + response.id,
|
||||||
|
{trigger: true}
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.catch(xhr => {
|
||||||
|
console.error('Rent collection initiation failed:', xhr);
|
||||||
|
|
||||||
|
let errorMessage = this.view.translate('rentCollectionError', 'messages', 'CVmhMietverhltnis');
|
||||||
|
|
||||||
|
if (xhr.status === 403) {
|
||||||
|
errorMessage = this.view.translate('Access denied', 'messages');
|
||||||
|
} else if (xhr.status === 404) {
|
||||||
|
errorMessage = this.view.translate('Not found', 'messages');
|
||||||
|
}
|
||||||
|
|
||||||
|
Espo.Ui.error(errorMessage);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return RentCollectionActionHandler;
|
||||||
|
});
|
||||||
@@ -2,27 +2,6 @@
|
|||||||
|
|
||||||
namespace Espo\Custom\Controllers;
|
namespace Espo\Custom\Controllers;
|
||||||
|
|
||||||
use Espo\Core\Exceptions\BadRequest;
|
|
||||||
use Espo\Core\Exceptions\Forbidden;
|
|
||||||
use Espo\Core\Api\Request;
|
|
||||||
|
|
||||||
class CMietobjekt extends \Espo\Core\Templates\Controllers\Base
|
class CMietobjekt extends \Espo\Core\Templates\Controllers\Base
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* POST Action: Initiate eviction lawsuit from Mietobjekt
|
|
||||||
*/
|
|
||||||
public function postActionInitiateEviction(Request $request): array
|
|
||||||
{
|
|
||||||
$data = $request->getParsedBody();
|
|
||||||
|
|
||||||
$id = $data->id ?? null;
|
|
||||||
if (!$id) {
|
|
||||||
throw new BadRequest('No Mietobjekt ID provided');
|
|
||||||
}
|
|
||||||
|
|
||||||
$service = $this->getRecordService();
|
|
||||||
$result = $service->initiateEviction($id);
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,44 @@
|
|||||||
|
|
||||||
namespace Espo\Custom\Controllers;
|
namespace Espo\Custom\Controllers;
|
||||||
|
|
||||||
|
use Espo\Core\Exceptions\BadRequest;
|
||||||
|
use Espo\Core\Api\Request;
|
||||||
|
|
||||||
class CVmhMietverhltnis extends \Espo\Core\Templates\Controllers\BasePlus
|
class CVmhMietverhltnis extends \Espo\Core\Templates\Controllers\BasePlus
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* POST Action: Initiate eviction lawsuit from Mietverhältnis
|
||||||
|
*/
|
||||||
|
public function postActionInitiateEviction(Request $request): array
|
||||||
|
{
|
||||||
|
$data = $request->getParsedBody();
|
||||||
|
|
||||||
|
$id = $data->id ?? null;
|
||||||
|
if (!$id) {
|
||||||
|
throw new BadRequest('No Mietverhältnis ID provided');
|
||||||
|
}
|
||||||
|
|
||||||
|
$service = $this->getRecordService();
|
||||||
|
$result = $service->initiateEviction($id);
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POST Action: Initiate rent collection from Mietverhältnis
|
||||||
|
*/
|
||||||
|
public function postActionInitiateRentCollection(Request $request): array
|
||||||
|
{
|
||||||
|
$data = $request->getParsedBody();
|
||||||
|
|
||||||
|
$id = $data->id ?? null;
|
||||||
|
if (!$id) {
|
||||||
|
throw new BadRequest('No Mietverhältnis ID provided');
|
||||||
|
}
|
||||||
|
|
||||||
|
$service = $this->getRecordService();
|
||||||
|
$result = $service->initiateRentCollection($id);
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,16 @@
|
|||||||
"vmhMietobjekt": "Mietobjekt"
|
"vmhMietobjekt": "Mietobjekt"
|
||||||
},
|
},
|
||||||
"labels": {
|
"labels": {
|
||||||
"Create CVmhMietverhltnis": "Mietverhältnis erstellen"
|
"Create CVmhMietverhltnis": "Mietverhältnis erstellen",
|
||||||
|
"Initiate Eviction": "Räumungsklage einleiten",
|
||||||
|
"Initiate Rent Collection": "Mietinkasso einleiten"
|
||||||
|
},
|
||||||
|
"messages": {
|
||||||
|
"confirmEviction": "Möchten Sie wirklich eine Räumungsklage aus diesem Mietverhältnis einleiten?",
|
||||||
|
"evictionCreated": "Räumungsklage wurde erfolgreich erstellt",
|
||||||
|
"evictionError": "Fehler beim Erstellen der Räumungsklage",
|
||||||
|
"confirmRentCollection": "Möchten Sie wirklich ein Mietinkasso aus diesem Mietverhältnis einleiten?",
|
||||||
|
"rentCollectionCreated": "Mietinkasso wurde erfolgreich erstellt",
|
||||||
|
"rentCollectionError": "Fehler beim Erstellen des Mietinkassos"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -45,7 +45,17 @@
|
|||||||
"vmhMietobjekt": "Property"
|
"vmhMietobjekt": "Property"
|
||||||
},
|
},
|
||||||
"labels": {
|
"labels": {
|
||||||
"Create CVmhMietverhltnis": "Create Mietverhältnis"
|
"Create CVmhMietverhltnis": "Create Mietverhältnis",
|
||||||
|
"Initiate Eviction": "Initiate Eviction Lawsuit",
|
||||||
|
"Initiate Rent Collection": "Initiate Rent Collection"
|
||||||
|
},
|
||||||
|
"messages": {
|
||||||
|
"confirmEviction": "Do you really want to initiate an eviction lawsuit from this tenancy?",
|
||||||
|
"evictionCreated": "Eviction lawsuit has been created successfully",
|
||||||
|
"evictionError": "Error creating eviction lawsuit",
|
||||||
|
"confirmRentCollection": "Do you really want to initiate rent collection from this tenancy?",
|
||||||
|
"rentCollectionCreated": "Rent collection has been created successfully",
|
||||||
|
"rentCollectionError": "Error creating rent collection"
|
||||||
},
|
},
|
||||||
"options": {
|
"options": {
|
||||||
"status": {
|
"status": {
|
||||||
|
|||||||
@@ -5,22 +5,6 @@
|
|||||||
],
|
],
|
||||||
"color": "#dea185",
|
"color": "#dea185",
|
||||||
"iconClass": "fas fa-house",
|
"iconClass": "fas fa-house",
|
||||||
"menu": {
|
|
||||||
"detail": {
|
|
||||||
"buttons": [
|
|
||||||
{
|
|
||||||
"label": "Räumungsklage einleiten",
|
|
||||||
"name": "initiateEviction",
|
|
||||||
"iconHtml": "<span class=\"fas fa-gavel fa-sm\"></span>",
|
|
||||||
"style": "danger",
|
|
||||||
"acl": "edit",
|
|
||||||
"handler": "custom:handlers/mietobjekt/eviction-action",
|
|
||||||
"initFunction": "initEvictionAction",
|
|
||||||
"actionFunction": "initiateEviction"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"relationshipPanels": {
|
"relationshipPanels": {
|
||||||
"vmhMietverhltnises2Mietobjekt": {
|
"vmhMietverhltnises2Mietobjekt": {
|
||||||
"layout": null,
|
"layout": null,
|
||||||
|
|||||||
@@ -3,6 +3,32 @@
|
|||||||
"boolFilterList": [
|
"boolFilterList": [
|
||||||
"onlyMy"
|
"onlyMy"
|
||||||
],
|
],
|
||||||
|
"menu": {
|
||||||
|
"detail": {
|
||||||
|
"buttons": [
|
||||||
|
{
|
||||||
|
"name": "initiateEviction",
|
||||||
|
"label": "Initiate Eviction",
|
||||||
|
"handler": "custom:handlers/mietverhaeltnis/eviction-action",
|
||||||
|
"initFunction": "initInitiateEviction",
|
||||||
|
"actionFunction": "actionInitiateEviction",
|
||||||
|
"iconHtml": "<span class=\"fas fa-gavel\"></span>",
|
||||||
|
"style": "danger",
|
||||||
|
"acl": "edit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "initiateRentCollection",
|
||||||
|
"label": "Initiate Rent Collection",
|
||||||
|
"handler": "custom:handlers/mietverhaeltnis/rent-collection-action",
|
||||||
|
"initFunction": "initInitiateRentCollection",
|
||||||
|
"actionFunction": "actionInitiateRentCollection",
|
||||||
|
"iconHtml": "<span class=\"fas fa-euro-sign\"></span>",
|
||||||
|
"style": "warning",
|
||||||
|
"acl": "edit"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"sidePanels": {
|
"sidePanels": {
|
||||||
"detail": [
|
"detail": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,132 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Espo\Custom\Services;
|
|
||||||
|
|
||||||
use Espo\Core\Exceptions\Forbidden;
|
|
||||||
use Espo\Core\Exceptions\NotFound;
|
|
||||||
use Espo\ORM\Entity;
|
|
||||||
|
|
||||||
class CMietobjekt extends \Espo\Services\Record
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Initiate eviction lawsuit (Räumungsklage) from Mietobjekt
|
|
||||||
*
|
|
||||||
* @param string $mietobjektId
|
|
||||||
* @return array
|
|
||||||
* @throws NotFound
|
|
||||||
* @throws Forbidden
|
|
||||||
*/
|
|
||||||
public function initiateEviction(string $mietobjektId): array
|
|
||||||
{
|
|
||||||
// Load Mietobjekt
|
|
||||||
$mietobjekt = $this->entityManager->getEntity('CMietobjekt', $mietobjektId);
|
|
||||||
if (!$mietobjekt) {
|
|
||||||
throw new NotFound('Mietobjekt not found');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check ACL - Read and Create permissions
|
|
||||||
if (!$this->acl->check($mietobjekt, 'read')) {
|
|
||||||
throw new Forbidden('No read access to Mietobjekt');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$this->acl->checkScope('CVmhRumungsklage', 'create')) {
|
|
||||||
throw new Forbidden('No create access to Räumungsklage');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start transaction to ensure atomicity
|
|
||||||
$this->entityManager->getTransactionManager()->start();
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Prepare data for new Räumungsklage
|
|
||||||
$data = new \stdClass();
|
|
||||||
$data->name = 'Räumungsklage - ' . $mietobjekt->get('name');
|
|
||||||
|
|
||||||
// Copy assignedUser and teams
|
|
||||||
if ($mietobjekt->get('assignedUserId')) {
|
|
||||||
$data->assignedUserId = $mietobjekt->get('assignedUserId');
|
|
||||||
}
|
|
||||||
|
|
||||||
$teamsIds = $mietobjekt->getLinkMultipleIdList('teams');
|
|
||||||
if (!empty($teamsIds)) {
|
|
||||||
$data->teamsIds = $teamsIds;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create Räumungsklage entity
|
|
||||||
$raeumungsklage = $this->entityManager->createEntity('CVmhRumungsklage', (array)$data);
|
|
||||||
|
|
||||||
if (!$raeumungsklage) {
|
|
||||||
throw new \RuntimeException('Failed to create Räumungsklage');
|
|
||||||
}
|
|
||||||
|
|
||||||
$raeumungsklagenRepo = $this->entityManager->getRepository('CVmhRumungsklage');
|
|
||||||
|
|
||||||
// Link Mietobjekt to Räumungsklage
|
|
||||||
$raeumungsklagenRepo
|
|
||||||
->getRelation($raeumungsklage, 'mietobjekte')
|
|
||||||
->relate($mietobjekt);
|
|
||||||
|
|
||||||
// Get and link Mietverhältnisse
|
|
||||||
$mietverhaeltnisse = $this->entityManager
|
|
||||||
->getRepository('CMietobjekt')
|
|
||||||
->getRelation($mietobjekt, 'vmhMietverhltnises')
|
|
||||||
->find();
|
|
||||||
|
|
||||||
foreach ($mietverhaeltnisse as $mietverhaeltnis) {
|
|
||||||
// Link Mietverhältnis to Räumungsklage
|
|
||||||
$raeumungsklagenRepo
|
|
||||||
->getRelation($raeumungsklage, 'vmhMietverhltnises')
|
|
||||||
->relate($mietverhaeltnis);
|
|
||||||
|
|
||||||
// Get Vermieter (Kläger) from Mietverhältnis
|
|
||||||
$vermieterBeteiligte = $this->entityManager
|
|
||||||
->getRepository('CVmhMietverhltnis')
|
|
||||||
->getRelation($mietverhaeltnis, 'vmhbeteiligtevermieter')
|
|
||||||
->find();
|
|
||||||
|
|
||||||
foreach ($vermieterBeteiligte as $vermieter) {
|
|
||||||
// Link as Kläger
|
|
||||||
$raeumungsklagenRepo
|
|
||||||
->getRelation($raeumungsklage, 'klaeger')
|
|
||||||
->relate($vermieter);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get Mieter (Beklagte) from Mietverhältnis
|
|
||||||
$mieterBeteiligte = $this->entityManager
|
|
||||||
->getRepository('CVmhMietverhltnis')
|
|
||||||
->getRelation($mietverhaeltnis, 'vmhbeteiligtemieter')
|
|
||||||
->find();
|
|
||||||
|
|
||||||
foreach ($mieterBeteiligte as $mieter) {
|
|
||||||
// Link as Beklagte
|
|
||||||
$raeumungsklagenRepo
|
|
||||||
->getRelation($raeumungsklage, 'beklagte')
|
|
||||||
->relate($mieter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy portal contacts from Mietobjekt
|
|
||||||
$portalContacts = $this->entityManager
|
|
||||||
->getRepository('CMietobjekt')
|
|
||||||
->getRelation($mietobjekt, 'contactsMietobjekt')
|
|
||||||
->find();
|
|
||||||
|
|
||||||
foreach ($portalContacts as $contact) {
|
|
||||||
$raeumungsklagenRepo
|
|
||||||
->getRelation($raeumungsklage, 'contactsRumungsklage')
|
|
||||||
->relate($contact);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Commit transaction
|
|
||||||
$this->entityManager->getTransactionManager()->commit();
|
|
||||||
|
|
||||||
return [
|
|
||||||
'id' => $raeumungsklage->getId(),
|
|
||||||
'name' => $raeumungsklage->get('name')
|
|
||||||
];
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
// Rollback on any error
|
|
||||||
$this->entityManager->getTransactionManager()->rollback();
|
|
||||||
throw $e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
371
custom/Espo/Custom/Services/CVmhMietverhltnis.php
Normal file
371
custom/Espo/Custom/Services/CVmhMietverhltnis.php
Normal file
@@ -0,0 +1,371 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Espo\Custom\Services;
|
||||||
|
|
||||||
|
use Espo\Core\Exceptions\Forbidden;
|
||||||
|
use Espo\Core\Exceptions\NotFound;
|
||||||
|
|
||||||
|
class CVmhMietverhltnis extends \Espo\Services\Record
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Initiate eviction lawsuit (Räumungsklage) from Mietverhältnis
|
||||||
|
*
|
||||||
|
* @param string $mietverhaeltnisId
|
||||||
|
* @return array
|
||||||
|
* @throws NotFound
|
||||||
|
* @throws Forbidden
|
||||||
|
*/
|
||||||
|
public function initiateEviction(string $mietverhaeltnisId): array
|
||||||
|
{
|
||||||
|
// 1. Load Mietverhältnis
|
||||||
|
$mietverhaeltnis = $this->entityManager->getEntity('CVmhMietverhltnis', $mietverhaeltnisId);
|
||||||
|
if (!$mietverhaeltnis) {
|
||||||
|
throw new NotFound('Mietverhältnis not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. ACL Checks
|
||||||
|
if (!$this->acl->check($mietverhaeltnis, 'read')) {
|
||||||
|
throw new Forbidden('No read access to Mietverhältnis');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->acl->checkScope('CVmhRumungsklage', 'create')) {
|
||||||
|
throw new Forbidden('No create access to Räumungsklage');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Start Transaction
|
||||||
|
$this->entityManager->getTransactionManager()->start();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 4. Prepare data for new Räumungsklage
|
||||||
|
$data = new \stdClass();
|
||||||
|
$data->name = 'Räumungsklage - ' . $mietverhaeltnis->get('name');
|
||||||
|
|
||||||
|
// Copy assignedUser and teams
|
||||||
|
if ($mietverhaeltnis->get('assignedUserId')) {
|
||||||
|
$data->assignedUserId = $mietverhaeltnis->get('assignedUserId');
|
||||||
|
}
|
||||||
|
|
||||||
|
$teamsIds = $mietverhaeltnis->getLinkMultipleIdList('teams');
|
||||||
|
if (!empty($teamsIds)) {
|
||||||
|
$data->teamsIds = $teamsIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. Create Räumungsklage entity
|
||||||
|
$raeumungsklage = $this->entityManager->createEntity('CVmhRumungsklage', (array)$data);
|
||||||
|
|
||||||
|
if (!$raeumungsklage) {
|
||||||
|
throw new \RuntimeException('Failed to create Räumungsklage');
|
||||||
|
}
|
||||||
|
|
||||||
|
$raeumungsklagenRepo = $this->entityManager->getRepository('CVmhRumungsklage');
|
||||||
|
|
||||||
|
// 6. Link Mietverhältnis to Räumungsklage
|
||||||
|
$raeumungsklagenRepo
|
||||||
|
->getRelation($raeumungsklage, 'vmhMietverhltnises')
|
||||||
|
->relate($mietverhaeltnis);
|
||||||
|
|
||||||
|
// 7. Get and link Mietobjekt
|
||||||
|
$mietobjekt = $this->entityManager
|
||||||
|
->getRepository('CVmhMietverhltnis')
|
||||||
|
->getRelation($mietverhaeltnis, 'vmhMietobjekt')
|
||||||
|
->findOne();
|
||||||
|
|
||||||
|
if ($mietobjekt) {
|
||||||
|
$raeumungsklagenRepo
|
||||||
|
->getRelation($raeumungsklage, 'mietobjekte')
|
||||||
|
->relate($mietobjekt);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 8. Get Vermieter (Kläger) from Mietverhältnis
|
||||||
|
$vermieterBeteiligte = $this->entityManager
|
||||||
|
->getRepository('CVmhMietverhltnis')
|
||||||
|
->getRelation($mietverhaeltnis, 'vmhbeteiligtevermieter')
|
||||||
|
->find();
|
||||||
|
|
||||||
|
foreach ($vermieterBeteiligte as $vermieter) {
|
||||||
|
// Link as Kläger
|
||||||
|
$raeumungsklagenRepo
|
||||||
|
->getRelation($raeumungsklage, 'klaeger')
|
||||||
|
->relate($vermieter);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 9. Get Mieter (Beklagte) from Mietverhältnis
|
||||||
|
$mieterBeteiligte = $this->entityManager
|
||||||
|
->getRepository('CVmhMietverhltnis')
|
||||||
|
->getRelation($mietverhaeltnis, 'vmhbeteiligtemieter')
|
||||||
|
->find();
|
||||||
|
|
||||||
|
foreach ($mieterBeteiligte as $mieter) {
|
||||||
|
// Link as Beklagte
|
||||||
|
$raeumungsklagenRepo
|
||||||
|
->getRelation($raeumungsklage, 'beklagte')
|
||||||
|
->relate($mieter);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 9b. Get Sonstige Bewohner (auch Beklagte) from Mietverhältnis
|
||||||
|
$sonstigeBewohner = $this->entityManager
|
||||||
|
->getRepository('CVmhMietverhltnis')
|
||||||
|
->getRelation($mietverhaeltnis, 'sonstigebesitzervmhmietverhltnis')
|
||||||
|
->find();
|
||||||
|
|
||||||
|
foreach ($sonstigeBewohner as $bewohner) {
|
||||||
|
// Link as Beklagte
|
||||||
|
$raeumungsklagenRepo
|
||||||
|
->getRelation($raeumungsklage, 'beklagte')
|
||||||
|
->relate($bewohner);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 10. Copy all documents from Mietverhältnis, Mietobjekt and Beteiligte
|
||||||
|
// 10a. Dokumente vom Mietverhältnis
|
||||||
|
$dokumenteMV = $this->entityManager
|
||||||
|
->getRepository('CVmhMietverhltnis')
|
||||||
|
->getRelation($mietverhaeltnis, 'dokumentesvmhMietverhltnisse')
|
||||||
|
->find();
|
||||||
|
|
||||||
|
foreach ($dokumenteMV as $dokument) {
|
||||||
|
$raeumungsklagenRepo
|
||||||
|
->getRelation($raeumungsklage, 'dokumentesvmhraumungsklage')
|
||||||
|
->relate($dokument);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 10b. Dokumente vom Mietobjekt
|
||||||
|
if ($mietobjekt) {
|
||||||
|
$dokumenteMO = $this->entityManager
|
||||||
|
->getRepository('CMietobjekt')
|
||||||
|
->getRelation($mietobjekt, 'dokumentesMietobjekt')
|
||||||
|
->find();
|
||||||
|
|
||||||
|
foreach ($dokumenteMO as $dokument) {
|
||||||
|
$raeumungsklagenRepo
|
||||||
|
->getRelation($raeumungsklage, 'dokumentesvmhraumungsklage')
|
||||||
|
->relate($dokument);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 10c. Dokumente von allen Beteiligten (Vermieter + Mieter + Sonstige)
|
||||||
|
$alleBeteiligte = array_merge(
|
||||||
|
iterator_to_array($vermieterBeteiligte),
|
||||||
|
iterator_to_array($mieterBeteiligte),
|
||||||
|
iterator_to_array($sonstigeBewohner)
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($alleBeteiligte as $beteiligter) {
|
||||||
|
$dokumenteBet = $this->entityManager
|
||||||
|
->getRepository('CBeteiligte')
|
||||||
|
->getRelation($beteiligter, 'dokumentesBeteiligte')
|
||||||
|
->find();
|
||||||
|
|
||||||
|
foreach ($dokumenteBet as $dokument) {
|
||||||
|
$raeumungsklagenRepo
|
||||||
|
->getRelation($raeumungsklage, 'dokumentesvmhraumungsklage')
|
||||||
|
->relate($dokument);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 11. Copy portal contacts from Mietverhältnis (nur vom Mietverhältnis!)
|
||||||
|
$portalContacts = $this->entityManager
|
||||||
|
->getRepository('CVmhMietverhltnis')
|
||||||
|
->getRelation($mietverhaeltnis, 'contactsMietverhltnis')
|
||||||
|
->find();
|
||||||
|
|
||||||
|
foreach ($portalContacts as $contact) {
|
||||||
|
$raeumungsklagenRepo
|
||||||
|
->getRelation($raeumungsklage, 'contactsRumungsklage')
|
||||||
|
->relate($contact);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 12. Commit transaction
|
||||||
|
$this->entityManager->getTransactionManager()->commit();
|
||||||
|
|
||||||
|
return [
|
||||||
|
'id' => $raeumungsklage->getId(),
|
||||||
|
'name' => $raeumungsklage->get('name')
|
||||||
|
];
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
// Rollback on any error
|
||||||
|
$this->entityManager->getTransactionManager()->rollback();
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initiate rent collection (Mietinkasso) from Mietverhältnis
|
||||||
|
*
|
||||||
|
* @param string $mietverhaeltnisId
|
||||||
|
* @return array
|
||||||
|
* @throws NotFound
|
||||||
|
* @throws Forbidden
|
||||||
|
*/
|
||||||
|
public function initiateRentCollection(string $mietverhaeltnisId): array
|
||||||
|
{
|
||||||
|
// 1. Load Mietverhältnis
|
||||||
|
$mietverhaeltnis = $this->entityManager->getEntity('CVmhMietverhltnis', $mietverhaeltnisId);
|
||||||
|
if (!$mietverhaeltnis) {
|
||||||
|
throw new NotFound('Mietverhältnis not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. ACL Checks
|
||||||
|
if (!$this->acl->check($mietverhaeltnis, 'read')) {
|
||||||
|
throw new Forbidden('No read access to Mietverhältnis');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->acl->checkScope('CMietinkasso', 'create')) {
|
||||||
|
throw new Forbidden('No create access to Mietinkasso');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Start Transaction
|
||||||
|
$this->entityManager->getTransactionManager()->start();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 4. Prepare data for new Mietinkasso
|
||||||
|
$data = new \stdClass();
|
||||||
|
$data->name = 'Mietinkasso - ' . $mietverhaeltnis->get('name');
|
||||||
|
|
||||||
|
// Copy assignedUser and teams
|
||||||
|
if ($mietverhaeltnis->get('assignedUserId')) {
|
||||||
|
$data->assignedUserId = $mietverhaeltnis->get('assignedUserId');
|
||||||
|
}
|
||||||
|
|
||||||
|
$teamsIds = $mietverhaeltnis->getLinkMultipleIdList('teams');
|
||||||
|
if (!empty($teamsIds)) {
|
||||||
|
$data->teamsIds = $teamsIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. Create Mietinkasso entity
|
||||||
|
$mietinkasso = $this->entityManager->createEntity('CMietinkasso', (array)$data);
|
||||||
|
|
||||||
|
if (!$mietinkasso) {
|
||||||
|
throw new \RuntimeException('Failed to create Mietinkasso');
|
||||||
|
}
|
||||||
|
|
||||||
|
$mietinkassoRepo = $this->entityManager->getRepository('CMietinkasso');
|
||||||
|
|
||||||
|
// 6. Link Mietverhältnis to Mietinkasso
|
||||||
|
$mietinkassoRepo
|
||||||
|
->getRelation($mietinkasso, 'vmhMietverhltnises')
|
||||||
|
->relate($mietverhaeltnis);
|
||||||
|
|
||||||
|
// 7. Get and link Mietobjekt
|
||||||
|
$mietobjekt = $this->entityManager
|
||||||
|
->getRepository('CVmhMietverhltnis')
|
||||||
|
->getRelation($mietverhaeltnis, 'vmhMietobjekt')
|
||||||
|
->findOne();
|
||||||
|
|
||||||
|
if ($mietobjekt) {
|
||||||
|
$mietinkassoRepo
|
||||||
|
->getRelation($mietinkasso, 'mietobjekte')
|
||||||
|
->relate($mietobjekt);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 8. Get Vermieter (Kläger) from Mietverhältnis
|
||||||
|
$vermieterBeteiligte = $this->entityManager
|
||||||
|
->getRepository('CVmhMietverhltnis')
|
||||||
|
->getRelation($mietverhaeltnis, 'vmhbeteiligtevermieter')
|
||||||
|
->find();
|
||||||
|
|
||||||
|
foreach ($vermieterBeteiligte as $vermieter) {
|
||||||
|
// Link as Kläger
|
||||||
|
$mietinkassoRepo
|
||||||
|
->getRelation($mietinkasso, 'klaeger')
|
||||||
|
->relate($vermieter);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 9. Get Mieter (Beklagte) from Mietverhältnis
|
||||||
|
$mieterBeteiligte = $this->entityManager
|
||||||
|
->getRepository('CVmhMietverhltnis')
|
||||||
|
->getRelation($mietverhaeltnis, 'vmhbeteiligtemieter')
|
||||||
|
->find();
|
||||||
|
|
||||||
|
foreach ($mieterBeteiligte as $mieter) {
|
||||||
|
// Link as Beklagte
|
||||||
|
$mietinkassoRepo
|
||||||
|
->getRelation($mietinkasso, 'beklagte')
|
||||||
|
->relate($mieter);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 9b. Get Sonstige Bewohner (auch Beklagte) from Mietverhältnis
|
||||||
|
$sonstigeBewohner = $this->entityManager
|
||||||
|
->getRepository('CVmhMietverhltnis')
|
||||||
|
->getRelation($mietverhaeltnis, 'sonstigebesitzervmhmietverhltnis')
|
||||||
|
->find();
|
||||||
|
|
||||||
|
foreach ($sonstigeBewohner as $bewohner) {
|
||||||
|
// Link as Beklagte
|
||||||
|
$mietinkassoRepo
|
||||||
|
->getRelation($mietinkasso, 'beklagte')
|
||||||
|
->relate($bewohner);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 10. Copy all documents from Mietverhältnis, Mietobjekt and Beteiligte
|
||||||
|
// 10a. Dokumente vom Mietverhältnis
|
||||||
|
$dokumenteMV = $this->entityManager
|
||||||
|
->getRepository('CVmhMietverhltnis')
|
||||||
|
->getRelation($mietverhaeltnis, 'dokumentesvmhMietverhltnisse')
|
||||||
|
->find();
|
||||||
|
|
||||||
|
foreach ($dokumenteMV as $dokument) {
|
||||||
|
$mietinkassoRepo
|
||||||
|
->getRelation($mietinkasso, 'dokumentesmietinkasso')
|
||||||
|
->relate($dokument);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 10b. Dokumente vom Mietobjekt
|
||||||
|
if ($mietobjekt) {
|
||||||
|
$dokumenteMO = $this->entityManager
|
||||||
|
->getRepository('CMietobjekt')
|
||||||
|
->getRelation($mietobjekt, 'dokumentesMietobjekt')
|
||||||
|
->find();
|
||||||
|
|
||||||
|
foreach ($dokumenteMO as $dokument) {
|
||||||
|
$mietinkassoRepo
|
||||||
|
->getRelation($mietinkasso, 'dokumentesmietinkasso')
|
||||||
|
->relate($dokument);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 10c. Dokumente von allen Beteiligten (Vermieter + Mieter + Sonstige)
|
||||||
|
$alleBeteiligte = array_merge(
|
||||||
|
iterator_to_array($vermieterBeteiligte),
|
||||||
|
iterator_to_array($mieterBeteiligte),
|
||||||
|
iterator_to_array($sonstigeBewohner)
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($alleBeteiligte as $beteiligter) {
|
||||||
|
$dokumenteBet = $this->entityManager
|
||||||
|
->getRepository('CBeteiligte')
|
||||||
|
->getRelation($beteiligter, 'dokumentesBeteiligte')
|
||||||
|
->find();
|
||||||
|
|
||||||
|
foreach ($dokumenteBet as $dokument) {
|
||||||
|
$mietinkassoRepo
|
||||||
|
->getRelation($mietinkasso, 'dokumentesmietinkasso')
|
||||||
|
->relate($dokument);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 11. Copy portal contacts from Mietverhältnis (nur vom Mietverhältnis!)
|
||||||
|
$portalContacts = $this->entityManager
|
||||||
|
->getRepository('CVmhMietverhltnis')
|
||||||
|
->getRelation($mietverhaeltnis, 'contactsMietverhltnis')
|
||||||
|
->find();
|
||||||
|
|
||||||
|
foreach ($portalContacts as $contact) {
|
||||||
|
$mietinkassoRepo
|
||||||
|
->getRelation($mietinkasso, 'contactsMietinkasso')
|
||||||
|
->relate($contact);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 12. Commit transaction
|
||||||
|
$this->entityManager->getTransactionManager()->commit();
|
||||||
|
|
||||||
|
return [
|
||||||
|
'id' => $mietinkasso->getId(),
|
||||||
|
'name' => $mietinkasso->get('name')
|
||||||
|
];
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
// Rollback on any error
|
||||||
|
$this->entityManager->getTransactionManager()->rollback();
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -359,8 +359,8 @@ return [
|
|||||||
0 => 'youtube.com',
|
0 => 'youtube.com',
|
||||||
1 => 'google.com'
|
1 => 'google.com'
|
||||||
],
|
],
|
||||||
'cacheTimestamp' => 1769252191,
|
'cacheTimestamp' => 1769253751,
|
||||||
'microtime' => 1769252191.810945,
|
'microtime' => 1769253751.94842,
|
||||||
'siteUrl' => 'https://crm.bitbylaw.com',
|
'siteUrl' => 'https://crm.bitbylaw.com',
|
||||||
'fullTextSearchMinLength' => 4,
|
'fullTextSearchMinLength' => 4,
|
||||||
'appTimestamp' => 1768843902,
|
'appTimestamp' => 1768843902,
|
||||||
|
|||||||
Reference in New Issue
Block a user