import datetime from collections import defaultdict from typing import List, Optional, Union, Dict, Tuple, TypedDict from pydantic import constr, field_validator from models import ServiceCategoryPrice, ServicePriceCategory, Deal, Product, DealProduct, DealStatusHistory from schemas.base import BaseSchema, OkMessageSchema from schemas.billing import DealBillRequestSchema,GroupBillRequestSchema from schemas.client import ClientSchema from schemas.marketplace import BaseMarketplaceSchema from schemas.product import ProductSchema from schemas.service import ServiceSchema, ServicePriceCategorySchema from schemas.shipping import PalletSchema, BoxSchema from schemas.shipping_warehouse import ShippingWarehouseSchema from schemas.user import UserSchema # region Entities class FastDeal(BaseSchema): name: str client: ClientSchema comment: str acceptance_date: datetime.datetime class DealGroupSchema(BaseSchema): id: int name: Optional[str] = None lexorank: str bill_request: Optional[GroupBillRequestSchema] = None class DealSummary(BaseSchema): id: int name: str client_name: str changed_at: datetime.datetime created_at: datetime.datetime deadline: Optional[datetime.datetime] = None status: int total_price: int rank: int base_marketplace: Optional[BaseMarketplaceSchema] = None total_products: int shipment_warehouse_id: Optional[int] shipment_warehouse_name: Optional[str] delivery_date: Optional[datetime.datetime] = None receiving_slot_date: Optional[datetime.datetime] = None bill_request: Optional[DealBillRequestSchema] = None group: Optional[DealGroupSchema] = None class DealServiceSchema(BaseSchema): service: ServiceSchema quantity: int price: int employees: List[UserSchema] is_fixed_price: bool class DealProductServiceSchema(BaseSchema): service: ServiceSchema price: int employees: List[UserSchema] is_fixed_price: bool class DealProductSchema(BaseSchema): product: ProductSchema services: List[DealProductServiceSchema] quantity: int comment: str = "" class DealStatusHistorySchema(BaseSchema): user: UserSchema changed_at: datetime.datetime from_status: int to_status: int next_status_deadline: datetime.datetime | None comment: str | None = None class AssignmentSchema(BaseSchema): user: UserSchema created_at: datetime.datetime class DealSchema(BaseSchema): id: int name: str client_id: int created_at: datetime.datetime current_status: int services: List[DealServiceSchema] products: List[DealProductSchema] status_history: List[DealStatusHistorySchema] is_deleted: bool is_completed: bool is_locked: bool client: ClientSchema comment: str shipping_warehouse: Optional[Union[ShippingWarehouseSchema, str]] = None bill_request: Optional[DealBillRequestSchema] = None category: Optional[ServicePriceCategorySchema] = None group: Optional[DealGroupSchema] = None manager: Optional[UserSchema] = None pallets: List[PalletSchema] = [] boxes: List[BoxSchema] = [] assignments: List[AssignmentSchema] = [] delivery_date: Optional[datetime.datetime] = None receiving_slot_date: Optional[datetime.datetime] = None class DealGeneralInfoSchema(BaseSchema): name: str is_deleted: bool is_completed: bool comment: str shipping_warehouse: Optional[str] = None delivery_date: Optional[datetime.datetime] = None receiving_slot_date: Optional[datetime.datetime] = None manager: Optional[UserSchema] = None # endregion Entities # region Requests class DealChangeStatusRequest(BaseSchema): deal_id: int new_status: int class DealCreateRequest(BaseSchema): name: str class DealQuickCreateRequest(BaseSchema): name: constr(strip_whitespace=True) client_name: constr(strip_whitespace=True) comment: str acceptance_date: datetime.datetime shipping_warehouse: constr(strip_whitespace=True) base_marketplace: BaseMarketplaceSchema category: Optional[ServicePriceCategorySchema] = None class DealSummaryRequest(BaseSchema): pass class DealAddServicesRequest(BaseSchema): deal_id: int services: list[DealServiceSchema] class DealUpdateServiceQuantityRequest(BaseSchema): deal_id: int service_id: int quantity: int class DealUpdateServiceRequest(BaseSchema): deal_id: int service: DealServiceSchema class DealAddServiceRequest(BaseSchema): deal_id: int service_id: int quantity: int price: int class DealDeleteServiceRequest(BaseSchema): deal_id: int service_id: int class DealDeleteServicesRequest(BaseSchema): deal_id: int service_ids: List[int] class DealUpdateProductQuantityRequest(BaseSchema): deal_id: int product_id: int quantity: int class DealAddProductRequest(BaseSchema): deal_id: int product: DealProductSchema class DealDeleteProductRequest(BaseSchema): deal_id: int product_id: int class DealDeleteProductsRequest(BaseSchema): deal_id: int product_ids: List[int] class DealUpdateGeneralInfoRequest(BaseSchema): deal_id: int data: DealGeneralInfoSchema class DealSummaryReorderRequest(BaseSchema): deal_id: int status: int index: int deadline: datetime.datetime | None = None comment: str | None = None class DealDeleteRequest(BaseSchema): deal_id: int class DealUpdateProductRequest(BaseSchema): deal_id: int product: DealProductSchema class DealServicesCopyRequest(BaseSchema): deal_id: int source_product_id: int destination_product_ids: List[int] class DealProductAddKitRequest(BaseSchema): deal_id: int product_id: int kit_id: int class DealAddKitRequest(BaseSchema): deal_id: int kit_id: int class DealCreateGuestUrlRequest(BaseSchema): deal_id: int class DealCompleteRequest(BaseSchema): deal_id: int class DealPrefillRequest(BaseSchema): old_deal_id: int new_deal_id: int class DealRecalculatePriceRequest(BaseSchema): deal_id: int class ManageEmployeeRequest(BaseSchema): deal_id: int user_id: int is_assign: bool class DealAddToGroupRequest(BaseSchema): deal_id: int group_id: int class DealCreateGroupRequest(BaseSchema): dragging_deal_id: int hovered_deal_id: int class DealRemoveFromGroupRequest(BaseSchema): deal_id: int class DealGroupUpdateRequest(BaseSchema): data: DealGroupSchema class DealGroupChangeStatusRequest(BaseSchema): group_id: int new_status: int # endregion Requests # region Responses class DealUpdateProductQuantityResponse(OkMessageSchema): pass class DealDeleteServicesResponse(OkMessageSchema): pass class DealGetAllResponse(BaseSchema): deals: List[DealSchema] class DealChangeStatusResponse(BaseSchema): ok: bool class DealCreateResponse(BaseSchema): ok: bool class DealQuickCreateResponse(BaseSchema): deal_id: int class DealSummaryResponse(BaseSchema): summaries: List[DealSummary] class DealAddServicesResponse(BaseSchema): ok: bool message: str class DealUpdateServiceQuantityResponse(BaseSchema): ok: bool message: str class DealUpdateServiceResponse(OkMessageSchema): pass class DealAddServiceResponse(OkMessageSchema): pass class DealDeleteServiceResponse(OkMessageSchema): pass class DealDeleteProductResponse(OkMessageSchema): pass class DealDeleteProductsResponse(OkMessageSchema): pass class DealAddProductResponse(OkMessageSchema): pass class DealUpdateGeneralInfoResponse(OkMessageSchema): pass class DealSummaryReorderResponse(OkMessageSchema): pass class DealDeleteResponse(OkMessageSchema): pass class DealUpdateProductResponse(OkMessageSchema): pass class DealServicesCopyResponse(OkMessageSchema): pass class DealProductAddKitResponse(OkMessageSchema): pass class DealAddKitResponse(OkMessageSchema): pass class DealCreateGuestUrlResponse(OkMessageSchema): url: str class DealCompleteResponse(OkMessageSchema): pass class DealPrefillResponse(OkMessageSchema): pass class DealRecalculatePriceResponse(OkMessageSchema): pass class ManageEmployeeResponse(OkMessageSchema): pass class GetAvailableEmployeesToAssignResponse(BaseSchema): employees: list[UserSchema] class DealAddToGroupResponse(OkMessageSchema): pass class DealCreateGroupResponse(OkMessageSchema): pass class DealRemoveFromGroupResponse(OkMessageSchema): pass class DealGroupUpdateResponse(OkMessageSchema): pass class DealGroupChangeStatusResponse(OkMessageSchema): pass # endregion Responses