Files
pms/pms_ocr_klippa/models/pms_property.py
2024-04-22 17:47:31 +02:00

188 lines
7.6 KiB
Python

from datetime import date, datetime
import requests
from dateutil.relativedelta import relativedelta
from odoo import _, fields, models
from odoo.exceptions import ValidationError
class PmsProperty(models.Model):
_inherit = "pms.property"
ocr_checkin_supplier = fields.Selection(selection_add=[("klippa", "Klippa")])
# 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_back:
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,
}
# 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"]
mapped_data = {}
for key, dict_value in document_data.items():
if dict_value and isinstance(dict_value, dict):
value = dict_value.get("value", False)
else:
continue
# Residence Address --------------------------------------------------
if key == "address" and value:
if "street_name" in value:
mapped_data["residence_street"] = value["street_name"] + (
" " + value["house_number"] if "house_number" in value else ""
)
if "city" in value:
mapped_data["residence_city"] = value["city"]
if "postcode" in value:
mapped_data["zip"] = value["postcode"]
if "province" in value:
mapped_data["residence_state_id"] = (
self.env["res.country.state"]
.search(
[
("name", "ilike", value["province"]),
(
"country_id",
"=",
self._get_country_id(value.get("country", False)),
),
]
)
.id
or False
)
# Document Data --------------------------------------------------
elif key == "issuing_country" and value:
mapped_data["document_country_id"] = self._get_country_id(value)
elif key == "document_number" and value:
mapped_data["document_support_number"] = value
elif key == "document_type" and value:
mapped_data["document_type"] = self._get_document_type(
klippa_type=value,
klippa_subtype=document_data.get("document_subtype", False),
)
elif key == "personal_number" and value:
mapped_data["document_number"] = value
elif key == "date_of_issue" and value:
mapped_data["document_expedition_date"] = datetime.strptime(
value, "%Y-%m-%dT%H:%M:%S"
).date()
elif (
key == "date_of_expiry"
and value
and not document_data.get("date_of_issue", False)
):
mapped_data["document_expiration_date"] = self._calc_expedition_date(
document_class_code=self._get_document_type(
klippa_type=document_data.get("document_class_code", False),
klippa_subtype=document_data.get("document_subtype", False),
),
date_of_expiry=value,
age=False,
date_of_birth=document_data.get("date_of_birth", False),
)
# Personal Data --------------------------------------------------
elif key == "gender" and value:
if value == "M":
mapped_data["gender"] = "male"
elif value == "F":
mapped_data["gender"] = "female"
else:
mapped_data["gender"] = "other"
elif key == "given_names" and value:
mapped_data["firstname"] = value
elif key == "surname" and value:
mapped_data["lastname"] = self._get_surnames(
origin_surname=value,
)[0]
mapped_data["lastname2"] = self._get_surnames(
origin_surname=value,
)[1]
elif key == "date_of_birth" and value:
mapped_data["birthdate"] = datetime.strptime(
value, "%Y-%m-%dT%H:%M:%S"
).date()
elif key == "nationality" and value:
mapped_data["nationality"] = self._get_country_id(value)
return mapped_data
def _calc_expedition_date(self, document_type, date_of_expiry, age, date_of_birth):
result = False
person_age = False
if age and age.value != "":
person_age = int(age.value)
elif date_of_birth and date_of_birth.value != "":
date_of_birth = datetime.strptime(
date_of_birth.value.replace("-", "/"), "%Y-%m-%dT%H:%M:%S"
).date()
person_age = relativedelta(date.today(), date_of_birth).years
if date_of_expiry and date_of_expiry.value != "" and person_age:
date_of_expiry = datetime.strptime(
date_of_expiry.value.replace("-", "/"), "%Y-%m-%dT%H:%M:%S"
).date()
if person_age < 30:
result = date_of_expiry - relativedelta(years=5)
elif person_age >= 30 and document_type and document_type.code == "P":
result = date_of_expiry - relativedelta(years=10)
elif 30 <= person_age < 70:
result = date_of_expiry - relativedelta(years=10)
return result.isoformat() if result else False
def _get_document_type(self, klippa_type, klippa_subtype):
document_type_ids = self.env["res.partner.id_category"].search(
[
("klippa_code", "=", klippa_type),
]
)
if not document_type_ids:
raise ValidationError(_(f"Document type not found: {klippa_type}"))
document_type_id = document_type_ids[0]
if len(document_type_ids) > 1:
document_type_id = document_type_ids.filtered(
lambda r: r.klippa_subtype_code == klippa_subtype
).id
return document_type_id
def _get_country_id(self, country_code):
return (
self.env["res.country"]
.search([("code_alpha3", "=", country_code)], limit=1)
.id
)
def _get_surnames(self, origin_surname):
# If origin surname has two or more surnames
if " " in origin_surname:
return origin_surname.split(" ")
else:
return [origin_surname, ""]