mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
67 lines
1.8 KiB
Python
67 lines
1.8 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import TYPE_CHECKING, Optional
|
|
|
|
from backend.utils.addressMatch import AddressMatch
|
|
from datatypes.epc.domain.epc_property_data import EpcPropertyData
|
|
from datatypes.epc.search import EpcSearchResult
|
|
|
|
if TYPE_CHECKING:
|
|
from backend.epc_client.client import EpcClientService
|
|
|
|
_MIN_MATCH_SCORE = 0.6
|
|
|
|
|
|
def find_best_epc_match(
|
|
service: EpcClientService,
|
|
postcode: str,
|
|
address: str,
|
|
) -> Optional[EpcPropertyData]:
|
|
candidates = service.search_by_postcode(postcode)
|
|
if not candidates:
|
|
return None
|
|
|
|
cert_num = _pick_best_cert(candidates, address, use_full_address=False)
|
|
if cert_num:
|
|
return _safe_get(service, cert_num)
|
|
|
|
cert_num = _pick_best_cert(candidates, address, use_full_address=True)
|
|
if cert_num:
|
|
return _safe_get(service, cert_num)
|
|
|
|
return None
|
|
|
|
|
|
def _pick_best_cert(
|
|
candidates: list[EpcSearchResult],
|
|
user_address: str,
|
|
use_full_address: bool,
|
|
) -> Optional[str]:
|
|
scored: list[tuple[float, str]] = [
|
|
(
|
|
AddressMatch.score(
|
|
user_address,
|
|
r.full_address if use_full_address else r.address_line_1,
|
|
),
|
|
r.certificate_number,
|
|
)
|
|
for r in candidates
|
|
]
|
|
if not scored:
|
|
return None
|
|
best_score = max(s for s, _ in scored)
|
|
if best_score < _MIN_MATCH_SCORE:
|
|
return None
|
|
top = [cert for s, cert in scored if s == best_score]
|
|
if len(top) != 1:
|
|
return None
|
|
return top[0]
|
|
|
|
|
|
def _safe_get(service: EpcClientService, cert_num: str) -> Optional[EpcPropertyData]:
|
|
from backend.epc_client.exceptions import EpcNotFoundError
|
|
|
|
try:
|
|
return service.get_by_certificate_number(cert_num)
|
|
except EpcNotFoundError:
|
|
return None
|