#6 editare factura emisa: S5 - scrierea sumelor editate in Oracle
La salvarea unei facturi deja emise, modificarile facute liniilor de articole se scriu acum real in VANZARI_DETALII, in aceeasi tranzactie cu restul salvarii, si totalurile documentului se recalculeaza din liniile efectiv salvate. - ofacturare_editare.prg: helper nou ScrieArticoleFacturaEditate. Idiomul e "marcheaza tot sters, invie ce ramane", nu delta, pentru ca actualizeaza_vanzari face UPDATE ... SET STERS = 0 pe tot documentul, fara garda; o scriere delta ar lasa liniile sterse sa reinvie la fiecare salvare. Cursor gol = no-op, ca o eroare la incarcare sa nu goleasca factura. - comun.vc2, ofacturare_comun.vc2: agatarea apelului dupa finalizeaza_modificare_nota si inainte de inchiderea tranzactiei, in ambele puncte de intrare. - omodificari.vc2: coloana Pret achizitie in grid, editabila doar pe liniile noi; liniile de set devin needitabile, cu marcaj; cinci validari la salvare. - teste: cinci suite noi (validari, grid UI, scriere reala, discount/valuta, rollback, al doilea punct de intrare) si asteptari actualizate in test_page3_articole. - docs: oracle_export.md - exportul all_source cere linesize 32767, altfel rupe liniile lungi prin mijlocul identificatorilor; scripturi-migrare-db.md - UpdateVersiune adauga singur extensia .sql. Cere scripturile ff_2026_08_09_01 (PACK_FACTURARE) si ff_2026_08_09_02 (VVANZARI_ARTICOLE). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SN8snvkk94KuhWwoXUUey3
This commit is contained in:
@@ -4,10 +4,11 @@
|
||||
*!* marius.mutu
|
||||
*!* helpere comune pentru editarea unei facturi emise: garda eFactura, cursoarele notei si ale rulajelor,
|
||||
*!* randul de vanzare corespunzator notei (inclusiv valuta documentului: in_valuta/id_valuta/nume_val),
|
||||
*!* liniile de articole pentru pagina de articole factura (inclusiv in_stoc, pentru corectia verdictului
|
||||
*!* RUL pe liniile nestocate), pregatirea cursorului de articole inainte de Createobject(frm_modific2024)
|
||||
*!* si construirea obiectului poArticol pentru adaugarea unei linii noi prin dialogul frm_articol_factura,
|
||||
*!* populat cu valuta documentului cand acesta e in valuta
|
||||
*!* liniile de articole pentru pagina de articole factura (inclusiv in_stoc si id_vanzare_set/pret_achizitie,
|
||||
*!* pentru corectia verdictului RUL pe liniile nestocate si pentru liniile din seturi), pregatirea
|
||||
*!* cursorului de articole inainte de Createobject(frm_modific2024), construirea obiectului poArticol
|
||||
*!* pentru adaugarea unei linii noi prin dialogul frm_articol_factura (populat cu valuta documentului
|
||||
*!* cand acesta e in valuta) si scrierea in VANZARI_DETALII a liniilor editate/adaugate/sterse
|
||||
|
||||
|
||||
*!* parametru: id_fact
|
||||
@@ -271,7 +272,7 @@ FUNCTION CreeazaCursorArticoleGol
|
||||
ENDIF
|
||||
CREATE CURSOR (m.lcAlias) (id_vanzare I NULL, id_vanzare_det I NULL, id_articol I NULL, cantitate N(12,3) NULL, pret N(14,4) NULL, pret_cu_tva N(14,4) NULL, proc_tvav N(6,4) NULL, ;
|
||||
discount_unitar N(14,4) NULL, id_gestiune I NULL, cont C(20) NULL, id_valuta I NULL, id_jtva_coloana I NULL, serie C(20) NULL, explicatie C(60) NULL, ;
|
||||
taxcode I NULL, lot C(20) NULL, sters I NULL, denumire C(100) NULL, codmat C(30) NULL, nume_gestiune C(60) NULL, nume_val C(20) NULL, ;
|
||||
taxcode I NULL, lot C(20) NULL, sters I NULL, id_vanzare_set I NULL, pret_achizitie N(14,4) NULL, denumire C(100) NULL, codmat C(30) NULL, nume_gestiune C(60) NULL, nume_val C(20) NULL, ;
|
||||
lmodificat L, valoare N(14,2), in_stoc I NULL)
|
||||
ENDFUNC && CreeazaCursorArticoleGol
|
||||
|
||||
@@ -455,3 +456,100 @@ FUNCTION CreeazaPoArticolNouTvd
|
||||
|
||||
RETURN loArticol
|
||||
ENDFUNC && CreeazaPoArticolNouTvd
|
||||
|
||||
|
||||
*!* parametri: id_vanzare (din tvanz.id_vanzare), alias articole (implicit tvd), alias vanzare (implicit tvanz)
|
||||
*!* scrie in VANZARI_DETALII liniile editate ale notei, ca diferenta fata de starea persistata: marcheaza
|
||||
*!* sters tot documentul, invie/actualizeaza liniile pastrate din alias, insereaza liniile noi, apoi
|
||||
*!* recalculeaza totalurile documentului (cu discountul din alias vanzare, ca sa nu poata diverge de
|
||||
*!* liniile scrise); ruleaza in tranzactia manuala deja deschisa de apelant, dupa finalizeaza_modificare_nota
|
||||
*!* - nu da COMMIT/ROLLBACK, nu inchide cursoare, salveaza si restaureaza workarea/pozitia curenta
|
||||
*!* retur logic: .T. daca a mers tot sau nu era nimic de facut, .F. la primul esec Oracle (se opreste acolo)
|
||||
FUNCTION ScrieArticoleFacturaEditate
|
||||
LPARAMETERS tnIdVanzare, tcAliasArticole, tcAliasVanzare
|
||||
|
||||
LOCAL lcAliasArt, lcAliasVanz, lnAreaOrigine, lnRecnoArt, llSucces, lcSql, lnDiscount, llDiscountNul
|
||||
lcAliasArt = IIF(Type('tcAliasArticole') = 'C' AND !Empty(m.tcAliasArticole), m.tcAliasArticole, 'tvd')
|
||||
lcAliasVanz = IIF(Type('tcAliasVanzare') = 'C' AND !Empty(m.tcAliasVanzare), m.tcAliasVanzare, 'tvanz')
|
||||
|
||||
*!* cursor gol de articole nu inseamna "document fara linii" - poate fi si un esec de incarcare (IncarcaArticoleFactura intoarce .T. cu cursor gol la eroare Oracle); fara ancora, ar goli tacut factura
|
||||
IF Nvl(m.tnIdVanzare,0) <= 0 OR !Used(m.lcAliasArt) OR !Used(m.lcAliasVanz) OR Reccount(m.lcAliasVanz) <> 1 OR Reccount(m.lcAliasArt) = 0
|
||||
RETURN .T.
|
||||
ENDIF
|
||||
|
||||
lnAreaOrigine = Select()
|
||||
llSucces = .T.
|
||||
|
||||
SELECT (m.lcAliasVanz)
|
||||
GO TOP
|
||||
llDiscountNul = Isnull(discount)
|
||||
lnDiscount = Nvl(discount,0)
|
||||
|
||||
*!* marcheaza sters tot documentul - perechea reset-ului STERS=0 din actualizeaza_vanzari
|
||||
lcSql = [update vanzari_detalii set sters = 1, id_utils = ] + Alltrim(Str(gnIdUtil)) + [, dataoras = sysdate ] + ;
|
||||
[where id_vanzare = ] + Alltrim(Str(m.tnIdVanzare)) + [ and sters = 0]
|
||||
llSucces = goExecutor.oExecuta(m.lcSql)
|
||||
|
||||
*!* invie si actualizeaza liniile pastrate - toate cele active din alias, nu doar lmodificat, pasul de mai sus le-a marcat pe toate
|
||||
IF m.llSucces
|
||||
SELECT (m.lcAliasArt)
|
||||
lnRecnoArt = Recno()
|
||||
SCAN FOR id_vanzare_det > 0 AND Nvl(sters,0) <> 1
|
||||
lcSql = [update vanzari_detalii set sters = 0, cantitate = ] + Alltrim(Str(Nvl(cantitate,0),18,3)) + ;
|
||||
[, pret = ] + Alltrim(Str(Nvl(pret,0),18,4)) + [, pret_cu_tva = ] + Alltrim(Str(Nvl(pret_cu_tva,0))) + ;
|
||||
[, id_utils = ] + Alltrim(Str(gnIdUtil)) + [, dataoras = sysdate ] + ;
|
||||
[where id_vanzare_det = ] + Alltrim(Str(id_vanzare_det)) + [ and id_vanzare = ] + Alltrim(Str(m.tnIdVanzare))
|
||||
llSucces = goExecutor.oExecuta(m.lcSql)
|
||||
IF !m.llSucces
|
||||
EXIT
|
||||
ENDIF
|
||||
ENDSCAN
|
||||
TRY
|
||||
GO m.lnRecnoArt IN (m.lcAliasArt)
|
||||
CATCH
|
||||
GO TOP IN (m.lcAliasArt)
|
||||
ENDTRY
|
||||
ENDIF
|
||||
|
||||
*!* insereaza liniile noi - fara id_vanzare_det, il genereaza trigger-ul TRG_VANZARI_DET_BEFOINS
|
||||
IF m.llSucces
|
||||
SELECT (m.lcAliasArt)
|
||||
lnRecnoArt = Recno()
|
||||
SCAN FOR id_vanzare_det = 0 AND Nvl(sters,0) <> 1
|
||||
lcSql = [insert into vanzari_detalii (id_vanzare, id_articol, cantitate, pret, pret_cu_tva, proc_tvav, discount_unitar, ] + ;
|
||||
[id_gestiune, cont, id_valuta, id_jtva_coloana, serie, explicatie, taxcode, lot, pret_achizitie, id_utils, dataoras) values (] + ;
|
||||
Alltrim(Str(m.tnIdVanzare)) + [,] + Alltrim(Str(Nvl(id_articol,0))) + [,] + Alltrim(Str(Nvl(cantitate,0),18,3)) + [,] + ;
|
||||
Alltrim(Str(Nvl(pret,0),18,4)) + [,] + Alltrim(Str(Nvl(pret_cu_tva,0))) + [,] + Alltrim(Str(Nvl(proc_tvav,0),18,4)) + [,] + ;
|
||||
Alltrim(Str(Nvl(discount_unitar,0),18,4)) + [,] + Iif(Isnull(id_gestiune),[NULL],Alltrim(Str(id_gestiune))) + [,] + ;
|
||||
Iif(Empty(Nvl(cont,'')),[NULL],['] + OracleSpecialCharacters(Alltrim(Nvl(cont,''))) + [']) + [,] + ;
|
||||
Iif(Isnull(id_valuta),[NULL],Alltrim(Str(id_valuta))) + [,] + Iif(Isnull(id_jtva_coloana),[NULL],Alltrim(Str(id_jtva_coloana))) + [,] + ;
|
||||
Iif(Empty(Nvl(serie,'')),[NULL],['] + OracleSpecialCharacters(Alltrim(Nvl(serie,''))) + [']) + [,] + ;
|
||||
Iif(Empty(Nvl(explicatie,'')),[NULL],['] + OracleSpecialCharacters(Alltrim(Nvl(explicatie,''))) + [']) + [,] + ;
|
||||
Iif(Isnull(taxcode),[NULL],Alltrim(Str(taxcode))) + [,] + ;
|
||||
Iif(Empty(Nvl(lot,'')),[NULL],['] + OracleSpecialCharacters(Alltrim(Nvl(lot,''))) + [']) + [,] + ;
|
||||
Alltrim(Str(Nvl(pret_achizitie,0),18,4)) + [,] + Alltrim(Str(gnIdUtil)) + [, sysdate)]
|
||||
llSucces = goExecutor.oExecuta(m.lcSql)
|
||||
IF !m.llSucces
|
||||
EXIT
|
||||
ENDIF
|
||||
ENDSCAN
|
||||
TRY
|
||||
GO m.lnRecnoArt IN (m.lcAliasArt)
|
||||
CATCH
|
||||
GO TOP IN (m.lcAliasArt)
|
||||
ENDTRY
|
||||
ENDIF
|
||||
|
||||
*!* recalculul totalurilor, cu discountul documentului dat ca parametru - .NULL. pastreaza discountul curent
|
||||
IF m.llSucces
|
||||
lcSql = [begin pack_facturare.recalculeaza_totaluri_vanzari(] + Alltrim(Str(m.tnIdVanzare)) + [,] + ;
|
||||
Iif(m.llDiscountNul,[NULL],Alltrim(Str(m.lnDiscount,18,4))) + [); end;]
|
||||
llSucces = goExecutor.oExecuta(m.lcSql)
|
||||
ENDIF
|
||||
|
||||
IF m.lnAreaOrigine > 0
|
||||
SELECT (m.lnAreaOrigine)
|
||||
ENDIF
|
||||
|
||||
RETURN m.llSucces
|
||||
ENDFUNC && ScrieArticoleFacturaEditate
|
||||
|
||||
Reference in New Issue
Block a user