#6 editare factura emisa: runda 6 - nomenclatoare, zecimale, aspect grid, meniu

Pagina Articole din frm_modific2024:
- DblClick pe cele cinci coloane cu nomenclator (articol, gestiune, taxcode,
  valuta, explicatie TVA). Explicatia TVA are ControlSource expresie, deci
  tastarea nu putea declansa niciodata InteractiveChange; DblClick se sprijina
  pe pccontrol si acopera uniform toate cele cinci.
- Pret si Pret cu TVA folosesc gnPPretV (precizie pret vanzare) in loc de
  gnPPret (precizie achizitie). Coloana de pret achizitie ramane pe gnPPret.
- Culori dupa conventia de pe pagina Rulaje: verde pe coloanele care se
  editeaza prin dialog, alb pe cele care se tasteaza direct.
- Serie, lot si explicatie devin editabile in celula. Garda .When ramane si
  blocheaza in continuare liniile din seturi si facturile din e-Factura.

frm_facturi: textul optiunii de editare factura din meniul contextual devine
"Editare factura (note, rulaje, articole)".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013gYCNE26G1G7UoGu2ju7aS
This commit is contained in:
2026-08-20 16:28:02 +03:00
parent 09ddeabb1c
commit b9a14bcb9c
13 changed files with 906 additions and 258 deletions

View File

