fix: kit discount amount + price sync no auto-insert + repackaging kit detection
Kit discount: v_disc_amt is per-kit, not per-unit — remove division by v_cantitate_web so discount lines compute correctly (e.g. -2 x 5 = -10). Price sync: stop auto-inserting missing articles into price policies (was inserting with wrong proc_tvav from GoMag). Log warning instead. Kit detection: extend to single-component repackagings (cantitate_roa > 1) in both PL/SQL package and price sync/validation services. Add repackaging kit pricing test for separate_line and distributed modes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -62,35 +62,6 @@ async def get_price_sync_status() -> dict:
|
|||||||
await db.close()
|
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):
|
async def run_catalog_price_sync(run_id: str):
|
||||||
global _current_price_sync
|
global _current_price_sync
|
||||||
async with _price_sync_lock:
|
async with _price_sync_lock:
|
||||||
@@ -176,7 +147,11 @@ async def run_catalog_price_sync(run_id: str):
|
|||||||
price_cu_tva = price * (1 + vat / 100)
|
price_cu_tva = price * (1 + vat / 100)
|
||||||
|
|
||||||
# For kits, sync each component individually from standalone GoMag prices
|
# For kits, sync each component individually from standalone GoMag prices
|
||||||
if sku in mapped_data and len(mapped_data[sku]) > 1:
|
mapped_comps = mapped_data.get(sku, [])
|
||||||
|
is_kit = len(mapped_comps) > 1 or (
|
||||||
|
len(mapped_comps) == 1 and (mapped_comps[0].get("cantitate_roa") or 1) > 1
|
||||||
|
)
|
||||||
|
if is_kit:
|
||||||
for comp in mapped_data[sku]:
|
for comp in mapped_data[sku]:
|
||||||
comp_codmat = comp["codmat"]
|
comp_codmat = comp["codmat"]
|
||||||
comp_product = products_by_sku.get(comp_codmat)
|
comp_product = products_by_sku.get(comp_codmat)
|
||||||
@@ -208,21 +183,14 @@ async def run_catalog_price_sync(run_id: str):
|
|||||||
updated += 1
|
updated += 1
|
||||||
_log(f" {comp_codmat}: {result['old_price']:.2f} → {result['new_price']:.2f} (kit {sku})")
|
_log(f" {comp_codmat}: {result['old_price']:.2f} → {result['new_price']:.2f} (kit {sku})")
|
||||||
elif result is None:
|
elif result is None:
|
||||||
# No price entry — insert one with correct price
|
_log(f" {comp_codmat}: LIPSESTE din politica {comp_pol} — adauga manual in ROA (kit {sku})")
|
||||||
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
|
continue
|
||||||
|
|
||||||
# Determine id_articol and policy
|
# Determine id_articol and policy
|
||||||
id_articol = None
|
id_articol = None
|
||||||
cantitate_roa = 1
|
cantitate_roa = 1
|
||||||
|
|
||||||
if sku in mapped_data and len(mapped_data[sku]) == 1:
|
if sku in mapped_data and len(mapped_data[sku]) == 1 and (mapped_data[sku][0].get("cantitate_roa") or 1) <= 1:
|
||||||
comp = mapped_data[sku][0]
|
comp = mapped_data[sku][0]
|
||||||
id_articol = comp["id_articol"]
|
id_articol = comp["id_articol"]
|
||||||
cantitate_roa = comp.get("cantitate_roa") or 1
|
cantitate_roa = comp.get("cantitate_roa") or 1
|
||||||
@@ -236,7 +204,7 @@ async def run_catalog_price_sync(run_id: str):
|
|||||||
|
|
||||||
# Determine policy
|
# Determine policy
|
||||||
cont = None
|
cont = None
|
||||||
if sku in mapped_data and len(mapped_data[sku]) == 1:
|
if sku in mapped_data and len(mapped_data[sku]) == 1 and (mapped_data[sku][0].get("cantitate_roa") or 1) <= 1:
|
||||||
cont = mapped_data[sku][0].get("cont")
|
cont = mapped_data[sku][0].get("cont")
|
||||||
elif sku in direct_id_map:
|
elif sku in direct_id_map:
|
||||||
cont = direct_id_map[sku].get("cont")
|
cont = direct_id_map[sku].get("cont")
|
||||||
|
|||||||
@@ -450,8 +450,10 @@ def validate_kit_component_prices(mapped_codmat_data: dict, id_pol: int,
|
|||||||
try:
|
try:
|
||||||
with conn.cursor() as cur:
|
with conn.cursor() as cur:
|
||||||
for sku, components in mapped_codmat_data.items():
|
for sku, components in mapped_codmat_data.items():
|
||||||
if len(components) <= 1:
|
if len(components) == 0:
|
||||||
continue # Not a kit
|
continue
|
||||||
|
if len(components) == 1 and (components[0].get("cantitate_roa") or 1) <= 1:
|
||||||
|
continue # True 1:1 mapping, no kit pricing needed
|
||||||
sku_missing = []
|
sku_missing = []
|
||||||
for comp in components:
|
for comp in components:
|
||||||
cont = str(comp.get("cont") or "").strip()
|
cont = str(comp.get("cont") or "").strip()
|
||||||
|
|||||||
@@ -63,6 +63,9 @@
|
|||||||
-- 20.03.2026 - dual policy vanzare/productie, kit pricing distributed/separate_line, SKU→CODMAT via ARTICOLE_TERTI
|
-- 20.03.2026 - dual policy vanzare/productie, kit pricing distributed/separate_line, SKU→CODMAT via ARTICOLE_TERTI
|
||||||
-- 20.03.2026 - kit discount deferred cross-kit (separate_line, merge-on-collision)
|
-- 20.03.2026 - kit discount deferred cross-kit (separate_line, merge-on-collision)
|
||||||
-- 20.03.2026 - merge_or_insert_articol: merge cantitati cand kit+individual au acelasi articol/pret
|
-- 20.03.2026 - merge_or_insert_articol: merge cantitati cand kit+individual au acelasi articol/pret
|
||||||
|
-- 20.03.2026 - kit pricing extins pt reambalari single-component (cantitate_roa > 1)
|
||||||
|
-- 21.03.2026 - diagnostic detaliat discount kit (id_pol, id_art, codmat in eroare)
|
||||||
|
-- 21.03.2026 - fix discount amount: v_disc_amt e per-kit, nu se imparte la v_cantitate_web
|
||||||
-- ====================================================================
|
-- ====================================================================
|
||||||
CREATE OR REPLACE PACKAGE PACK_IMPORT_COMENZI AS
|
CREATE OR REPLACE PACKAGE PACK_IMPORT_COMENZI AS
|
||||||
|
|
||||||
@@ -262,6 +265,7 @@ CREATE OR REPLACE PACKAGE BODY PACK_IMPORT_COMENZI AS
|
|||||||
|
|
||||||
-- Variabile kit pricing
|
-- Variabile kit pricing
|
||||||
v_kit_count NUMBER := 0;
|
v_kit_count NUMBER := 0;
|
||||||
|
v_max_cant_roa NUMBER := 1;
|
||||||
v_kit_comps t_kit_components;
|
v_kit_comps t_kit_components;
|
||||||
v_sum_list_prices NUMBER;
|
v_sum_list_prices NUMBER;
|
||||||
v_discount_total NUMBER;
|
v_discount_total NUMBER;
|
||||||
@@ -366,15 +370,17 @@ CREATE OR REPLACE PACKAGE BODY PACK_IMPORT_COMENZI AS
|
|||||||
v_found_mapping := FALSE;
|
v_found_mapping := FALSE;
|
||||||
|
|
||||||
-- Numara randurile ARTICOLE_TERTI pentru a detecta kituri (>1 rand = set compus)
|
-- Numara randurile ARTICOLE_TERTI pentru a detecta kituri (>1 rand = set compus)
|
||||||
SELECT COUNT(*) INTO v_kit_count
|
SELECT COUNT(*), NVL(MAX(at.cantitate_roa), 1)
|
||||||
|
INTO v_kit_count, v_max_cant_roa
|
||||||
FROM articole_terti at
|
FROM articole_terti at
|
||||||
WHERE at.sku = v_sku
|
WHERE at.sku = v_sku
|
||||||
AND at.activ = 1
|
AND at.activ = 1
|
||||||
AND at.sters = 0;
|
AND at.sters = 0;
|
||||||
|
|
||||||
IF v_kit_count > 1 AND p_kit_mode IS NOT NULL THEN
|
IF ((v_kit_count > 1) OR (v_kit_count = 1 AND v_max_cant_roa > 1))
|
||||||
|
AND p_kit_mode IS NOT NULL THEN
|
||||||
-- ============================================================
|
-- ============================================================
|
||||||
-- KIT PRICING: set compus cu >1 componente, mod activ
|
-- KIT PRICING: set compus (>1 componente) sau reambalare (cantitate_roa>1), mod activ
|
||||||
-- Prima trecere: colecteaza componente + preturi din politici
|
-- Prima trecere: colecteaza componente + preturi din politici
|
||||||
-- ============================================================
|
-- ============================================================
|
||||||
v_found_mapping := TRUE;
|
v_found_mapping := TRUE;
|
||||||
@@ -573,7 +579,7 @@ CREATE OR REPLACE PACKAGE BODY PACK_IMPORT_COMENZI AS
|
|||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
IF v_disc_amt != 0 THEN
|
IF v_disc_amt != 0 THEN
|
||||||
v_unit_pret := v_disc_amt / v_cantitate_web;
|
v_unit_pret := v_disc_amt;
|
||||||
|
|
||||||
-- Search for existing entry with same (ptva, pret) to merge qty
|
-- Search for existing entry with same (ptva, pret) to merge qty
|
||||||
v_kit_disc_found := FALSE;
|
v_kit_disc_found := FALSE;
|
||||||
@@ -707,7 +713,10 @@ CREATE OR REPLACE PACKAGE BODY PACK_IMPORT_COMENZI AS
|
|||||||
WHEN OTHERS THEN
|
WHEN OTHERS THEN
|
||||||
v_articole_eroare := v_articole_eroare + 1;
|
v_articole_eroare := v_articole_eroare + 1;
|
||||||
g_last_error := g_last_error || CHR(10) ||
|
g_last_error := g_last_error || CHR(10) ||
|
||||||
'Eroare linie discount kit TVA=' || v_kit_disc_list(j).ptva || '%: ' || SQLERRM;
|
'Eroare linie discount kit TVA=' || v_kit_disc_list(j).ptva ||
|
||||||
|
'% id_pol=' || NVL(p_kit_discount_id_pol, p_id_pol) ||
|
||||||
|
' id_art=' || v_disc_artid ||
|
||||||
|
' codmat=' || p_kit_discount_codmat || ': ' || SQLERRM;
|
||||||
END;
|
END;
|
||||||
END LOOP;
|
END LOOP;
|
||||||
END IF;
|
END IF;
|
||||||
|
|||||||
@@ -45,6 +45,14 @@ INSERT INTO NOM_ARTICOLE (
|
|||||||
-3, SYSDATE
|
-3, SYSDATE
|
||||||
);
|
);
|
||||||
|
|
||||||
|
-- Price entry for CAF01 in default price policy (id_pol=1)
|
||||||
|
-- Used for single-component repackaging kit pricing test
|
||||||
|
MERGE INTO crm_politici_pret_art dst
|
||||||
|
USING (SELECT 1 AS id_pol, 9999001 AS id_articol FROM DUAL) src
|
||||||
|
ON (dst.id_pol = src.id_pol AND dst.id_articol = src.id_articol)
|
||||||
|
WHEN NOT MATCHED THEN INSERT (id_pol, id_articol, pret, proc_tvav)
|
||||||
|
VALUES (src.id_pol, src.id_articol, 51.50, 19);
|
||||||
|
|
||||||
-- Create test mappings in ARTICOLE_TERTI
|
-- Create test mappings in ARTICOLE_TERTI
|
||||||
-- CAFE100 -> CAF01 (repackaging: 10x1kg = 1x10kg web package)
|
-- CAFE100 -> CAF01 (repackaging: 10x1kg = 1x10kg web package)
|
||||||
INSERT INTO ARTICOLE_TERTI (sku, codmat, cantitate_roa, procent_pret, activ)
|
INSERT INTO ARTICOLE_TERTI (sku, codmat, cantitate_roa, procent_pret, activ)
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
-- Cleanup test data created for Phase 1 validation tests
|
-- Cleanup test data created for Phase 1 validation tests
|
||||||
-- Remove test articles and mappings to leave database clean
|
-- Remove test articles and mappings to leave database clean
|
||||||
|
|
||||||
|
-- Remove test price entry
|
||||||
|
DELETE FROM crm_politici_pret_art WHERE id_pol = 1 AND id_articol = 9999001;
|
||||||
|
|
||||||
-- Remove test mappings
|
-- Remove test mappings
|
||||||
DELETE FROM ARTICOLE_TERTI WHERE sku IN ('CAFE100', '8000070028685', 'TEST001');
|
DELETE FROM ARTICOLE_TERTI WHERE sku IN ('CAFE100', '8000070028685', 'TEST001');
|
||||||
|
|
||||||
|
|||||||
@@ -330,6 +330,204 @@ def test_complete_import():
|
|||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def test_repackaging_kit_pricing():
|
||||||
|
"""
|
||||||
|
Test single-component repackaging with kit pricing.
|
||||||
|
CAFE100 -> CAF01 with cantitate_roa=10 (1 web package = 10 ROA units).
|
||||||
|
Verifies that kit pricing applies: list price per unit + discount line.
|
||||||
|
"""
|
||||||
|
print("\n" + "=" * 60)
|
||||||
|
print("🎯 REPACKAGING KIT PRICING TEST")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
success_count = 0
|
||||||
|
total_tests = 0
|
||||||
|
|
||||||
|
try:
|
||||||
|
with oracledb.connect(user=user, password=password, dsn=dsn) as conn:
|
||||||
|
with conn.cursor() as cur:
|
||||||
|
unique_suffix = random.randint(1000, 9999)
|
||||||
|
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||||
|
|
||||||
|
setup_test_data(cur)
|
||||||
|
|
||||||
|
# Create a test partner
|
||||||
|
partner_var = cur.var(oracledb.NUMBER)
|
||||||
|
partner_name = f'Test Repack {timestamp}-{unique_suffix}'
|
||||||
|
cur.execute("""
|
||||||
|
DECLARE v_id NUMBER;
|
||||||
|
BEGIN
|
||||||
|
v_id := PACK_IMPORT_PARTENERI.cauta_sau_creeaza_partener(
|
||||||
|
NULL, :name, 'JUD:Bucuresti;BUCURESTI;Str Test;1',
|
||||||
|
'0720000000', 'repack@test.com');
|
||||||
|
:result := v_id;
|
||||||
|
END;
|
||||||
|
""", {'name': partner_name, 'result': partner_var})
|
||||||
|
partner_id = partner_var.getvalue()
|
||||||
|
if not partner_id or partner_id <= 0:
|
||||||
|
print(" SKIP: Could not create test partner")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# ---- Test separate_line mode ----
|
||||||
|
total_tests += 1
|
||||||
|
order_number = f'TEST-REPACK-SEP-{timestamp}-{unique_suffix}'
|
||||||
|
# Web price: 2 packages * 10 units * some_price = total
|
||||||
|
# With list price 51.50/unit, 2 packs of 10 = 20 units
|
||||||
|
# Web price per package = 450 lei => total web = 900
|
||||||
|
# Expected: 20 units @ 51.50 = 1030, discount = 130
|
||||||
|
web_price_per_pack = 450.0
|
||||||
|
articles_json = f'[{{"sku": "CAFE100", "cantitate": 2, "pret": {web_price_per_pack}}}]'
|
||||||
|
|
||||||
|
print(f"\n1. Testing separate_line mode: {order_number}")
|
||||||
|
print(f" CAFE100 x2 @ {web_price_per_pack} lei/pack, cantitate_roa=10")
|
||||||
|
|
||||||
|
result_var = cur.var(oracledb.NUMBER)
|
||||||
|
cur.execute("""
|
||||||
|
DECLARE v_id NUMBER;
|
||||||
|
BEGIN
|
||||||
|
PACK_IMPORT_COMENZI.importa_comanda(
|
||||||
|
:order_number, SYSDATE, :partner_id,
|
||||||
|
:articles_json,
|
||||||
|
NULL, NULL,
|
||||||
|
1, -- id_pol (default price policy)
|
||||||
|
NULL, NULL,
|
||||||
|
'separate_line', -- kit_mode
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
v_id);
|
||||||
|
:result := v_id;
|
||||||
|
END;
|
||||||
|
""", {
|
||||||
|
'order_number': order_number,
|
||||||
|
'partner_id': partner_id,
|
||||||
|
'articles_json': articles_json,
|
||||||
|
'result': result_var
|
||||||
|
})
|
||||||
|
|
||||||
|
order_id = result_var.getvalue()
|
||||||
|
if order_id and order_id > 0:
|
||||||
|
print(f" Order created: ID {order_id}")
|
||||||
|
|
||||||
|
cur.execute("""
|
||||||
|
SELECT ce.CANTITATE, ce.PRET, na.CODMAT, na.DENUMIRE
|
||||||
|
FROM COMENZI_ELEMENTE ce
|
||||||
|
JOIN NOM_ARTICOLE na ON ce.ID_ARTICOL = na.ID_ARTICOL
|
||||||
|
WHERE ce.ID_COMANDA = :oid
|
||||||
|
ORDER BY ce.CANTITATE DESC
|
||||||
|
""", {'oid': order_id})
|
||||||
|
rows = cur.fetchall()
|
||||||
|
|
||||||
|
if len(rows) >= 2:
|
||||||
|
# Should have article line + discount line
|
||||||
|
art_line = [r for r in rows if r[0] > 0]
|
||||||
|
disc_line = [r for r in rows if r[0] < 0]
|
||||||
|
|
||||||
|
if art_line and disc_line:
|
||||||
|
print(f" Article: qty={art_line[0][0]}, price={art_line[0][1]:.2f} ({art_line[0][2]})")
|
||||||
|
print(f" Discount: qty={disc_line[0][0]}, price={disc_line[0][1]:.2f}")
|
||||||
|
total = sum(r[0] * r[1] for r in rows)
|
||||||
|
expected_total = web_price_per_pack * 2
|
||||||
|
print(f" Total: {total:.2f} (expected: {expected_total:.2f})")
|
||||||
|
if abs(total - expected_total) < 0.02:
|
||||||
|
print(" PASS: Total matches web price")
|
||||||
|
success_count += 1
|
||||||
|
else:
|
||||||
|
print(" FAIL: Total mismatch")
|
||||||
|
else:
|
||||||
|
print(f" FAIL: Expected article + discount lines, got {len(art_line)} art / {len(disc_line)} disc")
|
||||||
|
elif len(rows) == 1:
|
||||||
|
print(f" FAIL: Only 1 line (no discount). qty={rows[0][0]}, price={rows[0][1]:.2f}")
|
||||||
|
print(" Kit pricing did NOT activate for single-component repackaging")
|
||||||
|
else:
|
||||||
|
print(" FAIL: No order lines found")
|
||||||
|
else:
|
||||||
|
cur.execute("SELECT PACK_IMPORT_COMENZI.get_last_error FROM DUAL")
|
||||||
|
err = cur.fetchone()[0]
|
||||||
|
print(f" FAIL: Order import failed: {err}")
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
|
# ---- Test distributed mode ----
|
||||||
|
total_tests += 1
|
||||||
|
order_number2 = f'TEST-REPACK-DIST-{timestamp}-{unique_suffix}'
|
||||||
|
print(f"\n2. Testing distributed mode: {order_number2}")
|
||||||
|
|
||||||
|
result_var2 = cur.var(oracledb.NUMBER)
|
||||||
|
cur.execute("""
|
||||||
|
DECLARE v_id NUMBER;
|
||||||
|
BEGIN
|
||||||
|
PACK_IMPORT_COMENZI.importa_comanda(
|
||||||
|
:order_number, SYSDATE, :partner_id,
|
||||||
|
:articles_json,
|
||||||
|
NULL, NULL,
|
||||||
|
1, NULL, NULL,
|
||||||
|
'distributed',
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
v_id);
|
||||||
|
:result := v_id;
|
||||||
|
END;
|
||||||
|
""", {
|
||||||
|
'order_number': order_number2,
|
||||||
|
'partner_id': partner_id,
|
||||||
|
'articles_json': articles_json,
|
||||||
|
'result': result_var2
|
||||||
|
})
|
||||||
|
|
||||||
|
order_id2 = result_var2.getvalue()
|
||||||
|
if order_id2 and order_id2 > 0:
|
||||||
|
print(f" Order created: ID {order_id2}")
|
||||||
|
|
||||||
|
cur.execute("""
|
||||||
|
SELECT ce.CANTITATE, ce.PRET, na.CODMAT
|
||||||
|
FROM COMENZI_ELEMENTE ce
|
||||||
|
JOIN NOM_ARTICOLE na ON ce.ID_ARTICOL = na.ID_ARTICOL
|
||||||
|
WHERE ce.ID_COMANDA = :oid
|
||||||
|
""", {'oid': order_id2})
|
||||||
|
rows2 = cur.fetchall()
|
||||||
|
|
||||||
|
if len(rows2) == 1:
|
||||||
|
# Distributed: single line with adjusted price
|
||||||
|
total = rows2[0][0] * rows2[0][1]
|
||||||
|
expected_total = web_price_per_pack * 2
|
||||||
|
print(f" Line: qty={rows2[0][0]}, price={rows2[0][1]:.2f}, total={total:.2f}")
|
||||||
|
if abs(total - expected_total) < 0.02:
|
||||||
|
print(" PASS: Distributed price correct")
|
||||||
|
success_count += 1
|
||||||
|
else:
|
||||||
|
print(f" FAIL: Total {total:.2f} != expected {expected_total:.2f}")
|
||||||
|
else:
|
||||||
|
print(f" INFO: Got {len(rows2)} lines (expected 1 for distributed)")
|
||||||
|
for r in rows2:
|
||||||
|
print(f" qty={r[0]}, price={r[1]:.2f}, codmat={r[2]}")
|
||||||
|
else:
|
||||||
|
cur.execute("SELECT PACK_IMPORT_COMENZI.get_last_error FROM DUAL")
|
||||||
|
err = cur.fetchone()[0]
|
||||||
|
print(f" FAIL: Order import failed: {err}")
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
|
# Cleanup
|
||||||
|
teardown_test_data(cur)
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
print(f"RESULTS: {success_count}/{total_tests} tests passed")
|
||||||
|
print('=' * 60)
|
||||||
|
return success_count == total_tests
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"CRITICAL ERROR: {e}")
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
try:
|
||||||
|
with oracledb.connect(user=user, password=password, dsn=dsn) as conn:
|
||||||
|
with conn.cursor() as cur:
|
||||||
|
teardown_test_data(cur)
|
||||||
|
conn.commit()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
print("Starting complete order import test...")
|
print("Starting complete order import test...")
|
||||||
print(f"Timestamp: {datetime.now()}")
|
print(f"Timestamp: {datetime.now()}")
|
||||||
@@ -342,4 +540,12 @@ if __name__ == "__main__":
|
|||||||
else:
|
else:
|
||||||
print("🔧 PHASE 1 VALIDATION: NEEDS ATTENTION")
|
print("🔧 PHASE 1 VALIDATION: NEEDS ATTENTION")
|
||||||
|
|
||||||
|
# Run repackaging kit pricing test
|
||||||
|
print("\n")
|
||||||
|
repack_success = test_repackaging_kit_pricing()
|
||||||
|
if repack_success:
|
||||||
|
print("🎯 REPACKAGING KIT PRICING: SUCCESSFUL")
|
||||||
|
else:
|
||||||
|
print("🔧 REPACKAGING KIT PRICING: NEEDS ATTENTION")
|
||||||
|
|
||||||
exit(0 if success else 1)
|
exit(0 if success else 1)
|
||||||
Reference in New Issue
Block a user