Merge detached HEAD: Add Kündigung entity with complete layouts and fix all false placeholders in detail.json files for EspoCRM 7.x compatibility

This commit is contained in:
2026-01-25 10:31:03 +01:00
38 changed files with 1021 additions and 138 deletions

View File

@@ -44,7 +44,7 @@ class CVmhMietverhltnis extends \Espo\Core\Templates\Controllers\BasePlus
}
/**
* POST Action: Initiate termination from Mietverhältnis
* POST Action: Initiate termination (Kündigung) from Mietverhältnis
*/
public function postActionInitiateTermination(Request $request): array
{

View File

@@ -12,8 +12,8 @@
"vmhRumungsklagesBeklagte": "Beklagte",
"mietinkassosKlaeger": "Mietinkasso (Kläger)",
"mietinkassosBeklagte": "Mietinkasso (Beklagte)",
"kuendigungenVermieter": "Kündigungen (Vermieter)",
"kuendigungenMieter": "Kündigungen (Mieter)",
"kndigungenKuendiger": "Kündigungen (Kündigende)",
"kndigungenGekuendigte": "Kündigungen (Gekündigte)",
"adressens": "Adressen",
"calls1": "Anrufe",
"contactsBeteiligte": "Freigegebene Nutzer",
@@ -35,8 +35,8 @@
"vmhRumungsklagesBeklagte": "Beklagte",
"mietinkassosKlaeger": "Mietinkasso (Kläger)",
"mietinkassosBeklagte": "Mietinkasso (Beklagte)",
"kuendigungenVermieter": "Kündigungen (Vermieter)",
"kuendigungenMieter": "Kündigungen (Mieter)",
"kndigungenKuendiger": "Kündigungen (Kündigende)",
"kndigungenGekuendigte": "Kündigungen (Gekündigte)",
"adressens": "Adressen",
"calls1": "Anrufe",
"contactsBeteiligte": "Freigegebene Nutzer",

View File

@@ -14,7 +14,9 @@
"vmhRumungsklagesdokumente": "Räumungsklagen",
"kuendigungDokumente": "Kündigungen",
"beteiligte2dokumente": "Beteiligte",
"mietobjekt2dokumente": "Mietobjekte"
"mietobjekt2dokumente": "Mietobjekte",
"mietinkassosdokumente": "Mietinkasso",
"kndigungensdokumente": "Kündigungen"
},
"links": {
"contactsvmhdokumente": "Freigegebene Nutzer",
@@ -24,7 +26,8 @@
"kuendigungDokumente": "Kündigungen",
"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

@@ -6,8 +6,7 @@
"vmhMietverhltnises2Mietobjekt": "Mietverhältnisse (veraltet)",
"vmhMietverhltnises": "Mietverhältnisse",
"contactsMietobjekt": "Freigegebene Nutzer",
"dokumentesMietobjekt": "Dokumente",
"kuendigungen": "Kündigungen"
"dokumentesMietobjekt": "Dokumente"
},
"links": {
"vmhMietverhltnises2Mietobjekt": "Mietverhältnisse (veraltet)",
@@ -15,7 +14,7 @@
"contact2mietobjekt": "Kontakte",
"vmhRumungsklages": "Räumungsklagen",
"mietinkassos": "Mietinkasso",
"kuendigungen": "Kündigungen",
"kndigungen": "Kündigungen",
"contactsMietobjekt": "Freigegebene Nutzer",
"dokumentesMietobjekt": "Dokumente"
},

View File