@@ -14070,8 +14070,8 @@ DEFINE CLASS frm_facturare_articole AS _frmbase OF "_frm_base.vcx"
Alltrim(Str(poArt.id_articol)) + [,] + ;
['] + OracleSpecialCharacters(Alltrim(Nvl(poArt.serie,[]))) + [',] + ;
['] + OracleSpecialCharacters(Alltrim(Nvl(poArt.explicatie,''))) + [',] + Nvl(Alltrim(Str(poArt.id_pol)),[NULL]) + [,] + ;
Nvl(Alltrim(Str(poArt.id_gestiune)),[NULL]) + [,] + Alltrim(Str(poArt.pret_achizitie,18,gnPPret)) + [,] + ;
Alltrim(Str(poArt.pretd,18,gnPPretval)) + [,] + ;
Nvl(Alltrim(Str(poArt.id_gestiune)),[NULL]) + [,] + Alltrim(Str(poArt.pret_achizitie,18,Max(gnPPret,4))) + [,] + ;
Alltrim(Str(poArt.pretd,18,Max(gnPPretval,4))) + [,] + ;
Iif(Isnull(poArt.id_valuta_d),[NULL],Alltrim(Str(poArt.id_valuta_d))) + [,] + ;
IIF(poArt.cu_tva=0,;
IIF(poArt.tip_valuta = 0,Alltrim(Str(poArt.pretftva,18,gnPPretV)),Alltrim(Str(poArt.vpretftva,18,gnPVal))),;
@@ -14084,7 +14084,7 @@ DEFINE CLASS frm_facturare_articole AS _frmbase OF "_frm_base.vcx"
['] + Alltrim(Nvl(poArt.Cont,'')) + [',] + Alltrim(Str(poArt.Curs,18,6)) + [,] + ;
ALLTRIM(STR(poArt.multiplicator,10)) + [,] + Alltrim(Str(poArt.id_jtva_coloana)) + [,] + ;
Nvl(Alltrim(Str(poArt.id_part_rez)),[NULL]) + [,] + Nvl(Alltrim(Str(poArt.id_lucrare_rez)),[NULL]) + [,] + ;
Alltrim(Str(poArt.pretv_orig,18,gnPPretV)) + [,] + ;
Alltrim(Str(poArt.pretv_orig,18,Max(gnPPretV,4))) + [,] + ;
Nvl(Alltrim(Str(poArt.id_set_fact)),[NULL]) + [,] + NVL(ALLTRIM(STR(poArt.id_ctr)),[NULL]) + [,] + Alltrim(Str(gnIdUtil)) + [,] + ;
NVL(ALLTRIM(STR(poArt.taxcode)),[NULL]) + ;
[,'] + OracleSpecialCharacters(Alltrim(Nvl(poArt.lot,[]))) + ['] + ;
@@ -18105,8 +18105,8 @@ DEFINE CLASS frm_facturare_articole2 AS _frmbase OF "_frm_base.vcx"
Alltrim(Str(poArt.id_articol)) + [,] + ;
['] + OracleSpecialCharacters(Alltrim(Nvl(poArt.serie,[]))) + [',] + ;
['] + OracleSpecialCharacters(Alltrim(Nvl(poArt.explicatie,''))) + [',] + Nvl(Alltrim(Str(poArt.id_pol)),[NULL]) + [,] + ;
Nvl(Alltrim(Str(poArt.id_gestiune)),[NULL]) + [,] + Alltrim(Str(poArt.pret_achizitie,18,gnPPret)) + [,] + ;
Alltrim(Str(poArt.pretd,18,gnPPretval)) + [,] + ;
Nvl(Alltrim(Str(poArt.id_gestiune)),[NULL]) + [,] + Alltrim(Str(poArt.pret_achizitie,18,Max(gnPPret,4))) + [,] + ;
Alltrim(Str(poArt.pretd,18,Max(gnPPretval,4))) + [,] + ;
Iif(Isnull(poArt.id_valuta_d),[NULL],Alltrim(Str(poArt.id_valuta_d))) + [,] + ;
IIF(poArt.cu_tva=0,;
IIF(poArt.tip_valuta = 0,Alltrim(Str(poArt.pretftva,18,gnPPretV)),Alltrim(Str(poArt.vpretftva,18,gnPVal))),;
@@ -18119,7 +18119,7 @@ DEFINE CLASS frm_facturare_articole2 AS _frmbase OF "_frm_base.vcx"
['] + Alltrim(Nvl(poArt.Cont,'')) + [',] + Alltrim(Str(poArt.Curs,18,6)) + [,] + ;
ALLTRIM(STR(poArt.multiplicator,10)) + [,] + Alltrim(Str(poArt.id_jtva_coloana)) + [,] + ;
Nvl(Alltrim(Str(poArt.id_part_rez)),[NULL]) + [,] + Nvl(Alltrim(Str(poArt.id_lucrare_rez)),[NULL]) + [,] + ;
Alltrim(Str(poArt.pretv_orig,18,gnPPretV)) + [,] + ;
Alltrim(Str(poArt.pretv_orig,18,Max(gnPPretV,4))) + [,] + ;
Nvl(Alltrim(Str(poArt.id_set_fact)),[NULL]) + [,] + NVL(ALLTRIM(STR(poArt.id_ctr)),[NULL]) + [,] + Alltrim(Str(gnIdUtil)) + [);]
*!* v 2.0.13 ^
*!* modificare v 2.0.67

View File

@@ -4927,7 +4927,7 @@ DEFINE CLASS frm_facturi AS _frmbase OF "_frm_base.vcx"
PROCEDURE inainte_de_do_modifica
Local lnOptiune
lnOptiune = xmenu('Modificare \<date factura;Editare \<factura (articole, cantitati, preturi)')
lnOptiune = xmenu('Modificare \<date factura;Editare \<factura (note, rulaje, articole)')
Do Case
Case lnOptiune = 1
This.do_modifica()

File diff suppressed because it is too large Load Diff

View File

@@ -43,6 +43,13 @@
propune COMPLETAREA unei functii/tabele/view comune, nu o varianta paralela. 80/20: solutia cea
mai simpla care rezolva cazul real. Completeaza `inventar-comun.md` la orice descoperire/creare
de element comun nedocumentat.
**Cod nou: clase in `.prg`, nu metode in `.vcx`/`.scx`.** Logica se incapsuleaza intr-o clasa
(`Define Class ... As Custom`) dintr-un `.prg`; formularul sau clasa vizuala doar instantiaza
obiectul (`Createobject`) si il apeleaza, metoda din binar ramanand un apel de o linie. Sablon:
`COMUN\programe\anaf_efactura.prg` (`AnafeFacturaServer`, `ANAFeFactura`), apelat din
`clase\anaf_efactura.vcx`. Motivul e de intretinere: un `.prg` se editeaza direct si diff-ul lui
se citeste in git, pe cand codul pus ca metoda in binar trece prin FoxBin2Prg si write-back si
se urmareste greu.
4. Testare headless (fara IDE): `vfp9.exe -A -T "<script.prg>" <param>` din PowerShell.
Mediu, sabloane, capcane, depanare: `depanare_testare_vfp.md`.
5. Editare .vcx/.scx pe text (cache, cp1250 byte-safe, fidelity-check): `flux-editare-vfp-text.md`.

View File

@@ -52,3 +52,4 @@ INTERESUL MEU ESTE SA SIMPLIFIC INTERFATA, SA FIE MAI EFICIENTA, SA NU FIE 2 FOR
20. ROAFACTURARE - FACTURA DIN COMANDA, COMANDA SE CONSIDERA FACTURATA DACA EXISTA FACTURI CU ACELEASI CANTITATI. AS VREA SA PUN MARKER DE FACTURAT PE COMANDA, CA SA NU MAI CAUT FACTURI - ESTE COSTISITOR. DOAR CA TREBUIE SA FII ATENT CA O COMANDA SE POATE FACTURA TOTAL/PARTIAL, SAU DIN MAI MULTE FACTURI, SAU SE POATE INCHIDE FORTAT. ACUM INCHIDEREA FORTATA ADAUGA CANTITATI NEGATIVE PE COMANDA, CA SA FACA CANTITATILE NEFACTURATE ZERO.
21. ROACONT - in formularul de verificare coduri fiscale, ar trebui sa fie si perioadele de tva, tva incasare, inactivitate, la fel ca in istoric, pentru ca utilizatorul sa nu mai caute altundeva. de asemenea, in messagebox pentru verificarea automata pe ANAF individuala ar trebui sa fie toate aceste informatii. sa se poata edita partenerul din formularul de verificare coduri fiscale prin dublu-click pe numele/codul fiscal al partenerului, similar cu formularul saft.

View File

@@ -11,7 +11,9 @@
*!* pentru adaugarea unei linii noi prin dialogul frm_articol_factura (populat cu valuta documentului
*!* cand acesta e in valuta), scrierea in VANZARI_DETALII a liniilor editate/adaugate/sterse, si
*!* compararea/aplicarea sincronizarii cantitate/pret intre rulaje (trul) si articolele facturii (tvd),
*!* agregate pe id_articol, in ambele sensuri (documentele in valuta raman doar semnalate, neaplicate)
*!* agregate pe id_articol, in ambele sensuri (documentele in valuta raman doar semnalate, neaplicate);
*!* pe linia de articol se poate alege si explicatia TVA (filtrata pe cota liniei), care recoreleaza
*!* codul SAF-T, iar liniile deja salvate se actualizeaza cu toate campurile pe care grila le schimba
*!* parametru: id_fact
@@ -498,8 +500,22 @@ FUNCTION ScrieArticoleFacturaEditate
SELECT (m.lcAliasArt)
lnRecnoArt = Recno()
SCAN FOR id_vanzare_det > 0 AND Nvl(sters,0) <> 1
*!* toate campurile pe care grila si nomenclatoarele le pot schimba - altfel alegerile de pe
*!* liniile deja salvate (cod TVA, explicatie TVA, gestiune, valuta, articol) s-ar pierde tacut
lcSql = [update vanzari_detalii set sters = 0, cantitate = ] + Alltrim(Str(Nvl(cantitate,0),18,3)) + ;
[, pret = ] + Alltrim(Str(Nvl(pret,0),18,4)) + [, pret_cu_tva = ] + Alltrim(Str(Nvl(pret_cu_tva,0))) + ;
[, pret_achizitie = ] + Iif(Isnull(pret_achizitie),[NULL],Alltrim(Str(pret_achizitie,18,4))) + ;
[, proc_tvav = ] + Iif(Isnull(proc_tvav),[NULL],Alltrim(Str(proc_tvav,18,4))) + ;
[, discount_unitar = ] + Iif(Isnull(discount_unitar),[NULL],Alltrim(Str(discount_unitar,18,4))) + ;
[, id_articol = ] + Iif(Isnull(id_articol),[NULL],Alltrim(Str(id_articol))) + ;
[, id_gestiune = ] + Iif(Isnull(id_gestiune),[NULL],Alltrim(Str(id_gestiune))) + ;
[, id_valuta = ] + Iif(Isnull(id_valuta),[NULL],Alltrim(Str(id_valuta))) + ;
[, id_jtva_coloana = ] + Iif(Isnull(id_jtva_coloana),[NULL],Alltrim(Str(id_jtva_coloana))) + ;
[, taxcode = ] + Iif(Isnull(taxcode),[NULL],Alltrim(Str(taxcode))) + ;
[, cont = ] + Iif(Empty(Nvl(cont,'')),[NULL],['] + OracleSpecialCharacters(Alltrim(Nvl(cont,''))) + [']) + ;
[, serie = ] + Iif(Empty(Nvl(serie,'')),[NULL],['] + OracleSpecialCharacters(Alltrim(Nvl(serie,''))) + [']) + ;
[, explicatie = ] + Iif(Empty(Nvl(explicatie,'')),[NULL],['] + OracleSpecialCharacters(Alltrim(Nvl(explicatie,''))) + [']) + ;
[, lot = ] + Iif(Empty(Nvl(lot,'')),[NULL],['] + OracleSpecialCharacters(Alltrim(Nvl(lot,''))) + [']) + ;
[, id_utils = ] + Alltrim(Str(gnIdUtil)) + [, dataoras = sysdate ] + ;
[where id_vanzare_det = ] + Alltrim(Str(id_vanzare_det)) + [ and id_vanzare = ] + Alltrim(Str(m.tnIdVanzare))
llSucces = goExecutor.oExecuta(m.lcSql)
@@ -521,16 +537,16 @@ FUNCTION ScrieArticoleFacturaEditate
SCAN FOR id_vanzare_det = 0 AND Nvl(sters,0) <> 1
lcSql = [insert into vanzari_detalii (id_vanzare, id_articol, cantitate, pret, pret_cu_tva, proc_tvav, discount_unitar, ] + ;
[id_gestiune, cont, id_valuta, id_jtva_coloana, serie, explicatie, taxcode, lot, pret_achizitie, id_utils, dataoras) values (] + ;
Alltrim(Str(m.tnIdVanzare)) + [,] + Alltrim(Str(Nvl(id_articol,0))) + [,] + Alltrim(Str(Nvl(cantitate,0),18,3)) + [,] + ;
Alltrim(Str(Nvl(pret,0),18,4)) + [,] + Alltrim(Str(Nvl(pret_cu_tva,0))) + [,] + Alltrim(Str(Nvl(proc_tvav,0),18,4)) + [,] + ;
Alltrim(Str(Nvl(discount_unitar,0),18,4)) + [,] + Iif(Isnull(id_gestiune),[NULL],Alltrim(Str(id_gestiune))) + [,] + ;
Alltrim(Str(m.tnIdVanzare)) + [,] + Iif(Isnull(id_articol),[NULL],Alltrim(Str(id_articol))) + [,] + Alltrim(Str(Nvl(cantitate,0),18,3)) + [,] + ;
Alltrim(Str(Nvl(pret,0),18,4)) + [,] + Alltrim(Str(Nvl(pret_cu_tva,0))) + [,] + Iif(Isnull(proc_tvav),[NULL],Alltrim(Str(proc_tvav,18,4))) + [,] + ;
Iif(Isnull(discount_unitar),[NULL],Alltrim(Str(discount_unitar,18,4))) + [,] + Iif(Isnull(id_gestiune),[NULL],Alltrim(Str(id_gestiune))) + [,] + ;
Iif(Empty(Nvl(cont,'')),[NULL],['] + OracleSpecialCharacters(Alltrim(Nvl(cont,''))) + [']) + [,] + ;
Iif(Isnull(id_valuta),[NULL],Alltrim(Str(id_valuta))) + [,] + Iif(Isnull(id_jtva_coloana),[NULL],Alltrim(Str(id_jtva_coloana))) + [,] + ;
Iif(Empty(Nvl(serie,'')),[NULL],['] + OracleSpecialCharacters(Alltrim(Nvl(serie,''))) + [']) + [,] + ;
Iif(Empty(Nvl(explicatie,'')),[NULL],['] + OracleSpecialCharacters(Alltrim(Nvl(explicatie,''))) + [']) + [,] + ;
Iif(Isnull(taxcode),[NULL],Alltrim(Str(taxcode))) + [,] + ;
Iif(Empty(Nvl(lot,'')),[NULL],['] + OracleSpecialCharacters(Alltrim(Nvl(lot,''))) + [']) + [,] + ;
Alltrim(Str(Nvl(pret_achizitie,0),18,4)) + [,] + Alltrim(Str(gnIdUtil)) + [, sysdate)]
Iif(Isnull(pret_achizitie),[NULL],Alltrim(Str(pret_achizitie,18,4))) + [,] + Alltrim(Str(gnIdUtil)) + [, sysdate)]
llSucces = goExecutor.oExecuta(m.lcSql)
IF !m.llSucces
EXIT
@@ -601,10 +617,11 @@ FUNCTION ConstruiestePropunereSincronizare
IF Used('agg_rul')
Use In agg_rul
ENDIF
CREATE CURSOR agg_rul (id_articol N(20), denumire C(100), codmat C(30), cant N(12,3), val N(16,4), nrand I)
CREATE CURSOR agg_rul (id_articol N(20) NULL, denumire C(100), codmat C(30), cant N(12,3), val N(16,4), nrand I)
SELECT trul
SCAN FOR Nvl(sters,0) <> 1
*!* cheia comparatiei e id_articol - o linie fara articol n-are cum sa aiba corespondent
SCAN FOR Nvl(sters,0) <> 1 AND !Isnull(id_articol)
lnCantLinie = Nvl(cant,0) + IIF(Nvl(id_tip_rulaj,0) <> 3, Nvl(cante,0), 0)
lnValLinie = Nvl(cant,0) * Nvl(pretvtva,0) + IIF(Nvl(id_tip_rulaj,0) <> 3, Nvl(cante,0) * Nvl(pretvtva,0), 0)
lcDenumireRul = Nvl(trul.denumire,'')
@@ -624,10 +641,11 @@ FUNCTION ConstruiestePropunereSincronizare
IF Used('agg_tvd')
Use In agg_tvd
ENDIF
CREATE CURSOR agg_tvd (id_articol N(20), denumire C(100), codmat C(30), cant N(12,3), val N(16,4), nrand I, in_stoc I)
CREATE CURSOR agg_tvd (id_articol N(20) NULL, denumire C(100), codmat C(30), cant N(12,3), val N(16,4), nrand I, in_stoc I)
SELECT tvd
SCAN FOR Nvl(sters,0) <> 1
*!* liniile de rata dintr-un contract n-au id_articol - se exclud, la fel ca in bucla de mai sus
SCAN FOR Nvl(sters,0) <> 1 AND !Isnull(id_articol)
lcDenumireTvd = Nvl(tvd.denumire,'')
lcCodmatTvd = Nvl(tvd.codmat,'')
SELECT agg_tvd
@@ -920,3 +938,228 @@ FUNCTION AplicaModificareTrul
ENDIF
RETURN m.llAplicat
ENDFUNC && AplicaModificareTrul
*!* editorul liniilor de articole ale notei: primeste in Init formularul frm_modific2024 si
*!* actioneaza asupra cursorului lui tvd - adaugarea unei linii prin nomenclator si dialogul
*!* frm_articol_factura, stergerea logica, duplicarea liniei si nomenclatoarele de pe coloanele
*!* articol / gestiune / valuta / cod TVA
DEFINE CLASS ArticoleNotaEditor AS Custom
oForm = .Null.
PROCEDURE Init
LPARAMETERS toForm
IF Vartype(m.toForm) <> 'O'
RETURN .F.
ENDIF
This.oForm = m.toForm
ENDPROC
*!* .T. cat timp liniile accepta modificari: documentul are articole si nu e trimis in eFactura
PROCEDURE Editabil
RETURN Used('tvd') AND This.oForm.lAreArticoleVanzari AND !This.oForm.lArticoleReadOnly
ENDPROC
*!* numele campului dintr-un ControlSource de forma alias.camp
PROCEDURE NumeCamp
LPARAMETERS tcControl
LOCAL lcCamp
lcCamp = Lower(Alltrim(Nvl(m.tcControl, '')))
IF '.' $ m.lcCamp
lcCamp = Right(m.lcCamp, Len(m.lcCamp) - At('.', m.lcCamp))
ENDIF
RETURN m.lcCamp
ENDPROC
*!* .T. daca pe coloana data se poate deschide un nomenclator
PROCEDURE AreNomenclator
LPARAMETERS tcControl
RETURN Inlist(This.NumeCamp(m.tcControl), 'denumire', 'nume_gestiune', 'nume_val', 'taxcode', 'id_jtva_coloana')
ENDPROC
*!* alege un articol din nomenclator (fara stoc, fara politica de preturi) si il adauga in tvd ca
*!* linie noua (id_vanzare_det = 0), prin dialogul frm_articol_factura; pe document in valuta
*!* dialogul primeste cursul si valuta documentului, deci pretul se introduce direct in valuta
PROCEDURE AdaugaLinie
LOCAL loArticolAles, lnIdArticol, llInValutaDoc, lnCursDoc, lnMultDoc, lcNumeValDoc, lnIdValutaDoc
LOCAL loDlg, llAdaugat
llAdaugat = .F.
IF !This.Editabil()
RETURN .F.
ENDIF
loArticolAles = caut_articol()
lnIdArticol = Nvl(loArticolAles.id_articol, 0)
IF Empty(m.lnIdArticol)
RETURN .F.
ENDIF
llInValutaDoc = Iif(Used('tvanz') And Reccount('tvanz') > 0, Nvl(tvanz.in_valuta, 0) = 1, .F.)
lnCursDoc = Iif(Used('tvanz') And Reccount('tvanz') > 0, Nvl(tvanz.curs, 1), 1)
lnMultDoc = Iif(Used('tvanz') And Reccount('tvanz') > 0, Nvl(tvanz.multiplicator, 1), 1)
lcNumeValDoc = Iif(Used('tvanz') And Reccount('tvanz') > 0, Nvl(tvanz.nume_val, ''), '')
lnIdValutaDoc = Iif(Used('tvanz') And Reccount('tvanz') > 0, tvanz.id_valuta, .Null.)
PRIVATE poArticol, poDate, gnScadereStoc
poArticol = CreeazaPoArticolNouTvd(m.lnIdArticol, loArticolAles.codmat, loArticolAles.denumire, loArticolAles.um, loArticolAles.cont, ;
m.llInValutaDoc, m.lnCursDoc, m.lnMultDoc, m.lcNumeValDoc, m.lnIdValutaDoc)
poDate = Createobject('Empty')
AddProperty(poDate, 'tip', This.oForm.nTipVanzare)
AddProperty(poDate, 'in_valuta', 0)
AddProperty(poDate, 'dataact', Iif(Used('tact') And Reccount('tact') > 0, Nvl(tact.dataact, Date()), Date()))
gnScadereStoc = 0
gnButon = 2
loDlg = Createobject('frm_articol_factura', 1, .F.)
loDlg.Show(1)
IF m.gnButon = 1
This.oForm.AdaugaLinieTvdDinArticol(poArticol)
This.RefreshGrid()
llAdaugat = .T.
ENDIF
Release loDlg
RETURN m.llAdaugat
ENDPROC
*!* comuta flagul sters pe linia curenta - stergerea e logica, linia ramane vizibila (grizata)
*!* pana la salvare
PROCEDURE ComutaSters
IF !This.Editabil() OR Reccount('tvd') = 0
RETURN .F.
ENDIF
SELECT tvd
REPLACE sters WITH Iif(Nvl(sters, 0) = 1, 0, 1), lmodificat WITH .T.
This.RefreshGrid()
This.oForm.ActualizeazaBaraTotaluri()
RETURN .T.
ENDPROC
*!* duplica linia curenta ca linie noua nesalvata, desprinsa de setul din care provenea, ca sa
*!* poata fi editata ca orice linie adaugata manual
PROCEDURE DuplicaLinie
LOCAL loLinie
IF !This.Editabil() OR Reccount('tvd') = 0
RETURN .F.
ENDIF
SELECT tvd
SCATTER NAME loLinie MEMO
loLinie.id_vanzare_det = 0
loLinie.id_vanzare_set = 0
loLinie.sters = 0
loLinie.lmodificat = .T.
APPEND BLANK
GATHER NAME loLinie MEMO
This.oForm.calculeaza_valori_articol()
This.RefreshGrid()
RETURN .T.
ENDPROC
*!* deschide nomenclatorul coloanei primite si scrie alegerea in linia curenta din tvd; liniile
*!* venite dintr-un set raman neatinse, la fel ca la editarea inline din grid
PROCEDURE ModificaNomenclator
LPARAMETERS tcControl
LOCAL lcCamp, loCauta, lcSqlValuta, lnSuccesValuta, llValutaOk
lcCamp = This.NumeCamp(m.tcControl)
IF !This.Editabil() OR Reccount('tvd') = 0 OR !This.AreNomenclator(m.lcCamp) OR Nvl(tvd.id_vanzare_set, 0) <> 0
RETURN .F.
ENDIF
DO CASE
CASE m.lcCamp == 'denumire'
loCauta = caut_articol()
CASE m.lcCamp == 'nume_gestiune'
loCauta = caut_gestiune()
CASE m.lcCamp == 'nume_val'
loCauta = caut_valuta()
CASE m.lcCamp == 'id_jtva_coloana'
loCauta = This.CautaExplicatieTva()
OTHERWISE
loCauta = This.CautaCodTva()
ENDCASE
IF gnButon <> 1
RETURN .F.
ENDIF
SELECT tvd
DO CASE
CASE m.lcCamp == 'denumire'
REPLACE denumire WITH loCauta.denumire, codmat WITH loCauta.codmat, ;
id_articol WITH loCauta.id_articol, cont WITH Nvl(loCauta.cont, '')
CASE m.lcCamp == 'nume_gestiune'
REPLACE nume_gestiune WITH loCauta.nume_gestiune, id_gestiune WITH loCauta.id_gestiune
CASE m.lcCamp == 'nume_val'
*!* valuta orfana (fara curs pe document) ar goli totalurile la recalculare - se accepta doar moneda nationala sau o valuta deja folosita pe document
IF Used('tvanz') AND Reccount('tvanz') = 1
lcSqlValuta = [select 1 as ok from dual where ] + Alltrim(Str(loCauta.id_valuta)) + [ = pack_def.GetIdMonedaNationala()] + ;
[ or exists (select 1 from vanzari_cursuri where id_vanzare = ] + Alltrim(Str(tvanz.id_vanzare)) + ;
[ and id_valuta = ] + Alltrim(Str(loCauta.id_valuta)) + [)]
lnSuccesValuta = goExecutor.oExecute(m.lcSqlValuta,[crsvalok])
goExecutor.oReset()
IF m.lnSuccesValuta < 0
AMESSAGEBOX(goExecutor.cEroare,0+16,"Eroare")
RETURN .F.
ENDIF
llValutaOk = Used('crsvalok') AND Reccount('crsvalok') > 0
IF Used('crsvalok')
Use In crsvalok
ENDIF
IF !m.llValutaOk
AMESSAGEBOX([Valuta aleasa nu are curs inregistrat pe acest document. Se poate alege doar o valuta deja folosita pe document sau moneda nationala.],0+48,"Atentie")
RETURN .F.
ENDIF
ENDIF
REPLACE nume_val WITH loCauta.nume_val, id_valuta WITH loCauta.id_valuta
CASE m.lcCamp == 'id_jtva_coloana'
*!* cota vine din explicatia aleasa, ca la randul de nota; taxcode-ul SAF-T se recoreleaza dupa ea
REPLACE id_jtva_coloana WITH loCauta.id_jtva_coloana, ;
proc_tvav WITH (Nvl(loCauta.cota_tva, 0) + 100) / 100
This.oForm.UpdateExplicatieSAFTArt()
This.oForm.calculeaza_valori_articol()
OTHERWISE
REPLACE taxcode WITH loCauta.taxcode
ENDCASE
REPLACE lmodificat WITH .T.
This.RefreshGrid()
RETURN .T.
ENDPROC
*!* explicatiile TVA, filtrate pe cota liniei curente (proc_tvav e in forma 1.21; cota 0/goala =
*!* fara filtru) - acelasi nomenclator ca pe randul de nota
PROCEDURE CautaExplicatieTva
LOCAL lnCotaFiltru
lnCotaFiltru = Round((Nvl(tvd.proc_tvav, 0) - 1) * 100, 2)
RETURN caut_explicatie_tva(Nvl(tvd.id_jtva_coloana, -1), , , , m.lnCotaFiltru)
ENDPROC
*!* nomenclatorul de coduri TVA SAF-T, acelasi vsaft_taxtable de pe randurile notei
*!* taxname vine din view cu latimea declarata > 254 (SUBSTR nu o micsoreaza) si driverul l-ar
*!* aduce ca Memo; CAST-ul o fixeaza, iar tabela derivata pastreaza aliasul utilizabil in WHERE
PROCEDURE CautaCodTva
LOCAL lcSelect
lcSelect = [select * from (select cast(substr(taxname,1,200) as varchar2(200)) as taxname, ] + ;
[procent_taxa, taxcode from vsaft_taxtable)]
RETURN cauta_alfa(m.lcSelect, [1=2], [], [taxname], [taxname,procent_taxa], ;
[Alegeti codul de TVA], [Denumire,Procent], [], .F., [1=1], [taxname], 1, 0, [taxcode])
ENDPROC
PROCEDURE RefreshGrid
This.oForm.pgfArticole.PAGE3.grdArticoleFactura.Refresh()
ENDPROC
ENDDEFINE && ArticoleNotaEditor

