feat(invoice+import): refresh facturi, detalii factura, fix duplicate CODMAT + rollback

- PL/SQL: handle duplicate CODMAT in nom_articole with MAX(id_articol)
- import_service: add explicit conn.rollback() on Oracle errors
- sync_service: auto-fix stale ERROR orders that exist in Oracle
- invoice_service: add data_act (invoice date) from vanzari table
- sync router: new POST /api/dashboard/refresh-invoices endpoint
- order detail: enrich with invoice data (serie, numar, data factura)
- dashboard: refresh invoices button (desktop + mobile icon)
- quick map modal: compact single-row layout, pre-populate existing mappings
- quick map: link on SKU column instead of CODMAT

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-03-16 17:30:23 +00:00
parent 43327c4a70
commit 84b24b1434
11 changed files with 263 additions and 48 deletions

View File

@@ -128,6 +128,7 @@ def import_single_order(order, id_pol: int = None, id_sectie: int = None, app_se
"error": None
}
conn = None
try:
order_number = clean_web_text(order.number)
order_date = convert_web_date(order.date)
@@ -138,8 +139,8 @@ def import_single_order(order, id_pol: int = None, id_sectie: int = None, app_se
if database.pool is None:
raise RuntimeError("Oracle pool not initialized")
with database.pool.acquire() as conn:
with conn.cursor() as cur:
conn = database.pool.acquire()
with conn.cursor() as cur:
# Step 1: Process partner — use shipping person data for name
id_partener = cur.var(oracledb.DB_TYPE_NUMBER)
@@ -272,8 +273,24 @@ def import_single_order(order, id_pol: int = None, id_sectie: int = None, app_se
error_msg = str(e)
result["error"] = error_msg
logger.error(f"Oracle error importing order {order.number}: {error_msg}")
if conn:
try:
conn.rollback()
except Exception:
pass
except Exception as e:
result["error"] = str(e)
logger.error(f"Error importing order {order.number}: {e}")
if conn:
try:
conn.rollback()
except Exception:
pass
finally:
if conn:
try:
database.pool.release(conn)
except Exception:
pass
return result