Merge branch 'main' of gitea.romfast.ro:romfast/comun
This commit is contained in:
@@ -25,7 +25,7 @@ DEFINE CLASS actualizare_curs_bnr AS _custom OF "_baza.vcx"
|
||||
|
||||
*<PropValue>
|
||||
ccursor = ccrsbnr
|
||||
clink = https://www.bnr.ro/nbrfxrates.xml
|
||||
clink = https://curs.bnr.ro/nbrfxrates.xml
|
||||
ctempfile = C:\temp\temp.xml
|
||||
ddata = {}
|
||||
Height = 17
|
||||
|
||||
@@ -22,6 +22,26 @@ 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_08_DIAG_SPATIU_PACK` + `sys_2026_08_06_07_DIAG_SPATIU_GRANT3` (06.08.2026) scriu la
|
||||
top segmente si **tabela/coloana din care provine segmentul** (`DetaliuSegment`: `DBA_LOBS`,
|
||||
`DBA_LOB_PARTITIONS`, `DBA_INDEXES`; segmentele temporare se marcheaza ca atare) — fara asta un
|
||||
`SYS_LOB0000630560C00017$$` de 4 GB in email nu spune nimic, iar serverul clientului nu e accesibil
|
||||
direct. Atentie: pentru `LOB PARTITION`, `dba_segments.segment_name` e `lob_name`, nu
|
||||
`lob_partition_name`.
|
||||
|
||||
Emailurile ajung pe `marius.mutu@romfast.ro`, cate un expeditor per client
|
||||
(`roaupdate_<client>@romfast.ro`); citirea lor: `email-thunderbird.md`.
|
||||
|
||||
`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 500–2048 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`
|
||||
@@ -70,6 +90,15 @@ SYS, disc) se scriu doar cand exista deja o alerta — dau context, nu alerteaza
|
||||
|
||||
## Capcane
|
||||
|
||||
- **Segmentele `TEMPORARY` dintr-un tablespace permanent nu dispar intotdeauna la restart** (ACN,
|
||||
06.08.2026: 1.3 GB ramasi si dupa repornirea serviciului). Daca `v$sort_usage` e gol, sunt orfane
|
||||
si se curata fortat, ca `SYS`: `alter session set events 'immediate trace name DROP_SEGMENTS level
|
||||
<ts#+1>'` (`ts#` din `v$tablespace`) — la ACN au disparut instantaneu, cu tot spatiul recuperat.
|
||||
Daca nici asa nu pleaca, apartin unui DDL neterminat — cauta `SYS_JOURNAL%` (index online) sau
|
||||
obiecte `INVALID/UNUSABLE` in schema respectiva.
|
||||
- **`shrink space` pe un LOB cere ASSM**; pe un tablespace MSSM da `ORA-10635` (cazul `ROA` la ACN).
|
||||
Echivalentul care merge: `alter table t move lob (col) store as (tablespace <ts>)` — reconstruieste
|
||||
segmentul, tine tabela blocata cat dureaza si cere spatiu liber cat segmentul mutat.
|
||||
- **Privilegiile `ANY` nu se aplica pe obiectele din schema `SYS`** cat timp
|
||||
`O7_DICTIONARY_ACCESSIBILITY=FALSE` — orice curatare acolo cere `SYSDBA`.
|
||||
- Parola `SYS` e de obicei cea generica (vezi `COMUN\docs\local\oracle.md`), dar **nu la toti
|
||||
|
||||
41
docs/email-thunderbird.md
Normal file
41
docs/email-thunderbird.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# Citirea emailurilor (Thunderbird Portable)
|
||||
|
||||
Conectorul Gmail din Claude vede **doar** `mmarius28@gmail.com`. Conturile de lucru
|
||||
(`marius.mutu@romfast.ro` etc.) nu sunt acolo — se citesc local, din mbox-urile Thunderbird:
|
||||
|
||||
```
|
||||
D:\UTIL\portable\PortableApps\ThunderbirdPortable\Data\profile\ImapMail\<cont>\INBOX
|
||||
```
|
||||
|
||||
Conturi active (dupa `LastWriteTime`): `mail.romfast.ro` (~36 MB, contul principal) si
|
||||
`mail.romfast-1.ro` (~108 MB). Restul (`seanet.ro`, `romfast-4.ro`, `imap.googlemail.com`, …)
|
||||
sunt vechi de ani.
|
||||
|
||||
```powershell
|
||||
powershell -File COMUN\utile\citeste_email.ps1 -Cauta 'Diagnostic spatiu' -Ultimele 10
|
||||
powershell -File COMUN\utile\citeste_email.ps1 -Nr <linie> [-Linii 200]
|
||||
```
|
||||
|
||||
Prima forma listeaza `Cont / Linie / Data / De_la / Subiect` (filtru `-Cauta` pe subiect **sau**
|
||||
expeditor, `-Cont mail.romfast.ro` restrange la un cont); a doua tipareste mesajul care incepe la
|
||||
linia respectiva, pana la urmatorul separator mbox.
|
||||
|
||||
## Capcane
|
||||
|
||||
- **Nu da `Grep`/ripgrep pe folder**: `INBOX.sbd\Sent` are ~2.5 GB si cautarea expira.
|
||||
- **Numerotarea liniilor difera intre unelte** (`Select-String` vs `Get-Content` vs `StreamReader`)
|
||||
— mbox-ul are linii cu `\r` singur. Foloseste numarul dat de `citeste_email.ps1`, pentru ca
|
||||
`-Nr` citeste cu acelasi cititor; daca linia ceruta nu e inceput de mesaj, scriptul trece la
|
||||
contul urmator (`-Nr` fara `-Cont` cauta in toate).
|
||||
- Thunderbird tine fisierul deschis → citire doar cu `FileShare::ReadWrite` (scriptul o face).
|
||||
- Mesajele sunt in ordine cronologica, **cel mai nou la sfarsitul fisierului**; separatorul e
|
||||
`From - <data>`. Corpurile HTML/base64 se tipar brut — pentru ele ia doar `Content-Type` si
|
||||
primele linii, nu tot mesajul.
|
||||
|
||||
## Emailuri automate ROA
|
||||
|
||||
| Expeditor | Ce e |
|
||||
|---|---|
|
||||
| `roaupdate_acn@`, `roaupdate-sigma@`, `roaupdate-clever@`, `roaupdate-automotive@` … | jobul `DIAGSPATIU_ZILNIC`, subiect `Diagnostic spatiu Oracle <BAZA> <data> <ora>`, cate un expeditor per client. Vezi `depanare-spatiu-oracle.md` |
|
||||
|
||||
Emailul vine **doar la prag depasit**; tacere = totul in regula.
|
||||
@@ -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
|
||||
|
||||
@@ -17,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
|
||||
|
||||
@@ -14,6 +14,7 @@ a doua oara — daca a doua oara e nevoie de acelasi lucru, scrie scriptul.
|
||||
| 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` |
|
||||
| citirea emailurilor de pe conturile romfast | `COMUN\utile\citeste_email.ps1 [-Cauta ...] [-Nr <linie>]` | listeaza/extrage mesaje din mbox-urile Thunderbird Portable (conectorul Gmail nu vede conturile romfast). Vezi `email-thunderbird.md` |
|
||||
|
||||
Documentatia **nu** se genereaza automat si nu exista niciun hook care s-o scrie — `livrare.ps1`
|
||||
doar semnaleaza ce lipseste (changelog neatins, binar VFP fara textul lui sincronizat).
|
||||
|
||||
@@ -245,11 +245,11 @@ TRY
|
||||
DO CreeazaIntrodc WITH 'introdc'
|
||||
DO CreeazaIntrodc WITH 'introdc_sablon'
|
||||
INSERT INTO introdc_sablon (scd, scc, cu_tva, ordine, id_set, participa_valuta, tip_rand, ;
|
||||
id_jtva_coloana, ptva, explicatie_tva) ;
|
||||
VALUES ('371', '401', 1, 1, 1, .T., 'B', 208, 21, 'ACH. INT. 21%')
|
||||
id_jtva_coloana, ptva, explicatie_tva, taxcode) ;
|
||||
VALUES ('371', '401', 1, 1, 1, .T., 'B', 208, 21, 'ACH. INT. 21%', 301204)
|
||||
INSERT INTO introdc_sablon (scd, scc, cu_tva, ordine, id_set, participa_valuta, tip_rand, ;
|
||||
id_jtva_coloana, ptva, explicatie_tva) ;
|
||||
VALUES ('4426', '401', 1, 2, 1, .T., 'T', 209, 21, 'TVA ACH. INT. 21%')
|
||||
id_jtva_coloana, ptva, explicatie_tva, taxcode) ;
|
||||
VALUES ('4426', '401', 1, 2, 1, .T., 'T', 209, 21, 'TVA ACH. INT. 21%', 301204)
|
||||
GO TOP IN introdc_sablon
|
||||
|
||||
DO CreeazaRulTemp
|
||||
@@ -735,6 +735,34 @@ PROCEDURE VerificaRandD
|
||||
lcMsg = 'FAIL ' + tcLabel + '-randD: nu exista rand tip_rand=D in introdc dupa sincronizeaza() (diferenta asteptata=' + TRANSFORM(lnSumaAsteptata) + ')'
|
||||
ENDIF
|
||||
DO R7Log WITH lcMsg
|
||||
DO VerificaTaxCodeRandD WITH tcLabel
|
||||
SELECT (lnSel)
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE VerificaTaxCodeRandD
|
||||
*-- randul D (diferenta 6xx) nu are cod de taxa SAFT; randurile de baza si TVA il pastreaza.
|
||||
LPARAMETERS tcLabel
|
||||
LOCAL lnSel, lcMsg, lnTaxD, lnFaraTax
|
||||
lnSel = SELECT()
|
||||
SELECT introdc
|
||||
LOCATE FOR tip_rand == 'D'
|
||||
IF !FOUND()
|
||||
DO R7Log WITH 'FAIL ' + tcLabel + '-randD-taxcode: nu exista rand tip_rand=D'
|
||||
SELECT (lnSel)
|
||||
RETURN
|
||||
ENDIF
|
||||
lnTaxD = NVL(taxcode, 0)
|
||||
lnFaraTax = 0
|
||||
SCAN FOR INLIST(tip_rand, 'B', 'S', 'T', 'G') AND EMPTY(NVL(taxcode, 0))
|
||||
lnFaraTax = lnFaraTax + 1
|
||||
ENDSCAN
|
||||
IF EMPTY(lnTaxD) AND lnFaraTax = 0
|
||||
lcMsg = 'PASS ' + tcLabel + '-randD-taxcode: randul D are taxcode gol, iar randurile B/S/T/G il pastreaza'
|
||||
ELSE
|
||||
lcMsg = 'FAIL ' + tcLabel + '-randD-taxcode: taxcode pe randul D=' + TRANSFORM(lnTaxD) + ;
|
||||
' (astept 0), randuri B/S/T/G fara taxcode=' + TRANSFORM(lnFaraTax) + ' (astept 0)'
|
||||
ENDIF
|
||||
DO R7Log WITH lcMsg
|
||||
SELECT (lnSel)
|
||||
ENDPROC
|
||||
|
||||
|
||||
128
utile/Teste/nnir_registru_jurnal/date_test_nnir.md
Normal file
128
utile/Teste/nnir_registru_jurnal/date_test_nnir.md
Normal file
@@ -0,0 +1,128 @@
|
||||
# Date de test - NNIR editabil in Registru Jurnal
|
||||
|
||||
Baza: `MARIUSM_AUTO@ROA_CENTRAL` (test, nu productie). Verificare: `verif_nnir_cod.sql` in acest
|
||||
folder (`sqlplus ... @verif_nnir_cod.sql <cod>`).
|
||||
|
||||
| Caz | COD | AN | LUNA | ID_SET | NNIR curent | ACT randuri | RUL randuri | RUL_OBINV randuri |
|
||||
|---|---|---|---|---|---|---|---|---|
|
||||
| NIR/achizitie (principal) | 1140841 | 2026 | 7 | 209 | 3 | 7 (doar 1 cu nnir=3, restul 0) | 1 (nnir=3) | 0 |
|
||||
| Obiecte de inventar | 1140835 | 2026 | 6 | 211 | 2026060001 | 1 | 0 | 2 (nnir=2026060001) |
|
||||
| Fara rulaje | 1140848 | 2026 | 7 | 209 | 124 | 2 (ambele nnir=124) | 0 | 0 |
|
||||
| Nota de inventar (blocare) | 1140716 | 2026 | 3 | 90101 | 2026030004 | 1 | 1 (nnir=2026030004) | 0 |
|
||||
|
||||
Note:
|
||||
- ACT e pe linii (nu pe antet) - la COD 1140841 doar linia efectiv legata de rulaj are NNIR-ul
|
||||
real, restul liniilor documentului au NNIR=0. Sincronizarea (`WHERE Nvl(nnir,0) = vechi`) trebuie
|
||||
sa lase liniile cu 0 neatinse.
|
||||
- Nu exista nicio nota cu `id_set=90101` sau cu rulaje in `RUL_OBINV` in luna curenta de lucru
|
||||
(AN=2026, LUNA=7) - alese din perioade anterioare. Editarea reala prin `afisjurcom.do_modifica`
|
||||
e limitata la luna curenta (`comun.vc2:2265-2268`); testul instantiaza `frm_modific2024` direct
|
||||
(ca `test_repro_cnrcrt_footer.prg`), cu cursoare construite pe AN/LUNA propriu notei, ocolind
|
||||
acel filtru - la fel ca precedentul deja acceptat in `achizitie_import`.
|
||||
|
||||
## Stare implementare (livrata, 03.08.2026)
|
||||
|
||||
`COMUN\clase\omodificari.vc2` (frm_modific2024):
|
||||
- `Grid1.ColumnCount = 44`, `Column44.ControlSource = "nnir"` (la runtime apare calificat automat
|
||||
de VFP cu aliasul cursorului: `tact.nnir`), `ReadOnly = .F.` - confirmat prin instantiere reala
|
||||
(nu doar citire de sursa).
|
||||
- `PROCEDURE sincronizeaza_nnir(tnNnirVechi, tnNnirNou)` (`omodificari.vc2:13762`) - update pe
|
||||
`tact`/`trul`/`trul_obinv` unde `Nvl(nnir,0) = vechi`, cu revenire pe recno. Propaga si valoarea
|
||||
0 (stergerea NNIR) - nu exista garda `EMPTY` pe valoarea noua.
|
||||
- Legare pe coloana: `Grid1.Column44.Text1.When` retine valoarea veche in `thisform.nnnirvechi`;
|
||||
**`Grid1.Column44.Text1.LostFocus`** apeleaza `sincronizeaza_nnir` si `Thisform.Grid1.Refresh()`
|
||||
- `Valid` a fost eliminat (la textbox valoarea nu ajunge in ControlSource decat DUPA ce Valid
|
||||
returneaza .T., deci nu propaga). Testul declanseaza `LostFocus`.
|
||||
- Blocarea pentru `id_set = 90101` (nota de inventar): in `Init` (`omodificari.vc2:13654`) SI
|
||||
reimpusa in `Grid1.AfterRowColChange` (14289-14292), dupa `SetAll("ReadOnly", ...)` - fara a doua,
|
||||
`SetAll` anuleaza blocarea la prima navigare in grid.
|
||||
- `ColumnOrder = 7` in clasa, plus repozitionare la runtime in `Show()`, dupa `gridextra1.setup()`
|
||||
(13729-13738) - preferintele de grid salvate per utilizator impingeau coloana noua la coada
|
||||
(vezi `COMUN\docs\capcana_grid_preferinte_utilizator.md`). Pozitia NU e o asertiune stabila intre
|
||||
masini; asertat tare in test: `ControlSource = "nnir"`, `ReadOnly` (.F. normal / .T. pe
|
||||
id_set 90101), propagarea valorii.
|
||||
|
||||
## Cerinte de mediu descoperite la construirea harness-ului (deja tratate in scripturile livrate)
|
||||
|
||||
- `COMUN\utile\Teste\test_init_env_auto.prg` (generic) e de fapt specific ROACONT (`gcAppPath`,
|
||||
classlib-uri si proceduri hardcodate `D:\ROA\ROACONT\`) - inutilizabil pentru ROAGEST. S-a scris
|
||||
`COMUN\utile\Teste\test_init_env_auto_roagest.prg`, cu SET PATH/CLASSLIB/PROCEDURE reconstruite
|
||||
din `Programe\roagest.prg`.
|
||||
- `gcUserName` trebuie setat explicit inainte de `optiuni_firma` (`oinit_optiuni.prg`) - altfel
|
||||
`SCRIE_OPTIUNI(gcUserName)` da "Operator/operand type mismatch" (PUBLIC nedeclarat ramane
|
||||
logic .F.). **`gcUserName` e schema/userul de conectare Oracle** (`Programe\roagest.prg:560,575`)
|
||||
- `SCRIE_OPTIUNI` il foloseste direct in `from <gcUserName>.optiuni`, deci trebuie
|
||||
`gcUserName = m.gcS`, NU un nume de persoana (ex. 'MARIUS M' da ORA-00907, identificator invalid
|
||||
- incercare gresita initiala). Numele de persoana e `gcUserNameApp` (variabila separata).
|
||||
- `frm_modific2024` face `Seek(..,'crsJtvaTemp','id_jtva')` in ControlSource-ul coloanei de
|
||||
explicatie TVA a rulajelor (Column63) - evaluat la CONSTRUCTIA formularului. Fara cursorul
|
||||
deschis, `CREATEOBJECT('frm_modific2024',...)` pica cu "File 'crsjtvatemp.dbf' does not exist".
|
||||
Fix: `update_jtva_coloane('', 'crsJtvaTemp', 6)` (in `COMUN\programe\updateserver.prg:553`)
|
||||
inainte de instantiere - construieste direct cursorul cu indexul cerut, fara pasii intermediari
|
||||
folositi de exemplul ROACONT (`update_jtva_coloana`/`crsExplicatiiTVATemp`, care oricum nu
|
||||
exista in ROAGEST).
|
||||
- Mock-ul `amessagebox` trebuie incarcat **INAINTE** de `test_init_env_auto_roagest.prg` (nu doar
|
||||
dupa, cum sugereaza exemplele din `achizitie_import`) - `optiuni_firma` poate afisa un dialog
|
||||
real daca `SCRIE_OPTIUNI` raporteaza eroare, inainte sa apuce sa se incarce mock-ul "la coada".
|
||||
- La citirea unei coloane de grid prin ControlSource dintr-un cursor legat ca RecordSource, VFP
|
||||
calificat automat campul simplu cu aliasul (`nnir` -> `tact.nnir`) - comparatiile exacte
|
||||
`== 'NNIR'` trebuie sa accepte si forma calificata.
|
||||
- Coloanele de grid nu sunt garantat numite `Column<N>` - unele au `Name` custom (ex. `cAles` pe
|
||||
pozitia 41 in acest grid); accesul dinamic la coloana trebuie facut prin colectia
|
||||
`Grid1.Columns(i)`, nu prin constructia textuala a numelui `"column" + TRANSFORM(i)`.
|
||||
- `frm_modific2024.Grid1.AfterRowColChange` are propria logica de blocare pe sucursala (SetAll
|
||||
ReadOnly pe toate coloanele daca `Nvl(gnIdSucursala,0) <> Nvl(tAct.id_sucursala,0)`) - independenta
|
||||
de blocarea 90101, se declanseaza automat la pozitionare in grid. COD 1140835 (cazul obiecte de
|
||||
inventar) are `id_sucursala` diferit de sesiunea de test (`gnIdSucursala = NULL`), deci Column44
|
||||
iese `ReadOnly=.T.` in acest scenariu - nu e o eroare, e comportament existent, neplanificat de
|
||||
NNIR; sincronizarea tot functioneaza (apelul e direct, nu prin UI).
|
||||
- **Termin reatribuie COD nou**: `afisjurcom.do_modifica` (comun.vc2:2444-2487) cheama
|
||||
`oscrie_in_fisiere` de DOUA ori - intai `(2,.T.,llRul)` (STERGE, marcheaza `sters=1` pe COD-ul
|
||||
ORIGINAL, din `actactan` neatins de editare), apoi `(0,.T.,llRul)` (SCRIE varianta editata sub
|
||||
COD nou, generat de `pack_contafin`, sub AN/LUNA de sesiune curenta - nu pastreaza COD-ul/AN/LUNA
|
||||
notei editate). Verificarea si curatenia testului se fac dupa NNIR (marcaj distinct), nu dupa
|
||||
COD, si readuc nota originala la `sters=0` dupa test (pasul STERGE o dezactiveaza altfel permanent).
|
||||
- Salvarea reala cere tranzactie manuala explicita: `SQLSetProp(gnHandle,'Transactions',2)` inainte
|
||||
de blocul STERGE+SCRIE+finalizeaza, apoi `SQLCOMMIT(gnHandle)`/`SQLROLLBACK` +
|
||||
`SQLSetProp(...,1)` dupa - echivalentul direct al `thisform.do_deschide_tranzactie()`/
|
||||
`do_inchide_tranzactie()` din `afisjurcom` (`_frm_base.vc2:252-305`, mostenite, apelate pe
|
||||
formularul de jurnal - nu pe `frm_modific2024`, deci invizibile la o privire doar pe clasa notei).
|
||||
Fara acest wrapping, `oscrie_in_fisiere`/`finalizeaza_modificare_nota` raporteaza succes dar nu
|
||||
se vede nimic persistat, nici in aceeasi sesiune.
|
||||
|
||||
## Capcana: .FXP stale ascunde scenariile noi
|
||||
|
||||
VFP nu recompileaza .prg-ul daca exista un .FXP mai vechi - ruleaza tacut versiunea veche a
|
||||
scriptului. Simptom: suita raporteaza PASS-uri corecte, dar scenariile adaugate dupa ultima
|
||||
compilare nu apar deloc in log (verifica numarul de assert-uri, nu doar `0 FAIL`). Sterge
|
||||
.FXP-ul inainte de fiecare rulare.
|
||||
|
||||
## Capcana: dialog modal "Enter the value for <var>" in loc de eroare catchabila
|
||||
|
||||
O variabila memorie lipsa/umbrita folosita ca `?param` intr-un SQL pass-through (SQLEXEC/
|
||||
`goExecutor.oExecuta`) NU da o eroare VFP catchabila (ON ERROR) - deschide dialogul nativ
|
||||
"View Parameter" ("Enter the value for <var>"), MODAL, care blocheaza tot procesul headless la
|
||||
nesfarsit si nu lasa nimic in log (spre deosebire de un `REPLACE`/expresie cu aceeasi variabila
|
||||
lipsa, care DA eroare catchabila - vezi cazul `gnIdUtil` scapat o data ca `PRIVATE` neasignat).
|
||||
Simptom: proces `vfp9.exe` care nu mai raspunde, fara `.ERR`, fara linie noua in log.
|
||||
|
||||
Remediu: **garda explicita inainte de orice rulare care ajunge la cod ce foloseste `?param`** -
|
||||
verifica `TYPE(<nume>) == 'U'` pe toate variabilele relevante (nu doar cele proprii testului, ci
|
||||
si cele din codul apelat: `oscrie_in_fisiere`, `pack_contafin`/`pack_sesiune`, `oinit_optiuni.prg`)
|
||||
si opreste testul cu FAIL clar in log daca lipseste ceva, inainte sa ajunga la SQLEXEC. Implementat
|
||||
in `test_nnir_sincronizare.prg` (`NnirGardaVariabile`, apelata imediat dupa init mediu). `TYPE()`
|
||||
returneaza `'X'` (nu `'U'`) pentru NULL - o valoare NULL e un bind valid, doar variabila absenta
|
||||
e problema.
|
||||
|
||||
## Rezultat test complet (03.08.2026, pe binarul livrat)
|
||||
|
||||
**33 PASS, 0 FAIL** pe cele 6 scenarii: NIR, obiecte de inventar si nota fara rulaje (toate cu
|
||||
salvare reala prin Termin + verificare in Oracle), blocare `id_set=90101`, `NNIR -> 0`, si blocare
|
||||
`id_set=90101` pe sucursala curenta. Baza de test verificata dupa rulare: cele 4 note originale
|
||||
(1140841, 1140835, 1140848, 1140716) raman intacte (NNIR si `sters` la valorile initiale); notele
|
||||
noi create de Termin (COD reatribuit) au fost marcate `sters=1` de curatenia din test.
|
||||
|
||||
Scenariul 6 (`INVENTAR2`) exista pentru ca scenariul 4 ruleaza pe o nota din ALTA sucursala, unde
|
||||
`AfterRowColChange` blocheaza oricum tot gridul - trecea din motivul gresit. Scenariul 6 aliniaza
|
||||
`gnIdSucursala` la nota (`llReadOnly` iese `.F.`) si asertesteaza si ca restul coloanelor raman
|
||||
editabile, altfel blocarea NNIR nu dovedeste nimic.
|
||||
839
utile/Teste/nnir_registru_jurnal/test_nnir_sincronizare.prg
Normal file
839
utile/Teste/nnir_registru_jurnal/test_nnir_sincronizare.prg
Normal file
@@ -0,0 +1,839 @@
|
||||
* test_nnir_sincronizare.prg
|
||||
* Test e2e (fluxul real): NNIR editabil in Registru Jurnal, cu sincronizare in tact/trul/trul_obinv
|
||||
* si in ACT/RUL/RUL_OBINV (Oracle). Vezi cerinta initiala (todos.txt pct. 9) si
|
||||
* date_test_nnir.md (datele de test alese, an/luna/cod, stare implementare la data scrierii).
|
||||
*
|
||||
* Instantiaza frm_modific2024 direct (ca test_repro_cnrcrt_footer.prg din achizitie_import),
|
||||
* cu cursoarele tact/trul/trul_obinv construite exact ca afisjurcom.do_modifica (comun.vc2:2352-
|
||||
* 2434), dar pe AN/LUNA proprii notei - do_modifica limiteaza editarea la luna curenta de lucru
|
||||
* (comun.vc2:2265-2268), iar notele de test nu sunt toate in luna curenta.
|
||||
*
|
||||
* Editarea NNIR se simuleaza ca un utilizator: pozitionare pe rand, declansarea evenimentelor
|
||||
* reale ale coloanei (When la intrare, LostFocus la iesire - textboxul nu comite valoarea in
|
||||
* ControlSource inainte de Valid, de-aia implementarea sincronizeaza pe LostFocus), NU apel
|
||||
* direct al metodei de sincronizare. Salvarea (Termin) replica blocul din
|
||||
* afisjurcom.do_modifica (comun.vc2:2456-2487): oscrie_in_fisiere + pack_contafin.
|
||||
* finalizeaza_modificare_nota. Termin reatribuie COD nou (pack_contafin), sub AN/LUNA de sesiune
|
||||
* curenta - nu pastreaza COD-ul original; verificarea si curatenia de dupa salvare se fac dupa
|
||||
* valoarea NNIR marcaj (nu poate coincide cu date reale), marcand sters=1 (conventia aplicatiei)
|
||||
* orice a ajuns sub acea valoare - nota originala (COD/NNIR vechi) ramane intacta.
|
||||
*
|
||||
* Rulare headless (nu tine VFP IDE deschis; nu rula cu roagest.exe pornit):
|
||||
* & "C:\Program Files (x86)\Microsoft Visual FoxPro 9\vfp9.exe" -A -T ;
|
||||
* "D:\ROA\ROAGEST\COMUN\utile\Teste\nnir_registru_jurnal\test_nnir_sincronizare.prg"
|
||||
* Timeout recomandat: minim 220s. Log: %TEMP%\test_nnir_sincronizare_log.txt (PASS/FAIL pe linie).
|
||||
* STERGE .FXP-ul inainte de rulare: VFP nu recompileaza automat si ruleaza tacut versiunea
|
||||
* veche a scriptului - scenariile adaugate intre timp lipsesc cu totul din log.
|
||||
|
||||
LPARAMETERS tcMode
|
||||
tcMode = IIF(EMPTY(tcMode), 'ALL', UPPER(ALLTRIM(tcMode)))
|
||||
|
||||
SET SAFETY OFF
|
||||
SET TALK OFF
|
||||
|
||||
PUBLIC gcLogFile, gnFail, gnPass
|
||||
gcLogFile = ADDBS(SYS(2023)) + 'test_nnir_sincronizare_log.txt'
|
||||
gnFail = 0
|
||||
gnPass = 0
|
||||
STRTOFILE('START ' + tcMode + ' ' + TTOC(DATETIME()) + CHR(13)+CHR(10), gcLogFile)
|
||||
|
||||
ON ERROR DO NnirErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
|
||||
ON SHUTDOWN QUIT
|
||||
|
||||
* mock amessagebox incarcat INAINTE de mediul aplicatiei: optiuni_firma (in mediul de test)
|
||||
* poate afisa un dialog real daca SCRIE_OPTIUNI raporteaza eroare
|
||||
SET PROCEDURE TO D:\ROA\ROAGEST\COMUN\utile\Teste\mock_amessagebox.prg ADDITIVE
|
||||
DO D:\ROA\ROAGEST\COMUN\utile\Teste\test_init_env_auto_roagest.prg WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
|
||||
IF gnHandle <= 0
|
||||
DO NnirLog WITH 'EROARE: conectare Oracle esuata'
|
||||
DO NnirLog WITH 'REZULTAT SUITA: NEDETERMINAT'
|
||||
QUIT
|
||||
ENDIF
|
||||
DO NnirLog WITH 'mediu OK, gnAn=' + TRANSFORM(gnAn) + ' gnLuna=' + TRANSFORM(gnLuna)
|
||||
|
||||
* garda anti-blocaj: o variabila lipsa folosita ca ?param intr-un SQL pass-through NU da eroare
|
||||
* catchabila - VFP deschide dialogul modal nativ "Enter the value for <var>", care blocheaza
|
||||
* headless-ul la nesfarsit si nu lasa nimic in log (vezi date_test_nnir.md). Verificare
|
||||
* explicita INAINTE de orice apel care le foloseste, opreste testul cu FAIL clar daca lipseste ceva.
|
||||
IF !NnirGardaVariabile()
|
||||
DO NnirLog WITH 'REZULTAT SUITA: NEDETERMINAT (garda variabile a picat)'
|
||||
QUIT
|
||||
ENDIF
|
||||
|
||||
* mock amessagebox - se incarca ULTIMUL (dupa fisierele aplicatiei), vezi antetul mock-ului
|
||||
SET PROCEDURE TO D:\ROA\ROAGEST\COMUN\utile\Teste\mock_amessagebox.prg ADDITIVE
|
||||
|
||||
* Grid1.Column63 (explicatie TVA pe rulaje) face Seek pe alias 'crsJtvaTemp' la CONSTRUCTIA
|
||||
* formularului (inainte de Init) - fara cursorul deschis, CREATEOBJECT('frm_modific2024',...)
|
||||
* pica cu "File 'crsjtvatemp.dbf' does not exist"
|
||||
update_jtva_coloane('', 'crsJtvaTemp', 6)
|
||||
|
||||
LOCAL Omodif, lcCallWhen, lcCallLostFocus, lcCall
|
||||
|
||||
*=====================================================================================
|
||||
* Scenariul 1: NIR/achizitie, cu rulaje in RUL, cu salvare (Termin) + verificare Oracle
|
||||
*=====================================================================================
|
||||
IF INLIST(tcMode, 'ALL', 'NIR')
|
||||
LOCAL lnCod, lnAn, lnLuna, lnIdSet, lnNnirVechi, lnNnirNou
|
||||
LOCAL lnCntTactVechi, lnCntTrulVechi, lnCntTactNou, lnCntTrulNou
|
||||
LOCAL i, llGasit, lnColOrder, llReadOnly, lnColCheck, lcColName
|
||||
|
||||
lnCod = 1140841
|
||||
lnAn = 2026
|
||||
lnLuna = 7
|
||||
lnIdSet = 209
|
||||
lnNnirVechi = 3
|
||||
lnNnirNou = lnNnirVechi + 90000000
|
||||
|
||||
DO NnirConstruiesteCursoare WITH lnCod, lnAn, lnLuna
|
||||
|
||||
SELECT tact
|
||||
lnCntTactVechi = 0
|
||||
COUNT FOR NVL(nnir,0) = lnNnirVechi TO lnCntTactVechi
|
||||
SELECT trul
|
||||
lnCntTrulVechi = 0
|
||||
COUNT FOR NVL(nnir,0) = lnNnirVechi TO lnCntTrulVechi
|
||||
|
||||
Omodif = CREATEOBJECT('frm_modific2024', lnIdSet)
|
||||
IF VARTYPE(Omodif) <> 'O'
|
||||
DO NnirAssert WITH 'instantiere', 'NIR', .F., 'frm_modific2024 nu s-a instantiat'
|
||||
ELSE
|
||||
SELECT tact
|
||||
Omodif.grid1.SetFocus
|
||||
Omodif.gridextra1.setup()
|
||||
Omodif.CalculeazaTotal()
|
||||
|
||||
llGasit = .F.
|
||||
lnColOrder = 0
|
||||
llReadOnly = .T.
|
||||
lnColCheck = 0
|
||||
FOR i = 1 TO Omodif.grid1.ColumnCount
|
||||
lcColName = 'Omodif.grid1.Columns(' + TRANSFORM(i) + ')'
|
||||
IF NnirEsteColoanaNnir(EVALUATE(lcColName + '.ControlSource'))
|
||||
llGasit = .T.
|
||||
lnColOrder = EVALUATE(lcColName + '.ColumnOrder')
|
||||
llReadOnly = EVALUATE(lcColName + '.ReadOnly')
|
||||
lnColCheck = i
|
||||
ENDIF
|
||||
ENDFOR
|
||||
DO NnirAssert WITH 'coloana_grid', 'NIR', llGasit, 'ControlSource=nnir gasit=' + ;
|
||||
TRANSFORM(llGasit) + ' ColumnOrder=' + TRANSFORM(lnColOrder) + ' ReadOnly=' + TRANSFORM(llReadOnly)
|
||||
|
||||
IF llGasit
|
||||
DO NnirAssert WITH 'coloana_editabila', 'NIR', !llReadOnly, 'nota normala: ReadOnly asteptat .F.'
|
||||
|
||||
SELECT tact
|
||||
LOCATE FOR NVL(nnir,0) = lnNnirVechi
|
||||
IF FOUND()
|
||||
lcCallWhen = 'Omodif.grid1.Columns(' + TRANSFORM(lnColCheck) + ').Text1.When'
|
||||
&lcCallWhen
|
||||
REPLACE nnir WITH lnNnirNou
|
||||
lcCallLostFocus = 'Omodif.grid1.Columns(' + TRANSFORM(lnColCheck) + ').Text1.LostFocus'
|
||||
&lcCallLostFocus
|
||||
|
||||
SELECT tact
|
||||
lnCntTactNou = 0
|
||||
COUNT FOR NVL(nnir,0) = lnNnirNou TO lnCntTactNou
|
||||
DO NnirAssert WITH 'sync_tact', 'NIR', lnCntTactNou = lnCntTactVechi, ;
|
||||
TRANSFORM(lnCntTactNou) + ' randuri tact cu nnir nou (asteptat ' + TRANSFORM(lnCntTactVechi) + ')'
|
||||
|
||||
* trul = cursorul legat de pgfArticole.page1.grdRulaje (RecordSource) - verificare
|
||||
* explicita ca propagarea se vede in cursorul de rulaje, nu doar in tact
|
||||
SELECT trul
|
||||
lnCntTrulNou = 0
|
||||
COUNT FOR NVL(nnir,0) = lnNnirNou TO lnCntTrulNou
|
||||
DO NnirAssert WITH 'sync_trul', 'NIR', lnCntTrulNou = lnCntTrulVechi, ;
|
||||
TRANSFORM(lnCntTrulNou) + ' randuri trul (grid rulaje) cu nnir nou (asteptat ' + TRANSFORM(lnCntTrulVechi) + ')'
|
||||
ELSE
|
||||
DO NnirAssert WITH 'locate_rand_vechi', 'NIR', .F., 'nu s-a gasit randul cu nnir vechi in tact'
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
DO NnirVerificaOracleNeschimbat WITH lnCod, lnNnirVechi, 'NIR'
|
||||
|
||||
Omodif.Release()
|
||||
Omodif = NULL
|
||||
DO NnirSalveazaSiVerifica WITH lnCod, lnAn, lnLuna, lnIdSet, lnNnirVechi, lnNnirNou, 'NIR'
|
||||
ENDIF
|
||||
DO NnirCurataCursoare
|
||||
ENDIF
|
||||
|
||||
*=====================================================================================
|
||||
* Scenariul 2: obiecte de inventar, cu rulaje in RUL_OBINV, cu salvare + verificare Oracle
|
||||
*=====================================================================================
|
||||
IF INLIST(tcMode, 'ALL', 'OBINV')
|
||||
LOCAL lnCod2, lnAn2, lnLuna2, lnIdSet2, lnNnirVechi2, lnNnirNou2
|
||||
LOCAL lnCntTactVechi2, lnCntRobinvVechi2, lnCntTactNou2, lnCntRobinvNou2
|
||||
LOCAL i2, llGasit2, lnColOrder2, llReadOnly2, lnColCheck2, lcColName2
|
||||
|
||||
lnCod2 = 1140835
|
||||
lnAn2 = 2026
|
||||
lnLuna2 = 6
|
||||
lnIdSet2 = 211
|
||||
lnNnirVechi2 = 2026060001
|
||||
lnNnirNou2 = lnNnirVechi2 + 90000000
|
||||
|
||||
DO NnirConstruiesteCursoare WITH lnCod2, lnAn2, lnLuna2
|
||||
|
||||
SELECT tact
|
||||
lnCntTactVechi2 = 0
|
||||
COUNT FOR NVL(nnir,0) = lnNnirVechi2 TO lnCntTactVechi2
|
||||
SELECT trul_obinv
|
||||
lnCntRobinvVechi2 = 0
|
||||
COUNT FOR NVL(nnir,0) = lnNnirVechi2 TO lnCntRobinvVechi2
|
||||
|
||||
Omodif = CREATEOBJECT('frm_modific2024', lnIdSet2)
|
||||
IF VARTYPE(Omodif) <> 'O'
|
||||
DO NnirAssert WITH 'instantiere', 'OBINV', .F., 'frm_modific2024 nu s-a instantiat'
|
||||
ELSE
|
||||
SELECT tact
|
||||
Omodif.grid1.SetFocus
|
||||
Omodif.gridextra1.setup()
|
||||
Omodif.CalculeazaTotal()
|
||||
|
||||
llGasit2 = .F.
|
||||
lnColOrder2 = 0
|
||||
llReadOnly2 = .T.
|
||||
lnColCheck2 = 0
|
||||
FOR i2 = 1 TO Omodif.grid1.ColumnCount
|
||||
lcColName2 = 'Omodif.grid1.Columns(' + TRANSFORM(i2) + ')'
|
||||
IF NnirEsteColoanaNnir(EVALUATE(lcColName2 + '.ControlSource'))
|
||||
llGasit2 = .T.
|
||||
lnColOrder2 = EVALUATE(lcColName2 + '.ColumnOrder')
|
||||
llReadOnly2 = EVALUATE(lcColName2 + '.ReadOnly')
|
||||
lnColCheck2 = i2
|
||||
ENDIF
|
||||
ENDFOR
|
||||
DO NnirAssert WITH 'coloana_grid', 'OBINV', llGasit2, 'ControlSource=nnir gasit=' + ;
|
||||
TRANSFORM(llGasit2) + ' ColumnOrder=' + TRANSFORM(lnColOrder2) + ' ReadOnly=' + TRANSFORM(llReadOnly2)
|
||||
|
||||
IF llGasit2
|
||||
SELECT tact
|
||||
LOCATE FOR NVL(nnir,0) = lnNnirVechi2
|
||||
IF FOUND()
|
||||
lcCallWhen = 'Omodif.grid1.Columns(' + TRANSFORM(lnColCheck2) + ').Text1.When'
|
||||
&lcCallWhen
|
||||
REPLACE nnir WITH lnNnirNou2
|
||||
lcCallLostFocus = 'Omodif.grid1.Columns(' + TRANSFORM(lnColCheck2) + ').Text1.LostFocus'
|
||||
&lcCallLostFocus
|
||||
|
||||
SELECT tact
|
||||
lnCntTactNou2 = 0
|
||||
COUNT FOR NVL(nnir,0) = lnNnirNou2 TO lnCntTactNou2
|
||||
DO NnirAssert WITH 'sync_tact', 'OBINV', lnCntTactNou2 = lnCntTactVechi2, ;
|
||||
TRANSFORM(lnCntTactNou2) + ' randuri tact cu nnir nou (asteptat ' + TRANSFORM(lnCntTactVechi2) + ')'
|
||||
|
||||
SELECT trul_obinv
|
||||
lnCntRobinvNou2 = 0
|
||||
COUNT FOR NVL(nnir,0) = lnNnirNou2 TO lnCntRobinvNou2
|
||||
DO NnirAssert WITH 'sync_trul_obinv', 'OBINV', lnCntRobinvNou2 = lnCntRobinvVechi2, ;
|
||||
TRANSFORM(lnCntRobinvNou2) + ' randuri trul_obinv cu nnir nou (asteptat ' + TRANSFORM(lnCntRobinvVechi2) + ')'
|
||||
ELSE
|
||||
DO NnirAssert WITH 'locate_rand_vechi', 'OBINV', .F., 'nu s-a gasit randul cu nnir vechi in tact'
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
Omodif.Release()
|
||||
Omodif = NULL
|
||||
DO NnirSalveazaSiVerificaObinv WITH lnCod2, lnAn2, lnLuna2, lnIdSet2, lnNnirVechi2, lnNnirNou2
|
||||
ENDIF
|
||||
DO NnirCurataCursoare
|
||||
ENDIF
|
||||
|
||||
*=====================================================================================
|
||||
* Scenariul 3: nota fara rulaje - regresie (nu crapa), cu salvare + verificare Oracle
|
||||
*=====================================================================================
|
||||
IF INLIST(tcMode, 'ALL', 'FARARUL')
|
||||
LOCAL lnCod3, lnAn3, lnLuna3, lnIdSet3, lnNnirVechi3, lnNnirNou3
|
||||
LOCAL lnCntTactVechi3, lnCntTactNou3
|
||||
LOCAL i3, llGasit3, lnColCheck3, lcColName3
|
||||
|
||||
lnCod3 = 1140848
|
||||
lnAn3 = 2026
|
||||
lnLuna3 = 7
|
||||
lnIdSet3 = 209
|
||||
lnNnirVechi3 = 124
|
||||
lnNnirNou3 = lnNnirVechi3 + 90000000
|
||||
|
||||
DO NnirConstruiesteCursoare WITH lnCod3, lnAn3, lnLuna3
|
||||
|
||||
SELECT tact
|
||||
lnCntTactVechi3 = 0
|
||||
COUNT FOR NVL(nnir,0) = lnNnirVechi3 TO lnCntTactVechi3
|
||||
|
||||
Omodif = CREATEOBJECT('frm_modific2024', lnIdSet3)
|
||||
IF VARTYPE(Omodif) <> 'O'
|
||||
DO NnirAssert WITH 'instantiere', 'FARARUL', .F., 'frm_modific2024 nu s-a instantiat'
|
||||
ELSE
|
||||
SELECT tact
|
||||
Omodif.grid1.SetFocus
|
||||
Omodif.gridextra1.setup()
|
||||
Omodif.CalculeazaTotal()
|
||||
|
||||
llGasit3 = .F.
|
||||
lnColCheck3 = 0
|
||||
FOR i3 = 1 TO Omodif.grid1.ColumnCount
|
||||
lcColName3 = 'Omodif.grid1.Columns(' + TRANSFORM(i3) + ')'
|
||||
IF NnirEsteColoanaNnir(EVALUATE(lcColName3 + '.ControlSource'))
|
||||
llGasit3 = .T.
|
||||
lnColCheck3 = i3
|
||||
ENDIF
|
||||
ENDFOR
|
||||
DO NnirAssert WITH 'coloana_grid', 'FARARUL', llGasit3, 'ControlSource=nnir gasit=' + TRANSFORM(llGasit3)
|
||||
|
||||
IF llGasit3
|
||||
SELECT tact
|
||||
LOCATE FOR NVL(nnir,0) = lnNnirVechi3
|
||||
IF FOUND()
|
||||
lcCallWhen = 'Omodif.grid1.Columns(' + TRANSFORM(lnColCheck3) + ').Text1.When'
|
||||
&lcCallWhen
|
||||
REPLACE nnir WITH lnNnirNou3
|
||||
lcCallLostFocus = 'Omodif.grid1.Columns(' + TRANSFORM(lnColCheck3) + ').Text1.LostFocus'
|
||||
&lcCallLostFocus
|
||||
|
||||
SELECT tact
|
||||
lnCntTactNou3 = 0
|
||||
COUNT FOR NVL(nnir,0) = lnNnirNou3 TO lnCntTactNou3
|
||||
DO NnirAssert WITH 'sync_tact', 'FARARUL', lnCntTactNou3 = lnCntTactVechi3, ;
|
||||
TRANSFORM(lnCntTactNou3) + ' randuri tact cu nnir nou (asteptat ' + TRANSFORM(lnCntTactVechi3) + ')'
|
||||
DO NnirAssert WITH 'nu_crapa', 'FARARUL', .T., 'editarea pe nota fara rulaje nu a generat eroare'
|
||||
ELSE
|
||||
DO NnirAssert WITH 'locate_rand_vechi', 'FARARUL', .F., 'nu s-a gasit randul cu nnir vechi in tact'
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
Omodif.Release()
|
||||
Omodif = NULL
|
||||
DO NnirSalveazaSiVerifica WITH lnCod3, lnAn3, lnLuna3, lnIdSet3, lnNnirVechi3, lnNnirNou3, 'FARARUL'
|
||||
ENDIF
|
||||
DO NnirCurataCursoare
|
||||
ENDIF
|
||||
|
||||
*=====================================================================================
|
||||
* Scenariul 4: nota de inventar (id_set=90101) - regresie blocare editare NNIR
|
||||
*=====================================================================================
|
||||
IF INLIST(tcMode, 'ALL', 'INVENTAR')
|
||||
LOCAL lnCod4, lnAn4, lnLuna4, lnIdSet4
|
||||
LOCAL i4, llGasit4, llReadOnly4, lcColName4
|
||||
|
||||
lnCod4 = 1140716
|
||||
lnAn4 = 2026
|
||||
lnLuna4 = 3
|
||||
lnIdSet4 = 90101
|
||||
|
||||
DO NnirConstruiesteCursoare WITH lnCod4, lnAn4, lnLuna4
|
||||
|
||||
Omodif = CREATEOBJECT('frm_modific2024', lnIdSet4)
|
||||
IF VARTYPE(Omodif) <> 'O'
|
||||
DO NnirAssert WITH 'instantiere', 'INVENTAR', .F., 'frm_modific2024 nu s-a instantiat'
|
||||
ELSE
|
||||
SELECT tact
|
||||
Omodif.grid1.SetFocus
|
||||
Omodif.gridextra1.setup()
|
||||
Omodif.CalculeazaTotal()
|
||||
|
||||
llGasit4 = .F.
|
||||
llReadOnly4 = .F.
|
||||
FOR i4 = 1 TO Omodif.grid1.ColumnCount
|
||||
lcColName4 = 'Omodif.grid1.Columns(' + TRANSFORM(i4) + ')'
|
||||
IF NnirEsteColoanaNnir(EVALUATE(lcColName4 + '.ControlSource'))
|
||||
llGasit4 = .T.
|
||||
llReadOnly4 = EVALUATE(lcColName4 + '.ReadOnly')
|
||||
ENDIF
|
||||
ENDFOR
|
||||
DO NnirAssert WITH 'coloana_grid', 'INVENTAR', llGasit4, 'ControlSource=nnir gasit=' + TRANSFORM(llGasit4)
|
||||
IF llGasit4
|
||||
* nu se incearca editarea - doar se verifica blocarea, ca sa nu se altereze o nota
|
||||
* reala de inventar cat timp blocarea nu e implementata
|
||||
DO NnirAssert WITH 'coloana_blocata', 'INVENTAR', llReadOnly4, ;
|
||||
'id_set=90101: ReadOnly asteptat .T., gasit ' + TRANSFORM(llReadOnly4)
|
||||
ENDIF
|
||||
|
||||
Omodif.Release()
|
||||
Omodif = NULL
|
||||
ENDIF
|
||||
DO NnirCurataCursoare
|
||||
ENDIF
|
||||
|
||||
*=====================================================================================
|
||||
* Scenariul 5: stergere NNIR (-> 0) pe randul unei note cu rulaje - propagare la 0.
|
||||
* Comportament nou (runda 4): garda EMPTY(NVL(tnNnirNou,0)) eliminata din sincronizeaza_nnir,
|
||||
* ramane doar egalitatea - stergerea celulei (0 scris pe rand inainte de LostFocus) trebuie sa
|
||||
* se propage la toate liniile cu valoarea veche, nu doar schimbarile intre doua valori nenule.
|
||||
* Doar la nivel de cursoare (tact/trul) - nu se salveaza in Oracle.
|
||||
*=====================================================================================
|
||||
IF INLIST(tcMode, 'ALL', 'ZERO')
|
||||
LOCAL lnCodZ, lnAnZ, lnLunaZ, lnIdSetZ, lnNnirVechiZ
|
||||
LOCAL lnCntTactVechiZ, lnCntTrulVechiZ, lnCntTactRamasVechiZ, lnCntTrulRamasVechiZ
|
||||
LOCAL lnCntTactZeroZ, lnCntTrulZeroZ
|
||||
LOCAL iz, llGasitZ, lnColCheckZ, lcColNameZ
|
||||
|
||||
lnCodZ = 1140841
|
||||
lnAnZ = 2026
|
||||
lnLunaZ = 7
|
||||
lnIdSetZ = 209
|
||||
lnNnirVechiZ = 3
|
||||
|
||||
DO NnirConstruiesteCursoare WITH lnCodZ, lnAnZ, lnLunaZ
|
||||
|
||||
SELECT tact
|
||||
lnCntTactVechiZ = 0
|
||||
COUNT FOR NVL(nnir,0) = lnNnirVechiZ TO lnCntTactVechiZ
|
||||
SELECT trul
|
||||
lnCntTrulVechiZ = 0
|
||||
COUNT FOR NVL(nnir,0) = lnNnirVechiZ TO lnCntTrulVechiZ
|
||||
|
||||
Omodif = CREATEOBJECT('frm_modific2024', lnIdSetZ)
|
||||
IF VARTYPE(Omodif) <> 'O'
|
||||
DO NnirAssert WITH 'instantiere', 'ZERO', .F., 'frm_modific2024 nu s-a instantiat'
|
||||
ELSE
|
||||
SELECT tact
|
||||
Omodif.grid1.SetFocus
|
||||
Omodif.gridextra1.setup()
|
||||
Omodif.CalculeazaTotal()
|
||||
|
||||
llGasitZ = .F.
|
||||
lnColCheckZ = 0
|
||||
FOR iz = 1 TO Omodif.grid1.ColumnCount
|
||||
lcColNameZ = 'Omodif.grid1.Columns(' + TRANSFORM(iz) + ')'
|
||||
IF NnirEsteColoanaNnir(EVALUATE(lcColNameZ + '.ControlSource'))
|
||||
llGasitZ = .T.
|
||||
lnColCheckZ = iz
|
||||
ENDIF
|
||||
ENDFOR
|
||||
DO NnirAssert WITH 'coloana_grid', 'ZERO', llGasitZ, 'ControlSource=nnir gasit=' + TRANSFORM(llGasitZ)
|
||||
|
||||
IF llGasitZ
|
||||
SELECT tact
|
||||
LOCATE FOR NVL(nnir,0) = lnNnirVechiZ
|
||||
IF FOUND()
|
||||
lcCallWhen = 'Omodif.grid1.Columns(' + TRANSFORM(lnColCheckZ) + ').Text1.When'
|
||||
&lcCallWhen
|
||||
* simuleaza stergerea celulei: utilizatorul goleste campul, valoarea ajunge 0
|
||||
REPLACE nnir WITH 0
|
||||
lcCallLostFocus = 'Omodif.grid1.Columns(' + TRANSFORM(lnColCheckZ) + ').Text1.LostFocus'
|
||||
&lcCallLostFocus
|
||||
|
||||
SELECT tact
|
||||
lnCntTactRamasVechiZ = 0
|
||||
COUNT FOR NVL(nnir,0) = lnNnirVechiZ TO lnCntTactRamasVechiZ
|
||||
lnCntTactZeroZ = 0
|
||||
COUNT FOR NVL(nnir,0) = 0 TO lnCntTactZeroZ
|
||||
DO NnirAssert WITH 'sync_tact_zero', 'ZERO', lnCntTactRamasVechiZ = 0 AND lnCntTactZeroZ >= lnCntTactVechiZ, ;
|
||||
TRANSFORM(lnCntTactRamasVechiZ) + ' randuri tact au ramas pe valoarea veche (asteptat 0), ' + ;
|
||||
TRANSFORM(lnCntTactZeroZ) + ' au ajuns la 0 (asteptat cel putin ' + TRANSFORM(lnCntTactVechiZ) + ')'
|
||||
|
||||
* verificare explicita in cursorul legat de grid-ul de rulaje (pgfArticole.page1.grdRulaje)
|
||||
SELECT trul
|
||||
lnCntTrulRamasVechiZ = 0
|
||||
COUNT FOR NVL(nnir,0) = lnNnirVechiZ TO lnCntTrulRamasVechiZ
|
||||
lnCntTrulZeroZ = 0
|
||||
COUNT FOR NVL(nnir,0) = 0 TO lnCntTrulZeroZ
|
||||
DO NnirAssert WITH 'sync_trul_zero', 'ZERO', lnCntTrulRamasVechiZ = 0 AND lnCntTrulZeroZ >= lnCntTrulVechiZ, ;
|
||||
TRANSFORM(lnCntTrulRamasVechiZ) + ' randuri trul au ramas pe valoarea veche (asteptat 0), ' + ;
|
||||
TRANSFORM(lnCntTrulZeroZ) + ' au ajuns la 0 (asteptat cel putin ' + TRANSFORM(lnCntTrulVechiZ) + ')'
|
||||
ELSE
|
||||
DO NnirAssert WITH 'locate_rand_vechi', 'ZERO', .F., 'nu s-a gasit randul cu nnir vechi in tact'
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
Omodif.Release()
|
||||
Omodif = NULL
|
||||
ENDIF
|
||||
DO NnirCurataCursoare
|
||||
ENDIF
|
||||
|
||||
*=====================================================================================
|
||||
* Scenariul 6: nota de inventar (id_set=90101) pe sucursala CURENTA - blocarea NNIR trebuie sa
|
||||
* vina din regula 90101, nu din blocarea pe sucursala din AfterRowColChange. Scenariul 4 ruleaza
|
||||
* pe o nota din alta sucursala, unde SetAll("ReadOnly",.T.) blocheaza oricum tot gridul, deci ar
|
||||
* trece si fara implementare. Aici gnIdSucursala se aliniaza la id_sucursala notei (llReadOnly
|
||||
* iese .F.), se declanseaza AfterRowColChange (care face SetAll dupa Init) si se verifica ca
|
||||
* Column44 ramane blocata cat timp restul coloanelor sunt editabile.
|
||||
*=====================================================================================
|
||||
IF INLIST(tcMode, 'ALL', 'INVENTAR2')
|
||||
LOCAL lnCod6, lnAn6, lnLuna6, lnIdSet6
|
||||
LOCAL i6, llGasit6, llReadOnly6, lnEditabile6, lnSucVechi6, llMamaVechi6
|
||||
LOCAL lnIdSucNota6, lcColName6
|
||||
|
||||
lnCod6 = 1140716
|
||||
lnAn6 = 2026
|
||||
lnLuna6 = 3
|
||||
lnIdSet6 = 90101
|
||||
|
||||
DO NnirConstruiesteCursoare WITH lnCod6, lnAn6, lnLuna6
|
||||
|
||||
SELECT tact
|
||||
GO TOP
|
||||
lnIdSucNota6 = NVL(tact.id_sucursala, 0)
|
||||
lnSucVechi6 = gnIdSucursala
|
||||
llMamaVechi6 = glEMama
|
||||
gnIdSucursala = lnIdSucNota6
|
||||
glEMama = .F.
|
||||
|
||||
Omodif = CREATEOBJECT('frm_modific2024', lnIdSet6)
|
||||
IF VARTYPE(Omodif) <> 'O'
|
||||
DO NnirAssert WITH 'instantiere', 'INVENTAR2', .F., 'frm_modific2024 nu s-a instantiat'
|
||||
ELSE
|
||||
SELECT tact
|
||||
GO TOP
|
||||
Omodif.grid1.SetFocus
|
||||
Omodif.gridextra1.setup()
|
||||
Omodif.CalculeazaTotal()
|
||||
|
||||
* AfterRowColChange face SetAll("ReadOnly", llReadOnly) peste blocarea pusa in Init
|
||||
Omodif.grid1.AfterRowColChange(1)
|
||||
|
||||
llGasit6 = .F.
|
||||
llReadOnly6 = .F.
|
||||
lnEditabile6 = 0
|
||||
FOR i6 = 1 TO Omodif.grid1.ColumnCount
|
||||
lcColName6 = 'Omodif.grid1.Columns(' + TRANSFORM(i6) + ')'
|
||||
IF NnirEsteColoanaNnir(EVALUATE(lcColName6 + '.ControlSource'))
|
||||
llGasit6 = .T.
|
||||
llReadOnly6 = EVALUATE(lcColName6 + '.ReadOnly')
|
||||
ELSE
|
||||
IF !EVALUATE(lcColName6 + '.ReadOnly')
|
||||
lnEditabile6 = lnEditabile6 + 1
|
||||
ENDIF
|
||||
ENDIF
|
||||
ENDFOR
|
||||
|
||||
DO NnirAssert WITH 'coloana_grid', 'INVENTAR2', llGasit6, 'ControlSource=nnir gasit=' + TRANSFORM(llGasit6)
|
||||
* control: daca gridul e blocat integral, testul de blocare NNIR nu dovedeste nimic
|
||||
DO NnirAssert WITH 'grid_editabil', 'INVENTAR2', lnEditabile6 > 0, ;
|
||||
'coloane editabile (fara nnir): ' + TRANSFORM(lnEditabile6) + ' (asteptat > 0, ' + ;
|
||||
'gnIdSucursala=' + TRANSFORM(lnIdSucNota6) + ')'
|
||||
IF llGasit6
|
||||
DO NnirAssert WITH 'coloana_blocata', 'INVENTAR2', llReadOnly6, ;
|
||||
'id_set=90101 pe sucursala curenta: ReadOnly asteptat .T., gasit ' + TRANSFORM(llReadOnly6)
|
||||
ENDIF
|
||||
|
||||
Omodif.Release()
|
||||
Omodif = NULL
|
||||
ENDIF
|
||||
|
||||
gnIdSucursala = lnSucVechi6
|
||||
glEMama = llMamaVechi6
|
||||
DO NnirCurataCursoare
|
||||
ENDIF
|
||||
|
||||
DO NnirLog WITH 'REZULTAT SUITA: ' + TRANSFORM(gnPass) + ' PASS, ' + TRANSFORM(gnFail) + ' FAIL'
|
||||
QUIT
|
||||
|
||||
*=====================================================================================
|
||||
* proceduri ajutatoare (fara CREATEOBJECT - vezi depanare_testare_vfp.md / capcana l:
|
||||
* CREATEOBJECT apelat dintr-o procedura se comporta gresit in acest runtime headless)
|
||||
*=====================================================================================
|
||||
|
||||
PROCEDURE NnirLog
|
||||
LPARAMETERS tcMsg
|
||||
STRTOFILE(tcMsg + CHR(13)+CHR(10), gcLogFile, 1)
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE NnirAssert
|
||||
LPARAMETERS tcPas, tcCaz, llOk, tcDetaliu
|
||||
LOCAL lcRez
|
||||
lcRez = IIF(llOk, 'PASS', 'FAIL')
|
||||
IF llOk
|
||||
gnPass = gnPass + 1
|
||||
ELSE
|
||||
gnFail = gnFail + 1
|
||||
ENDIF
|
||||
DO NnirLog WITH lcRez + ' [' + tcCaz + '/' + tcPas + '] ' + tcDetaliu
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE NnirErr
|
||||
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
|
||||
DO NnirLog WITH 'ERR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
|
||||
ENDPROC
|
||||
|
||||
* verifica ca toate variabilele folosite ca ?param in SQL pass-through pe calea de test (env-init,
|
||||
* optiuni_firma, oscrie_in_fisiere, pack_contafin/pack_sesiune) sunt definite - o variabila
|
||||
* PUBLIC lipsa/umbrita da direct dialogul modal "Enter the value for <var>", nu o eroare catchabila
|
||||
FUNCTION NnirGardaVariabile
|
||||
LOCAL laVar(9), i, llOk
|
||||
laVar(1) = 'gnIdUtil'
|
||||
laVar(2) = 'gnAn'
|
||||
laVar(3) = 'gnLuna'
|
||||
laVar(4) = 'gnIdFirma'
|
||||
laVar(5) = 'gnIdSucursala'
|
||||
laVar(6) = 'gcS'
|
||||
laVar(7) = 'gnIdProgram'
|
||||
laVar(8) = 'gnId_Prg_Owner'
|
||||
laVar(9) = 'gnHandle'
|
||||
llOk = .T.
|
||||
FOR i = 1 TO ALEN(laVar)
|
||||
IF TYPE(laVar(i)) == 'U'
|
||||
DO NnirLog WITH 'FAIL [garda_variabile] ' + laVar(i) + ' nu exista (TYPE U) - ar fi dat dialog modal "Enter the value"'
|
||||
llOk = .F.
|
||||
ENDIF
|
||||
ENDFOR
|
||||
RETURN llOk
|
||||
ENDFUNC
|
||||
|
||||
* VFP calificat automat ControlSource-ul unui camp simplu cu aliasul cursorului (RecordSource) -
|
||||
* "nnir" definit in sursa apare la runtime ca "tact.nnir" - se accepta ambele forme
|
||||
FUNCTION NnirEsteColoanaNnir
|
||||
LPARAMETERS tcControlSource
|
||||
LOCAL lcCs
|
||||
lcCs = UPPER(ALLTRIM(TRANSFORM(tcControlSource)))
|
||||
RETURN lcCs == 'NNIR' OR RIGHT(lcCs, 5) == '.NNIR'
|
||||
ENDFUNC
|
||||
|
||||
* construieste tact/trul/trul_obinv exact ca afisjurcom.do_modifica (comun.vc2:2352-2434),
|
||||
* dar pe AN/LUNA proprii notei (nu gnAn/gnLuna) - vezi antetul fisierului
|
||||
PROCEDURE NnirConstruiesteCursoare
|
||||
LPARAMETERS tnCod, tnAn, tnLuna
|
||||
LOCAL lcSql, lnSucces
|
||||
|
||||
DO NnirCurataCursoare
|
||||
|
||||
lcSql = [select * from vact_tot where sters = 0 and an = ] + TRANSFORM(tnAn) + ;
|
||||
[ and luna = ] + TRANSFORM(tnLuna) + [ and cod = ] + TRANSFORM(tnCod) + [ order by id_act]
|
||||
lnSucces = goExecutor.oExecute(lcSql, 'v_act')
|
||||
goExecutor.oReset()
|
||||
IF lnSucces < 0
|
||||
DO NnirLog WITH 'EROARE construire tact: ' + goExecutor.cEroare
|
||||
RETURN .F.
|
||||
ENDIF
|
||||
SELECT * FROM v_act INTO CURSOR actactan
|
||||
SELECT .F. AS ales, T.*, CAST(0 AS N(2)) AS tipnota FROM actactan T INTO CURSOR tact READWRITE
|
||||
USE IN v_act
|
||||
|
||||
lcSql = [select * from vrul_tot where sters = 0 and an = ] + TRANSFORM(tnAn) + ;
|
||||
[ and luna = ] + TRANSFORM(tnLuna) + [ and cod = ] + TRANSFORM(tnCod) + [ order by id_rul]
|
||||
goExecutor.oExecute(lcSql, 'v_rul')
|
||||
goExecutor.oReset()
|
||||
SELECT *, valoare + valtva AS valoarectva, valoarev + valtvav AS valoarevctva ;
|
||||
FROM v_rul INTO CURSOR RUL_TEMP READWRITE
|
||||
SELECT * FROM RUL_TEMP INTO CURSOR trul READWRITE
|
||||
USE IN v_rul
|
||||
|
||||
lcSql = [select * from vrul_obinv_tot where sters = 0 and an = ] + TRANSFORM(tnAn) + ;
|
||||
[ and luna = ] + TRANSFORM(tnLuna) + [ and cod = ] + TRANSFORM(tnCod) + [ order by id_rul_obinv]
|
||||
goExecutor.oExecute(lcSql, 'v_rul_obinv')
|
||||
goExecutor.oReset()
|
||||
SELECT *, valoare + valtva AS valoarectva, valoarev + valtvav AS valoarevctva ;
|
||||
FROM v_rul_obinv INTO CURSOR RUL_TEMP_OBINV READWRITE
|
||||
SELECT * FROM RUL_TEMP_OBINV INTO CURSOR trul_obinv READWRITE
|
||||
USE IN v_rul_obinv
|
||||
|
||||
SELECT a.*, IIF(NVL(a.id_jtva_coloana,0)=0,0,1) AS cu_tva FROM tact a INTO CURSOR tact READWRITE
|
||||
SELECT tact
|
||||
GO TOP
|
||||
RETURN .T.
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE NnirCurataCursoare
|
||||
IF USED('tact')
|
||||
USE IN tact
|
||||
ENDIF
|
||||
IF USED('trul')
|
||||
USE IN trul
|
||||
ENDIF
|
||||
IF USED('trul_obinv')
|
||||
USE IN trul_obinv
|
||||
ENDIF
|
||||
IF USED('actactan')
|
||||
USE IN actactan
|
||||
ENDIF
|
||||
IF USED('rul_temp')
|
||||
USE IN rul_temp
|
||||
ENDIF
|
||||
IF USED('rul_temp_obinv')
|
||||
USE IN rul_temp_obinv
|
||||
ENDIF
|
||||
ENDPROC
|
||||
|
||||
FUNCTION NnirOraCount
|
||||
LPARAMETERS tcSql
|
||||
LOCAL lnVal, llOk
|
||||
lnVal = -1
|
||||
llOk = goExecutor.oExecuta(tcSql, 'cNnirOraCnt')
|
||||
IF llOk AND USED('cNnirOraCnt') AND RECCOUNT('cNnirOraCnt') > 0
|
||||
lnVal = cNnirOraCnt.cnt
|
||||
ENDIF
|
||||
IF USED('cNnirOraCnt')
|
||||
USE IN cNnirOraCnt
|
||||
ENDIF
|
||||
RETURN lnVal
|
||||
ENDFUNC
|
||||
|
||||
* verifica ca in Oracle nu s-a scris nimic dupa editarea DOAR in cursoare (echivalent Renunt)
|
||||
PROCEDURE NnirVerificaOracleNeschimbat
|
||||
LPARAMETERS tnCod, tnNnirVechi, tcCaz
|
||||
LOCAL lnCnt, lcSql
|
||||
lcSql = [select count(*) cnt from act where cod = ] + TRANSFORM(tnCod) + ;
|
||||
[ and nnir = ] + TRANSFORM(tnNnirVechi)
|
||||
lnCnt = NnirOraCount(lcSql)
|
||||
DO NnirAssert WITH 'renunt_neschimbat', tcCaz, lnCnt > 0, ;
|
||||
'ACT.NNIR in Oracle inainte de Termin ramane ' + TRANSFORM(tnNnirVechi) + ' (' + TRANSFORM(lnCnt) + ' randuri)'
|
||||
ENDPROC
|
||||
|
||||
* replica blocul de salvare din afisjurcom.do_modifica (comun.vc2:2456-2487): scrie tact/trul/
|
||||
* trul_obinv in ACT/RUL/RUL_OBINV prin oscrie_in_fisiere + pack_contafin.finalizeaza_modificare_
|
||||
* nota, verifica in Oracle, apoi reface valoarea originala (revert - baza de test ramane
|
||||
* neschimbata pentru rulari repetate)
|
||||
PROCEDURE NnirSalveazaSiVerifica
|
||||
LPARAMETERS tnCod, tnAn, tnLuna, tnIdSet, tnNnirVechi, tnNnirNou, tcCaz
|
||||
PRIVATE pnAn, pnLuna, pdDataOra
|
||||
LOCAL lnIdFact, lnIdfactd, llRul, lnSuccesSalvare, lcSqlFin, lnCnt, lcSql
|
||||
|
||||
pnAn = tnAn
|
||||
pnLuna = tnLuna
|
||||
pdDataOra = NULL
|
||||
|
||||
SELECT tact
|
||||
LOCATE FOR NVL(nnir,0) = tnNnirNou
|
||||
lnIdFact = NVL(id_fact, 0)
|
||||
lnIdfactd = NVL(id_factd, 0)
|
||||
|
||||
llRul = (RECCOUNT('trul') > 0) OR (RECCOUNT('trul_obinv') > 0)
|
||||
|
||||
* thisform.do_deschide_tranzactie()/do_inchide_tranzactie() din afisjurcom (_frm_base.vc2:252-
|
||||
* 305, mostenite, apelate pe formularul de jurnal, nu pe frm_modific2024) - echivalent direct,
|
||||
* fara instanta de forma: manual pe durata scrierii, apoi commit/rollback + revenire pe auto
|
||||
SQLSetProp(gnHandle, 'Transactions', 2)
|
||||
|
||||
* replica exact secventa din afisjurcom.do_modifica: intai STERGE nota veche (COD-ul
|
||||
* original, din actactan neatins de editare), abia apoi SCRIE varianta editata
|
||||
SELECT actactan
|
||||
lnSuccesSalvare = oscrie_in_fisiere(2, .T., llRul)
|
||||
DO NnirAssert WITH 'oscrie_in_fisiere_sterge', tcCaz, lnSuccesSalvare > 0, 'a returnat ' + TRANSFORM(lnSuccesSalvare)
|
||||
|
||||
IF lnSuccesSalvare > 0
|
||||
SELECT * FROM tact INTO CURSOR actactan READWRITE
|
||||
REPLACE ALL id_util WITH gnIdUtil, sters WITH 0 IN actactan
|
||||
|
||||
IF llRul
|
||||
SELECT * FROM trul INTO CURSOR rul_temp READWRITE
|
||||
REPLACE ALL id_util WITH gnIdUtil, sters WITH 0 IN rul_temp
|
||||
SELECT * FROM trul_obinv INTO CURSOR rul_temp_obinv READWRITE
|
||||
REPLACE ALL id_util WITH gnIdUtil, sters WITH 0 IN rul_temp_obinv
|
||||
ENDIF
|
||||
|
||||
lnSuccesSalvare = oscrie_in_fisiere(0, .T., llRul)
|
||||
DO NnirAssert WITH 'oscrie_in_fisiere', tcCaz, lnSuccesSalvare > 0, 'a returnat ' + TRANSFORM(lnSuccesSalvare)
|
||||
ENDIF
|
||||
|
||||
IF lnSuccesSalvare > 0
|
||||
lcSqlFin = [begin pack_contafin.finalizeaza_modificare_nota(?pnLuna,?pnAn,?pdDataOra,] + ;
|
||||
TRANSFORM(tnIdSet) + [,] + TRANSFORM(tnCod) + [,] + TRANSFORM(lnIdFact) + [,] + ;
|
||||
TRANSFORM(lnIdfactd) + [,?gnIdUtil); end;]
|
||||
lnSuccesSalvare = IIF(goExecutor.oExecuta(lcSqlFin), 1, -1)
|
||||
DO NnirAssert WITH 'finalizeaza_modificare_nota', tcCaz, lnSuccesSalvare > 0, 'a returnat ' + TRANSFORM(lnSuccesSalvare)
|
||||
ENDIF
|
||||
|
||||
IF lnSuccesSalvare > 0
|
||||
SQLCOMMIT(gnHandle)
|
||||
ELSE
|
||||
SQLROLLBACK(gnHandle)
|
||||
ENDIF
|
||||
SQLSetProp(gnHandle, 'Transactions', 1)
|
||||
|
||||
* Termin reatribuie COD nou (pack_contafin), sub AN/LUNA de sesiune curente - nu pastreaza
|
||||
* COD-ul original notei editate. Verificarea si curatenia se fac dupa valoarea NNIR marcaj
|
||||
* (distincta, nu poate coincide cu date reale), nu dupa COD-ul original.
|
||||
lcSql = [select count(*) cnt from act where sters = 0 and nnir = ] + TRANSFORM(tnNnirNou)
|
||||
lnCnt = NnirOraCount(lcSql)
|
||||
DO NnirAssert WITH 'oracle_act_final', tcCaz, lnCnt > 0, TRANSFORM(lnCnt) + ' randuri ACT cu nnir nou in Oracle'
|
||||
|
||||
IF RECCOUNT('trul') > 0
|
||||
lcSql = [select count(*) cnt from rul where sters = 0 and nnir = ] + TRANSFORM(tnNnirNou)
|
||||
lnCnt = NnirOraCount(lcSql)
|
||||
DO NnirAssert WITH 'oracle_rul_final', tcCaz, lnCnt > 0, TRANSFORM(lnCnt) + ' randuri RUL cu nnir nou in Oracle'
|
||||
ENDIF
|
||||
|
||||
* curatenie: pasul STERGE (oscrie_in_fisiere param 2) marcheaza sters=1 pe COD-ul ORIGINAL -
|
||||
* readuc nota originala activa, apoi marchez sters=1 (conventia aplicatiei) pe orice a ajuns
|
||||
* sub NNIR-ul marcaj (COD nou, atribuit de pack_contafin la scriere)
|
||||
goExecutor.oExecuta([update act set sters = 0 where cod = ] + TRANSFORM(tnCod))
|
||||
goExecutor.oExecuta([update rul set sters = 0 where cod = ] + TRANSFORM(tnCod))
|
||||
goExecutor.oExecuta([update rul_obinv set sters = 0 where cod = ] + TRANSFORM(tnCod))
|
||||
goExecutor.oExecuta([update act set sters = 1 where nnir = ] + TRANSFORM(tnNnirNou) + [ and cod <> ] + TRANSFORM(tnCod))
|
||||
goExecutor.oExecuta([update rul set sters = 1 where nnir = ] + TRANSFORM(tnNnirNou) + [ and cod <> ] + TRANSFORM(tnCod))
|
||||
goExecutor.oExecuta([update rul_obinv set sters = 1 where nnir = ] + TRANSFORM(tnNnirNou) + [ and cod <> ] + TRANSFORM(tnCod))
|
||||
goExecutor.oExecuta('commit')
|
||||
ENDPROC
|
||||
|
||||
* varianta pt. scenariul RUL_OBINV (verifica RUL_OBINV in loc de RUL)
|
||||
PROCEDURE NnirSalveazaSiVerificaObinv
|
||||
LPARAMETERS tnCod, tnAn, tnLuna, tnIdSet, tnNnirVechi, tnNnirNou
|
||||
PRIVATE pnAn, pnLuna, pdDataOra
|
||||
LOCAL lnIdFact, lnIdfactd, llRul, lnSuccesSalvare, lcSqlFin, lnCnt, lcSql
|
||||
|
||||
pnAn = tnAn
|
||||
pnLuna = tnLuna
|
||||
pdDataOra = NULL
|
||||
|
||||
SELECT tact
|
||||
LOCATE FOR NVL(nnir,0) = tnNnirNou
|
||||
lnIdFact = NVL(id_fact, 0)
|
||||
lnIdfactd = NVL(id_factd, 0)
|
||||
|
||||
llRul = (RECCOUNT('trul') > 0) OR (RECCOUNT('trul_obinv') > 0)
|
||||
|
||||
* thisform.do_deschide_tranzactie()/do_inchide_tranzactie() din afisjurcom (_frm_base.vc2:252-
|
||||
* 305, mostenite, apelate pe formularul de jurnal, nu pe frm_modific2024) - echivalent direct,
|
||||
* fara instanta de forma: manual pe durata scrierii, apoi commit/rollback + revenire pe auto
|
||||
SQLSetProp(gnHandle, 'Transactions', 2)
|
||||
|
||||
* replica exact secventa din afisjurcom.do_modifica: intai STERGE nota veche (COD-ul
|
||||
* original, din actactan neatins de editare), abia apoi SCRIE varianta editata
|
||||
SELECT actactan
|
||||
lnSuccesSalvare = oscrie_in_fisiere(2, .T., llRul)
|
||||
DO NnirAssert WITH 'oscrie_in_fisiere_sterge', 'OBINV', lnSuccesSalvare > 0, 'a returnat ' + TRANSFORM(lnSuccesSalvare)
|
||||
|
||||
IF lnSuccesSalvare > 0
|
||||
SELECT * FROM tact INTO CURSOR actactan READWRITE
|
||||
REPLACE ALL id_util WITH gnIdUtil, sters WITH 0 IN actactan
|
||||
|
||||
IF llRul
|
||||
SELECT * FROM trul INTO CURSOR rul_temp READWRITE
|
||||
REPLACE ALL id_util WITH gnIdUtil, sters WITH 0 IN rul_temp
|
||||
SELECT * FROM trul_obinv INTO CURSOR rul_temp_obinv READWRITE
|
||||
REPLACE ALL id_util WITH gnIdUtil, sters WITH 0 IN rul_temp_obinv
|
||||
ENDIF
|
||||
|
||||
lnSuccesSalvare = oscrie_in_fisiere(0, .T., llRul)
|
||||
DO NnirAssert WITH 'oscrie_in_fisiere', 'OBINV', lnSuccesSalvare > 0, 'a returnat ' + TRANSFORM(lnSuccesSalvare)
|
||||
ENDIF
|
||||
|
||||
IF lnSuccesSalvare > 0
|
||||
lcSqlFin = [begin pack_contafin.finalizeaza_modificare_nota(?pnLuna,?pnAn,?pdDataOra,] + ;
|
||||
TRANSFORM(tnIdSet) + [,] + TRANSFORM(tnCod) + [,] + TRANSFORM(lnIdFact) + [,] + ;
|
||||
TRANSFORM(lnIdfactd) + [,?gnIdUtil); end;]
|
||||
lnSuccesSalvare = IIF(goExecutor.oExecuta(lcSqlFin), 1, -1)
|
||||
DO NnirAssert WITH 'finalizeaza_modificare_nota', 'OBINV', lnSuccesSalvare > 0, 'a returnat ' + TRANSFORM(lnSuccesSalvare)
|
||||
ENDIF
|
||||
|
||||
IF lnSuccesSalvare > 0
|
||||
SQLCOMMIT(gnHandle)
|
||||
ELSE
|
||||
SQLROLLBACK(gnHandle)
|
||||
ENDIF
|
||||
SQLSetProp(gnHandle, 'Transactions', 1)
|
||||
|
||||
* Termin reatribuie COD nou (pack_contafin), sub AN/LUNA de sesiune curente - nu pastreaza
|
||||
* COD-ul original notei editate. Verificarea si curatenia se fac dupa valoarea NNIR marcaj
|
||||
* (distincta, nu poate coincide cu date reale), nu dupa COD-ul original.
|
||||
lcSql = [select count(*) cnt from act where sters = 0 and nnir = ] + TRANSFORM(tnNnirNou)
|
||||
lnCnt = NnirOraCount(lcSql)
|
||||
DO NnirAssert WITH 'oracle_act_final', 'OBINV', lnCnt > 0, TRANSFORM(lnCnt) + ' randuri ACT cu nnir nou in Oracle'
|
||||
|
||||
lcSql = [select count(*) cnt from rul_obinv where sters = 0 and nnir = ] + TRANSFORM(tnNnirNou)
|
||||
lnCnt = NnirOraCount(lcSql)
|
||||
DO NnirAssert WITH 'oracle_rul_obinv_final', 'OBINV', lnCnt > 0, TRANSFORM(lnCnt) + ' randuri RUL_OBINV cu nnir nou in Oracle'
|
||||
|
||||
* curatenie: pasul STERGE (oscrie_in_fisiere param 2) marcheaza sters=1 pe COD-ul ORIGINAL -
|
||||
* readuc nota originala activa, apoi marchez sters=1 (conventia aplicatiei) pe orice a ajuns
|
||||
* sub NNIR-ul marcaj (COD nou, atribuit de pack_contafin la scriere)
|
||||
goExecutor.oExecuta([update act set sters = 0 where cod = ] + TRANSFORM(tnCod))
|
||||
goExecutor.oExecuta([update rul set sters = 0 where cod = ] + TRANSFORM(tnCod))
|
||||
goExecutor.oExecuta([update rul_obinv set sters = 0 where cod = ] + TRANSFORM(tnCod))
|
||||
goExecutor.oExecuta([update act set sters = 1 where nnir = ] + TRANSFORM(tnNnirNou) + [ and cod <> ] + TRANSFORM(tnCod))
|
||||
goExecutor.oExecuta([update rul set sters = 1 where nnir = ] + TRANSFORM(tnNnirNou) + [ and cod <> ] + TRANSFORM(tnCod))
|
||||
goExecutor.oExecuta([update rul_obinv set sters = 1 where nnir = ] + TRANSFORM(tnNnirNou) + [ and cod <> ] + TRANSFORM(tnCod))
|
||||
goExecutor.oExecuta('commit')
|
||||
ENDPROC
|
||||
11
utile/Teste/nnir_registru_jurnal/verif_nnir_cod.sql
Normal file
11
utile/Teste/nnir_registru_jurnal/verif_nnir_cod.sql
Normal file
@@ -0,0 +1,11 @@
|
||||
-- verif_nnir_cod.sql - NNIR distinct pe ACT/RUL/RUL_OBINV pentru un COD dat
|
||||
-- Rulare: sqlplus -L -S MARIUSM_AUTO/<parola>@ROA_CENTRAL @verif_nnir_cod.sql <cod>
|
||||
set pagesize 200 linesize 200 trimspool on feedback off
|
||||
define v_cod = &1
|
||||
prompt ==ACT==
|
||||
select cod, an, luna, id_set, nnir from act where cod = &v_cod;
|
||||
prompt ==RUL_NNIR_DISTINCT==
|
||||
select an, luna, nnir, count(*) cnt from rul where cod = &v_cod group by an, luna, nnir;
|
||||
prompt ==RUL_OBINV_NNIR_DISTINCT==
|
||||
select an, luna, nnir, count(*) cnt from rul_obinv where cod = &v_cod group by an, luna, nnir;
|
||||
exit;
|
||||
302
utile/Teste/test_init_env_auto_roagest.prg
Normal file
302
utile/Teste/test_init_env_auto_roagest.prg
Normal file
@@ -0,0 +1,302 @@
|
||||
* test_init_env_auto_roagest.prg
|
||||
* Varianta ROAGEST a test_init_env_auto.prg (acel fisier e specializat pe ROACONT -
|
||||
* gcAppPath/clase/proceduri hardcodate D:\ROA\ROACONT\ - nu poate initializa mediul ROAGEST).
|
||||
* Initializare completa de mediu FARA interactiune, pentru vfp9.exe -A -T.
|
||||
*
|
||||
* Utilizare:
|
||||
* DO test_init_env_auto_roagest WITH 'CENTRAL', 'MARIUSM_AUTO', 'parola'
|
||||
* IF gnHandle <= 0 ... eroare conectare
|
||||
*
|
||||
* Dupa apel sunt disponibile: goConn/goExecutor/goApp/goLog/goApi, goFirma/goCalendar,
|
||||
* gnAn/gnLuna/gcS/gnIdFirma etc., SET PATH/CLASSLIB/PROCEDURE ca in roagest.prg,
|
||||
* pachetele Oracle de sesiune setate (pack_sesiune/pack_contafin).
|
||||
* ATENTIE: mentine lista de SET CLASSLIB/PROCEDURE sincronizata cu Programe\roagest.prg.
|
||||
|
||||
LPARAMETERS tcHost, tcSchema, tcPassword, tnAn, tnLuna
|
||||
|
||||
tcHost = IIF(EMPTY(tcHost), 'CENTRAL', tcHost)
|
||||
tcSchema = IIF(EMPTY(tcSchema), 'MARIUSM_AUTO', tcSchema)
|
||||
tcPassword = IIF(EMPTY(tcPassword), 'ROMFASTSOFT', tcPassword)
|
||||
|
||||
SET DELETED ON
|
||||
SET ANSI ON
|
||||
SET EXACT ON
|
||||
SET SAFETY OFF
|
||||
CLOSE DATABASES
|
||||
SET CENTURY ON
|
||||
SET DATE DMY
|
||||
SET NULLDISPLAY TO ''
|
||||
SET DECIMALS TO 4
|
||||
SET POINT TO '.'
|
||||
|
||||
PUBLIC CT_SUCCES, CT_INSUCCES, crlf, gnAn, gnLuna, gnIdUtil, glEMama, gnIdFirma, gcCondSucursala, ;
|
||||
gnIdSucursala, gcS, gcFirma, gcUserName, gcUserNameApp, gcNumeProgram, gcAppName, glLunaInchisa, ;
|
||||
buton, gnButon, pnButon, gl406, gcAcces, gnIdProgram, gnId_Prg_Owner
|
||||
CT_SUCCES = 1
|
||||
CT_INSUCCES = -1
|
||||
crlf = CHR(13) + CHR(10)
|
||||
gnAn = IIF(EMPTY(tnAn), YEAR(DATE()), tnAn)
|
||||
gnLuna = IIF(EMPTY(tnLuna), MONTH(DATE()), tnLuna)
|
||||
gnIdUtil = -3
|
||||
gnIdProgram = 0
|
||||
gnId_Prg_Owner = 0
|
||||
gnIdFirma = 110
|
||||
gcCondSucursala = []
|
||||
gnIdSucursala = m.gnIdFirma
|
||||
gcS = UPPER(ALLTRIM(tcSchema))
|
||||
gcFirma = m.gcS
|
||||
gcUserName = m.gcS
|
||||
gcUserNameApp = [MARIUS M]
|
||||
gcNumeProgram = [ROAGEST]
|
||||
gcAppName = [ROAGEST]
|
||||
glLunaInchisa = .F.
|
||||
glEMama = .F.
|
||||
gl406 = .F.
|
||||
* PUBLIC, nu Declare: nrcrt() (oproceduri_comune.prg) citeste NROR din ControlSource-uri
|
||||
* de grid mult dupa ce acest program s-a terminat (Declare ar muri la RETURN)
|
||||
PUBLIC nror(65000)
|
||||
buton = 1
|
||||
gnButon = 1
|
||||
pnButon = 1
|
||||
|
||||
LOCAL lcPath
|
||||
PUBLIC gcAppPath, DIRGEN, gcDirMare, gcBasePath, gcTempPath, gcGeneralIniFile, gcSettingsFile, ;
|
||||
gcSecurityPath, gcSecurityFile
|
||||
gcAppPath = [D:\ROA\ROAGEST\]
|
||||
Set Default To (gcAppPath)
|
||||
lcPath = gcAppPath + 'Date;' + ;
|
||||
gcAppPath + 'Include;' + ;
|
||||
gcAppPath + 'FERESTRE;' + ;
|
||||
gcAppPath + 'GRAFICE;' + ;
|
||||
gcAppPath + 'CLASE;' + ;
|
||||
gcAppPath + 'MENIURI;' + ;
|
||||
gcAppPath + 'PROGRAME;' + ;
|
||||
gcAppPath + 'RAPOARTE;' + ;
|
||||
gcAppPath + 'COMUN;' + ;
|
||||
gcAppPath + 'COMUN\CLASE;' + ;
|
||||
gcAppPath + 'COMUN\FERESTRE;' + ;
|
||||
gcAppPath + 'COMUN\PROGRAME;' + ;
|
||||
gcAppPath + 'COMUN\GRAFICE;' + ;
|
||||
gcAppPath + 'COMUN\RAPOARTE;' + ;
|
||||
gcAppPath + 'COMUN\MENIURI;' + ;
|
||||
gcAppPath + 'COMUN\UTILE\GRIDEXTRAS;' + ;
|
||||
gcAppPath + 'COMUN\UTILE\CTL32;' + ;
|
||||
gcAppPath + 'COMUN\UTILE\HPDF;' + ;
|
||||
gcAppPath + 'COMUN\UTILE\HPDF\REPORTOUTPUT;' + ;
|
||||
gcAppPath + 'COMUN\UTILE\WEB;' + ;
|
||||
gcAppPath + 'COMUN\UTILE\EXCEL;' + ;
|
||||
gcAppPath + 'COMUN\UTILE\NFJSON;' + ;
|
||||
Addbs(Substr(gcAppPath,1,Rat([\],gcAppPath,2)))+[COMUNROA\]
|
||||
SET PATH TO &lcPath ADDITIVE
|
||||
|
||||
Local lcMainClassLib
|
||||
lcMainClassLib = gcAppPath + "comun\clase\appwiz"
|
||||
SET CLASSLIB TO (lcMainClassLib) ADDITIVE
|
||||
SET CLASSLIB TO GESTIUNI ADDITIVE
|
||||
SET CLASSLIB TO CAUT ADDITIVE
|
||||
SET CLASSLIB TO BAZA ADDITIVE
|
||||
SET CLASSLIB TO comun ADDITIVE
|
||||
SET CLASSLIB TO accessibility.vcx ADDITIVE
|
||||
SET CLASSLIB TO messagebox ADDITIVE
|
||||
SET CLASSLIB TO registry ADDITIVE
|
||||
SET CLASSLIB TO cauta_alfa_forms.vcx ADDITIVE
|
||||
SET CLASSLIB TO DECABAZA ADDITIVE
|
||||
SET CLASSLIB TO onomenclatoare ADDITIVE
|
||||
SET CLASSLIB TO stocuri.vcx ADDITIVE
|
||||
SET CLASSLIB TO rulaje.vcx ADDITIVE
|
||||
SET CLASSLIB TO ointroduceri ADDITIVE
|
||||
SET CLASSLIB TO ointroduceri_web ADDITIVE
|
||||
SET CLASSLIB TO ointroduceri_depozit ADDITIVE
|
||||
SET CLASSLIB TO overificari ADDITIVE
|
||||
SET CLASSLIB TO ferestre_oracle ADDITIVE
|
||||
SET CLASSLIB TO ferestre_cere_date.vcx ADDITIVE
|
||||
SET CLASSLIB TO configurare.vcx ADDITIVE
|
||||
SET CLASSLIB TO serii_numere.vcx ADDITIVE
|
||||
SET CLASSLIB TO omodificari.vcx ADDITIVE
|
||||
SET CLASSLIB TO ocompensari.vcx ADDITIVE
|
||||
SET CLASSLIB TO caut_ora ADDITIVE
|
||||
SET CLASSLIB TO onote_contabile ADDITIVE
|
||||
SET CLASSLIB TO otoolbar ADDITIVE
|
||||
SET CLASSLIB TO bon_fisc ADDITIVE
|
||||
SET CLASSLIB TO onom_articole ADDITIVE
|
||||
SET CLASSLIB TO onom_retete ADDITIVE
|
||||
Set Classlib To oinventar ADDITIVE
|
||||
SET CLASSLIB TO orapoarte ADDITIVE
|
||||
SET CLASSLIB TO orapoarte_gestiuni ADDITIVE
|
||||
SET CLASSLIB TO orapoarte_parametri ADDITIVE
|
||||
SET CLASSLIB TO ONOM_CURS ADDITIVE
|
||||
SET CLASSLIB TO ctl32_statusbar_fals.vcx additive
|
||||
SET CLASSLIB TO ctl32_common.vcx additive
|
||||
SET CLASSLIB TO ctl32_structs.vcx additive
|
||||
SET CLASSLIB TO ctl32_progressbar.vcx additive
|
||||
SET CLASSLIB TO ctl32_balloontip.vcx additive
|
||||
SET CLASSLIB TO ocriterii.vcx ADDITIVE
|
||||
SET CLASSLIB TO oavize.vcx ADDITIVE
|
||||
SET CLASSLIB TO onomenclatoare2 ADDITIVE
|
||||
Set Classlib To oschimbare_pret.vcx additive
|
||||
SET CLASSLIB TO wwdialogs.vcx additive
|
||||
SET CLASSLIB TO oimportxml.vcx additive
|
||||
SET CLASSLIB TO excelxml.vcx ADDITIVE
|
||||
SET CLASSLIB TO orapoarte_obinv.vcx ADDITIVE
|
||||
SET CLASSLIB TO locale ADDITIVE
|
||||
|
||||
SET PROCEDURE TO PROCEDURI ADDITIVE
|
||||
SET PROCEDURE TO acces_meniu ADDITIVE
|
||||
SET PROCEDURE TO cauta_alfa ADDITIVE
|
||||
SET PROCEDURE TO pmenu ADDITIVE
|
||||
SET PROCEDURE TO proceduri_comune ADDITIVE
|
||||
SET PROCEDURE TO quitapp ADDITIVE
|
||||
SET PROCEDURE TO init_program ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_listari.prg ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_configurare.prg ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_articole.prg ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_retete.prg ADDITIVE
|
||||
SET PROCEDURE TO orapoarte.prg ADDITIVE
|
||||
SET PROCEDURE TO mesaje ADDITIVE
|
||||
SET PROCEDURE TO oserii_numere.prg ADDITIVE
|
||||
SET PROCEDURE TO oexport.prg ADDITIVE
|
||||
SET PROCEDURE TO wwConfig.prg ADDITIVE
|
||||
SET PROCEDURE TO proceduri_rapoarte.prg additive
|
||||
SET PROCEDURE TO OPROCEDURI_CURS.PRG ADDITIVE
|
||||
Set procedure to orapoarte_dinamice.prg additive
|
||||
SET PROCEDURE TO validare.prg additive
|
||||
SET PROCEDURE TO GENCURSOR.PRG ADDITIVE
|
||||
SET PROCEDURE TO OPROCEDURI_COMUNE.PRG ADDITIVE
|
||||
SET PROCEDURE TO OINIT_OPTIUNI.PRG ADDITIVE
|
||||
SET PROCEDURE TO updateserver.prg ADDITIVE
|
||||
SET PROCEDURE TO oinainte_de.prg ADDITIVE
|
||||
SET PROCEDURE TO ooperatii_comune.prg ADDITIVE
|
||||
SET PROCEDURE TO Ocompensari.PRG ADDITIVE
|
||||
SET PROCEDURE TO OPROCEDURI_aMS.PRG ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_rulaje additive
|
||||
SET PROCEDURE TO oproceduri_stocuri additive
|
||||
SET PROCEDURE TO OINTRODUCERI ADDITIVE
|
||||
SET PROCEDURE TO oHeader.prg ADDITIVE
|
||||
SET PROCEDURE TO proceduri_excel.PRG ADDITIVE
|
||||
SET PROCEDURE TO onomenclatoare.PRG ADDITIVE
|
||||
SET PROCEDURE TO osecurity ADDITIVE
|
||||
SET PROCEDURE TO ocautare ADDITIVE
|
||||
SET PROCEDURE TO orefaceri ADDITIVE
|
||||
SET PROCEDURE TO ofacturare_comun.PRG ADDITIVE
|
||||
SET PROCEDURE TO ofacturare_stoc.PRG ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_casademarcat ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_casa_marcat_e500 ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_casa_marcat_mp500 ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_util.prg ADDITIVE
|
||||
SET PROCEDURE TO wwxmlhttp.prg ADDITIVE
|
||||
SET PROCEDURE TO ini.prg ADDITIVE
|
||||
SET PROCEDURE TO odocumente.prg ADDITIVE
|
||||
SET PROCEDURE TO regex.prg ADDITIVE
|
||||
SET PROCEDURE TO wwutils.prg ADDITIVE
|
||||
SET PROCEDURE TO inchidere_k ADDITIVE
|
||||
Set procedure to oschimbare_pret.prg additive
|
||||
SET PROCEDURE TO iniacces.prg ADDITIVE
|
||||
SET PROCEDURE TO oupdate.prg additive
|
||||
SET PROCEDURE TO procese.prg additive
|
||||
SET PROCEDURE TO version.prg additive
|
||||
SET PROCEDURE TO xmlaccess.prg additive
|
||||
SET PROCEDURE TO xmlparser.prg additive
|
||||
SET PROCEDURE TO filebringer.prg additive
|
||||
SET PROCEDURE TO wwcodeupdate.prg additive
|
||||
SET PROCEDURE TO wwhttp.prg ADDITIVE
|
||||
Set Procedure To wwApi.prg Additive
|
||||
SET PROCEDURE TO xdate.prg Additive
|
||||
SET PROCEDURE TO ofacturare.prg ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_obinv.prg ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_facturare.prg ADDITIVE
|
||||
SET PROCEDURE TO email.prg ADDITIVE
|
||||
|
||||
Declare Integer GetPrivateProfileString In WIN32API ;
|
||||
string, String, String, String @, Integer, String
|
||||
Declare Integer WritePrivateProfileString In Win32Api ;
|
||||
string, String, String, String
|
||||
Declare Integer CopyFile In WIN32API ;
|
||||
STRING lpExistingFileName, STRING lpNewFileName, INTEGER bFailIfExists
|
||||
Declare Integer PathFileExists In shlwapi STRING pszPath
|
||||
|
||||
If Type('goApi') = 'U'
|
||||
Public goApi
|
||||
goApi = Newobject("wwAPI", "wwAPI.prg")
|
||||
ENDIF
|
||||
|
||||
PUBLIC gnHandle, goExecutor, goConn, goFirma, goCalendar, poLog, goLog, goApp
|
||||
DIRGEN = [D:\ROA\]
|
||||
gcDirMare = DIRGEN
|
||||
gcBasePath = dirgen
|
||||
gcSecurityPath = DIRGEN + 'Security\'
|
||||
gcSecurityFile = gcSecurityPath + 'ROA_SECURITY.TXT'
|
||||
gcGeneralIniFile = DIRGEN + "settings.ini"
|
||||
gcSettingsFile = m.gcGeneralIniFile
|
||||
gcTempPath = Addbs(shortpath(goApi.GetTempPath())) + gcS + [\]
|
||||
If !Directory(gcTempPath)
|
||||
Md (gcTempPath)
|
||||
Endif
|
||||
gcAcces = [1;2;3;4;5;6;7;8;]
|
||||
|
||||
poLog = Newobject("Log_Mesaje","Log_Mesaje.prg")
|
||||
goLog = poLog
|
||||
goApp = Createobject("wzApplication")
|
||||
gnHandle = 0
|
||||
goExecutor = createobject("oExecutor")
|
||||
goConn = createobject("oConn")
|
||||
goConn.Connect(m.tcHost, m.tcSchema, m.tcPassword)
|
||||
IF m.gnHandle <= 0
|
||||
RETURN .F.
|
||||
ENDIF
|
||||
|
||||
LOCAL llSucces, lcSql
|
||||
goFirma = null
|
||||
llSucces = goExecutor.oExecuta("select * from syn_v_nom_firme where schema = ?gcS", "cFirma")
|
||||
IF m.llSucces
|
||||
SELECT cFirma
|
||||
gnIdFirma = id_firma
|
||||
gnIdSucursala = null
|
||||
gcFirma = ALLTRIM(firma)
|
||||
SCATTER NAME goFirma
|
||||
IF TYPE('goFirma.codfiscalfro') = 'U'
|
||||
ADDPROPERTY(goFirma, 'codfiscalfro', ALLTRIM(STRTRAN(ALLTRIM(NVL(goFirma.cod_fiscal, '')), 'RO', '')))
|
||||
ENDIF
|
||||
ELSE
|
||||
goFirma = CREATEOBJECT('custom')
|
||||
goFirma.addproperty('cod_fiscal', '')
|
||||
goFirma.addproperty('schema', m.gcS)
|
||||
goFirma.addproperty('firma', m.gcS)
|
||||
goFirma.addproperty('codfiscalfro', '')
|
||||
ENDIF
|
||||
USE IN (SELECT('cFirma'))
|
||||
|
||||
goCalendar = null
|
||||
llSucces = goExecutor.oExecuta('SELECT anul, luna, tva_incasare FROM calendar WHERE an*12+luna = (select MAX(an*12+luna) FROM calendar)', 'cCalendar')
|
||||
IF m.llSucces
|
||||
SELECT cCalendar
|
||||
GO TOP
|
||||
IF EMPTY(m.tnAn)
|
||||
gnAn = anul
|
||||
gnLuna = luna
|
||||
ENDIF
|
||||
SCATTER NAME goCalendar
|
||||
ENDIF
|
||||
USE IN (SELECT('cCalendar'))
|
||||
|
||||
CREATE CURSOR dual (dummy c(10))
|
||||
INSERT INTO dual (dummy) VALUES ("")
|
||||
|
||||
actualizeaza_optiuni()
|
||||
Do optiuni_firma IN oinit_optiuni.prg
|
||||
|
||||
lcSql = [begin pack_sesiune.set_Id_Util(?gnIdUtil); end;]
|
||||
llSucces = goExecutor.oExecuta(lcSql)
|
||||
lcSql = [begin pack_sesiune.setluna(?gnLuna); pack_sesiune.setan(?gnAn); end;]
|
||||
llSucces = goExecutor.oExecuta(lcSql)
|
||||
lcSql = [begin pack_sesiune.setlunabal(?gnLuna); pack_sesiune.setanbal(?gnAn); end;]
|
||||
llSucces = goExecutor.oExecuta(lcSql)
|
||||
lcSql = [begin pack_contafin.SET_DATA_RON(?gcS); end;]
|
||||
llSucces = goExecutor.oExecuta(lcSql)
|
||||
lcSql = [begin pack_sesiune.set_data_ron(?gcS); end;]
|
||||
llSucces = goExecutor.oExecuta(lcSql)
|
||||
lcSql = [begin pack_contafin.set_id_sucursala(?gnIdSucursala); end;]
|
||||
llSucces = goExecutor.oExecuta(lcSql)
|
||||
lcSql = [begin pack_contafin.set_id_firma(?gnIdFirma); end;]
|
||||
llSucces = goExecutor.oExecuta(lcSql)
|
||||
|
||||
RETURN .T.
|
||||
103
utile/citeste_email.ps1
Normal file
103
utile/citeste_email.ps1
Normal file
@@ -0,0 +1,103 @@
|
||||
# Citeste emailurile din mbox-urile Thunderbird Portable (fara conectorul Gmail).
|
||||
# citeste_email.ps1 [-Cauta <text>] [-Cont <nume>] [-Ultimele <n>] -> lista mesaje
|
||||
# citeste_email.ps1 -Nr <linie> [-Linii <n>] -> corpul unui mesaj
|
||||
param(
|
||||
[string]$Cauta = '',
|
||||
[string]$Cont = '',
|
||||
[int]$Ultimele = 20,
|
||||
[int]$Nr = 0,
|
||||
[int]$Linii = 200,
|
||||
[string]$Radacina = 'D:\UTIL\portable\PortableApps\ThunderbirdPortable\Data\profile\ImapMail'
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
function Get-Mboxuri {
|
||||
param([string]$Cont)
|
||||
$c = if ($Cont) { $Cont } else { '*' }
|
||||
Get-ChildItem $Radacina -Directory -Filter $c |
|
||||
ForEach-Object { Join-Path $_.FullName 'INBOX' } |
|
||||
Where-Object { Test-Path $_ } |
|
||||
Where-Object { (Get-Item $_).LastWriteTime -gt (Get-Date).AddYears(-2) }
|
||||
}
|
||||
|
||||
function Deschide-Fisier {
|
||||
param([string]$Cale)
|
||||
# Thunderbird tine fisierul deschis -> FileShare ReadWrite obligatoriu
|
||||
$fs = New-Object IO.FileStream($Cale, [IO.FileMode]::Open, [IO.FileAccess]::Read, [IO.FileShare]::ReadWrite)
|
||||
New-Object IO.StreamReader($fs, [Text.Encoding]::GetEncoding(28591))
|
||||
}
|
||||
|
||||
function Decodeaza-Subiect {
|
||||
param([string]$S)
|
||||
$rx = [regex]'=\?([^?]+)\?([BbQq])\?([^?]*)\?='
|
||||
$rx.Replace($S, {
|
||||
param($m)
|
||||
$enc = [Text.Encoding]::GetEncoding($m.Groups[1].Value)
|
||||
$txt = $m.Groups[3].Value
|
||||
if ($m.Groups[2].Value -match '[Bb]') {
|
||||
$enc.GetString([Convert]::FromBase64String($txt))
|
||||
} else {
|
||||
$b = New-Object Collections.Generic.List[byte]
|
||||
for ($i = 0; $i -lt $txt.Length; $i++) {
|
||||
if ($txt[$i] -eq '=') { $b.Add([Convert]::ToByte($txt.Substring($i + 1, 2), 16)); $i += 2 }
|
||||
elseif ($txt[$i] -eq '_') { $b.Add(32) }
|
||||
else { $b.Add([byte][char]$txt[$i]) }
|
||||
}
|
||||
$enc.GetString($b.ToArray())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
# ---- corpul unui mesaj: de la linia data pana la urmatorul separator mbox ----
|
||||
if ($Nr -gt 0) {
|
||||
foreach ($f in Get-Mboxuri -Cont $Cont) {
|
||||
$r = Deschide-Fisier $f
|
||||
try {
|
||||
$i = 0; $scris = 0; $pornit = $false
|
||||
while ($null -ne ($l = $r.ReadLine())) {
|
||||
$i++
|
||||
if ($i -lt $Nr) { continue }
|
||||
# linia ceruta trebuie sa fie inceput de mesaj, altfel e alt cont
|
||||
if ($i -eq $Nr -and $l -notmatch '^From - \w\w\w \w\w\w ') { break }
|
||||
if ($pornit -and $l -match '^From - \w\w\w \w\w\w ') { break }
|
||||
$pornit = $true
|
||||
$l
|
||||
if (++$scris -ge $Linii) { "... (taiat la $Linii linii, mareste cu -Linii)"; break }
|
||||
}
|
||||
if ($pornit) { return }
|
||||
} finally { $r.Dispose() }
|
||||
}
|
||||
Write-Warning "Linia $Nr nu exista in mbox-urile cautate."
|
||||
return
|
||||
}
|
||||
|
||||
# ---- lista de mesaje ----
|
||||
$mesaje = @()
|
||||
foreach ($f in Get-Mboxuri -Cont $Cont) {
|
||||
$cont = Split-Path (Split-Path $f -Parent) -Leaf
|
||||
$r = Deschide-Fisier $f
|
||||
try {
|
||||
$i = 0; $inAntet = $false; $m = $null
|
||||
while ($null -ne ($l = $r.ReadLine())) {
|
||||
$i++
|
||||
if ($l -match '^From - \w\w\w \w\w\w ') {
|
||||
if ($m) { $mesaje += $m }
|
||||
$m = [pscustomobject]@{ Cont = $cont; Linie = $i; Data = ''; De_la = ''; Subiect = '' }
|
||||
$inAntet = $true
|
||||
continue
|
||||
}
|
||||
if (-not $inAntet -or -not $m) { continue }
|
||||
if ($l -eq '') { $inAntet = $false; continue }
|
||||
if ($l -like 'Date: *' -and -not $m.Data) { $m.Data = $l.Substring(6).Trim() }
|
||||
elseif ($l -like 'From: *' -and -not $m.De_la) { $m.De_la = $l.Substring(6).Trim() }
|
||||
elseif ($l -like 'Subject: *' -and -not $m.Subiect) { $m.Subiect = Decodeaza-Subiect $l.Substring(9).Trim() }
|
||||
}
|
||||
if ($m) { $mesaje += $m }
|
||||
} finally { $r.Dispose() }
|
||||
}
|
||||
|
||||
if ($Cauta) {
|
||||
$mesaje = $mesaje | Where-Object { $_.Subiect -like "*$Cauta*" -or $_.De_la -like "*$Cauta*" }
|
||||
}
|
||||
$mesaje | Select-Object -Last $Ultimele | Format-Table -AutoSize -Wrap
|
||||
Reference in New Issue
Block a user