raport VENITURI SI CHELTUIELI: parteneri, explicatii si interval de luni

This commit is contained in:
2026-08-24 13:22:16 +03:00
parent afd640b48a
commit 1e33fa2ed5

View File

@@ -51,6 +51,15 @@ Cuvinte rezervate, completate automat din globale (`orapoarte.vc2:1578-1586`):
Acestea **trebuie declarate cu `tipcamp = 'E'`**, iar `campid` = numele parametrului; altfel valoarea Acestea **trebuie declarate cu `tipcamp = 'E'`**, iar `campid` = numele parametrului; altfel valoarea
nu se rezolvă și apare „Nu este completata valoarea parametrului X!". nu se rezolvă și apare „Nu este completata valoarea parametrului X!".
Valoarea tastată de utilizator pentru un parametru rezervat este **ignorată** — se pune global. Deci
un interval (ex. lunile 1..7) cere doi parametri `tipcamp = 'N'` cu **alt nume**, iar numele nu are
voie să înceapă cu `AN`/`LUNA`/`SUCURSALA`: potrivirea din `do_instructiune_sql` e `=` VFP, iar cu
`SET EXACT OFF` un `LUNA_DE_LA` s-ar potrivi cu `LUNA`. Ex. `DE_LA_LUNA` / `PANA_LA_LUNA`, folosite
în SQL ca `luna between <%=DE_LA_LUNA%> and <%=PANA_LA_LUNA%>`.
Parametrul e citit din expresia de filtru spartă pe `AND` și apoi pe `=`, deci **merge doar operatorul
„egal"** (implicit la `N`) și numele nu poate conține `AND`.
`CSQL_PARAMETRI` = XML `VFPData` (encoding `Windows-1252`), câte un nod `crsparametri` cu `CSQL_PARAMETRI` = XML `VFPData` (encoding `Windows-1252`), câte un nod `crsparametri` cu
`parametru / titlu / camp / tipcamp / campid` (+ opțional `campcautare`); citit cu `XMLTOCURSOR` în `parametru / titlu / camp / tipcamp / campid` (+ opțional `campcautare`); citit cu `XMLTOCURSOR` în
`criterii_rapoarte_sql` și `parametri_rapoarte_sql` (`orapoarte_dinamice.prg:109-251`). `criterii_rapoarte_sql` și `parametri_rapoarte_sql` (`orapoarte_dinamice.prg:109-251`).
@@ -61,8 +70,8 @@ nu se rezolvă și apare „Nu este completata valoarea parametrului X!".
Șablon de urmat: `D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\07\ff_2026_07_23_01_GESTIUNE_RAPOARTE.sql` Șablon de urmat: `D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\07\ff_2026_07_23_01_GESTIUNE_RAPOARTE.sql`
(raportul `CHELTUIELI CUMULAT - REG JURNAL + RULAJE`, peste view-ul `VRUL_ACT_CHELTUIELI`) și (raportul `CHELTUIELI CUMULAT - REG JURNAL + RULAJE`, peste view-ul `VRUL_ACT_CHELTUIELI`) și
`...\2026\08\ff_2026_08_21_01_GESTIUNE_RAPOARTE.sql` (`VENITURI SI CHELTUIELI - REG JURNAL + `...\2026\08\ff_2026_08_24_03_GESTIUNE_RAPOARTE.sql` (`VENITURI SI CHELTUIELI - REG JURNAL +
RULAJE`, view `VRUL_ACT_VEN_CHELT`). Structura: RULAJE`, view-urile `VRUL_ACT_VEN_CHELT_DET` + `VRUL_ACT_VEN_CHELT_TOT`). Structura:
1. `CREATE OR REPLACE VIEW` cu logica raportului (SQL-ul din `CSQL` rămâne un `select` simplu peste 1. `CREATE OR REPLACE VIEW` cu logica raportului (SQL-ul din `CSQL` rămâne un `select` simplu peste
view — mai ușor de depanat și de refolosit). view — mai ușor de depanat și de refolosit).
@@ -79,6 +88,10 @@ RULAJE`, view `VRUL_ACT_VEN_CHELT`). Structura:
ca o problemă de drepturi. Verificare rapidă: `SEQ_RAPOARTE.last_number` a avansat, dar ca o problemă de drepturi. Verificare rapidă: `SEQ_RAPOARTE.last_number` a avansat, dar
`select * from rapoarte` nu are linia ⇒ lipsește `commit`. `select * from rapoarte` nu are linia ⇒ lipsește `commit`.
- Drepturile nu sunt opționale (vezi mai sus). - Drepturile nu sunt opționale (vezi mai sus).
- **`ACT.ID_PARTD` / `ACT.ID_PARTC` sunt `0` când nu există partener, niciodată `NULL`.** Un
`MIN(ID_PARTD)` peste notele unui document întoarce `0` și numele partenerului iese gol; corect e
`MIN(NULLIF(ID_PARTD, 0))`. Numele se iau din `NOM_PARTENERI.NUME` (în `VACT_TOT` sunt deja
rezolvate ca `PARTD`/`PARTC`).
- Ordinea coloanelor din `select`-ul din `CSQL` = ordinea coloanelor din grid. - Ordinea coloanelor din `select`-ul din `CSQL` = ordinea coloanelor din grid.
- `ORDER BY` se scrie în `CSQL`; coloanele tehnice de sortare pot fi selectate sau nu, dar trebuie să - `ORDER BY` se scrie în `CSQL`; coloanele tehnice de sortare pot fi selectate sau nu, dar trebuie să
existe în view. existe în view.
@@ -88,7 +101,13 @@ RULAJE`, view `VRUL_ACT_VEN_CHELT`). Structura:
Pentru totaluri la finalul listării (fără al doilea raport): `UNION ALL` cu rânduri sintetice care au Pentru totaluri la finalul listării (fără al doilea raport): `UNION ALL` cu rânduri sintetice care au
coloana de grupare **`NULL`** (Oracle sortează `NULLS LAST` la `ASC`, deci ajung ultimele) și un coloana de grupare **`NULL`** (Oracle sortează `NULLS LAST` la `ASC`, deci ajung ultimele) și un
`R_TIP` mai mare decât cele de detaliu; eticheta se pune într-o coloană text lată (`EXPLICATIA`), `R_TIP` mai mare decât cele de detaliu; eticheta se pune într-o coloană text lată (`EXPLICATIA`),
valoarea în coloana de sumă. Exemplu: `VRUL_ACT_VEN_CHELT`, `R_TIP` 9-15. valoarea în coloana de sumă. Exemplu: `VRUL_ACT_VEN_CHELT_TOT`, `R_TIP` 9-15.
Când raportul merge pe un **interval** de perioade, totalurile nu pot sta în view: view-ul le poate
da doar pe perioadă (altfel rândul agregat are `an`/`luna` `NULL` și cade la filtrul exterior). Deci
view-ul dă totalurile **pe lună**, iar `UNION ALL`-ul din `CSQL` le însumează pe intervalul cerut
(`group by r_tip, tip, explicatia`) — toate liniile fiind sume, adunarea pe luni e validă. Ramura de
totaluri pune `NULL` pe `an`/`luna`, deci blocul iese o singură dată, la finalul listării.
### Performanță: `WITH` materializat blochează filtrul de perioadă ### Performanță: `WITH` materializat blochează filtrul de perioadă
@@ -101,8 +120,8 @@ se aplică `an = ... and luna = ...`. Pe date de producție asta a însemnat 7.4
- `/*+ INLINE */` în CTE **nu** a rezolvat-o când CTE-ul e un `UNION ALL`. - `/*+ INLINE */` în CTE **nu** a rezolvat-o când CTE-ul e un `UNION ALL`.
- Ce funcționează: **view-uri separate în loc de CTE-uri referite de mai multe ori** — view-urile se - Ce funcționează: **view-uri separate în loc de CTE-uri referite de mai multe ori** — view-urile se
îmbină (view merging) și primesc predicatul. Vezi `VRUL_ACT_VEN_CHELT_DET` (detaliul) + îmbină (view merging) și primesc predicatul. Vezi `VRUL_ACT_VEN_CHELT_DET` (detaliul) +
`VRUL_ACT_VEN_CHELT` (detaliu `UNION ALL` totaluri, referă `_DET` de două ori) în `VRUL_ACT_VEN_CHELT_TOT` (totalurile pe lună, agregă `_DET`) în
`SCRIPTURI_CLAR\2026\08\ff_2026_08_21_01_GESTIUNE_RAPOARTE.sql`. `SCRIPTURI_CLAR\2026\08\ff_2026_08_24_03_GESTIUNE_RAPOARTE.sql`.
- Subinterogările auxiliare (ancore de dată, teste de existență, totaluri de control) citesc - Subinterogările auxiliare (ancore de dată, teste de existență, totaluri de control) citesc
**tabelele de bază `ACT` / `RUL`**, nu `VACT_TOT` / `VRUL_TOT`: view-urile astea nu filtrează **tabelele de bază `ACT` / `RUL`**, nu `VACT_TOT` / `VRUL_TOT`: view-urile astea nu filtrează
rânduri (doar left join-uri de nomenclator), dar `VRUL_TOT` are `FDOC`/`ID_FDOC` ca **subinterogări rânduri (doar left join-uri de nomenclator), dar `VRUL_TOT` are `FDOC`/`ID_FDOC` ca **subinterogări