From 5171ab775953abf9b6b0236eb41ee5b1b870e4b7 Mon Sep 17 00:00:00 2001 From: Robert M Date: Wed, 8 Dec 2021 15:29:56 +0100 Subject: [PATCH 1/6] add Preis COM --- src/bo4e/com/preis.py | 52 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/bo4e/com/preis.py diff --git a/src/bo4e/com/preis.py b/src/bo4e/com/preis.py new file mode 100644 index 000000000..0a7cc79c0 --- /dev/null +++ b/src/bo4e/com/preis.py @@ -0,0 +1,52 @@ +""" +Contains Preis class +and corresponding marshmallow schema for de-/serialization +""" + +from decimal import Decimal +from typing import Optional + +import attr +from marshmallow import fields, post_load +from marshmallow_enum import EnumField # type:ignore[import] + +from bo4e.com.com import COM, COMSchema +from bo4e.enum.waehrungseinheit import Waehrungseinheit +from bo4e.enum.mengeneinheit import Mengeneinheit +from bo4e.enum.preisstatus import Preisstatus + + +# pylint: disable=too-few-public-methods +@attr.s(auto_attribs=True, kw_only=True) +class Preis(COM): + """ + Abbildung eines Preises mit Wert, Einheit, Bezugswert und Status. + """ + + # required attributes + wert: Decimal = attr.ib(validator=attr.validators.instance_of(Decimal)) + einheit: Waehrungseinheit = attr.ib(validator=attr.validators.in_(Waehrungseinheit)) + bezugswert: Mengeneinheit = attr.ib(validator=attr.validators.in_(Mengeneinheit)) + + # optional attributes + status: Optional[Preisstatus] = attr.ib(default=None, validator=attr.validators.in_(Preisstatus)) + + +class PreisSchema(COMSchema): + """ + Schema for de-/serialization of Preis. + """ + + # required attributes + wert = fields.Decimal() + einheit = EnumField(Waehrungseinheit) + bezugswert = EnumField(Mengeneinheit) + + # optional attributes + status = EnumField(Preisstatus, load_default=None) + + # pylint: disable=no-self-use, unused-argument + @post_load + def deserialize(self, data, **kwargs) -> Preis: + """Deserialize JSON to Preis object""" + return Preis(**data) From a671220943a8f49e34d951c89c245d95e9d42fd3 Mon Sep 17 00:00:00 2001 From: Robert M Date: Wed, 8 Dec 2021 15:54:40 +0100 Subject: [PATCH 2/6] add as_string to optional Decimal --- src/bo4e/com/preis.py | 4 ++-- tests/test_preis.py | 0 2 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 tests/test_preis.py diff --git a/src/bo4e/com/preis.py b/src/bo4e/com/preis.py index 0a7cc79c0..b7eabfde9 100644 --- a/src/bo4e/com/preis.py +++ b/src/bo4e/com/preis.py @@ -29,7 +29,7 @@ class Preis(COM): bezugswert: Mengeneinheit = attr.ib(validator=attr.validators.in_(Mengeneinheit)) # optional attributes - status: Optional[Preisstatus] = attr.ib(default=None, validator=attr.validators.in_(Preisstatus)) + status: Optional[Preisstatus] = attr.ib(default=None) class PreisSchema(COMSchema): @@ -38,7 +38,7 @@ class PreisSchema(COMSchema): """ # required attributes - wert = fields.Decimal() + wert = fields.Decimal(as_string=True) einheit = EnumField(Waehrungseinheit) bezugswert = EnumField(Mengeneinheit) diff --git a/tests/test_preis.py b/tests/test_preis.py new file mode 100644 index 000000000..e69de29bb From 2fa22b98789aebdf26958ceb8aeb68bd4c829635 Mon Sep 17 00:00:00 2001 From: Robert M Date: Wed, 8 Dec 2021 15:54:52 +0100 Subject: [PATCH 3/6] add unittests --- tests/test_preis.py | 56 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/tests/test_preis.py b/tests/test_preis.py index e69de29bb..d3bc922ac 100644 --- a/tests/test_preis.py +++ b/tests/test_preis.py @@ -0,0 +1,56 @@ +from decimal import Decimal + +import pytest # type:ignore[import] + +from bo4e.com.preis import Preis, PreisSchema +from bo4e.enum.waehrungseinheit import Waehrungseinheit +from bo4e.enum.mengeneinheit import Mengeneinheit +from bo4e.enum.preisstatus import Preisstatus + + +class TestPreis: + def test_preis_only_required(self): + """ + Test de-/serialisation of Preis (only has required attributes). + """ + preis = Preis( + wert=Decimal(2.53), einheit=Waehrungseinheit.EUR, bezugswert=Mengeneinheit.KWH + ) + + schema = PreisSchema() + json_string = schema.dumps(preis, ensure_ascii=False) + + assert "KWH" in json_string + assert "EUR" in json_string + assert "null" in json_string + + preis_deserialized = schema.loads(json_string) + + assert isinstance(preis_deserialized.wert, Decimal) + assert isinstance(preis_deserialized.einheit, Waehrungseinheit) + assert isinstance(preis_deserialized.bezugswert, Mengeneinheit) + assert not preis_deserialized.status + + def test_wrong_datatype(self): + with pytest.raises(TypeError) as excinfo: + _ = Preis(wert=3.50, einheit=Waehrungseinheit.EUR, bezugswert=Mengeneinheit.KWH) + + assert "'wert' must be " in str(excinfo.value) + + def test_missing_required_attribute(self): + with pytest.raises(TypeError) as excinfo: + _ = Preis(wert=Decimal(3.50), einheit=Waehrungseinheit.EUR, status=Preisstatus.ENDGUELTIG) + + assert "missing 1 required" in str(excinfo.value) + + def test_optional_attribute(self): + preis = Preis(wert=Decimal(3.50), einheit=Waehrungseinheit.EUR, bezugswert=Mengeneinheit.KWH, status=Preisstatus.ENDGUELTIG) + + schema = PreisSchema() + json_string = schema.dumps(preis, ensure_ascii=False) + + assert "ENDGUELTIG" in json_string + + preis_deserialized = schema.loads(json_string) + + assert isinstance(preis_deserialized.status, Preisstatus) From 1e9756faecc1ce6e158a3043e4ff11910240d793 Mon Sep 17 00:00:00 2001 From: konstantin Date: Wed, 8 Dec 2021 16:01:57 +0100 Subject: [PATCH 4/6] black . --- tests/test_preis.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/test_preis.py b/tests/test_preis.py index d3bc922ac..4e05bd460 100644 --- a/tests/test_preis.py +++ b/tests/test_preis.py @@ -13,9 +13,7 @@ def test_preis_only_required(self): """ Test de-/serialisation of Preis (only has required attributes). """ - preis = Preis( - wert=Decimal(2.53), einheit=Waehrungseinheit.EUR, bezugswert=Mengeneinheit.KWH - ) + preis = Preis(wert=Decimal(2.53), einheit=Waehrungseinheit.EUR, bezugswert=Mengeneinheit.KWH) schema = PreisSchema() json_string = schema.dumps(preis, ensure_ascii=False) @@ -44,7 +42,12 @@ def test_missing_required_attribute(self): assert "missing 1 required" in str(excinfo.value) def test_optional_attribute(self): - preis = Preis(wert=Decimal(3.50), einheit=Waehrungseinheit.EUR, bezugswert=Mengeneinheit.KWH, status=Preisstatus.ENDGUELTIG) + preis = Preis( + wert=Decimal(3.50), + einheit=Waehrungseinheit.EUR, + bezugswert=Mengeneinheit.KWH, + status=Preisstatus.ENDGUELTIG, + ) schema = PreisSchema() json_string = schema.dumps(preis, ensure_ascii=False) From 5d23d5dc15f21d506f8e1f17d6cd39dee82d57d4 Mon Sep 17 00:00:00 2001 From: konstantin Date: Wed, 8 Dec 2021 16:02:10 +0100 Subject: [PATCH 5/6] isort . --- src/bo4e/com/preis.py | 2 +- tests/test_preis.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bo4e/com/preis.py b/src/bo4e/com/preis.py index b7eabfde9..eddc72546 100644 --- a/src/bo4e/com/preis.py +++ b/src/bo4e/com/preis.py @@ -11,9 +11,9 @@ from marshmallow_enum import EnumField # type:ignore[import] from bo4e.com.com import COM, COMSchema -from bo4e.enum.waehrungseinheit import Waehrungseinheit from bo4e.enum.mengeneinheit import Mengeneinheit from bo4e.enum.preisstatus import Preisstatus +from bo4e.enum.waehrungseinheit import Waehrungseinheit # pylint: disable=too-few-public-methods diff --git a/tests/test_preis.py b/tests/test_preis.py index 4e05bd460..056ff162c 100644 --- a/tests/test_preis.py +++ b/tests/test_preis.py @@ -3,9 +3,9 @@ import pytest # type:ignore[import] from bo4e.com.preis import Preis, PreisSchema -from bo4e.enum.waehrungseinheit import Waehrungseinheit from bo4e.enum.mengeneinheit import Mengeneinheit from bo4e.enum.preisstatus import Preisstatus +from bo4e.enum.waehrungseinheit import Waehrungseinheit class TestPreis: From 343d544550d13b2ce13614192bb3ba8afdbeb797 Mon Sep 17 00:00:00 2001 From: rmorlock <54396093+rmorlock@users.noreply.github.com> Date: Wed, 8 Dec 2021 16:25:20 +0100 Subject: [PATCH 6/6] Add docstrings to Preis COM (#237) Co-authored-by: konstantin --- src/bo4e/com/preis.py | 4 ++++ tests/test_preis.py | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/bo4e/com/preis.py b/src/bo4e/com/preis.py index eddc72546..452e0d3bb 100644 --- a/src/bo4e/com/preis.py +++ b/src/bo4e/com/preis.py @@ -24,11 +24,15 @@ class Preis(COM): """ # required attributes + #: Gibt die nomiale Höhe des Preises an. wert: Decimal = attr.ib(validator=attr.validators.instance_of(Decimal)) + #: Währungseinheit für den Preis, z.B. Euro oder Ct. einheit: Waehrungseinheit = attr.ib(validator=attr.validators.in_(Waehrungseinheit)) + #: Angabe, für welche Bezugsgröße der Preis gilt. Z.B. kWh. bezugswert: Mengeneinheit = attr.ib(validator=attr.validators.in_(Mengeneinheit)) # optional attributes + #: Gibt den Status des veröffentlichten Preises an status: Optional[Preisstatus] = attr.ib(default=None) diff --git a/tests/test_preis.py b/tests/test_preis.py index 056ff162c..2cb90848a 100644 --- a/tests/test_preis.py +++ b/tests/test_preis.py @@ -27,7 +27,8 @@ def test_preis_only_required(self): assert isinstance(preis_deserialized.wert, Decimal) assert isinstance(preis_deserialized.einheit, Waehrungseinheit) assert isinstance(preis_deserialized.bezugswert, Mengeneinheit) - assert not preis_deserialized.status + assert preis_deserialized.status is None + assert preis == preis_deserialized def test_wrong_datatype(self): with pytest.raises(TypeError) as excinfo: