campo-sirio/pr/pr0700.cpp
guy fbce256e5d Patch level : 2.0 496
Files correlati     : pr0.exe pr0700b.msk pr1.exe pr1100.msk pr1100a.frm pr1300a.frm pr1300a.msk
Ricompilazione Demo : [ ]
Commento            :

GF20035
Le stampe vengono visualizzate, ma se vengono inviate alla stampante non
stampa nulla e poi uscendo dalle voci di menù appare il messaggio:
"PR1 questo programma ha eseguito un'operazione non valida e sarà terminato".

GF20036
Vengono riportati gli importi solo delle provvigioni da liquidare al
momento della fatturazione, mentre per quelli da liquidare al momento del
pagamento non viene riporatto nulla.

GF20037
Se clicco due volte sulla riga che riporata gli estremi della fattura sulla
quale la provvigione è stata calcolata i tasti ANNULLA / CONFERMA / ELIMINA
non sono allineati correttamente.

GF20038
La % di provvigione che mi presenta nella relativa colonna in riferimento
in corrispondenza della rata non numerata non è corretta. (allego l'area
dati d'esempio sulla quale si può notare l'errore).
Secondo me dovrebbe essere zero


git-svn-id: svn://10.65.10.50/trunk@11233 c028cbd2-c16b-5b4b-a496-9718f37d4682
2003-06-12 09:05:46 +00:00

568 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;
TDocumento *_documento;
TLocalisamfile *_provv,
*_rdoc,
*_doc,
*_tab,
*_occas,
*_cfven;
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();
TLocalisamfile& doc = *app()._doc;
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();
doc.put(DOC_PROVV,"D");
doc.put(DOC_ANNO,m.get_int(F_ANNO));
doc.put(DOC_CODNUM,m.get(F_CODNUM));
doc.put(DOC_NDOC,m.get(F_NDOC));
if (doc.read() == NOERR) // Se esiste il documento allora prende i valori relativi al totale documento, totale provvigione e base di calcolo provvigione
{
TDocumento* documento = app()._documento;
int err = documento->read(doc.curr());
if (err == NOERR)
{
m.set(F_DATADOC, documento->data());
m.set(F_CLIENTE, documento->codcf());
m.set(F_CODVAL,documento->valuta());
m.set(F_CAMBIO,documento->cambio());
m.set(F_DATACAMBIO,documento->get_date(DOC_DATACAMBIO));
m.set(F_IMPDOC,documento->totale_doc());
m.set(F_IMPPRDOC,documento->provvigione());
m.set(F_IMPNETDOC, documento->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 = documento->calc_provvigioni(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(documento->anno(), m.get(F_CODNUM), documento->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("Errore %d tentando di leggere il documento specificato",err);
} // Altrimenti l'utente e' libero di inserire importi e rate
}
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("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("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("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)
f.mask().enable(-5);
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("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("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);
TString16 codnum = tt.get(1);
long ndoc = tt.get_long(2);
TString16 codval = tt.get(8);
m.set(F_MANNO,anno);
m.set(F_MCODNUM,codnum);
m.set(F_MNDOC,ndoc);
m.set(F_CODVAL, 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 = (TSheet_field&) ds.mask().field(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_CONDV, LF_RCONDV, LF_ANAMAG, LF_SCONTI, LF_UMART,
LF_TABCOM, LF_CLIFO,LF_INDSP, LF_MOVMAG, LF_RMOVMAG,0);
_msk = new TMask("pr0700b") ;
_provv = new TLocalisamfile(LF_PROVV);
_doc = new TLocalisamfile(LF_DOC);
_rdoc = new TLocalisamfile(LF_RIGHEDOC);
_cfven = new TLocalisamfile(LF_CFVEN);
_occas = new TLocalisamfile(LF_OCCAS);
_tab = new TLocalisamfile(LF_TAB);
_prag = new TProvvigioni_agente;
_documento = new TDocumento;
TSheet_field & sf = (TSheet_field&)_msk->field(F_DOC_SHEET);
sf.set_notify(doc_sheet_notify);
sf.sheet_mask().set_handler(F_NDOC,ndoc_handler);
TSheet_field & rs = (TSheet_field&)_msk->field(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 _documento;
delete _prag;
delete _provv;
delete _doc;
delete _rdoc;
delete _tab;
delete _cfven;
delete _occas;
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 = (TSheet_field&)_msk->field(F_DOC_SHEET);
TSheet_field & rs = (TSheet_field&)_msk->field(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());
}
}
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("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("Dati agente %s in uso da un altro utente.", (const char*) agente);
return;
}
KEY k;
bool repeat;
const char* msg = _prag->items() == 0 ? "Registrare i dati inseriti" : "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("Errore %d tentando di scrivere i dati provvigionali dell'agente.",err, (const char*) agente);
_prag->unlock();
}
void TGestione_provv_app::main_loop()
{
bool ok = TRUE;
TMask* m = new TMask("pr0700a");
while (ok)
{
xvt_statbar_set("Ricerca", TRUE);
m->reset();
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,"Gestione provvigioni");
return 0;
}