= insert()
:description: Legt ein neues ECM-Objekt an (dms.XMLInsert) und gibt object_id und object_type_id zurück. Für eine vollständige Instanz nach dem Insert: insert_and_get().
:keywords: insert, XMLInsert, object_id, object_type_id, Objekt anlegen, ECMFolderModel, ECMDocumentModel
:page-tags: api, dms

Legt ein neues Objekt auf dem Server an und gibt `(object_id, object_type_id)` zurück. Intern wird `dms.XMLInsert` verwendet. Die übergebene Modell-Instanz wird nicht verändert.

Wird die vollständige Instanz direkt nach dem Anlegen benötigt, ist xref:api/dms/insert_and_get.adoc[insert_and_get()] die kompaktere Alternative.

== Signatur

[tabs]
====
Sync::
+
[source,python]
----
ecm.dms.insert(
    model: T,
    files: list[JobRequestFile] | None = None,
    *,
    folder_id: int | ECMFolderModel | None = None,
    register_id: int | ECMRegisterModel | None = None,
    check_mandatory: bool = True,
) -> tuple[int, int]
----

Async::
+
[source,python]
----
await ecm.dms.insert(
    model: T,
    files: list[JobRequestFile] | None = None,
    *,
    folder_id: int | ECMFolderModel | None = None,
    register_id: int | ECMRegisterModel | None = None,
    check_mandatory: bool = True,
) -> tuple[int, int]
----
====

== Parameter

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

|`model`
|`ECMFolderModel \| ECMRegisterModel \| ECMDocumentModel`
|Die zu erstellende Modell-Instanz mit den gewünschten Feldwerten. Die Instanz wird nicht verändert.

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

|`folder_id`
|`int \| ECMFolderModel \| None`
|Ordner, in dem das Objekt abgelegt wird — entweder eine numerische ID oder eine `ECMFolderModel`-Instanz (deren `id` wird verwendet). Nur für Register und Dokumente gültig. Standard: `None`.

|`register_id`
|`int \| ECMRegisterModel \| None`
|Register, in dem das Dokument abgelegt wird (`ECMDocumentModel`), oder übergeordnetes Register (`ECMRegisterModel`) — entweder als numerische ID oder als `ECMRegisterModel`-Instanz. Standard: `None`.

|`check_mandatory`
|`bool`
|Wenn `True` (Standard), wird clientseitig geprüft, ob alle als `mandatory=True` deklarierten `ECMField`-Felder einen Wert haben. Bei `False` wird die client- und serverseitige Pflichtfeldprüfung deaktiviert (`CHECKOBLIGATION=0`).
|===

== Rückgabewert

`tuple[int, int]` — `(object_id, object_type_id)` des neu erstellten Objekts.

== Ausnahmen

`ECMException`:: Der Server hat den Insert abgelehnt (`ObjectID == -1`).
`ECMMissingArgumentException`:: `folder_id` fehlt bei einem Register- oder Dokument-Modell. Subklasse von `ECMException`.
`TypeError`:: `files` wurde für ein Ordner- oder Register-Modell übergeben.
`ValueError`:: `check_mandatory=True` und ein Pflichtfeld ist nicht gesetzt.

== Beispiele

=== Einfacher Ordner

[tabs]
====
Sync::
+
[source,python]
----
object_id, object_type_id = ecm.dms.insert(
    InvoiceFolder(Title="Rechnung 2024", Year=2024)
)
print(object_id)
----

Async::
+
[source,python]
----
object_id, object_type_id = await ecm.dms.insert(
    InvoiceFolder(Title="Rechnung 2024", Year=2024)
)
print(object_id)
----
====

=== Register in einem Ordner ablegen

[tabs]
====
Sync::
+
[source,python]
----
object_id, _ = ecm.dms.insert(
    InvoiceRegister(Name="Eingangsrechnungen"),
    folder_id=folder.system.id,
)
----

Async::
+
[source,python]
----
object_id, _ = await ecm.dms.insert(
    InvoiceRegister(Name="Eingangsrechnungen"),
    folder_id=folder.system.id,
)
----
====

=== Dokument mit Datei und Ablageort

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

object_id, _ = ecm.dms.insert(
    InvoiceDocument(Title="Rechnung Nr. 42"),
    files=[JobRequestFileFromPath("/tmp/rechnung.pdf")],
    folder_id=folder.system.id,
    register_id=register.system.id,
)
print(object_id)
----

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

object_id, _ = await ecm.dms.insert(
    InvoiceDocument(Title="Rechnung Nr. 42"),
    files=[JobRequestFileFromPath("/tmp/rechnung.pdf")],
    folder_id=folder.system.id,
    register_id=register.system.id,
)
print(object_id)
----
====

=== Modell-Instanz als folder_id / register_id übergeben

Statt einer numerischen ID kann direkt eine Modell-Instanz übergeben werden — `insert()` entnimmt daraus automatisch die ID:

[tabs]
====
Sync::
+
[source,python]
----
folder = ecm.dms.insert_and_get(InvoiceFolder(Title="Rechnung 2024"))
register = ecm.dms.insert_and_get(
    InvoiceRegister(Name="Eingang"),
    folder_id=folder,          # ECMFolderModel-Instanz statt int
)
object_id, _ = ecm.dms.insert(
    InvoiceDocument(Title="Rechnung Nr. 42"),
    folder_id=folder,          # ECMFolderModel-Instanz
    register_id=register,      # ECMRegisterModel-Instanz
)
----

Async::
+
[source,python]
----
folder = await ecm.dms.insert_and_get(InvoiceFolder(Title="Rechnung 2024"))
register = await ecm.dms.insert_and_get(
    InvoiceRegister(Name="Eingang"),
    folder_id=folder,
)
object_id, _ = await ecm.dms.insert(
    InvoiceDocument(Title="Rechnung Nr. 42"),
    folder_id=folder,
    register_id=register,
)
----
====

=== Pflichtfeldprüfung deaktivieren

[tabs]
====
Sync::
+
[source,python]
----
# check_mandatory=False: kein Fehler, auch wenn Pflichtfelder fehlen
object_id, _ = ecm.dms.insert(
    InvoiceFolder(Title="Entwurf"),
    check_mandatory=False,
)
----

Async::
+
[source,python]
----
object_id, _ = await ecm.dms.insert(
    InvoiceFolder(Title="Entwurf"),
    check_mandatory=False,
)
----
====

== Siehe auch

* xref:api/dms/insert_and_get.adoc[insert_and_get()] — kombiniert `insert()` und `get()` in einem Aufruf, wenn die vollständige Instanz benötigt wird
* xref:api/dms/update.adoc[update()] — aktualisiert ein bestehendes Objekt
