update: Major Overhault to all subsystems

This commit is contained in:
2026-03-07 11:32:18 +02:00
parent 810e81b323
commit b280d62ee5
107 changed files with 20414 additions and 929 deletions

View File

@@ -0,0 +1,141 @@
from enum import Enum
from typing import Any, Dict, List, Optional
from pydantic import BaseModel
class QuotationStatus(str, Enum):
draft = "draft"
sent = "sent"
accepted = "accepted"
rejected = "rejected"
class QuotationItemCreate(BaseModel):
product_id: Optional[str] = None
description: Optional[str] = None
unit_type: str = "pcs" # pcs / kg / m
unit_cost: float = 0.0
discount_percent: float = 0.0
quantity: float = 1.0
vat_percent: float = 24.0
sort_order: int = 0
class QuotationItemInDB(QuotationItemCreate):
id: str
quotation_id: str
line_total: float = 0.0
class QuotationCreate(BaseModel):
customer_id: str
title: Optional[str] = None
subtitle: Optional[str] = None
language: str = "en" # en / gr
order_type: Optional[str] = None
shipping_method: Optional[str] = None
estimated_shipping_date: Optional[str] = None
global_discount_label: Optional[str] = None
global_discount_percent: float = 0.0
shipping_cost: float = 0.0
shipping_cost_discount: float = 0.0
install_cost: float = 0.0
install_cost_discount: float = 0.0
extras_label: Optional[str] = None
extras_cost: float = 0.0
comments: List[str] = []
quick_notes: Optional[Dict[str, Any]] = None
items: List[QuotationItemCreate] = []
# Client override fields (for this quotation only; customer record is not modified)
client_org: Optional[str] = None
client_name: Optional[str] = None
client_location: Optional[str] = None
client_phone: Optional[str] = None
client_email: Optional[str] = None
class QuotationUpdate(BaseModel):
title: Optional[str] = None
subtitle: Optional[str] = None
language: Optional[str] = None
status: Optional[QuotationStatus] = None
order_type: Optional[str] = None
shipping_method: Optional[str] = None
estimated_shipping_date: Optional[str] = None
global_discount_label: Optional[str] = None
global_discount_percent: Optional[float] = None
shipping_cost: Optional[float] = None
shipping_cost_discount: Optional[float] = None
install_cost: Optional[float] = None
install_cost_discount: Optional[float] = None
extras_label: Optional[str] = None
extras_cost: Optional[float] = None
comments: Optional[List[str]] = None
quick_notes: Optional[Dict[str, Any]] = None
items: Optional[List[QuotationItemCreate]] = None
# Client override fields
client_org: Optional[str] = None
client_name: Optional[str] = None
client_location: Optional[str] = None
client_phone: Optional[str] = None
client_email: Optional[str] = None
class QuotationInDB(BaseModel):
id: str
quotation_number: str
customer_id: str
title: Optional[str] = None
subtitle: Optional[str] = None
language: str = "en"
status: QuotationStatus = QuotationStatus.draft
order_type: Optional[str] = None
shipping_method: Optional[str] = None
estimated_shipping_date: Optional[str] = None
global_discount_label: Optional[str] = None
global_discount_percent: float = 0.0
shipping_cost: float = 0.0
shipping_cost_discount: float = 0.0
install_cost: float = 0.0
install_cost_discount: float = 0.0
extras_label: Optional[str] = None
extras_cost: float = 0.0
comments: List[str] = []
quick_notes: Dict[str, Any] = {}
subtotal_before_discount: float = 0.0
global_discount_amount: float = 0.0
new_subtotal: float = 0.0
vat_amount: float = 0.0
final_total: float = 0.0
nextcloud_pdf_path: Optional[str] = None
nextcloud_pdf_url: Optional[str] = None
created_at: str
updated_at: str
items: List[QuotationItemInDB] = []
# Client override fields
client_org: Optional[str] = None
client_name: Optional[str] = None
client_location: Optional[str] = None
client_phone: Optional[str] = None
client_email: Optional[str] = None
class QuotationListItem(BaseModel):
id: str
quotation_number: str
title: Optional[str] = None
customer_id: str
status: QuotationStatus
final_total: float
created_at: str
updated_at: str
nextcloud_pdf_url: Optional[str] = None
class QuotationListResponse(BaseModel):
quotations: List[QuotationListItem]
total: int
class NextNumberResponse(BaseModel):
next_number: str