Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions src/bo4e/bo/fremdkosten.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
"""
Contains Fremdkosten class and corresponding marshmallow schema for de-/serialization
"""
from typing import List, Optional

import attr
from marshmallow import fields

from bo4e.bo.geschaeftsobjekt import Geschaeftsobjekt, GeschaeftsobjektSchema
from bo4e.com.betrag import Betrag, BetragSchema
from bo4e.com.fremdkostenblock import Fremdkostenblock, FremdkostenblockSchema
from bo4e.com.zeitraum import Zeitraum, ZeitraumSchema
from bo4e.enum.botyp import BoTyp


# pylint: disable=too-few-public-methods
@attr.s(auto_attribs=True, kw_only=True)
class Fremdkosten(Geschaeftsobjekt):
"""
Mit diesem BO werden die Fremdkosten, beispielsweise für eine Angebotserstellung oder eine Rechnungsprüfung,
übertragen.
Die Fremdkosten enthalten dabei alle Kostenblöcke, die von anderen Marktteilnehmern oder Instanzen erhoben werden.
"""

# required attributes
bo_typ: BoTyp = attr.ib(default=BoTyp.FREMDKOSTEN)
#: Für diesen Zeitraum wurden die Kosten ermittelt
gueltigkeit: Zeitraum = attr.ib(validator=attr.validators.instance_of(Zeitraum))
# optional attributes
#: Die Gesamtsumme über alle Kostenblöcke und -positionen
summe_kosten: Optional[Betrag] = attr.ib(
validator=attr.validators.optional(attr.validators.instance_of(Betrag)), default=None
)
#: In Kostenblöcken werden Kostenpositionen zusammengefasst. Beispiele: Netzkosten, Umlagen, Steuern etc
kostenbloecke: Optional[List[Fremdkostenblock]] = attr.ib(
default=None,
validator=attr.validators.optional(
attr.validators.deep_iterable(
member_validator=attr.validators.instance_of(Fremdkostenblock),
iterable_validator=attr.validators.instance_of(list),
)
),
)


class FremdkostenSchema(GeschaeftsobjektSchema):
"""
Schema for de-/serialization of Fremdkosten
"""

class_name = Fremdkosten
# required attributes
gueltigkeit = fields.Nested(ZeitraumSchema)

# optional attributes
summe_kosten = fields.Nested(BetragSchema, load_default=None)
kostenbloecke = fields.List(fields.Nested(FremdkostenblockSchema), load_default=None)
1 change: 1 addition & 0 deletions src/bo4e/enum/botyp.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class BoTyp(StrEnum):
AUSSCHREIBUNG = "AUSSCHREIUNG"
BUENDELVERTRAG = "BUENDELVERTRAG"
ENERGIEMENGE = "ENERGIEMENGE"
FREMDKOSTEN = "FREMDKOSTEN"
# It is practical to use the BoTyp Enum as discriminator in the database.
# Therefore, we added one additional entry for GESCHAEFTSOBJEKT
# This is not defined by the documentation!
Expand Down
32 changes: 32 additions & 0 deletions tests/test_fremdkosten.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import pytest # type:ignore[import]

from bo4e.bo.fremdkosten import Fremdkosten, FremdkostenSchema
from bo4e.com.fremdkostenblock import Fremdkostenblock
from tests.serialization_helper import assert_serialization_roundtrip # type:ignore[import]
from tests.test_betrag import example_betrag # type:ignore[import]
from tests.test_zeitraum import example_zeitraum # type:ignore[import]


class TestFremdkosten:
@pytest.mark.parametrize(
"fremdkosten",
[
pytest.param(
Fremdkosten(
gueltigkeit=example_zeitraum,
summe_kosten=example_betrag,
kostenbloecke=[Fremdkostenblock(kostenblockbezeichnung="teststring")],
)
),
],
)
def test_serialization_roundtrip(self, fremdkosten: Fremdkosten):
"""
Test de-/serialisation
"""
assert_serialization_roundtrip(fremdkosten, FremdkostenSchema())

def test_missing_required_attribute(self):
with pytest.raises(TypeError) as excinfo:
_ = Fremdkosten()
assert "missing 1 required" in str(excinfo.value)