feat(integrations): add SaleOrder service for Odoo sales

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Claude AI
2026-01-29 22:21:54 +00:00
parent d2ce86bd41
commit a40811b4a1
10 changed files with 620 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
from app.schemas.sale import (
SaleOrderLine,
SaleOrderResponse,
SaleOrderSearchResult,
QuotationCreate,
)
__all__ = [
"SaleOrderLine",
"SaleOrderResponse",
"SaleOrderSearchResult",
"QuotationCreate",
]

View File

@@ -0,0 +1,38 @@
from pydantic import BaseModel
from typing import Optional
class LeadCreate(BaseModel):
name: str
partner_id: Optional[int] = None
contact_name: Optional[str] = None
phone: Optional[str] = None
mobile: Optional[str] = None
email_from: Optional[str] = None
description: Optional[str] = None
expected_revenue: Optional[float] = None
source: Optional[str] = "WhatsApp"
class LeadResponse(BaseModel):
id: int
name: str
stage_id: int
stage_name: str
partner_id: Optional[int] = None
partner_name: Optional[str] = None
contact_name: Optional[str] = None
phone: Optional[str] = None
email_from: Optional[str] = None
expected_revenue: float
probability: float
user_id: Optional[int] = None
user_name: Optional[str] = None
class LeadSearchResult(BaseModel):
id: int
name: str
stage_name: str
expected_revenue: float
probability: float

View File

@@ -0,0 +1,43 @@
from pydantic import BaseModel
from typing import Optional
class PartnerBase(BaseModel):
name: str
phone: Optional[str] = None
mobile: Optional[str] = None
email: Optional[str] = None
street: Optional[str] = None
city: Optional[str] = None
country_id: Optional[int] = None
comment: Optional[str] = None
class PartnerCreate(PartnerBase):
pass
class PartnerUpdate(BaseModel):
name: Optional[str] = None
phone: Optional[str] = None
mobile: Optional[str] = None
email: Optional[str] = None
street: Optional[str] = None
city: Optional[str] = None
comment: Optional[str] = None
class PartnerResponse(PartnerBase):
id: int
display_name: Optional[str] = None
credit: Optional[float] = None
debit: Optional[float] = None
credit_limit: Optional[float] = None
class PartnerSearchResult(BaseModel):
id: int
name: str
phone: Optional[str] = None
mobile: Optional[str] = None
email: Optional[str] = None

View File

@@ -0,0 +1,31 @@
from pydantic import BaseModel
from typing import Optional
class ProductResponse(BaseModel):
id: int
name: str
default_code: Optional[str] = None
list_price: float
qty_available: float
virtual_available: float
description: Optional[str] = None
categ_name: Optional[str] = None
class ProductSearchResult(BaseModel):
id: int
name: str
default_code: Optional[str] = None
list_price: float
qty_available: float
class StockInfo(BaseModel):
product_id: int
product_name: str
qty_available: float
qty_reserved: float
qty_incoming: float
qty_outgoing: float
virtual_available: float

View File

@@ -0,0 +1,40 @@
from pydantic import BaseModel
from typing import Optional, List
class SaleOrderLine(BaseModel):
id: int
product_id: int
product_name: str
quantity: float
price_unit: float
price_subtotal: float
class SaleOrderResponse(BaseModel):
id: int
name: str
state: str
state_display: str
partner_id: int
partner_name: str
date_order: Optional[str] = None
amount_total: float
amount_untaxed: float
amount_tax: float
currency: str
order_lines: List[SaleOrderLine] = []
class SaleOrderSearchResult(BaseModel):
id: int
name: str
state: str
date_order: Optional[str] = None
amount_total: float
class QuotationCreate(BaseModel):
partner_id: int
lines: List[dict]
note: Optional[str] = None