refactor(price): remove price comparison UI and catalog sync

GoMag vs ROA price comparison generated too many false positives
(kits, volume discounts, special prices). Removes comparison columns,
dots, badges, catalog sync endpoints, and ~950 lines of dead code.
Keeps WRITE path (sync_prices_from_order) for kit pricing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-04-08 20:30:34 +00:00
parent 5584dd3c4f
commit 1d59f1a484
16 changed files with 20 additions and 972 deletions

View File

@@ -12,7 +12,7 @@ from pydantic import BaseModel
from pathlib import Path
from typing import Optional
from ..services import sync_service, scheduler_service, sqlite_service, invoice_service, validation_service
from ..services import sync_service, scheduler_service, sqlite_service, invoice_service
from .. import database
router = APIRouter(tags=["sync"])
@@ -40,56 +40,6 @@ async def _enrich_items_with_codmat(items: list) -> None:
"denumire": nom_map[sku], "direct": True}]
async def backfill_price_match():
"""Background task: check prices for all imported orders without cached price_match."""
try:
from ..database import get_sqlite
db = await get_sqlite()
try:
# Reset all cached price_match to re-evaluate with current logic
await db.execute("UPDATE orders SET price_match = NULL WHERE price_match IS NOT NULL")
await db.commit()
cursor = await db.execute("""
SELECT order_number FROM orders
WHERE status IN ('IMPORTED', 'ALREADY_IMPORTED')
AND price_match IS NULL
ORDER BY order_date DESC
""")
rows = [r["order_number"] for r in await cursor.fetchall()]
finally:
await db.close()
if not rows:
logger.info("backfill_price_match: no unchecked orders")
return
logger.info(f"backfill_price_match: checking {len(rows)} orders...")
app_settings = await sqlite_service.get_app_settings()
checked = 0
for order_number in rows:
try:
detail = await sqlite_service.get_order_detail(order_number)
if not detail:
continue
items = detail.get("items", [])
await _enrich_items_with_codmat(items)
price_data = await asyncio.to_thread(
validation_service.get_prices_for_order, items, app_settings
)
summary = price_data.get("summary", {})
if summary.get("oracle_available") is not False:
pm = summary.get("mismatches", 0) == 0
await sqlite_service.update_order_price_match(order_number, pm)
checked += 1
except Exception as e:
logger.debug(f"backfill_price_match: order {order_number} failed: {e}")
logger.info(f"backfill_price_match: done, {checked}/{len(rows)} updated")
except Exception as e:
logger.error(f"backfill_price_match failed: {e}")
class ScheduleConfig(BaseModel):
enabled: bool
interval_minutes: int = 5
@@ -116,9 +66,6 @@ class AppSettingsUpdate(BaseModel):
kit_discount_codmat: str = ""
kit_discount_id_pol: str = ""
price_sync_enabled: str = "1"
catalog_sync_enabled: str = "0"
price_sync_schedule: str = ""
gomag_products_url: str = ""
# API endpoints
@@ -217,31 +164,6 @@ async def sync_history(page: int = 1, per_page: int = 20):
return await sqlite_service.get_sync_runs(page, per_page)
@router.post("/api/price-sync/start")
async def start_price_sync(background_tasks: BackgroundTasks):
"""Trigger manual catalog price sync."""
from ..services import price_sync_service
result = await price_sync_service.prepare_price_sync()
if result.get("error"):
return {"error": result["error"]}
run_id = result["run_id"]
background_tasks.add_task(price_sync_service.run_catalog_price_sync, run_id=run_id)
return {"message": "Price sync started", "run_id": run_id}
@router.get("/api/price-sync/status")
async def price_sync_status():
"""Get current price sync status."""
from ..services import price_sync_service
return await price_sync_service.get_price_sync_status()
@router.get("/api/price-sync/history")
async def price_sync_history(page: int = 1, per_page: int = 20):
"""Get price sync run history."""
return await sqlite_service.get_price_sync_runs(page, per_page)
@router.get("/logs", response_class=HTMLResponse)
async def logs_page(request: Request, run: str = None):
return templates.TemplateResponse("logs.html", {"request": request, "selected_run": run or ""})
@@ -454,35 +376,8 @@ async def order_detail(order_number: str):
items = detail.get("items", [])
await _enrich_items_with_codmat(items)
# Price comparison against ROA Oracle
app_settings = await sqlite_service.get_app_settings()
try:
price_data = await asyncio.to_thread(
validation_service.get_prices_for_order, items, app_settings
)
price_items = price_data.get("items", {})
for idx, item in enumerate(items):
pi = price_items.get(idx)
if pi:
item["pret_roa"] = pi.get("pret_roa")
item["price_match"] = pi.get("match")
if pi.get("kit"):
item["kit"] = True
order_price_check = price_data.get("summary", {})
# Cache price_match in SQLite if changed
if order_price_check.get("oracle_available") is not False:
pm = order_price_check.get("mismatches", 0) == 0
cached = detail.get("order", {}).get("price_match")
cached_bool = True if cached == 1 else (False if cached == 0 else None)
if cached_bool != pm:
await sqlite_service.update_order_price_match(order_number, pm)
except Exception as e:
logger.warning(f"Price comparison failed for order {order_number}: {e}")
order_price_check = {"mismatches": 0, "checked": 0, "oracle_available": False}
# Enrich with invoice data
order = detail.get("order", {})
order["price_check"] = order_price_check
if order.get("factura_numar") and order.get("factura_data"):
order["invoice"] = {
"facturat": True,
@@ -562,7 +457,8 @@ async def order_detail(order_number: str):
"facturare_roa": order.get("adresa_facturare_roa"),
}
# Add settings for receipt display (app_settings already fetched above)
# Add settings for receipt display
app_settings = await sqlite_service.get_app_settings()
order["transport_vat"] = app_settings.get("transport_vat") or "21"
order["transport_codmat"] = app_settings.get("transport_codmat") or ""
order["discount_codmat"] = app_settings.get("discount_codmat") or ""
@@ -720,9 +616,6 @@ async def dashboard_orders(page: int = 1, per_page: int = 50,
# Enrich orders with invoice data — prefer SQLite cache, fallback to Oracle
all_orders = result["orders"]
for o in all_orders:
# price_match: 1=OK, 0=mismatch, NULL=not checked yet
pm = o.get("price_match")
o["price_match"] = True if pm == 1 else (False if pm == 0 else None)
if o.get("factura_numar") and o.get("factura_data"):
# Use cached invoice data from SQLite (only if complete)
o["invoice"] = {
@@ -1061,9 +954,6 @@ async def get_app_settings():
"kit_discount_codmat": s.get("kit_discount_codmat", ""),
"kit_discount_id_pol": s.get("kit_discount_id_pol", ""),
"price_sync_enabled": s.get("price_sync_enabled", "1"),
"catalog_sync_enabled": s.get("catalog_sync_enabled", "0"),
"price_sync_schedule": s.get("price_sync_schedule", ""),
"gomag_products_url": s.get("gomag_products_url", ""),
}
@@ -1090,9 +980,6 @@ async def update_app_settings(config: AppSettingsUpdate):
await sqlite_service.set_app_setting("kit_discount_codmat", config.kit_discount_codmat)
await sqlite_service.set_app_setting("kit_discount_id_pol", config.kit_discount_id_pol)
await sqlite_service.set_app_setting("price_sync_enabled", config.price_sync_enabled)
await sqlite_service.set_app_setting("catalog_sync_enabled", config.catalog_sync_enabled)
await sqlite_service.set_app_setting("price_sync_schedule", config.price_sync_schedule)
await sqlite_service.set_app_setting("gomag_products_url", config.gomag_products_url)
return {"success": True}