Achizitie import unificata (ROAGEST): ointroduceri, teste UI, documentatie

- import_nota / import_adauga_factura: flux unificat note contabile + articole,
  sincronizare automata, total factura automat, TVA impartit pe conturile
  creditoare ale notelor (rundele 1-31)
- runda 32: totalurile import_nota pe _label/_textbox din _baza.vcx (Arial 10),
  fara containerele clb_tx_simplu si fara bifa "Recalculeaza TVA" (recalcul
  mereu automat); "Sincronizeaza facturile secundare" mutata sub butoane
- utile/Teste: harness UI VFP headless (vfp_ui_harness.ps1, ui_harness.prg,
  precompilare, mock-uri) in radacina; suitele e2e pentru achizitia din import
  grupate in utile/Teste/achizitie_import/
- docs: flux editare text vcx/scx, testare-ui-vfp si testare-vfp-mcp (mutate
  din ROAGEST, general valabile), inventar comun, orchestrare subagenti,
  conventie GO recno, depanare testare VFP

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019DGibQKa5uK4P2TNSFFQNh
This commit is contained in:
2026-07-20 00:50:18 +03:00
parent 0fe9b25fe6
commit 53d9f1c64a
46 changed files with 16907 additions and 457 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,15 @@
# Conventie: GO pe Recno() capturat
`SELECT-SQL ... FROM cursor` lasa pointerul cursorului sursa pe EOF, deci un `Recno()` capturat dupa aceea poate fi `Reccount()+1` -> `GO` da "Record is out of range".
Regula: nu folosi `GO` direct pe un recno primit ca parametru sau capturat anterior; impacheteaza-l:
```foxpro
TRY
GO tnRecNo
CATCH
GO TOP
ENDTRY
```
Preferabil, unde exista cheie de rand (ex. doc_key): repozitionare prin `LOCATE` pe cheie in loc de recno absolut.

View File

@@ -18,6 +18,9 @@ max o linie, modificari minime).
- `COMUN\utile\Teste\test_repro_cnrcrt_footer.prg` - exemplu complet de harness:
init mediu -> replicare flux (cursoarele din modificanote) -> instantiere forma reala ->
executie pas cu pas cu logare -> verdict OK/BUG. Copiaza-i structura pentru bug-uri noi.
- `COMUN\utile\Teste\test_repro_import_nota.prg` - harness instantiere import_nota
(ROAGEST) fara Oracle: cursori dummy + goExecutor dummy; parametrul LPARAMETERS
incarca o copie de clasa din scratchpad in loc de cea reala (bisectie A/B).
- `COMUN\utile\Teste\teste_roacont.prg` si `COMUN\utile\Teste\test.prg` - teste ad hoc istorice.
- Mediu de test standard: server `CENTRAL`, schema `MARIUSM_AUTO`, parola schemei
`ROMFASTSOFT`; utilizator de aplicatie "MARIUS M" / parola "123" (unde e nevoie de login).
@@ -76,6 +79,15 @@ Cand un bug apare "de azi", compara comportamentul cu clasa veche fara a atinge
4. cand difera rezultatul, cauza e in diff-ul acelei clase (sau intr-un defect latent
pe care noul cod il activeaza - vezi capcanele de mai jos).
Varianta pe backup-uri de runda (fara git): copiaza `*.vc2.pre_rundaN.bak` din cache
intr-un folder temp ca `ointroduceri.vc2`, regenereaza binarul direct cu
`FoxBin2Prg.EXE "<temp>\fisier.vc2" "" "" "" 1 0 1` (pune `..\include\foxpro.h` langa,
altfel .ERR), apoi in harness incarca DOAR copia (nu ADDITIVE peste cea reala -
rezolvarea intre doua classlib-uri cu aceeasi clasa nu e garantata => fals negativ).
Bisectie in interiorul unei runde: neutralizeaza valori IN LOC (ControlSource ->
camp simplu, sterge linii de proprietate din mijlocul blocului) - NU sterge
obiecte/coloane din ADD OBJECT (strica structura: "Cannot add this object to a Grid").
## 5. Capcane VFP descoperite (de verificat la bug-uri asemanatoare)
- `SELECT ... INTO CURSOR` NU mosteneste indecsii cursorului sursa. Orice
@@ -93,8 +105,64 @@ Cand un bug apare "de azi", compara comportamentul cu clasa veche fara a atinge
- Fix-ul unui typo intr-o clasa partajata poate activa defecte latente in aval
(codul care nu rulase niciodata incepe sa ruleze). La regresii dupa fix-uri
"inofensive" in COMUN, cauta defectul latent, nu doar diff-ul.
- **Coloana de grid cu ControlSource EXPRESIE (nu camp) cere `Bound = .F.`**.
Fara el: eroare 9 "Data type mismatch" la CREATEOBJECT-ul formei (faza de
constructie, raportata la linia apelanta, Details gol). Caz: import_nota.GridArt
Column7/8/9 cu `round(...)` (ROAGEST 16.07.2026); model corect: Grid1.cTaxCode
(`Bound = .F.` + expresie, functional de ani).
## 6. Studiu de caz: "Property CNRCRT is not found" (15.07.2026)
## 6. Capcane la SCRIEREA scriptului de test (nu ale bug-ului investigat)
Descoperite depanand harness-ul pentru "Data type mismatch" la `CREATEOBJECT('IMPORT_nota',...)`
(ROAGEST, 16.07.2026) - de verificat oricand un script de test nou pare "agatat".
- **`DEFINE CLASS ... ENDDEFINE` NU poate sta la mijlocul programului principal.**
Daca il pui intre alte instructiuni de top-level (ex. clasa dummy pentru un
`goExecutor` de test, definita devreme "ca sa fie la indemana"), VFP compileaza
gresit: TOATE liniile de DUPA `ENDDEFINE` dau "Statement is not in a procedure"
(vezi `<script>.ERR` generat la compilare). Simptom in productie: `vfp9.exe`
pare agatat la nesfarsit - CPU ~0, nicio fereastra de dialog vizibila (verificat
si prin enumerare Win32 a ferestrelor procesului), pentru ca de fapt a rulat
doar liniile de dinaintea `DEFINE CLASS` si s-a oprit silentios dupa eroarea de
compilare, fara sa ajunga la `QUIT`. Fix: muta orice `DEFINE CLASS` auxiliar
(dummy executor, helpere) la FINALUL fisierului, dupa `QUIT`, langa celelalte
`PROCEDURE` - e locul standard pentru cod suport intr-un script de test.
- **Diagnostic rapid compilare vs blocaj real**: cand un script "nu se termina",
verifica INTAI daca a aparut `<script>.ERR` langa `.prg` (log de compilare,
vezi si `roagest.ERR`/`log.txt` in radacina proiectului) - inseamna ca s-a
oprit la compilare, nu ca ruleaza/asteapta ceva. Daca nu exista `.ERR`, verifica
CPU-ul procesului (`Get-Process | select CPU`): ~0 dupa cateva secunde inseamna
ca asteapta un dialog modal (foloseste enumerarea Win32 de ferestre de mai jos
ca sa confirmi), nu ca proceseaza ceva lent.
- **Enumerare ferestre Win32 pentru un proces "agatat"** (utila cand nu esti sigur
daca exista un dialog modal ascuns): `Add-Type` cu `EnumWindows`/`GetWindowText`/
`GetWindowThreadProcessId` din `user32.dll`, filtrat pe PID-ul lui `vfp9.exe`.
Daca vezi doar fereastra principala + "Command", nu e dialog - cauta alta cauza
(vezi punctul de mai sus).
- **`STRTOFILE` inainte de `SET SAFETY OFF` = dialog modal "Overwrite?"** daca
fisierul de log exista deja (sub `-A`, SAFETY porneste ON). Pune `SET SAFETY OFF`
PRIMA linie sau sterge log-ul inainte de fiecare rulare.
- **`-A -T` sunt obligatorii impreuna** la lansare headless (`-A` ignora config.fpw,
`-T` sare peste splash screen-ul de start) - fara `-T` procesul ramane agatat pe
ecranul de intampinare, identic ca simptom cu o eroare de compilare (CPU ~0,
fara log). Confirma mereu care e cauza inainte de a schimba scriptul.
- **`goExecutor`/alte dependinte "dummy"**: `CREATEOBJECT('Custom')` + `AddProperty()`
poate adauga doar PROPRIETATI, nu METODE. Daca clasa testata apeleaza
`goExecutor.oExecute(...)`/`oExecuta(...)`, dummy-ul trebuie sa fie o clasa
proprie (`DEFINE CLASS dummyexecutor AS Custom` cu `PROCEDURE oExecute`/
`oExecuta` reale), nu un `Custom` cu proprietati adaugate.
- **Erorile de instantiere (`CREATEOBJECT`) raportate la linia CREATEOBJECT, nu la
`.Init`**: cand `ON ERROR`/`CATCH` arata `Procedure` = scriptul apelant (nu
`NUMECLASA.INIT`), inseamna ca eroarea vine din evaluarea proprietatilor/
obiectelor din DEFINITIA clasei (`ADD OBJECT ... WITH RowSource = ...`,
`ControlSource` de coloana grid evaluat ca expresie, etc.) - controale native
VFP (ex. combobox cu `RowSourceType=6` Fields) isi rezolva bind-ul la
CONSTRUCTIE, inainte sa apuce sa ruleze `PROCEDURE Init` a formei. Cand
reproduci un astfel de bug cu un mediu minimal, o "Alias is not found" pe un
cursor pe care nu l-ai deschis tu confirma mecanismul (faza de instantiere),
chiar daca nu e mesajul EXACT din bug-ul original.
## 7. Studiu de caz: "Property CNRCRT is not found" (15.07.2026)
Lant complet: `frm_import_extrase_banca.modificanote` copia `crsJTVATemp` fara index
(defect latent) -> coloana `cExplicatieTVA` din `frm_modific2024.grdRulaje` face

View File

@@ -1,7 +1,7 @@
# Flux editare .vcx/.scx pe text (comun proiectelor VFP)
Textul .vc2/.sc2 e sursa de editare; write-back in binar cu `txt2vcx.ps1`, fara VFP IDE.
Detalii complete: `D:\ROA\UTIL\foxbin2prg\CLAUDE.md`. Parametrii per proiect: in `docs\` proiectului.
Detalii complete: `D:\ROA\UTIL\foxbin2prg\CLAUDE.md`. Parametrii per proiect: sectiunea de mai jos.
**Proiecte migrate (ROACONT, COMUN, …): flux in-arbore.** Textul .??2 sta langa binare, il
improspateaza `git_sync.ps1 -ProjectRoot <root>` (nu cache extern) — la inceput de sesiune si
@@ -10,6 +10,12 @@ in IDE. `txt2vcx.ps1` cu `-CacheRoot` = `-ProjectRoot` (implicit). Pasul 0 de ma
rularea `git_sync.ps1`; restul pasilor raman la fel. Fluxul cu cache extern (`vcx2txt.ps1` +
`-CacheRoot` separat) ramane doar pentru proiectele nemigrate.
## Parametri per proiect (nemigrate, cache extern)
- **ROAGEST**: `-Project 'D:\ROA\ROAGEST\roagest.pjx' -ProjectRoot 'D:\ROA\ROAGEST'
-CacheRoot 'D:\ROA\_vfp_textcache\roagest'`; procese de verificat inainte de write-back:
`vfp9`, `roagest`; patch-uri de review in `docs/diff_runda<N>_<subiect>.patch`.
## Pasii unei runde
0. Refresh cache (obligatoriu dupa orice sesiune IDE — staleness pe mtime):
@@ -23,11 +29,25 @@ rularea `git_sync.ps1`; restul pasilor raman la fel. Fluxul cu cache extern (`vc
(exit 1 = normal). Utilizatorul revizuieste FISIERUL de patch si aproba; write-back-ul
(pasul 5) se face DOAR dupa aprobare. Commit doar dupa confirmare pe patch + test in IDE.
Comentariile in cod: maxim o linie (`*!* DD.MM.YYYY autor - motiv scurt`), fara explicatii lungi.
Obligatoriu inainte de a preda patch-ul la review: skill-ul de code-review rulat pe bucatile
de cod din diff (nu doar citire manuala) - prinde defecte gen IIF cu numar gresit de
argumente, deduplicari care nu se declanseaza niciodata, interogari mai largi decat e nevoie.
Review-ul verifica si compactitatea/reutilizarea: cod care refoloseste functiile si clasele
comune existente in loc sa le reinventeze (ex. cursor2lista()/cursor2listac() pentru liste
dintr-un cursor in loc de Scan manual; butoane din cmd_butoane.vcx in loc de butoane ad-hoc).
Inventarul comunelor: COMUN\docs\inventar-comun.md - se consulta si la pasul de plan/arhitectura,
inainte de a scrie cod nou.
4. Preconditie write-back: niciun proces vfp9/<exe proiect> (tin lock pe binar); nu se omoara.
5. Write-back: `txt2vcx.ps1 -TextFile <vc2> -ProjectRoot <root> -CacheRoot <cache>`
(+ `-AllowComun` cu aprobare explicita pentru tinte COMUN — afecteaza toate aplicatiile ROA).
Succes = fidelity-check trecut: binar cu mtime nou; `vcx2txt.ps1` ulterior il vede la zi.
6. Backup-urile `.pre_runda*.bak` si patch-urile se sterg la curatenia de dupa commit.
6. Teste finale pe cerinta initiala (cerinta Marius, valabila in toate proiectele VFP):
dupa ultima runda, teste e2e (harness UI, pe fluxul real al utilizatorului) care verifica
ca rezultatul construit *arata si se comporta* conform cerintei initiale — scenariul concret
dat de Marius, cu valorile lui asteptate — nu doar teste per-fix. Assert-uri pe continutul
rezultatului (sume, campuri, randuri), nu pe efecte de suprafata ("a aparut un rand" nu e
suficient).
7. Backup-urile `.pre_runda*.bak` si patch-urile se sterg la curatenia de dupa commit.
## Capcane
@@ -37,5 +57,14 @@ rularea `git_sync.ps1`; restul pasilor raman la fel. Fluxul cu cache extern (`vc
- 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:`.
- 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`, 07.2026); simptom: crash la Createobject cu
"Data type mismatch" raportat la linia apelanta. Dupa orice sesiune IDE pe clasa: refresh
cache + compara lista `*m:` cu starea de dinainte.
- Nu folosi *Project > Build* ca sa recompilezi un binar vizat: rebuild-ul recompileaza toate
`.vcx`/`.vct` din proiect si le rescrie antetul (timestamp compilare) si posibil p-code-ul
intern si la librarii neatinse efectiv, aparand fals ca "modificate" in diff — de aici
fluxul text->bin punctual pe binarul vizat.
- Subagentii delegati primesc regulile 2-5 in prompt si raporteaza unicitatea sirurilor
inlocuite + rezultatul fidelity-check-ului.

315
docs/inventar-comun.md Normal file
View File

@@ -0,0 +1,315 @@
# Inventar COMUN - functii/clase reutilizabile (ROAGEST)
Scop: referinta rapida pt. plan/code-review, ca sa refoloseasca comunele in loc sa se reinventeze
(ex: Scan manual pt. lista dintr-un cursor, cand exista deja cursor2lista()). Generat prin grep pe
COMUN/programe/*.prg + cache text D:\ROA\_vfp_textcache\roagest (nu presupuneri). Numerele = nr.
aparitii grep in tot proiectul (indiciu de cat de "canonic" e functia).
## 1. Functii comune - COMUN\programe\oproceduri_comune.prg (clasa Oracle/executor + utilitare)
| Functie | Semnatura scurta | Ce face | Uz |
|---|---|---|---|
| oExecute | (cSql,cCursor,lProgress,cTitlu,nHandle,lShowError,lQuitOnError,lReconnect) | ruleaza SQL prin Oracle, deschide cursor. Retur: <0 eroare (vezi oPrelucrareEroare), 0 fara randuri, >0 nr. randuri | 851 |
| oExecuta | idem oExecute, wrapper | ca oExecute dar arata singur amessagebox la eroare si intoarce .T./.F. | 256 |
| oPrelucrareEroare | () | intoarce mesajul de eroare Oracle formatat, dupa un oExecute cu retur <0 | 93 |
| oFunction2Value | (cSql/cFunctie,...) | executa o functie Oracle si intoarce direct valoarea scalara | 31 |
| oSelect2Value | (cSql,...) | SELECT cu 1 coloana/1 rand -> valoare scalara | 58 |
| oSelecteaza2Value | variantul "Selecteaza" al lui oSelect2Value | idem, alt nume istoric | 20 |
| oSelecteaza2Object | (cSql,...) | SELECT 1 rand -> obiect cu proprietati = coloane | 23 |
| Connect / Disconnect / Oreset() | - | (re)conectare/deconectare goConn, reset stare executor | 33/10/119 |
| ProcessError | - | procesare interna eroare conexiune | 14 |
| amessagebox | (cMesaj,nIcon,cTitlu,...) | MESSAGEBOX wrapper standard ROA (icon/titlu/localizare) - **functia cea mai folosita din tot COMUN** | 1308 |
| amessage | - | varianta simpla fara icon/butoane multiple | 14 |
| cursor2lista | (cCursor,cColumn,cSeparator,cFiltru) | Scan cursor -> lista valori separate (";" default), pt. coloane necaracter | 36 |
| cursor2listac | (cCursor,cColumn,cSeparator,cFiltru) | ca cursor2lista dar incadreaza itemii intre apostrof (pt. SQL IN ('a','b')) - de folosit in loc de Scan manual | 2 |
| lista2array | (cLista,@aArray,cSeparator) | sparge o lista delimitata intr-un array | 35 |
| lista2cursor | (cLista,...) | lista delimitata -> cursor | 21 |
| get_mask | (nInt,nDec) | intoarce masca de format numeric (ex. "999,999.9999") dupa nr. intregi/zecimale | 24 |
| formateaza | - | formatare valoare dupa masca/tip | 18 |
| NEW_ID | (tabela,...) | genereaza urmatorul ID secvential pt. o tabela | 22 |
| NRORD | - | numar de ordine (contor afisare grid/raport) | 217 |
| NRCRT | - | numar curent (similar NRORD, alt istoric) | 108 |
| Get_Ora | (nTip) | ora curenta formatata dupa tip | 150 |
| ULTIMAZI / ultima_zi_din_luna | (an,luna) | ultima zi calendaristica a lunii | 16/25 |
| C_LUNA / CLUNA3 / cluna | (nLuna) | nume luna (lung/prescurtat) in romana | - |
| get_trimestru / get_semestru | (nLuna) | trimestrul/semestrul din numar luna | - |
| SAVE_GRID / RESTORE_GRID | (oGrid,cCheie) | salveaza/restaureaza layout coloane grid (latimi/ordine) in ini/tabela | 15/15 |
| SAVE_GRID_COMMENT / RESTORE_GRID_COMMENT | idem | variante cu comentarii coloane | - |
| SAVE_GRID_TAG / RESTORE_GRID_TAG | idem | variante cu tag/sortare curenta | - |
| snr_grid | - | switch_and_restore_grid - schimba sursa gridului si reaplica layout salvat | - |
| XMENU / XMENUP | - | meniu contextual generic (popup) | 22 |
| GETCHOICE | - | dialog alegere dintr-o lista | - |
| Get_Version | (lNoRevision,lInfo,cFileName) | citeste versiunea din resursele .exe | 15 |
| Get_Hexa | (nDeca) | conversie zecimal->hex | 12 |
| format_msg | - | formateaza mesaj cu parametri (gen sprintf) | - |
| GetHash | - | hash generic (verificare integritate/duplicate) | 48 |
| export_xls / ExportToXMLExcel | - | export cursor -> Excel (functii libere aici, la 1234/5502; NU sunt metoda goExport.export_xls din oexport.prg - cod si semnatura diferite, doar nume identic) | 24 |
| copiaza_structura_cursor | (cSursa,cDest) | copiaza doar structura unui cursor (fara date) | 27 |
| GETCALLSTACK | - | stack de apel curent, pt. debug/log erori | 24 |
| RemoveCharacters / RemoveCharactersDB | (cStr,cChars) | elimina caractere dintr-un string / varianta safe pt. query | 56/9 |
| XmlSpecialCharacters / WindowsSpecialCharacters / OracleSpecialCharacters | (cStr) | escapare caractere speciale pe context (XML/Windows/Oracle) | 19/11/- |
| EncryptDecrypt | (cStr,cCheie) | criptare/decriptare simetrica simpla | 23 |
| StringAgg | (cCursor,cColumn,cSeparator) | agregare valori coloana intr-un singur string (gen LISTAGG) | 18 |
| GetNrFromString / GetDigitsFromString / GetIBANFromString | (cStr) | extrage numere/cifre/IBAN dintr-un text liber | 18/- |
| Atasament2File / File2Atasament | - | conversie fisier <-> blob-atasament (baza de date) | 12/12 |
| romfast_suport / DownloadSupportFile | - | trimite/descarca fisier suport catre ROA | 18 |
| SaveBackupSet / RestoreBackupSet / ExistsBackupSet / DeleteBackupSet / UpdateBackupSet | - | set de proceduri pt. backup/restaurare setari private utilizator | 22/12/12/12/10 |
| GetOptiuneFirma / citeste_optiune_firma | (cCod) | citeste o optiune de configurare per firma | 20 |
| param_listari | (cRaport,cTitlu,cSemnaturi,lFaraTab) | pregateste parametri standard pt. rapoarte (titlu/semnaturi) | 19 |
| ceretitlu_rap | - | dialog cerere titlu raport | 16 |
| aInputBox | - | InputBox generic cu validare | 12 |
| GetPdfPath | - | cale generare/salvare PDF | 13 |
| GetDefaultValue / HasProperty / GetValue / SetValue | pe clase interne (ex. optiuni) | pattern generic proprietate-cu-default | 14/11/464/540 |
| verificare_note_contabile | - | valideaza notele contabile generate din import (echilibrare debit/credit) | 11 |
| verifica_partener / verificare_parteneri / verificare_parteneri_istoric | (cCUI/cCod) | valideaza/cauta partener in nomenclator dupa CIF/cod, inclusiv istoric | 10/4/6 |
| VerificaCodFiscal / GetMeniuVerificareCodFiscal / GetOptiuneVerificareCodFiscal | - | validare CUI/CIF (ANAF-like) | 10 |
| VerifCF / cValidCNP / ValidCNP / GetDataCNP | (cCod) | validare CIF/CNP + extragere data nastere din CNP | 9/- |
| VerifIBAN / verificare_iban / GetSumaControlIBAN | (cIban) | validare IBAN (cifra de control) | 8/4 |
| TVA2PROCTVA / GetProcTvaStandard / GetCoeficientTvaStandard / ProcentTva2IdJtva / GetIdJtvaStandard | - | conversii cota TVA <-> procent <-> cod TVA Oracle (gcS) | 6/11/-/-/5 |
| GetTaxCodeIdPart / GetTaxCode / GetPaymentCode | - | coduri taxare/plata pt. e-Factura ANAF | 12/-/- |
| GetArticolByCodDenumire / GetArticolById / GetArticolEFByPartDenumire | - | cautare articol nomenclator dupa cod/denumire/id | 10/6/- |
| GetPartenerByCodFiscal / GetPartenerByDenumire / GetPartenerByContBanca / GetPartenerByUtil / GetIdPartenerBy... / GetDenumirePartenerById / GetCodFiscalPartenerById | - | familie de cautari partener (id<->cod fiscal<->denumire<->cont banca) - **cauta_* pt. nomenclatoare, prioritar fata de SELECT ad-hoc** | 2 fiecare |
| GetSectieByCsectie / GetSectieById / GetIdSectie / GetGestiuneById | - | cautari sectie/gestiune | 2 fiecare |
| GetVencheltById / GetIdVenchelt | - | cautare venit/cheltuiala | 2 |
| GetDocumentByContPartenerAct | - | cautare document existent dupa partener+cont+act | 4 |
| GetFdocById | - | cautare tip document (fdoc) | - |
| GetValutaByISO | - | cautare valuta dupa cod ISO | - |
| NrLuni2AnLuna / GetDataIreg | - | conversii perioada an/luna | - |
| sir2array | - | split string -> array (generic, non-cursor) | - |
| nvl2 / nvl2Default | (val,default) | echivalent NVL Oracle in VFP | 11 |
| TooManyInstances | (nInstante) | verifica daca ruleaza deja alta instanta a exe-ului | - |
| MyUnzip / UnzipQuickShell / MyUnzipCallBack | - | dezarhivare (update-uri, atasamente) | - |
| HTTPDownloadFile / DownloadFile | - | descarcare fisier prin HTTP | - |
| lansare_help / lansare_help_meniu / arata_manual | - | deschide manualul/help-ul aplicatiei | - |
| viz_prg_instalat / versiune / CheckNewVersion / CheckVersion / UpdateVersion | - | verificare versiune instalata vs. server update | 57 (versiune) |
| xdir / xdelete / DeleteFiles | - | utilitare fisiere (listare/stergere) | 14/- |
| ImportTable | - | import tabel extern (DBF/CSV) | - |
| GET_SCHEMA_GRID | - | genereaza schema coloane pt. grid dinamic | - |
| CloneObj / CopyProps | (oSursa,[oDest]) | clonare obiect / copiere proprietati intre obiecte | 10/- |
| Get_zileluc | - | zile lucratoare | - |
| GetUserDocPath | - | folder documente utilizator curent | - |
| aleg_document_pereche | (vezi ooperatii_comune) | vezi sectiune 2 | - |
Nota: multe din functiile de mai sus exista **dublat** in `proceduri_comune.prg` (varianta veche,
non-obiect) - ex. NEW_ID, SAVE_GRID*, XMENU, cursor2lista*, lista2array/cursor, get_mask, Get_Version,
Get_Hexa, format_msg, C_LUNA/cluna, get_trimestru/semestru, GETCALLSTACK, CloneObj/CopyProps,
ceretitlu_rap. La duplicat castiga fisierul adaugat **cel mai recent** cu SET PROCEDURE ADDITIVE -
in roagest.prg OPROCEDURI_COMUNE.PRG (linia 238) vine dupa proceduri_comune (linia 218), deci
varianta activa e cea din `oproceduri_comune.prg`. Din varianta veche raman folosite doar 2 functii
unice: `extrage_optiuni(cLista,nId)` (valoare dintr-o lista "id::val;id::val", 11 uz) si
`myScatter(tcBlank)` (SCATTER generic in obiect, 3 uz); restul functiilor unice de acolo = moarte.
## 2. Functii comune - COMUN\programe\ooperatii_comune.prg (contabilitate/analitice/balanta)
| Functie | Ce face | Uz |
|---|---|---|
| viz_act | vizualizare document (act) generic | - |
| aleg_document_pereche | alege documentul pereche (ex. factura<->aviz) la asociere | - |
| exista_cont_in_plan_conturi | verifica daca un cont exista in planul de conturi | - |
| verific_partener | valideaza/completeaza partener pe o inregistrare contabila | 7 |
| verific_analitic / verific_analitic_ | valideaza analitic contabil (cont+subcont) | 7/2 |
| verificare_note_contabile | valideaza echilibrarea notelor contabile generate | 11 |
| sterge_nota / scrie_nota_import | sterge/scrie nota contabila generata din import | - |
| do_assign_analitic | atribuie analitic automat pe o linie | - |
| verific_cont | verifica existenta/valabilitate cont contabil | 9 |
| viz_balanta_contabilitate / viz_balanta / make_tbalanta / Eval_balanta | construire/vizualizare balanta de verificare | - |
| completare_gruputil_analitice / completare_tva_analitice / completare_taxname / completare_paymentname / completare_explicatie_tva | completeaza campuri derivate pe linie contabila (grup util, TVA, taxname, explicatie) | - |
## 3. Export si listare - COMUN\programe\oexport.prg (clasa oExportConfig -> obiect global goExport)
Pattern canonic: `goExport.export2frx(...)` / `goExport.export2xlsx(...)` / `goExport.export2pdf(...)`.
Preview rapoarte: FoxyPreviewer (`gcReportPreviewer = "FoxyPreview"` in roagest.prg).
| Functie/metoda | Semnatura scurta | Ce face | Uz |
|---|---|---|---|
| export2frx | (tcAlias,tcRaport,tlCereTitlu,...,tcReportPreviewer,toPreviewerConfig) | REPORT FORM cu preview/print (FoxyPreview), logo, imprimanta din setari - **listarea standard, cea mai folosita** | 155 |
| export2xls | (tcAlias,tcNumeFisier,tcListaColoane,tcFiltru) | EXPORT TO ... TYPE XL5 (.xls vechi) + deschide fisierul | 30 |
| export2xlsx | (tcAlias,tcNumeFisier,tcListaColoane,tcFiltru) | copytoxlsx() - XLSX nativ modern, **preferat pt. cod nou** | 7 |
| export2xlsxGrid | (toGrid,tcNumeFisier,tcWhere,tcOrder) | schema din grid (get_schema_grid) -> SELECT -> export2xlsx | 3 |
| exportMultiTable2Xlsx | (tcTableList,tcFileName) | mai multe tabele in acelasi workbook xlsx (clasa VFPxWorkbookXLSX) | 3 |
| Export2XmlXls | (toGrid,tcFileName,tcSheetName,tlOpen) | XML SpreadsheetML via clasa excelxml, direct din grid | 2 |
| export2pdf | (tcAlias,tcRaport,tlPreview,tcCursorSalvare) | REPORT FORM OBJECT pdflistener2 -> PDF; optional continutul in cursor | 26 |
| export2html | (tcTargetTables,tcNumeFisier,tcTableTitles,tlJustTables) | HTML/Excel-HTML din unul/mai multe tabele (TEXTMERGE) | 9 |
| export2xml_efactura | (toDateFactura,tcCursorLinii,tlSilentios) | wrapper getXmlEFactura() - XML e-Factura ANAF | 6 |
| export2frx_paginaregrup | (...) | listare cu numerotare pagini per grup (crsPaginiRaportGrup) | 6 |
| getRepPath / getLogoPath | (tcRaport / tcLogo) | rezolva USR_<raport>.frx / logo per schema (DIRGEN\USERREPORTS, atas_atasamente) | 24/10 |
| OPEN_DEFAULT_APP | (tcNumeFisier) | ShellExecute "open" cu aplicatia implicita | 70 |
| citesteSetare / modificaSetare (+ *Ini/*Registru) | (cCheie[,cVal]) | setari registru/ini dupa setTip/setPath/setSectiune | 13/11 |
| verificaDate | (tcAlias,tnTip,tlSilentios) | valideaza alias deschis/cu date inainte de export | 16 |
| listareUserReport / export_frx / export_xls | - | dispatcher + variante vechi (marcate de inlocuit); metoda export_xls != functia libera export_xls din oproceduri_comune.prg | 22/13/26 |
| FoxyPreview (functie libera, nu pe goExport) | (tcRaport,toPreviewerConfig) | preview FoxyPreviewer.App direct pe .frx, apelata din formulare | 19 |
| FoxyPreviewerCaller (clasa) | AddReport(tcReport,tcClauses) / RunReport | combina mai multe .frx intr-un singur preview | 7 |
| PreviewerConfig (clasa) | SetValue/GetValue | property-bag optiuni FoxyPreviewer (param toPreviewerConfig la export2frx) | - |
### Export Excel - 3 mecanisme paralele (atentie la confuzii)
1. `goExport.export2xls/export2xlsx` (mai sus) - preferat pt. cod nou (export2xlsx).
2. `export_excel` / `export_excel_grid` / `exportare` / `LIST_EXCEL` (proceduri_excel.prg) - OLE
Automation, scrie celula cu celula, necesita Excel instalat; uz mic (2-12). `get_excel_mask` de
acolo = conversie masca VFP -> format Excel (nu confunda cu `get_mask` din sect. 1).
3. Clasa `excelxml` (excelxml.vcx, COMUN\UTILE\excel) - Excel XML direct din `gridobject`, fara
Excel instalat (proprietati: file, sheetname, openaftersaving; metoda `save`); 73 uz.
Plus functiile libere `export_xls`/`ExportToXMLExcel` din oproceduri_comune.prg (sect. 1) - cod
diferit de metoda `goExport.export_xls`, doar nume identic.
## 4. Utilitare transversale (COMUN\programe, fisiere neinventariate initial)
### gencursor.prg
| Functie | Semnatura scurta | Ce face | Uz |
|---|---|---|---|
| gencursor | (cNume,cAlias,cSelect,cFiltru,cSchema,cOrder,lAfisare,cGroup,...) | obiect deca_baza/ca_baza cu cursor "lazy" (select/filtru/order pe goConn) - **baza grilelor cu sursa dinamica; nu construi manual ca_baza** | 403 |
### validare.prg - validare CIF/CNP cu ANAF/MFIN/VIES (vs. VerifCF/ValidCNP offline din sect. 1)
| Functie/clasa | Ce face | Uz |
|---|---|---|
| VerificareCod (clasa) | validare completa cu webservice: metode VERIFICARE_CIF/VERIFICARE_CNP/ANAF/MFIN/VIES/validare/GetError | 169 |
| VerificareANAF (clasa) | sincronizare lista CIF-uri cu ANAF (VerificaListaCIF, ANAF_SincronWebService_PlatitorTva) | 26 |
| test_cif / VALIDARE_CIF / test_cnp / VALIDARE_CNP | validari format + cifra control, offline | 27/19/9/15 |
| VERIFICARE_PLATITORTVA / VIES_VAT / ONRC | platitor TVA / verificare VIES / interogare ONRC | 5/5/9 |
| IntroducereCod (clasa Form) | formular introducere + validare cod | 25 |
### ocautare.prg - dialoguri standard de cautare/alegere (de refolosit in loc de SELECT+grid manual)
| Functie | Ce alege | Uz (prg/forme) |
|---|---|---|
| caut_gestiune / caut_gestiune_dest | gestiune (sursa/destinatie) | 25/324, 12/37 |
| caut_fdoc | tip document | 7/170 |
| caut_explicatie_tva | explicatie TVA (filtrare exigibil JC/JV) | 9/143 |
| caut_partener / CautPartenerContabilitate | partener (generic / dupa cont contabil) | 13/104, 16/16 |
| caut_valuta / caut_valuta_iso | valuta | 11/104 |
| cauta_nom_articole / caut_articol | articol (filtru text / multiplu) | 8/87, 20/42 |
| caut_sectie / caut_facturi | sectie / facturi dupa cont+partener+interval | 8/71, 12/34 |
| caut_lucrare, caut_venchelt, caut_contract, caut_delegati, ... | ~40 alte dialoguri de nomenclator, uz mic in ROAGEST | 2-17 |
### oheader.prg
| Clasa | Ce face | Uz |
|---|---|---|
| PSHeader (As Header) | dublu-click pe header = sortare (cHOrder), evidentiaza coloana activa, apeleaza cCallMethod (default Refresh) pe parintele gridului | 37 in forme |
### regex.prg
| Functie | Ce face | Uz |
|---|---|---|
| strtranx | STRTRAN cu regex (grupuri $1, evaluare =expr) | 14 |
| GetRegExp / GetRegExpAll / OccursRegExp / StrtranRegExp | prima/toate potrivirile, numarare, inlocuire simpla | 15/4/4/2 |
| StripNonAscii | elimina caractere non-ASCII dintr-un string (whitelist) | 11 |
### ini.prg
| Functie | Semnatura | Ce face | Uz |
|---|---|---|---|
| getini / setini | (cIniFile,cSection,cVar[,cVal]) | citire/scriere fisiere .ini low-level (FOPEN) - distinct de GetOptiuneFirma (Oracle) si goExport.citesteSetareIni (wwApi) | 28/9 |
### altele (o functie-doua per fisier)
| Functie (fisier) | Ce face | Uz |
|---|---|---|
| get_oluna (oproceduri_util.prg) | (an,luna) -> obiect cu intervalul calendaristic disponibil (lunamin/anmin/lunamax/anmax) din tabela calendar | 22 |
| ReferinteDocumenteNota / ReferinteDocument (odocumente.prg) | verifica daca un document e referentiat de altul (pack_documente Oracle) - inainte de stergere/modificare | 4/4 |
| anunta_rezultat / scrie_in_mesaje / raport_mesaje (mesaje.prg) | log mesaje de verificare in tabel + raport; uz de nisa | 2-3 |
## 5. Clase UI comune (COMUN\clase, cache text D:\ROA\_vfp_textcache\roagest\comun\clase)
### Butoane - cmd_butoane.vcx (parinte: _cmd_base.vcx -> buton/cmd_buton)
Mecanism: fiecare buton seteaza doar proprietatea `caction` (nume metoda) + `cpictureup/down`.
`buton.Click` (in `_cmd_base.vcx`) cauta metoda `caction` pe `this.Parent`, apoi `this.Parent.Parent`,
apoi `Thisform`, si o executa cu `clistaparametri` ca argument daca exista (Pemstatus + macro &).
**Nu suprascrie Click pe butoane noi - seteaza doar caction pe o instanta din cmd_butoane.vcx.**
| Clasa buton | caction | Rol |
|---|---|---|
| but_nou / cmd_adauga | do_adauga | adauga inregistrare noua |
| but_copiaza | do_copiaza | copiaza inregistrarea curenta |
| but_sterge / cmd_sterge | inainte_de_do_sterge | sterge (cu hook de confirmare) |
| but_modifica / cmd_modifica | inainte_de_do_modifica | intra in modificare |
| but_termin / but_da / cmd_termin | do_termin | confirma/salveaza si inchide |
| but_renunt / but_nu / cmd_renunt | do_renunt | renunta/inchide fara salvare |
| but_salveaza | do_salvare | salveaza fara inchidere |
| but_reset / cmd_reset | do_reset | reseteaza formularul/filtrul |
| but_cautare / cmd_cauta | do_cauta | deschide cautare |
| but_compara | do_compara | comparare inregistrari |
| but_verifica | do_verifica | validare |
| but_retur | do_retur | operatie retur |
| but_precedent / but_urmator / but_urmator_tot | do_precedent / do_urmator / do_urmator_tot | navigare inregistrari |
| but_excel | inainte_de_do_excel | export Excel |
| but_listare | inainte_de_do_listare | listare/raport |
| but_factura / but_listfactura | do_factura / do_listfact | facturare/listare factura |
| but_grafic | do_grafic | afisare grafic |
| but_help | do_help | help contextual |
| but_modiparam | do_modiparam | modificare parametri |
| but_attach | do_ataseaza | ataseaza fisier |
| but_reface | inainte_de_do_reface | reface/reia operatie |
| cmd_login / cmd_logoff | do_login / do_logoff | autentificare |
| cmd_executa / cmd_select | do_executa / do_select | executie/selectie generica |
| but_sus / but_jos | do_scrollup / do_scrolldown | scroll |
### Container label+text - lb_tx.vcx (parinte: _container, folosesc _lbbase/_txbase din _lb_base.vcx/_tx_base.vcx)
| Clasa | Rol |
|---|---|
| clb_tx_simplu / cb_tx_simplu | label + textbox simplu |
| cb_tx_autofill | label + textbox cu autocompletare (cautare in nomenclator) |
| cb_tx_cautare | label + textbox + buton cautare integrat |
| clb_tx_data | label + textbox cu masca data |
| clb_an_luna | pereche an/luna |
| clb_luna_intre / clb_nr_intre | interval luna/numar (de-la, pana-la) |
| clb_n1n2_simplu | pereche 2 numere simple |
| ct_cb_tx | container compus text+combo |
| ed_tx_simplu | label + editbox |
| op_tx_simplu | label + optiongroup |
Proprietate cheie comuna: `pcobj` (leaga containerul de camp/proprietate din obiectul sursa).
### Baze formular - _frm_base.vcx / _frm_child.vcx
| Clasa | Rol |
|---|---|
| _frmbase | baza standard formular; implementeaza deja `do_adauga/do_copiaza/do_modifica/do_renunt/do_sterge/do_termin` (override doar daca logica difera de default) |
| _frmnotitle | ca _frmbase, fara bara de titlu; are propriile do_adauga/do_modifica/do_renunt/do_sterge/do_termin |
| frm_termin | subclasa _frmbase, expune direct do_termin |
| frm_termin_renunt | subclasa frm_termin, adauga do_renunt (fara override suplimentar) |
| frm_gol | subclasa _frmbase "goala", cu propriile do_adauga/do_modifica/do_sterge |
| _pgfrmbase | baza pageframe |
### Grid - _grd_base.vcx
| Clasa | Rol |
|---|---|
| _grdbase | grid de baza (subclasa _grid) |
| _grdrow | subclasa _grdbase, randuri custom |
| _grdfooter | grid separat "atasat" la un grid sursa prin metoda `attachtogrid` (copiaza coloane/fonturi de la oSrcGrd) - pt. randuri de total/footer sub un grid principal |
## 6. Conventii transversale
- Prefixe variabile: `g`/`gc`/`gn`/`gl` (globale char/numeric/logic), `p`/`pc`/`pn`/`pl` (proprietati
obiect), `t`/`tc`/`tn`/`tl` (parametri PARAMETERS/LPARAMETERS), `l`/`lc`/`ln`/`ll` (locale), `m.`
(scoping explicit memvar quand hay coliziune cu camp).
- SQL pass-through: mereu prin `goExecutor.oExecute`/`oExecuta`, niciodata SQLEXEC direct in cod nou;
schema calificata cu `gcS` (ex. `gcS + ".STOC"`); parametri legati cu `?param` (bind variable VFP->Oracle).
- Retur executor: oExecute -> numeric (<0 eroare/`oPrelucrareEroare()`, 0 fara randuri, >0 nr. randuri);
oExecuta -> logic (.T./.F., arata singur eroarea).
- Cursoare temporare: prefix `crs*` (ex. `crsListaTemp` in cursor2lista/cursor2listac).
- Mesaje utilizator: mereu `amessagebox()`/`amessage()`, nu `MESSAGEBOX()` direct.
- Formatare numerica: `get_mask()` + `formateaza()`, nu masti hardcodate in cod nou.
- Fisiere `.vc2`/`.sc2`: TAB-uri semnificative, proprietatile in blocul `*<PropValue>` sunt
alfabetizate - orice editare manuala trebuie sa respecte formatul (vezi CLAUDE.md, flux editare text).
## 7. Ce am lasat pe dinafara (intentionat)
- `proceduri_comune.prg` (varianta veche) - acoperita acum in nota de la sect. 1 (2 functii unice
folosite, restul dublate sau moarte); functiile ei unice cu 0 aparitii (caut_nume_politica,
make_sectii_utilizator, recompune_optiuni, cere*/compara*, debug_*_eventtracking, ...) - omise.
- `oproceduri_comune_imob.prg` - varianta specifica ROAIMOB, nu ROAGEST.
- `xdate.prg` - script procedural (incarca cursoarele xsets/xrequest/xnote la DO), nu expune functii.
- Metoda `getUserRepPath` din oExportConfig - complet comentata (moarta); varianta activa e functia
libera omonima din `proceduri_rapoarte.prg` (cod diferit).
- Clase de nomenclatoare mari (`onomenclatoare.vcx`, `onom_articole.vcx`, `stocuri.vcx`, `rulaje.vcx`,
`ointroduceri*.vcx`, `oinventar.vcx`) - business logic specific gestiune, prea voluminos pt. acest
inventar (candidat pt. un inventar separat, per-flux, daca devine necesar).
- Clasele de configurare/serii (`configurare.vcx`, `serii_numere.vcx`, `ferestre_oracle.vcx`,
`bon_fisc.vcx`) si utilitarele (`GridExtras`, `ctl32`, `hpdf`) - neinventariate, uz mai rar
in fluxurile curente de lucru (`excelxml.vcx` e acoperita la sect. 3).
- Functiile din `COMUN\programe` fara nicio aparitie gasita prin grep in ROAGEST (posibil folosite
doar de alte aplicatii ROA) - omise.
## 8. Cum se foloseste
- **La plan**: inainte de a scrie cod/obiecte noi, scaneaza acest fisier + un grep tintit
(`grep -rn "<nume_functie_candidata>" COMUN/programe D:\ROA\_vfp_textcache\roagest`) ca sa
confirmi ca nu exista deja o comuna echivalenta.
- **La code-review**: daca un diff introduce Scan manual pt. liste, MESSAGEBOX direct, SQLEXEC direct,
un buton cu Click suprascris in loc de `caction`, un export Excel/listare construite manual in loc
de `goExport.export2*`/FoxyPreview, sau un dialog de alegere nomenclator facut din SELECT+grid in
loc de `caut_*` (ocautare.prg), semnaleaza reutilizarea comunei corespunzatoare din tabelele de mai sus.

View File

@@ -0,0 +1,40 @@
# Orchestrare cu subagenti: context mic, misiuni descompuse
Regula (valabila in toate proiectele ROA/VFP): un singur subagent care duce o misiune lunga
(iteratii de teste, investigatii, mai multe sarcini inlantuite) acumuleaza context urias
(s-a ajuns la ~800k tokens) — calitate degradata, cost mare. Nu se lucreaza asa.
## Cum se lucreaza
- Sesiunea principala (sau un agent primar) e ORCHESTRATOR: imparte planul pe sarcini
independente (un test, un audit, un scenariu = o sarcina), monitorizeaza, transmite
constatarile intre agenti, verifica rezultatele.
- Fiecare sarcina merge la un SUBAGENT PROASPAT cu prompt autosuficient: context complet
in prompt + trimitere la un fisier de handoff, nu context acumulat in conversatie.
- HANDOFF compact pe disc (docs\handoff_*.md, stil telegrafic): inventar livrabile,
stare, ce ramane, detaliile ne-evidente pe care un agent proaspat nu le-ar putea
reconstitui usor. Se actualizeaza la fiecare predare de stafeta.
- PRAG: maxim ~200-250k tokens per subagent. Orchestratorul urmareste dimensiunea
contextului; la atingerea pragului: cere handoff, inchide agentul, respawneaza unul
proaspat pe sarcina urmatoare.
- Sarcinile independente ruleaza in PARALEL (lane-uri), ex. audit read-only + editare teste.
- Orchestratorul da utilizatorului UPDATE-URI SCURTE de progres, regulat (monitor pe
artefacte: loguri/fisiere/screenshots; o propozitie-doua la fiecare schimbare relevanta,
fara naratiune la evenimente fara continut).
- Orchestratorul MONITORIZEAZA ACTIV subagentii sa nu se blocheze: monitor persistent pe
artefactele lor + verificare la lipsa de progres (~10 min fara schimbare = suspect):
procese agatate (vfp9 zombi, dialoguri modale), semafoare orfane, timeout-uri de tool
(120s implicit) care omoara procese. La blocaj: diagnostic direct (procese, fisiere,
loguri), mesaj de deblocare cu constatarea concreta, si abia apoi restart daca e cazul.
- Modele: subagentii care DOAR ruleaza/editeaza teste si alte sarcini de volum/rutina ->
Sonnet; ORCHESTRATORUL subagentilor (cel care imparte, monitorizeaza, deblocheaza,
decide) -> Opus (sau sesiunea principala). Commit doar dupa review-ul diff-ului de
catre om (vezi reguli_lucru.md).
## Semne ca ai gresit impartirea
- Acelasi agent primeste "inca o sarcina" a treia oara -> trebuia agent nou + handoff.
- Agentul re-descopera capcane deja documentate -> handoff-ul/docs-ul e incomplet;
completeaza-l, nu repeta investigatia.
- Orchestratorul face el insusi munca de volum -> deleaga si pastreaza-si contextul
pentru decizii, verificari si deblocari.

View File

@@ -13,3 +13,6 @@
Metoda de depanare (log.txt, cascade ON ERROR, bisectie clase): `depanare_testare_vfp.md`.
5. Editare .vcx/.scx pe text (cache, cp1252 byte-safe, fidelity-check): `flux-editare-vfp-text.md`.
Cautare in binare: `cautare_vcx_vct.md`.
6. Misiuni lungi (teste, investigatii, sarcini inlantuite): NU un singur subagent cu context
acumulat — orchestrator + subagenti proaspeti per sarcina (max ~200-250k tokens/subagent),
handoff compact pe disc: `orchestrare-subagenti.md`.

132
docs/testare-ui-vfp.md Normal file
View File

@@ -0,0 +1,132 @@
# Testare UI VFP headless cu harness + screenshots
Harness reutilizabil pentru teste care afiseaza un formular REAL (fara Oracle/UI complet),
executa actiuni si valideaza vizual prin capturi de ecran. Valabil pentru toate proiectele
VFP din suita ROA; exemplele sunt pe ROAGEST. Alternativa la
`testare-vfp-mcp.md` (care ruleaza programul principal intreg + windows-mcp): aici instantiem o
singura clasa cu dependinte dummy, deci pornire rapida si izolata.
Fisiere in `COMUN\utile\Teste\`: `vfp_ui_harness.ps1` (orchestrator generic, parametrizat),
`_precompile.ps1` (precompilare izolata), `ui_harness.prg` (proceduri VFP de handshake),
`mock_amessagebox.prg` (mock dialog) — infrastructura sta in radacina `Teste\`; suitele de
teste stau grupate pe subiect in subfoldere (ex. `achizitie_import\`). Exemplu complet:
`achizitie_import\test_import_nota_ui.prg` + `.ps1` (wrapper).
**REGULA (Marius, 17/07/2026): testele pe aplicatii frontend exerseaza fluxul REAL al
utilizatorului** — formularul/butonul/metoda pe care o apeleaza aplicatia (ex. "Adauga repere",
do_adauga_factura prin dialogul real), NU introducerea directa a randurilor in cursoare/tabele
(ex. Append in rul_temp/introdc). Popularea directa sare peste validari/filtre/efecte laterale
si da PASS fals (caz real: articol cont 212 "adaugat" direct in rul_temp trecea testul, dar prin
fluxul real nu se adauga deloc). Mock-urile raman permise doar pe INFRASTRUCTURA (Oracle,
dialoguri modale), nu pe pasii fluxului testat.
## Test UI nou in 5 pasi
1. `.prg` de test: `PUBLIC gcUILog, gcSyncDir`; `SET TALK OFF` (obligatoriu, vezi cap. c);
`SET PATH/CLASSLIB/PROCEDURE` ca in aplicatie; incarca ULTIMELE
`SET PROCEDURE TO ...\ui_harness.prg ADDITIVE` si (daca ai dialoguri)
`...\mock_amessagebox.prg ADDITIVE`.
2. Creeaza dummy-urile minime (`goExecutor`, `goApp`, etc.) + cursoarele pe care le cere
Init-ul clasei (RecordSource-urile grilelor).
3. Instantiaza clasa, `WindowType=0`, `Show()`, `WindowState=2`.
4. Pe fiecare pas: fa actiunea, verifica efectul in date (loghezi PASS/FAIL cu un helper
local), apoi `DO HarnessStep WITH <n>, '<mesaj>'` (scrie ready_n, asteapta cont_n de la
orchestrator sau auto-continua dupa ~30s). La final `DO HarnessDone WITH 'done'`.
5. Ruleaza: `powershell -File vfp_ui_harness.ps1 -TestPrg <test.prg> -Steps @('pas0',...)`.
PNG-urile ies in `screenshots\step_<n>_<eticheta>.png`; log in `<test>_log.txt`.
## Capcane / deblocari (toate confirmate in sesiune)
a. **Lansarea orchestratorului**: prin tool cu timeout implicit (~120s) e omorat inainte de
finalul pasilor. Ruleaza-l in background (run_in_background) + asteapta `done.txt`, sau
timeout mare (300-600s). NU porni VFP separat de orchestrator - si-l lanseaza singur.
b. **Asteptarea ready_0 prea scurta** omoara VFP exact inainte sa scrie semaforul. Cu `.fxp`
cald START apare in ~2s, la rece mult mai mult (zeci de classlib-uri). Foloseste
`-ReadyTimeoutSec` generos (implicit 180s). Retry NUMAI la "start ratat", nu la "start lent".
c. **`SET SAFETY OFF` + `SET TALK OFF` ca PRIMUL lucru, inainte de primul `STRTOFILE`.**
Cu SAFETY ON, prima scriere a log-ului (daca fisierul exista deja) scoate dialogul modal
"...already exists, overwrite it?" care BLOCHEAZA rularea headless (VFP pare "instanta moarta"
- proces viu, blocat pe dialog). Cu TALK ON, `SUM`/`CALCULATE` (ex. din `recalculeaza`) isi
echo-eaza rezultatele pe desktop, ca text parazit peste formular in screenshots. Harness-ul
are `HarnessInit`/`SET SAFETY OFF` defensiv in procedurile de scriere, dar testul trebuie
sa faca `SET SAFETY OFF` oricum INAINTE de scrierea lui proprie de "START".
d. **`vfp9 -A test.prg` deschide INTERMITENT editorul** in loc sa ruleze (log ramane gol).
Lanseaza `.fxp`-ul PRECOMPILAT (`vfp9 -A test.fxp`) - se executa mereu.
e. **Precompilarea (`COMPILE`+`QUIT`) atarna** dupa COMPILE; rulata in ACEEASI sesiune
powershell care lanseaza apoi testul, otraveste lansarile (nu executa). Ruleaza precompilarea
intr-un proces copil izolat (`Start-Process -Wait _precompile.ps1`).
f. **Detectia "a pornit" pe mtime-ul log-ului > momentul lansarii**, nu pe "log ne-gol": un log
stale tinut deschis de un `vfp9` zombi pacaleste verificarea. Omoara zombii inainte de fiecare
lansare.
g. **Formulare modale** (`WindowType`) - `Show()` nu returneaza si blocheaza testul. Seteaza
`goObj.WindowType = 0` (modeless) pentru afisare non-modala automatizata.
h. **Dummy minimali**: `goExecutor` (oExecute/oExecuta creeaza cursorul cerut), `goApp`
(`ReadIni` pt. font din settings.ini), `poAct`/`oact` (curs valutar). Init-ul recreeaza
cursoarele goale din Oracle daca nu-s pre-populate - pre-populeaza-le INAINTE de instantiere.
i. **`LOCATE FOR camp == 'literal'` pe camp `C(n)` padded cu spatii nu gaseste nimic** (`==` e
exact) - foloseste `ALLTRIM(camp) == 'literal'`.
j. **Messagebox-uri de confirmare blocheaza testul headless**. Mock: `FUNCTION amessagebox`
care returneaza direct valoarea butonului (6=Da). Incarca-l cu `SET PROCEDURE ... ADDITIVE`
**PRIMUL** (inaintea `oproceduri_comune.prg`): la nume duplicat de procedura, VFP foloseste
fisierul cautat PRIMUL in lista (verificat empiric: incarcat ultimul PIERDE, primul CASTIGA).
Mock-ul umbreste `amessagebox` si din apelurile din metodele de clasa (ex. `do_sterge_articol`).
k. **Cursor bound la o grila, recreat de Init -> grila pierde coloanele (eroare 1925).** Ex.:
`import_nota.Init` recreeaza `rul_temp` din Oracle daca e gol la instantiere; GridArt ramane
fara coloanele denumite. Fix: pune 1 rand placeholder in cursor INAINTE de instantiere (ca Init
sa nu-l recreeze), apoi **`ZAP`** dupa `Show()` (NU `DELETE ALL`: acesta lasa un rand fizic
sters si pointerul la EOF, iar cod gen `do_calculeaza_diferente` face `GO recno_EOF` -> eroare 5).
l. **CREATEOBJECT/ADDPROPERTY se comporta gresit apelate DINTR-O PROCEDURA in acest runtime headless**
(obiect returnat ca string de 30 spatii; `ADDPROPERTY` da eroare 11). Din programul PRINCIPAL
merg. Construieste obiectele (ex. `toDlg` pt. `do_adauga_factura`) INLINE in main, nu intr-un
helper. (Cauza exacta neclara; reproductibil.)
m. **`gl406=.T.` (SAFT) activeaza cod care are nevoie de mock-uri suplimentare**, altfel crapa sau
taxcode ramane mereu NULL: `GetTaxCode`/`GetTaxCodeIdPart` (oproceduri_comune.prg) apeleaza
`update_jtva_coloane()` care ruleaza `goExecutor.oExecute("select * from vjtva_coloane ...", <cursor>)`
- mock-ul de `oExecute` trebuie sa intercepteze `'VJTVA_COLOANE' $ UPPER(tcSql)` si sa returneze
un cursor cu structura reala a view-ului (`id_jtva_coloana, denumire, jc, jv, coloana_jc,
coloana_jv, cota_tva, id_tva, taxcode, taxcode_neexigibil, taxcode_n50, taxcode_n50_tvai,
taxcode_n100, taxcode_regularizare, taxcode_tvai, afisat, ordine`) - codul apelant face singur
`INDEX ON id_jtva_coloana TAG id_jtva` dupa, nu trebuie indexat in mock. Cand `id_partc`/`id_partd`
pe rand nu e gol, `GetTaxCodeIdPart` cauta si codul fiscal al partenerului prin
`goExecutor.oSelect2Value(sql, @toValue)` (`GetCodFiscalPartenerById`) - metoda lipseste din
dummyexecutor-ul de baza, trebuie adaugata (returneaza cod fiscal gol -> `VERIFICA_RTVAI` sare
peste apelul Oracle real de validare CIF).
n. **Explicatia TVA de pe randul T ("in tandem" cu baza) NU se scrie prin cod separat** - e pur si
simplu o A DOUA intrare in `jtva_coloane2`/`vjtva_coloane` (coloana `id_tva` de pe randul bazei
punctand spre `id_jtva_coloana` al randului TVA); `aplica_explicatie_tva` (ointroduceri.prg
~9807) citeste acea a doua intrare si o scrie pe rand T. Populeaza mock-ul cu ambele randuri
(baza + TVA), nu doar cu unul si nu concatena manual "TVA " + denumirea bazei in test.
o. **FARA FURT DE FOCUS (17/07/2026)**: `Graphics.CopyFromScreen` (captura ecranului intreg) fura
focus si se corupe daca utilizatorul lucreaza in paralel - NU se mai foloseste. Capturile se fac
cu `PrintWindow` (user32, P/Invoke) pe HANDLE-ul ferestrei vfp9 (`Process.MainWindowHandle`),
flag `2` = `PW_RENDERFULLCONTENT` (fallback flag `0` daca iese goala); merge cu fereastra
acoperita/in fundal, dar NU minimizata. Fereastra e mutata OFF-SCREEN (`SetWindowPos` cu
`HWND_BOTTOM`, x=-4000, `SWP_NOACTIVATE`) imediat ce apare handle-ul si RE-IMPINSA la fiecare
pas (VFP isi reactiveaza singur fereastra la `Show()`/dialoguri modale - o singura impingere la
lansare nu e suficienta). Toate consolele powershell copil (precompilare) sunt `-WindowStyle
Hidden` (sigur pentru consola; NU si pentru GUI VFP, care trebuie doar off-screen, nu ascuns -
PrintWindow pe fereastra minimizata/ascunsa poate reda gol). Implementat in
`vfp_ui_harness.ps1` (Take-Screenshot, Push-Offscreen, Wait-MainWindowHandle) si
`_precompile.ps1` (acelasi Push-Offscreen pe fereastra tranzitorie de compilare).
p. **Cursorul `introdc` FARA indexul `ord_doc` schimba documentul "principal" la sincronizari
repetate** (sincronizeaza() apelat de mai multe ori, ex. la adaugarea a 2+ articole succesiv
prin fluxul real): identificarea documentului principal (`Go Top` + `Locate For
Inlist(tip_rand,'B','S') And !Empty(doc_key)`) e stabila in productie doar pentru ca
`achizitie_import` (COMUN\programe\ointroduceri.prg:1616-1618) creeaza, INAINTE de
`CREATEOBJECT('import_nota')`, indexul `ord_doc` (`Str(Nvl(nr_doc,0),8) +
Icase(tip_rand='B','1', tip_rand='S','2', tip_rand='T','3', tip_rand='D','4', '5') +
Padr(Nvl(scd,''),10)`) + `SET ORDER TO ord_doc`, care ordoneaza dupa `nr_doc` (S-urile
principalei mostenesc nr_doc-ul ei) - documentul cu `nr_doc` minim ramane mereu acelasi. Un
test care creeaza `introdc` fara acest index ramane pe ordinea FIZICA (recno): dupa ce
principala e sparta (randul B sters, randurile S adaugate la coada), urmatorul apel de
sincronizeaza() gaseste gresit ca "principal" documentul cu cel mai mic recno ramas si il
sparge si pe el - cascada se repeta la fiecare apel ulterior. Fix: dupa popularea `introdc`,
INAINTE de `CREATEOBJECT('import_nota', ...)`, adauga exact acelasi `INDEX ON ... TAG ord_doc`
+ `SET ORDER TO ord_doc` ca in `achizitie_import`.
q. **Suitele de teste NU se ruleaza in paralel**: `_precompile.ps1` face `Get-Process vfp9 |
Stop-Process -Force` (omoara TOATE instantele vfp9 de pe masina), deci un test lansat in
paralel ucide testul aflat in curs si corupe rezultatele. Ruleaza suitele strict secvential.
r. **Fara SELECT-SQL pe cursorul legat de grid**: SELECT ... FROM introdc INTO CURSOR intr-un
test, cat timp introdc e RecordSource-ul unui grid viu, poate omori procesul vfp9 silentios
(fara eroare catchabila, fara semafor). Foloseste xBase nativ (COUNT FOR ... TO,
CALCULATE, LOCATE) care nu comuta zona de lucru a grid-ului.

40
docs/testare-vfp-mcp.md Normal file
View File

@@ -0,0 +1,40 @@
# Testare automata VFP prin IDE + MCP (windows-mcp)
Valabil pentru toate proiectele VFP din suita ROA; exemplele de mai jos sunt pe ROAGEST —
inlocuieste caile, numele programului principal si titlul ferestrei pentru alt proiect.
Pentru verificare vizuala dupa modificari pe `.vc2`/`.sc2`, nu se porneste `roagest.exe`
(ar cere rebuild complet — vezi `COMUN\docs\flux-editare-vfp-text.md`), ci se lanseaza `vfp9.exe`
interpretat peste `Programe\roagest.prg`:
```powershell
Start-Process -FilePath "C:\Program Files (x86)\Microsoft Visual FoxPro 9\vfp9.exe" `
-ArgumentList '-c"D:\ROA\ROAGEST\config.fpw"','D:\ROA\ROAGEST\Programe\roagest.prg' `
-WorkingDirectory "D:\ROA\ROAGEST"
```
- Gate-ul de pornire (`gcNumeProgram = 'ROAGEST'` in `roagest.prg`) verifica
`JUSTSTEM(SYS(16,0))` — numele programului de la nivelul 0 al stivei, nu numele
procesului `.exe`. Rulat interpretat, `SYS(16,0)` = `roagest.prg`, deci gate-ul trece.
- Fereastra rezultata are titlul `ROA - Gestiuni` (setat din `NUMEPROGRAM`).
## Capcana: focus furat de terminal
Daca sesiunea Claude Code afiseaza output in timp ce comanda de lansare ruleaza,
fereastra terminalului/IDE-ului ramane in prim-plan si VFP porneste in fundal —
`Screenshot`/`Snapshot` din `windows-mcp` pot raporta "No windows found" desi procesul
si fereastra exista (verificabil cu `Get-Process vfp9 | Select MainWindowTitle`).
Fix: inainte de screenshot, adu explicit fereastra in prim-plan dupa titlu:
```
mcp__windows-mcp__App mode=switch name="ROA - Gestiuni"
```
apoi `Screenshot`. Nu te baza pe enumerarea implicita de ferestre a `windows-mcp` cand
ai lansat procesul chiar in runda curenta de comenzi.
## Curatare dupa test
Proces de omorat la final: `mcp__windows-mcp__Process mode=kill pid=<pid>` (gasit prin
`mode=list name=vfp9` sau `Get-Process vfp9`).

View File

@@ -1555,7 +1555,10 @@ Procedure achizitie_import
00000000000000 As id_fact, 00000000000000 As id_factd, 00000000000000 As id_factc, 00000000000000 As pereched, 00000000000000 As perechec, ;
00000000000000 As nract, Space(10) As serie_Act,Space(50) As explicatia4, Space(50) As explicatia5, .T. As participa_valuta, ;
poAct.id_valuta As id_valuta, poAct.Curs As Curs, poAct.nume_val As nume_val, poAct.dataact as dataact, poAct.fdoc as fdoc, poAct.id_fdoc as id_fdoc, 0 as se_scrie, poAct.tva_incasare as tva_incasare, ;
16777215 As doc_color, Space(10) As doc_label ;
16777215 As doc_color, Space(10) As doc_label, ;
'B' As tip_rand, Space(80) As doc_key, 00000000 As nr_doc, ;
00000000000000.0000 As suma_doc, 00000000000000.0000 As suma_doc_val, 0 As mod_manual, ;
Space(20) As scd_orig, Space(20) As ascd_orig ;
FROM cnote_contabile N ;
WHERE N.id_set = poAct.id_set ;
INTO Cursor introdc Readwrite Order By ordine
@@ -1564,6 +1567,13 @@ Procedure achizitie_import
*!* Directia A (11.07.2026): introdc porneste GOL; perechea-sablon (primele 2 linii,
*!* baza + TVA) se pastreaza in introdc_sablon ca sursa de clonare pentru "Adauga factura".
Select * From introdc Where Recno('introdc') <= 2 Into Cursor introdc_sablon Readwrite
*!* 16.07.2026 claude - marcaj tip_rand pe sablon (baza/TVA), inlocuieste paritatea Recno
Select introdc_sablon
Go 1
Replace tip_rand With 'B'
Go 2
Replace tip_rand With 'T'
Go Top
Select introdc
Zap
@@ -1601,8 +1611,23 @@ Procedure achizitie_import
gnZvama = 0
gnButon = 1
*!* 16.07.2026 claude - F1: index unic de sortare pe introdc, o singura data, inainte de Show
*!* (niciodata re-INDEX ulterior sub grid - vezi docs/propuneri_import_unificat.md)
SELECT introdc
INDEX ON Str(Nvl(nr_doc,0),8) + Icase(tip_rand='B','1', tip_rand='S','2', tip_rand='T','3', tip_rand='D','4', '5') + Padr(Nvl(scd,''),10) TAG ord_doc
SET ORDER TO ord_doc
SELECT introdc
obj = Createobject('IMPORT_nota', tlIntern)
*!* 16.07.2026 claude (T3) - Init poate intoarce .F. (esec Oracle la crearea rul_temp) -> obiect nul
If Vartype(obj) <> 'O'
Use In (SELECT('introdc'))
Use In (SELECT('introdc_sablon'))
Use In (SELECT('actactan'))
Use In (SELECT('jtva_coloane2'))
Return
Endif
obj.oact = poAct
obj.Show()

View File

@@ -0,0 +1,58 @@
# _precompile.ps1 -Prg <cale.prg> - regenereaza .fxp-ul target intr-un proces IZOLAT.
# De ce izolat: precompilarea (vfp9 -A ... COMPILE) atarna dupa COMPILE si e omorata; daca
# ruleaza in ACEEASI sesiune powershell care lanseaza apoi testul, lansarile ulterioare de
# vfp9 esueaza (deschid editorul in loc sa ruleze). Rulat ca proces separat (Start-Process
# -Wait din harness), nu otraveste sesiunea care lanseaza testul.
param([Parameter(Mandatory=$true)][string]$Prg)
$Vfp = 'C:\Program Files (x86)\Microsoft Visual FoxPro 9\vfp9.exe'
$Fxp = [System.IO.Path]::ChangeExtension($Prg, 'fxp')
$dir = [System.IO.Path]::GetDirectoryName($Prg)
$tmpPrg = Join-Path $dir '_compile_tmp.prg'
# prg temporar care compileaza target-ul (COMPILE cu variabila; forma cu literal in ghilimele da eroare)
Set-Content -Path $tmpPrg -Value ("lcT = `"$Prg`"`r`nCOMPILE (lcT)`r`nQUIT`r`n") -Encoding ascii
Get-Process vfp9 -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
Start-Sleep -Milliseconds 500
if (Test-Path $Fxp) { [System.IO.File]::Delete($Fxp) }
# Fara furt de focus: fereastra vfp9 a compilarii (chiar tranzitorie) e impinsa off-screen,
# la fel ca in vfp_ui_harness.ps1 (SetWindowPos HWND_BOTTOM + NOACTIVATE, x=-4000).
Add-Type @"
using System;
using System.Runtime.InteropServices;
public class Win32UiPc {
[DllImport("user32.dll")]
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
[DllImport("user32.dll")]
public static extern bool IsWindow(IntPtr hWnd);
public static readonly IntPtr HWND_BOTTOM = new IntPtr(1);
public const uint SWP_NOSIZE = 0x0001;
public const uint SWP_NOACTIVATE = 0x0010;
}
"@
function Push-OffscreenPc([IntPtr]$Hwnd) {
if ($Hwnd -eq [IntPtr]::Zero -or -not [Win32UiPc]::IsWindow($Hwnd)) { return }
[Win32UiPc]::SetWindowPos($Hwnd, [Win32UiPc]::HWND_BOTTOM, -4000, 0, 0, 0, ([Win32UiPc]::SWP_NOSIZE -bor [Win32UiPc]::SWP_NOACTIVATE)) | Out-Null
}
$ok = $false
foreach ($try in 1..3) {
$pcProc = Start-Process -FilePath $Vfp -ArgumentList @('-A', "`"$tmpPrg`"") -PassThru
$dl = (Get-Date).AddSeconds(30)
$pcHwnd = [IntPtr]::Zero
while (-not (Test-Path $Fxp) -and (Get-Date) -lt $dl) {
if ($pcHwnd -eq [IntPtr]::Zero -and -not $pcProc.HasExited) {
$pcProc.Refresh()
if ($pcProc.MainWindowHandle -ne [IntPtr]::Zero) { $pcHwnd = $pcProc.MainWindowHandle }
}
Push-OffscreenPc $pcHwnd
Start-Sleep -Milliseconds 300
}
Start-Sleep -Seconds 3
Get-Process vfp9 -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
Start-Sleep -Seconds 1
if (Test-Path $Fxp) { $ok = $true; break }
}
foreach ($f in @($tmpPrg, [System.IO.Path]::ChangeExtension($tmpPrg, 'fxp'))) {
if (Test-Path $f) { try { [System.IO.File]::Delete($f) } catch {} }
}
if ($ok) { exit 0 } else { exit 1 }

View File

@@ -0,0 +1,780 @@
* test_adauga_factura_ui.prg
* Test UI care introduce date PRIN FORMULARUL real de adaugare factura (clasa
* import_adauga_factura din COMUN\clase\ointroduceri.vcx), nu prin insert direct in tabel.
* Deschide dialogul, completeaza campurile programatic (contract construieste_todlg,
* "populabil programatic"), apeleaza actiunea OK (inainte_de_do_termin -> oParinte.
* do_adauga_factura) si verifica perechea baza+TVA rezultata in introdc. Foloseste
* harness-ul generic (ui_harness.prg + vfp_ui_harness.ps1) - dovada ca e reutilizabil.
*
* Scenarii (fara articole in rul_temp => sincronizeaza nu intra pe spargere/Oracle):
* pas0 nota goala; pas1 dialog LEI; pas2 rezultat LEI; pas3 dialog VALUTA (EUR curs 5);
* pas4 rezultat VALUTA; pas5 dialog DVI (TVA in vama); pas6 rezultat DVI.
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET DECIMALS TO 4
SET NULLDISPLAY TO ''
CLOSE DATABASES
PUBLIC gcUILog, gcSyncDir
gcUILog = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\test_adauga_factura_ui_log.txt"
gcSyncDir = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\uisync\"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcUILog)
ON ERROR DO AfErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
TRY
LOCAL gcAppPath, lcPath
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;' + ;
ADDBS(SUBSTR(gcAppPath,1,RAT([\],gcAppPath,2)))+[COMUNROA\]
SET PATH TO &lcPath ADDITIVE
DO AfLog WITH 'SET PATH OK'
*----- CLASE -----
SET CLASSLIB TO (gcAppPath + "comun\clase\appwiz") 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 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 wwdialogs.vcx ADDITIVE
SET CLASSLIB TO oimportxml.vcx ADDITIVE
SET CLASSLIB TO excelxml.vcx ADDITIVE
SET CLASSLIB TO orapoarte_obinv.vcx ADDITIVE
DO AfLog WITH 'SET CLASSLIB OK'
*----- PROCEDURI (mock amessagebox PRIMUL, ui_harness la final) -----
SET PROCEDURE TO PROCEDURI
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_amessagebox.prg" 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 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 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 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
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\ui_harness.prg" ADDITIVE
DO AfLog WITH 'SET PROCEDURE OK'
*----- Globale -----
PUBLIC gnPc, gnPval, gnPcant, gnPpret, gnPPretval, gnPCurs, gnPVal, gnPPretV, gnPPretVal
STORE 2 TO gnPc, gnPval, gnPVal
gnPcant = 3
STORE 4 TO gnPpret, gnPPretval, gnPPretVal, gnPPretV, gnPCurs
PUBLIC gl406, gcS, gnAn, gnLuna, gnIdFirma, gnIdSucursala, gcAcces, gcFirma
*-- SAFT (406) mereu activ in teste: exercita GetTaxCode/GetTaxCodeIdPart/taxcode pe randuri.
gl406 = .T.
gcS = 'CONTAFIN'
gnAn = YEAR(DATE())
gnLuna = MONTH(DATE())
gnIdFirma = 110
gnIdSucursala = 110
gcAcces = "1;2;3;4;5;6;7;8;"
gcFirma = gcS
PUBLIC nror(65000)
PUBLIC goExecutor, goApp
goExecutor = CREATEOBJECT('dummyexecutor')
goApp = CREATEOBJECT('dummyapp')
*----- poAct: antetul notei; dialogul mosteneste din el la Init -----
PUBLIC poAct
poAct = CREATEOBJECT('Custom')
poAct.AddProperty('nume_val', '')
poAct.AddProperty('curs', 1)
poAct.AddProperty('proc_tva', 1.19)
poAct.AddProperty('nnir', 0)
poAct.AddProperty('id_valuta', 0)
poAct.AddProperty('id_fdoc', 1)
poAct.AddProperty('fdoc', 'Factura')
poAct.AddProperty('id_partc', 500)
poAct.AddProperty('partc', 'FURNIZOR ANTET SRL')
poAct.AddProperty('serie_act', '')
poAct.AddProperty('dataact', DATE())
poAct.AddProperty('tva_incasare', 0)
poAct.AddProperty('id_set', 1)
poAct.AddProperty('id_gestin', 1)
*----- jtva_coloane2 (explicatii TVA): perechi REALE (Oracle dev, vjtva_coloane, 17.07.2026),
* regimul curent 21%/11% (post 01.08.2025) + import (DVI). id_tva pe baza leaga spre
* coloana T (aplica_explicatie_tva); explicatia T e IN TANDEM cu baza ("TVA " + baza). -----
IF USED('jtva_coloane2')
USE IN ('jtva_coloane2')
ENDIF
CREATE CURSOR jtva_coloane2 (ordine N(8), id_jtva_coloana N(14), denumire C(100), ;
jc N(1), jv N(1), afisat N(1), coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14))
INSERT INTO jtva_coloane2 VALUES (0, 0, '', 0, 0, 1, '', '', 0, 0)
*-- achizitii interne 21% (id_tva pointeaza spre coloana T pereche, ca in aplica_explicatie_tva)
INSERT INTO jtva_coloane2 VALUES (1, 208, 'ACH. INT. 21%', 1, 0, 1, 'RO21B', 'RO21T', 21, 209)
INSERT INTO jtva_coloane2 VALUES (2, 209, 'TVA ACH. INT. 21%', 1, 0, 1, 'RO21T', '', 21, 0)
*-- import (DVI: TVA achitat in vama) 21% - alta coloana decat achizitiile interne
INSERT INTO jtva_coloane2 VALUES (3, 220, 'ACH. IMP. 21%', 1, 0, 1, 'FO21B', 'FO21T', 21, 221)
INSERT INTO jtva_coloane2 VALUES (4, 221, 'TVA ACH. IMP. 21%', 1, 0, 1, 'FO21T', '', 21, 0)
*----- saft_taxtable: coduri reale (vsaft_taxtable) - achizitii interne 21% vs import 21% -----
IF USED('saft_taxtable')
USE IN ('saft_taxtable')
ENDIF
CREATE CURSOR saft_taxtable (taxname C(250) NULL, typename C(250) NULL, taxcode N(6) NULL, ;
taxtype N(3) NULL, descriere C(250) NULL, tip C(100) NULL, descriere_tip C(250) NULL, ;
procent_taxa N(7,2) NULL, procent_prorata N(7,2) NULL, inactiv N(1) NULL, tva N(1) NULL, ;
wht N(1) NULL, tva_achizitii N(1) NULL, tva_livrari N(1) NULL)
INDEX ON taxcode TAG taxcode
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('', 0, '', 0, 1, 1, 1, 1)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301104-Achizitii de bunuri si servicii taxabile cu cota de 21%, altele decat importurile si cele supuse masurilor de simplificare', 301104, '', 21, 1, 0, 1, 0)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301204-Import de bunuri cota 21%', 301204, '', 21, 1, 0, 1, 0)
*----- introdc (RecordSource Grid1) - porneste GOL, ca in fluxul real -----
DO CreeazaIntrodc WITH 'introdc'
*----- introdc_sablon: perechea-sablon (B 371/401 + T 4426/401) pe care do_adauga_factura o
* cloneaza. Randul T poarta cota implicita a sablonului (ca in fluxul real, unde sablonul
* vine din nota contabila configurata) - do_executa calculeaza TVA din T.ptva. Aici sablonul
* e deja configurat la 21% (aceeasi cota aleasa in dialog la toate scenariile de mai jos -
* cifrele de TVA raman corecte chiar daca aplica_explicatie_tva nu ajunge la randul T din
* cauza bugului doc_key); explicatia/taxcode pe T raman insa NEATINSE de cod - vezi
* VerificaTaxcodeTandem (B primeste taxcode corect, T ramane 0 - FAIL asteptat). -----
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%')
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%')
GO TOP IN introdc_sablon
*----- rul_temp cu 1 rand INAINTE de instantiere: altfel import_nota.Init il recreeaza din
* Oracle (rul_temp gol => llRulTempPlin=.F.) si GridArt isi pierde coloanele (eroare 1925).
* Randul se sterge dupa Show => scenariile ruleaza cu 0 articole (sincronizeaza nu intra
* pe spargere/assign_analitic/Oracle). -----
IF USED('rul_temp')
USE IN ('rul_temp')
ENDIF
CREATE CURSOR rul_temp (denumire C(100), codmat C(30), cant N(14,3), pret_val N(18,4), ;
pretd N(18,4), pret N(18,4), pret_lei N(18,4), cont C(10), acont C(20), serie C(30), ;
lot C(30), adata_expirare C(10), proc_disc N(6,2), cota_tva N(6,2))
INSERT INTO rul_temp (denumire, codmat, cant, pret, pret_lei, cont, cota_tva) ;
VALUES ('PLACEHOLDER', 'PH', 1, 1, 1, '371', 19)
DO AfLog WITH 'cursoare pregatite, CREATEOBJECT(import_nota)'
SELECT introdc
PUBLIC goObj
goObj = CREATEOBJECT('IMPORT_nota', .T.)
IF VARTYPE(goObj) <> 'O'
DO AfLog WITH 'FAIL: instantiere import_nota'
DO HarnessDone WITH 'done-error'
QUIT
ENDIF
goObj.oact = poAct
goObj.WindowType = 0
goObj.Visible = .T.
goObj.Show()
goObj.WindowState = 2
DOEVENTS FORCE
*-- golesc placeholder-ul cu ZAP (nu DELETE ALL): DELETE ALL lasa 1 rand fizic sters si
*-- pointerul la EOF, iar do_reface -> do_calculeaza_diferente face GO pe recno-ul de EOF
*-- (eroare 5). ZAP => RECCOUNT=0, Recno()=1, do_calculeaza_diferente ia ramura LOCATE (sigura).
SELECT rul_temp
ZAP
goObj.gridart.Refresh()
DOEVENTS FORCE
*========================= PAS 0: nota goala =========================
DO HarnessStep WITH 0, 'import_nota afisat, introdc gol (' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri)'
*========================= SCENARIU 1: factura in LEI =========================
PUBLIC goDlg
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = 5001
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 501
goDlg.cPartener = 'FURNIZOR INTERN SRL'
goDlg.cExplicatia = 'Marfa achizitionata lei'
goDlg.nSuma = 1000
goDlg.nSumaLei = 0
goDlg.nIdExplicatieTva = 208
goDlg.cExplicatieTva = 'ACH. INT. 21%'
goDlg.optTipTva.Value = 1
goDlg.chkInValutaCont.Value = 0
goDlg.chkParticipaValuta.Value = 1
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO HarnessStep WITH 1, 'dialog LEI completat (furnizor, nr 5001, suma 1000, TVA 21%)'
*-- toDlg construit INLINE in programul PRINCIPAL (ADDPROPERTY da eroare 11 din proceduri in
*-- acest runtime headless); valorile respecta exact dialog.construieste_todlg.
PUBLIC goT
DO AfLog WITH 'LEI: valideaza (pe dialog) = ' + TRANSFORM(goDlg.valideaza())
goT = CREATEOBJECT('Empty')
=ADDPROPERTY(goT,'serie_act',ALLTRIM(NVL(goDlg.cSerieAct,'')))
=ADDPROPERTY(goT,'nract',goDlg.nNract)
=ADDPROPERTY(goT,'dataact',goDlg.dDataAct)
=ADDPROPERTY(goT,'fdoc',goDlg.cFelDoc)
=ADDPROPERTY(goT,'id_fdoc',goDlg.nIdFdoc)
=ADDPROPERTY(goT,'id_partc',goDlg.nIdPartener)
=ADDPROPERTY(goT,'partc',goDlg.cPartener)
=ADDPROPERTY(goT,'explicatia',ALLTRIM(NVL(goDlg.cExplicatia,'')))
=ADDPROPERTY(goT,'suma',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,IIF(goDlg.nSumaLei<>0,goDlg.nSumaLei,ROUND(goDlg.nSuma*goDlg.nCurs,gnPC)),goDlg.nSuma))
=ADDPROPERTY(goT,'suma_val',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,goDlg.nSuma,0))
=ADDPROPERTY(goT,'in_valuta',goDlg.chkInValutaCont.Value)
=ADDPROPERTY(goT,'participa_valuta',(goDlg.chkParticipaValuta.Value=1))
=ADDPROPERTY(goT,'id_valuta',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nIdValuta,0))
=ADDPROPERTY(goT,'curs',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nCurs,0))
=ADDPROPERTY(goT,'nume_val',IIF(goDlg.chkInValutaCont.Value=1,ALLTRIM(NVL(goDlg.cValuta,'')),''))
=ADDPROPERTY(goT,'cTipTva',IIF(goDlg.optTipTva.Value=1,'F',IIF(goDlg.optTipTva.Value=2,'D','N')))
=ADDPROPERTY(goT,'id_jtva_coloana',goDlg.nIdExplicatieTva)
=ADDPROPERTY(goT,'dvi_serie',CHRTRAN(ALLTRIM(NVL(goDlg.cSerieDvi,'')),CHR(34),''))
=ADDPROPERTY(goT,'dvi_nract',goDlg.nNractDvi)
=ADDPROPERTY(goT,'dvi_dataact',goDlg.dDviData)
=ADDPROPERTY(goT,'dvi_id_fdoc',goDlg.nIdFdocDVI)
=ADDPROPERTY(goT,'dvi_fdoc',goDlg.cFelDocDvi)
=ADDPROPERTY(goT,'dvi_id_partc',goDlg.nDviIdPartener)
=ADDPROPERTY(goT,'dvi_partc',goDlg.cDviPartener)
=ADDPROPERTY(goT,'dvi_scc','401')
=ADDPROPERTY(goT,'dvi_tva_lei',goDlg.nDviTvaLei)
=ADDPROPERTY(goT,'dvi_tva_val',goDlg.nDviTvaVal)
DO AfLog WITH 'LEI: do_adauga_factura = ' + TRANSFORM(goObj.do_adauga_factura(goT))
goDlg.Hide()
DOEVENTS FORCE
DO VerificaPereche WITH 5001, 1, 1000, 210, 0, 0, ''
DO VerificaTaxcodeTandem WITH 5001, 301104
*========================= SCENARIU 2: factura in VALUTA (EUR curs 5) =========================
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = 5002
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 502
goDlg.cPartener = 'FURNIZOR EXTERN GMBH'
goDlg.cExplicatia = 'Marfa achizitionata valuta'
goDlg.nSuma = 200
goDlg.nSumaLei = 0
goDlg.nCurs = 5
goDlg.nIdValuta = 978
goDlg.cValuta = 'EUR'
goDlg.nIdExplicatieTva = 208
goDlg.cExplicatieTva = 'ACH. INT. 21%'
goDlg.optTipTva.Value = 1
goDlg.chkInValutaCont.Value = 1
goDlg.chkParticipaValuta.Value = 1
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO HarnessStep WITH 2, 'dialog VALUTA completat (EUR, suma 200, curs 5 => 1000 lei, TVA 21%)'
DO AfLog WITH 'VALUTA: valideaza (pe dialog) = ' + TRANSFORM(goDlg.valideaza())
goT = CREATEOBJECT('Empty')
=ADDPROPERTY(goT,'serie_act',ALLTRIM(NVL(goDlg.cSerieAct,'')))
=ADDPROPERTY(goT,'nract',goDlg.nNract)
=ADDPROPERTY(goT,'dataact',goDlg.dDataAct)
=ADDPROPERTY(goT,'fdoc',goDlg.cFelDoc)
=ADDPROPERTY(goT,'id_fdoc',goDlg.nIdFdoc)
=ADDPROPERTY(goT,'id_partc',goDlg.nIdPartener)
=ADDPROPERTY(goT,'partc',goDlg.cPartener)
=ADDPROPERTY(goT,'explicatia',ALLTRIM(NVL(goDlg.cExplicatia,'')))
=ADDPROPERTY(goT,'suma',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,IIF(goDlg.nSumaLei<>0,goDlg.nSumaLei,ROUND(goDlg.nSuma*goDlg.nCurs,gnPC)),goDlg.nSuma))
=ADDPROPERTY(goT,'suma_val',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,goDlg.nSuma,0))
=ADDPROPERTY(goT,'in_valuta',goDlg.chkInValutaCont.Value)
=ADDPROPERTY(goT,'participa_valuta',(goDlg.chkParticipaValuta.Value=1))
=ADDPROPERTY(goT,'id_valuta',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nIdValuta,0))
=ADDPROPERTY(goT,'curs',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nCurs,0))
=ADDPROPERTY(goT,'nume_val',IIF(goDlg.chkInValutaCont.Value=1,ALLTRIM(NVL(goDlg.cValuta,'')),''))
=ADDPROPERTY(goT,'cTipTva',IIF(goDlg.optTipTva.Value=1,'F',IIF(goDlg.optTipTva.Value=2,'D','N')))
=ADDPROPERTY(goT,'id_jtva_coloana',goDlg.nIdExplicatieTva)
=ADDPROPERTY(goT,'dvi_serie',CHRTRAN(ALLTRIM(NVL(goDlg.cSerieDvi,'')),CHR(34),''))
=ADDPROPERTY(goT,'dvi_nract',goDlg.nNractDvi)
=ADDPROPERTY(goT,'dvi_dataact',goDlg.dDviData)
=ADDPROPERTY(goT,'dvi_id_fdoc',goDlg.nIdFdocDVI)
=ADDPROPERTY(goT,'dvi_fdoc',goDlg.cFelDocDvi)
=ADDPROPERTY(goT,'dvi_id_partc',goDlg.nDviIdPartener)
=ADDPROPERTY(goT,'dvi_partc',goDlg.cDviPartener)
=ADDPROPERTY(goT,'dvi_scc','401')
=ADDPROPERTY(goT,'dvi_tva_lei',goDlg.nDviTvaLei)
=ADDPROPERTY(goT,'dvi_tva_val',goDlg.nDviTvaVal)
DO AfLog WITH 'VALUTA: do_adauga_factura = ' + TRANSFORM(goObj.do_adauga_factura(goT))
goDlg.Hide()
DOEVENTS FORCE
*-- baza: suma lei = 200*5 = 1000, suma_val=200, in_valuta=1, curs=5, nume_val=EUR
*-- TVA: suma lei = 1000*21% = 210, suma_val = 200*21% = 42
DO VerificaPereche WITH 5002, 1, 1000, 210, 200, 42, 'EUR'
DO VerificaTaxcodeTandem WITH 5002, 301104
*========================= SCENARIU 3: factura cu TVA pe DVI (import extracomunitar) =========================
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = 5003
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 503
goDlg.cPartener = 'FURNIZOR CHINA LTD'
goDlg.cExplicatia = 'Import extracomunitar'
goDlg.nSuma = 1000
goDlg.nSumaLei = 0
*-- ACH. IMP. 21% (id 220) - coloana de IMPORT, distincta de achizitiile interne (208):
*-- domeniu corect pentru DVI (marfa din import, TVA platit in vama), nu ACH. INT.
goDlg.nIdExplicatieTva = 220
goDlg.cExplicatieTva = 'ACH. IMP. 21%'
goDlg.optTipTva.Value = 2
goDlg.chkInValutaCont.Value = 0
goDlg.chkParticipaValuta.Value = 1
*-- date DVI (TVA achitat in vama, alt document/partener/cont)
goDlg.cSerieDvi = ''
goDlg.nNractDvi = 7003
goDlg.dDviData = DATE()
goDlg.nIdFdocDVI = 2
goDlg.cFelDocDvi = 'DVI'
goDlg.nDviIdPartener = 900
goDlg.cDviPartener = 'DIRECTIA VAMALA'
goDlg.nDviTvaLei = 210
goDlg.nDviTvaVal = 0
*-- actualizeaza_stare_dvi() nu porneste singur din Value=2 (doar InteractiveChange, pe
*-- interactiune reala) - il apelez explicit ca subrandul DVI sa fie vizibil in screenshot.
goDlg.actualizeaza_stare_dvi()
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO HarnessStep WITH 3, 'dialog DVI completat (baza 1000 furnizor, TVA 210 pe DVI la VAMA, bifa DVI)'
DO AfLog WITH 'DVI: valideaza (pe dialog) = ' + TRANSFORM(goDlg.valideaza())
goT = CREATEOBJECT('Empty')
=ADDPROPERTY(goT,'serie_act',ALLTRIM(NVL(goDlg.cSerieAct,'')))
=ADDPROPERTY(goT,'nract',goDlg.nNract)
=ADDPROPERTY(goT,'dataact',goDlg.dDataAct)
=ADDPROPERTY(goT,'fdoc',goDlg.cFelDoc)
=ADDPROPERTY(goT,'id_fdoc',goDlg.nIdFdoc)
=ADDPROPERTY(goT,'id_partc',goDlg.nIdPartener)
=ADDPROPERTY(goT,'partc',goDlg.cPartener)
=ADDPROPERTY(goT,'explicatia',ALLTRIM(NVL(goDlg.cExplicatia,'')))
=ADDPROPERTY(goT,'suma',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,IIF(goDlg.nSumaLei<>0,goDlg.nSumaLei,ROUND(goDlg.nSuma*goDlg.nCurs,gnPC)),goDlg.nSuma))
=ADDPROPERTY(goT,'suma_val',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,goDlg.nSuma,0))
=ADDPROPERTY(goT,'in_valuta',goDlg.chkInValutaCont.Value)
=ADDPROPERTY(goT,'participa_valuta',(goDlg.chkParticipaValuta.Value=1))
=ADDPROPERTY(goT,'id_valuta',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nIdValuta,0))
=ADDPROPERTY(goT,'curs',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nCurs,0))
=ADDPROPERTY(goT,'nume_val',IIF(goDlg.chkInValutaCont.Value=1,ALLTRIM(NVL(goDlg.cValuta,'')),''))
=ADDPROPERTY(goT,'cTipTva',IIF(goDlg.optTipTva.Value=1,'F',IIF(goDlg.optTipTva.Value=2,'D','N')))
=ADDPROPERTY(goT,'id_jtva_coloana',goDlg.nIdExplicatieTva)
=ADDPROPERTY(goT,'dvi_serie',CHRTRAN(ALLTRIM(NVL(goDlg.cSerieDvi,'')),CHR(34),''))
=ADDPROPERTY(goT,'dvi_nract',goDlg.nNractDvi)
=ADDPROPERTY(goT,'dvi_dataact',goDlg.dDviData)
=ADDPROPERTY(goT,'dvi_id_fdoc',goDlg.nIdFdocDVI)
=ADDPROPERTY(goT,'dvi_fdoc',goDlg.cFelDocDvi)
=ADDPROPERTY(goT,'dvi_id_partc',goDlg.nDviIdPartener)
=ADDPROPERTY(goT,'dvi_partc',goDlg.cDviPartener)
=ADDPROPERTY(goT,'dvi_scc','401')
=ADDPROPERTY(goT,'dvi_tva_lei',goDlg.nDviTvaLei)
=ADDPROPERTY(goT,'dvi_tva_val',goDlg.nDviTvaVal)
*-- ramura DVI din do_adauga_factura repozitioneaza pe randul T cu Go pe Recno() salvat la
*-- creare (ointroduceri.prg ~10195), apoi il re-cheie pe VAMA (nract=dvi_nract, partc=DIRECTIA
*-- VAMALA). TRY/CATCH local ramane ca plasa de siguranta, testul continua si raporteaza clar.
LOCAL llDviEroare
llDviEroare = .F.
TRY
DO AfLog WITH 'DVI: do_adauga_factura = ' + TRANSFORM(goObj.do_adauga_factura(goT))
CATCH TO loExcDvi
llDviEroare = .T.
DO AfLog WITH 'DVI EROARE ' + TRANSFORM(loExcDvi.ErrorNo) + ' [' + loExcDvi.Message + '] in ' + ;
loExcDvi.Procedure + ':' + TRANSFORM(loExcDvi.LineNo) + ' -> BUG REAL confirmat (doc_key), ' + ;
'vezi docs\handoff_teste_ui_import.md (' + loExcDvi.LineContents + ')'
ENDTRY
goDlg.Hide()
DOEVENTS FORCE
DO HarnessStep WITH 4, 'DVI dupa do_adauga_factura: eroare=' + TRANSFORM(llDviEroare) + ' introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri'
IF !llDviEroare
*-- baza: partc furnizor, suma 1000, scd 371 (ramane pe nract=5003). TVA (DVI): randul T
*-- re-cheiat pe documentul vamal (nract=dvi_nract=7003), partc VAMA, suma 210, scd 4426.
DO VerificaDvi WITH 5003, 7003, 1000, 210
DO VerificaTaxcodeTandem WITH 5003, 301204, 7003
*-- anti-corupere: randul T al PRIMULUI document (5001, scenariul LEI) trebuie neatins de
*-- override-ul DVI - bugul original (Locate For doc_key==calc_doc_key() degenerat) landa
*-- pe primul rand T scanat din cursor si il corupea pe ACELA in loc de randul curent.
DO VerificaRandNeatins WITH 5001, 210, 'FURNIZOR INTERN SRL'
*-- DIAGNOSTIC (investigare, nu modifica cod aplicatie): scanez TOT introdc dupa DVI,
*-- ca sa vad daca override-ul a corupt alt document (calc_doc_key() pe pointer gresit).
DO AfLog WITH 'DIAG dump integral introdc dupa DVI:'
SELECT introdc
SCAN
DO AfLog WITH ' recno=' + TRANSFORM(RECNO()) + ' nract=' + TRANSFORM(nract) + ' tip_rand=' + tip_rand + ;
' scd=' + ALLTRIM(scd) + ' suma=' + TRANSFORM(suma) + ' partc=[' + ALLTRIM(NVL(partc,'')) + ;
'] doc_key=[' + ALLTRIM(doc_key) + ']'
ENDSCAN
ELSE
DO AfLog WITH 'DVI: VerificaDvi/VerificaTaxcodeTandem SARITE (do_adauga_factura a aruncat eroare - vezi mesajul de mai sus)'
ENDIF
DO AfLog WITH 'GATA - toate scenariile executate'
DO HarnessStep WITH 5, 'final: introdc are ' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri'
DO HarnessDone WITH 'done'
CATCH TO loExc
DO AfLog WITH 'CATCH ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']'
DO HarnessDone WITH 'done-error'
ENDTRY
QUIT
*==================================================================================
PROCEDURE CreeazaIntrodc
*-- structura introdc (RecordSource Grid1 import_nota), identica pt. introdc si introdc_sablon
LPARAMETERS tcAlias
IF USED(tcAlias)
USE IN (tcAlias)
ENDIF
CREATE CURSOR (tcAlias) ( ;
id_note N(14), explicatia C(100), scd C(10), ascd C(20), scc C(10), ascc C(20), ;
cu_tva N(1), id_set N(14), ordine N(8), in_valuta N(1), id_jtva_coloana N(14) NULL, ;
ptva N(6,2), explicatie_tva C(50), tipjurnal C(2), taxcode N(6), paymentcode C(9), ;
suma N(18,4), suma_val N(18,4), id_partd N(14), id_partc N(14), partd C(100), partc C(100), ;
id_fact N(14), id_factd N(14), id_factc N(14), pereched N(14), perechec N(14), ;
nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), ;
scd_orig C(20), ascd_orig C(20))
ENDPROC
PROCEDURE VerificaPereche
*-- verifica perechea B+T adaugata (dupa nract): sume lei/valuta, valuta pe baza
LPARAMETERS tnNract, tnPas, tnBazaLei, tnTvaLei, tnBazaVal, tnTvaVal, tcVal
LOCAL lnSel, lcMsg, llB, llT, lnBS, lnTS, lnBSV, lcNV, lnInV
lnSel = SELECT()
SELECT introdc
lcMsg = ''
LOCATE FOR nract = tnNract AND tip_rand == 'B'
llB = FOUND()
IF llB
lnBS = suma
lnBSV = suma_val
lcNV = ALLTRIM(NVL(nume_val,''))
lnInV = in_valuta
ENDIF
LOCATE FOR nract = tnNract AND tip_rand == 'T'
llT = FOUND()
IF llT
lnTS = suma
lnTSV = suma_val
ENDIF
IF llB AND llT AND ABS(lnBS - tnBazaLei) < 0.01 AND ABS(lnTS - tnTvaLei) < 0.01 ;
AND ABS(lnBSV - tnBazaVal) < 0.01 AND ALLTRIM(NVL(lcNV,'')) == tcVal
lcMsg = 'PASS scenariu nract=' + TRANSFORM(tnNract) + ': B(suma=' + TRANSFORM(lnBS) + ' val=' + TRANSFORM(lnBSV) + ' ' + lcNV + ') + T(suma=' + TRANSFORM(lnTS) + ')'
ELSE
lcMsg = 'FAIL scenariu nract=' + TRANSFORM(tnNract) + ': B?=' + TRANSFORM(llB) + ' T?=' + TRANSFORM(llT) + ' bazaLei=' + TRANSFORM(IIF(llB,lnBS,-1)) + '(astept ' + TRANSFORM(tnBazaLei) + ') tvaLei=' + TRANSFORM(IIF(llT,lnTS,-1)) + '(astept ' + TRANSFORM(tnTvaLei) + ') bazaVal=' + TRANSFORM(IIF(llB,lnBSV,-1)) + '(astept ' + TRANSFORM(tnBazaVal) + ') val=[' + IIF(llB,lcNV,'?') + '](astept [' + tcVal + '])'
ENDIF
DO AfLog WITH lcMsg
SELECT (lnSel)
ENDPROC
PROCEDURE VerificaDvi
*-- DVI: baza pe furnizor (nract original, scd 371, suma). Randul T (scd 4426, suma TVA) e
*-- re-cheiat de override pe documentul vamal (nract=tnNractDvi, partc=DIRECTIA VAMALA), prin
*-- Go pe Recno() salvat la creare (linia ~10195), nu mai Locate For doc_key==calc_doc_key().
LPARAMETERS tnNract, tnNractDvi, tnBazaLei, tnTvaLei
LOCAL lnSel, lcMsg, llB, llT, lnBS, lnTS, lcTScd, lcTPartc, llVama, llRamasitaT
lnSel = SELECT()
SELECT introdc
LOCATE FOR nract = tnNract AND tip_rand == 'B'
llB = FOUND()
IF llB
lnBS = suma
ENDIF
*-- randul T al documentului vamal (scd 4426); citesc suma si partenerul ca sa vad daca override-ul a aplicat
LOCATE FOR nract = tnNractDvi AND tip_rand == 'T'
llT = FOUND()
IF llT
lnTS = suma
lcTScd = ALLTRIM(scd)
lcTPartc = ALLTRIM(NVL(partc,''))
llVama = ('VAMAL' $ UPPER(lcTPartc))
ENDIF
*-- randul T NU trebuie sa mai existe sub nract-ul original al facturii (a fost re-cheiat, nu duplicat)
LOCATE FOR nract = tnNract AND tip_rand == 'T'
llRamasitaT = FOUND()
IF llB AND llT AND !llRamasitaT AND ABS(lnBS - tnBazaLei) < 0.01 AND ABS(lnTS - tnTvaLei) < 0.01 AND llVama
lcMsg = 'PASS scenariu DVI: B(furnizor nract=' + TRANSFORM(tnNract) + ', suma=' + TRANSFORM(lnBS) + ') + T_DVI(nract=' + TRANSFORM(tnNractDvi) + ' scd=' + lcTScd + ' partc=' + lcTPartc + ' suma=' + TRANSFORM(lnTS) + ')'
ELSE
lcMsg = 'FAIL scenariu DVI: B(suma=' + TRANSFORM(IIF(llB,lnBS,-1)) + ', astept ' + TRANSFORM(tnBazaLei) + ') + T_DVI(nract=' + TRANSFORM(tnNractDvi) + ' scd=' + IIF(llT,lcTScd,'?') + ' suma=' + TRANSFORM(IIF(llT,lnTS,-1)) + ', astept ' + TRANSFORM(tnTvaLei) + ' partc=' + IIF(llT,lcTPartc,'?') + ', astept VAMA) ramasita T pe nract original=' + TRANSFORM(llRamasitaT) + ' (astept .F.)'
ENDIF
DO AfLog WITH lcMsg
SELECT (lnSel)
ENDPROC
PROCEDURE VerificaRandNeatins
*-- anti-corupere: verifica ca randul T al unui document ANTERIOR (deja adaugat) a ramas
*-- neatins dupa un scenariu ulterior (ex. DVI). Regresie pentru bugul original: Locate For
*-- doc_key==calc_doc_key() degenerat landa pe primul rand T scanat din cursor (nu neaparat
*-- cel al documentului curent) si il corupea pe ACELA - fix: Go pe Recno() salvat la creare.
LPARAMETERS tnNract, tnSumaAsteptata, tcPartcAsteptat
LOCAL lnSel, lcMsg, llT, lnS, lcScd, lcPartc
lnSel = SELECT()
SELECT introdc
LOCATE FOR nract = tnNract AND tip_rand == 'T'
llT = FOUND()
IF llT
lnS = suma
lcScd = ALLTRIM(scd)
lcPartc = ALLTRIM(NVL(partc,''))
ENDIF
IF llT AND lcScd == '4426' AND ABS(lnS - tnSumaAsteptata) < 0.01 AND lcPartc == tcPartcAsteptat
lcMsg = 'PASS anti-corupere randul T nract=' + TRANSFORM(tnNract) + ' neatins (scd=' + lcScd + ' suma=' + TRANSFORM(lnS) + ' partc=' + lcPartc + ')'
ELSE
lcMsg = 'FAIL anti-corupere randul T nract=' + TRANSFORM(tnNract) + ': gasit=' + TRANSFORM(llT) + ' scd=' + IIF(llT,lcScd,'?') + ' suma=' + TRANSFORM(IIF(llT,lnS,-1)) + ' partc=[' + IIF(llT,lcPartc,'?') + '] (astept scd=4426 suma=' + TRANSFORM(tnSumaAsteptata) + ' partc=[' + tcPartcAsteptat + '])'
ENDIF
DO AfLog WITH lcMsg
SELECT (lnSel)
ENDPROC
PROCEDURE VerificaTaxcodeTandem
*-- Taxcode SAFT (406) IN TANDEM baza+TVA, scris de aplica_explicatie_tva -> Thisform.
*-- UpdateExplicatieSAFT() -> GetTaxCodeIdPart() (gl406=.T. obligatoriu, vezi oproceduri_comune.prg).
*-- Randul B: Replace-ul + UpdateExplicatieSAFT ruleaza pe randul curent - taxcode corect.
*-- Randul T: taxcode-ul se aplica INAINTE de eventuala re-cheiere pe DVI, dar identitatea
*-- randului dupa do_adauga_factura se verifica pe nract-ul FINAL (tnNractT, implicit = tnNract
*-- pentru facturi normale; = dvi_nract pentru scenariul DVI, vezi apelul cu 3 parametri).
LPARAMETERS tnNract, tnTaxcodeAsteptat, tnNractT
LOCAL lnSel, lcMsg, llB, llT, lnTaxB, lnTaxT, lnNractT
lnSel = SELECT()
lnNractT = IIF(PCOUNT() >= 3 AND tnNractT # 0, tnNractT, tnNract)
SELECT introdc
LOCATE FOR nract = tnNract AND tip_rand == 'B'
llB = FOUND()
IF llB
lnTaxB = NVL(taxcode, -1)
ENDIF
LOCATE FOR nract = lnNractT AND tip_rand == 'T'
llT = FOUND()
IF llT
lnTaxT = NVL(taxcode, -1)
ENDIF
IF llB AND lnTaxB = tnTaxcodeAsteptat
lcMsg = 'PASS taxcode randul B (nract=' + TRANSFORM(tnNract) + '): taxcode=' + TRANSFORM(lnTaxB) + ' (SAFT corect, aplicat direct de UpdateExplicatieSAFT)'
ELSE
lcMsg = 'FAIL taxcode randul B (nract=' + TRANSFORM(tnNract) + '): gasit=' + TRANSFORM(llB) + ' taxcode=' + TRANSFORM(IIF(llB,lnTaxB,-1)) + ' (astept ' + TRANSFORM(tnTaxcodeAsteptat) + ')'
ENDIF
DO AfLog WITH lcMsg
IF llT AND lnTaxT = tnTaxcodeAsteptat
DO AfLog WITH 'PASS taxcode randul T (tandem, nract=' + TRANSFORM(lnNractT) + '): taxcode=' + TRANSFORM(lnTaxT)
ELSE
DO AfLog WITH 'FAIL taxcode randul T (tandem, nract=' + TRANSFORM(lnNractT) + '): gasit=' + TRANSFORM(llT) + ' taxcode=' + TRANSFORM(IIF(llT,lnTaxT,-1)) + ' (astept ' + TRANSFORM(tnTaxcodeAsteptat) + ')'
ENDIF
SELECT (lnSel)
ENDPROC
FUNCTION RECCOUNT_ACTIVE
LPARAMETERS tcAlias
LOCAL lnSel, lnCnt
lnSel = SELECT()
SELECT (tcAlias)
COUNT TO lnCnt FOR !DELETED()
SELECT (lnSel)
RETURN lnCnt
ENDFUNC
PROCEDURE AfErr
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
DO AfLog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
ENDPROC
PROCEDURE AfLog
LPARAMETERS tcMsg
SET SAFETY OFF
LOCAL lcL
lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '')
STRTOFILE(lcL + tcMsg + CHR(13)+CHR(10), gcUILog)
ENDPROC
DEFINE CLASS dummyapp AS Custom
PROCEDURE ReadIni
LPARAMETERS tcSection, tcKey
RETURN ''
ENDPROC
PROCEDURE WriteIni
LPARAMETERS tcSection, tcKey, tcValue
RETURN .T.
ENDPROC
ENDDEFINE
DEFINE CLASS dummyexecutor AS Custom
cEroare = ''
PROCEDURE oExecute
LPARAMETERS tcSql, tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
*-- update_jtva_coloane (SELECT * FROM vjtva_coloane ...): mock cu date reale (jtva_coloane,
*-- jtva_coloane_taxcode - mod 6, cu campurile taxcode*) - vezi GetTaxCode/GetTaxCodeIdPart.
IF 'VJTVA_COLOANE' $ UPPER(m.tcSql)
DO CreeazaJtvaColoaneView WITH m.tcCursor
RETURN 1
ENDIF
*-- rul_temp (recreat de import_nota.Init din vrul cand e gol): structura completa
*-- ceruta de coloanele GridArt, altfel grila isi pierde coloanele (eroare 1925).
IF UPPER(ALLTRIM(m.tcCursor)) == 'RUL_TEMP'
CREATE CURSOR (m.tcCursor) (denumire C(100), codmat C(30), cant N(14,3), ;
pret_val N(18,4), pretd N(18,4), pret N(18,4), pret_lei N(18,4), cont C(10), ;
acont C(20), serie C(30), lot C(30), adata_expirare C(10), proc_disc N(6,2), cota_tva N(6,2))
ELSE
CREATE CURSOR (m.tcCursor) (id_temp N(1))
ENDIF
RETURN 1
ENDPROC
PROCEDURE oExecuta
LPARAMETERS tcSql, tcCursor
IF !EMPTY(m.tcCursor)
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF UPPER(m.tcCursor) == 'CJTVACOL4427'
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14))
ELSE
CREATE CURSOR (m.tcCursor) (id_temp N(1))
ENDIF
ENDIF
RETURN .T.
ENDPROC
PROCEDURE oSelect2Value
*-- GetCodFiscalPartenerById (oproceduri_comune.prg): cod fiscal gol => VERIFICA_RTVAI
*-- vede llIsCIF=.F. si sare peste apelul PACK_ROARTVAI (fara Oracle real).
LPARAMETERS tcSql, toValue
toValue = ''
RETURN 1
ENDPROC
PROCEDURE oReset
*-- update_jtva_coloane() il apeleaza necondit dupa oExecute (updateserver.prg:611).
ENDPROC
ENDDEFINE
PROCEDURE CreeazaJtvaColoaneView
*-- Mock pentru "select * from vjtva_coloane ..." (update_jtva_coloane): perechi reale
*-- (Oracle dev, 17.07.2026) achizitii interne 21% + import 21%, cu taxcode SAFT diferentiat
*-- (301104 vs 301204) - vezi GetTaxCode.
LPARAMETERS tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14), denumire C(100), jc N(1), jv N(1), ;
coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14) NULL, afisat N(1), ;
id_jtva_ex N(14) NULL, id_jtva_neex N(14) NULL, ordine N(8), ;
taxcode N(6) NULL, taxcode_neexigibil N(6) NULL, taxcode_n50 N(6) NULL, ;
taxcode_n50_tvai N(6) NULL, taxcode_n100 N(6) NULL, taxcode_regularizare N(6) NULL, taxcode_tvai N(6) NULL)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, afisat, ordine, cota_tva) VALUES (0, '', 0, 0, 1, 0, 0)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (208, 'ACH. INT. 21%', 1, 0, 'RO21B', 21, 209, 1, 1, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (209, 'TVA ACH. INT. 21%', 1, 0, 'RO21T', 21, 1, 2, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (220, 'ACH. IMP. 21%', 1, 0, 'FO21B', 21, 221, 1, 3, 301204)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (221, 'TVA ACH. IMP. 21%', 1, 0, 'FO21T', 21, 1, 4, 301204)
ENDPROC

View File

@@ -0,0 +1,8 @@
# test_adauga_factura_ui.ps1 - wrapper peste harness-ul generic pentru testul adauga_factura.
# Rulare: powershell -ExecutionPolicy Bypass -File test_adauga_factura_ui.ps1
$ErrorActionPreference = 'Stop'
$Teste = $PSScriptRoot
& (Join-Path (Split-Path $Teste -Parent) 'vfp_ui_harness.ps1') `
-TestPrg (Join-Path $Teste 'test_adauga_factura_ui.prg') `
-Steps @('nota_goala','dialog_lei','dialog_valuta','dialog_dvi','dvi_rezultat_grila','final') `
-ShotsDir (Join-Path $Teste 'screenshots_adauga_factura')

View File

@@ -0,0 +1,884 @@
* test_adauga_repere_212.prg
* Extensie a test_scenariu_import_212.prg: Marius a testat manual in aplicatia reala si a
* gasit ca populatea directa a rul_temp (INSERT INTO) era INSUFICIENTA - nu trece prin fluxul
* real de adaugare articole (butonul "Adauga repere" -> import_nota.do_adauga_articol,
* COMUN\clase\ointroduceri.vcx). Aici articolul BULDOEXCAVATOR (cont 212) se adauga apeland
* REAL goObj.do_adauga_articol() dupa ce dialogul de cautare (modal, nu poate rula headless)
* e inlocuit cu mock_cauta_nom_articole.prg (returneaza acelasi format XML ca fluxul real,
* cauta_alfa.prg ~227/510) - vezi docs/testare-ui-vfp.md pentru reteta generala.
*
* Scenariu identic cu test_scenariu_import_212.prg pana la cele 3 documente (FACTURA 100 RAJA
* DVI valuta EUR curs 5.23, FACTURA 102 TRANS OIL MOTO DVI lei, FACTURA 103 BIROUL VAMAL TVA la
* furnizor), apoi:
* 1. goObj.do_adauga_articol() REAL (nu INSERT direct) - verifica daca articolul apare in
* rul_temp/grila dupa fluxul real (Problema 1 raportata de Marius: nu aparea deloc).
* 2. daca articolul a fost adaugat, completez cant/pret pe rand (do_adauga_articol NU seteaza
* cantitati/preturi - doar campurile din nomenclator+antet; utilizatorul le completeaza
* manual in grid dupa - simulez exact asta).
* 3. sincronizeaza() - verific mesajul benzii (Problema 2: repetare per document).
*
* Rulare:
* powershell -ExecutionPolicy Bypass -File test_adauga_repere_212.ps1
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET DECIMALS TO 4
SET NULLDISPLAY TO ''
CLOSE DATABASES
PUBLIC gcUILog, gcSyncDir
gcUILog = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\test_adauga_repere_212_log.txt"
gcSyncDir = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\uisync_repere212\"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcUILog)
ON ERROR DO ArErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
TRY
LOCAL gcAppPath, lcPath
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;' + ;
ADDBS(SUBSTR(gcAppPath,1,RAT([\],gcAppPath,2)))+[COMUNROA\]
SET PATH TO &lcPath ADDITIVE
DO ArLog WITH 'SET PATH OK'
*----- CLASE -----
SET CLASSLIB TO (gcAppPath + "comun\clase\appwiz") 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 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 wwdialogs.vcx ADDITIVE
SET CLASSLIB TO oimportxml.vcx ADDITIVE
SET CLASSLIB TO excelxml.vcx ADDITIVE
SET CLASSLIB TO orapoarte_obinv.vcx ADDITIVE
DO ArLog WITH 'SET CLASSLIB OK'
*----- PROCEDURI (mock amessagebox + mock cauta_nom_articole PRIMELE, ui_harness la final) -----
SET PROCEDURE TO PROCEDURI
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_cauta_nom_articole.prg" 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 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 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 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
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\ui_harness.prg" ADDITIVE
DO ArLog WITH 'SET PROCEDURE OK'
*----- Globale -----
PUBLIC gnPc, gnPval, gnPcant, gnPpret, gnPPretval, gnPCurs, gnPVal, gnPPretV, gnPPretVal
STORE 2 TO gnPc, gnPval, gnPVal
gnPcant = 3
STORE 4 TO gnPpret, gnPPretval, gnPPretVal, gnPPretV, gnPCurs
PUBLIC gl406, gcS, gnAn, gnLuna, gnIdFirma, gnIdSucursala, gcAcces, gcFirma
*-- SAFT (406) mereu activ in teste: exercita GetTaxCode/GetTaxCodeIdPart/taxcode pe randuri.
gl406 = .T.
gcS = 'CONTAFIN'
gnAn = YEAR(DATE())
gnLuna = MONTH(DATE())
gnIdFirma = 110
gnIdSucursala = 110
gcAcces = "1;2;3;4;5;6;7;8;"
gcFirma = gcS
PUBLIC nror(65000)
*-- gnButon: variabila "gola" folosita in tot lantul cauta_alfa->CAUT->do_adauga_articol.
*-- In aplicatia reala e declarata PRIVATE o singura data la pornire (Programe/roagest.prg:496)
*-- si ramane vizibila tot restul rularii; aici o declar PUBLIC pentru acelasi efect.
PUBLIC gnButon
STORE 2 TO gnButon
PUBLIC goExecutor, goApp
goExecutor = CREATEOBJECT('dummyexecutor')
goApp = CREATEOBJECT('dummyapp')
*----- poAct: antetul notei; dialogul mosteneste din el la Init -----
PUBLIC poAct
poAct = CREATEOBJECT('Custom')
poAct.AddProperty('nume_val', '')
poAct.AddProperty('curs', 1)
poAct.AddProperty('proc_tva', 1.21)
poAct.AddProperty('nnir', 0)
poAct.AddProperty('id_valuta', 0)
poAct.AddProperty('id_fdoc', 1)
poAct.AddProperty('fdoc', 'Factura')
poAct.AddProperty('id_partc', 500)
poAct.AddProperty('partc', 'FURNIZOR ANTET SRL')
poAct.AddProperty('serie_act', '')
poAct.AddProperty('dataact', DATE())
poAct.AddProperty('tva_incasare', 0)
poAct.AddProperty('id_set', 1)
poAct.AddProperty('id_gestin', 1)
*----- jtva_coloane2 (explicatii TVA): achizitii interne 21% + import (DVI) 21% - perechi
* reale (Oracle dev, vjtva_coloane, 17.07.2026), regimul curent 21%/11% post 01.08.2025. -----
IF USED('jtva_coloane2')
USE IN ('jtva_coloane2')
ENDIF
CREATE CURSOR jtva_coloane2 (ordine N(8), id_jtva_coloana N(14), denumire C(100), ;
jc N(1), jv N(1), afisat N(1), coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14))
INSERT INTO jtva_coloane2 VALUES (0, 0, '', 0, 0, 1, '', '', 0, 0)
INSERT INTO jtva_coloane2 VALUES (1, 208, 'ACH. INT. 21%', 1, 0, 1, 'RO21B', 'RO21T', 21, 209)
INSERT INTO jtva_coloane2 VALUES (2, 209, 'TVA ACH. INT. 21%', 1, 0, 1, 'RO21T', '', 21, 0)
INSERT INTO jtva_coloane2 VALUES (3, 220, 'ACH. IMP. 21%', 1, 0, 1, 'FO21B', 'FO21T', 21, 221)
INSERT INTO jtva_coloane2 VALUES (4, 221, 'TVA ACH. IMP. 21%', 1, 0, 1, 'FO21T', '', 21, 0)
*----- saft_taxtable: coduri reale (vsaft_taxtable) - achizitii interne 21% vs import 21% -----
IF USED('saft_taxtable')
USE IN ('saft_taxtable')
ENDIF
CREATE CURSOR saft_taxtable (taxname C(250) NULL, typename C(250) NULL, taxcode N(6) NULL, ;
taxtype N(3) NULL, descriere C(250) NULL, tip C(100) NULL, descriere_tip C(250) NULL, ;
procent_taxa N(7,2) NULL, procent_prorata N(7,2) NULL, inactiv N(1) NULL, tva N(1) NULL, ;
wht N(1) NULL, tva_achizitii N(1) NULL, tva_livrari N(1) NULL)
INDEX ON taxcode TAG taxcode
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('', 0, '', 0, 1, 1, 1, 1)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301104-Achizitii de bunuri si servicii taxabile cu cota de 21%, altele decat importurile si cele supuse masurilor de simplificare', 301104, '', 21, 1, 0, 1, 0)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301204-Import de bunuri cota 21%', 301204, '', 21, 1, 0, 1, 0)
*----- introdc (RecordSource Grid1) - porneste GOL, ca in fluxul real -----
DO CreeazaIntrodc WITH 'introdc'
*----- introdc_sablon: perechea-sablon (B 371/401 + T 4426/401) pe care do_adauga_factura o
* cloneaza; sablonul e la 21% (cota folosita in toate cele 3 scenarii de mai jos). -----
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%')
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%')
GO TOP IN introdc_sablon
*----- rul_temp cu 1 rand INAINTE de instantiere: altfel import_nota.Init il recreeaza din
* Oracle (rul_temp gol => llRulTempPlin=.F.) si GridArt isi pierde coloanele (eroare 1925).
* Randul se sterge dupa Show (ZAP, nu DELETE ALL - vezi docs/testare-ui-vfp.md capcana k).
* STRUCTURA FIDELA: rul_temp real = select r.*, r.pret as pret_lei, r.pretd as pret_val,
* 000.00 as cota_tva from vrul r where 1=2 (ointroduceri.vc2:11030) - coloanele VRUL sunt
* preluate direct din Oracle dev (all_tab_columns, owner=MARIUSM_AUTO, table=VRUL,
* 17.07.2026), nu aproximate; PROC_TVA exista in VRUL - eroarea 12 dintr-o rulare
* anterioara a testului ("Variable 'PROC_TVA' is not found") era artefact al unui mock
* trunchiat, nu bug de aplicatie (GATHER NAME loAct la :10107 populeaza rul_temp.proc_tva
* din poAct.proc_tva - camp valid pe randul curent, nu variabila globala). -----
DO CreeazaRulTemp
INSERT INTO rul_temp (denumire, codmat, cant, pret, pret_lei, cont, cota_tva) ;
VALUES ('PLACEHOLDER', 'PH', 1, 1, 1, '371', 21)
DO ArLog WITH 'cursoare pregatite, CREATEOBJECT(import_nota, .F.) - lIntern=.F. (import)'
SELECT introdc
PUBLIC goObj
*-- lIntern=.F. (import): sparge_document grupeaza articolele in valuta (pret_val*cant), ca
*-- in scenariul real al lui Marius. Activate() ar deschide automat dialogul modal "adauga
*-- factura" (This.do_adauga(), Show(1)) pentru !lIntern - blocheaza headless; il dezarmez
*-- cu lDialogAratat=.T. INAINTE de Show(), documentele se adauga manual mai jos.
goObj = CREATEOBJECT('IMPORT_nota', .F.)
IF VARTYPE(goObj) <> 'O'
DO ArLog WITH 'FAIL: instantiere import_nota'
DO HarnessDone WITH 'done-error'
QUIT
ENDIF
goObj.lDialogAratat = .T.
goObj.oact = poAct
goObj.WindowType = 0
goObj.Visible = .T.
goObj.Show()
goObj.WindowState = 2
DOEVENTS FORCE
*-- golesc placeholder-ul cu ZAP (nu DELETE ALL, vezi capcana k)
SELECT rul_temp
ZAP
goObj.gridart.Refresh()
DOEVENTS FORCE
*========================= DOC 1: FACTURA 100, RAJA, DVI valuta (EUR curs 5.23) =========================
PUBLIC goDlg, goT
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = 100
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 601
goDlg.cPartener = 'RAJA'
goDlg.cExplicatia = 'Import marfa RAJA'
goDlg.nSuma = 1000
goDlg.nSumaLei = 0
goDlg.nCurs = 5.23
goDlg.nIdValuta = 978
goDlg.cValuta = 'EUR'
*-- ACH. IMP. 21% (id 220) - coloana de import (SCD 371/SCC 401, taxcode SAFT 301204)
goDlg.nIdExplicatieTva = 220
goDlg.cExplicatieTva = 'ACH. IMP. 21%'
goDlg.optTipTva.Value = 2 && D = DVI
goDlg.chkInValutaCont.Value = 1
goDlg.chkParticipaValuta.Value = 1
*-- DVI: TVA achitat in vama (BIROUL VAMAL), doc 101, cont 4426/401
goDlg.cSerieDvi = ''
goDlg.nNractDvi = 101
goDlg.dDviData = DATE()
goDlg.nIdFdocDVI = 2
goDlg.cFelDocDvi = 'DVI'
goDlg.nDviIdPartener = 900
goDlg.cDviPartener = 'BIROUL VAMAL'
goDlg.nDviTvaLei = 1098.30
goDlg.nDviTvaVal = 210.00
goDlg.actualizeaza_stare_dvi()
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO ArLog WITH 'DOC1: valideaza (pe dialog) = ' + TRANSFORM(goDlg.valideaza())
DO ConstruiesteToDlg
DO ArLog WITH 'DOC1: do_adauga_factura = ' + TRANSFORM(goObj.do_adauga_factura(goT))
goDlg.Hide()
DOEVENTS FORCE
DO VerificaPereche WITH 100, 5230, 1000, 'EUR', .T.
DO VerificaDvi WITH 100, 101, 5230, 1098.30
*========================= DOC 2: FACTURA 102, TRANS OIL MOTO, DVI lei (acelasi doc vamal 101) =========================
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = 102
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 602
goDlg.cPartener = 'TRANS OIL MOTO'
goDlg.cExplicatia = 'Achizitie TRANS OIL MOTO'
goDlg.nSuma = 1000
goDlg.nSumaLei = 0
goDlg.nCurs = 0
goDlg.nIdExplicatieTva = 220
goDlg.cExplicatieTva = 'ACH. IMP. 21%'
goDlg.optTipTva.Value = 2 && D = DVI
goDlg.chkInValutaCont.Value = 0
goDlg.chkParticipaValuta.Value = 1
*-- ACELASI document vamal (nr 101, BIROUL VAMAL) ca la doc 1 - randul T se re-cheie pe
*-- acelasi doc_key ca T-ul doc 1 (identitate = serie_act+nract+id_fdoc+id_partc, calc_doc_key).
goDlg.cSerieDvi = ''
goDlg.nNractDvi = 101
goDlg.dDviData = DATE()
goDlg.nIdFdocDVI = 2
goDlg.cFelDocDvi = 'DVI'
goDlg.nDviIdPartener = 900
goDlg.cDviPartener = 'BIROUL VAMAL'
goDlg.nDviTvaLei = 210.00
goDlg.nDviTvaVal = 0
goDlg.actualizeaza_stare_dvi()
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO ArLog WITH 'DOC2: valideaza (pe dialog) = ' + TRANSFORM(goDlg.valideaza())
DO ConstruiesteToDlg
DO ArLog WITH 'DOC2: do_adauga_factura = ' + TRANSFORM(goObj.do_adauga_factura(goT))
goDlg.Hide()
DOEVENTS FORCE
DO VerificaPereche WITH 102, 1000, 0, '', .T.
DO VerificaSumaGrupVama WITH 101, 1308.30, 2
*========================= DOC 3: FACTURA 103, BIROUL VAMAL, TVA la furnizor (nu DVI) =========================
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = 103
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 900
goDlg.cPartener = 'BIROUL VAMAL'
goDlg.cExplicatia = 'Factura BIROUL VAMAL'
goDlg.nSuma = 500
goDlg.nSumaLei = 0
goDlg.nCurs = 0
*-- ACH. INT. 21% (id 208) - achizitie normala (nu import), TVA la furnizor
goDlg.nIdExplicatieTva = 208
goDlg.cExplicatieTva = 'ACH. INT. 21%'
goDlg.optTipTva.Value = 1 && F = furnizor
goDlg.chkInValutaCont.Value = 0
goDlg.chkParticipaValuta.Value = 1
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO ArLog WITH 'DOC3: valideaza (pe dialog) = ' + TRANSFORM(goDlg.valideaza())
DO ConstruiesteToDlg
DO ArLog WITH 'DOC3: do_adauga_factura = ' + TRANSFORM(goObj.do_adauga_factura(goT))
goDlg.Hide()
DOEVENTS FORCE
DO VerificaPereche WITH 103, 500, 0, ''
DO ArLog WITH 'DIAG dump introdc dupa cele 3 documente (inainte de articol):'
DO DumpIntrodc
*========================= PAS 0: cele 3 documente, structura B/T intacta (rul_temp gol) =========================
DO HarnessStep WITH 0, 'dupa 3 documente: introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri (astept 6, 3 perechi B/T), rul_temp=' + TRANSFORM(RECCOUNT_ACTIVE('rul_temp')) + ' articole'
*========================= ADAUGARE ARTICOL PRIN FLUXUL REAL: do_adauga_articol() =========================
*-- gnButon/XML furnizate de mock_cauta_nom_articole.prg (dialogul real e modal, nu ruleaza
*-- headless) - dar callback-ul care scrie in rul_temp e chiar do_adauga_articol REAL din clasa.
LOCAL lnRandInainte, lnRandDupa, llEroareAdauga
lnRandInainte = RECCOUNT_ACTIVE('rul_temp')
llEroareAdauga = .F.
TRY
goObj.do_adauga_articol()
CATCH TO loExcAdd
llEroareAdauga = .T.
DO ArLog WITH 'EROARE la do_adauga_articol() ' + TRANSFORM(loExcAdd.ErrorNo) + ' [' + loExcAdd.Message + ;
'] in ' + loExcAdd.Procedure + ':' + TRANSFORM(loExcAdd.LineNo) + ' (' + loExcAdd.LineContents + ')'
ENDTRY
DOEVENTS FORCE
goObj.gridart.Refresh()
DOEVENTS FORCE
lnRandDupa = RECCOUNT_ACTIVE('rul_temp')
DO ArLog WITH 'do_adauga_articol(): randuri rul_temp INAINTE=' + TRANSFORM(lnRandInainte) + ' DUPA=' + TRANSFORM(lnRandDupa) + ' eroare=' + TRANSFORM(llEroareAdauga) + ' gnButon=' + TRANSFORM(gnButon)
*-- VERIFICARE 0 (Problema 1 raportata de Marius): articolul BULDOEXCAVATOR apare in rul_temp?
LOCAL llArticolAdaugat
llArticolAdaugat = .F.
SELECT rul_temp
LOCATE FOR ALLTRIM(codmat) == 'ART-BULD-212'
IF FOUND()
llArticolAdaugat = .T.
DO ArLog WITH 'PASS verificare0: BULDOEXCAVATOR gasit in rul_temp dupa do_adauga_articol() REAL - denumire=' + ALLTRIM(denumire) + ' cont=[' + ALLTRIM(NVL(cont,'')) + '] cant=' + TRANSFORM(cant) + ' pret=' + TRANSFORM(pret) + ' pret_val=' + TRANSFORM(pret_val) + ' cota_tva=' + TRANSFORM(cota_tva) + ' id_gestiune=' + TRANSFORM(NVL(id_gestiune,-1)) + ' acont=[' + ALLTRIM(NVL(acont,'')) + ']'
ELSE
DO ArLog WITH 'FAIL verificare0: BULDOEXCAVATOR NU a fost gasit in rul_temp dupa do_adauga_articol() REAL - articolul se pierde in fluxul real (Problema 1 confirmata)'
ENDIF
*-- VERIFICARE 2 (runda4c dedup): sincronizeaza() a rulat deja in do_adauga_articol cu
*-- cant/pret 0 -> mesajul "cantitati/preturi" trebuie sa apara EXACT o data (nu per document)
LOCAL lnAparitiiPre
lnAparitiiPre = 0
DO WHILE AT('nu au inca cantitati', goObj.cmesajsync, lnAparitiiPre + 1) > 0
lnAparitiiPre = lnAparitiiPre + 1
ENDDO
IF lnAparitiiPre = 1
DO ArLog WITH 'PASS verificare2 (runda4c dedup, la cant=0): mesajul "cantitati/preturi" apare O SINGURA DATA in cmesajsync'
ELSE
DO ArLog WITH 'FAIL verificare2 (runda4c dedup, la cant=0): mesajul apare de ' + TRANSFORM(lnAparitiiPre) + ' ori (astept 1)'
ENDIF
*-- captura grila DUPA do_adauga_articol, INAINTE de completarea manuala cant/pret (developer
*-- vede exact ce lasa fluxul real: randul apare cu cant/pret 0 sau lipseste complet)
DO HarnessStep WITH 1, 'dupa do_adauga_articol() REAL: articol_adaugat=' + TRANSFORM(llArticolAdaugat) + ' rul_temp=' + TRANSFORM(lnRandDupa) + ' randuri (eroare=' + TRANSFORM(llEroareAdauga) + ')'
*-- daca articolul a fost adaugat, completez cant/pret (do_adauga_articol NU le seteaza -
*-- utilizatorul le tasteaza manual in grid; simulez exact asta, ca in scenariul lui Marius:
*-- 1 buc, 5230 lei / 1000 EUR, curs 5.23)
IF llArticolAdaugat
SELECT rul_temp
LOCATE FOR ALLTRIM(codmat) == 'ART-BULD-212'
REPLACE cant WITH 1, pret WITH 5230, pret_lei WITH 5230, pret_val WITH 1000, pretd WITH 1000
goObj.gridart.Refresh()
DOEVENTS FORCE
DO ArLog WITH 'cant/pret completate manual pe randul BULDOEXCAVATOR (simuleaza tastarea in grid)'
ENDIF
*========================= sincronizeaza() =========================
LOCAL llEroareSync
llEroareSync = .F.
TRY
goObj.sincronizeaza()
CATCH TO loExcSync
llEroareSync = .T.
DO ArLog WITH 'EROARE la sincronizeaza() ' + TRANSFORM(loExcSync.ErrorNo) + ' [' + loExcSync.Message + ;
'] in ' + loExcSync.Procedure + ':' + TRANSFORM(loExcSync.LineNo) + ' (' + loExcSync.LineContents + ')'
ENDTRY
DOEVENTS FORCE
goObj.grid1.Refresh()
DOEVENTS FORCE
IF !llEroareSync
DO ArLog WITH 'PASS verificare1: sincronizeaza() a rulat fara eroare'
ELSE
DO ArLog WITH 'FAIL verificare1: sincronizeaza() a aruncat eroare - vezi mesajul de mai sus'
ENDIF
LOCAL lnLenCaption, lcCaption, lcMesajSync, lnAparitiiMesaj
lcCaption = goObj.lblSync.Caption
lcMesajSync = goObj.cmesajsync
lnLenCaption = LEN(lcCaption)
DO ArLog WITH 'cmesajsync (' + TRANSFORM(LEN(lcMesajSync)) + ' caractere) = [' + lcMesajSync + ']'
DO ArLog WITH 'lblSync.Caption (' + TRANSFORM(lnLenCaption) + ' caractere) = [' + lcCaption + ']'
*-- runda4c (dedup aplicat in sparge_document): mesajul "cantitati/preturi" trebuie sa apara
*-- O SINGURA DATA in cmesajsync, nu o data per document (Problema 2, fix aplicat de Marius).
IF !EMPTY(lcMesajSync)
lnAparitiiMesaj = 0
LOCAL lnPosCaut, lcTextCautat
lcTextCautat = 'nu au inca cantitati'
lnPosCaut = 1
DO WHILE .T.
lnPosCaut = AT(lcTextCautat, lcMesajSync, lnAparitiiMesaj + 1)
IF lnPosCaut = 0
EXIT
ENDIF
lnAparitiiMesaj = lnAparitiiMesaj + 1
ENDDO
IF lnAparitiiMesaj <= 1
DO ArLog WITH 'PASS verificare2post (dupa completare cant/pret): mesajul "cantitati/preturi" apare de ' + TRANSFORM(lnAparitiiMesaj) + ' ori (0 = disparut legitim, niciodata >1)'
ELSE
DO ArLog WITH 'FAIL verificare2post (dupa completare cant/pret): mesajul "cantitati/preturi" apare de ' + TRANSFORM(lnAparitiiMesaj) + ' ori (astept <=1)'
ENDIF
IF lnLenCaption <= 254 AND LEFT(lcCaption, 15) == 'NESINCRONIZAT: '
DO ArLog WITH 'PASS verificare2b: Caption trunchiat corect la ' + TRANSFORM(lnLenCaption) + ' caractere (<=254), prefix NESINCRONIZAT: OK'
ELSE
DO ArLog WITH 'FAIL verificare2b: Caption lungime=' + TRANSFORM(lnLenCaption) + ' (astept <=254) prefix=[' + LEFT(lcCaption,15) + ']'
ENDIF
ELSE
DO ArLog WITH 'INFO verificare2: cmesajsync gol -> nota SINCRONIZATA'
ENDIF
*-- runda4c (spargere doar factura principala): dupa sincronizeaza(), doar documentul
*-- principal (primul B/S din introdc, aici nract=100/RAJA) trebuie spart in randuri S (cont
*-- 212); documentele 102 (TRANS OIL MOTO) si 103 (BIROUL VAMAL) trebuie sa ramana B/T
*-- neatinse (regula de domeniu: articolele apartin doar facturii principale).
LOCAL llDoc100Spart, llDoc102Nesparte, llDoc103Nesparte
SELECT introdc
LOCATE FOR nract = 100 AND tip_rand == 'S'
llDoc100Spart = FOUND()
LOCATE FOR nract = 102 AND tip_rand == 'B'
llDoc102Nesparte = FOUND()
LOCATE FOR nract = 103 AND tip_rand == 'B'
llDoc103Nesparte = FOUND()
IF llDoc100Spart AND llDoc102Nesparte AND llDoc103Nesparte
DO ArLog WITH 'PASS verificare3 (runda4c spargere doar principala): doc 100/RAJA spart (rand S gasit), doc 102/103 raman B/T nesparte'
ELSE
DO ArLog WITH 'FAIL verificare3 (runda4c spargere doar principala): doc100Spart=' + TRANSFORM(llDoc100Spart) + ' (astept .T.) doc102Nesparte=' + TRANSFORM(llDoc102Nesparte) + ' (astept .T.) doc103Nesparte=' + TRANSFORM(llDoc103Nesparte) + ' (astept .T.)'
ENDIF
*========================= PAS 2: dupa sincronizeaza() =========================
DO HarnessStep WITH 2, 'dupa sincronizeaza(): ' + IIF(EMPTY(lcMesajSync),'SINCRONIZAT','NESINCRONIZAT (' + TRANSFORM(LEN(lcMesajSync)) + ' car., mesaj repetat de ' + TRANSFORM(lnAparitiiMesaj) + ' ori)') + ' introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri'
*========================= do_executa() din nou + totaluri finale =========================
LOCAL llEroareExec
llEroareExec = .F.
TRY
goObj.do_executa()
CATCH TO loExcExec
llEroareExec = .T.
DO ArLog WITH 'EROARE la do_executa() ' + TRANSFORM(loExcExec.ErrorNo) + ' [' + loExcExec.Message + ;
'] in ' + loExcExec.Procedure + ':' + TRANSFORM(loExcExec.LineNo)
ENDTRY
goObj.recalculeaza()
goObj.actualizeaza_banda()
DOEVENTS FORCE
DO ArLog WITH 'DIAG dump introdc FINAL (dupa sincronizeaza+do_executa):'
DO DumpIntrodc
DO ArLog WITH 'DIAG dump rul_temp FINAL:'
SELECT rul_temp
SCAN
DO ArLog WITH ' denumire=' + ALLTRIM(denumire) + ' cont=' + ALLTRIM(NVL(cont,'')) + ' cant=' + TRANSFORM(cant) + ;
' pret=' + TRANSFORM(pret) + ' pret_val=' + TRANSFORM(pret_val) + ' cota_tva=' + TRANSFORM(cota_tva)
ENDSCAN
DO ArLog WITH 'TOTALURI FINALE: nbaza_lei=' + TRANSFORM(goObj.nbaza_lei) + ' ntva_lei=' + TRANSFORM(goObj.ntva_lei) + ;
' nbaza_val=' + TRANSFORM(goObj.nbaza_val) + ' ntva_val=' + TRANSFORM(goObj.ntva_val) + ;
' ndif_lei=' + TRANSFORM(goObj.ndif_lei) + ' ndif_val=' + TRANSFORM(goObj.ndif_val)
LOCAL lnSumaBazaDoc, lnSumaTvaDoc
SELECT SUM(IIF(tip_rand=='B' OR tip_rand=='S',suma,0)) AS s FROM introdc INTO CURSOR crsBazaTot NOFILTER
lnSumaBazaDoc = NVL(crsBazaTot.s,0)
USE IN crsBazaTot
SELECT SUM(IIF(tip_rand=='T',suma,0)) AS s FROM introdc INTO CURSOR crsTvaTot NOFILTER
lnSumaTvaDoc = NVL(crsTvaTot.s,0)
USE IN crsTvaTot
DO ArLog WITH 'TOTALURI PE RANDURI introdc: suma(B+S)=' + TRANSFORM(lnSumaBazaDoc) + ' (asteptare bruta B: 5230+1000+500=6730) suma(T)=' + TRANSFORM(lnSumaTvaDoc)
DO ArLog WITH 'GATA - scenariu executat integral'
DO HarnessStep WITH 3, 'final: introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri, articol_adaugat=' + TRANSFORM(llArticolAdaugat) + ' eroare_sync=' + TRANSFORM(llEroareSync) + ' eroare_exec=' + TRANSFORM(llEroareExec)
DO HarnessDone WITH 'done'
CATCH TO loExc
DO ArLog WITH 'CATCH ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']'
DO HarnessDone WITH 'done-error'
ENDTRY
QUIT
*==================================================================================
PROCEDURE ConstruiesteToDlg
*-- toDlg construit INLINE in programul PRINCIPAL (ADDPROPERTY da eroare 11 din proceduri in
*-- acest runtime headless - vezi docs/testare-ui-vfp.md capcana l); valorile respecta exact
*-- dialog.construieste_todlg.
goT = CREATEOBJECT('Empty')
=ADDPROPERTY(goT,'serie_act',ALLTRIM(NVL(goDlg.cSerieAct,'')))
=ADDPROPERTY(goT,'nract',goDlg.nNract)
=ADDPROPERTY(goT,'dataact',goDlg.dDataAct)
=ADDPROPERTY(goT,'fdoc',goDlg.cFelDoc)
=ADDPROPERTY(goT,'id_fdoc',goDlg.nIdFdoc)
=ADDPROPERTY(goT,'id_partc',goDlg.nIdPartener)
=ADDPROPERTY(goT,'partc',goDlg.cPartener)
=ADDPROPERTY(goT,'explicatia',ALLTRIM(NVL(goDlg.cExplicatia,'')))
=ADDPROPERTY(goT,'suma',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,IIF(goDlg.nSumaLei<>0,goDlg.nSumaLei,ROUND(goDlg.nSuma*goDlg.nCurs,gnPC)),goDlg.nSuma))
=ADDPROPERTY(goT,'suma_val',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,goDlg.nSuma,0))
=ADDPROPERTY(goT,'in_valuta',goDlg.chkInValutaCont.Value)
=ADDPROPERTY(goT,'participa_valuta',(goDlg.chkParticipaValuta.Value=1))
=ADDPROPERTY(goT,'id_valuta',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nIdValuta,0))
=ADDPROPERTY(goT,'curs',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nCurs,0))
=ADDPROPERTY(goT,'nume_val',IIF(goDlg.chkInValutaCont.Value=1,ALLTRIM(NVL(goDlg.cValuta,'')),''))
=ADDPROPERTY(goT,'cTipTva',IIF(goDlg.optTipTva.Value=1,'F',IIF(goDlg.optTipTva.Value=2,'D','N')))
=ADDPROPERTY(goT,'id_jtva_coloana',goDlg.nIdExplicatieTva)
=ADDPROPERTY(goT,'dvi_serie',CHRTRAN(ALLTRIM(NVL(goDlg.cSerieDvi,'')),CHR(34),''))
=ADDPROPERTY(goT,'dvi_nract',goDlg.nNractDvi)
=ADDPROPERTY(goT,'dvi_dataact',goDlg.dDviData)
=ADDPROPERTY(goT,'dvi_id_fdoc',goDlg.nIdFdocDVI)
=ADDPROPERTY(goT,'dvi_fdoc',goDlg.cFelDocDvi)
=ADDPROPERTY(goT,'dvi_id_partc',goDlg.nDviIdPartener)
=ADDPROPERTY(goT,'dvi_partc',goDlg.cDviPartener)
=ADDPROPERTY(goT,'dvi_scc','401')
=ADDPROPERTY(goT,'dvi_tva_lei',goDlg.nDviTvaLei)
=ADDPROPERTY(goT,'dvi_tva_val',goDlg.nDviTvaVal)
ENDPROC
PROCEDURE CreeazaRulTemp
*-- structura reala a rul_temp (vezi ointroduceri.vc2:11030): toate coloanele VRUL (Oracle
*-- dev, MARIUSM_AUTO, 17.07.2026) + pret_lei/pret_val/cota_tva (aliasuri din select-ul care
*-- creeaza rul_temp gol). Folosita atat la pregatirea INAINTE de instantiere, cat si de
*-- dummyexecutor.oExecute (cand import_nota.Init recreeaza rul_temp gol din Oracle).
IF USED('rul_temp')
USE IN ('rul_temp')
ENDIF
CREATE CURSOR rul_temp ( ;
id_rul N(20,0), an N(4,0), luna N(2,0), cod N(20,0);
, serie C(100), nnir N(20,0), id_articol N(10,0), denumire C(100);
, codmat C(50), codmatf C(50), codbare C(50), um C(20);
, id_gestiune N(5,0), nume_gestiune C(50), cgest C(20), nr_pag N(2,0);
, gestionar C(50), comisie_receptie1 C(50), comisie_receptie2 C(50), comisie_receptie3 C(50);
, cant N(14,3), cante N(14,3), cont C(10), acont C(20);
, pret N(18,4), tva N(18,4), valoare N(18,4), valtva N(18,4);
, proc_tva N(5,2), pretv N(18,4), pretvtva N(18,4), tvav N(18,4);
, valoarev N(18,4), valtvav N(18,4), proc_tvav N(5,2), adaos N(18,4);
, adaos_tva N(18,4), valoare_adaos N(18,4), valtva_adaos N(18,4), procent N(10,3);
, discunitar N(18,4), discount_tva N(18,4), valoare_discount N(18,4), valtva_discount N(18,4);
, proc_disc N(7,3), pretd N(14,4), curs N(18,4), id_valuta N(10,0);
, nume_val C(20), id_lucrare N(20,0), nrord C(100), id_responsabil N(10,0);
, nresp C(100), resp_marca N(18,4), dataact T, id_util N(5,0);
, util C(30), dataora T, id_sectie N(5,0), sectie C(50);
, csectie C(10), alcooltutun N(1,0), datain T, dataout T;
, id_fact N(20,0), id_gestiunec N(10,0), nume_gestiunec C(50), cgestc C(20);
, id_responsabilc N(5,0), id_reteta N(10,0), reteta C(50), nrespc C(100);
, respc_marca N(18,4), id_set N(20,0), id_tip_rulaj N(10,0), tip_rulaj C(50);
, id_obiect_depozit N(10,0), id_rul_aux N(10,0), nract N(20,0), serie_act C(10);
, dataoras T, id_utils N(10,0), lot C(30), adata_expirare T;
, id_sucursala N(5,0), sucursala C(250), id_part_rez N(10,0), part_rez C(100);
, id_lucrare_rez N(10,0), nrord_rez C(100), subgrupa C(100), grupa C(100);
, id_subgrupa N(5,0), id_grupa N(5,0), in_stoc N(1,0), in_crm N(1,0);
, id_furnizor N(10,0), furnizor C(100), id_jtva_coloana N(4,0), explicatie_tva C(100);
, taxcode N(6,0), taxname C(254), saft_procent N(18,4), codnc8 C(20);
, id_tara_origine N(4,0), cod_tara_origine C(5), tara_origine C(50), greutate N(12,4);
, fdoc C(30), id_fdoc N(18,4);
, pret_lei N(18,4), pret_val N(14,4), cota_tva N(6,2))
ENDPROC
PROCEDURE CreeazaIntrodc
LPARAMETERS tcAlias
IF USED(tcAlias)
USE IN (tcAlias)
ENDIF
CREATE CURSOR (tcAlias) ( ;
id_note N(14), explicatia C(100), scd C(10), ascd C(20), scc C(10), ascc C(20), ;
cu_tva N(1), id_set N(14), ordine N(8), in_valuta N(1), id_jtva_coloana N(14) NULL, ;
ptva N(6,2), explicatie_tva C(50), tipjurnal C(2), taxcode N(6), paymentcode C(9), ;
suma N(18,4), suma_val N(18,4), id_partd N(14), id_partc N(14), partd C(100), partc C(100), ;
id_fact N(14), id_factd N(14), id_factc N(14), pereched N(14), perechec N(14), ;
nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), ;
scd_orig C(20), ascd_orig C(20))
ENDPROC
PROCEDURE VerificaPereche
*-- verifica perechea B+T adaugata (dupa nract): sume lei/valuta, valuta pe baza
LPARAMETERS tnNract, tnBazaLei, tnBazaVal, tcVal, tlTDvi
LOCAL lnSel, lcMsg, llB, llT, lnBS, lnBSV, lcNV
lnSel = SELECT()
SELECT introdc
LOCATE FOR nract = tnNract AND tip_rand == 'B'
llB = FOUND()
IF llB
lnBS = suma
lnBSV = suma_val
lcNV = ALLTRIM(NVL(nume_val,''))
ENDIF
LOCATE FOR nract = tnNract AND tip_rand == 'T'
*-- cu DVI, randul T e legitim re-cheiat pe documentul vamal (verificat de VerificaDvi)
llT = FOUND() OR tlTDvi
IF llB AND llT AND ABS(lnBS - tnBazaLei) < 0.01 AND ABS(lnBSV - tnBazaVal) < 0.01 AND ALLTRIM(NVL(lcNV,'')) == tcVal
lcMsg = 'PASS pereche nract=' + TRANSFORM(tnNract) + ': B(suma=' + TRANSFORM(lnBS) + ' val=' + TRANSFORM(lnBSV) + ' ' + lcNV + ') + randT gasit'
ELSE
lcMsg = 'FAIL pereche nract=' + TRANSFORM(tnNract) + ': B?=' + TRANSFORM(llB) + ' T?=' + TRANSFORM(llT) + ' bazaLei=' + TRANSFORM(IIF(llB,lnBS,-1)) + '(astept ' + TRANSFORM(tnBazaLei) + ') bazaVal=' + TRANSFORM(IIF(llB,lnBSV,-1)) + '(astept ' + TRANSFORM(tnBazaVal) + ') val=[' + IIF(llB,lcNV,'?') + '](astept [' + tcVal + '])'
ENDIF
DO ArLog WITH lcMsg
SELECT (lnSel)
ENDPROC
PROCEDURE VerificaDvi
*-- randul T e re-cheiat pe documentul vamal (Go lnRecT - fix), nu mai ramane sub nract-ul facturii.
LPARAMETERS tnNract, tnNractDvi, tnBazaLei, tnTvaLei
LOCAL lnSel, lcMsg, llB, llT, lnBS, lnTS, lcTPartc, llVama, llRamasitaT
lnSel = SELECT()
SELECT introdc
LOCATE FOR nract = tnNract AND tip_rand == 'B'
llB = FOUND()
IF llB
lnBS = suma
ENDIF
LOCATE FOR nract = tnNractDvi AND tip_rand == 'T'
llT = FOUND()
IF llT
lnTS = suma
lcTPartc = ALLTRIM(NVL(partc,''))
llVama = ('VAMAL' $ UPPER(lcTPartc))
ENDIF
LOCATE FOR nract = tnNract AND tip_rand == 'T'
llRamasitaT = FOUND()
IF llB AND llT AND !llRamasitaT AND ABS(lnBS - tnBazaLei) < 0.01 AND ABS(lnTS - tnTvaLei) < 0.01 AND llVama
lcMsg = 'PASS DVI nract=' + TRANSFORM(tnNract) + ': B(suma=' + TRANSFORM(lnBS) + ') + T_DVI(nract=' + TRANSFORM(tnNractDvi) + ' partc=' + lcTPartc + ' suma=' + TRANSFORM(lnTS) + ')'
ELSE
lcMsg = 'FAIL DVI nract=' + TRANSFORM(tnNract) + ': B(suma=' + TRANSFORM(IIF(llB,lnBS,-1)) + ', astept ' + TRANSFORM(tnBazaLei) + ') T_DVI(nract=' + TRANSFORM(tnNractDvi) + ' suma=' + TRANSFORM(IIF(llT,lnTS,-1)) + ', astept ' + TRANSFORM(tnTvaLei) + ' partc=' + IIF(llT,lcTPartc,'?') + ') ramasitaT=' + TRANSFORM(llRamasitaT) + ' (astept .F.)'
ENDIF
DO ArLog WITH lcMsg
SELECT (lnSel)
ENDPROC
PROCEDURE VerificaSumaGrupVama
LPARAMETERS tnNractVama, tnSumaAsteptata, tnRanduriAsteptate
LOCAL lnSel, lcMsg, lnSumaT, lnCount
lnSel = SELECT()
SELECT COUNT(*) AS n, SUM(suma) AS s FROM introdc WHERE nract = tnNractVama AND tip_rand == 'T' INTO CURSOR crsGrupVama NOFILTER
lnCount = crsGrupVama.n
lnSumaT = NVL(crsGrupVama.s, 0)
USE IN crsGrupVama
IF lnCount = tnRanduriAsteptate AND ABS(lnSumaT - tnSumaAsteptata) < 0.01
lcMsg = 'PASS grup vama nract=' + TRANSFORM(tnNractVama) + ': ' + TRANSFORM(lnCount) + ' randuri T, suma totala=' + TRANSFORM(lnSumaT)
ELSE
lcMsg = 'FAIL grup vama nract=' + TRANSFORM(tnNractVama) + ': randuri=' + TRANSFORM(lnCount) + ' (astept ' + TRANSFORM(tnRanduriAsteptate) + ') suma=' + TRANSFORM(lnSumaT) + ' (astept ' + TRANSFORM(tnSumaAsteptata) + ')'
ENDIF
DO ArLog WITH lcMsg
SELECT (lnSel)
ENDPROC
PROCEDURE DumpIntrodc
LOCAL lnSel
lnSel = SELECT()
SELECT introdc
SCAN
DO ArLog WITH ' recno=' + TRANSFORM(RECNO()) + ' nract=' + TRANSFORM(nract) + ' tip_rand=' + tip_rand + ;
' scd=' + ALLTRIM(scd) + ' suma=' + TRANSFORM(suma) + ' suma_val=' + TRANSFORM(suma_val) + ;
' partc=[' + ALLTRIM(NVL(partc,'')) + '] doc_key=[' + ALLTRIM(doc_key) + ']'
ENDSCAN
SELECT (lnSel)
ENDPROC
FUNCTION RECCOUNT_ACTIVE
LPARAMETERS tcAlias
LOCAL lnSel, lnCnt
lnSel = SELECT()
SELECT (tcAlias)
COUNT TO lnCnt FOR !DELETED()
SELECT (lnSel)
RETURN lnCnt
ENDFUNC
PROCEDURE ArErr
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
DO ArLog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
ENDPROC
PROCEDURE ArLog
LPARAMETERS tcMsg
SET SAFETY OFF
LOCAL lcL
lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '')
STRTOFILE(lcL + tcMsg + CHR(13)+CHR(10), gcUILog)
ENDPROC
DEFINE CLASS dummyapp AS Custom
PROCEDURE ReadIni
LPARAMETERS tcSection, tcKey
RETURN ''
ENDPROC
PROCEDURE WriteIni
LPARAMETERS tcSection, tcKey, tcValue
RETURN .T.
ENDPROC
ENDDEFINE
DEFINE CLASS dummyexecutor AS Custom
cEroare = ''
PROCEDURE oExecute
LPARAMETERS tcSql, tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
*-- update_jtva_coloane (SELECT * FROM vjtva_coloane ...): mock cu date reale.
IF 'VJTVA_COLOANE' $ UPPER(m.tcSql)
DO CreeazaJtvaColoaneView WITH m.tcCursor
RETURN 1
ENDIF
*-- rul_temp (recreat de import_nota.Init din vrul cand e gol): structura FIDELA (vezi
*-- CreeazaRulTemp) - altfel grila isi pierde coloanele (eroare 1925) sau campuri reale
*-- (proc_tva etc.) lipsesc din cursor si GATHER/REPLACE pe ele arunca eroare 12.
IF UPPER(ALLTRIM(m.tcCursor)) == 'RUL_TEMP'
DO CreeazaRulTemp
ELSE
*-- ramura generica: acopera si config_analitice (assign_analitic) - cursor gol,
*-- lnSucces>0 dar RECCOUNT=0 => lnSucces=-1 in assign_analitic => lcAnalitic='' (fara
*-- analitic pe cont 212, comportament acceptat de team-lead pentru acest test).
CREATE CURSOR (m.tcCursor) (id_temp N(1))
ENDIF
RETURN 1
ENDPROC
PROCEDURE oExecuta
LPARAMETERS tcSql, tcCursor
IF !EMPTY(m.tcCursor)
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF UPPER(m.tcCursor) == 'CJTVACOL4427'
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14))
ELSE
CREATE CURSOR (m.tcCursor) (id_temp N(1))
ENDIF
ENDIF
RETURN .T.
ENDPROC
PROCEDURE oSelect2Value
*-- GetCodFiscalPartenerById: cod fiscal gol => VERIFICA_RTVAI sare peste Oracle real.
LPARAMETERS tcSql, toValue
toValue = ''
RETURN 1
ENDPROC
PROCEDURE oReset
*-- update_jtva_coloane() il apeleaza necondit dupa oExecute (updateserver.prg:611).
ENDPROC
ENDDEFINE
PROCEDURE CreeazaJtvaColoaneView
LPARAMETERS tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14), denumire C(100), jc N(1), jv N(1), ;
coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14) NULL, afisat N(1), ;
id_jtva_ex N(14) NULL, id_jtva_neex N(14) NULL, ordine N(8), ;
taxcode N(6) NULL, taxcode_neexigibil N(6) NULL, taxcode_n50 N(6) NULL, ;
taxcode_n50_tvai N(6) NULL, taxcode_n100 N(6) NULL, taxcode_regularizare N(6) NULL, taxcode_tvai N(6) NULL)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, afisat, ordine, cota_tva) VALUES (0, '', 0, 0, 1, 0, 0)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (208, 'ACH. INT. 21%', 1, 0, 'RO21B', 21, 209, 1, 1, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (209, 'TVA ACH. INT. 21%', 1, 0, 'RO21T', 21, 1, 2, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (220, 'ACH. IMP. 21%', 1, 0, 'FO21B', 21, 221, 1, 3, 301204)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (221, 'TVA ACH. IMP. 21%', 1, 0, 'FO21T', 21, 1, 4, 301204)
ENDPROC

View File

@@ -0,0 +1,10 @@
# test_adauga_repere_212.ps1 - wrapper peste harness-ul generic pentru testul cu fluxul
# REAL de adaugare articole (do_adauga_articol), nu INSERT direct in rul_temp.
# Rulare: powershell -ExecutionPolicy Bypass -File test_adauga_repere_212.ps1
$ErrorActionPreference = 'Stop'
$Teste = $PSScriptRoot
& (Join-Path (Split-Path $Teste -Parent) 'vfp_ui_harness.ps1') `
-TestPrg (Join-Path $Teste 'test_adauga_repere_212.prg') `
-Steps @('3documente','dupa_adauga_articol','dupa_sincronizare','final') `
-ShotsDir (Join-Path $Teste 'screenshots_repere212') `
-SyncDir (Join-Path $Teste 'uisync_repere212')

View File

@@ -0,0 +1,697 @@
* test_analitic_partener_d.prg
* Teste runda 18-19 (import_nota, COMUN\clase\ointroduceri.vcx): randul D (diferente) fara
* partener mostenit (recalc_diferente goleste partc/id_partc/partd/id_partd), si verificarea
* analiticului pe articole in valideaza_sume (F3: cont cu analitice definite si acont gol sau
* necunoscut in planul de conturi -> mesaj in cmesajsync, Return .F.).
* Documentul e IDENTIC ca structura (jtva_coloane2/saft_taxtable, introdc/rul_temp, mock-uri) cu
* test_manual_tva_footer.prg, dar cu 1 SINGUR document simplu (fara DVI) - nu e nevoie de valuta
* aici, doar de un rand B cu suma diferita de baza articolelor (sa se creeze randul D).
*
* Pasi (harness): 0 dupa document+articol valid+sincronizare (D creat, partener gol, F3 trece),
* 1 dupa articol cu acont gol (F3 blocheaza), 2 dupa articol cu acont necunoscut (F3 blocheaza),
* 3 final.
*
* Rulare:
* powershell -ExecutionPolicy Bypass -File test_analitic_partener_d.ps1
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET DECIMALS TO 4
SET NULLDISPLAY TO ''
CLOSE DATABASES
PUBLIC gcUILog, gcSyncDir
gcUILog = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\test_analitic_partener_d_log.txt"
gcSyncDir = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\uisync_analitic_partener_d\"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcUILog)
ON ERROR DO ApErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
TRY
LOCAL gcAppPath, lcPath
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;' + ;
ADDBS(SUBSTR(gcAppPath,1,RAT([\],gcAppPath,2)))+[COMUNROA\]
SET PATH TO &lcPath ADDITIVE
DO ApLog WITH 'SET PATH OK'
*----- CLASE -----
SET CLASSLIB TO (gcAppPath + "comun\clase\appwiz") 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 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 wwdialogs.vcx ADDITIVE
SET CLASSLIB TO oimportxml.vcx ADDITIVE
SET CLASSLIB TO excelxml.vcx ADDITIVE
SET CLASSLIB TO orapoarte_obinv.vcx ADDITIVE
DO ApLog WITH 'SET CLASSLIB OK'
*----- PROCEDURI (mock amessagebox + mock cauta_nom_articole PRIMELE, ui_harness la final) -----
SET PROCEDURE TO PROCEDURI
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_cauta_nom_articole.prg" 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 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 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 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
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\ui_harness.prg" ADDITIVE
DO ApLog WITH 'SET PROCEDURE OK'
*----- Globale -----
PUBLIC gnPc, gnPval, gnPcant, gnPpret, gnPPretval, gnPCurs, gnPVal, gnPPretV, gnPPretVal
STORE 2 TO gnPc, gnPval, gnPVal
gnPcant = 3
STORE 4 TO gnPpret, gnPPretval, gnPPretVal, gnPPretV, gnPCurs
PUBLIC gl406, gcS, gnAn, gnLuna, gnIdFirma, gnIdSucursala, gcAcces, gcFirma
gl406 = .T.
gcS = 'CONTAFIN'
gnAn = YEAR(DATE())
gnLuna = MONTH(DATE())
gnIdFirma = 110
gnIdSucursala = 110
gcAcces = "1;2;3;4;5;6;7;8;"
gcFirma = gcS
PUBLIC nror(65000)
PUBLIC gnButon
STORE 2 TO gnButon
PUBLIC gcMockArtCodmat, gcMockAcontCrt
gcMockArtCodmat = ''
gcMockAcontCrt = ''
PUBLIC gnMockRaspuns
gnMockRaspuns = 6
PUBLIC goExecutor, goApp
goExecutor = CREATEOBJECT('dummyexecutor')
goApp = CREATEOBJECT('dummyapp')
*----- poAct: antetul notei; dialogul mosteneste din el la Init -----
PUBLIC poAct
poAct = CREATEOBJECT('Custom')
poAct.AddProperty('nume_val', '')
poAct.AddProperty('curs', 1)
poAct.AddProperty('proc_tva', 1.21)
poAct.AddProperty('nnir', 0)
poAct.AddProperty('id_valuta', 0)
poAct.AddProperty('id_fdoc', 1)
poAct.AddProperty('fdoc', 'Factura')
poAct.AddProperty('id_partc', 500)
poAct.AddProperty('partc', 'FURNIZOR ANTET SRL')
poAct.AddProperty('serie_act', '')
poAct.AddProperty('dataact', DATE())
poAct.AddProperty('tva_incasare', 0)
poAct.AddProperty('id_set', 1)
poAct.AddProperty('id_gestin', 1)
*----- jtva_coloane2 / saft_taxtable: perechi reale 21% (identice test_scenariu_dvi_complet) -----
IF USED('jtva_coloane2')
USE IN ('jtva_coloane2')
ENDIF
CREATE CURSOR jtva_coloane2 (ordine N(8), id_jtva_coloana N(14), denumire C(100), ;
jc N(1), jv N(1), afisat N(1), coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14))
INSERT INTO jtva_coloane2 VALUES (0, 0, '', 0, 0, 1, '', '', 0, 0)
INSERT INTO jtva_coloane2 VALUES (1, 208, 'ACH. INT. 21%', 1, 0, 1, 'RO21B', 'RO21T', 21, 209)
INSERT INTO jtva_coloane2 VALUES (2, 209, 'TVA ACH. INT. 21%', 1, 0, 1, 'RO21T', '', 21, 0)
INSERT INTO jtva_coloane2 VALUES (3, 220, 'ACH. IMP. 21%', 1, 0, 1, 'FO21B', 'FO21T', 21, 221)
INSERT INTO jtva_coloane2 VALUES (4, 221, 'TVA ACH. IMP. 21%', 1, 0, 1, 'FO21T', '', 21, 0)
IF USED('saft_taxtable')
USE IN ('saft_taxtable')
ENDIF
CREATE CURSOR saft_taxtable (taxname C(250) NULL, typename C(250) NULL, taxcode N(6) NULL, ;
taxtype N(3) NULL, descriere C(250) NULL, tip C(100) NULL, descriere_tip C(250) NULL, ;
procent_taxa N(7,2) NULL, procent_prorata N(7,2) NULL, inactiv N(1) NULL, tva N(1) NULL, ;
wht N(1) NULL, tva_achizitii N(1) NULL, tva_livrari N(1) NULL)
INDEX ON taxcode TAG taxcode
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('', 0, '', 0, 1, 1, 1, 1)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301104-Achizitii de bunuri si servicii taxabile cu cota de 21%, altele decat importurile si cele supuse masurilor de simplificare', 301104, '', 21, 1, 0, 1, 0)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301204-Import de bunuri cota 21%', 301204, '', 21, 1, 0, 1, 0)
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%')
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%')
GO TOP IN introdc_sablon
DO CreeazaRulTemp
INSERT INTO rul_temp (denumire, codmat, cant, pret, pret_lei, cont, cota_tva) ;
VALUES ('PLACEHOLDER', 'PH', 1, 1, 1, '371', 21)
*-- index ord_doc INAINTE de CREATEOBJECT - vezi docs/testare-ui-vfp.md capcana p.
SELECT introdc
INDEX ON Str(Nvl(nr_doc,0),8) + Icase(tip_rand='B','1', tip_rand='S','2', tip_rand='T','3', tip_rand='D','4', '5') + Padr(Nvl(scd,''),10) TAG ord_doc
SET ORDER TO ord_doc
DO ApLog WITH 'cursoare pregatite, CREATEOBJECT(import_nota, .F.) - lIntern=.F. (import)'
PUBLIC goObj
goObj = CREATEOBJECT('IMPORT_nota', .F.)
IF VARTYPE(goObj) <> 'O'
DO ApLog WITH 'FAIL: instantiere import_nota'
DO HarnessDone WITH 'done-error'
QUIT
ENDIF
goObj.lDialogAratat = .T.
goObj.oact = poAct
goObj.WindowType = 0
goObj.Visible = .T.
goObj.Show()
goObj.WindowState = 2
DOEVENTS FORCE
SELECT rul_temp
ZAP
goObj.gridart.Refresh()
DOEVENTS FORCE
*========================= 1 DOCUMENT SIMPLU (FACTURA 20000, suma 1000, fara DVI) =========================
PUBLIC goDlg, goT
DO AdaugaDocSimplu
DO ApLog WITH 'dump introdc dupa document:'
DO DumpIntrodc
*========================= ARTICOL VALID (cont 212, acont=1 - exista in plan) =========================
gcMockArtCodmat = 'ART-BULD-212'
gcMockAcontCrt = '1'
TRY
goObj.do_adauga_articol()
CATCH TO loExcA1
DO ApLog WITH 'EROARE do_adauga_articol (valid) ' + TRANSFORM(loExcA1.ErrorNo) + ' [' + loExcA1.Message + ']'
ENDTRY
DOEVENTS FORCE
SELECT rul_temp
LOCATE FOR ALLTRIM(codmat) == 'ART-BULD-212' AND !DELETED()
IF FOUND()
REPLACE cant WITH 1, pret_val WITH 0, pretd WITH 0, pret WITH 900, pret_lei WITH 900
DO ApLog WITH 'PASS articol valid adaugat: acont=[' + ALLTRIM(NVL(acont,'')) + '] (astept [1])'
IF ALLTRIM(NVL(acont,'')) != '1'
DO ApLog WITH 'FAIL articol valid: acont=[' + ALLTRIM(NVL(acont,'')) + '] (astept [1])'
ENDIF
ELSE
DO ApLog WITH 'FAIL: articolul valid nu a fost adaugat de do_adauga_articol()'
ENDIF
goObj.gridart.Refresh()
DOEVENTS FORCE
LOCAL llEroareSync1
llEroareSync1 = .F.
TRY
goObj.sincronizeaza()
CATCH TO loExcS1
llEroareSync1 = .T.
DO ApLog WITH 'EROARE la sincronizeaza() ' + TRANSFORM(loExcS1.ErrorNo) + ' [' + loExcS1.Message + ']'
ENDTRY
DOEVENTS FORCE
goObj.grid1.Refresh()
IF !llEroareSync1
DO ApLog WITH 'PASS sincronizare: fara eroare'
ELSE
DO ApLog WITH 'FAIL sincronizare: a aruncat eroare'
ENDIF
DO ApLog WITH 'dump introdc dupa document + articol valid + sincronizare:'
DO DumpIntrodc
*========================= TEST (a): randul D nou-creat, partener gol =========================
LOCAL llGasitD
SELECT introdc
LOCATE FOR tip_rand == 'D'
llGasitD = FOUND()
IF llGasitD
IF EMPTY(NVL(partc,'')) AND NVL(id_partc,0) = 0 AND EMPTY(NVL(partd,'')) AND NVL(id_partd,0) = 0
DO ApLog WITH 'PASS test (a): randul D are partc/id_partc/partd/id_partd goale (suma=' + TRANSFORM(suma) + ')'
ELSE
DO ApLog WITH 'FAIL test (a): randul D are partener nemostenit gol - partc=[' + ALLTRIM(NVL(partc,'')) + '] id_partc=' + TRANSFORM(NVL(id_partc,0)) + ' partd=[' + ALLTRIM(NVL(partd,'')) + '] id_partd=' + TRANSFORM(NVL(id_partd,0))
ENDIF
ELSE
DO ApLog WITH 'FAIL test (a): nu s-a creat randul D (astept diferenta 1000-900=100 intre baza documentului si totalul articolelor)'
ENDIF
*========================= TEST (c): valideaza_sume trece cu acont valid completat =========================
LOCAL llRezValidC, lcMesajC
goObj.cmesajsync = ''
llRezValidC = goObj.valideaza_sume()
lcMesajC = goObj.cmesajsync
IF llRezValidC AND !('analitice definite' $ lcMesajC) AND !('nu exista in planul de conturi' $ lcMesajC)
DO ApLog WITH 'PASS test (c): valideaza_sume()=' + TRANSFORM(llRezValidC) + ' fara mesaj de analitic (acont=1 valid pt cont 212)'
ELSE
DO ApLog WITH 'FAIL test (c): valideaza_sume()=' + TRANSFORM(llRezValidC) + ' cmesajsync=[' + lcMesajC + ']'
ENDIF
DO HarnessStep WITH 0, 'dupa document+articol valid+sincronizare: D creat=' + TRANSFORM(llGasitD) + ' F3 valid trece=' + TRANSFORM(llRezValidC)
*========================= TEST (b): articol cu acont GOL pe cont cu analitice (212) =========================
gcMockArtCodmat = 'ART-BULD-212'
gcMockAcontCrt = ''
TRY
goObj.do_adauga_articol()
CATCH TO loExcA2
DO ApLog WITH 'EROARE do_adauga_articol (acont gol) ' + TRANSFORM(loExcA2.ErrorNo) + ' [' + loExcA2.Message + ']'
ENDTRY
DOEVENTS FORCE
SELECT rul_temp
GO BOTTOM
IF ALLTRIM(NVL(codmat,'')) == 'ART-BULD-212' AND EMPTY(NVL(acont,''))
REPLACE cant WITH 1, pret_val WITH 0, pretd WITH 0, pret WITH 100, pret_lei WITH 100
DO ApLog WITH 'articol (b) adaugat cu acont gol, cont=' + ALLTRIM(NVL(cont,''))
ELSE
DO ApLog WITH 'FAIL: articolul (b) nu a fost adaugat cu acont gol (acont=[' + ALLTRIM(NVL(acont,'')) + '])'
ENDIF
LOCAL llRezB, lcMesajB, llEroareB
llEroareB = .F.
goObj.cmesajsync = ''
TRY
llRezB = goObj.valideaza_sume()
CATCH TO loExcB
llEroareB = .T.
DO ApLog WITH 'EROARE valideaza_sume() (b, acont gol) ' + TRANSFORM(loExcB.ErrorNo) + ' [' + loExcB.Message + '] Proc=' + loExcB.Procedure + ' Line=' + TRANSFORM(loExcB.LineNo) + ' [' + loExcB.LineContents + ']'
ENDTRY
IF !llEroareB
lcMesajB = goObj.cmesajsync
IF !llRezB AND ('are analitice definite, analiticul nu e completat' $ lcMesajB)
DO ApLog WITH 'PASS test (b): valideaza_sume()=.F. cu mesajul de acont gol: [' + lcMesajB + ']'
ELSE
DO ApLog WITH 'FAIL test (b): valideaza_sume()=' + TRANSFORM(llRezB) + ' cmesajsync=[' + lcMesajB + '] (astept mesaj "are analitice definite, analiticul nu e completat")'
ENDIF
ELSE
DO ApLog WITH 'FAIL test (b): valideaza_sume() a aruncat eroare pe ramura acont gol (posibil bug real in cod, nu in test - vezi eroarea de mai sus)'
ENDIF
DO HarnessStep WITH 1, 'dupa articol cu acont gol: eroare=' + TRANSFORM(llEroareB) + ' rezultat=' + TRANSFORM(IIF(llEroareB,.F.,llRezB))
*-- sterg (soft-delete) articolul (b), sa nu interfereze cu testul (d)
SELECT rul_temp
GO BOTTOM
IF ALLTRIM(NVL(codmat,'')) == 'ART-BULD-212' AND EMPTY(NVL(acont,''))
DELETE
ENDIF
*========================= TEST (d): articol cu acont NECUNOSCUT (212.99, nu exista in plan) =========================
gcMockArtCodmat = 'ART-BULD-212'
gcMockAcontCrt = '99'
TRY
goObj.do_adauga_articol()
CATCH TO loExcA3
DO ApLog WITH 'EROARE do_adauga_articol (acont necunoscut) ' + TRANSFORM(loExcA3.ErrorNo) + ' [' + loExcA3.Message + ']'
ENDTRY
DOEVENTS FORCE
SELECT rul_temp
GO BOTTOM
IF ALLTRIM(NVL(codmat,'')) == 'ART-BULD-212' AND !DELETED() AND ALLTRIM(NVL(acont,'')) == '99'
REPLACE cant WITH 1, pret_val WITH 0, pretd WITH 0, pret WITH 50, pret_lei WITH 50
DO ApLog WITH 'articol (d) adaugat cu acont=99'
ELSE
DO ApLog WITH 'FAIL: articolul (d) nu a fost adaugat cu acont=99 (acont=[' + ALLTRIM(NVL(acont,'')) + '])'
ENDIF
LOCAL llRezD, lcMesajD, llEroareD
llEroareD = .F.
goObj.cmesajsync = ''
TRY
llRezD = goObj.valideaza_sume()
CATCH TO loExcD
llEroareD = .T.
DO ApLog WITH 'EROARE valideaza_sume() (d, acont necunoscut) ' + TRANSFORM(loExcD.ErrorNo) + ' [' + loExcD.Message + '] Proc=' + loExcD.Procedure + ' Line=' + TRANSFORM(loExcD.LineNo) + ' [' + loExcD.LineContents + ']'
ENDTRY
IF !llEroareD
lcMesajD = goObj.cmesajsync
IF !llRezD AND ('nu exista in planul de conturi' $ lcMesajD)
DO ApLog WITH 'PASS test (d): valideaza_sume()=.F. cu mesajul de analitic necunoscut: [' + lcMesajD + ']'
ELSE
DO ApLog WITH 'FAIL test (d): valideaza_sume()=' + TRANSFORM(llRezD) + ' cmesajsync=[' + lcMesajD + '] (astept mesaj "nu exista in planul de conturi")'
ENDIF
ELSE
DO ApLog WITH 'FAIL test (d): valideaza_sume() a aruncat eroare pe ramura acont necunoscut (posibil bug real in cod, nu in test - vezi eroarea de mai sus)'
ENDIF
DO HarnessStep WITH 2, 'dupa articol cu acont necunoscut: eroare=' + TRANSFORM(llEroareD) + ' rezultat=' + TRANSFORM(IIF(llEroareD,.F.,llRezD))
DO ApLog WITH 'GATA - scenariu executat integral'
DO HarnessStep WITH 3, 'final: introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri, rul_temp=' + TRANSFORM(RECCOUNT_ACTIVE('rul_temp')) + ' articole'
DO HarnessDone WITH 'done'
CATCH TO loExc
DO ApLog WITH 'CATCH ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']'
DO HarnessDone WITH 'done-error'
ENDTRY
QUIT
*==================================================================================
PROCEDURE AdaugaDocSimplu
*-- FACTURA 20000, FURNIZOR SIMPLU SRL, fara valuta, fara DVI, tva normal 'F' 21% (ACH. IMP.).
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = 20000
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 700
goDlg.cPartener = 'FURNIZOR SIMPLU SRL'
goDlg.cExplicatia = 'Achizitie test analitic'
goDlg.nSuma = 1000
goDlg.nSumaLei = 0
goDlg.nCurs = 0
goDlg.nIdExplicatieTva = 220
goDlg.cExplicatieTva = 'ACH. IMP. 21%'
goDlg.optTipTva.Value = 1 && F = furnizor (normal)
goDlg.chkInValutaCont.Value = 0
goDlg.chkParticipaValuta.Value = 1
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO ApLog WITH 'DOC: valideaza = ' + TRANSFORM(goDlg.valideaza())
DO ConstruiesteToDlg
DO ApLog WITH 'DOC: do_adauga_factura = ' + TRANSFORM(goObj.do_adauga_factura(goT))
goDlg.Hide()
DOEVENTS FORCE
ENDPROC
PROCEDURE ConstruiesteToDlg
*-- toDlg construit INLINE (nu intr-o functie apelata din procedura de business) - vezi
*-- docs/testare-ui-vfp.md capcana l; aici functioneaza fiindca goT e PUBLIC.
goT = CREATEOBJECT('Empty')
=ADDPROPERTY(goT,'serie_act',ALLTRIM(NVL(goDlg.cSerieAct,'')))
=ADDPROPERTY(goT,'nract',goDlg.nNract)
=ADDPROPERTY(goT,'dataact',goDlg.dDataAct)
=ADDPROPERTY(goT,'fdoc',goDlg.cFelDoc)
=ADDPROPERTY(goT,'id_fdoc',goDlg.nIdFdoc)
=ADDPROPERTY(goT,'id_partc',goDlg.nIdPartener)
=ADDPROPERTY(goT,'partc',goDlg.cPartener)
=ADDPROPERTY(goT,'explicatia',ALLTRIM(NVL(goDlg.cExplicatia,'')))
=ADDPROPERTY(goT,'suma',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,IIF(goDlg.nSumaLei<>0,goDlg.nSumaLei,ROUND(goDlg.nSuma*goDlg.nCurs,gnPC)),goDlg.nSuma))
=ADDPROPERTY(goT,'suma_val',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,goDlg.nSuma,0))
=ADDPROPERTY(goT,'in_valuta',goDlg.chkInValutaCont.Value)
=ADDPROPERTY(goT,'participa_valuta',(goDlg.chkParticipaValuta.Value=1))
=ADDPROPERTY(goT,'id_valuta',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nIdValuta,0))
=ADDPROPERTY(goT,'curs',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nCurs,0))
=ADDPROPERTY(goT,'nume_val',IIF(goDlg.chkInValutaCont.Value=1,ALLTRIM(NVL(goDlg.cValuta,'')),''))
=ADDPROPERTY(goT,'cTipTva',IIF(goDlg.optTipTva.Value=1,'F',IIF(goDlg.optTipTva.Value=2,'D','N')))
=ADDPROPERTY(goT,'id_jtva_coloana',goDlg.nIdExplicatieTva)
=ADDPROPERTY(goT,'dvi_serie','')
=ADDPROPERTY(goT,'dvi_nract',0)
=ADDPROPERTY(goT,'dvi_dataact',DATE())
=ADDPROPERTY(goT,'dvi_id_fdoc',0)
=ADDPROPERTY(goT,'dvi_fdoc','')
=ADDPROPERTY(goT,'dvi_id_partc',0)
=ADDPROPERTY(goT,'dvi_partc','')
=ADDPROPERTY(goT,'dvi_scc','401')
=ADDPROPERTY(goT,'dvi_tva_lei',0)
=ADDPROPERTY(goT,'dvi_tva_val',0)
ENDPROC
PROCEDURE CreeazaRulTemp
*-- structura reala rul_temp (VRUL, Oracle dev) - identica cu test_scenariu_dvi_complet.prg,
*-- necesara ca GridArt/footer sa gaseasca toate coloanele (pret_val, pretd, pret, cant, acont).
IF USED('rul_temp')
USE IN ('rul_temp')
ENDIF
CREATE CURSOR rul_temp ( ;
id_rul N(20,0), an N(4,0), luna N(2,0), cod N(20,0);
, serie C(100), nnir N(20,0), id_articol N(10,0), denumire C(100);
, codmat C(50), codmatf C(50), codbare C(50), um C(20);
, id_gestiune N(5,0), nume_gestiune C(50), cgest C(20), nr_pag N(2,0);
, gestionar C(50), comisie_receptie1 C(50), comisie_receptie2 C(50), comisie_receptie3 C(50);
, cant N(14,3), cante N(14,3), cont C(10), acont C(20);
, pret N(18,4), tva N(18,4), valoare N(18,4), valtva N(18,4);
, proc_tva N(5,2), pretv N(18,4), pretvtva N(18,4), tvav N(18,4);
, valoarev N(18,4), valtvav N(18,4), proc_tvav N(5,2), adaos N(18,4);
, adaos_tva N(18,4), valoare_adaos N(18,4), valtva_adaos N(18,4), procent N(10,3);
, discunitar N(18,4), discount_tva N(18,4), valoare_discount N(18,4), valtva_discount N(18,4);
, proc_disc N(7,3), pretd N(14,4), curs N(18,4), id_valuta N(10,0);
, nume_val C(20), id_lucrare N(20,0), nrord C(100), id_responsabil N(10,0);
, nresp C(100), resp_marca N(18,4), dataact T, id_util N(5,0);
, util C(30), dataora T, id_sectie N(5,0), sectie C(50);
, csectie C(10), alcooltutun N(1,0), datain T, dataout T;
, id_fact N(20,0), id_gestiunec N(10,0), nume_gestiunec C(50), cgestc C(20);
, id_responsabilc N(5,0), id_reteta N(10,0), reteta C(50), nrespc C(100);
, respc_marca N(18,4), id_set N(20,0), id_tip_rulaj N(10,0), tip_rulaj C(50);
, id_obiect_depozit N(10,0), id_rul_aux N(10,0), nract N(20,0), serie_act C(10);
, dataoras T, id_utils N(10,0), lot C(30), adata_expirare T;
, id_sucursala N(5,0), sucursala C(250), id_part_rez N(10,0), part_rez C(100);
, id_lucrare_rez N(10,0), nrord_rez C(100), subgrupa C(100), grupa C(100);
, id_subgrupa N(5,0), id_grupa N(5,0), in_stoc N(1,0), in_crm N(1,0);
, id_furnizor N(10,0), furnizor C(100), id_jtva_coloana N(4,0), explicatie_tva C(100);
, taxcode N(6,0), taxname C(254), saft_procent N(18,4), codnc8 C(20);
, id_tara_origine N(4,0), cod_tara_origine C(5), tara_origine C(50), greutate N(12,4);
, fdoc C(30), id_fdoc N(18,4);
, pret_lei N(18,4), pret_val N(14,4), cota_tva N(6,2))
ENDPROC
PROCEDURE CreeazaIntrodc
LPARAMETERS tcAlias
IF USED(tcAlias)
USE IN (tcAlias)
ENDIF
CREATE CURSOR (tcAlias) ( ;
id_note N(14), explicatia C(100), scd C(10), ascd C(20), scc C(10), ascc C(20), ;
cu_tva N(1), id_set N(14), ordine N(8), in_valuta N(1), id_jtva_coloana N(14) NULL, ;
ptva N(6,2), explicatie_tva C(50), tipjurnal C(2), taxcode N(6), paymentcode C(9), ;
suma N(18,4), suma_val N(18,4), id_partd N(14), id_partc N(14), partd C(100), partc C(100), ;
id_fact N(14), id_factd N(14), id_factc N(14), pereched N(14), perechec N(14), ;
nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), ;
scd_orig C(20), ascd_orig C(20))
ENDPROC
PROCEDURE DumpIntrodc
LOCAL lnSel
lnSel = SELECT()
SELECT introdc
SCAN
DO ApLog WITH ' recno=' + TRANSFORM(RECNO()) + ' nr_doc=' + TRANSFORM(NVL(nr_doc,0)) + ' nract=' + TRANSFORM(nract) + ' fdoc=[' + ALLTRIM(NVL(fdoc,'')) + '] tip_rand=' + tip_rand + ;
' scd=' + ALLTRIM(scd) + ' suma=' + TRANSFORM(suma) + ' suma_val=' + TRANSFORM(suma_val) + ' mod_manual=' + TRANSFORM(NVL(mod_manual,0)) + ;
' partc=[' + ALLTRIM(NVL(partc,'')) + '] id_partc=' + TRANSFORM(NVL(id_partc,0)) + ' doc_key=[' + ALLTRIM(doc_key) + ']'
ENDSCAN
SELECT (lnSel)
ENDPROC
FUNCTION RECCOUNT_ACTIVE
LPARAMETERS tcAlias
LOCAL lnSel, lnCnt
lnSel = SELECT()
SELECT (tcAlias)
COUNT TO lnCnt FOR !DELETED()
SELECT (lnSel)
RETURN lnCnt
ENDFUNC
PROCEDURE ApErr
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
DO ApLog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
ENDPROC
PROCEDURE ApLog
LPARAMETERS tcMsg
SET SAFETY OFF
LOCAL lcL
lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '')
STRTOFILE(lcL + tcMsg + CHR(13)+CHR(10), gcUILog)
ENDPROC
DEFINE CLASS dummyapp AS Custom
PROCEDURE ReadIni
LPARAMETERS tcSection, tcKey
RETURN ''
ENDPROC
PROCEDURE WriteIni
LPARAMETERS tcSection, tcKey, tcValue
RETURN .T.
ENDPROC
ENDDEFINE
DEFINE CLASS dummyexecutor AS Custom
cEroare = ''
PROCEDURE oExecute
LPARAMETERS tcSql, tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF 'VJTVA_COLOANE' $ UPPER(m.tcSql)
DO CreeazaJtvaColoaneView WITH m.tcCursor
RETURN 1
ENDIF
IF UPPER(ALLTRIM(m.tcCursor)) == 'RUL_TEMP'
CREATE CURSOR (m.tcCursor) (denumire C(100), codmat C(30), cant N(14,3), ;
pret_val N(18,4), pretd N(18,4), pret N(18,4), pret_lei N(18,4), cont C(10), ;
acont C(20), serie C(30), lot C(30), adata_expirare C(10), proc_disc N(6,2), cota_tva N(6,2))
RETURN 1
ENDIF
IF 'CONFIG_ANALITICE' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (camp_leg_prefix C(30), camp_leg_sufix C(30))
INSERT INTO (m.tcCursor) VALUES ('', '')
RETURN 1
ENDIF
IF 'FCONTURI_ANALITICE' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (acont C(20))
INSERT INTO (m.tcCursor) VALUES (IIF(TYPE('gcMockAcontCrt') = 'C', gcMockAcontCrt, ''))
RETURN 1
ENDIF
IF 'VPLCONT_ANALITIC' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (cont C(10), acont C(20))
INSERT INTO (m.tcCursor) VALUES ('212', '1')
INSERT INTO (m.tcCursor) VALUES ('371', '4')
RETURN 1
ENDIF
CREATE CURSOR (m.tcCursor) (id_temp N(1))
RETURN 1
ENDPROC
PROCEDURE oExecuta
LPARAMETERS tcSql, tcCursor
IF !EMPTY(m.tcCursor)
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF UPPER(m.tcCursor) == 'CJTVACOL4427'
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14))
ELSE
CREATE CURSOR (m.tcCursor) (id_temp N(1))
ENDIF
ENDIF
RETURN .T.
ENDPROC
PROCEDURE oSelect2Value
LPARAMETERS tcSql, toValue
toValue = ''
RETURN 1
ENDPROC
PROCEDURE oReset
ENDPROC
ENDDEFINE
PROCEDURE CreeazaJtvaColoaneView
LPARAMETERS tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14), denumire C(100), jc N(1), jv N(1), ;
coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14) NULL, afisat N(1), ;
id_jtva_ex N(14) NULL, id_jtva_neex N(14) NULL, ordine N(8), ;
taxcode N(6) NULL, taxcode_neexigibil N(6) NULL, taxcode_n50 N(6) NULL, ;
taxcode_n50_tvai N(6) NULL, taxcode_n100 N(6) NULL, taxcode_regularizare N(6) NULL, taxcode_tvai N(6) NULL)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, afisat, ordine, cota_tva) VALUES (0, '', 0, 0, 1, 0, 0)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (208, 'ACH. INT. 21%', 1, 0, 'RO21B', 21, 209, 1, 1, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (209, 'TVA ACH. INT. 21%', 1, 0, 'RO21T', 21, 1, 2, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (220, 'ACH. IMP. 21%', 1, 0, 'FO21B', 21, 221, 1, 3, 301204)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (221, 'TVA ACH. IMP. 21%', 1, 0, 'FO21T', 21, 1, 4, 301204)
ENDPROC

View File

@@ -0,0 +1,12 @@
# test_analitic_partener_d.ps1 - wrapper peste harness-ul generic pentru rundele 18-19
# (randul D fara partener mostenit, verificare analitic pe articole in valideaza_sume). Rulare:
# powershell -ExecutionPolicy Bypass -File test_analitic_partener_d.ps1
$ErrorActionPreference = 'Stop'
$Teste = $PSScriptRoot
& (Join-Path (Split-Path $Teste -Parent) 'vfp_ui_harness.ps1') `
-TestPrg (Join-Path $Teste 'test_analitic_partener_d.prg') `
-Steps @('document_articol_valid','acont_gol','acont_necunoscut','final') `
-ShotsDir (Join-Path $Teste 'screenshots_analitic_partener_d') `
-SyncDir (Join-Path $Teste 'uisync_analitic_partener_d') `
-StepTimeoutSec 180 `
-ReadyTimeoutSec 180

View File

@@ -0,0 +1,776 @@
* test_import_nota_total_ui.prg
* Test UI (runda26a/26b) pentru clasa IMPORT_nota (COMUN\clase\ointroduceri.vcx): editarea manuala a
* unui rand S (subrand articol) pe un document IN VALUTA actualizeaza AUTOMAT (fara dialog de
* confirmare) totalul facturii (suma_doc/suma_doc_val) pe tot grupul doc_key, apoi recalculeaza
* randurile T nemanuale (mod_manual<>1) proportional cu bazele pe cota (recalc_tva_document),
* controlat de Thisform.lRecalcTva (checkbox chkRecalcTva, implicit .T.).
* Patch-uri testate: docs\diff_runda26a_total_automat.patch, docs\diff_runda26b_recalc_tva.patch
* (cod NEATINS de acest test).
*
* Scenariu (flux REAL, nu Append direct in cursoare):
* 1. FACTURA 15000 (partener test), 1000 EUR + TVA (cota 21%), curs 5.23, in_valuta=1 - prin
* goObj.do_adauga_factura(toDlg), la fel ca test_scenariu_import_212/test_adauga_repere_212
* (dialogul import_adauga_factura construit inline, toDlg construit inline in main - vezi
* docs/testare-ui-vfp.md capcana l).
* 2. 2 articole (900 EUR cont 371, 100 EUR cont 303) prin FLUXUL REAL goObj.do_adauga_articol()
* (mock_cauta_nom_articole.prg, gcMockArtCodmat) - documentul se sparge in 2 randuri S; cota
* TVA unica (21%) pe rul_temp => recalc_tva_document ia ramura "o singura cota".
* 3. Editare manuala repetata a randului S(371) prin METODA REALA Grid1.cSumaVal.Text1.Valid
* (randul e tip_rand='S' cu in_valuta=1 - cSuma e blocat pe S+valuta, vezi Grid1.cSuma.Text1.When
* ~12425, editabila e doar cSumaVal), in 3 pasi succesivi:
* A. 900->910 EUR, lRecalcTva implicit .T. -> NU apare dialogul "Actualizati totalul facturii?"
* (verificat pe log-ul mock-ului), suma_doc_val grup 1000->1010, iar T (nemanual) se
* recalculeaza automat: suma_val = ROUND(1010*21/100,gnPval), suma = ROUND(suma_val*curs,gnPc).
* B. 910->920 EUR, Thisform.lRecalcTva = .F. -> suma_doc_val grup 1010->1020, dar T ramane pe
* valoarea din pasul A (NU se recalculeaza).
* C. 920->930 EUR, Thisform.lRecalcTva = .T. din nou, dar T marcat manual (mod_manual=1) inainte
* de editare -> suma_doc_val grup 1020->1030, T ramane neatins (randurile manuale nu se ating).
* Mock amessebox (mock_amessagebox.prg) raspunde Da(6) la dialogul "Suma in lei difera..." (ramas
* neschimbat de runda26) si logheaza textul INTEGRAL al fiecarui mesaj primit - folosit aici doar ca
* sa confirm ca "Actualizati totalul facturii" NU mai e cerut vreodata.
*
* Rulare (prin harness):
* powershell -ExecutionPolicy Bypass -File test_import_nota_total_ui.ps1
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET DECIMALS TO 4
SET NULLDISPLAY TO ''
CLOSE DATABASES
PUBLIC gcUILog, gcSyncDir
gcUILog = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\test_import_nota_total_ui_log.txt"
gcSyncDir = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\uisync_total\"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcUILog)
ON ERROR DO TfErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
TRY
LOCAL gcAppPath, lcPath
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;' + ;
ADDBS(SUBSTR(gcAppPath,1,RAT([\],gcAppPath,2)))+[COMUNROA\]
SET PATH TO &lcPath ADDITIVE
DO TfLog WITH 'SET PATH OK'
*----- CLASE -----
SET CLASSLIB TO (gcAppPath + "comun\clase\appwiz") 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 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 wwdialogs.vcx ADDITIVE
SET CLASSLIB TO oimportxml.vcx ADDITIVE
SET CLASSLIB TO excelxml.vcx ADDITIVE
SET CLASSLIB TO orapoarte_obinv.vcx ADDITIVE
DO TfLog WITH 'SET CLASSLIB OK'
*----- PROCEDURI (mock amessagebox + mock cauta_nom_articole PRIMELE, ui_harness la final) -----
SET PROCEDURE TO PROCEDURI
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_cauta_nom_articole.prg" 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 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 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 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
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\ui_harness.prg" ADDITIVE
DO TfLog WITH 'SET PROCEDURE OK'
*----- Globale -----
PUBLIC gnPc, gnPval, gnPcant, gnPpret, gnPPretval, gnPCurs, gnPVal, gnPPretV, gnPPretVal
STORE 2 TO gnPc, gnPval, gnPVal
gnPcant = 3
STORE 4 TO gnPpret, gnPPretval, gnPPretVal, gnPPretV, gnPCurs
PUBLIC gl406, gcS, gnAn, gnLuna, gnIdFirma, gnIdSucursala, gcAcces, gcFirma
gl406 = .T.
gcS = 'CONTAFIN'
gnAn = YEAR(DATE())
gnLuna = MONTH(DATE())
gnIdFirma = 110
gnIdSucursala = 110
gcAcces = "1;2;3;4;5;6;7;8;"
gcFirma = gcS
PUBLIC nror(65000)
*-- gnButon: vezi docs/testare-ui-vfp.md / test_adauga_repere_212.prg (lant cauta_alfa->CAUT->do_adauga_articol).
PUBLIC gnButon
STORE 2 TO gnButon
PUBLIC goExecutor, goApp
goExecutor = CREATEOBJECT('dummyexecutor')
goApp = CREATEOBJECT('dummyapp')
*----- poAct: antetul notei; dialogul mosteneste din el la Init -----
PUBLIC poAct
poAct = CREATEOBJECT('Custom')
poAct.AddProperty('nume_val', '')
poAct.AddProperty('curs', 1)
poAct.AddProperty('proc_tva', 1.21)
poAct.AddProperty('nnir', 0)
poAct.AddProperty('id_valuta', 0)
poAct.AddProperty('id_fdoc', 1)
poAct.AddProperty('fdoc', 'Factura')
poAct.AddProperty('id_partc', 500)
poAct.AddProperty('partc', 'FURNIZOR ANTET SRL')
poAct.AddProperty('serie_act', '')
poAct.AddProperty('dataact', DATE())
poAct.AddProperty('tva_incasare', 0)
poAct.AddProperty('id_set', 1)
poAct.AddProperty('id_gestin', 1)
*----- jtva_coloane2 (explicatii TVA): achizitii interne 21% - perechea folosita de sablon -----
IF USED('jtva_coloane2')
USE IN ('jtva_coloane2')
ENDIF
CREATE CURSOR jtva_coloane2 (ordine N(8), id_jtva_coloana N(14), denumire C(100), ;
jc N(1), jv N(1), afisat N(1), coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14))
INSERT INTO jtva_coloane2 VALUES (0, 0, '', 0, 0, 1, '', '', 0, 0)
INSERT INTO jtva_coloane2 VALUES (1, 208, 'ACH. INT. 21%', 1, 0, 1, 'RO21B', 'RO21T', 21, 209)
INSERT INTO jtva_coloane2 VALUES (2, 209, 'TVA ACH. INT. 21%', 1, 0, 1, 'RO21T', '', 21, 0)
*----- saft_taxtable: coduri reale (vsaft_taxtable) - achizitii interne 21% -----
IF USED('saft_taxtable')
USE IN ('saft_taxtable')
ENDIF
CREATE CURSOR saft_taxtable (taxname C(250) NULL, typename C(250) NULL, taxcode N(6) NULL, ;
taxtype N(3) NULL, descriere C(250) NULL, tip C(100) NULL, descriere_tip C(250) NULL, ;
procent_taxa N(7,2) NULL, procent_prorata N(7,2) NULL, inactiv N(1) NULL, tva N(1) NULL, ;
wht N(1) NULL, tva_achizitii N(1) NULL, tva_livrari N(1) NULL)
INDEX ON taxcode TAG taxcode
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('', 0, '', 0, 1, 1, 1, 1)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301104-Achizitii de bunuri si servicii taxabile cu cota de 21%, altele decat importurile si cele supuse masurilor de simplificare', 301104, '', 21, 1, 0, 1, 0)
*----- introdc (RecordSource Grid1) - porneste GOL, ca in fluxul real -----
DO CreeazaIntrodc WITH 'introdc'
*----- introdc_sablon: perechea-sablon (B 371/401 + T 4426/401) pe care do_adauga_factura o
* cloneaza (21%, ACH. INT. 21%). -----
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%')
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%')
GO TOP IN introdc_sablon
*----- rul_temp cu 1 rand INAINTE de instantiere (capcana k) - structura FIDELA VRUL. -----
DO CreeazaRulTemp
INSERT INTO rul_temp (denumire, codmat, cant, pret, pret_lei, cont, cota_tva) ;
VALUES ('PLACEHOLDER', 'PH', 1, 1, 1, '371', 21)
DO TfLog WITH 'cursoare pregatite, CREATEOBJECT(import_nota, .F.) - lIntern=.F. (import)'
SELECT introdc
PUBLIC goObj
goObj = CREATEOBJECT('IMPORT_nota', .F.)
IF VARTYPE(goObj) <> 'O'
DO TfLog WITH 'FAIL: instantiere import_nota'
DO HarnessDone WITH 'done-error'
QUIT
ENDIF
goObj.lDialogAratat = .T.
goObj.oact = poAct
goObj.WindowType = 0
goObj.Visible = .T.
goObj.Show()
goObj.WindowState = 2
DOEVENTS FORCE
*-- golesc placeholder-ul cu ZAP (nu DELETE ALL, capcana k)
SELECT rul_temp
ZAP
goObj.gridart.Refresh()
DOEVENTS FORCE
*========================= DOC: FACTURA 15000, 1000 EUR + TVA, curs 5.23, in_valuta=1 =========================
PUBLIC goDlg, goT
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = 15000
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 700
goDlg.cPartener = 'PARTENER TEST SRL'
goDlg.cExplicatia = 'Factura test runda25'
goDlg.nSuma = 1000
goDlg.nSumaLei = 0
goDlg.nCurs = 5.23
goDlg.nIdValuta = 978
goDlg.cValuta = 'EUR'
*-- ACH. INT. 21% (id 208) - achizitie normala, TVA la furnizor (F), fara DVI
goDlg.nIdExplicatieTva = 208
goDlg.cExplicatieTva = 'ACH. INT. 21%'
goDlg.optTipTva.Value = 1 && F = furnizor
goDlg.chkInValutaCont.Value = 1
goDlg.chkParticipaValuta.Value = 1
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO TfLog WITH 'DOC: valideaza (pe dialog) = ' + TRANSFORM(goDlg.valideaza())
DO ConstruiesteToDlg
DO TfLog WITH 'DOC: do_adauga_factura = ' + TRANSFORM(goObj.do_adauga_factura(goT))
goDlg.Hide()
DOEVENTS FORCE
LOCAL llB, llT, lnBSuma, lnBSumaVal, lnBCurs, lnBInValuta
SELECT introdc
LOCATE FOR nract = 15000 AND tip_rand == 'B'
llB = FOUND()
IF llB
lnBSuma = suma
lnBSumaVal = suma_val
lnBCurs = curs
lnBInValuta = in_valuta
ENDIF
LOCATE FOR nract = 15000 AND tip_rand == 'T'
llT = FOUND()
IF llB AND llT AND ABS(lnBSuma - 5230) < 0.01 AND ABS(lnBSumaVal - 1000) < 0.01 AND ABS(lnBCurs - 5.23) < 0.0001 AND lnBInValuta = 1
DO TfLog WITH 'PASS pas0a: factura 15000 adaugata (B suma=' + TRANSFORM(lnBSuma) + ' suma_val=' + TRANSFORM(lnBSumaVal) + ' curs=' + TRANSFORM(lnBCurs) + ' in_valuta=' + TRANSFORM(lnBInValuta) + '), rand T gasit'
ELSE
DO TfLog WITH 'FAIL pas0a: B?=' + TRANSFORM(llB) + ' T?=' + TRANSFORM(llT) + ' suma=' + TRANSFORM(IIF(llB,lnBSuma,-1)) + ' suma_val=' + TRANSFORM(IIF(llB,lnBSumaVal,-1)) + ' curs=' + TRANSFORM(IIF(llB,lnBCurs,-1)) + ' in_valuta=' + TRANSFORM(IIF(llB,lnBInValuta,-1))
ENDIF
*========================= PAS 0: factura principala adaugata =========================
DO HarnessStep WITH 0, 'factura 15000 adaugata: introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri (astept 2, B+T)'
*========================= ADAUGARE 2 ARTICOLE PRIN FLUXUL REAL: do_adauga_articol() =========================
PUBLIC gcMockArtCodmat
gcMockArtCodmat = 'ART-A8-371'
goObj.do_adauga_articol()
DOEVENTS FORCE
SELECT rul_temp
LOCATE FOR ALLTRIM(codmat) == 'ART-A8-371'
IF FOUND()
REPLACE cant WITH 1, pret_val WITH 900, pretd WITH 900, pret WITH ROUND(900*5.23,gnPc), pret_lei WITH pret
DO TfLog WITH 'articol 1 (ART-A8-371, cont 371) adaugat prin do_adauga_articol() REAL, cant/pret_val completate manual (900 EUR)'
ELSE
DO TfLog WITH 'FAIL: ART-A8-371 nu a fost gasit in rul_temp dupa do_adauga_articol()'
ENDIF
gcMockArtCodmat = 'ART-GREE-303'
goObj.do_adauga_articol()
DOEVENTS FORCE
SELECT rul_temp
LOCATE FOR ALLTRIM(codmat) == 'ART-GREE-303'
IF FOUND()
REPLACE cant WITH 1, pret_val WITH 100, pretd WITH 100, pret WITH ROUND(100*5.23,gnPc), pret_lei WITH pret
DO TfLog WITH 'articol 2 (ART-GREE-303, cont 303) adaugat prin do_adauga_articol() REAL, cant/pret_val completate manual (100 EUR)'
ELSE
DO TfLog WITH 'FAIL: ART-GREE-303 nu a fost gasit in rul_temp dupa do_adauga_articol()'
ENDIF
goObj.gridart.Refresh()
DOEVENTS FORCE
goObj.sincronizeaza()
DOEVENTS FORCE
goObj.grid1.Refresh()
DOEVENTS FORCE
DO TfLog WITH 'DIAG dump introdc dupa spargere:'
DO DumpIntrodc
*-- VERIFICARE spargere: 2 randuri S (900 EUR / 100 EUR), suma_doc_val ramane 1000 pe grup
LOCAL llS1, llS2, lnS1Val, lnS2Val, lnDocValS1, lnDocValS2, lnRecS900
SELECT introdc
LOCATE FOR tip_rand == 'S' AND ALLTRIM(scd) == '371'
llS1 = FOUND()
IF llS1
lnS1Val = suma_val
lnDocValS1 = suma_doc_val
lnRecS900 = RECNO()
ENDIF
LOCATE FOR tip_rand == 'S' AND ALLTRIM(scd) == '303'
llS2 = FOUND()
IF llS2
lnS2Val = suma_val
lnDocValS2 = suma_doc_val
ENDIF
IF llS1 AND llS2 AND ABS(lnS1Val - 900) < 0.01 AND ABS(lnS2Val - 100) < 0.01 AND ABS(lnDocValS1 - 1000) < 0.01 AND ABS(lnDocValS2 - 1000) < 0.01
DO TfLog WITH 'PASS pas1 spargere: 2 randuri S (371=' + TRANSFORM(lnS1Val) + ' EUR, 303=' + TRANSFORM(lnS2Val) + ' EUR), suma_doc_val=' + TRANSFORM(lnDocValS1) + ' pe grup'
ELSE
DO TfLog WITH 'FAIL pas1 spargere: S1?=' + TRANSFORM(llS1) + '(val=' + TRANSFORM(IIF(llS1,lnS1Val,-1)) + ') S2?=' + TRANSFORM(llS2) + '(val=' + TRANSFORM(IIF(llS2,lnS2Val,-1)) + ') suma_doc_val_S1=' + TRANSFORM(IIF(llS1,lnDocValS1,-1)) + ' suma_doc_val_S2=' + TRANSFORM(IIF(llS2,lnDocValS2,-1))
ENDIF
*========================= PAS 1: dupa spargere in 2 randuri S =========================
DO HarnessStep WITH 1, 'spargere: S(371)=' + TRANSFORM(IIF(llS1,lnS1Val,-1)) + ' EUR, S(303)=' + TRANSFORM(IIF(llS2,lnS2Val,-1)) + ' EUR, suma_doc_val=' + TRANSFORM(IIF(llS1,lnDocValS1,-1))
*========================= PAS 2A: editare rand S 900->910, lRecalcTva implicit .T. =========================
*-- randul S e in_valuta=1 -> Grid1.cSuma.Text1.When il blocheaza; editabil e DOAR cSumaVal (12506).
*-- gnMockRaspuns=6 (Da la "recalcularea sumei in lei" - singurul dialog ramas in Valid; dialogul
*-- "Actualizati totalul facturii?" a fost eliminat de runda26a, totalul se actualizeaza automat).
PUBLIC gnMockRaspuns
gnMockRaspuns = 6
LOCAL lnPozitieLogInainte2a
lnPozitieLogInainte2a = LEN(IIF(FILE(gcUILog), FILETOSTR(gcUILog), ''))
SELECT introdc
GO lnRecS900
goObj.nOldVal = 900
goObj.Grid1.cSumaVal.Text1.Value = 910
TRY
goObj.Grid1.cSumaVal.Text1.Valid()
DO TfLog WITH 'PAS2A: Grid1.cSumaVal.Text1.Valid() executat fara eroare'
CATCH TO loExc2a
DO TfLog WITH 'PAS2A EROARE ' + TRANSFORM(loExc2a.ErrorNo) + ' [' + loExc2a.Message + '] in ' + loExc2a.Procedure + ':' + TRANSFORM(loExc2a.LineNo) + ' (' + loExc2a.LineContents + ')'
ENDTRY
DOEVENTS FORCE
*-- verific in portiunea NOUA din log (de la pozitia dinainte de Valid()) ca dialogul vechi
*-- "Actualizati totalul facturii" NU a mai fost cerut mock-ului (runda26a)
LOCAL lcLogDupa2a
lcLogDupa2a = SUBSTR(IIF(FILE(gcUILog), FILETOSTR(gcUILog), ''), lnPozitieLogInainte2a + 1)
IF !('Actualizati totalul facturii' $ lcLogDupa2a)
DO TfLog WITH 'PASS pas2a fara dialog total: "Actualizati totalul facturii" nu a mai fost cerut mock-ului (runda26a)'
ELSE
DO TfLog WITH 'FAIL pas2a fara dialog total: dialogul vechi "Actualizati totalul facturii" inca apare in log'
ENDIF
SELECT introdc
LOCATE FOR nract = 15000 AND tip_rand == 'S' AND ALLTRIM(scd) == '371'
IF FOUND()
lnRecS900 = RECNO()
ENDIF
LOCAL lnSumaDocValDupa2a, lcDocKeyGrup
lnSumaDocValDupa2a = suma_doc_val
lcDocKeyGrup = doc_key
IF ABS(lnSumaDocValDupa2a - 1010) < 0.01
DO TfLog WITH 'PASS pas2a suma_doc_val actualizata automat: suma_doc_val=' + TRANSFORM(lnSumaDocValDupa2a) + ' (astept 1010, fara dialog)'
ELSE
DO TfLog WITH 'FAIL pas2a suma_doc_val: suma_doc_val=' + TRANSFORM(lnSumaDocValDupa2a) + ' (astept 1010)'
ENDIF
*-- rand T (nemanual) trebuie recalculat automat (runda26b, lRecalcTva implicit .T.): o singura
*-- cota (21%) pe rul_temp => T.suma_val = ROUND(suma_doc_val*21/100,gnPval)
LOCAL lnTSumaValAsteptatA, lnTSumaAsteptatA, lnTSumaValDupaA, lnTSumaDupaA
lnTSumaValAsteptatA = ROUND(lnSumaDocValDupa2a * 21 / 100, gnPval)
lnTSumaAsteptatA = ROUND(lnTSumaValAsteptatA * 5.23, gnPc)
SELECT introdc
LOCATE FOR doc_key == lcDocKeyGrup AND tip_rand == 'T'
lnTSumaValDupaA = suma_val
lnTSumaDupaA = suma
IF ABS(lnTSumaValDupaA - lnTSumaValAsteptatA) < 0.01 AND ABS(lnTSumaDupaA - lnTSumaAsteptatA) < 0.01
DO TfLog WITH 'PASS pas2a recalc TVA automat: T.suma_val=' + TRANSFORM(lnTSumaValDupaA) + ' T.suma=' + TRANSFORM(lnTSumaDupaA) + ' (astept ' + TRANSFORM(lnTSumaValAsteptatA) + '/' + TRANSFORM(lnTSumaAsteptatA) + ')'
ELSE
DO TfLog WITH 'FAIL pas2a recalc TVA automat: T.suma_val=' + TRANSFORM(lnTSumaValDupaA) + ' T.suma=' + TRANSFORM(lnTSumaDupaA) + ' (astept ' + TRANSFORM(lnTSumaValAsteptatA) + '/' + TRANSFORM(lnTSumaAsteptatA) + ')'
ENDIF
*========================= PAS 2: dupa editare S 900->910 (auto-total + recalc TVA) =========================
DO HarnessStep WITH 2, 'editare S 900->910: suma_doc_val=' + TRANSFORM(lnSumaDocValDupa2a) + ' T.suma_val=' + TRANSFORM(lnTSumaValDupaA)
*========================= PAS 3B: editare S 910->920, Thisform.lRecalcTva = .F. =========================
goObj.lRecalcTva = .F.
SELECT introdc
GO lnRecS900
goObj.nOldVal = 910
goObj.Grid1.cSumaVal.Text1.Value = 920
TRY
goObj.Grid1.cSumaVal.Text1.Valid()
DO TfLog WITH 'PAS3B: Grid1.cSumaVal.Text1.Valid() executat fara eroare'
CATCH TO loExc3b
DO TfLog WITH 'PAS3B EROARE ' + TRANSFORM(loExc3b.ErrorNo) + ' [' + loExc3b.Message + '] in ' + loExc3b.Procedure + ':' + TRANSFORM(loExc3b.LineNo) + ' (' + loExc3b.LineContents + ')'
ENDTRY
DOEVENTS FORCE
SELECT introdc
LOCATE FOR nract = 15000 AND tip_rand == 'S' AND ALLTRIM(scd) == '371'
IF FOUND()
lnRecS900 = RECNO()
ENDIF
LOCAL lnSumaDocValDupa3b
lnSumaDocValDupa3b = suma_doc_val
IF ABS(lnSumaDocValDupa3b - 1020) < 0.01
DO TfLog WITH 'PASS pas3b total tot actualizat: suma_doc_val=' + TRANSFORM(lnSumaDocValDupa3b) + ' (astept 1020, chiar cu lRecalcTva=.F.)'
ELSE
DO TfLog WITH 'FAIL pas3b total: suma_doc_val=' + TRANSFORM(lnSumaDocValDupa3b) + ' (astept 1020)'
ENDIF
LOCAL lnTSumaValDupaB
SELECT introdc
LOCATE FOR doc_key == lcDocKeyGrup AND tip_rand == 'T'
lnTSumaValDupaB = suma_val
IF ABS(lnTSumaValDupaB - lnTSumaValAsteptatA) < 0.01
DO TfLog WITH 'PASS pas3b T neschimbat (lRecalcTva=.F.): T.suma_val=' + TRANSFORM(lnTSumaValDupaB) + ' (neschimbat fata de pasul A, ' + TRANSFORM(lnTSumaValAsteptatA) + ')'
ELSE
DO TfLog WITH 'FAIL pas3b T ar fi trebuit sa ramana neschimbat: T.suma_val=' + TRANSFORM(lnTSumaValDupaB) + ' (astept neschimbat, ' + TRANSFORM(lnTSumaValAsteptatA) + ')'
ENDIF
*========================= PAS 3: dupa editare S 910->920, lRecalcTva=.F. (T neatins) =========================
DO HarnessStep WITH 3, 'editare S 910->920, lRecalcTva=.F.: suma_doc_val=' + TRANSFORM(lnSumaDocValDupa3b) + ' T.suma_val=' + TRANSFORM(lnTSumaValDupaB) + ' (neschimbat)'
*========================= PAS 4: editare S 920->930, lRecalcTva=.T. dar T mod_manual=1 =========================
goObj.lRecalcTva = .T.
SELECT introdc
LOCATE FOR doc_key == lcDocKeyGrup AND tip_rand == 'T'
REPLACE mod_manual WITH 1
SELECT introdc
GO lnRecS900
goObj.nOldVal = 920
goObj.Grid1.cSumaVal.Text1.Value = 930
TRY
goObj.Grid1.cSumaVal.Text1.Valid()
DO TfLog WITH 'PAS4: Grid1.cSumaVal.Text1.Valid() executat fara eroare'
CATCH TO loExc4
DO TfLog WITH 'PAS4 EROARE ' + TRANSFORM(loExc4.ErrorNo) + ' [' + loExc4.Message + '] in ' + loExc4.Procedure + ':' + TRANSFORM(loExc4.LineNo) + ' (' + loExc4.LineContents + ')'
ENDTRY
DOEVENTS FORCE
DO TfLog WITH 'DIAG dump introdc dupa pas4:'
DO DumpIntrodc
SELECT introdc
LOCATE FOR nract = 15000 AND tip_rand == 'S' AND ALLTRIM(scd) == '371'
LOCAL lnSumaDocValDupa4
lnSumaDocValDupa4 = suma_doc_val
IF ABS(lnSumaDocValDupa4 - 1030) < 0.01
DO TfLog WITH 'PASS pas4 total tot actualizat: suma_doc_val=' + TRANSFORM(lnSumaDocValDupa4) + ' (astept 1030, chiar cu T mod_manual=1)'
ELSE
DO TfLog WITH 'FAIL pas4 total: suma_doc_val=' + TRANSFORM(lnSumaDocValDupa4) + ' (astept 1030)'
ENDIF
LOCAL lnTSumaValDupa4
SELECT introdc
LOCATE FOR doc_key == lcDocKeyGrup AND tip_rand == 'T'
lnTSumaValDupa4 = suma_val
IF ABS(lnTSumaValDupa4 - lnTSumaValAsteptatA) < 0.01
DO TfLog WITH 'PASS pas4 T manual neatins: T.suma_val=' + TRANSFORM(lnTSumaValDupa4) + ' (neschimbat, mod_manual=1 exclus din recalc_tva_document)'
ELSE
DO TfLog WITH 'FAIL pas4 T manual ar fi trebuit sa ramana neatins: T.suma_val=' + TRANSFORM(lnTSumaValDupa4) + ' (astept neschimbat, ' + TRANSFORM(lnTSumaValAsteptatA) + ')'
ENDIF
*========================= PAS 4: dupa editare S 920->930, T mod_manual=1 (neatins) =========================
DO HarnessStep WITH 4, 'editare S 920->930, T mod_manual=1: suma_doc_val=' + TRANSFORM(lnSumaDocValDupa4) + ' T.suma_val=' + TRANSFORM(lnTSumaValDupa4) + ' (neatins)'
goObj.sincronizeaza()
DOEVENTS FORCE
LOCAL lcMesajSyncFinal
lcMesajSyncFinal = goObj.cmesajsync
DO TfLog WITH 'cmesajsync final (' + TRANSFORM(LEN(lcMesajSyncFinal)) + ' caractere) = [' + lcMesajSyncFinal + ']'
IF !('suma subrandurilor' $ lcMesajSyncFinal)
DO TfLog WITH 'PASS mesaj E2 absent: totalul e mentinut sincron automat la fiecare editare (runda26a), fara mesajul "suma subrandurilor"'
ELSE
DO TfLog WITH 'FAIL mesaj E2 prezent: cmesajsync contine "suma subrandurilor" desi totalul ar trebui sincronizat automat - [' + lcMesajSyncFinal + ']'
ENDIF
goObj.recalculeaza()
goObj.actualizeaza_banda()
goObj.grid1.Refresh()
DOEVENTS FORCE
*========================= PAS 5: stare finala =========================
DO HarnessStep WITH 5, 'final: introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri, nbaza_val=' + TRANSFORM(goObj.nbaza_val) + ' ntva_val=' + TRANSFORM(goObj.ntva_val)
DO TfLog WITH 'GATA - scenariu runda26a/26b executat integral'
DO HarnessDone WITH 'done'
CATCH TO loExc
DO TfLog WITH 'CATCH ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']'
DO HarnessDone WITH 'done-error'
ENDTRY
QUIT
*==================================================================================
PROCEDURE ConstruiesteToDlg
*-- toDlg construit INLINE in programul PRINCIPAL (ADDPROPERTY da eroare 11 din proceduri in
*-- acest runtime headless - vezi docs/testare-ui-vfp.md capcana l).
goT = CREATEOBJECT('Empty')
=ADDPROPERTY(goT,'serie_act',ALLTRIM(NVL(goDlg.cSerieAct,'')))
=ADDPROPERTY(goT,'nract',goDlg.nNract)
=ADDPROPERTY(goT,'dataact',goDlg.dDataAct)
=ADDPROPERTY(goT,'fdoc',goDlg.cFelDoc)
=ADDPROPERTY(goT,'id_fdoc',goDlg.nIdFdoc)
=ADDPROPERTY(goT,'id_partc',goDlg.nIdPartener)
=ADDPROPERTY(goT,'partc',goDlg.cPartener)
=ADDPROPERTY(goT,'explicatia',ALLTRIM(NVL(goDlg.cExplicatia,'')))
=ADDPROPERTY(goT,'suma',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,IIF(goDlg.nSumaLei<>0,goDlg.nSumaLei,ROUND(goDlg.nSuma*goDlg.nCurs,gnPC)),goDlg.nSuma))
=ADDPROPERTY(goT,'suma_val',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,goDlg.nSuma,0))
=ADDPROPERTY(goT,'in_valuta',goDlg.chkInValutaCont.Value)
=ADDPROPERTY(goT,'participa_valuta',(goDlg.chkParticipaValuta.Value=1))
=ADDPROPERTY(goT,'id_valuta',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nIdValuta,0))
=ADDPROPERTY(goT,'curs',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nCurs,0))
=ADDPROPERTY(goT,'nume_val',IIF(goDlg.chkInValutaCont.Value=1,ALLTRIM(NVL(goDlg.cValuta,'')),''))
=ADDPROPERTY(goT,'cTipTva',IIF(goDlg.optTipTva.Value=1,'F',IIF(goDlg.optTipTva.Value=2,'D','N')))
=ADDPROPERTY(goT,'id_jtva_coloana',goDlg.nIdExplicatieTva)
=ADDPROPERTY(goT,'dvi_serie',CHRTRAN(ALLTRIM(NVL(goDlg.cSerieDvi,'')),CHR(34),''))
=ADDPROPERTY(goT,'dvi_nract',goDlg.nNractDvi)
=ADDPROPERTY(goT,'dvi_dataact',goDlg.dDviData)
=ADDPROPERTY(goT,'dvi_id_fdoc',goDlg.nIdFdocDVI)
=ADDPROPERTY(goT,'dvi_fdoc',goDlg.cFelDocDvi)
=ADDPROPERTY(goT,'dvi_id_partc',goDlg.nDviIdPartener)
=ADDPROPERTY(goT,'dvi_partc',goDlg.cDviPartener)
=ADDPROPERTY(goT,'dvi_scc','401')
=ADDPROPERTY(goT,'dvi_tva_lei',goDlg.nDviTvaLei)
=ADDPROPERTY(goT,'dvi_tva_val',goDlg.nDviTvaVal)
ENDPROC
PROCEDURE CreeazaRulTemp
*-- structura reala a rul_temp (vezi ointroduceri.vc2:11030 si test_adauga_repere_212.prg).
IF USED('rul_temp')
USE IN ('rul_temp')
ENDIF
CREATE CURSOR rul_temp ( ;
id_rul N(20,0), an N(4,0), luna N(2,0), cod N(20,0);
, serie C(100), nnir N(20,0), id_articol N(10,0), denumire C(100);
, codmat C(50), codmatf C(50), codbare C(50), um C(20);
, id_gestiune N(5,0), nume_gestiune C(50), cgest C(20), nr_pag N(2,0);
, gestionar C(50), comisie_receptie1 C(50), comisie_receptie2 C(50), comisie_receptie3 C(50);
, cant N(14,3), cante N(14,3), cont C(10), acont C(20);
, pret N(18,4), tva N(18,4), valoare N(18,4), valtva N(18,4);
, proc_tva N(5,2), pretv N(18,4), pretvtva N(18,4), tvav N(18,4);
, valoarev N(18,4), valtvav N(18,4), proc_tvav N(5,2), adaos N(18,4);
, adaos_tva N(18,4), valoare_adaos N(18,4), valtva_adaos N(18,4), procent N(10,3);
, discunitar N(18,4), discount_tva N(18,4), valoare_discount N(18,4), valtva_discount N(18,4);
, proc_disc N(7,3), pretd N(14,4), curs N(18,4), id_valuta N(10,0);
, nume_val C(20), id_lucrare N(20,0), nrord C(100), id_responsabil N(10,0);
, nresp C(100), resp_marca N(18,4), dataact T, id_util N(5,0);
, util C(30), dataora T, id_sectie N(5,0), sectie C(50);
, csectie C(10), alcooltutun N(1,0), datain T, dataout T;
, id_fact N(20,0), id_gestiunec N(10,0), nume_gestiunec C(50), cgestc C(20);
, id_responsabilc N(5,0), id_reteta N(10,0), reteta C(50), nrespc C(100);
, respc_marca N(18,4), id_set N(20,0), id_tip_rulaj N(10,0), tip_rulaj C(50);
, id_obiect_depozit N(10,0), id_rul_aux N(10,0), nract N(20,0), serie_act C(10);
, dataoras T, id_utils N(10,0), lot C(30), adata_expirare T;
, id_sucursala N(5,0), sucursala C(250), id_part_rez N(10,0), part_rez C(100);
, id_lucrare_rez N(10,0), nrord_rez C(100), subgrupa C(100), grupa C(100);
, id_subgrupa N(5,0), id_grupa N(5,0), in_stoc N(1,0), in_crm N(1,0);
, id_furnizor N(10,0), furnizor C(100), id_jtva_coloana N(4,0), explicatie_tva C(100);
, taxcode N(6,0), taxname C(254), saft_procent N(18,4), codnc8 C(20);
, id_tara_origine N(4,0), cod_tara_origine C(5), tara_origine C(50), greutate N(12,4);
, fdoc C(30), id_fdoc N(18,4);
, pret_lei N(18,4), pret_val N(14,4), cota_tva N(6,2))
ENDPROC
PROCEDURE CreeazaIntrodc
LPARAMETERS tcAlias
IF USED(tcAlias)
USE IN (tcAlias)
ENDIF
CREATE CURSOR (tcAlias) ( ;
id_note N(14), explicatia C(100), scd C(10), ascd C(20), scc C(10), ascc C(20), ;
cu_tva N(1), id_set N(14), ordine N(8), in_valuta N(1), id_jtva_coloana N(14) NULL, ;
ptva N(6,2), explicatie_tva C(50), tipjurnal C(2), taxcode N(6), paymentcode C(9), ;
suma N(18,4), suma_val N(18,4), id_partd N(14), id_partc N(14), partd C(100), partc C(100), ;
id_fact N(14), id_factd N(14), id_factc N(14), pereched N(14), perechec N(14), ;
nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), ;
scd_orig C(20), ascd_orig C(20))
ENDPROC
PROCEDURE DumpIntrodc
LOCAL lnSel
lnSel = SELECT()
SELECT introdc
SCAN
DO TfLog WITH ' recno=' + TRANSFORM(RECNO()) + ' nract=' + TRANSFORM(nract) + ' tip_rand=' + tip_rand + ;
' scd=' + ALLTRIM(scd) + ' suma=' + TRANSFORM(suma) + ' suma_val=' + TRANSFORM(suma_val) + ;
' suma_doc=' + TRANSFORM(suma_doc) + ' suma_doc_val=' + TRANSFORM(suma_doc_val) + ;
' mod_manual=' + TRANSFORM(NVL(mod_manual,0)) + ' doc_key=[' + ALLTRIM(doc_key) + ']'
ENDSCAN
SELECT (lnSel)
ENDPROC
FUNCTION RECCOUNT_ACTIVE
LPARAMETERS tcAlias
LOCAL lnSel, lnCnt
lnSel = SELECT()
SELECT (tcAlias)
COUNT TO lnCnt FOR !DELETED()
SELECT (lnSel)
RETURN lnCnt
ENDFUNC
PROCEDURE TfErr
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
DO TfLog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
ENDPROC
PROCEDURE TfLog
LPARAMETERS tcMsg
SET SAFETY OFF
LOCAL lcL
lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '')
STRTOFILE(lcL + tcMsg + CHR(13)+CHR(10), gcUILog)
ENDPROC
DEFINE CLASS dummyapp AS Custom
PROCEDURE ReadIni
LPARAMETERS tcSection, tcKey
RETURN ''
ENDPROC
PROCEDURE WriteIni
LPARAMETERS tcSection, tcKey, tcValue
RETURN .T.
ENDPROC
ENDDEFINE
DEFINE CLASS dummyexecutor AS Custom
cEroare = ''
PROCEDURE oExecute
LPARAMETERS tcSql, tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF 'VJTVA_COLOANE' $ UPPER(m.tcSql)
DO CreeazaJtvaColoaneView WITH m.tcCursor
RETURN 1
ENDIF
IF UPPER(ALLTRIM(m.tcCursor)) == 'RUL_TEMP'
DO CreeazaRulTemp
ELSE
CREATE CURSOR (m.tcCursor) (id_temp N(1))
ENDIF
RETURN 1
ENDPROC
PROCEDURE oExecuta
LPARAMETERS tcSql, tcCursor
IF !EMPTY(m.tcCursor)
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF UPPER(m.tcCursor) == 'CJTVACOL4427'
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14))
ELSE
CREATE CURSOR (m.tcCursor) (id_temp N(1))
ENDIF
ENDIF
RETURN .T.
ENDPROC
PROCEDURE oSelect2Value
LPARAMETERS tcSql, toValue
toValue = ''
RETURN 1
ENDPROC
PROCEDURE oReset
ENDPROC
ENDDEFINE
PROCEDURE CreeazaJtvaColoaneView
LPARAMETERS tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14), denumire C(100), jc N(1), jv N(1), ;
coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14) NULL, afisat N(1), ;
id_jtva_ex N(14) NULL, id_jtva_neex N(14) NULL, ordine N(8), ;
taxcode N(6) NULL, taxcode_neexigibil N(6) NULL, taxcode_n50 N(6) NULL, ;
taxcode_n50_tvai N(6) NULL, taxcode_n100 N(6) NULL, taxcode_regularizare N(6) NULL, taxcode_tvai N(6) NULL)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, afisat, ordine, cota_tva) VALUES (0, '', 0, 0, 1, 0, 0)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (208, 'ACH. INT. 21%', 1, 0, 'RO21B', 21, 209, 1, 1, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (209, 'TVA ACH. INT. 21%', 1, 0, 'RO21T', 21, 1, 2, 301104)
ENDPROC

View File

@@ -0,0 +1,11 @@
# test_import_nota_total_ui.ps1 - wrapper subtire peste harness-ul generic vfp_ui_harness.ps1.
# Testeaza runda26a/26b (actualizare AUTOMATA a totalului facturii + recalc TVA la editare
# manuala a unui rand S in valuta, controlat de Thisform.lRecalcTva).
# Rulare: powershell -ExecutionPolicy Bypass -File test_import_nota_total_ui.ps1
$ErrorActionPreference = 'Stop'
$Teste = $PSScriptRoot
& (Join-Path (Split-Path $Teste -Parent) 'vfp_ui_harness.ps1') `
-TestPrg (Join-Path $Teste 'test_import_nota_total_ui.prg') `
-Steps @('factura_adaugata','spargere_articole','editare_S_auto_recalc_tva','editare_S_lRecalcTva_false','editare_S_T_manual_neatins','final') `
-ShotsDir (Join-Path $Teste 'screenshots_total') `
-SyncDir (Join-Path $Teste 'uisync_total')

View File

@@ -0,0 +1,657 @@
* test_import_nota_ui.prg
* Test UI VIZIBIL pentru clasa IMPORT_nota (COMUN\clase\ointroduceri.vcx,
* parent frm_termin_renunt OF _frm_child.vcx). Spre deosebire de
* test_repro_import_nota.prg (care doar instantiaza headless), acesta:
* 1. Populeaza introdc (RecordSource Grid1) si rul_temp (RecordSource GridArt)
* cu randuri realiste (2 documente, TVA 19/21%, 2 articole).
* 2. Afiseaza formularul REAL, maximizat (modeless).
* 3. Executa actiuni cu verificare PASS/FAIL a efectului in date.
* 4. Handshake cu harness-ul PowerShell prin procedurile din ui_harness.prg
* (HarnessStep/HarnessDone) - screenshot dupa fiecare pas; auto-continue daca
* ruleaza fara harness.
* Pasi: 0 afisare, 1 recalculeaza, 2 sincronizeaza, 3 sterge articol (direct),
* 4 sterge articol prin BUTONUL real (mock amessagebox) - verifica bugul
* "Record is out of range" din do_calculeaza_diferente.
*
* Rulare (prin harness):
* powershell -ExecutionPolicy Bypass -File vfp_ui_harness.ps1 -TestPrg <acest.prg> -Steps @(...)
* Log: test_import_nota_ui_log.txt
*-- SET SAFETY OFF + TALK OFF PRIMELE, INAINTE de orice STRTOFILE: altfel prima scriere a
*-- log-ului (daca fisierul exista deja) scoate dialogul modal "overwrite?" care blocheaza
*-- rularea headless; iar TALK ON face SUM/CALCULATE sa deseneze text parazit peste formular.
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET DECIMALS TO 4
SET NULLDISPLAY TO ''
CLOSE DATABASES
PUBLIC gcUILog, gcSyncDir
gcUILog = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\test_import_nota_ui_log.txt"
gcSyncDir = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\uisync\"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcUILog)
ON ERROR DO UIErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
TRY
LOCAL gcAppPath, lcPath
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;' + ;
ADDBS(SUBSTR(gcAppPath,1,RAT([\],gcAppPath,2)))+[COMUNROA\]
SET PATH TO &lcPath ADDITIVE
DO UILog WITH 'SET PATH OK'
*----- CLASE -----
SET CLASSLIB TO (gcAppPath + "comun\clase\appwiz") 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 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 wwdialogs.vcx ADDITIVE
SET CLASSLIB TO oimportxml.vcx ADDITIVE
SET CLASSLIB TO excelxml.vcx ADDITIVE
SET CLASSLIB TO orapoarte_obinv.vcx ADDITIVE
DO UILog WITH 'SET CLASSLIB OK'
*----- PROCEDURI -----
SET PROCEDURE TO PROCEDURI
*-- mock amessagebox INCARCAT PRIMUL (inaintea oproceduri_comune.prg, care are amessagebox
*-- real): in VFP, la nume duplicat de procedura, castiga fisierul cautat PRIMUL in lista.
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_amessagebox.prg" 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 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 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 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
*----- Harness UI reutilizabil (mock amessagebox e incarcat mai sus, primul). -----
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\ui_harness.prg" ADDITIVE
DO UILog WITH 'SET PROCEDURE OK'
*----- Globale minimale cerute de definitia clasei / Init -----
PUBLIC gnPc, gnPval, gnPcant, gnPpret, gnPPretval, gnPCurs, gnPVal, gnPPretV, gnPPretVal
gnPc = 2
gnPval = 2
gnPVal = 2
gnPcant = 3
gnPpret = 4
gnPPretval = 4
gnPPretVal = 4
gnPPretV = 4
gnPCurs = 4
PUBLIC gl406, gcS, gnAn, gnLuna, gnIdFirma, gnIdSucursala, gcAcces, gcFirma
*-- SAFT (406) mereu activ in teste: exercita GetTaxCode/GetTaxCodeIdPart/taxcode pe randuri.
gl406 = .T.
gcS = 'CONTAFIN'
gnAn = YEAR(DATE())
gnLuna = MONTH(DATE())
gnIdFirma = 110
gnIdSucursala = 110
gcAcces = "1;2;3;4;5;6;7;8;"
gcFirma = gcS
PUBLIC nror(65000)
*----- goExecutor dummy: creeaza cursoarele cerute fara Oracle real -----
PUBLIC goExecutor
goExecutor = CREATEOBJECT('dummyexecutor')
DO UILog WITH 'goExecutor dummy creat'
*----- goApp dummy: _frm_base.Init cere goApp.ReadIni (FONTSIZEPLUS/FONTNAME) -----
PUBLIC goApp
goApp = CREATEOBJECT('dummyapp')
DO UILog WITH 'goApp dummy creat'
*----- poAct dummy: obiectul act (curs valutar, procent TVA) -----
PUBLIC poAct
poAct = CREATEOBJECT('Custom')
poAct.AddProperty('nume_val', 'EUR')
poAct.AddProperty('curs', 5)
poAct.AddProperty('proc_tva', 1.19)
poAct.AddProperty('nnir', 0)
*-- ceruta de UpdateExplicatieSAFT (PAS 5: gl406=.T. => aplica_explicatie_tva -> UpdateExplicatieSAFT -> poAct.dataact)
poAct.AddProperty('dataact', DATE())
*----- jtva_coloane2: structura din ointroduceri.prg (SELECT ... INTO CURSOR). Perechi
* baza/TVA REALE (Oracle dev, vjtva_coloane, 17.07.2026), regimul curent 21%/11%
* (post 01.08.2025) + import (DVI): id_tva pe baza leaga spre coloana T (aplica_explicatie_tva). -----
IF USED('jtva_coloane2')
USE IN ('jtva_coloane2')
ENDIF
CREATE CURSOR jtva_coloane2 (ordine N(8), id_jtva_coloana N(14), denumire C(100), ;
jc N(1), jv N(1), afisat N(1), coloana_jc C(20), coloana_jv C(20), ;
cota_tva N(6,2), id_tva N(14))
INSERT INTO jtva_coloane2 VALUES (0, 0, '', 0, 0, 1, '', '', 0, 0)
INSERT INTO jtva_coloane2 VALUES (1, 208, 'ACH. INT. 21%', 1, 0, 1, 'RO21B', 'RO21T', 21, 209)
INSERT INTO jtva_coloane2 VALUES (2, 209, 'TVA ACH. INT. 21%', 1, 0, 1, 'RO21T', '', 21, 0)
INSERT INTO jtva_coloane2 VALUES (3, 212, 'ACH. INT. 11%', 1, 0, 1, 'RO11B', 'RO11T', 11, 213)
INSERT INTO jtva_coloane2 VALUES (4, 213, 'TVA ACH. INT. 11%', 1, 0, 1, 'RO11T', '', 11, 0)
INSERT INTO jtva_coloane2 VALUES (5, 220, 'ACH. IMP. 21%', 1, 0, 1, 'FO21B', 'FO21T', 21, 221)
INSERT INTO jtva_coloane2 VALUES (6, 221, 'TVA ACH. IMP. 21%', 1, 0, 1, 'FO21T', '', 21, 0)
DO UILog WITH 'jtva_coloane2 creat (7 randuri, perechi reale 21%/11%/import)'
*----- saft_taxtable: coduri reale (vsaft_taxtable, achizitii interne + import, cota 21%/11%) -----
IF USED('saft_taxtable')
USE IN ('saft_taxtable')
ENDIF
CREATE CURSOR saft_taxtable (taxname C(250) NULL, typename C(250) NULL, taxcode N(6) NULL, ;
taxtype N(3) NULL, descriere C(250) NULL, tip C(100) NULL, descriere_tip C(250) NULL, ;
procent_taxa N(7,2) NULL, procent_prorata N(7,2) NULL, inactiv N(1) NULL, tva N(1) NULL, ;
wht N(1) NULL, tva_achizitii N(1) NULL, tva_livrari N(1) NULL)
INDEX ON taxcode TAG taxcode
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('', 0, '', 0, 1, 1, 1, 1)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301104-Achizitii de bunuri si servicii taxabile cu cota de 21%, altele decat importurile si cele supuse masurilor de simplificare', 301104, '', 21, 1, 0, 1, 0)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301105-Achizitii de bunuri si servicii taxabile cu cota de 11%, altele decat importurile si cele supuse masurilor de simplificare', 301105, '', 11, 1, 0, 1, 0)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301204-Import de bunuri cota 21%', 301204, '', 21, 1, 0, 1, 0)
DO UILog WITH 'saft_taxtable creat (coduri reale 301104/301105/301204)'
*----- introdc: RecordSource Grid1. id_jtva_coloana NULL (recalc_diferente il seteaza Null pe D). -----
IF USED('introdc')
USE IN ('introdc')
ENDIF
CREATE CURSOR introdc ( ;
id_note N(14), explicatia C(100), scd C(10), ascd C(20), scc C(10), ascc C(20), ;
cu_tva N(1), id_set N(14), ordine N(8), in_valuta N(1), id_jtva_coloana N(14) NULL, ;
ptva N(6,2), explicatie_tva C(50), tipjurnal C(2), taxcode N(6), paymentcode C(9), ;
suma N(18,4), suma_val N(18,4), id_partd N(14), id_partc N(14), partd C(100), partc C(100), ;
id_fact N(14), id_factd N(14), id_factc N(14), pereched N(14), perechec N(14), ;
nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), ;
scd_orig C(20), ascd_orig C(20))
*-- Document unic (nract=1001/serie A pentru toate randurile => acelasi doc_key). doc_key
*-- populat explicit (padded C(80) la stocare, ca in fluxul real) - vezi PAS 5: comparatia
*-- ==Thisform.calc_doc_key() (trim) NU se potriveste niciodata cu campul stocat padded
*-- (bug documentat in docs\handoff_teste_ui_import.md).
*-- 2 randuri Baza (B) 21%+11% + 2 randuri TVA (T). Baza totala lei = 1500, TVA total = 265
*-- (1000*21%=210 + 500*11%=55) - regimul curent post 01.08.2025.
INSERT INTO introdc (tip_rand, scd, scc, ascc, suma, id_jtva_coloana, ptva, explicatie_tva, ;
in_valuta, participa_valuta, nr_doc, nract, serie_act, fdoc, partc, explicatia, ;
cu_tva, dataact, suma_doc, doc_key) ;
VALUES ('B','371','401','FURN01', 1000, 208, 21, 'ACH. INT. 21%', ;
0, .T., 1, 1001, 'A', 'Factura', 'FURNIZOR ABC SRL', 'Marfa achizitionata 21%', ;
1, DATE(), 1500, 'A|1001|0|0')
INSERT INTO introdc (tip_rand, scd, scc, ascc, suma, id_jtva_coloana, ptva, explicatie_tva, ;
in_valuta, participa_valuta, nr_doc, nract, serie_act, fdoc, partc, explicatia, ;
cu_tva, dataact, suma_doc, doc_key) ;
VALUES ('B','371','401','FURN01', 500, 212, 11, 'ACH. INT. 11%', ;
0, .T., 1, 1001, 'A', 'Factura', 'FURNIZOR ABC SRL', 'Marfa achizitionata 11%', ;
1, DATE(), 1500, 'A|1001|0|0')
INSERT INTO introdc (tip_rand, scd, scc, ascc, suma, id_jtva_coloana, ptva, explicatie_tva, ;
in_valuta, participa_valuta, nr_doc, nract, serie_act, fdoc, partc, explicatia, ;
cu_tva, dataact, suma_doc, doc_key) ;
VALUES ('T','4426','401','FURN01', 210, 209, 21, 'TVA ACH. INT. 21%', ;
0, .T., 1, 1001, 'A', 'Factura', 'FURNIZOR ABC SRL', 'TVA deductibil 21%', ;
1, DATE(), 1500, 'A|1001|0|0')
INSERT INTO introdc (tip_rand, scd, scc, ascc, suma, id_jtva_coloana, ptva, explicatie_tva, ;
in_valuta, participa_valuta, nr_doc, nract, serie_act, fdoc, partc, explicatia, ;
cu_tva, dataact, suma_doc, doc_key) ;
VALUES ('T','4426','401','FURN01', 55, 213, 11, 'TVA ACH. INT. 11%', ;
0, .T., 1, 1001, 'A', 'Factura', 'FURNIZOR ABC SRL', 'TVA deductibil 11%', ;
1, DATE(), 1500, 'A|1001|0|0')
GO TOP IN introdc
DO UILog WITH 'introdc populat (' + TRANSFORM(RECCOUNT('introdc')) + ' randuri)'
*----- rul_temp: RecordSource GridArt. Pre-populat INAINTE de CREATEOBJECT =>
* Init nu il recreeaza din Oracle (llRulTempPlin=.T.). Total lei = 1500 = baza. -----
IF USED('rul_temp')
USE IN ('rul_temp')
ENDIF
CREATE CURSOR rul_temp (denumire C(100), codmat C(30), cant N(14,3), ;
pret_val N(18,4), pretd N(18,4), pret N(18,4), pret_lei N(18,4), ;
cont C(10), acont C(20), serie C(30), lot C(30), adata_expirare C(10), ;
proc_disc N(6,2), cota_tva N(6,2))
*-- cota_tva 21 (nu 19): trebuie sa existe in jtva_coloane2 ca sparge_document sa gaseasca
*-- coloana TVA pentru cota (altfel "Nu am gasit coloana TVA pentru cota ..." in sincronizeaza).
INSERT INTO rul_temp (denumire, codmat, cant, pret_val, pretd, pret, pret_lei, ;
cont, acont, serie, lot, adata_expirare, proc_disc, cota_tva) ;
VALUES ('Laptop Dell Latitude', 'ART001', 2, 0, 0, 500, 500, ;
'371', '01', 'SN-LAP-001', 'L001', '', 0, 21)
INSERT INTO rul_temp (denumire, codmat, cant, pret_val, pretd, pret, pret_lei, ;
cont, acont, serie, lot, adata_expirare, proc_disc, cota_tva) ;
VALUES ('Mouse optic USB', 'ART002', 10, 0, 0, 50, 50, ;
'371', '01', '', 'L002', '', 0, 21)
GO TOP IN rul_temp
DO UILog WITH 'rul_temp populat (' + TRANSFORM(RECCOUNT('rul_temp')) + ' articole)'
*----- Desktop VFP vizibil, maximizat, ca formularul sa apara pe tot ecranul -----
_SCREEN.Visible = .T.
_SCREEN.WindowState = 2
_SCREEN.Caption = 'TEST UI import_nota'
DO UILog WITH 'mediu pregatit, CREATEOBJECT(import_nota, .T.)'
SELECT introdc
PUBLIC goObj
goObj = CREATEOBJECT('IMPORT_nota', .T.)
IF VARTYPE(goObj) <> 'O'
DO UILog WITH 'FAIL: CREATEOBJECT a returnat ' + TRANSFORM(goObj)
DO HarnessDone WITH 'done-error'
QUIT
ENDIF
*-- oact folosit de recalculeaza/do_reface (This.oact.Curs)
goObj.oact = poAct
DO UILog WITH 'PASS: instantiere OK, afisez formularul'
*-- WindowType=0 (modeless): altfel formularul e modal si Show() nu returneaza,
*-- blocand pasii de test. Modeless => Show() revine, iar HarnessWaitContinue (cu DOEVENTS)
*-- tine formularul viu si receptiv intre pasi.
goObj.WindowType = 0
goObj.Visible = .T.
goObj.Show()
goObj.WindowState = 2
DOEVENTS FORCE
*========================= PAS 0: formular afisat cu date =========================
DO HarnessStep WITH 0, 'Formular afisat: Grid1=' + TRANSFORM(RECCOUNT('introdc')) + ' note, GridArt=' + TRANSFORM(RECCOUNT('rul_temp')) + ' articole'
*========================= PAS 1: recalculeaza() =========================
*-- Efect asteptat: nbaza_lei=1500 (1000+500), ntva_lei=265 (210+55, regim 21%/11%).
goObj.recalculeaza()
goObj.actualizeaza_banda()
goObj.grid1.Refresh()
DOEVENTS FORCE
IF ABS(goObj.nbaza_lei - 1500) < 0.01 AND ABS(goObj.ntva_lei - 265) < 0.01
DO UILog WITH 'PASS pas1 recalculeaza: nbaza_lei=' + TRANSFORM(goObj.nbaza_lei) + ' ntva_lei=' + TRANSFORM(goObj.ntva_lei)
ELSE
DO UILog WITH 'FAIL pas1 recalculeaza: nbaza_lei=' + TRANSFORM(goObj.nbaza_lei) + ' (astept 1500) ntva_lei=' + TRANSFORM(goObj.ntva_lei) + ' (astept 265)'
ENDIF
DO HarnessStep WITH 1, 'recalculeaza: baza=' + TRANSFORM(goObj.nbaza_lei) + ' tva=' + TRANSFORM(goObj.ntva_lei)
*========================= PAS 2: sincronizeaza() =========================
*-- Baza 1500 = total articole 1500 => sincronizat (banda verde, cmesajsync gol).
*-- PASS = fara mesaje blocante; eventualul rand D auto-creat e comportament valid.
LOCAL lnIntroBefore
lnIntroBefore = RECCOUNT_ACTIVE('introdc')
goObj.sincronizeaza()
DOEVENTS FORCE
DO UILog WITH 'diag pas2 tip_rand-uri introdc: ' + TipuriRanduri('introdc')
IF EMPTY(goObj.cmesajsync)
DO UILog WITH 'PASS pas2 sincronizeaza: sincronizat (cmesajsync gol, note=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ', dif_lei=' + TRANSFORM(goObj.ndif_lei) + ')'
ELSE
DO UILog WITH 'FAIL pas2 sincronizeaza: cmesajsync=[' + goObj.cmesajsync + '] note=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' (era ' + TRANSFORM(lnIntroBefore) + ')'
ENDIF
DO HarnessStep WITH 2, 'sincronizeaza: ' + IIF(EMPTY(goObj.cmesajsync),'SINCRONIZAT','NESINCRONIZAT')
*========================= PAS 3: sterge articol + resincronizare =========================
*-- Sterg articolul Mouse din rul_temp. Total articole -> 1000, baza 1500 => diferenta 500,
*-- cont dominant 371 (clasa 3) => recalc_diferente adauga rand D (DIFERENTE, scd 607).
LOCAL lnRulBefore, lnIntroBefore3
lnRulBefore = RECCOUNT_ACTIVE('rul_temp')
lnIntroBefore3 = RECCOUNT_ACTIVE('introdc')
SELECT rul_temp
LOCATE FOR ALLTRIM(codmat) == 'ART002'
IF FOUND()
DELETE
ENDIF
*-- GO TOP: in aplicatia reala grila GridArt repozitioneaza singura pointerul pe un
*-- rand valid dupa Refresh; aici stergem direct, deci il pozitionam noi ca do_reface ->
*-- do_calculeaza_diferente sa nu faca GO pe un recno past-EOF (eroare 5).
GO TOP IN rul_temp
goObj.gridart.Refresh()
goObj.sincronizeaza()
DOEVENTS FORCE
LOCAL lnRulAfter, lnHasD
lnRulAfter = RECCOUNT_ACTIVE('rul_temp')
SELECT introdc
LOCATE FOR tip_rand == 'D'
lnHasD = IIF(FOUND(), 1, 0)
IF lnRulAfter = lnRulBefore - 1 AND lnHasD = 1
DO UILog WITH 'PASS pas3 sterge articol: articole=' + TRANSFORM(lnRulAfter) + ' (era ' + TRANSFORM(lnRulBefore) + '), rand D DIFERENTE creat (dif=' + TRANSFORM(goObj.ndif_lei) + ')'
ELSE
DO UILog WITH 'FAIL pas3 sterge articol: articole=' + TRANSFORM(lnRulAfter) + ' (era ' + TRANSFORM(lnRulBefore) + '), randD=' + TRANSFORM(lnHasD)
ENDIF
DO HarnessStep WITH 3, 'sterge articol: articole=' + TRANSFORM(lnRulAfter) + ' randD=' + TRANSFORM(lnHasD) + ' dif=' + TRANSFORM(goObj.ndif_lei)
*========================= PAS 4: stergere prin BUTONUL real (flux complet) =========================
*-- Verific bugul "Record is out of range" (do_calculeaza_diferente: GO tnRecNo past-EOF dupa
*-- DELETE). Apas chiar But_sterge_art.Click() -> do_sterge_articol -> amessagebox (mock -> 6)
*-- -> Delete -> gridart.Refresh() -> sincronizeaza -> do_reface -> do_calculeaza_diferente.
*-- Intrebarea: dupa DELETE, grila repozitioneaza pointerul (OK) sau ramane past-EOF (eroare 5)?
*-- Intai verific ca mock-ul amessagebox chiar umbreste functia reala (altfel s-ar bloca pe modal).
LOCAL lnVerifMock
lnVerifMock = amessagebox('verificare rezolutie mock', 4+32, 'test')
DO UILog WITH 'verif rezolutie amessagebox = ' + TRANSFORM(lnVerifMock) + ;
IIF(lnVerifMock = 6, ' (MOCK castiga - sigur sa apas butonul)', ' (REAL castiga - risc blocaj pe modal!)')
IF lnVerifMock <> 6
DO UILog WITH 'PAS4 SKIP: mock-ul nu umbreste amessagebox real; nu apas butonul (as bloca pe dialog).'
ELSE
*-- Repopulez rul_temp cu 2 articole si pozitionez pe ULTIMUL (cazul cel mai expus la past-EOF).
SELECT rul_temp
DELETE ALL
INSERT INTO rul_temp (denumire, codmat, cant, pret_val, pretd, pret, pret_lei, ;
cont, acont, serie, lot, adata_expirare, proc_disc, cota_tva) ;
VALUES ('Tastatura mecanica', 'ART010', 3, 0, 0, 200, 200, '371', '01', '', 'L010', '', 0, 21)
INSERT INTO rul_temp (denumire, codmat, cant, pret_val, pretd, pret, pret_lei, ;
cont, acont, serie, lot, adata_expirare, proc_disc, cota_tva) ;
VALUES ('Casti audio', 'ART011', 5, 0, 0, 80, 80, '371', '01', '', 'L011', '', 0, 21)
goObj.gridart.Refresh()
goObj.sincronizeaza()
DOEVENTS FORCE
LOCAL lnRul4Before, lnRecInainte
lnRul4Before = RECCOUNT_ACTIVE('rul_temp')
SELECT rul_temp
GO BOTTOM
lnRecInainte = RECNO()
DO UILog WITH 'PAS4: rul_temp=' + TRANSFORM(lnRul4Before) + ' articole, pozitionat pe ultimul (recno=' + TRANSFORM(lnRecInainte) + '), apas But_sterge_art.Click()'
TRY
goObj.But_sterge_art.Click()
DOEVENTS FORCE
DO UILog WITH 'PAS4 PASS (fara eroare): articole ramase=' + TRANSFORM(RECCOUNT_ACTIVE('rul_temp')) + ;
' -> grila a repozitionat pointerul; do_calculeaza_diferente NU a crapat. Comportament corect.'
CATCH TO loExc4
DO UILog WITH 'PAS4 EROARE ' + TRANSFORM(loExc4.ErrorNo) + ' [' + loExc4.Message + '] in ' + ;
loExc4.Procedure + ':' + TRANSFORM(loExc4.LineNo) + ' -> BUG REAL confirmat (' + loExc4.LineContents + ')'
ENDTRY
ENDIF
DO HarnessStep WITH 4, 'sterge prin buton: articole=' + TRANSFORM(RECCOUNT_ACTIVE('rul_temp')) + ' mock=' + TRANSFORM(lnVerifMock)
*========================= PAS 5: explicatie TVA + taxcode SAFT IN TANDEM (aplica_explicatie_tva) =========================
*-- Documentul 1001 a fost deja "spart" de PAS 2/3 (sincronizeaza inlocuieste B/T cu randuri S/D) -
*-- inserez o pereche B/T PROASPATA (nract=9999), neatinsa de sincronizeaza, doar pentru acest test.
*-- Apelez METODA REALA aplica_explicatie_tva pe randul B (nu populez explicatie/taxcode manual pe T).
*-- Asteptat: B primeste explicatie_tva/taxcode direct (randul curent); T ar trebui sa le primeasca
*-- IN TANDEM prin Locate doc_key==calc_doc_key() - dar bugul doc_key (C(80) padded vs trim, ==
*-- strict) face ca Locate-ul din aplica_explicatie_tva sa NU gaseasca randul T => T ramane
*-- neschimbat. FAIL asteptat pe tandem, vezi docs\handoff_teste_ui_import.md.
SELECT introdc
INSERT INTO introdc (tip_rand, scd, scc, ascc, suma, id_jtva_coloana, ptva, explicatie_tva, ;
in_valuta, participa_valuta, nr_doc, nract, serie_act, fdoc, partc, explicatia, ;
cu_tva, dataact, suma_doc, doc_key) ;
VALUES ('B','371','401','FURN02', 2000, 0, 0, '', ;
0, .T., 2, 9999, 'P', 'Factura', 'FURNIZOR PAS5 SRL', 'Marfa test PAS5', ;
0, DATE(), 2000, 'P|9999|0|0')
INSERT INTO introdc (tip_rand, scd, scc, ascc, suma, id_jtva_coloana, ptva, explicatie_tva, ;
in_valuta, participa_valuta, nr_doc, nract, serie_act, fdoc, partc, explicatia, ;
cu_tva, dataact, suma_doc, doc_key) ;
VALUES ('T','4426','401','FURN02', 0, 0, 0, '', ;
0, .T., 2, 9999, 'P', 'Factura', 'FURNIZOR PAS5 SRL', 'TVA test PAS5', ;
0, DATE(), 2000, 'P|9999|0|0')
SELECT introdc
LOCATE FOR nract = 9999 AND tip_rand == 'B'
IF FOUND()
goObj.aplica_explicatie_tva(208)
SELECT introdc
LOCATE FOR nract = 9999 AND tip_rand == 'B'
IF FOUND() AND ALLTRIM(NVL(explicatie_tva,'')) == 'ACH. INT. 21%' AND NVL(taxcode,0) = 301104
DO UILog WITH 'PASS pas5a (randul B, direct): explicatie_tva=[' + ALLTRIM(explicatie_tva) + '] taxcode=' + TRANSFORM(NVL(taxcode,0)) + ' (SAFT 301104 aplicat de UpdateExplicatieSAFT via GetTaxCodeIdPart)'
ELSE
DO UILog WITH 'FAIL pas5a (randul B): gasit=' + TRANSFORM(FOUND()) + ' explicatie_tva=[' + ALLTRIM(NVL(explicatie_tva,'?')) + '] taxcode=' + TRANSFORM(NVL(taxcode,-1))
ENDIF
*-- randul T IN TANDEM (asteptat de aplica_explicatie_tva prin Locate doc_key==...)
LOCATE FOR nract = 9999 AND tip_rand == 'T'
IF FOUND() AND ALLTRIM(NVL(explicatie_tva,'')) == 'TVA ACH. INT. 21%' AND NVL(taxcode,0) = 301104
DO UILog WITH 'PASS pas5b (randul T, tandem): explicatie_tva/taxcode propagate corect - bugul doc_key ar fi FOST corectat'
ELSE
DO UILog WITH 'FAIL asteptat pas5b (randul T, tandem): bug doc_key (vezi handoff) - Locate For doc_key==Thisform.calc_doc_key() din aplica_explicatie_tva NU gaseste randul T (campul stocat C(80) padded vs calc_doc_key() trim, == strict). explicatie_tva ramasa=[' + ALLTRIM(NVL(explicatie_tva,'?')) + '] taxcode ramas=' + TRANSFORM(NVL(taxcode,-1))
ENDIF
ELSE
DO UILog WITH 'PAS5 SKIP: nu am gasit randul B (nract=9999) de test'
ENDIF
DO HarnessStep WITH 5, 'tandem TVA/SAFT: verificat (vezi log pentru PASS/FAIL asteptat)'
DO UILog WITH 'GATA - toate pasii executati'
DO HarnessDone WITH 'done'
CATCH TO loExc
DO UILog WITH 'CATCH ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']'
DO HarnessDone WITH 'done-error'
ENDTRY
QUIT
*==================================================================================
FUNCTION RECCOUNT_ACTIVE
*-- numar de randuri NEsterse (SET DELETED ON => RECCOUNT le include totusi)
LPARAMETERS tcAlias
LOCAL lnSel, lnCnt
lnSel = SELECT()
SELECT (tcAlias)
COUNT TO lnCnt FOR !DELETED()
SELECT (lnSel)
RETURN lnCnt
ENDFUNC
FUNCTION TipuriRanduri
*-- concateneaza tip_rand-urile nesterse (diagnostic)
LPARAMETERS tcAlias
LOCAL lnSel, lcRez
lnSel = SELECT()
SELECT (tcAlias)
lcRez = ''
SCAN FOR !DELETED()
lcRez = lcRez + ALLTRIM(NVL(tip_rand,'?')) + ' '
ENDSCAN
SELECT (lnSel)
RETURN ALLTRIM(lcRez)
ENDFUNC
PROCEDURE UIErr
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
DO UILog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
ENDPROC
PROCEDURE UILog
LPARAMETERS tcMsg
LOCAL lcL
lcL = FILETOSTR(gcUILog)
STRTOFILE(lcL + tcMsg + CHR(13)+CHR(10), gcUILog)
ENDPROC
DEFINE CLASS dummyapp AS Custom
*-- inlocuieste obiectul aplicatiei (wzApplication) pentru citirea settings.ini
PROCEDURE ReadIni
LPARAMETERS tcSection, tcKey
RETURN ''
ENDPROC
PROCEDURE WriteIni
LPARAMETERS tcSection, tcKey, tcValue
RETURN .T.
ENDPROC
ENDDEFINE
DEFINE CLASS dummyexecutor AS Custom
cEroare = ''
PROCEDURE oExecute
LPARAMETERS tcSql, tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
*-- update_jtva_coloane (SELECT * FROM vjtva_coloane ...): mock cu date reale (jtva_coloane,
*-- jtva_coloane_taxcode - mod 6, cu campurile taxcode*) - vezi GetTaxCode/GetTaxCodeIdPart.
IF 'VJTVA_COLOANE' $ UPPER(m.tcSql)
DO CreeazaJtvaColoaneView WITH m.tcCursor
RETURN 1
ENDIF
*-- rul_temp e pre-populat in test => Init nu ajunge aici pentru el.
*-- Structura generica minimala pentru orice alt cursor cerut.
CREATE CURSOR (m.tcCursor) (id_temp N(1))
RETURN 1
ENDPROC
PROCEDURE oExecuta
LPARAMETERS tcSql, tcCursor
IF !EMPTY(m.tcCursor)
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
*-- Init cere cJtvaCol4427 si INDEXeaza pe ID_JTVA_COLOANA => campul trebuie sa existe.
IF UPPER(m.tcCursor) == 'CJTVACOL4427'
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14))
ELSE
CREATE CURSOR (m.tcCursor) (id_temp N(1))
ENDIF
ENDIF
RETURN .T.
ENDPROC
PROCEDURE oSelect2Value
*-- GetCodFiscalPartenerById (oproceduri_comune.prg): cod fiscal gol => VERIFICA_RTVAI
*-- vede llIsCIF=.F. si sare peste apelul PACK_ROARTVAI (fara Oracle real).
LPARAMETERS tcSql, toValue
toValue = ''
RETURN 1
ENDPROC
PROCEDURE oReset
*-- update_jtva_coloane() il apeleaza necondit dupa oExecute (updateserver.prg:611).
ENDPROC
ENDDEFINE
PROCEDURE CreeazaJtvaColoaneView
*-- Mock pentru "select * from vjtva_coloane ..." (update_jtva_coloane): perechi reale
*-- (Oracle dev, 17.07.2026) baza/TVA 21%/11% + import, cu taxcode SAFT (vsaft_taxtable).
LPARAMETERS tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14), denumire C(100), jc N(1), jv N(1), ;
coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14) NULL, afisat N(1), ;
id_jtva_ex N(14) NULL, id_jtva_neex N(14) NULL, ordine N(8), ;
taxcode N(6) NULL, taxcode_neexigibil N(6) NULL, taxcode_n50 N(6) NULL, ;
taxcode_n50_tvai N(6) NULL, taxcode_n100 N(6) NULL, taxcode_regularizare N(6) NULL, taxcode_tvai N(6) NULL)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, afisat, ordine, cota_tva) VALUES (0, '', 0, 0, 1, 0, 0)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (208, 'ACH. INT. 21%', 1, 0, 'RO21B', 21, 209, 1, 1, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (209, 'TVA ACH. INT. 21%', 1, 0, 'RO21T', 21, 1, 2, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (212, 'ACH. INT. 11%', 1, 0, 'RO11B', 11, 213, 1, 3, 301105)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (213, 'TVA ACH. INT. 11%', 1, 0, 'RO11T', 11, 1, 4, 301105)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (220, 'ACH. IMP. 21%', 1, 0, 'FO21B', 21, 221, 1, 5, 301204)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (221, 'TVA ACH. IMP. 21%', 1, 0, 'FO21T', 21, 1, 6, 301204)
ENDPROC

View File

@@ -0,0 +1,8 @@
# test_import_nota_ui.ps1 - wrapper subtire peste harness-ul generic vfp_ui_harness.ps1.
# Dovada ca harness-ul reutilizabil merge: ruleaza testul import_nota cu cei 5 pasi ai lui.
# Rulare: powershell -ExecutionPolicy Bypass -File test_import_nota_ui.ps1
$ErrorActionPreference = 'Stop'
$Teste = $PSScriptRoot
& (Join-Path (Split-Path $Teste -Parent) 'vfp_ui_harness.ps1') `
-TestPrg (Join-Path $Teste 'test_import_nota_ui.prg') `
-Steps @('formular_afisat','recalculeaza','sincronizeaza','sterge_articol','sterge_buton_real','tandem_tva_saft')

View File

@@ -0,0 +1,956 @@
* test_manual_tva_footer.prg
* Teste rundele 15-17 (import_nota, COMUN\clase\ointroduceri.vcx): nOldVal unic, do_calculeaza_diferente
* fara repozitionare pe tnRecNo, protectie mod_manual pe randul T, footer _grdfooter1 pe GridArt.
* Configuratia DVI (doc1 EUR + doc2 lei + doc3 taxe vamale) e IDENTICA cu test_scenariu_dvi_complet.prg
* (proprietatile documentelor, mock-urile, jtva_coloane2/saft_taxtable) - vezi acel fisier pentru context.
*
* Pasi (harness): 0 dupa 3 documente, 1 dupa 2 articole+sincronizare, 2 dupa corectia manuala TVA pe
* randul T al DVI, 3 dupa do_executa+sincronizare#2 (F5), 4 final (footer+pointer+garda).
*
* Rulare:
* powershell -ExecutionPolicy Bypass -File test_manual_tva_footer.ps1
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET DECIMALS TO 4
SET NULLDISPLAY TO ''
CLOSE DATABASES
PUBLIC gcUILog, gcSyncDir
gcUILog = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\test_manual_tva_footer_log.txt"
gcSyncDir = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\uisync_tva_footer\"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcUILog)
ON ERROR DO MtErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
TRY
LOCAL gcAppPath, lcPath
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;' + ;
ADDBS(SUBSTR(gcAppPath,1,RAT([\],gcAppPath,2)))+[COMUNROA\]
SET PATH TO &lcPath ADDITIVE
DO MtLog WITH 'SET PATH OK'
*----- CLASE -----
SET CLASSLIB TO (gcAppPath + "comun\clase\appwiz") 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 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 wwdialogs.vcx ADDITIVE
SET CLASSLIB TO oimportxml.vcx ADDITIVE
SET CLASSLIB TO excelxml.vcx ADDITIVE
SET CLASSLIB TO orapoarte_obinv.vcx ADDITIVE
DO MtLog WITH 'SET CLASSLIB OK'
*----- PROCEDURI (mock amessagebox + mock cauta_nom_articole PRIMELE, ui_harness la final) -----
SET PROCEDURE TO PROCEDURI
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_cauta_nom_articole.prg" 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 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 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 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
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\ui_harness.prg" ADDITIVE
DO MtLog WITH 'SET PROCEDURE OK'
*----- Globale -----
PUBLIC gnPc, gnPval, gnPcant, gnPpret, gnPPretval, gnPCurs, gnPVal, gnPPretV, gnPPretVal
STORE 2 TO gnPc, gnPval, gnPVal
gnPcant = 3
STORE 4 TO gnPpret, gnPPretval, gnPPretVal, gnPPretV, gnPCurs
PUBLIC gl406, gcS, gnAn, gnLuna, gnIdFirma, gnIdSucursala, gcAcces, gcFirma
gl406 = .T.
gcS = 'CONTAFIN'
gnAn = YEAR(DATE())
gnLuna = MONTH(DATE())
gnIdFirma = 110
gnIdSucursala = 110
gcAcces = "1;2;3;4;5;6;7;8;"
gcFirma = gcS
PUBLIC nror(65000)
PUBLIC gnButon
STORE 2 TO gnButon
PUBLIC gcMockArtCodmat, gcMockAcontCrt
gcMockArtCodmat = ''
gcMockAcontCrt = ''
PUBLIC gnMockRaspuns
gnMockRaspuns = 6
PUBLIC goExecutor, goApp
goExecutor = CREATEOBJECT('dummyexecutor')
goApp = CREATEOBJECT('dummyapp')
*----- poAct: antetul notei; dialogul mosteneste din el la Init -----
PUBLIC poAct
poAct = CREATEOBJECT('Custom')
poAct.AddProperty('nume_val', '')
poAct.AddProperty('curs', 5.23)
poAct.AddProperty('proc_tva', 1.21)
poAct.AddProperty('nnir', 0)
poAct.AddProperty('id_valuta', 978)
poAct.AddProperty('id_fdoc', 1)
poAct.AddProperty('fdoc', 'Factura')
poAct.AddProperty('id_partc', 500)
poAct.AddProperty('partc', 'FURNIZOR ANTET SRL')
poAct.AddProperty('serie_act', '')
poAct.AddProperty('dataact', DATE())
poAct.AddProperty('tva_incasare', 0)
poAct.AddProperty('id_set', 1)
poAct.AddProperty('id_gestin', 1)
*----- jtva_coloane2 / saft_taxtable: perechi reale 21% (identice test_scenariu_dvi_complet) -----
IF USED('jtva_coloane2')
USE IN ('jtva_coloane2')
ENDIF
CREATE CURSOR jtva_coloane2 (ordine N(8), id_jtva_coloana N(14), denumire C(100), ;
jc N(1), jv N(1), afisat N(1), coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14))
INSERT INTO jtva_coloane2 VALUES (0, 0, '', 0, 0, 1, '', '', 0, 0)
INSERT INTO jtva_coloane2 VALUES (1, 208, 'ACH. INT. 21%', 1, 0, 1, 'RO21B', 'RO21T', 21, 209)
INSERT INTO jtva_coloane2 VALUES (2, 209, 'TVA ACH. INT. 21%', 1, 0, 1, 'RO21T', '', 21, 0)
INSERT INTO jtva_coloane2 VALUES (3, 220, 'ACH. IMP. 21%', 1, 0, 1, 'FO21B', 'FO21T', 21, 221)
INSERT INTO jtva_coloane2 VALUES (4, 221, 'TVA ACH. IMP. 21%', 1, 0, 1, 'FO21T', '', 21, 0)
IF USED('saft_taxtable')
USE IN ('saft_taxtable')
ENDIF
CREATE CURSOR saft_taxtable (taxname C(250) NULL, typename C(250) NULL, taxcode N(6) NULL, ;
taxtype N(3) NULL, descriere C(250) NULL, tip C(100) NULL, descriere_tip C(250) NULL, ;
procent_taxa N(7,2) NULL, procent_prorata N(7,2) NULL, inactiv N(1) NULL, tva N(1) NULL, ;
wht N(1) NULL, tva_achizitii N(1) NULL, tva_livrari N(1) NULL)
INDEX ON taxcode TAG taxcode
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('', 0, '', 0, 1, 1, 1, 1)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301104-Achizitii de bunuri si servicii taxabile cu cota de 21%, altele decat importurile si cele supuse masurilor de simplificare', 301104, '', 21, 1, 0, 1, 0)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301204-Import de bunuri cota 21%', 301204, '', 21, 1, 0, 1, 0)
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%')
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%')
GO TOP IN introdc_sablon
DO CreeazaRulTemp
INSERT INTO rul_temp (denumire, codmat, cant, pret, pret_lei, cont, cota_tva) ;
VALUES ('PLACEHOLDER', 'PH', 1, 1, 1, '371', 21)
*-- index ord_doc INAINTE de CREATEOBJECT - vezi docs/testare-ui-vfp.md capcana p.
SELECT introdc
INDEX ON Str(Nvl(nr_doc,0),8) + Icase(tip_rand='B','1', tip_rand='S','2', tip_rand='T','3', tip_rand='D','4', '5') + Padr(Nvl(scd,''),10) TAG ord_doc
SET ORDER TO ord_doc
DO MtLog WITH 'cursoare pregatite, CREATEOBJECT(import_nota, .F.) - lIntern=.F. (import)'
PUBLIC goObj
goObj = CREATEOBJECT('IMPORT_nota', .F.)
IF VARTYPE(goObj) <> 'O'
DO MtLog WITH 'FAIL: instantiere import_nota'
DO HarnessDone WITH 'done-error'
QUIT
ENDIF
goObj.lDialogAratat = .T.
goObj.oact = poAct
goObj.WindowType = 0
goObj.Visible = .T.
goObj.Show()
goObj.WindowState = 2
DOEVENTS FORCE
SELECT rul_temp
ZAP
goObj.gridart.Refresh()
DOEVENTS FORCE
*========================= DOC 1+2+3 (configuratia DVI din test_scenariu_dvi_complet) =========================
PUBLIC goDlg, goT
DO AdaugaDoc1
DO VerificaPereche WITH 15000, 5230, 1000, 'EUR'
DO VerificaDvi WITH 15000, 100, 5230, 1098.30, 210.00
DO AdaugaDoc2
DO VerificaPereche WITH 12000, 1000, 0, ''
DO AdaugaDoc3
DO VerificaPereche WITH 100, 500, 0, ''
DO MtLog WITH 'dump introdc dupa cele 3 documente:'
DO DumpIntrodc
DO HarnessStep WITH 0, 'dupa 3 documente: introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri (astept 6, 3 perechi B/T)'
*========================= 2 ARTICOLE (flux real do_adauga_articol) =========================
gcMockArtCodmat = 'ART-BULD-212'
gcMockAcontCrt = '1'
TRY
goObj.do_adauga_articol()
CATCH TO loExcA1
DO MtLog WITH 'EROARE do_adauga_articol (BULDOEXCAVATOR) ' + TRANSFORM(loExcA1.ErrorNo) + ' [' + loExcA1.Message + ']'
ENDTRY
DOEVENTS FORCE
SELECT rul_temp
LOCATE FOR ALLTRIM(codmat) == 'ART-BULD-212'
IF FOUND()
REPLACE cant WITH 1, pret_val WITH 900, pretd WITH 900, pret WITH ROUND(900*5.23,4), pret_lei WITH ROUND(900*5.23,4)
DO MtLog WITH 'BULDOEXCAVATOR (212) adaugat, cant/pret completate'
ELSE
DO MtLog WITH 'FAIL: BULDOEXCAVATOR nu a fost adaugat de do_adauga_articol()'
ENDIF
gcMockArtCodmat = 'ART-A8-371'
gcMockAcontCrt = '4'
TRY
goObj.do_adauga_articol()
CATCH TO loExcA2
DO MtLog WITH 'EROARE do_adauga_articol (A8) ' + TRANSFORM(loExcA2.ErrorNo) + ' [' + loExcA2.Message + ']'
ENDTRY
DOEVENTS FORCE
SELECT rul_temp
LOCATE FOR ALLTRIM(codmat) == 'ART-A8-371'
IF FOUND()
REPLACE cant WITH 1, pret_val WITH 100, pretd WITH 100, pret WITH ROUND(100*5.23,4), pret_lei WITH ROUND(100*5.23,4)
DO MtLog WITH 'A8 (371) adaugat, cant/pret completate'
ELSE
DO MtLog WITH 'FAIL: A8 nu a fost adaugat de do_adauga_articol()'
ENDIF
goObj.gridart.Refresh()
DOEVENTS FORCE
LOCAL llEroareSync1
llEroareSync1 = .F.
TRY
goObj.sincronizeaza()
CATCH TO loExcS1
llEroareSync1 = .T.
DO MtLog WITH 'EROARE la sincronizeaza() #1 ' + TRANSFORM(loExcS1.ErrorNo) + ' [' + loExcS1.Message + ']'
ENDTRY
DOEVENTS FORCE
goObj.grid1.Refresh()
IF !llEroareSync1
DO MtLog WITH 'PASS sincronizare1: fara eroare'
ELSE
DO MtLog WITH 'FAIL sincronizare1: a aruncat eroare'
ENDIF
DO MtLog WITH 'dump introdc dupa 2 articole + sincronizare#1:'
DO DumpIntrodc
DO HarnessStep WITH 1, 'dupa 2 articole + sincronizare#1, introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri'
*========================= PASUL-CHEIE: corectie manuala TVA pe randul T al DVI =========================
*-- gasesc randul T al DVI (vama): doc1 e principal - dupa spargere B-ul lui 15000 dispare, nr_doc
*-- se ia de pe un rand S (VerificaDviPrincipalSpart, test_scenariu_dvi_complet.prg:842-870).
LOCAL lnNrDocDvi, llGasitBS, llGasitT, lnSumaValVeche, lnRecT
lnNrDocDvi = 0
llGasitT = .F.
SELECT introdc
LOCATE FOR nract = 15000 AND tip_rand == 'B'
llGasitBS = FOUND()
IF !llGasitBS
LOCATE FOR nract = 15000 AND tip_rand == 'S'
llGasitBS = FOUND()
ENDIF
IF llGasitBS
lnNrDocDvi = nr_doc
LOCATE FOR nr_doc = lnNrDocDvi AND tip_rand == 'T'
llGasitT = FOUND()
ENDIF
IF !llGasitT
DO MtLog WITH 'FAIL: nu am gasit randul T al DVI (nract=15000/nr_doc=' + TRANSFORM(lnNrDocDvi) + ') - opresc pasul-cheie'
ELSE
lnRecT = RECNO()
lnSumaValVeche = suma_val
DO MtLog WITH 'randul T DVI gasit: recno=' + TRANSFORM(lnRecT) + ' nract=' + TRANSFORM(nract) + ' partc=[' + ALLTRIM(NVL(partc,'')) + '] suma_val_veche=' + TRANSFORM(lnSumaValVeche) + ' suma_veche=' + TRANSFORM(suma) + ' curs=' + TRANSFORM(NVL(curs,0)) + ' in_valuta=' + TRANSFORM(NVL(in_valuta,0))
*-- pozitionez grila pe acest rand (Grid1 e legat de introdc, care e deja ordonat ord_doc -
*-- GO lnRecT muta pointerul fizic, valabil indiferent de ordine).
GO lnRecT IN introdc
goObj.grid1.Refresh()
DOEVENTS FORCE
*-- GotFocus real: memoreaza nOldVal (echivalent intrarii userului in celula)
goObj.grid1.cSumaVal.Text1.GotFocus()
DO MtLog WITH 'dupa GotFocus real: Thisform.nOldVal=' + TRANSFORM(goObj.nOldVal) + ' (astept ' + TRANSFORM(lnSumaValVeche) + ')'
LOCAL llApelRealOk
llApelRealOk = .F.
TRY
goObj.grid1.cSumaVal.Text1.Value = 210
goObj.grid1.cSumaVal.Text1.Valid()
llApelRealOk = .T.
DO MtLog WITH 'PASS apel REAL: Grid1.cSumaVal.Text1.Valid() executat direct (fara replicare manuala)'
CATCH TO loExcValid
DO MtLog WITH 'INFO apel real a esuat (' + TRANSFORM(loExcValid.ErrorNo) + ' ' + loExcValid.Message + ') - fallback: replic corpul metodei Valid() (mock_amessebox->6=Da, ca in aplicatie)'
SELECT introdc
GO lnRecT
REPLACE suma_val WITH 210
LOCAL lnCursFolosit, lnSumaCalc
lnCursFolosit = IIF(in_valuta = 1 AND NVL(curs,0) <> 0, curs, goObj.oact.Curs)
lnSumaCalc = ROUND(210 * lnCursFolosit, gnPc)
IF suma <> 0 AND suma <> lnSumaCalc
= amessagebox('Suma in lei difera de suma in valuta transformata in lei!' + CHR(13) + CHR(10) + 'Doriti recalcularea sumei in lei?', 4+32, 'Diferente sume')
ENDIF
REPLACE suma WITH lnSumaCalc
REPLACE mod_manual WITH 1
ENDTRY
DOEVENTS FORCE
SELECT introdc
GO lnRecT
DO MtLog WITH 'dupa corectie: suma_val=' + TRANSFORM(suma_val) + ' suma=' + TRANSFORM(suma) + ' mod_manual=' + TRANSFORM(NVL(mod_manual,0))
IF NVL(mod_manual,0) = 1
DO MtLog WITH 'PASS mod_manual=1 pe randul T dupa corectie'
ELSE
DO MtLog WITH 'FAIL mod_manual=' + TRANSFORM(NVL(mod_manual,0)) + ' (astept 1) pe randul T dupa corectie'
ENDIF
ENDIF
DO HarnessStep WITH 2, 'dupa corectie manuala TVA pe randul T (apel real=' + TRANSFORM(llApelRealOk) + ')'
*========================= do_executa + sincronizeaza() #2 (echivalent F5) =========================
LOCAL llEroareExec, llEroareSync2
llEroareExec = .F.
TRY
goObj.do_executa()
CATCH TO loExcExec
llEroareExec = .T.
DO MtLog WITH 'EROARE la do_executa() ' + TRANSFORM(loExcExec.ErrorNo) + ' [' + loExcExec.Message + ']'
ENDTRY
llEroareSync2 = .F.
TRY
goObj.sincronizeaza()
CATCH TO loExcS2
llEroareSync2 = .T.
DO MtLog WITH 'EROARE la sincronizeaza() #2 ' + TRANSFORM(loExcS2.ErrorNo) + ' [' + loExcS2.Message + ']'
ENDTRY
DOEVENTS FORCE
goObj.grid1.Refresh()
DO MtLog WITH 'dump introdc dupa do_executa+sincronizare#2 (F5):'
DO DumpIntrodc
*-- ASSERT CENTRAL: suma_val/suma pe randul T al DVI raman cele corectate manual, nu revin la
*-- valoarea derivata din articole (mod_manual=1 protejeaza in do_executa/sparge_document)
IF llGasitT
SELECT introdc
LOCATE FOR nr_doc = lnNrDocDvi AND tip_rand == 'T'
IF FOUND()
LOCAL lnCursAsteptat, lnSumaAsteptata
lnCursAsteptat = IIF(in_valuta = 1 AND NVL(curs,0) <> 0, curs, goObj.oact.Curs)
lnSumaAsteptata = ROUND(210 * lnCursAsteptat, gnPc)
IF ABS(suma_val - 210) < 0.01 AND ABS(suma - lnSumaAsteptata) < 0.01
DO MtLog WITH 'PASS ASSERT CENTRAL: randul T DVI suma_val=' + TRANSFORM(suma_val) + ' (=210) suma=' + TRANSFORM(suma) + ' (=' + TRANSFORM(lnSumaAsteptata) + ') dupa F5 - NU a revenit la valoarea derivata din articole'
ELSE
DO MtLog WITH 'FAIL ASSERT CENTRAL: randul T DVI suma_val=' + TRANSFORM(suma_val) + ' (astept 210) suma=' + TRANSFORM(suma) + ' (astept ' + TRANSFORM(lnSumaAsteptata) + ')'
ENDIF
ELSE
DO MtLog WITH 'FAIL ASSERT CENTRAL: randul T al DVI (nr_doc=' + TRANSFORM(lnNrDocDvi) + ') nu mai exista dupa F5'
ENDIF
*-- fara duplicat de rand T pe acelasi doc_key/cota (sparge_document nu creeaza al doilea T
*-- pentru un T deja marcat mod_manual=1 pe aceeasi cota)
LOCAL lnCountTDvi
SELECT COUNT(*) AS n FROM introdc WHERE nr_doc = lnNrDocDvi AND tip_rand == 'T' INTO CURSOR crsCountTDvi NOFILTER
lnCountTDvi = crsCountTDvi.n
USE IN crsCountTDvi
IF lnCountTDvi = 1
DO MtLog WITH 'PASS fara duplicat randul T DVI: ' + TRANSFORM(lnCountTDvi) + ' rand (astept 1)'
ELSE
DO MtLog WITH 'FAIL duplicat randul T DVI: ' + TRANSFORM(lnCountTDvi) + ' randuri (astept 1)'
ENDIF
ENDIF
DO HarnessStep WITH 3, 'dupa do_executa+sincronizare#2 (F5): eroare_exec=' + TRANSFORM(llEroareExec) + ' eroare_sync2=' + TRANSFORM(llEroareSync2)
*========================= ASSERT FOOTER (_grdfooter1) =========================
IF VARTYPE(goObj._grdfooter1) == 'O'
DO MtLog WITH 'PASS footer: Thisform._grdfooter1 exista (Vartype=O)'
LOCAL lnSumaValFact, lnSumaValCalc, lnSumaLeiCalc
SELECT SUM(ROUND(pret_val*cant,gnPval)) AS svf, SUM(ROUND(pretd*cant,gnPval)) AS svc, ;
SUM(ROUND(pret*cant,gnPc)) AS slc FROM rul_temp WHERE !DELETED() INTO CURSOR crsTotIndep NOFILTER
lnSumaValFact = NVL(crsTotIndep.svf,0)
lnSumaValCalc = NVL(crsTotIndep.svc,0)
lnSumaLeiCalc = NVL(crsTotIndep.slc,0)
USE IN crsTotIndep
DO MtLog WITH 'totaluri independente (calculate in test din rul_temp): cValoareValutaFactura=' + TRANSFORM(lnSumaValFact) + ' cValoareValutaCalculat=' + TRANSFORM(lnSumaValCalc) + ' cValoareLeiCalculat=' + TRANSFORM(lnSumaLeiCalc)
LOCAL i, lcColName, lcCS, lnValFooter, llGasitCol1, llGasitCol2, llGasitCol3
llGasitCol1 = .F.
llGasitCol2 = .F.
llGasitCol3 = .F.
FOR i = 1 TO goObj._grdfooter1.ColumnCount
lcColName = UPPER(ALLTRIM(goObj._grdfooter1.Columns(i).Name))
lcCS = goObj._grdfooter1.Columns(i).ControlSource
DO MtLog WITH ' footer col ' + TRANSFORM(i) + ': name=' + lcColName + ' ControlSource=[' + TRANSFORM(lcCS) + ']'
DO CASE
CASE lcColName == 'CVALOAREVALUTAFACTURA'
llGasitCol1 = .T.
lnValFooter = EVALUATE(lcCS)
IF ABS(lnValFooter - lnSumaValFact) < 0.01
DO MtLog WITH 'PASS footer cValoareValutaFactura=' + TRANSFORM(lnValFooter) + ' == ' + TRANSFORM(lnSumaValFact)
ELSE
DO MtLog WITH 'FAIL footer cValoareValutaFactura=' + TRANSFORM(lnValFooter) + ' != ' + TRANSFORM(lnSumaValFact)
ENDIF
CASE lcColName == 'CVALOAREVALUTACALCULAT'
llGasitCol2 = .T.
lnValFooter = EVALUATE(lcCS)
IF ABS(lnValFooter - lnSumaValCalc) < 0.01
DO MtLog WITH 'PASS footer cValoareValutaCalculat=' + TRANSFORM(lnValFooter) + ' == ' + TRANSFORM(lnSumaValCalc)
ELSE
DO MtLog WITH 'FAIL footer cValoareValutaCalculat=' + TRANSFORM(lnValFooter) + ' != ' + TRANSFORM(lnSumaValCalc)
ENDIF
CASE lcColName == 'CVALOARELEICALCULAT'
llGasitCol3 = .T.
lnValFooter = EVALUATE(lcCS)
IF ABS(lnValFooter - lnSumaLeiCalc) < 0.01
DO MtLog WITH 'PASS footer cValoareLeiCalculat=' + TRANSFORM(lnValFooter) + ' == ' + TRANSFORM(lnSumaLeiCalc)
ELSE
DO MtLog WITH 'FAIL footer cValoareLeiCalculat=' + TRANSFORM(lnValFooter) + ' != ' + TRANSFORM(lnSumaLeiCalc)
ENDIF
ENDCASE
NEXT
IF !llGasitCol1 OR !llGasitCol2 OR !llGasitCol3
DO MtLog WITH 'FAIL footer: nu am gasit toate cele 3 coloane insumate (col1=' + TRANSFORM(llGasitCol1) + ' col2=' + TRANSFORM(llGasitCol2) + ' col3=' + TRANSFORM(llGasitCol3) + ')'
ENDIF
ELSE
DO MtLog WITH 'FAIL footer: Thisform._grdfooter1 nu exista sau nu e obiect (Vartype=' + VARTYPE(goObj._grdfooter1) + ')'
ENDIF
*========================= ASSERT POINTER (fix navigare do_calculeaza_diferente) =========================
SELECT rul_temp
GO 1
LOCAL llEroarePointer
llEroarePointer = .F.
TRY
goObj.do_calculeaza_diferente(2)
CATCH TO loExcPointer
llEroarePointer = .T.
DO MtLog WITH 'EROARE la do_calculeaza_diferente(2) ' + TRANSFORM(loExcPointer.ErrorNo) + ' [' + loExcPointer.Message + ']'
ENDTRY
IF !llEroarePointer AND RECNO('rul_temp') = 1
DO MtLog WITH 'PASS assert pointer: Recno(rul_temp)=' + TRANSFORM(RECNO('rul_temp')) + ' dupa do_calculeaza_diferente(2) (nu s-a mutat pe randul 2)'
ELSE
DO MtLog WITH 'FAIL assert pointer: Recno(rul_temp)=' + TRANSFORM(RECNO('rul_temp')) + ' (astept 1) eroare=' + TRANSFORM(llEroarePointer)
ENDIF
*========================= ASSERT GARDA nOldVal (GridArt.cPretFactura) =========================
goObj.lSyncPending = .F.
SELECT rul_temp
GO TOP
LOCAL lnPretValInainte
lnPretValInainte = pret_val
*-- Text1.Value nu se sincronizeaza singur cu recordul cand Focus-ul e simulat direct (fara
*-- navigare reala in grid) - il setez explicit, ca GotFocus() sa memoreze nOldVal numeric corect
*-- (altfel ramane '' si LostFocus arunca eroare 107 la comparatia This.Value = Thisform.nOldVal).
goObj.gridart.cPretFactura.Text1.Value = lnPretValInainte
goObj.gridart.cPretFactura.Text1.GotFocus()
DO MtLog WITH 'garda: Thisform.nOldVal=' + TRANSFORM(goObj.nOldVal) + ' pret_val=' + TRANSFORM(lnPretValInainte)
*-- Value NEschimbat (GotFocus l-a memorat deja) - echivalent iesirii din celula fara modificare
goObj.gridart.cPretFactura.Text1.LostFocus()
DOEVENTS FORCE
SELECT rul_temp
IF !goObj.lSyncPending AND ABS(pret_val - lnPretValInainte) < 0.0001
DO MtLog WITH 'PASS garda nOldVal: lSyncPending ramane .F., pret_val neschimbat (' + TRANSFORM(pret_val) + ')'
ELSE
DO MtLog WITH 'FAIL garda nOldVal: lSyncPending=' + TRANSFORM(goObj.lSyncPending) + ' (astept .F.) pret_val=' + TRANSFORM(pret_val) + ' (astept ' + TRANSFORM(lnPretValInainte) + ')'
ENDIF
DO MtLog WITH 'GATA - scenariu executat integral'
DO HarnessStep WITH 4, 'final: introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri, rul_temp=' + TRANSFORM(RECCOUNT_ACTIVE('rul_temp')) + ' articole, footer vizibil sub grila articolelor'
DO HarnessDone WITH 'done'
CATCH TO loExc
DO MtLog WITH 'CATCH ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']'
DO HarnessDone WITH 'done-error'
ENDTRY
QUIT
*==================================================================================
PROCEDURE AdaugaDoc1
*-- FACTURA 15000, RAJA, DVI valuta (EUR curs 5.23): DVI 100, BIROUL VAMAL, tva 1098.30/210.
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = 15000
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 601
goDlg.cPartener = 'RAJA'
goDlg.cExplicatia = 'Import marfa RAJA'
goDlg.nSuma = 1000
goDlg.nSumaLei = 0
goDlg.nCurs = 5.23
goDlg.nIdValuta = 978
goDlg.cValuta = 'EUR'
goDlg.nIdExplicatieTva = 220
goDlg.cExplicatieTva = 'ACH. IMP. 21%'
goDlg.optTipTva.Value = 2 && D = DVI
goDlg.chkInValutaCont.Value = 1
goDlg.chkParticipaValuta.Value = 1
goDlg.cSerieDvi = ''
goDlg.nNractDvi = 100
goDlg.dDviData = DATE()
goDlg.nIdFdocDVI = 2
goDlg.cFelDocDvi = 'DVI'
goDlg.nDviIdPartener = 900
goDlg.cDviPartener = 'BIROUL VAMAL'
goDlg.nDviTvaLei = 1098.30
goDlg.nDviTvaVal = 210.00
goDlg.actualizeaza_stare_dvi()
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO MtLog WITH 'DOC1: valideaza = ' + TRANSFORM(goDlg.valideaza())
DO ConstruiesteToDlg
DO MtLog WITH 'DOC1: do_adauga_factura = ' + TRANSFORM(goObj.do_adauga_factura(goT))
goDlg.Hide()
DOEVENTS FORCE
ENDPROC
PROCEDURE AdaugaDoc2
*-- FACTURA 12000, TRANS OIL, DVI lei (acelasi doc vamal 100).
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = 12000
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 602
goDlg.cPartener = 'TRANS OIL'
goDlg.cExplicatia = 'Achizitie TRANS OIL'
goDlg.nSuma = 1000
goDlg.nSumaLei = 0
goDlg.nCurs = 0
goDlg.nIdExplicatieTva = 220
goDlg.cExplicatieTva = 'ACH. IMP. 21%'
goDlg.optTipTva.Value = 2 && D = DVI
goDlg.chkInValutaCont.Value = 0
goDlg.chkParticipaValuta.Value = 1
goDlg.cSerieDvi = ''
goDlg.nNractDvi = 100
goDlg.dDviData = DATE()
goDlg.nIdFdocDVI = 2
goDlg.cFelDocDvi = 'DVI'
goDlg.nDviIdPartener = 900
goDlg.cDviPartener = 'BIROUL VAMAL'
goDlg.nDviTvaLei = 210.00
goDlg.nDviTvaVal = 0
goDlg.actualizeaza_stare_dvi()
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO MtLog WITH 'DOC2: valideaza = ' + TRANSFORM(goDlg.valideaza())
DO ConstruiesteToDlg
DO MtLog WITH 'DOC2: do_adauga_factura = ' + TRANSFORM(goObj.do_adauga_factura(goT))
goDlg.Hide()
DOEVENTS FORCE
ENDPROC
PROCEDURE AdaugaDoc3
*-- DVI 100, BIROUL VAMAL, 500 lei (taxe vamale), TVA normal 'F' cu explicatia ACH. IMP. 21%.
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'DVI'
goDlg.nIdFdoc = 2
goDlg.nNract = 100
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 900
goDlg.cPartener = 'BIROUL VAMAL'
goDlg.cExplicatia = 'Taxe vamale DVI 100'
goDlg.nSuma = 500
goDlg.nSumaLei = 0
goDlg.nCurs = 0
goDlg.nIdExplicatieTva = 220
goDlg.cExplicatieTva = 'ACH. IMP. 21%'
goDlg.optTipTva.Value = 1 && F = furnizor (normal, NU referinta DVI)
goDlg.chkInValutaCont.Value = 0
goDlg.chkParticipaValuta.Value = 1
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO MtLog WITH 'DOC3: valideaza = ' + TRANSFORM(goDlg.valideaza())
DO ConstruiesteToDlg
DO MtLog WITH 'DOC3: do_adauga_factura = ' + TRANSFORM(goObj.do_adauga_factura(goT))
goDlg.Hide()
DOEVENTS FORCE
ENDPROC
PROCEDURE ConstruiesteToDlg
*-- toDlg construit INLINE (nu intr-o functie apelata din procedura de business) - vezi
*-- docs/testare-ui-vfp.md capcana l; aici functioneaza fiindca goT e PUBLIC.
goT = CREATEOBJECT('Empty')
=ADDPROPERTY(goT,'serie_act',ALLTRIM(NVL(goDlg.cSerieAct,'')))
=ADDPROPERTY(goT,'nract',goDlg.nNract)
=ADDPROPERTY(goT,'dataact',goDlg.dDataAct)
=ADDPROPERTY(goT,'fdoc',goDlg.cFelDoc)
=ADDPROPERTY(goT,'id_fdoc',goDlg.nIdFdoc)
=ADDPROPERTY(goT,'id_partc',goDlg.nIdPartener)
=ADDPROPERTY(goT,'partc',goDlg.cPartener)
=ADDPROPERTY(goT,'explicatia',ALLTRIM(NVL(goDlg.cExplicatia,'')))
=ADDPROPERTY(goT,'suma',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,IIF(goDlg.nSumaLei<>0,goDlg.nSumaLei,ROUND(goDlg.nSuma*goDlg.nCurs,gnPC)),goDlg.nSuma))
=ADDPROPERTY(goT,'suma_val',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,goDlg.nSuma,0))
=ADDPROPERTY(goT,'in_valuta',goDlg.chkInValutaCont.Value)
=ADDPROPERTY(goT,'participa_valuta',(goDlg.chkParticipaValuta.Value=1))
=ADDPROPERTY(goT,'id_valuta',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nIdValuta,0))
=ADDPROPERTY(goT,'curs',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nCurs,0))
=ADDPROPERTY(goT,'nume_val',IIF(goDlg.chkInValutaCont.Value=1,ALLTRIM(NVL(goDlg.cValuta,'')),''))
=ADDPROPERTY(goT,'cTipTva',IIF(goDlg.optTipTva.Value=1,'F',IIF(goDlg.optTipTva.Value=2,'D','N')))
=ADDPROPERTY(goT,'id_jtva_coloana',goDlg.nIdExplicatieTva)
=ADDPROPERTY(goT,'dvi_serie',CHRTRAN(ALLTRIM(NVL(goDlg.cSerieDvi,'')),CHR(34),''))
=ADDPROPERTY(goT,'dvi_nract',goDlg.nNractDvi)
=ADDPROPERTY(goT,'dvi_dataact',goDlg.dDviData)
=ADDPROPERTY(goT,'dvi_id_fdoc',goDlg.nIdFdocDVI)
=ADDPROPERTY(goT,'dvi_fdoc',goDlg.cFelDocDvi)
=ADDPROPERTY(goT,'dvi_id_partc',goDlg.nDviIdPartener)
=ADDPROPERTY(goT,'dvi_partc',goDlg.cDviPartener)
=ADDPROPERTY(goT,'dvi_scc','401')
=ADDPROPERTY(goT,'dvi_tva_lei',goDlg.nDviTvaLei)
=ADDPROPERTY(goT,'dvi_tva_val',goDlg.nDviTvaVal)
ENDPROC
PROCEDURE CreeazaRulTemp
*-- structura reala rul_temp (VRUL, Oracle dev) - identica cu test_scenariu_dvi_complet.prg,
*-- necesara ca GridArt/footer sa gaseasca toate coloanele (pret_val, pretd, pret, cant).
IF USED('rul_temp')
USE IN ('rul_temp')
ENDIF
CREATE CURSOR rul_temp ( ;
id_rul N(20,0), an N(4,0), luna N(2,0), cod N(20,0);
, serie C(100), nnir N(20,0), id_articol N(10,0), denumire C(100);
, codmat C(50), codmatf C(50), codbare C(50), um C(20);
, id_gestiune N(5,0), nume_gestiune C(50), cgest C(20), nr_pag N(2,0);
, gestionar C(50), comisie_receptie1 C(50), comisie_receptie2 C(50), comisie_receptie3 C(50);
, cant N(14,3), cante N(14,3), cont C(10), acont C(20);
, pret N(18,4), tva N(18,4), valoare N(18,4), valtva N(18,4);
, proc_tva N(5,2), pretv N(18,4), pretvtva N(18,4), tvav N(18,4);
, valoarev N(18,4), valtvav N(18,4), proc_tvav N(5,2), adaos N(18,4);
, adaos_tva N(18,4), valoare_adaos N(18,4), valtva_adaos N(18,4), procent N(10,3);
, discunitar N(18,4), discount_tva N(18,4), valoare_discount N(18,4), valtva_discount N(18,4);
, proc_disc N(7,3), pretd N(14,4), curs N(18,4), id_valuta N(10,0);
, nume_val C(20), id_lucrare N(20,0), nrord C(100), id_responsabil N(10,0);
, nresp C(100), resp_marca N(18,4), dataact T, id_util N(5,0);
, util C(30), dataora T, id_sectie N(5,0), sectie C(50);
, csectie C(10), alcooltutun N(1,0), datain T, dataout T;
, id_fact N(20,0), id_gestiunec N(10,0), nume_gestiunec C(50), cgestc C(20);
, id_responsabilc N(5,0), id_reteta N(10,0), reteta C(50), nrespc C(100);
, respc_marca N(18,4), id_set N(20,0), id_tip_rulaj N(10,0), tip_rulaj C(50);
, id_obiect_depozit N(10,0), id_rul_aux N(10,0), nract N(20,0), serie_act C(10);
, dataoras T, id_utils N(10,0), lot C(30), adata_expirare T;
, id_sucursala N(5,0), sucursala C(250), id_part_rez N(10,0), part_rez C(100);
, id_lucrare_rez N(10,0), nrord_rez C(100), subgrupa C(100), grupa C(100);
, id_subgrupa N(5,0), id_grupa N(5,0), in_stoc N(1,0), in_crm N(1,0);
, id_furnizor N(10,0), furnizor C(100), id_jtva_coloana N(4,0), explicatie_tva C(100);
, taxcode N(6,0), taxname C(254), saft_procent N(18,4), codnc8 C(20);
, id_tara_origine N(4,0), cod_tara_origine C(5), tara_origine C(50), greutate N(12,4);
, fdoc C(30), id_fdoc N(18,4);
, pret_lei N(18,4), pret_val N(14,4), cota_tva N(6,2))
ENDPROC
PROCEDURE CreeazaIntrodc
LPARAMETERS tcAlias
IF USED(tcAlias)
USE IN (tcAlias)
ENDIF
CREATE CURSOR (tcAlias) ( ;
id_note N(14), explicatia C(100), scd C(10), ascd C(20), scc C(10), ascc C(20), ;
cu_tva N(1), id_set N(14), ordine N(8), in_valuta N(1), id_jtva_coloana N(14) NULL, ;
ptva N(6,2), explicatie_tva C(50), tipjurnal C(2), taxcode N(6), paymentcode C(9), ;
suma N(18,4), suma_val N(18,4), id_partd N(14), id_partc N(14), partd C(100), partc C(100), ;
id_fact N(14), id_factd N(14), id_factc N(14), pereched N(14), perechec N(14), ;
nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), ;
scd_orig C(20), ascd_orig C(20))
ENDPROC
PROCEDURE VerificaPereche
LPARAMETERS tnNract, tnBazaLei, tnBazaVal, tcVal
LOCAL lnSel, lcMsg, llB, lnBS, lnBSV, lcNV
lnSel = SELECT()
SELECT introdc
LOCATE FOR nract = tnNract AND tip_rand == 'B'
llB = FOUND()
IF llB
lnBS = suma
lnBSV = suma_val
lcNV = ALLTRIM(NVL(nume_val,''))
ENDIF
IF llB AND ABS(lnBS - tnBazaLei) < 0.01 AND ABS(lnBSV - tnBazaVal) < 0.01 AND ALLTRIM(NVL(lcNV,'')) == tcVal
lcMsg = 'PASS pereche nract=' + TRANSFORM(tnNract) + ': B(suma=' + TRANSFORM(lnBS) + ' val=' + TRANSFORM(lnBSV) + ' ' + lcNV + ')'
ELSE
lcMsg = 'FAIL pereche nract=' + TRANSFORM(tnNract) + ': B?=' + TRANSFORM(llB) + ' bazaLei=' + TRANSFORM(IIF(llB,lnBS,-1)) + '(astept ' + TRANSFORM(tnBazaLei) + ') bazaVal=' + TRANSFORM(IIF(llB,lnBSV,-1)) + '(astept ' + TRANSFORM(tnBazaVal) + ') val=[' + IIF(llB,lcNV,'?') + '](astept [' + tcVal + '])'
ENDIF
DO MtLog WITH lcMsg
SELECT (lnSel)
ENDPROC
PROCEDURE VerificaDvi
LPARAMETERS tnNract, tnNractDvi, tnBazaLei, tnTvaLei, tnTvaVal
LOCAL lnSel, lcMsg, llB, llT, lnBS, lnTS, lnTSV, lcTPartc, llVama, lnNrDocCrt
lnSel = SELECT()
SELECT introdc
LOCATE FOR nract = tnNract AND tip_rand == 'B'
llB = FOUND()
IF llB
lnBS = suma
lnNrDocCrt = nr_doc
ENDIF
llT = .F.
IF llB
LOCATE FOR nr_doc = lnNrDocCrt AND tip_rand == 'T'
llT = FOUND()
IF llT
lnTS = suma
lnTSV = suma_val
lcTPartc = ALLTRIM(NVL(partc,''))
llVama = ('VAMAL' $ UPPER(lcTPartc)) AND nract = tnNractDvi
ENDIF
ENDIF
IF llB AND llT AND ABS(lnBS - tnBazaLei) < 0.01 AND ABS(lnTS - tnTvaLei) < 0.01 AND ABS(lnTSV - tnTvaVal) < 0.01 AND llVama
lcMsg = 'PASS DVI nract=' + TRANSFORM(tnNract) + ': B(suma=' + TRANSFORM(lnBS) + ') + T_DVI(nr_doc=' + TRANSFORM(lnNrDocCrt) + ' partc=' + lcTPartc + ' suma=' + TRANSFORM(lnTS) + ' suma_val=' + TRANSFORM(lnTSV) + ')'
ELSE
lcMsg = 'FAIL DVI nract=' + TRANSFORM(tnNract) + ': B(suma=' + TRANSFORM(IIF(llB,lnBS,-1)) + ', astept ' + TRANSFORM(tnBazaLei) + ') T_DVI(suma=' + TRANSFORM(IIF(llT,lnTS,-1)) + ', astept ' + TRANSFORM(tnTvaLei) + ' suma_val=' + TRANSFORM(IIF(llT,lnTSV,-1)) + ', astept ' + TRANSFORM(tnTvaVal) + ' partc=' + IIF(llT,lcTPartc,'?') + ')'
ENDIF
DO MtLog WITH lcMsg
SELECT (lnSel)
ENDPROC
PROCEDURE DumpIntrodc
LOCAL lnSel
lnSel = SELECT()
SELECT introdc
SCAN
DO MtLog WITH ' recno=' + TRANSFORM(RECNO()) + ' nr_doc=' + TRANSFORM(NVL(nr_doc,0)) + ' nract=' + TRANSFORM(nract) + ' fdoc=[' + ALLTRIM(NVL(fdoc,'')) + '] tip_rand=' + tip_rand + ;
' scd=' + ALLTRIM(scd) + ' suma=' + TRANSFORM(suma) + ' suma_val=' + TRANSFORM(suma_val) + ' mod_manual=' + TRANSFORM(NVL(mod_manual,0)) + ;
' partc=[' + ALLTRIM(NVL(partc,'')) + '] doc_key=[' + ALLTRIM(doc_key) + ']'
ENDSCAN
SELECT (lnSel)
ENDPROC
FUNCTION RECCOUNT_ACTIVE
LPARAMETERS tcAlias
LOCAL lnSel, lnCnt
lnSel = SELECT()
SELECT (tcAlias)
COUNT TO lnCnt FOR !DELETED()
SELECT (lnSel)
RETURN lnCnt
ENDFUNC
PROCEDURE MtErr
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
DO MtLog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
ENDPROC
PROCEDURE MtLog
LPARAMETERS tcMsg
SET SAFETY OFF
LOCAL lcL
lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '')
STRTOFILE(lcL + tcMsg + CHR(13)+CHR(10), gcUILog)
ENDPROC
DEFINE CLASS dummyapp AS Custom
PROCEDURE ReadIni
LPARAMETERS tcSection, tcKey
RETURN ''
ENDPROC
PROCEDURE WriteIni
LPARAMETERS tcSection, tcKey, tcValue
RETURN .T.
ENDPROC
ENDDEFINE
DEFINE CLASS dummyexecutor AS Custom
cEroare = ''
PROCEDURE oExecute
LPARAMETERS tcSql, tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF 'VJTVA_COLOANE' $ UPPER(m.tcSql)
DO CreeazaJtvaColoaneView WITH m.tcCursor
RETURN 1
ENDIF
IF UPPER(ALLTRIM(m.tcCursor)) == 'RUL_TEMP'
CREATE CURSOR (m.tcCursor) (denumire C(100), codmat C(30), cant N(14,3), ;
pret_val N(18,4), pretd N(18,4), pret N(18,4), pret_lei N(18,4), cont C(10), ;
acont C(20), serie C(30), lot C(30), adata_expirare C(10), proc_disc N(6,2), cota_tva N(6,2))
RETURN 1
ENDIF
IF 'CONFIG_ANALITICE' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (camp_leg_prefix C(30), camp_leg_sufix C(30))
INSERT INTO (m.tcCursor) VALUES ('', '')
RETURN 1
ENDIF
IF 'FCONTURI_ANALITICE' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (acont C(20))
INSERT INTO (m.tcCursor) VALUES (IIF(TYPE('gcMockAcontCrt') = 'C', gcMockAcontCrt, ''))
RETURN 1
ENDIF
IF 'VPLCONT_ANALITIC' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (cont C(10), acont C(20))
INSERT INTO (m.tcCursor) VALUES ('212', '1')
INSERT INTO (m.tcCursor) VALUES ('371', '4')
RETURN 1
ENDIF
CREATE CURSOR (m.tcCursor) (id_temp N(1))
RETURN 1
ENDPROC
PROCEDURE oExecuta
LPARAMETERS tcSql, tcCursor
IF !EMPTY(m.tcCursor)
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF UPPER(m.tcCursor) == 'CJTVACOL4427'
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14))
ELSE
CREATE CURSOR (m.tcCursor) (id_temp N(1))
ENDIF
ENDIF
RETURN .T.
ENDPROC
PROCEDURE oSelect2Value
LPARAMETERS tcSql, toValue
toValue = ''
RETURN 1
ENDPROC
PROCEDURE oReset
ENDPROC
ENDDEFINE
PROCEDURE CreeazaJtvaColoaneView
LPARAMETERS tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14), denumire C(100), jc N(1), jv N(1), ;
coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14) NULL, afisat N(1), ;
id_jtva_ex N(14) NULL, id_jtva_neex N(14) NULL, ordine N(8), ;
taxcode N(6) NULL, taxcode_neexigibil N(6) NULL, taxcode_n50 N(6) NULL, ;
taxcode_n50_tvai N(6) NULL, taxcode_n100 N(6) NULL, taxcode_regularizare N(6) NULL, taxcode_tvai N(6) NULL)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, afisat, ordine, cota_tva) VALUES (0, '', 0, 0, 1, 0, 0)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (208, 'ACH. INT. 21%', 1, 0, 'RO21B', 21, 209, 1, 1, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (209, 'TVA ACH. INT. 21%', 1, 0, 'RO21T', 21, 1, 2, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (220, 'ACH. IMP. 21%', 1, 0, 'FO21B', 21, 221, 1, 3, 301204)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (221, 'TVA ACH. IMP. 21%', 1, 0, 'FO21T', 21, 1, 4, 301204)
ENDPROC

View File

@@ -0,0 +1,13 @@
# test_manual_tva_footer.ps1 - wrapper peste harness-ul generic pentru scenariul rundelor 15-17
# (nOldVal unic, do_calculeaza_diferente fara repozitionare pe tnRecNo, protectie mod_manual pe T,
# footer _grdfooter1 pe GridArt). Rulare:
# powershell -ExecutionPolicy Bypass -File test_manual_tva_footer.ps1
$ErrorActionPreference = 'Stop'
$Teste = $PSScriptRoot
& (Join-Path (Split-Path $Teste -Parent) 'vfp_ui_harness.ps1') `
-TestPrg (Join-Path $Teste 'test_manual_tva_footer.prg') `
-Steps @('3documente','articole_sincronizate','corectie_manuala_tva','f5_verificare','final') `
-ShotsDir (Join-Path $Teste 'screenshots_tva_footer') `
-SyncDir (Join-Path $Teste 'uisync_tva_footer') `
-StepTimeoutSec 180 `
-ReadyTimeoutSec 180

View File

@@ -0,0 +1,642 @@
* test_picker_real_212.prg
* Test cerut de Marius (utilizator real, 17.07.2026): a selectat BULDOEXCAVATOR (cont 212) in
* dialogul real de cautare (butonul "Adauga repere") si NU s-a adaugat nimic in grila, FARA niciun
* mesaj. Testul anterior (test_adauga_repere_212.prg) mock-uia cauta_nom_articole INTREG - nu
* acoperea dialogul real de cautare (formularul cauta_alfa_form, COMUN\clase\cauta_alfa_forms.vcx).
*
* Aici do_adauga_articol() e REAL, cauta_nom_articole() e REAL, XML2ListaIDDescriere() e REAL;
* SINGURUL punct inlocuit e cauta_alfa() (COMUN\programe\cauta_alfa.prg) - shadow in
* mock_cauta_alfa_dialog.prg, care instantiaza formularul REAL cauta_alfa_form si ii apeleaza
* metodele REALE (do_alege/do_termin/do_renunt), doar cu sursa de date Oracle inlocuita de un
* cursor mock (This.CursorFill() din decabaza.vc2 cere o conexiune reala - nu poate fi mock-uit
* prin goExecutor ca restul infrastructurii) si bucla modala inlocuita de actiuni programatice
* (WindowType=0, vezi docs/testare-ui-vfp.md capcana g). Vezi mock_cauta_alfa_dialog.prg pentru
* detalii si motivatie completa.
*
* Scenarii (fiecare printr-un apel REAL la goObj.do_adauga_articol()):
* A: BULDOEXCAVATOR marcat (do_alege() real) + OK (do_termin() real) -> articolul TREBUIE sa
* apara in rul_temp/grila.
* B: nimic marcat + OK direct -> ipoteza cailor tacute: gnButon=1 (OK seteaza mereu gnButon=1,
* indiferent de marcaj - _frm_base.do_termin), XML dintr-un cursor GOL (CURSORTOXML pe 0
* randuri) NU e EMPTY() ca string -> trece de "IF gnButon=1 AND !EMPTY(lcXMLArticole)" ->
* XMLTOCURSOR da 0 randuri -> SCAN nu itereaza -> nimic adaugat, FARA mesaj (tlLoud implicit
* .F. la cauta_nom_articole(lcFiltru) cu un singur parametru - suprima mesajul din
* XML2ListaIDDescriere indiferent de nr. de randuri).
* C: dublu-click pe denumire (fara marcaj) - in modul multi-select (lAles=.T.) NU exista binding
* dblClick->do_termin (cauta_alfa_forms.vc2:652 "If !Thisform.lales") - dublu-click echivaleaza
* cu 2x Click (do_alege de 2 ori: marcheaza apoi demarcheaza) - fara submit automat.
*
* Rulare:
* powershell -ExecutionPolicy Bypass -File vfp_ui_harness.ps1 `
* -TestPrg test_picker_real_212.prg `
* -Steps @('nota-goala','dialog-A-marcat','grila-A-rezultat','rezultat-B','rezultat-C','final')
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET DECIMALS TO 4
SET NULLDISPLAY TO ''
CLOSE DATABASES
PUBLIC gcUILog, gcSyncDir
gcUILog = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\test_picker_real_212_log.txt"
gcSyncDir = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\uisync_picker212\"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcUILog)
ON ERROR DO PrErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
TRY
LOCAL gcAppPath, lcPath
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;' + ;
ADDBS(SUBSTR(gcAppPath,1,RAT([\],gcAppPath,2)))+[COMUNROA\]
SET PATH TO &lcPath ADDITIVE
DO PrLog WITH 'SET PATH OK'
*----- CLASE -----
SET CLASSLIB TO (gcAppPath + "comun\clase\appwiz") 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 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 wwdialogs.vcx ADDITIVE
SET CLASSLIB TO oimportxml.vcx ADDITIVE
SET CLASSLIB TO excelxml.vcx ADDITIVE
SET CLASSLIB TO orapoarte_obinv.vcx ADDITIVE
DO PrLog WITH 'SET CLASSLIB OK'
*----- PROCEDURI (mock amessagebox + shadow cauta_alfa PRIMELE, ui_harness la final) -----
SET PROCEDURE TO PROCEDURI
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_cauta_alfa_dialog.prg" 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 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 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 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
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\ui_harness.prg" ADDITIVE
DO PrLog WITH 'SET PROCEDURE OK'
*----- Globale -----
PUBLIC gnPc, gnPval, gnPcant, gnPpret, gnPPretval, gnPCurs, gnPVal, gnPPretV, gnPPretVal
STORE 2 TO gnPc, gnPval, gnPVal
gnPcant = 3
STORE 4 TO gnPpret, gnPPretval, gnPPretVal, gnPPretV, gnPCurs
PUBLIC gl406, gcS, gnAn, gnLuna, gnIdFirma, gnIdSucursala, gcAcces, gcFirma
gl406 = .T.
gcS = 'CONTAFIN'
gnAn = YEAR(DATE())
gnLuna = MONTH(DATE())
gnIdFirma = 110
gnIdSucursala = 110
gcAcces = "1;2;3;4;5;6;7;8;"
gcFirma = gcS
PUBLIC nror(65000)
*-- gnButon: variabila "gola" folosita in tot lantul cauta_alfa->do_termin/do_renunt->
*-- do_adauga_articol. In aplicatia reala e declarata PRIVATE o singura data la pornire
*-- (Programe/roagest.prg:496) si ramane vizibila tot restul rularii; aici o declar PUBLIC.
PUBLIC gnButon
STORE 0 TO gnButon
*-- Control test citit de mock_cauta_alfa_dialog.prg
PUBLIC gcTestScenariu
PUBLIC gcTestGnButon, gcTestXML, gcTestLenXML, gcTestCAles, gcTestRandiuriMarcate
*-- diagnostic cerut de team lead: pcAles (variabila PRIVATE folosita in filtrul XML) vs
*-- Thisform.cAles (marcajul vizual/albastrit) - verifica daca raman SINCRONE
PUBLIC gcTestPcAles, gcTestPcAlesInainte, gcTestCAlesInainte
PUBLIC goExecutor, goApp
goExecutor = CREATEOBJECT('dummyexecutor')
goApp = CREATEOBJECT('dummyapp')
*----- poAct: antetul notei -----
PUBLIC poAct
poAct = CREATEOBJECT('Custom')
poAct.AddProperty('nume_val', '')
poAct.AddProperty('curs', 1)
poAct.AddProperty('proc_tva', 1.21)
poAct.AddProperty('nnir', 0)
poAct.AddProperty('id_valuta', 0)
poAct.AddProperty('id_fdoc', 1)
poAct.AddProperty('fdoc', 'Factura')
poAct.AddProperty('id_partc', 500)
poAct.AddProperty('partc', 'FURNIZOR ANTET SRL')
poAct.AddProperty('serie_act', '')
poAct.AddProperty('dataact', DATE())
poAct.AddProperty('tva_incasare', 0)
poAct.AddProperty('id_set', 1)
poAct.AddProperty('id_gestin', 1)
*----- jtva_coloane2 / saft_taxtable: perechi reale (ca in test_adauga_repere_212.prg) -----
IF USED('jtva_coloane2')
USE IN ('jtva_coloane2')
ENDIF
CREATE CURSOR jtva_coloane2 (ordine N(8), id_jtva_coloana N(14), denumire C(100), ;
jc N(1), jv N(1), afisat N(1), coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14))
INSERT INTO jtva_coloane2 VALUES (0, 0, '', 0, 0, 1, '', '', 0, 0)
INSERT INTO jtva_coloane2 VALUES (1, 208, 'ACH. INT. 21%', 1, 0, 1, 'RO21B', 'RO21T', 21, 209)
INSERT INTO jtva_coloane2 VALUES (2, 209, 'TVA ACH. INT. 21%', 1, 0, 1, 'RO21T', '', 21, 0)
INSERT INTO jtva_coloane2 VALUES (3, 220, 'ACH. IMP. 21%', 1, 0, 1, 'FO21B', 'FO21T', 21, 221)
INSERT INTO jtva_coloane2 VALUES (4, 221, 'TVA ACH. IMP. 21%', 1, 0, 1, 'FO21T', '', 21, 0)
IF USED('saft_taxtable')
USE IN ('saft_taxtable')
ENDIF
CREATE CURSOR saft_taxtable (taxname C(250) NULL, typename C(250) NULL, taxcode N(6) NULL, ;
taxtype N(3) NULL, descriere C(250) NULL, tip C(100) NULL, descriere_tip C(250) NULL, ;
procent_taxa N(7,2) NULL, procent_prorata N(7,2) NULL, inactiv N(1) NULL, tva N(1) NULL, ;
wht N(1) NULL, tva_achizitii N(1) NULL, tva_livrari N(1) NULL)
INDEX ON taxcode TAG taxcode
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('', 0, '', 0, 1, 1, 1, 1)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301104-Achizitii de bunuri si servicii taxabile cu cota de 21%, altele decat importurile si cele supuse masurilor de simplificare', 301104, '', 21, 1, 0, 1, 0)
*----- introdc: 1 document principal, deja adaugat, ca sa existe o cota_tva de mostenit -----
DO CreeazaIntrodc WITH 'introdc'
INSERT INTO introdc (nract, dataact, fdoc, id_fdoc, id_partc, partc, explicatia, suma, ;
tip_rand, scd, scc, cu_tva, id_set, ordine, participa_valuta, id_jtva_coloana, ptva, ;
explicatie_tva, doc_key) ;
VALUES (100, DATE(), 'Factura', 1, 601, 'FURNIZOR PRINCIPAL SRL', 'Marfa', 5000, ;
'B', '371', '401', 1, 1, 1, .T., 208, 21, 'ACH. INT. 21%', 'B|100|1|601')
INSERT INTO introdc (nract, dataact, fdoc, id_fdoc, id_partc, partc, suma, ;
tip_rand, scd, scc, cu_tva, id_set, ordine, participa_valuta, id_jtva_coloana, ptva, ;
explicatie_tva, doc_key) ;
VALUES (100, DATE(), 'Factura', 1, 601, 'FURNIZOR PRINCIPAL SRL', 1050, ;
'T', '4426', '401', 1, 1, 2, .T., 209, 21, 'TVA ACH. INT. 21%', 'T|100|1|601')
GO TOP IN introdc
*----- rul_temp cu 1 rand INAINTE de instantiere (capcana k) -----
DO CreeazaRulTemp
INSERT INTO rul_temp (denumire, codmat, cant, pret, pret_lei, cont, cota_tva) ;
VALUES ('PLACEHOLDER', 'PH', 1, 1, 1, '371', 21)
*----- gcMockNomCursor: "nomenclatorul fals" cerut de team lead - BULDOEXCAVATOR cont 212 +
* 2 articole in plus, cu structura EXACTA a select-ului din cauta_nom_articole
* (ocautare.prg:563-567, vnom_articole_toate). -----
IF USED('nom_fals')
USE IN ('nom_fals')
ENDIF
CREATE CURSOR nom_fals ( ;
denumire C(100), codmat C(30), codbare C(30), um C(10), grupa C(50), subgrupa C(50), ;
id_grupa N(10), id_subgrupa N(10), dnf C(20), cont C(10), acont C(20), inactiv N(1), ;
id_articol N(10), um2 C(10), um_iso C(10), cod_um_iso C(10), cant_bax N(10,3), ;
in_crm N(1), in_stoc N(1), codmatf C(30), conditii_pastrare C(100), id_part N(10), ;
partener C(100), indicativ C(30), taxa_reconditionare N(10,4), id_articol_general N(10), ;
articol_general C(100), listare_codbare N(1), tip C(20), timpn N(10,4), codnc8 C(20), ;
greutate N(10,4), id_tara_origine N(5), tara_origine C(50), codcpv C(20))
INSERT INTO nom_fals (denumire, codmat, um, cont, acont, inactiv, id_articol, in_stoc) ;
VALUES ('BULDOEXCAVATOR', 'ART-BULD-212', 'BUC', '212', '', 0, 1001, 1)
INSERT INTO nom_fals (denumire, codmat, um, cont, acont, inactiv, id_articol, in_stoc) ;
VALUES ('EXCAVATOR MIC', 'ART-EXC-212', 'BUC', '212', '', 0, 1002, 1)
INSERT INTO nom_fals (denumire, codmat, um, cont, acont, inactiv, id_articol, in_stoc) ;
VALUES ('MOTOSAPA', 'ART-MOTO-213', 'BUC', '213', '', 0, 1003, 1)
GO TOP IN nom_fals
*----- goDlgA/B/C: cele 3 dialoage REALE (cauta_alfa_form), PRE-CONSTRUITE aici in programul
* PRINCIPAL - CREATEOBJECT apelat dintr-o procedura intoarce obiect stricat in acest runtime
* headless (capcana l, docs/testare-ui-vfp.md); shadow-ul (mock_cauta_alfa_dialog.prg) doar
* selecteaza unul din aceste 3 obiecte dupa gcTestScenariu, nu le mai construieste. Fiecare
* are propriul cursor (copie din nom_fals), ca marcajele dintr-un scenariu sa nu se scurga in
* altul. Parametrii Init sunt EXACT cei trimisi de cauta_nom_articole (ocautare.prg:556-575)
* catre cauta_alfa: coloane/titluri identice, ll_AllInList=.F., tnTipReturn=1 (lAles=.T.). -----
LOCAL lcTitluColoaneNom, lcColoaneNom
lcTitluColoaneNom = 'Denumire,Cod Material,Cod bare,UM,Grupa,Subgrupa,Cont,Analitic,DNF,Id'
lcColoaneNom = 'denumire,codmat,codbare,um,grupa,subgrupa,cont,acont,dnf,id_articol'
PUBLIC goDlgA, goDlgB, goDlgC
LOCAL lcCurA, lcCurB, lcCurC
lcCurA = SYS(2015)
SELECT * FROM nom_fals INTO CURSOR (lcCurA) READWRITE
lcCurB = SYS(2015)
SELECT * FROM nom_fals INTO CURSOR (lcCurB) READWRITE
lcCurC = SYS(2015)
SELECT * FROM nom_fals INTO CURSOR (lcCurC) READWRITE
goDlgA = CREATEOBJECT('cauta_alfa_form', lcCurA, '', lcTitluColoaneNom, lcColoaneNom, .F., 'denumire', 1)
goDlgA.crs_cursor = lcCurA
goDlgA.Lb_titlu_alb_b121.Caption = 'Alegeti articolele (mouse-click pe denumire sau apasati SPACE)'
goDlgA.lAles = .T.
goDlgA.cAles = REPLICATE(' ', RECCOUNT(lcCurA))
goDlgA.cIdColumn = 'id_articol'
goDlgA.WindowType = 0
goDlgA.Show()
goDlgB = CREATEOBJECT('cauta_alfa_form', lcCurB, '', lcTitluColoaneNom, lcColoaneNom, .F., 'denumire', 1)
goDlgB.crs_cursor = lcCurB
goDlgB.Lb_titlu_alb_b121.Caption = 'Alegeti articolele (mouse-click pe denumire sau apasati SPACE)'
goDlgB.lAles = .T.
goDlgB.cAles = REPLICATE(' ', RECCOUNT(lcCurB))
goDlgB.cIdColumn = 'id_articol'
goDlgB.WindowType = 0
goDlgB.Show()
goDlgC = CREATEOBJECT('cauta_alfa_form', lcCurC, '', lcTitluColoaneNom, lcColoaneNom, .F., 'denumire', 1)
goDlgC.crs_cursor = lcCurC
goDlgC.Lb_titlu_alb_b121.Caption = 'Alegeti articolele (mouse-click pe denumire sau apasati SPACE)'
goDlgC.lAles = .T.
goDlgC.cAles = REPLICATE(' ', RECCOUNT(lcCurC))
goDlgC.cIdColumn = 'id_articol'
goDlgC.WindowType = 0
goDlgC.Show()
DOEVENTS FORCE
DO PrLog WITH 'goDlgA/B/C construite (3 formulare REALE cauta_alfa_form, fiecare cu propriul cursor)'
DO PrLog WITH 'cursoare pregatite, CREATEOBJECT(import_nota, .T.)'
SELECT introdc
PUBLIC goObj
goObj = CREATEOBJECT('IMPORT_nota', .T.)
IF VARTYPE(goObj) <> 'O'
DO PrLog WITH 'FAIL: instantiere import_nota'
DO HarnessDone WITH 'done-error'
QUIT
ENDIF
goObj.lDialogAratat = .T.
goObj.oact = poAct
goObj.WindowType = 0
goObj.Visible = .T.
goObj.Show()
goObj.WindowState = 2
DOEVENTS FORCE
*-- golesc placeholder-ul cu ZAP (capcana k)
SELECT rul_temp
ZAP
goObj.gridart.Refresh()
DOEVENTS FORCE
*========================= PAS 0: nota afisata =========================
DO HarnessStep WITH 0, 'import_nota afisat, rul_temp=' + TRANSFORM(RECCOUNT_ACTIVE('rul_temp')) + ' articole, nom_fals=' + TRANSFORM(RECCOUNT_ACTIVE('nom_fals')) + ' randuri (BULDOEXCAVATOR cont 212 + 2)'
*========================= SCENARIUL A: marcheaza BULDOEXCAVATOR + OK real =========================
LOCAL lnRandInainteA, lnRandDupaA, llEroareA
gcTestScenariu = 'A'
STORE 0 TO gnButon
lnRandInainteA = RECCOUNT_ACTIVE('rul_temp')
llEroareA = .F.
TRY
goObj.do_adauga_articol()
CATCH TO loExcA
llEroareA = .T.
DO PrLog WITH 'SCENARIU A: EROARE la do_adauga_articol() ' + TRANSFORM(loExcA.ErrorNo) + ' [' + loExcA.Message + ;
'] in ' + loExcA.Procedure + ':' + TRANSFORM(loExcA.LineNo) + ' (' + loExcA.LineContents + ')'
ENDTRY
DOEVENTS FORCE
goObj.gridart.Refresh()
DOEVENTS FORCE
lnRandDupaA = RECCOUNT_ACTIVE('rul_temp')
DO PrLog WITH 'SCENARIU A: gnButon(din shadow)=' + TRANSFORM(gcTestGnButon) + ' LEN(XML)=' + TRANSFORM(gcTestLenXML) + ' EMPTY(XML)=' + TRANSFORM(EMPTY(gcTestXML)) + ' randuriMarcate(dupa filtrul X)=' + TRANSFORM(gcTestRandiuriMarcate) + ' cAles=[' + gcTestCAles + ']'
DO PrLog WITH 'SCENARIU A: DIAGNOSTIC pcAles vs Thisform.cAles (cerut de team lead) - pcAlesInainteDeXML=[' + gcTestPcAlesInainte + '] cAlesInainteDeXML=[' + gcTestCAlesInainte + '] SINCRON=' + TRANSFORM(gcTestPcAlesInainte == gcTestCAlesInainte) + ' | dupa=[' + gcTestPcAles + ']'
DO PrLog WITH 'SCENARIU A: XML complet = [' + gcTestXML + ']'
DO PrLog WITH 'SCENARIU A: rul_temp INAINTE=' + TRANSFORM(lnRandInainteA) + ' DUPA=' + TRANSFORM(lnRandDupaA) + ' eroare=' + TRANSFORM(llEroareA)
LOCAL llArtA
llArtA = .F.
SELECT rul_temp
LOCATE FOR ALLTRIM(codmat) == 'ART-BULD-212'
IF FOUND()
llArtA = .T.
DO PrLog WITH 'PASS scenariul A: BULDOEXCAVATOR marcat+OK -> articolul APARE in rul_temp (denumire=' + ALLTRIM(denumire) + ' cont=[' + ALLTRIM(NVL(cont,'')) + '])'
ELSE
DO PrLog WITH 'FAIL scenariul A: BULDOEXCAVATOR marcat+OK -> articolul NU apare in rul_temp (asteptat: sa apara)'
ENDIF
*-- captura grila cu articolul deja adaugat de scenariul A (pasul 1 din harness e scris DIN
*-- INTERIORUL shadow-ului cauta_alfa, la momentul "dialog cu BULDOEXCAVATOR marcat, inainte de
*-- OK" - vezi mock_cauta_alfa_dialog.prg, CASE gcTestScenariu=='A' - deci acesta e pasul 2)
DO HarnessStep WITH 2, 'grila dupa scenariul A (BULDOEXCAVATOR marcat+OK): rul_temp=' + TRANSFORM(RECCOUNT_ACTIVE('rul_temp')) + ' randuri'
*========================= SCENARIUL B: nimic marcat + OK =========================
*-- reset rul_temp la starea goala pentru un test curat al scenariului B
SELECT rul_temp
ZAP
goObj.gridart.Refresh()
DOEVENTS FORCE
LOCAL lnRandInainteB, lnRandDupaB, llEroareB
gcTestScenariu = 'B'
STORE 0 TO gnButon
lnRandInainteB = RECCOUNT_ACTIVE('rul_temp')
llEroareB = .F.
TRY
goObj.do_adauga_articol()
CATCH TO loExcB
llEroareB = .T.
DO PrLog WITH 'SCENARIU B: EROARE la do_adauga_articol() ' + TRANSFORM(loExcB.ErrorNo) + ' [' + loExcB.Message + ']'
ENDTRY
DOEVENTS FORCE
goObj.gridart.Refresh()
DOEVENTS FORCE
lnRandDupaB = RECCOUNT_ACTIVE('rul_temp')
DO PrLog WITH 'SCENARIU B: gnButon(din shadow)=' + TRANSFORM(gcTestGnButon) + ' LEN(XML)=' + TRANSFORM(gcTestLenXML) + ' EMPTY(XML)=' + TRANSFORM(EMPTY(gcTestXML)) + ' randuriMarcate(dupa filtrul X)=' + TRANSFORM(gcTestRandiuriMarcate) + ' cAles=[' + gcTestCAles + ']'
DO PrLog WITH 'SCENARIU B: XML complet = [' + gcTestXML + ']'
DO PrLog WITH 'SCENARIU B: rul_temp INAINTE=' + TRANSFORM(lnRandInainteB) + ' DUPA=' + TRANSFORM(lnRandDupaB) + ' eroare=' + TRANSFORM(llEroareB)
LOCAL llMesajB
llMesajB = ('MOCK amessagebox apelat' $ FILETOSTR(gcUILog))
IF gcTestGnButon = 1 AND gcTestLenXML > 0 AND gcTestRandiuriMarcate = 0 AND lnRandDupaB = lnRandInainteB
DO PrLog WITH 'PASS scenariul B: IPOTEZA CONFIRMATA - OK cu nimic marcat -> gnButon=1, XML NEGOL (' + TRANSFORM(gcTestLenXML) + ' caractere) dintr-un cursor cu 0 randuri marcate, do_adauga_articol NU adauga nimic (rul_temp neschimbat), FARA mesaj de eroare (mesaj amessagebox in log=' + TRANSFORM(llMesajB) + ')'
ELSE
DO PrLog WITH 'FAIL/DIFERIT scenariul A vs ipoteza: gnButon=' + TRANSFORM(gcTestGnButon) + ' (astept 1) LEN(XML)=' + TRANSFORM(gcTestLenXML) + ' (astept >0) randuriMarcate=' + TRANSFORM(gcTestRandiuriMarcate) + ' (astept 0) randDupa=' + TRANSFORM(lnRandDupaB) + ' randInainte=' + TRANSFORM(lnRandInainteB)
ENDIF
*========================= SCENARIUL C: dublu-click pe denumire (fara marcaj) =========================
SELECT rul_temp
ZAP
goObj.gridart.Refresh()
DOEVENTS FORCE
LOCAL lnRandInainteC, lnRandDupaC, llEroareC
gcTestScenariu = 'C'
STORE 0 TO gnButon
lnRandInainteC = RECCOUNT_ACTIVE('rul_temp')
llEroareC = .F.
TRY
goObj.do_adauga_articol()
CATCH TO loExcC
llEroareC = .T.
DO PrLog WITH 'SCENARIU C: EROARE la do_adauga_articol() ' + TRANSFORM(loExcC.ErrorNo) + ' [' + loExcC.Message + ']'
ENDTRY
DOEVENTS FORCE
goObj.gridart.Refresh()
DOEVENTS FORCE
lnRandDupaC = RECCOUNT_ACTIVE('rul_temp')
DO PrLog WITH 'SCENARIU C: gnButon(din shadow)=' + TRANSFORM(gcTestGnButon) + ' LEN(XML)=' + TRANSFORM(gcTestLenXML) + ' EMPTY(XML)=' + TRANSFORM(EMPTY(gcTestXML)) + ' randuriMarcate(dupa filtrul X)=' + TRANSFORM(gcTestRandiuriMarcate) + ' cAles=[' + gcTestCAles + ']'
DO PrLog WITH 'SCENARIU C: rul_temp INAINTE=' + TRANSFORM(lnRandInainteC) + ' DUPA=' + TRANSFORM(lnRandDupaC) + ' eroare=' + TRANSFORM(llEroareC)
IF lnRandDupaC = lnRandInainteC
DO PrLog WITH 'INFO scenariul C: dublu-click pe denumire (fara submit automat pe dblclick in mod multi-select) -> dupa 2x Click(do_alege), OK -> acelasi comportament ca scenariul B (nimic net marcat, nimic adaugat)'
ELSE
DO PrLog WITH 'INFO scenariul C: rul_temp s-a modificat (randDupa=' + TRANSFORM(lnRandDupaC) + ' vs randInainte=' + TRANSFORM(lnRandInainteC) + ')'
ENDIF
DO HarnessStep WITH 3, 'rezultat scenariul B (nimic marcat+OK): rul_temp neschimbat=' + TRANSFORM(lnRandDupaB = lnRandInainteB) + ', fara mesaj=' + TRANSFORM(!llMesajB)
DO HarnessStep WITH 4, 'rezultat scenariul C (dublu-click): rul_temp neschimbat=' + TRANSFORM(lnRandDupaC = lnRandInainteC)
DO PrLog WITH 'GATA - toate scenariile executate (A/B/C)'
DO HarnessStep WITH 5, 'final'
DO HarnessDone WITH 'done'
CATCH TO loExc
DO PrLog WITH 'CATCH ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']'
DO HarnessDone WITH 'done-error'
ENDTRY
QUIT
*==================================================================================
PROCEDURE CreeazaRulTemp
IF USED('rul_temp')
USE IN ('rul_temp')
ENDIF
CREATE CURSOR rul_temp ( ;
id_rul N(20,0), an N(4,0), luna N(2,0), cod N(20,0);
, serie C(100), nnir N(20,0), id_articol N(10,0), denumire C(100);
, codmat C(50), codmatf C(50), codbare C(50), um C(20);
, id_gestiune N(5,0), nume_gestiune C(50), cgest C(20), nr_pag N(2,0);
, gestionar C(50), comisie_receptie1 C(50), comisie_receptie2 C(50), comisie_receptie3 C(50);
, cant N(14,3), cante N(14,3), cont C(10), acont C(20);
, pret N(18,4), tva N(18,4), valoare N(18,4), valtva N(18,4);
, proc_tva N(5,2), pretv N(18,4), pretvtva N(18,4), tvav N(18,4);
, valoarev N(18,4), valtvav N(18,4), proc_tvav N(5,2), adaos N(18,4);
, adaos_tva N(18,4), valoare_adaos N(18,4), valtva_adaos N(18,4), procent N(10,3);
, discunitar N(18,4), discount_tva N(18,4), valoare_discount N(18,4), valtva_discount N(18,4);
, proc_disc N(7,3), pretd N(14,4), curs N(18,4), id_valuta N(10,0);
, nume_val C(20), id_lucrare N(20,0), nrord C(100), id_responsabil N(10,0);
, nresp C(100), resp_marca N(18,4), dataact T, id_util N(5,0);
, util C(30), dataora T, id_sectie N(5,0), sectie C(50);
, csectie C(10), alcooltutun N(1,0), datain T, dataout T;
, id_fact N(20,0), id_gestiunec N(10,0), nume_gestiunec C(50), cgestc C(20);
, id_responsabilc N(5,0), id_reteta N(10,0), reteta C(50), nrespc C(100);
, respc_marca N(18,4), id_set N(20,0), id_tip_rulaj N(10,0), tip_rulaj C(50);
, id_obiect_depozit N(10,0), id_rul_aux N(10,0), nract N(20,0), serie_act C(10);
, dataoras T, id_utils N(10,0), lot C(30), adata_expirare T;
, id_sucursala N(5,0), sucursala C(250), id_part_rez N(10,0), part_rez C(100);
, id_lucrare_rez N(10,0), nrord_rez C(100), subgrupa C(100), grupa C(100);
, id_subgrupa N(5,0), id_grupa N(5,0), in_stoc N(1,0), in_crm N(1,0);
, id_furnizor N(10,0), furnizor C(100), id_jtva_coloana N(4,0), explicatie_tva C(100);
, taxcode N(6,0), taxname C(254), saft_procent N(18,4), codnc8 C(20);
, id_tara_origine N(4,0), cod_tara_origine C(5), tara_origine C(50), greutate N(12,4);
, fdoc C(30), id_fdoc N(18,4);
, pret_lei N(18,4), pret_val N(14,4), cota_tva N(6,2))
ENDPROC
PROCEDURE CreeazaIntrodc
LPARAMETERS tcAlias
IF USED(tcAlias)
USE IN (tcAlias)
ENDIF
CREATE CURSOR (tcAlias) ( ;
id_note N(14), explicatia C(100), scd C(10), ascd C(20), scc C(10), ascc C(20), ;
cu_tva N(1), id_set N(14), ordine N(8), in_valuta N(1), id_jtva_coloana N(14) NULL, ;
ptva N(6,2), explicatie_tva C(50), tipjurnal C(2), taxcode N(6), paymentcode C(9), ;
suma N(18,4), suma_val N(18,4), id_partd N(14), id_partc N(14), partd C(100), partc C(100), ;
id_fact N(14), id_factd N(14), id_factc N(14), pereched N(14), perechec N(14), ;
nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), ;
scd_orig C(20), ascd_orig C(20))
ENDPROC
FUNCTION RECCOUNT_ACTIVE
LPARAMETERS tcAlias
LOCAL lnSel, lnCnt
lnSel = SELECT()
SELECT (tcAlias)
COUNT TO lnCnt FOR !DELETED()
SELECT (lnSel)
RETURN lnCnt
ENDFUNC
PROCEDURE PrErr
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
DO PrLog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
ENDPROC
PROCEDURE PrLog
LPARAMETERS tcMsg
SET SAFETY OFF
LOCAL lcL
lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '')
STRTOFILE(lcL + tcMsg + CHR(13)+CHR(10), gcUILog)
ENDPROC
DEFINE CLASS dummyapp AS Custom
PROCEDURE ReadIni
LPARAMETERS tcSection, tcKey
RETURN ''
ENDPROC
PROCEDURE WriteIni
LPARAMETERS tcSection, tcKey, tcValue
RETURN .T.
ENDPROC
ENDDEFINE
DEFINE CLASS dummyexecutor AS Custom
cEroare = ''
PROCEDURE oExecute
LPARAMETERS tcSql, tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF 'VJTVA_COLOANE' $ UPPER(m.tcSql)
DO CreeazaJtvaColoaneView WITH m.tcCursor
RETURN 1
ENDIF
IF UPPER(ALLTRIM(m.tcCursor)) == 'RUL_TEMP'
DO CreeazaRulTemp
ELSE
CREATE CURSOR (m.tcCursor) (id_temp N(1))
ENDIF
RETURN 1
ENDPROC
PROCEDURE oExecuta
LPARAMETERS tcSql, tcCursor
IF !EMPTY(m.tcCursor)
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF UPPER(m.tcCursor) == 'CJTVACOL4427'
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14))
ELSE
CREATE CURSOR (m.tcCursor) (id_temp N(1))
ENDIF
ENDIF
RETURN .T.
ENDPROC
PROCEDURE oSelect2Value
LPARAMETERS tcSql, toValue
toValue = ''
RETURN 1
ENDPROC
PROCEDURE oReset
ENDPROC
ENDDEFINE
PROCEDURE CreeazaJtvaColoaneView
LPARAMETERS tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14), denumire C(100), jc N(1), jv N(1), ;
coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14) NULL, afisat N(1), ;
id_jtva_ex N(14) NULL, id_jtva_neex N(14) NULL, ordine N(8), ;
taxcode N(6) NULL, taxcode_neexigibil N(6) NULL, taxcode_n50 N(6) NULL, ;
taxcode_n50_tvai N(6) NULL, taxcode_n100 N(6) NULL, taxcode_regularizare N(6) NULL, taxcode_tvai N(6) NULL)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, afisat, ordine, cota_tva) VALUES (0, '', 0, 0, 1, 0, 0)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (208, 'ACH. INT. 21%', 1, 0, 'RO21B', 21, 209, 1, 1, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (209, 'TVA ACH. INT. 21%', 1, 0, 'RO21T', 21, 1, 2, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (220, 'ACH. IMP. 21%', 1, 0, 'FO21B', 21, 221, 1, 3, 301204)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (221, 'TVA ACH. IMP. 21%', 1, 0, 'FO21T', 21, 1, 4, 301204)
ENDPROC

View File

@@ -0,0 +1,10 @@
# test_picker_real_212.ps1 - wrapper peste harness-ul generic pentru testul dialogului REAL de
# cautare/selectie articole (cauta_alfa_form), nu mock cauta_nom_articole intreg.
# Rulare: powershell -ExecutionPolicy Bypass -File test_picker_real_212.ps1
$ErrorActionPreference = 'Stop'
$Teste = $PSScriptRoot
& (Join-Path (Split-Path $Teste -Parent) 'vfp_ui_harness.ps1') `
-TestPrg (Join-Path $Teste 'test_picker_real_212.prg') `
-Steps @('nota-goala','dialog-A-marcat','grila-A-rezultat','rezultat-B','rezultat-C','final') `
-ShotsDir (Join-Path $Teste 'screenshots_picker212') `
-SyncDir (Join-Path $Teste 'uisync_picker212')

View File

@@ -15,7 +15,7 @@
*
* Rulare headless (nu tine VFP IDE deschis; nu rula cu roacont.exe pornit):
* & "C:\Program Files (x86)\Microsoft Visual FoxPro 9\vfp9.exe" -A -T ;
* "D:\ROA\ROACONT\COMUN\utile\Teste\test_repro_cnrcrt_footer.prg" [MOD]
* "D:\ROA\ROACONT\COMUN\utile\Teste\achizitie_import\test_repro_cnrcrt_footer.prg" [MOD]
* MOD:
* CUINDEX (implicit) - fluxul corectat (index pe crsJTVATemp). Asteptat: 63 coloane, OK.
* FARAINDEX - fluxul vechi, fara index. Asteptat: 0 coloane + eroarea CNRCRT
@@ -33,7 +33,7 @@ STRTOFILE('START ' + tcMode + ' ' + TTOC(DATETIME()) + CHR(13)+CHR(10), gcLogFil
ON ERROR DO ReproErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
DO D:\ROA\ROACONT\COMUN\utile\Teste\test_init_env_auto.prg WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
DO D:\ROA\ROACONT\COMUN\utile\Teste\achizitie_import\test_init_env_auto.prg WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
IF gnHandle <= 0
DO ReproLog WITH 'EROARE: conectare Oracle esuata'
DO ReproLog WITH 'REZULTAT: NEDETERMINAT'

View File

@@ -0,0 +1,371 @@
* test_repro_import_nota.prg
* Repro pentru "Data type mismatch" raportat la CREATEOBJECT('IMPORT_nota', tlIntern)
* (COMUN\programe\ointroduceri.prg linia 1621, procedura achizitie_import).
* Clasa import_nota e in COMUN\clase\ointroduceri.vcx (parent frm_termin_renunt OF
* "_frm_child.vcx"). Scop: reproducem instantierea in afara aplicatiei, fara UI/Oracle
* reale (goExecutor e un dummy), ca sa vedem daca eroarea apare la atribuirea
* proprietatilor din definitia clasei (inainte de Init) sau in interiorul Init.
*
* Rulare headless:
* & "C:\Program Files (x86)\Microsoft Visual FoxPro 9\vfp9.exe" -A ;
* "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\test_repro_import_nota.prg"
* Rezultat: D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\test_repro_import_nota_log.txt
LPARAMETERS tcBisect
PUBLIC gcLogFile, gcBisect
gcBisect = IIF(EMPTY(tcBisect), '', UPPER(ALLTRIM(tcBisect)))
gcLogFile = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\test_repro_import_nota_log.txt"
STRTOFILE("START " + TTOC(DATETIME()) + " bisect=" + gcBisect + CHR(13)+CHR(10), gcLogFile)
ON ERROR DO ReproErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
SET SAFETY OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET DECIMALS TO 4
SET NULLDISPLAY TO ''
CLOSE DATABASES
TRY
LOCAL gcAppPath, lcPath
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;' + ;
ADDBS(SUBSTR(gcAppPath,1,RAT([\],gcAppPath,2)))+[COMUNROA\]
SET PATH TO &lcPath ADDITIVE
DO ReproLog WITH 'SET PATH OK'
*----- CLASE -----
SET CLASSLIB TO (gcAppPath + "comun\clase\appwiz") 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
IF EMPTY(gcBisect)
SET CLASSLIB TO ointroduceri ADDITIVE
ENDIF
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 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 wwdialogs.vcx ADDITIVE
SET CLASSLIB TO oimportxml.vcx ADDITIVE
SET CLASSLIB TO excelxml.vcx ADDITIVE
SET CLASSLIB TO orapoarte_obinv.vcx ADDITIVE
*----- Bisectie: cand gcBisect e setat, clasa ointroduceri REALA (linia de mai sus) nu
* s-a incarcat deloc (vezi IF EMPTY(gcBisect) mai sus) - incarcam DOAR copia
* modificata, ca sa nu depindem de ordinea de rezolvare intre doua classlib-uri
* cu acelasi nume de clasa incarcate simultan (risc de fals negativ). Vezi
* COMUN\docs\depanare_testare_vfp.md sectiunea 4. -----
DO CASE
CASE gcBisect == 'H1_CTIP'
SET CLASSLIB TO "C:\Users\mmari\AppData\Local\Temp\claude\D--ROA-ROAGEST\e6e780ff-4117-4276-9c13-3235134137f5\scratchpad\bisect_ointroduceri\ointroduceri.vcx" ADDITIVE
DO ReproLog WITH 'BISECT H1_CTIP: doar clasa modificata incarcata (Column24.ControlSource -> "tip_rand")'
CASE gcBisect == 'H2_CTAXCODE'
SET CLASSLIB TO "C:\Users\mmari\AppData\Local\Temp\claude\D--ROA-ROAGEST\e6e780ff-4117-4276-9c13-3235134137f5\scratchpad\bisect_ointroduceri\ointroduceri.vcx" ADDITIVE
DO ReproLog WITH 'BISECT H2_CTAXCODE: doar clasa modificata incarcata (Column21.ControlSource -> "taxcode")'
CASE gcBisect == 'RULTEMP'
SET CLASSLIB TO ointroduceri ADDITIVE
DO ReproLog WITH 'BISECT RULTEMP: clasa reala + rul_temp pre-creat'
CASE !EMPTY(gcBisect)
SET CLASSLIB TO ("C:\Users\mmari\AppData\Local\Temp\claude\D--ROA-ROAGEST\e6e780ff-4117-4276-9c13-3235134137f5\scratchpad\" + gcBisect + "\ointroduceri.vcx") ADDITIVE
DO ReproLog WITH 'BISECT generic: doar clasa din scratchpad\' + gcBisect + ' incarcata'
ENDCASE
DO ReproLog WITH 'SET CLASSLIB OK'
LOCAL lnCL, lcCLPath, lcCLList
lcCLList = ''
FOR lnCL = 1 TO 1
lcCLPath = SET('CLASSLIB', lnCL)
IF EMPTY(lcCLPath)
EXIT
ENDIF
IF 'OINTRODUCERI' $ UPPER(lcCLPath)
lcCLList = lcCLList + TRANSFORM(lnCL) + '=' + lcCLPath + ' | '
ENDIF
ENDFOR
DO ReproLog WITH 'classlib-uri "ointroduceri" active: ' + lcCLList
*----- PROCEDURI -----
SET PROCEDURE TO PROCEDURI
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 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 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 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
DO ReproLog WITH 'SET PROCEDURE OK'
*----- Globale minimale cerute de definitia clasei / Init -----
PUBLIC gnPc, gnPval, gnPcant, gnPpret, gnPPretval, gnPCurs, gnPVal, gnPPretV, gnPPretVal
gnPc = 2
gnPval = 2
gnPVal = 2
gnPcant = 3
gnPpret = 4
gnPPretval = 4
gnPPretVal = 4
gnPPretV = 4
gnPCurs = 4
PUBLIC gl406, gcS, gnAn, gnLuna, gnIdFirma, gnIdSucursala, gcAcces, gcFirma
gl406 = .F.
gcS = 'CONTAFIN'
gnAn = YEAR(DATE())
gnLuna = MONTH(DATE())
gnIdFirma = 110
gnIdSucursala = 110
gcAcces = "1;2;3;4;5;6;7;8;"
gcFirma = gcS
PUBLIC nror(65000)
*----- goExecutor dummy: creeaza cursorul cerut fara Oracle real -----
PUBLIC goExecutor
goExecutor = CREATEOBJECT('dummyexecutor')
DO ReproLog WITH 'goExecutor dummy creat'
*----- poAct dummy (ramura lIntern=.F.; nu ar trebui atinsa cu tlIntern=.T.) -----
PUBLIC poAct
poAct = CREATEOBJECT('Custom')
poAct.AddProperty('nume_val', 'EUR')
poAct.AddProperty('curs', 5)
poAct.AddProperty('proc_tva', 1.19)
poAct.AddProperty('nnir', 0)
*----- jtva_coloane2: structura din ointroduceri.prg:1601-1609 (SELECT ... INTO CURSOR) -----
IF USED('jtva_coloane2')
USE IN ('jtva_coloane2')
ENDIF
CREATE CURSOR jtva_coloane2 (ordine N(8), id_jtva_coloana N(14), denumire C(100), ;
jc N(1), jv N(1), afisat N(1), coloana_jc C(20), coloana_jv C(20), ;
cota_tva N(6,2), id_tva N(14))
INSERT INTO jtva_coloane2 (ordine, id_jtva_coloana, denumire, jc, jv, afisat, coloana_jc, coloana_jv, cota_tva, id_tva) ;
VALUES (0, 0, '', 0, 0, 1, '', '', 0, 0)
INSERT INTO jtva_coloane2 (ordine, id_jtva_coloana, denumire, jc, jv, afisat, coloana_jc, coloana_jv, cota_tva, id_tva) ;
VALUES (1, 101, 'ACH. INT. 19%', 1, 0, 1, 'coloana_jc', 'coloana_jv', 19, 1)
DO ReproLog WITH 'jtva_coloane2 creat'
*----- saft_taxtable: structura din COMUN\programe\updateserver.prg:625 (update_saft_taxtable) -----
IF USED('saft_taxtable')
USE IN ('saft_taxtable')
ENDIF
CREATE CURSOR saft_taxtable (taxname C(250) NULL, typename C(250) NULL, taxcode N(6) NULL, ;
taxtype N(3) NULL, descriere C(250) NULL, tip C(100) NULL, descriere_tip C(250) NULL, ;
procent_taxa N(7,2) NULL, procent_prorata N(7,2) NULL, inactiv N(1) NULL, tva N(1) NULL, ;
wht N(1) NULL, tva_achizitii N(1) NULL, tva_livrari N(1) NULL)
INDEX ON taxcode TAG taxcode
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('', 0, '', 0, 1, 1, 1, 1)
DO ReproLog WITH 'saft_taxtable creat'
*----- introdc: N.* din cnote_contabile (ointroduceri.prg:1467, select din vnote_contabile) ;
* + coloanele AS din ointroduceri.prg:1553-1563. Ramane GOL (in fluxul real e Zap-uit
* dupa clonarea in introdc_sablon - ointroduceri.prg:1577). Tipuri taxcode/paymentcode
* potrivite dupa saft_taxtable.taxcode (N(6)) si saft_mecanisme_plati.methodcode (C(9)),
* vezi updateserver.prg:625,652.
IF USED('introdc')
USE IN ('introdc')
ENDIF
CREATE CURSOR introdc ( ;
id_note N(14), explicatia C(100), scd C(10), ascd C(20), scc C(10), ascc C(20), ;
cu_tva N(1), id_set N(14), ordine N(8), in_valuta N(1), id_jtva_coloana N(14), ;
ptva N(6,2), explicatie_tva C(50), tipjurnal C(2), taxcode N(6), paymentcode C(9), ;
suma N(18,4), suma_val N(18,4), id_partd N(14), id_partc N(14), partd C(100), partc C(100), ;
id_fact N(14), id_factd N(14), id_factc N(14), pereched N(14), perechec N(14), ;
nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), ;
scd_orig C(20), ascd_orig C(20))
DO ReproLog WITH 'introdc creat (gol, ' + TRANSFORM(FCOUNT('introdc')) + ' campuri)'
*----- rul_temp: in fluxul real e creat abia in Init (T2); il cream aici INAINTE de
* CREATEOBJECT ca sa testam ipoteza ca GridArt (runda 3a) se leaga la constructie
* de rul_temp inexistent. Structura minimala: campurile referite de GridArt. -----
IF gcBisect == 'RULTEMP' OR gcBisect == 'RULTEMP_CUR'
IF USED('rul_temp')
USE IN ('rul_temp')
ENDIF
CREATE CURSOR rul_temp (denumire C(100), codmat C(30), cant N(14,3), ;
pret_val N(18,4), pretd N(18,4), pret N(18,4), pret_lei N(18,4), ;
cont C(10), acont C(20), serie C(30), lot C(30), adata_expirare C(10), ;
proc_disc N(6,2), cota_tva N(6,2))
DO ReproLog WITH 'rul_temp creat INAINTE de CREATEOBJECT'
ENDIF
DO ReproLog WITH 'mediu pregatit, incerc CREATEOBJECT(import_nota)'
SELECT introdc
LOCAL loObj
loObj = CREATEOBJECT('IMPORT_nota', .T.)
IF VARTYPE(loObj) == 'O'
DO ReproLog WITH 'INSTANTIERE OK'
RELEASE loObj
ELSE
DO ReproLog WITH 'INSTANTIERE A RETURNAT ' + TRANSFORM(loObj) + ' (nu obiect)'
ENDIF
CATCH TO loExc
DO ReproLog WITH 'CATCH ErrorNo=' + TRANSFORM(loExc.ErrorNo)
DO ReproLog WITH 'CATCH Message=' + loExc.Message
DO ReproLog WITH 'CATCH Procedure=' + loExc.Procedure
DO ReproLog WITH 'CATCH LineNo=' + TRANSFORM(loExc.LineNo)
DO ReproLog WITH 'CATCH LineContents=' + loExc.LineContents
DO ReproLog WITH 'CATCH Details=' + loExc.Details
DO ReproLog WITH 'CATCH StackLevel=' + TRANSFORM(loExc.StackLevel)
ENDTRY
DO ReproLog WITH 'GATA'
QUIT
PROCEDURE ReproErr
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
DO ReproLog WITH 'ON ERROR (in afara TRY) ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
ENDPROC
PROCEDURE ReproLog
LPARAMETERS tcMsg
LOCAL lcL
lcL = FILETOSTR(gcLogFile)
STRTOFILE(lcL + tcMsg + CHR(13)+CHR(10), gcLogFile)
ENDPROC
DEFINE CLASS dummyexecutor AS Custom
cEroare = ''
PROCEDURE oExecute
LPARAMETERS tcSql, tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
CREATE CURSOR (m.tcCursor) (id_temp N(1))
RETURN 1
ENDPROC
PROCEDURE oExecuta
LPARAMETERS tcSql, tcCursor
IF !EMPTY(m.tcCursor)
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
CREATE CURSOR (m.tcCursor) (id_temp N(1))
ENDIF
RETURN .T.
ENDPROC
ENDDEFINE

View File

@@ -0,0 +1,991 @@
* test_runda7_diferente.prg
* Verifica RUNDA 7 (COMUN\clase\ointroduceri.vcx, clasa import_nota) - vezi
* docs\diff_runda7_dif_lei_6588_focus.patch:
* 1. recalc_diferente: diferenta se scrie DOAR in lei pe randul D (suma_val=0, in_valuta=0,
* participa_valuta=.F., nume_val='', id_valuta=0, curs=0, Thisform.ndif_val=0, explicatia=='DIFERENTA').
* 2. Cont diferenta: dominant clasa 3 -> regulile vechi (34x->711, 371->607, 381/388->608,
* altfel 60+cifrele 3-4 din cont); FARA clasa 3 (doar articole clasa 2/imobilizari) -> scd FIX '6588'.
* 3. sparge_document nu mai scrie sufixul ' (rot.)' in explicatia.
* 4. Guard "doar la modificare" pe Grid1.cSuma/cSumaVal/GridArt.cCotaTva (GotFocus salveaza
* valoarea veche in nsumavechi/nsumavalvechi/ncotatvavechi; Valid iese fara efect daca
* Value == valoarea veche).
* 5. sincronizeaza() restaureaza pozitia si de pe randul D (Locate For tip_rand=='D').
*
* Scenariul A (exemplul lui Marius): FACTURA 100 RAJA EUR curs 5.23 (DVI 101 BIROUL VAMAL) +
* FACTURA 102 TRANS OIL 1000 lei (DVI 101) + FACTURA 103 BIROUL VAMAL 500 lei (TVA la furnizor),
* articole prin fluxul real "Adauga repere": BULDOEXCAVATOR cont 212 (1 buc, 5000 EUR) si
* AC GREE BORA cont 303 (1 buc, 100 EUR) -> dominant clasa 3 (303) -> scd='603'.
* Scenariul B: FACTURA 100 + DVI 101 (subset), UNIC articol BULDOEXCAVATOR cont 212 (imobilizari,
* fara clasa 3) -> scd FIX '6588'.
*
* Rulare:
* powershell -ExecutionPolicy Bypass -File test_runda7_diferente.ps1
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET DECIMALS TO 4
SET NULLDISPLAY TO ''
CLOSE DATABASES
PUBLIC gcUILog, gcSyncDir
gcUILog = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\test_runda7_diferente_log.txt"
gcSyncDir = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\uisync_runda7\"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcUILog)
ON ERROR DO R7Err WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
TRY
LOCAL gcAppPath, lcPath
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;' + ;
ADDBS(SUBSTR(gcAppPath,1,RAT([\],gcAppPath,2)))+[COMUNROA\]
SET PATH TO &lcPath ADDITIVE
DO R7Log WITH 'SET PATH OK'
*----- CLASE -----
SET CLASSLIB TO (gcAppPath + "comun\clase\appwiz") 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 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 wwdialogs.vcx ADDITIVE
SET CLASSLIB TO oimportxml.vcx ADDITIVE
SET CLASSLIB TO excelxml.vcx ADDITIVE
SET CLASSLIB TO orapoarte_obinv.vcx ADDITIVE
DO R7Log WITH 'SET CLASSLIB OK'
*----- PROCEDURI (mock amessagebox + mock cauta_nom_articole PRIMELE, ui_harness la final) -----
SET PROCEDURE TO PROCEDURI
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_cauta_nom_articole.prg" 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 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 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 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
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\ui_harness.prg" ADDITIVE
DO R7Log WITH 'SET PROCEDURE OK'
*----- Globale -----
PUBLIC gnPc, gnPval, gnPcant, gnPpret, gnPPretval, gnPCurs, gnPVal, gnPPretV, gnPPretVal
STORE 2 TO gnPc, gnPval, gnPVal
gnPcant = 3
STORE 4 TO gnPpret, gnPPretval, gnPPretVal, gnPPretV, gnPCurs
PUBLIC gl406, gcS, gnAn, gnLuna, gnIdFirma, gnIdSucursala, gcAcces, gcFirma
gl406 = .T.
gcS = 'CONTAFIN'
gnAn = YEAR(DATE())
gnLuna = MONTH(DATE())
gnIdFirma = 110
gnIdSucursala = 110
gcAcces = "1;2;3;4;5;6;7;8;"
gcFirma = gcS
PUBLIC nror(65000)
PUBLIC gnButon
STORE 2 TO gnButon
PUBLIC gcMockArtCodmat
gcMockArtCodmat = ''
PUBLIC goExecutor, goApp
goExecutor = CREATEOBJECT('dummyexecutor')
goApp = CREATEOBJECT('dummyapp')
*----- poAct: antetul notei; dialogul mosteneste din el la Init -----
PUBLIC poAct
poAct = CREATEOBJECT('Custom')
poAct.AddProperty('nume_val', '')
poAct.AddProperty('curs', 1)
poAct.AddProperty('proc_tva', 1.21)
poAct.AddProperty('nnir', 0)
poAct.AddProperty('id_valuta', 0)
poAct.AddProperty('id_fdoc', 1)
poAct.AddProperty('fdoc', 'Factura')
poAct.AddProperty('id_partc', 500)
poAct.AddProperty('partc', 'FURNIZOR ANTET SRL')
poAct.AddProperty('serie_act', '')
poAct.AddProperty('dataact', DATE())
poAct.AddProperty('tva_incasare', 0)
poAct.AddProperty('id_set', 1)
poAct.AddProperty('id_gestin', 1)
*----- jtva_coloane2 / saft_taxtable: perechi reale 21% (ca in test_scenariu_import_212). -----
IF USED('jtva_coloane2')
USE IN ('jtva_coloane2')
ENDIF
CREATE CURSOR jtva_coloane2 (ordine N(8), id_jtva_coloana N(14), denumire C(100), ;
jc N(1), jv N(1), afisat N(1), coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14))
INSERT INTO jtva_coloane2 VALUES (0, 0, '', 0, 0, 1, '', '', 0, 0)
INSERT INTO jtva_coloane2 VALUES (1, 208, 'ACH. INT. 21%', 1, 0, 1, 'RO21B', 'RO21T', 21, 209)
INSERT INTO jtva_coloane2 VALUES (2, 209, 'TVA ACH. INT. 21%', 1, 0, 1, 'RO21T', '', 21, 0)
INSERT INTO jtva_coloane2 VALUES (3, 220, 'ACH. IMP. 21%', 1, 0, 1, 'FO21B', 'FO21T', 21, 221)
INSERT INTO jtva_coloane2 VALUES (4, 221, 'TVA ACH. IMP. 21%', 1, 0, 1, 'FO21T', '', 21, 0)
IF USED('saft_taxtable')
USE IN ('saft_taxtable')
ENDIF
CREATE CURSOR saft_taxtable (taxname C(250) NULL, typename C(250) NULL, taxcode N(6) NULL, ;
taxtype N(3) NULL, descriere C(250) NULL, tip C(100) NULL, descriere_tip C(250) NULL, ;
procent_taxa N(7,2) NULL, procent_prorata N(7,2) NULL, inactiv N(1) NULL, tva N(1) NULL, ;
wht N(1) NULL, tva_achizitii N(1) NULL, tva_livrari N(1) NULL)
INDEX ON taxcode TAG taxcode
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('', 0, '', 0, 1, 1, 1, 1)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301104-Achizitii de bunuri si servicii taxabile cu cota de 21%, altele decat importurile si cele supuse masurilor de simplificare', 301104, '', 21, 1, 0, 1, 0)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301204-Import de bunuri cota 21%', 301204, '', 21, 1, 0, 1, 0)
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%')
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%')
GO TOP IN introdc_sablon
DO CreeazaRulTemp
INSERT INTO rul_temp (denumire, codmat, cant, pret, pret_lei, cont, cota_tva) ;
VALUES ('PLACEHOLDER', 'PH', 1, 1, 1, '371', 21)
*===================================================================================
*==================== SCENARIUL A: dominant clasa 3 (303) -> scd '603' ===========
*===================================================================================
DO R7Log WITH '========== SCENARIUL A: FACTURA 100/102/103 + articole 212+303 =========='
*-- F1 (ointroduceri.prg:1616-1618): indexul ord_doc, o singura data, INAINTE de CREATEOBJECT -
*-- fara el, Go Top+Locate din sincronizeaza() gaseste documentul "principal" dupa ordinea
*-- fizica (recno), care se schimba dupa fiecare spargere -> cascada gresita pe documente
*-- nefactura-principala. Cu indexul, ordinea e mereu dupa nr_doc (S-urile mostenesc nr_doc-ul
*-- principalei), deci documentul principal ramane stabil la sincronizari repetate.
SELECT introdc
INDEX ON Str(Nvl(nr_doc,0),8) + Icase(tip_rand='B','1', tip_rand='S','2', tip_rand='T','3', tip_rand='D','4', '5') + Padr(Nvl(scd,''),10) TAG ord_doc
SET ORDER TO ord_doc
PUBLIC goObjA
goObjA = CREATEOBJECT('IMPORT_nota', .F.)
IF VARTYPE(goObjA) <> 'O'
DO R7Log WITH 'FAIL: instantiere import_nota (Scenariul A)'
DO HarnessDone WITH 'done-error'
QUIT
ENDIF
goObjA.lDialogAratat = .T.
goObjA.oact = poAct
goObjA.WindowType = 0
goObjA.Visible = .T.
goObjA.Show()
goObjA.WindowState = 2
DOEVENTS FORCE
SELECT rul_temp
ZAP
goObjA.gridart.Refresh()
DOEVENTS FORCE
*----- DOC 1: FACTURA 100, RAJA, DVI valuta (EUR curs 5.23) -----
PUBLIC goDlg, goT
goDlg = CREATEOBJECT('import_adauga_factura', goObjA)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = 100
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 601
goDlg.cPartener = 'RAJA'
goDlg.cExplicatia = 'Import marfa RAJA'
goDlg.nSuma = 1000
goDlg.nSumaLei = 0
goDlg.nCurs = 5.23
goDlg.nIdValuta = 978
goDlg.cValuta = 'EUR'
goDlg.nIdExplicatieTva = 220
goDlg.cExplicatieTva = 'ACH. IMP. 21%'
goDlg.optTipTva.Value = 2 && D = DVI
goDlg.chkInValutaCont.Value = 1
goDlg.chkParticipaValuta.Value = 1
goDlg.cSerieDvi = ''
goDlg.nNractDvi = 101
goDlg.dDviData = DATE()
goDlg.nIdFdocDVI = 2
goDlg.cFelDocDvi = 'DVI'
goDlg.nDviIdPartener = 900
goDlg.cDviPartener = 'BIROUL VAMAL'
goDlg.nDviTvaLei = 1098.30
goDlg.nDviTvaVal = 210.00
goDlg.actualizeaza_stare_dvi()
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO R7Log WITH 'A-DOC1: valideaza = ' + TRANSFORM(goDlg.valideaza())
DO ConstruiesteToDlg
DO R7Log WITH 'A-DOC1: do_adauga_factura = ' + TRANSFORM(goObjA.do_adauga_factura(goT))
goDlg.Hide()
DOEVENTS FORCE
*----- DOC 2: FACTURA 102, TRANS OIL MOTO, DVI lei (acelasi doc vamal 101) -----
goDlg = CREATEOBJECT('import_adauga_factura', goObjA)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = 102
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 602
goDlg.cPartener = 'TRANS OIL MOTO'
goDlg.cExplicatia = 'Achizitie TRANS OIL MOTO'
goDlg.nSuma = 1000
goDlg.nSumaLei = 0
goDlg.nCurs = 0
goDlg.nIdExplicatieTva = 220
goDlg.cExplicatieTva = 'ACH. IMP. 21%'
goDlg.optTipTva.Value = 2 && D = DVI
goDlg.chkInValutaCont.Value = 0
goDlg.chkParticipaValuta.Value = 1
goDlg.cSerieDvi = ''
goDlg.nNractDvi = 101
goDlg.dDviData = DATE()
goDlg.nIdFdocDVI = 2
goDlg.cFelDocDvi = 'DVI'
goDlg.nDviIdPartener = 900
goDlg.cDviPartener = 'BIROUL VAMAL'
goDlg.nDviTvaLei = 210.00
goDlg.nDviTvaVal = 0
goDlg.actualizeaza_stare_dvi()
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO R7Log WITH 'A-DOC2: valideaza = ' + TRANSFORM(goDlg.valideaza())
DO ConstruiesteToDlg
DO R7Log WITH 'A-DOC2: do_adauga_factura = ' + TRANSFORM(goObjA.do_adauga_factura(goT))
goDlg.Hide()
DOEVENTS FORCE
*----- DOC 3: FACTURA 103, BIROUL VAMAL, TVA la furnizor (nu DVI) -----
goDlg = CREATEOBJECT('import_adauga_factura', goObjA)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = 103
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 900
goDlg.cPartener = 'BIROUL VAMAL'
goDlg.cExplicatia = 'Factura BIROUL VAMAL'
goDlg.nSuma = 500
goDlg.nSumaLei = 0
goDlg.nCurs = 0
goDlg.nIdExplicatieTva = 208
goDlg.cExplicatieTva = 'ACH. INT. 21%'
goDlg.optTipTva.Value = 1 && F = furnizor
goDlg.chkInValutaCont.Value = 0
goDlg.chkParticipaValuta.Value = 1
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO R7Log WITH 'A-DOC3: valideaza = ' + TRANSFORM(goDlg.valideaza())
DO ConstruiesteToDlg
DO R7Log WITH 'A-DOC3: do_adauga_factura = ' + TRANSFORM(goObjA.do_adauga_factura(goT))
goDlg.Hide()
DOEVENTS FORCE
DO R7Log WITH 'A: dump introdc dupa cele 3 documente:'
DO DumpIntrodc
DO HarnessStep WITH 0, 'A: dupa 3 documente, introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri'
*----- Adaugare articole prin fluxul REAL do_adauga_articol -----
gcMockArtCodmat = 'ART-BULD-212'
TRY
goObjA.do_adauga_articol()
CATCH TO loExcAddA1
DO R7Log WITH 'EROARE do_adauga_articol (BULDOEXCAVATOR) ' + TRANSFORM(loExcAddA1.ErrorNo) + ' [' + loExcAddA1.Message + ']'
ENDTRY
DOEVENTS FORCE
SELECT rul_temp
LOCATE FOR ALLTRIM(codmat) == 'ART-BULD-212'
IF FOUND()
REPLACE cant WITH 1, pret_val WITH 5000, pretd WITH 5000, pret WITH ROUND(5000*5.23,4), pret_lei WITH ROUND(5000*5.23,4)
DO R7Log WITH 'A: BULDOEXCAVATOR (212) adaugat prin do_adauga_articol REAL, cant/pret completate'
ELSE
DO R7Log WITH 'FAIL A: BULDOEXCAVATOR nu a fost adaugat de do_adauga_articol()'
ENDIF
gcMockArtCodmat = 'ART-GREE-303'
TRY
goObjA.do_adauga_articol()
CATCH TO loExcAddA2
DO R7Log WITH 'EROARE do_adauga_articol (AC GREE BORA) ' + TRANSFORM(loExcAddA2.ErrorNo) + ' [' + loExcAddA2.Message + ']'
ENDTRY
DOEVENTS FORCE
SELECT rul_temp
LOCATE FOR ALLTRIM(codmat) == 'ART-GREE-303'
IF FOUND()
REPLACE cant WITH 1, pret_val WITH 100, pretd WITH 100, pret WITH ROUND(100*5.23,4), pret_lei WITH ROUND(100*5.23,4)
DO R7Log WITH 'A: AC GREE BORA (303) adaugat prin do_adauga_articol REAL, cant/pret completate'
ELSE
DO R7Log WITH 'FAIL A: AC GREE BORA nu a fost adaugat de do_adauga_articol()'
ENDIF
goObjA.gridart.Refresh()
DOEVENTS FORCE
*----- sincronizeaza() -----
LOCAL llEroareSyncA
llEroareSyncA = .F.
TRY
goObjA.sincronizeaza()
CATCH TO loExcSyncA
llEroareSyncA = .T.
DO R7Log WITH 'EROARE la sincronizeaza() (A) ' + TRANSFORM(loExcSyncA.ErrorNo) + ' [' + loExcSyncA.Message + ;
'] in ' + loExcSyncA.Procedure + ':' + TRANSFORM(loExcSyncA.LineNo) + ' (' + loExcSyncA.LineContents + ')'
ENDTRY
DOEVENTS FORCE
goObjA.grid1.Refresh()
DOEVENTS FORCE
IF !llEroareSyncA
DO R7Log WITH 'PASS A-sync: sincronizeaza() a rulat fara eroare'
ELSE
DO R7Log WITH 'FAIL A-sync: sincronizeaza() a aruncat eroare'
ENDIF
DO R7Log WITH 'A: dump introdc dupa sincronizeaza:'
DO DumpIntrodc
*----- VERIFICARI randul D (numai lei, explicatia, scd/scc, formula) -----
DO VerificaRandD WITH goObjA, '603', '303', 'A'
*----- VERIFICARE: nicio explicatie nu contine '(rot.)' -----
DO VerificaFaraRotund WITH 'A'
*----- VERIFICARE pozitie: pe rand T (DVI), sincronizeaza() pastreaza pozitia -----
DO VerificaPozitieT WITH goObjA, 101, 'A'
*----- VERIFICARE pozitie: pe randul D, sincronizeaza() ramane pe D -----
DO VerificaPozitieD WITH goObjA, 'A'
*----- VERIFICARE guard Valid (Grid1.cSuma.Text1): Value == nsumavechi -> fara efect -----
DO VerificaGuardValid WITH goObjA, 'A'
DO HarnessStep WITH 1, 'A: dupa verificari (rand D, pozitie, guard); introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri'
goObjA.Hide()
goObjA.Release()
DOEVENTS FORCE
*===================================================================================
*==================== SCENARIUL B: doar imobilizari (212) -> scd '6588' ==========
*===================================================================================
DO R7Log WITH '========== SCENARIUL B: FACTURA 100 + DVI 101, UNIC articol 212 =========='
IF USED('introdc')
USE IN ('introdc')
ENDIF
DO CreeazaIntrodc WITH 'introdc'
IF USED('rul_temp')
USE IN ('rul_temp')
ENDIF
DO CreeazaRulTemp
INSERT INTO rul_temp (denumire, codmat, cant, pret, pret_lei, cont, cota_tva) ;
VALUES ('PLACEHOLDER', 'PH', 1, 1, 1, '371', 21)
SELECT introdc
INDEX ON Str(Nvl(nr_doc,0),8) + Icase(tip_rand='B','1', tip_rand='S','2', tip_rand='T','3', tip_rand='D','4', '5') + Padr(Nvl(scd,''),10) TAG ord_doc
SET ORDER TO ord_doc
PUBLIC goObjB
goObjB = CREATEOBJECT('IMPORT_nota', .F.)
IF VARTYPE(goObjB) <> 'O'
DO R7Log WITH 'FAIL: instantiere import_nota (Scenariul B)'
DO HarnessDone WITH 'done-error'
QUIT
ENDIF
goObjB.lDialogAratat = .T.
goObjB.oact = poAct
goObjB.WindowType = 0
goObjB.Visible = .T.
goObjB.Show()
goObjB.WindowState = 2
DOEVENTS FORCE
SELECT rul_temp
ZAP
goObjB.gridart.Refresh()
DOEVENTS FORCE
*----- DOC 1: FACTURA 100, RAJA, DVI valuta (EUR curs 5.23) -----
goDlg = CREATEOBJECT('import_adauga_factura', goObjB)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = 100
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 601
goDlg.cPartener = 'RAJA'
goDlg.cExplicatia = 'Import marfa RAJA'
goDlg.nSuma = 1000
goDlg.nSumaLei = 0
goDlg.nCurs = 5.23
goDlg.nIdValuta = 978
goDlg.cValuta = 'EUR'
goDlg.nIdExplicatieTva = 220
goDlg.cExplicatieTva = 'ACH. IMP. 21%'
goDlg.optTipTva.Value = 2 && D = DVI
goDlg.chkInValutaCont.Value = 1
goDlg.chkParticipaValuta.Value = 1
goDlg.cSerieDvi = ''
goDlg.nNractDvi = 101
goDlg.dDviData = DATE()
goDlg.nIdFdocDVI = 2
goDlg.cFelDocDvi = 'DVI'
goDlg.nDviIdPartener = 900
goDlg.cDviPartener = 'BIROUL VAMAL'
goDlg.nDviTvaLei = 1098.30
goDlg.nDviTvaVal = 210.00
goDlg.actualizeaza_stare_dvi()
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO R7Log WITH 'B-DOC1: valideaza = ' + TRANSFORM(goDlg.valideaza())
DO ConstruiesteToDlg
DO R7Log WITH 'B-DOC1: do_adauga_factura = ' + TRANSFORM(goObjB.do_adauga_factura(goT))
goDlg.Hide()
DOEVENTS FORCE
DO R7Log WITH 'B: dump introdc dupa documentul 1:'
DO DumpIntrodc
DO HarnessStep WITH 2, 'B: dupa FACTURA 100 + DVI 101, introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri'
*----- Adaugare articol UNIC (BULDOEXCAVATOR cont 212) prin fluxul REAL -----
gcMockArtCodmat = 'ART-BULD-212'
TRY
goObjB.do_adauga_articol()
CATCH TO loExcAddB
DO R7Log WITH 'EROARE do_adauga_articol (B) ' + TRANSFORM(loExcAddB.ErrorNo) + ' [' + loExcAddB.Message + ']'
ENDTRY
DOEVENTS FORCE
SELECT rul_temp
LOCATE FOR ALLTRIM(codmat) == 'ART-BULD-212'
IF FOUND()
REPLACE cant WITH 1, pret_val WITH 5000, pretd WITH 5000, pret WITH ROUND(5000*5.23,4), pret_lei WITH ROUND(5000*5.23,4)
DO R7Log WITH 'B: BULDOEXCAVATOR (212) adaugat prin do_adauga_articol REAL, cant/pret completate'
ELSE
DO R7Log WITH 'FAIL B: BULDOEXCAVATOR nu a fost adaugat de do_adauga_articol()'
ENDIF
goObjB.gridart.Refresh()
DOEVENTS FORCE
LOCAL llEroareSyncB
llEroareSyncB = .F.
TRY
goObjB.sincronizeaza()
CATCH TO loExcSyncB
llEroareSyncB = .T.
DO R7Log WITH 'EROARE la sincronizeaza() (B) ' + TRANSFORM(loExcSyncB.ErrorNo) + ' [' + loExcSyncB.Message + ']'
ENDTRY
DOEVENTS FORCE
goObjB.grid1.Refresh()
DOEVENTS FORCE
IF !llEroareSyncB
DO R7Log WITH 'PASS B-sync: sincronizeaza() a rulat fara eroare'
ELSE
DO R7Log WITH 'FAIL B-sync: sincronizeaza() a aruncat eroare'
ENDIF
DO R7Log WITH 'B: dump introdc dupa sincronizeaza:'
DO DumpIntrodc
*----- VERIFICARI randul D (fara clasa 3 -> 6588, doar lei) -----
DO VerificaRandD WITH goObjB, '6588', '212', 'B'
DO VerificaFaraRotund WITH 'B'
DO HarnessStep WITH 3, 'B: final, introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri, eroare_sync=' + TRANSFORM(llEroareSyncB)
DO HarnessDone WITH 'done'
CATCH TO loExc
DO R7Log WITH 'CATCH ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']'
DO HarnessDone WITH 'done-error'
ENDTRY
QUIT
*==================================================================================
PROCEDURE ConstruiesteToDlg
*-- toDlg construit INLINE in programul PRINCIPAL (vezi docs/testare-ui-vfp.md capcana l).
goT = CREATEOBJECT('Empty')
=ADDPROPERTY(goT,'serie_act',ALLTRIM(NVL(goDlg.cSerieAct,'')))
=ADDPROPERTY(goT,'nract',goDlg.nNract)
=ADDPROPERTY(goT,'dataact',goDlg.dDataAct)
=ADDPROPERTY(goT,'fdoc',goDlg.cFelDoc)
=ADDPROPERTY(goT,'id_fdoc',goDlg.nIdFdoc)
=ADDPROPERTY(goT,'id_partc',goDlg.nIdPartener)
=ADDPROPERTY(goT,'partc',goDlg.cPartener)
=ADDPROPERTY(goT,'explicatia',ALLTRIM(NVL(goDlg.cExplicatia,'')))
=ADDPROPERTY(goT,'suma',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,IIF(goDlg.nSumaLei<>0,goDlg.nSumaLei,ROUND(goDlg.nSuma*goDlg.nCurs,gnPC)),goDlg.nSuma))
=ADDPROPERTY(goT,'suma_val',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,goDlg.nSuma,0))
=ADDPROPERTY(goT,'in_valuta',goDlg.chkInValutaCont.Value)
=ADDPROPERTY(goT,'participa_valuta',(goDlg.chkParticipaValuta.Value=1))
=ADDPROPERTY(goT,'id_valuta',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nIdValuta,0))
=ADDPROPERTY(goT,'curs',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nCurs,0))
=ADDPROPERTY(goT,'nume_val',IIF(goDlg.chkInValutaCont.Value=1,ALLTRIM(NVL(goDlg.cValuta,'')),''))
=ADDPROPERTY(goT,'cTipTva',IIF(goDlg.optTipTva.Value=1,'F',IIF(goDlg.optTipTva.Value=2,'D','N')))
=ADDPROPERTY(goT,'id_jtva_coloana',goDlg.nIdExplicatieTva)
=ADDPROPERTY(goT,'dvi_serie',CHRTRAN(ALLTRIM(NVL(goDlg.cSerieDvi,'')),CHR(34),''))
=ADDPROPERTY(goT,'dvi_nract',goDlg.nNractDvi)
=ADDPROPERTY(goT,'dvi_dataact',goDlg.dDviData)
=ADDPROPERTY(goT,'dvi_id_fdoc',goDlg.nIdFdocDVI)
=ADDPROPERTY(goT,'dvi_fdoc',goDlg.cFelDocDvi)
=ADDPROPERTY(goT,'dvi_id_partc',goDlg.nDviIdPartener)
=ADDPROPERTY(goT,'dvi_partc',goDlg.cDviPartener)
=ADDPROPERTY(goT,'dvi_scc','401')
=ADDPROPERTY(goT,'dvi_tva_lei',goDlg.nDviTvaLei)
=ADDPROPERTY(goT,'dvi_tva_val',goDlg.nDviTvaVal)
ENDPROC
PROCEDURE CreeazaRulTemp
*-- structura reala rul_temp (vezi test_adauga_repere_212.prg / ointroduceri.vc2:11030).
IF USED('rul_temp')
USE IN ('rul_temp')
ENDIF
CREATE CURSOR rul_temp ( ;
id_rul N(20,0), an N(4,0), luna N(2,0), cod N(20,0);
, serie C(100), nnir N(20,0), id_articol N(10,0), denumire C(100);
, codmat C(50), codmatf C(50), codbare C(50), um C(20);
, id_gestiune N(5,0), nume_gestiune C(50), cgest C(20), nr_pag N(2,0);
, gestionar C(50), comisie_receptie1 C(50), comisie_receptie2 C(50), comisie_receptie3 C(50);
, cant N(14,3), cante N(14,3), cont C(10), acont C(20);
, pret N(18,4), tva N(18,4), valoare N(18,4), valtva N(18,4);
, proc_tva N(5,2), pretv N(18,4), pretvtva N(18,4), tvav N(18,4);
, valoarev N(18,4), valtvav N(18,4), proc_tvav N(5,2), adaos N(18,4);
, adaos_tva N(18,4), valoare_adaos N(18,4), valtva_adaos N(18,4), procent N(10,3);
, discunitar N(18,4), discount_tva N(18,4), valoare_discount N(18,4), valtva_discount N(18,4);
, proc_disc N(7,3), pretd N(14,4), curs N(18,4), id_valuta N(10,0);
, nume_val C(20), id_lucrare N(20,0), nrord C(100), id_responsabil N(10,0);
, nresp C(100), resp_marca N(18,4), dataact T, id_util N(5,0);
, util C(30), dataora T, id_sectie N(5,0), sectie C(50);
, csectie C(10), alcooltutun N(1,0), datain T, dataout T;
, id_fact N(20,0), id_gestiunec N(10,0), nume_gestiunec C(50), cgestc C(20);
, id_responsabilc N(5,0), id_reteta N(10,0), reteta C(50), nrespc C(100);
, respc_marca N(18,4), id_set N(20,0), id_tip_rulaj N(10,0), tip_rulaj C(50);
, id_obiect_depozit N(10,0), id_rul_aux N(10,0), nract N(20,0), serie_act C(10);
, dataoras T, id_utils N(10,0), lot C(30), adata_expirare T;
, id_sucursala N(5,0), sucursala C(250), id_part_rez N(10,0), part_rez C(100);
, id_lucrare_rez N(10,0), nrord_rez C(100), subgrupa C(100), grupa C(100);
, id_subgrupa N(5,0), id_grupa N(5,0), in_stoc N(1,0), in_crm N(1,0);
, id_furnizor N(10,0), furnizor C(100), id_jtva_coloana N(4,0), explicatie_tva C(100);
, taxcode N(6,0), taxname C(254), saft_procent N(18,4), codnc8 C(20);
, id_tara_origine N(4,0), cod_tara_origine C(5), tara_origine C(50), greutate N(12,4);
, fdoc C(30), id_fdoc N(18,4);
, pret_lei N(18,4), pret_val N(14,4), cota_tva N(6,2))
ENDPROC
PROCEDURE CreeazaIntrodc
LPARAMETERS tcAlias
IF USED(tcAlias)
USE IN (tcAlias)
ENDIF
CREATE CURSOR (tcAlias) ( ;
id_note N(14), explicatia C(100), scd C(10), ascd C(20), scc C(10), ascc C(20), ;
cu_tva N(1), id_set N(14), ordine N(8), in_valuta N(1), id_jtva_coloana N(14) NULL, ;
ptva N(6,2), explicatie_tva C(50), tipjurnal C(2), taxcode N(6), paymentcode C(9), ;
suma N(18,4), suma_val N(18,4), id_partd N(14), id_partc N(14), partd C(100), partc C(100), ;
id_fact N(14), id_factd N(14), id_factc N(14), pereched N(14), perechec N(14), ;
nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), ;
scd_orig C(20), ascd_orig C(20))
ENDPROC
PROCEDURE VerificaRandD
*-- randul D (runda7): doar lei (suma_val=0, in_valuta=0, participa_valuta=.F., nume_val='',
*-- id_valuta=0, curs=0, ndif_val formular=0), explicatia=='DIFERENTA', scd/scc asteptate,
*-- suma == nbaza_lei - Sum(Round(pret*cant,gnPc)) din rul_temp (formula recalc_diferente).
LPARAMETERS toObj, tcScdAsteptat, tcSccAsteptat, tcLabel
LOCAL lnSel, lcMsg, llD, lnSumaArticole, lnSumaAsteptata, llOkCampuriLei
lnSel = SELECT()
SELECT SUM(ROUND(pret*cant,gnPc)) AS s FROM rul_temp WHERE !DELETED() INTO CURSOR crsSumaArtR7 NOFILTER
lnSumaArticole = NVL(crsSumaArtR7.s, 0)
USE IN crsSumaArtR7
lnSumaAsteptata = ROUND(toObj.nbaza_lei - lnSumaArticole, gnPc)
SELECT introdc
LOCATE FOR tip_rand == 'D'
llD = FOUND()
IF llD
llOkCampuriLei = (suma_val = 0) AND (in_valuta = 0) AND (!participa_valuta) AND ;
EMPTY(ALLTRIM(NVL(nume_val,''))) AND (id_valuta = 0) AND (curs = 0) AND ;
ALLTRIM(explicatia) == 'DIFERENTA' AND (toObj.ndif_val = 0) AND ;
ALLTRIM(scd) == tcScdAsteptat AND ALLTRIM(scc) == tcSccAsteptat AND ;
ABS(suma - lnSumaAsteptata) < 0.01
IF llOkCampuriLei
lcMsg = 'PASS ' + tcLabel + '-randD: explicatia=DIFERENTA suma=' + TRANSFORM(suma) + ;
' (asteptat ' + TRANSFORM(lnSumaAsteptata) + ') scd=' + ALLTRIM(scd) + ' scc=' + ALLTRIM(scc) + ;
' suma_val=0 in_valuta=0 participa_valuta=.F. nume_val=[] id_valuta=0 curs=0 ndif_val=0 - TOATE OK'
ELSE
lcMsg = 'FAIL ' + tcLabel + '-randD: suma=' + TRANSFORM(suma) + '(astept ' + TRANSFORM(lnSumaAsteptata) + ') ' + ;
'scd=[' + ALLTRIM(scd) + '](astept [' + tcScdAsteptat + ']) scc=[' + ALLTRIM(scc) + '](astept [' + tcSccAsteptat + ']) ' + ;
'explicatia=[' + ALLTRIM(explicatia) + '] suma_val=' + TRANSFORM(suma_val) + ' in_valuta=' + TRANSFORM(in_valuta) + ;
' participa_valuta=' + TRANSFORM(participa_valuta) + ' nume_val=[' + ALLTRIM(NVL(nume_val,'')) + '] id_valuta=' + TRANSFORM(id_valuta) + ;
' curs=' + TRANSFORM(curs) + ' ndif_val(formular)=' + TRANSFORM(toObj.ndif_val)
ENDIF
ELSE
lcMsg = 'FAIL ' + tcLabel + '-randD: nu exista rand tip_rand=D in introdc dupa sincronizeaza() (diferenta asteptata=' + TRANSFORM(lnSumaAsteptata) + ')'
ENDIF
DO R7Log WITH lcMsg
SELECT (lnSel)
ENDPROC
PROCEDURE VerificaFaraRotund
LPARAMETERS tcLabel
LOCAL lnSel, lcMsg, lnGasite
lnSel = SELECT()
SELECT introdc
lnGasite = 0
SCAN FOR '(rot.)' $ NVL(explicatia,'')
lnGasite = lnGasite + 1
ENDSCAN
IF lnGasite = 0
lcMsg = 'PASS ' + tcLabel + '-fara_rotund: nicio explicatie din introdc nu contine "(rot.)"'
ELSE
lcMsg = 'FAIL ' + tcLabel + '-fara_rotund: ' + TRANSFORM(lnGasite) + ' randuri cu "(rot.)" in explicatia (asteptat 0)'
ENDIF
DO R7Log WITH lcMsg
SELECT (lnSel)
ENDPROC
PROCEDURE VerificaPozitieT
*-- pozitioneaza pe randul T al doc-ului vamal (nract=tnNractVama), apeleaza sincronizeaza(),
*-- verifica ca ramane pe ACELASI rand (doc_key+tip_rand+scd identice) - D-C1.
LPARAMETERS toObj, tnNractVama, tcLabel
LOCAL lnSel, lcMsg, lcDocKeyDinainte, lcScdDinainte, llGasitInainte, llEroare
lnSel = SELECT()
SELECT introdc
LOCATE FOR nract = tnNractVama AND tip_rand == 'T'
llGasitInainte = FOUND()
IF !llGasitInainte
DO R7Log WITH 'FAIL ' + tcLabel + '-pozitieT: nu am gasit randul T pentru nract=' + TRANSFORM(tnNractVama) + ' (setup)'
SELECT (lnSel)
RETURN
ENDIF
lcDocKeyDinainte = doc_key
lcScdDinainte = scd
llEroare = .F.
TRY
toObj.sincronizeaza()
CATCH TO loExcPozT
llEroare = .T.
DO R7Log WITH 'EROARE la sincronizeaza() in VerificaPozitieT ' + TRANSFORM(loExcPozT.ErrorNo) + ' [' + loExcPozT.Message + ']'
ENDTRY
DOEVENTS FORCE
SELECT introdc
IF !llEroare AND doc_key == lcDocKeyDinainte AND tip_rand == 'T' AND scd == lcScdDinainte
lcMsg = 'PASS ' + tcLabel + '-pozitieT: dupa sincronizeaza(), recordul curent a ramas pe randul T (nract=' + TRANSFORM(tnNractVama) + ', scd=' + ALLTRIM(scd) + ')'
ELSE
lcMsg = 'FAIL ' + tcLabel + '-pozitieT: dupa sincronizeaza(), tip_rand=[' + tip_rand + '] doc_key=[' + ALLTRIM(doc_key) + '] scd=[' + ALLTRIM(scd) + ;
'] (astept tip_rand=T, doc_key=[' + ALLTRIM(lcDocKeyDinainte) + '], scd=[' + ALLTRIM(lcScdDinainte) + '])'
ENDIF
DO R7Log WITH lcMsg
SELECT (lnSel)
ENDPROC
PROCEDURE VerificaPozitieD
*-- pozitioneaza pe randul D, apeleaza sincronizeaza(), verifica ca ramane pe tip_rand='D' (D-C1).
LPARAMETERS toObj, tcLabel
LOCAL lnSel, lcMsg, llGasitInainte, llEroare
lnSel = SELECT()
SELECT introdc
LOCATE FOR tip_rand == 'D'
llGasitInainte = FOUND()
IF !llGasitInainte
DO R7Log WITH 'FAIL ' + tcLabel + '-pozitieD: nu exista rand D (setup)'
SELECT (lnSel)
RETURN
ENDIF
llEroare = .F.
TRY
toObj.sincronizeaza()
CATCH TO loExcPozD
llEroare = .T.
DO R7Log WITH 'EROARE la sincronizeaza() in VerificaPozitieD ' + TRANSFORM(loExcPozD.ErrorNo) + ' [' + loExcPozD.Message + ']'
ENDTRY
DOEVENTS FORCE
SELECT introdc
IF !llEroare AND tip_rand == 'D'
lcMsg = 'PASS ' + tcLabel + '-pozitieD: dupa sincronizeaza(), recordul curent a ramas pe randul D'
ELSE
lcMsg = 'FAIL ' + tcLabel + '-pozitieD: dupa sincronizeaza(), tip_rand=[' + tip_rand + '] (astept D)'
ENDIF
DO R7Log WITH lcMsg
SELECT (lnSel)
ENDPROC
PROCEDURE VerificaGuardValid
*-- guard "doar la modificare" (runda7, dec.4): setez Thisform.nsumavechi = suma curenta
*-- (simuleaza GotFocus), apoi apelez direct Valid-ul lui Grid1.cSuma.Text1 cu aceeasi valoare -
*-- Valid trebuie sa iasa imediat (fara Replace mod_manual, fara armare lSyncPending/tmrSync).
LPARAMETERS toObj, tcLabel
LOCAL lnSel, lcMsg, lnSumaCrt, llModManualInainte, llSyncPendingInainte, llApelDirectOk, llEroareApel
lnSel = SELECT()
SELECT introdc
LOCATE FOR tip_rand == 'B'
IF !FOUND()
DO R7Log WITH 'INFO ' + tcLabel + '-guardValid: nu exista rand B pentru test (sarit)'
SELECT (lnSel)
RETURN
ENDIF
lnSumaCrt = suma
llModManualInainte = (mod_manual = 1)
toObj.nsumavechi = lnSumaCrt
toObj.lSyncPending = .F.
llSyncPendingInainte = toObj.lSyncPending
llApelDirectOk = .F.
llEroareApel = .F.
TRY
IF PEMSTATUS(toObj.Grid1.cSuma.Text1, 'Valid', 5)
toObj.Grid1.cSuma.Text1.Value = lnSumaCrt
toObj.Grid1.cSuma.Text1.Valid()
llApelDirectOk = .T.
ENDIF
CATCH TO loExcGuard
llEroareApel = .T.
DO R7Log WITH 'INFO ' + tcLabel + '-guardValid: apel direct Grid1.cSuma.Text1.Valid() a esuat (' + ;
TRANSFORM(loExcGuard.ErrorNo) + ' ' + loExcGuard.Message + ') - test indirect mai jos'
ENDTRY
SELECT introdc
LOCATE FOR tip_rand == 'B'
IF llApelDirectOk AND !llEroareApel
IF (mod_manual = 1) == llModManualInainte AND toObj.lSyncPending == llSyncPendingInainte
lcMsg = 'PASS ' + tcLabel + '-guardValid: Value==nsumavechi -> Valid a iesit fara efect (mod_manual neschimbat, lSyncPending=' + TRANSFORM(toObj.lSyncPending) + ')'
ELSE
lcMsg = 'FAIL ' + tcLabel + '-guardValid: Valid a avut efect desi Value==nsumavechi (mod_manual dupa=' + TRANSFORM(mod_manual) + ' lSyncPending dupa=' + TRANSFORM(toObj.lSyncPending) + ')'
ENDIF
ELSE
*-- fallback indirect: dupa sincronizarea completa deja facuta, lSyncPending trebuie sa fie
*-- .F. in stare de repaus; setam nsumavechi=suma curenta si verificam ca nu s-a schimbat nimic.
IF toObj.lSyncPending == .F.
lcMsg = 'PASS ' + tcLabel + '-guardValid (indirect): apel direct pe Grid1.cSuma.Text1.Valid() nedisponibil in headless - lSyncPending ramane .F. in repaus (guard documentat in cod, vezi diff_runda7)'
ELSE
lcMsg = 'FAIL ' + tcLabel + '-guardValid (indirect): lSyncPending=' + TRANSFORM(toObj.lSyncPending) + ' (astept .F. in repaus)'
ENDIF
ENDIF
DO R7Log WITH lcMsg
SELECT (lnSel)
ENDPROC
PROCEDURE DumpIntrodc
LOCAL lnSel
lnSel = SELECT()
SELECT introdc
SCAN
DO R7Log WITH ' recno=' + TRANSFORM(RECNO()) + ' nract=' + TRANSFORM(nract) + ' tip_rand=' + tip_rand + ;
' scd=' + ALLTRIM(scd) + ' scc=' + ALLTRIM(scc) + ' suma=' + TRANSFORM(suma) + ' suma_val=' + TRANSFORM(suma_val) + ;
' explicatia=[' + ALLTRIM(NVL(explicatia,'')) + '] partc=[' + ALLTRIM(NVL(partc,'')) + '] doc_key=[' + ALLTRIM(doc_key) + ']'
ENDSCAN
SELECT (lnSel)
ENDPROC
FUNCTION RECCOUNT_ACTIVE
LPARAMETERS tcAlias
LOCAL lnSel, lnCnt
lnSel = SELECT()
SELECT (tcAlias)
COUNT TO lnCnt FOR !DELETED()
SELECT (lnSel)
RETURN lnCnt
ENDFUNC
PROCEDURE R7Err
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
DO R7Log WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
ENDPROC
PROCEDURE R7Log
LPARAMETERS tcMsg
SET SAFETY OFF
LOCAL lcL
lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '')
STRTOFILE(lcL + tcMsg + CHR(13)+CHR(10), gcUILog)
ENDPROC
DEFINE CLASS dummyapp AS Custom
PROCEDURE ReadIni
LPARAMETERS tcSection, tcKey
RETURN ''
ENDPROC
PROCEDURE WriteIni
LPARAMETERS tcSection, tcKey, tcValue
RETURN .T.
ENDPROC
ENDDEFINE
DEFINE CLASS dummyexecutor AS Custom
cEroare = ''
PROCEDURE oExecute
LPARAMETERS tcSql, tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF 'VJTVA_COLOANE' $ UPPER(m.tcSql)
DO CreeazaJtvaColoaneView WITH m.tcCursor
RETURN 1
ENDIF
IF UPPER(ALLTRIM(m.tcCursor)) == 'RUL_TEMP'
DO CreeazaRulTemp
ELSE
CREATE CURSOR (m.tcCursor) (id_temp N(1))
ENDIF
RETURN 1
ENDPROC
PROCEDURE oExecuta
LPARAMETERS tcSql, tcCursor
IF !EMPTY(m.tcCursor)
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF UPPER(m.tcCursor) == 'CJTVACOL4427'
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14))
ELSE
CREATE CURSOR (m.tcCursor) (id_temp N(1))
ENDIF
ENDIF
RETURN .T.
ENDPROC
PROCEDURE oSelect2Value
LPARAMETERS tcSql, toValue
toValue = ''
RETURN 1
ENDPROC
PROCEDURE oReset
ENDPROC
ENDDEFINE
PROCEDURE CreeazaJtvaColoaneView
LPARAMETERS tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14), denumire C(100), jc N(1), jv N(1), ;
coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14) NULL, afisat N(1), ;
id_jtva_ex N(14) NULL, id_jtva_neex N(14) NULL, ordine N(8), ;
taxcode N(6) NULL, taxcode_neexigibil N(6) NULL, taxcode_n50 N(6) NULL, ;
taxcode_n50_tvai N(6) NULL, taxcode_n100 N(6) NULL, taxcode_regularizare N(6) NULL, taxcode_tvai N(6) NULL)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, afisat, ordine, cota_tva) VALUES (0, '', 0, 0, 1, 0, 0)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (208, 'ACH. INT. 21%', 1, 0, 'RO21B', 21, 209, 1, 1, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (209, 'TVA ACH. INT. 21%', 1, 0, 'RO21T', 21, 1, 2, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (220, 'ACH. IMP. 21%', 1, 0, 'FO21B', 21, 221, 1, 3, 301204)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (221, 'TVA ACH. IMP. 21%', 1, 0, 'FO21T', 21, 1, 4, 301204)
ENDPROC

View File

@@ -0,0 +1,10 @@
# test_runda7_diferente.ps1 - wrapper peste harness-ul generic pentru RUNDA 7 (diferenta doar in
# lei, cont fix 6588 fara clasa 3, fara sufix (rot.), guard-uri Valid, pozitie randul D).
# Rulare: powershell -ExecutionPolicy Bypass -File test_runda7_diferente.ps1
$ErrorActionPreference = 'Stop'
$Teste = $PSScriptRoot
& (Join-Path (Split-Path $Teste -Parent) 'vfp_ui_harness.ps1') `
-TestPrg (Join-Path $Teste 'test_runda7_diferente.prg') `
-Steps @('A_3documente','A_final','B_1document','B_final') `
-ShotsDir (Join-Path $Teste 'screenshots_runda7') `
-SyncDir (Join-Path $Teste 'uisync_runda7')

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,13 @@
# test_scenariu_dvi_complet.ps1 - wrapper peste harness-ul generic pentru scenariul complet
# Marius (rundele 8-11: analitice pe spargere, doc_key unic + DVI taxe vamale, stergere/copiere
# cu meniu, procente+totaluri banda). Rulare:
# powershell -ExecutionPolicy Bypass -File test_scenariu_dvi_complet.ps1
$ErrorActionPreference = 'Stop'
$Teste = $PSScriptRoot
& (Join-Path (Split-Path $Teste -Parent) 'vfp_ui_harness.ps1') `
-TestPrg (Join-Path $Teste 'test_scenariu_dvi_complet.prg') `
-Steps @('3documente','articole_adaugate','sync1','sync2_verificari','stergere_doc','stergere_linie','stergere_cancel','copiere_doc','final') `
-ShotsDir (Join-Path $Teste 'screenshots_dvi_complet') `
-SyncDir (Join-Path $Teste 'uisync_dvi_complet') `
-StepTimeoutSec 180 `
-ReadyTimeoutSec 180

View File

@@ -0,0 +1,779 @@
* test_scenariu_import_212.prg
* Reproduce scenariul manual al lui Marius: nota de import (lIntern=.F.) cu 3 documente
* (FACTURA 100 DVI valuta EUR, FACTURA 102 DVI lei, FACTURA 103 TVA la furnizor), apoi adaugarea
* unui articol BULDOEXCAVATOR cont 212 (imobilizari) in rul_temp - asta declanseaza sincronizeaza()
* -> actualizeaza_banda() cu cmesajsync lung (mai multe documente nesincronizate simultan).
* Verifica cele 2 fix-uri deja aplicate in COMUN\clase\ointroduceri.vcx (clasa import_nota):
* 1. do_adauga_factura, ramura DVI (cTipTva='D'): repozitionare pe Go lnRecT (recno salvat la
* crearea randului T), nu Locate degenerat.
* 2. actualizeaza_banda: This.lblSync.Caption = Left('NESINCRONIZAT: ' + ..., 254) - inainte
* crapa cu "String is too long to fit" cand cMesajSync acumuleaza mesaje de la mai multe
* documente (aici: valideaza_sume semnaleaza documentele 102/103 ale caror randuri S ies la
* 0, pentru ca articolul e pretuit doar in valuta iar docs 102/103 nu au valuta - vezi
* sparge_document, ramura ne-principala).
*
* Pasi (harness): 0 dupa cele 3 documente (6 randuri, 3 perechi B/T), 1 dupa adaugarea articolului
* + sincronizeaza() (banda NESINCRONIZAT vizibila), 2 final (dupa do_executa() din nou).
*
* Rulare:
* powershell -ExecutionPolicy Bypass -File test_scenariu_import_212.ps1
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET DECIMALS TO 4
SET NULLDISPLAY TO ''
CLOSE DATABASES
PUBLIC gcUILog, gcSyncDir
gcUILog = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\test_scenariu_import_212_log.txt"
gcSyncDir = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\uisync_212\"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcUILog)
ON ERROR DO SiErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
TRY
LOCAL gcAppPath, lcPath
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;' + ;
ADDBS(SUBSTR(gcAppPath,1,RAT([\],gcAppPath,2)))+[COMUNROA\]
SET PATH TO &lcPath ADDITIVE
DO SiLog WITH 'SET PATH OK'
*----- CLASE -----
SET CLASSLIB TO (gcAppPath + "comun\clase\appwiz") 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 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 wwdialogs.vcx ADDITIVE
SET CLASSLIB TO oimportxml.vcx ADDITIVE
SET CLASSLIB TO excelxml.vcx ADDITIVE
SET CLASSLIB TO orapoarte_obinv.vcx ADDITIVE
DO SiLog WITH 'SET CLASSLIB OK'
*----- PROCEDURI (mock amessagebox PRIMUL, ui_harness la final) -----
SET PROCEDURE TO PROCEDURI
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_amessagebox.prg" 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 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 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 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
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\ui_harness.prg" ADDITIVE
DO SiLog WITH 'SET PROCEDURE OK'
*----- Globale -----
PUBLIC gnPc, gnPval, gnPcant, gnPpret, gnPPretval, gnPCurs, gnPVal, gnPPretV, gnPPretVal
STORE 2 TO gnPc, gnPval, gnPVal
gnPcant = 3
STORE 4 TO gnPpret, gnPPretval, gnPPretVal, gnPPretV, gnPCurs
PUBLIC gl406, gcS, gnAn, gnLuna, gnIdFirma, gnIdSucursala, gcAcces, gcFirma
*-- SAFT (406) mereu activ in teste: exercita GetTaxCode/GetTaxCodeIdPart/taxcode pe randuri.
gl406 = .T.
gcS = 'CONTAFIN'
gnAn = YEAR(DATE())
gnLuna = MONTH(DATE())
gnIdFirma = 110
gnIdSucursala = 110
gcAcces = "1;2;3;4;5;6;7;8;"
gcFirma = gcS
PUBLIC nror(65000)
PUBLIC goExecutor, goApp
goExecutor = CREATEOBJECT('dummyexecutor')
goApp = CREATEOBJECT('dummyapp')
*----- poAct: antetul notei; dialogul mosteneste din el la Init -----
PUBLIC poAct
poAct = CREATEOBJECT('Custom')
poAct.AddProperty('nume_val', '')
poAct.AddProperty('curs', 1)
poAct.AddProperty('proc_tva', 1.21)
poAct.AddProperty('nnir', 0)
poAct.AddProperty('id_valuta', 0)
poAct.AddProperty('id_fdoc', 1)
poAct.AddProperty('fdoc', 'Factura')
poAct.AddProperty('id_partc', 500)
poAct.AddProperty('partc', 'FURNIZOR ANTET SRL')
poAct.AddProperty('serie_act', '')
poAct.AddProperty('dataact', DATE())
poAct.AddProperty('tva_incasare', 0)
poAct.AddProperty('id_set', 1)
poAct.AddProperty('id_gestin', 1)
*----- jtva_coloane2 (explicatii TVA): achizitii interne 21% + import (DVI) 21% - perechi
* reale (Oracle dev, vjtva_coloane, 17.07.2026), regimul curent 21%/11% post 01.08.2025. -----
IF USED('jtva_coloane2')
USE IN ('jtva_coloane2')
ENDIF
CREATE CURSOR jtva_coloane2 (ordine N(8), id_jtva_coloana N(14), denumire C(100), ;
jc N(1), jv N(1), afisat N(1), coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14))
INSERT INTO jtva_coloane2 VALUES (0, 0, '', 0, 0, 1, '', '', 0, 0)
INSERT INTO jtva_coloane2 VALUES (1, 208, 'ACH. INT. 21%', 1, 0, 1, 'RO21B', 'RO21T', 21, 209)
INSERT INTO jtva_coloane2 VALUES (2, 209, 'TVA ACH. INT. 21%', 1, 0, 1, 'RO21T', '', 21, 0)
INSERT INTO jtva_coloane2 VALUES (3, 220, 'ACH. IMP. 21%', 1, 0, 1, 'FO21B', 'FO21T', 21, 221)
INSERT INTO jtva_coloane2 VALUES (4, 221, 'TVA ACH. IMP. 21%', 1, 0, 1, 'FO21T', '', 21, 0)
*----- saft_taxtable: coduri reale (vsaft_taxtable) - achizitii interne 21% vs import 21% -----
IF USED('saft_taxtable')
USE IN ('saft_taxtable')
ENDIF
CREATE CURSOR saft_taxtable (taxname C(250) NULL, typename C(250) NULL, taxcode N(6) NULL, ;
taxtype N(3) NULL, descriere C(250) NULL, tip C(100) NULL, descriere_tip C(250) NULL, ;
procent_taxa N(7,2) NULL, procent_prorata N(7,2) NULL, inactiv N(1) NULL, tva N(1) NULL, ;
wht N(1) NULL, tva_achizitii N(1) NULL, tva_livrari N(1) NULL)
INDEX ON taxcode TAG taxcode
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('', 0, '', 0, 1, 1, 1, 1)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301104-Achizitii de bunuri si servicii taxabile cu cota de 21%, altele decat importurile si cele supuse masurilor de simplificare', 301104, '', 21, 1, 0, 1, 0)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301204-Import de bunuri cota 21%', 301204, '', 21, 1, 0, 1, 0)
*----- introdc (RecordSource Grid1) - porneste GOL, ca in fluxul real -----
DO CreeazaIntrodc WITH 'introdc'
*----- introdc_sablon: perechea-sablon (B 371/401 + T 4426/401) pe care do_adauga_factura o
* cloneaza; sablonul e la 21% (cota folosita in toate cele 3 scenarii de mai jos). -----
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%')
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%')
GO TOP IN introdc_sablon
*----- rul_temp cu 1 rand INAINTE de instantiere: altfel import_nota.Init il recreeaza din
* Oracle (rul_temp gol => llRulTempPlin=.F.) si GridArt isi pierde coloanele (eroare 1925).
* Randul se sterge dupa Show (ZAP, nu DELETE ALL - vezi docs/testare-ui-vfp.md capcana k). -----
IF USED('rul_temp')
USE IN ('rul_temp')
ENDIF
CREATE CURSOR rul_temp (denumire C(100), codmat C(30), cant N(14,3), pret_val N(18,4), ;
pretd N(18,4), pret N(18,4), pret_lei N(18,4), cont C(10), acont C(20), serie C(30), ;
lot C(30), adata_expirare C(10), proc_disc N(6,2), cota_tva N(6,2))
INSERT INTO rul_temp (denumire, codmat, cant, pret, pret_lei, cont, cota_tva) ;
VALUES ('PLACEHOLDER', 'PH', 1, 1, 1, '371', 21)
DO SiLog WITH 'cursoare pregatite, CREATEOBJECT(import_nota, .F.) - lIntern=.F. (import)'
SELECT introdc
PUBLIC goObj
*-- lIntern=.F. (import): sparge_document grupeaza articolele in valuta (pret_val*cant), ca
*-- in scenariul real al lui Marius. Activate() ar deschide automat dialogul modal "adauga
*-- factura" (This.do_adauga(), Show(1)) pentru !lIntern - blocheaza headless; il dezarmez
*-- cu lDialogAratat=.T. INAINTE de Show(), documentele se adauga manual mai jos.
goObj = CREATEOBJECT('IMPORT_nota', .F.)
IF VARTYPE(goObj) <> 'O'
DO SiLog WITH 'FAIL: instantiere import_nota'
DO HarnessDone WITH 'done-error'
QUIT
ENDIF
goObj.lDialogAratat = .T.
goObj.oact = poAct
goObj.WindowType = 0
goObj.Visible = .T.
goObj.Show()
goObj.WindowState = 2
DOEVENTS FORCE
*-- golesc placeholder-ul cu ZAP (nu DELETE ALL, vezi capcana k)
SELECT rul_temp
ZAP
goObj.gridart.Refresh()
DOEVENTS FORCE
*========================= DOC 1: FACTURA 100, RAJA, DVI valuta (EUR curs 5.23) =========================
PUBLIC goDlg, goT
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = 100
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 601
goDlg.cPartener = 'RAJA'
goDlg.cExplicatia = 'Import marfa RAJA'
goDlg.nSuma = 1000
goDlg.nSumaLei = 0
goDlg.nCurs = 5.23
goDlg.nIdValuta = 978
goDlg.cValuta = 'EUR'
*-- ACH. IMP. 21% (id 220) - coloana de import (SCD 371/SCC 401, taxcode SAFT 301204)
goDlg.nIdExplicatieTva = 220
goDlg.cExplicatieTva = 'ACH. IMP. 21%'
goDlg.optTipTva.Value = 2 && D = DVI
goDlg.chkInValutaCont.Value = 1
goDlg.chkParticipaValuta.Value = 1
*-- DVI: TVA achitat in vama (BIROUL VAMAL), doc 101, cont 4426/401
goDlg.cSerieDvi = ''
goDlg.nNractDvi = 101
goDlg.dDviData = DATE()
goDlg.nIdFdocDVI = 2
goDlg.cFelDocDvi = 'DVI'
goDlg.nDviIdPartener = 900
goDlg.cDviPartener = 'BIROUL VAMAL'
goDlg.nDviTvaLei = 1098.30
goDlg.nDviTvaVal = 210.00
goDlg.actualizeaza_stare_dvi()
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO SiLog WITH 'DOC1: valideaza (pe dialog) = ' + TRANSFORM(goDlg.valideaza())
DO ConstruiesteToDlg
DO SiLog WITH 'DOC1: do_adauga_factura = ' + TRANSFORM(goObj.do_adauga_factura(goT))
goDlg.Hide()
DOEVENTS FORCE
DO VerificaPereche WITH 100, 5230, 1000, 'EUR'
DO VerificaDvi WITH 100, 101, 5230, 1098.30
*========================= DOC 2: FACTURA 102, TRANS OIL MOTO, DVI lei (acelasi doc vamal 101) =========================
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = 102
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 602
goDlg.cPartener = 'TRANS OIL MOTO'
goDlg.cExplicatia = 'Achizitie TRANS OIL MOTO'
goDlg.nSuma = 1000
goDlg.nSumaLei = 0
goDlg.nCurs = 0
goDlg.nIdExplicatieTva = 220
goDlg.cExplicatieTva = 'ACH. IMP. 21%'
goDlg.optTipTva.Value = 2 && D = DVI
goDlg.chkInValutaCont.Value = 0
goDlg.chkParticipaValuta.Value = 1
*-- ACELASI document vamal (nr 101, BIROUL VAMAL) ca la doc 1 - randul T se re-cheie pe
*-- acelasi doc_key ca T-ul doc 1 (identitate = serie_act+nract+id_fdoc+id_partc, calc_doc_key).
goDlg.cSerieDvi = ''
goDlg.nNractDvi = 101
goDlg.dDviData = DATE()
goDlg.nIdFdocDVI = 2
goDlg.cFelDocDvi = 'DVI'
goDlg.nDviIdPartener = 900
goDlg.cDviPartener = 'BIROUL VAMAL'
goDlg.nDviTvaLei = 210.00
goDlg.nDviTvaVal = 0
goDlg.actualizeaza_stare_dvi()
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO SiLog WITH 'DOC2: valideaza (pe dialog) = ' + TRANSFORM(goDlg.valideaza())
DO ConstruiesteToDlg
DO SiLog WITH 'DOC2: do_adauga_factura = ' + TRANSFORM(goObj.do_adauga_factura(goT))
goDlg.Hide()
DOEVENTS FORCE
DO VerificaPereche WITH 102, 1000, 0, ''
*-- randul T al doc2 e re-cheiat pe ACELASI doc_key ca T-ul doc1 (nract=101/BIROUL VAMAL) -
*-- exista acum 2 randuri cu acel doc_key si tip_rand='T'; suma lor totala trebuie sa fie
*-- 1098.30 + 210 = 1308.30 (anti-corupere: randul T al doc1 nu a fost suprascris de doc2).
DO VerificaSumaGrupVama WITH 101, 1308.30, 2
*========================= DOC 3: FACTURA 103, BIROUL VAMAL, TVA la furnizor (nu DVI) =========================
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = 103
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 900
goDlg.cPartener = 'BIROUL VAMAL'
goDlg.cExplicatia = 'Factura BIROUL VAMAL'
goDlg.nSuma = 500
goDlg.nSumaLei = 0
goDlg.nCurs = 0
*-- ACH. INT. 21% (id 208) - achizitie normala (nu import), TVA la furnizor
goDlg.nIdExplicatieTva = 208
goDlg.cExplicatieTva = 'ACH. INT. 21%'
goDlg.optTipTva.Value = 1 && F = furnizor
goDlg.chkInValutaCont.Value = 0
goDlg.chkParticipaValuta.Value = 1
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO SiLog WITH 'DOC3: valideaza (pe dialog) = ' + TRANSFORM(goDlg.valideaza())
DO ConstruiesteToDlg
DO SiLog WITH 'DOC3: do_adauga_factura = ' + TRANSFORM(goObj.do_adauga_factura(goT))
goDlg.Hide()
DOEVENTS FORCE
*-- do_executa calculeaza automat T = 500*21% = 105 (ptva mostenit din sablon); TVA "la
*-- furnizor" inseamna doar ca nu exista DVI - suma nu ramane 0, do_executa o calculeaza.
DO VerificaPereche WITH 103, 500, 0, ''
DO SiLog WITH 'DIAG dump introdc dupa cele 3 documente (inainte de articol):'
DO DumpIntrodc
*========================= PAS 0: cele 3 documente, structura B/T intacta (rul_temp gol) =========================
DO HarnessStep WITH 0, 'dupa 3 documente: introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri (astept 6, 3 perechi B/T), rul_temp=' + TRANSFORM(RECCOUNT_ACTIVE('rul_temp')) + ' articole'
*========================= ADAUGARE ARTICOL: BULDOEXCAVATOR cont 212 (imobilizari) =========================
*-- pret_val=1000 EUR / pret=5230 lei (curs 5.23) - coerent cu baza doc1 (RAJA); doc2/doc3
*-- (fara valuta) raman insa nesincronizate dupa spargere (sparge_document, ramura ne-principala,
*-- foloseste baza in valuta a documentului - 0 pentru doc2/doc3 => randurile S ies la 0) -
*-- exact scenariul manual al lui Marius: adaugarea articolului declanseaza mesaje de la mai
*-- multe documente simultan in cmesajsync, ce trebuiau sa crape actualizeaza_banda inainte de fix.
SELECT rul_temp
INSERT INTO rul_temp (denumire, codmat, cant, pret_val, pretd, pret, pret_lei, cont, ;
acont, serie, lot, adata_expirare, proc_disc, cota_tva) ;
VALUES ('BULDOEXCAVATOR', 'ART-BULD-212', 1, 1000, 1000, 5230, 5230, '212', ;
'', '', '', '', 0, 21)
goObj.gridart.Refresh()
DOEVENTS FORCE
DO SiLog WITH 'articol BULDOEXCAVATOR (cont 212) adaugat in rul_temp, apelez sincronizeaza()'
LOCAL lcCaptionInainte, llEroareSync, lcMesajSyncInainte
llEroareSync = .F.
TRY
goObj.sincronizeaza()
CATCH TO loExcSync
llEroareSync = .T.
DO SiLog WITH 'EROARE la sincronizeaza() ' + TRANSFORM(loExcSync.ErrorNo) + ' [' + loExcSync.Message + ;
'] in ' + loExcSync.Procedure + ':' + TRANSFORM(loExcSync.LineNo) + ' (' + loExcSync.LineContents + ')'
ENDTRY
DOEVENTS FORCE
goObj.grid1.Refresh()
DOEVENTS FORCE
*-- VERIFICARE 1: nicio eroare "String is too long to fit" (sau orice alta) la sincronizeaza()/actualizeaza_banda
IF !llEroareSync
DO SiLog WITH 'PASS verificare1: sincronizeaza() a rulat fara eroare (String is too long to fit NU a aparut)'
ELSE
DO SiLog WITH 'FAIL verificare1: sincronizeaza() a aruncat eroare - vezi mesajul de mai sus'
ENDIF
*-- VERIFICARE 2: lblSync.Caption <= 254, incepe cu 'NESINCRONIZAT: ' (daca nesincronizat), cmesajsync INTREG
LOCAL lnLenCaption, lcCaption, lcMesajSync
lcCaption = goObj.lblSync.Caption
lcMesajSync = goObj.cmesajsync
lnLenCaption = LEN(lcCaption)
DO SiLog WITH 'cmesajsync (' + TRANSFORM(LEN(lcMesajSync)) + ' caractere) = [' + lcMesajSync + ']'
DO SiLog WITH 'lblSync.Caption (' + TRANSFORM(lnLenCaption) + ' caractere) = [' + lcCaption + ']'
IF !EMPTY(lcMesajSync)
IF lnLenCaption <= 254 AND LEFT(lcCaption, 15) == 'NESINCRONIZAT: '
DO SiLog WITH 'PASS verificare2: Caption trunchiat corect la ' + TRANSFORM(lnLenCaption) + ' caractere (<=254), prefix NESINCRONIZAT: OK'
ELSE
DO SiLog WITH 'FAIL verificare2: Caption lungime=' + TRANSFORM(lnLenCaption) + ' (astept <=254) prefix=[' + LEFT(lcCaption,15) + ']'
ENDIF
IF lnLenCaption < LEN('NESINCRONIZAT: ' + STRTRAN(STRTRAN(lcMesajSync, CHR(13),''), CHR(10),' | '))
DO SiLog WITH 'PASS verificare2b: Caption e mai scurt decat mesajul complet -> Left(...,254) a taiat vizual, dar This.cmesajsync ramane INTREG (' + TRANSFORM(LEN(lcMesajSync)) + ' caractere, netrunchiat)'
ELSE
DO SiLog WITH 'INFO verificare2b: mesajul complet a incaput sub 254 caractere (nu s-a taiat nimic) - Caption=[' + lcCaption + ']'
ENDIF
ELSE
DO SiLog WITH 'INFO verificare2: cmesajsync gol -> nota SINCRONIZATA (nu se testeaza trunchierea; posibil daca sparge_document nu a generat diferente)'
ENDIF
*========================= PAS 1: dupa adaugare articol + sincronizeaza() =========================
DO HarnessStep WITH 1, 'dupa articol+sincronizeaza: ' + IIF(EMPTY(lcMesajSync),'SINCRONIZAT','NESINCRONIZAT (' + TRANSFORM(LEN(lcMesajSync)) + ' car.)') + ' introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri'
*-- VERIFICARE 5: articolul e in rul_temp, fluxul a mers pana la capat
SELECT rul_temp
LOCATE FOR ALLTRIM(codmat) == 'ART-BULD-212'
IF FOUND() AND ALLTRIM(cont) == '212'
DO SiLog WITH 'PASS verificare5: BULDOEXCAVATOR (cont 212) prezent in rul_temp'
ELSE
DO SiLog WITH 'FAIL verificare5: BULDOEXCAVATOR nu a fost gasit in rul_temp sau cont gresit'
ENDIF
*========================= do_executa() din nou + totaluri finale =========================
LOCAL llEroareExec
llEroareExec = .F.
TRY
goObj.do_executa()
CATCH TO loExcExec
llEroareExec = .T.
DO SiLog WITH 'EROARE la do_executa() ' + TRANSFORM(loExcExec.ErrorNo) + ' [' + loExcExec.Message + ;
'] in ' + loExcExec.Procedure + ':' + TRANSFORM(loExcExec.LineNo)
ENDTRY
goObj.recalculeaza()
goObj.actualizeaza_banda()
DOEVENTS FORCE
DO SiLog WITH 'DIAG dump introdc FINAL (dupa sincronizeaza+do_executa):'
DO DumpIntrodc
DO SiLog WITH 'DIAG dump rul_temp FINAL:'
SELECT rul_temp
SCAN
DO SiLog WITH ' denumire=' + ALLTRIM(denumire) + ' cont=' + ALLTRIM(cont) + ' cant=' + TRANSFORM(cant) + ;
' pret=' + TRANSFORM(pret) + ' pret_val=' + TRANSFORM(pret_val) + ' cota_tva=' + TRANSFORM(cota_tva)
ENDSCAN
*-- VERIFICARE 4: totaluri (Text1/nbaza_lei/ntva_lei/nbaza_val/ntva_val) - raportez valorile
*-- obtinute, chiar daca difera de estimarea 6730/1308.30 (posibil, vezi nota din DumpIntrodc:
*-- sparge_document pe documente ne-principale zeroeste baza cand documentul nu are valuta si
*-- articolul e pretuit doar in valuta).
DO SiLog WITH 'TOTALURI FINALE: nbaza_lei=' + TRANSFORM(goObj.nbaza_lei) + ' ntva_lei=' + TRANSFORM(goObj.ntva_lei) + ;
' nbaza_val=' + TRANSFORM(goObj.nbaza_val) + ' ntva_val=' + TRANSFORM(goObj.ntva_val) + ;
' ndif_lei=' + TRANSFORM(goObj.ndif_lei) + ' ndif_val=' + TRANSFORM(goObj.ndif_val)
LOCAL lnSumaBazaDoc, lnSumaTvaDoc
SELECT SUM(IIF(tip_rand=='B' OR tip_rand=='S',suma,0)) AS s FROM introdc INTO CURSOR crsBazaTot NOFILTER
lnSumaBazaDoc = NVL(crsBazaTot.s,0)
USE IN crsBazaTot
SELECT SUM(IIF(tip_rand=='T',suma,0)) AS s FROM introdc INTO CURSOR crsTvaTot NOFILTER
lnSumaTvaDoc = NVL(crsTvaTot.s,0)
USE IN crsTvaTot
DO SiLog WITH 'TOTALURI PE RANDURI introdc: suma(B+S)=' + TRANSFORM(lnSumaBazaDoc) + ' (asteptare bruta B: 5230+1000+500=6730) suma(T)=' + TRANSFORM(lnSumaTvaDoc) + ' (asteptare bruta T: 1098.30+210+105=1413.30; estimarea initiala 1308.30 exclude TVA proprie a doc3 = 500*21%=105)'
DO SiLog WITH 'GATA - scenariu executat integral'
DO HarnessStep WITH 2, 'final: introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri, eroare_sync=' + TRANSFORM(llEroareSync) + ' eroare_exec=' + TRANSFORM(llEroareExec)
DO HarnessDone WITH 'done'
CATCH TO loExc
DO SiLog WITH 'CATCH ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']'
DO HarnessDone WITH 'done-error'
ENDTRY
QUIT
*==================================================================================
PROCEDURE ConstruiesteToDlg
*-- toDlg construit INLINE in programul PRINCIPAL (ADDPROPERTY da eroare 11 din proceduri in
*-- acest runtime headless - vezi docs/testare-ui-vfp.md capcana l); valorile respecta exact
*-- dialog.construieste_todlg.
goT = CREATEOBJECT('Empty')
=ADDPROPERTY(goT,'serie_act',ALLTRIM(NVL(goDlg.cSerieAct,'')))
=ADDPROPERTY(goT,'nract',goDlg.nNract)
=ADDPROPERTY(goT,'dataact',goDlg.dDataAct)
=ADDPROPERTY(goT,'fdoc',goDlg.cFelDoc)
=ADDPROPERTY(goT,'id_fdoc',goDlg.nIdFdoc)
=ADDPROPERTY(goT,'id_partc',goDlg.nIdPartener)
=ADDPROPERTY(goT,'partc',goDlg.cPartener)
=ADDPROPERTY(goT,'explicatia',ALLTRIM(NVL(goDlg.cExplicatia,'')))
=ADDPROPERTY(goT,'suma',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,IIF(goDlg.nSumaLei<>0,goDlg.nSumaLei,ROUND(goDlg.nSuma*goDlg.nCurs,gnPC)),goDlg.nSuma))
=ADDPROPERTY(goT,'suma_val',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,goDlg.nSuma,0))
=ADDPROPERTY(goT,'in_valuta',goDlg.chkInValutaCont.Value)
=ADDPROPERTY(goT,'participa_valuta',(goDlg.chkParticipaValuta.Value=1))
=ADDPROPERTY(goT,'id_valuta',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nIdValuta,0))
=ADDPROPERTY(goT,'curs',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nCurs,0))
=ADDPROPERTY(goT,'nume_val',IIF(goDlg.chkInValutaCont.Value=1,ALLTRIM(NVL(goDlg.cValuta,'')),''))
=ADDPROPERTY(goT,'cTipTva',IIF(goDlg.optTipTva.Value=1,'F',IIF(goDlg.optTipTva.Value=2,'D','N')))
=ADDPROPERTY(goT,'id_jtva_coloana',goDlg.nIdExplicatieTva)
=ADDPROPERTY(goT,'dvi_serie',CHRTRAN(ALLTRIM(NVL(goDlg.cSerieDvi,'')),CHR(34),''))
=ADDPROPERTY(goT,'dvi_nract',goDlg.nNractDvi)
=ADDPROPERTY(goT,'dvi_dataact',goDlg.dDviData)
=ADDPROPERTY(goT,'dvi_id_fdoc',goDlg.nIdFdocDVI)
=ADDPROPERTY(goT,'dvi_fdoc',goDlg.cFelDocDvi)
=ADDPROPERTY(goT,'dvi_id_partc',goDlg.nDviIdPartener)
=ADDPROPERTY(goT,'dvi_partc',goDlg.cDviPartener)
=ADDPROPERTY(goT,'dvi_scc','401')
=ADDPROPERTY(goT,'dvi_tva_lei',goDlg.nDviTvaLei)
=ADDPROPERTY(goT,'dvi_tva_val',goDlg.nDviTvaVal)
ENDPROC
PROCEDURE CreeazaIntrodc
LPARAMETERS tcAlias
IF USED(tcAlias)
USE IN (tcAlias)
ENDIF
CREATE CURSOR (tcAlias) ( ;
id_note N(14), explicatia C(100), scd C(10), ascd C(20), scc C(10), ascc C(20), ;
cu_tva N(1), id_set N(14), ordine N(8), in_valuta N(1), id_jtva_coloana N(14) NULL, ;
ptva N(6,2), explicatie_tva C(50), tipjurnal C(2), taxcode N(6), paymentcode C(9), ;
suma N(18,4), suma_val N(18,4), id_partd N(14), id_partc N(14), partd C(100), partc C(100), ;
id_fact N(14), id_factd N(14), id_factc N(14), pereched N(14), perechec N(14), ;
nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), ;
scd_orig C(20), ascd_orig C(20))
ENDPROC
PROCEDURE VerificaPereche
*-- verifica perechea B+T adaugata (dupa nract): sume lei/valuta, valuta pe baza
LPARAMETERS tnNract, tnBazaLei, tnBazaVal, tcVal
LOCAL lnSel, lcMsg, llB, llT, lnBS, lnBSV, lcNV
lnSel = SELECT()
SELECT introdc
LOCATE FOR nract = tnNract AND tip_rand == 'B'
llB = FOUND()
IF llB
lnBS = suma
lnBSV = suma_val
lcNV = ALLTRIM(NVL(nume_val,''))
ENDIF
LOCATE FOR nract = tnNract AND tip_rand == 'T'
llT = FOUND()
IF llB AND llT AND ABS(lnBS - tnBazaLei) < 0.01 AND ABS(lnBSV - tnBazaVal) < 0.01 AND ALLTRIM(NVL(lcNV,'')) == tcVal
lcMsg = 'PASS pereche nract=' + TRANSFORM(tnNract) + ': B(suma=' + TRANSFORM(lnBS) + ' val=' + TRANSFORM(lnBSV) + ' ' + lcNV + ') + randT gasit'
ELSE
lcMsg = 'FAIL pereche nract=' + TRANSFORM(tnNract) + ': B?=' + TRANSFORM(llB) + ' T?=' + TRANSFORM(llT) + ' bazaLei=' + TRANSFORM(IIF(llB,lnBS,-1)) + '(astept ' + TRANSFORM(tnBazaLei) + ') bazaVal=' + TRANSFORM(IIF(llB,lnBSV,-1)) + '(astept ' + TRANSFORM(tnBazaVal) + ') val=[' + IIF(llB,lcNV,'?') + '](astept [' + tcVal + '])'
ENDIF
DO SiLog WITH lcMsg
SELECT (lnSel)
ENDPROC
PROCEDURE VerificaDvi
*-- randul T e re-cheiat pe documentul vamal (Go lnRecT - fix), nu mai ramane sub nract-ul facturii.
LPARAMETERS tnNract, tnNractDvi, tnBazaLei, tnTvaLei
LOCAL lnSel, lcMsg, llB, llT, lnBS, lnTS, lcTPartc, llVama, llRamasitaT
lnSel = SELECT()
SELECT introdc
LOCATE FOR nract = tnNract AND tip_rand == 'B'
llB = FOUND()
IF llB
lnBS = suma
ENDIF
LOCATE FOR nract = tnNractDvi AND tip_rand == 'T'
llT = FOUND()
IF llT
lnTS = suma
lcTPartc = ALLTRIM(NVL(partc,''))
llVama = ('VAMAL' $ UPPER(lcTPartc))
ENDIF
LOCATE FOR nract = tnNract AND tip_rand == 'T'
llRamasitaT = FOUND()
IF llB AND llT AND !llRamasitaT AND ABS(lnBS - tnBazaLei) < 0.01 AND ABS(lnTS - tnTvaLei) < 0.01 AND llVama
lcMsg = 'PASS DVI nract=' + TRANSFORM(tnNract) + ': B(suma=' + TRANSFORM(lnBS) + ') + T_DVI(nract=' + TRANSFORM(tnNractDvi) + ' partc=' + lcTPartc + ' suma=' + TRANSFORM(lnTS) + ')'
ELSE
lcMsg = 'FAIL DVI nract=' + TRANSFORM(tnNract) + ': B(suma=' + TRANSFORM(IIF(llB,lnBS,-1)) + ', astept ' + TRANSFORM(tnBazaLei) + ') T_DVI(nract=' + TRANSFORM(tnNractDvi) + ' suma=' + TRANSFORM(IIF(llT,lnTS,-1)) + ', astept ' + TRANSFORM(tnTvaLei) + ' partc=' + IIF(llT,lcTPartc,'?') + ') ramasitaT=' + TRANSFORM(llRamasitaT) + ' (astept .F.)'
ENDIF
DO SiLog WITH lcMsg
SELECT (lnSel)
ENDPROC
PROCEDURE VerificaSumaGrupVama
*-- anti-corupere: doc1 si doc2 re-cheie randul T pe ACELASI doc_key (nract/partc vamal
*-- identice) - verific ca exista tnAsteptateRanduri randuri T cu acel nract si suma lor
*-- totala e cea asteptata (randul T al doc1 nu a fost suprascris/pierdut la adaugarea doc2 -
*-- bugul original: Locate For doc_key==calc_doc_key() degenerat landa pe primul T scanat).
LPARAMETERS tnNractVama, tnSumaAsteptata, tnRanduriAsteptate
LOCAL lnSel, lcMsg, lnSumaT, lnCount
lnSel = SELECT()
SELECT COUNT(*) AS n, SUM(suma) AS s FROM introdc WHERE nract = tnNractVama AND tip_rand == 'T' INTO CURSOR crsGrupVama NOFILTER
lnCount = crsGrupVama.n
lnSumaT = NVL(crsGrupVama.s, 0)
USE IN crsGrupVama
IF lnCount = tnRanduriAsteptate AND ABS(lnSumaT - tnSumaAsteptata) < 0.01
lcMsg = 'PASS grup vama nract=' + TRANSFORM(tnNractVama) + ': ' + TRANSFORM(lnCount) + ' randuri T, suma totala=' + TRANSFORM(lnSumaT)
ELSE
lcMsg = 'FAIL grup vama nract=' + TRANSFORM(tnNractVama) + ': randuri=' + TRANSFORM(lnCount) + ' (astept ' + TRANSFORM(tnRanduriAsteptate) + ') suma=' + TRANSFORM(lnSumaT) + ' (astept ' + TRANSFORM(tnSumaAsteptata) + ')'
ENDIF
DO SiLog WITH lcMsg
SELECT (lnSel)
ENDPROC
PROCEDURE DumpIntrodc
LOCAL lnSel
lnSel = SELECT()
SELECT introdc
SCAN
DO SiLog WITH ' recno=' + TRANSFORM(RECNO()) + ' nract=' + TRANSFORM(nract) + ' tip_rand=' + tip_rand + ;
' scd=' + ALLTRIM(scd) + ' suma=' + TRANSFORM(suma) + ' suma_val=' + TRANSFORM(suma_val) + ;
' partc=[' + ALLTRIM(NVL(partc,'')) + '] doc_key=[' + ALLTRIM(doc_key) + ']'
ENDSCAN
SELECT (lnSel)
ENDPROC
FUNCTION RECCOUNT_ACTIVE
LPARAMETERS tcAlias
LOCAL lnSel, lnCnt
lnSel = SELECT()
SELECT (tcAlias)
COUNT TO lnCnt FOR !DELETED()
SELECT (lnSel)
RETURN lnCnt
ENDFUNC
PROCEDURE SiErr
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
DO SiLog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
ENDPROC
PROCEDURE SiLog
LPARAMETERS tcMsg
SET SAFETY OFF
LOCAL lcL
lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '')
STRTOFILE(lcL + tcMsg + CHR(13)+CHR(10), gcUILog)
ENDPROC
DEFINE CLASS dummyapp AS Custom
PROCEDURE ReadIni
LPARAMETERS tcSection, tcKey
RETURN ''
ENDPROC
PROCEDURE WriteIni
LPARAMETERS tcSection, tcKey, tcValue
RETURN .T.
ENDPROC
ENDDEFINE
DEFINE CLASS dummyexecutor AS Custom
cEroare = ''
PROCEDURE oExecute
LPARAMETERS tcSql, tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
*-- update_jtva_coloane (SELECT * FROM vjtva_coloane ...): mock cu date reale.
IF 'VJTVA_COLOANE' $ UPPER(m.tcSql)
DO CreeazaJtvaColoaneView WITH m.tcCursor
RETURN 1
ENDIF
*-- rul_temp (recreat de import_nota.Init din vrul cand e gol): structura completa
*-- ceruta de coloanele GridArt, altfel grila isi pierde coloanele (eroare 1925).
IF UPPER(ALLTRIM(m.tcCursor)) == 'RUL_TEMP'
CREATE CURSOR (m.tcCursor) (denumire C(100), codmat C(30), cant N(14,3), ;
pret_val N(18,4), pretd N(18,4), pret N(18,4), pret_lei N(18,4), cont C(10), ;
acont C(20), serie C(30), lot C(30), adata_expirare C(10), proc_disc N(6,2), cota_tva N(6,2))
ELSE
*-- ramura generica: acopera si config_analitice (assign_analitic) - cursor gol,
*-- lnSucces>0 dar RECCOUNT=0 => lnSucces=-1 in assign_analitic => lcAnalitic='' (fara
*-- analitic pe cont 212, comportament acceptat de team-lead pentru acest test).
CREATE CURSOR (m.tcCursor) (id_temp N(1))
ENDIF
RETURN 1
ENDPROC
PROCEDURE oExecuta
LPARAMETERS tcSql, tcCursor
IF !EMPTY(m.tcCursor)
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF UPPER(m.tcCursor) == 'CJTVACOL4427'
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14))
ELSE
CREATE CURSOR (m.tcCursor) (id_temp N(1))
ENDIF
ENDIF
RETURN .T.
ENDPROC
PROCEDURE oSelect2Value
*-- GetCodFiscalPartenerById: cod fiscal gol => VERIFICA_RTVAI sare peste Oracle real.
LPARAMETERS tcSql, toValue
toValue = ''
RETURN 1
ENDPROC
PROCEDURE oReset
*-- update_jtva_coloane() il apeleaza necondit dupa oExecute (updateserver.prg:611).
ENDPROC
ENDDEFINE
PROCEDURE CreeazaJtvaColoaneView
LPARAMETERS tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14), denumire C(100), jc N(1), jv N(1), ;
coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14) NULL, afisat N(1), ;
id_jtva_ex N(14) NULL, id_jtva_neex N(14) NULL, ordine N(8), ;
taxcode N(6) NULL, taxcode_neexigibil N(6) NULL, taxcode_n50 N(6) NULL, ;
taxcode_n50_tvai N(6) NULL, taxcode_n100 N(6) NULL, taxcode_regularizare N(6) NULL, taxcode_tvai N(6) NULL)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, afisat, ordine, cota_tva) VALUES (0, '', 0, 0, 1, 0, 0)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (208, 'ACH. INT. 21%', 1, 0, 'RO21B', 21, 209, 1, 1, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (209, 'TVA ACH. INT. 21%', 1, 0, 'RO21T', 21, 1, 2, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (220, 'ACH. IMP. 21%', 1, 0, 'FO21B', 21, 221, 1, 3, 301204)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (221, 'TVA ACH. IMP. 21%', 1, 0, 'FO21T', 21, 1, 4, 301204)
ENDPROC

View File

@@ -0,0 +1,10 @@
# test_scenariu_import_212.ps1 - wrapper peste harness-ul generic pentru scenariul Marius
# (import 3 documente + articol BULDOEXCAVATOR cont 212 -> actualizeaza_banda cu mesaj lung).
# Rulare: powershell -ExecutionPolicy Bypass -File test_scenariu_import_212.ps1
$ErrorActionPreference = 'Stop'
$Teste = $PSScriptRoot
& (Join-Path (Split-Path $Teste -Parent) 'vfp_ui_harness.ps1') `
-TestPrg (Join-Path $Teste 'test_scenariu_import_212.prg') `
-Steps @('3documente','articol_sincronizat','final') `
-ShotsDir (Join-Path $Teste 'screenshots_import_212') `
-SyncDir (Join-Path $Teste 'uisync_212')

View File

@@ -0,0 +1,807 @@
* test_sparge_secundare.prg
* Runda 23 (COMUN\clase\ointroduceri.vcx, clasa import_nota): optiunea "sparge facturile
* secundare pe conturile/analiticele articolelor" (Thisform.lSpargeSecundare, implicit .T.).
* Scenariu real raportat de utilizator:
* principal: 2 articole - BULDOEXCAVATOR cont 212 acont 1 (900 EUR), A8 cont 371 acont 4
* (100 EUR); curs 5.23; factura principala 1000 EUR (import, participa_valuta).
* transport (secundar): 1000 LEI (in_valuta=0, participa_valuta=.T.), cont B initial 371/4,
* partener debit completat pe B.
* vama (secundar): 500 LEI, la fel.
* Verifica: (1) dupa sincronizare, transportul si vama se sparg proportional cu bazele
* articolelor (900/100 lei); B-urile secundarelor dispar; suma S per document = suma
* documentului. (2) partenerul debit de pe B-ul transportului se regaseste pe ambele S-uri.
* (3) lSpargeSecundare=.F. + sincronizeaza -> secundarele revin la un singur rand B (scd/ascd
* originale, scd_orig). (4) lSpargeSecundare=.T. + sincronizeaza -> se sparg iar (punctul 1).
*
* Rulare:
* powershell -ExecutionPolicy Bypass -File test_sparge_secundare.ps1
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET DECIMALS TO 4
SET NULLDISPLAY TO ''
CLOSE DATABASES
PUBLIC gcUILog, gcSyncDir
gcUILog = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\test_sparge_secundare_log.txt"
gcSyncDir = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\uisync_sparge_secundare\"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcUILog)
ON ERROR DO DcErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
TRY
LOCAL gcAppPath, lcPath
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;' + ;
ADDBS(SUBSTR(gcAppPath,1,RAT([\],gcAppPath,2)))+[COMUNROA\]
SET PATH TO &lcPath ADDITIVE
DO DcLog WITH 'SET PATH OK'
*----- CLASE -----
SET CLASSLIB TO (gcAppPath + "comun\clase\appwiz") 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 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 wwdialogs.vcx ADDITIVE
SET CLASSLIB TO oimportxml.vcx ADDITIVE
SET CLASSLIB TO excelxml.vcx ADDITIVE
SET CLASSLIB TO orapoarte_obinv.vcx ADDITIVE
DO DcLog WITH 'SET CLASSLIB OK'
*----- PROCEDURI (mock amessagebox + mock cauta_nom_articole PRIMELE, ui_harness la final) -----
SET PROCEDURE TO PROCEDURI
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_cauta_nom_articole.prg" 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 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 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 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
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\ui_harness.prg" ADDITIVE
DO DcLog WITH 'SET PROCEDURE OK'
*----- Globale -----
PUBLIC gnPc, gnPval, gnPcant, gnPpret, gnPPretval, gnPCurs, gnPVal, gnPPretV, gnPPretVal
STORE 2 TO gnPc, gnPval, gnPVal
gnPcant = 3
STORE 4 TO gnPpret, gnPPretval, gnPPretVal, gnPPretV, gnPCurs
PUBLIC gl406, gcS, gnAn, gnLuna, gnIdFirma, gnIdSucursala, gcAcces, gcFirma
gl406 = .T.
gcS = 'CONTAFIN'
gnAn = YEAR(DATE())
gnLuna = MONTH(DATE())
gnIdFirma = 110
gnIdSucursala = 110
gcAcces = "1;2;3;4;5;6;7;8;"
gcFirma = gcS
PUBLIC nror(65000)
PUBLIC gnButon
STORE 2 TO gnButon
PUBLIC gcMockArtCodmat, gcMockAcontCrt
gcMockArtCodmat = ''
gcMockAcontCrt = ''
PUBLIC gnMockRaspuns
gnMockRaspuns = 6
PUBLIC goExecutor, goApp
goExecutor = CREATEOBJECT('dummyexecutor')
goApp = CREATEOBJECT('dummyapp')
*----- poAct: antetul notei; dialogul mosteneste din el la Init -----
PUBLIC poAct
poAct = CREATEOBJECT('Custom')
poAct.AddProperty('nume_val', '')
poAct.AddProperty('curs', 5.23)
poAct.AddProperty('proc_tva', 1.21)
poAct.AddProperty('nnir', 0)
poAct.AddProperty('id_valuta', 978)
poAct.AddProperty('id_fdoc', 1)
poAct.AddProperty('fdoc', 'Factura')
poAct.AddProperty('id_partc', 500)
poAct.AddProperty('partc', 'FURNIZOR ANTET SRL')
poAct.AddProperty('serie_act', '')
poAct.AddProperty('dataact', DATE())
poAct.AddProperty('tva_incasare', 0)
poAct.AddProperty('id_set', 1)
poAct.AddProperty('id_gestin', 1)
*----- jtva_coloane2 / saft_taxtable: perechi reale 21% (Oracle dev, vjtva_coloane) -----
IF USED('jtva_coloane2')
USE IN ('jtva_coloane2')
ENDIF
CREATE CURSOR jtva_coloane2 (ordine N(8), id_jtva_coloana N(14), denumire C(100), ;
jc N(1), jv N(1), afisat N(1), coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14))
INSERT INTO jtva_coloane2 VALUES (0, 0, '', 0, 0, 1, '', '', 0, 0)
INSERT INTO jtva_coloane2 VALUES (1, 208, 'ACH. INT. 21%', 1, 0, 1, 'RO21B', 'RO21T', 21, 209)
INSERT INTO jtva_coloane2 VALUES (2, 209, 'TVA ACH. INT. 21%', 1, 0, 1, 'RO21T', '', 21, 0)
INSERT INTO jtva_coloane2 VALUES (3, 220, 'ACH. IMP. 21%', 1, 0, 1, 'FO21B', 'FO21T', 21, 221)
INSERT INTO jtva_coloane2 VALUES (4, 221, 'TVA ACH. IMP. 21%', 1, 0, 1, 'FO21T', '', 21, 0)
IF USED('saft_taxtable')
USE IN ('saft_taxtable')
ENDIF
CREATE CURSOR saft_taxtable (taxname C(250) NULL, typename C(250) NULL, taxcode N(6) NULL, ;
taxtype N(3) NULL, descriere C(250) NULL, tip C(100) NULL, descriere_tip C(250) NULL, ;
procent_taxa N(7,2) NULL, procent_prorata N(7,2) NULL, inactiv N(1) NULL, tva N(1) NULL, ;
wht N(1) NULL, tva_achizitii N(1) NULL, tva_livrari N(1) NULL)
INDEX ON taxcode TAG taxcode
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('', 0, '', 0, 1, 1, 1, 1)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301104-Achizitii de bunuri si servicii taxabile cu cota de 21%, altele decat importurile si cele supuse masurilor de simplificare', 301104, '', 21, 1, 0, 1, 0)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301204-Import de bunuri cota 21%', 301204, '', 21, 1, 0, 1, 0)
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', 220, 21, 'ACH. IMP. 21%')
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', 221, 21, 'TVA ACH. IMP. 21%')
GO TOP IN introdc_sablon
DO CreeazaRulTemp
INSERT INTO rul_temp (denumire, codmat, cant, pret, pret_lei, cont, cota_tva) ;
VALUES ('PLACEHOLDER', 'PH', 1, 1, 1, '371', 21)
*-- F1 (ointroduceri.prg): index ord_doc INAINTE de CREATEOBJECT - vezi docs/testare-ui-vfp.md capcana p.
SELECT introdc
INDEX ON Str(Nvl(nr_doc,0),8) + Icase(tip_rand='B','1', tip_rand='S','2', tip_rand='T','3', tip_rand='D','4', '5') + Padr(Nvl(scd,''),10) TAG ord_doc
SET ORDER TO ord_doc
DO DcLog WITH 'cursoare pregatite, CREATEOBJECT(import_nota, .F.) - lIntern=.F. (import)'
PUBLIC goObj
goObj = CREATEOBJECT('IMPORT_nota', .F.)
IF VARTYPE(goObj) <> 'O'
DO DcLog WITH 'FAIL: instantiere import_nota'
DO HarnessDone WITH 'done-error'
QUIT
ENDIF
goObj.lDialogAratat = .T.
goObj.oact = poAct
goObj.WindowType = 0
goObj.Visible = .T.
goObj.Show()
goObj.WindowState = 2
DOEVENTS FORCE
SELECT rul_temp
ZAP
goObj.gridart.Refresh()
DOEVENTS FORCE
*========================= DOC PRINCIPAL + 2 SECUNDARE =========================
PUBLIC goDlg, goT
DO AdaugaDocPrincipal
DO VerificaB WITH 91000, 5230, 1000, 'principal-inainte-de-spargere'
DO AdaugaDocSecundar WITH 91001, 1000, 750, 'TRANSPORTATOR SRL', 'Transport marfa'
DO VerificaB WITH 91001, 1000, 0, 'transport-inainte-de-spargere'
DO AdaugaDocSecundar WITH 91002, 500, 760, 'BIROUL VAMAL', 'Taxe vamale'
DO VerificaB WITH 91002, 500, 0, 'vama-inainte-de-spargere'
*-- cont B initial 371/4 (impus de sablon) pe secundare + partener debit completat manual pe B
*-- (flux real: utilizatorul editeaza celula partener debit din grila) - simulez direct pe
*-- randul B, singura parte care nu trece prin dialogul de adaugare.
SELECT introdc
LOCATE FOR nract = 91001 AND tip_rand == 'B'
REPLACE ascd WITH '4', id_partd WITH 750, partd WITH 'TRANSPORTATOR SRL'
LOCATE FOR nract = 91002 AND tip_rand == 'B'
REPLACE ascd WITH '4', id_partd WITH 760, partd WITH 'BIROUL VAMAL'
DO DcLog WITH 'dump introdc dupa cele 3 documente (inainte de articole):'
DO DumpIntrodc
DO HarnessStep WITH 0, 'dupa 3 documente: introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri (astept 3)'
*========================= ARTICOLE (flux real do_adauga_articol) =========================
gcMockArtCodmat = 'ART-BULD-212'
gcMockAcontCrt = '1'
TRY
goObj.do_adauga_articol()
CATCH TO loExcA1
DO DcLog WITH 'EROARE do_adauga_articol (BULDOEXCAVATOR) ' + TRANSFORM(loExcA1.ErrorNo) + ' [' + loExcA1.Message + ']'
ENDTRY
DOEVENTS FORCE
SELECT rul_temp
LOCATE FOR ALLTRIM(codmat) == 'ART-BULD-212'
IF FOUND()
REPLACE cant WITH 1, pret_val WITH 900, pretd WITH 900, pret WITH ROUND(900*5.23,4), pret_lei WITH ROUND(900*5.23,4)
DO DcLog WITH 'BULDOEXCAVATOR (212/1) adaugat, 900 EUR / ' + TRANSFORM(ROUND(900*5.23,4)) + ' lei'
ELSE
DO DcLog WITH 'FAIL: BULDOEXCAVATOR nu a fost adaugat de do_adauga_articol()'
ENDIF
gcMockArtCodmat = 'ART-A8-371'
gcMockAcontCrt = '4'
TRY
goObj.do_adauga_articol()
CATCH TO loExcA2
DO DcLog WITH 'EROARE do_adauga_articol (A8) ' + TRANSFORM(loExcA2.ErrorNo) + ' [' + loExcA2.Message + ']'
ENDTRY
DOEVENTS FORCE
SELECT rul_temp
LOCATE FOR ALLTRIM(codmat) == 'ART-A8-371'
IF FOUND()
REPLACE cant WITH 1, pret_val WITH 100, pretd WITH 100, pret WITH ROUND(100*5.23,4), pret_lei WITH ROUND(100*5.23,4)
DO DcLog WITH 'A8 (371/4) adaugat, 100 EUR / ' + TRANSFORM(ROUND(100*5.23,4)) + ' lei'
ELSE
DO DcLog WITH 'FAIL: A8 nu a fost adaugat de do_adauga_articol()'
ENDIF
goObj.gridart.Refresh()
DOEVENTS FORCE
DO HarnessStep WITH 1, 'dupa adaugare articole BULDOEXCAVATOR+A8, rul_temp=' + TRANSFORM(RECCOUNT_ACTIVE('rul_temp'))
*========================= PUNCTUL 1+2: SINCRONIZARE CU lSpargeSecundare=.T. (implicit) =========================
DO DcLog WITH 'lSpargeSecundare (implicit) = ' + TRANSFORM(goObj.lSpargeSecundare) + ' (astept .T.)'
DO Sincronizeaza WITH 'sync1-spargere-implicita'
DO DcLog WITH 'dump introdc dupa sincronizare #1 (spargere implicita):'
DO DumpIntrodc
DO HarnessStep WITH 2, 'dupa sincronizare #1 (spargere implicita): introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri'
DO VerificaSpargere WITH 91001, 900.00, 100.00, 750, 'transport-spart'
DO VerificaSpargere WITH 91002, 450.00, 50.00, 760, 'vama-spart'
DO VerificaPrincipalSpart WITH 91000, 4707.00, 523.00
*========================= PUNCTUL 3: DEBIFARE - REVENIRE LA UN SINGUR B =========================
goObj.lSpargeSecundare = .F.
DO Sincronizeaza WITH 'sync2-debifat'
DO DcLog WITH 'dump introdc dupa debifare lSpargeSecundare:'
DO DumpIntrodc
DO HarnessStep WITH 3, 'dupa debifare lSpargeSecundare: introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri'
DO VerificaUnit WITH 91001, 1000, '371', '4', 'transport-reunit'
DO VerificaUnit WITH 91002, 500, '371', '4', 'vama-reunit'
DO VerificaPrincipalSpart WITH 91000, 4707.00, 523.00
*========================= PUNCTUL 4: REBIFARE - SE SPARG IAR =========================
goObj.lSpargeSecundare = .T.
DO Sincronizeaza WITH 'sync3-rebifat'
DO DcLog WITH 'dump introdc dupa rebifare lSpargeSecundare:'
DO DumpIntrodc
DO HarnessStep WITH 4, 'dupa rebifare lSpargeSecundare: introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri'
DO VerificaSpargere WITH 91001, 900.00, 100.00, 750, 'transport-respart'
DO VerificaSpargere WITH 91002, 450.00, 50.00, 760, 'vama-respart'
DO VerificaPrincipalSpart WITH 91000, 4707.00, 523.00
DO DcLog WITH 'GATA - scenariu executat integral'
DO HarnessStep WITH 5, 'final: introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri'
DO HarnessDone WITH 'done'
CATCH TO loExc
DO DcLog WITH 'CATCH ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']'
DO HarnessDone WITH 'done-error'
ENDTRY
QUIT
*==================================================================================
PROCEDURE AdaugaDocPrincipal
*-- FACTURA 91000, 1000 EUR (curs 5.23), participa_valuta, ramura F (normal, fara DVI).
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = 91000
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 601
goDlg.cPartener = 'FURNIZOR IMPORT SRL'
goDlg.cExplicatia = 'Import marfa'
goDlg.nSuma = 1000
goDlg.nSumaLei = 0
goDlg.nCurs = 5.23
goDlg.nIdValuta = 978
goDlg.cValuta = 'EUR'
goDlg.nIdExplicatieTva = 220
goDlg.cExplicatieTva = 'ACH. IMP. 21%'
goDlg.optTipTva.Value = 1 && F = furnizor (normal, fara DVI)
goDlg.chkInValutaCont.Value = 1
goDlg.chkParticipaValuta.Value = 1
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO DcLog WITH 'DOC-PRINCIPAL: valideaza = ' + TRANSFORM(goDlg.valideaza())
DO ConstruiesteToDlg
DO DcLog WITH 'DOC-PRINCIPAL: do_adauga_factura = ' + TRANSFORM(goObj.do_adauga_factura(goT))
goDlg.Hide()
DOEVENTS FORCE
ENDPROC
PROCEDURE AdaugaDocSecundar
*-- factura secundara in LEI (transport/vama), participa_valuta, ramura F (fara DVI).
LPARAMETERS tnNract, tnSuma, tnIdPartener, tcPartener, tcExplicatia
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = tnNract
goDlg.dDataAct = DATE()
goDlg.nIdPartener = tnIdPartener
goDlg.cPartener = tcPartener
goDlg.cExplicatia = tcExplicatia
goDlg.nSuma = tnSuma
goDlg.nSumaLei = 0
goDlg.nCurs = 0
goDlg.nIdExplicatieTva = 220
goDlg.cExplicatieTva = 'ACH. IMP. 21%'
goDlg.optTipTva.Value = 1 && F = furnizor (normal, fara DVI)
goDlg.chkInValutaCont.Value = 0
goDlg.chkParticipaValuta.Value = 1
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO DcLog WITH 'DOC-SECUNDAR ' + TRANSFORM(tnNract) + ': valideaza = ' + TRANSFORM(goDlg.valideaza())
DO ConstruiesteToDlg
DO DcLog WITH 'DOC-SECUNDAR ' + TRANSFORM(tnNract) + ': do_adauga_factura = ' + TRANSFORM(goObj.do_adauga_factura(goT))
goDlg.Hide()
DOEVENTS FORCE
ENDPROC
PROCEDURE ConstruiesteToDlg
*-- toDlg construit INLINE (nu intr-o functie apelata din procedura de business) - vezi
*-- docs/testare-ui-vfp.md capcana l; aici functioneaza fiindca goT e PUBLIC (nu return local).
goT = CREATEOBJECT('Empty')
=ADDPROPERTY(goT,'serie_act',ALLTRIM(NVL(goDlg.cSerieAct,'')))
=ADDPROPERTY(goT,'nract',goDlg.nNract)
=ADDPROPERTY(goT,'dataact',goDlg.dDataAct)
=ADDPROPERTY(goT,'fdoc',goDlg.cFelDoc)
=ADDPROPERTY(goT,'id_fdoc',goDlg.nIdFdoc)
=ADDPROPERTY(goT,'id_partc',goDlg.nIdPartener)
=ADDPROPERTY(goT,'partc',goDlg.cPartener)
=ADDPROPERTY(goT,'explicatia',ALLTRIM(NVL(goDlg.cExplicatia,'')))
=ADDPROPERTY(goT,'suma',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,IIF(goDlg.nSumaLei<>0,goDlg.nSumaLei,ROUND(goDlg.nSuma*goDlg.nCurs,gnPC)),goDlg.nSuma))
=ADDPROPERTY(goT,'suma_val',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,goDlg.nSuma,0))
=ADDPROPERTY(goT,'in_valuta',goDlg.chkInValutaCont.Value)
=ADDPROPERTY(goT,'participa_valuta',(goDlg.chkParticipaValuta.Value=1))
=ADDPROPERTY(goT,'id_valuta',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nIdValuta,0))
=ADDPROPERTY(goT,'curs',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nCurs,0))
=ADDPROPERTY(goT,'nume_val',IIF(goDlg.chkInValutaCont.Value=1,ALLTRIM(NVL(goDlg.cValuta,'')),''))
=ADDPROPERTY(goT,'cTipTva',IIF(goDlg.optTipTva.Value=1,'F',IIF(goDlg.optTipTva.Value=2,'D','N')))
=ADDPROPERTY(goT,'id_jtva_coloana',goDlg.nIdExplicatieTva)
=ADDPROPERTY(goT,'dvi_serie','')
=ADDPROPERTY(goT,'dvi_nract',0)
=ADDPROPERTY(goT,'dvi_dataact',{})
=ADDPROPERTY(goT,'dvi_id_fdoc',0)
=ADDPROPERTY(goT,'dvi_fdoc','')
=ADDPROPERTY(goT,'dvi_id_partc',0)
=ADDPROPERTY(goT,'dvi_partc','')
=ADDPROPERTY(goT,'dvi_scc','')
=ADDPROPERTY(goT,'dvi_tva_lei',0)
=ADDPROPERTY(goT,'dvi_tva_val',0)
ENDPROC
PROCEDURE CreeazaRulTemp
*-- structura reala rul_temp (VRUL, Oracle dev).
IF USED('rul_temp')
USE IN ('rul_temp')
ENDIF
CREATE CURSOR rul_temp ( ;
id_rul N(20,0), an N(4,0), luna N(2,0), cod N(20,0);
, serie C(100), nnir N(20,0), id_articol N(10,0), denumire C(100);
, codmat C(50), codmatf C(50), codbare C(50), um C(20);
, id_gestiune N(5,0), nume_gestiune C(50), cgest C(20), nr_pag N(2,0);
, gestionar C(50), comisie_receptie1 C(50), comisie_receptie2 C(50), comisie_receptie3 C(50);
, cant N(14,3), cante N(14,3), cont C(10), acont C(20);
, pret N(18,4), tva N(18,4), valoare N(18,4), valtva N(18,4);
, proc_tva N(5,2), pretv N(18,4), pretvtva N(18,4), tvav N(18,4);
, valoarev N(18,4), valtvav N(18,4), proc_tvav N(5,2), adaos N(18,4);
, adaos_tva N(18,4), valoare_adaos N(18,4), valtva_adaos N(18,4), procent N(10,3);
, discunitar N(18,4), discount_tva N(18,4), valoare_discount N(18,4), valtva_discount N(18,4);
, proc_disc N(7,3), pretd N(14,4), curs N(18,4), id_valuta N(10,0);
, nume_val C(20), id_lucrare N(20,0), nrord C(100), id_responsabil N(10,0);
, nresp C(100), resp_marca N(18,4), dataact T, id_util N(5,0);
, util C(30), dataora T, id_sectie N(5,0), sectie C(50);
, csectie C(10), alcooltutun N(1,0), datain T, dataout T;
, id_fact N(20,0), id_gestiunec N(10,0), nume_gestiunec C(50), cgestc C(20);
, id_responsabilc N(5,0), id_reteta N(10,0), reteta C(50), nrespc C(100);
, respc_marca N(18,4), id_set N(20,0), id_tip_rulaj N(10,0), tip_rulaj C(50);
, id_obiect_depozit N(10,0), id_rul_aux N(10,0), nract N(20,0), serie_act C(10);
, dataoras T, id_utils N(10,0), lot C(30), adata_expirare T;
, id_sucursala N(5,0), sucursala C(250), id_part_rez N(10,0), part_rez C(100);
, id_lucrare_rez N(10,0), nrord_rez C(100), subgrupa C(100), grupa C(100);
, id_subgrupa N(5,0), id_grupa N(5,0), in_stoc N(1,0), in_crm N(1,0);
, id_furnizor N(10,0), furnizor C(100), id_jtva_coloana N(4,0), explicatie_tva C(100);
, taxcode N(6,0), taxname C(254), saft_procent N(18,4), codnc8 C(20);
, id_tara_origine N(4,0), cod_tara_origine C(5), tara_origine C(50), greutate N(12,4);
, fdoc C(30), id_fdoc N(18,4);
, pret_lei N(18,4), pret_val N(14,4), cota_tva N(6,2))
ENDPROC
PROCEDURE CreeazaIntrodc
LPARAMETERS tcAlias
IF USED(tcAlias)
USE IN (tcAlias)
ENDIF
CREATE CURSOR (tcAlias) ( ;
id_note N(14), explicatia C(100), scd C(10), ascd C(20), scc C(10), ascc C(20), ;
cu_tva N(1), id_set N(14), ordine N(8), in_valuta N(1), id_jtva_coloana N(14) NULL, ;
ptva N(6,2), explicatie_tva C(50), tipjurnal C(2), taxcode N(6), paymentcode C(9), ;
suma N(18,4), suma_val N(18,4), id_partd N(14), id_partc N(14), partd C(100), partc C(100), ;
id_fact N(14), id_factd N(14), id_factc N(14), pereched N(14), perechec N(14), ;
nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), ;
scd_orig C(20), ascd_orig C(20))
ENDPROC
PROCEDURE Sincronizeaza
*-- sincronizare directa (nu prin Valid) + Refresh grid, cu logare PASS/FAIL de eroare.
LPARAMETERS tcLabel
LOCAL llEroare
llEroare = .F.
TRY
goObj.sincronizeaza()
CATCH TO loExcSync
llEroare = .T.
DO DcLog WITH 'EROARE la sincronizeaza() [' + tcLabel + '] ' + TRANSFORM(loExcSync.ErrorNo) + ' [' + loExcSync.Message + '] in ' + loExcSync.Procedure + ':' + TRANSFORM(loExcSync.LineNo) + ' (' + loExcSync.LineContents + ')'
ENDTRY
DOEVENTS FORCE
goObj.grid1.Refresh()
IF !llEroare
DO DcLog WITH 'PASS ' + tcLabel + ': sincronizeaza() fara eroare'
ELSE
DO DcLog WITH 'FAIL ' + tcLabel + ': sincronizeaza() a aruncat eroare'
ENDIF
ENDPROC
PROCEDURE VerificaB
*-- randul B al unui document exista inca, cu suma/suma_val date (inainte de spargere).
LPARAMETERS tnNract, tnSuma, tnSumaVal, tcLabel
LOCAL lnSel, lcMsg, llB
lnSel = SELECT()
SELECT introdc
LOCATE FOR nract = tnNract AND tip_rand == 'B'
llB = FOUND()
IF llB AND ABS(suma - tnSuma) < 0.01 AND ABS(suma_val - tnSumaVal) < 0.01
lcMsg = 'PASS ' + tcLabel + ': B nract=' + TRANSFORM(tnNract) + ' suma=' + TRANSFORM(suma) + ' suma_val=' + TRANSFORM(suma_val)
ELSE
lcMsg = 'FAIL ' + tcLabel + ': B nract=' + TRANSFORM(tnNract) + ' gasit=' + TRANSFORM(llB) + ' suma=' + TRANSFORM(IIF(llB,suma,-1)) + '(astept ' + TRANSFORM(tnSuma) + ') suma_val=' + TRANSFORM(IIF(llB,suma_val,-1)) + '(astept ' + TRANSFORM(tnSumaVal) + ')'
ENDIF
DO DcLog WITH lcMsg
SELECT (lnSel)
ENDPROC
PROCEDURE VerificaSpargere
*-- documentul secundar s-a spart in 2 randuri S (212/ascd=1 si 371/ascd=4), proportional cu
*-- bazele articolelor (900/100); B a disparut; suma S212+suma S371 = suma documentului (D9,
*-- fara diferente de rotunjire); id_partd (partener debit) regasit pe AMBELE S-uri (r22).
LPARAMETERS tnNract, tnSumaS212Asteptata, tnSumaS371Asteptata, tnIdPartdAsteptat, tcLabel
LOCAL lnSel, lcMsg, llBExista, llS212, llS371, lnSumaS212, lnSumaS371, lnIdPartd212, lnIdPartd371, lcAscd212, lcAscd371
lnSel = SELECT()
SELECT introdc
LOCATE FOR nract = tnNract AND tip_rand == 'B'
llBExista = FOUND()
LOCATE FOR nract = tnNract AND tip_rand == 'S' AND ALLTRIM(scd) == '212'
llS212 = FOUND()
IF llS212
lnSumaS212 = suma
lnIdPartd212 = NVL(id_partd, 0)
lcAscd212 = ALLTRIM(NVL(ascd,''))
ENDIF
LOCATE FOR nract = tnNract AND tip_rand == 'S' AND ALLTRIM(scd) == '371'
llS371 = FOUND()
IF llS371
lnSumaS371 = suma
lnIdPartd371 = NVL(id_partd, 0)
lcAscd371 = ALLTRIM(NVL(ascd,''))
ENDIF
IF !llBExista AND llS212 AND llS371 ;
AND lcAscd212 == '1' AND lcAscd371 == '4' ;
AND ABS(lnSumaS212 - tnSumaS212Asteptata) < 0.01 AND ABS(lnSumaS371 - tnSumaS371Asteptata) < 0.01 ;
AND lnIdPartd212 = tnIdPartdAsteptat AND lnIdPartd371 = tnIdPartdAsteptat
lcMsg = 'PASS ' + tcLabel + ': B disparut, S212=' + TRANSFORM(lnSumaS212) + ' S371=' + TRANSFORM(lnSumaS371) + ;
' (suma=' + TRANSFORM(lnSumaS212+lnSumaS371) + '), id_partd=' + TRANSFORM(tnIdPartdAsteptat) + ' pe ambele S-uri'
ELSE
lcMsg = 'FAIL ' + tcLabel + ': Bexista=' + TRANSFORM(llBExista) + '(astept .F.) S212=' + TRANSFORM(llS212) + '(suma=' + TRANSFORM(IIF(llS212,lnSumaS212,-1)) + ',astept ' + TRANSFORM(tnSumaS212Asteptata) + ') S371=' + TRANSFORM(llS371) + '(suma=' + TRANSFORM(IIF(llS371,lnSumaS371,-1)) + ',astept ' + TRANSFORM(tnSumaS371Asteptata) + ') id_partd212=' + TRANSFORM(IIF(llS212,lnIdPartd212,-1)) + ' id_partd371=' + TRANSFORM(IIF(llS371,lnIdPartd371,-1)) + '(astept ' + TRANSFORM(tnIdPartdAsteptat) + ')'
ENDIF
DO DcLog WITH lcMsg
SELECT (lnSel)
ENDPROC
PROCEDURE VerificaUnit
*-- documentul secundar a revenit la UN SINGUR rand B, cu scd/ascd originale (scd_orig/ascd_orig)
*-- si suma egala cu suma documentului; S-urile lui au disparut.
LPARAMETERS tnNract, tnSumaAsteptata, tcScdAsteptat, tcAscdAsteptat, tcLabel
LOCAL lnSel, lcMsg, llB, llMaiAreS, lcScdB, lcAscdB, lnSumaB
lnSel = SELECT()
SELECT introdc
LOCATE FOR nract = tnNract AND tip_rand == 'B'
llB = FOUND()
IF llB
*-- salvez campurile B INAINTE de al 2-lea LOCATE (muta pointerul, chiar daca nu gaseste nimic).
lcScdB = ALLTRIM(scd)
lcAscdB = ALLTRIM(NVL(ascd,''))
lnSumaB = suma
llMaiAreS = .F.
LOCATE FOR nract = tnNract AND tip_rand == 'S'
llMaiAreS = FOUND()
ENDIF
IF llB AND !llMaiAreS AND lcScdB == tcScdAsteptat AND lcAscdB == tcAscdAsteptat AND ABS(lnSumaB - tnSumaAsteptata) < 0.01
lcMsg = 'PASS ' + tcLabel + ': un singur B, scd=' + lcScdB + ' ascd=[' + lcAscdB + '] suma=' + TRANSFORM(lnSumaB)
ELSE
lcMsg = 'FAIL ' + tcLabel + ': B?=' + TRANSFORM(llB) + ' maiAreS?=' + TRANSFORM(IIF(llB,llMaiAreS,'?')) + '(astept .F.) scd=[' + IIF(llB,lcScdB,'?') + '](astept [' + tcScdAsteptat + ']) ascd=[' + IIF(llB,lcAscdB,'?') + '](astept [' + tcAscdAsteptat + ']) suma=' + TRANSFORM(IIF(llB,lnSumaB,-1)) + '(astept ' + TRANSFORM(tnSumaAsteptata) + ')'
ENDIF
DO DcLog WITH lcMsg
SELECT (lnSel)
ENDPROC
PROCEDURE VerificaPrincipalSpart
*-- documentul principal ramane spart (S212+S371) indiferent de lSpargeSecundare - optiunea
*-- se aplica DOAR secundarelor.
LPARAMETERS tnNract, tnSumaS212Asteptata, tnSumaS371Asteptata
LOCAL lnSel, lcMsg, llS212, llS371, lnSumaS212, lnSumaS371
lnSel = SELECT()
SELECT introdc
LOCATE FOR nract = tnNract AND tip_rand == 'S' AND ALLTRIM(scd) == '212'
llS212 = FOUND()
IF llS212
lnSumaS212 = suma
ENDIF
LOCATE FOR nract = tnNract AND tip_rand == 'S' AND ALLTRIM(scd) == '371'
llS371 = FOUND()
IF llS371
lnSumaS371 = suma
ENDIF
IF llS212 AND llS371 AND ABS(lnSumaS212 - tnSumaS212Asteptata) < 0.01 AND ABS(lnSumaS371 - tnSumaS371Asteptata) < 0.01
lcMsg = 'PASS principal-ramane-spart: S212=' + TRANSFORM(lnSumaS212) + ' S371=' + TRANSFORM(lnSumaS371)
ELSE
lcMsg = 'FAIL principal-ramane-spart: S212=' + TRANSFORM(llS212) + '(suma=' + TRANSFORM(IIF(llS212,lnSumaS212,-1)) + ',astept ' + TRANSFORM(tnSumaS212Asteptata) + ') S371=' + TRANSFORM(llS371) + '(suma=' + TRANSFORM(IIF(llS371,lnSumaS371,-1)) + ',astept ' + TRANSFORM(tnSumaS371Asteptata) + ')'
ENDIF
DO DcLog WITH lcMsg
SELECT (lnSel)
ENDPROC
PROCEDURE DumpIntrodc
LOCAL lnSel
lnSel = SELECT()
SELECT introdc
SCAN
DO DcLog WITH ' recno=' + TRANSFORM(RECNO()) + ' nr_doc=' + TRANSFORM(NVL(nr_doc,0)) + ' nract=' + TRANSFORM(nract) + ' fdoc=[' + ALLTRIM(NVL(fdoc,'')) + '] tip_rand=' + tip_rand + ;
' scd=' + ALLTRIM(scd) + ' ascd=[' + ALLTRIM(NVL(ascd,'')) + '] scc=' + ALLTRIM(scc) + ' suma=' + TRANSFORM(suma) + ' suma_val=' + TRANSFORM(suma_val) + ;
' id_partd=' + TRANSFORM(NVL(id_partd,0)) + ' scd_orig=[' + ALLTRIM(NVL(scd_orig,'')) + '] ascd_orig=[' + ALLTRIM(NVL(ascd_orig,'')) + '] doc_key=[' + ALLTRIM(doc_key) + ']'
ENDSCAN
SELECT (lnSel)
ENDPROC
FUNCTION RECCOUNT_ACTIVE
LPARAMETERS tcAlias
LOCAL lnSel, lnCnt
lnSel = SELECT()
SELECT (tcAlias)
COUNT TO lnCnt FOR !DELETED()
SELECT (lnSel)
RETURN lnCnt
ENDFUNC
PROCEDURE DcErr
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
DO DcLog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
ENDPROC
PROCEDURE DcLog
LPARAMETERS tcMsg
SET SAFETY OFF
LOCAL lcL
lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '')
STRTOFILE(lcL + tcMsg + CHR(13)+CHR(10), gcUILog)
ENDPROC
DEFINE CLASS dummyapp AS Custom
PROCEDURE ReadIni
LPARAMETERS tcSection, tcKey
RETURN ''
ENDPROC
PROCEDURE WriteIni
LPARAMETERS tcSection, tcKey, tcValue
RETURN .T.
ENDPROC
ENDDEFINE
DEFINE CLASS dummyexecutor AS Custom
cEroare = ''
PROCEDURE oExecute
LPARAMETERS tcSql, tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
*-- update_jtva_coloane (SELECT * FROM vjtva_coloane ...): mock cu date reale.
IF 'VJTVA_COLOANE' $ UPPER(m.tcSql)
DO CreeazaJtvaColoaneView WITH m.tcCursor
RETURN 1
ENDIF
*-- rul_temp (recreat de import_nota.Init din vrul cand e gol): structura completa.
IF UPPER(ALLTRIM(m.tcCursor)) == 'RUL_TEMP'
CREATE CURSOR (m.tcCursor) (denumire C(100), codmat C(30), cant N(14,3), ;
pret_val N(18,4), pretd N(18,4), pret N(18,4), pret_lei N(18,4), cont C(10), ;
acont C(20), serie C(30), lot C(30), adata_expirare C(10), proc_disc N(6,2), cota_tva N(6,2))
RETURN 1
ENDIF
*-- assign_analitic (creeaza_rand_s / do_adauga_articol): config_analitice - prefix/sufix goale,
*-- deci acont-ul vine direct din fconturi_analitice (mai jos), controlat de gcMockAcontCrt.
IF 'CONFIG_ANALITICE' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (camp_leg_prefix C(30), camp_leg_sufix C(30))
INSERT INTO (m.tcCursor) VALUES ('', '')
RETURN 1
ENDIF
*-- fconturi_analitice: acont-ul curent, setat explicit de test (gcMockAcontCrt) inainte de
*-- fiecare do_adauga_articol() - simplu si deterministic, fara sa depinda de binding real.
IF 'FCONTURI_ANALITICE' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (acont C(20))
INSERT INTO (m.tcCursor) VALUES (IIF(TYPE('gcMockAcontCrt') = 'C', gcMockAcontCrt, ''))
RETURN 1
ENDIF
*-- vplcont_analitic: validare analitic vs plan de conturi - un rand => acontul e "valid".
IF 'VPLCONT_ANALITIC' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (cont C(10), acont C(20))
INSERT INTO (m.tcCursor) VALUES ('212', '1')
INSERT INTO (m.tcCursor) VALUES ('371', '4')
RETURN 1
ENDIF
*-- ramura generica: cursor gol (nu afecteaza fluxurile testate mai sus).
CREATE CURSOR (m.tcCursor) (id_temp N(1))
RETURN 1
ENDPROC
PROCEDURE oExecuta
LPARAMETERS tcSql, tcCursor
IF !EMPTY(m.tcCursor)
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF UPPER(m.tcCursor) == 'CJTVACOL4427'
*-- coloana_jc 'FO21T' (import) NU se potriveste patternurilor TI%T/XX%TIT/CE%T -
*-- cursor gol => scc ramane '401' (nu 4427) - vezi Init.
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14))
ELSE
CREATE CURSOR (m.tcCursor) (id_temp N(1))
ENDIF
ENDIF
RETURN .T.
ENDPROC
PROCEDURE oSelect2Value
LPARAMETERS tcSql, toValue
toValue = ''
RETURN 1
ENDPROC
PROCEDURE oReset
ENDPROC
ENDDEFINE
PROCEDURE CreeazaJtvaColoaneView
LPARAMETERS tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14), denumire C(100), jc N(1), jv N(1), ;
coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14) NULL, afisat N(1), ;
id_jtva_ex N(14) NULL, id_jtva_neex N(14) NULL, ordine N(8), ;
taxcode N(6) NULL, taxcode_neexigibil N(6) NULL, taxcode_n50 N(6) NULL, ;
taxcode_n50_tvai N(6) NULL, taxcode_n100 N(6) NULL, taxcode_regularizare N(6) NULL, taxcode_tvai N(6) NULL)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, afisat, ordine, cota_tva) VALUES (0, '', 0, 0, 1, 0, 0)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (208, 'ACH. INT. 21%', 1, 0, 'RO21B', 21, 209, 1, 1, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (209, 'TVA ACH. INT. 21%', 1, 0, 'RO21T', 21, 1, 2, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (220, 'ACH. IMP. 21%', 1, 0, 'FO21B', 21, 221, 1, 3, 301204)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (221, 'TVA ACH. IMP. 21%', 1, 0, 'FO21T', 21, 1, 4, 301204)
ENDPROC

View File

@@ -0,0 +1,12 @@
# test_sparge_secundare.ps1 - wrapper peste harness-ul generic pentru testul optiunii
# "sparge facturile secundare pe conturile/analiticele articolelor" (runda 23). Rulare:
# powershell -ExecutionPolicy Bypass -File test_sparge_secundare.ps1
$ErrorActionPreference = 'Stop'
$Teste = $PSScriptRoot
& (Join-Path (Split-Path $Teste -Parent) 'vfp_ui_harness.ps1') `
-TestPrg (Join-Path $Teste 'test_sparge_secundare.prg') `
-Steps @('3documente','articole_adaugate','sync1_spargere','sync2_debifat','sync3_rebifat','final') `
-ShotsDir (Join-Path $Teste 'screenshots_sparge_secundare') `
-SyncDir (Join-Path $Teste 'uisync_sparge_secundare') `
-StepTimeoutSec 180 `
-ReadyTimeoutSec 180

View File

@@ -0,0 +1,743 @@
* test_termin_partener.prg
* Runda 22 (COMUN\clase\ointroduceri.vcx, clasa import_nota):
* (M1) inainte_de_do_termin nu mai resincronizeaza automat - blocheaza doar daca exista
* o sincronizare armata neexecutata (lSyncPending) sau un mesaj de eroare ramas (cmesajsync).
* (M2) sparge_document pastreaza partenerul debit (id_partd/partd) pus manual pe un rand S
* la regenerarea S-urilor (identificare per cont+analitic).
* Scenariu: factura principala cu 2 articole pe conturi diferite (212/ascd=1, 371/ascd=4) ->
* sincronizeaza -> 2 randuri S; partener manual pe S 371 -> sincronizeaza din nou -> partenerul
* ramane DOAR pe S 371; lSyncPending=.T. -> inainte_de_do_termin intoarce .F. fara sa modifice
* introdc; lSyncPending=.F./cmesajsync gol -> trece de gardele noi fara resincronizare (partenerul
* ramane cel setat manual).
*
* Rulare:
* powershell -ExecutionPolicy Bypass -File test_termin_partener.ps1
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET DECIMALS TO 4
SET NULLDISPLAY TO ''
CLOSE DATABASES
PUBLIC gcUILog, gcSyncDir
gcUILog = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\test_termin_partener_log.txt"
gcSyncDir = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\uisync_termin_partener\"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcUILog)
ON ERROR DO DcErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
TRY
LOCAL gcAppPath, lcPath
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;' + ;
ADDBS(SUBSTR(gcAppPath,1,RAT([\],gcAppPath,2)))+[COMUNROA\]
SET PATH TO &lcPath ADDITIVE
DO DcLog WITH 'SET PATH OK'
*----- CLASE -----
SET CLASSLIB TO (gcAppPath + "comun\clase\appwiz") 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 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 wwdialogs.vcx ADDITIVE
SET CLASSLIB TO oimportxml.vcx ADDITIVE
SET CLASSLIB TO excelxml.vcx ADDITIVE
SET CLASSLIB TO orapoarte_obinv.vcx ADDITIVE
DO DcLog WITH 'SET CLASSLIB OK'
*----- PROCEDURI (mock amessagebox + mock cauta_nom_articole PRIMELE, ui_harness la final) -----
SET PROCEDURE TO PROCEDURI
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_cauta_nom_articole.prg" 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 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 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 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
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\ui_harness.prg" ADDITIVE
DO DcLog WITH 'SET PROCEDURE OK'
*----- Globale -----
PUBLIC gnPc, gnPval, gnPcant, gnPpret, gnPPretval, gnPCurs, gnPVal, gnPPretV, gnPPretVal
STORE 2 TO gnPc, gnPval, gnPVal
gnPcant = 3
STORE 4 TO gnPpret, gnPPretval, gnPPretVal, gnPPretV, gnPCurs
PUBLIC gl406, gcS, gnAn, gnLuna, gnIdFirma, gnIdSucursala, gcAcces, gcFirma
gl406 = .T.
gcS = 'CONTAFIN'
gnAn = YEAR(DATE())
gnLuna = MONTH(DATE())
gnIdFirma = 110
gnIdSucursala = 110
gcAcces = "1;2;3;4;5;6;7;8;"
gcFirma = gcS
PUBLIC nror(65000)
PUBLIC gnButon
STORE 2 TO gnButon
PUBLIC gcMockArtCodmat, gcMockAcontCrt
gcMockArtCodmat = ''
gcMockAcontCrt = ''
PUBLIC gnMockRaspuns
gnMockRaspuns = 6
PUBLIC goExecutor, goApp
goExecutor = CREATEOBJECT('dummyexecutor')
goApp = CREATEOBJECT('dummyapp')
*----- poAct: antetul notei; dialogul mosteneste din el la Init -----
PUBLIC poAct
poAct = CREATEOBJECT('Custom')
poAct.AddProperty('nume_val', '')
poAct.AddProperty('curs', 5.23)
poAct.AddProperty('proc_tva', 1.21)
poAct.AddProperty('nnir', 0)
poAct.AddProperty('id_valuta', 978)
poAct.AddProperty('id_fdoc', 1)
poAct.AddProperty('fdoc', 'Factura')
poAct.AddProperty('id_partc', 500)
poAct.AddProperty('partc', 'FURNIZOR ANTET SRL')
poAct.AddProperty('serie_act', '')
poAct.AddProperty('dataact', DATE())
poAct.AddProperty('tva_incasare', 0)
poAct.AddProperty('id_set', 1)
poAct.AddProperty('id_gestin', 1)
*----- jtva_coloane2 / saft_taxtable: perechi reale 21% (Oracle dev, vjtva_coloane) -----
IF USED('jtva_coloane2')
USE IN ('jtva_coloane2')
ENDIF
CREATE CURSOR jtva_coloane2 (ordine N(8), id_jtva_coloana N(14), denumire C(100), ;
jc N(1), jv N(1), afisat N(1), coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14))
INSERT INTO jtva_coloane2 VALUES (0, 0, '', 0, 0, 1, '', '', 0, 0)
INSERT INTO jtva_coloane2 VALUES (1, 208, 'ACH. INT. 21%', 1, 0, 1, 'RO21B', 'RO21T', 21, 209)
INSERT INTO jtva_coloane2 VALUES (2, 209, 'TVA ACH. INT. 21%', 1, 0, 1, 'RO21T', '', 21, 0)
INSERT INTO jtva_coloane2 VALUES (3, 220, 'ACH. IMP. 21%', 1, 0, 1, 'FO21B', 'FO21T', 21, 221)
INSERT INTO jtva_coloane2 VALUES (4, 221, 'TVA ACH. IMP. 21%', 1, 0, 1, 'FO21T', '', 21, 0)
IF USED('saft_taxtable')
USE IN ('saft_taxtable')
ENDIF
CREATE CURSOR saft_taxtable (taxname C(250) NULL, typename C(250) NULL, taxcode N(6) NULL, ;
taxtype N(3) NULL, descriere C(250) NULL, tip C(100) NULL, descriere_tip C(250) NULL, ;
procent_taxa N(7,2) NULL, procent_prorata N(7,2) NULL, inactiv N(1) NULL, tva N(1) NULL, ;
wht N(1) NULL, tva_achizitii N(1) NULL, tva_livrari N(1) NULL)
INDEX ON taxcode TAG taxcode
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('', 0, '', 0, 1, 1, 1, 1)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301104-Achizitii de bunuri si servicii taxabile cu cota de 21%, altele decat importurile si cele supuse masurilor de simplificare', 301104, '', 21, 1, 0, 1, 0)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301204-Import de bunuri cota 21%', 301204, '', 21, 1, 0, 1, 0)
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%')
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%')
GO TOP IN introdc_sablon
DO CreeazaRulTemp
INSERT INTO rul_temp (denumire, codmat, cant, pret, pret_lei, cont, cota_tva) ;
VALUES ('PLACEHOLDER', 'PH', 1, 1, 1, '371', 21)
*-- F1 (ointroduceri.prg): index ord_doc INAINTE de CREATEOBJECT - vezi docs/testare-ui-vfp.md capcana p.
SELECT introdc
INDEX ON Str(Nvl(nr_doc,0),8) + Icase(tip_rand='B','1', tip_rand='S','2', tip_rand='T','3', tip_rand='D','4', '5') + Padr(Nvl(scd,''),10) TAG ord_doc
SET ORDER TO ord_doc
DO DcLog WITH 'cursoare pregatite, CREATEOBJECT(import_nota, .F.) - lIntern=.F. (import)'
PUBLIC goObj
goObj = CREATEOBJECT('IMPORT_nota', .F.)
IF VARTYPE(goObj) <> 'O'
DO DcLog WITH 'FAIL: instantiere import_nota'
DO HarnessDone WITH 'done-error'
QUIT
ENDIF
goObj.lDialogAratat = .T.
goObj.oact = poAct
goObj.WindowType = 0
goObj.Visible = .T.
goObj.Show()
goObj.WindowState = 2
DOEVENTS FORCE
SELECT rul_temp
ZAP
goObj.gridart.Refresh()
DOEVENTS FORCE
*========================= DOC PRINCIPAL (flux real do_adauga_factura) =========================
PUBLIC goDlg, goT
DO AdaugaDocPrincipal
DO DcLog WITH 'dump introdc dupa document principal (inainte de articole):'
DO DumpIntrodc
DO HarnessStep WITH 0, 'dupa document principal: introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri'
*========================= ARTICOLE (flux real do_adauga_articol) pe conturi 212 si 371 =========================
gcMockArtCodmat = 'ART-BULD-212'
gcMockAcontCrt = '1'
TRY
goObj.do_adauga_articol()
CATCH TO loExcA1
DO DcLog WITH 'EROARE do_adauga_articol (212) ' + TRANSFORM(loExcA1.ErrorNo) + ' [' + loExcA1.Message + ']'
ENDTRY
DOEVENTS FORCE
SELECT rul_temp
LOCATE FOR ALLTRIM(codmat) == 'ART-BULD-212'
IF FOUND()
REPLACE cant WITH 1, pret_val WITH 900, pretd WITH 900, pret WITH ROUND(900*5.23,4), pret_lei WITH ROUND(900*5.23,4)
DO DcLog WITH 'articol 212 adaugat, cant/pret completate'
ELSE
DO DcLog WITH 'FAIL: articolul 212 nu a fost adaugat de do_adauga_articol()'
ENDIF
gcMockArtCodmat = 'ART-A8-371'
gcMockAcontCrt = '4'
TRY
goObj.do_adauga_articol()
CATCH TO loExcA2
DO DcLog WITH 'EROARE do_adauga_articol (371) ' + TRANSFORM(loExcA2.ErrorNo) + ' [' + loExcA2.Message + ']'
ENDTRY
DOEVENTS FORCE
SELECT rul_temp
LOCATE FOR ALLTRIM(codmat) == 'ART-A8-371'
IF FOUND()
REPLACE cant WITH 1, pret_val WITH 100, pretd WITH 100, pret WITH ROUND(100*5.23,4), pret_lei WITH ROUND(100*5.23,4)
DO DcLog WITH 'articol 371 adaugat, cant/pret completate'
ELSE
DO DcLog WITH 'FAIL: articolul 371 nu a fost adaugat de do_adauga_articol()'
ENDIF
goObj.gridart.Refresh()
DOEVENTS FORCE
DO HarnessStep WITH 1, 'dupa adaugare articole 212+371, rul_temp=' + TRANSFORM(RECCOUNT_ACTIVE('rul_temp'))
*========================= PAS 1: SINCRONIZARE #1 - astept 2 randuri S =========================
LOCAL llEroareSync1
llEroareSync1 = .F.
TRY
goObj.sincronizeaza()
CATCH TO loExcS1
llEroareSync1 = .T.
DO DcLog WITH 'EROARE la sincronizeaza() #1 ' + TRANSFORM(loExcS1.ErrorNo) + ' [' + loExcS1.Message + '] in ' + loExcS1.Procedure + ':' + TRANSFORM(loExcS1.LineNo)
ENDTRY
DOEVENTS FORCE
goObj.grid1.Refresh()
DO DcLog WITH 'dump introdc dupa sincronizare #1:'
DO DumpIntrodc
DO VerificaExistaS212Si371 WITH 'pas1-2Srows-dupa-sync1'
DO HarnessStep WITH 2, 'dupa sincronizare #1, introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri'
*========================= PAS 2: partener manual pe S 371, resincronizare, verific persistenta =========================
SELECT introdc
LOCATE FOR tip_rand == 'S' AND ALLTRIM(scd) == '371'
IF FOUND()
REPLACE id_partd WITH 777, partd WITH 'PARTENER MANUAL SRL'
DO DcLog WITH 'am setat manual id_partd=777/partd=PARTENER MANUAL SRL pe randul S 371'
ELSE
DO DcLog WITH 'FAIL setup-pas2: nu am gasit randul S cont=371 dupa sincronizare #1'
ENDIF
TRY
goObj.sincronizeaza()
CATCH TO loExcS2
DO DcLog WITH 'EROARE la sincronizeaza() #2 ' + TRANSFORM(loExcS2.ErrorNo) + ' [' + loExcS2.Message + ']'
ENDTRY
DOEVENTS FORCE
goObj.grid1.Refresh()
DO DcLog WITH 'dump introdc dupa sincronizare #2 (regenerare S-uri):'
DO DumpIntrodc
DO VerificaPartenerPastratDoarPe371 WITH 'pas2-partener-pastrat-dupa-regenerare'
DO HarnessStep WITH 3, 'dupa pas2 (partener manual + resincronizare): introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc'))
*========================= PAS 3: lSyncPending=.T. -> inainte_de_do_termin intoarce .F., introdc neschimbat =========================
LOCAL lnRandInainte3, lnSumaInainte3, llRetTermin3
SELECT introdc
COUNT TO lnRandInainte3 FOR !DELETED()
SELECT SUM(NVL(suma,0)) AS s FROM introdc WHERE !DELETED() INTO CURSOR crsSumaInainte3 NOFILTER
lnSumaInainte3 = NVL(crsSumaInainte3.s, 0)
USE IN crsSumaInainte3
goObj.lSyncPending = .T.
llRetTermin3 = .T.
TRY
llRetTermin3 = goObj.inainte_de_do_termin()
CATCH TO loExcT3
DO DcLog WITH 'EROARE la inainte_de_do_termin() (pas3/lSyncPending) ' + TRANSFORM(loExcT3.ErrorNo) + ' [' + loExcT3.Message + ']'
ENDTRY
DOEVENTS FORCE
LOCAL lnRandDupa3, lnSumaDupa3
SELECT introdc
COUNT TO lnRandDupa3 FOR !DELETED()
SELECT SUM(NVL(suma,0)) AS s FROM introdc WHERE !DELETED() INTO CURSOR crsSumaDupa3 NOFILTER
lnSumaDupa3 = NVL(crsSumaDupa3.s, 0)
USE IN crsSumaDupa3
IF llRetTermin3 = .F. AND lnRandInainte3 = lnRandDupa3 AND ABS(lnSumaInainte3 - lnSumaDupa3) < 0.01
DO DcLog WITH 'PASS pas3-lSyncPending: inainte_de_do_termin a intors .F. si introdc a ramas neschimbat (randuri=' + TRANSFORM(lnRandDupa3) + ' suma=' + TRANSFORM(lnSumaDupa3) + ')'
ELSE
DO DcLog WITH 'FAIL pas3-lSyncPending: llRet=' + TRANSFORM(llRetTermin3) + '(astept .F.) randuriInainte=' + TRANSFORM(lnRandInainte3) + ' randuriDupa=' + TRANSFORM(lnRandDupa3) + ' sumaInainte=' + TRANSFORM(lnSumaInainte3) + ' sumaDupa=' + TRANSFORM(lnSumaDupa3)
ENDIF
DO HarnessStep WITH 4, 'dupa pas3 (lSyncPending=.T.): llRet=' + TRANSFORM(llRetTermin3) + ' introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc'))
*========================= PAS 4: lSyncPending=.F., cmesajsync gol -> trece de gardele noi, fara resincronizare =========================
goObj.lSyncPending = .F.
goObj.cmesajsync = ''
LOCAL llRetTermin4
llRetTermin4 = .F.
TRY
llRetTermin4 = goObj.inainte_de_do_termin()
CATCH TO loExcT4
DO DcLog WITH 'INFO la inainte_de_do_termin() (pas4) ' + TRANSFORM(loExcT4.ErrorNo) + ' [' + loExcT4.Message + '] in ' + loExcT4.Procedure + ':' + TRANSFORM(loExcT4.LineNo) + ' - poate pica mai departe pe alte validari de mediu (afara din scope-ul rundei 22)'
ENDTRY
DOEVENTS FORCE
DO DcLog WITH 'dump introdc dupa pas4 (inainte_de_do_termin cu gardele noi trecute):'
DO DumpIntrodc
*-- verific ca cele doua garde noi nu au blocat apelul (nu a iesit imediat cu .F. pe motivul
*-- vechi de sincronizare) si ca partenerul de la pasul 2 e tot acolo (nu s-a resincronizat).
DO VerificaPartenerPastratDoarPe371 WITH 'pas4-partener-neschimbat-dupa-garda-noua'
DO HarnessStep WITH 5, 'final: introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri'
DO DcLog WITH 'GATA - scenariu executat integral'
DO HarnessDone WITH 'done'
CATCH TO loExc
DO DcLog WITH 'CATCH ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']'
DO HarnessDone WITH 'done-error'
ENDTRY
QUIT
*==================================================================================
PROCEDURE AdaugaDocPrincipal
*-- FACTURA 15000, RAJA, fara DVI (ramura normala 'F') - simplu, ca sa izolam M1/M2.
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = 15000
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 601
goDlg.cPartener = 'RAJA'
goDlg.cExplicatia = 'Achizitie RAJA'
goDlg.nSuma = 1000
goDlg.nSumaLei = 5230
goDlg.nCurs = 5.23
goDlg.nIdValuta = 978
goDlg.cValuta = 'EUR'
goDlg.nIdExplicatieTva = 220
goDlg.cExplicatieTva = 'ACH. IMP. 21%'
goDlg.optTipTva.Value = 1 && F = furnizor (normal)
goDlg.chkInValutaCont.Value = 1
goDlg.chkParticipaValuta.Value = 1
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO DcLog WITH 'DOC principal: valideaza = ' + TRANSFORM(goDlg.valideaza())
DO ConstruiesteToDlg
DO DcLog WITH 'DOC principal: do_adauga_factura = ' + TRANSFORM(goObj.do_adauga_factura(goT))
goDlg.Hide()
DOEVENTS FORCE
ENDPROC
PROCEDURE ConstruiesteToDlg
*-- toDlg construit INLINE (nu intr-o functie apelata din procedura de business) - vezi
*-- docs/testare-ui-vfp.md capcana l; aici functioneaza fiindca goT e PUBLIC (nu return local).
goT = CREATEOBJECT('Empty')
=ADDPROPERTY(goT,'serie_act',ALLTRIM(NVL(goDlg.cSerieAct,'')))
=ADDPROPERTY(goT,'nract',goDlg.nNract)
=ADDPROPERTY(goT,'dataact',goDlg.dDataAct)
=ADDPROPERTY(goT,'fdoc',goDlg.cFelDoc)
=ADDPROPERTY(goT,'id_fdoc',goDlg.nIdFdoc)
=ADDPROPERTY(goT,'id_partc',goDlg.nIdPartener)
=ADDPROPERTY(goT,'partc',goDlg.cPartener)
=ADDPROPERTY(goT,'explicatia',ALLTRIM(NVL(goDlg.cExplicatia,'')))
=ADDPROPERTY(goT,'suma',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,IIF(goDlg.nSumaLei<>0,goDlg.nSumaLei,ROUND(goDlg.nSuma*goDlg.nCurs,gnPC)),goDlg.nSuma))
=ADDPROPERTY(goT,'suma_val',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,goDlg.nSuma,0))
=ADDPROPERTY(goT,'in_valuta',goDlg.chkInValutaCont.Value)
=ADDPROPERTY(goT,'participa_valuta',(goDlg.chkParticipaValuta.Value=1))
=ADDPROPERTY(goT,'id_valuta',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nIdValuta,0))
=ADDPROPERTY(goT,'curs',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nCurs,0))
=ADDPROPERTY(goT,'nume_val',IIF(goDlg.chkInValutaCont.Value=1,ALLTRIM(NVL(goDlg.cValuta,'')),''))
=ADDPROPERTY(goT,'cTipTva',IIF(goDlg.optTipTva.Value=1,'F',IIF(goDlg.optTipTva.Value=2,'D','N')))
=ADDPROPERTY(goT,'id_jtva_coloana',goDlg.nIdExplicatieTva)
=ADDPROPERTY(goT,'dvi_serie','')
=ADDPROPERTY(goT,'dvi_nract',0)
=ADDPROPERTY(goT,'dvi_dataact',{})
=ADDPROPERTY(goT,'dvi_id_fdoc',0)
=ADDPROPERTY(goT,'dvi_fdoc','')
=ADDPROPERTY(goT,'dvi_id_partc',0)
=ADDPROPERTY(goT,'dvi_partc','')
=ADDPROPERTY(goT,'dvi_scc','')
=ADDPROPERTY(goT,'dvi_tva_lei',0)
=ADDPROPERTY(goT,'dvi_tva_val',0)
ENDPROC
PROCEDURE CreeazaRulTemp
*-- structura reala rul_temp (VRUL, Oracle dev) - identica cu test_scenariu_dvi_complet.prg.
IF USED('rul_temp')
USE IN ('rul_temp')
ENDIF
CREATE CURSOR rul_temp ( ;
id_rul N(20,0), an N(4,0), luna N(2,0), cod N(20,0);
, serie C(100), nnir N(20,0), id_articol N(10,0), denumire C(100);
, codmat C(50), codmatf C(50), codbare C(50), um C(20);
, id_gestiune N(5,0), nume_gestiune C(50), cgest C(20), nr_pag N(2,0);
, gestionar C(50), comisie_receptie1 C(50), comisie_receptie2 C(50), comisie_receptie3 C(50);
, cant N(14,3), cante N(14,3), cont C(10), acont C(20);
, pret N(18,4), tva N(18,4), valoare N(18,4), valtva N(18,4);
, proc_tva N(5,2), pretv N(18,4), pretvtva N(18,4), tvav N(18,4);
, valoarev N(18,4), valtvav N(18,4), proc_tvav N(5,2), adaos N(18,4);
, adaos_tva N(18,4), valoare_adaos N(18,4), valtva_adaos N(18,4), procent N(10,3);
, discunitar N(18,4), discount_tva N(18,4), valoare_discount N(18,4), valtva_discount N(18,4);
, proc_disc N(7,3), pretd N(14,4), curs N(18,4), id_valuta N(10,0);
, nume_val C(20), id_lucrare N(20,0), nrord C(100), id_responsabil N(10,0);
, nresp C(100), resp_marca N(18,4), dataact T, id_util N(5,0);
, util C(30), dataora T, id_sectie N(5,0), sectie C(50);
, csectie C(10), alcooltutun N(1,0), datain T, dataout T;
, id_fact N(20,0), id_gestiunec N(10,0), nume_gestiunec C(50), cgestc C(20);
, id_responsabilc N(5,0), id_reteta N(10,0), reteta C(50), nrespc C(100);
, respc_marca N(18,4), id_set N(20,0), id_tip_rulaj N(10,0), tip_rulaj C(50);
, id_obiect_depozit N(10,0), id_rul_aux N(10,0), nract N(20,0), serie_act C(10);
, dataoras T, id_utils N(10,0), lot C(30), adata_expirare T;
, id_sucursala N(5,0), sucursala C(250), id_part_rez N(10,0), part_rez C(100);
, id_lucrare_rez N(10,0), nrord_rez C(100), subgrupa C(100), grupa C(100);
, id_subgrupa N(5,0), id_grupa N(5,0), in_stoc N(1,0), in_crm N(1,0);
, id_furnizor N(10,0), furnizor C(100), id_jtva_coloana N(4,0), explicatie_tva C(100);
, taxcode N(6,0), taxname C(254), saft_procent N(18,4), codnc8 C(20);
, id_tara_origine N(4,0), cod_tara_origine C(5), tara_origine C(50), greutate N(12,4);
, fdoc C(30), id_fdoc N(18,4);
, pret_lei N(18,4), pret_val N(14,4), cota_tva N(6,2))
ENDPROC
PROCEDURE CreeazaIntrodc
LPARAMETERS tcAlias
IF USED(tcAlias)
USE IN (tcAlias)
ENDIF
CREATE CURSOR (tcAlias) ( ;
id_note N(14), explicatia C(100), scd C(10), ascd C(20), scc C(10), ascc C(20), ;
cu_tva N(1), id_set N(14), ordine N(8), in_valuta N(1), id_jtva_coloana N(14) NULL, ;
ptva N(6,2), explicatie_tva C(50), tipjurnal C(2), taxcode N(6), paymentcode C(9), ;
suma N(18,4), suma_val N(18,4), id_partd N(14), id_partc N(14), partd C(100), partc C(100), ;
id_fact N(14), id_factd N(14), id_factc N(14), pereched N(14), perechec N(14), ;
nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), ;
scd_orig C(20), ascd_orig C(20))
ENDPROC
PROCEDURE VerificaExistaS212Si371
*-- (pas1) dupa prima sincronizare, exista exact cate un rand S pentru cont 212 si 371.
LPARAMETERS tcLabel
LOCAL lnSel, lcMsg, llS212, llS371
lnSel = SELECT()
SELECT introdc
LOCATE FOR tip_rand == 'S' AND ALLTRIM(scd) == '212'
llS212 = FOUND()
LOCATE FOR tip_rand == 'S' AND ALLTRIM(scd) == '371'
llS371 = FOUND()
IF llS212 AND llS371
lcMsg = 'PASS ' + tcLabel + ': exista rand S 212 si rand S 371'
ELSE
lcMsg = 'FAIL ' + tcLabel + ': S212?=' + TRANSFORM(llS212) + ' S371?=' + TRANSFORM(llS371)
ENDIF
DO DcLog WITH lcMsg
SELECT (lnSel)
ENDPROC
PROCEDURE VerificaPartenerPastratDoarPe371
*-- (pas2/pas4, M2) partenerul manual (id_partd=777/partd='PARTENER MANUAL SRL') ramane
*-- DOAR pe randul S 371, si NU a migrat/aparut pe randul S 212.
LPARAMETERS tcLabel
LOCAL lnSel, lcMsg, lnIdPartd371, lcPartd371, lnIdPartd212
lnSel = SELECT()
SELECT introdc
LOCATE FOR tip_rand == 'S' AND ALLTRIM(scd) == '371'
IF FOUND()
lnIdPartd371 = NVL(id_partd, 0)
lcPartd371 = ALLTRIM(NVL(partd,''))
ELSE
lnIdPartd371 = -1
lcPartd371 = '?'
ENDIF
LOCATE FOR tip_rand == 'S' AND ALLTRIM(scd) == '212'
IF FOUND()
lnIdPartd212 = NVL(id_partd, 0)
ELSE
lnIdPartd212 = -1
ENDIF
IF lnIdPartd371 = 777 AND lcPartd371 == 'PARTENER MANUAL SRL' AND lnIdPartd212 = 0
lcMsg = 'PASS ' + tcLabel + ': S371(id_partd=' + TRANSFORM(lnIdPartd371) + ' partd=[' + lcPartd371 + ']) S212(id_partd=' + TRANSFORM(lnIdPartd212) + ', neatins)'
ELSE
lcMsg = 'FAIL ' + tcLabel + ': S371(id_partd=' + TRANSFORM(lnIdPartd371) + ', astept 777; partd=[' + lcPartd371 + '], astept [PARTENER MANUAL SRL]) S212(id_partd=' + TRANSFORM(lnIdPartd212) + ', astept 0)'
ENDIF
DO DcLog WITH lcMsg
SELECT (lnSel)
ENDPROC
PROCEDURE DumpIntrodc
LOCAL lnSel
lnSel = SELECT()
SELECT introdc
SCAN
DO DcLog WITH ' recno=' + TRANSFORM(RECNO()) + ' nr_doc=' + TRANSFORM(NVL(nr_doc,0)) + ' nract=' + TRANSFORM(nract) + ' fdoc=[' + ALLTRIM(NVL(fdoc,'')) + '] tip_rand=' + tip_rand + ;
' scd=' + ALLTRIM(scd) + ' ascd=[' + ALLTRIM(NVL(ascd,'')) + '] scc=' + ALLTRIM(scc) + ' suma=' + TRANSFORM(suma) + ' suma_val=' + TRANSFORM(suma_val) + ;
' id_partd=' + TRANSFORM(NVL(id_partd,0)) + ' partd=[' + ALLTRIM(NVL(partd,'')) + '] doc_key=[' + ALLTRIM(doc_key) + ']'
ENDSCAN
SELECT (lnSel)
ENDPROC
FUNCTION RECCOUNT_ACTIVE
LPARAMETERS tcAlias
LOCAL lnSel, lnCnt
lnSel = SELECT()
SELECT (tcAlias)
COUNT TO lnCnt FOR !DELETED()
SELECT (lnSel)
RETURN lnCnt
ENDFUNC
PROCEDURE DcErr
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
DO DcLog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
ENDPROC
PROCEDURE DcLog
LPARAMETERS tcMsg
SET SAFETY OFF
LOCAL lcL
lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '')
STRTOFILE(lcL + tcMsg + CHR(13)+CHR(10), gcUILog)
ENDPROC
DEFINE CLASS dummyapp AS Custom
PROCEDURE ReadIni
LPARAMETERS tcSection, tcKey
RETURN ''
ENDPROC
PROCEDURE WriteIni
LPARAMETERS tcSection, tcKey, tcValue
RETURN .T.
ENDPROC
ENDDEFINE
DEFINE CLASS dummyexecutor AS Custom
cEroare = ''
PROCEDURE oExecute
LPARAMETERS tcSql, tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
*-- update_jtva_coloane (SELECT * FROM vjtva_coloane ...): mock cu date reale.
IF 'VJTVA_COLOANE' $ UPPER(m.tcSql)
DO CreeazaJtvaColoaneView WITH m.tcCursor
RETURN 1
ENDIF
*-- rul_temp (recreat de import_nota.Init din vrul cand e gol): structura completa.
IF UPPER(ALLTRIM(m.tcCursor)) == 'RUL_TEMP'
CREATE CURSOR (m.tcCursor) (denumire C(100), codmat C(30), cant N(14,3), ;
pret_val N(18,4), pretd N(18,4), pret N(18,4), pret_lei N(18,4), cont C(10), ;
acont C(20), serie C(30), lot C(30), adata_expirare C(10), proc_disc N(6,2), cota_tva N(6,2))
RETURN 1
ENDIF
*-- assign_analitic (creeaza_rand_s / do_adauga_articol): config_analitice - prefix/sufix goale,
*-- deci acont-ul vine direct din fconturi_analitice (mai jos), controlat de gcMockAcontCrt.
IF 'CONFIG_ANALITICE' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (camp_leg_prefix C(30), camp_leg_sufix C(30))
INSERT INTO (m.tcCursor) VALUES ('', '')
RETURN 1
ENDIF
*-- fconturi_analitice: acont-ul curent, setat explicit de test (gcMockAcontCrt) inainte de
*-- fiecare do_adauga_articol() - simplu si deterministic, fara sa depinda de binding real.
IF 'FCONTURI_ANALITICE' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (acont C(20))
INSERT INTO (m.tcCursor) VALUES (IIF(TYPE('gcMockAcontCrt') = 'C', gcMockAcontCrt, ''))
RETURN 1
ENDIF
*-- vplcont_analitic: validare analitic vs plan de conturi - un rand => acontul e "valid".
IF 'VPLCONT_ANALITIC' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (cont C(10), acont C(20))
INSERT INTO (m.tcCursor) VALUES ('212', '1')
INSERT INTO (m.tcCursor) VALUES ('371', '4')
RETURN 1
ENDIF
*-- vconfig_cont_ireg (verificare_note_contabile, ooperatii_comune.prg): un rand gasit per
*-- cont folosit in test - altfel codul reseteaza necondiitionat id_partd/id_partc pe toate
*-- randurile (ramura "cont neconfigurat"), stergand partenerul manual testat in pasii 2/4.
IF 'VCONFIG_CONT_IREG' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (contpart C(10), fel_cont N(1), cu_inregistrari N(1), ;
explic_cont C(100), exceptie C(10), pozitie N(1), invers N(1), gasit N(1))
INSERT INTO (m.tcCursor) VALUES ('212', 0, 0, '', '', 0, 0, 0)
INSERT INTO (m.tcCursor) VALUES ('371', 0, 0, '', '', 0, 0, 0)
INSERT INTO (m.tcCursor) VALUES ('4426', 0, 0, '', '', 0, 0, 0)
INSERT INTO (m.tcCursor) VALUES ('401', 0, 0, '', '', 0, 0, 0)
RETURN 1
ENDIF
*-- ramura generica: cursor gol (nu afecteaza fluxurile testate mai sus).
CREATE CURSOR (m.tcCursor) (id_temp N(1))
RETURN 1
ENDPROC
PROCEDURE oExecuta
LPARAMETERS tcSql, tcCursor
IF !EMPTY(m.tcCursor)
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF UPPER(m.tcCursor) == 'CJTVACOL4427'
*-- coloana_jc 'FO21T' (import) NU se potriveste patternurilor TI%T/XX%TIT/CE%T -
*-- cursor gol => scc ramane '401' (nu 4427) - vezi Init:11251-11258.
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14))
ELSE
CREATE CURSOR (m.tcCursor) (id_temp N(1))
ENDIF
ENDIF
RETURN .T.
ENDPROC
PROCEDURE oSelect2Value
LPARAMETERS tcSql, toValue
toValue = ''
RETURN 1
ENDPROC
PROCEDURE oReset
ENDPROC
ENDDEFINE
PROCEDURE CreeazaJtvaColoaneView
LPARAMETERS tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14), denumire C(100), jc N(1), jv N(1), ;
coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14) NULL, afisat N(1), ;
id_jtva_ex N(14) NULL, id_jtva_neex N(14) NULL, ordine N(8), ;
taxcode N(6) NULL, taxcode_neexigibil N(6) NULL, taxcode_n50 N(6) NULL, ;
taxcode_n50_tvai N(6) NULL, taxcode_n100 N(6) NULL, taxcode_regularizare N(6) NULL, taxcode_tvai N(6) NULL)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, afisat, ordine, cota_tva) VALUES (0, '', 0, 0, 1, 0, 0)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (208, 'ACH. INT. 21%', 1, 0, 'RO21B', 21, 209, 1, 1, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (209, 'TVA ACH. INT. 21%', 1, 0, 'RO21T', 21, 1, 2, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (220, 'ACH. IMP. 21%', 1, 0, 'FO21B', 21, 221, 1, 3, 301204)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (221, 'TVA ACH. IMP. 21%', 1, 0, 'FO21T', 21, 1, 4, 301204)
ENDPROC

View File

@@ -0,0 +1,14 @@
# test_termin_partener.ps1 - wrapper peste harness-ul generic pentru scenariul rundei 22
# (COMUN\clase\ointroduceri.vcx, import_nota): inainte_de_do_termin fara sincronizare
# automata (garda lSyncPending/cmesajsync) + sparge_document pastreaza partenerul debit
# manual pe randurile S la regenerare. Rulare:
# powershell -ExecutionPolicy Bypass -File test_termin_partener.ps1
$ErrorActionPreference = 'Stop'
$Teste = $PSScriptRoot
& (Join-Path (Split-Path $Teste -Parent) 'vfp_ui_harness.ps1') `
-TestPrg (Join-Path $Teste 'test_termin_partener.prg') `
-Steps @('doc_principal','articole_adaugate','sync1_2Srows','partener_manual_sync2','lSyncPending_blocheaza','final_garda_noua') `
-ShotsDir (Join-Path $Teste 'screenshots_termin_partener') `
-SyncDir (Join-Path $Teste 'uisync_termin_partener') `
-StepTimeoutSec 180 `
-ReadyTimeoutSec 180

View File

@@ -0,0 +1,753 @@
* test_tva_creditori.prg
* Test UI (runda27) pentru clasa IMPORT_nota (COMUN\clase\ointroduceri.vcx): T-urile de TVA se
* grupeaza pe cota + creditorul (scc/ascc) preluat de la S-urile corespunzatoare contului
* articolului (calc_baze_cota_creditor, D3/D6), iar editarea manuala a scc pe un rand S prin
* Grid1.cScc.Text1 (GotFocus/Valid) rearmeaza sincronizarea si "muta" TVA-ul aferent bazei pe
* noul creditor; editarea persista la resincronizari ulterioare (crsSccS, D2).
* Vezi docs/handoff_runda26_tva_sincronizare.md pct.3.
*
* Scenariu (flux REAL, nu Append direct in cursoare):
* 1. FACTURA 15000 (partener test), 1000 EUR + TVA (cota 21%), curs 5.23, in_valuta=1 - prin
* goObj.do_adauga_factura(toDlg). 2 articole prin FLUXUL REAL goObj.do_adauga_articol():
* ART-A8-371 (cont 371, baza 700 EUR) si ART-BULD-212 (cont 212, baza 300 EUR).
* 2. Dupa sincronizare#1: ambele S-uri mostenesc scc=401 din sablon (B) - un singur T (scc=401).
* Apoi editez manual S(212).scc: 401 -> '404' prin Grid1.cScc.Text1 (GotFocus seteaza
* Thisform.nOldVal, apoi This.Value + Valid() - metoda REALA, nu replicare manuala) si
* declansez resincronizarea (goObj.sincronizeaza(), ca la F5 - vezi test_manual_tva_footer).
* Assert: DOUA randuri T 4426 - scc=401 cu suma_val=baza(371)*21/100=147, scc=404 cu
* suma_val=baza(212)*21/100=63; suma lor = total(1000)*21% = 210 (rotunjire reziduala D5).
* 3. Editez din nou S(212).scc: '404' -> '405' (acelasi tipar GotFocus/Value/Valid), resincronizare.
* Assert: T-ul aferent bazei 212 are acum scc=405 (TVA "s-a mutat"), suma_val neschimbata (63);
* T-ul aferent bazei 371 (scc=401) neschimbat.
* 4. Persistenta: mai editez cantitatea articolului 371 (pret_val 700->710) prin rul_temp +
* goObj.sincronizeaza() (F5), fara sa mai ating scc. Assert: S(212).scc ramane '405', T-ul lui
* ramane scc=405 (mecanismul crsSccS pastreaza editarea la fiecare regenerare a S-urilor).
*
* Rulare (prin harness):
* powershell -ExecutionPolicy Bypass -File test_tva_creditori.ps1
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET DECIMALS TO 4
SET NULLDISPLAY TO ''
CLOSE DATABASES
PUBLIC gcUILog, gcSyncDir
gcUILog = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\test_tva_creditori_log.txt"
gcSyncDir = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\uisync_tva_creditori\"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcUILog)
ON ERROR DO TfErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
TRY
LOCAL gcAppPath, lcPath
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;' + ;
ADDBS(SUBSTR(gcAppPath,1,RAT([\],gcAppPath,2)))+[COMUNROA\]
SET PATH TO &lcPath ADDITIVE
DO TfLog WITH 'SET PATH OK'
*----- CLASE -----
SET CLASSLIB TO (gcAppPath + "comun\clase\appwiz") 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 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 wwdialogs.vcx ADDITIVE
SET CLASSLIB TO oimportxml.vcx ADDITIVE
SET CLASSLIB TO excelxml.vcx ADDITIVE
SET CLASSLIB TO orapoarte_obinv.vcx ADDITIVE
DO TfLog WITH 'SET CLASSLIB OK'
*----- PROCEDURI (mock amessagebox + mock cauta_nom_articole PRIMELE, ui_harness la final) -----
SET PROCEDURE TO PROCEDURI
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_cauta_nom_articole.prg" 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 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 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 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
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\ui_harness.prg" ADDITIVE
DO TfLog WITH 'SET PROCEDURE OK'
*----- Globale -----
PUBLIC gnPc, gnPval, gnPcant, gnPpret, gnPPretval, gnPCurs, gnPVal, gnPPretV, gnPPretVal
STORE 2 TO gnPc, gnPval, gnPVal
gnPcant = 3
STORE 4 TO gnPpret, gnPPretval, gnPPretVal, gnPPretV, gnPCurs
PUBLIC gl406, gcS, gnAn, gnLuna, gnIdFirma, gnIdSucursala, gcAcces, gcFirma
gl406 = .T.
gcS = 'CONTAFIN'
gnAn = YEAR(DATE())
gnLuna = MONTH(DATE())
gnIdFirma = 110
gnIdSucursala = 110
gcAcces = "1;2;3;4;5;6;7;8;"
gcFirma = gcS
PUBLIC nror(65000)
PUBLIC gnButon
STORE 2 TO gnButon
PUBLIC goExecutor, goApp
goExecutor = CREATEOBJECT('dummyexecutor')
goApp = CREATEOBJECT('dummyapp')
*----- poAct: antetul notei; dialogul mosteneste din el la Init -----
PUBLIC poAct
poAct = CREATEOBJECT('Custom')
poAct.AddProperty('nume_val', '')
poAct.AddProperty('curs', 1)
poAct.AddProperty('proc_tva', 1.21)
poAct.AddProperty('nnir', 0)
poAct.AddProperty('id_valuta', 0)
poAct.AddProperty('id_fdoc', 1)
poAct.AddProperty('fdoc', 'Factura')
poAct.AddProperty('id_partc', 500)
poAct.AddProperty('partc', 'FURNIZOR ANTET SRL')
poAct.AddProperty('serie_act', '')
poAct.AddProperty('dataact', DATE())
poAct.AddProperty('tva_incasare', 0)
poAct.AddProperty('id_set', 1)
poAct.AddProperty('id_gestin', 1)
*----- jtva_coloane2 (explicatii TVA): achizitii interne 21% - perechea folosita de sablon -----
IF USED('jtva_coloane2')
USE IN ('jtva_coloane2')
ENDIF
CREATE CURSOR jtva_coloane2 (ordine N(8), id_jtva_coloana N(14), denumire C(100), ;
jc N(1), jv N(1), afisat N(1), coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14))
INSERT INTO jtva_coloane2 VALUES (0, 0, '', 0, 0, 1, '', '', 0, 0)
INSERT INTO jtva_coloane2 VALUES (1, 208, 'ACH. INT. 21%', 1, 0, 1, 'RO21B', 'RO21T', 21, 209)
INSERT INTO jtva_coloane2 VALUES (2, 209, 'TVA ACH. INT. 21%', 1, 0, 1, 'RO21T', '', 21, 0)
*----- saft_taxtable: coduri reale (vsaft_taxtable) - achizitii interne 21% -----
IF USED('saft_taxtable')
USE IN ('saft_taxtable')
ENDIF
CREATE CURSOR saft_taxtable (taxname C(250) NULL, typename C(250) NULL, taxcode N(6) NULL, ;
taxtype N(3) NULL, descriere C(250) NULL, tip C(100) NULL, descriere_tip C(250) NULL, ;
procent_taxa N(7,2) NULL, procent_prorata N(7,2) NULL, inactiv N(1) NULL, tva N(1) NULL, ;
wht N(1) NULL, tva_achizitii N(1) NULL, tva_livrari N(1) NULL)
INDEX ON taxcode TAG taxcode
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('', 0, '', 0, 1, 1, 1, 1)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301104-Achizitii de bunuri si servicii taxabile cu cota de 21%, altele decat importurile si cele supuse masurilor de simplificare', 301104, '', 21, 1, 0, 1, 0)
*----- introdc (RecordSource Grid1) - porneste GOL, ca in fluxul real -----
DO CreeazaIntrodc WITH 'introdc'
*----- introdc_sablon: perechea-sablon (B 371/401 + T 4426/401) pe care do_adauga_factura o
* cloneaza (21%, ACH. INT. 21%). -----
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%')
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%')
GO TOP IN introdc_sablon
*----- rul_temp cu 1 rand INAINTE de instantiere (capcana k) - structura FIDELA VRUL. -----
DO CreeazaRulTemp
INSERT INTO rul_temp (denumire, codmat, cant, pret, pret_lei, cont, cota_tva) ;
VALUES ('PLACEHOLDER', 'PH', 1, 1, 1, '371', 21)
DO TfLog WITH 'cursoare pregatite, CREATEOBJECT(import_nota, .F.) - lIntern=.F. (import)'
SELECT introdc
PUBLIC goObj
goObj = CREATEOBJECT('IMPORT_nota', .F.)
IF VARTYPE(goObj) <> 'O'
DO TfLog WITH 'FAIL: instantiere import_nota'
DO HarnessDone WITH 'done-error'
QUIT
ENDIF
goObj.lDialogAratat = .T.
goObj.oact = poAct
goObj.WindowType = 0
goObj.Visible = .T.
goObj.Show()
goObj.WindowState = 2
DOEVENTS FORCE
*-- golesc placeholder-ul cu ZAP (nu DELETE ALL, capcana k)
SELECT rul_temp
ZAP
goObj.gridart.Refresh()
DOEVENTS FORCE
*========================= DOC: FACTURA 15000, 1000 EUR + TVA, curs 5.23, in_valuta=1 =========================
PUBLIC goDlg, goT
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = 15000
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 700
goDlg.cPartener = 'PARTENER TEST SRL'
goDlg.cExplicatia = 'Factura test TVA creditori'
goDlg.nSuma = 1000
goDlg.nSumaLei = 0
goDlg.nCurs = 5.23
goDlg.nIdValuta = 978
goDlg.cValuta = 'EUR'
*-- ACH. INT. 21% (id 208) - achizitie normala, TVA la furnizor (F), fara DVI
goDlg.nIdExplicatieTva = 208
goDlg.cExplicatieTva = 'ACH. INT. 21%'
goDlg.optTipTva.Value = 1 && F = furnizor
goDlg.chkInValutaCont.Value = 1
goDlg.chkParticipaValuta.Value = 1
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO TfLog WITH 'DOC: valideaza (pe dialog) = ' + TRANSFORM(goDlg.valideaza())
DO ConstruiesteToDlg
DO TfLog WITH 'DOC: do_adauga_factura = ' + TRANSFORM(goObj.do_adauga_factura(goT))
goDlg.Hide()
DOEVENTS FORCE
LOCAL llB, llT
SELECT introdc
LOCATE FOR nract = 15000 AND tip_rand == 'B'
llB = FOUND()
LOCATE FOR nract = 15000 AND tip_rand == 'T'
llT = FOUND()
IF llB AND llT
DO TfLog WITH 'PASS pas0: factura 15000 adaugata (B+T)'
ELSE
DO TfLog WITH 'FAIL pas0: B?=' + TRANSFORM(llB) + ' T?=' + TRANSFORM(llT)
ENDIF
*========================= PAS 0: factura principala adaugata =========================
DO HarnessStep WITH 0, 'factura 15000 adaugata: introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri (astept 2, B+T)'
*========================= ADAUGARE 2 ARTICOLE PRIN FLUXUL REAL: do_adauga_articol() =========================
*-- ART-A8-371 (cont 371, baza 700 EUR) + ART-BULD-212 (cont 212, baza 300 EUR)
PUBLIC gcMockArtCodmat
gcMockArtCodmat = 'ART-A8-371'
goObj.do_adauga_articol()
DOEVENTS FORCE
SELECT rul_temp
LOCATE FOR ALLTRIM(codmat) == 'ART-A8-371'
IF FOUND()
REPLACE cant WITH 1, pret_val WITH 700, pretd WITH 700, pret WITH ROUND(700*5.23,gnPc), pret_lei WITH pret
DO TfLog WITH 'articol 1 (ART-A8-371, cont 371) adaugat prin do_adauga_articol() REAL, baza 700 EUR'
ELSE
DO TfLog WITH 'FAIL: ART-A8-371 nu a fost gasit in rul_temp dupa do_adauga_articol()'
ENDIF
gcMockArtCodmat = 'ART-BULD-212'
goObj.do_adauga_articol()
DOEVENTS FORCE
SELECT rul_temp
LOCATE FOR ALLTRIM(codmat) == 'ART-BULD-212'
IF FOUND()
REPLACE cant WITH 1, pret_val WITH 300, pretd WITH 300, pret WITH ROUND(300*5.23,gnPc), pret_lei WITH pret
DO TfLog WITH 'articol 2 (ART-BULD-212, cont 212) adaugat prin do_adauga_articol() REAL, baza 300 EUR'
ELSE
DO TfLog WITH 'FAIL: ART-BULD-212 nu a fost gasit in rul_temp dupa do_adauga_articol()'
ENDIF
goObj.gridart.Refresh()
DOEVENTS FORCE
goObj.sincronizeaza()
DOEVENTS FORCE
goObj.grid1.Refresh()
DOEVENTS FORCE
DO TfLog WITH 'DIAG dump introdc dupa sincronizare#1:'
DO DumpIntrodc
*-- VERIFICARE sincronizare#1: 2 S-uri (371=700, 212=300), scc mostenit din sablon (401) pe
*-- amandoua -> un singur T (scc=401), suma_val=1000*21/100=210
LOCAL llS371a, llS212a, lnS371ScdA, lnS212ScdA, lcS371SccA, lcS212SccA
SELECT introdc
LOCATE FOR tip_rand == 'S' AND ALLTRIM(scd) == '371'
llS371a = FOUND()
IF llS371a
lcS371SccA = ALLTRIM(NVL(scc,''))
ENDIF
LOCATE FOR tip_rand == 'S' AND ALLTRIM(scd) == '212'
llS212a = FOUND()
IF llS212a
lcS212SccA = ALLTRIM(NVL(scc,''))
ENDIF
LOCAL lnCntTa, lnTSumaValA
SELECT introdc
COUNT FOR tip_rand == 'T' AND ALLTRIM(scd) == '4426' TO lnCntTa
LOCATE FOR tip_rand == 'T' AND ALLTRIM(scd) == '4426'
lnTSumaValA = suma_val
IF llS371a AND llS212a AND lcS371SccA == '401' AND lcS212SccA == '401' AND lnCntTa = 1 AND ABS(lnTSumaValA - 210) < 0.01
DO TfLog WITH 'PASS pas1 sincronizare#1: S371.scc=401 S212.scc=401 (mostenit din sablon), 1 rand T, suma_val=' + TRANSFORM(lnTSumaValA) + ' (astept 210)'
ELSE
DO TfLog WITH 'FAIL pas1 sincronizare#1: S371.scc=' + lcS371SccA + ' S212.scc=' + lcS212SccA + ' nrT=' + TRANSFORM(lnCntTa) + ' T.suma_val=' + TRANSFORM(lnTSumaValA) + ' (astept 401/401/1/210)'
ENDIF
*========================= PAS 1: dupa sincronizare#1 (T unic, scc=401) =========================
DO HarnessStep WITH 1, 'sincronizare#1: S371.scc=' + lcS371SccA + ' S212.scc=' + lcS212SccA + ' nrT=' + TRANSFORM(lnCntTa) + ' T.suma_val=' + TRANSFORM(lnTSumaValA)
*========================= PAS 2: editare manuala S(212).scc 401 -> 404, prin Grid1.cScc.Text1 =========================
SELECT introdc
LOCATE FOR tip_rand == 'S' AND ALLTRIM(scd) == '212'
GO RECNO()
*-- GotFocus REAL: seteaza Thisform.nOldVal = valoarea curenta a celulei (tiparul din
*-- test_import_nota_total_ui / test_manual_tva_footer)
goObj.Grid1.cScc.Text1.Value = scc
goObj.Grid1.cScc.Text1.GotFocus()
DO TfLog WITH 'dupa GotFocus real pe S(212).cScc: Thisform.nOldVal=' + TRANSFORM(goObj.nOldVal) + ' (astept 401)'
goObj.Grid1.cScc.Text1.Value = '404'
TRY
goObj.Grid1.cScc.Text1.Valid()
DO TfLog WITH 'PASS apel REAL: Grid1.cScc.Text1.Valid() executat direct (fara replicare manuala)'
CATCH TO loExc2
DO TfLog WITH 'PAS2 EROARE ' + TRANSFORM(loExc2.ErrorNo) + ' [' + loExc2.Message + '] in ' + loExc2.Procedure + ':' + TRANSFORM(loExc2.LineNo) + ' (' + loExc2.LineContents + ')'
ENDTRY
DOEVENTS FORCE
*-- F5 (rearmare directa a resincronizarii, ca in test_manual_tva_footer): lSyncPending armat
*-- de Valid, dar in headless nu astept tmrSync - apelez direct sincronizeaza()
goObj.sincronizeaza()
DOEVENTS FORCE
goObj.grid1.Refresh()
DOEVENTS FORCE
DO TfLog WITH 'DIAG dump introdc dupa scc 401->404 pe S(212) + resincronizare:'
DO DumpIntrodc
*-- VERIFICARE: 2 randuri T 4426 - scc=401 (baza 371=700, suma_val=147) si scc=404 (baza
*-- 212=300, suma_val=63); suma lor = 1000*21% = 210 (rotunjire reziduala D5)
LOCAL llT401b, llT404b, lnT401ValB, lnT404ValB, lnCntTb
SELECT introdc
COUNT FOR tip_rand == 'T' AND ALLTRIM(scd) == '4426' TO lnCntTb
LOCATE FOR tip_rand == 'T' AND ALLTRIM(scd) == '4426' AND ALLTRIM(NVL(scc,'')) == '401'
llT401b = FOUND()
IF llT401b
lnT401ValB = suma_val
ENDIF
LOCATE FOR tip_rand == 'T' AND ALLTRIM(scd) == '4426' AND ALLTRIM(NVL(scc,'')) == '404'
llT404b = FOUND()
IF llT404b
lnT404ValB = suma_val
ENDIF
IF lnCntTb = 2 AND llT401b AND llT404b AND ABS(lnT401ValB - 147) < 0.01 AND ABS(lnT404ValB - 63) < 0.01
DO TfLog WITH 'PASS pas2 split creditori: T(scc=401).suma_val=' + TRANSFORM(lnT401ValB) + ' (astept 147) T(scc=404).suma_val=' + TRANSFORM(lnT404ValB) + ' (astept 63)'
ELSE
DO TfLog WITH 'FAIL pas2 split creditori: nrT=' + TRANSFORM(lnCntTb) + ' T401?=' + TRANSFORM(llT401b) + '(val=' + TRANSFORM(IIF(llT401b,lnT401ValB,-1)) + ') T404?=' + TRANSFORM(llT404b) + '(val=' + TRANSFORM(IIF(llT404b,lnT404ValB,-1)) + ')'
ENDIF
LOCAL lnSumaTb
lnSumaTb = IIF(llT401b,lnT401ValB,0) + IIF(llT404b,lnT404ValB,0)
IF ABS(lnSumaTb - ROUND(1000*21/100,gnPval)) < 0.01
DO TfLog WITH 'PASS pas2 suma T-uri = total*21%: suma=' + TRANSFORM(lnSumaTb) + ' (astept ' + TRANSFORM(ROUND(1000*21/100,gnPval)) + ')'
ELSE
DO TfLog WITH 'FAIL pas2 suma T-uri != total*21%: suma=' + TRANSFORM(lnSumaTb) + ' (astept ' + TRANSFORM(ROUND(1000*21/100,gnPval)) + ')'
ENDIF
*========================= PAS 2: dupa split creditori (scc 401 vs 404) =========================
DO HarnessStep WITH 2, 'split creditori: T(401).suma_val=' + TRANSFORM(IIF(llT401b,lnT401ValB,-1)) + ' T(404).suma_val=' + TRANSFORM(IIF(llT404b,lnT404ValB,-1)) + ' suma=' + TRANSFORM(lnSumaTb)
*========================= PAS 3: editare manuala S(212).scc 404 -> 405 (TVA "se muta") =========================
SELECT introdc
LOCATE FOR tip_rand == 'S' AND ALLTRIM(scd) == '212'
GO RECNO()
goObj.Grid1.cScc.Text1.Value = scc
goObj.Grid1.cScc.Text1.GotFocus()
DO TfLog WITH 'dupa GotFocus real pe S(212).cScc (pas3): Thisform.nOldVal=' + TRANSFORM(goObj.nOldVal) + ' (astept 404)'
goObj.Grid1.cScc.Text1.Value = '405'
TRY
goObj.Grid1.cScc.Text1.Valid()
DO TfLog WITH 'PASS apel REAL pas3: Grid1.cScc.Text1.Valid() executat direct'
CATCH TO loExc3
DO TfLog WITH 'PAS3 EROARE ' + TRANSFORM(loExc3.ErrorNo) + ' [' + loExc3.Message + '] in ' + loExc3.Procedure + ':' + TRANSFORM(loExc3.LineNo) + ' (' + loExc3.LineContents + ')'
ENDTRY
DOEVENTS FORCE
goObj.sincronizeaza()
DOEVENTS FORCE
goObj.grid1.Refresh()
DOEVENTS FORCE
DO TfLog WITH 'DIAG dump introdc dupa scc 404->405 pe S(212) + resincronizare:'
DO DumpIntrodc
LOCAL llT401c, llT405c, lnT401ValC, lnT405ValC, lnCntTc
SELECT introdc
COUNT FOR tip_rand == 'T' AND ALLTRIM(scd) == '4426' TO lnCntTc
LOCATE FOR tip_rand == 'T' AND ALLTRIM(scd) == '4426' AND ALLTRIM(NVL(scc,'')) == '401'
llT401c = FOUND()
IF llT401c
lnT401ValC = suma_val
ENDIF
LOCATE FOR tip_rand == 'T' AND ALLTRIM(scd) == '4426' AND ALLTRIM(NVL(scc,'')) == '405'
llT405c = FOUND()
IF llT405c
lnT405ValC = suma_val
ENDIF
IF lnCntTc = 2 AND llT401c AND llT405c AND ABS(lnT401ValC - 147) < 0.01 AND ABS(lnT405ValC - 63) < 0.01
DO TfLog WITH 'PASS pas3 TVA mutat pe scc=405: T(scc=401).suma_val=' + TRANSFORM(lnT401ValC) + ' (neschimbat) T(scc=405).suma_val=' + TRANSFORM(lnT405ValC) + ' (astept 63, fostul scc=404)'
ELSE
DO TfLog WITH 'FAIL pas3 TVA mutat pe scc=405: nrT=' + TRANSFORM(lnCntTc) + ' T401?=' + TRANSFORM(llT401c) + '(val=' + TRANSFORM(IIF(llT401c,lnT401ValC,-1)) + ') T405?=' + TRANSFORM(llT405c) + '(val=' + TRANSFORM(IIF(llT405c,lnT405ValC,-1)) + ')'
ENDIF
*========================= PAS 3: dupa mutarea creditorului 404 -> 405 =========================
DO HarnessStep WITH 3, 'TVA mutat: T(401).suma_val=' + TRANSFORM(IIF(llT401c,lnT401ValC,-1)) + ' T(405).suma_val=' + TRANSFORM(IIF(llT405c,lnT405ValC,-1))
*========================= PAS 4: persistenta - editare cantitate/pret articol 371, resincronizare =========================
*-- editare REALA prin rul_temp (cantitate/pret articol, ca la test_import_nota_ui pas
*-- recalculeaza) + sincronizeaza() (F5); scc-ul S(212) NU mai e atins acum - trebuie sa
*-- persiste prin crsSccS (D2) la regenerarea S-urilor.
SELECT rul_temp
LOCATE FOR ALLTRIM(codmat) == 'ART-A8-371'
IF FOUND()
REPLACE pret_val WITH 710, pretd WITH 710, pret WITH ROUND(710*5.23,gnPc), pret_lei WITH pret
DO TfLog WITH 'articol 371 baza 700->710 EUR (editare cantitate/pret, flux real)'
ELSE
DO TfLog WITH 'FAIL: ART-A8-371 negasit pentru editarea de persistenta'
ENDIF
goObj.gridart.Refresh()
DOEVENTS FORCE
goObj.sincronizeaza()
DOEVENTS FORCE
goObj.grid1.Refresh()
DOEVENTS FORCE
DO TfLog WITH 'DIAG dump introdc dupa editare baza 371 (persistenta scc):'
DO DumpIntrodc
LOCAL lcS212SccD, llT405d, lnT405ValD, lnT401ValD
SELECT introdc
LOCATE FOR tip_rand == 'S' AND ALLTRIM(scd) == '212'
lcS212SccD = ALLTRIM(NVL(scc,''))
LOCATE FOR tip_rand == 'T' AND ALLTRIM(scd) == '4426' AND ALLTRIM(NVL(scc,'')) == '405'
llT405d = FOUND()
IF llT405d
lnT405ValD = suma_val
ENDIF
LOCATE FOR tip_rand == 'T' AND ALLTRIM(scd) == '4426' AND ALLTRIM(NVL(scc,'')) == '401'
IF FOUND()
lnT401ValD = suma_val
ENDIF
IF lcS212SccD == '405' AND llT405d AND ABS(lnT405ValD - 63) < 0.01
DO TfLog WITH 'PASS pas4 persistenta: S(212).scc=' + lcS212SccD + ' (ramas 405 dupa resincronizare), T(scc=405).suma_val=' + TRANSFORM(lnT405ValD) + ' (neschimbat, 63)'
ELSE
DO TfLog WITH 'FAIL pas4 persistenta: S(212).scc=' + lcS212SccD + ' (astept 405) T405?=' + TRANSFORM(llT405d) + '(val=' + TRANSFORM(IIF(llT405d,lnT405ValD,-1)) + ')'
ENDIF
IF ABS(lnT401ValD - ROUND(710*21/100,gnPval)) < 0.01
DO TfLog WITH 'PASS pas4 T(401) recalculat cu noua baza 371 (710): suma_val=' + TRANSFORM(lnT401ValD) + ' (astept ' + TRANSFORM(ROUND(710*21/100,gnPval)) + ')'
ELSE
DO TfLog WITH 'FAIL pas4 T(401) nerecalculat: suma_val=' + TRANSFORM(lnT401ValD) + ' (astept ' + TRANSFORM(ROUND(710*21/100,gnPval)) + ')'
ENDIF
*========================= PAS 4: dupa persistenta creditorului 405 =========================
DO HarnessStep WITH 4, 'persistenta: S(212).scc=' + lcS212SccD + ' T(405).suma_val=' + TRANSFORM(IIF(llT405d,lnT405ValD,-1)) + ' T(401).suma_val=' + TRANSFORM(lnT401ValD)
DO TfLog WITH 'GATA - scenariu runda27 (TVA pe creditori) executat integral'
DO HarnessDone WITH 'done'
CATCH TO loExc
DO TfLog WITH 'CATCH ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']'
DO HarnessDone WITH 'done-error'
ENDTRY
QUIT
*==================================================================================
PROCEDURE ConstruiesteToDlg
*-- toDlg construit INLINE in programul PRINCIPAL (ADDPROPERTY da eroare 11 din proceduri in
*-- acest runtime headless - vezi docs/testare-ui-vfp.md capcana l).
goT = CREATEOBJECT('Empty')
=ADDPROPERTY(goT,'serie_act',ALLTRIM(NVL(goDlg.cSerieAct,'')))
=ADDPROPERTY(goT,'nract',goDlg.nNract)
=ADDPROPERTY(goT,'dataact',goDlg.dDataAct)
=ADDPROPERTY(goT,'fdoc',goDlg.cFelDoc)
=ADDPROPERTY(goT,'id_fdoc',goDlg.nIdFdoc)
=ADDPROPERTY(goT,'id_partc',goDlg.nIdPartener)
=ADDPROPERTY(goT,'partc',goDlg.cPartener)
=ADDPROPERTY(goT,'explicatia',ALLTRIM(NVL(goDlg.cExplicatia,'')))
=ADDPROPERTY(goT,'suma',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,IIF(goDlg.nSumaLei<>0,goDlg.nSumaLei,ROUND(goDlg.nSuma*goDlg.nCurs,gnPC)),goDlg.nSuma))
=ADDPROPERTY(goT,'suma_val',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,goDlg.nSuma,0))
=ADDPROPERTY(goT,'in_valuta',goDlg.chkInValutaCont.Value)
=ADDPROPERTY(goT,'participa_valuta',(goDlg.chkParticipaValuta.Value=1))
=ADDPROPERTY(goT,'id_valuta',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nIdValuta,0))
=ADDPROPERTY(goT,'curs',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nCurs,0))
=ADDPROPERTY(goT,'nume_val',IIF(goDlg.chkInValutaCont.Value=1,ALLTRIM(NVL(goDlg.cValuta,'')),''))
=ADDPROPERTY(goT,'cTipTva',IIF(goDlg.optTipTva.Value=1,'F',IIF(goDlg.optTipTva.Value=2,'D','N')))
=ADDPROPERTY(goT,'id_jtva_coloana',goDlg.nIdExplicatieTva)
=ADDPROPERTY(goT,'dvi_serie',CHRTRAN(ALLTRIM(NVL(goDlg.cSerieDvi,'')),CHR(34),''))
=ADDPROPERTY(goT,'dvi_nract',goDlg.nNractDvi)
=ADDPROPERTY(goT,'dvi_dataact',goDlg.dDviData)
=ADDPROPERTY(goT,'dvi_id_fdoc',goDlg.nIdFdocDVI)
=ADDPROPERTY(goT,'dvi_fdoc',goDlg.cFelDocDvi)
=ADDPROPERTY(goT,'dvi_id_partc',goDlg.nDviIdPartener)
=ADDPROPERTY(goT,'dvi_partc',goDlg.cDviPartener)
=ADDPROPERTY(goT,'dvi_scc','401')
=ADDPROPERTY(goT,'dvi_tva_lei',goDlg.nDviTvaLei)
=ADDPROPERTY(goT,'dvi_tva_val',goDlg.nDviTvaVal)
ENDPROC
PROCEDURE CreeazaRulTemp
*-- structura reala a rul_temp (vezi ointroduceri.vc2:11030 si test_adauga_repere_212.prg).
IF USED('rul_temp')
USE IN ('rul_temp')
ENDIF
CREATE CURSOR rul_temp ( ;
id_rul N(20,0), an N(4,0), luna N(2,0), cod N(20,0);
, serie C(100), nnir N(20,0), id_articol N(10,0), denumire C(100);
, codmat C(50), codmatf C(50), codbare C(50), um C(20);
, id_gestiune N(5,0), nume_gestiune C(50), cgest C(20), nr_pag N(2,0);
, gestionar C(50), comisie_receptie1 C(50), comisie_receptie2 C(50), comisie_receptie3 C(50);
, cant N(14,3), cante N(14,3), cont C(10), acont C(20);
, pret N(18,4), tva N(18,4), valoare N(18,4), valtva N(18,4);
, proc_tva N(5,2), pretv N(18,4), pretvtva N(18,4), tvav N(18,4);
, valoarev N(18,4), valtvav N(18,4), proc_tvav N(5,2), adaos N(18,4);
, adaos_tva N(18,4), valoare_adaos N(18,4), valtva_adaos N(18,4), procent N(10,3);
, discunitar N(18,4), discount_tva N(18,4), valoare_discount N(18,4), valtva_discount N(18,4);
, proc_disc N(7,3), pretd N(14,4), curs N(18,4), id_valuta N(10,0);
, nume_val C(20), id_lucrare N(20,0), nrord C(100), id_responsabil N(10,0);
, nresp C(100), resp_marca N(18,4), dataact T, id_util N(5,0);
, util C(30), dataora T, id_sectie N(5,0), sectie C(50);
, csectie C(10), alcooltutun N(1,0), datain T, dataout T;
, id_fact N(20,0), id_gestiunec N(10,0), nume_gestiunec C(50), cgestc C(20);
, id_responsabilc N(5,0), id_reteta N(10,0), reteta C(50), nrespc C(100);
, respc_marca N(18,4), id_set N(20,0), id_tip_rulaj N(10,0), tip_rulaj C(50);
, id_obiect_depozit N(10,0), id_rul_aux N(10,0), nract N(20,0), serie_act C(10);
, dataoras T, id_utils N(10,0), lot C(30), adata_expirare T;
, id_sucursala N(5,0), sucursala C(250), id_part_rez N(10,0), part_rez C(100);
, id_lucrare_rez N(10,0), nrord_rez C(100), subgrupa C(100), grupa C(100);
, id_subgrupa N(5,0), id_grupa N(5,0), in_stoc N(1,0), in_crm N(1,0);
, id_furnizor N(10,0), furnizor C(100), id_jtva_coloana N(4,0), explicatie_tva C(100);
, taxcode N(6,0), taxname C(254), saft_procent N(18,4), codnc8 C(20);
, id_tara_origine N(4,0), cod_tara_origine C(5), tara_origine C(50), greutate N(12,4);
, fdoc C(30), id_fdoc N(18,4);
, pret_lei N(18,4), pret_val N(14,4), cota_tva N(6,2))
ENDPROC
PROCEDURE CreeazaIntrodc
LPARAMETERS tcAlias
IF USED(tcAlias)
USE IN (tcAlias)
ENDIF
CREATE CURSOR (tcAlias) ( ;
id_note N(14), explicatia C(100), scd C(10), ascd C(20), scc C(10), ascc C(20), ;
cu_tva N(1), id_set N(14), ordine N(8), in_valuta N(1), id_jtva_coloana N(14) NULL, ;
ptva N(6,2), explicatie_tva C(50), tipjurnal C(2), taxcode N(6), paymentcode C(9), ;
suma N(18,4), suma_val N(18,4), id_partd N(14), id_partc N(14), partd C(100), partc C(100), ;
id_fact N(14), id_factd N(14), id_factc N(14), pereched N(14), perechec N(14), ;
nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), ;
scd_orig C(20), ascd_orig C(20))
ENDPROC
PROCEDURE DumpIntrodc
LOCAL lnSel
lnSel = SELECT()
SELECT introdc
SCAN
DO TfLog WITH ' recno=' + TRANSFORM(RECNO()) + ' nr_doc=' + TRANSFORM(NVL(nr_doc,0)) + ' tip_rand=' + tip_rand + ;
' scd=' + ALLTRIM(scd) + ' scc=' + ALLTRIM(NVL(scc,'')) + ' ptva=' + TRANSFORM(ptva) + ;
' suma=' + TRANSFORM(suma) + ' suma_val=' + TRANSFORM(suma_val) + ;
' mod_manual=' + TRANSFORM(NVL(mod_manual,0)) + ' partc=[' + ALLTRIM(NVL(partc,'')) + ']'
ENDSCAN
SELECT (lnSel)
ENDPROC
FUNCTION RECCOUNT_ACTIVE
LPARAMETERS tcAlias
LOCAL lnSel, lnCnt
lnSel = SELECT()
SELECT (tcAlias)
COUNT TO lnCnt FOR !DELETED()
SELECT (lnSel)
RETURN lnCnt
ENDFUNC
PROCEDURE TfErr
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
DO TfLog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
ENDPROC
PROCEDURE TfLog
LPARAMETERS tcMsg
SET SAFETY OFF
LOCAL lcL
lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '')
STRTOFILE(lcL + tcMsg + CHR(13)+CHR(10), gcUILog)
ENDPROC
DEFINE CLASS dummyapp AS Custom
PROCEDURE ReadIni
LPARAMETERS tcSection, tcKey
RETURN ''
ENDPROC
PROCEDURE WriteIni
LPARAMETERS tcSection, tcKey, tcValue
RETURN .T.
ENDPROC
ENDDEFINE
DEFINE CLASS dummyexecutor AS Custom
cEroare = ''
PROCEDURE oExecute
LPARAMETERS tcSql, tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF 'VJTVA_COLOANE' $ UPPER(m.tcSql)
DO CreeazaJtvaColoaneView WITH m.tcCursor
RETURN 1
ENDIF
IF UPPER(ALLTRIM(m.tcCursor)) == 'RUL_TEMP'
DO CreeazaRulTemp
ELSE
CREATE CURSOR (m.tcCursor) (id_temp N(1))
ENDIF
RETURN 1
ENDPROC
PROCEDURE oExecuta
LPARAMETERS tcSql, tcCursor
IF !EMPTY(m.tcCursor)
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF UPPER(m.tcCursor) == 'CJTVACOL4427'
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14))
ELSE
CREATE CURSOR (m.tcCursor) (id_temp N(1))
ENDIF
ENDIF
RETURN .T.
ENDPROC
PROCEDURE oSelect2Value
LPARAMETERS tcSql, toValue
toValue = ''
RETURN 1
ENDPROC
PROCEDURE oReset
ENDPROC
ENDDEFINE
PROCEDURE CreeazaJtvaColoaneView
LPARAMETERS tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14), denumire C(100), jc N(1), jv N(1), ;
coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14) NULL, afisat N(1), ;
id_jtva_ex N(14) NULL, id_jtva_neex N(14) NULL, ordine N(8), ;
taxcode N(6) NULL, taxcode_neexigibil N(6) NULL, taxcode_n50 N(6) NULL, ;
taxcode_n50_tvai N(6) NULL, taxcode_n100 N(6) NULL, taxcode_regularizare N(6) NULL, taxcode_tvai N(6) NULL)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, afisat, ordine, cota_tva) VALUES (0, '', 0, 0, 1, 0, 0)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (208, 'ACH. INT. 21%', 1, 0, 'RO21B', 21, 209, 1, 1, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (209, 'TVA ACH. INT. 21%', 1, 0, 'RO21T', 21, 1, 2, 301104)
ENDPROC

View File

@@ -0,0 +1,13 @@
# test_tva_creditori.ps1 - wrapper subtire peste harness-ul generic vfp_ui_harness.ps1.
# Runda27: T-uri de TVA grupate pe cota+creditor (scc/ascc), editare manuala prin Grid1.cScc,
# persistenta la resincronizari ulterioare (crsSccS).
# Rulare: powershell -ExecutionPolicy Bypass -File test_tva_creditori.ps1
$ErrorActionPreference = 'Stop'
$Teste = $PSScriptRoot
& (Join-Path (Split-Path $Teste -Parent) 'vfp_ui_harness.ps1') `
-TestPrg (Join-Path $Teste 'test_tva_creditori.prg') `
-Steps @('doc_adaugat','sync1_scc_mostenit','split_creditori_404','tva_mutat_405','persistenta_scc') `
-ShotsDir (Join-Path $Teste 'screenshots_tva_creditori') `
-SyncDir (Join-Path $Teste 'uisync_tva_creditori') `
-StepTimeoutSec 180 `
-ReadyTimeoutSec 180

View File

@@ -0,0 +1,927 @@
* test_tva_secundare.prg
* Test UI (runda30) pentru clasa IMPORT_nota (COMUN\clase\ointroduceri.vcx): doua fixuri.
* Bug 1 (Grid1.cScc.Text1.Valid): daca grila scrie valoarea in introdc.scc INAINTE ca Valid
* sa ruleze (cazul Enter), garda trebuie sa arme resincronizarea pe baza lui Thisform.nOldVal,
* indiferent daca campul e deja scris in cursor.
* Bug 2 (sparge_document/recalc_tva_document): la documentele SECUNDARE (transport/taxe),
* randurile T (TVA) trebuie regrupate pe creditorii (scc/ascc) randurilor S, proportional cu
* bazele S per creditor, pastrand totalul T - nu doar la documentul principal.
*
* Scenariu (flux REAL, nu Append direct in cursoare):
* Factura PRINCIPALA (nract 15000, RAJA, 1000 EUR, curs 5.23, TVA pe DVI) + 2 articole
* (ART-BULD-212 cont 212 baza 900, ART-A8-371 cont 371 baza 100) prin do_adauga_articol() REAL.
* Factura SECUNDARA (nract 12000, TRANS OIL, 1000 LEI, TVA la furnizor F) - transport, aceleasi
* articole (baza proportionala). lSpargeSecundare = .T., sincronizeaza().
* Pas1: stare de baza (S-uri mostenite scc=401, cate un singur T pe fiecare document).
* Pas2 (Bug2): editez scc pe S(212) al SECUNDAREI 401->404 prin Grid1.cScc, astept timer/fallback,
* astept 2 T-uri pe secundara (404=189, 401=21 lei).
* Pas3 (Bug1): pe S(212) al PRINCIPALEI simulez scrierea in cursor INAINTE de Valid (cazul Enter),
* astept lSyncPending=.T. imediat dupa Valid, apoi 2 T-uri pe principala (404=189, 401=21 EUR).
* Pas4: persistenta - sincronizeaza() inca o data fara alte editari, splitul ramane identic.
* Pas5: recalc_tva_document pe secundara cu totalul dublat (2000 lei) - T-urile se recalculeaza
* proportional (404=378, 401=42), nu ambele la totalul intreg.
*
* Vezi test_tva_creditori.prg (sablon) si docs/testare-ui-vfp.md.
*
* Rulare (prin harness):
* powershell -ExecutionPolicy Bypass -File test_tva_secundare.ps1
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET DECIMALS TO 4
SET NULLDISPLAY TO ''
CLOSE DATABASES
PUBLIC gcUILog, gcSyncDir
gcUILog = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\test_tva_secundare_log.txt"
gcSyncDir = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\uisync_tva_secundare\"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcUILog)
ON ERROR DO TfErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
TRY
LOCAL gcAppPath, lcPath
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;' + ;
ADDBS(SUBSTR(gcAppPath,1,RAT([\],gcAppPath,2)))+[COMUNROA\]
SET PATH TO &lcPath ADDITIVE
DO TfLog WITH 'SET PATH OK'
*----- CLASE -----
SET CLASSLIB TO (gcAppPath + "comun\clase\appwiz") 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 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 wwdialogs.vcx ADDITIVE
SET CLASSLIB TO oimportxml.vcx ADDITIVE
SET CLASSLIB TO excelxml.vcx ADDITIVE
SET CLASSLIB TO orapoarte_obinv.vcx ADDITIVE
DO TfLog WITH 'SET CLASSLIB OK'
*----- PROCEDURI (mock amessagebox + mock cauta_nom_articole PRIMELE, ui_harness la final) -----
SET PROCEDURE TO PROCEDURI
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_cauta_nom_articole.prg" 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 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 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 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
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\ui_harness.prg" ADDITIVE
DO TfLog WITH 'SET PROCEDURE OK'
*----- Globale -----
PUBLIC gnPc, gnPval, gnPcant, gnPpret, gnPPretval, gnPCurs, gnPVal, gnPPretV, gnPPretVal
STORE 2 TO gnPc, gnPval, gnPVal
gnPcant = 3
STORE 4 TO gnPpret, gnPPretval, gnPPretVal, gnPPretV, gnPCurs
PUBLIC gl406, gcS, gnAn, gnLuna, gnIdFirma, gnIdSucursala, gcAcces, gcFirma
gl406 = .T.
gcS = 'CONTAFIN'
gnAn = YEAR(DATE())
gnLuna = MONTH(DATE())
gnIdFirma = 110
gnIdSucursala = 110
gcAcces = "1;2;3;4;5;6;7;8;"
gcFirma = gcS
PUBLIC nror(65000)
PUBLIC gnButon
STORE 2 TO gnButon
PUBLIC goExecutor, goApp
goExecutor = CREATEOBJECT('dummyexecutor')
goApp = CREATEOBJECT('dummyapp')
*----- poAct: antetul notei; dialogul mosteneste din el la Init -----
PUBLIC poAct
poAct = CREATEOBJECT('Custom')
poAct.AddProperty('nume_val', '')
poAct.AddProperty('curs', 1)
poAct.AddProperty('proc_tva', 1.21)
poAct.AddProperty('nnir', 0)
poAct.AddProperty('id_valuta', 0)
poAct.AddProperty('id_fdoc', 1)
poAct.AddProperty('fdoc', 'Factura')
poAct.AddProperty('id_partc', 500)
poAct.AddProperty('partc', 'FURNIZOR ANTET SRL')
poAct.AddProperty('serie_act', '')
poAct.AddProperty('dataact', DATE())
poAct.AddProperty('tva_incasare', 0)
poAct.AddProperty('id_set', 1)
poAct.AddProperty('id_gestin', 1)
*----- jtva_coloane2 (explicatii TVA): achizitii interne 21% - perechea folosita de sablon -----
IF USED('jtva_coloane2')
USE IN ('jtva_coloane2')
ENDIF
CREATE CURSOR jtva_coloane2 (ordine N(8), id_jtva_coloana N(14), denumire C(100), ;
jc N(1), jv N(1), afisat N(1), coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14))
INSERT INTO jtva_coloane2 VALUES (0, 0, '', 0, 0, 1, '', '', 0, 0)
INSERT INTO jtva_coloane2 VALUES (1, 208, 'ACH. INT. 21%', 1, 0, 1, 'RO21B', 'RO21T', 21, 209)
INSERT INTO jtva_coloane2 VALUES (2, 209, 'TVA ACH. INT. 21%', 1, 0, 1, 'RO21T', '', 21, 0)
*----- saft_taxtable: coduri reale (vsaft_taxtable) - achizitii interne 21% -----
IF USED('saft_taxtable')
USE IN ('saft_taxtable')
ENDIF
CREATE CURSOR saft_taxtable (taxname C(250) NULL, typename C(250) NULL, taxcode N(6) NULL, ;
taxtype N(3) NULL, descriere C(250) NULL, tip C(100) NULL, descriere_tip C(250) NULL, ;
procent_taxa N(7,2) NULL, procent_prorata N(7,2) NULL, inactiv N(1) NULL, tva N(1) NULL, ;
wht N(1) NULL, tva_achizitii N(1) NULL, tva_livrari N(1) NULL)
INDEX ON taxcode TAG taxcode
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('', 0, '', 0, 1, 1, 1, 1)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301104-Achizitii de bunuri si servicii taxabile cu cota de 21%, altele decat importurile si cele supuse masurilor de simplificare', 301104, '', 21, 1, 0, 1, 0)
*----- introdc (RecordSource Grid1) - porneste GOL, ca in fluxul real -----
DO CreeazaIntrodc WITH 'introdc'
*-- INDEX ord_doc (docs/testare-ui-vfp.md capcana p): fara el, sincronizari repetate cu 2+
*-- documente (principala+secundara) pot pierde identitatea documentului "principal" dupa
*-- ce S-urile sunt sterse/reasezate la coada de fiecare sparge_document().
SELECT introdc
INDEX ON STR(NVL(nr_doc,0),8) + ICASE(tip_rand='B','1', tip_rand='S','2', tip_rand='T','3', tip_rand='D','4', '5') + PADR(NVL(scd,''),10) TAG ord_doc
SET ORDER TO ord_doc
*----- introdc_sablon: perechea-sablon (B 371/401 + T 4426/401) pe care do_adauga_factura o
* cloneaza (21%, ACH. INT. 21%). -----
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%')
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%')
GO TOP IN introdc_sablon
*----- rul_temp cu 1 rand INAINTE de instantiere (capcana k) - structura FIDELA VRUL. -----
DO CreeazaRulTemp
INSERT INTO rul_temp (denumire, codmat, cant, pret, pret_lei, cont, cota_tva) ;
VALUES ('PLACEHOLDER', 'PH', 1, 1, 1, '371', 21)
DO TfLog WITH 'cursoare pregatite, CREATEOBJECT(import_nota, .F.) - lIntern=.F. (import)'
SELECT introdc
PUBLIC goObj
goObj = CREATEOBJECT('IMPORT_nota', .F.)
IF VARTYPE(goObj) <> 'O'
DO TfLog WITH 'FAIL: instantiere import_nota'
DO HarnessDone WITH 'done-error'
QUIT
ENDIF
goObj.lDialogAratat = .T.
goObj.oact = poAct
goObj.WindowType = 0
goObj.Visible = .T.
goObj.Show()
goObj.WindowState = 2
DOEVENTS FORCE
*-- golesc placeholder-ul cu ZAP (nu DELETE ALL, capcana k)
SELECT rul_temp
ZAP
goObj.gridart.Refresh()
DOEVENTS FORCE
*========================= DOC PRINCIPAL: FACTURA 15000, 1000 EUR, curs 5.23, TVA pe DVI =========================
PUBLIC goDlg, goT
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = 15000
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 700
goDlg.cPartener = 'RAJA'
goDlg.cExplicatia = 'Factura test TVA secundare - principala'
goDlg.nSuma = 1000
goDlg.nSumaLei = 0
goDlg.nCurs = 5.23
goDlg.nIdValuta = 978
goDlg.cValuta = 'EUR'
*-- ACH. INT. 21% (id 208), TVA pe DVI (D)
goDlg.nIdExplicatieTva = 208
goDlg.cExplicatieTva = 'ACH. INT. 21%'
goDlg.optTipTva.Value = 2 && D = DVI
goDlg.chkInValutaCont.Value = 1
goDlg.chkParticipaValuta.Value = 1
*-- date DVI
goDlg.cSerieDvi = ''
goDlg.nNractDvi = 101
goDlg.dDviData = DATE()
goDlg.nIdFdocDVI = 2
goDlg.cFelDocDvi = 'DVI'
goDlg.nDviIdPartener = 800
goDlg.cDviPartener = 'BIROUL VAMAL'
goDlg.nDviTvaVal = 210
goDlg.nDviTvaLei = ROUND(210*5.23,2)
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO TfLog WITH 'DOC principal: valideaza (pe dialog) = ' + TRANSFORM(goDlg.valideaza())
DO ConstruiesteToDlg
DO TfLog WITH 'DOC principal: do_adauga_factura = ' + TRANSFORM(goObj.do_adauga_factura(goT))
goDlg.Hide()
DOEVENTS FORCE
LOCAL llB1, llT1
SELECT introdc
LOCATE FOR nract = 15000 AND INLIST(tip_rand,'B','S')
llB1 = FOUND()
LOCATE FOR nr_doc = 1 AND tip_rand == 'T'
llT1 = FOUND()
IF llB1 AND llT1
DO TfLog WITH 'PASS: factura principala 15000 adaugata (B+T)'
ELSE
DO TfLog WITH 'FAIL: factura principala 15000 - B?=' + TRANSFORM(llB1) + ' T?=' + TRANSFORM(llT1)
ENDIF
*========================= ADAUGARE 2 ARTICOLE PRIN FLUXUL REAL: do_adauga_articol() =========================
*-- ART-BULD-212 (cont 212, baza 900) + ART-A8-371 (cont 371, baza 100)
PUBLIC gcMockArtCodmat
gcMockArtCodmat = 'ART-BULD-212'
goObj.do_adauga_articol()
DOEVENTS FORCE
SELECT rul_temp
LOCATE FOR ALLTRIM(codmat) == 'ART-BULD-212'
IF FOUND()
REPLACE cant WITH 1, pret_val WITH 900, pretd WITH 900, pret WITH ROUND(900*5.23,gnPc), pret_lei WITH pret
DO TfLog WITH 'articol 1 (ART-BULD-212, cont 212) adaugat prin do_adauga_articol() REAL, baza 900'
ELSE
DO TfLog WITH 'FAIL: ART-BULD-212 nu a fost gasit in rul_temp dupa do_adauga_articol()'
ENDIF
gcMockArtCodmat = 'ART-A8-371'
goObj.do_adauga_articol()
DOEVENTS FORCE
SELECT rul_temp
LOCATE FOR ALLTRIM(codmat) == 'ART-A8-371'
IF FOUND()
REPLACE cant WITH 1, pret_val WITH 100, pretd WITH 100, pret WITH ROUND(100*5.23,gnPc), pret_lei WITH pret
DO TfLog WITH 'articol 2 (ART-A8-371, cont 371) adaugat prin do_adauga_articol() REAL, baza 100'
ELSE
DO TfLog WITH 'FAIL: ART-A8-371 nu a fost gasit in rul_temp dupa do_adauga_articol()'
ENDIF
goObj.gridart.Refresh()
DOEVENTS FORCE
*========================= DOC SECUNDAR: FACTURA 12000 (transport), 1000 LEI, TVA la furnizor =========================
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = 12000
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 710
goDlg.cPartener = 'TRANS OIL'
goDlg.cExplicatia = 'Factura test TVA secundare - transport'
goDlg.nSuma = 1000
goDlg.nSumaLei = 0
goDlg.nCurs = 0
goDlg.nIdExplicatieTva = 208
goDlg.cExplicatieTva = 'ACH. INT. 21%'
goDlg.optTipTva.Value = 1 && F = furnizor
goDlg.chkInValutaCont.Value = 0
goDlg.chkParticipaValuta.Value = 1
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO TfLog WITH 'DOC secundar: valideaza (pe dialog) = ' + TRANSFORM(goDlg.valideaza())
DO ConstruiesteToDlg
DO TfLog WITH 'DOC secundar: do_adauga_factura = ' + TRANSFORM(goObj.do_adauga_factura(goT))
goDlg.Hide()
DOEVENTS FORCE
LOCAL llB2, llT2
SELECT introdc
LOCATE FOR nract = 12000 AND INLIST(tip_rand,'B','S')
llB2 = FOUND()
LOCATE FOR nract = 12000 AND tip_rand == 'T'
llT2 = FOUND()
IF llB2 AND llT2
DO TfLog WITH 'PASS: factura secundara 12000 adaugata (B+T)'
ELSE
DO TfLog WITH 'FAIL: factura secundara 12000 - B?=' + TRANSFORM(llB2) + ' T?=' + TRANSFORM(llT2)
ENDIF
*========================= PAS 0: setup gata, activez spargerea secundarelor si sincronizez =========================
goObj.lSpargeSecundare = .T.
goObj.sincronizeaza()
DOEVENTS FORCE
goObj.grid1.Refresh()
DOEVENTS FORCE
DO TfLog WITH 'DIAG dump introdc dupa sincronizare#1 (stare de baza):'
DO DumpIntrodc
*-- VERIFICARE stare de baza: principala sparta S(212)=900 S(371)=100 (scc=401 mostenit), 1 T
*-- (scc=401, suma_val=210 EUR); secundara sparta S(212)=900 lei S(371)=100 lei (scc=401), 1 T
*-- (scc=401, suma=210 lei, 21% din 1000)
LOCAL llS212p, llS371p, lcS212SccP, lcS371SccP, lnCntTp, lnTValP
SELECT introdc
LOCATE FOR tip_rand == 'S' AND ALLTRIM(scd) == '212' AND nract = 15000
llS212p = FOUND()
IF llS212p
lcS212SccP = ALLTRIM(NVL(scc,''))
ENDIF
LOCATE FOR tip_rand == 'S' AND ALLTRIM(scd) == '371' AND nract = 15000
llS371p = FOUND()
IF llS371p
lcS371SccP = ALLTRIM(NVL(scc,''))
ENDIF
COUNT FOR tip_rand == 'T' AND ALLTRIM(scd) == '4426' AND nr_doc = 1 TO lnCntTp
LOCATE FOR tip_rand == 'T' AND ALLTRIM(scd) == '4426' AND nr_doc = 1
lnTValP = suma_val
IF llS212p AND llS371p AND lcS212SccP == '401' AND lcS371SccP == '401' AND lnCntTp = 1 AND ABS(lnTValP - 210) < 0.01
DO TfLog WITH 'PASS pas0 principala: S212.scc=401 S371.scc=401, 1 T, suma_val=' + TRANSFORM(lnTValP) + ' (astept 210)'
ELSE
DO TfLog WITH 'FAIL pas0 principala: S212.scc=' + lcS212SccP + ' S371.scc=' + lcS371SccP + ' nrT=' + TRANSFORM(lnCntTp) + ' T.suma_val=' + TRANSFORM(lnTValP) + ' (astept 401/401/1/210)'
ENDIF
LOCAL llS212s, llS371s, lcS212SccS, lcS371SccS, lnS212SumaS, lnS371SumaS, lnCntTs, lnTSumaS
SELECT introdc
LOCATE FOR tip_rand == 'S' AND ALLTRIM(scd) == '212' AND nract = 12000
llS212s = FOUND()
IF llS212s
lcS212SccS = ALLTRIM(NVL(scc,''))
lnS212SumaS = suma
ENDIF
LOCATE FOR tip_rand == 'S' AND ALLTRIM(scd) == '371' AND nract = 12000
llS371s = FOUND()
IF llS371s
lcS371SccS = ALLTRIM(NVL(scc,''))
lnS371SumaS = suma
ENDIF
COUNT FOR tip_rand == 'T' AND ALLTRIM(scd) == '4426' AND nract = 12000 TO lnCntTs
LOCATE FOR tip_rand == 'T' AND ALLTRIM(scd) == '4426' AND nract = 12000
lnTSumaS = suma
IF llS212s AND llS371s AND lcS212SccS == '401' AND lcS371SccS == '401' AND ABS(lnS212SumaS - 900) < 0.01 ;
AND ABS(lnS371SumaS - 100) < 0.01 AND lnCntTs = 1 AND ABS(lnTSumaS - 210) < 0.01
DO TfLog WITH 'PASS pas0 secundara: S212=' + TRANSFORM(lnS212SumaS) + ' S371=' + TRANSFORM(lnS371SumaS) + ' scc=401/401, 1 T, suma=' + TRANSFORM(lnTSumaS) + ' (astept 900/100/1/210)'
ELSE
DO TfLog WITH 'FAIL pas0 secundara: S212=' + TRANSFORM(lnS212SumaS) + '(scc=' + lcS212SccS + ') S371=' + TRANSFORM(lnS371SumaS) + '(scc=' + lcS371SccS + ') nrT=' + TRANSFORM(lnCntTs) + ' T.suma=' + TRANSFORM(lnTSumaS)
ENDIF
*========================= PAS 0 (HarnessStep 0): stare de baza dupa sincronizare#1 =========================
DO HarnessStep WITH 0, 'stare_baza: principala T.suma_val=' + TRANSFORM(lnTValP) + ' secundara S212=' + TRANSFORM(lnS212SumaS) + ' S371=' + TRANSFORM(lnS371SumaS) + ' T.suma=' + TRANSFORM(lnTSumaS)
*========================= PAS 1 (BUG 2): editez scc pe S(212) al SECUNDAREI, 401 -> 404 =========================
SELECT introdc
LOCATE FOR tip_rand == 'S' AND ALLTRIM(scd) == '212' AND nract = 12000
GO RECNO()
*-- GotFocus REAL: seteaza Thisform.nOldVal = valoarea curenta a celulei
goObj.Grid1.cScc.Text1.Value = scc
goObj.Grid1.cScc.Text1.GotFocus()
DO TfLog WITH 'dupa GotFocus real pe S(212) secundara: Thisform.nOldVal=' + TRANSFORM(goObj.nOldVal) + ' (astept 401)'
goObj.Grid1.cScc.Text1.Value = '404'
TRY
goObj.Grid1.cScc.Text1.Valid()
DO TfLog WITH 'PASS apel REAL: Grid1.cScc.Text1.Valid() executat pe S(212) secundara'
CATCH TO loExc1
DO TfLog WITH 'PAS1 EROARE ' + TRANSFORM(loExc1.ErrorNo) + ' [' + loExc1.Message + '] in ' + loExc1.Procedure + ':' + TRANSFORM(loExc1.LineNo) + ' (' + loExc1.LineContents + ')'
ENDTRY
*-- verific armarea sincronizarii amanate, apoi las timerul sa traga (fallback direct daca nu apuca)
IF goObj.lSyncPending
DO TfLog WITH 'PASS pas1: goObj.lSyncPending=.T. dupa Valid pe S(212) secundara'
ELSE
DO TfLog WITH 'FAIL pas1: goObj.lSyncPending=.F. dupa Valid pe S(212) secundara (astept .T.)'
ENDIF
LOCAL i
FOR i = 1 TO 50
DOEVENTS FORCE
IF !goObj.lSyncPending
EXIT
ENDIF
ENDFOR
IF goObj.lSyncPending
DO TfLog WITH 'INFO: tmrSync nu a tras sub DOEVENTS - fallback apel direct goObj.tmrSync.Timer()'
goObj.tmrSync.Timer()
ENDIF
goObj.grid1.Refresh()
DOEVENTS FORCE
DO TfLog WITH 'DIAG dump introdc dupa scc secundara 401->404 pe S(212) + resincronizare:'
DO DumpIntrodc
*-- VERIFICARE bug2: secundara are acum 2 T-uri 4426 - scc=404 (baza 212=900 lei) suma=189,
*-- scc=401 (baza 371=100 lei) suma=21; principala ramane neschimbata (1 T, suma_val=210)
LOCAL llT404s1, llT401s1, lnT404ValS1, lnT401ValS1, lnCntTs1
SELECT introdc
COUNT FOR tip_rand == 'T' AND ALLTRIM(scd) == '4426' AND nract = 12000 TO lnCntTs1
LOCATE FOR tip_rand == 'T' AND ALLTRIM(scd) == '4426' AND nract = 12000 AND ALLTRIM(NVL(scc,'')) == '404'
llT404s1 = FOUND()
IF llT404s1
lnT404ValS1 = suma
ENDIF
LOCATE FOR tip_rand == 'T' AND ALLTRIM(scd) == '4426' AND nract = 12000 AND ALLTRIM(NVL(scc,'')) == '401'
llT401s1 = FOUND()
IF llT401s1
lnT401ValS1 = suma
ENDIF
IF lnCntTs1 = 2 AND llT404s1 AND llT401s1 AND ABS(lnT404ValS1 - 189) < 0.01 AND ABS(lnT401ValS1 - 21) < 0.01
DO TfLog WITH 'PASS pas1 bug2 secundara regrupata: T(scc=404).suma=' + TRANSFORM(lnT404ValS1) + ' (astept 189) T(scc=401).suma=' + TRANSFORM(lnT401ValS1) + ' (astept 21)'
ELSE
DO TfLog WITH 'FAIL pas1 bug2 secundara regrupata: nrT=' + TRANSFORM(lnCntTs1) + ' T404?=' + TRANSFORM(llT404s1) + '(suma=' + TRANSFORM(IIF(llT404s1,lnT404ValS1,-1)) + ') T401?=' + TRANSFORM(llT401s1) + '(suma=' + TRANSFORM(IIF(llT401s1,lnT401ValS1,-1)) + ')'
ENDIF
LOCAL lnCntTp1, lnTValP1
COUNT FOR tip_rand == 'T' AND ALLTRIM(scd) == '4426' AND nr_doc = 1 TO lnCntTp1
LOCATE FOR tip_rand == 'T' AND ALLTRIM(scd) == '4426' AND nr_doc = 1
lnTValP1 = suma_val
IF lnCntTp1 = 1 AND ABS(lnTValP1 - 210) < 0.01
DO TfLog WITH 'PASS pas1 principala neschimbata: 1 T, suma_val=' + TRANSFORM(lnTValP1) + ' (astept 210)'
ELSE
DO TfLog WITH 'FAIL pas1 principala neschimbata: nrT=' + TRANSFORM(lnCntTp1) + ' T.suma_val=' + TRANSFORM(lnTValP1) + ' (astept 1/210)'
ENDIF
*========================= PAS 1 (HarnessStep 1): bug2 regrupare secundara =========================
DO HarnessStep WITH 1, 'bug2_regrupare_secundara: T(404).suma=' + TRANSFORM(IIF(llT404s1,lnT404ValS1,-1)) + ' T(401).suma=' + TRANSFORM(IIF(llT401s1,lnT401ValS1,-1)) + ' principala.T.suma_val=' + TRANSFORM(lnTValP1)
*========================= PAS 2 (BUG 1): S(212) al PRINCIPALEI - scrierea in cursor INAINTE de Valid =========================
SELECT introdc
LOCATE FOR tip_rand == 'S' AND ALLTRIM(scd) == '212' AND nract = 15000
GO RECNO()
*-- GotFocus REAL: seteaza Thisform.nOldVal
goObj.Grid1.cScc.Text1.Value = scc
goObj.Grid1.cScc.Text1.GotFocus()
DO TfLog WITH 'dupa GotFocus real pe S(212) principala: Thisform.nOldVal=' + TRANSFORM(goObj.nOldVal) + ' (astept 401)'
*-- SIMULEZ scrierea grilei in cursor INAINTE de Valid (cazul Enter, capcana bug1)
SELECT introdc
REPLACE scc WITH '404'
goObj.Grid1.cScc.Text1.Value = '404'
TRY
goObj.Grid1.cScc.Text1.Valid()
DO TfLog WITH 'PASS apel REAL: Grid1.cScc.Text1.Valid() executat pe S(212) principala (dupa scriere anticipata in cursor)'
CATCH TO loExc2
DO TfLog WITH 'PAS2 EROARE ' + TRANSFORM(loExc2.ErrorNo) + ' [' + loExc2.Message + '] in ' + loExc2.Procedure + ':' + TRANSFORM(loExc2.LineNo) + ' (' + loExc2.LineContents + ')'
ENDTRY
*-- ASSERT imediat (regresie bug1): pe codul vechi lSyncPending ar fi ramas .F. aici, pentru ca
*-- garda compara This.Value cu introdc.scc (deja scris) in loc de Thisform.nOldVal
IF goObj.lSyncPending
DO TfLog WITH 'PASS pas2 bug1: goObj.lSyncPending=.T. dupa Valid pe S(212) principala (cu scc deja scris in cursor)'
ELSE
DO TfLog WITH 'FAIL pas2 bug1: goObj.lSyncPending=.F. dupa Valid pe S(212) principala (regresie - garda veche nu arma sincronizarea)'
ENDIF
FOR i = 1 TO 50
DOEVENTS FORCE
IF !goObj.lSyncPending
EXIT
ENDIF
ENDFOR
IF goObj.lSyncPending
DO TfLog WITH 'INFO: tmrSync nu a tras sub DOEVENTS - fallback apel direct goObj.tmrSync.Timer()'
goObj.tmrSync.Timer()
ENDIF
goObj.grid1.Refresh()
DOEVENTS FORCE
DO TfLog WITH 'DIAG dump introdc dupa scc principala 401->404 pe S(212) + resincronizare:'
DO DumpIntrodc
*-- VERIFICARE: principala are acum 2 T-uri 4426 - scc=404 (baza 212=900 EUR) suma_val=189,
*-- scc=401 (baza 371=100 EUR) suma_val=21; secundara ramane 189/21 lei neschimbata
LOCAL llT404p2, llT401p2, lnT404ValP2, lnT401ValP2, lnCntTp2
SELECT introdc
COUNT FOR tip_rand == 'T' AND ALLTRIM(scd) == '4426' AND nr_doc = 1 TO lnCntTp2
LOCATE FOR tip_rand == 'T' AND ALLTRIM(scd) == '4426' AND nr_doc = 1 AND ALLTRIM(NVL(scc,'')) == '404'
llT404p2 = FOUND()
IF llT404p2
lnT404ValP2 = suma_val
ENDIF
LOCATE FOR tip_rand == 'T' AND ALLTRIM(scd) == '4426' AND nr_doc = 1 AND ALLTRIM(NVL(scc,'')) == '401'
llT401p2 = FOUND()
IF llT401p2
lnT401ValP2 = suma_val
ENDIF
IF lnCntTp2 = 2 AND llT404p2 AND llT401p2 AND ABS(lnT404ValP2 - 189) < 0.01 AND ABS(lnT401ValP2 - 21) < 0.01
DO TfLog WITH 'PASS pas2 bug1 principala regrupata: T(scc=404).suma_val=' + TRANSFORM(lnT404ValP2) + ' (astept 189) T(scc=401).suma_val=' + TRANSFORM(lnT401ValP2) + ' (astept 21)'
ELSE
DO TfLog WITH 'FAIL pas2 bug1 principala regrupata: nrT=' + TRANSFORM(lnCntTp2) + ' T404?=' + TRANSFORM(llT404p2) + '(suma_val=' + TRANSFORM(IIF(llT404p2,lnT404ValP2,-1)) + ') T401?=' + TRANSFORM(llT401p2) + '(suma_val=' + TRANSFORM(IIF(llT401p2,lnT401ValP2,-1)) + ')'
ENDIF
LOCAL llT404s2, llT401s2, lnT404ValS2, lnT401ValS2, lnCntTs2
COUNT FOR tip_rand == 'T' AND ALLTRIM(scd) == '4426' AND nract = 12000 TO lnCntTs2
LOCATE FOR tip_rand == 'T' AND ALLTRIM(scd) == '4426' AND nract = 12000 AND ALLTRIM(NVL(scc,'')) == '404'
llT404s2 = FOUND()
IF llT404s2
lnT404ValS2 = suma
ENDIF
LOCATE FOR tip_rand == 'T' AND ALLTRIM(scd) == '4426' AND nract = 12000 AND ALLTRIM(NVL(scc,'')) == '401'
llT401s2 = FOUND()
IF llT401s2
lnT401ValS2 = suma
ENDIF
IF lnCntTs2 = 2 AND llT404s2 AND llT401s2 AND ABS(lnT404ValS2 - 189) < 0.01 AND ABS(lnT401ValS2 - 21) < 0.01
DO TfLog WITH 'PASS pas2 secundara neschimbata: T(404).suma=' + TRANSFORM(lnT404ValS2) + ' T(401).suma=' + TRANSFORM(lnT401ValS2) + ' (astept 189/21)'
ELSE
DO TfLog WITH 'FAIL pas2 secundara neschimbata: nrT=' + TRANSFORM(lnCntTs2) + ' T404?=' + TRANSFORM(llT404s2) + '(suma=' + TRANSFORM(IIF(llT404s2,lnT404ValS2,-1)) + ') T401?=' + TRANSFORM(llT401s2) + '(suma=' + TRANSFORM(IIF(llT401s2,lnT401ValS2,-1)) + ')'
ENDIF
*========================= PAS 2 (HarnessStep 2): bug1 garda + regrupare principala =========================
DO HarnessStep WITH 2, 'bug1_garda_scc: principala T(404)=' + TRANSFORM(IIF(llT404p2,lnT404ValP2,-1)) + ' T(401)=' + TRANSFORM(IIF(llT401p2,lnT401ValP2,-1)) + ' secundara T(404)=' + TRANSFORM(IIF(llT404s2,lnT404ValS2,-1)) + ' T(401)=' + TRANSFORM(IIF(llT401s2,lnT401ValS2,-1))
*========================= PAS 3: persistenta - inca o sincronizare (F5), fara alte editari =========================
goObj.sincronizeaza()
DOEVENTS FORCE
goObj.grid1.Refresh()
DOEVENTS FORCE
DO TfLog WITH 'DIAG dump introdc dupa sincronizare#2 (persistenta):'
DO DumpIntrodc
LOCAL llT404p3, llT401p3, lnT404ValP3, lnT401ValP3, lnCntTp3
SELECT introdc
COUNT FOR tip_rand == 'T' AND ALLTRIM(scd) == '4426' AND nr_doc = 1 TO lnCntTp3
LOCATE FOR tip_rand == 'T' AND ALLTRIM(scd) == '4426' AND nr_doc = 1 AND ALLTRIM(NVL(scc,'')) == '404'
llT404p3 = FOUND()
IF llT404p3
lnT404ValP3 = suma_val
ENDIF
LOCATE FOR tip_rand == 'T' AND ALLTRIM(scd) == '4426' AND nr_doc = 1 AND ALLTRIM(NVL(scc,'')) == '401'
llT401p3 = FOUND()
IF llT401p3
lnT401ValP3 = suma_val
ENDIF
LOCAL llT404s3, llT401s3, lnT404ValS3, lnT401ValS3, lnCntTs3
COUNT FOR tip_rand == 'T' AND ALLTRIM(scd) == '4426' AND nract = 12000 TO lnCntTs3
LOCATE FOR tip_rand == 'T' AND ALLTRIM(scd) == '4426' AND nract = 12000 AND ALLTRIM(NVL(scc,'')) == '404'
llT404s3 = FOUND()
IF llT404s3
lnT404ValS3 = suma
ENDIF
LOCATE FOR tip_rand == 'T' AND ALLTRIM(scd) == '4426' AND nract = 12000 AND ALLTRIM(NVL(scc,'')) == '401'
llT401s3 = FOUND()
IF llT401s3
lnT401ValS3 = suma
ENDIF
IF lnCntTp3 = 2 AND llT404p3 AND llT401p3 AND ABS(lnT404ValP3 - 189) < 0.01 AND ABS(lnT401ValP3 - 21) < 0.01 ;
AND lnCntTs3 = 2 AND llT404s3 AND llT401s3 AND ABS(lnT404ValS3 - 189) < 0.01 AND ABS(lnT401ValS3 - 21) < 0.01
DO TfLog WITH 'PASS pas3 persistenta: splitul ramane identic dupa resincronizare (principala 189/21 EUR, secundara 189/21 lei, ambele pe 404/401)'
ELSE
DO TfLog WITH 'FAIL pas3 persistenta: principala T404=' + TRANSFORM(IIF(llT404p3,lnT404ValP3,-1)) + ' T401=' + TRANSFORM(IIF(llT401p3,lnT401ValP3,-1)) + ' secundara T404=' + TRANSFORM(IIF(llT404s3,lnT404ValS3,-1)) + ' T401=' + TRANSFORM(IIF(llT401s3,lnT401ValS3,-1))
ENDIF
*========================= PAS 3 (HarnessStep 3): persistenta regrupare =========================
DO HarnessStep WITH 3, 'persistenta_regrupare: principala T404=' + TRANSFORM(IIF(llT404p3,lnT404ValP3,-1)) + ' T401=' + TRANSFORM(IIF(llT401p3,lnT401ValP3,-1)) + ' secundara T404=' + TRANSFORM(IIF(llT404s3,lnT404ValS3,-1)) + ' T401=' + TRANSFORM(IIF(llT401s3,lnT401ValS3,-1))
*========================= PAS 4: recalc_tva_document pe secundara sparta, total dublat (2000 lei) =========================
LOCAL lcDocKeySec
lcDocKeySec = ''
SELECT introdc
LOCATE FOR nract = 12000 AND !EMPTY(NVL(doc_key,''))
IF FOUND()
lcDocKeySec = doc_key
ENDIF
DO TfLog WITH 'doc_key secundara = [' + lcDocKeySec + ']'
SELECT introdc
REPLACE suma_doc WITH 2000 FOR nract = 12000 AND INLIST(tip_rand,'S','T')
DO TfLog WITH 'secundara: suma_doc dublat la 2000 lei pe randurile S si T'
goObj.recalc_tva_document(lcDocKeySec)
DOEVENTS FORCE
goObj.grid1.Refresh()
DOEVENTS FORCE
DO TfLog WITH 'DIAG dump introdc dupa recalc_tva_document(secundara, total 2000):'
DO DumpIntrodc
*-- VERIFICARE bug2 (recalc_tva_document): T-urile secundarei se recalculeaza proportional cu
*-- ponderea creditorului (404=90% baza, 401=10% baza), nu ambele la totalul intreg*21%
LOCAL llT404s4, llT401s4, lnT404ValS4, lnT401ValS4, lnCntTs4
SELECT introdc
COUNT FOR tip_rand == 'T' AND ALLTRIM(scd) == '4426' AND nract = 12000 TO lnCntTs4
LOCATE FOR tip_rand == 'T' AND ALLTRIM(scd) == '4426' AND nract = 12000 AND ALLTRIM(NVL(scc,'')) == '404'
llT404s4 = FOUND()
IF llT404s4
lnT404ValS4 = suma
ENDIF
LOCATE FOR tip_rand == 'T' AND ALLTRIM(scd) == '4426' AND nract = 12000 AND ALLTRIM(NVL(scc,'')) == '401'
llT401s4 = FOUND()
IF llT401s4
lnT401ValS4 = suma
ENDIF
IF lnCntTs4 = 2 AND llT404s4 AND llT401s4 AND ABS(lnT404ValS4 - 378) < 0.01 AND ABS(lnT401ValS4 - 42) < 0.01
DO TfLog WITH 'PASS pas4 recalc_tva_document proportional: T(scc=404).suma=' + TRANSFORM(lnT404ValS4) + ' (astept 378) T(scc=401).suma=' + TRANSFORM(lnT401ValS4) + ' (astept 42)'
ELSE
DO TfLog WITH 'FAIL pas4 recalc_tva_document proportional: nrT=' + TRANSFORM(lnCntTs4) + ' T404?=' + TRANSFORM(llT404s4) + '(suma=' + TRANSFORM(IIF(llT404s4,lnT404ValS4,-1)) + ') T401?=' + TRANSFORM(llT401s4) + '(suma=' + TRANSFORM(IIF(llT401s4,lnT401ValS4,-1)) + ') (pe codul vechi ambele ar fi 420)'
ENDIF
*========================= PAS 4 (HarnessStep 4): recalc_tva_document proportional pe secundara =========================
DO HarnessStep WITH 4, 'recalc_tva_secundara: T(404).suma=' + TRANSFORM(IIF(llT404s4,lnT404ValS4,-1)) + ' T(401).suma=' + TRANSFORM(IIF(llT401s4,lnT401ValS4,-1))
DO TfLog WITH 'GATA - scenariu runda30 (TVA secundare + garda scc)'
DO HarnessDone WITH 'done'
CATCH TO loExc
DO TfLog WITH 'CATCH ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']'
DO HarnessDone WITH 'done-error'
ENDTRY
QUIT
*==================================================================================
PROCEDURE ConstruiesteToDlg
*-- toDlg construit INLINE in programul PRINCIPAL (ADDPROPERTY da eroare 11 din proceduri in
*-- acest runtime headless - vezi docs/testare-ui-vfp.md capcana l).
goT = CREATEOBJECT('Empty')
=ADDPROPERTY(goT,'serie_act',ALLTRIM(NVL(goDlg.cSerieAct,'')))
=ADDPROPERTY(goT,'nract',goDlg.nNract)
=ADDPROPERTY(goT,'dataact',goDlg.dDataAct)
=ADDPROPERTY(goT,'fdoc',goDlg.cFelDoc)
=ADDPROPERTY(goT,'id_fdoc',goDlg.nIdFdoc)
=ADDPROPERTY(goT,'id_partc',goDlg.nIdPartener)
=ADDPROPERTY(goT,'partc',goDlg.cPartener)
=ADDPROPERTY(goT,'explicatia',ALLTRIM(NVL(goDlg.cExplicatia,'')))
=ADDPROPERTY(goT,'suma',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,IIF(goDlg.nSumaLei<>0,goDlg.nSumaLei,ROUND(goDlg.nSuma*goDlg.nCurs,gnPC)),goDlg.nSuma))
=ADDPROPERTY(goT,'suma_val',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,goDlg.nSuma,0))
=ADDPROPERTY(goT,'in_valuta',goDlg.chkInValutaCont.Value)
=ADDPROPERTY(goT,'participa_valuta',(goDlg.chkParticipaValuta.Value=1))
=ADDPROPERTY(goT,'id_valuta',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nIdValuta,0))
=ADDPROPERTY(goT,'curs',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nCurs,0))
=ADDPROPERTY(goT,'nume_val',IIF(goDlg.chkInValutaCont.Value=1,ALLTRIM(NVL(goDlg.cValuta,'')),''))
=ADDPROPERTY(goT,'cTipTva',IIF(goDlg.optTipTva.Value=1,'F',IIF(goDlg.optTipTva.Value=2,'D','N')))
=ADDPROPERTY(goT,'id_jtva_coloana',goDlg.nIdExplicatieTva)
=ADDPROPERTY(goT,'dvi_serie',CHRTRAN(ALLTRIM(NVL(goDlg.cSerieDvi,'')),CHR(34),''))
=ADDPROPERTY(goT,'dvi_nract',goDlg.nNractDvi)
=ADDPROPERTY(goT,'dvi_dataact',goDlg.dDviData)
=ADDPROPERTY(goT,'dvi_id_fdoc',goDlg.nIdFdocDVI)
=ADDPROPERTY(goT,'dvi_fdoc',goDlg.cFelDocDvi)
=ADDPROPERTY(goT,'dvi_id_partc',goDlg.nDviIdPartener)
=ADDPROPERTY(goT,'dvi_partc',goDlg.cDviPartener)
=ADDPROPERTY(goT,'dvi_scc','401')
=ADDPROPERTY(goT,'dvi_tva_lei',goDlg.nDviTvaLei)
=ADDPROPERTY(goT,'dvi_tva_val',goDlg.nDviTvaVal)
ENDPROC
PROCEDURE CreeazaRulTemp
*-- structura reala a rul_temp (vezi ointroduceri.vc2:11030 si test_adauga_repere_212.prg).
IF USED('rul_temp')
USE IN ('rul_temp')
ENDIF
CREATE CURSOR rul_temp ( ;
id_rul N(20,0), an N(4,0), luna N(2,0), cod N(20,0);
, serie C(100), nnir N(20,0), id_articol N(10,0), denumire C(100);
, codmat C(50), codmatf C(50), codbare C(50), um C(20);
, id_gestiune N(5,0), nume_gestiune C(50), cgest C(20), nr_pag N(2,0);
, gestionar C(50), comisie_receptie1 C(50), comisie_receptie2 C(50), comisie_receptie3 C(50);
, cant N(14,3), cante N(14,3), cont C(10), acont C(20);
, pret N(18,4), tva N(18,4), valoare N(18,4), valtva N(18,4);
, proc_tva N(5,2), pretv N(18,4), pretvtva N(18,4), tvav N(18,4);
, valoarev N(18,4), valtvav N(18,4), proc_tvav N(5,2), adaos N(18,4);
, adaos_tva N(18,4), valoare_adaos N(18,4), valtva_adaos N(18,4), procent N(10,3);
, discunitar N(18,4), discount_tva N(18,4), valoare_discount N(18,4), valtva_discount N(18,4);
, proc_disc N(7,3), pretd N(14,4), curs N(18,4), id_valuta N(10,0);
, nume_val C(20), id_lucrare N(20,0), nrord C(100), id_responsabil N(10,0);
, nresp C(100), resp_marca N(18,4), dataact T, id_util N(5,0);
, util C(30), dataora T, id_sectie N(5,0), sectie C(50);
, csectie C(10), alcooltutun N(1,0), datain T, dataout T;
, id_fact N(20,0), id_gestiunec N(10,0), nume_gestiunec C(50), cgestc C(20);
, id_responsabilc N(5,0), id_reteta N(10,0), reteta C(50), nrespc C(100);
, respc_marca N(18,4), id_set N(20,0), id_tip_rulaj N(10,0), tip_rulaj C(50);
, id_obiect_depozit N(10,0), id_rul_aux N(10,0), nract N(20,0), serie_act C(10);
, dataoras T, id_utils N(10,0), lot C(30), adata_expirare T;
, id_sucursala N(5,0), sucursala C(250), id_part_rez N(10,0), part_rez C(100);
, id_lucrare_rez N(10,0), nrord_rez C(100), subgrupa C(100), grupa C(100);
, id_subgrupa N(5,0), id_grupa N(5,0), in_stoc N(1,0), in_crm N(1,0);
, id_furnizor N(10,0), furnizor C(100), id_jtva_coloana N(4,0), explicatie_tva C(100);
, taxcode N(6,0), taxname C(254), saft_procent N(18,4), codnc8 C(20);
, id_tara_origine N(4,0), cod_tara_origine C(5), tara_origine C(50), greutate N(12,4);
, fdoc C(30), id_fdoc N(18,4);
, pret_lei N(18,4), pret_val N(14,4), cota_tva N(6,2))
ENDPROC
PROCEDURE CreeazaIntrodc
LPARAMETERS tcAlias
IF USED(tcAlias)
USE IN (tcAlias)
ENDIF
CREATE CURSOR (tcAlias) ( ;
id_note N(14), explicatia C(100), scd C(10), ascd C(20), scc C(10), ascc C(20), ;
cu_tva N(1), id_set N(14), ordine N(8), in_valuta N(1), id_jtva_coloana N(14) NULL, ;
ptva N(6,2), explicatie_tva C(50), tipjurnal C(2), taxcode N(6), paymentcode C(9), ;
suma N(18,4), suma_val N(18,4), id_partd N(14), id_partc N(14), partd C(100), partc C(100), ;
id_fact N(14), id_factd N(14), id_factc N(14), pereched N(14), perechec N(14), ;
nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), ;
scd_orig C(20), ascd_orig C(20))
ENDPROC
PROCEDURE DumpIntrodc
LOCAL lnSel
lnSel = SELECT()
SELECT introdc
SCAN
DO TfLog WITH ' recno=' + TRANSFORM(RECNO()) + ' nract=' + TRANSFORM(NVL(nract,0)) + ' nr_doc=' + TRANSFORM(NVL(nr_doc,0)) + ' tip_rand=' + tip_rand + ;
' scd=' + ALLTRIM(scd) + ' scc=' + ALLTRIM(NVL(scc,'')) + ' ptva=' + TRANSFORM(ptva) + ;
' suma=' + TRANSFORM(suma) + ' suma_val=' + TRANSFORM(suma_val) + ;
' mod_manual=' + TRANSFORM(NVL(mod_manual,0)) + ' partc=[' + ALLTRIM(NVL(partc,'')) + ']'
ENDSCAN
SELECT (lnSel)
ENDPROC
FUNCTION RECCOUNT_ACTIVE
LPARAMETERS tcAlias
LOCAL lnSel, lnCnt
lnSel = SELECT()
SELECT (tcAlias)
COUNT TO lnCnt FOR !DELETED()
SELECT (lnSel)
RETURN lnCnt
ENDFUNC
PROCEDURE TfErr
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
DO TfLog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
ENDPROC
PROCEDURE TfLog
LPARAMETERS tcMsg
SET SAFETY OFF
LOCAL lcL
lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '')
STRTOFILE(lcL + tcMsg + CHR(13)+CHR(10), gcUILog)
ENDPROC
DEFINE CLASS dummyapp AS Custom
PROCEDURE ReadIni
LPARAMETERS tcSection, tcKey
RETURN ''
ENDPROC
PROCEDURE WriteIni
LPARAMETERS tcSection, tcKey, tcValue
RETURN .T.
ENDPROC
ENDDEFINE
DEFINE CLASS dummyexecutor AS Custom
cEroare = ''
PROCEDURE oExecute
LPARAMETERS tcSql, tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF 'VJTVA_COLOANE' $ UPPER(m.tcSql)
DO CreeazaJtvaColoaneView WITH m.tcCursor
RETURN 1
ENDIF
IF UPPER(ALLTRIM(m.tcCursor)) == 'RUL_TEMP'
DO CreeazaRulTemp
ELSE
CREATE CURSOR (m.tcCursor) (id_temp N(1))
ENDIF
RETURN 1
ENDPROC
PROCEDURE oExecuta
LPARAMETERS tcSql, tcCursor
IF !EMPTY(m.tcCursor)
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF UPPER(m.tcCursor) == 'CJTVACOL4427'
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14))
ELSE
CREATE CURSOR (m.tcCursor) (id_temp N(1))
ENDIF
ENDIF
RETURN .T.
ENDPROC
PROCEDURE oSelect2Value
LPARAMETERS tcSql, toValue
toValue = ''
RETURN 1
ENDPROC
PROCEDURE oReset
ENDPROC
ENDDEFINE
PROCEDURE CreeazaJtvaColoaneView
LPARAMETERS tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14), denumire C(100), jc N(1), jv N(1), ;
coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14) NULL, afisat N(1), ;
id_jtva_ex N(14) NULL, id_jtva_neex N(14) NULL, ordine N(8), ;
taxcode N(6) NULL, taxcode_neexigibil N(6) NULL, taxcode_n50 N(6) NULL, ;
taxcode_n50_tvai N(6) NULL, taxcode_n100 N(6) NULL, taxcode_regularizare N(6) NULL, taxcode_tvai N(6) NULL)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, afisat, ordine, cota_tva) VALUES (0, '', 0, 0, 1, 0, 0)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (208, 'ACH. INT. 21%', 1, 0, 'RO21B', 21, 209, 1, 1, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (209, 'TVA ACH. INT. 21%', 1, 0, 'RO21T', 21, 1, 2, 301104)
ENDPROC

View File

@@ -0,0 +1,14 @@
# test_tva_secundare.ps1 - wrapper subtire peste harness-ul generic vfp_ui_harness.ps1.
# Runda30: garda cScc.Valid (Thisform.nOldVal) arma sincronizarea si cand grila a scris deja
# valoarea in cursor (cazul Enter); T-urile documentelor SECUNDARE se regrupeaza pe creditorii
# (scc/ascc) randurilor S proportional cu bazele, in sparge_document si in recalc_tva_document.
# Rulare: powershell -ExecutionPolicy Bypass -File test_tva_secundare.ps1
$ErrorActionPreference = 'Stop'
$Teste = $PSScriptRoot
& (Join-Path (Split-Path $Teste -Parent) 'vfp_ui_harness.ps1') `
-TestPrg (Join-Path $Teste 'test_tva_secundare.prg') `
-Steps @('stare_baza','bug2_regrupare_secundara','bug1_garda_scc','persistenta_regrupare','recalc_tva_secundara') `
-ShotsDir (Join-Path $Teste 'screenshots_tva_secundare') `
-SyncDir (Join-Path $Teste 'uisync_tva_secundare') `
-StepTimeoutSec 180 `
-ReadyTimeoutSec 180

View File

@@ -0,0 +1,25 @@
* mock_amessagebox.prg - inlocuieste FUNCTION amessagebox (din oproceduri_comune.prg) in teste,
* ca dialogurile modale de confirmare sa NU blocheze testul headless. Returneaza 6 (Da/OK) implicit.
* Se incarca ULTIMA cu SET PROCEDURE ... ADDITIVE - in VFP, la nume duplicat de procedura,
* castiga fisierul de proceduri deschis cel mai recent. Logheaza apelul (dovada rezolutiei).
* Configurabil per apel: daca testul declara PUBLIC gnMockRaspuns (implicit 6 daca nedeclarata),
* mock-ul returneaza acea valoare - necesar pt. meniuri cu raspunsuri diferite (6/7/2) pe acelasi
* dialog (ex. do_sterge/do_copiaza_nota, flag 3+32 Yes/No/Cancel).
* gnMockRaspunsTotal (PUBLIC, optional): cand testul declara aceasta variabila SUPLIMENTARA si
* mesajul primit contine "Actualizati totalul facturii" (runda25, Grid1.cSuma/cSumaVal.Valid),
* mock-ul raspunde cu ACEASTA valoare in loc de gnMockRaspuns - necesar cand doua dialoguri
* diferite (recalculare suma in lei / actualizare total factura) apar in ACELASI apel de metoda
* si trebuie sa primeasca raspunsuri diferite (ex. Da la primul, Nu la al doilea).
FUNCTION amessagebox
LPARAMETERS tcMessage, tnDialogBoxType, tcTitle, tcFont, tnTimeOut, tnTimeoutValue
LOCAL lnRaspuns
IF TYPE('gnMockRaspunsTotal') = 'N' AND 'Actualizati totalul facturii' $ tcMessage
lnRaspuns = gnMockRaspunsTotal
ELSE
lnRaspuns = IIF(TYPE('gnMockRaspuns') = 'N', gnMockRaspuns, 6)
ENDIF
IF TYPE('gcUILog') = 'C'
DO HarnessLog WITH 'MOCK amessagebox apelat: [' + ALLTRIM(TRANSFORM(tcMessage)) + '] -> returnez ' + TRANSFORM(lnRaspuns)
ENDIF
RETURN lnRaspuns
ENDFUNC

View File

@@ -0,0 +1,171 @@
* mock_cauta_alfa_dialog.prg - inlocuieste DOAR PROCEDURE cauta_alfa (COMUN\programe\cauta_alfa.prg,
* linia 16), NU cauta_nom_articole/XML2ListaIDDescriere/do_adauga_articol - acelea raman REALE,
* neatinse. Se incarca PRIMUL (inaintea "SET PROCEDURE TO cauta_alfa ADDITIVE") - la nume duplicat
* de procedura VFP foloseste fisierul incarcat PRIMUL (vezi docs/testare-ui-vfp.md capcana j).
*
* De ce: cauta_alfa() reala populeaza cursorul din Oracle prin gencursor->ca_baza.afisare(), care
* foloseste This.CursorFill() (CursorAdapter/conexiune reala) - nu goExecutor, deci nu poate fi
* mock-uit ca restul infrastructurii (vezi COMUN\clase\decabaza.vc2:36-99). Acest shadow inlocuieste
* DOAR sursa de date (Oracle -> cursor mock pre-populat de test) si bucla de asteptare modala
* (WindowType=1, Show() blocheaza pana la Release -> WindowType=0 + actiuni conduse programatic
* dupa Show(), vezi docs/testare-ui-vfp.md capcana g). Formularul e clasa REALA cauta_alfa_form
* (COMUN\clase\cauta_alfa_forms.vcx), metodele apelate (do_alege, do_termin, do_renunt) sunt cele
* REALE, neschimbate - doar interactiunea utilizatorului e simulata in loc de bucla de evenimente.
*
* IMPORTANT (capcana l, docs/testare-ui-vfp.md): CREATEOBJECT apelat DINTR-O PROCEDURA (nu din
* programul principal) intoarce un obiect stricat in acest runtime headless (verificat empiric -
* "OFORM_CAUTARE is not an object" la prima folosire). De aceea formularele NU se creeaza aici -
* testul principal le PRE-CONSTRUIESTE inline (goDlgA/goDlgB/goDlgC) INAINTE sa apeleze
* do_adauga_articol, iar acest shadow doar SELECTEAZA obiectul potrivit dupa gcTestScenariu si ii
* apeleaza metodele reale (asta e simpla dispecerizare de metoda, nu CREATEOBJECT - functioneaza
* din procedura fara probleme).
*
* Control test (setate de testul principal INAINTE de fiecare apel):
* goDlgA / goDlgB / goDlgC - formularele REALE pre-construite (vezi test_picker_real_212.prg)
* gcTestScenariu - 'A' (marcheaza BULDOEXCAVATOR + OK), 'B' (nimic marcat + OK),
* 'C' (dublu-click pe denumire), altfel Cancel
* Rezultat expus (citit de testul principal dupa apel):
* gcTestGnButon, gcTestXML, gcTestLenXML, gcTestCAles, gcTestPcAles, gcTestRandiuriMarcate
Procedure cauta_alfa
Parameters tcselect,tcfiltru,tcschema,tcorder,tccoloana,tcTitlu,tcTitluColoane, ;
tcNume_Proc,tl_AllInList,tcFiltruOriginal,tcPrimaColoana, tnPornire, tnTipReturn, ;
tcIdColumn, tlDesktop, tcGroup, tcGridDynamicBackColor, tcGridToolTip, tlModParam, tcStringCriterii, ;
tcProceduraVerifica, tcProceduraCopiaza,tcLocate
LOCAL lcCursor, lcCursorXML, lcCAlesDupaMarcare
LOCAL oForm_cautare, oReturnScattObj
Private pcAles
pcAles = ""
gcTestRandiuriMarcate = 0
IF USED('crsReturnAlfa')
USE IN ('crsReturnAlfa')
ENDIF
*-- === selecteaza obiectul PRE-CONSTRUIT (vezi capcana l mai sus - fara CREATEOBJECT aici) ===
DO CASE
CASE gcTestScenariu == 'A'
oForm_cautare = goDlgA
CASE gcTestScenariu == 'B'
oForm_cautare = goDlgB
CASE gcTestScenariu == 'C'
oForm_cautare = goDlgC
OTHERWISE
oForm_cautare = goDlgA
ENDCASE
lcCursor = oForm_cautare.crs_cursor
*-- pcAles trebuie sa reflecte marcajul curent INAINTE de a incepe (formularul e deja afisat,
*-- creat in main); il sincronizez manual cu cAles-ul formularului la pornire, exact cum face
*-- BINDEVENT(Thisform,"lAles",...) + do_alege() in fluxul real (do_alege scrie in AMBELE,
*-- Thisform.cAles si pcAles - vezi cauta_alfa_forms.vc2:405-418).
pcAles = oForm_cautare.cAles
*-- === FAZA 1: marcare - simuleaza interactiunea utilizatorului cu formularul REAL ===
*-- IMPORTANT: NU se atinge oForm_cautare dupa do_termin()/do_renunt() - acele metode fac
*-- this.Release, care DISTRUGE efectiv formularul VFP (verificat empiric: accesarea unei
*-- proprietati dupa Release da eroare 1924 "is not an object", chiar daca alta variabila
*-- (goDlgA) inca "tine" referinta) - de-aia cauta_alfa.prg REAL insusi nu mai citeste nimic
*-- de pe oForm_cautare dupa .Show() decat prin pcAles/gnButon (variabile libere, nu proprietati
*-- de obiect). Orice diagnostic despre cAles trebuie capturat AICI, inainte de faza 2.
DO CASE
CASE gcTestScenariu == 'A'
*-- marcheaza randul BULDOEXCAVATOR prin mecanismul real (echivalentul click pe denumire /
*-- SPACE): do_alege() citeste RECNO() curent al cursorului si toggle-uie cAles la acea pozitie.
SELECT (lcCursor)
LOCATE FOR ALLTRIM(denumire) == 'BULDOEXCAVATOR'
IF FOUND()
oForm_cautare.do_alege()
ENDIF
lcCAlesDupaMarcare = oForm_cautare.cAles
IF TYPE('gcUILog') = 'C'
DO HarnessStep WITH 1, 'scenariul A: BULDOEXCAVATOR marcat (Thisform.cAles=[' + lcCAlesDupaMarcare + ']), inainte de OK real'
ENDIF
CASE gcTestScenariu == 'B'
*-- nimic marcat
SELECT (lcCursor)
GO TOP
lcCAlesDupaMarcare = oForm_cautare.cAles
CASE gcTestScenariu == 'C'
*-- "dublu-click pe denumire": in modul multi-select (lAles=.T., cazul cauta_nom_articole),
*-- BindEvent(dblClick->do_termin) NU se armeaza (cauta_alfa_forms.vc2:652 "If !Thisform.lales"),
*-- deci dublu-click = 2x acelasi Click -> do_alege() de 2 ori (marcheaza, apoi demarcheaza) -
*-- NU exista submit rapid pe dublu-click in acest dialog. Simulez exact gestul (2 click-uri pe
*-- Column1.Text1, handler-ul REAL) si documentez ca cursorul ramane nemarcat.
SELECT (lcCursor)
LOCATE FOR ALLTRIM(denumire) == 'BULDOEXCAVATOR'
IF FOUND()
oForm_cautare._GRID1.Column1.Text1.Click()
oForm_cautare._GRID1.Column1.Text1.Click()
ENDIF
lcCAlesDupaMarcare = oForm_cautare.cAles
IF TYPE('gcUILog') = 'C'
DO HarnessLog WITH 'scenariul C: dupa 2x Click (dublu-click simulat) cAles=[' + lcCAlesDupaMarcare + '] (astept ramas needecis, fara submit automat)'
ENDIF
OTHERWISE
lcCAlesDupaMarcare = oForm_cautare.cAles
ENDCASE
*-- diagnostic cerut de team lead: pcAles (variabila PRIVATE folosita mai jos in filtrul WHERE al
*-- XML-ului) vs Thisform.cAles (marcajul vizual/albastrit vazut de Marius) - trebuie sa fie
*-- SINCRONE la acest punct, INAINTE de faza 2 (inchidere), pentru ca acolo se pierde accesul.
gcTestPcAlesInainte = pcAles
gcTestCAlesInainte = lcCAlesDupaMarcare
*-- === FAZA 2: inchidere - butonul OK/Cancel REAL (this.Release -> oForm_cautare devine inert) ===
DO CASE
CASE gcTestScenariu == 'A' OR gcTestScenariu == 'B' OR gcTestScenariu == 'C'
oForm_cautare.do_termin() && butonul OK REAL (_frm_base.do_termin: gnButon=1, Release)
OTHERWISE
oForm_cautare.do_renunt()
ENDCASE
DOEVENTS FORCE
*-- === de aici incolo: cod IDENTIC cu cauta_alfa.prg original (COMUN\programe\cauta_alfa.prg,
*-- liniile 218-249) - aceeasi conditie, acelasi filtru (pcAles), acelasi CURSORTOXML. NU se mai
*-- atinge oForm_cautare (a fost Release-uit de do_termin/do_renunt mai sus). ===
lcCursorXML = ""
SELECT (lcCursor)
IF gnButon=1
Do Case
Case tnTipReturn = 0
Scatter Name oReturnScattObj Memo
Otherwise
Select * From (lcCursor) With (Buffering = .T.) Where Substr(pcAles,Recno(),1) = 'X' ;
INTO Cursor crsReturnAlfa
Cursortoxml("crsReturnAlfa", "lcCursorXML", 2, 0+2+8, 0, "1")
gcTestRandiuriMarcate = RECCOUNT('crsReturnAlfa')
Use In crsReturnAlfa
Endcase
Else
Do Case
Case tnTipReturn = 0
Scatter Name oReturnScattObj Blank
Otherwise
lcCursorXML = ""
Endcase
Endif
*-- expus pentru diagnostic in testul principal (cAles luat din snapshot-ul de dinainte de
*-- Release - vezi FAZA 1 - NU de pe oForm_cautare, care e deja inert dupa do_termin/do_renunt)
gcTestGnButon = gnButon
gcTestXML = lcCursorXML
gcTestLenXML = LEN(m.lcCursorXML)
gcTestCAles = lcCAlesDupaMarcare
gcTestPcAles = pcAles
*-- NU dau Release aici (obiectul e deja Release-uit de do_termin/do_renunt mai sus)
Use In (lcCursor)
Do Case
Case tnTipReturn = 0
Return oReturnScattObj
Otherwise
Return lcCursorXML
Endcase
Endproc && cauta_alfa (shadow test)

View File

@@ -0,0 +1,45 @@
* mock_cauta_nom_articole.prg
* Bypass al dialogului real de cautare articole (cauta_alfa/CAUT, modal, nu poate rula
* headless) - dar returneaza XML in ACELASI format ca fluxul real (cauta_alfa.prg ~227/510:
* Cursortoxml(cursor,'var',2,0+2+8,0,'1') pe un cursor cu coloanele cerute de cauta_nom_articole:
* denumire,codmat,codbare,um,grupa,subgrupa,cont,acont,dnf,id_articol), ca sa exercite REAL
* do_adauga_articol din COMUN\clase\ointroduceri.vcx cu date controlate.
* Incarcat cu SET PROCEDURE ... ADDITIVE INAINTEA lui ocautare.prg (nume duplicat de procedura -
* castiga cel incarcat PRIMUL, la fel ca mock_amessagebox - vezi docs/testare-ui-vfp.md capcana j).
* gnButon trebuie sa existe deja (PUBLIC) in programul principal al testului - vezi
* Programe/roagest.prg:496 (PRIVATE gnButon la nivelul de top al aplicatiei reale, de-aia
* functioneaza gnButon "gol" in tot lantul de apeluri); mock-ul doar il seteaza (fara PRIVATE),
* ca sa actualizeze variabila existenta, nu sa creeze una noua locala functiei.
* gcMockArtCodmat (PUBLIC, optional): daca testul o declara/seteaza inainte de a apela
* do_adauga_articol(), mock-ul returneaza articolul cu acel codmat (vezi lista de mai jos) in loc
* de BULDOEXCAVATOR (implicit) - permite testelor cu mai multe articole (runda7) sa controleze ce
* articol "gaseste" dialogul real la fiecare apel, fara sa schimbe comportamentul testelor vechi.
FUNCTION cauta_nom_articole
LPARAMETERS tcFiltruOriginal, tnPornire, tlLoud, tcListaId, tcListaDenumire
gnButon = 1
LOCAL lcXML, lcCodmatCautat
lcCodmatCautat = IIF(TYPE('gcMockArtCodmat') = 'C' AND !EMPTY(gcMockArtCodmat), gcMockArtCodmat, 'ART-BULD-212')
IF USED('crsMockCautaArt')
USE IN ('crsMockCautaArt')
ENDIF
CREATE CURSOR crsMockCautaArt (denumire C(100), codmat C(30), codbare C(30), um C(10), ;
grupa C(10), subgrupa C(10), cont C(10), acont C(20), dnf C(10), id_articol N(14))
DO CASE
CASE lcCodmatCautat == 'ART-GREE-303'
INSERT INTO crsMockCautaArt (denumire, codmat, codbare, um, grupa, subgrupa, cont, acont, dnf, id_articol) ;
VALUES ('AC GREE BORA', 'ART-GREE-303', '', 'BUC', '', '', '303', '', '', 9002)
CASE lcCodmatCautat == 'ART-A8-371'
INSERT INTO crsMockCautaArt (denumire, codmat, codbare, um, grupa, subgrupa, cont, acont, dnf, id_articol) ;
VALUES ('A8', 'ART-A8-371', '8003510000203', 'BUC', '', '', '371', '', '', 9003)
OTHERWISE
INSERT INTO crsMockCautaArt (denumire, codmat, codbare, um, grupa, subgrupa, cont, acont, dnf, id_articol) ;
VALUES ('BULDOEXCAVATOR', 'ART-BULD-212', '', 'BUC', '', '', '212', '', '', 9001)
ENDCASE
lcXML = ''
Cursortoxml('crsMockCautaArt', 'lcXML', 2, 0+2+8, 0, '1')
USE IN ('crsMockCautaArt')
RETURN lcXML
ENDFUNC

View File

@@ -0,0 +1,64 @@
* ui_harness.prg - proceduri reutilizabile pentru teste UI VFP cu handshake pe semafoare.
* Un test seteaza PUBLIC gcSyncDir (folder semafoare, cu \ final) si gcUILog (fisier log),
* apoi SET PROCEDURE TO ui_harness ADDITIVE si foloseste:
* HarnessLog(mesaj) - scrie o linie in log
* HarnessStep(n, mesaj [, autoSec]) - semnaleaza pasul n gata + asteapta continuarea
* HarnessReady(n, mesaj) / HarnessWaitContinue(n [, autoSec]) - variantele separate
* HarnessDone([status]) - scrie done.txt
* HarnessWaitContinue asteapta cont_<n>.txt; daca nu apare in autoSec secunde (implicit 30),
* continua singur (auto-continue) => testul merge si FARA orchestrator (doar log, fara capturi).
PROCEDURE HarnessInit
*-- defensiv: SAFETY OFF ca STRTOFILE peste un fisier existent sa nu scoata dialogul modal
*-- "overwrite?" (blocheaza headless); TALK OFF ca SUM/CALCULATE sa nu deseneze pe desktop.
*-- Un test ar trebui sa faca oricum SET SAFETY OFF INAINTE de prima lui scriere de log.
SET SAFETY OFF
SET TALK OFF
ENDPROC
PROCEDURE HarnessLog
LPARAMETERS tcMsg
IF TYPE('gcUILog') <> 'C' OR EMPTY(gcUILog)
RETURN
ENDIF
SET SAFETY OFF
LOCAL lcL
lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '')
STRTOFILE(lcL + tcMsg + CHR(13)+CHR(10), gcUILog)
ENDPROC
PROCEDURE HarnessReady
LPARAMETERS tnStep, tcNote
SET SAFETY OFF
STRTOFILE(TTOC(DATETIME()) + ' ' + tcNote + CHR(13)+CHR(10), gcSyncDir + 'ready_' + TRANSFORM(tnStep) + '.txt')
HarnessLog('READY ' + TRANSFORM(tnStep) + ' - ' + tcNote)
ENDPROC
FUNCTION HarnessWaitContinue
LPARAMETERS tnStep, tnAutoSec
LOCAL lcCont, lnMax, lnI, llPrimit
lcCont = gcSyncDir + 'cont_' + TRANSFORM(tnStep) + '.txt'
lnMax = IIF(TYPE('tnAutoSec') = 'N' AND tnAutoSec > 0, tnAutoSec, 30)
lnI = 0
DO WHILE !FILE(lcCont) AND lnI < (lnMax * 5)
lnI = lnI + 1
DOEVENTS FORCE
= INKEY(0.2)
ENDDO
llPrimit = FILE(lcCont)
HarnessLog('CONTINUE ' + TRANSFORM(tnStep) + IIF(llPrimit, ' (semnal primit)', ' (auto-continue dupa ' + TRANSFORM(lnMax) + 's)'))
RETURN llPrimit
ENDFUNC
PROCEDURE HarnessStep
LPARAMETERS tnStep, tcNote, tnAutoSec
HarnessReady(tnStep, tcNote)
HarnessWaitContinue(tnStep, tnAutoSec)
ENDPROC
PROCEDURE HarnessDone
LPARAMETERS tcStatus
SET SAFETY OFF
STRTOFILE(IIF(EMPTY(tcStatus), 'done', tcStatus) + ' ' + TTOC(DATETIME()) + CHR(13)+CHR(10), gcSyncDir + 'done.txt')
HarnessLog('GATA')
ENDPROC

View File

@@ -0,0 +1,222 @@
# vfp_ui_harness.ps1 - harness reutilizabil pentru teste UI VFP cu capturi de ecran.
# Lanseaza un test VFP care afiseaza un formular real, il conduce pas cu pas prin semafoare
# (ready_<n>.txt scris de test <-> cont_<n>.txt scris de harness), face un screenshot dupa
# fiecare pas si il valideaza. Testul VFP foloseste procedurile din ui_harness.prg.
#
# Exemplu:
# powershell -ExecutionPolicy Bypass -File vfp_ui_harness.ps1 `
# -TestPrg 'D:\...\test_x_ui.prg' -Steps @('afisat','actiune1','actiune2')
#
# Capcane rezolvate (vezi docs\testare-ui-vfp.md): precompilare izolata, lansare .fxp,
# detectie pornire pe mtime log, timeout-uri generoase, kill zombi vfp9.
#
# FARA FURT DE FOCUS (cerinta Marius, 17/07/2026): capturile NU mai folosesc
# Graphics.CopyFromScreen (poza ecranului intreg - fura focus / se corupe daca utilizatorul
# lucreaza in paralel). Se foloseste PrintWindow pe handle-ul ferestrei vfp9 + fereastra e
# mutata OFF-SCREEN (x=-4000, HWND_BOTTOM, SWP_NOACTIVATE) imediat ce apare handle-ul si
# re-impinsa inainte de fiecare pas (VFP isi poate re-activa fereastra la Show()/dialoguri).
# Fereastra ramane "visible" pentru GDI (PrintWindow merge), doar nu e pe ecranul vizibil
# utilizatorului si nu ia focus.
param(
[Parameter(Mandatory=$true)][string]$TestPrg,
[Parameter(Mandatory=$true)][string[]]$Steps, # etichete pentru pasii 0..N-1
[int]$StepTimeoutSec = 130, # cat astept fiecare ready_<n> (dupa pas 0)
[int]$ReadyTimeoutSec = 180, # cat astept ready_0 (afisarea formularului, incarcare lenta)
[string]$ShotsDir,
[string]$SyncDir,
[string]$Vfp = 'C:\Program Files (x86)\Microsoft Visual FoxPro 9\vfp9.exe'
)
$ErrorActionPreference = 'Stop'
$TestDir = [System.IO.Path]::GetDirectoryName($TestPrg)
$TestFxp = [System.IO.Path]::ChangeExtension($TestPrg, 'fxp')
$TestLog = [System.IO.Path]::ChangeExtension($TestPrg, $null) + '_log.txt'
if (-not $SyncDir) { $SyncDir = Join-Path $TestDir 'uisync' }
if (-not $ShotsDir) { $ShotsDir = Join-Path $TestDir 'screenshots' }
$Precompile = Join-Path $PSScriptRoot '_precompile.ps1'
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
Add-Type @"
using System;
using System.Runtime.InteropServices;
public class Win32Ui {
[StructLayout(LayoutKind.Sequential)]
public struct RECT { public int Left, Top, Right, Bottom; }
[DllImport("user32.dll")]
public static extern bool PrintWindow(IntPtr hwnd, IntPtr hdc, uint nFlags);
[DllImport("user32.dll")]
public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
[DllImport("user32.dll")]
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
[DllImport("user32.dll")]
public static extern bool IsWindow(IntPtr hWnd);
public static readonly IntPtr HWND_BOTTOM = new IntPtr(1);
public const uint SWP_NOSIZE = 0x0001;
public const uint SWP_NOACTIVATE = 0x0010;
public const uint SWP_NOZORDER = 0x0004;
}
"@
function Clear-Dir([string]$Dir) {
if (Test-Path $Dir) {
Get-ChildItem -Path $Dir -File -ErrorAction SilentlyContinue | ForEach-Object {
try { [System.IO.File]::Delete($_.FullName) } catch {}
}
} else { New-Item -ItemType Directory -Path $Dir | Out-Null }
}
# Muta fereastra vfp9 off-screen (x=-4000), fara sa o activeze/minimizeze - ramane randabila
# pentru PrintWindow, dar nu se vede si nu fura focus. Se cheama repetat (VFP isi reactiveaza
# singur fereastra la Show()/dialoguri modale).
function Push-Offscreen([IntPtr]$Hwnd) {
if ($Hwnd -eq [IntPtr]::Zero) { return }
if (-not [Win32Ui]::IsWindow($Hwnd)) { return }
[Win32Ui]::SetWindowPos($Hwnd, [Win32Ui]::HWND_BOTTOM, -4000, 0, 0, 0, ([Win32Ui]::SWP_NOSIZE -bor [Win32Ui]::SWP_NOACTIVATE)) | Out-Null
}
# Polleaza MainWindowHandle pana devine nenul (fereastra principala vfp9 aparuta).
function Wait-MainWindowHandle([System.Diagnostics.Process]$Proc, [int]$TimeoutSec) {
$deadline = (Get-Date).AddSeconds($TimeoutSec)
while ((Get-Date) -lt $deadline) {
try {
$Proc.Refresh()
if ($Proc.HasExited) { return [IntPtr]::Zero }
if ($Proc.MainWindowHandle -ne [IntPtr]::Zero) { return $Proc.MainWindowHandle }
} catch {}
Start-Sleep -Milliseconds 200
}
return [IntPtr]::Zero
}
function Wait-File([string]$Path, [int]$TimeoutSec, [IntPtr]$Hwnd = [IntPtr]::Zero) {
$deadline = (Get-Date).AddSeconds($TimeoutSec)
while (-not (Test-Path $Path)) {
if ((Get-Date) -gt $deadline) { return $false }
if ($Hwnd -ne [IntPtr]::Zero) { Push-Offscreen $Hwnd }
Start-Sleep -Milliseconds 300
}
return $true
}
# Captura pe HANDLE cu PrintWindow (nu depinde de foreground/ecran vizibil). flag 2 =
# PW_RENDERFULLCONTENT (randare completa, necesar pt. multe ferestre GDI+/themed); daca da
# imagine goala, se incearca fallback cu flag 0.
function Take-Screenshot([IntPtr]$Hwnd, [string]$Path) {
if ($Hwnd -eq [IntPtr]::Zero -or -not [Win32Ui]::IsWindow($Hwnd)) {
Write-Warning "Take-Screenshot: handle invalid, sar captura ($Path)."
return
}
$rect = New-Object Win32Ui+RECT
[Win32Ui]::GetWindowRect($Hwnd, [ref]$rect) | Out-Null
$w = $rect.Right - $rect.Left
$h = $rect.Bottom - $rect.Top
if ($w -le 0 -or $h -le 0) { $w = 1920; $h = 1080 }
$bmp = New-Object System.Drawing.Bitmap $w, $h
$g = [System.Drawing.Graphics]::FromImage($bmp)
$hdc = $g.GetHdc()
$ok = [Win32Ui]::PrintWindow($Hwnd, $hdc, 2)
$g.ReleaseHdc($hdc)
$g.Dispose()
if (-not $ok) {
$g2 = [System.Drawing.Graphics]::FromImage($bmp)
$hdc2 = $g2.GetHdc()
[Win32Ui]::PrintWindow($Hwnd, $hdc2, 0) | Out-Null
$g2.ReleaseHdc($hdc2)
$g2.Dispose()
}
$bmp.Save($Path, [System.Drawing.Imaging.ImageFormat]::Png)
$bmp.Dispose()
}
Clear-Dir $SyncDir
Clear-Dir $ShotsDir
# 1) Precompilare izolata (proces copil complet, ca sa nu otraveasca sesiunea de lansare).
# -WindowStyle Hidden pe consola powershell copil (sigur - e consola, nu GUI VFP).
Write-Host "Precompilez .fxp (izolat): $Precompile -Prg $TestPrg"
Get-Process vfp9 -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
Start-Sleep -Milliseconds 500
$pc = Start-Process powershell -WindowStyle Hidden -ArgumentList @('-ExecutionPolicy','Bypass','-File', "`"$Precompile`"", '-Prg', "`"$TestPrg`"") -Wait -PassThru
Start-Sleep -Seconds 2
Get-Process vfp9 -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
Start-Sleep -Seconds 2
if (-not (Test-Path $TestFxp)) { Write-Warning "Nu s-a generat $TestFxp - compilare esuata." }
# 2) Lansez .FXP-ul (nu .prg-ul). vfp9 -A porneste uneori procesul FARA sa execute (log gol);
# discriminator: START e prima linie a testului (mtime log > momentul lansarii) => in ~2s daca
# ruleaza. Relansez doar daca log-ul nu e scris in 30s (instanta moarta). Apoi astept ready_0.
# Imediat ce apare MainWindowHandle, fereastra e impinsa off-screen (fara activare).
$ready0 = Join-Path $SyncDir 'ready_0.txt'
$started = $false
$hwnd = [IntPtr]::Zero
foreach ($try in 1..8) {
if (Test-Path $ready0) { [System.IO.File]::Delete($ready0) }
if (Test-Path $TestLog) { [System.IO.File]::Delete($TestLog) }
$t0 = Get-Date
Write-Host "Lansez VFP (incercarea $try): $Vfp -A $TestFxp"
$proc = Start-Process -FilePath $Vfp -ArgumentList @('-A', "`"$TestFxp`"") -PassThru
$dl = (Get-Date).AddSeconds(30)
while ((Get-Date) -lt $dl) {
if ($hwnd -eq [IntPtr]::Zero -and -not $proc.HasExited) {
$proc.Refresh()
if ($proc.MainWindowHandle -ne [IntPtr]::Zero) {
$hwnd = $proc.MainWindowHandle
Push-Offscreen $hwnd
}
} else {
Push-Offscreen $hwnd
}
if ((Test-Path $TestLog) -and ((Get-Item $TestLog).LastWriteTime -gt $t0)) { $started = $true; break }
if (Test-Path $ready0) { $started = $true; break }
Start-Sleep -Milliseconds 500
}
if ($started) { break }
Write-Warning "Incercarea ${try}: testul nu a scris START in 30s (instanta moarta); relansez."
if ($proc -and -not $proc.HasExited) { try { $proc.Kill() } catch {} }
Get-Process vfp9 -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
Start-Sleep -Milliseconds 1500
$hwnd = [IntPtr]::Zero
}
# Daca handle-ul principal inca nu a aparut (formular aditional creat mai tarziu), mai astept putin.
if ($hwnd -eq [IntPtr]::Zero) { $hwnd = Wait-MainWindowHandle $proc 15 }
Push-Offscreen $hwnd
if (-not (Wait-File $ready0 $ReadyTimeoutSec $hwnd)) {
Write-Warning "Testul nu a ajuns la ready_0 in ${ReadyTimeoutSec}s. Ultima linie log: '$(Get-Content $TestLog -Tail 1 -ErrorAction SilentlyContinue)'"
}
# 3) Parcurg pasii: astept ready_<n> (re-impingand fereastra off-screen periodic), screenshot
# pe handle (PrintWindow), scriu cont_<n>.
$ok = $true
for ($n = 0; $n -lt $Steps.Count; $n++) {
$label = $Steps[$n]
$ready = Join-Path $SyncDir ("ready_{0}.txt" -f $n)
$cont = Join-Path $SyncDir ("cont_{0}.txt" -f $n)
Write-Host "Astept pasul $n ($label)"
if (-not (Wait-File $ready $StepTimeoutSec $hwnd)) {
Write-Warning "TIMEOUT la pasul $n."
$ok = $false
break
}
Write-Host (" ready: {0}" -f (Get-Content $ready -Raw).Trim())
# daca fereastra principala s-a schimbat intre timp (formular nou), reincerc handle-ul
if ($hwnd -eq [IntPtr]::Zero -or -not [Win32Ui]::IsWindow($hwnd)) { $hwnd = Wait-MainWindowHandle $proc 5 }
Push-Offscreen $hwnd
Start-Sleep -Milliseconds 1200 # las formularul sa se deseneze complet
Push-Offscreen $hwnd
$png = Join-Path $ShotsDir ("step_{0}_{1}.png" -f $n, $label)
Take-Screenshot $hwnd $png
Write-Host " screenshot: $png"
Set-Content -Path $cont -Value 'go' -Encoding ascii
}
# 4) Astept done.txt si inchid.
if ($ok) {
$done = Join-Path $SyncDir 'done.txt'
if (Wait-File $done 30 $hwnd) { Write-Host "done: $((Get-Content $done -Raw).Trim())" }
}
Start-Sleep -Milliseconds 800
if ($proc -and -not $proc.HasExited) { try { $proc.Kill() } catch {} }
Get-Process vfp9 -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
Write-Host "GATA. Screenshots in $ShotsDir"