git-svn-id: svn://10.65.10.50/branches/R_10_00@22925 c028cbd2-c16b-5b4b-a496-9718f37d4682
556 lines
18 KiB
C++
Executable File
556 lines
18 KiB
C++
Executable File
// Programma di gestione provvigioni
|
|
#include <applicat.h>
|
|
#include <msksheet.h>
|
|
|
|
#include "../ve/velib.h"
|
|
#include "prlib.h"
|
|
#include "provv.h"
|
|
#include "pr0700a.h"
|
|
#include "pr0700b.h"
|
|
#include "pr0.h"
|
|
|
|
class TGestione_provv_app : public TSkeleton_application
|
|
{
|
|
TMask *_msk;
|
|
TProvvigioni_agente *_prag;
|
|
TAssoc_array _vittime;
|
|
bool _dirty;
|
|
|
|
protected:
|
|
virtual bool create();
|
|
virtual bool destroy();
|
|
virtual void main_loop();
|
|
|
|
void kill_vittime();
|
|
void load_provvigioni(TMask* m);
|
|
void fill_sheet_doc();
|
|
bool check_totals();
|
|
static bool doc_sheet_notify(TSheet_field& ds, int r, KEY key);
|
|
static bool rate_sheet_notify(TSheet_field& rs, int r, KEY key);
|
|
static bool nrata_handler(TMask_field& f, KEY key);
|
|
static bool ndoc_handler(TMask_field& f, KEY key);
|
|
static bool calcola_rate_handler(TMask_field& f, KEY k);
|
|
static bool datascad_handler(TMask_field& f, KEY key);
|
|
static bool imprata_handler(TMask_field& f, KEY key);
|
|
static bool improvv_handler(TMask_field& f, KEY key);
|
|
static bool enable_handler(TMask_field& f, KEY k);
|
|
static void fill_rate_doc(TRate_doc& rd, TSheet_field& sf);
|
|
public:
|
|
};
|
|
|
|
static inline TGestione_provv_app& app() { return (TGestione_provv_app&) main_app(); }
|
|
static TString16 __current_key;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
// Da fare :
|
|
// - Quando si elimina l'ultima riga dello spreadsheet si posiziona sulla prima senza
|
|
// mandare un K_TAB per aggiornare le rate
|
|
// - Browse dei documenti in ricerca, quando si seleziona setta giustamente focusdirty() e manda
|
|
// un K_TAB. Quando si tenta di uscire dal campo si ha ancora il campo focusdirty()
|
|
// - Cercare di implementare scarico/saldo righe provvigionali per agente in base ad una
|
|
// impostata
|
|
// - Ultimo ma non meno importante (da ritenersi visualmente valido) lo riempimento fisso
|
|
// degli sheet (documenti e rate) in modo da evitare il fastidiosissimo sfarfallio in
|
|
// inserimento righe con elementi vuoti
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
bool TGestione_provv_app::calcola_rate_handler(TMask_field& f, KEY key)
|
|
{
|
|
// - Impostazione importi e provvigioni (documento) in caso di selezione documento
|
|
// - Calcolo righe di provvigioni in caso di selezione documento (integrato in TDocumento)
|
|
// - Rata 0 : importo rata = 0; importo provvigione = provvigione all'atto della fattura (percentuale sugli agenti)
|
|
// la provvigione rimanente va suddivisa in rate a seconda del codice pagamento
|
|
if (f.focusdirty() && key == K_TAB)
|
|
{
|
|
TMask& m = f.mask();
|
|
TSheet_field & rs = (TSheet_field&)app()._msk->field(F_RATE_SHEET);// Resetta lo spreadsheet
|
|
if (rs.items() > 0) // Resetta lo spreadsheet se vi sono delle righe
|
|
rs.reset();
|
|
TDocumento doc;
|
|
const int anno = m.get_int(F_ANNO);
|
|
const long numdoc = m.get_long(F_NDOC);
|
|
const TString& codnum = m.get(F_CODNUM);
|
|
const int err = doc.read('D', anno, (const char*) codnum, numdoc);
|
|
|
|
if (err == NOERR)
|
|
{
|
|
const TString8 agente = app()._msk->get(F_CODAGE);
|
|
const bool first = agente == doc.get(DOC_CODAG);
|
|
|
|
m.set(F_DATADOC, doc.data());
|
|
m.set(F_CLIENTE, doc.codcf());
|
|
m.set(F_CODVAL,doc.valuta());
|
|
m.set(F_CAMBIO,doc.cambio());
|
|
m.set(F_DATACAMBIO,doc.get_date(DOC_DATACAMBIO));
|
|
m.set(F_IMPDOC,doc.totale_doc());
|
|
m.set(F_IMPPRDOC,doc.provvigione(first));
|
|
m.set(F_IMPNETDOC, doc.totale_netto());
|
|
// Adesso calcoliamo la provvigione all'atto della fatturazione da inserire
|
|
// nella rata 0. Il residuo va ripartito nelle rate del documento
|
|
TProvvigioni_agente pra;
|
|
|
|
doc.calc_provvigione(pra, agente, first, false); // Non settare il flag di generata dal documento!
|
|
|
|
// Adesso genera le righe da mettere nello spreadsheet. Quando si uscira' dalla riga
|
|
// attuale verra' chiamata la doc_sheet_notify() con K_ENTER, che memorizza il tutto
|
|
// gestendo automaticamente la eventuale modifica di un documento gia' presente o meno.
|
|
|
|
TRate_doc& rd = pra.rate(doc.anno(), m.get(F_CODNUM), doc.numero()); // Estrae le rate appena calcolate
|
|
const int numrate = rd.items(); /* Numero rate per questo documento */
|
|
for (int i = 0; i < numrate; i++)
|
|
{
|
|
TToken_string& ttt = rs.row(i);
|
|
TRata& rt = rd[i];
|
|
ttt.add(rt.rata()); // Numero di rata
|
|
ttt.add(rt.datascad()); // Data scadenza della rata
|
|
ttt.add(rt.tipopag()); // Tipo pag per questa rata
|
|
ttt.add(rt.imprata().string()); // Importo della rata (occhio alla valuta)
|
|
ttt.add(rt.impprovv().string()); // Importo della provvigione per questa rata
|
|
ttt.add(""); // Tutti gli altri valori sono a 0
|
|
ttt.add(""); ttt.add(""); ttt.add("");
|
|
ttt.add(""); ttt.add("");
|
|
ttt.add(rt.codval());
|
|
}
|
|
rs.force_update();
|
|
f.set_focusdirty(FALSE);
|
|
f.set_dirty(FALSE);
|
|
}
|
|
else
|
|
return f.error_box(TR("Errore %d tentando di leggere il documento specificato"),err);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
bool TGestione_provv_app::ndoc_handler(TMask_field& f, KEY key)
|
|
{
|
|
if (key == K_ENTER) // Quando sta cambiando riga...
|
|
{ // Scorre tutte le righe dello spreadsheet esaminando ANNO+CODNUM+NDOC
|
|
// nel caso trovi un'altra riga con la stessa chiave, visualizza un errore
|
|
TSheet_field& s = *f.mask().get_sheet();
|
|
const int selected = s.selected();
|
|
const int items = s.items(); // Numero di righe dello spreadsheet
|
|
TToken_string& tt = s.row(selected);
|
|
int anno = tt.get_int(0);
|
|
TString codnum = tt.get(1);
|
|
long ndoc = tt.get_long(2);
|
|
TString key,other_key;
|
|
|
|
key.format("%4d%4s%7ld",anno,(const char*)codnum,ndoc);
|
|
for (int i = 0; i < items; i++)
|
|
if (i != selected)
|
|
{
|
|
TToken_string& ot = s.row(i);
|
|
anno = ot.get_int(0);
|
|
codnum = ot.get(1);
|
|
ndoc = ot.get_long(2);
|
|
other_key.format("%4d%4s%7ld",anno,(const char*)codnum,ndoc);
|
|
if (key == other_key)
|
|
return f.error_box(TR("Non e' possibile inserire due documenti con la stessa chiave"));
|
|
}
|
|
}
|
|
return calcola_rate_handler(f, key);
|
|
}
|
|
|
|
bool TGestione_provv_app::nrata_handler(TMask_field& f, KEY key)
|
|
{
|
|
if (key == K_ENTER)
|
|
{ // Scorre tutte le righe dello spreadsheet esaminando il numero di rata
|
|
// nel caso trovi un'altra riga con lo stesso numero, visualizza un errore
|
|
const int nrata = atoi(f.get());
|
|
TSheet_field& s = *f.mask().get_sheet();
|
|
const int selected = s.selected();
|
|
const int items = s.items(); // Numero di righe dello spreadsheet
|
|
for (int i = 0; i < items; i++)
|
|
if (i != selected)
|
|
{
|
|
int other_rata = s.row(i).get_int(0);
|
|
if (nrata == other_rata)
|
|
return f.error_box(TR("Non e' possibile inserire due rate con lo stesso numero"));
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
bool TGestione_provv_app::datascad_handler(TMask_field& f, KEY key)
|
|
{
|
|
if (key == K_ENTER && __current_key.not_empty())
|
|
{
|
|
TProvvigioni_agente* pa = app()._prag;
|
|
TRate_doc& rd = pa->rate(__current_key);
|
|
TDate d(f.get());
|
|
if (d < rd.datadoc())
|
|
return f.error_box(TR("La data di scadenza deve essere maggiore o uguale della data documento"));
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
// Abilita le colonne PAGATO e PROVVPAG per evntuale editing degli importi
|
|
bool TGestione_provv_app::enable_handler(TMask_field& f, KEY key)
|
|
{
|
|
if (key == K_SPACE)
|
|
{
|
|
TMask& m = f.mask();
|
|
m.enable(-5, !m.field(F_PROVVPAG).active());
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool TGestione_provv_app::imprata_handler(TMask_field& f, KEY key)
|
|
{
|
|
if (key == K_ENTER && __current_key.not_empty())
|
|
{
|
|
TProvvigioni_agente* pa = app()._prag;
|
|
TRate_doc& rd = pa->rate(__current_key);
|
|
real r(f.get());
|
|
r = abs(r);
|
|
if (r > abs(rd.impdoc()))
|
|
return f.error_box(TR("L'importo della rata non puo' essere maggiore dell'importo del documento"));
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
bool TGestione_provv_app::improvv_handler(TMask_field& f, KEY key)
|
|
{
|
|
if (key == K_ENTER && __current_key.not_empty())
|
|
{
|
|
TProvvigioni_agente* pa = app()._prag;
|
|
TRate_doc& rd = pa->rate(__current_key);
|
|
real r(f.get());
|
|
r = abs(r);
|
|
if (r > abs(rd.impprdoc()))
|
|
return f.error_box(TR("L'importo della provvigione non puo' essere maggiore dell'importo provvigione del documento"));
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
void TGestione_provv_app::fill_rate_doc(TRate_doc& rd, TSheet_field& sf)
|
|
{
|
|
// Righe delle rate
|
|
const int items = sf.items();
|
|
rd.remove_rata(); // cancella tutte le rate
|
|
for (int i = 0; i < items; i++) // Aggiunge le rate presenti nello sheet
|
|
{
|
|
TToken_string& tt = sf.row(i);
|
|
TRata* rt = new TRata;
|
|
rt->set(tt);
|
|
rd.add_rata(rt);
|
|
}
|
|
}
|
|
|
|
bool TGestione_provv_app::rate_sheet_notify(TSheet_field& ds, int r, KEY key)
|
|
{
|
|
TProvvigioni_agente* pa = app()._prag;
|
|
if (__current_key.empty() || pa->items() == 0)
|
|
return true;
|
|
|
|
TRate_doc& rd = pa->rate(__current_key);
|
|
|
|
switch (key)
|
|
{
|
|
case K_INS: // Inserimento di una nuova rata vuota
|
|
{
|
|
TRata* rt = new TRata;
|
|
// Nuova rata: va segnalata come inserita (generata = blank)
|
|
rd.add_rata(rt);
|
|
app()._dirty = true;
|
|
}
|
|
break;
|
|
case K_ENTER: // Notifica dell'avvenuta modifica di una rata
|
|
{
|
|
TRata& rt = rd[r]; // Sostituisce i valori della riga corrente
|
|
rt.set(ds.row(r));
|
|
app()._dirty = true;
|
|
}
|
|
break;
|
|
case K_DEL: // Notifica della cancellazione di una riga
|
|
rd.remove_rata(r);
|
|
rd.pack_rate(); // Effettua anche il pack degli elementi (corrispondenza 1 a 1 tra sheet ed array)
|
|
app()._dirty = true;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool TGestione_provv_app::doc_sheet_notify(TSheet_field& ds, int r, KEY key)
|
|
{
|
|
TProvvigioni_agente* pa = app()._prag;
|
|
|
|
switch (key)
|
|
{
|
|
case K_INS: // Inserimento di un nuovo documento
|
|
{
|
|
TSheet_field& rs = ds.mask().sfield(F_RATE_SHEET);
|
|
if (rs.items() > 0) // Resetta lo spreadsheet se vi sono delle righe
|
|
rs.reset();
|
|
app()._dirty = TRUE;
|
|
}
|
|
break;
|
|
case K_TAB: // Posizionamento sulla riga r
|
|
// Visualizza le rate relative sull'apposito sheet
|
|
{
|
|
TMask& m = ds.mask();
|
|
if (!m.is_running())
|
|
break;
|
|
|
|
TToken_string& tt = ds.row(r);
|
|
int anno = tt.get_int(0);
|
|
TString4 codnum = tt.get(1);
|
|
long ndoc = tt.get_long(2);
|
|
TString4 codval = tt.get(8);
|
|
|
|
m.set(F_MANNO,anno);
|
|
m.set(F_MCODNUM,codnum);
|
|
m.set(F_MNDOC,ndoc);
|
|
m.set(F_MCODVAL, codval);
|
|
|
|
__current_key.format("%4d%4s%7ld",anno,(const char*)codnum,ndoc);
|
|
TSheet_field& rs = ds.mask().sfield(F_RATE_SHEET);
|
|
if (rs.items() > 0) // Resetta lo spreadsheet se vi sono delle righe precedenti
|
|
rs.reset();
|
|
TRate_doc& rd = pa->rate(__current_key,TRUE);
|
|
const int items = rd.items();
|
|
for (int i = 0; i < items; i++)
|
|
{
|
|
TRata& rt = rd[i];
|
|
TToken_string& ttt = rs.row(i);
|
|
ttt.add(rt.rata());
|
|
ttt.add(rt.datascad());
|
|
ttt.add(rt.tipopag());
|
|
ttt.add(rt.imprata().string());
|
|
ttt.add(rt.impprovv().string());
|
|
ttt.add(rt.pagmat().string());
|
|
ttt.add(rt.provvmat().string());
|
|
ttt.add(rt.pagato().string());
|
|
ttt.add(rt.provvpag().string());
|
|
ttt.add(rt.saldata() ? "X" : " ");
|
|
ttt.add(rt.tipopagpr());
|
|
ttt.add(rt.codval());
|
|
}
|
|
rs.force_update();
|
|
}
|
|
break;
|
|
case K_ENTER: // Abbandono della riga r (modificata). Analogamente va fatto sullo sheet delle rate
|
|
// Memorizza rate e documento
|
|
// Confronta la chiave della riga attuale con quella ricavata quando ci si e'
|
|
// posizionati sopra.
|
|
// Se __current_key non e' vuota viene rimosso il vecchio TRate_doc
|
|
// e aggiunto quello con la chiave nuova
|
|
{
|
|
TToken_string& tt = ds.row(r);
|
|
int anno = tt.get_int(0);
|
|
TString codnum = tt.get(1);
|
|
long ndoc = tt.get_long(2);
|
|
|
|
TString k;
|
|
k.format("%4d%4s%7ld",anno,(const char*)codnum,ndoc);
|
|
bool flag = FALSE;
|
|
|
|
if (__current_key != k) // Se le chiavi sono diverse
|
|
{
|
|
TAssoc_array& vitt = app()._vittime;
|
|
if (__current_key.not_empty())
|
|
{
|
|
pa->remove_rate(__current_key); // Cancella il vecchio
|
|
vitt.add(__current_key);
|
|
}
|
|
__current_key = k;
|
|
if (vitt.is_key(k))
|
|
vitt.remove(k);
|
|
flag = TRUE;
|
|
}
|
|
TRate_doc& rd = pa->rate(k,flag); // Aggiunge il nuovo o prende lo stesso elemento
|
|
// Schiaffa dentro rate e dati documento
|
|
rd.set(tt);
|
|
fill_rate_doc(rd, ds.mask().sfield(F_RATE_SHEET));
|
|
app()._dirty = TRUE;
|
|
}
|
|
break;
|
|
case K_DEL: // Rimozione della riga r
|
|
// Rimuove il documento e le rate
|
|
pa->remove_rate(__current_key);
|
|
app()._vittime.add(__current_key);
|
|
__current_key.cut(0);
|
|
if (pa->items() == 0)
|
|
{
|
|
TSheet_field& rs = ds.mask().sfield(F_RATE_SHEET);
|
|
if (rs.items() > 0) // Resetta lo spreadsheet se vi sono delle righe
|
|
rs.reset();
|
|
}
|
|
app()._dirty = TRUE;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
bool TGestione_provv_app::create()
|
|
{
|
|
open_files(LF_PROVV, LF_CONDV, LF_RCONDV, LF_ANAMAG, LF_SCONTI, LF_UMART,
|
|
LF_TABCOM, LF_CLIFO,LF_INDSP, LF_MOVMAG, LF_RMOVMAG, LF_DOC,
|
|
LF_RIGHEDOC, LF_CFVEN, LF_OCCAS, LF_TAB, 0);
|
|
|
|
_msk = new TMask("pr0700b") ;
|
|
_prag = new TProvvigioni_agente;
|
|
TSheet_field & sf = _msk->sfield(F_DOC_SHEET);
|
|
sf.set_notify(doc_sheet_notify);
|
|
sf.sheet_mask().set_handler(F_NDOC,ndoc_handler);
|
|
TSheet_field & rs = _msk->sfield(F_RATE_SHEET);
|
|
rs.set_notify(rate_sheet_notify);
|
|
TMask& sm = rs.sheet_mask();
|
|
sm.set_handler(F_RATA,nrata_handler);
|
|
sm.set_handler(F_DATASCAD,datascad_handler);
|
|
sm.set_handler(F_IMPRATA,imprata_handler);
|
|
sm.set_handler(F_IMPPROVV,improvv_handler);
|
|
sm.set_handler(DLG_ENABLE,enable_handler);
|
|
|
|
return TSkeleton_application::create();
|
|
}
|
|
|
|
bool TGestione_provv_app::destroy()
|
|
{
|
|
delete _msk;
|
|
delete _prag;
|
|
return TRUE;
|
|
}
|
|
|
|
void TGestione_provv_app::fill_sheet_doc()
|
|
{
|
|
TString_array kl;
|
|
const int items = _prag->documenti(kl);
|
|
kl.sort(); // Cosi' i documenti sono in ordine
|
|
TSheet_field& sf = _msk->sfield(F_DOC_SHEET);
|
|
TSheet_field& rs = _msk->sfield(F_RATE_SHEET);
|
|
|
|
__current_key = "";
|
|
rs.reset();
|
|
sf.reset();
|
|
for (int i = 0; i < items; i++)
|
|
{
|
|
TRate_doc& rd = _prag->rate(kl.row(i));
|
|
TToken_string& tt = sf.row(i);
|
|
tt.add(rd.anno()); tt.add(rd.codnum());
|
|
tt.add(rd.ndoc()); tt.add(rd.datadoc());
|
|
tt.add(rd.impdoc().string());
|
|
tt.add(rd.impprdoc().string());
|
|
tt.add(rd.impnet().string());
|
|
tt.add(rd.codcf());
|
|
tt.add(rd.codval());
|
|
tt.add(rd.cambio().string());
|
|
tt.add(rd.datacam());
|
|
TToken_string key("C");
|
|
|
|
key.add(rd.codcf());
|
|
const TString & ragsoc = cache().get(LF_CLIFO, key, CLI_RAGSOC);
|
|
tt.add(ragsoc);
|
|
}
|
|
}
|
|
|
|
bool TGestione_provv_app::check_totals()
|
|
// Controlla che la somma delle provvigioni per ogni rata non sia superiore alla provvigione
|
|
// totale del documento. Ritorna TRUE se tutti i documenti hanno le provvigioni ok
|
|
{
|
|
TString_array kl;
|
|
const int items = _prag->documenti(kl);
|
|
bool rt = TRUE;
|
|
|
|
for (int i = 0; rt && i < items ; i++)
|
|
if (!_prag->rate(kl.row(i)).ok_provvigione())
|
|
{
|
|
rt = FALSE;
|
|
error_box(FR("La somma delle provvigioni supera l'importo della provvigione totale per il documento %s"),
|
|
(const char*)kl.row(i));
|
|
}
|
|
return rt;
|
|
}
|
|
|
|
void TGestione_provv_app::kill_vittime()
|
|
{
|
|
const TString16 agente = _msk->get(F_CODAGE);
|
|
TProvvigioni_agente prov;
|
|
FOR_EACH_ASSOC_OBJECT(_vittime, ass, key, doc)
|
|
{
|
|
const TFixed_string codice(key);
|
|
const int anno = atoi(codice.left(4));
|
|
const long ndoc = atol(codice.right(7));
|
|
TString16 codnum = codice.mid(4, 4); codnum.trim();
|
|
if (prov.read(agente, anno, codnum, ndoc) == NOERR)
|
|
prov.remove();
|
|
}
|
|
}
|
|
|
|
void TGestione_provv_app::load_provvigioni(TMask* m)
|
|
{
|
|
const TString16 agente = m->get(F_CODAGE);
|
|
const int anno = m->get_int(F_FILTERANNO);
|
|
|
|
_msk->set(F_CODAGE,agente);
|
|
_msk->set(F_RAGSOC,m->get(F_RAGSOC));
|
|
_msk->set(F_MANNO,"");
|
|
_msk->set(F_MCODNUM,"");
|
|
_msk->set(F_MNDOC,"");
|
|
if (_prag->read(agente, anno) == _islocked)
|
|
{
|
|
message_box(FR("Dati agente %s in uso da un altro utente."), (const char*) agente);
|
|
return;
|
|
}
|
|
|
|
KEY k;
|
|
bool repeat;
|
|
const char* msg = _prag->items() == 0 ? TR("Registrare i dati inseriti") : TR("Registrare le modifiche") ;
|
|
fill_sheet_doc(); // Inizializza lo sheet dei documenti
|
|
|
|
_dirty = false;
|
|
int err = NOERR;
|
|
do
|
|
{
|
|
k = _msk->run();
|
|
bool to_write = k == K_ENTER;
|
|
repeat = false;
|
|
if (k == K_ESC && _dirty)
|
|
{
|
|
k = yesnocancel_box(msg);
|
|
if (k == K_ESC)
|
|
repeat = true;
|
|
else if (k == K_YES)
|
|
to_write = true;
|
|
}
|
|
if (to_write)
|
|
{
|
|
if (check_totals()) // Controlla i totali delle provvigioni per tutti i documenti
|
|
{
|
|
kill_vittime(); // Cancella eventuali documenti eliminati dallo sheet
|
|
err = _prag->write();
|
|
}
|
|
else
|
|
repeat = true;
|
|
}
|
|
} while (repeat);
|
|
if (err != NOERR)
|
|
message_box(FR("Errore %d tentando di scrivere i dati provvigionali dell'agente %s."),err, (const char*) agente);
|
|
_prag->unlock();
|
|
}
|
|
|
|
void TGestione_provv_app::main_loop()
|
|
{
|
|
TMask* m = new TMask("pr0700a");
|
|
bool ok = true;
|
|
while (ok)
|
|
{
|
|
xvtil_statbar_set(TR("Ricerca"), true);
|
|
ok = m->run() == K_ENTER;
|
|
if (ok)
|
|
load_provvigioni(m);
|
|
}
|
|
delete m;
|
|
}
|
|
|
|
int pr0700(int argc, char** argv)
|
|
{
|
|
TGestione_provv_app a;
|
|
a.run(argc, argv, TR("Gestione provvigioni"));
|
|
return 0;
|
|
}
|