sync SVN r17985: sursa de referinta DDL (MARIUSM_AUTO) + aliniere la origin

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Euno5AmwoFEvBTdWH8C8S
This commit is contained in:
2026-08-06 12:44:15 +03:00
parent 72bf63cd04
commit 8fa842888a
15 changed files with 1103 additions and 55 deletions

View File

@@ -0,0 +1,17 @@
# Capcana: coloana noua intr-un grid existent ajunge la coada (preferinte GridExtras)
`GridExtras` (`COMUN\utile\GridExtras\gridextras.vc2:1051`, `restoregridpreferences` /
`savegridpreferences`) salveaza **per utilizator** latimea si ordinea coloanelor fiecarui grid,
in `%APPDATA%\...\gridprefs.tmp`, sub cheia `SYS(1272, grid)` (ex. `frm_modific2024.grid1`).
Salvarea se face live, la `columnmoved`/`columnresize`, nu la iesirea din formular.
Consecinta: `ColumnOrder` setat in clasa e neutralizat la runtime pentru orice utilizator care a
deschis deja formularul inainte de livrare - `gridextra1.setup()` restaureaza ordinea veche, iar
coloana nou adaugata (care nu exista in preferinte) ajunge ultima.
Solutie: repozitionare la runtime, in `Show()`, **dupa** `gridextra1.setup()`, aplicata o singura
data - cat timp preferintele salvate nu acopera toate coloanele (implementat pe
`frm_modific2024`, `COMUN\clase\omodificari.vc2`, coloana `nnir`).
La testare: pozitia coloanei nu e o asertiune stabila intre masini. Se asertesteaza tare
`ControlSource` si `ReadOnly`; `ColumnOrder` ramane informativ.

View File

@@ -22,6 +22,16 @@ cu `diag_spatiu.ps1`; **email doar la prag depasit**, tacere completa altfel. Su
Sectiunile informative (recyclebin, UNDO, TEMP, istoric statistici/scheduler, top segmente, audit
SYS, disc) se scriu doar cand exista deja o alerta — dau context, nu alerteaza singure.
`co_2026_08_06_01_DIAG_SPATIU_PACK` (06.08.2026) corecteaza doua lucruri vazute pe primele rulari:
- **pragul absolut (2048 MB) nu se mai aplica tablespace-urilor al caror maxim e sub el** — orice
`UNDOTBS`/`SYSTEM` plafonat la 5002048 MB alerta zilnic, prin definitie; acolo ramane doar garda
relativa de 15%.
- **emailul contine tot logul rularii** (alertele intai, apoi toate randurile din `DIAG_SPATIU_LOG`,
cu `!` pe cele peste prag, sortate pe sectiune si valoare descrescator), nu doar un pointer catre
tabela. Corpul e plafonat la 30000 de caractere (`EmailDiagSpatiu` lucreaza pe `VARCHAR2(32000)`),
cu marcaj `... restul in DIAG_SPATIU_LOG` la depasire.
## Mecanisme reutilizabile (din investigatia pentru job)
- **`CONTAFIN_ORACLE.SERVER_INFO`** tine parolele `PASSWORD_SYS`/`PASSWORD_CONTAFIN_ORACLE`

View File