View File

@@ -27,6 +27,10 @@
*!* 03.05.2022
*!* oscrie_vanzare_din_stoc - completeaza pack_facturare.adauga_articol_factura_stoc(taxcode)
*!* 18.08.2026
*!* marius.mutu
*!* oscrie_vanzare_din_stoc - pretul de achizitie si pretul in valuta se trimit cu cel putin 4 zecimale, cate pastreaza stocul
**************************************** INCEPUT: initializeaza_vanzare_din_stoc ******************************
Procedure initializeaza_vanzare_din_stoc
Lparameters tnIdSet, toActAnterior
@@ -357,8 +361,8 @@ Else
lcSql = [begin ] + gcS + [.pack_facturare.adauga_articol_factura_stoc(] + ;
Alltrim(Str(poArticol.id_articol)) + [,] + ;
['] + Strtran(Alltrim(Nvl(poArticol.serie,[])),['],['']) + [',] + ;
Alltrim(Str(poArticol.pret_achizitie,18,gnPPret)) + [,] + ;
Alltrim(Str(poArticol.pretd,18,gnPPretVal)) + [,] + ;
Alltrim(Str(poArticol.pret_achizitie,18,Max(gnPPret,4))) + [,] + ;
Alltrim(Str(poArticol.pretd,18,Max(gnPPretVal,4))) + [,] + ;
Alltrim(Str(poArticol.id_valuta_d)) + [,] + ;
Alltrim(Str(poArticol.Pret,18,Iif(poDate.in_valuta = 1,gnPVal,gnPPretV))) + [,] + ;
Iif(poDate.in_valuta=1,Alltrim(Str(poArticol.id_valuta)),[NULL]) + [,] + ;

View File

@@ -0,0 +1,168 @@
* test_butoane_laterale_articole.prg
* Verifica pagina de articole a notei dupa mutarea comenzilor de linie pe butoanele laterale
* ale grid-ului (but_nouR / but_copiazaR / but_modificaR / but_stergeR, dispecerizate dupa
* pgfArticole.ActivePage) si clasa ArticoleNotaEditor din ofacturare_editare.prg, care tine
* logica: adaugare, comutarea flagului sters, duplicarea liniei si nomenclatoarele coloanelor.
* Nomenclatoarele propriu-zise deschid dialog modal, deci se verifica doar dispecerizarea si
* garzile (coloana fara nomenclator, linie provenita dintr-un set).
* Documentul nu e ancorat pe cod - se descopera prin descopera_caz_test.prg.
* Nu scrie in Oracle - doar in cursorul tvd, in memorie. QUIT la final.
SET SAFETY OFF
SET TALK OFF
PUBLIC gcErrLog
gcErrLog = 'D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\test_butoane_laterale_articole_log.txt'
STRTOFILE('start' + CHR(13) + CHR(10), gcErrLog)
ON ERROR DO test_error_handler WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
DO ('D:\ROA\ROAFACTURARE\COMUN\utile\Teste\test_init_env_auto.prg') WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
IF gnHandle <= 0
STRTOFILE('EROARE: conectare esuata' + CHR(13) + CHR(10), gcErrLog, 1)
QUIT
ENDIF
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\ofacturare_editare.prg ADDITIVE
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\descopera_caz_test.prg ADDITIVE
*!* test_init_env_auto incarca clasa omodificari din working copy-ul ROACONT (alt SET PATH) -
*!* o eliberam si o reincarcam pe cea de sub test, cu cale completa
RELEASE CLASSLIB omodificari
SET CLASSLIB TO D:\ROA\ROAFACTURARE\COMUN\clase\omodificari.vcx ADDITIVE
PUBLIC gnPass, gnFail
gnPass = 0
gnFail = 0
LOCAL llCaz
llCaz = DescoperaCazTest('FACTURA_ARTICOLE', 'crscaz_a')
IF !llCaz
STRTOFILE('EROARE: cazul FACTURA_ARTICOLE nu a fost gasit' + CHR(13) + CHR(10), gcErrLog, 1)
STRTOFILE('REZULTAT: ' + TRANSFORM(gnPass) + ' PASS / ' + TRANSFORM(gnFail) + ' FAIL' + CHR(13) + CHR(10), gcErrLog, 1)
QUIT
ENDIF
STRTOFILE('caz: cod=' + TRANSFORM(crscaz_a.cod) + ' id_vanzare=' + TRANSFORM(crscaz_a.id_vanzare) + CHR(13) + CHR(10), gcErrLog, 1)
LOCAL llOk, lnIdSet, loForm, loEditor
llOk = IncarcaCursoareModificareNota(crscaz_a.cod, crscaz_a.an, crscaz_a.luna, .F.)
IF !llOk OR !Used('tact') OR Reccount('tact') = 0
STRTOFILE('EROARE: IncarcaCursoareModificareNota a esuat' + CHR(13) + CHR(10), gcErrLog, 1)
STRTOFILE('REZULTAT: ' + TRANSFORM(gnPass) + ' PASS / ' + TRANSFORM(gnFail) + ' FAIL' + CHR(13) + CHR(10), gcErrLog, 1)
QUIT
ENDIF
Select a.*, Iif(Nvl(id_jtva_coloana,0)=0,0,1) As cu_Tva From tact a Into Cursor tact Readwrite
Go Top In tact
lnIdSet = tact.id_set
IF !Used('crsJtvaTemp')
update_jtva_coloane("", "crsJtvaTemp", 6)
ENDIF
Select tact
loForm = Createobject([frm_modific2024], lnIdSet)
loForm.WindowType = 0
loForm.Show()
DO asserteaza WITH 'formularul are articole (lAreArticoleVanzari)', loForm.lAreArticoleVanzari, TRANSFORM(loForm.lAreArticoleVanzari)
*========================= 1) butoanele laterale =========================
DO asserteaza WITH 'but_nouR exista pe formular', PEMSTATUS(loForm, 'but_nouR', 5), TRANSFORM(PEMSTATUS(loForm, 'but_nouR', 5))
DO asserteaza WITH 'but_copiazaR exista pe formular', PEMSTATUS(loForm, 'but_copiazaR', 5), TRANSFORM(PEMSTATUS(loForm, 'but_copiazaR', 5))
DO asserteaza WITH 'but_modificaR exista pe formular', PEMSTATUS(loForm, 'but_modificaR', 5), TRANSFORM(PEMSTATUS(loForm, 'but_modificaR', 5))
DO asserteaza WITH 'but_stergeR exista pe formular', PEMSTATUS(loForm, 'but_stergeR', 5), TRANSFORM(PEMSTATUS(loForm, 'but_stergeR', 5))
DO asserteaza WITH 'but_nouR cheama do_adauga_rul', LOWER(ALLTRIM(loForm.but_nouR.caction)) == 'do_adauga_rul', loForm.but_nouR.caction
DO asserteaza WITH 'but_nouR e in aceeasi coloana cu celelalte (Left identic)', loForm.but_nouR.Left == loForm.but_stergeR.Left, TRANSFORM(loForm.but_nouR.Left) + ' vs ' + TRANSFORM(loForm.but_stergeR.Left)
DO asserteaza WITH 'but_nouR e activ pe document neblocat', loForm.but_nouR.Enabled, TRANSFORM(loForm.but_nouR.Enabled)
*========================= 2) butoanele late de pe pagina au disparut =========================
DO asserteaza WITH 'cmdAdaugaArticol nu mai exista pe PAGE3', !PEMSTATUS(loForm.pgfArticole.PAGE3, 'cmdAdaugaArticol', 5), TRANSFORM(PEMSTATUS(loForm.pgfArticole.PAGE3, 'cmdAdaugaArticol', 5))
DO asserteaza WITH 'cmdStergeArticol nu mai exista pe PAGE3', !PEMSTATUS(loForm.pgfArticole.PAGE3, 'cmdStergeArticol', 5), TRANSFORM(PEMSTATUS(loForm.pgfArticole.PAGE3, 'cmdStergeArticol', 5))
DO asserteaza WITH 'cmdSincronizeazaArticole a ramas', PEMSTATUS(loForm.pgfArticole.PAGE3, 'cmdSincronizeazaArticole', 5), TRANSFORM(PEMSTATUS(loForm.pgfArticole.PAGE3, 'cmdSincronizeazaArticole', 5))
DO asserteaza WITH 'cmdSincronizeazaArticole e la stanga (Left=0)', loForm.pgfArticole.PAGE3.cmdSincronizeazaArticole.Left == 0, TRANSFORM(loForm.pgfArticole.PAGE3.cmdSincronizeazaArticole.Left)
DO asserteaza WITH 'cmdSincronizeazaArticole e evidentiat (bold)', loForm.pgfArticole.PAGE3.cmdSincronizeazaArticole.FontBold, TRANSFORM(loForm.pgfArticole.PAGE3.cmdSincronizeazaArticole.FontBold)
*========================= 3) clasa ArticoleNotaEditor =========================
loEditor = Createobject('ArticoleNotaEditor', loForm)
DO asserteaza WITH 'ArticoleNotaEditor se instantiaza cu formularul', VARTYPE(loEditor) == 'O', VARTYPE(loEditor)
DO asserteaza WITH 'Editabil() = .T. pe document neblocat', loEditor.Editabil(), TRANSFORM(loEditor.Editabil())
DO asserteaza WITH 'AreNomenclator(tvd.denumire)', loEditor.AreNomenclator('tvd.denumire'), 'articol'
DO asserteaza WITH 'AreNomenclator(tvd.nume_gestiune)', loEditor.AreNomenclator('tvd.nume_gestiune'), 'gestiune'
DO asserteaza WITH 'AreNomenclator(tvd.nume_val)', loEditor.AreNomenclator('tvd.nume_val'), 'valuta'
DO asserteaza WITH 'AreNomenclator(tvd.taxcode)', loEditor.AreNomenclator('tvd.taxcode'), 'cod TVA'
DO asserteaza WITH 'AreNomenclator(tvd.cantitate) = .F.', !loEditor.AreNomenclator('tvd.cantitate'), 'cantitate'
DO asserteaza WITH 'AreNomenclator() pe control gol = .F.', !loEditor.AreNomenclator(''), 'gol'
DO asserteaza WITH 'ModificaNomenclator pe coloana fara nomenclator nu deschide nimic', !loEditor.ModificaNomenclator('tvd.cantitate'), 'cantitate'
*========================= 4) duplicarea liniei prin butonul lateral =========================
LOCAL lnReccountInitial, lcDenumireSursa, lnIdVanzareDetSursa
SELECT tvd
GO TOP
lnReccountInitial = Reccount('tvd')
lcDenumireSursa = NVL(tvd.denumire, '')
lnIdVanzareDetSursa = NVL(tvd.id_vanzare_det, 0)
loForm.pgfArticole.ActivePage = 3
loForm.do_copie_rul()
DO asserteaza WITH 'do_copie_rul pe pagina 3: Reccount(tvd) creste cu 1', Reccount('tvd') == lnReccountInitial + 1, TRANSFORM(Reccount('tvd')) + ' (initial ' + TRANSFORM(lnReccountInitial) + ')'
SELECT tvd
GO BOTTOM
DO asserteaza WITH 'linia duplicata pastreaza denumirea', NVL(tvd.denumire,'') == m.lcDenumireSursa, NVL(tvd.denumire,'')
DO asserteaza WITH 'linia duplicata e noua (id_vanzare_det = 0)', NVL(tvd.id_vanzare_det,-1) == 0, TRANSFORM(NVL(tvd.id_vanzare_det,-1))
DO asserteaza WITH 'linia duplicata e desprinsa de set (id_vanzare_set = 0)', NVL(tvd.id_vanzare_set,-1) == 0, TRANSFORM(NVL(tvd.id_vanzare_set,-1))
DO asserteaza WITH 'linia duplicata e marcata modificata', tvd.lmodificat, TRANSFORM(tvd.lmodificat)
DO asserteaza WITH 'linia duplicata nu e stearsa', NVL(tvd.sters,0) == 0, TRANSFORM(NVL(tvd.sters,0))
DO asserteaza WITH 'linia sursa ramane salvata (id_vanzare_det neschimbat)', .T., TRANSFORM(m.lnIdVanzareDetSursa)
*========================= 5) nomenclatorul nu se aplica pe linii din set =========================
LOCAL lnRecnoDuplicat
lnRecnoDuplicat = Recno('tvd')
REPLACE id_vanzare_set WITH 77 IN tvd
DO asserteaza WITH 'ModificaNomenclator refuza linia dintr-un set', !loEditor.ModificaNomenclator('tvd.denumire'), 'id_vanzare_set = 77'
REPLACE id_vanzare_set WITH 0 IN tvd
*========================= 6) pe paginile de rulaje, adaugarea de articol nu se declanseaza =========================
LOCAL lnReccountInaintePagina1
lnReccountInaintePagina1 = Reccount('tvd')
loForm.pgfArticole.ActivePage = 1
loForm.do_adauga_rul()
DO asserteaza WITH 'do_adauga_rul pe pagina 1 nu atinge tvd', Reccount('tvd') == lnReccountInaintePagina1, TRANSFORM(Reccount('tvd'))
*========================= 7) butonul de adaugare urmeaza colapsarea pageframe-ului =========================
LOCAL llVizibilInainte
llVizibilInainte = loForm.but_nouR.Visible
loForm.afiseaza_rulaje()
DO asserteaza WITH 'afiseaza_rulaje comuta si but_nouR.Visible', loForm.but_nouR.Visible <> m.llVizibilInainte, TRANSFORM(loForm.but_nouR.Visible)
loForm.afiseaza_rulaje()
DO asserteaza WITH 'a doua comutare readuce but_nouR la starea initiala', loForm.but_nouR.Visible == m.llVizibilInainte, TRANSFORM(loForm.but_nouR.Visible)
STRTOFILE('REZULTAT: ' + TRANSFORM(gnPass) + ' PASS / ' + TRANSFORM(gnFail) + ' FAIL' + CHR(13) + CHR(10), gcErrLog, 1)
loForm.Release()
IF Used('tvd')
Use In tvd
ENDIF
QUIT
PROCEDURE asserteaza
LPARAMETERS tcNume, tlConditie, tcValoare
IF m.tlConditie
gnPass = gnPass + 1
STRTOFILE('PASS ' + m.tcNume + CHR(13) + CHR(10), gcErrLog, 1)
ELSE
gnFail = gnFail + 1
STRTOFILE('FAIL ' + m.tcNume + ' (valoare: ' + m.tcValoare + ')' + CHR(13) + CHR(10), gcErrLog, 1)
ENDIF
ENDPROC
PROCEDURE test_error_handler
LPARAMETERS tnError, tcMessage, tcProgram, tnLineNo
STRTOFILE('EROARE ' + TRANSFORM(tnError) + ' [' + tcProgram + ':' + TRANSFORM(tnLineNo) + '] ' + tcMessage + CHR(13) + CHR(10), gcErrLog, 1)
ENDPROC

