Files
roagest/docs/flux-achizitie-import.md
Marius Mutu 80a418247e changelog 2.11.12: achizitie import - discount financiar, TVA DVI cu valuta proprie, cote multiple
Reguli de lucru in CLAUDE.md: stil de raspuns scurt, changelog compact,
curatenie (diff/handoff/temporare) inainte de commit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U9uDgDfUQXbh2Neib36CN8
2026-08-01 09:32:44 +03:00

261 lines
21 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Flux: Achiziție din import (NIR import)
Lanțul complet (descoperit la sesizarea „achiziție import", 07.2026):
- **Intrare**: `Clase\gestiuni.vcx` (`gestiuni.vc2:2045-2171`) → meniu „Achizitie din import /
Achizitie interna" → `DO achizitie_import WITH <id_set>, llIntern IN ointroduceri.prg`.
Id-uri de set: **208/209 = import**, **220/221 = intern** (perechi pe tip de operație).
- **`achizitie_import`** (`COMUN\programe\ointroduceri.prg:1435-1617`):
- antetul facturii = `poAct` (SCATTER din `actactan`, structura din `pmenu.prg:281-307`,
tabelul `ACT`) — o singură pereche `id_valuta` + `curs` pe act;
- liniile de notă = cursorul **`introdc`** (din view `vnote_contabile` filtrat pe `id_set`),
fiecare rând moștenește `id_valuta`/`curs`/`dataact`/`tva_incasare` din `poAct`; rândurile merg
în perechi **impar = linia de bază, par = linia de TVA**;
- cursorul **`jtva_coloane2`** (explicații TVA, cu rând 0 gol) — sursa dropdown-ului de explicație;
- deschide forma **`import_nota`** (`COMUN\clase\ointroduceri.vcx`). Atenție:
**`import_nota_original` din același .vcx NU e instanțiat nicăieri — e copie de rezervă.**
- **Modelul de documente**: un NIR de import = factura principală de achiziție (marfă și/sau
imobilizări; valuta/cursul ei = `poAct.id_valuta`/`poAct.Curs`, referința de conversie) + opțional
factura de transport (poate fi altă valută/curs) + opțional factura de taxe vamale + DVI
(declarația vamală, cu TVA-urile fiecărei facturi, plătite în lei). Toate devin linii în `introdc`,
apartenența la document fiind per rând: `nract`/`serie_act`/`id_fact` (rândurile au și `id_valuta`/
`curs` proprii, dar istoric codul folosește doar `poAct.Curs`).
- **`import_nota`** (nota contabilă a facturii): grila pe `introdc`; transport/alte taxe se introduc
ca linii de notă suplimentare cu flagurile `in_valuta` (suma e în valută) și `participa_valuta`
(linia intră în valoarea de intrare a mărfii). `do_executa` calculează procentele de repartizare
(stocate în `explicatia4`/`explicatia5`); `inainte_de_do_termin` sumează bazele
(lei/valută, liniile în lei se împart la `poAct.Curs`) și lansează **`import_nir`** cu
`procent_lei/procent_val/ncurs`.
- **`import_nir`** (grila de articole): `do_adauga``viz_catalog_articole()`
(`oproceduri_articole.prg:62`, câmpul `in_stoc` = „Gestionabil") filtrat pe conturile `scd` din
notă; prețul de intrare per articol = preț valută × `procent_val`, apoi × `ncurs` × `procent_lei`
(transportul „umflă" procentele peste 100). Diferența reziduală devine linia „DIFERENTE".
`do_modiparam` = preluare articole din XLS (creează articole noi prin `pack_preturi.adauga_articol`,
cont implicit 371).
- **Salvare**: `oscrie_in_fisiere` → tabelele temporare `ACT_TEMP`/`RUL_TEMP` → pachetul Oracle
**`PACK_CONTAFIN`** (`SCRIE_IN_ACT`, `SCRIE_IN_RUL`, `SCRIE_IN_STOC`, …). `SCRIE_IN_RUL` inserează
în `RUL` **exact** conținutul `RUL_TEMP` (nu derivă din ACT) — orice filtrare de rulaje se face în
clientul VFP. Sursa pachetului: `COMUN\docs\PACK_CONTAFIN.pck` (vezi `COMUN\docs\oracle_export.md`).
- **Articole negestionabile** (`nom_articole.in_stoc = 0`): modelul canonic e în clasa **`nir`**
(NIR-ul obișnuit, același `ointroduceri.vcx`), mecanism din 2009 — articolul intră normal în grilă
și participă la calcule, iar în `inainte_de_do_termin`, chiar înainte de scriere, se face
`Delete From rul_temp Where in_stoc = 0` (valoarea rămâne doar pe nota contabilă, nu ajunge în
`RUL`/`STOC`). Din v2.11.6 `import_nir` e aliniat la același model, cu un cursor temporar
(`crsNegest`) care readaugă rândurile șterse în grilă dacă `oscrie_in_fisiere` eșuează.
Cursorul `rul_temp` are coloana `in_stoc` pentru că e creat din view-ul `vrul` (`where 1=2`);
la `do_adauga` coloana se umple prin `GATHER NAME loArt` din cursorul catalogului, la
`do_modiparam` (XLS) explicit din selectul pe `nom_articole`.
- **Explicație TVA**: dropdown istoric `Grid1.cExplicatieTva.Combo1` (RowSource `jtva_coloane2`);
modelul alternativ cu formular de căutare = `frm_modific2024.do_modifica_explicatie_tva`
(`omodificari.vcx`) → `caut_explicatie_tva()` (`ocautare.prg:1934`, view `vjtva_coloane`,
întoarce DOAR `id_jtva_coloana, denumire, cota_tva`). Capcane: în `introdc.ptva` se ține **cota
brută** (21), pe când în registru jurnal `proc_tva` = (cota+100)/100; comutarea 4427/401 pe linia
de TVA se face prin SEEK în cursorul `cJtvaCol4427`.
Căutarea generică: `cauta_alfa()` (`COMUN\programe\cauta_alfa.prg`) → forma `cauta_alfa_form_plus`.
## Structura reală a șablonului `vnote_contabile` (verificat 11.07.2026)
Cursorul `introdc` NU pornește cu „2 linii" — se încarcă cu **toate** perechile-șablon din
`vnote_contabile` pentru `id_set`. Numărul de linii pe baza de dev (`MARIUSM_AUTO`):
**208 = 10 linii, 209 = 10, 220 = 10, 221 = 6**. Cele 10 linii ale setului de import (208) =
**5 perechi pre-alocate (bază+TVA) = 5 sloturi de document**:
| Pereche (ordine) | SCD/SCC bază | SCD/SCC TVA | Ce e |
|---|---|---|---|
| 1 (1-2) | 3028/401 | 4426/4427 | marfă CE 21% + TVA |
| 2 (3-4) | 3028/401 | 4426/4427 | slot repetat (gol) |
| 3 (5-6) | 3028/401 | 4426/4427 | slot repetat (gol) |
| 4 (7-8) | 3028/446 | 4426/446 | vamă/DVI (pe dev) |
| 5 (9-10) | 3028/446 | 4426/446 | slot repetat (gol) |
Model CONT2000: în loc să adaugi rânduri, ai **sloturi goale pre-alocate** pe care le completezi.
Factura principală = perechea 1 (2 linii); restul sunt sloturi pentru facturi suplimentare (3 marfă)
+ DVI (2). Un „document" = o pereche cu date.
**Corecție importantă (Marius, verificat pe bază reală de producție):** conturile 446 din setul 208
de pe dev **NU sunt reprezentative**. În realitate și DVI-ul vamă folosește **4426 = 401** (nu 446).
`vnote_contabile` e **configurabil per firmă**, deci șablonul variază — nu hardcoda conturile, ci
clonează perechea-șablon reală a setului. Practic: **un singur pattern de conturi** (bază 3028/401 +
TVA 4426/4427 sau 4426/401) acoperă și marfă, și DVI (DVI diferă doar prin partener/unde e plătit
TVA, nu prin conturi).
## DECIZIE 11.07.2026 — pivot la „Direcția A" (rescriere flux introducere)
Marius a decis să se **abandoneze modelul cu 10 sloturi pre-alocate**. Noul model (de implementat
într-o sesiune viitoare, e scop **M2**, mai mare decât runda 1 M1/M3/M6):
1. **`achizitie_import`**: `introdc` pornește **gol** (0 rânduri de document); se păstrează perechea-
șablon (bază+TVA, cu conturile reale din `vnote_contabile` ale setului) ca **sursă de clonare**.
Nu se mai încarcă cele 10 sloturi.
2. **Buton „Adaugă factură" + dialog (M2)**: clonează perechea-șablon, o completează cu datele
facturii, o adaugă în `introdc`. Se folosește **și pentru factura principală**, și pentru DVI
(radio-ul furnizor/DVI/fără schimbă doar partenerul/unde e plătit TVA, nu conturile).
3. **M1 (culori)**: rămâne cum e — fiecare factură adăugată = o pereche = un document = o culoare
(F1, F2, …), incremental, cheie `serie+nr+id_fdoc`. Codul M1 deja aplicat merge neschimbat pe
acest model.
Avertismente: atinge `COMUN` (blast radius: 22 `.pjx` referă `ointroduceri`) și **schimbă
comportamentul pentru toți userii de import** (nu mai văd sloturi pre-completate) — testare atentă,
dare în funcțiune deliberată.
## Model curent `import_nota` (după rundele 812, 07.2026, necomis)
- **`doc_key` e unic per document**: prefix `nr_doc` (contor intern) + câmpurile de business
(`calc_doc_key`). Rândul T al unei facturi cu TVA pe DVI poartă câmpurile vamei
(partener/nract/4426) dar **păstrează doc_key-ul facturii-mamă** — identitatea nu se mai
amestecă între documentele care partajează același nr. DVI (cauza istorică a: explicație TVA
scrisă pe T-ul altui document, suma T=0, ștergere în grup, propagare `copiaza_valoare` între
documente străine).
- **Spargerea principalei** (`sparge_document`/`creeaza_rand_s`): grupare `rul_temp` pe
`cont+acont`; analiticul articolului merge direct în `ascd` al rândului S (fallback
`assign_analitic` doar când nu e furnizat).
- **Procentele per rând** (`explicatia4`/`explicatia5` = coloanele "Procent lei/valuta"): scrise
de `sincronizeaza()` după spargere (nu de `do_executa`, care nu mai scrie procente), numitor =
baza documentului principal (`This.nbazaprincipala_lei/_val`, calculate în `recalculeaza`).
Principala = 100.00; celelalte = pondere lei și valută (convertit la `oact.Curs` dacă e în lei).
- **Ștergere/copiere**: `do_sterge` = meniu Da(document, pe doc_key)/Nu(doar linia)/Cancel;
`do_copiaza_nota` (buton „Copiază") = același meniu; copiază doar B+T cu `nr_doc`/`doc_key`
noi (S/D se regenerează la sincronizare). Capcană rezolvată acolo: `Calculate` mută pointerul
la EOF → poziția sursă se salvează/restaurează înainte de `Scatter`.
- **Rândul TOTAL** de sub grila notelor: `TxtFtvaLei`/`TxtFtvaVal` (fără TVA) lângă
`Text2`/`Text3` (cu TVA), setate în `actualizeaza_banda`.
- **Test e2e de referință**: `COMUN\utile\Teste\test_scenariu_dvi_complet.prg` (scenariul complet
cu 3 documente pe același DVI + articole 212/1 și 371/4 + ștergere/copiere).
- **Valori manuale protejate (r16)**: `mod_manual=1` se setează și pe rândul T (Valid-urile
`cSuma`/`cSumaVal`); `do_executa` nu rescrie T manual, `sparge_document` nu-l șterge și nu
creează duplicat pe aceeași cotă (`ptva`). Nimic nu resetează `mod_manual` pe rând existent.
- **`nOldVal` unic (r15)**: o singură proprietate pentru valoarea la intrarea în celulă
(GotFocus) — Valid/LostFocus ies devreme la valoare nemodificată (`cSuma`, `cSumaVal`,
`cCotaTva`, `cPretFactura`). `do_calculeaza_diferente` restaurează poziția `rul_temp` de la
intrarea în procedură (`tnRecNo` nu mai poziționează); `do_reface` repoziționează explicit.
- **Totaluri articole (r17)**: `_grdfooter1` (clasa `_grdfooter` din `_grd_base.vcx`) atașat la
`GridArt` la finalul `Init`; sume pe `cValoareValutaFactura`/`cValoareValutaCalculat`/
`cValoareLeiCalculat` din `rul_temp`, recalculate în `actualizeaza_banda` +
`do_calculeaza_diferente`. Vechile `Clb_leiftva/leitva/valftva/valtva` (dublau totalurile
notelor) au fost eliminate de pe `import_nota`. Totalurile de sub grila notelor rămân din
`introdc`; Diferențe lei = bază note Σ articole.
- **Test scenariul TVA manual + footer**: `COMUN\utile\Teste\test_manual_tva_footer.prg`.
- **TVA pe creditori și la secundare (r30)**: `sparge_document` regrupează T-urile nemanuale ale
documentelor secundare pe creditorii (scc/ascc) rândurilor S proprii, proporțional cu sumele S
(conservă totalul T, inclusiv TVA tastat la DVI); `recalc_tva_document` aplică aceeași pondere
(fără S-uri: împărțire egală 1/N); `uneste_document` reunește T-urile sparte când documentul
revine la B. Armarea resincronizării din `cScc/cAscc.Valid` se face pe garda `nOldVal` (nu pe
comparația cu câmpul — grila poate scrie câmpul înaintea Valid-ului, ex. Enter) + gardă `lInSync`
contra Valid-urilor re-declanșate de regenerare. Test: `COMUN\utile\Teste\test_tva_secundare.prg`.
## TVA DVI cu valută proprie + discount financiar (07-08.2026)
- **Două coloane noi client-side pe `introdc`** (fără migrare Oracle): `rand_dvi` (identitate —
1 pe rândul T scris de ramura DVI a `do_adauga_factura`) și `valuta_proprie` (autonomie — 1
când acel rând T are valută/curs diferite de ale documentului, setat la creare sau din grilă).
Nu s-a refolosit `mod_manual` — e supraîncărcat semantic (`sparge_document` face match și pe
el pentru alte scopuri, ar fi dat duplicate/omisiuni de rânduri T).
- **Rând „protejat"** = `Nvl(valuta_proprie,0)=1` (helper unic `rand_protejat()`, folosit
peste tot ca `Thisform.rand_protejat()`). E ocolit de `copiaza_valoare` (câmpurile valutare nu
se propagă pe el, câmpurile de identitate nu se propagă pe orice rând `rand_dvi=1`),
`do_executa`, `recalc_tva_document`, `uneste_document`, `sparge_document` (vezi mai jos)
și handlerele de grilă `cCurs`/`cInValuta`/`cValuta` (editare LOCALĂ, fără
propagare). Re-alegerea valutei documentului pe rândul protejat resetează `valuta_proprie=0`
(revert — reintră în propagări). Un DVI cu valuta facturii rămâne `valuta_proprie=0` și
urmează factura la propagări, identic cu azi.
- **Spargerea T-ului protejat** (`sparge_tva_protejat`, apelată din `sparge_document`): când
TOATE rândurile T ale documentului sunt protejate, TVA-ul facturii e integral cel de pe DVI —
nu se mai fabrică rânduri T din rândul de bază. Varianta inițială (`loRandT = loBaza`) dădea
**TVA dublă**: rândul protejat rămânea, plus un T nou cu conturile bazei (371 în loc de 4426),
în valuta facturii. Acum totalul protejat se sparge pe cotele articolelor (pondere
`bază_cotă × cotă`, rest de rotunjire pe |suma| maximă), păstrând prin `Gather` identitatea
vamală, valuta proprie și `rand_dvi`/`valuta_proprie` — deci rândurile rezultate rămân
protejate. O singură cotă = niciun rând atins (ieșire devreme). Analogul lui B → S, dar pe T.
- **Discount financiar pe factură**: un singur rând `tip_rand='G'` (401=767, suma = discountul
fără TVA), același `doc_key`/`nr_doc` cu factura, `participa_valuta=.F.`. Marfa (3028) și
prețurile articolelor rămân pe valoarea integrală — discountul schimbă doar baza de calcul a
TVA-ului: `T = (b-d)*p/100`, sold 401 = `b + (b-d)*p/100 - d`. Ordinea la creare e B → G → T.
Excluse structural din bazele TVA/diferență/spargere prin filtrele deja existente pe
`Inlist(tip_rand,'B','S')`/`'T'` — un singur loc nu filtra pe `tip_rand` (suma în valută din
footer, `do_executa`) și a primit `And tip_rand<>'G'`.
Punct unic de adevăr: `disc_document(doc_key, tlValuta)`. Se scade DIRECT în `do_executa` și
`recalc_tva_document` (același `doc_key`, exact), dar se REPARTIZEAZĂ prin factor în
`sparge_document`, unde bazele vin din `crsGrupCota` (articole), nu din `suma_doc`. Factorul e
clampat la 0: validarea din dialog compară discountul cu suma facturii, care poate fi mai mare
decât baza articolelor când rămâne rest pe rândul de diferențe → altfel ar ieși TVA negativă.
`suma_doc`/`suma_doc_val` rămân BRUTE (`sparge_document` repartizează toată baza pe rândurile
S, iar `verifica_sincronizare` compară `Suma(S)` cu `suma_doc`).
`do_adauga_factura` citește `toDlg.disc_baza_lei` sub gardă `Type(...)<>'U'` — e apelabil
programatic cu un `toDlg` minimal (import e-Factura/XLS), iar `Nvl` singur nu apără de o
proprietate inexistentă.
Limită cunoscută: rândurile create ulterior de `sparge_document`/`recalc_tva_document` se
adaugă la finalul cursorului, deci după sincronizare ordinea vizuală B/G/T nu mai e garantată
(grila nu are sortare).
- **Bifa „Valuta" pe secțiunea TVA DVI** (`chkDviInValuta`): pornește după factură (bifată când
factura e în valută) și rămâne pe alegerea manuală prin `ldviinvalutadirty`, ca `linvalutadirty`
la bază. Scoasă, ascunde valuta/cursul/TVA-ul valutar al DVI-ului și forțează `nDviCurs=1`,
`nDviTvaVal=0`. Condiția de ramură din `recalc_tva` trebuie să includă bifa, nu doar
`dvi_valuta_efectiva()` — aceasta din urmă întoarce valuta facturii și nu știe de bifă, deci
fără ea se scrie `dvi_tva_val` nenul împreună cu `dvi_in_valuta=.F.`. Cazul nou „factură în
valută, DVI doar în lei" dă `dvi_valuta_proprie=1`.
- **Concordanța cotelor pe factură multi-cotă**: rândurile S se generează pe `cont+analitic+cota_tva`
(doar la documentul principal) și primesc cota articolelor lor — `creeaza_rand_s` are parametrul
`tnCota`, care scrie `ptva` + `id_jtva_coloana`/`explicatie_tva` prin `gaseste_jtva_cota` (familia =
coloana bazei). Rândul G se sparge la fel, proporțional cu bazele pe cotă (`sparge_discount`, apelat
din `sparge_document` imediat după `calc_baze_cota_creditor`), păstrând totalul discountului;
e idempotentă (recalculează din suma rândurilor G existente). Fără astea, baza (S) și discountul (G)
rămâneau pe cota facturii în timp ce T-urile erau deja sparte pe cotele articolelor — în jurnalul de
TVA baza ieșea pe altă cotă decât TVA-ul. Articolele fără cotă proprie preiau cota documentului
înainte de grupare (altfel apare un grup tranzitoriu „cota 0").
- **`nOldVal` e NUMERIC**: coloanele caracter din grila notelor (`cScc`/`cAscc`) folosesc `cOldVal`.
O singură proprietate partajată între coloane numerice și caracter dădea „Operator/operand type
mismatch" în `cSuma.Text1.Valid` când Valid se re-declanșa fără GotFocus (refresh de grilă din
`sincronizeaza`). `cSuma`/`cSumaVal.Valid` au primit și garda `lInSync`, ca `cScc`/`cAscc`.
- **Două reprezentări ale „RON"** — capcană reală, ușor de reintrodus: rândul din picker
(`caut_valuta`/`vnom_valute`) e un rând REAL cu `id_valuta` nenul (`moneda_nationala=1`);
sentinela „fără valută" din `introdc`/`ACT` e `id_valuta=0`, `nume_val=''`. Comparațiile
trebuie făcute pe valuta EFECTIVĂ (`Empty(nume) Or Upper(nume)=='RON'`), nu pe id brut — o
factură fără valută + RON ales explicit pe DVI sunt ambele „fără valută", dar o comparație
de id-uri brute le-ar vedea ca diferite (`dvi_valuta_proprie` ar da fals 1).
## Ștergere note — model istoric pe paritate (înlocuit de rundele de mai sus)
- Butonul `But_sterge1` (clasa `but_sterge`) șterge nota curentă = **perechea bază+TVA**, de pe
oricare din cele două linii (`lnBaza = Recno() - Iif(Mod(Recno(),2)=0,1,0)`, apoi `Delete Next 2`).
Dispatch-ul butonului trece prin `inainte_de_do_sterge`, condiționat de `lactiv4` — setat `.T.`
în `Init`.
- Ștergerea e **logică**, nu fizică: `SET DELETED ON` (roagest.prg:28) ascunde perechea din grid și
din toate `Scan`/`Sum`-urile fluxului, iar Recno-urile rămase nu se schimbă → paritatea impar/par
se păstrează (perechile se șterg mereu împreună, deci și `Skip`-urile peste liniile șterse cad
corect). `Append Blank` ulterior continuă tot pe paritate corectă.
- **Capcană generală VFP: niciodată `ZAP` (sau închidere/recreare) pe cursorul-sursă al unui
grid** — Zap închide și recreează cursorul, grid-ul își pierde sursa și rămâne blank. Varianta
„copiez rândurile rămase + Zap + Append la loc" e greșită exact din acest motiv.
## Familia explicațiilor TVA pe factură multi-cotă (07.2026)
- **Perechea bază/TVA se citește din nomenclator** (`jtva_coloane2.id_tva`), iar trecerea de la o
cotă la alta în aceeași familie se face pe **semnătura coloanei** (`coloana_jc` fără cifre:
`FO21B``FOB`, `FO21T``FOT`) — `gaseste_jtva_cota`. Potrivirea pe primele 2 caractere confunda
coloana de bază cu cea de TVA.
- **Alinierea T → S** (`aliniaza_tva_la_baza`, la finalul `sparge_document`): fiecare rând T
primește perechea de TVA a rândului S de aceeași cotă, dar numai dacă explicația S-ului chiar are
cota rândului (altfel nu există pereche validă — cazul nomenclatorului incomplet). Fără ea, o
explicație aleasă din altă serie pe rândul S (ex. `CE11CTB`) muta rândurile T în seria CE, în timp
ce S-ul se re-alinia la familia documentului (`FO`) la resincronizare — bază și TVA pe rubrici
diferite în jurnalul de TVA.
- **`expl_manual`** (coloană client-side pe `introdc`, lângă `mod_manual`): 1 când utilizatorul
alege explicit explicația pe un rând T (`aplica_explicatie_tva` / combo-ul din grilă); rândurile
marcate nu se aliniază. Nu s-a refolosit `mod_manual` — acela înseamnă „nu-mi recalcula suma"
și ar fi înghețat și sumele. Peste regenerarea rândurilor T eticheta se păstrează prin snapshot
pe cotă (`crsExplT`, luat înainte de ștergere, reaplicat după); la `sparge_tva_protejat` rămâne
doar pe cota rândului original, cotele apărute din spargere se aliniază normal.
- **Golul de nomenclator la 11%**: importul de bunuri nu avea perechea de 11% (`FO11B`/`FO11T` =
236/237, adăugate 30.07.2026). Fără pereche, `sparge_document` lasă în `cmesajsync` mesajul
„Documentul <fdoc> are marfă la <cotă>%, dar nu există explicație TVA de <cotă>% în seria
'<serie>'" și finalizarea rămâne blocată; utilizatorul poate ocoli lipsa alegând manual o
explicație de 11% din altă serie.
- **`tlIntern` în `achizitie_import`**: `Createobject('IMPORT_nota', tlIntern)` primește parametrul
procedurii, dar codul din clasă trebuie să citească `Thisform.lIntern` — o referință la `tlIntern`
dintr-o metodă a formularului prinde variabila PRIVATE a apelantului doar cât timp acesta e pe
stivă (în `inainte_de_do_termin` era deja ieșit).
- **Fixture-uri de test**: cele 32 de teste din `COMUN\utile\Teste\achizitie_import` își creează
singure `introdc` prin `CREATE CURSOR` — orice coloană nouă folosită în SQL-ul din clasă trebuie
adăugată și acolo, altfel apare „SQL: Column '<X>' is not found".