*** ofacturare_editare *!* 11.08.2026 *!* 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, *!* si id_fact - pentru garda eFactura pe pagina de articole), *!* 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), scrierea in VANZARI_DETALII a liniilor editate/adaugate/sterse, si *!* compararea/aplicarea sincronizarii cantitate/pret intre rulaje (trul) si articolele facturii (tvd), *!* agregate pe id_articol, in ambele sensuri (documentele in valuta raman doar semnalate, neaplicate); *!* pe linia de articol se poate alege si explicatia TVA (filtrata pe cota liniei), care recoreleaza *!* codul SAF-T, iar liniile deja salvate se actualizeaza cu toate campurile pe care grila le schimba *!* parametru: id_fact *!* verifica daca factura cu id_fact dat a fost deja trimisa in eFactura (anaf_efactura) FUNCTION EsteInEFactura LPARAMETERS tnIdFact LOCAL lcSql, lnEFactura, llSucces lnEFactura = 0 lcSql = [select count(*) as lneFactura from anaf_efactura where id_fact = ] + Alltrim(Str(Nvl(m.tnIdFact,0))) llSucces = goExecutor.oSelecteaza2Value(m.lcSql, @lnEFactura) RETURN (Nvl(m.lnEFactura,0) > 0) ENDFUNC && EsteInEFactura *!* parametri: cod, an, luna, arata si randurile sterse (implicit .F.) *!* incarca cursoarele notei (tact) si ale rulajelor (trul, trul_obinv), cu recalculul de *!* valoare/valtva/valoarev/valtvav pe randurile goale; raman deschise READWRITE pe seama apelantului *!* pe eroare Oracle intoarce .F. si inchide ce a deschis pana atunci FUNCTION IncarcaCursoareModificareNota LPARAMETERS tnCod, tnAn, tnLuna, tlAratasterse LOCAL lcConditieSters, lcSql, lcCursor, lnSucces IF Used('actactan') Use In actactan ENDIF IF Used('tact') Use In tact ENDIF IF Used('rul_temp') Use In rul_temp ENDIF IF Used('trul') Use In trul ENDIF IF Used('rul_temp_obinv') Use In rul_temp_obinv ENDIF IF Used('trul_obinv') Use In trul_obinv ENDIF lcConditieSters = IIF(m.tlAratasterse, [ ], [ STERS = 0 AND ]) lcSql = [select * from vact_tot where ] + lcConditieSters + [ an = ] + Transform(m.tnAn) + [ and luna = ] + Transform(m.tnLuna) + [ and cod = ] + Alltrim(Str(m.tnCod)) + [ order by id_act] lcCursor = [v_act] lnSucces = goExecutor.oExecute(lcSql,lcCursor) goExecutor.oReset() IF lnSucces < 0 AMESSAGEBOX(goExecutor.cEroare,0+16,"Eroare") RETURN .F. ENDIF SELECT * FROM v_act INTO CURSOR actactan SELECT .F. AS ales, T.*, CAST(0 AS N(2)) AS tipnota FROM actactan T INTO CURSOR tact READWRITE USE IN v_act IF lnSucces > 0 lcSql = [select * from vrul_tot where ] + lcConditieSters + [ an = ] + Transform(m.tnAn) + [ and luna = ] + Transform(m.tnLuna) + [ and cod = ] + Alltrim(Str(m.tnCod)) + [ order by id_rul] lcCursor = [v_rul] lnSucces = goExecutor.oExecute(lcSql,lcCursor) goExecutor.oReset() IF lnSucces < 0 AMESSAGEBOX(goExecutor.cEroare,0+16,"Eroare") IF Used('actactan') Use In actactan ENDIF IF Used('tact') Use In tact ENDIF RETURN .F. ENDIF IF lnSucces > 0 UPDATE v_rul SET valoare = ROUND(IIF(cant<>0, cant, cante)*pret,m.gnPC) WHERE EMPTY(NVL(valoare,0)) UPDATE v_rul SET valtva = ROUND(IIF(cant<>0, cant, cante)*pret * (IIF(!EMPTY(NVL(proc_tva,0)), proc_tva, 1)-1), m.gnPC) WHERE EMPTY(NVL(valtva,0)) UPDATE v_rul SET valoarev = ROUND(IIF(cant<>0, cant, cante)*pretv,m.gnPC) WHERE EMPTY(NVL(valoarev,0)) UPDATE v_rul SET valtvav = ROUND(IIF(cant<>0, cant, cante)*pretv * (IIF(!EMPTY(NVL(proc_tvav,0)), proc_tvav, 1)-1), m.gnPC) WHERE EMPTY(NVL(valtvav,0)) SELECT *, ; valoare + valtva AS valoarectva, ; valoarev + valtvav AS valoarevctva ; FROM v_rul ; INTO CURSOR RUL_TEMP READWRITE SELECT * FROM RUL_TEMP INTO CURSOR trul READWRITE USE IN v_rul lcSql = [select * from vrul_obinv_tot where ] + lcConditieSters + [ an = ] + Transform(m.tnAn) + [ and luna = ] + Transform(m.tnLuna) + [ and cod = ] + Alltrim(Str(m.tnCod)) + [ order by id_rul_obinv] lcCursor = [v_rul_obinv] lnSucces = goExecutor.oExecute(lcSql,lcCursor) goExecutor.oReset() IF lnSucces < 0 AMESSAGEBOX(goExecutor.cEroare,0+16,"Eroare") IF Used('actactan') Use In actactan ENDIF IF Used('tact') Use In tact ENDIF IF Used('rul_temp') Use In rul_temp ENDIF IF Used('trul') Use In trul ENDIF RETURN .F. ENDIF ENDIF IF lnSucces > 0 UPDATE v_rul_obinv SET valoare = ROUND(IIF(cant<>0, cant, cante)*pret,m.gnPC) WHERE EMPTY(NVL(valoare,0)) UPDATE v_rul_obinv SET valtva = ROUND(IIF(cant<>0, cant, cante)*pret * (IIF(!EMPTY(NVL(proc_tva,0)), proc_tva, 1)-1), m.gnPC) WHERE EMPTY(NVL(valtva,0)) UPDATE v_rul_obinv SET valoarev = ROUND(IIF(cant<>0, cant, cante)*pretv,m.gnPC) WHERE EMPTY(NVL(valoarev,0)) UPDATE v_rul_obinv SET valtvav = ROUND(IIF(cant<>0, cant, cante)*pretv * (IIF(!EMPTY(NVL(proc_tvav,0)), proc_tvav, 1)-1), m.gnPC) WHERE EMPTY(NVL(valtvav,0)) SELECT *, ; valoare + valtva AS valoarectva, ; valoarev + valtvav AS valoarevctva ; FROM v_rul_obinv ; INTO CURSOR RUL_TEMP_OBINV READWRITE SELECT * FROM RUL_TEMP_OBINV INTO CURSOR trul_obinv READWRITE USE IN v_rul_obinv ENDIF ENDIF RETURN .T. ENDFUNC && IncarcaCursoareModificareNota *!* creeaza cursorul tvanz gol (structura VANZARI redusa) - fallback la eroare Oracle sau cod/data lipsa FUNCTION CreeazaCursorTvanzGol IF Used('tvanz') Use In tvanz ENDIF CREATE CURSOR tvanz (id_vanzare I, tip I, discount N(12,2), total_fara_tva N(14,2), total_tva N(14,2), total_cu_tva N(14,2), curs N(10,4), multiplicator N(10,4), ; in_valuta I NULL, id_valuta I NULL, nume_val C(20) NULL, id_fact I NULL) ENDFUNC && CreeazaCursorTvanzGol *!* parametri: cod, nract, serie_act, dataact (din cursorul notei, ex. tact) *!* incarca in tvanz randul din VANZARI al notei; cod singur nu e unic, de aceea filtrul cere tot setul *!* tvanz ramane deschis READWRITE, cu 0 randuri daca nu s-a gasit sau la eroare Oracle FUNCTION IncarcaVanzareNota LPARAMETERS tnCod, tnNract, tcSerieAct, tdDataAct LOCAL lcSql, lnSucces, lcSerieAct IF Used('v_vanz') Use In v_vanz ENDIF IF Empty(m.tnCod) OR Empty(m.tdDataAct) CreeazaCursorTvanzGol() RETURN .T. ENDIF lcSerieAct = Alltrim(Nvl(m.tcSerieAct,"")) lcSql = [select v.id_vanzare, v.tip, v.discount, v.total_fara_tva, v.total_tva, v.total_cu_tva, v.curs, v.multiplicator, ] + ; [v.in_valuta, v.id_valuta, nv.nume_val, v.id_fact from vanzari v left join nom_valute nv on nv.id_valuta = v.id_valuta where v.cod = ] + Transform(m.tnCod) + ; [ and Nvl(v.numar_act,-1) = ] + Transform(Nvl(m.tnNract,-1)) + ; [ and Nvl(v.serie_act,'') = '] + m.lcSerieAct + [' and trunc(v.data_act) = to_date('] + Dtoc(m.tdDataAct,1) + [','YYYYMMDD') and v.sters = 0] lnSucces = goExecutor.oExecute(lcSql,[v_vanz]) goExecutor.oReset() IF lnSucces < 0 AMESSAGEBOX(goExecutor.cEroare,0+16,"Eroare") CreeazaCursorTvanzGol() RETURN .T. ENDIF IF Used('tvanz') Use In tvanz ENDIF SELECT * FROM v_vanz INTO CURSOR tvanz READWRITE USE IN v_vanz RETURN .T. ENDFUNC && IncarcaVanzareNota *!* parametru: alias cu randurile notei (tact), cu campurile cod/nract/serie_act/dataact/sters *!* incearca toate combinatiile distincte (cod, nract, serie_act, dataact) din alias (sters=0) pana *!* gaseste un rand in VANZARI; lasa workarea si pozitia curenta neschimbate, .F. cu tvanz gol daca nu gaseste FUNCTION IncarcaVanzareDinNota LPARAMETERS tcAliasAct LOCAL lnAreaOrigine, lnRecnoOrigine, llGasit lnAreaOrigine = Select() llGasit = .F. IF Empty(m.tcAliasAct) OR !Used(m.tcAliasAct) OR Reccount(m.tcAliasAct) = 0 CreeazaCursorTvanzGol() IF m.lnAreaOrigine > 0 SELECT (m.lnAreaOrigine) ENDIF RETURN .F. ENDIF lnRecnoOrigine = Recno(m.tcAliasAct) IF Used('tmp_triplete_pozvanz') Use In tmp_triplete_pozvanz ENDIF *!* cod se ia tot din cursor, nu de pe randul curent - acesta poate fi la EOF dupa CalculeazaTotal SELECT DISTINCT cod, nract, serie_act, dataact FROM (m.tcAliasAct) WHERE sters = 0 INTO CURSOR tmp_triplete_pozvanz READWRITE SELECT tmp_triplete_pozvanz SCAN IncarcaVanzareNota(cod, nract, serie_act, dataact) IF Reccount('tvanz') = 1 llGasit = .T. EXIT ENDIF ENDSCAN IF Used('tmp_triplete_pozvanz') Use In tmp_triplete_pozvanz ENDIF IF !m.llGasit CreeazaCursorTvanzGol() ENDIF IF Used(m.tcAliasAct) IF m.lnRecnoOrigine > 0 AND m.lnRecnoOrigine <= Reccount(m.tcAliasAct) Go (m.lnRecnoOrigine) In (m.tcAliasAct) ELSE *!* pozitia initiala era EOF (Recno() peste Reccount()) - se restaureaza tot la EOF Go Bottom In (m.tcAliasAct) Skip In (m.tcAliasAct) ENDIF ENDIF IF m.lnAreaOrigine > 0 SELECT (m.lnAreaOrigine) ENDIF RETURN m.llGasit ENDFUNC && IncarcaVanzareDinNota *!* parametru: alias destinatie (implicit tvd) *!* creeaza gol, sub acel alias, un cursor cu structura view-ului VVANZARI_ARTICOLE FUNCTION CreeazaCursorArticoleGol LPARAMETERS tcAlias LOCAL lcAlias lcAlias = IIF(Type('tcAlias') = 'C' AND !Empty(m.tcAlias), m.tcAlias, 'tvd') IF Used(m.lcAlias) Use In (m.lcAlias) ENDIF CREATE CURSOR (m.lcAlias) (id_vanzare I NULL, id_vanzare_det I NULL, id_articol N(20) 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, 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 *!* creeaza cursorul tvd gol, cu structura view-ului VVANZARI_ARTICOLE FUNCTION CreeazaCursorTvdGol CreeazaCursorArticoleGol('tvd') ENDFUNC && CreeazaCursorTvdGol *!* parametri: id_vanzare, alias destinatie (implicit tvd) *!* incarca in alias liniile active (sters=0) ale vanzarii, din VVANZARI_ARTICOLE *!* aliasul ramane deschis READWRITE, cu 0 randuri la eroare Oracle FUNCTION IncarcaArticoleFactura LPARAMETERS tnIdVanzare, tcAliasDestinatie LOCAL lcSql, lnSucces, lcAlias lcAlias = IIF(Type('tcAliasDestinatie') = 'C' AND !Empty(m.tcAliasDestinatie), m.tcAliasDestinatie, 'tvd') IF Used('v_vd') Use In v_vd ENDIF *!* in_stoc vine din NOM_ARTICOLE (viewul nu-l expune) - corectia verdictului RUL pe liniile nestocate lcSql = [select v.*, na.in_stoc from vvanzari_articole v left join nom_articole na on na.id_articol = v.id_articol ] + ; [where v.id_vanzare = ] + Transform(Nvl(m.tnIdVanzare,0)) + [ and v.sters = 0 order by v.id_vanzare_det] lnSucces = goExecutor.oExecute(lcSql,[v_vd]) goExecutor.oReset() IF lnSucces < 0 AMESSAGEBOX(goExecutor.cEroare,0+16,"Eroare") CreeazaCursorArticoleGol(m.lcAlias) RETURN .T. ENDIF IF Used(m.lcAlias) Use In (m.lcAlias) ENDIF *!* valoarea cu TVA pe linie, cu discountul unitar scazut: pret_cu_tva e flag (0/1), nu pret - *!* formula difera dupa el, ca la calculeaza_valori_articol SELECT *, .F. AS lmodificat, ; ROUND(NVL(cantitate,0) * IIF(NVL(pret_cu_tva,0) = 0, (NVL(pret,0) - NVL(discount_unitar,0)) * NVL(proc_tvav,1), ; NVL(pret,0) - NVL(discount_unitar,0)), gnPC) AS valoare ; FROM v_vd INTO CURSOR (m.lcAlias) READWRITE USE IN v_vd RETURN .T. ENDFUNC && IncarcaArticoleFactura *!* parametru: alias cu randurile notei (tact) *!* descopera randul din VANZARI corespunzator notei (IncarcaVanzareDinNota) si, daca il gaseste, *!* pre-incarca liniile in crsArticoleFactura - apelat inainte de Createobject([frm_modific2024]), *!* ca Load() sa lege grid-ul o singura data pe cursorul deja plin; daca nu gaseste randul nu *!* creeaza crsArticoleFactura, Show() ramane fallback-ul; nu strica workarea/pozitia apelantului FUNCTION PregatesteArticoleFacturaEditare LPARAMETERS tcAliasAct LOCAL lnAreaOrigine, llGasit lnAreaOrigine = Select() llGasit = IncarcaVanzareDinNota(m.tcAliasAct) IF m.llGasit IncarcaArticoleFactura(tvanz.id_vanzare, 'crsArticoleFactura') ENDIF IF m.lnAreaOrigine > 0 SELECT (m.lnAreaOrigine) ENDIF RETURN m.llGasit ENDFUNC && PregatesteArticoleFacturaEditare *!* parametri: id_articol/codmat/denumire/um/cont, alese din nomenclator (caut_articol, fara stoc); *!* optional, cand documentul e in valuta: in_valuta/curs/multiplicator/nume_val/id_valuta *!* construieste obiectul poArticol gol, cu toate proprietatile citite de frm_articol_factura *!* (Createobject/Init/inainte_de_do_termin) - articol nou, cantitate implicita 1, fara TVA aleasa *!* (proc_tvav ramane NULL, ca Init sa aleaga singur cota standard curenta); daca in_valuta e adevarat, *!* tip_valuta/Curs/multiplicator/nume_val/id_valuta se populeaza cu valorile documentului FUNCTION CreeazaPoArticolNouTvd LPARAMETERS tnIdArticol, tcCodmat, tcDenumire, tcUm, tcCont, tlInValutaDoc, tnCursDoc, tnMultDoc, tcNumeValDoc, tnIdValutaDoc LOCAL loArticol, lnI LOCAL ARRAY laPropN(49) laPropN( 1)='id_articol' laPropN( 2)='Id_Pol' laPropN( 3)='id_gestiune' laPropN( 4)='id_c' laPropN( 5)='id_ctr' laPropN( 6)='id_valuta' laPropN( 7)='id_valuta_d' laPropN( 8)='id_lucrare_rez' laPropN( 9)='id_part_rez' laPropN(10)='id_jtva_coloana' laPropN(11)='taxcode' laPropN(12)='opt_facturare' laPropN(13)='gestionabil' laPropN(14)='tip_valuta' laPropN(15)='cantitate' laPropN(16)='Curs' laPropN(17)='multiplicator' laPropN(18)='pret_achizitie' laPropN(19)='pretv_orig' laPropN(20)='pretd' laPropN(21)='proc_tvav' laPropN(22)='preturi_cu_tva' laPropN(23)='pretftva' laPropN(24)='pretftva_val' laPropN(25)='pretctva' laPropN(26)='pretctva_val' laPropN(27)='tva' laPropN(28)='tva_val' laPropN(29)='discount_unitar' laPropN(30)='discount_unitar_val' laPropN(31)='discount_unitar_ctva' laPropN(32)='discount_unitar_ctva_val' laPropN(33)='valftva' laPropN(34)='valtva' laPropN(35)='valctva' laPropN(36)='valdiscountftva' laPropN(37)='valdiscounttva' laPropN(38)='valdiscountctva' laPropN(39)='valdiminuatftva' laPropN(40)='valdiminuattva' laPropN(41)='valdiminuatctva' laPropN(42)='vvalftva' laPropN(43)='vvaltva' laPropN(44)='vvalctva' laPropN(45)='vvaldiscountftva' laPropN(46)='vvaldiscounttva' laPropN(47)='vvaldiscountctva' laPropN(48)='vvaldiminuatftva' laPropN(49)='vvaldiminuattva' LOCAL ARRAY laPropC(11) laPropC( 1)='codmat' laPropC( 2)='codmatf' laPropC( 3)='denumire' laPropC( 4)='um' laPropC( 5)='serie' laPropC( 6)='lot' laPropC( 7)='explicatie' laPropC( 8)='numar_contract' laPropC( 9)='codbare' laPropC(10)='nume_val' laPropC(11)='Cont' loArticol = Createobject('Empty') FOR lnI = 1 TO ALEN(laPropN) =AddProperty(loArticol, laPropN(lnI), 0) ENDFOR =AddProperty(loArticol, 'vvaldiminuatctva', 0) FOR lnI = 1 TO ALEN(laPropC) =AddProperty(loArticol, laPropC(lnI), '') ENDFOR loArticol.id_articol = Nvl(m.tnIdArticol, 0) loArticol.id_ctr = .Null. loArticol.id_gestiune = -1000 loArticol.gestionabil = 0 loArticol.tip_valuta = 0 loArticol.Curs = 1 loArticol.multiplicator = 1 loArticol.cantitate = 1 loArticol.codmat = Nvl(m.tcCodmat, '') loArticol.denumire = Nvl(m.tcDenumire, '') loArticol.um = Nvl(m.tcUm, '') loArticol.Cont = Nvl(m.tcCont, '') loArticol.preturi_cu_tva = 0 loArticol.proc_tvav = .Null. IF m.tlInValutaDoc loArticol.tip_valuta = 1 loArticol.Curs = m.tnCursDoc loArticol.multiplicator = m.tnMultDoc loArticol.nume_val = Nvl(m.tcNumeValDoc, '') loArticol.id_valuta = m.tnIdValutaDoc ENDIF 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 *!* toate campurile pe care grila si nomenclatoarele le pot schimba - altfel alegerile de pe *!* liniile deja salvate (cod TVA, explicatie TVA, gestiune, valuta, articol) s-ar pierde tacut 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))) + ; [, pret_achizitie = ] + Iif(Isnull(pret_achizitie),[NULL],Alltrim(Str(pret_achizitie,18,4))) + ; [, proc_tvav = ] + Iif(Isnull(proc_tvav),[NULL],Alltrim(Str(proc_tvav,18,4))) + ; [, discount_unitar = ] + Iif(Isnull(discount_unitar),[NULL],Alltrim(Str(discount_unitar,18,4))) + ; [, id_articol = ] + Iif(Isnull(id_articol),[NULL],Alltrim(Str(id_articol))) + ; [, id_gestiune = ] + Iif(Isnull(id_gestiune),[NULL],Alltrim(Str(id_gestiune))) + ; [, id_valuta = ] + Iif(Isnull(id_valuta),[NULL],Alltrim(Str(id_valuta))) + ; [, id_jtva_coloana = ] + Iif(Isnull(id_jtva_coloana),[NULL],Alltrim(Str(id_jtva_coloana))) + ; [, taxcode = ] + Iif(Isnull(taxcode),[NULL],Alltrim(Str(taxcode))) + ; [, cont = ] + Iif(Empty(Nvl(cont,'')),[NULL],['] + OracleSpecialCharacters(Alltrim(Nvl(cont,''))) + [']) + ; [, serie = ] + Iif(Empty(Nvl(serie,'')),[NULL],['] + OracleSpecialCharacters(Alltrim(Nvl(serie,''))) + [']) + ; [, explicatie = ] + Iif(Empty(Nvl(explicatie,'')),[NULL],['] + OracleSpecialCharacters(Alltrim(Nvl(explicatie,''))) + [']) + ; [, lot = ] + Iif(Empty(Nvl(lot,'')),[NULL],['] + OracleSpecialCharacters(Alltrim(Nvl(lot,''))) + [']) + ; [, 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)) + [,] + Iif(Isnull(id_articol),[NULL],Alltrim(Str(id_articol))) + [,] + Alltrim(Str(Nvl(cantitate,0),18,3)) + [,] + ; Alltrim(Str(Nvl(pret,0),18,4)) + [,] + Alltrim(Str(Nvl(pret_cu_tva,0))) + [,] + Iif(Isnull(proc_tvav),[NULL],Alltrim(Str(proc_tvav,18,4))) + [,] + ; Iif(Isnull(discount_unitar),[NULL],Alltrim(Str(discount_unitar,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,''))) + [']) + [,] + ; Iif(Isnull(pret_achizitie),[NULL],Alltrim(Str(pret_achizitie,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 *!* parametru: tcDirectie - 'RUL_SURSA' (implicit, rulajul actualizeaza articolele) sau 'ARTICOLE_SURSA' *!* (articolele actualizeaza rulajul); orice alta valoare cade pe 'RUL_SURSA' *!* compara rulajele (trul) cu articolele facturii (tvd), agregate pe id_articol (singura cheie comuna, *!* fara FK la nivel de linie), si produce cursorul propunere_sincronizare (READWRITE, lasat deschis pe *!* seama apelantului): id_articol, denumire, codmat, cantitate_veche/noua, pret_vechi/nou, actiune *!* (Modificare/Adaugare/Semnalare/N-A), motiv. "vechi" = cursorul-tinta curent, "nou" = cursorul-sursa *!* calculat (agregare formula E.3: SUM(cant*pretvtva) + SUM(cante*pretvtva) pe randurile id_tip_rulaj<>3, *!* pret mediu ponderat); articolele identice intre sursa si tinta nu apar in cursor. N-A pe: articol *!* nestocat (fara randuri RUL posibile), articol cu mai multe randuri RUL active (niciodata alegere *!* automata a randului) sau document in valuta (conversia RUL<->valuta nu e acoperita de aceasta functie) *!* retur logic: .F. daca tvd/trul nu sunt deschise (cursorul iese oricum creat, gol) FUNCTION ConstruiestePropunereSincronizare LPARAMETERS tcDirectie LOCAL lcDirectie, lnAreaOrigine, lnCantLinie, lnValLinie, llDocInValuta LOCAL lnCantRul, lnValRul, lnNrandRul, lnPretRul, lcDenumireRul, lcCodmatRul LOCAL lnCantTvd, lnValTvd, lnNrandTvd, lnPretTvd, lcDenumireTvd, lcCodmatTvd, llInStoc LOCAL llGasitSursa, llGasitTinta, lnCantSursa, lnPretSursa, lnCantTinta, lnPretTinta LOCAL lnCantVechi, lnCantNou, lnPretVechi, lnPretNou, lcActiune, lcMotiv, lcDenumire, lcCodmat lcDirectie = IIF(Upper(Alltrim(Nvl(m.tcDirectie,''))) == 'ARTICOLE_SURSA', 'ARTICOLE_SURSA', 'RUL_SURSA') lnAreaOrigine = Select() IF Used('propunere_sincronizare') Use In propunere_sincronizare ENDIF CREATE CURSOR propunere_sincronizare (id_articol N(20), denumire C(100), codmat C(30), ; cantitate_veche N(12,3), cantitate_noua N(12,3), pret_vechi N(14,4), pret_nou N(14,4), ; actiune C(12), motiv C(80)) IF !Used('tvd') OR !Used('trul') IF m.lnAreaOrigine > 0 SELECT (m.lnAreaOrigine) ENDIF RETURN .F. ENDIF llDocInValuta = (Used('tvanz') AND Reccount('tvanz') = 1 AND Nvl(tvanz.in_valuta,0) <> 0) *!* agregare RUL pe articol (formula E.3) - cant/val insumate, nrand = randuri active distincte IF Used('agg_rul') Use In agg_rul ENDIF CREATE CURSOR agg_rul (id_articol N(20) NULL, denumire C(100), codmat C(30), cant N(12,3), val N(16,4), nrand I) SELECT trul *!* cheia comparatiei e id_articol - o linie fara articol n-are cum sa aiba corespondent SCAN FOR Nvl(sters,0) <> 1 AND !Isnull(id_articol) lnCantLinie = Nvl(cant,0) + IIF(Nvl(id_tip_rulaj,0) <> 3, Nvl(cante,0), 0) lnValLinie = Nvl(cant,0) * Nvl(pretvtva,0) + IIF(Nvl(id_tip_rulaj,0) <> 3, Nvl(cante,0) * Nvl(pretvtva,0), 0) lcDenumireRul = Nvl(trul.denumire,'') lcCodmatRul = Nvl(trul.codmat,'') SELECT agg_rul LOCATE FOR id_articol = trul.id_articol IF Found() REPLACE cant WITH cant + m.lnCantLinie, val WITH val + m.lnValLinie, nrand WITH nrand + 1 IN agg_rul ELSE INSERT INTO agg_rul (id_articol, denumire, codmat, cant, val, nrand) ; VALUES (trul.id_articol, m.lcDenumireRul, m.lcCodmatRul, m.lnCantLinie, m.lnValLinie, 1) ENDIF SELECT trul ENDSCAN *!* agregare articole factura pe articol - val se ia din tvd.valoare (deja calculata, cu TVA, la incarcare/editare) IF Used('agg_tvd') Use In agg_tvd ENDIF CREATE CURSOR agg_tvd (id_articol N(20) NULL, denumire C(100), codmat C(30), cant N(12,3), val N(16,4), nrand I, in_stoc I) SELECT tvd *!* liniile de rata dintr-un contract n-au id_articol - se exclud, la fel ca in bucla de mai sus SCAN FOR Nvl(sters,0) <> 1 AND !Isnull(id_articol) lcDenumireTvd = Nvl(tvd.denumire,'') lcCodmatTvd = Nvl(tvd.codmat,'') SELECT agg_tvd LOCATE FOR id_articol = tvd.id_articol IF Found() REPLACE cant WITH cant + Nvl(tvd.cantitate,0), val WITH val + Nvl(tvd.valoare,0), nrand WITH nrand + 1 IN agg_tvd ELSE INSERT INTO agg_tvd (id_articol, denumire, codmat, cant, val, nrand, in_stoc) ; VALUES (tvd.id_articol, m.lcDenumireTvd, m.lcCodmatTvd, Nvl(tvd.cantitate,0), Nvl(tvd.valoare,0), 1, Nvl(tvd.in_stoc,1)) ENDIF SELECT tvd ENDSCAN IF Used('crs_articole_unite') Use In crs_articole_unite ENDIF SELECT id_articol FROM agg_rul ; UNION ; SELECT id_articol FROM agg_tvd ; INTO CURSOR crs_articole_unite READWRITE SELECT crs_articole_unite SCAN lcDenumire = '' lcCodmat = '' SELECT agg_rul LOCATE FOR id_articol = crs_articole_unite.id_articol llGasitSursa = .F. && folosit mai jos doar dupa mapare pe directie IF Found() lnCantRul = cant lnValRul = val lnNrandRul = nrand lcDenumire = denumire lcCodmat = codmat ELSE lnCantRul = 0 lnValRul = 0 lnNrandRul = 0 ENDIF lnPretRul = IIF(m.lnCantRul <> 0, m.lnValRul / m.lnCantRul, 0) SELECT agg_tvd LOCATE FOR id_articol = crs_articole_unite.id_articol IF Found() lnCantTvd = cant lnValTvd = val lnNrandTvd = nrand llInStoc = (Nvl(in_stoc,1) <> 0) IF !Empty(Nvl(denumire,'')) lcDenumire = denumire lcCodmat = codmat ENDIF ELSE lnCantTvd = 0 lnValTvd = 0 lnNrandTvd = 0 llInStoc = .T. ENDIF lnPretTvd = IIF(m.lnCantTvd <> 0, m.lnValTvd / m.lnCantTvd, 0) IF m.lcDirectie == 'RUL_SURSA' llGasitSursa = (m.lnNrandRul > 0) llGasitTinta = (m.lnNrandTvd > 0) lnCantSursa = m.lnCantRul lnPretSursa = m.lnPretRul lnCantTinta = m.lnCantTvd lnPretTinta = m.lnPretTvd ELSE llGasitSursa = (m.lnNrandTvd > 0) llGasitTinta = (m.lnNrandRul > 0) lnCantSursa = m.lnCantTvd lnPretSursa = m.lnPretTvd lnCantTinta = m.lnCantRul lnPretTinta = m.lnPretRul ENDIF lnCantVechi = m.lnCantTinta lnPretVechi = m.lnPretTinta lnCantNou = m.lnCantSursa lnPretNou = m.lnPretSursa lcActiune = '' lcMotiv = '' DO CASE CASE m.llDocInValuta lcActiune = 'N-A' lcMotiv = 'Documentul e in valuta - sincronizarea automata a preturilor nu e suportata, verificati manual' CASE m.lnNrandRul > 1 lcActiune = 'N-A' lcMotiv = 'Mai multe randuri RUL active pe acelasi articol, verificati manual' CASE m.lnNrandTvd > 0 AND !m.llInStoc lcActiune = 'N-A' lcMotiv = 'Articol nestocat, fara corespondent in rulaje' CASE m.llGasitSursa AND !m.llGasitTinta lcActiune = 'Adaugare' lcMotiv = IIF(m.lcDirectie == 'ARTICOLE_SURSA', ; 'Articol prezent doar in articolele facturii - adaugarea unui rand nou in rulaje nu se aplica automat', '') CASE !m.llGasitSursa AND m.llGasitTinta lcActiune = 'Semnalare' lcMotiv = 'Articol fara corespondent in sursa - stergerea nu se face automat' OTHERWISE IF Abs(m.lnCantVechi - m.lnCantNou) < 0.0005 AND Round(m.lnPretVechi, m.gnPC) == Round(m.lnPretNou, m.gnPC) lcActiune = '' ELSE lcActiune = 'Modificare' ENDIF ENDCASE IF !Empty(m.lcActiune) INSERT INTO propunere_sincronizare (id_articol, denumire, codmat, cantitate_veche, cantitate_noua, ; pret_vechi, pret_nou, actiune, motiv) VALUES (crs_articole_unite.id_articol, m.lcDenumire, m.lcCodmat, ; m.lnCantVechi, m.lnCantNou, Round(m.lnPretVechi,4), Round(m.lnPretNou,4), m.lcActiune, m.lcMotiv) ENDIF SELECT crs_articole_unite ENDSCAN IF Used('agg_rul') Use In agg_rul ENDIF IF Used('agg_tvd') Use In agg_tvd ENDIF IF Used('crs_articole_unite') Use In crs_articole_unite ENDIF IF m.lnAreaOrigine > 0 SELECT (m.lnAreaOrigine) ENDIF RETURN .T. ENDFUNC && ConstruiestePropunereSincronizare *!* parametri: tcDirectie (ca la ConstruiestePropunereSincronizare), toForm (obiectul frm_modific2024, *!* opus/reutilizat pentru calculeaza_valori_articol/AdaugaLinieTvdDinArticol - fara el, liniile *!* Modificare/Adaugare pe tvd nu se aplica, doar cele pe trul, care nu au nevoie de metode de formular) *!* reconstruieste propunerea (ConstruiestePropunereSincronizare) si aplica tot ce nu e N-A/Semnalare, *!* DOAR in cursoarele din memorie (tvd/trul) - niciun INSERT/UPDATE Oracle; RUL_SURSA scrie in tvd *!* (cantitate/pret, pastrand pret_cu_tva existent pe rand), ARTICOLE_SURSA scrie doar cant/pretvtva pe *!* randul RUL deja existent (niciodata rand RUL nou - lipsesc contul/gestiunea sigure din articol) *!* retur numeric: cate linii au fost efectiv aplicate (ca apelantul sa poata reface bara de totaluri) FUNCTION AplicaSincronizareArticole LPARAMETERS tcDirectie, toForm LOCAL lcDirectie, lnAplicate, lnAreaOrigine, lnIdArticol, lcActiune, lnCantitateNoua, lnPretNou lcDirectie = IIF(Upper(Alltrim(Nvl(m.tcDirectie,''))) == 'ARTICOLE_SURSA', 'ARTICOLE_SURSA', 'RUL_SURSA') lnAplicate = 0 lnAreaOrigine = Select() IF !ConstruiestePropunereSincronizare(m.lcDirectie) IF m.lnAreaOrigine > 0 SELECT (m.lnAreaOrigine) ENDIF RETURN 0 ENDIF SELECT propunere_sincronizare SCAN FOR Inlist(Alltrim(actiune), 'Modificare', 'Adaugare') lnIdArticol = id_articol lcActiune = Alltrim(actiune) lnCantitateNoua = cantitate_noua lnPretNou = pret_nou DO CASE CASE m.lcDirectie == 'RUL_SURSA' AND m.lcActiune == 'Modificare' IF AplicaModificareTvd(m.lnIdArticol, m.lnCantitateNoua, m.lnPretNou, m.toForm) lnAplicate = m.lnAplicate + 1 ENDIF CASE m.lcDirectie == 'RUL_SURSA' AND m.lcActiune == 'Adaugare' IF AplicaAdaugareTvd(m.lnIdArticol, m.lnCantitateNoua, m.lnPretNou, m.toForm) lnAplicate = m.lnAplicate + 1 ENDIF CASE m.lcDirectie == 'ARTICOLE_SURSA' AND m.lcActiune == 'Modificare' IF AplicaModificareTrul(m.lnIdArticol, m.lnCantitateNoua, m.lnPretNou) lnAplicate = m.lnAplicate + 1 ENDIF *!* ARTICOLE_SURSA + Adaugare: fara scriere, un rand RUL nou nu se poate crea sigur din articol ENDCASE SELECT propunere_sincronizare ENDSCAN IF m.lnAreaOrigine > 0 SELECT (m.lnAreaOrigine) ENDIF RETURN m.lnAplicate ENDFUNC && AplicaSincronizareArticole *!* parametri: id_articol, cantitate/pret noi (pret_nou e intotdeauna cu TVA - formula E.3 din RUL), *!* toForm (opus, cu metoda calculeaza_valori_articol - fara el se scrie doar REPLACE-ul, fara recalcul *!* de valoare/bara totaluri, pe seama apelantului) *!* scrie in tvd (primul rand activ gasit pe articol) cantitatea si pretul propuse, pastrand pret_cu_tva *!* existent pe rand (converteste pret_nou la conventia fara TVA a randului daca era asa dinainte); *!* discount_unitar se reseteaza la 0 - pretul propus e deja pretul mediu ponderat efectiv din rulaje FUNCTION AplicaModificareTvd LPARAMETERS tnIdArticol, tnCantitateNoua, tnPretNouCuTva, toForm LOCAL lnAreaOrigine, llAplicat, lnPretDeScris, lnProcTvav lnAreaOrigine = Select() llAplicat = .F. IF Used('tvd') SELECT tvd LOCATE FOR id_articol = m.tnIdArticol AND Nvl(sters,0) <> 1 IF Found() lnProcTvav = Nvl(proc_tvav,1) IF m.lnProcTvav = 0 lnProcTvav = 1 ENDIF lnPretDeScris = IIF(Nvl(pret_cu_tva,0) = 0, m.tnPretNouCuTva / m.lnProcTvav, m.tnPretNouCuTva) REPLACE cantitate WITH m.tnCantitateNoua, pret WITH m.lnPretDeScris, discount_unitar WITH 0, ; lmodificat WITH .T. IN tvd IF Vartype(m.toForm) == 'O' AND Pemstatus(m.toForm, 'calculeaza_valori_articol', 5) m.toForm.calculeaza_valori_articol() ENDIF llAplicat = .T. ENDIF ENDIF IF m.lnAreaOrigine > 0 SELECT (m.lnAreaOrigine) ENDIF RETURN m.llAplicat ENDFUNC && AplicaModificareTvd *!* parametri: id_articol (existent doar in trul), cantitate/pret noi (pret_nou cu TVA), toForm (obligatoriu, *!* cu metoda AdaugaLinieTvdDinArticol - fara el functia nu are cum sa adauge linia, intoarce .F.) *!* construieste obiectul poArticol (tiparul din CreeazaPoArticolNouTvd, cont/id_gestiune/um preluate din *!* randul RUL al articolului) si il preda lui toForm.AdaugaLinieTvdDinArticol - linia noua intra in tvd *!* cu pret_cu_tva=1 (pretul propus e deja cu TVA) si discount_unitar=0; document RON (tip_valuta=0), *!* documentele in valuta sunt deja excluse la nivelul propunerii FUNCTION AplicaAdaugareTvd LPARAMETERS tnIdArticol, tnCantitateNoua, tnPretNouCuTva, toForm LOCAL lnAreaOrigine, llAplicat, loArticol lnAreaOrigine = Select() llAplicat = .F. IF Vartype(m.toForm) == 'O' AND Pemstatus(m.toForm, 'AdaugaLinieTvdDinArticol', 5) AND Used('trul') SELECT trul LOCATE FOR id_articol = m.tnIdArticol AND Nvl(sters,0) <> 1 IF Found() loArticol = CreeazaPoArticolNouTvd(trul.id_articol, Nvl(trul.codmat,''), Nvl(trul.denumire,''), ; Nvl(trul.um,''), Nvl(trul.cont,''), .F., 1, 1, '', 0) loArticol.id_gestiune = Nvl(trul.id_gestiune, -1000) loArticol.cantitate = m.tnCantitateNoua loArticol.preturi_cu_tva = 1 loArticol.pretctva = m.tnPretNouCuTva loArticol.proc_tvav = Nvl(trul.proc_tvav, 1) loArticol.discount_unitar_ctva = 0 m.toForm.AdaugaLinieTvdDinArticol(loArticol) llAplicat = .T. ENDIF ENDIF IF m.lnAreaOrigine > 0 SELECT (m.lnAreaOrigine) ENDIF RETURN m.llAplicat ENDFUNC && AplicaAdaugareTvd *!* parametri: id_articol, cantitate/pret noi (pret_nou cu TVA) *!* scrie in trul (singurul rand activ gasit pe articol - garantat unic, altfel propunerea a marcat N-A) *!* doar cant/cante (dupa care din ele era deja folosit pe rand) si pretvtva; nu atinge id_tip_rulaj, *!* conturi (scd/scc) sau alte campuri derivate (valoare/tva/etc.) - raman de recalculat de apelant daca e nevoie FUNCTION AplicaModificareTrul LPARAMETERS tnIdArticol, tnCantitateNoua, tnPretNouCuTva LOCAL lnAreaOrigine, llAplicat, lcCampCant lnAreaOrigine = Select() llAplicat = .F. IF Used('trul') SELECT trul LOCATE FOR id_articol = m.tnIdArticol AND Nvl(sters,0) <> 1 IF Found() lcCampCant = IIF(Nvl(cant,0) <> 0, 'cant', 'cante') REPLACE (m.lcCampCant) WITH m.tnCantitateNoua, pretvtva WITH m.tnPretNouCuTva IN trul llAplicat = .T. ENDIF ENDIF IF m.lnAreaOrigine > 0 SELECT (m.lnAreaOrigine) ENDIF RETURN m.llAplicat ENDFUNC && AplicaModificareTrul *!* editorul liniilor de articole ale notei: primeste in Init formularul frm_modific2024 si *!* actioneaza asupra cursorului lui tvd - adaugarea unei linii prin nomenclator si dialogul *!* frm_articol_factura, stergerea logica, duplicarea liniei si nomenclatoarele de pe coloanele *!* articol / gestiune / valuta / cod TVA DEFINE CLASS ArticoleNotaEditor AS Custom oForm = .Null. PROCEDURE Init LPARAMETERS toForm IF Vartype(m.toForm) <> 'O' RETURN .F. ENDIF This.oForm = m.toForm ENDPROC *!* .T. cat timp liniile accepta modificari: documentul are articole si nu e trimis in eFactura PROCEDURE Editabil RETURN Used('tvd') AND This.oForm.lAreArticoleVanzari AND !This.oForm.lArticoleReadOnly ENDPROC *!* numele campului dintr-un ControlSource de forma alias.camp PROCEDURE NumeCamp LPARAMETERS tcControl LOCAL lcCamp lcCamp = Lower(Alltrim(Nvl(m.tcControl, ''))) IF '.' $ m.lcCamp lcCamp = Right(m.lcCamp, Len(m.lcCamp) - At('.', m.lcCamp)) ENDIF RETURN m.lcCamp ENDPROC *!* .T. daca pe coloana data se poate deschide un nomenclator PROCEDURE AreNomenclator LPARAMETERS tcControl RETURN Inlist(This.NumeCamp(m.tcControl), 'denumire', 'nume_gestiune', 'nume_val', 'taxcode', 'id_jtva_coloana') ENDPROC *!* alege un articol din nomenclator (fara stoc, fara politica de preturi) si il adauga in tvd ca *!* linie noua (id_vanzare_det = 0), prin dialogul frm_articol_factura; pe document in valuta *!* dialogul primeste cursul si valuta documentului, deci pretul se introduce direct in valuta PROCEDURE AdaugaLinie LOCAL loArticolAles, lnIdArticol, llInValutaDoc, lnCursDoc, lnMultDoc, lcNumeValDoc, lnIdValutaDoc LOCAL loDlg, llAdaugat llAdaugat = .F. IF !This.Editabil() RETURN .F. ENDIF loArticolAles = caut_articol() lnIdArticol = Nvl(loArticolAles.id_articol, 0) IF Empty(m.lnIdArticol) RETURN .F. ENDIF llInValutaDoc = Iif(Used('tvanz') And Reccount('tvanz') > 0, Nvl(tvanz.in_valuta, 0) = 1, .F.) lnCursDoc = Iif(Used('tvanz') And Reccount('tvanz') > 0, Nvl(tvanz.curs, 1), 1) lnMultDoc = Iif(Used('tvanz') And Reccount('tvanz') > 0, Nvl(tvanz.multiplicator, 1), 1) lcNumeValDoc = Iif(Used('tvanz') And Reccount('tvanz') > 0, Nvl(tvanz.nume_val, ''), '') lnIdValutaDoc = Iif(Used('tvanz') And Reccount('tvanz') > 0, tvanz.id_valuta, .Null.) PRIVATE poArticol, poDate, gnScadereStoc poArticol = CreeazaPoArticolNouTvd(m.lnIdArticol, loArticolAles.codmat, loArticolAles.denumire, loArticolAles.um, loArticolAles.cont, ; m.llInValutaDoc, m.lnCursDoc, m.lnMultDoc, m.lcNumeValDoc, m.lnIdValutaDoc) poDate = Createobject('Empty') AddProperty(poDate, 'tip', This.oForm.nTipVanzare) AddProperty(poDate, 'in_valuta', 0) AddProperty(poDate, 'dataact', Iif(Used('tact') And Reccount('tact') > 0, Nvl(tact.dataact, Date()), Date())) gnScadereStoc = 0 gnButon = 2 loDlg = Createobject('frm_articol_factura', 1, .F.) loDlg.Show(1) IF m.gnButon = 1 This.oForm.AdaugaLinieTvdDinArticol(poArticol) This.RefreshGrid() llAdaugat = .T. ENDIF Release loDlg RETURN m.llAdaugat ENDPROC *!* comuta flagul sters pe linia curenta - stergerea e logica, linia ramane vizibila (grizata) *!* pana la salvare PROCEDURE ComutaSters IF !This.Editabil() OR Reccount('tvd') = 0 RETURN .F. ENDIF SELECT tvd REPLACE sters WITH Iif(Nvl(sters, 0) = 1, 0, 1), lmodificat WITH .T. This.RefreshGrid() This.oForm.ActualizeazaBaraTotaluri() RETURN .T. ENDPROC *!* duplica linia curenta ca linie noua nesalvata, desprinsa de setul din care provenea, ca sa *!* poata fi editata ca orice linie adaugata manual PROCEDURE DuplicaLinie LOCAL loLinie IF !This.Editabil() OR Reccount('tvd') = 0 RETURN .F. ENDIF SELECT tvd SCATTER NAME loLinie MEMO loLinie.id_vanzare_det = 0 loLinie.id_vanzare_set = 0 loLinie.sters = 0 loLinie.lmodificat = .T. APPEND BLANK GATHER NAME loLinie MEMO This.oForm.calculeaza_valori_articol() This.RefreshGrid() RETURN .T. ENDPROC *!* deschide nomenclatorul coloanei primite si scrie alegerea in linia curenta din tvd; liniile *!* venite dintr-un set raman neatinse, la fel ca la editarea inline din grid PROCEDURE ModificaNomenclator LPARAMETERS tcControl LOCAL lcCamp, loCauta, lcSqlValuta, lnSuccesValuta, llValutaOk lcCamp = This.NumeCamp(m.tcControl) IF !This.Editabil() OR Reccount('tvd') = 0 OR !This.AreNomenclator(m.lcCamp) OR Nvl(tvd.id_vanzare_set, 0) <> 0 RETURN .F. ENDIF DO CASE CASE m.lcCamp == 'denumire' loCauta = caut_articol() CASE m.lcCamp == 'nume_gestiune' loCauta = caut_gestiune() CASE m.lcCamp == 'nume_val' loCauta = caut_valuta() CASE m.lcCamp == 'id_jtva_coloana' loCauta = This.CautaExplicatieTva() OTHERWISE loCauta = This.CautaCodTva() ENDCASE IF gnButon <> 1 RETURN .F. ENDIF SELECT tvd DO CASE CASE m.lcCamp == 'denumire' REPLACE denumire WITH loCauta.denumire, codmat WITH loCauta.codmat, ; id_articol WITH loCauta.id_articol, cont WITH Nvl(loCauta.cont, '') CASE m.lcCamp == 'nume_gestiune' REPLACE nume_gestiune WITH loCauta.nume_gestiune, id_gestiune WITH loCauta.id_gestiune CASE m.lcCamp == 'nume_val' *!* valuta orfana (fara curs pe document) ar goli totalurile la recalculare - se accepta doar moneda nationala sau o valuta deja folosita pe document IF Used('tvanz') AND Reccount('tvanz') = 1 lcSqlValuta = [select 1 as ok from dual where ] + Alltrim(Str(loCauta.id_valuta)) + [ = pack_def.GetIdMonedaNationala()] + ; [ or exists (select 1 from vanzari_cursuri where id_vanzare = ] + Alltrim(Str(tvanz.id_vanzare)) + ; [ and id_valuta = ] + Alltrim(Str(loCauta.id_valuta)) + [)] lnSuccesValuta = goExecutor.oExecute(m.lcSqlValuta,[crsvalok]) goExecutor.oReset() IF m.lnSuccesValuta < 0 AMESSAGEBOX(goExecutor.cEroare,0+16,"Eroare") RETURN .F. ENDIF llValutaOk = Used('crsvalok') AND Reccount('crsvalok') > 0 IF Used('crsvalok') Use In crsvalok ENDIF IF !m.llValutaOk AMESSAGEBOX([Valuta aleasa nu are curs inregistrat pe acest document. Se poate alege doar o valuta deja folosita pe document sau moneda nationala.],0+48,"Atentie") RETURN .F. ENDIF ENDIF REPLACE nume_val WITH loCauta.nume_val, id_valuta WITH loCauta.id_valuta CASE m.lcCamp == 'id_jtva_coloana' *!* cota vine din explicatia aleasa, ca la randul de nota; taxcode-ul SAF-T se recoreleaza dupa ea REPLACE id_jtva_coloana WITH loCauta.id_jtva_coloana, ; proc_tvav WITH (Nvl(loCauta.cota_tva, 0) + 100) / 100 This.oForm.UpdateExplicatieSAFTArt() This.oForm.calculeaza_valori_articol() OTHERWISE REPLACE taxcode WITH loCauta.taxcode ENDCASE REPLACE lmodificat WITH .T. This.RefreshGrid() RETURN .T. ENDPROC *!* explicatiile TVA, filtrate pe cota liniei curente (proc_tvav e in forma 1.21; cota 0/goala = *!* fara filtru) - acelasi nomenclator ca pe randul de nota PROCEDURE CautaExplicatieTva LOCAL lnCotaFiltru lnCotaFiltru = Round((Nvl(tvd.proc_tvav, 0) - 1) * 100, 2) RETURN caut_explicatie_tva(Nvl(tvd.id_jtva_coloana, -1), , , , m.lnCotaFiltru) ENDPROC *!* nomenclatorul de coduri TVA SAF-T, acelasi vsaft_taxtable de pe randurile notei *!* taxname vine din view cu latimea declarata > 254 (SUBSTR nu o micsoreaza) si driverul l-ar *!* aduce ca Memo; CAST-ul o fixeaza, iar tabela derivata pastreaza aliasul utilizabil in WHERE PROCEDURE CautaCodTva LOCAL lcSelect lcSelect = [select * from (select cast(substr(taxname,1,200) as varchar2(200)) as taxname, ] + ; [procent_taxa, taxcode from vsaft_taxtable)] RETURN cauta_alfa(m.lcSelect, [1=2], [], [taxname], [taxname,procent_taxa], ; [Alegeti codul de TVA], [Denumire,Procent], [], .F., [1=1], [taxname], 1, 0, [taxcode]) ENDPROC PROCEDURE RefreshGrid This.oForm.pgfArticole.PAGE3.grdArticoleFactura.Refresh() ENDPROC ENDDEFINE && ArticoleNotaEditor