@@ -13,7 +13,7 @@
"warmmiete": "Warmmiete",
"vmhRumungsklages": "Räumungsklagen",
"mietinkassos": "Mietinkasso",
"kuendigungen": "Kündigungen",
"kndigungen": "Kündigungen",
"vmhbeteiligtevermieter": "Vermieter",
"vmhbeteiligtemieter": "Mieter",
"contactsMietverhltnis": "Freigegebene Nutzer",
@@ -34,7 +34,7 @@
"tasks": "Aufgaben",
"vmhRumungsklages": "Räumungsklagen",
"mietinkassos": "Mietinkasso",
"kuendigungen": "Kündigungen",
"kndigungen": "Kündigungen",
"vmhbeteiligtevermieter": "Vermieter",
"vmhbeteiligtemieter": "Mieter",
"contactsMietverhltnis": "Freigegebene Nutzer",
@@ -56,7 +56,7 @@
"confirmRentCollection": "Möchten Sie wirklich ein Mietinkasso aus diesem Mietverhältnis einleiten?",
"rentCollectionCreated": "Mietinkasso wurde erfolgreich erstellt",
"rentCollectionError": "Fehler beim Erstellen des Mietinkassos",
"confirmTermination": "Möchten Sie wirklich eine Kündigung für dieses Mietverhältnis erstellen?",
"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,8 +14,8 @@
"cMietobjekteContactPortal": "Mietobjekte (Portal)",
"cAdressenContact": "Adressen",
"cVmhRumungsklageContact": "Räumungsklagen (Portal)",
"cMietinkassoContact": "Mietinkasso (Portal)",
"cKuendigungContact": "Kündigungen (Portal)",
"cMietinkassoContact": "Mietinkasso",
"cKuendigungContact": "Kündigungen",
"cBankverbindungenContact": "Bankverbindungen"
},
"links": {
@@ -31,7 +31,7 @@
"cAdressenContact": "Adressen",
"cVmhRumungsklageContact": "Räumungsklagen (Portal)",
"cMietinkassoContact": "Mietinkasso",
"cKuendigungContact": "Kündigungen (Portal)",
"cKuendigungContact": "Kündigungen",
"cBankverbindungenContact": "Bankverbindungen"
},
"options": {

View File

@@ -11,8 +11,8 @@
"vmhRumungsklagesKlaeger": "Plaintiff",
"mietinkassosKlaeger": "Rent Collection (Plaintiff)",
"mietinkassosBeklagte": "Rent Collection (Defendant)",
"kuendigungenVermieter": "Terminations (Landlord)",
"kuendigungenMieter": "Terminations (Tenant)",
"kndigungenKuendiger": "Terminations (Terminating Party)",
"kndigungenGekuendigte": "Terminations (Terminated Party)",
"contactsBeteiligte": "Portal Users",
"dokumentesBeteiligte": "Documents"
},
@@ -29,8 +29,8 @@
"vmhRumungsklagesKlaeger": "Plaintiff",
"mietinkassosKlaeger": "Rent Collection (Plaintiff)",
"mietinkassosBeklagte": "Rent Collection (Defendant)",
"kuendigungenVermieter": "Terminations (Landlord)",
"kuendigungenMieter": "Terminations (Tenant)",
"kndigungenKuendiger": "Terminations (Terminating Party)",
"kndigungenGekuendigte": "Terminations (Terminated Party)",
"contactsBeteiligte": "Portal Users",
"dokumentesBeteiligte": "Documents",
"bankverbindungens": "Bank Accounts"

View File

@@ -11,7 +11,9 @@
"md5sum": "MD5 Checksum",
"sha256": "SHA256 Checksum",
"beteiligte2dokumente": "Parties",
"mietobjekt2dokumente": "Properties"
"mietobjekt2dokumente": "Properties",
"mietinkassosdokumente": "Rent Collection",
"kndigungensdokumente": "Terminations"
},
"links": {
"contactsvmhdokumente": "Portal Users",
@@ -21,7 +23,8 @@
"kuendigungDokumente": "Terminations",
"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,7 +20,7 @@
"contact2mietobjekt": "Contacts",
"vmhRumungsklages": "Eviction Lawsuits",
"mietinkassos": "Rent Collection",
"kuendigungen": "Terminations",
"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,7 +37,7 @@
"tasks": "Tasks",
"vmhRumungsklages": "Eviction Lawsuits",
"mietinkassos": "Rent Collection",
"kuendigungen": "Terminations",
"kndigungen": "Terminations",
"vmhbeteiligtevermieter": "Landlords",
"vmhbeteiligtemieter": "Tenants",
"contactsMietverhltnis": "Portal Users",
@@ -48,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?",
@@ -56,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,7 +25,7 @@
"cAdressenContact": "Addresses",
"cVmhRumungsklageContact": "Eviction Lawsuits (Portal)",
"cMietinkassoContact": "Rent Collection",
"cKuendigungContact": "Terminations (Portal)",
"cKuendigungContact": "Terminations",
"cBankverbindungenContact": "Bank Accounts"
},
"options": {

View File

@@ -5,7 +5,7 @@
{
"name": "rechtsform"
},
false
{}
],
[
{
@@ -19,13 +19,13 @@
{
"name": "disgTyp"
},
false
{}
],
[
{
"name": "firmenname"
},
false
{}
],
[
{

View File

@@ -5,7 +5,7 @@
{
"name": "name"
},
false
{}
]
],
"dynamicLogicVisible": null,
@@ -42,7 +42,7 @@
{
"name": "ydocumentuuid"
},
false
{}
]
],
"dynamicLogicVisible": null,