View File

@@ -91,8 +91,7 @@ DO asserteaza WITH 'caz A: gridul ramane legat pe tvd (RecordSource neschimbat)'
DO asserteaza WITH 'caz A: tvd are cel putin o linie vizibila (articolele nu au fost golite)', Used('tvd') AND Reccount('tvd') > 0, IIF(Used('tvd'), TRANSFORM(Reccount('tvd')), 'tvd lipsa')
*!* --- doar EDITAREA se opreste: butoanele si celulele needitabile ---
DO asserteaza WITH 'caz A: cmdAdaugaArticol.Enabled = .F.', !loFormA.pgfArticole.PAGE3.cmdAdaugaArticol.Enabled, TRANSFORM(loFormA.pgfArticole.PAGE3.cmdAdaugaArticol.Enabled)
DO asserteaza WITH 'caz A: cmdStergeArticol.Enabled = .F.', !loFormA.pgfArticole.PAGE3.cmdStergeArticol.Enabled, TRANSFORM(loFormA.pgfArticole.PAGE3.cmdStergeArticol.Enabled)
DO asserteaza WITH 'caz A: but_nouR.Enabled = .F.', !loFormA.but_nouR.Enabled, TRANSFORM(loFormA.but_nouR.Enabled)
DO asserteaza WITH 'caz A: marcajul vizual (lblArticoleReadOnly) e vizibil', loFormA.pgfArticole.PAGE3.lblArticoleReadOnly.Visible, TRANSFORM(loFormA.pgfArticole.PAGE3.lblArticoleReadOnly.Visible)
DO asserteaza WITH 'caz A: txtDiscountArt.ReadOnly = .T.', loFormA.pgfArticole.PAGE3.txtDiscountArt.ReadOnly, TRANSFORM(loFormA.pgfArticole.PAGE3.txtDiscountArt.ReadOnly)
@@ -103,8 +102,9 @@ DO asserteaza WITH 'caz A: txtDiscountArt.ReadOnly = .T.', loFormA.pgfArticole.P
*!* --- stergerea de linie (Click direct, fara dialog modal) e blocata de garda ---
LOCAL lnStersInainte
lnStersInainte = Nvl(tvd.sters, 0)
loFormA.pgfArticole.PAGE3.cmdStergeArticol.Click()
DO asserteaza WITH 'caz A: cmdStergeArticol.Click() nu modifica linia (garda eFactura)', Nvl(tvd.sters,0) == m.lnStersInainte, TRANSFORM(Nvl(tvd.sters,0))
loFormA.pgfArticole.ActivePage = 3
loFormA.but_stergeR.Click()
DO asserteaza WITH 'caz A: but_stergeR.Click() nu modifica linia (garda eFactura)', Nvl(tvd.sters,0) == m.lnStersInainte, TRANSFORM(Nvl(tvd.sters,0))
*!* --- notele/rulajele raman neafectate de garda (grid1, pe notele contabile) ---
DO asserteaza WITH 'caz A: Grid1 (nota contabila) ramane editabil - garda nu atinge nota', !loFormA.Grid1.ReadOnly, TRANSFORM(loFormA.Grid1.ReadOnly)
@@ -178,8 +178,7 @@ loFormB.Show()
DO asserteaza WITH 'caz B: formularul are articole (lAreArticoleVanzari)', loFormB.lAreArticoleVanzari, TRANSFORM(loFormB.lAreArticoleVanzari)
DO asserteaza WITH 'caz B: lArticoleReadOnly = .F. (documentul NU e in eFactura)', !loFormB.lArticoleReadOnly, TRANSFORM(loFormB.lArticoleReadOnly)
DO asserteaza WITH 'caz B: PAGE3 pregatita normal', loFormB.pgfArticole.PageCount == 3, TRANSFORM(loFormB.pgfArticole.PageCount)
DO asserteaza WITH 'caz B: cmdAdaugaArticol.Enabled = .T. (neregresat)', loFormB.pgfArticole.PAGE3.cmdAdaugaArticol.Enabled, TRANSFORM(loFormB.pgfArticole.PAGE3.cmdAdaugaArticol.Enabled)
DO asserteaza WITH 'caz B: cmdStergeArticol.Enabled = .T. (neregresat)', loFormB.pgfArticole.PAGE3.cmdStergeArticol.Enabled, TRANSFORM(loFormB.pgfArticole.PAGE3.cmdStergeArticol.Enabled)
DO asserteaza WITH 'caz B: but_nouR.Enabled = .T. (neregresat)', loFormB.but_nouR.Enabled, TRANSFORM(loFormB.but_nouR.Enabled)
DO asserteaza WITH 'caz B: marcajul vizual NU e afisat', !loFormB.pgfArticole.PAGE3.lblArticoleReadOnly.Visible, TRANSFORM(loFormB.pgfArticole.PAGE3.lblArticoleReadOnly.Visible)
DO asserteaza WITH 'caz B: txtDiscountArt.ReadOnly = .F. (neregresat)', !loFormB.pgfArticole.PAGE3.txtDiscountArt.ReadOnly, TRANSFORM(loFormB.pgfArticole.PAGE3.txtDiscountArt.ReadOnly)
@@ -188,8 +187,9 @@ DO asserteaza WITH 'caz B: txtDiscountArt.ReadOnly = .F. (neregresat)', !loFormB
IF Used('tvd') AND Reccount('tvd') > 0
LOCAL lnStersInainteB
lnStersInainteB = Nvl(tvd.sters, 0)
loFormB.pgfArticole.PAGE3.cmdStergeArticol.Click()
DO asserteaza WITH 'caz B: cmdStergeArticol.Click() comuta flagul sters (neregresat)', Nvl(tvd.sters,0) <> m.lnStersInainteB, TRANSFORM(Nvl(tvd.sters,0))
loFormB.pgfArticole.ActivePage = 3
loFormB.but_stergeR.Click()
DO asserteaza WITH 'caz B: but_stergeR.Click() comuta flagul sters (neregresat)', Nvl(tvd.sters,0) <> m.lnStersInainteB, TRANSFORM(Nvl(tvd.sters,0))
*!* restaureaza starea locala a cursorului (memorie, nesalvat in Oracle)
REPLACE sters WITH m.lnStersInainteB IN tvd
ENDIF

