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
447 lines
26 KiB
Markdown
447 lines
26 KiB
Markdown
# 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:
|
|
|
|
1. `4502-4508`: citeste `gnLuna`/`gnAn` in variabile, iese daca `crsfacturi` e gol.
|
|
2. `4516-4518`: garda **luna inchisa** (`glLunaInchisa`) - `Return` fara mesaj.
|
|
3. `4520-4527`: pozitioneaza pe randul curent din `crsfacturi`, citeste `id_vanzare`, `cod`,
|
|
an/luna din `data_act`, `sters`, `eproforma`.
|
|
4. `4529-4536`: daca deja sters -> mesaj si `Return`; confirmare cu `amessagebox(...,4+32,...)`.
|
|
5. `4541-4544`: garda **luna curenta** - `(pnAn*12)+pnLuna <> (gnAn*12)+gnLuna` -> mesaj si
|
|
`Return`.
|
|
6. `4546-4559`: ramura separata **STERGERE PROFORMA** (`eproforma=1`) - apeleaza direct
|
|
`pack_facturare.sterge_proforma(pnIdVanzare,gnIdUtil)` si iese cu `RETURN`, **inainte** de
|
|
garda de referinte de mai jos. Facturile/avizele nu intra pe aceasta ramura.
|
|
7. `4562-4567`: garda **referinte incasari/plati** -
|
|
`ReferinteDocumenteNota(pnAn, pnLuna, lnCod)` (definita in
|
|
`COMUN\programe\odocumente.prg:8`) -> daca `.T.`, mesaj si `Return`.
|
|
8. `4569-4614`: incarca cursoare pe `cod` din `vact_tot`/`vrul_tot`/`vrul_obinv_tot` (schema
|
|
`gcs`), filtrate `sters=0 and an=gnAn and luna=gnLuna and cod=lnCod`, in `actactan`/
|
|
`rul_temp`/`rul_temp_obinv`.
|
|
9. `4617-4620`: daca sunt randuri in `actactan`, deschide formularul modal `verificare`
|
|
(confirmare vizuala inainte de stergere efectiva).
|
|
10. `4622-4685`: daca `buton=1` din `verificare`, trece manual pe tranzactie
|
|
(`SQLSetprop(gnhandle,"Transactions",2)`), apeleaza `OSCRIE_IN_FISIERE(2,.F.,llRul)`, apoi
|
|
`pack_contafin.finalizeaza_stergere_nota(pnLuna,pnAn,Null,lnIdSet,lnCod,lnIdFact,lnIdFactD,
|
|
gnIdUtil)`, COMMIT/ROLLBACK dupa rezultat, revine pe tranzactie automata.
|
|
11. `4686-4701`: ramura alternativa (fara randuri in `actactan`, adica document fara nota) -
|
|
apel direct `pack_facturare.sterge_factura(pnIdVanzare,gnLuna,gnAn,gnIdUtil)`.
|
|
12. `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`:
|
|
```
|
|
If (pnAn * 12) + pnLuna <> (gnAn * 12) + gnLuna
|
|
amessagebox('Nu puteti sterge decat inregistrari din luna curenta!',0,'Atentie!')
|
|
Return
|
|
Endif
|
|
```
|
|
Text hardcodat pe "stergere" - la reutilizare pentru editare trebuie schimbat mesajul.
|
|
- **Referinte incasari/plati**, `ofacturare_comun.vc2:4562-4567`:
|
|
```
|
|
*** 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
|
|
```
|
|
Idem, mesajul e specific stergerii.
|
|
|
|
### 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 `N` prezent, seteaza `thisform.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 `cbuton4` definit pe `frm_facturi` - vizibilitatea lui
|
|
`but_sterge1` e gestionata separat, direct in `Init` (`4770-4773`): daca `glLunaInchisa`,
|
|
scoate manual `"4;"` din `gcAcces` si ascunde butonul. `lactiv4` insa tot se seteaza normal
|
|
din `gcAcces` (prin mecanismul generic), si `but_sterge1.Click` foloseste implicit
|
|
`caction = inainte_de_do_sterge` (default din clasa de baza `but_modifica`/`but_sterge`,
|
|
`cmd_butoane.vc2:358`), care verifica `This.lactiv4`.
|
|
- Tokenul "1" nu e folosit de `frm_facturi` (fara `cbuton1`) - 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:
|
|
|
|
1. **`do_modifica`** (`ofacturare_comun.vc2:4381-4480`), legata de `but_modifica1` (butonul din
|
|
bara de sus, `Left=609`, fara `caction` explicit -> foloseste default-ul din clasa de baza
|
|
`but_modifica` = `caction = inainte_de_do_modifica` -> `This.lactiv3` -> `do_modifica()`).
|
|
Deschide **`frm_modifica_factura`** (antet document) si, la `gnButon=1`, ruleaza
|
|
`pack_facturare.modifica_date_factura(...)` pe UNA sau MAI MULTE facturi (dupa selectie
|
|
multipla `ales=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).
|
|
2. **`do_modifica_explicatie`** (`ofacturare_comun.vc2:4482-4499`), legata de `But_modifica2`
|
|
(langa grid-ul de detalii, `caction = do_modifica_explicatie` explicit,
|
|
`ofacturare_comun.vc2:1433-1441`, tooltip "Modificare explicatie articol"). Deschide
|
|
**`frm_modifica_articol_factura`** (`ofacturare_comun.vc2:4959`, caption "Modifica explicatie
|
|
articol"), care editeaza DOAR `explicatie` (memo) si `taxcode` (combo SAFT) pe linia curenta
|
|
din `crsDetalii`. Garda: doar `poRec.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:
|
|
|
|
1. `2230-2232`: `If !Thisform.lactiv3 Then Return` (acelasi mecanism de drept ca A4).
|
|
2. `2238-2240`: garda luna inchisa (`glLunaInchisa`).
|
|
3. `2242-2258`: determina daca se arata si randurile sterse (`lleSters`, dupa filtrul curent),
|
|
citeste `cod`/`an`/`luna`/`id_set`/`sters`/`id_fact`/`id_factd` din `actjur`.
|
|
4. `2265-2268`: garda luna curenta - **acelasi tipar** ca in `do_sterge`:
|
|
`(pnAn*12)+pnLuna <> (gnAn*12)+gnLuna` -> mesaj -> `Return`.
|
|
5. `2278-2281`: garda suplimentara - `id_set` intre 30000-30009 (note din ROAPRODUCTIE) ->
|
|
blocate necontional.
|
|
6. `2313-2332`: inchide cursoarele reziduale `actactan`/`tact`/`rul_temp`/`trul`/
|
|
`rul_temp_obinv`/`trul_obinv` daca sunt deschise.
|
|
7. `2352-2368`: incarca `vact_tot` in `actactan` -> `tact` (READWRITE), filtrat
|
|
`sters=0 and an=gnAn and luna=gnLuna and cod=lnCod` (daca nu se arata stersele) sau fara
|
|
filtrul de sters, ORDER BY `id_act`.
|
|
8. `2370-2427`: daca succes, incarca similar `vrul_tot` -> `rul_temp`/`trul` si
|
|
`vrul_obinv_tot` -> `rul_temp_obinv`/`trul_obinv`, cu recalcul de `valoare`/`valtva`/
|
|
`valoarev`/`valtvav` pe randurile goale (2383-2387, 2412-2416) inainte de a construi
|
|
`trul`/`trul_obinv`.
|
|
9. `2429-2442`: alege clasa de formular dupa an (`gnAn >= gnAnFormNou` implicit 2007) ->
|
|
**`frm_modific2024`** (`Createobject([frm_modific2024], lnIdSet)`) sau varianta veche
|
|
`frm_modific`; `Select tact` inainte de `Omodif.Show()`.
|
|
10. `2444-2538`: daca `buton=1`, deschide tranzactie manuala (`do_deschide_tranzactie`),
|
|
`oscrie_in_fisiere(2,.T.,llRul)`, reconstruieste `actactan`/`RUL_TEMP`/`RUL_TEMP_OBINV` din
|
|
`tact`/`trul`/`trul_obinv` cu `id_util`/`sters=0`, apoi `oscrie_in_fisiere(0,.T.,llRul)`,
|
|
apoi **`pack_contafin.finalizeaza_modificare_nota(pnLuna,pnAn,pdDataOra,lnIdSet,lnCod,
|
|
lnIdFact,lnIdfactd,gnIdUtil)`** (2484-2487), `do_inchide_tranzactie` si `do_cauta` la final.
|
|
11. Cod comentat (2496-2513, dezactivat) arata o incercare anterioara de a apela direct
|
|
`pack_facturare.actualizeaza_vanzari` din client dupa `finalizeaza_modificare_nota` - azi
|
|
e mort, apelul real se face DOAR server-side, in interiorul lui
|
|
`finalizeaza_modificare_nota` (confirma faptul deja stabilit in `progres.md`).
|
|
12. `llVanzari` e declarata (`Store .F.`, 2235) dar logica ei de activare e tot comentata
|
|
(2292-2307) - variabila ramane mereu `.F.`, deci sincronizarea cu `VANZARI` e complet
|
|
transparenta pentru `afisjurcom`, 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 in `This.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 cu `Select tact` inainte de `Createobject`) - grid-ul principal `Grid1` are
|
|
`RecordSource` legat implicit pe `tact` (conventie mostenita, nu vazuta explicit in Init, dar
|
|
confirmata de apelul din A6 pas 9). Grid-urile din pageframe au `RecordSource` FIX in
|
|
definitia clasei: `pgfArticole.PAGE1.grdRulaje.RecordSource = "trul"`
|
|
(`omodificari.vc2:8669`) si (dupa acelasi tipar, de verificat direct) `grdRulajeObinv` pe
|
|
`trul_obinv`. **Deci apelantul trebuie sa aiba deschise, cu exact aceste nume de alias,
|
|
cursoarele `tact`/`trul`/`trul_obinv` READWRITE inainte de instantiere** - exact ce face A6
|
|
pas 7-8.
|
|
- **Iesire**: `do_termin` nu e suprascrisa in `frm_modific2024` - foloseste default-ul din
|
|
`_frmbase` (`_frm_base.vc2:363-376`, seteaza `gnButon=1`/`Buton=1` si inchide/ascunde), dar
|
|
trece prin `inainte_de_do_termin` proprie, foarte lunga (`13357-13549`, ~192 linii) - acolo e
|
|
validarea grea (verificari de total, TVA exigibil etc.) inainte sa lase `buton=1`. **Orice
|
|
validare noua legata de sume factura trebuie sa intre in acest lant**, nu doar in `do_salvare`.
|
|
- **La iesire cu `buton=1`, cursoarele `tact`/`trul`/`trul_obinv` raman deschise** (formularul nu
|
|
le inchide) - apelantul (A6 pas 10) le reciteste in `actactan`/`RUL_TEMP`/`RUL_TEMP_OBINV`
|
|
dupa `Show()`.
|
|
|
|
**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`):
|
|
1. Adauga metoda `do_editare_sume` (sau numele ales) pe `frm_facturi`.
|
|
2. Adauga `ADD OBJECT 'But_editare_sume1' AS but_modifica WITH ... caption/picture/tooltip/
|
|
pozitie ...` (poate mosteni orice clasa vizuala din `cmd_butoane.vcx`, nu neaparat
|
|
`but_modifica`).
|
|
3. Daca actiunea trebuie gateata separat de token-ul "3" (modificare antet/explicatie) - decizie
|
|
de arhitectura, vezi D1 - adauga `inainte_de_do_editare_sume` proprie care verifica
|
|
`This.lactivN` (N = tokenul nou ales, ex. "5"), si seteaza `caction =
|
|
inainte_de_do_editare_sume` pe buton (dupa modelul `but_modifica1`, care NU seteaza caption
|
|
explicit pe buton ci mosteneste `inainte_de_do_modifica` din `cmd_butoane.vc2:188`).
|
|
4. Adauga proprietatea `cbuton5 = But_editare_sume1` pe `frm_facturi` (langa `cbuton2`/`cbuton3`
|
|
existente, `ofacturare_comun.vc2:1352-1353`) ca butonul sa fie ascuns automat cand tokenul
|
|
"5" lipseste din `gcAcces` (mecanismul din A4).
|
|
5. Vezi `COMUN\docs\conventie_ux_formulare.md` pentru pozitionare/anchor in bara existenta.
|
|
|
|
## B. Deosebiri de fond fata de plan
|
|
|
|
1. **Garda eFactura NU e in `do_sterge`, e in `do_modifica`** (A3). Planul o citeaza gresit ca
|
|
parte a sablonului `do_sterge` ("Garda eFactura, de refolosit: `ofacturare_comun.vc2:4428-4432`"
|
|
sub titlul despre `do_sterge`). Practic nu schimba directia (garda tot exista si e
|
|
refolosibila), dar sursa corecta de citat si tiparul de extras (azi e un simplu `If`, nu un
|
|
`Return` cu mesaj ca restul garzilor) trebuie corectate in implementare.
|
|
2. **`frm_facturi.do_modifica` NU deschide `frm_modifica_articol_factura`** (A5). Planul (si
|
|
textul din task) atribuie asta lui `do_modifica`; in realitate `do_modifica` deschide
|
|
`frm_modifica_factura` (antet, alte campuri), iar `frm_modifica_articol_factura` (explicatie+
|
|
taxcode) e deschis de `do_modifica_explicatie`, legata de `But_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.
|
|
3. **Drepturile pe `frm_facturi` nu 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_facturi` doar declara ce
|
|
inseamna fiecare token pentru el (`cbuton2`, `cbuton3`) si manipuleaza direct `gcAcces`/
|
|
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.
|
|
4. 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 in `COMUN`, deci
|
|
reutilizabila ca atare din `afisjurcom.do_modifica` fara nicio mutare de cod - se apeleaza cu
|
|
aceiasi parametri (`an`, `luna`, `cod`), doar ca `afisjurcom` trebuie sa stie cand documentul
|
|
curent e o factura (vezi mai jos).
|
|
- **Garda eFactura** foloseste `poRec.id_fact` - `afisjurcom` are deja `lnIdFact`/`lnIdfactd`
|
|
(A6 pas 3) din `actjur`, deci parametrul exista, doar interogarea (azi inline in
|
|
`do_modifica` a lui `frm_facturi`) trebuie extrasa intr-o functie mica in `COMUN\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) - pentru `afisjurcom`
|
|
inseamna un test suplimentar (ex. `id_set` intre valorile care corespund facturarii, sau
|
|
existenta unui rand in `vanzari` cu acel `cod`) 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\` (langa
|
|
`odocumente.prg` sau intr-un fisier nou `ofacturare_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 din `frm_facturi` (actiune noua, S1) SI din `afisjurcom.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) pe `frm_facturi`
|
|
(`COMUN\clase\ofacturare_comun.vc2`), clonata dupa scheletul de garzi din `do_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` (sau `inainte_de_do_editare_sume`
|
|
daca se doreste gating explicit prin `lactivN`), token nou in `gcAcces` (propun "5", primul
|
|
liber - A4) + `cbuton5` pe `frm_facturi`.
|
|
- Semnatura: fara parametri (citeste contextul din `crsfacturi`/pozitia curenta, ca `do_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):
|
|
|
|
```foxpro
|
|
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
|
|
|
|
1. **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.
|
|
2. **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 prin `vdef_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).
|
|
3. **Cum se determina in `afisjurcom` ca documentul curent e o factura de vanzare**, ca sa aplice
|
|
garda eFactura/referinte doar atunci (S4 foloseste acelasi test pentru afisarea PAGE3). Optiuni:
|
|
test pe `id_set` (interval cunoscut pentru facturare) sau pe existenta unui rand in `vanzari`
|
|
cu `cod`-ul curent. A doua varianta e mai robusta (nu depinde de conventia de `id_set`) dar
|
|
costa un SELECT suplimentar la fiecare deschidere - de decis cu Marius pragul de cost acceptat.
|
|
4. ~~Numele exact al metodelor de tranzactie pe `_frmbase`~~ - rezolvat in cercetare:
|
|
`do_deschide_tranzactie` (`_frm_base.vc2:252-265`) si `do_inchide_tranzactie`
|
|
(`_frm_base.vc2:279`) exista amandoua pe `_frmbase`, deci reutilizabile ca atare in S3.
|