Compare commits

...

25 Commits

Author SHA1 Message Date
Dachamelemon
1caab1e7ba Merge pull request #3 from lblod/fix/shortname-commercialname-left-in-queries
fixed queries
2024-03-22 12:36:57 +01:00
Elias Papanikitas
121a95e8b3 fixed queries 2024-03-22 11:00:16 +01:00
Laurent Deketelaere
dd60850c5d Merge pull request #2 from lblod/formated-code
formatted code in app.js
2024-03-21 16:16:22 +01:00
Elias Papanikitas
66fa8df3b0 formatted code in app.js 2024-03-21 15:48:12 +01:00
Dachamelemon
f989247576 Merge pull request #1 from lblod/improvement/api-expansion
Feat/getting more data to create kbo organisation
2024-03-21 15:36:35 +01:00
Elias Papanikitas
c017f49593 applied changes to querries 2024-03-21 14:17:13 +01:00
Elias Papanikitas
16b9fc4eee applied requested changes 2024-03-21 13:51:31 +01:00
Elias Papanikitas
d4ec2d5083 small changes discussed in personal reviews 2024-03-21 11:33:54 +01:00
Elias Papanikitas
63620ce061 removed healing function from last tests 2024-03-13 15:38:12 +01:00
Elias Papanikitas
6b559889d7 fixed some pr comments 2024-03-13 11:21:08 +01:00
Elias Papanikitas
9c5a6ac4f6 removed healing function call in endpoint function 2024-03-06 12:04:55 +01:00
Elias Papanikitas
adcb348917 removed console.logs() 2024-03-06 10:56:52 +01:00
Elias Papanikitas
a93d4ab922 changed getIdentifiers to more suitable name 2024-03-06 10:49:27 +01:00
Elias Papanikitas
8fa52c7c55 refactoring some code and fixing typos 2024-03-05 18:04:52 +01:00
Elias Papanikitas
4827f1bb9b added error status codes and with responses 2024-03-04 15:32:28 +01:00
Elias Papanikitas
0d3922d646 fix improment 2024-03-04 13:50:03 +01:00
Elias Papanikitas
b7bbf41090 added .improvment to test improvement branches in woodpecker 2024-03-04 13:44:57 +01:00
Elias Papanikitas
76437af462 fixed query issues 2024-03-04 12:49:22 +01:00
Elias Papanikitas
adc49dbdc9 updated api to handle worship units and code refactoring 2024-03-01 13:31:39 +01:00
Elias Papanikitas
3ae00c1165 removed testing lines 2024-02-23 08:53:49 +01:00
Elias Papanikitas
c0f99d7621 updating/cron job fixed 2024-02-23 08:30:56 +01:00
Elias Papanikitas
9c421e426b updated querries and template for kbo 2024-02-20 10:42:56 +01:00
Elias Papanikitas
85e2ed2a05 javascript template bump 2024-02-20 10:42:09 +01:00
Elias Papanikitas
85251f1dfd fixed reschtsvorm 2024-02-07 15:14:17 +01:00
Elias Papanikitas
2f48d6b1a8 getting more data to create kbo organisation 2024-02-07 10:44:14 +01:00
7 changed files with 775 additions and 106 deletions

View File

@@ -0,0 +1,10 @@
steps:
build-feature:
image: woodpeckerci/plugin-docker-buildx
settings:
repo: ${CI_REPO}
tags: "improvement-${CI_COMMIT_BRANCH##improvement/}"
secrets: [ docker_username, docker_password ]
when:
branch: improvement/api-expansion*
event: push

View File

@@ -1,3 +1,3 @@
FROM semtech/mu-javascript-template:1.6.0
FROM semtech/mu-javascript-template:1.8.0
LABEL maintainer="redpencil.io <info@repdencil.io>"

18
api-error-handler.js Normal file
View File

@@ -0,0 +1,18 @@
export const API_STATUS_CODES = {
OK:{
STATUS: "OK",
CODE: 200
},
ERROR_NO_DATA_WEGWIJS:{
STATUS: "no data has been found, check if kbo numer is correct or organisation has OVO number. Organisation without OVO number are not in wegwijs",
CODE: 500
},
STATUS_NO_DATA_OP:{
STATUS: "no kbo number found in OP",
CODE: 400,
},
CUSTOM_SERVER_ERROR:{
STATUS: '',
CODE: 500
}
}

293
app.js
View File

