MIPESCA_test / models.py
Edoruin's picture
fix: update CaptureItem schema to match enriched frontend payload
770e172
"""Data models for Mi Pesca RD application."""
from dataclasses import dataclass, field
from datetime import datetime
from typing import List, Optional, Literal
@dataclass
class ClosedSeason:
"""Closed season information for a species."""
start: str # MM-DD format
end: str # MM-DD format
description: str
@dataclass
class Species:
"""Species data model."""
id: str
commonName: str
scientificName: str
category: Literal['Peces', 'Crustáceos', 'Moluscos', 'Fondo', 'Pelágico', 'Invertebrado']
imageUrl: str
protected: bool
closedSeason: Optional[ClosedSeason] = None
def to_dict(self):
"""Convert to dictionary for JSON serialization."""
data = {
'id': self.id,
'commonName': self.commonName,
'scientificName': self.scientificName,
'category': self.category,
'imageUrl': self.imageUrl,
'protected': self.protected
}
if self.closedSeason:
data['closedSeason'] = {
'start': self.closedSeason.start,
'end': self.closedSeason.end,
'description': self.closedSeason.description
}
return data
@dataclass
class CaptureItem:
"""Individual capture item (species with quantity)."""
speciesId: str
quantity: float
unit: Literal['lbs', 'units']
customName: Optional[str] = None
commonName: Optional[str] = None
category: Optional[str] = None
def to_dict(self):
"""Convert to dictionary for JSON serialization."""
return {
'speciesId': self.speciesId,
'quantity': self.quantity,
'unit': self.unit,
'customName': self.customName,
'commonName': self.commonName,
'category': self.category
}
@dataclass
class Capture:
"""Capture data model."""
id: str
timestamp: datetime
latitude: float
longitude: float
species: List[str]
items: List[CaptureItem]
fishingMethod: str
depth: float
synced: bool
# Simplified fields
port: Optional[str] = None
phone: Optional[str] = None
userId: Optional[str] = None
placeName: Optional[str] = None
totalWeight: float = 0
captureSource: str = 'device-gps'
syncedAt: Optional[datetime] = None
temperature: Optional[float] = None
seaState: Optional[str] = None
def to_dict(self):
"""Convert to dictionary for JSON serialization."""
return {
'id': self.id,
'timestamp': self.timestamp.isoformat() if isinstance(self.timestamp, datetime) else self.timestamp,
'latitude': self.latitude,
'longitude': self.longitude,
'species': self.species,
'items': [item.to_dict() if hasattr(item, 'to_dict') else item for item in self.items],
'fishingMethod': self.fishingMethod,
'depth': self.depth,
'synced': self.synced,
'port': self.port,
'phone': self.phone,
'userId': self.userId,
'placeName': self.placeName,
'totalWeight': self.totalWeight,
'captureSource': self.captureSource,
'syncedAt': self.syncedAt.isoformat() if self.syncedAt and isinstance(self.syncedAt, datetime) else self.syncedAt,
'temperature': self.temperature,
'seaState': self.seaState
}
@classmethod
def from_dict(cls, data: dict):
"""Create Capture instance from dictionary."""
items = []
for item in data.get('items', []):
if isinstance(item, dict):
items.append(CaptureItem(**item))
else:
items.append(item)
timestamp = data.get('timestamp')
if isinstance(timestamp, str):
timestamp = datetime.fromisoformat(timestamp.replace('Z', '+00:00'))
syncedAt = data.get('syncedAt')
if syncedAt and isinstance(syncedAt, str):
syncedAt = datetime.fromisoformat(syncedAt.replace('Z', '+00:00'))
return cls(
id=data.get('id'),
timestamp=timestamp,
latitude=data.get('latitude'),
longitude=data.get('longitude'),
species=data.get('species', []),
items=items,
fishingMethod=data.get('fishingMethod'),
depth=data.get('depth'),
synced=data.get('synced', False),
port=data.get('port'),
phone=data.get('phone'),
userId=data.get('userId'),
placeName=data.get('placeName'),
totalWeight=data.get('totalWeight', 0),
captureSource=data.get('captureSource', 'device-gps'),
syncedAt=syncedAt,
temperature=data.get('temperature'),
seaState=data.get('seaState')
)