@@ -76,6 +76,10 @@ fals `roundtrip text1 != text2`. Ruleaza atunci cu lista rebazata:
- Metoda noua de clasa cere `*m: nume` in `*<DefinedPropArrayMethod>`; fara ea, prima salvare
din IDE o arunca tacut, iar refresh-ul urmator absoarbe pierderea in cache (si in .bak-uri).
Override-urile de metode de baza (Init, Show, hook-uri) nu au nevoie de `*m:`.
- FoxBin2Prg NU pastreaza pozitia in text a unei metode noi: o regenereaza la pozitia
alfabetica din `*<DefinedPropArrayMethod>`. O metoda scrisa in alta parte a fisierului
face fidelity-check-ul sa pice. Sursa de adevar pentru relocare e textul regenerat din
`<staging>\verify\` - muta metoda unde apare acolo si reia write-back-ul.
- Salvarea din VFP IDE peste un binar scris de txt2vcx poate PIERDE si definitii `*m:` deja
existente, desi corpurile PROCEDURE raman (patit pe ROAGEST: `import_adauga_factura.recalc_tva`,
`import_nota.do_adauga/do_copie/do_reface`); simptom: crash la Createobject cu

View File

@@ -0,0 +1,53 @@
# Flux: modificare/stergere nota in Registrul Jurnal
Comportament CORECT (nu bug): la **modificarea** unei note din Registrul Jurnal, documentul
original nu se suprascrie. Se marcheaza `sters = 1` pe randurile vechi (`ACT`/`RUL`/`RUL_OBINV`),
apoi se scrie un document NOU cu alt `cod`, pastrand acelasi `id_fact`/`id_factd`. Ambele operatii
ruleaza intr-o tranzactie manuala unica (commit sau rollback pe amandoua).
## Unde
- `afisjurcom.do_modifica` - `COMUN\clase\comun.vc2:2222-2562`. Deschide tranzactia manuala
(`Thisform.do_deschide_tranzactie()`, linia 2448), apoi `oscrie_in_fisiere(2,...)` = STERGE
(linia 2451), apoi `oscrie_in_fisiere(0,...)` = SCRIE (linia 2479), apoi
`pack_contafin.finalizeaza_modificare_nota(...)` (2484-2486), apoi
`Thisform.do_inchide_tranzactie(...)` (linia 2535) - commit daca tot ce a rulat inainte a
reusit, rollback altfel.
- `do_deschide_tranzactie`/`do_inchide_tranzactie` (`_frmbase`, `COMUN\clase\_frm_base.vc2:252,279`;
varianta identica ca procedura globala in `COMUN\programe\oproceduri_rulaje.prg:287,303`):
`SQLSetProp(gnHandle,'Transactions',2)` la deschidere, `SQLCOMMIT`/`SQLROLLBACK` +
`SQLSetProp(...,'Transactions',1)` la inchidere.
- `oscrie_in_fisiere.prg` (`COMUN\programe\oscrie_in_fisiere.prg`): `tnScrie_Sterge` 0=scriere,
2=stergere. Apeleaza server-side `pack_contafin.init_scriere_act_rul_local` +
`final_scriere_act_rul_local` -> `finalizeaza_scriere_act_rul`, care ruleaza `SCRIE_IN_ACT`
(scriere) sau `STERGE_DIN_ACT` (stergere) din `PACK_CONTAFIN.pck`.
- `PACK_CONTAFIN.STERGE_DIN_ACT` (`COMUN\docs\PACK_CONTAFIN.pck:1815-1859`):
`UPDATE ACT SET STERS = 1 ... WHERE COD = tnCod` - marcheaza vechiul document, pe `cod`-ul vechi.
- `PACK_CONTAFIN.SCRIE_IN_ACT` (`PACK_CONTAFIN.pck:630-901`): `LN_COD := pack_contafin.GET_COD()`
(linia 648) aloca un `cod` nou; `UPDATE ACT_TEMP SET COD = LN_COD, ...` (linia 897) il scrie pe
noul document - `ID_FACT` nu e atins, ramane cel din documentul original.
- `PACK_CONTAFIN.finalizeaza_modificare_nota` (`PACK_CONTAFIN.pck:8601-8651`): aloca din nou
`lnCodNou := pack_contafin.get_cod()` si actualizeaza pe codul nou `vanzari`
(`pack_facturare.actualizeaza_vanzari`) si `atasamente_vanzari`. `nom_lucrari` se actualizeaza
DOAR pentru `id_set IN (31003,31004,31005,31011)` (repune `id_fact`), nu general. `gest_inventar`
NU se leaga de `cod`-ul nou - se identifica dupa `dataora_validat + an + luna` (cazul
`id_set = 90101`, note de inventariere).
## Atentie: nu e valabil la fel pentru stergerea simpla
`afisjurcom.do_sterge` (`comun.vc2:2565-2724`) ofera doua optiuni (`xmenu`, linia 2625):
- **Stergere document** (`lnOptiune = 1`): DOAR `OSCRIE_IN_FISIERE(2,...)` + `finalizeaza_stergere_nota`
- marcheaza `sters = 1`, NU se creeaza document nou.
- **Anulare document** (`lnOptiune = 2`): STERGE (linia 2698) + SCRIE (linia 2709, cu sumele puse pe
0) - creeaza si document nou, la fel ca la modificare - dar aici cele doua apeluri NU sunt
invelite intr-o tranzactie manuala comuna (nu apare `do_deschide_tranzactie`/
`do_inchide_tranzactie` in `do_sterge`); fiecare `OSCRIE_IN_FISIERE` isi gestioneaza singur
commit-ul (vezi `tlModificare`/`llManualTransactions` in `oscrie_in_fisiere.prg:111-165`).
## Implicatii practice
- Codul (`cod`) unui document din Registrul Jurnal NU e stabil dupa modificare/anulare - se schimba
la fiecare editare. Cod hardcodat sau retinut dintr-o executare anterioara devine invalid.
- Regasirea documentului editat se face dupa `id_fact` (sau alt marcaj stabil), niciodata dupa `cod`.
- Randurile `sters = 1` ramase in `ACT`/`RUL`/`RUL_OBINV` dupa o modificare sunt normale (istoric),
nu date corupte sau duplicate de curatat.

View File

@@ -15,6 +15,10 @@ PL/SQL Developer.
`PACK_CONTAFIN` există în schemele `MARIUSM_AUTO` (dev) și `ACN`, plus sinonim `PUBLIC`.
Exportul de referință se face din `MARIUSM_AUTO`.
Înainte de a lua o sursă de acolo ca referință pentru o modificare, verifică că `MARIUSM_AUTO` are
toate scripturile aplicate — procedura e în `scripturi-migrare-db.md`, secțiunea
"Sursa de referință pentru DDL".
## Gotcha sqlplus pe Windows/PowerShell
Nu trimite SQL prin pipe din PowerShell (`'select...' | sqlplus`) — BOM-ul UTF-16 sparge parserul

View File

@@ -0,0 +1,83 @@
# Publicarea scripturilor de baza de date catre clienti
Scriptul: `COMUN\utile\publicare_scripturi.ps1`. Inlocuieste pasii manuali din `tasks.exe`
(`D:\PROIECTE\fox\tasks`, formularul din `clase\generare_script.vcx`), care raman varianta de rezerva.
Cum se scrie un script de migrare: `scripturi-migrare-db.md`.
```powershell
powershell -File COMUN\utile\publicare_scripturi.ps1 -DryRun # ce ar face pe luna curenta
powershell -File COMUN\utile\publicare_scripturi.ps1 # luna curenta, tot fluxul
powershell -File COMUN\utile\publicare_scripturi.ps1 -Luna 2026-08 # alta luna
powershell -File COMUN\utile\publicare_scripturi.ps1 -Fisier a.sql,b.sql # doar scripturile date
```
Alte optiuni: `-DoarImport` (fara arhiva), `-DoarArhiva` (doar regenerare arhiva), `-Toate`
(republica si scripturile identice), `-FaraVerificareZip`, `-Settings`, `-ZipPath`, `-DirScripturi`,
`-Alias`, `-User`, `-Password`, `-SqlPlus`.
## Configurarea
Se citeste din `settings.ini`-ul lui `tasks.exe` (`D:\PROIECTE\fox\tasks\settings.ini`, schimbabil
cu `-Settings`), aceleasi chei pe care le foloseste formularul; orice parametru dat explicit bate
ini-ul.
| din ini | ce devine |
|---|---|
| `[connection] host_database` | nume de **DSN ODBC** — aliasul TNS e cheia `ServerName` a DSN-ului din registri (`CENTRAL``ROA_CENTRAL`) |
| `[connection] username_database` / `password_database` | utilizatorul Oracle |
| `[folder] script_folder` | directorul scripturilor, cu `\SCRIPTURI\``\SCRIPTURI_CLAR\` (+ `\<an>\<luna>\`) |
| `[folder] roa_output` | + `_UPDATE\` = directorul arhivelor |
| `[folder] sqlplus_exe` | clientul Oracle (si `TNS_ADMIN` = directorul lui) |
| `[script]` | prefixele valide (`CO_`, `FF_`, `RF_`, `SYS_`, `JCS_`) — prefix necunoscut = avertisment |
`sqlplus_exe` arata spre `instantclient_19_18`; `instantclient_11_2_0_2` (valoarea de dinainte) are
un `tnsnames.ora` vechi, cu `ROA_CENTRAL` pe `10.0.20.122` in loc de `.121`, deci conexiunea expira.
`settings.ini` e local (ignorat de SVN).
## Cei doi pasi
**1. Import** — fiecare `.sql` intra ca un rand in `CONTAFIN_ORACLE.UPD_DATABASE` de pe `ROA_CENTRAL`,
cu `SCRIPT_ORDER = 0` (randul contine scriptul intreg, nu instructiuni parsate), `SCRIPT_NAME` cu
MAJUSCULE si `.SQL`, `SCRIPT_TYPE` = ce urmeaza dupa `NN_`, `SCRIPT_CONTENT` = fisierul in clar.
`ID` vine din trigger, `DATAORA` din `SYSDATE` implicit, `SCRIPT_APPVER`/`SCRIPT_EXTRA_FILE` raman
goale. Daca `SCRIPT_NAME` exista deja, se face **update pe acelasi `id`** — asa se republica un
script corectat, pentru ca clientul face `MERGE ... on (a.id = b.id)`.
**2. Arhiva lunara** — in `Y:\ROAUPDATE\_UPDATE\` se scriu `database_YYYYMMDD_YYYYMMDD.zip` **si**
`databasen_...zip` (identice azi: `database_` era varianta criptata cu `wrap.exe`, nu se mai
foloseste). Fiecare contine XML-ul cu acelasi nume ca zip-ul (format `VFPData`/`crsxml`,
Windows-1252, CRLF, tab-uri, `script_content` gol) plus cate un `<STEM_MAJUSCULE>.sql` per script.
Indexii `roa_database.xml` / `roa_databasen.xml` listeaza arhivele existente si se schimba doar
cand apare o luna noua.
Continutul din arhiva se citeste **inapoi din baza**, nu de pe disc — deci arhiva contine exact ce
va primi clientul.
## Verificari facute automat
- fisier cu sfarsituri de linie LF: **refuzat** (parsarea pe client se face pe `CHR(13)+CHR(10)`);
- dupa import, continutul e citit inapoi din CLOB si comparat octet cu octet cu fisierul; la
diferenta se opreste inainte de arhiva;
- scripturile deja publicate cu acelasi continut se sar (`-Toate` forteaza republicarea);
- arhiva generata se citeste inapoi cu cititorul clientului (`pack_utils.decodebase64` +
`zip_util_pkg.get_file`) si se compara lungime + MD5 per fisier — o arhiva facuta din PowerShell
este citita corect de `zip_util_pkg`;
- fisierele inlocuite din `_UPDATE` se copiaza intai in `_UPDATE\_backup\<data_ora>\`.
`Y:\ROAUPDATE\_UPDATE\` e **live**: clientii descarca de acolo imediat ce fisierul e pus.
## Ce face clientul
`PACK_UPDATE.UpdateScripts` (`COMUN\docs\PACK_UPDATE.pck`) descarca indexul, apoi arhivele care
acopera perioada neaplicata, extrage XML-ul cu `zip_util_pkg.get_file`, face `MERGE` in
`UPD_DATABASE` pe `id`, apoi pentru fiecare rand cu `script_extra_file` pune continutul fisierului
in `script_content` — pentru `.sql` text clar, fara base64 (base64 e doar pentru instructiunile
parsate, alta ramura). Actualizare blocata: `depanare-pack-update.md`.
## Detalii de implementare
Continutul circula **hexazecimal** in ambele sensuri (`utl_i18n.raw_to_char` / `string_to_raw` cu
`WE8MSWIN1252`), pe bucati de 900 de octeti, in blocuri PL/SQL de cate 15 bucati. Motivul: baza e
`AL32UTF8`, fisierele sunt CP1252, iar comanda trimisa lui `sqlplus` ramane ASCII pur — nu depinde
de `NLS_LANG` si nu poate strica octetii >= 0x80. Consecinta utila: comparatia dintre fisier si
CLOB e exacta, nu pe lungime.

View File

@@ -60,6 +60,8 @@
`0xBA` strica `a`/`t` cu caciula (`0xE3`, `0xFE`) din alte fisiere;
- adaugi/rearanjezi controale pe formulare sau coloane in grid -> `conventie_ux_formulare.md`;
- grid needitabil pe formular cu 2+ grid-uri -> `capcana_grid_controlsource.md`;
- adaugi o coloana intr-un grid deja livrat (ordinea din clasa e neutralizata de
preferintele salvate per utilizator) -> `capcana_grid_preferinte_utilizator.md`;
- `GO` pe un `Recno()` capturat/primit ca parametru -> `conventie_go_recno.md`;
- `ALTER TABLE` pe cursorul intors de `goExecutor.oExecute()` -> `conventie_goexecutor_alter_table.md`;
- testare UI / prin MCP -> `testare-ui-vfp.md`, `testare-vfp-mcp.md`;

View File

@@ -3,7 +3,8 @@
Scripturile de migrare a schemei (si modelele pentru scripturi noi) sunt in
`DATABASE\SCRIPTURI_CLAR` de sub radacina suitei ROA (`gcDirMare`/`dirgen` — ex.
`D:\ROA\DATABASE\SCRIPTURI_CLAR`). Sursa SVN: `http://svnroa:3001/svn/ROA/DATABASE/Branches/RB-1.00`.
Pentru un script nou, urmeaza formatul/conventiile celor recente de acolo.
Pentru un script nou, urmeaza formatul/conventiile celor recente de acolo. Publicarea catre clienti
(import in `UPD_DATABASE` + arhiva lunara): `publicare-scripturi-db.md`.
Reguli confirmate de Marius (24.07.2026):
@@ -16,6 +17,34 @@ Reguli confirmate de Marius (24.07.2026):
- Aplicarea prin ODBC/`goExecutor`: sintaxa SQL*Plus `exec pachet.procedura(...)` nu functioneaza
— foloseste `begin pachet.procedura(...); end;`.
## Sursa de referinta pentru DDL: MARIUSM_AUTO, nu productia
Regula lui Marius (06.08.2026): **orice modificare de tabela, view, procedura, functie sau pachet se
scrie plecand de la sursa din schema de dezvoltare `MARIUSM_AUTO` (`ROA_CENTRAL`), niciodata de la
sursa citita dintr-o schema de client** (`VENDING`, `ACN`, ...). Schemele de client raman in urma:
pot avea scripturi neaplicate sau variante livrate separat (ex. pachetele `_10G_ROMCONSTRUCT`), iar o
modificare scrisa peste o sursa veche sterge corectii deja livrate.
Schemele de client raman utile doar pentru **masuratori pe date reale**, in citire.
### Verifica intai ca MARIUSM_AUTO e la zi
"Ultima versiune din dev" e ultima versiune doar daca toate scripturile din `SCRIPTURI_CLAR` chiar au
fost aplicate acolo. `pack_migrare.UpdateVersiune` inregistreaza fiecare script aplicat in tabela
`VERSIUNE` (`script_final` = numele fisierului, cu tot cu `.sql`), deci diferenta se vede direct:
```sql
select script_final, data_final from versiune order by data_script desc, seq_script desc;
```
```powershell
Get-ChildItem D:\ROA\DATABASE\SCRIPTURI_CLAR -Recurse -Filter *.sql |
Select-Object -ExpandProperty Name | Sort-Object
```
Daca lipsesc scripturi din `VERSIUNE`, **nu porni modificarea** pe sursa de acolo — semnaleaza-i lui
Marius ce nu e aplicat. Exportul sursei de referinta: `oracle_export.md`.
## Continutul unui script
- **Minimul necesar si intotdeauna SCOPED**: `update`/`insert` doar pe randurile cazului tratat

