docs: runda 6 - cercetari, propuneri si conventia mediului Oracle
Cercetarile si propunerile rundelor 4-6 pe editarea facturii emise. Starea rundei 6 si ce s-a stabilit intra in progres.md. Nou: docs/conventii_mediu_oracle.md - pe dev/test se lucreaza numai cu ROA_CENTRAL si schemele CONTAFIN_ORACLE si MARIUSM_AUTO; schema ACN nu se foloseste. Scripturile de pachet sunt necalificate, deci schema tinta o decide sirul de conectare, nu fisierul. roafacturare.pj2 regenerat de git_sync. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013gYCNE26G1G7UoGu2ju7aS
This commit is contained in:
143
docs/cercetare/rec_s8_rulaje_tip4.md
Normal file
143
docs/cercetare/rec_s8_rulaje_tip4.md
Normal file
@@ -0,0 +1,143 @@
|
||||
# Cercetare: rulaje (RUL) pe factura emisă din aviz (tip = 4) — `test_s8_matrice_surse.prg:308`
|
||||
|
||||
## Verdict
|
||||
|
||||
**Asserția e greșită pentru tip = 4.** Tabela `RUL` reține exclusiv mișcări pe conturi de stoc
|
||||
(`371` în datele verificate); o factură emisă din aviz nu atinge niciodată contul de stoc — ea doar
|
||||
transformă creanța provizorie (`418`) în creanță fermă (`4111`) și TVA neexigibilă în TVA colectată
|
||||
(`4428`→`4428`) — pentru că marfa a ieșit deja din gestiune la avizul-sursă (tip 22), care e cel ce
|
||||
scrie rândurile de `RUL`. `Reccount(trul) = 0` pe un document de tip 4 e starea corectă, nu un semn
|
||||
că editarea a distrus rulaje.
|
||||
|
||||
---
|
||||
|
||||
## Ce am verificat la sursă (cod + date Oracle)
|
||||
|
||||
### 1. De unde se umple `trul`
|
||||
|
||||
`IncarcaCursoareModificareNota` (`COMUN\programe\ofacturare_editare.prg:35-148`) încarcă `trul`
|
||||
direct din view-ul `vrul_tot`, filtrat pe `an`/`luna`/`cod`, fără nicio sinteză sau completare:
|
||||
|
||||
```
|
||||
COMUN\programe\ofacturare_editare.prg:76
|
||||
lcSql = [select * from vrul_tot where ] + lcConditieSters + [ an = ] + Transform(m.tnAn) + [ and luna = ] + Transform(m.tnLuna) + [ and cod = ] + Alltrim(Str(m.tnCod)) + [ order by id_rul]
|
||||
```
|
||||
|
||||
`Reccount(trul)` e deci exact numărul de rânduri deja existente în `RUL` (server) pentru acel `cod`
|
||||
— nu ceva calculat sau garantat nenul de vreo regulă de business în client.
|
||||
|
||||
### 2. Cine scrie rulajele — și diferența pe tip de document
|
||||
|
||||
Scrierea efectivă e server-side, în Oracle, `PACK_CONTAFIN.SCRIE_IN_RUL` (`COMUN\docs\PACK_CONTAFIN.pck:1896-2019`):
|
||||
face `INSERT INTO RUL (...) SELECT ... FROM RUL_TEMP` — deci **scrie exact ce a fost pus în
|
||||
`RUL_TEMP` de partea VFP**, fără vreo ramură condiționată de tipul documentului. Tot ce contează e
|
||||
dacă `RUL_TEMP` (populat din `trul`, deci din `vrul_tot` deja existent) are rânduri.
|
||||
|
||||
Pe partea VFP, calea de editare a facturii (cea exercitată de test, prin `frm_facturi.do_editare_factura`,
|
||||
`COMUN\clase\ofacturare_comun.vc2:3799-3821`) copiază necondiționat `trul` înapoi în `RUL_TEMP` și
|
||||
apelează `OSCRIE_IN_FISIERE(0,.T.,.T.)` — al treilea parametru (echivalentul lui `llRul` din editorul
|
||||
generic) e **hardcodat `.T.`**, nu depinde de starea inițială:
|
||||
|
||||
```
|
||||
COMUN\clase\ofacturare_comun.vc2:3811-3821
|
||||
If Used('rul_temp')
|
||||
Use In rul_temp
|
||||
Endif
|
||||
Select * From trul Into Cursor RUL_TEMP Readwrite
|
||||
Replace All id_util With gnIdUtil, sters With 0
|
||||
...
|
||||
lnSucces = OSCRIE_IN_FISIERE(0,.T.,.T.)
|
||||
```
|
||||
|
||||
Deci: dacă `trul` a fost gol la încărcare (pasul 1), rămâne gol și la scriere — codul **conservă**
|
||||
starea, nu o corectează și nu o strică. (Contrast: editorul generic de jurnal contabil,
|
||||
`afisjurcom.do_modifica`, `COMUN\clase\comun.vc2:2370-2482`, are un flag explicit `llRul` setat doar
|
||||
dacă `Reccount(lcCursor)>0` la încărcarea inițială din `vrul_tot` — dar calea de factură nu folosește
|
||||
acest flag deloc, e mereu `.T.`, ceea ce confirmă din nou că absența rândurilor din `RUL` nu e
|
||||
tratată ca eroare de nicio ramură a codului.)
|
||||
|
||||
Originea rândurilor din `RUL` e deci strict la **crearea/finalizarea notei**, nu la editare —
|
||||
`PACK_CONTAFIN.finalizeaza_modificare_nota` (apelat și la creare, și la editare) doar re-scrie ce
|
||||
primește; nu am găsit nicio ramură condiționată de `tip`/`ntip` care să decidă "acest tip de
|
||||
document trebuie să aibă rulaje" — decizia e implicită, dată de **ce conturi apar în notă**, nu de
|
||||
tipul documentului.
|
||||
|
||||
### 3. Rolul lui `IN_STOC` în `ActualizeazaVerdictActRul`
|
||||
|
||||
`COMUN\clase\omodificari.vc2:13045-13146`. Verdictul ACT/RUL are trei stări, toate **informative,
|
||||
niciodată eroare**:
|
||||
|
||||
```
|
||||
COMUN\clase\omodificari.vc2:13129-13139
|
||||
DO CASE
|
||||
CASE !m.llVerdictSigur
|
||||
lcVerdict = 'Verdict ACT/RUL: nu se aplica (informativ, date de import)'
|
||||
CASE Abs(This.nTotalActRon - This.nTotalRulRon) <= 0.02
|
||||
lcVerdict = 'Verdict ACT/RUL: sincronizat (informativ)'
|
||||
OTHERWISE
|
||||
lcVerdict = 'Verdict ACT/RUL: divergent (informativ, nu e eroare)'
|
||||
ENDCASE
|
||||
```
|
||||
|
||||
`in_stoc` corectează doar **suma** comparată (exclude valoarea liniilor nestocate din articolele
|
||||
facturii, convertită în RON, din totalul RUL — `tvd` unde `Nvl(in_stoc,1) = 0`, linia 13111), nu
|
||||
decide dacă documentul "trebuie" să aibă rulaje. Nu există în această metodă (verificat integral,
|
||||
liniile 13045-13146, nu doar grep) nicio ramură specifică pentru `RUL = 0` pe tip 4 — cazul cade pur
|
||||
și simplu în "divergent (informativ, nu e eroare)" dacă `nTotalActRon <> 0` și `nTotalRulRon = 0`, ceea
|
||||
ce confirmă că design-ul acceptă explicit acest caz ca non-eroare.
|
||||
|
||||
### 4. Verificare pe date, read-only, Oracle `MARIUSM_AUTO`/`ROA_CENTRAL`
|
||||
|
||||
Conectat cu succes (`sqlplus.exe`, `SET TRANSACTION READ ONLY` ... `ROLLBACK`, fișier `.sql` ASCII,
|
||||
fără pipe). Cod-urile curente (verificate din `VANZARI`, nu presupuse):
|
||||
|
||||
| id_vanzare | tip | cod (curent) | sters | RUL (cnt activ) | ACT (cnt activ) |
|
||||
|---|---|---|---|---|---|
|
||||
| 1048 | 1 | 1140918 | 0 | 1 | 5 |
|
||||
| 1052 | 22 (aviz) | 1140921 | 0 | 4 | 12 |
|
||||
| 1054 | 4 (factură din aviz) | **1140923** | 0 | **0** | 2 |
|
||||
| 1055 | 2 | 1140920 | 0 | 1 | 7 |
|
||||
|
||||
`id_vanzare = 1054` are `cod` curent `1140923` (confirmă realocarea din test:
|
||||
`1140910 -> 1140922 -> 1140923`, citită direct din `VANZARI`, nu presupusă).
|
||||
|
||||
Detaliu decisiv — conturile efective din `ACT`/`RUL` pentru perechea aviz→factură (avizul 1052 e cel
|
||||
mai probabil sursă a facturii 1054, pe baza secvenței de cod-uri și a fluxului tip 22→tip 4):
|
||||
|
||||
```
|
||||
ACT pe avizul 1052 (tip 22): scd/scc includ 607/371, 371/378, 378/371, 4428/371, 371/4428, 418/704, 418/4428
|
||||
RUL pe avizul 1052 (tip 22): 4 rânduri, toate CONT = 371 (cont de stoc)
|
||||
|
||||
ACT pe factura 1054 (tip 4): scd/scc = 4111/418 (305 lei) și 4428/4428 (52.93 lei) -- NICIUN cont 371
|
||||
RUL pe factura 1054 (tip 4): 0 rânduri
|
||||
```
|
||||
|
||||
Avizul e cel care mișcă efectiv contul de stoc (`371`) și de aceea are rânduri în `RUL` (care
|
||||
urmărește exclusiv cantități pe conturi de stoc — vezi și `cant`/`cante` din `trul`, folosite ca
|
||||
atare în `ActualizeazaVerdictActRul:13102`). Factura emisă din acel aviz nu mai atinge `371` deloc —
|
||||
transformă doar creanța provizorie (`418`) în creanță fermă (`4111`) și TVA neexigibilă (`4428`) în
|
||||
TVA colectată (`4428`). N-are, structural, ce rând de stoc să scrie.
|
||||
|
||||
Zero tranzacții deschise la final (`ROLLBACK` executat, `SET TRANSACTION READ ONLY` respectat pe tot
|
||||
scriptul).
|
||||
|
||||
## Ce am dedus (nu verificat direct, dar consistent cu toate dovezile de mai sus)
|
||||
|
||||
- Regula generală: `RUL` se scrie doar pentru documentele/notele care conțin mișcare pe cont de
|
||||
stoc (aviz, NIR, bonuri de consum etc.); facturile "de închidere" (emise din aviz, sau orice
|
||||
document care doar transformă o creanță provizorie într-una fermă) nu vor avea niciodată rânduri
|
||||
în `RUL`, indiferent câte documente de acest fel verifici — nu e o particularitate a lui
|
||||
`id_vanzare = 1054`, ci a tipului de operațiune contabilă.
|
||||
- Aserția de la `test_s8_matrice_surse.prg:308` (`Reccount(trul) > 0` obligatoriu după editare) e
|
||||
probabil corectă ca test general "rulajele nu trebuie distruse de editare" pentru documentele care
|
||||
AU avut rulaje înainte de editare, dar e o presupunere greșită aplicată universal — pentru tip 4
|
||||
(și, prin extensie, orice tip de document care nu atinge cont de stoc) condiția trebuie relaxată
|
||||
la "dacă documentul avea rulaje înainte, tot le are și după" sau pur și simplu exclusă pentru
|
||||
tip = 4.
|
||||
|
||||
## Fișiere atinse
|
||||
|
||||
Niciunul (misiune read-only). Fișiere citite: `COMUN\programe\ofacturare_editare.prg`,
|
||||
`COMUN\clase\omodificari.vc2`, `COMUN\clase\comun.vc2`, `COMUN\clase\ofacturare_comun.vc2`,
|
||||
`COMUN\docs\PACK_CONTAFIN.pck`. Interogări Oracle read-only pe `MARIUSM_AUTO`@`ROA_CENTRAL`, cu
|
||||
`ROLLBACK` la final.
|
||||
Reference in New Issue
Block a user