View File

@@ -0,0 +1,63 @@
{
"_delimiter_": {
"disabled": true
},
"activities": {
"disabled": true
},
"history": {
"disabled": true
},
"_tabBreak_0": {
"index": 0,
"tabBreak": true,
"tabLabel": "Freigegebene Nutzer"
},
"contactsKuendigung": {
"dynamicLogicVisible": null,
"style": "warning",
"dynamicLogicStyled": null,
"sticked": true,
"index": 1
},
"_tabBreak_1": {
"index": 2,
"tabBreak": true,
"tabLabel": "Kündigende"
},
"kuendiger": {
"index": 3
},
"_tabBreak_2": {
"index": 4,
"tabBreak": true,
"tabLabel": "Gekündigte"
},
"gekuendigte": {
"index": 5
},
"_tabBreak_3": {
"index": 6,
"tabBreak": true,
"tabLabel": "Mietverhältnisse"
},
"vmhMietverhltnises": {
"index": 7
},
"_tabBreak_4": {
"index": 8,
"tabBreak": true,
"tabLabel": "Dokumente"
},
"dokumenteskuendigung": {
"index": 9
},
"_tabBreak_5": {
"index": 10,
"tabBreak": true,
"tabLabel": "Mietobjekte"
},
"mietobjekte": {
"index": 11
}
}

View File

@@ -0,0 +1,11 @@
[
{
"name": ":assignedUser"
},
{
"name": "teams"
},
{
"name": "freigeschalteteNutzer"
}
]

View File

@@ -0,0 +1,114 @@
[
{
"label": "Kündigungsdetails",
"style": "default",
"tabBreak": false,
"rows": [
[
{
"name": "name"
},
{
"name": "kuendigungsart"
},
{
"name": "status"
},
{
"name": "advowareAktenzeichen"
}
],
[
{
"name": "kuendigungsgrund"
},
{
"name": "kuendigungsdatum"
},
{
"name": "zustelldatum"
},
{
"name": "zustellart"
}
],
[
{
"name": "kuendigungsfrist"
},
{
"name": "beendigungstermin"
},
{},
{}
],
[
{
"name": "kuendigungsgrundDetails"
}
]
]
},
{
"label": "Finanzielle Forderungen",
"style": "default",
"tabBreak": false,
"rows": [
[
{
"name": "rueckstandMiete"
},
{
"name": "rueckstandNebenkosten"
},
{
"name": "sonstigeForderungen"
},
{
"name": "aussergerichtlicheGebuehren13"
}
]
]
},
{
"label": "Notizen & Reaktion",
"style": "default",
"tabBreak": false,
"rows": [
[
{
"name": "reaktionMieter"
}
],
[
{
"name": "notizen"
}
],
[
{
"name": "description"
}
]
]
},
{
"label": "Advoware Sync",
"style": "default",
"tabBreak": true,
"tabLabel": "Erweitert",
"rows": [
[
{
"name": "betnr"
},
{
"name": "syncStatus"
},
{
"name": "advowareLastSync"
}
]
]
}
]

View File

@@ -0,0 +1,33 @@
[
{
"rows": [
[
{
"name": "name",
"noLabel": true
}
],
[
{
"name": "kuendigungsart"
},
{
"name": "status"
}
],
[
{
"name": "kuendigungsdatum"
},
{
"name": "beendigungstermin"
}
],
[
{
"name": "assignedUser"
}
]
]
}
]

