feat(address): ROA address cache refresh — 8-field format + manual refresh endpoint

Phase 5 address format upgrade (pre-existing working tree changes):
- import_service: extend vadrese_parteneri query to 8 fields (strada/numar/bloc/scara/apart/etaj/localitate/judet); strip trailing city name from address string passed to Oracle
- sync_service: extend _addr_match to compare bloc/scara/apart in addition to strada/numar
- 05_pack_import_parteneri.pck: updated PL/SQL package

New: address cache refresh mechanism:
- sqlite_service: add get_order_address_ids(), update_order_address_cache() (targeted 3-column update, no ANAF fields touched), get_orders_with_address_ids()
- sync.py: POST /api/orders/{order_number}/refresh-address endpoint (404/422/503/200); batch Oracle address refresh in refresh_invoices (single IN roundtrip, per-order mismatch recomputed)
- UI: refresh button (⟳) in ADRESE modal header (base.html); refreshOrderAddress() with loading state + toast (dashboard.js v43); window._detailOrderNumber global (shared.js v32)
- tests: TestRefreshOrderAddress — 4 tests (404, 422, 503, 200 with 8-field assert)

Oracle prod fix applied directly: ADRESE_PARTENERI id_adresa=4116 STRADA VASILE→VASILE GOLDIS

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-04-07 12:35:18 +00:00
parent a8ad54a604
commit ecde7fe440
10 changed files with 377 additions and 10 deletions

View File

@@ -1214,6 +1214,59 @@ async def update_gomag_addresses_batch(updates: list[dict]):
await db.close()
async def get_order_address_ids(order_number: str) -> dict | None:
"""Return id_adresa_livrare, id_adresa_facturare, adresa_*_gomag for an order."""
db = await get_sqlite()
try:
cursor = await db.execute("""SELECT id_adresa_livrare, id_adresa_facturare,
adresa_livrare_gomag, adresa_facturare_gomag,
adresa_livrare_roa
FROM orders WHERE order_number = ?""", [order_number])
row = await cursor.fetchone()
return dict(row) if row else None
finally:
await db.close()
async def update_order_address_cache(order_number: str, livr_roa: dict | None,
fact_roa: dict | None, mismatch: bool):
"""Update ONLY the 3 address-cache columns — does NOT touch ANAF/partner fields."""
db = await get_sqlite()
try:
await db.execute("""
UPDATE orders SET
adresa_livrare_roa = ?,
adresa_facturare_roa = ?,
address_mismatch = ?,
updated_at = datetime('now')
WHERE order_number = ?
""", (
json.dumps(livr_roa) if livr_roa else None,
json.dumps(fact_roa) if fact_roa else None,
1 if mismatch else 0,
order_number,
))
await db.commit()
finally:
await db.close()
async def get_orders_with_address_ids() -> list[dict]:
"""Get all orders that have Oracle address IDs stored (for batch refresh)."""
db = await get_sqlite()
try:
cursor = await db.execute("""
SELECT order_number, id_adresa_livrare, id_adresa_facturare,
adresa_livrare_gomag, adresa_facturare_gomag
FROM orders
WHERE id_adresa_livrare IS NOT NULL OR id_adresa_facturare IS NOT NULL
""")
rows = await cursor.fetchall()
return [dict(r) for r in rows]
finally:
await db.close()
async def get_orders_missing_anaf() -> list[dict]:
"""Get orders with cod_fiscal_roa set but no ANAF data (for backfill)."""
db = await get_sqlite()