Skip to content

Commit

Permalink
Merge pull request #1304 from Amsterdam/main
Browse files Browse the repository at this point in the history
Merge main
  • Loading branch information
NvdLaan authored Jan 30, 2025
2 parents d3b9c96 + 57762e0 commit 32448d7
Show file tree
Hide file tree
Showing 38 changed files with 474 additions and 1,397 deletions.
11 changes: 4 additions & 7 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ LOGGING_LEVEL=WARNING # To prevent flooding the logging in local development. De
SECRET_KEY_TOP_ZAKEN=SECRET_KEY_TOP_ZAKEN
SECRET_KEY_TON_ZAKEN=SECRET_KEY_TON_ZAKEN
BELASTING_API_URL=https://api-acc.belastingen.centric.eu/bel/inn/afne/vora/v1/vorderingenidentificatienummer/
BAG_API_SEARCH_URL=https://api.data.amsterdam.nl/atlas/search/adres/
BAG_API_PDOK_URL=https://api.pdok.nl/bzk/locatieserver/search/v3_1/free
BAG_API_NUMMERAANDUIDING_SEARCH_URL=https://api.data.amsterdam.nl/v1/bag/nummeraanduidingen/
BAG_API_BENKAGG_SEARCH_URL=https://api.data.amsterdam.nl/v1/benkagg/adresseerbareobjecten/
DECOS_JOIN_USERNAME=ZakenTop
Expand All @@ -26,12 +26,7 @@ DEFAULT_THEME=Vakantieverhuur
DEFAULT_REASON=SIG melding
VAKANTIEVERHUUR_TOERISTISCHE_VERHUUR_API_URL=https://api.acceptatie.toeristischeverhuur.nl/api/
VAKANTIEVERHUUR_TOERISTISCHE_VERHUUR_API_ACCESS_TOKEN=SECRET_ACCESS_TOKEN
VAKANTIEVERHUUR_TOERISTISCHE_VERHUUR_API_HEALTH_CHECK_BAG_ID=0503100000000209
VAKANTIEVERHUUR_REGISTRATIE_API_URL=https://acceptatie.toeristischeverhuur.nl/ext/api/Registrations/
VAKANTIEVERHUUR_REGISTRATIE_API_ACCESS_TOKEN=SECRET_ACCESS_TOKEN
VAKANTIEVERHUUR_REGISTRATIE_API_HEALTH_CHECK_BSN=999999990
VAKANTIEVERHUUR_REGISTRATIE_API_HEALTH_CHECK_BAG_ID=0503100000000209
VAKANTIEVERHUUR_REGISTRATIE_API_HEALTH_CHECK_REGISTRATION_NUMBER=05034542BC484F3891BB
VAKANTIEVERHUUR_TOERISTISCHE_VERHUUR_API_BSN=999999990
ZAKEN_CONTAINER_HOST=http://zaak-gateway:8000

DEFAULT_SCHEDULE_ACTIONS=Huisbezoek,Hercontrole
Expand All @@ -53,3 +48,5 @@ HOST=http://172.17.0.1:8080
USE_DECOS_MOCK_DATA=False
SESSION_COOKIE_AGE=25200
AXES_ENABLED=False
BRP_CLIENT_ID = client_id
BRP_CLIENT_SECRET = client_secret
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ __pycache__/
app/.env
app/.coverage
private_media/
.local.env
3 changes: 3 additions & 0 deletions .local.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Set these in your .local.env file
BRP_CLIENT_ID=
BRP_CLIENT_SECRET=
136 changes: 57 additions & 79 deletions app/apps/addresses/mock.py
Original file line number Diff line number Diff line change
@@ -1,81 +1,58 @@
def mock_do_bag_search_id_result():
def mock_do_bag_search_pdok_by_bag_id_result():
return {
"_links": {
"self": {
"href": "https://api.data.amsterdam.nl/atlas/search/adres/?q=1100MOmo%2042&page=1"
},
"next": {"href": None},
"prev": {"href": None},
},
"count_hits": 1,
"count": 1,
"results": [
{
"_links": {
"self": {
"href": "https://api.data.amsterdam.nl/bag/v1.1/verblijfsobject/0363010001028805/"
}
},
"type": "verblijfsobject",
"dataset": "v11_nummeraanduiding",
"adres": "Mockemstraat 42",
"postcode": "1100MO",
"straatnaam": "Mockemstraat",
"straatnaam_no_ws": "Mockemstraat",
"huisnummer": 42,
"toevoeging": "42",
"bag_huisletter": "",
"bag_toevoeging": "",
"woonplaats": "Amsterdam",
"type_adres": "Hoofdadres",
"status": "Naamgeving uitgegeven",
"landelijk_id": "0363200000516944",
"vbo_status": "Verblijfsobject in gebruik",
"adresseerbaar_object_id": "0363010001028805",
"subtype": "verblijfsobject",
"centroid": [6.969577908893136, 52.82184218979086],
"subtype_id": "0363010001028805",
"_display": "Mockemstraat 42",
}
],
}


