bmc_hub/app/modules/also/models/schemas.py

162 lines
4.5 KiB
Python
Raw Permalink Normal View History

from datetime import date, datetime
from decimal import Decimal
from typing import Any, Dict, List, Literal, Optional
from pydantic import BaseModel, Field
2026-07-03 20:20:22 +02:00
ALSO_SOURCE_TYPES = Literal["api", "xml", "json_export", "xml_export", "csv", "xlsx_export"]
ALSO_QUEUE_STATUSES = Literal[
"new",
"matching_products",
"matching_customers",
"ready_for_approval",
"approved",
"invoiced",
"error",
]
class AlsoImportJobCreate(BaseModel):
source_type: ALSO_SOURCE_TYPES
source_label: Optional[str] = None
file_name: Optional[str] = None
import_version: Optional[str] = None
raw_payload: Dict[str, Any] = Field(default_factory=dict)
class AlsoImportLineInput(BaseModel):
line_no: Optional[int] = None
source_line_ref: Optional[str] = None
company: Optional[str] = None
customer_id: Optional[str] = None
account_id: Optional[str] = None
vat: Optional[str] = None
also_company_id: Optional[str] = None
material_number: Optional[str] = None
product_name: Optional[str] = None
vendor: Optional[str] = None
cost_amount: Optional[Decimal] = None
sales_price: Optional[Decimal] = None
unit_price: Optional[Decimal] = None
total_price: Optional[Decimal] = None
currency: Optional[str] = None
billing_start: Optional[date] = None
charge_interval: Optional[str] = None
billing_interval: Optional[str] = None
billable_parameters: Optional[Decimal] = None
queue_status: ALSO_QUEUE_STATUSES = "new"
raw_line: Dict[str, Any] = Field(default_factory=dict)
class AlsoImportLinesRequest(BaseModel):
lines: List[AlsoImportLineInput] = Field(default_factory=list)
class AlsoQueueProcessRequest(BaseModel):
import_job_id: Optional[int] = Field(default=None, gt=0)
line_ids: List[int] = Field(default_factory=list)
limit: int = Field(default=500, ge=1, le=5000)
class AlsoQueueApproveRequest(BaseModel):
import_job_id: Optional[int] = Field(default=None, gt=0)
line_ids: List[int] = Field(default_factory=list)
class AlsoQueueProcessResult(BaseModel):
processed: int
updated: int
ready_for_approval: int
errored: int
class AlsoApproveResult(BaseModel):
approved_lines: int
created_drafts: int
draft_ids: List[int] = Field(default_factory=list)
class AlsoCompanyMappingUpsert(BaseModel):
also_company_id: str = Field(min_length=1)
also_customer_id: Optional[str] = None
customer_id: int = Field(gt=0)
match_confidence: Optional[Decimal] = None
notes: Optional[str] = None
class AlsoProductMappingUpsert(BaseModel):
material_number: str = Field(min_length=1)
vendor: str = Field(min_length=1)
hub_product_id: int = Field(gt=0)
product_name_snapshot: Optional[str] = None
2026-07-03 20:20:22 +02:00
class AlsoManualCompanyMapRequest(BaseModel):
customer_id: int = Field(gt=0)
notes: Optional[str] = None
class AlsoManualProductMapRequest(BaseModel):
product_id: int = Field(gt=0)
notes: Optional[str] = None
class AlsoImportJobResponse(BaseModel):
id: int
source_type: str
source_label: Optional[str] = None
status: str
file_name: Optional[str] = None
import_version: Optional[str] = None
imported_by_user_id: Optional[int] = None
imported_at: datetime
line_count: int = 0
class AlsoQueueLineResponse(BaseModel):
id: int
import_job_id: int
queue_status: str
company: Optional[str] = None
customer_id: Optional[str] = None
material_number: Optional[str] = None
product_name: Optional[str] = None
vendor: Optional[str] = None
total_price: Optional[Decimal] = None
2026-07-03 20:20:22 +02:00
cost_amount: Optional[Decimal] = None
effective_cost_amount: Optional[Decimal] = None
effective_margin_amount: Optional[Decimal] = None
currency: Optional[str] = None
matched_customer_id: Optional[int] = None
matched_product_id: Optional[int] = None
order_draft_id: Optional[int] = None
validation_errors_json: List[Dict[str, Any]] = Field(default_factory=list)
class AlsoDashboardSummaryResponse(BaseModel):
monthly_revenue: Decimal
monthly_cost: Decimal
monthly_margin: Decimal
unmatched_products: int
unmatched_customers: int
pending_approvals: int
invoiced_customers: int
class AlsoDifferenceItem(BaseModel):
customer_id: Optional[int] = None
customer_name: Optional[str] = None
material_number: Optional[str] = None
product_name: Optional[str] = None
vendor: Optional[str] = None
previous_month_qty: Decimal
current_month_qty: Decimal
change_percent: Optional[Decimal] = None
warning: bool = False