380 lines
29 KiB
Markdown
380 lines
29 KiB
Markdown
# S11 — Legaturile care raman pe `ID_VANZARE` la editarea prin regenerare
|
|
|
|
Stare: **in lucru**. Vezi sectiunea STARE / CE RAMANE la final pentru progres curent.
|
|
|
|
## Context (dat, nu se rediscuta)
|
|
|
|
#13 etapa II: editarea unei facturi = regenerare. Documentul vechi e soft-sters (`STERS=1`) si
|
|
reemis in aceeasi tranzactie. `ID_FACT`, seria, numarul si data se pastreaza. **`ID_VANZARE` se
|
|
schimba** — documentul reemis primeste un `id_vanzare` nou din secventa.
|
|
|
|
Sarcina: inventarul complet al legaturilor pe `VANZARI.ID_VANZARE` care se rup la aceasta
|
|
schimbare, clasificate (A) trebuie remigrat / (B) trebuie sters-refacut / (C) nu conteaza.
|
|
|
|
## 0. Puncte de plecare (de verificat, nu de preluat pe incredere)
|
|
|
|
- `docs\plan_13_unificare_formular_facturare.md` — sectiunea `#### S11` (linia ~3024)
|
|
- `docs\cercetare\idfact_refolosire_si_documente.md`
|
|
- `docs\cercetare\rec_cale_vanzari_detalii.md`
|
|
- `COMUN\docs\cercetare\rec_consumatori_vanzari.md`
|
|
- `docs\cercetare\cont_venit_corespondente.md`
|
|
- `docs\cercetare\legatura_linie_retur.md`
|
|
- `docs\cercetare\rec_d42_efactura.md`
|
|
- `docs\cercetare\s5c_factura_din_proforma.md` (sectiunea `VANZARI_CORESP`)
|
|
- PL/SQL: `D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\08\ff_2026_08_09_01_COMUN_PACK_FACTURARE.sql`
|
|
|
|
## 0-bis. Constatare centrala care schimba premisa din plan
|
|
|
|
**Mecanismul S9 (planificat) NU e acelasi cu mecanismul deja existent de editare (#6).** Astea sunt
|
|
doua cai distincte, si asta conteaza pentru fiecare consumator de mai jos:
|
|
|
|
- **#6, "editare directa"** (`frm_modific2024`/`omodificari.vc2`, `afisjurcom.do_modifica`,
|
|
`pack_contafin.finalizeaza_modificare_nota`): documentul vechi (identificat prin `cod`) primeste
|
|
`STERS=1` in `ACT`/`RUL`, se scrie un document nou cu `cod` nou, apoi
|
|
**`pack_facturare.actualizeaza_vanzari(V_COD_VECHI, V_COD_NOU)`**
|
|
(`ff_2026_08_09_01_COMUN_PACK_FACTURARE.sql:16012-16022`) face
|
|
`UPDATE VANZARI SET COD = V_COD_NOU, STERS = 0 WHERE COD = V_COD_VECHI` —
|
|
**randul `VANZARI` e REFOLOSIT, `ID_VANZARE` NU SE SCHIMBA**, doar `COD`. In continuare,
|
|
`finalizeaza_modificare_nota` face si `UPDATE atasamente_vanzari SET cod = lnCodNou WHERE cod =
|
|
tnCod` (`rec_modific2024.md:126`, confirmat `fisier:linie`). Acesta e mecanismul deja **livrat in
|
|
productie** (git log: `#6 editare factura emisa`, changelog 2.11.15/2.11.16).
|
|
- **#13 S9 (planificat, subiectul acestei cercetari)**: reemiterea merge **pe drumul normal de
|
|
emitere**, `scrie_factura2` -> `finalizeaza_factura` -> `scrie_in_vanzari`, care face
|
|
`INSERT INTO VANZARI (...) VALUES (...) RETURNING ID_VANZARE INTO pack_facturare.nid_vanzare`
|
|
(`rec_cale_vanzari_detalii.md:99`, confirmat separat in planul S9: „reemiterea scrie prin
|
|
`pack_facturare`, pe acelasi drum ca emiterea", `plan_13...md:2936-2937`). Acesta e un rand **nou**,
|
|
cu **`ID_VANZARE` nou din secventa** — exact premisa data de team-lead. `oscrie_in_fisiere`
|
|
intervine in S9 **doar la stergerea** documentului vechi (`plan_13...md:2938`), nu si la scriere,
|
|
deci **`actualizeaza_vanzari`/sincronizarea prin `finalizeaza_modificare_nota` NU se declanseaza
|
|
pentru S9** — acel mecanism ramane specific caii #6, nu se mosteneste automat de S9.
|
|
|
|
**Consecinta directa**: orice legatura tinuta azi prin `cod` (realiniata gratis de mecanismul #6) e
|
|
**expusa** la regenerarea din #13, pentru ca S9 nu trece prin `actualizeaza_vanzari`. Fiecare sectiune
|
|
de mai jos noteaza explicit daca protectia #6 s-ar fi aplicat sau nu.
|
|
|
|
## 1. Inventarul exhaustiv al consumatorilor de ID_VANZARE
|
|
|
|
| # | Tabela/mecanism | Cheie folosita | Scriitor(i) | Cititor(i) | Clasificare |
|
|
|---|---|---|---|---|---|
|
|
| 1 | `ATASAMENTE_VANZARI` | `ID_VANZARE` (FK real `FK_AT_VANZ001` -> `VANZARI.ID_VANZARE`) + coloana `COD` (legacy, vezi §2) | `ofacturare_comun.prg:466` (VFP INSERT direct), `pack_facturare.scrie_atasamente_factura` (PL/SQL, `ff_...:13955-13988`) | `VATASAMENTE_VANZARI` (view, JOIN pe `id_vanzare`), `ROAGEST`/`ROAIMOB` `oproceduri_atasamente.prg` (`citeste_atasament_vanzari`, `arata_meniu_at_vanz` — cauta pe `cod` via view) | **(A) trebuie remigrat** — vezi §2 |
|
|
| 2 | `marcheaza_facturat` -> `VANZARI.FACTURAT`/`ID_UTILFACT` | `VANZARI_CORESP.ID_VANZARE_FACT` (documentul nou) leaga la sursa | `pack_facturare.marcheaza_facturat`, apelata din `finalizeaza_factura` (`ff_...:14827,14831`) | citit la filtrarea avizelor/comenzilor facturabile | **(C) nu conteaza pentru discontinuitatea ID_VANZARE-ului documentului editat** — vezi §3 (releaga sursa, nu documentul editat insusi) |
|
|
| 3 | `VANZARI_CORESP` | `ID_VANZARE_FACT`/`ID_VANZARE_AVIZ`, ambele pe `VANZARI.ID_VANZARE` | `pack_facturare.scrie_corespondente_vanzari`, singurul writer (`s5c_factura_din_proforma.md:92-96`) | `sterge_factura` (garda la stergere), afisare "provine din X" | **(A) trebuie remigrat daca documentul editat e parte a unui lant retur/aviz->factura** — vezi §3 |
|
|
| 4 | `VANZARI_CANTITATI` | `ID_VANZARE` (a avizului sursa, nu a facturii editate) | `scrie_cantitati_vanzari_avize`, apelata doar `ntip=4` | `marcheaza_facturat(V_VERIFICARE=1)` | **(C) nu conteaza** — vezi §3, tine de sursa, neatinsa de editarea facturii |
|
|
| 5 | `DOCUMENTE` | `ID_DOC` = `ID_FACT` (nu `ID_VANZARE`) | `SET_IDFACT`/INSERT in `SCRIE_IN_ACT` | `SET_IDFACT` cautare veche (inactiva) | **(C) confirmat fara legatura cu ID_VANZARE** — vezi §4, acoperit deja de `idfact_refolosire_si_documente.md`, nu se reface |
|
|
| 6 | eFactura (`ANAF_EFACTURA`, `EsteInEFactura`) | `VANZARI.ID_FACT` (nu `ID_VANZARE`) | — | `ofacturare_editare.prg`/`omodificari.vc2` | **(C) nu conteaza** — cheia e `ID_FACT`, care se pastreaza — vezi §5 |
|
|
| 7 | Listari/rapoarte facturi (`FACT_VFACTURI*`, grid cautare) | `ID_VANZARE` + `ID_FACT`/serie+numar, cautari mixte | — | multiple | **de verificat, vezi §5** — cele care cauta dupa serie+numar/ID_FACT raman corecte; cele care tin un `ID_VANZARE` stocat undeva (ex. favorite, ultima factura deschisa) s-ar rupe |
|
|
| 8 | Incasari/plati (`INCASARI`, `PLATI`, `IREG_PARTENERI`) | **de verificat** | — | — | **in lucru, vezi §6** |
|
|
|
|
## 2. ATASAMENTE_VANZARI
|
|
|
|
**Nu sunt documente incarcate de utilizator — sunt exporturi PDF AUTO-GENERATE ale documentului
|
|
tiparit** (factura/aviz/recapitulatie/invoice), salvate automat dupa listare. Dovada, pas cu pas:
|
|
|
|
- Scrierea porneste din `frm_facturi.do_listeaza_formular`/fluxul de listare, la
|
|
`COMUN\programe\ofacturare.prg:2102-2105`:
|
|
```
|
|
If poDate.nRelistare = 0 And poDate.eProforma = 0 AND poDate.nEFactura = 0 And poDate.nSalveazaAtasamente = 1
|
|
poDate.scrieAtasamente()
|
|
Endif
|
|
```
|
|
imediat dupa exportul PDF al recapitulatiei (`:2068`, `goExport.export2pdf('crsrecapitulatie',
|
|
'recapitulatie', .F., poDate.cDocAtasate)`) — `poDate.cDocAtasate` **e** numele cursorului
|
|
`crsoDateDocAtasate`, populat de motorul de export PDF, nu de un dialog de upload.
|
|
- `crsoDateDocAtasate` se creeaza gol la `ofacturare.prg:233`: `Create Cursor crsoDateDocAtasate
|
|
(nume_frx c(50), fisier w)` — nicio referinta la `GETFILE()`/`GETPICT()`/dialog de fisier in tot
|
|
`ROAFACTURARE`/`COMUN` legata de acest cursor (cautat explicit, zero potriviri).
|
|
- `scrieAtasamente` (`ofacturare_comun.prg:429-475`) clasifica `TIP` dupa numele raportului
|
|
(`FACTURA_VAL*`->2, `FACTURA*`->1, `INVOICE*`->3, `RECAPITULATIE`->4, `AVIZ*`->5) si scrie:
|
|
`INSERT INTO ATASAMENTE_VANZARI(ID_VANZARE, TIP, FORMAT, DOCUMENT, ID_UTIL) VALUES (?pnId, ...)`
|
|
(`:466`) — `pnId = poDate.nid_vanzare` (sau `nid_vanzare_retur` pentru cazul aviz->factura). Deci
|
|
scriitorul **foloseste exclusiv `ID_VANZARE`**, niciodata `COD`.
|
|
- Cititorii confirmati: `ROAGEST\COMUN\programe\oproceduri_atasamente.prg` (identic in `ROAIMOB`) —
|
|
`citeste_atasament_vanzari` (`SELECT document FROM atasamente_vanzari WHERE id_at_vanz=...`) si
|
|
`arata_meniu_at_vanz(tnCod,...)` (`SELECT ... FROM vatasamente_vanzari a WHERE a.cod = ...`,
|
|
`:56`) — ambele read-only, mecanism de "vezi documentele salvate pentru aceasta factura",
|
|
disponibil din ROAGEST/ROAIMOB (alte produse ale suitei, confirmand ca S11 trebuia sa caute in
|
|
toata suita, nu doar ROAFACTURARE).
|
|
|
|
**Structura reala (interogata pe schema vie `MARIUSM_AUTO`)**: `ATASAMENTE_VANZARI(ID_AT_VANZ PK
|
|
NOT NULL din secventa, ID_VANZARE NUMBER NULL, DOCUMENT BLOB, TIP, FORMAT, STERS NOT NULL, ID_UTIL,
|
|
DATAORA NOT NULL, ID_UTILS, DATAORAS, COD NUMBER NULL)`. FK real: `FK_AT_VANZ001` pe `ID_VANZARE ->
|
|
VANZARI.ID_VANZARE` (`PK_VANZARI`). Coloana `COD` **nu e scrisa de niciun cod curent** (scriitorii
|
|
gasiti folosesc doar `ID_VANZARE`) — e populata azi doar de mecanismul legacy #6
|
|
(`finalizeaza_modificare_nota`'s `UPDATE atasamente_vanzari SET cod = lnCodNou WHERE cod = tnCod`,
|
|
care **nu poate seta `cod` pe un rand care nu-l are deja** — e un realiniere, nu o initializare).
|
|
Pe schema de test `MARIUSM_AUTO`, toate cele 20 de randuri existente au `COD` populat si
|
|
`ID_VANZARE` NULL (probabil date vechi, dinainte ca `ID_VANZARE` sa fie coloana activa) — cf.
|
|
memoriei de proiect, **zero cazuri in date nu e dovada**, dar dovada de cod (scriitorii folosesc
|
|
doar `ID_VANZARE`) e independenta de date si sta singura.
|
|
|
|
**Cheia reala de legatura azi e `ID_VANZARE`, prin view**: `VATASAMENTE_VANZARI` (definitie
|
|
interogata direct din `ALL_VIEWS`):
|
|
```sql
|
|
select a.id_at_vanz, a.tip, decode(a.tip,1,'Factura',2,'Factura in valuta',3,'Invoice',
|
|
4,'Recapitulatie',5,'Aviz','Alt document') as tip_doc, b.cod
|
|
from atasamente_vanzari a
|
|
left join vanzari b on a.id_vanzare = b.id_vanzare
|
|
where a.sters = 0 and b.sters = 0
|
|
```
|
|
`cod` in view **nu e coloana stocata pe `atasamente_vanzari`** — e `VANZARI.COD` curent, calculat
|
|
live prin JOIN pe `ID_VANZARE`. Consumatorii din alta suita (`ROACONT\Programe\orap_terti.prg:1854`,
|
|
`ROACONTRACTE\Programe\oparteneri_contracte.prg:190,229` — `LEFT JOIN vatasamente_vanzari ... ON
|
|
a.cod = b.cod`, pentru afisarea unui numar de atasamente pe rand de factura) folosesc de fapt tot
|
|
`ID_VANZARE`, indirect prin acest JOIN.
|
|
|
|
**Ce se rupe la regenerare (S9, calea B din §0-bis)**: `atasamente_vanzari.id_vanzare` al randurilor
|
|
vechi ramane neschimbat, aratand spre `VANZARI` cu `STERS=1` dupa stergerea documentului vechi.
|
|
`WHERE b.sters = 0` din view **filtreaza acele randuri afara** — atasamentele **dispar tacit** din
|
|
orice interogare prin `VATASAMENTE_VANZARI` (inclusiv `arata_meniu_at_vanz` din ROAGEST/ROAIMOB),
|
|
desi BLOB-ul ramane fizic in tabel. Documentul nou (`ID_VANZARE` nou) nu are niciun atasament legat.
|
|
**Clasificare: (A) trebuie remigrat** — `UPDATE atasamente_vanzari SET id_vanzare = :id_nou WHERE
|
|
id_vanzare = :id_vechi AND sters = 0`, in aceeasi tranzactie ca restul regenerarii (acelasi tipar ca
|
|
`actualizeaza_vanzari` de la #6, dar pe `id_vanzare` in loc de `cod`, si trebuie scris nou — #6 nu
|
|
acopera acest caz, cf. §0-bis).
|
|
|
|
**Corectie fata de premisa din briefing**: nu e "pierdere de date reala" in sensul de date
|
|
introduse de utilizator si irecuperabile — snapshot-ul se poate regenera prin relistare (acelasi
|
|
mecanism care l-a creat prima data). Ce s-ar pierde real e **istoricul exact al PDF-ului trimis
|
|
clientului la momentul emiterii initiale** (relevant daca factura a fost deja trimisa/tiparita
|
|
inainte de editare) — merita remigrare oricum, ca sa nu se piarda urma, dar motivatia corecta e
|
|
"pastrarea unui audit trail", nu "date introduse de utilizator".
|
|
|
|
## 3. marcheaza_facturat / VANZARI.FACTURAT / VANZARI_CANTITATI / VANZARI_CORESP
|
|
|
|
**Inventarul FK declarat pe `VANZARI.ID_VANZARE`** (interogare directa pe schema `ACN`, cea reala —
|
|
`ALL_CONS_COLUMNS`/`ALL_CONSTRAINTS`, `r_constraint_name = PK_VANZARI`), confirma si extinde lista
|
|
din briefing:
|
|
|
|
| Tabela | Coloana | Constraint |
|
|
|---|---|---|
|
|
| `ATASAMENTE_VANZARI` | `ID_VANZARE` | `FK_AT_VANZ001` |
|
|
| `VANZARI_CORESP` | `ID_VANZARE_FACT` | `FK_VANZARI_CORESP_001` |
|
|
| `VANZARI_CORESP` | `ID_VANZARE_AVIZ` | `FK_VANZARI_CORESP_002` |
|
|
| `VANZARI_CURSURI` | `ID_VANZARE` | `FK_VANZARE_CURS_002` |
|
|
| `VANZARI_DETALII` | `ID_VANZARE` | `FK_VANZARE_DET001` |
|
|
| `REST_NOTE_PLATA` | `ID_VANZARE` | `FK_REST_NOTE_PLATA_004` |
|
|
| `IPS_VOYAGES_VANZARI` | `VZ_ID` | `FK_VOYAGES_VANZARI_2` |
|
|
|
|
Primele cinci erau asteptate (vezi §1-2 si mai jos). **Ultimele doua nu erau in lista din plan** —
|
|
descoperite prin FK, nu prin cautare de text, exact motivul pentru care inventarul trebuia facut pe
|
|
schema, nu doar pe cod. Ambele sunt module de business **specifice unui singur tip de document**
|
|
(`pack_facturare.ntip`), nu cai generale:
|
|
|
|
- **`REST_NOTE_PLATA`** — modul restaurant (`PACK_RESTAURANT`, `nTipFacturaRestaurant`). La
|
|
stergerea unei vanzari de tip restaurant, `sterge_factura` cheama deja
|
|
`pack_restaurant.sterge_vanzare(V_ID_VANZARE, V_ID_UTIL)` (`ff_...:5593`, in `CASE`-ul de la
|
|
finalul procedurii) — un hook dedicat, separat de logica generala. **Nu s-a gasit un hook simetric
|
|
„re-leaga la reemitere"** in codul citit (nu era in scop sa se citeasca tot `PACK_RESTAURANT` —
|
|
pachet separat, mii de linii). Clasificare: **(A) suspecta, needs follow-up dedicat** — afecteaza
|
|
doar documentele cu `ntip = nTipFacturaRestaurant`, deci doar daca #13 include si acest tip in
|
|
„regenerabile" (de confirmat in `COMUN\docs\tipuri_documente_facturare.md`, cf. S13).
|
|
- **`IPS_VOYAGES_VANZARI`** — modul specific schemei `ACN` (`PACK_ACN`, `nTipFacturaACN`), legat de
|
|
un tabel `IPS_VOYAGES_VANZARI`/`IPS_VOYAGE_MEMBERS_VANZARI`/`IPS_VVOYAGE_MEMBERS` (confirmat in
|
|
`ris_2024_04_09_01_ACN.sql:258-266`, JOIN pe `vz.id_vanzare = vv.vz_id`) — pare o extensie de
|
|
business pentru un client specific (calatorii/voiaje), nu parte din suita generica ROA. Acelasi
|
|
tipar: `sterge_factura` cheama `pack_acn.sterge_vanzare(...)` la stergere (`ff_...:5596-5600`,
|
|
`execute immediate` conditionat de `pack_migrare.ObjectExist('PACK_ACN')` — pachetul exista doar
|
|
pe schema ACN). Clasificare: **(A) suspecta, needs follow-up dedicat** — probabil in afara
|
|
perimetrului #13 (client unic, tip de factura special), dar trebuie confirmat, nu presupus.
|
|
|
|
**`VANZARI_CURSURI`** — cursul valutar al documentului. Scris de `pack_facturare.scrie_cursuri(nid_vanzare)`
|
|
(`rec_cale_vanzari_detalii.md:102`), apelat **in interiorul aceluiasi `scrie_in_vanzari`** care
|
|
genereaza noul `ID_VANZARE` la reemitere (S9 foloseste exact acest drum, cf. §0-bis). Deci un rand
|
|
nou `VANZARI_CURSURI` se scrie automat pentru noul `ID_VANZARE`, fara nicio interventie separata.
|
|
**Clasificare: (B)** — se reface singur, ca parte a drumului normal de emitere, nimic de adaugat.
|
|
|
|
**`VANZARI_DETALII`** — liniile facturii. E miezul a ceea ce regenerarea insasi scrie (INSERT direct
|
|
pe noul `ID_VANZARE`, cf. `rec_cale_vanzari_detalii.md:105-113`) — nu e un consumator "extern" care
|
|
sa se rupa, e obiectul regenerarii. **Clasificare: (B)**, deja acoperit de proiectarea S9/S10, nu se
|
|
reface aici.
|
|
|
|
### VANZARI_CORESP — cazul netratat inca de plan: documentul editat e EL INSUSI parte a unui lant
|
|
|
|
Planul (S11, `plan_13...md:3024-3027`) trateaza `VANZARI_CORESP` ca pe o lista simpla, dar
|
|
`sterge_factura` (apelata de S9 la pasul de stergere) arata ca situatia are **doua fete diferite**,
|
|
niciuna simpla:
|
|
|
|
**(i) Garda de blocare — editarea unui document care e SURSA pentru altul e azi IMPOSIBILA, nu
|
|
riscanta.** `sterge_factura` (`ff_...:5450-5494`) verifica, INAINTE de orice stergere:
|
|
```sql
|
|
SELECT COUNT(*) INTO V_NR_FACT_RETUR FROM VANZARI_CORESP
|
|
WHERE STERS=0 AND ID_VANZARE_AVIZ = V_ID_VANZARE AND TIP = 3;
|
|
IF V_NR_FACT_RETUR > 0 THEN RAISE_APPLICATION_ERROR(-20000, 'Pentru acesta factura s-au emis facturi
|
|
de retur. Trebuie sa stergeti mai intai factura de retur!'); END IF;
|
|
```
|
|
si analog pentru `TIP IN (1,2)` (aviz cu factura/aviz de retur emise pe el) si pentru avizele-sursa
|
|
ale unei „facturi din aviz" (subquery imbricat, `:5478-5494`). **Consecinta pentru S9**: daca
|
|
utilizatorul incearca sa editeze (regenereze) o factura care are deja o factura de retur emisa
|
|
pe ea, sau un aviz care are deja o factura/aviz de retur emis pe el, **pasul de stergere din
|
|
tranzactia S9 arunca `ORA-20000`, tranzactia face rollback, documentul vechi ramane intact** — nu
|
|
e coruptie silentioasa, e un esec curat, dar e o **limitare functionala reala**: aceste documente
|
|
nu pot fi editate prin regenerare deloc, cat timp garda ramane activa (si nu exista niciun motiv
|
|
funcțional sa fie dezactivata — ar contrazice exact protectia pe care garda o ofera azi). *De
|
|
verificat de S12*: ca mesajul de eroare Oracle ajunge inteligibil la utilizator prin formularul de
|
|
editare, nu ca o eroare tehnica generica.
|
|
|
|
**(ii) Legaturile in care documentul editat e chiar `ID_VANZARE_FACT`/`ID_VANZARE_AVIZ` — marcate
|
|
`STERS=1` la stergere, NU remigrate automat, dar potential rescrise de reemitere daca parametrii
|
|
sunt refurnizati corect.** La stergerea documentului vechi, `sterge_factura` executa neconditionat
|
|
(`:5582-5585`):
|
|
```sql
|
|
UPDATE VANZARI_CORESP SET STERS = V_STERS
|
|
WHERE ID_VANZARE_FACT = V_ID_VANZARE OR ID_VANZARE_AVIZ = V_ID_VANZARE;
|
|
```
|
|
— orice legatura in care documentul vechi apare pe oricare parte devine `STERS=1`. **Nu exista cod
|
|
care sa recreeze automat legatura pentru noul `ID_VANZARE`.** Dar exista o cale prin care se
|
|
recreeaza **corect, de la sine**, daca S9 e proiectat sa refoloseasca drumul normal: `finalizeaza_factura`
|
|
(chemata de reemiterea normala) are un `CASE` pe `pack_facturare.ntip` care scrie din nou
|
|
corespondenta (`WHEN ntip=4: scrie_corespondente_vanzari(1)`; `WHEN ntip=24:
|
|
scrie_corespondente_vanzari(2)`; `WHEN ntip IN (8,9): scrie_corespondente_vanzari(3)`,
|
|
`ff_...:14823-14836`) — **daca** S9 seteaza `pack_facturare.ntip` la aceeasi valoare ca documentul
|
|
original SI re-populeaza `pack_facturare.clistaid`/`clistaid_avize` cu lista de `id_vanzare` sursa
|
|
originala **inainte** de reemitere, corespondenta se scrie natural, cu noul `ID_VANZARE_FACT`.
|
|
**Sursa lista originala e recuperabila** din randurile `VANZARI_CORESP` (acum `STERS=1`) ale
|
|
documentului vechi, citite INAINTE de stergere in aceeasi tranzactie — un pas suplimentar pe care
|
|
proiectarea S9 trebuie sa-l includa explicit, nu e „gratis". **Clasificare: (A) trebuie remigrat
|
|
— dar prin re-derivare + refolosirea mecanismului existent, nu prin UPDATE direct pe `VANZARI_CORESP`**
|
|
(un UPDATE direct ar trebui sa distinga cu grija cele doua roluri — FACT vs AVIZ — si ar risca sa
|
|
resusciteze legaturi catre documente inca sterse din alte motive; re-emiterea naturala prin `ntip`+
|
|
`clistaid` e mai sigura, pentru ca refoloseste exact logica deja validata de emiterea normala).
|
|
|
|
### marcheaza_facturat — pentru sursa documentului editat, nu pentru documentul insusi
|
|
|
|
`marcheaza_facturat` (`ff_...:15381-15418`) actioneaza pe **sursa** (avizul din care s-a facturat,
|
|
sau avizul-parinte al unui aviz de retur), nu pe documentul care se editeaza. La stergerea
|
|
documentului vechi (S9, pasul de stergere), pentru `V_TIP=4`/`V_TIP=24`, `sterge_factura` reseteaza
|
|
deja `FACTURAT=0`/`ID_UTILFACT=NULL` pe sursa (`:5504-5510`, `:5525-5533`) si marcheaza
|
|
`VANZARI_CANTITATI.STERS=1` pentru cantitatile consumate (`:5517-5523`, `:5535-5540`) — sursa e deci
|
|
**eliberata** corect de mecanismul EXISTENT, neschimbat. La reemitere, daca `ntip`/`clistaid_avize`
|
|
sunt refurnizate corect (acelasi argument ca la VANZARI_CORESP mai sus), `finalizeaza_factura`
|
|
cheama din nou `scrie_cantitati_vanzari_avize` + `marcheaza_facturat` (`:14825-14827`,`:14831`),
|
|
**reconsumand** sursa sub noul `ID_VANZARE_FACT`. **Clasificare: (C) — mecanismul deja exista si
|
|
functioneaza simetric (elibereaza la stergere, reconsuma la scriere), CONDITIONAT de aceeasi
|
|
cerinta ca la VANZARI_CORESP: S9 trebuie sa refurnizeze `ntip` si `clistaid`/`clistaid_avize`
|
|
originale la reemitere.** Aceasta e exact conditia pe care S12 o testeaza explicit („sursa eliberata
|
|
si reconsumata", `plan_13...md:3037`) — S11 confirma DE CE mecanismul poate functiona (nu e nevoie
|
|
de cod nou pentru asta), dar nu inlocuieste testul S12.
|
|
|
|
## 4. DOCUMENTE / ID_DOC — legatura cu ID_VANZARE
|
|
|
|
**Confirmat: fara legatura.** `DOCUMENTE(ID_DOC, ID_UTIL, DATAORA, TVA_INCASARE, SERIE_ACT, NRACT,
|
|
DATAACT, DATAIREG, ID_CTR, ID_SET, STERS, ...)` — INSERT-ul complet citat in
|
|
`idfact_refolosire_si_documente.md:143-148` (`PACK_CONTAFIN.pck:788-817`, cod activ) nu are nicio
|
|
coloana `ID_VANZARE`. Cheia `ID_DOC = ID_FACT`, care se PASTREAZA la regenerare (decizie E/F, deja
|
|
data). Acest raport nu reface analiza — deja acoperita exhaustiv de
|
|
`docs\cercetare\idfact_refolosire_si_documente.md` (S9, punctele A-C), care stabileste separat
|
|
conditiile pentru pastrarea `ID_FACT` (variabila noua de sesiune in `SET_IDFACT` + upsert real in
|
|
`DOCUMENTE`). **Clasificare: (C) — confirmat, fara actiune ceruta de S11.**
|
|
|
|
## 5. Borderou eFactura si listari
|
|
|
|
**eFactura: cheia e `ID_FACT`, nu `ID_VANZARE` — confirmat cu dovada proprie, independenta.**
|
|
`EsteInEFactura` (`COMUN\programe\ofacturare_editare.prg`, apelata din `ofacturare_comun.vc2:3764`
|
|
cu `lnIdFact = crsfacturi.id_fact`) verifica prezenta documentului in `ANAF_EFACTURA` **pe
|
|
`VANZARI.ID_FACT`**, nu pe `id_vanzare` — confirmat explicit ca eroare corectata in
|
|
`rec_d42_efactura.md:81-109` (implementarea initiala folosea gresit `id_vanzare`, corectata dupa
|
|
verificare pe date: `id_fact` si `id_vanzare` sunt spatii de ID complet diferite, 0 coincidente pe
|
|
142 facturi testate). **Cum `ID_FACT` se pastreaza la regenerare (decizie deja luata), `EsteInEFactura`
|
|
continua sa functioneze corect pe documentul reemis, fara nicio schimbare.** Aceeasi concluzie se
|
|
aplica probabil borderoului eFactura insusi (cautarea documentelor de trimis/trimise), dar
|
|
**construirea borderoului nu a fost citita in acest raport** (in afara scopului — cheia `ID_FACT`
|
|
fiind deja confirmata stabila, riscul e mic, dar afirmatia stricta „borderoul il gaseste corect"
|
|
ramane de verificat direct pe cod la implementare, nu doar dedusa). **Clasificare: (C), cu rezerva
|
|
de verificare directa a borderoului la implementare.**
|
|
|
|
**Listari/grid cautare facturi**: cursoarele de grid (`crsFacturi`, `crsFacturiOrd`,
|
|
`ofacturare_comun.vc2:3982,4134-4145,4983`) se reconstruiesc live din Oracle la fiecare deschidere
|
|
a formularului de listare, filtrate pe `sters=0` — nu tin niciun `id_vanzare` persistat intre
|
|
sesiuni. Documentul reemis (nou `id_vanzare`, acelasi `id_fact`/serie/numar) apare normal la
|
|
urmatoarea reincarcare a gridului. **Singurul risc identificat, nu confirmat ca problema reala**:
|
|
daca undeva in cod exista un `id_vanzare` **retinut pe termen lung** in afara sesiunii curente a
|
|
formularului (ex. „ultima factura deschisa", favorite, shortcut) — nu s-a gasit niciun asemenea
|
|
mecanism in codul citit (`ofacturare_comun.vc2`, `ofacturare.prg`), dar nici nu a fost cautat
|
|
exhaustiv in tot `ROAFACTURARE` (in afara bugetului acestei cercetari). **Clasificare: (C),
|
|
neconfirmat ca risc real — verificare suplimentara recomandata daca timpul permite.**
|
|
|
|
## 6. Incasari/plati si riscuri finale
|
|
|
|
**Cautare directa (negativa, dar utila): niciun tabel de incasari/plati nu are FK declarat pe
|
|
`VANZARI.ID_VANZARE`.** Interogarea exhaustiva `ALL_CONS_COLUMNS`/`ALL_CONSTRAINTS` pe schema `ACN`
|
|
(tabelul din §3) e completa pentru FK-uri declarate — `INCASARI`, `PLATI`, `IREG_PARTENERI` nu apar
|
|
in acea lista. Cautare text suplimentara (`grep -rn "ID_VANZARE"` filtrat pe fisiere cu
|
|
"incasari"/"plati"/"chitant" in nume, in tot `D:\ROA\DATABASE\SCRIPTURI_CLAR`) — **zero rezultate**.
|
|
Coerent cu arhitectura deja cunoscuta: incasarile/platile se leaga de facturi prin **`ID_FACT`**
|
|
(coloana pe `ACT`/`IREG_PARTENERI`, cf. `idfact_refolosire_si_documente.md`), nu prin `ID_VANZARE`
|
|
— `ID_FACT` se pastreaza la regenerare, deci **incasarile/platile nu sunt afectate structural**.
|
|
**Clasificare: (C), cu dovada dubla (schema + text), coerenta cu memoria de proiect „zero cazuri in
|
|
date nu e dovada" — aici insa e absenta de FK + absenta de text, nu absenta de date, deci e o
|
|
dovada structurala, nu doar un data point.**
|
|
|
|
## Rezumat clasificari
|
|
|
|
| Consumator | Clasificare | Actiune ceruta |
|
|
|---|---|---|
|
|
| `ATASAMENTE_VANZARI.ID_VANZARE` | **(A)** | `UPDATE ... SET id_vanzare=:nou WHERE id_vanzare=:vechi AND sters=0`, in tranzactia S9 |
|
|
| `VANZARI_CORESP` (documentul editat ca FACT/AVIZ al altui lant) | **(A)**, prin re-emitere naturala | S9 trebuie sa citeasca `ntip`+lista sursa originala INAINTE de stergere si sa le refurnizeze la reemitere |
|
|
| `marcheaza_facturat`/`VANZARI_CANTITATI` (sursa documentului editat) | **(C)**, conditionat | functioneaza automat DACA `ntip`/`clistaid` sunt refurnizate (acelasi mecanism ca mai sus) |
|
|
| `VANZARI_CURSURI` | **(B)** | se rescrie automat de `scrie_in_vanzari`, nimic de facut |
|
|
| `VANZARI_DETALII` | **(B)** | e obiectul regenerarii, acoperit de S9/S10 |
|
|
| `DOCUMENTE`/`ID_DOC` | **(C)** | confirmat fara legatura, acoperit de `idfact_refolosire_si_documente.md` |
|
|
| eFactura (`EsteInEFactura`, `ANAF_EFACTURA`) | **(C)** | cheie `ID_FACT`, pastrat — verificare directa a borderoului recomandata la implementare |
|
|
| Listari/grid facturi | **(C)** | cursoare live, fara stare persistata gasita |
|
|
| Incasari/plati | **(C)** | fara FK, fara referinta text — cheie e `ID_FACT` |
|
|
| `REST_NOTE_PLATA` (modul restaurant) | **(A)** suspecta | needs follow-up dedicat, `PACK_RESTAURANT` necitit integral |
|
|
| `IPS_VOYAGES_VANZARI` (modul ACN specific client) | **(A)** suspecta | needs follow-up dedicat, `PACK_ACN` necitit integral, posibil in afara perimetrului #13 |
|
|
|
|
## Riscuri si ce ramane de decis de Marius
|
|
|
|
1. **Editarea documentelor care sunt sursa unui lant retur/aviz e azi BLOCATA, nu doar riscanta.**
|
|
`sterge_factura` arunca `ORA-20000` daca documentul editat are deja facturi/avize de retur emise
|
|
pe el (§3.i). Nu e o eroare de proiectare — garda protejeaza integritatea lantului — dar
|
|
inseamna ca „editare prin regenerare" **nu va functiona deloc** pentru aceste documente, cat timp
|
|
utilizatorul nu sterge intai documentele-copil. **De decis**: acceptat ca limitare (cu mesaj
|
|
clar in UI, tradus din eroarea Oracle), sau se doreste alt comportament?
|
|
2. **Recuperarea `VANZARI_CORESP`/`marcheaza_facturat` la reemitere depinde de un pas pe care planul
|
|
nu-l mentioneaza explicit**: citirea listei sursa originale (`ID_VANZARE_AVIZ`/`ID_VANZARE_FACT`
|
|
din randurile `VANZARI_CORESP` ale documentului vechi) **inainte** de stergere, si refurnizarea
|
|
ei ca `pack_facturare.clistaid`/`clistaid_avize` la reemitere. Fara acest pas, corespondenta si
|
|
`marcheaza_facturat` **nu se scriu deloc** pentru documentul reemis (nu eroare, ci scriere lipsa
|
|
silentioasa) — de adaugat explicit in proiectarea S9, nu presupus „vine gratis" din drumul normal.
|
|
3. **`ATASAMENTE_VANZARI` nu e „date de utilizator pierdute"**, cf. §2 — e un audit trail de
|
|
PDF-uri auto-generate la listare. Remigrarea (`UPDATE ... SET id_vanzare`) e simpla si ieftina,
|
|
dar motivatia corecta pentru Marius e „pastrarea istoricului tiparit", nu „pierdere de date
|
|
introduse manual" — poate schimba prioritatea relativa fata de alte itemi din S11/S12.
|
|
4. **`REST_NOTE_PLATA` si `IPS_VOYAGES_VANZARI`** raman needs-investigation — descoperite prin FK,
|
|
nu prin text, deci nu erau in raza cautarilor anterioare (nici in planul S11 original). Daca
|
|
tipurile de document asociate (`nTipFacturaRestaurant`, `nTipFacturaACN`) nu sunt in domeniul
|
|
„regenerabile" al #13 (de confirmat in `tipuri_documente_facturare.md`, S13), riscul dispare de
|
|
la sine — dar asta trebuie confirmat, nu presupus.
|
|
5. **Borderoul eFactura insusi** (nu doar `EsteInEFactura`) nu a fost citit direct — cheia `ID_FACT`
|
|
fiind stabila, riscul e mic, dar afirmatia din *Gata cand* a S11 („documentul reemis se regaseste
|
|
corect in borderoul eFactura") merita o verificare punctuala pe cod la implementare, nu doar
|
|
dedusa din `EsteInEFactura`.
|
|
|
|
## STARE / CE RAMANE
|
|
|
|
**Cercetare incheiata pentru toate cele 7 puncte cerute de briefing**, cu dovada `fisier:linie` pe
|
|
fiecare afirmatie portanta: inventar exhaustiv (via FK Oracle + cod), `ATASAMENTE_VANZARI` (sectiune
|
|
proprie, cu corectia premisei „date de utilizator"), `marcheaza_facturat`/`VANZARI.FACTURAT`/
|
|
`VANZARI_CANTITATI`, `DOCUMENTE`/`ID_DOC` (confirmat, fara redeschidere), borderou eFactura si
|
|
listari, riscuri finale.
|
|
|
|
**Constatare centrala**: mecanismul S9 planificat (regenerare cu `ID_VANZARE` nou, pe drumul normal
|
|
de emitere) e **diferit** de mecanismul #6 deja livrat (`actualizeaza_vanzari`, reutilizeaza acelasi
|
|
`ID_VANZARE`, doar `COD` se schimba) — deci nicio protectie construita pentru #6 nu se mosteneste
|
|
automat de S9. Singurul consumator care chiar are nevoie de un `UPDATE` explicit nou este
|
|
`ATASAMENTE_VANZARI` (clasificare A simpla). `VANZARI_CORESP`/`marcheaza_facturat` se pot rezolva
|
|
**fara cod PL/SQL nou**, refolosind mecanismul existent (`finalizeaza_factura`'s `CASE` pe `ntip`),
|
|
**daca** S9 e proiectat sa citeasca si sa refurnizeze parametrii sursei originale — asta e o cerinta
|
|
de design care trebuie scrisa explicit in S9, nu deductibila implicit.
|
|
|
|
**Neverificat, ramas pentru follow-up** (declarat, nu ascuns): corpul complet al `PACK_RESTAURANT`/
|
|
`PACK_ACN` (pentru `REST_NOTE_PLATA`/`IPS_VOYAGES_VANZARI`), borderoul eFactura citit direct (nu doar
|
|
`EsteInEFactura`), o cautare exhaustiva de „id_vanzare retinut pe termen lung" in tot codul VFP
|
|
(favorite/shortcut-uri), si confirmarea in `tipuri_documente_facturare.md` a caror tipuri intra
|
|
efectiv in perimetrul „regenerabile" al #13 (ar elimina sau confirma riscurile 1 si 4).
|
|
|
|
Zero modificari de cod, zero write-back, zero `git_sync.ps1`/`txt2vcx.ps1`, zero commit. Pe Oracle
|
|
doar `SELECT` (schema `MARIUSM_AUTO`, interogari pe `ALL_TAB_COLUMNS`/`ALL_CONSTRAINTS`/`ALL_VIEWS`/
|
|
`ALL_SOURCE`, plus `SELECT` de numarare pe date de test — niciuna cu efect de scriere).
|