def mock_do_bag_search_id_result_without_links():
return {
"_links": {
"self": {
"href": "https://api.data.amsterdam.nl/atlas/search/adres/?q=1100MOmo%2042&page=1"
},
"next": {"href": None},
"prev": {"href": None},
},
"count_hits": 1,
"count": 1,
"results": [
{
"type": "verblijfsobject",
"dataset": "v11_nummeraanduiding",
"adres": "Mockemstraat 42",
"postcode": "1100MO",
"straatnaam": "Mockemstraat",
"straatnaam_no_ws": "Mockemstraat",
"huisnummer": 42,
"toevoeging": "42",
"bag_huisletter": "",
"bag_toevoeging": "",
"woonplaats": "Amsterdam",
"type_adres": "Hoofdadres",
"status": "Naamgeving uitgegeven",
"landelijk_id": "03635000650516944",
"vbo_status": "Verblijfsobject in gebruik",
"adresseerbaar_object_id": "03635000650516944",
"subtype": "verblijfsobject",
"centroid": [4.969577908893136, 52.82184218979086],
"subtype_id": "03635000650516944",
"_display": "Mockemstraat 42",
}
],
"response": {
"numFound": 1,
"start": 0,
"maxScore": 7.2593327,
"numFoundExact": True,
"docs": [
{
"bron": "BAG",
"woonplaatscode": "3594",
"type": "adres",
"woonplaatsnaam": "Amsterdam",
"wijkcode": "WK0363AF",
"huis_nlt": "1",
"openbareruimtetype": "Weg",
"buurtnaam": "Waterloopleinbuurt",
"gemeentecode": "0363",
"rdf_seealso": "http://bag.basisregistraties.overheid.nl/bag/id/nummeraanduiding/0363200012145295",
"weergavenaam": "Amstel 1, 1011PN Amsterdam",
"suggest": [
"Amstel 1, 1011PN Amsterdam",
"Amstel 1, 1011 PN Amsterdam",
],
"adrestype": "hoofdadres",
"straatnaam_verkort": "Amstel",
"id": "adr-9c02454e0f09cd9347aeb11cc03c9fb7",
"gekoppeld_perceel": ["ASD12-P-3514"],
"gemeentenaam": "Amsterdam",
"buurtcode": "BU0363AF09",
"wijknaam": "Nieuwmarkt/Lastage",
"identificatie": "0363010012143319-0363200012145295",
"openbareruimte_id": "0363300000002701",
"waterschapsnaam": "Waterschap Amstel, Gooi en Vecht",
"provinciecode": "PV27",
"postcode": "1011PN",
"provincienaam": "Noord-Holland",
"centroide_ll": "POINT(4.90016547 52.3676456)",
"geometrie_ll": "POINT(4.90016547 52.3676456)",
"nummeraanduiding_id": "0363200012145295",
"waterschapscode": "11",
"adresseerbaarobject_id": "0363010012143319",
"huisnummer": 1,
"provincieafkorting": "NH",
"geometrie_rd": "POINT(121828.874 486751.728)",
"centroide_rd": "POINT(121828.874 486751.728)",
"straatnaam": "Amstel",
"shards": "bag",
"_version_": 1816306460560195585,
"typesortering": 4.0,
"sortering": 1.0,
"shard": "bag",
}
],
}
}


