diff --git a/custom/Espo/Custom/Controllers/CVmhMietverhltnis.php b/custom/Espo/Custom/Controllers/CVmhMietverhltnis.php
index 78b1a241..36adbe88 100644
--- a/custom/Espo/Custom/Controllers/CVmhMietverhltnis.php
+++ b/custom/Espo/Custom/Controllers/CVmhMietverhltnis.php
@@ -42,4 +42,22 @@ class CVmhMietverhltnis extends \Espo\Core\Templates\Controllers\BasePlus
return $result;
}
+
+ /**
+ * POST Action: Initiate termination (Kündigung) from Mietverhältnis
+ */
+ public function postActionInitiateTermination(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->initiateTermination($id);
+
+ return $result;
+ }
}
diff --git a/custom/Espo/Custom/Resources/i18n/de_DE/CBeteiligte.json b/custom/Espo/Custom/Resources/i18n/de_DE/CBeteiligte.json
index 559d2481..ed853e77 100644
--- a/custom/Espo/Custom/Resources/i18n/de_DE/CBeteiligte.json
+++ b/custom/Espo/Custom/Resources/i18n/de_DE/CBeteiligte.json
@@ -12,6 +12,8 @@
"vmhRumungsklagesBeklagte": "Beklagte",
"mietinkassosKlaeger": "Mietinkasso (Kläger)",
"mietinkassosBeklagte": "Mietinkasso (Beklagte)",
+ "kndigungenKuendiger": "Kündigungen (Kündigende)",
+ "kndigungenGekuendigte": "Kündigungen (Gekündigte)",
"adressens": "Adressen",
"calls1": "Anrufe",
"contactsBeteiligte": "Freigegebene Nutzer",
@@ -33,6 +35,8 @@
"vmhRumungsklagesBeklagte": "Beklagte",
"mietinkassosKlaeger": "Mietinkasso (Kläger)",
"mietinkassosBeklagte": "Mietinkasso (Beklagte)",
+ "kndigungenKuendiger": "Kündigungen (Kündigende)",
+ "kndigungenGekuendigte": "Kündigungen (Gekündigte)",
"adressens": "Adressen",
"calls1": "Anrufe",
"contactsBeteiligte": "Freigegebene Nutzer",
diff --git a/custom/Espo/Custom/Resources/i18n/de_DE/CDokumente.json b/custom/Espo/Custom/Resources/i18n/de_DE/CDokumente.json
index 8484ef7a..3650c189 100644
--- a/custom/Espo/Custom/Resources/i18n/de_DE/CDokumente.json
+++ b/custom/Espo/Custom/Resources/i18n/de_DE/CDokumente.json
@@ -13,7 +13,9 @@
"vmhErstgespraechsdokumente": "Erstgespräche",
"vmhRumungsklagesdokumente": "Räumungsklagen",
"beteiligte2dokumente": "Beteiligte",
- "mietobjekt2dokumente": "Mietobjekte"
+ "mietobjekt2dokumente": "Mietobjekte",
+ "mietinkassosdokumente": "Mietinkasso",
+ "kndigungensdokumente": "Kündigungen"
},
"links": {
"contactsvmhdokumente": "Freigegebene Nutzer",
@@ -22,7 +24,8 @@
"vmhRumungsklagesdokumente": "Räumungsklagen",
"beteiligte2dokumente": "Beteiligte",
"mietobjekt2dokumente": "Mietobjekte",
- "mietinkassosdokumente": "Mietinkasso"
+ "mietinkassosdokumente": "Mietinkasso",
+ "kndigungensdokumente": "Kündigungen"
},
"labels": {
"Create CDokumente": "Dokument erstellen"
diff --git a/custom/Espo/Custom/Resources/i18n/de_DE/CKndigung.json b/custom/Espo/Custom/Resources/i18n/de_DE/CKndigung.json
index 01a25372..adca8af6 100644
--- a/custom/Espo/Custom/Resources/i18n/de_DE/CKndigung.json
+++ b/custom/Espo/Custom/Resources/i18n/de_DE/CKndigung.json
@@ -1,9 +1,94 @@
{
"links": {
+ "meetings": "Termine",
"calls": "Anrufe",
- "tasks": "Aufgaben"
+ "tasks": "Aufgaben",
+ "collaborators": "Mitarbeiter",
+ "vmhMietverhltnises": "Mietverhältnisse",
+ "mietobjekte": "Mietobjekte",
+ "kuendiger": "Kündigende (Vermieter)",
+ "gekuendigte": "Gekündigte (Mieter)",
+ "dokumenteskuendigung": "Dokumente",
+ "contactsKuendigung": "Portal-Freigaben"
},
"labels": {
- "Create CKndigung": "Kündigung erstellen"
+ "Create CKndigung": "Kündigung erstellen",
+ "CKndigung": "Kündigung"
+ },
+ "fields": {
+ "name": "Name",
+ "description": "Beschreibung",
+ "assignedUser": "Zugewiesen",
+ "teams": "Teams",
+ "createdAt": "Erstellt am",
+ "modifiedAt": "Geändert am",
+ "createdBy": "Erstellt von",
+ "modifiedBy": "Geändert von",
+ "freigeschalteteNutzer": "Freigeschaltete Nutzer",
+ "collaborators": "Mitarbeiter",
+ "advowareAktenzeichen": "Advoware Aktenzeichen",
+ "betnr": "Betreuernummer",
+ "advowareLastSync": "Letzter Sync",
+ "syncStatus": "Sync Status",
+ "kuendigungsart": "Kündigungsart",
+ "kuendigungsgrund": "Kündigungsgrund",
+ "kuendigungsgrundDetails": "Kündigungsgrund Details",
+ "kuendigungsdatum": "Kündigungsdatum",
+ "zustelldatum": "Zustelldatum",
+ "kuendigungsfrist": "Kündigungsfrist",
+ "beendigungstermin": "Beendigungstermin",
+ "status": "Status",
+ "zustellart": "Zustellart",
+ "reaktionMieter": "Reaktion Mieter",
+ "notizen": "Notizen",
+ "rueckstandMiete": "Rückstand Miete",
+ "rueckstandNebenkosten": "Rückstand Nebenkosten",
+ "sonstigeForderungen": "Sonstige Forderungen",
+ "aussergerichtlicheGebuehren13": "Außergerichtliche Gebühren (1,3)"
+ },
+ "options": {
+ "kuendigungsart": {
+ "Ordentlich": "Ordentlich",
+ "Ausserordentlich": "Außerordentlich",
+ "Fristlos": "Fristlos",
+ "AufgabeerklärungMieter": "Aufgabeerklärung Mieter"
+ },
+ "kuendigungsgrund": {
+ "Zahlungsverzug": "Zahlungsverzug",
+ "Pflichtverletzung": "Pflichtverletzung",
+ "Eigenbedarf": "Eigenbedarf",
+ "Verwertung": "Verwertung",
+ "VerhaltensbedingteLaermruhestoerung": "Verhaltensbedingte Lärm-/Ruhestörung",
+ "BeschaedigungSubstanz": "Beschädigung der Substanz",
+ "UnerlaubteUntervermietung": "Unerlaubte Untervermietung",
+ "StoerendeGeschaeftsfuehrung": "Störende Geschäftsführung",
+ "Sonstiges": "Sonstiges"
+ },
+ "status": {
+ "Entwurf": "Entwurf",
+ "Versendet": "Versendet",
+ "Zugestellt": "Zugestellt",
+ "Akzeptiert": "Akzeptiert",
+ "Bestritten": "Bestritten",
+ "Abgewickelt": "Abgewickelt",
+ "Zurückgezogen": "Zurückgezogen"
+ },
+ "zustellart": {
+ "Einschreiben": "Einschreiben",
+ "Persoenlich": "Persönlich",
+ "Gerichtsvollzieher": "Gerichtsvollzieher",
+ "Oeffentlich": "Öffentlich",
+ "Sonstiges": "Sonstiges"
+ },
+ "syncStatus": {
+ "clean": "Synchronisiert",
+ "unclean": "Änderungen ausstehend",
+ "failed": "Fehler"
+ }
+ },
+ "tooltips": {
+ "advowareAktenzeichen": "Aktenzeichen aus Advoware für die Synchronisation",
+ "betnr": "Betreuernummer aus Advoware",
+ "syncStatus": "Status der Synchronisation mit Advoware"
}
}
\ No newline at end of file
diff --git a/custom/Espo/Custom/Resources/i18n/de_DE/CMietobjekt.json b/custom/Espo/Custom/Resources/i18n/de_DE/CMietobjekt.json
index 9638c128..b9d58133 100644
--- a/custom/Espo/Custom/Resources/i18n/de_DE/CMietobjekt.json
+++ b/custom/Espo/Custom/Resources/i18n/de_DE/CMietobjekt.json
@@ -14,6 +14,7 @@
"contact2mietobjekt": "Kontakte",
"vmhRumungsklages": "Räumungsklagen",
"mietinkassos": "Mietinkasso",
+ "kndigungen": "Kündigungen",
"contactsMietobjekt": "Freigegebene Nutzer",
"dokumentesMietobjekt": "Dokumente"
},
diff --git a/custom/Espo/Custom/Resources/i18n/de_DE/CVmhMietverhltnis.json b/custom/Espo/Custom/Resources/i18n/de_DE/CVmhMietverhltnis.json
index b95acc7a..b4eccee8 100644
--- a/custom/Espo/Custom/Resources/i18n/de_DE/CVmhMietverhltnis.json
+++ b/custom/Espo/Custom/Resources/i18n/de_DE/CVmhMietverhltnis.json
@@ -13,6 +13,7 @@
"warmmiete": "Warmmiete",
"vmhRumungsklages": "Räumungsklagen",
"mietinkassos": "Mietinkasso",
+ "kndigungen": "Kündigungen",
"vmhbeteiligtevermieter": "Vermieter",
"vmhbeteiligtemieter": "Mieter",
"contactsMietverhltnis": "Freigegebene Nutzer",
@@ -33,6 +34,7 @@
"tasks": "Aufgaben",
"vmhRumungsklages": "Räumungsklagen",
"mietinkassos": "Mietinkasso",
+ "kndigungen": "Kündigungen",
"vmhbeteiligtevermieter": "Vermieter",
"vmhbeteiligtemieter": "Mieter",
"contactsMietverhltnis": "Freigegebene Nutzer",
@@ -44,7 +46,8 @@
"labels": {
"Create CVmhMietverhltnis": "Mietverhältnis erstellen",
"Initiate Eviction": "Räumungsklage einleiten",
- "Initiate Rent Collection": "Mietinkasso einleiten"
+ "Initiate Rent Collection": "Mietinkasso einleiten",
+ "Initiate Termination": "Kündigung erstellen"
},
"messages": {
"confirmEviction": "Möchten Sie wirklich eine Räumungsklage aus diesem Mietverhältnis einleiten?",
@@ -52,6 +55,9 @@
"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"
+ "rentCollectionError": "Fehler beim Erstellen des Mietinkassos",
+ "confirmTermination": "Möchten Sie wirklich eine Kündigung aus diesem Mietverhältnis erstellen?",
+ "terminationCreated": "Kündigung wurde erfolgreich erstellt",
+ "terminationError": "Fehler beim Erstellen der Kündigung"
}
}
\ No newline at end of file
diff --git a/custom/Espo/Custom/Resources/i18n/de_DE/Contact.json b/custom/Espo/Custom/Resources/i18n/de_DE/Contact.json
index ca681698..f0e22e86 100644
--- a/custom/Espo/Custom/Resources/i18n/de_DE/Contact.json
+++ b/custom/Espo/Custom/Resources/i18n/de_DE/Contact.json
@@ -14,6 +14,8 @@
"cMietobjekteContactPortal": "Mietobjekte (Portal)",
"cAdressenContact": "Adressen",
"cVmhRumungsklageContact": "Räumungsklagen (Portal)",
+ "cMietinkassoContact": "Mietinkasso",
+ "cKuendigungContact": "Kündigungen",
"cBankverbindungenContact": "Bankverbindungen"
},
"links": {
@@ -29,6 +31,7 @@
"cAdressenContact": "Adressen",
"cVmhRumungsklageContact": "Räumungsklagen (Portal)",
"cMietinkassoContact": "Mietinkasso",
+ "cKuendigungContact": "Kündigungen",
"cBankverbindungenContact": "Bankverbindungen"
},
"options": {
diff --git a/custom/Espo/Custom/Resources/i18n/en_US/CBeteiligte.json b/custom/Espo/Custom/Resources/i18n/en_US/CBeteiligte.json
index 64018d9c..857943bd 100644
--- a/custom/Espo/Custom/Resources/i18n/en_US/CBeteiligte.json
+++ b/custom/Espo/Custom/Resources/i18n/en_US/CBeteiligte.json
@@ -11,6 +11,8 @@
"vmhRumungsklagesKlaeger": "Plaintiff",
"mietinkassosKlaeger": "Rent Collection (Plaintiff)",
"mietinkassosBeklagte": "Rent Collection (Defendant)",
+ "kndigungenKuendiger": "Terminations (Terminating Party)",
+ "kndigungenGekuendigte": "Terminations (Terminated Party)",
"contactsBeteiligte": "Portal Users",
"dokumentesBeteiligte": "Documents"
},
@@ -27,6 +29,8 @@
"vmhRumungsklagesKlaeger": "Plaintiff",
"mietinkassosKlaeger": "Rent Collection (Plaintiff)",
"mietinkassosBeklagte": "Rent Collection (Defendant)",
+ "kndigungenKuendiger": "Terminations (Terminating Party)",
+ "kndigungenGekuendigte": "Terminations (Terminated Party)",
"contactsBeteiligte": "Portal Users",
"dokumentesBeteiligte": "Documents",
"bankverbindungens": "Bank Accounts"
diff --git a/custom/Espo/Custom/Resources/i18n/en_US/CDokumente.json b/custom/Espo/Custom/Resources/i18n/en_US/CDokumente.json
index 03d224db..db20161c 100644
--- a/custom/Espo/Custom/Resources/i18n/en_US/CDokumente.json
+++ b/custom/Espo/Custom/Resources/i18n/en_US/CDokumente.json
@@ -10,7 +10,9 @@
"md5sum": "MD5 Checksum",
"sha256": "SHA256 Checksum",
"beteiligte2dokumente": "Parties",
- "mietobjekt2dokumente": "Properties"
+ "mietobjekt2dokumente": "Properties",
+ "mietinkassosdokumente": "Rent Collection",
+ "kndigungensdokumente": "Terminations"
},
"links": {
"contactsvmhdokumente": "Portal Users",
@@ -19,7 +21,8 @@
"vmhRumungsklagesdokumente": "Eviction Lawsuits",
"beteiligte2dokumente": "Parties",
"mietobjekt2dokumente": "Properties",
- "mietinkassosdokumente": "Rent Collection"
+ "mietinkassosdokumente": "Rent Collection",
+ "kndigungensdokumente": "Terminations"
},
"labels": {
"Create CDokumente": "Create Dokument"
diff --git a/custom/Espo/Custom/Resources/i18n/en_US/CKndigung.json b/custom/Espo/Custom/Resources/i18n/en_US/CKndigung.json
index 9f9079f3..f34c66b9 100644
--- a/custom/Espo/Custom/Resources/i18n/en_US/CKndigung.json
+++ b/custom/Espo/Custom/Resources/i18n/en_US/CKndigung.json
@@ -1,12 +1,94 @@
{
"fields": {
+ "name": "Name",
+ "description": "Description",
+ "assignedUser": "Assigned User",
+ "teams": "Teams",
+ "createdAt": "Created At",
+ "modifiedAt": "Modified At",
+ "createdBy": "Created By",
+ "modifiedBy": "Modified By",
+ "freigeschalteteNutzer": "Authorized Users",
+ "collaborators": "Collaborators",
+ "advowareAktenzeichen": "Advoware File Number",
+ "betnr": "Case Number",
+ "advowareLastSync": "Last Sync",
+ "syncStatus": "Sync Status",
+ "kuendigungsart": "Termination Type",
+ "kuendigungsgrund": "Termination Reason",
+ "kuendigungsgrundDetails": "Termination Reason Details",
+ "kuendigungsdatum": "Termination Date",
+ "zustelldatum": "Delivery Date",
+ "kuendigungsfrist": "Notice Period",
+ "beendigungstermin": "End Date",
+ "status": "Status",
+ "zustellart": "Delivery Method",
+ "reaktionMieter": "Tenant Response",
+ "notizen": "Notes",
+ "rueckstandMiete": "Rent Arrears",
+ "rueckstandNebenkosten": "Utility Arrears",
+ "sonstigeForderungen": "Other Claims",
+ "aussergerichtlicheGebuehren13": "Extrajudicial Fees (1.3)"
},
"links": {
"meetings": "Meetings",
"calls": "Calls",
- "tasks": "Tasks"
+ "tasks": "Tasks",
+ "collaborators": "Collaborators",
+ "vmhMietverhltnises": "Tenancies",
+ "mietobjekte": "Properties",
+ "kuendiger": "Terminating Party (Landlord)",
+ "gekuendigte": "Terminated Party (Tenant)",
+ "dokumenteskuendigung": "Documents",
+ "contactsKuendigung": "Portal Access"
},
"labels": {
- "Create CKndigung": "Create Kündigung"
+ "Create CKndigung": "Create Termination",
+ "CKndigung": "Termination"
+ },
+ "options": {
+ "kuendigungsart": {
+ "Ordentlich": "Regular",
+ "Ausserordentlich": "Extraordinary",
+ "Fristlos": "Immediate",
+ "AufgabeerklärungMieter": "Tenant Surrender"
+ },
+ "kuendigungsgrund": {
+ "Zahlungsverzug": "Payment Default",
+ "Pflichtverletzung": "Breach of Contract",
+ "Eigenbedarf": "Owner's Need",
+ "Verwertung": "Exploitation",
+ "VerhaltensbedingteLaermruhestoerung": "Behavioral - Noise/Disturbance",
+ "BeschaedigungSubstanz": "Property Damage",
+ "UnerlaubteUntervermietung": "Unauthorized Subletting",
+ "StoerendeGeschaeftsfuehrung": "Disruptive Business Operations",
+ "Sonstiges": "Other"
+ },
+ "status": {
+ "Entwurf": "Draft",
+ "Versendet": "Sent",
+ "Zugestellt": "Delivered",
+ "Akzeptiert": "Accepted",
+ "Bestritten": "Disputed",
+ "Abgewickelt": "Settled",
+ "Zurückgezogen": "Withdrawn"
+ },
+ "zustellart": {
+ "Einschreiben": "Registered Mail",
+ "Persoenlich": "Personal Delivery",
+ "Gerichtsvollzieher": "Bailiff",
+ "Oeffentlich": "Public Notice",
+ "Sonstiges": "Other"
+ },
+ "syncStatus": {
+ "clean": "Synchronized",
+ "unclean": "Changes Pending",
+ "failed": "Failed"
+ }
+ },
+ "tooltips": {
+ "advowareAktenzeichen": "File number from Advoware for synchronization",
+ "betnr": "Case number from Advoware",
+ "syncStatus": "Synchronization status with Advoware"
}
}
diff --git a/custom/Espo/Custom/Resources/i18n/en_US/CMietobjekt.json b/custom/Espo/Custom/Resources/i18n/en_US/CMietobjekt.json
index fc630b1c..33210f1a 100644
--- a/custom/Espo/Custom/Resources/i18n/en_US/CMietobjekt.json
+++ b/custom/Espo/Custom/Resources/i18n/en_US/CMietobjekt.json
@@ -20,6 +20,7 @@
"contact2mietobjekt": "Contacts",
"vmhRumungsklages": "Eviction Lawsuits",
"mietinkassos": "Rent Collection",
+ "kndigungen": "Terminations",
"contactsMietobjekt": "Portal Users",
"dokumentesMietobjekt": "Documents"
},
diff --git a/custom/Espo/Custom/Resources/i18n/en_US/CVmhMietverhltnis.json b/custom/Espo/Custom/Resources/i18n/en_US/CVmhMietverhltnis.json
index 9b4b1962..dffabb6e 100644
--- a/custom/Espo/Custom/Resources/i18n/en_US/CVmhMietverhltnis.json
+++ b/custom/Espo/Custom/Resources/i18n/en_US/CVmhMietverhltnis.json
@@ -3,6 +3,7 @@
"status": "Status",
"vmhRumungsklages": "Eviction Lawsuits",
"mietinkassos": "Rent Collection",
+ "kndigungen": "Terminations",
"nutzungsart": "Type of Use",
"kndigungsgrundWohnraum": "Reason for Termination",
"auszugsfrist": "Move-out Deadline",
@@ -36,6 +37,7 @@
"tasks": "Tasks",
"vmhRumungsklages": "Eviction Lawsuits",
"mietinkassos": "Rent Collection",
+ "kndigungen": "Terminations",
"vmhbeteiligtevermieter": "Landlords",
"vmhbeteiligtemieter": "Tenants",
"contactsMietverhltnis": "Portal Users",
@@ -47,7 +49,8 @@
"labels": {
"Create CVmhMietverhltnis": "Create Mietverhältnis",
"Initiate Eviction": "Initiate Eviction Lawsuit",
- "Initiate Rent Collection": "Initiate Rent Collection"
+ "Initiate Rent Collection": "Initiate Rent Collection",
+ "Initiate Termination": "Create Termination"
},
"messages": {
"confirmEviction": "Do you really want to initiate an eviction lawsuit from this tenancy?",
@@ -55,7 +58,10 @@
"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"
+ "rentCollectionError": "Error creating rent collection",
+ "confirmTermination": "Do you really want to create a termination notice from this tenancy?",
+ "terminationCreated": "Termination notice has been created successfully",
+ "terminationError": "Error creating termination notice"
},
"options": {
"status": {
diff --git a/custom/Espo/Custom/Resources/i18n/en_US/Contact.json b/custom/Espo/Custom/Resources/i18n/en_US/Contact.json
index f4ac5932..83229c6f 100644
--- a/custom/Espo/Custom/Resources/i18n/en_US/Contact.json
+++ b/custom/Espo/Custom/Resources/i18n/en_US/Contact.json
@@ -8,7 +8,9 @@
"cVmhVermietersKontaktpersonen": "Vermieter",
"cVmhMietverhltnisesContact": "Mietverhältnisse",
"cDokumentesvmhcontact": "Dokumente",
- "cVmhmietobjekt2contact": "Mietobjekts"
+ "cVmhmietobjekt2contact": "Mietobjekts",
+ "cMietinkassoContact": "Rent Collection",
+ "cKuendigungContact": "Terminations"
},
"links": {
"cVmhRumungsklages": "Räumungsklagen",
@@ -23,6 +25,7 @@
"cAdressenContact": "Addresses",
"cVmhRumungsklageContact": "Eviction Lawsuits (Portal)",
"cMietinkassoContact": "Rent Collection",
+ "cKuendigungContact": "Terminations",
"cBankverbindungenContact": "Bank Accounts"
},
"options": {
diff --git a/custom/Espo/Custom/Resources/metadata/clientDefs/CKndigung.json b/custom/Espo/Custom/Resources/metadata/clientDefs/CKndigung.json
index 0115fec8..4a1513ab 100644
--- a/custom/Espo/Custom/Resources/metadata/clientDefs/CKndigung.json
+++ b/custom/Espo/Custom/Resources/metadata/clientDefs/CKndigung.json
@@ -33,5 +33,31 @@
}
]
},
- "iconClass": "fas fa-circle-stop"
+ "iconClass": "fas fa-file-contract",
+ "relationshipPanels": {
+ "vmhMietverhltnises": {
+ "layout": null,
+ "selectPrimaryFilterName": null
+ },
+ "mietobjekte": {
+ "layout": null,
+ "selectPrimaryFilterName": null
+ },
+ "kuendiger": {
+ "layout": null,
+ "selectPrimaryFilterName": null
+ },
+ "gekuendigte": {
+ "layout": null,
+ "selectPrimaryFilterName": null
+ },
+ "dokumenteskuendigung": {
+ "layout": null,
+ "selectPrimaryFilterName": null
+ },
+ "contactsKuendigung": {
+ "layout": null,
+ "selectPrimaryFilterName": "portalUsers"
+ }
+ }
}
\ No newline at end of file
diff --git a/custom/Espo/Custom/Resources/metadata/clientDefs/CVmhMietverhltnis.json b/custom/Espo/Custom/Resources/metadata/clientDefs/CVmhMietverhltnis.json
index d23a758e..07e82eca 100644
--- a/custom/Espo/Custom/Resources/metadata/clientDefs/CVmhMietverhltnis.json
+++ b/custom/Espo/Custom/Resources/metadata/clientDefs/CVmhMietverhltnis.json
@@ -25,6 +25,16 @@
"iconHtml": "",
"style": "warning",
"acl": "edit"
+ },
+ {
+ "name": "initiateTermination",
+ "label": "Initiate Termination",
+ "handler": "custom:handlers/mietverhaeltnis/termination-action",
+ "initFunction": "initInitiateTermination",
+ "actionFunction": "actionInitiateTermination",
+ "iconHtml": "",
+ "style": "primary",
+ "acl": "edit"
}
]
}
diff --git a/custom/Espo/Custom/Resources/metadata/entityDefs/CBeteiligte.json b/custom/Espo/Custom/Resources/metadata/entityDefs/CBeteiligte.json
index 9eb14219..78120690 100644
--- a/custom/Espo/Custom/Resources/metadata/entityDefs/CBeteiligte.json
+++ b/custom/Espo/Custom/Resources/metadata/entityDefs/CBeteiligte.json
@@ -294,6 +294,22 @@
"audited": false,
"isCustom": true
},
+ "kndigungenKuendiger": {
+ "type": "hasMany",
+ "relationName": "cBeteiligteKuendigungKuendiger",
+ "foreign": "kuendiger",
+ "entity": "CKndigung",
+ "audited": false,
+ "isCustom": true
+ },
+ "kndigungenGekuendigte": {
+ "type": "hasMany",
+ "relationName": "cBeteiligteKuendigungGekuendigte",
+ "foreign": "gekuendigte",
+ "entity": "CKndigung",
+ "audited": false,
+ "isCustom": true
+ },
"dokumentesBeteiligte": {
"type": "hasMany",
"relationName": "cBeteiligteDokumente",
diff --git a/custom/Espo/Custom/Resources/metadata/entityDefs/CDokumente.json b/custom/Espo/Custom/Resources/metadata/entityDefs/CDokumente.json
index ba5ce257..8517b980 100644
--- a/custom/Espo/Custom/Resources/metadata/entityDefs/CDokumente.json
+++ b/custom/Espo/Custom/Resources/metadata/entityDefs/CDokumente.json
@@ -176,6 +176,14 @@
"audited": false,
"isCustom": true
},
+ "kndigungensdokumente": {
+ "type": "hasMany",
+ "relationName": "cDokumenteKuendigung",
+ "foreign": "dokumenteskuendigung",
+ "entity": "CKndigung",
+ "audited": false,
+ "isCustom": true
+ },
"beteiligte2dokumente": {
"type": "hasMany",
"relationName": "cBeteiligteDokumente",
diff --git a/custom/Espo/Custom/Resources/metadata/entityDefs/CKndigung.json b/custom/Espo/Custom/Resources/metadata/entityDefs/CKndigung.json
index d521dd6a..c95347c5 100644
--- a/custom/Espo/Custom/Resources/metadata/entityDefs/CKndigung.json
+++ b/custom/Espo/Custom/Resources/metadata/entityDefs/CKndigung.json
@@ -34,6 +34,176 @@
"teams": {
"type": "linkMultiple",
"view": "views/fields/teams"
+ },
+ "freigeschalteteNutzer": {
+ "type": "link"
+ },
+ "collaborators": {
+ "type": "linkMultiple",
+ "view": "views/fields/collaborators",
+ "maxCount": 30,
+ "fieldManagerParamList": [
+ "readOnly",
+ "readOnlyAfterCreate",
+ "audited",
+ "autocompleteOnEmpty",
+ "maxCount",
+ "inlineEditDisabled",
+ "tooltipText"
+ ]
+ },
+ "advowareAktenzeichen": {
+ "type": "varchar",
+ "required": false,
+ "maxLength": 100,
+ "tooltip": true,
+ "isCustom": true,
+ "copyToClipboard": true
+ },
+ "betnr": {
+ "type": "int",
+ "required": false,
+ "tooltip": true,
+ "isCustom": true
+ },
+ "advowareLastSync": {
+ "type": "datetime",
+ "required": false,
+ "readOnly": true,
+ "tooltip": true,
+ "isCustom": true
+ },
+ "syncStatus": {
+ "type": "enum",
+ "required": false,
+ "options": [
+ "clean",
+ "unclean",
+ "failed"
+ ],
+ "style": {
+ "clean": "success",
+ "unclean": "warning",
+ "failed": "danger"
+ },
+ "default": "clean",
+ "tooltip": true,
+ "isCustom": true
+ },
+ "kuendigungsart": {
+ "type": "enum",
+ "required": false,
+ "options": [
+ "Ordentlich",
+ "Ausserordentlich",
+ "Fristlos",
+ "AufgabeerklärungMieter"
+ ],
+ "default": "Ordentlich",
+ "isCustom": true
+ },
+ "kuendigungsgrund": {
+ "type": "enum",
+ "required": false,
+ "options": [
+ "Zahlungsverzug",
+ "Pflichtverletzung",
+ "Eigenbedarf",
+ "Verwertung",
+ "VerhaltensbedingteLaermruhestoerung",
+ "BeschaedigungSubstanz",
+ "UnerlaubteUntervermietung",
+ "StoerendeGeschaeftsfuehrung",
+ "Sonstiges"
+ ],
+ "isCustom": true
+ },
+ "kuendigungsgrundDetails": {
+ "type": "text",
+ "required": false,
+ "isCustom": true
+ },
+ "kuendigungsdatum": {
+ "type": "date",
+ "required": false,
+ "isCustom": true
+ },
+ "zustelldatum": {
+ "type": "date",
+ "required": false,
+ "isCustom": true
+ },
+ "kuendigungsfrist": {
+ "type": "varchar",
+ "required": false,
+ "maxLength": 50,
+ "isCustom": true
+ },
+ "beendigungstermin": {
+ "type": "date",
+ "required": false,
+ "isCustom": true
+ },
+ "status": {
+ "type": "enum",
+ "required": false,
+ "options": [
+ "Entwurf",
+ "Versendet",
+ "Zugestellt",
+ "Akzeptiert",
+ "Bestritten",
+ "Abgewickelt",
+ "Zurückgezogen"
+ ],
+ "default": "Entwurf",
+ "isCustom": true
+ },
+ "zustellart": {
+ "type": "enum",
+ "required": false,
+ "options": [
+ "Einschreiben",
+ "Persoenlich",
+ "Gerichtsvollzieher",
+ "Oeffentlich",
+ "Sonstiges"
+ ],
+ "isCustom": true
+ },
+ "reaktionMieter": {
+ "type": "text",
+ "required": false,
+ "isCustom": true
+ },
+ "notizen": {
+ "type": "text",
+ "required": false,
+ "isCustom": true
+ },
+ "rueckstandMiete": {
+ "type": "currency",
+ "required": false,
+ "default": 0,
+ "isCustom": true
+ },
+ "rueckstandNebenkosten": {
+ "type": "currency",
+ "required": false,
+ "default": 0,
+ "isCustom": true
+ },
+ "sonstigeForderungen": {
+ "type": "currency",
+ "required": false,
+ "default": 0,
+ "isCustom": true
+ },
+ "aussergerichtlicheGebuehren13": {
+ "type": "currency",
+ "required": false,
+ "default": 0,
+ "isCustom": true
}
},
"links": {
@@ -75,11 +245,77 @@
"entity": "Email",
"foreign": "parent",
"layoutRelationshipsDisabled": true
+ },
+ "vmhMietverhltnises": {
+ "type": "hasMany",
+ "relationName": "cKuendigungVmhMietverhltnis",
+ "foreign": "kndigungen",
+ "entity": "CVmhMietverhltnis",
+ "audited": false,
+ "isCustom": true
+ },
+ "mietobjekte": {
+ "type": "hasMany",
+ "relationName": "cMietobjektKuendigung",
+ "foreign": "kndigungen",
+ "entity": "CMietobjekt",
+ "audited": false,
+ "isCustom": true
+ },
+ "freigeschalteteNutzer": {
+ "type": "belongsTo",
+ "foreign": "cKndigungen",
+ "entity": "Contact",
+ "audited": false,
+ "isCustom": true
+ },
+ "collaborators": {
+ "type": "hasMany",
+ "entity": "User",
+ "relationName": "entityCollaborator",
+ "layoutRelationshipsDisabled": true
+ },
+ "dokumenteskuendigung": {
+ "type": "hasMany",
+ "relationName": "cDokumenteKuendigung",
+ "foreign": "kndigungensdokumente",
+ "entity": "CDokumente",
+ "audited": false,
+ "isCustom": true
+ },
+ "contactsKuendigung": {
+ "type": "hasMany",
+ "relationName": "cKuendigungContact",
+ "foreign": "cKuendigungContact",
+ "entity": "Contact",
+ "audited": false,
+ "isCustom": true
+ },
+ "kuendiger": {
+ "type": "hasMany",
+ "relationName": "cBeteiligteKuendigungKuendiger",
+ "foreign": "kndigungenKuendiger",
+ "entity": "CBeteiligte",
+ "audited": false,
+ "isCustom": true
+ },
+ "gekuendigte": {
+ "type": "hasMany",
+ "relationName": "cBeteiligteKuendigungGekuendigte",
+ "foreign": "kndigungenGekuendigte",
+ "entity": "CBeteiligte",
+ "audited": false,
+ "isCustom": true
}
},
"collection": {
"orderBy": "createdAt",
- "order": "desc"
+ "order": "desc",
+ "textFilterFields": [
+ "name"
+ ],
+ "fullTextSearch": false,
+ "countDisabled": false
},
"indexes": {
"name": {
@@ -105,6 +341,39 @@
"createdAt",
"id"
]
+ },
+ "betnr": {
+ "columns": [
+ "betnr"
+ ]
+ },
+ "advowareAktenzeichen": {
+ "columns": [
+ "advowareAktenzeichen"
+ ]
+ },
+ "status": {
+ "columns": [
+ "status",
+ "deleted"
+ ]
+ },
+ "kuendigungsdatum": {
+ "columns": [
+ "kuendigungsdatum"
+ ]
+ },
+ "beendigungstermin": {
+ "columns": [
+ "beendigungstermin"
+ ]
+ },
+ "syncStatus": {
+ "columns": [
+ "syncStatus",
+ "deleted"
+ ]
}
- }
+ },
+ "optimisticConcurrencyControl": false
}
\ No newline at end of file
diff --git a/custom/Espo/Custom/Resources/metadata/entityDefs/CMietobjekt.json b/custom/Espo/Custom/Resources/metadata/entityDefs/CMietobjekt.json
index c653ac24..b54e7cd8 100644
--- a/custom/Espo/Custom/Resources/metadata/entityDefs/CMietobjekt.json
+++ b/custom/Espo/Custom/Resources/metadata/entityDefs/CMietobjekt.json
@@ -157,6 +157,14 @@
"entity": "CMietinkasso",
"audited": false,
"isCustom": true
+ },
+ "kndigungen": {
+ "type": "hasMany",
+ "relationName": "cMietobjektKuendigung",
+ "foreign": "mietobjekte",
+ "entity": "CKndigung",
+ "audited": false,
+ "isCustom": true
}
},
"collection": {
diff --git a/custom/Espo/Custom/Resources/metadata/entityDefs/CVmhMietverhltnis.json b/custom/Espo/Custom/Resources/metadata/entityDefs/CVmhMietverhltnis.json
index 45b642d2..e6ba3874 100644
--- a/custom/Espo/Custom/Resources/metadata/entityDefs/CVmhMietverhltnis.json
+++ b/custom/Espo/Custom/Resources/metadata/entityDefs/CVmhMietverhltnis.json
@@ -234,6 +234,14 @@
"audited": false,
"isCustom": true
},
+ "kndigungen": {
+ "type": "hasMany",
+ "relationName": "cKuendigungVmhMietverhltnis",
+ "foreign": "vmhMietverhltnises",
+ "entity": "CKndigung",
+ "audited": false,
+ "isCustom": true
+ },
"vmhbeteiligtevermieter": {
"type": "hasMany",
"relationName": "cBeteiligteVmhMietverhltnis",
diff --git a/custom/Espo/Custom/Resources/metadata/entityDefs/Contact.json b/custom/Espo/Custom/Resources/metadata/entityDefs/Contact.json
index 1e8fca88..a1f5a00d 100644
--- a/custom/Espo/Custom/Resources/metadata/entityDefs/Contact.json
+++ b/custom/Espo/Custom/Resources/metadata/entityDefs/Contact.json
@@ -94,6 +94,14 @@
"audited": false,
"isCustom": true
},
+ "cKuendigungContact": {
+ "type": "hasMany",
+ "relationName": "cKuendigungContact",
+ "foreign": "contactsKuendigung",
+ "entity": "CKndigung",
+ "audited": false,
+ "isCustom": true
+ },
"cBankverbindungenContact": {
"type": "hasMany",
"relationName": "cBankverbindungContact",
diff --git a/custom/Espo/Custom/Services/CVmhMietverhltnis.php b/custom/Espo/Custom/Services/CVmhMietverhltnis.php
index b28c3081..e23fcc0b 100644
--- a/custom/Espo/Custom/Services/CVmhMietverhltnis.php
+++ b/custom/Espo/Custom/Services/CVmhMietverhltnis.php
@@ -368,4 +368,185 @@ class CVmhMietverhltnis extends \Espo\Services\Record
throw $e;
}
}
+
+ /**
+ * Initiate termination (Kündigung) from Mietverhältnis
+ *
+ * @param string $mietverhaeltnisId
+ * @return array
+ * @throws NotFound
+ * @throws Forbidden
+ */
+ public function initiateTermination(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('CKndigung', 'create')) {
+ throw new Forbidden('No create access to Kündigung');
+ }
+
+ // 3. Start Transaction
+ $this->entityManager->getTransactionManager()->start();
+
+ try {
+ // 4. Prepare data for new Kündigung
+ $data = new \stdClass();
+ $data->name = 'Kündigung - ' . $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 Kündigung entity
+ $kuendigung = $this->entityManager->createEntity('CKndigung', (array)$data);
+
+ if (!$kuendigung) {
+ throw new \RuntimeException('Failed to create Kündigung');
+ }
+
+ $kuendigungRepo = $this->entityManager->getRepository('CKndigung');
+
+ // 6. Link Mietverhältnis to Kündigung
+ $kuendigungRepo
+ ->getRelation($kuendigung, 'vmhMietverhltnises')
+ ->relate($mietverhaeltnis);
+
+ // 7. Get and link Mietobjekt
+ $mietobjekt = $this->entityManager
+ ->getRepository('CVmhMietverhltnis')
+ ->getRelation($mietverhaeltnis, 'vmhMietobjekt')
+ ->findOne();
+
+ if ($mietobjekt) {
+ $kuendigungRepo
+ ->getRelation($kuendigung, 'mietobjekte')
+ ->relate($mietobjekt);
+ }
+
+ // 8. Get Vermieter (Kündigende) from Mietverhältnis
+ $vermieterBeteiligte = $this->entityManager
+ ->getRepository('CVmhMietverhltnis')
+ ->getRelation($mietverhaeltnis, 'vmhbeteiligtevermieter')
+ ->find();
+
+ foreach ($vermieterBeteiligte as $vermieter) {
+ // Link as Kündigende
+ $kuendigungRepo
+ ->getRelation($kuendigung, 'kuendiger')
+ ->relate($vermieter);
+ }
+
+ // 9. Get Mieter (Gekündigte) from Mietverhältnis
+ $mieterBeteiligte = $this->entityManager
+ ->getRepository('CVmhMietverhltnis')
+ ->getRelation($mietverhaeltnis, 'vmhbeteiligtemieter')
+ ->find();
+
+ foreach ($mieterBeteiligte as $mieter) {
+ // Link as Gekündigte
+ $kuendigungRepo
+ ->getRelation($kuendigung, 'gekuendigte')
+ ->relate($mieter);
+ }
+
+ // 9b. Get Sonstige Bewohner (auch Gekündigte) from Mietverhältnis
+ $sonstigeBewohner = $this->entityManager
+ ->getRepository('CVmhMietverhltnis')
+ ->getRelation($mietverhaeltnis, 'sonstigebesitzervmhmietverhltnis')
+ ->find();
+
+ foreach ($sonstigeBewohner as $bewohner) {
+ // Link as Gekündigte
+ $kuendigungRepo
+ ->getRelation($kuendigung, 'gekuendigte')
+ ->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) {
+ $kuendigungRepo
+ ->getRelation($kuendigung, 'dokumenteskuendigung')
+ ->relate($dokument);
+ }
+
+ // 10b. Dokumente vom Mietobjekt
+ if ($mietobjekt) {
+ $dokumenteMO = $this->entityManager
+ ->getRepository('CMietobjekt')
+ ->getRelation($mietobjekt, 'dokumentesMietobjekt')
+ ->find();
+
+ foreach ($dokumenteMO as $dokument) {
+ $kuendigungRepo
+ ->getRelation($kuendigung, 'dokumenteskuendigung')
+ ->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) {
+ $kuendigungRepo
+ ->getRelation($kuendigung, 'dokumenteskuendigung')
+ ->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) {
+ $kuendigungRepo
+ ->getRelation($kuendigung, 'contactsKuendigung')
+ ->relate($contact);
+ }
+
+ // 12. Commit transaction
+ $this->entityManager->getTransactionManager()->commit();
+
+ return [
+ 'id' => $kuendigung->getId(),
+ 'name' => $kuendigung->get('name')
+ ];
+ } catch (\Exception $e) {
+ // Rollback on any error
+ $this->entityManager->getTransactionManager()->rollback();
+ throw $e;
+ }
+ }
}
diff --git a/data/config.php b/data/config.php
index b5e1d35a..d325c9d3 100644
--- a/data/config.php
+++ b/data/config.php
@@ -360,8 +360,8 @@ return [
0 => 'youtube.com',
1 => 'google.com'
],
- 'cacheTimestamp' => 1769256001,
- 'microtime' => 1769256001.008295,
+ 'cacheTimestamp' => 1769331937,
+ 'microtime' => 1769331937.84435,
'siteUrl' => 'https://crm.bitbylaw.com',
'fullTextSearchMinLength' => 4,
'appTimestamp' => 1768843902,