diff --git a/datatypes/epc/domain/mapper.py b/datatypes/epc/domain/mapper.py index 0f1b8bad..bc8c7957 100644 --- a/datatypes/epc/domain/mapper.py +++ b/datatypes/epc/domain/mapper.py @@ -2549,7 +2549,9 @@ class EpcPropertyDataMapper: SapFlatDetails( level=schema.sap_flat_details.level, top_storey=schema.sap_flat_details.top_storey, - flat_location=schema.sap_flat_details.flat_location, + flat_location=_flat_location_int( + schema.sap_flat_details.flat_location + ), heat_loss_corridor=schema.sap_flat_details.heat_loss_corridor, storey_count=schema.sap_flat_details.storey_count, unheated_corridor_length_m=( @@ -3111,6 +3113,17 @@ def _clear_basement_flag_when_system_built( return replace(epc, sap_building_parts=new_parts) +def _flat_location_int(value: Any) -> int: + """`sap_flat_details.flat_location` is the flat's floor number, lodged by the + gov API as a plain int on most certs but as a banded string `"20+"` (floor 20 + or above) on high floors. The `epc_flat_details.flat_location` column is a + NOT-NULL integer, so the raw band crashed the modelling_e2e insert. Coerce the + band to its floor (`"20+"` → 20); Elmhurst caps the floor number at 30.""" + if isinstance(value, int): + return value + return int(str(value).strip().rstrip("+")) + + def _measurement_value(field: Any) -> float: """SAP measurements arrive as a `Measurement` (with `.value`), a raw dict {'value': N, 'quantity': '...'} when `from_dict` didn't coerce, or a plain