diff --git a/app.py b/app.py index 6040f82..c50a001 100644 --- a/app.py +++ b/app.py @@ -2,8 +2,9 @@ import json import os from functools import wraps from datetime import datetime, timedelta +import pytz -from flask import Flask, render_template, request, redirect, url_for, session, abort, jsonify +from flask import Flask, render_template, request, redirect, url_for, session, abort, jsonify from dotenv import load_dotenv import firebase_admin from firebase_admin import credentials, auth as fb_auth, firestore @@ -92,6 +93,35 @@ def get_user_profile(uid: str): return {"enabled": bool(data.get("enabled", False)), "caseEmail": data.get("caseEmail")} +def convert_to_pacific_time(date_str): + """Convert UTC date string to Pacific Time and format as YYYY-MM-DD. + + Args: + date_str (str): UTC date string in ISO 8601 format (e.g., "2025-10-24T19:20:22.377Z") + + Returns: + str: Date formatted as YYYY-MM-DD in Pacific Time, or empty string if input is empty + """ + if not date_str: + return '' + + try: + # Parse the UTC datetime + utc_time = datetime.fromisoformat(date_str.replace('Z', '+00:00')) + + # Set timezone to UTC + utc_time = utc_time.replace(tzinfo=pytz.UTC) + + # Convert to Pacific Time + pacific_time = utc_time.astimezone(pytz.timezone('America/Los_Angeles')) + + # Format as YYYY-MM-DD + return pacific_time.strftime('%Y-%m-%d') + except (ValueError, AttributeError) as e: + print(f"[WARN] Date conversion failed for '{date_str}': {e}") + return '' + + def fetch_all_projects(): """Fetch all projects for a user and store them in Firestore""" @@ -130,12 +160,12 @@ def fetch_all_projects(): lease_info_np = fetch_form(bearer, pid, "leaseInfoNP") or {} completed_tasks = [{"description": x.get("body") , - "completed": x.get("completedDate")} - for x in fetch_project_tasks(bearer, pid).get("items") + "completed": convert_to_pacific_time(x.get("completedDate"))} + for x in fetch_project_tasks(bearer, pid).get("items") if x.get("isCompleted")] pending_tasks = [{"description": x.get("body") , - "completed": x.get("completedDate")} - for x in fetch_project_tasks(bearer, pid).get("items") + "completed": convert_to_pacific_time(x.get("completedDate"))} + for x in fetch_project_tasks(bearer, pid).get("items") if not x.get("isCompleted")] team = fetch_project_team(bearer, pid) @@ -153,31 +183,31 @@ def fetch_all_projects(): ), '') # Extract notice service and expiration dates - notice_service_date = new_file_review.get("noticeServiceDate") or '' - notice_expiration_date = new_file_review.get("noticeExpirationDate") or '' + notice_service_date = convert_to_pacific_time(new_file_review.get("noticeServiceDate")) or '' + notice_expiration_date = convert_to_pacific_time(new_file_review.get("noticeExpirationDate")) or '' # Extract daily rent damages daily_rent_damages = lease_info_np.get("dailyRentDamages") or dates_and_deadlines.get("dailyRentDamages") or '' # Extract default date - default_date = dates_and_deadlines.get("defaultDate") or '' - case_filed_date = dates_and_deadlines.get("dateCaseFiled") or '' + default_date = convert_to_pacific_time(dates_and_deadlines.get("defaultDate")) or '' + case_filed_date = convert_to_pacific_time(dates_and_deadlines.get("dateCaseFiled")) or '' # Extract motion hearing dates - demurrer_hearing_date = dates_and_deadlines.get("demurrerHearingDate") or '' - motion_to_strike_hearing_date = dates_and_deadlines.get("mTSHearingDate") or '' - motion_to_quash_hearing_date = dates_and_deadlines.get("mTQHearingDate") or '' - other_motion_hearing_date = dates_and_deadlines.get("otherMotion1HearingDate") or '' + demurrer_hearing_date = convert_to_pacific_time(dates_and_deadlines.get("demurrerHearingDate")) or '' + motion_to_strike_hearing_date = convert_to_pacific_time(dates_and_deadlines.get("mTSHearingDate")) or '' + motion_to_quash_hearing_date = convert_to_pacific_time(dates_and_deadlines.get("mTQHearingDate")) or '' + other_motion_hearing_date = convert_to_pacific_time(dates_and_deadlines.get("otherMotion1HearingDate")) or '' # Extract MSC details - msc_date = dates_and_deadlines.get("mSCDate") or '' - msc_time = dates_and_deadlines.get("mSCTime") or '' + msc_date = convert_to_pacific_time(dates_and_deadlines.get("mSCDate")) or '' + msc_time = dates_and_deadlines.get("mSCTime") or '' # Time field, not converting msc_address = dates_and_deadlines.get("mSCAddress") or '' msc_div_dept_room = dates_and_deadlines.get("mSCDeptDiv") or '' # Extract trial details - trial_date = dates_and_deadlines.get("trialDate") or '' - trial_time = dates_and_deadlines.get("trialTime") or '' + trial_date = convert_to_pacific_time(dates_and_deadlines.get("trialDate")) or '' + trial_time = dates_and_deadlines.get("trialTime") or '' # Time field, not converting trial_address = dates_and_deadlines.get("trialAddress") or '' trial_div_dept_room = dates_and_deadlines.get("trialDeptDivRoom") or '' @@ -185,16 +215,16 @@ def fetch_all_projects(): final_result = dates_and_deadlines.get("finalResultOfTrialMSCCa") or '' # Extract settlement details - date_of_settlement = dates_and_deadlines.get("dateOfStipulation") or '' + date_of_settlement = convert_to_pacific_time(dates_and_deadlines.get("dateOfStipulation")) or '' final_obligation = dates_and_deadlines.get("finalObligationUnderTheStip") or '' def_comply_stip = dates_and_deadlines.get("defendantsComplyWithStip") or '' # Extract judgment and writ details - judgment_date = dates_and_deadlines.get("dateOfJudgment") or '' - writ_issued_date = dates_and_deadlines.get("writIssuedDate") or '' + judgment_date = convert_to_pacific_time(dates_and_deadlines.get("dateOfJudgment")) or '' + writ_issued_date = convert_to_pacific_time(dates_and_deadlines.get("writIssuedDate")) or '' # Extract lockout and stay details - scheduled_lockout = dates_and_deadlines.get("sheriffScheduledDate") or '' + scheduled_lockout = convert_to_pacific_time(dates_and_deadlines.get("sheriffScheduledDate")) or '' oppose_stays = dates_and_deadlines.get("opposeStays") or '' # Extract premises safety and entry code @@ -202,7 +232,7 @@ def fetch_all_projects(): matter_gate_code = property_info.get("propertyEntryCodeOrInstructions") or '' # Extract possession recovered date - date_possession_recovered = dates_and_deadlines.get("datePossessionRecovered") or '' + date_possession_recovered = convert_to_pacific_time(dates_and_deadlines.get("datePossessionRecovered")) or '' # Extract attorney fees and costs attorney_fees = fees_and_costs.get("attorneyFeesTotal") or '' @@ -212,7 +242,7 @@ def fetch_all_projects(): "client": c.get("firstName"), "matter_description": p.get("projectName"), "defendant_1": defendant_one.get('fullName', 'Unknown'), - "matter_open": dates_and_deadlines.get("dateCaseFiled") or p.get("createdDate"), + "matter_open": convert_to_pacific_time(dates_and_deadlines.get("dateCaseFiled") or p.get("createdDate")), "notice_type": new_file_review.get("noticeType", '') or '', "case_number": dates_and_deadlines.get('caseNumber', '') or '', "premises_address": property_info.get("premisesAddressWithUnit") or '', @@ -254,11 +284,11 @@ def fetch_all_projects(): "attorney_fees": attorney_fees, "costs": costs, "documents_url": matter_overview.get('documentShareFolderURL') or '', - "service_attempt_date_1": next(iter(service_info), {}).get('serviceDate'), + "service_attempt_date_1": convert_to_pacific_time(next(iter(service_info), {}).get('serviceDate')), "contacts": cs, "ProjectEmailAddress": p.get("projectEmailAddress"), "Number": p.get("number"), - "IncidentDate": (p.get("incidentDate") or detail.get("incidentDate")), + "IncidentDate": convert_to_pacific_time(p.get("incidentDate") or detail.get("incidentDate")), "ProjectId": pid, "ProjectName": p.get("projectName") or detail.get("projectName"), "ProjectUrl": p.get("projectUrl") or detail.get("projectUrl"), diff --git a/requirements.txt b/requirements.txt index fd09c07..7677532 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,3 +4,4 @@ python-dotenv==1.0.1 requests==2.32.3 itsdangerous==2.2.0 gunicorn==23.0.0 +pytz diff --git a/templates/base.html b/templates/base.html index 5370bf7..d457eca 100644 --- a/templates/base.html +++ b/templates/base.html @@ -9,10 +9,10 @@ - +
- Filevine Demo + Rothbard Law Group - Cases
-
+
{% block content %}{% endblock %}
diff --git a/templates/dashboard.html b/templates/dashboard.html index b64161f..9c053fb 100644 --- a/templates/dashboard.html +++ b/templates/dashboard.html @@ -1,10 +1,12 @@ {% extends 'base.html' %} {% block content %} -
-

Projects for {{ case_email }}

-
+
+

Projects for {{ case_email }}

+ +
- + @@ -235,7 +237,11 @@
Matter Num Client / Property
+
+ {% endblock %} \ No newline at end of file