updated querries and template for kbo

This commit is contained in:
Elias Papanikitas
2024-02-20 10:42:56 +01:00
parent 85e2ed2a05
commit 9c421e426b
3 changed files with 156 additions and 84 deletions

159
app.js
View File

@@ -1,4 +1,4 @@
import { app, errorHandler } from "mu";
import { app, errorHandler, uuid } from "mu";
import fetch from "node-fetch";
import { CronJob } from "cron";
import {
@@ -9,74 +9,96 @@ import {
createKboOrganisation,
createNewKboOrg,
linkAbbOrgToKboOrg,
getKboIdentifiers,
} from "./lib/queries";
import { CRON_PATTERN } from "./config";
import { CRON_PATTERN, ORGANIZATION_STATUS } from "./config";
app.post("/sync-kbo-data/:kboStructuredIdUuid", async function (req, res) {
try {
const kboStructuredIdUuid = req.params.kboStructuredIdUuid;
const identifiers = await getIdentifiers(kboStructuredIdUuid);
app.post(
"/sync-kbo-data/:kboStructuredIdUuid/:ovoOrKbo",
async function (req, res) {
try {
const kboStructuredIdUuid = req.params.kboStructuredIdUuid;
const createKbo = req.params.ovoOrKbo === "kbo" ? true : false;
const identifiers = await getIdentifiers(kboStructuredIdUuid);
console.log("create kbo? " + createKbo);
const wegwijsUrl = `https://api.wegwijs.vlaanderen.be/v1/search/organisations?q=kboNumber:${identifiers.kbo}&fields=changeTime,name,ovoNumber,kboNumber,labels,contacts,organisationClassifications,locations,parents)`;
const wegwijsUrl = `https://api.wegwijs.vlaanderen.be/v1/search/organisations?q=kboNumber:${identifiers.kbo}&fields=changeTime,name,shortName,ovoNumber,kboNumber,labels,contacts,organisationClassifications,locations,parents`;
console.log("url: " + wegwijsUrl);
const response = await fetch(wegwijsUrl);
const data = await response.json();
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
let kboObject = getKboFields(wegwijsInfo);
if (kboObject.ovoNumber) {
wegwijsOvo = kboObject.ovoNumber;
let wegwijsOvo = null;
let kboObject = 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
kboObject = getKboFields(wegwijsInfo);
if (kboObject.ovoNumber) {
wegwijsOvo = kboObject.ovoNumber;
}
}
let kboOrg = "";
//console.log(kboObject);
if (!identifiers.kboOrg) {
kboOrg = await createNewKboOrg(kboObject, "null");
if (createKbo && kboObject) {
//create kbo organisation
let kboOrg = null;
const kboIdentifiers = await getKboIdentifiers(identifiers.adminUnit);
let update = false;
if (kboIdentifiers) {
update = new Date(kboObject.changeTime).getTime() < new Date(kboIdentifiers.changeTime).getTime() ? true : false;
}
if(!kboIdentifiers || update){
kboOrg = await createNewKboOrg(kboObject, identifiers.kboId);
await linkAbbOrgToKboOrg(identifiers.adminUnit, kboOrg);
}
return res.status(200).send();
}
//Update Ovo Number
if (wegwijsOvo && wegwijsOvo != identifiers.ovo) {
console.log(identifiers.ovo);
let ovoStructuredIdUri = identifiers.ovoStructuredId;
if (!ovoStructuredIdUri) {
ovoStructuredIdUri = await constructOvoStructure(
identifiers.kboStructuredId
);
}
await updateOvoNumberAndUri(ovoStructuredIdUri, wegwijsOvo);
}
await linkAbbOrgToKboOrg(identifiers.adminUnit, kboOrg, identifiers.kbo);
return res.status(200).send(); // 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();
}
//Update Ovo Number
if (wegwijsOvo && wegwijsOvo != identifiers.ovo) {
console.log(identifiers.ovo);
let ovoStructuredIdUri = identifiers.ovoStructuredId;
if (!ovoStructuredIdUri) {
ovoStructuredIdUri = await constructOvoStructure(
identifiers.kboStructuredId
);
}
await updateOvoNumberAndUri(ovoStructuredIdUri, wegwijsOvo);
}
return res.status(200).send(); // 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();
}
});
);
function getKboFields(data) {
console.log(data.organisationClassifications);
let changeTime = data.changeTime;
//wegwijs naam
let organisationName = data.name;
let shortName = data.shortName;
let ovoNumber = data.ovoNumber;
let kboNumber = data.kboNumber;
//no lables = undefined
//formal naam according to KBO
let formalName = data.labels
?.filter((fields) => {
return fields.labelTypeId === "83c1c22a-6776-0ad6-68d2-819e1c6eec66";
})
.pop()?.value;
let startDate = data.labels
?.filter((fields) => {
return fields.labelTypeId === "83c1c22a-6776-0ad6-68d2-819e1c6eec66";
})
.pop()?.validity?.start;
let activeState = (data.labels
?.filter((fields) => {
return fields.labelTypeId === "83c1c22a-6776-0ad6-68d2-819e1c6eec66" && !fields.validity.hasOwnProperty("end");
}) ? ORGANIZATION_STATUS.ACTIVE : ORGANIZATION_STATUS.INACTIVE)
let email = data.contacts
?.filter((fields) => {
return (
@@ -85,19 +107,16 @@ function getKboFields(data) {
);
})
.pop()?.value;
let rechtsvorm = data.organisationClassifications
?.filter((fields) => {
console.log(fields);
return (
fields.organisationClassificationTypeId === "9bae7539-64fd-5759-743c-ad9dfa4143d4" ||
fields.organisationClassificationTypeId === "1131205e-9212-435d-b4cd-b0d955d08bcf"
fields.organisationClassificationTypeId ===
"9bae7539-64fd-5759-743c-ad9dfa4143d4" ||
fields.organisationClassificationTypeId ===
"1131205e-9212-435d-b4cd-b0d955d08bcf"
);
})
.pop()?.organisationClassificationName;
console.log(rechtsvorm)
let phone = data.contacts
?.filter((fields) => {
return (
@@ -106,7 +125,6 @@ function getKboFields(data) {
);
})
.pop()?.value;
let website = data.contacts
?.filter((fields) => {
return (
@@ -115,9 +133,7 @@ function getKboFields(data) {
);
})
.pop()?.value;
let province = data.parents?.parentOrganisationName;
let formattedAddress = data.locations
?.filter((fields) => {
return (
@@ -127,29 +143,32 @@ function getKboFields(data) {
})
.pop()?.formattedAddress;
//main location according to KBO
let adressComponent = data.locations
?.filter((fields) => {
return (
fields.isMainLocation === true &&
fields.locationTypeId === '537c0b5b-8ab8-fc3d-0b37-f8249cbdd3ba' &&
!fields.validity?.hasOwnProperty("end")
);
})
.pop()?.components;
return {
changeTime: (typeof changeTime != 'undefined' ? changeTime : ""),
organisationName: (typeof organisationName != 'undefined' ? organisationName : ""),
ovoNumber: (typeof ovoNumber != 'undefined' ? ovoNumber : ""),
kboNumber: (typeof kboNumber != 'undefined' ? kboNumber : ""),
formalName: (typeof formalName != 'undefined' ? formalName : ""),
rechtsvorm: (typeof rechtsvorm != 'undefined' ? rechtsvorm : ""),
email: (typeof email != 'undefined' ? email : ""),
phone: (typeof phone != 'undefined' ? phone : ""),
website: (typeof website != 'undefined' ? website : ""),
province: (typeof province != 'undefined' ? province : ""),
formattedAddress: (typeof formattedAddress != 'undefined' ? formattedAddress : ""),
adressComponent: (typeof adressComponent != 'undefined' ? adressComponent : ""),
changeTime: (changeTime ? changeTime : " "),
organisationName: (organisationName ? organisationName : " "),
shortName: (shortName ? shortName : organisationName),
ovoNumber: (ovoNumber ? ovoNumber : " "),
kboNumber: (kboNumber ? kboNumber : " "),
formalName: (formalName ? formalName : " "),
startDate: (startDate ? startDate : " "),
activeState: activeState,
rechtsvorm: (rechtsvorm ? rechtsvorm : " "),
email: (email ? email : " "),
phone: (phone ? phone : " "),
website: (website ? website : " "),
province: (province ? province : " "),
formattedAddress: (formattedAddress ? formattedAddress : " "),
adressComponent: (adressComponent ? adressComponent : " "),
};
}

View File

@@ -1 +1,6 @@
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"
}

View File

@@ -3,7 +3,7 @@ import { querySudo as query, updateSudo as update } from '@lblod/mu-auth-sudo';
export async function getIdentifiers(kboStructuredIdUuid) {
const queryStr = `
SELECT DISTINCT ?kbo ?ovo ?kboStructuredId ?ovoStructuredId ?bestuurseenheid ?kboOrganisation 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>
@@ -26,10 +26,9 @@ export async function getIdentifiers(kboStructuredIdUuid) {
?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 . }
OPTIONAL { ?ovoStructuredId <https://data.vlaanderen.be/ns/generiek#lokaleIdentificator> ?ovo .
}
?bestuurseenheid owl:sameAs ?kboOrganisation .
FILTER (?ovoNotation IN ("OVO-nummer"@nl, "OVO-nummer"))
}
}
@@ -45,6 +44,7 @@ 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,
kboUnit: binding.kboOrganisation?.value
}
@@ -52,6 +52,43 @@ export async function getIdentifiers(kboStructuredIdUuid) {
return null;
}
export async function getKboIdentifiers(administrativeUnit, changeTime) {
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 owl:sameAs ?abbUnit
FILTER(?abbUnit = ${sparqlEscapeUri(administrativeUnit)})
}
}
`;
const result = await query(queryStr);
if (result.results.bindings.length) {
const binding = result.results.bindings[0]; // We should only have one KBO/OVO couple
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}`
@@ -187,36 +224,46 @@ export async function getAllOvoAndKboCouples() {
return null;
}
export async function createRechtsVormStructure(){
}
export async function createNewKboOrg(kboOrg ,kboNummer){
export async function createNewKboOrg(kboOrg, kboId, isUpdate, oldKbo){
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}`;
let updateStr = `
const adressUuidId = uuid();
const adressUri = `http://data.lblod.info/id/adressen/${adressUuidId}`;
let updateStr = "";
updateStr += `
INSERT {
GRAPH ?g {
${sparqlEscapeUri(adressUri)} a <http://www.w3.org/ns/locn#Address> ;
<http://mu.semte.ch/vocabularies/core/uuid> ${sparqlEscapeString(adressUuidId)} ;
<http://www.w3.org/ns/locn#fullAddress> ${sparqlEscapeString(kboOrg.formattedAddress)} .
${sparqlEscapeUri(contactPointUri)} a <http://schema.org/ContactPoint> ;
<http://mu.semte.ch/vocabularies/core/uuid> ${sparqlEscapeString(contactPointUuidId)} ;
<http://schema.org/email> ${sparqlEscapeString(kboOrg.email)} ;
<http://schema.org/telephone> ${sparqlEscapeString(kboOrg.phone)} ;
<http://schema.org/contactType> ${sparqlEscapeString("Kbocontact")} ;
<http://xmlns.com/foaf/0.1/page> ${sparqlEscapeString(kboOrg.website)}.
<http://xmlns.com/foaf/0.1/page> ${sparqlEscapeString(kboOrg.website)} ;
<http://www.w3.org/ns/locn#address> ${sparqlEscapeUri(adressUri)}.
${sparqlEscapeUri(newKboIdUri)} a <http://mu.semte.ch/vocabularies/ext/KboEenheid> ;
<http://mu.semte.ch/vocabularies/core/uuid> ${sparqlEscapeString(newKboOrgIdUuId)} ;
<http://mu.semte.ch/vocabularies/ext/rechtsvorm> ${sparqlEscapeString(kboOrg.rechtsvorm)} ;
<http://mu.semte.ch/vocabularies/ext/shortName> ${sparqlEscapeString(kboOrg.shortName)} ;
<http://mu.semte.ch/vocabularies/ext/startDate> ${sparqlEscapeString(kboOrg.startDate)} ;
<http://www.w3.org/2004/02/skos/core#prefLabel> ${sparqlEscapeString(kboOrg.organisationName)} ;
<http://www.w3.org/2004/02/skos/core#altLabel> ${sparqlEscapeString(kboOrg.formalName)} ;
<https://data.lblod.info/vocabularies/generiek/geplandeEindDatum> ${sparqlEscapeString(kboOrg.changeTime)} ;
<http://www.w3.org/ns/adms#identifier> ${sparqlEscapeUri(kboId)} ;
<http://www.w3.org/ns/regorg#orgStatus> ${sparqlEscapeUri(kboOrg.activeState)} ;
<http://schema.org/contactPoint> ${sparqlEscapeUri(contactPointUri)} .
}
}WHERE{
@@ -230,8 +277,6 @@ export async function createNewKboOrg(kboOrg ,kboNummer){
return newKboIdUri;
}
export async function linkAbbOrgToKboOrg(abbOrgUri ,kboOrgUri){
let updateStr = `
INSERT {
@@ -242,6 +287,9 @@ export async function linkAbbOrgToKboOrg(abbOrgUri ,kboOrgUri){
VALUES ?g {
<http://mu.semte.ch/graphs/administrative-unit>
}
${sparqlEscapeUri(kboOrgUri)} a <http://mu.semte.ch/vocabularies/ext/KboEenheid> .
}
`