diff --git a/.gitignore b/.gitignore index 4cc0d4b..ac851e7 100644 --- a/.gitignore +++ b/.gitignore @@ -35,6 +35,9 @@ datasets/current/elections/campaign-expenses.trig # bulk procurement contracts (~56k a year, ~120 MB) — regenerate with `make -C etl procurement` datasets/current/procurement/contracts.trig +# bulk 2014-2020 EU-funds contracts (~26k, ~29 MB) — regenerate with `make -C etl eu-funds` +datasets/current/eu-funds/contracts.trig + # VTEK browser harvests (SKAIDRIS lobbying, PINREG private interests) — re-harvest with the # harvest-vtek skill, never edit; data/institution-aliases.csv (curated) IS committed etl/vtek/data/*.json diff --git a/CLAUDE.md b/CLAUDE.md index 1a242bd..e76cff0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -57,6 +57,18 @@ make -C etl/insolvency # company insolvency proceedings via get.data.gov # AVNT territory code to the AR municipality and emits one tidy CSV; # the lifecycle is a time:Interval on calendar days. Committed output # (~6.4k proceedings). In `make all`. +make -C etl/eu-funds # 2014-2020 EU structural-funds implementation contracts via + # get.data.gov.lt (finmin): one ltlod:EUFundingContract per + # document (eu-funds/{_id}), from finmin/sutartys/Contract (~26k, + # keyset-paginated) joined to its partners (ConPartner) and + # financing sources (ConFinSource) by _id, and to the project + # applications (finmin/paraiskos/Project) for the code + decision + # amounts. ltlod-eu-funds crosswalks the municipality text to the + # AR code. Beneficiary + partners link by bare JAR code. Most are + # code-less financial-instrument payouts; ~685 carry a project + # code with amounts. Repayments/irregularities are NOT modelled + # (their keys are a hash of an unpublished id). contracts.trig is + # gitignored bulk output (~29 MB). In `make all`. make -C etl land-acquisitions # NŽT applications to acquire agricultural/forest land (Spinta, # ~140k rows) + JAR names for the code check (547k rows); legal-entity # applications per document (applications.trig, ~430k quads, gitignored), @@ -430,7 +442,7 @@ since the rows differ in the image cell. - **dates before the calendar start** (1977-01-01, set by the earliest JAR registration 1977-11-11) would dangle: extend the calendar range in `calendar.rq` first (start date + the weekday offset), never drop the link. - Linked now: sittings, votes, agenda items, bill registrations, election rounds, campaign donations and expenses, procurement contracts, lobbying declarations, lobbyist registrations, land-acquisition applications and NŽT + Linked now: sittings, votes, agenda items, bill registrations, election rounds, campaign donations and expenses, procurement contracts, lobbying declarations, lobbyist registrations, EU-funding contract starts, land-acquisition applications and NŽT decisions (event; a contract's expiry date is left out — it reaches 2055, past the calendar); terms, sessions, Seimas seats, unit positions, parliamentary groups, public offices — @@ -675,6 +687,15 @@ reports, 624 older intentional bankruptcies added from the tyčiniai list), from municipalities resolve with 0 dangling (9 rows under the defunct Marijampolė-district code 2651 get no refArea). `ltlod:insolvent` links into `legal-entities/` dangle for every non-budget-institution until the full JAR register is loaded — expected. Committed output. +EU funds (`eu-funds/`, 2026-10-25 finmin feeds): contracts.trig = 25 978 EU-funding contracts +(3 dropped with no beneficiary code), of which 685 carry a formal project code with EU / total / +decided amounts (805 ConFinSource EU-amount rows); 1 820 project-partner links. All 25 978 graphs +validate, SHACL conforms, no blank nodes; 1 650 distinct start days and all 60 municipalities +resolve with 0 dangling. `ltlod:beneficiary`/`ltlod:fundingPartner` links into `legal-entities/` +dangle until the full JAR register is loaded — expected. Gitignored bulk output (~29 MB). +Repayments and irregularities are not modelled: their `project_hash`/`project_hash_id` keys hash +an unpublished internal SFMIS id — tested against every published id (code, `_id`, `project_id`, +`Contract._id`) under md5/sha*/crc/blake, salted, prefix/suffix, 0 matches. 2021-2027 not on Spinta. `python3 queries/render-examples.py` re-runs all example queries end-to-end. Name-based person links, audited 2026-10-21 (`make -C etl/audit score` over the 400-link sample in `etl/audit/reviews/`, verdicts filled; 0 wrong in 50 means precision >= 92.9 %; the `links` column is the diff --git a/README.md b/README.md index eea24d6..fbf8fba 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,7 @@ kalba (kaip SQL reliacinėms DB). Pavyzdžiai — [žemiau](#ką-jau-galima-atsa | [`employment`](etl/sodra/) (failas `employers.trig` neįtraukiamas į git — sugeneruojamas `make -C etl/sodra`; į git įtraukiamas tik kubo aprašas `dataset.trig`) | 114 316 darbdavių (2026 m. rugpjūtis): kiekvieno juridinio asmens (draudėjo) naujausio mėnesio apdraustųjų skaičius, vidutinis darbo užmokestis ir socialinio draudimo įmokos, taip pat paskutinių 12 mėnesių (`SODRA_MONTHS`) vidutinis apdraustųjų skaičius, pasvertas vidutinis darbo užmokestis ir įmokų suma; darbdavys susietas su JAR įrašu (`ltlod:employer`), mėnuo — su kalendoriumi (`dct:temporal`), registracijos savivaldybė — su administraciniu vienetu. Pasirinktinai (`SODRA_CUBE=1`) — ir visa mėnesių eilutė (~14 mln. ketvertų) | [Sodros atviri draudėjų duomenys](https://atvira.sodra.lt/imones/rinkiniai/index.html) (`monthly-{metai}.csv.zip`; svetainę saugo Cloudflare, todėl failai atsisiunčiami naršyklėje — žr. [`.claude/skills/harvest-sodra/`](.claude/skills/harvest-sodra/SKILL.md)) | | [`taxes`](etl/taxes/) (failai `taxpayers.trig` ir `taxes-paid.trig` neįtraukiami į git — sugeneruojami `make -C etl taxes`; į git įtraukiamas tik kubo aprašas `dataset.trig`) | 178 177 juridinių asmenų mokesčių įrašai (dviejų VMI srautų sąjunga): 30 764 turi dabartinę mokestinę nepriemoką (bendra, pradelsta, atidėta, atidėta pradelsta — EUR, su registracijos savivaldybe ir VMI skelbimo diena kalendoriuje), 620 689 (juridinis asmuo, metai) sumokėtų mokesčių stebėjimai 2022–2026 m. (175 198 skirtingi asmenys); mokesčių mokėtojas susietas su JAR įrašu (`ltlod:taxpayer`) — jungiasi su pirkimų tiekėjais, Sodros darbdaviais ir kampanijų aukotojais per tą patį kodą | [VMI](https://get.data.gov.lt/datasets/gov/vmi/ja_nepriemokos/:ns) per get.data.gov.lt (`vmi/ja_nepriemokos` nepriemokos ⋈ `vmi/ja_mokesciai` sumokėti mokesčiai, pagal JAR kodą; Valstybės duomenų agentūra, CC BY 4.0) | | [`insolvency-cases`](datasets/current/insolvency/) | 6 412 įmonių nemokumo bylų: 6 254 bankrotai (iš jų 834 pripažinti tyčiniais) ir 158 restruktūrizavimai; kiekviena byla susieta su JAR įrašu (`ltlod:insolvent`), savivaldybe ir kalendoriaus dienomis (pradžia ir pabaiga — `time:Interval`); nurodomas apygardos teismas, bankroto iniciatorius ir ne teismo / supaprastinto / tyčinio bankroto požymiai. Bankrotų ir restruktūrizavimų ataskaitiniai duomenys — nuo 2020 m., tyčinių bankrotų sąrašas — nuo 1994 m. | [AVNT](https://get.data.gov.lt/datasets/gov/avnt/imoniu_bankrotas/:ns) per get.data.gov.lt (`avnt/imoniu_bankrotas` + `avnt/imoniu_restrukturizavimas` + `avnt/tyciniai_bankrotai`; Valstybės duomenų agentūra, CC BY 4.0) | +| [`eu-funds`](etl/eu-funds/) (failas neįtraukiamas į git — sugeneruojamas `make -C etl eu-funds`) | 25 978 Europos Sąjungos struktūrinių fondų (2014–2020 m.) finansavimo sutarčių: kiekviena susieta su paramos gavėju (`ltlod:beneficiary`) ir projekto partneriais (JAR pagal įmonės kodą), savivaldybe ir pradžios diena kalendoriuje; ~685 turi formalų projekto kodą su skirtomis ES bei bendromis lėšomis (EUR), likusios — finansinių priemonių išmokos (be kodo). Lėšų grąžinimai ir pažeidimai neįtraukti — jų šaltinio raktas yra neskelbiamo vidinio identifikatoriaus maiša; 2021–2027 m. duomenų dar nėra | [Finansų ministerija](https://get.data.gov.lt/datasets/gov/finmin/sutartys/:ns) per get.data.gov.lt (`finmin/sutartys` ⋈ `finmin/paraiskos`; Valstybės duomenų agentūra, CC BY 4.0) | | [`land-acquisitions`](datasets/current/land-acquisitions/) (juridinių asmenų prašymų failas neįtraukiamas į git — sugeneruojamas `make -C etl land-acquisitions`) | prašymai Nacionalinei žemės tarnybai leisti įsigyti žemės ūkio ar miškų ūkio paskirties žemės (nuo 2023 m.): 17 842 juridinių asmenų prašymai po vieną — su NŽT sprendimu, prašomu ir jau valdomu plotu, savivaldybe, pateikimo ir sprendimo dienomis, susieti su juridiniu asmeniu, jei NŽT nurodytas pavadinimas atitinka JAR kodą; 121 869 fizinių asmenų prašymai — tik suskaičiuoti pagal savivaldybę, metus ir paskirtį (447 suvestinės, mažiau nei 3 prašymų langeliai praleisti), nes NŽT jų kodus ir vardus užšifruoja | [NŽT](https://get.data.gov.lt/datasets/gov/nzt/paraiskos/Paraiska) per get.data.gov.lt; pavadinimų patikra — pagal JAR | | [`calendar`](etl/calendar/) (failas neįtraukiamas į git — sugeneruojamas `make -C etl/calendar`) | kalendorius nuo 1977-01-01 (anksčiausia JAR registracija) iki kitų metų pabaigos: metai, mėnesiai ir dienos (2027 m. imtinai — 51 metai, 612 mėnesių, 18 627 dienos), valstybinių švenčių dienos pažymėtos; visos kitų rinkinių datos (posėdžiai, balsavimai, kadencijų, sesijų ir narysčių pradžios bei pabaigos, juridinių asmenų įregistravimas ir išregistravimas, deklaracijų ataskaitiniai metai) susietos su kalendoriaus diena ar metais (`dct:temporal`) | sugeneruojama ETL metu; šventės — pagal Švenčių dienų įstatymą ir Darbo kodeksą, su kiekvienos šventės galiojimo datomis ([`etl/calendar/data/holidays.csv`](etl/calendar/data/holidays.csv)) | | [`taxonomies`](datasets/current/taxonomies/) | 27 SKOS klasifikatorių: administracinių vienetų lygiai, teisinės formos (iš JAR), statusai, pareigų/padalinių/vietovių/gatvių tipai, Seimo veiklos (sesijų ir posėdžių) tipai, balsavimo būdai, klausimų svarstymo stadijos, deklaruojamo turto rūšys, VMI deklaruojančiųjų pareigybių grupės, valstybinės šventės, žemės paskirtys, NŽT sprendimai dėl žemės įsigijimo, pareiškėjo kodo patikros rezultatai, švietimo įstaigų tipai, kultūros paveldo apsaugos statusai, reikšmingumo lygmenys, objektų rūšys ir vertingųjų savybių pobūdis, lobistinės veiklos sritys, ryšių su juridiniais asmenimis pobūdžiai, asmenų susiejimo būdai, nemokumo bylų rūšys, bankroto iniciatoriai, apygardos teismai | JAR + išvesta iš duomenų | @@ -137,6 +138,8 @@ graph LR taxes -->|dct:temporal| calendar insolvency[nemokumo bylos] -->|ltlod:insolvent · JAR kodas| legal insolvency -->|sdmx-dimension:refArea| admin + eufunds[ES fondų finansavimas] -->|ltlod:beneficiary · JAR kodas| legal + eufunds -->|sdmx-dimension:refArea| admin land[prašymai įsigyti žemės] -->|ltlod:applicant · patikrinus pavadinimą| legal land -->|schema:location| admin sittings[plenariniai posėdžiai] -->|eli-dl:forms_part_of| sessions[sesijos] @@ -189,6 +192,7 @@ Principas: **pirmiausia W3C standartai → tada srities žodynai (ES SEMIC, OP k | Darbdavių statistika (Sodra) | W3C [Data Cube](https://www.w3.org/TR/vocab-data-cube/) (`qb:DataSet`, `qb:Observation` — vienas kiekvienam darbdaviui, pasirinktinai ir kiekvienam mėnesiui) + SDMX-RDF `sdmx-dimension:refArea` (savivaldybė); mėnuo — `dct:temporal` → kalendoriaus mėnuo; matai `ltlod:insuredCount`, `ltlod:averageWage`, `ltlod:contributions` ir 12 mėnesių `ltlod:meanInsuredCount`, `ltlod:meanAverageWage`, `ltlod:totalContributions` | | Juridinių asmenų mokesčiai (VMI) | W3C [Data Cube](https://www.w3.org/TR/vocab-data-cube/) (`qb:DataSet`, `qb:Observation`) + SDMX-RDF `sdmx-dimension:refArea` (savivaldybė); `ltlod:taxpayer` → juridinis asmuo (JAR kodas); nepriemokos momentinė nuotrauka (`#this`) — `dct:temporal` → kalendoriaus diena, matai `ltlod:arrears`, `ltlod:overdueArrears`, `ltlod:deferredArrears`, `ltlod:deferredOverdueArrears`; sumokėti mokesčiai (`#paid-{metai}`) — `dct:temporal` → kalendoriaus metai, matas `ltlod:taxesPaid` (visi — EUR) | | Nemokumo bylos (AVNT) | `ltlod:InsolvencyProceeding` — viena byla viename dokumente; `dct:type` → nemokumo rūšis (bankrotas / restruktūrizavimas), `ltlod:insolvent` → juridinis asmuo (JAR kodas), `sdmx-dimension:refArea` → savivaldybė, `ltlod:court` → apygardos teismas, `ltlod:initiatedBy` → bankroto iniciatorius; bylos eiga — W3C [Time](https://www.w3.org/TR/owl-time/) `time:hasTime` → `time:Interval` (`#start` → `#end` `time:Instant` → kalendoriaus diena); loginiai požymiai `ltlod:outOfCourt`, `ltlod:simplified`, `ltlod:intentional` | +| ES fondų finansavimas 2014–2020 (Finansų ministerija) | `ltlod:EUFundingContract` — viena įgyvendinimo sutartis viename dokumente; `dct:identifier` → projekto kodas, `ltlod:beneficiary` → paramos gavėjas, `ltlod:fundingPartner` → projekto partneriai (JAR kodas), `sdmx-dimension:refArea` → savivaldybė; matai `ltlod:euAmount` / `ltlod:totalAmount` / `ltlod:decidedEuAmount` (EUR); `dct:date` + `dct:temporal` → pradžios diena; loginiai požymiai `ltlod:stateAid` / `ltlod:deMinimisAid`. Nėra W3C/ES RDF žodyno sanglaudos projektams — tai `ltlod:` kaskados pabaiga | | Asmenys | FOAF (+ suderinama su [Core Person 2.0](https://semiceu.github.io/Core-Person-Vocabulary/releases/2.00/)) | | Klasifikatoriai | [SKOS](https://www.w3.org/TR/skos-primer/) | | Bendrasis fallback | [schema.org](https://schema.org/) — tik kur W3C/ES termino nėra: galiojimo ir gyvavimo datos (`schema:validFrom`/`validThrough`, `schema:foundingDate`/`dissolutionDate`), `schema:PoliticalParty`, `schema:EventSeries`/`schema:Event` (sesijos, posėdžiai) | @@ -245,6 +249,10 @@ make -C taxes # VMI juridinių asmenų mokesčiai: dabar make -C insolvency # įmonių nemokumo bylos (AVNT): bankrotai, restruktūrizavimai # ir tyčiniai bankrotai per get.data.gov.lt; ~6,4 tūkst. bylų, # susietų su JAR, savivaldybe ir kalendoriumi (į git įtraukiama) +make -C eu-funds # ES struktūrinių fondų (2014–2020 m.) finansavimo sutartys + # per get.data.gov.lt (finmin); ~26 tūkst. sutarčių, susietų su + # paramos gavėjais ir partneriais (JAR), savivaldybe ir + # kalendoriumi; failas neįtraukiamas į git make -C sodra # Sodros darbdavių duomenys iš naršykle atsisiųstų # data/monthly-{metai}.csv.zip (atvira.sodra.lt saugo Cloudflare; # SODRA_MONTHS=12 — kiek paskutinių mėnesių; @@ -444,7 +452,10 @@ Daugiau klausimų, į kuriuos duomenys jau atsako (visi su užklausomis ir pilna - kurie viešųjų pirkimų tiekėjai yra ar buvo nemokūs (bankrotas ar restruktūrizavimas), ir kurie politinių kampanijų rėmėjai vėliau tapo nemokūs (pirkimai / kampanijų finansavimas × nemokumo bylos per JAR kodą); -- kuriose savivaldybėse iškelta daugiausia bankroto bylų ir kaip jų skaičius kito pagal metus. +- kuriose savivaldybėse iškelta daugiausia bankroto bylų ir kaip jų skaičius kito pagal metus; +- kurių politikų deklaruoti juridiniai asmenys gavo 2014–2020 m. ES struktūrinių fondų paramą + (privatūs interesai × ES fondai per JAR kodą), ir kurios įmonės gavo ir ES paramą, ir laimėjo + viešuosius pirkimus (ES fondai × pirkimai per JAR kodą). Turto deklaracijų pjūviai pagal partiją, kadencijos pokyčius, turtą užsienyje ir dalyvavimą balsavimuose — duomenų istorijoje „Seimo turtas 2024“ (`app/stories/seimo-turtas-2024.ttl`). diff --git a/app/eu-funds.ttl b/app/eu-funds.ttl new file mode 100644 index 0000000..41e5964 --- /dev/null +++ b/app/eu-funds.ttl @@ -0,0 +1,85 @@ +@prefix dh: . +@prefix ldh: . +@prefix ac: . +@prefix rdf: . +@prefix dct: . +@prefix sp: . +@prefix spin: . + +<> a dh:Container ; + dct:title "ES fondų finansavimas"@lt, "EU funding"@en ; + rdf:_1 <#intro> ; + rdf:_2 <#chart-top-block> ; + rdf:_3 <#chart-per-year-block> . + +# rdf:_1..3 — intro + the largest EU-funded projects + funding per year. No children listing: +# ~26k contracts in title order answer nothing; a contract is reached from its beneficiary, +# its municipality and its start day. + +<#intro> a ldh:XHTML ; + rdf:value """
+

