feature: Added Transactions and major Order System Overhaul
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
from enum import Enum
|
||||
from typing import List, Optional
|
||||
from typing import Any, Dict, List, Optional
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
@@ -129,6 +129,50 @@ class CustomerLocation(BaseModel):
|
||||
country: Optional[str] = None
|
||||
|
||||
|
||||
# ── New customer status models ────────────────────────────────────────────────
|
||||
|
||||
class TechnicalIssue(BaseModel):
|
||||
active: bool = True
|
||||
opened_date: str # ISO string
|
||||
resolved_date: Optional[str] = None
|
||||
note: str
|
||||
opened_by: str
|
||||
resolved_by: Optional[str] = None
|
||||
|
||||
|
||||
class InstallSupportEntry(BaseModel):
|
||||
active: bool = True
|
||||
opened_date: str # ISO string
|
||||
resolved_date: Optional[str] = None
|
||||
note: str
|
||||
opened_by: str
|
||||
resolved_by: Optional[str] = None
|
||||
|
||||
|
||||
class TransactionEntry(BaseModel):
|
||||
date: str # ISO string
|
||||
flow: str # "invoice" | "payment" | "refund" | "credit"
|
||||
payment_type: Optional[str] = None # "cash" | "bank_transfer" | "card" | "paypal" — null for invoices
|
||||
category: str # "full_payment" | "advance" | "installment"
|
||||
amount: float
|
||||
currency: str = "EUR"
|
||||
invoice_ref: Optional[str] = None
|
||||
order_ref: Optional[str] = None
|
||||
recorded_by: str
|
||||
note: str = ""
|
||||
|
||||
|
||||
# Lightweight summary stored on customer doc for fast CustomerList expanded view
|
||||
class CrmSummary(BaseModel):
|
||||
active_order_status: Optional[str] = None
|
||||
active_order_status_date: Optional[str] = None
|
||||
active_order_title: Optional[str] = None
|
||||
active_issues_count: int = 0
|
||||
latest_issue_date: Optional[str] = None
|
||||
active_support_count: int = 0
|
||||
latest_support_date: Optional[str] = None
|
||||
|
||||
|
||||
class CustomerCreate(BaseModel):
|
||||
title: Optional[str] = None
|
||||
name: str
|
||||
@@ -143,9 +187,12 @@ class CustomerCreate(BaseModel):
|
||||
owned_items: List[OwnedItem] = []
|
||||
linked_user_ids: List[str] = []
|
||||
nextcloud_folder: Optional[str] = None
|
||||
folder_id: Optional[str] = None # Human-readable Nextcloud folder name, e.g. "saint-john-corfu"
|
||||
negotiating: bool = False
|
||||
has_problem: bool = False
|
||||
folder_id: Optional[str] = None
|
||||
relationship_status: str = "lead"
|
||||
technical_issues: List[Dict[str, Any]] = []
|
||||
install_support: List[Dict[str, Any]] = []
|
||||
transaction_history: List[Dict[str, Any]] = []
|
||||
crm_summary: Optional[Dict[str, Any]] = None
|
||||
|
||||
|
||||
class CustomerUpdate(BaseModel):
|
||||
@@ -162,8 +209,7 @@ class CustomerUpdate(BaseModel):
|
||||
owned_items: Optional[List[OwnedItem]] = None
|
||||
linked_user_ids: Optional[List[str]] = None
|
||||
nextcloud_folder: Optional[str] = None
|
||||
negotiating: Optional[bool] = None
|
||||
has_problem: Optional[bool] = None
|
||||
relationship_status: Optional[str] = None
|
||||
# folder_id intentionally excluded from update — set once at creation
|
||||
|
||||
|
||||
@@ -181,18 +227,34 @@ class CustomerListResponse(BaseModel):
|
||||
# ── Orders ───────────────────────────────────────────────────────────────────
|
||||
|
||||
class OrderStatus(str, Enum):
|
||||
draft = "draft"
|
||||
confirmed = "confirmed"
|
||||
in_production = "in_production"
|
||||
negotiating = "negotiating"
|
||||
awaiting_quotation = "awaiting_quotation"
|
||||
awaiting_customer_confirmation = "awaiting_customer_confirmation"
|
||||
awaiting_fulfilment = "awaiting_fulfilment"
|
||||
awaiting_payment = "awaiting_payment"
|
||||
manufacturing = "manufacturing"
|
||||
shipped = "shipped"
|
||||
delivered = "delivered"
|
||||
cancelled = "cancelled"
|
||||
installed = "installed"
|
||||
declined = "declined"
|
||||
complete = "complete"
|
||||
|
||||
|
||||
class PaymentStatus(str, Enum):
|
||||
pending = "pending"
|
||||
partial = "partial"
|
||||
paid = "paid"
|
||||
class OrderPaymentStatus(BaseModel):
|
||||
required_amount: float = 0
|
||||
received_amount: float = 0
|
||||
balance_due: float = 0
|
||||
advance_required: bool = False
|
||||
advance_amount: Optional[float] = None
|
||||
payment_complete: bool = False
|
||||
|
||||
|
||||
class OrderTimelineEvent(BaseModel):
|
||||
date: str # ISO string
|
||||
type: str # "quote_request" | "quote_sent" | "quote_accepted" | "quote_declined"
|
||||
# | "mfg_started" | "mfg_complete" | "order_shipped" | "installed"
|
||||
# | "payment_received" | "invoice_sent" | "note"
|
||||
note: str = ""
|
||||
updated_by: str
|
||||
|
||||
|
||||
class OrderDiscount(BaseModel):
|
||||
@@ -223,29 +285,36 @@ class OrderItem(BaseModel):
|
||||
class OrderCreate(BaseModel):
|
||||
customer_id: str
|
||||
order_number: Optional[str] = None
|
||||
status: OrderStatus = OrderStatus.draft
|
||||
title: Optional[str] = None
|
||||
created_by: Optional[str] = None
|
||||
status: OrderStatus = OrderStatus.negotiating
|
||||
status_updated_date: Optional[str] = None
|
||||
status_updated_by: Optional[str] = None
|
||||
items: List[OrderItem] = []
|
||||
subtotal: float = 0
|
||||
discount: Optional[OrderDiscount] = None
|
||||
total_price: float = 0
|
||||
currency: str = "EUR"
|
||||
shipping: Optional[OrderShipping] = None
|
||||
payment_status: PaymentStatus = PaymentStatus.pending
|
||||
payment_status: Optional[Dict[str, Any]] = None
|
||||
invoice_path: Optional[str] = None
|
||||
notes: Optional[str] = None
|
||||
timeline: List[Dict[str, Any]] = []
|
||||
|
||||
|
||||
class OrderUpdate(BaseModel):
|
||||
customer_id: Optional[str] = None
|
||||
order_number: Optional[str] = None
|
||||
title: Optional[str] = None
|
||||
status: Optional[OrderStatus] = None
|
||||
status_updated_date: Optional[str] = None
|
||||
status_updated_by: Optional[str] = None
|
||||
items: Optional[List[OrderItem]] = None
|
||||
subtotal: Optional[float] = None
|
||||
discount: Optional[OrderDiscount] = None
|
||||
total_price: Optional[float] = None
|
||||
currency: Optional[str] = None
|
||||
shipping: Optional[OrderShipping] = None
|
||||
payment_status: Optional[PaymentStatus] = None
|
||||
payment_status: Optional[Dict[str, Any]] = None
|
||||
invoice_path: Optional[str] = None
|
||||
notes: Optional[str] = None
|
||||
|
||||
|
||||
Reference in New Issue
Block a user