Compare commits

...

74 Commits

Author SHA1 Message Date
13b4f65723 sync SVN r18004/r18007: #6 editare factura emisa - pagina de articole
ofacturare_editare.prg (nou): helpere comune - garda eFactura, cursoarele
notei si ale rulajelor, randul de vanzare corespunzator notei si liniile de
articole citite din view-ul VVANZARI_ARTICOLE.

omodificari.vc2 (frm_modific2024): pagina noua de articole ale facturii,
deocamdata doar afisare. Apare numai cand ofacturare_editare.prg e
inregistrat si documentul are rand in VANZARI; in ROACONT si ROAGEST, unde
fisierul nu e incarcat, pagina lipseste si registrul jurnal ramane neatins.
Randul de vanzare al notei se cauta pe toate tripletele distincte (nract,
serie_act, dataact) din nota, pentru ca primul rand poate fi o incasare.

ofacturare_comun.vc2 (frm_facturi): do_editare_factura si butonul aferent,
dupa modelul lui do_sterge, cu garzile de luna inchisa, luna curenta,
document sters, referinte si eFactura.

docs: comentariile se scriu strict necesar, si in cod si in scripturile de
migrare - fara referinte la planuri, stories, decizii sau erori, istoricul
doar in antetul fisierului. Plus regula zero (predarea contextului),
capcanele de la testarea headless si completari pe fluxul text -> binar.

utile/Teste: suita de regresie pentru editarea facturii si harness-ul
watchdog (nu sunt in SVN, unde utile/Teste e ignorat). .gitignore ignora si
capturile PNG si watchdog_out/, ramase din rulari.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SN8snvkk94KuhWwoXUUey3
2026-08-08 16:47:24 +03:00
c5b0ce3a25 teste: suita headless pentru pretul cu TVA pe linie (ROAFACTURARE 2.11.14)
Patru niveluri, 38 de asertii, toate PASS pe binarul din SVN r17998:

- test_pret_cu_tva_dialog        - dialogul frm_articol_factura izolat (14)
- test_pret_cu_tva_nivel2        - factura in curs de compunere, adaugare si ambele cai de
                                   modificare (buton si dublu-clic), Renunta bit-identic (7)
- test_pret_cu_tva_nivel2_retur  - plafonul de cantitate recalculat, pe ramura de retur (4)
- test_pret_cu_tva_nivel3_gestiuni - ramura gestionabila, cu Oracle mockuit la granita prin
                                   dummyexecutor: preselectia gestiunii, excluderea liniei din
                                   propriul stoc, plafonul pe lot, multi-selectia (13)

Nivelurile 2 si 3 conduc dialoguri modale deschise din codul aplicatiei (Show(1) hardcodat),
prin Timer pe _SCREEN si detectie in _SCREEN.Forms - mecanismul e descris in
docs/testare-ui-vfp.md.

Suita nu e in SVN (utile/Teste e ignorat acolo), deci traieste doar in git.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SN8snvkk94KuhWwoXUUey3
2026-08-08 00:23:15 +03:00
f88b2b9a5b sync SVN r18000: todos - puncte marcate DONE si doua puncte noi
Marcate DONE: 2, 3, 4, 5, 8, 9. Punctul 13 precizeaza formularul unificat
frm_facturare_articole2. Noi: 16 (focus si renumerotare act la revenirea din formularul
de curs valutar) si 17 (eroare ORA neprietenoasa cand id_venchelt e null la finalizarea
facturii).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SN8snvkk94KuhWwoXUUey3
2026-08-08 00:23:01 +03:00
8df728cf8b sync SVN r17998: pret cu TVA pe linie si editarea liniei la introducerea facturii
ofacturare.vc2:
- frm_articol_factura: bifa "Pret cu TVA inclus" (preturi_cu_tva) editabila in dialogul
  per-articol; activa doar pe tipurile unde pretul e editabil.
- frm_facturare_articole: buton de modificare deasupra listei + dublu-clic pe linie, ambele
  redeschid dialogul pe linia curenta (do_modifica); Renunta lasa randul neschimbat.
- Plafonul de cantitate la modificare se recalculeaza din stocul disponibil (reversul
  decrementarii din do_adauga_articol), nu ramane la cantitatea aflata deja pe linie.
- Articolele gestionabile: modificarea redeschide tabelul cu gestiuni, pozitionat pe gestiunea
  liniei; do_alege_stoc primeste tnIdTempExclus, ca linia sa nu se scada pe ea insasi din stoc.
  Multi-selectia actualizeaza linia si adauga restul ca linii noi.
- frm_articol_gest_factura: bifa era desenata sub grd_gestiuni; forma inaltata si bifa mutata sub grid.

ofacturare_comun.vc2: scos un SET STEP ON ramas in cod.

docs/testare-ui-vfp.md: sectiune noua despre conducerea dialogurilor modale Show(1) din teste
(Timer pe _SCREEN, detectie prin _SCREEN.Forms, inchidere prin do_termin/do_renunt) si capcanele
platite pe parcurs.

Testat headless: Nivel 1 dialog 14 asertii, Nivel 2 factura in compunere 7, Nivel 2 retur 4,
Nivel 3 ramura gestionabila 13 - toate PASS, zero FAIL.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SN8snvkk94KuhWwoXUUey3
2026-08-08 00:18:20 +03:00
0684485107 sync SVN r17994: tipuri de documente facturare (semnificatia VANZARI.TIP) 2026-08-07 13:28:58 +03:00
be37c2c99c sync SVN r17994: reguli suplimentare pentru scripturile de migrare DB
Niciun ';' la capat de linie intr-un comentariu '--' din interiorul unei instructiuni
(SQL*Plus termina instructiunea acolo, chiar daca ';'-ul e in comentariu). Fiecare
script se incheie cu exec pack_migrare.UpdateVersiune('<nume_script>'); urmat de
commit; (UpdateVersiune e DML, fara commit explicit VERSIUNE minte despre ce s-a aplicat).
2026-08-07 13:26:38 +03:00
837b455687 sync SVN r17991: garda valuta la nota de curs eFactura, scos SET STEP ON
xmlefactura.prg: mentiunea despre cursul valutar din textul aditional se emite doar
cand documentul e chiar in valuta (in_valuta = 1).
ofacturare.vcx: scos SET STEP ON neconditionat din frm_facturare.do_scrie_factura.
2026-08-07 13:15:25 +03:00
e21512240f todo 2026-08-07 00:17:45 +03:00
8421d7ba7f Merge branch 'claude/todos-roacont' 2026-08-07 00:00:58 +03:00
ec51097277 Merge branch 'main' of gitea.romfast.ro:romfast/comun 2026-08-07 00:00:37 +03:00
117f2fb88a eFactura, verificare partener, istoric CF: numar pe bife, TVA la incasare, explicatii pe cota
- borderou si import eFactura: bifele de cautare arata numarul de documente in eticheta, inca
  de la deschiderea ferestrei. Numararea se face local din cursorul deja adus cand nicio bifa
  nu e bifata (cursorul e chiar setul de baza) si prin interogare doar cand o bifa e bifata,
  ca sa nu apara interogari inutile. Latimile bifelor au fost marite: erau croite exact pe
  textul original, iar " (N)" era taiat de marginea controlului.
- verificare cod fiscal: starea partenerului include "TVA la incasare", cu perioada in detalii;
  sursa e ANAF live sau cache-ul ISTORIC_CODURI_FISCALE (ocautare.prg, validare.prg).
- modificare nota: lista de explicatii TVA se filtreaza dupa cota TVA a liniei curente
  (omodificari.vc2, caut_explicatie_tva din oproceduri_comune.prg).
- istoric coduri fiscale: coloane nefolosite ascunse, adaugate cele venite de la ANAF
  (TVA la incasare, split TVA, inactiv si perioadele aferente) - overificari.vc2.
- docs/scripturi-migrare-db.md: regulile de rulare manuala pe schema tinta si un pachet per script.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8Ham1HJ8BB2v9nbtWgdZq
2026-08-07 00:00:21 +03:00
c6216e006e acces email Thunderbird + tabela de provenienta la top segmente in diagnosticul de spatiu 2026-08-06 23:29:18 +03:00
d0c2af8a31 Merge branch 'main' of gitea.romfast.ro:romfast/comun 2026-08-06 12:44:23 +03:00
8fa842888a sync SVN r17985: sursa de referinta DDL (MARIUSM_AUTO) + aliniere la origin
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Euno5AmwoFEvBTdWH8C8S
2026-08-06 12:44:15 +03:00
89695721f4 diag spatiu: emailul de alerta contine si logul complet al rularii
Nota in depanare-spatiu-oracle.md pentru co_2026_08_06_01_DIAG_SPATIU_PACK: pragul absolut
nu se mai aplica tablespace-urilor cu maximul sub el, iar emailul include tot
DIAG_SPATIU_LOG-ul rularii, plafonat la 30000 de caractere.
2026-08-06 10:40:06 +03:00
c599a9c053 sync SVN r17979 2026-08-06 00:34:35 +03:00
b35e62c880 achizitie import: linia de diferenta 6xx fara cod de taxa SAFT 2026-08-05 23:36:20 +03:00
54d97c0349 context_watch.ps1: nu mai raporteaza contextul altei sesiuni
La primul mesaj dintr-o sesiune noua transcriptul .jsonl inca nu e creat, asa
ca Test-Path pica si scriptul cadea pe fallback-ul "cel mai recent .jsonl din
directorul proiectului" - adica transcriptul sesiunii precedente, anuntand un
context de sute de k intr-o sesiune goala. Cand calea vine ca parametru sau pe
stdin si nu exista, iese tacut; fallback-ul pe director ramane doar pentru
invocarea manuala, fara cale.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UKTBDwMB1dAoN4DPBa1b2m
2026-08-05 22:21:32 +03:00
4d1179f8e5 diag_spatiu.ps1: aceleasi praguri ca jobul de diagnostic + plafonul editiei XE
Pragurile ies in capul scriptului si sunt cele din PACK_DIAG_SPATIU: tablespace-ul intra in atentie
sub 2048 MB ramasi sau sub 15% din maximul lui (inainte: sub 1 MB, adica dupa ce ORA-01653 e la usa),
iar FRA la 75% in loc de 80%.

Sectiune noua 2c: plafonul de date al editiei XE (4 GB pe 10.2, 11 GB pe 11.2, 12 GB de la 18c) -
limita e independenta de maxbytes-ul tablespace-urilor, baza poate refuza extinderea cu ORA-12952
desi tablespace-ul mai are loc. Pe alte editii sectiunea se sare.

Verificat pe XE 21c: sectiunea 2c da aceleasi cifre ca pachetul.
2026-08-05 21:55:13 +03:00
bd09073229 teste NNIR: avertisment .FXP stale (VFP ruleaza tacut versiunea veche a scriptului)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EBFMe75MwdnDQk3qhp1YB2
2026-08-03 23:45:58 +03:00
26d2c205c9 NNIR editabil in Registrul Jurnal (frm_modific2024) + teste 2026-08-03 23:44:27 +03:00
4666262c92 publicare scripturi de baza de date: script + documentatie
COMUN/utile/publicare_scripturi.ps1 face cei doi pasi ai publicarii (import in
UPD_DATABASE + arhiva lunara database[n]_*.zip in _UPDATE), cu configurarea citita
din settings.ini-ul lui tasks.exe si verificare octet cu octet a continutului.
2026-08-03 23:14:47 +03:00
72bf63cd04 depanare-spatiu-oracle.md: jobul zilnic de diagnostic + mecanismele reutilizabile
Jobul DIAGSPATIU_ZILNIC (SVN r17969) si mecanismele generale desprinse din investigatie:
cheile SERVER_INFO si GetSchemaParola, rularea ca SYS/OS prin UpdateSQLPLUS/ExecuteScriptOS,
de ce EmailLog nu se reutilizeaza, ordinea de aplicare a scripturilor sys_.

Capcane noi: parola SYS nu e generica la toti clientii, iar rolurile nu se aplica in pachete cu
drepturi de definitor - de aici granturile directe din sys_2026_08_03_05.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014sNn6dmAimtyXkDU4frJrh
2026-08-03 22:24:28 +03:00
05d91a05c6 todos 2026-08-03 20:42:46 +03:00
5f944e8bfa credentialele Oracle se muta in COMUN\docs\local\oracle.md
Fisierul era per proiect; acum e in COMUN, partajat de toate aplicatiile ROA.
Ramane neversionat in git (docs/local/ adaugat in .gitignore-ul COMUN), exista
doar in SVN. Parola SYS e generica, nu difera de la server la server.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014sNn6dmAimtyXkDU4frJrh
2026-08-03 19:06:44 +03:00
1d3e75803f livrare.ps1: fisierul de mesaj fara BOM
Out-File -Encoding utf8 in PS 5.1 scrie BOM, care ajungea ca prim caracter in
mesajul de commit (ex. un mesaj despre "sync SVN"). Se scrie cu
[IO.File]::WriteAllText si UTF8Encoding $false.

Nota in scripturi-uzuale.md: mesajele catre git/svn din PowerShell trec prin
fisier, UTF-8 fara BOM, LF.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014sNn6dmAimtyXkDU4frJrh
2026-08-03 18:26:41 +03:00
f4b48d9c20 livrare.ps1: mesajul de commit prin fisier, nu prin -m
PowerShell 5.1 nu escapeaza argumentele catre exe native, deci ghilimele duble
in mesaj (ex. un commit de "sync SVN") spargeau apelul git. Mesajul se scrie
intr-un fisier temporar si se foloseste git commit -F, sters in finally.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014sNn6dmAimtyXkDU4frJrh
2026-08-03 18:23:41 +03:00
d350119993 livrare.ps1: roa_sync la tree curat, rebase la push respins, garda SVN
- pasul 1 ruleaza roa_sync.ps1 cand tree-ul e curat (svn update + git_sync +
  reconciliere cu origin); cu modificari necomise ruleaza doar git_sync, ca
  roa_sync sa nu inglobeze munca in curs intr-un commit de sync SVN
- fetch inainte de commit: raporteaza cand ramura e in urma fata de origin
- push respins non-fast-forward: rebase + o singura reincercare, abort curat
  la conflict; fara --force
- avertisment pentru fisierele comise in git dar nefacute svn add
- docs: scripturi-uzuale.md - ce script se ruleaza si cand

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014sNn6dmAimtyXkDU4frJrh
2026-08-03 18:18:45 +03:00
48f15c1da1 scripturi de diagnostic baza de date + script de livrare
- diag_actualizare.ps1: de ce s-a oprit actualizarea (UPD_ISTORIC, UPD_LOG,
  script_master.log prin UTL_FILE, versiuni per schema, spatiu tablespace, verdict)
- diag_spatiu.ps1: spatiu Oracle la clienti (tablespace, audit, ADR, FRA, disc server)
- livrare.ps1: git_sync + curatenie + verificari + commit/push
- curatenie.ps1: sterge si docs\propuneri_*.md
- docs: depanare-spatiu-oracle.md nou, depanare-pack-update.md completat cu cazul SIGMA

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014sNn6dmAimtyXkDU4frJrh
2026-08-03 12:11:42 +03:00
5f3a17c5c7 fix: exportul Excel din GridExtras respecta ordinea de afisare a coloanelor
gridutils.copytoexcel parcurgea grid.Columns() pe indexul de creare, care in
VFP nu are legatura cu ColumnOrder. Coloanele se sorteaza acum dupa ColumnOrder
inainte de a construi lista de campuri, deci exportul iese in ordinea de pe
ecran, inclusiv dupa ce utilizatorul muta coloane (ordine salvata de
savegridpreferences).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YB2eA3Wd31DZiXjzVRc6VJ
2026-08-03 11:48:03 +03:00
a290a51276 docs: emailurile actualizarii si compatibilitatea scripturilor cu 10g/11g
Log-ul de actualizare (PACK_UPDATE.EmailLog, din baza) si buletinul informativ
(trimis de serverul de update) sunt doua fluxuri diferite, cu destinatari
configurati in locuri diferite.

Scripturile de migrare se scriu la nivelul Oracle 10.2 si trebuie sa ruleze
si pe 11.x; tabel cu versiunea minima a constructiilor uzuale si limitele XE.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TM9Cxpzrn9wBSkyBNr22Qc
2026-08-03 10:46:08 +03:00
fc1af63014 docs: script_master.log, unde apar erorile de aplicare a scripturilor
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TM9Cxpzrn9wBSkyBNr22Qc
2026-08-03 10:05:40 +03:00
a07b89e5e1 docs: capcane Oracle 10g la scripturile de migrare
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TM9Cxpzrn9wBSkyBNr22Qc
2026-08-03 10:05:33 +03:00
e75fc365c5 docs: depanarea actualizarii ROA (PACK_UPDATE)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TM9Cxpzrn9wBSkyBNr22Qc
2026-08-03 09:36:59 +03:00
5eb1f7ef40 Factura din contract: cod fiscal client precompletat
oDateFactura.Init completa clientul de pe contract fara cod fiscal, spre
deosebire de ramura de comanda. Formularul de cerere date arata acum codul
fiscal si permite verificarea ANAF fara a intra in cautarea de client.

todos: punct 10 - integrare contracte in ROAFACTURARE.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HdKazj8DDksshTb2vB3gZz
2026-08-03 08:35:56 +03:00
6aebd474fc Teste headless: verificare ANAF la alegerea clientului cu contract activ
Harness ROAACNPRO-specific (gcAppPath propriu, spre deosebire de test_init_env_auto.prg
care e fixat pe ROACONT), shadow pentru cauta_alfa() si testul care reproduce/confirma
label-ul ANAF pe caut_client_contract_activ(), plus repro pentru scoping-ul gresit al
lui poDate in do_cauta_partener (Thisform.poDate vs poDate PRIVATE).
2026-08-03 08:13:16 +03:00
71f661092d sync SVN r17952 2026-08-03 02:50:05 +03:00
e4f8736543 todos 2026-08-03 02:29:24 +03:00
006b58f644 curatenie.ps1: stergerea artefactelor de lucru dinaintea commit-ului
Script determinist (patch-uri, handoff-uri, *.pre_runda*.bak, .bak din cache text,
screenshots*/uisync*/.fxp/.err/loguri), cu protectie pe fisierele urmarite de git
si mod -DryRun. Referit din reguli_lucru.md (regula 1) si flux-editare-vfp-text.md.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RYbiinqXxdEqXi53x4Ro7K
2026-08-03 01:27:21 +03:00
6bef1e26ee achizitie import intern: campul pret lei redevine editabil
ControlSource-ul coloanei cPretFactura se rebindeaza calificat (rul_temp.pret_lei);
necalificat, VFP il rezolva pe workarea altei grile si celula nu accepta tastare.
Test de reproducere + nota docs/capcana_grid_controlsource.md.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RYbiinqXxdEqXi53x4Ro7K
2026-08-03 01:18:52 +03:00
80726b603e reguli: progres.md se sterge dupa commit, cand sarcinile sunt terminate
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RYbiinqXxdEqXi53x4Ro7K
2026-08-02 22:34:00 +03:00
c4d869921d verificare partener: garda pe cont NULL, hook-uri de disciplina, docs compactate
- ooperatii_comune: verific_partener nu mai construieste SQL NULL cand contul
  primit e NULL (EMPTY(.NULL.) e .F. in VFP)
- utile\context_watch.ps1 si utile\docs_revizie_check.ps1: masurarea contextului
  sesiunii si cadenta reviziei de documentatie, prin hook-uri Claude Code
  (instalare in docs\monitorizare-context.md)
- reguli_lucru: delegare la subagenti, modificari minime si scoped, scrierea si
  revizuirea documentatiei, changelog strictul necesar (regulile 3, 6, 9, 11, 12)
- scripturi-migrare-db: continutul unui script (scoped, fara select, idempotent)
- teste noi pentru cele doua erori din achizitia de import
- restul documentatiei compactata, fara pierdere de reguli

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RYbiinqXxdEqXi53x4Ro7K
2026-08-02 22:30:44 +03:00
20323d22b3 fix: F4 detalii ANAF pe formularul de cautare partener fara campul nume
Nvl() evalueaza ambele argumente, deci .nume era citit chiar cand cursorul avea
doar denumire - eroare "Variable 'NUME' is not found". Inlocuit cu Iif() pe
Type() in Detalii si VerificaAlegere.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RYbiinqXxdEqXi53x4Ro7K
2026-08-02 12:20:07 +03:00
974716fd85 todos 2026-08-02 11:51:25 +03:00
189e0a694e Verificare ANAF: o singura salvare in istoric si antete corecte pe formularele de verificare (SVN r17943)
VERIFICARE_CIF salva a doua oara in istoric ceea ce traseul ANAF (SalveazaIstoricDinCursor) tocmai
salvase, cu alte valori pentru PLATITORTVAMFIN si DATATVAMFIN, deci o apasare pe verificarea ANAF
lasa doua randuri in ISTORIC_CODURI_FISCALE. Pe traseul ANAF a doua salvare nu se mai face; traseele
MFIN/VIES raman neschimbate. Partea de baza de date: co_2026_08_02_05_COMUN_PACK_ISTORIC_CF.sql (SVN r17942).

Formularul de verificare in masa foloseste azi numai serviciul web ANAF (chkANAF fortat pe .T. in
Init), deci antetele arata sursa corecta: "Platitor TVA ANAF", "Firma ANAF" si "Data verificata"
(coloana arata data pentru care s-a interogat, nu data luarii in evidenta TVA). In fereastra cu
istoricul unui cod fiscal, coloanele DATATVAMFIN si PLATITORTVAMFIN sunt ascunse - dupa modificarea
din pachet raman inghetate.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018LkXBVHUNkb7Quq36TfQcs
2026-08-02 11:48:47 +03:00
f789ace574 docs: numerotarea scripturilor de migrare si ce intra in versiune_db.txt
Secventa NN e unica pe zi, comuna tuturor prefixelor (ff/co/sys/ris/rf). In versiune_db.txt
intra doar versiunea ultimului script ff_, pentru ca programele se conecteaza pe schema
firmei, nu pe CONTAFIN_ORACLE.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RYbiinqXxdEqXi53x4Ro7K
2026-08-02 11:42:57 +03:00
742e0561b5 Cache ANAF: randul curent din istoric se alege pe dataorav_anaf, nu pe id
Dupa fuziunea istoricelor de coduri fiscale, ID-ul nu mai urmeaza ordinea cronologica,
deci row_number() ordonat pe id putea intoarce un rand vechi ca stare curenta.
Ordonarea trece pe dataorav_anaf desc, cu id desc ca departajare.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014sKVgMkowK4HpbFxBQVM22
2026-08-02 10:34:34 +03:00
521993bf85 Verificare ANAF si la caut_partener: achizitie import, finalizare NIR, furnizor pe rulaj
caut_partener primeste tlVerificaANAF/tdDataDoc (acelasi bloc ca la caut_parteneri) si citeste
tip_persoana din vnom_parteneri, ca banda de stare sa distinga CNP de CIF, nu dupa lungimea codului.

Apelanti pe documente: factura si partenerul DVI din achizitia de import (data din formular,
dDataAct), furnizorul de la finalizarea NIR-ului (data cade pe poAct.dataact) si schimbarea
furnizorului pe rulaj.

verific_partener si verificare_note_contabile (ooperatii_comune.prg) cer verificarea si cand
completeaza partenerul lipsa pe cont, la salvarea documentului.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RYbiinqXxdEqXi53x4Ro7K
2026-08-02 10:09:12 +03:00
7abec07549 Verificare ANAF: la serviciul web ajung doar CIF-uri valide (SVN r17939)
Lotul ramas pentru ANAF se construia cu un Scan fara filtru pe cui_n, deci codurile
care nu sunt CUI RO valid (cod gol, alta tara, peste 10 cifre) erau retrimise la fiecare
rulare - fereastra arata "Verific codurile fiscale 1..16 / 16" desi cele 903 coduri reale
veneau din cache, iar cererea plecata spre ANAF era goala: {"cui":0} -> 404.

- lotul ramas: Scan For cui_n <> 0.
- NormalizeazaCoduriCursor: cui_n se completeaza doar daca trece si algoritmul cifrei de
  control (VerificareCod.VALIDARE_CIF), nu doar tara RO / numai cifre / maxim 10 caractere;
  plus Val() <> 0, ca un cod de zerouri sa nu ajunga la ANAF drept cui:0. VALIDARE_CIF nu
  s-a atins, e doar apelata.
- ANAF_SincronWebService_PlatitorTva: acelasi filtru la compunerea cererii (cele doua
  trebuie sa ramana identice) si LOOP cand grupul nu are niciun CUI valid, deci fara
  cerere HTTP goala.

Verificat: compilare curata; test headless pe NormalizeazaCoduriCursor (RO7320118, 7320118,
RO25501, "RO 1879855" trec; 7320119 cu cifra de control gresita, 0, cod gol, BG123456789,
CNP de 13 cifre sunt excluse). Fara fals-pozitive pe date reale: toate cele 903 coduri
confirmate de ANAF pe ROMFAST trec algoritmul.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JCzVWfqscv1xyo5uvJiWiW
2026-08-02 08:27:28 +03:00
5c8a201438 Cache ANAF: verificarea in masa a codurilor fiscale, pe transe (SVN r17935)
Verificarea "in masa" (VerificaListaCIF ... 'MASA') pica pe ORA-01795 peste 1000
de coduri, iar esecul trimitea tot lotul la ANAF, cu pauze de o secunda la fiecare
100 de coduri. Pe langa asta, fiecare rand servit din cache era salvat inapoi in
istoric si logat separat.

- programe/validare.prg: CitesteIstoricPentruCoduri citeste pe transe de maxim
  1000 de coduri legate cu OR in aceeasi interogare (fara obiecte noi in baza,
  compatibil cu Oracle 10g); plasa de siguranta cere codurile neacoperite o
  singura data, nu cod cu cod; SalveazaIstoricDinCursor sare peste randurile cu
  sursa CACHE*; bucla de log per rand devine o singura linie cu totalul.
- clase/overificari.vc2: completarea tabelului de parteneri foloseste index pe
  codul normalizat si SEEK in loc de LOCATE cu UDF (era patratic).
- utile/Teste/cache_anaf/: harness-uri de masurare si non-regresie pentru
  timpii de mai jos.

Masurat pe MARIUSM_AUTO, cu ANAF blocat: 1000 de coduri 5,1 s -> 0,318 s;
1001 coduri 16,6 s cu ORA-01795 -> 0,553 s fara eroare; 3000 de coduri 1,565 s;
200 de coduri din cache 3,93 s -> 0,05 s, cu 0 randuri noi in istoric;
completarea tabelului pentru 2000 de parteneri 11,97 s -> 0,028 s.
Randurile intoarse si verdictele raman identice.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JCzVWfqscv1xyo5uvJiWiW
2026-08-02 07:27:42 +03:00
4342aae78c TODOS 2026-08-02 01:46:57 +03:00
859e67e874 Cache ANAF pe ISTORIC_CODURI_FISCALE: verificare din memorie, plasa la tacere ANAF
Verificarile de partener nu mai depind exclusiv de raspunsul ANAF: se citeste
intai cache-ul din ISTORIC_CODURI_FISCALE (mutat in CONTAFIN_ORACLE), cu
provenienta afisata pe ecrane (sursa / data_sursa) si cu plasa de siguranta
cand ANAF tace. Ordinea cache/ANAF e configurabila; cache-ul expira.

- programe/validare.prg: verificare single si pe loturi peste cache, contract
  404 separat de caderea de serviciu, expirarea cache-ului, corectii la
  verdictul pe firma si la etichetarea CACHE_INDISP.
- programe/ocautare.prg: plasa de siguranta si banda de provenienta la cautarea
  de partener.
- programe/oproceduri_comune.prg: VERIFICA_RTVAI_DATA citeste si cache-ul.
- clase/overificari.vc2: propagarea provenientei in interfata.
- utile/Teste/: harness-uri de testare headless - echivalenta cache/ANAF pe 200
  de coduri reale, marginile pe inactiv si TVA la incasare, mock batch ANAF,
  baseline D394 si sondele de diagnostic ANAF.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JCzVWfqscv1xyo5uvJiWiW
2026-08-02 01:33:18 +03:00
ebb20fab7e achizitie import: numarul DVI nu mai suprascrie numarul facturii
In import_nota, randul de TVA al DVI-ului pastreaza doc_key-ul facturii-mama.
copiaza_valoare il sarea doar ca tinta, nu si ca sursa, asa ca o trecere prin
celula "Nr" a randului DVI scria numarul vamal peste randurile facturii (B/G/S)
si, la Terminat, in ACT si RUL.nract. Garda e acum in ambele sensuri, pentru
numar, serie, data, fel document si partener; propagarea de partener din
Grid1.cPartC.Text1.Valid a primit aceeasi protectie.

Garzile comparau numele de camp bar, dar ControlSource-ul unei coloane de grid
e calificat la runtime (introdc.nract), deci nu se activau pe drumul din grila.

Teste noi in utile/Teste/achizitie_import.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U9uDgDfUQXbh2Neib36CN8
2026-08-01 22:47:35 +03:00
832fea4913 achizitie import: TVA DVI cu valuta proprie, discount financiar, cote multiple
- TVA-ul de pe DVI poate avea valuta si curs proprii, diferite de ale facturii
  (rand "protejat": rand_dvi/valuta_proprie pe introdc, sparge_tva_protejat).
- Discount financiar pe factura: rand tip_rand='G' (401 = 767), TVA calculat pe
  baza diminuata, marfa si preturile articolelor pe valoarea integrala.
- Factura multi-cota: randurile S, G si T se sparg pe cotele articolelor, cu
  explicatia TVA din familia coloanei si alinierea T -> S.
- Teste noi in utile/Teste/achizitie_import (discount, DVI, cote, e2e).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U9uDgDfUQXbh2Neib36CN8
2026-08-01 09:32:35 +03:00
704e25e190 eroare validare daca nu exista internet 2026-07-30 13:51:57 +03:00
3421cc39d2 Borderou eFactura: bife de filtrare "Cu diferente" / "Lipsa din Reg. TVA"
Pe toate cele trei pagini (Facturi emise, Primite, Trimise) doua bife noi, colorate
ca randurile pe care le filtreaza: turcuaz "Cu diferente Reg. TVA" (jtotctva
completat, dar diferenta peste 0,15 lei sau eFactura in valuta) si gri "Lipsa din
Reg. TVA" (jtotctva null). Bifate impreuna se aduna cu OR.

Culorile din grid: gri = nu e in registru, turcuaz = diferenta peste 0,15 lei sau
necalculabila, alb = se potriveste. Expresia DynamicBackColor e sparta in doua
siruri, VFP nu accepta constante peste 255 caractere.

diferenta ramane NULL cand jtotctva e NULL (nu 0 fals), la fel ca la facturile
primite/trimise; jtotctva si diferenta sunt acum nullable in cursorul de facturi
emise.

Corectat lcFiltru3, care se construia din lcFiltru2 si pierdea conditiile paginii.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FW7zDopcHo2fHq5L53MjMM
2026-07-29 12:34:33 +03:00
e18784358b eFactura: acelasi cod de culori in borderou si in import, filtru de data sargabil
Galbenul de la randurile cu diferenta fata de Registrul TVA devine turcoaz in borderou,
ca sa insemne acelasi lucru in ambele ferestre: gri = factura nu e in registru,
turcoaz = e in registru dar valoarea difera cu peste 0.15 lei ori nu se poate compara
(factura in valuta), alb = se potriveste.

Importul preia regulile corectate ieri in borderou: diferenta ramane goala cand factura
nu e in registru sau e in valuta si tine cont de semnul notei de credit, iar jtotctva si
diferenta se declara nullable in cursor (altfel NULL devine 0 si gri-ul nu mai apare).
Pana acum importul colora orice diferenta de un ban si dadea turcoaz fals pe notele de
credit si pe facturile in valuta.

Filtrul initial al cursorului din fereastra de import compara data_act cu un interval
[prima zi a lunii, prima zi a lunii urmatoare) in loc de extract(year/month from data_act),
deci poate folosi IDX_ANAF_EFACTURA_1(FACTURA_EMISA, XDATA_ACT, DATA_RASPUNS). Filtrul
rula la fiecare deschidere a ferestrei, nu era amanat ca la borderou.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FW7zDopcHo2fHq5L53MjMM
2026-07-29 00:31:33 +03:00
69884c0a50 curatare 2026-07-29 00:18:55 +03:00
0df20461e2 Borderou eFactura: potrivire cu registrul de TVA rapida si corecta
Potrivirea pe numar compara nract cu grupurile de cifre extrase din xnumar_act,
in loc sa aplice un regex peste nract. Predicatul devine sargabil, deci foloseste
IDX_JC2007_003/IDX_JV2007_003 in loc sa scaneze toata luna din jurnal pentru
fiecare factura: borderoul de facturi trimise trece de la 97 de secunde la sub una
(masurat pe o firma cu 6006 facturi si 6466 randuri in jurnal).

Rezerva pe suma egala se pastreaza, dar in view se leaga prin COALESCE, nu prin OR:
se evalueaza doar pentru facturile pe care numarul nu le-a gasit. Legata prin OR,
potrivea nediferentiat orice document cu aceeasi suma la acelasi partener in aceeasi
zi - pana la 49 de documente pentru o factura - si afisa o "Diferenta" gresita.

jcnt si coloana "Pot." se elimina: dupa corectarea potrivirii numarul de documente
potrivite e practic intotdeauna 1, iar starea "nu e in registru" se citeste din
jtotctva IS NULL. jtotctva se declara nullable in cursor, altfel NULL-ul devine 0 si
randurile fara potrivire nu s-ar mai colora.

Pragul de la care un rand devine galben urca de la 0.01 la 0.15 lei: la 0.01 ieseau
841 de randuri galbene din 6006, toate diferente de rotunjire sub 0.11 lei.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FW7zDopcHo2fHq5L53MjMM
2026-07-28 23:31:04 +03:00
31a157cb55 todos 2026-07-28 17:08:21 +03:00
a5b3b29307 Verificare ANAF: optiunea arata setarile pe niveluri si revenirea la implicit
Dialogul din Initializari > Optiuni utilizator arata separat setarea
utilizatorului curent, setarea firmei, implicitul programului si starea
de pe calculator. Butonul "Nu" sterge setarea proprie (DELETE in
OPTIUNI_UTIL + reincarcarea cursorului), ca utilizatorul sa revina la
setarea firmei sau la implicit; setarea firmei nu se modifica de aici.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DhJwsrFFe1ZNAAtS8Twuti
2026-07-28 17:06:59 +03:00
5df79dcce8 corectie eroare 2026-07-28 16:08:21 +03:00
b1f8a8ed30 Borderou eFactura: diferenta ignora TVA-ul de taxare inversa
vizeFactura (anaf_efactura.prg), facturi primite: expresia diferentei scade jtva_ti din
jtotctva, ca la ecranul de import. Borderoul era ecranul din changelog, dar r17913 modificase
doar vizImportEFactura.

Scoate si sonda pe user_tab_columns din import_efactura.prg: versiune_db.txt este
2026_07_28_01 (exact scriptul care adauga jtva_ti), iar pack_migrare.VerificaVersiune nu lasa
programul sa porneasca pe o baza mai veche, deci coloana exista sigur.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DhJwsrFFe1ZNAAtS8Twuti
2026-07-28 15:55:54 +03:00
1d83854f56 Merge claude/anaf-tva-efactura: avertizare exigibilizare TVA, verificare ANAF 2026-07-28 15:12:58 +03:00
ccb8fd2cc6 Verificare ANAF: perioada de TVA spune ce reprezinta; optiunea intreaba inainte sa modifice
SufixPerioadaTVA lipea intervalul direct dupa verdict ("Neplatitor TVA
05/07/2002 - 18/04/2012"), ceea ce se citea ca perioada in care partenerul NU a
fost platitor - exact pe dos. Eticheta spune acum ce reprezinta: "inregistrat TVA
<de la> - <pana la>", respectiv "cod TVA anulat din <data>". Detaliile F4 arata
perioada si in ramurile "Nu exista partener cu CUI ..." si "Nu s-a putut citi
lista de parteneri", unde lipsea - adica tocmai in cazul in care utilizatorul
n-avea de unde sa afle ce inseamna datele din banda de stare.

ANAF_ComutaVerificare afisa un mesaj informativ si apoi cerea neconditionat
valoarea noua, propunand valoarea curenta. Cand verificarea era oprita local din
settings.ini, valoarea propusa era 0, iar un Enter reflex o salva ca optiune de
utilizator - ceea ce transforma tacut o oprire locala in oprire pe orice
calculator. Mesajul intreaba acum Da/Nu si propune 9 (oprire locala) in loc de 0.

reguli_lucru.md pct. 2: istoricul modificarilor sta doar in antetul fisierului,
la fel in .prg si in package-urile/procedurile PL/SQL Oracle; in corpul codului
doar comentarii functionale, niciodata data/autor/"am modificat".

Adaugat docs/sold-neexigibil-reportat-jc2007-jv2007.md: jc2007/jv2007 tin o linie
per factura PER PERIOADA (soldul neexigibil se reporteaza lunar), deci orice
interogare pe sold se filtreaza pe an/luna.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DhJwsrFFe1ZNAAtS8Twuti
2026-07-28 15:12:13 +03:00
248ac0e002 Note contabile: avertizare la salvare cand raman facturi cu TVA la incasare neexigibilizat
La salvarea notei, VerificaAvertizareExigibilizareTVA (identica in
frm_modific2007 si frm_modific2024) verifica incasarile si platile cu factura
pereche completata si avertizeaza daca vreuna dintre facturile lor cu TVA la
incasare nu are inca nota de TVA exigibilizat.

Candidatii sunt exact cele doua tipare pe care do_adauga_tva_exigibil le trateaza
automat (id_factd > 0 cu scc pe 5xx, id_factc > 0 cu scd pe 5xx); facturile deja
acoperite de o linie tipnota = 1 din nota curenta sunt suprimate. Soldul
neexigibil se citeste dintr-un singur SELECT peste VJC2025/VJV2025, filtrat pe
perioada curenta si pe toate cele 14 coloane de cota.

La "Da" se apeleaza do_adauga_tva_exigibil NEMODIFICAT, marcand temporar `ales`
doar pe liniile candidate si restaurandu-l dupa; programul ramane in formular,
ca notele adaugate sa poata fi verificate. Orice esec (optiune, cursor, SQL)
se logheaza si lasa salvarea sa continue.

Se poate opri din settings.ini [tva] avertizare_exigibilizare=0 sau din optiunea
RC_TVA_AVERT_EXIGIB.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DhJwsrFFe1ZNAAtS8Twuti
2026-07-28 15:11:56 +03:00
85ad3dea02 Borderou eFactura: diferenta ignora TVA-ul de taxare inversa
Expresia diferentei scade jtva_ti din jtotctva pentru facturile primite. Sonda pe user_tab_columns
inainte de construirea SELECT-ului, ca borderoul sa se deschida si daca migrarea DB nu a ajuns inca
la client. lcSchema (schema pozitionala) neatinsa.

SVN r17913; script DB in DATABASE r17912.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DhJwsrFFe1ZNAAtS8Twuti
2026-07-28 08:23:19 +03:00
d440dd91fc Verificare ANAF: perioada de inregistrare in scopuri de TVA + corectie mesaj fals la CNP/cod invalid
L1: perioada de TVA (inceput, sfarsit, anulare din oficiu) si mesajul ANAF integral propagate din
cursor pana in banda si in dialogul F4. Banda arata data doar la discordanta, anulare sau perioada
incheiata; F4 o arata intotdeauna.

L2: clasele de esec CNP si COD_INVALID au text propriu in F4, in loc de mesajul fals
'ANAF nu a raspuns'. Garda Vartype pe parametrul nou tnTipPersoana pentru apelantii cu vechea
semnatura (fisier partajat de ROACONT/ROAGEST/ROAFACTURARE).

SVN r17910.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DhJwsrFFe1ZNAAtS8Twuti
2026-07-28 00:50:11 +03:00
95cf54e447 Verificare ANAF: raspunsul 404 citit, intrerupator cand serviciul nu raspunde
Serviciul ANAF intoarce HTTP 404 cu corp complet pentru codurile inexistente
({"found":[],"notFound":[...]}), iar wrapper-ul citea corpul doar pe 200 - deci
verdictul "cod inexistent" nu aparea niciodata. Corpul se citeste acum la orice
status, iar verdictul se da doar cand notFound contine chiar codul interogat;
orice alt corp neinteles inseamna "nu a raspuns", nu acuzatie.

Timeout-uri reale pe apelurile web (2/2/3/3): garda Pemstatus din jurul lui
SetTimeouts intoarce .F. pe obiectul COM legat tarziu, deci timeout-urile nu se
aplicau, iar o gazda care inghite pachetele bloca interfata ~21 s per rand.
Aceleasi timeout-uri si pe drumul batch. Fallback-ul Microsoft.XMLHTTP, fara
timeout, a fost scos de pe calea single.

Cand serviciul nu raspunde, verificarile se opresc 10 minute si banda arata ca
au fost sarite, in loc sa taca. La deschiderea formularului pleaca o sonda
asincrona de disponibilitate, cu termen de viata, guard de reintrare si Abort()
la inchidere; randul care asteapta verdictul nu face apel propriu. Cache doar pe
rezultate pozitive. Codul fiscal nenumeric primeste mesaj propriu, in banda si
in detaliile F4.

ParseJsonANAFv8 restaureaza formatul datei si pe calea de eroare (o exceptie
lasa toata sesiunea pe YMD).

Teste: suita headless 70/70, cu sonda si clasele de esec mock-uite (fara retea)
si fixture peste corpurile 404 masurate pe serviciul real.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DhJwsrFFe1ZNAAtS8Twuti
2026-07-27 16:25:02 +03:00
eacf145536 reguli_lucru: curatenie dupa commit si capcana versiunilor text stale
Punctul 1: dupa commit se sterg patch-urile de review si backup-urile de lucru.

Punctul 5: versiunile `.??2` sunt instantanee si pot ramane in urma binarului.
Concret, un `.pj2` vechi de doua saptamani a dus la concluzia gresita ca proiectul
refera `clase\orapoarte.vcx`, cand `.PJX`-ul real refera `comun\clase\orapoarte.vcx`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P1J6WjsQn7i7c9uF7VweGc
2026-07-27 15:53:20 +03:00
a067389ae1 Rapoarte generice: corectare do_adauga, separator coloane de suma, scoatere SET STEP ON
ct_selectie.Init si ct_selectie_sql.Init apelau do_adauga cu 4 argumente, desi
metoda e declarata cu 6. lcCampId ajungea .F., iar Nvl(.F.,lcCamp) dadea Error 11
la deschiderea oricarui formular de raport generic, urmata de o cascada in
ct_ordonare1._scrollcontainer1.do_adaugaobiect.

ccoloanesuma si cnumecoloanesuma erau stocate cu virgula in formulare, dar codul
le citeste cu "|" (contract documentat in ct_selectie.Init: o coloana poate fi o
expresie de forma round(...,...)). Rezulta SUM(cantitate,valoare_ftva,valoare) si
ORA-00909. Migrate cele 12 valori pe "|"; clistacoloaneordine ramane pe virgula,
asa cum o citeste codul.

Scos SET STEP ON din ct_selectie.do_instructiune_sql si din
frm_date_rapoarte_articole_v.do_cauta - in EXE nu au efect, dar la rularea din
sursa opreau executia in debugger.

Adaugata coloana "Cont" in rapoartele de articole: contul de venit preluat din
nota contabila a politicii de preturi (primul rand dupa ORDINE), cu regula
debit/credit dupa structura notei.

Verificat headless: cele 6 formulare de raport se deschid cu 0 erori (inainte
10/10/14/9/1/9), do_instructiune_sql intoarce .T., iar SQL-ul generat se executa
pe Oracle si returneaza 31 de randuri grupate pe cont.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P1J6WjsQn7i7c9uF7VweGc
2026-07-27 15:49:18 +03:00
989c3dd6f4 Adauga scripts/roa_sync.ps1 (mutat din UTIL\foxbin2prg) + testele lui
Sync-ul de sesiune se distribuie de-acum cu COMUN (svn update / comun.git).
Fata de versiunea veche: dupa commit-ul local de sync reconciliaza cu origin
(fetch + ff-only sau rebase --empty=drop; sync-urile byte-identice cu origin
dispar singure) si face push automat DOAR cand tot ahead-ul e din commit-uri
de sync; conflict real -> abort + exit nenul. Switch -GitOnly pentru
reconciliere rapida / teste. Doc inrolare actualizat (tooling + pasul 6).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AvccPZXr4A9ihcTtExNoJT
2026-07-27 11:59:42 +03:00
39e3c4e238 Merge branch 'main' of gitea.romfast.ro:romfast/comun 2026-07-27 01:31:37 +03:00
889840357a Verificare ANAF la alegerea partenerului
ocautare.prg - miezul functionalitatii:
- anaf_verif_cautare: verdictul ANAF pe randul curent din formularul de cautare
  (label sub grid), la data documentului; discordantele si codurile fiscale invalide
  cu rosu; F4 sau click deschide detaliile.
- ANAF_StarePartener, cu cache pe sesiune, excludere parteneri externi si persoane
  fizice; ANAF_ValidareCod pentru CIF/CNP.
- ANAF_NivelVerificare: cascada RC_ANAF_VERIF_SELECTIE (kill-switch settings.ini >
  optiuni utilizator > optiuni firma > implicit 1), cu cache invalidat la schimbarea
  firmei sau utilizatorului; ANAF_ComutaVerificare pentru punctul de meniu.
- Detalii: alegerea variantei corecte de partener din perechea RO / fara RO, cu
  discriminator "are documente in perioada"; dupa Da sau Nu se inchide cautarea si
  se revine in formular cu partenerul ales (AplicaInlocuirePartenerANAF).
- ANAF_CaData: data documentului poate veni si ca DateTime (tact.dataact).
- Banda proprie sub grid pentru label: formularul creste cu 54, gridul isi pierde
  ancorarea de jos si primeste inaltimea din AjusteazaBanda, legata de Resize si
  Activate - formularul isi reaseaza gridul dupa Show, deci Activate e momentul util.

validare.prg: ANAF_VerificaCuiSingle, wrapper single-CUI peste serviciul ANAF, cu
data verificarii si o singura eroare logata pe sesiune.

cauta_alfa.prg: hook generic - ataseaza poVerifAlegere pe formularul de cautare
inainte de Show si il detaseaza dupa.

Apelanti opt-in (lVerificaANAF): baza.vc2 (lookup-ul generic de partener din
formularele actbaza/actbaza2007 lansate din meniuri), onote_contabile.vc2 (partener
debit/credit), omodificari.vc2 (do_cauta din cele trei clase de modificare, cu data
notei), ofacturare.vc2 (client, furnizor). Casa/banca ramane in afara: acolo partenerul
se alege pentru imperecherea facturilor.

cauta_alfa_forms.vc2: F4 deschide detaliile, iar terminarea cautarii trece prin
VerificaAlegere.

Teste: suita headless pentru fluxul de verificare (utile/Teste/partener_anaf/), cu
mock pentru apelul ANAF si pentru dialoguri.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019H3r66sVojGhgaKq5niu1u
2026-07-27 01:29:41 +03:00
191 changed files with 43377 additions and 1942 deletions

11
.gitignore vendored
View File

@@ -118,9 +118,20 @@ utile/hpdf/hpdferr.FPT
# --- SVN (COMUN este si working copy SVN) ---
.svn/
# --- notite neversionate in git (credentiale) - raman doar in SVN ---
docs/local/
# --- Windows / stare locala ---
*.lnk
Thumbs.db
Desktop.ini
bash.exe.stackdump
.claude/
# --- artefacte generate de rularile de test headless ---
# (numele reale poarta sufixul scenariului: screenshots_total/, uisync_212/, ...)
utile/Teste/**/screenshots*/
utile/Teste/**/uisync*/
utile/Teste/**/*_log.txt
utile/Teste/**/watchdog_out/
utile/Teste/**/*_dialog*.png

File diff suppressed because it is too large Load Diff

View File

@@ -10397,7 +10397,8 @@ DEFINE CLASS item AS container
*!* 03.10.2006
*!* MARIUS.MUTU
locauta = CautPartenerContabilitate(GetHash([cTitlu=>] + T + [??lAdaugCorespondente=>1??cTipuriParteneri=>] + lcTip))
*!* 26.07.2026 claude - verificare ANAF la alegerea partenerului pe formularele de documente
locauta = CautPartenerContabilitate(GetHash([cTitlu=>] + T + [??lAdaugCorespondente=>1??cTipuriParteneri=>] + lcTip + [??lVerificaANAF=>1]))
*!* modificare migrare v 1.0 > v 2.0
If poAct.id_set = 229
poAct.vid_part_rez = locauta.id_part

View File

@@ -564,6 +564,13 @@ DEFINE CLASS cauta_alfa_form AS _frmbase OF "_frm_base.vcx"
ENDPROC
PROCEDURE inainte_de_do_termin
If Type('This.oVerifAlegere') = 'O' And !Isnull(This.oVerifAlegere)
Return This.oVerifAlegere.VerificaAlegere(Thisform)
Endif
Return DODEFAULT()
ENDPROC
PROCEDURE Init
Lparameters tcCursor, tcNume_Proc, tcTitluColoana, tccoloana, tl_AllInList, ;
tcPrimaColoana, tnPornire, tcGridDynamicBackColor, tcGridToolTip, ;
@@ -705,6 +712,12 @@ DEFINE CLASS cauta_alfa_form AS _frmbase OF "_frm_base.vcx"
THIS.cb_tx_cautare1.SETFOCUS
KEYBOARD '{END}'
CASE nKeyCode = -3 && F4
NODEFAULT
IF TYPE('THIS.oVerifAlegere') = 'O' AND !ISNULL(THIS.oVerifAlegere)
THIS.oVerifAlegere.Detalii()
ENDIF
OTHERWISE
DODEFAULT(nKeyCode, nShiftAltCtrl)
ENDCASE

View File

@@ -1131,8 +1131,10 @@ DEFINE CLASS frm_articol_factura AS _frmbase OF "_frm_base.vcx"
*< OBJECTDATA: ObjPath="Clb_serie" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="Ed_tx_explicatie" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="cb_explicatie_saft" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="ck_pret_cu_tva" UniqueID="" Timestamp="" />
*<DefinedPropArrayMethod>
*m: do_aplica_mod_pret
*m: do_calculeaza_adaos
*m: do_calculeaza_discount
*m: do_calculeaza_pretctva
@@ -1155,7 +1157,7 @@ DEFINE CLASS frm_articol_factura AS _frmbase OF "_frm_base.vcx"
BorderStyle = 1
Caption = "Form"
DoCreate = .T.
Height = 450
Height = 500
larata = .T.
lcuadaos = .T.
lmodpretctva = .F.
@@ -1284,6 +1286,16 @@ DEFINE CLASS frm_articol_factura AS _frmbase OF "_frm_base.vcx"
_lbbase1.Top = 6
*< END OBJECT: ClassLib="lb_tx.vcx" BaseClass="container" />
ADD OBJECT 'ck_pret_cu_tva' AS _checkbox WITH ;
Alignment = 0, ;
Caption = "Pret cu TVA inclus", ;
ControlSource = "poArticol.preturi_cu_tva", ;
Left = 6, ;
Name = "ck_pret_cu_tva", ;
TabIndex = 24, ;
Top = 464
*< END OBJECT: ClassLib="_baza.vcx" BaseClass="checkbox" />
ADD OBJECT 'clb_articol' AS clb_tx_simplu WITH ;
Left = 6, ;
Name = "clb_articol", ;
@@ -1792,6 +1804,51 @@ DEFINE CLASS frm_articol_factura AS _frmbase OF "_frm_base.vcx"
_lbbase1.Top = 6
*< END OBJECT: ClassLib="lb_tx.vcx" BaseClass="container" />
PROCEDURE do_aplica_mod_pret
Lparameters lnTip && 1 = sume in lei, 2 = sume in valuta
If Inlist(poDate.tip,1,5,10,22,23,25,29,41) && documente pe baza de lista de preturi (1/5 factura lei si valuta, 10 factura fiscala in valuta, 22 aviz clienti, 23/25/41 transfer subunitati, 29 aviz clienti debitori): pretul e editabil oricum, pe restul doar daca e 0
If poArticol.preturi_cu_tva = 0
Thisform.lmodpretftva = .T.
Thisform.clb_pretftva.do_activeaza(lnTip)
Else
Thisform.lmodpretctva = .T.
Thisform.clb_pretctva.do_activeaza(lnTip)
Endif
Else
If Type('Thisform.clb_procent_adaos') = 'O'
Thisform.clb_procent_adaos.Visible = .F.
Endif
Thisform.lcuadaos = .F.
If poArticol.preturi_cu_tva = 0 And ;
((poArticol.pretftva = 0 And lnTip = 1) Or (poArticol.pretftva_val = 0 And lnTip = 2))
Thisform.lmodpretftva = .T.
Thisform.clb_pretftva.do_activeaza(lnTip)
Else
If poArticol.preturi_cu_tva = 1 And ;
((poArticol.pretctva = 0 And lnTip = 1) Or (poArticol.pretctva_val = 0 And lnTip = 2))
Thisform.lmodpretctva = .T.
Thisform.clb_pretctva.do_activeaza(lnTip)
Endif
Endif
Endif
If poArticol.preturi_cu_tva = 0
Thisform.clb_discount_unitar.do_activeaza(lnTip)
Thisform.clb_totalfdiscount.lb_explicatii.Caption = []
Thisform.clb_totalcdiscount.lb_explicatii.Caption = []
Thisform.clb_pret_diminuat.lb_explicatii.Caption = [(2) - (5)]
Else
Thisform.clb_discountctva.do_activeaza(lnTip)
Thisform.clb_totalfdiscount.lb_explicatii.Caption = [(1) * (4)]
Thisform.clb_totalcdiscount.lb_explicatii.Caption = [(1) * ( (4) - (7) )]
With Thisform.clb_pret_diminuat
.lb_explicatie.Caption = [Pret unitar diminuat cu TVA]
.lb_explicatii.Caption = [(4) - (7)]
Endwith
Endif
Thisform.ck_pret_cu_tva.Enabled = (Thisform.lmodpretftva Or Thisform.lmodpretctva)
ENDPROC
PROCEDURE do_calculeaza_adaos
Lparameters tnValoare,tnTip
If Thisform.lcuadaos
@@ -2364,54 +2421,7 @@ DEFINE CLASS frm_articol_factura AS _frmbase OF "_frm_base.vcx"
*!* *!* modificare v 2.0.46 ^
*!* modificare v 2.0.74 ^
*!* modificare v 2.0.4
*!* If Iif(Type('poArticol.modificabil')<>'U',poArticol.modificabil,0) = 1
*!* modificare v 2.0.30 : am adaugat 41
*!* modificare v 2.0.44 : am adaugat 42
*!* If Inlist(poDate.tip,1,3,5,21,22,23,25,28,29,41,42)
If Inlist(poDate.tip,1,5,10,22,23,25,29,41) && modificare v 2.0.56 : am adaugat 10
*!* modificare v 2.0.4 ^
If poArticol.preturi_cu_tva = 0
Thisform.lmodpretftva = .T.
Thisform.clb_pretftva.do_activeaza(lnTip)
Else
Thisform.lmodpretctva = .T.
*!* modificare v 2.0.4
*!* Thisform.RemoveObject('clb_procent_adaos')
*!* thisform.lcuadaos = .F.
*!* modificare v 2.0.4 ^
Thisform.clb_pretctva.do_activeaza(lnTip)
Endif
Else
Thisform.clb_procent_adaos.Visible = .F.
Thisform.lcuadaos = .F.
If poArticol.preturi_cu_tva = 0 And ;
((poArticol.pretftva = 0 And lnTip = 1) Or (poArticol.pretftva_val = 0 And lnTip = 2))
Thisform.lmodpretftva = .T.
Thisform.clb_pretftva.do_activeaza(lnTip)
Else
If poArticol.preturi_cu_tva = 1 And ;
((poArticol.pretctva = 0 And lnTip = 1) Or (poArticol.pretctva_val = 0 And lnTip = 2))
Thisform.lmodpretctva = .T.
Thisform.clb_pretctva.do_activeaza(lnTip)
Endif
Endif
Endif
If poArticol.preturi_cu_tva = 0
Thisform.clb_discount_unitar.do_activeaza(lnTip)
Thisform.clb_totalfdiscount.lb_explicatii.Caption = []
Thisform.clb_totalcdiscount.lb_explicatii.Caption = []
Thisform.clb_pret_diminuat.lb_explicatii.Caption = [(2) - (5)]
Else
Thisform.clb_discountctva.do_activeaza(lnTip)
Thisform.clb_totalfdiscount.lb_explicatii.Caption = [(1) * (4)]
Thisform.clb_totalcdiscount.lb_explicatii.Caption = [(1) * ( (4) - (7) )]
With Thisform.clb_pret_diminuat
.lb_explicatie.Caption = [Pret unitar diminuat cu TVA]
.lb_explicatii.Caption = [(4) - (7)]
Endwith
Endif
Thisform.do_aplica_mod_pret(lnTip)
*!* modificare v 2.0.19
*!* If (poDate.tip=2 And pnTipFacturare=3) Or INLIST(poDate.tip,4,23)
@@ -2570,6 +2580,19 @@ DEFINE CLASS frm_articol_factura AS _frmbase OF "_frm_base.vcx"
Thisform.UpdateExplicatieSaft()
ENDPROC
PROCEDURE ck_pret_cu_tva.InteractiveChange
Local lnTip
poArticol.preturi_cu_tva = This.Value
lnTip = Iif(poArticol.tip_valuta = 0, 1, 2)
If This.Value = 1
Thisform.do_calculeaza_pretftva(Iif(lnTip = 1, poArticol.pretctva, poArticol.pretctva_val), lnTip)
Else
Thisform.do_calculeaza_pretctva(Iif(lnTip = 1, poArticol.pretftva, poArticol.pretftva_val), lnTip)
Endif
Thisform.do_aplica_mod_pret(lnTip)
Thisform.do_calculeaza_totaluri()
ENDPROC
PROCEDURE clb_cantitate.Text_simplu1.InteractiveChange
lcval=This.ControlSource
&lcval=This.Value
@@ -3146,7 +3169,7 @@ DEFINE CLASS frm_articol_gest_factura AS frm_articol_factura OF "ofacturare.vcx"
*<PropValue>
cgridsortlist = grd_gestiuni
DoCreate = .T.
Height = 510
Height = 546
lretur = .F.
Name = "frm_articol_gest_factura"
Width = 835
@@ -3398,6 +3421,9 @@ DEFINE CLASS frm_articol_gest_factura AS frm_articol_factura OF "ofacturare.vcx"
Cb_contract._cbbase1.Top = 3
Cb_contract._cbbase1.Width = 274
Cb_contract._lbbase1.Name = "_lbbase1"
ck_pret_cu_tva.Left = 13
ck_pret_cu_tva.Name = "ck_pret_cu_tva"
ck_pret_cu_tva.Top = 510
*</PropValue>
ADD OBJECT 'Cb_tx_articol' AS cb_tx_cautare WITH ;
@@ -6949,7 +6975,9 @@ DEFINE CLASS frm_date_aviz AS _frmbase OF "_frm_base.vcx"
Endif
Otherwise
&& modificare v 2.0.93 : am adaugat 47
loCauta = CautPartenerContabilitate(GetHash([cTitlu=>Clienti??cCont=>]+Iif(INLIST(poDate.tip,42,47),[357],Iif(Inlist(poDate.tip,28,29),[461],Alltrim(gcCont411)))+[??lAdaugCorespondente=>1]))
loHash = GetHash([cTitlu=>Clienti??cCont=>]+Iif(INLIST(poDate.tip,42,47),[357],Iif(Inlist(poDate.tip,28,29),[461],Alltrim(gcCont411)))+[??lAdaugCorespondente=>1??lVerificaANAF=>1])
loHash.SetValue('dDataDoc', Iif(Type('poDate.dataact') = 'D', poDate.dataact, {}))
loCauta = CautPartenerContabilitate(loHash)
If !Empty(Nvl(loCauta.id_part,0)) And !Empty(loCauta.denumire)
poDate.id_client = loCauta.id_part
poDate.nume_client = loCauta.denumire
@@ -7906,7 +7934,9 @@ DEFINE CLASS frm_date_aviz_lucrare AS _frmbase OF "_frm_base.vcx"
PROCEDURE do_cauta_furnizor
Local loCauta
*!* loCauta = CautPartenerContabilitate(GetHash([cTitlu=>Alegeti furnizorul??cCont=>401??lAdaugCorespondente=>1]))
loCauta = CautPartenerContabilitate(GetHash([cTitlu=>Alegeti furnizorul??cCont=>401]))
loHash = GetHash([cTitlu=>Alegeti furnizorul??cCont=>401??lVerificaANAF=>1])
loHash.SetValue('dDataDoc', Iif(Type('poDate.dataact') = 'D', poDate.dataact, {}))
loCauta = CautPartenerContabilitate(loHash)
If !Empty(loCauta.id_part) And !Empty(loCauta.denumire) AND !ISNULL(loCauta.id_part)
poDate.id_furnizor = loCauta.id_part
poDate.furnizor = Alltrim(loCauta.denumire)
@@ -8970,7 +9000,9 @@ DEFINE CLASS frm_date_factura AS _frmbase OF "_frm_base.vcx"
PROCEDURE do_cauta_client
Local loCauta
loCauta = CautPartenerContabilitate(GetHash([cTitlu=>Clienti??cCont=>4111??lAdaugCorespondente=>1]))
loHash = GetHash([cTitlu=>Clienti??cCont=>4111??lAdaugCorespondente=>1??lVerificaANAF=>1])
loHash.SetValue('dDataDoc', Iif(Type('poDate.dataact') = 'D', poDate.dataact, {}))
loCauta = CautPartenerContabilitate(loHash)
If !Empty(Nvl(loCauta.id_part,0)) And !Empty(loCauta.denumire)
If loCauta.id_part <> poDate.id_client
poDate.listaid = []
@@ -11042,6 +11074,7 @@ DEFINE CLASS frm_facturare_articole AS _frmbase OF "_frm_base.vcx"
*< OBJECTDATA: ObjPath="grd_contracte.cNumar_contract.Text1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="grd_contracte.cCodbare.Header1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="grd_contracte.cCodbare.Text1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="But_modifica1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="But_sterge1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="lb_total_mod" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="Gridextra1" UniqueID="" Timestamp="" />
@@ -11156,6 +11189,16 @@ DEFINE CLASS frm_facturare_articole AS _frmbase OF "_frm_base.vcx"
Gridsort1.Top = 36
*</PropValue>
ADD OBJECT 'But_modifica1' AS but_modifica WITH ;
Anchor = 9, ;
caction = do_modifica, ;
Left = 773, ;
Name = "But_modifica1", ;
TabIndex = 13, ;
Top = 61, ;
Visible = .T.
*< END OBJECT: ClassLib="cmd_butoane.vcx" BaseClass="commandbutton" />
ADD OBJECT 'But_renunt1' AS but_renunt WITH ;
Anchor = 8, ;
Height = 27, ;
@@ -13155,12 +13198,15 @@ DEFINE CLASS frm_facturare_articole AS _frmbase OF "_frm_base.vcx"
ENDPROC
PROCEDURE do_alege_stoc
Lparameters tnIdArticol,tnCantitate,tcNumeArticol,tlImplicit,tnPret,tnDiscount,toGrid, tlRetur
Lparameters tnIdArticol,tnCantitate,tcNumeArticol,tlImplicit,tnPret,tnDiscount,toGrid, tlRetur, tnIdTempExclus
* llImplicit => vezi thisform.do_adauga
* tnPret => doar pentru retururi : e pretul de vanzare fara TVA
* toGrid => gridul din care vine articolul
* tlRetur => factura normala cu articol retur (nu factura de retur tip 8,9). se comporta la fel ca factura de retur. se selecteaza din RUL, dar nu stiu factura din care fac retur
* tnIdTempExclus => id_temp-ul liniei modificate, exclus din cantitatea deja retinuta pe factura (0 la adaugare)
If Type('tnIdTempExclus') <> 'N'
tnIdTempExclus = 0
Endif
Private pnIdArticol
Local llReturn,lofrmadarticol,lcSql, llFacturareFaraStoc
llFactuareFaraStoc = .F.
@@ -13226,7 +13272,7 @@ DEFINE CLASS frm_facturare_articole AS _frmbase OF "_frm_base.vcx"
* Arat cantitatile din stoc - cantitatile deja pe factura curenta
Select Iif(poDate.tip=41,-1,1)*Sum(cantitate) As cantitate,id_articol,id_gestiune,pret_achizitie,serie,lot,Cont, ;
id_part_rez,id_lucrare_rez,pretv_orig,pretd,id_valuta_d ;
FROM crsfactura Where id_articol = pnIdArticol ;
FROM crsfactura Where id_articol = pnIdArticol And id_temp <> tnIdTempExclus ;
GROUP By id_articol,id_gestiune,pret_achizitie,serie,lot,Cont,id_part_rez,id_lucrare_rez,pretv_orig,pretd,id_valuta_d ;
INTO CURSOR crsFacturaArticoleTemp
@@ -13269,6 +13315,12 @@ DEFINE CLASS frm_facturare_articole AS _frmbase OF "_frm_base.vcx"
SELECT (m.lcCursor)
Go Top
If tnIdTempExclus > 0
Locate For id_gestiune = poArticol.id_gestiune And Pret = poArticol.pret_achizitie And Cont = poArticol.Cont And Nvl(serie,'') = Nvl(poArticol.serie,'') And Nvl(lot,'') = Nvl(poArticol.lot,'') And Nvl(id_part_rez,0) = Nvl(poArticol.id_part_rez,0) And Nvl(id_lucrare_rez,0) = Nvl(poArticol.id_lucrare_rez,0) And pretv = poArticol.pretv_orig And pretd = poArticol.pretd And Nvl(id_valuta,0) = Nvl(poArticol.id_valuta_d,0)
If !Found()
Go Top
Endif
Endif
Do Case
Case Reccount(lcCursor) = 0
amessagebox("Articolul "+Alltrim(tcNumeArticol)+" nu mai este pe stoc!",0+48,"Atentie")
@@ -13691,6 +13743,176 @@ DEFINE CLASS frm_facturare_articole AS _frmbase OF "_frm_base.vcx"
*!* modificare v 2.0.67 ^
ENDPROC
PROCEDURE do_modifica
If Reccount('crsfactura')>0
Private poArticol, pnProcentDiscountMem
Local lnRecno, ofrmadarticol
Select crsfactura
lnRecno = Recno()
Scatter Name poArticol MEMO
AddProperty(poArticol,'preturi_cu_tva',poArticol.cu_tva)
AddProperty(poArticol,'discount_unitar',poArticol.discountftva)
AddProperty(poArticol,'discount_unitar_ctva',poArticol.discountctva)
AddProperty(poArticol,'pretftva_val',poArticol.vpretftva)
AddProperty(poArticol,'pretctva_val',poArticol.vpretctva)
AddProperty(poArticol,'discount_unitar_val',poArticol.vdiscountftva)
AddProperty(poArticol,'discount_unitar_ctva_val',poArticol.vdiscountctva)
Removeproperty(poArticol,'cu_tva')
Removeproperty(poArticol,'discountftva')
Removeproperty(poArticol,'discountctva')
Removeproperty(poArticol,'vpretftva')
Removeproperty(poArticol,'vpretctva')
Removeproperty(poArticol,'vdiscountftva')
Removeproperty(poArticol,'vdiscountctva')
AddProperty(poArticol,'tva',poArticol.pretctva - poArticol.pretftva)
AddProperty(poArticol,'tva_val',poArticol.pretctva_val - poArticol.pretftva_val)
pnProcentDiscountMem = 0
If Nvl(gnMemProcDisc, 0) = 1
pnProcentDiscountMem = Thisform.nproc_disc_mem
Endif
* plafonul de cantitate = stocul disponibil reconstituit din cursorul sursa; fara randul in cursor ramane cantitatea liniei
Local lnCantitateMax, lcCursorStoc, lcAliasCrt, lnRecnoStoc, lnCantitateVeche, lnIdTempLinie, lnDeltaCantitate, lnTotalCantitate
lnCantitateMax = poArticol.cantitate
lcCursorStoc = Iif(poArticol.opt_facturare = 0, [crsarticole], [crsarticole1])
If Used(lcCursorStoc)
lcAliasCrt = Alias()
Select (lcCursorStoc)
lnRecnoStoc = Recno()
Locate For id_c = poArticol.id_c
If Found()
Do Case
Case (gnScadereStoc = 1 And poDate.tip = 23) Or Inlist(poDate.tip, 4, 21, 28, 42, 47) && adaugarea scade stocul; lista e cea validata la plafon (fara 3 si 25): 23 transfer subunitati, 4 din avize, 21/28/42/47 catre clienti
lnCantitateMax = cantitate + poArticol.cantitate
Case Inlist(poDate.tip, 8, 9, 24) && adaugarea creste stocul: 8/9 retur factura in lei si in valuta, 24 aviz de retur
lnCantitateMax = cantitate - poArticol.cantitate
Endcase
Endif
Try
Go lnRecnoStoc
Catch
Go Top
Endtry
Select (lcAliasCrt)
Endif
gnButon = 2
lnCantitateVeche = poArticol.cantitate
lnIdTempLinie = poArticol.id_temp
Do Case
Case (poArticol.gestionabil = 0 Or gnScadereStoc = 0 Or poDate.tip = 45) && 45 = ROARESTAURANT
ofrmadarticol = Createobject("frm_articol_factura", lnCantitateMax, .F.)
ofrmadarticol.Show(1)
Release ofrmadarticol
Otherwise
Thisform.do_alege_stoc(poArticol.id_articol, lnCantitateMax, poArticol.denumire, .F., poArticol.pretftva, poArticol.discount_unitar, Thisform.grd_factura, .F., lnIdTempLinie)
Endcase
If gnButon = 1
Select crsfactura
Try
Go lnRecno
Catch
Go Top
Endtry
If Used('crsartselectate')
lnTotalCantitate = poArticol.cantitate
Select crsartselectate
Go Top
poArticol.pret_achizitie = Pret
poArticol.serie = Nvl(serie, [])
poArticol.lot = Nvl(lot, [])
poArticol.id_gestiune = id_gestiune
poArticol.Cont = Alltrim(Cont)
poArticol.cantitate = cantitate
poArticol.pretv_orig = pretv
poArticol.id_lucrare_rez = id_lucrare_rez
poArticol.id_part_rez = id_part_rez
poArticol.pretd = pretd
poArticol.id_valuta_d = id_valuta
Select crsfactura
Endif
Gather Name poArticol Fields Like pret_achizitie, denumire, cantitate, id_articol, Id_Pol, Cont, id_gestiune, Proc_Tvav, ;
pretftva, valftva, valtva, valctva, valdiscountftva, valdiscounttva, valdiscountctva, Pretctva, ;
valdiminuatftva, valdiminuattva, valdiminuatctva, ;
vvalftva, vvaltva, vvalctva, vvaldiscountftva, vvaldiscounttva, vvaldiscountctva, ;
vvaldiminuatftva, vvaldiminuattva, vvaldiminuatctva, id_c, lot, serie, explicatie, ;
id_valuta, gestionabil, tip_valuta, id_jtva_coloana, taxcode, id_lucrare_rez, id_part_rez, pretv_orig, pretd, id_valuta_d, id_ctr, opt_facturare, nume_val MEMO
Replace cu_tva With poArticol.preturi_cu_tva, ;
discountftva With poArticol.discount_unitar, discountctva With poArticol.discount_unitar_ctva, ;
vpretftva With Nvl(poArticol.pretftva_val,0), vpretctva With Nvl(poArticol.pretctva_val,0), ;
vdiscountftva With Nvl(poArticol.discount_unitar_val,0), vdiscountctva With Nvl(poArticol.discount_unitar_ctva_val,0)
If Used('crsartselectate')
Select crsartselectate
Skip
Scan Rest
poArticol.pret_achizitie = Pret
poArticol.serie = Nvl(serie, [])
poArticol.lot = Nvl(lot, [])
poArticol.id_gestiune = id_gestiune
poArticol.Cont = Alltrim(Cont)
poArticol.cantitate = cantitate
poArticol.pretv_orig = pretv
poArticol.id_lucrare_rez = id_lucrare_rez
poArticol.id_part_rez = id_part_rez
poArticol.pretd = pretd
poArticol.id_valuta_d = id_valuta
Select crsfactura
Append Blank
Gather Name poArticol Fields Like pret_achizitie, denumire, cantitate, id_articol, Id_Pol, ;
Cont, id_gestiune, Proc_Tvav, pretftva, Pretctva, ;
id_c, lot, serie, explicatie, ;
id_valuta, gestionabil, tip_valuta, id_jtva_coloana, taxcode, id_lucrare_rez, id_part_rez, pretv_orig, pretd, id_valuta_d, nume_val, id_ctr, opt_facturare MEMO
Replace id_temp With Recno(), codmat With Nvl(poArticol.codmat, Space(50)), ;
codbare With Nvl(poArticol.codbare, Space(50)), ;
codmatf With Nvl(poArticol.codmatf, Space(50)), um With Nvl(poArticol.um, Space(50)), ;
Curs With Nvl(poArticol.Curs, 0), multiplicator With Nvl(poArticol.multiplicator, 1), ;
cu_tva With poArticol.preturi_cu_tva, ;
vpretftva With Nvl(poArticol.pretftva_val, 0), vpretctva With Nvl(poArticol.pretctva_val, 0), ;
discountftva With poArticol.discount_unitar, discountctva With poArticol.discount_unitar_ctva, ;
vdiscountftva With Nvl(poArticol.discount_unitar_val, 0), ;
vdiscountctva With Nvl(poArticol.discount_unitar_ctva_val, 0)
poArticol = calculeaza_totaluri(poArticol)
Gather Name poArticol Fields Like valftva, valtva, valctva, ;
valdiscountftva, valdiscounttva, valdiscountctva, ;
valdiminuatftva, valdiminuattva, valdiminuatctva, ;
vvalftva, vvaltva, vvalctva, ;
vvaldiscountftva, vvaldiscounttva, vvaldiscountctva, ;
vvaldiminuatftva, vvaldiminuattva, vvaldiminuatctva MEMO
Endscan
Use In crsartselectate
poArticol.cantitate = lnTotalCantitate
Select crsfactura
Endif
lnDeltaCantitate = poArticol.cantitate - lnCantitateVeche
If lnDeltaCantitate <> 0 And Used(lcCursorStoc)
lcAliasCrt = Alias()
Select (lcCursorStoc)
lnRecnoStoc = Recno()
Do Case
Case (gnScadereStoc = 1 And poDate.tip = 23) Or Inlist(poDate.tip, 4, 21, 28, 42, 47)
Replace cantitate With cantitate - lnDeltaCantitate For id_c = poArticol.id_c
Case Inlist(poDate.tip, 8, 9, 24)
Replace cantitate With cantitate + lnDeltaCantitate For id_c = poArticol.id_c
Endcase
Try
Go lnRecnoStoc
Catch
Go Top
Endtry
Select (lcAliasCrt)
Endif
If Nvl(gnMemProcDisc, 0) = 1
Thisform.nproc_disc_mem = pnProcentDiscountMem
Endif
Thisform.do_calculeaza_totaluri()
Thisform.grd_factura.Refresh()
Thisform.grd_factura.SetFocus()
Endif
Release poArticol, pnProcentDiscountMem
Endif
ENDPROC
PROCEDURE do_renunt
*!* modificare 19.01.2007
DODEFAULT()
@@ -14000,7 +14222,6 @@ DEFINE CLASS frm_facturare_articole AS _frmbase OF "_frm_base.vcx"
pnParametruAditional = 0
llReturn = .T.
lcListaIncasare = ''
SET STEP ON
llEproforma = (poDate.eProforma = 1)
If Inlist(poDate.ntip_incasare, 11, 2, 3) && 11 = CHITANTA, 2 = BON FISCAL, 3 = POS/Card
@@ -15507,6 +15728,10 @@ DEFINE CLASS frm_facturare_articole AS _frmbase OF "_frm_base.vcx"
*Nu sterge
ENDPROC
PROCEDURE grd_factura.DblClick
Thisform.do_modifica()
ENDPROC
PROCEDURE grd_factura.Init
*Nu sterge
ENDPROC

View File

@@ -150,7 +150,7 @@ DEFINE CLASS frm_borderou_facturi AS _frmbase OF "_frm_base.vcx"
ADD OBJECT 'Cmd_executa1' AS cmd_executa WITH ;
Anchor = 6, ;
Caption = "Marcheaz<61> \<trimis", ;
Caption = "Marcheaz<61> \<trimis", ;
ForeColor = 0,128,0, ;
Height = 27, ;
Left = 140, ;
@@ -1334,8 +1334,10 @@ DEFINE CLASS frm_facturi AS _frmbase OF "_frm_base.vcx"
*< OBJECTDATA: ObjPath="But_attach1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="But_listare1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="But_verifica1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="But_editare1" UniqueID="" Timestamp="" />
*<DefinedPropArrayMethod>
*m: do_editare_factura
*m: do_listare_cc
*m: do_listare_centr
*m: do_listare_document
@@ -1350,7 +1352,7 @@ DEFINE CLASS frm_facturi AS _frmbase OF "_frm_base.vcx"
*<PropValue>
BorderStyle = 1
cbuton2 = but_listare1;but_listare2;But_listare3
cbuton3 = but_modifica1;but_modifica2
cbuton3 = but_modifica1;but_modifica2;But_editare1
cfiltru_initial =
cgridsortlist = grid_facturi,grid_detalii
DoCreate = .T.
@@ -1410,6 +1412,17 @@ DEFINE CLASS frm_facturi AS _frmbase OF "_frm_base.vcx"
Visible = .F.
*< END OBJECT: ClassLib="cmd_butoane.vcx" BaseClass="commandbutton" />
ADD OBJECT 'But_editare1' AS but_modifica WITH ;
Anchor = 12, ;
caction = do_editare_factura, ;
Caption = "", ;
Left = 650, ;
Name = "But_editare1", ;
TabIndex = 29, ;
ToolTipText = "Editare factura (articole, cantitati, preturi)", ;
Top = 341
*< END OBJECT: ClassLib="cmd_butoane.vcx" BaseClass="commandbutton" />
ADD OBJECT 'But_listare1' AS but_listare WITH ;
Anchor = 8, ;
Left = 698, ;
@@ -3471,7 +3484,7 @@ DEFINE CLASS frm_facturi AS _frmbase OF "_frm_base.vcx"
Anchor = 12, ;
AutoSize = .T., ;
BackStyle = 0, ;
Caption = "Total <20>n valuta", ;
Caption = "Total <20>n valuta", ;
FontSize = 10, ;
Height = 18, ;
Left = 311, ;
@@ -3711,6 +3724,150 @@ DEFINE CLASS frm_facturi AS _frmbase OF "_frm_base.vcx"
This.do_cauta()
ENDPROC
PROCEDURE do_editare_factura
If !This.lactiv3
Return
Endif
If Reccount('crsfacturi') = 0
amessagebox("Nu exista inregistrari pentru editare!",0+48,"Atentie")
Return
Endif
If glLunaInchisa
Return
Endif
Local lnSters, llEProforma, lnIdSet, lnIdFactD, lnSucces, Omodif, llGasitRand
Private pnAn, pnLuna, lnCod, lnIdFact, lnIdVanzare
Store 0 To pnAn, pnLuna, lnCod, lnIdFact, lnIdSet, lnIdFactD, lnIdVanzare
Select crsfacturi
lnIdVanzare = id_vanzare
lnCod = cod
pnAn = Year(data_act)
pnLuna = Month(data_act)
lnSters = sters
lnIdFact = id_fact
llEProforma = (eproforma = 1)
If lnSters = 1
amessagebox("Acest document este deja sters!",0+48,"Atentie")
Return
Endif
If llEProforma
amessagebox("Proformele nu pot fi editate pe aceasta cale!",0+48,"Atentie")
Return
Endif
If (pnAn * 12) + pnLuna <> (gnAn * 12) + gnLuna
amessagebox('Nu puteti edita decat inregistrari din luna curenta!',0,'Atentie!')
Return
Endif
*** verificare restrictie editare documente cu referinte (incasari/plati)
If ReferinteDocumenteNota(pnAn, pnLuna, lnCod) && odocumente.prg
amessagebox("Documentul are referinte (incasari/plati). Nu poate fi editat.", 0+48,"Editare")
Return
Endif
*** verificare restrictie editare facturi trimise in eFactura
If EsteInEFactura(lnIdFact) && ofacturare_editare.prg
amessagebox("Documentul a fost trimis in eFactura. Nu poate fi editat.", 0+48,"Editare")
Return
Endif
If IncarcaCursoareModificareNota(lnCod, pnAn, pnLuna, .F.) && ofacturare_editare.prg
If Reccount('actactan') = 0
amessagebox("Nu exista nota contabila pentru aceasta factura.",0+48,"Atentie")
Else
Select actactan
llGasitRand = .F.
If lnIdFact > 0
Locate For Nvl(id_fact, 0) = lnIdFact
llGasitRand = Found()
Endif
If !llGasitRand
*** rezerva: nota nu contine id_fact-ul din vanzari (avize, transferuri, documente vechi)
Go Top
lnIdFact = id_fact
Endif
lnIdSet = id_set
lnIdFactD = id_factd
Select a.*, Iif(Nvl(id_jtva_coloana,0)=0,0,1) As cu_Tva From tact a Into Cursor tact Readwrite
Select tact
Omodif = Createobject([frm_modific2024], lnIdSet)
Omodif.Show()
If buton = 1
If Thisform.do_deschide_tranzactie()
Select actactan
lnSucces = OSCRIE_IN_FISIERE(2,.T.,.T.)
If lnSucces > 0
If Used('actactan')
Use In actactan
Endif
Select tact
Replace id_jtva_coloana With Null, proc_tva With 0 For cu_Tva = 0
Select * From tact Into Cursor actactan Readwrite
Replace All id_util With gnIdUtil, sters With 0
If Used('rul_temp')
Use In rul_temp
Endif
Select * From trul Into Cursor RUL_TEMP Readwrite
Replace All id_util With gnIdUtil, sters With 0
If Used('rul_temp_obinv')
Use In rul_temp_obinv
Endif
Select * From trul_obinv Into Cursor RUL_TEMP_OBINV Readwrite
Replace All id_util With gnIdUtil, sters With 0
lnSucces = OSCRIE_IN_FISIERE(0,.T.,.T.)
Endif
If lnSucces > 0
lcSql = [begin pack_contafin.finalizeaza_modificare_nota(?pnLuna,?pnAn,Null,] + Alltrim(Str(lnIdSet)) + [,] + ;
Alltrim(Str(lnCod)) + [,] + Alltrim(Str(lnIdFact)) + [,] + Alltrim(Str(lnIdFactD)) + [,?gnIdUtil); end;]
lnSucces = Iif(goExecutor.oExecuta(lcSql),1,-1)
Endif
If Thisform.do_inchide_tranzactie(Iif(lnSucces<0,2,1))
If lnSucces > 0
Thisform.do_cauta()
Endif
Endif
Endif
Endif
Endif
If Used('actactan')
Use In actactan
Endif
If Used('tact')
Use In tact
Endif
If Used('rul_temp')
Use In rul_temp
Endif
If Used('trul')
Use In trul
Endif
If Used('rul_temp_obinv')
Use In rul_temp_obinv
Endif
If Used('trul_obinv')
Use In trul_obinv
Endif
Endif
Select crsfacturi
Locate For id_vanzare = lnIdVanzare
If !Found()
Go Top
Endif
ENDPROC
PROCEDURE do_listare
*!* 26.11.2019
*!* marius.mutu
@@ -4333,7 +4490,6 @@ DEFINE CLASS frm_facturi AS _frmbase OF "_frm_base.vcx"
Select crsdetalii
Calculate Max(proc_tvav) To lnProcTvav
SET STEP ON
creeaza_facturacrs([crsfactura])
prelucreaza_facturacrs([crsdetalii], [crsfactura], lnProcTvav, lnDiscount, lnDiscountVal)
@@ -4382,7 +4538,6 @@ DEFINE CLASS frm_facturi AS _frmbase OF "_frm_base.vcx"
PROCEDURE do_modifica
Local ofrmmodificare As "frm_modifica_factura"
Local lcSql, lnSucces
SET STEP ON
PRIVATE poRec, pneFactura
If Reccount('crsfacturi') > 0
Local lnRecno, lnNrInreg, lnNrInregMod
@@ -4990,7 +5145,7 @@ DEFINE CLASS frm_modifica_articol_factura AS frm_termin_renunt OF "_frm_child.vc
_shape2.Top = 0
_shape2.Width = 64
_shape2.ZOrderSet = 2
Lb_titlu_alb_b121.Caption = "Modific<69> explica<63>ie articol"
Lb_titlu_alb_b121.Caption = "Modific<69> explica<63>ie articol"
Lb_titlu_alb_b121.Name = "Lb_titlu_alb_b121"
Lb_titlu_alb_b121.TabIndex = 5
Lb_titlu_alb_b121.ZOrderSet = 3
@@ -5048,7 +5203,7 @@ DEFINE CLASS frm_modifica_articol_factura AS frm_termin_renunt OF "_frm_child.vc
_edbase1.Name = "_edbase1", ;
_edbase1.Top = 23, ;
_edbase1.Width = 325, ;
_lbbase1.Caption = "Explica<63>ie", ;
_lbbase1.Caption = "Explica<63>ie", ;
_lbbase1.Name = "_lbbase1"
*< END OBJECT: ClassLib="lb_tx.vcx" BaseClass="container" />
@@ -5282,7 +5437,7 @@ DEFINE CLASS frm_modifica_factura AS frm_termin_renunt OF "_frm_child.vcx"
Text_simplu1.Name = "Text_simplu1", ;
Text_simplu1.Top = 3, ;
Text_simplu1.Width = 177, ;
Lb_simplu1.Caption = "Data <20>i ora expedierii", ;
Lb_simplu1.Caption = "Data <20>i ora expedierii", ;
Lb_simplu1.Name = "Lb_simplu1"
*< END OBJECT: ClassLib="lb_tx.vcx" BaseClass="container" />
@@ -5332,7 +5487,7 @@ DEFINE CLASS frm_modifica_factura AS frm_termin_renunt OF "_frm_child.vcx"
Top = 128, ;
ZOrderSet = 9, ;
img_cautare.Name = "img_cautare", ;
clb_tx_cautare.Lb_simplu1.Caption = "Ma<4D>ina", ;
clb_tx_cautare.Lb_simplu1.Caption = "Ma<4D>ina", ;
clb_tx_cautare.Lb_simplu1.Name = "Lb_simplu1", ;
clb_tx_cautare.Name = "clb_tx_cautare", ;
clb_tx_cautare.Text_simplu1.Left = 133, ;
@@ -6822,7 +6977,7 @@ DEFINE CLASS frm_proforme AS _frmbase OF "_frm_base.vcx"
Anchor = 12, ;
AutoSize = .T., ;
BackStyle = 0, ;
Caption = "Total <20>n valuta", ;
Caption = "Total <20>n valuta", ;
FontSize = 10, ;
Height = 18, ;
Left = 311, ;
@@ -6854,7 +7009,7 @@ DEFINE CLASS frm_proforme AS _frmbase OF "_frm_base.vcx"
OPTION1.Top = 5, ;
OPTION1.Value = 1, ;
OPTION2.AutoSize = .T., ;
OPTION2.Caption = "<22>n valuta", ;
OPTION2.Caption = "<22>n valuta", ;
OPTION2.FontCharSet = 238, ;
OPTION2.FontSize = 10, ;
OPTION2.Left = 55, ;
@@ -6862,7 +7017,7 @@ DEFINE CLASS frm_proforme AS _frmbase OF "_frm_base.vcx"
OPTION2.Top = 5, ;
Option3.AutoSize = .T., ;
Option3.BackStyle = 0, ;
Option3.Caption = "<22>n RON", ;
Option3.Caption = "<22>n RON", ;
Option3.FontCharSet = 238, ;
Option3.FontSize = 10, ;
Option3.Height = 18, ;
@@ -6893,7 +7048,7 @@ DEFINE CLASS frm_proforme AS _frmbase OF "_frm_base.vcx"
OPTION1.Top = 5, ;
OPTION1.Value = 0, ;
OPTION2.AutoSize = .T., ;
OPTION2.Caption = "<22>terse", ;
OPTION2.Caption = "<22>terse", ;
OPTION2.FontCharSet = 238, ;
OPTION2.FontSize = 10, ;
OPTION2.ForeColor = 255,0,0, ;
@@ -6902,7 +7057,7 @@ DEFINE CLASS frm_proforme AS _frmbase OF "_frm_base.vcx"
OPTION2.Top = 5, ;
Option3.AutoSize = .T., ;
Option3.BackStyle = 0, ;
Option3.Caption = "Ne<4E>terse", ;
Option3.Caption = "Ne<4E>terse", ;
Option3.FontCharSet = 238, ;
Option3.FontSize = 10, ;
Option3.Height = 18, ;

View File

@@ -22,6 +22,7 @@ DEFINE CLASS frm_date_rapoarte_articole AS _frmbase OF "_frm_base.vcx"
*< OBJECTDATA: ObjPath="Ct_selectie1.Ct_selectie_nume_client" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="Ct_selectie1.Ct_selectie_serie" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="Ct_selectie1.Ct_selectie_numar_act" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="Ct_selectie1.Ct_selectie_cont" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="But_listare1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="But_excel1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="Ct_opt_categorie" UniqueID="" Timestamp="" />
@@ -243,9 +244,9 @@ DEFINE CLASS frm_date_rapoarte_articole AS _frmbase OF "_frm_base.vcx"
*< END OBJECT: ClassLib="caut_ora.vcx" BaseClass="container" />
ADD OBJECT 'Ct_selectie1' AS ct_selectie WITH ;
ccoloanesuma = cantitate,valoare_ftva,valoare, ;
ccoloanesuma = cantitate|valoare_ftva|valoare, ;
clistacoloaneordine = 1,2, ;
cnumecoloanesuma = Cantitate,Valoare fara TVA,Valoare cu TVA, ;
cnumecoloanesuma = Cantitate|Valoare fara TVA|Valoare cu TVA, ;
cnumetabela = fact_vrap_fact_articole, ;
Height = 384, ;
Left = 24, ;
@@ -292,6 +293,18 @@ DEFINE CLASS frm_date_rapoarte_articole AS _frmbase OF "_frm_base.vcx"
ck_camp.Name = "ck_camp"
*< END OBJECT: ClassLib="orapoarte.vcx" BaseClass="container" />
ADD OBJECT 'Ct_selectie1.Ct_selectie_cont' AS ct_selectie_camp WITH ;
ccamp = cont, ;
cnumecamp = Cont, ;
Left = 120, ;
Name = "Ct_selectie_cont", ;
nid_container = 8, ;
TabIndex = 9, ;
Top = 57, ;
ck_camp.Alignment = 0, ;
ck_camp.Name = "ck_camp"
*< END OBJECT: ClassLib="orapoarte.vcx" BaseClass="container" />
ADD OBJECT 'Ct_selectie1.Ct_selectie_data_act' AS ct_selectie_camp WITH ;
ccamp = data_act, ;
cnumecamp = Data factura, ;
@@ -927,9 +940,9 @@ DEFINE CLASS frm_date_rapoarte_articole_tr AS frm_termin OF "_frm_child.vcx"
*< END OBJECT: ClassLib="caut_ora.vcx" BaseClass="container" />
ADD OBJECT 'Ct_selectie1' AS ct_selectie WITH ;
ccoloanesuma = adaos,cantitate,valoare_ftva,valoare,val_achizitie, ;
ccoloanesuma = adaos|cantitate|valoare_ftva|valoare|val_achizitie, ;
clistacoloaneordine = 1,2,3,4, ;
cnumecoloanesuma = Adaos,Cantitate,Valoare fara TVA,Valoare cu TVA,Valoare achizitie, ;
cnumecoloanesuma = Adaos|Cantitate|Valoare fara TVA|Valoare cu TVA|Valoare achizitie, ;
cnumetabela = fact_vrap_articole_transfer, ;
Height = 158, ;
Left = 7, ;
@@ -1576,6 +1589,7 @@ DEFINE CLASS frm_date_rapoarte_articole_v AS frm_termin OF "_frm_child.vcx"
*< OBJECTDATA: ObjPath="Ct_selectie1.Ct_selectie_procent_adaos" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="Ct_selectie1.Ct_selectie_valoare_achizitie" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="Ct_selectie1.Ct_selectie_valoare_adaos" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="Ct_selectie1.Ct_selectie_cont" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="Ct_opt_categorie" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="Ct_opt_grupa" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="Ct_opt_subgrupa" UniqueID="" Timestamp="" />
@@ -1794,9 +1808,9 @@ DEFINE CLASS frm_date_rapoarte_articole_v AS frm_termin OF "_frm_child.vcx"
ADD OBJECT 'Ct_selectie1' AS ct_selectie WITH ;
Anchor = 15, ;
ccoloanesuma = cantitate,valoare_ftva,valoare, ;
ccoloanesuma = cantitate|valoare_ftva|valoare, ;
clistacoloaneordine = 1,2, ;
cnumecoloanesuma = Cantitate,Valoare fara TVA, Valoare cu TVA, ;
cnumecoloanesuma = Cantitate|Valoare fara TVA| Valoare cu TVA, ;
cnumetabela = fact_vrap_articole_vandute, ;
Height = 479, ;
Left = 4, ;
@@ -1857,6 +1871,18 @@ DEFINE CLASS frm_date_rapoarte_articole_v AS frm_termin OF "_frm_child.vcx"
ck_camp.Name = "ck_camp"
*< END OBJECT: ClassLib="orapoarte.vcx" BaseClass="container" />
ADD OBJECT 'Ct_selectie1.Ct_selectie_cont' AS ct_selectie_camp WITH ;
ccamp = cont, ;
cnumecamp = Cont, ;
Left = 248, ;
Name = "Ct_selectie_cont", ;
nid_container = 15, ;
TabIndex = 8, ;
Top = 57, ;
ck_camp.Alignment = 0, ;
ck_camp.Name = "ck_camp"
*< END OBJECT: ClassLib="orapoarte.vcx" BaseClass="container" />
ADD OBJECT 'Ct_selectie1.Ct_selectie_data_act' AS ct_selectie_camp WITH ;
ccamp = data_act, ;
cnumecamp = Data factura, ;
@@ -2041,7 +2067,6 @@ DEFINE CLASS frm_date_rapoarte_articole_v AS frm_termin OF "_frm_child.vcx"
Thisform.clb_data_referinta.SetFocus()
Return
Otherwise
SET STEP ON
With This.ct_selectie1
.do_instructiune_sql()
lcSql = .csql
@@ -2544,9 +2569,9 @@ DEFINE CLASS frm_date_rapoarte_avize AS _frmbase OF "_frm_base.vcx"
*< END OBJECT: ClassLib="caut_ora.vcx" BaseClass="container" />
ADD OBJECT 'Ct_selectie1' AS ct_selectie WITH ;
ccoloanesuma = avizat,facturat, ;
ccoloanesuma = avizat|facturat, ;
clistacoloaneordine = 1, ;
cnumecoloanesuma = Valoare avizata,Valoare facturata, ;
cnumecoloanesuma = Valoare avizata|Valoare facturata, ;
cnumetabela = fact_vrap_avize_fact, ;
Height = 408, ;
Left = 24, ;
@@ -3202,7 +3227,7 @@ DEFINE CLASS frm_date_rapoarte_avize_tr AS _frmbase OF "_frm_base.vcx"
ADD OBJECT 'Ct_selectie1' AS ct_selectie WITH ;
ccoloanesuma = avizat, ;
clistacoloaneordine = 1, ;
cnumecoloanesuma = Valoare avizata,Valoare facturata, ;
cnumecoloanesuma = Valoare avizata|Valoare facturata, ;
cnumetabela = fact_vrap_avize_transfer, ;
Height = 408, ;
Left = 24, ;
@@ -3802,9 +3827,9 @@ DEFINE CLASS frm_date_rapoarte_facturi AS _frmbase OF "_frm_base.vcx"
*< END OBJECT: ClassLib="caut_ora.vcx" BaseClass="container" />
ADD OBJECT 'Ct_selectie1' AS ct_selectie WITH ;
ccoloanesuma = facturat,incasat, ;
ccoloanesuma = facturat|incasat, ;
clistacoloaneordine = 1, ;
cnumecoloanesuma = Valoare facturata,Valoare incasata, ;
cnumecoloanesuma = Valoare facturata|Valoare incasata, ;
cnumetabela = fact_vrap_fact_incasari, ;
Height = 444, ;
Left = 24, ;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -25,7 +25,7 @@ DEFINE CLASS actualizare_curs_bnr AS _custom OF "_baza.vcx"
*<PropValue>
ccursor = ccrsbnr
clink = https://www.bnr.ro/nbrfxrates.xml
clink = https://curs.bnr.ro/nbrfxrates.xml
ctempfile = C:\temp\temp.xml
ddata = {}
Height = 17

View File

@@ -6965,6 +6965,7 @@ DEFINE CLASS frm_note_contabile2007_nou AS _frmbase OF "_frm_base.vcx"
WITH loHash
.SetValue("cTitlu", "Alege<67>i partenerul")
.SetValue("cCont", lcCont)
.SetValue("lVerificaANAF", .T.) && 26.07.2026 claude - verificare ANAF la alegerea partenerului
ENDWITH
loPartener = CautPartenerContabilitate(loHash)

View File

@@ -832,7 +832,6 @@ DEFINE CLASS ct_selectie AS _container OF "_baza.vcx"
Else
lnPozitii = 1
Endif
SET STEP ON
For i = lnPozitii To Alen(Thisform.ct_selectie1.aselectie,1)
If !Empty(Thisform.ct_selectie1.aselectie[i,1])
llSelectieVida = .F.
@@ -1219,7 +1218,7 @@ DEFINE CLASS ct_selectie AS _container OF "_baza.vcx"
Else
lcNumeCamp = lcNume
Endif
This.do_adauga(lcNume,lcNumeCamp,.F.,.T.)
This.do_adauga(lcNume,lcNumeCamp,.F.,.T.,.F.,.NULL.)
Endfor
Endif
Bindevent(This,"lcrosstabulare",This,"do_actualizeaza_culori_sume",1)
@@ -1812,7 +1811,7 @@ DEFINE CLASS ct_selectie_sql AS _container OF "_baza.vcx"
Else
lcNumeCamp = lcNume
Endif
This.do_adauga(lcNume,lcNumeCamp,.F.,.T.)
This.do_adauga(lcNume,lcNumeCamp,.F.,.T.,.F.,.NULL.)
Endfor
Endif
Bindevent(This,"lcrosstabulare",This,"do_actualizeaza_culori_sume",1)
@@ -2046,7 +2045,7 @@ DEFINE CLASS frm_date_rapoarte AS _frmbase OF "_frm_base.vcx"
*< END OBJECT: ClassLib="caut_ora.vcx" BaseClass="container" />
ADD OBJECT 'Ct_selectie1' AS ct_selectie WITH ;
ccoloanesuma = facturat,incasat, ;
ccoloanesuma = facturat|incasat, ;
cnumetabela = fact_vrap_fact_incasari, ;
Left = 24, ;
Name = "Ct_selectie1", ;

View File

@@ -1596,6 +1596,8 @@ DEFINE CLASS frm_verificare_parteneri AS _frmbase OF "_frm_base.vcx"
*< OBJECTDATA: ObjPath="_grdbase1.cInactiv.Check1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="_grdbase1.Column26.Header1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="_grdbase1.Column26.Text1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="_grdbase1.Column27.Header1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="_grdbase1.Column27.Text1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="But_verifica1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="Gridextra1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="chkMFIN" UniqueID="" Timestamp="" />
@@ -1658,7 +1660,7 @@ DEFINE CLASS frm_verificare_parteneri AS _frmbase OF "_frm_base.vcx"
ADD OBJECT '_grdbase1' AS _grdbase WITH ;
Anchor = 15, ;
ColumnCount = 26, ;
ColumnCount = 27, ;
DeleteMark = .F., ;
HeaderHeight = 32, ;
Height = 283, ;
@@ -1835,7 +1837,13 @@ DEFINE CLASS frm_verificare_parteneri AS _frmbase OF "_frm_base.vcx"
Column26.DynamicBackColor = "RGB(255,202,228)", ;
Column26.Name = "Column26", ;
Column26.ReadOnly = .T., ;
Column26.Width = 150
Column26.Width = 150, ;
Column27.ColumnOrder = 27, ;
Column27.ControlSource = "IIF(EMPTY(NVL(sursa,'')),'',IIF(ALLTRIM(sursa)=='ANAF','ANAF','CACHE '+DTOC(NVL(data_sursa,DATE()))+IIF(ALLTRIM(sursa)=='CACHE_INDISP',' (ANAF indisponibil)','')))", ;
Column27.Name = "Column27", ;
Column27.ReadOnly = .T., ;
Column27.Visible = .T., ;
Column27.Width = 230
*< END OBJECT: ClassLib="_grd_base.vcx" BaseClass="grid" />
ADD OBJECT '_grdbase1.cInactiv.Check1' AS checkbox WITH ;
@@ -2011,7 +2019,7 @@ DEFINE CLASS frm_verificare_parteneri AS _frmbase OF "_frm_base.vcx"
ADD OBJECT '_grdbase1.Column16.Header1' AS header WITH ;
Alignment = 2, ;
Caption = "Data TVA MFIN", ;
Caption = "Data verificata", ;
Name = "Header1", ;
WordWrap = .T.
*< END OBJECT: BaseClass="header" />
@@ -2037,7 +2045,7 @@ DEFINE CLASS frm_verificare_parteneri AS _frmbase OF "_frm_base.vcx"
ADD OBJECT '_grdbase1.Column17.Header1' AS header WITH ;
Alignment = 2, ;
Caption = "Platitor TVA MFIN", ;
Caption = "Platitor TVA ANAF", ;
Name = "Header1", ;
WordWrap = .T.
*< END OBJECT: BaseClass="header" />
@@ -2170,6 +2178,22 @@ DEFINE CLASS frm_verificare_parteneri AS _frmbase OF "_frm_base.vcx"
SelectedBackColor = 100,185,255
*< END OBJECT: BaseClass="textbox" />
ADD OBJECT '_grdbase1.Column27.Header1' AS header WITH ;
Alignment = 2, ;
Caption = "Provenienta", ;
Name = "Header1"
*< END OBJECT: BaseClass="header" />
ADD OBJECT '_grdbase1.Column27.Text1' AS textbox WITH ;
BackColor = 255,255,255, ;
BorderStyle = 0, ;
ForeColor = 0,0,0, ;
Margin = 0, ;
Name = "Text1", ;
ReadOnly = .T., ;
SelectedBackColor = 100,185,255
*< END OBJECT: BaseClass="textbox" />
ADD OBJECT '_grdbase1.Column3.Header1' AS header WITH ;
Alignment = 2, ;
Caption = "CIF/CNP", ;
@@ -2215,7 +2239,7 @@ DEFINE CLASS frm_verificare_parteneri AS _frmbase OF "_frm_base.vcx"
ADD OBJECT '_grdbase1.Column5.Header1' AS header WITH ;
Alignment = 2, ;
Caption = "Firma MFIN", ;
Caption = "Firma ANAF", ;
Name = "Header1"
*< END OBJECT: BaseClass="header" />
@@ -2695,7 +2719,6 @@ DEFINE CLASS frm_verificare_parteneri AS _frmbase OF "_frm_base.vcx"
lcConditieSuplimentara = Iif(m.llLiniaCurenta, "recno() >= " + Alltrim(Str(m.lnRecord)), ".T.")
If m.llServiciuWebANAF
SET STEP ON
&& verificare serviciu web ANAF
SELECT distinct cod_fiscal, IIF(!EMPTY(NVL(data, {})), data, DATE(m.gnAn, m.gnLuna, 1)) as data ;
FROM crsVerificareParteneri ;
@@ -2704,6 +2727,10 @@ DEFINE CLASS frm_verificare_parteneri AS _frmbase OF "_frm_base.vcx"
loVerificareANAF = CREATEOBJECT("VerificareANAF") && validare.prg
SELECT crsVerificareParteneri
REPLACE ALL cod_fiscalfro WITH ALLTRIM(Strtran(cod_fiscal, loVerificare.GetCodTara(cod_fiscal),''))
INDEX ON cod_fiscalfro TAG cfro
SELECT distinct data FROM cListaCIFTempX INTO CURSOR cListaCIFTempData
SELECT cListaCIFTempData
SCAN
@@ -2718,16 +2745,29 @@ DEFINE CLASS frm_verificare_parteneri AS _frmbase OF "_frm_base.vcx"
SCAN
SCATTER NAME loRec
WITH loRec
lcCheieCauta = PADR(ALLTRIM(STR(.cui)), 30)
SELECT crsVerificareParteneri
LOCATE FOR ALLTRIM(Strtran(cod_fiscal, loVerificare.GetCodTara(cod_fiscal),'')) = ALLTRIM(STR(.cui)) AND (EMPTY(NVL(data, {})) OR data = m.ldData)
IF FOUND()
llGasit = .F.
IF SEEK(m.lcCheieCauta, 'crsVerificareParteneri', 'cfro')
llGasit = .T.
DO WHILE !(EMPTY(NVL(data, {})) OR data = m.ldData)
SKIP
IF EOF() OR cod_fiscalfro <> m.lcCheieCauta
llGasit = .F.
EXIT
ENDIF
ENDDO
ENDIF
IF llGasit
Replace firma With .denumire, adresa With .adresa, datatvamfin With TRANSFORM(.data), platitortvamfin With .tva, stare With .mesaj, cod WITH ALLTRIM(STR(.cui)), ;
tvaincasare WITH .tvaincasare, splittva WITH .splittva, inactiv WITH .inactiv
ENDIF
tvaincasare WITH .tvaincasare, splittva WITH .splittva, inactiv WITH .inactiv, ;
sursa WITH NVL(.sursa, 'ANAF'), data_sursa WITH .data_sursa
ENDIF
ENDWITH
ENDSCAN && (m.lcCursorVerificareANAF)
ENDIF
ENDSCAN && cListaCIFTempData
SET ORDER TO 0 IN crsVerificareParteneri
USE IN (SELECT('cListaCIFTempData'))
USE IN (SELECT('cListaCIFTempX'))
USE IN (SELECT('cListaCIFTemp'))
@@ -2887,6 +2927,20 @@ DEFINE CLASS frm_verificare_parteneri AS _frmbase OF "_frm_base.vcx"
this._grDBASE1.HeaderHeight = 32
ENDPROC
PROCEDURE Load
*** campurile de provenienta (cache/ANAF) trebuie sa existe INAINTE ca grid-ul sa se construiasca (Load ruleaza inaintea obiectelor din forma);
*** ALTER TABLE nu functioneaza pe acest cursor (are campuri peste 10 caractere, ex. platitortvamfin) - se rematerializeaza cu SELECT
LOCAL lcAliasTmp
IF TYPE('crsVerificareParteneri.sursa') = 'U'
lcAliasTmp = 'crsVPTmp' + Sys(2015)
SELECT *, SPACE(20) AS sursa, {} AS data_sursa FROM crsVerificareParteneri INTO CURSOR (lcAliasTmp) READWRITE
USE IN (SELECT('crsVerificareParteneri'))
SELECT * FROM (lcAliasTmp) INTO CURSOR crsVerificareParteneri READWRITE
USE IN (SELECT(lcAliasTmp))
ENDIF
DODEFAULT()
ENDPROC
PROCEDURE meniu_dblclick
*** Verificare cod fiscal de pe inregistrarea curenta
Local loDate As "empty"
@@ -3009,6 +3063,31 @@ DEFINE CLASS frm_verificare_parteneri_istoric AS _frmbase OF "_frm_base.vcx"
*< OBJECTDATA: ObjPath="_grdbase1.cDataOraV.Text1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="_grdbase1.cUtilV.Header1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="_grdbase1.cUtilV.Text1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="_grdbase1.cDataOravAnaf.Header1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="_grdbase1.cDataOravAnaf.Text1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="_grdbase1.cTvaIncasare.Header1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="_grdbase1.cTvaIncasare.Text1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="_grdbase1.cTvaIncasare._checkbox1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="_grdbase1.cSplitTva.Header1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="_grdbase1.cSplitTva.Text1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="_grdbase1.cSplitTva._checkbox1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="_grdbase1.cInactiv.Header1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="_grdbase1.cInactiv.Text1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="_grdbase1.cInactiv._checkbox1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="_grdbase1.cDataInceputScpTva.Header1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="_grdbase1.cDataInceputScpTva.Text1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="_grdbase1.cDataSfarsitScpTva.Header1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="_grdbase1.cDataSfarsitScpTva.Text1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="_grdbase1.cDataAnulImpScpTva.Header1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="_grdbase1.cDataAnulImpScpTva.Text1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="_grdbase1.cDataInceputTvaInc.Header1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="_grdbase1.cDataInceputTvaInc.Text1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="_grdbase1.cDataSfarsitTvaInc.Header1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="_grdbase1.cDataSfarsitTvaInc.Text1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="_grdbase1.cDataInactivare.Header1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="_grdbase1.cDataInactivare.Text1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="_grdbase1.cDataReactivare.Header1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="_grdbase1.cDataReactivare.Text1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="Gridextra1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="lblInfo" UniqueID="" Timestamp="" />
@@ -3058,7 +3137,7 @@ DEFINE CLASS frm_verificare_parteneri_istoric AS _frmbase OF "_frm_base.vcx"
ADD OBJECT '_grdbase1' AS _grdbase WITH ;
Anchor = 15, ;
ColumnCount = 16, ;
ColumnCount = 27, ;
DeleteMark = .F., ;
HeaderHeight = 32, ;
Height = 190, ;
@@ -3103,19 +3182,19 @@ DEFINE CLASS frm_verificare_parteneri_istoric AS _frmbase OF "_frm_base.vcx"
Column6.ControlSource = "codpostal", ;
Column6.Name = "cCodPostal", ;
Column6.ReadOnly = .T., ;
Column6.Visible = .T., ;
Column6.Visible = .F., ;
Column6.Width = 75, ;
Column7.ColumnOrder = 11, ;
Column7.ControlSource = "telefon", ;
Column7.Name = "cTelefon", ;
Column7.ReadOnly = .T., ;
Column7.Visible = .T., ;
Column7.Visible = .F., ;
Column7.Width = 75, ;
Column8.ColumnOrder = 12, ;
Column8.ControlSource = "fax", ;
Column8.Name = "cFax", ;
Column8.ReadOnly = .T., ;
Column8.Visible = .T., ;
Column8.Visible = .F., ;
Column8.Width = 75, ;
Column9.ColumnOrder = 6, ;
Column9.ControlSource = "platitortvavies", ;
@@ -3123,18 +3202,20 @@ DEFINE CLASS frm_verificare_parteneri_istoric AS _frmbase OF "_frm_base.vcx"
Column9.Name = "cPlatitorTVAVies", ;
Column9.ReadOnly = .T., ;
Column9.Sparse = .F., ;
Column9.Visible = .T., ;
Column9.Visible = .F., ;
Column9.Width = 54, ;
Column10.ColumnOrder = 5, ;
Column10.ControlSource = "datatvamfin", ;
Column10.Name = "cDataTVAMfin", ;
Column10.ReadOnly = .T., ;
Column10.Visible = .F., ;
Column11.ColumnOrder = 4, ;
Column11.ControlSource = "platitortvamfin", ;
Column11.CurrentControl = "_checkbox1", ;
Column11.Name = "cPlatitorTVAMfin", ;
Column11.ReadOnly = .T., ;
Column11.Sparse = .F., ;
Column11.Visible = .F., ;
Column11.Width = 51, ;
Column12.ColumnOrder = 3, ;
Column12.ControlSource = "stare", ;
@@ -3154,7 +3235,57 @@ DEFINE CLASS frm_verificare_parteneri_istoric AS _frmbase OF "_frm_base.vcx"
Column16.ControlSource = "utilv", ;
Column16.Name = "cUtilV", ;
Column16.ReadOnly = .T., ;
Column16.Width = 114
Column16.Width = 114, ;
Column17.ControlSource = "dataorav_anaf", ;
Column17.Name = "cDataOravAnaf", ;
Column17.ReadOnly = .T., ;
Column17.Width = 85, ;
Column18.ControlSource = "tvaincasare", ;
Column18.CurrentControl = "_checkbox1", ;
Column18.Name = "cTvaIncasare", ;
Column18.ReadOnly = .T., ;
Column18.Sparse = .F., ;
Column18.Width = 54, ;
Column19.ControlSource = "splittva", ;
Column19.CurrentControl = "_checkbox1", ;
Column19.Name = "cSplitTva", ;
Column19.ReadOnly = .T., ;
Column19.Sparse = .F., ;
Column19.Width = 54, ;
Column20.ControlSource = "inactiv", ;
Column20.CurrentControl = "_checkbox1", ;
Column20.Name = "cInactiv", ;
Column20.ReadOnly = .T., ;
Column20.Sparse = .F., ;
Column20.Width = 54, ;
Column21.ControlSource = "data_inceput_scptva", ;
Column21.Name = "cDataInceputScpTva", ;
Column21.ReadOnly = .T., ;
Column21.Width = 85, ;
Column22.ControlSource = "data_sfarsit_scptva", ;
Column22.Name = "cDataSfarsitScpTva", ;
Column22.ReadOnly = .T., ;
Column22.Width = 85, ;
Column23.ControlSource = "data_anul_imp_scptva", ;
Column23.Name = "cDataAnulImpScpTva", ;
Column23.ReadOnly = .T., ;
Column23.Width = 85, ;
Column24.ControlSource = "data_inceput_tvainc", ;
Column24.Name = "cDataInceputTvaInc", ;
Column24.ReadOnly = .T., ;
Column24.Width = 85, ;
Column25.ControlSource = "data_sfarsit_tvainc", ;
Column25.Name = "cDataSfarsitTvaInc", ;
Column25.ReadOnly = .T., ;
Column25.Width = 85, ;
Column26.ControlSource = "data_inactivare", ;
Column26.Name = "cDataInactivare", ;
Column26.ReadOnly = .T., ;
Column26.Width = 85, ;
Column27.ControlSource = "data_reactivare", ;
Column27.Name = "cDataReactivare", ;
Column27.ReadOnly = .T., ;
Column27.Width = 85
*< END OBJECT: ClassLib="_grd_base.vcx" BaseClass="grid" />
ADD OBJECT '_grdbase1.cAdresa.Header1' AS header WITH ;
@@ -3205,6 +3336,70 @@ DEFINE CLASS frm_verificare_parteneri_istoric AS _frmbase OF "_frm_base.vcx"
Visible = .T.
*< END OBJECT: BaseClass="textbox" />
ADD OBJECT '_grdbase1.cDataAnulImpScpTva.Header1' AS header WITH ;
Alignment = 2, ;
Caption = "Anulare scutire TVA", ;
Name = "Header1", ;
WordWrap = .T.
*< END OBJECT: BaseClass="header" />
ADD OBJECT '_grdbase1.cDataAnulImpScpTva.Text1' AS textbox WITH ;
BackColor = 255,255,255, ;
BorderStyle = 0, ;
ForeColor = 0,0,0, ;
Margin = 0, ;
Name = "Text1", ;
ReadOnly = .T.
*< END OBJECT: BaseClass="textbox" />
ADD OBJECT '_grdbase1.cDataInactivare.Header1' AS header WITH ;
Alignment = 2, ;
Caption = "Data inactivare", ;
Name = "Header1", ;
WordWrap = .T.
*< END OBJECT: BaseClass="header" />
ADD OBJECT '_grdbase1.cDataInactivare.Text1' AS textbox WITH ;
BackColor = 255,255,255, ;
BorderStyle = 0, ;
ForeColor = 0,0,0, ;
Margin = 0, ;
Name = "Text1", ;
ReadOnly = .T.
*< END OBJECT: BaseClass="textbox" />
ADD OBJECT '_grdbase1.cDataInceputScpTva.Header1' AS header WITH ;
Alignment = 2, ;
Caption = "Inceput scutire TVA", ;
Name = "Header1", ;
WordWrap = .T.
*< END OBJECT: BaseClass="header" />
ADD OBJECT '_grdbase1.cDataInceputScpTva.Text1' AS textbox WITH ;
BackColor = 255,255,255, ;
BorderStyle = 0, ;
ForeColor = 0,0,0, ;
Margin = 0, ;
Name = "Text1", ;
ReadOnly = .T.
*< END OBJECT: BaseClass="textbox" />
ADD OBJECT '_grdbase1.cDataInceputTvaInc.Header1' AS header WITH ;
Alignment = 2, ;
Caption = "Inceput TVA incasare", ;
Name = "Header1", ;
WordWrap = .T.
*< END OBJECT: BaseClass="header" />
ADD OBJECT '_grdbase1.cDataInceputTvaInc.Text1' AS textbox WITH ;
BackColor = 255,255,255, ;
BorderStyle = 0, ;
ForeColor = 0,0,0, ;
Margin = 0, ;
Name = "Text1", ;
ReadOnly = .T.
*< END OBJECT: BaseClass="textbox" />
ADD OBJECT '_grdbase1.cDataOra.Header1' AS header WITH ;
Alignment = 2, ;
Caption = "Creat la", ;
@@ -3233,6 +3428,69 @@ DEFINE CLASS frm_verificare_parteneri_istoric AS _frmbase OF "_frm_base.vcx"
Name = "Text1"
*< END OBJECT: BaseClass="textbox" />
ADD OBJECT '_grdbase1.cDataOravAnaf.Header1' AS header WITH ;
Alignment = 2, ;
Caption = "Data ANAF", ;
Name = "Header1"
*< END OBJECT: BaseClass="header" />
ADD OBJECT '_grdbase1.cDataOravAnaf.Text1' AS textbox WITH ;
BackColor = 255,255,255, ;
BorderStyle = 0, ;
ForeColor = 0,0,0, ;
Margin = 0, ;
Name = "Text1", ;
ReadOnly = .T.
*< END OBJECT: BaseClass="textbox" />
ADD OBJECT '_grdbase1.cDataReactivare.Header1' AS header WITH ;
Alignment = 2, ;
Caption = "Data reactivare", ;
Name = "Header1", ;
WordWrap = .T.
*< END OBJECT: BaseClass="header" />
ADD OBJECT '_grdbase1.cDataReactivare.Text1' AS textbox WITH ;
BackColor = 255,255,255, ;
BorderStyle = 0, ;
ForeColor = 0,0,0, ;
Margin = 0, ;
Name = "Text1", ;
ReadOnly = .T.
*< END OBJECT: BaseClass="textbox" />
ADD OBJECT '_grdbase1.cDataSfarsitScpTva.Header1' AS header WITH ;
Alignment = 2, ;
Caption = "Sfarsit scutire TVA", ;
Name = "Header1", ;
WordWrap = .T.
*< END OBJECT: BaseClass="header" />
ADD OBJECT '_grdbase1.cDataSfarsitScpTva.Text1' AS textbox WITH ;
BackColor = 255,255,255, ;
BorderStyle = 0, ;
ForeColor = 0,0,0, ;
Margin = 0, ;
Name = "Text1", ;
ReadOnly = .T.
*< END OBJECT: BaseClass="textbox" />
ADD OBJECT '_grdbase1.cDataSfarsitTvaInc.Header1' AS header WITH ;
Alignment = 2, ;
Caption = "Sfarsit TVA incasare", ;
Name = "Header1", ;
WordWrap = .T.
*< END OBJECT: BaseClass="header" />
ADD OBJECT '_grdbase1.cDataSfarsitTvaInc.Text1' AS textbox WITH ;
BackColor = 255,255,255, ;
BorderStyle = 0, ;
ForeColor = 0,0,0, ;
Margin = 0, ;
Name = "Text1", ;
ReadOnly = .T.
*< END OBJECT: BaseClass="textbox" />
ADD OBJECT '_grdbase1.cDataTVAMfin.Header1' AS header WITH ;
Alignment = 2, ;
Caption = "Data TVA MFIN", ;
@@ -3281,6 +3539,29 @@ DEFINE CLASS frm_verificare_parteneri_istoric AS _frmbase OF "_frm_base.vcx"
Visible = .T.
*< END OBJECT: BaseClass="textbox" />
ADD OBJECT '_grdbase1.cInactiv._checkbox1' AS _checkbox WITH ;
Alignment = 2, ;
Caption = "", ;
Left = 19, ;
Name = "_checkbox1", ;
ReadOnly = .T., ;
Top = 96
*< END OBJECT: ClassLib="_baza.vcx" BaseClass="checkbox" />
ADD OBJECT '_grdbase1.cInactiv.Header1' AS header WITH ;
Alignment = 2, ;
Caption = "Inactiv", ;
Name = "Header1"
*< END OBJECT: BaseClass="header" />
ADD OBJECT '_grdbase1.cInactiv.Text1' AS textbox WITH ;
BackColor = 255,255,255, ;
BorderStyle = 0, ;
ForeColor = 0,0,0, ;
Margin = 0, ;
Name = "Text1"
*< END OBJECT: BaseClass="textbox" />
ADD OBJECT '_grdbase1.cJudet.Header1' AS header WITH ;
Alignment = 2, ;
Caption = "Judet", ;
@@ -3362,6 +3643,29 @@ DEFINE CLASS frm_verificare_parteneri_istoric AS _frmbase OF "_frm_base.vcx"
Visible = .T.
*< END OBJECT: BaseClass="textbox" />
ADD OBJECT '_grdbase1.cSplitTva._checkbox1' AS _checkbox WITH ;
Alignment = 2, ;
Caption = "", ;
Left = 19, ;
Name = "_checkbox1", ;
ReadOnly = .T., ;
Top = 120
*< END OBJECT: ClassLib="_baza.vcx" BaseClass="checkbox" />
ADD OBJECT '_grdbase1.cSplitTva.Header1' AS header WITH ;
Alignment = 2, ;
Caption = "Split TVA", ;
Name = "Header1"
*< END OBJECT: BaseClass="header" />
ADD OBJECT '_grdbase1.cSplitTva.Text1' AS textbox WITH ;
BackColor = 255,255,255, ;
BorderStyle = 0, ;
ForeColor = 0,0,0, ;
Margin = 0, ;
Name = "Text1"
*< END OBJECT: BaseClass="textbox" />
ADD OBJECT '_grdbase1.cStare.Header1' AS header WITH ;
Alignment = 2, ;
Caption = "Stare", ;
@@ -3392,6 +3696,29 @@ DEFINE CLASS frm_verificare_parteneri_istoric AS _frmbase OF "_frm_base.vcx"
Visible = .T.
*< END OBJECT: BaseClass="textbox" />
ADD OBJECT '_grdbase1.cTvaIncasare._checkbox1' AS _checkbox WITH ;
Alignment = 2, ;
Caption = "", ;
Left = 19, ;
Name = "_checkbox1", ;
ReadOnly = .T., ;
Top = 144
*< END OBJECT: ClassLib="_baza.vcx" BaseClass="checkbox" />
ADD OBJECT '_grdbase1.cTvaIncasare.Header1' AS header WITH ;
Alignment = 2, ;
Caption = "TVA incasare", ;
Name = "Header1"
*< END OBJECT: BaseClass="header" />
ADD OBJECT '_grdbase1.cTvaIncasare.Text1' AS textbox WITH ;
BackColor = 255,255,255, ;
BorderStyle = 0, ;
ForeColor = 0,0,0, ;
Margin = 0, ;
Name = "Text1"
*< END OBJECT: BaseClass="textbox" />
ADD OBJECT '_grdbase1.cUtil.Header1' AS header WITH ;
Alignment = 2, ;
Caption = "Creat de", ;

View File

@@ -5018,7 +5018,7 @@ DEFINE CLASS frm_rulaje AS _frmbase OF "_frm_base.vcx"
ENDPROC
PROCEDURE pgframe.Page2.but_modifica_furnizor.Click
loCaut = caut_partener()
loCaut = caut_partener(,,,, .T., Thisform.dataact)
IF TYPE('loCaut') = 'O' AND !ISNULL(loCaut)
thisform.partener = ALLTRIM(loCaut.denumire)
thisform.id_partener = loCaut.id_part

1
docs/.ultima_revizie Normal file
View File

@@ -0,0 +1 @@
2026-08-02

View File

@@ -1,127 +1,138 @@
# Prompt: căutare și editare în cod VFP (foxbin2prg) — reutilizabil în orice proiect Visual FoxPro
Acest fișier conține un **prompt gata de copiat** pentru Claude Code (sau alt agent), care
configurează și folosește sistemul `foxbin2prg` ca să poată **căuta** cod-sursă aflat **în interiorul
fișierelor binare VFP** (`.vcx/.vct`, `.scx/.sct`, `.frx/.frt`, `.mnx/.mnt`, `.dbc/.dct`) într-un
proiect nou — și, pentru `.vcx`/`.scx`, să poată și **modifica** acel cod direct pe text, cu
write-back în binar (`txt2vcx.ps1`), fără trecere prin IDE-ul VFP.
Unealta e partajată și stă la `D:\ROA\UTIL\foxbin2prg\` — nu trebuie copiată per proiect. Doar
spui agentului care e proiectul curent (folderul + fișierul `.pjx`).
---
## Cum se folosește
1. Deschide proiectul VFP în Claude Code.
2. Copiază blocul de mai jos în prompt.
3. Înlocuiește cele **3 valori** marcate `<<...>>` cu datele proiectului tău:
- `<<RADACINA_PROIECT>>` = folderul rădăcină al proiectului (ex. `D:\ROA\ROAGEST`)
- `<<FISIER_PJX>>` = calea către `.pjx` (ex. `D:\ROA\ROAGEST\roagest.pjx`)
- `<<NUME_PROIECT>>` = etichetă scurtă pentru folderul de cache (ex. `roagest`)
---
## ▼▼▼ PROMPT DE COPIAT ▼▼▼
```
Acest proiect este o aplicație Visual FoxPro 9. O mare parte din cod (proceduri, metode,
parametri) NU stă în fișiere .prg, ci în interiorul fișierelor binare VFP: librării de clase
(.vcx+.vct), forme (.scx+.sct), rapoarte (.frx+.frt), meniuri (.mnx+.mnt). Un grep direct pe
acestea nu e lizibil (sunt tabele DBF cu memo binar).
Ca să poți căuta în acel cod, folosește unealta partajată foxbin2prg, care convertește binarele
în reprezentarea lor TEXT (.vc2/.sc2/.fr2/.mn2/.dc2) într-un cache, și apoi caută în cache.
PARAMETRII PROIECTULUI CURENT:
- Rădăcină proiect: <<RADACINA_PROIECT>>
- Fișier proiect (.pjx): <<FISIER_PJX>>
- Cache text: D:\ROA\_vfp_textcache\<<NUME_PROIECT>>
REGULA DE AUR: cache-ul text e sursa pentru CĂUTARE (toate tipurile de binar) și, DOAR pentru
.vcx/.scx, și pentru EDITARE cu write-back (txt2vcx.ps1, vezi PAS 3). Pentru .frx/.mnx/.dbc
textul rămâne doar pentru citire — modificările la ele se fac în IDE-ul VFP, pe binar.
PAS 1 — populează cache-ul text (la începutul sesiunii, sau după ce s-a modificat ceva în IDE).
Rulează în PowerShell (e incremental — sare peste ce e deja la zi):
& 'D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1' -Project '<<FISIER_PJX>>' -ProjectRoot '<<RADACINA_PROIECT>>' -CacheRoot 'D:\ROA\_vfp_textcache\<<NUME_PROIECT>>'
(Folosește un -CacheRoot distinct per proiect ca să nu amesteci cache-urile. Implicit scriptul
convertește doar .vcx și .scx; pentru a include și rapoarte/meniuri adaugă: -Types vcx,scx,frx,mnx)
Dacă scriptul se plânge că lipsește FoxBin2Prg.EXE, trebuie compilat o singură dată: deschide
'D:\ROA\UTIL\foxbin2prg\foxbin2prg.pj2' în VFP 9 și Build > Build Executable. Anunță-mă să fac asta.
PAS 2 — caută în cache cu unealta Grep (NU în binarele originale):
Grep pe folderul 'D:\ROA\_vfp_textcache\<<NUME_PROIECT>>' pentru numele de metodă/procedură/variabilă căutat.
Ex.: caută "PROCEDURE do_salvare" sau numele tabelei/cursorului implicat.
CONVERSIE PUNCTUALĂ (un fișier sau folder care NU e în proiect, ex. o librărie din COMUN):
& 'D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1' -Source 'CALE\catre\librarie.vcx' -CacheRoot 'D:\ROA\_vfp_textcache\<<NUME_PROIECT>>'
ALTE OPȚIUNI: -Force (reconvertește tot), -Clean (șterge cache-ul întâi).
PAS 3 — modificare de cod în .vcx/.scx (flux write-back pe text). Ordinea e obligatorie:
a. Investighează pe cache, propune modificarea și AȘTEAPTĂ ACORDUL pe abordare înainte să
editezi ceva.
b. Refresh cache (PAS 1) dacă a rulat vreo sesiune de IDE de la ultimul refresh (staleness-ul
se verifică pe mtime și txt2vcx refuză corect scrierea peste modificări nevăzute). Înainte
de write-back închide COMPLET VFP IDE și exe-ul aplicației — procesele reziduale țin lock
pe binare.
c. Editează .vc2/.sc2 BYTE-SAFE: formatul e position-sensitive (nu reformata/reflow linii),
proprietățile sunt alfabetizate (una nouă se inserează la locul ei alfabetic). Headerul
CPID="1252" poate minți despre codepage-ul real al diacriticelor — citește/scrie fișierul
ca bytes (PowerShell), conținutul NOU doar ASCII; nu folosi unelte care re-encodează.
d. Write-back:
& 'D:\ROA\UTIL\foxbin2prg\txt2vcx.ps1' -TextFile 'D:\ROA\_vfp_textcache\<<NUME_PROIECT>>\Clase\lib.vc2' -ProjectRoot '<<RADACINA_PROIECT>>' -CacheRoot 'D:\ROA\_vfp_textcache\<<NUME_PROIECT>>'
Regenerează + compilează binarul în staging, verifică fidelitatea (roundtrip byte-identic
față de textul editat) și abia apoi copiază binarul în proiect; la orice eșec proiectul
rămâne neatins. Ținte sub COMUN\ cer flag-ul -AllowComun ȘI aprobare explicită — o
modificare acolo afectează toate aplicațiile ROA.
e. Diff lizibil pentru review: extrage binarul vechi din git (git show HEAD:cale > temp, atât
.vcx cât și .vct), regenerează-i textul cu vcx2txt.ps1 -Source într-un folder temporar și
compară cu cache-ul editat: git diff --no-index. COMMIT DOAR după ce omul confirmă pe diff
și testează în IDE.
EXCEPȚII: pentru .mnx (GENMENU) și .frx (fragile la round-trip) nu există write-back — scrie
propunerea de modificare într-un fișier docs/propuneri_<subiect>.md (cod + unde se inserează),
iar aplicarea se face manual în IDE-ul VFP.
FLUX TIPIC: la prima sesiune rulează PAS 1 o dată, apoi caută cu Grep în cache (PAS 2). La
sesiunile următoare rescrie doar ce s-a schimbat. Când citești codul unei metode, dă referințe
fișier:linie din cache.
```
## ▲▲▲ SFÂRȘIT PROMPT ▲▲▲
---
## Note pentru adaptare
- `<<NUME_PROIECT>>` îl poți pune orice etichescurtă (ex. `roagest`), doar ca numele
folderului de cache să fie unic per proiect.
- Ține cache-ul în `D:\ROA\_vfp_textcache\`, adică **în afara** folderului `foxbin2prg`. Motiv:
`ReCreate_FoxBin2Prg.prg` face `Prg2Bin` recursiv pe tot folderul tool-ului și ar reconverti
`.??2`-urile din orice cache aflat sub el înapoi în binare parazitare.
- Scriptul citește lista de fișiere direct din `.pjx`, deci convertește **doar** ce folosește
efectiv proiectul (rapid), nu tot `COMUN\`.
- Cache-ul (`D:\ROA\_vfp_textcache\<proiect>`) e regenerabil și e în afara arborelui de versionare
al proiectului (și în afara clonei foxbin2prg) — poate fi șters oricând.
- Conversia NU necesită IDE-ul VFP deschis (folosește `FoxBin2Prg.EXE` compilat).
- Fără backup-uri `.bak` lângă binarele din proiect — git e mecanismul de restore; `txt2vcx.ps1`
ține o copie de siguranță doar în folderul temp al rulării.
- Editările de volum se pot delega la subagenți (Sonnet, în background) — sesiunea principală
orchestrează, verifică diff/fidelity și intervine doar la deblocări și decizii.
- Detalii complete despre write-back (guard-uri, encoding, dialoguri VFP modale la text corupt,
testul de regresie `test_roundtrip.ps1`): `D:\ROA\UTIL\foxbin2prg\CLAUDE.md`.
- Exemplu funcțional, rodat pe ROAGEST: `D:\ROA\ROAGEST\docs\flux-editare-vfp-text.md` și
`D:\ROA\ROAGEST\docs\CLAUDE.md` (modul de lucru complet, cu review pe diff înainte de commit).
- Ghid complet doar-căutare (varianta ROAACNPRO, cu exemple): `D:\ROA\ROAACNPRO\docs\cautare_vcx_vct.md`.
- Tabel corespondență binar → text: `.vcx``.vc2`, `.scx``.sc2`, `.frx``.fr2`, `.mnx``.mn2`,
`.dbc``.dc2`, `.lbx``.lb2`.
# Prompt: căutare și editare în cod VFP (foxbin2prg) — reutilizabil în orice proiect Visual FoxPro
**Prompt gata de copiat** pentru Claude Code (sau alt agent), care configurează și folosește
sistemul `foxbin2prg` ca să poată **căuta** cod-sursă aflat **în interiorul fișierelor binare VFP**
(`.vcx/.vct`, `.scx/.sct`, `.frx/.frt`, `.mnx/.mnt`, `.dbc/.dct`) într-un proiect nou — și, pentru
`.vcx`/`.scx`, să poată și **modifica** acel cod direct pe text, cu write-back în binar
(`txt2vcx.ps1`), fără trecere prin IDE-ul VFP.
Unealta e partajată, la `D:\ROA\UTIL\foxbin2prg\` — nu se copiază per proiect. Doar spui agentului
care e proiectul curent (folderul + fișierul `.pjx`).
---
## Cum se folosește
1. Deschide proiectul VFP în Claude Code.
2. Copiază blocul de mai jos în prompt.
3. Înlocuiește cele **3 valori** marcate `<<...>>`:
- `<<RADACINA_PROIECT>>` = folderul rădăcină al proiectului (ex. `D:\ROA\ROAGEST`)
- `<<FISIER_PJX>>` = calea către `.pjx` (ex. `D:\ROA\ROAGEST\roagest.pjx`)
- `<<NUME_PROIECT>>` = etichetă scurtă pentru folderul de cache (ex. `roagest`)
---
## ▼▼▼ PROMPT DE COPIAT ▼▼▼
```
Acest proiect este o aplicație Visual FoxPro 9. O mare parte din cod (proceduri, metode,
parametri) NU stă în fișiere .prg, ci în interiorul fișierelor binare VFP: librării de clase
(.vcx+.vct), forme (.scx+.sct), rapoarte (.frx+.frt), meniuri (.mnx+.mnt). Un grep direct pe
acestea nu e lizibil (sunt tabele DBF cu memo binar).
Ca să poți căuta în acel cod, folosește unealta partajată foxbin2prg, care convertește binarele
în reprezentarea lor TEXT (.vc2/.sc2/.fr2/.mn2/.dc2) într-un cache, și apoi caută în cache.
PARAMETRII PROIECTULUI CURENT:
- Rădăcină proiect: <<RADACINA_PROIECT>>
- Fișier proiect (.pjx): <<FISIER_PJX>>
- Cache text: D:\ROA\_vfp_textcache\<<NUME_PROIECT>>
REGULA DE AUR: cache-ul text e sursa pentru CĂUTARE (toate tipurile de binar) și, DOAR pentru
.vcx/.scx, și pentru EDITARE cu write-back (txt2vcx.ps1, vezi PAS 3). Pentru .frx/.mnx/.dbc
textul rămâne doar pentru citire — modificările la ele se fac în IDE-ul VFP, pe binar.
PAS 1 — populează cache-ul text (la începutul sesiunii, sau după ce s-a modificat ceva în IDE).
Rulează în PowerShell (e incremental — sare peste ce e deja la zi):
& 'D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1' -Project '<<FISIER_PJX>>' -ProjectRoot '<<RADACINA_PROIECT>>' -CacheRoot 'D:\ROA\_vfp_textcache\<<NUME_PROIECT>>'
(Folosește un -CacheRoot distinct per proiect ca să nu amesteci cache-urile. Implicit scriptul
convertește doar .vcx și .scx; pentru a include și rapoarte/meniuri adaugă: -Types vcx,scx,frx,mnx)
Dacă scriptul se plânge că lipsește FoxBin2Prg.EXE, trebuie compilat o singură dată: deschide
'D:\ROA\UTIL\foxbin2prg\foxbin2prg.pj2' în VFP 9 și Build > Build Executable. Anunță-mă să fac asta.
PAS 2 — caută în cache cu unealta Grep (NU în binarele originale):
Grep pe folderul 'D:\ROA\_vfp_textcache\<<NUME_PROIECT>>' pentru numele de metodă/procedură/variabilă căutat.
Ex.: caută "PROCEDURE do_salvare" sau numele tabelei/cursorului implicat.
PAS 2b — atribuie rezultatele clasei/metodei care le conține. Grep dă doar fișier:linie, iar
într-un .vc2 antetul clasei poate fi cu mii de linii mai sus și ~2/3 din fișier e metadata:
& 'D:\ROA\UTIL\foxbin2prg\vfp_symbols.ps1' -CacheRoot 'D:\ROA\_vfp_textcache\<<NUME_PROIECT>>' -ProjectRoot '<<RADACINA_PROIECT>>' -Grep 'expresie' -CodeOnly
Alte moduri: -Where 'fisier.vc2:1234' (cine deține linia), -Find 'nume' (unde e DEFINIT, nu și
apelurile), -Class 'nume_clasa' (lanț de moștenire + metode cu intervalele de linii).
Indexul se reconstruiește singur din cache; rulează PAS 1 înainte.
OBLIGATORIU înainte de PAS 3: intervalul exact al metodei. Într-un .vc2 cu multe clase, Init,
Show, do_adauga există în aproape fiecare — fără interval editezi metoda din altă clasă.
CONVERSIE PUNCTUALĂ (un fișier sau folder care NU e în proiect, ex. o librărie din COMUN):
& 'D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1' -Source 'CALE\catre\librarie.vcx' -CacheRoot 'D:\ROA\_vfp_textcache\<<NUME_PROIECT>>'
ALTE OPȚIUNI: -Force (reconvertește tot), -Clean (șterge cache-ul întâi).
PAS 3 — modificare de cod în .vcx/.scx (flux write-back pe text). Ordinea e obligatorie:
a. Investighează pe cache, propune modificarea și AȘTEAPTĂ ACORDUL pe abordare înainte să
editezi ceva.
b. Refresh cache (PAS 1) dacă a rulat vreo sesiune de IDE de la ultimul refresh (staleness-ul
se verifică pe mtime și txt2vcx refuză corect scrierea peste modificări nevăzute). Înainte
de write-back închide COMPLET VFP IDE și exe-ul aplicației — procesele reziduale țin lock
pe binare.
c. Editează .vc2/.sc2 BYTE-SAFE: formatul e position-sensitive (nu reformata/reflow linii),
proprietățile sunt alfabetizate (una nouă se inserează la locul ei alfabetic). Headerul
CPID="1252" poate minți despre codepage-ul real al diacriticelor — citește/scrie fișierul
ca bytes (PowerShell), conținutul NOU doar ASCII; nu folosi unelte care re-encodează.
d. Write-back:
& 'D:\ROA\UTIL\foxbin2prg\txt2vcx.ps1' -TextFile 'D:\ROA\_vfp_textcache\<<NUME_PROIECT>>\Clase\lib.vc2' -ProjectRoot '<<RADACINA_PROIECT>>' -CacheRoot 'D:\ROA\_vfp_textcache\<<NUME_PROIECT>>'
Regenerează + compilează binarul în staging, verifică fidelitatea (roundtrip byte-identic
față de textul editat) și abia apoi copiază binarul în proiect; la orice eșec proiectul
rămâne neatins. Ținte sub COMUN\ cer flag-ul -AllowComun ȘI aprobare explicită — o
modificare acolo afectează toate aplicațiile ROA.
e. Diff lizibil pentru review: extrage binarul vechi din git (git show HEAD:cale > temp, atât
.vcx cât și .vct), regenerează-i textul cu vcx2txt.ps1 -Source într-un folder temporar și
compară cu cache-ul editat: git diff --no-index. COMMIT DOAR după ce omul confirmă pe diff
și testează în IDE.
EXCEPȚII: pentru .mnx (GENMENU) și .frx (fragile la round-trip) nu există write-back — scrie
propunerea de modificare într-un fișier docs/propuneri_<subiect>.md (cod + unde se inserează),
iar aplicarea se face manual în IDE-ul VFP.
FLUX TIPIC: la prima sesiune rulează PAS 1 o dată, apoi caută cu Grep în cache (PAS 2). La
sesiunile următoare rescrie doar ce s-a schimbat. Când citești codul unei metode, dă referințe
fișier:linie din cache.
```
## ▲▲▲ SFÂRȘIT PROMPT ▲▲▲
---
## Note pentru adaptare
- `<<NUME_PROIECT>>` poate fi orice etichetă scurtă (ex. `roagest`), unică per proiect (numele
folderului de cache).
- Ține cache-ul în `D:\ROA\_vfp_textcache\`, adică **în afara** folderului `foxbin2prg`. Motiv:
`ReCreate_FoxBin2Prg.prg` face `Prg2Bin` recursiv pe tot folderul tool-ului și ar reconverti
`.??2`-urile din orice cache aflat sub el înapoi în binare parazitare.
- Scriptul citește lista de fișiere direct din `.pjx`, deci convertește doar ce folosește efectiv
proiectul (rapid), nu tot `COMUN\`.
- Cache-ul e regenerabil, în afara arborelui de versionare al proiectului (și al clonei
foxbin2prg) — poate fi șters oricând.
- Conversia NU necesită IDE-ul VFP deschis (folosește `FoxBin2Prg.EXE` compilat).
- Fără backup-uri `.bak` lângă binarele din proiect — git e mecanismul de restore; `txt2vcx.ps1`
ține o copie de siguranță doar în folderul temp al rulării.
- Editările de volum se pot delega la subagenți (Sonnet, în background) — sesiunea principală
orchestrează, verifică diff/fidelity și intervine doar la deblocări și decizii.
- Detalii complete despre write-back (guard-uri, encoding, dialoguri VFP modale la text corupt,
testul de regresie `test_roundtrip.ps1`): `D:\ROA\UTIL\foxbin2prg\CLAUDE.md`.
- Exemplu funcțional, rodat pe ROAGEST: `D:\ROA\ROAGEST\docs\flux-editare-vfp-text.md` și
`D:\ROA\ROAGEST\docs\CLAUDE.md` (modul de lucru complet, cu review pe diff înainte de commit).
- Ghid complet doar-căutare (varianta ROAACNPRO, cu exemple): `D:\ROA\ROAACNPRO\docs\cautare_vcx_vct.md`.
- Tabel corespondență binar → text: `.vcx``.vc2`, `.scx``.sc2`, `.frx``.fr2`, `.mnx``.mn2`,
`.dbc``.dc2`, `.lbx``.lb2`.

View File

@@ -0,0 +1,14 @@
# Capcana: grid needitabil cand formularul are 2+ grid-uri
Pe un formular cu doua sau mai multe grid-uri, gridul ale carui coloane au `ControlSource`
**necalificat** (`camp` in loc de `alias.camp`) devine needitabil - nu se poate scrie in celule.
VFP rezolva numele necalificat pe workarea curenta, care e a celuilalt grid/cursor.
Solutii:
- **Recomandat**: `ControlSource` calificat complet (`alias.camp`) pe fiecare coloana. Obligatoriu
cand sunt implicate mai multe cursoare/tabele.
- Alternativa (doar cu un singur cursor sursa): `SELECT <alias>` inainte de `DO FORM` /
`CreateObject()`, ca workarea curenta la instantiere sa fie cea corecta.
Constatat pe ROAGEST (coloana "pret lei" nu accepta scriere pana la calificarea ControlSource-ului).

View File

@@ -0,0 +1,17 @@
# Capcana: coloana noua intr-un grid existent ajunge la coada (preferinte GridExtras)
`GridExtras` (`COMUN\utile\GridExtras\gridextras.vc2:1051`, `restoregridpreferences` /
`savegridpreferences`) salveaza **per utilizator** latimea si ordinea coloanelor fiecarui grid,
in `%APPDATA%\...\gridprefs.tmp`, sub cheia `SYS(1272, grid)` (ex. `frm_modific2024.grid1`).
Salvarea se face live, la `columnmoved`/`columnresize`, nu la iesirea din formular.
Consecinta: `ColumnOrder` setat in clasa e neutralizat la runtime pentru orice utilizator care a
deschis deja formularul inainte de livrare - `gridextra1.setup()` restaureaza ordinea veche, iar
coloana nou adaugata (care nu exista in preferinte) ajunge ultima.
Solutie: repozitionare la runtime, in `Show()`, **dupa** `gridextra1.setup()`, aplicata o singura
data - cat timp preferintele salvate nu acopera toate coloanele (implementat pe
`frm_modific2024`, `COMUN\clase\omodificari.vc2`, coloana `nnir`).
La testare: pozitia coloanei nu e o asertiune stabila intre masini. Se asertesteaza tare
`ControlSource` si `ReadOnly`; `ColumnOrder` ramane informativ.

View File

@@ -1,139 +1,183 @@
# Căutare în codul din librăriile/formele VFP (`.vcx`/`.vct`, `.scx`/`.sct`, ...)
Partajat între proiectele ROA* (companion narativ la `PROMPT_cautare_vfp.md` din acest folder,
care e varianta "prompt de copiat" — acest fișier e ghidul de referință complet, cu exemple).
Cum se caută cod-sursă (proceduri, metode, parametri) care **nu** stă în fișiere `.prg`, ci
în interiorul fișierelor binare VFP: librării de clase (`.vcx`+`.vct`), forme (`.scx`+`.sct`),
rapoarte (`.frx`+`.frt`), meniuri (`.mnx`+`.mnt`), baze de date (`.dbc`+`.dct`).
## De ce e nevoie de asta
Un `.vcx` este de fapt o **tabelă DBF**: codul metodelor stă în câmpuri memo în `.vct`. Un
`grep` direct pe `.vct` *găsește* textul, dar îl vede ca fișier binar (octeți `\0` între linii),
fără numere de linie utile și greu de citit. Soluția: convertim binarul în reprezentarea lui
**TEXT** (`.vc2`, `.sc2`, …) — un PRG-style lizibil, cu metode sortate alfabetic — și căutăm
în text cu `grep`/`Grep`.
> **Regula de aur:** textul generat e **doar pentru citire/căutare**, CU O EXCEPȚIE: pentru
> `.vcx`/`.scx` se poate și edita pe text, cu write-back în binar (`txt2vcx.ps1`) — vezi
> `PROMPT_cautare_vfp.md` pasul 3 pentru fluxul complet (ordine obligatorie, encoding,
> fidelity check). Pentru `.frx`/`.mnx`/`.dbc` nu există write-back — modificările se fac tot
> în **IDE-ul VFP**.
## Unelte disponibile (verificate)
| Unealtă | Cale | Rol | Recomandare |
|---|---|---|---|
| **FoxBin2Prg** | `D:\ROA\UTIL\foxbin2prg\FoxBin2Prg.EXE` | Binar VFP ⇄ text bidirecțional (`.vc2/.sc2/.fr2/.mn2/.dc2/.lb2`) | **De folosit.** Complet, fidel, include corpul metodelor, parametri, comentarii |
| vcx2prg | `D:\ROA\UTIL\vcx2prg\x2prg.prg` | Doar `.vcx``.prg` *compilabil* | Alternativă; mai vechi, doar clase, necesită IDE VFP deschis pentru a rula forma |
| prgtovcx | `D:\ROA\UTIL\prgtovcx\prgtovcx.PRG` | Invers: `.prg``.vcx` | **Nu** pentru căutare (e direcția opusă) |
FoxBin2Prg e prima alegere: rulează din linia de comandă fără IDE deschis (EXE compilat), acoperă
toate tipurile de container, și produce text mult mai fidel decât vcx2prg.
> Dacă `FoxBin2Prg.EXE` lipsește, se compilează o singură dată: deschide
> `D:\ROA\UTIL\foxbin2prg\foxbin2prg.pj2` în VFP 9 și *Build > Build Executable*. Lângă EXE trebuie
> să existe `filename_caps.exe` și fișierele `props*.txt` (sunt deja în folder).
## Mod recomandat: scriptul `vcx2txt.ps1`
`D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1` automatizează tot: copiază binarul + memo-ul într-un
**cache** care oglindește structura proiectului (ca să nu murdărească arborele SVN), rulează
FoxBin2Prg, păstrează doar fișierul text. E **incremental** (sare peste ce e deja la zi).
Parametrizează scriptul cu proiectul curent și un cache separat per proiect (nu amesteca
cache-urile mai multor proiecte ROA):
```powershell
# DOAR fișierele proiectului curent (recomandat, rapid) -> cache text propriu
powershell -ExecutionPolicy Bypass -File D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1 `
-Project '<RADACINA_PROIECT>\<proiect>.pjx' -ProjectRoot '<RADACINA_PROIECT>' `
-CacheRoot 'D:\ROA\UTIL\foxbin2prg\_textcache_<nume_proiect>'
# include și rapoartele (.frx) și meniurile (.mnx)
powershell -ExecutionPolicy Bypass -File D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1 `
-Project '<RADACINA_PROIECT>\<proiect>.pjx' -ProjectRoot '<RADACINA_PROIECT>' `
-CacheRoot 'D:\ROA\UTIL\foxbin2prg\_textcache_<nume_proiect>' -Types vcx,scx,frx,mnx
# conversie punctuală a unui fișier sau folder (chiar dacă NU e în proiect, ex. o clasă din COMUN)
powershell -ExecutionPolicy Bypass -File D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1 -Source '<RADACINA_PROIECT>\COMUN\clase\caut.vcx'
# rebuild curat (șterge cache-ul întâi) / forțează reconversia
powershell -ExecutionPolicy Bypass -File D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1 `
-Project '<RADACINA_PROIECT>\<proiect>.pjx' -ProjectRoot '<RADACINA_PROIECT>' `
-CacheRoot 'D:\ROA\UTIL\foxbin2prg\_textcache_<nume_proiect>' -Clean
```
Exemplu concret (ROAAUTO):
```powershell
powershell -ExecutionPolicy Bypass -File D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1 `
-Project D:\ROA\ROAAUTO\roaauto.pjx -ProjectRoot D:\ROA\ROAAUTO `
-CacheRoot D:\ROA\UTIL\foxbin2prg\_textcache_roaauto
```
Rezultatul ajunge în cache-ul indicat, cu aceeași structură de directoare ca proiectul (ex.:
`_textcache_roaauto\Clase\odevize.vc2`, `_textcache_roaauto\comun\clase\_frm_base.vc2`). Apoi:
```bash
# cu unealta Grep (preferat) sau grep:
grep -rn "PROCEDURE do_calcul_tarife" "D:\ROA\UTIL\foxbin2prg\_textcache_<nume_proiect>"
grep -rln "factura_salvare" "D:\ROA\UTIL\foxbin2prg\_textcache_<nume_proiect>" # ce clase ating subiectul
```
Flux tipic pentru o problemă: rulează scriptul cu parametrii de mai sus o dată (populează
cache-ul), apoi caută cu `Grep` în cache. La sesiuni următoare rescrie doar ce s-a schimbat
(incremental). Dacă ai nevoie de o librărie din `COMUN\` care nu e în proiect, convertește-o
punctual cu `-Source`.
## Alternativă manuală (fără script)
FoxBin2Prg scrie textul **lângă sursă**. Ca să nu murdărești folderul de clase al proiectului,
copiază perechea binar+memo într-un folder temporar și convertește acolo:
```powershell
# .vcx -> .vc2 (cType gol = extensia decide direcția BIN2PRG)
Copy-Item D:\ROA\<proiect>\Clase\odevize.vcx, D:\ROA\<proiect>\Clase\odevize.vct D:\tmp\
& 'D:\ROA\UTIL\foxbin2prg\FoxBin2Prg.EXE' 'D:\tmp\odevize.vcx' '' '' '' '1' '0' '1'
# => D:\tmp\odevize.vc2
```
Pozițiile parametrilor folosite: `fișier, cType, cTextName, lGenText, cDontShowErrors=1,
cDebug=0, cDontShowProgress=1`. **Lasă `cType` gol** — extensia (`.vcx`) determină direcția.
(Nu da explicit `"BIN2PRG"` pentru un singur fișier: în acel mod EXE-ul așteaptă un *director*.)
Detalii complete de parametri: `D:\ROA\UTIL\foxbin2prg\docs\FoxBin2Prg_Run.md`.
## Soluție rapidă „murdară" (un singur fișier, fără conversie)
Pentru o verificare rapidă „există metoda X undeva în librărie?", `grep` merge direct pe `.vct`
(o vede ca binar, dar găsește potrivirile):
```bash
grep -c "PROCEDURE" "D:\ROA\<proiect>\Clase\odevize.VCT"
grep -a -o "PROCEDURE [a-zA-Z0-9_]*" "D:\ROA\<proiect>\Clase\odevize.VCT"
```
Bun pentru „da/nu" și nume de metode; pentru citit corpul/contextul, folosește conversia în text.
## Corespondență extensii binar → text
| Container | Binar (+memo) | Text |
|---|---|---|
| Librărie clase | `.vcx` + `.vct` | `.vc2` |
| Formă | `.scx` + `.sct` | `.sc2` |
| Raport | `.frx` + `.frt` | `.fr2` |
| Etichetă | `.lbx` + `.lbt` | `.lb2` |
| Meniu | `.mnx` + `.mnt` | `.mn2` |
| Bază de date | `.dbc` + `.dct` | `.dc2` |
## Note
- Codul aplicației stă mai ales în `Clase\*.vcx`; o mare parte din `.vcx`-uri sunt în
`COMUN\` (framework partajat între toate aplicațiile ROA — vezi `CLAUDE.md` per proiect).
- Cache-ul text e regenerabil și e în afara arborelui SVN/git al proiectului — poate fi șters
oricând.
- Conversia **nu** necesită IDE-ul VFP deschis (folosește EXE-ul compilat).
- Vezi și [conventie_encoding_cp1252.md](conventie_encoding_cp1252.md) — capcană de encoding la
editarea `.sc2`/`.vc2` (nu doar la căutare).
# Căutare în codul din librăriile/formele VFP (`.vcx`/`.vct`, `.scx`/`.sct`, ...)
Partajat între proiectele ROA* (companion narativ la `PROMPT_cautare_vfp.md` din acest folder
varianta "prompt de copiat" — acest fișier e ghidul de referință complet, cu exemple).
Căutare de cod-sursă (proceduri, metode, parametri) care **nu** stă în `.prg`, ci în interiorul
binarelor VFP: librării de clase (`.vcx`+`.vct`), forme (`.scx`+`.sct`), rapoarte (`.frx`+`.frt`),
meniuri (`.mnx`+`.mnt`), baze de date (`.dbc`+`.dct`).
## De ce e nevoie de asta
Un `.vcx` e o **tabelă DBF**: codul metodelor stă în câmpuri memo în `.vct`. `grep` direct pe
`.vct` găsește textul dar ca binar (octeți `\0` între linii), fără numere de linie și greu de
citit. Soluția: convertim binarul în reprezentarea lui **TEXT** (`.vc2`, `.sc2`, …) — PRG-style
lizibil, metode sortate alfabetic — și căutăm în text cu `grep`/`Grep`.
> **Regula de aur:** textul generat e **doar pentru citire/căutare**, CU O EXCEPȚIE: pentru
> `.vcx`/`.scx` se poate și edita pe text, cu write-back în binar (`txt2vcx.ps1`) — vezi
> `PROMPT_cautare_vfp.md` pasul 3 (ordine obligatorie, encoding, fidelity check). Pentru
> `.frx`/`.mnx`/`.dbc` nu există write-back — modificările se fac tot în **IDE-ul VFP**.
## Unelte disponibile (verificate)
| Unealtă | Cale | Rol | Recomandare |
|---|---|---|---|
| **FoxBin2Prg** | `D:\ROA\UTIL\foxbin2prg\FoxBin2Prg.EXE` | Binar VFP ⇄ text bidirecțional (`.vc2/.sc2/.fr2/.mn2/.dc2/.lb2`) | **De folosit.** Fidel, include corpul metodelor, parametri, comentarii |
| vcx2prg | `D:\ROA\UTIL\vcx2prg\x2prg.prg` | Doar `.vcx``.prg` compilabil | Alternativă mai veche, doar clase, necesită IDE VFP deschis |
| prgtovcx | `D:\ROA\UTIL\prgtovcx\prgtovcx.PRG` | Invers: `.prg``.vcx` | **Nu** pentru căutare (direcție opusă) |
FoxBin2Prg e prima alegere: rulează din linia de comandă fără IDE deschis (EXE compilat), acoperă
toate tipurile de container, text mai fidel decât vcx2prg.
> Dacă `FoxBin2Prg.EXE` lipsește: deschide `D:\ROA\UTIL\foxbin2prg\foxbin2prg.pj2` în VFP 9 și
> *Build > Build Executable*. Lângă EXE trebuie să existe `filename_caps.exe` și `props*.txt`
> (deja în folder).
## Mod recomandat: scriptul `vcx2txt.ps1`
`D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1` copiază binarul + memo-ul într-un **cache** care oglindește
structura proiectului (nu murdărește arborele SVN), rulează FoxBin2Prg, păstrează doar textul.
**Incremental** (sare peste ce e deja la zi).
```powershell
# DOAR fișierele proiectului curent (recomandat, rapid) -> cache text propriu
powershell -ExecutionPolicy Bypass -File D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1 `
-Project '<RADACINA_PROIECT>\<proiect>.pjx' -ProjectRoot '<RADACINA_PROIECT>' `
-CacheRoot 'D:\ROA\_vfp_textcache\<nume_proiect>'
# include și rapoartele (.frx) și meniurile (.mnx)
powershell -ExecutionPolicy Bypass -File D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1 `
-Project '<RADACINA_PROIECT>\<proiect>.pjx' -ProjectRoot '<RADACINA_PROIECT>' `
-CacheRoot 'D:\ROA\_vfp_textcache\<nume_proiect>' -Types vcx,scx,frx,mnx
# conversie punctuală a unui fișier/folder (chiar dacă NU e în proiect, ex. o clasă din COMUN)
powershell -ExecutionPolicy Bypass -File D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1 -Source '<RADACINA_PROIECT>\COMUN\clase\caut.vcx'
# rebuild curat (șterge cache-ul întâi) / forțează reconversia
powershell -ExecutionPolicy Bypass -File D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1 `
-Project '<RADACINA_PROIECT>\<proiect>.pjx' -ProjectRoot '<RADACINA_PROIECT>' `
-CacheRoot 'D:\ROA\_vfp_textcache\<nume_proiect>' -Clean
```
Exemplu (ROAAUTO):
```powershell
powershell -ExecutionPolicy Bypass -File D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1 `
-Project D:\ROA\ROAAUTO\roaauto.pjx -ProjectRoot D:\ROA\ROAAUTO `
-CacheRoot D:\ROA\_vfp_textcache\roaauto
```
> Cache-ul trebuie să stea **în afara** folderului `D:\ROA\UTIL\foxbin2prg`: `ReCreate_FoxBin2Prg.prg`
> face `Prg2Bin` recursiv pe tot folderul uneltei și ar reconverti `.??2`-urile din cache în binare
> rătăcite.
Rezultatul ajunge în cache, cu aceeași structură de directoare ca proiectul (ex.:
`roaauto\Clase\odevize.vc2`, `roaauto\comun\clase\_frm_base.vc2`). Apoi:
```bash
grep -rn "PROCEDURE do_calcul_tarife" "D:\ROA\_vfp_textcache\<nume_proiect>"
grep -rln "factura_salvare" "D:\ROA\_vfp_textcache\<nume_proiect>" # ce clase ating subiectul
```
Flux tipic: rulează scriptul o dată (populează cache-ul), apoi caută cu `Grep` în cache. La
sesiuni următoare rescrie doar ce s-a schimbat (incremental). Pentru o librărie din `COMUN\` care
nu e în proiect, convertește-o punctual cu `-Source`.
## Indexul de simboluri: `vfp_symbols.ps1`
`grep` spune *unde* e textul, nu *în ce metodă*. Într-un `.vc2` asta contează: fișierele au uzual
zeci de mii de linii, din care ~2/3 sunt proprietăți și metadata (nu cod), iar antetul clasei poate
fi cu mii de linii deasupra potrivirii. `D:\ROA\UTIL\foxbin2prg\vfp_symbols.ps1` reține intervalul
de linii al fiecărei clase/metode/proceduri — din cache-ul text **și** din `.prg`-urile proiectului
— și etichetează rezultatele.
```powershell
$s = 'D:\ROA\UTIL\foxbin2prg\vfp_symbols.ps1'
$c = @('-CacheRoot', 'D:\ROA\_vfp_textcache\<nume_proiect>', '-ProjectRoot', '<RADACINA_PROIECT>')
# căutare etichetată cu clasa.metoda; -CodeOnly taie potrivirile din metadata/proprietăți
powershell -ExecutionPolicy Bypass -File $s @c -Grep '<expresie>' -CodeOnly
powershell -ExecutionPolicy Bypass -File $s @c -Where '<fisier>.vc2:<linie>' # cine deține linia
powershell -ExecutionPolicy Bypass -File $s @c -Find '<nume>' # unde e DEFINIT
powershell -ExecutionPolicy Bypass -File $s @c -Class '<nume_clasa>' # moștenire + metode
```
Exemplu (ROAACNPRO — parametrii impliciți ai scriptului țintesc deja acest proiect):
```
> vfp_symbols.ps1 -Grep 'calcul_cheiaj' -CodeOnly
clase\oacnpro.vc2:14937: [frm_tranzit.do_executa] llSucces = calcul_cheiaj(m.lcVyeIds)
> vfp_symbols.ps1 -Class oApp
oApp (roaacnpro.prg:88) -> RoaApp (roa.prg:1) -> Custom (clasă de bază VFP)
```
Când merită în locul unui `grep` direct:
- **înainte de o editare cu `txt2vcx.ps1`** — `-Where`/`-Class` dau intervalul exact al metodei.
Într-un `.vc2` cu 15 clase, `Init`, `Show`, `do_adauga`, `do_executa2` există în aproape fiecare;
fără interval e ușor să nimerești metoda cu același nume din altă clasă;
- **rezultate multe** — `-CodeOnly` arată doar codul (pe `goExecutor` în ROAACNPRO: 1401 potriviri
de cod din 1505, restul metadata);
- **„definit sau doar apelat?"** — `-Find` dă doar definiția, `grep` dă tot;
- **moștenire** — `-Class` arată lanțul cu fișier:linie, deci se vede dacă o metodă e suprascrisă
local sau vine din `COMUN`.
Indexul (`_symbols.tsv`, în rădăcina cache-ului) se reconstruiește singur când cache-ul e mai nou
(~4 s pentru ~200 de fișiere); e regenerabil, se poate șterge oricând. Rulează întâi `vcx2txt.ps1`:
indexul e derivat din cache, deci nu poate ști de modificări făcute în IDE și neconvertite.
Limite: nu rezolvă apelurile indirecte (`EVALUATE`, `SET CLASSLIB`) — dă candidații, nu
certitudinea. Clasele de bază VFP (`form`, `custom`) apar ca neindexate: normal, n-au sursă în
proiect. Copiile vechi de `.prg` din subfoldere (ex. `COMUN\programe\roa\`) sunt excluse implicit
prin `-ExcludePrg`; dă `-ExcludePrg ''` ca să vezi tot.
## Alternativă manuală (fără script)
FoxBin2Prg scrie textul **lângă sursă**. Ca să nu murdărești folderul de clase al proiectului,
copiază perechea binar+memo într-un folder temporar și convertește acolo:
```powershell
# .vcx -> .vc2 (cType gol = extensia decide direcția BIN2PRG)
Copy-Item D:\ROA\<proiect>\Clase\odevize.vcx, D:\ROA\<proiect>\Clase\odevize.vct D:\tmp\
& 'D:\ROA\UTIL\foxbin2prg\FoxBin2Prg.EXE' 'D:\tmp\odevize.vcx' '' '' '' '1' '0' '1'
# => D:\tmp\odevize.vc2
```
Poziții parametri: `fișier, cType, cTextName, lGenText, cDontShowErrors=1, cDebug=0,
cDontShowProgress=1`. **Lasă `cType` gol** — extensia (`.vcx`) determină direcția. (Nu da explicit
`"BIN2PRG"` pentru un singur fișier: în acel mod EXE-ul așteaptă un *director*.)
Detalii complete de parametri: `D:\ROA\UTIL\foxbin2prg\docs\FoxBin2Prg_Run.md`.
## Soluție rapidă „murdară" (un singur fișier, fără conversie)
Pentru „există metoda X undeva în librărie?", `grep` merge direct pe `.vct` (îl vede ca binar, dar
găsește potrivirile):
```bash
grep -c "PROCEDURE" "D:\ROA\<proiect>\Clase\odevize.VCT"
grep -a -o "PROCEDURE [a-zA-Z0-9_]*" "D:\ROA\<proiect>\Clase\odevize.VCT"
```
Bun pentru „da/nu" și nume de metode; pentru corp/context, folosește conversia în text.
## Corespondență extensii binar → text
| Container | Binar (+memo) | Text |
|---|---|---|
| Librărie clase | `.vcx` + `.vct` | `.vc2` |
| Formă | `.scx` + `.sct` | `.sc2` |
| Raport | `.frx` + `.frt` | `.fr2` |
| Etichetă | `.lbx` + `.lbt` | `.lb2` |
| Meniu | `.mnx` + `.mnt` | `.mn2` |
| Bază de date | `.dbc` + `.dct` | `.dc2` |
## Note
- Codul aplicației stă mai ales în `Clase\*.vcx`; multe `.vcx`-uri sunt în `COMUN\` (framework
partajat între toate aplicațiile ROA — vezi `CLAUDE.md` per proiect).
- Cache-ul text e regenerabil, în afara arborelui SVN/git al proiectului — poate fi șters oricând.
- Conversia **nu** necesită IDE-ul VFP deschis (folosește EXE-ul compilat).
- Vezi și [conventie_encoding_cp1252.md](conventie_encoding_cp1252.md) — capcană de encoding la
editarea `.sc2`/`.vc2` (nu doar la căutare).

View File

@@ -1,82 +1,71 @@
# Capcană: corupere diacritice la editarea `.sc2`/`.vc2` (encoding cp1252)
Partajat între proiectele ROA* (similar cu `PROMPT_cautare_vfp.md` din acest folder) — capcana
ține de formatul `.sc2`/`.vc2` produs de FoxBin2Prg, nu de un proiect anume.
Descoperit de 2 ori în aceeași sesiune (2026-07-10, în ROAAUTO): odată în
`COMUN/clase/cmd_butoane.vc2` (clasa `cmd_select_adv`), odată în `Clase/ofundal_dev.vc2`
(meniul principal) — de fiecare dată un agent anterior a editat text-cache-ul cu un tool care
nu scrie cp1252 nativ, și a corupt TOATE caracterele cu diacritice din fișier, nu doar linia
pe care voia s-o schimbe.
## De ce se întâmplă
Fișierele `.sc2`/`.vc2` generate de FoxBin2Prg sunt **cp1252 (Windows-1252)**, nu UTF-8
(vezi antetul fiecărui fișier: `CPID="1252"`). Dacă un editor/tool citește fișierul ca UTF-8
(sau alt encoding), fiecare byte >= 0x80 (diacritic) devine invalid ca secvență UTF-8 și e
înlocuit cu caracterul de replacement U+FFFD. Dacă apoi tool-ul **salvează rezultatul tot ca
UTF-8**, acel U+FFFD e scris ca 3 octeți UTF-8 (`0xEF 0xBF 0xBD`) — care, citiți înapoi ca
cp1252 (cum face FoxBin2Prg la write-back), apar ca `�`. Rezultatul: caracterul original e
**ireversibil pierdut** (nu mai există în fișier sub nicio formă) — recuperabil DOAR din altă
sursă (git history, backup).
Codebase-ul ROA folosește un hack vechi de "reciclare" a unor caractere cp1252 needependente
de Ș/ă/ț (care nu au echivalent direct în cp1252) pentru diacritice românești:
| Literă românească | Caracter folosit (cp1252) | Byte |
|---|---|---|
| ă | ã (a-tilde) | `0xE3` |
| Ă | Ã | `0xC3` |
| ț | þ (thorn minuscul) | `0xFE` |
| Ș (majusculă) | ª (ordinal masculin) | `0xAA` |
| ș (minusculă) | º (ordinal feminin) | `0xBA` |
| î, â | î, â (existente nativ în cp1252) | `0xEE`, `0xE2` |
Aceste caractere par "gunoi"/typo la prima vedere într-un editor UTF-8 (`ã`, `þ`, `ª`, `º`) —
**sunt corecte, nu le "corecta" fără să verifici encoding-ul.**
## Cum se verifică dacă un fișier `.sc2`/`.vc2` e corupt
```powershell
$bytes = [System.IO.File]::ReadAllBytes("<path>.vc2")
$text = [System.Text.Encoding]::GetEncoding(1252).GetString($bytes)
$text -split "`r`n" | Select-String ([char]0xFFFD) # cauta caracterul de replacement
```
Dacă apare `�` (sau `$text` conține U+FFFD) în output — fișierul are corupere de encoding.
## Cum se repară
1. **Nu edita orbește peste corupere** — caracterul original e deja pierdut din fișierul
curent.
2. Dacă fișierul e sub control de versiune (git) și corupera s-a întâmplat **într-o sesiune
anterioară necomisă** (deci HEAD-ul git încă are versiunea curată): recuperează originalul
convertind binarul din HEAD în text și comparând:
```bash
git show HEAD:<cale>.vcx > /tmp/head.vcx
git show HEAD:<cale>.vct > /tmp/head.vct # (sau .VCT, dupa caz)
powershell -File D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1 -Source /tmp/head.vcx -CacheRoot /tmp/head_out
```
apoi decodează ambele fișiere (HEAD curat + curent corupt) ca cp1252 și compară linie cu
linie (PowerShell, nu `diff` direct — `diff`/Bash nu decodează cp1252 corect pentru afișare,
deși detectează totuși diferența de octeți).
3. Reconstruiește fișierul text pornind de la versiunea HEAD (curată), și reaplică DOAR
modificările intenționate din sesiunea curentă peste ea (nu invers — nu încerca să "cârpești"
fișierul corupt caracter cu caracter, e mai sigur să repornești de la baza curată).
4. Scrie rezultatul înapoi ca bytes cp1252 (`[System.Text.Encoding]::GetEncoding(1252).GetBytes(...)`),
NU ca string UTF-8/`Out-File` implicit (care scrie UTF-8 sau UTF-16 după caz).
5. Rulează write-back (`txt2vcx.ps1 -Force`) și verifică fidelity check = zero diferențe.
## Cum se evită pe viitor
Când editezi `.sc2`/`.vc2` cu tool-uri text (Read/Edit/Write), verifică întâi dacă fișierul
conține diacritice (`ã`, `þ`, `ª`, `º`, `î`, `â` etc.) — dacă da, **orice rescrie completă a
fișierului trebuie făcută la nivel de octeți cu encoding cp1252 explicit**, nu presupunând
UTF-8 implicit. Editările punctuale (Edit tool, string replace) sunt sigure DOAR dacă tool-ul
păstrează restul fișierului byte-identic (nu rescrie tot fișierul reîncodat).
## Vezi și
`PROMPT_cautare_vfp.md` din acest folder, pasul 3.c — menționează deja riscul ("Headerul
CPID="1252" poate minți...") pe scurt; acest fișier e detalierea completă (tabel de caractere,
pași de recuperare din git).
# Capcană: corupere diacritice la editarea `.sc2`/`.vc2` (encoding cp1252)
Partajat între proiectele ROA* — capcana ține de formatul `.sc2`/`.vc2` produs de FoxBin2Prg,
nu de un proiect anume.
## De ce se întâmplă
Fișierele `.sc2`/`.vc2` sunt **cp1252** (Windows-1252), nu UTF-8 (vezi antetul: `CPID="1252"`).
Dacă un editor/tool citește fișierul ca UTF-8, fiecare byte >= 0x80 (diacritic) devine invalid
ca secvență UTF-8 și e înlocuit cu U+FFFD. Dacă tool-ul apoi **salvează tot ca UTF-8**, acel
U+FFFD e scris ca 3 octeți (`0xEF 0xBF 0xBD`) — care, citiți înapoi ca cp1252 (cum face
FoxBin2Prg la write-back), apar ca `�`. Caracterul original e **ireversibil pierdut**
(recuperabil DOAR din altă sursă: git history, backup).
Codebase-ul ROA "reciclează" caractere cp1252 fără echivalent direct pentru Ș/ă/ț:
| Literă românească | Caracter folosit (cp1252) | Byte |
|---|---|---|
| ă | ã (a-tilde) | `0xE3` |
| Ă | Ã | `0xC3` |
| ț | þ (thorn minuscul) | `0xFE` |
| Ș (majusculă) | ª (ordinal masculin) | `0xAA` |
| ș (minusculă) | º (ordinal feminin) | `0xBA` |
| î, â | î, â (native cp1252) | `0xEE`, `0xE2` |
Par "gunoi"/typo într-un editor UTF-8 (`ã`, `þ`, `ª`, `º`) — **sunt corecte, nu le "corecta"
fără să verifici encoding-ul.**
## Cum se verifică dacă un fișier `.sc2`/`.vc2` e corupt
```powershell
$bytes = [System.IO.File]::ReadAllBytes("<path>.vc2")
$text = [System.Text.Encoding]::GetEncoding(1252).GetString($bytes)
$text -split "`r`n" | Select-String ([char]0xFFFD) # cauta caracterul de replacement
```
Dacă apare `�` (sau `$text` conține U+FFFD) — fișierul are corupere de encoding.
## Cum se repară
1. **Nu edita orbește peste corupere** — caracterul original e deja pierdut din fișierul curent.
2. Dacă corupera s-a întâmplat într-o sesiune anterioară necomisă (HEAD-ul git încă e curat):
recuperează originalul convertind binarul din HEAD în text:
```bash
git show HEAD:<cale>.vcx > /tmp/head.vcx
git show HEAD:<cale>.vct > /tmp/head.vct # (sau .VCT, dupa caz)
powershell -File D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1 -Source /tmp/head.vcx -CacheRoot /tmp/head_out
```
apoi decodează ambele fișiere (HEAD curat + curent corupt) ca cp1252 și compară linie cu
linie (PowerShell, nu `diff`/Bash direct — nu decodează cp1252 corect la afișare, deși
detectează totuși diferența de octeți).
3. Reconstruiește fișierul text pornind de la versiunea HEAD (curată), reaplicând DOAR
modificările intenționate din sesiunea curentă (nu invers — nu cârpi fișierul corupt
caracter cu caracter).
4. Scrie rezultatul înapoi ca bytes cp1252
(`[System.Text.Encoding]::GetEncoding(1252).GetBytes(...)`), NU ca string UTF-8/`Out-File`
implicit.
5. Rulează write-back (`txt2vcx.ps1 -Force`) și verifică fidelity check = zero diferențe.
## Cum se evită pe viitor
Când editezi `.sc2`/`.vc2` cu tool-uri text (Read/Edit/Write), verifică întâi dacă fișierul
conține diacritice (`ã`, `þ`, `ª`, `º`, `î`, `â` etc.) — dacă da, **orice rescrie completă
trebuie făcută la nivel de octeți cu encoding cp1252 explicit**, nu presupunând UTF-8.
Editările punctuale (Edit tool, string replace) sunt sigure DOAR dacă tool-ul păstrează restul
fișierului byte-identic (nu rescrie tot fișierul reîncodat).
## Vezi și
`PROMPT_cautare_vfp.md` din acest folder, pasul 3.c — menționează riscul pe scurt; acest fișier
e detalierea completă (tabel de caractere, pași de recuperare din git).

View File

@@ -1,65 +1,55 @@
# Capcană: `ALTER TABLE` pe cursorul întors de `goExecutor.oExecute()`
Partajat între proiectele ROA* — `goExecutor` (clasa `oExecutor`, definită în
`COMUN/programe/oproceduri_comune.prg`, metoda `oExecute`) e utilitarul standard pentru
interogări SQL pass-through (`SQLExec`) către Oracle, folosit peste tot în codul ROA*.
## Ce nu funcționează
```foxpro
lnSucces = goExecutor.oExecute(lcSql, lcCursor)
...
ALTER TABLE (lcCursor) ADD COLUMN coloananoua L && <- pică
```
Cursorul întors de `oExecute()` (rezultatul unui `SQLExec`) poate refuza comenzi DDL
ulterioare, cu erori în lanț (descoperite empiric, în această ordine, în ROAAUTO
`autopass_cursor_comenzi`/`autopass_cursor_operatii`):
1. `Function is not supported on remote tables.` — pe `ALTER TABLE` direct pe cursorul
original.
2. Chiar și după o încercare de rematerializare (`SELECT * FROM (cursor) INTO CURSOR
(acelasi_nume) READWRITE`) → `Alias name is already in use.` (sursa și ținta nu pot
avea același nume într-un `SELECT...INTO CURSOR`).
3. Cu un alias scratch diferit ca țintă (`SELECT * FROM (cursor) INTO CURSOR
(nume_final_diferit_de_sursa) READWRITE`) → tot `Invalid operation for the cursor.` pe
`ALTER TABLE`, chiar dacă acum cursorul final teoretic ar trebui să fie unul local
obișnuit.
Nu există niciun alt loc în codul ROA* care să facă `ALTER TABLE` imediat după
`goExecutor.oExecute()` — deci acest pattern nu avea niciun precedent testat înainte de
funcțiile AUTOPASS.
## Ce funcționează
**Nu folosi `ALTER TABLE` deloc pe rezultatul unui `oExecute()`.** Include coloanele
suplimentare direct în `SELECT`-ul de rematerializare, ca expresii literale alături de `*`
(VFP suportă `SELECT *, expr AS coloana FROM ...`):
```foxpro
lcCursorRaw = lcCursor + '_raw'
IF USED(lcCursorRaw)
USE IN (lcCursorRaw)
ENDIF
lnSucces = goExecutor.oExecute(lcSql, lcCursorRaw)
IF lnSucces < 0
* tratare eroare, RETURN
ENDIF
SELECT *, .F. AS coloananoua, SPACE(100) AS altacoloana ;
FROM (lcCursorRaw) INTO CURSOR (lcCursor) READWRITE
USE IN (lcCursorRaw)
* de-aici incolo doar REPLACE (date), NICIODATA ALTER TABLE (structura) pe (lcCursor)
```
După acest pas, cursorul (`lcCursor`) e un cursor local obișnuit — `ALTER TABLE` funcționează
normal pe el DUPĂ ACEEA (ex. dintr-o altă funcție care primește cursorul deja gata construit,
nu direct rezultatul unui `oExecute`), doar comanda imediat următoare unui `oExecute()` e
restricționată.
## Vezi și
Exemplu complet aplicat: ROAAUTO, `Programe/oproceduri_autopass.prg`,
`autopass_cursor_comenzi()`/`autopass_cursor_operatii()`.
# Capcană: `ALTER TABLE` pe cursorul întors de `goExecutor.oExecute()`
Partajat între proiectele ROA* — `goExecutor` (clasa `oExecutor`, definită în
`COMUN/programe/oproceduri_comune.prg`, metoda `oExecute`) e utilitarul standard pentru
interogări SQL pass-through (`SQLExec`) către Oracle, folosit peste tot în codul ROA*.
## Ce nu funcționează
```foxpro
lnSucces = goExecutor.oExecute(lcSql, lcCursor)
...
ALTER TABLE (lcCursor) ADD COLUMN coloananoua L && <- pică
```
Cursorul întors de `oExecute()` poate refuza comenzi DDL ulterioare, cu erori în lanț
(descoperite empiric, în această ordine):
1. `Function is not supported on remote tables.` — pe `ALTER TABLE` direct pe cursorul original.
2. Chiar și după rematerializare (`SELECT * FROM (cursor) INTO CURSOR (acelasi_nume) READWRITE`)
`Alias name is already in use.` (sursa și ținta nu pot avea același nume).
3. Cu alias scratch diferit ca țintă → tot `Invalid operation for the cursor.` pe `ALTER TABLE`,
chiar dacă țintă ar trebui să fie deja un cursor local obișnuit.
## Ce funcționează
**Nu folosi `ALTER TABLE` deloc pe rezultatul unui `oExecute()`.** Include coloanele
suplimentare direct în `SELECT`-ul de rematerializare, ca expresii literale alături de `*`
(VFP suportă `SELECT *, expr AS coloana FROM ...`):
```foxpro
lcCursorRaw = lcCursor + '_raw'
IF USED(lcCursorRaw)
USE IN (lcCursorRaw)
ENDIF
lnSucces = goExecutor.oExecute(lcSql, lcCursorRaw)
IF lnSucces < 0
* tratare eroare, RETURN
ENDIF
SELECT *, .F. AS coloananoua, SPACE(100) AS altacoloana ;
FROM (lcCursorRaw) INTO CURSOR (lcCursor) READWRITE
USE IN (lcCursorRaw)
* de-aici incolo doar REPLACE (date), NICIODATA ALTER TABLE (structura) pe (lcCursor)
```
După acest pas, cursorul (`lcCursor`) e un cursor local obișnuit — `ALTER TABLE` funcționează
normal pe el DUPĂ ACEEA (ex. într-o altă funcție care primește cursorul deja gata construit),
doar comanda imediat următoare unui `oExecute()` e restricționată.
## Vezi și
Exemplu complet aplicat: ROAAUTO, `Programe/oproceduri_autopass.prg`,
`autopass_cursor_comenzi()`/`autopass_cursor_operatii()`.

View File

@@ -0,0 +1,21 @@
# Garzi pe valori NULL (VFP)
Campurile din cursoarele intoarse de Oracle pot fi `.NULL.`. In VFP `EMPTY(.NULL.)` intoarce
`.F.`, deci o garda scrisa doar cu `EMPTY()` **nu prinde NULL**, iar concatenarea cu NULL face
tot sirul NULL (inclusiv un SQL construit prin `+`).
Forma corecta, cu tipul evaluat primul ca sa opreasca acolo:
```foxpro
If Type('tcCont') # 'C' Or Empty(Nvl(tcCont, ''))
Return
Endif
```
- `Nvl(x, '')` in interiorul lui `Empty()`, nu `Isnull(x) Or Empty(x)`.
- `TYPE()` pe o variabila cu NULL de tip caracter intoarce tot `'C'` - nu tine loc de `Nvl`.
- Acelasi tratament la orice text construit prin `+` din campuri de cursor
(SQL, mesaje, chei): un singur camp NULL anuleaza tot sirul.
Simptom tipic cand lipseste garda: `SQL statement parameter is required for non-prepared
SQLEXEC() calls` in `OEXECUTOR.OEXECUTE` - SQL-ul ajuns la `SQLEXEC` era `.NULL.`.

View File

@@ -1,48 +1,53 @@
# Convenție UX pentru formulare VFP (preferința lui Marius, valabilă pe toate proiectele ROA*)
Partajat între proiectele ROA* (similar cu `PROMPT_cautare_vfp.md`, `prompt_project_insights_docs.md`
din acest folder) — pentru că `COMUN\` e clonat/sincronizat în fiecare aplicație ROA, e locul
corect pentru o convenție de design care nu ține de un singur proiect.
Origine: confirmat de Marius pe `frm_autopass.scx` (ROAAUTO) după o rundă de regrupare vizuală
(2026-07-10) — "imi place designul acesta" pe layout-ul cu rânduri clar separate pe funcție,
butoane grupate la margini, fără elemente lipite unele de altele.
## Ce înseamnă in practică, pe proprietăți VFP
- **Fiecare grup funcțional pe rândul lui** — nu înghesui controale fără legătură directă pe
același `Top`. Ex: rândul de perioadă (date + Actualizează) separat de rândul de
statistici (Declarabile/Transmise/Blocate), separat de panoul de configurare.
- **Spațiere vizibilă între grupuri, strânsă în interiorul unui grup** — butoane din
aceeași acțiune (ex. Validează dry-run → Transmite → Renunță) la 6-10px unele de altele;
gap de 20-30px față de următorul grup funcțional (ex. Selectează tot vs. grupul
Validare/Transmitere vs. Actualizează statusuri).
- **Butoanele secundare/de configurare aliniate la marginea din dreapta a containerului**,
nu lipite imediat după textbox-ul pe care îl controlează — altfel nu se disting vizual ca
acțiune separată de câmpul de input.
- **Acțiunea principală + oprirea ei alăturate** — un buton de tip "Renunță/Oprește" trebuie
poziționat lângă acțiunea pe care o anulează (ex. Transmite + Renunță), nu împrăștiat în
altă parte a rândului.
- **Un singur rând de acțiuni cât se poate** — dacă mai multe grupuri de butoane încap pe
lățimea formei, preferă un singur rând orizontal în loc să adaugi rânduri noi dedesubt;
păstrează formele compacte pe verticală.
- **Caption-uri scurte, sentence case, nu ALL CAPS** — ex. "Transmite" nu "TRANSMITE";
"Dashboard AutoPass" nu "Deschide dashboard AUTOPASS". ALL CAPS/text lung pe un buton
citește ca zgomot, nu ca ierarhie.
- **Culoare = semnal, nu decor** — folosește culoare distinctă doar pentru acțiuni cu
semnificație clară (verde = acțiune pozitivă/transmite, roșu = oprire/pericol, albastru =
navigare/deschidere link extern); restul butoanelor rămân stilul implicit din `_baza.vcx`.
## Vocabular
Funcțional, compact, aerisit, minimalist, grupat, ușor de înțeles de utilizatori, aer aerisit,
modern — asta e reperul calitativ pentru orice formular nou sau refacere de layout, dincolo de
regulile mecanice de mai sus, pe orice aplicație ROA*.
## Vezi și
- `PROMPT_cautare_vfp.md` din acest folder — cum se caută/editează cod în binarele VFP text-cache
(relevant când aplici aceste reguli prin fluxul `.sc2`/`.vc2` + write-back).
- Capcana de encoding cp1252 la editarea `.sc2`/`.vc2` (corupere diacritice) — documentată în
proiectul unde a fost descoperită (ROAAUTO `docs/conventie_encoding_cp1252.md`); relevantă ori
de câte ori editezi text-cache-ul unui formular/librărie pentru a aplica aceste reguli de UX.
# Convenție UX pentru formulare VFP (preferința lui Marius, valabilă pe toate proiectele ROA*)
Partajat între proiectele ROA* `COMUN\` e clonat/sincronizat în fiecare aplicație ROA, e locul
corect pentru o convenție de design care nu ține de un singur proiect.
## Ce înseamnă in practică, pe proprietăți VFP
- **Fiecare grup funcțional pe rândul lui**, nu înghesuit pe același `Top` cu altul fără
legătură (ex: perioadă / statistici / configurare, pe rânduri separate).
- **Spațiere vizibilă între grupuri, strânsă în interiorul unui grup** — butoane din aceeași
acțiune la 6-10px unele de altele; gap de 20-30px față de următorul grup funcțional.
- **Butoanele secundare/de configurare aliniate la marginea din dreapta a containerului**, nu
lipite imediat după textbox-ul pe care îl controlează — altfel nu se disting ca acțiune
separată de câmpul de input.
- **Acțiunea principală + oprirea ei alăturate** (ex. Transmite + Renunță), nu împrăștiate în
altă parte a rândului.
- **Un singur rând de acțiuni cât se poate** — un rând orizontal in loc de rânduri noi
dedesubt; formele rămân compacte pe verticală.
- **Caption-uri scurte, sentence case, nu ALL CAPS** — ex. "Transmite" nu "TRANSMITE". ALL
CAPS/text lung pe un buton citește ca zgomot, nu ca ierarhie.
- **Culoare = semnal, nu decor** — doar pentru acțiuni cu semnificație clară (verde =
pozitiv/transmite, roșu = oprire/pericol, albastru = navigare/link extern); restul butoanelor
rămân stilul implicit din `_baza.vcx`.
## Clase de controale (confirmat de Marius, 24.07.2026, pe frm_verif_partener_anaf ROACONT)
- **Intotdeauna controale din `_baza.vcx`, nu controale native VFP** — orice grid, label,
textbox, checkbox etc. dintr-un formular nou se bazeaza pe clasa corespunzatoare din
`COMUN\clase\_baza.vcx`, nu pe clasa nativa Visual FoxPro. Clasele din `_baza.vcx` au
fontul default **Arial 10** — nu se suprascrie FontName pe controale (explicit: fara
Arial Narrow).
- **Butoanele de inchidere/confirmare stau in bara de titlu**, din `cmd_butoane.vcx`
modelul Renunt/Termin (clasa de forma `frm_termin_renunt` din `_frm_child.vcx` le aduce
deja). Nu se dubleaza aceste actiuni cu butoane in corpul formei.
- **Actiunile care au corespondent `but_*` in `cmd_butoane.vcx`** (Nou/Adauga, Modifica,
Salveaza, Sterge, Verifica etc.) folosesc CU PREDILECTIE clasa dedicata `but_*`
respectiva — nu se improvizeaza un buton generic pentru o actiune care are deja clasa ei.
- **Doar actiunile FARA corespondent `but_*`** primesc butoane pe clasele `cmd_*` din
`cmd_butoane.vcx` (ex. `cmd_executa`) — nu clase improvizate si nu CommandButton nativ.
## Vocabular
Funcțional, compact, aerisit, minimalist, grupat, ușor de înțeles de utilizatori, modern —
asta e reperul calitativ pentru orice formular nou sau refacere de layout, pe orice
aplicație ROA*.
## Vezi și
- `PROMPT_cautare_vfp.md` din acest folder — cum se caută/editează cod în binarele VFP text-cache
(relevant când aplici aceste reguli prin fluxul `.sc2`/`.vc2` + write-back).
- `conventie_encoding_cp1252.md` din acest folder — capcana de corupere a diacriticelor la
editarea `.sc2`/`.vc2`; relevantă ori de câte ori editezi text-cache-ul unui formular/librărie
pentru a aplica aceste reguli de UX.

View File

@@ -0,0 +1,176 @@
# Depanare actualizare ROA (CONTAFIN_ORACLE.PACK_UPDATE)
Actualizarea automata a aplicatiilor si a bazei ruleaza din jobul `CONTAFIN_ORACLE.UPDATEROA_ZILNIC`
-> `PACK_UPDATE.UpdateROA`, in 3 etape secventiale: **UpdateApp** (descarca arhivele programelor) ->
**UpdateScripts** (umple `UPD_DATABASE`) -> **UpdateDatabaseSqlPlus** (aplica scripturile pe scheme).
O etapa esuata le opreste pe toate urmatoarele.
## Scriptul de diagnostic
`COMUN\utile\diag_actualizare.ps1 -Alias <ALIAS_TNS>` ruleaza tot lantul de mai jos si scoate un
verdict (unde a ramas rularea, care e scriptul candidat, unde e eroarea). Strict read-only; `-Disc`
adauga verificarea spatiului pe discurile serverului (singura parte care scrie ceva — un `.ps1`
temporar in `DMPDIR`). Foloseste-l intai; sectiunile de mai jos explica ce citeste si de ce.
Cand cauza e spatiul (tablespace plin, audit/loguri Oracle care umplu discul), continua cu
`depanare-spatiu-oracle.md` si `COMUN\utile\diag_spatiu.ps1`.
## Unde te uiti, in ordine
| Ce | Unde |
|---|---|
| pana unde a ajuns fiecare rulare | `UPD_ISTORIC` (`stare`: 0=start, 1=aplicatii, 2=scripturi, 3=aplicare, 4=incheiat; `dataora_end` gol = neincheiata) |
| cauza reala a esecului | `UPD_LOG` (`dataora_start` = rularea, `secventa`+`dataora` = ordinea; `explicatie` e CLOB) |
| ce a raportat jobul | `dba_scheduler_job_run_details` (`log_date`, `status`, `additional_info`) |
| ce versiuni s-au descarcat | `UPD_PROGRAME` |
| scripturi disponibile / aplicate | `UPD_DATABASE.script_date` vs `<schema>.VERSIUNE.data_script` |
| **erorile din aplicarea scripturilor** | **`C:\DMPDIR\script_master.log` pe serverul de baze de date** |
Un sir de rulari oprite la aceeasi `stare` da direct etapa vinovata, iar prima zi din sir da data de
la care s-a schimbat ceva.
## Capcane
- **`UPD_LOG` se goleste la fiecare rulare.** Nu ai istoric: iei log-ul rularii curente, altfel
relansezi ca sa-l reproduci.
- **Eroarea din `additional_info` a jobului e de obicei falsa.** Pe orice esec se apeleaza `EmailLog`,
iar daca SMTP-ul e picat ridica `ORA-20000` care inlocuieste eroarea originala. Cauza adevarata e
in `UPD_LOG`.
- **`UpdateApp` abandoneaza tot la primul program nedescarcat** (`exit` din bucla, `CT_INSUCCES`) —
deci si programele de dupa el in lista, si ambele etape de baza de date. Un singur fisier
indisponibil blocheaza actualizarile la infinit, tacut.
- **`GetStare` refuza o rulare noua** cat timp precedenta e neincheiata si nu a trecut o ora.
Se deblocheaza cu `exec contafin_oracle.pack_update.IncheiereActualizare`.
- Programele `%USERREPORTS%` merg toate in directorul `UPD_USERREPORTS`, nu in `UPD_<nume_program>`.
## Aplicarea scripturilor (script_master.log)
Etapa 3 nu ruleaza scripturile din PL/SQL, ci genereaza in `DMPDIR` (`C:\DMPDIR`) cate un
`script_<SCHEMA>.sql` plus `script_master.sql`, pe care le da unui **SQL\*Plus extern**, cu iesirea
in `C:\DMPDIR\script_master.log` (`script_master2.log` = pasii de la final).
**Erorile de aici NU ajung in `UPD_LOG`.** O rulare care esueaza la un script arata perfect curata
in baza: `UPD_LOG` fara nicio eroare, doar `UpdateSchemaSQLPLUS ... / UpdateDatabaseSQLPLUS END`.
Semnele indirecte sunt ca rularea ramane la `stare = 3` fara `dataora_end`, iar
`<schema>.VERSIUNE` nu mai avanseaza. Scriptul vinovat e primul din `UPD_DATABASE` de dupa ultima
versiune inregistrata acolo, iar mesajul real e doar in `script_master.log`.
Scripturile au `WHENEVER SQLERROR EXIT SQL.SQLCODE ROLLBACK`, deci primul esec opreste tot lantul
si se repeta identic la fiecare rulare pana e reparat.
Fisierul se poate citi si fara acces la desktopul serverului, prin `UTL_FILE` pe directorul
`DMPDIR` (`fopen(...,'R',32767)` + `get_line` in bucla; tine ultimele N linii intr-un tablou —
partea utila e la sfarsit).
### Caz: nu orice esec de script e o problema de SQL (SIGMA, 03.08.2026)
`ff_2026_07_29_02_COMUN_TVA11.SQL` a picat pe `MARCU` cu `ORA-01653: unable to extend table
SYS.INFO ... in tablespace SYSTEM` (din `SYS.PINFO`/`SYS.AUTH_PACK`, recursiv). Tablespace-ul
`SYSTEM` era plin: autoextensibil, dar cu `maxbytes` atins la 600 MB, ~2 MB liberi. **Orice**
script ar fi picat identic — `AUTH_PACK` scrie in `SYS.INFO` la fiecare conectare. Cand eroarea nu
priveste obiectele scriptului, verifica intai spatiul.
Ce a contat, pentru data viitoare:
- **`maxbytes` mic nu e o limita XE.** Cele 11 GB ale XE sunt pe *date utilizator*; un plafon mic pe
`SYSTEM.DBF` e o setare de instalare. Se ridica din `contafin_oracle` (are `ALTER DATABASE`):
`alter database datafile '<cale>\SYSTEM.DBF' autoextend on next 50M maxsize 2000M;`
- **Spatiul pe discul serverului se verifica fara RDP**, cu `sys.ExecuteScriptOS` (vezi mai jos) —
`Get-WmiObject Win32_LogicalDisk -Filter "DriveType=3"`, iesire in `DMPDIR`, citita cu `UTL_FILE`.
Job asincron, dar raspunde in cateva secunde.
- **`SYS.INFO` e tabel ROA, nu obiect de dictionar** (log de login scris de `PINFO`, ~7 randuri per
conectare, +16-17k randuri/luna, nimic din baza nu-l citeste). Se poate goli, **dar numai ca
`SYSDBA`**: privilegiile `ANY` (`DROP ANY TABLE`, `DELETE ANY TABLE`) nu se aplica pe obiectele
din schema `SYS` cat timp `O7_DICTIONARY_ACCESSIBILITY=FALSE`, deci din `contafin_oracle` iese
`ORA-01031`.
- Restul lui `SYSTEM` era dictionar Oracle (`IDL_UB1$`, `SOURCE$`, `IDL_UB2$`, `ARGUMENT$` ~207 MB) —
de neatins fara export/import. `AUD$`/`FGA_LOG$` erau goale. Recyclebin-ul si bloat-ul de scheduler
stateau in `ROA`/`SYSAUX`, nu in `SYSTEM`.
## Descarcarea (UpdateApp)
Cu `server_info.POWERSHELLDOWNLOAD = '1'`, `PACK_UTILS.DownloadFileOS` scrie un `.ps1` cu `curl` in
`DMPDIR`, il lanseaza cu `sys.ExecuteScriptOS` si asteapta aparitia fisierului in directorul Oracle
`UPD_<PROGRAM>`. Daca **folderul de pe disc lipseste**, curl esueaza mut si in log apare doar
`Fisierul NU s-a salvat pe disc.` — verifica intai directorul, nu reteaua.
Verificari rapide (read-only, din `contafin_oracle`):
```sql
-- calea configurata
select directory_name, directory_path from all_directories where directory_name like 'UPD%';
-- fisierul chiar exista pe disc?
select dbms_lob.fileexists(bfilename('UPD_ROACONT','ROACONT-2.11.70.zip')) from dual;
```
```sql
-- directorul exista si e scriibil? ORA-29283 = cale OS inexistenta sau fara drept de scriere
declare f utl_file.file_type; begin
f := utl_file.fopen('UPD_USERREPORTS','__probe.txt','W'); utl_file.fclose(f);
utl_file.fremove('UPD_USERREPORTS','__probe.txt');
end;
/
```
URL-ul se testeaza direct cu `curl` de pe orice masina (`optiuni.UPD_URL_APP`, cu `|CUSTOMERID|`
inlocuit din `sys.auth_detalii.detalii`); daca da 200, problema e local pe server.
## Comenzi OS pe serverul de baze de date
`sys.ExecuteScriptOS(<powershell>, <cale .ps1>)` creeaza un job scheduler `executable`**asincron**,
deci rezultatul se verifica prin polling, nu imediat. Scriptul se scrie cu
`pack_utils_file.clob2fileX(<clob>, 'DMPDIR', '<nume>.ps1')`. Utila cand ai doar acces Oracle
(ex. tunel SSH), fara RDP:
```sql
declare lcPS server_info.value%type; begin
select value into lcPS from server_info where upper(name)='POWERSHELLPATH';
pack_utils_file.filedelete('DMPDIR','x.ps1');
pack_utils_file.clob2fileX('New-Item -ItemType Directory -Force -Path ''D:\...'' | Out-Null',
'DMPDIR','x.ps1');
sys.ExecuteScriptOS(lcPS, 'C:\DMPDIR\x.ps1');
end;
/
```
## Emailuri: log de actualizare vs buletin informativ
Sunt **doua emailuri diferite, trimise de doua masini diferite** — se confunda usor.
| | Log de actualizare | Buletin informativ |
|---|---|---|
| Cine trimite | baza de date, `PACK_UPDATE.EmailLog` (`UTL_SMTP` direct catre `EMAIL_SMTP:EMAIL_PORT`, `AUTH LOGIN`) | **serverul de update** (ASP.NET); baza doar face un GET pe `optiuni.UPD_URL_BULETININF` (cu `|CUSTOMERID|`) prin `PACK_UTILS.URL2Clob`, din `UpdateApp` |
| Destinatari | `server_info.EMAIL_TO` + `EMAIL_CC` | configurati pe serverul de update, **nu** in `server_info` (ex. `office@romfast.ro`) |
| Subiect / continut | `Actualizare ROA dd.mm.yyyy hh24:mi:ss`; liniile din `UPD_LOG`, text simplu separat cu TAB | compus de serverul de update |
| In `UPD_LOG` | erorile SMTP: `EROARE: utl_smpt ERROR CODE ...` | raspunsul HTTP, verbatim (ex. `ERR-1-BULETIN INFORMATIV NU S-A TRIMIS. MOTIVUL: Error: 1429`) |
Detalii care conteaza la depanare:
- **`EMAIL_CC` nu produce un antet `Cc:`.** Codul il concateneaza cu virgula la `EMAIL_TO` si trimite
`RCPT TO` pentru toti; antetul e un singur `To: <toti>`. Deci un email primit *in Cc* nu vine de la
`EmailLog`.
- **`EMAIL_FROM` e per server de client** (`roaupdate-<client>@romfast.ro`) si difera de contul
autentificat, care e acelasi peste tot (`EMAIL_USERNAME = roaupdate@romfast.ro`). Expeditorul e
singurul indiciu din email despre serverul care l-a trimis. Daca `EMAIL_FROM` lipseste, se compune
din `UTL_INADDR.get_host_name`.
- **Un buletin esuat nu opreste nimic**: raspunsul `ERR-1-...` e text normal, se scrie in `UPD_LOG` si
actualizarea merge mai departe. Doar exceptiile HTTP ajung ca `ERR: <url> ...`.
- **Un SMTP picat, in schimb, opreste tot** — `EmailLog` ridica `ORA-20000` care mascheaza eroarea
reala (vezi „Capcane" mai sus). E singurul loc din lantul de email care are voie sa arunce.
## Configurare (CONTAFIN_ORACLE)
- `server_info`: `POWERSHELLDOWNLOAD`, `POWERSHELLPATH`, `POWERSHELLTIMEOUT`, `CURLPATH`,
`SQLPLUSPATH`, `EMAIL_METHOD`/`EMAIL_SMTP`/`EMAIL_PORT`/`EMAIL_USERNAME`/`EMAIL_PASSWORD`/
`EMAIL_FROM`/`EMAIL_TO`.
- `optiuni`: `UPD_URL_APP`, `UPD_URL_DATABASE`, `UPD_URL_BULETININF` (daca lipsesc, pachetul
foloseste URL-uri implicite din cod).
## Conectare la serverul unui client
Tunel SSH pe 1521 + alias TNS pe `127.0.0.1` in `D:\ROA\instantclient_19_18\tnsnames.ora`
(ex. `ROA_ROMCONSTRUCT`), utilizator `contafin_oracle`. Vezi `oracle_export.md` pentru client si
capcana de encoding; parolele stau in `COMUN\docs\local\oracle.md` (neversionat in git).
Serverele de client pot fi Oracle 10g: unele coloane din `dba_scheduler_*` lipsesc
(`dba_scheduler_running_jobs.last_start_date`) — foloseste `dba_scheduler_job_run_details`.

View File

@@ -0,0 +1,122 @@
# Depanare spatiu Oracle la clienti
```powershell
powershell -File COMUN\utile\diag_spatiu.ps1 -Alias <ALIAS_TNS> [-Disc] [-SysPassword <parola>] [-Top 30]
```
Strict read-only in afara lui `-Disc` (singura parte care scrie: un `.ps1` temporar in `DMPDIR`,
lansat cu `sys.ExecuteScriptOS` si sters la final). Actiunile de curatare sunt doar **sugerate**,
niciodata executate. 8 sectiuni: conexiune/versiune (CDB-PDB), tablespace + top segmente, audit,
alert log/trace/ADR, archivelog/FRA, disc server, alti mancatori de spatiu, verdict.
Pentru actualizarea blocata de spatiu, punctul de plecare e `depanare-pack-update.md`.
## Jobul automat `DIAGSPATIU_ZILNIC` (SVN r17969)
Echivalentul in baza al scriptului de mai sus, rulat zilnic la 06:00 de la fiecare client:
`co_2026_08_03_02` (tabela `DIAG_SPATIU_LOG`, istoric purjat la 90 zile), `co_2026_08_03_03`
(`PACK_DIAG_SPATIU`), `co_2026_08_03_04` (jobul), `sys_2026_08_03_05` (granturi). Praguri identice
cu `diag_spatiu.ps1`; **email doar la prag depasit**, tacere completa altfel. Sursa de referinta:
`COMUN\docs\PACK_DIAG_SPATIU.pck`.
Sectiunile informative (recyclebin, UNDO, TEMP, istoric statistici/scheduler, top segmente, audit
SYS, disc) se scriu doar cand exista deja o alerta — dau context, nu alerteaza singure.
`co_2026_08_06_08_DIAG_SPATIU_PACK` + `sys_2026_08_06_07_DIAG_SPATIU_GRANT3` (06.08.2026) scriu la
top segmente si **tabela/coloana din care provine segmentul** (`DetaliuSegment`: `DBA_LOBS`,
`DBA_LOB_PARTITIONS`, `DBA_INDEXES`; segmentele temporare se marcheaza ca atare) — fara asta un
`SYS_LOB0000630560C00017$$` de 4 GB in email nu spune nimic, iar serverul clientului nu e accesibil
direct. Atentie: pentru `LOB PARTITION`, `dba_segments.segment_name` e `lob_name`, nu
`lob_partition_name`.
Emailurile ajung pe `marius.mutu@romfast.ro`, cate un expeditor per client
(`roaupdate_<client>@romfast.ro`); citirea lor: `email-thunderbird.md`.
`co_2026_08_06_01_DIAG_SPATIU_PACK` (06.08.2026) corecteaza doua lucruri vazute pe primele rulari:
- **pragul absolut (2048 MB) nu se mai aplica tablespace-urilor al caror maxim e sub el** — orice
`UNDOTBS`/`SYSTEM` plafonat la 5002048 MB alerta zilnic, prin definitie; acolo ramane doar garda
relativa de 15%.
- **emailul contine tot logul rularii** (alertele intai, apoi toate randurile din `DIAG_SPATIU_LOG`,
cu `!` pe cele peste prag, sortate pe sectiune si valoare descrescator), nu doar un pointer catre
tabela. Corpul e plafonat la 30000 de caractere (`EmailDiagSpatiu` lucreaza pe `VARCHAR2(32000)`),
cu marcaj `... restul in DIAG_SPATIU_LOG` la depasire.
## Mecanisme reutilizabile (din investigatia pentru job)
- **`CONTAFIN_ORACLE.SERVER_INFO`** tine parolele `PASSWORD_SYS`/`PASSWORD_CONTAFIN_ORACLE`
(zip+base64, nu criptare), caile `SQLPLUSPATH`/`POWERSHELLPATH`/`DMPDIR`, cheile `EMAIL_*` si
cache-ul `VERSIUNE_<SCHEMA>`. Parola se citeste cu `PACK_UPDATE.GetSchemaParola('<SCHEMA>')`
(decodeaza doar pentru `SYS` si `CONTAFIN_ORACLE`; pentru schemele de firma intoarce
`'ROMFASTSOFT'` hardcodat).
- **Rulare ca `SYS` din PL/SQL**: scrii un `.sql` in `DMPDIR` cu `connect sys/<parola>@ROA as
sysdba` + `spool`, il lansezi cu `sys.UpdateSQLPLUS` si astepti fisierul de iesire; pentru OS,
`sys.ExecuteScriptOS` (PowerShell). Ambele sunt asincrone (job `dbms_scheduler` de tip
`executable`, auto-drop) — mecanismul folosit si de `PACK_UPDATE.UpdateDatabaseSqlPlus`. Fisierele
temporare au nume proprii, ca sa nu se bata cu `script_master.sql` al actualizarii.
- **`PACK_UPDATE.EmailLog` nu e reutilizabila** pentru alt continut: subiectul e hardcodat
("Actualizare ROA ...") si corpul vine din `UPD_LOG`. Pentru alte alerte, bloc `UTL_SMTP` propriu
care citeste aceleasi chei `EMAIL_*`.
- **Scripturile `sys_*`** se aplica automat, ca orice `co_`/`ff_`: prefixul e recunoscut in
`PACK_UPDATE.UpdateSchema*`, schema `SYS` se actualizeaza **prima**, iar `UpdateVersiune` isi
scrie randul in `CONTAFIN_ORACLE.versiune` (schema `SYS` n-are tabela proprie). Deci un `sys_`
livrat in aceeasi zi ruleaza inaintea scripturilor `co_` care depind de el.
## Ce umple spatiul, in ordinea frecventei
- **Tablespace cu `maxbytes` atins** — nu "disc plin", ci un plafon pus la instalare. Pe XE limita
de 11/12 GB e pe *date utilizator*, nu pe `SYSTEM`.
- **`SYSAUX`** — SQL Tuning Sets (`wri$_sqlset_*`), AWR, audit policies active pe un PDB nou.
- **Fisierele `.aud`** din `audit_file_dest` (`adump`) — zeci de mii, niciodata curatate; **nu se vad
din SQL**, doar cu `-Disc`.
- **Alert log / trace / incident** (`diagnostic_dest`) — se purja cu `adrci purge`.
- **FRA plina cu `log_mode=ARCHIVELOG`** → `ORA-00257`/`ORA-19809`; baza se blocheaza brusc, fara
eroare vizibila in aplicatie.
- Recyclebin, `UNDO` umflat, istoric statistici/scheduler, `TEMP`.
- **Tabele de log ale aplicatiei** care cresc nelimitat (tiparul `SYS.INFO` de pe SIGMA) — apar in
raportul de top segmente, numele difera per client.
## Cazuri
- **Rompetrol Energy** (XE 21c): `ORA-12954`, limita de 12 GB pe `dba_data_files` atinsa. `SYSAUX`
umflat la 7.8 GB din SQL Tuning Sets (~5 GB) + AWR + audit policies. `TRUNCATE wri$_sqlset_*` a
eliberat segmentele, dar `RESIZE` a picat cu `ORA-03297` (`SYSAUX` nu se shrink pe XE 21c) →
singura solutie a fost **recrearea PDB-ului**, 13.5 GB → 3 GB. Detalii:
`E:\proiecte\ROMFASTSQL\proxmox\lxc108-oracle\clienti\oracle-xe-21c\` (`README.md`,
`depanare-ora-12954-spatiu.md`).
- **ROA_CENTRAL** (`ORA-65114`, 02.08.2026): acelasi tipar, rezolvat prin curatenie tintita in loc
de recreare PDB; SQL-uri gata scrise in acelasi repo (`docs/curatenie-spatiu-oracle.sql`).
- **SIGMA** (03.08.2026): `SYSTEM` plafonat la 600 MB — vezi `depanare-pack-update.md`.
## Capcane
- **Segmentele `TEMPORARY` dintr-un tablespace permanent nu dispar intotdeauna la restart** (ACN,
06.08.2026: 1.3 GB ramasi si dupa repornirea serviciului). Daca `v$sort_usage` e gol, sunt orfane
si se curata fortat, ca `SYS`: `alter session set events 'immediate trace name DROP_SEGMENTS level
<ts#+1>'` (`ts#` din `v$tablespace`) — la ACN au disparut instantaneu, cu tot spatiul recuperat.
Daca nici asa nu pleaca, apartin unui DDL neterminat — cauta `SYS_JOURNAL%` (index online) sau
obiecte `INVALID/UNUSABLE` in schema respectiva.
- **`shrink space` pe un LOB cere ASSM**; pe un tablespace MSSM da `ORA-10635` (cazul `ROA` la ACN).
Echivalentul care merge: `alter table t move lob (col) store as (tablespace <ts>)` — reconstruieste
segmentul, tine tabela blocata cat dureaza si cere spatiu liber cat segmentul mutat.
- **Privilegiile `ANY` nu se aplica pe obiectele din schema `SYS`** cat timp
`O7_DICTIONARY_ACCESSIBILITY=FALSE` — orice curatare acolo cere `SYSDBA`.
- Parola `SYS` e de obicei cea generica (vezi `COMUN\docs\local\oracle.md`), dar **nu la toti
clientii** (ex. ROMCONSTRUCT) — cand nu merge, se ia cu `PACK_UPDATE.GetSchemaParola('SYS')`.
`-SysPassword` ramane optional: diagnosticul de baza merge complet fara el, doar sectiunile
SYSDBA se sar.
- **Rolurile nu se aplica in pachete cu drepturi de definitor**: un pachet care refera static
`dba_*`/`v$*` iese `INVALID` la clientul care are accesul doar prin rolul `DBA`, chiar daca
aceleasi interogari merg din SQL*Plus. De aceea granturile directe din `sys_2026_08_03_05`.
Lantul de actualizare **nu** se opreste in acest caz: `sqlplus` iese cu cod 0 la eroare de
compilare, deci se vede doar ca pachet invalid + job cazut.
- **Curatenia poate esua din lipsa de spatiu** (`DBMS_AUDIT_MGMT.CLEAN_AUDIT_TRAIL` a picat asa la
Rompetrol): intai ridici plafonul, apoi cureti.
- `RESIZE` pe datafile da `ORA-03297` daca extentele folosite nu sunt la coada fisierului — un
`DELETE` fara `MOVE`/`SHRINK` nu recupereaza MB.
- Dimensiunile reale ale fisierelor de pe disc nu se vad din SQL — `-Disc`, prin `ExecuteScriptOS`.
- **`-Disc` merge doar pe servere Windows** (`ExecuteScriptOS` lanseaza PowerShell). Pe Linux
expira curat dupa 60s, cu mesaj.
- **`MAX_PDB_STORAGE` se citeste doar de pe un alias care tinteste radacina CDB.** De pe un
serviciu de PDB (cazul obisnuit al aliasurilor din `tnsnames.ora`), `alter session set
container=CDB$ROOT` da `ORA-01031` — e nevoie de un alias separat spre radacina.

View File

@@ -26,20 +26,20 @@ $p = Start-Process 'C:\Program Files (x86)\Microsoft Visual FoxPro 9\vfp9.exe' -
$p.WaitForExit(120000); if (!$p.HasExited) { $p.Kill() }
```
- `-A` ignora config.fpw implicit, `-T` sare peste splash; **ambele obligatorii** - fara `-T`
procesul ramane pe ecranul de intampinare (simptom identic cu o eroare de compilare).
Un `-c<cale>` explicit (lipit de flag) e preluat chiar si impreuna cu `-A`.
- **SAFETY**: sub `-A` porneste ON, deci primul `STRTOFILE` peste un log existent (sau
`COMPILE` peste un `.err`/`.fxp` existent) scoate dialogul modal "overwrite?" si procesul
pare agatat. Pune `SET SAFETY OFF` ca PRIMA linie din script si/sau `SAFETY=OFF` +
`RESOURCE=OFF` intr-un config.fpw propriu pasat cu `-c`. Verificare: logheaza
`SET("SAFETY")`/`SET("RESOURCE")` la start.
procesul ramane pe ecranul de intampinare (simptom identic cu o eroare de compilare). `-c<cale>`
explicit (lipit de flag) e preluat si cu `-A`.
- **SAFETY**: sub `-A` porneste ON - primul `STRTOFILE` peste un log existent (sau `COMPILE` peste
un `.err`/`.fxp` existent) scoate dialogul modal "overwrite?" si procesul pare agatat. Pune
`SET SAFETY OFF` ca PRIMA linie din script si/sau `SAFETY=OFF`+`RESOURCE=OFF` intr-un config.fpw
propriu pasat cu `-c`. Verificare: logheaza `SET("SAFETY")`/`SET("RESOURCE")` la start.
- In script: logare cu STRTOFILE (nu WAIT WINDOW / debugger - nu exista consola);
`ON ERROR DO <handler> WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()` care logheaza si
continua (mimeaza ErrorHandler); `QUIT` obligatoriu la final.
- `LINENO()` din handler e relativ la inceputul metodei: linia in `.vc2` = linia raportata +
linia `PROCEDURE`.
- Nu rula cu IDE-ul sau exe-ul aplicatiei deschis (lock pe binare); sterge `.fxp`-ul vechi
daca ai editat scriptul intre rulari.
- Nu rula cu IDE-ul sau exe-ul aplicatiei deschis (lock pe binare); sterge `.fxp`-ul vechi dupa
editarea scriptului - altfel VFP ruleaza codul vechi din `.fxp` fara niciun semn (testul poate
trece fals; se prinde doar cand lipseste din log o linie scrisa doar de codul nou).
- Forme modale: `Show(1)` blocheaza. Replica in script doar liniile relevante din Show, sau
seteaza `WindowType = 0`.
@@ -67,7 +67,7 @@ Cel mai ieftin test dupa o modificare: `COMPILE` headless, fara aplicatie si far
## 5. Bisectia versiunilor de clase (regresii)
Cand un bug apare "de azi", compara cu clasa veche fara a atinge SVN:
Cand un bug apare "de azi", compara cu clasa veche fara sa atingi SVN:
1. `git show <rev>:clase\fisier.vcx > temp\fisier.vcx` (+ `.vct`); pentru diff lizibil,
`vcx2txt.ps1 -Source temp\fisier.vcx -CacheRoot temp\txt`.
2. In harness incarca DOAR copia (`SET CLASSLIB TO temp\fisier.vcx`), **nu ADDITIVE peste cea
@@ -87,8 +87,8 @@ Cand un bug apare "de azi", compara cu clasa veche fara a atinge SVN:
pe copie crapa; recreeaza indexul dupa copiere. Acelasi lucru pentru cursorii creati intr-un
test: trebuie sa aiba EXACT indecsii pe care ii creeaza fluxul real inainte de instantiere,
altfel ordinea/logica difera si testul da rezultat fals.
- **Un grid isi pierde TOATE coloanele** (`ColumnCount` devine 0, fara eroare in log) daca un
ControlSource crapa la re-evaluare in timp ce coloanele sunt atinse programatic (ex. font per
- **Un grid isi pierde TOATE coloanele** (`ColumnCount` devine 0, fara eroare in log) daca
ControlSource crapa la re-evaluare cat timp coloanele sunt atinse programatic (ex. font per
coloana la Init). Simptome in aval: `attachtogrid` copiaza 0 coloane, apoi `calctotal` da
"Property <cColWithLabel> is not found". Similar, un cursor legat la grid recreat de Init
lasa grid-ul fara coloane (eroare 1925).
@@ -98,29 +98,56 @@ Cand un bug apare "de azi", compara cu clasa veche fara a atinge SVN:
- **Coloana de grid cu ControlSource EXPRESIE (nu camp) cere `Bound = .F.`** Fara el: eroare 9
"Data type mismatch" la `CREATEOBJECT`-ul formei (faza de constructie, raportata la linia
apelanta, Details gol).
- **Erorile de instantiere sunt raportate la linia `CREATEOBJECT`, nu la `.Init`**: daca
- **Erorile de instantiere se raporteaza la linia `CREATEOBJECT`, nu la `.Init`**: daca
`Procedure` = scriptul apelant, eroarea vine din evaluarea definitiei clasei (`ADD OBJECT ...
WITH RowSource`, ControlSource-expresie), pentru ca bind-ul controalelor native se rezolva la
WITH RowSource`, ControlSource-expresie) - bind-ul controalelor native se rezolva la
CONSTRUCTIE, inainte de `Init`.
- **Literal string > 255 caractere = eroare de COMPILARE, nu de runtime** (masurat 24.07.2026:
255 trece, 256 pica). Mesaj: `Unrecognized command verb` daca linia incepe cu un apel de
metoda, `Command contains unrecognized phrase/keyword` la o atribuire. Insidios: restul
programului ruleaza, doar linia aceea lipseste din `.fxp` si da eroare 16 cand se ajunge la
ea. De aceea SQL-ul lung se scrie cu `TEXT TO <var> [TEXTMERGE] NOSHOW ... ENDTEXT` sau
concatenat. Verificare: `awk 'length($0) > 260 {print NR": "length($0)}' fisier.prg`.
- **Literal string > 255 caractere = eroare de COMPILARE, nu runtime** (255 trece, 256 pica).
Mesaj: `Unrecognized command verb` daca linia incepe cu un apel de metoda,
`Command contains unrecognized phrase/keyword` la o atribuire. Insidios: restul programului
ruleaza, doar linia lipseste din `.fxp` si da eroare 16 cand se ajunge la ea. De aceea SQL-ul
lung se scrie cu `TEXT TO <var> [TEXTMERGE] NOSHOW ... ENDTEXT` sau concatenat. Verificare:
`awk 'length($0) > 260 {print NR": "length($0)}' fisier.prg`.
- **Linie de COD (nu doar literal string) prea lunga intr-o metoda de clasa `.vc2` poate arunca
eroarea 11 ("Function argument value, type, or count is invalid") pe PRIMA instructiune a
metodei, nu pe linia vinovata** - simptom derutant. Se exclude prin diagnostic: aceeasi
expresie merge normal la nivel de program, in alta clasa, intr-o subclasa cu metoda noua, si
pe instanta virgina - deci nu tine de tipul datelor, de context sau de clasa parinte. Reper
practic: linii preexistente >200 caractere intr-o clasa mare functioneaza pana la ~250; pragul
real e in jur de 255, ca la literalii de string. Remediu: sparge expresia in pasi cu variabile
locale. Verificare (comparat intre fisierul curent si un backup anterior):
```powershell
$l=[IO.File]::ReadAllLines($p,[Text.Encoding]::GetEncoding(28591))
for($i=0;$i -lt $l.Length;$i++){ if($l[$i].Length -gt 200){ "{0}: len={1}" -f ($i+1), $l[$i].Length } }
```
- **Un UDF care citeste campul curent (`Nvl(camp,0)=1` sau similar) nu e de incredere intr-o
clauza de filtrare** (`SELECT ... WHERE`, `LOCATE FOR`, `SCAN FOR`, `DELETE FOR`) - pointerul
nu e garantat pe randul evaluat la fiecare apel, deci filtrul devine practic o valoare
constanta (nu se declanseaza deloc, sau loveste tot). Simptome vazute: comasare de randuri
care nu se mai producea deloc; test agatat. Remediu: in clauze de filtrare foloseste expresia
INLINE pe camp (`Nvl(camp,0) <> 1`); pastreaza helper-ul doar in cod procedural (`If`,
`Replace` pe randul curent), unde pointerul e garantat pozitionat.
- **`SET PROCEDURE TO x.prg`**: in `.exe` se rezolva din modulele compilate (orice `.prg` din
`.pjx`), din IDE doar prin `SET PATH`. O cale lipsa din `SET PATH` se vede deci doar necompilat,
iar in `Try` trece tacut.
## 7. Capcane la SCRIEREA scriptului de test
- **`SET SAFETY OFF` in primele linii, INAINTE de orice `STRTOFILE`/`CREATE CURSOR`** (plus
`SET TALK OFF`). Fara el VFP deschide dialogul de confirmare la suprascriere, iar headless
dialogul blocheaza procesul pana la timeout. Suitele existente il au deja - capcana apare la
scripturile ad-hoc, scrise repede pentru o masuratoare.
- **`DEFINE CLASS ... ENDDEFINE` nu poate sta la mijlocul programului principal.** Toate liniile
de DUPA `ENDDEFINE` dau "Statement is not in a procedure" (vezi `<script>.ERR`); scriptul
ruleaza doar pana acolo si se opreste silentios, fara sa ajunga la `QUIT` - simptom: vfp9.exe
pare agatat la nesfarsit. Pune orice `DEFINE CLASS` auxiliar la FINALUL fisierului.
de DUPA `ENDDEFINE` dau "Statement is not in a procedure" (vezi `<script>.ERR`); scriptul se
opreste silentios, fara sa ajunga la `QUIT` - simptom: vfp9.exe pare agatat la nesfarsit. Pune
orice `DEFINE CLASS` auxiliar la FINALUL fisierului.
- **Dummy-uri cu metode**: `CREATEOBJECT('Custom')` + `AddProperty()` adauga doar PROPRIETATI.
Daca clasa testata apeleaza `goExecutor.oExecute(...)`, dummy-ul trebuie sa fie
`DEFINE CLASS dummyexecutor AS Custom` cu `PROCEDURE oExecute` reala.
- **Diagnostic "script agatat"**, in ordine: (1) exista `<script>.ERR` langa `.prg`? => s-a
oprit la compilare; (2) CPU-ul procesului ~0 dupa cateva secunde (`Get-Process | select CPU`)
=> asteapta un dialog modal, nu proceseaza; confirma enumerand ferestrele procesului cu
=> asteapta un dialog modal; confirma enumerand ferestrele procesului cu
`EnumWindows`/`GetWindowText`/`GetWindowThreadProcessId` (`Add-Type`, user32) filtrat pe PID -
daca vezi doar fereastra principala + "Command", nu e dialog, cauta alta cauza (tipic `-T`
lipsa). Confirma mereu cauza inainte de a schimba scriptul.

41
docs/email-thunderbird.md Normal file
View File

@@ -0,0 +1,41 @@
# Citirea emailurilor (Thunderbird Portable)
Conectorul Gmail din Claude vede **doar** `mmarius28@gmail.com`. Conturile de lucru
(`marius.mutu@romfast.ro` etc.) nu sunt acolo — se citesc local, din mbox-urile Thunderbird:
```
D:\UTIL\portable\PortableApps\ThunderbirdPortable\Data\profile\ImapMail\<cont>\INBOX
```
Conturi active (dupa `LastWriteTime`): `mail.romfast.ro` (~36 MB, contul principal) si
`mail.romfast-1.ro` (~108 MB). Restul (`seanet.ro`, `romfast-4.ro`, `imap.googlemail.com`, …)
sunt vechi de ani.
```powershell
powershell -File COMUN\utile\citeste_email.ps1 -Cauta 'Diagnostic spatiu' -Ultimele 10
powershell -File COMUN\utile\citeste_email.ps1 -Nr <linie> [-Linii 200]
```
Prima forma listeaza `Cont / Linie / Data / De_la / Subiect` (filtru `-Cauta` pe subiect **sau**
expeditor, `-Cont mail.romfast.ro` restrange la un cont); a doua tipareste mesajul care incepe la
linia respectiva, pana la urmatorul separator mbox.
## Capcane
- **Nu da `Grep`/ripgrep pe folder**: `INBOX.sbd\Sent` are ~2.5 GB si cautarea expira.
- **Numerotarea liniilor difera intre unelte** (`Select-String` vs `Get-Content` vs `StreamReader`)
— mbox-ul are linii cu `\r` singur. Foloseste numarul dat de `citeste_email.ps1`, pentru ca
`-Nr` citeste cu acelasi cititor; daca linia ceruta nu e inceput de mesaj, scriptul trece la
contul urmator (`-Nr` fara `-Cont` cauta in toate).
- Thunderbird tine fisierul deschis → citire doar cu `FileShare::ReadWrite` (scriptul o face).
- Mesajele sunt in ordine cronologica, **cel mai nou la sfarsitul fisierului**; separatorul e
`From - <data>`. Corpurile HTML/base64 se tipar brut — pentru ele ia doar `Content-Type` si
primele linii, nu tot mesajul.
## Emailuri automate ROA
| Expeditor | Ce e |
|---|---|
| `roaupdate_acn@`, `roaupdate-sigma@`, `roaupdate-clever@`, `roaupdate-automotive@` … | jobul `DIAGSPATIU_ZILNIC`, subiect `Diagnostic spatiu Oracle <BAZA> <data> <ora>`, cate un expeditor per client. Vezi `depanare-spatiu-oracle.md` |
Emailul vine **doar la prag depasit**; tacere = totul in regula.

View File

@@ -10,11 +10,21 @@ in IDE. `txt2vcx.ps1` cu `-CacheRoot` = `-ProjectRoot` (implicit). Pasul 0 de ma
rularea `git_sync.ps1`; restul pasilor raman la fel. Fluxul cu cache extern (`vcx2txt.ps1` +
`-CacheRoot` separat) ramane doar pentru proiectele nemigrate.
**Capcana: `git_sync.ps1` cu `-ProjectRoot` pe COMUN direct.** Lista implicita
`-RoundtripExempt` are cai de forma `COMUN\clase\<f>.vcx` (raportate la radacina unei aplicatii,
unde COMUN e subfolder) si se lipeste de `-ProjectRoot`. Cand radacina E chiar COMUN, caile nu
mai potrivesc si clasele scutite (FFC/third-party cu `#INCLUDE`, ex. `oinventar.vcx`) raporteaza
fals `roundtrip text1 != text2`. Ruleaza atunci cu lista rebazata:
`git_sync.ps1 -ProjectRoot 'D:\ROA\ROAGEST\COMUN' -RoundtripExempt @('clase\accessibility.vcx',
'clase\oinventar.vcx','clase\_gdiplus.vcx','clase\_reportlistener.vcx',
'utile\foxcharts\foxcharts.vcx','utile\web\_webview.vcx')` - si apeleaza scriptul cu `&`, nu cu
`powershell -File` (acolo lista nu se leaga ca array).
## Parametri per proiect (nemigrate, cache extern)
- **ROAGEST**: `-Project 'D:\ROA\ROAGEST\roagest.pjx' -ProjectRoot 'D:\ROA\ROAGEST'
-CacheRoot 'D:\ROA\_vfp_textcache\roagest'`; procese de verificat inainte de write-back:
`vfp9`, `roagest`; patch-uri de review in `docs/diff_runda<N>_<subiect>.patch`.
-CacheRoot 'D:\ROA\_vfp_textcache\roagest'`; patch-uri de review in
`docs/diff_runda<N>_<subiect>.patch`.
## Pasii unei runde
@@ -26,9 +36,12 @@ rularea `git_sync.ps1`; restul pasilor raman la fel. Fluxul cu cache extern (`vc
NU tool-ul Edit/Write (UTF-8 strica diacriticele). Continut nou ASCII, TAB-uri ca in jur,
fara reflow (format position-sensitive, proprietati alfabetizate). Valabil si pentru `.prg`.
3. Patch review: `git diff --no-index <bak> <editat> > docs/diff_runda<N>_<subiect>.patch`
(exit 1 = normal). Utilizatorul revizuieste FISIERUL de patch si aproba; write-back-ul
(pasul 5) se face DOAR dupa aprobare. Commit doar dupa confirmare pe patch + test in IDE.
Comentariile in cod: maxim o linie (`*!* DD.MM.YYYY autor - motiv scurt`), fara explicatii lungi.
(exit 1 = normal). Utilizatorul revizuieste FISIERUL de patch si aproba — aprobarea
conditioneaza COMMIT-ul, nu write-back-ul: pasii 5 si 6 se fac imediat, fara sa astepti
raspunsul (si pe `COMUN`), ca review-ul sa primeasca rezultate de test, nu o propunere
netestata. Rollback daca patch-ul e respins sau modificarea nu merge: `git checkout` pe
binare (`.vcx`+`.vct`) sau write-back din `*.pre_runda<N>.bak`.
Comentariile in cod: conventia din `reguli_lucru.md` (punctul 2).
Obligatoriu inainte de a preda patch-ul la review: skill-ul de code-review rulat pe bucatile
de cod din diff (nu doar citire manuala) - prinde defecte gen IIF cu numar gresit de
argumente, deduplicari care nu se declanseaza niciodata, interogari mai largi decat e nevoie.
@@ -37,9 +50,14 @@ rularea `git_sync.ps1`; restul pasilor raman la fel. Fluxul cu cache extern (`vc
dintr-un cursor in loc de Scan manual; butoane din cmd_butoane.vcx in loc de butoane ad-hoc).
Inventarul comunelor: COMUN\docs\inventar-comun.md - se consulta si la pasul de plan/arhitectura,
inainte de a scrie cod nou.
4. Preconditie write-back: niciun proces vfp9/<exe proiect> (tin lock pe binar); nu se omoara.
4. Preconditie write-back: binarul tinta sa nu fie blocat. `txt2vcx.ps1` verifica singur
(`Test-ExclusiveAccess` pe `.vcx`+`.vct`) si refuza cu mesaj clar daca e lock. NU conteaza
existenta altor instante `vfp9` — utilizatorul poate lucra in paralel in alt proiect VFP —
si NU se omoara procese: cand lock-ul exista, se cere utilizatorului sa inchida sesiunea.
5. Write-back: `txt2vcx.ps1 -TextFile <vc2> -ProjectRoot <root> -CacheRoot <cache>`
(+ `-AllowComun` cu aprobare explicita pentru tinte COMUN — afecteaza toate aplicatiile ROA).
(+ `-AllowComun` pentru tinte COMUN — afecteaza toate aplicatiile ROA, deci schimbarea in sine
se propune explicit, dar write-back-ul local nu asteapta aprobarea; nimic nu pleaca la celelalte
aplicatii pana la commit+push).
Succes = fidelity-check trecut: binar cu mtime nou; `vcx2txt.ps1` ulterior il vede la zi.
6. Teste finale pe cerinta initiala (cerinta Marius, valabila in toate proiectele VFP):
dupa ultima runda, teste e2e (harness UI, pe fluxul real al utilizatorului) care verifica
@@ -47,7 +65,8 @@ rularea `git_sync.ps1`; restul pasilor raman la fel. Fluxul cu cache extern (`vc
dat de Marius, cu valorile lui asteptate — nu doar teste per-fix. Assert-uri pe continutul
rezultatului (sume, campuri, randuri), nu pe efecte de suprafata ("a aparut un rand" nu e
suficient).
7. Backup-urile `.pre_runda*.bak` si patch-urile se sterg la curatenia de dupa commit.
7. Curatenie dupa commit (backup-uri `.pre_runda*.bak`, patch-uri, artefacte de test):
`powershell -File COMUN\utile\curatenie.ps1` — vezi regula 1 din `reguli_lucru.md`.
## Capcane
@@ -57,9 +76,24 @@ rularea `git_sync.ps1`; restul pasilor raman la fel. Fluxul cu cache extern (`vc
- Metoda noua de clasa cere `*m: nume` in `*<DefinedPropArrayMethod>`; fara ea, prima salvare
din IDE o arunca tacut, iar refresh-ul urmator absoarbe pierderea in cache (si in .bak-uri).
Override-urile de metode de baza (Init, Show, hook-uri) nu au nevoie de `*m:`.
- **Proprietate noua de clasa cere identic `*p: nume` in `*<DefinedPropArrayMethod>`** — nu doar
valoarea in `*<PropValue>`. Fara `*p:`, valoarea se scrie in text, **trece fidelity-check-ul**
(fidelity compara doar text-sursa cu text-regenerat) si ajunge in binar ca text, dar VFP nu o
materializeaza pe obiect: `PEMSTATUS(o,'nume',5)` da `.F.` si orice acces cade cu eroarea 1734
"Property ... is not found". Dovedit in ambele sensuri pe o clasa de proba izolata (cu `*p:` ->
`.T.`, fara -> `.F.`).
- **FoxBin2Prg sorteaza alfabetic cu `_` DUPA literele obisnuite**, nu in ordine ASCII brut (unde
`'_' (0x5F) < 'v' (0x76)` pe litere mici). O intrare `*p:`/`*m:` scrisa de mana in ordine "ASCII
corecta" pica fidelity-check-ul; ordinea canonica se citeste din textul regenerat in
`<staging>\verify\*.vc2` (vezi punctul de mai jos despre pozitia metodelor noi — se aplica identic
proprietatilor).
- FoxBin2Prg NU pastreaza pozitia in text a unei metode noi: o regenereaza la pozitia
alfabetica din `*<DefinedPropArrayMethod>`. O metoda scrisa in alta parte a fisierului
face fidelity-check-ul sa pice. Sursa de adevar pentru relocare e textul regenerat din
`<staging>\verify\` - muta metoda unde apare acolo si reia write-back-ul.
- Salvarea din VFP IDE peste un binar scris de txt2vcx poate PIERDE si definitii `*m:` deja
existente, desi corpurile PROCEDURE raman (patit pe ROAGEST: `import_adauga_factura.recalc_tva`,
`import_nota.do_adauga/do_copie/do_reface`, 07.2026); simptom: crash la Createobject cu
`import_nota.do_adauga/do_copie/do_reface`); simptom: crash la Createobject cu
"Data type mismatch" raportat la linia apelanta. Dupa orice sesiune IDE pe clasa: refresh
cache + compara lista `*m:` cu starea de dinainte.
- Nu folosi *Project > Build* ca sa recompilezi un binar vizat: rebuild-ul recompileaza toate
@@ -68,3 +102,8 @@ rularea `git_sync.ps1`; restul pasilor raman la fel. Fluxul cu cache extern (`vc
fluxul text->bin punctual pe binarul vizat.
- Subagentii delegati primesc regulile 2-5 in prompt si raporteaza unicitatea sirurilor
inlocuite + rezultatul fidelity-check-ului.
- Fisierele `.vc2`/`.sc2` sunt CRLF, dar here-string-urile PowerShell (`"...`r`n..."` sau
`@"..."@`) produc LF simplu pe orice linie noua inserata daca nu incluzi explicit `` `r`n ``
la fiecare capat de linie - rezultatul e un fisier cu sfarsituri de linie amestecate (CRLF pe
continutul vechi, LF pe cel nou). Verificare finala obligatorie dupa orice scriere: numara
octetii `0x0A` neprecedati de `0x0D` (LF izolati) - trebuie sa fie 0.

View File

@@ -0,0 +1,53 @@
# Flux: modificare/stergere nota in Registrul Jurnal
Comportament CORECT (nu bug): la **modificarea** unei note din Registrul Jurnal, documentul
original nu se suprascrie. Se marcheaza `sters = 1` pe randurile vechi (`ACT`/`RUL`/`RUL_OBINV`),
apoi se scrie un document NOU cu alt `cod`, pastrand acelasi `id_fact`/`id_factd`. Ambele operatii
ruleaza intr-o tranzactie manuala unica (commit sau rollback pe amandoua).
## Unde
- `afisjurcom.do_modifica` - `COMUN\clase\comun.vc2:2222-2562`. Deschide tranzactia manuala
(`Thisform.do_deschide_tranzactie()`, linia 2448), apoi `oscrie_in_fisiere(2,...)` = STERGE
(linia 2451), apoi `oscrie_in_fisiere(0,...)` = SCRIE (linia 2479), apoi
`pack_contafin.finalizeaza_modificare_nota(...)` (2484-2486), apoi
`Thisform.do_inchide_tranzactie(...)` (linia 2535) - commit daca tot ce a rulat inainte a
reusit, rollback altfel.
- `do_deschide_tranzactie`/`do_inchide_tranzactie` (`_frmbase`, `COMUN\clase\_frm_base.vc2:252,279`;
varianta identica ca procedura globala in `COMUN\programe\oproceduri_rulaje.prg:287,303`):
`SQLSetProp(gnHandle,'Transactions',2)` la deschidere, `SQLCOMMIT`/`SQLROLLBACK` +
`SQLSetProp(...,'Transactions',1)` la inchidere.
- `oscrie_in_fisiere.prg` (`COMUN\programe\oscrie_in_fisiere.prg`): `tnScrie_Sterge` 0=scriere,
2=stergere. Apeleaza server-side `pack_contafin.init_scriere_act_rul_local` +
`final_scriere_act_rul_local` -> `finalizeaza_scriere_act_rul`, care ruleaza `SCRIE_IN_ACT`
(scriere) sau `STERGE_DIN_ACT` (stergere) din `PACK_CONTAFIN.pck`.
- `PACK_CONTAFIN.STERGE_DIN_ACT` (`COMUN\docs\PACK_CONTAFIN.pck:1815-1859`):
`UPDATE ACT SET STERS = 1 ... WHERE COD = tnCod` - marcheaza vechiul document, pe `cod`-ul vechi.
- `PACK_CONTAFIN.SCRIE_IN_ACT` (`PACK_CONTAFIN.pck:630-901`): `LN_COD := pack_contafin.GET_COD()`
(linia 648) aloca un `cod` nou; `UPDATE ACT_TEMP SET COD = LN_COD, ...` (linia 897) il scrie pe
noul document - `ID_FACT` nu e atins, ramane cel din documentul original.
- `PACK_CONTAFIN.finalizeaza_modificare_nota` (`PACK_CONTAFIN.pck:8601-8651`): aloca din nou
`lnCodNou := pack_contafin.get_cod()` si actualizeaza pe codul nou `vanzari`
(`pack_facturare.actualizeaza_vanzari`) si `atasamente_vanzari`. `nom_lucrari` se actualizeaza
DOAR pentru `id_set IN (31003,31004,31005,31011)` (repune `id_fact`), nu general. `gest_inventar`
NU se leaga de `cod`-ul nou - se identifica dupa `dataora_validat + an + luna` (cazul
`id_set = 90101`, note de inventariere).
## Atentie: nu e valabil la fel pentru stergerea simpla
`afisjurcom.do_sterge` (`comun.vc2:2565-2724`) ofera doua optiuni (`xmenu`, linia 2625):
- **Stergere document** (`lnOptiune = 1`): DOAR `OSCRIE_IN_FISIERE(2,...)` + `finalizeaza_stergere_nota`
- marcheaza `sters = 1`, NU se creeaza document nou.
- **Anulare document** (`lnOptiune = 2`): STERGE (linia 2698) + SCRIE (linia 2709, cu sumele puse pe
0) - creeaza si document nou, la fel ca la modificare - dar aici cele doua apeluri NU sunt
invelite intr-o tranzactie manuala comuna (nu apare `do_deschide_tranzactie`/
`do_inchide_tranzactie` in `do_sterge`); fiecare `OSCRIE_IN_FISIERE` isi gestioneaza singur
commit-ul (vezi `tlModificare`/`llManualTransactions` in `oscrie_in_fisiere.prg:111-165`).
## Implicatii practice
- Codul (`cod`) unui document din Registrul Jurnal NU e stabil dupa modificare/anulare - se schimba
la fiecare editare. Cod hardcodat sau retinut dintr-o executare anterioara devine invalid.
- Regasirea documentului editat se face dupa `id_fact` (sau alt marcaj stabil), niciodata dupa `cod`.
- Randurile `sters = 1` ramase in `ACT`/`RUL`/`RUL_OBINV` dupa o modificare sunt normale (istoric),
nu date corupte sau duplicate de curatat.

View File

@@ -1,65 +1,46 @@
# Flux SVN + git pentru COMUN
**SVN = șeful** (munca reală circulă prin el). **git = oglindă** pentru unelte (Claude, căutare).
git primește de la SVN, niciodată invers.
## Reguli
1. **Munca reală se comite DOAR în SVN.** Nu face `git commit` cu o modificare nouă care n-a trecut prin SVN.
2. **git se împrospătează DIN svn**, într-o singură direcție.
3. **COMUN se publică pe git dintr-UN SINGUR folder** (publisher, ex. `ROAAUTO\COMUN`). Celelalte doar se aliniază la origin.
## Lucrat în paralel în 2 proiecte (ex. roagest + roaauto), fișiere diferite
### 1. Împaci în SVN
```
# ROAGEST\COMUN
svn commit -m "modificari roagest"
# ROAAUTO\COMUN
svn update # aduce fisierele din roagest (alte fisiere -> fara conflict)
svn commit -m "modificari roaauto"
# ROAGEST\COMUN
svn update # aduce fisierele din roaauto
```
Acum ambele copii SVN au tot. E sursa de adevăr.
### 2. Oglindești în git (doar din folderul publisher)
```
cd ROAAUTO\COMUN
git add -A
git commit -m "sync svn"
git push
```
### 3. Celălalt folder: aliniere, NU commit
```
cd ROAGEST\COMUN
git fetch origin
git reset --hard origin/main
```
Sigur: fișierele sunt deja identice cu origin (le-a făcut svn), `reset` doar mută pointerul.
## Când te muți dintr-un proiect în altul
```
svn update # in proiectul unde intri
git reset --hard origin/main # in COMUN, ca git-ul sa fie curat
```
## Regula care rezumă tot
> Un singur folder publică în git (commit+push). Celelalte doar `git reset --hard origin/main`.
> Munca circulă prin SVN; git fotografiază rezultatul.
## Model de branching (git urmareste text .??2)
git urmareste versiunile text FoxBin2Prg (.vc2/.sc2/…), improspatate in-arbore cu
`git_sync.ps1` la inceput de sesiune si inainte de orice commit; nu comite cat timp
`git_sync` raporteaza esecuri (exit nenul). Doua benzi:
- **`main` = oglinda SVN**: primeste DOAR commit-uri `sync SVN rN`, facute din stare curata
(imediat dupa `svn update`, inainte de lucru local).
- **Claude lucreaza pe branch** `claude/<subiect>` si comite doar acolo;
`git diff main..claude/<subiect>` arata exact si numai munca lui.
- Dupa ce modificarile intra in SVN (`svn commit` facut de utilizator), branch-ul se inchide
(merge in `main` la urmatorul sync sau stergere).
- Igiena: sync pe `main` doar din stare curata — `svn update` in mijlocul lucrului amesteca
binarele pe disc.
# Flux SVN + git pentru COMUN
**SVN = șeful** (munca reală circulă prin el). **git = oglindă** pentru unelte (Claude, căutare).
git primește de la SVN, niciodată invers.
## Reguli
1. **Munca reală se comite DOAR în SVN.** Nu face `git commit` cu o modificare noua care n-a
trecut prin SVN.
2. **git se împrospătează DIN svn**, într-o singură direcție.
3. **COMUN se publică pe git dintr-UN SINGUR folder** (publisher, ex. `ROAAUTO\COMUN`). Celelalte
doar se aliniază la origin.
## Lucrat în paralel în 2 proiecte (ex. roagest + roaauto), fișiere diferite
1. **Împaci în SVN**: `svn commit` in ROAGEST\COMUN -> `svn update` in ROAAUTO\COMUN (aduce
fisierele din roagest, fara conflict pe fisiere diferite) -> `svn commit` acolo -> `svn update`
inapoi in ROAGEST\COMUN. Acum ambele copii SVN au tot — e sursa de adevăr.
2. **Oglindești în git, doar din folderul publisher**: `git add -A` + `git commit` + `git push`
in ROAAUTO\COMUN.
3. **Celălalt folder: aliniere, NU commit** — in ROAGEST\COMUN: `git fetch origin` +
`git reset --hard origin/main`. Sigur: fișierele sunt deja identice cu origin (le-a făcut svn),
`reset` doar mută pointerul.
Când te muți dintr-un proiect în altul: `svn update` in proiectul unde intri, apoi
`git reset --hard origin/main` in COMUN, ca git-ul sa fie curat.
## Regula care rezumă tot
> Un singur folder publică în git (commit+push). Celelalte doar `git reset --hard origin/main`.
> Munca circulă prin SVN; git fotografiază rezultatul.
## Model de branching (git urmareste text .??2)
git urmareste versiunile text FoxBin2Prg (.vc2/.sc2/…), improspatate in-arbore cu `git_sync.ps1`
la inceput de sesiune si inainte de orice commit; nu comite cat timp `git_sync` raporteaza esecuri
(exit nenul). Doua benzi:
- **`main` = oglinda SVN**: primeste DOAR commit-uri `sync SVN rN`, facute din stare curata
(imediat dupa `svn update`, inainte de lucru local).
- **Claude lucreaza pe branch** `claude/<subiect>` si comite doar acolo;
`git diff main..claude/<subiect>` arata exact si numai munca lui.
- Dupa ce modificarile intra in SVN (`svn commit` facut de utilizator), branch-ul se inchide
(merge in `main` la urmatorul sync sau stergere).
- Igiena: sync pe `main` doar din stare curata — `svn update` in mijlocul lucrului amesteca
binarele pe disc.

View File

@@ -1,86 +0,0 @@
# Prompt: init git in paralel cu SVN pentru un proiect ROA
Foloseste acest prompt intr-o sesiune Claude Code noua, deschisa in radacina proiectului
tinta (ex. `D:\ROA\ROAIMOB`). Functioneaza generic pentru orice proiect VFP din `D:\ROA\`
care are structura ROAACNPRO (proiect + subfolder COMUN\ partajat, ambele in SVN).
---
```
Vreau sa initializezi git pentru proiectul VFP din directorul curent, in paralel cu SVN-ul
existent (nu atinge SVN, nu rula comenzi svn, doar adauga .svn/ in .gitignore).
Structura e identica cu D:\ROA\ROAACNPRO: acest folder e propriul proiect VFP (are un .PJX
al lui), si contine un subfolder COMUN\ care e framework-ul PARTAJAT intre toate aplicatiile
ROA, versionat separat prin SVN (are propriul .svn\).
Fa exact ce s-a facut deja pentru ROAACNPRO (poti citi acolo ca referinta/sablon):
- D:\ROA\ROAACNPRO\.gitignore (sablon pentru .gitignore-ul proiectului principal)
- D:\ROA\ROAACNPRO\COMUN\.gitignore (sablon pentru .gitignore-ul din COMUN)
- D:\ROA\ROAACNPRO\CLAUDE.md (conventii proiect) si docs\cautare_vcx_vct.md (cum se cauta
cod in interiorul .vcx/.scx binare, via D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1)
Pasi:
1. Verifica intai ce exista deja: `git status`/`.git` in radacina si in COMUN\, si
`git remote -v` daca exista deja vreun remote configurat gresit (asa cum a fost cazul la
ROAACNPRO, unde originul proiectului principal pointa gresit catre repo-ul comun.git).
2. REPO PRINCIPAL (radacina acestui folder):
- Daca nu exista .git, `git init -b main`.
- Creeaza/adapteaza .gitignore dupa modelul ROAACNPRO/.gitignore (artefacte VFP compilate:
*.fxp, *.mpx, *.bak, *.mpr, *.err, log.txt, *.tmp, *.dct, *.exe, cruft Windows), plus
obligatoriu `COMUN/` (COMUN e gestionat de git-ul lui separat, nu de-al acestui repo)
si `.svn/`.
- Deduce numele repo-ului gitea dupa conventia romfast/<nume-folder-lowercase>.git
(ex. romfast/roaimob.git). INAINTE sa creezi/pushezi orice, verifica cu
`git ls-remote git@gitea.romfast.ro:romfast/<nume>.git` daca exista deja si ce contine
(clone --depth 1 intr-un folder temporar din scratchpad daca ai dubii). Daca exista deja
cu istoric care nu se potriveste cu ce ai local, OPRESTE-TE si intreaba-ma inainte sa
faci push sau orice suprascriere.
- Daca remote-ul e gol/nou: add -A, commit "Initial commit — sursa <PROIECT>", adauga
origin, push normal (fara --force).
3. COMUN\ (subfolder-ul partajat):
- Initializeaza un git SEPARAT, propriu, in interiorul COMUN\ (COMUN are propriul .git,
nu e tracked de repo-ul principal — de-asta l-am exclus mai sus).
- .gitignore propriu in COMUN\ dupa modelul ROAACNPRO/COMUN/.gitignore (artefacte VFP +
`.svn/` + `bash.exe.stackdump`).
- Origin-ul din COMUN\ trebuie sa fie EXACT acelasi repo pentru toate proiectele ROA:
git@gitea.romfast.ro:romfast/comun.git — repo-ul asta e deja populat (din COMUN-ul lui
ROAACNPRO). NU face commit+push orbeste peste el.
- Fa intai `git fetch origin`, compara continutul de pe origin/main cu fisierele locale
din acest COMUN\ (diff pe folder, nu doar pe nume). Daca sunt identice sau diferentele
sunt neglijabile, seteaza pur si simplu branch-ul local sa urmareasca origin/main (fara
sa strici fisierele din working copy SVN). Daca sunt diferente reale intre COMUN-ul
acestui proiect si cel deja impins pe gitea, arata-mi un rezumat al diferentelor si
intreaba-ma explicit cum procedez (nu face force-push fara aprobarea mea explicita —
ar sterge ireversibil istoricul comun tuturor proiectelor ROA).
4. Cautare in cod VFP binar (.vcx/.scx) pentru acest proiect:
- Foloseste acelasi vcx2txt.ps1, dar parametrizat pentru proiectul curent (nu ROAACNPRO):
powershell -ExecutionPolicy Bypass -File D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1 `
-Project D:\ROA\<PROIECT>\<proiect>.PJX -ProjectRoot D:\ROA\<PROIECT> `
-CacheRoot D:\ROA\UTIL\foxbin2prg\_textcache_<proiect>
- Cache separat per proiect (nu-l amesteca cu _textcache al ROAACNPRO). Grep in cache-ul
respectiv, la fel ca in docs\cautare_vcx_vct.md.
5. La final, adauga/actualizeaza CLAUDE.md al acestui proiect cu o sectiune scurta: git ruleaza
in paralel cu SVN legacy (SVN ramane sursa "vie" pentru COMUN, sincronizat manual catre git);
COMUN e partajat intre toate aplicatiile ROA prin acelasi git@gitea.romfast.ro:romfast/comun.git;
cautarile in .vcx/.scx se fac cu vcx2txt.ps1 parametrizat pentru acest proiect (vezi mai sus).
Inainte de orice `push --force` sau orice operatie care ar suprascrie istoric remote deja
existent (mai ales pe romfast/comun.git, care e comun mai multor proiecte), opreste-te si
intreaba-ma explicit — nu decide singur.
```
---
## Note
- Cel mai sensibil pas e COMUN\: daca versiunea de COMUN a noului proiect difera de cea deja
impinsa pe `comun.git` (din ROAACNPRO), Claude trebuie sa se opreasca si sa intrebe cum se
reconciliaza, nu sa faca force-push automat.
- Daca `romfast/<proiect>.git` nu exista inca pe gitea, trebuie creat gol acolo inainte de push
(manual sau prin API) — altfel push-ul esueaza cu "repository not found".

View File

@@ -1,46 +1,46 @@
# Inrolarea unui proiect ROA (Visual FoxPro) in fluxul git-text FoxBin2Prg
Instructiuni pas cu pas pentru o sesiune Claude Code care inroleaza un proiect ROA
in fluxul in care git urmareste DOAR versiunile text FoxBin2Prg (.vc2/.sc2/.fr2/.mn2/
.lb2/.pj2/.dc2/.db2) generate in arbore, langa binarele VFP. SVN ramane sursa de
adevar si nu se atinge (niciun svn commit fara acordul explicit al utilizatorului).
Pasi pentru o sesiune Claude Code care inroleaza un proiect ROA in fluxul in care git urmareste
DOAR versiunile text FoxBin2Prg (.vc2/.sc2/.fr2/.mn2/.lb2/.pj2/.dc2/.db2) generate in arbore,
langa binarele VFP. SVN ramane sursa de adevar si nu se atinge (niciun svn commit fara acordul
explicit al utilizatorului).
Proiecte deja inrolate (16.07.2026): ROACONT, ROAGEST, ROAAUTO, ROAIMOB, ROAACNPRO,
ROAFACTURARE + COMUN (romfast/comun.git). Modelul de referinta este ROACONT.
Proiecte deja inrolate: ROACONT, ROAGEST, ROAAUTO, ROAIMOB, ROAACNPRO, ROAFACTURARE + COMUN
(romfast/comun.git). Modelul de referinta e ROACONT.
## Reguli pentru sesiunea care executa
- Foloseste EXCLUSIV PowerShell pentru comenzi (NU tool-ul Bash — bash.exe crapa pe
aceste masini si lasa stackdump-uri).
- NU face niciun `svn commit`. NU modifica binarele VFP. La final binarele trebuie sa
fie byte-identice (verificabil cu `svn status`: niciun binar M).
- Rularile de conversie dureaza zeci de minute pe proiecte mari: sunt incrementale,
daca expira timeout-ul tool-ului se reiau pana la capat.
- Foloseste EXCLUSIV PowerShell (NU Bash — bash.exe crapa pe aceste masini si lasa stackdump-uri).
- NU face niciun `svn commit`. NU modifica binarele VFP. La final binarele trebuie sa fie
byte-identice (`svn status`: niciun binar M).
- Rularile de conversie dureaza zeci de minute pe proiecte mari: sunt incrementale, daca expira
timeout-ul tool-ului se reiau pana la capat.
- Nu rula doua conversii git_sync in paralel pe acelasi arbore.
## Preconditii
1. Tooling-ul partajat exista in `D:\ROA\UTIL\foxbin2prg\`: `git_sync.ps1`,
`vfp_filemap.ps1`, `txt2vcx.ps1`, `roa_sync.ps1`, `test_git_sync.ps1`,
`test_roundtrip.ps1`. Citeste-le inainte (macar help-ul din git_sync.ps1).
2. Proiectul e working copy SVN valid (`svn info D:\ROA\<PROIECT>`), cu `COMUN\`
inauntru (external SVN).
3. Repo-ul gitea exista: `git ls-remote git@gitea.romfast.ro:romfast/<proiect>.git`.
Daca nu exista, cere utilizatorului sa-l creeze din interfata gitea (NU crea
repo-uri prin API din proprie initiativa).
4. SVN global-ignores pe masina contine `*.vc2 *.sc2 *.fr2 *.mn2 *.lb2 *.pj2 *.dc2
*.db2 *.dbf.cfg` (in `%APPDATA%\Subversion\config`, sectiunea [miscellany]).
Fara asta, textele apar ca `?` in svn status si risca svn add accidental.
5. Daca proiectul ARE deja git cu istoric si urmeaza reset: confirmarea utilizatorului
ca nu exista clone active pe alte masini (force-push rescrie istoria).
1. Tooling partajat in `D:\ROA\UTIL\foxbin2prg\`: `git_sync.ps1`, `vfp_filemap.ps1`,
`txt2vcx.ps1`, `test_git_sync.ps1`, `test_roundtrip.ps1`. Citeste-le inainte (macar help-ul
din git_sync.ps1). `roa_sync.ps1` (+ `test_roa_sync.ps1`) traieste in `COMUN\scripts\` si
vine singur cu svn update; in foxbin2prg a ramas doar un stub de compatibilitate.
2. Proiectul e working copy SVN valid (`svn info D:\ROA\<PROIECT>`), cu `COMUN\` inauntru
(external SVN).
3. Repo-ul gitea exista: `git ls-remote git@gitea.romfast.ro:romfast/<proiect>.git`. Daca nu
exista, cere utilizatorului sa-l creeze din interfata gitea (NU crea repo-uri prin API din
proprie initiativa).
4. SVN global-ignores pe masina contine `*.vc2 *.sc2 *.fr2 *.mn2 *.lb2 *.pj2 *.dc2 *.db2
*.dbf.cfg` (in `%APPDATA%\Subversion\config`, sectiunea [miscellany]). Fara asta, textele apar
ca `?` in svn status si risca svn add accidental.
5. Daca proiectul ARE deja git cu istoric si urmeaza reset: confirmarea utilizatorului ca nu
exista clone active pe alte masini (force-push rescrie istoria).
## Pasi
### 1. Inventar prealabil (inainte de orice stergere)
- Exista `.git`? Noteaza `git remote -v` si branch-ul. Exista `COMUN\.git`?
- `git ls-files *.dbf` (daca exista repo vechi): tabelele urmarite azi ca binare sunt
candidate la conversie .db2 (cerinta: tot ce e convertibil trece pe text).
- `git ls-files *.dbf` (daca exista repo vechi): tabelele urmarite azi ca binare sunt candidate
la conversie .db2 (cerinta: tot ce e convertibil trece pe text).
### 2. Conversia completa
@@ -48,25 +48,25 @@ ROAFACTURARE + COMUN (romfast/comun.git). Modelul de referinta este ROACONT.
& D:\ROA\UTIL\foxbin2prg\git_sync.ps1 -ProjectRoot D:\ROA\<PROIECT>
```
- DbfList implicit acopera `Locale\locale*.dbf`, `Help\*.dbf`, `DATE\Optiuni_*.dbf`
si toate dbf-urile COMUN. Tabele de configurare specifice proiectului se adauga cu
`-DbfList` explicit (ATENTIE: parametrii array NU se pot pasa prin
`powershell -File` — invoca scriptul in-process cu `&`, altfel array-ul se
colapseaza). Tabele operationale mari nu se adauga; un .db2 peste 5 MB ramane binar.
- DbfList implicit acopera `Locale\locale*.dbf`, `Help\*.dbf`, `DATE\Optiuni_*.dbf` si toate
dbf-urile COMUN. Tabele de configurare specifice proiectului se adauga cu `-DbfList` explicit
(ATENTIE: parametrii array NU se pot pasa prin `powershell -File` — invoca scriptul in-process
cu `&`, altfel array-ul se colapseaza). Tabele operationale mari nu se adauga; un .db2 peste
5 MB ramane binar.
- Esecuri de conversie — se investigheaza fiecare:
- meniuri pre-VFP9 ("NOT in VFP 9 Format"): raman binare, cu exceptii negate `!` in
.gitignore; intra in flux doar dupa re-salvare in VFP9 (MODIFY MENU -> save);
- clase FFC/third-party cu roundtrip fals-negativ (#INCLUDE lipsa in staging izolat,
ex. cele 6 din COMUN deja scutite implicit): se adauga la `-RoundtripExempt`;
- clase FFC/third-party cu roundtrip fals-negativ (#INCLUDE lipsa in staging izolat, ex. cele
6 din COMUN deja scutite implicit): se adauga la `-RoundtripExempt`;
- alte esecuri reale: fisierul ramane binar urmarit (exceptie `!`) si se raporteaza.
- Regula: nu se trece mai departe cu esecuri neexplicate (exit code nenul).
### 3. .gitignore si .gitattributes
- Copiaza `D:\ROA\ROACONT\.gitignore` ca model si adapteaza: sectiunea machine-local
(exe-ul proiectului, <proiect>_ref.DBF/FPT/CDX, FOXUSER, .ini/.ARM, log-uri) si
sectiunea dbf: fiecare .dbf care are .db2 se ignora INDIVIDUAL (plus .fpt-ul lui).
NU ignora: `*.??2`, `*.dbf.cfg`, grafica (bmp/ico/jpg/png), ocx, tmpl.
- Copiaza `D:\ROA\ROACONT\.gitignore` ca model si adapteaza: sectiunea machine-local (exe-ul
proiectului, <proiect>_ref.DBF/FPT/CDX, FOXUSER, .ini/.ARM, log-uri) si sectiunea dbf: fiecare
.dbf care are .db2 se ignora INDIVIDUAL (plus .fpt-ul lui). NU ignora: `*.??2`, `*.dbf.cfg`,
grafica (bmp/ico/jpg/png), ocx, tmpl.
- `.gitattributes` cu `* -text` (SVN ramane autoritatea EOL; git nu normalizeaza).
### 4. Init/reset repo proiect
@@ -79,13 +79,12 @@ git -C D:\ROA\<PROIECT> add -A
```
VERIFICARE OBLIGATORIE inainte de commit (`git ls-files` pe staged):
- 0 binare convertibile urmarite (vcx/vct/scx/sct/frx/frt/mnx/mnt/lbx/lbt/pjx/pjt/
dbc/dct/cdx/dcx), cu exceptia celor cu `!` justificate;
- 0 binare convertibile urmarite (vcx/vct/scx/sct/frx/frt/mnx/mnt/lbx/lbt/pjx/pjt/dbc/dct/cdx/dcx),
cu exceptia celor cu `!` justificate;
- textele .??2 prezente; 0 fisiere din COMUN/ (are repo-ul lui).
Commit: `Initial: flux text FoxBin2Prg (git urmareste .??2 in-arbore, binarele VFP
git-ignored)` + linia Co-Authored-By a sesiunii. Push: `git push -u origin main`
(`--force` doar la reset).
Commit: `Initial: flux text FoxBin2Prg (git urmareste .??2 in-arbore, binarele VFP git-ignored)`
+ linia Co-Authored-By a sesiunii. Push: `git push -u origin main` (`--force` doar la reset).
### 5. Clona COMUN a proiectului
@@ -98,34 +97,34 @@ git -C D:\ROA\<PROIECT>\COMUN reset origin/main # mixed: pastreaza disc
git -C D:\ROA\<PROIECT>\COMUN checkout origin/main -- .gitignore
```
Diferentele ramase in `git status` = revizii SVN diferite ale clonei (normal).
NU comite nimic in comun.git dintr-o clona decalata — comun se comite doar din clona
in care s-a lucrat efectiv, dupa svn update.
Diferentele ramase in `git status` = revizii SVN diferite ale clonei (normal). NU comite nimic in
comun.git dintr-o clona decalata — comun se comite doar din clona in care s-a lucrat efectiv,
dupa svn update.
### 6. roa_sync.bat
Copiaza `D:\ROA\ROACONT\roa_sync.bat` in radacina proiectului (e generic, foloseste
`%~dp0`) si include-l in commit. Utilizatorul il ruleaza la inceput de sesiune:
svn update -> git_sync -> commit "sync SVN rN" pe main (proiect + COMUN) -> inchide
branch-urile claude/* cu diff gol.
Copiaza `D:\ROA\ROAFACTURARE\roa_sync.bat` in radacina proiectului (generic, foloseste `%~dp0` si
cheama `COMUN\scripts\roa_sync.ps1`) si include-l in commit. Utilizatorul il ruleaza la inceput de
sesiune: svn update -> git_sync -> commit "sync SVN rN" pe main (proiect + COMUN) -> reconciliere
cu origin + push (doar commit-uri de sync) -> inchide branch-urile claude/* cu diff gol.
### 7. Verificari finale
- Acoperire: fiecare binar convertibil din arbore (inclusiv COMUN) are text .??2
langa el (exceptiile `!` enumerate si justificate).
- Acoperire: fiecare binar convertibil din arbore (inclusiv COMUN) are text .??2 langa el
(exceptiile `!` enumerate si justificate).
- `svn status`: niciun binar modificat, niciun .??2 adaugat in SVN.
- `git ls-remote origin main` = HEAD-ul local.
- Raport final: numar texte per tip, esecuri/scutiri, commit hash, push status.
## Note operationale
- Dialogurile modale FoxBin2Prg sunt suprimate de scripturi printr-un `foxbin2prg.cfg`
cu `DontShowErrors: 1` scris per-director de staging (cfg-ul global de langa exe NU
e fiabil). Daca utilizatorul vede totusi un MessageBox, e un dialog nativ VFP —
watchdog-ul din Invoke-FoxBin2PrgSafe il omoara la timeout.
- Dialogurile modale FoxBin2Prg sunt suprimate de scripturi printr-un `foxbin2prg.cfg` cu
`DontShowErrors: 1` scris per-director de staging (cfg-ul global de langa exe NU e fiabil).
Daca utilizatorul vede totusi un MessageBox, e un dialog nativ VFP — watchdog-ul din
Invoke-FoxBin2PrgSafe il omoara la timeout.
- Tabelele legate de un DBC au nevoie de .dbc/.dct/.dcx si .cdx langa ele la conversie
(git_sync face asta automat in staging).
- `DBF_Conversion_Support: 4` (scris de git_sync in cfg-ul de staging) exporta DATELE
in .db2, nu doar structura.
- Fisierele doar-git (docs, .bat, .gitignore) se comit separat, inainte de sync-ul
"sync SVN rN", altfel nimeresc in commit-ul de sincronizare.
- `DBF_Conversion_Support: 4` (scris de git_sync in cfg-ul de staging) exporta DATELE in .db2, nu
doar structura.
- Fisierele doar-git (docs, .bat, .gitignore) se comit separat, inainte de sync-ul "sync SVN rN",
altfel nimeresc in commit-ul de sincronizare.

View File

@@ -1,9 +1,8 @@
# Inventar COMUN - functii/clase reutilizabile (ROAGEST)
Scop: referinta rapida pt. plan/code-review, ca sa refoloseasca comunele in loc sa se reinventeze
(ex: Scan manual pt. lista dintr-un cursor, cand exista deja cursor2lista()). Generat prin grep pe
COMUN/programe/*.prg + cache text D:\ROA\_vfp_textcache\roagest (nu presupuneri). Numerele = nr.
aparitii grep in tot proiectul (indiciu de cat de "canonic" e functia).
Scop: reutilizare comune la plan/code-review (ex. cursor2lista() in loc de Scan manual pe cursor).
Generat prin grep pe COMUN/programe/*.prg + cache text D:\ROA\_vfp_textcache\roagest. Numerele =
nr. aparitii grep in proiect (indiciu cat de "canonic" e functia).
## 1. Functii comune - COMUN\programe\oproceduri_comune.prg (clasa Oracle/executor + utilitare)
@@ -90,14 +89,14 @@ aparitii grep in tot proiectul (indiciu de cat de "canonic" e functia).
| GetUserDocPath | - | folder documente utilizator curent | - |
| aleg_document_pereche | (vezi ooperatii_comune) | vezi sectiune 2 | - |
Nota: multe din functiile de mai sus exista **dublat** in `proceduri_comune.prg` (varianta veche,
Nota: multe functii de mai sus exista **dublat** in `proceduri_comune.prg` (varianta veche,
non-obiect) - ex. NEW_ID, SAVE_GRID*, XMENU, cursor2lista*, lista2array/cursor, get_mask, Get_Version,
Get_Hexa, format_msg, C_LUNA/cluna, get_trimestru/semestru, GETCALLSTACK, CloneObj/CopyProps,
ceretitlu_rap. La duplicat castiga fisierul adaugat **cel mai recent** cu SET PROCEDURE ADDITIVE -
in roagest.prg OPROCEDURI_COMUNE.PRG (linia 238) vine dupa proceduri_comune (linia 218), deci
varianta activa e cea din `oproceduri_comune.prg`. Din varianta veche raman folosite doar 2 functii
unice: `extrage_optiuni(cLista,nId)` (valoare dintr-o lista "id::val;id::val", 11 uz) si
`myScatter(tcBlank)` (SCATTER generic in obiect, 3 uz); restul functiilor unice de acolo = moarte.
ceretitlu_rap. La duplicat castiga fisierul incarcat **cel mai recent** cu SET PROCEDURE ADDITIVE -
in roagest.prg OPROCEDURI_COMUNE.PRG (linia 238) vine dupa proceduri_comune (linia 218), deci activa
e varianta din `oproceduri_comune.prg`. Unice din varianta veche: `extrage_optiuni(cLista,nId)`
(valoare din lista "id::val;id::val", 11 uz), `myScatter(tcBlank)` (SCATTER generic in obiect, 3 uz);
restul functiilor unice de acolo = moarte.
## 2. Functii comune - COMUN\programe\ooperatii_comune.prg (contabilitate/analitice/balanta)
@@ -142,12 +141,12 @@ Preview rapoarte: FoxyPreviewer (`gcReportPreviewer = "FoxyPreview"` in roagest.
| PreviewerConfig (clasa) | SetValue/GetValue | property-bag optiuni FoxyPreviewer (param toPreviewerConfig la export2frx) | - |
### Export Excel - 3 mecanisme paralele (atentie la confuzii)
1. `goExport.export2xls/export2xlsx` (mai sus) - preferat pt. cod nou (export2xlsx).
1. `goExport.export2xls/export2xlsx` (mai sus) - preferat pt. cod nou.
2. `export_excel` / `export_excel_grid` / `exportare` / `LIST_EXCEL` (proceduri_excel.prg) - OLE
Automation, scrie celula cu celula, necesita Excel instalat; uz mic (2-12). `get_excel_mask` de
acolo = conversie masca VFP -> format Excel (nu confunda cu `get_mask` din sect. 1).
Automation celula-cu-celula, cere Excel instalat; uz mic (2-12). `get_excel_mask` acolo =
masca VFP -> format Excel (nu confunda cu `get_mask` din sect. 1).
3. Clasa `excelxml` (excelxml.vcx, COMUN\UTILE\excel) - Excel XML direct din `gridobject`, fara
Excel instalat (proprietati: file, sheetname, openaftersaving; metoda `save`); 73 uz.
Excel instalat (proprietati file/sheetname/openaftersaving, metoda `save`); 73 uz.
Plus functiile libere `export_xls`/`ExportToXMLExcel` din oproceduri_comune.prg (sect. 1) - cod
diferit de metoda `goExport.export_xls`, doar nume identic.
@@ -288,28 +287,28 @@ Proprietate cheie comuna: `pcobj` (leaga containerul de camp/proprietate din obi
## 7. Ce am lasat pe dinafara (intentionat)
- `proceduri_comune.prg` (varianta veche) - acoperita acum in nota de la sect. 1 (2 functii unice
folosite, restul dublate sau moarte); functiile ei unice cu 0 aparitii (caut_nume_politica,
- `proceduri_comune.prg` (varianta veche) - acoperita in nota sect. 1 (2 functii unice folosite,
restul dublate/moarte); functiile ei unice cu 0 aparitii (caut_nume_politica,
make_sectii_utilizator, recompune_optiuni, cere*/compara*, debug_*_eventtracking, ...) - omise.
- `oproceduri_comune_imob.prg` - varianta specifica ROAIMOB, nu ROAGEST.
- `xdate.prg` - script procedural (incarca cursoarele xsets/xrequest/xnote la DO), nu expune functii.
- Metoda `getUserRepPath` din oExportConfig - complet comentata (moarta); varianta activa e functia
libera omonima din `proceduri_rapoarte.prg` (cod diferit).
- Clase de nomenclatoare mari (`onomenclatoare.vcx`, `onom_articole.vcx`, `stocuri.vcx`, `rulaje.vcx`,
`ointroduceri*.vcx`, `oinventar.vcx`) - business logic specific gestiune, prea voluminos pt. acest
inventar (candidat pt. un inventar separat, per-flux, daca devine necesar).
`ointroduceri*.vcx`, `oinventar.vcx`) - business logic gestiune, prea voluminos pt. acest inventar
(candidat pt. inventar separat per-flux, daca devine necesar).
- Clasele de configurare/serii (`configurare.vcx`, `serii_numere.vcx`, `ferestre_oracle.vcx`,
`bon_fisc.vcx`) si utilitarele (`GridExtras`, `ctl32`, `hpdf`) - neinventariate, uz mai rar
in fluxurile curente de lucru (`excelxml.vcx` e acoperita la sect. 3).
- Functiile din `COMUN\programe` fara nicio aparitie gasita prin grep in ROAGEST (posibil folosite
doar de alte aplicatii ROA) - omise.
`bon_fisc.vcx`) si utilitarele (`GridExtras`, `ctl32`, `hpdf`) - neinventariate, uz rar in
fluxurile curente (`excelxml.vcx` e acoperita la sect. 3).
- Functiile din `COMUN\programe` fara nicio aparitie prin grep in ROAGEST (posibil doar alte
aplicatii ROA) - omise.
## 8. Cum se foloseste
- **La plan**: inainte de a scrie cod/obiecte noi, scaneaza acest fisier + un grep tintit
- **La plan**: inainte de cod/obiecte noi, scaneaza acest fisier + un grep tintit
(`grep -rn "<nume_functie_candidata>" COMUN/programe D:\ROA\_vfp_textcache\roagest`) ca sa
confirmi ca nu exista deja o comuna echivalenta.
- **La code-review**: daca un diff introduce Scan manual pt. liste, MESSAGEBOX direct, SQLEXEC direct,
un buton cu Click suprascris in loc de `caction`, un export Excel/listare construite manual in loc
de `goExport.export2*`/FoxyPreview, sau un dialog de alegere nomenclator facut din SELECT+grid in
loc de `caut_*` (ocautare.prg), semnaleaza reutilizarea comunei corespunzatoare din tabelele de mai sus.
- **La code-review**: daca un diff introduce Scan manual pt. liste, MESSAGEBOX direct, SQLEXEC
direct, un buton cu Click suprascris in loc de `caction`, export Excel/listare construite manual
in loc de `goExport.export2*`/FoxyPreview, sau un dialog de alegere nomenclator din SELECT+grid
in loc de `caut_*` (ocautare.prg), semnaleaza comuna corespunzatoare din tabelele de mai sus.

View File

@@ -0,0 +1,42 @@
# Hook-uri de disciplina (regulile 9 si 12)
## Monitorizare context sesiune (regula 9)
Agentul nu-si vede singur consumul de context. `COMUN\utile\context_watch.ps1` il citeste din
transcriptul sesiunii (ultimul `usage`: `input_tokens + cache_read + cache_creation`) si avertizeaza
peste prag: 250k = pregateste predarea, 275k = handoff acum.
Instalare, o data per calculator, in `%USERPROFILE%\.claude\settings.json` (nivel utilizator, prinde
toate proiectele):
```json
"hooks": {
"UserPromptSubmit": [
{ "hooks": [ { "type": "command",
"command": "powershell -NoProfile -ExecutionPolicy Bypass -File \"D:\\ROA\\ROAGEST\\COMUN\\utile\\context_watch.ps1\" -Stdout" } ] }
]
}
```
- Ruleaza la fiecare mesaj al utilizatorului (~1s); sub prag nu scrie nimic.
- `-Stdout` e obligatoriu pe `UserPromptSubmit` (mesajul intra in context, exit 0). Fara el scrie pe
stderr si iese cu 2 - forma pentru `PostToolUse`.
- Praguri configurabile: `-Prag`, `-PragMax`.
- Verificare manuala: `powershell -File ...\context_watch.ps1 -Prag 900000 -PragMax 950000 -Intotdeauna`
(afiseaza `CONTEXT <n>k` indiferent de prag).
## Revizuire periodica a docs (regula 12)
`COMUN\utile\docs_revizie_check.ps1` compara data din markerul `COMUN\docs\.ultima_revizie` cu ziua
curenta si, peste 30 de zile, cere o runda de compactare. Se pune ca hook `SessionStart`, in acelasi
`settings.json`, cu `-Stdout`:
```json
"SessionStart": [
{ "hooks": [ { "type": "command",
"command": "powershell -NoProfile -ExecutionPolicy Bypass -File \"D:\\ROA\\ROAGEST\\COMUN\\utile\\docs_revizie_check.ps1\" -Stdout" } ] }
]
```
Dupa o revizie aplicata: `powershell -File ...\docs_revizie_check.ps1 -Marcheaza` (rescrie markerul).
Interval configurabil cu `-Zile`.

View File

@@ -1,61 +1,65 @@
# Export surse Oracle (PACK_CONTAFIN & co.) — cum se face
`PACK_CONTAFIN.pck` din acest folder este exportul sursei pachetului PL/SQL `PACK_CONTAFIN`.
**Claude Code își face singur exportul/reîmprospătarea** — nu mai e nevoie de export manual din
PL/SQL Developer.
## Conexiune
- Client: `D:\ROA\instantclient_19_18\sqlplus.exe` (`TNS_ADMIN` e deja setat spre același folder).
- Alias TNS: `ROA_CENTRAL``10.0.20.121:1521`, `SERVICE_NAME=ROA` (vezi `tnsnames.ora`).
- Schema/utilizator: `MARIUSM_AUTO` (schema de dezvoltare a lui Marius).
- **Parola nu e versionată** — se află local, în `D:\ROA\ROAGEST\docs\local\oracle.md`
(folder ignorat de git), pe mașina de lucru.
`PACK_CONTAFIN` există în schemele `MARIUSM_AUTO` (dev) și `ACN`, plus un sinonim `PUBLIC`.
Exportul de referință se face din `MARIUSM_AUTO`.
## Gotcha sqlplus pe Windows/PowerShell
Nu trimite SQL prin pipe din PowerShell (`'select...' | sqlplus`) — BOM-ul UTF-16 sparge parserul
(`SP2-0734: unknown command beginning "select..."`). Scrie un fișier `.sql` cu encoding **ASCII**
și rulează-l cu `@fisier.sql`.
## Comanda de export (re-generare .pck)
```sql
-- export_pack.sql
set pagesize 0 linesize 400 trimspool on feedback off heading off termout off
spool D:\ROA\ROAGEST\COMUN\docs\PACK_CONTAFIN.pck
select text from all_source where owner='MARIUSM_AUTO' and name='PACK_CONTAFIN' and type='PACKAGE' order by line;
select '/' from dual;
select text from all_source where owner='MARIUSM_AUTO' and name='PACK_CONTAFIN' and type='PACKAGE BODY' order by line;
select '/' from dual;
spool off
exit
```
```powershell
& 'D:\ROA\instantclient_19_18\sqlplus.exe' -L -S 'MARIUSM_AUTO/<parola>@ROA_CENTRAL' '@export_pack.sql'
```
Același tipar merge pentru orice alt pachet/procedură (`PACK_SESIUNE`, `PACK_PRETURI`, …) sau pentru
DDL de tabele/view-uri (`all_tab_columns`, `dbms_metadata.get_ddl`).
## Ce e strict necesar de știut despre PACK_CONTAFIN
Pachetul central de **scriere a documentelor** — clientul VFP populează tabelele temporare
`ACT_TEMP`/`RUL_TEMP` (prin `oscrie_in_fisiere`-ul din COMUN), apoi pachetul distribuie:
- `SCRIE_IN_FISIERE` — orchestratorul (apelat per document).
- `SCRIE_IN_ACT``ACT_TEMP``ACT` (notele contabile).
- `SCRIE_IN_RUL``RUL_TEMP``RUL` (mișcările de stoc); completează `COD`, `DATAORA`, `ID_FACT`
(min. `id_fact` fără conturi 5xx), `ID_SUCURSALA`, `DATAIN`/`DATAOUT` din `dataact`, opțional
`ID_RUL_AUX` pe furnizor (opțiunea de firmă `RULAJFURNIZOR`). **Scrie exact ce e în RUL_TEMP — nu
derivă rulaje din ACT**, deci filtrarea liniilor de rulaj se face în clientul VFP.
- `SCRIE_IN_RUL_OBINV` / `SCRIE_IN_STOC` / `SCRIE_IN_STOC_OBINV` — variantele pentru obiecte de
inventar și actualizarea stocului.
- `VERIFICA_NOTE_CONTABILE`, `SCRIE_JC_2007`/`SCRIE_JV_2007` (jurnale TVA),
`SCRIE_IN_BALANTA(_PARTENERI)`, `sterge_document`, `finalizeaza_document_*`.
- Stare de sesiune prin settere/gettere (`SET_COD`/`GET_COD`, `SET_IDFACT`, `SET_ID_SUCURSALA`, …)
+ `PACK_SESIUNE` (an/lună, opțiuni firmă).
# Export surse Oracle (PACK_CONTAFIN & co.) — cum se face
`PACK_CONTAFIN.pck` din acest folder este exportul sursei pachetului PL/SQL `PACK_CONTAFIN`.
Claude Code își face singur exportul/reîmprospătarea — nu mai e nevoie de export manual din
PL/SQL Developer.
## Conexiune
- Client: `D:\ROA\instantclient_19_18\sqlplus.exe` (`TNS_ADMIN` deja setat spre același folder).
- Alias TNS: `ROA_CENTRAL``10.0.20.121:1521`, `SERVICE_NAME=ROA` (vezi `tnsnames.ora`).
- Schema/utilizator: `MARIUSM_AUTO` (schema de dezvoltare a lui Marius).
- **Schema de lucru pentru verificari: `MARIUSM_AUTO` pe `ROA_CENTRAL`** - nu `ACN` sau altele.
- **Parola nu e versionată în git** — în `COMUN\docs\local\oracle.md` (ignorat de git, există în SVN).
`PACK_CONTAFIN` există în schemele `MARIUSM_AUTO` (dev) și `ACN`, plus sinonim `PUBLIC`.
Exportul de referință se face din `MARIUSM_AUTO`.
Înainte de a lua o sursă de acolo ca referință pentru o modificare, verifică că `MARIUSM_AUTO` are
toate scripturile aplicate — procedura e în `scripturi-migrare-db.md`, secțiunea
"Sursa de referință pentru DDL".
## Gotcha sqlplus pe Windows/PowerShell
Nu trimite SQL prin pipe din PowerShell (`'select...' | sqlplus`) — BOM-ul UTF-16 sparge parserul
(`SP2-0734: unknown command beginning "select..."`). Scrie un fișier `.sql` cu encoding **ASCII**
și rulează-l cu `@fisier.sql`.
## Comanda de export (re-generare .pck)
```sql
-- export_pack.sql
set pagesize 0 linesize 400 trimspool on feedback off heading off termout off
spool D:\ROA\ROAGEST\COMUN\docs\PACK_CONTAFIN.pck
select text from all_source where owner='MARIUSM_AUTO' and name='PACK_CONTAFIN' and type='PACKAGE' order by line;
select '/' from dual;
select text from all_source where owner='MARIUSM_AUTO' and name='PACK_CONTAFIN' and type='PACKAGE BODY' order by line;
select '/' from dual;
spool off
exit
```
```powershell
& 'D:\ROA\instantclient_19_18\sqlplus.exe' -L -S 'MARIUSM_AUTO/<parola>@ROA_CENTRAL' '@export_pack.sql'
```
Același tipar merge pentru orice alt pachet/procedură (`PACK_SESIUNE`, `PACK_PRETURI`, …) sau
pentru DDL de tabele/view-uri (`all_tab_columns`, `dbms_metadata.get_ddl`).
## Ce e strict necesar de știut despre PACK_CONTAFIN
Pachetul central de **scriere a documentelor** — clientul VFP populează tabelele temporare
`ACT_TEMP`/`RUL_TEMP` (prin `oscrie_in_fisiere`-ul din COMUN), apoi pachetul distribuie:
- `SCRIE_IN_FISIERE` — orchestratorul (apelat per document).
- `SCRIE_IN_ACT``ACT_TEMP``ACT` (notele contabile).
- `SCRIE_IN_RUL` `RUL_TEMP` `RUL` (mișcările de stoc); completează `COD`, `DATAORA`, `ID_FACT`
(min. `id_fact` fără conturi 5xx), `ID_SUCURSALA`, `DATAIN`/`DATAOUT` din `dataact`, opțional
`ID_RUL_AUX` pe furnizor (opțiunea de firmă `RULAJFURNIZOR`). **Scrie exact ce e în RUL_TEMP — nu
derivă rulaje din ACT**, deci filtrarea liniilor de rulaj se face în clientul VFP.
- `SCRIE_IN_RUL_OBINV` / `SCRIE_IN_STOC` / `SCRIE_IN_STOC_OBINV` — variantele pentru obiecte de
inventar și actualizarea stocului.
- `VERIFICA_NOTE_CONTABILE`, `SCRIE_JC_2007`/`SCRIE_JV_2007` (jurnale TVA),
`SCRIE_IN_BALANTA(_PARTENERI)`, `sterge_document`, `finalizeaza_document_*`.
- Stare de sesiune prin settere/gettere (`SET_COD`/`GET_COD`, `SET_IDFACT`, `SET_ID_SUCURSALA`, …)
+ `PACK_SESIUNE` (an/lună, opțiuni firmă).

View File

@@ -1,8 +1,47 @@
# Orchestrare cu subagenti: context mic, misiuni descompuse
Regula (valabila in toate proiectele ROA/VFP): un singur subagent care duce o misiune lunga
(iteratii de teste, investigatii, mai multe sarcini inlantuite) acumuleaza context urias
(s-a ajuns la ~800k tokens) — calitate degradata, cost mare. Nu se lucreaza asa.
(iteratii de teste, investigatii, mai multe sarcini inlantuite) acumuleaza context urias
calitate degradata, cost mare. Nu se lucreaza asa.
## REGULA ZERO: predarea contextului e OBLIGATORIE, nu optionala
Se aplica **identic sesiunii principale si oricarui subagent**. Nu e o recomandare de eficienta,
e o conditie de corectitudine: un context supraincarcat pierde tacut decizii deja luate si reia
investigatii deja platite.
**Declansatoare — la oricare dintre ele, predarea porneste imediat:**
1. contextul propriu a trecut de **~50% din fereastra** (orchestrator) sau de **~200-250k tokens**
(subagent);
2. harness-ul anunta compactare automata (`PreCompact`) — **prea tarziu ca sa mai amani, dar nu
prea tarziu ca sa scrii fisierul**; scrie handoff-ul inainte sa raspunzi orice altceva;
3. utilizatorul semnaleaza ca s-a atins limita;
4. s-a terminat un bloc de lucru — indiferent cat context a mai ramas.
**Procedura, in ordine, fara exceptii:**
1. **Opreste lucrul.** Nu incepe o sarcina noua, nu porni o rulare noua. Daca esti in mijlocul unei
editari, du-o pana la o stare **consistenta pe disc** (text si binare sincronizate) si atat.
2. **Scrie handoff-ul pe disc** (`docs\handoff_<subiect>.md`). Nu in mesaj, nu in raport — **pe
disc**. Un mesaj catre orchestrator se pierde; fisierul nu.
3. **Confirma in doua randuri** ce ai lasat in urma si daca ceva e intr-o stare periculoasa
(fisier editat fara write-back, tranzactie deschisa, proces ramas viu, date de test consumate).
4. **Opreste-te.** Blocul urmator il ia un agent proaspat. "Mai am putin" nu e motiv de amanare —
exact acolo se pierd lucrurile.
**Obligatia e a fiecaruia, nu doar a orchestratorului.** Un subagent care simte ca se apropie de
prag **anunta singur** si cere predarea; nu asteapta sa fie oprit. Un orchestrator care se apropie
de prag isi scrie propriul handoff si preda orchestrarea unei sesiuni noi — regula nu are portita
pentru "eu doar coordonez".
**Ce intra obligatoriu in handoff**: inventarul livrabilelor cu `fisier:linie`; ce e terminat si ce
nu; **daca write-back-ul e facut** pentru fiecare fisier atins; comanda exacta de rulare a testelor
si unde scriu logurile; ce s-a stabilit deja (ca sa nu se reia); ce e interzis; starea datelor de
test consumate; capcanele de mediu platite. Fara analize noi — doar stare.
Doua lectii platite scump, amandoua din aceeasi cauza — un agent tinut peste prag (`s5-nivel2`
533k, `s2d-modifica-gestiuni` 434k). Predarea e aproape gratuita: raportul e oricum deja scris.
## Cum se lucreaza
@@ -38,3 +77,64 @@ Regula (valabila in toate proiectele ROA/VFP): un singur subagent care duce o mi
completeaza-l, nu repeta investigatia.
- Orchestratorul face el insusi munca de volum -> deleaga si pastreaza-si contextul
pentru decizii, verificari si deblocari.
## Disciplina de context a ORCHESTRATORULUI
Pragul de ~200-250k e pentru subagenti, dar orchestratorul se umple la fel de repede daca isi
lasa in sesiune munca de CITIT (masurat: o runda de implementare + 4 rulari de teste a dus
sesiunea principala la ~570k desi tot codul fusese scris de subagenti). Principalii consumatori:
citirea rezultatelor de test dupa fiecare rulare (cu tot cu liniile "OK"), citirea codului pentru
diagnostic, fixuri aplicate direct in loc de delegate.
- **Nu citi log-uri brute.** Scripturile de raportare afiseaza DOAR esecurile plus un total
("22 OK, 3 FAIL: <nume + linia de esec>"). Tabelul complet se citeste o singura data, la
baseline - nu dupa fiecare rulare. Pentru suitele VFP exista deja:
`COMUN\utile\Teste\raport_teste.ps1 -Dir <folder> [-Tot] [-Baseline <fisier>]` - fara `-Tot`
afiseaza doar esecurile, iar cu `-Baseline` le marcheaza `[preexistent]` vs `[NOU - REGRESIE]`.
- **Nu citi cod ca sa diagnostichezi.** Deleaga cu "adu-mi dovada, nu fisierul": agentul intoarce
cauza + linia + citatul minim. Verifici afirmatia, nu o redescoperi.
- **Verifica prin assert, nu prin citire.** Daca vrei sa stii ca ceva e adevarat, cere o comanda
care intoarce da/nu, nu continutul din care ai deduce singur.
- **Nu aplica fixuri direct** decat sub ~5 linii si doar daca ai deja contextul in sesiune.
- **Prag si pe orchestrator**: la ~50% din fereastra, scrie handoff-ul si reia orchestrarea
dintr-o sesiune noua. Handoff-ul e deja pe disc - exact pentru asta exista. Vezi **Regula zero**
de la inceputul fisierului: obligatia e aceeasi ca pentru subagenti, fara portita pentru
"eu doar coordonez".
## Model de lucru: backlog de story-uri mici, context mic per story
Impartirea pe "lane-uri" mari (o clasa, un modul) produce subagenti cu context mare si serializare
pe fisier. Alternativa mai ieftina si mai robusta: **backlog de story-uri mici, fiecare rezolvabila
cu context mic, rulate in bucla de agenti PROASPETI.**
Doua fisiere pe disc tin toata starea:
- `docs/handoff_<subiect>.md` - **contextul stabil**: reguli de editare, cai, ancore verificate,
capcane confirmate, decizii luate. Il citeste fiecare agent; se actualizeaza rar.
- `docs/backlog_<subiect>.md` - **starea vie**: story-uri cu ID, criteriu de acceptare
VERIFICABIL, fisiere atinse, stare (`todo` / `in lucru` / `gata` / `blocat de #N`).
Bucla:
1. orchestratorul ia primul story `todo` neblocat;
2. spawneaza un agent proaspat cu prompt = trimitere la handoff + textul story-ului + criteriul
de acceptare. **Nimic altceva** - fara istoric, fara rapoartele celorlalti agenti;
3. agentul modifica, ruleaza verificarea din criteriu si raporteaza **verdict + ce a schimbat +
ce a descoperit neasteptat**, atat;
4. orchestratorul marcheaza story-ul in backlog si trece la urmatorul.
O story buna: are criteriu de acceptare care se poate RULA (un test, un grep, o comanda da/nu);
atinge un singur fisier sau o singura zona (altfel story-urile se serializeaza intre ele); incape
in 15-20 de linii de descriere; nu cere citirea intregului fisier ca sa fie inteleasa.
Sablon:
### S7 - garda pe randul protejat in recalcule
Fisiere: COMUN\clase\<x>.vc2 (do_executa, recalc_tva_document)
Blocat de: S4
De facut: <2-4 propozitii>
Acceptare: test_<y>.ps1 trece 12/12 SI `rand_protejat()` nu mai apare in nicio clauza Where
Stare: todo
Cand un story pica de doua ori la rand, nu-l reincerca a treia oara cu acelasi prompt: semnul e ca
descrierea sau criteriul e gresit, nu executia. Rescrie story-ul (mai mic, sau cu criteriul
corectat) inainte de a mai cheltui un agent.

View File

@@ -1,6 +1,6 @@
# Prompt: seteaza conventia docs/ (insight-uri de proiect) intr-un proiect ROA
Template partajat intre proiectele ROA* (similar cu `changelog_template.txt`). Origine: ROAIMOB, 08/07/2026. Copiaza blocul de mai jos (adaptat, daca e nevoie) intr-o sesiune Claude Code din radacina oricarui proiect ROA* pentru a initializa aceeasi conventie.
Template partajat intre proiectele ROA* (similar cu `changelog_template.txt`). Copiaza blocul de mai jos (adaptat, daca e nevoie) intr-o sesiune Claude Code din radacina oricarui proiect ROA* pentru a initializa aceeasi conventie.
---

View File

@@ -0,0 +1,83 @@
# Publicarea scripturilor de baza de date catre clienti
Scriptul: `COMUN\utile\publicare_scripturi.ps1`. Inlocuieste pasii manuali din `tasks.exe`
(`D:\PROIECTE\fox\tasks`, formularul din `clase\generare_script.vcx`), care raman varianta de rezerva.
Cum se scrie un script de migrare: `scripturi-migrare-db.md`.
```powershell
powershell -File COMUN\utile\publicare_scripturi.ps1 -DryRun # ce ar face pe luna curenta
powershell -File COMUN\utile\publicare_scripturi.ps1 # luna curenta, tot fluxul
powershell -File COMUN\utile\publicare_scripturi.ps1 -Luna 2026-08 # alta luna
powershell -File COMUN\utile\publicare_scripturi.ps1 -Fisier a.sql,b.sql # doar scripturile date
```
Alte optiuni: `-DoarImport` (fara arhiva), `-DoarArhiva` (doar regenerare arhiva), `-Toate`
(republica si scripturile identice), `-FaraVerificareZip`, `-Settings`, `-ZipPath`, `-DirScripturi`,
`-Alias`, `-User`, `-Password`, `-SqlPlus`.
## Configurarea
Se citeste din `settings.ini`-ul lui `tasks.exe` (`D:\PROIECTE\fox\tasks\settings.ini`, schimbabil
cu `-Settings`), aceleasi chei pe care le foloseste formularul; orice parametru dat explicit bate
ini-ul.
| din ini | ce devine |
|---|---|
| `[connection] host_database` | nume de **DSN ODBC** — aliasul TNS e cheia `ServerName` a DSN-ului din registri (`CENTRAL``ROA_CENTRAL`) |
| `[connection] username_database` / `password_database` | utilizatorul Oracle |
| `[folder] script_folder` | directorul scripturilor, cu `\SCRIPTURI\``\SCRIPTURI_CLAR\` (+ `\<an>\<luna>\`) |
| `[folder] roa_output` | + `_UPDATE\` = directorul arhivelor |
| `[folder] sqlplus_exe` | clientul Oracle (si `TNS_ADMIN` = directorul lui) |
| `[script]` | prefixele valide (`CO_`, `FF_`, `RF_`, `SYS_`, `JCS_`) — prefix necunoscut = avertisment |
`sqlplus_exe` arata spre `instantclient_19_18`; `instantclient_11_2_0_2` (valoarea de dinainte) are
un `tnsnames.ora` vechi, cu `ROA_CENTRAL` pe `10.0.20.122` in loc de `.121`, deci conexiunea expira.
`settings.ini` e local (ignorat de SVN).
## Cei doi pasi
**1. Import** — fiecare `.sql` intra ca un rand in `CONTAFIN_ORACLE.UPD_DATABASE` de pe `ROA_CENTRAL`,
cu `SCRIPT_ORDER = 0` (randul contine scriptul intreg, nu instructiuni parsate), `SCRIPT_NAME` cu
MAJUSCULE si `.SQL`, `SCRIPT_TYPE` = ce urmeaza dupa `NN_`, `SCRIPT_CONTENT` = fisierul in clar.
`ID` vine din trigger, `DATAORA` din `SYSDATE` implicit, `SCRIPT_APPVER`/`SCRIPT_EXTRA_FILE` raman
goale. Daca `SCRIPT_NAME` exista deja, se face **update pe acelasi `id`** — asa se republica un
script corectat, pentru ca clientul face `MERGE ... on (a.id = b.id)`.
**2. Arhiva lunara** — in `Y:\ROAUPDATE\_UPDATE\` se scriu `database_YYYYMMDD_YYYYMMDD.zip` **si**
`databasen_...zip` (identice azi: `database_` era varianta criptata cu `wrap.exe`, nu se mai
foloseste). Fiecare contine XML-ul cu acelasi nume ca zip-ul (format `VFPData`/`crsxml`,
Windows-1252, CRLF, tab-uri, `script_content` gol) plus cate un `<STEM_MAJUSCULE>.sql` per script.
Indexii `roa_database.xml` / `roa_databasen.xml` listeaza arhivele existente si se schimba doar
cand apare o luna noua.
Continutul din arhiva se citeste **inapoi din baza**, nu de pe disc — deci arhiva contine exact ce
va primi clientul.
## Verificari facute automat
- fisier cu sfarsituri de linie LF: **refuzat** (parsarea pe client se face pe `CHR(13)+CHR(10)`);
- dupa import, continutul e citit inapoi din CLOB si comparat octet cu octet cu fisierul; la
diferenta se opreste inainte de arhiva;
- scripturile deja publicate cu acelasi continut se sar (`-Toate` forteaza republicarea);
- arhiva generata se citeste inapoi cu cititorul clientului (`pack_utils.decodebase64` +
`zip_util_pkg.get_file`) si se compara lungime + MD5 per fisier — o arhiva facuta din PowerShell
este citita corect de `zip_util_pkg`;
- fisierele inlocuite din `_UPDATE` se copiaza intai in `_UPDATE\_backup\<data_ora>\`.
`Y:\ROAUPDATE\_UPDATE\` e **live**: clientii descarca de acolo imediat ce fisierul e pus.
## Ce face clientul
`PACK_UPDATE.UpdateScripts` (`COMUN\docs\PACK_UPDATE.pck`) descarca indexul, apoi arhivele care
acopera perioada neaplicata, extrage XML-ul cu `zip_util_pkg.get_file`, face `MERGE` in
`UPD_DATABASE` pe `id`, apoi pentru fiecare rand cu `script_extra_file` pune continutul fisierului
in `script_content` — pentru `.sql` text clar, fara base64 (base64 e doar pentru instructiunile
parsate, alta ramura). Actualizare blocata: `depanare-pack-update.md`.
## Detalii de implementare
Continutul circula **hexazecimal** in ambele sensuri (`utl_i18n.raw_to_char` / `string_to_raw` cu
`WE8MSWIN1252`), pe bucati de 900 de octeti, in blocuri PL/SQL de cate 15 bucati. Motivul: baza e
`AL32UTF8`, fisierele sunt CP1252, iar comanda trimisa lui `sqlplus` ramane ASCII pur — nu depinde
de `NLS_LANG` si nu poate strica octetii >= 0x80. Consecinta utila: comparatia dintre fisier si
CLOB e exacta, nu pe lungime.

View File

@@ -1,30 +1,114 @@
# Reguli de lucru agent (comune proiectelor ROA VFP)
1. Modificari de cod: livreaza FISIER de diff `docs\diff_runda<N>_<subiect>.patch`
(`git diff --no-index <baseline.bak> <editat>`), nu diff in terminal.
Write-back in binar (txt2vcx) si commit DOAR dupa aprobarea patch-ului de catre utilizator.
Patch-urile sunt intermediare de review: NU se comit NICIODATA in git (sunt in
.gitignore ca `docs/diff_runda*.patch`); raman doar local, pe disc.
2. Comentarii in cod: max o linie `*!* DD.MM.YYYY autor - motiv scurt`, DOAR la
functionalitati noi/schimbate. La rezolvari de erori NU se adauga comentarii.
Explicatiile merg in docs/ sau in mesajul de commit, nu in cod.
Changelog (`changelog_<aplicatie>.txt`): text minimal, pe limba utilizatorului,
nu tehnic - o fraza scurta per intrare `:nou:`/`:modificare:`/`:eroare:`.
3. Modificari minime: doar ce s-a cerut; fara refactorizari sau curatenie din oficiu.
4. Testare headless (fara IDE): `vfp9.exe -A -T "<script.prg>" <param>` din PowerShell.
Mediu, sabloane, capcane si metoda de depanare: `depanare_testare_vfp.md`.
5. Editare .vcx/.scx pe text (cache, cp1252 byte-safe, fidelity-check): `flux-editare-vfp-text.md`.
Cautare in binare: `cautare_vcx_vct.md`.
6. Misiuni lungi (teste, investigatii, sarcini inlantuite): NU un singur subagent cu context
acumulat — orchestrator + subagenti proaspeti per sarcina (max ~200-250k tokens/subagent),
handoff compact pe disc: `orchestrare-subagenti.md`.
7. Conventii obligatorii, de citit cand atingi zona respectiva:
- editezi `.vc2`/`.sc2` pe text (orice write, chiar pe o linie) -> `conventie_encoding_cp1252.md`
(tool care nu scrie cp1252 nativ corupe TOATE diacriticele din fisier);
- adaugi/rearanjezi controale pe formulare sau coloane in grid -> `conventie_ux_formulare.md`;
- scrii cod cu `GO` pe un `Recno()` capturat sau primit ca parametru -> `conventie_go_recno.md`;
- `ALTER TABLE` pe cursorul intors de `goExecutor.oExecute()` -> `conventie_goexecutor_alter_table.md`;
- testare UI / prin MCP -> `testare-ui-vfp.md`, `testare-vfp-mcp.md`;
- export date din Oracle -> `oracle_export.md`;
- modifici schema Oracle (tabele/view-uri/pachete) -> `scripturi-migrare-db.md`
(unde stau scripturile de migrare si modelele pentru scripturi noi).
# Reguli de lucru agent (comune proiectelor ROA VFP)
1. Modificari de cod: diff ca FISIER `docs\diff_runda<N>_<subiect>.patch`
(`git diff --no-index <baseline.bak> <editat>`), nu in terminal. **COMMIT-ul** e singurul pas
care asteapta aprobarea patch-ului. Write-back-ul in binar (txt2vcx) si testele se fac IMEDIAT
dupa editarea `.vc2`/`.sc2`, fara sa astepti raspunsul — inclusiv pe `COMUN` — ca sa ajungi la
review cu rezultatele testelor, nu cu o propunere netestata; daca nu merge, revii cu
`git checkout` pe binare (`.vcx`+`.vct`) sau cu write-back din `*.pre_runda*.bak`.
Patch-urile (in .gitignore, `docs/diff_runda*.patch`) nu se comit niciodata, raman local.
Curatenia de dinainte de commit NU se face pe cap de agent, ci cu
`powershell -File COMUN\utile\curatenie.ps1` (`-DryRun` listeaza fara sa stearga): patch-uri,
handoff-uri/planuri de runda, `*.pre_runda*.bak`, `.bak`-urile din cache-ul text si artefactele
de test (`screenshots*`, `uisync*`, `.fxp`, `.err`, loguri). Sterge doar fisiere neurmarite de
git — cele tracked sunt sarite.
2. Comentarii in cod SI in scripturile de migrare `.sql`: minime, strict functionale, descriu
comportamentul CURENT (ca si cum ar fi scris asa de la inceput). **Doar daca e cazul** — un
comentariu se scrie acolo unde explica o **ramura** sau un **filtru** care nu se citeste singur,
ca sa se inteleaga codul; unde codul e limpede, nu se comenteaza. O linie de regula, 2-3 doar
pentru metode cu contract nebanal (parametri, cursor asteptat/lasat deschis, pozitionare la
iesire), 4-5 in antetul unui script de migrare (ce e obiectul si ce contract are). Istoricul
modificarilor sta DOAR in ANTETUL fisierului (niciodata inline) — la fel in `.prg`, in `.sql`
si in PL/SQL Oracle.
INTERZIS in comentariu: nume de agent ("claude"), referinte la planuri, stories, propuneri,
decizii, etape sau erori (`docs/plan_*.md`, `docs/propuneri_*.md`, "#6", "S4", "M2", "T3",
"dec.6", "runda27", "E7", "D-H2"), trimiteri la rapoartele din `docs/` ("vezi raportul,
sectiunea ..."), justificarea alegerii facute (de ce numele acesta, de ce s-a respins varianta
cealalta), istoricul modificarii ("inlocuieste...", "nu mai depinde de...", "mutat din..."),
date si autori pe cod nou.
Comentarii vechi in stil jurnal nu se rescriu din oficiu — doar cand blocul e oricum atins
sau la cerere explicita.
Antet: o singura intrare CUMULATIVA per functionalitate (`*!* DD.MM.YYYY` / `*!* autor` /
`*!* ce face, 1-2 fraze`) — la revenire se rescrie intrarea, nu se adauga alta; autorul e cine
semneaza livrarea (ex. `marius.mutu`), niciodata agent. Doar comportamentul final — fara
revizii/runde/patch-uri/corectii. La rezolvari de erori: fara comentarii.
Explicatiile merg in docs/ sau in mesajul de commit, nu in cod.
Changelog (`changelog_<aplicatie>.txt`): strictul necesar, pe limba utilizatorului, non-tehnic
— 1-3 fraze/intrare, fara detalii de implementare, fara enumerarea locurilor atinse. Cat timp
lucrarea n-a ajuns la utilizatori, erorile introduse si corectate in interior NU se mentioneaza
— intrarea descrie functionalitatea finala, `:nou:`/`:modificare:`; `:eroare:` doar pentru erori
care au fost in productie.
3. Modificari minime si SCOPED: doar ce s-a cerut, doar pe cazul cu problema, fara refactorizari
din oficiu. Cauta intai ce exista (`inventar-comun.md`) si refoloseste; daca lipseste ceva,
propune COMPLETAREA unei functii/tabele/view comune, nu o varianta paralela. 80/20: solutia cea
mai simpla care rezolva cazul real. Completeaza `inventar-comun.md` la orice descoperire/creare
de element comun nedocumentat.
4. Testare headless (fara IDE): `vfp9.exe -A -T "<script.prg>" <param>` din PowerShell.
Mediu, sabloane, capcane, depanare: `depanare_testare_vfp.md`.
5. Editare .vcx/.scx pe text (cache, cp1252 byte-safe, fidelity-check): `flux-editare-vfp-text.md`.
Cautare in binare: `cautare_vcx_vct.md`. Versiunile `.??2` sunt instantanee, pot fi mai vechi
decat binarul — verifica mtime inainte de concluzii; continutul real e in `.PJX`.
6. Delegare: implementarile, testele, verificarile si cercetarile se dau unor subagenti Sonnet in
background (lane-uri paralele); sesiunea principala doar orchestreaza si verifica, ca sa nu i
se umple contextul. Misiuni lungi: subagenti proaspeti per sarcina (max ~200-250k
tokens/subagent), nu unul singur cu context acumulat; handoff compact pe disc:
`orchestrare-subagenti.md`.
**Verificarea a ce se intoarce** — pentru executie delegarea merge, pentru concluzii nu:
- **citeste contractul functiei apelate, nu-l presupune.** Un raport care descrie corect
structura codului poate gresi sensul: ex. `goExecutor.oExecute` intoarce succes/insucces
(`CT_SUCCES`/`CT_INSUCCES`), NU numarul de randuri — o garda `If lnSucces > 0` citita ca
"are randuri" a produs un bug inexistent, raportat ca blocant. Deschide functia.
- **fix ingust, nu supra-constructie.** Cand premisa se corecteaza, corectia se restrange:
mecanismele noi introduse "ca sa fie sigur" diverg de la codul-sablon si blocheaza
refolosirea lui in alta parte.
- **"zero cazuri in date" nu dovedeste nimic** pe scheme cu date de test; raspunsul vine din
cod. Si invers: o potrivire de cifre pe 1-2 documente nu e o regula.
- **cere raportul sa separe "testat" de "analizat static"**, si ce n-a putut fi acoperit. Un
agent care nu e intrebat explicit va prezenta amandoua la fel.
- **spune-i ca poate infirma briefingul.** Altfel implementeaza corectia ceruta chiar cand a
descoperit ca nu e nevoie de ea.
7. Conventii obligatorii, de citit cand atingi zona respectiva:
- editezi fisiere cu octeti cp1252 - `.vc2`/`.sc2`, dar si `.prg` (ex. `programe\ocautare.prg`,
unde `s`-urile cu virgula din `masina`/`si contul`/`transa` sunt octetul `0xBA`) ->
`conventie_encoding_cp1252.md`. Orice write cu un tool ce nu scrie cp1252 nativ (Edit/Write)
corupe caracterele >= 0x80 din TOT fisierul (`0xBA` -> `EF BF BD`), chiar la o singura linie
schimbata, si o repeta la FIECARE scriere — editeaza tot ce ai de editat, verifica byte-level
si repara o singura data DUPA ultima scriere. Verificare: `perl -ne 'print "$.\n" if
/[\x80-\xFF]/' <fisier>`; reparare (pt. `0xBA`): `perl -e
'binmode(STDIN);binmode(STDOUT);local $/;$_=<STDIN>;s/\xEF\xBF\xBD/\xBA/g;print' < f > f.tmp`.
`EF BF BD` nu spune ce caracter s-a pierdut - toate diacriticele devin la fel; ia octetul corect
per pozitie din `svn cat <fisier>` (necorupt) inainte sa inlocuiesti - o inlocuire oarba cu
`0xBA` strica `a`/`t` cu caciula (`0xE3`, `0xFE`) din alte fisiere;
- adaugi/rearanjezi controale pe formulare sau coloane in grid -> `conventie_ux_formulare.md`;
- grid needitabil pe formular cu 2+ grid-uri -> `capcana_grid_controlsource.md`;
- adaugi o coloana intr-un grid deja livrat (ordinea din clasa e neutralizata de
preferintele salvate per utilizator) -> `capcana_grid_preferinte_utilizator.md`;
- `GO` pe un `Recno()` capturat/primit ca parametru -> `conventie_go_recno.md`;
- `ALTER TABLE` pe cursorul intors de `goExecutor.oExecute()` -> `conventie_goexecutor_alter_table.md`;
- testare UI / prin MCP -> `testare-ui-vfp.md`, `testare-vfp-mcp.md`;
- garzi pe valori NULL din Oracle -> `conventie_null_vfp.md`;
- export date din Oracle -> `oracle_export.md`;
- actualizarea ROA nu se finalizeaza (job update, PACK_UPDATE) -> `depanare-pack-update.md`;
- modifici schema Oracle (tabele/view-uri/pachete) -> `scripturi-migrare-db.md`.
8. Eroare raportata de utilizator: nu analiza statica indelungata — scrie intai un test care o
reproduce pe fluxul real; el da cauza si confirma remedierea. Analiza statica doar cat sa stii
ce sa pui in test.
9. Context sesiune principala: la peste **250k** salveaza contextul intr-un handoff pe disc, il
predai unei sesiuni noi si te opresti. Limita maxima absoluta: **275k**. Nu estima - masoara:
hook-ul din `monitorizare-context.md` anunta pragul la fiecare mesaj.
10. Fisier de progres MASTER per proiect (`docs\progres.md`): la zi pe tot parcursul, nu doar la
predare — stare curenta, facut/testat, ipoteze excluse (cu dovada), ce urmeaza, fisiere atinse,
comenzi de rulat. O sesiune noua porneste de acolo, fara sa reia investigatia. E ajutor de
predare, nu documentatie: dupa commit, cu toate sarcinile terminate, se sterge.
11. La final de lucrare/cercetare: **propune** actualizarea documentatiei — `COMUN\docs\` daca e
comun tuturor aplicatiilor, `docs\` al proiectului daca e specific (plus `inventar-comun.md`,
regula 3). Doar relevant si reutilizabil (80/20): flux ascuns, capcana, procedura/tabela cheie
— nu tot ce ai atins, nu verbose. Cateva randuri; propui, nu scrii din oficiu.
O notita = regula + strictul de context ca sa fie aplicabila: fara cazul particular in care ai
gasit-o, fara simptomele lantului de erori, fara ce se deduce din cod (cititorul stie deja).
12. Revizuire periodica a documentatiei (`COMUN\docs\`, `docs\` al proiectului, inclusiv acest
fisier): compacteaza pastrand semantica — taie ce se deduce din cod, exemplele repetate,
istoricul, tot ce nu mai schimba o decizie. Scopul: docs + reguli sa ocupe cat mai putin context
la incarcare. Propui rezultatul, nu rescrii din oficiu; nu pierzi nicio regula/capcana, doar
cuvintele in plus. Fisierele de reguli/conventii se completeaza doar cu ce e super-util,
simplu si concis. Cadenta o da hook-ul din `monitorizare-context.md` (marker la 30 de zile).

View File

@@ -1,7 +1,135 @@
# Scripturi migrare baza de date Oracle
Scripturile de migrare a schemei (si modelele pentru scripturi noi) sunt in
`DATABASE\SCRIPTURI_CLAR` de sub radacina suitei ROA (folderul parinte al aplicatiei,
`gcDirMare`/`dirgen` — ex. `D:\ROA\DATABASE\SCRIPTURI_CLAR`).
Sursa SVN: `http://svnroa:3001/svn/ROA/DATABASE/Branches/RB-1.00`.
Pentru un script nou, urmeaza formatul/conventiile celor recente de acolo.
`DATABASE\SCRIPTURI_CLAR` de sub radacina suitei ROA (`gcDirMare`/`dirgen` — ex.
`D:\ROA\DATABASE\SCRIPTURI_CLAR`). Sursa SVN: `http://svnroa:3001/svn/ROA/DATABASE/Branches/RB-1.00`.
Pentru un script nou, urmeaza formatul/conventiile celor recente de acolo. Publicarea catre clienti
(import in `UPD_DATABASE` + arhiva lunara): `publicare-scripturi-db.md`.
Reguli confirmate de Marius (24.07.2026):
- **Line-endings CRLF obligatoriu** in scripturile `.sql` — tool-urile agentului scriu implicit
LF; dupa orice scriere, verifica si converteste byte-safe LF -> CRLF (fara decodare/reincodare).
Parsarea pe fluxul ROA (ex. `ALINES` pe `CHR(13)+CHR(10)`) esueaza silentios pe LF: tot fisierul
devine un singur rand.
- `versiune_db.txt` (marker-ul `YYYY_MM_DD_NN` din radacina aplicatiei) se scrie fara newline la
final (conventia existenta).
- Aplicarea prin ODBC/`goExecutor`: sintaxa SQL*Plus `exec pachet.procedura(...)` nu functioneaza
— foloseste `begin pachet.procedura(...); end;`.
- **Niciun `;` la capat de linie intr-un comentariu `--` din interiorul unei instructiuni.** SQL*Plus
termina instructiunea acolo, chiar daca `;`-ul e in comentariu: restul `CREATE VIEW`-ului ajunge sa
fie interpretat linie cu linie ca si comenzi, cu zeci de `SP2-0734` si un `ORA-00936` derutant care
arata spre comentariu. Pus la sfarsit de fraza, `.` in loc de `;`. Comentariile de **dinaintea**
instructiunii nu sunt afectate.
- **Fiecare script se incheie cu `exec pack_migrare.UpdateVersiune('<nume_script>');` urmat de
`commit;`.** DDL-ul comite implicit, dar `UpdateVersiune` e DML: fara `commit` explicit, un script
se poate aplica fara ca versiunea sa se inregistreze, iar `VERSIUNE` ajunge sa minta despre ce s-a
aplicat.
- **Rularea manuala se face conectat pe schema tinta** (`CONTAFIN_ORACLE` pentru `co_`, schema firmei
pentru `ff_`), niciodata cu un user de lucru. DDL-ul neprefixat (`create or replace package ...`)
merge pe schema conexiunii: pe alt user iese `PLS-00304` si ramane un obiect orfan, iar pachetul
tinta ramane neschimbat. In acelasi script, DML-ul pe tabele cu sinonim public nimereste tabela
reala si pare ca totul a mers — verifica intotdeauna iesirea sqlplus si `all_objects`.
`PACK_UPDATE` face `CONNECT <schema>/<parola>@ROA` real per schema (`UpdateSchemaSQLPLUS`, parola
din `SERVER_INFO`), deci scriptul neprefixat e corect pentru livrare.
## Sursa de referinta pentru DDL: MARIUSM_AUTO, nu productia
Regula lui Marius (06.08.2026): **orice modificare de tabela, view, procedura, functie sau pachet se
scrie plecand de la sursa din schema de dezvoltare `MARIUSM_AUTO` (`ROA_CENTRAL`), niciodata de la
sursa citita dintr-o schema de client** (`VENDING`, `ACN`, ...). Schemele de client raman in urma:
pot avea scripturi neaplicate sau variante livrate separat (ex. pachetele `_10G_ROMCONSTRUCT`), iar o
modificare scrisa peste o sursa veche sterge corectii deja livrate.
Schemele de client raman utile doar pentru **masuratori pe date reale**, in citire.
### Verifica intai ca MARIUSM_AUTO e la zi
"Ultima versiune din dev" e ultima versiune doar daca toate scripturile din `SCRIPTURI_CLAR` chiar au
fost aplicate acolo. `pack_migrare.UpdateVersiune` inregistreaza fiecare script aplicat in tabela
`VERSIUNE` (`script_final` = numele fisierului, cu tot cu `.sql`), deci diferenta se vede direct:
```sql
select script_final, data_final from versiune order by data_script desc, seq_script desc;
```
```powershell
Get-ChildItem D:\ROA\DATABASE\SCRIPTURI_CLAR -Recurse -Filter *.sql |
Select-Object -ExpandProperty Name | Sort-Object
```
Daca lipsesc scripturi din `VERSIUNE`, **nu porni modificarea** pe sursa de acolo — semnaleaza-i lui
Marius ce nu e aplicat. Exportul sursei de referinta: `oracle_export.md`.
## Continutul unui script
- **Minimul necesar si intotdeauna SCOPED**: `update`/`insert` doar pe randurile cazului tratat
(setul, codul, firma anume), niciodata pe toate randurile care "seamana" cu el.
- **Fara `select` de raportare in script** — nu-l citeste nimeni la aplicare si poate da eroare.
Verificarile se fac inainte, separat, pe schema de lucru.
- **Idempotent**: rulat de doua ori nu mai schimba nimic (`merge`, `where <coloana> is null`).
- **Un pachet sta singur in scriptul lui**, fara alt DDL sau DML alaturi: modificarile de tabele si
curateniile de date merg in scripturi separate, cu numar propriu.
- **Comentarii strict necesare**, ca in cod: antet de 4-5 randuri (data + autor, ce e obiectul, ce
contract are), fara referinte la planuri, stories, propuneri, decizii sau erori, fara trimiteri la
rapoartele din `docs/`, fara justificarea alegerilor si fara istoricul modificarii. Regula completa
si lista de interdictii: `reguli_lucru.md`, punctul 2.
## Compatibilitate cu serverele clientilor
Serverul de dezvoltare e mai nou decat serverele clientilor, deci un script care trece local poate
pica la client si opri actualizarea.
Parcul de servere (03.08.2026): **un client pe Oracle 10.2** (ROMCONSTRUCT), cativa pe **XE 11 si
11g** standard, restul pe **XE 18/19/21 si 18/21**.
**Regula: orice script care ajunge in comune se scrie la nivelul Oracle 10.2 si trebuie sa ruleze pe
10.2 si pe 11.x.** Numitorul comun e 10.2 — nu se folosesc facilitati 11g si cu atat mai putin 12c+,
oricat de comod ar fi pe dev. Proba inainte de publicare se face pe serverul cel mai vechi
(ROMCONSTRUCT), nu pe dev.
Constructii care merg pe dev si pica mai jos:
| Constructie | Disponibila de la | Ce iese sub ea |
|---|---|---|
| identificator peste 30 de caractere (tabela, index, constrangere, coloana) | 12.2 | `ORA-00972` |
| `REGEXP_COUNT` | 11.1 | `ORA-00904` in SQL / `PLS-00201` in PL/SQL |
| `CONTINUE` (instructiune PL/SQL) | 11.1 | `PLS-00201: identificatorul 'CONTINUE' trebuie declarat` |
| `LISTAGG` | 11.2 | `ORA-00904` |
| `PIVOT` / `UNPIVOT` | 11.1 | eroare de sintaxa |
| trigger compus (`COMPOUND TRIGGER`) | 11.1 | eroare de compilare |
| `secventa.NEXTVAL` direct intr-o atribuire PL/SQL | 11.1 | `PLS-00357` (pe 10g: `select ... into` din `dual`) |
| `FETCH FIRST n ROWS`, `CROSS APPLY`, `LATERAL` | 12.1 | eroare de sintaxa (pe 10g/11g: `rownum`) |
| `IDENTITY`, `DEFAULT ON NULL`, coloane invizibile | 12.1 | eroare de sintaxa |
| `VALIDATE_CONVERSION`, `CAST ... DEFAULT ON CONVERSION ERROR` | 12.2 | `ORA-00904` |
| `FORALL` cu campuri de record din colectie (`S(i).camp`) | 11.1 | `PLS-00436` / `PLS-00382` |
Editiile **XE** adauga limite proprii, independent de sintaxa: XE 11.2 nu are partitionare, executie
paralela si nici masina virtuala Java in baza; XE 18/19/21 au setul de facilitati al editiei mari,
dar plafonate pe resurse (12 GB de date, 2 GB RAM, 2 fire de executie). Deci nimic care sa depinda de
partitionare sau de Java in baza, si nicio operatie care sa presupuna spatiu/memorie de server mare.
Plus, independent de versiune: **un obiect nu se poate referi la ceva creat de un script ulterior.**
Pe dev obiectul exista deja, deci pachetul compileaza; la client scriptele se aplica in ordine si
iese `ORA-00942` / corp invalid. Cand un script creeaza o tabela si altul un pachet care o foloseste,
tabela trebuie sa fie prima in ordinea `YYYY_MM_DD_NN`.
Un pachet care nu are echivalent 10g se livreaza ca varianta separata pentru serverul acela
(ex. `ff_..._PACK_CONTAFIN_10G_ROMCONSTRUCT.pck`). La aplicarea manuala a unei astfel de variante se
compileaza **doar PACKAGE BODY-ul**: recrearea specificatiei invalideaza dependentele si da
`ORA-04068` utilizatorilor conectati. Inainte, verifica ca specificatia din fisier e identica cu cea
de pe server.
Verificarea erorii se face in `C:\DMPDIR\script_master.log` de pe serverul clientului
(`depanare-pack-update.md`) — nu apare in `UPD_LOG`.
## Numerotare si versiune_db.txt
Numele scriptului: `<prefix>_YYYY_MM_DD_NN_<subiect>.sql`. Prefixe in uz: `ff` (schema fiecarei
firme), `co` (`CONTAFIN_ORACLE`), `sys`, `ris`, `rf`.
- **`NN` e o secventa unica pe zi, comuna tuturor prefixelor** — un numar consumat de un `co_`
nu se reia intr-un `ff_` din aceeasi zi si invers.
- In `versiune_db.txt` (radacina aplicatiei) se trece **doar versiunea ultimului script `ff_`**:
programele se conecteaza pe schema firmei, nu pe `CONTAFIN_ORACLE`, deci markerul urmareste
numai migrarile aplicate acolo.

34
docs/scripturi-uzuale.md Normal file
View File

@@ -0,0 +1,34 @@
# Scripturi uzuale (sarcini repetitive)
**Regula: o sarcina care se repeta se pune intr-un script si de atunci se apeleaza scriptul.**
Nu reface lantul de pasi din memorie la fiecare sesiune si nu da unui subagent aceleasi instructiuni
a doua oara — daca a doua oara e nevoie de acelasi lucru, scrie scriptul.
| Cand | Ce rulezi | Ce face |
|---|---|---|
| inceput de sesiune, si dupa orice `svn update` | `roa_sync.bat` din radacina proiectului (→ `COMUN\scripts\roa_sync.ps1`) | `svn update``git_sync` (texte `.??2`) → commit `sync SVN r<rev>` → reconciliere cu `origin` (ff/rebase) → push conditionat → inchide branch-urile `claude/*` terminate |
| inainte de un commit | `COMUN\utile\curatenie.ps1` (`-DryRun` doar listeaza) | sterge artefactele de lucru netrackuite: patch-uri de review, `handoff*`/`runda*`/`propuneri_*`, backup-uri `*.pre_runda*.bak`, artefacte de test |
| la "commit / push" | `COMUN\utile\livrare.ps1 -Mesaj "..." [-Comun]` | `git_sync``curatenie` → verificari de livrare → status/diff pe ambele repo-uri → commit + push. `COMUN` doar cu `-Comun`; `push --force` nu exista |
| editare `.vcx`/`.scx` | `D:\ROA\UTIL\foxbin2prg\` : `git_sync.ps1`, `vfp_symbols.ps1`, `txt2vcx.ps1` | reimprospatare text in-arbore, index de simboluri, write-back cu fidelity-check |
| actualizare de baza de date blocata | `COMUN\utile\diag_actualizare.ps1 -Alias <TNS>` | `UPD_ISTORIC``UPD_LOG``script_master.log` → versiuni per schema → job → tablespace → verdict. Vezi `depanare-pack-update.md` |
| spatiu plin la un client | `COMUN\utile\diag_spatiu.ps1 -Alias <TNS> [-Disc] [-SysPassword]` | tablespace, audit, ADR, FRA, disc server, top segmente. Vezi `depanare-spatiu-oracle.md` |
| publicare scripturi de baza de date | `COMUN\utile\publicare_scripturi.ps1 [-Luna YYYY-MM] [-Fisier ...] [-DryRun]` | import in `UPD_DATABASE` → arhiva lunara `database[n]_*.zip` + indexi in `_UPDATE`, cu verificare octet cu octet. Vezi `publicare-scripturi-db.md` |
| teste UI VFP | harness din `COMUN\utile\Teste` | vezi `testare-ui-vfp.md` |
| citirea emailurilor de pe conturile romfast | `COMUN\utile\citeste_email.ps1 [-Cauta ...] [-Nr <linie>]` | listeaza/extrage mesaje din mbox-urile Thunderbird Portable (conectorul Gmail nu vede conturile romfast). Vezi `email-thunderbird.md` |
Documentatia **nu** se genereaza automat si nu exista niciun hook care s-o scrie — `livrare.ps1`
doar semnaleaza ce lipseste (changelog neatins, binar VFP fara textul lui sincronizat).
Candidati inca nescrisi: un helper pentru rulat SQL prin `sqlplus` (fisier ASCII + `@fisier.sql`,
refacut manual la fiecare interogare) si un wrapper care ruleaza `diag_spatiu.ps1` peste toti
clientii, cu un rezumat pe un rand per server.
Fluxul SVN ↔ git din spatele lui `roa_sync`: `fluxul_svn_git.md`.
**Mesaje de commit din PowerShell catre `git`/`svn` (exe native): niciodata `-m $mesaj`.**
PowerShell nu escapeaza ghilimele/backtick/`$` cand paseaza argumente catre un exe nativ - un
mesaj cu `"..."` sparge comanda. Solutie: scrie mesajul intr-un fisier temporar si foloseste
`git commit -F <fisier>` / `svn commit -F <fisier>`, cu textul **UTF-8 fara BOM**
(`[IO.File]::WriteAllText($cale, $mesaj, (New-Object Text.UTF8Encoding $false))` - `Out-File
-Encoding utf8` in PS 5.1 scrie BOM, care ajunge ca prim caracter in mesajul de commit) si
**LF, nu CRLF** (`svn commit -F` refuza fisiere cu linii mixte CRLF/LF: `E135000`).

View File

@@ -0,0 +1,16 @@
# `jc2007` / `jv2007` — reguli
Masurat pe date (`MARIUSM_AUTO`, 28.07.2026).
- **O linie per factura PER PERIOADA**, nu una per factura. Cat timp factura are sold de TVA
neexigibil, randul ei se reporteaza luna de luna cu soldul ramas (masurat: acelasi `id_fact` in
113-115 perioade). Reportarea e in tabela de baza, nu introdusa de view-uri.
- Deci **orice interogare pe sold neexigibil se filtreaza pe `an`/`luna`**. Soldul lunii curente e
cel la zi; fara filtru intorci si facturi stinse demult.
- Nu cauta si in perioade anterioare "ca sa nu scapi nimic" — o factura din mai apare si pe randul
lunii iulie. Ai dubla randurile.
- `tva_incasare` **nu exista pe tabele**, doar pe view-uri (`VJC2025`/`VJV2025`, `vjc2010`/`vjv2010`).
- Coloanele de sold neexigibil, lista completa: `ro24nb/nt`, `ro20nb/nt`, `ro21nb/nt`, `ro11nb/nt`,
`ro19nb/nt`, `ro9nb/nt`, `ro5nb/nt`. **21% si 11% sunt in vigoare din august 2025** si lipsesc din
filtre mai vechi — verifica lista inainte de a refolosi un filtru existent.
- `vjc2010`/`vjv2010` au si ele coloanele `ro11*`/`ro21*`.

View File

@@ -11,11 +11,11 @@ Fisiere in `COMUN\utile\Teste\`: `vfp_ui_harness.ps1` (orchestrator generic, par
`mock_amessagebox.prg` (mock dialog) — infrastructura sta in radacina `Teste\`; suitele stau in
subfoldere pe subiect. Exemplu complet: `achizitie_import\test_import_nota_ui.prg` + `.ps1`.
**REGULA (Marius, 17/07/2026): testele pe aplicatii frontend exerseaza fluxul REAL al
**REGULA (Marius): testele pe aplicatii frontend exerseaza fluxul REAL al
utilizatorului** — formularul/butonul/metoda pe care o apeleaza aplicatia, NU introducerea
directa a randurilor in cursoare/tabele. Popularea directa sare peste validari/filtre/efecte
laterale si da PASS fals (caz real: un articol "adaugat" direct in cursor trecea testul, dar
prin fluxul real nu se adauga deloc). Mock-urile raman permise doar pe INFRASTRUCTURA (Oracle,
laterale si da PASS fals (caz real: articol "adaugat" direct in cursor trecea testul, dar prin
fluxul real nu se adauga deloc). Mock-urile raman permise doar pe INFRASTRUCTURA (Oracle,
dialoguri modale), nu pe pasii fluxului testat.
## Test UI nou in 5 pasi
@@ -33,7 +33,57 @@ dialoguri modale), nu pe pasii fluxului testat.
5. `powershell -File vfp_ui_harness.ps1 -TestPrg <test.prg> -Steps @('pas0',...)`.
PNG-uri in `screenshots\step_<n>_<eticheta>.png`; log in `<test>_log.txt`.
## Capcane / deblocari (toate confirmate in sesiune)
## Dialoguri modale (`Show(1)`)
Doua situatii, cu solutii diferite:
**A. Testul instantiaza el dialogul**`WindowType = 0` inainte de `Show()` (pasul 3 de mai sus).
`Show()` revine imediat si conduci formularul pas cu pas. Prefera intotdeauna varianta asta.
**B. `Show(1)` e hardcodat in metoda aplicatiei** (ex. `frm_facturare_articole.do_adauga_articol` /
`do_modifica`): testul nu are referinta la dialog, deci nu poate seta `WindowType`, iar fluxul real
cere sa treaca prin buton. Se conduce dintr-un **Timer pe `_SCREEN`**, pregatit INAINTE de actiunea
care deschide dialogul:
1. `_SCREEN.AddObject('tmrDrv','Timer')`, `Interval = 200`,
`BINDEVENT(_SCREEN.tmrDrv, 'Timer', <obiect driver>, 'Executa')`, `Enabled = .T.`
2. `Show(1)` **chiar pompeaza mesaje Windows** cat e modal — timerul ticaie normal (masurat: 229
tick-uri in 46s). Bucla modala nu e oarba la evenimente externe.
3. **Detectia formularului: `_SCREEN.Forms(i)` / `_SCREEN.FormCount`**, potrivit pe `.Class`.
**`_SCREEN.ActiveForm` NU merge headless** — a ramas gol la toate cele 229 de tick-uri: depinde
de `WM_ACTIVATE`, care nu se declanseaza fara focus real, pe cand colectia `Forms` contine
formularul indiferent de activare.
4. **Referinta la controale**: `loForm.<nume>` merge normal; iterarea `loForm.Controls(i)` cu
potrivire pe `.Name` e alternativa robusta (utila si ca diagnostic, pentru ca listeaza ce EXISTA
cu adevarat). **Daca accesul da 1925 "Unknown member" pe un control care sigur e in clasa,
suspecteaza mediul de test, nu colectia**: o eroare in constructia unui obiect adaugat mai
devreme opreste adaugarea celor de dupa, iar formularul ramane incomplet fara sa se plange (caz
real: lipsa cursorului `saft_taxtable`, capcana j, a lasat instanta cu 21 de controale in loc de
25, iar controlul urmator din ordinea de adaugare "disparea"). Verifica intai `ControlCount` si
lista de nume.
5. **Inchiderea**: `do_termin()` (gateaza pe `inainte_de_do_termin()`, seteaza `gnButon = 1` si
elibereaza — `_frm_base.vc2:363-371`) sau `do_renunt()`. **Daca validarea respinge, `do_termin()`
nu seteaza `gnButon` si NU elibereaza formularul, deci `Show(1)` ramane blocat** — in testele
care asteapta o respingere de validare, iesi prin `do_renunt()`.
6. **Driverul se instrumenteaza obligatoriu**: log pe fiecare pas, `TRY/CATCH` cu
`ErrorNo`/`Message`/`LineNo`, iar steagul "am tratat dialogul" se seteaza **dupa** interactiunea
reusita, nu inainte. Altfel prima eroare e invizibila si blocheaza orice reincercare — simptomul
e tick-uri la nesfarsit pana la timeout, fara nicio urma in log.
**Regula de metoda, invatata scump**: mediul unei suite noi se mosteneste din suita care **TRECE**,
nu din una care esueaza. Un mediu copiat dintr-un test nevalidat a produs trei defecte succesive
(cursor `saft_taxtable` lipsa, mock `poArticol` incomplet, nume de variabila coliziv), fiecare
descoperit dupa cate o rulare, si toate aratau ca defecte de aplicatie sau ca "test agatat". Cand
doua suite au nevoie de acelasi mediu, **extrage-l intr-un singur loc** (cu grija la capcana l
pentru constructia obiectelor).
Doua non-dovezi, ca sa nu se piarda timp pe ele:
- `AMEMBERS(a, o)` **fara flagul 2** intoarce proprietati/metode, **nu** obiectele continute —
absenta unui control din acea lista nu inseamna ca lipseste din clasa.
- `==` pe doua obiecte da eroare **107** "Operator/operand type mismatch"; pentru identitate se
foloseste `COMPOBJ()`.
## Capcane / deblocari
a. **`SET SAFETY OFF` + `SET TALK OFF` inaintea primului `STRTOFILE`.** Cu SAFETY ON, scrierea
log-ului existent scoate un dialog modal care blocheaza rularea (proces viu, "instanta
@@ -46,23 +96,25 @@ c. **Asteptarea `ready_0`**: cu `.fxp` cald START apare in ~2s, la rece mult mai
classlib-uri). `-ReadyTimeoutSec` generos (implicit 180s); retry NUMAI la "start ratat",
nu la "start lent". Detectia "a pornit" se face pe mtime-ul log-ului > momentul lansarii
(un log stale tinut de un vfp9 zombi pacaleste verificarea "log ne-gol") - omoara zombii
inainte de fiecare lansare.
PROPRII (filtrati pe linia de comanda, vezi punctul e) inainte de fiecare lansare.
d. **`vfp9 -A test.prg` deschide INTERMITENT editorul** in loc sa ruleze (log gol). Lanseaza
`.fxp`-ul PRECOMPILAT. Precompilarea (`COMPILE`+`QUIT`) atarna dupa COMPILE si, rulata in
ACEEASI sesiune powershell, otraveste lansarile ulterioare - ruleaza-o intr-un proces copil
izolat (`Start-Process -Wait _precompile.ps1`).
e. **Suitele NU se ruleaza in paralel**: `_precompile.ps1` face `Get-Process vfp9 | Stop-Process
-Force` (omoara toate instantele), deci un test lansat in paralel il ucide pe cel in curs.
f. **FARA FURT DE FOCUS (17/07/2026)**: `Graphics.CopyFromScreen` fura focus si se corupe daca
utilizatorul lucreaza in paralel - nu se mai foloseste. Capturile se fac cu `PrintWindow`
(user32, P/Invoke) pe `Process.MainWindowHandle`, flag `2` = `PW_RENDERFULLCONTENT`
(fallback `0` daca iese goala); merge cu fereastra acoperita, dar NU minimizata. Fereastra
se muta OFF-SCREEN (`SetWindowPos`, `HWND_BOTTOM`, x=-4000, `SWP_NOACTIVATE`) imediat ce
apare handle-ul si SE RE-IMPINGE la fiecare pas (VFP se reactiveaza singur la
`Show()`/dialoguri). Consolele powershell copil sunt `-WindowStyle Hidden` (sigur pentru
consola, NU pentru GUI VFP - ascunsa, `PrintWindow` poate reda gol). Implementat in
`vfp_ui_harness.ps1` (Take-Screenshot, Push-Offscreen, Wait-MainWindowHandle) si
`_precompile.ps1`.
e. **Suitele NU se ruleaza in paralel**: harness-ul omoara instantele `vfp9` ramase inainte de
fiecare lansare, deci un al doilea test pornit peste primul il ucide. Omorarea e filtrata pe
linia de comanda (`Win32_Process.CommandLine` contine folderul de teste): instantele `vfp9`
straine (sesiunea IDE a utilizatorului, teste dintr-un ALT proiect VFP) nu sunt atinse. Nu
reintroduce `Get-Process vfp9 | Stop-Process -Force` fara filtru.
f. **FARA FURT DE FOCUS**: `Graphics.CopyFromScreen` fura focus si se corupe daca
utilizatorul lucreaza in paralel - nu se mai foloseste. Capturile: `PrintWindow` (user32,
P/Invoke) pe `Process.MainWindowHandle`, flag `2` = `PW_RENDERFULLCONTENT` (fallback `0` daca
iese goala); merge cu fereastra acoperita, NU minimizata. Fereastra se muta OFF-SCREEN
(`SetWindowPos`, `HWND_BOTTOM`, x=-4000, `SWP_NOACTIVATE`) la aparitia handle-ului si SE
RE-IMPINGE la fiecare pas (VFP se reactiveaza singur la `Show()`/dialoguri). Consolele
powershell copil: `-WindowStyle Hidden` (sigur pentru consola, NU pentru GUI VFP ascunsa -
`PrintWindow` poate reda gol). Implementat in `vfp_ui_harness.ps1` (Take-Screenshot,
Push-Offscreen, Wait-MainWindowHandle) si `_precompile.ps1`.
g. **Mock de messagebox**: `FUNCTION amessagebox` care returneaza direct valoarea butonului
(6=Da), incarcat cu `SET PROCEDURE ... ADDITIVE` **PRIMUL**, inaintea fisierelor aplicatiei:
la nume duplicat de procedura VFP foloseste fisierul cautat PRIMUL (verificat empiric).
@@ -79,17 +131,84 @@ i. **Cursorii trebuie sa aiba EXACT indecsii creati de fluxul real** inainte de
uneori in cascada la apeluri repetate. Verifica in codul apelant ce indecsi se creeaza si
replica-i identic.
j. **Mock-urile de date trebuie sa reproduca structura si semantica REALA a sursei** (view
Oracle: toate coloanele; relatii intre randuri: toate randurile implicate, nu unul singur cu
valori "compuse" manual in test). Un mock incomplet lasa campuri mereu NULL sau ascunde
pasul care se testeaza. Cand un flag global activeaza cod suplimentar (ex. `gl406`), acel
cod cere mock-uri in plus - verifica ce apeleaza si adauga metodele lipsa din dummy.
Oracle: toate coloanele; relatii intre randuri: toate randurile implicate, nu una singura cu
valori "compuse" manual). Un mock incomplet lasa campuri NULL sau ascunde pasul testat. Cand
un flag global activeaza cod suplimentar (ex. `gl406`), acel cod cere mock-uri in plus -
verifica ce apeleaza si adauga metodele lipsa din dummy. Cu `gl406=.T.` (SAFT),
`GetTaxCodeIdPart`/`GetTaxCode` cer: `goApp.ReadIni`/`WriteIni` (clasa `dummyapp` are nevoie
de METODE, nu doar proprietate), `goExecutor.oReset` (no-op e suficient), si cursor
`saft_taxtable` real (nu doar mock pe `goExecutor` - `update_jtva_coloane` face
`USE saft_taxtable` direct pe alias). Fara ele, simptomul e dialog nativ Windows "Open" (cauta
`saft_taxtable.dbf`) care blocheaza headless la nesfarsit, fara linie noua in log si CPU 0% -
vezi `depanare_testare_vfp.md` pentru diagnostic cu `EnumWindows`/`PrintWindow`. Acelasi
simptom apare si FARA `gl406`: un control cu `RowSourceType=3` legat direct in clasa de un SQL
pe `saft_taxtable` (ex. combo pe explicatie SAFT) isi evalueaza `RowSource` la constructia
formularului indiferent de `gl406` sau de `Visible=.F.` - cursorul mock trebuie creat oricum.
k. **`LOCATE FOR camp == 'literal'` pe camp `C(n)` padded nu gaseste nimic** (`==` e exact) -
foloseste `ALLTRIM(camp) == 'literal'`.
l. **`CREATEOBJECT`/`ADDPROPERTY` se comporta gresit apelate DINTR-O PROCEDURA in acest runtime
headless** (obiect returnat ca string de 30 spatii; `ADDPROPERTY` da eroare 11). Din
programul PRINCIPAL merg. Construieste obiectele-parametru INLINE in main, nu intr-un helper.
(Cauza neclara; reproductibil.)
headless** (obiect returnat ca string de 30 spatii; `ADDPROPERTY` da eroare 11). Din programul
PRINCIPAL merg. Construieste obiectele-parametru INLINE in main, nu intr-un helper. Cauza
confirmata intr-un caz concret: linie de cod prea lunga in ACEEASI metoda de clasa - vezi
`depanare_testare_vfp.md` sectiunea 6; remediul (constructie inline) ramane valabil oricum.
m. **Fara `SELECT-SQL` pe cursorul legat de grid**: `SELECT ... FROM <cursor> INTO CURSOR` cat
timp cursorul e RecordSource-ul unui grid viu poate omori procesul vfp9 silentios (fara
eroare catchabila, fara semafor). Foloseste xBase nativ (`COUNT FOR ... TO`, `CALCULATE`,
`LOCATE`), care nu comuta zona de lucru a grid-ului.
n. **Wrapper-ul `.ps1` trebuie sa paseze `-SyncDir` daca `.prg`-ul isi seteaza propriul
`gcSyncDir`** - altfel testul scrie semafoarele intr-un folder si `vfp_ui_harness.ps1` le
asteapta in cel implicit (`uisync\`), deadlock pana la timeout. Simptom identic cu "test
agatat", dar FARA `.ERR` si cu CPU ~0 la procesul vfp9 (nu un dialog modal - procesul chiar
asteapta un fisier care nu vine). Timeout minim: ~30s x numarul de pasi din `-Steps`
(auto-continue per checkpoint din `HarnessWaitContinue`), plus marja de pornire.
o. **Formularul resincronizeaza singur dupa o alegere din grid** (`lSyncPending` + `tmrSync`,
ex. `do_modifica_explicatie_tva` din `ointroduceri.vcx`): starea imediat dupa actiune NU e
observabila - `DOEVENTS FORCE` lasa timer-ul sa porneasca, iar resincronizarea rescrie ce
tocmai s-a aplicat (la explicatia TVA: randul S revine la familia documentului, randurile T se
realiniaza dupa el). Scrie assert-urile pe starea de DUPA resincronizare, pe un efect pe care
resincronizarea NU il repara (acolo: `scc`-ul randului T, atins doar la schimbarea explicatiei)
- altfel testul pica fara sa fie ceva gresit in cod.
p. **Nu numi variabilele ca functii built-in VFP.** VFP e insensibil la litere mari/mici, iar la
coliziune **functia castiga**. Caz real: `LOCAL loCk` pentru referinta la un checkbox se ciocneste
cu `LOCK()``loCk.Value = 1` da eroarea **1924 "LOCK is not an object"**, iar `VARTYPE(loCk)`
evalueaza `LOCK()` si intoarce `'L'`, deci verificarile de tipul `VARTYPE(lo...) == 'O'` ies
**tacut false** si par sa spuna ca obiectul nu a fost gasit — masuratoarea e stricata, nu
rezultatul. Simptom de recunoscut: mesajul de eroare contine numele **cu majuscule** al unei
functii VFP, nu numele variabilei asa cum ai scris-o. Prefixeaza distinctiv (`loBifa`, `loCtrl`).
q. **`DO ... WITH` paseaza PRIN REFERINTA, iar variabila devine invizibila sub numele ei propriu in
procedura apelata.** Consecinta urata: orice `?variabila` din SQL passthrough de pe lantul
apelurilor respective nu se mai poate lega, si VFP deschide dialogul nativ **"View Parameter —
Enter the value for `<var>`"**, care blocheaza testul headless la infinit (fara log, fara
eroare). Dovedit pe date: o variabila globala era valida in programul principal la fiecare
checkpoint, dar `TYPE()` intorcea `'U'` (nedefinita) exact la intrarea in procedurile apelate cu
`DO proc WITH gnAn, gnLuna` — si valida in cele apelate fara `DO ... WITH` — corelatie exacta cu
**sintaxa apelului**, nu cu ce face procedura. Remediu: paranteze pe fiecare argument forteaza
pasarea prin valoare — `DO proc WITH (gnAn), (gnLuna)`.
r. **O suita care testeaza o clasa din `COMUN` poate incarca implicit copia ALTUI PRODUS**, daca
harnessul de mediu comun (ex. `test_init_env_auto.prg`) face `SET DEFAULT TO`/`SET PATH` pe
working copy-ul altui produs (ex. `D:\ROA\ROACONT\...`) inainte de `SET CLASSLIB TO <clasa>
ADDITIVE`: `Createobject` gaseste prima clasa cu acel nume pe `PATH`, care poate fi
`D:\ROA\ROACONT\COMUN\clase\<clasa>.vcx` in loc de fisierul editat sub test — silentios, fara
eroare. Simptom: testul trece curat, dar valideaza cod vechi/alt working copy; orice concluzie
trasa asa e nula. Remediu, dupa initializarea mediului comun: `RELEASE CLASSLIB <nume>` +
`SET CLASSLIB TO <cale completa a fisierului sub test> ADDITIVE` (`SET CLASSLIB ... ADDITIVE`
**singur**, fara `RELEASE` intai, da eroarea 24 "Alias name is already in use" si pastreaza
tacut copia veche). Verificare obligatorie dupa instantiere: `loForm.ClassLibrary` trebuie sa
arate calea completa asteptata.
s. **Dialoguri native care nu apar in log si nu sunt prinse de `ON ERROR`/mock-uri** (ex. "View
Parameter", "Open" pe fisier lipsa): nu se depaneaza orbeste, se ruleaza sub
`COMUN\utile\Teste\watchdog_vfp.ps1 -Script <test.prg> -AutoDismiss`. Lanseaza `vfp9.exe -A -T`,
polleaza ferestrele top-level ale procesului (identificate prin `Process.MainWindowHandle`, nu
dupa numele clasei — VFP foloseste clase `vfp9...` si pentru shell-ul principal si pentru
dialogurile proprii), captureaza PNG + textul fiecarui control copil (`WM_GETTEXT`) la orice
fereastra noua, si omoara procesul la iesire (`finally`, niciodata ramas viu). **Interzis strict:
input real** (`keybd_event`/`SetForegroundWindow`/`SendInput`/`mouse_event`) — masina e
partajata, un input injectat la nivel de sistem ajunge in orice fereastra are focus in acel
moment, nu neaparat in dialogul tintit (patit: un ESCAPE injectat a intrerupt sesiunea IDE a
utilizatorului, aflat in lucru in paralel). `-AutoDismiss` foloseste STRICT mesaje Windows
tintite pe handle (`BM_CLICK` pe buton Cancel/Anulare, altfel `WM_COMMAND IDCANCEL` ->
ESCAPE ca mesaj `WM_KEYDOWN`/`WM_KEYUP` -> `WM_CLOSE`); pe dialogurile proprii VFP owner-drawn
(butoane desenate, nu HWND-uri reale) dismiss-ul poate esua cinstit — captura PNG + dump text
raman oricum de incredere, indiferent de rezultatul dismiss-ului. Sterge intotdeauna `.fxp`-ul
vechi inainte de FIECARE rulare (watchdog-ul o face singur la lansare) — altfel VFP ruleaza
tacut codul compilat vechi si rulari "identice" dau rezultate diferite, fara nicio urma in log.

View File

@@ -14,16 +14,16 @@ Start-Process -FilePath "C:\Program Files (x86)\Microsoft Visual FoxPro 9\vfp9.e
```
- Gate-ul de pornire (`gcNumeProgram = 'ROAGEST'` in `roagest.prg`) verifica
`JUSTSTEM(SYS(16,0))` — numele programului de la nivelul 0 al stivei, nu numele
procesului `.exe`. Rulat interpretat, `SYS(16,0)` = `roagest.prg`, deci gate-ul trece.
`JUSTSTEM(SYS(16,0))` — numele programului de la nivelul 0 al stivei, nu numele procesului
`.exe`. Rulat interpretat, `SYS(16,0)` = `roagest.prg`, deci gate-ul trece.
- Fereastra rezultata are titlul `ROA - Gestiuni` (setat din `NUMEPROGRAM`).
## Capcana: focus furat de terminal
Daca sesiunea Claude Code afiseaza output in timp ce comanda de lansare ruleaza,
fereastra terminalului/IDE-ului ramane in prim-plan si VFP porneste in fundal —
`Screenshot`/`Snapshot` din `windows-mcp` pot raporta "No windows found" desi procesul
si fereastra exista (verificabil cu `Get-Process vfp9 | Select MainWindowTitle`).
Daca sesiunea Claude Code afiseaza output in timp ce comanda de lansare ruleaza, fereastra
terminalului/IDE-ului ramane in prim-plan si VFP porneste in fundal — `Screenshot`/`Snapshot`
din `windows-mcp` pot raporta "No windows found" desi procesul si fereastra exista (verificabil
cu `Get-Process vfp9 | Select MainWindowTitle`).
Fix: inainte de screenshot, adu explicit fereastra in prim-plan dupa titlu:
@@ -31,8 +31,8 @@ Fix: inainte de screenshot, adu explicit fereastra in prim-plan dupa titlu:
mcp__windows-mcp__App mode=switch name="ROA - Gestiuni"
```
apoi `Screenshot`. Nu te baza pe enumerarea implicita de ferestre a `windows-mcp` cand
ai lansat procesul chiar in runda curenta de comenzi.
apoi `Screenshot`. Nu te baza pe enumerarea implicita de ferestre a `windows-mcp` cand ai lansat
procesul chiar in runda curenta de comenzi.
## Curatare dupa test

View File

@@ -0,0 +1,118 @@
# Tipurile de document din facturare (`VANZARI.TIP`) si seturile de contare (`ID_SET`)
Referinta pentru toata suita ROA: `PACK_FACTURARE` e in `COMUN`, iar `VANZARI.TIP` e citit de
view-urile `FACT_VFACTURI` / `FACT_VFACTURI2`, de gridul principal de listare si de retiparire.
**Surse** (nu presupuneri):
- perechile `(lnIdSet, tnTip)` — comentariul din antetul `PACK_FACTURARE` (`:80-125` in exportul
`all_source`), singurul loc care le documenteaza impreuna;
- eticheta afisata — `CASE a.tip` din coloana `EXPLICATIE` a celor doua view-uri, citit din sursa
live de pe `MARIUSM_AUTO` (06.08.2026);
- restul — cod, marcat ca atare.
`ID_SET` e setul de formule contabile (`XSETS.ID_SET`, ajunge in `ACT.ID_SET`), pus in variabila de
pachet `pack_facturare.nid_set` din `initializeaza_date_factura` (`:1864`). **Regula generala: setul
"cu scadere din gestiune" e cel de baza + 10.**
## Facturi
| `ID_SET` | cu scadere | `TIP` | Document | `EXPLICATIE` afisat |
|---|---|---|---|---|
| 25000 | 25010 | 1 | pe baza de lista de preturi | `POLITICA PRETURI` |
| 25001 | 25011 | 2 | pe baza de contracte | `CONTRACT` |
| 25002 | 25012 | 3 | pe baza de comenzi | `COMANDA` |
| 25003 | 25013 | 4 | pe baza de avize | `FACT. DIN AVIZ` |
| 25004 | 25014 | 5 | lista de preturi in valuta | `POLITICA PRETURI - INVOICE` |
| 25005 | 25015 | 6 | contract in valuta | `CONTRACT - VALUTA` |
| 25006 | — | 7 | credit note | `CREDIT NOTE` |
| 25007 | 25017 | 8 | retur factura in lei | `RETUR FACTURA IN LEI` |
| 25008 | 25018 | 9 | retur factura in valuta | `RETUR INVOICE` |
| 25009 | 25019 | 10 | factura fiscala in valuta | `POLITICA PRETURI - FACTURA VALUTA` |
| 25042 | 25052 | 43 | bon fiscal (ROARETAIL, colectate de la magazine) | `BONURI FISCALE MAGAZINE` |
| 25043 | — | 44 | factura hotel | `HOTEL` |
| 25044 | 25054 | 45 | factura restaurant | `RESTAURANT` |
| 25045 | 25055 | **46** | **nota de plata restaurant** | **nicio ramura** |
| 25047 | 25057 | 48 | factura marfa custodie **cu** descarcare K | `FACT. CUSTODIE CU DESCARCARE PE BAZA DE K` |
| 25048 | 25058 | 49 | factura marfa custodie **fara** descarcare K | `FACT. CUSTODIE FARA DESCARCARE PE BAZA DE K` |
| 25051 | 25061 | 52 | pe baza de contract, factura fiscala in valuta | `CONTRACT - FACTURA VALUTA` |
| 50100 | 25060 | 51 | factura ROAACNPRO | `COMERCIAL-FACTURARE` |
## Avize de expeditie
| `ID_SET` | cu scadere | `TIP` | Document | `EXPLICATIE` afisat |
|---|---|---|---|---|
| 25020 | 25030 | 21 | catre clienti, **din comanda** | `AVIZ PE BAZA DE COMANDA` |
| 25021 | 25031 | 22 | catre clienti, din lista de preturi | `AVIZ DIN POLITICA DE PRETURI` |
| 25022 | 25032 | 23 | transfer catre subunitati, din lista | `TRANSFER` |
| 25023 | 25033 | 24 | aviz de retur | `AVIZ DE RETUR` |
| 25024 | 25034 | 25 | transfer catre subunitati, **din comanda** | `TRANSFER PE BAZA DE COMANDA` |
| 25025 | 25035 | 26 | catre clienti, din contract | `AVIZ PE BAZA DE CONTRACT` |
| 25026 | 25036 | 27 | transfer catre subunitati, **pe baza de lucrare** | `TRANSFER PE BAZA DE LUCRARE` |
| 25027 | 25037 | 28 | catre clienti debitori, **din comanda** | `CLIENTI DEBITORI - COMANDA` |
| 25028 | 25038 | 29 | catre clienti debitori, din lista | `CLIENTI DEBITORI - POLITICA PRETURI` |
| 25029 | 25039 | 30 | transfer catre subunitati, pe baza de NIR | `AVIZ PE BAZA DE NIR` |
| 25040 | 25050 | 41 | retur transfer catre subunitati, lista de pret | `RETUR TRANSFER` |
| 25041 | 25051 | 42 | catre clienti **custodie, din comanda** | `CLIENTI IN CUSTODIE - COMANDA` |
| 25046 | 25056 | **47** | catre clienti **custodie, din comanda, pentru descarcare cu K** | `CLIENTI IN CUSTODIE - COMANDA (K)` |
| 25049 | 25059 | 50 | *in lucru* — retur de la clienti custodie | nicio ramura |
## Tipuri negative
Nu apar in comentariul din pachet; luate din `CASE`-ul `EXPLICATIE`. Vin din alte produse sau din
fluxuri valorice.
| `TIP` | `EXPLICATIE` afisat | Observatii |
|---|---|---|
| -1 | `MATERII PRIME SI MATERIALE` | |
| -2 | `PRODUSE` | |
| -3 | `MARFURI LA PRET DE ACHIZITIE` | |
| -4 | `MARFURI LA PRET DE VANZARE` | |
| -6 | `RETUR TRANSFER DIN GESTIUNE VALORICA` | ROAGEST; `ID_SET` 236/240/241/242 |
| -7 | `AVIZ DE RETUR - VALORIC` | |
| -8 | `FACTURA DE RETUR - VALORICA` | |
| -9 | `PROTOCOL CU TVA - AVIZ EXPEDITIE` | |
| -10 | `SPONSORIZARE - AVIZ EXPEDITIE` | |
| -11 | `MARFURI LA PRET DE ACHIZITIE *` | |
| -12 | `DEVIZE AUTO` | **ROAAUTO**, `factureaza_deviz` din `oproceduri_devize.prg` |
| -13 | `RETUR MARFA IN CUSTODIE` | |
## Seturile de tipuri folosite in cod (unde conteaza incadrarea)
| Set | Unde | Ce face |
|---|---|---|
| `{3, 21, 28, 42, 47}` | `initializeaza_date_factura` (`:1888-1894`) | populeaza `pack_facturare.nid_comanda` din `clistaid` |
| `+ {27}` | `scrie_avize_lucrare:5859` | suprascrie `nid_comanda` prin cursor pe `COMENZI` legat de `ID_LUCRARE` |
| `{3, 21, 27, 28, 42, 46}` | `ALTELE` in ambele view-uri | afiseaza **comanda** (`nr_comanda/data`) |
| `{4, 24, 8, 9}` | `ALTELE` in ambele view-uri | afiseaza **avizul** |
| `{23, 25, 27, 30, 41, -6}` | `CLIENT` in ambele view-uri | afiseaza gestiunea, nu partenerul |
| `{23, 25, 27, 30, 41}` si `-6` | `scrie_in_vanzari` (disc `:13530-13540`) | `lnIdGestiune` explicit, nu `min()` din detalii |
## Capcane confirmate
1. **`46` vs `47` in `ALTELE`.** Lista din view contine `46` (nota de plata restaurant, document
care n-are comanda) si **nu contine** `47` (aviz custodie din comanda, care are). Pachetul
populeaza `nid_comanda` pentru `47`, nu pentru `46`. `CASE`-ul `EXPLICATIE` din acelasi view are
ramura pentru `47` si **nu** are pentru `46` — deci cele doua `CASE`-uri din acelasi view se
contrazic pe aceste doua cifre. Decizia lui Marius (06.08.2026): **se adauga `47`, `46` ramane
asa cum a fost scris.**
2. **Efect vizibil pe `46`, azi**: ramura fiind luata fara ca documentul sa aiba comanda,
`f.nr_comanda || '/' || to_char(f.data_comanda, ...)` da un **`/`** singur in coloana "Altele",
nu gol. Nu s-a observat pe date pentru ca niciun client verificat nu foloseste modulul de
restaurant (0 documente `tip=46` si pe `MARIUSM_AUTO`, si pe `VENDING`).
3. **`ID_SET` 25051 apare de doua ori** in comentariul din pachet: ca set "cu scadere" pentru
`tip=42` si ca set de baza pentru `tip=52`. Coliziune in documentatie, neverificata pe
`XSETS` — de lamurit inainte de a te baza pe ea.
4. **`tip=51`**: comentariul spune "factura ROAACNPRO", eticheta afisata e `COMERCIAL-FACTURARE`.
Acelasi lucru, doua denumiri; eticheta din view e cea confirmata de constantele VFP curente
(`ofacturare_comun.vc2:3654,3657`).
5. **`tip=50`** e marcat "in lucru" in comentariu si n-are ramura de eticheta — de tratat ca
neterminat, nu ca tip valid.
6. **Comentariul nu e cod.** E singura documentare a perechilor `(ID_SET, TIP)`, dar poate fi ramas
in urma. Inainte de a te baza pe o linie din el pentru o modificare, confirm-o pe cod
(`initializeaza_date_factura`, `CASE`-urile din view-uri) sau pe `XSETS`.
## Legaturi
- `scripturi-migrare-db.md` — sursa de referinta pentru DDL e `MARIUSM_AUTO`, nu o schema de client.
- `conventie_null_vfp.md``TIP_INCASARE` si celelalte coloane `0` vs `NULL` din view-uri.

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

51
docs/todos.txt Normal file
View File

@@ -0,0 +1,51 @@
DONE 1. ROACONT. verificarea codurilor fiscale pe ANAF sa foloseasta istoricul de verificari drept cache 1 luna, in loc sa verifice mereu pe anaf. DE FAPT VREAU VERIFICARE ANAF CARE ACTUALIZEAZA SI CACHE, SI DACA NU MERGE ANAF, SA FOLOSEASCA CACHE
Vreau acelasi sistem de cache si pentru Registrul TVA la incasare care acum se descarca in schema comuna de baza de date CONTAFIN_ORACLE, pe serverul de baza de date, arhive zip de la anaf si se actualizeaza tabelele de rtvai_*
Poate folosesti exact datele de la anaf descarcate pentru verificarea codurilor fiscale, in cazul in care exista informatia.
Vreau ca verificarile de coduri fiscale din D406, D394, Registrele de TVA sa foloseasca direct ANAF, si sa actualizeze cache-ul istoricul din baza de date (ISTORIC_CODURI_FISCALE)
DONE 2. ROACONT - Borderou eFactura, checkbox-urile diferente fata de Registrele de TVA sa aiba in caption si numarul de inregistrari cu diferente, astfel incat utilizatorul sa stie daca este cazul sa filtreze pentru afisarea facturilor cu diferente
DONE 3. ROACONT - modificare nota, explicatia tva sa filtreze dupa procent tva din tabel, ca sa arate o selectie mai mica de explicatii tva. vezi cum ai facut la explicatia tva din ointroduceri.vcx > import_nota.
DONE 4. ROACONT - overificari.vcx > formularul istoric coduri fiscale are coloane care nu mai au relavanta sau nu mai sunt completate din tabel. in tabelul contafin_oracle.istoric_coduri_fiscale, campul regcom are spatii si nu se afiseaza in formularul istoric. verifica
DONE 5. ROACONT - VERIFICARE cod fiscal, label-ul de sub grid-ul cu rezultate si detalii F4 sa contina si status "TVA Incasare"
6. ROAFACTURARE - EDITARE FACTURA EMISA ANTERIOR, CARE NU A FOST TRIMISA INCA IN EFACTURA (anaf_efactura.id_fact). punctul critic este ca notele contabile si eventual rulajele generate se genereaza complicat la emiterea facturii prin pack_facturare, iar editarea este o simpla editare, si nu sincronizeaza si notele contabile si rulajele. si sunt diverse tipuri de facturi sau de avize (pe baza de lista de preturi, pe baza de comanda, pe baza de contract, pe baza de aviz) si fiecare genereaza note contabile sau rulaje si articole de vanzare (vanzari si vanzari_detalii)
7. ROAFACTURARE - TVA unitar si valoarea TVA pe o linie de articol este calculata si nu salvata in vanzari si vanzari_detalii. din aceasta cauza, daca o factura are valoare totala 99.99 lei, dar utilizatorul doreste 100.00 lei total cu tva (pentru ca politica de preturi are bifat preturi fara TVA si se porneste calculul incepand de la pretul fara TVA al articolului) tva-ul se calculeaza rotunjit si nu se poate edita, ca sa dea factura fix 100.00 lei. implicatiile calculului TVA in loc de salvare sunt foarte mari si adanci in program, la introducerea facturii, listarea facturii initiale, relistarea facturii
Sau de fapt este posibil sa poata utilizatorul sa modifice "preturi_cu_tva" la nivel de fiecare articol, la introducerea facturii si ulterior la editare factura, tocmai pentru ca utilizatorul doreste sa ajusteze tva-ul total pentru ca are restrictie sa dea facturii o valoare totala rotunjita, si se poate ajusta exact din pretul cu tva individual. pret_cu_tva se salveaza in vanzari_detalii pe fiecare articol.
DONE 8. ROAFACTURARE - in pack_facturare am salvat in vanzari valori totale denormalizat (fara tva, tva, cu tva, numarul avizului/comanda/contract etc.) ca sa nu le calculez in view din vanzari_detalii pentru ca view-ul de facturi este foarte complex, cu functii si expresii si nu era optimizabil si acceseaza total tabelele vanzari si vanzari_detalii. folosesc un view pe modelul original, si un view cu valorile totale din vanzari. doar ca am observat un bug, la facturile din avize, nu se salveaza corect in vanzari avizul sau numarul/data/suma chitantei daca factura este achitata numerar. trebuie depanat. schema de verificare productie este VENDING@ROA_VENDING
DONE 9. ROAGEST - MODIFICARE REGISTRU JURNAL - SA SE POATA MODIFICA SI "NNIR" in notele contabile si sincronizat in rulajele asociate. nu exista coloana NNIR in formularul de editare.
10. ROAFACTURARE - Integrare pagina contracte si rapoarte contracte in ROAFACTURARE, similar COMENZI in ROAFACTURARE - facturare pe baza de comenzi/contracte. trebuie comasate si drepturile pe obiectele din roacontracte cu obiectele noi din ROAFACTURARE.
11. ROAFACTURARE - Integrare politici de preturi in ROAFACTURARE - sunt numai editari de liste de preturi, note contabile, nomenclator articole, drepturi pe liste de preturi, care toate se folosesc numai in programul ROAFACTURARE
12. ROAFACTURARE - sa pot sa folosesc direct nomenclatorul de articole pe post de lista de preturi, sa nu mai definesc liste de preturi, note contabile asociate. Acum am un echivalent (lista de articole din stoc ca o lista de preturi virtuala)
Ca sa vand un articol, trebuie sa il introduc in nomenclatorul de articole obligatoriu. Acum trebuie sa il introduc si intr-o lista de preturi, ca sa am valuta, nota contabila de vanzare si daca are pret_cu_tva sau nu, procentul de tva vanzare, si bineinteles, pretul.
Am vazut la SAGA (alt ERP popular) ca in nomenclatorul de articole au cateva coloane de multe preturi, probabil pentru mai multe liste de preturi (todos-articole-preturi-saga.png)
Ideea este sa se poata face configurarea mult mai repede, eficient, dintr-un singur loc, ca sa se poata face factura mai rapid. Acum este nevoie de mult suport tehnic/instructaj si configurari pana se ajunge la facturare, si daca apare un articol diferit (ex: vanzare auto, in loc de marfa in mod normal), trebuie creata o politica noua de preturi, ca sa ii spun ce nota contabila de vanzare (4111 = 7xx) sa aiba aiba articolul respectiv.
13. ROAFACTURARE - FORMULARUL DE FACTURARE SA INCLUDA SI FORMULARUL DATE_FACTURA/DATE_AVIZ ETC. SI SA NU MAI INCARCE DE PE SERVER TOATE ARTICOLELE DIN TOATE POLITICELE DE PRETURI - INTRUCAT ESTE POSIBIL SA FIE SI MII DE ARTICOLE SI DUREAZA MULT SA LE ADUCA DE PE SERVER. AM INCEPUT DEJA MAI DEMULT UN FORMULAR UNIFICAT frm_facturare_articole2, DAR ERA MULT DE INTEGRAT DIN FORMULARUL VECHI.
FRONTEND SIMILAR PE CARE IL DORESC ESTE IN ROAACPRO > FACTURA, SAU IN IMPORTUL DE EFACTURA, IN CARE AM INTEGRAT DATELE FACTURI, DOAR CA FACTURAREA DIN ROAFACTURARE ESTE MAI COMPLEXA - ESTE FOLOSITA SI PENTRU POLITICI DE PRETURI SI PENTRU CONTRACT/COMANDA/AVIZ/RETUR ETC.
INTERESUL MEU ESTE SA SIMPLIFIC INTERFATA, SA FIE MAI EFICIENTA, SA NU FIE 2 FORMULARE PENTRU FACTURA, SA FAC MAI RAPID.
14. ROACONT - efactura se salveaza xml detaliat si xml zip efactura si ocupa mult spatiu. vreau sa stiu cand nu mai este nevoie de xml detaliat si daca se poate curata tabelul ca sa nu mai ocupe spatiu, cel putin pentru facturi mai vechi. este important zip pentru ca este factura originala anaf.
15. ROACONT - ce locuri din program mai folosesc frm_modific2007 in loc de frm_modific2024. trebuie migrat la formularul mai nou.
16. ROAFACTURARE - in date_factura/date_aviz etc, la finalizare se verifica cursul valutar necesar pentru politicile de preturi care se factureaza. la revenire din formularul de curs valutar, focusul revine inainte de numar document, cred ca pe TIP DOCUMENT, si la iesire din serie se regenereaza numar act, ceea ce este periculos daca utilizatorul l-a schimbat si se modifica automat.
17. ROAFACTURARE - daca o nota contabile de vanzare nu are configurat tip de venit/cheltuiala, si nici articolele din lista de preturi, si nici nu se completeaza tip venit/cheltuiala la facturare, la finalizarea facturii apare o eroare oracle ORA ca id_venchelt nu are voie sa fie null. eroarea nu este user friendly si nu se poate recupera usor, pentru ca trebuie sa se dea renunt la toata factura si sa se reia tot porcesul, cu completarea tip venit cheltuiala. si nici nu stiu de ce este obligatoriu tip venit/cheltuiala.
18. ROAFACTURARE - EMITERE FACTURA DIN PROFORMA
19. ROAFACTURARE - EDITARE PROFORMA

View File

@@ -30,6 +30,10 @@
*!* Validarea si xml2pdfanaf se fac cu serviciul autentificat cu token efactura api.anaf.ro in loc de serviciul neautentificat https://webservicesp.anaf.ro/
*!* serviciul neautentificat nu mai raspundea
*!* 28.07.2026
*!* marius.mutu
*!* vizeFactura: potrivirea cu registrul se face dupa numarul facturii ca grup complet de cifre din xnumar_act (comparat cu nract prin apartenenta, ca sa poata folosi indexul), cu rezerva pe suma egala doar pentru facturile in RON, codul fiscal normalizat pe ambele parti; diferenta ramane goala cand factura nu e in registru sau e in valuta
*********************************
* Se apeleaza din ROACONT > Borderou eFactura
* Intoarce .T. daca descarcarea zip efactura si actualizarea efactura in baza de date s-au realizat cu succes
@@ -2867,10 +2871,10 @@ Define Class ANAFeFactura As Custom
* FACTURI PRIMITE
lcData1 = '01' + PADL(INT(m.gnLuna),2,'0') + ALLTRIM(STR(m.gnAn))
Text To lcSchema Noshow
ales N(1), id N(20), id_fact N(20), data_act D, data_scad D, numar_act C(30), xfurnizor C(200), xclient C(200), id_incarcare C(36), id_descarcare c(36) null, tip_mesaj_raspuns C(50) null,mesaj_raspuns C(250) null, data_raspuns D null, trimis N(1) null, data_trimis T null, cod_fiscal_emitent C(30) null, cod_fiscal_beneficiar C(30) null, detalii M null, total_fara_tva N(16,4), total_tva N(16,4), total_tva_ron N(16,4), total_cu_tva N(16,4), discount_fara_tva N(16,4), taxe_fara_tva N(16,4), valoare_fara_tva N(16,4), total_de_plata N(16,4), nume_valuta C(5), test N(1) null, jtotctva N(16,4), descriere M null, detalii_plata M null, diferenta N(16,4), procesat N(1), tip_persoana N(1) null, descarcat N(1) null, filepath c(250) null, procesat_server N(1) null, creditnote N(1)
ales N(1), id N(20), id_fact N(20), data_act D, data_scad D, numar_act C(30), xfurnizor C(200), xclient C(200), id_incarcare C(36), id_descarcare c(36) null, tip_mesaj_raspuns C(50) null,mesaj_raspuns C(250) null, data_raspuns D null, trimis N(1) null, data_trimis T null, cod_fiscal_emitent C(30) null, cod_fiscal_beneficiar C(30) null, detalii M null, total_fara_tva N(16,4), total_tva N(16,4), total_tva_ron N(16,4), total_cu_tva N(16,4), discount_fara_tva N(16,4), taxe_fara_tva N(16,4), valoare_fara_tva N(16,4), total_de_plata N(16,4), nume_valuta C(5), test N(1) null, jtotctva N(16,4) null, descriere M null, detalii_plata M null, diferenta N(16,4) null, procesat N(1), tip_persoana N(1) null, descarcat N(1) null, filepath c(250) null, procesat_server N(1) null, creditnote N(1)
Endtext
Text To lcSelect Noshow
SELECT 0 as ales, id, id_fact, data_act, data_scad, numar_act, xfurnizor, xclient, id_incarcare, id_descarcare, tip_mesaj_raspuns, mesaj_raspuns, data_raspuns, NVL(trimis,0) as trimis, data_trimis, cod_fiscal_emitent, cod_fiscal_beneficiar, '' as detalii, total_fara_tva, total_tva, total_tva_ron, total_cu_tva, discount_fara_tva, taxe_fara_tva, valoare_fara_tva, total_de_plata, nume_valuta, test, jtotctva, descriere, detalii_plata, decode(creditnote,0,1,-1) * NVL(total_cu_tva, 0.00)-NVL(jtotctva, 0.00) as diferenta, procesat, tip_persoana, descarcat, filepath, procesat_server, creditnote FROM anaf_vefactura_primit
SELECT 0 as ales, id, id_fact, data_act, data_scad, numar_act, xfurnizor, xclient, id_incarcare, id_descarcare, tip_mesaj_raspuns, mesaj_raspuns, data_raspuns, NVL(trimis,0) as trimis, data_trimis, cod_fiscal_emitent, cod_fiscal_beneficiar, '' as detalii, total_fara_tva, total_tva, total_tva_ron, total_cu_tva, discount_fara_tva, taxe_fara_tva, valoare_fara_tva, total_de_plata, nume_valuta, test, jtotctva, descriere, detalii_plata, case when jtotctva is null then null when NVL(nume_valuta,'RON') <> 'RON' then null else decode(creditnote,0,1,-1) * NVL(total_cu_tva, 0.00)-(NVL(jtotctva, 0.00)-NVL(jtva_ti, 0.00)) end as diferenta, procesat, tip_persoana, descarcat, filepath, procesat_server, creditnote FROM anaf_vefactura_primit
Endtext
lcOrder = [data_act,numar_act,data_raspuns]
lcgroup = []
@@ -2887,10 +2891,10 @@ SELECT 0 as ales, id, id_fact, data_act, data_scad, numar_act, xfurnizor, xclien
* FACTURI TRIMISE
Text To lcSchema Noshow
ales N(1), id N(20), id_fact N(20), data_act D, data_scad D, numar_act C(30), xfurnizor C(200), xclient C(200), id_incarcare C(36), id_descarcare c(36) null, mesaj_trimis C(250) null, tip_mesaj_raspuns C(50) null,mesaj_raspuns C(250) null, data_raspuns D null, trimis N(1) null, data_trimis T null, cod_fiscal_emitent C(30) null, cod_fiscal_beneficiar C(30) null, detalii M null, total_fara_tva N(16,4), total_tva N(16,4), total_tva_ron N(16,4), total_cu_tva N(16,4), discount_fara_tva N(16,4), taxe_fara_tva N(16,4), valoare_fara_tva N(16,4), total_de_plata N(16,4), nume_valuta C(5), test N(1) null, jtotctva N(16,4), descriere M null, detalii_plata M null, diferenta N(16,4), procesat N(1), tip_persoana N(1) null, descarcat N(1) null, filepath c(250) null, procesat_server N(1) null, creditnote N(1)
ales N(1), id N(20), id_fact N(20), data_act D, data_scad D, numar_act C(30), xfurnizor C(200), xclient C(200), id_incarcare C(36), id_descarcare c(36) null, mesaj_trimis C(250) null, tip_mesaj_raspuns C(50) null,mesaj_raspuns C(250) null, data_raspuns D null, trimis N(1) null, data_trimis T null, cod_fiscal_emitent C(30) null, cod_fiscal_beneficiar C(30) null, detalii M null, total_fara_tva N(16,4), total_tva N(16,4), total_tva_ron N(16,4), total_cu_tva N(16,4), discount_fara_tva N(16,4), taxe_fara_tva N(16,4), valoare_fara_tva N(16,4), total_de_plata N(16,4), nume_valuta C(5), test N(1) null, jtotctva N(16,4) null, descriere M null, detalii_plata M null, diferenta N(16,4) null, procesat N(1), tip_persoana N(1) null, descarcat N(1) null, filepath c(250) null, procesat_server N(1) null, creditnote N(1)
Endtext
Text To lcSelect Noshow
SELECT 0 as ales, id, id_fact, data_act, data_scad, numar_act, xfurnizor, xclient, id_incarcare, id_descarcare, mesaj_trimis, tip_mesaj_raspuns, mesaj_raspuns, data_raspuns, NVL(trimis,0) as trimis, data_trimis, cod_fiscal_emitent, cod_fiscal_beneficiar, '' as detalii, total_fara_tva, total_tva, total_tva_ron, total_cu_tva, discount_fara_tva, taxe_fara_tva, valoare_fara_tva, total_de_plata, nume_valuta, test, jtotctva, descriere, detalii_plata, decode(creditnote,0,1,-1) * NVL(total_cu_tva, 0.00)-NVL(jtotctva, 0.00) as diferenta, procesat, tip_persoana, descarcat, filepath, procesat_server, creditnote FROM anaf_vefactura_trimis
SELECT 0 as ales, id, id_fact, data_act, data_scad, numar_act, xfurnizor, xclient, id_incarcare, id_descarcare, mesaj_trimis, tip_mesaj_raspuns, mesaj_raspuns, data_raspuns, NVL(trimis,0) as trimis, data_trimis, cod_fiscal_emitent, cod_fiscal_beneficiar, '' as detalii, total_fara_tva, total_tva, total_tva_ron, total_cu_tva, discount_fara_tva, taxe_fara_tva, valoare_fara_tva, total_de_plata, nume_valuta, test, jtotctva, descriere, detalii_plata, case when jtotctva is null then null when NVL(nume_valuta,'RON') <> 'RON' then null else decode(creditnote,0,1,-1) * NVL(total_cu_tva, 0.00)-NVL(jtotctva, 0.00) end as diferenta, procesat, tip_persoana, descarcat, filepath, procesat_server, creditnote FROM anaf_vefactura_trimis
Endtext
lcOrder = [data_act,numar_act,data_trimis,data_raspuns]
lcgroup = []
@@ -2905,12 +2909,13 @@ SELECT 0 as ales, id, id_fact, data_act, data_scad, numar_act, xfurnizor, xclien
Select crsFacturiTrimise
Go Top
*!* diferenta ramane goala cand factura nu e in Registrul de Vanzari, ca la facturile primite/trimise
* FACTURI EMISE
Text To lcSchema Noshow
ales N(1), id N(20), id_fact N(20), id_vanzare N(10), data_act D, numar_act N(14), in_valuta N(1) null, curs N(10,4) null, valval N(16,2), tvaval N(16,2),totval N(16,2), total_fara_tva N(16,2), total_tva N(16,2), total_cu_tva N(16,2), nume_valuta C(5) null, client C(100), id_client N(10), cod_fiscal C(30), tip_persoana N(1) null, trimis N(1) null, data_trimis T null, stare C(100) null, id_incarcare C(36) null, mesaj_trimis C(250) null, id_descarcare c(36) null, tip_mesaj_raspuns C(50) null,mesaj_raspuns C(250) null, data_raspuns D null, cod_fiscal_emitent C(30) null, cod_fiscal_beneficiar C(30) null, detalii M null, xfurnizor C(200), xclient C(200), xdata_act D, xnumar_act C(30), xtotal_fara_tva N(16,4), xtotal_tva N(16,4), xtotal_tva_ron N(16,4), xtotal_cu_tva N(16,4), xdiscount_fara_tva N(16,4), xtaxe_fara_tva N(16,4), xvaloare_fara_tva N(16,4), xtotal_de_plata N(16,4), xnume_valuta C(5), test N(1) null, id_util N(10), utilizator C(100), jtotctva N(16,4), diferenta N(16,4), procesat N(1), procesat_server N(1), creditnote N(1)
ales N(1), id N(20), id_fact N(20), id_vanzare N(10), data_act D, numar_act N(14), in_valuta N(1) null, curs N(10,4) null, valval N(16,2), tvaval N(16,2),totval N(16,2), total_fara_tva N(16,2), total_tva N(16,2), total_cu_tva N(16,2), nume_valuta C(5) null, client C(100), id_client N(10), cod_fiscal C(30), tip_persoana N(1) null, trimis N(1) null, data_trimis T null, stare C(100) null, id_incarcare C(36) null, mesaj_trimis C(250) null, id_descarcare c(36) null, tip_mesaj_raspuns C(50) null,mesaj_raspuns C(250) null, data_raspuns D null, cod_fiscal_emitent C(30) null, cod_fiscal_beneficiar C(30) null, detalii M null, xfurnizor C(200), xclient C(200), xdata_act D, xnumar_act C(30), xtotal_fara_tva N(16,4), xtotal_tva N(16,4), xtotal_tva_ron N(16,4), xtotal_cu_tva N(16,4), xdiscount_fara_tva N(16,4), xtaxe_fara_tva N(16,4), xvaloare_fara_tva N(16,4), xtotal_de_plata N(16,4), xnume_valuta C(5), test N(1) null, id_util N(10), utilizator C(100), jtotctva N(16,4) null, diferenta N(16,4) null, procesat N(1), procesat_server N(1), creditnote N(1)
Endtext
Text To lcSelect Noshow
SELECT 0 as ales, id, id_fact, id_vanzare, data_act, numar_act, in_valuta, curs, valval, tvaval, totval, total_fara_tva, total_tva,total_cu_tva, nume_valuta, client, id_client, cod_fiscal, NVL(tip_persoana,1) as tip_persoana, NVL(trimis,0) as trimis, data_trimis, stare, id_incarcare, mesaj_trimis, id_descarcare, tip_mesaj_raspuns, mesaj_raspuns, data_raspuns, cod_fiscal_emitent, cod_fiscal_beneficiar, '' as detalii, xfurnizor, xclient, xdata_act, xnumar_act, xtotal_fara_tva, xtotal_tva, xtotal_tva_ron, xtotal_cu_tva, xdiscount_fara_tva, xtaxe_fara_tva, xvaloare_fara_tva, xtotal_de_plata, xnume_valuta, test, id_util, utilizator, jtotctva, decode(creditnote,0,1,-1) * ROUND(NVL(xtotal_cu_tva , 0.00) * decode(in_valuta,1,curs,1), 2)-NVL(jtotctva, 0.00) as diferenta, procesat, procesat_server,creditnote FROM anaf_vefactura_emis
SELECT 0 as ales, id, id_fact, id_vanzare, data_act, numar_act, in_valuta, curs, valval, tvaval, totval, total_fara_tva, total_tva,total_cu_tva, nume_valuta, client, id_client, cod_fiscal, NVL(tip_persoana,1) as tip_persoana, NVL(trimis,0) as trimis, data_trimis, stare, id_incarcare, mesaj_trimis, id_descarcare, tip_mesaj_raspuns, mesaj_raspuns, data_raspuns, cod_fiscal_emitent, cod_fiscal_beneficiar, '' as detalii, xfurnizor, xclient, xdata_act, xnumar_act, xtotal_fara_tva, xtotal_tva, xtotal_tva_ron, xtotal_cu_tva, xdiscount_fara_tva, xtaxe_fara_tva, xvaloare_fara_tva, xtotal_de_plata, xnume_valuta, test, id_util, utilizator, jtotctva, case when jtotctva is null then null else decode(creditnote,0,1,-1) * ROUND(NVL(xtotal_cu_tva , 0.00) * decode(in_valuta,1,curs,1), 2)-NVL(jtotctva, 0.00) end as diferenta, procesat, procesat_server,creditnote FROM anaf_vefactura_emis
Endtext
lcOrder = [data_act,numar_act]
lcgroup = []

View File

@@ -207,8 +207,18 @@ ENDIF
Endif
.cIdColumn = lcIdColumn
Endwith
If Type('poVerifAlegere') = 'O' And !Isnull(poVerifAlegere)
AddProperty(oForm_cautare, 'oVerifAlegere', poVerifAlegere)
poVerifAlegere.Activeaza(oForm_cautare)
Endif
oForm_cautare.Show()
If Type('poVerifAlegere') = 'O' And !Isnull(poVerifAlegere)
poVerifAlegere.Dezactiveaza()
Endif
*!* modificare 30.11.2006
If Type("lorec") = "O"
poRec = lorec

View File

@@ -3,6 +3,12 @@
*!* 13.08.2024
*!* vizImportEFactura + discountfaratva
*!* 28.07.2026
*!* marius.mutu
*!* borderoul eFactura, facturi primite: diferenta ignora TVA-ul de taxare inversa (coloana
*!* jtva_ti din view-ul anaf_vefactura_primit), ca sa nu mai apara colorate fals facturile
*!* cu 4426=4427
Procedure importEfacturaPrimite
DO vizImportEFactura WITH 'PRIMITE'
ENDPROC
@@ -17,7 +23,7 @@ PROCEDURE vizImportEFactura
Private poFacturi, poFacturiDetalii
Local loFrmFacturi As "frm_efactura_import", lcTip, llPrimite
Local lcData1, lcFiltru, lcFiltruOriginal, lcOrder, lcSchema, lcgroup, llAfiseaza, llModParam
Local lcData1, lcData2, lcFiltru, lcFiltruOriginal, lcOrder, lcSchema, lcgroup, ldData1, llAfiseaza, llModParam
poFacturi = Null
poFacturiDetalii = Null
@@ -25,15 +31,19 @@ PROCEDURE vizImportEFactura
llPrimite = (m.lcTip = 'PRIMITE')
lcTabel = IIF(m.lcTip = 'PRIMITE', 'anaf_vefactura_primit', 'anaf_vefactura_trimis')
* FACTURI PRIMITE/TRIMISE
lcData1 = '01' + Padl(Int(m.gnLuna),2,'0') + Alltrim(Str(m.gnAn))
*!* data_act pe interval (nu extract(year/month...)) ca sa poata folosi IDX_ANAF_EFACTURA_1(FACTURA_EMISA,XDATA_ACT,DATA_RASPUNS)
ldData1 = GOMONTH(DATE(m.gnAn, m.gnLuna, 1), 1)
lcData2 = '01' + PADL(MONTH(m.ldData1),2,'0') + ALLTRIM(STR(YEAR(m.ldData1)))
TEXT To lcSchema Noshow
ales N(1), id N(20), id_fact N(20), data_act D, data_scad D, numar_act C(30), xfurnizor C(200), xclient C(200), partener C(200), id_incarcare C(36), id_descarcare c(36) null, tip_mesaj_raspuns C(50) null,mesaj_raspuns C(250) null, data_raspuns D null, trimis N(1) null, data_trimis T null, cod_fiscal C(30) null, cod_fiscal_emitent C(30) null, cod_fiscal_beneficiar C(30) null, detalii M null, total_fara_tva N(16,4), total_tva N(16,4), total_tva_ron N(16,4), total_cu_tva N(16,4), discount_fara_tva N(16,4), taxe_fara_tva N(16,4), valoare_fara_tva N(16,4), total_de_plata N(16,4), nume_valuta C(5), test N(1) null, jtotctva N(16,4), descriere M null, detalii_plata M null, diferenta N(16,4), procesat N(1), SerieActRoa V(10) Null, NrActRoa N(14) Null, IdPartRoa N(10) Null, PartenerRoa V(100) null, codFiscalROA V(20), idValutaROA N(5) null,numeValutaROA V(5) null, cursROA N(16,6) null,Cont c(4) Null,ACont c(4) Null,TVAIncasare N(1),Fdoc V(20) null,Id_Fdoc N(5) Null,Nrord V(100) null,Id_Lucrare I Null,Contract V(100) Null,Id_Ctr I Null,Sectie V(100) null,Id_Sectie I Null,dst_chlt V(100) null, Id_venchelt I NUll, nresp V(100) null, Id_responsabil I NUll , completat N(1), completatdet N(1), creditnote N(1), explicatiaROA V(100) null
ales N(1), id N(20), id_fact N(20), data_act D, data_scad D, numar_act C(30), xfurnizor C(200), xclient C(200), partener C(200), id_incarcare C(36), id_descarcare c(36) null, tip_mesaj_raspuns C(50) null,mesaj_raspuns C(250) null, data_raspuns D null, trimis N(1) null, data_trimis T null, cod_fiscal C(30) null, cod_fiscal_emitent C(30) null, cod_fiscal_beneficiar C(30) null, detalii M null, total_fara_tva N(16,4), total_tva N(16,4), total_tva_ron N(16,4), total_cu_tva N(16,4), discount_fara_tva N(16,4), taxe_fara_tva N(16,4), valoare_fara_tva N(16,4), total_de_plata N(16,4), nume_valuta C(5), test N(1) null, jtotctva N(16,4) null, descriere M null, detalii_plata M null, diferenta N(16,4) null, procesat N(1), SerieActRoa V(10) Null, NrActRoa N(14) Null, IdPartRoa N(10) Null, PartenerRoa V(100) null, codFiscalROA V(20), idValutaROA N(5) null,numeValutaROA V(5) null, cursROA N(16,6) null,Cont c(4) Null,ACont c(4) Null,TVAIncasare N(1),Fdoc V(20) null,Id_Fdoc N(5) Null,Nrord V(100) null,Id_Lucrare I Null,Contract V(100) Null,Id_Ctr I Null,Sectie V(100) null,Id_Sectie I Null,dst_chlt V(100) null, Id_venchelt I NUll, nresp V(100) null, Id_responsabil I NUll , completat N(1), completatdet N(1), creditnote N(1), explicatiaROA V(100) null
ENDTEXT
*!* diferenta ramane goala cand factura nu e in Registrul TVA sau e in valuta si tine cont de semnul notei de credit, ca la borderou
TEXT To lcSelect TEXTMERGE Noshow
SELECT 0 as ales, id, id_fact, data_act, data_scad, numar_act, xfurnizor, xclient, partener, id_incarcare, id_descarcare, tip_mesaj_raspuns, mesaj_raspuns, data_raspuns, NVL(trimis,0) as trimis, data_trimis, cod_fiscal, cod_fiscal_emitent, cod_fiscal_beneficiar, '' as detalii, total_fara_tva, total_tva, total_tva_ron, total_cu_tva, discount_fara_tva, taxe_fara_tva, valoare_fara_tva, total_de_plata, nume_valuta, test, jtotctva, descriere, detalii_plata, NVL(total_cu_tva, 0.00)-NVL(jtotctva, 0.00) as diferenta, procesat,
SELECT 0 as ales, id, id_fact, data_act, data_scad, numar_act, xfurnizor, xclient, partener, id_incarcare, id_descarcare, tip_mesaj_raspuns, mesaj_raspuns, data_raspuns, NVL(trimis,0) as trimis, data_trimis, cod_fiscal, cod_fiscal_emitent, cod_fiscal_beneficiar, '' as detalii, total_fara_tva, total_tva, total_tva_ron, total_cu_tva, discount_fara_tva, taxe_fara_tva, valoare_fara_tva, total_de_plata, nume_valuta, test, jtotctva, descriere, detalii_plata, case when jtotctva is null then null when NVL(nume_valuta,'RON') <> 'RON' then null else decode(creditnote,0,1,-1) * NVL(total_cu_tva,0.00) - (NVL(jtotctva,0.00) - NVL(jtva_ti,0.00)) end as diferenta, procesat,
'' as SerieActRoa, CAST(null as Number(14)) as NrActRoa, CAST(null as Number(20)) as idPartRoa, '' as PartenerRoa, '' as codFiscalROA, CAST(null as Number(10)) as idValutaROA, '' as numeValutaROA, CAST(null as Number(16,6)) as cursROA,
'' as Cont, '' as acont, 0 as TVAIncasare, '' as Fdoc, CAST(0 as Number(5)) as Id_Fdoc, '' as Nrord, CAST(0 as Number(10)) as id_Lucrare, '' as Contract, CAST(null as Number(10)) as id_ctr,
'' Sectie, CAST(0 as Number(10)) as id_Sectie, '' as dst_chlt, CAST(0 as Number(10)) as id_Venchelt, '' as nresp, CAST(0 as Number(10)) as id_responsabil, 0 as completat, 0 as completatdet, creditnote, '' as explicatiaROA
@@ -42,7 +52,7 @@ SELECT 0 as ales, id, id_fact, data_act, data_scad, numar_act, xfurnizor, xclien
lcOrder = [data_act,numar_act,data_raspuns]
lcgroup = []
lcFiltru = [(extract(year from data_act) = ?gnAn and extract(month from data_act) = ?gnLuna) or (data_act is null and data_raspuns >= to_date('] + m.lcData1 + [','ddmmyyyy'))]
lcFiltru = [(data_act >= to_date('] + m.lcData1 + [','ddmmyyyy') and data_act < to_date('] + m.lcData2 + [','ddmmyyyy')) or (data_act is null and data_raspuns >= to_date('] + m.lcData1 + [','ddmmyyyy'))]
lcFiltruOriginal = []
llModParam = .T.
llAfiseaza = .F.

File diff suppressed because it is too large Load Diff

View File

@@ -261,6 +261,7 @@ Define Class oDateFactura As Custom
If INLIST(m.tnTip, 2, 6, 52) And Type('goContract') <> 'U' && FACTURARE DIN ROACONTRACTE
.id_client = goContract.id_part
.nume_client = goContract.denumire
.cod_fiscal = ALLTRIM(NVL(goContract.cod_fiscal, ''))
.listaid = goContract.id_ctr
.descriere = goContract.contract
.id_sectie = goContract.id_sectie

View File

@@ -0,0 +1,296 @@
*** ofacturare_editare
*!* 08.08.2026
*!* marius.mutu
*!* helpere comune pentru editarea unei facturi emise: garda eFactura, cursoarele notei si ale rulajelor,
*!* randul de vanzare corespunzator notei si liniile de articole pentru pagina de articole factura
*!* parametru: id_fact
*!* verifica daca factura cu id_fact dat a fost deja trimisa in eFactura (anaf_efactura)
FUNCTION EsteInEFactura
LPARAMETERS tnIdFact
LOCAL lcSql, lnEFactura, llSucces
lnEFactura = 0
lcSql = [select count(*) as lneFactura from anaf_efactura where id_fact = ] + Alltrim(Str(Nvl(m.tnIdFact,0)))
llSucces = goExecutor.oSelecteaza2Value(m.lcSql, @lnEFactura)
RETURN (Nvl(m.lnEFactura,0) > 0)
ENDFUNC && EsteInEFactura
*!* parametri: cod, an, luna, arata si randurile sterse (implicit .F.)
*!* incarca cursoarele notei (tact) si ale rulajelor (trul, trul_obinv), cu recalculul de
*!* valoare/valtva/valoarev/valtvav pe randurile goale; raman deschise READWRITE pe seama apelantului
*!* pe eroare Oracle intoarce .F. si inchide ce a deschis pana atunci
FUNCTION IncarcaCursoareModificareNota
LPARAMETERS tnCod, tnAn, tnLuna, tlAratasterse
LOCAL lcConditieSters, lcSql, lcCursor, lnSucces
IF Used('actactan')
Use In actactan
ENDIF
IF Used('tact')
Use In tact
ENDIF
IF Used('rul_temp')
Use In rul_temp
ENDIF
IF Used('trul')
Use In trul
ENDIF
IF Used('rul_temp_obinv')
Use In rul_temp_obinv
ENDIF
IF Used('trul_obinv')
Use In trul_obinv
ENDIF
lcConditieSters = IIF(m.tlAratasterse, [ ], [ STERS = 0 AND ])
lcSql = [select * from vact_tot where ] + lcConditieSters + [ an = ] + Transform(m.tnAn) + [ and luna = ] + Transform(m.tnLuna) + [ and cod = ] + Alltrim(Str(m.tnCod)) + [ order by id_act]
lcCursor = [v_act]
lnSucces = goExecutor.oExecute(lcSql,lcCursor)
goExecutor.oReset()
IF lnSucces < 0
AMESSAGEBOX(goExecutor.cEroare,0+16,"Eroare")
RETURN .F.
ENDIF
SELECT * FROM v_act INTO CURSOR actactan
SELECT .F. AS ales, T.*, CAST(0 AS N(2)) AS tipnota FROM actactan T INTO CURSOR tact READWRITE
USE IN v_act
IF lnSucces > 0
lcSql = [select * from vrul_tot where ] + lcConditieSters + [ an = ] + Transform(m.tnAn) + [ and luna = ] + Transform(m.tnLuna) + [ and cod = ] + Alltrim(Str(m.tnCod)) + [ order by id_rul]
lcCursor = [v_rul]
lnSucces = goExecutor.oExecute(lcSql,lcCursor)
goExecutor.oReset()
IF lnSucces < 0
AMESSAGEBOX(goExecutor.cEroare,0+16,"Eroare")
IF Used('actactan')
Use In actactan
ENDIF
IF Used('tact')
Use In tact
ENDIF
RETURN .F.
ENDIF
IF lnSucces > 0
UPDATE v_rul SET valoare = ROUND(IIF(cant<>0, cant, cante)*pret,m.gnPC) WHERE EMPTY(NVL(valoare,0))
UPDATE v_rul SET valtva = ROUND(IIF(cant<>0, cant, cante)*pret * (IIF(!EMPTY(NVL(proc_tva,0)), proc_tva, 1)-1), m.gnPC) WHERE EMPTY(NVL(valtva,0))
UPDATE v_rul SET valoarev = ROUND(IIF(cant<>0, cant, cante)*pretv,m.gnPC) WHERE EMPTY(NVL(valoarev,0))
UPDATE v_rul SET valtvav = ROUND(IIF(cant<>0, cant, cante)*pretv * (IIF(!EMPTY(NVL(proc_tvav,0)), proc_tvav, 1)-1), m.gnPC) WHERE EMPTY(NVL(valtvav,0))
SELECT *, ;
valoare + valtva AS valoarectva, ;
valoarev + valtvav AS valoarevctva ;
FROM v_rul ;
INTO CURSOR RUL_TEMP READWRITE
SELECT * FROM RUL_TEMP INTO CURSOR trul READWRITE
USE IN v_rul
lcSql = [select * from vrul_obinv_tot where ] + lcConditieSters + [ an = ] + Transform(m.tnAn) + [ and luna = ] + Transform(m.tnLuna) + [ and cod = ] + Alltrim(Str(m.tnCod)) + [ order by id_rul_obinv]
lcCursor = [v_rul_obinv]
lnSucces = goExecutor.oExecute(lcSql,lcCursor)
goExecutor.oReset()
IF lnSucces < 0
AMESSAGEBOX(goExecutor.cEroare,0+16,"Eroare")
IF Used('actactan')
Use In actactan
ENDIF
IF Used('tact')
Use In tact
ENDIF
IF Used('rul_temp')
Use In rul_temp
ENDIF
IF Used('trul')
Use In trul
ENDIF
RETURN .F.
ENDIF
ENDIF
IF lnSucces > 0
UPDATE v_rul_obinv SET valoare = ROUND(IIF(cant<>0, cant, cante)*pret,m.gnPC) WHERE EMPTY(NVL(valoare,0))
UPDATE v_rul_obinv SET valtva = ROUND(IIF(cant<>0, cant, cante)*pret * (IIF(!EMPTY(NVL(proc_tva,0)), proc_tva, 1)-1), m.gnPC) WHERE EMPTY(NVL(valtva,0))
UPDATE v_rul_obinv SET valoarev = ROUND(IIF(cant<>0, cant, cante)*pretv,m.gnPC) WHERE EMPTY(NVL(valoarev,0))
UPDATE v_rul_obinv SET valtvav = ROUND(IIF(cant<>0, cant, cante)*pretv * (IIF(!EMPTY(NVL(proc_tvav,0)), proc_tvav, 1)-1), m.gnPC) WHERE EMPTY(NVL(valtvav,0))
SELECT *, ;
valoare + valtva AS valoarectva, ;
valoarev + valtvav AS valoarevctva ;
FROM v_rul_obinv ;
INTO CURSOR RUL_TEMP_OBINV READWRITE
SELECT * FROM RUL_TEMP_OBINV INTO CURSOR trul_obinv READWRITE
USE IN v_rul_obinv
ENDIF
ENDIF
RETURN .T.
ENDFUNC && IncarcaCursoareModificareNota
*!* creeaza cursorul tvanz gol (structura VANZARI redusa) - fallback la eroare Oracle sau cod/data lipsa
FUNCTION CreeazaCursorTvanzGol
IF Used('tvanz')
Use In tvanz
ENDIF
CREATE CURSOR tvanz (id_vanzare I, tip I, discount N(12,2), total_fara_tva N(14,2), total_tva N(14,2), total_cu_tva N(14,2))
ENDFUNC && CreeazaCursorTvanzGol
*!* parametri: cod, nract, serie_act, dataact (din cursorul notei, ex. tact)
*!* incarca in tvanz randul din VANZARI al notei; cod singur nu e unic, de aceea filtrul cere tot setul
*!* tvanz ramane deschis READWRITE, cu 0 randuri daca nu s-a gasit sau la eroare Oracle
FUNCTION IncarcaVanzareNota
LPARAMETERS tnCod, tnNract, tcSerieAct, tdDataAct
LOCAL lcSql, lnSucces, lcSerieAct
IF Used('v_vanz')
Use In v_vanz
ENDIF
IF Empty(m.tnCod) OR Empty(m.tdDataAct)
CreeazaCursorTvanzGol()
RETURN .T.
ENDIF
lcSerieAct = Alltrim(Nvl(m.tcSerieAct,""))
lcSql = [select id_vanzare, tip, discount, total_fara_tva, total_tva, total_cu_tva from vanzari where cod = ] + Transform(m.tnCod) + ;
[ and Nvl(numar_act,-1) = ] + Transform(Nvl(m.tnNract,-1)) + ;
[ and Nvl(serie_act,'') = '] + m.lcSerieAct + [' and trunc(data_act) = to_date('] + Dtoc(m.tdDataAct,1) + [','YYYYMMDD') and sters = 0]
lnSucces = goExecutor.oExecute(lcSql,[v_vanz])
goExecutor.oReset()
IF lnSucces < 0
AMESSAGEBOX(goExecutor.cEroare,0+16,"Eroare")
CreeazaCursorTvanzGol()
RETURN .T.
ENDIF
IF Used('tvanz')
Use In tvanz
ENDIF
SELECT * FROM v_vanz INTO CURSOR tvanz READWRITE
USE IN v_vanz
RETURN .T.
ENDFUNC && IncarcaVanzareNota
*!* parametru: alias cu randurile notei (tact), cu campurile cod/nract/serie_act/dataact/sters
*!* incearca toate combinatiile distincte (cod, nract, serie_act, dataact) din alias (sters=0) pana
*!* gaseste un rand in VANZARI; lasa workarea si pozitia curenta neschimbate, .F. cu tvanz gol daca nu gaseste
FUNCTION IncarcaVanzareDinNota
LPARAMETERS tcAliasAct
LOCAL lnAreaOrigine, lnRecnoOrigine, llGasit
lnAreaOrigine = Select()
llGasit = .F.
IF Empty(m.tcAliasAct) OR !Used(m.tcAliasAct) OR Reccount(m.tcAliasAct) = 0
CreeazaCursorTvanzGol()
IF m.lnAreaOrigine > 0
SELECT (m.lnAreaOrigine)
ENDIF
RETURN .F.
ENDIF
lnRecnoOrigine = Recno(m.tcAliasAct)
IF Used('tmp_triplete_pozvanz')
Use In tmp_triplete_pozvanz
ENDIF
*!* cod se ia tot din cursor, nu de pe randul curent - acesta poate fi la EOF dupa CalculeazaTotal
SELECT DISTINCT cod, nract, serie_act, dataact FROM (m.tcAliasAct) WHERE sters = 0 INTO CURSOR tmp_triplete_pozvanz READWRITE
SELECT tmp_triplete_pozvanz
SCAN
IncarcaVanzareNota(cod, nract, serie_act, dataact)
IF Reccount('tvanz') = 1
llGasit = .T.
EXIT
ENDIF
ENDSCAN
IF Used('tmp_triplete_pozvanz')
Use In tmp_triplete_pozvanz
ENDIF
IF !m.llGasit
CreeazaCursorTvanzGol()
ENDIF
IF Used(m.tcAliasAct)
IF m.lnRecnoOrigine > 0 AND m.lnRecnoOrigine <= Reccount(m.tcAliasAct)
Go (m.lnRecnoOrigine) In (m.tcAliasAct)
ELSE
*!* pozitia initiala era EOF (Recno() peste Reccount()) - se restaureaza tot la EOF
Go Bottom In (m.tcAliasAct)
Skip In (m.tcAliasAct)
ENDIF
ENDIF
IF m.lnAreaOrigine > 0
SELECT (m.lnAreaOrigine)
ENDIF
RETURN m.llGasit
ENDFUNC && IncarcaVanzareDinNota
*!* creeaza cursorul tvd gol, cu structura view-ului VVANZARI_ARTICOLE
FUNCTION CreeazaCursorTvdGol
IF Used('tvd')
Use In tvd
ENDIF
CREATE CURSOR tvd (id_vanzare I, id_vanzare_det I, id_articol I, cantitate N(12,3), pret N(14,4), pret_cu_tva N(14,4), proc_tvav N(6,4), ;
discount_unitar N(14,4), id_gestiune I, cont C(20), id_valuta I, id_jtva_coloana I, serie C(20), explicatie C(60), ;
taxcode I, lot C(20), sters I, denumire C(100), codmat C(30), nume_gestiune C(60), nume_val C(20))
ENDFUNC && CreeazaCursorTvdGol
*!* parametru: id_vanzare
*!* incarca in tvd liniile active (sters=0) ale vanzarii, din VVANZARI_ARTICOLE
*!* tvd ramane deschis READWRITE, cu 0 randuri la eroare Oracle
FUNCTION IncarcaArticoleFactura
LPARAMETERS tnIdVanzare
LOCAL lcSql, lnSucces
IF Used('v_vd')
Use In v_vd
ENDIF
lcSql = [select * from vvanzari_articole where id_vanzare = ] + Transform(Nvl(m.tnIdVanzare,0)) + [ and sters = 0 order by id_vanzare_det]
lnSucces = goExecutor.oExecute(lcSql,[v_vd])
goExecutor.oReset()
IF lnSucces < 0
AMESSAGEBOX(goExecutor.cEroare,0+16,"Eroare")
CreeazaCursorTvdGol()
RETURN .T.
ENDIF
IF Used('tvd')
Use In tvd
ENDIF
SELECT * FROM v_vd INTO CURSOR tvd READWRITE
USE IN v_vd
RETURN .T.
ENDFUNC && IncarcaArticoleFactura

View File

@@ -80,6 +80,13 @@
*!* In xsets s-a modificat 21% de la 01.08.2025
*!* 28.07.2026
*!* marius.mutu
*!* achizitie_import - blocul de TVA din DVI poate avea valuta si curs proprii, diferite de ale
*!* facturii (inclusiv fara valuta), iar factura poate avea discount financiar; cursorul introdc
*!* primeste coloanele rand_dvi si valuta_proprie.
#Define CRLF Chr(13) + Chr(10)
********* INCEPUT: lans_Nir_Bon ***********
@@ -1557,8 +1564,8 @@ Procedure achizitie_import
poAct.id_valuta As id_valuta, poAct.Curs As Curs, poAct.nume_val As nume_val, poAct.dataact as dataact, poAct.fdoc as fdoc, poAct.id_fdoc as id_fdoc, 0 as se_scrie, poAct.tva_incasare as tva_incasare, ;
16777215 As doc_color, Space(10) As doc_label, ;
'B' As tip_rand, Space(80) As doc_key, 00000000 As nr_doc, ;
00000000000000.0000 As suma_doc, 00000000000000.0000 As suma_doc_val, 0 As mod_manual, ;
Space(20) As scd_orig, Space(20) As ascd_orig ;
00000000000000.0000 As suma_doc, 00000000000000.0000 As suma_doc_val, 0 As mod_manual, 0 As expl_manual, ;
Space(20) As scd_orig, Space(20) As ascd_orig, 0 As rand_dvi, 0 As valuta_proprie ;
FROM cnote_contabile N ;
WHERE N.id_set = poAct.id_set ;
INTO Cursor introdc Readwrite Order By ordine
@@ -1615,7 +1622,7 @@ Procedure achizitie_import
*!* 16.07.2026 claude - F1: index unic de sortare pe introdc, o singura data, inainte de Show
*!* (niciodata re-INDEX ulterior sub grid - vezi docs/propuneri_import_unificat.md)
SELECT introdc
INDEX ON Str(Nvl(nr_doc,0),8) + Icase(tip_rand='B','1', tip_rand='S','2', tip_rand='T','3', tip_rand='D','4', '5') + Padr(Nvl(scd,''),10) TAG ord_doc
INDEX ON Str(Nvl(nr_doc,0),8) + Icase(tip_rand='B','1', tip_rand='S','2', tip_rand='G','3', tip_rand='T','4', tip_rand='D','5', '6') + Padr(Nvl(scd,''),10) TAG ord_doc
SET ORDER TO ord_doc
SELECT introdc

View File

@@ -1,129 +0,0 @@
* ointroduceri_efactura.prg
Procedure importEfacturaPrimite
DO vizImportEFactura WITH 'PRIMITE'
ENDPROC
PROCEDURE importEfacturaTrimise
DO vizImportEFactura WITH 'TRIMISE'
ENDPROC
PROCEDURE vizImportEFactura
LPARAMETERS tcTip
* tcTIP: PRIMITE/TRIMISE
Private poFacturi, poFacturiDetalii
Local loFrmFacturi As "frm_efactura_import", lcTip, llPrimite
Local lcData1, lcFiltru, lcFiltruOriginal, lcOrder, lcSchema, lcgroup, llAfiseaza, llModParam
poFacturi = Null
poFacturiDetalii = Null
lcTip = IIF(TYPE('tcTip') = 'C' and !EMPTY(m.tcTip), UPPER(ALLTRIM(m.tcTip)), 'PRIMITE')
llPrimite = (m.lcTip = 'PRIMITE')
lcTabel = IIF(m.lcTip = 'PRIMITE', 'anaf_vefactura_primit', 'anaf_vefactura_trimis')
* FACTURI PRIMITE/TRIMISE
lcData1 = '01' + Padl(Int(m.gnLuna),2,'0') + Alltrim(Str(m.gnAn))
TEXT To lcSchema Noshow
ales N(1), id N(20), id_fact N(20), data_act D, data_scad D, numar_act C(30), xfurnizor C(200), xclient C(200), partener C(200), id_incarcare C(36), id_descarcare c(36) null, tip_mesaj_raspuns C(50) null,mesaj_raspuns C(250) null, data_raspuns D null, trimis N(1) null, data_trimis T null, cod_fiscal C(30) null, cod_fiscal_emitent C(30) null, cod_fiscal_beneficiar C(30) null, detalii M null, total_fara_tva N(16,4), total_tva N(16,4), total_cu_tva N(16,4), discount_fara_tva N(16,4), taxe_fara_tva N(16,4), valoare_fara_tva N(16,4), total_de_plata N(16,4), nume_valuta C(5), test N(1) null, jtotctva N(16,4), descriere M null, detalii_plata M null, diferenta N(16,4), procesat N(1)
ENDTEXT
TEXT To lcSelect TEXTMERGE Noshow
SELECT 0 as ales, id, id_fact, data_act, data_scad, numar_act, xfurnizor, xclient, partener, id_incarcare, id_descarcare, tip_mesaj_raspuns, mesaj_raspuns, data_raspuns, NVL(trimis,0) as trimis, data_trimis, cod_fiscal, cod_fiscal_emitent, cod_fiscal_beneficiar, detalii, total_fara_tva, total_tva, total_cu_tva, discount_fara_tva, taxe_fara_tva, valoare_fara_tva, total_de_plata, nume_valuta, test, jtotctva, descriere, detalii_plata, NVL(total_cu_tva, 0.00)-NVL(jtotctva, 0.00) as diferenta, procesat FROM <<m.lcTabel>>
ENDTEXT
lcOrder = [data_act,numar_act,data_raspuns]
lcgroup = []
lcFiltru = [(extract(year from data_act) = ?gnAn and extract(month from data_act) = ?gnLuna) or (data_act is null and data_raspuns >= to_date('] + m.lcData1 + [','ddmmyyyy'))]
lcFiltruOriginal = []
llModParam = .T.
llAfiseaza = .F.
gencursor('poFacturi', 'crsFacturi', lcSelect, lcFiltru, lcSchema, lcOrder, llAfiseaza, lcgroup, llModParam, lcFiltruOriginal)
poFacturi.ca_baza1.afisare()
Select crsFacturi
Go Top
* DETALII FACTURI PRIMITE/TRIMISE/EMISE
TEXT To lcSchema Noshow
id_tip N(10) null, cont c(4) null, id_articol N(20) null, id_gestiune N(20) null, id N(20), id_efactura N(20), nr N(5), articol V(250), descriere V(250), detalii M, cantitate N(18,6), um V(20), um_iso V(50), id_um I, um_roa V(50), pret N(20,6), proctva N(7,2), valoarefaratva N(20,6), in_stoc N(1), articol_roa V(250)
ENDTEXT
TEXT To lcSelect Noshow
select CAST(0 as number(10)) as id_tip, CAST('' as Varchar2(4)) as cont, CAST(null as Number(20)) as id_articol, CAST(null as Number(20)) as id_gestiune, id, id_efactura, nr, articol, descriere, detalii, cantitate, um, um_iso, id_um, um_roa, pret, proctva, valoarefaratva, 0 as in_stoc, CAST('' as Varchar2(250)) as articol_roa from anaf_vefactura_detalii
ENDTEXT
lcOrder = [nr]
lcgroup = []
lcFiltru = [1=2] && IIF(!EMPTY(NVL(crsFacturiPrimite.id,0)), [id_efactura=] + ALLTRIM(STR(crsFacturiPrimite.id)), [1=2])
lcFiltruOriginal = []
llModParam = .T.
llAfiseaza = .F.
gencursor('poFacturiDetalii', 'crsDetaliiFacturi', lcSelect, lcFiltru, lcSchema, lcOrder, llAfiseaza, lcgroup, llModParam, lcFiltruOriginal)
poFacturiDetalii.ca_baza1.afisare()
* Cursoare helper
CREATE CURSOR cTip (id I, in_stoc N(1), tip V(50), cont V(4))
INSERT INTO cTip (tip, cont, in_stoc) VALUES ('Nedefinit','', 0)
INSERT INTO cTip (tip, cont, in_stoc) VALUES ('Ch. mat. nestoc.','604', 0)
INSERT INTO cTip (tip, cont, in_stoc) VALUES ('Ch. Energie','6051', 0)
INSERT INTO cTip (tip, cont, in_stoc) VALUES ('Ch. Apa','6052', 0)
INSERT INTO cTip (tip, cont, in_stoc) VALUES ('Ch. Gaze','6053', 0)
INSERT INTO cTip (tip, cont, in_stoc) VALUES ('Ch. chirii','6123', 0)
INSERT INTO cTip (tip, cont, in_stoc) VALUES ('Ch. colaboratori','621', 0)
INSERT INTO cTip (tip, cont, in_stoc) VALUES ('Ch. comisioane','622', 0)
INSERT INTO cTip (tip, cont, in_stoc) VALUES ('Ch. protocol','623', 0)
INSERT INTO cTip (tip, cont, in_stoc) VALUES ('Ch. transp. bunuri/pers.','624', 0)
INSERT INTO cTip (tip, cont, in_stoc) VALUES ('Ch. deplasari','625', 0)
INSERT INTO cTip (tip, cont, in_stoc) VALUES ('Ch. posta/telecom.','626', 0)
INSERT INTO cTip (tip, cont, in_stoc) VALUES ('Ch. terti','628', 0)
INSERT INTO cTip (tip, cont, in_stoc) VALUES ('Altele','461', 0)
INSERT INTO cTip (tip, cont, in_stoc) VALUES ('-----------------','', 0)
INSERT INTO cTip (tip, cont, in_stoc) VALUES ('Marfuri','371', 1)
INSERT INTO cTip (tip, cont, in_stoc) VALUES ('Materii prime','301', 1)
INSERT INTO cTip (tip, cont, in_stoc) VALUES ('Materiale auxiliare','3021', 1)
INSERT INTO cTip (tip, cont, in_stoc) VALUES ('Ambalaje','381', 1)
INSERT INTO cTip (tip, cont, in_stoc) VALUES ('Obiecte de inventar','303', 1)
INSERT INTO cTip (tip, cont, in_stoc) VALUES ('Amenajari provizorii','323', 1)
INSERT INTO cTip (tip, cont, in_stoc) VALUES ('Mat. spre prelucrare','8032', 1)
INSERT INTO cTip (tip, cont, in_stoc) VALUES ('Mat. in pastrare/consig.','8033', 1)
INSERT INTO cTip (tip, cont, in_stoc) VALUES ('Discount financiar','767', 1)
INSERT INTO cTip (tip, cont, in_stoc) VALUES ('Combustibili','3022', 1)
INSERT INTO cTip (tip, cont, in_stoc) VALUES ('Piese de schimb','3024', 1)
INSERT INTO cTip (tip, cont, in_stoc) VALUES ('Alte mat. consumabile','3028', 1)
INSERT INTO cTip (tip, cont, in_stoc) VALUES ('Discount comercial','609', 1)
INSERT INTO cTip (tip, cont, in_stoc) VALUES ('Ambalaje SGR','461', 0)
REPLACE ALL id WITH RECNO()-1 IN cTip
GO TOP IN cTip
INDEX on id TAG id
*!* llSucces = goExecutor.oExecuta("select id_articol, denumire, codmat from vnom_articole where inactiv = 0", 'cArticole')
*!* SELECT cArticole
*!* INDEX on id_articol TAG id_articol
llSucces = goExecutor.oExecuta([select distinct nume_gestiune,cgest,id_gestiune,nr_pag,cont from vgest_gestiuni_util where inactiv = 0 and id_util = ] + Alltrim(Str(m.gnIdUtil)), 'cGestiuni')
SELECT cGestiuni
INDEX on id_gestiune TAG id_gest
llSucces = goExecutor.oExecuta("select cod_um_iso, um_iso from syn_vnom_um_iso", 'cUMISO')
SELECT cUMISO
INDEX on cod_um_iso TAG cod_um_iso
llSucces = goExecutor.oExecuta("select id, um, cod_um_iso, um_iso from vnom_um", 'cUM')
SELECT cUM
INDEX on id TAG id
Select crsFacturi
loFrmFacturi = Createobject("frm_import_efactura", m.llPrimite)
* Do Form anaf_efactura Name loFrmBorderou Linked With this Noshow
loFrmFacturi.Show(1)
Use In (Select('crsFacturi'))
Use In (Select('crsDetaliiFacturi'))
Use In (Select('cTip'))
Use In (Select('cArticole'))
Use In (Select('cGestiuni'))
Endproc && vizFacturiPrimite

View File

@@ -397,7 +397,7 @@ Function verific_partener
ll_l=.F.
If Empty(tcCont) Or Type('tccont')#'C'
If Type('tccont')#'C' Or Empty(Nvl(tcCont,''))
Return ll_l
Else
lcCont = Alltrim(tcCont)
@@ -439,7 +439,7 @@ Function verific_partener
llNou = .T.
*!* modificare 10.12.2010
loCauta = CautPartenerContabilitate(GetHash([cTitlu=>] + Alltrim(lcTitlu)+[??cCont=>] + Alltrim(lcCont) + [??] + ;
[lAdaugCorespondente=>1]))
[lAdaugCorespondente=>1??lVerificaANAF=>1]))
*!* locauta = caut_parteneri(lcCont, lcTitlu,,llNou)
*!* modificare 10.12.2010 ^
If !Empty(loCauta.id_part)
@@ -889,7 +889,7 @@ Procedure verificare_note_contabile
*!* modificare 10.12.2010
loPart = CautPartenerContabilitate(GetHash([cTitlu=>] + Alltrim(lcTitlu) + [??] + ;
[cCont=>] + Alltrim(lcCont) + [??] + ;
[lAdaugCorespondente=>1]))
[lAdaugCorespondente=>1??lVerificaANAF=>1]))
*!* loPart = caut_parteneri(lcCont , lcTitlu)
*!* modificare 10.12.2010 ^
Select (lcAct)

View File

@@ -64,6 +64,10 @@
*!* 22.07.2025
*!* GetNamePermutations - limitare la 4 cuvinte si maxim 10 permutari
*!* 31.07.2026
*!* marius.mutu
*!* verifica_partener_show_info: marcaj de provenienta (cache ANAF) langa denumirea firmei, cand disponibil
#Include COMUN\ROA.H
Define Class oexecutor As Custom
@@ -4597,6 +4601,7 @@ Procedure verificare_parteneri
Endproc && verificare_parteneri
*!* 01.08.2026 marius.mutu istoricul e comun tuturor firmelor, nu se mai filtreaza pe schema_sursa
Procedure verificare_parteneri_istoric
Lparameters tcCodFiscal, tcNume
@@ -4613,7 +4618,9 @@ Procedure verificare_parteneri_istoric
Endif
Text To lcSql Noshow
select id, dataora, id_util, dataorav, id_utilv, cod_fiscal, firma, adresa, judet, regcom, codpostal, telefon, fax, datatvamfin, platitortvamfin, stare, platitortvavies, util, utilv
select id, dataora, id_util, dataorav, id_utilv, cod_fiscal, firma, adresa, judet, regcom, codpostal, telefon, fax, datatvamfin, platitortvamfin, stare, platitortvavies,
dataorav_anaf, tvaincasare, splittva, inactiv, data_inceput_scptva, data_sfarsit_scptva, data_anul_imp_scptva, data_inceput_tvainc, data_sfarsit_tvainc, data_inactivare, data_reactivare,
util, utilv
from vistoric_coduri_fiscale
where cod_fiscal = ?pcCodFiscal
Endtext
@@ -4764,7 +4771,7 @@ Function verifica_partener_show_info
*** tcMesajIntrebare: IN, optional, daca se intreaba ceva la sfarsitul formularului (ex: Se completeaza datele in formularul partener nou?)
Local lcCodFiscal, lcDenumire, lcText, llCodRO, llPlatitorTVAMfin, llPlatitorTVAVIES, lnDialogType
Local lnRaspuns, loPartener
Local lnRaspuns, loPartener, lcProvenienta
lcCodFiscal = Transform(m.tcCodFiscal)
lcDenumire = Transform(m.tcDenumire)
@@ -4776,9 +4783,16 @@ Function verifica_partener_show_info
llTvaIncasare = loPartener.tvaincasare
llSplitTVA = loPartener.splittva
llInactiv = loPartener.inactiv
*!* 01.08.2026 marius.mutu: marcaj explicit al sursei (ANAF live / cache), nu doar pe randurile din cache
lcProvenienta = ''
If Pemstatus(m.loPartener, 'sursa', 5) And !Empty(Alltrim(Nvl(loPartener.sursa, '')))
lcProvenienta = Iif(Alltrim(Nvl(loPartener.sursa, '')) == 'ANAF', '(sursa: ANAF)', ;
'(sursa: CACHE ' + Dtoc(Nvl(loPartener.data_sursa, Date())) + Iif(Alltrim(Nvl(loPartener.sursa, '')) == 'CACHE_INDISP', ', ANAF indisponibil', '') + ')')
Endif
lcText = 'VERIFICARE CIF: ' + m.lcCodFiscal + ' ' + m.lcDenumire + crlf + crlf + ;
Alltrim(loPartener.firma) + crlf + ;
Iif(!Empty(m.lcProvenienta), m.lcProvenienta + crlf, '') + ;
Iif((m.llPlatitorTVAMfin And !m.llCodRO) Or (!m.llPlatitorTVAMfin And m.llCodRO), ' *** ATENTIE *** ', '') + ;
Iif(m.llPlatitorTVAMfin, "PLATITOR TVA (" + Alltrim(loPartener.datatvamfin) + ")", "NEPLATITOR TVA") + crlf + ;
'Stare: ' + Alltrim(loPartener.stare) + crlf + ;

File diff suppressed because it is too large Load Diff

View File

@@ -371,7 +371,7 @@ Define Class ExportEFactura As Custom
lcTextAditional = m.lcTextAditional + Iif(!Empty(m.lcTextAditional), ' # ', '') + "Taxare inversa"
ENDIF
IF !EMPTY(NVL(loDate.curs,0)) AND ATC('curs', m.lcTextAditional) = 0
IF loDate.in_valuta = 1 AND !EMPTY(NVL(loDate.curs,0)) AND ATC('curs', m.lcTextAditional) = 0
lcTextAditional = m.lcTextAditional + Iif(!Empty(m.lcTextAditional), ' # ', '') + "Curs: " + ALLTRIM(STR(loDate.curs, 10,4)) + " RON/" + STRTRAN(ALLTRIM(Nvl(loDate.cValuta, '')),'EURO', 'EUR',1,1,1)
ENDIF

338
scripts/roa_sync.ps1 Normal file
View File

@@ -0,0 +1,338 @@
<#
.SYNOPSIS
Sincronizare de inceput de sesiune pentru un proiect ROA (flux SVN + git text FoxBin2Prg).
.DESCRIPTION
Traieste in COMUN\scripts\ si se distribuie automat prin svn update (fiecare proiect isi
ruleaza copia lui: <ProjectRoot>\COMUN\scripts\roa_sync.ps1, de regula prin roa_sync.bat
din radacina proiectului). Pasul 2 depinde de tooling-ul din D:\ROA\UTIL\foxbin2prg
(git_sync.ps1 + FoxBin2Prg.EXE), care ramane acolo.
Pasii:
1. svn update pe ProjectRoot (include externalul COMUN\). Esec / conflicte -> stop, exit nenul.
2. git_sync.ps1 -ProjectRoot <ProjectRoot> (improspateaza textele .??2, inclusiv COMUN).
Esec (exit nenul) -> avertizare, fara commit-uri de sync, exit nenul.
3. Repo proiect (ProjectRoot\.git): pe main comite "sync SVN r<REV>" daca sunt schimbari,
apoi reconciliaza cu origin si face push conditionat (vezi mai jos).
4. La fel repo COMUN (ProjectRoot\COMUN\.git), cu revizia din svn info pe folderul COMUN.
5. Inchide branch-urile claude/* terminate (git diff main..branch gol) in ambele repo-uri.
6. Sumar final (commit / reconciliere / push per repo + avertismente).
Reconcilierea cu origin (pasii 3-4, DUPA commit-ul local de sync - commit-ul intai face
tree-ul curat si aduce sub urmarire fisierele noi, deci nu mai apar blocajele clasice de
pull peste modificari necomise / fisiere netracked):
- git fetch origin; fara remote origin sau fetch esuat (offline) -> avertisment si
comportamentul vechi (doar commit local), exit 0.
- doar in urma fata de origin/main -> git merge --ff-only origin/main.
- divergenta -> git rebase origin/main. Commit-urile de sync al caror continut e deja
identic pe origin (alta masina a rulat acelasi svn update + sync + push inaintea
noastra) devin goale la rebase si sunt aruncate automat - NU e conflict si nu cere
interventie manuala.
- conflict REAL la rebase -> git rebase --abort, avertisment, exit nenul la final.
- push origin main DOAR daca toate commit-urile ahead de origin/main sunt commit-uri de
sync ("sync SVN[ r<rev>]" - continut oglindit din SVN, sursa de adevar). Orice commit
non-sync nepushed blocheaza push-ul automat (avertisment; push manual dupa review).
- push respins (push simultan de pe alta masina) -> reia fetch + reconciliere + push,
maxim 3 incercari, apoi avertisment (se reconciliaza la urmatoarea rulare).
Exit: nenul la esec svn/git_sync sau conflict real cu origin; avertismentele (offline,
push sarit din cauza commit-urilor non-sync, push esuat) lasa exit 0 si apar in sumar.
.PARAMETER ProjectRoot
Radacina proiectului. Implicit: directorul curent, daca are .git si un .pjx.
.PARAMETER GitOnly
Sare peste pasii SVN (1) si regenerarea textelor (2): doar commit + reconciliere + push +
inchidere branch-uri. Pentru reconciliere rapida cu origin sau pentru teste
(test_roa_sync.ps1) - nu cere working copy SVN si nici FoxBin2Prg.
#>
[CmdletBinding()]
param(
[string]$ProjectRoot = '',
[switch]$GitOnly
)
$ErrorActionPreference = 'Stop'
# --- deduce ProjectRoot din directorul curent daca nu e dat ---
if (-not $ProjectRoot) {
$cwd = (Get-Location).Path
$hasGit = Test-Path -LiteralPath (Join-Path $cwd '.git')
$hasPjx = @(Get-ChildItem -LiteralPath $cwd -Filter '*.pjx' -File -ErrorAction SilentlyContinue).Count -gt 0
if ($hasGit -and $hasPjx) {
$ProjectRoot = $cwd
} else {
Write-Host "EROARE: -ProjectRoot nedat si directorul curent nu pare radacina de proiect ROA (lipseste .git sau .pjx): $cwd"
exit 1
}
}
if (-not (Test-Path -LiteralPath $ProjectRoot -PathType Container)) {
Write-Host "EROARE: ProjectRoot nu exista: $ProjectRoot"
exit 1
}
$ProjectRoot = (Get-Item -LiteralPath $ProjectRoot).FullName
$comunRoot = Join-Path $ProjectRoot 'COMUN'
# tooling-ul de conversie ramane in clona foxbin2prg (acolo sta si FoxBin2Prg.EXE)
$gitSync = 'D:\ROA\UTIL\foxbin2prg\git_sync.ps1'
Write-Host "=== roa_sync: ProjectRoot=$ProjectRoot$(if($GitOnly){' (-GitOnly)'}) ==="
# --- helper: revizia SVN a unui folder ---
function Get-SvnRev([string]$path) {
# EAP local Continue: sub Stop, redirectarea 2>$null a stderr-ului nativ arunca in PS 5.1
$ErrorActionPreference = 'Continue'
$rev = (& svn info --show-item revision $path 2>$null | Out-String).Trim()
if ($LASTEXITCODE -ne 0 -or -not $rev) { return '' }
return $rev
}
# =========================== 1. svn update ===========================
$rev = ''
Write-Host ''
if ($GitOnly) {
Write-Host "--- 1. svn update: sarit (-GitOnly) ---"
} else {
Write-Host "--- 1. svn update ---"
$svnOut = & svn update $ProjectRoot
$svnExit = $LASTEXITCODE
$svnOut | ForEach-Object { Write-Host " $_" }
if ($svnExit -ne 0) {
Write-Host "EROARE: svn update a esuat (exit $svnExit). Ma opresc."
exit 1
}
# svn poate iesi 0 dar raporta conflicte in sumar
if ($svnOut | Where-Object { $_ -match 'Summary of conflicts|conflict' }) {
Write-Host "EROARE: svn update raporteaza conflicte. Rezolva-le manual, apoi reia. Ma opresc."
exit 1
}
$rev = Get-SvnRev $ProjectRoot
Write-Host " Revizie SVN ProjectRoot: $(if($rev){$rev}else{'necunoscuta'})"
}
# =========================== 2. git_sync ===========================
Write-Host ''
if ($GitOnly) {
Write-Host "--- 2. git_sync: sarit (-GitOnly) ---"
} else {
Write-Host "--- 2. git_sync (texte .??2) ---"
if (-not (Test-Path -LiteralPath $gitSync)) {
Write-Host "EROARE: nu gasesc git_sync.ps1 la $gitSync. Ma opresc."
exit 1
}
& powershell -ExecutionPolicy Bypass -NoProfile -File $gitSync -ProjectRoot $ProjectRoot
$syncExit = $LASTEXITCODE
if ($syncExit -ne 0) {
Write-Host ''
Write-Host "AVERTISMENT: git_sync a raportat esecuri (exit $syncExit). NU fac commit-uri de sync. Ma opresc."
exit 1
}
}
# =========================== 3-4. commit sync + reconciliere origin per repo ===========================
# Pe main comite schimbarile ca "sync SVN r<rev>", apoi fetch + ff/rebase fata de origin/main
# (sync-urile cu continut deja identic pe origin devin goale la rebase si dispar) si push
# DOAR daca tot ahead-ul e din commit-uri de sync. Intoarce starea pasilor.
function Sync-Repo {
param([string]$RepoDir, [string]$Rev, [string]$Label)
# EAP local Continue: git scrie normal pe stderr (fetch/push/rebase), iar sub Stop
# redirectarea 2>$null ar arunca NativeCommandError in PS 5.1; verificam $LASTEXITCODE.
$ErrorActionPreference = 'Continue'
$r = [PSCustomObject]@{ Commit='nimic'; Origin='-'; Push='-'; Warnings=@() }
if (-not (Test-Path -LiteralPath (Join-Path $RepoDir '.git'))) {
Write-Host " ${Label}: fara repo git ($RepoDir) - sar peste."
$r.Commit = 'fara-repo'
return $r
}
$branch = (& git -C $RepoDir rev-parse --abbrev-ref HEAD).Trim()
if ($branch -ne 'main') {
# tree curat = putem trece pe main; altfel nu atingem branch-ul
$dirty = @(& git -C $RepoDir status --porcelain).Count -gt 0
if ($dirty) {
Write-Host " ${Label}: esti pe '$branch'; sync-ul se face pe main. Ai modificari necomise - sar peste."
$r.Commit = 'skip-branch'
return $r
}
Write-Host " ${Label}: pe '$branch' cu tree curat - fac checkout main."
& git -C $RepoDir checkout main | Out-Null
if ($LASTEXITCODE -ne 0) {
Write-Host " ${Label}: checkout main a esuat - sar peste."
$r.Commit = 'skip-branch'
return $r
}
}
& git -C $RepoDir add -A | Out-Null
$staged = @(& git -C $RepoDir status --porcelain).Count -gt 0
if ($staged) {
$msg = if ($Rev) { "sync SVN r$Rev" } else { "sync SVN" }
& git -C $RepoDir commit -m $msg | Out-Null
if ($LASTEXITCODE -ne 0) {
Write-Host " ${Label}: commit a esuat - sar peste reconciliere."
$r.Commit = 'esec-commit'
$r.Warnings += "${Label}: commit de sync esuat"
return $r
}
Write-Host " ${Label}: commit '$msg'."
$r.Commit = 'commit'
} else {
Write-Host " ${Label}: nimic de comis."
}
# --- reconciliere cu origin (dupa commit: tree curat, fisierele noi sunt deja urmarite) ---
$originUrl = (& git -C $RepoDir remote get-url origin 2>$null | Out-String).Trim()
if ($LASTEXITCODE -ne 0 -or -not $originUrl) {
Write-Host " ${Label}: fara remote origin - repo doar local, sar peste reconciliere."
$r.Origin = 'fara-origin'
return $r
}
& git -C $RepoDir fetch origin 2>$null | Out-Null
if ($LASTEXITCODE -ne 0) {
Write-Host " ${Label}: AVERTISMENT: git fetch origin a esuat (offline / gitea inaccesibil?); reconcilierea ramane pe urmatoarea rulare."
$r.Origin = 'fetch-esuat'
$r.Warnings += "${Label}: fetch origin esuat - reconciliere amanata"
return $r
}
& git -C $RepoDir rev-parse --verify --quiet origin/main 2>$null | Out-Null
if ($LASTEXITCODE -ne 0) {
Write-Host " ${Label}: origin nu are inca main - sar peste reconciliere."
$r.Origin = 'fara-origin-main'
return $r
}
for ($attempt = 1; $attempt -le 3; $attempt++) {
$behind = [int]((& git -C $RepoDir rev-list --count main..origin/main | Out-String).Trim())
$ahead = [int]((& git -C $RepoDir rev-list --count origin/main..main | Out-String).Trim())
if ($behind -gt 0 -and $ahead -eq 0) {
& git -C $RepoDir merge --ff-only origin/main 2>$null | Out-Null
if ($LASTEXITCODE -ne 0) {
Write-Host " ${Label}: AVERTISMENT: fast-forward la origin/main a esuat neasteptat - verifica manual."
$r.Origin = 'conflict'
$r.Warnings += "${Label}: fast-forward esuat - verifica manual repo-ul"
return $r
}
Write-Host " ${Label}: adus la zi cu origin/main (fast-forward, $behind commit-uri)."
$r.Origin = 'ff'
} elseif ($behind -gt 0 -and $ahead -gt 0) {
Write-Host " ${Label}: local si origin au divergat (ahead $ahead / behind $behind) - rebase pe origin/main."
& git -C $RepoDir rebase --empty=drop origin/main 2>$null | Out-Null
if ($LASTEXITCODE -ne 0) {
& git -C $RepoDir rebase --abort 2>$null | Out-Null
Write-Host " ${Label}: CONFLICT real la rebase pe origin/main - rebase anulat. Rezolva manual: git -C $RepoDir rebase origin/main"
$r.Origin = 'conflict'
$r.Warnings += "${Label}: conflict real cu origin/main - reconciliere manuala necesara"
return $r
}
$r.Origin = 'rebase'
} elseif ($r.Origin -eq '-') {
$r.Origin = if ($ahead -gt 0) { 'doar-ahead' } else { 'la-zi' }
}
# --- push doar daca tot ahead-ul e din commit-uri de sync ---
$aheadMsgs = @(& git -C $RepoDir log --format=%s origin/main..main) | Where-Object { $_ -and $_.Trim() }
if ($aheadMsgs.Count -eq 0) {
Write-Host " ${Label}: la zi cu origin/main; nimic de impins."
$r.Push = 'nimic'
return $r
}
$nonSync = @($aheadMsgs | Where-Object { $_ -notmatch '^sync SVN( r\S+)?$' })
if ($nonSync.Count -gt 0) {
Write-Host " ${Label}: AVERTISMENT: ahead de origin include commit-uri non-sync - NU fac push automat (push manual dupa review):"
$nonSync | Select-Object -First 5 | ForEach-Object { Write-Host " - $_" }
$r.Push = 'sarit-non-sync'
$r.Warnings += "${Label}: push sarit - exista commit-uri non-sync nepushed"
return $r
}
& git -C $RepoDir push origin main 2>$null | Out-Null
if ($LASTEXITCODE -eq 0) {
Write-Host " ${Label}: push origin main ($($aheadMsgs.Count) commit-uri de sync)."
$r.Push = 'push'
return $r
}
if ($attempt -lt 3) {
Write-Host " ${Label}: push respins (probabil push simultan de pe alta masina) - refetch si reiau (incercarea $($attempt+1))."
& git -C $RepoDir fetch origin 2>$null | Out-Null
if ($LASTEXITCODE -ne 0) {
Write-Host " ${Label}: AVERTISMENT: refetch esuat dupa push respins."
$r.Push = 'esec'
$r.Warnings += "${Label}: push esuat si refetch esuat - reconciliere la urmatoarea rulare"
return $r
}
}
}
Write-Host " ${Label}: AVERTISMENT: push respins de 3 ori - renunt; se reconciliaza la urmatoarea rulare."
$r.Push = 'esec'
$r.Warnings += "${Label}: push esuat dupa 3 incercari"
return $r
}
Write-Host ''
Write-Host "--- 3. sync repo proiect ---"
$resProj = Sync-Repo -RepoDir $ProjectRoot -Rev $rev -Label 'proiect'
Write-Host ''
Write-Host "--- 4. sync repo COMUN ---"
$revComun = ''
$resComun = [PSCustomObject]@{ Commit='nimic'; Origin='-'; Push='-'; Warnings=@() }
if (Test-Path -LiteralPath $comunRoot -PathType Container) {
if (-not $GitOnly) { $revComun = Get-SvnRev $comunRoot }
$resComun = Sync-Repo -RepoDir $comunRoot -Rev $revComun -Label 'COMUN'
} else {
Write-Host " COMUN: folderul nu exista ($comunRoot) - sar peste."
}
# =========================== 5. inchidere branch-uri claude/* ===========================
# Inchide branch-urile claude/* al caror diff fata de main e gol (munca lor a intrat prin sync).
function Close-ClaudeBranches {
param([string]$RepoDir, [string]$Label)
$closed = @(); $active = @()
if (-not (Test-Path -LiteralPath (Join-Path $RepoDir '.git'))) { return @{ Closed=$closed; Active=$active } }
$branches = @(& git -C $RepoDir for-each-ref --format='%(refname:short)' refs/heads/claude 2>$null) |
Where-Object { $_ -and $_.Trim() } | ForEach-Object { $_.Trim() }
foreach ($b in $branches) {
$diff = @(& git -C $RepoDir diff --name-only main..$b 2>$null) | Where-Object { $_ -and $_.Trim() }
if ($diff.Count -eq 0) {
& git -C $RepoDir branch -D $b | Out-Null
if ($LASTEXITCODE -eq 0) { $closed += $b; Write-Host " ${Label}: inchis $b" }
else { Write-Host " ${Label}: nu am putut sterge $b" }
} else {
$active += $b
Write-Host " ${Label}: activ $b ($($diff.Count) fisiere diferite)"
}
}
return @{ Closed=$closed; Active=$active }
}
Write-Host ''
Write-Host "--- 5. inchidere branch-uri claude/* ---"
$brProj = Close-ClaudeBranches -RepoDir $ProjectRoot -Label 'proiect'
$brComun = @{ Closed=@(); Active=@() }
if (Test-Path -LiteralPath $comunRoot -PathType Container) {
$brComun = Close-ClaudeBranches -RepoDir $comunRoot -Label 'COMUN'
}
# =========================== 6. sumar ===========================
$commits = @()
if ($resProj.Commit -eq 'commit') { $commits += "proiect: sync SVN$(if($rev){" r$rev"})" }
if ($resComun.Commit -eq 'commit') { $commits += "COMUN: sync SVN$(if($revComun){" r$revComun"})" }
$closedAll = @($brProj.Closed + $brComun.Closed)
$activeAll = @($brProj.Active + $brComun.Active)
$warnAll = @($resProj.Warnings + $resComun.Warnings)
Write-Host ''
Write-Host "===================== SUMAR ====================="
Write-Host "Revizie SVN: proiect=$(if($rev){$rev}else{'?'})$(if($revComun){" COMUN=$revComun"})"
if ($commits.Count -gt 0) {
Write-Host "Commit-uri de sync:"
$commits | ForEach-Object { Write-Host " $_" }
} else {
Write-Host "Commit-uri de sync: nimic de sincronizat"
}
Write-Host "Origin: proiect=$($resProj.Origin)/push=$($resProj.Push) COMUN=$($resComun.Origin)/push=$($resComun.Push)"
Write-Host "Branch-uri inchise: $(if($closedAll.Count){$closedAll -join ', '}else{'niciunul'})"
Write-Host "Branch-uri active: $(if($activeAll.Count){$activeAll -join ', '}else{'niciunul'})"
if ($warnAll.Count -gt 0) {
Write-Host "AVERTISMENTE:"
$warnAll | ForEach-Object { Write-Host " $_" }
}
Write-Host "================================================"
if (($resProj.Origin -eq 'conflict') -or ($resComun.Origin -eq 'conflict')) { exit 1 }
exit 0

239
scripts/test_roa_sync.ps1 Normal file
View File

@@ -0,0 +1,239 @@
<#
.SYNOPSIS
Teste standalone (fara Pester) pentru reconcilierea cu origin din roa_sync.ps1, pe
fixture-uri git construite in TEMP (origin bare + doua clone "masini"). Ruleaza
roa_sync.ps1 -GitOnly (fara SVN, fara FoxBin2Prg), deci nu atinge niciun proiect real.
Scenarii:
(A) scenariul din 2026-07-27: modificari locale necomise + fisier netracked, toate
byte-identice cu ce a impins deja alta masina -> reconciliere automata (sync-ul
local devine gol la rebase si e aruncat), fara interventie manuala, exit 0;
(B) behind + continut local NOU -> rebase pastreaza sync-ul si il impinge pe origin;
(C) doar behind, fara modificari locale -> fast-forward la origin/main;
(D) conflict real (acelasi fisier, continut diferit) -> rebase --abort, exit nenul,
repo lasat curat (fara rebase in curs), commit-ul local pastrat;
(E) garda de push: commit non-sync ahead de origin -> push blocat + avertisment;
(F) fetch esuat (origin inaccesibil) -> comportamentul vechi (doar commit local), exit 0;
(G) push respins o data (hook pre-receive, simuleaza push simultan) -> retry reuseste;
(H) repo fara remote origin -> doar commit local, exit 0.
#>
[CmdletBinding()]
param()
$ErrorActionPreference = 'Stop'
$script:RoaSync = Join-Path $PSScriptRoot 'roa_sync.ps1'
$script:Failures = @()
function Assert([bool]$cond, [string]$msg) {
if ($cond) { Write-Host " PASS: $msg" -ForegroundColor Green }
else { Write-Host " FAIL: $msg" -ForegroundColor Red; $script:Failures += $msg }
}
# --- git in fixture: EAP Continue local (git scrie pe stderr; sub Stop 2>$null ar arunca) ---
function G {
param([Parameter(Mandatory)][string]$Repo,
[Parameter(Mandatory, ValueFromRemainingArguments)][string[]]$GitArgs)
$prev = $ErrorActionPreference; $ErrorActionPreference = 'Continue'
$out = (& git -C $Repo @GitArgs 2>$null | Out-String).Trim()
$code = $LASTEXITCODE
$ErrorActionPreference = $prev
if ($code -ne 0) { throw "git -C $Repo $($GitArgs -join ' ') a esuat (exit $code)" }
return $out
}
# scriere fisier cu octeti determinati (acelasi continut => aceiasi octeti pe ambele "masini")
function WF([string]$path, [string]$content) { [IO.File]::WriteAllText($path, $content) }
function Set-RepoConfig([string]$repo) {
$null = G $repo config user.name 'Test ROA'
$null = G $repo config user.email 'test@roa.local'
$null = G $repo config commit.gpgsign false
$null = G $repo config core.autocrlf false
}
# --- lume de test: origin bare + masinaA (a impins deja) + masinaB (fixture-ul testat) ---
function New-World([string]$tag) {
$root = Join-Path $env:TEMP ("rs_test_{0}_{1}_{2}" -f $tag, $PID, [Guid]::NewGuid().ToString('N').Substring(0,8))
New-Item -ItemType Directory -Force -Path $root | Out-Null
$bare = Join-Path $root 'origin.git'
$null = G $root init --bare origin.git
$null = G $bare symbolic-ref HEAD refs/heads/main
# -c la clone seteaza configul in noul repo INAINTE de checkout: cu autocrlf global true,
# checkout-ul ar scrie CRLF si un add -A ulterior ar vedea fals toate fisierele modificate
$null = G $root clone -c core.autocrlf=false origin.git masinaA
$A = Join-Path $root 'masinaA'
Set-RepoConfig $A
$null = G $A checkout -b main
WF (Join-Path $A 'a.prg') "linie 1`nv1`n"
WF (Join-Path $A 'b.prg') "b v1`n"
$null = G $A add -A
$null = G $A commit -m 'initial'
$null = G $A push -u origin main
$null = G $root clone -c core.autocrlf=false origin.git masinaB
$B = Join-Path $root 'masinaB'
Set-RepoConfig $B
return [PSCustomObject]@{ Root=$root; Bare=$bare; A=$A; B=$B }
}
function Remove-World($w) {
Remove-Item -Recurse -Force -LiteralPath $w.Root -ErrorAction SilentlyContinue
}
function Invoke-RoaSync([string]$Fixture) {
$prev = $ErrorActionPreference; $ErrorActionPreference = 'Continue'
$raw = & powershell -ExecutionPolicy Bypass -NoProfile -File $script:RoaSync -ProjectRoot $Fixture -GitOnly 2>&1 | Out-String
$exit = $LASTEXITCODE
$ErrorActionPreference = $prev
return [PSCustomObject]@{ Exit=$exit; Raw=$raw }
}
# ============================== SCENARIILE ==============================
function Test-ContinutIdentic {
Write-Host "`n--- (A) scenariul 2026-07-27: local byte-identic cu origin (modificat + netracked) ---"
$w = New-World 'ident'
try {
# masina A a facut svn update + sync + push inaintea noastra
WF (Join-Path $w.A 'a.prg') "linie 1`nv2`n"
WF (Join-Path $w.A 'wincrypt.h') "#define W 1`n"
$null = G $w.A add -A; $null = G $w.A commit -m 'sync SVN r100'; $null = G $w.A push origin main
# masina B: acelasi svn update + regenerare => aceleasi continuturi, necomise/netracked
WF (Join-Path $w.B 'a.prg') "linie 1`nv2`n"
WF (Join-Path $w.B 'wincrypt.h') "#define W 1`n"
$r = Invoke-RoaSync $w.B
Assert ($r.Exit -eq 0) "A: exit 0, fara interventie manuala (exit=$($r.Exit))"
Assert ((G $w.B rev-parse main) -eq (G $w.Bare rev-parse main)) "A: main local == origin/main dupa reconciliere"
Assert ((G $w.B log -1 --format=%s) -eq 'sync SVN r100') "A: sync-ul local gol a fost aruncat (tip = commit-ul masinii A)"
Assert ([string]::IsNullOrWhiteSpace((G $w.B status --porcelain))) "A: working tree curat"
} finally { Remove-World $w }
}
function Test-ContinutNou {
Write-Host "`n--- (B) behind + continut local nou: rebase pastreaza sync-ul si il impinge ---"
$w = New-World 'nou'
try {
WF (Join-Path $w.A 'a.prg') "linie 1`nv2`n"
$null = G $w.A add -A; $null = G $w.A commit -m 'sync SVN r100'; $null = G $w.A push origin main
# masina B: aceeasi modificare (identica) + un fisier NOU pe care origin nu il are
WF (Join-Path $w.B 'a.prg') "linie 1`nv2`n"
WF (Join-Path $w.B 'c.prg') "continut nou local`n"
$r = Invoke-RoaSync $w.B
Assert ($r.Exit -eq 0) "B: exit 0 (exit=$($r.Exit))"
Assert ((G $w.B log -1 --format=%s) -eq 'sync SVN') "B: sync-ul local (continut nou) pastrat dupa rebase"
Assert ((G $w.B rev-parse main) -eq (G $w.Bare rev-parse main)) "B: push automat - origin/main actualizat"
Assert ((G $w.Bare ls-tree --name-only main) -match 'c\.prg') "B: c.prg a ajuns pe origin"
} finally { Remove-World $w }
}
function Test-DoarBehind {
Write-Host "`n--- (C) doar behind, fara modificari locale: fast-forward ---"
$w = New-World 'ff'
try {
WF (Join-Path $w.A 'b.prg') "b v2`n"
$null = G $w.A add -A; $null = G $w.A commit -m 'sync SVN r101'; $null = G $w.A push origin main
$r = Invoke-RoaSync $w.B
Assert ($r.Exit -eq 0) "C: exit 0 (exit=$($r.Exit))"
Assert ($r.Raw -match 'fast-forward') "C: reconciliere prin fast-forward"
Assert ((G $w.B rev-parse main) -eq (G $w.Bare rev-parse main)) "C: main local == origin/main"
} finally { Remove-World $w }
}
function Test-ConflictReal {
Write-Host "`n--- (D) conflict real: rebase abortat, exit nenul, repo curat ---"
$w = New-World 'conf'
try {
WF (Join-Path $w.A 'a.prg') "linie 1`nvarianta A`n"
$null = G $w.A add -A; $null = G $w.A commit -m 'sync SVN r102'; $null = G $w.A push origin main
WF (Join-Path $w.B 'a.prg') "linie 1`nvarianta B`n"
$r = Invoke-RoaSync $w.B
Assert ($r.Exit -ne 0) "D: exit nenul la conflict real (exit=$($r.Exit))"
Assert ($r.Raw -match 'CONFLICT') "D: conflictul e raportat explicit"
$inRebase = (Test-Path (Join-Path $w.B '.git\rebase-merge')) -or (Test-Path (Join-Path $w.B '.git\rebase-apply'))
Assert (-not $inRebase) "D: rebase anulat curat (fara rebase in curs)"
Assert ((G $w.B log -1 --format=%s) -eq 'sync SVN') "D: commit-ul local de sync pastrat"
Assert ([string]::IsNullOrWhiteSpace((G $w.B status --porcelain))) "D: working tree curat dupa abort"
Assert ((G $w.Bare log -1 --format=%s) -eq 'sync SVN r102') "D: origin neatins"
} finally { Remove-World $w }
}
function Test-GardaNonSync {
Write-Host "`n--- (E) garda de push: commit non-sync ahead blocheaza push-ul automat ---"
$w = New-World 'guard'
try {
$init = G $w.Bare rev-parse main
# commit local non-sync (lucrare in curs, nepushed) + modificari de sync necomise
WF (Join-Path $w.B 'd.prg') "lucru manual`n"
$null = G $w.B add -A; $null = G $w.B commit -m 'lucrare manuala neaprobata'
WF (Join-Path $w.B 'b.prg') "b v2`n"
$r = Invoke-RoaSync $w.B
Assert ($r.Exit -eq 0) "E: exit 0 (exit=$($r.Exit))"
Assert ($r.Raw -match 'non-sync') "E: avertisment despre commit-uri non-sync"
Assert ((G $w.Bare rev-parse main) -eq $init) "E: origin neatins (fara push)"
Assert ((G $w.B log -1 --format=%s) -eq 'sync SVN') "E: sync-ul local totusi comis"
} finally { Remove-World $w }
}
function Test-Offline {
Write-Host "`n--- (F) fetch esuat (origin inaccesibil): doar commit local, exit 0 ---"
$w = New-World 'off'
try {
$null = G $w.B remote set-url origin (Join-Path $w.Root 'inexistent.git')
WF (Join-Path $w.B 'b.prg') "b v3`n"
$r = Invoke-RoaSync $w.B
Assert ($r.Exit -eq 0) "F: exit 0 (exit=$($r.Exit))"
Assert ($r.Raw -match 'fetch origin a esuat') "F: avertisment de fetch esuat"
Assert ((G $w.B log -1 --format=%s) -eq 'sync SVN') "F: commit-ul local de sync facut totusi"
} finally { Remove-World $w }
}
function Test-PushRetry {
Write-Host "`n--- (G) push respins o data (simulare push simultan): retry reuseste ---"
$w = New-World 'retry'
try {
# hook pre-receive: respinge cat timp exista flagul reject_once, apoi accepta
$hook = "#!/bin/sh`nif [ -f reject_once ]; then`n rm -f reject_once`n exit 1`nfi`nexit 0`n"
[IO.File]::WriteAllText((Join-Path $w.Bare 'hooks\pre-receive'), $hook)
WF (Join-Path $w.Bare 'reject_once') "1"
WF (Join-Path $w.B 'b.prg') "b v4`n"
$r = Invoke-RoaSync $w.B
Assert ($r.Exit -eq 0) "G: exit 0 (exit=$($r.Exit))"
Assert ($r.Raw -match 'push respins') "G: prima incercare respinsa si raportata"
Assert ((G $w.Bare rev-parse main) -eq (G $w.B rev-parse main)) "G: push reusit la reincercare"
} finally { Remove-World $w }
}
function Test-FaraOrigin {
Write-Host "`n--- (H) repo fara remote origin: doar commit local ---"
$w = New-World 'noorig'
try {
$null = G $w.B remote remove origin
WF (Join-Path $w.B 'b.prg') "b v5`n"
$r = Invoke-RoaSync $w.B
Assert ($r.Exit -eq 0) "H: exit 0 (exit=$($r.Exit))"
Assert ($r.Raw -match 'fara remote origin') "H: lipsa origin raportata"
Assert ((G $w.B log -1 --format=%s) -eq 'sync SVN') "H: commit-ul local de sync facut"
} finally { Remove-World $w }
}
# ============================== MAIN ==============================
if (-not (Test-Path -LiteralPath $script:RoaSync)) { throw "Nu gasesc roa_sync.ps1: $script:RoaSync" }
Write-Host "=== test_roa_sync.ps1 ==="
Test-ContinutIdentic
Test-ContinutNou
Test-DoarBehind
Test-ConflictReal
Test-GardaNonSync
Test-Offline
Test-PushRetry
Test-FaraOrigin
Write-Host "`n=== REZULTAT ==="
if ($script:Failures.Count -eq 0) {
Write-Host "TOATE testele au trecut." -ForegroundColor Green
exit 0
} else {
Write-Host "$($script:Failures.Count) test(e) esuate:" -ForegroundColor Red
$script:Failures | ForEach-Object { Write-Host " - $_" -ForegroundColor Red }
exit 1
}

View File

@@ -2434,7 +2434,7 @@ DEFINE CLASS gridutils AS form
PROCEDURE copytoexcel
*!* LPARAMETERS tcXLSFile, tcSheet, tvWorkArea, tcExcelFieldList, tcTableFieldList, tcTableForExpr
#DEFINE ALPHANUMERICCHR "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz1234567890"
LOCAL lnCounter, loColumn, lcXLSFile, lcSheetName, lcAliasWas, lcGridAlias, ;
LOCAL lnCounter, lnOrder, laOrder, loColumn, lcXLSFile, lcSheetName, lcAliasWas, lcGridAlias, ;
lcExcelFieldList, lcTableFieldList, lcTableForExpression, loHeaderObject, ;
lcFileName, lcAction, lcPath, loExcelApp, loWorkBook, lcKeyName
m.lcXLSFile = "C:\" + SYS(2015) + ".xls"
@@ -2445,8 +2445,15 @@ DEFINE CLASS gridutils AS form
*!* m.lcTableForExpression = FILTER(this.gridobject.recordsource)
m.lcSheetName = "Sheet1"
STORE "" TO m.lcExcelFieldList, m.lcTableFieldList
*!* coloanele se exporta in ordinea de afisare din grid (ColumnOrder), nu in ordinea de creare
DIMENSION laOrder[MAX(THIS.gridobject.COLUMNCOUNT, 1), 2]
FOR m.lnCounter = 1 TO THIS.gridobject.COLUMNCOUNT
m.loColumn = THIS.gridobject.COLUMNS(m.lnCounter)
laOrder[m.lnCounter, 1] = THIS.gridobject.COLUMNS(m.lnCounter).COLUMNORDER
laOrder[m.lnCounter, 2] = m.lnCounter
ENDFOR
=ASORT(laOrder)
FOR m.lnOrder = 1 TO THIS.gridobject.COLUMNCOUNT
m.loColumn = THIS.gridobject.COLUMNS(laOrder[m.lnOrder, 2])
IF m.loColumn.VISIBLE AND m.loColumn.WIDTH > 0
m.loHeaderObject = m.loColumn.CONTROLS(1)
m.lcExcelFieldList = m.lcExcelFieldList + IIF(!EMPTY(m.lcExcelFieldList), ',', '') ;

View File

@@ -10,7 +10,15 @@ $dir = [System.IO.Path]::GetDirectoryName($Prg)
$tmpPrg = Join-Path $dir '_compile_tmp.prg'
# prg temporar care compileaza target-ul (COMPILE cu variabila; forma cu literal in ghilimele da eroare)
Set-Content -Path $tmpPrg -Value ("lcT = `"$Prg`"`r`nCOMPILE (lcT)`r`nQUIT`r`n") -Encoding ascii
Get-Process vfp9 -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
# omoara doar vfp9 proprii (linia de comanda contine folderul testului), nu instante straine
function Stop-VfpProprii([string]$Marker) {
Get-CimInstance Win32_Process -Filter "Name='vfp9.exe'" -ErrorAction SilentlyContinue | ForEach-Object {
if ($_.CommandLine -and $_.CommandLine.ToLower().Contains($Marker.ToLower())) {
Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue
}
}
}
Stop-VfpProprii $dir
Start-Sleep -Milliseconds 500
if (Test-Path $Fxp) { [System.IO.File]::Delete($Fxp) }
@@ -48,7 +56,7 @@ foreach ($try in 1..3) {
Start-Sleep -Milliseconds 300
}
Start-Sleep -Seconds 3
Get-Process vfp9 -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
Stop-VfpProprii $dir
Start-Sleep -Seconds 1
if (Test-Path $Fxp) { $ok = $true; break }
}

View File

@@ -4,5 +4,11 @@
* (capcana l: CREATEOBJECT/ADDPROPERTY nu merg corect apelate dintr-o procedura in acest runtime).
FUNCTION caut_valuta
LPARAMETERS tnPornire, tlDesktop, tlFaraMonedaNationala
LOCAL loRezultat
IF TYPE('goMockValutaCoada') = 'O' AND !ISNULL(goMockValutaCoada) AND goMockValutaCoada.Count > 0
loRezultat = goMockValutaCoada.Item(1)
goMockValutaCoada.Remove(1)
RETURN loRezultat
ENDIF
RETURN goMockValuta
ENDFUNC

View File

@@ -0,0 +1,50 @@
* mock_cauta_alfa_tva11.prg - shadow PROCEDURE cauta_alfa (COMUN\programe\cauta_alfa.prg) DOAR
* pentru testul de reproducere TVA 11% pe explicatia TVA din grid (do_modifica_explicatie_tva,
* COMUN\clase\ointroduceri.vcx). Acelasi motiv ca mock_cauta_alfa_dialog.prg (cauta_alfa real
* populeaza cursorul din Oracle prin gencursor/CursorAdapter - nemock-uibil prin goExecutor) -
* vezi acel fisier pentru detalii complete despre flux. Aici simplificat la modul SINGLE-SELECT:
* do_modifica_explicatie_tva nu trimite tnTipReturn, deci cauta_alfa il impune 0 (obiect scatter
* pe randul curent, lAles=.F.) - submit-ul e echivalentul unui dublu-click pe randul dialogului
* (bind dblClick->do_termin activ doar in modul single-select, cauta_alfa_forms.vc2:652
* "If !Thisform.lales"), fara nevoie de marcaj (cAles).
*
* Control test (setat de testul principal INAINTE de fiecare apel):
* goDlgTva11 - formularul REAL cauta_alfa_form, pre-construit in main (capcana l:
* CREATEOBJECT dintr-o procedura da obiect stricat in acest runtime headless)
* gcTestTvaAlege - denumirea randului de ales (coloana "denumire" a cursorului dialogului)
Procedure cauta_alfa
Parameters tcselect,tcfiltru,tcschema,tcorder,tccoloana,tcTitlu,tcTitluColoane, ;
tcNume_Proc,tl_AllInList,tcFiltruOriginal,tcPrimaColoana, tnPornire, tnTipReturn, ;
tcIdColumn, tlDesktop, tcGroup, tcGridDynamicBackColor, tcGridToolTip, tlModParam, tcStringCriterii, ;
tcProceduraVerifica, tcProceduraCopiaza,tcLocate
LOCAL lcCursor, oReturnScattObj
lcCursor = goDlgTva11.crs_cursor
SELECT (lcCursor)
LOCATE FOR ALLTRIM(denumire) == ALLTRIM(gcTestTvaAlege)
IF !FOUND()
GO TOP
ENDIF
IF TYPE('gcUILog') = 'C'
DO HarnessLog WITH 'MOCK cauta_alfa(explicatie tva) pozitionat pe [' + ALLTRIM(denumire) + '] id_jtva_coloana=' + TRANSFORM(id_jtva_coloana) + ' cota_tva=' + TRANSFORM(cota_tva)
ENDIF
*-- echivalentul dublu-click pe randul dialogului (submit direct, mod single-select):
*-- butonul OK REAL (_frm_base.do_termin: gnButon=1, Release oForm_cautare)
goDlgTva11.do_termin()
DOEVENTS FORCE
*-- de aici incolo: cod IDENTIC cu cauta_alfa.prg real (tnTipReturn=0 implicit) - SCATTER
*-- pe randul curent al cursorului (NU se mai atinge oForm_cautare, Release-uit mai sus)
SELECT (lcCursor)
IF gnButon = 1
SCATTER NAME oReturnScattObj MEMO
ELSE
SCATTER NAME oReturnScattObj MEMO BLANK
ENDIF
RETURN oReturnScattObj
Endproc && cauta_alfa (shadow test tva11)

View File

@@ -0,0 +1,19 @@
* mock_oscrie_in_fisiere.prg - inlocuieste oscrie_in_fisiere (COMUN\programe\oscrie_in_fisiere.prg)
* in testul e2e - functia reala face scriere Oracle NATIVA (SQLSetprop pe gnHandle, conexiune
* SQLCONNECT reala), imposibil de mock-uit prin goExecutor/dummyexecutor (acela intercepteaza
* doar apeluri oExecute/oExecuta, nu SQL nativ). Fara mock, testul se opreste la eroarea 1466
* "Connection handle is invalid" - asteptata, nu bug (vezi handoff_dvi_discount.md).
* Incarcat cu SET PROCEDURE ADDITIVE INAINTE de fisierele reale (castiga primul incarcat,
* capcana g - vezi antetul mock_caut_valuta.prg). Foloseste DOAR in test_e2e_dvi_ron_discount.prg,
* NU global pentru suita - scrierea reala in ACT/actactan trebuie testata separat, cu conexiune
* Oracle vie (nu aici).
* Contract: aceiasi parametri ca apelul real (tnScrie_Sterge, tlModificare, tlRul,
* tlNuSuprascrieCod, tlLoadBackup - vezi oscrie_in_fisiere.prg:14), intoarce 1 (succes - acelasi
* cod folosit de functia reala la finalul ei, linia 108/167).
FUNCTION oscrie_in_fisiere
LPARAMETERS tnScrie_Sterge, tlModificare, tlRul, tlNuSuprascrieCod, tlLoadBackup
IF TYPE('gcUILog') = 'C'
DO HarnessLog WITH 'MOCK oscrie_in_fisiere apelat: tnScrie_Sterge=' + TRANSFORM(NVL(tnScrie_Sterge,-1)) + ' tlModificare=' + TRANSFORM(NVL(tlModificare,.F.)) + ' tlRul=' + TRANSFORM(NVL(tlRul,.F.)) + ' -> succes mock'
ENDIF
RETURN 1
ENDFUNC

View File

@@ -0,0 +1,41 @@
*--------------------------------------------------------------------------------------------------------------------------------------------------------
* (EN) AUTOGENERATED - ATTENTION!! - NOT INTENDED FOR EXECUTION!! USE ONLY FOR MERGING CHANGES AND STORING WITH SCM TOOLS!!
*--------------------------------------------------------------------------------------------------------------------------------------------------------
*< FOXBIN2PRG: Version="1.21" SourceFile="verificare.scx" CPID="1252" /> (Solo para binarios VFP 9 / Only for VFP 9 binaries)
*
*
DEFINE CLASS dataenvironment AS dataenvironment
*< CLASSDATA: Baseclass="dataenvironment" Timestamp="" Scale="" Uniqueid="" ClassIcon="1" />
*<PropValue>
DataSource = .NULL.
Height = 0
Left = 0
Name = "Dataenvironment"
Top = 0
Width = 0
*</PropValue>
ENDDEFINE
DEFINE CLASS form1 AS form
*< CLASSDATA: Baseclass="form" Timestamp="" Scale="" Uniqueid="" />
*<PropValue>
AutoCenter = .T.
Caption = "STUB verificare (test harness only)"
DoCreate = .T.
Height = 100
Name = "FORM1"
Visible = .F.
Width = 200
WindowType = 0
*</PropValue>
PROCEDURE Init
LPARAMETERS tVerificAnalitic, tAlegPartener, tnButonIntoarcere, tlNuVerificCont
gnButon = 1
RETURN .F.
ENDPROC
ENDDEFINE

View File

@@ -541,8 +541,8 @@ PROCEDURE CreeazaIntrodc
nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), ;
scd_orig C(20), ascd_orig C(20))
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), expl_manual N(1), ;
scd_orig C(20), ascd_orig C(20), rand_dvi N(1), valuta_proprie N(1))
ENDPROC
PROCEDURE VerificaPereche

View File

@@ -535,22 +535,21 @@ TRY
DO ArLog WITH 'INFO verificare2: cmesajsync gol -> nota SINCRONIZATA'
ENDIF
*-- runda4c (spargere doar factura principala): dupa sincronizeaza(), doar documentul
*-- principal (primul B/S din introdc, aici nract=100/RAJA) trebuie spart in randuri S (cont
*-- 212); documentele 102 (TRANS OIL MOTO) si 103 (BIROUL VAMAL) trebuie sa ramana B/T
*-- neatinse (regula de domeniu: articolele apartin doar facturii principale).
LOCAL llDoc100Spart, llDoc102Nesparte, llDoc103Nesparte
*-- lSpargeSecundare implicit .T. si documentele 102/103 sunt participante (lIntern=.F.,
*-- id_jtva_coloana nenul): dupa sincronizeaza() se sparg TOATE documentele B/S in randuri S
*-- pe conturile articolelor (aici doar 212), nu doar documentul principal (100/RAJA).
LOCAL llDoc100Spart, llDoc102Spart, llDoc103Spart
SELECT introdc
LOCATE FOR nract = 100 AND tip_rand == 'S'
llDoc100Spart = FOUND()
LOCATE FOR nract = 102 AND tip_rand == 'B'
llDoc102Nesparte = FOUND()
LOCATE FOR nract = 103 AND tip_rand == 'B'
llDoc103Nesparte = FOUND()
IF llDoc100Spart AND llDoc102Nesparte AND llDoc103Nesparte
DO ArLog WITH 'PASS verificare3 (runda4c spargere doar principala): doc 100/RAJA spart (rand S gasit), doc 102/103 raman B/T nesparte'
LOCATE FOR nract = 102 AND tip_rand == 'S'
llDoc102Spart = FOUND()
LOCATE FOR nract = 103 AND tip_rand == 'S'
llDoc103Spart = FOUND()
IF llDoc100Spart AND llDoc102Spart AND llDoc103Spart
DO ArLog WITH 'PASS verificare3 (lSpargeSecundare implicit): doc 100/102/103 toate sparte (rand S gasit pe fiecare)'
ELSE
DO ArLog WITH 'FAIL verificare3 (runda4c spargere doar principala): doc100Spart=' + TRANSFORM(llDoc100Spart) + ' (astept .T.) doc102Nesparte=' + TRANSFORM(llDoc102Nesparte) + ' (astept .T.) doc103Nesparte=' + TRANSFORM(llDoc103Nesparte) + ' (astept .T.)'
DO ArLog WITH 'FAIL verificare3 (lSpargeSecundare implicit): doc100Spart=' + TRANSFORM(llDoc100Spart) + ' (astept .T.) doc102Spart=' + TRANSFORM(llDoc102Spart) + ' (astept .T.) doc103Spart=' + TRANSFORM(llDoc103Spart) + ' (astept .T.)'
ENDIF
*========================= PAS 2: dupa sincronizeaza() =========================
@@ -691,8 +690,8 @@ PROCEDURE CreeazaIntrodc
nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), ;
scd_orig C(20), ascd_orig C(20))
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), expl_manual N(1), ;
scd_orig C(20), ascd_orig C(20), rand_dvi N(1), valuta_proprie N(1))
ENDPROC
PROCEDURE VerificaPereche

View File

@@ -254,7 +254,7 @@ TRY
*-- index ord_doc INAINTE de CREATEOBJECT - vezi docs/testare-ui-vfp.md capcana p.
SELECT introdc
INDEX ON Str(Nvl(nr_doc,0),8) + Icase(tip_rand='B','1', tip_rand='S','2', tip_rand='T','3', tip_rand='D','4', '5') + Padr(Nvl(scd,''),10) TAG ord_doc
INDEX ON Str(Nvl(nr_doc,0),8) + Icase(tip_rand='B','1', tip_rand='S','2', tip_rand='G','3', tip_rand='T','4', tip_rand='D','5', '6') + Padr(Nvl(scd,''),10) TAG ord_doc
SET ORDER TO ord_doc
DO ApLog WITH 'cursoare pregatite, CREATEOBJECT(import_nota, .F.) - lIntern=.F. (import)'
@@ -566,8 +566,8 @@ PROCEDURE CreeazaIntrodc
nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), ;
scd_orig C(20), ascd_orig C(20))
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), expl_manual N(1), ;
scd_orig C(20), ascd_orig C(20), rand_dvi N(1), valuta_proprie N(1))
ENDPROC
PROCEDURE DumpIntrodc

View File

@@ -281,8 +281,8 @@ poAct.AddProperty('id_valuta', 1)
nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), ;
scd_orig C(20), ascd_orig C(20))
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), expl_manual N(1), ;
scd_orig C(20), ascd_orig C(20), rand_dvi N(1), valuta_proprie N(1))
INSERT INTO introdc (tip_rand, scd, scc, ascc, suma, suma_val, id_jtva_coloana, ptva, explicatie_tva, ;
in_valuta, participa_valuta, id_valuta, curs, nume_val, nr_doc, nract, serie_act, fdoc, partc, explicatia, ;

View File

@@ -0,0 +1,670 @@
* test_diag_controlsource_calificat.prg
* REGRESIE (initial diagnostic - a demonstrat un ocolire a gardei, acum fixata): izoleaza
* copiaza_valoare() de dialog/sparge_document, insert direct in introdc - doua randuri,
* acelasi doc_key: B nract=15000/id_fdoc=1/id_partc=601, T-DVI nract=101/id_fdoc=2/
* id_partc=900/rand_dvi=1.
*
* Context: This.Parent.ControlSource (folosit de Grid1.cNract/cDataAct/cSerie_act.Text1.Valid
* ca argument pentru Thisform.copiaza_valoare) e "nract" la design-time in .vcx, dar la
* runtime VFP il rescrie calificat cu alias-ul RecordSource-ului grid-ului ("introdc.nract").
* Garda din copiaza_valoare (COMUN\clase\ointroduceri.vcx) normalizeaza acum tcCamp la numele
* de camp BAR (dupa ultimul punct) inainte de Inlist - testul verifica DIRECT ca garda
* blocheaza propagarea de pe randul T-DVI (sursa) atat pe drumul real (Grid1.cNract/
* cDataAct.Text1.Valid()), cat si prin apel direct cu literalul 'nract'. Grid1.cPartC.
* Text1.Valid NU foloseste copiaza_valoare (are logica proprie, verificari directe pe
* rand_dvi) - neafectat de aceasta problema, testat separat in test_repro_trigger_partener.prg.
*
* Rulare:
* powershell -ExecutionPolicy Bypass -File test_diag_controlsource_calificat.ps1
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET DECIMALS TO 4
SET NULLDISPLAY TO ''
CLOSE DATABASES
PUBLIC gcUILog, gcSyncDir
gcUILog = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\test_diag_controlsource_calificat_log.txt"
gcSyncDir = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\uisync_diag_controlsource_calificat\"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcUILog)
ON ERROR DO EeErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
TRY
LOCAL gcAppPath, lcPath
gcAppPath = "D:\ROA\ROAGEST\"
SET DEFAULT TO (gcAppPath)
lcPath = gcAppPath + 'COMUN\Utile\Teste\achizitie_import\stub_verificare;' + ;
gcAppPath + 'Date;' + gcAppPath + 'Include;' + gcAppPath + 'FERESTRE;' + ;
gcAppPath + 'GRAFICE;' + gcAppPath + 'CLASE;' + gcAppPath + 'MENIURI;' + ;
gcAppPath + 'PROGRAME;' + gcAppPath + 'RAPOARTE;' + gcAppPath + 'COMUN;' + ;
gcAppPath + 'COMUN\CLASE;' + gcAppPath + 'COMUN\FERESTRE;' + gcAppPath + 'COMUN\PROGRAME;' + ;
gcAppPath + 'COMUN\GRAFICE;' + gcAppPath + 'COMUN\RAPOARTE;' + gcAppPath + 'COMUN\MENIURI;' + ;
gcAppPath + 'COMUN\UTILE\GRIDEXTRAS;' + gcAppPath + 'COMUN\UTILE\CTL32;' + ;
gcAppPath + 'COMUN\UTILE\HPDF;' + gcAppPath + 'COMUN\UTILE\HPDF\REPORTOUTPUT;' + ;
gcAppPath + 'COMUN\UTILE\WEB;' + gcAppPath + 'COMUN\UTILE\EXCEL;' + ;
ADDBS(SUBSTR(gcAppPath,1,RAT([\],gcAppPath,2)))+[COMUNROA\]
SET PATH TO &lcPath ADDITIVE
DO EeLog WITH 'SET PATH OK'
*----- CLASE -----
SET CLASSLIB TO (gcAppPath + "comun\clase\appwiz") ADDITIVE
SET CLASSLIB TO GESTIUNI ADDITIVE
SET CLASSLIB TO CAUT ADDITIVE
SET CLASSLIB TO BAZA ADDITIVE
SET CLASSLIB TO comun ADDITIVE
SET CLASSLIB TO accessibility.vcx ADDITIVE
SET CLASSLIB TO messagebox ADDITIVE
SET CLASSLIB TO registry ADDITIVE
SET CLASSLIB TO cauta_alfa_forms.vcx ADDITIVE
SET CLASSLIB TO DECABAZA ADDITIVE
SET CLASSLIB TO onomenclatoare ADDITIVE
SET CLASSLIB TO stocuri.vcx ADDITIVE
SET CLASSLIB TO rulaje.vcx ADDITIVE
SET CLASSLIB TO ointroduceri ADDITIVE
SET CLASSLIB TO ointroduceri_web ADDITIVE
SET CLASSLIB TO ointroduceri_depozit ADDITIVE
SET CLASSLIB TO overificari ADDITIVE
SET CLASSLIB TO ferestre_oracle ADDITIVE
SET CLASSLIB TO ferestre_cere_date.vcx ADDITIVE
SET CLASSLIB TO configurare.vcx ADDITIVE
SET CLASSLIB TO serii_numere.vcx ADDITIVE
SET CLASSLIB TO omodificari.vcx ADDITIVE
SET CLASSLIB TO ocompensari.vcx ADDITIVE
SET CLASSLIB TO caut_ora ADDITIVE
SET CLASSLIB TO onote_contabile ADDITIVE
SET CLASSLIB TO otoolbar ADDITIVE
SET CLASSLIB TO bon_fisc ADDITIVE
SET CLASSLIB TO onom_articole ADDITIVE
SET CLASSLIB TO onom_retete ADDITIVE
SET CLASSLIB TO orapoarte ADDITIVE
SET CLASSLIB TO orapoarte_gestiuni ADDITIVE
SET CLASSLIB TO orapoarte_parametri ADDITIVE
SET CLASSLIB TO ONOM_CURS ADDITIVE
SET CLASSLIB TO ctl32_statusbar_fals.vcx ADDITIVE
SET CLASSLIB TO ctl32_common.vcx ADDITIVE
SET CLASSLIB TO ctl32_structs.vcx ADDITIVE
SET CLASSLIB TO ctl32_progressbar.vcx ADDITIVE
SET CLASSLIB TO ctl32_balloontip.vcx ADDITIVE
SET CLASSLIB TO ocriterii.vcx ADDITIVE
SET CLASSLIB TO oavize.vcx ADDITIVE
SET CLASSLIB TO onomenclatoare2 ADDITIVE
SET CLASSLIB TO wwdialogs.vcx ADDITIVE
SET CLASSLIB TO oimportxml.vcx ADDITIVE
SET CLASSLIB TO excelxml.vcx ADDITIVE
SET CLASSLIB TO orapoarte_obinv.vcx ADDITIVE
DO EeLog WITH 'SET CLASSLIB OK'
*----- PROCEDURI (mock-uri PRIMELE, ui_harness la final) -----
SET PROCEDURE TO PROCEDURI
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\mock_caut_valuta.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_cauta_nom_articole.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\mock_oscrie_in_fisiere.prg" ADDITIVE
SET PROCEDURE TO acces_meniu ADDITIVE
SET PROCEDURE TO cauta_alfa ADDITIVE
SET PROCEDURE TO pmenu ADDITIVE
SET PROCEDURE TO proceduri_comune ADDITIVE
SET PROCEDURE TO quitapp ADDITIVE
SET PROCEDURE TO init_program ADDITIVE
SET PROCEDURE TO oproceduri_listari.prg ADDITIVE
SET PROCEDURE TO oproceduri_configurare.prg ADDITIVE
SET PROCEDURE TO oproceduri_articole.prg ADDITIVE
SET PROCEDURE TO oproceduri_retete.prg ADDITIVE
SET PROCEDURE TO orapoarte.prg ADDITIVE
SET PROCEDURE TO mesaje ADDITIVE
SET PROCEDURE TO oserii_numere.prg ADDITIVE
SET PROCEDURE TO oexport.prg ADDITIVE
SET PROCEDURE TO wwConfig.prg ADDITIVE
SET PROCEDURE TO proceduri_rapoarte.prg ADDITIVE
SET PROCEDURE TO OPROCEDURI_CURS.PRG ADDITIVE
SET PROCEDURE TO validare.prg ADDITIVE
SET PROCEDURE TO GENCURSOR.PRG ADDITIVE
SET PROCEDURE TO OPROCEDURI_COMUNE.PRG ADDITIVE
SET PROCEDURE TO OINIT_OPTIUNI.PRG ADDITIVE
SET PROCEDURE TO updateserver.prg ADDITIVE
SET PROCEDURE TO oinainte_de.prg ADDITIVE
SET PROCEDURE TO ooperatii_comune.prg ADDITIVE
SET PROCEDURE TO Ocompensari.PRG ADDITIVE
SET PROCEDURE TO OPROCEDURI_aMS.PRG ADDITIVE
SET PROCEDURE TO oproceduri_rulaje ADDITIVE
SET PROCEDURE TO oproceduri_stocuri ADDITIVE
SET PROCEDURE TO OINTRODUCERI ADDITIVE
SET PROCEDURE TO oHeader.prg ADDITIVE
SET PROCEDURE TO proceduri_excel.PRG ADDITIVE
SET PROCEDURE TO onomenclatoare.PRG ADDITIVE
SET PROCEDURE TO osecurity ADDITIVE
SET PROCEDURE TO ocautare ADDITIVE
SET PROCEDURE TO orefaceri ADDITIVE
SET PROCEDURE TO ofacturare_comun.PRG ADDITIVE
SET PROCEDURE TO ofacturare_stoc.PRG ADDITIVE
SET PROCEDURE TO oproceduri_casademarcat ADDITIVE
SET PROCEDURE TO oproceduri_casa_marcat_e500 ADDITIVE
SET PROCEDURE TO oproceduri_casa_marcat_mp500 ADDITIVE
SET PROCEDURE TO oproceduri_util.prg ADDITIVE
SET PROCEDURE TO wwxmlhttp.prg ADDITIVE
SET PROCEDURE TO ini.prg ADDITIVE
SET PROCEDURE TO odocumente.prg ADDITIVE
SET PROCEDURE TO regex.prg ADDITIVE
SET PROCEDURE TO wwutils.prg ADDITIVE
SET PROCEDURE TO inchidere_k ADDITIVE
SET PROCEDURE TO iniacces.prg ADDITIVE
SET PROCEDURE TO oupdate.prg ADDITIVE
SET PROCEDURE TO procese.prg ADDITIVE
SET PROCEDURE TO version.prg ADDITIVE
SET PROCEDURE TO xmlaccess.prg ADDITIVE
SET PROCEDURE TO xmlparser.prg ADDITIVE
SET PROCEDURE TO filebringer.prg ADDITIVE
SET PROCEDURE TO wwcodeupdate.prg ADDITIVE
SET PROCEDURE TO wwhttp.prg ADDITIVE
SET PROCEDURE TO xdate.prg ADDITIVE
SET PROCEDURE TO ofacturare.prg ADDITIVE
SET PROCEDURE TO oproceduri_obinv.prg ADDITIVE
SET PROCEDURE TO oproceduri_facturare.prg ADDITIVE
SET PROCEDURE TO email.prg ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\ui_harness.prg" ADDITIVE
DO EeLog WITH 'SET PROCEDURE OK'
*----- Globale -----
PUBLIC gnPc, gnPval, gnPcant, gnPpret, gnPPretval, gnPCurs, gnPVal, gnPPretV, gnPPretVal
STORE 2 TO gnPc, gnPval, gnPVal
gnPcant = 3
STORE 4 TO gnPpret, gnPPretval, gnPPretVal, gnPPretV, gnPCurs
PUBLIC gl406, gcS, gnAn, gnLuna, gnIdFirma, gnIdSucursala, gcAcces, gcFirma
gl406 = .T.
gcS = 'CONTAFIN'
gnAn = YEAR(DATE())
gnLuna = MONTH(DATE())
gnIdFirma = 110
gnIdSucursala = 110
gcAcces = "1;2;3;4;5;6;7;8;"
gcFirma = gcS
PUBLIC nror(65000)
PUBLIC gnMockRaspuns, gcMockUltimMesaj, gnMockUltimTip, gcMockArtCodmat
gnMockRaspuns = 6
gcMockUltimMesaj = ''
gnMockUltimTip = 0
PUBLIC gnButon
gnButon = 1
gcMockArtCodmat = ''
PUBLIC goExecutor, goApp
goExecutor = CREATEOBJECT('dummyexecutor')
goApp = CREATEOBJECT('dummyapp')
*----- poAct: antetul notei (factura import EUR, curs 5.23) -----
PUBLIC poAct
poAct = CREATEOBJECT('Custom')
poAct.AddProperty('nume_val', 'EUR')
poAct.AddProperty('curs', 5.23)
poAct.AddProperty('proc_tva', 1.21)
poAct.AddProperty('nnir', 0)
poAct.AddProperty('id_valuta', 978)
poAct.AddProperty('id_fdoc', 1)
poAct.AddProperty('fdoc', 'Factura')
poAct.AddProperty('id_partc', 601)
poAct.AddProperty('partc', 'FURNIZOR EXTERN GMBH')
poAct.AddProperty('serie_act', '')
poAct.AddProperty('dataact', DATE())
poAct.AddProperty('tva_incasare', 0)
poAct.AddProperty('id_set', 1)
poAct.AddProperty('id_gestin', 1)
*----- jtva_coloane2 / saft_taxtable: perechi reale 21% (achizitii interne + import) -----
IF USED('jtva_coloane2')
USE IN ('jtva_coloane2')
ENDIF
CREATE CURSOR jtva_coloane2 (ordine N(8), id_jtva_coloana N(14), denumire C(100), ;
jc N(1), jv N(1), afisat N(1), coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14))
INSERT INTO jtva_coloane2 VALUES (0, 0, '', 0, 0, 1, '', '', 0, 0)
INSERT INTO jtva_coloane2 VALUES (1, 208, 'ACH. INT. 21%', 1, 0, 1, 'RO21B', 'RO21T', 21, 209)
INSERT INTO jtva_coloane2 VALUES (2, 209, 'TVA ACH. INT. 21%', 1, 0, 1, 'RO21T', '', 21, 0)
INSERT INTO jtva_coloane2 VALUES (3, 220, 'ACH. IMP. 21%', 1, 0, 1, 'FO21B', 'FO21T', 21, 221)
INSERT INTO jtva_coloane2 VALUES (4, 221, 'TVA ACH. IMP. 21%', 1, 0, 1, 'FO21T', '', 21, 0)
IF USED('saft_taxtable')
USE IN ('saft_taxtable')
ENDIF
CREATE CURSOR saft_taxtable (taxname C(250) NULL, typename C(250) NULL, taxcode N(6) NULL, ;
taxtype N(3) NULL, descriere C(250) NULL, tip C(100) NULL, descriere_tip C(250) NULL, ;
procent_taxa N(7,2) NULL, procent_prorata N(7,2) NULL, inactiv N(1) NULL, tva N(1) NULL, ;
wht N(1) NULL, tva_achizitii N(1) NULL, tva_livrari N(1) NULL)
INDEX ON taxcode TAG taxcode
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('', 0, '', 0, 1, 1, 1, 1)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301204-Import de bunuri cota 21%', 301204, '', 21, 1, 0, 1, 0)
DO CreeazaIntrodc WITH 'introdc'
DO CreeazaIntrodc WITH 'introdc_sablon'
INSERT INTO introdc_sablon (scd, scc, cu_tva, ordine, id_set, participa_valuta, tip_rand, ;
id_jtva_coloana, ptva, explicatie_tva) ;
VALUES ('371', '401', 1, 1, 1, .T., 'B', 208, 21, 'ACH. INT. 21%')
INSERT INTO introdc_sablon (scd, scc, cu_tva, ordine, id_set, participa_valuta, tip_rand, ;
id_jtva_coloana, ptva, explicatie_tva) ;
VALUES ('4426', '401', 1, 2, 1, .T., 'T', 209, 21, 'TVA ACH. INT. 21%')
GO TOP IN introdc_sablon
DO CreeazaRulTemp
INSERT INTO rul_temp (denumire, codmat, cant, pret, pret_lei, cont, cota_tva) ;
VALUES ('PLACEHOLDER', 'PH', 1, 1, 1, '371', 21)
*-- index ord_doc INAINTE de CREATEOBJECT (capcana p, docs/testare-ui-vfp.md)
SELECT introdc
INDEX ON Str(Nvl(nr_doc,0),8) + Icase(tip_rand='B','1', tip_rand='S','2', tip_rand='G','3', tip_rand='T','4', tip_rand='D','5', '6') + Padr(Nvl(scd,''),10) TAG ord_doc
SET ORDER TO ord_doc
*-- vezi antetul test_e2e_dvi_ron_discount.prg: tlIntern BARA, aceeasi valoare ca la CREATEOBJECT
PRIVATE tlIntern
tlIntern = .F.
PUBLIC gcTempPath
gcTempPath = ADDBS(SYS(2023))
PUBLIC gnHandle
gnHandle = -1
PUBLIC gnTipGest
gnTipGest = 0
PUBLIC gcCondSucursala
gcCondSucursala = ''
DO EeLog WITH 'cursoare pregatite, CREATEOBJECT(import_nota, .F. - mod import)'
PUBLIC goObj
goObj = CREATEOBJECT('IMPORT_nota', .F.)
IF VARTYPE(goObj) <> 'O'
DO EeLog WITH 'FAIL: instantiere import_nota'
DO HarnessDone WITH 'done-error'
QUIT
ENDIF
goObj.lDialogAratat = .T.
goObj.oact = poAct
goObj.lSpargeSecundare = .F.
goObj.WindowType = 0
goObj.Visible = .T.
goObj.Show()
goObj.WindowState = 2
DOEVENTS FORCE
SELECT rul_temp
ZAP
goObj.gridart.Refresh()
DOEVENTS FORCE
PRIVATE pnAsserts, pnPass
STORE 0 TO pnAsserts, pnPass
DO HarnessStep WITH 0, 'nota goala afisata, mod import (.F.)'
*========================= DIAGNOSTIC: insert DIRECT (fara dialog), izoleaza copiaza_valoare() =========================
*-- doua randuri, ACELASI doc_key: B (nract=15000/id_fdoc=1/id_partc=601) si T-DVI
*-- (nract=101/id_fdoc=2/id_partc=900, rand_dvi=1) - minim necesar ca sa testam DOAR garda
*-- din copiaza_valoare(), fara sparge_document/sincronizare/dialog in cale.
SELECT introdc
APPEND BLANK
REPLACE nract WITH 15000, id_fdoc WITH 1, id_partc WITH 601, serie_act WITH '', ;
tip_rand WITH 'B', nr_doc WITH 1, scd WITH '371', scc WITH '401', suma WITH 5000, ;
rand_dvi WITH 0, dataact WITH {^2026-07-20}
APPEND BLANK
REPLACE nract WITH 101, id_fdoc WITH 2, id_partc WITH 900, serie_act WITH '', ;
tip_rand WITH 'T', nr_doc WITH 1, scd WITH '4426', scc WITH '401', suma WITH 900, ;
rand_dvi WITH 1, dataact WITH {^2026-07-25}
*-- doc_key IDENTIC pe ambele randuri (T-DVI pastreaza doc_key-ul MAMEI, calculat pe baza
*-- identitatii facturii B - la fel ca in do_adauga_factura, unde Replace doc_key se face
*-- INAINTE de suprascrierea cu identitatea vamala pe randul T)
LOCAL lcDocKeyComun
SELECT introdc
GO TOP
lcDocKeyComun = goObj.calc_doc_key()
REPLACE ALL doc_key WITH lcDocKeyComun
GO TOP
DO DumpIntrodc WITH 'DUMP inainte de copiaza_valoare (insert direct, fara dialog)'
DO HarnessStep WITH 1, 'randuri B/T-DVI inserate direct, acelasi doc_key'
*========================= TRIGGER: pointerul pe randul T-DVI, copiaza_valoare('nract') DIRECT =========================
SELECT introdc
LOCATE FOR Nvl(rand_dvi,0) = 1
=Assert3('17-pozitionare pe randul T-DVI reusita (inainte de trigger)', IIF(FOUND(),1,0), 1)
LOCAL llTriggerOk
llTriggerOk = .F.
IF FOUND()
DO EeLog WITH 'DEBUG Grid1.cNract.ControlSource=[' + goObj.Grid1.cNract.ControlSource + '] LEN=' + TRANSFORM(LEN(goObj.Grid1.cNract.ControlSource)) + ' vs literal [nract] LEN=' + TRANSFORM(LEN('nract'))
DO EeLog WITH 'DEBUG Grid1.cDataAct.ControlSource=[' + goObj.Grid1.cDataAct.ControlSource + '] LEN=' + TRANSFORM(LEN(goObj.Grid1.cDataAct.ControlSource))
DO EeLog WITH 'DEBUG Grid1.cSerie_act.ControlSource=[' + goObj.Grid1.cSerie_act.ControlSource + '] LEN=' + TRANSFORM(LEN(goObj.Grid1.cSerie_act.ControlSource))
goObj.Grid1.cNract.Text1.Valid()
llTriggerOk = .T.
ENDIF
DOEVENTS FORCE
=Assert3('18-TRIGGER executat fara eroare', IIF(llTriggerOk,1,0), 1)
DO EeLog WITH 'TRIGGER folosit: Grid1.cNract.Text1.Valid()'
DO DumpIntrodc WITH 'DUMP dupa TRIGGER (copiaza_valoare direct, pointer pe T-DVI)'
*========================= TRIGGER 2: acelasi izolat, dar pe coloana Data (cDataAct) =========================
*-- randul B primeste si el o data (diferita de T-DVI), ca sa se poata verifica propagarea
SELECT introdc
GO 1
REPLACE dataact WITH {^2026-07-20}
GO 2
REPLACE dataact WITH {^2026-07-25}
GO 2
LOCAL llTrigger2Ok
llTrigger2Ok = .F.
goObj.Grid1.cDataAct.Text1.Valid()
llTrigger2Ok = .T.
DOEVENTS FORCE
=Assert3('19-TRIGGER 2 (cDataAct) executat fara eroare', IIF(llTrigger2Ok,1,0), 1)
DO DumpIntrodc WITH 'DUMP dupa TRIGGER 2 (cDataAct.Valid, pointer pe T-DVI)'
GO 1 IN introdc
pnAsserts = pnAsserts + 1
IF introdc.dataact == {^2026-07-20}
pnPass = pnPass + 1
DO EeLog WITH ' PASS 20-randul B (dataact) NESCHIMBAT dupa TRIGGER 2 (=' + DTOC(introdc.dataact) + ')'
ELSE
DO EeLog WITH ' FAIL 20-randul B (dataact) a devenit ' + DTOC(introdc.dataact) + ' dupa TRIGGER 2 (asteptat 20.07.2026)'
ENDIF
*========================= ASSERT-URI DUPA TRIGGER: nract pe B trebuie sa RAMANA 15000 =========================
LOCAL llBugG, llBugS, lnCntSVerif
llBugG = .F.
llBugS = .F.
SELECT introdc
LOCATE FOR tip_rand == 'B' AND Nvl(rand_dvi,0) <> 1
IF FOUND()
pnAsserts = pnAsserts + 1
IF nract == 15000
pnPass = pnPass + 1
DO EeLog WITH ' PASS 20-B.nract ramane 15000 dupa trigger (=' + TRANSFORM(nract) + ')'
ELSE
llBugG = .T.
DO EeLog WITH ' FAIL 20-B.nract dupa trigger = ' + TRANSFORM(nract) + ' (asteptat 15000) -> BUG'
ENDIF
ELSE
pnAsserts = pnAsserts + 1
DO EeLog WITH ' FAIL 20: randul B negasit dupa trigger'
ENDIF
*-- randul T-DVI insusi trebuie sa ramana 101 (sursa neschimbata de propriul apel)
SELECT introdc
LOCATE FOR Nvl(rand_dvi,0) = 1
=Assert3('22-T-DVI.nract ramane 101 (randul sursa neschimbat)', IIF(FOUND(), nract, -1), 101)
*-- doc_key: NU trebuie regenerat (llSursaProtejata blocheaza si regenerarea de doc_key)
LOCAL lcDocKeyB, lcDocKeyT
SELECT introdc
LOCATE FOR tip_rand == 'B'
lcDocKeyB = ALLTRIM(NVL(doc_key,''))
LOCATE FOR Nvl(rand_dvi,0) = 1
lcDocKeyT = ALLTRIM(NVL(doc_key,''))
pnAsserts = pnAsserts + 1
IF lcDocKeyB == lcDocKeyT
pnPass = pnPass + 1
DO EeLog WITH ' PASS 25-doc_key B si T-DVI raman identice dupa trigger ([' + lcDocKeyB + '])'
ELSE
DO EeLog WITH ' FAIL 25-doc_key B=[' + lcDocKeyB + '] <> doc_key T-DVI=[' + lcDocKeyT + '] dupa trigger'
ENDIF
LOCAL llBugSDupaSync2
llBugSDupaSync2 = .F.
DO HarnessStep WITH 2, 'final: ' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' PASS'
DO EeLog WITH '========================================================='
IF llBugG OR llBugS OR llBugSDupaSync2
DO EeLog WITH 'BUG CONFIRMAT: nract-ul randului T-DVI (101) s-a propagat peste nract-ul' + ;
' randurilor B/G/S ale facturii principale (asteptat 15000) dupa ce Valid()/' + ;
'copiaza_valoare() a rulat cu pointerul pe randul T-DVI.'
ELSE
DO EeLog WITH 'BUG NECONFIRMAT: nract-ul randurilor B/G/S a ramas 15000 dupa trigger si dupa re-sincronizare.'
ENDIF
DO EeLog WITH '========================================================='
DO EeLog WITH 'REZULTAT: ' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' assert-uri PASS'
IF pnPass = pnAsserts
DO EeLog WITH 'REZULTAT: PASS (' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ')'
ELSE
DO EeLog WITH 'REZULTAT: FAIL (' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' assert-uri PASS)'
ENDIF
DO HarnessDone WITH 'done'
CATCH TO loExc
DO EeLog WITH 'CATCH ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']'
DO HarnessDone WITH 'done-error'
ENDTRY
QUIT
*==================================================================================
PROCEDURE DumpIntrodc
LPARAMETERS tcTitlu
LOCAL lcSelAnt, lnRecAnt
lcSelAnt = SELECT()
lnRecAnt = IIF(USED('introdc'), IIF(EOF('introdc') OR BOF('introdc'), 0, RECNO('introdc')), 0)
DO EeLog WITH tcTitlu
IF !USED('introdc')
DO EeLog WITH ' (introdc neinstantiat)'
RETURN
ENDIF
SELECT introdc
SCAN
DO EeLog WITH ' tip_rand=' + ALLTRIM(NVL(tip_rand,'?')) + ' nract=' + TRANSFORM(NVL(nract,0)) + ;
' doc_key=[' + ALLTRIM(NVL(doc_key,'')) + '] rand_dvi=' + TRANSFORM(NVL(rand_dvi,0)) + ;
' scd=' + ALLTRIM(NVL(scd,'')) + ' scc=' + ALLTRIM(NVL(scc,'')) + ' suma=' + TRANSFORM(NVL(suma,0))
ENDSCAN
IF lnRecAnt > 0
TRY
GO lnRecAnt
CATCH
GO TOP
ENDTRY
ENDIF
SELECT (lcSelAnt)
ENDPROC
PROCEDURE CreeazaIntrodc
*-- coloane rand_dvi N(1), valuta_proprie N(1) (rand_dvi = randul T-DVI)
LPARAMETERS tcAlias
IF USED(tcAlias)
USE IN (tcAlias)
ENDIF
CREATE CURSOR (tcAlias) ( ;
id_note N(14), explicatia C(100), scd C(10), ascd C(20), scc C(10), ascc C(20), ;
cu_tva N(1), id_set N(14), ordine N(8), in_valuta N(1), id_jtva_coloana N(14) NULL, ;
ptva N(6,2), explicatie_tva C(50), tipjurnal C(2), taxcode N(6), paymentcode C(9), ;
suma N(18,4), suma_val N(18,4), id_partd N(14), id_partc N(14), partd C(100), partc C(100), ;
id_fact N(14), id_factd N(14), id_factc N(14), pereched N(14), perechec N(14), ;
nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), expl_manual N(1), ;
scd_orig C(20), ascd_orig C(20), rand_dvi N(1), valuta_proprie N(1))
ENDPROC
PROCEDURE CreeazaRulTemp
IF USED('rul_temp')
USE IN ('rul_temp')
ENDIF
CREATE CURSOR rul_temp ( ;
id_rul N(20,0), an N(4,0), luna N(2,0), cod N(20,0);
, serie C(100), nnir N(20,0), id_articol N(10,0), denumire C(100);
, codmat C(50), codmatf C(50), codbare C(50), um C(20);
, id_gestiune N(5,0), nume_gestiune C(50), cgest C(20), nr_pag N(2,0);
, gestionar C(50), comisie_receptie1 C(50), comisie_receptie2 C(50), comisie_receptie3 C(50);
, cant N(14,3), cante N(14,3), cont C(10), acont C(20);
, pret N(18,4), tva N(18,4), valoare N(18,4), valtva N(18,4);
, proc_tva N(5,2), pretv N(18,4), pretvtva N(18,4), tvav N(18,4);
, valoarev N(18,4), valtvav N(18,4), proc_tvav N(5,2), adaos N(18,4);
, adaos_tva N(18,4), valoare_adaos N(18,4), valtva_adaos N(18,4), procent N(10,3);
, discunitar N(18,4), discount_tva N(18,4), valoare_discount N(18,4), valtva_discount N(18,4);
, proc_disc N(7,3), pretd N(14,4), curs N(18,4), id_valuta N(10,0);
, nume_val C(20), id_lucrare N(20,0), nrord C(100), id_responsabil N(10,0);
, nresp C(100), resp_marca N(18,4), dataact T, id_util N(5,0);
, util C(30), dataora T, id_sectie N(5,0), sectie C(50);
, csectie C(10), alcooltutun N(1,0), datain T, dataout T;
, id_fact N(20,0), id_gestiunec N(10,0), nume_gestiunec C(50), cgestc C(20);
, id_responsabilc N(5,0), id_reteta N(10,0), reteta C(50), nrespc C(100);
, respc_marca N(18,4), id_set N(20,0), id_tip_rulaj N(10,0), tip_rulaj C(50);
, id_obiect_depozit N(10,0), id_rul_aux N(10,0), nract N(20,0), serie_act C(10);
, dataoras T, id_utils N(10,0), lot C(30), adata_expirare T;
, id_sucursala N(5,0), sucursala C(250), id_part_rez N(10,0), part_rez C(100);
, id_lucrare_rez N(10,0), nrord_rez C(100), subgrupa C(100), grupa C(100);
, id_subgrupa N(5,0), id_grupa N(5,0), in_stoc N(1,0), in_crm N(1,0);
, id_furnizor N(10,0), furnizor C(100), id_jtva_coloana N(4,0), explicatie_tva C(100);
, taxcode N(6,0), taxname C(254), saft_procent N(18,4), codnc8 C(20);
, id_tara_origine N(4,0), cod_tara_origine C(5), tara_origine C(50), greutate N(12,4);
, fdoc C(30), id_fdoc N(18,4);
, pret_lei N(18,4), pret_val N(14,4), cota_tva N(6,2))
ENDPROC
FUNCTION RECCOUNT_ACTIVE
LPARAMETERS tcAlias
LOCAL lnSel, lnCnt
lnSel = SELECT()
SELECT (tcAlias)
COUNT TO lnCnt FOR !DELETED()
SELECT (lnSel)
RETURN lnCnt
ENDFUNC
PROCEDURE Assert3
LPARAMETERS tcLabel, tuActual, tuExpected
pnAsserts = pnAsserts + 1
IF ABS(NVL(tuActual,0) - tuExpected) < 0.02
pnPass = pnPass + 1
DO EeLog WITH ' PASS ' + tcLabel + ' (=' + TRANSFORM(tuActual) + ')'
ELSE
DO EeLog WITH ' FAIL ' + tcLabel + ' (actual=' + TRANSFORM(tuActual) + ' asteptat=' + TRANSFORM(tuExpected) + ')'
ENDIF
ENDPROC
PROCEDURE AssertStr
LPARAMETERS tcLabel, tcActual, tcExpected
pnAsserts = pnAsserts + 1
IF tcActual == tcExpected
pnPass = pnPass + 1
DO EeLog WITH ' PASS ' + tcLabel + ' (=[' + tcActual + '])'
ELSE
DO EeLog WITH ' FAIL ' + tcLabel + ' (actual=[' + tcActual + '] asteptat=[' + tcExpected + '])'
ENDIF
ENDPROC
PROCEDURE EeErr
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
DO EeLog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
ENDPROC
PROCEDURE EeLog
LPARAMETERS tcMsg
SET SAFETY OFF
LOCAL lcL
lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '')
STRTOFILE(lcL + tcMsg + CHR(13)+CHR(10), gcUILog)
ENDPROC
DEFINE CLASS dummyapp AS Custom
PROCEDURE ReadIni
LPARAMETERS tcSection, tcKey
RETURN ''
ENDPROC
PROCEDURE WriteIni
LPARAMETERS tcSection, tcKey, tcValue
RETURN .T.
ENDPROC
ENDDEFINE
DEFINE CLASS dummyexecutor AS Custom
cEroare = ''
PROCEDURE oExecute
LPARAMETERS tcSql, tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF 'VJTVA_COLOANE' $ UPPER(m.tcSql)
DO CreeazaJtvaColoaneView WITH m.tcCursor
RETURN 1
ENDIF
IF UPPER(ALLTRIM(m.tcCursor)) == 'RUL_TEMP'
CREATE CURSOR (m.tcCursor) (denumire C(100), codmat C(30), cant N(14,3), ;
pret_val N(18,4), pretd N(18,4), pret N(18,4), pret_lei N(18,4), cont C(10), ;
acont C(20), serie C(30), lot C(30), adata_expirare C(10), proc_disc N(6,2), cota_tva N(6,2))
RETURN 1
ENDIF
IF 'CONFIG_ANALITICE' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (camp_leg_prefix C(30), camp_leg_sufix C(30))
INSERT INTO (m.tcCursor) VALUES ('', '')
RETURN 1
ENDIF
IF 'FCONTURI_ANALITICE' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (acont C(20))
INSERT INTO (m.tcCursor) VALUES (IIF(TYPE('gcMockAcontCrt') = 'C', gcMockAcontCrt, ''))
RETURN 1
ENDIF
IF 'VPLCONT_ANALITIC' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (cont C(10), acont C(20))
RETURN 1
ENDIF
IF 'VCONFIG_CONT_IREG' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (contpart C(10), fel_cont N(1), cu_inregistrari N(1), ;
explic_cont C(100), exceptie C(10), pozitie N(1), invers N(1), gasit N(1))
INSERT INTO (m.tcCursor) VALUES ('401', 0, 0, 'Furnizori', '', 0, 0, 0)
RETURN 1
ENDIF
CREATE CURSOR (m.tcCursor) (id_temp N(1))
RETURN 1
ENDPROC
PROCEDURE oExecuta
LPARAMETERS tcSql, tcCursor
IF !EMPTY(m.tcCursor)
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF UPPER(m.tcCursor) == 'CJTVACOL4427'
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14))
ELSE
CREATE CURSOR (m.tcCursor) (id_temp N(1))
ENDIF
ENDIF
RETURN .T.
ENDPROC
PROCEDURE oSelect2Value
LPARAMETERS tcSql, toValue
toValue = ''
RETURN 1
ENDPROC
PROCEDURE oReset
ENDPROC
ENDDEFINE
PROCEDURE CreeazaJtvaColoaneView
LPARAMETERS tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14), denumire C(100), jc N(1), jv N(1), ;
coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14) NULL, afisat N(1), ;
id_jtva_ex N(14) NULL, id_jtva_neex N(14) NULL, ordine N(8), ;
taxcode N(6) NULL, taxcode_neexigibil N(6) NULL, taxcode_n50 N(6) NULL, ;
taxcode_n50_tvai N(6) NULL, taxcode_n100 N(6) NULL, taxcode_regularizare N(6) NULL, taxcode_tvai N(6) NULL)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, afisat, ordine, cota_tva) VALUES (0, '', 0, 0, 1, 0, 0)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (208, 'ACH. INT. 21%', 1, 0, 'RO21B', 21, 209, 1, 1, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (209, 'TVA ACH. INT. 21%', 1, 0, 'RO21T', 21, 1, 2, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (220, 'ACH. IMP. 21%', 1, 0, 'FO21B', 21, 221, 1, 3, 301204)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (221, 'TVA ACH. IMP. 21%', 1, 0, 'FO21T', 21, 1, 4, 301204)
ENDPROC

View File

@@ -0,0 +1,15 @@
# test_diag_controlsource_calificat.ps1 - DIAGNOSTIC: izoleaza copiaza_valoare() de dialog/
# sparge_document, ca sa demonstreze ca garda noua (rand-sursa protejat, adaugata in fix)
# functioneaza CORECT cand tcCamp e literalul 'nract', dar e OCOLITA cand tcCamp vine din
# This.Parent.ControlSource al coloanei Grid1.cNract, pentru ca la runtime ControlSource
# devine "introdc.nract" (calificat cu alias-ul), nu "nract" (asa cum apare la design-time
# in .vcx) - vezi test_diag_controlsource_calificat_log.txt.
$ErrorActionPreference = 'Stop'
$Teste = $PSScriptRoot
& (Join-Path (Split-Path $Teste -Parent) 'vfp_ui_harness.ps1') `
-TestPrg (Join-Path $Teste 'test_diag_controlsource_calificat.prg') `
-Steps @('nota_goala','randuri_inserate','final') `
-ShotsDir (Join-Path $Teste 'screenshots_diag_controlsource_calificat') `
-SyncDir (Join-Path $Teste 'uisync_diag_controlsource_calificat') `
-StepTimeoutSec 180 `
-ReadyTimeoutSec 180

View File

@@ -0,0 +1,878 @@
* test_discount_factura.prg
* Runda32 (model B/G/T, plan docs/plan_runda32_discount_baza.md): discount financiar pe factura
* de import - UN SINGUR rand nou tip_rand='G' (acelasi doc_key/nr_doc cu factura), creat intre
* randul B si randul T:
* G: scd = contul 401 (cu analitic) preluat de pe CREDITUL randului B, scc='767', suma/
* suma_val = baza discount (POZITIVE), id_partd/partd = partenerul facturii (preluat de
* pe creditul B), participa_valuta=.F., cota/coloana de TVA ale bazei documentului,
* explicatia='DISCOUNT'.
* Randul T (4426/4427) se calculeaza pe baza NETA: T.suma = (B.suma - G.suma) * ptva/100,
* T.suma_val = (B.suma_val - G.suma_val) * ptva/100 - calculat automat de do_executa() (apelat
* din do_adauga_factura), nu necesita pas separat.
* Verifica: conturi/sume/semne/parteneri corecte pe G; ordinea fizica in cursor (Append Blank:
* B -> G -> T); T calculat pe baza neta; preturile articolelor si randul D neafectate; G
* supravietuieste sparge_document/uneste_document/sincronizeaza (nu doar la creare); stergere
* factura (document) sterge si discountul; variante discount=0 (fara G) si factura in RON
* (fara valuta).
*
* ASUMPTII (de confruntat cu implementarea reala):
* - toDlg poarta disc_baza_lei/disc_baza_val (fara are_discount/disc_tva_lei/disc_tva_val,
* eliminate in Runda32); discountul e activ cand Round(Nvl(toDlg.disc_baza_lei,0),gnPC)<>0;
* - G se scrie DUPA Endcase-ul ramurii de TVA (F/D/N), inainte de crearea randului T (plan
* pct. 6: ordinea devine B -> G -> T), clonat din randul B proaspat creat;
* - assert-ul pe actactan/inainte_de_do_termin (:9555 zona, !Inlist(tip_rand,'D','G')) e
* best-effort (TRY/CATCH) - harness-ul nu modeleaza integral scrierea reala in ACT/actactan;
* - grid-ul NU are index de sortare in productie (randurile noi se adauga la finalul
* cursorului) - verificarea de ordine se face pe RECNO fizic, imediat dupa creare, nu pe un
* index custom.
*
* Rulare:
* powershell -ExecutionPolicy Bypass -File test_discount_factura.ps1
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET DECIMALS TO 4
SET NULLDISPLAY TO ''
CLOSE DATABASES
PUBLIC gcUILog, gcSyncDir
gcUILog = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\test_discount_factura_log.txt"
gcSyncDir = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\uisync_discount_factura\"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcUILog)
ON ERROR DO DcErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
TRY
LOCAL gcAppPath, lcPath
gcAppPath = "D:\ROA\ROAGEST\"
SET DEFAULT TO (gcAppPath)
lcPath = gcAppPath + 'Date;' + gcAppPath + 'Include;' + gcAppPath + 'FERESTRE;' + ;
gcAppPath + 'GRAFICE;' + gcAppPath + 'CLASE;' + gcAppPath + 'MENIURI;' + ;
gcAppPath + 'PROGRAME;' + gcAppPath + 'RAPOARTE;' + gcAppPath + 'COMUN;' + ;
gcAppPath + 'COMUN\CLASE;' + gcAppPath + 'COMUN\FERESTRE;' + gcAppPath + 'COMUN\PROGRAME;' + ;
gcAppPath + 'COMUN\GRAFICE;' + gcAppPath + 'COMUN\RAPOARTE;' + gcAppPath + 'COMUN\MENIURI;' + ;
gcAppPath + 'COMUN\UTILE\GRIDEXTRAS;' + gcAppPath + 'COMUN\UTILE\CTL32;' + ;
gcAppPath + 'COMUN\UTILE\HPDF;' + gcAppPath + 'COMUN\UTILE\HPDF\REPORTOUTPUT;' + ;
gcAppPath + 'COMUN\UTILE\WEB;' + gcAppPath + 'COMUN\UTILE\EXCEL;' + ;
ADDBS(SUBSTR(gcAppPath,1,RAT([\],gcAppPath,2)))+[COMUNROA\]
SET PATH TO &lcPath ADDITIVE
DO DcLog WITH 'SET PATH OK'
*----- CLASE -----
SET CLASSLIB TO (gcAppPath + "comun\clase\appwiz") ADDITIVE
SET CLASSLIB TO GESTIUNI ADDITIVE
SET CLASSLIB TO CAUT ADDITIVE
SET CLASSLIB TO BAZA ADDITIVE
SET CLASSLIB TO comun ADDITIVE
SET CLASSLIB TO accessibility.vcx ADDITIVE
SET CLASSLIB TO messagebox ADDITIVE
SET CLASSLIB TO registry ADDITIVE
SET CLASSLIB TO cauta_alfa_forms.vcx ADDITIVE
SET CLASSLIB TO DECABAZA ADDITIVE
SET CLASSLIB TO onomenclatoare ADDITIVE
SET CLASSLIB TO stocuri.vcx ADDITIVE
SET CLASSLIB TO rulaje.vcx ADDITIVE
SET CLASSLIB TO ointroduceri ADDITIVE
SET CLASSLIB TO ointroduceri_web ADDITIVE
SET CLASSLIB TO ointroduceri_depozit ADDITIVE
SET CLASSLIB TO overificari ADDITIVE
SET CLASSLIB TO ferestre_oracle ADDITIVE
SET CLASSLIB TO ferestre_cere_date.vcx ADDITIVE
SET CLASSLIB TO configurare.vcx ADDITIVE
SET CLASSLIB TO serii_numere.vcx ADDITIVE
SET CLASSLIB TO omodificari.vcx ADDITIVE
SET CLASSLIB TO ocompensari.vcx ADDITIVE
SET CLASSLIB TO caut_ora ADDITIVE
SET CLASSLIB TO onote_contabile ADDITIVE
SET CLASSLIB TO otoolbar ADDITIVE
SET CLASSLIB TO bon_fisc ADDITIVE
SET CLASSLIB TO onom_articole ADDITIVE
SET CLASSLIB TO onom_retete ADDITIVE
SET CLASSLIB TO orapoarte ADDITIVE
SET CLASSLIB TO orapoarte_gestiuni ADDITIVE
SET CLASSLIB TO orapoarte_parametri ADDITIVE
SET CLASSLIB TO ONOM_CURS ADDITIVE
SET CLASSLIB TO ctl32_statusbar_fals.vcx ADDITIVE
SET CLASSLIB TO ctl32_common.vcx ADDITIVE
SET CLASSLIB TO ctl32_structs.vcx ADDITIVE
SET CLASSLIB TO ctl32_progressbar.vcx ADDITIVE
SET CLASSLIB TO ctl32_balloontip.vcx ADDITIVE
SET CLASSLIB TO ocriterii.vcx ADDITIVE
SET CLASSLIB TO oavize.vcx ADDITIVE
SET CLASSLIB TO onomenclatoare2 ADDITIVE
SET CLASSLIB TO wwdialogs.vcx ADDITIVE
SET CLASSLIB TO oimportxml.vcx ADDITIVE
SET CLASSLIB TO excelxml.vcx ADDITIVE
SET CLASSLIB TO orapoarte_obinv.vcx ADDITIVE
DO DcLog WITH 'SET CLASSLIB OK'
*----- PROCEDURI (mock-uri PRIMELE, ui_harness la final) -----
SET PROCEDURE TO PROCEDURI
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_cauta_nom_articole.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\mock_caut_valuta.prg" ADDITIVE
SET PROCEDURE TO acces_meniu ADDITIVE
SET PROCEDURE TO cauta_alfa ADDITIVE
SET PROCEDURE TO pmenu ADDITIVE
SET PROCEDURE TO proceduri_comune ADDITIVE
SET PROCEDURE TO quitapp ADDITIVE
SET PROCEDURE TO init_program ADDITIVE
SET PROCEDURE TO oproceduri_listari.prg ADDITIVE
SET PROCEDURE TO oproceduri_configurare.prg ADDITIVE
SET PROCEDURE TO oproceduri_articole.prg ADDITIVE
SET PROCEDURE TO oproceduri_retete.prg ADDITIVE
SET PROCEDURE TO orapoarte.prg ADDITIVE
SET PROCEDURE TO mesaje ADDITIVE
SET PROCEDURE TO oserii_numere.prg ADDITIVE
SET PROCEDURE TO oexport.prg ADDITIVE
SET PROCEDURE TO wwConfig.prg ADDITIVE
SET PROCEDURE TO proceduri_rapoarte.prg ADDITIVE
SET PROCEDURE TO OPROCEDURI_CURS.PRG ADDITIVE
SET PROCEDURE TO validare.prg ADDITIVE
SET PROCEDURE TO GENCURSOR.PRG ADDITIVE
SET PROCEDURE TO OPROCEDURI_COMUNE.PRG ADDITIVE
SET PROCEDURE TO OINIT_OPTIUNI.PRG ADDITIVE
SET PROCEDURE TO updateserver.prg ADDITIVE
SET PROCEDURE TO oinainte_de.prg ADDITIVE
SET PROCEDURE TO ooperatii_comune.prg ADDITIVE
SET PROCEDURE TO Ocompensari.PRG ADDITIVE
SET PROCEDURE TO OPROCEDURI_aMS.PRG ADDITIVE
SET PROCEDURE TO oproceduri_rulaje ADDITIVE
SET PROCEDURE TO oproceduri_stocuri ADDITIVE
SET PROCEDURE TO OINTRODUCERI ADDITIVE
SET PROCEDURE TO oHeader.prg ADDITIVE
SET PROCEDURE TO proceduri_excel.PRG ADDITIVE
SET PROCEDURE TO onomenclatoare.PRG ADDITIVE
SET PROCEDURE TO osecurity ADDITIVE
SET PROCEDURE TO ocautare ADDITIVE
SET PROCEDURE TO orefaceri ADDITIVE
SET PROCEDURE TO ofacturare_comun.PRG ADDITIVE
SET PROCEDURE TO ofacturare_stoc.PRG ADDITIVE
SET PROCEDURE TO oproceduri_casademarcat ADDITIVE
SET PROCEDURE TO oproceduri_casa_marcat_e500 ADDITIVE
SET PROCEDURE TO oproceduri_casa_marcat_mp500 ADDITIVE
SET PROCEDURE TO oproceduri_util.prg ADDITIVE
SET PROCEDURE TO wwxmlhttp.prg ADDITIVE
SET PROCEDURE TO ini.prg ADDITIVE
SET PROCEDURE TO odocumente.prg ADDITIVE
SET PROCEDURE TO regex.prg ADDITIVE
SET PROCEDURE TO wwutils.prg ADDITIVE
SET PROCEDURE TO inchidere_k ADDITIVE
SET PROCEDURE TO iniacces.prg ADDITIVE
SET PROCEDURE TO oupdate.prg ADDITIVE
SET PROCEDURE TO procese.prg ADDITIVE
SET PROCEDURE TO version.prg ADDITIVE
SET PROCEDURE TO xmlaccess.prg ADDITIVE
SET PROCEDURE TO xmlparser.prg ADDITIVE
SET PROCEDURE TO filebringer.prg ADDITIVE
SET PROCEDURE TO wwcodeupdate.prg ADDITIVE
SET PROCEDURE TO wwhttp.prg ADDITIVE
SET PROCEDURE TO xdate.prg ADDITIVE
SET PROCEDURE TO ofacturare.prg ADDITIVE
SET PROCEDURE TO oproceduri_obinv.prg ADDITIVE
SET PROCEDURE TO oproceduri_facturare.prg ADDITIVE
SET PROCEDURE TO email.prg ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\ui_harness.prg" ADDITIVE
DO DcLog WITH 'SET PROCEDURE OK'
PUBLIC goMockValuta
goMockValuta = CREATEOBJECT('Custom')
goMockValuta.AddProperty('id_valuta', 978)
goMockValuta.AddProperty('nume_val', 'EUR')
*----- Globale -----
PUBLIC gnPc, gnPval, gnPcant, gnPpret, gnPPretval, gnPCurs, gnPVal, gnPPretV, gnPPretVal
STORE 2 TO gnPc, gnPval, gnPVal
gnPcant = 3
STORE 4 TO gnPpret, gnPPretval, gnPPretVal, gnPPretV, gnPCurs
PUBLIC gl406, gcS, gnAn, gnLuna, gnIdFirma, gnIdSucursala, gcAcces, gcFirma
gl406 = .T.
gcS = 'CONTAFIN'
gnAn = YEAR(DATE())
gnLuna = MONTH(DATE())
gnIdFirma = 110
gnIdSucursala = 110
gcAcces = "1;2;3;4;5;6;7;8;"
gcFirma = gcS
PUBLIC nror(65000)
PUBLIC gnButon
STORE 2 TO gnButon
PUBLIC gcMockArtCodmat, gcMockAcontCrt
gcMockArtCodmat = ''
gcMockAcontCrt = ''
PUBLIC gnMockRaspuns
gnMockRaspuns = 6
PUBLIC goExecutor, goApp
goExecutor = CREATEOBJECT('dummyexecutor')
goApp = CREATEOBJECT('dummyapp')
*----- poAct: antetul notei (moneda principala EUR, curs 5.23) -----
PUBLIC poAct
poAct = CREATEOBJECT('Custom')
poAct.AddProperty('nume_val', 'EUR')
poAct.AddProperty('curs', 5.23)
poAct.AddProperty('proc_tva', 1.21)
poAct.AddProperty('nnir', 0)
poAct.AddProperty('id_valuta', 978)
poAct.AddProperty('id_fdoc', 1)
poAct.AddProperty('fdoc', 'Factura')
poAct.AddProperty('id_partc', 601)
poAct.AddProperty('partc', 'RAJA')
poAct.AddProperty('serie_act', '')
poAct.AddProperty('dataact', DATE())
poAct.AddProperty('tva_incasare', 0)
poAct.AddProperty('id_set', 1)
poAct.AddProperty('id_gestin', 1)
*----- jtva_coloane2 / saft_taxtable: perechi reale 21% -----
IF USED('jtva_coloane2')
USE IN ('jtva_coloane2')
ENDIF
CREATE CURSOR jtva_coloane2 (ordine N(8), id_jtva_coloana N(14), denumire C(100), ;
jc N(1), jv N(1), afisat N(1), coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14))
INSERT INTO jtva_coloane2 VALUES (0, 0, '', 0, 0, 1, '', '', 0, 0)
INSERT INTO jtva_coloane2 VALUES (1, 208, 'ACH. INT. 21%', 1, 0, 1, 'RO21B', 'RO21T', 21, 209)
INSERT INTO jtva_coloane2 VALUES (2, 209, 'TVA ACH. INT. 21%', 1, 0, 1, 'RO21T', '', 21, 0)
INSERT INTO jtva_coloane2 VALUES (3, 220, 'ACH. IMP. 21%', 1, 0, 1, 'FO21B', 'FO21T', 21, 221)
INSERT INTO jtva_coloane2 VALUES (4, 221, 'TVA ACH. IMP. 21%', 1, 0, 1, 'FO21T', '', 21, 0)
IF USED('saft_taxtable')
USE IN ('saft_taxtable')
ENDIF
CREATE CURSOR saft_taxtable (taxname C(250) NULL, typename C(250) NULL, taxcode N(6) NULL, ;
taxtype N(3) NULL, descriere C(250) NULL, tip C(100) NULL, descriere_tip C(250) NULL, ;
procent_taxa N(7,2) NULL, procent_prorata N(7,2) NULL, inactiv N(1) NULL, tva N(1) NULL, ;
wht N(1) NULL, tva_achizitii N(1) NULL, tva_livrari N(1) NULL)
INDEX ON taxcode TAG taxcode
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('', 0, '', 0, 1, 1, 1, 1)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301204-Import de bunuri cota 21%', 301204, '', 21, 1, 0, 1, 0)
DO CreeazaIntrodc WITH 'introdc'
DO CreeazaIntrodc WITH 'introdc_sablon'
INSERT INTO introdc_sablon (scd, scc, cu_tva, ordine, id_set, participa_valuta, tip_rand, ;
id_jtva_coloana, ptva, explicatie_tva) ;
VALUES ('371', '401', 1, 1, 1, .T., 'B', 208, 21, 'ACH. INT. 21%')
INSERT INTO introdc_sablon (scd, scc, cu_tva, ordine, id_set, participa_valuta, tip_rand, ;
id_jtva_coloana, ptva, explicatie_tva) ;
VALUES ('4426', '401', 1, 2, 1, .T., 'T', 209, 21, 'TVA ACH. INT. 21%')
GO TOP IN introdc_sablon
DO CreeazaRulTemp
INSERT INTO rul_temp (denumire, codmat, cant, pret, pret_lei, cont, cota_tva) ;
VALUES ('PLACEHOLDER', 'PH', 1, 1, 1, '371', 21)
SELECT introdc
INDEX ON Str(Nvl(nr_doc,0),8) + Icase(tip_rand='B','1', tip_rand='S','2', tip_rand='G','3', tip_rand='T','4', tip_rand='D','5', '6') + Padr(Nvl(scd,''),10) TAG ord_doc
SET ORDER TO ord_doc
DO DcLog WITH 'cursoare pregatite, CREATEOBJECT(import_nota, .F.)'
PUBLIC goObj
goObj = CREATEOBJECT('IMPORT_nota', .F.)
IF VARTYPE(goObj) <> 'O'
DO DcLog WITH 'FAIL: instantiere import_nota'
DO HarnessDone WITH 'done-error'
QUIT
ENDIF
goObj.lDialogAratat = .T.
goObj.oact = poAct
goObj.lSpargeSecundare = .F.
goObj.WindowType = 0
goObj.Visible = .T.
goObj.Show()
goObj.WindowState = 2
DOEVENTS FORCE
SELECT rul_temp
ZAP
goObj.gridart.Refresh()
DOEVENTS FORCE
PRIVATE pnAsserts, pnPass
STORE 0 TO pnAsserts, pnPass
*========================= DOC1: FACTURA EUR + discount (100 EUR / 523.00 lei, curs 5.23) =========================
PUBLIC goDlg, goT, gcDocKey1, gnB1ScdCredit, gnB1IdPartc, gcB1Partc
DO AdaugaFactura WITH 15000, 'RAJA', 601, 100.00
DO HarnessStep WITH 0, 'dupa DOC1 (cu discount): introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri'
SELECT introdc
SET ORDER TO
LOCATE FOR nract = 15000 AND tip_rand == 'B'
=Assert3('1-DOC1: rand B gasit', IIF(FOUND(),1,0), 1)
LOCAL lnRecnoB1
lnRecnoB1 = 0
IF FOUND()
gcDocKey1 = ALLTRIM(NVL(doc_key,''))
gnB1IdPartc = id_partc
gcB1Partc = ALLTRIM(NVL(partc,''))
lnRecnoB1 = RECNO()
ENDIF
LOCAL lnCntG1, lnRecnoG1, lnRecnoT1
STORE 0 TO lnCntG1, lnRecnoG1, lnRecnoT1
SELECT introdc
SCAN FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1
DO CASE
CASE tip_rand == 'G'
lnCntG1 = lnCntG1 + 1
lnRecnoG1 = RECNO()
DO DcLog WITH 'DOC1 G: scd=' + ALLTRIM(scd) + ' scc=' + ALLTRIM(scc) + ' suma=' + TRANSFORM(suma) + ' suma_val=' + TRANSFORM(suma_val) + ' id_partd=' + TRANSFORM(NVL(id_partd,0)) + ' explicatia=[' + ALLTRIM(NVL(explicatia,'')) + ']'
CASE tip_rand == 'T' AND lnRecnoT1 = 0
lnRecnoT1 = RECNO()
ENDCASE
ENDSCAN
=Assert3('2-DOC1: exact 1 rand G (model B/G/T)', lnCntG1, 1)
SELECT introdc
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND tip_rand == 'G'
=Assert3('3-DOC1: randul G gasit', IIF(FOUND(),1,0), 1)
IF FOUND()
=AssertStr('4-G.scd == 401 (analitic preluat de pe creditul B)', ALLTRIM(scd), '401')
=AssertStr('5-G.scc == 767', ALLTRIM(scc), '767')
=Assert3('6-G.suma=523.00 (POZITIVA, 100 EUR x curs 5.23)', suma, 523.00)
=Assert3('7-G.suma_val=100.00 (POZITIVA)', suma_val, 100.00)
=Assert3('8-G.id_partd = partenerul facturii (preluat de pe creditul B)', NVL(id_partd,0), gnB1IdPartc)
=AssertStr('9-G.partd = partenerul facturii', ALLTRIM(NVL(partd,'?')), gcB1Partc)
=Assert3('10-G.participa_valuta=.F.', IIF(participa_valuta,1,0), 0)
=Assert3('11-G.ptva = cota documentului (G e baza de TVA)', NVL(ptva,0), 21)
=Assert3('12-G.cu_tva=1', NVL(cu_tva,0), 1)
=Assert3('13-G.id_jtva_coloana = coloana bazei', NVL(id_jtva_coloana,0), goDlg.nIdExplicatieTva)
=AssertStr('14-G.explicatia=DISCOUNT', ALLTRIM(NVL(explicatia,'?')), 'DISCOUNT')
=AssertStr('15-G.doc_key = doc_key facturii', ALLTRIM(NVL(doc_key,'?')), gcDocKey1)
ELSE
pnAsserts = pnAsserts + 11
DO DcLog WITH ' FAIL 4-15: G negasit'
ENDIF
SELECT introdc
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND tip_rand == 'T'
=Assert3('16-DOC1: randul T gasit', IIF(FOUND(),1,0), 1)
IF FOUND()
=Assert3('17-T.suma=988.47 ((5230.00-523.00)*21%, baza NETA)', suma, 988.47)
=Assert3('18-T.suma_val=189.00 ((1000.00-100.00)*21%, baza NETA in valuta)', suma_val, 189.00)
ELSE
pnAsserts = pnAsserts + 2
DO DcLog WITH ' FAIL 17-18: T negasit'
ENDIF
*========================= ORDINE FIZICA IN CURSOR (Append Blank: B -> G -> T) =========================
=Assert3('19-ordine fizica: B/G/T gasite (recno>0)', IIF(lnRecnoB1>0 AND lnRecnoG1>0 AND lnRecnoT1>0,1,0), 1)
=Assert3('20-ordine fizica: RECNO(B) < RECNO(G)', IIF(lnRecnoB1 < lnRecnoG1,1,0), 1)
=Assert3('21-ordine fizica: RECNO(G) < RECNO(T)', IIF(lnRecnoG1 < lnRecnoT1,1,0), 1)
DO HarnessStep WITH 1, 'DOC1 (G creat, T pe baza neta) verificat - vezi log'
*========================= ARTICOL + PRETURI NEAFECTATE DE DISCOUNT =========================
SELECT introdc
SET ORDER TO ord_doc
gcMockArtCodmat = 'ART-BULD-212'
gcMockAcontCrt = '1'
TRY
goObj.do_adauga_articol()
CATCH TO loExcA1
DO DcLog WITH 'EROARE do_adauga_articol ' + TRANSFORM(loExcA1.ErrorNo) + ' [' + loExcA1.Message + ']'
ENDTRY
DOEVENTS FORCE
SELECT rul_temp
LOCATE FOR ALLTRIM(codmat) == 'ART-BULD-212'
IF FOUND()
REPLACE cant WITH 1, pret_val WITH 1000, pretd WITH 1000, pret WITH ROUND(1000*5.23,4), pret_lei WITH ROUND(1000*5.23,4)
ENDIF
goObj.gridart.Refresh()
DOEVENTS FORCE
LOCAL llEroareSync1
llEroareSync1 = .F.
TRY
goObj.sincronizeaza()
CATCH TO loExcS1
llEroareSync1 = .T.
DO DcLog WITH 'EROARE la sincronizeaza() ' + TRANSFORM(loExcS1.ErrorNo) + ' [' + loExcS1.Message + ']'
ENDTRY
DOEVENTS FORCE
=Assert3('22-sincronizeaza() (dupa articol) fara eroare', IIF(llEroareSync1,0,1), 1)
SELECT rul_temp
LOCATE FOR ALLTRIM(codmat) == 'ART-BULD-212'
IF FOUND()
=Assert3('23-pretul articolului NEAFECTAT de discount (pretd=1000)', pretd, 1000)
ELSE
pnAsserts = pnAsserts + 1
DO DcLog WITH ' FAIL 23: articolul negasit dupa sincronizare'
ENDIF
SELECT introdc
LOCATE FOR tip_rand == 'D'
IF FOUND()
DO DcLog WITH 'rand D (diferenta) dupa discount+articol: suma=' + TRANSFORM(suma)
=Assert3('24-randul D NEAFECTAT de discount (|suma|<=0.02)', ABS(suma), 0)
ELSE
pnAsserts = pnAsserts + 1
pnPass = pnPass + 1
DO DcLog WITH ' INFO 24: nu exista rand D (diferenta 0) - OK'
ENDIF
*========================= G SUPRAVIETUIESTE dupa sincronizare (nu doar la creare) =========================
LOCAL lnCntGDupaSync
lnCntGDupaSync = 0
SELECT introdc
SCAN FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND tip_rand == 'G'
lnCntGDupaSync = lnCntGDupaSync + 1
ENDSCAN
=Assert3('25-dupa sincronizare (cu articol): tot 1 rand G (nu s-a dublat/sters)', lnCntGDupaSync, 1)
*-- a doua sincronizare (stabilitate la re-rulare)
TRY
goObj.sincronizeaza()
CATCH TO loExcS2
DO DcLog WITH 'EROARE la sincronizeaza() #2 ' + TRANSFORM(loExcS2.ErrorNo) + ' [' + loExcS2.Message + ']'
ENDTRY
DOEVENTS FORCE
LOCAL lnCntGDupaSync2
lnCntGDupaSync2 = 0
SELECT introdc
SCAN FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND tip_rand == 'G'
lnCntGDupaSync2 = lnCntGDupaSync2 + 1
ENDSCAN
=Assert3('26-dupa a doua sincronizare: tot 1 rand G (stabil)', lnCntGDupaSync2, 1)
DO HarnessStep WITH 2, 'articol/preturi/stabilitate G verificate - vezi log'
*========================= inainte_de_do_termin: G nu genereaza rand fals de finalizare NIR (best-effort) =========================
TRY
goObj.inainte_de_do_termin()
DO DcLog WITH 'INFO inainte_de_do_termin() rulat fara eroare'
IF USED('actactan')
LOCAL lnCntGActactan
lnCntGActactan = 0
SELECT actactan
SCAN FOR tip_rand == 'G'
lnCntGActactan = lnCntGActactan + 1
ENDSCAN
DO DcLog WITH 'actactan: ' + TRANSFORM(lnCntGActactan) + ' randuri G gasite (fara relevanta pt NIR fals - vezi INFO)'
ELSE
DO DcLog WITH 'INFO: cursorul actactan nu exista in acest harness (scriere reala neacoperita de dummyexecutor) - assert 27 omis'
ENDIF
CATCH TO loExcNir
DO DcLog WITH 'INFO inainte_de_do_termin() a aruncat eroare in acest harness (dependent de Oracle real): ' + loExcNir.Message + ' - assert 27 omis'
ENDTRY
DO HarnessStep WITH 3, 'inainte_de_do_termin (best-effort) verificat - vezi log'
*========================= STERGERE FACTURA -> STERGE SI DISCOUNTUL =========================
SELECT introdc
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND tip_rand == 'B'
IF !FOUND()
*-- dupa spargere B poate lipsi - folosesc orice rand al documentului pentru pozitionare
SELECT introdc
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1
ENDIF
=Assert3('28-rand al DOC1 gasit pentru stergere', IIF(FOUND(),1,0), 1)
IF FOUND()
gnMockRaspuns = 6 && Da = tot documentul
TRY
goObj.do_sterge()
CATCH TO loExcDel
DO DcLog WITH 'EROARE do_sterge ' + TRANSFORM(loExcDel.ErrorNo) + ' [' + loExcDel.Message + ']'
ENDTRY
DOEVENTS FORCE
ENDIF
LOCAL lnCntDupaStergere
lnCntDupaStergere = 0
SELECT introdc
SCAN FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1
lnCntDupaStergere = lnCntDupaStergere + 1
ENDSCAN
=Assert3('29-dupa stergere document: 0 randuri ramase (inclusiv G)', lnCntDupaStergere, 0)
DO HarnessStep WITH 4, 'stergere factura + discount verificata - vezi log'
*========================= VARIANTA A: discount = 0 (fara G, T pe baza integrala) =========================
SELECT rul_temp
ZAP
PUBLIC gcDocKey2
DO AdaugaFactura WITH 15001, 'TRANS OIL', 602, 0.00
SELECT introdc
LOCATE FOR nract = 15001 AND tip_rand == 'B'
IF FOUND()
gcDocKey2 = ALLTRIM(NVL(doc_key,''))
ENDIF
LOCAL lnCntG2A
lnCntG2A = 0
SELECT introdc
SCAN FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey2 AND tip_rand == 'G'
lnCntG2A = lnCntG2A + 1
ENDSCAN
=Assert3('30-VARIANTA discount=0: niciun rand G', lnCntG2A, 0)
SELECT introdc
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey2 AND tip_rand == 'T'
=Assert3('31-VARIANTA discount=0: randul T gasit', IIF(FOUND(),1,0), 1)
IF FOUND()
=Assert3('32-VARIANTA discount=0: T.suma=1098.30 (baza integrala 5230.00*21%)', suma, 1098.30)
=Assert3('33-VARIANTA discount=0: T.suma_val=210.00 (baza integrala 1000.00*21%)', suma_val, 210.00)
ELSE
pnAsserts = pnAsserts + 2
DO DcLog WITH ' FAIL 32-33: T (discount=0) negasit'
ENDIF
DO HarnessStep WITH 5, 'varianta discount=0 verificata - vezi log'
*========================= VARIANTA B: FACTURA IN RON (fara valuta) + discount 400 lei =========================
PUBLIC gcDocKey3
DO AdaugaFacturaRon WITH 15002, 'FURNIZOR INTERN SRL', 603, 400.00
SELECT introdc
LOCATE FOR nract = 15002 AND tip_rand == 'B'
IF FOUND()
gcDocKey3 = ALLTRIM(NVL(doc_key,''))
ENDIF
LOCAL lnCntG3
lnCntG3 = 0
SELECT introdc
SCAN FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey3 AND tip_rand == 'G'
lnCntG3 = lnCntG3 + 1
=Assert3('34.'+TRANSFORM(RECNO())+'-VARIANTA RON: G.suma_val=0 (fara valuta)', NVL(suma_val,0), 0)
ENDSCAN
=Assert3('35-VARIANTA RON: exact 1 rand G', lnCntG3, 1)
SELECT introdc
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey3 AND tip_rand == 'G'
IF FOUND()
=Assert3('36-VARIANTA RON: G.suma=400.00', suma, 400.00)
ELSE
pnAsserts = pnAsserts + 1
DO DcLog WITH ' FAIL 36: G (RON) negasit'
ENDIF
SELECT introdc
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey3 AND tip_rand == 'T'
IF FOUND()
=Assert3('37-VARIANTA RON: T.suma=336.00 ((2000.00-400.00)*21%)', suma, 336.00)
=Assert3('38-VARIANTA RON: T.suma_val=0 (fara valuta)', NVL(suma_val,0), 0)
ELSE
pnAsserts = pnAsserts + 2
DO DcLog WITH ' FAIL 37-38: T (RON) negasit'
ENDIF
DO HarnessStep WITH 6, 'varianta factura RON + discount verificata - vezi log'
DO DcLog WITH 'REZULTAT: ' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' assert-uri PASS'
IF pnPass = pnAsserts
DO DcLog WITH 'REZULTAT: PASS (' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ')'
ELSE
DO DcLog WITH 'REZULTAT: FAIL (' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' assert-uri PASS)'
ENDIF
DO HarnessStep WITH 7, 'final: ' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' PASS'
DO HarnessDone WITH 'done'
CATCH TO loExc
DO DcLog WITH 'CATCH ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']'
DO HarnessDone WITH 'done-error'
ENDTRY
QUIT
*==================================================================================
PROCEDURE AdaugaFactura
*-- FACTURA EUR curs 5.23, 1000 EUR, TVA pe furnizor (F, normal - discountul e independent
*-- de ramura TVA); baza discountul e in EUR (aceeasi unitate ca suma facturii).
LPARAMETERS tnNract, tcPartener, tnIdPartener, tnDiscBazaVal
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = tnNract
goDlg.dDataAct = DATE()
goDlg.nIdPartener = tnIdPartener
goDlg.cPartener = tcPartener
goDlg.cExplicatia = 'Import marfa ' + tcPartener
goDlg.nSuma = 1000
goDlg.nSumaLei = 0
goDlg.nCurs = 5.23
goDlg.nIdValuta = 978
goDlg.cValuta = 'EUR'
goDlg.nIdExplicatieTva = 208
goDlg.cExplicatieTva = 'ACH. INT. 21%'
goDlg.optTipTva.Value = 1 && F = furnizor (normal)
goDlg.chkInValutaCont.Value = 1
goDlg.chkParticipaValuta.Value = 1
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO DcLog WITH 'DOC ' + TRANSFORM(tnNract) + ': valideaza = ' + TRANSFORM(goDlg.valideaza())
DO ConstruiesteToDlgF1F2 WITH ROUND(tnDiscBazaVal*5.23,4), tnDiscBazaVal
DO DcLog WITH 'DOC ' + TRANSFORM(tnNract) + ': do_adauga_factura = ' + TRANSFORM(goObj.do_adauga_factura(goT))
goDlg.Hide()
DOEVENTS FORCE
ENDPROC
PROCEDURE AdaugaFacturaRon
*-- Varianta FACTURA IN RON (fara valuta) + discount - disc_baza_val=0.
LPARAMETERS tnNract, tcPartener, tnIdPartener, tnDiscBazaLei
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = tnNract
goDlg.dDataAct = DATE()
goDlg.nIdPartener = tnIdPartener
goDlg.cPartener = tcPartener
goDlg.cExplicatia = 'Achizitie ' + tcPartener
goDlg.nSuma = 2000
goDlg.nSumaLei = 0
goDlg.nCurs = 0
goDlg.nIdExplicatieTva = 208
goDlg.cExplicatieTva = 'ACH. INT. 21%'
goDlg.optTipTva.Value = 1
goDlg.chkInValutaCont.Value = 0
goDlg.chkParticipaValuta.Value = 1
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO DcLog WITH 'DOC ' + TRANSFORM(tnNract) + ' (RON): valideaza = ' + TRANSFORM(goDlg.valideaza())
DO ConstruiesteToDlgF1F2 WITH tnDiscBazaLei, 0
DO DcLog WITH 'DOC ' + TRANSFORM(tnNract) + ' (RON): do_adauga_factura = ' + TRANSFORM(goObj.do_adauga_factura(goT))
goDlg.Hide()
DOEVENTS FORCE
ENDPROC
PROCEDURE ConstruiesteToDlgF1F2
*-- Runda32: doar disc_baza_lei/disc_baza_val (are_discount/disc_tva_lei/disc_tva_val
*-- eliminate din construieste_todlg).
LPARAMETERS tnDiscBazaLei, tnDiscBazaVal
goT = CREATEOBJECT('Empty')
=ADDPROPERTY(goT,'serie_act',ALLTRIM(NVL(goDlg.cSerieAct,'')))
=ADDPROPERTY(goT,'nract',goDlg.nNract)
=ADDPROPERTY(goT,'dataact',goDlg.dDataAct)
=ADDPROPERTY(goT,'fdoc',goDlg.cFelDoc)
=ADDPROPERTY(goT,'id_fdoc',goDlg.nIdFdoc)
=ADDPROPERTY(goT,'id_partc',goDlg.nIdPartener)
=ADDPROPERTY(goT,'partc',goDlg.cPartener)
=ADDPROPERTY(goT,'explicatia',ALLTRIM(NVL(goDlg.cExplicatia,'')))
=ADDPROPERTY(goT,'suma',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,IIF(goDlg.nSumaLei<>0,goDlg.nSumaLei,ROUND(goDlg.nSuma*goDlg.nCurs,gnPC)),goDlg.nSuma))
=ADDPROPERTY(goT,'suma_val',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,goDlg.nSuma,0))
=ADDPROPERTY(goT,'in_valuta',goDlg.chkInValutaCont.Value)
=ADDPROPERTY(goT,'participa_valuta',(goDlg.chkParticipaValuta.Value=1))
=ADDPROPERTY(goT,'id_valuta',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nIdValuta,0))
=ADDPROPERTY(goT,'curs',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nCurs,0))
=ADDPROPERTY(goT,'nume_val',IIF(goDlg.chkInValutaCont.Value=1,ALLTRIM(NVL(goDlg.cValuta,'')),''))
=ADDPROPERTY(goT,'cTipTva',IIF(goDlg.optTipTva.Value=1,'F',IIF(goDlg.optTipTva.Value=2,'D','N')))
=ADDPROPERTY(goT,'id_jtva_coloana',goDlg.nIdExplicatieTva)
=ADDPROPERTY(goT,'dvi_serie','')
=ADDPROPERTY(goT,'dvi_nract',0)
=ADDPROPERTY(goT,'dvi_dataact',DATE())
=ADDPROPERTY(goT,'dvi_id_fdoc',0)
=ADDPROPERTY(goT,'dvi_fdoc','')
=ADDPROPERTY(goT,'dvi_id_partc',0)
=ADDPROPERTY(goT,'dvi_partc','')
=ADDPROPERTY(goT,'dvi_scc','401')
=ADDPROPERTY(goT,'dvi_tva_lei',0)
=ADDPROPERTY(goT,'dvi_tva_val',0)
=ADDPROPERTY(goT,'dvi_in_valuta',.F.)
=ADDPROPERTY(goT,'dvi_id_valuta',0)
=ADDPROPERTY(goT,'dvi_curs',0)
=ADDPROPERTY(goT,'dvi_nume_val','')
=ADDPROPERTY(goT,'dvi_valuta_proprie',0)
*-- Runda32: discount financiar - doar baza (fara are_discount/disc_tva_lei/disc_tva_val)
=ADDPROPERTY(goT,'disc_baza_lei',tnDiscBazaLei)
=ADDPROPERTY(goT,'disc_baza_val',tnDiscBazaVal)
ENDPROC
PROCEDURE CreeazaRulTemp
IF USED('rul_temp')
USE IN ('rul_temp')
ENDIF
CREATE CURSOR rul_temp ( ;
id_rul N(20,0), an N(4,0), luna N(2,0), cod N(20,0);
, serie C(100), nnir N(20,0), id_articol N(10,0), denumire C(100);
, codmat C(50), codmatf C(50), codbare C(50), um C(20);
, id_gestiune N(5,0), nume_gestiune C(50), cgest C(20), nr_pag N(2,0);
, gestionar C(50), comisie_receptie1 C(50), comisie_receptie2 C(50), comisie_receptie3 C(50);
, cant N(14,3), cante N(14,3), cont C(10), acont C(20);
, pret N(18,4), tva N(18,4), valoare N(18,4), valtva N(18,4);
, proc_tva N(5,2), pretv N(18,4), pretvtva N(18,4), tvav N(18,4);
, valoarev N(18,4), valtvav N(18,4), proc_tvav N(5,2), adaos N(18,4);
, adaos_tva N(18,4), valoare_adaos N(18,4), valtva_adaos N(18,4), procent N(10,3);
, discunitar N(18,4), discount_tva N(18,4), valoare_discount N(18,4), valtva_discount N(18,4);
, proc_disc N(7,3), pretd N(14,4), curs N(18,4), id_valuta N(10,0);
, nume_val C(20), id_lucrare N(20,0), nrord C(100), id_responsabil N(10,0);
, nresp C(100), resp_marca N(18,4), dataact T, id_util N(5,0);
, util C(30), dataora T, id_sectie N(5,0), sectie C(50);
, csectie C(10), alcooltutun N(1,0), datain T, dataout T;
, id_fact N(20,0), id_gestiunec N(10,0), nume_gestiunec C(50), cgestc C(20);
, id_responsabilc N(5,0), id_reteta N(10,0), reteta C(50), nrespc C(100);
, respc_marca N(18,4), id_set N(20,0), id_tip_rulaj N(10,0), tip_rulaj C(50);
, id_obiect_depozit N(10,0), id_rul_aux N(10,0), nract N(20,0), serie_act C(10);
, dataoras T, id_utils N(10,0), lot C(30), adata_expirare T;
, id_sucursala N(5,0), sucursala C(250), id_part_rez N(10,0), part_rez C(100);
, id_lucrare_rez N(10,0), nrord_rez C(100), subgrupa C(100), grupa C(100);
, id_subgrupa N(5,0), id_grupa N(5,0), in_stoc N(1,0), in_crm N(1,0);
, id_furnizor N(10,0), furnizor C(100), id_jtva_coloana N(4,0), explicatie_tva C(100);
, taxcode N(6,0), taxname C(254), saft_procent N(18,4), codnc8 C(20);
, id_tara_origine N(4,0), cod_tara_origine C(5), tara_origine C(50), greutate N(12,4);
, fdoc C(30), id_fdoc N(18,4);
, pret_lei N(18,4), pret_val N(14,4), cota_tva N(6,2))
ENDPROC
PROCEDURE CreeazaIntrodc
*-- Runda30 (F1/pas2): coloane NOI rand_dvi N(1), valuta_proprie N(1) fata de structura veche.
LPARAMETERS tcAlias
IF USED(tcAlias)
USE IN (tcAlias)
ENDIF
CREATE CURSOR (tcAlias) ( ;
id_note N(14), explicatia C(100), scd C(10), ascd C(20), scc C(10), ascc C(20), ;
cu_tva N(1), id_set N(14), ordine N(8), in_valuta N(1), id_jtva_coloana N(14) NULL, ;
ptva N(6,2), explicatie_tva C(50), tipjurnal C(2), taxcode N(6), paymentcode C(9), ;
suma N(18,4), suma_val N(18,4), id_partd N(14), id_partc N(14), partd C(100), partc C(100), ;
id_fact N(14), id_factd N(14), id_factc N(14), pereched N(14), perechec N(14), ;
nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), expl_manual N(1), ;
scd_orig C(20), ascd_orig C(20), rand_dvi N(1), valuta_proprie N(1))
ENDPROC
FUNCTION RECCOUNT_ACTIVE
LPARAMETERS tcAlias
LOCAL lnSel, lnCnt
lnSel = SELECT()
SELECT (tcAlias)
COUNT TO lnCnt FOR !DELETED()
SELECT (lnSel)
RETURN lnCnt
ENDFUNC
PROCEDURE Assert3
LPARAMETERS tcLabel, tuActual, tuExpected
pnAsserts = pnAsserts + 1
IF ABS(NVL(tuActual,0) - tuExpected) < 0.02
pnPass = pnPass + 1
DO DcLog WITH ' PASS ' + tcLabel + ' (=' + TRANSFORM(tuActual) + ')'
ELSE
DO DcLog WITH ' FAIL ' + tcLabel + ' (actual=' + TRANSFORM(tuActual) + ' asteptat=' + TRANSFORM(tuExpected) + ')'
ENDIF
ENDPROC
PROCEDURE AssertStr
LPARAMETERS tcLabel, tcActual, tcExpected
pnAsserts = pnAsserts + 1
IF tcActual == tcExpected
pnPass = pnPass + 1
DO DcLog WITH ' PASS ' + tcLabel + ' (=[' + tcActual + '])'
ELSE
DO DcLog WITH ' FAIL ' + tcLabel + ' (actual=[' + tcActual + '] asteptat=[' + tcExpected + '])'
ENDIF
ENDPROC
PROCEDURE DcErr
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
DO DcLog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
ENDPROC
PROCEDURE DcLog
LPARAMETERS tcMsg
SET SAFETY OFF
LOCAL lcL
lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '')
STRTOFILE(lcL + tcMsg + CHR(13)+CHR(10), gcUILog)
ENDPROC
DEFINE CLASS dummyapp AS Custom
PROCEDURE ReadIni
LPARAMETERS tcSection, tcKey
RETURN ''
ENDPROC
PROCEDURE WriteIni
LPARAMETERS tcSection, tcKey, tcValue
RETURN .T.
ENDPROC
ENDDEFINE
DEFINE CLASS dummyexecutor AS Custom
cEroare = ''
PROCEDURE oExecute
LPARAMETERS tcSql, tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF 'VJTVA_COLOANE' $ UPPER(m.tcSql)
DO CreeazaJtvaColoaneView WITH m.tcCursor
RETURN 1
ENDIF
IF UPPER(ALLTRIM(m.tcCursor)) == 'RUL_TEMP'
CREATE CURSOR (m.tcCursor) (denumire C(100), codmat C(30), cant N(14,3), ;
pret_val N(18,4), pretd N(18,4), pret N(18,4), pret_lei N(18,4), cont C(10), ;
acont C(20), serie C(30), lot C(30), adata_expirare C(10), proc_disc N(6,2), cota_tva N(6,2))
RETURN 1
ENDIF
IF 'CONFIG_ANALITICE' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (camp_leg_prefix C(30), camp_leg_sufix C(30))
INSERT INTO (m.tcCursor) VALUES ('', '')
RETURN 1
ENDIF
IF 'FCONTURI_ANALITICE' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (acont C(20))
INSERT INTO (m.tcCursor) VALUES (IIF(TYPE('gcMockAcontCrt') = 'C', gcMockAcontCrt, ''))
RETURN 1
ENDIF
IF 'VPLCONT_ANALITIC' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (cont C(10), acont C(20))
INSERT INTO (m.tcCursor) VALUES ('371', '4')
RETURN 1
ENDIF
CREATE CURSOR (m.tcCursor) (id_temp N(1))
RETURN 1
ENDPROC
PROCEDURE oExecuta
LPARAMETERS tcSql, tcCursor
IF !EMPTY(m.tcCursor)
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF UPPER(m.tcCursor) == 'CJTVACOL4427'
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14))
ELSE
CREATE CURSOR (m.tcCursor) (id_temp N(1))
ENDIF
ENDIF
RETURN .T.
ENDPROC
PROCEDURE oSelect2Value
LPARAMETERS tcSql, toValue
toValue = ''
RETURN 1
ENDPROC
PROCEDURE oReset
ENDPROC
ENDDEFINE
PROCEDURE CreeazaJtvaColoaneView
LPARAMETERS tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14), denumire C(100), jc N(1), jv N(1), ;
coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14) NULL, afisat N(1), ;
id_jtva_ex N(14) NULL, id_jtva_neex N(14) NULL, ordine N(8), ;
taxcode N(6) NULL, taxcode_neexigibil N(6) NULL, taxcode_n50 N(6) NULL, ;
taxcode_n50_tvai N(6) NULL, taxcode_n100 N(6) NULL, taxcode_regularizare N(6) NULL, taxcode_tvai N(6) NULL)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, afisat, ordine, cota_tva) VALUES (0, '', 0, 0, 1, 0, 0)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (208, 'ACH. INT. 21%', 1, 0, 'RO21B', 21, 209, 1, 1, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (209, 'TVA ACH. INT. 21%', 1, 0, 'RO21T', 21, 1, 2, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (220, 'ACH. IMP. 21%', 1, 0, 'FO21B', 21, 221, 1, 3, 301204)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (221, 'TVA ACH. IMP. 21%', 1, 0, 'FO21T', 21, 1, 4, 301204)
ENDPROC

View File

@@ -0,0 +1,12 @@
# test_discount_factura.ps1 - wrapper peste harness-ul generic pentru discountul financiar pe
# factura de import (model B/G/T, un singur rand G) - Runda32.
# powershell -ExecutionPolicy Bypass -File test_discount_factura.ps1
$ErrorActionPreference = 'Stop'
$Teste = $PSScriptRoot
& (Join-Path (Split-Path $Teste -Parent) 'vfp_ui_harness.ps1') `
-TestPrg (Join-Path $Teste 'test_discount_factura.prg') `
-Steps @('doc1_creat','doc1_g_t_verificat','articol_stabilitate','nir_best_effort','stergere_document','discount_zero','factura_ron','final') `
-ShotsDir (Join-Path $Teste 'screenshots_discount_factura') `
-SyncDir (Join-Path $Teste 'uisync_discount_factura') `
-StepTimeoutSec 180 `
-ReadyTimeoutSec 180

View File

@@ -0,0 +1,723 @@
* test_discount_multicota.prg
* Runda32 (model B/G/T): factura de import cu articole pe DOUA cote TVA (21% si 11%) + discount
* financiar. Verifica distribuirea discountului in sparge_document (calc_baze_cota_creditor +
* lnFactorDisc): fiecare rand T e scalat cu ACELASI factor de discount ((baza_grup_tot -
* discount) / baza_grup_tot), aplicat pe baza PROPRIE a cotei, nu pe un singur T global.
* Flux REAL: dialogul `import_adauga_factura` + doua `do_adauga_articol()` (cote diferite) +
* `sincronizeaza()` (declanseaza sparge_document, documentul e principal si unic).
*
* Discountul se sparge si el pe cote (sparge_discount), proportional cu bazele: fiecare rand G
* poarta cota lui, iar randurile S poarta cota articolelor lor - baza si TVA-ul sunt concordante.
* Scenariu: factura EUR curs 5, 1500 EUR (=1000 la 21% + 500 la 11%, fara diferenta reziduala),
* discount baza 150 EUR (10% din total):
* - lnFactorDisc = (1500-150)/1500 = 0.9
* - T(21%): suma_val = ROUND(1000*0.9*21/100,2) = 189.00, suma = 945.00
* - T(11%): suma_val = ROUND(500*0.9*11/100,2) = 49.50, suma = 247.50
* - suma T-urilor = 238.50 (val) / 1192.50 (lei) - fara reziduu de rotunjire (numere curate).
*
* ASUMPTII: jtva_coloane2 are 2 familii import (FO) la 21%/11% (id 220/222, coloana_jc
* FO21B/FO11B) ca gaseste_jtva_cota sa gaseasca perechea corecta pentru a doua cota; articolele
* au conturi DIFERITE (212/371), dar fara randuri S preexistente calc_baze_cota_creditor le da
* la amandoua ACELASI creditor fallback (scc/ascc-ul randului B), deci crsGrupCota le separa
* DOAR dupa cota_tva (grupare pe cota_tva+scc+ascc, nu pe cont).
*
* Rulare:
* powershell -ExecutionPolicy Bypass -File test_discount_multicota.ps1
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET DECIMALS TO 4
SET NULLDISPLAY TO ''
CLOSE DATABASES
PUBLIC gcUILog, gcSyncDir
gcUILog = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\test_discount_multicota_log.txt"
gcSyncDir = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\uisync_discount_multicota\"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcUILog)
ON ERROR DO McErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
TRY
LOCAL gcAppPath, lcPath
gcAppPath = "D:\ROA\ROAGEST\"
SET DEFAULT TO (gcAppPath)
lcPath = gcAppPath + 'Date;' + gcAppPath + 'Include;' + gcAppPath + 'FERESTRE;' + ;
gcAppPath + 'GRAFICE;' + gcAppPath + 'CLASE;' + gcAppPath + 'MENIURI;' + ;
gcAppPath + 'PROGRAME;' + gcAppPath + 'RAPOARTE;' + gcAppPath + 'COMUN;' + ;
gcAppPath + 'COMUN\CLASE;' + gcAppPath + 'COMUN\FERESTRE;' + gcAppPath + 'COMUN\PROGRAME;' + ;
gcAppPath + 'COMUN\GRAFICE;' + gcAppPath + 'COMUN\RAPOARTE;' + gcAppPath + 'COMUN\MENIURI;' + ;
gcAppPath + 'COMUN\UTILE\GRIDEXTRAS;' + gcAppPath + 'COMUN\UTILE\CTL32;' + ;
gcAppPath + 'COMUN\UTILE\HPDF;' + gcAppPath + 'COMUN\UTILE\HPDF\REPORTOUTPUT;' + ;
gcAppPath + 'COMUN\UTILE\WEB;' + gcAppPath + 'COMUN\UTILE\EXCEL;' + ;
ADDBS(SUBSTR(gcAppPath,1,RAT([\],gcAppPath,2)))+[COMUNROA\]
SET PATH TO &lcPath ADDITIVE
DO McLog WITH 'SET PATH OK'
*----- CLASE -----
SET CLASSLIB TO (gcAppPath + "comun\clase\appwiz") ADDITIVE
SET CLASSLIB TO GESTIUNI ADDITIVE
SET CLASSLIB TO CAUT ADDITIVE
SET CLASSLIB TO BAZA ADDITIVE
SET CLASSLIB TO comun ADDITIVE
SET CLASSLIB TO accessibility.vcx ADDITIVE
SET CLASSLIB TO messagebox ADDITIVE
SET CLASSLIB TO registry ADDITIVE
SET CLASSLIB TO cauta_alfa_forms.vcx ADDITIVE
SET CLASSLIB TO DECABAZA ADDITIVE
SET CLASSLIB TO onomenclatoare ADDITIVE
SET CLASSLIB TO stocuri.vcx ADDITIVE
SET CLASSLIB TO rulaje.vcx ADDITIVE
SET CLASSLIB TO ointroduceri ADDITIVE
SET CLASSLIB TO ointroduceri_web ADDITIVE
SET CLASSLIB TO ointroduceri_depozit ADDITIVE
SET CLASSLIB TO overificari ADDITIVE
SET CLASSLIB TO ferestre_oracle ADDITIVE
SET CLASSLIB TO ferestre_cere_date.vcx ADDITIVE
SET CLASSLIB TO configurare.vcx ADDITIVE
SET CLASSLIB TO serii_numere.vcx ADDITIVE
SET CLASSLIB TO omodificari.vcx ADDITIVE
SET CLASSLIB TO ocompensari.vcx ADDITIVE
SET CLASSLIB TO caut_ora ADDITIVE
SET CLASSLIB TO onote_contabile ADDITIVE
SET CLASSLIB TO otoolbar ADDITIVE
SET CLASSLIB TO bon_fisc ADDITIVE
SET CLASSLIB TO onom_articole ADDITIVE
SET CLASSLIB TO onom_retete ADDITIVE
SET CLASSLIB TO orapoarte ADDITIVE
SET CLASSLIB TO orapoarte_gestiuni ADDITIVE
SET CLASSLIB TO orapoarte_parametri ADDITIVE
SET CLASSLIB TO ONOM_CURS ADDITIVE
SET CLASSLIB TO ctl32_statusbar_fals.vcx ADDITIVE
SET CLASSLIB TO ctl32_common.vcx ADDITIVE
SET CLASSLIB TO ctl32_structs.vcx ADDITIVE
SET CLASSLIB TO ctl32_progressbar.vcx ADDITIVE
SET CLASSLIB TO ctl32_balloontip.vcx ADDITIVE
SET CLASSLIB TO ocriterii.vcx ADDITIVE
SET CLASSLIB TO oavize.vcx ADDITIVE
SET CLASSLIB TO onomenclatoare2 ADDITIVE
SET CLASSLIB TO wwdialogs.vcx ADDITIVE
SET CLASSLIB TO oimportxml.vcx ADDITIVE
SET CLASSLIB TO excelxml.vcx ADDITIVE
SET CLASSLIB TO orapoarte_obinv.vcx ADDITIVE
DO McLog WITH 'SET CLASSLIB OK'
*----- PROCEDURI (mock-uri PRIMELE, ui_harness la final) -----
SET PROCEDURE TO PROCEDURI
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_cauta_nom_articole.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\mock_caut_valuta.prg" ADDITIVE
SET PROCEDURE TO acces_meniu ADDITIVE
SET PROCEDURE TO cauta_alfa ADDITIVE
SET PROCEDURE TO pmenu ADDITIVE
SET PROCEDURE TO proceduri_comune ADDITIVE
SET PROCEDURE TO quitapp ADDITIVE
SET PROCEDURE TO init_program ADDITIVE
SET PROCEDURE TO oproceduri_listari.prg ADDITIVE
SET PROCEDURE TO oproceduri_configurare.prg ADDITIVE
SET PROCEDURE TO oproceduri_articole.prg ADDITIVE
SET PROCEDURE TO oproceduri_retete.prg ADDITIVE
SET PROCEDURE TO orapoarte.prg ADDITIVE
SET PROCEDURE TO mesaje ADDITIVE
SET PROCEDURE TO oserii_numere.prg ADDITIVE
SET PROCEDURE TO oexport.prg ADDITIVE
SET PROCEDURE TO wwConfig.prg ADDITIVE
SET PROCEDURE TO proceduri_rapoarte.prg ADDITIVE
SET PROCEDURE TO OPROCEDURI_CURS.PRG ADDITIVE
SET PROCEDURE TO validare.prg ADDITIVE
SET PROCEDURE TO GENCURSOR.PRG ADDITIVE
SET PROCEDURE TO OPROCEDURI_COMUNE.PRG ADDITIVE
SET PROCEDURE TO OINIT_OPTIUNI.PRG ADDITIVE
SET PROCEDURE TO updateserver.prg ADDITIVE
SET PROCEDURE TO oinainte_de.prg ADDITIVE
SET PROCEDURE TO ooperatii_comune.prg ADDITIVE
SET PROCEDURE TO Ocompensari.PRG ADDITIVE
SET PROCEDURE TO OPROCEDURI_aMS.PRG ADDITIVE
SET PROCEDURE TO oproceduri_rulaje ADDITIVE
SET PROCEDURE TO oproceduri_stocuri ADDITIVE
SET PROCEDURE TO OINTRODUCERI ADDITIVE
SET PROCEDURE TO oHeader.prg ADDITIVE
SET PROCEDURE TO proceduri_excel.PRG ADDITIVE
SET PROCEDURE TO onomenclatoare.PRG ADDITIVE
SET PROCEDURE TO osecurity ADDITIVE
SET PROCEDURE TO ocautare ADDITIVE
SET PROCEDURE TO orefaceri ADDITIVE
SET PROCEDURE TO ofacturare_comun.PRG ADDITIVE
SET PROCEDURE TO ofacturare_stoc.PRG ADDITIVE
SET PROCEDURE TO oproceduri_casademarcat ADDITIVE
SET PROCEDURE TO oproceduri_casa_marcat_e500 ADDITIVE
SET PROCEDURE TO oproceduri_casa_marcat_mp500 ADDITIVE
SET PROCEDURE TO oproceduri_util.prg ADDITIVE
SET PROCEDURE TO wwxmlhttp.prg ADDITIVE
SET PROCEDURE TO ini.prg ADDITIVE
SET PROCEDURE TO odocumente.prg ADDITIVE
SET PROCEDURE TO regex.prg ADDITIVE
SET PROCEDURE TO wwutils.prg ADDITIVE
SET PROCEDURE TO inchidere_k ADDITIVE
SET PROCEDURE TO iniacces.prg ADDITIVE
SET PROCEDURE TO oupdate.prg ADDITIVE
SET PROCEDURE TO procese.prg ADDITIVE
SET PROCEDURE TO version.prg ADDITIVE
SET PROCEDURE TO xmlaccess.prg ADDITIVE
SET PROCEDURE TO xmlparser.prg ADDITIVE
SET PROCEDURE TO filebringer.prg ADDITIVE
SET PROCEDURE TO wwcodeupdate.prg ADDITIVE
SET PROCEDURE TO wwhttp.prg ADDITIVE
SET PROCEDURE TO xdate.prg ADDITIVE
SET PROCEDURE TO ofacturare.prg ADDITIVE
SET PROCEDURE TO oproceduri_obinv.prg ADDITIVE
SET PROCEDURE TO oproceduri_facturare.prg ADDITIVE
SET PROCEDURE TO email.prg ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\ui_harness.prg" ADDITIVE
DO McLog WITH 'SET PROCEDURE OK'
PUBLIC goMockValuta
goMockValuta = CREATEOBJECT('Custom')
goMockValuta.AddProperty('id_valuta', 978)
goMockValuta.AddProperty('nume_val', 'EUR')
*----- Globale -----
PUBLIC gnPc, gnPval, gnPcant, gnPpret, gnPPretval, gnPCurs, gnPVal, gnPPretV, gnPPretVal
STORE 2 TO gnPc, gnPval, gnPVal
gnPcant = 3
STORE 4 TO gnPpret, gnPPretval, gnPPretVal, gnPPretV, gnPCurs
PUBLIC gl406, gcS, gnAn, gnLuna, gnIdFirma, gnIdSucursala, gcAcces, gcFirma
gl406 = .T.
gcS = 'CONTAFIN'
gnAn = YEAR(DATE())
gnLuna = MONTH(DATE())
gnIdFirma = 110
gnIdSucursala = 110
gcAcces = "1;2;3;4;5;6;7;8;"
gcFirma = gcS
PUBLIC nror(65000)
PUBLIC gnButon
STORE 2 TO gnButon
PUBLIC gcMockArtCodmat, gcMockAcontCrt
gcMockArtCodmat = ''
gcMockAcontCrt = ''
PUBLIC gnMockRaspuns
gnMockRaspuns = 6
PUBLIC goExecutor, goApp
goExecutor = CREATEOBJECT('dummyexecutor')
goApp = CREATEOBJECT('dummyapp')
*----- poAct: antetul notei (moneda principala EUR, curs 5) -----
PUBLIC poAct
poAct = CREATEOBJECT('Custom')
poAct.AddProperty('nume_val', 'EUR')
poAct.AddProperty('curs', 5)
poAct.AddProperty('proc_tva', 1.21)
poAct.AddProperty('nnir', 0)
poAct.AddProperty('id_valuta', 978)
poAct.AddProperty('id_fdoc', 1)
poAct.AddProperty('fdoc', 'Factura')
poAct.AddProperty('id_partc', 601)
poAct.AddProperty('partc', 'MULTI SUPPLY SRL')
poAct.AddProperty('serie_act', '')
poAct.AddProperty('dataact', DATE())
poAct.AddProperty('tva_incasare', 0)
poAct.AddProperty('id_set', 1)
poAct.AddProperty('id_gestin', 1)
*----- jtva_coloane2 / saft_taxtable: DOUA familii import (FO), 21% si 11% -----
IF USED('jtva_coloane2')
USE IN ('jtva_coloane2')
ENDIF
CREATE CURSOR jtva_coloane2 (ordine N(8), id_jtva_coloana N(14), denumire C(100), ;
jc N(1), jv N(1), afisat N(1), coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14))
INSERT INTO jtva_coloane2 VALUES (0, 0, '', 0, 0, 1, '', '', 0, 0)
INSERT INTO jtva_coloane2 VALUES (1, 220, 'ACH. IMP. 21%', 1, 0, 1, 'FO21B', 'FO21T', 21, 221)
INSERT INTO jtva_coloane2 VALUES (2, 221, 'TVA ACH. IMP. 21%', 1, 0, 1, 'FO21T', '', 21, 0)
INSERT INTO jtva_coloane2 VALUES (3, 222, 'ACH. IMP. 11%', 1, 0, 1, 'FO11B', 'FO11T', 11, 223)
INSERT INTO jtva_coloane2 VALUES (4, 223, 'TVA ACH. IMP. 11%', 1, 0, 1, 'FO11T', '', 11, 0)
IF USED('saft_taxtable')
USE IN ('saft_taxtable')
ENDIF
CREATE CURSOR saft_taxtable (taxname C(250) NULL, typename C(250) NULL, taxcode N(6) NULL, ;
taxtype N(3) NULL, descriere C(250) NULL, tip C(100) NULL, descriere_tip C(250) NULL, ;
procent_taxa N(7,2) NULL, procent_prorata N(7,2) NULL, inactiv N(1) NULL, tva N(1) NULL, ;
wht N(1) NULL, tva_achizitii N(1) NULL, tva_livrari N(1) NULL)
INDEX ON taxcode TAG taxcode
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('', 0, '', 0, 1, 1, 1, 1)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301204-Import de bunuri cota 21%', 301204, '', 21, 1, 0, 1, 0)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301205-Import de bunuri cota 11%', 301205, '', 11, 1, 0, 1, 0)
DO CreeazaIntrodc WITH 'introdc'
DO CreeazaIntrodc WITH 'introdc_sablon'
INSERT INTO introdc_sablon (scd, scc, cu_tva, ordine, id_set, participa_valuta, tip_rand, ;
id_jtva_coloana, ptva, explicatie_tva) ;
VALUES ('371', '401', 1, 1, 1, .T., 'B', 220, 21, 'ACH. IMP. 21%')
INSERT INTO introdc_sablon (scd, scc, cu_tva, ordine, id_set, participa_valuta, tip_rand, ;
id_jtva_coloana, ptva, explicatie_tva) ;
VALUES ('4426', '401', 1, 2, 1, .T., 'T', 221, 21, 'TVA ACH. IMP. 21%')
GO TOP IN introdc_sablon
DO CreeazaRulTemp
INSERT INTO rul_temp (denumire, codmat, cant, pret, pret_lei, cont, cota_tva) ;
VALUES ('PLACEHOLDER', 'PH', 1, 1, 1, '371', 21)
SELECT introdc
INDEX ON Str(Nvl(nr_doc,0),8) + Icase(tip_rand='B','1', tip_rand='S','2', tip_rand='G','3', tip_rand='T','4', tip_rand='D','5', '6') + Padr(Nvl(scd,''),10) TAG ord_doc
SET ORDER TO ord_doc
DO McLog WITH 'cursoare pregatite, CREATEOBJECT(import_nota, .F.)'
PUBLIC goObj
goObj = CREATEOBJECT('IMPORT_nota', .F.)
IF VARTYPE(goObj) <> 'O'
DO McLog WITH 'FAIL: instantiere import_nota'
DO HarnessDone WITH 'done-error'
QUIT
ENDIF
goObj.lDialogAratat = .T.
goObj.oact = poAct
goObj.lSpargeSecundare = .F.
goObj.WindowType = 0
goObj.Visible = .T.
goObj.Show()
goObj.WindowState = 2
DOEVENTS FORCE
SELECT rul_temp
ZAP
goObj.gridart.Refresh()
DOEVENTS FORCE
PRIVATE pnAsserts, pnPass
STORE 0 TO pnAsserts, pnPass
*========================= FACTURA: 1500 EUR (1000@21% + 500@11%), discount 150 EUR =========================
PUBLIC goDlg, goT, gcDocKey1
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = 16000
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 601
goDlg.cPartener = 'MULTI SUPPLY SRL'
goDlg.cExplicatia = 'Import marfa multicota'
goDlg.nSuma = 1500
goDlg.nSumaLei = 0
goDlg.nCurs = 5
goDlg.nIdValuta = 978
goDlg.cValuta = 'EUR'
goDlg.nIdExplicatieTva = 220
goDlg.cExplicatieTva = 'ACH. IMP. 21%'
goDlg.optTipTva.Value = 1
goDlg.chkInValutaCont.Value = 1
goDlg.chkParticipaValuta.Value = 1
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO McLog WITH 'valideaza = ' + TRANSFORM(goDlg.valideaza())
goT = CREATEOBJECT('Empty')
=ADDPROPERTY(goT,'serie_act','')
=ADDPROPERTY(goT,'nract',goDlg.nNract)
=ADDPROPERTY(goT,'dataact',goDlg.dDataAct)
=ADDPROPERTY(goT,'fdoc',goDlg.cFelDoc)
=ADDPROPERTY(goT,'id_fdoc',goDlg.nIdFdoc)
=ADDPROPERTY(goT,'id_partc',goDlg.nIdPartener)
=ADDPROPERTY(goT,'partc',goDlg.cPartener)
=ADDPROPERTY(goT,'explicatia',ALLTRIM(NVL(goDlg.cExplicatia,'')))
=ADDPROPERTY(goT,'suma',ROUND(goDlg.nSuma*goDlg.nCurs,gnPC))
=ADDPROPERTY(goT,'suma_val',goDlg.nSuma)
=ADDPROPERTY(goT,'in_valuta',goDlg.chkInValutaCont.Value)
=ADDPROPERTY(goT,'participa_valuta',.T.)
=ADDPROPERTY(goT,'id_valuta',goDlg.nIdValuta)
=ADDPROPERTY(goT,'curs',goDlg.nCurs)
=ADDPROPERTY(goT,'nume_val',ALLTRIM(NVL(goDlg.cValuta,'')))
=ADDPROPERTY(goT,'cTipTva','F')
=ADDPROPERTY(goT,'id_jtva_coloana',goDlg.nIdExplicatieTva)
=ADDPROPERTY(goT,'dvi_serie','')
=ADDPROPERTY(goT,'dvi_nract',0)
=ADDPROPERTY(goT,'dvi_dataact',DATE())
=ADDPROPERTY(goT,'dvi_id_fdoc',0)
=ADDPROPERTY(goT,'dvi_fdoc','')
=ADDPROPERTY(goT,'dvi_id_partc',0)
=ADDPROPERTY(goT,'dvi_partc','')
=ADDPROPERTY(goT,'dvi_scc','401')
=ADDPROPERTY(goT,'dvi_tva_lei',0)
=ADDPROPERTY(goT,'dvi_tva_val',0)
=ADDPROPERTY(goT,'dvi_in_valuta',.F.)
=ADDPROPERTY(goT,'dvi_id_valuta',0)
=ADDPROPERTY(goT,'dvi_curs',0)
=ADDPROPERTY(goT,'dvi_nume_val','')
=ADDPROPERTY(goT,'dvi_valuta_proprie',0)
=ADDPROPERTY(goT,'disc_baza_lei',ROUND(150*5,gnPC))
=ADDPROPERTY(goT,'disc_baza_val',150)
LOCAL llOkAdauga
llOkAdauga = goObj.do_adauga_factura(goT)
=Assert3('1-do_adauga_factura(goT) reuseste', IIF(llOkAdauga,1,0), 1)
goDlg.Hide()
DOEVENTS FORCE
SELECT introdc
SET ORDER TO
LOCATE FOR nract = 16000 AND tip_rand == 'B'
IF FOUND()
gcDocKey1 = ALLTRIM(NVL(doc_key,''))
ENDIF
SELECT introdc
SET ORDER TO ord_doc
DO HarnessStep WITH 0, 'factura creata, doc_key=' + gcDocKey1
*========================= DOUA ARTICOLE, COTE DIFERITE (21% si 11%) =========================
gcMockArtCodmat = 'ART-BULD-212'
gcMockAcontCrt = ''
TRY
goObj.do_adauga_articol()
CATCH TO loExcA1
DO McLog WITH 'EROARE do_adauga_articol (1) ' + TRANSFORM(loExcA1.ErrorNo) + ' [' + loExcA1.Message + ']'
ENDTRY
DOEVENTS FORCE
SELECT rul_temp
LOCATE FOR ALLTRIM(codmat) == 'ART-BULD-212'
IF FOUND()
REPLACE cant WITH 1, pret_val WITH 1000, pretd WITH 1000, pret WITH ROUND(1000*5,4), ;
pret_lei WITH ROUND(1000*5,4), cota_tva WITH 21
ENDIF
gcMockArtCodmat = 'ART-A8-371'
TRY
goObj.do_adauga_articol()
CATCH TO loExcA2
DO McLog WITH 'EROARE do_adauga_articol (2) ' + TRANSFORM(loExcA2.ErrorNo) + ' [' + loExcA2.Message + ']'
ENDTRY
DOEVENTS FORCE
SELECT rul_temp
LOCATE FOR ALLTRIM(codmat) == 'ART-A8-371'
IF FOUND()
REPLACE cant WITH 1, pret_val WITH 500, pretd WITH 500, pret WITH ROUND(500*5,4), ;
pret_lei WITH ROUND(500*5,4), cota_tva WITH 11
ENDIF
goObj.gridart.Refresh()
DOEVENTS FORCE
=Assert3('2-doua articole in rul_temp', RECCOUNT_ACTIVE('rul_temp'), 2)
DO HarnessStep WITH 1, 'articole (21% si 11%) adaugate'
*========================= sincronizeaza() (declanseaza sparge_document) =========================
LOCAL llEroareSync
llEroareSync = .F.
TRY
goObj.sincronizeaza()
CATCH TO loExcS
llEroareSync = .T.
DO McLog WITH 'EROARE sincronizeaza() ' + TRANSFORM(loExcS.ErrorNo) + ' [' + loExcS.Message + '] in ' + loExcS.Procedure + ':' + TRANSFORM(loExcS.LineNo)
ENDTRY
DOEVENTS FORCE
=Assert3('3-sincronizeaza() fara eroare', IIF(llEroareSync,0,1), 1)
*========================= G: discountul se sparge pe cote (baza TVA-ului) =========================
LOCAL lnCntG, lnSumGVal, lnSumG
STORE 0 TO lnCntG, lnSumGVal, lnSumG
SELECT introdc
SCAN FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND tip_rand == 'G'
lnCntG = lnCntG + 1
lnSumGVal = lnSumGVal + suma_val
lnSumG = lnSumG + suma
ENDSCAN
=Assert3('4-doua randuri G (unul pe cota)', lnCntG, 2)
=Assert3('4a-total discount valuta pastrat', lnSumGVal, 150.00)
=Assert3('4b-total discount lei pastrat', lnSumG, 750.00)
SELECT introdc
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND tip_rand == 'G' AND ptva == 21
=Assert3('5-G(21%) gasit', IIF(FOUND(),1,0), 1)
IF FOUND()
=Assert3('5a-G(21%).suma_val=100.00 (150*1000/1500)', suma_val, 100.00)
=Assert3('5b-G(21%).suma=500.00', suma, 500.00)
ELSE
pnAsserts = pnAsserts + 2
DO McLog WITH ' FAIL 5a-5b: G(21%) negasit'
ENDIF
SELECT introdc
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND tip_rand == 'G' AND ptva == 11
=Assert3('6-G(11%) gasit', IIF(FOUND(),1,0), 1)
IF FOUND()
=Assert3('6a-G(11%).suma_val=50.00 (150*500/1500)', suma_val, 50.00)
=Assert3('6b-G(11%).suma=250.00', suma, 250.00)
ELSE
pnAsserts = pnAsserts + 2
DO McLog WITH ' FAIL 6a-6b: G(11%) negasit'
ENDIF
*========================= T-uri: cate unul pe cota, scalate cu acelasi factor de discount =========================
SELECT introdc
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND tip_rand == 'T' AND ptva == 21
=Assert3('7-T(21%) gasit', IIF(FOUND(),1,0), 1)
IF FOUND()
=Assert3('8-T(21%).suma_val=189.00 (1000*0.9*21%)', suma_val, 189.00)
=Assert3('9-T(21%).suma=945.00', suma, 945.00)
ELSE
pnAsserts = pnAsserts + 2
DO McLog WITH ' FAIL 8-9: T(21%) negasit'
ENDIF
SELECT introdc
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND tip_rand == 'T' AND ptva == 11
=Assert3('10-T(11%) gasit', IIF(FOUND(),1,0), 1)
IF FOUND()
=Assert3('11-T(11%).suma_val=49.50 (500*0.9*11%)', suma_val, 49.50)
=Assert3('12-T(11%).suma=247.50', suma, 247.50)
ELSE
pnAsserts = pnAsserts + 2
DO McLog WITH ' FAIL 11-12: T(11%) negasit'
ENDIF
LOCAL lnCntT, lnSumTVal, lnSumT
STORE 0 TO lnCntT, lnSumTVal, lnSumT
SELECT introdc
SCAN FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND tip_rand == 'T'
lnCntT = lnCntT + 1
lnSumTVal = lnSumTVal + suma_val
lnSumT = lnSumT + suma
ENDSCAN
=Assert3('13-exact 2 randuri T (o cota fiecare)', lnCntT, 2)
=Assert3('14-suma T-urilor (valuta) = 238.50, fara reziduu de rotunjire', lnSumTVal, 238.50)
=Assert3('15-suma T-urilor (lei) = 1192.50, fara reziduu de rotunjire', lnSumT, 1192.50)
*========================= S: cota randului de baza = cota articolelor lui =========================
LOCAL lnCntS
lnCntS = 0
SELECT introdc
SCAN FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND tip_rand == 'S'
lnCntS = lnCntS + 1
ENDSCAN
=Assert3('16-doua randuri S', lnCntS, 2)
SELECT introdc
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND tip_rand == 'S' AND ptva == 21
=Assert3('17-S cu cota 21 (articolul de 1000)', IIF(FOUND(),1,0), 1)
IF FOUND()
=Assert3('17a-S(21%).suma_val=1000.00', suma_val, 1000.00)
ELSE
pnAsserts = pnAsserts + 1
DO McLog WITH ' FAIL 17a: S(21%) negasit'
ENDIF
SELECT introdc
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND tip_rand == 'S' AND ptva == 11
=Assert3('18-S cu cota 11 (articolul de 500)', IIF(FOUND(),1,0), 1)
IF FOUND()
=Assert3('18a-S(11%).suma_val=500.00', suma_val, 500.00)
ELSE
pnAsserts = pnAsserts + 1
DO McLog WITH ' FAIL 18a: S(11%) negasit'
ENDIF
DO HarnessStep WITH 2, 'T-uri multicota verificate - suma val=' + TRANSFORM(lnSumTVal) + ' lei=' + TRANSFORM(lnSumT)
DO McLog WITH 'REZULTAT: ' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' assert-uri PASS'
IF pnPass = pnAsserts
DO McLog WITH 'REZULTAT: PASS (' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ')'
ELSE
DO McLog WITH 'REZULTAT: FAIL (' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' assert-uri PASS)'
ENDIF
DO HarnessStep WITH 3, 'final: ' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' PASS'
DO HarnessDone WITH 'done'
CATCH TO loExc
DO McLog WITH 'CATCH ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']'
DO HarnessDone WITH 'done-error'
ENDTRY
QUIT
*==================================================================================
PROCEDURE CreeazaRulTemp
IF USED('rul_temp')
USE IN ('rul_temp')
ENDIF
CREATE CURSOR rul_temp ( ;
id_rul N(20,0), an N(4,0), luna N(2,0), cod N(20,0);
, serie C(100), nnir N(20,0), id_articol N(10,0), denumire C(100);
, codmat C(50), codmatf C(50), codbare C(50), um C(20);
, id_gestiune N(5,0), nume_gestiune C(50), cgest C(20), nr_pag N(2,0);
, gestionar C(50), comisie_receptie1 C(50), comisie_receptie2 C(50), comisie_receptie3 C(50);
, cant N(14,3), cante N(14,3), cont C(10), acont C(20);
, pret N(18,4), tva N(18,4), valoare N(18,4), valtva N(18,4);
, proc_tva N(5,2), pretv N(18,4), pretvtva N(18,4), tvav N(18,4);
, valoarev N(18,4), valtvav N(18,4), proc_tvav N(5,2), adaos N(18,4);
, adaos_tva N(18,4), valoare_adaos N(18,4), valtva_adaos N(18,4), procent N(10,3);
, discunitar N(18,4), discount_tva N(18,4), valoare_discount N(18,4), valtva_discount N(18,4);
, proc_disc N(7,3), pretd N(14,4), curs N(18,4), id_valuta N(10,0);
, nume_val C(20), id_lucrare N(20,0), nrord C(100), id_responsabil N(10,0);
, nresp C(100), resp_marca N(18,4), dataact T, id_util N(5,0);
, util C(30), dataora T, id_sectie N(5,0), sectie C(50);
, csectie C(10), alcooltutun N(1,0), datain T, dataout T;
, id_fact N(20,0), id_gestiunec N(10,0), nume_gestiunec C(50), cgestc C(20);
, id_responsabilc N(5,0), id_reteta N(10,0), reteta C(50), nrespc C(100);
, respc_marca N(18,4), id_set N(20,0), id_tip_rulaj N(10,0), tip_rulaj C(50);
, id_obiect_depozit N(10,0), id_rul_aux N(10,0), nract N(20,0), serie_act C(10);
, dataoras T, id_utils N(10,0), lot C(30), adata_expirare T;
, id_sucursala N(5,0), sucursala C(250), id_part_rez N(10,0), part_rez C(100);
, id_lucrare_rez N(10,0), nrord_rez C(100), subgrupa C(100), grupa C(100);
, id_subgrupa N(5,0), id_grupa N(5,0), in_stoc N(1,0), in_crm N(1,0);
, id_furnizor N(10,0), furnizor C(100), id_jtva_coloana N(4,0), explicatie_tva C(100);
, taxcode N(6,0), taxname C(254), saft_procent N(18,4), codnc8 C(20);
, id_tara_origine N(4,0), cod_tara_origine C(5), tara_origine C(50), greutate N(12,4);
, fdoc C(30), id_fdoc N(18,4);
, pret_lei N(18,4), pret_val N(14,4), cota_tva N(6,2))
ENDPROC
PROCEDURE CreeazaIntrodc
LPARAMETERS tcAlias
IF USED(tcAlias)
USE IN (tcAlias)
ENDIF
CREATE CURSOR (tcAlias) ( ;
id_note N(14), explicatia C(100), scd C(10), ascd C(20), scc C(10), ascc C(20), ;
cu_tva N(1), id_set N(14), ordine N(8), in_valuta N(1), id_jtva_coloana N(14) NULL, ;
ptva N(6,2), explicatie_tva C(50), tipjurnal C(2), taxcode N(6), paymentcode C(9), ;
suma N(18,4), suma_val N(18,4), id_partd N(14), id_partc N(14), partd C(100), partc C(100), ;
id_fact N(14), id_factd N(14), id_factc N(14), pereched N(14), perechec N(14), ;
nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), expl_manual N(1), ;
scd_orig C(20), ascd_orig C(20), rand_dvi N(1), valuta_proprie N(1))
ENDPROC
FUNCTION RECCOUNT_ACTIVE
LPARAMETERS tcAlias
LOCAL lnSel, lnCnt
lnSel = SELECT()
SELECT (tcAlias)
COUNT TO lnCnt FOR !DELETED()
SELECT (lnSel)
RETURN lnCnt
ENDFUNC
PROCEDURE Assert3
LPARAMETERS tcLabel, tuActual, tuExpected
pnAsserts = pnAsserts + 1
IF ABS(NVL(tuActual,0) - tuExpected) < 0.02
pnPass = pnPass + 1
DO McLog WITH ' PASS ' + tcLabel + ' (=' + TRANSFORM(tuActual) + ')'
ELSE
DO McLog WITH ' FAIL ' + tcLabel + ' (actual=' + TRANSFORM(tuActual) + ' asteptat=' + TRANSFORM(tuExpected) + ')'
ENDIF
ENDPROC
PROCEDURE McErr
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
DO McLog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
ENDPROC
PROCEDURE McLog
LPARAMETERS tcMsg
SET SAFETY OFF
LOCAL lcL
lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '')
STRTOFILE(lcL + tcMsg + CHR(13)+CHR(10), gcUILog)
ENDPROC
DEFINE CLASS dummyapp AS Custom
PROCEDURE ReadIni
LPARAMETERS tcSection, tcKey
RETURN ''
ENDPROC
PROCEDURE WriteIni
LPARAMETERS tcSection, tcKey, tcValue
RETURN .T.
ENDPROC
ENDDEFINE
DEFINE CLASS dummyexecutor AS Custom
cEroare = ''
PROCEDURE oExecute
LPARAMETERS tcSql, tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF 'VJTVA_COLOANE' $ UPPER(m.tcSql)
DO CreeazaJtvaColoaneView WITH m.tcCursor
RETURN 1
ENDIF
IF UPPER(ALLTRIM(m.tcCursor)) == 'RUL_TEMP'
CREATE CURSOR (m.tcCursor) (denumire C(100), codmat C(30), cant N(14,3), ;
pret_val N(18,4), pretd N(18,4), pret N(18,4), pret_lei N(18,4), cont C(10), ;
acont C(20), serie C(30), lot C(30), adata_expirare C(10), proc_disc N(6,2), cota_tva N(6,2))
RETURN 1
ENDIF
IF 'CONFIG_ANALITICE' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (camp_leg_prefix C(30), camp_leg_sufix C(30))
INSERT INTO (m.tcCursor) VALUES ('', '')
RETURN 1
ENDIF
IF 'FCONTURI_ANALITICE' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (acont C(20))
INSERT INTO (m.tcCursor) VALUES (IIF(TYPE('gcMockAcontCrt') = 'C', gcMockAcontCrt, ''))
RETURN 1
ENDIF
IF 'VPLCONT_ANALITIC' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (cont C(10), acont C(20))
RETURN 1
ENDIF
IF 'VCONFIG_CONT_IREG' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (contpart C(10), fel_cont N(1), cu_inregistrari N(1), ;
explic_cont C(100), exceptie C(10), pozitie N(1), invers N(1), gasit N(1))
INSERT INTO (m.tcCursor) VALUES ('401', 0, 0, 'Furnizori', '', 0, 0, 0)
RETURN 1
ENDIF
CREATE CURSOR (m.tcCursor) (id_temp N(1))
RETURN 1
ENDPROC
PROCEDURE oExecuta
LPARAMETERS tcSql, tcCursor
IF !EMPTY(m.tcCursor)
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF UPPER(m.tcCursor) == 'CJTVACOL4427'
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14))
ELSE
CREATE CURSOR (m.tcCursor) (id_temp N(1))
ENDIF
ENDIF
RETURN .T.
ENDPROC
PROCEDURE oSelect2Value
LPARAMETERS tcSql, toValue
toValue = ''
RETURN 1
ENDPROC
PROCEDURE oReset
ENDPROC
ENDDEFINE
PROCEDURE CreeazaJtvaColoaneView
LPARAMETERS tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14), denumire C(100), jc N(1), jv N(1), ;
coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14) NULL, afisat N(1), ;
id_jtva_ex N(14) NULL, id_jtva_neex N(14) NULL, ordine N(8), ;
taxcode N(6) NULL, taxcode_neexigibil N(6) NULL, taxcode_n50 N(6) NULL, ;
taxcode_n50_tvai N(6) NULL, taxcode_n100 N(6) NULL, taxcode_regularizare N(6) NULL, taxcode_tvai N(6) NULL)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, afisat, ordine, cota_tva) VALUES (0, '', 0, 0, 1, 0, 0)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (220, 'ACH. IMP. 21%', 1, 0, 'FO21B', 21, 221, 1, 1, 301204)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (221, 'TVA ACH. IMP. 21%', 1, 0, 'FO21T', 21, 1, 2, 301204)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (222, 'ACH. IMP. 11%', 1, 0, 'FO11B', 11, 223, 1, 3, 301205)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (223, 'TVA ACH. IMP. 11%', 1, 0, 'FO11T', 11, 1, 4, 301205)
ENDPROC

View File

@@ -0,0 +1,12 @@
# test_discount_multicota.ps1 - wrapper peste harness-ul generic pentru discountul financiar
# distribuit pe doua cote TVA (21%/11%) - Runda32.
# powershell -ExecutionPolicy Bypass -File test_discount_multicota.ps1
$ErrorActionPreference = 'Stop'
$Teste = $PSScriptRoot
& (Join-Path (Split-Path $Teste -Parent) 'vfp_ui_harness.ps1') `
-TestPrg (Join-Path $Teste 'test_discount_multicota.prg') `
-Steps @('factura_creata','articole_adaugate','sincronizare','final') `
-ShotsDir (Join-Path $Teste 'screenshots_discount_multicota') `
-SyncDir (Join-Path $Teste 'uisync_discount_multicota') `
-StepTimeoutSec 180 `
-ReadyTimeoutSec 180

View File

@@ -0,0 +1,624 @@
* test_discount_valuta.prg
* Runda32 (model B/G/T): discount financiar pe factura de import IN VALUTA - verifica suma
* (lei) si suma_val (valuta) pe randul G (discount) si pe randul T (TVA pe baza neta), pentru
* DOUA valute diferite (EUR cu suma_lei introdusa manual, GBP cu suma_lei auto-calculata din
* curs) - discountul insusi e introdus in valuta facturii (aceeasi unitate ca txtSuma).
*
* DOC1 (EUR, curs 4.50, 1000 EUR, nSumaLei introdus manual = 4500.00):
* discount baza = 200 EUR -> disc_baza_lei=900.00, disc_baza_val=200.00
* G.suma=900.00, G.suma_val=200.00
* T.suma = (4500.00-900.00)*21% = 756.00, T.suma_val = (1000.00-200.00)*21% = 168.00
* DOC2 (GBP, curs 5.75, 500 GBP, nSumaLei auto = ROUND(500*5.75,2) = 2875.00):
* discount baza = 60 GBP -> disc_baza_lei=345.00, disc_baza_val=60.00
* G.suma=345.00, G.suma_val=60.00
* T.suma = (2875.00-345.00)*21% = 531.30, T.suma_val = (500.00-60.00)*21% = 92.40
*
* Flux REAL: dialogul `import_adauga_factura` (toDlg construit inline, capcana l -
* CREATEOBJECT/ADDPROPERTY nu merg dintr-o procedura in acest runtime headless).
*
* Rulare:
* powershell -ExecutionPolicy Bypass -File test_discount_valuta.ps1
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET DECIMALS TO 4
SET NULLDISPLAY TO ''
CLOSE DATABASES
PUBLIC gcUILog, gcSyncDir
gcUILog = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\test_discount_valuta_log.txt"
gcSyncDir = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\uisync_discount_valuta\"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcUILog)
ON ERROR DO DvErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
TRY
LOCAL gcAppPath, lcPath
gcAppPath = "D:\ROA\ROAGEST\"
SET DEFAULT TO (gcAppPath)
lcPath = gcAppPath + 'Date;' + gcAppPath + 'Include;' + gcAppPath + 'FERESTRE;' + ;
gcAppPath + 'GRAFICE;' + gcAppPath + 'CLASE;' + gcAppPath + 'MENIURI;' + ;
gcAppPath + 'PROGRAME;' + gcAppPath + 'RAPOARTE;' + gcAppPath + 'COMUN;' + ;
gcAppPath + 'COMUN\CLASE;' + gcAppPath + 'COMUN\FERESTRE;' + gcAppPath + 'COMUN\PROGRAME;' + ;
gcAppPath + 'COMUN\GRAFICE;' + gcAppPath + 'COMUN\RAPOARTE;' + gcAppPath + 'COMUN\MENIURI;' + ;
gcAppPath + 'COMUN\UTILE\GRIDEXTRAS;' + gcAppPath + 'COMUN\UTILE\CTL32;' + ;
gcAppPath + 'COMUN\UTILE\HPDF;' + gcAppPath + 'COMUN\UTILE\HPDF\REPORTOUTPUT;' + ;
gcAppPath + 'COMUN\UTILE\WEB;' + gcAppPath + 'COMUN\UTILE\EXCEL;' + ;
ADDBS(SUBSTR(gcAppPath,1,RAT([\],gcAppPath,2)))+[COMUNROA\]
SET PATH TO &lcPath ADDITIVE
DO DvLog WITH 'SET PATH OK'
*----- CLASE -----
SET CLASSLIB TO (gcAppPath + "comun\clase\appwiz") ADDITIVE
SET CLASSLIB TO GESTIUNI ADDITIVE
SET CLASSLIB TO CAUT ADDITIVE
SET CLASSLIB TO BAZA ADDITIVE
SET CLASSLIB TO comun ADDITIVE
SET CLASSLIB TO accessibility.vcx ADDITIVE
SET CLASSLIB TO messagebox ADDITIVE
SET CLASSLIB TO registry ADDITIVE
SET CLASSLIB TO cauta_alfa_forms.vcx ADDITIVE
SET CLASSLIB TO DECABAZA ADDITIVE
SET CLASSLIB TO onomenclatoare ADDITIVE
SET CLASSLIB TO stocuri.vcx ADDITIVE
SET CLASSLIB TO rulaje.vcx ADDITIVE
SET CLASSLIB TO ointroduceri ADDITIVE
SET CLASSLIB TO ointroduceri_web ADDITIVE
SET CLASSLIB TO ointroduceri_depozit ADDITIVE
SET CLASSLIB TO overificari ADDITIVE
SET CLASSLIB TO ferestre_oracle ADDITIVE
SET CLASSLIB TO ferestre_cere_date.vcx ADDITIVE
SET CLASSLIB TO configurare.vcx ADDITIVE
SET CLASSLIB TO serii_numere.vcx ADDITIVE
SET CLASSLIB TO omodificari.vcx ADDITIVE
SET CLASSLIB TO ocompensari.vcx ADDITIVE
SET CLASSLIB TO caut_ora ADDITIVE
SET CLASSLIB TO onote_contabile ADDITIVE
SET CLASSLIB TO otoolbar ADDITIVE
SET CLASSLIB TO bon_fisc ADDITIVE
SET CLASSLIB TO onom_articole ADDITIVE
SET CLASSLIB TO onom_retete ADDITIVE
SET CLASSLIB TO orapoarte ADDITIVE
SET CLASSLIB TO orapoarte_gestiuni ADDITIVE
SET CLASSLIB TO orapoarte_parametri ADDITIVE
SET CLASSLIB TO ONOM_CURS ADDITIVE
SET CLASSLIB TO ctl32_statusbar_fals.vcx ADDITIVE
SET CLASSLIB TO ctl32_common.vcx ADDITIVE
SET CLASSLIB TO ctl32_structs.vcx ADDITIVE
SET CLASSLIB TO ctl32_progressbar.vcx ADDITIVE
SET CLASSLIB TO ctl32_balloontip.vcx ADDITIVE
SET CLASSLIB TO ocriterii.vcx ADDITIVE
SET CLASSLIB TO oavize.vcx ADDITIVE
SET CLASSLIB TO onomenclatoare2 ADDITIVE
SET CLASSLIB TO wwdialogs.vcx ADDITIVE
SET CLASSLIB TO oimportxml.vcx ADDITIVE
SET CLASSLIB TO excelxml.vcx ADDITIVE
SET CLASSLIB TO orapoarte_obinv.vcx ADDITIVE
DO DvLog WITH 'SET CLASSLIB OK'
*----- PROCEDURI (mock-uri PRIMELE, ui_harness la final) -----
SET PROCEDURE TO PROCEDURI
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_cauta_nom_articole.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\mock_caut_valuta.prg" ADDITIVE
SET PROCEDURE TO acces_meniu ADDITIVE
SET PROCEDURE TO cauta_alfa ADDITIVE
SET PROCEDURE TO pmenu ADDITIVE
SET PROCEDURE TO proceduri_comune ADDITIVE
SET PROCEDURE TO quitapp ADDITIVE
SET PROCEDURE TO init_program ADDITIVE
SET PROCEDURE TO oproceduri_listari.prg ADDITIVE
SET PROCEDURE TO oproceduri_configurare.prg ADDITIVE
SET PROCEDURE TO oproceduri_articole.prg ADDITIVE
SET PROCEDURE TO oproceduri_retete.prg ADDITIVE
SET PROCEDURE TO orapoarte.prg ADDITIVE
SET PROCEDURE TO mesaje ADDITIVE
SET PROCEDURE TO oserii_numere.prg ADDITIVE
SET PROCEDURE TO oexport.prg ADDITIVE
SET PROCEDURE TO wwConfig.prg ADDITIVE
SET PROCEDURE TO proceduri_rapoarte.prg ADDITIVE
SET PROCEDURE TO OPROCEDURI_CURS.PRG ADDITIVE
SET PROCEDURE TO validare.prg ADDITIVE
SET PROCEDURE TO GENCURSOR.PRG ADDITIVE
SET PROCEDURE TO OPROCEDURI_COMUNE.PRG ADDITIVE
SET PROCEDURE TO OINIT_OPTIUNI.PRG ADDITIVE
SET PROCEDURE TO updateserver.prg ADDITIVE
SET PROCEDURE TO oinainte_de.prg ADDITIVE
SET PROCEDURE TO ooperatii_comune.prg ADDITIVE
SET PROCEDURE TO Ocompensari.PRG ADDITIVE
SET PROCEDURE TO OPROCEDURI_aMS.PRG ADDITIVE
SET PROCEDURE TO oproceduri_rulaje ADDITIVE
SET PROCEDURE TO oproceduri_stocuri ADDITIVE
SET PROCEDURE TO OINTRODUCERI ADDITIVE
SET PROCEDURE TO oHeader.prg ADDITIVE
SET PROCEDURE TO proceduri_excel.PRG ADDITIVE
SET PROCEDURE TO onomenclatoare.PRG ADDITIVE
SET PROCEDURE TO osecurity ADDITIVE
SET PROCEDURE TO ocautare ADDITIVE
SET PROCEDURE TO orefaceri ADDITIVE
SET PROCEDURE TO ofacturare_comun.PRG ADDITIVE
SET PROCEDURE TO ofacturare_stoc.PRG ADDITIVE
SET PROCEDURE TO oproceduri_casademarcat ADDITIVE
SET PROCEDURE TO oproceduri_casa_marcat_e500 ADDITIVE
SET PROCEDURE TO oproceduri_casa_marcat_mp500 ADDITIVE
SET PROCEDURE TO oproceduri_util.prg ADDITIVE
SET PROCEDURE TO wwxmlhttp.prg ADDITIVE
SET PROCEDURE TO ini.prg ADDITIVE
SET PROCEDURE TO odocumente.prg ADDITIVE
SET PROCEDURE TO regex.prg ADDITIVE
SET PROCEDURE TO wwutils.prg ADDITIVE
SET PROCEDURE TO inchidere_k ADDITIVE
SET PROCEDURE TO iniacces.prg ADDITIVE
SET PROCEDURE TO oupdate.prg ADDITIVE
SET PROCEDURE TO procese.prg ADDITIVE
SET PROCEDURE TO version.prg ADDITIVE
SET PROCEDURE TO xmlaccess.prg ADDITIVE
SET PROCEDURE TO xmlparser.prg ADDITIVE
SET PROCEDURE TO filebringer.prg ADDITIVE
SET PROCEDURE TO wwcodeupdate.prg ADDITIVE
SET PROCEDURE TO wwhttp.prg ADDITIVE
SET PROCEDURE TO xdate.prg ADDITIVE
SET PROCEDURE TO ofacturare.prg ADDITIVE
SET PROCEDURE TO oproceduri_obinv.prg ADDITIVE
SET PROCEDURE TO oproceduri_facturare.prg ADDITIVE
SET PROCEDURE TO email.prg ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\ui_harness.prg" ADDITIVE
DO DvLog WITH 'SET PROCEDURE OK'
PUBLIC goMockValuta
goMockValuta = CREATEOBJECT('Custom')
goMockValuta.AddProperty('id_valuta', 978)
goMockValuta.AddProperty('nume_val', 'EUR')
*----- Globale -----
PUBLIC gnPc, gnPval, gnPcant, gnPpret, gnPPretval, gnPCurs, gnPVal, gnPPretV, gnPPretVal
STORE 2 TO gnPc, gnPval, gnPVal
gnPcant = 3
STORE 4 TO gnPpret, gnPPretval, gnPPretVal, gnPPretV, gnPCurs
PUBLIC gl406, gcS, gnAn, gnLuna, gnIdFirma, gnIdSucursala, gcAcces, gcFirma
gl406 = .T.
gcS = 'CONTAFIN'
gnAn = YEAR(DATE())
gnLuna = MONTH(DATE())
gnIdFirma = 110
gnIdSucursala = 110
gcAcces = "1;2;3;4;5;6;7;8;"
gcFirma = gcS
PUBLIC nror(65000)
PUBLIC gnButon
STORE 2 TO gnButon
PUBLIC gcMockArtCodmat, gcMockAcontCrt
gcMockArtCodmat = ''
gcMockAcontCrt = ''
PUBLIC gnMockRaspuns
gnMockRaspuns = 6
PUBLIC goExecutor, goApp
goExecutor = CREATEOBJECT('dummyexecutor')
goApp = CREATEOBJECT('dummyapp')
*----- poAct: antetul notei (moneda principala EUR, curs 4.50) -----
PUBLIC poAct
poAct = CREATEOBJECT('Custom')
poAct.AddProperty('nume_val', 'EUR')
poAct.AddProperty('curs', 4.50)
poAct.AddProperty('proc_tva', 1.21)
poAct.AddProperty('nnir', 0)
poAct.AddProperty('id_valuta', 978)
poAct.AddProperty('id_fdoc', 1)
poAct.AddProperty('fdoc', 'Factura')
poAct.AddProperty('id_partc', 601)
poAct.AddProperty('partc', 'EURO IMPEX')
poAct.AddProperty('serie_act', '')
poAct.AddProperty('dataact', DATE())
poAct.AddProperty('tva_incasare', 0)
poAct.AddProperty('id_set', 1)
poAct.AddProperty('id_gestin', 1)
*----- jtva_coloane2 / saft_taxtable: perechi reale 21% -----
IF USED('jtva_coloane2')
USE IN ('jtva_coloane2')
ENDIF
CREATE CURSOR jtva_coloane2 (ordine N(8), id_jtva_coloana N(14), denumire C(100), ;
jc N(1), jv N(1), afisat N(1), coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14))
INSERT INTO jtva_coloane2 VALUES (0, 0, '', 0, 0, 1, '', '', 0, 0)
INSERT INTO jtva_coloane2 VALUES (1, 208, 'ACH. INT. 21%', 1, 0, 1, 'RO21B', 'RO21T', 21, 209)
INSERT INTO jtva_coloane2 VALUES (2, 209, 'TVA ACH. INT. 21%', 1, 0, 1, 'RO21T', '', 21, 0)
INSERT INTO jtva_coloane2 VALUES (3, 220, 'ACH. IMP. 21%', 1, 0, 1, 'FO21B', 'FO21T', 21, 221)
INSERT INTO jtva_coloane2 VALUES (4, 221, 'TVA ACH. IMP. 21%', 1, 0, 1, 'FO21T', '', 21, 0)
IF USED('saft_taxtable')
USE IN ('saft_taxtable')
ENDIF
CREATE CURSOR saft_taxtable (taxname C(250) NULL, typename C(250) NULL, taxcode N(6) NULL, ;
taxtype N(3) NULL, descriere C(250) NULL, tip C(100) NULL, descriere_tip C(250) NULL, ;
procent_taxa N(7,2) NULL, procent_prorata N(7,2) NULL, inactiv N(1) NULL, tva N(1) NULL, ;
wht N(1) NULL, tva_achizitii N(1) NULL, tva_livrari N(1) NULL)
INDEX ON taxcode TAG taxcode
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('', 0, '', 0, 1, 1, 1, 1)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301204-Import de bunuri cota 21%', 301204, '', 21, 1, 0, 1, 0)
DO CreeazaIntrodc WITH 'introdc'
DO CreeazaIntrodc WITH 'introdc_sablon'
INSERT INTO introdc_sablon (scd, scc, cu_tva, ordine, id_set, participa_valuta, tip_rand, ;
id_jtva_coloana, ptva, explicatie_tva) ;
VALUES ('371', '401', 1, 1, 1, .T., 'B', 208, 21, 'ACH. INT. 21%')
INSERT INTO introdc_sablon (scd, scc, cu_tva, ordine, id_set, participa_valuta, tip_rand, ;
id_jtva_coloana, ptva, explicatie_tva) ;
VALUES ('4426', '401', 1, 2, 1, .T., 'T', 209, 21, 'TVA ACH. INT. 21%')
GO TOP IN introdc_sablon
DO CreeazaRulTemp
INSERT INTO rul_temp (denumire, codmat, cant, pret, pret_lei, cont, cota_tva) ;
VALUES ('PLACEHOLDER', 'PH', 1, 1, 1, '371', 21)
SELECT introdc
INDEX ON Str(Nvl(nr_doc,0),8) + Icase(tip_rand='B','1', tip_rand='S','2', tip_rand='G','3', tip_rand='T','4', tip_rand='D','5', '6') + Padr(Nvl(scd,''),10) TAG ord_doc
SET ORDER TO ord_doc
DO DvLog WITH 'cursoare pregatite, CREATEOBJECT(import_nota, .F.)'
PUBLIC goObj
goObj = CREATEOBJECT('IMPORT_nota', .F.)
IF VARTYPE(goObj) <> 'O'
DO DvLog WITH 'FAIL: instantiere import_nota'
DO HarnessDone WITH 'done-error'
QUIT
ENDIF
goObj.lDialogAratat = .T.
goObj.oact = poAct
goObj.lSpargeSecundare = .F.
goObj.WindowType = 0
goObj.Visible = .T.
goObj.Show()
goObj.WindowState = 2
DOEVENTS FORCE
SELECT rul_temp
ZAP
goObj.gridart.Refresh()
DOEVENTS FORCE
PRIVATE pnAsserts, pnPass
STORE 0 TO pnAsserts, pnPass
*========================= DOC1: EUR, nSumaLei introdus manual =========================
PUBLIC goDlg, goT, gcDocKey1
DO AdaugaFacturaValuta WITH 17000, 'EURO IMPEX', 601, 978, 'EUR', 4.50, 1000, 4500.00, 200.00
SELECT introdc
SET ORDER TO
LOCATE FOR nract = 17000 AND tip_rand == 'B'
IF FOUND()
gcDocKey1 = ALLTRIM(NVL(doc_key,''))
ENDIF
SELECT introdc
SET ORDER TO ord_doc
SELECT introdc
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND tip_rand == 'B'
=Assert3('1-DOC1(EUR): B.suma=4500.00 (nSumaLei manual)', suma, 4500.00)
=Assert3('2-DOC1(EUR): B.suma_val=1000.00', suma_val, 1000.00)
SELECT introdc
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND tip_rand == 'G'
=Assert3('3-DOC1(EUR): randul G gasit', IIF(FOUND(),1,0), 1)
IF FOUND()
=Assert3('4-DOC1(EUR): G.suma=900.00', suma, 900.00)
=Assert3('5-DOC1(EUR): G.suma_val=200.00', suma_val, 200.00)
ELSE
pnAsserts = pnAsserts + 2
DO DvLog WITH ' FAIL 4-5: G (DOC1) negasit'
ENDIF
SELECT introdc
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND tip_rand == 'T'
=Assert3('6-DOC1(EUR): randul T gasit', IIF(FOUND(),1,0), 1)
IF FOUND()
=Assert3('7-DOC1(EUR): T.suma=756.00 ((4500-900)*21%)', suma, 756.00)
=Assert3('8-DOC1(EUR): T.suma_val=168.00 ((1000-200)*21%)', suma_val, 168.00)
ELSE
pnAsserts = pnAsserts + 2
DO DvLog WITH ' FAIL 7-8: T (DOC1) negasit'
ENDIF
DO HarnessStep WITH 0, 'DOC1 (EUR) verificat'
*========================= DOC2: GBP, nSumaLei auto-calculat din curs =========================
PUBLIC gcDocKey2
DO AdaugaFacturaValuta WITH 17001, 'BRITISH TRADE LTD', 604, 826, 'GBP', 5.75, 500, 0, 60.00
SELECT introdc
LOCATE FOR nract = 17001 AND tip_rand == 'B'
IF FOUND()
gcDocKey2 = ALLTRIM(NVL(doc_key,''))
ENDIF
SELECT introdc
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey2 AND tip_rand == 'B'
=Assert3('9-DOC2(GBP): B.suma=2875.00 (auto ROUND(500*5.75,2))', suma, 2875.00)
=Assert3('10-DOC2(GBP): B.suma_val=500.00', suma_val, 500.00)
SELECT introdc
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey2 AND tip_rand == 'G'
=Assert3('11-DOC2(GBP): randul G gasit', IIF(FOUND(),1,0), 1)
IF FOUND()
=Assert3('12-DOC2(GBP): G.suma=345.00', suma, 345.00)
=Assert3('13-DOC2(GBP): G.suma_val=60.00', suma_val, 60.00)
ELSE
pnAsserts = pnAsserts + 2
DO DvLog WITH ' FAIL 12-13: G (DOC2) negasit'
ENDIF
SELECT introdc
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey2 AND tip_rand == 'T'
=Assert3('14-DOC2(GBP): randul T gasit', IIF(FOUND(),1,0), 1)
IF FOUND()
=Assert3('15-DOC2(GBP): T.suma=531.30 ((2875-345)*21%)', suma, 531.30)
=Assert3('16-DOC2(GBP): T.suma_val=92.40 ((500-60)*21%)', suma_val, 92.40)
ELSE
pnAsserts = pnAsserts + 2
DO DvLog WITH ' FAIL 15-16: T (DOC2) negasit'
ENDIF
DO HarnessStep WITH 1, 'DOC2 (GBP) verificat'
DO DvLog WITH 'REZULTAT: ' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' assert-uri PASS'
IF pnPass = pnAsserts
DO DvLog WITH 'REZULTAT: PASS (' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ')'
ELSE
DO DvLog WITH 'REZULTAT: FAIL (' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' assert-uri PASS)'
ENDIF
DO HarnessStep WITH 2, 'final: ' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' PASS'
DO HarnessDone WITH 'done'
CATCH TO loExc
DO DvLog WITH 'CATCH ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']'
DO HarnessDone WITH 'done-error'
ENDTRY
QUIT
*==================================================================================
PROCEDURE AdaugaFacturaValuta
*-- factura in valuta oarecare (id/nume/curs date), discount in ACEEASI valuta ca suma.
LPARAMETERS tnNract, tcPartener, tnIdPartener, tnIdValuta, tcValuta, tnCurs, tnSuma, tnSumaLei, tnDiscBazaVal
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = tnNract
goDlg.dDataAct = DATE()
goDlg.nIdPartener = tnIdPartener
goDlg.cPartener = tcPartener
goDlg.cExplicatia = 'Import marfa ' + tcPartener
goDlg.nSuma = tnSuma
goDlg.nSumaLei = tnSumaLei
goDlg.nCurs = tnCurs
goDlg.nIdValuta = tnIdValuta
goDlg.cValuta = tcValuta
goDlg.nIdExplicatieTva = 208
goDlg.cExplicatieTva = 'ACH. INT. 21%'
goDlg.optTipTva.Value = 1
goDlg.chkInValutaCont.Value = 1
goDlg.chkParticipaValuta.Value = 1
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO DvLog WITH 'DOC ' + TRANSFORM(tnNract) + ' (' + tcValuta + '): valideaza = ' + TRANSFORM(goDlg.valideaza())
goT = CREATEOBJECT('Empty')
=ADDPROPERTY(goT,'serie_act','')
=ADDPROPERTY(goT,'nract',goDlg.nNract)
=ADDPROPERTY(goT,'dataact',goDlg.dDataAct)
=ADDPROPERTY(goT,'fdoc',goDlg.cFelDoc)
=ADDPROPERTY(goT,'id_fdoc',goDlg.nIdFdoc)
=ADDPROPERTY(goT,'id_partc',goDlg.nIdPartener)
=ADDPROPERTY(goT,'partc',goDlg.cPartener)
=ADDPROPERTY(goT,'explicatia',ALLTRIM(NVL(goDlg.cExplicatia,'')))
=ADDPROPERTY(goT,'suma',IIF(goDlg.nSumaLei<>0,goDlg.nSumaLei,ROUND(goDlg.nSuma*goDlg.nCurs,gnPC)))
=ADDPROPERTY(goT,'suma_val',goDlg.nSuma)
=ADDPROPERTY(goT,'in_valuta',1)
=ADDPROPERTY(goT,'participa_valuta',.T.)
=ADDPROPERTY(goT,'id_valuta',goDlg.nIdValuta)
=ADDPROPERTY(goT,'curs',goDlg.nCurs)
=ADDPROPERTY(goT,'nume_val',ALLTRIM(NVL(goDlg.cValuta,'')))
=ADDPROPERTY(goT,'cTipTva','F')
=ADDPROPERTY(goT,'id_jtva_coloana',goDlg.nIdExplicatieTva)
=ADDPROPERTY(goT,'dvi_serie','')
=ADDPROPERTY(goT,'dvi_nract',0)
=ADDPROPERTY(goT,'dvi_dataact',DATE())
=ADDPROPERTY(goT,'dvi_id_fdoc',0)
=ADDPROPERTY(goT,'dvi_fdoc','')
=ADDPROPERTY(goT,'dvi_id_partc',0)
=ADDPROPERTY(goT,'dvi_partc','')
=ADDPROPERTY(goT,'dvi_scc','401')
=ADDPROPERTY(goT,'dvi_tva_lei',0)
=ADDPROPERTY(goT,'dvi_tva_val',0)
=ADDPROPERTY(goT,'dvi_in_valuta',.F.)
=ADDPROPERTY(goT,'dvi_id_valuta',0)
=ADDPROPERTY(goT,'dvi_curs',0)
=ADDPROPERTY(goT,'dvi_nume_val','')
=ADDPROPERTY(goT,'dvi_valuta_proprie',0)
=ADDPROPERTY(goT,'disc_baza_lei',ROUND(tnDiscBazaVal*tnCurs,gnPC))
=ADDPROPERTY(goT,'disc_baza_val',tnDiscBazaVal)
DO DvLog WITH 'DOC ' + TRANSFORM(tnNract) + ' (' + tcValuta + '): do_adauga_factura = ' + TRANSFORM(goObj.do_adauga_factura(goT))
goDlg.Hide()
DOEVENTS FORCE
ENDPROC
PROCEDURE CreeazaRulTemp
IF USED('rul_temp')
USE IN ('rul_temp')
ENDIF
CREATE CURSOR rul_temp ( ;
id_rul N(20,0), an N(4,0), luna N(2,0), cod N(20,0);
, serie C(100), nnir N(20,0), id_articol N(10,0), denumire C(100);
, codmat C(50), codmatf C(50), codbare C(50), um C(20);
, id_gestiune N(5,0), nume_gestiune C(50), cgest C(20), nr_pag N(2,0);
, gestionar C(50), comisie_receptie1 C(50), comisie_receptie2 C(50), comisie_receptie3 C(50);
, cant N(14,3), cante N(14,3), cont C(10), acont C(20);
, pret N(18,4), tva N(18,4), valoare N(18,4), valtva N(18,4);
, proc_tva N(5,2), pretv N(18,4), pretvtva N(18,4), tvav N(18,4);
, valoarev N(18,4), valtvav N(18,4), proc_tvav N(5,2), adaos N(18,4);
, adaos_tva N(18,4), valoare_adaos N(18,4), valtva_adaos N(18,4), procent N(10,3);
, discunitar N(18,4), discount_tva N(18,4), valoare_discount N(18,4), valtva_discount N(18,4);
, proc_disc N(7,3), pretd N(14,4), curs N(18,4), id_valuta N(10,0);
, nume_val C(20), id_lucrare N(20,0), nrord C(100), id_responsabil N(10,0);
, nresp C(100), resp_marca N(18,4), dataact T, id_util N(5,0);
, util C(30), dataora T, id_sectie N(5,0), sectie C(50);
, csectie C(10), alcooltutun N(1,0), datain T, dataout T;
, id_fact N(20,0), id_gestiunec N(10,0), nume_gestiunec C(50), cgestc C(20);
, id_responsabilc N(5,0), id_reteta N(10,0), reteta C(50), nrespc C(100);
, respc_marca N(18,4), id_set N(20,0), id_tip_rulaj N(10,0), tip_rulaj C(50);
, id_obiect_depozit N(10,0), id_rul_aux N(10,0), nract N(20,0), serie_act C(10);
, dataoras T, id_utils N(10,0), lot C(30), adata_expirare T;
, id_sucursala N(5,0), sucursala C(250), id_part_rez N(10,0), part_rez C(100);
, id_lucrare_rez N(10,0), nrord_rez C(100), subgrupa C(100), grupa C(100);
, id_subgrupa N(5,0), id_grupa N(5,0), in_stoc N(1,0), in_crm N(1,0);
, id_furnizor N(10,0), furnizor C(100), id_jtva_coloana N(4,0), explicatie_tva C(100);
, taxcode N(6,0), taxname C(254), saft_procent N(18,4), codnc8 C(20);
, id_tara_origine N(4,0), cod_tara_origine C(5), tara_origine C(50), greutate N(12,4);
, fdoc C(30), id_fdoc N(18,4);
, pret_lei N(18,4), pret_val N(14,4), cota_tva N(6,2))
ENDPROC
PROCEDURE CreeazaIntrodc
LPARAMETERS tcAlias
IF USED(tcAlias)
USE IN (tcAlias)
ENDIF
CREATE CURSOR (tcAlias) ( ;
id_note N(14), explicatia C(100), scd C(10), ascd C(20), scc C(10), ascc C(20), ;
cu_tva N(1), id_set N(14), ordine N(8), in_valuta N(1), id_jtva_coloana N(14) NULL, ;
ptva N(6,2), explicatie_tva C(50), tipjurnal C(2), taxcode N(6), paymentcode C(9), ;
suma N(18,4), suma_val N(18,4), id_partd N(14), id_partc N(14), partd C(100), partc C(100), ;
id_fact N(14), id_factd N(14), id_factc N(14), pereched N(14), perechec N(14), ;
nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), expl_manual N(1), ;
scd_orig C(20), ascd_orig C(20), rand_dvi N(1), valuta_proprie N(1))
ENDPROC
PROCEDURE Assert3
LPARAMETERS tcLabel, tuActual, tuExpected
pnAsserts = pnAsserts + 1
IF ABS(NVL(tuActual,0) - tuExpected) < 0.02
pnPass = pnPass + 1
DO DvLog WITH ' PASS ' + tcLabel + ' (=' + TRANSFORM(tuActual) + ')'
ELSE
DO DvLog WITH ' FAIL ' + tcLabel + ' (actual=' + TRANSFORM(tuActual) + ' asteptat=' + TRANSFORM(tuExpected) + ')'
ENDIF
ENDPROC
PROCEDURE DvErr
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
DO DvLog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
ENDPROC
PROCEDURE DvLog
LPARAMETERS tcMsg
SET SAFETY OFF
LOCAL lcL
lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '')
STRTOFILE(lcL + tcMsg + CHR(13)+CHR(10), gcUILog)
ENDPROC
DEFINE CLASS dummyapp AS Custom
PROCEDURE ReadIni
LPARAMETERS tcSection, tcKey
RETURN ''
ENDPROC
PROCEDURE WriteIni
LPARAMETERS tcSection, tcKey, tcValue
RETURN .T.
ENDPROC
ENDDEFINE
DEFINE CLASS dummyexecutor AS Custom
cEroare = ''
PROCEDURE oExecute
LPARAMETERS tcSql, tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF 'VJTVA_COLOANE' $ UPPER(m.tcSql)
DO CreeazaJtvaColoaneView WITH m.tcCursor
RETURN 1
ENDIF
IF UPPER(ALLTRIM(m.tcCursor)) == 'RUL_TEMP'
CREATE CURSOR (m.tcCursor) (denumire C(100), codmat C(30), cant N(14,3), ;
pret_val N(18,4), pretd N(18,4), pret N(18,4), pret_lei N(18,4), cont C(10), ;
acont C(20), serie C(30), lot C(30), adata_expirare C(10), proc_disc N(6,2), cota_tva N(6,2))
RETURN 1
ENDIF
IF 'CONFIG_ANALITICE' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (camp_leg_prefix C(30), camp_leg_sufix C(30))
INSERT INTO (m.tcCursor) VALUES ('', '')
RETURN 1
ENDIF
IF 'FCONTURI_ANALITICE' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (acont C(20))
INSERT INTO (m.tcCursor) VALUES (IIF(TYPE('gcMockAcontCrt') = 'C', gcMockAcontCrt, ''))
RETURN 1
ENDIF
IF 'VPLCONT_ANALITIC' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (cont C(10), acont C(20))
INSERT INTO (m.tcCursor) VALUES ('371', '4')
RETURN 1
ENDIF
CREATE CURSOR (m.tcCursor) (id_temp N(1))
RETURN 1
ENDPROC
PROCEDURE oExecuta
LPARAMETERS tcSql, tcCursor
IF !EMPTY(m.tcCursor)
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF UPPER(m.tcCursor) == 'CJTVACOL4427'
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14))
ELSE
CREATE CURSOR (m.tcCursor) (id_temp N(1))
ENDIF
ENDIF
RETURN .T.
ENDPROC
PROCEDURE oSelect2Value
LPARAMETERS tcSql, toValue
toValue = ''
RETURN 1
ENDPROC
PROCEDURE oReset
ENDPROC
ENDDEFINE
PROCEDURE CreeazaJtvaColoaneView
LPARAMETERS tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14), denumire C(100), jc N(1), jv N(1), ;
coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14) NULL, afisat N(1), ;
id_jtva_ex N(14) NULL, id_jtva_neex N(14) NULL, ordine N(8), ;
taxcode N(6) NULL, taxcode_neexigibil N(6) NULL, taxcode_n50 N(6) NULL, ;
taxcode_n50_tvai N(6) NULL, taxcode_n100 N(6) NULL, taxcode_regularizare N(6) NULL, taxcode_tvai N(6) NULL)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, afisat, ordine, cota_tva) VALUES (0, '', 0, 0, 1, 0, 0)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (208, 'ACH. INT. 21%', 1, 0, 'RO21B', 21, 209, 1, 1, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (209, 'TVA ACH. INT. 21%', 1, 0, 'RO21T', 21, 1, 2, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (220, 'ACH. IMP. 21%', 1, 0, 'FO21B', 21, 221, 1, 3, 301204)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (221, 'TVA ACH. IMP. 21%', 1, 0, 'FO21T', 21, 1, 4, 301204)
ENDPROC

View File

@@ -0,0 +1,12 @@
# test_discount_valuta.ps1 - wrapper peste harness-ul generic pentru discountul financiar pe
# factura de import in valuta (EUR/GBP) - suma/suma_val pe randurile G si T - Runda32.
# powershell -ExecutionPolicy Bypass -File test_discount_valuta.ps1
$ErrorActionPreference = 'Stop'
$Teste = $PSScriptRoot
& (Join-Path (Split-Path $Teste -Parent) 'vfp_ui_harness.ps1') `
-TestPrg (Join-Path $Teste 'test_discount_valuta.prg') `
-Steps @('doc1_eur','doc2_gbp','final') `
-ShotsDir (Join-Path $Teste 'screenshots_discount_valuta') `
-SyncDir (Join-Path $Teste 'uisync_discount_valuta') `
-StepTimeoutSec 180 `
-ReadyTimeoutSec 180

View File

@@ -0,0 +1,613 @@
* test_dvi_bifa_valuta.prg
* Runda32 (control nou chkDviInValuta, sectiunea TVA DVI): factura de import IN VALUTA (EUR)
* cu bifa "Valuta" a DVI-ului SCOASA - DVI-ul e platit doar in lei, desi factura insasi e in
* valuta ("factura in valuta, DVI doar in lei", cazul nou din plan).
*
* Verifica:
* - la Init (factura in valuta), bifa porneste BIFATA (chkInValutaCont=1, valuta <> RON);
* - dupa scoaterea bifei: lblDviValuta/txtDviValuta/cmdDviValuta/lblDviCurs/txtDviCurs
* ascunse, nDviCurs=1; txtDviTvaVal ramane vizibil, comuta pe lei (nDviTvaVal recalculat, nu 0);
* - randul T (DVI) creat de do_adauga_factura: FARA valuta/curs/suma_val (in_valuta=0,
* id_valuta=0, curs=0, nume_val='', suma_val=0), suma = nDviTvaLei (introdus direct);
* - valuta_proprie=1 (starea de valuta a DVI-ului difera de a facturii - factura are valuta,
* DVI nu mai are, dupa scoaterea bifei).
*
* Flux REAL: dialogul `import_adauga_factura` (toDlg construit inline in programul principal,
* capcana l - CREATEOBJECT/ADDPROPERTY nu merg dintr-o procedura in acest runtime headless).
*
* CAPCANA l (mock_caut_valuta.prg, confirmata si in test_e2e_dvi_ron_discount.prg): apelul REAL
* goDlg.construieste_todlg() arunca eroarea 11 pe primul Addproperty in acest runtime headless
* (CREATEOBJECT/ADDPROPERTY nu merg corect apelate dintr-o METODA, doar din programul PRINCIPAL) -
* nu poate fi exercitat direct. toDlg se construieste inline in program, cu formula COPIATA
* EXACT din ointroduceri.vc2 PROCEDURE construieste_todlg (~6157-6202, verificata in cache dupa
* ce lane-ul de dialog a terminat Runda32):
* lcDviVal = Iif(lDviValutaDirty, cDviValuta, cValuta) -- dvi_valuta_efectiva()
* llDviFaraVal = (chkDviInValuta.Value=0) Or Empty(lcDviVal) Or Upper(lcDviVal)=='RON'
* llFactFaraVal = Empty(cValuta) Or Upper(cValuta)=='RON'
* llDviPropriu = (dvi_id_valuta_efectiva()<>nIdValuta Or dvi_curs_efectiv()<>nCurs)
* dvi_valuta_proprie = Iif(llDviFaraVal And llFactFaraVal, 0, Iif(llDviFaraVal<>llFactFaraVal, 1, Iif(llDviPropriu,1,0)))
* IMPORTANT: dvi_curs_efectiv()/dvi_id_valuta_efectiva() NU citesc nDviCurs/nDviIdValuta direct -
* doar cand lDviValutaDirty/lDviCursDirty sunt adevarate (alegere explicita prin picker/curs
* tastat). In acest test bifa e scoasa fara sa se atinga picker-ul/cursul DVI, deci flagurile
* dirty raman .F. si valorile EFECTIVE raman cele ale facturii (nIdValuta/nCurs), NU nDviCurs=1
* fortat de actualizeaza_stare_dvi_valuta() pe widget - acel 1 e doar pentru afisaj, nefolosit
* de formula toDlg.
* SCOPUL testului ramane do_adauga_factura() (crearea randului T dintr-un toDlg dat) - NU
* verifica daca dialogul real produce chiar acest toDlg (blocat de capcana l).
*
* Rulare:
* powershell -ExecutionPolicy Bypass -File test_dvi_bifa_valuta.ps1
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET DECIMALS TO 4
SET NULLDISPLAY TO ''
CLOSE DATABASES
PUBLIC gcUILog, gcSyncDir
gcUILog = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\test_dvi_bifa_valuta_log.txt"
gcSyncDir = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\uisync_dvi_bifa_valuta\"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcUILog)
ON ERROR DO BvErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
TRY
LOCAL gcAppPath, lcPath
gcAppPath = "D:\ROA\ROAGEST\"
SET DEFAULT TO (gcAppPath)
lcPath = gcAppPath + 'Date;' + gcAppPath + 'Include;' + gcAppPath + 'FERESTRE;' + ;
gcAppPath + 'GRAFICE;' + gcAppPath + 'CLASE;' + gcAppPath + 'MENIURI;' + ;
gcAppPath + 'PROGRAME;' + gcAppPath + 'RAPOARTE;' + gcAppPath + 'COMUN;' + ;
gcAppPath + 'COMUN\CLASE;' + gcAppPath + 'COMUN\FERESTRE;' + gcAppPath + 'COMUN\PROGRAME;' + ;
gcAppPath + 'COMUN\GRAFICE;' + gcAppPath + 'COMUN\RAPOARTE;' + gcAppPath + 'COMUN\MENIURI;' + ;
gcAppPath + 'COMUN\UTILE\GRIDEXTRAS;' + gcAppPath + 'COMUN\UTILE\CTL32;' + ;
gcAppPath + 'COMUN\UTILE\HPDF;' + gcAppPath + 'COMUN\UTILE\HPDF\REPORTOUTPUT;' + ;
gcAppPath + 'COMUN\UTILE\WEB;' + gcAppPath + 'COMUN\UTILE\EXCEL;' + ;
ADDBS(SUBSTR(gcAppPath,1,RAT([\],gcAppPath,2)))+[COMUNROA\]
SET PATH TO &lcPath ADDITIVE
DO BvLog WITH 'SET PATH OK'
*----- CLASE -----
SET CLASSLIB TO (gcAppPath + "comun\clase\appwiz") ADDITIVE
SET CLASSLIB TO GESTIUNI ADDITIVE
SET CLASSLIB TO CAUT ADDITIVE
SET CLASSLIB TO BAZA ADDITIVE
SET CLASSLIB TO comun ADDITIVE
SET CLASSLIB TO accessibility.vcx ADDITIVE
SET CLASSLIB TO messagebox ADDITIVE
SET CLASSLIB TO registry ADDITIVE
SET CLASSLIB TO cauta_alfa_forms.vcx ADDITIVE
SET CLASSLIB TO DECABAZA ADDITIVE
SET CLASSLIB TO onomenclatoare ADDITIVE
SET CLASSLIB TO stocuri.vcx ADDITIVE
SET CLASSLIB TO rulaje.vcx ADDITIVE
SET CLASSLIB TO ointroduceri ADDITIVE
SET CLASSLIB TO ointroduceri_web ADDITIVE
SET CLASSLIB TO ointroduceri_depozit ADDITIVE
SET CLASSLIB TO overificari ADDITIVE
SET CLASSLIB TO ferestre_oracle ADDITIVE
SET CLASSLIB TO ferestre_cere_date.vcx ADDITIVE
SET CLASSLIB TO configurare.vcx ADDITIVE
SET CLASSLIB TO serii_numere.vcx ADDITIVE
SET CLASSLIB TO omodificari.vcx ADDITIVE
SET CLASSLIB TO ocompensari.vcx ADDITIVE
SET CLASSLIB TO caut_ora ADDITIVE
SET CLASSLIB TO onote_contabile ADDITIVE
SET CLASSLIB TO otoolbar ADDITIVE
SET CLASSLIB TO bon_fisc ADDITIVE
SET CLASSLIB TO onom_articole ADDITIVE
SET CLASSLIB TO onom_retete ADDITIVE
SET CLASSLIB TO orapoarte ADDITIVE
SET CLASSLIB TO orapoarte_gestiuni ADDITIVE
SET CLASSLIB TO orapoarte_parametri ADDITIVE
SET CLASSLIB TO ONOM_CURS ADDITIVE
SET CLASSLIB TO ctl32_statusbar_fals.vcx ADDITIVE
SET CLASSLIB TO ctl32_common.vcx ADDITIVE
SET CLASSLIB TO ctl32_structs.vcx ADDITIVE
SET CLASSLIB TO ctl32_progressbar.vcx ADDITIVE
SET CLASSLIB TO ctl32_balloontip.vcx ADDITIVE
SET CLASSLIB TO ocriterii.vcx ADDITIVE
SET CLASSLIB TO oavize.vcx ADDITIVE
SET CLASSLIB TO onomenclatoare2 ADDITIVE
SET CLASSLIB TO wwdialogs.vcx ADDITIVE
SET CLASSLIB TO oimportxml.vcx ADDITIVE
SET CLASSLIB TO excelxml.vcx ADDITIVE
SET CLASSLIB TO orapoarte_obinv.vcx ADDITIVE
DO BvLog WITH 'SET CLASSLIB OK'
*----- PROCEDURI (mock-uri PRIMELE, ui_harness la final) -----
SET PROCEDURE TO PROCEDURI
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\mock_caut_valuta.prg" ADDITIVE
SET PROCEDURE TO acces_meniu ADDITIVE
SET PROCEDURE TO cauta_alfa ADDITIVE
SET PROCEDURE TO pmenu ADDITIVE
SET PROCEDURE TO proceduri_comune ADDITIVE
SET PROCEDURE TO quitapp ADDITIVE
SET PROCEDURE TO init_program ADDITIVE
SET PROCEDURE TO oproceduri_listari.prg ADDITIVE
SET PROCEDURE TO oproceduri_configurare.prg ADDITIVE
SET PROCEDURE TO oproceduri_articole.prg ADDITIVE
SET PROCEDURE TO oproceduri_retete.prg ADDITIVE
SET PROCEDURE TO orapoarte.prg ADDITIVE
SET PROCEDURE TO mesaje ADDITIVE
SET PROCEDURE TO oserii_numere.prg ADDITIVE
SET PROCEDURE TO oexport.prg ADDITIVE
SET PROCEDURE TO wwConfig.prg ADDITIVE
SET PROCEDURE TO proceduri_rapoarte.prg ADDITIVE
SET PROCEDURE TO OPROCEDURI_CURS.PRG ADDITIVE
SET PROCEDURE TO validare.prg ADDITIVE
SET PROCEDURE TO GENCURSOR.PRG ADDITIVE
SET PROCEDURE TO OPROCEDURI_COMUNE.PRG ADDITIVE
SET PROCEDURE TO OINIT_OPTIUNI.PRG ADDITIVE
SET PROCEDURE TO updateserver.prg ADDITIVE
SET PROCEDURE TO oinainte_de.prg ADDITIVE
SET PROCEDURE TO ooperatii_comune.prg ADDITIVE
SET PROCEDURE TO Ocompensari.PRG ADDITIVE
SET PROCEDURE TO OPROCEDURI_aMS.PRG ADDITIVE
SET PROCEDURE TO oproceduri_rulaje ADDITIVE
SET PROCEDURE TO oproceduri_stocuri ADDITIVE
SET PROCEDURE TO OINTRODUCERI ADDITIVE
SET PROCEDURE TO oHeader.prg ADDITIVE
SET PROCEDURE TO proceduri_excel.PRG ADDITIVE
SET PROCEDURE TO onomenclatoare.PRG ADDITIVE
SET PROCEDURE TO osecurity ADDITIVE
SET PROCEDURE TO ocautare ADDITIVE
SET PROCEDURE TO orefaceri ADDITIVE
SET PROCEDURE TO ofacturare_comun.PRG ADDITIVE
SET PROCEDURE TO ofacturare_stoc.PRG ADDITIVE
SET PROCEDURE TO oproceduri_casademarcat ADDITIVE
SET PROCEDURE TO oproceduri_casa_marcat_e500 ADDITIVE
SET PROCEDURE TO oproceduri_casa_marcat_mp500 ADDITIVE
SET PROCEDURE TO oproceduri_util.prg ADDITIVE
SET PROCEDURE TO wwxmlhttp.prg ADDITIVE
SET PROCEDURE TO ini.prg ADDITIVE
SET PROCEDURE TO odocumente.prg ADDITIVE
SET PROCEDURE TO regex.prg ADDITIVE
SET PROCEDURE TO wwutils.prg ADDITIVE
SET PROCEDURE TO inchidere_k ADDITIVE
SET PROCEDURE TO iniacces.prg ADDITIVE
SET PROCEDURE TO oupdate.prg ADDITIVE
SET PROCEDURE TO procese.prg ADDITIVE
SET PROCEDURE TO version.prg ADDITIVE
SET PROCEDURE TO xmlaccess.prg ADDITIVE
SET PROCEDURE TO xmlparser.prg ADDITIVE
SET PROCEDURE TO filebringer.prg ADDITIVE
SET PROCEDURE TO wwcodeupdate.prg ADDITIVE
SET PROCEDURE TO wwhttp.prg ADDITIVE
SET PROCEDURE TO xdate.prg ADDITIVE
SET PROCEDURE TO ofacturare.prg ADDITIVE
SET PROCEDURE TO oproceduri_obinv.prg ADDITIVE
SET PROCEDURE TO oproceduri_facturare.prg ADDITIVE
SET PROCEDURE TO email.prg ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\ui_harness.prg" ADDITIVE
DO BvLog WITH 'SET PROCEDURE OK'
*----- Globale -----
PUBLIC gnPc, gnPval, gnPcant, gnPpret, gnPPretval, gnPCurs, gnPVal, gnPPretV, gnPPretVal
STORE 2 TO gnPc, gnPval, gnPVal
gnPcant = 3
STORE 4 TO gnPpret, gnPPretval, gnPPretVal, gnPPretV, gnPCurs
PUBLIC gl406, gcS, gnAn, gnLuna, gnIdFirma, gnIdSucursala, gcAcces, gcFirma
gl406 = .T.
gcS = 'CONTAFIN'
gnAn = YEAR(DATE())
gnLuna = MONTH(DATE())
gnIdFirma = 110
gnIdSucursala = 110
gcAcces = "1;2;3;4;5;6;7;8;"
gcFirma = gcS
PUBLIC nror(65000)
PUBLIC gnMockRaspuns, gcMockUltimMesaj, gnMockUltimTip
gnMockRaspuns = 6
gcMockUltimMesaj = ''
gnMockUltimTip = 0
PUBLIC goExecutor, goApp
goExecutor = CREATEOBJECT('dummyexecutor')
goApp = CREATEOBJECT('dummyapp')
*----- poAct: antetul notei (factura in EUR, curs 5) -----
PUBLIC poAct
poAct = CREATEOBJECT('Custom')
poAct.AddProperty('nume_val', 'EUR')
poAct.AddProperty('curs', 5)
poAct.AddProperty('proc_tva', 1.21)
poAct.AddProperty('nnir', 0)
poAct.AddProperty('id_valuta', 978)
poAct.AddProperty('id_fdoc', 1)
poAct.AddProperty('fdoc', 'Factura')
poAct.AddProperty('id_partc', 601)
poAct.AddProperty('partc', 'FURNIZOR EXTERN GMBH')
poAct.AddProperty('serie_act', '')
poAct.AddProperty('dataact', DATE())
poAct.AddProperty('tva_incasare', 0)
poAct.AddProperty('id_set', 1)
poAct.AddProperty('id_gestin', 1)
*----- jtva_coloane2 / saft_taxtable: perechi reale 21% -----
IF USED('jtva_coloane2')
USE IN ('jtva_coloane2')
ENDIF
CREATE CURSOR jtva_coloane2 (ordine N(8), id_jtva_coloana N(14), denumire C(100), ;
jc N(1), jv N(1), afisat N(1), coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14))
INSERT INTO jtva_coloane2 VALUES (0, 0, '', 0, 0, 1, '', '', 0, 0)
INSERT INTO jtva_coloane2 VALUES (1, 220, 'ACH. IMP. 21%', 1, 0, 1, 'FO21B', 'FO21T', 21, 221)
INSERT INTO jtva_coloane2 VALUES (2, 221, 'TVA ACH. IMP. 21%', 1, 0, 1, 'FO21T', '', 21, 0)
IF USED('saft_taxtable')
USE IN ('saft_taxtable')
ENDIF
CREATE CURSOR saft_taxtable (taxname C(250) NULL, typename C(250) NULL, taxcode N(6) NULL, ;
taxtype N(3) NULL, descriere C(250) NULL, tip C(100) NULL, descriere_tip C(250) NULL, ;
procent_taxa N(7,2) NULL, procent_prorata N(7,2) NULL, inactiv N(1) NULL, tva N(1) NULL, ;
wht N(1) NULL, tva_achizitii N(1) NULL, tva_livrari N(1) NULL)
INDEX ON taxcode TAG taxcode
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('', 0, '', 0, 1, 1, 1, 1)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301204-Import de bunuri cota 21%', 301204, '', 21, 1, 0, 1, 0)
DO CreeazaIntrodc WITH 'introdc'
DO CreeazaIntrodc WITH 'introdc_sablon'
INSERT INTO introdc_sablon (scd, scc, cu_tva, ordine, id_set, participa_valuta, tip_rand, ;
id_jtva_coloana, ptva, explicatie_tva) ;
VALUES ('371', '401', 1, 1, 1, .T., 'B', 220, 21, 'ACH. IMP. 21%')
INSERT INTO introdc_sablon (scd, scc, cu_tva, ordine, id_set, participa_valuta, tip_rand, ;
id_jtva_coloana, ptva, explicatie_tva) ;
VALUES ('4426', '401', 1, 2, 1, .T., 'T', 221, 21, 'TVA ACH. IMP. 21%')
GO TOP IN introdc_sablon
IF USED('rul_temp')
USE IN ('rul_temp')
ENDIF
CREATE CURSOR rul_temp (denumire C(100), codmat C(30), cant N(14,3), pret_val N(18,4), ;
pretd N(18,4), pret N(18,4), pret_lei N(18,4), cont C(10), acont C(20), serie C(30), ;
lot C(30), adata_expirare C(10), proc_disc N(6,2), cota_tva N(6,2))
INSERT INTO rul_temp (denumire, codmat, cant, pret, pret_lei, cont, cota_tva) ;
VALUES ('PLACEHOLDER', 'PH', 1, 1, 1, '371', 21)
SELECT introdc
INDEX ON Str(Nvl(nr_doc,0),8) + Icase(tip_rand='B','1', tip_rand='S','2', tip_rand='G','3', tip_rand='T','4', tip_rand='D','5', '6') + Padr(Nvl(scd,''),10) TAG ord_doc
SET ORDER TO ord_doc
DO BvLog WITH 'cursoare pregatite, CREATEOBJECT(import_nota, .F.)'
PUBLIC goObj
goObj = CREATEOBJECT('IMPORT_nota', .F.)
IF VARTYPE(goObj) <> 'O'
DO BvLog WITH 'FAIL: instantiere import_nota'
DO HarnessDone WITH 'done-error'
QUIT
ENDIF
goObj.lDialogAratat = .T.
goObj.oact = poAct
goObj.lSpargeSecundare = .F.
goObj.WindowType = 0
goObj.Visible = .T.
goObj.Show()
goObj.WindowState = 2
DOEVENTS FORCE
SELECT rul_temp
ZAP
goObj.gridart.Refresh()
DOEVENTS FORCE
PRIVATE pnAsserts, pnPass
STORE 0 TO pnAsserts, pnPass
*========================= DIALOG: factura EUR, mod TVA DVI =========================
PUBLIC goDlg
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = 18000
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 601
goDlg.cPartener = 'FURNIZOR EXTERN GMBH'
goDlg.cExplicatia = 'Import marfa, DVI fara valuta proprie'
goDlg.nSuma = 1000
goDlg.nSumaLei = 0
goDlg.nCurs = 5
goDlg.nIdValuta = 978
goDlg.cValuta = 'EUR'
goDlg.chkInValutaCont.Value = 1
goDlg.chkParticipaValuta.Value = 1
goDlg.nIdExplicatieTva = 220
goDlg.cExplicatieTva = 'ACH. IMP. 21%'
goDlg.nProcentTva = 21
goDlg.cSerieDvi = ''
goDlg.nNractDvi = 19000
goDlg.dDviData = DATE()
goDlg.nIdFdocDVI = 2
goDlg.cFelDocDvi = 'DVI'
goDlg.nDviIdPartener = 900
goDlg.cDviPartener = 'DIRECTIA VAMALA'
goDlg.optTipTva.Value = 2
goDlg.optTipTva.InteractiveChange()
*========================= bifa Valuta DVI: porneste BIFATA (factura are valuta) =========================
=Assert3('1-la Init, factura in valuta: chkDviInValuta.Value=1 (bifata)', goDlg.chkDviInValuta.Value, 1)
=Assert3('2-la Init: txtDviValuta.Visible=1 (sectiune vizibila)', IIF(goDlg.txtDviValuta.Visible,1,0), 1)
*========================= scoatere bifa: sectiunea valuta DVI se ascunde, curs=1, tva val=0 =========================
goDlg.chkDviInValuta.Value = 0
goDlg.chkDviInValuta.InteractiveChange()
=Assert3('3-dupa scoatere bifa: txtDviValuta.Visible=0', IIF(goDlg.txtDviValuta.Visible,1,0), 0)
=Assert3('4-dupa scoatere bifa: cmdDviValuta.Visible=0', IIF(goDlg.cmdDviValuta.Visible,1,0), 0)
=Assert3('5-dupa scoatere bifa: txtDviCurs.Visible=0', IIF(goDlg.txtDviCurs.Visible,1,0), 0)
=Assert3('6-dupa scoatere bifa: txtDviTvaVal.Visible=1 (ramane vizibil, comuta pe lei)', IIF(goDlg.txtDviTvaVal.Visible,1,0), 1)
=Assert3('7-dupa scoatere bifa: nDviCurs=1', goDlg.nDviCurs, 1)
=Assert3('8-dupa scoatere bifa: nDviTvaVal=1050 (TVA recalculat in lei, nu 0)', goDlg.nDviTvaVal, 1050)
*-- TVA DVI in lei, introdusa direct (proprietate reala, ca in restul suitei - vezi
*-- test_dvi_dialog_ui.prg scenariul F1)
goDlg.nDviTvaLei = 900.00
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO HarnessStep WITH 0, 'dialog completat, bifa Valuta DVI scoasa'
*========================= toDlg construit inline, do_adauga_factura REAL =========================
*-- formula copiata exact din construieste_todlg (vezi CAPCANA l in antet) - lDviValutaDirty/
*-- lDviCursDirty raman .F. (nu s-a atins picker-ul/cursul DVI), deci valorile efective ale
*-- DVI-ului raman cele mostenite de la factura (nIdValuta/nCurs), nu nDviCurs=1 fortat de
*-- actualizeaza_stare_dvi_valuta() pe widget.
PUBLIC goT
LOCAL lcDviValEfectiv, llDviFaraVal, llFactFaraVal, llDviPropriu, lnDviIdValutaEfectiv, lnDviCursEfectiv, llValutaProprie
lnDviIdValutaEfectiv = IIF(goDlg.lDviValutaDirty, goDlg.nDviIdValuta, goDlg.nIdValuta)
lnDviCursEfectiv = IIF(goDlg.lDviValutaDirty OR goDlg.lDviCursDirty, goDlg.nDviCurs, goDlg.nCurs)
lcDviValEfectiv = IIF(goDlg.lDviValutaDirty, ALLTRIM(NVL(goDlg.cDviValuta,'')), ALLTRIM(NVL(goDlg.cValuta,'')))
llDviFaraVal = (goDlg.chkDviInValuta.Value = 0) OR EMPTY(lcDviValEfectiv) OR UPPER(lcDviValEfectiv) == 'RON'
llFactFaraVal = (EMPTY(goDlg.cValuta) OR UPPER(ALLTRIM(goDlg.cValuta)) == 'RON')
llDviPropriu = (lnDviIdValutaEfectiv <> goDlg.nIdValuta OR lnDviCursEfectiv <> goDlg.nCurs)
llValutaProprie = IIF(llDviFaraVal AND llFactFaraVal, 0, IIF(llDviFaraVal <> llFactFaraVal, 1, IIF(llDviPropriu,1,0)))
goT = CREATEOBJECT('Empty')
=ADDPROPERTY(goT,'serie_act','')
=ADDPROPERTY(goT,'nract',goDlg.nNract)
=ADDPROPERTY(goT,'dataact',goDlg.dDataAct)
=ADDPROPERTY(goT,'fdoc',goDlg.cFelDoc)
=ADDPROPERTY(goT,'id_fdoc',goDlg.nIdFdoc)
=ADDPROPERTY(goT,'id_partc',goDlg.nIdPartener)
=ADDPROPERTY(goT,'partc',goDlg.cPartener)
=ADDPROPERTY(goT,'explicatia',ALLTRIM(NVL(goDlg.cExplicatia,'')))
=ADDPROPERTY(goT,'suma',ROUND(goDlg.nSuma*goDlg.nCurs,gnPC))
=ADDPROPERTY(goT,'suma_val',goDlg.nSuma)
=ADDPROPERTY(goT,'in_valuta',1)
=ADDPROPERTY(goT,'participa_valuta',.T.)
=ADDPROPERTY(goT,'id_valuta',goDlg.nIdValuta)
=ADDPROPERTY(goT,'curs',goDlg.nCurs)
=ADDPROPERTY(goT,'nume_val',ALLTRIM(NVL(goDlg.cValuta,'')))
=ADDPROPERTY(goT,'cTipTva','D')
=ADDPROPERTY(goT,'id_jtva_coloana',goDlg.nIdExplicatieTva)
=ADDPROPERTY(goT,'dvi_serie',ALLTRIM(NVL(goDlg.cSerieDvi,'')))
=ADDPROPERTY(goT,'dvi_nract',goDlg.nNractDvi)
=ADDPROPERTY(goT,'dvi_dataact',goDlg.dDviData)
=ADDPROPERTY(goT,'dvi_id_fdoc',goDlg.nIdFdocDVI)
=ADDPROPERTY(goT,'dvi_fdoc',goDlg.cFelDocDvi)
=ADDPROPERTY(goT,'dvi_id_partc',goDlg.nDviIdPartener)
=ADDPROPERTY(goT,'dvi_partc',goDlg.cDviPartener)
=ADDPROPERTY(goT,'dvi_scc','401')
=ADDPROPERTY(goT,'dvi_tva_lei',goDlg.nDviTvaLei)
=ADDPROPERTY(goT,'dvi_tva_val',goDlg.nDviTvaVal)
*-- bifa scoasa => dvi_in_valuta=.F. (llDviFaraVal), indiferent de valuta efectiva mostenita
=ADDPROPERTY(goT,'dvi_in_valuta',!llDviFaraVal)
=ADDPROPERTY(goT,'dvi_id_valuta',lnDviIdValutaEfectiv)
=ADDPROPERTY(goT,'dvi_curs',lnDviCursEfectiv)
=ADDPROPERTY(goT,'dvi_nume_val',lcDviValEfectiv)
=ADDPROPERTY(goT,'dvi_valuta_proprie',llValutaProprie)
=ADDPROPERTY(goT,'disc_baza_lei',0)
=ADDPROPERTY(goT,'disc_baza_val',0)
LOCAL llOkAdauga
llOkAdauga = goObj.do_adauga_factura(goT)
=Assert3('9-do_adauga_factura(goT) reuseste', IIF(llOkAdauga,1,0), 1)
goDlg.Hide()
DOEVENTS FORCE
DO HarnessStep WITH 1, 'document creat, dupa Termin'
*========================= randul T (DVI): fara valuta/curs/suma_val =========================
SELECT introdc
SET ORDER TO
LOCATE FOR Nvl(rand_dvi,0) = 1
=Assert3('10-randul T-DVI (rand_dvi=1) gasit', IIF(FOUND(),1,0), 1)
IF FOUND()
=Assert3('11-T-DVI.suma=900.00 (nDviTvaLei introdus)', suma, 900.00)
=Assert3('12-T-DVI.suma_val=0 (fara valuta)', NVL(suma_val,0), 0)
=Assert3('13-T-DVI.in_valuta=0', NVL(in_valuta,0), 0)
=Assert3('14-T-DVI.id_valuta=0', NVL(id_valuta,0), 0)
=Assert3('15-T-DVI.curs=0', NVL(curs,0), 0)
=AssertStr('16-T-DVI.nume_val=""', ALLTRIM(NVL(nume_val,'?')), '')
=Assert3('17-T-DVI.valuta_proprie=1 (factura are valuta, DVI nu mai are)', NVL(valuta_proprie,0), 1)
ELSE
pnAsserts = pnAsserts + 7
DO BvLog WITH ' FAIL 11-17: T-DVI negasit'
ENDIF
*-- randul B (baza facturii) ramane in valuta - discountul/bifa DVI nu-l afecteaza
SELECT introdc
LOCATE FOR nract = 18000 AND tip_rand == 'B'
=Assert3('18-randul B (baza) gasit', IIF(FOUND(),1,0), 1)
IF FOUND()
=Assert3('19-B.in_valuta=1 (factura ramane in valuta)', NVL(in_valuta,0), 1)
=Assert3('20-B.suma_val=1000.00', NVL(suma_val,0), 1000.00)
ELSE
pnAsserts = pnAsserts + 2
DO BvLog WITH ' FAIL 19-20: B negasit'
ENDIF
DO HarnessStep WITH 2, 'randul T-DVI fara valuta verificat - vezi log'
DO BvLog WITH 'REZULTAT: ' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' assert-uri PASS'
IF pnPass = pnAsserts
DO BvLog WITH 'REZULTAT: PASS (' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ')'
ELSE
DO BvLog WITH 'REZULTAT: FAIL (' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' assert-uri PASS)'
ENDIF
DO HarnessStep WITH 3, 'final: ' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' PASS'
DO HarnessDone WITH 'done'
CATCH TO loExc
DO BvLog WITH 'CATCH ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']'
DO HarnessDone WITH 'done-error'
ENDTRY
QUIT
*==================================================================================
PROCEDURE CreeazaIntrodc
LPARAMETERS tcAlias
IF USED(tcAlias)
USE IN (tcAlias)
ENDIF
CREATE CURSOR (tcAlias) ( ;
id_note N(14), explicatia C(100), scd C(10), ascd C(20), scc C(10), ascc C(20), ;
cu_tva N(1), id_set N(14), ordine N(8), in_valuta N(1), id_jtva_coloana N(14) NULL, ;
ptva N(6,2), explicatie_tva C(50), tipjurnal C(2), taxcode N(6), paymentcode C(9), ;
suma N(18,4), suma_val N(18,4), id_partd N(14), id_partc N(14), partd C(100), partc C(100), ;
id_fact N(14), id_factd N(14), id_factc N(14), pereched N(14), perechec N(14), ;
nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), expl_manual N(1), ;
scd_orig C(20), ascd_orig C(20), rand_dvi N(1), valuta_proprie N(1))
ENDPROC
PROCEDURE Assert3
LPARAMETERS tcLabel, tuActual, tuExpected
pnAsserts = pnAsserts + 1
IF ABS(NVL(tuActual,0) - tuExpected) < 0.02
pnPass = pnPass + 1
DO BvLog WITH ' PASS ' + tcLabel + ' (=' + TRANSFORM(tuActual) + ')'
ELSE
DO BvLog WITH ' FAIL ' + tcLabel + ' (actual=' + TRANSFORM(tuActual) + ' asteptat=' + TRANSFORM(tuExpected) + ')'
ENDIF
ENDPROC
PROCEDURE AssertStr
LPARAMETERS tcLabel, tcActual, tcExpected
pnAsserts = pnAsserts + 1
IF tcActual == tcExpected
pnPass = pnPass + 1
DO BvLog WITH ' PASS ' + tcLabel + ' (=[' + tcActual + '])'
ELSE
DO BvLog WITH ' FAIL ' + tcLabel + ' (actual=[' + tcActual + '] asteptat=[' + tcExpected + '])'
ENDIF
ENDPROC
PROCEDURE BvErr
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
DO BvLog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
ENDPROC
PROCEDURE BvLog
LPARAMETERS tcMsg
SET SAFETY OFF
LOCAL lcL
lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '')
STRTOFILE(lcL + tcMsg + CHR(13)+CHR(10), gcUILog)
ENDPROC
DEFINE CLASS dummyapp AS Custom
PROCEDURE ReadIni
LPARAMETERS tcSection, tcKey
RETURN ''
ENDPROC
PROCEDURE WriteIni
LPARAMETERS tcSection, tcKey, tcValue
RETURN .T.
ENDPROC
ENDDEFINE
DEFINE CLASS dummyexecutor AS Custom
cEroare = ''
PROCEDURE oExecute
LPARAMETERS tcSql, tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF 'VJTVA_COLOANE' $ UPPER(m.tcSql)
DO CreeazaJtvaColoaneView WITH m.tcCursor
RETURN 1
ENDIF
IF UPPER(ALLTRIM(m.tcCursor)) == 'RUL_TEMP'
CREATE CURSOR (m.tcCursor) (denumire C(100), codmat C(30), cant N(14,3), ;
pret_val N(18,4), pretd N(18,4), pret N(18,4), pret_lei N(18,4), cont C(10), ;
acont C(20), serie C(30), lot C(30), adata_expirare C(10), proc_disc N(6,2), cota_tva N(6,2))
RETURN 1
ENDIF
IF 'CONFIG_ANALITICE' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (camp_leg_prefix C(30), camp_leg_sufix C(30))
INSERT INTO (m.tcCursor) VALUES ('', '')
RETURN 1
ENDIF
IF 'FCONTURI_ANALITICE' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (acont C(20))
INSERT INTO (m.tcCursor) VALUES ('')
RETURN 1
ENDIF
IF 'VPLCONT_ANALITIC' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (cont C(10), acont C(20))
RETURN 1
ENDIF
IF 'VCONFIG_CONT_IREG' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (contpart C(10), fel_cont N(1), cu_inregistrari N(1), ;
explic_cont C(100), exceptie C(10), pozitie N(1), invers N(1), gasit N(1))
INSERT INTO (m.tcCursor) VALUES ('401', 0, 0, 'Furnizori', '', 0, 0, 0)
RETURN 1
ENDIF
CREATE CURSOR (m.tcCursor) (id_temp N(1))
RETURN 1
ENDPROC
PROCEDURE oExecuta
LPARAMETERS tcSql, tcCursor
IF !EMPTY(m.tcCursor)
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF UPPER(m.tcCursor) == 'CJTVACOL4427'
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14))
ELSE
CREATE CURSOR (m.tcCursor) (id_temp N(1))
ENDIF
ENDIF
RETURN .T.
ENDPROC
PROCEDURE oSelect2Value
LPARAMETERS tcSql, toValue
toValue = ''
RETURN 1
ENDPROC
PROCEDURE oReset
ENDPROC
ENDDEFINE
PROCEDURE CreeazaJtvaColoaneView
LPARAMETERS tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14), denumire C(100), jc N(1), jv N(1), ;
coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14) NULL, afisat N(1), ;
id_jtva_ex N(14) NULL, id_jtva_neex N(14) NULL, ordine N(8), ;
taxcode N(6) NULL, taxcode_neexigibil N(6) NULL, taxcode_n50 N(6) NULL, ;
taxcode_n50_tvai N(6) NULL, taxcode_n100 N(6) NULL, taxcode_regularizare N(6) NULL, taxcode_tvai N(6) NULL)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, afisat, ordine, cota_tva) VALUES (0, '', 0, 0, 1, 0, 0)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (220, 'ACH. IMP. 21%', 1, 0, 'FO21B', 21, 221, 1, 1, 301204)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (221, 'TVA ACH. IMP. 21%', 1, 0, 'FO21T', 21, 1, 2, 301204)
ENDPROC

View File

@@ -0,0 +1,12 @@
# test_dvi_bifa_valuta.ps1 - wrapper peste harness-ul generic pentru bifa noua "Valuta" din
# sectiunea TVA DVI (chkDviInValuta) - Runda32.
# powershell -ExecutionPolicy Bypass -File test_dvi_bifa_valuta.ps1
$ErrorActionPreference = 'Stop'
$Teste = $PSScriptRoot
& (Join-Path (Split-Path $Teste -Parent) 'vfp_ui_harness.ps1') `
-TestPrg (Join-Path $Teste 'test_dvi_bifa_valuta.prg') `
-Steps @('dialog_bifa_scoasa','document_creat','rand_t_dvi_verificat','final') `
-ShotsDir (Join-Path $Teste 'screenshots_dvi_bifa_valuta') `
-SyncDir (Join-Path $Teste 'uisync_dvi_bifa_valuta') `
-StepTimeoutSec 180 `
-ReadyTimeoutSec 180

View File

@@ -0,0 +1,794 @@
* test_dvi_dialog_ui.prg
* Runda30 (F1, plan fizzy-imagining-parnas.md): teste UI pe formularul REAL de adaugare
* factura (import_adauga_factura, COMUN\clase\ointroduceri.vcx), clona a test_adauga_factura_ui.prg,
* focalizata pe comportamentul dialogului pentru blocul DVI (valuta/curs proprii) si discount:
* 1. precompletarea valutei/cursului DVI din factura la Init (mirror automat);
* 2. contractul nou al mock_caut_valuta (goMockValutaCoada, coada FIFO) exercitat prin
* 2 pick-uri diferite in acelasi flux (valuta facturii, apoi valuta DVI) + fallback
* la contractul vechi (goMockValuta) cand coada se goleste;
* 3. alegerea RON pe DVI (curs fix 1, curs disabled, TVA valuta ascunsa si 0);
* 4. garda de dirty: TVA in valuta DVI editat manual (txtDviTvaVal.Valid) nu mai e
* rescris de recalc_tva (cazul unei a treia valute, diferita de RON si de factura);
* 5. Runda32: discountul e activ direct pe nDiscBaza<>0 (fara chkAreDiscount); caption-ul
* txtDiscBaza urmeaza valuta facturii, txtDiscBaza e permanent vizibil;
* 6. dirty-flags: txtDviCurs.Valid seteaza dirty; realegerea valutei DVI reseteaza cursul;
* 7. validari blocante: DVI non-RON cu curs 0; discount negativ; discount >= suma facturii.
*
* ASUMPTII (de confruntat cu implementarea reala):
* - proprietatile de dialog se numesc nDviIdValuta, cDviValuta, nDviCurs, lDviCursDirty,
* lDviTvaValDirty, nDiscBaza (verificate pe ointroduceri.vc2, lane F1+F2 dialog,
* 27.07.2026; Runda32 elimina chkAreDiscount/txtDiscTva/nDiscTva/lDiscTvaDirty);
* - RON e o valuta cu id propriu (1), nu id_valuta=0 (vezi test_repro_valuta_dblclick.prg);
* picker-ul (cmdValuta/cmdDviValuta.Click) ignora rezultate cu id_valuta=0 (guard
* !Empty(Nvl(loCauta.id_valuta,0))).
*
* Rulare:
* powershell -ExecutionPolicy Bypass -File test_dvi_dialog_ui.ps1
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET DECIMALS TO 4
SET NULLDISPLAY TO ''
CLOSE DATABASES
PUBLIC gcUILog, gcSyncDir
gcUILog = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\test_dvi_dialog_ui_log.txt"
gcSyncDir = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\uisync_dvi_dialog\"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcUILog)
ON ERROR DO DdErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
TRY
LOCAL gcAppPath, lcPath
gcAppPath = "D:\ROA\ROAGEST\"
SET DEFAULT TO (gcAppPath)
lcPath = gcAppPath + 'Date;' + gcAppPath + 'Include;' + gcAppPath + 'FERESTRE;' + ;
gcAppPath + 'GRAFICE;' + gcAppPath + 'CLASE;' + gcAppPath + 'MENIURI;' + ;
gcAppPath + 'PROGRAME;' + gcAppPath + 'RAPOARTE;' + gcAppPath + 'COMUN;' + ;
gcAppPath + 'COMUN\CLASE;' + gcAppPath + 'COMUN\FERESTRE;' + gcAppPath + 'COMUN\PROGRAME;' + ;
gcAppPath + 'COMUN\GRAFICE;' + gcAppPath + 'COMUN\RAPOARTE;' + gcAppPath + 'COMUN\MENIURI;' + ;
gcAppPath + 'COMUN\UTILE\GRIDEXTRAS;' + gcAppPath + 'COMUN\UTILE\CTL32;' + ;
gcAppPath + 'COMUN\UTILE\HPDF;' + gcAppPath + 'COMUN\UTILE\HPDF\REPORTOUTPUT;' + ;
gcAppPath + 'COMUN\UTILE\WEB;' + gcAppPath + 'COMUN\UTILE\EXCEL;' + ;
ADDBS(SUBSTR(gcAppPath,1,RAT([\],gcAppPath,2)))+[COMUNROA\]
SET PATH TO &lcPath ADDITIVE
DO DdLog WITH 'SET PATH OK'
*----- CLASE -----
SET CLASSLIB TO (gcAppPath + "comun\clase\appwiz") ADDITIVE
SET CLASSLIB TO GESTIUNI ADDITIVE
SET CLASSLIB TO CAUT ADDITIVE
SET CLASSLIB TO BAZA ADDITIVE
SET CLASSLIB TO comun ADDITIVE
SET CLASSLIB TO accessibility.vcx ADDITIVE
SET CLASSLIB TO messagebox ADDITIVE
SET CLASSLIB TO registry ADDITIVE
SET CLASSLIB TO cauta_alfa_forms.vcx ADDITIVE
SET CLASSLIB TO DECABAZA ADDITIVE
SET CLASSLIB TO onomenclatoare ADDITIVE
SET CLASSLIB TO stocuri.vcx ADDITIVE
SET CLASSLIB TO rulaje.vcx ADDITIVE
SET CLASSLIB TO ointroduceri ADDITIVE
SET CLASSLIB TO ointroduceri_web ADDITIVE
SET CLASSLIB TO ointroduceri_depozit ADDITIVE
SET CLASSLIB TO overificari ADDITIVE
SET CLASSLIB TO ferestre_oracle ADDITIVE
SET CLASSLIB TO ferestre_cere_date.vcx ADDITIVE
SET CLASSLIB TO configurare.vcx ADDITIVE
SET CLASSLIB TO serii_numere.vcx ADDITIVE
SET CLASSLIB TO omodificari.vcx ADDITIVE
SET CLASSLIB TO ocompensari.vcx ADDITIVE
SET CLASSLIB TO caut_ora ADDITIVE
SET CLASSLIB TO onote_contabile ADDITIVE
SET CLASSLIB TO otoolbar ADDITIVE
SET CLASSLIB TO bon_fisc ADDITIVE
SET CLASSLIB TO onom_articole ADDITIVE
SET CLASSLIB TO onom_retete ADDITIVE
SET CLASSLIB TO orapoarte ADDITIVE
SET CLASSLIB TO orapoarte_gestiuni ADDITIVE
SET CLASSLIB TO orapoarte_parametri ADDITIVE
SET CLASSLIB TO ONOM_CURS ADDITIVE
SET CLASSLIB TO ctl32_statusbar_fals.vcx ADDITIVE
SET CLASSLIB TO ctl32_common.vcx ADDITIVE
SET CLASSLIB TO ctl32_structs.vcx ADDITIVE
SET CLASSLIB TO ctl32_progressbar.vcx ADDITIVE
SET CLASSLIB TO ctl32_balloontip.vcx ADDITIVE
SET CLASSLIB TO ocriterii.vcx ADDITIVE
SET CLASSLIB TO oavize.vcx ADDITIVE
SET CLASSLIB TO onomenclatoare2 ADDITIVE
SET CLASSLIB TO wwdialogs.vcx ADDITIVE
SET CLASSLIB TO oimportxml.vcx ADDITIVE
SET CLASSLIB TO excelxml.vcx ADDITIVE
SET CLASSLIB TO orapoarte_obinv.vcx ADDITIVE
DO DdLog WITH 'SET CLASSLIB OK'
*----- PROCEDURI (mock-uri PRIMELE, ui_harness la final) -----
SET PROCEDURE TO PROCEDURI
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\mock_caut_valuta.prg" ADDITIVE
SET PROCEDURE TO acces_meniu ADDITIVE
SET PROCEDURE TO cauta_alfa ADDITIVE
SET PROCEDURE TO pmenu ADDITIVE
SET PROCEDURE TO proceduri_comune ADDITIVE
SET PROCEDURE TO quitapp ADDITIVE
SET PROCEDURE TO init_program ADDITIVE
SET PROCEDURE TO oproceduri_listari.prg ADDITIVE
SET PROCEDURE TO oproceduri_configurare.prg ADDITIVE
SET PROCEDURE TO oproceduri_articole.prg ADDITIVE
SET PROCEDURE TO oproceduri_retete.prg ADDITIVE
SET PROCEDURE TO orapoarte.prg ADDITIVE
SET PROCEDURE TO mesaje ADDITIVE
SET PROCEDURE TO oserii_numere.prg ADDITIVE
SET PROCEDURE TO oexport.prg ADDITIVE
SET PROCEDURE TO wwConfig.prg ADDITIVE
SET PROCEDURE TO proceduri_rapoarte.prg ADDITIVE
SET PROCEDURE TO OPROCEDURI_CURS.PRG ADDITIVE
SET PROCEDURE TO validare.prg ADDITIVE
SET PROCEDURE TO GENCURSOR.PRG ADDITIVE
SET PROCEDURE TO OPROCEDURI_COMUNE.PRG ADDITIVE
SET PROCEDURE TO OINIT_OPTIUNI.PRG ADDITIVE
SET PROCEDURE TO updateserver.prg ADDITIVE
SET PROCEDURE TO oinainte_de.prg ADDITIVE
SET PROCEDURE TO ooperatii_comune.prg ADDITIVE
SET PROCEDURE TO Ocompensari.PRG ADDITIVE
SET PROCEDURE TO OPROCEDURI_aMS.PRG ADDITIVE
SET PROCEDURE TO oproceduri_rulaje ADDITIVE
SET PROCEDURE TO oproceduri_stocuri ADDITIVE
SET PROCEDURE TO OINTRODUCERI ADDITIVE
SET PROCEDURE TO oHeader.prg ADDITIVE
SET PROCEDURE TO proceduri_excel.PRG ADDITIVE
SET PROCEDURE TO onomenclatoare.PRG ADDITIVE
SET PROCEDURE TO osecurity ADDITIVE
SET PROCEDURE TO ocautare ADDITIVE
SET PROCEDURE TO orefaceri ADDITIVE
SET PROCEDURE TO ofacturare_comun.PRG ADDITIVE
SET PROCEDURE TO ofacturare_stoc.PRG ADDITIVE
SET PROCEDURE TO oproceduri_casademarcat ADDITIVE
SET PROCEDURE TO oproceduri_casa_marcat_e500 ADDITIVE
SET PROCEDURE TO oproceduri_casa_marcat_mp500 ADDITIVE
SET PROCEDURE TO oproceduri_util.prg ADDITIVE
SET PROCEDURE TO wwxmlhttp.prg ADDITIVE
SET PROCEDURE TO ini.prg ADDITIVE
SET PROCEDURE TO odocumente.prg ADDITIVE
SET PROCEDURE TO regex.prg ADDITIVE
SET PROCEDURE TO wwutils.prg ADDITIVE
SET PROCEDURE TO inchidere_k ADDITIVE
SET PROCEDURE TO iniacces.prg ADDITIVE
SET PROCEDURE TO oupdate.prg ADDITIVE
SET PROCEDURE TO procese.prg ADDITIVE
SET PROCEDURE TO version.prg ADDITIVE
SET PROCEDURE TO xmlaccess.prg ADDITIVE
SET PROCEDURE TO xmlparser.prg ADDITIVE
SET PROCEDURE TO filebringer.prg ADDITIVE
SET PROCEDURE TO wwcodeupdate.prg ADDITIVE
SET PROCEDURE TO wwhttp.prg ADDITIVE
SET PROCEDURE TO xdate.prg ADDITIVE
SET PROCEDURE TO ofacturare.prg ADDITIVE
SET PROCEDURE TO oproceduri_obinv.prg ADDITIVE
SET PROCEDURE TO oproceduri_facturare.prg ADDITIVE
SET PROCEDURE TO email.prg ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\ui_harness.prg" ADDITIVE
DO DdLog WITH 'SET PROCEDURE OK'
*----- Globale -----
PUBLIC gnPc, gnPval, gnPcant, gnPpret, gnPPretval, gnPCurs, gnPVal, gnPPretV, gnPPretVal
STORE 2 TO gnPc, gnPval, gnPVal
gnPcant = 3
STORE 4 TO gnPpret, gnPPretval, gnPPretVal, gnPPretV, gnPCurs
PUBLIC gl406, gcS, gnAn, gnLuna, gnIdFirma, gnIdSucursala, gcAcces, gcFirma
gl406 = .T.
gcS = 'CONTAFIN'
gnAn = YEAR(DATE())
gnLuna = MONTH(DATE())
gnIdFirma = 110
gnIdSucursala = 110
gcAcces = "1;2;3;4;5;6;7;8;"
gcFirma = gcS
PUBLIC nror(65000)
PUBLIC gnMockRaspuns, gcMockUltimMesaj, gnMockUltimTip
gnMockRaspuns = 6
gcMockUltimMesaj = ''
gnMockUltimTip = 0
PUBLIC goExecutor, goApp
goExecutor = CREATEOBJECT('dummyexecutor')
goApp = CREATEOBJECT('dummyapp')
*----- poAct: antetul notei (factura in EUR, curs 5 - ca DVI-ul sa aiba ce mosteni la Init) -----
PUBLIC poAct
poAct = CREATEOBJECT('Custom')
poAct.AddProperty('nume_val', 'EUR')
poAct.AddProperty('curs', 5)
poAct.AddProperty('proc_tva', 1.21)
poAct.AddProperty('nnir', 0)
poAct.AddProperty('id_valuta', 978)
poAct.AddProperty('id_fdoc', 1)
poAct.AddProperty('fdoc', 'Factura')
poAct.AddProperty('id_partc', 501)
poAct.AddProperty('partc', 'FURNIZOR EXTERN GMBH')
poAct.AddProperty('serie_act', '')
poAct.AddProperty('dataact', DATE())
poAct.AddProperty('tva_incasare', 0)
poAct.AddProperty('id_set', 1)
poAct.AddProperty('id_gestin', 1)
*----- jtva_coloane2 / saft_taxtable: perechi reale 21% (achizitii interne + import) -----
IF USED('jtva_coloane2')
USE IN ('jtva_coloane2')
ENDIF
CREATE CURSOR jtva_coloane2 (ordine N(8), id_jtva_coloana N(14), denumire C(100), ;
jc N(1), jv N(1), afisat N(1), coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14))
INSERT INTO jtva_coloane2 VALUES (0, 0, '', 0, 0, 1, '', '', 0, 0)
INSERT INTO jtva_coloane2 VALUES (1, 208, 'ACH. INT. 21%', 1, 0, 1, 'RO21B', 'RO21T', 21, 209)
INSERT INTO jtva_coloane2 VALUES (2, 209, 'TVA ACH. INT. 21%', 1, 0, 1, 'RO21T', '', 21, 0)
INSERT INTO jtva_coloane2 VALUES (3, 220, 'ACH. IMP. 21%', 1, 0, 1, 'FO21B', 'FO21T', 21, 221)
INSERT INTO jtva_coloane2 VALUES (4, 221, 'TVA ACH. IMP. 21%', 1, 0, 1, 'FO21T', '', 21, 0)
IF USED('saft_taxtable')
USE IN ('saft_taxtable')
ENDIF
CREATE CURSOR saft_taxtable (taxname C(250) NULL, typename C(250) NULL, taxcode N(6) NULL, ;
taxtype N(3) NULL, descriere C(250) NULL, tip C(100) NULL, descriere_tip C(250) NULL, ;
procent_taxa N(7,2) NULL, procent_prorata N(7,2) NULL, inactiv N(1) NULL, tva N(1) NULL, ;
wht N(1) NULL, tva_achizitii N(1) NULL, tva_livrari N(1) NULL)
INDEX ON taxcode TAG taxcode
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('', 0, '', 0, 1, 1, 1, 1)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301204-Import de bunuri cota 21%', 301204, '', 21, 1, 0, 1, 0)
DO CreeazaIntrodc WITH 'introdc'
DO CreeazaIntrodc WITH 'introdc_sablon'
INSERT INTO introdc_sablon (scd, scc, cu_tva, ordine, id_set, participa_valuta, tip_rand, ;
id_jtva_coloana, ptva, explicatie_tva) ;
VALUES ('371', '401', 1, 1, 1, .T., 'B', 208, 21, 'ACH. INT. 21%')
INSERT INTO introdc_sablon (scd, scc, cu_tva, ordine, id_set, participa_valuta, tip_rand, ;
id_jtva_coloana, ptva, explicatie_tva) ;
VALUES ('4426', '401', 1, 2, 1, .T., 'T', 209, 21, 'TVA ACH. INT. 21%')
GO TOP IN introdc_sablon
IF USED('rul_temp')
USE IN ('rul_temp')
ENDIF
CREATE CURSOR rul_temp (denumire C(100), codmat C(30), cant N(14,3), pret_val N(18,4), ;
pretd N(18,4), pret N(18,4), pret_lei N(18,4), cont C(10), acont C(20), serie C(30), ;
lot C(30), adata_expirare C(10), proc_disc N(6,2), cota_tva N(6,2))
INSERT INTO rul_temp (denumire, codmat, cant, pret, pret_lei, cont, cota_tva) ;
VALUES ('PLACEHOLDER', 'PH', 1, 1, 1, '371', 21)
*-- index ord_doc INAINTE de CREATEOBJECT (capcana p, docs/testare-ui-vfp.md)
SELECT introdc
INDEX ON Str(Nvl(nr_doc,0),8) + Icase(tip_rand='B','1', tip_rand='S','2', tip_rand='G','3', tip_rand='T','4', tip_rand='D','5', '6') + Padr(Nvl(scd,''),10) TAG ord_doc
SET ORDER TO ord_doc
DO DdLog WITH 'cursoare pregatite, CREATEOBJECT(import_nota, .F. - mod import)'
PUBLIC goObj
goObj = CREATEOBJECT('IMPORT_nota', .F.)
IF VARTYPE(goObj) <> 'O'
DO DdLog WITH 'FAIL: instantiere import_nota'
DO HarnessDone WITH 'done-error'
QUIT
ENDIF
goObj.lDialogAratat = .T.
goObj.oact = poAct
goObj.lSpargeSecundare = .F.
goObj.WindowType = 0
goObj.Visible = .T.
goObj.Show()
goObj.WindowState = 2
DOEVENTS FORCE
SELECT rul_temp
ZAP
goObj.gridart.Refresh()
DOEVENTS FORCE
PRIVATE pnAsserts, pnPass
STORE 0 TO pnAsserts, pnPass
DO HarnessStep WITH 0, 'nota goala afisata, mod import (.F.)'
*========================= SCENARIU G: coada FIFO a mock-ului, 2 pick-uri in acelasi flux =========================
*-- valuta facturii (GBP) apoi valuta DVI (CHF) - independente; dupa coada, fallback la
*-- contractul vechi (goMockValuta fix).
PUBLIC goDlg
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = 6001
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 601
goDlg.cPartener = 'FURNIZOR UK LTD'
goDlg.nSuma = 100
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
PUBLIC goMockValuta, goMockValutaCoada
goMockValuta = CREATEOBJECT('Custom')
goMockValuta.AddProperty('id_valuta', 978)
goMockValuta.AddProperty('nume_val', 'EUR')
goMockValutaCoada = CREATEOBJECT('Collection')
LOCAL loValGbp, loValChf
loValGbp = CREATEOBJECT('Custom')
loValGbp.AddProperty('id_valuta', 826)
loValGbp.AddProperty('nume_val', 'GBP')
goMockValutaCoada.Add(loValGbp)
loValChf = CREATEOBJECT('Custom')
loValChf.AddProperty('id_valuta', 756)
loValChf.AddProperty('nume_val', 'CHF')
goMockValutaCoada.Add(loValChf)
goDlg.cmdValuta.Click()
=Assert3('G1-pick1 (valuta facturii) seteaza nIdValuta=826 (GBP)', goDlg.nIdValuta, 826)
=AssertStr('G2-pick1 cValuta=GBP', ALLTRIM(goDlg.cValuta), 'GBP')
=Assert3('G3-DVI mirror dupa pick1 (nDviIdValuta=826, nu e dirty inca)', goDlg.nDviIdValuta, 826)
goDlg.cmdDviValuta.Click()
=Assert3('G4-pick2 (valuta DVI) seteaza nDviIdValuta=756 (CHF)', goDlg.nDviIdValuta, 756)
=AssertStr('G5-pick2 cDviValuta=CHF', ALLTRIM(goDlg.cDviValuta), 'CHF')
=Assert3('G6-valuta facturii ramane GBP (independenta de pick2)', goDlg.nIdValuta, 826)
=Assert3('G7-coada goala dupa 2 pick-uri (Count=0)', goMockValutaCoada.Count, 0)
LOCAL loFallback
loFallback = caut_valuta()
=Assert3('G8-coada goala: caut_valuta() revine la contractul vechi (goMockValuta EUR=978)', loFallback.id_valuta, 978)
goDlg.Hide()
DOEVENTS FORCE
DO HarnessStep WITH 1, 'scenariul G (coada FIFO mock_caut_valuta) verificat - vezi log'
*========================= SCENARIU A: precompletare valuta/curs DVI din factura la Init =========================
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
=Assert3('A1-precompletare nDviIdValuta=978 (EUR, ca factura) la Init', goDlg.nDviIdValuta, 978)
=AssertStr('A2-precompletare cDviValuta=EUR la Init', ALLTRIM(goDlg.cDviValuta), 'EUR')
=Assert3('A3-precompletare nDviCurs=5 (ca factura) la Init', goDlg.nDviCurs, 5)
goDlg.optTipTva.Value = 2
goDlg.optTipTva.InteractiveChange()
=Assert3('A4-txtDviValuta.Visible=1 in mod TVA DVI', IIF(goDlg.txtDviValuta.Visible,1,0), 1)
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO HarnessStep WITH 2, 'scenariul A (precompletare DVI la Init) verificat - vezi log'
goDlg.Hide()
DOEVENTS FORCE
*========================= SCENARIU B: alegerea RON pe DVI =========================
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.optTipTva.Value = 2
goDlg.optTipTva.InteractiveChange()
PUBLIC goMockValutaCoada
goMockValutaCoada = CREATEOBJECT('Collection')
LOCAL loValRon
loValRon = CREATEOBJECT('Custom')
loValRon.AddProperty('id_valuta', 1)
loValRon.AddProperty('nume_val', 'RON')
goMockValutaCoada.Add(loValRon)
goDlg.cmdDviValuta.Click()
=Assert3('B1-alegere RON: nDviIdValuta=1', goDlg.nDviIdValuta, 1)
=AssertStr('B2-alegere RON: cDviValuta=RON', ALLTRIM(goDlg.cDviValuta), 'RON')
=Assert3('B3-alegere RON: nDviCurs fixat la 1', goDlg.nDviCurs, 1)
=Assert3('B4-alegere RON: txtDviCurs.Enabled=0 (disabled)', IIF(goDlg.txtDviCurs.Enabled,1,0), 0)
=Assert3('B5-alegere RON: txtDviTvaVal.Visible=1 (ramane vizibil, comuta pe lei)', IIF(goDlg.txtDviTvaVal.Visible,1,0), 1)
=Assert3('B6-alegere RON: nDviTvaVal=0', goDlg.nDviTvaVal, 0)
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO HarnessStep WITH 3, 'scenariul B (RON pe DVI) verificat - vezi log'
goDlg.Hide()
DOEVENTS FORCE
*========================= SCENARIU C: garda de dirty pe TVA in valuta DVI (a treia valuta) =========================
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.chkInValutaCont.Value = 1
goDlg.nSuma = 1000
goDlg.nProcentTva = 21
goDlg.optTipTva.Value = 2
goDlg.optTipTva.InteractiveChange()
PUBLIC goMockValutaCoada
goMockValutaCoada = CREATEOBJECT('Collection')
LOCAL loValUsd
loValUsd = CREATEOBJECT('Custom')
loValUsd.AddProperty('id_valuta', 840)
loValUsd.AddProperty('nume_val', 'USD')
goMockValutaCoada.Add(loValUsd)
goDlg.cmdDviValuta.Click()
=AssertStr('C1-DVI in USD (a treia valuta, diferita de EUR factura)', ALLTRIM(goDlg.cDviValuta), 'USD')
goDlg.txtDviCurs.Value = 4.5
goDlg.txtDviCurs.Valid()
goDlg.recalc_tva()
*-- nSumaLei=1000*5=5000; TvaLei=5000*21%=1050; TvaVal(auto)=Round(1050/4.5,2)=233.33
=Assert3('C2-baseline auto nDviTvaVal=233.33 (1050/4.5)', goDlg.nDviTvaVal, 233.33)
goDlg.txtDviTvaVal.Value = 999.99
goDlg.txtDviTvaVal.Valid()
=Assert3('C3-dupa editare manuala, nDviTvaVal=999.99', goDlg.nDviTvaVal, 999.99)
=Assert3('C4-lDviTvaValDirty=1 dupa editare manuala', IIF(goDlg.lDviTvaValDirty,1,0), 1)
goDlg.recalc_tva()
=Assert3('C5-dupa recalc_tva() repetat, nDviTvaVal ramane manual (999.99, nu se rescrie)', goDlg.nDviTvaVal, 999.99)
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO HarnessStep WITH 4, 'scenariul C (garda dirty TVA valuta DVI) verificat - vezi log'
goDlg.Hide()
DOEVENTS FORCE
*========================= SCENARIU D: discount fara bifa (Runda32), caption dupa valuta =========================
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
=Assert3('D1-txtDiscBaza.Visible=1 permanent (fara chkAreDiscount)', IIF(goDlg.txtDiscBaza.Visible,1,0), 1)
=AssertContains('D2-caption txtDiscBaza urmeaza valuta facturii (EUR)', 'EUR', goDlg.lblDiscBaza.Caption)
goDlg.chkInValutaCont.Value = 0
goDlg.chkInValutaCont.InteractiveChange()
=AssertContains('D3-caption dupa scoaterea valutei: "RON"', 'RON', goDlg.lblDiscBaza.Caption)
goDlg.txtDiscBaza.Value = 500
goDlg.txtDiscBaza.Valid()
=Assert3('D4-nDiscBaza=500 dupa completare', goDlg.nDiscBaza, 500)
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO HarnessStep WITH 5, 'scenariul D (discount fara bifa, caption dupa valuta) verificat - vezi log'
goDlg.Hide()
DOEVENTS FORCE
*========================= SCENARIU E: dirty-flags txtDviCurs + revert la realegere valuta DVI =========================
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.optTipTva.Value = 2
goDlg.optTipTva.InteractiveChange()
goDlg.txtDviCurs.Value = 4.75
goDlg.txtDviCurs.Valid()
=Assert3('E1-lDviCursDirty=1 dupa editare manuala curs DVI', IIF(goDlg.lDviCursDirty,1,0), 1)
=Assert3('E2-nDviCurs=4.75 dupa editare manuala', goDlg.nDviCurs, 4.75)
PUBLIC goMockValutaCoada
goMockValutaCoada = CREATEOBJECT('Collection')
LOCAL loValEur2
loValEur2 = CREATEOBJECT('Custom')
loValEur2.AddProperty('id_valuta', 978)
loValEur2.AddProperty('nume_val', 'EUR')
goMockValutaCoada.Add(loValEur2)
goDlg.cmdDviValuta.Click()
=Assert3('E3-lDviCursDirty resetat (0) dupa realegerea valutei DVI', IIF(goDlg.lDviCursDirty,1,0), 0)
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO HarnessStep WITH 6, 'scenariul E (dirty-flags txtDviCurs + revert) verificat - vezi log'
goDlg.Hide()
DOEVENTS FORCE
*========================= SCENARIU F1: validare blocanta - DVI non-RON cu curs 0 =========================
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = 6002
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 601
goDlg.cPartener = 'FURNIZOR UK LTD'
goDlg.nSuma = 100
goDlg.optTipTva.Value = 2
goDlg.optTipTva.InteractiveChange()
goDlg.nNractDvi = 7002
goDlg.dDviData = DATE()
goDlg.nDviIdPartener = 900
goDlg.cDviPartener = 'DIRECTIA VAMALA'
goDlg.nDviTvaLei = 21
goDlg.nDviIdValuta = 840
goDlg.cDviValuta = 'USD'
goDlg.nDviCurs = 0
*-- flagurile dirty marcheaza ca DVI a fost ales explicit (picker/curs tastat) - fara ele,
*-- dvi_valuta_efectiva()/dvi_curs_efectiv() urmeaza factura (EUR), nu USD/0 setate direct
goDlg.lDviValutaDirty = .T.
goDlg.lDviCursDirty = .T.
gcMockUltimMesaj = ''
LOCAL llOkF1
llOkF1 = goDlg.valideaza()
=Assert3('F1a-valideaza() respinge DVI non-RON cu curs 0', IIF(llOkF1,1,0), 0)
=AssertContains('F1b-mesaj contine "curs"', 'curs', gcMockUltimMesaj)
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO HarnessStep WITH 7, 'scenariul F1 (DVI curs 0 blocant) verificat - vezi log'
goDlg.Hide()
DOEVENTS FORCE
*========================= SCENARIU F2: validari blocante - discount negativ / discount >= suma =========================
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = 6003
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 601
goDlg.cPartener = 'FURNIZOR UK LTD'
goDlg.nSuma = 100
goDlg.nIdExplicatieTva = 208
goDlg.cExplicatieTva = 'ACH. INT. 21%'
goDlg.optTipTva.Value = 1
goDlg.txtDiscBaza.Value = -10
goDlg.txtDiscBaza.Valid()
gcMockUltimMesaj = ''
LOCAL llOkF2a
llOkF2a = goDlg.valideaza()
=Assert3('F2a-valideaza() respinge discount negativ', IIF(llOkF2a,1,0), 0)
=AssertContains('F2b-mesaj contine "discount"', 'discount', gcMockUltimMesaj)
goDlg.txtDiscBaza.Value = 100
goDlg.txtDiscBaza.Valid()
gcMockUltimMesaj = ''
LOCAL llOkF2c
llOkF2c = goDlg.valideaza()
=Assert3('F2c-valideaza() respinge discount >= suma facturii', IIF(llOkF2c,1,0), 0)
=AssertContains('F2d-mesaj contine "discount"', 'discount', gcMockUltimMesaj)
goDlg.txtDiscBaza.Value = 50
goDlg.txtDiscBaza.Valid()
LOCAL llOkF2e
llOkF2e = goDlg.valideaza()
=Assert3('F2e-discount < suma: valideaza() trece', IIF(llOkF2e,1,0), 1)
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO HarnessStep WITH 8, 'scenariul F2 (discount negativ / >=suma blocante) verificat - vezi log'
goDlg.Hide()
DOEVENTS FORCE
*========================= SCENARIU H: regresie - Tab fara modificare NU inghenuncheaza dirty =========================
*-- Regresia reala reparata de orchestrator: garda veche (This.Value<>Thisform.nXxx) nu se
*-- declansa NICIODATA, nici in productie, pentru ca ControlSource sincronizeaza proprietatea
*-- legata INAINTE ca Valid sa apuce sa compare. Fix: tipar nOldVal (GotFocus retine valoarea
*-- la intrare, Valid seteaza dirty doar daca s-a schimbat fata de acel moment - cf.
*-- GridArt.cCant.Text1.GotFocus, deja existent in proiect). Fara acest test, un refactor
*-- viitor ar putea reintroduce garda veche (mereu "dirty", declansata de intamplare de
*-- initializarea la 0 a lui nOldVal) fara sa aprinda nimic.
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = 6004
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 601
goDlg.cPartener = 'FURNIZOR UK LTD'
goDlg.nSuma = 100
goDlg.optTipTva.Value = 2
goDlg.optTipTva.InteractiveChange()
*-- txtDviTvaVal: valoare initiala, dirty resetat, Tab FARA modificare, apoi modificare reala
goDlg.lDviTvaValDirty = .F.
goDlg.txtDviTvaVal.Value = 500
goDlg.txtDviTvaVal.GotFocus()
goDlg.txtDviTvaVal.Valid()
=Assert3('H1-txtDviTvaVal: Tab fara modificare NU seteaza dirty', IIF(goDlg.lDviTvaValDirty,1,0), 0)
goDlg.txtDviTvaVal.Value = 777
goDlg.txtDviTvaVal.Valid()
=Assert3('H2-txtDviTvaVal: modificare reala SETEAZA dirty', IIF(goDlg.lDviTvaValDirty,1,0), 1)
*-- txtDviCurs: acelasi tipar
goDlg.lDviCursDirty = .F.
goDlg.txtDviCurs.Value = 5
goDlg.txtDviCurs.GotFocus()
goDlg.txtDviCurs.Valid()
=Assert3('H3-txtDviCurs: Tab fara modificare NU seteaza dirty', IIF(goDlg.lDviCursDirty,1,0), 0)
goDlg.txtDviCurs.Value = 6
goDlg.txtDviCurs.Valid()
=Assert3('H4-txtDviCurs: modificare reala SETEAZA dirty', IIF(goDlg.lDviCursDirty,1,0), 1)
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO HarnessStep WITH 9, 'scenariul H (Tab fara modificare nu seteaza dirty) verificat - vezi log'
goDlg.Hide()
DOEVENTS FORCE
DO DdLog WITH 'REZULTAT: ' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' assert-uri PASS'
IF pnPass = pnAsserts
DO DdLog WITH 'REZULTAT: PASS (' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ')'
ELSE
DO DdLog WITH 'REZULTAT: FAIL (' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' assert-uri PASS)'
ENDIF
DO HarnessStep WITH 10, 'final: ' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' PASS'
DO HarnessDone WITH 'done'
CATCH TO loExc
DO DdLog WITH 'CATCH ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']'
DO HarnessDone WITH 'done-error'
ENDTRY
QUIT
*==================================================================================
PROCEDURE CreeazaIntrodc
*-- Runda30 (F1/pas2): coloane NOI rand_dvi N(1), valuta_proprie N(1) fata de structura veche.
LPARAMETERS tcAlias
IF USED(tcAlias)
USE IN (tcAlias)
ENDIF
CREATE CURSOR (tcAlias) ( ;
id_note N(14), explicatia C(100), scd C(10), ascd C(20), scc C(10), ascc C(20), ;
cu_tva N(1), id_set N(14), ordine N(8), in_valuta N(1), id_jtva_coloana N(14) NULL, ;
ptva N(6,2), explicatie_tva C(50), tipjurnal C(2), taxcode N(6), paymentcode C(9), ;
suma N(18,4), suma_val N(18,4), id_partd N(14), id_partc N(14), partd C(100), partc C(100), ;
id_fact N(14), id_factd N(14), id_factc N(14), pereched N(14), perechec N(14), ;
nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), expl_manual N(1), ;
scd_orig C(20), ascd_orig C(20), rand_dvi N(1), valuta_proprie N(1))
ENDPROC
FUNCTION RECCOUNT_ACTIVE
LPARAMETERS tcAlias
LOCAL lnSel, lnCnt
lnSel = SELECT()
SELECT (tcAlias)
COUNT TO lnCnt FOR !DELETED()
SELECT (lnSel)
RETURN lnCnt
ENDFUNC
PROCEDURE Assert3
LPARAMETERS tcLabel, tuActual, tuExpected
pnAsserts = pnAsserts + 1
IF ABS(NVL(tuActual,0) - tuExpected) < 0.02
pnPass = pnPass + 1
DO DdLog WITH ' PASS ' + tcLabel + ' (=' + TRANSFORM(tuActual) + ')'
ELSE
DO DdLog WITH ' FAIL ' + tcLabel + ' (actual=' + TRANSFORM(tuActual) + ' asteptat=' + TRANSFORM(tuExpected) + ')'
ENDIF
ENDPROC
PROCEDURE AssertStr
LPARAMETERS tcLabel, tcActual, tcExpected
pnAsserts = pnAsserts + 1
IF tcActual == tcExpected
pnPass = pnPass + 1
DO DdLog WITH ' PASS ' + tcLabel + ' (=[' + tcActual + '])'
ELSE
DO DdLog WITH ' FAIL ' + tcLabel + ' (actual=[' + tcActual + '] asteptat=[' + tcExpected + '])'
ENDIF
ENDPROC
PROCEDURE AssertContains
LPARAMETERS tcLabel, tcNeedle, tcHaystack
pnAsserts = pnAsserts + 1
IF UPPER(ALLTRIM(tcNeedle)) $ UPPER(ALLTRIM(NVL(tcHaystack,'')))
pnPass = pnPass + 1
DO DdLog WITH ' PASS ' + tcLabel + ' ([' + tcNeedle + '] gasit in [' + tcHaystack + '])'
ELSE
DO DdLog WITH ' FAIL ' + tcLabel + ' ([' + tcNeedle + '] NEGASIT in [' + tcHaystack + '])'
ENDIF
ENDPROC
PROCEDURE DdErr
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
DO DdLog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
ENDPROC
PROCEDURE DdLog
LPARAMETERS tcMsg
SET SAFETY OFF
LOCAL lcL
lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '')
STRTOFILE(lcL + tcMsg + CHR(13)+CHR(10), gcUILog)
ENDPROC
DEFINE CLASS dummyapp AS Custom
PROCEDURE ReadIni
LPARAMETERS tcSection, tcKey
RETURN ''
ENDPROC
PROCEDURE WriteIni
LPARAMETERS tcSection, tcKey, tcValue
RETURN .T.
ENDPROC
ENDDEFINE
DEFINE CLASS dummyexecutor AS Custom
cEroare = ''
PROCEDURE oExecute
LPARAMETERS tcSql, tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF 'VJTVA_COLOANE' $ UPPER(m.tcSql)
DO CreeazaJtvaColoaneView WITH m.tcCursor
RETURN 1
ENDIF
IF UPPER(ALLTRIM(m.tcCursor)) == 'RUL_TEMP'
CREATE CURSOR (m.tcCursor) (denumire C(100), codmat C(30), cant N(14,3), ;
pret_val N(18,4), pretd N(18,4), pret N(18,4), pret_lei N(18,4), cont C(10), ;
acont C(20), serie C(30), lot C(30), adata_expirare C(10), proc_disc N(6,2), cota_tva N(6,2))
RETURN 1
ENDIF
IF 'CONFIG_ANALITICE' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (camp_leg_prefix C(30), camp_leg_sufix C(30))
INSERT INTO (m.tcCursor) VALUES ('', '')
RETURN 1
ENDIF
IF 'FCONTURI_ANALITICE' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (acont C(20))
INSERT INTO (m.tcCursor) VALUES (IIF(TYPE('gcMockAcontCrt') = 'C', gcMockAcontCrt, ''))
RETURN 1
ENDIF
IF 'VPLCONT_ANALITIC' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (cont C(10), acont C(20))
INSERT INTO (m.tcCursor) VALUES ('371', '4')
RETURN 1
ENDIF
CREATE CURSOR (m.tcCursor) (id_temp N(1))
RETURN 1
ENDPROC
PROCEDURE oExecuta
LPARAMETERS tcSql, tcCursor
IF !EMPTY(m.tcCursor)
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF UPPER(m.tcCursor) == 'CJTVACOL4427'
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14))
ELSE
CREATE CURSOR (m.tcCursor) (id_temp N(1))
ENDIF
ENDIF
RETURN .T.
ENDPROC
PROCEDURE oSelect2Value
LPARAMETERS tcSql, toValue
toValue = ''
RETURN 1
ENDPROC
PROCEDURE oReset
ENDPROC
ENDDEFINE
PROCEDURE CreeazaJtvaColoaneView
LPARAMETERS tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14), denumire C(100), jc N(1), jv N(1), ;
coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14) NULL, afisat N(1), ;
id_jtva_ex N(14) NULL, id_jtva_neex N(14) NULL, ordine N(8), ;
taxcode N(6) NULL, taxcode_neexigibil N(6) NULL, taxcode_n50 N(6) NULL, ;
taxcode_n50_tvai N(6) NULL, taxcode_n100 N(6) NULL, taxcode_regularizare N(6) NULL, taxcode_tvai N(6) NULL)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, afisat, ordine, cota_tva) VALUES (0, '', 0, 0, 1, 0, 0)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (208, 'ACH. INT. 21%', 1, 0, 'RO21B', 21, 209, 1, 1, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (209, 'TVA ACH. INT. 21%', 1, 0, 'RO21T', 21, 1, 2, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (220, 'ACH. IMP. 21%', 1, 0, 'FO21B', 21, 221, 1, 3, 301204)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (221, 'TVA ACH. IMP. 21%', 1, 0, 'FO21T', 21, 1, 4, 301204)
ENDPROC

View File

@@ -0,0 +1,11 @@
# test_dvi_dialog_ui.ps1 - wrapper peste harness-ul generic pentru testul dialogului DVI/discount.
# Rulare: powershell -ExecutionPolicy Bypass -File test_dvi_dialog_ui.ps1
$ErrorActionPreference = 'Stop'
$Teste = $PSScriptRoot
& (Join-Path (Split-Path $Teste -Parent) 'vfp_ui_harness.ps1') `
-TestPrg (Join-Path $Teste 'test_dvi_dialog_ui.prg') `
-Steps @('nota_goala','coada_fifo_mock','precompletare_dvi','ron_pe_dvi','garda_dirty_tva_dvi','discount_fara_bifa','dirty_curs_dvi','f1_dvi_curs_zero','f2_discount_negativ_sau_max','tab_fara_modificare','final') `
-ShotsDir (Join-Path $Teste 'screenshots_dvi_dialog') `
-SyncDir (Join-Path $Teste 'uisync_dvi_dialog') `
-StepTimeoutSec 180 `
-ReadyTimeoutSec 180

View File

@@ -0,0 +1,718 @@
* test_dvi_multicota.prg
* Scenariul raportat de Marius (28.07.2026): factura de import in EUR cu discount financiar,
* TVA-ul platit in vama (DVI) in RON si articole pe DOUA cote (21% si 11%). Verifica pe fluxul
* REAL (dialog import_adauga_factura + do_adauga_articol + sincronizeaza) ca toate cele trei
* familii de randuri ale documentului ajung pe cotele articolelor, concordant:
* - S (baza): cate un rand pe cont+cota, cu ptva-ul articolelor lui (creeaza_rand_s + tnCota);
* - G (discount): spart proportional cu bazele pe cota (sparge_discount), total pastrat;
* - T (TVA DVI, rand protejat valuta_proprie=1): spart pe cote cu pondere baza x cota
* (sparge_tva_protejat), total pastrat = suma tastata de pe DVI.
*
* Cifre: 1500 EUR (1000@21% + 500@11%), curs 5, discount 150 EUR (10%), TVA DVI 1192.50 lei
* (= TVA-ul corect pe baze diminuate: (1000-100)*21% + (500-50)*11% = 238.50 EUR x 5).
* - G: 100 EUR (500 lei) pe 21% + 50 EUR (250 lei) pe 11%
* - T: 1192.50 * 210/265 = 945.00 lei pe 21% + 1192.50 * 55/265 = 247.50 lei pe 11%
* (ponderi: 1000*21% = 210, 500*11% = 55), suma_val = 0 pe ambele (DVI in RON).
*
* Rulare:
* powershell -ExecutionPolicy Bypass -File test_dvi_multicota.ps1
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET DECIMALS TO 4
SET NULLDISPLAY TO ''
CLOSE DATABASES
PUBLIC gcUILog, gcSyncDir
gcUILog = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\test_dvi_multicota_log.txt"
gcSyncDir = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\uisync_dvi_multicota\"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcUILog)
ON ERROR DO McErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
TRY
LOCAL gcAppPath, lcPath
gcAppPath = "D:\ROA\ROAGEST\"
SET DEFAULT TO (gcAppPath)
lcPath = gcAppPath + 'Date;' + gcAppPath + 'Include;' + gcAppPath + 'FERESTRE;' + ;
gcAppPath + 'GRAFICE;' + gcAppPath + 'CLASE;' + gcAppPath + 'MENIURI;' + ;
gcAppPath + 'PROGRAME;' + gcAppPath + 'RAPOARTE;' + gcAppPath + 'COMUN;' + ;
gcAppPath + 'COMUN\CLASE;' + gcAppPath + 'COMUN\FERESTRE;' + gcAppPath + 'COMUN\PROGRAME;' + ;
gcAppPath + 'COMUN\GRAFICE;' + gcAppPath + 'COMUN\RAPOARTE;' + gcAppPath + 'COMUN\MENIURI;' + ;
gcAppPath + 'COMUN\UTILE\GRIDEXTRAS;' + gcAppPath + 'COMUN\UTILE\CTL32;' + ;
gcAppPath + 'COMUN\UTILE\HPDF;' + gcAppPath + 'COMUN\UTILE\HPDF\REPORTOUTPUT;' + ;
gcAppPath + 'COMUN\UTILE\WEB;' + gcAppPath + 'COMUN\UTILE\EXCEL;' + ;
ADDBS(SUBSTR(gcAppPath,1,RAT([\],gcAppPath,2)))+[COMUNROA\]
SET PATH TO &lcPath ADDITIVE
DO McLog WITH 'SET PATH OK'
*----- CLASE -----
SET CLASSLIB TO (gcAppPath + "comun\clase\appwiz") ADDITIVE
SET CLASSLIB TO GESTIUNI ADDITIVE
SET CLASSLIB TO CAUT ADDITIVE
SET CLASSLIB TO BAZA ADDITIVE
SET CLASSLIB TO comun ADDITIVE
SET CLASSLIB TO accessibility.vcx ADDITIVE
SET CLASSLIB TO messagebox ADDITIVE
SET CLASSLIB TO registry ADDITIVE
SET CLASSLIB TO cauta_alfa_forms.vcx ADDITIVE
SET CLASSLIB TO DECABAZA ADDITIVE
SET CLASSLIB TO onomenclatoare ADDITIVE
SET CLASSLIB TO stocuri.vcx ADDITIVE
SET CLASSLIB TO rulaje.vcx ADDITIVE
SET CLASSLIB TO ointroduceri ADDITIVE
SET CLASSLIB TO ointroduceri_web ADDITIVE
SET CLASSLIB TO ointroduceri_depozit ADDITIVE
SET CLASSLIB TO overificari ADDITIVE
SET CLASSLIB TO ferestre_oracle ADDITIVE
SET CLASSLIB TO ferestre_cere_date.vcx ADDITIVE
SET CLASSLIB TO configurare.vcx ADDITIVE
SET CLASSLIB TO serii_numere.vcx ADDITIVE
SET CLASSLIB TO omodificari.vcx ADDITIVE
SET CLASSLIB TO ocompensari.vcx ADDITIVE
SET CLASSLIB TO caut_ora ADDITIVE
SET CLASSLIB TO onote_contabile ADDITIVE
SET CLASSLIB TO otoolbar ADDITIVE
SET CLASSLIB TO bon_fisc ADDITIVE
SET CLASSLIB TO onom_articole ADDITIVE
SET CLASSLIB TO onom_retete ADDITIVE
SET CLASSLIB TO orapoarte ADDITIVE
SET CLASSLIB TO orapoarte_gestiuni ADDITIVE
SET CLASSLIB TO orapoarte_parametri ADDITIVE
SET CLASSLIB TO ONOM_CURS ADDITIVE
SET CLASSLIB TO ctl32_statusbar_fals.vcx ADDITIVE
SET CLASSLIB TO ctl32_common.vcx ADDITIVE
SET CLASSLIB TO ctl32_structs.vcx ADDITIVE
SET CLASSLIB TO ctl32_progressbar.vcx ADDITIVE
SET CLASSLIB TO ctl32_balloontip.vcx ADDITIVE
SET CLASSLIB TO ocriterii.vcx ADDITIVE
SET CLASSLIB TO oavize.vcx ADDITIVE
SET CLASSLIB TO onomenclatoare2 ADDITIVE
SET CLASSLIB TO wwdialogs.vcx ADDITIVE
SET CLASSLIB TO oimportxml.vcx ADDITIVE
SET CLASSLIB TO excelxml.vcx ADDITIVE
SET CLASSLIB TO orapoarte_obinv.vcx ADDITIVE
DO McLog WITH 'SET CLASSLIB OK'
*----- PROCEDURI (mock-uri PRIMELE, ui_harness la final) -----
SET PROCEDURE TO PROCEDURI
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_cauta_nom_articole.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\mock_caut_valuta.prg" ADDITIVE
SET PROCEDURE TO acces_meniu ADDITIVE
SET PROCEDURE TO cauta_alfa ADDITIVE
SET PROCEDURE TO pmenu ADDITIVE
SET PROCEDURE TO proceduri_comune ADDITIVE
SET PROCEDURE TO quitapp ADDITIVE
SET PROCEDURE TO init_program ADDITIVE
SET PROCEDURE TO oproceduri_listari.prg ADDITIVE
SET PROCEDURE TO oproceduri_configurare.prg ADDITIVE
SET PROCEDURE TO oproceduri_articole.prg ADDITIVE
SET PROCEDURE TO oproceduri_retete.prg ADDITIVE
SET PROCEDURE TO orapoarte.prg ADDITIVE
SET PROCEDURE TO mesaje ADDITIVE
SET PROCEDURE TO oserii_numere.prg ADDITIVE
SET PROCEDURE TO oexport.prg ADDITIVE
SET PROCEDURE TO wwConfig.prg ADDITIVE
SET PROCEDURE TO proceduri_rapoarte.prg ADDITIVE
SET PROCEDURE TO OPROCEDURI_CURS.PRG ADDITIVE
SET PROCEDURE TO validare.prg ADDITIVE
SET PROCEDURE TO GENCURSOR.PRG ADDITIVE
SET PROCEDURE TO OPROCEDURI_COMUNE.PRG ADDITIVE
SET PROCEDURE TO OINIT_OPTIUNI.PRG ADDITIVE
SET PROCEDURE TO updateserver.prg ADDITIVE
SET PROCEDURE TO oinainte_de.prg ADDITIVE
SET PROCEDURE TO ooperatii_comune.prg ADDITIVE
SET PROCEDURE TO Ocompensari.PRG ADDITIVE
SET PROCEDURE TO OPROCEDURI_aMS.PRG ADDITIVE
SET PROCEDURE TO oproceduri_rulaje ADDITIVE
SET PROCEDURE TO oproceduri_stocuri ADDITIVE
SET PROCEDURE TO OINTRODUCERI ADDITIVE
SET PROCEDURE TO oHeader.prg ADDITIVE
SET PROCEDURE TO proceduri_excel.PRG ADDITIVE
SET PROCEDURE TO onomenclatoare.PRG ADDITIVE
SET PROCEDURE TO osecurity ADDITIVE
SET PROCEDURE TO ocautare ADDITIVE
SET PROCEDURE TO orefaceri ADDITIVE
SET PROCEDURE TO ofacturare_comun.PRG ADDITIVE
SET PROCEDURE TO ofacturare_stoc.PRG ADDITIVE
SET PROCEDURE TO oproceduri_casademarcat ADDITIVE
SET PROCEDURE TO oproceduri_casa_marcat_e500 ADDITIVE
SET PROCEDURE TO oproceduri_casa_marcat_mp500 ADDITIVE
SET PROCEDURE TO oproceduri_util.prg ADDITIVE
SET PROCEDURE TO wwxmlhttp.prg ADDITIVE
SET PROCEDURE TO ini.prg ADDITIVE
SET PROCEDURE TO odocumente.prg ADDITIVE
SET PROCEDURE TO regex.prg ADDITIVE
SET PROCEDURE TO wwutils.prg ADDITIVE
SET PROCEDURE TO inchidere_k ADDITIVE
SET PROCEDURE TO iniacces.prg ADDITIVE
SET PROCEDURE TO oupdate.prg ADDITIVE
SET PROCEDURE TO procese.prg ADDITIVE
SET PROCEDURE TO version.prg ADDITIVE
SET PROCEDURE TO xmlaccess.prg ADDITIVE
SET PROCEDURE TO xmlparser.prg ADDITIVE
SET PROCEDURE TO filebringer.prg ADDITIVE
SET PROCEDURE TO wwcodeupdate.prg ADDITIVE
SET PROCEDURE TO wwhttp.prg ADDITIVE
SET PROCEDURE TO xdate.prg ADDITIVE
SET PROCEDURE TO ofacturare.prg ADDITIVE
SET PROCEDURE TO oproceduri_obinv.prg ADDITIVE
SET PROCEDURE TO oproceduri_facturare.prg ADDITIVE
SET PROCEDURE TO email.prg ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\ui_harness.prg" ADDITIVE
DO McLog WITH 'SET PROCEDURE OK'
PUBLIC goMockValuta
goMockValuta = CREATEOBJECT('Custom')
goMockValuta.AddProperty('id_valuta', 978)
goMockValuta.AddProperty('nume_val', 'EUR')
*----- Globale -----
PUBLIC gnPc, gnPval, gnPcant, gnPpret, gnPPretval, gnPCurs, gnPVal, gnPPretV, gnPPretVal
STORE 2 TO gnPc, gnPval, gnPVal
gnPcant = 3
STORE 4 TO gnPpret, gnPPretval, gnPPretVal, gnPPretV, gnPCurs
PUBLIC gl406, gcS, gnAn, gnLuna, gnIdFirma, gnIdSucursala, gcAcces, gcFirma
gl406 = .T.
gcS = 'CONTAFIN'
gnAn = YEAR(DATE())
gnLuna = MONTH(DATE())
gnIdFirma = 110
gnIdSucursala = 110
gcAcces = "1;2;3;4;5;6;7;8;"
gcFirma = gcS
PUBLIC nror(65000)
PUBLIC gnButon
STORE 2 TO gnButon
PUBLIC gcMockArtCodmat, gcMockAcontCrt
gcMockArtCodmat = ''
gcMockAcontCrt = ''
PUBLIC gnMockRaspuns
gnMockRaspuns = 6
PUBLIC goExecutor, goApp
goExecutor = CREATEOBJECT('dummyexecutor')
goApp = CREATEOBJECT('dummyapp')
*----- poAct: antetul notei (moneda principala EUR, curs 5) -----
PUBLIC poAct
poAct = CREATEOBJECT('Custom')
poAct.AddProperty('nume_val', 'EUR')
poAct.AddProperty('curs', 5)
poAct.AddProperty('proc_tva', 1.21)
poAct.AddProperty('nnir', 0)
poAct.AddProperty('id_valuta', 978)
poAct.AddProperty('id_fdoc', 1)
poAct.AddProperty('fdoc', 'Factura')
poAct.AddProperty('id_partc', 601)
poAct.AddProperty('partc', 'MULTI SUPPLY SRL')
poAct.AddProperty('serie_act', '')
poAct.AddProperty('dataact', DATE())
poAct.AddProperty('tva_incasare', 0)
poAct.AddProperty('id_set', 1)
poAct.AddProperty('id_gestin', 1)
*----- jtva_coloane2 / saft_taxtable: DOUA familii import (FO), 21% si 11% -----
IF USED('jtva_coloane2')
USE IN ('jtva_coloane2')
ENDIF
CREATE CURSOR jtva_coloane2 (ordine N(8), id_jtva_coloana N(14), denumire C(100), ;
jc N(1), jv N(1), afisat N(1), coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14))
INSERT INTO jtva_coloane2 VALUES (0, 0, '', 0, 0, 1, '', '', 0, 0)
INSERT INTO jtva_coloane2 VALUES (1, 220, 'ACH. IMP. 21%', 1, 0, 1, 'FO21B', 'FO21T', 21, 221)
INSERT INTO jtva_coloane2 VALUES (2, 221, 'TVA ACH. IMP. 21%', 1, 0, 1, 'FO21T', '', 21, 0)
INSERT INTO jtva_coloane2 VALUES (3, 222, 'ACH. IMP. 11%', 1, 0, 1, 'FO11B', 'FO11T', 11, 223)
INSERT INTO jtva_coloane2 VALUES (4, 223, 'TVA ACH. IMP. 11%', 1, 0, 1, 'FO11T', '', 11, 0)
IF USED('saft_taxtable')
USE IN ('saft_taxtable')
ENDIF
CREATE CURSOR saft_taxtable (taxname C(250) NULL, typename C(250) NULL, taxcode N(6) NULL, ;
taxtype N(3) NULL, descriere C(250) NULL, tip C(100) NULL, descriere_tip C(250) NULL, ;
procent_taxa N(7,2) NULL, procent_prorata N(7,2) NULL, inactiv N(1) NULL, tva N(1) NULL, ;
wht N(1) NULL, tva_achizitii N(1) NULL, tva_livrari N(1) NULL)
INDEX ON taxcode TAG taxcode
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('', 0, '', 0, 1, 1, 1, 1)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301204-Import de bunuri cota 21%', 301204, '', 21, 1, 0, 1, 0)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301205-Import de bunuri cota 11%', 301205, '', 11, 1, 0, 1, 0)
DO CreeazaIntrodc WITH 'introdc'
DO CreeazaIntrodc WITH 'introdc_sablon'
INSERT INTO introdc_sablon (scd, scc, cu_tva, ordine, id_set, participa_valuta, tip_rand, ;
id_jtva_coloana, ptva, explicatie_tva) ;
VALUES ('371', '401', 1, 1, 1, .T., 'B', 220, 21, 'ACH. IMP. 21%')
INSERT INTO introdc_sablon (scd, scc, cu_tva, ordine, id_set, participa_valuta, tip_rand, ;
id_jtva_coloana, ptva, explicatie_tva) ;
VALUES ('4426', '401', 1, 2, 1, .T., 'T', 221, 21, 'TVA ACH. IMP. 21%')
GO TOP IN introdc_sablon
DO CreeazaRulTemp
INSERT INTO rul_temp (denumire, codmat, cant, pret, pret_lei, cont, cota_tva) ;
VALUES ('PLACEHOLDER', 'PH', 1, 1, 1, '371', 21)
SELECT introdc
INDEX ON Str(Nvl(nr_doc,0),8) + Icase(tip_rand='B','1', tip_rand='S','2', tip_rand='G','3', tip_rand='T','4', tip_rand='D','5', '6') + Padr(Nvl(scd,''),10) TAG ord_doc
SET ORDER TO ord_doc
DO McLog WITH 'cursoare pregatite, CREATEOBJECT(import_nota, .F.)'
PUBLIC goObj
goObj = CREATEOBJECT('IMPORT_nota', .F.)
IF VARTYPE(goObj) <> 'O'
DO McLog WITH 'FAIL: instantiere import_nota'
DO HarnessDone WITH 'done-error'
QUIT
ENDIF
goObj.lDialogAratat = .T.
goObj.oact = poAct
goObj.lSpargeSecundare = .F.
goObj.WindowType = 0
goObj.Visible = .T.
goObj.Show()
goObj.WindowState = 2
DOEVENTS FORCE
SELECT rul_temp
ZAP
goObj.gridart.Refresh()
DOEVENTS FORCE
PRIVATE pnAsserts, pnPass
STORE 0 TO pnAsserts, pnPass
*========================= FACTURA: 1500 EUR (1000@21% + 500@11%), discount 150 EUR =========================
PUBLIC goDlg, goT, gcDocKey1
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = 17000
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 601
goDlg.cPartener = 'MULTI SUPPLY SRL'
goDlg.cExplicatia = 'Import marfa multicota'
goDlg.nSuma = 1500
goDlg.nSumaLei = 0
goDlg.nCurs = 5
goDlg.nIdValuta = 978
goDlg.cValuta = 'EUR'
goDlg.nIdExplicatieTva = 220
goDlg.cExplicatieTva = 'ACH. IMP. 21%'
goDlg.optTipTva.Value = 2
goDlg.chkInValutaCont.Value = 1
goDlg.chkParticipaValuta.Value = 1
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO McLog WITH 'valideaza = ' + TRANSFORM(goDlg.valideaza())
goT = CREATEOBJECT('Empty')
=ADDPROPERTY(goT,'serie_act','')
=ADDPROPERTY(goT,'nract',goDlg.nNract)
=ADDPROPERTY(goT,'dataact',goDlg.dDataAct)
=ADDPROPERTY(goT,'fdoc',goDlg.cFelDoc)
=ADDPROPERTY(goT,'id_fdoc',goDlg.nIdFdoc)
=ADDPROPERTY(goT,'id_partc',goDlg.nIdPartener)
=ADDPROPERTY(goT,'partc',goDlg.cPartener)
=ADDPROPERTY(goT,'explicatia',ALLTRIM(NVL(goDlg.cExplicatia,'')))
=ADDPROPERTY(goT,'suma',ROUND(goDlg.nSuma*goDlg.nCurs,gnPC))
=ADDPROPERTY(goT,'suma_val',goDlg.nSuma)
=ADDPROPERTY(goT,'in_valuta',goDlg.chkInValutaCont.Value)
=ADDPROPERTY(goT,'participa_valuta',.T.)
=ADDPROPERTY(goT,'id_valuta',goDlg.nIdValuta)
=ADDPROPERTY(goT,'curs',goDlg.nCurs)
=ADDPROPERTY(goT,'nume_val',ALLTRIM(NVL(goDlg.cValuta,'')))
=ADDPROPERTY(goT,'cTipTva','D')
=ADDPROPERTY(goT,'id_jtva_coloana',goDlg.nIdExplicatieTva)
=ADDPROPERTY(goT,'dvi_serie','')
=ADDPROPERTY(goT,'dvi_nract',9017)
=ADDPROPERTY(goT,'dvi_dataact',DATE())
=ADDPROPERTY(goT,'dvi_id_fdoc',2)
=ADDPROPERTY(goT,'dvi_fdoc','DVI')
=ADDPROPERTY(goT,'dvi_id_partc',901)
=ADDPROPERTY(goT,'dvi_partc','DIRECTIA VAMALA')
=ADDPROPERTY(goT,'dvi_scc','401')
=ADDPROPERTY(goT,'dvi_tva_lei',1192.50)
=ADDPROPERTY(goT,'dvi_tva_val',0)
=ADDPROPERTY(goT,'dvi_in_valuta',.F.)
=ADDPROPERTY(goT,'dvi_id_valuta',0)
=ADDPROPERTY(goT,'dvi_curs',0)
=ADDPROPERTY(goT,'dvi_nume_val','')
=ADDPROPERTY(goT,'dvi_valuta_proprie',1)
=ADDPROPERTY(goT,'disc_baza_lei',ROUND(150*5,gnPC))
=ADDPROPERTY(goT,'disc_baza_val',150)
LOCAL llOkAdauga
llOkAdauga = goObj.do_adauga_factura(goT)
=Assert3('1-do_adauga_factura(goT) reuseste', IIF(llOkAdauga,1,0), 1)
goDlg.Hide()
DOEVENTS FORCE
SELECT introdc
SET ORDER TO
LOCATE FOR nract = 17000 AND tip_rand == 'B'
IF FOUND()
gcDocKey1 = ALLTRIM(NVL(doc_key,''))
ENDIF
SELECT introdc
SET ORDER TO ord_doc
DO HarnessStep WITH 0, 'factura creata, doc_key=' + gcDocKey1
*========================= DOUA ARTICOLE, COTE DIFERITE (21% si 11%) =========================
gcMockArtCodmat = 'ART-BULD-212'
gcMockAcontCrt = ''
TRY
goObj.do_adauga_articol()
CATCH TO loExcA1
DO McLog WITH 'EROARE do_adauga_articol (1) ' + TRANSFORM(loExcA1.ErrorNo) + ' [' + loExcA1.Message + ']'
ENDTRY
DOEVENTS FORCE
SELECT rul_temp
LOCATE FOR ALLTRIM(codmat) == 'ART-BULD-212'
IF FOUND()
REPLACE cant WITH 1, pret_val WITH 1000, pretd WITH 1000, pret WITH ROUND(1000*5,4), ;
pret_lei WITH ROUND(1000*5,4), cota_tva WITH 21
ENDIF
gcMockArtCodmat = 'ART-A8-371'
TRY
goObj.do_adauga_articol()
CATCH TO loExcA2
DO McLog WITH 'EROARE do_adauga_articol (2) ' + TRANSFORM(loExcA2.ErrorNo) + ' [' + loExcA2.Message + ']'
ENDTRY
DOEVENTS FORCE
SELECT rul_temp
LOCATE FOR ALLTRIM(codmat) == 'ART-A8-371'
IF FOUND()
REPLACE cant WITH 1, pret_val WITH 500, pretd WITH 500, pret WITH ROUND(500*5,4), ;
pret_lei WITH ROUND(500*5,4), cota_tva WITH 11
ENDIF
goObj.gridart.Refresh()
DOEVENTS FORCE
=Assert3('2-doua articole in rul_temp', RECCOUNT_ACTIVE('rul_temp'), 2)
DO HarnessStep WITH 1, 'articole (21% si 11%) adaugate'
*========================= sincronizeaza() (declanseaza sparge_document) =========================
LOCAL llEroareSync
llEroareSync = .F.
TRY
goObj.sincronizeaza()
CATCH TO loExcS
llEroareSync = .T.
DO McLog WITH 'EROARE sincronizeaza() ' + TRANSFORM(loExcS.ErrorNo) + ' [' + loExcS.Message + '] in ' + loExcS.Procedure + ':' + TRANSFORM(loExcS.LineNo)
ENDTRY
DOEVENTS FORCE
=Assert3('3-sincronizeaza() fara eroare', IIF(llEroareSync,0,1), 1)
*========================= G: discountul se sparge pe cote (baza TVA-ului) =========================
LOCAL lnCntG, lnSumGVal, lnSumG
STORE 0 TO lnCntG, lnSumGVal, lnSumG
SELECT introdc
SCAN FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND tip_rand == 'G'
lnCntG = lnCntG + 1
lnSumGVal = lnSumGVal + suma_val
lnSumG = lnSumG + suma
ENDSCAN
=Assert3('4-doua randuri G (unul pe cota)', lnCntG, 2)
=Assert3('4a-total discount valuta pastrat', lnSumGVal, 150.00)
=Assert3('4b-total discount lei pastrat', lnSumG, 750.00)
SELECT introdc
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND tip_rand == 'G' AND ptva == 21
=Assert3('5-G(21%) gasit', IIF(FOUND(),1,0), 1)
IF FOUND()
=Assert3('5a-G(21%).suma_val=100.00 (150*1000/1500)', suma_val, 100.00)
=Assert3('5b-G(21%).suma=500.00', suma, 500.00)
ELSE
pnAsserts = pnAsserts + 2
DO McLog WITH ' FAIL 5a-5b: G(21%) negasit'
ENDIF
SELECT introdc
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND tip_rand == 'G' AND ptva == 11
=Assert3('6-G(11%) gasit', IIF(FOUND(),1,0), 1)
IF FOUND()
=Assert3('6a-G(11%).suma_val=50.00 (150*500/1500)', suma_val, 50.00)
=Assert3('6b-G(11%).suma=250.00', suma, 250.00)
ELSE
pnAsserts = pnAsserts + 2
DO McLog WITH ' FAIL 6a-6b: G(11%) negasit'
ENDIF
*========================= T-uri: TVA DVI in RON, protejat, spart pe cote =========================
SELECT introdc
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND tip_rand == 'T' AND ptva == 21
=Assert3('7-T(21%) gasit', IIF(FOUND(),1,0), 1)
IF FOUND()
=Assert3('8-T(21%).suma=945.00 (1192.50*210/265)', suma, 945.00)
=Assert3('8a-T(21%).suma_val=0 (TVA DVI in RON)', suma_val, 0)
=Assert3('8b-T(21%) ramane rand DVI protejat', NVL(rand_dvi,0)+NVL(valuta_proprie,0), 2)
=Assert3('9-T(21%) partener vamal', NVL(id_partc,0), 901)
ELSE
pnAsserts = pnAsserts + 2
DO McLog WITH ' FAIL 8-9: T(21%) negasit'
ENDIF
SELECT introdc
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND tip_rand == 'T' AND ptva == 11
=Assert3('10-T(11%) gasit', IIF(FOUND(),1,0), 1)
IF FOUND()
=Assert3('11-T(11%).suma=247.50 (1192.50*55/265)', suma, 247.50)
=Assert3('11a-T(11%).suma_val=0 (TVA DVI in RON)', suma_val, 0)
=Assert3('12-T(11%) ramane rand DVI protejat', NVL(rand_dvi,0)+NVL(valuta_proprie,0), 2)
ELSE
pnAsserts = pnAsserts + 2
DO McLog WITH ' FAIL 11-12: T(11%) negasit'
ENDIF
LOCAL lnCntT, lnSumTVal, lnSumT
STORE 0 TO lnCntT, lnSumTVal, lnSumT
SELECT introdc
SCAN FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND tip_rand == 'T'
lnCntT = lnCntT + 1
lnSumTVal = lnSumTVal + suma_val
lnSumT = lnSumT + suma
ENDSCAN
=Assert3('13-exact 2 randuri T (o cota fiecare)', lnCntT, 2)
=Assert3('14-suma T-urilor (valuta) = 0 (DVI in RON)', lnSumTVal, 0)
=Assert3('15-suma T-urilor (lei) = 1192.50 (totalul tastat pe DVI)', lnSumT, 1192.50)
*========================= S: cota randului de baza = cota articolelor lui =========================
LOCAL lnCntS
lnCntS = 0
SELECT introdc
SCAN FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND tip_rand == 'S'
lnCntS = lnCntS + 1
ENDSCAN
=Assert3('16-doua randuri S', lnCntS, 2)
SELECT introdc
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND tip_rand == 'S' AND ptva == 21
=Assert3('17-S cu cota 21 (articolul de 1000)', IIF(FOUND(),1,0), 1)
IF FOUND()
=Assert3('17a-S(21%).suma_val=1000.00', suma_val, 1000.00)
ELSE
pnAsserts = pnAsserts + 1
DO McLog WITH ' FAIL 17a: S(21%) negasit'
ENDIF
SELECT introdc
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND tip_rand == 'S' AND ptva == 11
=Assert3('18-S cu cota 11 (articolul de 500)', IIF(FOUND(),1,0), 1)
IF FOUND()
=Assert3('18a-S(11%).suma_val=500.00', suma_val, 500.00)
ELSE
pnAsserts = pnAsserts + 1
DO McLog WITH ' FAIL 18a: S(11%) negasit'
ENDIF
DO HarnessStep WITH 2, 'T-uri DVI multicota verificate - suma val=' + TRANSFORM(lnSumTVal) + ' lei=' + TRANSFORM(lnSumT)
DO McLog WITH 'REZULTAT: ' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' assert-uri PASS'
IF pnPass = pnAsserts
DO McLog WITH 'REZULTAT: PASS (' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ')'
ELSE
DO McLog WITH 'REZULTAT: FAIL (' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' assert-uri PASS)'
ENDIF
DO HarnessStep WITH 3, 'final: ' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' PASS'
DO HarnessDone WITH 'done'
CATCH TO loExc
DO McLog WITH 'CATCH ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']'
DO HarnessDone WITH 'done-error'
ENDTRY
QUIT
*==================================================================================
PROCEDURE CreeazaRulTemp
IF USED('rul_temp')
USE IN ('rul_temp')
ENDIF
CREATE CURSOR rul_temp ( ;
id_rul N(20,0), an N(4,0), luna N(2,0), cod N(20,0);
, serie C(100), nnir N(20,0), id_articol N(10,0), denumire C(100);
, codmat C(50), codmatf C(50), codbare C(50), um C(20);
, id_gestiune N(5,0), nume_gestiune C(50), cgest C(20), nr_pag N(2,0);
, gestionar C(50), comisie_receptie1 C(50), comisie_receptie2 C(50), comisie_receptie3 C(50);
, cant N(14,3), cante N(14,3), cont C(10), acont C(20);
, pret N(18,4), tva N(18,4), valoare N(18,4), valtva N(18,4);
, proc_tva N(5,2), pretv N(18,4), pretvtva N(18,4), tvav N(18,4);
, valoarev N(18,4), valtvav N(18,4), proc_tvav N(5,2), adaos N(18,4);
, adaos_tva N(18,4), valoare_adaos N(18,4), valtva_adaos N(18,4), procent N(10,3);
, discunitar N(18,4), discount_tva N(18,4), valoare_discount N(18,4), valtva_discount N(18,4);
, proc_disc N(7,3), pretd N(14,4), curs N(18,4), id_valuta N(10,0);
, nume_val C(20), id_lucrare N(20,0), nrord C(100), id_responsabil N(10,0);
, nresp C(100), resp_marca N(18,4), dataact T, id_util N(5,0);
, util C(30), dataora T, id_sectie N(5,0), sectie C(50);
, csectie C(10), alcooltutun N(1,0), datain T, dataout T;
, id_fact N(20,0), id_gestiunec N(10,0), nume_gestiunec C(50), cgestc C(20);
, id_responsabilc N(5,0), id_reteta N(10,0), reteta C(50), nrespc C(100);
, respc_marca N(18,4), id_set N(20,0), id_tip_rulaj N(10,0), tip_rulaj C(50);
, id_obiect_depozit N(10,0), id_rul_aux N(10,0), nract N(20,0), serie_act C(10);
, dataoras T, id_utils N(10,0), lot C(30), adata_expirare T;
, id_sucursala N(5,0), sucursala C(250), id_part_rez N(10,0), part_rez C(100);
, id_lucrare_rez N(10,0), nrord_rez C(100), subgrupa C(100), grupa C(100);
, id_subgrupa N(5,0), id_grupa N(5,0), in_stoc N(1,0), in_crm N(1,0);
, id_furnizor N(10,0), furnizor C(100), id_jtva_coloana N(4,0), explicatie_tva C(100);
, taxcode N(6,0), taxname C(254), saft_procent N(18,4), codnc8 C(20);
, id_tara_origine N(4,0), cod_tara_origine C(5), tara_origine C(50), greutate N(12,4);
, fdoc C(30), id_fdoc N(18,4);
, pret_lei N(18,4), pret_val N(14,4), cota_tva N(6,2))
ENDPROC
PROCEDURE CreeazaIntrodc
LPARAMETERS tcAlias
IF USED(tcAlias)
USE IN (tcAlias)
ENDIF
CREATE CURSOR (tcAlias) ( ;
id_note N(14), explicatia C(100), scd C(10), ascd C(20), scc C(10), ascc C(20), ;
cu_tva N(1), id_set N(14), ordine N(8), in_valuta N(1), id_jtva_coloana N(14) NULL, ;
ptva N(6,2), explicatie_tva C(50), tipjurnal C(2), taxcode N(6), paymentcode C(9), ;
suma N(18,4), suma_val N(18,4), id_partd N(14), id_partc N(14), partd C(100), partc C(100), ;
id_fact N(14), id_factd N(14), id_factc N(14), pereched N(14), perechec N(14), ;
nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), expl_manual N(1), ;
scd_orig C(20), ascd_orig C(20), rand_dvi N(1), valuta_proprie N(1))
ENDPROC
FUNCTION RECCOUNT_ACTIVE
LPARAMETERS tcAlias
LOCAL lnSel, lnCnt
lnSel = SELECT()
SELECT (tcAlias)
COUNT TO lnCnt FOR !DELETED()
SELECT (lnSel)
RETURN lnCnt
ENDFUNC
PROCEDURE Assert3
LPARAMETERS tcLabel, tuActual, tuExpected
pnAsserts = pnAsserts + 1
IF ABS(NVL(tuActual,0) - tuExpected) < 0.02
pnPass = pnPass + 1
DO McLog WITH ' PASS ' + tcLabel + ' (=' + TRANSFORM(tuActual) + ')'
ELSE
DO McLog WITH ' FAIL ' + tcLabel + ' (actual=' + TRANSFORM(tuActual) + ' asteptat=' + TRANSFORM(tuExpected) + ')'
ENDIF
ENDPROC
PROCEDURE McErr
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
DO McLog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
ENDPROC
PROCEDURE McLog
LPARAMETERS tcMsg
SET SAFETY OFF
LOCAL lcL
lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '')
STRTOFILE(lcL + tcMsg + CHR(13)+CHR(10), gcUILog)
ENDPROC
DEFINE CLASS dummyapp AS Custom
PROCEDURE ReadIni
LPARAMETERS tcSection, tcKey
RETURN ''
ENDPROC
PROCEDURE WriteIni
LPARAMETERS tcSection, tcKey, tcValue
RETURN .T.
ENDPROC
ENDDEFINE
DEFINE CLASS dummyexecutor AS Custom
cEroare = ''
PROCEDURE oExecute
LPARAMETERS tcSql, tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF 'VJTVA_COLOANE' $ UPPER(m.tcSql)
DO CreeazaJtvaColoaneView WITH m.tcCursor
RETURN 1
ENDIF
IF UPPER(ALLTRIM(m.tcCursor)) == 'RUL_TEMP'
CREATE CURSOR (m.tcCursor) (denumire C(100), codmat C(30), cant N(14,3), ;
pret_val N(18,4), pretd N(18,4), pret N(18,4), pret_lei N(18,4), cont C(10), ;
acont C(20), serie C(30), lot C(30), adata_expirare C(10), proc_disc N(6,2), cota_tva N(6,2))
RETURN 1
ENDIF
IF 'CONFIG_ANALITICE' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (camp_leg_prefix C(30), camp_leg_sufix C(30))
INSERT INTO (m.tcCursor) VALUES ('', '')
RETURN 1
ENDIF
IF 'FCONTURI_ANALITICE' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (acont C(20))
INSERT INTO (m.tcCursor) VALUES (IIF(TYPE('gcMockAcontCrt') = 'C', gcMockAcontCrt, ''))
RETURN 1
ENDIF
IF 'VPLCONT_ANALITIC' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (cont C(10), acont C(20))
RETURN 1
ENDIF
IF 'VCONFIG_CONT_IREG' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (contpart C(10), fel_cont N(1), cu_inregistrari N(1), ;
explic_cont C(100), exceptie C(10), pozitie N(1), invers N(1), gasit N(1))
INSERT INTO (m.tcCursor) VALUES ('401', 0, 0, 'Furnizori', '', 0, 0, 0)
RETURN 1
ENDIF
CREATE CURSOR (m.tcCursor) (id_temp N(1))
RETURN 1
ENDPROC
PROCEDURE oExecuta
LPARAMETERS tcSql, tcCursor
IF !EMPTY(m.tcCursor)
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF UPPER(m.tcCursor) == 'CJTVACOL4427'
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14))
ELSE
CREATE CURSOR (m.tcCursor) (id_temp N(1))
ENDIF
ENDIF
RETURN .T.
ENDPROC
PROCEDURE oSelect2Value
LPARAMETERS tcSql, toValue
toValue = ''
RETURN 1
ENDPROC
PROCEDURE oReset
ENDPROC
ENDDEFINE
PROCEDURE CreeazaJtvaColoaneView
LPARAMETERS tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14), denumire C(100), jc N(1), jv N(1), ;
coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14) NULL, afisat N(1), ;
id_jtva_ex N(14) NULL, id_jtva_neex N(14) NULL, ordine N(8), ;
taxcode N(6) NULL, taxcode_neexigibil N(6) NULL, taxcode_n50 N(6) NULL, ;
taxcode_n50_tvai N(6) NULL, taxcode_n100 N(6) NULL, taxcode_regularizare N(6) NULL, taxcode_tvai N(6) NULL)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, afisat, ordine, cota_tva) VALUES (0, '', 0, 0, 1, 0, 0)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (220, 'ACH. IMP. 21%', 1, 0, 'FO21B', 21, 221, 1, 1, 301204)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (221, 'TVA ACH. IMP. 21%', 1, 0, 'FO21T', 21, 1, 2, 301204)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (222, 'ACH. IMP. 11%', 1, 0, 'FO11B', 11, 223, 1, 3, 301205)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (223, 'TVA ACH. IMP. 11%', 1, 0, 'FO11T', 11, 1, 4, 301205)
ENDPROC

View File

@@ -0,0 +1,12 @@
# test_dvi_multicota.ps1 - wrapper peste harness-ul generic pentru TVA-ul pe DVI + discountul financiar
# distribuite pe doua cote TVA (21%/11%).
# powershell -ExecutionPolicy Bypass -File test_dvi_multicota.ps1
$ErrorActionPreference = 'Stop'
$Teste = $PSScriptRoot
& (Join-Path (Split-Path $Teste -Parent) 'vfp_ui_harness.ps1') `
-TestPrg (Join-Path $Teste 'test_dvi_multicota.prg') `
-Steps @('factura_creata','articole_adaugate','sincronizare','final') `
-ShotsDir (Join-Path $Teste 'screenshots_dvi_multicota') `
-SyncDir (Join-Path $Teste 'uisync_dvi_multicota') `
-StepTimeoutSec 180 `
-ReadyTimeoutSec 180

View File

@@ -0,0 +1,648 @@
* test_dvi_tva_manual.prg
* Runda30 (F1, plan fizzy-imagining-parnas.md): TVA DVI editat MANUAL in dialog (valoare
* diferita de baza*cota) trebuie sa supravietuiasca do_executa()/sincronizeaza() - motorul
* trebuie sa marcheze randul T rezultat cu mod_manual=1 (semantica EXISTENTA, refolosita - vezi
* garda deja prezenta in do_executa: "If Nvl(mod_manual,0) <> 1"), nu sa rescrie suma la
* fiecare recalculare.
* Verifica:
* - DOC1 (TVA DVI manual, 1200.00 <> 1098.30 auto): randul T are mod_manual=1 si suma=1200.00,
* verificat pe CURSORUL introdc (nu doar pe proprietatea din dialog), supravietuieste
* do_executa() si sincronizeaza();
* - DOC2 (control, TVA DVI = baza*cota, 1098.30 exact): randul T are mod_manual=0 (nu orice
* rand DVI devine automat manual - doar cel cu valoare divergenta).
*
* ASUMPTIE (de confruntat cu implementarea reala): mod_manual se determina prin COMPARAREA
* toDlg.dvi_tva_lei cu baza*cota (nu printr-un flag suplimentar de dirty in toDlg) - vezi
* text plan sectiunea "F1 - modificari", do_adauga_factura.
*
* Rulare:
* powershell -ExecutionPolicy Bypass -File test_dvi_tva_manual.ps1
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET DECIMALS TO 4
SET NULLDISPLAY TO ''
CLOSE DATABASES
PUBLIC gcUILog, gcSyncDir
gcUILog = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\test_dvi_tva_manual_log.txt"
gcSyncDir = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\uisync_dvi_tva_manual\"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcUILog)
ON ERROR DO DcErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
TRY
LOCAL gcAppPath, lcPath
gcAppPath = "D:\ROA\ROAGEST\"
SET DEFAULT TO (gcAppPath)
lcPath = gcAppPath + 'Date;' + gcAppPath + 'Include;' + gcAppPath + 'FERESTRE;' + ;
gcAppPath + 'GRAFICE;' + gcAppPath + 'CLASE;' + gcAppPath + 'MENIURI;' + ;
gcAppPath + 'PROGRAME;' + gcAppPath + 'RAPOARTE;' + gcAppPath + 'COMUN;' + ;
gcAppPath + 'COMUN\CLASE;' + gcAppPath + 'COMUN\FERESTRE;' + gcAppPath + 'COMUN\PROGRAME;' + ;
gcAppPath + 'COMUN\GRAFICE;' + gcAppPath + 'COMUN\RAPOARTE;' + gcAppPath + 'COMUN\MENIURI;' + ;
gcAppPath + 'COMUN\UTILE\GRIDEXTRAS;' + gcAppPath + 'COMUN\UTILE\CTL32;' + ;
gcAppPath + 'COMUN\UTILE\HPDF;' + gcAppPath + 'COMUN\UTILE\HPDF\REPORTOUTPUT;' + ;
gcAppPath + 'COMUN\UTILE\WEB;' + gcAppPath + 'COMUN\UTILE\EXCEL;' + ;
ADDBS(SUBSTR(gcAppPath,1,RAT([\],gcAppPath,2)))+[COMUNROA\]
SET PATH TO &lcPath ADDITIVE
DO DcLog WITH 'SET PATH OK'
*----- CLASE -----
SET CLASSLIB TO (gcAppPath + "comun\clase\appwiz") ADDITIVE
SET CLASSLIB TO GESTIUNI ADDITIVE
SET CLASSLIB TO CAUT ADDITIVE
SET CLASSLIB TO BAZA ADDITIVE
SET CLASSLIB TO comun ADDITIVE
SET CLASSLIB TO accessibility.vcx ADDITIVE
SET CLASSLIB TO messagebox ADDITIVE
SET CLASSLIB TO registry ADDITIVE
SET CLASSLIB TO cauta_alfa_forms.vcx ADDITIVE
SET CLASSLIB TO DECABAZA ADDITIVE
SET CLASSLIB TO onomenclatoare ADDITIVE
SET CLASSLIB TO stocuri.vcx ADDITIVE
SET CLASSLIB TO rulaje.vcx ADDITIVE
SET CLASSLIB TO ointroduceri ADDITIVE
SET CLASSLIB TO ointroduceri_web ADDITIVE
SET CLASSLIB TO ointroduceri_depozit ADDITIVE
SET CLASSLIB TO overificari ADDITIVE
SET CLASSLIB TO ferestre_oracle ADDITIVE
SET CLASSLIB TO ferestre_cere_date.vcx ADDITIVE
SET CLASSLIB TO configurare.vcx ADDITIVE
SET CLASSLIB TO serii_numere.vcx ADDITIVE
SET CLASSLIB TO omodificari.vcx ADDITIVE
SET CLASSLIB TO ocompensari.vcx ADDITIVE
SET CLASSLIB TO caut_ora ADDITIVE
SET CLASSLIB TO onote_contabile ADDITIVE
SET CLASSLIB TO otoolbar ADDITIVE
SET CLASSLIB TO bon_fisc ADDITIVE
SET CLASSLIB TO onom_articole ADDITIVE
SET CLASSLIB TO onom_retete ADDITIVE
SET CLASSLIB TO orapoarte ADDITIVE
SET CLASSLIB TO orapoarte_gestiuni ADDITIVE
SET CLASSLIB TO orapoarte_parametri ADDITIVE
SET CLASSLIB TO ONOM_CURS ADDITIVE
SET CLASSLIB TO ctl32_statusbar_fals.vcx ADDITIVE
SET CLASSLIB TO ctl32_common.vcx ADDITIVE
SET CLASSLIB TO ctl32_structs.vcx ADDITIVE
SET CLASSLIB TO ctl32_progressbar.vcx ADDITIVE
SET CLASSLIB TO ctl32_balloontip.vcx ADDITIVE
SET CLASSLIB TO ocriterii.vcx ADDITIVE
SET CLASSLIB TO oavize.vcx ADDITIVE
SET CLASSLIB TO onomenclatoare2 ADDITIVE
SET CLASSLIB TO wwdialogs.vcx ADDITIVE
SET CLASSLIB TO oimportxml.vcx ADDITIVE
SET CLASSLIB TO excelxml.vcx ADDITIVE
SET CLASSLIB TO orapoarte_obinv.vcx ADDITIVE
DO DcLog WITH 'SET CLASSLIB OK'
*----- PROCEDURI (mock-uri PRIMELE, ui_harness la final) -----
SET PROCEDURE TO PROCEDURI
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_cauta_nom_articole.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\mock_caut_valuta.prg" ADDITIVE
SET PROCEDURE TO acces_meniu ADDITIVE
SET PROCEDURE TO cauta_alfa ADDITIVE
SET PROCEDURE TO pmenu ADDITIVE
SET PROCEDURE TO proceduri_comune ADDITIVE
SET PROCEDURE TO quitapp ADDITIVE
SET PROCEDURE TO init_program ADDITIVE
SET PROCEDURE TO oproceduri_listari.prg ADDITIVE
SET PROCEDURE TO oproceduri_configurare.prg ADDITIVE
SET PROCEDURE TO oproceduri_articole.prg ADDITIVE
SET PROCEDURE TO oproceduri_retete.prg ADDITIVE
SET PROCEDURE TO orapoarte.prg ADDITIVE
SET PROCEDURE TO mesaje ADDITIVE
SET PROCEDURE TO oserii_numere.prg ADDITIVE
SET PROCEDURE TO oexport.prg ADDITIVE
SET PROCEDURE TO wwConfig.prg ADDITIVE
SET PROCEDURE TO proceduri_rapoarte.prg ADDITIVE
SET PROCEDURE TO OPROCEDURI_CURS.PRG ADDITIVE
SET PROCEDURE TO validare.prg ADDITIVE
SET PROCEDURE TO GENCURSOR.PRG ADDITIVE
SET PROCEDURE TO OPROCEDURI_COMUNE.PRG ADDITIVE
SET PROCEDURE TO OINIT_OPTIUNI.PRG ADDITIVE
SET PROCEDURE TO updateserver.prg ADDITIVE
SET PROCEDURE TO oinainte_de.prg ADDITIVE
SET PROCEDURE TO ooperatii_comune.prg ADDITIVE
SET PROCEDURE TO Ocompensari.PRG ADDITIVE
SET PROCEDURE TO OPROCEDURI_aMS.PRG ADDITIVE
SET PROCEDURE TO oproceduri_rulaje ADDITIVE
SET PROCEDURE TO oproceduri_stocuri ADDITIVE
SET PROCEDURE TO OINTRODUCERI ADDITIVE
SET PROCEDURE TO oHeader.prg ADDITIVE
SET PROCEDURE TO proceduri_excel.PRG ADDITIVE
SET PROCEDURE TO onomenclatoare.PRG ADDITIVE
SET PROCEDURE TO osecurity ADDITIVE
SET PROCEDURE TO ocautare ADDITIVE
SET PROCEDURE TO orefaceri ADDITIVE
SET PROCEDURE TO ofacturare_comun.PRG ADDITIVE
SET PROCEDURE TO ofacturare_stoc.PRG ADDITIVE
SET PROCEDURE TO oproceduri_casademarcat ADDITIVE
SET PROCEDURE TO oproceduri_casa_marcat_e500 ADDITIVE
SET PROCEDURE TO oproceduri_casa_marcat_mp500 ADDITIVE
SET PROCEDURE TO oproceduri_util.prg ADDITIVE
SET PROCEDURE TO wwxmlhttp.prg ADDITIVE
SET PROCEDURE TO ini.prg ADDITIVE
SET PROCEDURE TO odocumente.prg ADDITIVE
SET PROCEDURE TO regex.prg ADDITIVE
SET PROCEDURE TO wwutils.prg ADDITIVE
SET PROCEDURE TO inchidere_k ADDITIVE
SET PROCEDURE TO iniacces.prg ADDITIVE
SET PROCEDURE TO oupdate.prg ADDITIVE
SET PROCEDURE TO procese.prg ADDITIVE
SET PROCEDURE TO version.prg ADDITIVE
SET PROCEDURE TO xmlaccess.prg ADDITIVE
SET PROCEDURE TO xmlparser.prg ADDITIVE
SET PROCEDURE TO filebringer.prg ADDITIVE
SET PROCEDURE TO wwcodeupdate.prg ADDITIVE
SET PROCEDURE TO wwhttp.prg ADDITIVE
SET PROCEDURE TO xdate.prg ADDITIVE
SET PROCEDURE TO ofacturare.prg ADDITIVE
SET PROCEDURE TO oproceduri_obinv.prg ADDITIVE
SET PROCEDURE TO oproceduri_facturare.prg ADDITIVE
SET PROCEDURE TO email.prg ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\ui_harness.prg" ADDITIVE
DO DcLog WITH 'SET PROCEDURE OK'
PUBLIC goMockValuta
goMockValuta = CREATEOBJECT('Custom')
goMockValuta.AddProperty('id_valuta', 978)
goMockValuta.AddProperty('nume_val', 'EUR')
*----- Globale -----
PUBLIC gnPc, gnPval, gnPcant, gnPpret, gnPPretval, gnPCurs, gnPVal, gnPPretV, gnPPretVal
STORE 2 TO gnPc, gnPval, gnPVal
gnPcant = 3
STORE 4 TO gnPpret, gnPPretval, gnPPretVal, gnPPretV, gnPCurs
PUBLIC gl406, gcS, gnAn, gnLuna, gnIdFirma, gnIdSucursala, gcAcces, gcFirma
gl406 = .T.
gcS = 'CONTAFIN'
gnAn = YEAR(DATE())
gnLuna = MONTH(DATE())
gnIdFirma = 110
gnIdSucursala = 110
gcAcces = "1;2;3;4;5;6;7;8;"
gcFirma = gcS
PUBLIC nror(65000)
PUBLIC gnButon
STORE 2 TO gnButon
PUBLIC gcMockArtCodmat, gcMockAcontCrt
gcMockArtCodmat = ''
gcMockAcontCrt = ''
PUBLIC gnMockRaspuns
gnMockRaspuns = 6
PUBLIC goExecutor, goApp
goExecutor = CREATEOBJECT('dummyexecutor')
goApp = CREATEOBJECT('dummyapp')
*----- poAct: antetul notei (moneda principala EUR, curs 5.23) -----
PUBLIC poAct
poAct = CREATEOBJECT('Custom')
poAct.AddProperty('nume_val', 'EUR')
poAct.AddProperty('curs', 5.23)
poAct.AddProperty('proc_tva', 1.21)
poAct.AddProperty('nnir', 0)
poAct.AddProperty('id_valuta', 978)
poAct.AddProperty('id_fdoc', 1)
poAct.AddProperty('fdoc', 'Factura')
poAct.AddProperty('id_partc', 601)
poAct.AddProperty('partc', 'RAJA')
poAct.AddProperty('serie_act', '')
poAct.AddProperty('dataact', DATE())
poAct.AddProperty('tva_incasare', 0)
poAct.AddProperty('id_set', 1)
poAct.AddProperty('id_gestin', 1)
*----- jtva_coloane2 / saft_taxtable: perechi reale 21% -----
IF USED('jtva_coloane2')
USE IN ('jtva_coloane2')
ENDIF
CREATE CURSOR jtva_coloane2 (ordine N(8), id_jtva_coloana N(14), denumire C(100), ;
jc N(1), jv N(1), afisat N(1), coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14))
INSERT INTO jtva_coloane2 VALUES (0, 0, '', 0, 0, 1, '', '', 0, 0)
INSERT INTO jtva_coloane2 VALUES (1, 208, 'ACH. INT. 21%', 1, 0, 1, 'RO21B', 'RO21T', 21, 209)
INSERT INTO jtva_coloane2 VALUES (2, 209, 'TVA ACH. INT. 21%', 1, 0, 1, 'RO21T', '', 21, 0)
INSERT INTO jtva_coloane2 VALUES (3, 220, 'ACH. IMP. 21%', 1, 0, 1, 'FO21B', 'FO21T', 21, 221)
INSERT INTO jtva_coloane2 VALUES (4, 221, 'TVA ACH. IMP. 21%', 1, 0, 1, 'FO21T', '', 21, 0)
IF USED('saft_taxtable')
USE IN ('saft_taxtable')
ENDIF
CREATE CURSOR saft_taxtable (taxname C(250) NULL, typename C(250) NULL, taxcode N(6) NULL, ;
taxtype N(3) NULL, descriere C(250) NULL, tip C(100) NULL, descriere_tip C(250) NULL, ;
procent_taxa N(7,2) NULL, procent_prorata N(7,2) NULL, inactiv N(1) NULL, tva N(1) NULL, ;
wht N(1) NULL, tva_achizitii N(1) NULL, tva_livrari N(1) NULL)
INDEX ON taxcode TAG taxcode
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('', 0, '', 0, 1, 1, 1, 1)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301204-Import de bunuri cota 21%', 301204, '', 21, 1, 0, 1, 0)
DO CreeazaIntrodc WITH 'introdc'
DO CreeazaIntrodc WITH 'introdc_sablon'
INSERT INTO introdc_sablon (scd, scc, cu_tva, ordine, id_set, participa_valuta, tip_rand, ;
id_jtva_coloana, ptva, explicatie_tva) ;
VALUES ('371', '401', 1, 1, 1, .T., 'B', 208, 21, 'ACH. INT. 21%')
INSERT INTO introdc_sablon (scd, scc, cu_tva, ordine, id_set, participa_valuta, tip_rand, ;
id_jtva_coloana, ptva, explicatie_tva) ;
VALUES ('4426', '401', 1, 2, 1, .T., 'T', 209, 21, 'TVA ACH. INT. 21%')
GO TOP IN introdc_sablon
DO CreeazaRulTemp
INSERT INTO rul_temp (denumire, codmat, cant, pret, pret_lei, cont, cota_tva) ;
VALUES ('PLACEHOLDER', 'PH', 1, 1, 1, '371', 21)
SELECT introdc
INDEX ON Str(Nvl(nr_doc,0),8) + Icase(tip_rand='B','1', tip_rand='S','2', tip_rand='G','3', tip_rand='T','4', tip_rand='D','5', '6') + Padr(Nvl(scd,''),10) TAG ord_doc
SET ORDER TO ord_doc
DO DcLog WITH 'cursoare pregatite, CREATEOBJECT(import_nota, .F.)'
PUBLIC goObj
goObj = CREATEOBJECT('IMPORT_nota', .F.)
IF VARTYPE(goObj) <> 'O'
DO DcLog WITH 'FAIL: instantiere import_nota'
DO HarnessDone WITH 'done-error'
QUIT
ENDIF
goObj.lDialogAratat = .T.
goObj.oact = poAct
goObj.lSpargeSecundare = .F.
goObj.WindowType = 0
goObj.Visible = .T.
goObj.Show()
goObj.WindowState = 2
DOEVENTS FORCE
SELECT rul_temp
ZAP
goObj.gridart.Refresh()
DOEVENTS FORCE
PRIVATE pnAsserts, pnPass
STORE 0 TO pnAsserts, pnPass
*========================= DOC1: TVA DVI MANUAL (1200.00, diferit de auto 1098.30) =========================
PUBLIC goDlg, goT
DO AdaugaDoc WITH 15000, 'RAJA', 601, 1200.00
DO HarnessStep WITH 0, 'dupa DOC1 (manual): introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri'
SELECT introdc
LOCATE FOR nract = 15086 AND Nvl(rand_dvi,0) = 1
=Assert3('1-DOC1: rand T-DVI gasit', IIF(FOUND(),1,0), 1)
IF FOUND()
DO DcLog WITH 'DOC1 T-DVI: suma=' + TRANSFORM(suma) + ' mod_manual=' + TRANSFORM(NVL(mod_manual,0))
=Assert3('2-DOC1: T-DVI.suma=1200.00 (valoare manuala, NU 1098.30 auto)', suma, 1200.00)
=Assert3('3-DOC1: T-DVI.mod_manual=1 (dirty, valoare difera de baza*cota)', NVL(mod_manual,0), 1)
ELSE
pnAsserts = pnAsserts + 2
DO DcLog WITH ' FAIL 2-3: T-DVI DOC1 negasit'
ENDIF
*-- garda do_executa (existenta - reutilizata prin mod_manual=1)
goObj.do_executa()
DOEVENTS FORCE
SELECT introdc
LOCATE FOR nract = 15086 AND Nvl(rand_dvi,0) = 1
=Assert3('4-DOC1: dupa do_executa() suma ramane 1200.00', IIF(FOUND(),suma,-1), 1200.00)
*-- sincronizare completa
LOCAL llEroareSync1
llEroareSync1 = .F.
TRY
goObj.sincronizeaza()
CATCH TO loExcS1
llEroareSync1 = .T.
DO DcLog WITH 'EROARE la sincronizeaza() DOC1 ' + TRANSFORM(loExcS1.ErrorNo) + ' [' + loExcS1.Message + ']'
ENDTRY
DOEVENTS FORCE
=Assert3('5-DOC1: sincronizeaza() fara eroare', IIF(llEroareSync1,0,1), 1)
SELECT introdc
LOCATE FOR nract = 15086 AND Nvl(rand_dvi,0) = 1
=Assert3('6-DOC1: dupa sincronizeaza() suma ramane 1200.00', IIF(FOUND(),suma,-1), 1200.00)
IF FOUND()
=Assert3('7-DOC1: dupa sincronizeaza() mod_manual ramane 1', NVL(mod_manual,0), 1)
ELSE
pnAsserts = pnAsserts + 1
ENDIF
DO HarnessStep WITH 1, 'DOC1 (TVA DVI manual) verificat - vezi log'
*========================= DOC2 (CONTROL): TVA DVI = baza*cota EXACT (1098.30) =========================
DO AdaugaDoc WITH 15001, 'TRANS OIL', 602, 1098.30
DO HarnessStep WITH 2, 'dupa DOC2 (control): introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri'
SELECT introdc
LOCATE FOR nract = 15087 AND Nvl(rand_dvi,0) = 1
=Assert3('8-DOC2: rand T-DVI gasit', IIF(FOUND(),1,0), 1)
IF FOUND()
DO DcLog WITH 'DOC2 T-DVI: suma=' + TRANSFORM(suma) + ' mod_manual=' + TRANSFORM(NVL(mod_manual,0))
=Assert3('9-DOC2: T-DVI.suma=1098.30 (auto, coincide cu baza*cota)', suma, 1098.30)
=Assert3('10-DOC2: T-DVI.mod_manual=0 (nu e marcat manual - valoarea coincide cu auto-calc)', NVL(mod_manual,0), 0)
ELSE
pnAsserts = pnAsserts + 2
DO DcLog WITH ' FAIL 9-10: T-DVI DOC2 negasit'
ENDIF
DO HarnessStep WITH 3, 'DOC2 (control, TVA auto) verificat - vezi log'
DO DcLog WITH 'REZULTAT: ' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' assert-uri PASS'
IF pnPass = pnAsserts
DO DcLog WITH 'REZULTAT: PASS (' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ')'
ELSE
DO DcLog WITH 'REZULTAT: FAIL (' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' assert-uri PASS)'
ENDIF
DO HarnessStep WITH 4, 'final: ' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' PASS'
DO HarnessDone WITH 'done'
CATCH TO loExc
DO DcLog WITH 'CATCH ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']'
DO HarnessDone WITH 'done-error'
ENDTRY
QUIT
*==================================================================================
PROCEDURE AdaugaDoc
*-- FACTURA EUR curs 5.23, 1000 EUR (5230 lei), TVA pe DVI cu valuta facturii (fara
*-- valuta_proprie - acest test tinteste STRICT supravietuirea valorii manuale, nu
*-- independenta valutara, acoperita in celelalte 2 fisiere de test).
LPARAMETERS tnNract, tcPartener, tnIdPartener, tnDviTvaLei
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = tnNract
goDlg.dDataAct = DATE()
goDlg.nIdPartener = tnIdPartener
goDlg.cPartener = tcPartener
goDlg.cExplicatia = 'Import marfa ' + tcPartener
goDlg.nSuma = 1000
goDlg.nSumaLei = 0
goDlg.nCurs = 5.23
goDlg.nIdValuta = 978
goDlg.cValuta = 'EUR'
goDlg.nIdExplicatieTva = 220
goDlg.cExplicatieTva = 'ACH. IMP. 21%'
goDlg.optTipTva.Value = 2 && D = DVI
goDlg.chkInValutaCont.Value = 1
goDlg.chkParticipaValuta.Value = 1
goDlg.cSerieDvi = ''
goDlg.nNractDvi = tnNract + 86
goDlg.dDviData = DATE()
goDlg.nIdFdocDVI = 2
goDlg.cFelDocDvi = 'DVI'
goDlg.nDviIdPartener = 900
goDlg.cDviPartener = 'BIROUL VAMAL'
goDlg.nDviTvaLei = tnDviTvaLei
goDlg.nDviTvaVal = ROUND(tnDviTvaLei/5.23,4)
*-- DVI cu valuta facturii (EUR) - fara valuta_proprie, ca sa izoleze testul pe mod_manual
goDlg.nDviIdValuta = 978
goDlg.cDviValuta = 'EUR'
goDlg.nDviCurs = 5.23
goDlg.actualizeaza_stare_dvi()
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO DcLog WITH 'DOC ' + TRANSFORM(tnNract) + ': valideaza = ' + TRANSFORM(goDlg.valideaza())
DO ConstruiesteToDlgF1F2
DO DcLog WITH 'DOC ' + TRANSFORM(tnNract) + ': do_adauga_factura = ' + TRANSFORM(goObj.do_adauga_factura(goT))
goDlg.Hide()
DOEVENTS FORCE
ENDPROC
PROCEDURE ConstruiesteToDlgF1F2
goT = CREATEOBJECT('Empty')
=ADDPROPERTY(goT,'serie_act',ALLTRIM(NVL(goDlg.cSerieAct,'')))
=ADDPROPERTY(goT,'nract',goDlg.nNract)
=ADDPROPERTY(goT,'dataact',goDlg.dDataAct)
=ADDPROPERTY(goT,'fdoc',goDlg.cFelDoc)
=ADDPROPERTY(goT,'id_fdoc',goDlg.nIdFdoc)
=ADDPROPERTY(goT,'id_partc',goDlg.nIdPartener)
=ADDPROPERTY(goT,'partc',goDlg.cPartener)
=ADDPROPERTY(goT,'explicatia',ALLTRIM(NVL(goDlg.cExplicatia,'')))
=ADDPROPERTY(goT,'suma',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,IIF(goDlg.nSumaLei<>0,goDlg.nSumaLei,ROUND(goDlg.nSuma*goDlg.nCurs,gnPC)),goDlg.nSuma))
=ADDPROPERTY(goT,'suma_val',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,goDlg.nSuma,0))
=ADDPROPERTY(goT,'in_valuta',goDlg.chkInValutaCont.Value)
=ADDPROPERTY(goT,'participa_valuta',(goDlg.chkParticipaValuta.Value=1))
=ADDPROPERTY(goT,'id_valuta',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nIdValuta,0))
=ADDPROPERTY(goT,'curs',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nCurs,0))
=ADDPROPERTY(goT,'nume_val',IIF(goDlg.chkInValutaCont.Value=1,ALLTRIM(NVL(goDlg.cValuta,'')),''))
=ADDPROPERTY(goT,'cTipTva',IIF(goDlg.optTipTva.Value=1,'F',IIF(goDlg.optTipTva.Value=2,'D','N')))
=ADDPROPERTY(goT,'id_jtva_coloana',goDlg.nIdExplicatieTva)
=ADDPROPERTY(goT,'dvi_serie',CHRTRAN(ALLTRIM(NVL(goDlg.cSerieDvi,'')),CHR(34),''))
=ADDPROPERTY(goT,'dvi_nract',goDlg.nNractDvi)
=ADDPROPERTY(goT,'dvi_dataact',goDlg.dDviData)
=ADDPROPERTY(goT,'dvi_id_fdoc',goDlg.nIdFdocDVI)
=ADDPROPERTY(goT,'dvi_fdoc',goDlg.cFelDocDvi)
=ADDPROPERTY(goT,'dvi_id_partc',goDlg.nDviIdPartener)
=ADDPROPERTY(goT,'dvi_partc',goDlg.cDviPartener)
=ADDPROPERTY(goT,'dvi_scc','401')
=ADDPROPERTY(goT,'dvi_tva_lei',goDlg.nDviTvaLei)
=ADDPROPERTY(goT,'dvi_tva_val',goDlg.nDviTvaVal)
=ADDPROPERTY(goT,'dvi_in_valuta',!(EMPTY(goDlg.cDviValuta) OR UPPER(ALLTRIM(NVL(goDlg.cDviValuta,'')))=='RON'))
=ADDPROPERTY(goT,'dvi_id_valuta',goDlg.nDviIdValuta)
=ADDPROPERTY(goT,'dvi_curs',goDlg.nDviCurs)
=ADDPROPERTY(goT,'dvi_nume_val',ALLTRIM(NVL(goDlg.cDviValuta,'')))
=ADDPROPERTY(goT,'dvi_valuta_proprie',IIF(!(EMPTY(goDlg.cDviValuta) OR UPPER(ALLTRIM(NVL(goDlg.cDviValuta,'')))=='RON') OR !(EMPTY(goDlg.cValuta) OR UPPER(ALLTRIM(NVL(goDlg.cValuta,'')))=='RON'),IIF(goDlg.nDviIdValuta<>goDlg.nIdValuta OR goDlg.nDviCurs<>goDlg.nCurs,1,0),0))
=ADDPROPERTY(goT,'disc_baza_lei',0)
=ADDPROPERTY(goT,'disc_baza_val',0)
ENDPROC
PROCEDURE CreeazaRulTemp
IF USED('rul_temp')
USE IN ('rul_temp')
ENDIF
CREATE CURSOR rul_temp ( ;
id_rul N(20,0), an N(4,0), luna N(2,0), cod N(20,0);
, serie C(100), nnir N(20,0), id_articol N(10,0), denumire C(100);
, codmat C(50), codmatf C(50), codbare C(50), um C(20);
, id_gestiune N(5,0), nume_gestiune C(50), cgest C(20), nr_pag N(2,0);
, gestionar C(50), comisie_receptie1 C(50), comisie_receptie2 C(50), comisie_receptie3 C(50);
, cant N(14,3), cante N(14,3), cont C(10), acont C(20);
, pret N(18,4), tva N(18,4), valoare N(18,4), valtva N(18,4);
, proc_tva N(5,2), pretv N(18,4), pretvtva N(18,4), tvav N(18,4);
, valoarev N(18,4), valtvav N(18,4), proc_tvav N(5,2), adaos N(18,4);
, adaos_tva N(18,4), valoare_adaos N(18,4), valtva_adaos N(18,4), procent N(10,3);
, discunitar N(18,4), discount_tva N(18,4), valoare_discount N(18,4), valtva_discount N(18,4);
, proc_disc N(7,3), pretd N(14,4), curs N(18,4), id_valuta N(10,0);
, nume_val C(20), id_lucrare N(20,0), nrord C(100), id_responsabil N(10,0);
, nresp C(100), resp_marca N(18,4), dataact T, id_util N(5,0);
, util C(30), dataora T, id_sectie N(5,0), sectie C(50);
, csectie C(10), alcooltutun N(1,0), datain T, dataout T;
, id_fact N(20,0), id_gestiunec N(10,0), nume_gestiunec C(50), cgestc C(20);
, id_responsabilc N(5,0), id_reteta N(10,0), reteta C(50), nrespc C(100);
, respc_marca N(18,4), id_set N(20,0), id_tip_rulaj N(10,0), tip_rulaj C(50);
, id_obiect_depozit N(10,0), id_rul_aux N(10,0), nract N(20,0), serie_act C(10);
, dataoras T, id_utils N(10,0), lot C(30), adata_expirare T;
, id_sucursala N(5,0), sucursala C(250), id_part_rez N(10,0), part_rez C(100);
, id_lucrare_rez N(10,0), nrord_rez C(100), subgrupa C(100), grupa C(100);
, id_subgrupa N(5,0), id_grupa N(5,0), in_stoc N(1,0), in_crm N(1,0);
, id_furnizor N(10,0), furnizor C(100), id_jtva_coloana N(4,0), explicatie_tva C(100);
, taxcode N(6,0), taxname C(254), saft_procent N(18,4), codnc8 C(20);
, id_tara_origine N(4,0), cod_tara_origine C(5), tara_origine C(50), greutate N(12,4);
, fdoc C(30), id_fdoc N(18,4);
, pret_lei N(18,4), pret_val N(14,4), cota_tva N(6,2))
ENDPROC
PROCEDURE CreeazaIntrodc
*-- Runda30 (F1/pas2): coloane NOI rand_dvi N(1), valuta_proprie N(1) fata de structura veche.
LPARAMETERS tcAlias
IF USED(tcAlias)
USE IN (tcAlias)
ENDIF
CREATE CURSOR (tcAlias) ( ;
id_note N(14), explicatia C(100), scd C(10), ascd C(20), scc C(10), ascc C(20), ;
cu_tva N(1), id_set N(14), ordine N(8), in_valuta N(1), id_jtva_coloana N(14) NULL, ;
ptva N(6,2), explicatie_tva C(50), tipjurnal C(2), taxcode N(6), paymentcode C(9), ;
suma N(18,4), suma_val N(18,4), id_partd N(14), id_partc N(14), partd C(100), partc C(100), ;
id_fact N(14), id_factd N(14), id_factc N(14), pereched N(14), perechec N(14), ;
nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), expl_manual N(1), ;
scd_orig C(20), ascd_orig C(20), rand_dvi N(1), valuta_proprie N(1))
ENDPROC
FUNCTION RECCOUNT_ACTIVE
LPARAMETERS tcAlias
LOCAL lnSel, lnCnt
lnSel = SELECT()
SELECT (tcAlias)
COUNT TO lnCnt FOR !DELETED()
SELECT (lnSel)
RETURN lnCnt
ENDFUNC
PROCEDURE Assert3
LPARAMETERS tcLabel, tuActual, tuExpected
pnAsserts = pnAsserts + 1
IF ABS(NVL(tuActual,0) - tuExpected) < 0.02
pnPass = pnPass + 1
DO DcLog WITH ' PASS ' + tcLabel + ' (=' + TRANSFORM(tuActual) + ')'
ELSE
DO DcLog WITH ' FAIL ' + tcLabel + ' (actual=' + TRANSFORM(tuActual) + ' asteptat=' + TRANSFORM(tuExpected) + ')'
ENDIF
ENDPROC
PROCEDURE AssertStr
LPARAMETERS tcLabel, tcActual, tcExpected
pnAsserts = pnAsserts + 1
IF tcActual == tcExpected
pnPass = pnPass + 1
DO DcLog WITH ' PASS ' + tcLabel + ' (=[' + tcActual + '])'
ELSE
DO DcLog WITH ' FAIL ' + tcLabel + ' (actual=[' + tcActual + '] asteptat=[' + tcExpected + '])'
ENDIF
ENDPROC
PROCEDURE DcErr
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
DO DcLog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
ENDPROC
PROCEDURE DcLog
LPARAMETERS tcMsg
SET SAFETY OFF
LOCAL lcL
lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '')
STRTOFILE(lcL + tcMsg + CHR(13)+CHR(10), gcUILog)
ENDPROC
DEFINE CLASS dummyapp AS Custom
PROCEDURE ReadIni
LPARAMETERS tcSection, tcKey
RETURN ''
ENDPROC
PROCEDURE WriteIni
LPARAMETERS tcSection, tcKey, tcValue
RETURN .T.
ENDPROC
ENDDEFINE
DEFINE CLASS dummyexecutor AS Custom
cEroare = ''
PROCEDURE oExecute
LPARAMETERS tcSql, tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF 'VJTVA_COLOANE' $ UPPER(m.tcSql)
DO CreeazaJtvaColoaneView WITH m.tcCursor
RETURN 1
ENDIF
IF UPPER(ALLTRIM(m.tcCursor)) == 'RUL_TEMP'
CREATE CURSOR (m.tcCursor) (denumire C(100), codmat C(30), cant N(14,3), ;
pret_val N(18,4), pretd N(18,4), pret N(18,4), pret_lei N(18,4), cont C(10), ;
acont C(20), serie C(30), lot C(30), adata_expirare C(10), proc_disc N(6,2), cota_tva N(6,2))
RETURN 1
ENDIF
IF 'CONFIG_ANALITICE' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (camp_leg_prefix C(30), camp_leg_sufix C(30))
INSERT INTO (m.tcCursor) VALUES ('', '')
RETURN 1
ENDIF
IF 'FCONTURI_ANALITICE' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (acont C(20))
INSERT INTO (m.tcCursor) VALUES (IIF(TYPE('gcMockAcontCrt') = 'C', gcMockAcontCrt, ''))
RETURN 1
ENDIF
IF 'VPLCONT_ANALITIC' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (cont C(10), acont C(20))
INSERT INTO (m.tcCursor) VALUES ('371', '4')
RETURN 1
ENDIF
CREATE CURSOR (m.tcCursor) (id_temp N(1))
RETURN 1
ENDPROC
PROCEDURE oExecuta
LPARAMETERS tcSql, tcCursor
IF !EMPTY(m.tcCursor)
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF UPPER(m.tcCursor) == 'CJTVACOL4427'
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14))
ELSE
CREATE CURSOR (m.tcCursor) (id_temp N(1))
ENDIF
ENDIF
RETURN .T.
ENDPROC
PROCEDURE oSelect2Value
LPARAMETERS tcSql, toValue
toValue = ''
RETURN 1
ENDPROC
PROCEDURE oReset
ENDPROC
ENDDEFINE
PROCEDURE CreeazaJtvaColoaneView
LPARAMETERS tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14), denumire C(100), jc N(1), jv N(1), ;
coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14) NULL, afisat N(1), ;
id_jtva_ex N(14) NULL, id_jtva_neex N(14) NULL, ordine N(8), ;
taxcode N(6) NULL, taxcode_neexigibil N(6) NULL, taxcode_n50 N(6) NULL, ;
taxcode_n50_tvai N(6) NULL, taxcode_n100 N(6) NULL, taxcode_regularizare N(6) NULL, taxcode_tvai N(6) NULL)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, afisat, ordine, cota_tva) VALUES (0, '', 0, 0, 1, 0, 0)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (208, 'ACH. INT. 21%', 1, 0, 'RO21B', 21, 209, 1, 1, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (209, 'TVA ACH. INT. 21%', 1, 0, 'RO21T', 21, 1, 2, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (220, 'ACH. IMP. 21%', 1, 0, 'FO21B', 21, 221, 1, 3, 301204)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (221, 'TVA ACH. IMP. 21%', 1, 0, 'FO21T', 21, 1, 4, 301204)
ENDPROC

View File

@@ -0,0 +1,12 @@
# test_dvi_tva_manual.ps1 - wrapper peste harness-ul generic pentru TVA DVI editat manual in
# dialog (supravietuieste do_executa/sincronizeaza) - F1, runda30.
# powershell -ExecutionPolicy Bypass -File test_dvi_tva_manual.ps1
$ErrorActionPreference = 'Stop'
$Teste = $PSScriptRoot
& (Join-Path (Split-Path $Teste -Parent) 'vfp_ui_harness.ps1') `
-TestPrg (Join-Path $Teste 'test_dvi_tva_manual.prg') `
-Steps @('doc1_manual_creat','doc1_manual_verificat','doc2_control_creat','doc2_control_verificat','final') `
-ShotsDir (Join-Path $Teste 'screenshots_dvi_tva_manual') `
-SyncDir (Join-Path $Teste 'uisync_dvi_tva_manual') `
-StepTimeoutSec 180 `
-ReadyTimeoutSec 180

View File

@@ -0,0 +1,769 @@
* test_dvi_valuta_proprie_usd.prg
* Runda30 (F1, plan fizzy-imagining-parnas.md): factura import EUR (curs 5.23) cu TVA DVI in
* USD (curs 4.00) - a treia valuta, aleasa direct pe blocul DVI din dialog, NU printr-un al
* doilea document DVI separat (spre deosebire de test_valuta_dvi_usd.prg, care acopera fluxul
* VECHI cu doua documente - ramane neatins, regresie separata).
* Verifica:
* - randul T (TVA DVI) poarta valuta/curs proprii (USD/4.00), rand_dvi=1, valuta_proprie=1;
* - spargere pe cote (sparge_document, prin sincronizeaza cu articole): T-ul protejat ramane
* neatins si NU se naste niciun rand T suplimentar pe factura - TVA-ul documentului e
* integral cel de pe DVI (altfel iese TVA dubla: o data pe DVI, o data pe factura);
* - caz "singurul T e cel protejat" cu o singura cota pe articole: randul protejat ramane
* neschimbat (spargerea pe cote se face doar cand articolele au cote diferite);
* - editarea cursului pe randul T protejat in grila NU modifica Thisform.oact.curs si NU
* corupe preturile articolelor (rul_temp);
* - revert valuta_proprie: re-alegerea valutei documentului (EUR) pe randul protejat il
* reseteaza la valuta_proprie=0.
*
* ASUMPTII (de confruntat cu implementarea reala):
* - proprietatile de dialog nDviIdValuta/cDviValuta/nDviCurs, setate direct (fara picker);
* - randul protejat se identifica prin rand_dvi=1 (index ord_doc nu distinge intre T-uri);
* - revert-ul valuta_proprie se declanseaza prin Grid1.cValuta.Text1.DblClick (caut_valuta),
* mock_caut_valuta.prg (contract vechi, valoare fixa) intoarce EUR - suficient pentru acest
* test, deoarece valuta de revenit e chiar valuta facturii.
*
* Rulare:
* powershell -ExecutionPolicy Bypass -File test_dvi_valuta_proprie_usd.ps1
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET DECIMALS TO 4
SET NULLDISPLAY TO ''
CLOSE DATABASES
PUBLIC gcUILog, gcSyncDir
gcUILog = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\test_dvi_valuta_proprie_usd_log.txt"
gcSyncDir = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\uisync_dvi_valuta_proprie_usd\"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcUILog)
ON ERROR DO DcErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
TRY
LOCAL gcAppPath, lcPath
gcAppPath = "D:\ROA\ROAGEST\"
SET DEFAULT TO (gcAppPath)
lcPath = gcAppPath + 'Date;' + gcAppPath + 'Include;' + gcAppPath + 'FERESTRE;' + ;
gcAppPath + 'GRAFICE;' + gcAppPath + 'CLASE;' + gcAppPath + 'MENIURI;' + ;
gcAppPath + 'PROGRAME;' + gcAppPath + 'RAPOARTE;' + gcAppPath + 'COMUN;' + ;
gcAppPath + 'COMUN\CLASE;' + gcAppPath + 'COMUN\FERESTRE;' + gcAppPath + 'COMUN\PROGRAME;' + ;
gcAppPath + 'COMUN\GRAFICE;' + gcAppPath + 'COMUN\RAPOARTE;' + gcAppPath + 'COMUN\MENIURI;' + ;
gcAppPath + 'COMUN\UTILE\GRIDEXTRAS;' + gcAppPath + 'COMUN\UTILE\CTL32;' + ;
gcAppPath + 'COMUN\UTILE\HPDF;' + gcAppPath + 'COMUN\UTILE\HPDF\REPORTOUTPUT;' + ;
gcAppPath + 'COMUN\UTILE\WEB;' + gcAppPath + 'COMUN\UTILE\EXCEL;' + ;
ADDBS(SUBSTR(gcAppPath,1,RAT([\],gcAppPath,2)))+[COMUNROA\]
SET PATH TO &lcPath ADDITIVE
DO DcLog WITH 'SET PATH OK'
*----- CLASE -----
SET CLASSLIB TO (gcAppPath + "comun\clase\appwiz") ADDITIVE
SET CLASSLIB TO GESTIUNI ADDITIVE
SET CLASSLIB TO CAUT ADDITIVE
SET CLASSLIB TO BAZA ADDITIVE
SET CLASSLIB TO comun ADDITIVE
SET CLASSLIB TO accessibility.vcx ADDITIVE
SET CLASSLIB TO messagebox ADDITIVE
SET CLASSLIB TO registry ADDITIVE
SET CLASSLIB TO cauta_alfa_forms.vcx ADDITIVE
SET CLASSLIB TO DECABAZA ADDITIVE
SET CLASSLIB TO onomenclatoare ADDITIVE
SET CLASSLIB TO stocuri.vcx ADDITIVE
SET CLASSLIB TO rulaje.vcx ADDITIVE
SET CLASSLIB TO ointroduceri ADDITIVE
SET CLASSLIB TO ointroduceri_web ADDITIVE
SET CLASSLIB TO ointroduceri_depozit ADDITIVE
SET CLASSLIB TO overificari ADDITIVE
SET CLASSLIB TO ferestre_oracle ADDITIVE
SET CLASSLIB TO ferestre_cere_date.vcx ADDITIVE
SET CLASSLIB TO configurare.vcx ADDITIVE
SET CLASSLIB TO serii_numere.vcx ADDITIVE
SET CLASSLIB TO omodificari.vcx ADDITIVE
SET CLASSLIB TO ocompensari.vcx ADDITIVE
SET CLASSLIB TO caut_ora ADDITIVE
SET CLASSLIB TO onote_contabile ADDITIVE
SET CLASSLIB TO otoolbar ADDITIVE
SET CLASSLIB TO bon_fisc ADDITIVE
SET CLASSLIB TO onom_articole ADDITIVE
SET CLASSLIB TO onom_retete ADDITIVE
SET CLASSLIB TO orapoarte ADDITIVE
SET CLASSLIB TO orapoarte_gestiuni ADDITIVE
SET CLASSLIB TO orapoarte_parametri ADDITIVE
SET CLASSLIB TO ONOM_CURS ADDITIVE
SET CLASSLIB TO ctl32_statusbar_fals.vcx ADDITIVE
SET CLASSLIB TO ctl32_common.vcx ADDITIVE
SET CLASSLIB TO ctl32_structs.vcx ADDITIVE
SET CLASSLIB TO ctl32_progressbar.vcx ADDITIVE
SET CLASSLIB TO ctl32_balloontip.vcx ADDITIVE
SET CLASSLIB TO ocriterii.vcx ADDITIVE
SET CLASSLIB TO oavize.vcx ADDITIVE
SET CLASSLIB TO onomenclatoare2 ADDITIVE
SET CLASSLIB TO wwdialogs.vcx ADDITIVE
SET CLASSLIB TO oimportxml.vcx ADDITIVE
SET CLASSLIB TO excelxml.vcx ADDITIVE
SET CLASSLIB TO orapoarte_obinv.vcx ADDITIVE
DO DcLog WITH 'SET CLASSLIB OK'
*----- PROCEDURI (mock-uri PRIMELE, ui_harness la final) -----
SET PROCEDURE TO PROCEDURI
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_cauta_nom_articole.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\mock_caut_valuta.prg" ADDITIVE
SET PROCEDURE TO acces_meniu ADDITIVE
SET PROCEDURE TO cauta_alfa ADDITIVE
SET PROCEDURE TO pmenu ADDITIVE
SET PROCEDURE TO proceduri_comune ADDITIVE
SET PROCEDURE TO quitapp ADDITIVE
SET PROCEDURE TO init_program ADDITIVE
SET PROCEDURE TO oproceduri_listari.prg ADDITIVE
SET PROCEDURE TO oproceduri_configurare.prg ADDITIVE
SET PROCEDURE TO oproceduri_articole.prg ADDITIVE
SET PROCEDURE TO oproceduri_retete.prg ADDITIVE
SET PROCEDURE TO orapoarte.prg ADDITIVE
SET PROCEDURE TO mesaje ADDITIVE
SET PROCEDURE TO oserii_numere.prg ADDITIVE
SET PROCEDURE TO oexport.prg ADDITIVE
SET PROCEDURE TO wwConfig.prg ADDITIVE
SET PROCEDURE TO proceduri_rapoarte.prg ADDITIVE
SET PROCEDURE TO OPROCEDURI_CURS.PRG ADDITIVE
SET PROCEDURE TO validare.prg ADDITIVE
SET PROCEDURE TO GENCURSOR.PRG ADDITIVE
SET PROCEDURE TO OPROCEDURI_COMUNE.PRG ADDITIVE
SET PROCEDURE TO OINIT_OPTIUNI.PRG ADDITIVE
SET PROCEDURE TO updateserver.prg ADDITIVE
SET PROCEDURE TO oinainte_de.prg ADDITIVE
SET PROCEDURE TO ooperatii_comune.prg ADDITIVE
SET PROCEDURE TO Ocompensari.PRG ADDITIVE
SET PROCEDURE TO OPROCEDURI_aMS.PRG ADDITIVE
SET PROCEDURE TO oproceduri_rulaje ADDITIVE
SET PROCEDURE TO oproceduri_stocuri ADDITIVE
SET PROCEDURE TO OINTRODUCERI ADDITIVE
SET PROCEDURE TO oHeader.prg ADDITIVE
SET PROCEDURE TO proceduri_excel.PRG ADDITIVE
SET PROCEDURE TO onomenclatoare.PRG ADDITIVE
SET PROCEDURE TO osecurity ADDITIVE
SET PROCEDURE TO ocautare ADDITIVE
SET PROCEDURE TO orefaceri ADDITIVE
SET PROCEDURE TO ofacturare_comun.PRG ADDITIVE
SET PROCEDURE TO ofacturare_stoc.PRG ADDITIVE
SET PROCEDURE TO oproceduri_casademarcat ADDITIVE
SET PROCEDURE TO oproceduri_casa_marcat_e500 ADDITIVE
SET PROCEDURE TO oproceduri_casa_marcat_mp500 ADDITIVE
SET PROCEDURE TO oproceduri_util.prg ADDITIVE
SET PROCEDURE TO wwxmlhttp.prg ADDITIVE
SET PROCEDURE TO ini.prg ADDITIVE
SET PROCEDURE TO odocumente.prg ADDITIVE
SET PROCEDURE TO regex.prg ADDITIVE
SET PROCEDURE TO wwutils.prg ADDITIVE
SET PROCEDURE TO inchidere_k ADDITIVE
SET PROCEDURE TO iniacces.prg ADDITIVE
SET PROCEDURE TO oupdate.prg ADDITIVE
SET PROCEDURE TO procese.prg ADDITIVE
SET PROCEDURE TO version.prg ADDITIVE
SET PROCEDURE TO xmlaccess.prg ADDITIVE
SET PROCEDURE TO xmlparser.prg ADDITIVE
SET PROCEDURE TO filebringer.prg ADDITIVE
SET PROCEDURE TO wwcodeupdate.prg ADDITIVE
SET PROCEDURE TO wwhttp.prg ADDITIVE
SET PROCEDURE TO xdate.prg ADDITIVE
SET PROCEDURE TO ofacturare.prg ADDITIVE
SET PROCEDURE TO oproceduri_obinv.prg ADDITIVE
SET PROCEDURE TO oproceduri_facturare.prg ADDITIVE
SET PROCEDURE TO email.prg ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\ui_harness.prg" ADDITIVE
DO DcLog WITH 'SET PROCEDURE OK'
*----- goMockValuta: fix EUR (valuta facturii) - suficient pentru revert (Grid1.cValuta
* DblClick alege valuta documentului). goMockValutaCoada pregatit pentru contractul nou. -----
PUBLIC goMockValuta, goMockValutaCoada
goMockValuta = CREATEOBJECT('Custom')
goMockValuta.AddProperty('id_valuta', 978)
goMockValuta.AddProperty('nume_val', 'EUR')
goMockValutaCoada = CREATEOBJECT('Collection')
LOCAL loValFact, loValDvi
loValFact = CREATEOBJECT('Custom')
loValFact.AddProperty('id_valuta', 978)
loValFact.AddProperty('nume_val', 'EUR')
goMockValutaCoada.Add(loValFact)
loValDvi = CREATEOBJECT('Custom')
loValDvi.AddProperty('id_valuta', 840)
loValDvi.AddProperty('nume_val', 'USD')
goMockValutaCoada.Add(loValDvi)
*----- Globale -----
PUBLIC gnPc, gnPval, gnPcant, gnPpret, gnPPretval, gnPCurs, gnPVal, gnPPretV, gnPPretVal
STORE 2 TO gnPc, gnPval, gnPVal
gnPcant = 3
STORE 4 TO gnPpret, gnPPretval, gnPPretVal, gnPPretV, gnPCurs
PUBLIC gl406, gcS, gnAn, gnLuna, gnIdFirma, gnIdSucursala, gcAcces, gcFirma
gl406 = .T.
gcS = 'CONTAFIN'
gnAn = YEAR(DATE())
gnLuna = MONTH(DATE())
gnIdFirma = 110
gnIdSucursala = 110
gcAcces = "1;2;3;4;5;6;7;8;"
gcFirma = gcS
PUBLIC nror(65000)
PUBLIC gnButon
STORE 2 TO gnButon
PUBLIC gcMockArtCodmat, gcMockAcontCrt
gcMockArtCodmat = ''
gcMockAcontCrt = ''
PUBLIC gnMockRaspuns
gnMockRaspuns = 6
PUBLIC goExecutor, goApp
goExecutor = CREATEOBJECT('dummyexecutor')
goApp = CREATEOBJECT('dummyapp')
*----- poAct: antetul notei (moneda principala EUR, curs 5.23) -----
PUBLIC poAct
poAct = CREATEOBJECT('Custom')
poAct.AddProperty('nume_val', 'EUR')
poAct.AddProperty('curs', 5.23)
poAct.AddProperty('proc_tva', 1.21)
poAct.AddProperty('nnir', 0)
poAct.AddProperty('id_valuta', 978)
poAct.AddProperty('id_fdoc', 1)
poAct.AddProperty('fdoc', 'Factura')
poAct.AddProperty('id_partc', 601)
poAct.AddProperty('partc', 'RAJA')
poAct.AddProperty('serie_act', '')
poAct.AddProperty('dataact', DATE())
poAct.AddProperty('tva_incasare', 0)
poAct.AddProperty('id_set', 1)
poAct.AddProperty('id_gestin', 1)
*----- jtva_coloane2 / saft_taxtable: perechi reale 21% -----
IF USED('jtva_coloane2')
USE IN ('jtva_coloane2')
ENDIF
CREATE CURSOR jtva_coloane2 (ordine N(8), id_jtva_coloana N(14), denumire C(100), ;
jc N(1), jv N(1), afisat N(1), coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14))
INSERT INTO jtva_coloane2 VALUES (0, 0, '', 0, 0, 1, '', '', 0, 0)
INSERT INTO jtva_coloane2 VALUES (1, 208, 'ACH. INT. 21%', 1, 0, 1, 'RO21B', 'RO21T', 21, 209)
INSERT INTO jtva_coloane2 VALUES (2, 209, 'TVA ACH. INT. 21%', 1, 0, 1, 'RO21T', '', 21, 0)
INSERT INTO jtva_coloane2 VALUES (3, 220, 'ACH. IMP. 21%', 1, 0, 1, 'FO21B', 'FO21T', 21, 221)
INSERT INTO jtva_coloane2 VALUES (4, 221, 'TVA ACH. IMP. 21%', 1, 0, 1, 'FO21T', '', 21, 0)
IF USED('saft_taxtable')
USE IN ('saft_taxtable')
ENDIF
CREATE CURSOR saft_taxtable (taxname C(250) NULL, typename C(250) NULL, taxcode N(6) NULL, ;
taxtype N(3) NULL, descriere C(250) NULL, tip C(100) NULL, descriere_tip C(250) NULL, ;
procent_taxa N(7,2) NULL, procent_prorata N(7,2) NULL, inactiv N(1) NULL, tva N(1) NULL, ;
wht N(1) NULL, tva_achizitii N(1) NULL, tva_livrari N(1) NULL)
INDEX ON taxcode TAG taxcode
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('', 0, '', 0, 1, 1, 1, 1)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301204-Import de bunuri cota 21%', 301204, '', 21, 1, 0, 1, 0)
DO CreeazaIntrodc WITH 'introdc'
DO CreeazaIntrodc WITH 'introdc_sablon'
INSERT INTO introdc_sablon (scd, scc, cu_tva, ordine, id_set, participa_valuta, tip_rand, ;
id_jtva_coloana, ptva, explicatie_tva) ;
VALUES ('371', '401', 1, 1, 1, .T., 'B', 208, 21, 'ACH. INT. 21%')
INSERT INTO introdc_sablon (scd, scc, cu_tva, ordine, id_set, participa_valuta, tip_rand, ;
id_jtva_coloana, ptva, explicatie_tva) ;
VALUES ('4426', '401', 1, 2, 1, .T., 'T', 209, 21, 'TVA ACH. INT. 21%')
GO TOP IN introdc_sablon
DO CreeazaRulTemp
INSERT INTO rul_temp (denumire, codmat, cant, pret, pret_lei, cont, cota_tva) ;
VALUES ('PLACEHOLDER', 'PH', 1, 1, 1, '371', 21)
SELECT introdc
INDEX ON Str(Nvl(nr_doc,0),8) + Icase(tip_rand='B','1', tip_rand='S','2', tip_rand='G','3', tip_rand='T','4', tip_rand='D','5', '6') + Padr(Nvl(scd,''),10) TAG ord_doc
SET ORDER TO ord_doc
DO DcLog WITH 'cursoare pregatite, CREATEOBJECT(import_nota, .F.)'
PUBLIC goObj
goObj = CREATEOBJECT('IMPORT_nota', .F.)
IF VARTYPE(goObj) <> 'O'
DO DcLog WITH 'FAIL: instantiere import_nota'
DO HarnessDone WITH 'done-error'
QUIT
ENDIF
goObj.lDialogAratat = .T.
goObj.oact = poAct
goObj.lSpargeSecundare = .F.
goObj.WindowType = 0
goObj.Visible = .T.
goObj.Show()
goObj.WindowState = 2
DOEVENTS FORCE
SELECT rul_temp
ZAP
goObj.gridart.Refresh()
DOEVENTS FORCE
PRIVATE pnAsserts, pnPass
STORE 0 TO pnAsserts, pnPass
*========================= DOC1: FACTURA EUR + TVA DVI in USD (valuta proprie) =========================
PUBLIC goDlg, goT, gcDocKey1
DO AdaugaDoc1
DO HarnessStep WITH 0, 'dupa AdaugaDoc1: introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri'
SELECT introdc
LOCATE FOR Nvl(rand_dvi,0) = 1
=Assert3('1-rand T-DVI gasit (rand_dvi=1)', IIF(FOUND(),1,0), 1)
IF FOUND()
gcDocKey1 = ALLTRIM(NVL(doc_key,''))
DO DcLog WITH 'T-DVI: doc_key=[' + gcDocKey1 + '] suma=' + TRANSFORM(suma) + ' suma_val=' + TRANSFORM(suma_val) + ' curs=' + TRANSFORM(curs) + ' nume_val=[' + ALLTRIM(NVL(nume_val,'')) + ']'
=Assert3('2-T-DVI.in_valuta=1 (USD e valuta)', NVL(in_valuta,0), 1)
=Assert3('3-T-DVI.valuta_proprie=1 (USD <> EUR factura)', NVL(valuta_proprie,0), 1)
=Assert3('4-T-DVI.id_valuta=840 (USD)', NVL(id_valuta,0), 840)
=Assert3('5-T-DVI.curs=4.00', NVL(curs,0), 4.00)
=AssertStr('6-T-DVI.nume_val=USD', ALLTRIM(NVL(nume_val,'?')), 'USD')
=Assert3('7-T-DVI.suma_val=274.58 (1098.30/4.00)', suma_val, 274.58)
ELSE
DO DcLog WITH ' FAIL: nu exista rand T-DVI - sar restul verificarilor dependente'
ENDIF
*========================= ARTICOLE (flux real do_adauga_articol) - documentul devine principal =========================
gcMockArtCodmat = 'ART-A8-371'
gcMockAcontCrt = '4'
TRY
goObj.do_adauga_articol()
CATCH TO loExcA1
DO DcLog WITH 'EROARE do_adauga_articol ' + TRANSFORM(loExcA1.ErrorNo) + ' [' + loExcA1.Message + ']'
ENDTRY
DOEVENTS FORCE
SELECT rul_temp
LOCATE FOR ALLTRIM(codmat) == 'ART-A8-371'
IF FOUND()
REPLACE cant WITH 1, pret_val WITH 1000, pretd WITH 1000, pret WITH ROUND(1000*5.23,4), pret_lei WITH ROUND(1000*5.23,4)
ELSE
DO DcLog WITH 'FAIL: articolul nu a fost adaugat de do_adauga_articol()'
ENDIF
goObj.gridart.Refresh()
DOEVENTS FORCE
DO HarnessStep WITH 1, 'dupa adaugare articol, rul_temp=' + TRANSFORM(RECCOUNT_ACTIVE('rul_temp'))
*========================= SINCRONIZARE (declanseaza sparge_document: singurul T e cel protejat) =========================
LOCAL llEroareSync
llEroareSync = .F.
TRY
goObj.sincronizeaza()
CATCH TO loExcS1
llEroareSync = .T.
DO DcLog WITH 'EROARE la sincronizeaza() ' + TRANSFORM(loExcS1.ErrorNo) + ' [' + loExcS1.Message + '] in ' + loExcS1.Procedure + ':' + TRANSFORM(loExcS1.LineNo)
ENDTRY
DOEVENTS FORCE
=Assert3('8-sincronizeaza() fara eroare', IIF(llEroareSync,0,1), 1)
DO DumpIntrodc
DO HarnessStep WITH 2, 'dupa sincronizare: introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri'
*========================= T PROTEJAT SUPRAVIETUIESTE SPARGERII, NECOMASAT/NEATINS =========================
SELECT introdc
LOCATE FOR Nvl(rand_dvi,0) = 1
=Assert3('9-dupa sincronizare: T-DVI (rand_dvi=1) inca exista', IIF(FOUND(),1,0), 1)
IF FOUND()
=Assert3('10-T-DVI.suma_val neschimbata (274.58)', suma_val, 274.58)
=Assert3('11-T-DVI.curs neschimbat (4.00)', curs, 4.00)
=Assert3('12-T-DVI.valuta_proprie ramane 1', NVL(valuta_proprie,0), 1)
ELSE
pnAsserts = pnAsserts + 3
DO DcLog WITH ' FAIL 10-12: T-DVI a disparut dupa sincronizare (sparge_document l-a atins gresit)'
ENDIF
*========================= NICIUN T SUPLIMENTAR PE FACTURA (TVA-ul e integral cel de pe DVI) =========================
LOCAL lnCntTNormale, lnCntTTotal
lnCntTNormale = 0
lnCntTTotal = 0
SELECT introdc
SCAN FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND tip_rand == 'T'
lnCntTTotal = lnCntTTotal + 1
IF Nvl(rand_dvi,0) = 0
lnCntTNormale = lnCntTNormale + 1
DO DcLog WITH 'T-duplicat: suma=' + TRANSFORM(suma) + ' suma_val=' + TRANSFORM(suma_val) + ' scd=[' + ALLTRIM(NVL(scd,'')) + '] partc=[' + ALLTRIM(NVL(partc,'')) + '] nume_val=[' + ALLTRIM(NVL(nume_val,'')) + ']'
ENDIF
ENDSCAN
=Assert3('13-niciun rand T nou pe factura (TVA-ul e doar pe DVI)', lnCntTNormale, 0)
=Assert3('14-un singur rand T pe document (articolele au o singura cota)', lnCntTTotal, 1)
SELECT introdc
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND tip_rand == 'T'
IF FOUND()
=Assert3('15-T-ul ramas e cel protejat (rand_dvi=1)', NVL(rand_dvi,0), 1)
=AssertStr('16-T pastreaza valuta proprie USD', ALLTRIM(NVL(nume_val,'?')), 'USD')
=Assert3('17-T pastreaza suma_val tastata (274.58)', suma_val, 274.58)
ELSE
pnAsserts = pnAsserts + 3
DO DcLog WITH ' FAIL 15-17: nu exista niciun rand T pe document'
ENDIF
DO HarnessStep WITH 3, 'TVA doar pe randul DVI protejat (' + TRANSFORM(lnCntTTotal) + ' rand T pe document) - vezi log'
*========================= EDITARE CURS PE T PROTEJAT IN GRILA: oact.curs SI preturi articole NEATINSE =========================
LOCAL lnCursInainte, lnPretInainte
lnCursInainte = goObj.oact.curs
SELECT rul_temp
LOCATE FOR ALLTRIM(codmat) == 'ART-A8-371'
lnPretInainte = IIF(FOUND(),pret,-1)
SELECT introdc
LOCATE FOR Nvl(rand_dvi,0) = 1
=Assert3('18-rand T-DVI gasit pentru editare curs in grila', IIF(FOUND(),1,0), 1)
IF FOUND()
goObj.grid1.cCurs.text1.Value = 4.50
goObj.grid1.cCurs.text1.Valid()
DOEVENTS FORCE
ENDIF
=Assert3('19-dupa editare curs pe T-DVI: oact.curs NESCHIMBAT (5.23)', goObj.oact.curs, lnCursInainte)
SELECT rul_temp
LOCATE FOR ALLTRIM(codmat) == 'ART-A8-371'
=Assert3('20-dupa editare curs pe T-DVI: pretul articolului NESCHIMBAT', IIF(FOUND(),pret,-1), lnPretInainte)
SELECT introdc
LOCATE FOR Nvl(rand_dvi,0) = 1
IF FOUND()
=Assert3('21-T-DVI.curs actualizat local (4.50)', curs, 4.50)
=Assert3('22-T-DVI.suma_val recalculata (1098.30/4.50=244.07)', suma_val, 244.07)
ELSE
pnAsserts = pnAsserts + 2
DO DcLog WITH ' FAIL 21-22: T-DVI negasit dupa editare curs in grila'
ENDIF
DO HarnessStep WITH 4, 'editare curs pe T protejat verificata (oact.curs+preturi intacte) - vezi log'
*========================= REVERT valuta_proprie: re-alegerea valutei documentului (EUR) =========================
SELECT introdc
LOCATE FOR Nvl(rand_dvi,0) = 1
=Assert3('23-rand T-DVI gasit pentru revert valuta', IIF(FOUND(),1,0), 1)
IF FOUND()
TRY
goObj.grid1.cValuta.text1.DblClick()
CATCH TO loExcRevert
DO DcLog WITH 'INFO cValuta.text1.DblClick a aruncat eroare (poate necesita alt trigger): ' + loExcRevert.Message
ENDTRY
DOEVENTS FORCE
ENDIF
SELECT introdc
LOCATE FOR Nvl(rand_dvi,0) = 1
IF FOUND()
DO DcLog WITH 'dupa revert: id_valuta=' + TRANSFORM(NVL(id_valuta,0)) + ' nume_val=[' + ALLTRIM(NVL(nume_val,'')) + '] valuta_proprie=' + TRANSFORM(NVL(valuta_proprie,0))
=Assert3('24-dupa re-alegere valuta facturii (EUR) pe T-DVI: valuta_proprie reseteaza la 0', NVL(valuta_proprie,0), 0)
=Assert3('25-dupa revert: id_valuta devine 978 (EUR, valuta facturii)', NVL(id_valuta,0), 978)
ELSE
pnAsserts = pnAsserts + 2
DO DcLog WITH ' FAIL 24-25: T-DVI negasit dupa incercarea de revert'
ENDIF
DO HarnessStep WITH 5, 'revert valuta_proprie verificat - vezi log'
DO DcLog WITH 'REZULTAT: ' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' assert-uri PASS'
IF pnPass = pnAsserts
DO DcLog WITH 'REZULTAT: PASS (' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ')'
ELSE
DO DcLog WITH 'REZULTAT: FAIL (' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' assert-uri PASS)'
ENDIF
DO HarnessStep WITH 6, 'final: ' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' PASS'
DO HarnessDone WITH 'done'
CATCH TO loExc
DO DcLog WITH 'CATCH ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']'
DO HarnessDone WITH 'done-error'
ENDTRY
QUIT
*==================================================================================
PROCEDURE AdaugaDoc1
*-- FACTURA 15000 RAJA, 1000 EUR curs 5.23 (5230 lei), TVA pe DVI ('D'): DVI 101 BIROUL
*-- VAMAL, tva 1098.30 lei / 274.58 USD (curs propriu 4.00) - a treia valuta, diferita de
*-- EUR (factura) si de RON.
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = 15000
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 601
goDlg.cPartener = 'RAJA'
goDlg.cExplicatia = 'Import marfa RAJA'
goDlg.nSuma = 1000
goDlg.nSumaLei = 0
goDlg.nCurs = 5.23
goDlg.nIdValuta = 978
goDlg.cValuta = 'EUR'
goDlg.nIdExplicatieTva = 220
goDlg.cExplicatieTva = 'ACH. IMP. 21%'
goDlg.optTipTva.Value = 2 && D = DVI
goDlg.chkInValutaCont.Value = 1
goDlg.chkParticipaValuta.Value = 1
goDlg.cSerieDvi = ''
goDlg.nNractDvi = 101
goDlg.dDviData = DATE()
goDlg.nIdFdocDVI = 2
goDlg.cFelDocDvi = 'DVI'
goDlg.nDviIdPartener = 900
goDlg.cDviPartener = 'BIROUL VAMAL'
goDlg.nDviTvaLei = 1098.30
goDlg.nDviTvaVal = 274.58
*-- F1 NOU: valuta/curs proprii DVI - USD, a treia valuta (diferita de EUR/factura si de RON)
goDlg.nDviIdValuta = 840
goDlg.cDviValuta = 'USD'
goDlg.nDviCurs = 4.00
goDlg.actualizeaza_stare_dvi()
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO DcLog WITH 'DOC1: valideaza = ' + TRANSFORM(goDlg.valideaza())
DO ConstruiesteToDlgF1F2
DO DcLog WITH 'DOC1: do_adauga_factura = ' + TRANSFORM(goObj.do_adauga_factura(goT))
goDlg.Hide()
DOEVENTS FORCE
ENDPROC
PROCEDURE ConstruiesteToDlgF1F2
goT = CREATEOBJECT('Empty')
=ADDPROPERTY(goT,'serie_act',ALLTRIM(NVL(goDlg.cSerieAct,'')))
=ADDPROPERTY(goT,'nract',goDlg.nNract)
=ADDPROPERTY(goT,'dataact',goDlg.dDataAct)
=ADDPROPERTY(goT,'fdoc',goDlg.cFelDoc)
=ADDPROPERTY(goT,'id_fdoc',goDlg.nIdFdoc)
=ADDPROPERTY(goT,'id_partc',goDlg.nIdPartener)
=ADDPROPERTY(goT,'partc',goDlg.cPartener)
=ADDPROPERTY(goT,'explicatia',ALLTRIM(NVL(goDlg.cExplicatia,'')))
=ADDPROPERTY(goT,'suma',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,IIF(goDlg.nSumaLei<>0,goDlg.nSumaLei,ROUND(goDlg.nSuma*goDlg.nCurs,gnPC)),goDlg.nSuma))
=ADDPROPERTY(goT,'suma_val',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,goDlg.nSuma,0))
=ADDPROPERTY(goT,'in_valuta',goDlg.chkInValutaCont.Value)
=ADDPROPERTY(goT,'participa_valuta',(goDlg.chkParticipaValuta.Value=1))
=ADDPROPERTY(goT,'id_valuta',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nIdValuta,0))
=ADDPROPERTY(goT,'curs',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nCurs,0))
=ADDPROPERTY(goT,'nume_val',IIF(goDlg.chkInValutaCont.Value=1,ALLTRIM(NVL(goDlg.cValuta,'')),''))
=ADDPROPERTY(goT,'cTipTva',IIF(goDlg.optTipTva.Value=1,'F',IIF(goDlg.optTipTva.Value=2,'D','N')))
=ADDPROPERTY(goT,'id_jtva_coloana',goDlg.nIdExplicatieTva)
=ADDPROPERTY(goT,'dvi_serie',CHRTRAN(ALLTRIM(NVL(goDlg.cSerieDvi,'')),CHR(34),''))
=ADDPROPERTY(goT,'dvi_nract',goDlg.nNractDvi)
=ADDPROPERTY(goT,'dvi_dataact',goDlg.dDviData)
=ADDPROPERTY(goT,'dvi_id_fdoc',goDlg.nIdFdocDVI)
=ADDPROPERTY(goT,'dvi_fdoc',goDlg.cFelDocDvi)
=ADDPROPERTY(goT,'dvi_id_partc',goDlg.nDviIdPartener)
=ADDPROPERTY(goT,'dvi_partc',goDlg.cDviPartener)
=ADDPROPERTY(goT,'dvi_scc','401')
=ADDPROPERTY(goT,'dvi_tva_lei',goDlg.nDviTvaLei)
=ADDPROPERTY(goT,'dvi_tva_val',goDlg.nDviTvaVal)
=ADDPROPERTY(goT,'dvi_in_valuta',!(EMPTY(goDlg.cDviValuta) OR UPPER(ALLTRIM(NVL(goDlg.cDviValuta,'')))=='RON'))
=ADDPROPERTY(goT,'dvi_id_valuta',goDlg.nDviIdValuta)
=ADDPROPERTY(goT,'dvi_curs',goDlg.nDviCurs)
=ADDPROPERTY(goT,'dvi_nume_val',ALLTRIM(NVL(goDlg.cDviValuta,'')))
=ADDPROPERTY(goT,'dvi_valuta_proprie',IIF(!(EMPTY(goDlg.cDviValuta) OR UPPER(ALLTRIM(NVL(goDlg.cDviValuta,'')))=='RON') OR !(EMPTY(goDlg.cValuta) OR UPPER(ALLTRIM(NVL(goDlg.cValuta,'')))=='RON'),IIF(goDlg.nDviIdValuta<>goDlg.nIdValuta OR goDlg.nDviCurs<>goDlg.nCurs,1,0),0))
=ADDPROPERTY(goT,'disc_baza_lei',0)
=ADDPROPERTY(goT,'disc_baza_val',0)
ENDPROC
PROCEDURE CreeazaRulTemp
IF USED('rul_temp')
USE IN ('rul_temp')
ENDIF
CREATE CURSOR rul_temp ( ;
id_rul N(20,0), an N(4,0), luna N(2,0), cod N(20,0);
, serie C(100), nnir N(20,0), id_articol N(10,0), denumire C(100);
, codmat C(50), codmatf C(50), codbare C(50), um C(20);
, id_gestiune N(5,0), nume_gestiune C(50), cgest C(20), nr_pag N(2,0);
, gestionar C(50), comisie_receptie1 C(50), comisie_receptie2 C(50), comisie_receptie3 C(50);
, cant N(14,3), cante N(14,3), cont C(10), acont C(20);
, pret N(18,4), tva N(18,4), valoare N(18,4), valtva N(18,4);
, proc_tva N(5,2), pretv N(18,4), pretvtva N(18,4), tvav N(18,4);
, valoarev N(18,4), valtvav N(18,4), proc_tvav N(5,2), adaos N(18,4);
, adaos_tva N(18,4), valoare_adaos N(18,4), valtva_adaos N(18,4), procent N(10,3);
, discunitar N(18,4), discount_tva N(18,4), valoare_discount N(18,4), valtva_discount N(18,4);
, proc_disc N(7,3), pretd N(14,4), curs N(18,4), id_valuta N(10,0);
, nume_val C(20), id_lucrare N(20,0), nrord C(100), id_responsabil N(10,0);
, nresp C(100), resp_marca N(18,4), dataact T, id_util N(5,0);
, util C(30), dataora T, id_sectie N(5,0), sectie C(50);
, csectie C(10), alcooltutun N(1,0), datain T, dataout T;
, id_fact N(20,0), id_gestiunec N(10,0), nume_gestiunec C(50), cgestc C(20);
, id_responsabilc N(5,0), id_reteta N(10,0), reteta C(50), nrespc C(100);
, respc_marca N(18,4), id_set N(20,0), id_tip_rulaj N(10,0), tip_rulaj C(50);
, id_obiect_depozit N(10,0), id_rul_aux N(10,0), nract N(20,0), serie_act C(10);
, dataoras T, id_utils N(10,0), lot C(30), adata_expirare T;
, id_sucursala N(5,0), sucursala C(250), id_part_rez N(10,0), part_rez C(100);
, id_lucrare_rez N(10,0), nrord_rez C(100), subgrupa C(100), grupa C(100);
, id_subgrupa N(5,0), id_grupa N(5,0), in_stoc N(1,0), in_crm N(1,0);
, id_furnizor N(10,0), furnizor C(100), id_jtva_coloana N(4,0), explicatie_tva C(100);
, taxcode N(6,0), taxname C(254), saft_procent N(18,4), codnc8 C(20);
, id_tara_origine N(4,0), cod_tara_origine C(5), tara_origine C(50), greutate N(12,4);
, fdoc C(30), id_fdoc N(18,4);
, pret_lei N(18,4), pret_val N(14,4), cota_tva N(6,2))
ENDPROC
PROCEDURE CreeazaIntrodc
*-- Runda30 (F1/pas2): coloane NOI rand_dvi N(1), valuta_proprie N(1) fata de structura veche.
LPARAMETERS tcAlias
IF USED(tcAlias)
USE IN (tcAlias)
ENDIF
CREATE CURSOR (tcAlias) ( ;
id_note N(14), explicatia C(100), scd C(10), ascd C(20), scc C(10), ascc C(20), ;
cu_tva N(1), id_set N(14), ordine N(8), in_valuta N(1), id_jtva_coloana N(14) NULL, ;
ptva N(6,2), explicatie_tva C(50), tipjurnal C(2), taxcode N(6), paymentcode C(9), ;
suma N(18,4), suma_val N(18,4), id_partd N(14), id_partc N(14), partd C(100), partc C(100), ;
id_fact N(14), id_factd N(14), id_factc N(14), pereched N(14), perechec N(14), ;
nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), expl_manual N(1), ;
scd_orig C(20), ascd_orig C(20), rand_dvi N(1), valuta_proprie N(1))
ENDPROC
FUNCTION RECCOUNT_ACTIVE
LPARAMETERS tcAlias
LOCAL lnSel, lnCnt
lnSel = SELECT()
SELECT (tcAlias)
COUNT TO lnCnt FOR !DELETED()
SELECT (lnSel)
RETURN lnCnt
ENDFUNC
PROCEDURE DumpIntrodc
LOCAL lnSel
lnSel = SELECT()
SELECT introdc
SCAN
DO DcLog WITH ' recno=' + TRANSFORM(RECNO()) + ' nr_doc=' + TRANSFORM(NVL(nr_doc,0)) + ' nract=' + TRANSFORM(nract) + ' fdoc=[' + ALLTRIM(NVL(fdoc,'')) + '] tip_rand=' + tip_rand + ;
' scd=' + ALLTRIM(scd) + ' scc=' + ALLTRIM(scc) + ' suma=' + TRANSFORM(suma) + ' suma_val=' + TRANSFORM(suma_val) + ;
' rand_dvi=' + TRANSFORM(NVL(rand_dvi,0)) + ' valuta_proprie=' + TRANSFORM(NVL(valuta_proprie,0)) + ' doc_key=[' + ALLTRIM(doc_key) + ']'
ENDSCAN
SELECT (lnSel)
ENDPROC
PROCEDURE Assert3
LPARAMETERS tcLabel, tuActual, tuExpected
pnAsserts = pnAsserts + 1
IF ABS(NVL(tuActual,0) - tuExpected) < 0.02
pnPass = pnPass + 1
DO DcLog WITH ' PASS ' + tcLabel + ' (=' + TRANSFORM(tuActual) + ')'
ELSE
DO DcLog WITH ' FAIL ' + tcLabel + ' (actual=' + TRANSFORM(tuActual) + ' asteptat=' + TRANSFORM(tuExpected) + ')'
ENDIF
ENDPROC
PROCEDURE AssertStr
LPARAMETERS tcLabel, tcActual, tcExpected
pnAsserts = pnAsserts + 1
IF tcActual == tcExpected
pnPass = pnPass + 1
DO DcLog WITH ' PASS ' + tcLabel + ' (=[' + tcActual + '])'
ELSE
DO DcLog WITH ' FAIL ' + tcLabel + ' (actual=[' + tcActual + '] asteptat=[' + tcExpected + '])'
ENDIF
ENDPROC
PROCEDURE DcErr
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
DO DcLog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
ENDPROC
PROCEDURE DcLog
LPARAMETERS tcMsg
SET SAFETY OFF
LOCAL lcL
lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '')
STRTOFILE(lcL + tcMsg + CHR(13)+CHR(10), gcUILog)
ENDPROC
DEFINE CLASS dummyapp AS Custom
PROCEDURE ReadIni
LPARAMETERS tcSection, tcKey
RETURN ''
ENDPROC
PROCEDURE WriteIni
LPARAMETERS tcSection, tcKey, tcValue
RETURN .T.
ENDPROC
ENDDEFINE
DEFINE CLASS dummyexecutor AS Custom
cEroare = ''
PROCEDURE oExecute
LPARAMETERS tcSql, tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF 'VJTVA_COLOANE' $ UPPER(m.tcSql)
DO CreeazaJtvaColoaneView WITH m.tcCursor
RETURN 1
ENDIF
IF UPPER(ALLTRIM(m.tcCursor)) == 'RUL_TEMP'
CREATE CURSOR (m.tcCursor) (denumire C(100), codmat C(30), cant N(14,3), ;
pret_val N(18,4), pretd N(18,4), pret N(18,4), pret_lei N(18,4), cont C(10), ;
acont C(20), serie C(30), lot C(30), adata_expirare C(10), proc_disc N(6,2), cota_tva N(6,2))
RETURN 1
ENDIF
IF 'CONFIG_ANALITICE' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (camp_leg_prefix C(30), camp_leg_sufix C(30))
INSERT INTO (m.tcCursor) VALUES ('', '')
RETURN 1
ENDIF
IF 'FCONTURI_ANALITICE' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (acont C(20))
INSERT INTO (m.tcCursor) VALUES (IIF(TYPE('gcMockAcontCrt') = 'C', gcMockAcontCrt, ''))
RETURN 1
ENDIF
IF 'VPLCONT_ANALITIC' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (cont C(10), acont C(20))
INSERT INTO (m.tcCursor) VALUES ('371', '4')
RETURN 1
ENDIF
CREATE CURSOR (m.tcCursor) (id_temp N(1))
RETURN 1
ENDPROC
PROCEDURE oExecuta
LPARAMETERS tcSql, tcCursor
IF !EMPTY(m.tcCursor)
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF UPPER(m.tcCursor) == 'CJTVACOL4427'
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14))
ELSE
CREATE CURSOR (m.tcCursor) (id_temp N(1))
ENDIF
ENDIF
RETURN .T.
ENDPROC
PROCEDURE oSelect2Value
LPARAMETERS tcSql, toValue
toValue = ''
RETURN 1
ENDPROC
PROCEDURE oReset
ENDPROC
ENDDEFINE
PROCEDURE CreeazaJtvaColoaneView
LPARAMETERS tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14), denumire C(100), jc N(1), jv N(1), ;
coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14) NULL, afisat N(1), ;
id_jtva_ex N(14) NULL, id_jtva_neex N(14) NULL, ordine N(8), ;
taxcode N(6) NULL, taxcode_neexigibil N(6) NULL, taxcode_n50 N(6) NULL, ;
taxcode_n50_tvai N(6) NULL, taxcode_n100 N(6) NULL, taxcode_regularizare N(6) NULL, taxcode_tvai N(6) NULL)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, afisat, ordine, cota_tva) VALUES (0, '', 0, 0, 1, 0, 0)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (208, 'ACH. INT. 21%', 1, 0, 'RO21B', 21, 209, 1, 1, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (209, 'TVA ACH. INT. 21%', 1, 0, 'RO21T', 21, 1, 2, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (220, 'ACH. IMP. 21%', 1, 0, 'FO21B', 21, 221, 1, 3, 301204)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (221, 'TVA ACH. IMP. 21%', 1, 0, 'FO21T', 21, 1, 4, 301204)
ENDPROC

View File

@@ -0,0 +1,12 @@
# test_dvi_valuta_proprie_usd.ps1 - wrapper peste harness-ul generic pentru TVA DVI in a treia
# valuta (USD), proprie fata de factura (EUR) - F1, runda30.
# powershell -ExecutionPolicy Bypass -File test_dvi_valuta_proprie_usd.ps1
$ErrorActionPreference = 'Stop'
$Teste = $PSScriptRoot
& (Join-Path (Split-Path $Teste -Parent) 'vfp_ui_harness.ps1') `
-TestPrg (Join-Path $Teste 'test_dvi_valuta_proprie_usd.prg') `
-Steps @('doc1_creat','articol_adaugat','sync_sparge','tva_doar_pe_dvi','curs_grid_protejat','revert_valuta_proprie','final') `
-ShotsDir (Join-Path $Teste 'screenshots_dvi_valuta_proprie_usd') `
-SyncDir (Join-Path $Teste 'uisync_dvi_valuta_proprie_usd') `
-StepTimeoutSec 180 `
-ReadyTimeoutSec 180

View File

@@ -0,0 +1,948 @@
* test_dvi_valuta_ron.prg
* Runda30 (F1, plan fizzy-imagining-parnas.md): factura import EUR (curs 5.23) cu TVA DVI
* platita in RON (fara valuta proprie a DVI - selectie explicita, diferita de valuta facturii).
* Verifica:
* - randul T (TVA DVI) primeste rand_dvi=1, valuta_proprie=1 (RON <> EUR factura),
* in_valuta=0, participa_valuta=.F.;
* - suma T NU se schimba dupa do_executa()/sincronizeaza()/recalc_tva_document() explicit;
* - suma T e imuna la schimbarea cursului facturii (copiaza_valoare sare randul protejat);
* - footer TVA in valuta (recalculeaza/ntva_val) EXCLUDE randul T RON chiar daca suma_val
* ar contine reziduu (assert direct pe filtrul participa_valuta din Sum);
* - uneste_document (test izolat, cursor construit direct) nu comaseaza un rand T protejat;
* - debifare in_valuta la nivel de document: randurile B/S se golesc de valuta, randul T
* protejat ramane neschimbat (deja RON) si isi pastreaza valuta_proprie=1.
*
* ASUMPTII (de confruntat cu implementarea reala, vezi raportul catre orchestrator):
* - proprietatile noi de dialog se numesc nDviIdValuta, cDviValuta, nDviCurs (RON = 0/''/0);
* - toDlg.dvi_valuta_proprie e calculat de do_adauga_factura ca 1 cand valuta/curs DVI difera
* de valuta/curs facturii (aici construit direct in ConstruiesteToDlgF1F2, ca proxy);
* - recalc_tva_document primeste garda suplimentara Nvl(valuta_proprie,0)=0 langa mod_manual.
*
* Rulare:
* powershell -ExecutionPolicy Bypass -File test_dvi_valuta_ron.ps1
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET DECIMALS TO 4
SET NULLDISPLAY TO ''
CLOSE DATABASES
PUBLIC gcUILog, gcSyncDir
gcUILog = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\test_dvi_valuta_ron_log.txt"
gcSyncDir = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\uisync_dvi_valuta_ron\"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcUILog)
ON ERROR DO DcErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
TRY
LOCAL gcAppPath, lcPath
gcAppPath = "D:\ROA\ROAGEST\"
SET DEFAULT TO (gcAppPath)
lcPath = gcAppPath + 'Date;' + gcAppPath + 'Include;' + gcAppPath + 'FERESTRE;' + ;
gcAppPath + 'GRAFICE;' + gcAppPath + 'CLASE;' + gcAppPath + 'MENIURI;' + ;
gcAppPath + 'PROGRAME;' + gcAppPath + 'RAPOARTE;' + gcAppPath + 'COMUN;' + ;
gcAppPath + 'COMUN\CLASE;' + gcAppPath + 'COMUN\FERESTRE;' + gcAppPath + 'COMUN\PROGRAME;' + ;
gcAppPath + 'COMUN\GRAFICE;' + gcAppPath + 'COMUN\RAPOARTE;' + gcAppPath + 'COMUN\MENIURI;' + ;
gcAppPath + 'COMUN\UTILE\GRIDEXTRAS;' + gcAppPath + 'COMUN\UTILE\CTL32;' + ;
gcAppPath + 'COMUN\UTILE\HPDF;' + gcAppPath + 'COMUN\UTILE\HPDF\REPORTOUTPUT;' + ;
gcAppPath + 'COMUN\UTILE\WEB;' + gcAppPath + 'COMUN\UTILE\EXCEL;' + ;
ADDBS(SUBSTR(gcAppPath,1,RAT([\],gcAppPath,2)))+[COMUNROA\]
SET PATH TO &lcPath ADDITIVE
DO DcLog WITH 'SET PATH OK'
*----- CLASE -----
SET CLASSLIB TO (gcAppPath + "comun\clase\appwiz") ADDITIVE
SET CLASSLIB TO GESTIUNI ADDITIVE
SET CLASSLIB TO CAUT ADDITIVE
SET CLASSLIB TO BAZA ADDITIVE
SET CLASSLIB TO comun ADDITIVE
SET CLASSLIB TO accessibility.vcx ADDITIVE
SET CLASSLIB TO messagebox ADDITIVE
SET CLASSLIB TO registry ADDITIVE
SET CLASSLIB TO cauta_alfa_forms.vcx ADDITIVE
SET CLASSLIB TO DECABAZA ADDITIVE
SET CLASSLIB TO onomenclatoare ADDITIVE
SET CLASSLIB TO stocuri.vcx ADDITIVE
SET CLASSLIB TO rulaje.vcx ADDITIVE
SET CLASSLIB TO ointroduceri ADDITIVE
SET CLASSLIB TO ointroduceri_web ADDITIVE
SET CLASSLIB TO ointroduceri_depozit ADDITIVE
SET CLASSLIB TO overificari ADDITIVE
SET CLASSLIB TO ferestre_oracle ADDITIVE
SET CLASSLIB TO ferestre_cere_date.vcx ADDITIVE
SET CLASSLIB TO configurare.vcx ADDITIVE
SET CLASSLIB TO serii_numere.vcx ADDITIVE
SET CLASSLIB TO omodificari.vcx ADDITIVE
SET CLASSLIB TO ocompensari.vcx ADDITIVE
SET CLASSLIB TO caut_ora ADDITIVE
SET CLASSLIB TO onote_contabile ADDITIVE
SET CLASSLIB TO otoolbar ADDITIVE
SET CLASSLIB TO bon_fisc ADDITIVE
SET CLASSLIB TO onom_articole ADDITIVE
SET CLASSLIB TO onom_retete ADDITIVE
SET CLASSLIB TO orapoarte ADDITIVE
SET CLASSLIB TO orapoarte_gestiuni ADDITIVE
SET CLASSLIB TO orapoarte_parametri ADDITIVE
SET CLASSLIB TO ONOM_CURS ADDITIVE
SET CLASSLIB TO ctl32_statusbar_fals.vcx ADDITIVE
SET CLASSLIB TO ctl32_common.vcx ADDITIVE
SET CLASSLIB TO ctl32_structs.vcx ADDITIVE
SET CLASSLIB TO ctl32_progressbar.vcx ADDITIVE
SET CLASSLIB TO ctl32_balloontip.vcx ADDITIVE
SET CLASSLIB TO ocriterii.vcx ADDITIVE
SET CLASSLIB TO oavize.vcx ADDITIVE
SET CLASSLIB TO onomenclatoare2 ADDITIVE
SET CLASSLIB TO wwdialogs.vcx ADDITIVE
SET CLASSLIB TO oimportxml.vcx ADDITIVE
SET CLASSLIB TO excelxml.vcx ADDITIVE
SET CLASSLIB TO orapoarte_obinv.vcx ADDITIVE
DO DcLog WITH 'SET CLASSLIB OK'
*----- PROCEDURI (mock-uri PRIMELE, ui_harness la final) -----
SET PROCEDURE TO PROCEDURI
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_cauta_nom_articole.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\mock_caut_valuta.prg" ADDITIVE
SET PROCEDURE TO acces_meniu ADDITIVE
SET PROCEDURE TO cauta_alfa ADDITIVE
SET PROCEDURE TO pmenu ADDITIVE
SET PROCEDURE TO proceduri_comune ADDITIVE
SET PROCEDURE TO quitapp ADDITIVE
SET PROCEDURE TO init_program ADDITIVE
SET PROCEDURE TO oproceduri_listari.prg ADDITIVE
SET PROCEDURE TO oproceduri_configurare.prg ADDITIVE
SET PROCEDURE TO oproceduri_articole.prg ADDITIVE
SET PROCEDURE TO oproceduri_retete.prg ADDITIVE
SET PROCEDURE TO orapoarte.prg ADDITIVE
SET PROCEDURE TO mesaje ADDITIVE
SET PROCEDURE TO oserii_numere.prg ADDITIVE
SET PROCEDURE TO oexport.prg ADDITIVE
SET PROCEDURE TO wwConfig.prg ADDITIVE
SET PROCEDURE TO proceduri_rapoarte.prg ADDITIVE
SET PROCEDURE TO OPROCEDURI_CURS.PRG ADDITIVE
SET PROCEDURE TO validare.prg ADDITIVE
SET PROCEDURE TO GENCURSOR.PRG ADDITIVE
SET PROCEDURE TO OPROCEDURI_COMUNE.PRG ADDITIVE
SET PROCEDURE TO OINIT_OPTIUNI.PRG ADDITIVE
SET PROCEDURE TO updateserver.prg ADDITIVE
SET PROCEDURE TO oinainte_de.prg ADDITIVE
SET PROCEDURE TO ooperatii_comune.prg ADDITIVE
SET PROCEDURE TO Ocompensari.PRG ADDITIVE
SET PROCEDURE TO OPROCEDURI_aMS.PRG ADDITIVE
SET PROCEDURE TO oproceduri_rulaje ADDITIVE
SET PROCEDURE TO oproceduri_stocuri ADDITIVE
SET PROCEDURE TO OINTRODUCERI ADDITIVE
SET PROCEDURE TO oHeader.prg ADDITIVE
SET PROCEDURE TO proceduri_excel.PRG ADDITIVE
SET PROCEDURE TO onomenclatoare.PRG ADDITIVE
SET PROCEDURE TO osecurity ADDITIVE
SET PROCEDURE TO ocautare ADDITIVE
SET PROCEDURE TO orefaceri ADDITIVE
SET PROCEDURE TO ofacturare_comun.PRG ADDITIVE
SET PROCEDURE TO ofacturare_stoc.PRG ADDITIVE
SET PROCEDURE TO oproceduri_casademarcat ADDITIVE
SET PROCEDURE TO oproceduri_casa_marcat_e500 ADDITIVE
SET PROCEDURE TO oproceduri_casa_marcat_mp500 ADDITIVE
SET PROCEDURE TO oproceduri_util.prg ADDITIVE
SET PROCEDURE TO wwxmlhttp.prg ADDITIVE
SET PROCEDURE TO ini.prg ADDITIVE
SET PROCEDURE TO odocumente.prg ADDITIVE
SET PROCEDURE TO regex.prg ADDITIVE
SET PROCEDURE TO wwutils.prg ADDITIVE
SET PROCEDURE TO inchidere_k ADDITIVE
SET PROCEDURE TO iniacces.prg ADDITIVE
SET PROCEDURE TO oupdate.prg ADDITIVE
SET PROCEDURE TO procese.prg ADDITIVE
SET PROCEDURE TO version.prg ADDITIVE
SET PROCEDURE TO xmlaccess.prg ADDITIVE
SET PROCEDURE TO xmlparser.prg ADDITIVE
SET PROCEDURE TO filebringer.prg ADDITIVE
SET PROCEDURE TO wwcodeupdate.prg ADDITIVE
SET PROCEDURE TO wwhttp.prg ADDITIVE
SET PROCEDURE TO xdate.prg ADDITIVE
SET PROCEDURE TO ofacturare.prg ADDITIVE
SET PROCEDURE TO oproceduri_obinv.prg ADDITIVE
SET PROCEDURE TO oproceduri_facturare.prg ADDITIVE
SET PROCEDURE TO email.prg ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\ui_harness.prg" ADDITIVE
DO DcLog WITH 'SET PROCEDURE OK'
*----- goMockValuta (contract vechi, folosit ca fallback) + goMockValutaCoada (contract nou,
* coada FIFO - pregatit aici pentru cand mock_caut_valuta.prg va fi actualizat separat;
* acest test NU invoca picker-ul cmdValuta/cmdDviValuta.Click, seteaza id_valuta/curs
* direct pe dialog, ca in testele existente). -----
PUBLIC goMockValuta, goMockValutaCoada
goMockValuta = CREATEOBJECT('Custom')
goMockValuta.AddProperty('id_valuta', 978)
goMockValuta.AddProperty('nume_val', 'EUR')
goMockValutaCoada = CREATEOBJECT('Collection')
LOCAL loValFact, loValDvi
loValFact = CREATEOBJECT('Custom')
loValFact.AddProperty('id_valuta', 978)
loValFact.AddProperty('nume_val', 'EUR')
goMockValutaCoada.Add(loValFact)
loValDvi = CREATEOBJECT('Custom')
loValDvi.AddProperty('id_valuta', 1)
loValDvi.AddProperty('nume_val', 'RON')
goMockValutaCoada.Add(loValDvi)
*----- Globale -----
PUBLIC gnPc, gnPval, gnPcant, gnPpret, gnPPretval, gnPCurs, gnPVal, gnPPretV, gnPPretVal
STORE 2 TO gnPc, gnPval, gnPVal
gnPcant = 3
STORE 4 TO gnPpret, gnPPretval, gnPPretVal, gnPPretV, gnPCurs
PUBLIC gl406, gcS, gnAn, gnLuna, gnIdFirma, gnIdSucursala, gcAcces, gcFirma
gl406 = .T.
gcS = 'CONTAFIN'
gnAn = YEAR(DATE())
gnLuna = MONTH(DATE())
gnIdFirma = 110
gnIdSucursala = 110
gcAcces = "1;2;3;4;5;6;7;8;"
gcFirma = gcS
PUBLIC nror(65000)
PUBLIC gnButon
STORE 2 TO gnButon
PUBLIC gcMockArtCodmat, gcMockAcontCrt
gcMockArtCodmat = ''
gcMockAcontCrt = ''
PUBLIC gnMockRaspuns
gnMockRaspuns = 6
PUBLIC goExecutor, goApp
goExecutor = CREATEOBJECT('dummyexecutor')
goApp = CREATEOBJECT('dummyapp')
*----- poAct: antetul notei (moneda principala EUR, curs 5.23) -----
PUBLIC poAct
poAct = CREATEOBJECT('Custom')
poAct.AddProperty('nume_val', 'EUR')
poAct.AddProperty('curs', 5.23)
poAct.AddProperty('proc_tva', 1.21)
poAct.AddProperty('nnir', 0)
poAct.AddProperty('id_valuta', 978)
poAct.AddProperty('id_fdoc', 1)
poAct.AddProperty('fdoc', 'Factura')
poAct.AddProperty('id_partc', 601)
poAct.AddProperty('partc', 'RAJA')
poAct.AddProperty('serie_act', '')
poAct.AddProperty('dataact', DATE())
poAct.AddProperty('tva_incasare', 0)
poAct.AddProperty('id_set', 1)
poAct.AddProperty('id_gestin', 1)
*----- jtva_coloane2 / saft_taxtable: perechi reale 21% -----
IF USED('jtva_coloane2')
USE IN ('jtva_coloane2')
ENDIF
CREATE CURSOR jtva_coloane2 (ordine N(8), id_jtva_coloana N(14), denumire C(100), ;
jc N(1), jv N(1), afisat N(1), coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14))
INSERT INTO jtva_coloane2 VALUES (0, 0, '', 0, 0, 1, '', '', 0, 0)
INSERT INTO jtva_coloane2 VALUES (1, 208, 'ACH. INT. 21%', 1, 0, 1, 'RO21B', 'RO21T', 21, 209)
INSERT INTO jtva_coloane2 VALUES (2, 209, 'TVA ACH. INT. 21%', 1, 0, 1, 'RO21T', '', 21, 0)
INSERT INTO jtva_coloane2 VALUES (3, 220, 'ACH. IMP. 21%', 1, 0, 1, 'FO21B', 'FO21T', 21, 221)
INSERT INTO jtva_coloane2 VALUES (4, 221, 'TVA ACH. IMP. 21%', 1, 0, 1, 'FO21T', '', 21, 0)
IF USED('saft_taxtable')
USE IN ('saft_taxtable')
ENDIF
CREATE CURSOR saft_taxtable (taxname C(250) NULL, typename C(250) NULL, taxcode N(6) NULL, ;
taxtype N(3) NULL, descriere C(250) NULL, tip C(100) NULL, descriere_tip C(250) NULL, ;
procent_taxa N(7,2) NULL, procent_prorata N(7,2) NULL, inactiv N(1) NULL, tva N(1) NULL, ;
wht N(1) NULL, tva_achizitii N(1) NULL, tva_livrari N(1) NULL)
INDEX ON taxcode TAG taxcode
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('', 0, '', 0, 1, 1, 1, 1)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301204-Import de bunuri cota 21%', 301204, '', 21, 1, 0, 1, 0)
DO CreeazaIntrodc WITH 'introdc'
DO CreeazaIntrodc WITH 'introdc_sablon'
INSERT INTO introdc_sablon (scd, scc, cu_tva, ordine, id_set, participa_valuta, tip_rand, ;
id_jtva_coloana, ptva, explicatie_tva) ;
VALUES ('371', '401', 1, 1, 1, .T., 'B', 208, 21, 'ACH. INT. 21%')
INSERT INTO introdc_sablon (scd, scc, cu_tva, ordine, id_set, participa_valuta, tip_rand, ;
id_jtva_coloana, ptva, explicatie_tva) ;
VALUES ('4426', '401', 1, 2, 1, .T., 'T', 209, 21, 'TVA ACH. INT. 21%')
GO TOP IN introdc_sablon
DO CreeazaRulTemp
INSERT INTO rul_temp (denumire, codmat, cant, pret, pret_lei, cont, cota_tva) ;
VALUES ('PLACEHOLDER', 'PH', 1, 1, 1, '371', 21)
*-- index ord_doc INAINTE de CREATEOBJECT (capcana p, docs/testare-ui-vfp.md)
SELECT introdc
INDEX ON Str(Nvl(nr_doc,0),8) + Icase(tip_rand='B','1', tip_rand='S','2', tip_rand='G','3', tip_rand='T','4', tip_rand='D','5', '6') + Padr(Nvl(scd,''),10) TAG ord_doc
SET ORDER TO ord_doc
DO DcLog WITH 'cursoare pregatite, CREATEOBJECT(import_nota, .F.)'
PUBLIC goObj
goObj = CREATEOBJECT('IMPORT_nota', .F.)
IF VARTYPE(goObj) <> 'O'
DO DcLog WITH 'FAIL: instantiere import_nota'
DO HarnessDone WITH 'done-error'
QUIT
ENDIF
goObj.lDialogAratat = .T.
goObj.oact = poAct
goObj.lSpargeSecundare = .F.
goObj.WindowType = 0
goObj.Visible = .T.
goObj.Show()
goObj.WindowState = 2
DOEVENTS FORCE
SELECT rul_temp
ZAP
goObj.gridart.Refresh()
DOEVENTS FORCE
PRIVATE pnAsserts, pnPass
STORE 0 TO pnAsserts, pnPass
*========================= DOC1: FACTURA EUR + TVA DVI in RON =========================
PUBLIC goDlg, goT, gcDocKey1
DO AdaugaDoc1
DO HarnessStep WITH 0, 'dupa AdaugaDoc1: introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri'
SELECT introdc
LOCATE FOR Nvl(rand_dvi,0) = 1
=Assert3('1-rand T-DVI gasit (rand_dvi=1)', IIF(FOUND(),1,0), 1)
IF FOUND()
gcDocKey1 = ALLTRIM(NVL(doc_key,''))
DO DcLog WITH 'T-DVI: doc_key=[' + gcDocKey1 + '] suma=' + TRANSFORM(suma) + ' in_valuta=' + TRANSFORM(NVL(in_valuta,0)) + ' participa_valuta=' + TRANSFORM(participa_valuta) + ' valuta_proprie=' + TRANSFORM(NVL(valuta_proprie,0))
=Assert3('2-T-DVI.in_valuta=0', NVL(in_valuta,0), 0)
=Assert3('3-T-DVI.participa_valuta=.F.', IIF(participa_valuta,1,0), 0)
=Assert3('4-T-DVI.valuta_proprie=1', NVL(valuta_proprie,0), 1)
=Assert3('5-T-DVI.id_valuta=0', NVL(id_valuta,0), 0)
=Assert3('6-T-DVI.curs=0', NVL(curs,0), 0)
=AssertStr('7-T-DVI.nume_val=""', ALLTRIM(NVL(nume_val,'?')), '')
=Assert3('8-T-DVI.suma=1098.30 (baza*cota auto, nemanual)', suma, 1098.30)
=Assert3('9-T-DVI.mod_manual=0 (valoare auto)', NVL(mod_manual,0), 0)
ELSE
DO DcLog WITH ' FAIL: nu exista rand T-DVI - sar restul verificarilor dependente'
ENDIF
*========================= GARDA do_executa (nu rescrie T protejat) =========================
goObj.do_executa()
DOEVENTS FORCE
SELECT introdc
LOCATE FOR Nvl(rand_dvi,0) = 1
=Assert3('10-dupa do_executa(): T-DVI.suma neschimbata (1098.30)', IIF(FOUND(),suma,-1), 1098.30)
*========================= GARDA recalc_tva_document (nu rescrie T protejat) =========================
IF !EMPTY(gcDocKey1)
TRY
goObj.recalc_tva_document(gcDocKey1)
CATCH TO loExcRtd
DO DcLog WITH 'INFO recalc_tva_document a aruncat eroare (poate nu accepta parametru direct): ' + loExcRtd.Message
ENDTRY
DOEVENTS FORCE
SELECT introdc
LOCATE FOR Nvl(rand_dvi,0) = 1
=Assert3('11-dupa recalc_tva_document(): T-DVI.suma neschimbata (1098.30)', IIF(FOUND(),suma,-1), 1098.30)
ELSE
pnAsserts = pnAsserts + 1
DO DcLog WITH ' FAIL 11: gcDocKey1 gol, nu pot apela recalc_tva_document'
ENDIF
*========================= SINCRONIZARE completa (pipeline complet) =========================
LOCAL llEroareSync
llEroareSync = .F.
TRY
goObj.sincronizeaza()
CATCH TO loExcS1
llEroareSync = .T.
DO DcLog WITH 'EROARE la sincronizeaza() ' + TRANSFORM(loExcS1.ErrorNo) + ' [' + loExcS1.Message + '] in ' + loExcS1.Procedure + ':' + TRANSFORM(loExcS1.LineNo)
ENDTRY
DOEVENTS FORCE
=Assert3('12-sincronizeaza() fara eroare', IIF(llEroareSync,0,1), 1)
SELECT introdc
LOCATE FOR Nvl(rand_dvi,0) = 1
=Assert3('13-dupa sincronizeaza(): rand T-DVI inca gasit', IIF(FOUND(),1,0), 1)
IF FOUND()
=Assert3('14-dupa sincronizeaza(): T-DVI.suma neschimbata (1098.30)', suma, 1098.30)
=Assert3('15-dupa sincronizeaza(): T-DVI.valuta_proprie ramane 1', NVL(valuta_proprie,0), 1)
=Assert3('16-dupa sincronizeaza(): T-DVI.participa_valuta ramane .F.', IIF(participa_valuta,1,0), 0)
ELSE
pnAsserts = pnAsserts + 3
DO DcLog WITH ' FAIL 14-16: T-DVI a disparut dupa sincronizare'
ENDIF
DO HarnessStep WITH 1, 'dupa garzi executie/recalc/sincronizare - vezi log'
*========================= FOOTER TVA VALUTA: participa_valuta exclude T-DVI din ntva_val =========================
*-- injectez artificial un suma_val nenul pe T-DVI (bypass motor) - daca filtrul pe
*-- participa_valuta e corect, ntva_val NU se schimba fata de o rulare fara injectie.
LOCAL lnNtvaValInainte, lnNtvaValDupa
goObj.recalculeaza()
lnNtvaValInainte = goObj.ntva_val
SELECT introdc
LOCATE FOR Nvl(rand_dvi,0) = 1
IF FOUND()
REPLACE suma_val WITH 999.99
goObj.recalculeaza()
lnNtvaValDupa = goObj.ntva_val
DO DcLog WITH 'FOOTER: ntva_val inainte=' + TRANSFORM(lnNtvaValInainte) + ' dupa injectie suma_val=999.99 pe T-DVI: ' + TRANSFORM(lnNtvaValDupa)
=Assert3('17-footer ntva_val NU include suma_val injectata pe T-DVI (participa_valuta=.F.)', ABS(lnNtvaValDupa - lnNtvaValInainte), 0)
*-- recalculeaza() e agregare read-only dar scaneaza cu SUM/CALCULATE (scope ALL), care
*-- muta pointerul de inregistrare la EOF - re-LOCATE inainte de REPLACE, altfel reset-ul
*-- de mai jos rateaza randul T-DVI (ramane cu suma_val=999.99 injectat mai sus).
LOCATE FOR Nvl(rand_dvi,0) = 1
REPLACE suma_val WITH 0
goObj.recalculeaza()
ELSE
pnAsserts = pnAsserts + 1
DO DcLog WITH ' FAIL 17: T-DVI negasit pentru testul de footer'
ENDIF
DO HarnessStep WITH 2, 'footer TVA valuta verificat - vezi log'
*========================= IMUNITATE LA SCHIMBAREA CURSULUI FACTURII (copiaza_valoare) =========================
SELECT introdc
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND tip_rand == 'B'
=Assert3('18-rand B gasit pentru schimbare curs', IIF(FOUND(),1,0), 1)
IF FOUND()
goObj.grid1.cCurs.text1.Value = 6.00
goObj.grid1.cCurs.text1.Valid()
DOEVENTS FORCE
ENDIF
SELECT introdc
LOCATE FOR Nvl(rand_dvi,0) = 1
IF FOUND()
=Assert3('19-dupa schimbare curs factura: T-DVI.curs ramane 0', NVL(curs,0), 0)
=Assert3('20-dupa schimbare curs factura: T-DVI.suma_val ramane 0', NVL(suma_val,0), 0)
=Assert3('21-dupa schimbare curs factura: T-DVI.suma neschimbata (1098.30)', suma, 1098.30)
ELSE
pnAsserts = pnAsserts + 3
DO DcLog WITH ' FAIL 19-21: T-DVI negasit dupa schimbare curs factura'
ENDIF
SELECT introdc
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND tip_rand == 'B'
IF FOUND()
=Assert3('22-randul B a primit noul curs (6.00, propagare normala)', curs, 6.00)
ENDIF
DO HarnessStep WITH 3, 'imunitate curs verificata - vezi log'
*========================= DEBIFARE in_valuta LA NIVEL DE DOCUMENT, CU T PROTEJAT =========================
SELECT introdc
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND tip_rand == 'B'
=Assert3('23-rand B gasit pentru debifare in_valuta', IIF(FOUND(),1,0), 1)
IF FOUND()
goObj.grid1.cInValuta.check1.Value = 0
goObj.grid1.cInValuta.check1.Valid()
=Assert3('24-armare lSyncPending dupa debifare (pre-DOEVENTS)', IIF(goObj.lSyncPending,1,0), 1)
DOEVENTS FORCE
=Assert3('25-sync consumat dupa debifare', IIF(goObj.lSyncPending,1,0), 0)
ENDIF
LOCAL lnCntBSGolite
lnCntBSGolite = 0
SELECT introdc
SCAN FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND INLIST(tip_rand,'B','S')
lnCntBSGolite = lnCntBSGolite + 1
=Assert3('26.'+TRANSFORM(RECNO())+'-B/S.in_valuta=0 dupa debifare', NVL(in_valuta,0), 0)
=Assert3('27.'+TRANSFORM(RECNO())+'-B/S.curs=0 dupa debifare', NVL(curs,0), 0)
ENDSCAN
=Assert3('28-cel putin un rand B/S golit', IIF(lnCntBSGolite>0,1,0), 1)
SELECT introdc
LOCATE FOR Nvl(rand_dvi,0) = 1
IF FOUND()
=Assert3('29-T-DVI ramane in_valuta=0 dupa debifare document (nu s-a schimbat)', NVL(in_valuta,0), 0)
=Assert3('30-T-DVI ramane valuta_proprie=1 dupa debifare document (nu se reseteaza)', NVL(valuta_proprie,0), 1)
=Assert3('31-T-DVI.suma neschimbata (1098.30) dupa debifare document', suma, 1098.30)
ELSE
pnAsserts = pnAsserts + 3
DO DcLog WITH ' FAIL 29-31: T-DVI negasit dupa debifare document'
ENDIF
DO HarnessStep WITH 4, 'debifare in_valuta cu T protejat verificata - vezi log'
*========================= UNESTE_DOCUMENT CU RAND T PROTEJAT (cursor izolat, construit direct) =========================
DO TestUnesteDocumentCuProtejat
*========================= IDENTITATE PROPRIE PE RANDUL DVI (cursor izolat, construit direct) =========================
DO TestIdentitateDviProtejata
DO DcLog WITH 'REZULTAT: ' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' assert-uri PASS'
IF pnPass = pnAsserts
DO DcLog WITH 'REZULTAT: PASS (' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ')'
ELSE
DO DcLog WITH 'REZULTAT: FAIL (' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' assert-uri PASS)'
ENDIF
DO HarnessStep WITH 5, 'final: ' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' PASS'
DO HarnessDone WITH 'done'
CATCH TO loExc
DO DcLog WITH 'CATCH ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']'
DO HarnessDone WITH 'done-error'
ENDTRY
QUIT
*==================================================================================
PROCEDURE AdaugaDoc1
*-- FACTURA 15000 RAJA, 1000 EUR curs 5.23 (5230 lei), TVA pe DVI ('D'): DVI 101 BIROUL
*-- VAMAL, tva 1098.30 lei, dar platita in RON (fara valuta proprie DVI) - diferita de
*-- valuta facturii (EUR) => valuta_proprie=1 pe randul T rezultat.
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = 15000
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 601
goDlg.cPartener = 'RAJA'
goDlg.cExplicatia = 'Import marfa RAJA'
goDlg.nSuma = 1000
goDlg.nSumaLei = 0
goDlg.nCurs = 5.23
goDlg.nIdValuta = 978
goDlg.cValuta = 'EUR'
goDlg.nIdExplicatieTva = 220
goDlg.cExplicatieTva = 'ACH. IMP. 21%'
goDlg.optTipTva.Value = 2 && D = DVI
goDlg.chkInValutaCont.Value = 1
goDlg.chkParticipaValuta.Value = 1
goDlg.cSerieDvi = ''
goDlg.nNractDvi = 101
goDlg.dDviData = DATE()
goDlg.nIdFdocDVI = 2
goDlg.cFelDocDvi = 'DVI'
goDlg.nDviIdPartener = 900
goDlg.cDviPartener = 'BIROUL VAMAL'
goDlg.nDviTvaLei = 1098.30
goDlg.nDviTvaVal = 0
*-- F1 NOU: valuta/curs proprii DVI - RON (fara valuta), explicit diferite de factura (EUR)
goDlg.nDviIdValuta = 0
goDlg.cDviValuta = ''
goDlg.nDviCurs = 0
goDlg.actualizeaza_stare_dvi()
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO DcLog WITH 'DOC1: valideaza = ' + TRANSFORM(goDlg.valideaza())
DO ConstruiesteToDlgF1F2
DO DcLog WITH 'DOC1: do_adauga_factura = ' + TRANSFORM(goObj.do_adauga_factura(goT))
goDlg.Hide()
DOEVENTS FORCE
ENDPROC
PROCEDURE ConstruiesteToDlgF1F2
*-- toDlg construit INLINE (capcana l) - camp de baza + extensiile F1 (dvi_*) si F2 (discount,
*-- neutre in acest test). Deciderul valutar al DVI e dvi_in_valuta (nu dvi_tva_val).
goT = CREATEOBJECT('Empty')
=ADDPROPERTY(goT,'serie_act',ALLTRIM(NVL(goDlg.cSerieAct,'')))
=ADDPROPERTY(goT,'nract',goDlg.nNract)
=ADDPROPERTY(goT,'dataact',goDlg.dDataAct)
=ADDPROPERTY(goT,'fdoc',goDlg.cFelDoc)
=ADDPROPERTY(goT,'id_fdoc',goDlg.nIdFdoc)
=ADDPROPERTY(goT,'id_partc',goDlg.nIdPartener)
=ADDPROPERTY(goT,'partc',goDlg.cPartener)
=ADDPROPERTY(goT,'explicatia',ALLTRIM(NVL(goDlg.cExplicatia,'')))
=ADDPROPERTY(goT,'suma',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,IIF(goDlg.nSumaLei<>0,goDlg.nSumaLei,ROUND(goDlg.nSuma*goDlg.nCurs,gnPC)),goDlg.nSuma))
=ADDPROPERTY(goT,'suma_val',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,goDlg.nSuma,0))
=ADDPROPERTY(goT,'in_valuta',goDlg.chkInValutaCont.Value)
=ADDPROPERTY(goT,'participa_valuta',(goDlg.chkParticipaValuta.Value=1))
=ADDPROPERTY(goT,'id_valuta',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nIdValuta,0))
=ADDPROPERTY(goT,'curs',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nCurs,0))
=ADDPROPERTY(goT,'nume_val',IIF(goDlg.chkInValutaCont.Value=1,ALLTRIM(NVL(goDlg.cValuta,'')),''))
=ADDPROPERTY(goT,'cTipTva',IIF(goDlg.optTipTva.Value=1,'F',IIF(goDlg.optTipTva.Value=2,'D','N')))
=ADDPROPERTY(goT,'id_jtva_coloana',goDlg.nIdExplicatieTva)
=ADDPROPERTY(goT,'dvi_serie',CHRTRAN(ALLTRIM(NVL(goDlg.cSerieDvi,'')),CHR(34),''))
=ADDPROPERTY(goT,'dvi_nract',goDlg.nNractDvi)
=ADDPROPERTY(goT,'dvi_dataact',goDlg.dDviData)
=ADDPROPERTY(goT,'dvi_id_fdoc',goDlg.nIdFdocDVI)
=ADDPROPERTY(goT,'dvi_fdoc',goDlg.cFelDocDvi)
=ADDPROPERTY(goT,'dvi_id_partc',goDlg.nDviIdPartener)
=ADDPROPERTY(goT,'dvi_partc',goDlg.cDviPartener)
=ADDPROPERTY(goT,'dvi_scc','401')
=ADDPROPERTY(goT,'dvi_tva_lei',goDlg.nDviTvaLei)
=ADDPROPERTY(goT,'dvi_tva_val',goDlg.nDviTvaVal)
*-- F1 NOU: valuta/curs proprii ale DVI (deciderul e dvi_in_valuta, nu dvi_tva_val)
=ADDPROPERTY(goT,'dvi_in_valuta',!(EMPTY(goDlg.cDviValuta) OR UPPER(ALLTRIM(NVL(goDlg.cDviValuta,'')))=='RON'))
=ADDPROPERTY(goT,'dvi_id_valuta',goDlg.nDviIdValuta)
=ADDPROPERTY(goT,'dvi_curs',goDlg.nDviCurs)
=ADDPROPERTY(goT,'dvi_nume_val',ALLTRIM(NVL(goDlg.cDviValuta,'')))
=ADDPROPERTY(goT,'dvi_valuta_proprie',IIF(!(EMPTY(goDlg.cDviValuta) OR UPPER(ALLTRIM(NVL(goDlg.cDviValuta,'')))=='RON') OR !(EMPTY(goDlg.cValuta) OR UPPER(ALLTRIM(NVL(goDlg.cValuta,'')))=='RON'),IIF(goDlg.nDviIdValuta<>goDlg.nIdValuta OR goDlg.nDviCurs<>goDlg.nCurs,1,0),0))
*-- Runda32 (neutru in acest test - fara discount)
=ADDPROPERTY(goT,'disc_baza_lei',0)
=ADDPROPERTY(goT,'disc_baza_val',0)
ENDPROC
PROCEDURE TestUnesteDocumentCuProtejat
*-- test izolat: cursor introdc construit DIRECT (nu prin dialog) cu un document ce are
*-- 2 randuri T "normale" (mod_manual=0, valuta_proprie=0, de comasat) + 1 rand T protejat
*-- (rand_dvi=1, valuta_proprie=1, mod_manual=0, NU trebuie comasat). Verifica ca
*-- uneste_document() lasa randul protejat intact si comaseaza doar restul.
LOCAL lcDocKeyX, lnCntTDupa
lcDocKeyX = 'X|900001|0|0'
SELECT introdc
APPEND BLANK
REPLACE tip_rand WITH 'S', scd WITH '371', scc WITH '401', suma WITH 1000, suma_val WITH 0, ;
nr_doc WITH 900001, nract WITH 900001, fdoc WITH 'Factura', doc_key WITH lcDocKeyX, ;
mod_manual WITH 0, rand_dvi WITH 0, valuta_proprie WITH 0
APPEND BLANK
REPLACE tip_rand WITH 'T', scd WITH '4426', scc WITH '401', suma WITH 100, suma_val WITH 0, ;
ptva WITH 21, nr_doc WITH 900001, nract WITH 900001, fdoc WITH 'Factura', doc_key WITH lcDocKeyX, ;
mod_manual WITH 0, rand_dvi WITH 0, valuta_proprie WITH 0
APPEND BLANK
REPLACE tip_rand WITH 'T', scd WITH '4426', scc WITH '4427', suma WITH 110, suma_val WITH 0, ;
ptva WITH 21, nr_doc WITH 900001, nract WITH 900001, fdoc WITH 'Factura', doc_key WITH lcDocKeyX, ;
mod_manual WITH 0, rand_dvi WITH 0, valuta_proprie WITH 0
APPEND BLANK
REPLACE tip_rand WITH 'T', scd WITH '4426', scc WITH '401', suma WITH 1098.30, suma_val WITH 0, ;
ptva WITH 21, nr_doc WITH 900001, nract WITH 101, fdoc WITH 'DVI', partc WITH 'BIROUL VAMAL', ;
doc_key WITH lcDocKeyX, mod_manual WITH 0, rand_dvi WITH 1, valuta_proprie WITH 1
TRY
goObj.uneste_document(PADR(lcDocKeyX, 80))
CATCH TO loExcU
DO DcLog WITH 'EROARE uneste_document ' + TRANSFORM(loExcU.ErrorNo) + ' [' + loExcU.Message + '] in ' + loExcU.Procedure + ':' + TRANSFORM(loExcU.LineNo)
ENDTRY
lnCntTDupa = 0
SELECT introdc
SCAN FOR ALLTRIM(NVL(doc_key,'')) == lcDocKeyX AND tip_rand == 'T'
lnCntTDupa = lnCntTDupa + 1
DO DcLog WITH 'UNESTE: rand T ramas rand_dvi=' + TRANSFORM(NVL(rand_dvi,0)) + ' valuta_proprie=' + TRANSFORM(NVL(valuta_proprie,0)) + ' suma=' + TRANSFORM(suma)
ENDSCAN
=Assert3('32-uneste_document: raman EXACT 2 randuri T (1 comasat + 1 protejat)', lnCntTDupa, 2)
SELECT introdc
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == lcDocKeyX AND tip_rand == 'T' AND Nvl(rand_dvi,0) = 1
=Assert3('33-uneste_document: randul protejat (rand_dvi=1) supravietuieste', IIF(FOUND(),1,0), 1)
IF FOUND()
=Assert3('34-uneste_document: randul protejat.suma neschimbata (1098.30)', suma, 1098.30)
=Assert3('35-uneste_document: randul protejat.valuta_proprie ramane 1', NVL(valuta_proprie,0), 1)
ELSE
pnAsserts = pnAsserts + 2
DO DcLog WITH ' FAIL 34-35: randul protejat negasit dupa uneste_document'
ENDIF
SELECT introdc
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == lcDocKeyX AND tip_rand == 'T' AND Nvl(rand_dvi,0) = 0
=Assert3('36-uneste_document: randul comasat (nemanual, nevaluta_proprie) exista', IIF(FOUND(),1,0), 1)
IF FOUND()
=Assert3('37-uneste_document: randul comasat.suma = 100+110 = 210', suma, 210)
ELSE
pnAsserts = pnAsserts + 1
DO DcLog WITH ' FAIL 37: randul comasat negasit dupa uneste_document'
ENDIF
ENDPROC
PROCEDURE TestIdentitateDviProtejata
*-- test izolat: randul DVI (rand_dvi=1) trebuie sa isi pastreze identitatea PROPRIE
*-- (nract, serie_act, partc, fdoc, id_fdoc) cand copiaza_valoare() propaga aceste campuri
*-- pe grupul doc_key; un rand NORMAL din acelasi grup trebuie sa PRIMEASCA valoarea noua
*-- (assert dublu per camp - altfel testul ar trece si daca propagarea s-ar strica de tot).
*-- Verifica si coerenta doc_key pe grup dupa fiecare propagare (toate 5 campuri sunt chei -
*-- llCheie regenereaza doc_key pe tot grupul, inclusiv pe randul protejat).
LOCAL lcDocKeyX, lnRecnoB, lcDocKeyCrt
lcDocKeyX = 'IDPROT|5001|1|601'
SELECT introdc
APPEND BLANK
REPLACE tip_rand WITH 'B', scd WITH '371', scc WITH '401', suma WITH 1000, ;
nr_doc WITH 950001, nract WITH 5001, serie_act WITH 'FACT', id_fdoc WITH 1, fdoc WITH 'Factura', ;
id_partc WITH 601, partc WITH 'FURNIZOR ORIGINAL', doc_key WITH lcDocKeyX, ;
mod_manual WITH 0, rand_dvi WITH 0, valuta_proprie WITH 0
APPEND BLANK
REPLACE tip_rand WITH 'S', scd WITH '4426', scc WITH '401', suma WITH 190, ;
nr_doc WITH 950001, nract WITH 5001, serie_act WITH 'FACT', id_fdoc WITH 1, fdoc WITH 'Factura', ;
id_partc WITH 601, partc WITH 'FURNIZOR ORIGINAL', doc_key WITH lcDocKeyX, ;
mod_manual WITH 0, rand_dvi WITH 0, valuta_proprie WITH 0
APPEND BLANK
REPLACE tip_rand WITH 'T', scd WITH '4426', scc WITH '401', suma WITH 95, ;
nr_doc WITH 950001, nract WITH 9001, serie_act WITH 'VAMA', id_fdoc WITH 2, fdoc WITH 'DVI', ;
id_partc WITH 900, partc WITH 'DIRECTIA VAMALA', doc_key WITH lcDocKeyX, ;
mod_manual WITH 0, rand_dvi WITH 1, valuta_proprie WITH 1
SELECT introdc
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == lcDocKeyX AND tip_rand == 'B'
=Assert3('38-IDP: randul B gasit pentru test identitate DVI', IIF(FOUND(),1,0), 1)
IF !FOUND()
pnAsserts = pnAsserts + 20
DO DcLog WITH ' FAIL 39-59: randul B negasit, sar restul testului de identitate DVI'
RETURN
ENDIF
lnRecnoB = RECNO()
*-- NOTA: introdc e cursor PARTAJAT intre scenariile fisierului - alte scenarii (AdaugaDoc1,
*-- TestUnesteDocumentCuProtejat) au deja propriile randuri rand_dvi=1/tip_rand='S' cu alt
*-- doc_key. Fiecare LOCATE de mai jos e SCOPAT pe lcDocKeyCrt (doc_key-ul CURENT al
*-- grupului, recalculat dupa fiecare propagare) - dublu rol: (a) evita sa gaseasca randul
*-- altui scenariu, (b) FOUND() dupa scopare e chiar dovada de coerenta - daca doc_key nu
*-- s-ar fi propagat uniform pe grup, randul n-ar mai fi gasit sub noul doc_key.
*-- 1. nract: 5001 -> 5002
GO lnRecnoB
REPLACE nract WITH 5002
goObj.copiaza_valoare('nract')
SELECT introdc
GO lnRecnoB
lcDocKeyCrt = ALLTRIM(NVL(doc_key,''))
=Assert3('39-IDP nract: B.nract=5002 (propriu, control)', nract, 5002)
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == lcDocKeyCrt AND Nvl(rand_dvi,0) = 1
=Assert3('40-IDP nract: DVI gasit sub doc_key curent (coerenta grup)', IIF(FOUND(),1,0), 1)
=Assert3('41-IDP nract: DVI.nract ramane 9001 (protejat)', NVL(nract,0), 9001)
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == lcDocKeyCrt AND tip_rand == 'S'
=Assert3('42-IDP nract: S gasit sub doc_key curent (coerenta grup)', IIF(FOUND(),1,0), 1)
=Assert3('43-IDP nract: S.nract=5002 (propagat pe randul normal)', NVL(nract,0), 5002)
*-- 2. serie_act: 'FACT' -> 'FACT2'
GO lnRecnoB
REPLACE serie_act WITH 'FACT2'
goObj.copiaza_valoare('serie_act')
GO lnRecnoB
lcDocKeyCrt = ALLTRIM(NVL(doc_key,''))
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == lcDocKeyCrt AND Nvl(rand_dvi,0) = 1
=Assert3('44-IDP serie_act: DVI gasit sub doc_key curent (coerenta grup)', IIF(FOUND(),1,0), 1)
=AssertStr('45-IDP serie_act: DVI.serie_act ramane VAMA (protejat)', ALLTRIM(NVL(serie_act,'')), 'VAMA')
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == lcDocKeyCrt AND tip_rand == 'S'
=Assert3('46-IDP serie_act: S gasit sub doc_key curent (coerenta grup)', IIF(FOUND(),1,0), 1)
=AssertStr('47-IDP serie_act: S.serie_act=FACT2 (propagat)', ALLTRIM(NVL(serie_act,'')), 'FACT2')
*-- 3. partc: 'FURNIZOR ORIGINAL' -> 'FURNIZOR NOU'
GO lnRecnoB
REPLACE partc WITH 'FURNIZOR NOU'
goObj.copiaza_valoare('partc')
GO lnRecnoB
lcDocKeyCrt = ALLTRIM(NVL(doc_key,''))
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == lcDocKeyCrt AND Nvl(rand_dvi,0) = 1
=Assert3('48-IDP partc: DVI gasit sub doc_key curent (coerenta grup)', IIF(FOUND(),1,0), 1)
=AssertStr('49-IDP partc: DVI.partc ramane DIRECTIA VAMALA (protejat)', ALLTRIM(NVL(partc,'')), 'DIRECTIA VAMALA')
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == lcDocKeyCrt AND tip_rand == 'S'
=Assert3('50-IDP partc: S gasit sub doc_key curent (coerenta grup)', IIF(FOUND(),1,0), 1)
=AssertStr('51-IDP partc: S.partc=FURNIZOR NOU (propagat)', ALLTRIM(NVL(partc,'')), 'FURNIZOR NOU')
*-- 4. fdoc: 'Factura' -> 'Factura Noua'
GO lnRecnoB
REPLACE fdoc WITH 'Factura Noua'
goObj.copiaza_valoare('fdoc')
GO lnRecnoB
lcDocKeyCrt = ALLTRIM(NVL(doc_key,''))
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == lcDocKeyCrt AND Nvl(rand_dvi,0) = 1
=Assert3('52-IDP fdoc: DVI gasit sub doc_key curent (coerenta grup)', IIF(FOUND(),1,0), 1)
=AssertStr('53-IDP fdoc: DVI.fdoc ramane DVI (protejat)', ALLTRIM(NVL(fdoc,'')), 'DVI')
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == lcDocKeyCrt AND tip_rand == 'S'
=Assert3('54-IDP fdoc: S gasit sub doc_key curent (coerenta grup)', IIF(FOUND(),1,0), 1)
=AssertStr('55-IDP fdoc: S.fdoc=Factura Noua (propagat)', ALLTRIM(NVL(fdoc,'')), 'Factura Noua')
*-- 5. id_fdoc: 1 -> 3
GO lnRecnoB
REPLACE id_fdoc WITH 3
goObj.copiaza_valoare('id_fdoc')
GO lnRecnoB
lcDocKeyCrt = ALLTRIM(NVL(doc_key,''))
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == lcDocKeyCrt AND Nvl(rand_dvi,0) = 1
=Assert3('56-IDP id_fdoc: DVI gasit sub doc_key curent (coerenta grup finala)', IIF(FOUND(),1,0), 1)
=Assert3('57-IDP id_fdoc: DVI.id_fdoc ramane 2 (protejat)', NVL(id_fdoc,0), 2)
LOCATE FOR ALLTRIM(NVL(doc_key,'')) == lcDocKeyCrt AND tip_rand == 'S'
=Assert3('58-IDP id_fdoc: S gasit sub doc_key curent (coerenta grup finala)', IIF(FOUND(),1,0), 1)
=Assert3('59-IDP id_fdoc: S.id_fdoc=3 (propagat)', NVL(id_fdoc,0), 3)
ENDPROC
PROCEDURE CreeazaRulTemp
IF USED('rul_temp')
USE IN ('rul_temp')
ENDIF
CREATE CURSOR rul_temp ( ;
id_rul N(20,0), an N(4,0), luna N(2,0), cod N(20,0);
, serie C(100), nnir N(20,0), id_articol N(10,0), denumire C(100);
, codmat C(50), codmatf C(50), codbare C(50), um C(20);
, id_gestiune N(5,0), nume_gestiune C(50), cgest C(20), nr_pag N(2,0);
, gestionar C(50), comisie_receptie1 C(50), comisie_receptie2 C(50), comisie_receptie3 C(50);
, cant N(14,3), cante N(14,3), cont C(10), acont C(20);
, pret N(18,4), tva N(18,4), valoare N(18,4), valtva N(18,4);
, proc_tva N(5,2), pretv N(18,4), pretvtva N(18,4), tvav N(18,4);
, valoarev N(18,4), valtvav N(18,4), proc_tvav N(5,2), adaos N(18,4);
, adaos_tva N(18,4), valoare_adaos N(18,4), valtva_adaos N(18,4), procent N(10,3);
, discunitar N(18,4), discount_tva N(18,4), valoare_discount N(18,4), valtva_discount N(18,4);
, proc_disc N(7,3), pretd N(14,4), curs N(18,4), id_valuta N(10,0);
, nume_val C(20), id_lucrare N(20,0), nrord C(100), id_responsabil N(10,0);
, nresp C(100), resp_marca N(18,4), dataact T, id_util N(5,0);
, util C(30), dataora T, id_sectie N(5,0), sectie C(50);
, csectie C(10), alcooltutun N(1,0), datain T, dataout T;
, id_fact N(20,0), id_gestiunec N(10,0), nume_gestiunec C(50), cgestc C(20);
, id_responsabilc N(5,0), id_reteta N(10,0), reteta C(50), nrespc C(100);
, respc_marca N(18,4), id_set N(20,0), id_tip_rulaj N(10,0), tip_rulaj C(50);
, id_obiect_depozit N(10,0), id_rul_aux N(10,0), nract N(20,0), serie_act C(10);
, dataoras T, id_utils N(10,0), lot C(30), adata_expirare T;
, id_sucursala N(5,0), sucursala C(250), id_part_rez N(10,0), part_rez C(100);
, id_lucrare_rez N(10,0), nrord_rez C(100), subgrupa C(100), grupa C(100);
, id_subgrupa N(5,0), id_grupa N(5,0), in_stoc N(1,0), in_crm N(1,0);
, id_furnizor N(10,0), furnizor C(100), id_jtva_coloana N(4,0), explicatie_tva C(100);
, taxcode N(6,0), taxname C(254), saft_procent N(18,4), codnc8 C(20);
, id_tara_origine N(4,0), cod_tara_origine C(5), tara_origine C(50), greutate N(12,4);
, fdoc C(30), id_fdoc N(18,4);
, pret_lei N(18,4), pret_val N(14,4), cota_tva N(6,2))
ENDPROC
PROCEDURE CreeazaIntrodc
*-- Runda30 (F1/pas2): coloane NOI rand_dvi N(1), valuta_proprie N(1) fata de structura veche.
LPARAMETERS tcAlias
IF USED(tcAlias)
USE IN (tcAlias)
ENDIF
CREATE CURSOR (tcAlias) ( ;
id_note N(14), explicatia C(100), scd C(10), ascd C(20), scc C(10), ascc C(20), ;
cu_tva N(1), id_set N(14), ordine N(8), in_valuta N(1), id_jtva_coloana N(14) NULL, ;
ptva N(6,2), explicatie_tva C(50), tipjurnal C(2), taxcode N(6), paymentcode C(9), ;
suma N(18,4), suma_val N(18,4), id_partd N(14), id_partc N(14), partd C(100), partc C(100), ;
id_fact N(14), id_factd N(14), id_factc N(14), pereched N(14), perechec N(14), ;
nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), expl_manual N(1), ;
scd_orig C(20), ascd_orig C(20), rand_dvi N(1), valuta_proprie N(1))
ENDPROC
FUNCTION RECCOUNT_ACTIVE
LPARAMETERS tcAlias
LOCAL lnSel, lnCnt
lnSel = SELECT()
SELECT (tcAlias)
COUNT TO lnCnt FOR !DELETED()
SELECT (lnSel)
RETURN lnCnt
ENDFUNC
PROCEDURE Assert3
LPARAMETERS tcLabel, tuActual, tuExpected
pnAsserts = pnAsserts + 1
IF ABS(NVL(tuActual,0) - tuExpected) < 0.02
pnPass = pnPass + 1
DO DcLog WITH ' PASS ' + tcLabel + ' (=' + TRANSFORM(tuActual) + ')'
ELSE
DO DcLog WITH ' FAIL ' + tcLabel + ' (actual=' + TRANSFORM(tuActual) + ' asteptat=' + TRANSFORM(tuExpected) + ')'
ENDIF
ENDPROC
PROCEDURE AssertStr
LPARAMETERS tcLabel, tcActual, tcExpected
pnAsserts = pnAsserts + 1
IF tcActual == tcExpected
pnPass = pnPass + 1
DO DcLog WITH ' PASS ' + tcLabel + ' (=[' + tcActual + '])'
ELSE
DO DcLog WITH ' FAIL ' + tcLabel + ' (actual=[' + tcActual + '] asteptat=[' + tcExpected + '])'
ENDIF
ENDPROC
PROCEDURE DcErr
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
DO DcLog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
ENDPROC
PROCEDURE DcLog
LPARAMETERS tcMsg
SET SAFETY OFF
LOCAL lcL
lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '')
STRTOFILE(lcL + tcMsg + CHR(13)+CHR(10), gcUILog)
ENDPROC
DEFINE CLASS dummyapp AS Custom
PROCEDURE ReadIni
LPARAMETERS tcSection, tcKey
RETURN ''
ENDPROC
PROCEDURE WriteIni
LPARAMETERS tcSection, tcKey, tcValue
RETURN .T.
ENDPROC
ENDDEFINE
DEFINE CLASS dummyexecutor AS Custom
cEroare = ''
PROCEDURE oExecute
LPARAMETERS tcSql, tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF 'VJTVA_COLOANE' $ UPPER(m.tcSql)
DO CreeazaJtvaColoaneView WITH m.tcCursor
RETURN 1
ENDIF
IF UPPER(ALLTRIM(m.tcCursor)) == 'RUL_TEMP'
CREATE CURSOR (m.tcCursor) (denumire C(100), codmat C(30), cant N(14,3), ;
pret_val N(18,4), pretd N(18,4), pret N(18,4), pret_lei N(18,4), cont C(10), ;
acont C(20), serie C(30), lot C(30), adata_expirare C(10), proc_disc N(6,2), cota_tva N(6,2))
RETURN 1
ENDIF
IF 'CONFIG_ANALITICE' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (camp_leg_prefix C(30), camp_leg_sufix C(30))
INSERT INTO (m.tcCursor) VALUES ('', '')
RETURN 1
ENDIF
IF 'FCONTURI_ANALITICE' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (acont C(20))
INSERT INTO (m.tcCursor) VALUES (IIF(TYPE('gcMockAcontCrt') = 'C', gcMockAcontCrt, ''))
RETURN 1
ENDIF
IF 'VPLCONT_ANALITIC' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (cont C(10), acont C(20))
INSERT INTO (m.tcCursor) VALUES ('371', '4')
RETURN 1
ENDIF
CREATE CURSOR (m.tcCursor) (id_temp N(1))
RETURN 1
ENDPROC
PROCEDURE oExecuta
LPARAMETERS tcSql, tcCursor
IF !EMPTY(m.tcCursor)
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF UPPER(m.tcCursor) == 'CJTVACOL4427'
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14))
ELSE
CREATE CURSOR (m.tcCursor) (id_temp N(1))
ENDIF
ENDIF
RETURN .T.
ENDPROC
PROCEDURE oSelect2Value
LPARAMETERS tcSql, toValue
toValue = ''
RETURN 1
ENDPROC
PROCEDURE oReset
ENDPROC
ENDDEFINE
PROCEDURE CreeazaJtvaColoaneView
LPARAMETERS tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14), denumire C(100), jc N(1), jv N(1), ;
coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14) NULL, afisat N(1), ;
id_jtva_ex N(14) NULL, id_jtva_neex N(14) NULL, ordine N(8), ;
taxcode N(6) NULL, taxcode_neexigibil N(6) NULL, taxcode_n50 N(6) NULL, ;
taxcode_n50_tvai N(6) NULL, taxcode_n100 N(6) NULL, taxcode_regularizare N(6) NULL, taxcode_tvai N(6) NULL)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, afisat, ordine, cota_tva) VALUES (0, '', 0, 0, 1, 0, 0)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (208, 'ACH. INT. 21%', 1, 0, 'RO21B', 21, 209, 1, 1, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (209, 'TVA ACH. INT. 21%', 1, 0, 'RO21T', 21, 1, 2, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (220, 'ACH. IMP. 21%', 1, 0, 'FO21B', 21, 221, 1, 3, 301204)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (221, 'TVA ACH. IMP. 21%', 1, 0, 'FO21T', 21, 1, 4, 301204)
ENDPROC

View File

@@ -0,0 +1,11 @@
# test_dvi_valuta_ron.ps1 - wrapper peste harness-ul generic pentru TVA DVI in RON (F1, runda30).
# powershell -ExecutionPolicy Bypass -File test_dvi_valuta_ron.ps1
$ErrorActionPreference = 'Stop'
$Teste = $PSScriptRoot
& (Join-Path (Split-Path $Teste -Parent) 'vfp_ui_harness.ps1') `
-TestPrg (Join-Path $Teste 'test_dvi_valuta_ron.prg') `
-Steps @('doc1_creat','garzi_executie','footer_valuta','imunitate_curs','debifare_document','final') `
-ShotsDir (Join-Path $Teste 'screenshots_dvi_valuta_ron') `
-SyncDir (Join-Path $Teste 'uisync_dvi_valuta_ron') `
-StepTimeoutSec 180 `
-ReadyTimeoutSec 180

View File

@@ -0,0 +1,951 @@
* test_e2e_dvi_ron_discount.prg
* Runda30 (F1+F2) + Runda32 (model B/G/T, un singur rand G): test e2e pe SCENARIUL EXACT cerut
* de Marius - factura de import in valuta (EUR), TVA DVI platit in RON (valuta proprie DVI,
* diferita de a facturii), discount financiar (doar baza, fara bifa), articole adaugate, apoi
* finalizare. Flux REAL: dialogul `import_adauga_factura` (nu insert direct in cursoare) +
* `do_adauga_articol()` real + `sincronizeaza()` real.
*
* IMPORTANT: toDlg (contractul pentru do_adauga_factura) se construieste INLINE, in programul
* PRINCIPAL, NU prin apelul `goDlg.construieste_todlg()` - capcana documentata deja in antetul
* `mock_caut_valuta.prg` ("CREATEOBJECT/ADDPROPERTY nu merg corect apelate dintr-o procedura in
* acest runtime"): confirmat prin diagnostic (28.07.2026) ca aceasta metoda arunca eroare 11
* ("argument invalid") pe PRIMUL Addproperty, universal, pe orice instanta (inclusiv virgina),
* dar EXACT ACELASI cod, apelat din programul principal cu goDlg.* in loc de This.*, functioneaza
* corect. NU incerca sa "repari" apeland metoda direct - vezi handoff_dvi_discount.md pentru
* dovezile complete (izolare fata de tip de date, mediu, mostenire de clasa, lungime de linie).
*
* Assert-uri rand cu rand pe `introdc` (sursa de adevar inainte de scrierea finala):
* - randul B (baza factura): scd=371, suma=5000.00 (1000 EUR x curs 5), suma_val=1000.00,
* in_valuta=1, id_valuta=978 (EUR), partener facturii;
* - randul T-DVI (rand_dvi=1): scd=4426/scc=401, suma=840.00 (baza NETA lei x 21% =
* (5000-1000)*21%, discountul scade baza DVI-ului), suma_val=0, in_valuta=0, id_valuta=0/
* curs=0/nume_val='' (normalizare RON->fara valuta pe randul scris, desi pe dialog RON are
* id real 1 - vezi conventia din handoff), participa_valuta=.F., partenerul vamal (DIRECTIA
* VAMALA), mod_manual=1 (valoarea NETA difera de auto-calculul brut baza*cota=1050.00 facut
* de do_adauga_factura la creare, deci randul e protejat de do_executa - vezi Runda32);
* - randul G (discount, un singur rand, model B/G/T): scd = scc-ul randului B (analitic
* mostenit), scc=767, suma=+1000.00, suma_val=+200.00 (POZITIV), id_partd = partenerul
* facturii (de pe creditul B), participa_valuta=.F., cu_tva=0, ptva=0;
* - pretul articolului (rul_temp) neafectat de discount: pret_lei=4000.00 (800 EUR x 5);
* - randul D (diferenta), daca apare, e informativ (best-effort - nu il forteaza scenariul);
* - totalurile din subsol (D4): txtftvalei/txtftvaval raman pe baza integrala (5000.00/
* 1000.00); Text2/Text3 (cu TVA) scad discountul (4840.00 = 5000+840-1000, respectiv
* 800.00 = 1000+0-200) - verificate imediat dupa Termin, inainte de a adauga articole
* (documentul nu e inca spart pe randuri S, B ramane intreg pentru un calcul curat).
*
* Acoperea si cerinta FINALA (Runda32): factura de import in valuta + discount + TVA pe DVI,
* cu assert-uri pe cele trei randuri (B/G/T) si pe totalurile din subsolul notei.
*
* PASUL FINAL "Terminat" (scrierea in `actactan` prin `import_nota.inainte_de_do_termin()`)
* SE RULEAZA (nu mai e sarit). Acel cod deschide `Do Form verificare` (formular MODAL real,
* `COMUN\ferestre\verificare.scx`, WindowType=1) - fara mock ar ramane blocat la nesfarsit.
* Testul foloseste un STUB `verificare.scx` dedicat, in `stub_verificare\` (langa acest test,
* NU peste formularul real) - form gol, `WindowType=0`, `Init` seteaza `gnButon=1` si
* `Return .F.` (impiedica instantierea => `Do Form` revine imediat, fara afisare). Stub-ul
* castiga rezolutia `Do Form` pentru ca `stub_verificare` e primul folder din `SET PATH`
* (inaintea lui `COMUN\FERESTRE`, unde e formularul real) - confirmat empiric: `SET PATH`
* rezolva pe ORDINEA din lista, primul folder cu fisierul cerut castiga.
* Assert-uri suplimentare rand cu rand pe `actactan` (structura reala, fara `tip_rand`/
* `rand_dvi` - randurile se identifica dupa scd/scc/semnul sumei): B (scd=371), T-DVI
* (scd=4426, suma POZITIVA), G (scc=767, un singur rand) + niciun rand fals de finalizare NIR.
*
* Rulare:
* powershell -ExecutionPolicy Bypass -File test_e2e_dvi_ron_discount.ps1
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET DECIMALS TO 4
SET NULLDISPLAY TO ''
CLOSE DATABASES
PUBLIC gcUILog, gcSyncDir
gcUILog = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\test_e2e_dvi_ron_discount_log.txt"
gcSyncDir = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\uisync_e2e_dvi_ron_discount\"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcUILog)
ON ERROR DO EeErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
TRY
LOCAL gcAppPath, lcPath
gcAppPath = "D:\ROA\ROAGEST\"
SET DEFAULT TO (gcAppPath)
lcPath = gcAppPath + 'COMUN\Utile\Teste\achizitie_import\stub_verificare;' + ;
gcAppPath + 'Date;' + gcAppPath + 'Include;' + gcAppPath + 'FERESTRE;' + ;
gcAppPath + 'GRAFICE;' + gcAppPath + 'CLASE;' + gcAppPath + 'MENIURI;' + ;
gcAppPath + 'PROGRAME;' + gcAppPath + 'RAPOARTE;' + gcAppPath + 'COMUN;' + ;
gcAppPath + 'COMUN\CLASE;' + gcAppPath + 'COMUN\FERESTRE;' + gcAppPath + 'COMUN\PROGRAME;' + ;
gcAppPath + 'COMUN\GRAFICE;' + gcAppPath + 'COMUN\RAPOARTE;' + gcAppPath + 'COMUN\MENIURI;' + ;
gcAppPath + 'COMUN\UTILE\GRIDEXTRAS;' + gcAppPath + 'COMUN\UTILE\CTL32;' + ;
gcAppPath + 'COMUN\UTILE\HPDF;' + gcAppPath + 'COMUN\UTILE\HPDF\REPORTOUTPUT;' + ;
gcAppPath + 'COMUN\UTILE\WEB;' + gcAppPath + 'COMUN\UTILE\EXCEL;' + ;
ADDBS(SUBSTR(gcAppPath,1,RAT([\],gcAppPath,2)))+[COMUNROA\]
SET PATH TO &lcPath ADDITIVE
DO EeLog WITH 'SET PATH OK'
*----- CLASE -----
SET CLASSLIB TO (gcAppPath + "comun\clase\appwiz") ADDITIVE
SET CLASSLIB TO GESTIUNI ADDITIVE
SET CLASSLIB TO CAUT ADDITIVE
SET CLASSLIB TO BAZA ADDITIVE
SET CLASSLIB TO comun ADDITIVE
SET CLASSLIB TO accessibility.vcx ADDITIVE
SET CLASSLIB TO messagebox ADDITIVE
SET CLASSLIB TO registry ADDITIVE
SET CLASSLIB TO cauta_alfa_forms.vcx ADDITIVE
SET CLASSLIB TO DECABAZA ADDITIVE
SET CLASSLIB TO onomenclatoare ADDITIVE
SET CLASSLIB TO stocuri.vcx ADDITIVE
SET CLASSLIB TO rulaje.vcx ADDITIVE
SET CLASSLIB TO ointroduceri ADDITIVE
SET CLASSLIB TO ointroduceri_web ADDITIVE
SET CLASSLIB TO ointroduceri_depozit ADDITIVE
SET CLASSLIB TO overificari ADDITIVE
SET CLASSLIB TO ferestre_oracle ADDITIVE
SET CLASSLIB TO ferestre_cere_date.vcx ADDITIVE
SET CLASSLIB TO configurare.vcx ADDITIVE
SET CLASSLIB TO serii_numere.vcx ADDITIVE
SET CLASSLIB TO omodificari.vcx ADDITIVE
SET CLASSLIB TO ocompensari.vcx ADDITIVE
SET CLASSLIB TO caut_ora ADDITIVE
SET CLASSLIB TO onote_contabile ADDITIVE
SET CLASSLIB TO otoolbar ADDITIVE
SET CLASSLIB TO bon_fisc ADDITIVE
SET CLASSLIB TO onom_articole ADDITIVE
SET CLASSLIB TO onom_retete ADDITIVE
SET CLASSLIB TO orapoarte ADDITIVE
SET CLASSLIB TO orapoarte_gestiuni ADDITIVE
SET CLASSLIB TO orapoarte_parametri ADDITIVE
SET CLASSLIB TO ONOM_CURS ADDITIVE
SET CLASSLIB TO ctl32_statusbar_fals.vcx ADDITIVE
SET CLASSLIB TO ctl32_common.vcx ADDITIVE
SET CLASSLIB TO ctl32_structs.vcx ADDITIVE
SET CLASSLIB TO ctl32_progressbar.vcx ADDITIVE
SET CLASSLIB TO ctl32_balloontip.vcx ADDITIVE
SET CLASSLIB TO ocriterii.vcx ADDITIVE
SET CLASSLIB TO oavize.vcx ADDITIVE
SET CLASSLIB TO onomenclatoare2 ADDITIVE
SET CLASSLIB TO wwdialogs.vcx ADDITIVE
SET CLASSLIB TO oimportxml.vcx ADDITIVE
SET CLASSLIB TO excelxml.vcx ADDITIVE
SET CLASSLIB TO orapoarte_obinv.vcx ADDITIVE
DO EeLog WITH 'SET CLASSLIB OK'
*----- PROCEDURI (mock-uri PRIMELE, ui_harness la final) -----
SET PROCEDURE TO PROCEDURI
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\mock_caut_valuta.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_cauta_nom_articole.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\mock_oscrie_in_fisiere.prg" ADDITIVE
SET PROCEDURE TO acces_meniu ADDITIVE
SET PROCEDURE TO cauta_alfa ADDITIVE
SET PROCEDURE TO pmenu ADDITIVE
SET PROCEDURE TO proceduri_comune ADDITIVE
SET PROCEDURE TO quitapp ADDITIVE
SET PROCEDURE TO init_program ADDITIVE
SET PROCEDURE TO oproceduri_listari.prg ADDITIVE
SET PROCEDURE TO oproceduri_configurare.prg ADDITIVE
SET PROCEDURE TO oproceduri_articole.prg ADDITIVE
SET PROCEDURE TO oproceduri_retete.prg ADDITIVE
SET PROCEDURE TO orapoarte.prg ADDITIVE
SET PROCEDURE TO mesaje ADDITIVE
SET PROCEDURE TO oserii_numere.prg ADDITIVE
SET PROCEDURE TO oexport.prg ADDITIVE
SET PROCEDURE TO wwConfig.prg ADDITIVE
SET PROCEDURE TO proceduri_rapoarte.prg ADDITIVE
SET PROCEDURE TO OPROCEDURI_CURS.PRG ADDITIVE
SET PROCEDURE TO validare.prg ADDITIVE
SET PROCEDURE TO GENCURSOR.PRG ADDITIVE
SET PROCEDURE TO OPROCEDURI_COMUNE.PRG ADDITIVE
SET PROCEDURE TO OINIT_OPTIUNI.PRG ADDITIVE
SET PROCEDURE TO updateserver.prg ADDITIVE
SET PROCEDURE TO oinainte_de.prg ADDITIVE
SET PROCEDURE TO ooperatii_comune.prg ADDITIVE
SET PROCEDURE TO Ocompensari.PRG ADDITIVE
SET PROCEDURE TO OPROCEDURI_aMS.PRG ADDITIVE
SET PROCEDURE TO oproceduri_rulaje ADDITIVE
SET PROCEDURE TO oproceduri_stocuri ADDITIVE
SET PROCEDURE TO OINTRODUCERI ADDITIVE
SET PROCEDURE TO oHeader.prg ADDITIVE
SET PROCEDURE TO proceduri_excel.PRG ADDITIVE
SET PROCEDURE TO onomenclatoare.PRG ADDITIVE
SET PROCEDURE TO osecurity ADDITIVE
SET PROCEDURE TO ocautare ADDITIVE
SET PROCEDURE TO orefaceri ADDITIVE
SET PROCEDURE TO ofacturare_comun.PRG ADDITIVE
SET PROCEDURE TO ofacturare_stoc.PRG ADDITIVE
SET PROCEDURE TO oproceduri_casademarcat ADDITIVE
SET PROCEDURE TO oproceduri_casa_marcat_e500 ADDITIVE
SET PROCEDURE TO oproceduri_casa_marcat_mp500 ADDITIVE
SET PROCEDURE TO oproceduri_util.prg ADDITIVE
SET PROCEDURE TO wwxmlhttp.prg ADDITIVE
SET PROCEDURE TO ini.prg ADDITIVE
SET PROCEDURE TO odocumente.prg ADDITIVE
SET PROCEDURE TO regex.prg ADDITIVE
SET PROCEDURE TO wwutils.prg ADDITIVE
SET PROCEDURE TO inchidere_k ADDITIVE
SET PROCEDURE TO iniacces.prg ADDITIVE
SET PROCEDURE TO oupdate.prg ADDITIVE
SET PROCEDURE TO procese.prg ADDITIVE
SET PROCEDURE TO version.prg ADDITIVE
SET PROCEDURE TO xmlaccess.prg ADDITIVE
SET PROCEDURE TO xmlparser.prg ADDITIVE
SET PROCEDURE TO filebringer.prg ADDITIVE
SET PROCEDURE TO wwcodeupdate.prg ADDITIVE
SET PROCEDURE TO wwhttp.prg ADDITIVE
SET PROCEDURE TO xdate.prg ADDITIVE
SET PROCEDURE TO ofacturare.prg ADDITIVE
SET PROCEDURE TO oproceduri_obinv.prg ADDITIVE
SET PROCEDURE TO oproceduri_facturare.prg ADDITIVE
SET PROCEDURE TO email.prg ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\ui_harness.prg" ADDITIVE
DO EeLog WITH 'SET PROCEDURE OK'
*----- Globale -----
PUBLIC gnPc, gnPval, gnPcant, gnPpret, gnPPretval, gnPCurs, gnPVal, gnPPretV, gnPPretVal
STORE 2 TO gnPc, gnPval, gnPVal
gnPcant = 3
STORE 4 TO gnPpret, gnPPretval, gnPPretVal, gnPPretV, gnPCurs
PUBLIC gl406, gcS, gnAn, gnLuna, gnIdFirma, gnIdSucursala, gcAcces, gcFirma
gl406 = .T.
gcS = 'CONTAFIN'
gnAn = YEAR(DATE())
gnLuna = MONTH(DATE())
gnIdFirma = 110
gnIdSucursala = 110
gcAcces = "1;2;3;4;5;6;7;8;"
gcFirma = gcS
PUBLIC nror(65000)
PUBLIC gnMockRaspuns, gcMockUltimMesaj, gnMockUltimTip, gcMockArtCodmat
gnMockRaspuns = 6
gcMockUltimMesaj = ''
gnMockUltimTip = 0
PUBLIC gnButon
gnButon = 1
gcMockArtCodmat = ''
PUBLIC goExecutor, goApp
goExecutor = CREATEOBJECT('dummyexecutor')
goApp = CREATEOBJECT('dummyapp')
*----- poAct: antetul notei (factura import EUR, curs 5) -----
PUBLIC poAct
poAct = CREATEOBJECT('Custom')
poAct.AddProperty('nume_val', 'EUR')
poAct.AddProperty('curs', 5)
poAct.AddProperty('proc_tva', 1.21)
poAct.AddProperty('nnir', 0)
poAct.AddProperty('id_valuta', 978)
poAct.AddProperty('id_fdoc', 1)
poAct.AddProperty('fdoc', 'Factura')
poAct.AddProperty('id_partc', 601)
poAct.AddProperty('partc', 'FURNIZOR EXTERN GMBH')
poAct.AddProperty('serie_act', '')
poAct.AddProperty('dataact', DATE())
poAct.AddProperty('tva_incasare', 0)
poAct.AddProperty('id_set', 1)
poAct.AddProperty('id_gestin', 1)
*----- jtva_coloane2 / saft_taxtable: perechi reale 21% (achizitii interne + import) -----
IF USED('jtva_coloane2')
USE IN ('jtva_coloane2')
ENDIF
CREATE CURSOR jtva_coloane2 (ordine N(8), id_jtva_coloana N(14), denumire C(100), ;
jc N(1), jv N(1), afisat N(1), coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14))
INSERT INTO jtva_coloane2 VALUES (0, 0, '', 0, 0, 1, '', '', 0, 0)
INSERT INTO jtva_coloane2 VALUES (1, 208, 'ACH. INT. 21%', 1, 0, 1, 'RO21B', 'RO21T', 21, 209)
INSERT INTO jtva_coloane2 VALUES (2, 209, 'TVA ACH. INT. 21%', 1, 0, 1, 'RO21T', '', 21, 0)
INSERT INTO jtva_coloane2 VALUES (3, 220, 'ACH. IMP. 21%', 1, 0, 1, 'FO21B', 'FO21T', 21, 221)
INSERT INTO jtva_coloane2 VALUES (4, 221, 'TVA ACH. IMP. 21%', 1, 0, 1, 'FO21T', '', 21, 0)
IF USED('saft_taxtable')
USE IN ('saft_taxtable')
ENDIF
CREATE CURSOR saft_taxtable (taxname C(250) NULL, typename C(250) NULL, taxcode N(6) NULL, ;
taxtype N(3) NULL, descriere C(250) NULL, tip C(100) NULL, descriere_tip C(250) NULL, ;
procent_taxa N(7,2) NULL, procent_prorata N(7,2) NULL, inactiv N(1) NULL, tva N(1) NULL, ;
wht N(1) NULL, tva_achizitii N(1) NULL, tva_livrari N(1) NULL)
INDEX ON taxcode TAG taxcode
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('', 0, '', 0, 1, 1, 1, 1)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301204-Import de bunuri cota 21%', 301204, '', 21, 1, 0, 1, 0)
DO CreeazaIntrodc WITH 'introdc'
DO CreeazaIntrodc WITH 'introdc_sablon'
INSERT INTO introdc_sablon (scd, scc, cu_tva, ordine, id_set, participa_valuta, tip_rand, ;
id_jtva_coloana, ptva, explicatie_tva) ;
VALUES ('371', '401', 1, 1, 1, .T., 'B', 208, 21, 'ACH. INT. 21%')
INSERT INTO introdc_sablon (scd, scc, cu_tva, ordine, id_set, participa_valuta, tip_rand, ;
id_jtva_coloana, ptva, explicatie_tva) ;
VALUES ('4426', '401', 1, 2, 1, .T., 'T', 209, 21, 'TVA ACH. INT. 21%')
GO TOP IN introdc_sablon
DO CreeazaRulTemp
INSERT INTO rul_temp (denumire, codmat, cant, pret, pret_lei, cont, cota_tva) ;
VALUES ('PLACEHOLDER', 'PH', 1, 1, 1, '371', 21)
*-- index ord_doc INAINTE de CREATEOBJECT (capcana p, docs/testare-ui-vfp.md)
SELECT introdc
INDEX ON Str(Nvl(nr_doc,0),8) + Icase(tip_rand='B','1', tip_rand='S','2', tip_rand='G','3', tip_rand='T','4', tip_rand='D','5', '6') + Padr(Nvl(scd,''),10) TAG ord_doc
SET ORDER TO ord_doc
*-- import_nota.inainte_de_do_termin() citeste variabila BARA tlIntern (linia
*-- "Iif(tlIntern, 0, 100)"), nu This.lIntern - se bazeaza pe mostenirea PRIVATE de-a
*-- lungul stivei de apel de la achizitie_import(tnIdSet, tlIntern), procedura reala care
*-- ar instantia formularul (Show() modal, deci tlIntern ramane "vizibil" din metodele
*-- formularului). Testul ocoleste achizitie_import (CREATEOBJECT direct, ca toate
*-- celelalte teste din suita), deci tlIntern trebuie declarata explicit aici, cu ACEEASI
*-- valoare data la CREATEOBJECT (.F. = mod import) - nu e defect de cod, e o conventie de
*-- scop de variabila care presupune fluxul real prin achizitie_import.
PRIVATE tlIntern
tlIntern = .F.
*-- alt global de mediu real (roagest.prg la pornire) folosit de clase pentru export
*-- fisiere temporare (XML/PDF/index) - nedeclarat pana acum pentru ca pasul Terminat
*-- nu fusese exercitat headless inainte de stub-ul verificare.scx
PUBLIC gcTempPath
gcTempPath = ADDBS(SYS(2023))
*-- gnHandle: handle SQLCONNECT real (SQLSetprop/SQLExec native) folosit de
*-- oscrie_in_fisiere - -1 e conventia din dbaccesscontroller.prg pt. "fara conexiune";
*-- fara o conexiune Oracle reala, scrierea propriu-zisa in ACT nu poate fi validata aici
PUBLIC gnHandle
gnHandle = -1
*-- gnTipGest: citit bare la Do listare_nir With poAct.nnir, gnTipGest In oproceduri_listari,
*-- dupa oscrie_in_fisiere() cu succes - 0 = gestiune normala (nu declanseaza ramurile
*-- speciale gnTipGest=6/7 vazute in cod pentru marfa la pret de vanzare)
PUBLIC gnTipGest
gnTipGest = 0
*-- gcCondSucursala: fragment WHERE folosit la rapoarte multi-sucursala (listare_nir) -
*-- gol = fara filtrare (o singura sucursala, ca in test_init_env.prg)
PUBLIC gcCondSucursala
gcCondSucursala = ''
DO EeLog WITH 'cursoare pregatite, CREATEOBJECT(import_nota, .F. - mod import)'
PUBLIC goObj
goObj = CREATEOBJECT('IMPORT_nota', .F.)
IF VARTYPE(goObj) <> 'O'
DO EeLog WITH 'FAIL: instantiere import_nota'
DO HarnessDone WITH 'done-error'
QUIT
ENDIF
goObj.lDialogAratat = .T.
goObj.oact = poAct
goObj.lSpargeSecundare = .F.
goObj.WindowType = 0
goObj.Visible = .T.
goObj.Show()
goObj.WindowState = 2
DOEVENTS FORCE
SELECT rul_temp
ZAP
goObj.gridart.Refresh()
DOEVENTS FORCE
PRIVATE pnAsserts, pnPass
STORE 0 TO pnAsserts, pnPass
DO HarnessStep WITH 0, 'nota goala afisata, mod import (.F.)'
*========================= DIALOG: factura EUR + TVA DVI in RON + discount financiar =========================
PUBLIC goDlg
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = 8001
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 601
goDlg.cPartener = 'FURNIZOR EXTERN GMBH'
goDlg.cExplicatia = 'Marfa import cu DVI in RON si discount'
goDlg.nSuma = 1000
goDlg.nSumaLei = 0
goDlg.nCurs = 5
goDlg.nIdValuta = 978
goDlg.cValuta = 'EUR'
goDlg.chkInValutaCont.Value = 1
goDlg.chkParticipaValuta.Value = 1
goDlg.nIdExplicatieTva = 220
goDlg.cExplicatieTva = 'ACH. IMP. 21%'
goDlg.nProcentTva = 21
*-- DVI: identitate (document vamal, partener vamal)
goDlg.cSerieDvi = ''
goDlg.nNractDvi = 9001
goDlg.dDviData = DATE()
goDlg.nIdFdocDVI = 2
goDlg.cFelDocDvi = 'DVI'
goDlg.nDviIdPartener = 900
goDlg.cDviPartener = 'DIRECTIA VAMALA'
*-- comuta pe mod TVA DVI (radio "TVA in vama") - flux real, InteractiveChange
goDlg.optTipTva.Value = 2
goDlg.optTipTva.InteractiveChange()
*-- alegere RON pe blocul DVI, prin picker-ul REAL (mock_caut_valuta, coada FIFO cu 1 pick)
PUBLIC goMockValuta, goMockValutaCoada
goMockValuta = CREATEOBJECT('Custom')
goMockValuta.AddProperty('id_valuta', 1)
goMockValuta.AddProperty('nume_val', 'RON')
goMockValutaCoada = CREATEOBJECT('Collection')
LOCAL loValRon
loValRon = CREATEOBJECT('Custom')
loValRon.AddProperty('id_valuta', 1)
loValRon.AddProperty('nume_val', 'RON')
goMockValutaCoada.Add(loValRon)
goDlg.cmdDviValuta.Click()
=AssertStr('1-DVI valuta aleasa RON', ALLTRIM(goDlg.cDviValuta), 'RON')
=Assert3('2-DVI curs fixat la 1 (RON)', goDlg.nDviCurs, 1)
=Assert3('3-DVI TVA lei auto = baza_lei*21% = 1050.00', goDlg.nDviTvaLei, 1050.00)
*-- discount financiar (Runda32: doar baza, fara bifa) - Valid() reface imediat TVA DVI pe
*-- baza NETA (suma-discount), fara auto-calcul separat de "TVA discount"
goDlg.txtDiscBaza.Value = 200
goDlg.txtDiscBaza.Valid()
=Assert3('4-dupa discount: DVI TVA lei pe baza NETA = (5000-1000)*21% = 840.00', goDlg.nDviTvaLei, 840.00)
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO HarnessStep WITH 1, 'dialog completat: factura EUR 1000, DVI TVA RON 840.00 (baza neta), discount baza 200'
*-- valideaza() REAL de pe dialog (buton Termin apeleaza mereu asta primul)
LOCAL llOkValid
llOkValid = goDlg.valideaza()
=Assert3('6a-dialog valideaza() reuseste', IIF(llOkValid,1,0), 1)
*-- toDlg construit INLINE in programul PRINCIPAL, NU prin goDlg.construieste_todlg() -
*-- capcana l (vezi antetul mock_caut_valuta.prg): CREATEOBJECT/ADDPROPERTY nu merg corect
*-- apelate dintr-o PROCEDURA/METODA in acest runtime headless (confirmat: crapa universal,
*-- inclusiv pe o instanta virgina, cu eroarea 11 pe primul Addproperty din construieste_todlg;
*-- acelasi cod, apelat din programul principal cu goDlg.* in loc de This.*, functioneaza OK).
*-- Lista de campuri COPIATA din construieste_todlg (ointroduceri.vc2 ~6180) ca sa ramana
*-- fidela contractului - vezi si celelalte teste motor (test_dvi_valuta_ron.prg etc.), care
*-- folosesc acelasi tipar.
PUBLIC goT
goT = CREATEOBJECT('Empty')
=ADDPROPERTY(goT,'serie_act',ALLTRIM(NVL(goDlg.cSerieAct,'')))
=ADDPROPERTY(goT,'nract',goDlg.nNract)
=ADDPROPERTY(goT,'dataact',goDlg.dDataAct)
=ADDPROPERTY(goT,'fdoc',goDlg.cFelDoc)
=ADDPROPERTY(goT,'id_fdoc',goDlg.nIdFdoc)
=ADDPROPERTY(goT,'id_partc',goDlg.nIdPartener)
=ADDPROPERTY(goT,'partc',goDlg.cPartener)
=ADDPROPERTY(goT,'explicatia',ALLTRIM(NVL(goDlg.cExplicatia,'')))
=ADDPROPERTY(goT,'suma',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,IIF(goDlg.nSumaLei<>0,goDlg.nSumaLei,ROUND(goDlg.nSuma*goDlg.nCurs,gnPC)),goDlg.nSuma))
=ADDPROPERTY(goT,'suma_val',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,goDlg.nSuma,0))
=ADDPROPERTY(goT,'in_valuta',goDlg.chkInValutaCont.Value)
=ADDPROPERTY(goT,'participa_valuta',(goDlg.chkParticipaValuta.Value=1))
=ADDPROPERTY(goT,'id_valuta',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nIdValuta,0))
=ADDPROPERTY(goT,'curs',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nCurs,0))
=ADDPROPERTY(goT,'nume_val',IIF(goDlg.chkInValutaCont.Value=1,ALLTRIM(NVL(goDlg.cValuta,'')),''))
=ADDPROPERTY(goT,'cTipTva',IIF(goDlg.optTipTva.Value=1,'F',IIF(goDlg.optTipTva.Value=2,'D','N')))
=ADDPROPERTY(goT,'id_jtva_coloana',goDlg.nIdExplicatieTva)
IF goDlg.optTipTva.Value = 2
=ADDPROPERTY(goT,'dvi_serie',CHRTRAN(ALLTRIM(NVL(goDlg.cSerieDvi,'')),CHR(34),''))
=ADDPROPERTY(goT,'dvi_nract',goDlg.nNractDvi)
=ADDPROPERTY(goT,'dvi_dataact',goDlg.dDviData)
=ADDPROPERTY(goT,'dvi_id_fdoc',goDlg.nIdFdocDVI)
=ADDPROPERTY(goT,'dvi_fdoc',goDlg.cFelDocDvi)
=ADDPROPERTY(goT,'dvi_id_partc',goDlg.nDviIdPartener)
=ADDPROPERTY(goT,'dvi_partc',goDlg.cDviPartener)
=ADDPROPERTY(goT,'dvi_scc','401')
=ADDPROPERTY(goT,'dvi_tva_lei',goDlg.nDviTvaLei)
=ADDPROPERTY(goT,'dvi_tva_val',goDlg.nDviTvaVal)
*-- dvi_in_valuta: LOGIC (nu numeric), derivat dupa NUME - fidel cu construieste_todlg
=ADDPROPERTY(goT,'dvi_in_valuta',!(EMPTY(goDlg.cDviValuta) OR UPPER(ALLTRIM(goDlg.cDviValuta))=='RON'))
=ADDPROPERTY(goT,'dvi_id_valuta',goDlg.nDviIdValuta)
=ADDPROPERTY(goT,'dvi_curs',goDlg.nDviCurs)
=ADDPROPERTY(goT,'dvi_nume_val',ALLTRIM(NVL(goDlg.cDviValuta,'')))
*-- dvi_valuta_proprie: regula pe valuta EFECTIVA (fix task #9) - daca ambele parti sunt
*-- efectiv "fara valuta" (gol sau RON), rezultat 0; altfel compara id/curs ca inainte
=ADDPROPERTY(goT,'dvi_valuta_proprie',IIF(!(EMPTY(goDlg.cDviValuta) OR UPPER(ALLTRIM(goDlg.cDviValuta))=='RON') OR !(EMPTY(goDlg.cValuta) OR UPPER(ALLTRIM(goDlg.cValuta))=='RON'),IIF(goDlg.nDviIdValuta<>goDlg.nIdValuta OR goDlg.nDviCurs<>goDlg.nCurs,1,0),0))
ENDIF
=ADDPROPERTY(goT,'disc_baza_lei',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,ROUND(goDlg.nDiscBaza*goDlg.nCurs,gnPC),goDlg.nDiscBaza))
=ADDPROPERTY(goT,'disc_baza_val',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,goDlg.nDiscBaza,0))
*-- "Termin" REAL: oParinte.do_adauga_factura() cu toDlg-ul construit mai sus
LOCAL llOkAdauga
llOkAdauga = goObj.do_adauga_factura(goT)
=Assert3('6-do_adauga_factura(goT) reuseste (Termin)', IIF(llOkAdauga,1,0), 1)
goDlg.Hide()
DOEVENTS FORCE
DO HarnessStep WITH 2, 'dupa Termin pe dialog: introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri'
*========================= ASSERT-URI RAND CU RAND PE introdc =========================
LOCAL lcSccB
SELECT introdc
LOCATE FOR nract = 8001 AND tip_rand == 'B'
=Assert3('7-randul B (baza factura) gasit', IIF(FOUND(),1,0), 1)
IF FOUND()
lcSccB = ALLTRIM(NVL(scc,''))
=AssertStr('8-B.scd=371', ALLTRIM(scd), '371')
=Assert3('9-B.suma=5000.00 (1000 EUR x curs 5)', suma, 5000.00)
=Assert3('10-B.suma_val=1000.00', suma_val, 1000.00)
=Assert3('11-B.in_valuta=1', NVL(in_valuta,0), 1)
=Assert3('12-B.id_valuta=978 (EUR)', NVL(id_valuta,0), 978)
=AssertStr('13-B.nume_val=EUR', ALLTRIM(NVL(nume_val,'')), 'EUR')
=Assert3('14-B.id_partc=601 (furnizorul facturii)', NVL(id_partc,0), 601)
=AssertStr('15-B.partc=FURNIZOR EXTERN GMBH', ALLTRIM(NVL(partc,'')), 'FURNIZOR EXTERN GMBH')
ELSE
pnAsserts = pnAsserts + 8
DO EeLog WITH ' FAIL 8-15: randul B negasit'
ENDIF
SELECT introdc
LOCATE FOR Nvl(rand_dvi,0) = 1
=Assert3('16-randul T-DVI (rand_dvi=1) gasit', IIF(FOUND(),1,0), 1)
IF FOUND()
=AssertStr('17-T-DVI.scd=4426', ALLTRIM(scd), '4426')
=AssertStr('18-T-DVI.scc=401', ALLTRIM(scc), '401')
=Assert3('19-T-DVI.suma=840.00 (baza NETA lei x 21%, discount scazut din baza DVI)', suma, 840.00)
=Assert3('20-T-DVI.suma_val=0 (RON)', NVL(suma_val,0), 0)
=Assert3('21-T-DVI.in_valuta=0', NVL(in_valuta,0), 0)
=Assert3('22-T-DVI.id_valuta=0 (normalizare fara-valuta pe randul scris)', NVL(id_valuta,0), 0)
=Assert3('23-T-DVI.curs=0', NVL(curs,0), 0)
=AssertStr('24-T-DVI.nume_val="" ', ALLTRIM(NVL(nume_val,'?')), '')
=Assert3('25-T-DVI.participa_valuta=.F. (nu intra in footer valuta)', IIF(participa_valuta,1,0), 0)
=Assert3('26-T-DVI.valuta_proprie=1 (RON <> EUR factura)', NVL(valuta_proprie,0), 1)
=Assert3('27-T-DVI.id_partc=900 (Directia Vamala)', NVL(id_partc,0), 900)
=AssertStr('28-T-DVI.partc=DIRECTIA VAMALA', ALLTRIM(NVL(partc,'')), 'DIRECTIA VAMALA')
=Assert3('29-T-DVI.mod_manual=0 (TVA-ul tastat coincide cu auto-calculul pe baza neta 840.00)', NVL(mod_manual,0), 0)
ELSE
pnAsserts = pnAsserts + 12
DO EeLog WITH ' FAIL 17-29: randul T-DVI negasit'
ENDIF
LOCAL lnCntGDoc1
lnCntGDoc1 = 0
SELECT introdc
SCAN FOR nract = 8001 AND tip_rand == 'G'
lnCntGDoc1 = lnCntGDoc1 + 1
ENDSCAN
=Assert3('30b-exact un singur rand G (model B/G/T, Runda32)', lnCntGDoc1, 1)
SELECT introdc
LOCATE FOR nract = 8001 AND tip_rand == 'G' AND ALLTRIM(NVL(scc,'')) == '767'
=Assert3('30-randul G (discount, 401->767) gasit', IIF(FOUND(),1,0), 1)
IF FOUND()
IF !EMPTY(lcSccB)
=AssertStr('31-G.scd = analitic mostenit de pe creditul B', ALLTRIM(scd), lcSccB)
ENDIF
=Assert3('32-G.suma=+1000.00 (baza discount in lei, POZITIV)', suma, 1000.00)
=Assert3('33-G.suma_val=+200.00 (POZITIV)', suma_val, 200.00)
=Assert3('34-G.id_partd=601 (furnizorul facturii, de pe creditul B)', NVL(id_partd,0), 601)
=Assert3('35-G.participa_valuta=.F.', IIF(participa_valuta,1,0), 0)
=Assert3('36-G.cu_tva=1 (mostenit din linia de baza, runda33)', NVL(cu_tva,0), 1)
=Assert3('37-G.ptva=21 (aceeasi cota ca linia de baza, runda33)', NVL(ptva,0), 21)
ELSE
pnAsserts = pnAsserts + 6
DO EeLog WITH ' FAIL 31-37: randul G negasit'
ENDIF
*========================= TOTALURI SUBSOL (Runda32: total cu TVA scade discountul, =========================
*========================= total fara TVA ramane baza integrala - D4) - inainte de a adauga =========================
*========================= articole (document inca nespart, B ramane intreg) =========================
=Assert3('37b-subsol: txtftvalei (fara TVA) = baza integrala 5000.00', goObj.txtftvalei.Value, 5000.00)
=Assert3('37c-subsol: Text2 (cu TVA) = baza+TVA-discount = 5000+840-1000 = 4840.00', goObj.Text2.Value, 4840.00)
=Assert3('37d-subsol: txtftvaval (fara TVA, valuta) = baza integrala 1000.00', goObj.txtftvaval.Value, 1000.00)
=Assert3('37e-subsol: Text3 (cu TVA, valuta) = baza+TVA-discount = 1000+0-200 = 800.00', goObj.Text3.Value, 800.00)
*========================= ARTICOL prin do_adauga_articol() REAL =========================
gcMockArtCodmat = 'ART-BULD-212'
LOCAL llEroareArt
llEroareArt = .F.
TRY
goObj.do_adauga_articol()
CATCH TO loExcArt
llEroareArt = .T.
DO EeLog WITH 'EROARE do_adauga_articol ' + TRANSFORM(loExcArt.ErrorNo) + ' [' + loExcArt.Message + ']'
ENDTRY
DOEVENTS FORCE
=Assert3('43-do_adauga_articol() fara eroare', IIF(llEroareArt,0,1), 1)
SELECT rul_temp
LOCATE FOR ALLTRIM(codmat) == 'ART-BULD-212'
=Assert3('44-articolul BULDOEXCAVATOR adaugat in rul_temp', IIF(FOUND(),1,0), 1)
IF FOUND()
REPLACE cant WITH 1, pret_val WITH 800, pretd WITH 800, pret WITH ROUND(800*5,4), ;
pret_lei WITH ROUND(800*5,4), cota_tva WITH 21
ELSE
pnAsserts = pnAsserts + 1
DO EeLog WITH ' FAIL 44: articolul nu a fost adaugat'
ENDIF
goObj.gridart.Refresh()
DOEVENTS FORCE
DO HarnessStep WITH 3, 'articol adaugat (BULDOEXCAVATOR, 800 EUR)'
*========================= sincronizeaza() REAL =========================
LOCAL llEroareSync
llEroareSync = .F.
TRY
goObj.sincronizeaza()
CATCH TO loExcSync
llEroareSync = .T.
DO EeLog WITH 'EROARE sincronizeaza() ' + TRANSFORM(loExcSync.ErrorNo) + ' [' + loExcSync.Message + '] in ' + loExcSync.Procedure + ':' + TRANSFORM(loExcSync.LineNo)
ENDTRY
DOEVENTS FORCE
=Assert3('45-sincronizeaza() fara eroare', IIF(llEroareSync,0,1), 1)
*-- pretul articolului neafectat de discount (discount participa_valuta=.F., exclus din baze)
SELECT rul_temp
LOCATE FOR ALLTRIM(codmat) == 'ART-BULD-212'
=Assert3('46-dupa sincronizeaza(): pret_lei articol neschimbat (4000.00)', IIF(FOUND(),pret_lei,-1), 4000.00)
*-- randurile T-DVI si G supravietuiesc sincronizarii (nu doar la creare)
SELECT introdc
LOCATE FOR Nvl(rand_dvi,0) = 1
=Assert3('47-dupa sincronizeaza(): T-DVI inca gasit', IIF(FOUND(),1,0), 1)
IF FOUND()
=Assert3('48-dupa sincronizeaza(): T-DVI.suma neschimbata (840.00, baza neta, protejata de mod_manual=1)', suma, 840.00)
ELSE
pnAsserts = pnAsserts + 1
DO EeLog WITH ' FAIL 48: T-DVI a disparut dupa sincronizare'
ENDIF
SELECT introdc
LOCATE FOR nract = 8001 AND tip_rand == 'G' AND ALLTRIM(NVL(scc,'')) == '767'
=Assert3('49-dupa sincronizeaza(): G inca gasit', IIF(FOUND(),1,0), 1)
IF FOUND()
=Assert3('50-dupa sincronizeaza(): G.suma neschimbata (+1000.00)', suma, 1000.00)
ELSE
pnAsserts = pnAsserts + 1
DO EeLog WITH ' FAIL 50: G a disparut dupa sincronizare'
ENDIF
*-- randul D (diferenta) - informativ, best-effort (nu e fortat de acest scenariu)
SELECT introdc
LOCATE FOR nract = 8001 AND tip_rand == 'D'
IF FOUND()
DO EeLog WITH 'INFO randul D (diferenta) exista: suma=' + TRANSFORM(suma) + ' - neafectat de discount (G exclus din bazele de calcul)'
ELSE
DO EeLog WITH 'INFO randul D (diferenta) nu apare in acest scenariu (numere curate, fara rotunjire reziduala) - nu e o cerinta a acestui test'
ENDIF
DO HarnessStep WITH 4, 'sincronizeaza() verificat - vezi log'
*========================= Terminat -> scriere in actactan (stub verificare.scx, vezi handoff) =========================
DO CreeazaActactan
LOCAL llEroareTermin
llEroareTermin = .F.
TRY
goObj.inainte_de_do_termin()
CATCH TO loExcTermin
llEroareTermin = .T.
DO EeLog WITH 'EROARE inainte_de_do_termin() ' + TRANSFORM(loExcTermin.ErrorNo) + ' [' + loExcTermin.Message + '] in ' + loExcTermin.Procedure + ':' + TRANSFORM(loExcTermin.LineNo)
ENDTRY
=Assert3('51-inainte_de_do_termin() fara eroare (Terminat)', IIF(llEroareTermin,0,1), 1)
*-- Randurile in actactan sunt scrise INAINTE de Do Form verificare/oscrie_in_fisiere/
*-- listare_nir (Scan For suma<>0 Or se_scrie=1 / Append/Gather, mult mai devreme in
*-- metoda) - o eroare TARZIE (ex. in raportarea NIR, dupa scriere) nu invalideaza datele
*-- deja scrise. De-aia verific actactan INDIFERENT de llEroareTermin.
IF USED('actactan')
DO EeLog WITH 'DIAG dump actactan dupa Terminat:'
SELECT actactan
SCAN
DO EeLog WITH ' recno=' + TRANSFORM(RECNO()) + ' nract=' + TRANSFORM(nract) + ' scd=' + ALLTRIM(NVL(scd,'')) + ' scc=' + ALLTRIM(NVL(scc,'')) + ;
' suma=' + TRANSFORM(suma) + ' suma_val=' + TRANSFORM(NVL(suma_val,0)) + ' in_valuta=?' + ' id_valuta=' + TRANSFORM(NVL(id_valuta,0)) + ;
' id_partd=' + TRANSFORM(NVL(id_partd,0)) + ' id_partc=' + TRANSFORM(NVL(id_partc,0)) + ' partc=[' + ALLTRIM(NVL(partc,'')) + ']'
ENDSCAN
=Assert3('52-actactan folosit dupa Terminat', IIF(USED('actactan'),1,0), 1)
*-- randul "B" (baza facturii) - sincronizeaza() redistribuie valoarea originala pe
*-- conturile REALE ale articolelor participante (212 = contul articolului BULDOEXCAVATOR,
*-- nu 371, placeholder-ul din sablon) - comportament PRE-EXISTENT de participare la pret,
*-- neschimbat de F1/F2. Nu (mai) pin-uiesc contul/suma exacta (ar cere sa refac math-ul
*-- complet de spargere pe cote) - verific doar ca valoarea facturii e reprezentata,
*-- atribuita corect furnizorului, in EUR.
SELECT actactan
LOCATE FOR nract = 8001 AND ALLTRIM(NVL(scc,'')) == '401' AND suma > 0 AND NVL(id_partc,0) = 601
=Assert3('53-actactan: cel putin un rand de baza (scc=401, furnizor) gasit', IIF(FOUND(),1,0), 1)
IF FOUND()
=Assert3('56-actactan randul de baza: id_valuta=978 (EUR)', NVL(id_valuta,0), 978)
=AssertStr('57-actactan randul de baza: nume_val=EUR', ALLTRIM(NVL(nume_val,'')), 'EUR')
=Assert3('58-actactan randul de baza: id_partc=601 (furnizorul facturii)', NVL(id_partc,0), 601)
ELSE
pnAsserts = pnAsserts + 3
DO EeLog WITH ' FAIL 56-58: niciun rand de baza gasit in actactan'
ENDIF
*-- NU verific suma totala exacta pe randurile de baza: cu un singur articol (800 EUR)
*-- fata de baza integrala a facturii (1000 EUR), sincronizeaza() mai scrie si un rand de
*-- diferenta/reconciliere (scd=6588) - matematica exacta de spargere pe conturi tine de
*-- participarea la pret (pre-existenta, neschimbata de F1/F2), nu de scopul acestui test.
SELECT actactan
LOCATE FOR ALLTRIM(NVL(scd,'')) == '4426' AND suma > 0
=Assert3('59-actactan randul T-DVI (scd=4426, suma pozitiva) gasit', IIF(FOUND(),1,0), 1)
IF FOUND()
=Assert3('60-actactan T-DVI.suma=840.00 (baza neta)', suma, 840.00)
=Assert3('61-actactan T-DVI.suma_val=0 (RON, in_valuta=0, necopiat)', NVL(suma_val,0), 0)
=Assert3('62-actactan T-DVI.id_valuta=0 (RON normalizat)', NVL(id_valuta,0), 0)
=Assert3('63-actactan T-DVI.id_partc=900 (Directia Vamala)', NVL(id_partc,0), 900)
=AssertStr('64-actactan T-DVI.partc=DIRECTIA VAMALA', ALLTRIM(NVL(partc,'')), 'DIRECTIA VAMALA')
ELSE
pnAsserts = pnAsserts + 4
DO EeLog WITH ' FAIL 60-64: randul T-DVI negasit in actactan'
ENDIF
SELECT actactan
LOCATE FOR nract = 8001 AND ALLTRIM(NVL(scc,'')) == '767'
=Assert3('65-actactan randul G (scc=767, discount baza) gasit', IIF(FOUND(),1,0), 1)
IF FOUND()
=Assert3('66-actactan G.suma=+1000.00 (POZITIV)', suma, 1000.00)
=Assert3('67-actactan G.suma_val=+200.00 (POZITIV, valuta mostenita de la B)', NVL(suma_val,0), 200.00)
=Assert3('68-actactan G.id_partd=601 (furnizorul facturii)', NVL(id_partd,0), 601)
ELSE
pnAsserts = pnAsserts + 3
DO EeLog WITH ' FAIL 66-68: randul G negasit in actactan'
ENDIF
*-- niciun rand fals de finalizare NIR: scd gol + scc=401 + suma=0, generat cand un rand cu_tva=0 (G) nu e exclus corect
SELECT actactan
LOCATE FOR EMPTY(NVL(scd,'')) AND ALLTRIM(NVL(scc,'')) == '401' AND NVL(suma,0) = 0
=Assert3('73-niciun rand fals de finalizare NIR in actactan', IIF(FOUND(),1,0), 0)
ELSE
pnAsserts = pnAsserts + 16
DO EeLog WITH ' FAIL 52-73: inainte_de_do_termin() a esuat sau actactan nu exista - assert-urile pe actactan sarite'
ENDIF
DO EeLog WITH 'REZULTAT: ' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' assert-uri PASS'
IF pnPass = pnAsserts
DO EeLog WITH 'REZULTAT: PASS (' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ')'
ELSE
DO EeLog WITH 'REZULTAT: FAIL (' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' assert-uri PASS)'
ENDIF
DO HarnessStep WITH 5, 'final: ' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' PASS'
DO HarnessDone WITH 'done'
CATCH TO loExc
DO EeLog WITH 'CATCH ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']'
DO HarnessDone WITH 'done-error'
ENDTRY
QUIT
*==================================================================================
PROCEDURE CreeazaIntrodc
*-- Runda30 (F1/pas2): coloane NOI rand_dvi N(1), valuta_proprie N(1) fata de structura veche.
LPARAMETERS tcAlias
IF USED(tcAlias)
USE IN (tcAlias)
ENDIF
CREATE CURSOR (tcAlias) ( ;
id_note N(14), explicatia C(100), scd C(10), ascd C(20), scc C(10), ascc C(20), ;
cu_tva N(1), id_set N(14), ordine N(8), in_valuta N(1), id_jtva_coloana N(14) NULL, ;
ptva N(6,2), explicatie_tva C(50), tipjurnal C(2), taxcode N(6), paymentcode C(9), ;
suma N(18,4), suma_val N(18,4), id_partd N(14), id_partc N(14), partd C(100), partc C(100), ;
id_fact N(14), id_factd N(14), id_factc N(14), pereched N(14), perechec N(14), ;
nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), expl_manual N(1), ;
scd_orig C(20), ascd_orig C(20), rand_dvi N(1), valuta_proprie N(1))
ENDPROC
PROCEDURE CreeazaRulTemp
IF USED('rul_temp')
USE IN ('rul_temp')
ENDIF
CREATE CURSOR rul_temp ( ;
id_rul N(20,0), an N(4,0), luna N(2,0), cod N(20,0);
, serie C(100), nnir N(20,0), id_articol N(10,0), denumire C(100);
, codmat C(50), codmatf C(50), codbare C(50), um C(20);
, id_gestiune N(5,0), nume_gestiune C(50), cgest C(20), nr_pag N(2,0);
, gestionar C(50), comisie_receptie1 C(50), comisie_receptie2 C(50), comisie_receptie3 C(50);
, cant N(14,3), cante N(14,3), cont C(10), acont C(20);
, pret N(18,4), tva N(18,4), valoare N(18,4), valtva N(18,4);
, proc_tva N(5,2), pretv N(18,4), pretvtva N(18,4), tvav N(18,4);
, valoarev N(18,4), valtvav N(18,4), proc_tvav N(5,2), adaos N(18,4);
, adaos_tva N(18,4), valoare_adaos N(18,4), valtva_adaos N(18,4), procent N(10,3);
, discunitar N(18,4), discount_tva N(18,4), valoare_discount N(18,4), valtva_discount N(18,4);
, proc_disc N(7,3), pretd N(14,4), curs N(18,4), id_valuta N(10,0);
, nume_val C(20), id_lucrare N(20,0), nrord C(100), id_responsabil N(10,0);
, nresp C(100), resp_marca N(18,4), dataact T, id_util N(5,0);
, util C(30), dataora T, id_sectie N(5,0), sectie C(50);
, csectie C(10), alcooltutun N(1,0), datain T, dataout T;
, id_fact N(20,0), id_gestiunec N(10,0), nume_gestiunec C(50), cgestc C(20);
, id_responsabilc N(5,0), id_reteta N(10,0), reteta C(50), nrespc C(100);
, respc_marca N(18,4), id_set N(20,0), id_tip_rulaj N(10,0), tip_rulaj C(50);
, id_obiect_depozit N(10,0), id_rul_aux N(10,0), nract N(20,0), serie_act C(10);
, dataoras T, id_utils N(10,0), lot C(30), adata_expirare T;
, id_sucursala N(5,0), sucursala C(250), id_part_rez N(10,0), part_rez C(100);
, id_lucrare_rez N(10,0), nrord_rez C(100), subgrupa C(100), grupa C(100);
, id_subgrupa N(5,0), id_grupa N(5,0), in_stoc N(1,0), in_crm N(1,0);
, id_furnizor N(10,0), furnizor C(100), id_jtva_coloana N(4,0), explicatie_tva C(100);
, taxcode N(6,0), taxname C(254), saft_procent N(18,4), codnc8 C(20);
, id_tara_origine N(4,0), cod_tara_origine C(5), tara_origine C(50), greutate N(12,4);
, fdoc C(30), id_fdoc N(18,4);
, pret_lei N(18,4), pret_val N(14,4), cota_tva N(6,2))
ENDPROC
PROCEDURE CreeazaActactan
*-- structura minima ceruta de GATHER-urile
*-- din import_nota.inainte_de_do_termin() (Scan For suma<>0 Or se_scrie=1 / Append Blank /
*-- Gather Name poAct + Gather Name loFact Fields ...). Fara ea, GATHER FIELDS ar da eroare
*-- de camp inexistent inainte sa ajunga la Do Form verificare.
IF USED('actactan')
USE IN ('actactan')
ENDIF
CREATE CURSOR actactan ( ;
id_fdoc N(14), fdoc C(50), dataact D, serie_act C(10), nract N(14), ;
partc C(100), id_partc N(14), partd C(100), id_partd N(14), ;
suma N(18,4), suma_val N(18,4), explicatia C(100), explicatia4 C(50), explicatia5 C(50), ;
scd C(10), ascd C(20), scc C(10), ascc C(20), id_jtva_coloana N(14) NULL, taxcode N(6), ;
id_valuta N(14), curs N(14,4), nume_val C(10), proc_tva N(8,4), nnir N(14), ;
tva_incasare N(1), id_set N(14), id_gestin N(14))
ENDPROC
FUNCTION RECCOUNT_ACTIVE
LPARAMETERS tcAlias
LOCAL lnSel, lnCnt
lnSel = SELECT()
SELECT (tcAlias)
COUNT TO lnCnt FOR !DELETED()
SELECT (lnSel)
RETURN lnCnt
ENDFUNC
PROCEDURE Assert3
LPARAMETERS tcLabel, tuActual, tuExpected
pnAsserts = pnAsserts + 1
IF ABS(NVL(tuActual,0) - tuExpected) < 0.02
pnPass = pnPass + 1
DO EeLog WITH ' PASS ' + tcLabel + ' (=' + TRANSFORM(tuActual) + ')'
ELSE
DO EeLog WITH ' FAIL ' + tcLabel + ' (actual=' + TRANSFORM(tuActual) + ' asteptat=' + TRANSFORM(tuExpected) + ')'
ENDIF
ENDPROC
PROCEDURE AssertStr
LPARAMETERS tcLabel, tcActual, tcExpected
pnAsserts = pnAsserts + 1
IF tcActual == tcExpected
pnPass = pnPass + 1
DO EeLog WITH ' PASS ' + tcLabel + ' (=[' + tcActual + '])'
ELSE
DO EeLog WITH ' FAIL ' + tcLabel + ' (actual=[' + tcActual + '] asteptat=[' + tcExpected + '])'
ENDIF
ENDPROC
PROCEDURE EeErr
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
DO EeLog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
ENDPROC
PROCEDURE EeLog
LPARAMETERS tcMsg
SET SAFETY OFF
LOCAL lcL
lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '')
STRTOFILE(lcL + tcMsg + CHR(13)+CHR(10), gcUILog)
ENDPROC
DEFINE CLASS dummyapp AS Custom
PROCEDURE ReadIni
LPARAMETERS tcSection, tcKey
RETURN ''
ENDPROC
PROCEDURE WriteIni
LPARAMETERS tcSection, tcKey, tcValue
RETURN .T.
ENDPROC
ENDDEFINE
DEFINE CLASS dummyexecutor AS Custom
cEroare = ''
PROCEDURE oExecute
LPARAMETERS tcSql, tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF 'VJTVA_COLOANE' $ UPPER(m.tcSql)
DO CreeazaJtvaColoaneView WITH m.tcCursor
RETURN 1
ENDIF
IF UPPER(ALLTRIM(m.tcCursor)) == 'RUL_TEMP'
CREATE CURSOR (m.tcCursor) (denumire C(100), codmat C(30), cant N(14,3), ;
pret_val N(18,4), pretd N(18,4), pret N(18,4), pret_lei N(18,4), cont C(10), ;
acont C(20), serie C(30), lot C(30), adata_expirare C(10), proc_disc N(6,2), cota_tva N(6,2))
RETURN 1
ENDIF
IF 'CONFIG_ANALITICE' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (camp_leg_prefix C(30), camp_leg_sufix C(30))
INSERT INTO (m.tcCursor) VALUES ('', '')
RETURN 1
ENDIF
IF 'FCONTURI_ANALITICE' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (acont C(20))
INSERT INTO (m.tcCursor) VALUES (IIF(TYPE('gcMockAcontCrt') = 'C', gcMockAcontCrt, ''))
RETURN 1
ENDIF
IF 'VPLCONT_ANALITIC' $ UPPER(m.tcSql)
*-- gol: niciun cont nu cere analitic in scenariul acestui test (371/401 folosite
*-- fara analitic, ca in restul suitei - vezi verificare_note_contabile)
CREATE CURSOR (m.tcCursor) (cont C(10), acont C(20))
RETURN 1
ENDIF
IF 'VCONFIG_CONT_IREG' $ UPPER(m.tcSql)
*-- 401 recunoscut ca si cont cu parteneri (verificare_note_contabile) - altfel
*-- verif_part goleste id_partc/id_partd pe randurile T-DVI/G inainte de actactan
CREATE CURSOR (m.tcCursor) (contpart C(10), fel_cont N(1), cu_inregistrari N(1), ;
explic_cont C(100), exceptie C(10), pozitie N(1), invers N(1), gasit N(1))
INSERT INTO (m.tcCursor) VALUES ('401', 0, 0, 'Furnizori', '', 0, 0, 0)
RETURN 1
ENDIF
CREATE CURSOR (m.tcCursor) (id_temp N(1))
RETURN 1
ENDPROC
PROCEDURE oExecuta
LPARAMETERS tcSql, tcCursor
IF !EMPTY(m.tcCursor)
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF UPPER(m.tcCursor) == 'CJTVACOL4427'
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14))
ELSE
CREATE CURSOR (m.tcCursor) (id_temp N(1))
ENDIF
ENDIF
RETURN .T.
ENDPROC
PROCEDURE oSelect2Value
LPARAMETERS tcSql, toValue
toValue = ''
RETURN 1
ENDPROC
PROCEDURE oReset
ENDPROC
ENDDEFINE
PROCEDURE CreeazaJtvaColoaneView
LPARAMETERS tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14), denumire C(100), jc N(1), jv N(1), ;
coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14) NULL, afisat N(1), ;
id_jtva_ex N(14) NULL, id_jtva_neex N(14) NULL, ordine N(8), ;
taxcode N(6) NULL, taxcode_neexigibil N(6) NULL, taxcode_n50 N(6) NULL, ;
taxcode_n50_tvai N(6) NULL, taxcode_n100 N(6) NULL, taxcode_regularizare N(6) NULL, taxcode_tvai N(6) NULL)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, afisat, ordine, cota_tva) VALUES (0, '', 0, 0, 1, 0, 0)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (208, 'ACH. INT. 21%', 1, 0, 'RO21B', 21, 209, 1, 1, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (209, 'TVA ACH. INT. 21%', 1, 0, 'RO21T', 21, 1, 2, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (220, 'ACH. IMP. 21%', 1, 0, 'FO21B', 21, 221, 1, 3, 301204)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (221, 'TVA ACH. IMP. 21%', 1, 0, 'FO21T', 21, 1, 4, 301204)
ENDPROC

View File

@@ -0,0 +1,13 @@
# test_e2e_dvi_ron_discount.ps1 - wrapper peste harness-ul generic pentru testul e2e
# (factura import EUR + TVA DVI in RON + discount financiar + articol + sincronizare).
# NU exercita pasul "Terminat" (scriere in actactan) - vezi antetul .prg pentru motiv.
# Rulare: powershell -ExecutionPolicy Bypass -File test_e2e_dvi_ron_discount.ps1
$ErrorActionPreference = 'Stop'
$Teste = $PSScriptRoot
& (Join-Path (Split-Path $Teste -Parent) 'vfp_ui_harness.ps1') `
-TestPrg (Join-Path $Teste 'test_e2e_dvi_ron_discount.prg') `
-Steps @('nota_goala','dialog_completat','dupa_termin_dialog','articol_adaugat','sincronizat','final') `
-ShotsDir (Join-Path $Teste 'screenshots_e2e_dvi_ron_discount') `
-SyncDir (Join-Path $Teste 'uisync_e2e_dvi_ron_discount') `
-StepTimeoutSec 180 `
-ReadyTimeoutSec 180

View File

@@ -666,8 +666,8 @@ PROCEDURE CreeazaIntrodc
nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), ;
scd_orig C(20), ascd_orig C(20))
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), expl_manual N(1), ;
scd_orig C(20), ascd_orig C(20), rand_dvi N(1), valuta_proprie N(1))
ENDPROC
PROCEDURE DumpIntrodc

View File

@@ -285,8 +285,8 @@ TRY
nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), ;
scd_orig C(20), ascd_orig C(20))
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), expl_manual N(1), ;
scd_orig C(20), ascd_orig C(20), rand_dvi N(1), valuta_proprie N(1))
*-- Document unic (nract=1001/serie A pentru toate randurile => acelasi doc_key). doc_key
*-- populat explicit (padded C(80) la stocare, ca in fluxul real) - vezi PAS 5: comparatia

View File

@@ -250,7 +250,7 @@ TRY
*-- index ord_doc INAINTE de CREATEOBJECT - vezi docs/testare-ui-vfp.md capcana p.
SELECT introdc
INDEX ON Str(Nvl(nr_doc,0),8) + Icase(tip_rand='B','1', tip_rand='S','2', tip_rand='T','3', tip_rand='D','4', '5') + Padr(Nvl(scd,''),10) TAG ord_doc
INDEX ON Str(Nvl(nr_doc,0),8) + Icase(tip_rand='B','1', tip_rand='S','2', tip_rand='G','3', tip_rand='T','4', tip_rand='D','5', '6') + Padr(Nvl(scd,''),10) TAG ord_doc
SET ORDER TO ord_doc
DO MtLog WITH 'cursoare pregatite, CREATEOBJECT(import_nota, .F.) - lIntern=.F. (import)'
@@ -773,8 +773,8 @@ PROCEDURE CreeazaIntrodc
nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), ;
scd_orig C(20), ascd_orig C(20))
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), expl_manual N(1), ;
scd_orig C(20), ascd_orig C(20), rand_dvi N(1), valuta_proprie N(1))
ENDPROC
PROCEDURE VerificaPereche

View File

@@ -0,0 +1,682 @@
* test_ordine_randuri_document.prg
* Runda32 (model B/G/T): ordinea FIZICA de creare a randurilor unui document nou e B -> G -> T
* (azi era B -> T -> G, cu G adaugat la sfarsit). Verifica RECNO() imediat dupa
* do_adauga_factura(), cat timp documentul e singurul din cursor (nimic altceva interleaved):
* - DOC1 (Furnizor, cu discount): 3 randuri contigue, in ordinea B, G, T;
* - DOC2 (Furnizor, fara discount): 2 randuri contigue, B, T (G lipseste, nu strica ordinea);
* - DOC3 (TVA DVI, cu discount): tot B, G, T - randul T e repurpozat pentru DVI (conturi/sume
* din dvi_*), dar pozitia lui fizica ramane a treia, dupa G.
* Verifica si ordinea DE AFISARE (index ord_doc: B, G, T) - vezi VerificaOrdineAfisare().
*
* Flux REAL: dialogul `import_adauga_factura` (toDlg construit inline in programul principal,
* capcana l - CREATEOBJECT/ADDPROPERTY nu merg dintr-o procedura in acest runtime headless).
*
* Rulare:
* powershell -ExecutionPolicy Bypass -File test_ordine_randuri_document.ps1
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET DECIMALS TO 4
SET NULLDISPLAY TO ''
CLOSE DATABASES
PUBLIC gcUILog, gcSyncDir
gcUILog = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\test_ordine_randuri_document_log.txt"
gcSyncDir = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\uisync_ordine_randuri\"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcUILog)
ON ERROR DO OrErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
TRY
LOCAL gcAppPath, lcPath
gcAppPath = "D:\ROA\ROAGEST\"
SET DEFAULT TO (gcAppPath)
lcPath = gcAppPath + 'Date;' + gcAppPath + 'Include;' + gcAppPath + 'FERESTRE;' + ;
gcAppPath + 'GRAFICE;' + gcAppPath + 'CLASE;' + gcAppPath + 'MENIURI;' + ;
gcAppPath + 'PROGRAME;' + gcAppPath + 'RAPOARTE;' + gcAppPath + 'COMUN;' + ;
gcAppPath + 'COMUN\CLASE;' + gcAppPath + 'COMUN\FERESTRE;' + gcAppPath + 'COMUN\PROGRAME;' + ;
gcAppPath + 'COMUN\GRAFICE;' + gcAppPath + 'COMUN\RAPOARTE;' + gcAppPath + 'COMUN\MENIURI;' + ;
gcAppPath + 'COMUN\UTILE\GRIDEXTRAS;' + gcAppPath + 'COMUN\UTILE\CTL32;' + ;
gcAppPath + 'COMUN\UTILE\HPDF;' + gcAppPath + 'COMUN\UTILE\HPDF\REPORTOUTPUT;' + ;
gcAppPath + 'COMUN\UTILE\WEB;' + gcAppPath + 'COMUN\UTILE\EXCEL;' + ;
ADDBS(SUBSTR(gcAppPath,1,RAT([\],gcAppPath,2)))+[COMUNROA\]
SET PATH TO &lcPath ADDITIVE
DO OrLog WITH 'SET PATH OK'
*----- CLASE -----
SET CLASSLIB TO (gcAppPath + "comun\clase\appwiz") ADDITIVE
SET CLASSLIB TO GESTIUNI ADDITIVE
SET CLASSLIB TO CAUT ADDITIVE
SET CLASSLIB TO BAZA ADDITIVE
SET CLASSLIB TO comun ADDITIVE
SET CLASSLIB TO accessibility.vcx ADDITIVE
SET CLASSLIB TO messagebox ADDITIVE
SET CLASSLIB TO registry ADDITIVE
SET CLASSLIB TO cauta_alfa_forms.vcx ADDITIVE
SET CLASSLIB TO DECABAZA ADDITIVE
SET CLASSLIB TO onomenclatoare ADDITIVE
SET CLASSLIB TO stocuri.vcx ADDITIVE
SET CLASSLIB TO rulaje.vcx ADDITIVE
SET CLASSLIB TO ointroduceri ADDITIVE
SET CLASSLIB TO ointroduceri_web ADDITIVE
SET CLASSLIB TO ointroduceri_depozit ADDITIVE
SET CLASSLIB TO overificari ADDITIVE
SET CLASSLIB TO ferestre_oracle ADDITIVE
SET CLASSLIB TO ferestre_cere_date.vcx ADDITIVE
SET CLASSLIB TO configurare.vcx ADDITIVE
SET CLASSLIB TO serii_numere.vcx ADDITIVE
SET CLASSLIB TO omodificari.vcx ADDITIVE
SET CLASSLIB TO ocompensari.vcx ADDITIVE
SET CLASSLIB TO caut_ora ADDITIVE
SET CLASSLIB TO onote_contabile ADDITIVE
SET CLASSLIB TO otoolbar ADDITIVE
SET CLASSLIB TO bon_fisc ADDITIVE
SET CLASSLIB TO onom_articole ADDITIVE
SET CLASSLIB TO onom_retete ADDITIVE
SET CLASSLIB TO orapoarte ADDITIVE
SET CLASSLIB TO orapoarte_gestiuni ADDITIVE
SET CLASSLIB TO orapoarte_parametri ADDITIVE
SET CLASSLIB TO ONOM_CURS ADDITIVE
SET CLASSLIB TO ctl32_statusbar_fals.vcx ADDITIVE
SET CLASSLIB TO ctl32_common.vcx ADDITIVE
SET CLASSLIB TO ctl32_structs.vcx ADDITIVE
SET CLASSLIB TO ctl32_progressbar.vcx ADDITIVE
SET CLASSLIB TO ctl32_balloontip.vcx ADDITIVE
SET CLASSLIB TO ocriterii.vcx ADDITIVE
SET CLASSLIB TO oavize.vcx ADDITIVE
SET CLASSLIB TO onomenclatoare2 ADDITIVE
SET CLASSLIB TO wwdialogs.vcx ADDITIVE
SET CLASSLIB TO oimportxml.vcx ADDITIVE
SET CLASSLIB TO excelxml.vcx ADDITIVE
SET CLASSLIB TO orapoarte_obinv.vcx ADDITIVE
DO OrLog WITH 'SET CLASSLIB OK'
*----- PROCEDURI (mock-uri PRIMELE, ui_harness la final) -----
SET PROCEDURE TO PROCEDURI
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\mock_caut_valuta.prg" ADDITIVE
SET PROCEDURE TO acces_meniu ADDITIVE
SET PROCEDURE TO cauta_alfa ADDITIVE
SET PROCEDURE TO pmenu ADDITIVE
SET PROCEDURE TO proceduri_comune ADDITIVE
SET PROCEDURE TO quitapp ADDITIVE
SET PROCEDURE TO init_program ADDITIVE
SET PROCEDURE TO oproceduri_listari.prg ADDITIVE
SET PROCEDURE TO oproceduri_configurare.prg ADDITIVE
SET PROCEDURE TO oproceduri_articole.prg ADDITIVE
SET PROCEDURE TO oproceduri_retete.prg ADDITIVE
SET PROCEDURE TO orapoarte.prg ADDITIVE
SET PROCEDURE TO mesaje ADDITIVE
SET PROCEDURE TO oserii_numere.prg ADDITIVE
SET PROCEDURE TO oexport.prg ADDITIVE
SET PROCEDURE TO wwConfig.prg ADDITIVE
SET PROCEDURE TO proceduri_rapoarte.prg ADDITIVE
SET PROCEDURE TO OPROCEDURI_CURS.PRG ADDITIVE
SET PROCEDURE TO validare.prg ADDITIVE
SET PROCEDURE TO GENCURSOR.PRG ADDITIVE
SET PROCEDURE TO OPROCEDURI_COMUNE.PRG ADDITIVE
SET PROCEDURE TO OINIT_OPTIUNI.PRG ADDITIVE
SET PROCEDURE TO updateserver.prg ADDITIVE
SET PROCEDURE TO oinainte_de.prg ADDITIVE
SET PROCEDURE TO ooperatii_comune.prg ADDITIVE
SET PROCEDURE TO Ocompensari.PRG ADDITIVE
SET PROCEDURE TO OPROCEDURI_aMS.PRG ADDITIVE
SET PROCEDURE TO oproceduri_rulaje ADDITIVE
SET PROCEDURE TO oproceduri_stocuri ADDITIVE
SET PROCEDURE TO OINTRODUCERI ADDITIVE
SET PROCEDURE TO oHeader.prg ADDITIVE
SET PROCEDURE TO proceduri_excel.PRG ADDITIVE
SET PROCEDURE TO onomenclatoare.PRG ADDITIVE
SET PROCEDURE TO osecurity ADDITIVE
SET PROCEDURE TO ocautare ADDITIVE
SET PROCEDURE TO orefaceri ADDITIVE
SET PROCEDURE TO ofacturare_comun.PRG ADDITIVE
SET PROCEDURE TO ofacturare_stoc.PRG ADDITIVE
SET PROCEDURE TO oproceduri_casademarcat ADDITIVE
SET PROCEDURE TO oproceduri_casa_marcat_e500 ADDITIVE
SET PROCEDURE TO oproceduri_casa_marcat_mp500 ADDITIVE
SET PROCEDURE TO oproceduri_util.prg ADDITIVE
SET PROCEDURE TO wwxmlhttp.prg ADDITIVE
SET PROCEDURE TO ini.prg ADDITIVE
SET PROCEDURE TO odocumente.prg ADDITIVE
SET PROCEDURE TO regex.prg ADDITIVE
SET PROCEDURE TO wwutils.prg ADDITIVE
SET PROCEDURE TO inchidere_k ADDITIVE
SET PROCEDURE TO iniacces.prg ADDITIVE
SET PROCEDURE TO oupdate.prg ADDITIVE
SET PROCEDURE TO procese.prg ADDITIVE
SET PROCEDURE TO version.prg ADDITIVE
SET PROCEDURE TO xmlaccess.prg ADDITIVE
SET PROCEDURE TO xmlparser.prg ADDITIVE
SET PROCEDURE TO filebringer.prg ADDITIVE
SET PROCEDURE TO wwcodeupdate.prg ADDITIVE
SET PROCEDURE TO wwhttp.prg ADDITIVE
SET PROCEDURE TO xdate.prg ADDITIVE
SET PROCEDURE TO ofacturare.prg ADDITIVE
SET PROCEDURE TO oproceduri_obinv.prg ADDITIVE
SET PROCEDURE TO oproceduri_facturare.prg ADDITIVE
SET PROCEDURE TO email.prg ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\ui_harness.prg" ADDITIVE
DO OrLog WITH 'SET PROCEDURE OK'
*----- Globale -----
PUBLIC gnPc, gnPval, gnPcant, gnPpret, gnPPretval, gnPCurs, gnPVal, gnPPretV, gnPPretVal
STORE 2 TO gnPc, gnPval, gnPVal
gnPcant = 3
STORE 4 TO gnPpret, gnPPretval, gnPPretVal, gnPPretV, gnPCurs
PUBLIC gl406, gcS, gnAn, gnLuna, gnIdFirma, gnIdSucursala, gcAcces, gcFirma
gl406 = .T.
gcS = 'CONTAFIN'
gnAn = YEAR(DATE())
gnLuna = MONTH(DATE())
gnIdFirma = 110
gnIdSucursala = 110
gcAcces = "1;2;3;4;5;6;7;8;"
gcFirma = gcS
PUBLIC nror(65000)
PUBLIC gnMockRaspuns, gcMockUltimMesaj, gnMockUltimTip
gnMockRaspuns = 6
gcMockUltimMesaj = ''
gnMockUltimTip = 0
PUBLIC goExecutor, goApp
goExecutor = CREATEOBJECT('dummyexecutor')
goApp = CREATEOBJECT('dummyapp')
*----- poAct: antetul notei (factura in EUR, curs 5) -----
PUBLIC poAct
poAct = CREATEOBJECT('Custom')
poAct.AddProperty('nume_val', 'EUR')
poAct.AddProperty('curs', 5)
poAct.AddProperty('proc_tva', 1.21)
poAct.AddProperty('nnir', 0)
poAct.AddProperty('id_valuta', 978)
poAct.AddProperty('id_fdoc', 1)
poAct.AddProperty('fdoc', 'Factura')
poAct.AddProperty('id_partc', 601)
poAct.AddProperty('partc', 'FURNIZOR ORDINE SRL')
poAct.AddProperty('serie_act', '')
poAct.AddProperty('dataact', DATE())
poAct.AddProperty('tva_incasare', 0)
poAct.AddProperty('id_set', 1)
poAct.AddProperty('id_gestin', 1)
*----- jtva_coloane2 / saft_taxtable: perechi reale 21% -----
IF USED('jtva_coloane2')
USE IN ('jtva_coloane2')
ENDIF
CREATE CURSOR jtva_coloane2 (ordine N(8), id_jtva_coloana N(14), denumire C(100), ;
jc N(1), jv N(1), afisat N(1), coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14))
INSERT INTO jtva_coloane2 VALUES (0, 0, '', 0, 0, 1, '', '', 0, 0)
INSERT INTO jtva_coloane2 VALUES (1, 220, 'ACH. IMP. 21%', 1, 0, 1, 'FO21B', 'FO21T', 21, 221)
INSERT INTO jtva_coloane2 VALUES (2, 221, 'TVA ACH. IMP. 21%', 1, 0, 1, 'FO21T', '', 21, 0)
IF USED('saft_taxtable')
USE IN ('saft_taxtable')
ENDIF
CREATE CURSOR saft_taxtable (taxname C(250) NULL, typename C(250) NULL, taxcode N(6) NULL, ;
taxtype N(3) NULL, descriere C(250) NULL, tip C(100) NULL, descriere_tip C(250) NULL, ;
procent_taxa N(7,2) NULL, procent_prorata N(7,2) NULL, inactiv N(1) NULL, tva N(1) NULL, ;
wht N(1) NULL, tva_achizitii N(1) NULL, tva_livrari N(1) NULL)
INDEX ON taxcode TAG taxcode
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('', 0, '', 0, 1, 1, 1, 1)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301204-Import de bunuri cota 21%', 301204, '', 21, 1, 0, 1, 0)
DO CreeazaIntrodc WITH 'introdc'
DO CreeazaIntrodc WITH 'introdc_sablon'
INSERT INTO introdc_sablon (scd, scc, cu_tva, ordine, id_set, participa_valuta, tip_rand, ;
id_jtva_coloana, ptva, explicatie_tva) ;
VALUES ('371', '401', 1, 1, 1, .T., 'B', 220, 21, 'ACH. IMP. 21%')
INSERT INTO introdc_sablon (scd, scc, cu_tva, ordine, id_set, participa_valuta, tip_rand, ;
id_jtva_coloana, ptva, explicatie_tva) ;
VALUES ('4426', '401', 1, 2, 1, .T., 'T', 221, 21, 'TVA ACH. IMP. 21%')
GO TOP IN introdc_sablon
IF USED('rul_temp')
USE IN ('rul_temp')
ENDIF
CREATE CURSOR rul_temp (denumire C(100), codmat C(30), cant N(14,3), pret_val N(18,4), ;
pretd N(18,4), pret N(18,4), pret_lei N(18,4), cont C(10), acont C(20), serie C(30), ;
lot C(30), adata_expirare C(10), proc_disc N(6,2), cota_tva N(6,2))
INSERT INTO rul_temp (denumire, codmat, cant, pret, pret_lei, cont, cota_tva) ;
VALUES ('PLACEHOLDER', 'PH', 1, 1, 1, '371', 21)
SELECT introdc
INDEX ON Str(Nvl(nr_doc,0),8) + Icase(tip_rand='B','1', tip_rand='S','2', tip_rand='G','3', tip_rand='T','4', tip_rand='D','5', '6') + Padr(Nvl(scd,''),10) TAG ord_doc
SET ORDER TO ord_doc
DO OrLog WITH 'cursoare pregatite, CREATEOBJECT(import_nota, .F.)'
PUBLIC goObj
goObj = CREATEOBJECT('IMPORT_nota', .F.)
IF VARTYPE(goObj) <> 'O'
DO OrLog WITH 'FAIL: instantiere import_nota'
DO HarnessDone WITH 'done-error'
QUIT
ENDIF
goObj.lDialogAratat = .T.
goObj.oact = poAct
goObj.lSpargeSecundare = .F.
goObj.WindowType = 0
goObj.Visible = .T.
goObj.Show()
goObj.WindowState = 2
DOEVENTS FORCE
SELECT rul_temp
ZAP
goObj.gridart.Refresh()
DOEVENTS FORCE
PRIVATE pnAsserts, pnPass
STORE 0 TO pnAsserts, pnPass
*========================= DOC1: Furnizor + discount (B, G, T) =========================
PUBLIC goDlg, goT
DO AdaugaFacturaF WITH 20000, 100.00
SELECT introdc
SET ORDER TO
=VerificaOrdine('DOC1 (Furnizor+discount)', GasesteDocKey(20000), .T., 1)
=VerificaOrdineAfisare('DOC1 (Furnizor+discount)', GasesteNrDoc(20000), .T.)
DO HarnessStep WITH 0, 'DOC1 (Furnizor+discount) verificat'
*========================= DOC2: Furnizor, fara discount (B, T - fara G) =========================
DO AdaugaFacturaF WITH 20001, 0.00
=VerificaOrdine('DOC2 (Furnizor, fara discount)', GasesteDocKey(20001), .F., 2)
=VerificaOrdineAfisare('DOC2 (Furnizor, fara discount)', GasesteNrDoc(20001), .F.)
DO HarnessStep WITH 1, 'DOC2 (fara discount) verificat'
*========================= DOC3: TVA DVI + discount (B, G, T-DVI) =========================
*-- doc_key ramane al documentului-mama pe toata ramura DVI (ointroduceri.vc2 ~9096-9097);
*-- randul T primeste insa nract-ul DVI-ului (toDlg.dvi_nract), deci NU se poate localiza
*-- documentul dupa nract - vezi GasesteDocKey().
DO AdaugaFacturaDvi WITH 20002, 150.00
=VerificaOrdine('DOC3 (TVA DVI+discount)', GasesteDocKey(20002), .T., 3)
=VerificaOrdineAfisare('DOC3 (TVA DVI+discount)', GasesteNrDoc(20002), .T.)
DO HarnessStep WITH 2, 'DOC3 (DVI+discount) verificat'
DO OrLog WITH 'REZULTAT: ' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' assert-uri PASS'
IF pnPass = pnAsserts
DO OrLog WITH 'REZULTAT: PASS (' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ')'
ELSE
DO OrLog WITH 'REZULTAT: FAIL (' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' assert-uri PASS)'
ENDIF
DO HarnessStep WITH 3, 'final: ' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' PASS'
DO HarnessDone WITH 'done'
CATCH TO loExc
DO OrLog WITH 'CATCH ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']'
DO HarnessDone WITH 'done-error'
ENDTRY
QUIT
*==================================================================================
PROCEDURE AdaugaFacturaF
*-- factura EUR curs 5, mod Furnizor (F), discount optional (0 = fara discount).
LPARAMETERS tnNract, tnDiscBazaVal
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = tnNract
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 601
goDlg.cPartener = 'FURNIZOR ORDINE SRL'
goDlg.cExplicatia = 'Import marfa ordine randuri'
goDlg.nSuma = 1000
goDlg.nSumaLei = 0
goDlg.nCurs = 5
goDlg.nIdValuta = 978
goDlg.cValuta = 'EUR'
goDlg.nIdExplicatieTva = 220
goDlg.cExplicatieTva = 'ACH. IMP. 21%'
goDlg.optTipTva.Value = 1
goDlg.chkInValutaCont.Value = 1
goDlg.chkParticipaValuta.Value = 1
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO OrLog WITH 'DOC ' + TRANSFORM(tnNract) + ': valideaza = ' + TRANSFORM(goDlg.valideaza())
goT = CREATEOBJECT('Empty')
=ADDPROPERTY(goT,'serie_act','')
=ADDPROPERTY(goT,'nract',goDlg.nNract)
=ADDPROPERTY(goT,'dataact',goDlg.dDataAct)
=ADDPROPERTY(goT,'fdoc',goDlg.cFelDoc)
=ADDPROPERTY(goT,'id_fdoc',goDlg.nIdFdoc)
=ADDPROPERTY(goT,'id_partc',goDlg.nIdPartener)
=ADDPROPERTY(goT,'partc',goDlg.cPartener)
=ADDPROPERTY(goT,'explicatia',ALLTRIM(NVL(goDlg.cExplicatia,'')))
=ADDPROPERTY(goT,'suma',ROUND(goDlg.nSuma*goDlg.nCurs,gnPC))
=ADDPROPERTY(goT,'suma_val',goDlg.nSuma)
=ADDPROPERTY(goT,'in_valuta',1)
=ADDPROPERTY(goT,'participa_valuta',.T.)
=ADDPROPERTY(goT,'id_valuta',goDlg.nIdValuta)
=ADDPROPERTY(goT,'curs',goDlg.nCurs)
=ADDPROPERTY(goT,'nume_val',ALLTRIM(NVL(goDlg.cValuta,'')))
=ADDPROPERTY(goT,'cTipTva','F')
=ADDPROPERTY(goT,'id_jtva_coloana',goDlg.nIdExplicatieTva)
=ADDPROPERTY(goT,'dvi_serie','')
=ADDPROPERTY(goT,'dvi_nract',0)
=ADDPROPERTY(goT,'dvi_dataact',DATE())
=ADDPROPERTY(goT,'dvi_id_fdoc',0)
=ADDPROPERTY(goT,'dvi_fdoc','')
=ADDPROPERTY(goT,'dvi_id_partc',0)
=ADDPROPERTY(goT,'dvi_partc','')
=ADDPROPERTY(goT,'dvi_scc','401')
=ADDPROPERTY(goT,'dvi_tva_lei',0)
=ADDPROPERTY(goT,'dvi_tva_val',0)
=ADDPROPERTY(goT,'dvi_in_valuta',.F.)
=ADDPROPERTY(goT,'dvi_id_valuta',0)
=ADDPROPERTY(goT,'dvi_curs',0)
=ADDPROPERTY(goT,'dvi_nume_val','')
=ADDPROPERTY(goT,'dvi_valuta_proprie',0)
=ADDPROPERTY(goT,'disc_baza_lei',ROUND(tnDiscBazaVal*5,gnPC))
=ADDPROPERTY(goT,'disc_baza_val',tnDiscBazaVal)
DO OrLog WITH 'DOC ' + TRANSFORM(tnNract) + ': do_adauga_factura = ' + TRANSFORM(goObj.do_adauga_factura(goT))
goDlg.Hide()
DOEVENTS FORCE
ENDPROC
PROCEDURE AdaugaFacturaDvi
*-- factura EUR curs 5, mod TVA DVI (D), discount optional.
LPARAMETERS tnNract, tnDiscBazaVal
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = tnNract
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 601
goDlg.cPartener = 'FURNIZOR ORDINE SRL'
goDlg.cExplicatia = 'Import marfa ordine randuri (DVI)'
goDlg.nSuma = 1000
goDlg.nSumaLei = 0
goDlg.nCurs = 5
goDlg.nIdValuta = 978
goDlg.cValuta = 'EUR'
goDlg.nIdExplicatieTva = 220
goDlg.cExplicatieTva = 'ACH. IMP. 21%'
goDlg.optTipTva.Value = 2
goDlg.chkInValutaCont.Value = 1
goDlg.chkParticipaValuta.Value = 1
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO OrLog WITH 'DOC ' + TRANSFORM(tnNract) + ' (DVI): valideaza = ' + TRANSFORM(goDlg.valideaza())
goT = CREATEOBJECT('Empty')
=ADDPROPERTY(goT,'serie_act','')
=ADDPROPERTY(goT,'nract',goDlg.nNract)
=ADDPROPERTY(goT,'dataact',goDlg.dDataAct)
=ADDPROPERTY(goT,'fdoc',goDlg.cFelDoc)
=ADDPROPERTY(goT,'id_fdoc',goDlg.nIdFdoc)
=ADDPROPERTY(goT,'id_partc',goDlg.nIdPartener)
=ADDPROPERTY(goT,'partc',goDlg.cPartener)
=ADDPROPERTY(goT,'explicatia',ALLTRIM(NVL(goDlg.cExplicatia,'')))
=ADDPROPERTY(goT,'suma',ROUND(goDlg.nSuma*goDlg.nCurs,gnPC))
=ADDPROPERTY(goT,'suma_val',goDlg.nSuma)
=ADDPROPERTY(goT,'in_valuta',1)
=ADDPROPERTY(goT,'participa_valuta',.T.)
=ADDPROPERTY(goT,'id_valuta',goDlg.nIdValuta)
=ADDPROPERTY(goT,'curs',goDlg.nCurs)
=ADDPROPERTY(goT,'nume_val',ALLTRIM(NVL(goDlg.cValuta,'')))
=ADDPROPERTY(goT,'cTipTva','D')
=ADDPROPERTY(goT,'id_jtva_coloana',goDlg.nIdExplicatieTva)
=ADDPROPERTY(goT,'dvi_serie','')
=ADDPROPERTY(goT,'dvi_nract',tnNract+1000)
=ADDPROPERTY(goT,'dvi_dataact',DATE())
=ADDPROPERTY(goT,'dvi_id_fdoc',2)
=ADDPROPERTY(goT,'dvi_fdoc','DVI')
=ADDPROPERTY(goT,'dvi_id_partc',900)
=ADDPROPERTY(goT,'dvi_partc','DIRECTIA VAMALA')
=ADDPROPERTY(goT,'dvi_scc','401')
=ADDPROPERTY(goT,'dvi_tva_lei',1050.00)
=ADDPROPERTY(goT,'dvi_tva_val',0)
=ADDPROPERTY(goT,'dvi_in_valuta',.F.)
=ADDPROPERTY(goT,'dvi_id_valuta',0)
=ADDPROPERTY(goT,'dvi_curs',0)
=ADDPROPERTY(goT,'dvi_nume_val','')
=ADDPROPERTY(goT,'dvi_valuta_proprie',1)
=ADDPROPERTY(goT,'disc_baza_lei',ROUND(tnDiscBazaVal*5,gnPC))
=ADDPROPERTY(goT,'disc_baza_val',tnDiscBazaVal)
DO OrLog WITH 'DOC ' + TRANSFORM(tnNract) + ' (DVI): do_adauga_factura = ' + TRANSFORM(goObj.do_adauga_factura(goT))
goDlg.Hide()
DOEVENTS FORCE
ENDPROC
PROCEDURE GasesteDocKey
*-- doc_key ramane al documentului-mama pe toata ramura (inclusiv randul T repurpozat pentru
*-- DVI, care primeste alt nract - vezi ointroduceri.vc2 ~9096-9097) - localizeaza documentul
*-- prin randul B (singurul care pastreaza mereu nract-ul facturii) si intoarce doc_key.
LPARAMETERS tnNract
LOCAL lcDocKey
lcDocKey = ''
SELECT introdc
LOCATE FOR nract == tnNract AND tip_rand == 'B'
IF FOUND()
lcDocKey = ALLTRIM(NVL(doc_key,''))
ENDIF
RETURN lcDocKey
ENDPROC
PROCEDURE GasesteNrDoc
*-- nr_doc al randului B (identic pe toate randurile B/G/T ale aceluiasi document) - vezi ointroduceri.vc2 ~9032.
LPARAMETERS tnNract
LOCAL lnNrDoc
lnNrDoc = 0
SELECT introdc
LOCATE FOR nract == tnNract AND tip_rand == 'B'
IF FOUND()
lnNrDoc = nr_doc
ENDIF
RETURN lnNrDoc
ENDPROC
PROCEDURE VerificaOrdine
*-- verifica RECNO() fizic: B < [G <] T, contigue, imediat dupa creare documentului doc_key.
LPARAMETERS tcLabel, tcDocKey, tlAreG, tnPasIdx
LOCAL lnRecnoB, lnRecnoG, lnRecnoT
STORE 0 TO lnRecnoB, lnRecnoG, lnRecnoT
=Assert3(tcLabel + '-doc_key gasit (GasesteDocKey)', IIF(!EMPTY(tcDocKey),1,0), 1)
SELECT introdc
SCAN FOR ALLTRIM(NVL(doc_key,'')) == tcDocKey
DO CASE
CASE tip_rand == 'B' AND lnRecnoB = 0
lnRecnoB = RECNO()
CASE tip_rand == 'G'
lnRecnoG = RECNO()
CASE tip_rand == 'T' AND lnRecnoT = 0
lnRecnoT = RECNO()
ENDCASE
ENDSCAN
=Assert3(tcLabel + '-B gasit (recno>0)', IIF(lnRecnoB>0,1,0), 1)
=Assert3(tcLabel + '-T gasit (recno>0)', IIF(lnRecnoT>0,1,0), 1)
IF tlAreG
=Assert3(tcLabel + '-G gasit (recno>0)', IIF(lnRecnoG>0,1,0), 1)
=Assert3(tcLabel + '-ordine: RECNO(B) < RECNO(G)', IIF(lnRecnoB < lnRecnoG,1,0), 1)
=Assert3(tcLabel + '-ordine: RECNO(G) < RECNO(T)', IIF(lnRecnoG < lnRecnoT,1,0), 1)
=Assert3(tcLabel + '-contiguitate: RECNO(G)=RECNO(B)+1', IIF(lnRecnoG = lnRecnoB+1,1,0), 1)
=Assert3(tcLabel + '-contiguitate: RECNO(T)=RECNO(G)+1', IIF(lnRecnoT = lnRecnoG+1,1,0), 1)
ELSE
=Assert3(tcLabel + '-fara discount: niciun rand G', IIF(lnRecnoG=0,1,0), 1)
=Assert3(tcLabel + '-ordine: RECNO(B) < RECNO(T)', IIF(lnRecnoB < lnRecnoT,1,0), 1)
=Assert3(tcLabel + '-contiguitate: RECNO(T)=RECNO(B)+1', IIF(lnRecnoT = lnRecnoB+1,1,0), 1)
ENDIF
DO OrLog WITH tcLabel + ': RECNO(B)=' + TRANSFORM(lnRecnoB) + ' RECNO(G)=' + TRANSFORM(lnRecnoG) + ' RECNO(T)=' + TRANSFORM(lnRecnoT)
ENDPROC
PROCEDURE VerificaOrdineAfisare
*-- verifica ordinea DE AFISARE (Set Order To ord_doc): pentru acelasi nr_doc, succesiunea tip_rand.
LPARAMETERS tcLabel, tnNrDoc, tlAreG
LOCAL lcSecventa, lcAsteptat
lcSecventa = ''
SELECT introdc
SET ORDER TO ord_doc
GO TOP
SCAN FOR nr_doc == tnNrDoc
lcSecventa = lcSecventa + tip_rand
ENDSCAN
SET ORDER TO
lcAsteptat = IIF(tlAreG, 'BGT', 'BT')
=AssertStr(tcLabel + '-afisare: secventa tip_rand (ord_doc)', lcSecventa, lcAsteptat)
ENDPROC
PROCEDURE CreeazaIntrodc
LPARAMETERS tcAlias
IF USED(tcAlias)
USE IN (tcAlias)
ENDIF
CREATE CURSOR (tcAlias) ( ;
id_note N(14), explicatia C(100), scd C(10), ascd C(20), scc C(10), ascc C(20), ;
cu_tva N(1), id_set N(14), ordine N(8), in_valuta N(1), id_jtva_coloana N(14) NULL, ;
ptva N(6,2), explicatie_tva C(50), tipjurnal C(2), taxcode N(6), paymentcode C(9), ;
suma N(18,4), suma_val N(18,4), id_partd N(14), id_partc N(14), partd C(100), partc C(100), ;
id_fact N(14), id_factd N(14), id_factc N(14), pereched N(14), perechec N(14), ;
nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), expl_manual N(1), ;
scd_orig C(20), ascd_orig C(20), rand_dvi N(1), valuta_proprie N(1))
ENDPROC
PROCEDURE Assert3
LPARAMETERS tcLabel, tuActual, tuExpected
pnAsserts = pnAsserts + 1
IF ABS(NVL(tuActual,0) - tuExpected) < 0.02
pnPass = pnPass + 1
DO OrLog WITH ' PASS ' + tcLabel + ' (=' + TRANSFORM(tuActual) + ')'
ELSE
DO OrLog WITH ' FAIL ' + tcLabel + ' (actual=' + TRANSFORM(tuActual) + ' asteptat=' + TRANSFORM(tuExpected) + ')'
ENDIF
ENDPROC
PROCEDURE AssertStr
LPARAMETERS tcLabel, tcActual, tcExpected
pnAsserts = pnAsserts + 1
IF tcActual == tcExpected
pnPass = pnPass + 1
DO OrLog WITH ' PASS ' + tcLabel + ' (=[' + tcActual + '])'
ELSE
DO OrLog WITH ' FAIL ' + tcLabel + ' (actual=[' + tcActual + '] asteptat=[' + tcExpected + '])'
ENDIF
ENDPROC
PROCEDURE OrErr
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
DO OrLog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
ENDPROC
PROCEDURE OrLog
LPARAMETERS tcMsg
SET SAFETY OFF
LOCAL lcL
lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '')
STRTOFILE(lcL + tcMsg + CHR(13)+CHR(10), gcUILog)
ENDPROC
DEFINE CLASS dummyapp AS Custom
PROCEDURE ReadIni
LPARAMETERS tcSection, tcKey
RETURN ''
ENDPROC
PROCEDURE WriteIni
LPARAMETERS tcSection, tcKey, tcValue
RETURN .T.
ENDPROC
ENDDEFINE
DEFINE CLASS dummyexecutor AS Custom
cEroare = ''
PROCEDURE oExecute
LPARAMETERS tcSql, tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF 'VJTVA_COLOANE' $ UPPER(m.tcSql)
DO CreeazaJtvaColoaneView WITH m.tcCursor
RETURN 1
ENDIF
IF UPPER(ALLTRIM(m.tcCursor)) == 'RUL_TEMP'
CREATE CURSOR (m.tcCursor) (denumire C(100), codmat C(30), cant N(14,3), ;
pret_val N(18,4), pretd N(18,4), pret N(18,4), pret_lei N(18,4), cont C(10), ;
acont C(20), serie C(30), lot C(30), adata_expirare C(10), proc_disc N(6,2), cota_tva N(6,2))
RETURN 1
ENDIF
IF 'CONFIG_ANALITICE' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (camp_leg_prefix C(30), camp_leg_sufix C(30))
INSERT INTO (m.tcCursor) VALUES ('', '')
RETURN 1
ENDIF
IF 'FCONTURI_ANALITICE' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (acont C(20))
INSERT INTO (m.tcCursor) VALUES ('')
RETURN 1
ENDIF
IF 'VPLCONT_ANALITIC' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (cont C(10), acont C(20))
RETURN 1
ENDIF
IF 'VCONFIG_CONT_IREG' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (contpart C(10), fel_cont N(1), cu_inregistrari N(1), ;
explic_cont C(100), exceptie C(10), pozitie N(1), invers N(1), gasit N(1))
INSERT INTO (m.tcCursor) VALUES ('401', 0, 0, 'Furnizori', '', 0, 0, 0)
RETURN 1
ENDIF
CREATE CURSOR (m.tcCursor) (id_temp N(1))
RETURN 1
ENDPROC
PROCEDURE oExecuta
LPARAMETERS tcSql, tcCursor
IF !EMPTY(m.tcCursor)
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF UPPER(m.tcCursor) == 'CJTVACOL4427'
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14))
ELSE
CREATE CURSOR (m.tcCursor) (id_temp N(1))
ENDIF
ENDIF
RETURN .T.
ENDPROC
PROCEDURE oSelect2Value
LPARAMETERS tcSql, toValue
toValue = ''
RETURN 1
ENDPROC
PROCEDURE oReset
ENDPROC
ENDDEFINE
PROCEDURE CreeazaJtvaColoaneView
LPARAMETERS tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14), denumire C(100), jc N(1), jv N(1), ;
coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14) NULL, afisat N(1), ;
id_jtva_ex N(14) NULL, id_jtva_neex N(14) NULL, ordine N(8), ;
taxcode N(6) NULL, taxcode_neexigibil N(6) NULL, taxcode_n50 N(6) NULL, ;
taxcode_n50_tvai N(6) NULL, taxcode_n100 N(6) NULL, taxcode_regularizare N(6) NULL, taxcode_tvai N(6) NULL)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, afisat, ordine, cota_tva) VALUES (0, '', 0, 0, 1, 0, 0)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (220, 'ACH. IMP. 21%', 1, 0, 'FO21B', 21, 221, 1, 1, 301204)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (221, 'TVA ACH. IMP. 21%', 1, 0, 'FO21T', 21, 1, 2, 301204)
ENDPROC

View File

@@ -0,0 +1,12 @@
# test_ordine_randuri_document.ps1 - wrapper peste harness-ul generic pentru ordinea fizica de
# creare a randurilor (B -> G -> T) la adaugarea unei facturi - Runda32.
# powershell -ExecutionPolicy Bypass -File test_ordine_randuri_document.ps1
$ErrorActionPreference = 'Stop'
$Teste = $PSScriptRoot
& (Join-Path (Split-Path $Teste -Parent) 'vfp_ui_harness.ps1') `
-TestPrg (Join-Path $Teste 'test_ordine_randuri_document.prg') `
-Steps @('doc1_furnizor_discount','doc2_furnizor_fara_discount','doc3_dvi_discount','final') `
-ShotsDir (Join-Path $Teste 'screenshots_ordine_randuri') `
-SyncDir (Join-Path $Teste 'uisync_ordine_randuri') `
-StepTimeoutSec 180 `
-ReadyTimeoutSec 180

View File

@@ -541,8 +541,8 @@ PROCEDURE CreeazaIntrodc
nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), ;
scd_orig C(20), ascd_orig C(20))
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), expl_manual N(1), ;
scd_orig C(20), ascd_orig C(20), rand_dvi N(1), valuta_proprie N(1))
ENDPROC
FUNCTION RECCOUNT_ACTIVE

View File

@@ -0,0 +1,853 @@
* test_repro_bug_nract_dvi_propagat.prg
* Test de REPRODUCERE (nu modifica NIMIC din codul aplicatiei). Ipoteza de verificat:
* Grid1.cNract.Text1.Valid (COMUN\clase\ointroduceri.vcx) apeleaza neconditionat
* Thisform.copiaza_valoare('nract'). copiaza_valoare propaga valoarea campului pe tot
* grupul doc_key, sarind DOAR randurile-TINTA cu rand_dvi=1 - dar NU protejeaza cazul in
* care randul-SURSA (pozitia curenta la apel) e chiar randul T al DVI-ului. Randul T al
* DVI-ului pastreaza doc_key-ul facturii-mama (vezi do_adauga_factura, cazul cTipTva='D':
* "doc_key ramane al documentului-mama, desi randul poarta partener/conturi de vama"),
* deci daca Valid se declanseaza cu pointerul din introdc pe randul DVI, numarul DVI-ului
* (101) s-ar scrie peste nract-ul randurilor B/G/S ale facturii principale (15000).
*
* Model de test (structura harness, capcane, toDlg inline): test_e2e_dvi_ron_discount.prg.
* Scenariu: factura import EUR (curs 5.23), discount financiar (doar baza), TVA pe DVI
* platit in RON, DVI cu nract/partener propriu (vama). Flux REAL: import_adauga_factura
* (dialog) + do_adauga_articol() + sincronizeaza() reale, NU insert direct in cursoare.
*
* Rulare:
* powershell -ExecutionPolicy Bypass -File test_repro_bug_nract_dvi_propagat.ps1
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET DECIMALS TO 4
SET NULLDISPLAY TO ''
CLOSE DATABASES
PUBLIC gcUILog, gcSyncDir
gcUILog = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\test_repro_bug_nract_dvi_propagat_log.txt"
gcSyncDir = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\uisync_repro_bug_nract_dvi\"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcUILog)
ON ERROR DO EeErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
TRY
LOCAL gcAppPath, lcPath
gcAppPath = "D:\ROA\ROAGEST\"
SET DEFAULT TO (gcAppPath)
lcPath = gcAppPath + 'COMUN\Utile\Teste\achizitie_import\stub_verificare;' + ;
gcAppPath + 'Date;' + gcAppPath + 'Include;' + gcAppPath + 'FERESTRE;' + ;
gcAppPath + 'GRAFICE;' + gcAppPath + 'CLASE;' + gcAppPath + 'MENIURI;' + ;
gcAppPath + 'PROGRAME;' + gcAppPath + 'RAPOARTE;' + gcAppPath + 'COMUN;' + ;
gcAppPath + 'COMUN\CLASE;' + gcAppPath + 'COMUN\FERESTRE;' + gcAppPath + 'COMUN\PROGRAME;' + ;
gcAppPath + 'COMUN\GRAFICE;' + gcAppPath + 'COMUN\RAPOARTE;' + gcAppPath + 'COMUN\MENIURI;' + ;
gcAppPath + 'COMUN\UTILE\GRIDEXTRAS;' + gcAppPath + 'COMUN\UTILE\CTL32;' + ;
gcAppPath + 'COMUN\UTILE\HPDF;' + gcAppPath + 'COMUN\UTILE\HPDF\REPORTOUTPUT;' + ;
gcAppPath + 'COMUN\UTILE\WEB;' + gcAppPath + 'COMUN\UTILE\EXCEL;' + ;
ADDBS(SUBSTR(gcAppPath,1,RAT([\],gcAppPath,2)))+[COMUNROA\]
SET PATH TO &lcPath ADDITIVE
DO EeLog WITH 'SET PATH OK'
*----- CLASE -----
SET CLASSLIB TO (gcAppPath + "comun\clase\appwiz") ADDITIVE
SET CLASSLIB TO GESTIUNI ADDITIVE
SET CLASSLIB TO CAUT ADDITIVE
SET CLASSLIB TO BAZA ADDITIVE
SET CLASSLIB TO comun ADDITIVE
SET CLASSLIB TO accessibility.vcx ADDITIVE
SET CLASSLIB TO messagebox ADDITIVE
SET CLASSLIB TO registry ADDITIVE
SET CLASSLIB TO cauta_alfa_forms.vcx ADDITIVE
SET CLASSLIB TO DECABAZA ADDITIVE
SET CLASSLIB TO onomenclatoare ADDITIVE
SET CLASSLIB TO stocuri.vcx ADDITIVE
SET CLASSLIB TO rulaje.vcx ADDITIVE
SET CLASSLIB TO ointroduceri ADDITIVE
SET CLASSLIB TO ointroduceri_web ADDITIVE
SET CLASSLIB TO ointroduceri_depozit ADDITIVE
SET CLASSLIB TO overificari ADDITIVE
SET CLASSLIB TO ferestre_oracle ADDITIVE
SET CLASSLIB TO ferestre_cere_date.vcx ADDITIVE
SET CLASSLIB TO configurare.vcx ADDITIVE
SET CLASSLIB TO serii_numere.vcx ADDITIVE
SET CLASSLIB TO omodificari.vcx ADDITIVE
SET CLASSLIB TO ocompensari.vcx ADDITIVE
SET CLASSLIB TO caut_ora ADDITIVE
SET CLASSLIB TO onote_contabile ADDITIVE
SET CLASSLIB TO otoolbar ADDITIVE
SET CLASSLIB TO bon_fisc ADDITIVE
SET CLASSLIB TO onom_articole ADDITIVE
SET CLASSLIB TO onom_retete ADDITIVE
SET CLASSLIB TO orapoarte ADDITIVE
SET CLASSLIB TO orapoarte_gestiuni ADDITIVE
SET CLASSLIB TO orapoarte_parametri ADDITIVE
SET CLASSLIB TO ONOM_CURS ADDITIVE
SET CLASSLIB TO ctl32_statusbar_fals.vcx ADDITIVE
SET CLASSLIB TO ctl32_common.vcx ADDITIVE
SET CLASSLIB TO ctl32_structs.vcx ADDITIVE
SET CLASSLIB TO ctl32_progressbar.vcx ADDITIVE
SET CLASSLIB TO ctl32_balloontip.vcx ADDITIVE
SET CLASSLIB TO ocriterii.vcx ADDITIVE
SET CLASSLIB TO oavize.vcx ADDITIVE
SET CLASSLIB TO onomenclatoare2 ADDITIVE
SET CLASSLIB TO wwdialogs.vcx ADDITIVE
SET CLASSLIB TO oimportxml.vcx ADDITIVE
SET CLASSLIB TO excelxml.vcx ADDITIVE
SET CLASSLIB TO orapoarte_obinv.vcx ADDITIVE
DO EeLog WITH 'SET CLASSLIB OK'
*----- PROCEDURI (mock-uri PRIMELE, ui_harness la final) -----
SET PROCEDURE TO PROCEDURI
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\mock_caut_valuta.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_cauta_nom_articole.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\mock_oscrie_in_fisiere.prg" ADDITIVE
SET PROCEDURE TO acces_meniu ADDITIVE
SET PROCEDURE TO cauta_alfa ADDITIVE
SET PROCEDURE TO pmenu ADDITIVE
SET PROCEDURE TO proceduri_comune ADDITIVE
SET PROCEDURE TO quitapp ADDITIVE
SET PROCEDURE TO init_program ADDITIVE
SET PROCEDURE TO oproceduri_listari.prg ADDITIVE
SET PROCEDURE TO oproceduri_configurare.prg ADDITIVE
SET PROCEDURE TO oproceduri_articole.prg ADDITIVE
SET PROCEDURE TO oproceduri_retete.prg ADDITIVE
SET PROCEDURE TO orapoarte.prg ADDITIVE
SET PROCEDURE TO mesaje ADDITIVE
SET PROCEDURE TO oserii_numere.prg ADDITIVE
SET PROCEDURE TO oexport.prg ADDITIVE
SET PROCEDURE TO wwConfig.prg ADDITIVE
SET PROCEDURE TO proceduri_rapoarte.prg ADDITIVE
SET PROCEDURE TO OPROCEDURI_CURS.PRG ADDITIVE
SET PROCEDURE TO validare.prg ADDITIVE
SET PROCEDURE TO GENCURSOR.PRG ADDITIVE
SET PROCEDURE TO OPROCEDURI_COMUNE.PRG ADDITIVE
SET PROCEDURE TO OINIT_OPTIUNI.PRG ADDITIVE
SET PROCEDURE TO updateserver.prg ADDITIVE
SET PROCEDURE TO oinainte_de.prg ADDITIVE
SET PROCEDURE TO ooperatii_comune.prg ADDITIVE
SET PROCEDURE TO Ocompensari.PRG ADDITIVE
SET PROCEDURE TO OPROCEDURI_aMS.PRG ADDITIVE
SET PROCEDURE TO oproceduri_rulaje ADDITIVE
SET PROCEDURE TO oproceduri_stocuri ADDITIVE
SET PROCEDURE TO OINTRODUCERI ADDITIVE
SET PROCEDURE TO oHeader.prg ADDITIVE
SET PROCEDURE TO proceduri_excel.PRG ADDITIVE
SET PROCEDURE TO onomenclatoare.PRG ADDITIVE
SET PROCEDURE TO osecurity ADDITIVE
SET PROCEDURE TO ocautare ADDITIVE
SET PROCEDURE TO orefaceri ADDITIVE
SET PROCEDURE TO ofacturare_comun.PRG ADDITIVE
SET PROCEDURE TO ofacturare_stoc.PRG ADDITIVE
SET PROCEDURE TO oproceduri_casademarcat ADDITIVE
SET PROCEDURE TO oproceduri_casa_marcat_e500 ADDITIVE
SET PROCEDURE TO oproceduri_casa_marcat_mp500 ADDITIVE
SET PROCEDURE TO oproceduri_util.prg ADDITIVE
SET PROCEDURE TO wwxmlhttp.prg ADDITIVE
SET PROCEDURE TO ini.prg ADDITIVE
SET PROCEDURE TO odocumente.prg ADDITIVE
SET PROCEDURE TO regex.prg ADDITIVE
SET PROCEDURE TO wwutils.prg ADDITIVE
SET PROCEDURE TO inchidere_k ADDITIVE
SET PROCEDURE TO iniacces.prg ADDITIVE
SET PROCEDURE TO oupdate.prg ADDITIVE
SET PROCEDURE TO procese.prg ADDITIVE
SET PROCEDURE TO version.prg ADDITIVE
SET PROCEDURE TO xmlaccess.prg ADDITIVE
SET PROCEDURE TO xmlparser.prg ADDITIVE
SET PROCEDURE TO filebringer.prg ADDITIVE
SET PROCEDURE TO wwcodeupdate.prg ADDITIVE
SET PROCEDURE TO wwhttp.prg ADDITIVE
SET PROCEDURE TO xdate.prg ADDITIVE
SET PROCEDURE TO ofacturare.prg ADDITIVE
SET PROCEDURE TO oproceduri_obinv.prg ADDITIVE
SET PROCEDURE TO oproceduri_facturare.prg ADDITIVE
SET PROCEDURE TO email.prg ADDITIVE
SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\ui_harness.prg" ADDITIVE
DO EeLog WITH 'SET PROCEDURE OK'
*----- Globale -----
PUBLIC gnPc, gnPval, gnPcant, gnPpret, gnPPretval, gnPCurs, gnPVal, gnPPretV, gnPPretVal
STORE 2 TO gnPc, gnPval, gnPVal
gnPcant = 3
STORE 4 TO gnPpret, gnPPretval, gnPPretVal, gnPPretV, gnPCurs
PUBLIC gl406, gcS, gnAn, gnLuna, gnIdFirma, gnIdSucursala, gcAcces, gcFirma
gl406 = .T.
gcS = 'CONTAFIN'
gnAn = YEAR(DATE())
gnLuna = MONTH(DATE())
gnIdFirma = 110
gnIdSucursala = 110
gcAcces = "1;2;3;4;5;6;7;8;"
gcFirma = gcS
PUBLIC nror(65000)
PUBLIC gnMockRaspuns, gcMockUltimMesaj, gnMockUltimTip, gcMockArtCodmat
gnMockRaspuns = 6
gcMockUltimMesaj = ''
gnMockUltimTip = 0
PUBLIC gnButon
gnButon = 1
gcMockArtCodmat = ''
PUBLIC goExecutor, goApp
goExecutor = CREATEOBJECT('dummyexecutor')
goApp = CREATEOBJECT('dummyapp')
*----- poAct: antetul notei (factura import EUR, curs 5.23) -----
PUBLIC poAct
poAct = CREATEOBJECT('Custom')
poAct.AddProperty('nume_val', 'EUR')
poAct.AddProperty('curs', 5.23)
poAct.AddProperty('proc_tva', 1.21)
poAct.AddProperty('nnir', 0)
poAct.AddProperty('id_valuta', 978)
poAct.AddProperty('id_fdoc', 1)
poAct.AddProperty('fdoc', 'Factura')
poAct.AddProperty('id_partc', 601)
poAct.AddProperty('partc', 'FURNIZOR EXTERN GMBH')
poAct.AddProperty('serie_act', '')
poAct.AddProperty('dataact', DATE())
poAct.AddProperty('tva_incasare', 0)
poAct.AddProperty('id_set', 1)
poAct.AddProperty('id_gestin', 1)
*----- jtva_coloane2 / saft_taxtable: perechi reale 21% (achizitii interne + import) -----
IF USED('jtva_coloane2')
USE IN ('jtva_coloane2')
ENDIF
CREATE CURSOR jtva_coloane2 (ordine N(8), id_jtva_coloana N(14), denumire C(100), ;
jc N(1), jv N(1), afisat N(1), coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14))
INSERT INTO jtva_coloane2 VALUES (0, 0, '', 0, 0, 1, '', '', 0, 0)
INSERT INTO jtva_coloane2 VALUES (1, 208, 'ACH. INT. 21%', 1, 0, 1, 'RO21B', 'RO21T', 21, 209)
INSERT INTO jtva_coloane2 VALUES (2, 209, 'TVA ACH. INT. 21%', 1, 0, 1, 'RO21T', '', 21, 0)
INSERT INTO jtva_coloane2 VALUES (3, 220, 'ACH. IMP. 21%', 1, 0, 1, 'FO21B', 'FO21T', 21, 221)
INSERT INTO jtva_coloane2 VALUES (4, 221, 'TVA ACH. IMP. 21%', 1, 0, 1, 'FO21T', '', 21, 0)
IF USED('saft_taxtable')
USE IN ('saft_taxtable')
ENDIF
CREATE CURSOR saft_taxtable (taxname C(250) NULL, typename C(250) NULL, taxcode N(6) NULL, ;
taxtype N(3) NULL, descriere C(250) NULL, tip C(100) NULL, descriere_tip C(250) NULL, ;
procent_taxa N(7,2) NULL, procent_prorata N(7,2) NULL, inactiv N(1) NULL, tva N(1) NULL, ;
wht N(1) NULL, tva_achizitii N(1) NULL, tva_livrari N(1) NULL)
INDEX ON taxcode TAG taxcode
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('', 0, '', 0, 1, 1, 1, 1)
INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
VALUES ('301204-Import de bunuri cota 21%', 301204, '', 21, 1, 0, 1, 0)
DO CreeazaIntrodc WITH 'introdc'
DO CreeazaIntrodc WITH 'introdc_sablon'
INSERT INTO introdc_sablon (scd, scc, cu_tva, ordine, id_set, participa_valuta, tip_rand, ;
id_jtva_coloana, ptva, explicatie_tva) ;
VALUES ('371', '401', 1, 1, 1, .T., 'B', 208, 21, 'ACH. INT. 21%')
INSERT INTO introdc_sablon (scd, scc, cu_tva, ordine, id_set, participa_valuta, tip_rand, ;
id_jtva_coloana, ptva, explicatie_tva) ;
VALUES ('4426', '401', 1, 2, 1, .T., 'T', 209, 21, 'TVA ACH. INT. 21%')
GO TOP IN introdc_sablon
DO CreeazaRulTemp
INSERT INTO rul_temp (denumire, codmat, cant, pret, pret_lei, cont, cota_tva) ;
VALUES ('PLACEHOLDER', 'PH', 1, 1, 1, '371', 21)
*-- index ord_doc INAINTE de CREATEOBJECT (capcana p, docs/testare-ui-vfp.md)
SELECT introdc
INDEX ON Str(Nvl(nr_doc,0),8) + Icase(tip_rand='B','1', tip_rand='S','2', tip_rand='G','3', tip_rand='T','4', tip_rand='D','5', '6') + Padr(Nvl(scd,''),10) TAG ord_doc
SET ORDER TO ord_doc
*-- vezi antetul test_e2e_dvi_ron_discount.prg: tlIntern BARA, aceeasi valoare ca la CREATEOBJECT
PRIVATE tlIntern
tlIntern = .F.
PUBLIC gcTempPath
gcTempPath = ADDBS(SYS(2023))
PUBLIC gnHandle
gnHandle = -1
PUBLIC gnTipGest
gnTipGest = 0
PUBLIC gcCondSucursala
gcCondSucursala = ''
DO EeLog WITH 'cursoare pregatite, CREATEOBJECT(import_nota, .F. - mod import)'
PUBLIC goObj
goObj = CREATEOBJECT('IMPORT_nota', .F.)
IF VARTYPE(goObj) <> 'O'
DO EeLog WITH 'FAIL: instantiere import_nota'
DO HarnessDone WITH 'done-error'
QUIT
ENDIF
goObj.lDialogAratat = .T.
goObj.oact = poAct
goObj.lSpargeSecundare = .F.
goObj.WindowType = 0
goObj.Visible = .T.
goObj.Show()
goObj.WindowState = 2
DOEVENTS FORCE
SELECT rul_temp
ZAP
goObj.gridart.Refresh()
DOEVENTS FORCE
PRIVATE pnAsserts, pnPass
STORE 0 TO pnAsserts, pnPass
DO HarnessStep WITH 0, 'nota goala afisata, mod import (.F.)'
*========================= DIALOG: factura EUR 15000 + TVA DVI (nract 101) in RON + discount =========================
PUBLIC goDlg
goDlg = CREATEOBJECT('import_adauga_factura', goObj)
goDlg.cFelDoc = 'Factura'
goDlg.nIdFdoc = 1
goDlg.nNract = 15000
goDlg.dDataAct = DATE()
goDlg.nIdPartener = 601
goDlg.cPartener = 'FURNIZOR EXTERN GMBH'
goDlg.cExplicatia = 'Repro bug propagare nract DVI'
goDlg.nSuma = 1000
goDlg.nSumaLei = 0
goDlg.nCurs = 5.23
goDlg.nIdValuta = 978
goDlg.cValuta = 'EUR'
goDlg.chkInValutaCont.Value = 1
goDlg.chkParticipaValuta.Value = 1
goDlg.nIdExplicatieTva = 220
goDlg.cExplicatieTva = 'ACH. IMP. 21%'
goDlg.nProcentTva = 21
*-- DVI: identitate proprie (document vamal, partener vamal, nract 101)
goDlg.cSerieDvi = ''
goDlg.nNractDvi = 101
goDlg.dDviData = DATE()
goDlg.nIdFdocDVI = 2
goDlg.cFelDocDvi = 'DVI'
goDlg.nDviIdPartener = 900
goDlg.cDviPartener = 'DIRECTIA VAMALA'
*-- comuta pe mod TVA DVI (radio "TVA in vama") - flux real, InteractiveChange
goDlg.optTipTva.Value = 2
goDlg.optTipTva.InteractiveChange()
*-- alegere RON pe blocul DVI, prin picker-ul REAL (mock_caut_valuta, coada FIFO cu 1 pick)
PUBLIC goMockValuta, goMockValutaCoada
goMockValuta = CREATEOBJECT('Custom')
goMockValuta.AddProperty('id_valuta', 1)
goMockValuta.AddProperty('nume_val', 'RON')
goMockValutaCoada = CREATEOBJECT('Collection')
LOCAL loValRon
loValRon = CREATEOBJECT('Custom')
loValRon.AddProperty('id_valuta', 1)
loValRon.AddProperty('nume_val', 'RON')
goMockValutaCoada.Add(loValRon)
goDlg.cmdDviValuta.Click()
=AssertStr('1-DVI valuta aleasa RON', ALLTRIM(goDlg.cDviValuta), 'RON')
=Assert3('2-DVI curs fixat la 1 (RON)', goDlg.nDviCurs, 1)
*-- discount financiar (doar baza, fara bifa) - Valid() reface TVA DVI pe baza NETA
goDlg.txtDiscBaza.Value = 100
goDlg.txtDiscBaza.Valid()
goDlg.WindowType = 0
goDlg.Visible = .T.
goDlg.Show()
DOEVENTS FORCE
DO HarnessStep WITH 1, 'dialog completat: factura EUR nract=15000, DVI nract=101, discount baza 100'
*-- valideaza() REAL de pe dialog (buton Termin apeleaza mereu asta primul)
LOCAL llOkValid
llOkValid = goDlg.valideaza()
=Assert3('3-dialog valideaza() reuseste', IIF(llOkValid,1,0), 1)
*-- toDlg construit INLINE in programul PRINCIPAL (capcana l, vezi antetul mock_caut_valuta.prg)
PUBLIC goT
goT = CREATEOBJECT('Empty')
=ADDPROPERTY(goT,'serie_act',ALLTRIM(NVL(goDlg.cSerieAct,'')))
=ADDPROPERTY(goT,'nract',goDlg.nNract)
=ADDPROPERTY(goT,'dataact',goDlg.dDataAct)
=ADDPROPERTY(goT,'fdoc',goDlg.cFelDoc)
=ADDPROPERTY(goT,'id_fdoc',goDlg.nIdFdoc)
=ADDPROPERTY(goT,'id_partc',goDlg.nIdPartener)
=ADDPROPERTY(goT,'partc',goDlg.cPartener)
=ADDPROPERTY(goT,'explicatia',ALLTRIM(NVL(goDlg.cExplicatia,'')))
=ADDPROPERTY(goT,'suma',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,IIF(goDlg.nSumaLei<>0,goDlg.nSumaLei,ROUND(goDlg.nSuma*goDlg.nCurs,gnPC)),goDlg.nSuma))
=ADDPROPERTY(goT,'suma_val',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,goDlg.nSuma,0))
=ADDPROPERTY(goT,'in_valuta',goDlg.chkInValutaCont.Value)
=ADDPROPERTY(goT,'participa_valuta',(goDlg.chkParticipaValuta.Value=1))
=ADDPROPERTY(goT,'id_valuta',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nIdValuta,0))
=ADDPROPERTY(goT,'curs',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nCurs,0))
=ADDPROPERTY(goT,'nume_val',IIF(goDlg.chkInValutaCont.Value=1,ALLTRIM(NVL(goDlg.cValuta,'')),''))
=ADDPROPERTY(goT,'cTipTva',IIF(goDlg.optTipTva.Value=1,'F',IIF(goDlg.optTipTva.Value=2,'D','N')))
=ADDPROPERTY(goT,'id_jtva_coloana',goDlg.nIdExplicatieTva)
IF goDlg.optTipTva.Value = 2
=ADDPROPERTY(goT,'dvi_serie',CHRTRAN(ALLTRIM(NVL(goDlg.cSerieDvi,'')),CHR(34),''))
=ADDPROPERTY(goT,'dvi_nract',goDlg.nNractDvi)
=ADDPROPERTY(goT,'dvi_dataact',goDlg.dDviData)
=ADDPROPERTY(goT,'dvi_id_fdoc',goDlg.nIdFdocDVI)
=ADDPROPERTY(goT,'dvi_fdoc',goDlg.cFelDocDvi)
=ADDPROPERTY(goT,'dvi_id_partc',goDlg.nDviIdPartener)
=ADDPROPERTY(goT,'dvi_partc',goDlg.cDviPartener)
=ADDPROPERTY(goT,'dvi_scc','401')
=ADDPROPERTY(goT,'dvi_tva_lei',goDlg.nDviTvaLei)
=ADDPROPERTY(goT,'dvi_tva_val',goDlg.nDviTvaVal)
=ADDPROPERTY(goT,'dvi_in_valuta',!(EMPTY(goDlg.cDviValuta) OR UPPER(ALLTRIM(goDlg.cDviValuta))=='RON'))
=ADDPROPERTY(goT,'dvi_id_valuta',goDlg.nDviIdValuta)
=ADDPROPERTY(goT,'dvi_curs',goDlg.nDviCurs)
=ADDPROPERTY(goT,'dvi_nume_val',ALLTRIM(NVL(goDlg.cDviValuta,'')))
=ADDPROPERTY(goT,'dvi_valuta_proprie',IIF(!(EMPTY(goDlg.cDviValuta) OR UPPER(ALLTRIM(goDlg.cDviValuta))=='RON') OR !(EMPTY(goDlg.cValuta) OR UPPER(ALLTRIM(goDlg.cValuta))=='RON'),IIF(goDlg.nDviIdValuta<>goDlg.nIdValuta OR goDlg.nDviCurs<>goDlg.nCurs,1,0),0))
ENDIF
=ADDPROPERTY(goT,'disc_baza_lei',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,ROUND(goDlg.nDiscBaza*goDlg.nCurs,gnPC),goDlg.nDiscBaza))
=ADDPROPERTY(goT,'disc_baza_val',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,goDlg.nDiscBaza,0))
*-- "Termin" REAL: oParinte.do_adauga_factura() cu toDlg-ul construit mai sus
LOCAL llOkAdauga
llOkAdauga = goObj.do_adauga_factura(goT)
=Assert3('4-do_adauga_factura(goT) reuseste (Termin)', IIF(llOkAdauga,1,0), 1)
goDlg.Hide()
DOEVENTS FORCE
DO HarnessStep WITH 2, 'dupa Termin pe dialog: introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri'
DO DumpIntrodc WITH 'DUMP dupa Termin (inainte de articol/sincronizare)'
*========================= BASELINE: B/T-DVI/G create corect =========================
SELECT introdc
LOCATE FOR nract = 15000 AND tip_rand == 'B'
=Assert3('5-randul B (baza factura) gasit', IIF(FOUND(),1,0), 1)
IF FOUND()
=Assert3('6-BASELINE B.nract=15000', nract, 15000)
=AssertStr('7-B.scd=371', ALLTRIM(scd), '371')
ELSE
pnAsserts = pnAsserts + 2
DO EeLog WITH ' FAIL 6-7: randul B negasit'
ENDIF
SELECT introdc
LOCATE FOR Nvl(rand_dvi,0) = 1
=Assert3('8-randul T-DVI (rand_dvi=1) gasit', IIF(FOUND(),1,0), 1)
IF FOUND()
=Assert3('9-BASELINE T-DVI.nract=101', nract, 101)
=AssertStr('10-T-DVI.scd=4426', ALLTRIM(scd), '4426')
ELSE
pnAsserts = pnAsserts + 2
DO EeLog WITH ' FAIL 9-10: randul T-DVI negasit'
ENDIF
SELECT introdc
LOCATE FOR nract = 15000 AND tip_rand == 'G'
=Assert3('11-randul G (discount) gasit', IIF(FOUND(),1,0), 1)
IF FOUND()
=Assert3('12-BASELINE G.nract=15000', nract, 15000)
ELSE
pnAsserts = pnAsserts + 1
DO EeLog WITH ' FAIL 12: randul G negasit'
ENDIF
*========================= ARTICOL prin do_adauga_articol() REAL =========================
gcMockArtCodmat = 'ART-BULD-212'
LOCAL llEroareArt
llEroareArt = .F.
TRY
goObj.do_adauga_articol()
CATCH TO loExcArt
llEroareArt = .T.
DO EeLog WITH 'EROARE do_adauga_articol ' + TRANSFORM(loExcArt.ErrorNo) + ' [' + loExcArt.Message + ']'
ENDTRY
DOEVENTS FORCE
=Assert3('13-do_adauga_articol() fara eroare', IIF(llEroareArt,0,1), 1)
SELECT rul_temp
LOCATE FOR ALLTRIM(codmat) == 'ART-BULD-212'
=Assert3('14-articolul adaugat in rul_temp', IIF(FOUND(),1,0), 1)
IF FOUND()
REPLACE cant WITH 1, pret_val WITH 800, pretd WITH 800, pret WITH ROUND(800*5.23,4), ;
pret_lei WITH ROUND(800*5.23,4), cota_tva WITH 21
ELSE
pnAsserts = pnAsserts + 1
DO EeLog WITH ' FAIL 14: articolul nu a fost adaugat'
ENDIF
goObj.gridart.Refresh()
DOEVENTS FORCE
DO HarnessStep WITH 3, 'articol adaugat (BULDOEXCAVATOR, 800 EUR)'
*========================= sincronizeaza() REAL (creeaza randurile S) =========================
LOCAL llEroareSync
llEroareSync = .F.
TRY
goObj.sincronizeaza()
CATCH TO loExcSync
llEroareSync = .T.
DO EeLog WITH 'EROARE sincronizeaza() ' + TRANSFORM(loExcSync.ErrorNo) + ' [' + loExcSync.Message + '] in ' + loExcSync.Procedure + ':' + TRANSFORM(loExcSync.LineNo)
ENDTRY
DOEVENTS FORCE
=Assert3('15-sincronizeaza() fara eroare', IIF(llEroareSync,0,1), 1)
DO DumpIntrodc WITH 'DUMP dupa sincronizeaza() (inainte de TRIGGER)'
LOCAL lnCntSDoc1
lnCntSDoc1 = 0
SELECT introdc
SCAN FOR nract = 15000 AND tip_rand == 'S'
lnCntSDoc1 = lnCntSDoc1 + 1
ENDSCAN
=Assert3('16-cel putin un rand S creat de sincronizeaza()', IIF(lnCntSDoc1 >= 1, 1, 0), 1)
DO HarnessStep WITH 4, 'sincronizat: ' + TRANSFORM(lnCntSDoc1) + ' rand(uri) S, nract=15000 pe B/G/S (baseline)'
*========================= TRIGGER: pointerul pe randul T-DVI, Valid() pe coloana Nr =========================
SELECT introdc
LOCATE FOR Nvl(rand_dvi,0) = 1
=Assert3('17-pozitionare pe randul T-DVI reusita (inainte de trigger)', IIF(FOUND(),1,0), 1)
LOCAL llTriggerOk, lcVarianta
llTriggerOk = .F.
lcVarianta = ''
IF FOUND()
TRY
goObj.Grid1.cNract.Text1.Valid()
llTriggerOk = .T.
lcVarianta = 'Grid1.cNract.Text1.Valid() (apel direct pe coloana din grid)'
CATCH TO loExcTrig1
DO EeLog WITH 'INFO Grid1.cNract.Text1.Valid() a esuat (' + TRANSFORM(loExcTrig1.ErrorNo) + ' ' + loExcTrig1.Message + '), incerc fallback copiaza_valoare()'
SELECT introdc
LOCATE FOR Nvl(rand_dvi,0) = 1
TRY
goObj.copiaza_valoare('nract')
llTriggerOk = .T.
lcVarianta = 'copiaza_valoare(''nract'') (fallback, apel direct pe metoda)'
CATCH TO loExcTrig2
DO EeLog WITH 'EROARE si fallback copiaza_valoare(''nract'') a esuat: ' + TRANSFORM(loExcTrig2.ErrorNo) + ' ' + loExcTrig2.Message
ENDTRY
ENDTRY
ENDIF
DOEVENTS FORCE
=Assert3('18-TRIGGER executat fara eroare', IIF(llTriggerOk,1,0), 1)
DO EeLog WITH 'TRIGGER folosit: ' + lcVarianta
DO DumpIntrodc WITH 'DUMP dupa TRIGGER (Valid()/copiaza_valoare pe randul T-DVI)'
*========================= ASSERT-URI DUPA TRIGGER: nract pe G/S trebuie sa RAMANA 15000 =========================
*-- randul B NU mai exista in acest punct (sincronizeaza() de mai sus l-a transformat in S -
*-- comportament normal, nu are rost sa-l cautam aici; verificarea lui se face doar S mai jos).
LOCAL llBugG, llBugS, lnCntSVerif
llBugG = .F.
llBugS = .F.
SELECT introdc
LOCATE FOR tip_rand == 'G' AND Nvl(rand_dvi,0) <> 1
IF FOUND()
pnAsserts = pnAsserts + 1
IF nract == 15000
pnPass = pnPass + 1
DO EeLog WITH ' PASS 20-G.nract ramane 15000 dupa trigger (=' + TRANSFORM(nract) + ')'
ELSE
llBugG = .T.
DO EeLog WITH ' FAIL 20-G.nract dupa trigger = ' + TRANSFORM(nract) + ' (asteptat 15000) -> BUG'
ENDIF
ELSE
pnAsserts = pnAsserts + 1
DO EeLog WITH ' FAIL 20: randul G negasit dupa trigger'
ENDIF
lnCntSVerif = 0
SELECT introdc
SCAN FOR tip_rand == 'S' AND Nvl(rand_dvi,0) <> 1
lnCntSVerif = lnCntSVerif + 1
pnAsserts = pnAsserts + 1
IF nract == 15000
pnPass = pnPass + 1
DO EeLog WITH ' PASS 21.' + TRANSFORM(lnCntSVerif) + '-S.nract ramane 15000 dupa trigger (=' + TRANSFORM(nract) + ')'
ELSE
llBugS = .T.
DO EeLog WITH ' FAIL 21.' + TRANSFORM(lnCntSVerif) + '-S.nract dupa trigger = ' + TRANSFORM(nract) + ' (asteptat 15000) -> BUG'
ENDIF
ENDSCAN
*-- randul T-DVI insusi trebuie sa ramana 101 (sursa neschimbata de propriul Valid)
SELECT introdc
LOCATE FOR Nvl(rand_dvi,0) = 1
=Assert3('22-T-DVI.nract ramane 101 (randul sursa neschimbat)', IIF(FOUND(), nract, -1), 101)
*========================= dupa un NOU sincronizeaza(): randurile S refac starea =========================
LOCAL llEroareSync2
llEroareSync2 = .F.
TRY
goObj.sincronizeaza()
CATCH TO loExcSync2
llEroareSync2 = .T.
DO EeLog WITH 'EROARE al doilea sincronizeaza() ' + TRANSFORM(loExcSync2.ErrorNo) + ' [' + loExcSync2.Message + ']'
ENDTRY
DOEVENTS FORCE
=Assert3('23-al doilea sincronizeaza() fara eroare', IIF(llEroareSync2,0,1), 1)
DO DumpIntrodc WITH 'DUMP dupa AL DOILEA sincronizeaza() (post-trigger)'
LOCAL llBugSDupaSync2
llBugSDupaSync2 = .F.
lnCntSVerif = 0
SELECT introdc
SCAN FOR tip_rand == 'S' AND Nvl(rand_dvi,0) <> 1
lnCntSVerif = lnCntSVerif + 1
pnAsserts = pnAsserts + 1
IF nract == 15000
pnPass = pnPass + 1
DO EeLog WITH ' PASS 24.' + TRANSFORM(lnCntSVerif) + '-dupa al 2-lea sync: S.nract=15000 (=' + TRANSFORM(nract) + ')'
ELSE
llBugSDupaSync2 = .T.
DO EeLog WITH ' FAIL 24.' + TRANSFORM(lnCntSVerif) + '-dupa al 2-lea sync: S.nract=' + TRANSFORM(nract) + ' (asteptat 15000) -> BUG persista dupa sincronizare'
ENDIF
ENDSCAN
DO HarnessStep WITH 5, 'final: ' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' PASS'
DO EeLog WITH '========================================================='
IF llBugG OR llBugS OR llBugSDupaSync2
DO EeLog WITH 'BUG CONFIRMAT: nract-ul randului T-DVI (101) s-a propagat peste nract-ul' + ;
' randurilor B/G/S ale facturii principale (asteptat 15000) dupa ce Valid()/' + ;
'copiaza_valoare() a rulat cu pointerul pe randul T-DVI.'
ELSE
DO EeLog WITH 'BUG NECONFIRMAT: nract-ul randurilor B/G/S a ramas 15000 dupa trigger si dupa re-sincronizare.'
ENDIF
DO EeLog WITH '========================================================='
DO EeLog WITH 'REZULTAT: ' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' assert-uri PASS'
IF pnPass = pnAsserts
DO EeLog WITH 'REZULTAT: PASS (' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ')'
ELSE
DO EeLog WITH 'REZULTAT: FAIL (' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' assert-uri PASS)'
ENDIF
DO HarnessDone WITH 'done'
CATCH TO loExc
DO EeLog WITH 'CATCH ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']'
DO HarnessDone WITH 'done-error'
ENDTRY
QUIT
*==================================================================================
PROCEDURE DumpIntrodc
LPARAMETERS tcTitlu
LOCAL lcSelAnt, lnRecAnt
lcSelAnt = SELECT()
lnRecAnt = IIF(USED('introdc'), IIF(EOF('introdc') OR BOF('introdc'), 0, RECNO('introdc')), 0)
DO EeLog WITH tcTitlu
IF !USED('introdc')
DO EeLog WITH ' (introdc neinstantiat)'
RETURN
ENDIF
SELECT introdc
SCAN
DO EeLog WITH ' tip_rand=' + ALLTRIM(NVL(tip_rand,'?')) + ' nract=' + TRANSFORM(NVL(nract,0)) + ;
' doc_key=[' + ALLTRIM(NVL(doc_key,'')) + '] rand_dvi=' + TRANSFORM(NVL(rand_dvi,0)) + ;
' scd=' + ALLTRIM(NVL(scd,'')) + ' scc=' + ALLTRIM(NVL(scc,'')) + ' suma=' + TRANSFORM(NVL(suma,0))
ENDSCAN
IF lnRecAnt > 0
TRY
GO lnRecAnt
CATCH
GO TOP
ENDTRY
ENDIF
SELECT (lcSelAnt)
ENDPROC
PROCEDURE CreeazaIntrodc
*-- coloane rand_dvi N(1), valuta_proprie N(1) (rand_dvi = randul T-DVI)
LPARAMETERS tcAlias
IF USED(tcAlias)
USE IN (tcAlias)
ENDIF
CREATE CURSOR (tcAlias) ( ;
id_note N(14), explicatia C(100), scd C(10), ascd C(20), scc C(10), ascc C(20), ;
cu_tva N(1), id_set N(14), ordine N(8), in_valuta N(1), id_jtva_coloana N(14) NULL, ;
ptva N(6,2), explicatie_tva C(50), tipjurnal C(2), taxcode N(6), paymentcode C(9), ;
suma N(18,4), suma_val N(18,4), id_partd N(14), id_partc N(14), partd C(100), partc C(100), ;
id_fact N(14), id_factd N(14), id_factc N(14), pereched N(14), perechec N(14), ;
nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), expl_manual N(1), ;
scd_orig C(20), ascd_orig C(20), rand_dvi N(1), valuta_proprie N(1))
ENDPROC
PROCEDURE CreeazaRulTemp
IF USED('rul_temp')
USE IN ('rul_temp')
ENDIF
CREATE CURSOR rul_temp ( ;
id_rul N(20,0), an N(4,0), luna N(2,0), cod N(20,0);
, serie C(100), nnir N(20,0), id_articol N(10,0), denumire C(100);
, codmat C(50), codmatf C(50), codbare C(50), um C(20);
, id_gestiune N(5,0), nume_gestiune C(50), cgest C(20), nr_pag N(2,0);
, gestionar C(50), comisie_receptie1 C(50), comisie_receptie2 C(50), comisie_receptie3 C(50);
, cant N(14,3), cante N(14,3), cont C(10), acont C(20);
, pret N(18,4), tva N(18,4), valoare N(18,4), valtva N(18,4);
, proc_tva N(5,2), pretv N(18,4), pretvtva N(18,4), tvav N(18,4);
, valoarev N(18,4), valtvav N(18,4), proc_tvav N(5,2), adaos N(18,4);
, adaos_tva N(18,4), valoare_adaos N(18,4), valtva_adaos N(18,4), procent N(10,3);
, discunitar N(18,4), discount_tva N(18,4), valoare_discount N(18,4), valtva_discount N(18,4);
, proc_disc N(7,3), pretd N(14,4), curs N(18,4), id_valuta N(10,0);
, nume_val C(20), id_lucrare N(20,0), nrord C(100), id_responsabil N(10,0);
, nresp C(100), resp_marca N(18,4), dataact T, id_util N(5,0);
, util C(30), dataora T, id_sectie N(5,0), sectie C(50);
, csectie C(10), alcooltutun N(1,0), datain T, dataout T;
, id_fact N(20,0), id_gestiunec N(10,0), nume_gestiunec C(50), cgestc C(20);
, id_responsabilc N(5,0), id_reteta N(10,0), reteta C(50), nrespc C(100);
, respc_marca N(18,4), id_set N(20,0), id_tip_rulaj N(10,0), tip_rulaj C(50);
, id_obiect_depozit N(10,0), id_rul_aux N(10,0), nract N(20,0), serie_act C(10);
, dataoras T, id_utils N(10,0), lot C(30), adata_expirare T;
, id_sucursala N(5,0), sucursala C(250), id_part_rez N(10,0), part_rez C(100);
, id_lucrare_rez N(10,0), nrord_rez C(100), subgrupa C(100), grupa C(100);
, id_subgrupa N(5,0), id_grupa N(5,0), in_stoc N(1,0), in_crm N(1,0);
, id_furnizor N(10,0), furnizor C(100), id_jtva_coloana N(4,0), explicatie_tva C(100);
, taxcode N(6,0), taxname C(254), saft_procent N(18,4), codnc8 C(20);
, id_tara_origine N(4,0), cod_tara_origine C(5), tara_origine C(50), greutate N(12,4);
, fdoc C(30), id_fdoc N(18,4);
, pret_lei N(18,4), pret_val N(14,4), cota_tva N(6,2))
ENDPROC
FUNCTION RECCOUNT_ACTIVE
LPARAMETERS tcAlias
LOCAL lnSel, lnCnt
lnSel = SELECT()
SELECT (tcAlias)
COUNT TO lnCnt FOR !DELETED()
SELECT (lnSel)
RETURN lnCnt
ENDFUNC
PROCEDURE Assert3
LPARAMETERS tcLabel, tuActual, tuExpected
pnAsserts = pnAsserts + 1
IF ABS(NVL(tuActual,0) - tuExpected) < 0.02
pnPass = pnPass + 1
DO EeLog WITH ' PASS ' + tcLabel + ' (=' + TRANSFORM(tuActual) + ')'
ELSE
DO EeLog WITH ' FAIL ' + tcLabel + ' (actual=' + TRANSFORM(tuActual) + ' asteptat=' + TRANSFORM(tuExpected) + ')'
ENDIF
ENDPROC
PROCEDURE AssertStr
LPARAMETERS tcLabel, tcActual, tcExpected
pnAsserts = pnAsserts + 1
IF tcActual == tcExpected
pnPass = pnPass + 1
DO EeLog WITH ' PASS ' + tcLabel + ' (=[' + tcActual + '])'
ELSE
DO EeLog WITH ' FAIL ' + tcLabel + ' (actual=[' + tcActual + '] asteptat=[' + tcExpected + '])'
ENDIF
ENDPROC
PROCEDURE EeErr
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
DO EeLog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
ENDPROC
PROCEDURE EeLog
LPARAMETERS tcMsg
SET SAFETY OFF
LOCAL lcL
lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '')
STRTOFILE(lcL + tcMsg + CHR(13)+CHR(10), gcUILog)
ENDPROC
DEFINE CLASS dummyapp AS Custom
PROCEDURE ReadIni
LPARAMETERS tcSection, tcKey
RETURN ''
ENDPROC
PROCEDURE WriteIni
LPARAMETERS tcSection, tcKey, tcValue
RETURN .T.
ENDPROC
ENDDEFINE
DEFINE CLASS dummyexecutor AS Custom
cEroare = ''
PROCEDURE oExecute
LPARAMETERS tcSql, tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF 'VJTVA_COLOANE' $ UPPER(m.tcSql)
DO CreeazaJtvaColoaneView WITH m.tcCursor
RETURN 1
ENDIF
IF UPPER(ALLTRIM(m.tcCursor)) == 'RUL_TEMP'
CREATE CURSOR (m.tcCursor) (denumire C(100), codmat C(30), cant N(14,3), ;
pret_val N(18,4), pretd N(18,4), pret N(18,4), pret_lei N(18,4), cont C(10), ;
acont C(20), serie C(30), lot C(30), adata_expirare C(10), proc_disc N(6,2), cota_tva N(6,2))
RETURN 1
ENDIF
IF 'CONFIG_ANALITICE' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (camp_leg_prefix C(30), camp_leg_sufix C(30))
INSERT INTO (m.tcCursor) VALUES ('', '')
RETURN 1
ENDIF
IF 'FCONTURI_ANALITICE' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (acont C(20))
INSERT INTO (m.tcCursor) VALUES (IIF(TYPE('gcMockAcontCrt') = 'C', gcMockAcontCrt, ''))
RETURN 1
ENDIF
IF 'VPLCONT_ANALITIC' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (cont C(10), acont C(20))
RETURN 1
ENDIF
IF 'VCONFIG_CONT_IREG' $ UPPER(m.tcSql)
CREATE CURSOR (m.tcCursor) (contpart C(10), fel_cont N(1), cu_inregistrari N(1), ;
explic_cont C(100), exceptie C(10), pozitie N(1), invers N(1), gasit N(1))
INSERT INTO (m.tcCursor) VALUES ('401', 0, 0, 'Furnizori', '', 0, 0, 0)
RETURN 1
ENDIF
CREATE CURSOR (m.tcCursor) (id_temp N(1))
RETURN 1
ENDPROC
PROCEDURE oExecuta
LPARAMETERS tcSql, tcCursor
IF !EMPTY(m.tcCursor)
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
IF UPPER(m.tcCursor) == 'CJTVACOL4427'
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14))
ELSE
CREATE CURSOR (m.tcCursor) (id_temp N(1))
ENDIF
ENDIF
RETURN .T.
ENDPROC
PROCEDURE oSelect2Value
LPARAMETERS tcSql, toValue
toValue = ''
RETURN 1
ENDPROC
PROCEDURE oReset
ENDPROC
ENDDEFINE
PROCEDURE CreeazaJtvaColoaneView
LPARAMETERS tcCursor
IF USED(m.tcCursor)
USE IN (m.tcCursor)
ENDIF
CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14), denumire C(100), jc N(1), jv N(1), ;
coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14) NULL, afisat N(1), ;
id_jtva_ex N(14) NULL, id_jtva_neex N(14) NULL, ordine N(8), ;
taxcode N(6) NULL, taxcode_neexigibil N(6) NULL, taxcode_n50 N(6) NULL, ;
taxcode_n50_tvai N(6) NULL, taxcode_n100 N(6) NULL, taxcode_regularizare N(6) NULL, taxcode_tvai N(6) NULL)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, afisat, ordine, cota_tva) VALUES (0, '', 0, 0, 1, 0, 0)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (208, 'ACH. INT. 21%', 1, 0, 'RO21B', 21, 209, 1, 1, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (209, 'TVA ACH. INT. 21%', 1, 0, 'RO21T', 21, 1, 2, 301104)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
VALUES (220, 'ACH. IMP. 21%', 1, 0, 'FO21B', 21, 221, 1, 3, 301204)
INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
VALUES (221, 'TVA ACH. IMP. 21%', 1, 0, 'FO21T', 21, 1, 4, 301204)
ENDPROC

Some files were not shown because too many files have changed in this diff Show More