Release v4928.1.4.2 stable
This commit is contained in:
89
tests/test_v4911_odoo_name_match_reconciliation.py
Normal file
89
tests/test_v4911_odoo_name_match_reconciliation.py
Normal file
@@ -0,0 +1,89 @@
|
||||
"""v4.9.11 regression tests for Odoo name-only reconciliation.
|
||||
|
||||
Odoo customers may not have VAT/NIF filled in. Reconciliation should still be
|
||||
able to suggest/link by normalized company name and should not abort the whole
|
||||
process candidate list when an individual suggestion lookup fails.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import types
|
||||
|
||||
if "sqlalchemy" not in sys.modules:
|
||||
sqlalchemy = types.ModuleType("sqlalchemy")
|
||||
sqlalchemy.text = lambda sql: sql
|
||||
sys.modules["sqlalchemy"] = sqlalchemy
|
||||
|
||||
if "app.db" not in sys.modules:
|
||||
app_db = types.ModuleType("app.db")
|
||||
app_db.engine = object()
|
||||
sys.modules["app.db"] = app_db
|
||||
|
||||
if "app.action_catalog" not in sys.modules:
|
||||
action_catalog = types.ModuleType("app.action_catalog")
|
||||
action_catalog.get_action_config = lambda code: {"route": "rever", "action": code, "action_required": True, "safe_to_post": False}
|
||||
sys.modules["app.action_catalog"] = action_catalog
|
||||
|
||||
from app import reconciliation_service as svc
|
||||
|
||||
|
||||
def test_company_name_normalization_matches_odoo_without_nif():
|
||||
score = svc._name_match_score(
|
||||
"ELEGANTLEGACY, LDA VALONGO Portugal",
|
||||
"Elegantlegacy Lda",
|
||||
"Oportunidade · elegantlegacy",
|
||||
)
|
||||
assert score >= 35
|
||||
|
||||
|
||||
def test_single_odoo_sale_without_nif_becomes_process_candidate(monkeypatch):
|
||||
monkeypatch.setattr(
|
||||
svc,
|
||||
"list_reconciliation_items",
|
||||
lambda *, status, limit, days: [
|
||||
{
|
||||
"id": "odoo-sale-274",
|
||||
"source_system": "odoo",
|
||||
"external_type": "odoo_sale_order",
|
||||
"title": "Venda Odoo sem oportunidade · S00274",
|
||||
"customer_name": "ELEGANTLEGACY, LDA",
|
||||
"customer_tax_id": "",
|
||||
"customer_email": "",
|
||||
"document_number": "S00274",
|
||||
"document_date": "2026-06-02",
|
||||
"amount": "537.00",
|
||||
"currency": "EUR",
|
||||
"operation_suggestions": [],
|
||||
}
|
||||
],
|
||||
)
|
||||
|
||||
candidates = svc.list_reconciliation_process_candidates(status="open", days=7, limit=10)
|
||||
|
||||
assert len(candidates) == 1
|
||||
candidate = candidates[0]
|
||||
assert candidate["match_key"] == "name"
|
||||
assert candidate["confidence"] == "alta"
|
||||
assert candidate["identity_reason"] == "nome fiscal"
|
||||
assert candidate["customer_name"] == "ELEGANTLEGACY, LDA"
|
||||
assert candidate["suggested_stage"] == "ODOO_ORDER_CREATED"
|
||||
assert candidate["suggested_action"] == "SEND_INVOICE"
|
||||
assert candidate["item_ids"] == ["odoo-sale-274"]
|
||||
|
||||
|
||||
def test_list_process_candidates_is_resilient_when_item_query_fails(monkeypatch):
|
||||
def fail_listing(*, status, limit, days):
|
||||
raise RuntimeError("simulated db lookup failure")
|
||||
|
||||
monkeypatch.setattr(svc, "list_reconciliation_items", fail_listing)
|
||||
|
||||
assert svc.list_reconciliation_process_candidates(status="open", days=7, limit=10) == []
|
||||
|
||||
|
||||
def test_person_name_only_is_not_high_confidence_identity():
|
||||
confidence, reason = svc._process_group_identity_label(
|
||||
"name",
|
||||
[{"customer_name": "Bruno Oliveira", "customer_tax_id": "", "source_system": "odoo"}],
|
||||
)
|
||||
|
||||
assert confidence == "média"
|
||||
assert reason == "nome"
|
||||
Reference in New Issue
Block a user