From febcd59e395934d88d8861742f6c56a7efb0590e Mon Sep 17 00:00:00 2001 From: TrisNol Date: Sun, 17 Sep 2023 19:20:28 +0200 Subject: [PATCH] test(data-extraction): Include first unit tests --- Jupyter/API-tests/News/notebook.ipynb | 34 +-- poetry.lock | 14 +- pyproject.toml | 1 + .../models/company.py | 37 ++- .../unternehmensregister/__init__.py | 1 + .../unternehmensregister/transform.py | 219 ++++++++++-------- tests/models/company_test.py | 20 +- tests/utils/data_extraction/__init__.py | 1 - .../unternehmensregister/extract_test.py | 81 +++++++ .../unternehmensregister/load_test.py | 0 .../unternehmensregister/transform_test.py | 208 +++++++++++++++++ 11 files changed, 492 insertions(+), 124 deletions(-) create mode 100644 src/aki_prj23_transparenzregister/utils/data_extraction/unternehmensregister/__init__.py delete mode 100644 tests/utils/data_extraction/__init__.py create mode 100644 tests/utils/data_extraction/unternehmensregister/extract_test.py create mode 100644 tests/utils/data_extraction/unternehmensregister/load_test.py create mode 100644 tests/utils/data_extraction/unternehmensregister/transform_test.py diff --git a/Jupyter/API-tests/News/notebook.ipynb b/Jupyter/API-tests/News/notebook.ipynb index 981ba18..f61b9c6 100644 --- a/Jupyter/API-tests/News/notebook.ipynb +++ b/Jupyter/API-tests/News/notebook.ipynb @@ -607,7 +607,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -638,24 +638,32 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 2, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[{'title': 'BMP Greengas: Gläubiger fordern knapp eine Dreiviertelmilliarde Euro von insolventer EnBW-Tochter', 'link': 'https://www.handelsblatt.com/unternehmen/energie/bmp-greengas-glaeubiger-fordern-mehr-als-700-millionen-euro-von-insolventer-enbw-tochter/29394600.html', 'description': 'BMP Greengas verkaufte Biomethan an Stadtwerke und Energieversorger in ganz Deutschland. Die Insolvenz des Gashändlers könnte die öffentliche Hand Hunderte Millionen Euro kosten.', 'category': 'Energie', 'pubDate': 'Fri, 15 Sep 2023 20:26:51 +0200', 'guid': 'https://www.handelsblatt.com/29394600.html', 'content:encoded': '\"\"BMP Greengas verkaufte Biomethan an Stadtwerke und Energieversorger in ganz Deutschland. Die Insolvenz des Gashändlers könnte die öffentliche Hand Hunderte Millionen Euro kosten.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/biogasanlage/29394638/3-format2020.jpg', '@type': 'image/jpeg', '@length': '852752'}}, {'title': 'Pharma- und Agrarchemiekonzern: Weniger Hierarchien, weniger Manager: Bayer-Chef startet erste Phase des Umbaus', 'link': 'https://www.handelsblatt.com/unternehmen/industrie/pharma-und-agrarchemiekonzern-bayer-chef-bill-anderson-startet-erste-phase-des-umbaus/29393764.html', 'description': 'Bill Anderson hat der Bürokratie im eigenen Konzern den Kampf angesagt. Der neue CEO plant die Straffung der Bayer-Organisation – inklusive Stellenabbau. Führungskräfte sind verunsichert.', 'category': 'Industrie', 'pubDate': 'Fri, 15 Sep 2023 15:24:06 +0200', 'guid': 'https://www.handelsblatt.com/29393764.html', 'content:encoded': '\"\"Bill Anderson hat der Bürokratie im eigenen Konzern den Kampf angesagt. Der neue CEO plant die Straffung der Bayer-Organisation – inklusive Stellenabbau. Führungskräfte sind verunsichert.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/chempark-leverkusen/29394336/2-format2020.jpg', '@type': 'image/jpeg', '@length': '792899'}}, {'title': 'Offshore: Vattenfall will trotz Krise einen Mega-Windpark in der Nordsee bauen', 'link': 'https://www.handelsblatt.com/unternehmen/energie/offshore-vattenfall-will-trotz-krise-einen-mega-windpark-in-der-nordsee-bauen/29393316.html', 'description': 'Kurz nachdem der Konzern ein Windprojekt in Großbritannien gestoppt hat, kündigt er einen neuen Offshore-Park\\xa0in der Nordsee an. Der Unterschied liegt im System.', 'category': 'Energie', 'pubDate': 'Fri, 15 Sep 2023 20:01:15 +0200', 'guid': 'https://www.handelsblatt.com/29393316.html', 'content:encoded': '\"\"Kurz nachdem der Konzern ein Windprojekt in Großbritannien gestoppt hat, kündigt er einen neuen Offshore-Park\\xa0in der Nordsee an. Der Unterschied liegt im System.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/offshore/29394452/2-format2020.jpg', '@type': 'image/jpeg', '@length': '791043'}}, {'title': 'Anwälte: Probleme beseitigen, bevor sie entstehen: Das sind die Top-Dealmaker in Deutschlands Wirtschaftskanzleien', 'link': 'https://www.handelsblatt.com/unternehmen/dienstleister/anwaelte-das-sind-die-top-dealmaker-in-deutschlands-wirtschaftskanzleien/29391254.html', 'description': 'Gute Wirtschaftsanwälte sind heute weit mehr als bloße Rechtsberater. Das Handelsblatt portraitiert die neue Elite unter den Topjuristen.', 'category': 'Dienstleister', 'pubDate': 'Sat, 16 Sep 2023 14:38:56 +0200', 'guid': 'https://www.handelsblatt.com/29391254.html', 'content:encoded': '\"\"Gute Wirtschaftsanwälte sind heute weit mehr als bloße Rechtsberater. Das Handelsblatt portraitiert die neue Elite unter den Topjuristen.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/rechtsanwaelte/29392486/3-format2020.jpg', '@type': 'image/jpeg', '@length': '14415400'}}, {'title': 'Start-up-Check: Buntes Craft Beer aus Berlin: Vorreiter Fuerst Wiacek will auf dem deutschen Markt expandieren', 'link': 'https://www.handelsblatt.com/unternehmen/handel-konsumgueter/start-up-check-craft-beer-vorreiter-fuerst-wiacek-will-auf-dem-deutschen-markt-expandieren/29390886.html', 'description': 'Das Start-up zählt zu den bekanntesten deutschen Namen in der Brauerszene. Mit Geld aus einer Crowdinvesting-Kampagne wollen die Gründer nun das Geschäft auf dem Heimatmarkt vorantreiben.', 'category': 'Handel + Konsumgüter', 'pubDate': 'Sat, 16 Sep 2023 13:53:10 +0200', 'guid': 'https://www.handelsblatt.com/29390886.html', 'content:encoded': '\"\"Das Start-up zählt zu den bekanntesten deutschen Namen in der Brauerszene. Mit Geld aus einer Crowdinvesting-Kampagne wollen die Gründer nun das Geschäft auf dem Heimatmarkt vorantreiben.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/bierdosen-von-fuerst-wiacek/29391684/2-format2020.jpg', '@type': 'image/jpeg', '@length': '428952'}}, {'title': 'Interview: Berliner Hostel-Chef zur Adlon-Chefin: „Wir müssen gucken, ob unsere Gäste bald noch Geld haben, um zu verreisen“', 'link': 'https://www.handelsblatt.com/unternehmen/dienstleister/interview-berliner-hostel-chef-zur-adlon-chefin-wir-muessen-gucken-ob-unsere-gaeste-bald-noch-geld-haben-um-zu-verreisen/29390926.html', 'description': 'Karina Ansos vom Berliner Hotel Adlon und Oliver Winter von den a&o-Hostels sprechen über den zurückliegenden Sommer, leere Betten und die neuen Ansprüche ihrer Gäste.', 'category': 'Dienstleister', 'pubDate': 'Sat, 16 Sep 2023 12:00:00 +0200', 'guid': 'https://www.handelsblatt.com/29390926.html', 'content:encoded': '\"\"Karina Ansos vom Berliner Hotel Adlon und Oliver Winter von den a&o-Hostels sprechen über den zurückliegenden Sommer, leere Betten und die neuen Ansprüche ihrer Gäste.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/das-hotel-adlon-in-berlin/29391130/2-format2020.jpg', '@type': 'image/jpeg', '@length': '505831'}}, {'title': 'Metall- und Elektroindustrie: IG Metall sieht Vier-Tage-Woche nicht als Priorität', 'link': 'https://www.handelsblatt.com/unternehmen/industrie/metall-und-elektroindustrie-ig-metall-sieht-vier-tage-woche-nicht-als-prioritaet/29395094.html', 'description': 'Der derzeitige\\xa0Tarifvertrag\\xa0läuft noch bis Herbst 2024. Die IG Metall wird bei den\\xa0Verhandlungen im November\\xa0den Schwerpunkt\\xa0auf höhere Löhne und Gehälter\\xa0legen.', 'category': 'Industrie', 'pubDate': 'Sat, 16 Sep 2023 11:56:46 +0200', 'guid': 'https://www.handelsblatt.com/29395094.html', 'content:encoded': '\"\"Der derzeitige\\xa0Tarifvertrag\\xa0läuft noch bis Herbst 2024. Die IG Metall wird bei den\\xa0Verhandlungen im November\\xa0den Schwerpunkt\\xa0auf höhere Löhne und Gehälter\\xa0legen.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/ig-metall/29395102/2-format2020.jpg', '@type': 'image/jpeg', '@length': '253352'}}, {'title': 'Autoindustrie: Stellantis bietet in US-Autostreik 19,5 Prozent mehr Lohn', 'link': 'https://www.handelsblatt.com/unternehmen/industrie/autoindustrie-stellantis-bietet-in-us-autostreik-19-5-prozent-mehr-lohn/29395018.html', 'description': 'Zuvor hatte der Autobauer seinen Angestellten einen 17,5 Prozent-Zuschlag zugesichert. Die Gewerkschaft UAW bestreikte daraufhin erstmals gleichzeitig GM, Ford und Chrysler.', 'category': 'Industrie', 'pubDate': 'Sat, 16 Sep 2023 09:20:19 +0200', 'guid': 'https://www.handelsblatt.com/29395018.html', 'content:encoded': '\"\"Zuvor hatte der Autobauer seinen Angestellten einen 17,5 Prozent-Zuschlag zugesichert. Die Gewerkschaft UAW bestreikte daraufhin erstmals gleichzeitig GM, Ford und Chrysler.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/uaw-gewerkschaftsstreik/29395020/2-format2020.jpg', '@type': 'image/jpeg', '@length': '1225813'}}, {'title': 'Private-Equity-Manager: Heuschrecken oder Mehrwert-Schaffer? Das sind die wichtigsten Köpfe der Private-Equity-Branche in Deutschland', 'link': 'https://www.handelsblatt.com/unternehmen/dienstleister/private-equity-manager-das-sind-die-wichtigsten-koepfe-der-private-equity-branche-in-deutschland/29391250.html', 'description': 'Ihr Image ist ausbaufähig, ihr Gewerbe verschwiegen. Erfolgreiche Private-Equity-Manager erwirtschaften Millionen. Wir zeigen, wer das Geschäft vorantreibt.', 'category': 'Dienstleister', 'pubDate': 'Sat, 16 Sep 2023 08:14:23 +0200', 'guid': 'https://www.handelsblatt.com/29391250.html', 'content:encoded': '\"\"Ihr Image ist ausbaufähig, ihr Gewerbe verschwiegen. Erfolgreiche Private-Equity-Manager erwirtschaften Millionen. Wir zeigen, wer das Geschäft vorantreibt.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/private-equity-manager/29392528/2-format2020.jpg', '@type': 'image/jpeg', '@length': '16140205'}}, {'title': 'Vor Börsengang: Sandalen-Hersteller Birkenstock steigert Umsatz', 'link': 'https://www.handelsblatt.com/unternehmen/handel-konsumgueter/vor-boersengang-sandalen-hersteller-birkenstock-steigert-umsatz/29394738.html', 'description': 'Vor allem die gestiegenen Preise haben den Umsatz des Unternehmens deutlich angekurbelt. Am Dienstag hatte Birkenstock seinen Börsengang in den USA angekündigt.', 'category': 'Handel + Konsumgüter', 'pubDate': 'Fri, 15 Sep 2023 19:18:00 +0200', 'guid': 'https://www.handelsblatt.com/29394738.html', 'content:encoded': '\"\"Vor allem die gestiegenen Preise haben den Umsatz des Unternehmens deutlich angekurbelt. Am Dienstag hatte Birkenstock seinen Börsengang in den USA angekündigt.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/birkenstock-/29394746/2-format2020.jpg', '@type': 'image/jpeg', '@length': '567008'}}, {'title': 'Getränkehersteller: Beschäftigte bei Coca-Cola Deutschland erhalten mehr Geld', 'link': 'https://www.handelsblatt.com/unternehmen/handel-konsumgueter/getraenkehersteller-beschaeftigte-bei-coca-cola-deutschland-erhalten-mehr-geld/29394378.html', 'description': 'Beide Seiten profitieren vom Ergebnis der Tarifverhandlungen des Getränkeherstellers. Während das Gehalt der Beschäftigten steigt, weitet der Konzern seine Produktion aus.', 'category': 'Handel + Konsumgüter', 'pubDate': 'Fri, 15 Sep 2023 16:29:01 +0200', 'guid': 'https://www.handelsblatt.com/29394378.html', 'content:encoded': '\"\"Beide Seiten profitieren vom Ergebnis der Tarifverhandlungen des Getränkeherstellers. Während das Gehalt der Beschäftigten steigt, weitet der Konzern seine Produktion aus.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/coca-cola/29394398/4-format2020.jpg', '@type': 'image/jpeg', '@length': '423214'}}, {'title': 'Medien: Disney erhält Zehn-Milliarden-Angebot für TV-Geschäft – Streaming soll teurer werden', 'link': 'https://www.handelsblatt.com/unternehmen/it-medien/disney-disneys-streaming-angebot-soll-deutlich-teurer-werden/29393708.html', 'description': 'Im Juli hat Konzernchef Iger angedeutet, das klassische Fernsehgeschäft veräußern zu wollen. Nun gibt es erste Interessenten. Beim Streaming will der Konzern sparen.', 'category': 'Medien', 'pubDate': 'Fri, 15 Sep 2023 14:16:05 +0200', 'guid': 'https://www.handelsblatt.com/29393708.html', 'content:encoded': '\"\"Im Juli hat Konzernchef Iger angedeutet, das klassische Fernsehgeschäft veräußern zu wollen. Nun gibt es erste Interessenten. Beim Streaming will der Konzern sparen.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/szene-aus-der-star-wars-serie-ahsoka/29394038/2-format2020.jpg', '@type': 'image/jpeg', '@length': '381338'}}, {'title': 'Familienunternehmen: „Unterschiedliche Auffassungen“ über Strategie: Haniel-Chef Thomas Schmidt geht', 'link': 'https://www.handelsblatt.com/unternehmen/mittelstand/familienunternehmer/familienunternehmen-haniel-chef-thomas-schmidt-geht-nachfolgersuche-laeuft/29392702.html', 'description': 'Der Vertrag von Thomas Schmidt wird nicht verlängert. Der Manager sollte Haniel neu aufstellen, brachte aber keine Stabilität in den Konzern. Der Wechsel kommt zu einem heiklen Zeitpunkt.', 'category': 'Familienunternehmer', 'pubDate': 'Fri, 15 Sep 2023 14:00:00 +0200', 'guid': 'https://www.handelsblatt.com/29392702.html', 'content:encoded': '\"\"Der Vertrag von Thomas Schmidt wird nicht verlängert. Der Manager sollte Haniel neu aufstellen, brachte aber keine Stabilität in den Konzern. Der Wechsel kommt zu einem heiklen Zeitpunkt.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/thomas-schmidt/29393538/3-format2020.jpg', '@type': 'image/jpeg', '@length': '628007'}}, {'title': 'Fußball: Hertha-Investor übernimmt Premier-League-Club Everton', 'link': 'https://www.handelsblatt.com/unternehmen/dienstleister/fussball-hertha-investor-uebernimmt-premier-league-club-everton/29393828.html', 'description': 'Der bisherige Besitzer Farhad Moshiri verkauft 777 Partners seine gesamte Beteiligung. Damit gehört der US-Investmentfirma nun eine ganze Reihe internationaler Klubs.', 'category': 'Dienstleister', 'pubDate': 'Fri, 15 Sep 2023 13:06:26 +0200', 'guid': 'https://www.handelsblatt.com/29393828.html', 'content:encoded': '\"\"Der bisherige Besitzer Farhad Moshiri verkauft 777 Partners seine gesamte Beteiligung. Damit gehört der US-Investmentfirma nun eine ganze Reihe internationaler Klubs.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/spiel-von-everton-gegen-manchester-city/29393854/2-format2020.jpg', '@type': 'image/jpeg', '@length': '419103'}}, {'title': 'Pharmakonzern: Novartis-Aktionäre stimmen für Sandoz-Abspaltung', 'link': 'https://www.handelsblatt.com/unternehmen/industrie/pharmakonzern-novartis-aktionaere-stimmen-fuer-sandoz-abspaltung/29393702.html', 'description': 'Die Generikatochter des Schweizer Pharmakonzerns startet wohl im Index mittelgroßer Firmen. Die Schätzungen zum Börsenwert von Sandoz weichen stark voneinander ab.', 'category': 'Industrie', 'pubDate': 'Fri, 15 Sep 2023 12:49:04 +0200', 'guid': 'https://www.handelsblatt.com/29393702.html', 'content:encoded': '\"\"Die Generikatochter des Schweizer Pharmakonzerns startet wohl im Index mittelgroßer Firmen. Die Schätzungen zum Börsenwert von Sandoz weichen stark voneinander ab.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/novartis/29393800/2-format2020.jpg', '@type': 'image/jpeg', '@length': '284440'}}, {'title': 'Fraport: Betreiber von Frankfurter Flughafen verlängert Vertrag mit Chef', 'link': 'https://www.handelsblatt.com/unternehmen/handel-konsumgueter/fraport-betreiber-von-frankfurter-flughafen-verlaengert-vertrag-mit-chef/29393576.html', 'description': 'Stefan Schulte bleibt Vorstandsvorsitzender von Fraport. Er muss in den kommenden Jahren die hohe Verschuldung des Konzerns abbauen – und dessen Weg zur Klimaneutralität ebnen.', 'category': 'Handel + Konsumgüter', 'pubDate': 'Fri, 15 Sep 2023 12:39:52 +0200', 'guid': 'https://www.handelsblatt.com/29393576.html', 'content:encoded': '\"\"Stefan Schulte bleibt Vorstandsvorsitzender von Fraport. Er muss in den kommenden Jahren die hohe Verschuldung des Konzerns abbauen – und dessen Weg zur Klimaneutralität ebnen.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/stefan-schulte-im-terminal-1-des-frankfurter-flughafens/29393602/2-format2020.jpg', '@type': 'image/jpeg', '@length': '509793'}}, {'title': 'Autoindustrie: Preiskampf in China bremst Absatz von Volkswagen', 'link': 'https://www.handelsblatt.com/unternehmen/industrie/autoindustrie-preiskampf-in-china-bremst-absatz-von-volkswagen/29393448.html', 'description': 'Europas größter Autokonzern musste sein Absatzziel für das laufende Jahr bereits nach unten korrigieren. In anderen Märkten entwickelt sich das Geschäft von VW positiv.', 'category': 'Industrie', 'pubDate': 'Fri, 15 Sep 2023 11:55:27 +0200', 'guid': 'https://www.handelsblatt.com/29393448.html', 'content:encoded': '\"\"Europas größter Autokonzern musste sein Absatzziel für das laufende Jahr bereits nach unten korrigieren. In anderen Märkten entwickelt sich das Geschäft von VW positiv.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/volkswagen-werk-in-shanghai/29393522/2-format2020.jpg', '@type': 'image/jpeg', '@length': '28972'}}, {'title': 'Nationalmannschaft: Rettig wird Geschäftsführer Sport beim DFB', 'link': 'https://www.handelsblatt.com/unternehmen/management/nationalmannschaft-andreas-rettig-wird-geschaeftsfuehrer-sport-beim-dfb-/29393462.html', 'description': 'Der Deutsche Fußball-Bund hat einen Nachfolger für Oliver Bierhoff gefunden. Der ehemalige DFL-Geschäftsführer Rettig soll den Bereich der Nationalmannschaft übernehmen.', 'category': 'Management', 'pubDate': 'Fri, 15 Sep 2023 11:38:02 +0200', 'guid': 'https://www.handelsblatt.com/29393462.html', 'content:encoded': '\"\"Der Deutsche Fußball-Bund hat einen Nachfolger für Oliver Bierhoff gefunden. Der ehemalige DFL-Geschäftsführer Rettig soll den Bereich der Nationalmannschaft übernehmen.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/andreas-rettig/29393518/2-format2020.jpg', '@type': 'image/jpeg', '@length': '395783'}}, {'title': 'Rüstungsindustrie: Lufthansa beteiligt sich an Rheinmetall-Konsortium für Kampfjet', 'link': 'https://www.handelsblatt.com/unternehmen/handel-konsumgueter/ruestungsindustrie-lufthansa-beteiligt-sich-an-rheinmetall-konsortium-fuer-kampfjet/29393382.html', 'description': 'Rheinmetall produziert künftig Teile des Rumpfs des Lockheed-Kampfjets. Nun hat die Lufthansa bestätigt, dass sie sich an Fertigung und Wartung der Flugzeuge beteiligt.', 'category': 'Handel + Konsumgüter', 'pubDate': 'Fri, 15 Sep 2023 11:22:21 +0200', 'guid': 'https://www.handelsblatt.com/29393382.html', 'content:encoded': '\"\"Rheinmetall produziert künftig Teile des Rumpfs des Lockheed-Kampfjets. Nun hat die Lufthansa bestätigt, dass sie sich an Fertigung und Wartung der Flugzeuge beteiligt.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/kampfjet-f-35/29393442/2-format2020.jpg', '@type': 'image/jpeg', '@length': '375575'}}, {'title': 'Dieselskandal: Verpflichtender Rückruf droht: Neue Vorwürfe gegen Mercedes im Dieselskandal', 'link': 'https://www.handelsblatt.com/unternehmen/industrie/dieselskandal-mercedes-droht-neuer-behoerdenaerger-wegen-e-klasse/29393172.html', 'description': 'In einer wichtigen Baureihe soll der Konzern mehrere Abschalteinrichtungen genutzt haben. Ein freiwilliges Software-Update von Mercedes könnte dem Kraftfahrt-Bundesamt nicht ausreichen.', 'category': 'Industrie', 'pubDate': 'Fri, 15 Sep 2023 10:31:01 +0200', 'guid': 'https://www.handelsblatt.com/29393172.html', 'content:encoded': '\"\"In einer wichtigen Baureihe soll der Konzern mehrere Abschalteinrichtungen genutzt haben. Ein freiwilliges Software-Update von Mercedes könnte dem Kraftfahrt-Bundesamt nicht ausreichen.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/mercedes-logo/29393210/3-format2020.jpg', '@type': 'image/jpeg', '@length': '534599'}}, {'title': 'Luftfahrt: Lufthansa lässt den Großraumjet A380 länger fliegen', 'link': 'https://www.handelsblatt.com/unternehmen/handel-konsumgueter/luftfahrt-lufthansa-laesst-den-grossraumjet-a380-laenger-fliegen/29393056.html', 'description': 'Der Konzern leidet unter Lieferengpässen bei neuen Flugzeugen. Daher wird der Riesenjet A380 länger im Einsatz sein – und soll nun sogar eine neue Businessklasse bekommen.', 'category': 'Handel + Konsumgüter', 'pubDate': 'Fri, 15 Sep 2023 10:00:00 +0200', 'guid': 'https://www.handelsblatt.com/29393056.html', 'content:encoded': '\"\"Der Konzern leidet unter Lieferengpässen bei neuen Flugzeugen. Daher wird der Riesenjet A380 länger im Einsatz sein – und soll nun sogar eine neue Businessklasse bekommen.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/a380-der-lufthansa/29393088/3-format2020.jpg', '@type': 'image/jpeg', '@length': '297925'}}, {'title': 'Bahn-Pünktlichkeit: Bahn-Pünktlichkeit auf Tiefpunkt: Jeder dritte Passagier war 2022 mit über 15 Minuten Verspätung am Ziel', 'link': 'https://www.handelsblatt.com/unternehmen/handel-konsumgueter/bahn-puenktlichkeit-jeder-dritte-bahnreisende-war-2022-mit-mehr-als-15-minuten-verspaetung-am-ziel/29392970.html', 'description': 'Die pünktliche Ankunft ist entscheidend für ein gutes Bahn-Erlebnis, doch allzu oft scheitert es daran. Ein bestimmter Grund sticht dabei heraus.', 'category': 'Handel + Konsumgüter', 'pubDate': 'Fri, 15 Sep 2023 07:58:20 +0200', 'guid': 'https://www.handelsblatt.com/29392970.html', 'content:encoded': '\"\"Die pünktliche Ankunft ist entscheidend für ein gutes Bahn-Erlebnis, doch allzu oft scheitert es daran. Ein bestimmter Grund sticht dabei heraus.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/ice/29392990/2-format2020.jpg', '@type': 'image/jpeg', '@length': '507442'}}, {'title': 'Unternehmensberater: Netzwerker und Problemlöser: So gewinnen Deutschlands Top-Berater das Vertrauen ihrer Auftraggeber', 'link': 'https://www.handelsblatt.com/unternehmen/dienstleister/unternehmensberater-so-gewinnen-deutschlands-top-berater-das-vertrauen-ihrer-auftraggeber/29391258.html', 'description': 'Kaum ein Konzern kommt ohne Unternehmensberater aus. Doch einige wenige stechen aus der Masse heraus, weil selbst Vorstandschefs auf sie hören. Das sind die wichtigsten Köpfe.', 'category': 'Dienstleister', 'pubDate': 'Fri, 15 Sep 2023 04:00:00 +0200', 'guid': 'https://www.handelsblatt.com/29391258.html', 'content:encoded': '\"\"Kaum ein Konzern kommt ohne Unternehmensberater aus. Doch einige wenige stechen aus der Masse heraus, weil selbst Vorstandschefs auf sie hören. Das sind die wichtigsten Köpfe.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/unternehmensberater/29392472/2-format2020.jpg', '@type': 'image/jpeg', '@length': '8070157'}}, {'title': 'Investmentbanking: Dienstleister statt „Master of the Universe“: Wie eine frische Generation von Bankern ihren Job neu definiert', 'link': 'https://www.handelsblatt.com/unternehmen/dienstleister/investmentbanking-wie-eine-frische-generation-von-bankern-ihren-job-neu-definiert/29391262.html', 'description': 'Dealmaker und Newcomer: Die deutsche Elite der Investmentbanker tickt anders als ihre Vorgänger bis vor wenigen Jahren. Das sind die spannendsten Köpfe.', 'category': 'Dienstleister', 'pubDate': 'Fri, 15 Sep 2023 04:00:00 +0200', 'guid': 'https://www.handelsblatt.com/29391262.html', 'content:encoded': '\"\"Dealmaker und Newcomer: Die deutsche Elite der Investmentbanker tickt anders als ihre Vorgänger bis vor wenigen Jahren. Das sind die spannendsten Köpfe.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/frankfurter-bankenviertel/29393596/2-format2020.jpg', '@type': 'image/jpeg', '@length': '1711319'}}, {'title': 'Management: Deutschlands neue Dealmaker: Wie Profis heute Vertrauen aufbauen und Geschäfte anbahnen', 'link': 'https://www.handelsblatt.com/unternehmen/dienstleister/management-deutschlands-neue-dealmaker-wie-profis-heute-vertrauen-aufbauen-und-geschaefte-anbahnen/29343370.html', 'description': 'Große Bugwelle und eindrucksvoller Titel? Das zieht beim Kontakteknüpfen immer seltener. So knüpfen Deutschlands neue Dealmaker heute ihre Netzwerke.', 'category': 'Dienstleister', 'pubDate': 'Fri, 15 Sep 2023 04:00:00 +0200', 'guid': 'https://www.handelsblatt.com/29343370.html', 'content:encoded': '\"\"Große Bugwelle und eindrucksvoller Titel? Das zieht beim Kontakteknüpfen immer seltener. So knüpfen Deutschlands neue Dealmaker heute ihre Netzwerke.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/die-dealmaker-der-deutschen-wirtschaft/29391896/4-format2020.png', '@type': 'image/png', '@length': '2299085'}}, {'title': 'Logistik: Frühere Haniel-Chefkontrolleurin Nowotne steigt bei der Kühne Holding ein', 'link': 'https://www.handelsblatt.com/unternehmen/handel-konsumgueter/logistik-fruehere-haniel-chefkontrolleurin-doreen-nowotne-steigt-bei-der-kuehne-holding-ein/29392438.html', 'description': 'Die 50-Jährige wechselt ins Management der Beteiligungsgesellschaft von Milliardär Klaus Michael Kühne. Damit dürfte sie direkt mit einem großen Logistik-Deal beschäftigt sein.', 'category': 'Handel + Konsumgüter', 'pubDate': 'Thu, 14 Sep 2023 18:56:10 +0200', 'guid': 'https://www.handelsblatt.com/29392438.html', 'content:encoded': '\"\"Die 50-Jährige wechselt ins Management der Beteiligungsgesellschaft von Milliardär Klaus Michael Kühne. Damit dürfte sie direkt mit einem großen Logistik-Deal beschäftigt sein.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/doreen-nowotne/28296996/4-format2020.jpg', '@type': 'image/jpeg', '@length': '164622'}}, {'title': 'HHLA-Deal: Hapag-Lloyd droht mit Abzug von Transportvolumen aus Hamburg', 'link': 'https://www.handelsblatt.com/unternehmen/handel-konsumgueter/hhla-deal-hapag-lloyd-droht-mit-abzug-von-transportvolumen-aus-hamburg/29392196.html', 'description': 'Der Teilverkauf des Hafenbetreibers HHLA an MSC könnten der Reederei neue Konkurrenz vor der Haustür bescheren. Der Hapag-Chef droht mit Konsequenzen.', 'category': 'Handel + Konsumgüter', 'pubDate': 'Thu, 14 Sep 2023 17:06:25 +0200', 'guid': 'https://www.handelsblatt.com/29392196.html', 'content:encoded': '\"\"Der Teilverkauf des Hafenbetreibers HHLA an MSC könnten der Reederei neue Konkurrenz vor der Haustür bescheren. Der Hapag-Chef droht mit Konsequenzen.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/reederei-hapag-lloyd/29392238/2-format2020.jpg', '@type': 'image/jpeg', '@length': '465839'}}, {'title': 'Tabakbranche: Zigaretten-Nachfrage sinkt, elektronische Alternativen sind im Trend', 'link': 'https://www.handelsblatt.com/unternehmen/handel-konsumgueter/tabakbranche-zigaretten-nachfrage-sinkt-elektronische-alternativen-sind-im-trend/29392122.html', 'description': 'E-Zigaretten werden in Deutschland immer beliebter. Experten warnen allerdings davor, die gesundheitlichen Folgen zu unterschätzen. Auch von Umweltschützern gibt es Kritik.', 'category': 'Handel + Konsumgüter', 'pubDate': 'Thu, 14 Sep 2023 16:51:57 +0200', 'guid': 'https://www.handelsblatt.com/29392122.html', 'content:encoded': '\"\"E-Zigaretten werden in Deutschland immer beliebter. Experten warnen allerdings davor, die gesundheitlichen Folgen zu unterschätzen. Auch von Umweltschützern gibt es Kritik.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/e-zigarette/29392160/2-format2020.jpg', '@type': 'image/jpeg', '@length': '1303227'}}, {'title': 'Logistik: Auch Eurogate-Aktionär erwägt Gegenangebot zum HHLA-Deal', 'link': 'https://www.handelsblatt.com/unternehmen/handel-konsumgueter/logistik-auch-eurogate-aktionaer-erwaegt-gegenangebot-zum-hhla-deal/29392116.html', 'description': 'Nach dem Milliardär Kühne reagiert auch der Unternehmer Thomas Eckelmann mit scharfer Kritik am Teilverkauf des Hafenbetreibers. Er bringt ebenfalls eine Gegenofferte ins Spiel.', 'category': 'Handel + Konsumgüter', 'pubDate': 'Thu, 14 Sep 2023 16:40:00 +0200', 'guid': 'https://www.handelsblatt.com/29392116.html', 'content:encoded': '\"\"Nach dem Milliardär Kühne reagiert auch der Unternehmer Thomas Eckelmann mit scharfer Kritik am Teilverkauf des Hafenbetreibers. Er bringt ebenfalls eine Gegenofferte ins Spiel.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/eurogate-containerschiff/29392164/2-format2020.jpg', '@type': 'image/jpeg', '@length': '797989'}}, {'title': 'Erneuerbare Energien: Vattenfall plant weiteren Windpark in der Nordsee bei Borkum', 'link': 'https://www.handelsblatt.com/unternehmen/energie/erneuerbare-energien-vattenfall-plant-weiteren-windpark-in-der-nordsee-bei-borkum/29391822.html', 'description': 'Es ist bereits das zweite Offshore-Projekt des schwedischen Konzerns in der Nähe der Insel. Zusammen sollen beide Anlagen Strom für mehr als 1,7 Millionen Haushalte produzieren.', 'category': 'Energie', 'pubDate': 'Thu, 14 Sep 2023 15:22:23 +0200', 'guid': 'https://www.handelsblatt.com/29391822.html', 'content:encoded': '\"\"Es ist bereits das zweite Offshore-Projekt des schwedischen Konzerns in der Nähe der Insel. Zusammen sollen beide Anlagen Strom für mehr als 1,7 Millionen Haushalte produzieren.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/offshore-windpark/29391886/3-format2020.jpg', '@type': 'image/jpeg', '@length': '523248'}}, {'title': 'Elektromobilität: Volkswagen baut in Zwickau Stellen ab – Zukunft von 2000 weiteren Befristeten ungewiss', 'link': 'https://www.handelsblatt.com/unternehmen/industrie/elektromobilitaet-volkswagen-baut-in-zwickau-hunderte-befristete-stellen-ab/29390984.html', 'description': 'Die Elektrowende bei Volkswagen stockt – das schlägt sich auch auf die Produktion nieder. Erste befristet Beschäftigte an VWs Haupt-Elektrostandort müssen nun gehen.', 'category': 'Industrie', 'pubDate': 'Thu, 14 Sep 2023 15:09:09 +0200', 'guid': 'https://www.handelsblatt.com/29390984.html', 'content:encoded': '\"\"Die Elektrowende bei Volkswagen stockt – das schlägt sich auch auf die Produktion nieder. Erste befristet Beschäftigte an VWs Haupt-Elektrostandort müssen nun gehen.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/vw-produktion-in-zwickau/29393960/2-format2020.jpg', '@type': 'image/jpeg', '@length': '562332'}}, {'title': 'Rechtsstreit: Gute Aussichten für VW in Streit um italienische Millionenstrafe', 'link': 'https://www.handelsblatt.com/unternehmen/industrie/rechtsstreit-gute-aussichten-fuer-vw-in-streit-um-italienische-millionenstrafe/29391826.html', 'description': 'Der Autobauer konnte im Verfahren um eine mögliche Doppelbestrafung einen Teilerfolg erzielen. In dem Rechtsstreit geht es um mutmaßlich illegale Abschalteinrichtungen.', 'category': 'Industrie', 'pubDate': 'Thu, 14 Sep 2023 15:04:00 +0200', 'guid': 'https://www.handelsblatt.com/29391826.html', 'content:encoded': '\"\"Der Autobauer konnte im Verfahren um eine mögliche Doppelbestrafung einen Teilerfolg erzielen. In dem Rechtsstreit geht es um mutmaßlich illegale Abschalteinrichtungen.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/volkswagen/29391842/2-format2020.jpg', '@type': 'image/jpeg', '@length': '408014'}}, {'title': 'Bärchenwurst-Produzent: Deutscher Hersteller beantragt als erster in der EU Zulassung von Fleisch aus Zellkulturen', 'link': 'https://www.handelsblatt.com/unternehmen/handel-konsumgueter/baerchenwurst-firma-erstmals-verkauf-von-laborfleisch-in-der-eu-beantragt/29391370.html', 'description': 'Fleisch, das im Bioreaktor gezüchtet wird, ist bisher nur in Singapur und den USA zugelassen. Nun will ein deutsches Familienunternehmen in der EU zum Pionier werden.', 'category': 'Handel + Konsumgüter', 'pubDate': 'Thu, 14 Sep 2023 14:00:00 +0200', 'guid': 'https://www.handelsblatt.com/29391370.html', 'content:encoded': '\"\"Fleisch, das im Bioreaktor gezüchtet wird, ist bisher nur in Singapur und den USA zugelassen. Nun will ein deutsches Familienunternehmen in der EU zum Pionier werden.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/symbolbild-hotdogs/29391650/3-format2020.jpg', '@type': 'image/jpeg', '@length': '478283'}}, {'title': 'Branchenverband VCI: „Keine Erholung in Sicht“: Chemieindustrie erwartet weitere Einbußen', 'link': 'https://www.handelsblatt.com/unternehmen/industrie/branchenverband-vci-keine-erholung-in-sicht-chemieindustrie-erwartet-weitere-einbussen/29391256.html', 'description': 'Die deutsche Chemieindustrie drosselt ihre Produktion noch stärker als erwartet. In besonders betroffenen Bereichen steht bereits Kurzarbeit auf der Agenda.', 'category': 'Industrie', 'pubDate': 'Thu, 14 Sep 2023 11:32:00 +0200', 'guid': 'https://www.handelsblatt.com/29391256.html', 'content:encoded': '\"\"Die deutsche Chemieindustrie drosselt ihre Produktion noch stärker als erwartet. In besonders betroffenen Bereichen steht bereits Kurzarbeit auf der Agenda.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/chemieanlage-in-sachsen/29391314/2-format2020.jpg', '@type': 'image/jpeg', '@length': '289018'}}, {'title': 'Einzelhandel: Versteckte Preiserhöhungen: Carrefour prangert Nestlé, Pepsi und Unilever an', 'link': 'https://www.handelsblatt.com/unternehmen/handel-konsumgueter/einzelhandel-carrefour-prangert-nestle-pepsi-und-unilever-wegen-versteckter-preiserhoehungen-an/29391006.html', 'description': 'Frankreich kämpft seit Monaten gegen steigende Lebensmittelpreise. Nun warnt die Kette Carrefour die Kunden vor gewissen Produkten. Das soll den Druck auf die Großkonzerne erhöhen.', 'category': 'Handel + Konsumgüter', 'pubDate': 'Thu, 14 Sep 2023 10:35:49 +0200', 'guid': 'https://www.handelsblatt.com/29391006.html', 'content:encoded': '\"\"Frankreich kämpft seit Monaten gegen steigende Lebensmittelpreise. Nun warnt die Kette Carrefour die Kunden vor gewissen Produkten. Das soll den Druck auf die Großkonzerne erhöhen.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/carrefour-markt/29391138/3-format2020.jpg', '@type': 'image/jpeg', '@length': '541675'}}, {'title': 'Industriekonzern: Thyssen-Krupp macht Klimaschutz zum Geschäft: Konzern bündelt grüne Technologien', 'link': 'https://www.handelsblatt.com/unternehmen/industrie/greentech-thyssen-krupp-buendelt-technologien-in-neuer-sparte-decarbon/29390636.html', 'description': 'Thyssen-Krupp gründet eine neue Sparte. Bei der Umsetzung des Effizienzprogramms für den Konzern schlägt Vorstandschef Lopez zudem einen anderen Kurs ein als seine Vorgängerin.', 'category': 'Industrie', 'pubDate': 'Thu, 14 Sep 2023 08:02:42 +0200', 'guid': 'https://www.handelsblatt.com/29390636.html', 'content:encoded': '\"\"Thyssen-Krupp gründet eine neue Sparte. Bei der Umsetzung des Effizienzprogramms für den Konzern schlägt Vorstandschef Lopez zudem einen anderen Kurs ein als seine Vorgängerin.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/thyssen-krupp-setzt-auf-gruen/29390700/2-format2020.jpg', '@type': 'image/jpeg', '@length': '515385'}}, {'title': 'Gas: Chevron-Streik in Australien könnte sich auf LNG-Versorgung in Europa auswirken', 'link': 'https://www.handelsblatt.com/unternehmen/energie/gas-chevron-streik-in-australien-koennte-sich-auf-lng-versorgung-in-europa-auswirken/29390458.html', 'description': 'Zwei Wochen sollen zwei LNG-Projekte bestreikt werden. Dass der Ausfall länger anhält und zu einem anhaltenden Anstieg der Gaspreise führt, sei jedoch unwahrscheinlich.', 'category': 'Energie', 'pubDate': 'Thu, 14 Sep 2023 03:30:00 +0200', 'guid': 'https://www.handelsblatt.com/29390458.html', 'content:encoded': '\"\"Zwei Wochen sollen zwei LNG-Projekte bestreikt werden. Dass der Ausfall länger anhält und zu einem anhaltenden Anstieg der Gaspreise führt, sei jedoch unwahrscheinlich.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/chevron/29390470/2-format2020.jpg', '@type': 'image/jpeg', '@length': '501369'}}, {'title': 'Biotechkonzern: Moderna punktet mit Daten zu mRNA-Grippeimpfstoff – Aktie steigt um sieben Prozent', 'link': 'https://www.handelsblatt.com/unternehmen/industrie/biotechkonzern-moderna-punktet-mit-daten-zu-mrna-grippeimpfstoff/29389474.html', 'description': 'Aufgrund der sinkenden Nachfrage nach Covid-Vakzinen setzt der US-Konzern auf neue Mittel. Der Grippeimpfstoff könnte nun schon in einem Jahr auf den Markt kommen.', 'category': 'Industrie', 'pubDate': 'Wed, 13 Sep 2023 16:35:04 +0200', 'guid': 'https://www.handelsblatt.com/29389474.html', 'content:encoded': '\"\"Aufgrund der sinkenden Nachfrage nach Covid-Vakzinen setzt der US-Konzern auf neue Mittel. Der Grippeimpfstoff könnte nun schon in einem Jahr auf den Markt kommen.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/moderna/29389522/3-format2020.jpg', '@type': 'image/jpeg', '@length': '285836'}}, {'title': 'E-Autobauer: Vietnam: VinFast will in Asien expandieren', 'link': 'https://www.handelsblatt.com/unternehmen/industrie/e-autobauer-vietnam-vinfast-will-in-asien-expandieren/29388566.html', 'description': 'Das Unternehmen plant eine Expansion in sieben asiatische Märkte und ein Werk in Indonesien. Zudem will der Autobauer noch weitere Märkte im Ausland erschließen.', 'category': 'Industrie', 'pubDate': 'Wed, 13 Sep 2023 12:06:00 +0200', 'guid': 'https://www.handelsblatt.com/29388566.html', 'content:encoded': '\"\"Das Unternehmen plant eine Expansion in sieben asiatische Märkte und ein Werk in Indonesien. Zudem will der Autobauer noch weitere Märkte im Ausland erschließen.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/-vinfast-/29388568/2-format2020.jpg', '@type': 'image/jpeg', '@length': '613900'}}, {'title': 'Hamburger Hafen: „Diese Lösung ist ein Affront“ – Kühne erwägt Gegenofferte für Hamburger Hafenbetreiber', 'link': 'https://www.handelsblatt.com/unternehmen/handel-konsumgueter/hamburger-hafen-kuehne-erwaegt-gegenofferte-fuer-hamburger-hafenbetreiber-hhla/29388256.html', 'description': 'Der Milliardär will sich mit dem Teilverkauf des Hamburger Hafenbetreibers an MSC nicht abfinden. Dabei könnte Kühne auch über seine eigene Holding eingreifen.', 'category': 'Handel + Konsumgüter', 'pubDate': 'Wed, 13 Sep 2023 11:04:29 +0200', 'guid': 'https://www.handelsblatt.com/29388256.html', 'content:encoded': '\"\"Der Milliardär will sich mit dem Teilverkauf des Hamburger Hafenbetreibers an MSC nicht abfinden. Dabei könnte Kühne auch über seine eigene Holding eingreifen.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/containerschiff-von-msc-in-hamburg/29388468/2-format2020.jpg', '@type': 'image/jpeg', '@length': '624341'}}, {'title': 'Luftfahrt: Führung der Kabinengewerkschaft UFO tritt zurück', 'link': 'https://www.handelsblatt.com/unternehmen/handel-konsumgueter/luftfahrt-fuehrung-der-kabinengewerkschaft-ufo-tritt-zurueck/29388142.html', 'description': 'Beide UFO-Vorsitzende haben nach eigenen Angaben einen neuen Job. Ihre Aufgabe, die angeschlagene Arbeitnehmervertretung auf Kurs zu bringen, sei erfüllt.', 'category': 'Handel + Konsumgüter', 'pubDate': 'Wed, 13 Sep 2023 10:30:00 +0200', 'guid': 'https://www.handelsblatt.com/29388142.html', 'content:encoded': '\"\"Beide UFO-Vorsitzende haben nach eigenen Angaben einen neuen Job. Ihre Aufgabe, die angeschlagene Arbeitnehmervertretung auf Kurs zu bringen, sei erfüllt.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/daniel-kassa-mbuambi/29388200/2-format2020.jpg', '@type': 'image/jpeg', '@length': '24852'}}, {'title': 'E-Autos: Sorge vor Jobabbau bei VW in Zwickau – Betriebsversammlung geplant', 'link': 'https://www.handelsblatt.com/unternehmen/industrie/e-autos-sorge-vor-jobabbau-bei-vw-in-zwickau-betriebsversammlung-geplant/29388148.html', 'description': 'Die geringe Nachfrage nach Elektroautos könnte VW-Mitarbeitende mit befristeten Verträgen ihre Anstellung kosten. Vertrauensleute der IG Metall wenden sich jetzt mit einem Brief an die Geschäftsführung.', 'category': 'Industrie', 'pubDate': 'Wed, 13 Sep 2023 10:00:00 +0200', 'guid': 'https://www.handelsblatt.com/29388148.html', 'content:encoded': '\"\"Die geringe Nachfrage nach Elektroautos könnte VW-Mitarbeitende mit befristeten Verträgen ihre Anstellung kosten. Vertrauensleute der IG Metall wenden sich jetzt mit einem Brief an die Geschäftsführung.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/vw-werk-in-zwickau/29388166/2-format2020.jpg', '@type': 'image/jpeg', '@length': '629358'}}, {'title': 'Automatisierung: ABB baut neues Roboterwerk: „Produktion in Europa wird nur mit mehr Automatisierung überleben“', 'link': 'https://www.handelsblatt.com/unternehmen/handel-konsumgueter/automatisierung-abb-baut-neues-roboterwerk-in-schweden/29384396.html', 'description': 'Der Konzern investiert 280 Millionen Dollar in einen neuen Robotik-Campus. Experten rechnen mit weiter wachsender Nachfrage in Europa – noch haben sich einige Hoffnungen aber nicht erfüllt.', 'category': 'Handel + Konsumgüter', 'pubDate': 'Wed, 13 Sep 2023 09:00:00 +0200', 'guid': 'https://www.handelsblatt.com/29384396.html', 'content:encoded': '\"\"Der Konzern investiert 280 Millionen Dollar in einen neuen Robotik-Campus. Experten rechnen mit weiter wachsender Nachfrage in Europa – noch haben sich einige Hoffnungen aber nicht erfüllt.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/roboter-von-abb-im-einsatz/29387076/2-format2020.jpg', '@type': 'image/jpeg', '@length': '1040732'}}, {'title': 'Truck-Hersteller: Teurer als gedacht – Entwicklung selbstfahrender Lkw geht nur langsam voran', 'link': 'https://www.handelsblatt.com/unternehmen/industrie/truck-hersteller-teurer-als-gedacht-entwicklung-selbstfahrender-lkw-geht-nur-langsam-voran/29386888.html', 'description': 'Autonomes Fahren auf der Straße kommt auch bei Lkw\\xa0später als geplant. Die Branche klagt über hohe Entwicklungskosten und den fehlenden politischen Willen.', 'category': 'Industrie', 'pubDate': 'Wed, 13 Sep 2023 04:00:00 +0200', 'guid': 'https://www.handelsblatt.com/29386888.html', 'content:encoded': '\"\"Autonomes Fahren auf der Straße kommt auch bei Lkw\\xa0später als geplant. Die Branche klagt über hohe Entwicklungskosten und den fehlenden politischen Willen.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/selbstfahrender-lkw-von-daimler/29387132/2-format2020.jpg', '@type': 'image/jpeg', '@length': '314682'}}, {'title': 'IPO: Birkenstock beantragt Börsengang in den USA – Als Luxusmarke winkt eine hohe Bewertung', 'link': 'https://www.handelsblatt.com/unternehmen/handel-konsumgueter/ipo-birkenstock-beantragt-boersengang-in-den-usa/29387586.html', 'description': 'Der deutsche Sandalenhersteller geht in der zweiten Oktoberwoche an die New Yorker Börse. Ein französischer Luxuskonzern spielt dabei eine entscheidende Rolle.', 'category': 'Handel + Konsumgüter', 'pubDate': 'Tue, 12 Sep 2023 23:41:00 +0200', 'guid': 'https://www.handelsblatt.com/29387586.html', 'content:encoded': '\"\"Der deutsche Sandalenhersteller geht in der zweiten Oktoberwoche an die New Yorker Börse. Ein französischer Luxuskonzern spielt dabei eine entscheidende Rolle.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/sandalette-von-birkenstock/29388854/3-format2020.jpg', '@type': 'image/jpeg', '@length': '323255'}}, {'title': 'Bernard Looney: Verstöße gegen Verhaltenskodex: BP-Chef tritt mit sofortiger Wirkung zurück', 'link': 'https://www.handelsblatt.com/unternehmen/energie/oelkonzern-bp-chef-looney-tritt-mit-sofortiger-wirkung-zurueck/29387528.html', 'description': 'Bernard Looney hatte frühere Beziehungen zu Arbeitskollegen nicht vollständig transparent gemacht. Finanzchef Murray Auchincloss wird übergangsweise den Vorstandsvorsitz übernehmen.', 'category': 'Energie', 'pubDate': 'Tue, 12 Sep 2023 21:27:00 +0200', 'guid': 'https://www.handelsblatt.com/29387528.html', 'content:encoded': '\"\"Bernard Looney hatte frühere Beziehungen zu Arbeitskollegen nicht vollständig transparent gemacht. Finanzchef Murray Auchincloss wird übergangsweise den Vorstandsvorsitz übernehmen.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/bernard-looney/29387530/2-format2020.jpg', '@type': 'image/jpeg', '@length': '348761'}}, {'title': 'Syntellix AG: Verdacht auf Insolvenzverschleppung: Ermittlungen gegen Utz Claassen', 'link': 'https://www.handelsblatt.com/unternehmen/industrie/syntellix-ag-verdacht-auf-insolvenzverschleppung-ermittlungen-gegen-utz-claassen/29386436.html', 'description': 'Mitarbeiter warten auf Gehälter, Anwälte auf Honorare. Jetzt ist der Vorstandschef im Visier der Justiz. Er weist die Vorwürfe als haltlos zurück.', 'category': 'Industrie', 'pubDate': 'Tue, 12 Sep 2023 18:31:56 +0200', 'guid': 'https://www.handelsblatt.com/29386436.html', 'content:encoded': '\"\"Mitarbeiter warten auf Gehälter, Anwälte auf Honorare. Jetzt ist der Vorstandschef im Visier der Justiz. Er weist die Vorwürfe als haltlos zurück.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/utz-claassen/29389318/2-format2020.jpg', '@type': 'image/jpeg', '@length': '518491'}}, {'title': 'Luftfahrt: Lufthansa lässt 20 Flugzeuge wegen Triebwerksproblem am Boden', 'link': 'https://www.handelsblatt.com/unternehmen/handel-konsumgueter/luftfahrt-lufthansa-laesst-20-flugzeuge-wegen-triebwerksproblem-am-boden/29387380.html', 'description': 'Wegen Mängeln müssen zahlreiche Triebwerke des Herstellers Pratt & Whitney überarbeitet werden. Das trifft auch die größte deutsche Fluggesellschaft.', 'category': 'Handel + Konsumgüter', 'pubDate': 'Tue, 12 Sep 2023 18:17:09 +0200', 'guid': 'https://www.handelsblatt.com/29387380.html', 'content:encoded': '\"\"Wegen Mängeln müssen zahlreiche Triebwerke des Herstellers Pratt & Whitney überarbeitet werden. Das trifft auch die größte deutsche Fluggesellschaft.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/lufthansa-flugzeug-des-modells-a320-neo/29389166/2-format2020.jpg', '@type': 'image/jpeg', '@length': '275726'}}, {'title': 'Pay-TV-Sender: Barny Mills steigt zum Chef von Sky Deutschland auf', 'link': 'https://www.handelsblatt.com/unternehmen/it-medien/pay-tv-sender-barny-mills-steigt-zum-chef-von-sky-deutschland-auf/29387120.html', 'description': 'Der bisherige Finanzvorstand wird Nachfolger von Devesh Raj. Dem Bezahlsender setzt vor allem die Konkurrenz durch Streaming-Dienste stark zu.', 'category': 'Medien', 'pubDate': 'Tue, 12 Sep 2023 17:04:57 +0200', 'guid': 'https://www.handelsblatt.com/29387120.html', 'content:encoded': '\"\"Der bisherige Finanzvorstand wird Nachfolger von Devesh Raj. Dem Bezahlsender setzt vor allem die Konkurrenz durch Streaming-Dienste stark zu.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/hauptsitz-von-sky-deutschland-in-unterfoehring-bei-muenchen/29387158/2-format2020.jpg', '@type': 'image/jpeg', '@length': '756209'}}, {'title': 'Detecon: „Das ist nicht unser Wachstumsweg“: Neuer Chef will Telekom-Beratertochter breiter aufstellen', 'link': 'https://www.handelsblatt.com/unternehmen/dienstleister/juergen-schaefer-neuer-chef-will-telekom-beratertochter-detecon-breiter-aufstellen-/29380426.html', 'description': 'Mit oder ohne die Telekom? Der ehemalige Roland-Berger-Berater Jürgen Schäfer will mehr Synergien mit dem Mutterkonzern nutzen – und gleichzeitig externe Kunden gewinnen.', 'category': 'Dienstleister', 'pubDate': 'Tue, 12 Sep 2023 15:47:29 +0200', 'guid': 'https://www.handelsblatt.com/29380426.html', 'content:encoded': '\"\"Mit oder ohne die Telekom? Der ehemalige Roland-Berger-Berater Jürgen Schäfer will mehr Synergien mit dem Mutterkonzern nutzen – und gleichzeitig externe Kunden gewinnen.', 'enclosure': {'@url': 'https://www.handelsblatt.com/images/juergen-schaefer/29384144/3-format2020.jpg', '@type': 'image/jpeg', '@length': '253142'}}]\n" + ] + } + ], "source": [ "handelsblatt = HandelsblattRSS()\n", "\n", "items = handelsblatt.get_news_for_category()\n", + "print(items)\n", + "# from utils.mongodb.mongo import MongoConnector, MongoNewsService\n", "\n", - "from utils.mongodb.mongo import MongoConnector, MongoNewsService\n", + "# connector = MongoConnector(\n", + "# hostname=\"trisnol.tech\",\n", + "# database=\"transparenzregister\",\n", + "# username=\"root\",\n", + "# password=\"pR0R0v2e2\",\n", + "# )\n", "\n", - "connector = MongoConnector(\n", - " hostname=\"trisnol.tech\",\n", - " database=\"transparenzregister\",\n", - " username=\"root\",\n", - " password=\"pR0R0v2e2\",\n", - ")\n", - "\n", - "service = MongoNewsService(connector)" + "# service = MongoNewsService(connector)" ] }, { @@ -870,7 +878,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.7" + "version": "3.11.3" }, "orig_nbformat": 4 }, diff --git a/poetry.lock b/poetry.lock index f5ed50a..06d4b01 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,5 +1,17 @@ # This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. +[[package]] +name = "aenum" +version = "3.1.15" +description = "Advanced Enumerations (compatible with Python's stdlib Enum), NamedTuples, and NamedConstants" +optional = false +python-versions = "*" +files = [ + {file = "aenum-3.1.15-py2-none-any.whl", hash = "sha256:27b1710b9d084de6e2e695dab78fe9f269de924b51ae2850170ee7e1ca6288a5"}, + {file = "aenum-3.1.15-py3-none-any.whl", hash = "sha256:e0dfaeea4c2bd362144b87377e2c61d91958c5ed0b4daf89cb6f45ae23af6288"}, + {file = "aenum-3.1.15.tar.gz", hash = "sha256:8cbd76cd18c4f870ff39b24284d3ea028fbe8731a58df3aa581e434c575b9559"}, +] + [[package]] name = "alabaster" version = "0.7.13" @@ -5610,4 +5622,4 @@ ingest = ["selenium"] [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "ca7006861e8580466abc2a7e0555ef97365754f6406e83a777ee0a87bc8c1dc0" +content-hash = "f8728eee18c7402c68901a65631c2f3c0bd1a04fb1fb952f3746a12f47a9b9a4" diff --git a/pyproject.toml b/pyproject.toml index b6b5291..bd3f5a8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,6 +36,7 @@ version = "0.1.0" [tool.poetry.dependencies] SQLAlchemy = {version = "^1.4.46", extras = ["mypy"]} +aenum = "^3.1.15" dash = "^2.11.1" dash-bootstrap-components = "^1.4.2" deutschland = {git = "https://github.com/TrisNol/deutschland.git", branch = "hotfix/python-3.11-support"} diff --git a/src/aki_prj23_transparenzregister/models/company.py b/src/aki_prj23_transparenzregister/models/company.py index 69972be..0668b5f 100644 --- a/src/aki_prj23_transparenzregister/models/company.py +++ b/src/aki_prj23_transparenzregister/models/company.py @@ -2,16 +2,31 @@ from dataclasses import asdict, dataclass from enum import Enum +from aenum import MultiValueEnum -class RelationshipRoleEnum(Enum): - """_summary_. - Args: - Enum (_type_): _description_ - """ +class RelationshipRoleEnum(str, MultiValueEnum): + """Roles taken by entities in relationships to a Company.""" - STAKEHOLDER = "" ORGANISATION = "ORGANISATION" + KOMMANDITIST = "Kommanditist(in)", "Kommanditist" + GESCHAEFTSFUEHRER = "Geschäftsführer(in)", "Geschäftsführer" + PROKURIST = "Prokurist(in)", "Prokurist" + VORSTAND = "Vorstand" + INHABER = "Inhaber(in)", "Inhaber" + HAFTENDER_GESELLSCHAFTER = ( + "Persönlich haftende(r) Gesellschafter(in)", + "Persönlich haftender Gesellschafter", + ) + LIQUIDATOR = "Liquidator(in)", "Liquidator" + PARTNER = "Partner(in)", "Partner" + DIREKTOR = "Geschäftsführende(r) Direktor(in)", "Geschäftsführender Direktor" + LEITUNG = "Mitglied des Leitungsorgans" + VORSTANDSVORSITZENDER = "Vorstandsvorsitzende(r)", "Vorstandsvorsitzender" + NACHFOLGER = "Rechtsnachfolger" + STAENDIGER_VERTRETER = "Ständige(r) Vertreter(in)" + SONSTIGER_VERTRETER = "Sonstige(r) Vertreter(in)", "Sonstiger Vertreter" + GESCHAEFTSLEITER = "Geschäftsleiter(in)", "Geschäftsleiter" @dataclass @@ -32,7 +47,7 @@ class Location: zip_code: str | None = None -class CompanyRelationshipEnum(Enum): +class CompanyRelationshipEnum(str, Enum): """Type of companyrelations.""" PERSON = "Person" @@ -136,10 +151,10 @@ class Company: last_update: str relationships: list[CompanyRelationship] # yearly_results: Optional[list[FinancialResults]] - company_type: str # TODO define Enum - capital: Capital | None - business_purpose: str - founding_date: str + company_type: str | None = None # TODO define Enum + capital: Capital | None | None = None + business_purpose: str | None = None + founding_date: str | None = None def to_dict(self) -> dict: """_summary_. diff --git a/src/aki_prj23_transparenzregister/utils/data_extraction/unternehmensregister/__init__.py b/src/aki_prj23_transparenzregister/utils/data_extraction/unternehmensregister/__init__.py new file mode 100644 index 0000000..9cc8256 --- /dev/null +++ b/src/aki_prj23_transparenzregister/utils/data_extraction/unternehmensregister/__init__.py @@ -0,0 +1 @@ +"""Everything regarding data extraction from the Unternehmensregister.""" diff --git a/src/aki_prj23_transparenzregister/utils/data_extraction/unternehmensregister/transform.py b/src/aki_prj23_transparenzregister/utils/data_extraction/unternehmensregister/transform.py index 2d0eea2..2f599a4 100644 --- a/src/aki_prj23_transparenzregister/utils/data_extraction/unternehmensregister/transform.py +++ b/src/aki_prj23_transparenzregister/utils/data_extraction/unternehmensregister/transform.py @@ -12,10 +12,14 @@ from tqdm import tqdm from aki_prj23_transparenzregister.models.company import ( Capital, Company, + CompanyID, CompanyRelationship, + CompanyRelationshipEnum, CompanyToCompanyRelationship, Location, + PersonName, PersonToCompanyRelationship, + RelationshipRoleEnum, ) @@ -57,7 +61,45 @@ def parse_stakeholder(data: dict) -> CompanyRelationship | None: "description": data["Beteiligter"]["Natuerliche_Person"][ "Voller_Name" ]["Nachname"], - "location": { + "location": Location( + **{ + "city": data["Beteiligter"]["Natuerliche_Person"][ + "Anschrift" + ][-1]["Ort"] + if isinstance( + data["Beteiligter"]["Natuerliche_Person"]["Anschrift"], + list, + ) + else data["Beteiligter"]["Natuerliche_Person"]["Anschrift"][ + "Ort" + ] + } + ), + "role": RelationshipRoleEnum( + data["Rolle"]["Rollenbezeichnung"]["content"] + ), + "type": CompanyRelationshipEnum.COMPANY, + } + ) + return PersonToCompanyRelationship( + **{ + "name": PersonName( + **{ + "firstname": data["Beteiligter"]["Natuerliche_Person"][ + "Voller_Name" + ]["Vorname"], + "lastname": data["Beteiligter"]["Natuerliche_Person"][ + "Voller_Name" + ]["Nachname"], + } + ), + "date_of_birth": data["Beteiligter"]["Natuerliche_Person"]["Geburt"][ + "Geburtsdatum" + ] + if "Geburt" in data["Beteiligter"]["Natuerliche_Person"] + else None, + "location": Location( + **{ "city": data["Beteiligter"]["Natuerliche_Person"]["Anschrift"][ -1 ]["Ort"] @@ -67,37 +109,12 @@ def parse_stakeholder(data: dict) -> CompanyRelationship | None: else data["Beteiligter"]["Natuerliche_Person"]["Anschrift"][ "Ort" ] - }, - "role": data["Rolle"]["Rollenbezeichnung"]["content"], - "type": "Company", - } - ) - return PersonToCompanyRelationship( - **{ - "name": { - "firstname": data["Beteiligter"]["Natuerliche_Person"][ - "Voller_Name" - ]["Vorname"], - "lastname": data["Beteiligter"]["Natuerliche_Person"][ - "Voller_Name" - ]["Nachname"], - }, - "date_of_birth": data["Beteiligter"]["Natuerliche_Person"]["Geburt"][ - "Geburtsdatum" - ] - if "Geburt" in data["Beteiligter"]["Natuerliche_Person"] - else None, - "location": { - "city": data["Beteiligter"]["Natuerliche_Person"]["Anschrift"][-1][ - "Ort" - ] - if isinstance( - data["Beteiligter"]["Natuerliche_Person"]["Anschrift"], list - ) - else data["Beteiligter"]["Natuerliche_Person"]["Anschrift"]["Ort"] - }, - "role": data["Rolle"]["Rollenbezeichnung"]["content"], - "type": "Person", + } + ), + "role": RelationshipRoleEnum( + data["Rolle"]["Rollenbezeichnung"]["content"] + ), + "type": CompanyRelationshipEnum.PERSON, } ) if "Organisation" in data["Beteiligter"]: @@ -107,23 +124,29 @@ def parse_stakeholder(data: dict) -> CompanyRelationship | None: "description": data["Beteiligter"]["Organisation"]["Bezeichnung"][ "Bezeichnung_Aktuell" ], - "location": { - "city": data["Beteiligter"]["Organisation"]["Anschrift"]["Ort"], - "street": data["Beteiligter"]["Organisation"]["Anschrift"][ - "Strasse" - ] - if "Strasse" in data["Beteiligter"]["Organisation"]["Anschrift"] - else None, - "house_number": data["Beteiligter"]["Organisation"]["Anschrift"][ - "Hausnummer" - ] - if "Hausnummer" in data["Beteiligter"]["Organisation"]["Anschrift"] - else None, - "zip_code": data["Beteiligter"]["Organisation"]["Anschrift"][ - "Postleitzahl" - ], - }, - "type": "Company", + "location": Location( + **{ + "city": data["Beteiligter"]["Organisation"]["Anschrift"]["Ort"], + "street": data["Beteiligter"]["Organisation"]["Anschrift"][ + "Strasse" + ] + if "Strasse" in data["Beteiligter"]["Organisation"]["Anschrift"] + else None, + "house_number": data["Beteiligter"]["Organisation"][ + "Anschrift" + ]["Hausnummer"] + if "Hausnummer" + in data["Beteiligter"]["Organisation"]["Anschrift"] + else None, + "zip_code": data["Beteiligter"]["Organisation"]["Anschrift"][ + "Postleitzahl" + ] + if "Postleitzahl" + in data["Beteiligter"]["Organisation"]["Anschrift"] + else None, + } + ), + "type": CompanyRelationshipEnum.COMPANY, } ) return None @@ -166,20 +189,6 @@ def loc_from_beteiligung(data: dict) -> Location: ) -def name_from_organisation(data: dict) -> str: - """Extract the company from the description. - - Args: - data (dict): Data export - - Returns: - str: Company name - """ - return data["XJustiz_Daten"]["Fachdaten_Register"]["Basisdaten_Register"][ - "Organisation" - ]["Bezeichnung"]["Bezeichnung_Aktuell"] - - def name_from_beteiligung(data: dict) -> str: """Extract the Company name from an Unternehmensregister export by using the first relationship found. @@ -374,6 +383,48 @@ def map_founding_date(data: dict) -> str | None: return None +def map_company_id(data: dict) -> CompanyID: + """Retrieve Company ID from export. + + Args: + data (dict): Data export + + Returns: + CompanyID: ID of the company + """ + return CompanyID( + **{ + "hr_number": data["XJustiz_Daten"]["Grunddaten"]["Verfahrensdaten"][ + "Instanzdaten" + ]["Aktenzeichen"], + "district_court": { + "name": data["XJustiz_Daten"]["Grunddaten"]["Verfahrensdaten"][ + "Beteiligung" + ][1]["Beteiligter"]["Organisation"]["Bezeichnung"][ + "Bezeichnung_Aktuell" + ] + if "Organisation" + in data["XJustiz_Daten"]["Grunddaten"]["Verfahrensdaten"][ + "Beteiligung" + ][1]["Beteiligter"] + else data["XJustiz_Daten"]["Grunddaten"]["Verfahrensdaten"][ + "Beteiligung" + ][1]["Beteiligter"]["Natuerliche_Person"]["Voller_Name"]["Nachname"], + "city": data["XJustiz_Daten"]["Grunddaten"]["Verfahrensdaten"][ + "Beteiligung" + ][1]["Beteiligter"]["Organisation"]["Sitz"]["Ort"] + if "Organisation" + in data["XJustiz_Daten"]["Grunddaten"]["Verfahrensdaten"][ + "Beteiligung" + ][1]["Beteiligter"] + else data["XJustiz_Daten"]["Grunddaten"]["Verfahrensdaten"][ + "Beteiligung" + ][1]["Beteiligter"]["Natuerliche_Person"]["Anschrift"]["Ort"], + }, + } + ) + + def map_unternehmensregister_json(data: dict) -> Company: """Processes the Unternehmensregister structured export to a Company by using several helper methods. @@ -386,33 +437,7 @@ def map_unternehmensregister_json(data: dict) -> Company: result: dict = {"relationships": []} # TODO Refactor mapping - this is a nightmare... - result["id"] = { - "hr_number": data["XJustiz_Daten"]["Grunddaten"]["Verfahrensdaten"][ - "Instanzdaten" - ]["Aktenzeichen"], - "district_court": { - "name": data["XJustiz_Daten"]["Grunddaten"]["Verfahrensdaten"][ - "Beteiligung" - ][1]["Beteiligter"]["Organisation"]["Bezeichnung"]["Bezeichnung_Aktuell"] - if "Organisation" - in data["XJustiz_Daten"]["Grunddaten"]["Verfahrensdaten"]["Beteiligung"][1][ - "Beteiligter" - ] - else data["XJustiz_Daten"]["Grunddaten"]["Verfahrensdaten"]["Beteiligung"][ - 1 - ]["Beteiligter"]["Natuerliche_Person"]["Voller_Name"]["Nachname"], - "city": data["XJustiz_Daten"]["Grunddaten"]["Verfahrensdaten"][ - "Beteiligung" - ][1]["Beteiligter"]["Organisation"]["Sitz"]["Ort"] - if "Organisation" - in data["XJustiz_Daten"]["Grunddaten"]["Verfahrensdaten"]["Beteiligung"][1][ - "Beteiligter" - ] - else data["XJustiz_Daten"]["Grunddaten"]["Verfahrensdaten"]["Beteiligung"][ - 1 - ]["Beteiligter"]["Natuerliche_Person"]["Anschrift"]["Ort"], - }, - } + result["id"] = map_company_id(data) result["name"] = name_from_beteiligung(data) result["location"] = loc_from_beteiligung(data) @@ -438,12 +463,12 @@ def map_unternehmensregister_json(data: dict) -> Company: if __name__ == "__main__": from loguru import logger - transform_xml_to_json( - "./data/Unternehmensregister/scraping/", "./data/Unternehmensregister/export/" - ) - - for file in tqdm(glob.glob1("./data/Unternehmensregister/export", "*.json")): - path = os.path.join("./data/Unternehmensregister/export", file) + # transform_xml_to_json( + # "./data/Unternehmensregister/scraping/", "./data/Unternehmensregister/export/" + # ) + base_path = "./Jupyter/API-tests/Unternehmensregister/data/Unternehmensregister" + for file in tqdm(glob.glob1(f"{base_path}/export", "*.json")): + path = os.path.join(f"{base_path}/export", file) with open(path, encoding="utf-8") as file_object: try: data = json.loads(file_object.read()) @@ -452,7 +477,7 @@ if __name__ == "__main__": name = "".join(e for e in company.name if e.isalnum())[:50] with open( - f"./data/Unternehmensregister/transformed/{name}.json", + f"{base_path}/transformed/{name}.json", "w+", encoding="utf-8", ) as export_file: diff --git a/tests/models/company_test.py b/tests/models/company_test.py index a044492..df0a0f7 100644 --- a/tests/models/company_test.py +++ b/tests/models/company_test.py @@ -1,7 +1,12 @@ """Test Models.company.""" -from aki_prj23_transparenzregister.models.company import Company, CompanyID, Location +from aki_prj23_transparenzregister.models.company import ( + Capital, + Company, + CompanyID, + Location, +) def test_to_dict() -> None: @@ -10,12 +15,17 @@ def test_to_dict() -> None: location = Location( city="Insmouth", house_number="19", street="Harbor", zip_code="1890" ) + capital = Capital(currency="BTC", type="Virtual assets", value=42) company = Company( id=company_id, last_update="Tomorrow", location=location, name="BLANK GmbH", relationships=[], + business_purpose="Blockchain and NFTs", + capital=capital, + company_type="Something", + founding_date="Yesterday", ) assert company.to_dict() == { @@ -32,4 +42,12 @@ def test_to_dict() -> None: }, "name": "BLANK GmbH", "relationships": [], + "business_purpose": "Blockchain and NFTs", + "capital": { + "value": capital.value, + "currency": capital.currency, + "type": capital.type, + }, + "company_type": "Something", + "founding_date": "Yesterday", } diff --git a/tests/utils/data_extraction/__init__.py b/tests/utils/data_extraction/__init__.py deleted file mode 100644 index 0388525..0000000 --- a/tests/utils/data_extraction/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Tests for data_extraction.""" diff --git a/tests/utils/data_extraction/unternehmensregister/extract_test.py b/tests/utils/data_extraction/unternehmensregister/extract_test.py new file mode 100644 index 0000000..21d4c50 --- /dev/null +++ b/tests/utils/data_extraction/unternehmensregister/extract_test.py @@ -0,0 +1,81 @@ +import glob +import os +from tempfile import TemporaryDirectory + +from aki_prj23_transparenzregister.utils.data_extraction.unternehmensregister import ( + extract, +) + + +def prepare_temporary_dir(directory: str, formats: list[str]) -> None: + for index in range(len(formats)): + test_file = os.path.join(directory, f"file-{index}.{formats[index]}") + with open(test_file, "w") as file: + file.write(f"Hello There {index}") + + +def test_rename_latest_file() -> None: + with TemporaryDirectory() as temp_dir: + # Create some test files in the temporary directory + test_file1 = os.path.join(temp_dir, "file1.xml") + test_file2 = os.path.join(temp_dir, "file2.xml") + test_file3 = os.path.join(temp_dir, "file3.xml") + + # Create files with different modification times + with open(test_file1, "w") as f: + f.write("Content 1") + with open(test_file2, "w") as f: + f.write("Content 2") + with open(test_file3, "w") as f: + f.write("Content 3") + + # Rename the latest file to 'new_file.xml' + extract.rename_latest_file(temp_dir, "new_file.xml") + + glob.glob1(temp_dir, "*.xml") + # Verify that 'file3.xml' is renamed to 'new_file.xml' + assert not os.path.exists(test_file3) + assert os.path.exists(os.path.join(temp_dir, "new_file.xml")) + + # Verify that 'file1.xml' and 'file2.xml' are still present + assert os.path.exists(test_file1) + assert os.path.exists(test_file2) + + # Verify that renaming with a different pattern works + with open(test_file1, "w") as f: + f.write("Content 4") + with open(os.path.join(temp_dir, "file4.txt"), "w") as f: + f.write("Content 5") + + # Rename the latest .txt file to 'new_file.txt' + extract.rename_latest_file(temp_dir, "new_file.txt", pattern="*.txt") + + # Verify that 'file4.txt' is renamed to 'new_file.txt' + assert not os.path.exists(os.path.join(temp_dir, "file4.txt")) + assert os.path.exists(os.path.join(temp_dir, "new_file.txt")) + + # Verify that 'file1.xml' is still present and unchanged + with open(test_file1) as f: + assert f.read() == "Content 4" + + +def test_get_num_files_default_pattern() -> None: + with TemporaryDirectory() as temp_dir: + prepare_temporary_dir(temp_dir, ["xml", "xml", "xml"]) + + expected_result = 3 + assert extract.get_num_files(temp_dir) == expected_result + + +def test_get_num_files_different_pattern() -> None: + with TemporaryDirectory() as temp_dir: + prepare_temporary_dir(temp_dir, ["xml", "txt", "json"]) + + num_files = extract.get_num_files(temp_dir, "*.txt") + assert num_files == 1 + + +def test_wait_for_download_condition() -> None: + with TemporaryDirectory() as temp_dir: + prepare_temporary_dir(temp_dir, ["xml", "txt"]) + assert extract.wait_for_download_condition(temp_dir, 2) is False diff --git a/tests/utils/data_extraction/unternehmensregister/load_test.py b/tests/utils/data_extraction/unternehmensregister/load_test.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/utils/data_extraction/unternehmensregister/transform_test.py b/tests/utils/data_extraction/unternehmensregister/transform_test.py new file mode 100644 index 0000000..091f861 --- /dev/null +++ b/tests/utils/data_extraction/unternehmensregister/transform_test.py @@ -0,0 +1,208 @@ +import json +import os +from tempfile import TemporaryDirectory + +from aki_prj23_transparenzregister.models.company import ( + CompanyRelationshipEnum, + CompanyToCompanyRelationship, + Location, + PersonName, + PersonToCompanyRelationship, + RelationshipRoleEnum, +) +from aki_prj23_transparenzregister.utils.data_extraction.unternehmensregister import ( + transform, +) + + +def test_transform_xml_to_json() -> None: + with TemporaryDirectory() as temp_source_dir: + with open(os.path.join(temp_source_dir, "test.xml"), "w") as file: + xml_input = """ + + Hello World! + + """ + file.write(xml_input) + with TemporaryDirectory() as temp_target_dir: + transform.transform_xml_to_json(temp_source_dir, temp_target_dir) + with open(os.path.join(temp_target_dir, "test.json")) as file: + json_output = json.load(file) + assert json_output == {"test": {"message": "Hello World!"}} + + +def test_parse_stakeholder_org_hidden_in_person() -> None: + data = { + "Beteiligter": { + "Natuerliche_Person": { + "Voller_Name": {"Vorname": None, "Nachname": "Some Company KG"}, + "Anschrift": {"Ort": "Area 51"}, + } + }, + "Rolle": {"Rollenbezeichnung": {"content": "Kommanditist(in)"}}, + } + expected_result = CompanyToCompanyRelationship( + role=RelationshipRoleEnum.KOMMANDITIST, # type: ignore + description="Some Company KG", + type=CompanyRelationshipEnum.COMPANY, + location=Location(**{"city": "Area 51"}), + ) + assert transform.parse_stakeholder(data) == expected_result + + +def test_parse_stakeholder_person() -> None: + data = { + "Beteiligter": { + "Natuerliche_Person": { + "Voller_Name": {"Vorname": "Stephen", "Nachname": "King"}, + "Anschrift": {"Ort": "Maine"}, + "Geburt": {"Geburtsdatum": "1947-09-21"}, + } + }, + "Rolle": {"Rollenbezeichnung": {"content": "Geschäftsleiter(in)"}}, + } + expected_result = PersonToCompanyRelationship( + role=RelationshipRoleEnum.GESCHAEFTSLEITER, # type: ignore + date_of_birth="1947-09-21", + name=PersonName(**{"firstname": "Stephen", "lastname": "King"}), + type=CompanyRelationshipEnum.PERSON, + location=Location(**{"city": "Maine"}), + ) + assert transform.parse_stakeholder(data) == expected_result + + +def test_parse_stakeholder_org() -> None: + data = { + "Beteiligter": { + "Organisation": { + "Bezeichnung": {"Bezeichnung_Aktuell": "Transparenzregister kG"}, + "Anschrift": { + "Ort": "Iserlohn", + "Strasse": "Hauptstrasse", + "Hausnummer": "42", + "Postleitzahl": "58636", + }, + "Geburt": {"Geburtsdatum": "1947-09-21"}, + } + }, + "Rolle": {"Rollenbezeichnung": {"content": "Geschäftsführender Direktor"}}, + } + expected_result = CompanyToCompanyRelationship( + description="Transparenzregister kG", + role=RelationshipRoleEnum.DIREKTOR, # type: ignore + type=CompanyRelationshipEnum.COMPANY, + location=Location( + **{ + "city": "Iserlohn", + "zip_code": "58636", + "house_number": "42", + "street": "Hauptstrasse", + } + ), + ) + assert transform.parse_stakeholder(data) == expected_result + + +def test_parse_stakeholder_no_result() -> None: + data: dict = {"Beteiligter": {}} + assert transform.parse_stakeholder(data) is None + + +def test_loc_from_beteiligung() -> None: + data = { + "XJustiz_Daten": { + "Grunddaten": { + "Verfahrensdaten": { + "Beteiligung": [ + { + "Beteiligter": { + "Beteiligtennummer": "1", + "Organisation": { + "Bezeichnung": { + "Bezeichnung_Aktuell": "1 A Autenrieth Kunststofftechnik GmbH & Co. KG" + }, + "Sitz": { + "Ort": "Heroldstatt", + "Staat": { + "@xsi:type": "WL_Staaten", + "@wl_version": "1.5", + "@wl_fassung": "2", + "content": "DE", + }, + }, + "Anschrift": { + "Strasse": "Gewerbestraße", + "Hausnummer": "8", + "Postleitzahl": "72535", + "Ort": "Heroldstatt", + }, + }, + } + }, + ] + } + } + } + } + + expected_result = Location( + city="Heroldstatt", house_number="8", street="Gewerbestraße", zip_code="72535" + ) + assert transform.loc_from_beteiligung(data) == expected_result + + +def test_name_from_beteiligung() -> None: + data = { + "XJustiz_Daten": { + "Grunddaten": { + "Verfahrensdaten": { + "Beteiligung": [ + { + "Beteiligter": { + "Beteiligtennummer": "1", + "Organisation": { + "Bezeichnung": { + "Bezeichnung_Aktuell": "1 A Autenrieth Kunststofftechnik GmbH & Co. KG" + }, + }, + } + }, + ] + } + } + } + } + + expected_result = "1 A Autenrieth Kunststofftechnik GmbH & Co. KG" + assert transform.name_from_beteiligung(data) == expected_result + + +def test_map_rechtsform() -> None: + data = { + "XJustiz_Daten": { + "Fachdaten_Register": { + "Basisdaten_Register": { + "Aktuelles_Satzungsdatum": "1952-07-15", + "Rechtstraeger": { + "Rechtsform": { + "content": "Gesellschaft mit beschränkter Haftung" + }, + }, + } + } + } + } + expected_result = "Gesellschaft mit beschränkter Haftung" + assert transform.map_rechtsform("", data) == expected_result + + +def test_map_rechtsform_from_name() -> None: + data = [ + ("GEA Farm Technologies GmbH", "Gesellschaft mit beschränkter Haftung"), + ("Atos SE", "Europäische Aktiengesellschaft (SE)"), + ("Bilkenroth KG", "Kommanditgesellschaft"), + ("jfoiahfo8sah 98548902 öhz ö", None), + ] + + for company_name, expected_result in data: + assert transform.map_rechtsform(company_name, {}) == expected_result