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:
Claude Agent
2026-03-21 11:04:09 +00:00
parent 10c1afca01
commit 61ae58ef25
6 changed files with 245 additions and 49 deletions

View File

@@ -330,16 +330,222 @@ def test_complete_import():
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__":
print("Starting complete order import test...")
print(f"Timestamp: {datetime.now()}")
success = test_complete_import()
print(f"\nTest completed at: {datetime.now()}")
if success:
print("🎯 PHASE 1 VALIDATION: SUCCESSFUL")
else:
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)