From 580ca595a516c22ed07062d0db363106f13b2473 Mon Sep 17 00:00:00 2001 From: Claude Agent Date: Wed, 25 Mar 2026 21:39:14 +0000 Subject: [PATCH] fix(import): insert kit discount lines per-kit under components instead of deferred cross-kit Discount lines now appear immediately after each kit's components on the order, making it clear which package each discount belongs to. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../06_pack_import_comenzi.pck | 128 ++++++------------ 1 file changed, 44 insertions(+), 84 deletions(-) diff --git a/api/database-scripts/06_pack_import_comenzi.pck b/api/database-scripts/06_pack_import_comenzi.pck index 3d66e6f..931e918 100644 --- a/api/database-scripts/06_pack_import_comenzi.pck +++ b/api/database-scripts/06_pack_import_comenzi.pck @@ -32,7 +32,7 @@ -- distributed: discountul fata de suma componentelor se distribuie -- proportional in pretul fiecarei componente -- separate_line: componentele se insereaza la pret plin + --- linii discount separate grupate pe cota TVA +-- linii discount separate per-kit sub componente, grupate pe cota TVA -- p_id_pol_productie — politica de pret pentru articole de productie -- (cont in 341/345); NULL = nu se foloseste -- p_kit_discount_codmat — CODMAT-ul articolului discount (Mode separate_line) @@ -67,6 +67,7 @@ -- 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 -- 25.03.2026 - skip negative kit discount (markup), ROUND prices to nzecimale_pretv +-- 25.03.2026 - kit discount inserat per-kit sub componente (nu deferred cross-kit) -- ==================================================================== CREATE OR REPLACE PACKAGE PACK_IMPORT_COMENZI AS @@ -274,17 +275,6 @@ CREATE OR REPLACE PACKAGE BODY PACK_IMPORT_COMENZI AS v_pret_ajustat NUMBER; v_discount_allocated NUMBER; - -- Acumulare discount-uri kit cross-kit (separate_line, deferred insertion) - TYPE t_kit_disc_entry IS RECORD ( - ptva NUMBER, - pret NUMBER, -- pret unitar (disc_amt / cantitate_web) - qty NUMBER -- cantitate negativa acumulata - ); - TYPE t_kit_disc_list IS TABLE OF t_kit_disc_entry INDEX BY PLS_INTEGER; - v_kit_disc_list t_kit_disc_list; - v_kit_disc_count PLS_INTEGER := 0; - v_kit_disc_found BOOLEAN; - -- Zecimale pret vanzare (din optiuni firma, default 2) v_nzec_pretv PLS_INTEGER := NVL(TO_NUMBER(pack_sesiune.getoptiunefirma(USER, 'PPRETV')), 2); @@ -523,14 +513,13 @@ CREATE OR REPLACE PACKAGE BODY PACK_IMPORT_COMENZI AS END LOOP; ELSIF p_kit_mode = 'separate_line' THEN - -- Mode B: componente la pret plin, discount deferred cross-kit + -- Mode B: componente la pret plin, discount per-kit imediat sub componente DECLARE TYPE t_vat_discount IS TABLE OF NUMBER INDEX BY PLS_INTEGER; v_vat_disc t_vat_discount; v_vat_key PLS_INTEGER; v_vat_disc_alloc NUMBER; v_disc_amt NUMBER; - v_unit_pret NUMBER; BEGIN -- Inserare componente la pret plin + acumulare discount pe cota TVA (per kit) FOR i_comp IN 1 .. v_kit_comps.COUNT LOOP @@ -572,42 +561,50 @@ CREATE OR REPLACE PACKAGE BODY PACK_IMPORT_COMENZI AS END IF; END LOOP; - -- Merge per-kit discounts into cross-kit list (v_kit_disc_list) - v_vat_disc_alloc := 0; - v_vat_key := v_vat_disc.FIRST; - WHILE v_vat_key IS NOT NULL LOOP - -- Remainder trick per kit - IF v_vat_key = v_vat_disc.LAST THEN - v_disc_amt := v_discount_total - v_vat_disc_alloc; - ELSE - v_disc_amt := v_vat_disc(v_vat_key); - v_vat_disc_alloc := v_vat_disc_alloc + v_disc_amt; - END IF; + -- Inserare imediata discount per kit (sub componentele kitului) + IF v_discount_total > 0 AND p_kit_discount_codmat IS NOT NULL THEN + DECLARE + v_disc_artid NUMBER; + BEGIN + v_disc_artid := resolve_id_articol(p_kit_discount_codmat, p_id_gestiune); + IF v_disc_artid IS NOT NULL THEN + v_vat_disc_alloc := 0; + v_vat_key := v_vat_disc.FIRST; + WHILE v_vat_key IS NOT NULL LOOP + -- Remainder trick per kit + IF v_vat_key = v_vat_disc.LAST THEN + v_disc_amt := v_discount_total - v_vat_disc_alloc; + ELSE + v_disc_amt := v_vat_disc(v_vat_key); + v_vat_disc_alloc := v_vat_disc_alloc + v_disc_amt; + END IF; - IF v_disc_amt > 0 THEN - v_unit_pret := ROUND(v_disc_amt, v_nzec_pretv); + IF v_disc_amt > 0 THEN + BEGIN + PACK_COMENZI.adauga_articol_comanda( + V_ID_COMANDA => v_id_comanda, + V_ID_ARTICOL => v_disc_artid, + V_ID_POL => NVL(p_kit_discount_id_pol, p_id_pol), + V_CANTITATE => -1 * v_cantitate_web, + V_PRET => ROUND(v_disc_amt, v_nzec_pretv), + V_ID_UTIL => c_id_util, + V_ID_SECTIE => p_id_sectie, + V_PTVA => v_vat_key); + v_articole_procesate := v_articole_procesate + 1; + EXCEPTION + WHEN OTHERS THEN + v_articole_eroare := v_articole_eroare + 1; + g_last_error := g_last_error || CHR(10) || + 'Eroare linie discount kit TVA=' || v_vat_key || + '% codmat=' || p_kit_discount_codmat || ': ' || SQLERRM; + END; + END IF; - -- Search for existing entry with same (ptva, pret) to merge qty - v_kit_disc_found := FALSE; - FOR j IN 1 .. v_kit_disc_count LOOP - IF v_kit_disc_list(j).ptva = v_vat_key - AND v_kit_disc_list(j).pret = v_unit_pret THEN - v_kit_disc_list(j).qty := v_kit_disc_list(j).qty + (-1 * v_cantitate_web); - v_kit_disc_found := TRUE; - EXIT; - END IF; - END LOOP; - - IF NOT v_kit_disc_found THEN - v_kit_disc_count := v_kit_disc_count + 1; - v_kit_disc_list(v_kit_disc_count).ptva := v_vat_key; - v_kit_disc_list(v_kit_disc_count).pret := v_unit_pret; - v_kit_disc_list(v_kit_disc_count).qty := -1 * v_cantitate_web; + v_vat_key := v_vat_disc.NEXT(v_vat_key); + END LOOP; END IF; - END IF; - - v_vat_key := v_vat_disc.NEXT(v_vat_key); - END LOOP; + END; + END IF; END; -- end mode B per-kit block END IF; -- end kit mode branching @@ -692,43 +689,6 @@ CREATE OR REPLACE PACKAGE BODY PACK_IMPORT_COMENZI AS END LOOP; - -- ============================================================ - -- INSERARE DISCOUNT-URI KIT DEFERRED (separate_line) - -- Linii cu preturi diferite raman separate, coliziuni merged pe qty - -- ============================================================ - IF p_kit_mode = 'separate_line' AND v_kit_disc_count > 0 THEN - DECLARE - v_disc_artid NUMBER; - BEGIN - v_disc_artid := resolve_id_articol(p_kit_discount_codmat, p_id_gestiune); - - IF v_disc_artid IS NOT NULL THEN - FOR j IN 1 .. v_kit_disc_count LOOP - BEGIN - PACK_COMENZI.adauga_articol_comanda( - V_ID_COMANDA => v_id_comanda, - V_ID_ARTICOL => v_disc_artid, - V_ID_POL => NVL(p_kit_discount_id_pol, p_id_pol), - V_CANTITATE => v_kit_disc_list(j).qty, - V_PRET => v_kit_disc_list(j).pret, - V_ID_UTIL => c_id_util, - V_ID_SECTIE => p_id_sectie, - V_PTVA => v_kit_disc_list(j).ptva); - v_articole_procesate := v_articole_procesate + 1; - EXCEPTION - WHEN OTHERS THEN - v_articole_eroare := v_articole_eroare + 1; - g_last_error := g_last_error || CHR(10) || - '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 LOOP; - END IF; - END; - END IF; - -- Verifica daca s-au procesat articole cu succes IF v_articole_procesate = 0 THEN g_last_error := g_last_error || CHR(10) || 'IMPORTA_COMANDA ' ||