sync SVN r18077
This commit is contained in:
210
docs/cercetare/pack_auto_actualizeaza_deviz.md
Normal file
210
docs/cercetare/pack_auto_actualizeaza_deviz.md
Normal file
@@ -0,0 +1,210 @@
|
||||
# Cercetare: `pack_auto.actualizeaza_deviz` si riscul asupra devizului ROAAUTO la #13
|
||||
|
||||
Scop: `plan_13_unificare_formular_facturare.md` vrea sa permita adaugarea unei linii noi pe o
|
||||
factura deja emisa, inclusiv pe facturile ROAAUTO (`tip = -12`). Intrebarea: ce se intampla cu
|
||||
**devizul** din ROAAUTO cand factura primeste o linie pe care devizul nu o stie. Punctul de
|
||||
plecare a fost `pack_auto.actualizeaza_deviz`, apelat din
|
||||
`D:\ROA\ROAAUTO\Programe\oproceduri_devize.prg:1310`, al carei corp nu fusese citit inainte de
|
||||
aceasta cercetare.
|
||||
|
||||
Continua `roaauto_facturi.md` si `roaauto_articole_lista_preturi.md` (deja citite, nu reiau
|
||||
constatarile lor: acelasi `PACK_FACTURARE`, `VANZARI_DETALII_TEMP` -> `VANZARI_DETALII`,
|
||||
`tip=-12`, liniile sintetice `-100000..-100008` plus liniile reale "Alte servicii", editorul
|
||||
`frm_modific2024` read-only, `oviz_devize.vc2:4536` blocheaza modificarea dupa `nrfact`).
|
||||
|
||||
## 1. Unde e definit `PACK_AUTO`
|
||||
|
||||
`D:\ROA\DATABASE\SCRIPTURI_CLAR\<an>\<luna>\ff_..._AUTO_PACK_AUTO.sql` — 14 versiuni istorice
|
||||
gasite (2013-2026). Sursa de adevar folosita (cea mai recenta, dupa conventia deja aplicata in
|
||||
`roaauto_facturi.md` pentru `PACK_FACTURARE`):
|
||||
|
||||
**`D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\03\ff_2026_03_31_02_AUTO_PACK_AUTO.sql`** (1804 linii,
|
||||
antet "17.03.2026 / robert / creare procedura setOptiuneInchidere").
|
||||
|
||||
Semnatura in spec: `:74-76`. Corp: `:692-733`.
|
||||
|
||||
## 2. Ce face `actualizeaza_deviz`, pas cu pas
|
||||
|
||||
Corpul complet (`ff_2026_03_31_02_AUTO_PACK_AUTO.sql:692-733`):
|
||||
|
||||
```sql
|
||||
procedure actualizeaza_deviz(tnProcTvav IN NUMBER,
|
||||
tcSirIdOrdl IN VARCHAR2,
|
||||
tnIdSet IN NUMBER) is
|
||||
lcSeparator VARCHAR2(1) := ',';
|
||||
lnIdFact DOCUMENTE.ID_DOC%TYPE;
|
||||
begin
|
||||
-- nu iau pack_contafin.get_idfact pentru ca s-ar putea sa am id_fact de la incasare, nu de la factura
|
||||
SELECT MAX(ID_FACT)
|
||||
INTO lnIdFact
|
||||
FROM ACT
|
||||
WHERE COD = pack_contafin.get_cod()
|
||||
AND SCD NOT LIKE '5%';
|
||||
|
||||
UPDATE DEV_ORDL
|
||||
SET PROC_TVAV = tnProcTvav
|
||||
WHERE ID_ORDL IN (SELECT X FROM table(charn2collection(tcSirIdOrdl, lcSeparator)));
|
||||
|
||||
UPDATE /*+ INDEX(RUL IDX_RUL_001) */ RUL
|
||||
SET ID_FACT = lnIdFact
|
||||
WHERE ID_SET <> 229
|
||||
AND ID_LUCRARE IN (SELECT ID_LUCRARE FROM DEV_ORDL
|
||||
WHERE ID_ORDL IN (SELECT X FROM table(charn2collection(tcSirIdOrdl, lcSeparator))));
|
||||
|
||||
IF tnIdSet IN (31003, 31004, 31005, 31006, 31007, 31011) THEN
|
||||
UPDATE NOM_LUCRARI
|
||||
SET ID_FACT = lnIdFact
|
||||
WHERE ID_LUCRARE IN (SELECT ID_LUCRARE FROM DEV_ORDL
|
||||
WHERE ID_ORDL IN (SELECT X FROM table(charn2collection(tcSirIdOrdl, lcSeparator))));
|
||||
END IF;
|
||||
end actualizeaza_deviz;
|
||||
```
|
||||
|
||||
Trei pasi, toti indexati pe `ID_ORDL`/`ID_LUCRARE` (comanda/lucrarea din ROAAUTO), **niciunul pe
|
||||
`VANZARI`/`VANZARI_DETALII`**:
|
||||
|
||||
1. Citeste `lnIdFact` = cel mai mare `ID_FACT` din `ACT` pentru "codul" curent de sesiune
|
||||
(`pack_contafin.get_cod()`), excluzand notele de incasare (`SCD NOT LIKE '5%'`) — comentariul
|
||||
din cod explica de ce: la momentul apelului pot exista in `ACT` atat o nota de incasare cat si
|
||||
nota/factura propriu-zisa, si vrea explicit factura.
|
||||
2. `UPDATE DEV_ORDL SET PROC_TVAV = tnProcTvav` — scrie cota de TVA pe comenzile din
|
||||
`tcSirIdOrdl` (lista CSV de `ID_ORDL`, despartita cu `charn2collection`).
|
||||
3. `UPDATE RUL SET ID_FACT = lnIdFact WHERE ID_SET <> 229 AND ID_LUCRARE IN (...)` — leaga
|
||||
inapoi randurile din `RUL` (jurnalul de manopera/materiale al lucrarii, folosit si la
|
||||
`frm_inchidere_productie.do_executa` pentru totalul pe sectii, vezi §4) de documentul creat.
|
||||
4. Doar daca `tnIdSet` e unul din `{31003,31004,31005,31006,31007,31011}`, acelasi `ID_FACT` se
|
||||
scrie si pe `NOM_LUCRARI` (nomenclatorul de lucrari).
|
||||
|
||||
**Nu exista niciun `SELECT`/`UPDATE` pe `VANZARI` sau `VANZARI_DETALII` in `actualizeaza_deviz`**
|
||||
si, verificat suplimentar, **in tot pachetul `PACK_AUTO`** (grep pe `VANZARI` in cele 1804 linii
|
||||
ale fisierului: 0 potriviri). Deci raspunsul direct la intrebarea din brief: procedura **nu
|
||||
recalculeaza niciun total al devizului din liniile facturii** — nu citeste liniile facturii deloc.
|
||||
Ce face e sa "stampileze" `ID_FACT` (documentul de vanzare/nota abia creat) pe randurile din `RUL`
|
||||
si `NOM_LUCRARI` legate de comenzile din `tcSirIdOrdl`, plus sa actualizeze cota TVA pe
|
||||
`DEV_ORDL`. E o legatura *deviz -> document*, nu un recalcul *document -> total deviz*.
|
||||
|
||||
## 3. Ce se intampla cu o linie de factura pe care devizul nu o are
|
||||
|
||||
Raspunsul e neted, pentru ca premisa intrebarii (un `SUM` peste `VANZARI_DETALII`) nu exista in
|
||||
cod: **procedura nu vede deloc liniile facturii**, nici cele cunoscute (sintetice
|
||||
`-100000..-100008`), nici cele reale (nomenclator, cazul "Alte servicii" din raportul anterior),
|
||||
nici una noua adaugata din afara. Ea opereaza exclusiv pe `ID_ORDL`/`ID_LUCRARE` (identitatea
|
||||
comenzii ROAAUTO), primite ca parametru `tcSirIdOrdl` — nu deriva niciodata acest identificator
|
||||
din continutul `VANZARI_DETALII`.
|
||||
|
||||
Precedentul "Alte servicii" (articole reale, `id_articol` pozitiv, cf.
|
||||
`roaauto_articole_lista_preturi.md` §2) confirma exact acest comportament pe date deja live: acele
|
||||
linii coexista cu liniile sintetice in `VANZARI_DETALII` de multa vreme, fara ca
|
||||
`actualizeaza_deviz` sa faca vreo distinctie — pentru ca nu se uita la `VANZARI_DETALII` deloc.
|
||||
|
||||
**Consecinta pentru #13**: adaugarea unei linii noi pe `VANZARI_DETALII` pentru o vanzare
|
||||
`tip=-12` nu poate "dezechilibra" ce scrie `actualizeaza_deviz`, pentru simplul motiv ca aceasta
|
||||
procedura nu depinde de continutul `VANZARI_DETALII`. Nu exista *eroare*, nu exista *ignorare
|
||||
explicita* — e o absenta totala de citire.
|
||||
|
||||
Important insa (nuanta pe care intrebarea din brief o presupune implicit gresit): asta **nu**
|
||||
inseamna ca "devizul" (asa cum e prezentat operatorului in ROAAUTO) ar reflecta automat noua
|
||||
linie. Totalul devizului afisat in `oviz_devize.vc2` e calculat client-side din `RUL` (vezi
|
||||
`crsTotaluri`, construit cu un `SELECT SUM(...) FROM RUL ... GROUP BY ID_SECTIE` in
|
||||
`oviz_devize.vc2:7816-7823`, in `frm_inchidere_productie.do_executa`) si din cursoarele
|
||||
`crsdeviz`/`crsalteserv` calculate in `oproceduri_devize.prg` la momentul facturarii — niciodata
|
||||
din `VANZARI_DETALII`. Deci o linie adaugata ulterior pe factura **nu va aparea niciodata** in
|
||||
totalul devizului asa cum il calculeaza ROAAUTO, indiferent daca `actualizeaza_deviz` mai ruleaza
|
||||
sau nu — pur si simplu acel total nu are o sursa care sa citeasca `VANZARI_DETALII`.
|
||||
|
||||
## 4. Cand e apelata
|
||||
|
||||
Cautare in ROAAUTO (`Grep` pe `actualizeaza_deviz`, cele trei aparitii de cod, plus istoric
|
||||
`.??2`) si in tot `D:\ROA\DATABASE\SCRIPTURI_CLAR` (niciun alt pachet Oracle nu o apeleaza — grep
|
||||
pe `actualizeaza_deviz` in tot arborele SCRIPTURI_CLAR gaseste doar fisierele care *definesc*
|
||||
`PACK_AUTO`/vechiul `PACK_DEVIZE`, nu vreun apel extern):
|
||||
|
||||
Trei puncte de apel, toate in VFP, niciunul intr-un trigger/job Oracle:
|
||||
|
||||
1. **La emiterea facturii** — `oproceduri_devize.prg:1310`, in acelasi bloc `lcSql` cu
|
||||
`pack_facturare.scrie_in_vanzari` (linia 1302), cu `tnIdSet` dinamic (`lnIdSet`, calculat mai
|
||||
sus in `factureaza_deviz`). Comentariu la linia 1311: *"am scos apelul catre
|
||||
`pack_devize.dev_completeaza_rul`; e inclus in `actualizeaza_deviz`"* — confirma ca functia a
|
||||
inlocuit o procedura mai veche cu acelasi scop (legare RUL -> document).
|
||||
2. **`frm_inchidere_productie.do_executa`** (`oviz_devize.vc2:7896`, clasa la `:7143`) — cu
|
||||
`tnIdSet` **fix, 31007** — apelata dupa ce formularul de **inchidere productie** scrie o
|
||||
*nota contabila* (`oscrie_in_fisiere()` peste cursorul `actactan`, `:7889`), **nu** o factura;
|
||||
nu apeleaza `pack_facturare.scrie_in_vanzari`, deci nu atinge `VANZARI` deloc pe acest drum.
|
||||
3. **`frm_inchidere_regie.do_executa`** (`oviz_devize.vc2:8907`, clasa la `:8093`) — identic,
|
||||
`tnIdSet` fix **31006**, pentru inchiderea de **regie** (overhead), tot printr-o nota
|
||||
contabila, nu o factura.
|
||||
|
||||
Deci `actualizeaza_deviz` nu e specifica facturarii — e o operatie generica *"leaga
|
||||
comenzile/lucrarile astea de ultimul document contabil creat pentru codul curent"*, refolosita si
|
||||
la doua fluxuri de inchidere interna care nu produc facturi de vanzare. In niciunul din cele trei
|
||||
cazuri nu e re-declansata mai tarziu (nu exista un al patrulea apel, nici din UI, nici din
|
||||
schedule/trigger Oracle) — deci editarea ulterioara a unei facturi deja emise (obiectivul #13) nu
|
||||
ar re-invoca automat aceasta procedura, pentru ca nimic din codul citit o cheama in afara celor 3
|
||||
puncte de mai sus.
|
||||
|
||||
## 5. Alte proceduri din `PACK_AUTO` care citesc `VANZARI`/`VANZARI_DETALII` pentru un deviz
|
||||
|
||||
**Niciuna.** Grep pe `VANZARI` in intregul fisier `ff_2026_03_31_02_AUTO_PACK_AUTO.sql` (1804 de
|
||||
linii, tot pachetul, nu doar `actualizeaza_deviz`) — 0 potriviri. `PACK_AUTO` nu are nicio
|
||||
dependenta de tabelele de vanzari/facturare; toata legatura cu partea financiara trece prin `ACT`
|
||||
(note contabile) si `DEV_ORDL`/`RUL`/`NOM_LUCRARI` (structura proprie ROAAUTO).
|
||||
|
||||
Singurul loc care **citeste** liniile facturii pentru re-listarea unui deviz e in afara
|
||||
`PACK_AUTO`, pe partea VFP: `relisteaza_factura_deviz`
|
||||
(`D:\ROA\ROAAUTO\Programe\oproceduri_devize.prg:1516-1576`, mentionata in raportul anterior).
|
||||
Verificat acum sursa: interogheaza direct view-urile COMUN `fact_vfacturi`
|
||||
(`:1531`, filtrat `WHERE cod = ...`) si **`fact_vfacturi_detalii`** (`:1564`,
|
||||
`select * from fact_vfacturi_detalii where id_vanzare = <poDate.nid_vanzare>` — fara alt filtru).
|
||||
View-ul e definit in
|
||||
`D:\ROA\DATABASE\SCRIPTURI_CLAR\2024\06\ff_2024_06_04_01_COMUN_FACTURARE.sql:8-94`:
|
||||
`create or replace view fact_vfacturi_detalii as select ... from vanzari_detalii a left join
|
||||
nom_articole b ... ` — un simplu wrapper peste `VANZARI_DETALII` cu join-uri de denumire, **fara
|
||||
nicio clauza `WHERE`** care sa restranga la id-uri de articol cunoscute sau la liniile
|
||||
"originale" ale devizului.
|
||||
|
||||
**Consecinta**: o linie noua inserata in `VANZARI_DETALII` pentru acel `id_vanzare` **va aparea
|
||||
automat** la o re-listare/re-tiparire ulterioara prin `relisteaza_factura_deviz` — comportament
|
||||
asteptat de la un view neconditionat, nu o stricare. Nu exista risc de eroare sau de excludere pe
|
||||
acest drum; riscul (daca exista) e doar de **asteptare a utilizatorului**: factura retiparita va
|
||||
arata linia noua, dar ecranul de deviz din ROAAUTO (total calculat din `RUL`, §3) nu o va arata
|
||||
niciodata, pentru ca nu deriva din `VANZARI_DETALII`.
|
||||
|
||||
## 6. Concluzie operationala pentru #13
|
||||
|
||||
**Da, se poate adauga o linie pe o vanzare `tip=-12` fara sa "strice" `pack_auto.actualizeaza_deviz`
|
||||
sau vreo alta procedura din `PACK_AUTO`** — pentru ca niciuna din ele nu citeste `VANZARI`/
|
||||
`VANZARI_DETALII`; nu exista mecanism Oracle-side care sa recalculeze/verifice totalul devizului
|
||||
din liniile facturii, deci nu exista nimic de dezechilibrat la acel nivel. Nu e nevoie de niciun
|
||||
apel Oracle suplimentar din partea ROAFACTURARE ca sa "anunte" ROAAUTO despre linia noua —
|
||||
`actualizeaza_deviz` n-ar face nimic util cu acea informatie oricum (opereaza pe `ID_ORDL`, nu pe
|
||||
linii de factura).
|
||||
|
||||
Ce **nu** rezolva aceasta concluzie, si ramane responsabilitatea planului #13, nu a acestei
|
||||
proceduri:
|
||||
|
||||
- **Desincronizare de afisare, nu de date**: totalul devizului aratat in ROAAUTO
|
||||
(`oviz_devize.vc2`, calculat din `RUL`/cursoarele de facturare) nu va reflecta niciodata o
|
||||
linie adaugata ulterior direct pe `VANZARI_DETALII` — nici azi (cu liniile "Alte servicii"),
|
||||
nici cu o linie noua din editorul unificat. Daca produsul vrea ca devizul sa "stie" de linia
|
||||
noua vizual, ar trebui cod nou in ROAAUTO (nu exista azi), nu un apel catre `actualizeaza_deviz`.
|
||||
- **Reprintarea** (`relisteaza_factura_deviz`) va include automat linia noua (§5) — de verificat
|
||||
daca asta e comportamentul dorit de produs sau o suprindere pentru operatorul ROAAUTO.
|
||||
- Confirmat si direct in cod ROAFACTURARE: `Grep` pe `pack_auto` in
|
||||
`D:\ROA\ROAFACTURARE` (inclusiv `COMUN`) nu gaseste nicio referinta in cod, doar in `docs\`
|
||||
(planul #13 si aceste rapoarte) — azi ROAFACTURARE nu apeleaza deloc `PACK_AUTO`, confirmand ca
|
||||
nu exista deja o presupunere ascunsa de sincronizare intre cele doua.
|
||||
|
||||
## Neverificat
|
||||
|
||||
- Ce reprezinta exact tabelele `ACT`/`RUL`/`NOM_LUCRARI`/`DEV_ORDL` la nivel de schema completa
|
||||
(DDL/comentarii) — inteles doar din felul in care sunt folosite in cod, nu dintr-un dictionar de
|
||||
date citit explicit.
|
||||
- Daca vreun raport fiscal/SAF-T (mentionat generic in `ff_2022_03_24_01_COMUN_SAFT.sql`, nedeschis)
|
||||
agrega `VANZARI_DETALII` intr-un mod care ar fi afectat de o linie noua pe `tip=-12` — in afara
|
||||
ariei `PACK_AUTO` cerute, nu a fost investigat.
|
||||
- Daca `frm_incasare_finala.do_recalculeaza_total`/`calculeaza_total` (`oviz_devize.vc2:6494,6700`)
|
||||
ar putea fi reconciliate manual de un operator ca sa "vada" o linie adaugata ulterior — nu am
|
||||
citit corpul acestor metode, doar semnalul ca exista.
|
||||
- Istoricul complet al celorlalte 13 versiuni `AUTO_PACK_AUTO.sql` nu a fost comparat linie cu
|
||||
linie cu cea din 2026-03 — presupun (conform conventiei deja aplicate pentru `PACK_FACTURARE`)
|
||||
ca cea mai recenta e sursa de adevar pentru comportamentul curent din productie.
|
||||
Reference in New Issue
Block a user