Small fixes + Postcodelookup fallback
This commit is contained in:
parent
f05152c626
commit
bf84540401
@ -1,12 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* Postcode Service - Handles postcode lookup via postcode.tech API
|
||||
* with fallback to openpostcode.nl API
|
||||
*/
|
||||
|
||||
class PostcodeService
|
||||
{
|
||||
/**
|
||||
* Lookup address by postcode and house number
|
||||
* Uses postcode.tech as primary, falls back to openpostcode.nl
|
||||
*
|
||||
* @param string $postcode
|
||||
* @param string $number
|
||||
@ -14,7 +16,7 @@ class PostcodeService
|
||||
*/
|
||||
public static function lookup(string $postcode, string $number): array
|
||||
{
|
||||
$postcode = str_replace(' ', '', $postcode);
|
||||
$postcode = strtoupper(str_replace(' ', '', $postcode));
|
||||
|
||||
if (empty($postcode) || empty($number)) {
|
||||
return [
|
||||
@ -24,6 +26,26 @@ class PostcodeService
|
||||
];
|
||||
}
|
||||
|
||||
// Try primary service (postcode.tech)
|
||||
$result = self::lookupPostcodeTech($postcode, $number);
|
||||
|
||||
// If primary service fails (server error or timeout), try fallback
|
||||
if (!$result['success'] && $result['http_code'] >= 500) {
|
||||
$result = self::lookupOpenPostcode($postcode, $number);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup via postcode.tech API (primary)
|
||||
*
|
||||
* @param string $postcode
|
||||
* @param string $number
|
||||
* @return array
|
||||
*/
|
||||
private static function lookupPostcodeTech(string $postcode, string $number): array
|
||||
{
|
||||
$url = "https://postcode.tech/api/v1/postcode?postcode={$postcode}&number={$number}";
|
||||
|
||||
$ch = curl_init($url);
|
||||
@ -42,21 +64,16 @@ class PostcodeService
|
||||
if ($curlError || $httpCode >= 500) {
|
||||
return [
|
||||
'success' => false,
|
||||
'error' => 'Postcode service niet bereikbaar, vul straat en woonplaats zelf in',
|
||||
'error' => 'Postcode.tech service niet bereikbaar',
|
||||
'details' => $curlError,
|
||||
'http_code' => 503
|
||||
];
|
||||
}
|
||||
|
||||
if ($httpCode >= 400) {
|
||||
$decoded = json_decode($response, true);
|
||||
$errorMessage = ($decoded && isset($decoded['error']))
|
||||
? $decoded['error']
|
||||
: 'Postcode niet gevonden of ongeldige invoer, vul straat en woonplaats zelf in';
|
||||
|
||||
return [
|
||||
'success' => false,
|
||||
'error' => $errorMessage,
|
||||
'error' => self::translateErrorMessage($response, $httpCode),
|
||||
'http_code' => $httpCode
|
||||
];
|
||||
}
|
||||
@ -69,4 +86,123 @@ class PostcodeService
|
||||
'http_code' => 200
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup via openpostcode.nl API (fallback)
|
||||
* No authentication required
|
||||
*
|
||||
* @param string $postcode
|
||||
* @param string $number
|
||||
* @return array
|
||||
*/
|
||||
private static function lookupOpenPostcode(string $postcode, string $number): array
|
||||
{
|
||||
$url = "https://openpostcode.nl/api/address?postcode={$postcode}&huisnummer={$number}";
|
||||
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$curlError = curl_error($ch);
|
||||
curl_close($ch);
|
||||
|
||||
if ($curlError || $httpCode >= 500) {
|
||||
return [
|
||||
'success' => false,
|
||||
'error' => 'Postcode service niet bereikbaar, vul straat en woonplaats zelf in',
|
||||
'details' => $curlError,
|
||||
'http_code' => 503
|
||||
];
|
||||
}
|
||||
|
||||
if ($httpCode >= 400) {
|
||||
return [
|
||||
'success' => false,
|
||||
'error' => self::translateErrorMessage($response, $httpCode),
|
||||
'http_code' => $httpCode
|
||||
];
|
||||
}
|
||||
|
||||
$data = json_decode($response, true);
|
||||
|
||||
// Transform openpostcode.nl response to match postcode.tech format
|
||||
$transformedData = self::transformOpenPostcodeResponse($data);
|
||||
|
||||
return [
|
||||
'success' => true,
|
||||
'data' => $transformedData,
|
||||
'http_code' => 200
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform openpostcode.nl response to match postcode.tech format
|
||||
*
|
||||
* openpostcode.nl returns:
|
||||
* - postcode, huisnummer, straat, buurt, wijk, woonplaats, gemeente, provincie, latitude, longitude
|
||||
*
|
||||
* postcode.tech returns:
|
||||
* - postcode, number, street, city, municipality, province, geo (lat, lng)
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
private static function transformOpenPostcodeResponse(array $data): array
|
||||
{
|
||||
return [
|
||||
'postcode' => $data['postcode'] ?? '',
|
||||
'number' => $data['huisnummer'] ?? '',
|
||||
'street' => $data['straat'] ?? '',
|
||||
'city' => $data['woonplaats'] ?? '',
|
||||
'municipality' => $data['gemeente'] ?? '',
|
||||
'province' => $data['provincie'] ?? '',
|
||||
'geo' => [
|
||||
'lat' => $data['latitude'] ?? null,
|
||||
'lng' => $data['longitude'] ?? null
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate API error messages to user-friendly Dutch messages
|
||||
*
|
||||
* @param string $response Raw API response
|
||||
* @param int $httpCode HTTP status code
|
||||
* @return string User-friendly error message in Dutch
|
||||
*/
|
||||
private static function translateErrorMessage(string $response, int $httpCode): string
|
||||
{
|
||||
$decoded = json_decode($response, true);
|
||||
$apiError = ($decoded && isset($decoded['error'])) ? strtolower($decoded['error']) : '';
|
||||
|
||||
// Map common API error messages to Dutch user-friendly messages
|
||||
if (strpos($apiError, 'huisnummer not found') !== false ||
|
||||
strpos($apiError, 'house number not found') !== false ||
|
||||
strpos($apiError, 'number not found') !== false) {
|
||||
return 'Dit huisnummer is niet gevonden bij deze postcode. Controleer het huisnummer of vul het adres handmatig in.';
|
||||
}
|
||||
|
||||
if (strpos($apiError, 'postcode not found') !== false ||
|
||||
strpos($apiError, 'invalid postcode') !== false) {
|
||||
return 'Deze postcode is niet gevonden. Controleer de postcode of vul het adres handmatig in.';
|
||||
}
|
||||
|
||||
if (strpos($apiError, 'invalid') !== false) {
|
||||
return 'Ongeldige invoer. Controleer de postcode en het huisnummer.';
|
||||
}
|
||||
|
||||
if ($httpCode === 404) {
|
||||
return 'Adres niet gevonden. Controleer de postcode en het huisnummer of vul het adres handmatig in.';
|
||||
}
|
||||
|
||||
if ($httpCode === 429) {
|
||||
return 'Te veel verzoeken. Probeer het later opnieuw of vul het adres handmatig in.';
|
||||
}
|
||||
|
||||
// Default message
|
||||
return 'Adres niet gevonden. Vul straat en woonplaats handmatig in.';
|
||||
}
|
||||
}
|
||||
|
||||
32
index.html
32
index.html
@ -200,10 +200,25 @@
|
||||
</template>
|
||||
</select>
|
||||
</div>
|
||||
<div x-show="recommendedOptions.length > 0" x-cloak class="mt-8 space-y-3">
|
||||
<p class="text-[10px] font-black text-red-500 uppercase tracking-widest italic px-2 text-center">
|
||||
Wellicht ook interessant</p>
|
||||
|
||||
<template x-for="u in recommendedOptions" :key="u.id">
|
||||
<div
|
||||
class="flex items-center justify-between p-4 border rounded-2xl bg-slate-50 hover:bg-white transition-all shadow-sm">
|
||||
<span class="text-xs font-bold text-slate-700"
|
||||
x-text="u.name + ' (€' + u.price + ')'"></span>
|
||||
<button @click="toggleUpsell(u)" :class="isInCart(u.id) ? 'bg-red-500' : 'bg-green-600'"
|
||||
class="text-white px-6 py-2 rounded-xl text-[10px] font-black uppercase shadow-md"
|
||||
x-text="isInCart(u.id) ? 'Verwijder' : 'Voeg toe'">
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<div class="mt-8 border-t pt-6">
|
||||
<h2 class="font-bold mb-4 text-slate-400 uppercase text-[10px] tracking-widest italic text-center">
|
||||
Extra's</h2>
|
||||
Voeg extra product toe</h2>
|
||||
<div class="flex gap-2">
|
||||
<!-- Custom searchable dropdown for extra products -->
|
||||
<div class="relative flex-1" x-data="{ openExtra: false }" @click.away="openExtra = false">
|
||||
@ -244,22 +259,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div x-show="recommendedOptions.length > 0" x-cloak class="mt-8 space-y-3">
|
||||
<p class="text-[10px] font-black text-red-500 uppercase tracking-widest italic px-2 text-center">
|
||||
Aanbevolen</p>
|
||||
|
||||
<template x-for="u in recommendedOptions" :key="u.id">
|
||||
<div
|
||||
class="flex items-center justify-between p-4 border rounded-2xl bg-slate-50 hover:bg-white transition-all shadow-sm">
|
||||
<span class="text-xs font-bold text-slate-700"
|
||||
x-text="u.name + ' (€' + u.price + ')'"></span>
|
||||
<button @click="toggleUpsell(u)" :class="isInCart(u.id) ? 'bg-red-500' : 'bg-green-600'"
|
||||
class="text-white px-6 py-2 rounded-xl text-[10px] font-black uppercase shadow-md"
|
||||
x-text="isInCart(u.id) ? 'Verwijder' : 'Voeg toe'">
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 lg:col-span-3">
|
||||
|
||||
@ -58,8 +58,8 @@ const FormsComponent = {
|
||||
const data = await ApiService.lookupPostcode(this.form.postcode, this.form.houseno);
|
||||
|
||||
if (data.street) {
|
||||
this.form.street = data.street.toUpperCase();
|
||||
this.form.city = data.city.toUpperCase();
|
||||
this.form.street = data.street;
|
||||
this.form.city = data.city;
|
||||
} else if (data.error) {
|
||||
this.addressError = data.error;
|
||||
} else {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user