feat(settings): add GoMag API config, Oracle dropdowns, compact 2x2 layout
- Remove ID_GESTIUNE from config (unused) - Add GoMag API settings (key, shop, days_back, limit) to SQLite — editable without restart - sync_service reads GoMag settings from SQLite before download - gomag_client.download_orders accepts api_key/api_shop/limit overrides - New GET /api/settings/sectii and /api/settings/politici endpoints for Oracle dropdowns (nom_sectii.sectie, crm_politici_preturi.nume_lista_preturi) - id_pol, id_sectie, transport_id_pol, discount_id_pol now use select dropdowns - order_reader extracts discount_vat from GoMag JSON discounts[].vat - import_service uses GoMag discount_vat as primary, settings as fallback - settings.html redesigned to compact 2x2 grid (GoMag API | Import ROA / Transport | Discount) - settings.js v2: loadDropdowns() sequential before loadSettings() Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
import asyncio
|
||||
import json
|
||||
import logging
|
||||
from datetime import datetime
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
from fastapi import APIRouter, Request, BackgroundTasks
|
||||
from fastapi.templating import Jinja2Templates
|
||||
from fastapi.responses import HTMLResponse
|
||||
@@ -10,6 +13,7 @@ from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
from ..services import sync_service, scheduler_service, sqlite_service, invoice_service
|
||||
from .. import database
|
||||
|
||||
router = APIRouter(tags=["sync"])
|
||||
templates = Jinja2Templates(directory=str(Path(__file__).parent.parent / "templates"))
|
||||
@@ -29,6 +33,10 @@ class AppSettingsUpdate(BaseModel):
|
||||
discount_id_pol: str = ""
|
||||
id_pol: str = ""
|
||||
id_sectie: str = ""
|
||||
gomag_api_key: str = ""
|
||||
gomag_api_shop: str = ""
|
||||
gomag_order_days_back: str = "7"
|
||||
gomag_limit: str = "100"
|
||||
|
||||
|
||||
# API endpoints
|
||||
@@ -457,16 +465,21 @@ async def get_schedule():
|
||||
@router.get("/api/settings")
|
||||
async def get_app_settings():
|
||||
"""Get application settings."""
|
||||
settings = await sqlite_service.get_app_settings()
|
||||
from ..config import settings as config_settings
|
||||
s = await sqlite_service.get_app_settings()
|
||||
return {
|
||||
"transport_codmat": settings.get("transport_codmat", ""),
|
||||
"transport_vat": settings.get("transport_vat", "21"),
|
||||
"discount_codmat": settings.get("discount_codmat", ""),
|
||||
"transport_id_pol": settings.get("transport_id_pol", ""),
|
||||
"discount_vat": settings.get("discount_vat", "19"),
|
||||
"discount_id_pol": settings.get("discount_id_pol", ""),
|
||||
"id_pol": settings.get("id_pol", ""),
|
||||
"id_sectie": settings.get("id_sectie", ""),
|
||||
"transport_codmat": s.get("transport_codmat", ""),
|
||||
"transport_vat": s.get("transport_vat", "21"),
|
||||
"discount_codmat": s.get("discount_codmat", ""),
|
||||
"transport_id_pol": s.get("transport_id_pol", ""),
|
||||
"discount_vat": s.get("discount_vat", "19"),
|
||||
"discount_id_pol": s.get("discount_id_pol", ""),
|
||||
"id_pol": s.get("id_pol", ""),
|
||||
"id_sectie": s.get("id_sectie", ""),
|
||||
"gomag_api_key": s.get("gomag_api_key", "") or config_settings.GOMAG_API_KEY,
|
||||
"gomag_api_shop": s.get("gomag_api_shop", "") or config_settings.GOMAG_API_SHOP,
|
||||
"gomag_order_days_back": s.get("gomag_order_days_back", "") or str(config_settings.GOMAG_ORDER_DAYS_BACK),
|
||||
"gomag_limit": s.get("gomag_limit", "") or str(config_settings.GOMAG_LIMIT),
|
||||
}
|
||||
|
||||
|
||||
@@ -481,4 +494,48 @@ async def update_app_settings(config: AppSettingsUpdate):
|
||||
await sqlite_service.set_app_setting("discount_id_pol", config.discount_id_pol)
|
||||
await sqlite_service.set_app_setting("id_pol", config.id_pol)
|
||||
await sqlite_service.set_app_setting("id_sectie", config.id_sectie)
|
||||
await sqlite_service.set_app_setting("gomag_api_key", config.gomag_api_key)
|
||||
await sqlite_service.set_app_setting("gomag_api_shop", config.gomag_api_shop)
|
||||
await sqlite_service.set_app_setting("gomag_order_days_back", config.gomag_order_days_back)
|
||||
await sqlite_service.set_app_setting("gomag_limit", config.gomag_limit)
|
||||
return {"success": True}
|
||||
|
||||
|
||||
@router.get("/api/settings/sectii")
|
||||
async def get_sectii():
|
||||
"""Get list of sections from Oracle for dropdown."""
|
||||
def _query():
|
||||
conn = database.get_oracle_connection()
|
||||
try:
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"SELECT id_sectie, sectie FROM nom_sectii WHERE sters=0 AND inactiv=0 ORDER BY id_sectie"
|
||||
)
|
||||
return [{"id": str(row[0]), "label": f"{row[0]} - {row[1]}"} for row in cur]
|
||||
finally:
|
||||
database.pool.release(conn)
|
||||
try:
|
||||
return await asyncio.to_thread(_query)
|
||||
except Exception as e:
|
||||
logger.error(f"get_sectii error: {e}")
|
||||
return []
|
||||
|
||||
|
||||
@router.get("/api/settings/politici")
|
||||
async def get_politici():
|
||||
"""Get list of price policies from Oracle for dropdown."""
|
||||
def _query():
|
||||
conn = database.get_oracle_connection()
|
||||
try:
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"SELECT id_pol, nume_lista_preturi FROM crm_politici_preturi WHERE sters=0 ORDER BY id_pol"
|
||||
)
|
||||
return [{"id": str(row[0]), "label": f"{row[0]} - {row[1]}"} for row in cur]
|
||||
finally:
|
||||
database.pool.release(conn)
|
||||
try:
|
||||
return await asyncio.to_thread(_query)
|
||||
except Exception as e:
|
||||
logger.error(f"get_politici error: {e}")
|
||||
return []
|
||||
|
||||
Reference in New Issue
Block a user