Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DIM@6313 - KvK Zoeken API upgraden #756

Merged
merged 2 commits into from
Mar 19, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env.local.example
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
OIDC_CLIENT_SECRET=
OIDC_CLIENT_ID=
OIDC_AUTHORITY=
KVK_BASE_URL=
KVK_BASE_URL=https://api.kvk.nl/test/api
KVK_API_KEY=
HAAL_CENTRAAL_BASE_URL=
HAAL_CENTRAAL_API_KEY=
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
1. Make a copy of .env.local.example, rename it .env.local and fill in the required secrets. This is a subset, a complete overview can be found at https://kiss-klantinteractie-servicesysteem.readthedocs.io/en/latest/INSTALLATION/:
- `OIDC_CLIENT_SECRET`, `OIDC_CLIENT_ID`, `OIDC_AUTHORITY`: use any OIDC provider. Users have access if they have a claim of either type `role` or type `roles` and a value that corresponds to the environment variable `OIDC_KLANTCONTACTMEDEWERKER_ROLE` (`Klantcontactmedewerker` by default). If you're using Azure AD, this can be done by [creating an application role and assigning it to either groups or individual users](https://learn.microsoft.com/en-us/azure/active-directory/develop/howto-add-app-roles-in-azure-ad-apps). Do the same with `OIDC_KLANTCONTACTMEDEWERKER_ROLE` (`Redacteur` by default) to enable a user to manage content in KISS.
- `OIDC_MEDEWERKER_IDENTIFICATIE_CLAIM` and `OIDC_MEDEWERKER_IDENTIFICATIE_TRUNCATE`: the current ZGW standards limit the medewerker identificatie to a maximum of 24 characters. If you are using KISS with OpenKlant / OpenZaak, this means you either need to configure a claim in `OIDC_MEDEWERKER_IDENTIFICATIE_CLAIM` that will never exceed this limit, or configure for it to be truncated by setting `OIDC_MEDEWERKER_IDENTIFICATIE_TRUNCATE` to 24. If you are using KISS with the eSuite, make sure you configure a claim in `OIDC_MEDEWERKER_IDENTIFICATIE_CLAIM` that contains te username known in the eSuite.
- `KVK_BASE_URL`: for the KvK test environment, use `https://api.kvk.nl/test/api/v1`
- `KVK_BASE_URL`: for the KvK test environment, use `https://api.kvk.nl/test/api`
- `KVK_API_KEY`: for the KvK test environment, look for the API key on [the KvK website](https://developers.kvk.nl/documentation/testing)
2. Download the Root and intermediate certificates from [the KvK website](https://developers.kvk.nl/documentation/install-tls-certificate#download-certificates) and place them in a `certificates` folder in the root of the repo
Now, you can either run the application from Visual Studio or with docker-compose
Expand Down
12 changes: 6 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 25 additions & 18 deletions src/features/klant/bedrijf/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,38 +17,39 @@ import type {
} from "./types";

export const bedrijfQuery = <K extends SearchCategories>(
query: BedrijfQuery<K>
query: BedrijfQuery<K>,
) => query;

type KvkPagination = {
pagina: number;
aantal: number;
resultatenPerPagina: number;
totaal: number;
resultaten: any[];
};

const parseKvkPagination = async ({
pagina,
aantal,
resultatenPerPagina,
totaal,
resultaten,
}: KvkPagination): Promise<Paginated<Bedrijf>> => ({
page: await Promise.all(resultaten.map(mapHandelsRegister)),
pageNumber: pagina,
totalRecords: totaal,
pageSize: aantal,
totalPages: totaal === 0 ? 0 : Math.ceil(totaal / aantal),
pageSize: resultatenPerPagina,
totalPages: totaal === 0 ? 0 : Math.ceil(totaal / resultatenPerPagina),
});

const handelsRegisterBaseUrl = "/api/kvk";
const zoekenUrl = `${handelsRegisterBaseUrl}/v2/zoeken`;

const bedrijfQueryDictionary: BedrijfQueryDictionary = {
postcodeHuisnummer: ({ postcode, huisnummer }) => [
["postcode", postcode.numbers + postcode.digits],
["huisnummer", huisnummer],
],
kvkNummer: (search) => [["kvkNummer", search]],
handelsnaam: (search) => [["handelsnaam", search]],
handelsnaam: (search) => [["naam", search]],
};

const getSearchBedrijvenUrl = <K extends SearchCategories>({
Expand All @@ -61,20 +62,26 @@ const getSearchBedrijvenUrl = <K extends SearchCategories>({
// TODO: think about how to search in both klantregister and handelsregister for phone / email

params.set("pagina", page?.toString() ?? "1");
params.set("type", "hoofdvestiging,nevenvestiging");
params.set("type", "hoofdvestiging");
params.append("type", "nevenvestiging");

const searchParams = bedrijfQueryDictionary[query.field](query.value);

searchParams.forEach((tuple) => {
params.set(...tuple);
});

return `${handelsRegisterBaseUrl}/zoeken?${params}`;
return `${zoekenUrl}?${params}`;
};

async function mapHandelsRegister(json: any): Promise<Bedrijf> {
const { vestigingsnummer, kvkNummer, handelsnaam, straatnaam, plaats } =
json ?? {};
const { vestigingsnummer, kvkNummer, naam, adres } = json ?? {};

const { binnenlandsAdres, buitenlandsAdres } = adres ?? {};

const { straatnaam, plaats } = binnenlandsAdres ?? {};

const { straatHuisnummer, postcodeWoonplaats } = buitenlandsAdres ?? {};

let vestiging: KvkVestiging | undefined;

Expand All @@ -90,9 +97,9 @@ async function mapHandelsRegister(json: any): Promise<Bedrijf> {
_typeOfKlant: "bedrijf",
kvkNummer,
vestigingsnummer,
bedrijfsnaam: handelsnaam,
straatnaam,
woonplaats: plaats,
bedrijfsnaam: naam,
straatnaam: straatnaam || straatHuisnummer,
woonplaats: plaats || postcodeWoonplaats,
...(vestiging ?? {}),
};
}
Expand Down Expand Up @@ -162,31 +169,31 @@ type SearchBedrijfArguments<K extends SearchCategories> = {
};

export function useSearchBedrijven<K extends SearchCategories>(
getArgs: () => SearchBedrijfArguments<K>
getArgs: () => SearchBedrijfArguments<K>,
) {
return ServiceResult.fromFetcher(
() => getSearchBedrijvenUrl(getArgs()),
searchBedrijvenInHandelsRegister
searchBedrijvenInHandelsRegister,
);
}

const getVestingUrl = (vestigingsnummer?: string) => {
if (!vestigingsnummer) return "";
return handelsRegisterBaseUrl + "/vestigingsprofielen/" + vestigingsnummer;
return handelsRegisterBaseUrl + "/v1/vestigingsprofielen/" + vestigingsnummer;
};

const fetchVestiging = (url: string) =>
fetchLoggedIn(url).then(throwIfNotOk).then(parseJson).then(mapVestiging);

export const useBedrijfByVestigingsnummer = (
getVestigingsnummer: () => string | undefined
getVestigingsnummer: () => string | undefined,
) => {
const getUrl = () => {
const vestigingsnummer = getVestigingsnummer();
if (!vestigingsnummer) return "";
const searchParams = new URLSearchParams();
searchParams.set("vestigingsnummer", vestigingsnummer);
return `${handelsRegisterBaseUrl}/zoeken?${searchParams}`;
return `${zoekenUrl}?${searchParams}`;
};

const getUniqueId = () => {
Expand Down
Loading