Files
comun/programe/ofacturare_rutare_scriere.prg
Marius Mutu 8e022d332e #13: formular de facturare unificat - etapa curenta
Squash al branch-ului de lucru plan13-s2.

Clase: ofacturare (nucleul formularului unificat), ofacturare_comun,
ferestre_cere_date, ocomenzi, caut_ora (lista de preturi in combo-urile de
cautare), omodificari.

Programe: ofacturare impartit - ofacturare_antet, ofacturare_rutare_scriere si
ogrid_latimi sunt fisiere noi; oproceduri_facturare primeste discountul pe linie
si cota standard de TVA cand articolul nu are cota pe politica.

Documentatie: capcana SQLExec no_data_found, conventia de encoding, depanarea
testelor VFP si regulile de lucru - conflictele cu modificarile venite din alte
proiecte sunt rezolvate pastrand ambele parti.

Loguri de rulare a testelor scoase din versionare; testele raman.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PkyjGyrV2S7932om4kfSiK
2026-09-09 21:38:25 +03:00

569 lines
24 KiB
Plaintext

*** ofacturare_rutare_scriere
*!* helpere pentru S8b: comparatia stare-incarcata / stare-curenta la editarea unui document existent,
*!* si alegerea rutei de scriere (regenerare / modifica_date_factura / modifica_explicatie_articol / nimic),
*!* si mutarea borderoului eFactura la reemitere
*!* parametri: poDate deja incarcat (dupa IncarcaAntetFacturaEditare + IncarcaLiniiFacturaEditare),
*!* discountul curent in lei/valuta (Thisform.ndiscfactron/ndiscfactval, DUPA do_calculeaza_totaluri)
*!* construieste si intoarce instantaneul: identitatea documentului vechi (id_vanzare, id_fact, cod,
*!* an, luna - din variabilele PRIVATE deja capturate in do_editare_unificata, inainte de stergere),
*!* cei 14 parametri de antet, discountul de document (suma + indicator, separat de antet - nu e
*!* parametru al modifica_date_factura), copie a liniilor din crsfactura (doar campurile-intrare,
*!* cheie id_temp); .NULL. daca poDate nu e in editare
FUNCTION CreeazaSnapshotEditare
LPARAMETERS toDate, tnDiscountRon, tnDiscountValuta, tnIdVanzare, tnIdFact, tnCod, tnAn, tnLuna
LOCAL loSnapshot
IF VARTYPE(toDate) <> 'O' OR !toDate.lEditare
RETURN .NULL.
ENDIF
loSnapshot = CREATEOBJECT('Empty')
*!* id-ul real al documentului - NU toDate.nid_vanzare (ramane la sentinela 9999999999 pe calea de
*!* editare, IncarcaAntetFacturaEditare nu-l populeaza) - transmis explicit din do_editare_unificata
=AddProperty(loSnapshot, 'id_vanzare', NVL(m.tnIdVanzare,0))
*!* identitatea documentului vechi - pentru stergerea si reemiterea din S9, nu pentru scrierea azi
=AddProperty(loSnapshot, 'id_fact', NVL(m.tnIdFact,0))
=AddProperty(loSnapshot, 'cod', NVL(m.tnCod,0))
=AddProperty(loSnapshot, 'an', NVL(m.tnAn,0))
=AddProperty(loSnapshot, 'luna', NVL(m.tnLuna,0))
*!* id_util/dataora ale creatiei documentului vechi - din crsFacturi (gridul din frm_facturi) cand e
*!* deschis, fara interogare Oracle noua; altfel (apel fara grid) interogare minima directa pe VANZARI
LOCAL lnAreaSnapshot, llGasitAudit, lnIdUtilAudit, ldDataoraAudit
lnAreaSnapshot = 0
llGasitAudit = .F.
IF USED('crsfacturi')
lnAreaSnapshot = SELECT()
SELECT crsfacturi
LOCATE FOR id_vanzare = m.tnIdVanzare
IF FOUND('crsfacturi')
=AddProperty(loSnapshot, 'id_util', NVL(crsfacturi.id_util,0))
=AddProperty(loSnapshot, 'dataora', NVL(crsfacturi.dataora,{}))
llGasitAudit = .T.
ENDIF
IF m.lnAreaSnapshot > 0
SELECT (m.lnAreaSnapshot)
ENDIF
ENDIF
IF !m.llGasitAudit
lnIdUtilAudit = 0
ldDataoraAudit = {}
IF USED('v_snap_audit_s14')
USE IN v_snap_audit_s14
ENDIF
IF goExecutor.oExecuta([select id_util, dataora from vanzari where id_vanzare = ] + ALLTRIM(STR(NVL(m.tnIdVanzare,0),14,0)), 'v_snap_audit_s14')
SELECT v_snap_audit_s14
IF RECCOUNT('v_snap_audit_s14') > 0
GO TOP
lnIdUtilAudit = NVL(id_util,0)
ldDataoraAudit = NVL(dataora,{})
ENDIF
USE IN v_snap_audit_s14
ENDIF
=AddProperty(loSnapshot, 'id_util', lnIdUtilAudit)
=AddProperty(loSnapshot, 'dataora', ldDataoraAudit)
ENDIF
*!* cei 14 parametri de antet (modifica_date_factura_parametri.md) - valorile brute din poDate
=AddProperty(loSnapshot, 'id_ruta', NVL(toDate.id_ruta,0))
=AddProperty(loSnapshot, 'id_delegat', NVL(toDate.id_delegat,0))
=AddProperty(loSnapshot, 'id_agent', NVL(toDate.id_agent,0))
=AddProperty(loSnapshot, 'id_masina', NVL(toDate.id_masina,0))
=AddProperty(loSnapshot, 'dataora_exp', NVL(toDate.dataora_exp,{}))
=AddProperty(loSnapshot, 'id_facturare', NVL(toDate.id_facturare,0))
=AddProperty(loSnapshot, 'listare_detaliata', NVL(toDate.nListareDetaliata,0))
=AddProperty(loSnapshot, 'text_aditional', NVL(toDate.text_aditional,''))
=AddProperty(loSnapshot, 'tip_saft', NVL(toDate.tip_saft,0))
=AddProperty(loSnapshot, 'efactura', NVL(toDate.eFactura,0))
=AddProperty(loSnapshot, 'data_act', NVL(toDate.dataact,{}))
=AddProperty(loSnapshot, 'data_scad', NVL(toDate.datascad,{}))
=AddProperty(loSnapshot, 'numar_act', NVL(toDate.nract,0))
=AddProperty(loSnapshot, 'serie_act', NVL(toDate.serie_act,''))
*!* discountul de document - grup de sume, NU parametru al modifica_date_factura (S8b §1, 9e);
*!* suma vine din Thisform.ndiscfactron/ndiscfactval DUPA do_calculeaza_totaluri, nu din poDate
=AddProperty(loSnapshot, 'discount_ron', NVL(m.tnDiscountRon,0))
=AddProperty(loSnapshot, 'discount_val', NVL(m.tnDiscountValuta,0))
=AddProperty(loSnapshot, 'discount_evidentiat', NVL(toDate.discount_evidentiat,0))
*!* liniile - doar campurile pe care utilizatorul le poate schimba, cheie id_temp (=id_vanzare_det)
IF USED('crsfactura')
IF USED('snap_linii_editare')
USE IN snap_linii_editare
ENDIF
SELECT id_temp, cantitate, pretctva, pretftva, discountctva, discountftva, cu_tva, proc_tvav, ;
id_articol, id_gestiune, id_jtva_coloana, taxcode, explicatie, lot, serie, id_pol, pretd, id_valuta_d ;
FROM crsfactura INTO CURSOR snap_linii_editare READWRITE
ENDIF
RETURN loSnapshot
ENDFUNC && CreeazaSnapshotEditare
*!* parametri: poSnapshotEditare (din CreeazaSnapshotEditare), poDate curent, discountul curent in
*!* lei/valuta (Thisform.ndiscfactron/ndiscfactval), alias curent al liniilor (crsfactura)
*!* intoarce un cod de ruta: 1=regenerare, 2=modifica_date_factura, 3=modifica_explicatie_articol,
*!* 0=nimic; lant cu prioritate (sumele primele) - vezi s8b_rutarea_scrierii.md sectiunea 3.1
*!* .NULL. de instantaneu => 0 (document nou, nu editare - nu se ruteaza)
FUNCTION AlegeRutaScriereEditare
LPARAMETERS toSnapshot, toDate, tnDiscRonCurent, tnDiscValCurent, tcAliasLinii
LOCAL lcAlias, llSumeSchimbate
IF VARTYPE(toSnapshot) <> 'O'
RETURN 0
ENDIF
lcAlias = IIF(TYPE('tcAliasLinii') = 'C' AND !EMPTY(m.tcAliasLinii), m.tcAliasLinii, 'crsfactura')
llSumeSchimbate = LiniiAuSumeSchimbate(m.lcAlias) OR ;
!(ROUND(NVL(m.tnDiscRonCurent,0), gnPc) == ROUND(toSnapshot.discount_ron, gnPc)) OR ;
!(ROUND(NVL(m.tnDiscValCurent,0), gnPc) == ROUND(toSnapshot.discount_val, gnPc)) OR ;
NVL(toDate.discount_evidentiat,0) <> toSnapshot.discount_evidentiat
IF m.llSumeSchimbate
RETURN 1 && regenerare - implementarea propriu-zisa e S9
ENDIF
IF !AntetIdenticCuSnapshot(m.toSnapshot, m.toDate)
RETURN 2 && modifica_date_factura
ENDIF
IF ExplicatieLinieSchimbata(m.lcAlias)
RETURN 3 && modifica_explicatie_articol
ENDIF
RETURN 0 && nimic
ENDFUNC && AlegeRutaScriereEditare
*!* parametru: alias curent al liniilor (implicit crsfactura)
*!* .T. daca s-a adaugat/sters o linie sau s-a schimbat cantitate/pret/discount/tva/gestiune/lot/serie
*!* pe o linie existenta, comparat cu snap_linii_editare (cheie id_temp); precizie: gnPPretV pe
*!* pret/discount, gnPCant pe cantitate - nu pe valoarea bruta
FUNCTION LiniiAuSumeSchimbate
LPARAMETERS tcAlias
LOCAL lcAlias, llRezultat, lnAreaOrigine, lnIdTemp
lcAlias = IIF(TYPE('tcAlias') = 'C' AND !EMPTY(m.tcAlias), m.tcAlias, 'crsfactura')
IF !USED('snap_linii_editare') OR !USED(m.lcAlias)
RETURN .F.
ENDIF
lnAreaOrigine = SELECT()
llRezultat = .F.
*!* chei doar in snapshot => linie stearsa; chei doar in curent (sau id_temp = 0) => linie noua;
*!* daca reccount-urile coincid dar continutul difera (o stergere + o adaugare), scan-ul de mai
*!* jos gaseste oricum cheia din snapshot lipsa din curent
IF RECCOUNT('snap_linii_editare') <> RECCOUNT(m.lcAlias)
llRezultat = .T.
ELSE
SELECT snap_linii_editare
SCAN
lnIdTemp = id_temp
SELECT (m.lcAlias)
LOCATE FOR id_temp = m.lnIdTemp
IF !FOUND()
llRezultat = .T.
EXIT
ENDIF
IF !(ROUND(cantitate, gnPCant) == ROUND(snap_linii_editare.cantitate, gnPCant)) OR ;
!(ROUND(IIF(cu_tva=1,pretctva,pretftva), gnPPretV) == ROUND(IIF(snap_linii_editare.cu_tva=1,snap_linii_editare.pretctva,snap_linii_editare.pretftva), gnPPretV)) OR ;
!(ROUND(IIF(cu_tva=1,discountctva,discountftva), gnPPretV) == ROUND(IIF(snap_linii_editare.cu_tva=1,snap_linii_editare.discountctva,snap_linii_editare.discountftva), gnPPretV)) OR ;
!(ROUND(proc_tvav,4) == ROUND(snap_linii_editare.proc_tvav,4)) OR ;
NVL(id_articol,0) <> NVL(snap_linii_editare.id_articol,0) OR ;
NVL(id_gestiune,0) <> NVL(snap_linii_editare.id_gestiune,0) OR ;
ALLTRIM(NVL(lot,'')) <> ALLTRIM(NVL(snap_linii_editare.lot,'')) OR ;
ALLTRIM(NVL(serie,'')) <> ALLTRIM(NVL(snap_linii_editare.serie,''))
llRezultat = .T.
EXIT
ENDIF
SELECT snap_linii_editare
ENDSCAN
ENDIF
IF m.lnAreaOrigine > 0
SELECT (m.lnAreaOrigine)
ENDIF
RETURN m.llRezultat
ENDFUNC && LiniiAuSumeSchimbate
*!* .T. daca oricare din cei 14 parametri de antet difera fata de snapshot (comparatie simetrica NVL)
FUNCTION AntetIdenticCuSnapshot
LPARAMETERS toSnapshot, toDate
RETURN (NVL(toDate.id_ruta,0) == toSnapshot.id_ruta) AND ;
(NVL(toDate.id_delegat,0) == toSnapshot.id_delegat) AND ;
(NVL(toDate.id_agent,0) == toSnapshot.id_agent) AND ;
(NVL(toDate.id_masina,0) == toSnapshot.id_masina) AND ;
(NVL(toDate.dataora_exp,{}) == toSnapshot.dataora_exp) AND ;
(NVL(toDate.id_facturare,0) == toSnapshot.id_facturare) AND ;
(NVL(toDate.nListareDetaliata,0) == toSnapshot.listare_detaliata) AND ;
(NVL(toDate.text_aditional,'') == toSnapshot.text_aditional) AND ;
(NVL(toDate.tip_saft,0) == toSnapshot.tip_saft) AND ;
(NVL(toDate.eFactura,0) == toSnapshot.efactura) AND ;
(NVL(toDate.dataact,{}) == toSnapshot.data_act) AND ;
(NVL(toDate.datascad,{}) == toSnapshot.data_scad) AND ;
(NVL(toDate.nract,0) == toSnapshot.numar_act) AND ;
(NVL(toDate.serie_act,'') == toSnapshot.serie_act)
ENDFUNC && AntetIdenticCuSnapshot
*!* .T. daca s-a schimbat explicatia sau taxcode-ul pe cel putin o linie existenta (fara alte schimbari -
*!* apelat doar dupa ce LiniiAuSumeSchimbate a intors .F.)
FUNCTION ExplicatieLinieSchimbata
LPARAMETERS tcAlias
LOCAL lcAlias, llRezultat, lnAreaOrigine, lnIdTemp
lcAlias = IIF(TYPE('tcAlias') = 'C' AND !EMPTY(m.tcAlias), m.tcAlias, 'crsfactura')
IF !USED('snap_linii_editare') OR !USED(m.lcAlias)
RETURN .F.
ENDIF
lnAreaOrigine = SELECT()
llRezultat = .F.
SELECT snap_linii_editare
SCAN
lnIdTemp = id_temp
SELECT (m.lcAlias)
LOCATE FOR id_temp = m.lnIdTemp
IF FOUND() AND (ALLTRIM(NVL(explicatie,'')) <> ALLTRIM(NVL(snap_linii_editare.explicatie,'')) OR ;
NVL(taxcode,0) <> NVL(snap_linii_editare.taxcode,0) OR ;
NVL(id_jtva_coloana,0) <> NVL(snap_linii_editare.id_jtva_coloana,0))
llRezultat = .T.
EXIT
ENDIF
SELECT snap_linii_editare
ENDSCAN
IF m.lnAreaOrigine > 0
SELECT (m.lnAreaOrigine)
ENDIF
RETURN m.llRezultat
ENDFUNC && ExplicatieLinieSchimbata
*!* parametri: poDate curent (antet complet), poSnapshotEditare (id-ul real al documentului - vezi
*!* CreeazaSnapshotEditare); scrie cei 14 parametri prin modifica_date_factura, acelasi tipar SQL ca
*!* frm_facturi.do_modifica (ofacturare_comun.vc2:4705-4726) - fara tranzactie manuala, la fel ca
*!* apelantul copiat; .T. la succes, .F. la eroare Oracle sau la id de document lipsa (cu amessagebox)
FUNCTION ScrieAntetEditare
LPARAMETERS toDate, toSnapshot
LOCAL lcSql, lnSucces
*!* PRIVATE, nu LOCAL: parametrii legati (?) din TEXT TO se rezolva in scopul in care ruleaza
*!* goExecutor.oExecute, nu in cel al acestei functii - un LOCAL/LPARAMETERS e invizibil acolo si
*!* SQLExec ramane agatat (acelasi idiom ca poRec in frm_facturi.do_modifica, Private declarat)
PRIVATE poRecEditare, lnTipSaft
IF VARTYPE(toSnapshot) <> 'O' OR EMPTY(NVL(toSnapshot.id_vanzare,0)) OR toSnapshot.id_vanzare = 9999999999
amessagebox('Documentul editat nu are un id valid - nimic nu a fost scris.',16,'Eroare')
RETURN .F.
ENDIF
poRecEditare = toDate
*!* tip_saft = 0 inseamna nesetat (documente vechi, dinainte de SAFT) - se scrie NULL, nu 0, la fel
*!* ca frm_facturi.do_modifica (ofacturare_comun.vc2:4701-4703)
lnTipSaft = poRecEditare.tip_saft
IF NVL(m.lnTipSaft,0) = 0
lnTipSaft = .NULL.
ENDIF
TEXT TO lcSql NOSHOW TEXTMERGE
begin pack_facturare.modifica_date_factura(<<Alltrim(Str(toSnapshot.id_vanzare))>>,
<<Alltrim(Nvl(Str(toDate.id_ruta),[NULL]))>>,
<<Alltrim(Nvl(Str(toDate.id_delegat),[NULL]))>>,
<<Alltrim(Nvl(Str(toDate.id_agent),[NULL]))>>,
<<Alltrim(Nvl(Str(toDate.id_masina),[NULL]))>>,
to_date('<<TTOC(toDate.dataora_exp,1)>>','YYYYMMDDHH24:MI:SS'),
<<Alltrim(Nvl(Str(toDate.id_facturare),[NULL]))>>,
<<ALLTRIM(STR(NVL(toDate.nListareDetaliata,0)))>>,
?poRecEditare.text_aditional,
?lnTipSaft,
?poRecEditare.eFactura,
?poRecEditare.dataact,
?poRecEditare.datascad,
?poRecEditare.nract,
?poRecEditare.serie_act);
end;
ENDTEXT
lnSucces = goExecutor.oExecute(lcSql)
IF lnSucces < 0
amessagebox(goExecutor.oPrelucrareEroare(),16,"Eroare")
RETURN .F.
ENDIF
RETURN .T.
ENDFUNC && ScrieAntetEditare
*!* parametru: alias curent al liniilor (crsfactura); scrie explicatia/taxcode pe fiecare linie
*!* modificata fata de snap_linii_editare, prin modifica_explicatie_articol - acelasi tipar SQL ca
*!* frm_modifica_articol_factura.inainte_de_do_termin (ofacturare_comun.vc2:5407-5409); se opreste
*!* la primul esec Oracle (.F.), fara tranzactie manuala
FUNCTION ScrieExplicatieEditare
LPARAMETERS tcAlias
LOCAL lcAlias, lnAreaOrigine, lnIdTemp, lcSql, llSucces
*!* PRIVATE, nu LOCAL - vezi ScrieAntetEditare: ?lnTaxcodeEditare trebuie vizibil din interiorul
*!* goExecutor.oExecuta; acelasi tipar ca ?poRec.taxcode in frm_modifica_articol_factura
PRIVATE lnTaxcodeEditare
lcAlias = IIF(TYPE('tcAlias') = 'C' AND !EMPTY(m.tcAlias), m.tcAlias, 'crsfactura')
IF !USED('snap_linii_editare') OR !USED(m.lcAlias)
RETURN .T.
ENDIF
lnAreaOrigine = SELECT()
llSucces = .T.
SELECT snap_linii_editare
SCAN
lnIdTemp = id_temp
SELECT (m.lcAlias)
LOCATE FOR id_temp = m.lnIdTemp
IF FOUND() AND (ALLTRIM(NVL(explicatie,'')) <> ALLTRIM(NVL(snap_linii_editare.explicatie,'')) OR ;
NVL(taxcode,0) <> NVL(snap_linii_editare.taxcode,0) OR ;
NVL(id_jtva_coloana,0) <> NVL(snap_linii_editare.id_jtva_coloana,0))
lnTaxcodeEditare = taxcode
lcSql = [begin pack_facturare.modifica_explicatie_articol(] + Alltrim(Str(m.lnIdTemp)) + [,] + ;
['] + Nvl(Alltrim(OracleSpecialCharacters(explicatie)),'') + [',?gnIdUtil,?lnTaxcodeEditare,] + ;
Iif(Isnull(id_jtva_coloana),[null],Alltrim(Str(id_jtva_coloana))) + [); end;]
llSucces = goExecutor.oExecuta(lcSql)
IF !m.llSucces
EXIT
ENDIF
ENDIF
SELECT snap_linii_editare
ENDSCAN
IF m.lnAreaOrigine > 0
SELECT (m.lnAreaOrigine)
ENDIF
RETURN m.llSucces
ENDFUNC && ScrieExplicatieEditare
*!* parametru: toDate (oDateFactura incarcat pentru editare - IncarcaAntetFacturaEditare populeaza deja
*!* cListaSursa - comanda/contract - si cListaSursaAvize - avize, din VANZARI_CORESP TIP=1; S9 §1.5/1.7)
*!* intoarce lista de refurnizat ca poDate.listaid la reemitere, aleasa dupa tip - acelasi CASE ca
*!* dispecerizarea de scriere din do_scrie_factura (ofacturare.vc2:20171,20214,20249): avize (Tip=4)
*!* -> cListaSursaAvize; comenzi (3,21,25,28,42,47) -> cListaSursa; restul (contract/ELSE) -> '' (nu
*!* foloseau listaid la emiterea normala nici azi)
*!* .NULL. de toDate => ''; nu modifica toDate - apelantul decide cand scrie rezultatul pe poDate.listaid
FUNCTION CalculeazaListaidReemitere
LPARAMETERS toDate
IF VARTYPE(toDate) <> 'O'
RETURN ''
ENDIF
DO CASE
CASE toDate.tip = 4
RETURN ALLTRIM(NVL(toDate.cListaSursaAvize, ''))
CASE INLIST(toDate.tip, 3, 21, 25, 28, 42, 47)
RETURN ALLTRIM(NVL(toDate.cListaSursa, ''))
OTHERWISE
RETURN ''
ENDCASE
ENDFUNC && CalculeazaListaidReemitere
*!* piciorul de stergere extras din ofacturare_comun.vc2:4837-4977 (frm_facturi.do_sterge), parametrizat -
*!* fara UI (fara confirmare "sunteti sigur", fara refresh de grid) si fara tranzactie proprie:
*!* nici SQLSetprop, nici COMMIT/ROLLBACK cand apelantul are deja Transactions=2 -
*!* oscrie_in_fisiere e deja transaction-aware (oscrie_in_fisiere.prg:111-117): daca apelantul a
*!* deschis deja Transactions=2 inainte de a chema aceasta functie, intra in aceeasi tranzactie
*!* (necesar pentru S9-4, stergere+reemitere atomic); altfel fiecare pas isi face singur commit
*!* oscrie_in_fisiere posteaza reversarea sub perioada globala activa gnAn/gnLuna (linia lui interna,
*!* neschimbabila de aici) - de-aia interogarea vact_tot/vrul_tot si sterge_factura raman pe gnAn/gnLuna
*!* ca in original, iar tnAn/tnLuna (perioada documentului) intra doar la finalizeaza_stergere_nota,
*!* exact ca pnAn/pnLuna in do_sterge - garda de mai jos impune egalitatea, ca in do_sterge original
*!* tnIdUtil optional - implicit gnIdUtil daca nu e transmis
*!* tnIdSetVechi, tnIdFdocVechi, tdDataIregVechi optionale, prin referinta: id_set-ul, felul de
*!* document si data inregistrarii contabile ale notei sterse, citite din acelasi cursor;
*!* raman neatinse daca documentul nu are nota contabila
*!* intoarce .T. daca documentul a fost sters (cu sau fara reversare de stoc), .F. la eroare sau garda
FUNCTION StergeDocumentFacturare
LPARAMETERS tnIdVanzare, tnCod, tnAn, tnLuna, tnIdUtil, tnIdSetVechi, tnIdFdocVechi, tdDataIregVechi
LOCAL lcSql, lcCursor, lcConditieSters, llRul, llSucces, lnIdSet, lnIdFact, lnIdFactD
LOCAL lcCaleDateMenu, lnRezOscrie
*!* PRIVATE - legate cu ? in SQL trimis prin goExecutor, invizibile ca LPARAMETERS in scopul lui oExecuta
PRIVATE pnIdVanzareSterge, pnAnSterge, pnLunaSterge, pnIdUtilSterge
pnIdVanzareSterge = NVL(tnIdVanzare, 0)
pnAnSterge = NVL(tnAn, 0)
pnLunaSterge = NVL(tnLuna, 0)
pnIdUtilSterge = NVL(tnIdUtil, gnIdUtil)
IF EMPTY(m.pnIdVanzareSterge) OR EMPTY(m.pnAnSterge) OR EMPTY(m.pnLunaSterge)
RETURN .F.
ENDIF
*!* aceeasi garda "luna curenta" ca in do_sterge (ofacturare_comun.vc2:4809) - obligatorie, nu doar UI:
*!* oscrie_in_fisiere posteaza mereu sub gnAn/gnLuna, indiferent ce se cere aici
IF (m.pnAnSterge * 12) + m.pnLunaSterge <> (gnAn * 12) + gnLuna
RETURN .F.
ENDIF
llRul = .F.
llSucces = .F.
lcConditieSters = [ STERS = 0 AND ]
Use In (SELECT('actactan'))
lcSql = [select * from ] + gcs + [.vact_tot where ] + lcConditieSters + [ an = ] + Transform(gnAn) + [ and luna = ] + Transform(gnLuna) + [ and cod = ] + Alltrim(Str(m.tnCod)) + [ order by id_act]
lcCursor = [v_act]
IF goExecutor.oExecuta(lcSql, lcCursor)
Select * From v_act Into Cursor actactan
Use In v_act
lcSql = [select * from ] + gcs + [.vrul_tot where ] + lcConditieSters + [ an = ] + Transform(gnAn) + [ and luna = ] + Transform(gnLuna) + [ and cod = ] + Alltrim(Str(m.tnCod)) + [ order by id_rul]
lcCursor = [v_rul]
IF goExecutor.oExecuta(lcSql, lcCursor)
IF Reccount(lcCursor) > 0
llRul = .T.
ENDIF
lcSql = [select * from ] + gcs + [.vrul_obinv_tot where ] + lcConditieSters + [ an = ] + Transform(gnAn) + [ and luna = ] + Transform(gnLuna) + [ and cod = ] + Alltrim(Str(m.tnCod)) + [ order by id_rul_obinv]
lcCursor = [v_rul_obinv]
IF goExecutor.oExecuta(lcSql, lcCursor)
IF Reccount(lcCursor) > 0
llRul = .T.
ENDIF
Select * From v_rul Into Cursor rul_temp
Use In v_rul
Select * From v_rul_obinv Into Cursor rul_temp_obinv
Use In v_rul_obinv
IF Reccount('actactan') > 0
lcCaleDateMenu = gcAppPath + [\COMUN\DATEMENU\]
IF !Used('INFISIERE')
Use &lcCaleDateMenu.INFISIERE In 0 Alias INFISIERE
ENDIF
lnRezOscrie = OSCRIE_IN_FISIERE(2, .F., m.llRul)
IF Used('infisiere')
Use In INFISIERE
ENDIF
IF lnRezOscrie < 0
IF lnRezOscrie <> -5
amessagebox(goExecutor.cEroare, 0+16, "Eroare")
ENDIF
ELSE
Select actactan
GO top
lnIdSet = id_set
*!* VARTYPE, nu PARAMETERS() - acesta din urma raporteaza ultimul apel imbricat
IF VARTYPE(m.tnIdSetVechi) = 'N'
tnIdSetVechi = m.lnIdSet
ENDIF
IF VARTYPE(m.tnIdFdocVechi) = 'N' AND !Isnull(id_fdoc)
tnIdFdocVechi = id_fdoc
ENDIF
IF Inlist(VARTYPE(m.tdDataIregVechi), 'D', 'T') AND !Isnull(dataireg)
tdDataIregVechi = dataireg
ENDIF
lnIdFact = id_fact
lnIdFactD = id_factd
lcSql = [begin pack_contafin.finalizeaza_stergere_nota(?pnLunaSterge,?pnAnSterge,Null,] + Alltrim(Str(m.lnIdSet)) + [,] + ;
Alltrim(Str(m.tnCod)) + [,] + Alltrim(Str(m.lnIdFact)) + [,] + Alltrim(Str(m.lnIdFactD)) + [,?pnIdUtilSterge); end;]
IF goExecutor.oExecuta(lcSql)
llSucces = .T.
ENDIF
ENDIF
*!* doar cand apelantul nu are deja o tranzactie manuala deschisa - altfel COMMIT-ul
*!* ar inchide-o inainte ca apelantul sa-si termine propria scriere
IF SQLGetprop(gnHandle, "Transactions") <> 2
goExecutor.oExecuta(IIF(m.llSucces, "COMMIT", "ROLLBACK"))
ENDIF
ELSE
lcSql = [begin ] + gcs + [.pack_facturare.sterge_factura(?pnIdVanzareSterge,?gnLuna,?gnAn,?pnIdUtilSterge); end;]
llSucces = goExecutor.oExecuta(lcSql)
ENDIF
ENDIF
ENDIF
ENDIF
IF Used('actactan')
Use In actactan
ENDIF
IF Used('rul_temp')
Use In rul_temp
ENDIF
IF Used('rul_temp_obinv')
Use In rul_temp_obinv
ENDIF
RETURN m.llSucces
ENDFUNC && StergeDocumentFacturare
*!* impune ID_FACT-ul documentului vechi pentru reemiterea curenta, tintit pe grupul (nract, serie_act)
*!* al facturii - bucla din SCRIE_IN_ACT parcurge si grupul de incasare, care poate fi primul cand
*!* chitanta are aceeasi serie ca factura (masurat: docs\propunere_s9_7_cablare_idfact.md sectiunea 1.5)
*!* literale, nu bind ? - bind-ul prin goExecutor se leaga de PRIVATE/PUBLIC, nu de LOCAL/LPARAMETERS
*!* .F. daca id-ul lipseste (document fara nota contabila) sau daca apelul Oracle a picat
FUNCTION ForteazaIdFactReemitere
LPARAMETERS tnIdFact, tnNract, tcSerieAct
IF EMPTY(NVL(m.tnIdFact, 0))
RETURN .F.
ENDIF
RETURN goExecutor.oExecuta([begin pack_contafin.nIdFactFortat := ] + ALLTRIM(STR(m.tnIdFact,14,0)) + ;
[; pack_contafin.nNractFortat := ] + ALLTRIM(STR(NVL(m.tnNract,0),14,0)) + ;
[; pack_contafin.cSerieFortata := ] + ;
IIF(EMPTY(NVL(m.tcSerieAct,[])), [NULL], ['] + OracleSpecialCharacters(ALLTRIM(m.tcSerieAct)) + [']) + ;
[; end;])
ENDFUNC && ForteazaIdFactReemitere
*!* sterge fortarea din sesiunea Oracle: ROLLBACK nu reseteaza starea PL/SQL de pachet, iar gnHandle
*!* traieste cat aplicatia - o reemitere picata ar contamina documentul urmator al aceluiasi utilizator
*!* no-op in afara regenerarii, ca sa nu coste un apel pe drumul normal de scriere
FUNCTION CurataIdFactFortat
IF TYPE('plRegenerareEditare') <> 'L' OR !plRegenerareEditare
RETURN .T.
ENDIF
RETURN goExecutor.oExecuta([begin pack_contafin.nIdFactFortat := NULL; ] + ;
[pack_contafin.nNractFortat := NULL; pack_contafin.cSerieFortata := NULL; end;])
ENDFUNC && CurataIdFactFortat
*!* impune id_util/dataora ale creatiei documentului vechi la reemitere - simetric cu ForteazaIdFactReemitere,
*!* dar pe variabile proprii PACK_FACTURARE (nid_util_fortat/ddataora_fortata), resetate de
*!* initializeaza_date_factura: apelul trebuie facut DUPA acel apel, altfel e inert
*!* .F. daca id_util lipseste (document fara creator) sau daca apelul Oracle a picat
FUNCTION ForteazaAuditCreareReemitere
LPARAMETERS tnIdUtil, tdDataora
IF EMPTY(NVL(m.tnIdUtil, 0))
RETURN .F.
ENDIF
RETURN goExecutor.oExecuta([begin pack_facturare.nid_util_fortat := ] + ALLTRIM(STR(m.tnIdUtil,14,0)) + ;
[; pack_facturare.ddataora_fortata := ] + ;
IIF(EMPTY(NVL(m.tdDataora,{})), [NULL], [to_date(']+TTOC(m.tdDataora,1)+[','YYYYMMDDHH24MISS')]) + ;
[; end;])
ENDFUNC && ForteazaAuditCreareReemitere
*!* sterge fortarea auditului de creare din sesiunea Oracle - simetric cu CurataIdFactFortat
*!* no-op in afara regenerarii, ca sa nu coste un apel pe drumul normal de scriere
FUNCTION CurataAuditCreareFortat
IF TYPE('plRegenerareEditare') <> 'L' OR !plRegenerareEditare
RETURN .T.
ENDIF
RETURN goExecutor.oExecuta([begin pack_facturare.nid_util_fortat := NULL; ] + ;
[pack_facturare.ddataora_fortata := NULL; end;])
ENDFUNC && CurataAuditCreareFortat
*!* parametri: id_vanzare vechi si nou; muta randurile de borderou eFactura ale documentului
*!* regenerat pe id-ul nou - FACT_BORDEROU_DETALII n-are STERS, iar FACT_VBORDEROU_DETALII nu
*!* filtreaza vanzari.sters, deci fara mutare borderoul ar afisa in continuare valorile
*!* documentului sters, cu serie si numar corecte
*!* UPDATE fara randuri potrivite = succes; .F. doar la eroare Oracle sau id lipsa
FUNCTION MutaBorderouReemitere
LPARAMETERS tnIdVanzareVechi, tnIdVanzareNou
IF EMPTY(NVL(m.tnIdVanzareVechi,0)) OR EMPTY(NVL(m.tnIdVanzareNou,0))
RETURN .F.
ENDIF
RETURN goExecutor.oExecuta([update ] + gcs + [.fact_borderou_detalii set id_vanzare = ] + ;
ALLTRIM(STR(m.tnIdVanzareNou,14,0)) + [ where id_vanzare = ] + ;
ALLTRIM(STR(m.tnIdVanzareVechi,14,0)))
ENDFUNC && MutaBorderouReemitere