from __future__ import annotations from datetime import date, datetime from typing import Any from pydantic import BaseModel, Field class OverviewMetric(BaseModel): code: str label: str value: str unit: str | None = None highlight: str = "normal" note: str | None = None class AlertItem(BaseModel): level: str title: str description: str owner: str action: str class FlowStep(BaseModel): step_code: str title: str status: str summary: str quantity: str class BoardSection(BaseModel): title: str items: list[FlowStep] class DashboardPayload(BaseModel): company: str overview: list[OverviewMetric] alerts: list[AlertItem] flow_board: list[BoardSection] class DashboardSalesOrderRead(BaseModel): order_id: int order_no: str customer_code: str | None = None customer_name: str order_date: date promised_date: date | None = None delivery_address: str | None = None total_amount: float status: str line_count: int total_order_qty: float total_delivered_qty: float mrp_count: int purchase_order_count: int work_order_count: int completion_receipt_count: int delivery_count: int return_count: int updated_at: datetime | None = None class DashboardMaterialLotRead(BaseModel): lot_id: int lot_no: str material_item_id: int material_code: str material_name: str specification: str | None = None warehouse_name: str inbound_weight_kg: float remaining_weight_kg: float unit_cost: float inbound_amount: float issued_batch_count: int issued_weight_kg: float finished_batch_count: int finished_qty: float delivery_count: int status: str quality_status: str created_at: datetime | None = None class LifecycleDetailItem(BaseModel): label: str value: str class LifecycleNode(BaseModel): id: str type: str title: str subtitle: str | None = None status: str | None = None stage: str level: int tone: str = "normal" summary: str | None = None metrics: list[LifecycleDetailItem] = Field(default_factory=list) details: list[LifecycleDetailItem] = Field(default_factory=list) raw: dict[str, Any] = Field(default_factory=dict) class LifecycleEdge(BaseModel): id: str source: str target: str label: str | None = None class SalesOrderLifecycleRead(BaseModel): order: DashboardSalesOrderRead nodes: list[LifecycleNode] edges: list[LifecycleEdge] class MaterialLotLifecycleRead(BaseModel): lot: DashboardMaterialLotRead nodes: list[LifecycleNode] edges: list[LifecycleEdge]