fix: price sync kit components + vat_included type bug

- Fix vat_included comparison: GoMag API returns int 1, not str "1",
  causing all prices to be multiplied by TVA again (double TVA)
- Normalize vat_included to string in gomag_client at parse time
- Price sync now processes kit components individually by looking up
  each component's CODMAT as standalone GoMag product
- Add _insert_component_price for components without existing Oracle price
- resolve_mapped_codmats: ROW_NUMBER dedup for CODMATs with multiple
  NOM_ARTICOLE entries, prefer article with current stock
- pack_import_comenzi: merge_or_insert_articol to merge quantities when
  same article appears from kit + individual on same order

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-03-20 15:07:53 +00:00
parent 0666d6bcdf
commit b221b257a3
5 changed files with 189 additions and 37 deletions

View File

@@ -62,6 +62,35 @@ async def get_price_sync_status() -> dict:
await db.close()
def _insert_component_price(id_articol: int, id_pol: int, price_cu_tva: float,
proc_tvav: float, conn):
"""Insert a new price entry in crm_politici_pret_art for a kit component."""
with conn.cursor() as cur:
cur.execute("""
SELECT PRETURI_CU_TVA, ID_VALUTA FROM CRM_POLITICI_PRETURI WHERE ID_POL = :pol
""", {"pol": id_pol})
row = cur.fetchone()
if not row:
return
preturi_cu_tva, id_valuta = row
if preturi_cu_tva == 1:
pret = price_cu_tva
else:
pret = round(price_cu_tva / proc_tvav, 4)
cur.execute("""
INSERT INTO CRM_POLITICI_PRET_ART
(ID_POL, ID_ARTICOL, PRET, ID_VALUTA,
ID_UTIL, DATAORA, PROC_TVAV, PRETFTVA, PRETCTVA)
VALUES
(:id_pol, :id_articol, :pret, :id_valuta,
-3, SYSDATE, :proc_tvav, 0, 0)
""", {"id_pol": id_pol, "id_articol": id_articol, "pret": pret,
"id_valuta": id_valuta, "proc_tvav": proc_tvav})
conn.commit()
async def run_catalog_price_sync(run_id: str):
global _current_price_sync
async with _price_sync_lock:
@@ -96,6 +125,9 @@ async def run_catalog_price_sync(run_id: str):
await _finish_run(run_id, "completed", log_lines, products_total=0)
return
# Index products by SKU for kit component lookup
products_by_sku = {p["sku"]: p for p in products}
# Connect to Oracle
conn = await asyncio.to_thread(database.get_oracle_connection)
try:
@@ -136,16 +168,54 @@ async def run_catalog_price_sync(run_id: str):
continue
vat = float(product.get("vat", "19"))
vat_included = product.get("vat_included", "1")
# Calculate price with TVA
if vat_included == "1":
# Calculate price with TVA (vat_included can be int 1 or str "1")
if str(product.get("vat_included", "1")) == "1":
price_cu_tva = price
else:
price_cu_tva = price * (1 + vat / 100)
# Skip kits (>1 CODMAT)
# For kits, sync each component individually from standalone GoMag prices
if sku in mapped_data and len(mapped_data[sku]) > 1:
for comp in mapped_data[sku]:
comp_codmat = comp["codmat"]
comp_product = products_by_sku.get(comp_codmat)
if not comp_product:
continue # Component not in GoMag as standalone product
comp_price_str = comp_product.get("price", "0")
comp_price = float(comp_price_str) if comp_price_str else 0
if comp_price <= 0:
continue
comp_vat = float(comp_product.get("vat", "19"))
# vat_included can be int 1 or str "1"
if str(comp_product.get("vat_included", "1")) == "1":
comp_price_cu_tva = comp_price
else:
comp_price_cu_tva = comp_price * (1 + comp_vat / 100)
comp_cont_str = str(comp.get("cont") or "").strip()
comp_pol = id_pol_productie if (comp_cont_str in ("341", "345") and id_pol_productie) else id_pol
matched += 1
result = await asyncio.to_thread(
validation_service.compare_and_update_price,
comp["id_articol"], comp_pol, comp_price_cu_tva, conn
)
if result and result["updated"]:
updated += 1
_log(f" {comp_codmat}: {result['old_price']:.2f}{result['new_price']:.2f} (kit {sku})")
elif result is None:
# No price entry — insert one with correct price
proc_tvav = 1 + (comp_vat / 100)
await asyncio.to_thread(
_insert_component_price,
comp["id_articol"], comp_pol, comp_price_cu_tva, proc_tvav, conn
)
updated += 1
_log(f" {comp_codmat}: NOU → {comp_price_cu_tva:.2f} (kit {sku})")
continue
# Determine id_articol and policy