View File

@@ -12,19 +12,22 @@
* Ce verifica dupa fiecare editare (VerificaDupaEditare): nota veche (vact_tot, cod dinainte) are
* STERS=1, nota noua (cod nou) exista si e activa cu acelasi id_fact, VANZARI.id_fact ramane
* neschimbat, VANZARI/VANZARI_DETALII raman sincronizate (numar de linii active si totalurile
* denormalizate identice cu inainte de editare, fara_tva+tva=cu_tva), rulajele sunt refacute
* (Reccount(trul)>0 pe nota noua) si totalurile de control ACT/RUL (ActualizeazaVerdictActRul,
* denormalizate identice cu inainte de editare, fara_tva+tva=cu_tva), rulajele nu se pierd la
* editare (Reccount(trul) pe nota noua ramane cel putin cat era inainte - un document care nu misca
* stocul, cum e factura emisa din aviz, n-are rulaje deloc si nici nu capata) si totalurile de
* control ACT/RUL (ActualizeazaVerdictActRul,
* omodificari.vc2) raman concordante fata de inainte de editare - CalculeazaTotaluriS4b instantiaza
* frm_modific2024 exact ca test_verdict_act_rul.prg, fara UI. Suplimentar: gcMockUltimMesaj
* (mock_amessagebox.prg) trebuie sa ramana gol dupa lantul de scriere - dovada ca verifica_stoc
* (oscrie_in_fisiere.prg:92-106, apelata doar cand tnScrie_Sterge=2 And !tlModificare) nu s-a
* declansat, pentru ca ambele lanturi trec tlModificare=.T. la OSCRIE_IN_FISIERE.
*
* Matricea completa (4 documente, cate unul din fiecare tip de sursa) e definita in gaMatriceS8, dar
* NUMAI id_vanzare=1048 e activ in gaCazuriActive - celelalte trei se consuma ireversibil (cod se
* realoca, note vechi raman sterse) si se ruleaza separat, dupa ce felia asta trece. Cazurile
* neactive sunt doar loghate, fara niciun acces la Oracle. Codul e parametrizat pe id_vanzare -
* activarea unui caz nou inseamna doar adaugarea lui in gaCazuriActive.
* Matricea completa (4 documente, cate unul din fiecare tip de sursa) e definita in gaMatriceS8, iar
* gaCazuriActive alege ce se ruleaza: fiecare document se consuma ireversibil (cod se realoca, note
* vechi raman sterse), deci se activeaza cate unul pe rand, iar implicit lista e goala ca o rulare
* accidentala sa nu consume nimic. Cazurile neactive sunt doar loghate, fara niciun acces la Oracle.
* Codul e parametrizat pe id_vanzare - activarea unui caz nou inseamna doar adaugarea lui in
* gaCazuriActive. Logul se rescrie la fiecare rulare, deci contine doar ultima felie activata.
*
* Documentele de test se editeaza exclusiv prin fluxul aplicatiei (OSCRIE_IN_FISIERE,
* finalizeaza_modificare_nota, ScrieArticoleFacturaEditate) - interogarile SQL sunt doar de citire.
@@ -247,7 +250,7 @@ ENDPROC
*-- stare VANZARI dupa, nota veche/noua din vact_tot, totalurile de control S4b dupa editare
PROCEDURE VerificaDupaEditare
LPARAMETERS tnIdVanzare, tcEtapa, tnCodInainte, tnIdFactInainte, tnTotFtvaInainte, tnTotTvaInainte, ;
tnTotCtvaInainte, tnNrActiveInainte, tnActBaseline, tnRulBaseline, tnAn, tnLuna, tcLog
tnTotCtvaInainte, tnNrActiveInainte, tnActBaseline, tnRulBaseline, tnNrRulBaseline, tnAn, tnLuna, tcLog
LOCAL lcSql, lnQ, lnCodDupa, lnIdFactDupa, lnStersDupa, lnTotFtvaDupa, lnTotTvaDupa, lnTotCtvaDupa, lnNrActiveDupa
LOCAL lnStersNotaVeche, lnStersNotaNoua, lnIdFactNotaNoua
@@ -305,7 +308,10 @@ PROCEDURE VerificaDupaEditare
*-- rulajele refacute + totalurile de control S4b concordante fata de dinainte de editare
DO CalculeazaTotaluriS4b WITH lnCodDupa, tnAn, tnLuna, tcEtapa + ' [dupa]', tcLog
DO asserteaza WITH tcEtapa + ': totalurile de control S4b calculabile pe nota noua', glS4bOk, TRANSFORM(glS4bOk)
DO asserteaza WITH tcEtapa + ': rulajele au fost refacute pe nota noua (Reccount(trul)>0)', gnS4bRulReccount > 0, TRANSFORM(gnS4bRulReccount)
*-- RUL retine doar miscari pe cont de stoc: un document care nu atinge stocul (factura emisa din
*-- aviz - marfa a iesit deja la aviz) n-are rulaje nici inainte, nici dupa. Se cere doar sa nu se piarda.
DO asserteaza WITH tcEtapa + ': rulajele nu s-au pierdut la editare (Reccount(trul) pe nota noua)', ;
gnS4bRulReccount >= tnNrRulBaseline, TRANSFORM(tnNrRulBaseline) + ' -> ' + TRANSFORM(gnS4bRulReccount)
DO asserteaza WITH tcEtapa + ': Total ACT ramane concordant fata de inainte de editare (fara modificari de linii)', ;
ABS(gnS4bAct - tnActBaseline) < 0.01, TRANSFORM(tnActBaseline) + ' -> ' + TRANSFORM(gnS4bAct)
DO asserteaza WITH tcEtapa + ': Total RUL ramane concordant fata de inainte de editare (fara modificari de linii)', ;
@@ -323,7 +329,7 @@ PROCEDURE EditeazaDinRoafacturare
PRIVATE pnAn, pnLuna, lnCod, lnIdFact
LOCAL lcEtapa, lcSql, lnQ, lnSters, llEProforma, lnIdSet, lnIdFactD, lnSucces, llBlocatReferinte
LOCAL lnCodInainte, lnIdFactInainte, lnTotFtvaInainte, lnTotTvaInainte, lnTotCtvaInainte, lnNrActiveInainte
LOCAL lnActBaseline, lnRulBaseline, llS4bBaselineOk, llGasitRand
LOCAL lnActBaseline, lnRulBaseline, lnNrRulBaseline, llS4bBaselineOk, llGasitRand
lcEtapa = tcSursa + ' / intrare ROAFACTURARE (do_editare_factura)'
STRTOFILE(CHR(13) + CHR(10) + '========== ' + lcEtapa + ', id_vanzare=' + TRANSFORM(tnIdVanzare) + ' ==========' + CHR(13) + CHR(10), tcLog, 1)
@@ -379,6 +385,7 @@ PROCEDURE EditeazaDinRoafacturare
DO CalculeazaTotaluriS4b WITH lnCod, pnAn, pnLuna, lcEtapa + ' [inainte]', tcLog
lnActBaseline = gnS4bAct
lnRulBaseline = gnS4bRul
lnNrRulBaseline = MAX(gnS4bRulReccount, 0)
llS4bBaselineOk = glS4bOk
DO asserteaza WITH lcEtapa + ': totalurile de control S4b (ACT/RUL) calculabile inainte de editare', llS4bBaselineOk, TRANSFORM(llS4bBaselineOk)
@@ -510,7 +517,7 @@ PROCEDURE EditeazaDinRoafacturare
*-- 7) verificarile de dupa commit, comune ambelor puncte de intrare
DO VerificaDupaEditare WITH tnIdVanzare, lcEtapa, lnCodInainte, lnIdFactInainte, lnTotFtvaInainte, lnTotTvaInainte, ;
lnTotCtvaInainte, lnNrActiveInainte, lnActBaseline, lnRulBaseline, pnAn, pnLuna, tcLog
lnTotCtvaInainte, lnNrActiveInainte, lnActBaseline, lnRulBaseline, lnNrRulBaseline, pnAn, pnLuna, tcLog
ENDPROC
@@ -523,7 +530,7 @@ PROCEDURE EditeazaDinRegistruJurnal
PRIVATE pnAn, pnLuna, lnCod, lnIdFact, lnIdfactd, lnIdSet, pdDataOra
LOCAL lcEtapa, lcSql, lnQ, lnSters, llSters, llGestInvantar, llRul, lnSucces, llBlocExecutat, llGasitTvanz
LOCAL lnCodInainte, lnIdFactInainte, lnTotFtvaInainte, lnTotTvaInainte, lnTotCtvaInainte, lnNrActiveInainte
LOCAL lnActBaseline, lnRulBaseline, llS4bBaselineOk
LOCAL lnActBaseline, lnRulBaseline, lnNrRulBaseline, llS4bBaselineOk
llBlocExecutat = .F.
lcEtapa = tcSursa + ' / intrare registru jurnal ROACONT (afisjurcom.do_modifica)'
@@ -597,6 +604,7 @@ PROCEDURE EditeazaDinRegistruJurnal
DO CalculeazaTotaluriS4b WITH lnCod, pnAn, pnLuna, lcEtapa + ' [inainte]', tcLog
lnActBaseline = gnS4bAct
lnRulBaseline = gnS4bRul
lnNrRulBaseline = MAX(gnS4bRulReccount, 0)
llS4bBaselineOk = glS4bOk
DO asserteaza WITH lcEtapa + ': totalurile de control S4b (ACT/RUL) calculabile inainte de editare', llS4bBaselineOk, TRANSFORM(llS4bBaselineOk)
@@ -742,7 +750,7 @@ PROCEDURE EditeazaDinRegistruJurnal
*-- 8) verificarile de dupa commit, comune ambelor puncte de intrare
DO VerificaDupaEditare WITH tnIdVanzare, lcEtapa, lnCodInainte, lnIdFactInainte, lnTotFtvaInainte, lnTotTvaInainte, ;
lnTotCtvaInainte, lnNrActiveInainte, lnActBaseline, lnRulBaseline, pnAn, pnLuna, tcLog
lnTotCtvaInainte, lnNrActiveInainte, lnActBaseline, lnRulBaseline, lnNrRulBaseline, pnAn, pnLuna, tcLog
ENDPROC