2014–2020 m. Europos Sąjungos struktūrinių fondų investicijų projektų įgyvendinimo duomenys (Finansų ministerija). Kiekviena sutartis susieta su paramos gavėju ir projekto partneriais (Juridinių asmenų registre pagal įmonės kodą), savivaldybe ir pradžios diena kalendoriuje.

+

Didžioji dalis įrašų — finansinių priemonių išmokos (pvz., dalinis palūkanų kompensavimas smulkiajam verslui) be atskiro projekto kodo; maždaug 685 turi formalų projekto kodą su skirtomis ES bei bendromis lėšomis. Lėšų grąžinimai ir nustatyti pažeidimai čia neįtraukti — jų šaltinio raktas yra neskelbiamo vidinio identifikatoriaus maiša, nesusiejama su projektu ar gavėju. 2021–2027 m. laikotarpio atvirų duomenų dar nėra.

+
"""^^rdf:XMLLiteral . + +<#chart-top-block> a ldh:Object ; + rdf:value <#chart-top> . + +<#chart-top> a ldh:ResultSetChart ; + dct:title "Daugiausia ES lėšų gavę projektai"@lt, "Projects awarded the most EU funds"@en ; + spin:query <#chart-top-query> ; + ldh:chartType ac:Table ; + ldh:categoryVarName "projektas" ; + ldh:seriesVarName "es_lesos_eur" ; + ldh:seriesVarName "gavejas" . + +<#chart-top-query> a sp:Select ; + dct:title "Projektai pagal skirtas ES fondų lėšas"@lt, "Projects by EU funds awarded"@en ; + sp:text """PREFIX dct: +PREFIX ltlod: + +# The coded projects with the largest EU-fund amount (ltlod:euAmount), with the beneficiary +# name as the contract recorded it. Only ~685 contracts carry a project code and amounts. +SELECT ?projektas (SAMPLE(?ben) AS ?gavejas) (SAMPLE(?eu) AS ?es_lesos_eur) +WHERE +{ + GRAPH ?graph + { + ?contract a ltlod:EUFundingContract ; + dct:identifier ?projektas ; + ltlod:euAmount ?eu ; + ltlod:beneficiaryName ?ben . + } +} +GROUP BY ?projektas +ORDER BY DESC(?es_lesos_eur) +LIMIT 20""" . + +<#chart-per-year-block> a ldh:Object ; + rdf:value <#chart-per-year> . + +<#chart-per-year> a ldh:ResultSetChart ; + dct:title "Sutartys pagal pradžios metus"@lt, "Contracts by start year"@en ; + spin:query <#chart-per-year-query> ; + ldh:chartType ac:BarChart ; + ldh:categoryVarName "metai" ; + ldh:seriesVarName "sutartys" . + +<#chart-per-year-query> a sp:Select ; + dct:title "ES fondų sutarčių skaičius pagal pradžios metus"@lt, "EU-funding contracts by start year"@en ; + sp:text """PREFIX dct: +PREFIX ltlod: + +# Contracts (incl. the code-less instrument payouts) by the year they started. +SELECT ?metai (COUNT(DISTINCT ?contract) AS ?sutartys) +WHERE +{ + GRAPH ?graph + { + ?contract a ltlod:EUFundingContract ; + dct:date ?date . + } + BIND(SUBSTR(STR(?date), 1, 4) AS ?metai) +} +GROUP BY ?metai +ORDER BY ?metai""" . diff --git a/app/ns.ttl b/app/ns.ttl index ee38041..b3151ad 100644 --- a/app/ns.ttl +++ b/app/ns.ttl @@ -1126,6 +1126,79 @@ ltlod:deregistrationDate a owl:DatatypeProperty ; rdfs:range xsd:date ; rdfs:isDefinedBy : . +# 2014-2020 EU structural-funds contracts (etl/eu-funds/). The beneficiary and project +# partners link to the legal entity; each has its own inverse view (as beneficiary / as partner). +ltlod:EUFundingContract a owl:Class ; + rdfs:label "ES fondų finansavimo sutartis"@lt, "EU funding contract"@en ; + rdfs:isDefinedBy : . + +ltlod:beneficiary a owl:ObjectProperty ; + rdfs:label "Paramos gavėjas"@lt, "Beneficiary"@en ; + rdfs:domain ltlod:EUFundingContract ; + rdfs:range rov:RegisteredOrganization ; + ldh:inverseView :EUFundingAsBeneficiary ; + rdfs:isDefinedBy : . + +ltlod:fundingPartner a owl:ObjectProperty ; + rdfs:label "Projekto partneris"@lt, "Project partner"@en ; + rdfs:domain ltlod:EUFundingContract ; + rdfs:range rov:RegisteredOrganization ; + ldh:inverseView :EUFundingAsPartner ; + rdfs:isDefinedBy : . + +ltlod:beneficiaryCode a owl:DatatypeProperty ; + rdfs:label "Paramos gavėjo kodas"@lt, "Beneficiary code"@en ; + rdfs:domain ltlod:EUFundingContract ; + rdfs:range xsd:string ; + rdfs:isDefinedBy : . + +ltlod:beneficiaryName a owl:DatatypeProperty ; + rdfs:label "Paramos gavėjo pavadinimas"@lt, "Beneficiary name"@en ; + rdfs:domain ltlod:EUFundingContract ; + rdfs:isDefinedBy : . + +ltlod:euAmount a owl:DatatypeProperty ; + rdfs:label "ES fondų lėšos, EUR"@lt, "EU funds, EUR"@en ; + rdfs:domain ltlod:EUFundingContract ; + rdfs:range xsd:decimal ; + rdfs:isDefinedBy : . + +ltlod:totalAmount a owl:DatatypeProperty ; + rdfs:label "Visa projekto vertė, EUR"@lt, "Total project value, EUR"@en ; + rdfs:domain ltlod:EUFundingContract ; + rdfs:range xsd:decimal ; + rdfs:isDefinedBy : . + +ltlod:decidedEuAmount a owl:DatatypeProperty ; + rdfs:label "Skirtos ES lėšos, EUR"@lt, "Decided EU funds, EUR"@en ; + rdfs:domain ltlod:EUFundingContract ; + rdfs:range xsd:decimal ; + rdfs:isDefinedBy : . + +ltlod:stateAid a owl:DatatypeProperty ; + rdfs:label "Valstybės pagalba"@lt, "State aid"@en ; + rdfs:domain ltlod:EUFundingContract ; + rdfs:range xsd:boolean ; + rdfs:isDefinedBy : . + +ltlod:deMinimisAid a owl:DatatypeProperty ; + rdfs:label "De minimis pagalba"@lt, "De minimis aid"@en ; + rdfs:domain ltlod:EUFundingContract ; + rdfs:range xsd:boolean ; + rdfs:isDefinedBy : . + +ltlod:implementationFrom a owl:DatatypeProperty ; + rdfs:label "Įgyvendinimo pradžia"@lt, "Implementation start"@en ; + rdfs:domain ltlod:EUFundingContract ; + rdfs:range xsd:date ; + rdfs:isDefinedBy : . + +ltlod:implementationTill a owl:DatatypeProperty ; + rdfs:label "Įgyvendinimo pabaiga"@lt, "Implementation end"@en ; + rdfs:domain ltlod:EUFundingContract ; + rdfs:range xsd:date ; + rdfs:isDefinedBy : . + # the observation month as a literal (xsd:gYearMonth), for sorting dct:date a owl:DatatypeProperty ; rdfs:label "Mėnuo"@lt, "Month"@en ; @@ -1287,9 +1360,9 @@ eli-dl:had_voter_abstention a owl:ObjectProperty ; # person/facility through the instant. dct:temporal a owl:ObjectProperty ; rdfs:label "Laikas"@lt, "Time"@en ; - rdfs:domain [ owl:unionOf ( schema:Event eli-dl:Vote eli-dl:Activity eli-dl:DraftLegislationWork time:Instant ltlod:AssetDeclaration ltlod:CampaignDonation ltlod:CampaignExpense epo:Contract ltlod:LobbyingDeclaration ltlod:Lobbyist qb:Observation ltlod:LandAcquisitionApplication ltlod:LandAcquisitionDecision ) ] ; + rdfs:domain [ owl:unionOf ( schema:Event eli-dl:Vote eli-dl:Activity eli-dl:DraftLegislationWork time:Instant ltlod:AssetDeclaration ltlod:CampaignDonation ltlod:CampaignExpense epo:Contract ltlod:LobbyingDeclaration ltlod:Lobbyist qb:Observation ltlod:LandAcquisitionApplication ltlod:LandAcquisitionDecision ltlod:EUFundingContract ) ] ; rdfs:range dct:PeriodOfTime ; - ldh:inverseView :DaySittings, :DayVotes, :DayAgendaItems, :DayBills, :DayTerms, :DaySessions, :DayMembershipsBegan, :DayMembershipsEnded, :YearDeclarations, :DayRegistrations, :DayDeregistrations, :DayElections, :DayCampaignDonations, :DayCampaignExpenses, :DayFacilityRegistrations, :DayContracts, :DayLobbying, :DayLobbyistRegistrations, :DayInterestTies, :MonthEmployers, :DayLandApplications, :DayLandDecisions, :YearLandTotals, :DayInsolvencyProceedings ; + ldh:inverseView :DaySittings, :DayVotes, :DayAgendaItems, :DayBills, :DayTerms, :DaySessions, :DayMembershipsBegan, :DayMembershipsEnded, :YearDeclarations, :DayRegistrations, :DayDeregistrations, :DayElections, :DayCampaignDonations, :DayCampaignExpenses, :DayFacilityRegistrations, :DayContracts, :DayLobbying, :DayLobbyistRegistrations, :DayInterestTies, :MonthEmployers, :DayLandApplications, :DayLandDecisions, :YearLandTotals, :DayInsolvencyProceedings, :DayEUFunding ; rdfs:isDefinedBy : . time:intervalIn a owl:ObjectProperty ; @@ -4062,6 +4135,80 @@ ORDER BY ?title """ ; rdfs:isDefinedBy : . +# 2014-2020 EU structural-funds contracts (etl/eu-funds/). A legal entity's EU-funded +# contracts as the beneficiary and, separately, as a project partner; newest first. +:EUFundingAsBeneficiary a ldh:View ; + dct:title "ES fondų finansavimas (gavėjas)"@lt, "EU funding (beneficiary)"@en ; + spin:query :SelectEUFundingAsBeneficiary ; + ac:mode ac:TableMode ; + ldh:showWhenEmpty false ; + rdfs:isDefinedBy : . + +:SelectEUFundingAsBeneficiary a sp:Select ; + rdfs:label "Select the legal entity's EU-funding contracts as beneficiary" ; + sp:text """ +PREFIX dct: +PREFIX ltlod: +SELECT DISTINCT ?contract +WHERE + { GRAPH ?graph + { ?contract ltlod:beneficiary $about ; + a ltlod:EUFundingContract . + OPTIONAL { ?contract dct:date ?date } + } + } +ORDER BY DESC(?date) +""" ; + rdfs:isDefinedBy : . + +:EUFundingAsPartner a ldh:View ; + dct:title "ES fondų finansavimas (partneris)"@lt, "EU funding (partner)"@en ; + spin:query :SelectEUFundingAsPartner ; + ac:mode ac:TableMode ; + ldh:showWhenEmpty false ; + rdfs:isDefinedBy : . + +:SelectEUFundingAsPartner a sp:Select ; + rdfs:label "Select the legal entity's EU-funding contracts as a project partner" ; + sp:text """ +PREFIX dct: +PREFIX ltlod: +SELECT DISTINCT ?contract +WHERE + { GRAPH ?graph + { ?contract ltlod:fundingPartner $about ; + a ltlod:EUFundingContract . + OPTIONAL { ?contract dct:date ?date } + } + } +ORDER BY DESC(?date) +""" ; + rdfs:isDefinedBy : . + +# A calendar day's EU-funding contracts: those that started that day. +:DayEUFunding a ldh:View ; + dct:title "ES fondų finansavimas"@lt, "EU funding"@en ; + spin:query :SelectDayEUFunding ; + ldh:showWhenEmpty false ; + rdfs:isDefinedBy : . + +:SelectDayEUFunding a sp:Select ; + rdfs:label "Select the EU-funding contracts started on the day" ; + sp:text """ +PREFIX dct: +PREFIX ltlod: +SELECT DISTINCT ?contract +WHERE + { GRAPH ?graph + { ?contract dct:temporal $about ; + a ltlod:EUFundingContract ; + dct:title ?title + } + } +ORDER BY ?title +""" ; + rdfs:isDefinedBy : . + :MonthEmployers a ldh:View ; dct:title "Darbdaviai (Sodra)"@lt, "Employers (Sodra)"@en ; spin:query :SelectMonthEmployers ; diff --git a/etl/Makefile b/etl/Makefile index af82fc4..7e89a98 100644 --- a/etl/Makefile +++ b/etl/Makefile @@ -5,7 +5,7 @@ # make admin-units | seimas | officials | declarations | legal-entities | facilities | procurement | vtek | land-acquisitions | taxonomies | calendar | elections # make sodra # opt-in: needs the browser-harvested Sodra zips in sodra/data/ -DOMAINS := taxonomies calendar admin-units seimas officials declarations legal-entities elections facilities procurement vtek land-acquisitions taxes insolvency sodra +DOMAINS := taxonomies calendar admin-units seimas officials declarations legal-entities elections facilities procurement vtek land-acquisitions taxes insolvency eu-funds sodra .PHONY: all clean $(DOMAINS) @@ -21,7 +21,9 @@ DOMAINS := taxonomies calendar admin-units seimas officials declarations legal-e # calendar days/years; a plain Spinta fetch, so (unlike sodra) it is part of `all` # insolvency after legal-entities and admin-units — proceedings link to legal entities and # municipalities; a plain Spinta fetch, committed output -all: taxonomies calendar admin-units seimas officials declarations legal-entities elections facilities procurement vtek land-acquisitions taxes insolvency +# eu-funds after legal-entities and admin-units — contracts link to beneficiaries/partners +# (by bare JAR code) and municipalities; a plain Spinta fetch, gitignored bulk output +all: taxonomies calendar admin-units seimas officials declarations legal-entities elections facilities procurement vtek land-acquisitions taxes insolvency eu-funds $(DOMAINS): $(MAKE) -C $@ all diff --git a/etl/ONTOLOGY-NOTES.md b/etl/ONTOLOGY-NOTES.md index dfff204..878bf86 100644 --- a/etl/ONTOLOGY-NOTES.md +++ b/etl/ONTOLOGY-NOTES.md @@ -104,6 +104,7 @@ authority table except for settlements. Each `time:Interval` has `time:hasBeginn | Employer statistics (Sodra) | W3C **Data Cube** (`qb:DataSet` + `qb:DataStructureDefinition`, `qb:Observation`) + **SDMX-RDF** `sdmx-dimension:refArea` (→ the municipality, AR `sav_kodas`); month dimension `dct:temporal` → the calendar **month**, plus a `dct:date` `xsd:gYearMonth` literal; custom **`ltlod:employer`** (dimension → `legal-entities/{ja_kodas}/#this`), latest-month measures **`ltlod:insuredCount`**, **`ltlod:averageWage`**, **`ltlod:contributions`** and window measures **`ltlod:monthsReported`**, **`ltlod:meanInsuredCount`**, **`ltlod:meanAverageWage`** (headcount-weighted), **`ltlod:totalContributions`** | **Default = one summary observation per employer** (the document's `#this`: its latest month in the 12-month window, the figures as published, plus the window aggregates over the months it reported) — ~1.9M quads, browsable, one row per employer. The full monthly series (~14M quads) is opt-in (`SODRA_CUBE=1`): `#{yyyy-mm}` observations of a second qb:DataSet (`#monthly`), an overlay merged into the same documents. Data Cube is the W3C vocabulary for this shape (values per employer × month), and qb/SDMX namespaces dereference; the summary stays a qb:Observation (of its own DSD) so both share dimensions and the latest-month measures. Measures must be literals on the observation, so schema.org's `numberOfEmployees` (→ `QuantitativeValue` node, no period) does not fit; no W3C/EU/SDMX measure exists for insured persons, wage or contributions, hence `ltlod:` (typed `qb:MeasureProperty` in `ns.ttl`; wage and contributions are EUR). `dct:temporal` (not `sdmx-dimension:refPeriod`) is the month dimension so observations join the calendar like every other dated entity and the month page gets its `:MonthEmployers` view (summary observations only: `ltlod:monthsReported`). Observations carry every dimension (Data Cube normalized form). Values are kept as Sodra publishes them; an unpublished value is an absent measure (Sodra suppresses the wage of small employers, so the window mean wage covers only the months it was published). The summary's municipality is the most recent one the employer reported in the window. | | Legal-entity taxes (VMI) | W3C **Data Cube** (`qb:DataSet` + `qb:DataStructureDefinition`, `qb:Observation`) + **SDMX-RDF** `sdmx-dimension:refArea` (→ the registration municipality, AR `sav_kodas`); custom dimension **`ltlod:taxpayer`** (→ `legal-entities/{ja_kodas}/#this`); the arrears snapshot (`#this`) carries `dct:temporal` → the calendar **day** (+ `dct:date` `xsd:date`) and measures **`ltlod:arrears`**, **`ltlod:overdueArrears`**, **`ltlod:deferredArrears`**, **`ltlod:deferredOverdueArrears`** (EUR); taxes paid (`#paid-{yyyy}`) carry `dct:temporal` → the calendar **year** (+ `dct:date` `xsd:gYear`) and measure **`ltlod:taxesPaid`** (EUR) | The two VMI feeds (current arrears per entity; taxes paid per entity per year) are both observations keyed on the taxpayer, so Data Cube is the same fit as the Sodra employer figures, and the taxpayer document reuses the shape (`#this` the arrears snapshot — the document topic, present even for an entity that owes nothing but paid tax — plus one `#paid-{yyyy}` observation per reporting year). No W3C/EU/SDMX measure exists for tax arrears or taxes paid, hence `ltlod:` (typed `qb:MeasureProperty` in `ns.ttl`, all EUR). `ltlod:taxpayer` links by bare JAR code, so it joins procurement contractors, Sodra employers and campaign donors with no lookup; it dangles until the full JAR register is loaded. Amounts are kept as VMI publishes them; a measure absent (not zero) means VMI publishes no value. The calendar day (one publication date, tens of thousands of entities) and year (every taxpaying company) carry the `dct:temporal` link but get no calendar listing — neither population fits a calendar page's budget, unlike a day's procurement contracts. | | Insolvency (AVNT bankruptcy / restructuring) | custom **`ltlod:InsolvencyProceeding`** (one per proceeding); `dct:type` → `taxonomies/insolvency-types/` (`bankrotas` / `restrukturizavimas`); **`ltlod:insolvent`** → `legal-entities/{imones_kodas}/#this` (+ `ltlod:companyCode`/`ltlod:companyName` literals); `sdmx-dimension:refArea` → the municipality; **`ltlod:court`** → `taxonomies/courts/` (5 apygardos teismai), **`ltlod:initiatedBy`** → `taxonomies/insolvency-initiators/`; lifecycle as W3C **Time** `time:hasTime` → `time:Interval` (`#period`) → `#start` / `#end` `time:Instant` → `dct:temporal` calendar day (begin always, end when the proceeding closed); boolean flags **`ltlod:outOfCourt`**, **`ltlod:simplified`**, **`ltlod:intentional`** + `ltlod:intentionalDate` / `ltlod:liquidationDate` / `ltlod:deregistrationDate` literals | No W3C/EU/schema.org vocabulary for insolvency proceedings (ePO covers procurement only; the EU has no insolvency ontology), so the proceeding class is the `ltlod:` end of the cascade, but its shape reuses the project's norms: the legal-entity link by bare code (dangles until the full JAR loads), the municipality by AR `sav_kodas`, and the period as the same `time:hasTime` interval as Seimas terms and legal-entity registration, so a day page reaches the proceeding through its `#start`/`#end` instant. The AVNT **territory code** (`teritorijos_kodas`, a 4-digit `26XX` statistical code, 7-digit for sub-municipal rows) crosswalks to the AR `sav_kodas` by its last two digits — `2611`→`11` Alytus, `2641`→`41` Vilnius r. — with one hardcoded exception (`2601`→`13`, Vilnius city) and one defunct code with no current municipality (`2651`, the Marijampolė district abolished in 2000); the start date coalesces `bankroto_data` (court) with `ne_teismo_tvarka` (out-of-court). The three sources overlap: `BankrotoAtaskaitosDatos` (2020+, full fields) carries the intentional-bankruptcy date inline, and `TycinisBankrotas` (1994–2025) adds the ~630 intentional bankruptcies that predate 2020 as their own proceedings (its court/dates only); `...Finansai` financials are **left out** — their `eil_nr` key joins to no company code in the report tables. | +| EU structural funds 2014-2020 (finmin) | custom **`ltlod:EUFundingContract`** (one per implementation contract); `dct:identifier` → the project code (coded ones); **`ltlod:beneficiary`** → `legal-entities/{executor_code}/#this` (+ `ltlod:beneficiaryCode`/`ltlod:beneficiaryName`), **`ltlod:fundingPartner`** → the partners; `sdmx-dimension:refArea` → the municipality; measures `ltlod:euAmount` / `ltlod:totalAmount` / `ltlod:decidedEuAmount` (EUR); `dct:date` + `dct:temporal` → the start day; `ltlod:implementationFrom`/`Till` date literals; booleans `ltlod:stateAid` / `ltlod:deMinimisAid` | No W3C/EU RDF vocabulary for cohesion-fund projects dereferences (EU Kohesio is an app, not a published ontology; ePO is procurement-only), so the class is the `ltlod:` end of the cascade; the beneficiary/partner links reuse the bare-JAR-code join (dangle until the full register loads) and the municipality the AR `sav_kodas` (crosswalked from the free-text name). One `Contract` per document keyed by the Spinta `_id` (no business key: most records are code-less financial-instrument payouts, e.g. partial interest compensation to SMEs; only ~685 carry a formal project code with amounts via the `paraiskos/Project` ref and a `ConFinSource` breakdown). Partners and fin sources join by `Contract._id`. **Repayments and irregularities (`sutartys/Repayment`, `kontroles_veiksmai/Suspicion`) are not modelled**: they are keyed by an opaque `project_hash`/`project_hash_id` that is a hash of an unpublished internal SFMIS id — tested 2026-10-25, it matches no standard hash (md5/sha*/crc/blake, salted, prefix/suffix) of any published id (code, `_id`, `project_id`, `Contract._id`), so repayments and pažeidimai cannot be attributed to a beneficiary. The 2021-2027 programme is not on Spinta. | | Validity dates | `schema:validFrom` / `schema:validThrough` (admin units), `schema:foundingDate` / `schema:dissolutionDate` (legal entities) | No EU RDF term for registry lifecycle dates (INSPIRE models them as `beginLifespanVersion` in GML only). | ## Legacy vocabulary disposition (2012 datasets) diff --git a/etl/URI-SCHEME.md b/etl/URI-SCHEME.md index 90ca375..6f112a4 100644 --- a/etl/URI-SCHEME.md +++ b/etl/URI-SCHEME.md @@ -100,6 +100,7 @@ None exists yet; the subdomain naming rule is still open. | `taxes/{ja_kodas}/` | JAR company code (9 digits) — one document per legal entity | `qb:Observation` (`#this` = the current tax-arrears snapshot; `ltlod:taxpayer` → `legal-entities/{ja_kodas}/#this`) | VMI via get.data.gov.lt (`vmi/ja_nepriemokos` arrears ⋈ `vmi/ja_mokesciai` taxes paid, by JAR code); gitignored bulk output (`taxpayers.trig`) | | `taxes/dataset/` | fixed slug (never collides: taxpayer slugs are digits) | `qb:DataSet`s (`#this` arrears, `#paid` taxes paid per year) + their `qb:DataStructureDefinition`s | generated (`etl/taxes/mappings/dataset.rq`), committed | | `insolvency-cases/{imones_kodas}-{start}/` | legal-entity code + the proceeding's start date (`305544521-2024-09-04`) | `ltlod:InsolvencyProceeding` (`ltlod:insolvent` → `legal-entities/{imones_kodas}/#this`) | AVNT via get.data.gov.lt (bankruptcies `avnt/imoniu_bankrotas` + restructurings `avnt/imoniu_restrukturizavimas` + intentional `avnt/tyciniai_bankrotai`, `ltlod-insolvency`); committed | +| `eu-funds/{_id}/` | the source Spinta `_id` (no business key — most records are code-less instrument payouts) | `ltlod:EUFundingContract` (`ltlod:beneficiary`/`ltlod:fundingPartner` → `legal-entities/{code}/#this`) | 2014-2020 EU structural funds, Finance Ministry via get.data.gov.lt (`finmin/sutartys/Contract` ⋈ `ConPartner`/`ConFinSource` ⋈ `finmin/paraiskos/Project`, `ltlod-eu-funds`); gitignored bulk output | | `constituencies/{kadencijos_id}-{nr}/` | Seimas term id + single-member electoral-district number (districts are redrawn every election, so the number alone is ambiguous) | `ltlod:ElectoralDistrict` | apps.lrs.lt members feed (`išrinkimo_būdas`) — **not** an admin unit, own container | | `elections/{slug}/` | `seimas-{year}` — the election type and year (one Seimas election per year at most; a future municipal/presidential/EP pipeline adds its own prefix) | `ltlod:Election` + `schema:Event` | VRK results map (ArcGIS feature services), `etl/elections/data/elections.csv` for dates and terms | | `election-results/{election}-{nr}/` | election slug + single-member constituency number (`seimas-2024-1`); the constituency is `constituencies/{kadencijos_id}-{nr}/`, the term derived from the election | `ltlod:ConstituencyContest` | VRK results map, `LRS_{year}_V_T1/T2_APG` + `LRS_{year}_D_APG` layers | diff --git a/etl/eu-funds/Makefile b/etl/eu-funds/Makefile new file mode 100644 index 0000000..e67c1a8 --- /dev/null +++ b/etl/eu-funds/Makefile @@ -0,0 +1,38 @@ +include ../config.mk + +# 2014-2020 EU structural-funds implementation contracts from the Finance Ministry's open +# data on get.data.gov.lt (datasets/gov/finmin/sutartys), joined to the project applications +# (finmin/paraiskos) for the code and decision amounts. ltlod-eu-funds fetches Contract +# (~26k, keyset-paginated), its partners (ConPartner) and financing sources (ConFinSource), +# crosswalks the municipality text to the AR code, and emits contracts.csv + partners.csv. +# One ltlod:EUFundingContract per document, keyed by the source _id. Most contracts are +# code-less financial-instrument payouts; ~685 carry a formal project code with amounts. +# Repayments and irregularities are not modelled (their source keys are an unpublished hash). +# make -C etl/eu-funds + +CACHE := cache +OUT := ../../datasets/current/eu-funds + +.PHONY: all clean FORCE +all: $(OUT)/contracts.trig + +# one run writes both files (partners.csv is a by-product; not a grouped target — macOS make 3.81) +$(CACHE)/contracts.csv: FORCE + @mkdir -p $(CACHE) + uv run --project ../tools ltlod-eu-funds \ + --contracts $(CACHE)/contracts.csv --partners $(CACHE)/partners.csv + +$(CACHE)/partners.csv: $(CACHE)/contracts.csv ; + +$(CACHE)/%.nt: $(CACHE)/%.csv + $(LIB)/csv2rdf.sh $< $(BASE) > $@ + +$(OUT)/contracts.trig: $(CACHE)/contracts.nt $(CACHE)/partners.nt mappings/contracts.rq + @mkdir -p $(OUT) + $(LIB)/graphify.sh mappings/contracts.rq $(BASE) $(CACHE)/contracts.nt $(CACHE)/partners.nt > $@ + JVM_ARGS=-Xmx8g $(LIB)/validate.sh $@ $(BASE) $$(($$(wc -l < $(CACHE)/contracts.csv) - 1)) + +clean: + rm -rf $(CACHE) + +FORCE: diff --git a/etl/eu-funds/mappings/contracts.rq b/etl/eu-funds/mappings/contracts.rq new file mode 100644 index 0000000..ef18366 --- /dev/null +++ b/etl/eu-funds/mappings/contracts.rq @@ -0,0 +1,99 @@ +PREFIX dct: +PREFIX foaf: +PREFIX xsd: +PREFIX sdmx-dimension: +PREFIX ltlod: + +PREFIX dh: +PREFIX sioc: + +# 2014-2020 EU structural-funds implementation contracts (finmin/sutartys, normalized by +# ltlod-eu-funds), one ltlod:EUFundingContract per named graph keyed by the source _id. +# The beneficiary (executor_code) and project partners link to legal-entities/{code}/#this +# by the bare JAR code; the contract lies in a municipality (sdmx-dimension:refArea). ~685 +# carry a formal project code (dct:identifier) with the EU / total / decided EU amounts; the +# rest are code-less financial-instrument payouts with only the beneficiary, dates and aid +# flags. The contract's start is a day event (dct:date + dct:temporal); the implementation +# span and finish are date literals. Repayments and irregularities are not modelled — their +# source keys are a hash of an unpublished id (see ltlod-eu-funds). +# +# Two UNION branches (contract row / partner row) build the same ?graph from the id, so +# their triples merge per document. +CONSTRUCT +{ + GRAPH ?graph + { + ?graph a dh:Item ; + dct:created ?now ; + sioc:has_container ?container ; + dct:title ?title ; + foaf:primaryTopic ?this . + + ?this a ltlod:EUFundingContract ; + dct:title ?title ; + dct:identifier ?code ; + ltlod:beneficiary ?beneficiary ; + ltlod:beneficiaryCode ?benCode ; + ltlod:beneficiaryName ?benName ; + sdmx-dimension:refArea ?municipality ; + ltlod:euAmount ?euAmount ; + ltlod:totalAmount ?totalAmount ; + ltlod:decidedEuAmount ?decidedEu ; + ltlod:stateAid ?stateAid ; + ltlod:deMinimisAid ?deMinimis ; + dct:date ?started ; + dct:temporal ?startedDay ; + ltlod:implementationFrom ?implFrom ; + ltlod:implementationTill ?implTill ; + ltlod:fundingPartner ?partner . + } +} +WHERE +{ + { + ?row <#id> ?id ; + <#name> ?nameRaw ; + <#beneficiary_code> ?benCodeRaw . + OPTIONAL { ?row <#code> ?codeRaw . FILTER(?codeRaw != "") } + OPTIONAL { ?row <#beneficiary_name> ?benNameRaw . FILTER(?benNameRaw != "") } + OPTIONAL { ?row <#foreign> ?foreign . FILTER(?foreign != "") } + OPTIONAL { ?row <#sav> ?savCode . FILTER(?savCode != "") } + OPTIONAL { ?row <#eu_amount> ?euRaw . FILTER(?euRaw != "") } + OPTIONAL { ?row <#total_amount> ?totalRaw . FILTER(?totalRaw != "") } + OPTIONAL { ?row <#decision_eu_amount> ?decidedRaw . FILTER(?decidedRaw != "") } + OPTIONAL { ?row <#state_aid> ?stateRaw . FILTER(?stateRaw != "") } + OPTIONAL { ?row <#de_minimis> ?minimisRaw . FILTER(?minimisRaw != "") } + OPTIONAL { ?row <#started> ?startedRaw . FILTER(?startedRaw != "") } + OPTIONAL { ?row <#impl_from> ?implFromRaw . FILTER(?implFromRaw != "") } + OPTIONAL { ?row <#impl_till> ?implTillRaw . FILTER(?implTillRaw != "") } + + BIND(uri(concat(str($base), "eu-funds/", encode_for_uri(?id), "/")) AS ?graph) + BIND(uri(concat(str(?graph), "#this")) AS ?this) + BIND(STRLANG(?nameRaw, "lt") AS ?title) + BIND(IF(BOUND(?codeRaw), ?codeRaw, ?undef) AS ?code) + BIND(?benCodeRaw AS ?benCode) + BIND(IF(BOUND(?benNameRaw), STRLANG(?benNameRaw, "lt"), ?undef) AS ?benName) + # the beneficiary resolves to a JAR entity only for a Lithuanian legal person with a code + BIND(IF(?benCodeRaw != "" && !BOUND(?foreign), uri(concat(str($base), "legal-entities/", ?benCodeRaw, "/#this")), ?undef) AS ?beneficiary) + BIND(IF(BOUND(?savCode), uri(concat(str($base), "admin-units/", ?savCode, "/#this")), ?undef) AS ?municipality) + BIND(IF(BOUND(?euRaw), STRDT(?euRaw, xsd:decimal), ?undef) AS ?euAmount) + BIND(IF(BOUND(?totalRaw), STRDT(?totalRaw, xsd:decimal), ?undef) AS ?totalAmount) + BIND(IF(BOUND(?decidedRaw), STRDT(?decidedRaw, xsd:decimal), ?undef) AS ?decidedEu) + BIND(IF(BOUND(?stateRaw), true, ?undef) AS ?stateAid) + BIND(IF(BOUND(?minimisRaw), true, ?undef) AS ?deMinimis) + BIND(IF(BOUND(?startedRaw), STRDT(?startedRaw, xsd:date), ?undef) AS ?started) + BIND(IF(BOUND(?startedRaw), uri(concat(str($base), "calendar/", REPLACE(?startedRaw, "-", "/"), "/#this")), ?undef) AS ?startedDay) + BIND(IF(BOUND(?implFromRaw), STRDT(?implFromRaw, xsd:date), ?undef) AS ?implFrom) + BIND(IF(BOUND(?implTillRaw), STRDT(?implTillRaw, xsd:date), ?undef) AS ?implTill) + } + UNION + { + ?row <#contract_id> ?cid ; + <#partner_code> ?partnerCode . + FILTER(?partnerCode != "") + BIND(uri(concat(str($base), "eu-funds/", encode_for_uri(?cid), "/")) AS ?graph) + BIND(uri(concat(str($base), "legal-entities/", ?partnerCode, "/#this")) AS ?partner) + } + + BIND(NOW() AS ?now) +} diff --git a/etl/shapes/eu-funds.ttl b/etl/shapes/eu-funds.ttl new file mode 100644 index 0000000..8315353 --- /dev/null +++ b/etl/shapes/eu-funds.ttl @@ -0,0 +1,38 @@ +# SHACL shapes for 2014-2020 EU structural-funds contracts (datasets/current/eu-funds/*.trig, +# etl/eu-funds/mappings/contracts.rq). One ltlod:EUFundingContract per document, keyed by the +# source _id; every one carries a title, a beneficiary code and name. The project code, +# beneficiary legal-entity link, municipality, amounts, aid flags, start day and dates are +# present only where the source has them (most contracts are code-less instrument payouts). + +PREFIX sh: +PREFIX rdf: +PREFIX xsd: +PREFIX dct: +PREFIX sdmx-dimension: +PREFIX ltlod: +PREFIX : + +:EUFundingContractShape a sh:NodeShape ; + sh:targetClass ltlod:EUFundingContract ; + sh:property + [ sh:path dct:title ; sh:datatype rdf:langString ; + sh:languageIn ("lt") ; sh:minCount 1 ; sh:maxCount 1 ] , + [ sh:path dct:identifier ; sh:datatype xsd:string ; sh:maxCount 1 ] , + [ sh:path ltlod:beneficiary ; sh:nodeKind sh:IRI ; sh:maxCount 1 ; + sh:pattern "/legal-entities/[^/]+/#this$" ] , + [ sh:path ltlod:beneficiaryCode ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ] , + [ sh:path ltlod:beneficiaryName ; sh:datatype rdf:langString ; sh:maxCount 1 ] , + [ sh:path sdmx-dimension:refArea ; sh:nodeKind sh:IRI ; sh:maxCount 1 ; + sh:pattern "/admin-units/[0-9]+/#this$" ] , + [ sh:path ltlod:euAmount ; sh:datatype xsd:decimal ; sh:maxCount 1 ] , + [ sh:path ltlod:totalAmount ; sh:datatype xsd:decimal ; sh:maxCount 1 ] , + [ sh:path ltlod:decidedEuAmount ; sh:datatype xsd:decimal ; sh:maxCount 1 ] , + [ sh:path ltlod:stateAid ; sh:datatype xsd:boolean ; sh:maxCount 1 ] , + [ sh:path ltlod:deMinimisAid ; sh:datatype xsd:boolean ; sh:maxCount 1 ] , + [ sh:path dct:date ; sh:datatype xsd:date ; sh:maxCount 1 ] , + [ sh:path dct:temporal ; sh:nodeKind sh:IRI ; sh:maxCount 1 ; + sh:pattern "/calendar/[0-9]{4}/[0-9]{2}/[0-9]{2}/#this$" ] , + [ sh:path ltlod:implementationFrom ; sh:datatype xsd:date ; sh:maxCount 1 ] , + [ sh:path ltlod:implementationTill ; sh:datatype xsd:date ; sh:maxCount 1 ] , + [ sh:path ltlod:fundingPartner ; sh:nodeKind sh:IRI ; + sh:pattern "/legal-entities/[^/]+/#this$" ] . diff --git a/etl/tools/pyproject.toml b/etl/tools/pyproject.toml index d16a1f7..612db00 100644 --- a/etl/tools/pyproject.toml +++ b/etl/tools/pyproject.toml @@ -27,6 +27,7 @@ ltlod-vtek = "ltlod_etl.vtek:main" ltlod-sodra = "ltlod_etl.sodra:main" ltlod-land = "ltlod_etl.land_acquisitions:main" ltlod-insolvency = "ltlod_etl.insolvency:main" +ltlod-eu-funds = "ltlod_etl.eu_funds:main" ltlod-taxes = "ltlod_etl.taxes:main" ltlod-audit = "ltlod_etl.audit:main" diff --git a/etl/tools/src/ltlod_etl/eu_funds.py b/etl/tools/src/ltlod_etl/eu_funds.py new file mode 100644 index 0000000..3a2fd06 --- /dev/null +++ b/etl/tools/src/ltlod_etl/eu_funds.py @@ -0,0 +1,212 @@ +"""Fetch 2014-2020 EU structural-funds implementation data (get.data.gov.lt, finmin) and +flatten it to two CSVs for CSV2RDF: + + contracts.csv id,code,name,beneficiary_code,beneficiary_name,foreign,legal_person_type, + sav,started,finished,impl_from,impl_till,state_aid,de_minimis,eu_amount, + total_amount,decision_eu_amount + partners.csv contract_id,partner_code,partner_name + +One row per implementation contract (finmin/sutartys/Contract, ~26k) — a grant agreement +with a beneficiary (executor_code, a JAR code). ~805 carry a formal project code +(finmin/paraiskos/Project, reached via Contract.project) with decision amounts and a full +financing breakdown (ConFinSource); the rest are code-less financial-instrument payouts +(e.g. partial interest compensation to SMEs) with only the beneficiary, dates and aid flags. + +Joins (all by the Spinta _id, verified 2026-10-25): + ConPartner.project._id = Contract._id (project partners, also JAR-coded) + ConFinSource.project._id = Contract._id (financing sources; the EU and total amounts) + Contract.project._id = paraiskos/Project._id (the code + decision amounts) + +The municipality is a free-text field (e.g. "Akmenės raj."), crosswalked to the AR +savivaldybe code by normalizing the abbreviation and matching the registry name; the valid +set is read live, so an unmatched value gets no refArea link (logged), never a guess. + +NOT fetched: Repayment (lėšų grąžinimai) and kontroles_veiksmai/Suspicion (pažeidimai) are +keyed by an opaque project_hash / project_hash_id that is a hash of an UNPUBLISHED internal +SFMIS identifier — tested 2026-10-25, it matches no hash (md5/sha*/crc/blake, salted, +prefix/suffix) of any published id (project code, _id, project_id, Contract._id), so the +repayments and irregularities cannot be attributed to a project or beneficiary. Also absent: +the 2021-2027 programme (not on Spinta). +""" + +import argparse +import csv +import io +import sys +import time + +import httpx + +API = "https://get.data.gov.lt/datasets/gov/finmin" +AR_SAVIVALDYBE = "https://get.data.gov.lt/datasets/gov/rc/ar/savivaldybe/Savivaldybe" +PAGE = 20000 + + +def fetch_all(client: httpx.Client, url: str) -> list[dict]: + """A small model's full CSV export; fail loudly if empty or a WAF block.""" + for attempt in range(5): + try: + r = client.get(url) + if r.status_code == 200 and "," in r.text.splitlines()[0]: + return list(csv.DictReader(io.StringIO(r.text))) + print(f"WARN {url[:80]}: HTTP {r.status_code}", file=sys.stderr) + except (httpx.HTTPError, IndexError) as e: + print(f"WARN {url[:80]}: {e}", file=sys.stderr) + time.sleep(5 * 2 ** attempt) + sys.exit(f"ERROR: kept failing: {url[:120]}") + + +def fetch_keyset(client: httpx.Client, model: str, select: str) -> list[dict]: + """A large model, keyset-paginated on _id (lossless; the plain CSV export truncates).""" + rows: list[dict] = [] + last = "" + while True: + q = f"select(_id,{select})&sort(_id)&limit({PAGE})" + if last: + q += f"&_id>'{last}'" + page = fetch_all(client, f"{API}/{model}/:format/csv?{q}") + if not page: + break + rows.extend(page) + last = page[-1]["_id"] + print(f" {model}: {len(rows)} rows", file=sys.stderr) + if not rows: + sys.exit(f"ERROR: {model} returned no rows") + return rows + + +def municipality_crosswalk(client: httpx.Client) -> dict[str, str]: + """finmin municipality text (e.g. 'Akmenės raj.', 'Alytaus miesto', 'Birštono') -> AR + sav_kodas, by normalizing the abbreviation and matching the registry name.""" + ar = fetch_all(client, f"{AR_SAVIVALDYBE}/:format/csv?select(sav_kodas,pavadinimas)") + by_name = {(r["pavadinimas"] or "").strip(): str(r["sav_kodas"]).strip() for r in ar} + return by_name + + +def to_sav(text: str, by_name: dict[str, str]) -> str: + """Map one finmin municipality text to an AR sav_kodas, or '' if none matches.""" + t = (text or "").strip() + if not t: + return "" + norm = t.replace(" raj.", " rajono") + # exact ("Alytaus miesto", "Birštono") or prefix ("Akmenės rajono" vs AR "Akmenės rajono") + for name, code in by_name.items(): + if name == norm or name.startswith(norm + " ") or name == norm + " savivaldybė": + return code + for name, code in by_name.items(): + if name.startswith(norm): + return code + # fallback for a form the registry spells without the type word (finmin "Visagino + # miesto" vs AR "Visagino"): the first token, only if it names exactly one municipality. + # Cities that also have a rajono match exactly above, so this stays unambiguous. + stem = norm.split()[0] + hits = [code for name, code in by_name.items() if name.split()[0] == stem] + return hits[0] if len(hits) == 1 else "" + + +def flag(v) -> str: + return "1" if str(v).strip().lower() in ("true", "1", "taip") else "" + + +def amount(v) -> str: + v = (str(v) if v is not None else "").strip() + return v if v not in ("", "None") else "" + + +def main() -> None: + ap = argparse.ArgumentParser(description=__doc__.splitlines()[0]) + ap.add_argument("--contracts", required=True) + ap.add_argument("--partners", required=True) + args = ap.parse_args() + + with httpx.Client(timeout=600, follow_redirects=True) as client: + print("fetching municipality crosswalk…", file=sys.stderr) + by_name = municipality_crosswalk(client) + print("fetching contracts…", file=sys.stderr) + contracts = fetch_keyset( + client, "sutartys/Contract", + "name,project._id,project.code,project.decision_eu_amount,executor," + "executor_code,executor_foreign_person,legal_person_type,municipality," + "started,finished,impl_from,impl_till,state_aid,de_minimis_aid") + print("fetching partners…", file=sys.stderr) + partners = fetch_all(client, f"{API}/sutartys/ConPartner/:format/csv" + "?select(project._id,partner,code)") + print("fetching financing sources…", file=sys.stderr) + finsrc = fetch_all(client, f"{API}/sutartys/ConFinSource/:format/csv" + "?select(project._id,fin_source,amount)") + + # financing: EU-fund and total amounts per contract (_id) + eu_amount: dict[str, str] = {} + total_amount: dict[str, str] = {} + for r in finsrc: + cid = (r.get("project._id") or "").strip() + src = (r.get("fin_source") or "").strip() + amt = amount(r.get("amount")) + if not cid or not amt: + continue + if src == "ES fondų lėšos": + eu_amount[cid] = amt + elif src == "Iš viso": + total_amount[cid] = amt + + unmatched_sav = set() + with open(args.contracts, "w", newline="") as f: + w = csv.writer(f) + w.writerow(["id", "code", "name", "beneficiary_code", "beneficiary_name", "foreign", + "legal_person_type", "sav", "started", "finished", "impl_from", + "impl_till", "state_aid", "de_minimis", "eu_amount", "total_amount", + "decision_eu_amount"]) + n = skipped = 0 + for r in contracts: + cid = (r.get("_id") or "").strip() + ben = (r.get("executor_code") or "").strip() + if not cid or not ben: + # a funding record with no beneficiary code has no JAR link — drop it + skipped += 1 if cid else 0 + continue + muni = (r.get("municipality") or "").strip() + sav = to_sav(muni, by_name) + if muni and not sav: + unmatched_sav.add(muni) + w.writerow([ + cid, + (r.get("project.code") or "").strip(), + (r.get("name") or "").strip(), + (r.get("executor_code") or "").strip(), + (r.get("executor") or "").strip(), + flag(r.get("executor_foreign_person")), + (r.get("legal_person_type") or "").strip(), + sav, + (r.get("started") or "").strip(), + (r.get("finished") or "").strip(), + (r.get("impl_from") or "").strip(), + (r.get("impl_till") or "").strip(), + flag(r.get("state_aid")), + flag(r.get("de_minimis_aid")), + eu_amount.get(cid, ""), + total_amount.get(cid, ""), + amount(r.get("project.decision_eu_amount")), + ]) + n += 1 + + p = 0 + with open(args.partners, "w", newline="") as f: + w = csv.writer(f) + w.writerow(["contract_id", "partner_code", "partner_name"]) + for r in partners: + cid = (r.get("project._id") or "").strip() + code = (r.get("code") or "").strip() + if not cid or not code: + continue + w.writerow([cid, code, (r.get("partner") or "").strip()]) + p += 1 + + coded = sum(1 for r in contracts + if (r.get("project.code") or "").strip() and (r.get("executor_code") or "").strip()) + print(f"contracts: {n} ({coded} with a project code; {skipped} dropped with no beneficiary), " + f"partners: {p}; EU amounts: {len(eu_amount)}; " + f"unmatched municipalities: {sorted(unmatched_sav)}", file=sys.stderr) + + +if __name__ == "__main__": + main() diff --git a/queries/EXAMPLES.md b/queries/EXAMPLES.md index 8b82ddc..13f1360 100644 --- a/queries/EXAMPLES.md +++ b/queries/EXAMPLES.md @@ -3515,6 +3515,159 @@ Rezultatai: +## Politikų įmonės ir ES fondų parama + +**Į kokį klausimą atsako:** kurių politikų deklaruoti juridiniai asmenys gavo 2014–2020 m. ES struktūrinių fondų paramą? + +**Kaip veikia:** privataus intereso ryšio įmonė (`ltlod:interestOrganization`) ir paramos gavėjas (`ltlod:beneficiary`) — tas pats `legal-entities/{jar}/#this` IRI. Imami tik nuosavybės ar valdymo ryšiai (akcininkas, vadovas, valdybos narys ir pan.). ES lėšos susumuojamos ten, kur jos nurodytos (tik ~685 koduotų projektų; finansinių priemonių išmokos sumų neturi). Politiko ryšys su ES lėšų gavusia įmone — signalas patikrinti, ne išvada. Užklausa kerta `vtek` ir `eu-funds` rinkinius. + +```sparql +# VTEK private interests × 2014-2020 EU funds (via the JAR code): officials whose declared +# ownership or control tie is to a company that received EU structural-funds support. The +# interest tie's organization (ltlod:interestOrganization) and the funding beneficiary +# (ltlod:beneficiary) are the same legal-entities/{jar}/#this IRI, so they join with no lookup. +# A politician with a stake in a company drawing EU money is worth a look — not a verdict, a +# flag. Only ownership/control ties (not a declared workplace or plain membership). EU amounts +# are summed where present (only the ~685 coded projects carry them; instrument payouts do not). +# Needs the vtek, eu-funds and the full JAR register loaded. +PREFIX foaf: +PREFIX org: +PREFIX skos: +PREFIX ltlod: + +SELECT ?official ?entity ?tie_role (COUNT(DISTINCT ?contract) AS ?projects) (SUM(?eu) AS ?eu_eur) +WHERE +{ + GRAPH ?interestGraph + { + ?tie ltlod:interestOrganization ?org ; + org:member ?person ; + org:role ?role ; + ltlod:organizationName ?entity . + } + GRAPH ?roleGraph { ?role skos:notation ?roleCode ; skos:prefLabel ?tie_role . FILTER(LANG(?tie_role) = "lt") } + FILTER(?roleCode IN ("akcininkas", "dalininkas", "savininkas", "vadovas", + "vadovas-ar-jo-pavaduotojas", "valdybos-narys", "kolegialaus-valdymo-organo-narys", + "pirmininkas", "pirmininkas-ar-jo-pavaduotojas")) + GRAPH ?contractGraph + { + ?contract a ltlod:EUFundingContract ; + ltlod:beneficiary ?org . + OPTIONAL { ?contract ltlod:euAmount ?eu } + } + GRAPH ?personGraph { ?person foaf:name ?official } +} +GROUP BY ?official ?entity ?tie_role +ORDER BY DESC(?eu_eur) +``` + +Rezultatai: + +| official | entity | tie_role | projects | eu_eur | +|---|---|---|---|---| +| Vitalijus Mitrofanovas | Uždaroji akcinė bendrovė "Akmenės laisvoji ekonominė zona" | Valdybos narys | 1 | 2726257.02 | +| Valentinas Tamulis | UAB "Kėdainių laisvoji ekonominė zona" | Valdybos narys | 1 | | +| Kazimieras Račkauskis | UAB BALTIC MARKETING COMPANY | Akcininkas | 1 | | +| Eugenijus Jovaiša | Uždaroji akcinė bendrovė "ELEKTRONINĖS LEIDYBOS NAMAI" | Akcininkas | 1 | | +| Linas Kukuraitis | Viešoji įstaiga Pal. J. Matulaičio socialinis centras | Dalininkas | 1 | | +| Kęstutis Masiulis | Mykolo Romerio universitetas | Kolegialaus valdymo organo narys | 105 | | +| Robertas Kaunas | UAB "Inkodus" | Akcininkas | 2 | | +| Šarūnas Čėsna | UAB "Telesita" | Akcininkas | 2 | | +| Artūras Visockas | UAB "Šiaulių laisvoji ekonominė zona" | Valdybos narys | 2 | | +| Vidmantas Kanopa | Uždaroji akcinė bendrovė "Daivida" | Akcininkas | 3 | | +| Algirdas Neiberka | Vilkaviškio miesto vietos veiklos grupė | Kolegialaus valdymo organo narys | 4 | | + + + +## Įmonės, gavusios ir ES fondų, ir viešųjų pirkimų + +**Į kokį klausimą atsako:** kurios įmonės gavo ir ES struktūrinių fondų paramą, ir laimėjo viešųjų pirkimų sutarčių — du viešųjų pinigų srautai tai pačiai įmonei? + +**Kaip veikia:** paramos gavėjas (`ltlod:beneficiary`) ir pirkimų tiekėjas (`epo:playedBy`) — tas pats `legal-entities/{jar}/#this` IRI, nukaltas iš JAR kodo. Platus viešųjų pinigų pėdsakas savaime nėra pažeidimas, bet derinį verta žemėlapyje matyti. Užklausa kerta `eu-funds` ir `procurement` rinkinius. + +```sparql +# Cross-domain: 2014-2020 EU funds × public procurement (via the JAR code). +# Companies that both received EU structural-funds support AND won public procurement +# contracts — two streams of public money to the same legal entity. The beneficiary +# (ltlod:beneficiary) and the contractor (epo:playedBy) are the same legal-entities/{jar}/#this +# IRI, minted from the bare JAR code, so they join with neither register loaded. A broad public +# footprint is not wrongdoing, but the combination is worth mapping. EU amounts are summed where +# present (only the ~685 coded projects carry them). Needs the eu-funds and procurement datasets. +PREFIX epo: +PREFIX skos: +PREFIX ltlod: + +SELECT ?name ?eu_projects ?eu_eur ?contracts ?contracts_eur +WHERE +{ + { + SELECT ?org (COUNT(DISTINCT ?contract) AS ?eu_projects) (SUM(?eu) AS ?eu_eur) + WHERE + { + GRAPH ?fundingGraph + { + ?contract a ltlod:EUFundingContract ; + ltlod:beneficiary ?org . + OPTIONAL { ?contract ltlod:euAmount ?eu } + } + } + GROUP BY ?org + } + { + SELECT ?org (COUNT(DISTINCT ?pc) AS ?contracts) (SUM(?value) AS ?contracts_eur) + WHERE + { + GRAPH ?contractGraph + { + ?pc epo:bindsContractor/epo:playedBy ?org ; + epo:hasContractValue/epo:hasAmountValue ?value . + } + } + GROUP BY ?org + } + GRAPH ?entityGraph { ?org skos:prefLabel ?name } +} +ORDER BY DESC(?eu_eur) +``` + +Rezultatai: + +| name | eu_projects | eu_eur | contracts | contracts_eur | +|---|---|---|---|---| +| UAB Vilniaus kogeneracinė jėgainė | 2 | 138070391.69 | 8 | 6633946.0 | +| LIETUVOS MOKSLINIŲ BIBLIOTEKŲ ASOCIACIJA | 1 | 26762938.42 | 2 | 49088.09 | +| Akcinė bendrovė Vidaus vandens kelių direkcija | 1 | 23261121.0 | 1 | 103213.0 | +| Mokslo ir inovacijų sklaidos centras | 1 | 18193000.0 | 1 | 20000.0 | +| VIEŠOJI ĮSTAIGA ŠIAULIŲ REGIONO ATLIEKŲ TVARKYMO CENTRAS | 1 | 10066232.87 | 4 | 209226.75 | +| Nacionalinė visuomenės sveikatos priežiūros laboratorija | 3 | 6515387.2 | 14 | 265500.36 | +| UAB Tauragės regiono atliekų tvarkymo centras | 1 | 2554095.39 | 6 | 97608.79 | +| Viešoji įstaiga Valakupių reabilitacijos centras | 1 | 1500000.0 | 1 | 12000.0 | +| Lietuvos hidrometeorologijos tarnyba prie Aplinkos ministerijos | 1 | 1013670.0 | 4 | 78751.28 | +| Viešoji įstaiga Respublikinė Klaipėdos ligoninė | 1 | 957016.49 | 2 | 78784.54 | +| Marijampolės specialieji socialinės globos namai | 1 | 660820.31 | 8 | 134076.14 | +| Jonavos politechnikos mokykla | 1 | 499998.92 | 1 | 12177.0 | +| Uždaroji akcinė bendrovė "Kalvarijos komunalininkas" | 1 | 437252.87 | 4 | 263761.55 | +| NO NOISE LT, UAB | 1 | 185710.18 | 3 | 43154.0 | +| Vilkaviškio vyskupijos Caritas | 1 | 130087.58 | 1 | 14999.99 | +| VšĮ Projektų valdymo ir mokymo centras | 2 | 95798.39 | 3 | 38000.0 | +| Lietuvos teismo ekspertizės centras | 1 | 81434.25 | 2 | 31962.13 | +| Uždaroji akcinė bendrovė "PALANGOS VANDENYS" | 1 | 74802.39 | 3 | 41206.18 | +| Uždaroji akcinė bendrovė "Kautra" | 1 | 65435.47 | 67 | 8218710.06 | +| Panevėžio švietimo centras | 1 | 19104.32 | 5 | 93940.0 | +| MB "Pagauk" | 1 | 6500.0 | 9 | 260770.93 | +| Lietuvos inžinerijos ir technologijų pramonės asociacija LINPRA | 8 | | 1 | 10000.0 | +| Šiaulių "Aušros" muziejus | 3 | | 1 | 10000.0 | +| Nacionalinis maisto ir veterinarijos rizikos vertinimo institutas | 3 | | 1 | 10000.0 | +| Uždaroji akcinė bendrovė "Jonavos vandenys" | 7 | | 1 | 10000.0 | +| UAB "GINARA AUTOSERVISAS" | 1 | | 1 | 10000.0 | +| Šiaulių miesto koncertinė įstaiga "Saulė" | 1 | | 1 | 10000.0 | +| VšĮ "KOSMOS THEATRE" | 3 | | 1 | 10000.0 | +| UAB "Virtualu" | 1 | | 1 | 10000.0 | +| UAB "Drymeta" | 2 | | 1 | 10000.0 | +| … |   |  |  |  | + + + ## Naujos įmonės be darbuotojų, siekiančios įsigyti žemės **Į kokį klausimą atsako:** kurios nuo 2020 m. įregistruotos bendrovės, neturinčios apdraustųjų darbuotojų, prašė leidimo įsigyti daugiausia žemės ūkio ar miško paskirties žemės? diff --git a/queries/eu-funds-and-procurement.rq b/queries/eu-funds-and-procurement.rq new file mode 100644 index 0000000..faaadb9 --- /dev/null +++ b/queries/eu-funds-and-procurement.rq @@ -0,0 +1,42 @@ +# Cross-domain: 2014-2020 EU funds × public procurement (via the JAR code). +# Companies that both received EU structural-funds support AND won public procurement +# contracts — two streams of public money to the same legal entity. The beneficiary +# (ltlod:beneficiary) and the contractor (epo:playedBy) are the same legal-entities/{jar}/#this +# IRI, minted from the bare JAR code, so they join with neither register loaded. A broad public +# footprint is not wrongdoing, but the combination is worth mapping. EU amounts are summed where +# present (only the ~685 coded projects carry them). Needs the eu-funds and procurement datasets. +PREFIX epo: +PREFIX skos: +PREFIX ltlod: + +SELECT ?name ?eu_projects ?eu_eur ?contracts ?contracts_eur +WHERE +{ + { + SELECT ?org (COUNT(DISTINCT ?contract) AS ?eu_projects) (SUM(?eu) AS ?eu_eur) + WHERE + { + GRAPH ?fundingGraph + { + ?contract a ltlod:EUFundingContract ; + ltlod:beneficiary ?org . + OPTIONAL { ?contract ltlod:euAmount ?eu } + } + } + GROUP BY ?org + } + { + SELECT ?org (COUNT(DISTINCT ?pc) AS ?contracts) (SUM(?value) AS ?contracts_eur) + WHERE + { + GRAPH ?contractGraph + { + ?pc epo:bindsContractor/epo:playedBy ?org ; + epo:hasContractValue/epo:hasAmountValue ?value . + } + } + GROUP BY ?org + } + GRAPH ?entityGraph { ?org skos:prefLabel ?name } +} +ORDER BY DESC(?eu_eur) diff --git a/queries/pinreg-ties-eu-funds.rq b/queries/pinreg-ties-eu-funds.rq new file mode 100644 index 0000000..8b551f8 --- /dev/null +++ b/queries/pinreg-ties-eu-funds.rq @@ -0,0 +1,37 @@ +# VTEK private interests × 2014-2020 EU funds (via the JAR code): officials whose declared +# ownership or control tie is to a company that received EU structural-funds support. The +# interest tie's organization (ltlod:interestOrganization) and the funding beneficiary +# (ltlod:beneficiary) are the same legal-entities/{jar}/#this IRI, so they join with no lookup. +# A politician with a stake in a company drawing EU money is worth a look — not a verdict, a +# flag. Only ownership/control ties (not a declared workplace or plain membership). EU amounts +# are summed where present (only the ~685 coded projects carry them; instrument payouts do not). +# Needs the vtek, eu-funds and the full JAR register loaded. +PREFIX foaf: +PREFIX org: +PREFIX skos: +PREFIX ltlod: + +SELECT ?official ?entity ?tie_role (COUNT(DISTINCT ?contract) AS ?projects) (SUM(?eu) AS ?eu_eur) +WHERE +{ + GRAPH ?interestGraph + { + ?tie ltlod:interestOrganization ?org ; + org:member ?person ; + org:role ?role ; + ltlod:organizationName ?entity . + } + GRAPH ?roleGraph { ?role skos:notation ?roleCode ; skos:prefLabel ?tie_role . FILTER(LANG(?tie_role) = "lt") } + FILTER(?roleCode IN ("akcininkas", "dalininkas", "savininkas", "vadovas", + "vadovas-ar-jo-pavaduotojas", "valdybos-narys", "kolegialaus-valdymo-organo-narys", + "pirmininkas", "pirmininkas-ar-jo-pavaduotojas")) + GRAPH ?contractGraph + { + ?contract a ltlod:EUFundingContract ; + ltlod:beneficiary ?org . + OPTIONAL { ?contract ltlod:euAmount ?eu } + } + GRAPH ?personGraph { ?person foaf:name ?official } +} +GROUP BY ?official ?entity ?tie_role +ORDER BY DESC(?eu_eur) diff --git a/queries/render-examples.py b/queries/render-examples.py index 68a7664..7116c83 100644 --- a/queries/render-examples.py +++ b/queries/render-examples.py @@ -512,6 +512,24 @@ "finansavusi kampaniją ir netrukus bankrutavusi, verta dėmesio — auka galėjo nualinti jau " "smunkančią įmonę, arba politinis ryšys turi reikšmės tolesniems įvykiams. Užklausa kerta " "`elections` ir `insolvency` rinkinius."), + ("pinreg-ties-eu-funds.rq", + "Politikų įmonės ir ES fondų parama", + "**Į kokį klausimą atsako:** kurių politikų deklaruoti juridiniai asmenys gavo 2014–2020 m. " + "ES struktūrinių fondų paramą?\n\n" + "**Kaip veikia:** privataus intereso ryšio įmonė (`ltlod:interestOrganization`) ir paramos " + "gavėjas (`ltlod:beneficiary`) — tas pats `legal-entities/{jar}/#this` IRI. Imami tik " + "nuosavybės ar valdymo ryšiai (akcininkas, vadovas, valdybos narys ir pan.). ES lėšos " + "susumuojamos ten, kur jos nurodytos (tik ~685 koduotų projektų; finansinių priemonių " + "išmokos sumų neturi). Politiko ryšys su ES lėšų gavusia įmone — signalas patikrinti, ne " + "išvada. Užklausa kerta `vtek` ir `eu-funds` rinkinius."), + ("eu-funds-and-procurement.rq", + "Įmonės, gavusios ir ES fondų, ir viešųjų pirkimų", + "**Į kokį klausimą atsako:** kurios įmonės gavo ir ES struktūrinių fondų paramą, ir laimėjo " + "viešųjų pirkimų sutarčių — du viešųjų pinigų srautai tai pačiai įmonei?\n\n" + "**Kaip veikia:** paramos gavėjas (`ltlod:beneficiary`) ir pirkimų tiekėjas (`epo:playedBy`) " + "— tas pats `legal-entities/{jar}/#this` IRI, nukaltas iš JAR kodo. Platus viešųjų pinigų " + "pėdsakas savaime nėra pažeidimas, bet derinį verta žemėlapyje matyti. Užklausa kerta " + "`eu-funds` ir `procurement` rinkinius."), ("land-new-companies.rq", "Naujos įmonės be darbuotojų, siekiančios įsigyti žemės", "**Į kokį klausimą atsako:** kurios nuo 2020 m. įregistruotos bendrovės, neturinčios "