TVA BREAKDOWN

This commit is contained in:
2025-12-12 16:39:50 +02:00
parent 20448f7aa0
commit 6c3dd89f6d
2 changed files with 55 additions and 4 deletions

View File

@@ -1,7 +1,9 @@
"""CRUD operations for receipts.""" """CRUD operations for receipts."""
import json
from datetime import datetime, date from datetime import datetime, date
from typing import Optional, List, Tuple from decimal import Decimal
from typing import Optional, List, Tuple, Any
from sqlalchemy import select, func, or_ from sqlalchemy import select, func, or_
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload from sqlalchemy.orm import selectinload
@@ -10,6 +12,31 @@ from app.db.models.receipt import Receipt, ReceiptStatus
from app.schemas.receipt import ReceiptCreate, ReceiptUpdate, ReceiptFilter from app.schemas.receipt import ReceiptCreate, ReceiptUpdate, ReceiptFilter
def _serialize_tva_breakdown(tva_breakdown: Optional[List[Any]]) -> Optional[str]:
"""Serialize TVA breakdown list to JSON string for SQLite storage."""
if tva_breakdown is None:
return None
# Convert Decimal to float for JSON serialization
serializable = []
for entry in tva_breakdown:
if hasattr(entry, 'model_dump'):
# Pydantic model
item = entry.model_dump()
elif isinstance(entry, dict):
item = entry.copy()
else:
item = dict(entry)
# Convert Decimal to float
if 'amount' in item and isinstance(item['amount'], Decimal):
item['amount'] = float(item['amount'])
serializable.append(item)
return json.dumps(serializable)
class ReceiptCRUD: class ReceiptCRUD:
"""CRUD operations for Receipt model.""" """CRUD operations for Receipt model."""
@@ -20,8 +47,12 @@ class ReceiptCRUD:
created_by: str, created_by: str,
) -> Receipt: ) -> Receipt:
"""Create a new receipt.""" """Create a new receipt."""
# Get data as dict and serialize tva_breakdown to JSON string
receipt_data = data.model_dump()
receipt_data['tva_breakdown'] = _serialize_tva_breakdown(receipt_data.get('tva_breakdown'))
receipt = Receipt( receipt = Receipt(
**data.model_dump(), **receipt_data,
created_by=created_by, created_by=created_by,
status=ReceiptStatus.DRAFT, status=ReceiptStatus.DRAFT,
) )
@@ -132,6 +163,10 @@ class ReceiptCRUD:
"""Update receipt fields.""" """Update receipt fields."""
update_data = data.model_dump(exclude_unset=True) update_data = data.model_dump(exclude_unset=True)
# Serialize tva_breakdown to JSON string if present
if 'tva_breakdown' in update_data:
update_data['tva_breakdown'] = _serialize_tva_breakdown(update_data['tva_breakdown'])
for field, value in update_data.items(): for field, value in update_data.items():
setattr(receipt, field, value) setattr(receipt, field, value)

View File

@@ -1,9 +1,10 @@
"""Pydantic schemas for receipts API.""" """Pydantic schemas for receipts API."""
import json
from datetime import datetime, date from datetime import datetime, date
from decimal import Decimal from decimal import Decimal
from typing import Optional, List from typing import Optional, List, Any, Union
from pydantic import BaseModel, Field, ConfigDict from pydantic import BaseModel, Field, ConfigDict, field_validator
from app.db.models.receipt import ReceiptType, ReceiptDirection, ReceiptStatus from app.db.models.receipt import ReceiptType, ReceiptDirection, ReceiptStatus
from app.db.models.accounting_entry import EntryType from app.db.models.accounting_entry import EntryType
@@ -148,6 +149,21 @@ class ReceiptResponse(ReceiptBase):
attachments: List[AttachmentResponse] = [] attachments: List[AttachmentResponse] = []
entries: List[AccountingEntryResponse] = [] entries: List[AccountingEntryResponse] = []
@field_validator('tva_breakdown', mode='before')
@classmethod
def parse_tva_breakdown(cls, v: Any) -> Optional[List[dict]]:
"""Deserialize tva_breakdown from JSON string if needed."""
if v is None:
return None
if isinstance(v, str):
try:
return json.loads(v)
except (json.JSONDecodeError, TypeError):
return None
if isinstance(v, list):
return v
return None
class ReceiptListResponse(BaseModel): class ReceiptListResponse(BaseModel):
"""Schema for paginated receipt list response.""" """Schema for paginated receipt list response."""