Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
* Datafordeler CRV service endpoint update - GraphQL.

## [3.0.3] - 2025-11-19

Expand Down
112 changes: 100 additions & 12 deletions src/Plugin/os2web/DataLookup/DatafordelerCVR.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Render\Markup;
use Drupal\os2web_datalookup\LookupResult\CompanyLookupResult;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Psr\Http\Message\ResponseInterface;

/**
* Defines a plugin for DatafordelerCVR.
Expand All @@ -17,22 +19,41 @@
* group = "cvr_lookup"
* )
*/
class DatafordelerCVR extends DatafordelerBase implements DataLookupCompanyInterface {
class DatafordelerCVR extends DataLookupBase implements DataLookupCompanyInterface {

/**
* Http client.
*
* @var \GuzzleHttp\Client
*/
protected Client $httpClient;

/**
* {@inheritdoc}
*/
public function defaultConfiguration(): array {
return [
'webserviceurl_live' => 'https://s5-certservices.datafordeler.dk/CVR/HentCVRData/1/REST/',
'webserviceurl_live' => 'https://graphql.datafordeler.dk/flexibleCurrent/v1',
'api_key' => '',
] + parent::defaultConfiguration();
}

/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state): array {
$form = parent::buildConfigurationForm($form, $form_state);
$form['webserviceurl_live'] = [
'#type' => 'textfield',
'#title' => $this->t('Webservice URL (LIVE)'),
'#description' => $this->t('Live URL against which to make the request, e.g. https://graphql.datafordeler.dk/flexibleCurrent/v1'),
'#default_value' => $this->configuration['webserviceurl_live'],
];

$form['api_key'] = [
'#type' => 'textfield',
'#title' => $this->t('API Key'),
'#default_value' => $this->configuration['api_key'],
];

$form['test_cvr'] = [
'#type' => 'textfield',
Expand All @@ -46,7 +67,12 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
* {@inheritdoc}
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state): void {
parent::submitConfigurationForm($form, $form_state);
$keys = array_keys($this->defaultConfiguration());
$configuration = $this->getConfiguration();
foreach ($keys as $key) {
$configuration[$key] = $form_state->getValue($key);
}
$this->setConfiguration($configuration);

if (!empty($form_state->getValue('test_cvr'))) {
$lookupResult = $this->lookup($form_state->getValue('test_cvr'));
Expand All @@ -66,26 +92,28 @@ public function lookup(string $param): CompanyLookupResult {
try {
$msg = sprintf('Hent virksomhed med CVRNummer: %s', $param);
$this->auditLogger->info('DataLookup', $msg);
$response = $this->getResponse('hentVirksomhedMedCVRNummer', ['query' => ['pCVRNummer' => $param]]);
$response = $this->executeQuery($param);
$result = json_decode((string) $response->getBody());
}
catch (ClientException $e) {
catch (GuzzleException $e) {
$msg = sprintf('Hent virksomhed med CVRNummer (%s): %s', $param, $e->getMessage());
$this->auditLogger->error('DataLookup', $msg);
$result = $e->getMessage();
}

$cvrResult = new CompanyLookupResult();
if ($result && isset($result->virksomhed) && !empty((array) $result->virksomhed)) {
if ($result && isset($result->data->CVR_Virksomhed->nodes) && !empty($result->data->CVR_Virksomhed->nodes)) {
$companyGraph = $result->data->CVR_Virksomhed->nodes[0]->id_CVR_CVREnhed_id_ref->nodes[0];

$cvrResult->setSuccessful();
$cvrResult->setCvr($param);

if ($result->virksomhedsnavn) {
$cvrResult->setName($result->virksomhedsnavn->vaerdi);
if ($companyGraph->id_CVR_Navn_CVREnhedsId_ref) {
$cvrResult->setName($companyGraph->id_CVR_Navn_CVREnhedsId_ref->vaerdi);
}

if ($result->beliggenhedsadresse) {
$address = $result->beliggenhedsadresse;
if ($companyGraph->id_CVR_Adressering_CVREnhedsId_ref) {
$address = $companyGraph->id_CVR_Adressering_CVREnhedsId_ref->nodes[0];

$cvrResult->setStreet($address->CVRAdresse_vejnavn ?? '');
$cvrResult->setHouseNr($address->CVRAdresse_husnummerFra ?? '');
Expand Down Expand Up @@ -124,4 +152,64 @@ public function lookup(string $param): CompanyLookupResult {
return $cvrResult;
}

/**
* Executes the GraphQL lookup request for a specific CVR number.
*
* Builds the GraphQL payload and sends it to the configured Datafordeler
* endpoint using the shared HTTP request flow from the parent class.
*
* @param string $cvr
* The CVR number to look up.
*
* @return \Psr\Http\Message\ResponseInterface
* The raw HTTP response from the GraphQL endpoint.
*
* @throws \GuzzleHttp\Exception\GuzzleException
*/
private function executeQuery($cvr): ResponseInterface {
$this->httpClient = new Client();

// Setting date to TODAY 00:00:00, so that we are always getting up-to-date
// information.
$virkningstid = (new \DateTimeImmutable('today', new \DateTimeZone('UTC')))
->format('Y-m-d\T00:00:00\Z');

$query = <<<GRAPHQL
{ CVR_Virksomhed(first: 1, virkningstid: "{$virkningstid}", where: { CVRNummer: { eq: {$cvr} } }) {
nodes {
CVRNummer
id_CVR_CVREnhed_id_ref(first: 1) {
nodes {
id_CVR_Navn_CVREnhedsId_ref { vaerdi }
id_CVR_Adressering_CVREnhedsId_ref(first: 1, where: { AdresseringAnvendelse: { in: ["beliggenhedsadresse", "postadresse"] } }) {
nodes {
AdresseringAnvendelse
CVRAdresse_vejnavn
CVRAdresse_husnummerFra
CVRAdresse_etagebetegnelse
CVRAdresse_doerbetegnelse
CVRAdresse_postnummer
CVRAdresse_postdistrikt
CVRAdresse_kommunekode
}
}
}
}
}
}
}
GRAPHQL;

$webserviceUrl = $this->configuration['webserviceurl_live'];

return $this->httpClient->post($webserviceUrl, [
'query' => [
'apiKey' => $this->configuration['api_key'],
],
'json' => [
'query' => $query,
],
]);
}

}
Loading