feat(import): confirmare valori needs_review in bloc + rapid din tabel (B1)
Randurile needs_review (flaguri de coercion: VIN citit ca numar, odometru
float, data ambigua) cereau confirmare umana DOAR prin modalul de editare,
un rand pe rand. Adauga doua cai care pastreaza omul in bucla (fara
auto-accept):
- Buton "Confirma toate valorile" (bulk): ruta noua
POST /_import/{id}/confirma-toate-review marcheaza reviewed=1 pe TOATE
randurile needs_review din batch cu un click. Scoped pe cont (404
cross-account, 409 batch comis), o singura recompute + re-randare
#import-section, dupa modelul web_mapare_operatii.
- Confirm rapid per-rand direct din tabel: buton in coloana Actiuni pe
randurile needs_review, refoloseste ruta existenta /confirma-review
(reviewed=1 pe un singur rand) cu hx-swap="none"; HX-Trigger
reincarcaPreview reincarca sectiunea cu contoare/banner corecte.
Butonul bulk e randat in bannerul de discoverability (si in varianta OOB
din _preview_rand.html). Editarea unei valori reseteaza reviewed=0 ca
inainte (D#9, neschimbat).
Teste noi (tests/test_import_review.py): bulk marcheaza toate randurile,
guard committed 409, scoping 404 cross-account (fara efect pe randurile
altui cont), prezenta butonului rapid in tabel, confirm rapid per-rand
seteaza reviewed=1 fara a atinge alte randuri.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3611,6 +3611,63 @@ async def web_confirma_review(
|
||||
conn.close()
|
||||
|
||||
|
||||
@router.post("/_import/{import_id}/confirma-toate-review", response_class=HTMLResponse)
|
||||
async def web_confirma_toate_review(
|
||||
request: Request,
|
||||
import_id: int,
|
||||
) -> HTMLResponse:
|
||||
"""Confirma in bloc TOATE randurile needs_review din batch → reviewed=1 (B1).
|
||||
|
||||
Un singur click marcheaza reviewed=1 pe toate randurile cu resolved_status='needs_review'
|
||||
din batch-ul curent (om in bucla: operatorul confirma explicit intreg lotul, fara
|
||||
auto-accept). Refoloseste EXACT logica din /confirma-review (reviewed=1 = marcaj separat,
|
||||
NU camp de continut), aplicata in masa. La recalcul (_web_compute_preview) randurile cu
|
||||
reviewed=1 si fara erori reale devin ok.
|
||||
|
||||
CSRF + scoped sesiune (404 cross-account) + guard committed (409). O singura recompute
|
||||
+ re-randare #import-section la final (identic cu web_mapare_operatii).
|
||||
"""
|
||||
account_id = require_login(request)
|
||||
conn = get_connection()
|
||||
try:
|
||||
form = await request.form()
|
||||
verify_csrf(request, str(form.get("csrf_token") or ""))
|
||||
|
||||
# Guard batch: 404 cross-account (nu confirmam existenta), 409 committed.
|
||||
acct = account_or_default(account_id)
|
||||
batch = conn.execute(
|
||||
"SELECT id, status FROM import_batches WHERE id=? AND account_id=?",
|
||||
(import_id, acct),
|
||||
).fetchone()
|
||||
if not batch:
|
||||
raise HTTPException(status_code=404, detail="batch de import inexistent sau inaccesibil")
|
||||
if batch["status"] == "committed":
|
||||
raise HTTPException(status_code=409, detail="batch deja comis; confirmarea nu mai are efect")
|
||||
|
||||
# Marcheaza reviewed=1 pe toate randurile needs_review ale batch-ului (scoped pe batch,
|
||||
# deja verificat ca apartine contului). Acelasi marcaj ca /confirma-review, in masa.
|
||||
cur = conn.execute(
|
||||
"UPDATE import_rows SET reviewed=1 "
|
||||
"WHERE batch_id=? AND resolved_status='needs_review'",
|
||||
(import_id,),
|
||||
)
|
||||
n_confirmate = cur.rowcount if cur.rowcount is not None and cur.rowcount >= 0 else 0
|
||||
|
||||
message = (
|
||||
f"Confirmate {n_confirmate} randuri cu valori de verificat."
|
||||
if n_confirmate
|
||||
else "Niciun rand de confirmat."
|
||||
)
|
||||
result = _web_compute_preview(conn, import_id, account_id)
|
||||
if isinstance(result, str):
|
||||
return templates.TemplateResponse("_upload.html", _ctx(request, error=result))
|
||||
return templates.TemplateResponse("_preview_import.html", _ctx(
|
||||
request, import_id=import_id, message=message, **result
|
||||
))
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
@router.post("/_import/{import_id}/mapare-operatie", response_class=HTMLResponse)
|
||||
async def web_mapare_operatie(
|
||||
request: Request,
|
||||
|
||||
Reference in New Issue
Block a user