Add termination (Kündigung) functionality and related translations

- Implemented the ability to initiate terminations from Mietverhältnisse.
- Added new fields and options for terminations in both German and English language files.
- Updated metadata definitions to include relationships for terminations with Mietobjekte and Beteiligte.
- Enhanced the service layer to handle termination creation, including linking relevant entities and copying documents.
- Updated configuration timestamps for deployment.
This commit is contained in:
2026-01-25 10:06:02 +01:00
parent 07ff3c5c54
commit 30326da8c6
23 changed files with 771 additions and 18 deletions

View File

@@ -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;
}
}

View File

@@ -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",

View File

@@ -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"

View File

@@ -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"
}
}

View File

@@ -14,6 +14,7 @@
"contact2mietobjekt": "Kontakte",
"vmhRumungsklages": "Räumungsklagen",
"mietinkassos": "Mietinkasso",
"kndigungen": "Kündigungen",
"contactsMietobjekt": "Freigegebene Nutzer",
"dokumentesMietobjekt": "Dokumente"
},

View File

@@ -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"
}
}

View File

@@ -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": {

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"
}
}

View File

@@ -20,6 +20,7 @@
"contact2mietobjekt": "Contacts",
"vmhRumungsklages": "Eviction Lawsuits",
"mietinkassos": "Rent Collection",
"kndigungen": "Terminations",
"contactsMietobjekt": "Portal Users",
"dokumentesMietobjekt": "Documents"
},

View File

@@ -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": {

View File

@@ -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": {

View File

@@ -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"
}
}
}

View File

@@ -25,6 +25,16 @@
"iconHtml": "<span class=\"fas fa-euro-sign\"></span>",
"style": "warning",
"acl": "edit"
},
{
"name": "initiateTermination",
"label": "Initiate Termination",
"handler": "custom:handlers/mietverhaeltnis/termination-action",
"initFunction": "initInitiateTermination",
"actionFunction": "actionInitiateTermination",
"iconHtml": "<span class=\"fas fa-file-contract\"></span>",
"style": "primary",
"acl": "edit"
}
]
}

View File

@@ -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",

View File

@@ -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",

View File

@@ -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
}

View File

@@ -157,6 +157,14 @@
"entity": "CMietinkasso",
"audited": false,
"isCustom": true
},
"kndigungen": {
"type": "hasMany",
"relationName": "cMietobjektKuendigung",
"foreign": "mietobjekte",
"entity": "CKndigung",
"audited": false,
"isCustom": true
}
},
"collection": {

View File

@@ -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",

View File

@@ -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",

View File

@@ -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;
}
}
}

View File

@@ -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,