Files
gexp/routers/search.py
T

155 lines
5.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from fastapi import APIRouter, Request
from fastapi.responses import Response
from fastapi.templating import Jinja2Templates
from services.template_utils import render_template
from services.search_service import (
get_person_with_properties,
search_persons,
search_properties,
)
router = APIRouter()
templates = Jinja2Templates(directory="templates")
@router.get("/search")
async def search(
request: Request,
q: str = "",
property_number: str = "",
district: str = "",
block: str = "",
):
persons = []
properties = []
selected_person = None
if q:
persons = search_persons(q)
if property_number or district or block:
properties = search_properties(property_number, district, block)
# If exactly one person found, preload their full details (across all scopes)
if len(persons) == 1 and not properties:
selected_person = get_person_with_properties(persons[0]["id"], None)
return render_template(
templates,
request,
"search.html",
{
"q": q,
"property_number": property_number,
"district": district,
"block": block,
"persons": persons,
"properties": properties,
"selected_person": selected_person,
},
)
@router.get("/persons/{person_id}")
async def person_detail(request: Request, person_id: int, search_scope: str = ""):
data = get_person_with_properties(person_id, search_scope.strip() or None)
if not data:
return render_template(
templates,
request,
"search.html",
{
"error": "Person not found",
"q": "",
"persons": [],
"properties": [],
"selected_person": None,
"property_number": "",
"district": "",
"block": "",
},
status_code=404,
)
return render_template(templates, request, "person_detail.html", data)
@router.get("/persons/{person_id}/export")
async def person_export_csv(person_id: int, qaza: str = ""):
import io
import csv
data = get_person_with_properties(person_id, qaza.strip() or None)
if not data:
return Response("Person not found", status_code=404)
person = data["person"]
properties = data["properties"]
output = io.StringIO()
# Write BOM for Excel to open Arabic UTF-8 correctly
output.write('\ufeff')
writer = csv.writer(output)
fullname_parts = [person.get("first_name", ""), person.get("father_name", ""), person.get("family_name", "")]
fullname = " ".join(f for f in fullname_parts if f)
writer.writerow(["بيانات الشخص"])
writer.writerow(["الاسم كامل", fullname])
writer.writerow(["رقم السجل", person.get("registry_number")])
writer.writerow(["مكان السجل", person.get("registry_place")])
writer.writerow(["تاريخ الولادة", person.get("birth_date")])
writer.writerow(["الهوا / المنشأ", person.get("family_origin")])
writer.writerow([])
# Document-level info (search scope, request numbers)
docs = data.get("documents", [])
if docs:
writer.writerow(["بيانات الوثائق"])
for d in docs:
parts = []
if d.get("request_number"):
parts.append(f"رقم الطلب: {d['request_number']}")
if d.get("request_date"):
parts.append(f"تاريخ: {d['request_date']}")
if d.get("search_scope"):
parts.append(f"القضاء: {d['search_scope']}")
if d.get("page_info"):
parts.append(f"صفحة: {d['page_info']}")
if parts:
writer.writerow(parts)
writer.writerow([])
writer.writerow(["العقارات المملوكة"])
writer.writerow(["اسم الفريق", "رقم العقار", "القسم", "البلوك", "المنطقة العقارية", "القضاء", "عدد الأسهم", "نوع الملكية"])
for p in properties:
writer.writerow([
p.get("party_name") or "",
p.get("property_number") or "",
p.get("section") or "",
p.get("block") or "",
p.get("real_estate_district") or "",
p.get("qaza") or "",
p.get("num_shares") or "",
p.get("ownership_type") or ""
])
content = output.getvalue()
# Safe filename use RFC 5987 encoding for Arabic characters
from urllib.parse import quote
safename = fullname.replace(" ", "_") or "person"
if qaza:
safe_qaza = qaza.replace(" ", "_").replace(":", "").replace("-", "")
safename += f"_{safe_qaza}"
encoded_name = quote(f"report_{safename}.csv")
return Response(
content=content,
media_type="text/csv",
headers={"Content-Disposition": f"attachment; filename=report.csv; filename*=UTF-8''{encoded_name}"}
)