diff --git a/api/bro_import/bulk_import.py b/api/bro_import/bulk_import.py index 0378734..14a22a4 100644 --- a/api/bro_import/bulk_import.py +++ b/api/bro_import/bulk_import.py @@ -1,4 +1,4 @@ -import traceback +import logging import requests from django.conf import settings @@ -6,6 +6,8 @@ from api import models from api.bro_import import config +logger = logging.getLogger(__name__) + class FetchBROIDsError(Exception): """Custom exception for errors during BRO IDs fetching.""" @@ -43,7 +45,7 @@ def run(self) -> None: ) data_importer.run() except requests.RequestException as e: - traceback.print_exc() + logger.exception(e) raise DataImportError(f"Error fetching BRO IDs from {url}: {e}") from e def _create_bro_ids_import_url(self) -> str: diff --git a/api/bro_upload/config.py b/api/bro_upload/config.py deleted file mode 100644 index b1aeff2..0000000 --- a/api/bro_upload/config.py +++ /dev/null @@ -1,25 +0,0 @@ -from .xml_generators import gmn_generators - -# Mapping for the determination of which xml generator should be used for a given request_type -xml_generator_mapping = { - "GMN_StartRegistration": gmn_generators.GMNStartregistration, -} - - -# Declaration urls -brocom = "http://www.broservices.nl/xsd/brocommon/3.0" -gml = "http://www.opengis.net/gml/3.2" -xsi = "http://www.w3.org/2001/XMLSchema-instance" -gmn = "http://www.broservices.nl/xsd/isgmn/1.0" - -gmn_xsi_schemalocation = "http://www.broservices.nl/xsd/isgmn/1.0 https://schema.broservices.nl/xsd/isgmn/1.0/isgmn-messages.xsd" - -# Declaration configuration per request type -declaration_mapping = { - "GMN_StartRegistration": { - None: gmn, - "brocom": brocom, - "gml": gml, - "xsi": xsi, - }, -} diff --git a/api/bro_upload/delivery.py b/api/bro_upload/delivery.py index 943b877..488b153 100644 --- a/api/bro_upload/delivery.py +++ b/api/bro_upload/delivery.py @@ -1,8 +1,20 @@ +import logging import time -import traceback +from typing import Any + +from django.template.exceptions import TemplateDoesNotExist +from django.template.loader import render_to_string from .. import models as api_models -from . import config, utils +from . import utils + +logger = logging.getLogger(__name__) + + +class XMLGenerationError(Exception): + """Exception raised when XML generation fails.""" + + pass class XMLValidationError(Exception): @@ -41,9 +53,6 @@ def __init__( self.upload_task_instance = upload_task_instance self.bro_username = bro_username self.bro_password = bro_password - self.xml_generator_class = config.xml_generator_mapping.get( - self.upload_task_instance.registration_type - ) def process(self) -> None: # Generate the XML file. @@ -69,7 +78,7 @@ def process(self) -> None: def _generate_xml_file(self) -> str: try: - generator = self.xml_generator_class( + generator = XMLGenerator( self.upload_task_instance.registration_type, self.upload_task_instance.request_type, self.upload_task_instance.metadata, @@ -78,7 +87,7 @@ def _generate_xml_file(self) -> str: return generator.create_xml_file() except Exception as e: - traceback.print_exc() + logger.exception(e) raise RuntimeError(f"Error generating XML file: {e}") from e def _validate_xml_file(self, xml_file: str) -> None: @@ -123,23 +132,21 @@ def _deliver_xml_file(self, xml_file: str) -> str: return delivery_url - def _check_delivery(self, delivery_url: str) -> str | None: + def _check_delivery(self, delivery_url: str) -> bool: """Checks the delivery status.""" delivery_info = utils.check_delivery_status( delivery_url, self.bro_username, self.bro_password ) - errors = delivery_info.json()["brondocuments"][0]["errors"] + errors = delivery_info["brondocuments"][0]["errors"] if errors: raise DeliveryError(f"Errors found after delivering the XML file: {errors}") else: - delivery_status = delivery_info.json()["status"] - delivery_brondocument_status = delivery_info.json()["brondocuments"][0][ - "status" - ] + delivery_status = delivery_info["status"] + delivery_brondocument_status = delivery_info["brondocuments"][0]["status"] if ( delivery_status == "DOORGELEVERD" @@ -149,3 +156,40 @@ def _check_delivery(self, delivery_url: str) -> str | None: else: return False + + +class XMLGenerator: + """XML generator based on Django Templates.""" + + def __init__( + self, + registration_type: str, + request_type: str, + metadata: dict[str, Any], + sourcedocs_data: dict[str, Any], + ) -> None: + self.metadata = metadata + self.sourcedocs_data = sourcedocs_data + self.template_filepath = f"{request_type}_{registration_type}.html" + + def create_xml_file(self) -> str: + """Fills in the provided data into the templates""" + try: + rendered_xml = render_to_string( + self.template_filepath, + { + "metadata": self.metadata, + "sourcedocs_data": self.sourcedocs_data, + }, + ) + return rendered_xml + + except TemplateDoesNotExist as e: + logger.exception(e) + raise XMLGenerationError( + "De aangeleverde combinatie van request type en registratie type is niet mogelijk. Als de combinatie in de BRO wel mogelijk is, vraag dan deze combinatie aan bij Nelen & Schuurmans." + ) from e + + except Exception as e: + logger.exception(e) + raise XMLGenerationError(e) from e diff --git a/api/bro_upload/templates/delete_GMN_Closure.html b/api/bro_upload/templates/delete_GMN_Closure.html new file mode 100644 index 0000000..b876e57 --- /dev/null +++ b/api/bro_upload/templates/delete_GMN_Closure.html @@ -0,0 +1,17 @@ + + {{ metadata.requestReference }} + {{ metadata.deliveryAccountableParty }} + {{ metadata.broId }} + {{ metadata.qualityRegime }} + {{ metadata.correctionReason }} + + + + {{ sourcedocs_data.eventDate }} + + + + diff --git a/api/bro_upload/templates/delete_GMN_MeasuringPoint.html b/api/bro_upload/templates/delete_GMN_MeasuringPoint.html new file mode 100644 index 0000000..c902cc9 --- /dev/null +++ b/api/bro_upload/templates/delete_GMN_MeasuringPoint.html @@ -0,0 +1,28 @@ + + {{ metadata.requestReference }} + {{ metadata.deliveryAccountableParty }} + {{ metadata.broId }} + {{ metadata.qualityRegime }} + {{ metadata.correctionReason }} + + + + {{ sourcedocs_data.eventDate }} + + + + {{ sourcedocs_data.measuringPointCode }} + + + {{ sourcedocs_data.broId }} + {{ sourcedocs_data.tubeNumber }} + + + + + + + diff --git a/api/bro_upload/templates/delete_GMN_MeasuringPointEndDate.html b/api/bro_upload/templates/delete_GMN_MeasuringPointEndDate.html new file mode 100644 index 0000000..d6e4228 --- /dev/null +++ b/api/bro_upload/templates/delete_GMN_MeasuringPointEndDate.html @@ -0,0 +1,18 @@ + + {{ metadata.requestReference }} + {{ metadata.deliveryAccountableParty }} + {{ metadata.broId }} + {{ metadata.qualityRegime }} + {{ metadata.correctionReason }} + + + + {{ sourcedocs_data.eventDate }} + + {{ sourcedocs_data.measuringPointCode }} + + + diff --git a/api/bro_upload/templates/delete_GMN_TubeReference.html b/api/bro_upload/templates/delete_GMN_TubeReference.html new file mode 100644 index 0000000..ef2d6f7 --- /dev/null +++ b/api/bro_upload/templates/delete_GMN_TubeReference.html @@ -0,0 +1,28 @@ + + {{ metadata.requestReference }} + {{ metadata.deliveryAccountableParty }} + {{ metadata.broId }} + {{ metadata.qualityRegime }} + {{ metadata.correctionReason }} + + + + {{ sourcedocs_data.eventDate }} + + + + {{ sourcedocs_data.evemeasuringPointCodentDate }} + + + {{ sourcedocs_data.broId }} + {{ sourcedocs_data.tubeNumber }} + + + + + + + diff --git a/api/bro_upload/templates/insert_GMN_MeasuringPoint.html b/api/bro_upload/templates/insert_GMN_MeasuringPoint.html new file mode 100644 index 0000000..fa1b858 --- /dev/null +++ b/api/bro_upload/templates/insert_GMN_MeasuringPoint.html @@ -0,0 +1,28 @@ + + {{ metadata.requestReference }} + {{ metadata.deliveryAccountableParty }} + {{ metadata.broId }} + {{ metadata.qualityRegime }} + {{ metadata.correctionReason }} + + + + {{ sourcedocs_data.eventDate }} + + + + {{ sourcedocs_data.evenmeasuringPointCodetDate }} + + + {{ sourcedocs_data.broId }} + {{ sourcedocs_data.tubeNumber }} + + + + + + + diff --git a/api/bro_upload/templates/insert_GMN_TubeReference.html b/api/bro_upload/templates/insert_GMN_TubeReference.html new file mode 100644 index 0000000..a00c7ff --- /dev/null +++ b/api/bro_upload/templates/insert_GMN_TubeReference.html @@ -0,0 +1,28 @@ + + {{ metadata.requestReference }} + {{ metadata.deliveryAccountableParty }} + {{ metadata.broId }} + {{ metadata.qualityRegime }} + {{ metadata.correctionReason }} + + + + {{ sourcedocs_data.eventDate }} + + + + {{ sourcedocs_data.measuringPointCode }} + + + {{ sourcedocs_data.broId }} + {{ sourcedocs_data.tubeNumber }} + + + + + + + diff --git a/api/bro_upload/templates/move_GMN_Closure.html b/api/bro_upload/templates/move_GMN_Closure.html new file mode 100644 index 0000000..99df738 --- /dev/null +++ b/api/bro_upload/templates/move_GMN_Closure.html @@ -0,0 +1,20 @@ + + {{ metadata.requestReference }} + {{ metadata.deliveryAccountableParty }} + {{ metadata.broId }} + {{ metadata.qualityRegime }} + {{ metadata.correctionReason }} + + + + {{ sourcedocs_data.eventDate }} + + + + + {{ sourcedocs_data.dateToBeCorrected }} + + diff --git a/api/bro_upload/templates/move_GMN_MeasuringPoint.html b/api/bro_upload/templates/move_GMN_MeasuringPoint.html new file mode 100644 index 0000000..18ec00d --- /dev/null +++ b/api/bro_upload/templates/move_GMN_MeasuringPoint.html @@ -0,0 +1,31 @@ + + {{ metadata.requestReference }} + {{ metadata.deliveryAccountableParty }} + {{ metadata.broId }} + {{ metadata.qualityRegime }} + {{ metadata.correctionReason }} + + + + {{ sourcedocs_data.eventDate }} + + + + {{ sourcedocs_data.measuringPointCode }} + + + {{ sourcedocs_data.broId }} + {{ sourcedocs_data.tubeNumber }} + + + + + + + + {{ sourcedocs_data.dateToBeCorrected }} + + diff --git a/api/bro_upload/templates/move_GMN_MeasuringPointEndDate.html b/api/bro_upload/templates/move_GMN_MeasuringPointEndDate.html new file mode 100644 index 0000000..cf9e13c --- /dev/null +++ b/api/bro_upload/templates/move_GMN_MeasuringPointEndDate.html @@ -0,0 +1,21 @@ + + {{ metadata.requestReference }} + {{ metadata.deliveryAccountableParty }} + {{ metadata.broId }} + {{ metadata.qualityRegime }} + {{ metadata.correctionReason }} + + + + {{ sourcedocs_data.eventDate }} + + {{ sourcedocs_data.measuringPointCode }} + + + + {{ sourcedocs_data.dateToBeCorrected }} + + diff --git a/api/bro_upload/templates/move_GMN_StartRegistration.html b/api/bro_upload/templates/move_GMN_StartRegistration.html new file mode 100644 index 0000000..2f00c05 --- /dev/null +++ b/api/bro_upload/templates/move_GMN_StartRegistration.html @@ -0,0 +1,39 @@ +This XML file does not appear to have any style information associated with it. The document tree is shown below. + + {{ metadata.requestReference }} + {{ metadata.deliveryAccountableParty }} + {{ metadata.broId }} + {{ metadata.qualityRegime }} + {{ metadata.correctionReason }} + + + {{ sourcedocs_data.objectIdAccountableParty }} + {{ sourcedocs_data.name }} + {{ sourcedocs_data.deliveryContext }} + {{ sourcedocs_data.monitoringPurpose }} + {{ sourcedocs_data.groundwaterAspect }} + + {{ sourcedocs_data.startDateMonitoring }} + +{% for measuringpoint in sourcedocs_data.measuringPoints %} + + + {{ measuringpoint.measuringPointCode }} + + + {{ measuringpoint.broId }} + {{ measuringpoint.tubeNumber }} + + + + +{% endfor %} + + + + {{ sourcedocs_data.dateToBeCorrected }} + + diff --git a/api/bro_upload/templates/move_GMN_TubeReference.html b/api/bro_upload/templates/move_GMN_TubeReference.html new file mode 100644 index 0000000..1d8abef --- /dev/null +++ b/api/bro_upload/templates/move_GMN_TubeReference.html @@ -0,0 +1,31 @@ + + {{ metadata.requestReference }} + {{ metadata.deliveryAccountableParty }} + {{ metadata.broId }} + {{ metadata.qualityRegime }} + {{ metadata.correctionReason }} + + + + {{ sourcedocs_data.eventDate }} + + + + {{ sourcedocs_data.measuringPointCode }} + + + {{ sourcedocs_data.broId }} + {{ sourcedocs_data.tubeNumber }} + + + + + + + + {{ sourcedocs_data.dateToBeCorrected }} + + diff --git a/api/bro_upload/templates/registration_GMN_Closure.html b/api/bro_upload/templates/registration_GMN_Closure.html new file mode 100644 index 0000000..c9d038e --- /dev/null +++ b/api/bro_upload/templates/registration_GMN_Closure.html @@ -0,0 +1,16 @@ + + {{ metadata.requestReference }} + {{ metadata.deliveryAccountableParty }} + {{ metadata.broId }} + {{ metadata.qualityRegime }} + + + + {{ measuringpoint.endDateMonitoring }} + + + + diff --git a/api/bro_upload/templates/registration_GMN_MeasuringPoint.html b/api/bro_upload/templates/registration_GMN_MeasuringPoint.html new file mode 100644 index 0000000..2138f6d --- /dev/null +++ b/api/bro_upload/templates/registration_GMN_MeasuringPoint.html @@ -0,0 +1,27 @@ + + {{ metadata.requestReference }} + {{ metadata.deliveryAccountableParty }} + {{ metadata.broId }} + {{ metadata.qualityRegime }} + + + + {{ sourcedocs_data.eventDate }} + + + + {{ sourcedocs_data.measuringPointCode }} + + + {{ sourcedocs_data.broId }} + {{ sourcedocs_data.tubeNumber }} + + + + + + + diff --git a/api/bro_upload/templates/registration_GMN_MeasuringPointEndDate.html b/api/bro_upload/templates/registration_GMN_MeasuringPointEndDate.html new file mode 100644 index 0000000..90dca5c --- /dev/null +++ b/api/bro_upload/templates/registration_GMN_MeasuringPointEndDate.html @@ -0,0 +1,17 @@ + + {{ metadata.requestReference }} + {{ metadata.deliveryAccountableParty }} + {{ metadata.broId }} + {{ metadata.qualityRegime }} + + + + {{ measuringpoint.eventDate }} + + {{ measuringpoint.measuringPointCode }} + + + diff --git a/api/bro_upload/templates/registration_GMN_StartRegistration.html b/api/bro_upload/templates/registration_GMN_StartRegistration.html new file mode 100644 index 0000000..a0cdd5c --- /dev/null +++ b/api/bro_upload/templates/registration_GMN_StartRegistration.html @@ -0,0 +1,33 @@ + + {{ metadata.requestReference }} + {{ metadata.deliveryAccountableParty }} + {{ metadata.qualityRegime }} + + + {{ sourcedocs_data.objectIdAccountableParty }} + {{ sourcedocs_data.name }} + {{ sourcedocs_data.deliveryContext }} + {{ sourcedocs_data.monitoringPurpose }} + {{ sourcedocs_data.groundwaterAspect }} + + {{ sourcedocs_data.startDateMonitoring }} + +{% for measuringpoint in sourcedocs_data.measuringPoints %} + + + {{ measuringpoint.measuringPointCode }} + + + {{ measuringpoint.broId }} + {{ measuringpoint.tubeNumber }} + + + + +{% endfor %} + + + diff --git a/api/bro_upload/templates/registration_GMN_TubeReference.html b/api/bro_upload/templates/registration_GMN_TubeReference.html new file mode 100644 index 0000000..20de05d --- /dev/null +++ b/api/bro_upload/templates/registration_GMN_TubeReference.html @@ -0,0 +1,27 @@ + + {{ metadata.requestReference }} + {{ metadata.deliveryAccountableParty }} + {{ metadata.broId }} + {{ metadata.qualityRegime }} + + + + {{ sourcedocs_data.eventDate }} + + + + {{ sourcedocs_data.measuringPointCode }} + + + {{ sourcedocs_data.broId }} + {{ sourcedocs_data.tubeNumber }} + + + + + + + diff --git a/api/bro_upload/templates/replace_GMN_MeasuringPoint.html b/api/bro_upload/templates/replace_GMN_MeasuringPoint.html new file mode 100644 index 0000000..21bbb3a --- /dev/null +++ b/api/bro_upload/templates/replace_GMN_MeasuringPoint.html @@ -0,0 +1,28 @@ + + {{ metadata.requestReference }} + {{ metadata.deliveryAccountableParty }} + {{ metadata.broId }} + {{ metadata.qualityRegime }} + {{ metadata.correctionReason }} + + + + {{ sourcedocs_data.eventDate }} + + + + {{ sourcedocs_data.measuringPointCode }} + + + {{ sourcedocs_data.broId }} + {{ sourcedocs_data.tubeNumber }} + + + + + + + diff --git a/api/bro_upload/templates/replace_GMN_StartRegistration.html b/api/bro_upload/templates/replace_GMN_StartRegistration.html new file mode 100644 index 0000000..68c50be --- /dev/null +++ b/api/bro_upload/templates/replace_GMN_StartRegistration.html @@ -0,0 +1,35 @@ + + {{ metadata.requestReference }} + {{ metadata.deliveryAccountableParty }} + {{ metadata.broId }} + {{ metadata.qualityRegime }}/A + {{ metadata.correctionReason }} + + + {{ sourcedocs_data.objectIdAccountableParty }} + {{ sourcedocs_data.name }} + {{ sourcedocs_data.deliveryContext }} + {{ sourcedocs_data.monitoringPurpose }} + {{ sourcedocs_data.groundwaterAspect }} + + {{ sourcedocs_data.startDateMonitoring }} + +{% for measuringpoint in sourcedocs_data.measuringPoints %} + + + {{ measuringpoint.measuringPointCode }} + + + {{ measuringpoint.broId }} + {{ measuringpoint.tubeNumber }} + + + + +{% endfor %} + + + diff --git a/api/bro_upload/templates/replace_GMN_TubeReference.html b/api/bro_upload/templates/replace_GMN_TubeReference.html new file mode 100644 index 0000000..366f9b2 --- /dev/null +++ b/api/bro_upload/templates/replace_GMN_TubeReference.html @@ -0,0 +1,28 @@ + + {{ metadata.requestReference }} + {{ metadata.deliveryAccountableParty }} + {{ metadata.broId }} + {{ metadata.qualityRegime }} + {{ metadata.correctionReason }} + + + + {{ sourcedocs_data.eventDate }} + + + + {{ sourcedocs_data.measuringPointCode }} + + + {{ sourcedocs_data.broId }} + {{ sourcedocs_data.tubeNumber }} + + + + + + + diff --git a/api/bro_upload/utils.py b/api/bro_upload/utils.py index 4685a91..f077a35 100644 --- a/api/bro_upload/utils.py +++ b/api/bro_upload/utils.py @@ -1,10 +1,12 @@ import json -import traceback +import logging from typing import Any import requests from django.conf import settings +logger = logging.getLogger(__name__) + def validate_xml_file( xml_file: bytes, bro_username: str, bro_password: str, project_number: str @@ -24,7 +26,7 @@ def validate_xml_file( return r.json() except requests.RequestException as e: - traceback.print_exc() + logger.exception(e) raise RuntimeError(f"Validate xml error: {e}") @@ -44,7 +46,7 @@ def create_upload_url(bro_username: str, bro_password: str, project_number: str) return upload_url except requests.RequestException as e: - traceback.print_exc() + logger.exception(e) raise RuntimeError(f"Create upload url error: {e}") @@ -70,7 +72,7 @@ def add_xml_to_upload( return r.headers["Location"] except requests.RequestException as e: - traceback.print_exc() + logger.exception(e) raise RuntimeError(f"Add XML to upload error: {e}") @@ -98,13 +100,13 @@ def create_delivery( return r.headers["Location"] except requests.RequestException as e: - traceback.print_exc() + logger.exception(e) raise RuntimeError(f"Deliver uploaded XML error: {e}") def check_delivery_status( delivery_url: str, bro_username: str, bro_password: str -) -> str: +) -> dict[str, Any]: """Checks the Delivery info. Step 4 of 4 in the upload process.""" try: r = requests.get( @@ -112,8 +114,8 @@ def check_delivery_status( auth=(bro_username, bro_password), ) - return r + return r.json() except requests.RequestException as e: - traceback.print_exc() + logger.exception(e) raise RuntimeError(f"Delivery info check error: {e}") diff --git a/api/bro_upload/xml_generators/base_generator.py b/api/bro_upload/xml_generators/base_generator.py deleted file mode 100644 index 0bbb630..0000000 --- a/api/bro_upload/xml_generators/base_generator.py +++ /dev/null @@ -1,82 +0,0 @@ -from abc import ABC, abstractmethod -from typing import Any - -from lxml import etree -from lxml.etree import tostring - -from .. import config - - -class XMLGenerator(ABC): - """Handles the creation of the XML files. - - This baseclass is inherited by the XML Generators per request type. - Only the _create_sourcedocument varies per request type. - - Returns: - XML in str format - """ - - def __init__( - self, - registration_type: str, - request_type: str, - metadata: dict[str, Any], - sourcedocs_data: dict[str, Any], - ) -> None: - self.registration_type = registration_type - self.request_type = request_type - self.metadata = metadata - self.sourcedocs_data = sourcedocs_data - self.namespace = None - self.xsi_schema_location = None - self.xml_tree = None - - def create_xml_file(self) -> str: - """Generates the XML file, based on the provided request_type, metadata and sourcedocs_data""" - self._setup_xml_tree() - self._add_metadata() - - self.source_document = etree.Element("sourceDocument") - self._create_sourcedocument() - self.xml_tree.append(self.source_document) - - xml_file = etree.ElementTree(self.xml_tree) - xml_string = tostring(xml_file, encoding="utf-8", method="xml") - - return xml_string - - def _setup_xml_tree(self) -> None: - """Sets up the basis of the XML File, consisting of the declaration urls.""" - self.xml_tree = etree.Element( - f"{self.request_type}Request", - nsmap=self.namespace, - ) - - if self.xsi_schema_location: - self.xml_tree.set( - "{http://www.w3.org/2001/XMLSchema-instance}schemaLocation", - self.xsi_schema_location, - ) - - def _add_metadata(self): - """Fills in the metadata (all information between the declaration sourcedocs.""" - - metadata_options = [ - "requestReference", - "deliveryAccountableParty", - "broId", - "qualityRegime", - ] - for metadata_field in metadata_options: - if metadata_field in self.metadata.keys(): - metadata_element = etree.SubElement( - self.xml_tree, - f"{{{config.brocom}}}{metadata_field}", - ) - metadata_element.text = self.metadata[metadata_field] - - @abstractmethod - def _create_sourcedocument(self): - """Creates the sourcedocs XML structure.""" - pass diff --git a/api/bro_upload/xml_generators/frd_generators.py b/api/bro_upload/xml_generators/frd_generators.py deleted file mode 100644 index bbb0296..0000000 --- a/api/bro_upload/xml_generators/frd_generators.py +++ /dev/null @@ -1,7 +0,0 @@ -from .base_generator import XMLGenerator - - -class FRDStartregistration(XMLGenerator): - """Generates a XML file for the 10_FRD_StartRegistration.xml""" - - pass diff --git a/api/bro_upload/xml_generators/gld_generators.py b/api/bro_upload/xml_generators/gld_generators.py deleted file mode 100644 index cb57cf4..0000000 --- a/api/bro_upload/xml_generators/gld_generators.py +++ /dev/null @@ -1,7 +0,0 @@ -from .base_generator import XMLGenerator - - -class GLDStartregistration(XMLGenerator): - """Generates a XML file for the 10_GLD_StartRegistration.xml.""" - - pass diff --git a/api/bro_upload/xml_generators/gmn_generators.py b/api/bro_upload/xml_generators/gmn_generators.py deleted file mode 100644 index 100b87c..0000000 --- a/api/bro_upload/xml_generators/gmn_generators.py +++ /dev/null @@ -1,148 +0,0 @@ -from lxml import etree - -from .. import config -from .base_generator import XMLGenerator - - -class GMNStartregistration(XMLGenerator): - """Generates a XML file for the 01_GMN_StartRegistration.""" - - def __init__( - self, - registration_type: str, - request_type: str, - metadata: dict, - srcdocdata: dict, - ) -> None: - super().__init__(registration_type, request_type, metadata, srcdocdata) - self.namespace = config.declaration_mapping[self.registration_type] - self.xsi_schema_location = config.gmn_xsi_schemalocation - self.id_count = 1 - - def _create_sourcedocument(self): - """Example XML for register: - https://www.bro-productomgeving.nl/__attachments/159095997/01_GMN_StartRegistration.xml?inst-v=6362ee09-a77d-4052-8ab8-caf3a373ad16 - """ - # Create main sourcedocs element - main_element = etree.Element(f"{{{config.gmn}}}GMN_StartRegistration") - main_element.set(f"{{{config.gml}}}id", f"id_000{self.id_count}") - self.id_count += 1 - - # Create object id accountable party element - object_id_accountable_party_element = etree.SubElement( - main_element, - "objectIdAccountableParty", - ) - object_id_accountable_party_element.text = self.sourcedocs_data[ - "objectIdAccountableParty" - ] - - # Create name element - name_element = etree.SubElement( - main_element, - "name", - ) - name_element.text = self.sourcedocs_data["name"] - - # Create delivery context element - delivery_context_element = etree.SubElement( - main_element, - "deliveryContext", - attrib={"codeSpace": "urn:bro:gmn:DeliveryContext"}, - ) - delivery_context_element.text = self.sourcedocs_data["deliveryContext"] - - # Create monitoring purpose element - monitoring_purpose_element = etree.SubElement( - main_element, - "monitoringPurpose", - attrib={"codeSpace": "urn:bro:gmn:MonitoringPurpose"}, - ) - monitoring_purpose_element.text = self.sourcedocs_data["monitoringPurpose"] - - # Create groundwater aspect element - groundwater_aspect_element = etree.SubElement( - main_element, - "groundwaterAspect", - attrib={"codeSpace": "urn:bro:gmn:GroundwaterAspect"}, - ) - groundwater_aspect_element.text = self.sourcedocs_data["groundwaterAspect"] - - # Create startdate monitoring element - startdate_monitoring_element = etree.SubElement( - main_element, - "startDateMonitoring", - ) - - startdate_date_element = etree.SubElement( - startdate_monitoring_element, - f"{{{config.brocom}}}date", - ) - startdate_date_element.text = self.sourcedocs_data["startDateMonitoring"] - - # Add measuringpoints - for measuringpoint in self.sourcedocs_data["measuringPoints"]: - # Main element - measuringpoint_main_element = etree.SubElement( - main_element, - "measuringPoint", - ) - - # Sub element - measuringpoint_sub_element = etree.SubElement( - measuringpoint_main_element, - "MeasuringPoint", - ) - measuringpoint_sub_element.set( - f"{{{config.gml}}}id", f"id_000{self.id_count}" - ) - self.id_count += 1 - - measuringpoint_code_element = etree.SubElement( - measuringpoint_sub_element, - "measuringPointCode", - ) - measuringpoint_code_element.text = measuringpoint["measuringPointCode"] - - # monitoringTube element - monitoring_tube_element = etree.SubElement( - measuringpoint_sub_element, - "monitoringTube", - ) - - # GroundwaterMonitoringTube element - groundwater_monitoring_tube_element = etree.SubElement( - monitoring_tube_element, - "GroundwaterMonitoringTube", - ) - groundwater_monitoring_tube_element.set( - f"{{{config.gml}}}id", f"id_000{self.id_count}" - ) - self.id_count += 1 - - bro_id_element = etree.SubElement( - groundwater_monitoring_tube_element, - "broId", - ) - bro_id_element.text = measuringpoint["broId"] - - tube_number_element = etree.SubElement( - groundwater_monitoring_tube_element, - "tubeNumber", - ) - tube_number_element.text = measuringpoint["tubeNumber"] - - # Add startregistration to sourcedocs - self.source_document.append(main_element) - - -class GMNMeasuringPoint(XMLGenerator): - """Generates a XML file for the 02_GMN_MeasuringPoint.xml.""" - - pass - - -class GMNTubeReference(XMLGenerator): - """Generates a XML file for the 03_GMN_TubeReference.xml.""" - - pass diff --git a/api/bro_upload/xml_generators/gmw_generators.py b/api/bro_upload/xml_generators/gmw_generators.py deleted file mode 100644 index 75d36b2..0000000 --- a/api/bro_upload/xml_generators/gmw_generators.py +++ /dev/null @@ -1,7 +0,0 @@ -from .base_generator import XMLGenerator - - -class GMWStartregistration(XMLGenerator): - """Generates a XML file for the registrationRequestGMW.xml.""" - - pass diff --git a/api/choices.py b/api/choices.py index 7cff7e5..6036a33 100644 --- a/api/choices.py +++ b/api/choices.py @@ -14,6 +14,10 @@ REGISTRATION_TYPE_OPTIONS = [ ("GMN_StartRegistration", "GMN_StartRegistration"), + ("GMN_MeasuringPoint", "GMN_MeasuringPoint"), + ("GMN_MeasuringPointEndDate", "GMN_MeasuringPointEndDate"), + ("GMN_TubeReference", "GMN_TubeReference"), + ("GMN_Closure", "GMN_Closure"), ] REQUEST_TYPE_OPTIONS = [ diff --git a/api/migrations/0021_remove_userprofile_default_project_number_and_more.py b/api/migrations/0021_remove_userprofile_default_project_number_and_more.py new file mode 100644 index 0000000..fd7de80 --- /dev/null +++ b/api/migrations/0021_remove_userprofile_default_project_number_and_more.py @@ -0,0 +1,21 @@ +# Generated by Django 5.0.1 on 2024-03-14 12:18 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("api", "0020_remove_userprofile_bro_user_password_and_more"), + ] + + operations = [ + migrations.RemoveField( + model_name="userprofile", + name="default_project_number", + ), + migrations.AlterField( + model_name="uploadtask", + name="project_number", + field=models.CharField(max_length=20), + ), + ] diff --git a/api/migrations/0022_alter_uploadtask_registration_type.py b/api/migrations/0022_alter_uploadtask_registration_type.py new file mode 100644 index 0000000..61078ef --- /dev/null +++ b/api/migrations/0022_alter_uploadtask_registration_type.py @@ -0,0 +1,26 @@ +# Generated by Django 5.0.1 on 2024-03-14 19:13 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("api", "0021_remove_userprofile_default_project_number_and_more"), + ] + + operations = [ + migrations.AlterField( + model_name="uploadtask", + name="registration_type", + field=models.CharField( + choices=[ + ("GMN_StartRegistration", "GMN_StartRegistration"), + ("GMN_MeasuringPoint", "GMN_MeasuringPoint"), + ("GMN_MeasuringPointEndDate", "GMN_MeasuringPointEndDate"), + ("GMN_TubeReference", "GMN_TubeReference"), + ("GMN_Closure", "GMN_Closure"), + ], + max_length=235, + ), + ), + ] diff --git a/api/models.py b/api/models.py index e1e2273..b24e55a 100644 --- a/api/models.py +++ b/api/models.py @@ -32,8 +32,6 @@ class UserProfile(models.Model): created = models.DateTimeField(auto_now_add=True) updated = models.DateTimeField(auto_now=True) - default_project_number = models.CharField(max_length=20, blank=True, null=True) - def __str__(self): return self.user.username @@ -55,7 +53,7 @@ class ImportTask(models.Model): log = models.TextField(blank=True) def __str__(self): - return f"{self.bro_domain} import - {self.data_owner} ({self.created})" + return f"{self.bro_domain} import - {self.data_owner}" class UploadTask(models.Model): @@ -68,7 +66,7 @@ class UploadTask(models.Model): bro_domain = models.CharField( max_length=3, choices=choices.BRO_DOMAIN_CHOICES, default=None ) - project_number = models.CharField(max_length=20, blank=True, null=True) + project_number = models.CharField(max_length=20, blank=False) registration_type = models.CharField( blank=False, max_length=235, choices=choices.REGISTRATION_TYPE_OPTIONS ) @@ -81,4 +79,4 @@ class UploadTask(models.Model): log = models.TextField(blank=True) def __str__(self) -> str: - return f"{self.request_type} {self.registration_type} {self.created}" + return f"{self.data_owner}: {self.registration_type} ({self.request_type})" diff --git a/api/tests/test_bro_upload.py b/api/tests/test_bro_upload.py new file mode 100644 index 0000000..80f9675 --- /dev/null +++ b/api/tests/test_bro_upload.py @@ -0,0 +1,98 @@ +import pytest + +from api.bro_upload import delivery + +expected_xml_str = """ + test + 27376655 + IMBRO/A + + + test + test + kaderrichtlijnWater + strategischBeheerKwaliteitRegionaal + kwantiteit + + 2024-01-01 + + + + + GMW000000038946 + + + GMW000000038946 + 1 + + + + + + + + GMW000000038946 + + + GMW000000038946 + 2 + + + + + + + + +""" + + +def test_xml_generator1(): + generator = delivery.XMLGenerator( + registration_type="GMN_StartRegistration", + request_type="registration", + metadata={ + "requestReference": "test", + "deliveryAccountableParty": "27376655", + "qualityRegime": "IMBRO/A", + }, + sourcedocs_data={ + "objectIdAccountableParty": "test", + "name": "test", + "deliveryContext": "kaderrichtlijnWater", + "monitoringPurpose": "strategischBeheerKwaliteitRegionaal", + "groundwaterAspect": "kwantiteit", + "startDateMonitoring": "2024-01-01", + "measuringPoints": [ + { + "measuringPointCode": "GMW000000038946", + "broId": "GMW000000038946", + "tubeNumber": "1", + }, + { + "measuringPointCode": "GMW000000038946", + "broId": "GMW000000038946", + "tubeNumber": "2", + }, + ], + }, + ) + + print(generator.create_xml_file()) + + assert generator.create_xml_file() == expected_xml_str + + +def test_xml_generator2(): + """Tests a non existing combination of registration_type and request type.""" + with pytest.raises(delivery.XMLGenerationError): + generator = delivery.XMLGenerator( + registration_type="GMN_StartRegistration", + request_type="insert", + metadata={}, + sourcedocs_data={}, + ) + generator.create_xml_file() diff --git a/api/tests/test_models.py b/api/tests/test_models.py index f03c1a5..68fd07b 100644 --- a/api/tests/test_models.py +++ b/api/tests/test_models.py @@ -1,6 +1,76 @@ +import pytest + from api import models as api_models +from gmn import models as gmn_models +from gmw import models as gmw_models + + +@pytest.fixture +def organisation(): + return api_models.Organisation(name="Nieuwegein") -def test_organisation1(): - organisation = api_models.Organisation(name="Nieuwegein") +def test_organisation_name(organisation): assert str(organisation) == "Nieuwegein" + + +def test_import_task_name(organisation): + import_task = api_models.ImportTask( + bro_domain="GMN", + kvk_number="123456789", + data_owner=organisation, + ) + + assert str(import_task) == "GMN import - Nieuwegein" + + +def test_upload_task_name(organisation): + upload_task = api_models.UploadTask( + bro_domain="GMN", + data_owner=organisation, + project_number="1", + registration_type="GMN_StartRegistration", + request_type="registration", + ) + + assert str(upload_task) == "Nieuwegein: GMN_StartRegistration (registration)" + + +@pytest.fixture +def gmn(organisation): + return gmn_models.GMN( + data_owner=organisation, + bro_id="GMN123456789", + ) + + +def test_gmn_name(gmn): + assert str(gmn) == "GMN123456789" + + +def test_measuringpoint_name(organisation, gmn): + measuringpoint = gmn_models.Measuringpoint( + data_owner=organisation, gmn=gmn, measuringpoint_code="MP1234" + ) + + assert str(measuringpoint) == "MP1234" + + +@pytest.fixture +def gmw(organisation): + return gmw_models.GMW( + data_owner=organisation, + bro_id="GMW123456789", + ) + + +def test_gmw_name(gmw): + assert str(gmw) == "GMW123456789" + + +def test_monitoringtube_name(organisation, gmw): + monitoring_tube = gmw_models.MonitoringTube( + data_owner=organisation, gmw=gmw, tube_number="1" + ) + + assert str(monitoring_tube) == "GMW123456789-1" diff --git a/api/views.py b/api/views.py index b3826a4..3e913b7 100644 --- a/api/views.py +++ b/api/views.py @@ -70,27 +70,6 @@ class UserProfileDetailView(generics.RetrieveUpdateAPIView): lookup_field = "uuid" permission_classes = [permissions.IsAuthenticated] - # update makes sure only project number, token and password can be changed - def update(self, request, *args, **kwargs): - partial = kwargs.pop("partial", False) - instance = self.get_object() - - data = request.data - allowed_fields = { - "default_project_number", - } - for key in data.keys(): - if key not in allowed_fields: - return Response( - {"error": f"Cannot update field {key}"}, - status=status.HTTP_400_BAD_REQUEST, - ) - - serializer = self.get_serializer(instance, data=request.data, partial=partial) - serializer.is_valid(raise_exception=True) - self.perform_update(serializer) - return Response(serializer.data) - class ImportTaskListView(mixins.UserOrganizationMixin, generics.ListAPIView): """ @@ -244,10 +223,6 @@ def post(self, request): # Update the instance of the new task upload_task_instance.status = "PENDING" upload_task_instance.data_owner = data_owner - upload_task_instance.project_number = ( - upload_task_instance.project_number - or user_profile.default_project_number - ) upload_task_instance.save() if not upload_task_instance.project_number: diff --git a/bro_hub/settings.py b/bro_hub/settings.py index e269e00..32da55f 100644 --- a/bro_hub/settings.py +++ b/bro_hub/settings.py @@ -60,7 +60,7 @@ TEMPLATES = [ { "BACKEND": "django.template.backends.django.DjangoTemplates", - "DIRS": [], + "DIRS": [os.path.join(BASE_DIR, "api", "bro_upload", "templates")], "APP_DIRS": True, "OPTIONS": { "context_processors": [ @@ -146,7 +146,7 @@ # Automatically discover tasks in Django app CELERY_IMPORTS = ("api.tasks",) # TODO: fix celery env settings -CELERY_BROKER_URL = "redis://localhost:6379/0" +CELERY_BROKER_URL = "redis://redis:6379/0" # BRO SETTINGS BRO_UITGIFTE_SERVICE_URL = "https://publiek.broservices.nl" diff --git a/docker-compose.yml b/docker-compose.yml index e7a7ab9..0a14ee7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,6 +12,25 @@ services: - pgdata:/var/lib/postgresql/data restart: unless-stopped + redis: + image: redis:latest + expose: + - 6379 + + celery: + environment: + - DJANGO_SETTINGS_MODULE=bro_hub.settings + - FIELD_ENCRYPTION_KEY="DUMMY-NEEDS-PROD-SETTING-Xgb1GczqZe909UMNc4= + build: . + command: celery -A bro_hub worker --loglevel=INFO + volumes: + - .:/code + links: + - redis + depends_on: + - db + - redis + web: build: . # command: "bin/gunicorn -b 0.0.0.0:${PORT:-5000} --workers=3 --timeout 90 --preload --max-requests=10000 trs.wsgi" @@ -32,6 +51,12 @@ services: # - NENS_AUTH_ISSUER # - NENS_AUTH_CLIENT_ID # - NENS_AUTH_CLIENT_SECRET + depends_on: + - db + - redis + - celery + + volumes: pgdata: diff --git a/gmn/migrations/0015_alter_gmn_delivery_accountable_party_and_more.py b/gmn/migrations/0015_alter_gmn_delivery_accountable_party_and_more.py new file mode 100644 index 0000000..9093762 --- /dev/null +++ b/gmn/migrations/0015_alter_gmn_delivery_accountable_party_and_more.py @@ -0,0 +1,82 @@ +# Generated by Django 5.0.1 on 2024-03-14 19:39 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("gmn", "0014_alter_gmn_data_owner_and_more"), + ] + + operations = [ + migrations.AlterField( + model_name="gmn", + name="delivery_accountable_party", + field=models.CharField(max_length=8, null=True), + ), + migrations.AlterField( + model_name="gmn", + name="delivery_context", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="gmn", + name="groundwater_aspect", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="gmn", + name="monitoring_purpose", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="gmn", + name="name", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="gmn", + name="object_registration_time", + field=models.DateTimeField(null=True), + ), + migrations.AlterField( + model_name="gmn", + name="quality_regime", + field=models.CharField(max_length=50, null=True), + ), + migrations.AlterField( + model_name="gmn", + name="registration_status", + field=models.CharField(max_length=50, null=True), + ), + migrations.AlterField( + model_name="gmn", + name="start_date_monitoring", + field=models.DateField(null=True), + ), + migrations.AlterField( + model_name="measuringpoint", + name="gmw_bro_id", + field=models.CharField(max_length=50, null=True), + ), + migrations.AlterField( + model_name="measuringpoint", + name="measuringpoint_code", + field=models.CharField(max_length=50, null=True), + ), + migrations.AlterField( + model_name="measuringpoint", + name="measuringpoint_start_date", + field=models.DateField(null=True), + ), + migrations.AlterField( + model_name="measuringpoint", + name="tube_number", + field=models.CharField(max_length=50, null=True), + ), + migrations.AlterField( + model_name="measuringpoint", + name="tube_start_date", + field=models.DateField(null=True), + ), + ] diff --git a/gmn/models.py b/gmn/models.py index 3f823ac..8a4f015 100644 --- a/gmn/models.py +++ b/gmn/models.py @@ -16,15 +16,15 @@ class GMN(models.Model): updated_at = models.DateTimeField(auto_now=True) data_owner = models.ForeignKey(Organisation, on_delete=models.CASCADE) bro_id = models.CharField(max_length=18) - delivery_accountable_party = models.CharField(max_length=8) - quality_regime = models.CharField(max_length=50) - name = models.CharField(max_length=100) - delivery_context = models.CharField(max_length=100) - monitoring_purpose = models.CharField(max_length=100) - groundwater_aspect = models.CharField(max_length=100) - start_date_monitoring = models.DateField() - object_registration_time = models.DateTimeField() - registration_status = models.CharField(max_length=50) + delivery_accountable_party = models.CharField(max_length=8, null=True) + quality_regime = models.CharField(max_length=50, null=True) + name = models.CharField(max_length=100, null=True) + delivery_context = models.CharField(max_length=100, null=True) + monitoring_purpose = models.CharField(max_length=100, null=True) + groundwater_aspect = models.CharField(max_length=100, null=True) + start_date_monitoring = models.DateField(null=True) + object_registration_time = models.DateTimeField(null=True) + registration_status = models.CharField(max_length=50, null=True) def __str__(self): return self.bro_id @@ -46,11 +46,11 @@ class Measuringpoint(models.Model): updated_at = models.DateTimeField(auto_now=True) data_owner = models.ForeignKey(Organisation, on_delete=models.CASCADE) gmn = models.ForeignKey(GMN, on_delete=models.CASCADE) - measuringpoint_code = models.CharField(max_length=50) - measuringpoint_start_date = models.DateField() - gmw_bro_id = models.CharField(max_length=50) - tube_number = models.CharField(max_length=50) - tube_start_date = models.DateField() + measuringpoint_code = models.CharField(max_length=50, null=True) + measuringpoint_start_date = models.DateField(null=True) + gmw_bro_id = models.CharField(max_length=50, null=True) + tube_number = models.CharField(max_length=50, null=True) + tube_start_date = models.DateField(null=True) def __str__(self): return self.measuringpoint_code diff --git a/gmw/migrations/0008_alter_monitoringtube_tube_top_diameter.py b/gmw/migrations/0008_alter_monitoringtube_tube_top_diameter.py new file mode 100644 index 0000000..c81c477 --- /dev/null +++ b/gmw/migrations/0008_alter_monitoringtube_tube_top_diameter.py @@ -0,0 +1,17 @@ +# Generated by Django 5.0.1 on 2024-03-14 19:13 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("gmw", "0007_alter_gmw_construction_standard_alter_gmw_data_owner_and_more"), + ] + + operations = [ + migrations.AlterField( + model_name="monitoringtube", + name="tube_top_diameter", + field=models.CharField(max_length=100, null=True), + ), + ] diff --git a/gmw/migrations/0009_alter_gmw_well_stability.py b/gmw/migrations/0009_alter_gmw_well_stability.py new file mode 100644 index 0000000..b275f1f --- /dev/null +++ b/gmw/migrations/0009_alter_gmw_well_stability.py @@ -0,0 +1,17 @@ +# Generated by Django 5.0.1 on 2024-03-14 19:22 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("gmw", "0008_alter_monitoringtube_tube_top_diameter"), + ] + + operations = [ + migrations.AlterField( + model_name="gmw", + name="well_stability", + field=models.CharField(max_length=100, null=True), + ), + ] diff --git a/gmw/migrations/0010_alter_gmw_construction_standard_and_more.py b/gmw/migrations/0010_alter_gmw_construction_standard_and_more.py new file mode 100644 index 0000000..4364ea6 --- /dev/null +++ b/gmw/migrations/0010_alter_gmw_construction_standard_and_more.py @@ -0,0 +1,207 @@ +# Generated by Django 5.0.1 on 2024-03-14 19:39 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("gmw", "0009_alter_gmw_well_stability"), + ] + + operations = [ + migrations.AlterField( + model_name="gmw", + name="construction_standard", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="gmw", + name="delivered_location", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="gmw", + name="delivery_accountable_party", + field=models.CharField(max_length=8, null=True), + ), + migrations.AlterField( + model_name="gmw", + name="delivery_context", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="gmw", + name="ground_level_position", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="gmw", + name="ground_level_positioning_method", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="gmw", + name="ground_level_stable", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="gmw", + name="initial_function", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="gmw", + name="local_vertical_reference_point", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="gmw", + name="nitg_code", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="gmw", + name="object_registration_time", + field=models.DateTimeField(null=True), + ), + migrations.AlterField( + model_name="gmw", + name="offset", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="gmw", + name="owner", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="gmw", + name="quality_regime", + field=models.CharField(max_length=50, null=True), + ), + migrations.AlterField( + model_name="gmw", + name="registration_status", + field=models.CharField(max_length=50, null=True), + ), + migrations.AlterField( + model_name="gmw", + name="removed", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="gmw", + name="standardized_location", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="gmw", + name="vertical_datum", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="gmw", + name="well_code", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="gmw", + name="well_head_protector", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="monitoringtube", + name="artesian_well_cap_present", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="monitoringtube", + name="glue", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="monitoringtube", + name="number_of_geo_ohm_cables", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="monitoringtube", + name="plain_tube_part_length", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="monitoringtube", + name="screen_bottom_position", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="monitoringtube", + name="screen_length", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="monitoringtube", + name="screen_top_position", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="monitoringtube", + name="sediment_sump_present", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="monitoringtube", + name="sock_material", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="monitoringtube", + name="tube_in_use", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="monitoringtube", + name="tube_material", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="monitoringtube", + name="tube_number", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="monitoringtube", + name="tube_packing_material", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="monitoringtube", + name="tube_part_inserted", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="monitoringtube", + name="tube_status", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="monitoringtube", + name="tube_top_position", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="monitoringtube", + name="tube_top_positioning_method", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="monitoringtube", + name="tube_type", + field=models.CharField(max_length=100, null=True), + ), + migrations.AlterField( + model_name="monitoringtube", + name="variable_diameter", + field=models.CharField(max_length=100, null=True), + ), + ] diff --git a/gmw/models.py b/gmw/models.py index f13e6fc..2196c06 100644 --- a/gmw/models.py +++ b/gmw/models.py @@ -19,31 +19,27 @@ class GMW(models.Model): on_delete=models.CASCADE, ) bro_id = models.CharField(max_length=18) - delivery_accountable_party = models.CharField(max_length=8) - quality_regime = models.CharField(max_length=50) - delivery_context = models.CharField(max_length=100) - construction_standard = models.CharField(max_length=100) - initial_function = models.CharField(max_length=100) - removed = models.CharField(max_length=100) - ground_level_stable = models.CharField(max_length=100) - well_stability = models.CharField(max_length=100) - nitg_code = models.CharField(max_length=100) - well_code = models.CharField(max_length=100) - owner = models.CharField(max_length=100) - well_head_protector = models.CharField(max_length=100) - delivered_location = models.CharField(max_length=100) - local_vertical_reference_point = models.CharField( - max_length=100, - ) - offset = models.CharField(max_length=100) - vertical_datum = models.CharField(max_length=100) - ground_level_position = models.CharField(max_length=100) - ground_level_positioning_method = models.CharField( - max_length=100, - ) - standardized_location = models.CharField(max_length=100) - object_registration_time = models.DateTimeField() - registration_status = models.CharField(max_length=50) + delivery_accountable_party = models.CharField(max_length=8, null=True) + quality_regime = models.CharField(max_length=50, null=True) + delivery_context = models.CharField(max_length=100, null=True) + construction_standard = models.CharField(max_length=100, null=True) + initial_function = models.CharField(max_length=100, null=True) + removed = models.CharField(max_length=100, null=True) + ground_level_stable = models.CharField(max_length=100, null=True) + well_stability = models.CharField(max_length=100, null=True) + nitg_code = models.CharField(max_length=100, null=True) + well_code = models.CharField(max_length=100, null=True) + owner = models.CharField(max_length=100, null=True) + well_head_protector = models.CharField(max_length=100, null=True) + delivered_location = models.CharField(max_length=100, null=True) + local_vertical_reference_point = models.CharField(max_length=100, null=True) + offset = models.CharField(max_length=100, null=True) + vertical_datum = models.CharField(max_length=100, null=True) + ground_level_position = models.CharField(max_length=100, null=True) + ground_level_positioning_method = models.CharField(max_length=100, null=True) + standardized_location = models.CharField(max_length=100, null=True) + object_registration_time = models.DateTimeField(null=True) + registration_status = models.CharField(max_length=50, null=True) def __str__(self): return self.bro_id @@ -63,28 +59,26 @@ class MonitoringTube(models.Model): on_delete=models.CASCADE, ) gmw = models.ForeignKey(GMW, on_delete=models.CASCADE) - tube_number = models.CharField(max_length=100) - tube_type = models.CharField(max_length=100) - artesian_well_cap_present = models.CharField(max_length=100) - sediment_sump_present = models.CharField(max_length=100) - number_of_geo_ohm_cables = models.CharField(max_length=100) - tube_top_diameter = models.CharField(max_length=100) - variable_diameter = models.CharField(max_length=100) - tube_status = models.CharField(max_length=100) - tube_top_position = models.CharField(max_length=100) - tube_top_positioning_method = models.CharField( - max_length=100, - ) - tube_part_inserted = models.CharField(max_length=100) - tube_in_use = models.CharField(max_length=100) - tube_packing_material = models.CharField(max_length=100) - tube_material = models.CharField(max_length=100) - glue = models.CharField(max_length=100) - screen_length = models.CharField(max_length=100) - sock_material = models.CharField(max_length=100) - screen_top_position = models.CharField(max_length=100) - screen_bottom_position = models.CharField(max_length=100) - plain_tube_part_length = models.CharField(max_length=100) + tube_number = models.CharField(max_length=100, null=True) + tube_type = models.CharField(max_length=100, null=True) + artesian_well_cap_present = models.CharField(max_length=100, null=True) + sediment_sump_present = models.CharField(max_length=100, null=True) + number_of_geo_ohm_cables = models.CharField(max_length=100, null=True) + tube_top_diameter = models.CharField(max_length=100, null=True) + variable_diameter = models.CharField(max_length=100, null=True) + tube_status = models.CharField(max_length=100, null=True) + tube_top_position = models.CharField(max_length=100, null=True) + tube_top_positioning_method = models.CharField(max_length=100, null=True) + tube_part_inserted = models.CharField(max_length=100, null=True) + tube_in_use = models.CharField(max_length=100, null=True) + tube_packing_material = models.CharField(max_length=100, null=True) + tube_material = models.CharField(max_length=100, null=True) + glue = models.CharField(max_length=100, null=True) + screen_length = models.CharField(max_length=100, null=True) + sock_material = models.CharField(max_length=100, null=True) + screen_top_position = models.CharField(max_length=100, null=True) + screen_bottom_position = models.CharField(max_length=100, null=True) + plain_tube_part_length = models.CharField(max_length=100, null=True) def __str__(self): return f"{self.gmw}-{self.tube_number}" diff --git a/requirements.txt b/requirements.txt index 06e9e39..d208dda 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,7 +12,6 @@ markdown pytest pytest-django xmltodict -lxml python-dotenv django-encrypted-model-fields django-filter