fix(address+ui): remove TIER 2 reuse, typed diff badges, false positive reduction

- Remove TIER 2 address lookup (county+city without street) from PL/SQL — creates
  new address when street differs instead of reusing wrong one
- Replace generic "N diferente" badge with typed micro-badges (CUI, Denumire, TVA,
  Adr. livr., Adr. fact., Preturi) with red/amber semantic colors
- Extend addrMatch() regex to strip full Romanian address words (STRADA, NUMAR, BLOC,
  COMUNA, SAT, MUNICIPIUL, etc.) — fixes "Strada X" vs "X" false positives
- Extend normalize_company_name() for II, PFA, INTREPRINDERE INDIVIDUALA legal forms
- Persist address_mismatch to SQLite so "Dif." filter includes address-only diffs
- Add red/amber indicator dots to desktop table and mobile list rows
- 12 unit tests for normalization and server-side address matching

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-04-06 14:28:57 +00:00
parent fc1013bff6
commit 31095c07f7
11 changed files with 160 additions and 44 deletions

View File

@@ -634,3 +634,85 @@ class TestGetPricesForOrderCantitateRoa:
assert result["items"][0]["match"] is None
assert result["items"][0]["kit"] is True
assert result["summary"]["mismatches"] == 0
# ── normalize_company_name (II, PFA, INTREPRINDERE INDIVIDUALA) ──
class TestNormalizeCompanyNameExtended:
"""Tests for extended legal form stripping in normalize_company_name."""
def test_strip_ii_at_start(self):
from app.services.anaf_service import normalize_company_name
assert normalize_company_name("II CHIRITA N ION") == "CHIRITA N ION"
def test_no_strip_ii_mid_name(self):
from app.services.anaf_service import normalize_company_name
result = normalize_company_name("TEHNICA II SRL")
assert "II" in result # II should remain (Roman numeral)
def test_strip_pfa(self):
from app.services.anaf_service import normalize_company_name
assert normalize_company_name("PFA POPESCU ION") == "POPESCU ION"
def test_strip_intreprindere_individuala(self):
from app.services.anaf_service import normalize_company_name
result = normalize_company_name("CHIRIȚĂ N. ION ÎNTREPRINDERE INDIVIDUALĂ")
assert "CHIRITA N ION" == result
def test_strip_ii_with_dots(self):
from app.services.anaf_service import normalize_company_name
assert normalize_company_name("I.I. CHIRITA N ION") == "CHIRITA N ION"
# ── _addr_match (server-side address comparison) ─<><E29480><EFBFBD>
class TestAddrMatch:
"""Tests for _addr_match server-side address comparison."""
def test_matching_addresses(self):
from app.services.sync_service import _addr_match
import json
g = json.dumps({"address": "Str. Elisabeta 10", "city": "Bucuresti", "region": "Bucuresti"})
r = json.dumps({"strada": "Elisabeta", "numar": "10", "localitate": "Bucuresti", "judet": "Bucuresti"})
assert _addr_match(g, r) is True
def test_street_mismatch(self):
from app.services.sync_service import _addr_match
import json
g = json.dumps({"address": "Str. Elisabeta 10", "city": "Bucuresti", "region": "Bucuresti"})
r = json.dumps({"strada": "Victoriei", "numar": "10", "localitate": "Bucuresti", "judet": "Bucuresti"})
assert _addr_match(g, r) is False
def test_city_mismatch(self):
from app.services.sync_service import _addr_match
import json
g = json.dumps({"address": "Elisabeta 10", "city": "Brasov", "region": "Brasov"})
r = json.dumps({"strada": "Elisabeta", "numar": "10", "localitate": "Cluj", "judet": "Brasov"})
assert _addr_match(g, r) is False
def test_county_mismatch(self):
from app.services.sync_service import _addr_match
import json
g = json.dumps({"address": "Elisabeta 10", "city": "Brasov", "region": "Brasov"})
r = json.dumps({"strada": "Elisabeta", "numar": "10", "localitate": "Brasov", "judet": "Cluj"})
assert _addr_match(g, r) is False
def test_none_input_returns_true(self):
from app.services.sync_service import _addr_match
assert _addr_match(None, None) is True
assert _addr_match(None, '{"strada":"x"}') is True
assert _addr_match('{"address":"x"}', None) is True
def test_strada_prefix_stripping(self):
"""'Strada Elisabeta' should match 'ELISABETA' after normalization."""
from app.services.sync_service import _addr_match
import json
g = json.dumps({"address": "Strada Elisabeta 10", "city": "Bucuresti", "region": "Bucuresti"})
r = json.dumps({"strada": "Elisabeta", "numar": "10", "localitate": "Bucuresti", "judet": "Bucuresti"})
assert _addr_match(g, r) is True
def test_malformed_json_returns_true(self):
from app.services.sync_service import _addr_match
assert _addr_match("{bad json", '{"strada":"x"}') is True