Expand All @@ -84,7 +61,7 @@ def mock_get_bag_identificatie_and_stadsdeel_result_without_stadsdeel():
"_embedded": {
"adresseerbareobjecten": [
{
"huisnummer": 42,
"huisnummer": 1,
"identificatie": "123456789"
# No "gebiedenStadsdeelNaam" key
}
Expand All @@ -99,8 +76,9 @@ def mock_get_bag_identificatie_and_stadsdeel_result():
"adresseerbareobjecten": [
{
"identificatie": "123456789",
"huisnummer": 42,
"huisnummer": 1,
"gebiedenStadsdeelNaam": "Zuidoost",
"typeAdresseerbaarObjectOmschrijving": "verblijfsobject",
}
]
}
Expand Down
73 changes: 29 additions & 44 deletions app/apps/addresses/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@

from django.db import models
from utils.api_queries_bag import (
do_bag_search_benkagg_by_bag_id,
do_bag_search_by_bag_id,
do_bag_search_benkagg_by_id,
do_bag_search_pdok_by_bag_id,
)
from utils.coordinates import convert_polygon_to_latlng

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -80,44 +79,40 @@ def get_or_create_by_bag_id(bag_id):
return Address.objects.get_or_create(bag_id=bag_id)[0]

def get_bag_address_data(self):
bag_search_response = do_bag_search_by_bag_id(self.bag_id)
bag_search_results = bag_search_response.get("results", [])

bag_search_response = do_bag_search_pdok_by_bag_id(self.bag_id)
bag_search_results = bag_search_response.get("response", {}).get("docs", [])
if bag_search_results:
# A BAG search will return an array with 1 or more results.
# There could be a "Nevenadres" so check addresses for "Hoofdadres".

found_address = None
for address in bag_search_results:
if address.get("type_adres") == "Hoofdadres":
found_address = address
break # Found first desired object so break the loop.

found_bag_data = found_address or bag_search_results[0]

found_bag_data = bag_search_results[0]
self.postal_code = found_bag_data.get("postcode", "")
self.street_name = found_bag_data.get("straatnaam", "")
self.number = found_bag_data.get("huisnummer", "")
self.suffix_letter = found_bag_data.get("bag_huisletter", "")
self.suffix = found_bag_data.get("bag_toevoeging", "")
# Temporarily property for type. Could be verblijfsobject (huis) or standplaats (woonboot).
self.type = found_bag_data.get("type", "verblijfsobject")

centroid = found_bag_data.get("centroid", None)
self.suffix_letter = found_bag_data.get("huisletter", "")
self.suffix = found_bag_data.get("huisnummertoevoeging", "")
self.nummeraanduiding_id = found_bag_data.get("nummeraanduiding_id", "")
centroid_string = found_bag_data.get("centroide_ll", None)
centroid = self._parse_centroid(centroid_string)
if centroid:
self.lng = centroid[0]
self.lat = centroid[1]

def get_bag_identificatie_and_stadsdeel(self):
def _parse_centroid(self, centroid):
# Check if the string starts with 'POINT(' and ends with ')'
if centroid.startswith("POINT(") and centroid.endswith(")"):
# Remove the 'POINT(' at the beginning and ')' at the end
coordinates_str = centroid[6:-1]
# Split the string by space to get the individual numbers
coordinates = coordinates_str.split()
# Convert the string numbers to float and return as a list
return [float(coordinates[0]), float(coordinates[1])]
else:
raise ValueError("Input string is not in the correct format.")

def get_bag_type_and_stadsdeel(self):
"""
Retrieves the identificatie(nummeraanduiding_id) and stadsdeel of an address by bag_id.
nummeraanduiding_id is needed for BRP and stadsdeel is used for filtering.
If an address has an standplaats (woonboot) instead of verblijfsobject, the coordinates
will be calculated by a polygon.
Retrieves the stadsdeel and type of address by identificatie(nummeraanduiding_id).
"""

is_boat = self.type == "standplaats"
response = do_bag_search_benkagg_by_bag_id(self.bag_id, is_boat)
response = do_bag_search_benkagg_by_id(self.nummeraanduiding_id)

adresseerbareobjecten = response.get("_embedded", {}).get(
"adresseerbareobjecten", []
Expand All @@ -132,29 +127,19 @@ def get_bag_identificatie_and_stadsdeel(self):
),
{},
)