View File

@@ -0,0 +1,31 @@
[
{
"name": "name",
"link": true,
"width": 20
},
{
"name": "kuendigungsart",
"width": 12
},
{
"name": "status",
"width": 12
},
{
"name": "kuendigungsdatum",
"width": 12
},
{
"name": "beendigungstermin",
"width": 12
},
{
"name": "assignedUser",
"width": 16
},
{
"name": "modifiedAt",
"width": 16
}
]

View File

@@ -0,0 +1,15 @@
[
{
"name": "name",
"link": true
},
{
"name": "kuendigungsart"
},
{
"name": "status"
},
{
"name": "kuendigungsdatum"
}
]

View File

@@ -19,7 +19,7 @@
{
"name": "kuendigungsservice"
},
false
{}
],
[
{

View File

@@ -13,7 +13,7 @@
{
"name": "lage"
},
false
{}
],
[
{

View File

@@ -44,9 +44,9 @@
{
"name": "besorgnisNichtRechtzeitigerAuszug"
},
false,
false,
false
{},
{},
{}
]
],
"dynamicLogicVisible": null,

View File

@@ -19,7 +19,7 @@
{
"name": "kuendigungsservice"
},
false
{}
],
[
{

View File

@@ -46,7 +46,7 @@
{
"name": "advowareBetnr"
},
false
{}
]
],
"dynamicLogicVisible": null,

View File

