docs: planurile, proiectarile si rapoartele de lucru intra in versionare
Folderul docs\ era pana acum in afara oricarui control de versiuni - nici git, nici SVN - desi contine planurile pe puncte, proiectarile si rapoartele de cercetare pe care se sprijina modificarile din cod. O stergere acolo era definitiva. Fisierele intermediare (handoff-uri intre sesiuni, diff-uri deja aplicate) au fost sterse inainte, nu versionate: ce era durabil in ele a intrat in antetele fisierelor de test la care se refereau. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SN8snvkk94KuhWwoXUUey3
This commit is contained in:
373
docs/cercetare/optiune_firma_cont_debit.md
Normal file
373
docs/cercetare/optiune_firma_cont_debit.md
Normal file
@@ -0,0 +1,373 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user