View File

@@ -12,6 +12,7 @@ a doua oara — daca a doua oara e nevoie de acelasi lucru, scrie scriptul.
| editare `.vcx`/`.scx` | `D:\ROA\UTIL\foxbin2prg\` : `git_sync.ps1`, `vfp_symbols.ps1`, `txt2vcx.ps1` | reimprospatare text in-arbore, index de simboluri, write-back cu fidelity-check |
| actualizare de baza de date blocata | `COMUN\utile\diag_actualizare.ps1 -Alias <TNS>` | `UPD_ISTORIC``UPD_LOG``script_master.log` → versiuni per schema → job → tablespace → verdict. Vezi `depanare-pack-update.md` |
| spatiu plin la un client | `COMUN\utile\diag_spatiu.ps1 -Alias <TNS> [-Disc] [-SysPassword]` | tablespace, audit, ADR, FRA, disc server, top segmente. Vezi `depanare-spatiu-oracle.md` |
| publicare scripturi de baza de date | `COMUN\utile\publicare_scripturi.ps1 [-Luna YYYY-MM] [-Fisier ...] [-DryRun]` | import in `UPD_DATABASE` → arhiva lunara `database[n]_*.zip` + indexi in `_UPDATE`, cu verificare octet cu octet. Vezi `publicare-scripturi-db.md` |
| teste UI VFP | harness din `COMUN\utile\Teste` | vezi `testare-ui-vfp.md` |
Documentatia **nu** se genereaza automat si nu exista niciun hook care s-o scrie — `livrare.ps1`