@@ -1,100 +1,285 @@
import { app, errorHandler } from 'mu';
import fetch from 'node-fetch';
import { CronJob } from 'cron';
import { app, errorHandler } from "mu";
import fetch from "node-fetch";
import { CronJob } from "cron";
import {
getIdentifiers,
getAbbOrganizationInfo,
constructOvoStructure,
updateOvoNumberAndUri,
getAllOvoAndKboCouples
createNewKboOrg,
linkAbbOrgToKboOrg,
getKboOrgnizationInfo,
updateKboOrg,
getAllAbbKboOrganizations,
} from "./lib/queries";
import { CRON_PATTERN } from './config';
import {
CRON_PATTERN,
ORGANIZATION_STATUS,
WEGWIJS_API,
WEGWIJS_API_FIELDS,
} from "./config";
import { API_STATUS_CODES } from "./api-error-handler";
import { WEGWIJS_DATA_OBJECT_IDS } from "./wegwijs-object-data-ids";
app.post('/sync-from-kbo/:kboStructuredIdUuid', async function(req, res) {
app.post("/sync-kbo-data/:kboStructuredIdUuid", async function (req, res) {
try {
const kboStructuredIdUuid = req.params.kboStructuredIdUuid;
const identifiers = await getIdentifiers(kboStructuredIdUuid);
const abbOrganizationInfo = await getAbbOrganizationInfo(
kboStructuredIdUuid
);
const response = await fetch(`https://api.wegwijs.vlaanderen.be/v1/search/organisations?q=kboNumber:${identifiers.kbo}&fields=ovoNumber,kboNumber)`);
if (!abbOrganizationInfo?.kbo) {
return setServerStatus(API_STATUS_CODES.STATUS_NO_DATA_OP, res);
}
const wegwijsUrl = `${WEGWIJS_API}?q=kboNumber:${abbOrganizationInfo.kbo}&fields=${WEGWIJS_API_FIELDS}`;
console.log("url: " + wegwijsUrl);
const response = await fetch(wegwijsUrl);
const data = await response.json();
let wegwijsOvo = null;
if (data.length) {
// We got a match on the KBO, getting the associated OVO back
const wegwijsInfo = data[0]; // Wegwijs should only have only one entry per KBO
if (wegwijsInfo.ovoNumber)
wegwijsOvo = wegwijsInfo.ovoNumber;
if (!data.length) {
return setServerStatus(API_STATUS_CODES.ERROR_NO_DATA_WEGWIJS, res);
}
// We got a match on the KBO, getting the associated OVO back
const wegwijsInfo = data[0]; // Wegwijs should only have only one entry per KBO
const kboObject = getKboFields(wegwijsInfo);
const kboIdentifiers = await getKboOrgnizationInfo(
abbOrganizationInfo.adminUnit
);
if (!kboIdentifiers && kboObject) {
await createKbo(
kboObject,
abbOrganizationInfo.kboId,
abbOrganizationInfo.adminUnit
);
}
if (wegwijsOvo && (wegwijsOvo != identifiers.ovo)) {
let ovoStructuredIdUri = identifiers.ovoStructuredId;
if (isUpdateNeeded(kboObject, kboIdentifiers)) {
await updateKboOrg(kboObject, kboIdentifiers);
}
let wegwijsOvo = kboObject.ovoNumber ?? null;
//Update Ovo Number
if (wegwijsOvo && wegwijsOvo != abbOrganizationInfo.ovo) {
let ovoStructuredIdUri = abbOrganizationInfo.ovoStructuredId;
if (!ovoStructuredIdUri) {
ovoStructuredIdUri = await constructOvoStructure(identifiers.kboStructuredId);
ovoStructuredIdUri = await constructOvoStructure(
abbOrganizationInfo.kboStructuredId
);
}
await updateOvoNumberAndUri(ovoStructuredIdUri, wegwijsOvo);
}
return res.status(200).send(); // since we await, it should be 200
return setServerStatus(API_STATUS_CODES.OK, res); // since we await, it should be 200
} catch (e) {
console.log("Something went wrong while calling /sync-from-kbo", e);
return res.status(500).send();
return setServerStatus(API_STATUS_CODES.CUSTOM_SERVER_ERROR, res, e);
}
});
new CronJob(CRON_PATTERN, async function() {
const now = new Date().toISOString();
console.log(`OVO numbers healing triggered by cron job at ${now}`);
try {
await healOvoNumbers();
} catch (err) {
console.log(`An error occurred during OVO numbers healing at ${now}: ${err}`)
}
}, null, true);
function getKboFields(data) {
const {
changeTime,
shortName,
ovoNumber,
kboNumber,
labels = [],
contacts = [],
organisationClassifications = [],
locations = [],
} = data;
async function healOvoNumbers() {
//no labels = undefined
//formal name according to KBO
let formalName = extractObjectData(
labels,
WEGWIJS_DATA_OBJECT_IDS.LABELS
)?.value;
let email = extractObjectData(
contacts,
WEGWIJS_DATA_OBJECT_IDS.CONTACTS.EMAIL
)?.value;
let phone = extractObjectData(
contacts,
WEGWIJS_DATA_OBJECT_IDS.CONTACTS.PHONE
)?.value;
let website = extractObjectData(
contacts,
WEGWIJS_DATA_OBJECT_IDS.CONTACTS.WEBSITE
)?.value;
//main location according to KBO
let formattedAddress = extractObjectData(
locations,
WEGWIJS_DATA_OBJECT_IDS.ADDRESS
)?.formattedAddress;
let adressComponent = extractObjectData(
locations,
WEGWIJS_DATA_OBJECT_IDS.ADDRESS
)?.components;
let rechtsvorm = organisationClassifications?.find((fields) => {
return (
fields[WEGWIJS_DATA_OBJECT_IDS.RECHTSVORM.NAME] ===
WEGWIJS_DATA_OBJECT_IDS.RECHTSVORM.ID_1 ||
fields.organisationClassificationTypeId ===
WEGWIJS_DATA_OBJECT_IDS.RECHTSVORM.ID_2
);
})?.organisationClassificationName;
let startDate = labels?.find((fields) => {
return (
fields[WEGWIJS_DATA_OBJECT_IDS.LABELS.NAME] ===
WEGWIJS_DATA_OBJECT_IDS.LABELS.ID
);
})?.validity?.start;
let activeState = labels?.find((fields) => {
return (
fields[WEGWIJS_DATA_OBJECT_IDS.LABELS.NAME] ===
WEGWIJS_DATA_OBJECT_IDS.LABELS.ID &&
!fields.validity.hasOwnProperty("end")
);
})
? ORGANIZATION_STATUS.ACTIVE
: ORGANIZATION_STATUS.INACTIVE;
//currently no commercial name available
return {
changeTime,
shortName,
ovoNumber,
kboNumber,
formalName,
startDate,
activeState,
rechtsvorm,
email,
phone,
website,
formattedAddress,
adressComponent,
};
}
new CronJob(
CRON_PATTERN,
async function () {
const now = new Date().toISOString();
console.log(`Wegwijs data healing triggered by cron job at ${now}`);
try {
await healAbbWithWegWijsData();
} catch (err) {
console.log(
`An error occurred during wegwijs data healing at ${now}: ${err}`
);
}
},
null,
true
);
async function healAbbWithWegWijsData() {
try {
console.log('Healing starting...');
const identifiersCouplesOP = await getAllOvoAndKboCouples();
const identifiersCouplesWegwijs = await getAllOvoAndKboCouplesWegwijs();
for (const identifiersCoupleOP of identifiersCouplesOP) {
const wegwijsOvo = identifiersCouplesWegwijs[identifiersCoupleOP.kbo];
// If a KBO can't be found in wegwijs but we already have an OVO for it in OP, we keep that OVO.
// It happens especially a lot for worship services that sometimes lack data in Wegwijs
if (wegwijsOvo && (identifiersCoupleOP.ovo != wegwijsOvo)) {
// We have a mismatch, let's update the OVO number
let ovoStructuredIdUri = identifiersCoupleOP.ovoStructuredId;
if (!ovoStructuredIdUri) {
ovoStructuredIdUri = await constructOvoStructure(identifiersCoupleOP.kboStructuredId);
console.log("Healing wegwijs info starting...");
const kboIdentifiersOP = await getAllAbbKboOrganizations();
const kboIdentifiersWegwijs = await getAllOvoAndKboCouplesWegwijs();
for (const kboIdentifierOP of kboIdentifiersOP) {
const wegwijsKboOrg = kboIdentifiersWegwijs[kboIdentifierOP.kbo];
if (wegwijsKboOrg) {
const wegwijsOvo = wegwijsKboOrg.ovoNumber;
// If a KBO can't be found in wegwijs but we already have an OVO for it in OP, we keep that OVO.
// It happens especially a lot for worship services that sometimes lack data in Wegwijs
if (wegwijsOvo && kboIdentifierOP.ovo != wegwijsOvo) {
// We have a mismatch, let's update the OVO number
let ovoStructuredIdUri = kboIdentifierOP.ovoStructuredId;
console.log(ovoStructuredIdUri);
if (!ovoStructuredIdUri) {
ovoStructuredIdUri = await constructOvoStructure(
kboIdentifierOP.kboStructuredId
);
}
await updateOvoNumberAndUri(ovoStructuredIdUri, wegwijsOvo);
}
await updateOvoNumberAndUri(ovoStructuredIdUri, wegwijsOvo);
if (!kboIdentifierOP?.kboOrg) {
await createKbo(
wegwijsKboOrg,
kboIdentifierOP.kboId,
kboIdentifierOP.abbOrg
);
}
if (isUpdateNeeded(wegwijsKboOrg, kboIdentifierOP)) {
const kboIdentifiers = await getKboOrgnizationInfo(
kboIdentifierOP.abbOrg
);
await updateKboOrg(wegwijsKboOrg, kboIdentifiers);
}
}
}
console.log('Healing complete!');
console.log("Healing complete!");
} catch (err) {
console.log(`An error occurred during OVO numbers healing: ${err}`)
console.log(`An error occurred during wegwijs info healing: ${err}`);
}
}
async function getAllOvoAndKboCouplesWegwijs() {
let couples = {};
const response = await fetch(`https://api.wegwijs.vlaanderen.be/v1/search/organisations?q=kboNumber:/.*[0-9].*/&fields=ovoNumber,kboNumber&scroll=true`);
const scrollId = JSON.parse(response.headers.get('x-search-metadata')).scrollId;
const response = await fetch(
`${WEGWIJS_API}?q=kboNumber:/.*[0-9].*/&fields=${WEGWIJS_API_FIELDS},parents&scroll=true`
);
const scrollId = JSON.parse(
response.headers.get("x-search-metadata")
).scrollId;
let data = await response.json();
do {
data.forEach(unit => {
couples[unit.kboNumber] = unit.ovoNumber;
data.forEach((unit) => {
const wegwijsUnit = getKboFields(unit);
couples[wegwijsUnit.kboNumber] = wegwijsUnit;
});
const response = await fetch(`https://api.wegwijs.vlaanderen.be/v1/search/organisations/scroll?id=${scrollId}`);
const response = await fetch(`${WEGWIJS_API}/scroll?id=${scrollId}`);
data = await response.json();
} while (data.length)
} while (data.length);
return couples;
}
function isUpdateNeeded(kboWegwijs, kboAbb) {
let update = false;
if (kboWegwijs?.changeTime && kboAbb?.changeTime) {
update =
new Date(kboWegwijs.changeTime).getTime() >
new Date(kboAbb.changeTime).getTime();
}
return update;
}
async function createKbo(wegwijsKboOrg, kboId, abbOrg) {
let newKboOrgUri = await createNewKboOrg(wegwijsKboOrg, kboId);
await linkAbbOrgToKboOrg(abbOrg, newKboOrgUri);
}
function setServerStatus(statusCode, res, message) {
if (statusCode.CODE === 500) {
console.log("Something went wrong while calling /sync-from-kbo", message);
}
return res.status(statusCode.CODE).send(statusCode.STATUS);
}
function extractObjectData(array, field) {
return array?.find((fields) => {
return fields[field.NAME] === field.ID;
});
}
app.use(errorHandler);

View File

@@ -1 +1,10 @@
export const CRON_PATTERN = process.env.CRON_PATTERN || '0 0 0 * * *'; // every day at midnight
export const CRON_PATTERN = process.env.CRON_PATTERN || '0 0 0 * * *'; // every day at midnight
export const ORGANIZATION_STATUS = {
ACTIVE: "http://lblod.data.gift/concepts/63cc561de9188d64ba5840a42ae8f0d6",
INACTIVE: "http://lblod.data.gift/concepts/d02c4e12bf88d2fdf5123b07f29c9311"
}
export const WEGWIJS_API = "https://api.wegwijs.vlaanderen.be/v1/search/organisations";
export const WEGWIJS_API_FIELDS = "changeTime,name,shortName,ovoNumber,kboNumber,labels,contacts,organisationClassifications,locations"

View File

@@ -1,33 +1,35 @@
import { uuid, sparqlEscapeUri, sparqlEscapeString } from "mu";
import { querySudo as query, updateSudo as update } from '@lblod/mu-auth-sudo';
import { querySudo as query, updateSudo as update } from "@lblod/mu-auth-sudo";
export async function getIdentifiers(kboStructuredIdUuid) {
export async function getAbbOrganizationInfo(kboStructuredIdUuid) {
const queryStr = `
SELECT DISTINCT ?kbo ?ovo ?kboStructuredId ?ovoStructuredId WHERE {
SELECT DISTINCT ?kbo ?kboId ?ovo ?kboStructuredId ?ovoStructuredId ?bestuurseenheid WHERE {
VALUES ?g {
<http://mu.semte.ch/graphs/administrative-unit>
<http://mu.semte.ch/graphs/worship-service>
}
GRAPH ?g {
?kboStructuredId a <https://data.vlaanderen.be/ns/generiek#GestructureerdeIdentificator> ;
<http://mu.semte.ch/vocabularies/core/uuid> ${sparqlEscapeString(kboStructuredIdUuid)} ;
<http://mu.semte.ch/vocabularies/core/uuid> ${sparqlEscapeString(
kboStructuredIdUuid
)} ;
<https://data.vlaanderen.be/ns/generiek#lokaleIdentificator> ?kbo .
?kboId <https://data.vlaanderen.be/ns/generiek#gestructureerdeIdentificator> ?kboStructuredId ;
<http://www.w3.org/2004/02/skos/core#notation> ?kboNotation .
?bestuurseeheid <http://www.w3.org/ns/adms#identifier> ?kboId .
?bestuurseenheid <http://www.w3.org/ns/adms#identifier> ?kboId .
FILTER (?kboNotation IN ("KBO nummer"@nl, "KBO nummer"))
OPTIONAL {
?bestuurseeheid <http://www.w3.org/ns/adms#identifier> ?ovoId .
?bestuurseenheid <http://www.w3.org/ns/adms#identifier> ?ovoId .
?ovoId <https://data.vlaanderen.be/ns/generiek#gestructureerdeIdentificator> ?ovoStructuredId ;
<http://www.w3.org/2004/02/skos/core#notation> ?ovoNotation .
OPTIONAL { ?ovoStructuredId <https://data.vlaanderen.be/ns/generiek#lokaleIdentificator> ?ovo . }
FILTER (?ovoNotation IN ("OVO-nummer"@nl, "OVO-nummer"))
}
}
@@ -43,29 +45,78 @@ export async function getIdentifiers(kboStructuredIdUuid) {
kboStructuredId: binding.kboStructuredId.value,
ovo: binding.ovo?.value,
ovoStructuredId: binding.ovoStructuredId?.value,
kboId: binding.kboId?.value,
adminUnit: binding.bestuurseenheid.value,
};
}
return null;
}
export async function getKboOrgnizationInfo(administrativeUnit) {
const queryStr = `
SELECT DISTINCT ?kboUnit ?abbUnit ?changeTime ?contactPointUri ?addressUri WHERE {
VALUES ?g {
<http://mu.semte.ch/graphs/administrative-unit>
<http://mu.semte.ch/graphs/worship-service>
}
GRAPH ?g {
?kboUnit a <http://mu.semte.ch/vocabularies/ext/KboEenheid> ;
<http://mu.semte.ch/vocabularies/core/uuid> ?uuid ;
<http://schema.org/contactPoint> ?contactPointUri ;
<https://data.lblod.info/vocabularies/generiek/geplandeEindDatum> ?changeTime .
?contactPointUri <http://www.w3.org/ns/locn#address> ?addressUri .
?kboUnit <http://www.w3.org/2002/07/owl#sameAs> ?abbUnit
FILTER(?abbUnit = ${sparqlEscapeUri(administrativeUnit)})
}
}
`;
const result = await query(queryStr);
if (result.results.bindings.length) {
const binding = result.results.bindings[0];
return {
kboUnit: binding.kboUnit?.value,
abbUnit: binding.abbUnit?.value,
changeTime: binding.changeTime?.value,
contactPointUri: binding.contactPointUri?.value,
addressUri: binding.addressUri?.value,
};
}
return null;
}
export async function constructOvoStructure(kboStructuredId) {
const idUuid = uuid();
const idUri = `http://data.lblod.info/id/identificatoren/${idUuid}`
const idUri = `http://data.lblod.info/id/identificatoren/${idUuid}`;
const structuredIdUuid = uuid();
const structuredIdUri = `http://data.lblod.info/id/gestructureerdeIdentificatoren/${structuredIdUuid}`
const structuredIdUri = `http://data.lblod.info/id/gestructureerdeIdentificatoren/${structuredIdUuid}`;
const updateStr = `
INSERT {
GRAPH ?g {
?bestuurseenheid <http://www.w3.org/ns/adms#identifier> ${sparqlEscapeUri(idUri)} .
?bestuurseenheid <http://www.w3.org/ns/adms#identifier> ${sparqlEscapeUri(
idUri
)} .
${sparqlEscapeUri(idUri)} a <http://www.w3.org/ns/adms#Identifier> ;
<http://mu.semte.ch/vocabularies/core/uuid> ${sparqlEscapeString(idUuid)} ;
<http://mu.semte.ch/vocabularies/core/uuid> ${sparqlEscapeString(
idUuid
)} ;
<http://www.w3.org/2004/02/skos/core#notation> "OVO-nummer" ;
<https://data.vlaanderen.be/ns/generiek#gestructureerdeIdentificator> ${sparqlEscapeUri(structuredIdUri)} .
<https://data.vlaanderen.be/ns/generiek#gestructureerdeIdentificator> ${sparqlEscapeUri(
structuredIdUri
)} .
${sparqlEscapeUri(structuredIdUri)} a <https://data.vlaanderen.be/ns/generiek#GestructureerdeIdentificator> ;
<http://mu.semte.ch/vocabularies/core/uuid> ${sparqlEscapeString(structuredIdUuid)} .
${sparqlEscapeUri(
structuredIdUri
)} a <https://data.vlaanderen.be/ns/generiek#GestructureerdeIdentificator> ;
<http://mu.semte.ch/vocabularies/core/uuid> ${sparqlEscapeString(
structuredIdUuid
)} .
}
} WHERE {
VALUES ?g {
@@ -73,10 +124,14 @@ export async function constructOvoStructure(kboStructuredId) {
<http://mu.semte.ch/graphs/worship-service>
}
GRAPH ?g {
${sparqlEscapeUri(kboStructuredId)} a <https://data.vlaanderen.be/ns/generiek#GestructureerdeIdentificator> ;
${sparqlEscapeUri(
kboStructuredId
)} a <https://data.vlaanderen.be/ns/generiek#GestructureerdeIdentificator> ;
<https://data.vlaanderen.be/ns/generiek#lokaleIdentificator> ?kbo .
?kboId <https://data.vlaanderen.be/ns/generiek#gestructureerdeIdentificator> ${sparqlEscapeUri(kboStructuredId)} ;
?kboId <https://data.vlaanderen.be/ns/generiek#gestructureerdeIdentificator> ${sparqlEscapeUri(
kboStructuredId
)} ;
<http://www.w3.org/2004/02/skos/core#notation> ?notation .
?bestuurseenheid <http://www.w3.org/ns/adms#identifier> ?kboId .
@@ -95,7 +150,9 @@ export async function updateOvoNumberAndUri(ovoStructuredIdUri, wegwijsOvo) {
DELETE {
GRAPH ?g {
?bestuureseenheid <http://www.w3.org/2002/07/owl#sameAs> ?ovoUri .
${sparqlEscapeUri(ovoStructuredIdUri)} <https://data.vlaanderen.be/ns/generiek#lokaleIdentificator> ?ovo .
${sparqlEscapeUri(
ovoStructuredIdUri
)} <https://data.vlaanderen.be/ns/generiek#lokaleIdentificator> ?ovo .
}
}
`;
@@ -104,8 +161,14 @@ export async function updateOvoNumberAndUri(ovoStructuredIdUri, wegwijsOvo) {
updateStr += `
INSERT {
GRAPH ?g {
?bestuureseenheid <http://www.w3.org/2002/07/owl#sameAs> ${sparqlEscapeUri(`http://data.vlaanderen.be/id/organisatie/${wegwijsOvo}`)} .
${sparqlEscapeUri(ovoStructuredIdUri)} <https://data.vlaanderen.be/ns/generiek#lokaleIdentificator> ${sparqlEscapeString(wegwijsOvo)} .
?bestuureseenheid <http://www.w3.org/2002/07/owl#sameAs> ${sparqlEscapeUri(
`http://data.vlaanderen.be/id/organisatie/${wegwijsOvo}`
)} .
${sparqlEscapeUri(
ovoStructuredIdUri
)} <https://data.vlaanderen.be/ns/generiek#lokaleIdentificator> ${sparqlEscapeString(
wegwijsOvo
)} .
}
}
`;
@@ -119,15 +182,21 @@ export async function updateOvoNumberAndUri(ovoStructuredIdUri, wegwijsOvo) {
}
GRAPH ?g {
${sparqlEscapeUri(ovoStructuredIdUri)} a <https://data.vlaanderen.be/ns/generiek#GestructureerdeIdentificator> .
${sparqlEscapeUri(
ovoStructuredIdUri
)} a <https://data.vlaanderen.be/ns/generiek#GestructureerdeIdentificator> .
OPTIONAL {
?bestuureseenheid
<http://www.w3.org/ns/adms#identifier>/<https://data.vlaanderen.be/ns/generiek#gestructureerdeIdentificator> ${sparqlEscapeUri(ovoStructuredIdUri)} ;
<http://www.w3.org/ns/adms#identifier>/<https://data.vlaanderen.be/ns/generiek#gestructureerdeIdentificator> ${sparqlEscapeUri(
ovoStructuredIdUri
)} ;
<http://www.w3.org/2002/07/owl#sameAs> ?ovoUri .
}
OPTIONAL { ${sparqlEscapeUri(ovoStructuredIdUri)} <https://data.vlaanderen.be/ns/generiek#lokaleIdentificator> ?ovo . }
OPTIONAL { ${sparqlEscapeUri(
ovoStructuredIdUri
)} <https://data.vlaanderen.be/ns/generiek#lokaleIdentificator> ?ovo . }
}
}
`;
@@ -135,27 +204,47 @@ export async function updateOvoNumberAndUri(ovoStructuredIdUri, wegwijsOvo) {
await update(updateStr);
}
export async function getAllOvoAndKboCouples() {
const queryStr = `
SELECT DISTINCT ?kbo ?ovo ?kboStructuredId ?ovoStructuredId WHERE {
VALUES ?g {
<http://mu.semte.ch/graphs/administrative-unit>
<http://mu.semte.ch/graphs/worship-service>
}
GRAPH ?g {
?kboId <https://data.vlaanderen.be/ns/generiek#gestructureerdeIdentificator> ?kboStructuredId ;
<http://www.w3.org/2004/02/skos/core#notation> ?kboNotation .
?kboStructuredId a <https://data.vlaanderen.be/ns/generiek#GestructureerdeIdentificator> ;
<https://data.vlaanderen.be/ns/generiek#lokaleIdentificator> ?kbo .
?bestuurseeheid <http://www.w3.org/ns/adms#identifier> ?kboId .
FILTER (?kboNotation IN ("KBO nummer"@nl, "KBO nummer"))
OPTIONAL {
?bestuurseeheid <http://www.w3.org/ns/adms#identifier> ?ovoId .
export async function getAllAbbKboOrganizations() {
let queryStr = `
SELECT ?kbo ?ovo ?kboStructuredId ?ovoStructuredId ?abbOrg ?kboOrg ?kboId ?changeTime where {
VALUES ?g {
<http://mu.semte.ch/graphs/administrative-unit>
<http://mu.semte.ch/graphs/worship-service>
}
GRAPH ?g {
?kboId <https://data.vlaanderen.be/ns/generiek#gestructureerdeIdentificator> ?kboStructuredId ;
<http://www.w3.org/2004/02/skos/core#notation> ?kboNotation .
?kboStructuredId a <https://data.vlaanderen.be/ns/generiek#GestructureerdeIdentificator> ;
<https://data.vlaanderen.be/ns/generiek#lokaleIdentificator> ?kbo .
?abbOrg <http://www.w3.org/ns/adms#identifier> ?kboId .
FILTER (?kboNotation IN ("KBO nummer"@nl, "KBO nummer"))
FILTER (!regex(?abbOrg, "kboBestuurseenheden","i"))
OPTIONAL{
?kboOrg owl:sameAs ?abbOrg .
?kboOrg <https://data.lblod.info/vocabularies/generiek/geplandeEindDatum> ?changeTime ;
<http://mu.semte.ch/vocabularies/ext/rechtsvorm> ?rechtsVrom ;
<http://www.w3.org/2004/02/skos/core#altLabel> ?shortName ;
<http://mu.semte.ch/vocabularies/ext/startDate> ?startDate ;
<http://www.w3.org/ns/regorg#legalName> ?legalName ;
<http://www.w3.org/ns/regorg#orgStatus> ?activeState ;
<http://schema.org/contactPoint> ?contact .
?contact <http://schema.org/email> ?email ;
<http://schema.org/telephone> ?phone ;
<http://schema.org/contactType> ?contactType ;
<http://xmlns.com/foaf/0.1/page> ?website ;
<http://www.w3.org/ns/locn#address> ?address .
?address <http://www.w3.org/ns/locn#fullAddress> ?fullAddress.
}
OPTIONAL{
?abbOrg <http://www.w3.org/ns/adms#identifier> ?ovoId .
?ovoId <https://data.vlaanderen.be/ns/generiek#gestructureerdeIdentificator> ?ovoStructuredId ;
<http://www.w3.org/2004/02/skos/core#notation> ?ovoNotation .
@@ -163,24 +252,353 @@ export async function getAllOvoAndKboCouples() {
FILTER (?ovoNotation IN ("OVO-nummer"@nl, "OVO-nummer"))
}
}
}
`;
}
}
`;
const result = await query(queryStr);
if (result.results.bindings.length) {
const bindings = result.results.bindings;
return bindings.map(binding => {
return bindings.map((binding) => {
return {
kbo: binding.kbo.value,
kbo: binding.kbo?.value,
kboStructuredId: binding.kboStructuredId.value,
ovo: binding.ovo?.value,
ovoStructuredId: binding.ovoStructuredId?.value,
}
kboOrg: binding.kboOrg?.value,
abbOrg: binding.abbOrg?.value,
kboId: binding.kboId?.value,
changeTime: binding.changeTime?.value,
};
});
}
return null;
}
export async function createNewKboOrg(kboOrg, kboId) {
const newKboOrgIdUuId = uuid();
const newKboIdUri = `http://data.lblod.info/id/kboBestuurseenheden/${newKboOrgIdUuId}`;
const contactPointUuidId = uuid();
const contactPointUri = `http://data.lblod.info/id/contact-punten/${contactPointUuidId}`;
const adressUuidId = uuid();
const adressUri = `http://data.lblod.info/id/adressen/${adressUuidId}`;
let updateStr = `
INSERT {
GRAPH ?g {
${sparqlEscapeUri(adressUri)} a <http://www.w3.org/ns/locn#Address> ;
<http://mu.semte.ch/vocabularies/core/uuid> ${sparqlEscapeString(
adressUuidId
)} `;
if (kboOrg.formattedAddress) {
updateStr += `;
<http://www.w3.org/ns/locn#fullAddress> ${sparqlEscapeString(
kboOrg.formattedAddress
)}`;
}
updateStr += " .";
updateStr += `
${sparqlEscapeUri(contactPointUri)} a <http://schema.org/ContactPoint> ;
<http://mu.semte.ch/vocabularies/core/uuid> ${sparqlEscapeString(
contactPointUuidId
)} ;
<http://purl.org/dc/terms/source> <https://economie.fgov.be/>`;
if (kboOrg.email) {
updateStr += `; <http://schema.org/email> ${sparqlEscapeString(
kboOrg.email
)}`;
}
if (kboOrg.phone) {
updateStr += `; <http://schema.org/telephone> ${sparqlEscapeString(
kboOrg.phone
)}`;
}
if (kboOrg.website) {
updateStr += `; <http://xmlns.com/foaf/0.1/page> ${sparqlEscapeString(
kboOrg.website
)}`;
}
updateStr += `
; <http://schema.org/contactType> ${sparqlEscapeString("Kbocontact")} ;
<http://www.w3.org/ns/locn#address> ${sparqlEscapeUri(adressUri)}.`;
updateStr += ` ${sparqlEscapeUri(
newKboIdUri
)} a <http://mu.semte.ch/vocabularies/ext/KboEenheid> ;
<http://mu.semte.ch/vocabularies/core/uuid> ${sparqlEscapeString(
newKboOrgIdUuId
)}`;
if (kboOrg.rechtsvorm) {
updateStr += `; <http://mu.semte.ch/vocabularies/ext/rechtsvorm> ${sparqlEscapeString(
kboOrg.rechtsvorm
)}`;
}
if (kboOrg.startDate) {
updateStr += `; <http://mu.semte.ch/vocabularies/ext/startDate> ${sparqlEscapeString(
kboOrg.startDate
)}`;
}
if (kboOrg.formalName) {
updateStr += `; <http://www.w3.org/ns/regorg#legalName> ${sparqlEscapeString(
kboOrg.formalName
)}`;
}
if (kboOrg.shortName) {
updateStr += `; <http://www.w3.org/2004/02/skos/core#altLabel> ${sparqlEscapeString(
kboOrg.shortName
)}`;
}
if (kboOrg.changeTime) {
updateStr += `; <https://data.lblod.info/vocabularies/generiek/geplandeEindDatum> ${sparqlEscapeString(
kboOrg.changeTime
)}`;
}
if (kboId) {
updateStr += `; <http://www.w3.org/ns/adms#identifier> ${sparqlEscapeUri(
kboId
)}`;
}
if (kboOrg.activeState) {
updateStr += `; <http://www.w3.org/ns/regorg#orgStatus> ${sparqlEscapeUri(
kboOrg.activeState
)}`;
}
updateStr += `; <http://schema.org/contactPoint> ${sparqlEscapeUri(
contactPointUri
)} .
}
}WHERE{
VALUES ?g {
<http://mu.semte.ch/graphs/administrative-unit>
<http://mu.semte.ch/graphs/worship-service>
}
}
`;
await update(updateStr);
return newKboIdUri;
}
export async function updateKboOrg(newKboInfo, identifiers) {
//update address
await updateKboAddress(newKboInfo, identifiers);
//update ContactPoint
await updateKboContact(newKboInfo, identifiers);
//update kboUnit
await updateKboAdministrativeUnit(newKboInfo, identifiers);
}
export async function linkAbbOrgToKboOrg(abbOrgUri, kboOrgUri) {
if (abbOrgUri && kboOrgUri) {
let updateStr = `
INSERT {
GRAPH ?g {
${sparqlEscapeUri(
kboOrgUri
)} <http://www.w3.org/2002/07/owl#sameAs> ${sparqlEscapeUri(abbOrgUri)} .
}
}WHERE {
VALUES ?g {
<http://mu.semte.ch/graphs/administrative-unit>
<http://mu.semte.ch/graphs/worship-service>
}
${sparqlEscapeUri(
kboOrgUri
)} a <http://mu.semte.ch/vocabularies/ext/KboEenheid> .
}
`;
await update(updateStr);
}
}
async function updateKboAddress(newKboInfo, identifiers) {
let updateStr = `
DELETE{
GRAPH ?g{
?adressUri a <http://www.w3.org/ns/locn#Address> ;
<http://www.w3.org/ns/locn#fullAddress> ?fulladdress .
}
}
INSERT{
graph ?g{
?adressUri a <http://www.w3.org/ns/locn#Address>
`;
if (newKboInfo.formattedAddress) {
updateStr += `
;
<http://www.w3.org/ns/locn#fullAddress> ${sparqlEscapeString(
newKboInfo.formattedAddress
)}
`;
}
updateStr += `
.
}
}
`;
updateStr += `
WHERE{
VALUES ?g {
<http://mu.semte.ch/graphs/administrative-unit>
}
GRAPH ?g {
?adressUri a <http://www.w3.org/ns/locn#Address> ;
<http://www.w3.org/ns/locn#fullAddress> ?fulladdress .
FILTER(?adressUri = ${sparqlEscapeUri(identifiers.addressUri)})
}
}
`;
await update(updateStr);
}
async function updateKboContact(newKboInfo, identifiers) {
let updateStr = `
DELETE{
GRAPH ?g{
?contact a <http://schema.org/ContactPoint> ;
<http://schema.org/email> ?email ;
<http://schema.org/telephone> ?phone ;
<http://xmlns.com/foaf/0.1/page> ?website .
}
}
INSERT{
graph ?g{
?contact a <http://schema.org/ContactPoint>
`;
if (newKboInfo.email) {
updateStr += `; <http://schema.org/email> ${sparqlEscapeString(
newKboInfo.email
)}`;
}
if (newKboInfo.phone) {
updateStr += `; <http://schema.org/telephone> ${sparqlEscapeString(
newKboInfo.phone
)}`;
}
if (newKboInfo.phone) {
updateStr += `; <http://xmlns.com/foaf/0.1/page> ${sparqlEscapeString(
newKboInfo.website
)}`;
}
updateStr += `
.
}
}
`;
updateStr += `
WHERE{
VALUES ?g {
<http://mu.semte.ch/graphs/administrative-unit>
}
GRAPH ?g {
?contact a <http://schema.org/ContactPoint> ;
<http://schema.org/email> ?email ;
<http://schema.org/telephone> ?phone ;
<http://xmlns.com/foaf/0.1/page> ?website .
FILTER(?contact = ${sparqlEscapeUri(identifiers.contactPointUri)})
}
}
`;
await update(updateStr);
}
async function updateKboAdministrativeUnit(newKboInfo, identifiers) {
let updateStr = `
DELETE{
GRAPH ?g{
?kboUnit a <http://mu.semte.ch/vocabularies/ext/KboEenheid> ;
<http://mu.semte.ch/vocabularies/ext/rechtsvorm> ?rechtsVorm ;
<http://www.w3.org/2004/02/skos/core#altLabel> ?shortName ;
<http://mu.semte.ch/vocabularies/ext/startDate> ?startDate ;
<http://www.w3.org/ns/regorg#legalName> ?orgName ;
<https://data.lblod.info/vocabularies/generiek/geplandeEindDatum> ?changeTime ;
<http://www.w3.org/ns/regorg#orgStatus> ?activeState .
}
}
INSERT{
graph ?g{
?kboUnit a <http://mu.semte.ch/vocabularies/ext/KboEenheid>
`;
if (newKboInfo.rechtsvorm) {
updateStr += `
;
<http://mu.semte.ch/vocabularies/ext/rechtsvorm> ${sparqlEscapeString(
newKboInfo.rechtsvorm
)}
`;
}
if (newKboInfo.startDate) {
updateStr += `
;
<http://mu.semte.ch/vocabularies/ext/startDate> ${sparqlEscapeString(
newKboInfo.startDate
)}
`;
}
if (newKboInfo.formalName) {
updateStr += `; <http://www.w3.org/ns/regorg#legalName> ${sparqlEscapeString(
newKboInfo.formalName
)}`;
}
if (newKboInfo.shortName) {
updateStr += `; <http://www.w3.org/2004/02/skos/core#altLabel> ${sparqlEscapeString(
newKboInfo.shortName
)}`;
}
if (newKboInfo.changeTime) {
updateStr += `
;
<https://data.lblod.info/vocabularies/generiek/geplandeEindDatum> ${sparqlEscapeString(
newKboInfo.changeTime
)}
`;
}
if (newKboInfo.activeState) {
updateStr += `
;
<http://www.w3.org/ns/regorg#orgStatus> ${sparqlEscapeUri(
newKboInfo.activeState
)}
`;
}
updateStr += `
.
}
}
`;
updateStr += `
WHERE{
VALUES ?g {
<http://mu.semte.ch/graphs/administrative-unit>
}
GRAPH ?g {
?kboUnit a <http://mu.semte.ch/vocabularies/ext/KboEenheid> ;
<http://mu.semte.ch/vocabularies/ext/rechtsvorm> ?rechtsVorm ;
<http://www.w3.org/2004/02/skos/core#altLabel> ?shortName ;
<http://mu.semte.ch/vocabularies/ext/startDate> ?startDate ;
<http://www.w3.org/ns/regorg#legalName> ?orgName ;
<https://data.lblod.info/vocabularies/generiek/geplandeEindDatum> ?changeTime ;
<http://www.w3.org/ns/regorg#orgStatus> ?activeState .
FILTER(?kboUnit = ${sparqlEscapeUri(identifiers.kboUnit)})
}
}
`;
await update(updateStr);
}
// Update queries: via mu-auth if it comes from the frontend ?

View File

@@ -0,0 +1,29 @@
export const WEGWIJS_DATA_OBJECT_IDS = {
LABELS: {
ID: "83c1c22a-6776-0ad6-68d2-819e1c6eec66",
NAME: "labelTypeId",
},
ADDRESS: {
ID: "537c0b5b-8ab8-fc3d-0b37-f8249cbdd3ba",
NAME: "locationTypeId",
},
RECHTSVORM: {
ID_1: "9bae7539-64fd-5759-743c-ad9dfa4143d4",
ID_2: "1131205e-9212-435d-b4cd-b0d955d08bcf",
NAME: "organisationClassificationTypeId",
},
CONTACTS: {
EMAIL: {
ID: "6763f372-02c5-478c-b7d7-802dc60a64b9",
NAME: "contactTypeId",
},
PHONE: {
ID: "d792d4ff-8c34-4336-8434-56ecb40f2fa4",
NAME: "contactTypeId",
},
WEBSITE: {
ID: "f611e91d-a811-4519-afa6-08f0e9dcdd9b",
NAME: "contactTypeId",
},
},
};