// Programma di gestione provvigioni #include #include #include #include #include "prlib.h" #include "provv.h" #include "pr0700a.h" #include "pr0700b.h" #include "pr0.h" class TGestione_provv_app:public TApplication { TMask *_msk; TLocalisamfile *_provv; TProvvigioni_agente *_prag; bool _dirty; protected: virtual bool create(); virtual bool destroy(); virtual bool menu(MENU_TAG) ; 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 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 void fill_rate_doc(TRate_doc& rd, TSheet_field& sf); public: TGestione_provv_app() {}; ~TGestione_provv_app() {}; }; static inline TGestione_provv_app& app() { return (TGestione_provv_app&) main_app(); } static TString16 __current_key; //////////////////////////////////////////////////////////////////////////////////////// // Da fare : // - abilitazione colonne provvpag e pagato con pulsante // - Calcolo provvigioni in caso di selezione documento // //////////////////////////////////////////////////////////////////////////////////////// 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::ndoc_handler(TMask_field& f, KEY key) { if (key == K_ENTER) { // 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 lo stessa chiave"); } } if (key == K_TAB) { // - Impostazione importi e provvigioni in caso di selezione documento // - Calcolo righe di provvigioni in caso di selezione documento } 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; } 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()); if (r > 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()); if (r > 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) { if (__current_key.empty()) return TRUE; TProvvigioni_agente* pa = app()._prag; TRate_doc& rd = pa->rate(__current_key); switch (key) { case K_INS: // Inserimento di una nuova rata vuota { TRata* rt = new TRata; rt->set_generata(); // Nuova rata: va segnalata come inserita 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); // Effettua anche il pack degli elementi 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 = (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; 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); TString codnum = tt.get(1); long ndoc = tt.get_long(2); m.set(F_MANNO,anno); m.set(F_MCODNUM,codnum); m.set(F_MNDOC,ndoc); __current_key.format("%4d%4s%7ld",anno,(const char*)codnum,ndoc); TSheet_field& rs = (TSheet_field&) ds.mask().field(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.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()); int i = 1; i++; } 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 { if (__current_key.not_empty()) pa->remove_rate(__current_key); // Cancella il vecchio __current_key = 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,(TSheet_field&)ds.mask().field(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()._dirty = TRUE; break; default: break; } return TRUE; } bool TGestione_provv_app::create() { _msk = new TMask("pr0700b") ; _provv = new TLocalisamfile(LF_PROVV); _prag = new TProvvigioni_agente; TSheet_field & sf = (TSheet_field&)_msk->field(F_DOC_SHEET); sf.set_notify(doc_sheet_notify); sf.sheet_mask().set_handler(F_ANNO,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); dispatch_e_menu(MENU_ITEM(1)); return TRUE; } bool TGestione_provv_app::destroy() { delete _msk; delete _provv; 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 = (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.tipo()); 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::load_provvigioni(TMask* m) { TString agente = m->get(F_CODAGE); _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,""); _prag->read(agente); KEY k; bool repeat; const char* msg = _prag->rows() == 0 ? "Registrare i dati inseriti" : "Registrare le modifiche" ; fill_sheet_doc(); // Inizializza lo sheet dei documenti _dirty = FALSE; 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 _prag->write(); else repeat = TRUE; } while (repeat); } bool TGestione_provv_app::menu(MENU_TAG) { 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; return 0; } int pr0700(int argc, char** argv) { TGestione_provv_app a; a.run(argc,argv,"Gestione provvigioni"); return 0; }