This commit is contained in:
Nitzan Pomerantz
2025-10-26 23:26:27 +02:00
parent bad0810053
commit 34af8362b9
3 changed files with 50 additions and 25 deletions
+15 -7
View File
@@ -6,7 +6,7 @@ Israeli real estate MCP system. Models provide validation, serialization,
and type safety throughout the codebase.
"""
from datetime import datetime
from datetime import date, datetime
from typing import Any, Dict, List, Optional
from pydantic import BaseModel, Field, field_validator, computed_field, ConfigDict
@@ -105,7 +105,7 @@ class Deal(BaseModel):
# Required fields
objectid: int = Field(..., description="Unique deal identifier")
deal_amount: float = Field(..., alias="dealAmount", description="Transaction amount in NIS")
deal_date: str = Field(..., alias="dealDate", description="Transaction date (ISO format)")
deal_date: date = Field(..., alias="dealDate", description="Transaction date")
# Common optional fields
asset_area: Optional[float] = Field(None, alias="assetArea", description="Property area in sqm")
@@ -150,13 +150,21 @@ class Deal(BaseModel):
@field_validator('deal_date', mode='before')
@classmethod
def parse_deal_date(cls, v: Any) -> str:
"""Parse deal date to ISO format string."""
if isinstance(v, str):
def parse_deal_date(cls, v: Any) -> date:
"""Parse deal date string into a date object."""
if isinstance(v, date):
return v
if isinstance(v, datetime):
return v.isoformat()
return str(v)
return v.date()
if isinstance(v, str):
# Handle ISO format with optional time and timezone
if 'T' in v:
v = v.split('T')[0]
try:
return date.fromisoformat(v)
except ValueError:
raise ValueError(f"Invalid date format: {v}")
raise TypeError(f"Unsupported type for date parsing: {type(v)}")
class DealStatistics(BaseModel):
+7 -2
View File
@@ -6,10 +6,13 @@ This module provides pure mathematical functions for analyzing real estate deal
from collections import Counter
from typing import List
from datetime import datetime
import logging
from datetime import date
from .models import Deal, DealStatistics
logger = logging.getLogger(__name__)
def calculate_deal_statistics(deals: List[Deal]) -> DealStatistics:
"""
@@ -127,6 +130,7 @@ def calculate_deal_statistics(deals: List[Deal]) -> DealStatistics:
date_str = date_str.split('T')[0]
parsed_dates.append(date_str)
except (ValueError, TypeError):
logger.warning(f"Invalid date format: {date_str}")
continue
if parsed_dates:
@@ -135,7 +139,8 @@ def calculate_deal_statistics(deals: List[Deal]) -> DealStatistics:
"earliest": sorted_dates[0],
"latest": sorted_dates[-1],
}
except:
except (ValueError, TypeError):
logger.warning("Invalid date format: {date_range_dict}")
pass
return DealStatistics(
+22 -10
View File
@@ -427,21 +427,33 @@ class TestModelIntegration:
def test_deal_to_statistics_workflow(self):
"""Test creating deals and calculating statistics."""
# Import the function to test integration
from nadlan_mcp.govmap.statistics import calculate_deal_statistics
deals = [
Deal(
objectid=i,
deal_amount=1500000.0 + (i * 10000),
deal_date=f"2024-01-{i+1:02d}",
asset_area=80.0 + i,
objectid=1,
deal_amount=1000000.0,
deal_date="2024-01-01",
asset_area=100.0,
property_type_description="דירה"
)
for i in range(10)
),
Deal(
objectid=2,
deal_amount=2000000.0,
deal_date="2024-01-02",
asset_area=100.0,
property_type_description="דירה"
),
]
# Verify all deals have price_per_sqm
for deal in deals:
assert deal.price_per_sqm is not None
assert deal.price_per_sqm > 0
stats = calculate_deal_statistics(deals)
assert isinstance(stats, DealStatistics)
assert stats.total_deals == 2
assert stats.price_statistics["mean"] == 1500000.0
assert stats.price_per_sqm_statistics["mean"] == 15000.0
assert stats.property_type_distribution["דירה"] == 2
def test_autocomplete_to_deals_workflow(self):
"""Test autocomplete response leading to deal search."""