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
40 changes: 40 additions & 0 deletions docs/api/bo4e.com.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,22 @@ bo4e.com.adresse module
:undoc-members:
:show-inheritance:

bo4e.com.angebotsposition module
--------------------------------

.. automodule:: bo4e.com.angebotsposition
:members:
:undoc-members:
:show-inheritance:

bo4e.com.aufabschlagproort module
---------------------------------

.. automodule:: bo4e.com.aufabschlagproort
:members:
:undoc-members:
:show-inheritance:

bo4e.com.aufabschlagstaffelproort module
----------------------------------------

Expand Down Expand Up @@ -140,6 +156,14 @@ bo4e.com.preisgarantie module
:undoc-members:
:show-inheritance:

bo4e.com.regionalegueltigkeit module
------------------------------------

.. automodule:: bo4e.com.regionalegueltigkeit
:members:
:undoc-members:
:show-inheritance:

bo4e.com.regionskriterium module
--------------------------------

Expand All @@ -164,6 +188,14 @@ bo4e.com.sigmoidparameter module
:undoc-members:
:show-inheritance:

bo4e.com.standorteigenschaftenallgemein module
----------------------------------------------

.. automodule:: bo4e.com.standorteigenschaftenallgemein
:members:
:undoc-members:
:show-inheritance:

bo4e.com.standorteigenschaftengas module
----------------------------------------

Expand Down Expand Up @@ -236,6 +268,14 @@ bo4e.com.zeitraum module
:undoc-members:
:show-inheritance:

bo4e.com.zeitreihenwert module
------------------------------

.. automodule:: bo4e.com.zeitreihenwert
:members:
:undoc-members:
:show-inheritance:

bo4e.com.zeitreihenwertkompakt module
-------------------------------------

Expand Down
11 changes: 11 additions & 0 deletions docs/api/bo4e.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,17 @@ Subpackages
bo4e.enum
bo4e.schemata

Submodules
----------

bo4e.validators module
----------------------

.. automodule:: bo4e.validators
:members:
:undoc-members:
:show-inheritance:

Module contents
---------------

