import uuid from datetime import datetime, date from typing import Any from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select import openpyxl from app.models.customer import Customer from app.models.visit import Visit from app.models.work_plan import WorkPlan from app.models.mini_business import MiniBusiness from app.models.key_visit import KeyVisit from app.models.user import User async def import_from_excel(db: AsyncSession, file_bytes: bytes, manager_id: uuid.UUID) -> dict: """Parse old weekly report Excel and import data. Returns summary stats.""" wb = openpyxl.load_workbook(io.BytesIO(file_bytes), data_only=True) stats = {"visits": 0, "work_plans": 0, "mini_business": 0, "key_visits": 0, "skipped": 0, "skip_reasons": []} # Resolve customer name -> id cache customers_result = await db.execute(select(Customer.id, Customer.name)) customer_map = {c.name: c.id for c in customers_result.all()} # ── Parse Sheet 1: 每日拜访记录 ── if "每日拜访记录" in wb.sheetnames: ws = wb["每日拜访记录"] for row in ws.iter_rows(min_row=2, values_only=True): if not row[0]: continue try: cust_name, visit_date_str, visit_method, time_range, visitor_name, visitor_phone, content, demand, companions_str, mgr_str = \ row[0], str(row[1]) if row[1] else str(date.today()), \ str(row[2]) if row[2] else "上门", str(row[3]) if row[3] else "", \ str(row[4]) if row[4] else "", str(row[5]) if row[5] else "", \ str(row[6]) if row[6] else "", str(row[7]) if row[7] else "", \ str(row[8]) if row[8] else "", str(row[9]) if row[9] else "" customer_id = customer_map.get(cust_name) if not customer_id: stats["skipped"] += 1 stats["skip_reasons"].append(f"客户「{cust_name}」不存在,跳过") continue try: visit_date = datetime.strptime(visit_date_str[:10], "%Y-%m-%d").date() except ValueError: visit_date = date.today() existing = await db.execute( select(Visit).where( Visit.visit_date == visit_date, Visit.manager_id == manager_id, Visit.customer_id == customer_id, ) ) if existing.scalar_one_or_none(): stats["skipped"] += 1 stats["skip_reasons"].append(f"重复:{cust_name} {visit_date} 已存在") continue visit = Visit( customer_id=customer_id, visit_date=visit_date, visit_method=visit_method if visit_method in ["上门", "电话", "微信", "出差"] else "上门", time_range=time_range, visitor_name=visitor_name, visitor_phone=visitor_phone, communication_content=content, customer_demand=demand, manager_id=manager_id, ) db.add(visit) stats["visits"] += 1 except Exception: stats["skipped"] += 1 await db.commit() return stats import io