= update_and_get()
:description: Aktualisiert ein ECM-Objekt (dms.XMLUpdate) und liest die vollständige aktualisierte Instanz zurück. Kombiniert update() und get() in einem Aufruf.
:keywords: update_and_get, XMLUpdate, Instanz, aktualisieren, Serverfelder, ECMFolderModel
:page-tags: api, dms

Kombiniert xref:api/dms/update.adoc[update()] und xref:api/dms/get.adoc[get()] in einem einzigen Aufruf: Aktualisiert ein bestehendes Objekt und gibt sofort die vollständige, vom Server befüllte Modell-Instanz zurück.

`get()` wird immer ausgeführt — auch wenn `update()` keine Änderungen erkannt hat und der Server-Aufruf übersprungen wurde.

== Signatur

[tabs]
====
Sync::
+
[source,python]
----
ecm.dms.update_and_get(
    model: T,
    files: list[JobRequestFile] | None = None,
    replace_files: bool = True,
    force: bool = False,
    *,
    check_mandatory: bool = True,
    rights: bool = False,
    base_params: bool = False,
    file_properties: bool = False,
    variants: bool = False,
    use_result_list: bool = False,
    fields: list[str | ECMField] | None = None,
) -> T
----

Async::
+
[source,python]
----
await ecm.dms.update_and_get(
    model: T,
    files: list[JobRequestFile] | None = None,
    replace_files: bool = True,
    force: bool = False,
    *,
    check_mandatory: bool = True,
    rights: bool = False,
    base_params: bool = False,
    file_properties: bool = False,
    variants: bool = False,
    use_result_list: bool = False,
    fields: list[str | ECMField] | None = None,
) -> T
----
====

== Parameter

=== Update-Parameter

[cols="1,1,3"]
|===
|Name |Typ |Beschreibung

|`model`
|`ECMFolderModel \| ECMRegisterModel \| ECMDocumentModel`
|Die zu aktualisierende Modell-Instanz. Muss vom Server geladen worden sein, damit `model.system.id` gesetzt ist.

|`files`
|`list[JobRequestFile] \| None`
|Optionale Dateiliste für das Dokument. Nur für `ECMDocumentModel` erlaubt — bei Ordner- oder Register-Modellen wird `TypeError` geworfen. Standard: `None`.

|`replace_files`
|`bool`
|Wenn `True` (Standard) und `files` übergeben wurden, ersetzen die neuen Dateien die vorhandenen Dokumentdateien (`REPLACEFILES=1`). Wenn `False`, werden die Dateien hinzugefügt.

|`force`
|`bool`
|Wenn `True`, wird der Update-Aufruf immer ausgeführt, auch wenn keine Änderungen erkannt wurden. Standard: `False`.

|`check_mandatory`
|`bool`
|Wenn `True` (Standard), wird clientseitig geprüft, ob alle Pflichtfelder gesetzt sind. Bei `False` wird die Pflichtfeldprüfung client- und serverseitig deaktiviert (`CHECKOBLIGATION=0`).
|===

=== Get-Parameter

Die folgenden Parameter werden unverändert an xref:api/dms/get.adoc[get()] weitergeleitet. Detailbeschreibung und Verhalten siehe dort.

[cols="1,1,3"]
|===
|Name |Typ |Kurzübersicht

|`rights`
|`bool`
|Zugriffsrechte mit abrufen (`obj.system.rights`). Standard: `False`.

|`base_params`
|`bool`
|Verwaltungsparameter mit abrufen (`obj.system.base_params`). Standard: `False`.

|`file_properties`
|`bool`
|Datei-Metadaten mit abrufen (`obj.system.file_properties`, nur Dokumente). Standard: `False`.

|`variants`
|`bool`
|W-Modul-Versionsverzweigungen mit abrufen (`obj.system.variants`). Standard: `False`.

|`use_result_list`
|`bool`
|Abrufmodus umschalten (ermöglicht `folder_id`/`register_id` im Ergebnis). Standard: `False`.

|`fields`
|`list[str \| ECMField] \| None`
|Zurückgegebene Felder einschränken. Nur bei `use_result_list=True` wirksam. Standard: `None`.
|===

== Rückgabewert

Eine typisierte Modell-Instanz mit allen vom Server befüllten Feldern (ID, Systemfelder, Indexfelder).

