""" Shared data model for Project entities used across the application. This defines the structure of project data that is fetched from Filevine and stored in Firestore. """ from typing import List, Dict, Any, Optional from datetime import datetime import pytz class ProjectModel: """ Data model for a Filevine project with all its associated fields. This model defines the structure that will be used for Firestore storage and API responses. """ def __init__(self, client: str = "", matter_description: str = "", defendant_1: str = "", matter_open: str = "", notice_type: str = "", case_number: str = "", premises_address: str = "", premises_city: str = "", responsible_attorney: str = "", staff_person: str = "", staff_person_2: str = "", phase_name: str = "", completed_tasks: List[Dict[str, Any]] = None, pending_tasks: List[Dict[str, Any]] = None, notice_service_date: str = "", notice_expiration_date: str = "", case_filed_date: str = "", case_field_date: str = "", daily_rent_damages: str = "", default_date: str = "", demurrer_hearing_date: str = "", motion_to_strike_hearing_date: str = "", motion_to_quash_hearing_date: str = "", other_motion_hearing_date: str = "", msc_date: str = "", msc_time: str = "", msc_address: str = "", msc_div_dept_room: str = "", trial_date: str = "", trial_time: str = "", trial_address: str = "", trial_div_dept_room: str = "", final_result: str = "", date_of_settlement: str = "", final_obligation: str = "", def_comply_stip: str = "", judgment_date: str = "", writ_issued_date: str = "", scheduled_lockout: str = "", oppose_stays: str = "", premises_safety: str = "", matter_gate_code: str = "", date_possession_recovered: str = "", attorney_fees: str = "", costs: str = "", documents_url: str = "", service_attempt_date_1: str = "", contacts: List[Dict[str, Any]] = None, project_email_address: str = "", number: str = "", incident_date: str = "", project_id: str = "", project_name: str = "", project_url: str = "", property_contacts: Dict[str, Any] = None, viewing_emails: List[str] = None, viewing_domains: List[str] = None ): self.client = client self.matter_description = matter_description self.defendant_1 = defendant_1 self.matter_open = matter_open self.notice_type = notice_type self.case_number = case_number self.premises_address = premises_address self.premises_city = premises_city self.responsible_attorney = responsible_attorney self.staff_person = staff_person self.staff_person_2 = staff_person_2 self.phase_name = phase_name self.completed_tasks = completed_tasks or [] self.pending_tasks = pending_tasks or [] self.notice_service_date = notice_service_date self.notice_expiration_date = notice_expiration_date self.case_filed_date = case_filed_date or case_field_date self.case_field_date = case_field_date self.daily_rent_damages = daily_rent_damages self.default_date = default_date self.demurrer_hearing_date = demurrer_hearing_date self.motion_to_strike_hearing_date = motion_to_strike_hearing_date self.motion_to_quash_hearing_date = motion_to_quash_hearing_date self.other_motion_hearing_date = other_motion_hearing_date self.msc_date = msc_date self.msc_time = msc_time self.msc_address = msc_address self.msc_div_dept_room = msc_div_dept_room self.trial_date = trial_date self.trial_time = trial_time self.trial_address = trial_address self.trial_div_dept_room = trial_div_dept_room self.final_result = final_result self.date_of_settlement = date_of_settlement self.final_obligation = final_obligation self.def_comply_stip = def_comply_stip self.judgment_date = judgment_date self.writ_issued_date = writ_issued_date self.scheduled_lockout = scheduled_lockout self.oppose_stays = oppose_stays self.premises_safety = premises_safety self.matter_gate_code = matter_gate_code self.date_possession_recovered = date_possession_recovered self.attorney_fees = attorney_fees self.costs = costs self.documents_url = documents_url self.service_attempt_date_1 = service_attempt_date_1 self.contacts = contacts or [] self.project_email_address = project_email_address self.number = number self.incident_date = incident_date self.project_id = project_id self.project_name = project_name self.project_url = project_url self.property_contacts = property_contacts or {} self.viewing_emails = viewing_emails or [] self.viewing_domains = viewing_domains or [] def to_dict(self) -> Dict[str, Any]: """Convert the ProjectModel to a dictionary for Firestore storage.""" return { "client": self.client, "matter_description": self.matter_description, "defendant_1": self.defendant_1, "matter_open": self.matter_open, "notice_type": self.notice_type, "case_number": self.case_number, "premises_address": self.premises_address, "premises_city": self.premises_city, "responsible_attorney": self.responsible_attorney, "staff_person": self.staff_person, "staff_person_2": self.staff_person_2, "phase_name": self.phase_name, "completed_tasks": self.completed_tasks, "pending_tasks": self.pending_tasks, "notice_service_date": self.notice_service_date, "notice_expiration_date": self.notice_expiration_date, "case_filed_date": self.case_filed_date, "case_field_date": self.case_field_date, "daily_rent_damages": self.daily_rent_damages, "default_date": self.default_date, "demurrer_hearing_date": self.demurrer_hearing_date, "motion_to_strike_hearing_date": self.motion_to_strike_hearing_date, "motion_to_quash_hearing_date": self.motion_to_quash_hearing_date, "other_motion_hearing_date": self.other_motion_hearing_date, "msc_date": self.msc_date, "msc_time": self.msc_time, "msc_address": self.msc_address, "msc_div_dept_room": self.msc_div_dept_room, "trial_date": self.trial_date, "trial_time": self.trial_time, "trial_address": self.trial_address, "trial_div_dept_room": self.trial_div_dept_room, "final_result": self.final_result, "date_of_settlement": self.date_of_settlement, "final_obligation": self.final_obligation, "def_comply_stip": self.def_comply_stip, "judgment_date": self.judgment_date, "writ_issued_date": self.writ_issued_date, "scheduled_lockout": self.scheduled_lockout, "oppose_stays": self.oppose_stays, "premises_safety": self.premises_safety, "matter_gate_code": self.matter_gate_code, "date_possession_recovered": self.date_possession_recovered, "attorney_fees": self.attorney_fees, "costs": self.costs, "documents_url": self.documents_url, "service_attempt_date_1": self.service_attempt_date_1, "contacts": self.contacts, "ProjectEmailAddress": self.project_email_address, "number": self.number, "IncidentDate": self.incident_date, "ProjectId": self.project_id, "ProjectName": self.project_name, "ProjectUrl": self.project_url, "property_contacts": self.property_contacts, "viewing_emails": self.viewing_emails, "viewing_domains": self.viewing_domains } @classmethod def from_dict(cls, data: Dict[str, Any]) -> 'ProjectModel': """Create a ProjectModel instance from a dictionary (e.g., from Firestore).""" return cls( client=data.get("client", ""), matter_description=data.get("matter_description", ""), defendant_1=data.get("defendant_1", ""), matter_open=data.get("matter_open", ""), notice_type=data.get("notice_type", ""), case_number=data.get("case_number", ""), premises_address=data.get("premises_address", ""), premises_city=data.get("premises_city", ""), responsible_attorney=data.get("responsible_attorney", ""), staff_person=data.get("staff_person", ""), staff_person_2=data.get("staff_person_2", ""), phase_name=data.get("phase_name", ""), completed_tasks=data.get("completed_tasks", []), pending_tasks=data.get("pending_tasks", []), notice_service_date=data.get("notice_service_date", ""), notice_expiration_date=data.get("notice_expiration_date", ""), case_filed_date=data.get("case_filed_date", ""), case_field_date=data.get("case_field_date", ""), daily_rent_damages=data.get("daily_rent_damages", ""), default_date=data.get("default_date", ""), demurrer_hearing_date=data.get("demurrer_hearing_date", ""), motion_to_strike_hearing_date=data.get("motion_to_strike_hearing_date", ""), motion_to_quash_hearing_date=data.get("motion_to_quash_hearing_date", ""), other_motion_hearing_date=data.get("other_motion_hearing_date", ""), msc_date=data.get("msc_date", ""), msc_time=data.get("msc_time", ""), msc_address=data.get("msc_address", ""), msc_div_dept_room=data.get("msc_div_dept_room", ""), trial_date=data.get("trial_date", ""), trial_time=data.get("trial_time", ""), trial_address=data.get("trial_address", ""), trial_div_dept_room=data.get("trial_div_dept_room", ""), final_result=data.get("final_result", ""), date_of_settlement=data.get("date_of_settlement", ""), final_obligation=data.get("final_obligation", ""), def_comply_stip=data.get("def_comply_stip", ""), judgment_date=data.get("judgment_date", ""), writ_issued_date=data.get("writ_issued_date", ""), scheduled_lockout=data.get("scheduled_lockout", ""), oppose_stays=data.get("oppose_stays", ""), premises_safety=data.get("premises_safety", ""), matter_gate_code=data.get("matter_gate_code", ""), date_possession_recovered=data.get("date_possession_recovered", ""), attorney_fees=data.get("attorney_fees", ""), costs=data.get("costs", ""), documents_url=data.get("documents_url", ""), service_attempt_date_1=data.get("service_attempt_date_1", ""), contacts=data.get("contacts", []), project_email_address=data.get("ProjectEmailAddress", ""), number=data.get("Number", ""), incident_date=data.get("IncidentDate", ""), project_id=data.get("ProjectId", ""), project_name=data.get("ProjectName", ""), project_url=data.get("ProjectUrl", ""), property_contacts=data.get("property_contacts", {}), viewing_emails=data.get("viewing_emails", []), viewing_domains=data.get("viewing_domains", []) )