Compare commits
24 Commits
3b9ca92b96
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 3af008992c | |||
| b3cbeef691 | |||
| db22b1acf9 | |||
| 82ab6209f6 | |||
| 5756a5a8ec | |||
| 140ba162de | |||
| 6afaad03bf | |||
| ea977c7bfc | |||
| 265ba78b0a | |||
| 17eea3b64a | |||
| 26c33e03a2 | |||
| 8999a5339f | |||
| bc5ff8211f | |||
| 53ef674f70 | |||
| f2e539629e | |||
| 869403cd3e | |||
| 8b5a670ff1 | |||
| 57c5fcb5d6 | |||
| 7cd7d57708 | |||
| 58655dac6e | |||
| 0c9255842d | |||
| 1ae9d3f14a | |||
| 5bc2cb82f1 | |||
| 96577f0005 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -104,5 +104,6 @@ roacont_ref.FPT
|
||||
# --- COMUN este gestionat separat, prin propriul sau git (romfast/comun.git) ---
|
||||
COMUN/
|
||||
|
||||
docs/diff_runda*.patch
|
||||
docs/diff_*.patch
|
||||
.gstack/
|
||||
docs/local/
|
||||
|
||||
46
CLAUDE.md
46
CLAUDE.md
@@ -46,6 +46,25 @@ Editing: write-back text→binary via `txt2vcx.ps1` is supported **only for `.vc
|
||||
(vcx/scx); `.frx/.mnx/.lbx/.pjx/.dbc/.dbf` are editable **only in the VFP IDE** (no write-back).
|
||||
See `D:\ROA\UTIL\foxbin2prg\CLAUDE.md` and `COMUN\docs\flux-editare-vfp-text.md`.
|
||||
|
||||
Grep can't tell **which class/method** a hit inside a `.vc2` belongs to (the class header may be
|
||||
thousands of lines above it, and ~2/3 of the file is properties/metadata). `vfp_symbols.ps1`
|
||||
indexes the line range of every class/method/procedure and labels hits with their owner — use it
|
||||
before any `txt2vcx.ps1` edit to get the exact line range of the method you are changing. Its
|
||||
built-in defaults target ROAACNPRO, so always pass this project's paths:
|
||||
|
||||
```powershell
|
||||
$s = 'D:\ROA\UTIL\foxbin2prg\vfp_symbols.ps1'
|
||||
$c = @('-CacheRoot', 'D:\ROA\ROACONT', '-ProjectRoot', 'D:\ROA\ROACONT', '-IndexFile', 'D:\ROA\_vfp_textcache\roacont\_symbols.tsv')
|
||||
|
||||
powershell -ExecutionPolicy Bypass -File $s @c -Grep '<expression>' -CodeOnly # hits labeled class.method, code only
|
||||
powershell -ExecutionPolicy Bypass -File $s @c -Where '<file>.vc2:<line>' # who owns this line
|
||||
powershell -ExecutionPolicy Bypass -File $s @c -Find '<name>' # where it is DEFINED
|
||||
powershell -ExecutionPolicy Bypass -File $s @c -Class '<class name>' # inheritance chain + methods
|
||||
```
|
||||
|
||||
The index (`_symbols.tsv`) rebuilds itself when the text is newer, so refresh the text first — it
|
||||
can't see IDE edits that were never converted. Full search guide: `COMUN\docs\cautare_vcx_vct.md`.
|
||||
|
||||
Orphan cleanup: on each full run `git_sync` deletes `.??2` text whose binary was removed from
|
||||
SVN (and `.db2` whose table left the per-project list) and reports it, so git records the
|
||||
deletion.
|
||||
@@ -170,6 +189,10 @@ ROACONT - X.Y.Z
|
||||
-->
|
||||
```
|
||||
|
||||
Regula de continut: changelog-ul e pentru utilizatori — se scrie **doar ce vede utilizatorul**,
|
||||
scurt si compact. Erorile introduse si reparate in aceeasi versiune nelivrata **nu se trec**
|
||||
(clientul nu le-a vazut niciodata); intrarea versiunii curente se rescrie, nu se acumuleaza.
|
||||
|
||||
Tags in use: `:nou:` (new feature), `:modificare:` (change/fix to existing behavior),
|
||||
`:eroare:` (bug fix), `:adaugare:` (addition). Version numbers increment per entry (current
|
||||
series is `2.11.x`). When asked to log a change, follow this exact format/tag set rather than
|
||||
@@ -215,6 +238,29 @@ Preferintele lui Marius pentru sesiunile pe acest proiect:
|
||||
(`.vcx`/`.scx`), diff-ul lizibil se face pe forma text `.vc2`/`.sc2` regenerata cu
|
||||
`git_sync.ps1`, inainte de write-back cu `txt2vcx.ps1`.
|
||||
|
||||
## Stil de raspuns: scurt si concret
|
||||
|
||||
Marius vrea raspunsuri **clare, concise, fara vorbarie**. Regula, nu preferinta.
|
||||
|
||||
- **Starea si ce urmeaza, nu povestea.** Ce e gata, ce e stricat, ce trebuie decis, ce urmeaza —
|
||||
in liste scurte, cu fisier si linie. Fara reconstituirea drumului pana la rezultat.
|
||||
- **Fara naratiune de proces**: ce a raportat fiecare agent, cine ce a corectat, cum au fost
|
||||
coordonate benzile. Intra in `docs/`, nu in raspuns.
|
||||
- **Fara laude si fara reluari.** Nu repeta ce s-a spus deja in conversatie.
|
||||
- Detaliile tehnice lungi (dovezi, iesiri de test, metodologie) se scriu in fisier si se
|
||||
**trimite la el**, nu se copiaza in raspuns.
|
||||
- Cand e ceva de decis: enunta decizia si optiunile in cateva randuri, cu recomandarea ta.
|
||||
|
||||
**Formatul obligatoriu al raspunsului**, in aceasta ordine, maxim cateva randuri fiecare:
|
||||
|
||||
1. **Am facut:** ce e gata (fisier:linie).
|
||||
2. **Urmeaza:** ce fac mai departe.
|
||||
3. **De la tine:** intrebarea, clar si simpla, cu recomandarea mea.
|
||||
|
||||
Explicatiile, dovezile si descoperirile colaterale merg in `docs/`, cu un link. Nu se reia in
|
||||
raspuns rationamentul, nu se explica de ce a fost greu, nu se justifica alegerile decat daca
|
||||
sunt cerute.
|
||||
|
||||
## Skill routing
|
||||
|
||||
When the user's request matches an available skill, invoke it via the Skill tool. When in doubt, invoke the skill.
|
||||
|
||||
@@ -20865,7 +20865,6 @@ DEFINE CLASS frm_deconttva AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
|
||||
Set Date To Ymd
|
||||
Set Mark To '-'
|
||||
SET STEP ON
|
||||
lcNumePrenumeDeclarant = Alltrim(NVL(gofirma.declarant,''))
|
||||
lcNumeDeclarant = lcNumePrenumeDeclarant
|
||||
lcPrenumeDeclarant = ""
|
||||
@@ -21063,7 +21062,6 @@ DEFINE CLASS frm_deconttva AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
|
||||
Set Date To Ymd
|
||||
Set Mark To '-'
|
||||
Set Step On
|
||||
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
|
||||
lcNumeDeclarant = lcNumePrenumeDeclarant
|
||||
lcPrenumeDeclarant = ""
|
||||
@@ -21274,7 +21272,6 @@ DEFINE CLASS frm_deconttva AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
|
||||
Set Date To Ymd
|
||||
Set Mark To '-'
|
||||
Set Step On
|
||||
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
|
||||
lcNumeDeclarant = lcNumePrenumeDeclarant
|
||||
lcPrenumeDeclarant = ""
|
||||
@@ -21485,7 +21482,6 @@ DEFINE CLASS frm_deconttva AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
|
||||
Set Date To Ymd
|
||||
Set Mark To '-'
|
||||
Set Step On
|
||||
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
|
||||
lcNumeDeclarant = lcNumePrenumeDeclarant
|
||||
lcPrenumeDeclarant = ""
|
||||
@@ -22921,7 +22917,6 @@ DEFINE CLASS frm_deconttva_201601 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
|
||||
Set Date To Ymd
|
||||
Set Mark To '-'
|
||||
SET STEP ON
|
||||
lcNumePrenumeDeclarant = Alltrim(NVL(gofirma.declarant,''))
|
||||
lcNumeDeclarant = lcNumePrenumeDeclarant
|
||||
lcPrenumeDeclarant = ""
|
||||
@@ -23119,7 +23114,6 @@ DEFINE CLASS frm_deconttva_201601 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
|
||||
Set Date To Ymd
|
||||
Set Mark To '-'
|
||||
Set Step On
|
||||
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
|
||||
lcNumeDeclarant = lcNumePrenumeDeclarant
|
||||
lcPrenumeDeclarant = ""
|
||||
@@ -23330,7 +23324,6 @@ DEFINE CLASS frm_deconttva_201601 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
|
||||
Set Date To Ymd
|
||||
Set Mark To '-'
|
||||
Set Step On
|
||||
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
|
||||
lcNumeDeclarant = lcNumePrenumeDeclarant
|
||||
lcPrenumeDeclarant = ""
|
||||
@@ -23541,7 +23534,6 @@ DEFINE CLASS frm_deconttva_201601 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
|
||||
Set Date To Ymd
|
||||
Set Mark To '-'
|
||||
Set Step On
|
||||
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
|
||||
lcNumeDeclarant = lcNumePrenumeDeclarant
|
||||
lcPrenumeDeclarant = ""
|
||||
@@ -25155,7 +25147,6 @@ DEFINE CLASS frm_deconttva_201701 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
|
||||
Set Date To Ymd
|
||||
Set Mark To '-'
|
||||
SET STEP ON
|
||||
lcNumePrenumeDeclarant = Alltrim(NVL(gofirma.declarant,''))
|
||||
lcNumeDeclarant = lcNumePrenumeDeclarant
|
||||
lcPrenumeDeclarant = ""
|
||||
@@ -25353,7 +25344,6 @@ DEFINE CLASS frm_deconttva_201701 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
|
||||
Set Date To Ymd
|
||||
Set Mark To '-'
|
||||
Set Step On
|
||||
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
|
||||
lcNumeDeclarant = lcNumePrenumeDeclarant
|
||||
lcPrenumeDeclarant = ""
|
||||
@@ -25564,7 +25554,6 @@ DEFINE CLASS frm_deconttva_201701 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
|
||||
Set Date To Ymd
|
||||
Set Mark To '-'
|
||||
Set Step On
|
||||
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
|
||||
lcNumeDeclarant = lcNumePrenumeDeclarant
|
||||
lcPrenumeDeclarant = ""
|
||||
@@ -25775,7 +25764,6 @@ DEFINE CLASS frm_deconttva_201701 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
|
||||
Set Date To Ymd
|
||||
Set Mark To '-'
|
||||
Set Step On
|
||||
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
|
||||
lcNumeDeclarant = lcNumePrenumeDeclarant
|
||||
lcPrenumeDeclarant = ""
|
||||
@@ -25997,7 +25985,6 @@ DEFINE CLASS frm_deconttva_201701 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
|
||||
Set Date To Ymd
|
||||
Set Mark To '-'
|
||||
Set Step On
|
||||
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
|
||||
lcNumeDeclarant = lcNumePrenumeDeclarant
|
||||
lcPrenumeDeclarant = ""
|
||||
@@ -26221,7 +26208,6 @@ DEFINE CLASS frm_deconttva_201701 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
|
||||
Set Date To Ymd
|
||||
Set Mark To '-'
|
||||
Set Step On
|
||||
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
|
||||
lcNumeDeclarant = lcNumePrenumeDeclarant
|
||||
lcPrenumeDeclarant = ""
|
||||
@@ -26425,7 +26411,6 @@ DEFINE CLASS frm_deconttva_201701 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
|
||||
Set Date To Ymd
|
||||
Set Mark To '-'
|
||||
Set Step On
|
||||
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
|
||||
lcNumeDeclarant = lcNumePrenumeDeclarant
|
||||
lcPrenumeDeclarant = ""
|
||||
@@ -26631,7 +26616,6 @@ DEFINE CLASS frm_deconttva_201701 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
|
||||
Set Date To Ymd
|
||||
Set Mark To '-'
|
||||
Set Step On
|
||||
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
|
||||
lcNumeDeclarant = lcNumePrenumeDeclarant
|
||||
lcPrenumeDeclarant = ""
|
||||
@@ -26835,7 +26819,6 @@ DEFINE CLASS frm_deconttva_201701 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
|
||||
Set Date To Ymd
|
||||
Set Mark To '-'
|
||||
Set Step On
|
||||
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
|
||||
lcNumeDeclarant = lcNumePrenumeDeclarant
|
||||
lcPrenumeDeclarant = ""
|
||||
@@ -28466,7 +28449,6 @@ DEFINE CLASS frm_deconttva_202601 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
|
||||
Set Date To Ymd
|
||||
Set Mark To '-'
|
||||
SET STEP ON
|
||||
lcNumePrenumeDeclarant = Alltrim(NVL(gofirma.declarant,''))
|
||||
lcNumeDeclarant = lcNumePrenumeDeclarant
|
||||
lcPrenumeDeclarant = ""
|
||||
@@ -28664,7 +28646,6 @@ DEFINE CLASS frm_deconttva_202601 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
|
||||
Set Date To Ymd
|
||||
Set Mark To '-'
|
||||
Set Step On
|
||||
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
|
||||
lcNumeDeclarant = lcNumePrenumeDeclarant
|
||||
lcPrenumeDeclarant = ""
|
||||
@@ -28875,7 +28856,6 @@ DEFINE CLASS frm_deconttva_202601 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
|
||||
Set Date To Ymd
|
||||
Set Mark To '-'
|
||||
Set Step On
|
||||
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
|
||||
lcNumeDeclarant = lcNumePrenumeDeclarant
|
||||
lcPrenumeDeclarant = ""
|
||||
@@ -29086,7 +29066,6 @@ DEFINE CLASS frm_deconttva_202601 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
|
||||
Set Date To Ymd
|
||||
Set Mark To '-'
|
||||
Set Step On
|
||||
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
|
||||
lcNumeDeclarant = lcNumePrenumeDeclarant
|
||||
lcPrenumeDeclarant = ""
|
||||
@@ -29308,7 +29287,6 @@ DEFINE CLASS frm_deconttva_202601 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
|
||||
Set Date To Ymd
|
||||
Set Mark To '-'
|
||||
Set Step On
|
||||
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
|
||||
lcNumeDeclarant = lcNumePrenumeDeclarant
|
||||
lcPrenumeDeclarant = ""
|
||||
@@ -29532,7 +29510,6 @@ DEFINE CLASS frm_deconttva_202601 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
|
||||
Set Date To Ymd
|
||||
Set Mark To '-'
|
||||
Set Step On
|
||||
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
|
||||
lcNumeDeclarant = lcNumePrenumeDeclarant
|
||||
lcPrenumeDeclarant = ""
|
||||
@@ -29736,7 +29713,6 @@ DEFINE CLASS frm_deconttva_202601 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
|
||||
Set Date To Ymd
|
||||
Set Mark To '-'
|
||||
Set Step On
|
||||
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
|
||||
lcNumeDeclarant = lcNumePrenumeDeclarant
|
||||
lcPrenumeDeclarant = ""
|
||||
@@ -29942,7 +29918,6 @@ DEFINE CLASS frm_deconttva_202601 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
|
||||
Set Date To Ymd
|
||||
Set Mark To '-'
|
||||
Set Step On
|
||||
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
|
||||
lcNumeDeclarant = lcNumePrenumeDeclarant
|
||||
lcPrenumeDeclarant = ""
|
||||
@@ -30146,7 +30121,6 @@ DEFINE CLASS frm_deconttva_202601 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
|
||||
Set Date To Ymd
|
||||
Set Mark To '-'
|
||||
Set Step On
|
||||
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
|
||||
lcNumeDeclarant = lcNumePrenumeDeclarant
|
||||
lcPrenumeDeclarant = ""
|
||||
@@ -38862,7 +38836,6 @@ DEFINE CLASS frm_regcump2010 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
*!* Delete From cListRCTemp Where Padl(nract,14,'0') + '|' + Dtos(dataact) + '|' + Padr(denumire,100,' ') Not In ;
|
||||
*!* (Select Padl(nract,14,'0') + '|' + Dtos(dataact) + '|' + Padr(denumire,100,' ') From cListRC WHERE !EMPTY(NVL(denumire,'')) )
|
||||
*!* Endif
|
||||
SET STEP ON
|
||||
WAIT WINDOW 'TVA exigibilizat din plati facturi cu TVA Incasare' NOWAIT
|
||||
*** ADAUG TVA INCASARE (DIN INCASARI/PLATI, TVA 4427 LA 90 ZILE)
|
||||
TEXT to m.lcSql textmerge noshow
|
||||
@@ -42642,14 +42615,14 @@ DEFINE CLASS frm_regcump2025 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
from vjc2010
|
||||
where an = <<m.gnAn>>
|
||||
and luna = <<m.gnLuna>>
|
||||
and (RO11nt <> 0 or RO21nt <> 0 or ro19nt <> 0 or ro9nt <> 0 or ro5nt <> 0)
|
||||
and (RO11nt <> 0 or RO21nt <> 0 or ro20nt <> 0 or ro24nt <> 0 or ro19nt <> 0 or ro9nt <> 0 or ro5nt <> 0)
|
||||
and tva_incasare = 1)
|
||||
group by id_fact, cont) ip
|
||||
on jc.id_fact = ip.id_fact
|
||||
where jc.an = <<m.gnAn>>
|
||||
and jc.luna = <<m.gnLuna>>
|
||||
and jc.tva_incasare = 1
|
||||
and (jc.RO11nt <> 0 or jc.RO21nt <> 0 or jc.ro19nt <> 0 or jc.ro9nt <> 0 or jc.ro5nt <> 0)
|
||||
and (jc.RO11nt <> 0 or jc.RO21nt <> 0 or jc.ro20nt <> 0 or jc.ro24nt <> 0 or jc.ro19nt <> 0 or jc.ro9nt <> 0 or jc.ro5nt <> 0)
|
||||
and nvl(ip.sold, 0) - (RO11nb + RO11nt + RO21nb + RO21nt + RO20nb + RO20nt + RO24nb + RO24nt + ro19nb + ro19nt + ro9nb + ro9nt + ro5nb + ro5nt) <> 0
|
||||
ENDTEXT
|
||||
|
||||
@@ -43155,7 +43128,6 @@ DEFINE CLASS frm_regcump2025 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
lcWhere = Alltrim(Substr(m.lcWhere, m.lnPos + 11))
|
||||
Endif
|
||||
Endif
|
||||
SET STEP ON
|
||||
Do Case
|
||||
Case m.lnTipJurnal = 1
|
||||
pcSubtitlu = "Achizitii de bunuri si prestari de sevicii taxabile din tara"
|
||||
@@ -43452,7 +43424,6 @@ DEFINE CLASS frm_regcump2025 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
*!* Delete From cListRCTemp Where Padl(nract,14,'0') + '|' + Dtos(dataact) + '|' + Padr(denumire,100,' ') Not In ;
|
||||
*!* (Select Padl(nract,14,'0') + '|' + Dtos(dataact) + '|' + Padr(denumire,100,' ') From cListRC WHERE !EMPTY(NVL(denumire,'')) )
|
||||
*!* Endif
|
||||
SET STEP ON
|
||||
WAIT WINDOW 'TVA exigibilizat din plati facturi cu TVA Incasare' NOWAIT
|
||||
*** ADAUG TVA INCASARE (DIN INCASARI/PLATI, TVA 4427 LA 90 ZILE)
|
||||
TEXT to m.lcSql textmerge noshow
|
||||
@@ -43467,7 +43438,7 @@ DEFINE CLASS frm_regcump2025 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
LEFT Join JTVA_COLOANE J2 On J.id_jtva_coloana = J2.id_tva
|
||||
left join nom_fdoc fdoc on a.id_fdoc = fdoc.id_fdoc
|
||||
where a.an = ?m.gnAn and a.luna = ?m.gnLuna and a.sters = 0 and a.scd = '4426' And a.scc = '4428' And Nvl(a.id_jtva_coloana, 0) <> 0
|
||||
and jc.an = ?m.gnAn and jc.luna = ?m.gnLuna and (jc.RO11nt <> 0 or jc.RO21nt <> 0 or jc.ro19nt <> 0 or jc.ro9nt <> 0 or jc.ro5nt <> 0)
|
||||
and jc.an = ?m.gnAn and jc.luna = ?m.gnLuna and (jc.RO11nt <> 0 or jc.RO21nt <> 0 or jc.ro20nt <> 0 or jc.ro24nt <> 0 or jc.ro19nt <> 0 or jc.ro9nt <> 0 or jc.ro5nt <> 0)
|
||||
ORDER BY a.cod, J2.COLOANA_JC
|
||||
ENDTEXT
|
||||
|
||||
@@ -44214,7 +44185,6 @@ DEFINE CLASS frm_regcump2025 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
*!* 25.08.2014
|
||||
*!* marius.mutu
|
||||
*!* se transmit si soldurile pe cote de TVA 24,9,5 pentru cazul in care soldul total este 0
|
||||
SET STEP ON
|
||||
Local lcXMLFacturi
|
||||
If !(luna_inchisa Or m.glEMama)
|
||||
Select *, (RO11NB+RO21NB+RO24NB+RO20NB+RO19NB+RO09NB+RO05NB + RO11NT+RO21NT+RO24NT+RO20NT+RO19NT+RO09NT+RO05NT) as soldn, ;
|
||||
@@ -50170,7 +50140,6 @@ DEFINE CLASS frm_regvanz2010 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE do_excel
|
||||
SET STEP ON
|
||||
do export_excel_grid WITH thisform._grdbase1,"dataact, nract", "", this.lb_titlu_alb_b121.caption IN proceduri_excel.prg
|
||||
|
||||
return
|
||||
@@ -50521,7 +50490,6 @@ DEFINE CLASS frm_regvanz2010 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
|
||||
update_jtva_coloane('JV')
|
||||
*** SELECTEZ FACTURILE CU TVA_INCASARE CU TOTAL BAZA, TVA, BAZAN, TVAN
|
||||
SET STEP ON
|
||||
Select r.cod, r.id_fact, r.tip, r.denumire, r.nract, r.SERIE_ACT, r.dataact, r.COD_FISCAL, Space(10) As COD_TVA, Space(100) As EXPLICATIE_TVA, r.TOTCTVA, r.TOTFTVATAX, r.TOTTVATAX, TVA_INCASARE, ;
|
||||
(RO24B + RO20B + RO19B + RO9B + RO5B + CESCDD1 + CESCDD2 + CEOPTR + FODD + FOFDD + CESVDD + CESVFDD + CESVFS + ROTI + WRN + WRSCDD + WRSCFDD) As BAZA, ;
|
||||
(RO24T + RO20T + RO19T + RO9T + RO5T) As TVA, ;
|
||||
@@ -51396,7 +51364,6 @@ DEFINE CLASS frm_regvanz2010 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
*!* 25.08.2014
|
||||
*!* marius.mutu
|
||||
*!* se transmit si soldurile pe cote de TVA 24,9,5 pentru cazul in care soldul total este 0
|
||||
SET STEP ON
|
||||
Local lcXMLFacturi
|
||||
If !(luna_inchisa Or m.glEMama)
|
||||
Select *, (RO24NB+RO20NB+RO19NB+RO9NB+RO5NB + RO24NT+RO20NT+RO19NT+RO9NT+RO5NT) as soldn, ;
|
||||
@@ -53816,8 +53783,8 @@ DEFINE CLASS frm_regvanz2025 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
select jv.id_fact,
|
||||
ip.cont,
|
||||
nvl(ip.sold, 0) as soldf,
|
||||
(RO11nb + RO11nt + RO21nb + RO21nt + ro19nb + ro19nt + ro9nb + ro9nt + ro5nb + ro5nt) as soldn,
|
||||
nvl(ip.sold, 0) - (RO11nb + RO11nt + RO21nb + RO21nt + ro19nb + ro19nt + ro9nb + ro9nt + ro5nb + ro5nt) as solddif,
|
||||
(RO11nb + RO11nt + RO21nb + RO21nt + RO20nb + RO20nt + RO24nb + RO24nt + ro19nb + ro19nt + ro9nb + ro9nt + ro5nb + ro5nt) as soldn,
|
||||
nvl(ip.sold, 0) - (RO11nb + RO11nt + RO21nb + RO21nt + RO20nb + RO20nt + RO24nb + RO24nt + ro19nb + ro19nt + ro9nb + ro9nt + ro5nb + ro5nt) as solddif,
|
||||
jv.denumire,
|
||||
jv.nract,
|
||||
jv.serie_act,
|
||||
@@ -53830,6 +53797,10 @@ DEFINE CLASS frm_regvanz2025 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
jv.RO11nt,
|
||||
jv.RO21nb,
|
||||
jv.RO21nt,
|
||||
jv.RO20nb,
|
||||
jv.RO20nt,
|
||||
jv.RO24nb,
|
||||
jv.RO24nt,
|
||||
jv.ro19nb,
|
||||
jv.ro19nt,
|
||||
jv.ro9nb,
|
||||
@@ -53849,15 +53820,15 @@ DEFINE CLASS frm_regvanz2025 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
from vjv2010
|
||||
where an = <<m.gnAn>>
|
||||
and luna = <<m.gnLuna>>
|
||||
and (RO11nt <> 0 or RO21nt <> 0 or ro19nt <> 0 or ro9nt <> 0 or ro5nt <> 0)
|
||||
and (RO11nt <> 0 or RO21nt <> 0 or ro20nt <> 0 or ro24nt <> 0 or ro19nt <> 0 or ro9nt <> 0 or ro5nt <> 0)
|
||||
and tva_incasare = 1)
|
||||
group by id_fact, cont) ip
|
||||
on jv.id_fact = ip.id_fact
|
||||
where jv.an = <<m.gnAn>>
|
||||
and jv.luna = <<m.gnLuna>>
|
||||
and jv.tva_incasare = 1
|
||||
and (jv.RO11nt <> 0 or jv.RO21nt <> 0 or jv.ro19nt <> 0 or jv.ro9nt <> 0 or jv.ro5nt <> 0)
|
||||
and nvl(ip.sold, 0) - (RO11nb + RO11nt + RO21nb + RO21nt + ro19nb + ro19nt + ro9nb + ro9nt + ro5nb + ro5nt) <> 0
|
||||
and (jv.RO11nt <> 0 or jv.RO21nt <> 0 or jv.ro20nt <> 0 or jv.ro24nt <> 0 or jv.ro19nt <> 0 or jv.ro9nt <> 0 or jv.ro5nt <> 0)
|
||||
and nvl(ip.sold, 0) - (RO11nb + RO11nt + RO21nb + RO21nt + RO20nb + RO20nt + RO24nb + RO24nt + ro19nb + ro19nt + ro9nb + ro9nt + ro5nb + ro5nt) <> 0
|
||||
ENDTEXT
|
||||
|
||||
llSucces = goExecutor.oExecuta(m.lcSql, "crsSoldDif")
|
||||
@@ -53888,7 +53859,6 @@ DEFINE CLASS frm_regvanz2025 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE do_excel
|
||||
SET STEP ON
|
||||
do export_excel_grid WITH thisform._grdbase1,"dataact, nract", "", this.lb_titlu_alb_b121.caption IN proceduri_excel.prg
|
||||
|
||||
return
|
||||
@@ -54377,7 +54347,7 @@ DEFINE CLASS frm_regvanz2025 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
LEFT Join JTVA_COLOANE J2 On J.id_jtva_coloana = J2.id_tva
|
||||
left join nom_fdoc fdoc on a.id_fdoc = fdoc.id_fdoc
|
||||
where a.an = ?m.gnAn and a.luna = ?m.gnLuna and a.sters = 0 and a.scd = '4428' And a.scc = '4427' And Nvl(a.id_jtva_coloana, 0) <> 0
|
||||
and jv.an = ?m.gnAn and jv.luna = ?m.gnLuna and (jv.RO11nt <> 0 or jv.RO21nt <> 0 or jv.ro19nt <> 0 or jv.ro9nt <> 0 or jv.ro5nt <> 0)
|
||||
and jv.an = ?m.gnAn and jv.luna = ?m.gnLuna and (jv.RO11nt <> 0 or jv.RO21nt <> 0 or jv.ro20nt <> 0 or jv.ro24nt <> 0 or jv.ro19nt <> 0 or jv.ro9nt <> 0 or jv.ro5nt <> 0)
|
||||
order by a.cod, J2.COLOANA_JC
|
||||
ENDTEXT
|
||||
|
||||
@@ -55063,7 +55033,6 @@ DEFINE CLASS frm_regvanz2025 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
|
||||
*!* 25.08.2014
|
||||
*!* marius.mutu
|
||||
*!* se transmit si soldurile pe cote de TVA 24,9,5 pentru cazul in care soldul total este 0
|
||||
SET STEP ON
|
||||
Local lcXMLFacturi
|
||||
If !(luna_inchisa Or m.glEMama)
|
||||
Select *, (RO11NB+RO21NB+RO24NB+RO20NB+RO19NB+RO9NB+RO5NB + RO11NT+RO21NT+RO24NT+RO20NT+RO19NT+RO9NT+RO5NT) as soldn, ;
|
||||
|
||||
@@ -771,7 +771,7 @@ Procedure inchidere_tva_sold
|
||||
Local lnIdSet, lnNrAct, lnProcTVA, lnRecords, lnSucces, lnSuma, loAct
|
||||
Local lnCota, lnCotaTVA, lnSuma24, lnSuma5, lnSuma9, lnSumaT
|
||||
Local lnSuma24T, lnSuma5T, lnSuma9T, lnSumaNT, lcMesaj
|
||||
SET STEP ON
|
||||
Local lnSuma11, lnSuma19, lnSuma20, lnSuma21, lnSuma11T, lnSuma19T, lnSuma20T, lnSuma21T
|
||||
lcJurnal = Upper(Alltrim(m.tcJurnal)) && JC/JV
|
||||
If m.lcJurnal = 'JC' && Jurnal Cumparari
|
||||
lcSCD = '4426'
|
||||
@@ -788,7 +788,6 @@ SET STEP ON
|
||||
lcMesaj = ''
|
||||
lnIdSet = 99999 && nota fara predefinire
|
||||
lnBut = lans(m.lnIdSet)
|
||||
Set Step On
|
||||
If m.lnBut = 1
|
||||
Select actactan
|
||||
Scatter Name loAct
|
||||
@@ -799,8 +798,18 @@ SET STEP ON
|
||||
lnNrAct = crsTVAIncasareTemp.nract
|
||||
lnIdFact = crsTVAIncasareTemp.id_fact
|
||||
lnSumaT = soldn
|
||||
lnSuma21 = soldn21
|
||||
lnSuma11 = soldn11
|
||||
lnSuma21 = 0
|
||||
lnSuma11 = 0
|
||||
lnSuma21T = 0
|
||||
lnSuma11T = 0
|
||||
If Type('crsTVAIncasareTemp.soldn21') = 'N'
|
||||
lnSuma21 = crsTVAIncasareTemp.soldn21
|
||||
lnSuma11 = crsTVAIncasareTemp.soldn11
|
||||
Endif
|
||||
If Type('crsTVAIncasareTemp.ro21nt') = 'N'
|
||||
lnSuma21T = crsTVAIncasareTemp.ro21nt
|
||||
lnSuma11T = crsTVAIncasareTemp.ro11nt
|
||||
Endif
|
||||
|
||||
lnSuma24 = soldn24
|
||||
lnSuma20 = soldn20
|
||||
@@ -809,16 +818,12 @@ SET STEP ON
|
||||
lnSuma5 = soldn5
|
||||
|
||||
If m.lcJurnal = 'JC' && Jurnal Cumparari
|
||||
lnSuma21T = ro21nt
|
||||
lnSuma11T = ro11nt
|
||||
lnSuma24T = ro24nt
|
||||
lnSuma20T = ro20nt
|
||||
lnSuma19T = ro19nt
|
||||
lnSuma9T = ro09nt
|
||||
lnSuma5T = ro05nt
|
||||
ELSE
|
||||
lnSuma21T = ro21nt
|
||||
lnSuma11T = ro11nt
|
||||
lnSuma24T = ro24nt
|
||||
lnSuma20T = ro20nt
|
||||
lnSuma19T = ro19nt
|
||||
@@ -830,7 +835,7 @@ SET STEP ON
|
||||
lnSuma = m.lnSumaT
|
||||
lnCotaTVA = 0.00
|
||||
If m.lnSumaT = 0
|
||||
lnSuma = Iif(m.lnCota = 1, m.lnSuma24, Iif(m.lnCota = 2, m.lnSuma20, Iif(m.lnCota = 3, m.lnSuma19, Iif(m.lnCota = 4, m.lnSuma9, Iif(m.lnCota = 5, m.lnSuma5, Iif(m.lnCota = 21, m.lnSuma21, m.lnSuma11))))))
|
||||
lnSuma = Iif(m.lnCota = 1, m.lnSuma24, Iif(m.lnCota = 2, m.lnSuma20, Iif(m.lnCota = 3, m.lnSuma19, Iif(m.lnCota = 4, m.lnSuma9, Iif(m.lnCota = 5, m.lnSuma5, Iif(m.lnCota = 6, m.lnSuma21, m.lnSuma11))))))
|
||||
lnCotaTVA = Iif(m.lnCota = 1, 1.24, Iif(m.lnCota = 2, 1.20, Iif(m.lnCota = 3, 1.19, Iif(m.lnCota = 4, 1.09, Iif(m.lnCota = 5, 1.05, Iif(m.lnCota = 6, 1.21, 1.11))))))
|
||||
Endif
|
||||
|
||||
|
||||
@@ -1991,9 +1991,10 @@ select *
|
||||
Use In (Select('cIncasariBanca2'))
|
||||
|
||||
*** Verific pe ANAF starea split tva la data curenta
|
||||
*!* 31.07.2026 marius.mutu: ordine explicita MASA (CACHE,ANAF) - corect pentru data trecuta pdDataI
|
||||
SELECT distinct cod_fiscal FROM cFacturiTVA INTO CURSOR cCodFiscalTemp
|
||||
loVerificareANAF = CREATEOBJECT("VerificareANAF")
|
||||
loVerificareANAF.VerificaListaCIF("cCodFiscalTemp", m.pdDataI, "crsANAF")
|
||||
loVerificareANAF.VerificaListaCIF("cCodFiscalTemp", m.pdDataI, "crsANAF", "MASA")
|
||||
USE IN (SELECT('cCodFiscalTemp'))
|
||||
IF USED("crsAnaf")
|
||||
*!* crsANAF (cui N(13), data D, denumire V(100), firma V(100), adresa C(244), scpTVA L, data_inceput_ScpTVA D, data_sfarsit_ScpTVA D, data_anul_imp_ScpTVA D, mesaj_ScpTVA C(244), ;
|
||||
@@ -2308,9 +2309,10 @@ select *
|
||||
Use In (Select('cIncasariBanca2'))
|
||||
|
||||
*** Verific pe ANAF starea split tva la data curenta
|
||||
*!* 31.07.2026 marius.mutu: ordine explicita UNIC (ANAF intai) - starea de azi, cache-ul ramane plasa de siguranta
|
||||
SELECT distinct cod_fiscal FROM cFacturiTVA INTO CURSOR cCodFiscalTemp
|
||||
loVerificareANAF = CREATEOBJECT("VerificareANAF")
|
||||
loVerificareANAF.VerificaListaCIF("cCodFiscalTemp", Date(), "crsANAF")
|
||||
loVerificareANAF.VerificaListaCIF("cCodFiscalTemp", Date(), "crsANAF", "UNIC")
|
||||
USE IN (SELECT('cCodFiscalTemp'))
|
||||
IF USED("crsAnaf")
|
||||
*!* crsANAF (cui N(13), data D, denumire V(100), firma V(100), adresa C(244), scpTVA L, data_inceput_ScpTVA D, data_sfarsit_ScpTVA D, data_anul_imp_ScpTVA D, mesaj_ScpTVA C(244), ;
|
||||
|
||||
@@ -209,6 +209,7 @@ SET PROCEDURE TO onomenclatoare.prg ADDITIVE
|
||||
SET PROCEDURE TO saft_d406.prg ADDITIVE
|
||||
SET PROCEDURE TO ofacturare.prg ADDITIVE
|
||||
SET PROCEDURE TO ofacturare_comun.prg ADDITIVE
|
||||
SET PROCEDURE TO ofacturare_editare.prg ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_facturare.prg ADDITIVE
|
||||
SET PROCEDURE TO anaf_efactura.prg ADDITIVE
|
||||
SET PROCEDURE TO import_efactura.prg ADDITIVE
|
||||
|
||||
@@ -81,6 +81,10 @@
|
||||
*!* 01.072026
|
||||
*!* oSalesInvoices - se facea join dublu vanzari - jv2007 in cazul facturilor cu tva la incasare
|
||||
|
||||
*!* 27.07.2026
|
||||
*!* do_erori_saft, do_ident_saft - raport erori validator pe intelesul utilizatorului (fisierul <xml>_explicat.txt): pagina, pozitie, partener/cont identificat, explicatie scurta si sectiunea "Cum rezolvati"
|
||||
*!* erorile fictive TaxCode "nu se afla in lista" (bug DUKIntegrator) sunt separate si ignorabile; chatbot-ul primeste doar erorile reale; mesajul separat de parteneri respinsi (do_erori_partener_saft) eliminat din flux
|
||||
|
||||
* saft_D406
|
||||
Procedure viz_saft_d406
|
||||
loD406 = Createobject("D406")
|
||||
@@ -254,10 +258,10 @@ Define Class d406 As Custom
|
||||
Local lcTaxTable, lcTipDeclaratie
|
||||
LOCAL lnBytes, llSucces
|
||||
Local lcAssetTransactions, lcAssets, lcCaleFisier, lcComunPath, lcConfigDir, lcFileName
|
||||
Local lcFisierRaspuns, lcMovementofGoods, lcNumeFisier, lcOwners, lcParams, lcPhysicalStock
|
||||
Local lcFisierExplicat, lcFisierRaspuns, lcMovementofGoods, lcNumeFisier, lcOwners, lcParams, lcPhysicalStock
|
||||
Local lcProducts, lcUOMTable, lcValidator, lcXMLTemp, lnFileHandle, lnSec, lcSufixCale, lcSufixFisier
|
||||
LOCAL lcMessage, loChatBot, lcMesajErori
|
||||
LOCAL lnAn1, lnAn2, lnLuna1, lnLuna2
|
||||
LOCAL lnAn1, lnAn2, lnLuna1, lnLuna2, lnEroriFictive, lnEroriReale
|
||||
|
||||
lnAn1 = This.oUnitate.an1
|
||||
lnLuna1 = This.oUnitate.luna1
|
||||
@@ -552,24 +556,30 @@ Define Class d406 As Custom
|
||||
DELETE FILE(m.lcFisierRaspuns)
|
||||
|
||||
* Lansare validator pentru creare PDF
|
||||
lcParams = ' "' + m.lcFileName + '"'
|
||||
lcParams = ' "' + m.lcFileName + '"'
|
||||
OPEN_DEFAULT_APP(m.lcValidator, m.lcParams)
|
||||
|
||||
ELSE
|
||||
*!* 26.07.2026 scot din fisierul de erori codurile de partener respinse de validator
|
||||
lcMesajErori = This.do_erori_partener_saft(m.lcFisierRaspuns)
|
||||
IF !EMPTY(m.lcMesajErori)
|
||||
IF AMESSAGEBOX(m.lcMesajErori + CHR(13) + CHR(10) + CHR(13) + CHR(10) + 'Doriti exportul listei in Excel?',0+4+48,_screen.Caption) = 6
|
||||
goExport.export2xlsx('cEroriPartSaft', 'erori_cod_partener_saft_' + ALLTRIM(STR(m.lnAn2)) + PADL(m.lnLuna2, 2, '0'))
|
||||
ENDIF
|
||||
USE IN (SELECT('cEroriPartSaft'))
|
||||
*!* 27.07.2026 un singur raport compact cu erorile explicate si identificate, erorile fictive de TaxCode (bug DUKIntegrator) separate
|
||||
lnEroriReale = 0
|
||||
lnEroriFictive = 0
|
||||
lcMesajErori = ''
|
||||
* Mai astept 2 secunde pentru ca se deschide fisierul cu erori si DUKIntegrator inca scrie in fisier si fisierul deschis sau parsat este partial
|
||||
Wait Window Timeout 2 "S-a generat fisierul raspuns. Se clasifica erorile..."
|
||||
|
||||
lcFisierExplicat = This.do_erori_saft(m.lcFisierRaspuns, @lnEroriReale, @lnEroriFictive, @lcMesajErori)
|
||||
OPEN_DEFAULT_APP(m.lcFisierRaspuns)
|
||||
IF !EMPTY(m.lcFisierExplicat)
|
||||
OPEN_DEFAULT_APP(m.lcFisierExplicat)
|
||||
ENDIF
|
||||
IF AMESSAGEBOX('Validare cu erori fisier: ' + m.lcFileName + CHR(13) + CHR(10) + 'Doriti sa interogati chatbot-ul de suport tehnic?',0+4+48,_screen.Caption) = 6
|
||||
lcMessage = FILETOSTR(m.lcFisierRaspuns)
|
||||
IF AMESSAGEBOX('Validare cu erori fisier: ' + m.lcFileName + CHR(13) + CHR(10) + ;
|
||||
'Erori de rezolvat: ' + ALLTRIM(STR(m.lnEroriReale)) + ;
|
||||
IIF(m.lnEroriFictive > 0, ' (+' + ALLTRIM(STR(m.lnEroriFictive)) + ' fictive - bug validator, se pot ignora)', '') + CHR(13) + CHR(10) + CHR(13) + CHR(10) + ;
|
||||
'Doriti sa interogati chatbot-ul de suport tehnic?',0+4+48,_screen.Caption) = 6
|
||||
lcMessage = EVL(m.lcMesajErori, FILETOSTR(m.lcFisierRaspuns))
|
||||
loChatBot = CREATEOBJECT("oChatBotLaunch", m.lcMessage)
|
||||
loChatBot.Launch()
|
||||
ENDIF
|
||||
OPEN_DEFAULT_APP(m.lcFisierRaspuns)
|
||||
ENDIF
|
||||
ENDIF
|
||||
ELSE
|
||||
AMESSAGEBOX('Nu s-a creat fisierul raspuns ' + m.lcFisierRaspuns + ' dupa validare!', 0+48,_screen.Caption)
|
||||
@@ -1311,6 +1321,338 @@ and b1.cont = b2.cont
|
||||
RETURN m.lcMesaj
|
||||
ENDPROC && do_erori_partener_saft
|
||||
|
||||
*************************************************
|
||||
* Parseaza fisierul de raspuns al validatorului ANAF, grupeaza erorile cu
|
||||
* explicatii pe intelesul utilizatorului si separa erorile fictive de TaxCode
|
||||
* (bug DUKIntegrator: apar cand exista alta eroare reala, pentru coduri valide)
|
||||
* Scrie raportul in <fisier>_explicat.txt si intoarce calea lui, gol la esec
|
||||
*************************************************
|
||||
PROCEDURE do_erori_saft
|
||||
LPARAMETERS tcFisierRaspuns, tnReale, tnFictive, tcMesajChat
|
||||
|
||||
LOCAL lcActiune, lcCRLF, lcCod, lcFisierExplicat, lcIdent, lcLegenda, lcLinie, lcLocatie, lcMarker
|
||||
LOCAL lcMesaj, lcMesajChat, lcPagina, lcProblema, lcRaport, lcSelect, lcValoare, llFictiv, lnCateg
|
||||
LOCAL lnFictive, lnFile, lnI, lnPoz, lnRand, lnReale
|
||||
|
||||
lcFisierExplicat = ''
|
||||
lcCRLF = CHR(13) + CHR(10)
|
||||
lcSelect = SELECT()
|
||||
|
||||
IF !FILE(m.tcFisierRaspuns)
|
||||
RETURN m.lcFisierExplicat
|
||||
ENDIF
|
||||
|
||||
*!* o eroare = linia de localizare "E:/F: sectiune ... (N)" + linia de mesaj; erorile fatale de parsare sunt pe o singura linie
|
||||
CREATE CURSOR cErrSaft (categ N(3), pagina C(30), rand N(7), valoare C(30), mesaj C(240), brut M)
|
||||
lnFile = FOPEN(m.tcFisierRaspuns, 0)
|
||||
IF m.lnFile < 0
|
||||
USE IN (SELECT('cErrSaft'))
|
||||
SELECT (m.lcSelect)
|
||||
RETURN m.lcFisierExplicat
|
||||
ENDIF
|
||||
lcLocatie = ''
|
||||
DO WHILE !FEOF(m.lnFile)
|
||||
lcLinie = FGETS(m.lnFile, 8192)
|
||||
IF INLIST(LEFT(LTRIM(m.lcLinie), 2), 'E:', 'F:')
|
||||
lcLocatie = m.lcLinie
|
||||
LOOP
|
||||
ENDIF
|
||||
IF ATC('Eroare fatala de parsare', m.lcLinie) > 0
|
||||
INSERT INTO cErrSaft (categ, pagina, rand, valoare, mesaj, brut) VALUES (11, '', 0, '', LEFT(ALLTRIM(m.lcLinie), 240), m.lcLinie)
|
||||
lcLocatie = ''
|
||||
LOOP
|
||||
ENDIF
|
||||
lcMesaj = ALLTRIM(m.lcLinie)
|
||||
IF EMPTY(m.lcMesaj) OR EMPTY(m.lcLocatie)
|
||||
LOOP
|
||||
ENDIF
|
||||
|
||||
* pagina din aplicatie, dupa sectiunea din linia de localizare
|
||||
DO CASE
|
||||
CASE ATC('PurchaseInvoices', m.lcLocatie) > 0
|
||||
lcPagina = 'Facturi achizitie'
|
||||
CASE ATC('SalesInvoices', m.lcLocatie) > 0
|
||||
lcPagina = 'Facturi vanzare'
|
||||
CASE ATC('Payments', m.lcLocatie) > 0
|
||||
lcPagina = 'Plati'
|
||||
CASE ATC('MovementOfGoods', m.lcLocatie) > 0
|
||||
lcPagina = 'Miscari bunuri'
|
||||
CASE ATC('AssetTransactions', m.lcLocatie) > 0
|
||||
lcPagina = 'Tranzactii active'
|
||||
CASE ATC('GeneralLedgerEntries', m.lcLocatie) > 0
|
||||
lcPagina = 'Inregistrari contabile'
|
||||
CASE ATC('GeneralLedgerAccounts', m.lcLocatie) > 0
|
||||
lcPagina = 'Conturi contabile'
|
||||
CASE ATC('Customers', m.lcLocatie) > 0
|
||||
lcPagina = 'Clienti'
|
||||
CASE ATC('Suppliers', m.lcLocatie) > 0
|
||||
lcPagina = 'Furnizori'
|
||||
CASE ATC('TaxTable', m.lcLocatie) > 0
|
||||
lcPagina = 'Nomenclator coduri taxa'
|
||||
CASE ATC('Products', m.lcLocatie) > 0
|
||||
lcPagina = 'Articole'
|
||||
CASE ATC('PhysicalStock', m.lcLocatie) > 0
|
||||
lcPagina = 'Stocuri'
|
||||
CASE ATC('Assets', m.lcLocatie) > 0
|
||||
lcPagina = 'Active'
|
||||
CASE ATC('Header', m.lcLocatie) > 0
|
||||
lcPagina = 'Definirea Companiei'
|
||||
OTHERWISE
|
||||
lcPagina = ''
|
||||
ENDCASE
|
||||
|
||||
* pozitia din grid = indexul elementului de nivel document din localizare
|
||||
lnRand = 0
|
||||
FOR lnI = 1 TO 8
|
||||
lcMarker = 'sectiune ' + GETWORDNUM('Transaction,Invoice,Payment,Customer,Supplier,Account,Asset,Product', m.lnI, ',') + ' ('
|
||||
lnPoz = ATC(m.lcMarker, m.lcLocatie)
|
||||
IF m.lnPoz > 0
|
||||
lnRand = INT(VAL(SUBSTR(m.lcLocatie, m.lnPoz + LEN(m.lcMarker))))
|
||||
EXIT
|
||||
ENDIF
|
||||
ENDFOR
|
||||
|
||||
lcValoare = ''
|
||||
DO CASE
|
||||
CASE ATC('formatul este invalid', m.lcMesaj) > 0 AND (ATC('CustomerID', m.lcMesaj) > 0 OR ATC('SupplierID', m.lcMesaj) > 0 OR ATC('RegistrationNumber', m.lcMesaj) > 0)
|
||||
lnCateg = 1
|
||||
CASE ATC('nu se afla in lista', m.lcMesaj) > 0 AND ATC('TaxCode (', m.lcLocatie) > 0
|
||||
lnCateg = 12
|
||||
lcValoare = STREXTRACT(m.lcMesaj, [valoarea '], ['])
|
||||
CASE ATC('vid nepermis', m.lcMesaj) > 0 AND (ATC('CustomerID (', m.lcLocatie) > 0 OR ATC('SupplierID (', m.lcLocatie) > 0)
|
||||
lnCateg = 2
|
||||
CASE ATC([elementul 'AccountID'], m.lcMesaj) > 0 AND ATC('Payments', m.lcLocatie) > 0
|
||||
lnCateg = 3
|
||||
CASE ATC([elementul 'InvoiceLine'], m.lcMesaj) > 0
|
||||
lnCateg = 4
|
||||
CASE ATC([elementul 'RegistrationNumber'], m.lcMesaj) > 0 OR (ATC('vid nepermis', m.lcMesaj) > 0 AND ATC('RegistrationNumber (', m.lcLocatie) > 0)
|
||||
lnCateg = 5
|
||||
CASE ATC('planul de conturi', m.lcMesaj) > 0
|
||||
lnCateg = 6
|
||||
lcValoare = STREXTRACT(m.lcMesaj, '[', ']')
|
||||
CASE ATC('vid nepermis', m.lcMesaj) > 0 AND ATC('AccountDescription', m.lcLocatie) > 0
|
||||
lnCateg = 7
|
||||
CASE ATC('BankAccount_choice', m.lcMesaj) > 0
|
||||
lnCateg = 8
|
||||
CASE ATC('SupplierInfo_choice', m.lcMesaj) > 0
|
||||
lnCateg = 9
|
||||
CASE ATC([elementul 'Transaction'], m.lcMesaj) > 0
|
||||
lnCateg = 10
|
||||
OTHERWISE
|
||||
lnCateg = 13
|
||||
ENDCASE
|
||||
INSERT INTO cErrSaft (categ, pagina, rand, valoare, mesaj, brut) ;
|
||||
VALUES (m.lnCateg, m.lcPagina, m.lnRand, LEFT(m.lcValoare, 30), IIF(m.lnCateg = 13, LEFT(m.lcMesaj, 240), ''), m.lcLocatie + m.lcCRLF + m.lcLinie)
|
||||
lcLocatie = ''
|
||||
ENDDO
|
||||
= FCLOSE(m.lnFile)
|
||||
|
||||
IF RECCOUNT('cErrSaft') = 0
|
||||
USE IN (SELECT('cErrSaft'))
|
||||
SELECT (m.lcSelect)
|
||||
RETURN m.lcFisierExplicat
|
||||
ENDIF
|
||||
|
||||
*!* erorile fictive TaxCode (bug DUKIntegrator): codul semnalat exista de fapt in nomenclator
|
||||
SELECT DISTINCT valoare FROM cErrSaft WHERE categ = 12 INTO CURSOR cCodTaxaVerif
|
||||
SELECT cCodTaxaVerif
|
||||
SCAN
|
||||
lcCod = ALLTRIM(cCodTaxaVerif.valoare)
|
||||
IF EMPTY(m.lcCod) OR LEN(CHRTRAN(m.lcCod, '0123456789', '')) > 0
|
||||
LOOP
|
||||
ENDIF
|
||||
llFictiv = .F.
|
||||
IF USED('cTaxTable')
|
||||
SELECT cTaxTable
|
||||
LOCATE FOR ALLTRIM(STR(taxcode)) == m.lcCod
|
||||
llFictiv = FOUND()
|
||||
ELSE
|
||||
IF goExecutor.oExecuta('SELECT taxcode FROM vsaft_taxtable WHERE taxcode = ' + m.lcCod, 'cTaxVerifTmp')
|
||||
llFictiv = (RECCOUNT('cTaxVerifTmp') > 0)
|
||||
USE IN (SELECT('cTaxVerifTmp'))
|
||||
ENDIF
|
||||
ENDIF
|
||||
IF m.llFictiv
|
||||
UPDATE cErrSaft SET categ = 90 WHERE categ = 12 AND ALLTRIM(valoare) == m.lcCod
|
||||
ENDIF
|
||||
SELECT cCodTaxaVerif
|
||||
ENDSCAN
|
||||
USE IN (SELECT('cCodTaxaVerif'))
|
||||
|
||||
SELECT cErrSaft
|
||||
COUNT FOR categ = 90 TO lnFictive
|
||||
|
||||
*!* textul pentru chatbot: erorile brute, fara cele fictive (bug validator)
|
||||
lcMesajChat = ''
|
||||
SELECT cErrSaft
|
||||
SCAN FOR categ < 90
|
||||
lcMesajChat = m.lcMesajChat + brut + m.lcCRLF
|
||||
ENDSCAN
|
||||
|
||||
*!* dedup: aceeasi problema pe aceeasi pozitie o singura data (ex: CustomerID + RegistrationNumber pe acelasi client)
|
||||
SELECT DISTINCT categ, pagina, valoare, mesaj, rand FROM cErrSaft WHERE categ < 90 ORDER BY 1, 2, 5 INTO CURSOR cErrPoz
|
||||
lnReale = RECCOUNT('cErrPoz')
|
||||
|
||||
lcRaport = 'ERORI VALIDARE D406 SAF-T - ' + JUSTFNAME(m.tcFisierRaspuns) + m.lcCRLF + ;
|
||||
'Erori de rezolvat: ' + ALLTRIM(STR(m.lnReale)) + ' | Fictive (bug validator, se pot ignora): ' + ALLTRIM(STR(m.lnFictive)) + m.lcCRLF + ;
|
||||
REPLICATE('=', 110) + m.lcCRLF
|
||||
lcLegenda = ''
|
||||
SELECT cErrPoz
|
||||
SCAN
|
||||
lcIdent = This.do_ident_saft(ALLTRIM(cErrPoz.pagina), cErrPoz.rand)
|
||||
lcActiune = ''
|
||||
DO CASE
|
||||
CASE cErrPoz.categ = 1
|
||||
lcProblema = 'cod partener SAF-T invalid (CUI/CNP gresit sau tip PJ/PF gresit)'
|
||||
lcActiune = 'Parteneri: corectati tip persoana / cod fiscal in Initializare > Entitati; CNP-uri invalide in masa: Initializari cod taxa/plata > Stergere CNP-uri invalide'
|
||||
CASE cErrPoz.categ = 2
|
||||
lcProblema = 'partener fara cod fiscal pe plata (sau nota nu e plata catre terti)'
|
||||
lcActiune = 'Plati: completati codul fiscal al partenerului (partener virtual: CUI-ul firmei) sau stergeti codul de plata de pe notele care nu sunt plati catre terti, in Registrul Jurnal'
|
||||
CASE cErrPoz.categ = 3
|
||||
lcProblema = 'plata fara cont contabil (nota nu e plata catre terti)'
|
||||
lcActiune = 'Plati: completati codul fiscal al partenerului (partener virtual: CUI-ul firmei) sau stergeti codul de plata de pe notele care nu sunt plati catre terti, in Registrul Jurnal'
|
||||
CASE cErrPoz.categ = 4
|
||||
lcProblema = 'factura fara articole (probabil document sters)'
|
||||
lcActiune = 'Facturi fara articole: Refacere Registru TVA Cumparari/Vanzari, apoi regenerati D406'
|
||||
CASE cErrPoz.categ = 5
|
||||
lcProblema = 'PJ fara cod fiscal sau PF marcata ca PJ'
|
||||
lcActiune = 'Parteneri: corectati tip persoana / cod fiscal in Initializare > Entitati; CNP-uri invalide in masa: Initializari cod taxa/plata > Stergere CNP-uri invalide'
|
||||
CASE cErrPoz.categ = 6
|
||||
lcProblema = 'contul ' + ALLTRIM(cErrPoz.valoare) + ' nu exista in planul de conturi'
|
||||
lcActiune = 'Conturi: corectati contul in notele din Registrul Jurnal sau completati planul de conturi al firmei'
|
||||
CASE cErrPoz.categ = 7
|
||||
lcProblema = 'cont fara denumire (nu exista in planul de conturi al firmei)'
|
||||
lcActiune = 'Conturi: corectati contul in notele din Registrul Jurnal sau completati planul de conturi al firmei'
|
||||
CASE cErrPoz.categ = 8
|
||||
lcProblema = 'lipseste contul bancar (IBAN) al firmei'
|
||||
lcActiune = 'Cont bancar: completati IBAN-ul in Definirea Companiei'
|
||||
CASE cErrPoz.categ = 9
|
||||
lcProblema = 'adresa furnizorului incompleta (judet/localitate) sau document sters'
|
||||
lcActiune = 'Adresa furnizor: dublu click pe furnizor in Facturi achizitie; daca e document sters cu valoare 0: Refacere Registru TVA Cumparari'
|
||||
CASE cErrPoz.categ = 10
|
||||
lcProblema = 'nu exista note contabile in perioada'
|
||||
lcActiune = 'Registru gol: introduceti o nota cu valoare 0 (ex: 371 = 371)'
|
||||
CASE cErrPoz.categ = 11
|
||||
lcProblema = ALLTRIM(cErrPoz.mesaj)
|
||||
lcActiune = 'Caracter nepermis: inlocuiti & cu "si" in campul sursa (denumire/adresa) si regenerati D406'
|
||||
CASE cErrPoz.categ = 12
|
||||
lcProblema = 'cod taxa ' + ALLTRIM(cErrPoz.valoare) + ' inexistent in nomenclatorul SAF-T'
|
||||
lcActiune = 'Cod taxa: corectati codul de taxa pe notele din Registrul Jurnal'
|
||||
OTHERWISE
|
||||
lcProblema = ALLTRIM(cErrPoz.mesaj)
|
||||
ENDCASE
|
||||
IF !EMPTY(m.lcActiune) AND ATC(m.lcActiune, m.lcLegenda) = 0
|
||||
lcLegenda = m.lcLegenda + '- ' + m.lcActiune + m.lcCRLF
|
||||
ENDIF
|
||||
lcRaport = m.lcRaport + PADR(ALLTRIM(cErrPoz.pagina), 20) + ' ' + ;
|
||||
PADR(IIF(cErrPoz.rand > 0, 'poz.' + ALLTRIM(STR(cErrPoz.rand)), ''), 8) + ' ' + ;
|
||||
IIF(EMPTY(m.lcIdent), '', PADR(m.lcIdent, 45) + ' ') + '- ' + m.lcProblema + m.lcCRLF
|
||||
ENDSCAN
|
||||
USE IN (SELECT('cErrPoz'))
|
||||
IF m.lnReale = 0
|
||||
lcRaport = m.lcRaport + 'Niciuna.' + m.lcCRLF
|
||||
ENDIF
|
||||
IF !EMPTY(m.lcLegenda)
|
||||
lcRaport = m.lcRaport + m.lcCRLF + 'CUM REZOLVATI:' + m.lcCRLF + m.lcLegenda
|
||||
ENDIF
|
||||
|
||||
IF m.lnFictive > 0
|
||||
lcIdent = ''
|
||||
SELECT valoare, COUNT(*) AS nr FROM cErrSaft WHERE categ = 90 GROUP BY 1 ORDER BY 1 INTO CURSOR cErrFictivSaft
|
||||
SELECT cErrFictivSaft
|
||||
SCAN
|
||||
lcIdent = m.lcIdent + IIF(EMPTY(m.lcIdent), '', ', ') + ALLTRIM(cErrFictivSaft.valoare) + ' (' + ALLTRIM(STR(cErrFictivSaft.nr)) + 'x)'
|
||||
ENDSCAN
|
||||
USE IN (SELECT('cErrFictivSaft'))
|
||||
lcRaport = m.lcRaport + m.lcCRLF + 'FICTIVE - BUG VALIDATOR ANAF (se pot ignora): cod taxa ' + m.lcIdent + m.lcCRLF + ;
|
||||
'Codurile sunt valide (exista in nomenclator); erorile apar doar cand exista alta eroare reala si dispar dupa rezolvarea ei.' + m.lcCRLF
|
||||
ENDIF
|
||||
|
||||
lcRaport = m.lcRaport + m.lcCRLF + 'Erorile brute: ' + m.tcFisierRaspuns + m.lcCRLF
|
||||
|
||||
lcFisierExplicat = ADDBS(JUSTPATH(m.tcFisierRaspuns)) + JUSTSTEM(m.tcFisierRaspuns) + '_explicat.txt'
|
||||
IF FILE(m.lcFisierExplicat)
|
||||
DELETE FILE (m.lcFisierExplicat)
|
||||
ENDIF
|
||||
= STRTOFILE(m.lcRaport, m.lcFisierExplicat)
|
||||
IF !FILE(m.lcFisierExplicat)
|
||||
lcFisierExplicat = ''
|
||||
ENDIF
|
||||
|
||||
USE IN (SELECT('cErrSaft'))
|
||||
SELECT (m.lcSelect)
|
||||
tnReale = m.lnReale
|
||||
tnFictive = m.lnFictive
|
||||
tcMesajChat = m.lcMesajChat
|
||||
|
||||
RETURN m.lcFisierExplicat
|
||||
ENDPROC && do_erori_saft
|
||||
|
||||
*************************************************
|
||||
* Identificatorul de afisat pentru pozitia tnRand din cursorul paginii tcPagina
|
||||
* (sectiunile XML se scriu prin SCAN secvential, deci pozitia din eroare este
|
||||
* a tnRand-a inregistrare vizibila; la Conturi ramane activ filtrul writer-ului)
|
||||
*************************************************
|
||||
PROCEDURE do_ident_saft
|
||||
LPARAMETERS tcPagina, tnRand
|
||||
|
||||
LOCAL lcAlias, lcIdent, lcSelect, lnRecno
|
||||
|
||||
lcIdent = ''
|
||||
IF m.tnRand <= 0
|
||||
RETURN m.lcIdent
|
||||
ENDIF
|
||||
DO CASE
|
||||
CASE m.tcPagina == 'Clienti'
|
||||
lcAlias = 'cCustomers'
|
||||
CASE m.tcPagina == 'Furnizori'
|
||||
lcAlias = 'cSuppliers'
|
||||
CASE m.tcPagina == 'Conturi contabile'
|
||||
lcAlias = 'cGeneralLedgerAccounts'
|
||||
CASE m.tcPagina == 'Inregistrari contabile'
|
||||
lcAlias = 'cGeneralLedgerEntries'
|
||||
CASE m.tcPagina == 'Plati'
|
||||
lcAlias = 'cPayments'
|
||||
CASE m.tcPagina == 'Facturi vanzare'
|
||||
lcAlias = 'cSalesInvoices'
|
||||
CASE m.tcPagina == 'Facturi achizitie'
|
||||
lcAlias = 'cPurchaseInvoices'
|
||||
OTHERWISE
|
||||
lcAlias = ''
|
||||
ENDCASE
|
||||
IF EMPTY(m.lcAlias) OR !USED(m.lcAlias)
|
||||
RETURN m.lcIdent
|
||||
ENDIF
|
||||
|
||||
lcSelect = SELECT()
|
||||
SELECT (m.lcAlias)
|
||||
lnRecno = RECNO()
|
||||
GO TOP
|
||||
IF m.tnRand > 1 AND !EOF()
|
||||
SKIP m.tnRand - 1
|
||||
ENDIF
|
||||
IF !EOF()
|
||||
DO CASE
|
||||
CASE INLIST(m.lcAlias, 'cCustomers', 'cSuppliers')
|
||||
lcIdent = ALLTRIM(NVL(saftpartid, '')) + ' ' + ALLTRIM(NVL(denumire, ''))
|
||||
CASE m.lcAlias == 'cGeneralLedgerAccounts'
|
||||
lcIdent = 'cont ' + ALLTRIM(NVL(cont, '')) + ' ' + ALLTRIM(NVL(denumire, ''))
|
||||
CASE m.lcAlias == 'cGeneralLedgerEntries'
|
||||
lcIdent = 'nota ' + ALLTRIM(TRANSFORM(cod)) + IIF(EMPTY(dataact), '', ' / ' + DTOC(dataact)) + ' cont ' + ALLTRIM(NVL(cont, '')) + ' ' + ALLTRIM(NVL(saftpartid, ''))
|
||||
CASE m.lcAlias == 'cPayments'
|
||||
lcIdent = IIF(TYPE('denumire') = 'C', ALLTRIM(NVL(denumire, '')) + ' ', '') + LEFT(ALLTRIM(NVL(explicatia, '')), 40)
|
||||
OTHERWISE
|
||||
lcIdent = 'fact. ' + ALLTRIM(TRANSFORM(nract)) + IIF(EMPTY(dataact), '', ' / ' + DTOC(dataact)) + ' ' + ALLTRIM(NVL(saftpartid, ''))
|
||||
ENDCASE
|
||||
ENDIF
|
||||
IF BETWEEN(m.lnRecno, 1, RECCOUNT(m.lcAlias))
|
||||
GO m.lnRecno
|
||||
ENDIF
|
||||
SELECT (m.lcSelect)
|
||||
|
||||
RETURN LEFT(ALLTRIM(m.lcIdent), 45)
|
||||
ENDPROC && do_ident_saft
|
||||
|
||||
&& IAU SOLDURILE DIN BALANTA DE VERIFICARE PENTRU CONTURILE DE IMOBLIZARI SI AMORTIZARI
|
||||
&& SI LE COMPAR CU VALOAREA DE INVENTAR SI AMORTIZAREA TOTALA DIN IMOBILIZARI CORPORALE/NECORPORALE CONTABIL
|
||||
Procedure do_verifica_imobilizari
|
||||
|
||||
133
TODOS.md
133
TODOS.md
@@ -92,3 +92,136 @@ Sursa: `docs/design-alegere-partener-anaf.md`, REVIZIA 4 (implementata doar nive
|
||||
- **Cerinte tehnice deja verificate** (de nepierdut la implementare) — sectiunea 8 din
|
||||
`docs/design-alegere-partener-anaf.md`: UC1, D-F2, C4, H1, H4, H5, H8, H9, M1, M7.
|
||||
- **Efort:** L. **Depinde de:** masuratorile de mai sus.
|
||||
- **Masurat partial (27.07.2026)**, vezi `docs/plan-reparatie-anaf-404-breaker.md`: latenta
|
||||
unui apel la ANAF sanatos 0,08 s; gazda care inghite pachetele 21,05 s fara timeout-uri,
|
||||
4,00 s cu SetTimeouts(2000,2000,3000,3000); WinHTTP asincron `Send()` 0,009 s,
|
||||
`WaitForResponse(0)` 0 s. Ramane nemasurat comportamentul la rafale (de la al catelea 429).
|
||||
|
||||
## P4 — Contract 404 pe drumul batch ANAF (D406 si sincronizari) — PRELUAT
|
||||
Preluat 31.07.2026, povestea S5 din transa `docs/contract-cache-anaf.md` (`docs/diff-S5-contract-404-batch.md`).
|
||||
- **Ce:** `validare.prg:1827` citeste corpul raspunsului doar pe `Status = 200`, la fel cum
|
||||
facea si wrapper-ul single-CUI. Pe loturi, un CUI inexistent si o cadere de serviciu ajung
|
||||
la utilizator ca acelasi lucru ("nu s-a putut verifica").
|
||||
- **De ce:** masurat 27.07.2026 — ANAF intoarce HTTP 404 cu corp complet
|
||||
`{"found":[],"notFound":[<cui>]}`, deci informatia exista, doar e aruncata. Regula corecta,
|
||||
stabilita si implementata pe calea single-CUI: verdict "inexistent" doar cand `notFound`
|
||||
contine chiar codul cerut (`notFound` apare si in raspunsurile de succes, ca tablou gol).
|
||||
- **Ce s-a facut deja in transa din 27.07:** doar timeout-urile pe calea batch (~105 s de
|
||||
fereastra inghetata devin ~20 s pe 500 de coduri). Logica de verdict nu s-a atins.
|
||||
- **De ce nu acum:** atinge interpretarea raspunsului in D406 si in sincronizari, deci cere
|
||||
runda proprie de teste pe declaratie, nu doar pe formularul de cautare.
|
||||
- **Efort:** M. **Depinde de:** transa `plan-reparatie-anaf-404-breaker.md` (regula notFound).
|
||||
|
||||
## P5 — Verificare ANAF dupa tara partenerului (punctul D)
|
||||
- **Ce:** tara partenerului adusa in cursorul de cautare, ca `cod_tara` caracter (gol sau `RO`
|
||||
= se verifica), in locul euristicii pe primele doua litere din codul fiscal.
|
||||
- **De ce:** dupa reparatia din 27.07, un partener extern cu cod pur numeric ajunge la ANAF si
|
||||
poate primi verdict rosu "Cod fiscal inexistent la ANAF". In MARIUSM_AUTO: 2825 parteneri,
|
||||
dintre care 21 cu alta tara — suprafata mica, dar reala si acum vizibila.
|
||||
- **Decizii deja luate (nu se redeschid):** se verifica dupa tara, nu dupa literele codului;
|
||||
tara necompletata = Romania; respinse explicit de Marius — functie noua cu query per partener
|
||||
si selectia din `VNOM_PARTENERI` ("prea multe join-uri in adresa"). `VALIDARE_CIF` nu se
|
||||
atinge in nicio varianta (folosita in toata suita).
|
||||
- **Ramas de facut:** lantul scurt `NOM_PARTENERI → ADRESE_PARTENERI (principala=1) →
|
||||
SYN_NOM_LOCALITATI → SYN_NOM_JUDETE → SYN_NOM_TARI.PRESCURTARE`, masurat fata de cautarea de
|
||||
azi (28 ms pe filtrul `cont='401' and denumire like 'FA%'`); al doilea drum,
|
||||
`CautPartenerContabilitate` (`ocautare.prg` ~890-960), selecteaza direct din tabela si cere
|
||||
join separat.
|
||||
- **Conditie de intrare:** reclamatii pe parteneri externi marcati rosu, vizibile in logul de
|
||||
discordante (`anaf_verif_cautare`).
|
||||
- **Efort:** M. **Depinde de:** masuratoarea lantului scurt.
|
||||
|
||||
## Amanari review /autoplan — cache ANAF pe ISTORIC_CODURI_FISCALE (29.07.2026)
|
||||
|
||||
Sursa: `docs/design-cache-anaf-istoric-coduri-fiscale.md`, sectiunea GSTACK REVIEW REPORT.
|
||||
|
||||
## P2 — Cascada de ferestre modale la verificarea in masa cu ANAF cazut
|
||||
- **Ce:** `AMESSAGEBOX` este apelat in interiorul buclei pe grupuri din
|
||||
`ANAF_SincronWebService_PlatitorTva` (`COMUN\programe\validare.prg:1968`, `:1970`, `:1976`,
|
||||
`:1993`, `:1996`). La 3000 de parteneri = 30 de grupuri, deci pana la 30 de ferestre modale
|
||||
de inchis manual la o singura rulare de D406.
|
||||
- **De ce:** cu ANAF cazut, plasa de siguranta introdusa de proiectarea din 29.07 lucreaza in
|
||||
spatele acestui zid de modale — castigul e invizibil pentru utilizator. Probabil mai valoros
|
||||
decat cache-ul insusi.
|
||||
- **Fix:** un singur mesaj la sfarsitul rularii (numar de grupuri esuate), nu unul per grup.
|
||||
- **De ce nu acum:** atinge interpretarea raspunsului pe traseul in masa (acelasi cod ca P4 de
|
||||
mai sus), deci cere runda proprie de teste pe declaratie.
|
||||
- **Efort:** S-M. **Depinde de:** mock-ul pe calea batch (T1 din review).
|
||||
|
||||
## P3 — Bucla O(n^2) la imperecherea rezultatului ANAF cu lista de parteneri
|
||||
- **Ce:** `COMUN\clase\overificari.vc2:2722` face `LOCATE FOR ...` liniar in interiorul unui
|
||||
`SCAN` peste cursorul de raspuns ANAF. Costul creste cu patratul numarului de parteneri.
|
||||
- **De ce:** tranșa de cache adauga peste bucla un apel de procedura Oracle per cod, deci
|
||||
ambele cresc pe acelasi traseu.
|
||||
- **Conditie de intrare:** masuratoarea ceruta oricum la E4, pe un lot de ~500 de coduri.
|
||||
Daca timpul e acceptabil, nu se atinge.
|
||||
- **Efort:** M. **Depinde de:** masuratoarea de la E4.
|
||||
|
||||
## P3 — Parsarea sarita cand primul rezultat nu are `dcod_judet`
|
||||
- **Ce:** `COMUN\programe\validare.prg:1986-1994` — daca
|
||||
`found_vfpsafe_[1].adresa_domiciliu_fiscal.dcod_judet` lipseste (cazul unui lot in care toate
|
||||
codurile sunt `notFound`, deci `found` e gol), se afiseaza fereastra de eroare "Serviciul web
|
||||
ANAF intors mesaj de eroare" si nu se parseaza nimic, desi raspunsul e valid.
|
||||
- **De ce:** face ca un lot legitim de coduri inexistente sa arate ca o defectiune de serviciu.
|
||||
- **Efort:** S. **Depinde de:** acelasi contract 404 pe calea batch (P4 de mai sus).
|
||||
|
||||
## P3 — `DATATVAMFIN` ramane text
|
||||
- **Ce:** `VARCHAR2(30)` din 2012, afisat direct la `COMUN\programe\oproceduri_comune.prg:4783`.
|
||||
Noile coloane de interval il fac redundant.
|
||||
- **De ce nu acum:** decizia explicita a proiectarii din 29.07 (Intrebarea deschisa 2).
|
||||
- **Efort:** S. **Depinde de:** livrarea coloanelor de interval.
|
||||
|
||||
## Amanari transa cache ANAF — completare (01.08.2026)
|
||||
|
||||
Sursa: `docs/diff-TRANSA-cache-anaf.md`, `docs/handoff_cache_anaf.md`.
|
||||
|
||||
## P1 — Rulare reala prin `PACK_UPDATE` pe TEST, inainte de prima livrare (decizie de EXECUTIE)
|
||||
- **Ce s-a facut deja:** cele trei scripturi ale transei (`co_2026_07_30_02_RTVAI_PACK_ROARTVAI.sql`,
|
||||
`co_2026_07_31_01_COMUN_ISTORIC_CF.sql`, `ff_2026_07_31_01_COMUN_ISTORIC_CF.sql`) figurau
|
||||
"aplicate" in tabela `versiune` din rulari manuale sqlplus, desi coada reala `UPD_DATABASE` nu
|
||||
avea niciun rand pentru ele. **Randurile s-au curatat** (`CONTAFIN_ORACLE` -9, `MARIUSM_AUTO` -7,
|
||||
`ACN` -1, zero randuri ramase pentru cele trei scripturi) si **toate trei s-au dovedit
|
||||
re-rulabile** (DDL gardat, inserturi `where not exists`, pachete `CREATE OR REPLACE`) — nu mai
|
||||
e nicio decizie tehnica de luat.
|
||||
- **Ce ramane:** doar **executia** propriu-zisa prin `PACK_UPDATE`, netrasa inca.
|
||||
`SCRIPTURI_CLAR` mai contine scripturi straine de transa, neaplicate — daca motorul ia tot ce
|
||||
gaseste pe disc, ar rula si munca in lucru a altcuiva pe un server de test partajat. Banda Oracle
|
||||
stabileste pe sursa daca fluxul se poate limita la cele trei fisiere ale transei.
|
||||
- **Efort:** S. **Depinde de:** decizia lui Marius de a executa `PACK_UPDATE` pe TEST (nimeni n-a
|
||||
apasat butonul inca); detaliu complet `docs\audit-oracle-final.md`.
|
||||
|
||||
## P3 — Export Excel din verificarea in masa (D406/D394) nu duce mai departe provenienta cache
|
||||
- **Ce:** `Programe\orapoarte.prg` (`Copy To ... Type Xl5`) nu adauga `sursa`/`data_sursa` in
|
||||
fisierul exportat — un fisier trimis mai departe nu arata ca o parte din verdicte vin din cache,
|
||||
nu dintr-un raspuns proaspat ANAF.
|
||||
- **De ce nu acum:** cursoarele exportate (`cFacturiTVA` si perechea de la a doua raportare) ar
|
||||
cere o coloana noua, iar `ALTER TABLE ADD COLUMN` pica pe cursor liber cu nume de camp peste 10
|
||||
caractere (`platitortva` are 11) — ar cere rematerializarea cursorului in doua situri de
|
||||
raportare, cu schimbarea formatului unui fisier care ajunge la client. Amanat explicit de
|
||||
Marius, 01.08.2026.
|
||||
- **Efort:** M. **Depinde de:** decizie separata daca merita rematerializarea cursoarelor.
|
||||
|
||||
## P2 — Clarificare cu ANAF: marginea perioadelor scpTVA/splittva/inactiv
|
||||
- **Ce:** cache-ul ANAF (`ISTORIC_CODURI_FISCALE`) foloseste conventie inclusiva la sfarsitul
|
||||
intervalelor `SCPTVA`/`SPLITTVA`/`INACTIV` (spre deosebire de `TVAINCASARE`, aliniat 01.08.2026
|
||||
la conventia exclusiva a RTVAI). Nu exista ground truth local (registru echivalent
|
||||
`rtvai_istoric`) pentru aceste trei campuri.
|
||||
- **De ce:** risc de verdicte gresite cu o zi pe declaratii D394/D406 la marginea perioadelor,
|
||||
acelasi tipar de defect confirmat pe `tvaincasare` (vezi `docs\handoff_cache_anaf.md`,
|
||||
sectiunea A-ter).
|
||||
- **Efort:** S (o intrebare catre ANAF) -> M (aplicarea raspunsului in cod, daca schimba
|
||||
conventia). **Depinde de:** raspunsul ANAF.
|
||||
|
||||
## P3 — Test UI pe gridul de verificare parteneri (coloana de provenienta cache)
|
||||
- **Ce:** confirmare vizuala (paint real, nu doar `EVALUATE` pe `ControlSource`) ca noua coloana
|
||||
de provenienta (`sursa`/`data_sursa`, S8) se afiseaza corect in gridul de verificare.
|
||||
- **De ce nu acum:** cere write-back `.vc2` pe `overificari.vc2`, deci dupa aprobarea lui Marius
|
||||
pe diff.
|
||||
- **Efort:** S. **Depinde de:** aprobarea write-back-ului `.vc2` al transei cache ANAF.
|
||||
|
||||
## Curatenie mediu — randuri orfane in tabela `versiune` (MARIUSM_AUTO)
|
||||
- **Ce:** doua randuri `co_2026_07_30_01_COMUN_ISTORIC_CF.sql` in `MARIUSM_AUTO.versiune`, din
|
||||
testarea manuala a lui S1 dinainte de redenumirea in `ff_`.
|
||||
- **De ce nu acum:** fara efect (motorul `PACK_UPDATE` dispecerizeaza dupa numele fisierului de pe
|
||||
disc, nu dupa stringul din `versiune`) — curatenie de mediu de test, nu de productie.
|
||||
- **Efort:** S. **Depinde de:** nimic, se poate face oricand.
|
||||
|
||||
@@ -1,12 +1,110 @@
|
||||
<!--
|
||||
04/08/2026
|
||||
ROACONT - 2.11.71
|
||||
|
||||
:modificare:
|
||||
Verificare cod fiscal. Starea partenerului arata acum si "TVA la incasare", cu perioada in detalii (F4).
|
||||
|
||||
:modificare:
|
||||
Modificare nota. Lista de explicatii TVA se filtreaza dupa cota TVA a liniei curente.
|
||||
|
||||
:modificare:
|
||||
Borderou eFactura si import eFactura. Bifele de cautare arata in eticheta numarul de documente, inca de la deschiderea ferestrei.
|
||||
|
||||
:modificare:
|
||||
Istoric coduri fiscale. S-au ascuns coloanele nefolosite si s-au adaugat datele venite de la ANAF (TVA la incasare, split TVA, inactiv si perioadele aferente).
|
||||
|
||||
:eroare:
|
||||
Istoric coduri fiscale. Verificarea repetata a aceluiasi cod fiscal nu mai adauga inregistrari inutile in istoric.
|
||||
-->
|
||||
<!--
|
||||
02/08/2026
|
||||
ROACONT - 2.11.70
|
||||
|
||||
:modificare:
|
||||
Verificarea in masa a codurilor fiscale este mai rapida. Cache-ul se citeste pe transe, deci nu mai apare eroare la un numar mare de coduri.
|
||||
|
||||
:eroare:
|
||||
La ANAF se trimit doar codurile fiscale valide. Codurile care nu sunt CUI valid nu mai sunt trimise la fiecare rulare.
|
||||
|
||||
:eroare:
|
||||
Verificarea putea lua din cache un verdict mai vechi. Acum se ia intotdeauna ultima verificare, dupa data ei.
|
||||
|
||||
:nou:
|
||||
Note contabile. La completarea partenerului pentru conturile de parteneri se face si verificarea ANAF, ca la introducerea documentelor.
|
||||
-->
|
||||
<!--
|
||||
01/08/2026
|
||||
ROACONT - 2.11.69
|
||||
|
||||
:nou:
|
||||
S-a introdus un cache pentru verificarea partenerilor la ANAF. Verificarea se face pe serverul ANAF, iar daca acesta nu raspunde se ia din cache-ul din baza de date. Cache-ul are valabilitate de 30 de zile. Verificarea in masa (D406, D394, registre) e mult mai rapida.
|
||||
|
||||
:modificare:
|
||||
Se vede provenienta fiecarui verdict: "ANAF" sau "CACHE <data>". La verificarea in masa, in coloana "Provenienta"; la alegerea partenerului, in fereastra cu datele partenerului.
|
||||
|
||||
:eroare:
|
||||
Verificare TVA la incasare la o data din trecut. Ultima zi a unei perioade deja incheiate era raportata gresit ca activa.
|
||||
-->
|
||||
|
||||
<!--
|
||||
30/07/2026
|
||||
ROACONT - 2.11.68
|
||||
|
||||
:modificare:
|
||||
D406. Se asteapta 2 secunde suplimentare fisierul de erori generat de DUKIntegrator pentru ca fisierul sa fie complet.
|
||||
|
||||
:eroare:
|
||||
S-a corectat o eroare la verificare coduri fiscale daca nu exista internet.
|
||||
-->
|
||||
|
||||
<!--
|
||||
28/07/2026
|
||||
ROACONT - 2.11.67
|
||||
|
||||
:modificare:
|
||||
Borderou eFactura, Import eFactura. Deschiderea listelor de facturi este mult mai rapida.
|
||||
|
||||
Borderou eFactura. Imbunatatiri la potrivirea documentelor cu Registrul de TVA dupa numar document sau suma.
|
||||
Numarul documentului se potriveste si cand a fost introdus in contabilitate fara separatori (eFactura "40-33-129052" introdusa ca 4033129052). Doua facturi cu aceeasi valoare, acelasi partener si aceeasi zi nu mai apar cu valoare dubla fata de Registrul de TVA.
|
||||
|
||||
Facturile colorate "turcoaz" = eFactura exista in Registrul de TVA, dar valoarea difera cu peste 0,15 lei (sau diferenta nu se poate calcula - ex: eFactura in valuta)
|
||||
Facturile colorate "gri" = eFactura nu se regaseste in Registrul de TVA (nu s-a introdus in contabilitate sau nu s-a potrivit numarul si nici suma)
|
||||
-->
|
||||
|
||||
<!--
|
||||
28/07/2026
|
||||
ROACONT - 2.11.66
|
||||
|
||||
:modificare:
|
||||
Borderou eFactura, facturi primite. Facturile cu taxare inversa nu mai apar colorate ca avand diferenta fata de Registrul Cumparari. In eFactura taxarea inversa are TVA zero, dar in contabilitate se inregistreaza 4426 = 4427, iar diferenta afisata tine cont acum de acest TVA.
|
||||
|
||||
:nou:
|
||||
Note contabile Exigibilizare TVA. La salvarea notei se avertizeaza daca nu s-a adaugat nota de TVA exigibilizat pentru incasarile/platile aferente facturilor cu TVA la incasare.
|
||||
|
||||
:modificare:
|
||||
Registre TVA. Corectare filtru "Diferenta sold" si lista TVA-ului exigibilizat din plati iau in calcul si facturile cu TVA neexigibil 24% sau 20%.
|
||||
|
||||
:nou:
|
||||
D406 SAF-T. La validarea cu erori se deschide si un fisier de erori pe intelesul utilizatorului: pentru fiecare eroare - pagina, pozitia, partenerul sau contul in cauza si cum se rezolva. Erorile fictive "Cod taxa nu se afla in lista" (bug al validatorului ANAF) sunt separate la sfarsit si se pot ignora.
|
||||
|
||||
:modificare:
|
||||
Alegere partener. Starea de TVA de la ANAF arata si perioada de cand este valabila.
|
||||
Alegere partener. La CNP/CUI invalid se afiseaza "Persoana fizica - CNP corect", respectiv "Cod fiscal invalid - nu s-a interogat ANAF".
|
||||
Corectare salvare optiune verificare ANAF la alegere partener "Initializari > Optiuni utilizator > "Verificare ANAF la alegerea partenerului".
|
||||
-->
|
||||
|
||||
<!--
|
||||
27/07/2026
|
||||
ROACONT - 2.11.65
|
||||
|
||||
:nou:
|
||||
Alegere partener. Pe randul curent din lista se afiseaza starea partenerului la ANAF, la data documentului: platitor sau neplatitor de TVA, inactiv la ANAF, cod fiscal invalid. Discordantele fata de nomenclator apar cu rosu.
|
||||
Alegere partener. Pe randul curent din lista se afiseaza starea partenerului la ANAF, la data documentului: platitor sau neplatitor de TVA, inactiv la ANAF, cod fiscal invalid sau inexistent la ANAF. Discordantele fata de nomenclator apar cu rosu.
|
||||
|
||||
Tasta F4 (sau click pe mesajul de stare) deschide detaliile verificarii ANAF si se poate inlocui partenerul ales cu varianta corecta.
|
||||
|
||||
Daca serviciul ANAF nu raspunde, mesajul arata ca verificarea a fost sarita si se reia dupa cateva minute, fara sa blocheze lucrul.
|
||||
|
||||
:nou:
|
||||
Optiune per utilizator pentru afisarea starii ANAF in cautarea de partener si pentru confirmarea la alegerea unui partener cu discordanta (implicit se afiseaza doar starea, fara confirmare). Se schimba din Initializari > Optiuni utilizator > "Verificare ANAF la alegerea partenerului".
|
||||
|
||||
|
||||
@@ -1,793 +0,0 @@
|
||||
<!-- /autoplan restore point: /c/Users/mmari/.gstack/projects/ROACONT/claude-partener-anaf-autoplan-restore-20260726-165226.md -->
|
||||
# Design: Asistenta alegere partener corect la introducere (verificare ANAF automata)
|
||||
|
||||
Generat de /office-hours pe 24.07.2026
|
||||
Branch: main (implementarea va merge pe claude/<subiect>)
|
||||
Repo: romfast/roacont (mirror git al SVN ^/ROACONT/Trunk)
|
||||
Status: APPROVED (24.07.2026, D7)
|
||||
Mode: Startup (intraprenoriat — produs intern ROA)
|
||||
|
||||
## Problema
|
||||
|
||||
La introducerea facturilor de achizitie/vanzare (si la incasari/plati) utilizatorul
|
||||
alege partenerul dintr-un dialog de cautare. Cand un partener isi schimba calitatea
|
||||
de platitor TVA, conventia ROA cere ALT partener (alt `nom_parteneri.id_par`) cu
|
||||
acelasi nume si cod fiscal cu/fara RO; cel vechi se marcheaza de regula INACTIV.
|
||||
Probleme concrete:
|
||||
|
||||
1. Utilizatorul nu are nicio informatie, la selectie, despre situatia ANAF curenta
|
||||
a partenerului (platitor TVA sau nu, activ/radiat) — statutul se poate schimba
|
||||
oricand, chiar daca partenerul nu are inca o "pereche".
|
||||
2. Perechea inactiva e complet invizibila (filtru hardcodat `STERS=0 AND INACTIV=0`),
|
||||
deci la o noua schimbare de calitate utilizatorul creeaza al TREILEA duplicat in
|
||||
loc sa reactiveze partenerul vechi.
|
||||
3. Alegerea gresita din pereche rupe imperecherea plati/incasari cu facturi
|
||||
(aceeasi cheie `id_part`), producand solduri fantoma pe doi parteneri.
|
||||
4. Importurile (eFactura, extrase) compara codul fiscal doar cu UPPER+ALLTRIM,
|
||||
deci `RO12345` si `12345` sunt terti diferiti — fabrica de duplicate noi.
|
||||
|
||||
## Evidenta cererii
|
||||
|
||||
- Situatie recurenta la clientii ROACONT: parteneri care comuta calitatea de
|
||||
platitor TVA de mai multe ori; utilizatori care aleg din greseala membrul gresit
|
||||
al perechii; corectii manuale costisitoare la imperecherea plati-facturi.
|
||||
- Butonul de verificare ANAF exista deja in nomenclator si e folosit — dar e in alt
|
||||
flux decat introducerea, unde se ia de fapt decizia.
|
||||
|
||||
## Status quo (fluxul actual, mapat in cod)
|
||||
|
||||
- Nucleu selectie: `CautPartenerContabilitate()` — `COMUN\programe\ocautare.prg:56`
|
||||
(SELECT `ID_PART, DENUMIRE, COD_FISCAL` din `NOM_PARTENERI`, filtru inactivi
|
||||
`:117-121`), varianta casa/banca `caut_parteneri()` `:161` (param `tlInactiv`
|
||||
`:175-177`), selectie multipla `caut_parteneri_xml()` `:199`.
|
||||
- Dialog: `cauta_alfa_form(_plus)` — `COMUN\clase\cauta_alfa_forms.vc2` (do_cauta,
|
||||
do_alege, do_adauga/buton Nou).
|
||||
- Puncte de apel: note contabile/facturi (`Clase\ointroduceri_cont.vc2`,
|
||||
`verific_partener` :1542/:4769 → `do_cauta_partener` :921/:3848), casa/banca
|
||||
(`COMUN\clase\ocasabanca.vc2:1788,1823`), stornare
|
||||
(`Ferestre\frm_stornare_plinc.sc2:368`), importuri
|
||||
(`frm_import_extrase_banca.sc2`, `frm_import_note_a4200.sc2`,
|
||||
`oproceduri_import.prg:364/:746`).
|
||||
- Verificare ANAF existenta: clasa `VerificareANAF` cu
|
||||
`ANAF_SincronWebService_PlatitorTva` — `COMUN\programe\validare.prg:1552,1603`
|
||||
(endpoint v9 `PlatitorTvaRest`, loturi max 100 CUI, pauza 1s; intoarce `scpTVA`,
|
||||
`statusInactivi`, `statusTvaIncasare`, denumire/adresa); buton `but_verifica`
|
||||
(`COMUN\clase\cmd_butoane.vc2:427`) doar pe nomenclator/formular verificare.
|
||||
- Statutul TVA NU e stocat pe partener: se deduce din prefixul `RO` al
|
||||
`COD_FISCAL` (ex. `saft_d406.prg:1066`). Rezultatele verificarii merg doar in
|
||||
istoric (`pack_parteneri.save_istoric_cod_fiscal`, `validare.prg:757`).
|
||||
|
||||
## Utilizator tinta si pana cea mai ingusta
|
||||
|
||||
Operatorul de contabilitate care introduce zilnic facturi si incasari/plati.
|
||||
Pana cea mai ingusta: in momentul alegerii partenerului, sa i se spuna automat
|
||||
"ANAF zice altceva decat codul fiscal al partenerului ales" si sa i se ofere
|
||||
perechea corecta (inclusiv cea inactiva) sau crearea unui partener nou.
|
||||
|
||||
## Constrangeri
|
||||
|
||||
- 80/20: modificari minime cu efect maxim; fara refactorizari; fara schimbare de
|
||||
schema Oracle (fara coloana "platitor TVA" pe `nom_parteneri`).
|
||||
- VFP9 legacy, fara teste automate; comentarii in cod max o linie `*!*`.
|
||||
- Conventia ROA ramane: partener nou la schimbare de calitate TVA; regula se
|
||||
documenteaza (nu era scrisa nicaieri pana la acest document).
|
||||
- Fara commit (git/SVN) fara review pe diff in `docs/`.
|
||||
|
||||
## Premise agreate
|
||||
|
||||
1. Modelul de date ramane neschimbat; statutul TVA se deduce din prefixul RO.
|
||||
2. (revizuita) Durerea are DOUA surse: lipsa de vizibilitate la selectie SI
|
||||
duplicatele nascute la import din compararea nenormalizata a codului fiscal.
|
||||
3. Punctul de interventie cu efect maxim e nucleul de selectie din `ocautare.prg`
|
||||
(+ dialogul `cauta_alfa_form`), mostenit de toate punctele de apel.
|
||||
4. (decizie utilizator, D5) Verificarea ANAF se face AUTOMAT la fiecare alegere de
|
||||
partener, nu doar cand exista pereche — statutul se poate schimba intre timp.
|
||||
|
||||
## Perspectiva cross-model (subagent independent)
|
||||
|
||||
- Steelman: dialogul de selectie devine "ghid de decizie" — o singura interventie
|
||||
in nucleu, mostenita de toate formularele, fara schimbare de model de date.
|
||||
- Insight-cheie: criteriul de "partener corect" nu e doar ANAF, ci SI "pe ce
|
||||
id_part sunt documentele existente" → fereastra de decizie afiseaza data
|
||||
ultimului document per membru al perechii.
|
||||
- Premisa contestata (acceptata): duplicatele se nasc si la import → fixul de
|
||||
potrivire normalizata intra in pachet.
|
||||
- Idee laterala retinuta ca transa viitoare: raport pasiv de discordante
|
||||
"prefix RO vs ultimul istoric ANAF" peste datele deja colectate.
|
||||
|
||||
## Abordari considerate
|
||||
|
||||
### A: Doar buton manual "Verificare ANAF" in dialogul de selectie
|
||||
Refolosire `but_verifica`; zero latenta automata. Respinsa ca insuficienta:
|
||||
protectia depinde de disciplina utilizatorului.
|
||||
|
||||
### B (ALEASA): Verificare ANAF automata la alegere + fereastra de decizie + fix import
|
||||
Detalii mai jos. Completeness 9/10 pe durerea descrisa.
|
||||
|
||||
### C: B + raport pasiv discordante ANAF din istoric
|
||||
Amanata ca transa separata (depinde de cat de des ruleaza clientii verificarea in
|
||||
lot; decuplata de hot path — se poate adauga oricand).
|
||||
|
||||
## Abordarea recomandata (aprobata: B)
|
||||
|
||||
Interventie intr-un singur punct comun + doua completari mici:
|
||||
|
||||
1. **Functie noua** `VerificaPartenerLaSelectie(toPartener)` in
|
||||
`COMUN\programe\ocautare.prg`, apelata din `CautPartenerContabilitate()`
|
||||
**inainte de blocul `ADAUGA_CORESP_TIP_PART` (`ocautare.prg:148-150`)** — daca
|
||||
utilizatorul comuta pe pereche, corespondentele tip-partener se adauga pe
|
||||
id_part-ul FINAL, nu pe cel initial. Acopera note/facturi, stornare, importuri
|
||||
fara sa atinga cele ~10 puncte de apel.
|
||||
- **Contract**: functia primeste si poate REESCRIE obiectul de retur
|
||||
(`id_part`, `nume/denumire`, `cod_fiscal`, `tip`); daca `loCauta` e NULL/gol
|
||||
(utilizatorul a renuntat la cautare), verificarea se sare complet.
|
||||
- **Politica de activare (decizie eng review D1, apelanti triati in cod)**:
|
||||
hibrid explicit. `CautPartenerContabilitate`: hook ON implicit (apelantii
|
||||
sunt fluxuri de introducere), cu opt-out DOAR la `orap_terti.prg:1019`
|
||||
(raport). `caut_parteneri`: hook OFF implicit, activat EXPLICIT (parametru
|
||||
nou `tlVerificaANAF`) la cele 4 puncte de introducere: `ocasabanca.vc2`
|
||||
(:1823), `frm_import_extrase_banca.sc2` (:2211, :2616),
|
||||
`ointroduceri_cont.vc2` (:9665, :9704). Fluxurile de consultare (fisa
|
||||
cont `fisa_cont_noua.sc2:459`, `orap_trezorerie.prg:31/:229`,
|
||||
`orap_terti.prg:826/:1794/:1986`) raman NEATINSE, fara nicio modificare.
|
||||
- Apel ANAF pentru CUI-ul partenerului ales: **wrapper nou single-CUI** peste
|
||||
`VerificareANAF` (functia de lot `ANAF_SincronWebService_PlatitorTva` e
|
||||
construita pentru loturi de 100 cu logging intens — nu se cheama direct in
|
||||
hot path); timeout-ul se seteaza pe obiectul WinHTTP cu `SetTimeouts`.
|
||||
- **Cache pe sesiune** — proprietate pe un obiect global existent (ex.
|
||||
`goApp`) sau colectie publica declarata in `roacont.prg`, cheie = CUI
|
||||
normalizat (fara RO), valoare = rezultat+timestamp; se goleste la
|
||||
schimbarea firmei. Un CUI verificat o data pe sesiune nu mai genereaza
|
||||
apel — limiteaza si presiunea pe serviciul ANAF (mai multi operatori
|
||||
simultan raman fiecare cu 1 apel/CUI/sesiune).
|
||||
- **Degradare tacuta**: fara internet / ANAF cazut / timeout ⇒ comportament
|
||||
identic cu azi (fara mesaje de eroare in hot path).
|
||||
- **Guard obligatoriu de mediu partajat**: `ocautare.prg` e inclus si de alte
|
||||
produse ROA — hook-ul verifica intai existenta clasei
|
||||
(`TYPE("goApp")`/`ALINES`+`SET("PROCEDURE")` sau `try CREATEOBJECT` cu
|
||||
fallback) si degradeaza tacut daca `validare.prg`/`VerificareANAF` nu sunt
|
||||
incarcate in acel produs. Fara guard, orice selectie de partener din
|
||||
produsele-frate ar crapa la runtime.
|
||||
- **Excluderi**: persoane fizice (TIP_PERSOANA=2 / CNP 13 cifre), coduri
|
||||
nenumerice dupa eliminarea RO, parteneri externi (COD_TARA<>RO).
|
||||
2. **La discordanta** (ANAF `scpTVA` ≠ prefixul RO al partenerului ales, sau
|
||||
`statusInactivi` = inactiv/radiat) — fereastra compacta de decizie
|
||||
(**forma noua mica in `COMUN\ferestre\`**, pe stilul dialogurilor existente;
|
||||
nu AMESSAGEBOX — are grid cu membrii perechii si 3-4 butoane):
|
||||
- Cauta perechea dupa CUI normalizat (fara RO), **INCLUSIV INACTIV=1**
|
||||
(interogare Oracle ieftina; filtrul gridului principal NU se schimba).
|
||||
- Afiseaza toti membrii: ID, denumire, cod fiscal, activ/inactiv,
|
||||
**data ultimului document** per `id_part` (MAX peste jurnal cumparari,
|
||||
jurnal vanzari si casa/banca — lista exacta a tabelelor se confirma la
|
||||
implementare; atentie la lipsa indexului pe `id_part` pe baze mari — se
|
||||
ruleaza DOAR in fereastra de discordanta, nu in hot path).
|
||||
- Actiuni: (a) alege perechea concordanta cu ANAF; (b) **swap ghidat** cu
|
||||
confirmare: reactiveaza perechea + inactiveaza partenerul curent (evita al
|
||||
treilea duplicat); dupa swap se face **refresh pe cursorul de selectie**
|
||||
(cel vechi dispare, cel reactivat apare); (c) fara pereche: propune buton
|
||||
"Nou" cu CUI-ul corect precompletat; (d) continua oricum (utilizatorul
|
||||
decide, nimic blocant).
|
||||
- **Guvernarea swap-ului (decizie CEO review D2)**: swap-ul se executa prin
|
||||
calea EXISTENTA de modificare nomenclator (`nom_parteneri_modifica` /
|
||||
pachetul Oracle aferent), NU prin UPDATE ad-hoc in ocautare.prg — o
|
||||
singura cale de scriere in nom_parteneri. Gating cu dreptul EXISTENT de
|
||||
modificare nomenclator parteneri (`verifica_drepturi`): fara drept,
|
||||
butonul de swap e dezactivat cu tooltip explicativ, dar perechea poate fi
|
||||
in continuare ALEASA.
|
||||
- **Kill-switch (decizie CEO review D4)**: optiune noua in `settings.ini`,
|
||||
sectiunea `[anaf]`, `verificare_selectie=1` implicit (citita cu `getini`).
|
||||
Cu 0, verificarea automata la selectie e oprita complet (comportament
|
||||
identic cu azi) — rollback chirurgical per statie/client fara downgrade
|
||||
de exe.
|
||||
- Concordanta ⇒ nicio fereastra, flux identic cu azi.
|
||||
3. **Fix import** (`Programe\oproceduri_import.prg`, potrivirea
|
||||
`GetPartenerByCodFiscal` :449 / dedup :4479-4495, citare verificata): cand
|
||||
potrivirea exacta esueaza, se incearca potrivirea pe CUI normalizat (fara
|
||||
RO); la gasire NU se alege automat — se cere confirmare ("exista partener cu
|
||||
acelasi CUI fara/cu RO — folosesti acela sau creezi unul nou?").
|
||||
**Pe loturi** (zip eFactura): confirmarile NU se pun una cate una in mijlocul
|
||||
importului — discordantele se colecteaza si se prezinta o singura data, la
|
||||
final, intr-o lista cu optiune per rand + "aplica la toate". Opreste fabrica
|
||||
de duplicate fara sa blocheze importul.
|
||||
4. **Optional** (redundant partial cu verificarea automata — se taie daca
|
||||
diff-ul creste): buton `but_verifica` si in `cauta_alfa_form`, pentru
|
||||
verificare manuala INAINTE de alegere.
|
||||
|
||||
### Ce NU facem (explicit)
|
||||
- Nu adaugam coloana TVA / data verificare pe `nom_parteneri`.
|
||||
- Nu facem merge/reasignare de documente intre id_part-uri.
|
||||
- Nu schimbam filtrul `STERS=0 AND INACTIV=0` al gridului de selectie.
|
||||
- Nu blocam alegerea: toate avertismentele sunt informative, cu "continua oricum".
|
||||
|
||||
## Intrebari deschise
|
||||
|
||||
1. ~~Drepturile swap~~ — REZOLVAT (CEO review D2): dreptul existent de
|
||||
modificare nomenclator parteneri; executie prin calea existenta de
|
||||
modificare, nu UPDATE ad-hoc.
|
||||
2. TTL cache: pe sesiune (propus) sau pe zi (persistat)? Propunerea: sesiune.
|
||||
3. `caut_parteneri_xml` (selectie multipla) intra in scope sau ramane pe fluxul
|
||||
vechi? Propunerea: ramane pe fluxul vechi (volum mare de CUI-uri per apel).
|
||||
4. Latenta reala ANAF in orele de varf — de masurat inainte de a decide timeout-ul.
|
||||
5. ~~Sursa `tip` la comutare~~ — REZOLVAT (eng review D2): la comutarea pe
|
||||
pereche, `tip` se recalculeaza pentru id-ul perechii cu acelasi criteriu ca
|
||||
in SELECT-ul gridului (apartenenta la `coresp_tip_part` pentru tipurile
|
||||
contului); hook-ul fiind inainte de blocul `ocautare.prg:148-150`, blocul
|
||||
existent adauga natural corespondenta lipsa pe id-ul FINAL. Nota de
|
||||
implementare: wrapper-ul single-CUI sta in `validare.prg`, langa clasa
|
||||
`VerificareANAF` (coeziune).
|
||||
|
||||
## Criterii de succes
|
||||
|
||||
- La alegerea unui partener discordant cu ANAF, utilizatorul vede fereastra de
|
||||
decizie intr-un timp acceptabil (tinta orientativa <3s; pragul final se
|
||||
fixeaza dupa masuratorile de latenta din Tema) si poate ajunge la perechea
|
||||
inactiva fara sa iasa din fluxul de introducere.
|
||||
- Zero regresie de viteza cand ANAF nu raspunde (degradare tacuta).
|
||||
- Importul eFactura nu mai creeaza partener nou fara confirmare cand exista
|
||||
pereche pe CUI normalizat.
|
||||
- Niciun duplicat nou "al treilea" la clientii-pilot dupa o luna de folosire.
|
||||
|
||||
## Plan de distributie
|
||||
|
||||
Livrare in `roacont.exe` prin fluxul existent: build din VFP IDE (`roacont.PJX`),
|
||||
revizie in `pj2`, intrare in `changelog_roacont.txt` (tag `:nou:`), commit SVN de
|
||||
catre Marius dupa aprobarea diff-ului. Nu necesita migrare Oracle (fara DDL).
|
||||
|
||||
## Dependinte
|
||||
|
||||
- Serviciul ANAF `PlatitorTvaRest v9` (deja folosit in verificarea din nomenclator).
|
||||
- `COMUN\programe\validare.prg` si `ocautare.prg` sunt partajate cu alte produse
|
||||
ROA care le includ — de verificat la implementare cine mai apeleaza
|
||||
`caut_parteneri`/`CautPartenerContabilitate` din alte produse (blast radius
|
||||
COMUN vs COMUNROA).
|
||||
|
||||
## Anexa: harta erorilor, edge-case-uri si teste (CEO review D3)
|
||||
|
||||
### Harta erorilor (regula-cheie: verificarea esueaza TACUT, swap-ul esueaza ZGOMOTOS)
|
||||
|
||||
| Cale | Ce poate merge prost | Actiune | Utilizatorul vede |
|
||||
|---|---|---|---|
|
||||
| Apel ANAF (wrapper) | timeout / DNS / HTTP 5xx / 429 | degradare tacuta + UN log pe sesiune (nu per apel) | nimic (flux ca azi) |
|
||||
| Raspuns ANAF | JSON malformat / CUI negasit / refuz | tratat ca "fara informatie" → degradare tacuta | nimic |
|
||||
| Query pereche Oracle | eroare goExecutor | degradare tacuta + log | nimic |
|
||||
| MAX(data doc) per id_part | lent / eroare | fereastra se deschide FARA coloana "ultim doc" | fereastra fara acea coloana |
|
||||
| Swap (via nom_parteneri_modifica) | eroare Oracle / lock / drept lipsa | mesaj de EROARE vizibil; partenerul ramane neschimbat | AMESSAGEBOX cu cauza |
|
||||
| Anulare fereastra (ESC/inchidere) | — | selectia ORIGINALA ramane valabila | revine in formular cu partenerul ales initial |
|
||||
| Dublu-click / reintrare | apel dublu in curs | guard de reintrare (flag "verificare in curs") | un singur apel, o singura fereastra |
|
||||
|
||||
### Ordinea operatiilor (performanta)
|
||||
1. Alege partener → 2. cache lookup CUI → 3. apel ANAF (doar daca nu e in
|
||||
cache) → 4. concordant ⇒ STOP (zero query suplimentar pe selectiile normale)
|
||||
→ 5. DOAR la discordanta: query pereche pe CUI normalizat (inclusiv inactivi)
|
||||
+ MAX(data doc) per membru → 6. fereastra de decizie.
|
||||
|
||||
### Reguli de implementare
|
||||
- **`NormalizeazaCUI()`** — functie UNICA in COMUN (strip RO doar daca restul
|
||||
e numeric, UPPER, fara spatii), folosita de wrapper, de query-ul de pereche
|
||||
si de fixul de import. Fara logica duplicata in 3 locuri.
|
||||
- **Indicator vizual**: wait cursor + text scurt "Verificare ANAF..." pe durata
|
||||
apelului (hot path-ul devine perceptibil doar cand chiar se apeleaza ANAF).
|
||||
- **Logging**: fiecare discordanta gasita se logheaza in `goLog` (CUI, id_part
|
||||
ales, ce a zis ANAF, ce a decis utilizatorul) — diagnosticabil ulterior.
|
||||
- **Kill-switch**: `settings.ini [anaf] verificare_selectie=0` dezactiveaza
|
||||
complet hook-ul (verificat la intrare in functie, inainte de orice).
|
||||
|
||||
### Lista de teste (manual / harness headless — test_init_env_auto)
|
||||
1. Partener concordant (RO + ANAF platitor) → niciun mesaj, flux identic.
|
||||
2. Discordant cu pereche ACTIVA → fereastra, alegerea perechii scrie id-ul corect.
|
||||
3. Discordant cu pereche INACTIVA → fereastra o arata; swap reactiveaza/inactiveaza
|
||||
+ refresh cursor; fara drept de nomenclator → buton dezactivat, alegerea merge.
|
||||
4. Discordant FARA pereche → propunere "Nou" cu CUI precompletat.
|
||||
5. Fara internet / ANAF cazut → zero mesaje, flux identic cu azi, un log.
|
||||
6. Persoana fizica (CNP) / partener extern (COD_TARA<>RO) / CUI gol → skip total.
|
||||
7. Import lot eFactura cu discordante → confirmarile apar O DATA la final,
|
||||
"aplica la toate" functioneaza, niciun partener creat fara confirmare.
|
||||
8. Dublu-click rapid pe rand → un singur apel ANAF, o singura fereastra.
|
||||
9. Kill-switch 0 → comportament identic cu versiunea anterioara.
|
||||
10. Cache: al doilea document pe acelasi partener in aceeasi sesiune → zero
|
||||
apel ANAF nou.
|
||||
11. REGRESIE (eng review D1): fisa de cont si rapoartele terti/trezorerie NU
|
||||
declanseaza verificarea ANAF — comportament identic cu versiunea anterioara.
|
||||
|
||||
## Specificatia vizuala a ferestrei de decizie (design review D2-D3)
|
||||
|
||||
```
|
||||
+--- Verificare partener ANAF ------------------------------------+
|
||||
| ANAF: NEPLATITOR TVA (din 01.03.2026). Partenerul ales are |
|
||||
| codul fiscal RO12345678 — nu corespunde. | <- verdictul, PRIMUL
|
||||
+------------------------------------------------------------------+
|
||||
| ID | Denumire | Cod fiscal | Stare | Ultim document |
|
||||
| 1234 | FIRMA SRL | RO12345678 | Activ | 15.06.2026 | <- alegerea initiala
|
||||
|>5678 | FIRMA SRL | 12345678 | INACTIV | 20.02.2026 | <- PERECHEA, preselectata
|
||||
+------------------------------------------------------------------+
|
||||
| [Alege selectat] [Reactiveaza+inactiveaza] [Nou] [Continua] |
|
||||
+------------------------------------------------------------------+
|
||||
```
|
||||
|
||||
- **Ierarhie**: 1) verdictul intr-o propozitie (status ANAF + data + de ce nu
|
||||
corespunde), 2) gridul cu toti membrii, randul CONCORDANT cu ANAF preselectat,
|
||||
3) butoanele. Ton utilitar, fara alarmism — o singura decizie pe ecran.
|
||||
- **Tastatura (decizie D2)**: Enter = alege randul selectat (preselectat:
|
||||
perechea concordanta); sageti = schimba selectia; ESC = pastreaza alegerea
|
||||
originala (inchide fara nicio actiune); swap DOAR pe butonul dedicat, cu
|
||||
confirmare suplimentara — niciodata pe Enter. Hotkey-uri pe butoane (VFP \<).
|
||||
- **Conventii existente refolosite**: randul INACTIV colorat gri
|
||||
RGB(225,225,225) + tooltip — aceeasi conventie pe care utilizatorii o stiu
|
||||
din cauta_alfa_form ("partenerii de alt tip sunt colorati gri",
|
||||
ocautare.prg:136-137); butoane din cmd_butoane.vcx; erori prin AMESSAGEBOX;
|
||||
fereastra pe clasele de baza cont2000 (stil identic cu dialogurile existente).
|
||||
- **Starea "fara pereche"**: fereastra FARA grid — doar verdictul + butoanele
|
||||
[Nou (CUI precompletat)] si [Continua]; Enter = Continua (aici NU exista
|
||||
alternativa corecta de preselectat, deci implicitul ramane conservator).
|
||||
- **Butonul de swap fara drept de nomenclator**: dezactivat (nu ascuns), cu
|
||||
tooltip "Necesita drept de modificare nomenclator parteneri".
|
||||
- **Indicator in dialogul de selectie**: pe durata apelului ANAF — wait cursor
|
||||
+ WAIT WINDOW "Verificare ANAF..." NOWAIT, sters imediat dupa raspuns;
|
||||
vizibil doar cand apelul chiar are loc (cache miss).
|
||||
|
||||
## Regula de lucru documentata (nota ceruta — nu era scrisa nicaieri)
|
||||
|
||||
**Conventie ROA — schimbarea calitatii de platitor TVA a unui partener:**
|
||||
1. NU se modifica codul fiscal al partenerului existent (istoricul documentelor
|
||||
ramane legat de `id_part`-ul vechi si de statutul TVA de la acea data).
|
||||
2. Se foloseste ALT partener cu acelasi nume si codul fiscal cu/fara RO dupa noua
|
||||
calitate. Daca perechea EXISTA deja (chiar inactiva), se REACTIVEAZA aceea —
|
||||
nu se creeaza al treilea duplicat.
|
||||
3. De regula, membrul care nu mai corespunde se marcheaza INACTIV ca sa nu mai
|
||||
apara la introducere. Daca ambii raman activi (situatii tranzitorii),
|
||||
utilizatorul alege dupa situatia ANAF si dupa documentul introdus.
|
||||
4. La incasari/plati se alege ACELASI `id_part` ca pe facturile pe care le
|
||||
stinge — altfel imperecherea plati-facturi se rupe.
|
||||
|
||||
(La implementare, acest text se muta/copiaza si in `COMUN\docs\` daca vrem sa fie
|
||||
vizibil si celorlalte produse ROA.)
|
||||
|
||||
## Tema (assignment)
|
||||
|
||||
Inainte de implementare, ruleaza pe o baza reala de client doua masuratori:
|
||||
1. `SELECT` de numarare: cate grupuri de CUI normalizat (fara RO) au >1 partener
|
||||
si cati dintre ei au membri inactivi — dimensioneaza problema reala.
|
||||
2. 10 apeluri ANAF `PlatitorTvaRest` la ore diferite — masoara latenta reala
|
||||
pentru alegerea timeout-ului.
|
||||
Rezultatele decid timeout-ul si daca fereastra de decizie are nevoie de
|
||||
pre-incarcare asincrona.
|
||||
|
||||
## Ce am observat la felul in care gandesti
|
||||
|
||||
- Ai respins ambele extreme si ai corectat exact pe mecanism: "chiar daca nu
|
||||
exista o pereche, tot trebuie facuta verificarea automata pe ANAF, pentru ca
|
||||
intre timp partenerul isi poate fi schimbat calitatea" — ai vazut ca riscul e
|
||||
in timp, nu in structura datelor.
|
||||
- Ai adus singur cazul-limita care omoara solutiile naive: "partenerul anterior
|
||||
este marcat inactiv... si exista situatii in care isi schimba calitatea de mai
|
||||
multe ori" — perechea invizibila din cauza filtrului INACTIV=0.
|
||||
- "80/20 minim de modificari cu maxim de efecte" — ai cerut explicit constrangerea
|
||||
de cost inainte de solutii, nu dupa.
|
||||
|
||||
## GSTACK REVIEW REPORT
|
||||
|
||||
| Review | Trigger | Why | Runs | Status | Findings |
|
||||
|--------|---------|-----|------|--------|----------|
|
||||
| CEO Review | `/plan-ceo-review` | Scope & strategy | 1 | CLEAR | mode: HOLD_SCOPE, 3 constatari decise (swap guvernat, anexa spec, kill-switch), 0 critical gaps |
|
||||
| Codex Review | `/codex review` | Independent 2nd opinion | 0 | — | sarit (2 verificari independente rulate azi la office-hours) |
|
||||
| Eng Review | `/plan-eng-review` | Architecture & tests (required) | 1 | CLEAR | 2 issues (politica hook hibrid D1, recalc tip D2), 13/13 cai cu test, 0 critical gaps |
|
||||
| Design Review | `/plan-design-review` | UI/UX gaps | 1 | CLEAR | score: 5/10 → 9/10, 3 decizii (focus, Enter=perechea, spec vizuala) |
|
||||
| DX Review | `/plan-devex-review` | Developer experience gaps | 0 | — | n/a (nu e produs developer-facing) |
|
||||
|
||||
- **UNRESOLVED:** 0 — toate deciziile CEO (D1-D6), eng (D1-D2) si design (D1-D3) au raspuns.
|
||||
- **VERDICT:** CEO + ENG + DESIGN CLEARED — planul e complet, gata de implementare pe branch claude/partener-anaf.
|
||||
|
||||
---
|
||||
|
||||
## REVIZIA 2 (25.07.2026) — V2': verdict ANAF in formularul de cautare
|
||||
|
||||
Status: APPROVED (25.07.2026, feedback live Marius + D1a/D2 confirmate).
|
||||
Aceasta revizie INLOCUIESTE sectiunile "fereastra de decizie" si "Specificatia
|
||||
vizuala a ferestrei de decizie" din designul initial. Restul (hook, wrapper
|
||||
single-CUI, NormalizeazaCUI, cache, kill-switch, excluderi, degradare tacuta,
|
||||
fix import, politica de activare pe apelanti) RAMANE VALABIL.
|
||||
|
||||
### Motivatia (test live 25.07, ROMFAST 1879855)
|
||||
|
||||
Fereastra de decizie implementata in rundele 1-8 s-a dovedit confuza in uz real:
|
||||
1. Utilizatorul nu intelege de ce a aparut fereastra; mesajul de sus e insuficient
|
||||
(fara numele partenerului, fara ce inseamna verdictul, fara ce are de facut).
|
||||
2. Gridul arata TOT grupul de CUI, inclusiv membrii cu aceeasi problema — nu ghideaza.
|
||||
3. Butonul Inactiveaza/Activeaza cere o operatiune de nomenclator ambigua (pe care
|
||||
rand? in pereche cu cine?) in mijlocul fluxului de introducere.
|
||||
4. Verificarea ANAF e invizibila cand totul corespunde (WAIT WINDOW NOWAIT dispare
|
||||
la orice miscare de mouse) — utilizatorul nu stie ca protectia exista.
|
||||
5. Butonul "Nou" din fereastra dubleaza butonul Nou al cautarii.
|
||||
|
||||
### Solutia revizuita
|
||||
|
||||
**1. Label ANAF in `cauta_alfa_form` (COMUN\clase\cauta_alfa_forms.vc2)** —
|
||||
verdictul pentru RANDUL CURENT din grid, vizibil INAINTE de alegere:
|
||||
|
||||
```
|
||||
+--- Cautare partener --------------------------------------------+
|
||||
| Cautare: ROMFAST_ [Nou] |
|
||||
| | Denumire | Cod fiscal | ... ||
|
||||
| |>ROMFAST CONSTANTA SRL | 1879855 | ||
|
||||
| ANAF: PLATITOR TVA — codul 1879855 (fara RO) NU corespunde. | <- label
|
||||
+------------------------------------------------------------------+
|
||||
```
|
||||
|
||||
Starile labelului (texte finale, spec Marius 25.07):
|
||||
- gol — persoana fizica / partener extern / CUI nenumeric / kill-switch 0 /
|
||||
eroare-timeout ANAF (degradare tacuta);
|
||||
- "Verificare ANAF..." — pe durata apelului (persistent, nu WAIT WINDOW);
|
||||
- concordant (VERDE): "ANAF: Platitor TVA (RO1879855 FAGA SRL)" — cod fiscal +
|
||||
denumirea ANAF;
|
||||
- discordant (ROSU, bold): "(!) ANAF: Platitor TVA (1879855 ROMFAST CONSTANTA
|
||||
SRL) » detalii" — marcaj (!) si sageata » (chr 187, cp1252) care indica
|
||||
apasarea pentru detalii; cursor mana pe label (clickabil).
|
||||
|
||||
Declansare: `AfterRowColChange` reporneste un timer debounce (~400ms); apelul se
|
||||
face doar daca utilizatorul ramane pe rand (cache per CUI pe sesiune → un singur
|
||||
apel real per partener). Navigarea rapida nu declanseaza nimic.
|
||||
|
||||
Blast radius: label + timer + proprietate de activare intra in clasa comuna, dar
|
||||
INERTE implicit (proprietate .F.); se activeaza doar din cautarile de parteneri
|
||||
cu verificare ANAF (tlVerificaANAF / CautPartenerContabilitate), cu guard-urile
|
||||
existente pentru produsele-frate. Celelalte nomenclatoare nu vad nicio diferenta.
|
||||
|
||||
**2. Dublu-click pe label** → AMESSAGEBOX cu detaliile complete: nume + cod ales,
|
||||
verdict ANAF, codul fiscal corect, perechea existenta (cautata pe CUI normalizat,
|
||||
INCLUSIV inactiva) sau indrumarea catre butonul Nou al cautarii daca nu exista.
|
||||
|
||||
**3. La alegerea unui partener discordant (D1a)** — plasa de siguranta: apare
|
||||
automat dialogul de decizie (formularul de cautare ramane deschis). Format
|
||||
final (spec Marius, 25.07) — lista numerotata + butoane care spun exact ce aleg:
|
||||
|
||||
```
|
||||
1. ROMFAST CONSTANTA SRL (CUI: 1879855, ID: 108) ANAF: PLATITOR TVA
|
||||
2. FAGA SRL (CUI: RO1879855, ID: 200140) inactiv
|
||||
|
||||
[Alege FAGA SRL] [Alege ROMFAST CONSTANTA SRL] [Renunta]
|
||||
```
|
||||
|
||||
- Butonul perechii alege perechea; butonul alesului pastreaza alegerea;
|
||||
Renunta (si ESC) = ramai in cautare. Fara linie de mapare Da/Nu.
|
||||
- Fara pereche: randul 1 + "Nu exista partener cu CUI RO1879855 (il puteti
|
||||
crea cu butonul Nou)." — butoane [Continua] [Renunta].
|
||||
- Mai multi candidati: lista numerotata a candidatilor + "Alegeti manual." —
|
||||
buton unic, ramai in cautare.
|
||||
- Implementare: AMESSAGEBOX nu suporta etichete custom pe butoane — dialogul e
|
||||
o clasa mica `DEFINE CLASS ... AS Form` definita IN COD in ocautare.prg
|
||||
(fara .scx, fara binar), 2-3 butoane cu Caption dinamic (denumiri trunchiate
|
||||
rezonabil). Detaliile de la dublu-click pe label folosesc acelasi format
|
||||
numerotat, pur informativ.
|
||||
|
||||
**FARA activare/reactivare (decizie Marius, 25.07)**: alegerea unei perechi
|
||||
inactive doar FOLOSESTE acel id_part pe document — partenerul ramane inactiv,
|
||||
"inactiv" apare pur informativ. Motivatie: pe incasari/plati utilizatorul vrea
|
||||
partenerul cu facturile/soldul, indiferent de TVA; nu toti utilizatorii au
|
||||
drepturi de modificare nomenclator; orice operatiune de nomenclator in fluxul
|
||||
de introducere incurca. Activarea/inactivarea raman exclusiv operatiuni
|
||||
manuale in nomenclatorul de parteneri.
|
||||
|
||||
**4. Alegere rapida (D2)**: daca utilizatorul alege inainte ca timerul sa fi
|
||||
verificat randul, verificarea se face PE LOC la selectie (alegerile rapide nu
|
||||
ocolesc protectia).
|
||||
|
||||
### Ce se ELIMINA din implementarea rundelor 1-8
|
||||
|
||||
- `COMUN\ferestre\frm_verif_partener_anaf` (.sc2/.scx/.sct) — fereastra dispare.
|
||||
- But_swap / ActualizeazaCaptionSwap / apelul `PACK_PARTENERI.MODIFICA_INACTIV`.
|
||||
- Migrarea `ff_2026_07_24_01_COMUN_PACK_PARTENERI.sql` — NU se mai ruleaza pe
|
||||
productie; `versiune_db.txt` revine la valoarea anterioara. (Procedura ramane
|
||||
aplicata pe schema de test — inofensiva, se poate drop-ui separat.)
|
||||
- Deschiderea ferestrei din hook (`Do Form ... frm_verif_partener_anaf`).
|
||||
|
||||
### Ce se PASTREAZA neschimbat
|
||||
|
||||
`NormalizeazaCUI`, wrapper single-CUI `ANAF_VerificaCuiSingle`, cache-ul pe
|
||||
sesiune + golirea la schimbarea firmei, kill-switch `[anaf] verificare_selectie`,
|
||||
excluderile (PF/extern/nenumeric), degradarea tacuta, fixul de import
|
||||
(oproceduri_import.prg), politica de activare pe apelanti (tlVerificaANAF,
|
||||
opt-out orap_terti), regula de lucru documentata, harta erorilor (mai putin
|
||||
randul de swap — eliminat).
|
||||
|
||||
### Teste afectate
|
||||
|
||||
Suita `COMUN\utile\Teste\partener_anaf\` se rescrie pe noul flux: label (stari,
|
||||
debounce, dublu-click), D1a (cele 3 butoane), D2 (alegere rapida), reactivare
|
||||
single-row, regresie nomenclatoare non-partener (label inert).
|
||||
|
||||
---
|
||||
|
||||
## REVIZIA 3 (25.07.2026) — verdict la data documentului + texte finale
|
||||
|
||||
Status: APPROVED (25.07.2026, feedback live Marius pe screenshot-ul din productie).
|
||||
Aceasta revizie ajusteaza doar textele si adauga data documentului; restul REVIZIEI 2
|
||||
ramane valabil.
|
||||
|
||||
### 1. Textul labelului
|
||||
|
||||
Denumirea si codul fiscal afisate sunt cele de la ANAF (nu cele ale randului ales),
|
||||
in ordinea NUME apoi COD, plus data la care s-a cerut starea:
|
||||
|
||||
- concordant (verde): `ANAF: Platitor TVA (ROMFAST SRL RO1879855) la 15.06.2026`
|
||||
- discordant (rosu, bold): `(!) ANAF: Platitor TVA (ROMFAST SRL RO1879855) la 15.06.2026 >> click detalii`
|
||||
|
||||
Sageata `»` (Chr(187)) se inlocuieste cu `>>` ASCII (fara risc de encoding cp1252),
|
||||
iar textul devine `click detalii`. Marcajul `(!)` se pastreaza la discordanta.
|
||||
|
||||
### 2. Dialogurile (detalii la dublu-click + confirmarea la alegere)
|
||||
|
||||
Format aerisit, cu antet comun (metodele `AntetDialog` / `ListaCorecti` din
|
||||
`anaf_verif_cautare`):
|
||||
|
||||
```
|
||||
ROMFAST CONSTANTA SRL (CUI: 1879855, ID: 108)
|
||||
|
||||
! ANAF: Platitor TVA (ROMFAST SRL, RO1879855) la 15.06.2026
|
||||
|
||||
Parteneri ROA cu CUI RO1879855:
|
||||
1. ABSOLUT SRL (ID: 598) inactiv
|
||||
2. ROMFAST S.R.L. (ID: 614)
|
||||
```
|
||||
|
||||
- lista contine DOAR partenerii cu codul fiscal corect (fara cel deja ales),
|
||||
ordonati alfabetic (`ORDER BY UPPER(DENUMIRE)` in `ANAF_CautaPereche`);
|
||||
- fara candidati: `Nu exista partener cu CUI RO1879855 (il puteti crea cu butonul Nou).`;
|
||||
- la alegere, ultimul rand ramane maparea butoanelor:
|
||||
`Da = alege 1. <denumire> Nu = pastreaza selectia Abandon = inapoi la cautare`.
|
||||
|
||||
### 3. Starea ANAF la data documentului
|
||||
|
||||
Serviciul `PlatitorTvaRest v9` primea deja o data (era `Date()`); acum primeste data
|
||||
documentului, cand exista:
|
||||
|
||||
- `ANAF_VerificaCuiSingle(tcCui, tdData)` si `ANAF_StarePartener(tcCodFiscal, tdData)`;
|
||||
data goala/lipsa => data curenta (comportament identic cu inainte);
|
||||
- cheia de cache pe sesiune devine `CUI + data` (acelasi CUI la doua date = doua apeluri);
|
||||
- transport: cheia de hash `dDataDoc` pentru `CautPartenerContabilitate`, parametrul 7
|
||||
`tdDataDoc` pentru `caut_parteneri`; proprietatea `dDataDoc` pe `anaf_verif_cautare`;
|
||||
- sursele datei in apelanti: `poAct.dataact` (introduceri note/facturi,
|
||||
`ointroduceri_cont.vc2`: `do_cauta_partener` x2, gridurile de partener din
|
||||
`frm_note`/`frm_note2007`, `frm_plati_impozite`) si `poDate.dataact` (facturare,
|
||||
`ofacturare.vc2`: `do_cauta_client`, `do_cauta_furnizor`); toate cu guard `Type(...)='D'`.
|
||||
|
||||
### 4. Casa/banca — verificare scoasa
|
||||
|
||||
Punctul activat in runda 1 (`ocasabanca.vc2`, `Ck_bancasa.InteractiveChange`) NU e
|
||||
introducere de document: e checkbox-ul de filtrare care alege casa/banca proprie
|
||||
(`filtru = ' AND id_bancasa = ...'`), fara data de document. Verificarea ANAF se
|
||||
dezactiveaza acolo (revenire la apelul fara `tlVerificaANAF`).
|
||||
|
||||
### 5. Comentarii in cod
|
||||
|
||||
Regula de lucru confirmata de Marius (25.07): fara comentarii in corpul codului; o
|
||||
singura linie scurta in antetul fisierului, fara autor "claude". Comentariile inline
|
||||
adaugate in rundele 1-11 pentru aceasta functionalitate se elimina.
|
||||
|
||||
### 6. Import din extras de cont — corectie de abordare (decizie Marius, 25.07)
|
||||
|
||||
La importul din extras e vorba de PLATI/INCASARI, nu de facturi: statutul ANAF
|
||||
(platitor/neplatitor) nu ajuta cu nimic acolo. Singurul criteriu care conteaza e
|
||||
"partenerul pe care stau facturile", pentru ca `GetDocumentByContPartenerAct`
|
||||
(`COMUN\programe\oproceduri_comune.prg:6942`) cauta documentul strict pe `id_part`
|
||||
(`ireg_parteneri`, an/luna curente), iar `GetPartenerByCodFiscal` (`:6557`)
|
||||
normalizeaza CUI-ul si ia orbeste `MAX(id_part)` din grup.
|
||||
|
||||
Prin urmare:
|
||||
- verificarea ANAF se scoate din formularul de import extrase (cele doua pickere
|
||||
manuale de partener din configurari);
|
||||
- confirmarea pe loturi pentru discordantele de CUI (adaugata in runda 1) se
|
||||
ELIMINA — importul nu mai intreaba nimic;
|
||||
- cand exista mai multi parteneri cu acelasi CUI normalizat, alegerea se face
|
||||
dupa documente, nu dupa `MAX(id_part)`:
|
||||
1. daca linia de extras are numar de document si optiunea "Asociaza facturi" e
|
||||
bifata, documentul se cauta pe TOTI membrii grupului, iar nota merge pe
|
||||
partenerul pe care s-a gasit factura (se muta si `id_partd`/`id_partc`);
|
||||
2. altfel, se alege membrul cu documente in perioada curenta (`ireg_parteneri`,
|
||||
numar de randuri, la egalitate soldul cel mai mare in modul);
|
||||
3. daca niciun membru nu are documente, ramane alegerea de azi.
|
||||
- la initializare facturi din balanta (`CompleteazaParteneriROA`) confirmarea per
|
||||
partener se elimina: se foloseste tacut partenerul existent cu acelasi CUI
|
||||
normalizat, iar cursorul de parteneri primeste coloana normalizata calculata o
|
||||
singura data (fara `Locate` cu apel de functie per partener).
|
||||
|
||||
---
|
||||
|
||||
## REVIZIA 4 (26.07.2026) — verificare neintruziva la alegerea partenerului
|
||||
|
||||
Status: APROBATA CU MODIFICARI dupa review /autoplan (26.07.2026, 3 lentile:
|
||||
CEO / design / inginerie, Codex indisponibil pe masina). Aceasta revizie
|
||||
inlocuieste punctul 3 al REVIZIEI 2 ("La alegerea unui partener discordant")
|
||||
si punctul 2 al REVIZIEI 3 (maparea butoanelor la alegere).
|
||||
|
||||
Motivatia (Marius, 26.07): formularul de avertizare de la alegerea partenerului
|
||||
e intruziv si confuz, mai ales pe incasari/plati, unde partenerul NU e o alegere
|
||||
libera — e determinat de facturile de imperecheat, iar o propunere de schimbare
|
||||
a partenerului exact in acel punct sparge imperecherea (`GetDocumentByContPartenerAct`
|
||||
cauta documentul strict pe `id_part`).
|
||||
|
||||
### Decizii de poarta (review /autoplan, 26.07)
|
||||
|
||||
| # | Decizie | Continut |
|
||||
|---|---|---|
|
||||
| D1 / UC1 | **Marcajul colorat pe toate randurile NU intra in aceasta transa** | Implicit ramane nivelul 1 (verdict pe randul curent). Ghidarea o preia, in Detalii, semnul "are documente in perioada" pe fiecare candidat. Marcajul in grid devine transa separata, dupa masuratori (vezi "Transa viitoare") |
|
||||
| UC2 | **Polaritate inversata** | `CautPartenerContabilitate` devine OFF implicit + opt-in explicit `lVerificaANAF=>1` pe 8 apeluri. Simetric cu `caut_parteneri` |
|
||||
| UC3 | **Detalii ramane AMESSAGEBOX** | Fara formular nou definit in cod. Optiunea per utilizator se comuta dintr-un punct de meniu, dupa modelul `RC_REGCUMP_LISTARE_BUG` |
|
||||
|
||||
### 1. Ce se scoate din calea de alegere
|
||||
|
||||
`VerificaAlegere` (`ocautare.prg:428`) nu mai deschide nimic pe comportamentul
|
||||
implicit: cand nivelul de confirmare e 0 face `Return .T.` imediat, fara apel
|
||||
sincron la ANAF.
|
||||
|
||||
La nivelul 3 (opt-in) comportamentul ramane exact cel de azi: verificare sincrona
|
||||
+ `Amessagebox(...,3+48)` cu lista numerotata + `aInputBox` pentru varianta.
|
||||
ATENTIE (eroare factuala corectata): clasa `anaf_dialog` **nu exista** — a fost
|
||||
eliminata la runda 11, iar confirmarea de azi e AMESSAGEBOX. Nicio parte a acestei
|
||||
revizii nu se sprijina pe ea.
|
||||
|
||||
Chiar cand nu se afiseaza nimic, alegerea unui partener discordant **se logheaza**
|
||||
in `goLog` (CUI, `id_part` ales, verdict) — e singura sursa de date despre
|
||||
frecventa reala a problemei, si conditia de intrare pentru transa viitoare.
|
||||
|
||||
### 2. Detalii (click pe label) — decizia, la cererea utilizatorului
|
||||
|
||||
Ramane `AMESSAGEBOX`, cu formatul din REVIZIA 3, plus doua schimbari:
|
||||
|
||||
1. **Discriminatorul pe documente** langa fiecare candidat — criteriul care conteaza
|
||||
efectiv la imperechere, nu statutul TVA:
|
||||
```
|
||||
ROMFAST CONSTANTA SRL (CUI: 1879855, ID: 108)
|
||||
|
||||
! ANAF: Platitor TVA (ROMFAST SRL, RO1879855) la 15.06.2026
|
||||
|
||||
Parteneri ROA cu CUI RO1879855:
|
||||
1. ABSOLUT SRL (ID: 598) inactiv
|
||||
2. ROMFAST S.R.L. (ID: 614) are documente in perioada
|
||||
```
|
||||
Sursa: `ireg_parteneri` pe anul/luna curente, un singur SELECT, **doar la
|
||||
deschiderea Detalii** (niciodata in calea de navigare prin grid).
|
||||
2. **Alegerea variantei se face de aici** (butoanele AMESSAGEBOX + `aInputBox`
|
||||
cand sunt mai multi candidati), adica exact mecanismul existent, mutat de pe
|
||||
calea impusa pe calea ceruta de utilizator. Foloseste `poANAFInlocuire` +
|
||||
`AplicaInlocuirePartenerANAF`, cu guardul obligatoriu de la punctul 5 (C2).
|
||||
|
||||
Detalii se deschide si cand `oStare` e `.Null.` (ANAF picat, cod fiscal invalid):
|
||||
afiseaza antetul si o linie explicita ("ANAF nu a raspuns — verificarea a fost
|
||||
sarita"), nu returneaza mut ca azi (`ocautare.prg:411`).
|
||||
|
||||
Labelul devine clickabil pe ambele stari (verde si rosu) si primeste **F4** ca
|
||||
echivalent de tastatura (utilizatorii lucreaza fara mouse); textul labelului spune
|
||||
`F4 = detalii`. Codul de tasta pentru F4 se confirma la implementare — ramura
|
||||
`OTHERWISE` din `cauta_alfa_forms.vc2:715` nu intra in conflict cu redirectarea
|
||||
literelor catre caseta de cautare.
|
||||
|
||||
### 3. Cascada de optiuni — o singura scara
|
||||
|
||||
O singura optiune, `RC_ANAF_VERIF_SELECTIE`, cu valori cumulative:
|
||||
|
||||
| Valoare | Comportament |
|
||||
|---|---|
|
||||
| 0 | oprit (nicio verificare) |
|
||||
| **1** | **verdict pe randul curent (implicit)** |
|
||||
| 2 | rezervat pentru marcajul in grid (transa viitoare) |
|
||||
| 3 | verdict + confirmare la alegerea unui partener discordant (opt-in) |
|
||||
|
||||
Rezolvare, prima valoare gasita castiga:
|
||||
1. `settings.ini [anaf] verificare_selectie` — **doar kill-switch pe valoarea 0**,
|
||||
nu sursa de nivel (altfel bifa/optiunea utilizatorului devine silentios
|
||||
inoperanta si nimeni nu poate explica de ce);
|
||||
2. `citeste_optiune_utilizator('RC_ANAF_VERIF_SELECTIE')` — per utilizator;
|
||||
3. `citeste_optiune('RC_ANAF_VERIF_SELECTIE')` — per firma;
|
||||
4. hardcodat: 1.
|
||||
|
||||
Comutarea per utilizator: punct de meniu, dupa modelul `RC_REGCUMP_LISTARE_BUG`
|
||||
(citeste valoarea, arata starea, scrie noua valoare cu `scrie_optiune_utilizator`).
|
||||
Etichete fara ambiguitate: `Arata starea ANAF in cautarea de partener` /
|
||||
`Intreaba la alegerea unui partener discordant`.
|
||||
|
||||
Seed-ul per firma se amana: cascada cade oricum pe implicitul hardcodat, iar un
|
||||
INSERT in `optiuni` e citit de COMUN in toate produsele — nu e "discoverabilitate",
|
||||
e comutator suite-wide.
|
||||
|
||||
### 4. Politica de activare (inversata, UC2)
|
||||
|
||||
`CautPartenerContabilitate` (`ocautare.prg:507`) devine **OFF implicit**, cu opt-in
|
||||
explicit `lVerificaANAF=>1`. Motivul, verificat: exista ~68 de apelanti, dintre care
|
||||
lista de opt-out acoperea ~20, toti din ROACONT; ar fi ramas ON prin omisiune
|
||||
`COMUN\clase\baza.vc2:10400` (clasa de baza UI, deci toate produsele),
|
||||
`orapoarte_cont.vc2:3843` (filtru de raport), `ofacturare.vc2:20946` ("Alegeti Banca"),
|
||||
`:20957` ("casa in lei"), `:19441` (Agenti), `:7160/:7997/:9257` (Responsabili),
|
||||
`:13793/:17826` (Partener rezervare), plus `oinventar`, `omodificari`,
|
||||
`onomenclatoare`, `ferestre_cere_date`, `ooperatii_comune.prg`. `ROAGEST` si
|
||||
`ROAAUTO` incarca `validare.prg` (`roagest.prg:234`, `roaauto.prg:198`), deci toate
|
||||
guardurile existente trec si la ele.
|
||||
|
||||
**Lista ON (singurele locuri cu `lVerificaANAF=>1`):**
|
||||
- `Clase\ointroduceri_cont.vc2` — `do_cauta_partener` (x2, `:921`, `:3850`);
|
||||
- `Clase\ointroduceri_cont.vc2` — gridurile de partener din `frm_note` (`:7096`, `:7120`)
|
||||
si `frm_note2007` (`:8943`, `:8984`);
|
||||
- `COMUN\clase\ofacturare.vc2` — `do_cauta_client`, `do_cauta_furnizor`.
|
||||
|
||||
Parametrul `lNuVerificaANAF` dispare. Consecinta de curatat: dupa inversare, niciun
|
||||
apelant nu mai trimite `tlVerificaANAF` la `caut_parteneri` — se decide explicit daca
|
||||
parametrii `tlVerificaANAF`/`tdDataDoc` si ramura ANAF din `caut_parteneri`
|
||||
(`ocautare.prg:625`) raman sau se scot ca ei cod mort.
|
||||
|
||||
### 5. Reguli obligatorii de implementare (constatari verificate in cod)
|
||||
|
||||
| # | Regula | Ancoraj |
|
||||
|---|---|---|
|
||||
| C2 | `AplicaInlocuirePartenerANAF` se apeleaza **doar cand `gnButon = 1`**; `poANAFInlocuire` se reseteaza la intrarea in Detalii si pe ramura de abandon. Altfel: utilizatorul alege varianta in Detalii, apoi anuleaza cautarea, iar `Scatter ... Blank` (`cauta_alfa.prg:243`) + guardul slab `Type('toPartener.id_part')='N'` fac ca apelantul sa primeasca totusi partenerul — pe incasari rupe imperecherea | `ocautare.prg:165`, `:609`, `:666` |
|
||||
| C3 | `do_termin` pe formularul de cautare se apeleaza **dupa** ce AMESSAGEBOX-ul a returnat, niciodata din interiorul unui dialog modal copil (`do_termin` face `this.Release`) | `_frm_base.vc2:363-371` |
|
||||
| H2 | Eroarea de SELECT din `ANAF_CautaPereche` nu mai are voie sa apara ca "Nu exista partener cu CUI ... (il puteti crea cu butonul Nou)" — asta indruma activ spre al treilea duplicat. `ListaCorecti` primeste un parametru de eroare; la eroare mesajul devine "Nu s-a putut citi lista de parteneri" si sugestia "Nou" dispare. Cursorul se inchide si pe ramura de eroare | `ocautare.prg:154-157`, `:389-405`, `:423`, `:455` |
|
||||
| H6 | Cascada se citeste **o singura data**, la intrarea in `CautPartenerContabilitate`/`caut_parteneri`, cu `lcSel = Select()` / `Select(m.lcSel)` in jur. Niciodata din `Activeaza`, `VerificaRand` sau dintr-un handler de UI. `citeste_optiune_utilizator` **nu restaureaza** zona de lucru, iar `scrie_optiune_utilizator` da AMESSAGEBOX la eroare si face `TABLEUPDATE` in afara ramurii de succes | `oinit_optiuni.prg:731-740`, `:770-778` |
|
||||
| H7 | Cascada testeaza `!Empty(Alltrim(valoare))` pe fiecare nivel. Patternul existent `Int(Val(Nvl(citeste_optiune_utilizator(...), '0')))` mapeaza absent -> 0 = OPRIT si ar opri verificarea la primul nivel gol | `Clase\ovanzcump.vc2` (pattern), `oinit_optiuni.prg:730`, `:808` |
|
||||
| M9 | Citirea `getini` iese de pe calea per-rand: azi `ANAF_StarePartener` o face la fiecare verificare, cu `FOPEN`/scan/`FCLOSE` pe `DIRGEN\settings.ini`, care e de regula pe share de retea. Kill-switch-ul se citeste odata cu cascada | `ocautare.prg:59`, `ini.prg:288`, `roacont.prg:441` |
|
||||
| M2 | Se foloseste `This.oForm.crs_cursor`, nu `_GRID1.RecordSource`: `SAVE_GRID` goleste `RecordSource` pe toata durata repopularii, care include un round-trip Oracle | `oproceduri_comune.prg:1387`, `ocautare.prg:303`, `:414`, `:443` |
|
||||
| M5 | Valorile de cascada cache-uite pe sesiune se invalideaza la schimbarea firmei sau a utilizatorului (ca si cache-ul ANAF) | — |
|
||||
| A2 | Guard suplimentar `'OINIT_OPTIUNI' $ Upper(Set('Procedure'))` inainte de orice apel la cascada: `ROACASA` incarca `ocautare` fara `oinit_optiuni` | `ocautare.prg:63` (modelul existent) |
|
||||
| B1 | Bug in codul de azi: `VerificaRand` iese pe `Reccount = 0` fara sa goleasca labelul, deci verdictul precedent ramane pe ecran atribuit unei liste goale | `ocautare.prg:304-306` |
|
||||
| B2 | Spec vs implementare: `SeteazaLabel` forteaza `FontBold = .F.`, desi REVIZIA 2/3 cere discordanta in rosu **bold**. Se aliniaza (bold la discordanta) | `ocautare.prg:353` |
|
||||
| B3 | `Anchor` al labelului devine 14 (Left+Bottom+Right) — cu 6 textul se taie la redimensionare; labelul urca deasupra `cmd_select` (invizibil pe fluxul de partener), fara sa mai creasca inaltimea formei | `cauta_alfa_forms.vc2:47`, `:269-279`, `ocautare.prg:245-257` |
|
||||
| B4 | Denumirea ANAF se trunchiaza la ~24 caractere in label (cea completa apare in Detalii): textul discordant la lungime maxima depaseste 2 randuri de Arial 10 in ~487x30px si se taie fara elipsa | `ocautare.prg:367` |
|
||||
| B5 | `SET STEP ON` viu la `validare.prg:1841` (preexistent, nu din aceasta lucrare) — in IDE deschide debuggerul. De scos | `validare.prg:1841` |
|
||||
|
||||
Wrapperul batch ANAF **nu se scrie** in aceasta transa: fara marcaj in grid nu are
|
||||
consumator (YAGNI).
|
||||
|
||||
### 6. Ce se pastreaza neschimbat
|
||||
|
||||
Textele si culorile labelului (REVIZIA 3 pt. 1, cu corectia B2), starea la data
|
||||
documentului (REVIZIA 3 pt. 3), `dDataDoc`/`tdDataDoc`, `NormalizeazaCUI`,
|
||||
`ANAF_VerificaCuiSingle`, cache-ul pe sesiune + golirea la schimbarea firmei,
|
||||
excluderile (PF/extern/nenumeric), degradarea tacuta, `ANAF_CautaPereche`,
|
||||
`AplicaInlocuirePartenerANAF`, fixul de import (REVIZIA 3 pt. 6), regula "fara
|
||||
comentarii in corpul codului" (REVIZIA 3 pt. 5), hook-ul generic din `cauta_alfa.prg`
|
||||
si cele 8 linii din `cauta_alfa_forms.vc2`.
|
||||
|
||||
### 7. Teste (toate fezabile in harnessul headless)
|
||||
|
||||
1. Cascada: ini `0` bate tot; utilizator bate firma; firma bate hardcodatul;
|
||||
**absent != 0** (H7); lipsa `crsOptiuni`/`crsOptiuniUtilizator`/`goExecutor`.
|
||||
2. Nivel 1 (implicit): label prezent; `VerificaAlegere` nu deschide nimic si **nu
|
||||
face niciun apel HTTP** la alegere (contorul de apeluri exista deja in suita).
|
||||
3. Nivel 0: `poVerifAlegere` neinstantiat, zero apeluri, label absent.
|
||||
4. Nivel 3: dialogul existent, cele 3 rezultate — testele actuale, rulate cu
|
||||
optiunea pe 3.
|
||||
5. **C2 (testul cel mai important, lipsa azi):** `poANAFInlocuire` setat + `gnButon = 2`
|
||||
(Renunta) => obiectul returnat ramane blank, `id_part = 0`.
|
||||
6. H2: `ANAF_CautaPereche` esuat (mock pe `goExecutor`) => mesaj de eroare, fara
|
||||
sugestia "Nou".
|
||||
7. Detalii cu `oStare` `.Null.` => se deschide, cu linia explicativa.
|
||||
8. Discriminatorul "are documente in perioada" (mock pe `goExecutor`, cu si fara randuri).
|
||||
9. Bug-ul B1: cautare fara rezultate => labelul se goleste.
|
||||
10. Zona de lucru: `Alias()` identic inainte si dupa citirea/scrierea optiunilor (H6).
|
||||
11. Punctul de meniu scrie valoarea corecta si are efect imediat (`M6`: la trecerea
|
||||
pe 0 se opreste si timerul si se goleste labelul pe cautarea deschisa).
|
||||
12. Regresie: apelantii care NU au `lVerificaANAF=>1` nu instantiaza `poVerifAlegere`.
|
||||
|
||||
### 8. Transa viitoare — marcaj in grid (nivelul 2), cu conditii de intrare
|
||||
|
||||
Nu se implementeaza pana nu exista, in aceasta ordine:
|
||||
1. **Masuratori** (Tema din planul initial, inca nefacuta): latenta reala a unui apel
|
||||
ANAF la ore diferite; comportamentul la rafale (30 loturi de 20 CUI la interval
|
||||
scurt — de la al catelea vine 429); numarul real de perechi de CUI duplicat la un
|
||||
client real.
|
||||
2. **Date din loguri**: cate discordante apar efectiv la pilot si in ce flux.
|
||||
|
||||
Cerinte tehnice de respectat atunci (toate verificate acum, ca sa nu se piarda):
|
||||
|
||||
| # | Cerinta |
|
||||
|---|---|
|
||||
| UC1 | Criteriul de colorare corect pe trezorerie e "are documente in perioada" (SELECT local), nu statutul ANAF: pe o incasare, verdele dupa ANAF indruma spre partenerul fara facturi |
|
||||
| D-F2 | `DynamicForeColor` e **invizibil pe randul selectat** (`_baza.vc2:200-201`: highlight bleumarin cu text alb). Semnalul are nevoie de al doilea canal: `DynamicFontBold`, care supravietuieste highlight-ului. Verde+bold pentru randul confirmat, restul normal; rosul dispare de pe randuri (are 3 sensuri distincte: prefix gresit, radiat la ANAF, CIF invalid) |
|
||||
| C4 | Un singur `anaf_timer` cu doua consumatoare = nedeterminism: `do_cauta` face `Go Top` + `SetFocus` dupa `actualizeaza_grid1`, deci `AfterRowColChange` rearmeaza acelasi timer. Necesar: doua flag-uri (sau doua timere) + flag de suprimare `lInBatch`, `GO` pe `Recno()` salvat, colectarea CUI-urilor fara `SELECT-SQL` pe cursorul legat de grid |
|
||||
| H1 | CUI-urile din `notfound` sunt inserate ca randuri blank (`scpTVA = .F.`, denumire goala) — fara filtru `!Empty(denumire)` orice partener cu prefix RO negasit la ANAF ar aparea marcat gresit | `validare.prg:1984-1996` |
|
||||
| H4 | `Collection.GetKey` e supraincarcat: cu argument numeric intoarce cheia de la index, nu indexul. Cheile se construiesc string: `'P' + Transform(id_part)`, si `Item()` doar dupa `GetKey(...) <> 0` |
|
||||
| H5 | Expresia `Dynamic*` se evalueaza in context de pictare: referinta necalificata (`ANAF_CuloareRand(id_part)`), corp intreg in `TRY/CATCH` cu `Return Rgb(0,0,0)`, `Nvl(id_part,0)` (randul `<TOATE INREGISTRARILE>` de pe ramura `lAllInList` are `id_part` blank), zero apeluri care schimba zona de lucru. O eroare aici se repeta la fiecare repaint |
|
||||
| H8 | Curatarea binding-ului pe metoda: `Unbindevents(form, 'actualizeaza_grid1', This, 'DupaGrid')` cu 4 argumente — varianta cu 1 argument sterge si `BINDEVENT(Thisform,"lAles",...)` din `Init` si rupe selectia multipla |
|
||||
| H9 | Codul ROA impune >= 1s intre interogarile ANAF (`validare.prg:1777`, `INKEY(1)`); un debounce de 400ms il incalca. Necesare: interval minim global pe sesiune + circuit-breaker la 3 esecuri + log per cod HTTP distinct (azi `gvANAF_EroareLogataSesiune` amuteste toata sesiunea dupa prima eroare, iar 429/5xx sunt indistinguibile de "fara informatie") |
|
||||
| M1 | Delegatul `DupaGrid` trebuie sa aiba semnatura metodei delegate (`Lparameters pcFiltru`), altfel eroare 1229 |
|
||||
| M7 | Codul fiscal invalid nu are stare in schema de culori — se decide explicit sau se documenteaza omisiunea |
|
||||
| Test | Partile netestabile in harnessul actual: ordinea actiunilor sub timer, reentranta pe cursorul gridului, culorile efectiv randate. Daca intra, intra cu risc de regresie permanent |
|
||||
| Invariant | Intreg mecanismul depinde de `PRIVATE poVerifAlegere`/`poANAFInlocuire` vizibile prin domeniu dinamic, ceea ce functioneaza doar pentru ca formularul de cautare e `WindowType = 1` (modal). Orice trecere la modeless rupe atribuirea **fara eroare** |
|
||||
@@ -1,2 +1,2 @@
|
||||
@echo off
|
||||
powershell -ExecutionPolicy Bypass -File D:\ROA\UTIL\foxbin2prg\roa_sync.ps1 -ProjectRoot "%~dp0."
|
||||
@echo off
|
||||
powershell -ExecutionPolicy Bypass -File "%~dp0COMUN\scripts\roa_sync.ps1" -ProjectRoot "%~dp0."
|
||||
|
||||
@@ -25,7 +25,7 @@ _LegalTrademark = ""
|
||||
_ProductName = "ROA - Financiar Contabilitate"
|
||||
_MajorVer = "2"
|
||||
_MinorVer = "11"
|
||||
_Revision = "64"
|
||||
_Revision = "70"
|
||||
_LanguageID = "Romana"
|
||||
_AutoIncrement = "0"
|
||||
*</DevInfo>
|
||||
|
||||
@@ -1 +1 @@
|
||||
2026_07_26_02
|
||||
2026_08_02_01
|
||||
Reference in New Issue
Block a user