== Ausnahmen

`ValueError`:: `model.system.id` ist `None` oder `check_mandatory=True` und ein Pflichtfeld ist nicht gesetzt.
`TypeError`:: `files` wurde für ein Ordner- oder Register-Modell übergeben.

== Beispiele

=== Einfaches Feldupdate

[tabs]
====
Sync::
+
[source,python]
----
folder = ecm.dms.get(InvoiceFolder, 12345)
folder.Title = "Rechnung 2024 (aktualisiert)"
folder = ecm.dms.update_and_get(folder)
print(folder.system.id, folder.Title)
----

Async::
+
[source,python]
----
folder = await ecm.dms.get(InvoiceFolder, 12345)
folder.Title = "Rechnung 2024 (aktualisiert)"
folder = await ecm.dms.update_and_get(folder)
print(folder.system.id, folder.Title)
----
====

=== Dokument mit Datei ersetzen

[tabs]
====
Sync::
+
[source,python]
----
from ecmind_blue_client.rpc import JobRequestFileFromPath

doc = ecm.dms.get(InvoiceDocument, 42)
doc.Title = "Rechnung Nr. 42 (korrigiert)"
doc = ecm.dms.update_and_get(
    doc,
    files=[JobRequestFileFromPath("/tmp/rechnung_v2.pdf")],
)
print(doc.system.file_properties.extension)  # erfordert file_properties=True
----

Async::
+
[source,python]
----
from ecmind_blue_client.rpc import JobRequestFileFromPath

doc = await ecm.dms.get(InvoiceDocument, 42)
doc.Title = "Rechnung Nr. 42 (korrigiert)"
doc = await ecm.dms.update_and_get(
    doc,
    files=[JobRequestFileFromPath("/tmp/rechnung_v2.pdf")],
)
----
====

=== Mit Metadaten aus get()

Die `rights`-, `base_params`- und `file_properties`-Parameter verhalten sich identisch zu xref:api/dms/get.adoc[get()]:

[tabs]
====
Sync::
+
[source,python]
----
doc = ecm.dms.get(InvoiceDocument, 42)
doc.Title = "Rechnung Nr. 42 (korrigiert)"
doc = ecm.dms.update_and_get(
    doc,
    files=[JobRequestFileFromPath("/tmp/rechnung_v2.pdf")],
    rights=True,
    base_params=True,
    file_properties=True,
)
print(doc.system.rights.edit_metadata)
print(doc.system.base_params.creator)
print(doc.system.file_properties.extension)
----

Async::
+
[source,python]
----
doc = await ecm.dms.get(InvoiceDocument, 42)
doc.Title = "Rechnung Nr. 42 (korrigiert)"
doc = await ecm.dms.update_and_get(
    doc,
    files=[JobRequestFileFromPath("/tmp/rechnung_v2.pdf")],
    rights=True,
    base_params=True,
    file_properties=True,
)
print(doc.system.rights.edit_metadata)
print(doc.system.base_params.creator)
print(doc.system.file_properties.extension)
----
====

=== Ablageort aus dem Ergebnis lesen (use_result_list)

`folder_id` und `register_id` im Ergebnis sind nur mit `use_result_list=True` verfügbar — siehe xref:api/dms/get.adoc#_abrufmodi[Abrufmodi in get()]:

[tabs]
====
Sync::
+
[source,python]
----
doc = ecm.dms.get(InvoiceDocument, 42)
doc.Title = "Rechnung Nr. 42 (aktualisiert)"
doc = ecm.dms.update_and_get(doc, use_result_list=True)
print(doc.system.folder_id)
print(doc.system.register_id)
----

Async::
+
[source,python]
----
doc = await ecm.dms.get(InvoiceDocument, 42)
doc.Title = "Rechnung Nr. 42 (aktualisiert)"
doc = await ecm.dms.update_and_get(doc, use_result_list=True)
print(doc.system.folder_id)
print(doc.system.register_id)
----
====

== Siehe auch

* xref:api/dms/update.adoc[update()] — aktualisiert ein Objekt, ohne es zurückzugeben
* xref:api/dms/insert_and_get.adoc[insert_and_get()] — entsprechendes Muster für das Anlegen neuer Objekte
* xref:api/dms/get.adoc[get()] — lädt ein einzelnes Objekt vom Server
