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:
@@ -91,6 +91,40 @@ def _derive_customer_info(order):
|
||||
return shipping_name, billing_name, customer, payment_method, delivery_method
|
||||
|
||||
|
||||
async def _fix_stale_error_orders(existing_map: dict, run_id: str):
|
||||
"""Fix orders stuck in ERROR status that are actually in Oracle.
|
||||
|
||||
This can happen when a previous import committed partially (no rollback on error).
|
||||
If the order exists in Oracle COMENZI, update SQLite status to ALREADY_IMPORTED.
|
||||
"""
|
||||
from ..database import get_sqlite
|
||||
db = await get_sqlite()
|
||||
try:
|
||||
cursor = await db.execute(
|
||||
"SELECT order_number FROM orders WHERE status = 'ERROR'"
|
||||
)
|
||||
error_orders = [row["order_number"] for row in await cursor.fetchall()]
|
||||
fixed = 0
|
||||
for order_number in error_orders:
|
||||
if order_number in existing_map:
|
||||
id_comanda = existing_map[order_number]
|
||||
await db.execute("""
|
||||
UPDATE orders SET
|
||||
status = 'ALREADY_IMPORTED',
|
||||
id_comanda = ?,
|
||||
error_message = NULL,
|
||||
updated_at = datetime('now')
|
||||
WHERE order_number = ? AND status = 'ERROR'
|
||||
""", (id_comanda, order_number))
|
||||
fixed += 1
|
||||
_log_line(run_id, f"#{order_number} → status corectat ERROR → ALREADY_IMPORTED (ID: {id_comanda})")
|
||||
if fixed:
|
||||
await db.commit()
|
||||
logger.info(f"Fixed {fixed} stale ERROR orders that exist in Oracle")
|
||||
finally:
|
||||
await db.close()
|
||||
|
||||
|
||||
async def run_sync(id_pol: int = None, id_sectie: int = None, run_id: str = None) -> dict:
|
||||
"""Run a full sync cycle. Returns summary dict."""
|
||||
global _current_sync
|
||||
@@ -191,6 +225,10 @@ async def run_sync(id_pol: int = None, id_sectie: int = None, run_id: str = None
|
||||
validation_service.check_orders_in_roa, min_date, conn
|
||||
)
|
||||
|
||||
# Step 2a-fix: Fix ERROR orders that are actually in Oracle
|
||||
# (can happen if previous import committed partially without rollback)
|
||||
await _fix_stale_error_orders(existing_map, run_id)
|
||||
|
||||
# Step 2b: Validate SKUs (reuse same connection)
|
||||
all_skus = order_reader.get_all_skus(orders)
|
||||
validation = await asyncio.to_thread(validation_service.validate_skus, all_skus, conn)
|
||||
@@ -447,6 +485,7 @@ async def run_sync(id_pol: int = None, id_sectie: int = None, run_id: str = None
|
||||
total_fara_tva=inv.get("total_fara_tva"),
|
||||
total_tva=inv.get("total_tva"),
|
||||
total_cu_tva=inv.get("total_cu_tva"),
|
||||
data_act=inv.get("data_act"),
|
||||
)
|
||||
invoices_updated += 1
|
||||
if invoices_updated:
|
||||
|
||||
Reference in New Issue
Block a user