refactor(price): remove price comparison UI and catalog sync
GoMag vs ROA price comparison generated too many false positives (kits, volume discounts, special prices). Removes comparison columns, dots, badges, catalog sync endpoints, and ~950 lines of dead code. Keeps WRITE path (sync_prices_from_order) for kit pricing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -588,193 +588,3 @@ def sync_prices_from_order(orders, mapped_codmat_data: dict, direct_id_map: dict
|
||||
return updated
|
||||
|
||||
|
||||
def get_prices_for_order(items: list[dict], app_settings: dict, conn=None) -> dict:
|
||||
"""Compare GoMag prices with ROA prices for order items.
|
||||
|
||||
Args:
|
||||
items: list of order items, each with 'sku', 'price', 'quantity', 'codmat_details'
|
||||
(codmat_details = [{"codmat", "cantitate_roa", "id_articol"?, "cont"?, "direct"?}])
|
||||
app_settings: dict with 'id_pol', 'id_pol_productie'
|
||||
conn: Oracle connection (optional, will acquire if None)
|
||||
|
||||
Returns: {
|
||||
"items": {idx: {"pret_roa": float|None, "match": bool|None, "pret_gomag": float}},
|
||||
"summary": {"mismatches": int, "checked": int, "oracle_available": bool}
|
||||
}
|
||||
"""
|
||||
try:
|
||||
id_pol = int(app_settings.get("id_pol", 0) or 0)
|
||||
id_pol_productie = int(app_settings.get("id_pol_productie", 0) or 0)
|
||||
except (ValueError, TypeError):
|
||||
id_pol = 0
|
||||
id_pol_productie = 0
|
||||
|
||||
def _empty_result(oracle_available: bool) -> dict:
|
||||
return {
|
||||
"items": {
|
||||
idx: {"pret_roa": None, "match": None, "pret_gomag": float(item.get("price") or 0)}
|
||||
for idx, item in enumerate(items)
|
||||
},
|
||||
"summary": {"mismatches": 0, "checked": 0, "oracle_available": oracle_available}
|
||||
}
|
||||
|
||||
if not items or not id_pol:
|
||||
return _empty_result(oracle_available=False)
|
||||
|
||||
own_conn = conn is None
|
||||
try:
|
||||
if own_conn:
|
||||
conn = database.get_oracle_connection()
|
||||
|
||||
# Step 1: Collect codmats; use id_articol/cont from codmat_details when already known
|
||||
pre_resolved = {} # {codmat: {"id_articol": int, "cont": str}}
|
||||
all_codmats = set()
|
||||
for item in items:
|
||||
for cd in (item.get("codmat_details") or []):
|
||||
codmat = cd.get("codmat")
|
||||
if not codmat:
|
||||
continue
|
||||
all_codmats.add(codmat)
|
||||
if cd.get("id_articol") and codmat not in pre_resolved:
|
||||
pre_resolved[codmat] = {
|
||||
"id_articol": cd["id_articol"],
|
||||
"cont": cd.get("cont") or "",
|
||||
}
|
||||
|
||||
# Step 2: Resolve missing id_articols via nom_articole
|
||||
need_resolve = all_codmats - set(pre_resolved.keys())
|
||||
if need_resolve:
|
||||
db_resolved = resolve_codmat_ids(need_resolve, conn=conn)
|
||||
pre_resolved.update(db_resolved)
|
||||
|
||||
codmat_info = pre_resolved # {codmat: {"id_articol": int, "cont": str}}
|
||||
|
||||
# Step 3: Get PRETURI_CU_TVA flag once per policy
|
||||
policies = {id_pol}
|
||||
if id_pol_productie and id_pol_productie != id_pol:
|
||||
policies.add(id_pol_productie)
|
||||
|
||||
pol_cu_tva = {} # {id_pol: bool}
|
||||
with conn.cursor() as cur:
|
||||
for pol in policies:
|
||||
cur.execute(
|
||||
"SELECT PRETURI_CU_TVA FROM CRM_POLITICI_PRETURI WHERE ID_POL = :pol",
|
||||
{"pol": pol},
|
||||
)
|
||||
row = cur.fetchone()
|
||||
pol_cu_tva[pol] = (int(row[0] or 0) == 1) if row else False
|
||||
|
||||
# Step 4: Batch query PRET + PROC_TVAV for all id_articols across both policies
|
||||
all_id_articols = list({
|
||||
info["id_articol"]
|
||||
for info in codmat_info.values()
|
||||
if info.get("id_articol")
|
||||
})
|
||||
price_map = {} # {(id_pol, id_articol): (pret, proc_tvav)}
|
||||
|
||||
if all_id_articols:
|
||||
pol_list = list(policies)
|
||||
pol_placeholders = ",".join([f":p{k}" for k in range(len(pol_list))])
|
||||
with conn.cursor() as cur:
|
||||
for i in range(0, len(all_id_articols), 500):
|
||||
batch = all_id_articols[i:i + 500]
|
||||
art_placeholders = ",".join([f":a{j}" for j in range(len(batch))])
|
||||
params = {f"a{j}": aid for j, aid in enumerate(batch)}
|
||||
for k, pol in enumerate(pol_list):
|
||||
params[f"p{k}"] = pol
|
||||
cur.execute(f"""
|
||||
SELECT ID_POL, ID_ARTICOL, PRET, PROC_TVAV
|
||||
FROM CRM_POLITICI_PRET_ART
|
||||
WHERE ID_POL IN ({pol_placeholders}) AND ID_ARTICOL IN ({art_placeholders})
|
||||
""", params)
|
||||
for row in cur:
|
||||
price_map[(row[0], row[1])] = (row[2], row[3])
|
||||
|
||||
# Step 5: Compute pret_roa per item and compare with GoMag price
|
||||
result_items = {}
|
||||
mismatches = 0
|
||||
checked = 0
|
||||
|
||||
for idx, item in enumerate(items):
|
||||
pret_gomag = float(item.get("price") or 0)
|
||||
result_items[idx] = {"pret_gomag": pret_gomag, "pret_roa": None, "match": None}
|
||||
|
||||
codmat_details = item.get("codmat_details") or []
|
||||
if not codmat_details:
|
||||
continue
|
||||
|
||||
is_kit = len(codmat_details) > 1 or (
|
||||
len(codmat_details) == 1
|
||||
and float(codmat_details[0].get("cantitate_roa") or 1) != 1
|
||||
)
|
||||
|
||||
if is_kit:
|
||||
# Kit/pachet: prețul GoMag e comercial, ROA e suma componente din lista
|
||||
# de prețuri — diferența e gestionată de discount line
|
||||
result_items[idx]["kit"] = True
|
||||
continue
|
||||
|
||||
pret_roa_total = 0.0
|
||||
all_resolved = True
|
||||
|
||||
for cd in codmat_details:
|
||||
codmat = cd.get("codmat")
|
||||
if not codmat:
|
||||
all_resolved = False
|
||||
break
|
||||
|
||||
info = codmat_info.get(codmat, {})
|
||||
id_articol = info.get("id_articol")
|
||||
if not id_articol:
|
||||
all_resolved = False
|
||||
break
|
||||
|
||||
# Dual-policy routing: cont 341/345 → production, else → sales
|
||||
cont = str(info.get("cont") or cd.get("cont") or "").strip()
|
||||
if cont in ("341", "345") and id_pol_productie:
|
||||
pol = id_pol_productie
|
||||
else:
|
||||
pol = id_pol
|
||||
|
||||
price_entry = price_map.get((pol, id_articol))
|
||||
if price_entry is None:
|
||||
all_resolved = False
|
||||
break
|
||||
|
||||
pret, proc_tvav = price_entry
|
||||
proc_tvav = float(proc_tvav or 1.19)
|
||||
|
||||
if pol_cu_tva.get(pol):
|
||||
pret_cu_tva = float(pret or 0)
|
||||
else:
|
||||
pret_cu_tva = float(pret or 0) * proc_tvav
|
||||
|
||||
cantitate_roa = float(cd.get("cantitate_roa") or 1)
|
||||
if is_kit:
|
||||
pret_roa_total += pret_cu_tva * cantitate_roa
|
||||
else:
|
||||
pret_roa_total = pret_cu_tva # cantitate_roa==1 for simple items
|
||||
|
||||
if not all_resolved:
|
||||
continue
|
||||
|
||||
pret_roa = round(pret_roa_total, 4)
|
||||
match = pret_gomag <= pret_roa + 0.01
|
||||
result_items[idx]["pret_roa"] = pret_roa
|
||||
result_items[idx]["match"] = match
|
||||
checked += 1
|
||||
if not match:
|
||||
mismatches += 1
|
||||
|
||||
logger.info(f"get_prices_for_order: {checked}/{len(items)} checked, {mismatches} mismatches")
|
||||
return {
|
||||
"items": result_items,
|
||||
"summary": {"mismatches": mismatches, "checked": checked, "oracle_available": True},
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"get_prices_for_order failed: {e}")
|
||||
return _empty_result(oracle_available=False)
|
||||
finally:
|
||||
if own_conn and conn:
|
||||
database.pool.release(conn)
|
||||
|
||||
Reference in New Issue
Block a user