nummeraanduiding_id = found_bag_object.get("identificatie")
if nummeraanduiding_id:
self.nummeraanduiding_id = nummeraanduiding_id

# Temporarily property for type. Could be verblijfsobject (huis) or standplaats (woonboot).
# It's not used by now, but could be useful in the future.
self.type = found_bag_object.get("typeAdresseerbaarObjectOmschrijving")
district_name = found_bag_object.get("gebiedenStadsdeelNaam")

if district_name:
self.district = District.objects.get_or_create(name=district_name)[0]

# Get coordinates for standplaats (woonboot).
ligplaats_geometrie = found_bag_object.get("ligplaatsGeometrie") or {}
ligplaats_coordinates = ligplaats_geometrie.get("coordinates")
if ligplaats_coordinates:
(lat, lng) = convert_polygon_to_latlng(ligplaats_coordinates)
self.lng = lng
self.lat = lat

def update_bag_data(self):
self.get_bag_address_data()
# Prevent a nummeraanduiding_id error while creating a case.
try:
self.get_bag_identificatie_and_stadsdeel()
self.get_bag_type_and_stadsdeel()
except Exception as e:
logger.error(
f"Could not retrieve nummeraanduiding_id for bag_id:{self.bag_id}: {e}"
Expand Down
50 changes: 34 additions & 16 deletions app/apps/addresses/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,30 +21,30 @@ class Meta:
model = Address
fields = (
"bag_id",
"id",
"district",
"full_address",
"street_name",
"number",
"suffix_letter",
"suffix",
"postal_code",
"housing_corporation",
"id",
"lat",
"lng",
"full_address",
"district",
"housing_corporation",
"number",
"nummeraanduiding_id",
"postal_code",
"street_name",
"suffix",
"suffix_letter",
)
read_only_fields = (
"district",
"full_address",
"id",
"street_name",
"number",
"suffix_letter",
"suffix",
"postal_code",
"lat",
"lng",
"full_address",
"district",
"number",
"postal_code",
"street_name",
"suffix",
"suffix_letter",
)
extra_kwargs = {"bag_id": {"validators": []}}

Expand Down Expand Up @@ -110,9 +110,27 @@ class ResidentsSerializer(serializers.Serializer):
_embedded = serializers.DictField()


class GetResidentsSerializer(serializers.Serializer):
obo_access_token = serializers.DictField()


class MeldingenSerializer(serializers.Serializer):
pageNumber = serializers.IntegerField()
pageSize = serializers.IntegerField()
totalPages = serializers.IntegerField()
totalRecords = serializers.IntegerField()
data = serializers.ListField(child=serializers.DictField())


class RegistrationNumberSerializer(serializers.Serializer):
registrationNumber = serializers.CharField(required=True)


class RegistrationDetailsSerializer(serializers.Serializer):
registrationNumber = serializers.CharField(required=True)
requester = serializers.DictField()
rentalHouse = serializers.DictField()
requestForOther = serializers.BooleanField()
requestForBedAndBreakfast = serializers.BooleanField()
createdAt = serializers.DateTimeField()
agreementDate = serializers.DateTimeField()
Loading

0 comments on commit 32448d7

Please sign in to comment.