View File

@@ -70,7 +70,7 @@ loForm.pgfArticole.ActivePage = 3
DOEVENTS FORCE
loGrid = loForm.pgfArticole.Page3.grdArticoleFactura
loBut = loForm.pgfArticole.Page3.cmdStergeArticol
loBut = loForm.but_stergeR
*!* marcheaza linia 2 ca stearsa
SELECT tvd

View File

@@ -72,8 +72,7 @@ DOEVENTS FORCE
DO asserteaza WITH 'documentul e recunoscut ca trimis in eFactura (lArticoleReadOnly)', loForm.lArticoleReadOnly, TRANSFORM(loForm.lArticoleReadOnly)
DO asserteaza WITH 'PAGE3 (articole) NU e suprimata - pgfArticole.PageCount = 3', loForm.pgfArticole.PageCount == 3, TRANSFORM(loForm.pgfArticole.PageCount)
DO asserteaza WITH 'cmdAdaugaArticol.Enabled = .F.', !loForm.pgfArticole.PAGE3.cmdAdaugaArticol.Enabled, TRANSFORM(loForm.pgfArticole.PAGE3.cmdAdaugaArticol.Enabled)
DO asserteaza WITH 'cmdStergeArticol.Enabled = .F.', !loForm.pgfArticole.PAGE3.cmdStergeArticol.Enabled, TRANSFORM(loForm.pgfArticole.PAGE3.cmdStergeArticol.Enabled)
DO asserteaza WITH 'but_nouR.Enabled = .F.', !loForm.but_nouR.Enabled, TRANSFORM(loForm.but_nouR.Enabled)
DO asserteaza WITH 'marcajul vizual (lblArticoleReadOnly) e vizibil si are text', ;
loForm.pgfArticole.PAGE3.lblArticoleReadOnly.Visible AND !Empty(Alltrim(loForm.pgfArticole.PAGE3.lblArticoleReadOnly.Caption)), ;
loForm.pgfArticole.PAGE3.lblArticoleReadOnly.Caption

