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:
171
utile/Teste/mock_cauta_alfa_dialog.prg
Normal file
171
utile/Teste/mock_cauta_alfa_dialog.prg
Normal 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)
|
||||
Reference in New Issue
Block a user