Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6912cec711 | ||
|
|
efb5760925 | ||
|
|
00ddb35f40 | ||
|
|
227f093ebe | ||
|
|
9daccc7736 | ||
|
|
b25514e580 | ||
|
|
789cbd5703 | ||
|
|
c174bfaa03 | ||
|
|
b2e6c0edd0 | ||
|
|
ba3e33f01b | ||
|
|
e2e64c9b0d | ||
| fe789ce33f |
22
CHANGELOG.md
22
CHANGELOG.md
@@ -1,16 +1,32 @@
|
||||
# Changelog
|
||||
## 1.39.0 (2026-04-02)
|
||||
- Add KBO organizations report to report generation service [OP-3738]
|
||||
- Add organizations detail report (addresses and contact info) to report generation service [OP-3738]
|
||||
- Query organisations: organisational data [OP-3761]
|
||||
|
||||
## 1.38.3 (2026-02-26)
|
||||
### Deploy notes
|
||||
```
|
||||
drc restart report-generation
|
||||
```
|
||||
|
||||
## 1.38.4 (2026-02-26)
|
||||
### Backend
|
||||
- Related organisations: Duplicate relations between municipalities and OCMWs [OP-3743]
|
||||
- Bump frontend [OP-3735]
|
||||
|
||||
### Deploy instructions
|
||||
```
|
||||
drc restart migrations cache
|
||||
drc pull frontend && drc up -d frontend
|
||||
```
|
||||
|
||||
## 1.38.3 (2026-02-26)
|
||||
### Backend
|
||||
- Related organisations: Duplicate relations between municipalities and OCMWs [OP-3743]
|
||||
|
||||
### Deploy instructions
|
||||
```
|
||||
drc restart migrations cache
|
||||
```
|
||||
|
||||
## 1.38.2 (2026-02-20)
|
||||
### Backend
|
||||
- Remove deprecated organizations-public-info producer [OP-3581]
|
||||
|
||||
@@ -187,19 +187,22 @@ Update `docker-compose.override.yml` to:
|
||||
vendor-management-consumer:
|
||||
environment:
|
||||
DCR_SYNC_BASE_URL: "https://dev.loket.lblod.info/" # or another endpoint
|
||||
DCR_DISABLE_INITIAL_SYNC: "true"
|
||||
BATCH_SIZE: "500"
|
||||
DCR_SECRET_KEY: "<key>>" # fill in key for selected endpoint
|
||||
DCR_SYNC_LOGIN_ENDPOINT: "https://dev.loket.lblod.info/sync/vendor-management/login" # login for selected endpoint
|
||||
DCR_DISABLE_DELTA_INGEST: "false"
|
||||
DCR_DISABLE_INITIAL_SYNC: "false"
|
||||
```
|
||||
Then:
|
||||
```
|
||||
drc up -d migrations
|
||||
drc up -d db vendor-management-consumer
|
||||
```
|
||||
Finally, put the stack back up.
|
||||
# Wait until success of the previous step
|
||||
|
||||
Finally, put the stack back up and reindex elasticsearch:
|
||||
```
|
||||
drc up -d
|
||||
sh scripts/reset-elastic.sh
|
||||
```
|
||||
|
||||
### Setting up the delta-producers related services
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
import OrganizationsReport from './organizations-report'
|
||||
import RelatedOrganizationsReport from './related-organizations-report'
|
||||
import KboOrganizationsReport from './kbo-organizations-report'
|
||||
import OrganizationsDetailReport from './organizations-detail-report'
|
||||
import OrganizationsPlatformReport from './organizations-platform-report'
|
||||
|
||||
export default [
|
||||
OrganizationsReport,
|
||||
RelatedOrganizationsReport,
|
||||
KboOrganizationsReport,
|
||||
OrganizationsDetailReport,
|
||||
OrganizationsPlatformReport,
|
||||
];
|
||||
|
||||
108
config/reports/kbo-organizations-report.js
Normal file
108
config/reports/kbo-organizations-report.js
Normal file
@@ -0,0 +1,108 @@
|
||||
import { generateReportFromData, batchedQuery } from "../helpers.js";
|
||||
import { PREFIXES } from "./utils";
|
||||
|
||||
export default {
|
||||
cronPattern: "0 00 4 * * *",
|
||||
name: "kboOrganizations",
|
||||
execute: async () => {
|
||||
const reportData = {
|
||||
title: "kbo organizations",
|
||||
description: "List of KBO Organizations with contact information",
|
||||
filePrefix: "exports/kbo-organizations",
|
||||
};
|
||||
|
||||
console.log("Generating KBO organizations report");
|
||||
|
||||
const queryString = `
|
||||
${PREFIXES}
|
||||
|
||||
SELECT DISTINCT
|
||||
?org
|
||||
?org_legal_name
|
||||
?org_classification_label
|
||||
?org_status_label
|
||||
?org_kbo_number
|
||||
?org_contact_point
|
||||
?org_full_address
|
||||
?org_email
|
||||
?org_telephone
|
||||
?website
|
||||
WHERE {
|
||||
?org <http://purl.org/dc/terms/source> <https://economie.fgov.be/> .
|
||||
?org a <http://mu.semte.ch/vocabularies/ext/KboOrganisatie> .
|
||||
|
||||
OPTIONAL { ?org regorg:legalName ?org_legal_name . }
|
||||
|
||||
OPTIONAL {
|
||||
?org <http://mu.semte.ch/vocabularies/ext/rechtsvorm> ?org_classification_label .
|
||||
}
|
||||
|
||||
OPTIONAL {
|
||||
?org regorg:orgStatus ?org_status .
|
||||
?org_status skos:prefLabel ?org_status_label .
|
||||
}
|
||||
|
||||
OPTIONAL {
|
||||
?org adms:identifier ?identifier .
|
||||
?identifier skos:notation "KBO nummer" ;
|
||||
generiek:gestructureerdeIdentificator ?id1 .
|
||||
?id1 generiek:lokaleIdentificator ?org_kbo_number .
|
||||
}
|
||||
|
||||
OPTIONAL {
|
||||
?org schema:contactPoint ?org_contact_point .
|
||||
|
||||
OPTIONAL {
|
||||
?org_contact_point locn:address ?org_address .
|
||||
?org_address locn:fullAddress ?org_full_address .
|
||||
}
|
||||
|
||||
OPTIONAL { ?org_contact_point schema:email ?org_email . }
|
||||
OPTIONAL { ?org_contact_point schema:telephone ?org_telephone . }
|
||||
OPTIONAL { ?org_contact_point foaf:page ?website . }
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const queryResponse = await batchedQuery(queryString);
|
||||
|
||||
const data = queryResponse.results.bindings.map((row) => ({
|
||||
org: getSafeValue(row, "org"),
|
||||
org_legal_name: getSafeValue(row, "org_legal_name"),
|
||||
org_classification_label: getSafeValue(row, "org_classification_label"),
|
||||
org_status_label: getSafeValue(row, "org_status_label"),
|
||||
org_kbo_number: getSafeValue(row, "org_kbo_number"),
|
||||
org_contact_point: getSafeValue(row, "org_contact_point"),
|
||||
org_full_address: getSafeValue(row, "org_full_address"),
|
||||
org_email: getSafeValue(row, "org_email"),
|
||||
org_telephone: getSafeValue(row, "org_telephone"),
|
||||
website: getSafeValue(row, "website"),
|
||||
}));
|
||||
|
||||
await generateReportFromData(
|
||||
data,
|
||||
[
|
||||
"org",
|
||||
"org_legal_name",
|
||||
"org_classification_label",
|
||||
"org_status_label",
|
||||
"org_kbo_number",
|
||||
"org_contact_point",
|
||||
"org_full_address",
|
||||
"org_email",
|
||||
"org_telephone",
|
||||
"website",
|
||||
],
|
||||
reportData,
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
function getSafeValue(entry, property) {
|
||||
return entry[property] ? wrapInQuote(entry[property].value) : null;
|
||||
}
|
||||
|
||||
// Some values might contain commas; wrapping them in escapes quotes doesn't disrupt the columns.
|
||||
function wrapInQuote(value) {
|
||||
return `\"${value}\"`;
|
||||
}
|
||||
147
config/reports/organizations-detail-report.js
Normal file
147
config/reports/organizations-detail-report.js
Normal file
@@ -0,0 +1,147 @@
|
||||
import { generateReportFromData, batchedQuery } from "../helpers.js";
|
||||
import { PREFIXES } from "./utils";
|
||||
|
||||
export default {
|
||||
cronPattern: "0 00 4 * * *",
|
||||
name: "organizationsDetail",
|
||||
execute: async () => {
|
||||
const reportData = {
|
||||
title: "organizations detail",
|
||||
description:
|
||||
"List of Organizations with address and contact information",
|
||||
filePrefix: "exports/organizations-detail",
|
||||
};
|
||||
|
||||
console.log("Generating organizations detail report");
|
||||
|
||||
const queryString = `
|
||||
${PREFIXES}
|
||||
|
||||
SELECT DISTINCT ?org
|
||||
?org_pref_label ?org_classification_label ?org_status_label ?org_kbo_number
|
||||
|
||||
?primary_email
|
||||
?website
|
||||
?primary_telephone
|
||||
?secondary_telephone
|
||||
|
||||
?full_address
|
||||
?land
|
||||
?gemeente
|
||||
?straat
|
||||
?huisnummer
|
||||
?busnummer
|
||||
?postcode
|
||||
?province
|
||||
|
||||
WHERE {
|
||||
?org a org:Organization .
|
||||
OPTIONAL { ?org regorg:legalName ?org_legal_name . }
|
||||
OPTIONAL { ?org skos:prefLabel ?org_pref_label . }
|
||||
OPTIONAL {
|
||||
?org org:classification ?org_classification .
|
||||
?org_classification skos:prefLabel ?org_classification_label .
|
||||
}
|
||||
OPTIONAL {
|
||||
?org regorg:orgStatus ?org_status .
|
||||
?org_status skos:prefLabel ?org_status_label .
|
||||
}
|
||||
OPTIONAL {
|
||||
?org adms:identifier ?identifier .
|
||||
?identifier skos:notation "KBO nummer" ;
|
||||
generiek:gestructureerdeIdentificator ?id1 .
|
||||
?id1 generiek:lokaleIdentificator ?org_kbo_number .
|
||||
}
|
||||
OPTIONAL {
|
||||
?org org:hasPrimarySite ?org_site .
|
||||
?org_site organisatie:bestaatUit ?org_address .
|
||||
?org_site org:siteAddress ?org_contact_point .
|
||||
|
||||
OPTIONAL {
|
||||
?org_contact_point schema:email ?primary_email .
|
||||
?org_contact_point schema:contactType "Primary" .
|
||||
}
|
||||
OPTIONAL {
|
||||
?org_contact_point schema:telephone ?primary_telephone .
|
||||
?org_contact_point schema:contactType "Primary" .
|
||||
}
|
||||
OPTIONAL {
|
||||
?org_contact_point schema:telephone ?secondary_telephone .
|
||||
?org_contact_point schema:contactType "Secondary" .
|
||||
}
|
||||
|
||||
OPTIONAL {
|
||||
?org_contact_point foaf:page ?website .
|
||||
?org_contact_point schema:contactType "Primary" .
|
||||
}
|
||||
|
||||
OPTIONAL { ?org_contact_point schema:contactType ?contact_type . }
|
||||
|
||||
OPTIONAL { ?org_address locn:fullAddress ?full_address . }
|
||||
OPTIONAL { ?org_address adres:land ?land . }
|
||||
OPTIONAL { ?org_address adres:gemeentenaam ?gemeente . }
|
||||
OPTIONAL { ?org_address locn:thoroughfare ?straat . }
|
||||
OPTIONAL { ?org_address adres:Adresvoorstelling.huisnummer ?huisnummer . }
|
||||
OPTIONAL { ?org_address adres:Adresvoorstelling.busnummer ?busnummer . }
|
||||
OPTIONAL { ?org_address locn:postCode ?postcode . }
|
||||
OPTIONAL { ?org_address locn:adminUnitL2 ?province . }
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const queryResponse = await batchedQuery(queryString);
|
||||
|
||||
const data = queryResponse.results.bindings.map((row) => ({
|
||||
org: getSafeValue(row, "org"),
|
||||
org_pref_label: getSafeValue(row, "org_pref_label"),
|
||||
org_classification_label: getSafeValue(row, "org_classification_label"),
|
||||
org_status_label: getSafeValue(row, "org_status_label"),
|
||||
org_kbo_number: getSafeValue(row, "org_kbo_number"),
|
||||
primary_email: getSafeValue(row, "primary_email"),
|
||||
website: getSafeValue(row, "website"),
|
||||
primary_telephone: getSafeValue(row, "primary_telephone"),
|
||||
secondary_telephone: getSafeValue(row, "secondary_telephone"),
|
||||
full_address: getSafeValue(row, "full_address"),
|
||||
land: getSafeValue(row, "land"),
|
||||
gemeente: getSafeValue(row, "gemeente"),
|
||||
straat: getSafeValue(row, "straat"),
|
||||
huisnummer: getSafeValue(row, "huisnummer"),
|
||||
busnummer: getSafeValue(row, "busnummer"),
|
||||
postcode: getSafeValue(row, "postcode"),
|
||||
province: getSafeValue(row, "province"),
|
||||
}));
|
||||
|
||||
await generateReportFromData(
|
||||
data,
|
||||
[
|
||||
"org",
|
||||
"org_pref_label",
|
||||
"org_classification_label",
|
||||
"org_status_label",
|
||||
"org_kbo_number",
|
||||
"primary_email",
|
||||
"website",
|
||||
"primary_telephone",
|
||||
"secondary_telephone",
|
||||
"full_address",
|
||||
"land",
|
||||
"gemeente",
|
||||
"straat",
|
||||
"huisnummer",
|
||||
"busnummer",
|
||||
"postcode",
|
||||
"province",
|
||||
],
|
||||
reportData,
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
function getSafeValue(entry, property) {
|
||||
return entry[property] ? wrapInQuote(entry[property].value) : null;
|
||||
}
|
||||
|
||||
// Some values might contain commas; wrapping them in escapes quotes doesn't disrupt the columns.
|
||||
function wrapInQuote(value) {
|
||||
return `\"${value}\"`;
|
||||
}
|
||||
123
config/reports/organizations-platform-report.js
Normal file
123
config/reports/organizations-platform-report.js
Normal file
@@ -0,0 +1,123 @@
|
||||
import { generateReportFromData, batchedQuery } from "../helpers.js";
|
||||
import { PREFIXES } from "./utils";
|
||||
|
||||
export default {
|
||||
cronPattern: "0 00 2 * * *",
|
||||
name: "organizationsPlatform",
|
||||
execute: async () => {
|
||||
const reportData = {
|
||||
title: "organizations platform",
|
||||
description: "List of Organizations with digital platform information",
|
||||
filePrefix: "exports/organizations-platform",
|
||||
};
|
||||
|
||||
console.log("Generating organizations platform report");
|
||||
|
||||
const queryString = `
|
||||
${PREFIXES}
|
||||
PREFIX muAccount: <http://mu.semte.ch/vocabularies/account/>
|
||||
|
||||
SELECT
|
||||
?org
|
||||
?org_pref_label
|
||||
?org_classification_label
|
||||
?org_status_label
|
||||
?org_legal_name
|
||||
?org_alt_label
|
||||
?org_werkingsgebied_label
|
||||
?org_ovo_number
|
||||
?org_kbo_number
|
||||
(COALESCE(?platforms, "Loket voor Lokale Besturen") AS ?org_digitaal_platform)
|
||||
WHERE {
|
||||
?org a org:Organization .
|
||||
|
||||
OPTIONAL { ?org skos:prefLabel ?org_pref_label }
|
||||
OPTIONAL { ?org skos:altLabel ?org_alt_label }
|
||||
|
||||
OPTIONAL {
|
||||
?org regorg:legalName ?org_legal_name .
|
||||
}
|
||||
|
||||
OPTIONAL {
|
||||
?org org:classification ?org_classification .
|
||||
?org_classification skos:prefLabel ?org_classification_label .
|
||||
}
|
||||
|
||||
OPTIONAL {
|
||||
?org regorg:orgStatus ?org_status .
|
||||
?org_status skos:prefLabel ?org_status_label .
|
||||
}
|
||||
|
||||
OPTIONAL {
|
||||
?org besluit:werkingsgebied ?org_werkingsgebied .
|
||||
?org_werkingsgebied rdfs:label ?org_werkingsgebied_label .
|
||||
}
|
||||
|
||||
OPTIONAL {
|
||||
?org adms:identifier ?identifier1 .
|
||||
?identifier1 skos:notation "KBO nummer" ;
|
||||
generiek:gestructureerdeIdentificator ?id1 .
|
||||
?id1 generiek:lokaleIdentificator ?org_kbo_number .
|
||||
}
|
||||
|
||||
OPTIONAL {
|
||||
?org adms:identifier ?identifier2 .
|
||||
?identifier2 skos:notation "OVO-nummer" ;
|
||||
generiek:gestructureerdeIdentificator ?id2 .
|
||||
?id2 generiek:lokaleIdentificator ?org_ovo_number .
|
||||
}
|
||||
|
||||
OPTIONAL {
|
||||
SELECT ?org (GROUP_CONCAT(DISTINCT ?digitaal_platform; separator=", ") AS ?platforms)
|
||||
WHERE {
|
||||
?vendor a ext:Vendor ;
|
||||
muAccount:canActOnBehalfOf ?org ;
|
||||
foaf:name ?digitaal_platform .
|
||||
}
|
||||
GROUP BY ?org
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const queryResponse = await batchedQuery(queryString);
|
||||
|
||||
const data = queryResponse.results.bindings.map((row) => ({
|
||||
"URI organisatie": getSafeValue(row, "org"),
|
||||
"label naam": getSafeValue(row, "org_pref_label"),
|
||||
"label classificatie": getSafeValue(row, "org_classification_label"),
|
||||
"label status": getSafeValue(row, "org_status_label"),
|
||||
"label juridische naam": getSafeValue(row, "org_legal_name"),
|
||||
"label alternatieve naam": getSafeValue(row, "org_alt_label"),
|
||||
"label werkingsgebied": getSafeValue(row, "org_werkingsgebied_label"),
|
||||
"label OVO nummer": getSafeValue(row, "org_ovo_number"),
|
||||
"label KBO nummer": getSafeValue(row, "org_kbo_number"),
|
||||
"label digitaal platform": getSafeValue(row, "org_digitaal_platform"),
|
||||
}));
|
||||
|
||||
await generateReportFromData(
|
||||
data,
|
||||
[
|
||||
"URI organisatie",
|
||||
"label naam",
|
||||
"label classificatie",
|
||||
"label status",
|
||||
"label juridische naam",
|
||||
"label alternatieve naam",
|
||||
"label werkingsgebied",
|
||||
"label OVO nummer",
|
||||
"label KBO nummer",
|
||||
"label digitaal platform",
|
||||
],
|
||||
reportData,
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
function getSafeValue(entry, property) {
|
||||
return entry[property] ? wrapInQuote(entry[property].value) : null;
|
||||
}
|
||||
|
||||
// Some values might contain commas; wrapping them in escapes quotes doesn't disrupt the columns.
|
||||
function wrapInQuote(value) {
|
||||
return `\"${value}\"`;
|
||||
}
|
||||
@@ -212,7 +212,7 @@ services:
|
||||
restart: always
|
||||
logging: *default-logging
|
||||
frontend:
|
||||
image: lblod/frontend-organization-portal:1.36.4
|
||||
image: lblod/frontend-organization-portal:1.36.5
|
||||
volumes:
|
||||
- ./config/frontend/add-x-frame-options-header.conf:/config/add-x-frame-options.conf
|
||||
environment:
|
||||
|
||||
Reference in New Issue
Block a user