diff --git a/src/bo4e/__init__.py b/src/bo4e/__init__.py
index d198e5d8b..32d78d178 100644
--- a/src/bo4e/__init__.py
+++ b/src/bo4e/__init__.py
@@ -13,7 +13,6 @@
"Angebot",
"Ausschreibung",
"Bilanzierung",
- "Buendelvertrag",
"Energiemenge",
"Fremdkosten",
"Geraet",
@@ -95,7 +94,6 @@
"Umschaltzeit",
"Zaehlzeitsaison",
"Zaehlzeittagtyp",
- "Unterschrift",
"Vertragskonditionen",
"Vertragsteil",
"VerwendungszweckProMarktrolle",
@@ -215,7 +213,6 @@
from .bo.angebot import Angebot
from .bo.ausschreibung import Ausschreibung
from .bo.bilanzierung import Bilanzierung
-from .bo.buendelvertrag import Buendelvertrag
from .bo.energiemenge import Energiemenge
from .bo.fremdkosten import Fremdkosten
from .bo.geraet import Geraet
@@ -298,7 +295,6 @@
from .com.tarifpreisposition import Tarifpreisposition
from .com.tarifpreiszeitscheibe import Tarifpreiszeitscheibe
from .com.umschaltzeit import Umschaltzeit
-from .com.unterschrift import Unterschrift
from .com.vertragskonditionen import Vertragskonditionen
from .com.vertragsteil import Vertragsteil
from .com.verwendungszweckpromarktrolle import VerwendungszweckProMarktrolle
diff --git a/src/bo4e/bo/buendelvertrag.py b/src/bo4e/bo/buendelvertrag.py
deleted file mode 100644
index 87334c4be..000000000
--- a/src/bo4e/bo/buendelvertrag.py
+++ /dev/null
@@ -1,76 +0,0 @@
-"""
-Contains Buendelvertrag class
-"""
-
-# pylint: disable=too-few-public-methods
-# pylint: disable=no-name-in-module
-from typing import TYPE_CHECKING, Annotated, Literal, Optional
-
-import pydantic
-from pydantic import Field
-
-from ..enum.botyp import BoTyp
-from ..utils import postprocess_docstring
-from .geschaeftsobjekt import Geschaeftsobjekt
-
-if TYPE_CHECKING:
- from ..com.unterschrift import Unterschrift
- from ..com.vertragskonditionen import Vertragskonditionen
- from ..enum.sparte import Sparte
- from ..enum.vertragsart import Vertragsart
- from ..enum.vertragsstatus import Vertragsstatus
- from .geschaeftspartner import Geschaeftspartner
- from .vertrag import Vertrag
-
-
-@postprocess_docstring
-class Buendelvertrag(Geschaeftsobjekt):
- """
- Abbildung eines Bündelvertrags.
- Es handelt sich hierbei um eine Liste von Einzelverträgen, die in einem Vertragsobjekt gebündelt sind.
-
- .. raw:: html
-
-
-
- .. HINT::
- `Buendelvertrag JSON Schema `_
-
- """
-
- typ: Annotated[Literal[BoTyp.BUENDELVERTRAG], Field(alias="_typ")] = BoTyp.BUENDELVERTRAG
-
- # pylint: disable=duplicate-code
- vertragsnummer: Optional[str] = None
- """Eine im Verwendungskontext eindeutige Nummer für den Vertrag"""
- vertragsart: Optional["Vertragsart"] = None
- """Hier ist festgelegt, um welche Art von Vertrag es sich handelt. Z.B. Netznutzungvertrag"""
- vertragsstatus: Optional["Vertragsstatus"] = None
- """Gibt den Status des Vertrages an"""
- sparte: Optional["Sparte"] = None
- """Unterscheidungsmöglichkeiten für die Sparte"""
- vertragsbeginn: Optional[pydantic.AwareDatetime] = None
- """Gibt an, wann der Vertrag beginnt (inklusiv)"""
- vertragsende: Optional[pydantic.AwareDatetime] = None
- """Gibt an, wann der Vertrag (voraussichtlich) endet oder beendet wurde (exklusiv)"""
- vertragspartner1: Optional["Geschaeftspartner"] = None
- """
- Der "erstgenannte" Vertragspartner. In der Regel der Aussteller des Vertrags.
- Beispiel: "Vertrag zwischen Vertagspartner 1 ..."
- """
- vertragspartner2: Optional["Geschaeftspartner"] = None
- """
- Der "zweitgenannte" Vertragspartner. In der Regel der Empfänger des Vertrags.
- Beispiel "Vertrag zwischen Vertagspartner 1 und Vertragspartner 2"
- """
-
- einzelvertraege: Optional[list["Vertrag"]] = None
- """Die Liste mit den Einzelverträgen zu den Abnahmestellen"""
- vertragskonditionen: Optional[list["Vertragskonditionen"]] = None
- """Festlegungen zu Laufzeiten und Kündigungsfristen"""
- unterzeichnervp1: Optional[list["Unterschrift"]] = None
- """Unterzeichner des Vertragspartners1"""
- unterzeichnervp2: Optional[list["Unterschrift"]] = None
- """Unterzeichner des Vertragspartners2"""
- beschreibung: Optional[str] = None
- """Beschreibung zum Vertrag"""
diff --git a/src/bo4e/bo/vertrag.py b/src/bo4e/bo/vertrag.py
index 9d62ea617..2a7881fae 100644
--- a/src/bo4e/bo/vertrag.py
+++ b/src/bo4e/bo/vertrag.py
@@ -12,13 +12,13 @@
from .geschaeftsobjekt import Geschaeftsobjekt
if TYPE_CHECKING:
- from ..com.unterschrift import Unterschrift
from ..com.vertragskonditionen import Vertragskonditionen
from ..com.vertragsteil import Vertragsteil
from ..enum.sparte import Sparte
from ..enum.vertragsart import Vertragsart
from ..enum.vertragsstatus import Vertragsstatus
from .geschaeftspartner import Geschaeftspartner
+ from .produkt import Produkt
# pylint: disable=unused-argument
# pylint: disable=no-name-in-module
@@ -56,29 +56,31 @@ class Vertrag(Geschaeftsobjekt):
vertragsende: Optional[pydantic.AwareDatetime] = None
"""Gibt an, wann der Vertrag (voraussichtlich) endet oder beendet wurde (exklusiv)"""
# todo: add von/bis validator
- vertragspartner1: Optional["Geschaeftspartner"] = None
+ vertragsaussteller: Optional["Geschaeftspartner"] = None
"""
- Der "erstgenannte" Vertragspartner.
- In der Regel der Aussteller des Vertrags.
- Beispiel: "Vertrag zwischen Vertragspartner 1 ..."
+ Der Aussteller des Vertrags (in der Regel der "erstgenannte" Vertragspartner).
+ Beispiel: "Vertrag zwischen Vertragsaussteller ..."
"""
- vertragspartner2: Optional["Geschaeftspartner"] = None
+ vertragsempfaenger: Optional["Geschaeftspartner"] = None
"""
- Der "zweitgenannte" Vertragspartner.
- In der Regel der Empfänger des Vertrags.
- Beispiel "Vertrag zwischen Vertragspartner 1 und Vertragspartner 2".
+ Der Empfänger des Vertrags (in der Regel der "zweitgenannte" Vertragspartner).
+ Beispiel "Vertrag zwischen Vertragsaussteller und Vertragsempfänger".
"""
vertragsteile: Optional[list["Vertragsteil"]] = None
"""
- Der Vertragsteil wird dazu verwendet, eine vertragliche Leistung in Bezug zu einer Lokation
- (Markt- oder Messlokation) festzulegen.
+ Der Vertragsteil wird dazu verwendet, eine vertragliche Leistung in Bezug zu einer
+ Lokationszuordnung (Markt-, Mess-, Netzlokationen etc.) festzulegen.
"""
beschreibung: Optional[str] = None
"""Beschreibung zum Vertrag"""
vertragskonditionen: Optional["Vertragskonditionen"] = None
"""Festlegungen zu Laufzeiten und Kündigungsfristen"""
- unterzeichnervp1: Optional[list["Unterschrift"]] = None
- """Unterzeichner des Vertragspartners 1"""
- unterzeichnervp2: Optional[list["Unterschrift"]] = None
- """Unterzeichner des Vertragspartners 2"""
+ vertragsabschluss_datum: Optional[pydantic.AwareDatetime] = None
+ """
+ Datum, an dem der Vertrag geschlossen (angenommen und unterschrieben) wurde.
+ """
+ kuendigungsgrund: Optional[str] = None
+ """Grund für die Kündigung des Vertrags"""
+ produkt: Optional["Produkt"] = None
+ """Das dem Vertrag zugrundeliegende Produkt"""
diff --git a/src/bo4e/com/unterschrift.py b/src/bo4e/com/unterschrift.py
deleted file mode 100644
index 4789d492d..000000000
--- a/src/bo4e/com/unterschrift.py
+++ /dev/null
@@ -1,39 +0,0 @@
-"""
-Contains Unterschrift class
-"""
-
-from typing import Annotated, Literal, Optional
-
-import pydantic
-from pydantic import Field
-
-from ..enum.comtyp import ComTyp
-from ..utils import postprocess_docstring
-from .com import COM
-
-# pylint: disable=too-few-public-methods
-
-
-@postprocess_docstring
-class Unterschrift(COM):
- """
- Modellierung einer Unterschrift, z.B. für Verträge, Angebote etc.
-
- .. raw:: html
-
-
-
- .. HINT::
- `Unterschrift JSON Schema `_
-
- """
-
- typ: Annotated[Literal[ComTyp.UNTERSCHRIFT], Field(alias="_typ")] = ComTyp.UNTERSCHRIFT
-
- name: Optional[str] = None
- """Name des Unterschreibers"""
-
- ort: Optional[str] = None
- """Ort, an dem die Unterschrift geleistet wird"""
- datum: Optional[pydantic.AwareDatetime] = None
- """Datum der Unterschrift"""
diff --git a/src/bo4e/com/vertragskonditionen.py b/src/bo4e/com/vertragskonditionen.py
index acb852ca9..7a20272ec 100644
--- a/src/bo4e/com/vertragskonditionen.py
+++ b/src/bo4e/com/vertragskonditionen.py
@@ -2,7 +2,6 @@
Contains Vertragskonditionen class
"""
-from decimal import Decimal
from typing import TYPE_CHECKING, Annotated, Literal, Optional
from pydantic import Field
@@ -38,10 +37,8 @@ class Vertragskonditionen(COM):
"""
Freitext zur Beschreibung der Konditionen, z.B. "Standardkonditionen Gas"
"""
- anzahl_abschlaege: Optional[Decimal] = None
+ anzahl_abschlaege: Optional[int] = None
"""Anzahl der vereinbarten Abschläge pro Jahr, z.B. 12"""
- vertragslaufzeit: Optional["Zeitraum"] = None
- """Über diesen Zeitraum läuft der Vertrag"""
kuendigungsfrist: Optional["Zeitraum"] = None
"""Innerhalb dieser Frist kann der Vertrag gekündigt werden"""
vertragsverlaengerung: Optional["Zeitraum"] = None
diff --git a/src/bo4e/com/vertragsteil.py b/src/bo4e/com/vertragsteil.py
index 9243df22c..6339b887b 100644
--- a/src/bo4e/com/vertragsteil.py
+++ b/src/bo4e/com/vertragsteil.py
@@ -13,6 +13,7 @@
if TYPE_CHECKING:
+ from ..bo.lokationszuordnung import Lokationszuordnung
from .menge import Menge
# pylint: disable=too-few-public-methods
@@ -22,7 +23,7 @@
class Vertragsteil(COM):
"""
Abbildung für einen Vertragsteil. Der Vertragsteil wird dazu verwendet,
- eine vertragliche Leistung in Bezug zu einer Lokation (Markt- oder Messlokation) festzulegen.
+ eine vertragliche Leistung in Bezug zu einer Lokationszuordnung (Markt-, Mess-, Netzlokationen etc.) festzulegen.
.. raw:: html
@@ -44,10 +45,10 @@ class Vertragsteil(COM):
Ende der Gültigkeit des Vertragsteils (exklusiv)
"""
- lokation: Optional[str] = None
+ lokationszuordnung: Optional["Lokationszuordnung"] = None
"""
- Der Identifier für diejenigen Markt- oder Messlokation, die zu diesem Vertragsteil gehören.
- Verträge für mehrere Lokationen werden mit mehreren Vertragsteilen abgebildet
+ Die Lokationszuordnung (Markt-, Mess-, Netzlokationen etc.), die zu diesem Vertragsteil gehört.
+ Verträge für mehrere Lokationen werden mit mehreren Vertragsteilen abgebildet.
"""
vertraglich_fixierte_menge: Optional["Menge"] = None
"""
diff --git a/src/bo4e/enum/botyp.py b/src/bo4e/enum/botyp.py
index afa1e4261..ad990b706 100644
--- a/src/bo4e/enum/botyp.py
+++ b/src/bo4e/enum/botyp.py
@@ -14,7 +14,6 @@ class BoTyp(StrEnum):
ANGEBOT = "ANGEBOT"
AUSSCHREIBUNG = "AUSSCHREIBUNG"
BILANZIERUNG = "BILANZIERUNG"
- BUENDELVERTRAG = "BUENDELVERTRAG"
ENERGIEMENGE = "ENERGIEMENGE"
FREMDKOSTEN = "FREMDKOSTEN"
GERAET = "GERAET"
diff --git a/src/bo4e/enum/comtyp.py b/src/bo4e/enum/comtyp.py
index 71de53fec..21967a6d6 100644
--- a/src/bo4e/enum/comtyp.py
+++ b/src/bo4e/enum/comtyp.py
@@ -58,7 +58,6 @@ class ComTyp(StrEnum):
TARIFPREISPOSITION = "TARIFPREISPOSITION"
TARIFPREISZEITSCHEIBE = "TARIFPREISZEITSCHEIBE"
UMSCHALTZEIT = "UMSCHALTZEIT"
- UNTERSCHRIFT = "UNTERSCHRIFT"
VERTRAGSKONDITIONEN = "VERTRAGSKONDITIONEN"
VERTRAGSTEIL = "VERTRAGSTEIL"
VERWENDUNGSZWECKPROMARKTROLLE = "VERWENDUNGSZWECKPROMARKTROLLE"
diff --git a/src/bo4e/enum/vertragsstatus.py b/src/bo4e/enum/vertragsstatus.py
index c6535647d..84e5c5cb8 100644
--- a/src/bo4e/enum/vertragsstatus.py
+++ b/src/bo4e/enum/vertragsstatus.py
@@ -8,21 +8,11 @@ class Vertragsstatus(StrEnum):
Abbildung einer Statusinformation für Verträge.
"""
- IN_ARBEIT = "IN_ARBEIT"
- """in Arbeit"""
- UEBERMITTELT = "UEBERMITTELT"
- """übermittelt"""
- ANGENOMMEN = "ANGENOMMEN"
- """angenommen"""
AKTIV = "AKTIV"
- """aktiv"""
- ABGELEHNT = "ABGELEHNT"
- """abgelehnt"""
- WIDERRUFEN = "WIDERRUFEN"
- """widerrufen"""
- STORNIERT = "STORNIERT"
- """storniert"""
+ """aktiv; die Beendigung wird über das Vertragsende modelliert"""
GEKUENDIGT = "GEKUENDIGT"
"""gekündigt"""
- BEENDET = "BEENDET"
- """beendet"""
+ STORNIERT = "STORNIERT"
+ """storniert (durch den Vertragsaussteller)"""
+ WIDERRUFEN = "WIDERRUFEN"
+ """widerrufen (durch den Vertragsempfänger)"""
diff --git a/tests/test_adresse.py b/tests/test_adresse.py
index 403bf3829..528b2617c 100644
--- a/tests/test_adresse.py
+++ b/tests/test_adresse.py
@@ -12,7 +12,6 @@
Person,
Sparte,
Titel,
- Unterschrift,
Vertrag,
Vertragsart,
Vertragskonditionen,
@@ -34,7 +33,7 @@ class TestVertrag:
sparte=Sparte.STROM,
vertragsbeginn=datetime(2021, 4, 30, 13, 45, tzinfo=timezone.utc),
vertragsende=datetime(2021, 6, 5, 16, 30, tzinfo=timezone.utc),
- vertragspartner1=Geschaeftspartner(
+ vertragsaussteller=Geschaeftspartner(
ansprechpartner=[Person(), Person()],
anrede=Anrede.EHELEUTE,
individuelle_anrede="Künstler",
@@ -54,7 +53,7 @@ class TestVertrag:
hausnummer="3",
),
),
- vertragspartner2=Geschaeftspartner(
+ vertragsempfaenger=Geschaeftspartner(
ansprechpartner=[Person(), Person()],
organisationstyp=Organisationstyp.UNTERNEHMEN,
organisationsname="Hochfrequenz",
@@ -78,8 +77,6 @@ class TestVertrag:
],
beschreibung="Hello Vertrag",
vertragskonditionen=Vertragskonditionen(beschreibung="Beschreibung"),
- unterzeichnervp1=[Unterschrift(name="Foo")],
- unterzeichnervp2=[Unterschrift(name="Bar"), Unterschrift(name="Dr.No")],
),
),
],
diff --git a/tests/test_buendelvertrag.py b/tests/test_buendelvertrag.py
deleted file mode 100644
index 5fa42d90d..000000000
--- a/tests/test_buendelvertrag.py
+++ /dev/null
@@ -1,43 +0,0 @@
-from datetime import datetime, timezone
-
-import pytest
-
-from bo4e import (
- Buendelvertrag,
- Geschaeftspartner,
- Sparte,
- Unterschrift,
- Vertrag,
- Vertragsart,
- Vertragskonditionen,
- Vertragsstatus,
-)
-from tests.serialization_helper import assert_serialization_roundtrip
-
-
-class TestBuendelvertrag:
- @pytest.mark.parametrize(
- "buendelvertrag",
- [
- pytest.param(
- Buendelvertrag(
- vertragsnummer="1234567890",
- vertragsart=Vertragsart.NETZNUTZUNGSVERTRAG,
- vertragsstatus=Vertragsstatus.AKTIV,
- sparte=Sparte.STROM,
- vertragsbeginn=datetime(2021, 4, 30, 13, 45, tzinfo=timezone.utc),
- vertragsende=datetime(2200, 4, 30, 13, 45, tzinfo=timezone.utc),
- vertragspartner1=Geschaeftspartner(),
- vertragspartner2=Geschaeftspartner(),
- einzelvertraege=[Vertrag()],
- vertragskonditionen=[Vertragskonditionen()],
- unterzeichnervp1=[Unterschrift()],
- unterzeichnervp2=[Unterschrift(), Unterschrift()],
- beschreibung="Das ist ein Bündelvertrag mit allen optionalen Feldern ausgefüllt.",
- ),
- id="all attributes at first level",
- ),
- ],
- )
- def test_serialization_roundtrip(self, buendelvertrag: Buendelvertrag) -> None:
- assert_serialization_roundtrip(buendelvertrag)
diff --git a/tests/test_unterschrift.py b/tests/test_unterschrift.py
deleted file mode 100644
index dbe1d7119..000000000
--- a/tests/test_unterschrift.py
+++ /dev/null
@@ -1,26 +0,0 @@
-from datetime import datetime, timezone
-
-import pytest
-
-from bo4e import Unterschrift
-from tests.serialization_helper import assert_serialization_roundtrip
-
-
-class TestUnterschrift:
- @pytest.mark.parametrize(
- "unterschrift",
- [
- pytest.param(
- Unterschrift(
- name="Foo",
- ort="Grünwald",
- datum=datetime(2019, 6, 7, tzinfo=timezone.utc),
- ),
- ),
- ],
- )
- def test_serialization_roundtrip(self, unterschrift: Unterschrift) -> None:
- """
- Test de-/serialisation of Unterschrift.
- """
- assert_serialization_roundtrip(unterschrift)
diff --git a/tests/test_vertrag.py b/tests/test_vertrag.py
index 0954ae591..a07a23d63 100644
--- a/tests/test_vertrag.py
+++ b/tests/test_vertrag.py
@@ -11,7 +11,6 @@
Person,
Sparte,
Titel,
- Unterschrift,
Vertrag,
Vertragsart,
Vertragskonditionen,
@@ -33,7 +32,7 @@ class TestVertrag:
sparte=Sparte.STROM,
vertragsbeginn=datetime(2021, 4, 30, 13, 45, tzinfo=timezone.utc),
vertragsende=datetime(2021, 6, 5, 16, 30, tzinfo=timezone.utc),
- vertragspartner1=Geschaeftspartner(
+ vertragsaussteller=Geschaeftspartner(
ansprechpartner=[Person(), Person()],
anrede=Anrede.EHELEUTE,
individuelle_anrede="Künstler",
@@ -47,7 +46,7 @@ class TestVertrag:
website="bo4e.de",
geschaeftspartnerrollen=[Geschaeftspartnerrolle.DIENSTLEISTER],
),
- vertragspartner2=Geschaeftspartner(
+ vertragsempfaenger=Geschaeftspartner(
ansprechpartner=[Person(), Person()],
organisationstyp=Organisationstyp.UNTERNEHMEN,
organisationsname="Hochfrequenz",
@@ -65,8 +64,8 @@ class TestVertrag:
],
beschreibung="Hello Vertrag",
vertragskonditionen=Vertragskonditionen(beschreibung="Beschreibung"),
- unterzeichnervp1=[Unterschrift(name="Foo")],
- unterzeichnervp2=[Unterschrift(name="Bar"), Unterschrift(name="Dr.No")],
+ vertragsabschluss_datum=datetime(2021, 4, 30, 13, 45, tzinfo=timezone.utc),
+ kuendigungsgrund="Umzug",
),
),
],
diff --git a/tests/test_vertragskonditionen.py b/tests/test_vertragskonditionen.py
index c3904a5ff..5efd36c5b 100644
--- a/tests/test_vertragskonditionen.py
+++ b/tests/test_vertragskonditionen.py
@@ -1,6 +1,3 @@
-from datetime import datetime, timezone
-from decimal import Decimal
-
import pytest
from bo4e import Mengeneinheit, Vertragskonditionen, Zeitraum
@@ -14,11 +11,7 @@ class TestVertragskonditionen:
pytest.param(
Vertragskonditionen(
beschreibung="Foobar",
- anzahl_abschlaege=Decimal(3),
- vertragslaufzeit=Zeitraum(
- startdatum=datetime(2012, 9, 21, tzinfo=timezone.utc),
- enddatum=datetime(2013, 10, 11, tzinfo=timezone.utc),
- ),
+ anzahl_abschlaege=3,
kuendigungsfrist=Zeitraum(dauer="P3W"),
vertragsverlaengerung=Zeitraum(dauer="P14D"),
abschlagszyklus=Zeitraum(dauer="P5D"),
diff --git a/tests/test_vertragsteil.py b/tests/test_vertragsteil.py
index 2a324630d..6ec03f1d2 100644
--- a/tests/test_vertragsteil.py
+++ b/tests/test_vertragsteil.py
@@ -3,7 +3,7 @@
import pytest
-from bo4e import Menge, Mengeneinheit, Vertragsteil
+from bo4e import Lokationszuordnung, Menge, Mengeneinheit, Vertragsteil
from tests.serialization_helper import assert_serialization_roundtrip
@@ -15,7 +15,7 @@ class TestVertragsteil:
Vertragsteil(
vertragsteilbeginn=datetime(2001, 3, 15, tzinfo=timezone.utc),
vertragsteilende=datetime(2007, 11, 27, tzinfo=timezone.utc),
- lokation="Bar",
+ lokationszuordnung=Lokationszuordnung(),
vertraglich_fixierte_menge=Menge(wert=Decimal(3.1), einheit=Mengeneinheit.KWH),
minimale_abnahmemenge=Menge(wert=Decimal(2000), einheit=Mengeneinheit.KWH),
maximale_abnahmemenge=Menge(wert=Decimal(0.111111), einheit=Mengeneinheit.KWH),