374 lines
22 KiB
Markdown
374 lines
22 KiB
Markdown
# Optiune de firma pentru contul de debit (`SCD`) pe ramura fara politica de pret (#13, decizia 36)
|
||
|
||
Cercetare read-only, terminata. Continua `canal_cont_venit_fara_politica.md` (proiectarea
|
||
parametrului de cont, sectiunea "Proiectarea parametrului de cont contabil", `:27-241`) si
|
||
verificarea ei, `parametru_cont_contabilizeaza_articol.md`. Acolo, randul `SCD` din tabelul de
|
||
sectiunea 3 propunea **`SCD` hardcodat `'4111'`**, marcat explicit "de confirmat cu Marius"
|
||
(`canal_cont_venit_fara_politica.md:146`). **Decizia 36 (Marius, 10.08.2026): `SCD` vine dintr-o
|
||
optiune de firma, cu `4111` ca implicit** — motivul fiind ca se poate schimba la client fara
|
||
recompilare. Aici e proiectarea acelei optiuni. Decizia 31 se aplica: datele din baza de dev arata
|
||
ce *exista*, nu ce e configurat la client — nu se generalizeaza pe numere, doar pe tipar/structura.
|
||
|
||
Oracle interogat doar `SELECT`, schema `MARIUSM_AUTO`/`ROA_CENTRAL`. Niciun fisier de cod atins.
|
||
|
||
---
|
||
|
||
## 0. Rezumat, in cinci randuri
|
||
|
||
Mecanismul de optiuni de firma **exista deja de 15+ ani** (`PACK_SESIUNE.getoptiunefirma`, tabelul
|
||
`OPTIUNI`, 458 randuri azi) si are **exact tiparul cerut deja in productie, in acelasi pachet**:
|
||
`pack_facturare.scrie_incasare2` seteaza `V_SCD` dintr-o optiune (`RF_CONT_INCASARE_BONFISCAL` etc.,
|
||
cate una per tip de incasare), cu fallback pe un cont hardcodat daca optiunea lipseste — **acelasi
|
||
camp (`SCD`), acelasi pachet, aceeasi sursa Oracle** (`ff_2026_08_09_01_COMUN_PACK_FACTURARE.sql`,
|
||
liniile 13191-13233, tratate integral in sectiunea 2). Ecranul de editare (`frm_optiuni`/
|
||
`frm_optiuni_nou`, `COMUN\clase\oOptiuni.vc2`) e **complet generic** peste tabelul `OPTIUNI` —
|
||
adaugarea cheii noi **nu cere niciun cod VFP nou** in ecranul de optiuni, doar randul in tabel.
|
||
Propunerea (sectiunea 3): cheia noua `FACT_SCD_ARTFPRET` (sau numele ales de Marius), instalata cu
|
||
valoare implicita `'4111'` chiar in randul din `OPTIUNI` (tiparul deja folosit de toate exemplele
|
||
gasite), **plus** fallback hardcodat `'4111'` in cod langa `getoptiunefirma`, in oglinda exacta a
|
||
tiparului `scrie_incasare2` — dubla plasa de siguranta (instalare veche fara randul din `OPTIUNI`
|
||
**si** rand editat gresit/gol raman amandoua acoperite).
|
||
|
||
---
|
||
|
||
## 1. Cum functioneaza mecanismul de optiuni de firma, azi
|
||
|
||
### 1.1 Stocare — tabelul `OPTIUNI`
|
||
|
||
Interogat direct (`ALL_TAB_COLUMNS`, schema curenta), 458 randuri azi:
|
||
|
||
| Coloana | Tip | Null | Rol |
|
||
|---|---|---|---|
|
||
| `ID_OPTIUNI` | `NUMBER` | N | cheie surogat, PK implicita |
|
||
| `VARNAME` | `VARCHAR2(30)` | Y | cheia optiunii — cautata `UPPER(TRIM(...))`, deci case-insensitive in practica |
|
||
| `VARTYPE` | `VARCHAR2(10)` | Y | eticheta de tip pentru randare/parsare in VFP: `CHARACTER`/`NUMERIC`/`CURRENCY`/`DATE`/`DATETIME`/`LOGICAL` — **descriptiva, nu impusa de Oracle**; distinct azi: `CHARACTER` 156, `NUMERIC` 288, `LOGICAL` 11, `DATE` 3 |
|
||
| `VARVALUE` | `VARCHAR2(1000)` | Y | valoarea, **mereu text**, indiferent de `VARTYPE` |
|
||
| `VARVALUE2` | `CLOB` | Y | valoare alternativa, folosita de un mecanism separat (`citeste_optiune(tcOptiune, tlValue2)`, `oinit_optiuni.prg:802-823`) — irelevant aici |
|
||
| `VARDESC` | `VARCHAR2(100)` | Y | descriere afisata in ecran |
|
||
| `PROGRAM` | `VARCHAR2(30)` | Y | produsul care a creat optiunea (metadata) |
|
||
| `PROGRAME` | `VARCHAR2(1000)` | Y | lista CSV de produse pentru care optiunea e vizibila/relevanta (folosita la filtrare in incarcarea globala VFP, sectiunea 1.4) |
|
||
| `ID_PRG_OWNER` | `NUMBER` | Y | neexaminat mai departe, neрелevant aici |
|
||
|
||
**Fara `ID_FIRMA`.** Motivul: fiecare firma are **schema Oracle proprie** — tabelul `OPTIUNI` din
|
||
schema curenta de conexiune **este** deja "optiunile firmei curente"; nu exista randare
|
||
multi-firma in acelasi tabel. Confirmat si de codul VFP: `frm_optiuni.cschema` e setat la
|
||
constanta de compilare `CONTAFIN_ORACLE` (`oOptiuni.vc2:1089`, acelasi simbol folosit peste tot in
|
||
COMUN pentru "schema firmei curente"), iar `getoptiunefirma(tcS, tcOptiune)` **primeste** un
|
||
parametru de schema (`tcS`, azi mereu `USER`) dar **nu il foloseste in interogare** — `select
|
||
varvalue from optiuni` fara calificare de schema (cod exact la sectiunea 1.2) — pentru ca sesiunea
|
||
Oracle e deja conectata direct in schema firmei. `tcS` ramane doar din compatibilitate istorica cu
|
||
supraincarcarea `getOptiuneFirma(tcOptiune)` (fara schema), care apeleaza pe cea cu doi parametri
|
||
cu `user` (sectiunea 1.2).
|
||
|
||
### 1.2 Semnatura si contract — `PACK_SESIUNE.getoptiunefirma`
|
||
|
||
Sursa curenta confirmata prin `ALL_SOURCE` pe pachetul live (`PACK_SESIUNE`, tip `PACKAGE BODY`) —
|
||
identica, verificat, cu ultima versiune gasita in `SCRIPTURI_CLAR`
|
||
(`2014/04/ff_2014_04_24_01_COMUN_PACK_SESIUNE.sql:328-350`; nicio modificare de atunci, cautare
|
||
`FUNCTION getoptiunefirma` in `SCRIPTURI_CLAR/2024`, `/2025`, `/2026` — zero rezultate):
|
||
|
||
```sql
|
||
FUNCTION getoptiunefirma(tcS IN VARCHAR2, tcOptiune IN VARCHAR2)
|
||
RETURN VARCHAR2 IS
|
||
lcValue Optiuni.Varvalue%Type := '';
|
||
BEGIN
|
||
BEGIN
|
||
select varvalue
|
||
INTO lcValue
|
||
from optiuni
|
||
where UPPER(TRIM(VARNAME)) = UPPER(TRIM(tcOptiune));
|
||
EXCEPTION
|
||
WHEN OTHERS THEN
|
||
lcValue := '';
|
||
END;
|
||
RETURN lcValue;
|
||
END;
|
||
|
||
FUNCTION getOptiuneFirma(tcOptiune IN VARCHAR2) RETURN VARCHAR2 IS
|
||
lcValue Optiuni.Varvalue%Type := '';
|
||
BEGIN
|
||
lcValue := getOptiuneFirma(user, tcOptiune);
|
||
return lcValue;
|
||
END;
|
||
```
|
||
|
||
Contract, verificat pe `RETURN`, nu dedus din nume:
|
||
|
||
- **Parametru**: numele optiunii (`tcOptiune`), cautat `UPPER(TRIM(...))` — insensibil la caz si la
|
||
spatii; a doua forma (`getOptiuneFirma(tcOptiune)`, un singur parametru) e cea folosita azi peste
|
||
tot in `pack_facturare` (vezi sectiunea 2) — deleaga la forma cu doi parametri cu `user`.
|
||
- **Cand optiunea NU exista** (`NO_DATA_FOUND`, prins de `WHEN OTHERS` generic): **`RETURN ''`**
|
||
(string gol), **niciodata `NULL` explicit si niciodata exceptie propagata**. Insa in Oracle un
|
||
`VARCHAR2` egal cu `''` **este** `NULL` la nivel de reprezentare (Oracle nu distinge stringul gol
|
||
de `NULL`) — deci orice apelant care testeaza `IF V_X IS NULL THEN` dupa un apel la
|
||
`getoptiunefirma` **prinde si cazul "optiune inexistenta"**, fara cod suplimentar. Acesta e
|
||
exact tiparul folosit de toti apelantii gasiti (sectiunea 2).
|
||
- **`WHEN OTHERS THEN lcValue := ''`** inghite **orice** eroare, nu doar `NO_DATA_FOUND` (de ex. si
|
||
`TOO_MANY_ROWS` daca ar exista vreodata doua randuri cu acelasi `VARNAME` — nu exista constrangere
|
||
`UNIQUE` pe `VARNAME`, doar convenția aplicatiei). Nu e un risc nou introdus de propunerea de
|
||
fata — e comportamentul mecanismului de 15+ ani, pastrat ca atare.
|
||
- **Variante**: **o singura functie**, intotdeauna `VARCHAR2`. **Nu exista** `getoptiunefirma`
|
||
numerica/booleana separata in Oracle — conversia se face **la apelant**, in PL/SQL cu
|
||
`TO_NUMBER(NVL(...))` (exemplu confirmat, acelasi fisier, `scrie_incasare2`,
|
||
`ff_...:13177`: `TO_NUMBER(NVL(pack_sesiune.getoptiunefirma('D406'), '0'))`) sau in VFP cu
|
||
`VAL()`/`CTOD()`/etc., pe baza coloanei `VARTYPE` (vezi `oinit_optiuni.prg:179-211`, functia
|
||
`actualizeaza_optiuni_program`, care materializeaza fiecare optiune intr-o variabila globala VFP
|
||
cu prefix dupa tip: `gc<nume>` pentru `CHARACTER`, `gn<nume>` pentru `NUMERIC`,
|
||
`gl<nume>` pentru `LOGICAL` etc.). **Pentru un cont contabil (`VARCHAR2(4)`), varianta corecta e
|
||
cea de baza, `VARTYPE='CHARACTER'`** — exact tipul folosit de toate exemplele cu cont din
|
||
sectiunea 2, fara nicio conversie necesara la citire in PL/SQL (`V_SCD` e deja `VARCHAR2`).
|
||
|
||
### 1.3 Ecranul de editare — complet generic peste tabel
|
||
|
||
`COMUN\clase\oOptiuni.vc2`, doua clase relevante:
|
||
|
||
- **`frm_optiuni`** (`:1064-1314`) — grid pe view-ul VFP local `v_optiuni` (populat dintr-un
|
||
`SELECT * FROM <schema>.optiuni`, vezi `oinit_optiuni.prg:337` in `viz_optiuni`), 4 coloane
|
||
(`varname`, `vartype`, `varvalue`, `vardesc`), cu cautare doar dupa `varname LIKE`
|
||
(`do_cauta`, `:1261-1278`) si butoane Adauga/Modifica/Sterge care deschid `frm_optiuni_nou`.
|
||
- **`frm_optiuni_nou`** (`:1316-1462`) — formular Adauga/Modifica cu 4 campuri: `varname` (text,
|
||
`Format="!K"` = uppercase), `vartype` (combobox cu lista fixa `CHARACTER,CURRENCY,NUMERIC,
|
||
DATETIME,DATE,LOGICAL`), `varvalue` (text), `vardesc` (text). Validare la salvare
|
||
(`inainte_de_do_termin`, `:1417-1450`): **doar "nu e gol"** pe `varname`, `vartype`, `varvalue` —
|
||
**nicio validare de format sau de continut** (nu verifica lungime, nu verifica daca `varvalue`
|
||
e un cont existent in planul de conturi, nimic specific per optiune).
|
||
- **`cus_odata_optiuni`** (`:139-206`) — clasa de persistenta: `INSERT`/`UPDATE`/`DELETE` generic pe
|
||
`optiuni (varname, vartype, varvalue, vardesc)` — confirma ca **orice cheie noua** functioneaza
|
||
fara nicio schimbare la acest cod; scrie exact cele 4 coloane editabile din ecran.
|
||
|
||
**Concluzie la intrebarea "adaugarea unei optiuni noi cere cod nou in ecran": NU.** Ecranul e
|
||
generic peste tabel dupa cele 4 coloane editabile. Randul nou (`FACT_SCD_ARTFPRET`, sectiunea 3)
|
||
apare automat in grid dupa ce e inserat, si e editabil din prima fara nicio modificare VFP.
|
||
|
||
*Nota conexa, nu necesara pentru mecanismul Oracle*: la fiecare pornire de sesiune, VFP
|
||
materializeaza **toate** randurile din `OPTIUNI` in variabile globale (`optiuni_firma`,
|
||
`oinit_optiuni.prg:234-310`), filtrate `Isnull(programe) Or gcNumeProgram $ programe` — deci coloana
|
||
`PROGRAME` conteaza doar pentru **vizibilitatea in acest mecanism global VFP**, nu pentru
|
||
`getoptiunefirma` (care nu se uita deloc la `PROGRAME`). Optiunea noua nu are nevoie de acest canal
|
||
VFP (Oracle o citeste direct), dar completarea corecta a `PROGRAME` evita zgomot/confuzie daca
|
||
cineva se uita in `frm_optiuni` din ROAFACTURARE si se asteapta sa vada optiunea listata acolo cu
|
||
`gcNumeProgram = 'ROAFACTURARE'` in `PROGRAME`.
|
||
|
||
---
|
||
|
||
## 2. Exemple reale de optiuni existente, cu lantul complet
|
||
|
||
### 2a. `RF_CONT_INCASARE_*` — exact tiparul cerut, in acelasi pachet, pe acelasi camp `SCD`
|
||
|
||
**Cel mai relevant exemplu posibil**: patru optiuni care alimenteaza direct `SCD` pe o nota
|
||
contabila, in `pack_facturare.scrie_incasare2` — **aceeasi functie Oracle pe care propunerea de la
|
||
`canal_cont_venit_fara_politica.md` o modifica** (acelasi fisier,
|
||
`ff_2026_08_09_01_COMUN_PACK_FACTURARE.sql`).
|
||
|
||
**Randul din tabel** (interogat direct, 4 randuri, VARTYPE `CHARACTER` la toate):
|
||
|
||
| VARNAME | VARVALUE azi | VARDESC | PROGRAM | PROGRAME |
|
||
|---|---|---|---|---|
|
||
| `RF_CONT_INCASARE_BONFISCAL` | `5311` | `CONTUL DEBITOR PENTRU NOTA DE INCASARE 5311 = 4111` | `ROAFACTURARE` | `ROAFACTURARE,ROAACNPRO,ROACOMENZI,ROACONTRACTE,ROAGEST,ROARESTAURANT` |
|
||
| `RF_CONT_INCASARE_CARDBANCAR` | `5125` | `CONTUL DEBITOR PENTRU NOTA DE INCASARE 5113 = 4111` | idem | idem |
|
||
| `RF_CONT_INCASARE_TICHETE` | `5323` | `CONTUL DEBITOR PENTRU NOTA DE INCASARE 5323 = 4111` | idem | idem |
|
||
| `RF_CONT_INCASARE_CHITANTA` | `5311` | `CONTUL DEBITOR PENTRU NOTA DE INCASARE 5311 = 4111` | idem | idem |
|
||
|
||
(`VARDESC` mentioneaza si `= 4111` — nu e o eroare de copy-paste: e nota ca partea de credit a
|
||
notei de incasare e contul de clienti `4111`, deci descrierea documenteaza ambele parti ale notei,
|
||
nu doar valoarea implicita a optiunii.)
|
||
|
||
**Insertia originala** (`SCRIPTURI_CLAR/2010/08/ff_2010_08_11_01_OPTIUNI.sql:9-19`), tiparul de
|
||
migrare de urmat:
|
||
|
||
```sql
|
||
insert into optiuni (VARNAME, VARTYPE, PROGRAM, VARVALUE, VARDESC, ID_PRG_OWNER, PROGRAME)
|
||
values ('RF_CONT_INCASARE_BONFISCAL', 'CHARACTER', 'ROAFACTURARE', '5311',
|
||
'CONTUL DEBITOR PENTRU NOTA DE INCASARE 5311 = 4111', null, 'ROAFACTURARE');
|
||
```
|
||
|
||
**Apelul din PL/SQL** (`ff_2026_08_09_01_COMUN_PACK_FACTURARE.sql:13161-13234`,
|
||
`PROCEDURE scrie_incasare2`), citit integral — **exact tiparul "optiune cu fallback hardcodat" cerut
|
||
de decizia 36**:
|
||
|
||
```sql
|
||
V_SCD := V_PSCD; -- parametru explicit, daca a fost dat de apelant (ff_...:13185)
|
||
CASE
|
||
WHEN V_TIP = nTipIncasareBonFiscal THEN
|
||
...
|
||
IF V_SCD IS NULL THEN
|
||
V_SCD := PACK_SESIUNE.getoptiunefirma('RF_CONT_INCASARE_BONFISCAL');
|
||
END IF;
|
||
IF V_SCD IS NULL THEN
|
||
V_SCD := '5311'; -- fallback hardcodat, instalare veche
|
||
END IF;
|
||
...
|
||
END CASE;
|
||
```
|
||
|
||
Trei niveluri, in ordine: **(1) parametru explicit daca a fost dat, (2) optiunea de firma, (3)
|
||
constanta hardcodata** — folosita si daca randul din `OPTIUNI` lipseste complet (instalare veche,
|
||
migrare neaplicata) *si* daca a fost sters/golit manual din ecran. Acest cont ajunge apoi direct in
|
||
`INSERT INTO ACT_TEMP (..., SCD, ...)` (`ff_...:13241-13249` in continuare), **fara nicio validare
|
||
suplimentara de format sau de existenta in planul de conturi** — nici in Oracle, nici in ecranul de
|
||
optiuni (sectiunea 1.3), nici la `INSERT`.
|
||
|
||
**Ecranul de editare**: acelasi `frm_optiuni`/`frm_optiuni_nou` generic (sectiunea 1.3) — niciun
|
||
ecran dedicat pentru aceste 4 optiuni, se editeaza ca text simplu in grid.
|
||
|
||
### 2b. `D406` — optiune numerica/booleana folosita ca flag, cu conversie explicita la citire
|
||
|
||
`VARNAME='D406'`, `VARTYPE='NUMERIC'`, `VARVALUE='1'`, `PROGRAM='ROACONT'`,
|
||
`PROGRAME='ROACONT,ROAAUTO,ROACONTRACTE,ROADEVIZE,ROAFACTURARE,...'`. Citita in acelasi
|
||
`scrie_incasare2` (`ff_...:13177`): `lnD406 := TO_NUMBER(NVL(pack_sesiune.getoptiunefirma('D406'),
|
||
'0'))` — **tipar de citire pentru optiune numerica**: `getoptiunefirma` intoarce mereu text,
|
||
apelantul face `NVL(...,'0')` inainte de `TO_NUMBER` (aici fallback-ul `'0'` e in acelasi loc cu
|
||
apelul, nu separat ca la `RF_CONT_INCASARE_*` — variatie minora de stil intre autori, nu o regula
|
||
diferita).
|
||
|
||
### 2c. `CONT411` si `DEVCONTALTELE` — optiuni "cont" mai vechi, azi orfane in cod
|
||
|
||
`CONT411` (`VARTYPE='CHARACTER'`, `VARVALUE='4111'`, `VARDESC='411 SAU 4111'`, fara `PROGRAM`) si
|
||
`DEVCONTALTELE` (`VARTYPE='CHARACTER'`, `VARVALUE='704'`, `VARDESC='CONT ALTE SERVICII FACTURA'`,
|
||
`PROGRAM='ROAAUTO'`) — cautare `grep` pentru ambele in tot `SCRIPTURI_CLAR`: **niciun apelant activ
|
||
gasit** (doar insertiile originale din 2011). Probabil cod dezafectat sau folosit doar din alt
|
||
produs/raport neexaminat aici. Mentionate pentru completitudine si pentru ca `CONT411` confirma
|
||
**exact valoarea implicita ceruta de Marius** (`4111`) ca precedent de configurare tot pe un cont
|
||
de clienti — dar **nu** au un lant activ de apel, deci nu sunt un exemplu de "tipar in uz" la fel de
|
||
tare ca `RF_CONT_INCASARE_*`.
|
||
|
||
### 2d. `EFACTURA_CONT_ART_E`/`EFACTURA_CONT_ART_P` — optiune "cont implicit pe articol", azi goala
|
||
|
||
`VARTYPE='CHARACTER'`, `VARVALUE` **goala** azi (nesetata pe baza curenta), `VARDESC='CONT ARTICOLE
|
||
IMPLICIT FACTURI EMISE'`/`'...PRIMITE'`, `PROGRAM='ROACONT'`. Confirma ca tiparul "cont implicit
|
||
configurabil, gol pana e setat manual" exista deja ca optiune (nu s-a putut verifica in aceasta
|
||
runda cine o citeste — cautare in afara scopului, modulul `ROACONT`/eFactura nu a fost deschis).
|
||
Relevanta doar ca a patra confirmare a conventiei de nume (`EFACTURA_CONT_ART_<sufix>`), nu ca lant
|
||
complet verificat.
|
||
|
||
---
|
||
|
||
## 3. Propunerea concreta
|
||
|
||
### 3.1 Cheia optiunii
|
||
|
||
**`FACT_SCD_ARTFPRET`** — respecta conventia dominanta observata in tabel: prefix de modul
|
||
(`FACT` pentru optiunile specifice `pack_facturare`/ROAFACTURARE, ca `FACTSETURI`,
|
||
`FACTALGREPCOM`, `FACTURACUCHITANTA`, `FACTURAEMAIL`, `FACTURASOLD` — toate `PROGRAM='ROAFACTURARE'`)
|
||
plus sufix descriptiv scurt fara diacritice si fara spatii (`SCD` = campul contabil vizat,
|
||
`ARTFPRET` = "articol fara politica de pret" — in oglinda cu numele deja folosit in proiectarea
|
||
anterioara, "ramura fara politica"). Nicio cheie `SCD`/`SCC` existenta azi in tabel (cautare directa,
|
||
zero rezultate) — nu exista risc de coliziune de nume. **Alternativa mai scurta**, daca Marius
|
||
prefera: `SCD_FARA_POLITICA` (fara prefix de modul) — tiparul din tabel nu e strict, exista si chei
|
||
fara prefix (`D406`, `CONT411`); prefixul `FACT_` e recomandat, nu obligatoriu.
|
||
|
||
### 3.2 Valoarea implicita si unde traieste
|
||
|
||
**Tiparul deja stabilit si folosit de `RF_CONT_INCASARE_*` (sectiunea 2a) se copiaza identic**:
|
||
implicitul traieste **in doua locuri**, nu unul:
|
||
|
||
1. **In randul din `OPTIUNI`, la instalare** — valoarea `VARVALUE='4111'` scrisa direct de scriptul
|
||
de migrare (sectiunea 3.4). Asta e valoarea pe care o vede si o poate schimba Marius/clientul din
|
||
`frm_optiuni`, fara recompilare — exact cerinta deciziei 36.
|
||
2. **Hardcodat in PL/SQL, langa apelul `getoptiunefirma`**, ca a doua plasa de siguranta pentru
|
||
instalari vechi unde migrarea nu a rulat inca sau randul a fost sters/golit manual din ecran:
|
||
|
||
```sql
|
||
V_SCD := PACK_SESIUNE.getoptiunefirma('FACT_SCD_ARTFPRET');
|
||
IF V_SCD IS NULL THEN -- acopera si randul lipsa, si VARVALUE gol/sters din ecran (sectiunea 1.2)
|
||
V_SCD := '4111';
|
||
END IF;
|
||
```
|
||
|
||
Plasata **in ramura noua din `contabilizeaza_articol`** (`canal_cont_venit_fara_politica.md:146`,
|
||
randul `SCD` din tabelul design-ului), **in locul** liniei `SCD := '4111'` hardcodat propuse acolo —
|
||
inlocuire punctuala, restul ramurii (`ASCD` calculat din `GetAnaliticByGrupUtilizatori(...,
|
||
V_SCD)`, deja dependent de `V_SCD`) ramane neschimbat, primeste automat valoarea corecta indiferent
|
||
de sursa (optiune sau fallback).
|
||
|
||
### 3.3 Comportamentul cand optiunea lipseste sau e invalida
|
||
|
||
- **Lipseste randul din `OPTIUNI`** (instalare veche, migrare neaplicata): `getoptiunefirma` intoarce
|
||
`''` -> tratat `IS NULL` in Oracle -> fallback la `'4111'` hardcodat (sectiunea 3.2, pasul 2).
|
||
**Acoperit prin constructie**, acelasi tipar ca `RF_CONT_INCASARE_*`.
|
||
- **Randul exista dar `VARVALUE` e gol** (sters manual din ecran, fara sa fi fost stearsa cheia):
|
||
identic cazului anterior — `''` tot `IS NULL` in Oracle. **Acoperit prin constructie.**
|
||
- **`VARVALUE` contine un cont care nu exista in planul de conturi**, sau un string cu lungime/
|
||
format invalid: **nu exista nicio validare azi**, nici in `getoptiunefirma`, nici in ecranul de
|
||
optiuni (sectiunea 1.3, "nicio validare de format sau de continut"), nici la `INSERT INTO
|
||
ACT_TEMP` (coloana `SCD` e `VARCHAR2(4) NULL` fara `CHECK`, fara `FK`, confirmat in DDL-ul deja
|
||
citat in `canal_cont_venit_fara_politica.md`, sectiunea DDL). Un cont inexistent ar ajunge pe nota
|
||
neschimbat — **exact acelasi risc pe care il are deja `RF_CONT_INCASARE_*` de 15 ani**, nu unul
|
||
nou introdus de aceasta propunere. Daca se doreste o garda, ar trebui adaugata **la citire** (in
|
||
ramura noua din `contabilizeaza_articol`, dupa cele doua atribuiri de mai sus, cu un `SELECT
|
||
COUNT(*) FROM PLCONT WHERE COD_CONT = V_SCD` sau echivalent) — **nu exista azi un precedent de
|
||
validare pe niciuna dintre optiunile de tip cont examinate**, deci adaugarea uneia ar fi o
|
||
imbunatatire noua, nu o continuare a unui tipar existent; de decis explicit (sectiunea 4).
|
||
- **Lungime > 4 caractere** in `VARVALUE` (campul din tabel e `VARCHAR2(1000)`, mult mai lat decat
|
||
`ACT_TEMP.SCD VARCHAR2(4)`): ar da `ORA-12899` (value too large) la `INSERT INTO ACT_TEMP` daca
|
||
cineva scrie din greseala un text lung in ecran — eroare Oracle standard, nu un `NULL`/gol tacut;
|
||
comportament acceptabil ca gardă minimala "gratuita", fara cod suplimentar.
|
||
|
||
### 3.4 Scriptul de migrare — schita, neaplicata
|
||
|
||
Tiparul exact al insertiei `RF_CONT_INCASARE_BONFISCAL` (sectiunea 2a), idempotent prin verificarea
|
||
existentei prealabile (tipar comun in scripturile de migrare vazute in `SCRIPTURI_CLAR`, desi
|
||
insertia originala din 2010 nu avea garda — cea de mai jos o adauga, mai sigura pentru un script
|
||
care ar putea rula de doua ori):
|
||
|
||
```sql
|
||
-- ff_<data>_NN_COMUN_OPTIUNI.sql (schita, neaplicata)
|
||
DECLARE
|
||
V_CNT NUMBER;
|
||
BEGIN
|
||
SELECT COUNT(*) INTO V_CNT FROM OPTIUNI WHERE UPPER(TRIM(VARNAME)) = 'FACT_SCD_ARTFPRET';
|
||
IF V_CNT = 0 THEN
|
||
INSERT INTO OPTIUNI (VARNAME, VARTYPE, PROGRAM, VARVALUE, VARDESC, PROGRAME)
|
||
VALUES ('FACT_SCD_ARTFPRET', 'CHARACTER', 'ROAFACTURARE', '4111',
|
||
'CONTUL DEBITOR (SCD) PENTRU ARTICOL FACTURAT FARA POLITICA DE PRET',
|
||
'ROAFACTURARE');
|
||
END IF;
|
||
END;
|
||
/
|
||
exec pack_migrare.UpdateVersiune('ff_<data>_NN_COMUN_OPTIUNI');
|
||
commit;
|
||
```
|
||
|
||
`ID_PRG_OWNER` omis (rand `NULL` in toate exemplele citate, coloana pare neutilizata activ pentru
|
||
optiuni de firma simple). `PROGRAME='ROAFACTURARE'` — restrans, spre deosebire de
|
||
`RF_CONT_INCASARE_*` care listeaza 6 produse; de largit doar daca se confirma (in afara scopului
|
||
acestei cercetari, sectiunea "Ce ramane de decis") ca alte produse din suita ajung sa apeleze aceeasi
|
||
ramura din `contabilizeaza_articol` prin `adauga_articol_factura` simplu.
|
||
|
||
### 3.5 Validare la salvare in ecran
|
||
|
||
**Nu** — confirmat la sectiunea 1.3: `frm_optiuni_nou` valideaza doar "camp nevid" pe cele 3 campuri
|
||
principale, nicio validare specifica per-cheie. Optiunea noua se comporta identic cu restul tabelei:
|
||
utilizatorul poate scrie orice text de pana la 1000 caractere in `VARVALUE`, cu riscurile descrise
|
||
la sectiunea 3.3.
|
||
|
||
---
|
||
|
||
## 4. Ce ramane de decis
|
||
|
||
1. **Numele exact al cheii** — `FACT_SCD_ARTFPRET` propus (sectiunea 3.1); Marius poate prefera alt
|
||
nume sau formatul mai scurt `SCD_FARA_POLITICA`.
|
||
2. **Se adauga o validare a contului la citire** (cont trebuie sa existe in planul de conturi) sau
|
||
se pastreaza tiparul actual, fara validare, ca la `RF_CONT_INCASARE_*`? Niciun exemplu existent nu
|
||
valideaza — a introduce validare ar fi prima data cand se face asta pe o optiune de tip cont.
|
||
3. **`PROGRAME` restrans la `ROAFACTURARE` sau extins** ca la `RF_CONT_INCASARE_*` (6 produse)? Tine
|
||
de raspunsul, inca deschis in `parametru_cont_contabilizeaza_articol.md` sectiunea 2d, la
|
||
intrebarea daca alte produse din suita apeleaza `adauga_articol_factura` simplu.
|
||
4. **Textul exact din `VARDESC`** — schita de mai sus e o propunere, nu o cerinta.
|
||
|
||
---
|
||
|
||
## Ce nu s-a putut stabili
|
||
|
||
- **Cine citeste azi `EFACTURA_CONT_ART_E`/`EFACTURA_CONT_ART_P`** (sectiunea 2d) — cautarea s-a
|
||
oprit la insertia originala; modulul `ROACONT`/eFactura nu a fost deschis, in afara scopului
|
||
cerut (exemplul a servit doar ca a patra confirmare de conventie de nume, nu ca lant complet).
|
||
- **Definitia view-ului VFP local `v_optiuni`** (folosit ca `RecordSource` in `frm_optiuni`) — e un
|
||
cursor/view generat dinamic prin `gencursor()`/`goExecutor.oExecute()` din `oinit_optiuni.prg`, nu
|
||
un obiect Oracle persistent (interogare `DBMS_METADATA` pe `V_OPTIUNI` a esuat cu "object not
|
||
found", asteptat) — nu schimba nimic din propunere, doar noteaza ca numele nu desemneaza o vedere
|
||
Oracle.
|
||
- **Daca `CONT411`/`DEVCONTALTELE` (sectiunea 2c) mai au vreun apelant in alt produs din suita**
|
||
(ROACONT, ROAGEST etc.) — cautarea s-a limitat la `SCRIPTURI_CLAR` (tot codul PL/SQL istoric); nu
|
||
s-a cautat in `.vc2`/`.prg` din alte COMUN-uri de produs.
|