diff --git a/backend/condition/domain/lbwf_element.py b/backend/condition/domain/lbwf_element.py deleted file mode 100644 index 52928c72..00000000 --- a/backend/condition/domain/lbwf_element.py +++ /dev/null @@ -1,131 +0,0 @@ -from enum import StrEnum - - -class LbwfElement(StrEnum): - AHR_CAT = "Accessible Housing Register Category" - ASBESTOS = "Asbestos Present" - ASSETSAREA = "Assets Area for Decent Homes and Investment" - DECNTHMINC = "Include for Decent Homes Reporting - LBWF Stock" - EICINSFREQ = "EICR - Elec Install Conditions Report Inspection Frequency" - EXTBALCONY = "Private Balconies in External Area" - EXTBKSDDR1 = "Back and Side Doors 1 in External Area" - EXTBKSDDR2 = "Back and Side Doors 2 in External Area" - EXTBPOINTG = "Brickwork Pointing in External Area" - EXTCHIMNEY = "Chimneys in External Area" - EXTDWNPTYP = "Downpipes in External Area" - EXTDRPKERB = "Drop Kerb in External Area" - EXTEXTDECS = "External Decorations in External Area" - EXTFASOFBR = "Fascia / Soffit / Bargeboard in External Area" - EXTGARDOOR = "Garage Door in External Area" - EXTGARROOF = "Garage Roof in External Area" - EXTGARSTDR = "Garage and Store Doors in External Area" - EXTGARSTRF = "Garage and Store Roofs in External Area" - EXTGARSTWD = "Garage and Store Windows in External Area" - EXTGARWDWS = "Garage Windows in External Area" - EXTGUTRTYP = "Gutters in External Area" - EXTHARDSTD = "Hardstanding in External Area" - EXTINTDWNP = "Internal Downpipes in External Area" - EXTLINTELS = "Lintels in External Area" - EXTOUTBOH = "Overhaul of Outbuilding in External Area" - EXTPARKING = "Parking in External Area" - EXTPCHCNPY = "Porch and / or Canopy in External Area" - EXTPTFRDR1 = "Patio and French Doors 1 in External Area" - EXTROOF1 = "Roof Covering 1 in External Area" - EXTROOF2 = "Roof Covering 2 in External Area" - EXTROOF3 = "Roof Covering 3 in External Area" - EXTRFSTR1 = "Roof Structure 1 in External Area" - EXTRFSTR2 = "Roof Structure 2 in External Area" - EXTRFSTR3 = "Roof Structure 3 in External Area" - EXTSTOREY = "Number of Storeys within the Property or Block" - EXTSTRDOOR = "Store Door in External Area" - EXTSTRINSP = "Structural Defects in External Area" - EXTSTRROOF = "Store Roof in External Area" - EXTSTRWDWS = "Store Windows in External Area" - EXTWALLFN1 = "Wall Finish 1 in External Area" - EXTWALLFN2 = "Wall Finish 2 in External Area" - EXTWALLINS = "Wall Insulation Improvement in External Area" - EXTWALLSPL = "Wall Spalling in External Area" - EXTWALLSTR = "Wall Structure in External Area" - EXTWNDWS1 = "Windows 1 in External Area" - EXTWNDWS2 = "Windows 2 in External Area" - FFHHDAMP = "Fitness for Human Habitation - Serious problem with damp" - FFHHDRNWC = ( - "Fitness for Human Habitation - Problems with the drainage or the lavatories" - ) - FFHHHCWAT = ( - "Fitness for Human Habitation - Problem with the supply of hot and cold water" - ) - FFHHNEGLC = ( - "Fitness for Human Habitation - Building neglected and is in a bad condition" - ) - FFHHNONAT = "Fitness for Human Habitation - Not enough natural light" - FFHHNOVEN = "Fitness for Human Habitation - Not enough ventilation" - FFHHPRPCK = ( - "Fitness for Human Habitation - Difficult to prepare and cook food or wash up" - ) - FFHHUNLAY = "Fitness for Human Habitation - Unsafe layout" - FFHHUNSTA = "Fitness for Human Habitation - Building is unstable" - FRARISKRTG = "Fire Risk Assessment Rating" - FRAEVACSTR = "Fire Risk Assessment Evacuation Strategy" - FRATYPE = "Fire Risk Assessment Type" - FLVL = "Floor Level of Front Door" - HHSRSASB = "Asbestos (and MMF)" - HHSRSBIOC = "Biocides" - HHSRSCO = "Carbon monoxide" - HHSRSCOLD = "Excess cold" - HHSRSCLOW = "Collision hazards and low headroom" - HHSRSCROWD = "Crowding and space" - HHSRSDAMP = "Damp and mould growth" - HHSRSDOMES = "Domestic hygeine, Pests and Refuse" - HHSRSELEC = "Electrical hazards" - HHSRSENTRP = "Collision and entrapment" - HHSRSENTRY = "Entry by intruders" - HHSRSEXPLO = "Explosions" - HHSRSFBATH = "Falls associated with baths etc" - HHSRSFBETW = "Falling between levels" - HHSRSFIRE = "Fire" - HHSRSFLAME = "Flames, hot surfaces etc" - HHSRSFLEVE = "Falling on level surfaces etc" - HHSRSFOOD = "Food safety" - HHSRSFSTAI = "Falling on stairs etc" - HHSRSFUEL = "Uncombusted fuel gas" - HHSRSHEAT = "Excess heat" - HHSRSLEAD = "Lead" - HHSRSLIGHT = "Lighting" - HHSRSNO2 = "Nitrogen dioxide" - HHSRSNOISE = "Noise" - HHSRSORGAN = "Volatile organic compounds" - HHSRSPERS = "Personal hygeine, Sanitation and Drainage" - HHSRSPOSI = "Position and operability of amenities etc" - HHSRSRADIA = "Radiation" - HHSRSSO2 = "Sulphur dioxide and smoke" - HHSRSSTRUC = "Structural collapse and falling elements" - HHSRSWATER = "Water supply" - INTACCRAMP = "Access Ramp 1:12 Gradient to Property" - INTADDWCW = "Additional WCs and / or WHBs in Property" - INTBTHADEQ = "Adequacy of Bathroom Location in Property" - INTBTHREML = "Source of Bathroom Remaining Life in Property" - INTBTHRLOC = "Location of Bathroom in Property" - INTBOILERF = "Boiler Fuel in Property" - INTCHEXTNT = "Extent of Central Heating in Property" - INTCKRLOC = "Adequacy of Cooker Location in Property" - INTCOMHTG = "Community Heating in Property" - INTELECTRC = "Electrics Required in Property" - INTFLRLVL = "Floor Level Location for Property" - INTFRDOOR = "Type and Location of Front Door in Property" - INTFRDRFRR = "Front Door Fire Rating in Property" - INTGASAVAI = "Gas Available in Property" - INTHEATREC = "Heat Recovery Units in Property" - INTHTDISYS = "Heating Distribution System in Property" - INTHTIMP = "Heating Improvement Required in Property" - INTKITADEQ = "Adequacy of Kitchen and Type in Property" - INTKITREML = "Source of Kitchen Remaining Life in Property" - INTLOFTINS = "Size in mm of Loft Insulation Thickness in Property" - INTNSEINSL = "Adequacy of Noise Insulation in Property" - INTPROGHTG = "Programmable Heating in Property" - INTSMKDET = "Smoke Detectors in Property" - INTSTEPSFD = "Number of Steps to Front Door for Property" - INTTNTINST = "Tenant Installed Kitchen in Property" - INTWDWTYPE = "Windows in Property" - INTWTRHTNG = "Type of Water Heating in Property" - QUALITYSTD = "Quality standard" diff --git a/backend/condition/domain/mapping/element_mapping.py b/backend/condition/domain/mapping/element_mapping.py new file mode 100644 index 00000000..01e1f316 --- /dev/null +++ b/backend/condition/domain/mapping/element_mapping.py @@ -0,0 +1,12 @@ +from dataclasses import dataclass +from typing import Optional +from xml.dom.minidom import Element + +from backend.condition.domain.aspect_type import AspectType + + +@dataclass(frozen=True) +class ElementMapping: + element: Element + aspect_type: AspectType + element_instance: Optional[int] = None diff --git a/backend/condition/domain/mapping/lbwf/lbwf_element_map.py b/backend/condition/domain/mapping/lbwf/lbwf_element_map.py index 750a76c6..047013f4 100644 --- a/backend/condition/domain/mapping/lbwf/lbwf_element_map.py +++ b/backend/condition/domain/mapping/lbwf/lbwf_element_map.py @@ -1,179 +1,170 @@ -from dataclasses import dataclass -from typing import Optional - from backend.condition.domain.element import Element from backend.condition.domain.aspect_type import AspectType +from backend.condition.domain.mapping.element_mapping import ElementMapping -@dataclass(frozen=True) -class LbwfElementMapping: - element: Element - aspect_type: AspectType - element_instance: Optional[int] = None - - -LBWF_ELEMENT_MAP: dict[str, LbwfElementMapping] = { +LBWF_ELEMENT_MAP: dict[str, ElementMapping] = { # ========================================================== # PROPERTY / GENERAL # ========================================================== - "AHR_CAT": LbwfElementMapping( + "AHR_CAT": ElementMapping( element=Element.ACCESSIBLE_HOUSING_REGISTER, aspect_type=AspectType.CATEGORY, ), - "ASSETSAREA": LbwfElementMapping( + "ASSETSAREA": ElementMapping( element=Element.PROPERTY, aspect_type=AspectType.AREA, ), - # "DECNTHMINC": LbwfElementMapping( + # "DECNTHMINC": ElementMapping( # element=Element.DECENT_HOMES, # aspect_type=AspectType.INCLUSION, # ), # Ignore this one - "QUALITYSTD": LbwfElementMapping( + "QUALITYSTD": ElementMapping( element=Element.QUALITY_STANDARD, aspect_type=AspectType.TYPE, ), - "EXTSTOREY": LbwfElementMapping( + "EXTSTOREY": ElementMapping( element=Element.PROPERTY, aspect_type=AspectType.CONFIGURATION, ), - "FLVL": LbwfElementMapping( + "FLVL": ElementMapping( element=Element.FLOOR_LEVEL_FRONT_DOOR, aspect_type=AspectType.LOCATION, ), # ========================================================== # ASBESTOS (NON-HHSRS RECORD) # ========================================================== - "ASBESTOS": LbwfElementMapping( + "ASBESTOS": ElementMapping( element=Element.ASBESTOS, aspect_type=AspectType.PRESENCE, ), # ========================================================== # INTERNAL – BATHROOMS & KITCHENS # ========================================================== - "INTBTHRLOC": LbwfElementMapping( + "INTBTHRLOC": ElementMapping( element=Element.BATHROOM, aspect_type=AspectType.LOCATION, ), - "INTBTHADEQ": LbwfElementMapping( + "INTBTHADEQ": ElementMapping( element=Element.BATHROOM, aspect_type=AspectType.ADEQUACY, ), - "INTKITADEQ": LbwfElementMapping( + "INTKITADEQ": ElementMapping( element=Element.KITCHEN, aspect_type=AspectType.ADEQUACY, ), - "INTCKRLOC": LbwfElementMapping( + "INTCKRLOC": ElementMapping( element=Element.KITCHEN, aspect_type=AspectType.LOCATION, ), # ========================================================== # INTERNAL – HEATING # ========================================================== - "INTCHEXTNT": LbwfElementMapping( + "INTCHEXTNT": ElementMapping( element=Element.HEATING_EXTENT, aspect_type=AspectType.CONFIGURATION, ), - "INTCHDIST": LbwfElementMapping( + "INTCHDIST": ElementMapping( element=Element.HEATING_DISTRIBUTION, aspect_type=AspectType.TYPE, ), - "INTCHBLR": LbwfElementMapping( + "INTCHBLR": ElementMapping( element=Element.HEATING_BOILER, aspect_type=AspectType.TYPE, ), # ========================================================== # INTERNAL – FIRE # ========================================================== - "FRARISKRTG": LbwfElementMapping( + "FRARISKRTG": ElementMapping( element=Element.FIRE_RISK_ASSESSMENT, aspect_type=AspectType.RATING, ), - "FRATYPE": LbwfElementMapping( + "FRATYPE": ElementMapping( element=Element.FIRE_RISK_ASSESSMENT, aspect_type=AspectType.TYPE, ), - "FRAEVACSTR": LbwfElementMapping( + "FRAEVACSTR": ElementMapping( element=Element.FIRE_RISK_ASSESSMENT, aspect_type=AspectType.STRATEGY, ), - "INTSMKDET": LbwfElementMapping( + "INTSMKDET": ElementMapping( element=Element.SMOKE_DETECTION, aspect_type=AspectType.PRESENCE, ), - "INTCHEXTNT": LbwfElementMapping( + "INTCHEXTNT": ElementMapping( element=Element.HEATING_SYSTEM, aspect_type=AspectType.EXTENT, ), # ========================================================== # HEATING & SERVICES # ========================================================== - "INTBOILERF": LbwfElementMapping( + "INTBOILERF": ElementMapping( element=Element.BOILER_FUEL, aspect_type=AspectType.TYPE, ), - "INTHTDISYS": LbwfElementMapping( + "INTHTDISYS": ElementMapping( element=Element.HEATING_SYSTEM, aspect_type=AspectType.DISTRIBUTION, ), - "INTWTRHTNG": LbwfElementMapping( + "INTWTRHTNG": ElementMapping( element=Element.WATER_HEATING, aspect_type=AspectType.TYPE, ), # ========================================================== # EXTERNAL – WALLS (INSTANCED) # ========================================================== - "EXTWALLSTR": LbwfElementMapping( + "EXTWALLSTR": ElementMapping( element=Element.EXTERNAL_WALL, aspect_type=AspectType.STRUCTURE, element_instance=1, ), - "EXTWALLFN1": LbwfElementMapping( + "EXTWALLFN1": ElementMapping( element=Element.EXTERNAL_WALL, aspect_type=AspectType.FINISH, element_instance=1, ), - "EXTWALLFN2": LbwfElementMapping( + "EXTWALLFN2": ElementMapping( element=Element.EXTERNAL_WALL, aspect_type=AspectType.FINISH, element_instance=2, ), - "EXTWALLINS": LbwfElementMapping( + "EXTWALLINS": ElementMapping( element=Element.EXTERNAL_WALL, aspect_type=AspectType.INSULATION, ), - "EXTWALLSPL": LbwfElementMapping( + "EXTWALLSPL": ElementMapping( element=Element.EXTERNAL_WALL, aspect_type=AspectType.CONDITION, ), # ========================================================== # EXTERNAL – ROOFS (INSTANCED) # ========================================================== - "EXTRFSTR1": LbwfElementMapping( + "EXTRFSTR1": ElementMapping( element=Element.ROOF, aspect_type=AspectType.STRUCTURE, element_instance=1, ), - "EXTRFSTR2": LbwfElementMapping( + "EXTRFSTR2": ElementMapping( element=Element.ROOF, aspect_type=AspectType.STRUCTURE, element_instance=2, ), - "EXTRFSTR3": LbwfElementMapping( + "EXTRFSTR3": ElementMapping( element=Element.ROOF, aspect_type=AspectType.STRUCTURE, element_instance=3, ), - "EXTROOF1": LbwfElementMapping( + "EXTROOF1": ElementMapping( element=Element.ROOF, aspect_type=AspectType.COVERING, element_instance=1, ), - "EXTROOF2": LbwfElementMapping( + "EXTROOF2": ElementMapping( element=Element.ROOF, aspect_type=AspectType.COVERING, element_instance=2, ), - "EXTROOF3": LbwfElementMapping( + "EXTROOF3": ElementMapping( element=Element.ROOF, aspect_type=AspectType.COVERING, element_instance=3, @@ -181,34 +172,34 @@ LBWF_ELEMENT_MAP: dict[str, LbwfElementMapping] = { # ========================================================== # EXTERNAL – DOORS & WINDOWS # ========================================================== - "INTFRDOOR": LbwfElementMapping( + "INTFRDOOR": ElementMapping( element=Element.EXTERNAL_DOOR, aspect_type=AspectType.TYPE, ), - "INTFRDRFRR": LbwfElementMapping( + "INTFRDRFRR": ElementMapping( element=Element.EXTERNAL_DOOR, aspect_type=AspectType.FIRE_RATING, ), - "EXTBKSDDR1": LbwfElementMapping( + "EXTBKSDDR1": ElementMapping( element=Element.EXTERNAL_DOOR, aspect_type=AspectType.TYPE, element_instance=1, ), - "EXTBKSDDR2": LbwfElementMapping( + "EXTBKSDDR2": ElementMapping( element=Element.EXTERNAL_DOOR, aspect_type=AspectType.TYPE, element_instance=2, ), - "INTWDWTYPE": LbwfElementMapping( + "INTWDWTYPE": ElementMapping( element=Element.EXTERNAL_WINDOWS, aspect_type=AspectType.TYPE, ), - "EXTWNDWS1": LbwfElementMapping( + "EXTWNDWS1": ElementMapping( element=Element.EXTERNAL_WINDOWS, aspect_type=AspectType.TYPE, element_instance=1, ), - "EXTWNDWS2": LbwfElementMapping( + "EXTWNDWS2": ElementMapping( element=Element.EXTERNAL_WINDOWS, aspect_type=AspectType.TYPE, element_instance=2, @@ -216,121 +207,121 @@ LBWF_ELEMENT_MAP: dict[str, LbwfElementMapping] = { # ========================================================== # HHSRS # ========================================================== - "HHSRSDAMP": LbwfElementMapping( + "HHSRSDAMP": ElementMapping( element=Element.HHSRS_DAMP_AND_MOULD, aspect_type=AspectType.RISK, ), - "HHSRSCOLD": LbwfElementMapping( + "HHSRSCOLD": ElementMapping( element=Element.HHSRS_EXCESS_COLD, aspect_type=AspectType.RISK, ), - "HHSRSHEAT": LbwfElementMapping( + "HHSRSHEAT": ElementMapping( element=Element.HHSRS_EXCESS_HEAT, aspect_type=AspectType.RISK, ), - "HHSRSASB": LbwfElementMapping( + "HHSRSASB": ElementMapping( element=Element.HHSRS_ASBESTOS_AND_MMF, aspect_type=AspectType.RISK, ), - "HHSRSBIOCIDES": LbwfElementMapping( + "HHSRSBIOCIDES": ElementMapping( element=Element.HHSRS_BIOCIDES, aspect_type=AspectType.RISK, ), - "HHSRSCO": LbwfElementMapping( + "HHSRSCO": ElementMapping( element=Element.HHSRS_CARBON_MONOXIDE, aspect_type=AspectType.RISK, ), - "HHSRSLEAD": LbwfElementMapping( + "HHSRSLEAD": ElementMapping( element=Element.HHSRS_LEAD, aspect_type=AspectType.RISK, ), - "HHSRSRADIA": LbwfElementMapping( + "HHSRSRADIA": ElementMapping( element=Element.HHSRS_RADIATION, aspect_type=AspectType.RISK, ), - "HHSRSFUEL": LbwfElementMapping( + "HHSRSFUEL": ElementMapping( element=Element.HHSRS_UNCOMBUSTED_FUEL_GAS, aspect_type=AspectType.RISK, ), - "HHSRSORGAN": LbwfElementMapping( + "HHSRSORGAN": ElementMapping( element=Element.HHSRS_VOLATILE_ORGANIC_COMPOUNDS, aspect_type=AspectType.RISK ), - "HHSRSCROWD": LbwfElementMapping( + "HHSRSCROWD": ElementMapping( element=Element.HHSRS_CROWDING_AND_SPACE, aspect_type=AspectType.RISK, ), - "HHSRSENTRY": LbwfElementMapping( + "HHSRSENTRY": ElementMapping( element=Element.HHSRS_ENTRY_BY_INTRUDERS, aspect_type=AspectType.RISK, ), - "HHSRSLIGHT": LbwfElementMapping( + "HHSRSLIGHT": ElementMapping( element=Element.HHSRS_LIGHTING, aspect_type=AspectType.RISK, ), - "HHSRSNOISE": LbwfElementMapping( + "HHSRSNOISE": ElementMapping( element=Element.HHSRS_NOISE, aspect_type=AspectType.RISK, ), - "HHSRSDOMES": LbwfElementMapping( + "HHSRSDOMES": ElementMapping( element=Element.HHSRS_DOMESTIC_HYGIENE_PESTS_REFUSE, aspect_type=AspectType.RISK, ), - "HHSRSFOOD": LbwfElementMapping( + "HHSRSFOOD": ElementMapping( element=Element.HHSRS_FOOD_SAFETY, aspect_type=AspectType.RISK, ), - "HHSRSPERS": LbwfElementMapping( + "HHSRSPERS": ElementMapping( element=Element.HHSRS_PERSONAL_HYGIENE_SANITATION, aspect_type=AspectType.RISK, ), - "HHSRSWATER": LbwfElementMapping( + "HHSRSWATER": ElementMapping( element=Element.HHSRS_WATER_SUPPLY, aspect_type=AspectType.RISK, ), - "HHSRSFBATH": LbwfElementMapping( + "HHSRSFBATH": ElementMapping( element=Element.HHSRS_FALLS_ASSOCIATED_WITH_BATHS, aspect_type=AspectType.RISK, ), - "HHSRSFLEVE": LbwfElementMapping( + "HHSRSFLEVE": ElementMapping( element=Element.HHSRS_FALLS_ON_LEVEL_SURFACES, aspect_type=AspectType.RISK, ), - "HHSRSFSTAI": LbwfElementMapping( + "HHSRSFSTAI": ElementMapping( element=Element.HHSRS_FALLS_ON_STAIRS, aspect_type=AspectType.RISK, ), - "HHSRSFBETW": LbwfElementMapping( + "HHSRSFBETW": ElementMapping( element=Element.HHSRS_FALLS_BETWEEN_LEVELS, aspect_type=AspectType.RISK, ), - "HHSRSELEC": LbwfElementMapping( + "HHSRSELEC": ElementMapping( element=Element.HHSRS_ELECTRICAL_HAZARDS, aspect_type=AspectType.RISK, ), - "HHSRSFIRE": LbwfElementMapping( + "HHSRSFIRE": ElementMapping( element=Element.HHSRS_FIRE, aspect_type=AspectType.RISK, ), - "HHSRSFLAME": LbwfElementMapping( + "HHSRSFLAME": ElementMapping( element=Element.HHSRS_FLAMES_HOT_SURFACES, aspect_type=AspectType.RISK, ), - "HHSRSENTRP": LbwfElementMapping( + "HHSRSENTRP": ElementMapping( element=Element.HHSRS_COLLISION_AND_ENTRAPMENT, aspect_type=AspectType.RISK, ), - "HHSRSEXPLO": LbwfElementMapping( + "HHSRSEXPLO": ElementMapping( element=Element.HHSRS_EXPLOSIONS, aspect_type=AspectType.RISK, ), - "HHSRSSTRUC": LbwfElementMapping( + "HHSRSSTRUC": ElementMapping( element=Element.HHSRS_STRUCTURAL_COLLAPSE, aspect_type=AspectType.RISK, ), - "HHSRSCLOW": LbwfElementMapping( + "HHSRSCLOW": ElementMapping( element=Element.HHSRS_COLLISION_AND_ENTRAPMENT, aspect_type=AspectType.RISK ), - "HHSRSPOSI": LbwfElementMapping( + "HHSRSPOSI": ElementMapping( element=Element.HHSRS_AMENITIES, aspect_type=AspectType.RISK, ), diff --git a/backend/condition/domain/mapping/lbwf/lbwf_mapper.py b/backend/condition/domain/mapping/lbwf/lbwf_mapper.py index 01f48a35..635e5898 100644 --- a/backend/condition/domain/mapping/lbwf/lbwf_mapper.py +++ b/backend/condition/domain/mapping/lbwf/lbwf_mapper.py @@ -2,10 +2,8 @@ from typing import Any, List, Optional from backend.condition.domain.asset_condition import AssetCondition from backend.condition.domain.element import Element -from backend.condition.domain.mapping.lbwf.lbwf_element_map import ( - LbwfElementMapping, - LBWF_ELEMENT_MAP, -) +from backend.condition.domain.mapping.element_mapping import ElementMapping +from backend.condition.domain.mapping.lbwf.lbwf_element_map import LBWF_ELEMENT_MAP from backend.condition.domain.mapping.mapper import Mapper from backend.condition.parsing.records.lbwf.lbwf_asset_condition import ( LbwfAssetCondition, @@ -19,7 +17,7 @@ logger = setup_logger() class LbwfMapper(Mapper): def map_asset_conditions_for_property( - self, client_data: Any, survey_year: Optional[int] + self, client_data: Any, survey_year: Optional[int] = None ) -> List[AssetCondition]: assert isinstance( client_data, LbwfHouse @@ -30,7 +28,7 @@ class LbwfMapper(Mapper): uprn: int = client_data.uprn for raw_asset in client_data.assets: try: - element_mapping: LbwfElementMapping = LbwfMapper._map_element( + element_mapping: ElementMapping = LbwfMapper._map_element( raw_asset.element_code ) except: @@ -59,7 +57,7 @@ class LbwfMapper(Mapper): return mapped_assets @staticmethod - def _map_element(lbwf_element_code: str) -> LbwfElementMapping: + def _map_element(lbwf_element_code: str) -> ElementMapping: return LBWF_ELEMENT_MAP[lbwf_element_code] @staticmethod diff --git a/backend/condition/domain/mapping/mapper.py b/backend/condition/domain/mapping/mapper.py index 4e51d46b..c0b07184 100644 --- a/backend/condition/domain/mapping/mapper.py +++ b/backend/condition/domain/mapping/mapper.py @@ -3,9 +3,12 @@ from typing import Any, List, Optional from backend.condition.domain.asset_condition import AssetCondition + class Mapper(ABC): @abstractmethod - def map_asset_conditions_for_property(self, client_data: Any, survey_year: Optional[int]) -> List[AssetCondition]: - #TODO: client_data should be properly typed - pass \ No newline at end of file + def map_asset_conditions_for_property( + self, client_data: Any, survey_year: Optional[int] = None + ) -> List[AssetCondition]: + # TODO: client_data should be properly typed + pass diff --git a/backend/condition/domain/mapping/peabody/peabody_element_map.py b/backend/condition/domain/mapping/peabody/peabody_element_map.py new file mode 100644 index 00000000..2a1203c0 --- /dev/null +++ b/backend/condition/domain/mapping/peabody/peabody_element_map.py @@ -0,0 +1,40 @@ +from backend.condition.domain.mapping.element_mapping import ElementMapping + + +PEABODY_ELEMENT_MAP = { + # -------------------- + # GENERAL + # -------------------- + ("100", "1"): ElementMapping(element="property", aspect="type"), + ("100", "3"): ElementMapping(element="property", aspect="age_band"), + ("100", "14"): ElementMapping(element="property", aspect="construction_type"), + # -------------------- + # EXTERNALS + # -------------------- + ("120", "1"): ElementMapping(element="external_wall", aspect="structure"), + ("120", "2"): ElementMapping(element="external_wall", aspect="finish"), + ("110", "1"): ElementMapping(element="roof", aspect="covering"), + # -------------------- + # INTERNALS + # -------------------- + ("160", "1"): ElementMapping(element="kitchen", aspect="condition"), + ("190", "1"): ElementMapping(element="bathroom", aspect="condition"), + # -------------------- + # HHSRS (PEABODY) + # -------------------- + ("54", "1"): ElementMapping( + element="hhsrs", aspect="risk", is_hhsrs=True, hhsrs_hazard_id=1 + ), + ("54", "2"): ElementMapping( + element="hhsrs", aspect="risk", is_hhsrs=True, hhsrs_hazard_id=2 + ), + ("54", "4"): ElementMapping( + element="hhsrs", aspect="risk", is_hhsrs=True, hhsrs_hazard_id=4 + ), + ("54", "24"): ElementMapping( + element="hhsrs", aspect="risk", is_hhsrs=True, hhsrs_hazard_id=24 + ), + ("54", "29"): ElementMapping( + element="hhsrs", aspect="risk", is_hhsrs=True, hhsrs_hazard_id=29 + ), +} diff --git a/backend/condition/domain/mapping/peabody/peabody_mapper.py b/backend/condition/domain/mapping/peabody/peabody_mapper.py index 8413b888..3f0ee931 100644 --- a/backend/condition/domain/mapping/peabody/peabody_mapper.py +++ b/backend/condition/domain/mapping/peabody/peabody_mapper.py @@ -13,6 +13,6 @@ logger = setup_logger() class PeabodyMapper(Mapper): def map_asset_conditions_for_property( - self, client_data: Any, survey_year: Optional[int] + self, client_data: Any, survey_year: Optional[int] = None ) -> List[AssetCondition]: raise NotImplementedError diff --git a/backend/condition/tests/mapping/test_peabody_mapper.py b/backend/condition/tests/mapping/test_peabody_mapper.py index de027fe7..ca3f78a4 100644 --- a/backend/condition/tests/mapping/test_peabody_mapper.py +++ b/backend/condition/tests/mapping/test_peabody_mapper.py @@ -1,5 +1,8 @@ from datetime import datetime +from typing import List +from backend.condition.domain.aspect_type import AspectType +from backend.condition.domain.element import Element from backend.condition.domain.mapping.peabody.peabody_mapper import PeabodyMapper from backend.condition.parsing.records.peabody.peabody_asset_condition import ( PeabodyAssetCondition, @@ -18,23 +21,42 @@ def test_peabody_mapper_maps_property(): full_address="FLAT 1 RANDOM SQUARE FAKE STREET LONDON E1 1EE", location_type_code=1, parent_lo_reference="RAND1000", - element_code=50, - element="Internal", - sub_element_code=3, - sub_element="CCU", - material_code=2, - material_or_answer="RCD/MCB CCU", - renewal_quantity=1, - renewal_year=2038, - renewal_cost=500, + element_code=130, + element="WINDOWS", + sub_element_code=1, + sub_element="Windows", + material_code=1, + material_or_answer="UPVC Double Glazed", + renewal_quantity=8, + renewal_year=2036, + renewal_cost=4800, cloned="N", lo_type_code=1, - condition_survey_date=datetime(2024, 2, 15, 0, 0, 0), + condition_survey_date=datetime(2024, 2, 15, 12, 47, 0), ) ], ) + mapper = PeabodyMapper() + expected_assets: List[AssetCondition] = [ + AssetCondition( + uprn=1, + element=Element.EXTERNAL_WINDOWS, + aspect_type=AspectType.MATERIAL, + value="UPVC Double Glazed", + quantity=8, + install_date=None, + renewal_year=2036, + element_instance=None, + source_system=None, + comments=None, + ) + ] # act + actual_assets = mapper.map_asset_conditions_for_property(peabody_property) # assert - assert False # temp + assert len(actual_assets) == len(expected_assets) + + for i, (actual, expected) in enumerate(zip(actual_assets, expected_assets)): + assert actual == expected, f"Mismatch at index {i}"