Expand Down
52 changes: 52 additions & 0 deletions src/bo4e/com/aufabschlagproort.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""
Contains AufAbschlagProOrt class
and corresponding marshmallow schema for de-/serialization
"""

from typing import List

import attr
from marshmallow import fields, post_load

from bo4e.com.aufabschlagstaffelproort import AufAbschlagstaffelProOrt, AufAbschlagstaffelProOrtSchema
from bo4e.com.com import COM, COMSchema
from bo4e.validators import check_list_length_at_least_one


# pylint: disable=too-few-public-methods
@attr.s(auto_attribs=True, kw_only=True)
class AufAbschlagProOrt(COM):
"""
Mit dieser Komponente können Auf- und Abschläge verschiedener Typen im Zusammenhang
mit örtlichen Gültigkeiten abgebildet werden.
"""

# required attributes
#: Die Postleitzahl des Ortes für den der Aufschlag gilt.
postleitzahl: str = attr.ib(validator=attr.validators.instance_of(str))
#: Der Ort für den der Aufschlag gilt.
ort: str = attr.ib(validator=attr.validators.instance_of(str))
#: Die ene't-Netznummer des Netzes in dem der Aufschlag gilt.
netznr: str = attr.ib(validator=attr.validators.instance_of(str))
#: Werte für die gestaffelten Auf/Abschläge mit regionaler Eingrenzung.
staffeln: List[AufAbschlagstaffelProOrt] = attr.ib(
validator=[attr.validators.instance_of(List), check_list_length_at_least_one]
)


class AufAbschlagProOrtSchema(COMSchema):
"""
Schema for de-/serialization of AufAbschlagProOrt.
"""

# required attributes
postleitzahl = fields.Str()
ort = fields.Str()
netznr = fields.Str()
staffeln = fields.List(fields.Nested(AufAbschlagstaffelProOrtSchema))

# pylint: disable=no-self-use, unused-argument
@post_load
def deserialize(self, data, **kwargs) -> AufAbschlagProOrt:
"""Deserialize JSON to AufAbschlagstaffelProOrt object"""
return AufAbschlagProOrt(**data)
14 changes: 4 additions & 10 deletions src/bo4e/com/energiemix.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from bo4e.enum.oekolabel import Oekolabel
from bo4e.enum.oekozertifikat import Oekozertifikat
from bo4e.enum.sparte import Sparte
from bo4e.validators import check_list_length_at_least_one


# pylint: disable=too-few-public-methods, too-many-instance-attributes
Expand All @@ -34,16 +35,9 @@ class Energiemix(COM):
#: Jahr, für das der Energiemix gilt
gueltigkeitsjahr: int = attr.ib(validator=attr.validators.instance_of(int))
#: Anteile der jeweiligen Erzeugungsart
anteil: List[Energieherkunft] = attr.ib(validator=attr.validators.instance_of(List))

@anteil.validator
# pylint: disable=unused-argument, no-self-use
def check_list_length(self, attribute, value):
"""
Check that minimal list length is at least one.
"""
if len(value) < 1:
raise ValueError("anteil must not be empty.")
anteil: List[Energieherkunft] = attr.ib(
validator=[attr.validators.instance_of(List), check_list_length_at_least_one]
)

# optional attributes
#: Bemerkung zum Energiemix
Expand Down
11 changes: 11 additions & 0 deletions src/bo4e/validators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"""
Contains validators for BO s and COM s classes.
"""

# pylint: disable=unused-argument
def check_list_length_at_least_one(instance, attribute, value):
"""
Check that minimal list length is at least one.
"""
if len(value) < 1:
raise ValueError(f"List {attribute.name} must not be empty.")
63 changes: 63 additions & 0 deletions tests/test_aufabschlagproort.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
from decimal import Decimal

import pytest # type:ignore[import]

from bo4e.com.aufabschlagproort import AufAbschlagProOrt, AufAbschlagProOrtSchema
from bo4e.com.aufabschlagstaffelproort import AufAbschlagstaffelProOrt
from tests.serialization_helper import assert_serialization_roundtrip # type:ignore[import]


class TestAufAbschlagProOrt:
@pytest.mark.parametrize(
"aufabschlagproort, expected_json_dict",
[
pytest.param(
AufAbschlagProOrt(
postleitzahl="01187",
ort="Dresden",
netznr="2",
staffeln=[
AufAbschlagstaffelProOrt(
wert=Decimal(2.5),
staffelgrenze_von=Decimal(1),
staffelgrenze_bis=Decimal(5),
)
],
),
{
"postleitzahl": "01187",
"ort": "Dresden",
"netznr": "2",
"staffeln": [
{
"wert": "2.5",
"staffelgrenzeVon": "1",
"staffelgrenzeBis": "5",
}
],
},
)
],
)
def test_serialization_roundtrip(self, aufabschlagproort, expected_json_dict):
"""
Test de-/serialisation of AufAbschlagProOrt with minimal attributes.
"""
assert_serialization_roundtrip(aufabschlagproort, AufAbschlagProOrtSchema(), expected_json_dict)

def test_missing_required_attribute(self):
with pytest.raises(TypeError) as excinfo:
_ = AufAbschlagProOrt()

assert "missing 4 required" in str(excinfo.value)

def test_failing_validation_list_length_at_least_one(self):
with pytest.raises(ValueError) as excinfo:
_ = AufAbschlagProOrt(
postleitzahl="01187",
ort="Dresden",
netznr="2",
staffeln=[],
)

assert "List staffeln must not be empty." in str(excinfo.value)
2 changes: 1 addition & 1 deletion tests/test_energiemix.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,4 @@ def test_energiemix_anteil_required(self):
anteil=[],
)

assert "anteil must not be empty." in str(excinfo.value)
assert "List anteil must not be empty." in str(excinfo.value)