diff --git a/pms_ocr_klippa/__manifest__.py b/pms_ocr_klippa/__manifest__.py index f28b501b7..96536750d 100644 --- a/pms_ocr_klippa/__manifest__.py +++ b/pms_ocr_klippa/__manifest__.py @@ -16,6 +16,8 @@ "data": [ "data/pms_ocr_klippa_data.xml", "views/res_partner_id_category_views.xml", + "views/klippa_log_views.xml", + "security/ir.model.access.csv", ], "installable": True, } diff --git a/pms_ocr_klippa/models/__init__.py b/pms_ocr_klippa/models/__init__.py index 45a7df3f4..fc951df03 100644 --- a/pms_ocr_klippa/models/__init__.py +++ b/pms_ocr_klippa/models/__init__.py @@ -1,2 +1,3 @@ from . import pms_property from . import res_partner_id_category +from . import klippa_log diff --git a/pms_ocr_klippa/models/klippa_log.py b/pms_ocr_klippa/models/klippa_log.py new file mode 100644 index 000000000..eeffdbf48 --- /dev/null +++ b/pms_ocr_klippa/models/klippa_log.py @@ -0,0 +1,99 @@ +from datetime import timedelta + +from odoo import fields, models + + +class KlippaLog(models.Model): + _name = "klippa.log" + + pms_property_id = fields.Many2one( + string="PMS Property", + help="PMS Property", + comodel_name="pms.property", + required=True, + ) + request_id = fields.Text( + string="Klippa Request ID", + help="Request Klippa ID", + ) + image_base64_front = fields.Text( + string="Front Image", + help="Front Image", + ) + image_base64_back = fields.Text( + string="Back Image", + help="Back Image", + ) + klippa_response = fields.Text( + string="Klippa Response", + help="Response", + ) + klippa_status = fields.Char( + string="Status", + help="Status", + ) + request_datetime = fields.Datetime( + string="Request Date", + help="Request Date", + ) + response_datetime = fields.Datetime( + string="Response Date", + help="Response Date", + ) + request_duration = fields.Float( + string="Request Duration", + help="Request Duration", + ) + mapped_duration = fields.Float( + string="Mapped Duration", + help="Mapped Duration", + ) + total_duration = fields.Float( + string="Total Duration", + help="Total Duration", + ) + endpoint = fields.Char( + string="Endpoint", + help="Endpoint", + ) + request_size = fields.Integer( + string="Request Size", + help="Request Size", + ) + response_size = fields.Integer( + string="Response Size", + help="Response Size", + ) + request_headers = fields.Text( + string="Request Headers", + help="Request Headers", + ) + request_url = fields.Char( + string="Request URL", + help="Request URL", + ) + service_response = fields.Text( + string="Resvice Response", + help="Resvice Response", + ) + final_status = fields.Char( + string="Final Status", + help="Final Status", + ) + error = fields.Text( + string="Error", + help="Error", + ) + + def clean_log_data(self, offset=60): + """Clean log data older than the offset. + + :param int offset: The number of days to keep the log data. + + """ + self.sudo().search( + [ + ("final_status", "=", "success"), + ("create_date", "<", fields.Datetime.now() - timedelta(days=offset)), + ] + ).unlink() diff --git a/pms_ocr_klippa/models/pms_property.py b/pms_ocr_klippa/models/pms_property.py index 739ed979c..e6900bb4e 100644 --- a/pms_ocr_klippa/models/pms_property.py +++ b/pms_ocr_klippa/models/pms_property.py @@ -20,38 +20,88 @@ class PmsProperty(models.Model): # flake8: noqa: C901 def _klippa_document_process(self, image_base_64_front, image_base_64_back=False): - ocr_klippa_url = ( - self.env["ir.config_parameter"].sudo().get_param("ocr_klippa_url") - ) - ocr_klippa_api_key = ( - self.env["ir.config_parameter"].sudo().get_param("ocr_klippa_api_key") - ) - document = [] - if image_base_64_front: - document.append(image_base_64_front) - if image_base_64_back: - document.append(image_base_64_back) - if not document: - raise ValidationError(_("No document image found")) + try: + ocr_klippa_url = ( + self.env["ir.config_parameter"].sudo().get_param("ocr_klippa_url") + ) + ocr_klippa_api_key = ( + self.env["ir.config_parameter"].sudo().get_param("ocr_klippa_api_key") + ) + document = [] + if image_base_64_front: + document.append(image_base_64_front) + if image_base_64_back: + document.append(image_base_64_back) + if not document: + raise ValidationError(_("No document image found")) - headers = { - "X-Auth-Key": ocr_klippa_api_key, - "Content-Type": "application/json", - } - payload = { - "document": document, - } + headers = { + "X-Auth-Key": ocr_klippa_api_key, + "Content-Type": "application/json", + } + payload = { + "document": document, + } + log_data = { + "pms_property_id": self.id, + "image_base64_front": image_base_64_front, + "image_base64_back": image_base_64_back, + "request_datetime": datetime.now(), + "endpoint": ocr_klippa_url, + "request_size": len(image_base_64_front) + len(image_base_64_back), + "request_headers": str(headers), + } - # Call Klippa OCR API - result = requests.post( - ocr_klippa_url, - headers=headers, - json=payload, - ) - json_data = result.json() - if json_data.get("result") != "success": - raise ValidationError(_("Error calling Klippa OCR API")) - document_data = json_data["data"]["parsed"] + # Call Klippa OCR API + result = requests.post( + ocr_klippa_url, + headers=headers, + json=payload, + ) + json_data = result.json() + log_data.extend( + { + "klippa_response": json_data, + "klippa_status": json_data.get("result", "error"), + "response_datetime": datetime.now(), + "response_size": len(str(json_data)), + "request_duration": ( + datetime.now() - log_data["request_datetime"] + ).seconds, + } + ) + if json_data.get("result") != "success": + raise ValidationError(_("Error calling Klippa OCR API")) + document_data = json_data["data"]["parsed"] + init_mapped_datetime = datetime.now() + mapped_data = self._map_klippa_data(document_data) + log_data.extend( + { + "service_response": mapped_data, + "mapped_duration": (datetime.now() - init_mapped_datetime).seconds, + "total_duration": ( + datetime.now() - log_data["request_datetime"] + ).seconds, + "final_status": "success", + } + ) + self.env["klippa.log"].sudo().create(log_data) + return mapped_data + except Exception as e: + log_data.extend( + { + "error": str(e), + "final_status": "error", + "total_duration": ( + datetime.now() - log_data["request_datetime"] + ).seconds, + } + ) + self.env["klippa.log"].sudo().create(log_data) + _logger.error(e) + raise ValidationError(_("Error processing Klippa document")) + + def _map_klippa_data(self, document_data): mapped_data = {} found_partner = False if document_data.get("personal_number", False): @@ -225,7 +275,7 @@ class PmsProperty(models.Model): value["province"], self.env["res.country.state"].search(domain).mapped("name"), ) - if candidates and candidates[1] >= 90: + if candidates[1] >= 90: country_state = self.env["res.country.state"].search( domain + [("name", "=", candidates[0])] ) diff --git a/pms_ocr_klippa/security/ir.model.access.csv b/pms_ocr_klippa/security/ir.model.access.csv new file mode 100644 index 000000000..7f2838d97 --- /dev/null +++ b/pms_ocr_klippa/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +techinal_klippa_log_access,techinal_klippa_log_access,model_klippa_log,base.group_system,1,1,1,1 diff --git a/pms_ocr_klippa/static/description/index.html b/pms_ocr_klippa/static/description/index.html index aa53b2c3c..7043ce79f 100644 --- a/pms_ocr_klippa/static/description/index.html +++ b/pms_ocr_klippa/static/description/index.html @@ -1,4 +1,3 @@ - diff --git a/pms_ocr_klippa/views/klippa_log_views.xml b/pms_ocr_klippa/views/klippa_log_views.xml new file mode 100644 index 000000000..4a65e2677 --- /dev/null +++ b/pms_ocr_klippa/views/klippa_log_views.xml @@ -0,0 +1,104 @@ + + + + klippa.log.tree + klippa.log + + + + + + + + + + + + + klippa.log.form + klippa.log + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + klippa.log.search + klippa.log + + + + + + + + + + + + klippa.log.pivot + klippa.log + + + + + + + + + + klippa.log.graph + klippa.log + + + + + + + + + + Klippa Log + klippa.log + tree,form,pivot,graph + + + + +