From 66bb66dd3652d48be1483143af093220bdd83467 Mon Sep 17 00:00:00 2001 From: Maciej Pienczyn Date: Sun, 1 Feb 2026 07:56:56 +0100 Subject: [PATCH] feat: Add all 10 missing KRS data fields MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extend KRS data collection and display: 1. NIP - displayed in company profile 2. REGON - displayed in company profile 3. Email from KRS (adresPocztyElektronicznej) 4. WWW from KRS (adresStronyInternetowej) 5. ePUAP address (adresDoDoreczenElektronicznychWpisanyDoBAE) 6. Company agreement date (data zawarcia umowy) 7. Company duration (czas trwania spółki) 8. Share information (informacja o udziałach) 9. Financial statements history (sprawozdania finansowe) 10. Full PKD codes with class/subclass (e.g., 62.03.Z) 11. Court registry data (sygnatura, sąd, rok obrotowy) Updated krs_api_service.py: - Extended KRSCompanyData dataclass with new fields - Updated parse_krs_response() to extract all data - PKD now returns dict with kod, opis, glowna Updated templates/company_detail.html: - Display NIP and REGON from KRS - Contact section with email, www, ePUAP - Company agreement section - Financial statements history grid - Court registry information - Improved PKD display with full codes Co-Authored-By: Claude Opus 4.5 --- krs_api_service.py | 112 ++++++++++++++++++++++++++++-- templates/company_detail.html | 126 ++++++++++++++++++++++++++++++++-- 2 files changed, 227 insertions(+), 11 deletions(-) diff --git a/krs_api_service.py b/krs_api_service.py index 3b7b093..4cc8266 100644 --- a/krs_api_service.py +++ b/krs_api_service.py @@ -36,6 +36,12 @@ class KRSCompanyData: powiat: Optional[str] gmina: Optional[str] kraj: str + poczta: Optional[str] # NOWE + + # Contact from KRS (NOWE) + email_krs: Optional[str] + www_krs: Optional[str] + adres_epuap: Optional[str] # Capital kapital_zakladowy: Optional[float] @@ -46,17 +52,31 @@ class KRSCompanyData: data_ostatniego_wpisu: Optional[str] numer_ostatniego_wpisu: Optional[int] + # Company agreement/statute (NOWE) + data_umowy_spolki: Optional[str] + czas_trwania_spolki: Optional[str] + informacja_o_udzialach: Optional[str] + # Management (anonymized in Open API) zarzad: List[Dict[str, str]] + nazwa_organu: Optional[str] # NOWE sposob_reprezentacji: Optional[str] # Shareholders (anonymized in Open API) wspolnicy: List[Dict[str, Any]] # Other - przedmiot_dzialalnosci: List[str] + przedmiot_dzialalnosci: List[Dict[str, str]] # ZMIANA: teraz słownik z pełnymi kodami czy_opp: bool + # Financial statements (NOWE) + sprawozdania_finansowe: List[Dict[str, str]] + + # Court/Registry info (NOWE) + sygnatura_akt: Optional[str] + sad_rejestrowy: Optional[str] + dzien_konczacy_rok_obrotowy: Optional[str] + # Metadata data_odpisu: str stan_z_dnia: str @@ -80,6 +100,12 @@ class KRSCompanyData: 'powiat': self.powiat, 'gmina': self.gmina, 'kraj': self.kraj, + 'poczta': self.poczta, + }, + 'kontakt_krs': { + 'email': self.email_krs, + 'www': self.www_krs, + 'adres_epuap': self.adres_epuap, }, 'kapital': { 'zakladowy': self.kapital_zakladowy, @@ -90,11 +116,23 @@ class KRSCompanyData: 'ostatniego_wpisu': self.data_ostatniego_wpisu, 'numer_ostatniego_wpisu': self.numer_ostatniego_wpisu, }, + 'umowa_spolki': { + 'data_umowy': self.data_umowy_spolki, + 'czas_trwania': self.czas_trwania_spolki, + 'informacja_o_udzialach': self.informacja_o_udzialach, + }, 'zarzad': self.zarzad, + 'nazwa_organu': self.nazwa_organu, 'sposob_reprezentacji': self.sposob_reprezentacji, 'wspolnicy': self.wspolnicy, 'przedmiot_dzialalnosci': self.przedmiot_dzialalnosci, 'czy_opp': self.czy_opp, + 'sprawozdania_finansowe': self.sprawozdania_finansowe, + 'rejestr': { + 'sygnatura_akt': self.sygnatura_akt, + 'sad_rejestrowy': self.sad_rejestrowy, + 'dzien_konczacy_rok_obrotowy': self.dzien_konczacy_rok_obrotowy, + }, 'metadata': { 'data_odpisu': self.data_odpisu, 'stan_z_dnia': self.stan_z_dnia, @@ -161,7 +199,7 @@ def parse_krs_response(data: Dict[str, Any]) -> Optional[KRSCompanyData]: dane_podmiotu = dzial1.get('danePodmiotu', {}) identyfikatory = dane_podmiotu.get('identyfikatory', {}) - # Address + # Address and Contact siedziba_adres = dzial1.get('siedzibaIAdres', {}) siedziba = siedziba_adres.get('siedziba', {}) adres = siedziba_adres.get('adres', {}) @@ -170,6 +208,16 @@ def parse_krs_response(data: Dict[str, Any]) -> Optional[KRSCompanyData]: kapital = dzial1.get('kapital', {}) kapital_zakladowy = kapital.get('wysokoscKapitaluZakladowego', {}) + # Company agreement/statute + umowa_statut = dzial1.get('umowaStatut', {}) + pozostale = dzial1.get('pozostaleInformacje', {}) + + # Get first date of company agreement + data_umowy = None + umowy_list = umowa_statut.get('informacjaOZawarciuZmianieUmowyStatutu', []) + if umowy_list: + data_umowy = umowy_list[0].get('zawarcieZmianaUmowyStatutu') + # Management reprezentacja = dzial2.get('reprezentacja', {}) sklad_zarzadu = reprezentacja.get('sklad', []) @@ -181,7 +229,7 @@ def parse_krs_response(data: Dict[str, Any]) -> Optional[KRSCompanyData]: 'imie_drugie': osoba.get('imiona', {}).get('imieDrugie', ''), 'nazwisko': osoba.get('nazwisko', {}).get('nazwiskoICzlon', ''), 'funkcja': osoba.get('funkcjaWOrganie', ''), - # Note: Data is anonymized in Open API + 'zawieszona': osoba.get('czyZawieszona', False), }) # Shareholders @@ -195,13 +243,36 @@ def parse_krs_response(data: Dict[str, Any]) -> Optional[KRSCompanyData]: 'calosc_udzialow': wspolnik.get('czyPosiadaCaloscUdzialow', False), }) - # Business activities (PKD) + # Business activities (PKD) - with full codes przedmiot = [] przedmiot_dzial = dzial3.get('przedmiotDzialalnosci', {}) for pkd in przedmiot_dzial.get('przedmiotPrzewazajacejDzialalnosci', []): - przedmiot.append(f"{pkd.get('kodDzial', '')} - {pkd.get('opis', '')} (główna)") + kod_pelny = f"{pkd.get('kodDzial', '')}.{pkd.get('kodKlasa', '')}.{pkd.get('kodPodklasa', '')}" + przedmiot.append({ + 'kod': kod_pelny, + 'opis': pkd.get('opis', ''), + 'glowna': True, + }) for pkd in przedmiot_dzial.get('przedmiotPozostalejDzialalnosci', []): - przedmiot.append(f"{pkd.get('kodDzial', '')} - {pkd.get('opis', '')}") + kod_pelny = f"{pkd.get('kodDzial', '')}.{pkd.get('kodKlasa', '')}.{pkd.get('kodPodklasa', '')}" + przedmiot.append({ + 'kod': kod_pelny, + 'opis': pkd.get('opis', ''), + 'glowna': False, + }) + + # Financial statements + sprawozdania = [] + wzmianki = dzial3.get('wzmiankiOZlozonychDokumentach', {}) + for sf in wzmianki.get('wzmiankaOZlozeniuRocznegoSprawozdaniaFinansowego', []): + sprawozdania.append({ + 'data_zlozenia': sf.get('dataZlozenia', ''), + 'za_okres': sf.get('zaOkresOdDo', ''), + }) + + # Fiscal year end + rok_obrotowy = dzial3.get('informacjaODniuKonczacymRokObrotowy', {}) + dzien_konczacy = rok_obrotowy.get('dzienKonczacyPierwszyRokObrotowy') # Parse capital value kapital_value = None @@ -219,6 +290,7 @@ def parse_krs_response(data: Dict[str, Any]) -> Optional[KRSCompanyData]: regon=identyfikatory.get('regon'), forma_prawna=dane_podmiotu.get('formaPrawna', ''), + # Address ulica=adres.get('ulica'), nr_domu=adres.get('nrDomu'), nr_lokalu=adres.get('nrLokalu'), @@ -228,20 +300,48 @@ def parse_krs_response(data: Dict[str, Any]) -> Optional[KRSCompanyData]: powiat=siedziba.get('powiat'), gmina=siedziba.get('gmina'), kraj=adres.get('kraj', 'POLSKA'), + poczta=adres.get('poczta'), + # Contact from KRS + email_krs=siedziba_adres.get('adresPocztyElektronicznej'), + www_krs=siedziba_adres.get('adresStronyInternetowej'), + adres_epuap=siedziba_adres.get('adresDoDoreczenElektronicznychWpisanyDoBAE'), + + # Capital kapital_zakladowy=kapital_value, kapital_waluta=kapital_zakladowy.get('waluta', 'PLN'), + # Dates data_rejestracji=naglowek.get('dataRejestracjiWKRS'), data_ostatniego_wpisu=naglowek.get('dataOstatniegoWpisu'), numer_ostatniego_wpisu=naglowek.get('numerOstatniegoWpisu'), + # Company agreement + data_umowy_spolki=data_umowy, + czas_trwania_spolki=pozostale.get('czasNaJakiUtworzonyZostalPodmiot'), + informacja_o_udzialach=pozostale.get('informacjaOLiczbieUdzialow'), + + # Management zarzad=zarzad, + nazwa_organu=reprezentacja.get('nazwaOrganu'), sposob_reprezentacji=reprezentacja.get('sposobReprezentacji'), + + # Shareholders wspolnicy=wspolnicy, + + # Business activities przedmiot_dzialalnosci=przedmiot, czy_opp=dane_podmiotu.get('czyPosiadaStatusOPP', False), + # Financial statements + sprawozdania_finansowe=sprawozdania, + + # Court/Registry info + sygnatura_akt=naglowek.get('sygnaturaAktSprawyDotyczacejOstatniegoWpisu'), + sad_rejestrowy=naglowek.get('oznaczenieSaduDokonujacegoOstatniegoWpisu'), + dzien_konczacy_rok_obrotowy=dzien_konczacy, + + # Metadata data_odpisu=naglowek.get('dataCzasOdpisu', ''), stan_z_dnia=naglowek.get('stanZDnia', ''), ) diff --git a/templates/company_detail.html b/templates/company_detail.html index 70cf827..fd9ef0d 100755 --- a/templates/company_detail.html +++ b/templates/company_detail.html @@ -1371,6 +1371,26 @@ + + {% if krs.nip %} +
+
NIP
+
+ {{ krs.nip[:3] }}-{{ krs.nip[3:6] }}-{{ krs.nip[6:8] }}-{{ krs.nip[8:] }} +
+
+ {% endif %} + + + {% if krs.regon %} +
+
REGON
+
+ {{ krs.regon }} +
+
+ {% endif %} + {% if company.krs_registration_date or (krs.daty and krs.daty.rejestracji) %}
@@ -1391,10 +1411,66 @@
{% endif %} + + {% if krs.kontakt_krs and (krs.kontakt_krs.email or krs.kontakt_krs.www or krs.kontakt_krs.adres_epuap) %} +
+
Dane kontaktowe z KRS
+
+ {% if krs.kontakt_krs.email %} +
+
Email
+ {{ krs.kontakt_krs.email }} +
+ {% endif %} + {% if krs.kontakt_krs.www %} +
+
Strona WWW
+ {{ krs.kontakt_krs.www }} +
+ {% endif %} + {% if krs.kontakt_krs.adres_epuap %} +
+
Adres ePUAP (BAE)
+ {{ krs.kontakt_krs.adres_epuap }} +
+ {% endif %} +
+
+ {% endif %} + + + {% if krs.umowa_spolki and (krs.umowa_spolki.data_umowy or krs.umowa_spolki.czas_trwania) %} +
+
Umowa spółki
+
+ {% if krs.umowa_spolki.data_umowy %} +
+
Data zawarcia/zmiany umowy
+
{{ krs.umowa_spolki.data_umowy }}
+
+ {% endif %} + {% if krs.umowa_spolki.czas_trwania %} +
+
Czas trwania spółki
+
{{ krs.umowa_spolki.czas_trwania }}
+
+ {% endif %} + {% if krs.umowa_spolki.informacja_o_udzialach %} +
+
Informacja o udziałach
+
{{ krs.umowa_spolki.informacja_o_udzialach }}
+
+ {% endif %} +
+
+ {% endif %} + {% if company.krs_representation or krs.sposob_reprezentacji %}
-
Sposób reprezentacji
+
+ {% if krs.nazwa_organu %}{{ krs.nazwa_organu }} - {% endif %}Sposób reprezentacji +
{{ company.krs_representation or krs.sposob_reprezentacji }}
@@ -1475,11 +1551,33 @@
Przedmiot działalności z KRS ({{ krs.przedmiot_dzialalnosci|length }} PKD)
-
+
{% for pkd in krs.przedmiot_dzialalnosci %} - - {{ pkd }} - +
+ + {{ pkd.kod if pkd.kod else pkd }}{% if pkd.glowna %} ★{% endif %} + + + {{ pkd.opis if pkd.opis else '' }}{% if pkd.glowna %} (główna){% endif %} + +
+ {% endfor %} +
+
+ {% endif %} + + + {% if krs.sprawozdania_finansowe and krs.sprawozdania_finansowe|length > 0 %} +
+
+ Sprawozdania finansowe ({{ krs.sprawozdania_finansowe|length }}) +
+
+ {% for sf in krs.sprawozdania_finansowe %} +
+
Złożono: {{ sf.data_zlozenia }}
+
{{ sf.za_okres }}
+
{% endfor %}
@@ -1514,6 +1612,24 @@
{% endif %} + + {% if krs.rejestr and (krs.rejestr.sygnatura_akt or krs.rejestr.sad_rejestrowy or krs.rejestr.dzien_konczacy_rok_obrotowy) %} +
+
Dane rejestrowe
+
+ {% if krs.rejestr.sygnatura_akt %} +
Sygnatura akt: {{ krs.rejestr.sygnatura_akt }}
+ {% endif %} + {% if krs.rejestr.sad_rejestrowy %} +
Sąd dokonujący wpisu: {{ krs.rejestr.sad_rejestrowy }}
+ {% endif %} + {% if krs.rejestr.dzien_konczacy_rok_obrotowy %} +
Dzień kończący rok obrotowy: {{ krs.rejestr.dzien_konczacy_rok_obrotowy }}
+ {% endif %} +
+
+ {% endif %} + {% if krs.metadata or krs.daty %}