@@ -13,7 +13,7 @@
{
"name": "anruferIst"
},
false
{}
],
[
{
@@ -35,7 +35,7 @@
{
"name": "address"
},
false
{}
],
[
{

View File

@@ -5,7 +5,7 @@
{
"name": "userName"
},
false
{}
],
[
{

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

@@ -294,19 +294,19 @@
"audited": false,
"isCustom": true
},
"kuendigungenVermieter": {
"kndigungenKuendiger": {
"type": "hasMany",
"relationName": "cBeteiligteKuendigungVermieter",
"foreign": "vermieter",
"entity": "CKuendigung",
"relationName": "cBeteiligteKuendigungKuendiger",
"foreign": "kuendiger",
"entity": "CKndigung",
"audited": false,
"isCustom": true
},
"kuendigungenMieter": {
"kndigungenGekuendigte": {
"type": "hasMany",
"relationName": "cBeteiligteKuendigungMieter",
"foreign": "mieter",
"entity": "CKuendigung",
"relationName": "cBeteiligteKuendigungGekuendigte",
"foreign": "gekuendigte",
"entity": "CKndigung",
"audited": false,
"isCustom": true
},

View File

@@ -176,11 +176,11 @@
"audited": false,
"isCustom": true
},
"kuendigungDokumente": {
"kndigungensdokumente": {
"type": "hasMany",
"relationName": "cDokumenteKuendigung",
"foreign": "dokumenteKuendigung",
"entity": "CKuendigung",
"foreign": "dokumenteskuendigung",
"entity": "CKndigung",
"audited": false,
"isCustom": true
},

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

@@ -158,11 +158,11 @@
"audited": false,
"isCustom": true
},
"kuendigungen": {
"kndigungen": {
"type": "hasMany",
"relationName": "cKuendigungMietobjekt",
"foreign": "mietobjekt",
"entity": "CKuendigung",
"relationName": "cMietobjektKuendigung",
"foreign": "mietobjekte",
"entity": "CKndigung",
"audited": false,
"isCustom": true
}

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

@@ -98,7 +98,7 @@
"type": "hasMany",
"relationName": "cKuendigungContact",
"foreign": "contactsKuendigung",
"entity": "CKuendigung",
"entity": "CKndigung",
"audited": false,
"isCustom": true
},

View File

@@ -390,7 +390,7 @@ class CVmhMietverhltnis extends \Espo\Services\Record
throw new Forbidden('No read access to Mietverhältnis');
}
if (!$this->acl->checkScope('CKuendigung', 'create')) {
if (!$this->acl->checkScope('CKndigung', 'create')) {
throw new Forbidden('No create access to Kündigung');
}
@@ -412,33 +412,18 @@ class CVmhMietverhltnis extends \Espo\Services\Record
$data->teamsIds = $teamsIds;
}
// Pre-fill dates from Mietverhältnis
if ($mietverhaeltnis->get('auszugsfrist')) {
$data->kuendigungsfrist = $mietverhaeltnis->get('auszugsfrist');
}
// Pre-fill Kündigungsgrund from Mietverhältnis
if ($mietverhaeltnis->get('kndigungsgrundWohnraum')) {
$data->kuendigungsgrund = $mietverhaeltnis->get('kndigungsgrundWohnraum');
}
// Pre-fill Besorgnis nicht rechtzeitiger Auszug
if ($mietverhaeltnis->get('besorgnisNichtRechtzeitigerAuszug')) {
$data->besorgnisNichtRechtzeitigerAuszug = $mietverhaeltnis->get('besorgnisNichtRechtzeitigerAuszug');
}
// 5. Create Kündigung entity
$kuendigung = $this->entityManager->createEntity('CKuendigung', (array)$data);
$kuendigung = $this->entityManager->createEntity('CKndigung', (array)$data);
if (!$kuendigung) {
throw new \RuntimeException('Failed to create Kündigung');
}
$kuendigungRepo = $this->entityManager->getRepository('CKuendigung');
$kuendigungRepo = $this->entityManager->getRepository('CKndigung');
// 6. Link Mietverhältnis to Kündigung
$kuendigungRepo
->getRelation($kuendigung, 'vmhMietverhltnis')
->getRelation($kuendigung, 'vmhMietverhltnises')
->relate($mietverhaeltnis);
// 7. Get and link Mietobjekt
@@ -449,37 +434,97 @@ class CVmhMietverhltnis extends \Espo\Services\Record
if ($mietobjekt) {
$kuendigungRepo
->getRelation($kuendigung, 'mietobjekt')
->getRelation($kuendigung, 'mietobjekte')
->relate($mietobjekt);
}
// 8. Get Vermieter from Mietverhältnis
// 8. Get Vermieter (Kündigende) from Mietverhältnis
$vermieterBeteiligte = $this->entityManager
->getRepository('CVmhMietverhltnis')
->getRelation($mietverhaeltnis, 'vmhbeteiligtevermieter')
->find();
foreach ($vermieterBeteiligte as $vermieter) {
// Link as Vermieter
// Link as Kündigende
$kuendigungRepo
->getRelation($kuendigung, 'vermieter')
->getRelation($kuendigung, 'kuendiger')
->relate($vermieter);
}
// 9. Get Mieter from Mietverhältnis
// 9. Get Mieter (Gekündigte) from Mietverhältnis
$mieterBeteiligte = $this->entityManager
->getRepository('CVmhMietverhltnis')
->getRelation($mietverhaeltnis, 'vmhbeteiligtemieter')
->find();
foreach ($mieterBeteiligte as $mieter) {
// Link as Mieter
// Link as Gekündigte
$kuendigungRepo
->getRelation($kuendigung, 'mieter')
->getRelation($kuendigung, 'gekuendigte')
->relate($mieter);
}
// 10. Link Portal Contacts
// 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')
@@ -491,7 +536,7 @@ class CVmhMietverhltnis extends \Espo\Services\Record
->relate($contact);
}
// 11. Commit transaction
// 12. Commit transaction
$this->entityManager->getTransactionManager()->commit();
return [

View File

@@ -293,44 +293,91 @@ class EntityValidator:
"""Prüfe Layout-Dateien auf häufige Fehler."""
print_header("5. LAYOUT-STRUKTUR VALIDIERUNG")
layouts_path = self.metadata_path / "clientDefs"
if not layouts_path.exists():
print_warning("Keine clientDefs gefunden")
return True
layouts_base = self.custom_path / "layouts"
layout_errors = []
layout_warnings = []
checked_layouts = 0
for client_def_file in layouts_path.glob("*.json"):
try:
with open(client_def_file, 'r', encoding='utf-8') as f:
client_def = json.load(f)
# Prüfe auf häufige Layout-Fehler in bottomPanels
bottom_panels = client_def.get('bottomPanelsDetail', {})
for panel_key, panel_def in bottom_panels.items():
checked_layouts += 1
# 1. Prüfe bottomPanelsDetail.json Dateien (KRITISCH: Muss Objekt sein, kein Array!)
if layouts_base.exists():
for bottom_panel_file in layouts_base.rglob("bottomPanelsDetail.json"):
try:
with open(bottom_panel_file, 'r', encoding='utf-8') as f:
content = json.load(f)
# Prüfe auf unnötige false-Elemente
if isinstance(panel_def, dict):
for key, value in panel_def.items():
if value is False and key not in ['disabled', 'sticked']:
layout_errors.append(
f"{client_def_file.stem}: bottomPanelsDetail.{panel_key}.{key} "
f"sollte nicht 'false' sein"
)
except Exception:
pass # JSON-Fehler bereits gemeldet
checked_layouts += 1
entity_name = bottom_panel_file.parent.name
# KRITISCHER CHECK: bottomPanelsDetail.json MUSS Objekt sein (nicht Array)!
if isinstance(content, list):
layout_errors.append(
f"{entity_name}/bottomPanelsDetail.json: FEHLER - Ist Array statt Objekt! "
f"EspoCRM 7.x erfordert Objekt-Format mit Keys wie 'contacts', '_tabBreak_0', etc."
)
elif isinstance(content, dict):
# Prüfe auf false-Werte in falschen Kontexten
for key, value in content.items():
if isinstance(value, dict):
for subkey, subvalue in value.items():
if subvalue is False and subkey not in ['disabled', 'sticked']:
layout_warnings.append(
f"{entity_name}/bottomPanelsDetail.json: {key}.{subkey} "
f"sollte nicht 'false' sein"
)
except Exception:
pass # JSON-Fehler bereits in validate_json_syntax gemeldet
# 2. Prüfe detail.json Dateien auf deprecated false-Platzhalter
if layouts_base.exists():
for detail_file in layouts_base.rglob("detail.json"):
try:
with open(detail_file, 'r', encoding='utf-8') as f:
content = json.load(f)
entity_name = detail_file.parent.name
# Prüfe ob content ein Array von Panels ist
if isinstance(content, list):
for panel_idx, panel in enumerate(content):
if not isinstance(panel, dict):
continue
rows = panel.get('rows', [])
for row_idx, row in enumerate(rows):
if not isinstance(row, list):
continue
for cell_idx, cell in enumerate(row):
# KRITISCH: false als Platzhalter ist deprecated in EspoCRM 7.x!
if cell is False:
layout_errors.append(
f"{entity_name}/detail.json: Panel {panel_idx}, Row {row_idx}, "
f"Cell {cell_idx} verwendet 'false' als Platzhalter. "
f"In EspoCRM 7.x muss '{{}}' (leeres Objekt) verwendet werden!"
)
except Exception:
pass # JSON-Fehler bereits gemeldet
# Ergebnisse ausgeben
if layout_errors:
print_warning(f"{len(layout_errors)} Layout-Strukturprobleme:")
for err in layout_errors[:5]:
print(f" {Colors.YELLOW}{Colors.END} {err}")
if len(layout_errors) > 5:
print(f" {Colors.YELLOW}...{Colors.END} und {len(layout_errors) - 5} weitere")
self.warnings.extend(layout_errors)
else:
print_success(f"{checked_layouts} Layout-Definitionen geprüft")
print_error(f"{len(layout_errors)} KRITISCHE Layout-Fehler gefunden:")
for err in layout_errors:
print(f" {Colors.RED}{Colors.END} {err}")
self.errors.extend(layout_errors)
return False
if layout_warnings:
print_warning(f"{len(layout_warnings)} Layout-Warnungen:")
for warn in layout_warnings[:5]:
print(f" {Colors.YELLOW}{Colors.END} {warn}")
if len(layout_warnings) > 5:
print(f" {Colors.YELLOW}...{Colors.END} und {len(layout_warnings) - 5} weitere")
self.warnings.extend(layout_warnings)
if not layout_errors and not layout_warnings:
print_success(f"{checked_layouts} Layout-Dateien geprüft, keine Fehler")
elif not layout_errors:
print_success(f"{checked_layouts} Layout-Dateien geprüft, keine kritischen Fehler")
return True