docs: planurile, proiectarile si rapoartele de lucru intra in versionare
Folderul docs\ era pana acum in afara oricarui control de versiuni - nici git, nici SVN - desi contine planurile pe puncte, proiectarile si rapoartele de cercetare pe care se sprijina modificarile din cod. O stergere acolo era definitiva. Fisierele intermediare (handoff-uri intre sesiuni, diff-uri deja aplicate) au fost sterse inainte, nu versionate: ce era durabil in ele a intrat in antetele fisierelor de test la care se refereau. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SN8snvkk94KuhWwoXUUey3
This commit is contained in:
240
docs/cercetare/cont_venit_corespondente.md
Normal file
240
docs/cercetare/cont_venit_corespondente.md
Normal file
@@ -0,0 +1,240 @@
|
||||
# Corespondenta cont de stoc (3xx) -> cont de venit (7xx): ce exista in cod
|
||||
|
||||
**Context**: continuare a `cont_venit_articol_fara_politica.md`, care stabilise ca `VANZARI_DETALII.CONT`
|
||||
e un cont de **gestiune/stoc** (371, 301-303, 357), fara sa gaseasca un cont de venit pe linia de
|
||||
factura in `pack_facturare`, si lasase neverificat unde se genereaza efectiv contul de venit.
|
||||
Cercetarea de fata raspunde la cele 4 intrebari, cu corectii fata de raportul anterior.
|
||||
|
||||
## Raspuns scurt
|
||||
|
||||
1. **Nu exista un tabel de corespondenta "3xx -> 7xx"** (nume de forma `CORESPONDENTA*`,
|
||||
`NOM_CONTURI*`, `CONT_VENIT*`, `ARTICOLE_CONTABILE*`) nicaieri in `SCRIPTURI_CLAR`. In schimb
|
||||
exista un **mecanism echivalent functional, dar configurat manual, nu derivat automat din contul
|
||||
de stoc**: tabelul `NOTE_CONTABILE` (coloane `SCD`/`ASCD` = cont+analitic debitor,
|
||||
`SCC`/`ASCC` = cont+analitic creditor), legat de politica de pret a articolului prin
|
||||
`CRM_POLITICI_PRETURI.ID_NOTA -> CRM_NOTE_VANZARI.ID_SET -> NOTE_CONTABILE`. Un contabil
|
||||
configureaza acest tabel dintr-un ecran dedicat (`frm_config_note_contabile[2007]`), nu se
|
||||
calculeaza din `NOM_ARTICOLE.CONT`/`STOC.CONT`.
|
||||
2. **`NOM_ARTICOLE.CONT` NU e restrans la conturi de stoc (clasa 3).** Validarea la editare
|
||||
(`verific_cont`) verifica doar ca respectivul cod exista in planul de conturi al anului curent
|
||||
(`vplcont_sintetic`), fara filtru pe clasa. UI-ul trimite explicit catre "Planul de conturi"
|
||||
(buton de help general), nu catre un subset de conturi de stoc. Asta confirma afirmatia lui
|
||||
Marius: campul accepta orice cont, inclusiv 6xx/7xx.
|
||||
3. **Nota contabila a vanzarii SE genereaza in `pack_facturare`** — raportul anterior a cautat
|
||||
literalii `707`/`704`/`706`/`708` (care nu apar hardcodati nicaieri, corect) si a conchis gresit
|
||||
ca lipseste mecanismul. El exista, dar e **indirect**: `pack_facturare.contabilizeaza_articol`
|
||||
(`ff_2026_08_06_10_COMUN_PACK_FACTURARE.sql:7182-7556`) ia `SCD`/`SCC` din `NOTE_CONTABILE` (via
|
||||
politica de pret a articolului) si scrie nota cu `pack_facturare.scrie_nota(...)`. `SCC` (contul
|
||||
creditor) e contul de venit efectiv al liniei — nu vine din `VANZARI_DETALII.CONT` (care ramane
|
||||
contul de gestiune, folosit separat, doar pentru descarcarea de gestiune, in
|
||||
`descarca_gestiune`).
|
||||
4. **`ID_VENCHELT`/`NOM_VENIT_CHELTUIELI` nu are coloana de cont** (nicio `ALTER TABLE
|
||||
NOM_VENIT_CHELTUIELI ADD ... CONT` in `SCRIPTURI_CLAR`). E o dimensiune analitica separata
|
||||
(clasificare venituri/cheltuieli, posibil pentru raportare/buget), transmisa ca parametru propriu
|
||||
catre `scrie_nota`, in paralel cu `SCD`/`SCC` — nu e sursa contului.
|
||||
|
||||
## 1. Nu exista tabel de corespondenta 3xx->7xx; exista `NOTE_CONTABILE` + politica de pret
|
||||
|
||||
### Cautare tabel dedicat — negativa
|
||||
Cautari in `D:\ROA\DATABASE\SCRIPTURI_CLAR` (`CREATE TABLE`/`ALTER TABLE`, case-insensitive) pentru
|
||||
`CORESPONDENT*`, `NOM_CONTURI*`, `CONT_VENIT*`, `PLAN_CONTURI*`, `ARTICOLE_CONTABILE*`: niciun
|
||||
rezultat relevant — singurele hituri pe `CORESPONDENT` sunt cuvantul romanesc generic ("banca
|
||||
corespondenta" etc.) in sute de fisiere fara legatura, iar `CONT_VENIT` nu apare deloc ca nume de
|
||||
tabel/coloana.
|
||||
|
||||
### Mecanismul real: lant de 4 tabele, configurat pe politica de pret
|
||||
`pack_facturare.contabilizeaza_articol` (`ff_...:7227-7280`) foloseste acest cursor pentru a afla
|
||||
contul debitor/creditor al liniei de vanzare:
|
||||
|
||||
```sql
|
||||
CURSOR cursor_articol IS
|
||||
SELECT A.ID_POL_ART, A.ID_POL, A.ID_ARTICOL, A.PRET, ...
|
||||
NVL(pack_facturare.nid_venchelt, NVL(A.ID_VENCHELT, C.ID_VENCHELT)) AS ID_VENCHELT,
|
||||
NVL(pack_facturare.nid_sectie_stoc, C.ID_SECTIE) as ID_SECTIE,
|
||||
C.ID_SET, D.EXPLICATIE, D.SCD, D.ASCD, D.SCC, D.ASCC, D.CU_TVA, ...
|
||||
FROM CRM_POLITICI_PRET_ART A
|
||||
LEFT JOIN CRM_POLITICI_PRETURI B ON A.ID_POL = B.ID_POL
|
||||
LEFT JOIN CRM_NOTE_VANZARI C ON B.ID_NOTA = C.ID_NOTA
|
||||
LEFT JOIN NOTE_CONTABILE D ON C.ID_SET = D.ID_SET
|
||||
WHERE A.ID_POL = detalii_articol.id_pol AND A.ID_ARTICOL = detalii_articol.id_articol;
|
||||
```
|
||||
(`ff_2026_08_06_10_COMUN_PACK_FACTURARE.sql:7227-7280`)
|
||||
|
||||
Lantul e: **articol + politica de pret** (`CRM_POLITICI_PRET_ART`, deja documentat in raportul
|
||||
anterior ca avand `PRET`/`PROC_TVAV`/`ID_VALUTA`, fara `CONT`) `->` **antetul politicii de pret**
|
||||
(`CRM_POLITICI_PRETURI.ID_POL`, care are `ID_NOTA`) `->` **nota de vanzare CRM**
|
||||
(`CRM_NOTE_VANZARI.ID_NOTA`, care are `ID_SET`) `->` **sablonul de nota contabila**
|
||||
(`NOTE_CONTABILE.ID_SET`, care are `SCD`/`ASCD`/`SCC`/`ASCC`/`EXPLICATIE`/`CU_TVA`/`IN_VALUTA`).
|
||||
|
||||
Apoi, la scriere (`ff_...:7405-7437`):
|
||||
```sql
|
||||
CASE
|
||||
WHEN pack_facturare.ntip <= 20 or pack_facturare.ntip IN (...) THEN
|
||||
-- factura, factura roahotel
|
||||
V_SCD := crs_rand_articol.scd;
|
||||
V_ASCD := NVL(crs_rand_articol.ascd, PACK_FACTURARE.GetAnaliticByGrupUtilizatori(...));
|
||||
WHEN pack_facturare.ntip in (28, 29) THEN
|
||||
-- aviz catre clienti debitori
|
||||
V_SCD := '461'; ...
|
||||
ELSE
|
||||
-- aviz
|
||||
V_SCD := '418'; ...
|
||||
END CASE;
|
||||
|
||||
V_SCC := crs_rand_articol.scc;
|
||||
V_ASCC := NVL(crs_rand_articol.ascc, PACK_FACTURARE.GetAnaliticByGrupUtilizatori(...));
|
||||
```
|
||||
(`ff_2026_08_06_10_COMUN_PACK_FACTURARE.sql:7407-7437`)
|
||||
|
||||
Pentru o factura normala (`ntip <= 20`), `V_SCD` e contul debitor din nota (tipic un cont de
|
||||
creante, 411/etc.), iar `V_SCC` e contul creditor din nota — **acesta e efectiv contul de venit**
|
||||
al liniei (707/704/706/708, in functie de cum a configurat contabilul nota respectiva), preluat
|
||||
**direct din `NOTE_CONTABILE.SCC`**, fara nicio derivare din contul de stoc al articolului. Perechea
|
||||
`V_SCD`/`V_SCC` (plus `ID_VENCHELT`, `ID_SECTIE`, `EXPLICATIE`, cota TVA) e trimisa la
|
||||
`pack_facturare.scrie_nota(...)` (`ff_...:7452-7476`), care scrie randul in nota contabila
|
||||
efectiva a vanzarii.
|
||||
|
||||
**Concluzie fata de ipoteza lui Marius**: mecanismul exista si rezolva exact problema — "de unde
|
||||
stiu contul de venit al unei linii de vanzare, indiferent daca articolul e gestionabil sau nu" —
|
||||
dar **nu e o corespondenta automata cont-stoc -> cont-venit**. E o **configurare manuala per
|
||||
politica de pret**: fiecare politica de pret (`CRM_POLITICI_PRETURI`) e legata la o "nota de
|
||||
vanzare" CRM (`CRM_NOTE_VANZARI`), care la randul ei e legata la un sablon de nota contabila
|
||||
(`NOTE_CONTABILE`) cu perechea SCD/SCC fixata de un contabil. Politica de pret aplicata articolului
|
||||
decide, indirect, contul de venit — nu clasa/valoarea contului de gestiune al articolului.
|
||||
|
||||
### Ecranul de configurare (unde se seteaza SCD/SCC)
|
||||
`D:\ROA\ROAFACTURARE\COMUN\ferestre\frm_config_note_contabile.sc2` (+ varianta
|
||||
`frm_config_note_contabile2007.sc2` pentru anii >= 2007, selectata in
|
||||
`COMUN\programe\omeniu_initializari.prg:257-282`) e formularul din meniu "Configurare note
|
||||
contabile". Clasa e `onote_contabile.vc2`, cu un grid `gridInregistrari` avand coloanele
|
||||
`cScd`/`cAscd`/`cScc`/`cAscc` (`onote_contabile.vc2:2401-2435`) legate direct de
|
||||
`cnote_contab.scd`/`.scc`/`.ascd`/`.ascc`, si salvare prin INSERT/UPDATE direct pe
|
||||
`note_contabile(explicatie,scd,ascd,scc,ascc,ordine,cu_tva,ptva,id_set,in_valuta,...)`
|
||||
(`onote_contabile.vc2:315-322`, `:486-493`). Deci **contabilul e cel care scrie manual perechea
|
||||
SCD/SCC** (inclusiv contul de venit `SCC`) pentru fiecare `id_set`/nota, nu exista automatism care
|
||||
sa deriveze `SCC` din contul de gestiune al articolului.
|
||||
|
||||
## 2. `NOM_ARTICOLE.CONT` — nu e restrans la clasa 3
|
||||
|
||||
- **Camp**: `Clb_tx_cont.Text_simplu1.ControlSource = "porec.cont"`, `MaxLength = 4`, eticheta
|
||||
`"Cont*"` (obligatoriu), buton de help cu tooltip `"Help - Planul de conturi (CTRL+ H)"` —
|
||||
`COMUN\clase\onom_articole.vc2:1058-1087`. Trimiterea catre "Planul de conturi" (nu catre un
|
||||
subset "conturi de stoc") sugereaza ca formularul asteapta orice cont valid, nu doar clasa 3.
|
||||
- **Validare la Valid() al campului** (in alt formular generic de conturi, `onomenclatoare.vc2`, nu
|
||||
in cel de articole, dar foloseste aceeasi functie globala):
|
||||
```
|
||||
PROCEDURE clb_cont.Text_simplu1.Valid
|
||||
IF !EMPTY(this.Value)
|
||||
lnVerificat = verific_cont(thisform.orec.cont)
|
||||
IF lnVerificat < 0
|
||||
RETURN 0
|
||||
ENDIF
|
||||
ENDIF
|
||||
ENDPROC
|
||||
```
|
||||
(`COMUN\clase\onomenclatoare.vc2:3251-3258`)
|
||||
- **`verific_cont`** (`COMUN\programe\oproceduri_comune.prg:2389-2415`):
|
||||
```
|
||||
Procedure verific_cont
|
||||
Parameters tcCont, tlNoMessage
|
||||
lcSel = [SELECT cont from ] + GCS + [.vplcont_sintetic WHERE TRIM(cont) = ?pcCont and an = ?gnAn ]
|
||||
...
|
||||
If Reccount('crs_verific') = 0
|
||||
lnSucces = -1
|
||||
Endif
|
||||
If lnSucces < 0 And !tlNoMessage
|
||||
amessagebox('Acest cont nu este definit in planul de conturi!', 0 + 48, 'Atentie')
|
||||
Endif
|
||||
Endproc
|
||||
```
|
||||
Singura conditie e ca `cont` sa existe in `vplcont_sintetic` (planul de conturi sintetic al
|
||||
anului curent, `gnAn`) — **fara `LIKE '3%'`, fara `SUBSTR(cont,1,1) = '3'`, fara nicio alta
|
||||
restrictie de clasa**. O varianta identica exista si in
|
||||
`COMUN\programe\ooperatii_comune.prg:1307` (nu am comparat corp cu corp, dar semnatura e aceeasi).
|
||||
- Nu exista `CHECK CONSTRAINT` pe `NOM_ARTICOLE.CONT` in `SCRIPTURI_CLAR` (cautare
|
||||
`CHECK.*CONT`/`constraint.*CONT.*check` — zero rezultate relevante), deci nici la nivel de
|
||||
baza de date nu exista o restrictie de clasa.
|
||||
- Nu am gasit nicaieri in `COMUN` sau `ROAFACTURARE` o ramificare pe `Left(cont,1)`/
|
||||
`SUBSTR(cont,1,1)` aplicata specific campului `NOM_ARTICOLE.CONT` (cautare in
|
||||
`D:\ROA\ROAFACTURARE` si `D:\ROA\ROAFACTURARE\COMUN`) — singurul loc cu `SUBSTR(cont,1,1)` gasit e
|
||||
in `onomenclatoare.vc2:3647`, un filtru de grid pe planul de conturi general (tab-uri "1", "2",
|
||||
"3"... pentru navigare in plan), fara legatura cu articolele.
|
||||
|
||||
**Concluzie**: campul e validat generic (orice cont din planul de conturi al anului), fara
|
||||
restrictie de clasa la nivel de UI sau DB. Asta confirma ce a spus Marius: un articol negestionabil
|
||||
poate avea legitim un cont 6xx/7xx in `NOM_ARTICOLE.CONT`.
|
||||
|
||||
## 3. Unde se genereaza efectiv nota contabila a vanzarii
|
||||
|
||||
Raportul anterior cauta gresit literalii `707`/`704`/`706`/`708` (niciunul nu apare hardcodat — corect)
|
||||
si a conchis ca nu exista mecanism in `pack_facturare`. De fapt **exista, dar e in `pack_facturare`,
|
||||
nu intr-un pachet separat de contabilitate**:
|
||||
|
||||
- **Functia**: `pack_facturare.contabilizeaza_articol(detalii_articol VANZARI_DETALII_TEMP%ROWTYPE)`
|
||||
(`ff_2026_08_06_10_COMUN_PACK_FACTURARE.sql:7182-7556`), apelata pe fiecare rand din
|
||||
`VANZARI_DETALII_TEMP` — vezi apelul `V_INCASAT_CALCUL := V_INCASAT_CALCUL +
|
||||
pack_facturare.contabilizeaza_articol(tab_detalii(i));` in `scrie_aviz_retur`
|
||||
(`ff_...:7148-7150`); acelasi tipar se repeta si in fluxul principal de facturare (nu doar in
|
||||
aviz-retur — semnatura si structura functiei arata ca acopera si `ntip <= 20`, adica factura
|
||||
propriu-zisa, prin `CASE ... WHEN pack_facturare.ntip <= 20 ...` la `ff_...:7409-7421`).
|
||||
- **Sursa `SCD`/`SCC`**: vezi sectiunea 1 — cursorul `cursor_articol` (`ff_...:7227-7280`), pe baza
|
||||
politicii de pret a articolului (`detalii_articol.id_pol`), nu pe `VANZARI_DETALII.CONT`.
|
||||
- **`VANZARI_DETALII.CONT` ramane folosit separat, doar pentru gestiune**: in aceeasi functie,
|
||||
`descarca_gestiune(...)` primeste explicit `detalii_articol.cont` ca parametru
|
||||
(`ff_...:7485-7507`, apelat cand `nscadere_stoc = 1 AND id_gestiune <> -1000 AND in_stoc = 1`) —
|
||||
acesta e contul de gestiune/stoc (371/301-303/357 etc., documentat in raportul anterior),
|
||||
folosit pentru randul de descarcare de gestiune (marfa iesita din stoc), complet independent de
|
||||
`V_SCD`/`V_SCC` calculate mai sus pentru randul de venit al vanzarii. **Cele doua conturi
|
||||
coexista pe aceeasi linie de vanzare, cu surse complet diferite**: unul (gestiune) vine din
|
||||
`NOM_ARTICOLE.CONT`/`STOC.CONT`/`NOM_GESTIUNI.CONT` (cf. raport anterior), celalalt (venit) vine
|
||||
din `NOTE_CONTABILE.SCC` via politica de pret.
|
||||
- **Nu exista fallback/hardcodare** pentru `SCC`: daca `NOTE_CONTABILE` nu are un rand pentru
|
||||
`ID_SET`-ul politicii, `LEFT JOIN`-urile din `cursor_articol` produc `NULL` pe `SCC`/`SCD`
|
||||
(fara eroare explicita in acest cursor — spre deosebire de cazul `V_COMPUS`/politica lipsa la
|
||||
`ff_...:7293-7311`, care ridica `FACT-024`).
|
||||
|
||||
## 4. `ID_VENCHELT` / `NOM_VENIT_CHELTUIELI`
|
||||
|
||||
- **Nu are coloana de cont**: nicio `ALTER TABLE NOM_VENIT_CHELTUIELI ADD ... CONT` in
|
||||
`SCRIPTURI_CLAR` (cautare directa, zero rezultate) si nicio `CREATE TABLE NOM_VENIT_CHELTUIELI`
|
||||
in arhiva (tabelul predateaza 2009, inceputul arhivei `SCRIPTURI_CLAR` — la fel ca
|
||||
`NOTE_CONTABILE`, `CRM_NOTE_VANZARI`, `CRM_POLITICI_PRETURI`, pentru care nu exista `CREATE TABLE`
|
||||
in arhiva din acelasi motiv).
|
||||
- **Structura vazuta din uz**: `NOM_VENIT_CHELTUIELI.ID_VENCHELT%TYPE` (tip declarat repetat in
|
||||
`pack_facturare`, ex. `ff_...:191`) si `ACT.ID_VENCHELT%TYPE` (`ff_...:6725`) — deci
|
||||
`ID_VENCHELT` e o coloana FK pe `ACT` (tabelul de note contabile efective) si pe `CRM_NOTE_VANZARI`
|
||||
/ `CRM_POLITICI_PRET_ART` (vezi `NVL(B.ID_VENCHELT, D.ID_VENCHELT)` la `ff_...:7205`, unde `B` =
|
||||
`CRM_POLITICI_PRET_ART`, `D` = `CRM_NOTE_VANZARI` in cursorul comentat din pachet).
|
||||
- **Cine il consuma**: `pack_facturare.contabilizeaza_articol` il rezolva cu prioritate similara
|
||||
contului: `NVL(pack_facturare.nid_venchelt, NVL(A.ID_VENCHELT, C.ID_VENCHELT))` (override global de
|
||||
sesiune -> articol/politica -> nota de vanzare) si il trimite ca parametru propriu catre
|
||||
`scrie_nota(...)` (`ff_...:7461`), **separat** de `SCD`/`SCC`. E deci o **a treia dimensiune**
|
||||
(clasificare venituri/cheltuieli) atasata randului de nota contabila, nu sursa contului insusi —
|
||||
raportul anterior avea dreptate sa il caracterizeze ca "o clasificare, nu un cont", desi nu
|
||||
urmarise consumatorul pana la capat.
|
||||
- Numele `NOM_VENIT_CHELTUIELI` si folosirea alaturi de `SCD`/`SCC`/`ID_SECTIE` sugereaza un
|
||||
centru de venituri/cheltuieli pentru raportare (posibil situatii financiare pe sectii/centre de
|
||||
cost), nu un mecanism alternativ de determinare a contului 7xx.
|
||||
|
||||
## Neverificat
|
||||
|
||||
- **Structura completa (toate coloanele) a `NOTE_CONTABILE`, `CRM_NOTE_VANZARI`,
|
||||
`CRM_POLITICI_PRETURI` si `NOM_VENIT_CHELTUIELI`**: niciuna nu are `CREATE TABLE` in
|
||||
`SCRIPTURI_CLAR` (arhiva incepe 2009, tabelele sunt mai vechi). Coloanele folosite in cod sunt
|
||||
confirmate (`SCD`/`ASCD`/`SCC`/`ASCC`/`EXPLICATIE`/`CU_TVA`/`IN_VALUTA`/`ID_SET` pe
|
||||
`NOTE_CONTABILE`; `ID_NOTA`/`ID_SET` pe `CRM_NOTE_VANZARI`; `ID_NOTA`/`ID_POL` pe
|
||||
`CRM_POLITICI_PRETURI`; `ID_VENCHELT` pe `NOM_VENIT_CHELTUIELI`), dar lista completa ar necesita
|
||||
interogarea schemei Oracle live (`DESC NOTE_CONTABILE` etc.) sau un export DDL mai vechi decat
|
||||
2009, in afara bugetului acestei cercetari.
|
||||
- **Continutul efectiv al `NOTE_CONTABILE.SCC`** pentru notele configurate curent (adica ce conturi
|
||||
707/704/706/708 sunt de fapt setate, si daca fiecare politica de pret are o nota configurata) —
|
||||
ar necesita interogarea datelor din schema Oracle live, nu doar codul static.
|
||||
- **Daca `contabilizeaza_articol` e chiar apelata pe fluxul principal de facturare** (nu doar din
|
||||
`scrie_aviz_retur`) — am dedus asta din `CASE ... ntip <= 20 ...` (factura normala tratata explicit
|
||||
in functie), dar nu am urmarit *toti* apelantii ei in fisier (fisierul are 17000+ linii; cautarea
|
||||
`pack_facturare.contabilizeaza_articol` ar trebui repetata exhaustiv daca se doreste certitudine
|
||||
completa pe toate punctele de intrare — facturare avans, deviz, retail etc.).
|
||||
- **Comportamentul cand `NOTE_CONTABILE`/`CRM_NOTE_VANZARI` lipsesc pentru o politica de pret**:
|
||||
cursorul foloseste `LEFT JOIN`, deci `SCD`/`SCC` ar ajunge `NULL` fara eroare explicita in acest
|
||||
punct — nu am verificat daca exista o validare ulterioara (la `scrie_nota` sau la commit-ul notei)
|
||||
care sa blocheze o nota cu cont `NULL`.
|
||||
Reference in New Issue
Block a user