feat(lexware): add integration foundation
This commit is contained in:
parent
8d37eb29b3
commit
ffffb68898
28 changed files with 1150 additions and 11 deletions
81
backend/hermes/app/schemas/lexware.py
Normal file
81
backend/hermes/app/schemas/lexware.py
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
from decimal import Decimal
|
||||
from typing import Literal
|
||||
|
||||
from pydantic import BaseModel, Field, field_validator, model_validator
|
||||
|
||||
from app.schemas.system_setting import SettingsSource, normalize_text
|
||||
|
||||
|
||||
LexwareSyncStatus = Literal["pending", "success", "failed", "skipped"]
|
||||
LexwareSyncDirection = Literal["push", "pull"]
|
||||
|
||||
|
||||
class LexwareSettingsResponse(BaseModel):
|
||||
enabled: bool = False
|
||||
api_base_url: str = "https://api.lexware.io"
|
||||
api_key_is_set: bool = False
|
||||
organization_name: str = ""
|
||||
default_tax_rate: Decimal = Decimal("19.00")
|
||||
default_payment_terms_days: int = 14
|
||||
source: SettingsSource
|
||||
|
||||
|
||||
class LexwareSettingsUpdate(BaseModel):
|
||||
enabled: bool = False
|
||||
api_base_url: str = Field(default="https://api.lexware.io", max_length=500)
|
||||
api_key: str | None = Field(default=None, max_length=2000)
|
||||
organization_name: str = Field(default="", max_length=255)
|
||||
default_tax_rate: Decimal = Field(default=Decimal("19.00"), ge=Decimal("0"), le=Decimal("100"))
|
||||
default_payment_terms_days: int = Field(default=14, ge=0, le=365)
|
||||
|
||||
@field_validator("api_base_url", "api_key", "organization_name", mode="before")
|
||||
@classmethod
|
||||
def normalize_strings(cls, value: object) -> str:
|
||||
return normalize_text(value)
|
||||
|
||||
@field_validator("api_base_url")
|
||||
@classmethod
|
||||
def normalize_base_url(cls, value: str) -> str:
|
||||
return (value or "https://api.lexware.io").rstrip("/")
|
||||
|
||||
@model_validator(mode="after")
|
||||
def validate_enabled_configuration(self):
|
||||
if self.enabled and not self.api_base_url:
|
||||
raise ValueError("API Base URL ist erforderlich, wenn Lexware aktiviert ist")
|
||||
return self
|
||||
|
||||
|
||||
class LexwareTestConnectionResponse(BaseModel):
|
||||
success: bool
|
||||
message: str
|
||||
source: SettingsSource
|
||||
api_base_url: str
|
||||
organization_name: str = ""
|
||||
|
||||
|
||||
class LexwareCustomerMapping(BaseModel):
|
||||
name: str
|
||||
email: str
|
||||
phone: str
|
||||
search_strategy: str
|
||||
create_payload: dict
|
||||
|
||||
|
||||
class LexwareLineItemMapping(BaseModel):
|
||||
title: str
|
||||
description: str | None
|
||||
quantity: Decimal
|
||||
unit: str
|
||||
unit_price: Decimal
|
||||
tax_rate: Decimal
|
||||
total: Decimal
|
||||
|
||||
|
||||
class LexwareInvoicePreparationResponse(BaseModel):
|
||||
ready_for_export: bool
|
||||
payload_summary: dict
|
||||
customer_mapping: LexwareCustomerMapping
|
||||
line_item_mapping: list[LexwareLineItemMapping]
|
||||
tax_mapping: dict
|
||||
warnings: list[str]
|
||||
sync_record_id: int
|
||||
Loading…
Add table
Add a link
Reference in a new issue