"""Field mapping utilities for mobile.de listing format conversion.""" from __future__ import annotations from datetime import date from decimal import Decimal from typing import Any from app.models.vehicle import Vehicle # mobile.de category mapping based on vehicle_type _CATEGORY_MAP: dict[str, str] = { "lkw": "Truck", "pkw": "Car", "baumaschine": "ConstructionMachine", "stapler": "ForkliftTruck", "transporter": "Van", } # LKW sub-type mapping for mobile.de category refinement _LKW_TYPE_MAP: dict[str, str] = { "sattelzugmaschine": "SemiTractor", "sattelauflieger": "SemiTrailer", "kipper": "Tipper", "kuehlmobil": "RefrigeratedVehicle", "tieflader": "LowLoader", "silofahrzeug": "SiloVehicle", "tankwagen": "TankVehicle", "kranwagen": "CraneVehicle", "muldenkipper": "DumperTruck", "sattelkipper": "SemiTipper", "schwertransporter": "HeavyTransporter", "sonderkonstruktion": "SpecialConstruction", "pritsche": "Flatbed", "planenlkw": "TarpaulinTruck", "boxenlkw": "BoxBodyTruck", "iso_lkw": "IsoTruck", } def _format_first_registration(reg_date: date | None) -> str | None: """Convert date to YYYY-MM format for mobile.de.""" if reg_date is None: return None return reg_date.strftime("%Y-%m") def _format_mileage(vehicle: Vehicle) -> dict[str, Any] | None: """Map mileage or operating hours to mobile.de mileage field.""" if vehicle.mileage_km is not None: return {"value": vehicle.mileage_km, "unit": "km"} if vehicle.operating_hours is not None: unit = vehicle.operating_hours_unit or "h" return {"value": float(vehicle.operating_hours), "unit": unit} return None def _format_price(price: Decimal) -> dict[str, Any]: """Map price to mobile.de price format.""" return { "amount": float(price), "currency": "EUR", } def _format_power(power_kw: int | None, power_hp: int | None) -> dict[str, Any] | None: """Map power to mobile.de power format.""" if power_kw is None and power_hp is None: return None return { "powerKw": power_kw, "powerHp": power_hp, } def _format_category(vehicle: Vehicle) -> str: """Determine mobile.de category from vehicle type and lkw_type.""" base = _CATEGORY_MAP.get(vehicle.vehicle_type, "Other") if vehicle.vehicle_type == "lkw" and vehicle.lkw_type: # Try direct match, then strip lkw_ prefix for lookup lkw_key = vehicle.lkw_type if lkw_key in _LKW_TYPE_MAP: return _LKW_TYPE_MAP[lkw_key] stripped = lkw_key.removeprefix("lkw_") if stripped in _LKW_TYPE_MAP: return _LKW_TYPE_MAP[stripped] return base return base def map_fields(vehicle: Vehicle) -> dict[str, Any]: """Map a Vehicle model to the mobile.de listing Ad format. Converts internal vehicle fields to the mobile.de REST API listing format. See: https://developer.mobile.de/api/seller-listings """ mileage = _format_mileage(vehicle) power = _format_power(vehicle.power_kw, vehicle.power_hp) ad: dict[str, Any] = { "vin": vehicle.fin, "make": vehicle.make, "model": vehicle.model, "category": _format_category(vehicle), "price": _format_price(vehicle.price), "availabilityStatus": vehicle.availability, "condition": vehicle.condition, } if vehicle.first_registration is not None: ad["firstRegistration"] = _format_first_registration( vehicle.first_registration ) if mileage is not None: ad["mileage"] = mileage if power is not None: ad["power"] = power if vehicle.fuel_type is not None: ad["fuelType"] = vehicle.fuel_type if vehicle.transmission is not None: ad["transmission"] = vehicle.transmission if vehicle.color is not None: ad["color"] = vehicle.color if vehicle.year is not None: ad["year"] = vehicle.year if vehicle.location is not None: ad["sellerLocation"] = vehicle.location if vehicle.machine_type is not None: ad["bodyType"] = vehicle.machine_type elif vehicle.body_type is not None: ad["bodyType"] = vehicle.body_type if vehicle.description is not None: ad["description"] = vehicle.description return ad