#13: formular de facturare unificat - etapa curenta
Squash al branch-ului de lucru plan13-s2. Cod: clasa noua ofacturare_util (geometrie si utilitare de formular), inrolata in roafacturare.prg; meniul "Facturare (nou)" plat, cu reparatia literalului peste limita VFP de 255 de caractere care impiedica compilarea metodei. Livrare: changelog 2.11.19, marcajul de versiune DB pentru scripturile finale din SCRIPTURI_CLAR\2026\09, inventarul livrarii in docs/livrare_13.md si registrul de erori deschise. Documentatia de lucru a etapei (cercetare, rapoarte, handoff-uri, snapshot-uri de scripturi si backup-uri de rollback) a fost scoasa din arbore. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PkyjGyrV2S7932om4kfSiK
This commit is contained in:
@@ -1,231 +0,0 @@
|
||||
# Golul ntip=4 (facturare din avize) fata de proiectarea parametrului de cont contabil
|
||||
|
||||
Cercetare read-only, continua `canal_cont_venit_fara_politica.md` (sectiunea "Proiectarea
|
||||
parametrului de cont contabil", liniile 13-227). Confirma si extinde golul deja semnalat, mai
|
||||
succint, in `parametru_cont_contabilizeaza_articol.md:49-56,167-168`.
|
||||
|
||||
Sursa Oracle: `D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\08\ff_2026_08_09_01_COMUN_PACK_FACTURARE.sql`
|
||||
(17217 linii). **Toate liniile citate mai jos sunt verificate direct pe acest fisier in aceasta
|
||||
runda** — numerele din cererea initiala (7520-7537, 5096) s-au dovedit **identice**, fara offset,
|
||||
fata de fisierul curent (nu +17 cum se anticipa).
|
||||
|
||||
## Verdict, in cinci randuri
|
||||
|
||||
**Ramura `ntip=4` e EXCLUSA STRUCTURAL, dar nu prin mecanismul presupus initial** (nu prin garda
|
||||
`id_pol` din `cursor_articol`/FACT-024 a lui `contabilizeaza_articol`). Blocajul real e **cu o
|
||||
functie mai devreme**: `adauga_articol_factura`, ramura `WHEN pack_facturare.ntip = 4`
|
||||
(`:5080-5103`), cauta randul original din avizul sursa prin `A.ID_POL = V_ID_POL` **fara niciun
|
||||
handler de exceptie** — daca `V_ID_POL` e `NULL` (exact cazul "articol fara politica"), `NULL =
|
||||
NULL` nu se potriveste niciodata in SQL, deci `SELECT ... INTO` **cade mereu cu `NO_DATA_FOUND`
|
||||
neprins**, la momentul **adaugarii articolului in factura** (`adauga_articol_factura`), cu mult
|
||||
inainte ca linia sa ajunga vreodata la `contabilizeaza_articol`. Practic, un articol fara politica
|
||||
**nu poate fi adaugat deloc** pe un document `ntip=4` — eroarea apare la primul pas, nu la scriere.
|
||||
**Gol sora mai important, gasit in aceasta cercetare**: ramurile de **aviz** (`ntip` in afara
|
||||
bucket-ului "factura") — `28`/`29` (SCD hardcodat `461`) si toate celelalte (SCD hardcodat `418`)
|
||||
— **raman perfect accesibile** cu `cont_venit` populat, iar ramura noua propusa hardcodeaza
|
||||
`SCD='4111'` necondiționat de `ntip`, ceea ce ar scrie contul gresit pe orice aviz cu articol fara
|
||||
politica. Vezi sectiunea "Ramuri sora" mai jos — mai grav decat golul `ntip=4` insusi, pentru ca
|
||||
e efectiv atins, nu doar teoretic.
|
||||
|
||||
## 1. Lantul de dovezi pentru "ntip=4 e exclus" — pas cu pas
|
||||
|
||||
### 1.1. `ntip` e o variabila de pachet, setata o singura data per document
|
||||
|
||||
```
|
||||
ff_...:165 ntip NUMBER(2); -- declarata in spec, variabila publica de pachet
|
||||
ff_...:1882 pack_facturare.ntip := V_TIP; -- in initializeaza_date_factura (una din cele 4 supraincarcari, ~1650-1918)
|
||||
```
|
||||
|
||||
`V_TIP` vine din `poDate.Tip` la apelul VFP `pack_facturare.initializeaza_date_factura(...)`
|
||||
(`COMUN\clase\ofacturare.vc2:13981-13999`, argumentul `Alltrim(Str(poDate.Tip))` pozitionat ca
|
||||
`V_TIP`). O data setat, `pack_facturare.ntip` ramane valabil pentru toate apelurile ulterioare
|
||||
din aceeasi tranzactie (`adauga_articol_factura`, apoi `scrie_factura2`/`scrie_factura_avize_retur`/
|
||||
`scrie_aviz_retur` -> `contabilizeaza_articol`) — **e o singura valoare per document, nu per linie**.
|
||||
|
||||
### 1.2. Apelanti VFP care produc `poDate.Tip = 4`
|
||||
|
||||
Comentat consecvent `&& factura din aviz` / `&& aviz` in tot codul VFP:
|
||||
```
|
||||
COMUN\clase\ofacturare_comun.vc2:4347 If poDate.tip = 4 && factura din aviz
|
||||
COMUN\programe\oproceduri_facturare.prg:1253 If poDate.tip = 4 && factura din aviz
|
||||
COMUN\programe\ofacturare.prg:1512 Case poDate.tip = 4
|
||||
COMUN\clase\ofacturare.vc2:9534,9636,9674,14301,15151,18299,19022 Case poDate.tip = 4 (afisare/validare)
|
||||
```
|
||||
`ofacturare.prg:1268,1488,1504` trateaza si combinatia `poDate.tip = 4 And Not
|
||||
Empty(poDate.id_comanda_aviz)` alaturi de `ntip IN (3,21,28,42,47)` — confirma ca `ntip=4` e
|
||||
categoria distincta "facturare pe baza de avize existente" (formularul dedicat de facturare din
|
||||
avize), separata de facturarea directa sau din comenzi.
|
||||
|
||||
### 1.3. `adauga_articol_factura`, ramura `ntip=4` — blocajul real
|
||||
|
||||
```
|
||||
ff_...:4989-5015 PROCEDURE adauga_articol_factura(..., V_ID_POL IN NUMBER, ...)
|
||||
```
|
||||
`V_ID_POL` e parametru direct (nu derivat), trimis de VFP la
|
||||
`COMUN\clase\ofacturare.vc2:14072` (si identic `:18107`):
|
||||
```
|
||||
Nvl(Alltrim(Str(poArt.id_pol)),[NULL])
|
||||
```
|
||||
Daca `poArt.id_pol` e `.NULL.` in VFP (cazul "articol fara politica" — premiza intregului
|
||||
proiect #13), `Str()` propaga `.NULL.`, iar `Nvl(...)` trimite literalul SQL `NULL` — deci
|
||||
`V_ID_POL` ajunge `NULL` in Oracle exact cand articolul n-are politica.
|
||||
|
||||
In corpul `adauga_articol_factura`, CASE-ul care determina pretul/TVA/valuta ramurii (`:5052-5220`)
|
||||
are, pentru `ntip=4`:
|
||||
```
|
||||
ff_...:5080-5103
|
||||
WHEN pack_facturare.ntip = 4 THEN
|
||||
-- facturare din avize
|
||||
SELECT DISTINCT A.PRET, A.PROC_TVAV, A.ID_VALUTA, A.PRET_CU_TVA, B.IN_STOC
|
||||
INTO V_PRET, V_PROC_TVAV, V_ID_VALUTA, V_PRETURI_CU_TVA, V_IN_STOC
|
||||
FROM VANZARI_DETALII A
|
||||
LEFT JOIN NOM_ARTICOLE B ON A.ID_ARTICOL = B.ID_ARTICOL
|
||||
WHERE A.ID_ARTICOL = V_ID_ARTICOL
|
||||
AND A.ID_POL = V_ID_POL
|
||||
AND NVL(A.ID_GESTIUNE, -1000) = V_ID_GESTIUNE
|
||||
AND A.DISCOUNT_UNITAR = V_DISCOUNT_UNITAR
|
||||
AND NVL(A.CONT, 'XXXX') = V_CONT
|
||||
AND A.ID_VANZARE IN (SELECT X FROM table(cast(CHARN2COLLECTION(pack_facturare.clistaid, ',') AS num_tab)));
|
||||
```
|
||||
**Fara niciun `EXCEPTION WHEN NO_DATA_FOUND`** — spre deosebire de ramurile vecine din acelasi
|
||||
CASE: `ntip=45` are handler cu `FACT-018` (`:5140-5145`), `V_OPT_FACTURARE=3` are handler cu
|
||||
fallback + `FACT-012` (`:5167-5185`), `ELSE` are handler cu `FACT-013` (`:5188-5198`). Doar ramurile
|
||||
`ntip IN (3,21,28,42,47)` (`:5053-5078`, cauta in `COMENZI_ELEMENTE` dupa comanda, nu dupa politica)
|
||||
si `ntip=4` sunt fara plasa de siguranta.
|
||||
|
||||
Cu `V_ID_POL = NULL`, `A.ID_POL = V_ID_POL` **nu se poate potrivi niciodata** (semantica SQL: orice
|
||||
comparatie cu `NULL` da `UNKNOWN`, niciodata `TRUE`, indiferent ce e stocat in `A.ID_POL`) —
|
||||
`SELECT ... INTO` (fara `DISTINCT`+agregat care sa tolereze zero randuri) **arunca mereu
|
||||
`NO_DATA_FOUND`**. Neprinsa aici, exceptia se propaga necaptata pana la apelantul PL/SQL (blocul
|
||||
anonim generat de VFP), care se intoarce la `goExecutor` ca eroare Oracle bruta (`ORA-01403: no
|
||||
data found`), **nu ca `FACT-024`** — vezi punctul 3 mai jos pentru diferenta.
|
||||
|
||||
**Concluzie pas 1.3**: un articol fara politica (`V_ID_POL=NULL`, exact scenariul `cont_venit`)
|
||||
**nu poate fi adaugat pe un document `ntip=4`** — apelul `adauga_articol_factura` insusi esueaza,
|
||||
inainte ca `VANZARI_DETALII_TEMP` sa primeasca randul, deci **cu mult inainte** ca
|
||||
`contabilizeaza_articol` (unde e ramura noua `cont_venit`) sa vada vreodata acea linie.
|
||||
|
||||
### 1.4. Blocajul secundar (daca 1.3 n-ar exista): `contabilizeaza_articol` insusi
|
||||
|
||||
Chiar daca ipotetic linia ar ajunge in `VANZARI_DETALII_TEMP` cu `id_pol=NULL`, funcia care scrie
|
||||
efectiv factura are propria garda, **inaintea oricarui ntip**:
|
||||
```
|
||||
ff_...:7278-7302 BEGIN
|
||||
SELECT COMPUS, ID_POL_ART INTO V_COMPUS, V_ID_POL_ART
|
||||
FROM VCRM_POLITICI_PRET_ART
|
||||
WHERE ID_ARTICOL = detalii_articol.id_articol
|
||||
AND ID_POL = detalii_articol.id_pol;
|
||||
EXCEPTION
|
||||
WHEN NO_DATA_FOUND THEN
|
||||
... RAISE_APPLICATION_ERROR(-20000, '... (FACT-024)');
|
||||
END;
|
||||
```
|
||||
Aceasta ruleaza **la inceputul functiei, inainte de `OPEN cursor_articol`** (`:7393`) si deci
|
||||
inainte de CASE-ul pe `ntip` (`:7398-7423`) si de IF-ul `ntip<>4` (`:7472`). Cu `id_pol=NULL`,
|
||||
`FACT-024` cade aici, indiferent de `ntip` — **confirma independent ca ramura `ntip=4` de la
|
||||
`:7520-7537` (`scrie_fact_aviz_custodie`) e neatinsa azi de o linie fara politica**, e a doua
|
||||
plasa de siguranta, redundanta cu 1.3 dar pe alt strat.
|
||||
|
||||
**Ramura propusa `cont_venit IS NOT NULL`** (proiectare `canal_cont_venit_fara_politica.md`
|
||||
sectiunea 3) se planteaza "inainte de `:7278`" — deci **inlocuieste ambele garda de mai sus** cand
|
||||
`cont_venit` e populat. Asta e sigur (design-ul insusi), dar devine irelevant pentru `ntip=4`
|
||||
pentru ca linia nu ajunge niciodata aici (blocata la 1.3).
|
||||
|
||||
## 2. Ce se intampla defensiv daca cineva ajunge totusi acolo
|
||||
|
||||
Doua scenarii distincte, cu raspunsuri diferite:
|
||||
|
||||
**(a) Scenariul normal — `cont_venit` populat, `id_pol` NULL (cum cere premiza proiectului)**:
|
||||
esec **la adaugarea articolului**, nu la scrierea facturii. Eroare Oracle bruta
|
||||
(`ORA-01403: no data found`), aparuta din `adauga_articol_factura` (`:5080-5103`), propagata prin
|
||||
`goExecutor` catre VFP ca `oPrelucrareEroare()` — **nu `FACT-024`** (acela e alt cod, alta functie,
|
||||
alt moment). Utilizatorul vede un mesaj Oracle generic, nu un mesaj de business explicativ. Nu
|
||||
exista azi niciun cod care sa traduca acest caz intr-un mesaj prietenos — e un gol de UX, nu de
|
||||
integritate a datelor (nu se scrie nimic gresit, doar esueaza fara explicatie buna).
|
||||
|
||||
**(b) Scenariul defensiv real — `cont_venit` SI `id_pol` populate simultan pe aceeasi linie**
|
||||
(nimic in schema nu impune exclusivitate reciproca; `VANZARI_DETALII_TEMP.CONT_VENIT` e o coloana
|
||||
noua, fara `CHECK` care sa lege de `ID_POL`). Daca cineva (bug in VFP, sau folosire deliberata
|
||||
combinata pe viitor) ar trimite ambele populate pe un document `ntip=4`: pasul 1.3 ar reusi
|
||||
(`V_ID_POL` nu mai e NULL, deci `SELECT` din `VANZARI_DETALII` isi gaseste randul), linia intra in
|
||||
`VANZARI_DETALII_TEMP` cu `cont_venit` **si** `id_pol` completate. La `contabilizeaza_articol`,
|
||||
ramura noua (`detalii_articol.cont_venit IS NOT NULL`) preia controlul complet — **fara sa
|
||||
verifice `ntip`** — si executa necondiționat `scrie_nota` + `descarca_gestiune` + discount, exact
|
||||
ca pentru o factura normala. **Nu cade cu nicio eroare. Scrie tacut date gresite**: sare complet
|
||||
peste `scrie_fact_aviz_custodie` (`:7521-7536`), care exista tocmai pentru ca marfa a iesit deja
|
||||
din gestiune cand s-a scris avizul sursa — rularea `descarca_gestiune` in loc de acea functie
|
||||
**descarca stocul a doua oara** pentru aceeasi marfa, fara nicio garda care sa prinda dubla
|
||||
scadere. Acesta e raspunsul relevant pentru textul de plan: nu un crash, un **defect tacut de
|
||||
date** daca vreodata cele doua canale se intalnesc pe aceeasi linie.
|
||||
|
||||
## 3. Toate valorile `ntip` relevante in zona `contabilizeaza_articol` (`:7173-7547`) — verdict per valoare
|
||||
|
||||
Ramura noua (`cont_venit IS NOT NULL`) inlocuieste tot ce e listat mai jos, necondiționat de `ntip`
|
||||
(design-ul, sectiunea 3, nu mentioneaza `ntip` deloc in continutul ramurii noi). Verdictul de mai
|
||||
jos e "atinsa" = poate ajunge cu `cont_venit` populat prin `adauga_articol_factura` fara sa esueze
|
||||
la pasul 1.3-echivalent; "neatinsa" = blocata structural inainte de a ajunge aici (ca `ntip=4`);
|
||||
"ambigua" = depinde de alt cod neverificat complet in aceasta runda.
|
||||
|
||||
| `ntip` | Comportament azi in `contabilizeaza_articol` | Atinsa de linie `cont_venit`? | Verdict fata de ramura noua |
|
||||
|---|---|---|---|
|
||||
| `<=20` sau `IN (43,44,45,46,48,49,51,52)` (`:7400-7412`) | SCD/ASCD din politica (`crs_rand_articol.scd`) — bucket "factura" | **DA** — `adauga_articol_factura` pentru aceste `ntip` foloseste calea generica (`ELSE`, `:5187-5203`, fara cerinta de `id_pol`) sau ramuri proprii (`2,6,26,52`→contract, `45`→restaurant) care oricum accepta `V_PRET_TEMP` cand nu gasesc potrivire | **E cazul acoperit de design** — SCD='4111' hardcodat e gandit exact pentru acest bucket. Fara probleme noi, cu exceptia sub-cazurilor de mai jos. |
|
||||
| `= 46` (`nTipNotaPlata`), sub-caz al bucketului "factura" | `scrie_nota` **NU se apeleaza** (`:7441`, `IF ntip <> nTipNotaPlata`) | DA (e in bucketul de mai sus) | **GOL SORA nou, neconsemnat in proiectare**: ramura noua apeleaza `scrie_nota` necondiționat — pentru un document `NotaPlata` cu linie `cont_venit`, s-ar scrie o nota care azi e sarita intentionat. De adaugat aceeasi garda in ramura noua. |
|
||||
| `= 7`, sub-caz al bucketului "factura" | `EXPLICATIE` primeste sufix `' INVOICE:' + cdescriere` (`:7431-7433`) | DA | **Gol cosmetic**: ramura noua foloseste direct `detalii_articol.explicatia`, fara sufix. Probabil acceptabil (design-ul il numeste "mai bun"), dar e o schimbare de continut pe documente de export, de confirmat. |
|
||||
| `IN (8,9)`, sub-caz al bucketului "factura" | `EXPLICATIE` primeste sufix `' RETUR FACTURA:' + cdescriere` (`:7434-7436`) | DA | Acelasi gol cosmetic ca mai sus. |
|
||||
| `IN (28,29)` (`:7413-7417`) | SCD hardcodat `'461'` — aviz catre clienti debitori | **DA** — `adauga_articol_factura` pentru `28` intra pe ramura `ntip IN (3,21,28,42,47)` (`:5053-5078`), care cauta in `COMENZI_ELEMENTE` dupa comanda+pret, **nu dupa `id_pol`** — un articol fara politica poate gasi potrivire aici daca exista element de comanda corespunzator | **GOL SORA, mai grav decat `ntip=4`**: ramura noua ar scrie `SCD='4111'` in loc de `'461'` pe un aviz catre client debitor — cont contabil gresit, atins efectiv. |
|
||||
| toate celelalte (`ELSE`, `:7418-7422`: `21,22,23,24,25,27,30,41,42,47,...`) | SCD hardcodat `'418'` — aviz generic | **DA, pentru aceleasi motive** (multe din aceste `ntip` — `3,21,42,47` — trec prin ramura "din comenzi" fara cerinta de `id_pol`; altele avansate direct din bucket implicit `ELSE` din `adauga_articol_factura`, `:5187-5203`, care nu cere `id_pol` deloc) | **Acelasi gol SCD hardcodat**, aplicabil la orice document de tip aviz (nu doar 28/29). |
|
||||
| `= 4` (`:7472,7520-7537`) | `scrie_fact_aviz_custodie` in loc de `descarca_gestiune`+discount | **NU** — exclus structural la pasul 1.3 (`adauga_articol_factura` esueaza inainte) | Neatins in scenariul normal (a); atins doar in scenariul defensiv (b) daca cineva forteaza `id_pol` si `cont_venit` simultan — vezi sectiunea 2. |
|
||||
|
||||
**Cel mai important rezultat al acestui tabel**: golul cerut explicit (`ntip=4`) e cel **mai putin
|
||||
grav** dintre cele gasite, pentru ca e singurul exclus structural. Golurile reale, efectiv atinse,
|
||||
sunt hardcodarea `SCD='4111'` pe orice document de tip **aviz** (`28`,`29` si bucket-ul `ELSE`) si
|
||||
omisiunea gardei `ntip=46` pentru `scrie_nota`.
|
||||
|
||||
## 4. Text propus pentru plan (sectiunea deciziei 34)
|
||||
|
||||
```
|
||||
**Ramura `ntip=4` (facturare din avize, `:7520-7537`) — exclusa structural, nu necesita cod
|
||||
suplimentar.** `adauga_articol_factura`, ramura `WHEN ntip=4` (`:5080-5103`), cauta randul sursa
|
||||
din `VANZARI_DETALII` prin `A.ID_POL = V_ID_POL`, fara handler de exceptie — cu `V_ID_POL=NULL`
|
||||
(exact cazul liniei fara politica), comparatia nu se poate potrivi niciodata, deci apelul cade cu
|
||||
`ORA-01403` la adaugarea articolului, inainte ca linia sa ajunga la `contabilizeaza_articol`. Un
|
||||
articol fara politica nu poate fi, structural, adaugat pe un document `ntip=4`; ramura noua
|
||||
`cont_venit` nu are nimic de tratat aici.
|
||||
|
||||
**Gol descoperit, de acoperit inainte de implementare**: ramurile de **aviz** (`ntip IN (28,29)` →
|
||||
`SCD='461'`, celelalte → `SCD='418'`, `:7413-7422`) **raman accesibile** cu `cont_venit` populat —
|
||||
`adauga_articol_factura` nu cere `id_pol` pentru aceste `ntip` (foloseste calea "din comenzi" sau
|
||||
calea implicita). Ramura noua trebuie sa aleaga `SCD` in functie de `ntip` (pastrand `'461'`/`'418'`
|
||||
pentru avize), nu sa hardcodeze `'4111'` necondiționat — altfel orice aviz cu articol fara politica
|
||||
primeste contul de clienti in loc de contul de aviz. Similar, ramura noua trebuie sa pastreze garda
|
||||
`IF ntip <> nTipNotaPlata` inainte de a apela `scrie_nota` (azi sarita pentru `ntip=46`).
|
||||
|
||||
**Defensiv (opțional)**: daca se doreste o garda explicita in loc de a te baza pe imposibilitatea
|
||||
structurala de mai sus, se poate adauga `IF detalii_articol.cont_venit IS NOT NULL AND
|
||||
pack_facturare.ntip = 4 THEN RAISE_APPLICATION_ERROR(...)` la inceputul ramurii noi — util doar
|
||||
daca cineva ar reusi vreodata sa populeze simultan `id_pol` si `cont_venit` pe o linie `ntip=4`
|
||||
(azi imposibil pe caile VFP cunoscute), caz in care ramura noua ar rula altfel tacut
|
||||
`descarca_gestiune` in loc de `scrie_fact_aviz_custodie`, riscand dubla descarcare de gestiune.
|
||||
```
|
||||
|
||||
## 5. Ce nu s-a putut stabili in aceasta runda
|
||||
|
||||
- **Daca exista vreo cale VFP care sa populeze simultan `poArt.id_pol` si viitorul `cont_venit`**
|
||||
(scenariul defensiv (b)) — cercetarea de fata arata doar ca schema/codul Oracle nu o impiedica;
|
||||
n-am gasit (si nici n-am cautat exhaustiv) un loc in VFP care ar genera aceasta combinatie azi.
|
||||
Probabil imposibil pe fluxurile curente (proiectarea de baza presupune `cont_venit` populat
|
||||
**doar** cand `id_pol` lipseste), dar nu demonstrat exhaustiv pe tot codul VFP.
|
||||
- **Comportamentul exact `oExecute`/`oPrelucrareEroare` la o exceptie Oracle neprinsa** (scenariul
|
||||
(a)) — presupus ca ajunge la utilizator ca mesaj Oracle brut prin mecanismul general de eroare al
|
||||
`goExecutor`, dar nu am urmarit codul `oPrelucrareEroare()` in aceasta runda pentru a confirma
|
||||
formatarea exacta.
|
||||
- **Daca `ntip IN (23,25,30,41)` (transfer subunitati) si `IN (42,47)` (custodie) pot, in practica,
|
||||
sa primeasca un articol fara politica** prin ramura "din comenzi" a `adauga_articol_factura`
|
||||
(`:5053-5078`) — argumentat structural posibil (nu cere `id_pol`), dar nu testat pe date, nu
|
||||
urmarit pana la capat daca `COMENZI_ELEMENTE` insusi ar putea contine un rand fara politica.
|
||||
|
||||
## Handoff
|
||||
|
||||
Cercetare incheiata, toate cele 5 livrabile cerute de team-lead sunt in sectiunile 1-4 de mai sus.
|
||||
Niciun cod atins, nicio scriere Oracle, doar `SELECT`/`Read`/`Grep`. Context consumat moderat —
|
||||
nu a fost necesara predarea de context.
|
||||
Reference in New Issue
Block a user