11 KiB
Handoff: cercetare "cost materiale / rulaj + manoperă" (read-only)
Sarcina (subagent lane-cost): găsește și documentează cum se determină azi (a) costul de
achiziție al unei piese ieșite pe o comandă/factură și (b) valoarea + orele de manoperă,
pentru cererea clientului de a afișa aceste valori în listele de comenzi/facturi. Cercetare
READ-ONLY — niciun fișier din proiect nu a fost modificat.
Stare: COMPLET
Toate constatările au fost transmise integral către team-lead prin două mesaje SendMessage
(cu citate exacte de cod și file:line). Acest fișier e doar predarea pe disc, conform REGULA
ZERO — pentru cazul în care mesajele s-ar pierde. Nu există lucru neterminat, fișiere editate,
tranzacții deschise sau date de test consumate.
Important: în timp ce scriam handoff-ul am găsit că exista deja pe disc
docs/propuneri_coloane_manopera_piese_viz.md —
un document mult mai complet (scris cu acces direct la Oracle: EXPLAIN PLAN, autotrace,
măsurători reale pe schema MARIUSM_AUTO/ROA_CENTRAL), care acoperă și depășește tot ce
am găsit eu static din cod. Acela e documentul de referință pentru implementare, nu acesta.
Constatările mele (fără acces DB, doar citire de cod) coincid cu ale lui la toate punctele
verificabile static.
Inventar constatări (file:line)
1. Tabelul RUL (rulaj) — coloane relevante
Schema cursorului viz_rulaje: COMUN/programe/oproceduri_rulaje.prg:15-25.
PRET n(16,4) = preț achiziție/cost per rând de mișcare, PRETV n(16,4) = preț vânzare,
CANT/CANTE = cantitate, COD = document sursă, ID_LUCRARE, ID_GESTIUNE, STERS.
2. Cost achiziție — DEJA STOCAT pe linia de vânzare/factură (nu recalculat la citire)
- Schema cursor linii deviz:
Programe/oproceduri_devize.prg:882—pret_achizitie N(20,4). - Populat din lotul de stoc consumat:
COMUN/clase/ofacturare.vc2:4233,13131,13511—poArticol.pret_achizitie = Pret. - Scris efectiv prin
pack_facturare.adauga_articol_factura_deviz(Programe/oproceduri_devize.prg:1218-1244). - Persistă și la editare facturi:
COMUN/programe/ofacturare_editare.prg:225,547,652,775,807-817; schema tabelvanzari_det:COMUN/programe/oproceduri_facturare.prg:378-491,1114-1133. - Rapoarte care citesc costul direct de pe linie, fără recalcul:
COMUN/programe/oproceduri_rapoarte_fact.prg:579-590(viewfact_vfacturi_detalii).
3. Algoritm de determinare a costului la ieșire — FIFO pe LOT, din tabela STOC
Sursă (în afara repo-ului git ROAAUTO, în D:\ROA\DATABASE\SCRIPTURI_CLAR\ — istoric SVN al
schemei Oracle COMUN, actualizat curent, ultimul fișier relevant la 2026-09-16):
PACK_FACTURARE.cursor_gestiuni_articol
(D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\09\ff_2026_09_16_04_COMUN_PACK_FACTURARE.sql:4513-4597).
Selectează loturi din STOC (nu din RUL), filtrate pe LUNA/AN/ID_ARTICOL/
ID_GESTIUNE, cantitate rămasă = CANTS + CANT - CANTE > 0, ordonate ORDER BY DATAIN
(FIFO pe data intrării lotului). PRET = costul lotului ales, scris o singură dată pe linia
de vânzare (punctul 2). Rapoartele nu re-rulează FIFO, doar re-însumează ce s-a scris deja.
4. Manoperă — ore și valoare
DDL DEV_OPER: Scripturi_instalare/tabele.sql:674-693 — TIMPN NUMBER(8,3) (ore),
PRET NUMBER(17,4) (tarif orar), ID_ORDL (FK spre DEV_ORDL, fără index explicit pe
DEV_OPER.ID_ORDL în DDL). DEV_ORDL are index pe ID_LUCRARE (IDX_ORDL_00001,
Scripturi_instalare/tabele.sql:636).
Valoare manoperă = TIMPN * PRET, agregată în raport:
Programe/oproceduri_listari.prg:1608-1621 (facturi_emise_pe_sectii).
5. Raportul cerut de client EXISTĂ DEJA — view Oracle AUTO_ISTORIC_COMENZI
Versiune curentă (ultima modificare găsită, 2025-06-30, nimic mai nou):
D:\ROA\DATABASE\SCRIPTURI_CLAR\2025\06\ff_2025_06_30_01_AUTO.sql:37-95.
(select sum(round(pret * cante, 2)) from rul where sters = 0 and id_lucrare = a.id_lucrare) as val_materiale_ach,
(select sum(round(pretv * cante, 2)) from rul where sters = 0 and id_lucrare = a.id_lucrare) as val_materiale_vz,
(select sum(b1.timpn) from dev_ordl a1 left join dev_oper b1 on a1.id_ordl=b1.id_ordl where a1.id_lucrare=a.id_lucrare and a1.sters=0 and b1.sters=0) as ore_manopera,
(select sum(round(b1.timpn*b1.pret,2)) from dev_ordl a1 left join dev_oper b1 on a1.id_ordl=b1.id_ordl where a1.id_lucrare=a.id_lucrare and a1.sters=0 and b1.sters=0) as val_manopera,
Subselecte corelate pe id_lucrare (nu scan fără filtru), susținute de indexul
IDX_RUL_001 on RUL(ID_LUCRARE, STERS) (creat D:\ROA\DATABASE\SCRIPTURI\2009\1\ff_2009_01_21_01_GESTIUNI.sql:63,
încă folosit activ cu hint în producție — ultima apariție
D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\03\ff_2026_03_31_02_AUTO_PACK_AUTO.sql:711).
Folosit deja în VFP: Programe/oproceduri_vizualizare.prg:441-457 (vizualizare_ist_comenzi),
afișat în grid Clase/oviz_devize.vc2:9585-9607 (ControlSource: val_materiale_ach,
val_materiale_vz, val_materiale_factura, val_manopera_factura, ore_manopera).
6. Raportul care CHIAR scanează tot RUL fără scopare pe lucrare (risc real, dar altă bucată de cod)
Programe/oproceduri_listari.prg:1607-1625 (facturi_emise_pe_sectii):
left join (select sum(round(pret*cante,2)) as valoarea, sum(round(pretv*cante,2)) as valoarev,
id_lucrare, id_sectie from rul where sters=0 group by id_lucrare, id_sectie) e
on a.id_lucrare = e.id_lucrare and a.id_sectie = e.id_sectie
GROUP BY peste tot RUL (fără filtru pe id_lucrare în where), join-ul pe perioadă se face
abia după — spre deosebire de AUTO_ISTORIC_COMENZI (punctul 5), care e corelat per lucrare.
Acesta e adevăratul candidat de "selecție pe toată baza de date", dacă vreodată devine relevant
de optimizat.
Ce s-a stabilit deja (să nu se reia)
- Costul de achiziție e stocat pe linia de vânzare/factură (
pret_achizitie), nu recalculat FIFO la fiecare citire — FIFO rulează o singură dată, la facturare, pe tabelaSTOC. - View-ul
AUTO_ISTORIC_COMENZIdeja livrează exact coloanele cerute de client și e deja folosit în ecranul „Istoric comenzi"; documentul de propuneri recomandă copierea acelorași subinterogări înAUTO_NORMARE_COMENZI/AUTO_FACTURI_EMISEpentru ecranele „Vizualizare comenzi"/"Facturi". - Sursa de adevăr pentru DDL/PL-SQL Oracle (istoric complet de migrări, inclusiv versiuni curente
ale pachetelor și view-urilor) NU e în
Scripturi_instalare\din ROAAUTO, ci înD:\ROA\DATABASE\SCRIPTURI\(brut, cronologic) șiD:\ROA\DATABASE\SCRIPTURI_CLAR\(reformatat) — repo SVN separat, partajat între toate aplicațiile ROA.
Interzis / nu s-a făcut
Nicio modificare de cod, niciun script Oracle rulat, niciun write-back .vc2/.sc2. Cercetare
pur read-only, conform mandatului primit.
Runda 2 — întrebări punctuale de la team-lead (trimise, nu doar aici)
Sursă: PACK_FACTURARE.descarca_gestiune, în
D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\09\ff_2026_09_16_04_COMUN_PACK_FACTURARE.sql (versiune
curentă, 2026-09-16).
RUL.PRETla ieșire — SIGUR: nu se recalculează îndescarca_gestiune. Procedura primeșteV_PRET_ACHIZITIE IN NUMBERca parametru, selectează dinSTOCexact lotul cu acel preț (AND A.PRET = V_PRET_ACHIZITIE, linia 8766 și analog 8659/8899/10642), apoiV_PRET := tab_stoc(i).PRET(linia 8975) șiV_PRET as PRETînINSERT INTO RUL_TEMP(linia 9456). FIFO-ul (alegerea lotului) se face separat, mai devreme, încursor_gestiuni_articol(ORDER BY DATAIN, raportat runda 1). Incert: n-am găsit niciunINSERT INTO RULliteral (fără_TEMP) în acest fișier — nu am urmărit cumRUL_TEMPajunge fizic înRUL. Nu schimbă răspunsul (valoareaPRETe fixată laV_PREToricum), dar rămâne un gol de investigat dacă cineva vrea firul complet.- RUL pe
id_lucrare= doar piese, niciodată manoperă — SIGUR: gardă la intrarea îndescarca_gestiune(liniile 8264-8270):Articolele cuSELECT MAX(IN_STOC) INTO lnInStoc FROM NOM_ARTICOLE WHERE ID_ARTICOL = V_ID_ARTICOL; if lnInStoc = 0 then GOTO SFARSIT; end if;IN_STOC=0(servicii/manoperă) nu ajung niciodată să scrie înRUL_TEMP/RUL. Replicat pe VFP pringestionabil = Iif(Nvl(in_stoc,0)<>0,1,0)(COMUN/programe/ofacturare_editare.prg:242). CANTEvsCANT— SIGUR:CANTE=ieșire,CANT=intrare, din formula solduluiCANTS+CANT-CANTE(folosită consecvent, ex.cursor_gestiuni_articol). La retur (ramuraWHEN pack_facturare.ntip IN (8,9)dindescarca_gestiune, ~linia 8355) nu se folosesc cantități negative — ieșirea originală (a.cante) devinecant(intrare) pe rândul nou:SELECT 1 as tip, ..., a.cante as cant, 0 as cante, ... FROM RUL A ... WHERE A.CANTE<>0.DEV_OPER.TIMPN= ore — SIGUR pe bază de uz, nicio conversie de unitate întâlnită:Programe/oproceduri_listari.prg:1620(sum(...timpn) as ore),:2005(sum(timpn) as ore), captionClase/odevize.vc2:6310("Total ore"). NiciunCOMMENT ON COLUMNgăsit în DDL — eticheta vine din convenția de cod, nu dintr-un comentariu de schemă.VANZARI_DETALII.PRET_ACHIZITIE— mecanism SIGUR, procentul de 95% zero INCERT: scris de același flux (descarca_gestiune/finalizare factură), doar pentru linii gestionabile (IN_STOC<>0), cuV_PRETdinSTOC(condiție de MERGE, linia 12741:AND A.PRET_ACHIZITIE = V_PRET ...). Pentru linii de manoperă (IN_STOC=0) rămâne 0 prin design (codul nici nu rulează pentru ele — punctul 2). Nu am verificat empiric (fără acces Oracle) dacă cele ~95% zero din schema de test chiar corespund liniilor de manoperă sau ascund și piese needescărcate din alt motiv — am recomandat team-lead-ului un count peIN_STOC × (PRET_ACHIZITIE=0)pentru confirmare.
Concluzie rundă 2: pret_achizitie de pe VANZARI_DETALII e de încredere ca sursă a costului
pe factură pentru liniile de piese; un 0 pe linie de manoperă e corect, nu semnal de problemă.
CORECTARE ulterioară (din docs/propuneri_coloane_manopera_piese_viz.md, actualizat de altcineva
cu acces Oracle, după ce am trimis răspunsul de mai sus): pe schema de test, PRET_ACHIZITIE = 0
nu doar pe liniile de manoperă (IN_STOC=0: 2475/2526 = 98%), ci și pe 96% din liniile de piese
gestionabile (IN_STOC=1: 8561/8889 = 96%). Deci concluzia mea "e de încredere pentru piese" nu
se confirmă empiric — mecanismul de scriere există (descris mai sus), dar pe date reale coloana e
goală aproape peste tot, inclusiv acolo unde ar trebui completată. Motivul exact nu e stabilit
(posibil: câmpul se completează doar pe un anumit flux de facturare, sau pe majoritatea documentelor
din baza de test descărcarea de gestiune nu s-a mai executat din alt motiv). Nu folosiți
VANZARI_DETALII.PRET_ACHIZITIE ca sursă de cost fără verificare suplimentară — RUL.PRET (via
AUTO_ISTORIC_COMENZI) rămâne sursa confirmată empiric.