diff --git a/poetry.lock b/poetry.lock index 50c8359..f3e703f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1523,6 +1523,52 @@ files = [ {file = "fqdn-1.5.1.tar.gz", hash = "sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f"}, ] +[[package]] +name = "frozendict" +version = "2.3.8" +description = "A simple immutable dictionary" +optional = false +python-versions = ">=3.6" +files = [ + {file = "frozendict-2.3.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d188d062084fba0e4bf32719ff7380b26c050b932ff164043ce82ab90587c52b"}, + {file = "frozendict-2.3.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f2a4e818ac457f6354401dcb631527af25e5a20fcfc81e6b5054b45fc245caca"}, + {file = "frozendict-2.3.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9a506d807858fa961aaa5b48dab6154fdc6bd045bbe9310788bbff141bb42d13"}, + {file = "frozendict-2.3.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:750632cc890d8ee9484fe6d31b261159144b6efacc08e1317fe46accd1410373"}, + {file = "frozendict-2.3.8-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7ee5fe2658a8ac9a57f748acaf563f6a47f80b8308cbf0a04fac0ba057d41f75"}, + {file = "frozendict-2.3.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23c4bb46e6b8246e1e7e49b5593c2bc09221db0d8f31f7c092be8dfb42b9e620"}, + {file = "frozendict-2.3.8-cp310-cp310-win_amd64.whl", hash = "sha256:c31abc8acea309b132dde441856829f6003a3d242da8b54bce4c0f2a3c8c63f0"}, + {file = "frozendict-2.3.8-cp310-cp310-win_arm64.whl", hash = "sha256:9ea5520e85447ff8d4681e181941e482662817ccba921b7cb3f87922056d892a"}, + {file = "frozendict-2.3.8-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f83fed36497af9562ead5e9fb8443224ba2781786bd3b92b1087cb7d0ff20135"}, + {file = "frozendict-2.3.8-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27c5c1d29d0eda7979253ec88abc239da1313b38f39f4b16984db3b3e482300"}, + {file = "frozendict-2.3.8-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4c785de7f1a13f15963945f400656b18f057c2fc76c089dacf127a2bb188c03"}, + {file = "frozendict-2.3.8-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:8cf35ddd25513428ec152614def9696afb93ae5ec0eb54fa6aa6206eda77ac4c"}, + {file = "frozendict-2.3.8-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:ffc684773de7c88724788fa9787d0016fd75830412d58acbd9ed1a04762c675b"}, + {file = "frozendict-2.3.8-cp36-cp36m-win_amd64.whl", hash = "sha256:4c258aab9c8488338634f2ec670ef049dbf0ab0e7a2fa9bc2c7b5009cb614801"}, + {file = "frozendict-2.3.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:47fc26468407fdeb428cfc89495b7921419e670355c21b383765482fdf6c5c14"}, + {file = "frozendict-2.3.8-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ea638228692db2bf94bce40ea4b25f4077588497b516bd16576575560094bd9"}, + {file = "frozendict-2.3.8-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a75bf87e76c4386caecdbdd02a99e53ad43a6b5c38fb3d5a634a9fc9ce41462"}, + {file = "frozendict-2.3.8-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ed5a6c5c7a0f57269577c2a338a6002949aea21a23b7b7d06da7e7dced8b605b"}, + {file = "frozendict-2.3.8-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d086440328a465dea9bef2dbad7548d75d1a0a0d21f43a08c03e1ec79ac5240e"}, + {file = "frozendict-2.3.8-cp37-cp37m-win_amd64.whl", hash = "sha256:0bc4767e2f83db5b701c787e22380296977368b0c57e485ca71b2eedfa11c4a3"}, + {file = "frozendict-2.3.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:638cf363d3cbca31a341503cf2219eac52a5f5140449676fae3d9644cd3c5487"}, + {file = "frozendict-2.3.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2b2fd8ce36277919b36e3c834d2389f3cd7ac068ae730c312671dd4439a5dd65"}, + {file = "frozendict-2.3.8-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3957d52f1906b0c85f641a1911d214255873f6408ab4e5ad657cc27a247fb145"}, + {file = "frozendict-2.3.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72cfe08ab8ae524e54848fa90b22d02c1b1ecfb3064438696bcaa4b953f18772"}, + {file = "frozendict-2.3.8-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4742e76c4111bd09198d3ab66cef94be8506212311338f9182d6ef5f5cb60493"}, + {file = "frozendict-2.3.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:313ed8d9ba6bac35d7635cd9580ee5721a0fb016f4d2d20f0efa05dbecbdb1be"}, + {file = "frozendict-2.3.8-cp38-cp38-win_amd64.whl", hash = "sha256:d3c6ce943946c2a61501c8cf116fff0892d11dd579877eb36e2aea2c27fddfef"}, + {file = "frozendict-2.3.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f0f573dc4861dd7ec9e055c8cceaf45355e894e749f621f199aab7b311ac4bdb"}, + {file = "frozendict-2.3.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2b3435e5f1ca5ae68a5e95e64b09d6d5c645cadd6b87569a0b3019dd248c8d00"}, + {file = "frozendict-2.3.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:145afd033ebfade28416093335261b8ec1af5cccc593482309e7add062ec8668"}, + {file = "frozendict-2.3.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da98427de26b5a2865727947480cbb53860089c4d195baa29c539da811cea617"}, + {file = "frozendict-2.3.8-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5e82befa7c385a668d569cebbebbdf49cee6fea4083f08e869a1b08cfb640a9f"}, + {file = "frozendict-2.3.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:80abe81d36e889ceec665e06ec764a7638000fa3e7be09786ac4d3ddc64b76db"}, + {file = "frozendict-2.3.8-cp39-cp39-win_amd64.whl", hash = "sha256:8ccc94ac781710db44e142e1a11ff9b31d02c032c01c6868d51fcbef73086225"}, + {file = "frozendict-2.3.8-cp39-cp39-win_arm64.whl", hash = "sha256:e72dbc1bcc2203cef38d205f692396f5505921a5680f66aa9a7e8bb71fd38f28"}, + {file = "frozendict-2.3.8-py311-none-any.whl", hash = "sha256:ba41a7ed019bd03b62d63ed3f8dea35b8243d1936f7c9ed4b5298ca45a01928e"}, + {file = "frozendict-2.3.8.tar.gz", hash = "sha256:5526559eca8f1780a4ee5146896f59afc31435313560208dd394a3a5e537d3ff"}, +] + [[package]] name = "future" version = "0.18.3" @@ -1810,13 +1856,13 @@ test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio" [[package]] name = "ipython" -version = "8.16.0" +version = "8.16.1" description = "IPython: Productive Interactive Computing" optional = false python-versions = ">=3.9" files = [ - {file = "ipython-8.16.0-py3-none-any.whl", hash = "sha256:dba644376826a532e362da945a672865be7efda76ecf999219e6021bda85d702"}, - {file = "ipython-8.16.0.tar.gz", hash = "sha256:7a1b2e1e6a3ec5baa466163c451335081f31859883889ff0289c6b21f7a095e2"}, + {file = "ipython-8.16.1-py3-none-any.whl", hash = "sha256:0852469d4d579d9cd613c220af7bf0c9cc251813e12be647cb9d463939db9b1e"}, + {file = "ipython-8.16.1.tar.gz", hash = "sha256:ad52f58fca8f9f848e256c629eff888efc0528c12fe0f8ec14f33205f23ef938"}, ] [package.dependencies] @@ -1905,13 +1951,13 @@ files = [ [[package]] name = "jedi" -version = "0.19.0" +version = "0.19.1" description = "An autocompletion tool for Python that can be used for text editors." optional = false python-versions = ">=3.6" files = [ - {file = "jedi-0.19.0-py2.py3-none-any.whl", hash = "sha256:cb8ce23fbccff0025e9386b5cf85e892f94c9b822378f8da49970471335ac64e"}, - {file = "jedi-0.19.0.tar.gz", hash = "sha256:bcf9894f1753969cbac8022a8c2eaee06bfa3724e4192470aaffe7eb6272b0c4"}, + {file = "jedi-0.19.1-py2.py3-none-any.whl", hash = "sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0"}, + {file = "jedi-0.19.1.tar.gz", hash = "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd"}, ] [package.dependencies] @@ -1920,7 +1966,7 @@ parso = ">=0.8.3,<0.9.0" [package.extras] docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alabaster (==0.7.12)", "babel (==2.9.1)", "chardet (==4.0.0)", "commonmark (==0.8.1)", "docutils (==0.17.1)", "future (==0.18.2)", "idna (==2.10)", "imagesize (==1.2.0)", "mock (==1.0.1)", "packaging (==20.9)", "pyparsing (==2.4.7)", "pytz (==2021.1)", "readthedocs-sphinx-ext (==2.1.4)", "recommonmark (==0.5.0)", "requests (==2.25.1)", "six (==1.15.0)", "snowballstemmer (==2.1.0)", "sphinx (==1.8.5)", "sphinx-rtd-theme (==0.4.3)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"] qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] -testing = ["Django (<3.1)", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] +testing = ["Django", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] [[package]] name = "jinja2" @@ -3605,13 +3651,13 @@ testing = ["aboutcode-toolkit (>=6.0.0)", "black", "pytest (>=6,!=7.0.0)", "pyte [[package]] name = "platformdirs" -version = "3.10.0" +version = "3.11.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." optional = false python-versions = ">=3.7" files = [ - {file = "platformdirs-3.10.0-py3-none-any.whl", hash = "sha256:d7c24979f292f916dc9cbf8648319032f551ea8c49a4c9bf2fb556a02070ec1d"}, - {file = "platformdirs-3.10.0.tar.gz", hash = "sha256:b45696dab2d7cc691a3226759c0d3b00c47c8b6e293d96f6436f733303f77f6d"}, + {file = "platformdirs-3.11.0-py3-none-any.whl", hash = "sha256:e9d171d00af68be50e9202731309c4e658fd8bc76f55c11c7dd760d023bda68e"}, + {file = "platformdirs-3.11.0.tar.gz", hash = "sha256:cf8ee52a3afdb965072dcc652433e0c7e3e40cf5ea1477cd4b3b1d2eb75495b3"}, ] [package.extras] @@ -4205,13 +4251,13 @@ dev = ["pre-commit", "pytest-asyncio", "tox"] [[package]] name = "pytest-repeat" -version = "0.9.1" +version = "0.9.2" description = "pytest plugin for repeating tests" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.7" files = [ - {file = "pytest-repeat-0.9.1.tar.gz", hash = "sha256:5cd3289745ab3156d43eb9c8e7f7d00a926f3ae5c9cf425bec649b2fe15bad5b"}, - {file = "pytest_repeat-0.9.1-py2.py3-none-any.whl", hash = "sha256:4474a7d9e9137f6d8cc8ae297f8c4168d33c56dd740aa78cfffe562557e6b96e"}, + {file = "pytest-repeat-0.9.2.tar.gz", hash = "sha256:79673445ae99aee333b811c7d0037aeb408f933b8898375ff2f4fff1e3ba686b"}, + {file = "pytest_repeat-0.9.2-py3-none-any.whl", hash = "sha256:05782f82b328311551c5929c50430e9103fed562354707db8511c392e8c798d0"}, ] [package.dependencies] @@ -4929,23 +4975,24 @@ testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jar [[package]] name = "setuptools-scm" -version = "8.0.3" +version = "8.0.4" description = "the blessed package to manage your versions by scm tags" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-scm-8.0.3.tar.gz", hash = "sha256:0169fd70197efda2f8c4d0b2a7a3d614431b488116f37b79d031e9e7ec884d8c"}, - {file = "setuptools_scm-8.0.3-py3-none-any.whl", hash = "sha256:813822234453438a13c78d05c8af29918fbc06f88efb33d38f065340bbb48c39"}, + {file = "setuptools-scm-8.0.4.tar.gz", hash = "sha256:b5f43ff6800669595193fd09891564ee9d1d7dcb196cab4b2506d53a2e1c95c7"}, + {file = "setuptools_scm-8.0.4-py3-none-any.whl", hash = "sha256:b47844cd2a84b83b3187a5782c71128c28b4c94cad8bfb871da2784a5cb54c4f"}, ] [package.dependencies] packaging = ">=20" setuptools = "*" +typing-extensions = "*" [package.extras] docs = ["entangled-cli[rich]", "mkdocs", "mkdocs-entangled-plugin", "mkdocs-material", "mkdocstrings[python]", "pygments"] rich = ["rich"] -test = ["pytest", "rich", "virtualenv (>20)"] +test = ["build", "pytest", "rich", "wheel"] [[package]] name = "shapely" @@ -5947,4 +5994,4 @@ web-server = ["dash", "dash-auth", "dash-bootstrap-components", "matplotlib", "s [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "765464a1fd45dac750e329972ffbedfc44a11b7e43e718153fdb9304a52f9293" +content-hash = "54b48197ec857377c4cbb8a122f7dc76cc714bb437c31631984caa44f3adb943" diff --git a/pyproject.toml b/pyproject.toml index ac9478e..f207b42 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,6 +55,7 @@ dash = "^2.13.0" dash-auth = "^2.0.0" dash-bootstrap-components = "^1.5.0" deutschland = {git = "https://github.com/TrisNol/deutschland.git", branch = "hotfix/python-3.11-support"} +frozendict = "^2.3.8" loguru = "^0.7.0" matplotlib = "^3.7.2" pgeocode = "^0.4.1" diff --git a/src/aki_prj23_transparenzregister/models/company.py b/src/aki_prj23_transparenzregister/models/company.py index 6cadbdc..3ad0591 100644 --- a/src/aki_prj23_transparenzregister/models/company.py +++ b/src/aki_prj23_transparenzregister/models/company.py @@ -1,6 +1,6 @@ """Company model.""" from dataclasses import asdict, dataclass -from enum import Enum +from enum import Enum, StrEnum from aenum import MultiValueEnum @@ -95,8 +95,8 @@ class Location: zip_code: str | None = None -class CompanyRelationshipEnum(str, Enum): - """Type of companyrelations.""" +class CompanyRelationshipEnum(StrEnum): + """Type of company-relations.""" PERSON = "Person" COMPANY = "Company" @@ -182,12 +182,12 @@ class YearlyResult: class CurrencyEnum(str, MultiValueEnum): """Enum of possible currencies.""" - EURO = "EUR" + EURO = "EUR", "€" DEUTSCHE_MARK = "DM", "DEM" KEINE_ANGABE = "" -class CapitalTypeEnum(str, Enum): +class CapitalTypeEnum(StrEnum): """Enum of possible capital types.""" HAFTEINLAGE = "Hafteinlage" diff --git a/src/aki_prj23_transparenzregister/utils/data_transfer.py b/src/aki_prj23_transparenzregister/utils/data_transfer.py index 42c754e..7892815 100644 --- a/src/aki_prj23_transparenzregister/utils/data_transfer.py +++ b/src/aki_prj23_transparenzregister/utils/data_transfer.py @@ -1,16 +1,18 @@ """This module contains the data transfer and refinement functionalities between staging and production DB.""" from datetime import date from functools import lru_cache -from typing import Any +from typing import Any, Final, Literal import pgeocode import sqlalchemy as sa from cachetools import LRUCache, cached +from frozendict import frozendict from loguru import logger from sqlalchemy.orm import Session from tqdm import tqdm from aki_prj23_transparenzregister.config.config_providers import JsonFileConfigProvider +from aki_prj23_transparenzregister.models.company import CapitalTypeEnum, CurrencyEnum from aki_prj23_transparenzregister.utils.enum_types import RelationTypeEnum from aki_prj23_transparenzregister.utils.logger_config import configer_logger from aki_prj23_transparenzregister.utils.mongo.company_mongo_service import ( @@ -196,6 +198,40 @@ def get_company_id( return company_id +CURRENCY_CONVERSION_DICT: Final[frozendict[CurrencyEnum, float]] = frozendict( + {CurrencyEnum("DM"): 1.95583, CurrencyEnum("EUR"): 1} +) + + +def norm_capital( + capital: dict[Literal["value", "currency", "type"], Any] +) -> dict[ + Literal["capital_value", "capital_currency", "capital_type"], + CurrencyEnum | float | CapitalTypeEnum, +]: + """Changes the value of the currency from DM to EUR to be better comparable. + + Args: + capital: The capital a company has to be normed by currency value. + + Returns: + A normed version of the currency. + """ + if len(capital) != 3: # noqa: PLR2004 + logger.warning("The capital isn't formatted as expected. Look into that.") + return {} + + return { + "capital_value": round( + capital["value"] + / CURRENCY_CONVERSION_DICT[CurrencyEnum(capital["currency"])], + 2, + ), + "capital_currency": CurrencyEnum(capital["currency"]), + "capital_type": CapitalTypeEnum(capital["type"]), + } + + @lru_cache(1000) def get_geocodes( zip_code: str, @@ -242,6 +278,7 @@ def add_company(company: dict[str, Any], db: Session) -> None: zip_code=simplify_string(location.get("zip_code")), street=simplify_string(location.get("street")), last_update=last_update, + # **norm_capital(company.get("capital", {})), **get_geocodes(location.get("zip_code")), # type: ignore ) db.add(company_entry) diff --git a/tests/utils/data_transfer_test.py b/tests/utils/data_transfer_test.py index dfbb0c5..a67525e 100644 --- a/tests/utils/data_transfer_test.py +++ b/tests/utils/data_transfer_test.py @@ -12,7 +12,9 @@ from pytest_mock import MockerFixture from sqlalchemy.engine import Engine from sqlalchemy.orm import Session +from aki_prj23_transparenzregister.models.company import CapitalTypeEnum, CurrencyEnum from aki_prj23_transparenzregister.utils import data_transfer +from aki_prj23_transparenzregister.utils.data_transfer import norm_capital from aki_prj23_transparenzregister.utils.sql import entities @@ -1019,7 +1021,35 @@ def test_add_annual_report_financial_key_error(full_db: Session) -> None: ) -@pytest.mark.working_on() +@pytest.mark.parametrize("capital_type", [_.value for _ in CapitalTypeEnum]) +@pytest.mark.parametrize("currency", ["€", "EUR"]) +def test_norm_capital_eur(currency: str, capital_type: str) -> None: + """Tests if eur entries can be converted / normed correctly.""" + assert norm_capital({"value": 5, "currency": currency, "type": capital_type}) == { + "capital_value": 5.0, + "capital_currency": CurrencyEnum("EUR"), + "capital_type": CapitalTypeEnum(capital_type), + } + + +@pytest.mark.parametrize("capital_type", list(CapitalTypeEnum)) +@pytest.mark.parametrize("currency", ["DM", "DEM"]) +def test_norm_capital_dm(currency: str, capital_type: CapitalTypeEnum) -> None: + """Tests if dm entries can be converted / normed correctly.""" + assert norm_capital( + capital={"value": 5, "currency": currency, "type": capital_type} + ) == { + "capital_value": 2.56, + "capital_currency": CurrencyEnum("DM"), + "capital_type": CapitalTypeEnum(capital_type), + } + + +def test_norm_capital_fail() -> None: + """Tests if the entry is dropped if it isn't complete.""" + assert norm_capital({"something": "something"}) == {} # type: ignore + + @pytest.mark.parametrize( ("zip_code", "results"), [