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
41 KiB
Cercetare + proiectare — S5: acoperirea tuturor tipurilor de document
Proiectare pe cod, READ-ONLY (fara editari, fara git_sync.ps1/txt2vcx.ps1, fara commit, fara
scriere pe Oracle — numai SELECT), pentru povestea S5 din
docs\plan_13_unificare_formular_facturare.md (#### S5). Nu s-a atins
COMUN\clase\ofacturare_comun.vc2 si COMUN\programe\ofacturare_editare.prg (perimetrul altei
sarcini in lucru) — doar citite cand au aparut in cautari (n-a fost cazul).
Sursa VFP: COMUN\clase\ofacturare.vc2 (frm_facturare_articole = formularul de productie,
:10968-15739; frm_facturare_articole2 = prototipul, :15741-19355 — nu e subclasa a
primului, mostenesc separat din _frmbase, au Init propriu fiecare). Sursa de rutare:
COMUN\programe\ofacturare.prg (factureaza = standard, :81-...; factureaza2 = prototip,
:660-...). Referinta de tipuri: COMUN\docs\tipuri_documente_facturare.md.
Verdict (rezumat, citeste asta primul)
Do Case-ul dinfrm_facturare_articole.Init(ofacturare.vc2:15109-15248) acopera 21 de valori detip(grupate in 14 ramuri):1,2,3,4,5,6,7,8,9,10,21,22,23,24,25,26,28,29,41,42,47.- Patru tipuri sunt reale, reachable prin
factureaza(), dar nu apar in niciunCase— pierd titlu, cap de coloana, mesaj de stoc, vizibilitate discount, eliminarecSerie:45(factura restaurant),48/49(custodie cu/fara descarcare K),52(contract, factura fiscala valuta). Confirmat pe meniuri (Meniuri\politica.mn2:18,26,29,Meniuri\contracte.mn2:18) si pe rutarea cursorului (ofacturare.prg:271-282), care le recunoaste — doar Init-ul formularului de articole nu le-a "prins" niciodata. Nu doar52, cum semnalase raportul S4b — sunt patru, nu unul. - Cinci tipuri din referinta (
43,44,46,50,51) nu sunt niciodata pasate luifactureaza()in tot arboreleD:\ROA(cautare exhaustiva, zero potriviri) — nu ajung la acest formular deloc azi.50e marcat explicit "in lucru" in sursa;51(ROAACNPRO) folosesteid_set=50100, un interval separat de restul (25000+), semn ca provine dintr-un flux Oracle direct al altui produs, nu dinfactureaza()local. - Descoperire centrala, dincolo de ce cerea misiunea: prototipul (
frm_facturare_articole2.Init,:18988-19080) nu e o versiune partiala a Do Case-ului standard — e aproape gol. Singurul lucru pe care-l face pe tip e sa aleaga cuvantullcTipDoc("factura" vs "aviz"), pe o lista mai scurta (lipseste24). Nu seteaza titlu (nu existalb_titlu_alb_b121in tot fisierul prototipului), nu schimba capul coloanei de cantitate, nu schimba mesajul de stoc, nu ascunde discountul, nu are deloc conceptul de coloanacSerie(gridul prototipului,grd_factura, n-are niciodataRemoveObject('cSerie')— cautare pe tot fisierul, zero potriviri in intervalul15741-19355). Daca formularul unificat porneste de la prototip (cum indica decizia de baza a planului), toata diferentierea pe tip trebuie reconstruita de la zero, nu doar completata. - Rutarea cursorului diverge intre standard si prototip pe trei tipuri, nu doua:
23(confirmat deja de S4/S4b), plus52si24, gasite aici — pe prototip,Case Inlist(tnTip, 2, 26, 6)(ofacturare.prg:762) omite52fata de standard (Inlist(tnTip, 2, 26, 6, 52),:283), siCase Inlist(tnTip, 8, 9)(:819) omite24fata de standard (Inlist(tnTip, 8, 9, 24),:307). Daca cineva ar factura tip52sau24prin prototip azi (gnFacturareNou=1),lcSqlCursorar ramane nedefinit — eroare, nu doar diferenta de comportament. - Tipurile
26si52n-au niciun bookkeepingcrsarticole(nici Rol A, nici Rol B) — inchis aici punctul lasat deschis de raportul S4 punctul 2: excluderea lor din toate cele patruCase-uri de bookkeeping dindo_adauga_articol/do_stergee totala (Do Case exhaustiv, fara ramura implicita), nu doar "neconfirmata". 27si30raman pe calea lor — confirmat pe cod, cu o nuanta importanta pentru30: nu e un formular separat, ci acelasifrm_facturare_articole, instantiat si trecut prin acelasiInit/Do Case, dar niciodata aratat (ofacturare.prg:444-453: calculeaza totalurile, apasa programaticbut_termin1.Click(), apoiRelease(), faraShow()). Tip30e afectat de golurile dinDo Caseexact ca oricare alt tip needitat — doar ca defectele (titlu, cap de coloana) nu se vad niciodata pe ecran.
0. Metoda de verificare — lista de referinta
Lista completa de tipuri vine din COMUN\docs\tipuri_documente_facturare.md (sursa unica, deja
verificata pe cod de acea cercetare). Tipuri incluse in tabelul de mai jos: toate cele din sectiunile
"Facturi" si "Avize de expeditie" (documentele care intra prin frm_facturare_articole/2).
Sectiunea "Tipuri negative" (-1..-13) nu intra in acest formular — sunt scrise de alte produse
(ROAGEST, ROAAUTO) prin propriile lor fluxuri, niciodata prin factureaza() din ROAFACTURARE
(cautare exhaustiva factureaza(- in tot D:\ROA, zero potriviri) — declarate aici explicit ramase
pe calea altui produs, nu "neacoperite".
1. Tabelul complet, tip cu tip
Coloane: tip = VANZARI.TIP · Case propriu = are ramura proprie in frm_facturare_articole.Init
(ofacturare.vc2:15109-15248)? · titlu = ce seteaza pe lb_titlu_alb_b121.Caption · cap
cantitate = ce seteaza pe grd_articole.cCantitate.header1.Caption (implicit ramane cel din
design, [Cantitate in stoc], daca nu e suprascris) · mesaj stoc = This.cmesaj_cantitate ·
discount = clb_discount.Visible · cSerie = coloana ramane (Da) sau se scoate (Nu) ·
butoane = ce se face vizibil (but_urmator_tot1/but_retur, ambele .F. la design) · cursor
standard = ramura din factureaza (ofacturare.prg:266-308) · cursor prototip = ramura din
factureaza2 (:748-822, gol daca lipseste) · Rol crsarticole = A (cantitate ramasa de
facturat) / B (plafon de sesiune) / — (fara bookkeeping), din docs\cercetare\s4_punct2_registru_cantitate_ramasa.md
· stare S5 = acoperit azi / gol de completat / ramas pe calea veche / neatins.
Facturi
| tip | denumire | Case propriu | titlu | cap cantitate | mesaj stoc | discount | cSerie |
butoane vizibile | cursor standard | cursor prototip | Rol | stare S5 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | lista de preturi (lei) | Da :15122 (grup 1,5,7,10) |
— (implicit) | "Cantitate in stoc" | "nu e pe stoc!" | vizibil (implicit) | Nu (scoasa) | but_retur |
cursor_preturi (grup 1,22,5,29,7,10,23), :279-282 |
cursor_preturi (grup 1,22,5,29,7,10), :758-761 |
B (gestionabil, 1,22,29) |
acoperit azi, de portat |
| 2 | contract (lei) | Da :15129 (grup 2,6) |
"FACTURA PE CTR. …" | "Cantitate in stoc" | "nu e pe stoc!" | vizibil | Nu | — | cursor_contract (grup 2,26,6,52), :283-291 |
cursor_contract (grup 2,26,6 — fara 52), :762-769 |
B doar pt. opt_facturare=0; — pe rest |
acoperit azi, de portat |
| 3 | comanda | Da :15144 |
"FACTURA LA COMANDA …" | "Cantitate comandata" | "cantitate comandata facturata" | vizibil | Nu | but_urmator_tot1 |
cursor_comanda (grup 3,21,25,28,42,47), :292-293 |
cursor_comanda (acelasi grup), :771-773 |
A | acoperit azi, de portat |
| 4 | din avize | Da :15151 |
"FACTURA DIN AVIZE" | — (implicit) | "cantitate de pe aviz facturata" | ascuns (.F., :15154) |
Da (nu se scoate) | but_urmator_tot1 |
cursor_avize, :294-295 |
cursor_avize, :774-775 |
A | acoperit azi, de portat |
| 5 | lista de preturi valuta | Da :15122 (grup 1,5,7,10) |
— | "Cantitate in stoc" | "nu e pe stoc!" | vizibil | Nu | but_retur |
cursor_preturi |
cursor_preturi |
— | acoperit azi, de portat |
| 6 | contract valuta | Da :15129 (grup 2,6) |
"FACTURA PE CTR. …" | "Cantitate in stoc" | "nu e pe stoc!" | vizibil | Nu | — | cursor_contract |
cursor_contract |
B partial (ca 2) | acoperit azi, de portat |
| 7 | credit note | Da :15122 (grup 1,5,7,10) |
— | "Cantitate in stoc" | "nu e pe stoc!" | vizibil | Nu | but_retur |
cursor_preturi |
cursor_preturi |
— | acoperit azi, de portat |
| 8 | retur factura lei | Da :15236 (grup 8,9) |
— | "Cant. max. de returnat" | "nu se mai poate returna" | vizibil | Da (nu se scoate) | but_urmator_tot1 |
cursor_retur, :306-307 |
cursor_retur (grup 8,9), :819-820 |
B (invers) | acoperit azi, de portat |
| 9 | retur factura valuta | Da :15236 (grup 8,9) |
— | "Cant. max. de returnat" | "nu se mai poate returna" | vizibil | Da | but_urmator_tot1 |
cursor_retur |
cursor_retur |
B (invers) | acoperit azi, de portat |
| 10 | factura fiscala valuta | Da :15122 (grup 1,5,7,10) |
— | "Cantitate in stoc" | "nu e pe stoc!" | vizibil | Nu | but_retur |
cursor_preturi |
cursor_preturi |
— | acoperit azi, de portat |
| 43 | bon fiscal magazine (ROARETAIL) | Nu | — | — | — | — | — | — | nicio ramura | nicio ramura | n/a | neatins — niciodata pasat lui factureaza() (cautat in tot D:\ROA); colectat de la magazine prin alt flux |
| 44 | factura hotel | Nu | — | — | — | — | — | — | nicio ramura | nicio ramura | n/a | neatins — la fel, zero apeluri factureaza(44 |
| 45 | factura restaurant | Nu — lipseste din Do Case |
nesetat | nesetat (implicit) | nesetat (ramane "nu e pe stoc!" default, :15108) |
nesetat (ramane vizibil) | Da, ramane (nescoasa) | nesetat | cursor_preturi, :275-278 |
cursor_preturi, :754-757 |
— (exclus explicit din bookkeeping, :12871,17178) |
gol real de completat — reachable din Meniuri\politica.mn2:18 |
| 46 | nota de plata restaurant | Nu | — | — | — | — | — | — | nicio ramura | nicio ramura | n/a | neatins — zero apeluri factureaza(46; zero documente in date de test (tipuri_documente_facturare.md, capcana 2) |
| 48 | custodie cu descarcare K | Nu — lipseste din Do Case |
nesetat | nesetat | nesetat | nesetat | Da, ramane | nesetat | cursor_articole_k, :271-273 |
cursor_articole_k, :750-752 |
— | gol real de completat — reachable din Meniuri\politica.mn2:29 (submeniu Marfaincus) |
| 49 | custodie fara descarcare K | Nu — lipseste din Do Case |
nesetat | nesetat | nesetat | nesetat | Da, ramane | nesetat | cursor_articole_k |
cursor_articole_k |
— | gol real de completat — reachable din Meniuri\politica.mn2:26 |
| 50 | (in lucru) retur custodie | Nu | — | — | — | — | — | — | nicio ramura | nicio ramura | n/a | neatins, marcat explicit "in lucru" in tipuri_documente_facturare.md |
| 51 | factura ROAACNPRO | Nu | — | — | — | — | — | — | nicio ramura | nicio ramura | n/a | neatins — id_set=50100, interval separat; probabil scris direct de ROAACNPRO, nu prin factureaza() local |
| 52 | contract, factura fiscala valuta | Nu — lipseste din Do Case |
nesetat | nesetat | nesetat | nesetat | Da, ramane | nesetat | cursor_contract (grup 2,26,6,52) |
lipseste din grupul contract (:762) — lcSqlCursor nedefinit pe prototip |
— (confirmat, vezi §2) | gol real de completat — reachable din Meniuri\contracte.mn2:18 |
Avize de expeditie
| tip | denumire | Case propriu | titlu | cap cantitate | mesaj stoc | discount | cSerie |
butoane vizibile | cursor standard | cursor prototip | Rol | stare S5 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 21 | catre clienti, din comanda | Da :15168 (grup 21,28,42,47) |
"AVIZ DE EXPEDITIE DIN COMANDA" | — (implicit) | "avizata cantitatea comandata" | ascuns | Nu | but_urmator_tot1 |
cursor_comanda |
cursor_comanda |
A | acoperit azi, de portat |
| 22 | catre clienti, din lista | Da :15178 (grup 22,29) |
"AVIZ DE EXPEDITIE DIN LISTA DE PRETURI" | — | "nu e pe stoc!" | ascuns | Nu | — | cursor_preturi |
cursor_preturi |
B | acoperit azi, de portat |
| 23 | transfer subunitati, din lista | Da :15187 |
"TRANSFER INTRE SUBUNITATI" | — | "nu e pe stoc!" | ascuns | Nu | — | cursor_preturi (grup 1,22,5,29,7,10,23), :279 |
cursor_gestiune (grup 23,41), :776-778 |
B (cod comun, indiferent de sursa) | acoperit azi, dar sursa de cursor diverge intre forme — vezi §3 |
| 24 | aviz retur | Da :15242 |
"RETUR AVIZ DE EXPEDITIE" | "Cant. max. de returnat" | "nu se mai poate returna" | (nemodificat aici) | Nu | but_urmator_tot1 |
cursor_retur (grup 8,9,24), :306-307 |
lipseste din grupul retur (:819, doar 8,9) — lcSqlCursor nedefinit pe prototip |
B (invers) | acoperit azi, dar prototipul n-are ramura de cursor — vezi §3 |
| 25 | transfer subunitati, din comanda | Da :15206 |
"TRANSFER INTRE SUBUNITATI PE BAZA DE COMANDA" | — | "avizata cantitatea comandata" | ascuns | Nu | but_urmator_tot1 |
cursor_comanda |
cursor_comanda |
A | acoperit azi, de portat |
| 26 | catre clienti, din contract | Da :15216 |
"AVIZ DE EXPEDITIE DIN CONTRACTUL …" | "Cantitate in stoc" | "nu e pe stoc!" | ascuns | Nu | — | cursor_contract (grup 2,26,6,52) |
cursor_contract (grup 2,26,6 — fara 52, dar 26 e prezent) |
— (confirmat, §2) | acoperit azi, de portat |
| 27 | transfer subunitati, pe lucrare | n/a — ramane pe calea lui | n/a | n/a | n/a | n/a | n/a | n/a | cursor_lucrare, :302-304 |
cursor_lucrare, :815-817 |
n/a | ramas pe calea veche — frm_avizare_lucrare, confirmat §4 |
| 28 | catre clienti debitori, din comanda | Da :15168 (grup 21,28,42,47) |
"AVIZ DE EXPEDITIE DIN COMANDA" | — | "avizata cantitatea comandata" | ascuns | Nu | but_urmator_tot1 |
cursor_comanda |
cursor_comanda |
A | acoperit azi, de portat |
| 29 | catre clienti debitori, din lista | Da :15178 (grup 22,29) |
"AVIZ DE EXPEDITIE DIN LISTA DE PRETURI" | — | "nu e pe stoc!" | ascuns | Nu | — | cursor_preturi |
cursor_preturi |
B | acoperit azi, de portat |
| 30 | transfer subunitati, pe NIR | n/a — ramane pe calea lui, dar prin acelasi formular | (irelevant — formular niciodata aratat) | (irelevant) | (irelevant) | (irelevant) | (irelevant) | (irelevant) | cursor_aviz_nir, :299-300 |
cursor_aviz_nir, :813 |
n/a | ramas pe calea veche, cu nuanta — vezi §4 |
| 41 | retur transfer, lista pret | Da :15197 |
"RETUR TRANSFER" | — | "nu e pe stoc!" | ascuns | Nu | — | cursor_gestiune, :296-298 |
cursor_gestiune (grup 23,41) |
B | acoperit azi, de portat |
| 42 | catre clienti custodie, din comanda | Da :15168 (grup 21,28,42,47) |
"AVIZ DE EXPEDITIE DIN COMANDA" | — | "avizata cantitatea comandata" | ascuns | Nu | but_urmator_tot1 |
cursor_comanda |
cursor_comanda |
A | acoperit azi, de portat |
| 47 | catre clienti custodie K, din comanda | Da :15168 (grup 21,28,42,47) |
"AVIZ DE EXPEDITIE DIN COMANDA" | — | "avizata cantitatea comandata" | ascuns | Nu | but_urmator_tot1 |
cursor_comanda |
cursor_comanda |
A | acoperit azi, de portat |
| 50 | (in lucru) retur clienti custodie | Nu | — | — | — | — | — | — | nicio ramura | nicio ramura | n/a | neatins, "in lucru" |
Tipuri negative (-1..-13, ROAGEST/ROAAUTO): ramase pe calea altui produs — nu trec
niciodata prin factureaza()/factureaza2 din ROAFACTURARE (cautare exhaustiva, zero potriviri),
deci nu intra in perimetrul Do Case-ului acestui formular. Declarate aici explicit, nu omise.
2. Tipurile care nu intra in niciun Case — inventar complet
Cerinta explicita a misiunii: "nu doar 52". Lista completa, verificata pe intreg Do Case-ul
(ofacturare.vc2:15109-15248, citit integral, nu esantion) fata de lista de referinta:
Nu apar in niciun Case al frm_facturare_articole.Init:
| tip | reachable prin factureaza()? |
ce pierde concret |
|---|---|---|
| 43 | Nu (0 apeluri in tot D:\ROA) |
irelevant — nu ajunge la acest formular |
| 44 | Nu | irelevant |
| 45 | Da (Meniuri\politica.mn2:18) |
titlu, cap coloana cantitate, mesaj de stoc, cSerie nescoasa (ramane vizibila, desi tip 45 e explicit exclus din bookkeeping-ul de cantitate — cele doua lucruri nu sunt legate) |
| 46 | Nu | irelevant — zero documente si in datele de test |
| 48 | Da (Meniuri\politica.mn2:29, submeniu Marfaincus) |
idem 45 |
| 49 | Da (Meniuri\politica.mn2:26) |
idem 45 |
| 50 | Nu, "in lucru" | irelevant azi |
| 51 | Nu (interval id_set separat, alt produs) |
irelevant pentru acest formular |
| 52 | Da (Meniuri\contracte.mn2:18) |
titlu (ramane cel implicit al formularului), cSerie nescoasa, cap coloana cantitate implicit — cel mai vizibil defect, pentru ca 2/6 (acelasi grup logic) au titlu corect |
Concluzie: din cele noua tipuri fara Case, patru sunt reale si vizibile utilizatorului azi
(45, 48, 49, 52) — acestea sunt golul de completat cu valoare, nu doar 52. Celelalte cinci
(43,44,46,50,51) nu ajung niciodata la acest formular in fluxul curent — nu au nevoie de ramura in
Do Case pana cand ceva le conecteaza la factureaza() (posibil, dar in afara perimetrului
observabil aici; de tratat ca risc, nu ca bug, la sectiunea 10).
De ce raman "invizibile" azi cu cSerie/titlu implicit, nu cu eroare: Do Case ... Endcase fara
ramura Otherwise in VFP nu genereaza nicio eroare cand nimic nu se potriveste — pur si simplu sare
peste tot blocul. De-asta tip 45/48/49/52 "merg" (formularul se deschide, factureaza cu succes), doar
cu UI-ul netratat pentru cazul lor specific — un defect tacut, nu un crash, motiv probabil pentru care
n-a fost observat/raportat pana acum.
3. Divergentele standard vs. prototip
| Aspect | Standard (factureaza) |
Prototip (factureaza2) |
Comportament corect de pastrat |
|---|---|---|---|
| Cursor pe tip 23 | cursor_preturi (grup 1,22,5,29,7,10,23, :279) — tratat ca lista de preturi |
cursor_gestiune (grup 23,41, :776-778) — tratat ca transfer |
cursor_gestiune, impreuna cu 41 (deja stabilit de S4/S4b: transferul e o singura familie de tip, indiferent daca porneste "din lista" sau "retur"; tratarea ca lista de preturi pe standard e inconsistenta cu propriul titlu "TRANSFER INTRE SUBUNITATI" pe care tot standardul il afiseaza pentru tip 23) |
| Cursor pe tip 52 | prezent, grupat cu 2,26,6 (:283) |
absent din grupul contract (:762, doar 2,26,6) — lcSqlCursor ramane nedefinit daca cineva factureaza tip 52 prin prototip |
prezent, grupat cu 2,6,26 — lipsa lui pe prototip e o eroare de portare, nu o alegere deliberata (nimic in cod sugereaza ca 52 trebuia tratat diferit de 2/6/26 la nivel de cursor) |
| Cursor pe tip 24 | prezent, grupat cu 8,9 (:306-307) |
absent din grupul retur (:819, doar 8,9) — lcSqlCursor nedefinit |
prezent, grupat cu 8,9 — acelasi tip de omisiune ca la 52 |
| Init: diferentiere pe tip | 14 ramuri, seteaza titlu/cap coloana/mesaj/discount/cSerie/butoane |
practic nimic — doar lcTipDoc ("factura"/"aviz"), pe o lista fara tip 24 |
toata logica standardului, portata — prototipul nu are nimic de pastrat aici in afara de pozitia lcTipDoc |
Coloana cSerie |
exista in grid prin design, se scoate condiționat (10 din 21 tipuri acoperite) | nu exista deloc ca si coloana in grd_factura (gridul unic al prototipului) |
de decis explicit la proiectare (§5) — nu e o simpla portare, gridul insusi trebuie sa capete coloana |
but_urmator_tot1 (sau echivalentul lui) |
vizibil pe 9 din 21 de tipuri (§1) | nu exista conceptul in Init — prototipul nu are nimic care sa corespunda azi | de portat lista completa de vizibilitate din standard |
clb_discount.Visible |
ascuns explicit pe toate tipurile de aviz (21,28,42,47,22,29,23,41,25,26) |
niciodata atins in Init | de portat integral |
De ce conteaza asta pentru S5: planul spune ca formularul unificat se bazeaza pe prototip (arhitectura lui: grid unic, editare inline, cautare pe server — deja deciziile S1-S4). Dar diferentierea pe tip nu vine "aproape gata" din prototip — vine aproape in intregime din standard, si trebuie portata, nu doar completata cu cele patru tipuri lipsa. Cele doua liste (tipuri lipsa din standard: 45/48/49/52; tot ce lipseste din prototip: aproape totul) sunt probleme diferite, care se rezolva in aceeasi miscare daca proiectarea de la §5 porneste de la o sursa unica de configurare portata integral din standard, cu cele patru completari incluse de la inceput (nu adaugate separat, dupa portare).
4. Tipurile speciale (27, 30) — confirmate pe cod
Tip 27 — transfer pe baza de lucrare
Confirmat la trei niveluri, toate in ofacturare.prg:
Do Case tnTip = 27 -> poDate.nIdTipDoc = 6(:188-189, tip document AVIZ);Do Case tnTip = 27 -> lcObiect = [frm_date_aviz_lucrare](:218-219) — formular de antet diferit, nufrm_date_aviz/frm_date_factura;Do Case tnTip = 27 -> lcObject = [frm_avizare_lucrare](:386-387) — formular de articole diferit, nufrm_facturare_articole. Cursorul sursa e si el propriu:cursor_lucrare(:302-304), populat pepoDate.id_lucrare, un camp pe care restul tipurilor nu-l au.
Ce il tine pe calea lui: id_lucrare — o legatura pe care niciun alt tip de document n-o are
(lucrare de service/executie, nu comanda/aviz/contract). frm_avizare_lucrare grupeaza gestiunile
destinatie diferit (crsgestiunidest, :388-393, cu optiunea <TOATE>), o structura pe care
frm_facturare_articole/2 n-o au. Formularul unificat n-ar avea id_lucrare si n-ar avea
gruparea pe gestiuni destinatie — motiv suficient sa ramana separat, confirmat pe cod, nu
presupus.
Tip 30 — transfer pe baza de NIR
Nuanta importanta, gasita aici: tip 30 nu ocoleste frm_facturare_articole — il
instantiaza, exact ca orice alt tip din grupul "otherwise" (ofacturare.prg:395, lcObject = [frm_facturare_articole], ramura Else a lui If tnTip = 27). Trece prin acelasi Init, acelasi
Do Case de la :15109-15248 (unde 30 nu are ramura proprie — ar avea aceleasi goluri ca 45/48/49
daca ar fi vreodata aratat). Diferenta reala: formularul nu e niciodata aratat
(ofacturare.prg:444-453):
IF tnTip = 30 && AVIZ DIN NIR
ofrmdetaliifactura.do_calculeaza_totaluri()
ofrmdetaliifactura.but_termin1.Click()
plVizibil = .F.
...
ELSE
...
If plVizibil
ofrmdetaliifactura.Show()
Else
ofrmdetaliifactura.Release()
pnButon = 2
Endif
ENDIF
Ce il tine pe calea lui: nu structura formularului (e acelasi obiect), ci automatizarea
completa a fluxului — cursorul sursa (cursor_aviz_nir, populat din VRUL/tranzactii de receptie,
nu din comanda/lista de preturi) vine deja complet, iar codul apeleaza direct metodele de finalizare
fara interactiune. Pentru formularul unificat: daca arhitectura noua pastreaza acelasi tipar
("creeaza obiectul, populeaza, cheama finalizarea, Release() fara Show()"), tip 30 continua sa
functioneze neschimbat — nu are nevoie de ramura in configurarea vizuala (§5), pentru ca vizualul nu
se vede niciodata. Singurul risc real: daca do_calculeaza_totaluri()/but_termin1.Click() ale
formularului unificat ajung sa citeasca vreo proprietate pe care doar Do Case-ul vizual o seteaza
azi (de exemplu, un cod care ar verifica This.cmesaj_cantitate sau lcTipDoc in logica de calcul,
nu doar in UI) — de verificat explicit la implementare, nu presupus ca "nu conteaza pentru ca nu
se vede".
5. Ce structura inlocuieste Do Case-ul de 140 de linii
Optiunile comparate
(a) Pastreaza Do Case, doar completeaza-l (adauga ramuri pentru 45/48/49/52, porteaza restul in
prototip). Cost minim imediat, dar nu rezolva problema de fond: un Do Case fara Otherwise nu
semnaleaza niciodata un tip lipsa — exact mecanismul care a produs golul de azi (patru tipuri reale
pierdute, ani la rand, fara nicio eroare). Orice tip nou de document adaugat in viitor (suita are deja
46,50 "in lucru", 43,44,51 din alte fluxuri) risca aceeasi soarta.
(b) Metoda separata per grup de tipuri (configureaza_lista_preturi(), configureaza_comanda(),
...). Mai clar decat un Do Case unic, dar tot implicit — un tip nou tot nu declanseaza nicio
eroare daca nimeni nu-l adauga in metoda corecta; doar muta problema din 140 de linii intr-un fisier
cu mai multe metode mici, fara sa adauge un mecanism de detectie.
(c) Tabel de configurare per tip (RECOMANDAT). Un cursor/tabel cu un rand per tip, coloanele
fiind exact proprietatile pe care Do Case-ul le seteaza azi: titlu, cap_cantitate, mesaj_stoc,
discount_vizibil (L), are_serie (L), tip_doc (factura/aviz), buton_tot_vizibil (L),
buton_retur_vizibil (L), grup_sursa (pentru meniul S4b: lista/comanda/aviz-comanda/transfer/ retur/contract-articole/contract-rate). Populat printr-un singur bloc de INSERT INTO (sau un DBF
static, configuratie_tip_document.dbf, editabil fara compilare) — un rand per tip din
tipuri_documente_facturare.md, inclusiv cele patru azi lipsa.
Init devine:
SELECT * FROM configuratie_tip_document WHERE tip = poDate.tip INTO CURSOR crscfgtip
If Reccount('crscfgtip') = 0
* tip necunoscut -- eroare explicita, nu formular netratat tacut
AMESSAGEBOX("Tip de document necunoscut in configurare: " + Transform(poDate.tip), 16, "Eroare configurare")
Thisform.Release()
Return
Endif
This.lb_titlu_alb_b121.Caption = crscfgtip.titlu
This.grd_articole.cCantitate.header1.Caption = crscfgtip.cap_cantitate
This.cmesaj_cantitate = crscfgtip.mesaj_stoc
This.clb_discount.Visible = crscfgtip.discount_vizibil
If !crscfgtip.are_serie
This.grd_articole.RemoveObject('cSerie')
Endif
This.but_urmator_tot1.Visible = crscfgtip.buton_tot_vizibil
This.but_retur.Visible = crscfgtip.buton_retur_vizibil
De ce e mai bun decat (a)/(b) pe cost de intretinere:
- Un tip lipsa devine o eroare vizibila la deschidere, nu un formular netratat tacut — exact defectul care a permis golul de azi sa treaca neobservat ani la rand.
- "Cat de usor se vede un tip lipsa" e mecanic, nu vizual — vezi §8, o interogare simpla compara
lista de tipuri din configurare cu lista de referinta din
tipuri_documente_facturare.md, fara sa ruleze formularul. - Grupurile identice raman explicite, nu implicite — azi, "tipurile 21,28,42,47 au acelasi titlu"
se vede doar citind
Inlist(...); intr-un tabel, acelasi lucru se vede ca patru randuri cu aceeasi valoare in coloanatitlu— usor de generat cu un singurINSERTper grup (FOR EACH tip IN (21,28,42,47) ... INSERT ...), nu mai putin explicit, dar auditabil cuSELECT titlu, COUNT(*) GROUP BY titlu. - Coloana
are_serierezolva si divergenta standard/prototip de la §3 — prototipul nu are azi conceptul deloc; cu configurarea noua, adaugarea coloaneicSeriein gridul unificat devine conditionata de aceeasi sursa unica, indiferent de forma de baza.
Cost: portarea initiala a ~21 de randuri (14 ramuri distincte de azi + 4 completari + grupare
explicita), plus un nou tabel/cursor de intretinut. Nu e cod nou complex — e date, nu logica; riscul
de regresie e in acuratetea portarii (fiecare valoare trebuie sa corespunda exact cu ce face azi
Do Case-ul), verificabil linie cu linie fata de tabelul din §1.
Recomandare finala: (c), cu tabelul de configurare implementat ca DBF static (nu cursor
generat in cod) — editabil de oricine fara sa recompileze, si direct verificabil cu SELECT fara sa
porneasca formularul (vezi §8).
6. Grupuri naturale de tipuri
Din tabelul §1, grupurile care au azi (sau ar trebui sa aiba) valori identice pe toate coloanele:
| Grup | Tipuri | Ce difera in interiorul grupului |
|---|---|---|
| Lista de preturi, fara stoc special | 1, 5, 7, 10 | Nimic in Init — difera doar valuta/tip document la nivel de antet (poDate.in_valuta, nIdTipDoc), nu in acest formular |
| Contract, factura | 2, 6 (+ 52 de adaugat) | Nimic in Init dupa completare — 52 e valuta, ca 6, dar cu alt id_set; titlul/coloanele sunt identice |
| Aviz din comanda (clienti/debitori/custodie) | 21, 28, 42, 47 | Nimic in Init — difera doar destinatia comerciala (client normal/debitor/custodie), invizibila la acest nivel |
| Aviz din lista de preturi | 22, 29 | Nimic — difera doar client normal/debitor |
| Retur facturi | 8, 9 | Nimic — lei/valuta |
| Transfer subunitati | 23, 41 | Sens (din lista vs. retur) — titlu diferit ("TRANSFER..." vs "RETUR TRANSFER"), restul identic; trebuie unificate pe cursor (§3) inainte de unificare vizuala |
| Comanda proprie | 3 | Singur — cap de coloana propriu ("Cantitate comandata") |
| Avize proprii | 4 | Singur — discount vizibil (spre deosebire de toate celelalte avize) |
| Aviz din contract | 26 | Singur — titlu propriu, dar cursor comun cu grupul contract |
| Aviz retur | 24 | Singur — cursor comun cu 8/9, dar titlu si but_urmator_tot1 proprii |
| Custodie K | 48, 49 | Identice ca structura vizuala (ambele lipsesc azi) — difera doar cu/fara descarcare K, invizibil la acest nivel |
| Restaurant | 45 | Singur, azi lipsa |
Observatie de proiectare: grupurile "aviz din comanda" (21/28/42/47) si "comanda" (3) au acelasi
cap de coloana si mesaj de stoc conceptual ("cantitate comandata"), dar text usor diferit
("facturata"/"avizata") — pastrate distincte in tabelul de configurare (nu fortate identice), pentru
ca diferenta e deliberata in codul de azi (:15149 vs :15176, verb diferit).
7. Pasi de implementare, ordonati
- Extrage tabelul de configurare din
Do Case-ul standard, exhaustiv — un rand per tip dintipuri_documente_facturare.mdcare intra prin acest formular (Facturi + Avize, exclus 27/30/ negative), valorile copiate exact din §1. Gata cand:SELECT DISTINCT tip FROM configuratie_tip_documentproduce exact multimea{1,2,3,4,5,6,7,8,9,10,21,22,23,24,25,26,28,29, 41,42,45,47,48,49,52}(23 de tipuri) — nici unul in minus, nici unul in plus fata de lista calculata in §8. - Completeaza cele patru randuri azi lipsa (45,48,49,52) cu valori coerente cu grupul lor logic
(45 langa lista de preturi cu stoc dezactivat conceptual; 48/49 langa custodie K; 52 langa 2/6) —
decizie de continut, nu doar de structura; de validat cu Marius inainte de a le considera
"gata", pentru ca azi nu exista niciun titlu/mesaj de referinta pentru ele (nimeni nu l-a vazut
pe ecran). Gata cand: cele patru randuri au valori nenule pe toate coloanele obligatorii
(
titlu,cap_cantitate,mesaj_stoc). - Corecteaza rutarea cursorului:
23trece pecursor_gestiune(unificat cu41, nu mai divide standard/prototip);52si24primesc ramura de cursor pe orice cale ramane vie din prototip (daca formularul unificat pastreazafactureaza2-stil, sau devine parte din calea unica dacafactureaza/factureaza2se unesc — decizie separata, in afara acestei povesti). Gata cand: deschiderea formularului pe tip23,24si52prin calea noua produce acelasi continut incrsarticoleca varianta care functiona deja (23→prototip vechi pentru comparatie de continut,24/52→standard). - Adauga coloana
cSeriein gridul unificat, condiționata peare_serie— azi absenta din gridul prototipului; adaugata o singura data, aratata/ascunsa din configurare, nu prinRemoveObjectscris de mana pe fiecare tip. Gata cand: pe un tip cuare_serie=.T.(ex. 4) coloana e vizibila; pe un tip cuare_serie=.F.(ex. 3) nu e. - Inlocuieste
Do Case-ul dinInitcu citirea din configurare (structura din §5), inclusiv ramura de eroare explicita pe tip necunoscut. Gata cand: pentru fiecare din cele 23 de tipuri, deschiderea formularului seteaza exact valorile din tabelul §1/pasul 2 (comparatie automata, nu vizuala — proprietatile sunt citibile headless). - Verifica tipurile speciale raman neatinse: 27 (cale total separata, neschimbata), 30 (acelasi
formular, dar
do_calculeaza_totaluri/but_termin1.Click()nu citesc nimic setat doar de vechiulDo Casevizual — verificare explicita, §4). Gata cand: un document tip 30 de test se finalizeaza cu acelasi rezultat inVANZARI/VANZARI_DETALIIinainte si dupa migrare. - Documenteaza tipurile neatinse (43,44,46,50,51) ca decizie explicita, nu ca omisiune — un
comentariu in tabelul de configurare (
* 43,44,46,50,51: neconectate la factureaza() in ROAFACTURARE, verificat <data>) ca viitorii cititori sa nu presupuna ca lipsesc din greseala. Gata cand: comentariul exista si linkeaza spre acest raport.
Depinde de: S4 (cautarea articolelor pe server) pentru arhitectura gridului unic — pasul 4 de aici
presupune ca gridul unificat exista deja in forma stabilita de S4; S4b (bara de butoane) pentru
buton_tot_vizibil/buton_retur_vizibil, care alimenteaza si meniul xmenu() de acolo — coloanele
grup_sursa din tabelul de configurare (§5) sunt exact ce cere S4b sectiunea 3.
8. Cum se verifica ca acoperirea e completa — proba mecanica
Nu o citire — o interogare care compara doua liste. Doua surse de adevar:
- Lista de referinta: tipurile din
COMUN\docs\tipuri_documente_facturare.md, sectiunile "Facturi" si "Avize de expeditie", minus cele confirmate neatinse azi de acest formular (27, 30 raman — vezi nuanta §4 — dar 43,44,46,50,51 se exclud daca raman neconectate; de recalculat lista la fiecare rulare, nu de la o constanta inghetata). - Lista din configurare (dupa implementarea §5):
SELECT DISTINCT tip FROM configuratie_tip_document.
Script de verificare (headless, fara UI, rulabil oricand):
* verifica_acoperire_tip.prg — proba mecanica pentru S5
LOCAL lnLipsa, lnInPlus
* 1. lista de referinta -- tinuta manual sincron cu tipuri_documente_facturare.md
* (facturi + avize, exclus negative; 27/30 raman in lista, tratate separat la pasul 3)
DIMENSION laReferinta[23]
laReferinta = [1,2,3,4,5,6,7,8,9,10,21,22,23,24,25,26,27,28,29,30,41,42,47,52] && + 45,48,49 dupa Pasul 2
* 2. lista din configurare
SELECT DISTINCT tip FROM configuratie_tip_document INTO CURSOR crsCfg
* 3. tipuri de referinta fara configurare (exclus 27, 30 -- cale separata confirmata)
* 4. tipuri in configurare fara corespondent in referinta (config "orfana")
* -- ambele liste trebuie sa fie goale la "gata"
Alternativ, fara sa astepte implementarea §5: acelasi principiu se aplica azi direct pe
Do Case-ul din ofacturare.vc2:15109-15248, extragand tipurile din fiecare Case ... Inlist/= prin
vfp_symbols.ps1 -Grep 'Case (poDate\.tip|Inlist\(poDate\.tip' si comparand rezultatul cu lista de
referinta — exact tehnica folosita in aceasta cercetare pentru a produce tabelul din §1 (nu o
citire vizuala, o extractie sistematica).
Pentru cursor (rutare, §3): acelasi principiu, pe ofacturare.prg, comparand tipurile din fiecare
Do Case/Inlist de la :266-308 (standard) cu cele de la :748-822 (prototip) — orice tip prezent
intr-una si absent in cealalta e o divergenta de raportat (asa au fost gasite 52 si 24 in aceasta
sesiune).
9. Ce nu se poate testa headless
- Titlul, capul de coloana, mesajul de stoc ca text afisat efectiv pe ecran — verificabile
headless doar ca proprietati setate (
This.lb_titlu_alb_b121.CaptiondupaInit(), apelat direct cu unpoDatede test), nu ca randare vizuala. Diferenta conteaza: o proprietate corect setata pe un control care nu exista (lb_titlu_alb_b121lipsa din prototip azi) ar trece "headless" fara sa arate nimic real — de confirmat mai intai ca ambele controale exista in formularul unificat. - Coloanele de grid (
grd_articole/grd_factura, coloanacSerienoua) — capcana deja cunoscuta pe acest proiect: sub-A -T(rulare headless),ColumnCount=0/RecordSourceraman artefacte, coloanele nu se materializeaza. Exista un harness UI vizibil care le citeste corect — orice verificare aare_serie/coloanelor trebuie sa treaca prin acela, nu prin-A -T. - Tip 30 — fluxul complet fara
Show()— se poate rula headless (nu deschide nicio fereastra prin constructie), dar verificarea "rezultatul in Oracle e identic inainte/dupa" cere date de test reale (un NIR cu articole), nu doar apelul metodei. - Popup-ul/dialogul viitor din S4b (
xmenu(),cauta_alfa), dacagrup_sursadin tabelul de configurare (§5/§6) ajunge sa-l alimenteze direct — mostenit ca limitare de la raportul S4b (§8de acolo): continutullcMeniuverificabil ca text, popup-ul afisat nu. - Comportamentul real al meniurilor
politica.mn2/contracte.mn2pentru tipurile 45/48/49/52 — se poate confirma ca exista intrarea de meniu (citire.mn2, facuta in aceasta cercetare), dar nu ca apasarea ei in productie deschide exact formularul asteptat, fara o rulare UI vizibila.
10. Riscuri si ce ramane de decis de Marius
- Continutul exact (titlu/mesaj) pentru cele patru tipuri azi netratate (45,48,49,52) — codul nu
ofera niciun precedent vizual (n-au fost vazute niciodata corect pe ecran), deci textele propuse in
Pasul 2 (§7) sunt o propunere, nu o recuperare a unui text existent. Recomandare: 45 langa
grupul "lista de preturi fara stoc" (e exclus explicit din bookkeeping de stoc,
:12871); 48/49 cu titlu care mentioneaza "custodie" (singurul lucru care le distinge conceptual azi, in afara de coeficientul K, invizibil la acest nivel); 52 identic cu 2/6 ("FACTURA PE CTR. ..."), pentru coerenta cu gruparea deja facuta corect infrm_date_factura.Init(:9530,9632,9670, grupul2,6,52). - Daca 23 trece pe
cursor_gestiunepe calea unificata, comportamentul vizibil pentru operator se schimba (sursa de articole devine stocul din gestiune, nu lista de preturi) — decizie de produs, nu doar tehnica, deja semnalata de S4/S4b, dar repetata aici pentru ca afecteaza direct §5/§7 (tabelul de configurare trebuie sa reflecte alegerea finala, nu ambele variante). Recomandare:cursor_gestiune, argumentat de coerenta cu titlul "TRANSFER INTRE SUBUNITATI" pe care insusi standardul il afiseaza azi pentru 23 (titlul spune "transfer", cursorul azi spune "lista de preturi" — inconsistenta interna de rezolvat, nu de pastrat). - Daca 43,44,46,50,51 raman permanent neconectate la
factureaza(), sau exista planuri sa fie activate — nu s-a gasit nicio dovada de cod ca ar fi in curs, dar nici o confirmare ca sunt abandonate definitiv (in afara de50, marcat explicit "in lucru" in sursa). De intrebat pe Marius direct, pentru ca raspunsul schimba daca tabelul de configurare (§5) trebuie sa le includa preventiv sau poate ramane cu 23 de randuri. - Coloana
cSeriepe gridul unificat — cost de adaugare — prototipul n-are azi conceptul deloc; adaugarea ei presupune modificari de grid (nu doar de cod), posibil in afara perimetrului text-only (.vc2/.sc2printxt2vcx.ps1) daca structura de coloane a gridului cere editare in IDE — de confirmat la implementare, nu presupus ca e o simpla proprietate. - Tabel de configurare ca
DBFstatic vs.INSERT-uri in cod — recomandarea (§5) e DBF, pentru editabilitate fara recompilare, dar suita foloseste azi predominant cod pentru acest fel de configurare (niciun precedent de DBF static de configurare gasit infrm_facturare_articole/frm_date_factura) — de validat cu Marius daca abaterea de la conventia existenta merita beneficiul, sau daca un cursor generat in cod (mai aproape de stilul actual, dar mai putin editabil) e preferat.
Handoff
Cercetare + proiectare incheiata in aceasta sesiune, fara sa fie nevoie de predare de context.
Toate cele zece sectiuni cerute de misiune sunt completate, cu fisier:linie verificat direct pe
fisierele text reale (ofacturare.vc2, ofacturare.prg, nu .bak), plus meniurile .mn2 si
raportul S4/S4b/S4_punct2 citate ca sursa pentru punctele deja stabilite (nereinvestigate).
Descoperiri dincolo de cerinta explicita a misiunii, semnalate clar in text: (1) patru tipuri lipsa
din Do Case, nu unul (45/48/49/52, sectiunea 2); (2) prototipul (frm_facturare_articole2.Init)
e aproape complet gol pe diferentiere de tip, nu doar incomplet (sectiunea 3) — cea mai mare
descoperire a acestei sesiuni, cu impact direct asupra efortului de implementare estimat pentru S5;
(3) doua divergente noi de rutare a cursorului (52, 24), pe langa cea deja cunoscuta (23) (sectiunea
3); (4) tipurile 26 si 52 confirmate fara niciun bookkeeping crsarticole, inchizand punctul lasat
deschis de raportul S4 punctul 2 (sectiunea 1, nota de subsol pe tabel).
Niciun fisier de cod atins, niciun git_sync.ps1/txt2vcx.ps1 rulat, nicio scriere pe Oracle (numai
Read/Grep/vfp_symbols.ps1 pe fisiere de pe disc).