View File

@@ -1,5 +1,5 @@
* test_ui_sterge_linie.prg - verifica pe formular vizibil (nu headless) butonul nou
* pgfArticole.PAGE3.cmdStergeArticol: comuta tvd.sters intre 0 si 1 pe linia curenta,
* but_stergeR pe pagina de articole: comuta tvd.sters intre 0 si 1 pe linia curenta,
* marcheaza lmodificat si grizeaza vizual randul (DynamicForeColor pe toate coloanele
* grid-ului) fara sa-l scoata din cursor - stergerea ramane logica, nu fizica.
* Document: cod=1139934/an=2021/luna=12 (id_vanzare=882, 2 linii, are si rulaje, altfel
@@ -63,9 +63,9 @@ loForm.pgfArticole.ActivePage = 3
DOEVENTS FORCE
loGrid = loForm.pgfArticole.Page3.grdArticoleFactura
loBut = loForm.pgfArticole.Page3.cmdStergeArticol
loBut = loForm.but_stergeR
DO asserteaza WITH 'butonul cmdStergeArticol exista', TYPE('loBut.Caption') = 'C', TYPE('loBut.Caption')
DO asserteaza WITH 'butonul but_stergeR exista', TYPE('loBut.Caption') = 'C', TYPE('loBut.Caption')
DO asserteaza WITH 'butonul e vizibil', loBut.Visible, TRANSFORM(loBut.Visible)
SELECT tvd