Folderul docs\ era pana acum in afara oricarui control de versiuni - nici git, nici SVN - desi contine planurile pe puncte, proiectarile si rapoartele de cercetare pe care se sprijina modificarile din cod. O stergere acolo era definitiva. Fisierele intermediare (handoff-uri intre sesiuni, diff-uri deja aplicate) au fost sterse inainte, nu versionate: ce era durabil in ele a intrat in antetele fisierelor de test la care se refereau. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SN8snvkk94KuhWwoXUUey3
26 KiB
Cercetare S1-S3 (plan_06_editare_factura.md) - stare cod la 08.08.2026
Refera ancorele planului dupa commit-urile #7/#8. Toate liniile de mai jos sunt din textul
.vc2 regenerat de git_sync.ps1 in aceasta sesiune (deci la zi cu binarul).
A. Ancore re-verificate
A1. frm_facturi.do_sterge - COMUN\clase\ofacturare_comun.vc2:4501-4717
Clasa frm_facturi incepe la ofacturare_comun.vc2:1168 (mosteneste _frmbase). Metoda
do_sterge e imediat dupa do_modifica_explicatie (4482-4499) si inainte de do_verifica
(4719-4766). Structura pe pasi:
4502-4508: citestegnLuna/gnAnin variabile, iese dacacrsfacturie gol.4516-4518: garda luna inchisa (glLunaInchisa) -Returnfara mesaj.4520-4527: pozitioneaza pe randul curent dincrsfacturi, citesteid_vanzare,cod, an/luna dindata_act,sters,eproforma.4529-4536: daca deja sters -> mesaj siReturn; confirmare cuamessagebox(...,4+32,...).4541-4544: garda luna curenta -(pnAn*12)+pnLuna <> (gnAn*12)+gnLuna-> mesaj siReturn.4546-4559: ramura separata STERGERE PROFORMA (eproforma=1) - apeleaza directpack_facturare.sterge_proforma(pnIdVanzare,gnIdUtil)si iese cuRETURN, inainte de garda de referinte de mai jos. Facturile/avizele nu intra pe aceasta ramura.4562-4567: garda referinte incasari/plati -ReferinteDocumenteNota(pnAn, pnLuna, lnCod)(definita inCOMUN\programe\odocumente.prg:8) -> daca.T., mesaj siReturn.4569-4614: incarca cursoare pecoddinvact_tot/vrul_tot/vrul_obinv_tot(schemagcs), filtratesters=0 and an=gnAn and luna=gnLuna and cod=lnCod, inactactan/rul_temp/rul_temp_obinv.4617-4620: daca sunt randuri inactactan, deschide formularul modalverificare(confirmare vizuala inainte de stergere efectiva).4622-4685: dacabuton=1dinverificare, trece manual pe tranzactie (SQLSetprop(gnhandle,"Transactions",2)), apeleazaOSCRIE_IN_FISIERE(2,.F.,llRul), apoipack_contafin.finalizeaza_stergere_nota(pnLuna,pnAn,Null,lnIdSet,lnCod,lnIdFact,lnIdFactD, gnIdUtil), COMMIT/ROLLBACK dupa rezultat, revine pe tranzactie automata.4686-4701: ramura alternativa (fara randuri inactactan, adica document fara nota) - apel directpack_facturare.sterge_factura(pnIdVanzare,gnLuna,gnAn,gnIdUtil).4707-4716: inchide cursoarele temporare.
Nu exista nicio verificare eFactura in do_sterge - vezi A3, e o corectie fata de plan.
A2. Cele 3 garzi lipsa din do_modifica - confirmate, linii curente
Toate trei sunt in do_sterge (A1) si lipsesc din do_modifica (ofacturare_comun.vc2:4381-4480,
care nu verifica deloc luna sau referinte, doar sters+eFactura, vezi A3):
- Luna inchisa,
ofacturare_comun.vc2:4516-4518:If glLunaInchisa Return Endif - Luna curenta,
ofacturare_comun.vc2:4541-4544:Text hardcodat pe "stergere" - la reutilizare pentru editare trebuie schimbat mesajul.If (pnAn * 12) + pnLuna <> (gnAn * 12) + gnLuna amessagebox('Nu puteti sterge decat inregistrari din luna curenta!',0,'Atentie!') Return Endif - Referinte incasari/plati,
ofacturare_comun.vc2:4562-4567:Idem, mesajul e specific stergerii.*** verificare restrictie stergere documente cu referinte (incasari/plati) llReferinteDocumente = ReferinteDocumenteNota(pnAn, pnLuna, lnCod) && && odocumente.prg If llReferinteDocumente amessagebox("Documentul are referinte (incasari/plati). Nu poate fi sters.", 0+48,"Stergere") Return Endif
A3. Garda eFactura - CORECTIE fata de plan: e in do_modifica, NU in do_sterge
Cautare exhaustiva anaf_efactura in ofacturare_comun.vc2: o singura aparitie, la linia
4426, in interiorul lui do_modifica (4381-4480). do_sterge nu contine deloc anaf_efactura.
Cod exact, ofacturare_comun.vc2:4426-4430:
lcSql = [select count(*) as lneFactura from anaf_efactura where id_fact = ] + ALLTRIM(STR(poRec.id_fact))
pneFactura = 0
llSucces = goExecutor.oSelecteaza2Value(m.lcSql, @pneFactura)
If poRec.sters = 0 AND NVL(m.pnEFactura,0) = 0
(pneFactura/pnEFactura e aceeasi variabila, VFP e case-insensitive.)
Garda e refolosibila ca atare (interogare + conditie), dar trebuie extrasa dintr-un If care
astazi conditioneaza doar deschiderea dialogului frm_modifica_factura - pentru actiunea noua
S1 trebuie sa devina un Return explicit cu mesaj, dupa modelul celorlalte garzi din
do_sterge, nu o simpla conditie de If.
A4. Mecanismul de drepturi pe frm_facturi
Nu exista o proprietate lactiv3/lactiv4 setata explicit in ofacturare_comun.vc2 - ele sunt
proprietati generice mostenite din _frmbase (_frm_base.vc2:7), populate dinamic din
gcAcces de metoda comuna actualizeaza_drepturi, _frm_base.vc2:195-228:
- Format
gcAcces = "opt1;opt2;...;optN;"(string cu numere separate prin;). - Pentru fiecare token
Nprezent, seteazathisform.lactivN = .T.(linia 203-205:lcProp='thisform.lactiv'+Alltrim(lcAcces)+&lcProp=.T.). - Daca exista si o proprietate
thisform.cbutonN(lista de nume de butoane separate prin;), seteaza.Visible = .T.pe fiecare buton din lista (206-221).
Uzul din inainte_de_do_modifica/inainte_de_do_sterge (_frm_base.vc2:476-481, 493-498):
If This.lactiv3 Then This.do_modifica() / If This.lactiv4 Then This.do_sterge(). Deci
lactivN gateaza EXECUTIA actiunii, cbutonN gateaza VIZIBILITATEA butoanelor asociate.
Tokenii folositi azi de frm_facturi (proprietati proprii clasei, ofacturare_comun.vc2:1352-1353):
cbuton2 = but_listare1;but_listare2;But_listare3(token "2" = listare)cbuton3 = but_modifica1;but_modifica2(token "3" = modificare - ambele butoane de modificare, cel de antet si cel de explicatie articol, vezi A5)- Tokenul "4" (stergere) nu are
cbuton4definit pefrm_facturi- vizibilitatea luibut_sterge1e gestionata separat, direct inInit(4770-4773): dacaglLunaInchisa, scoate manual"4;"dingcAccessi ascunde butonul.lactiv4insa tot se seteaza normal dingcAcces(prin mecanismul generic), sibut_sterge1.Clickfoloseste implicitcaction = inainte_de_do_sterge(default din clasa de bazabut_modifica/but_sterge,cmd_butoane.vc2:358), care verificaThis.lactiv4. - Tokenul "1" nu e folosit de
frm_facturi(faracbuton1) - liber pentru o semnificatie noua daca s-ar dori, dar mai curat e un token nou (ex. "5").
Sursa lui gcAcces: variabila globala PUBLIC (comentariul *:Global gcAcces,
ofacturare_comun.vc2:4770), NU e setata in codul lui frm_facturi sau in procedura care il
deschide (COMUN\programe\oproceduri_facturare.prg:416, 505 - Createobject("frm_facturi")
fara nicio atribuire de gcAcces inainte). E populata inainte, la click pe iconita de pe
ecranul-fundal (ofundal.vc2:69,186,311,391 - gcAcces = This.coptiuni_active), unde
coptiuni_active per iconita vine din dezactiveaza_imagini (COMUN\programe\acces_meniu.prg:39-80),
care citeste central din view-ul Oracle contafin_oracle.vdef_util_obiecte (interogat in
citeste_drepturi, acces_meniu.prg:17-37, filtrat pe id_util/id_program/id_firma) si
mapeaza pe cheia iconitei (cheie) ultima cifra la un token numeric. Editarea drepturilor per
grup se face prin PACK_DREPTURI.grupdreptmodproc (COMUN\clase\drept_grupuri.vc2:39, apelat
din frm_grupuri).
Nu am gasit un catalog central editabil in VFP care sa enumere sensul fiecarui token numeric
per program (ex. un tabel optiuni_program cu eticheta "3 = modificare"). Sensul e o conventie
fixata in cod (proprietatile cbutonN din fiecare clasa de formular) - vezi intrebarea D2.
A5. frm_facturi.do_modifica - CORECTIE fata de descrierea din task/plan
Contrar formularii din plan_06 ("butonul existent din frm_facturi deschide
frm_modifica_articol_factura, care editeaza doar explicatie si taxcode"), in codul de azi
exista DOUA actiuni distincte de "modificare" pe frm_facturi, ambele gateate de acelasi token
"3" (cbuton3), dar cu efecte diferite:
do_modifica(ofacturare_comun.vc2:4381-4480), legata debut_modifica1(butonul din bara de sus,Left=609, faracactionexplicit -> foloseste default-ul din clasa de bazabut_modifica=caction = inainte_de_do_modifica->This.lactiv3->do_modifica()). Deschidefrm_modifica_factura(antet document) si, lagnButon=1, ruleazapack_facturare.modifica_date_factura(...)pe UNA sau MAI MULTE facturi (dupa selectie multiplaales=1) cu campurile:id_ruta,id_delegat,id_agent,id_masina,dataora_exp,id_facturare,listare_detaliata,text_aditional,tip_saft,efactura(flag intentie trimitere),data_act,data_scad,numar_act,serie_act. Niciun camp de suma/cantitate/pret. Contine garda eFactura (A3).do_modifica_explicatie(ofacturare_comun.vc2:4482-4499), legata deBut_modifica2(langa grid-ul de detalii,caction = do_modifica_explicatieexplicit,ofacturare_comun.vc2:1433-1441, tooltip "Modificare explicatie articol"). Deschidefrm_modifica_articol_factura(ofacturare_comun.vc2:4959, caption "Modifica explicatie articol"), care editeaza DOARexplicatie(memo) sitaxcode(combo SAFT) pe linia curenta dincrsDetalii. Garda: doarpoRec.sters = 0- fara verificare eFactura.
Deci descrierea corecta pentru plan: actiunea care deschide frm_modifica_articol_factura e
do_modifica_explicatie (nu do_modifica), iar niciuna din cele doua actiuni existente nu
atinge sume/cantitati - confirma nevoia unei actiuni noi (S1), dar sablonul de clonat pentru
garzi ramane do_sterge, nu vreuna din cele doua do_modifica*.
A6. afisjurcom.do_modifica - COMUN\clase\comun.vc2:2222-2563
Clasa afisjurcom (extinde _frmbase). Pasi:
2230-2232:If !Thisform.lactiv3 Then Return(acelasi mecanism de drept ca A4).2238-2240: garda luna inchisa (glLunaInchisa).2242-2258: determina daca se arata si randurile sterse (lleSters, dupa filtrul curent), citestecod/an/luna/id_set/sters/id_fact/id_factddinactjur.2265-2268: garda luna curenta - acelasi tipar ca indo_sterge:(pnAn*12)+pnLuna <> (gnAn*12)+gnLuna-> mesaj ->Return.2278-2281: garda suplimentara -id_setintre 30000-30009 (note din ROAPRODUCTIE) -> blocate necontional.2313-2332: inchide cursoarele rezidualeactactan/tact/rul_temp/trul/rul_temp_obinv/trul_obinvdaca sunt deschise.2352-2368: incarcavact_totinactactan->tact(READWRITE), filtratsters=0 and an=gnAn and luna=gnLuna and cod=lnCod(daca nu se arata stersele) sau fara filtrul de sters, ORDER BYid_act.2370-2427: daca succes, incarca similarvrul_tot->rul_temp/trulsivrul_obinv_tot->rul_temp_obinv/trul_obinv, cu recalcul devaloare/valtva/valoarev/valtvavpe randurile goale (2383-2387, 2412-2416) inainte de a construitrul/trul_obinv.2429-2442: alege clasa de formular dupa an (gnAn >= gnAnFormNouimplicit 2007) ->frm_modific2024(Createobject([frm_modific2024], lnIdSet)) sau varianta vechefrm_modific;Select tactinainte deOmodif.Show().2444-2538: dacabuton=1, deschide tranzactie manuala (do_deschide_tranzactie),oscrie_in_fisiere(2,.T.,llRul), reconstruiesteactactan/RUL_TEMP/RUL_TEMP_OBINVdintact/trul/trul_obinvcuid_util/sters=0, apoioscrie_in_fisiere(0,.T.,llRul), apoipack_contafin.finalizeaza_modificare_nota(pnLuna,pnAn,pdDataOra,lnIdSet,lnCod, lnIdFact,lnIdfactd,gnIdUtil)(2484-2487),do_inchide_tranzactiesido_cautala final.- Cod comentat (2496-2513, dezactivat) arata o incercare anterioara de a apela direct
pack_facturare.actualizeaza_vanzaridin client dupafinalizeaza_modificare_nota- azi e mort, apelul real se face DOAR server-side, in interiorul luifinalizeaza_modificare_nota(confirma faptul deja stabilit inprogres.md). llVanzarie declarata (Store .F., 2235) dar logica ei de activare e tot comentata (2292-2307) - variabila ramane mereu.F., deci sincronizarea cuVANZARIe complet transparenta pentruafisjurcom, indiferent de tipul documentului.
A7. frm_modific2024 - COMUN\clase\omodificari.vc2:6375-...
Clasa (DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx") incepe la linia 6375.
Metodele proprii merg de la Activate (12238) pana la ultimul handler de grid
(pgfArticole.PAGE2.grdRulajeObinv.Init, 15422-15424) - interval 12238-15424, usor deplasat
fata de planul vechi (12200-15319).
Contract de intrare (Init, 13551-13660):
Lparameters tnIdSet, tlNotaNoua, toBackupXML, toSet, tlVizualizare
tnIdSet: id-ul setului de nota (obligatoriu, stocat inThis.nid_set).tlNotaNoua:.T.daca vine din nota fara predefinire.toBackupXML,toSet: obiecte optionale (backup XML, respectiv setul de editare restrictionata "doar Salveaza/Renunta" -This.lEditare).tlVizualizare: parametru opus, numeric sau logic -1/.T.=vizualizare,2=modificare (default),3=verificare note (13576-13591).- Nu primeste cursoare ca parametru. Formularul se leaga la aliasul curent
tact(setat de apelant cuSelect tactinainte deCreateobject) - grid-ul principalGrid1areRecordSourcelegat implicit petact(conventie mostenita, nu vazuta explicit in Init, dar confirmata de apelul din A6 pas 9). Grid-urile din pageframe auRecordSourceFIX in definitia clasei:pgfArticole.PAGE1.grdRulaje.RecordSource = "trul"(omodificari.vc2:8669) si (dupa acelasi tipar, de verificat direct)grdRulajeObinvpetrul_obinv. Deci apelantul trebuie sa aiba deschise, cu exact aceste nume de alias, cursoareletact/trul/trul_obinvREADWRITE inainte de instantiere - exact ce face A6 pas 7-8. - Iesire:
do_terminnu e suprascrisa infrm_modific2024- foloseste default-ul din_frmbase(_frm_base.vc2:363-376, seteazagnButon=1/Buton=1si inchide/ascunde), dar trece prininainte_de_do_terminproprie, foarte lunga (13357-13549, ~192 linii) - acolo e validarea grea (verificari de total, TVA exigibil etc.) inainte sa lasebuton=1. Orice validare noua legata de sume factura trebuie sa intre in acest lant, nu doar indo_salvare. - La iesire cu
buton=1, cursoareletact/trul/trul_obinvraman deschise (formularul nu le inchide) - apelantul (A6 pas 10) le reciteste inactactan/RUL_TEMP/RUL_TEMP_OBINVdupaShow().
Pageframe existent (pgfArticole, omodificari.vc2:8627-8642, doar 2 pagini azi):
PAGE1.Caption = "Rulaje materii prime, materiale, marfuri, obiecte inventar (303)" (grid grdRulaje pe trul)
PAGE2.Caption = "Rulaje obiecte inventar in folosinta (8039)" (grid grdRulajeObinv pe trul_obinv)
Nu exista azi PAGE3 - de adaugat pentru S4.
A8. Butonul/actiunea in bara formularului si modelul de adaugare
Modelul concret (But_modifica2, ofacturare_comun.vc2:1433-1441):
ADD OBJECT 'But_modifica2' AS but_modifica WITH ;
Anchor = 12, ;
caction = do_modifica_explicatie, ;
Caption = "", ;
Left = 710, ;
Name = "But_modifica2", ;
TabIndex = 27, ;
ToolTipText = "Modificare explicatie articol", ;
Top = 341
Dispatch generic: Click din clasa de baza a butoanelor (_cmd_base.vc2:41-... si a doua
implementare la 120-...) citeste This.cAction si il executa pe Thisform (cu
This.clistaparametri optional ca argument). Deci un buton nou nu are nevoie de propriul
Click - doar de caction = <nume_metoda_pe_thisform>.
Pentru o actiune noua gateata de drept (ca but_modifica1, nu ca But_modifica2):
- Adauga metoda
do_editare_sume(sau numele ales) pefrm_facturi. - Adauga
ADD OBJECT 'But_editare_sume1' AS but_modifica WITH ... caption/picture/tooltip/ pozitie ...(poate mosteni orice clasa vizuala dincmd_butoane.vcx, nu neaparatbut_modifica). - Daca actiunea trebuie gateata separat de token-ul "3" (modificare antet/explicatie) - decizie
de arhitectura, vezi D1 - adauga
inainte_de_do_editare_sumeproprie care verificaThis.lactivN(N = tokenul nou ales, ex. "5"), si seteazacaction = inainte_de_do_editare_sumepe buton (dupa modelulbut_modifica1, care NU seteaza caption explicit pe buton ci mostenesteinainte_de_do_modificadincmd_butoane.vc2:188). - Adauga proprietatea
cbuton5 = But_editare_sume1pefrm_facturi(langacbuton2/cbuton3existente,ofacturare_comun.vc2:1352-1353) ca butonul sa fie ascuns automat cand tokenul "5" lipseste dingcAcces(mecanismul din A4). - Vezi
COMUN\docs\conventie_ux_formulare.mdpentru pozitionare/anchor in bara existenta.
B. Deosebiri de fond fata de plan
- Garda eFactura NU e in
do_sterge, e indo_modifica(A3). Planul o citeaza gresit ca parte a sablonuluido_sterge("Garda eFactura, de refolosit:ofacturare_comun.vc2:4428-4432" sub titlul despredo_sterge). Practic nu schimba directia (garda tot exista si e refolosibila), dar sursa corecta de citat si tiparul de extras (azi e un simpluIf, nu unReturncu mesaj ca restul garzilor) trebuie corectate in implementare. frm_facturi.do_modificaNU deschidefrm_modifica_articol_factura(A5). Planul (si textul din task) atribuie asta luido_modifica; in realitatedo_modificadeschidefrm_modifica_factura(antet, alte campuri), iarfrm_modifica_articol_factura(explicatie+ taxcode) e deschis dedo_modifica_explicatie, legata deBut_modifica2. Nu schimba concluzia planului (niciuna din cele doua nu atinge sume), dar numele metodei/formularului de citat in orice implementare viitoare trebuie sa fie cel corect.- Drepturile pe
frm_facturinu sunt "lactiv3/lactiv4 + tokeni in gcAcces" ca fapt autonom al formularului - sunt mecanismul GENERIC din_frm_base.actualizeaza_drepturi(A4), aplicat oricarui formular care extinde_frmbase.frm_facturidoar declara ce inseamna fiecare token pentru el (cbuton2,cbuton3) si manipuleaza directgcAcces/ vizibilitatea pentru cazul special "luna inchisa" (Init, 4770-4773). Nu exista o lista centrala DB-editabila a semnificatiei tokenilor (vezi D2) - planul nu gresea factual, dar ii lipsea acest nivel de detaliu, relevant pentru cum se inregistreaza un token nou. - Restul ancorelor (A1, A2, A6, A7) confirma planul, doar cu liniile deplasate de commit-urile #7/#8 - nicio diferenta de fond.
C. Propunerea de implementare S1-S3
Arhitectura: unde se pune ce
Decizia lui Marius (progres.md, punctul 5) cere ca garzile sa se aplice pe AMBELE puncte de
intrare (frm_facturi din ROAFACTURARE si afisjurcom din ROACONT/ROAGEST). Azi, garzile
"luna inchisa" si "luna curenta" exista deja si independent in ambele clase
(do_sterge/A1 respectiv do_modifica/A6) - fiecare punct de intrare are propria lor copie,
pattern deja folosit in cod (nu e o incalcare noua sa le duplic). Garda "referinte
incasari/plati" si garda "eFactura" insa exista azi doar in frm_facturi (ROAFACTURARE) -
afisjurcom.do_modifica nu le are deloc.
Recomandare:
ReferinteDocumenteNota(COMUN\programe\odocumente.prg:8) e deja inCOMUN, deci reutilizabila ca atare dinafisjurcom.do_modificafara nicio mutare de cod - se apeleaza cu aceiasi parametri (an,luna,cod), doar caafisjurcomtrebuie sa stie cand documentul curent e o factura (vezi mai jos).- Garda eFactura foloseste
poRec.id_fact-afisjurcomare dejalnIdFact/lnIdfactd(A6 pas 3) dinactjur, deci parametrul exista, doar interogarea (azi inline indo_modificaa luifrm_facturi) trebuie extrasa intr-o functie mica inCOMUN\programe\(ex.EsteInEFactura(tnIdFact)) ca sa fie apelabila din ambele clase fara duplicare literala a SQL-ului. - Cazul "documentul curent e o factura de vanzare" trebuie detectat in ambele puncte de intrare
(nu doar in
frm_facturi, care STIE deja ca lucreaza cu facturi) - pentruafisjurcominseamna un test suplimentar (ex.id_setintre valorile care corespund facturarii, sau existenta unui rand invanzaricu acelcod) inainte de a aplica garda eFactura/referinte - pe alte tipuri de note aceste garzi nu au sens si nu trebuie sa apara. - Cel mai simplu 80/20: o singura functie noua in
COMUN\programe\(langaodocumente.prgsau intr-un fisier nouofacturare_editare.prg), ex.VerificaEditareFactura(tnCod, tnAn, tnLuna, tnIdFact), care ruleaza toate garzile aplicabile facturii (eFactura + referinte; luna inchisa/curenta raman ca azi, duplicate local, pentru ca deja exista identic in ambele clase) si intoarce.T./.F.+ mesajul de eroare deja afisat. Apelata dinfrm_facturi(actiune noua, S1) SI dinafisjurcom.do_modifica(adaugare minima, cateva linii), cu un test prealabil "e factura?" facut de fiecare apelant dupa contextul lui.
S1 - Actiunea noua in frm_facturi
- Metoda noua
do_editare_sume(nume de discutat) pefrm_facturi(COMUN\clase\ofacturare_comun.vc2), clonata dupa scheletul de garzi dindo_sterge(A1 pasii 1-7), dar FARA ramurile de stergere efectiva (pasii 8-12) - se opreste dupa garzi si preda la S2/S3. - Buton nou dupa modelul A8, cu
caption = do_editare_sume(sauinainte_de_do_editare_sumedaca se doreste gating explicit prinlactivN), token nou ingcAcces(propun "5", primul liber - A4) +cbuton5pefrm_facturi. - Semnatura: fara parametri (citeste contextul din
crsfacturi/pozitia curenta, cado_sterge).
S2 - Incarcarea cursoarelor (COMUN, refolosibila)
Extrage pasii 7-8 din A6 (incarcarea vact_tot/vrul_tot/vrul_obinv_tot in
tact/trul/trul_obinv, filtrate pe cod+an+luna) intr-o procedura comuna, ex.
IncarcaCursoareModificareNota(tnCod, tnAn, tnLuna, tlAratasterse) in COMUN\programe\, apelata
identic din afisjurcom.do_modifica (inlocuind codul inline de azi, refactorizare minima) si din
noua actiune din frm_facturi. Asta e singura cale sa se garanteze ca cele doua puncte de
intrare incarca EXACT acelasi lucru, cerinta explicita a lui Marius.
S3 - Deschiderea frm_modific2024 (cod apelant ~40 linii)
Schita (in frm_facturi.do_editare_sume, dupa ce S1 a validat garzile si S2 a incarcat
cursoarele):
PROCEDURE do_editare_sume
* garzi S1 (eFactura, referinte, luna inchisa/curenta) - vezi A1, A3
...
Local lnCod, pnAn, pnLuna, lnIdSet, lnIdFact, lnIdFactD
* citeste cod/an/luna/id_set/id_fact/id_factd din crsfacturi, ca in A1 pas 3
If !IncarcaCursoareModificareNota(lnCod, pnAn, pnLuna, .F.) && S2, COMUN
Return
Endif
If Reccount('actactan') = 0
amessagebox("Nu exista nota contabila pentru aceasta factura.",0+48,"Atentie")
Return
Endif
Select tact
Local Omodif
Omodif = Createobject([frm_modific2024], lnIdSet)
Omodif.Show()
If Omodif.gnButon = 1 && sau variabila globala Buton, ca in A6 pas 10
If Thisform.do_deschide_tranzactie()
lnSucces = OSCRIE_IN_FISIERE(2,.T.,.T.)
If lnSucces > 0
* reconstruieste actactan/RUL_TEMP/RUL_TEMP_OBINV din tact/trul/trul_obinv, ca in A6
...
lnSucces = OSCRIE_IN_FISIERE(0,.T.,.T.)
Endif
If lnSucces > 0
lcSql = [begin pack_contafin.finalizeaza_modificare_nota(...); end;] && A6 pas 10
lnSucces = Iif(goExecutor.oExecuta(lcSql),1,-1)
Endif
Thisform.do_inchide_tranzactie(Iif(lnSucces<0,2,1))
If lnSucces > 0
Thisform.do_cauta()
Endif
Endif
Endif
* inchide actactan/rul_temp/rul_temp_obinv/tact/trul/trul_obinv
ENDPROC
Notă: do_deschide_tranzactie/do_inchide_tranzactie exista deja pe _frmbase
(_frm_base.vc2:252-265 si un omolog de inchidere, de verificat numele exact la implementare -
afisjurcom il foloseste direct, A6 pas 10) - de reutilizat, nu de reprodus manual ca in
do_sterge (care foloseste SQLSetprop direct, tipar mai vechi).
Fisiere atinse (estimare S1-S3)
| Fisier | Proiect | Ce se schimba |
|---|---|---|
COMUN\clase\ofacturare_comun.vc2 |
COMUN (cross-project) | metoda noua do_editare_sume + buton nou pe frm_facturi, token nou in cbuton* |
COMUN\clase\comun.vc2 |
COMUN (cross-project) | afisjurcom.do_modifica - apel la garda noua + la IncarcaCursoareModificareNota (inlocuind codul inline) |
COMUN\programe\odocumente.prg sau fisier nou COMUN\programe\ofacturare_editare.prg |
COMUN (cross-project) | functiile comune noi: garda eFactura extrasa, IncarcaCursoareModificareNota |
COMUN\clase\omodificari.vc2 |
COMUN (cross-project) | NEATINS in S1-S3 (S4 adauga PAGE3) |
Orice modificare in COMUN\clase\comun.vc2 (afisjurcom) afecteaza registrul jurnal din TOATE
produsele ROA care il folosesc (ROACONT, ROAGEST, posibil altele) - de tratat cu maxima grija si
testat separat de frm_facturi.
D. Intrebari deschise
- Ce token numeric folosim pentru dreptul nou si daca trebuie sa fie distinct de tokenul "3" (modificare) existent, sau daca e acceptabil ca cine are drept de "modificare" (token 3) sa capete automat si dreptul de editare sume. Propunere: token separat (ex. "5"), pentru ca editarea sumelor are impact contabil mult mai mare decat editarea campurilor de antet/ explicatie - un utilizator ar trebui sa primeasca acest drept explicit, nu implicit prin dreptul existent.
- Cum se inregistreaza practic un token nou in sistemul de drepturi ca un administrator sa-l
poata acorda per grup din
frm_grupuri(COMUN\clase\drept_grupuri.vc2). Am gasit mecanismul tehnic (gcAcces->lactivN/cbutonN, populat prinvdef_util_obiecte+PACK_DREPTURI.grupdreptmodproc), dar nu am gasit un catalog editabil al semnificatiei tokenilor per program - posibil sa fie o eticheta hardcodata undeva neindexat inca in cache-ul text, sau sa fie nevoie de un rand nou in Oracle. De clarificat inainte de S1, altfel tokenul nou risca sa fie "orfan" (functioneaza in cod dar nimeni nu-l poate acorda din UI). - Cum se determina in
afisjurcomca documentul curent e o factura de vanzare, ca sa aplice garda eFactura/referinte doar atunci (S4 foloseste acelasi test pentru afisarea PAGE3). Optiuni: test peid_set(interval cunoscut pentru facturare) sau pe existenta unui rand invanzaricucod-ul curent. A doua varianta e mai robusta (nu depinde de conventia deid_set) dar costa un SELECT suplimentar la fiecare deschidere - de decis cu Marius pragul de cost acceptat. Numele exact al metodelor de tranzactie pe- rezolvat in cercetare:_frmbasedo_deschide_tranzactie(_frm_base.vc2:252-265) sido_inchide_tranzactie(_frm_base.vc2:279) exista amandoua pe_frmbase, deci reutilizabile ca atare in S3.