// Programma di gestione provvigioni #include #include #include #include "../cg/cgsaldac.h" #include "prlib.h" #include #include #include #include "provv.h" #include "pr0800a.h" #include "pr0.h" class TAggiornamento_maturato_mask : public TAutomask { protected: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); public: void load_params(); void save_params(); TAggiornamento_maturato_mask() : TAutomask("pr0800a") {} }; bool TAggiornamento_maturato_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) { case F_A_CODAGE: if (e == fe_close) { const long a_cod = atol(o.get()); const long da_cod = get_long(F_DA_CODAGE); if (a_cod > 0L && da_cod > a_cod) return error_box(TR("Codice agente finale minore del codice agente iniziale")); } break; case F_CHECK_INSOLUTI: if (e == fe_init) { const TRectype prov(LF_PROVV); o.enable(prov.exist(PROV_DATASTAMPA)); } break; default: break; } return true; } class TAggiornamento_maturato_app : public TSkeleton_application { protected: virtual bool create(); virtual void main_loop(); public: void aggiorna_maturato(const TAggiornamento_maturato_mask &m); }; //////////////////////////////////////////////////////////////////////////////////////// // 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 TAggiornamento_maturato_app::create() { const bool saldaconto = has_module(SCAUT, CHK_DONGLE); if (!saldaconto) return error_box(TR("Questo programma necessita del saldaconto")); open_files(LF_PROVV, LF_TABCOM, LF_DOC, LF_PARTITE, LF_SCADENZE, LF_PAGSCA, LF_TAB, 0); return TSkeleton_application::create(); } static bool prov_saldata(const TRectype& prov) { bool is_saldata = prov.get_bool(PROV_SALDATA); if (!is_saldata) { const real importo_rata = prov.get(PROV_IMPRATA); const real importo_pagato = prov.get(PROV_PAGATO); if ((importo_rata > ZERO) && (importo_rata <= importo_pagato)) // come fosse saldata, per cui ... is_saldata = true; } return is_saldata; } static bool scan_func(const TRelation& rel, void* pJolly) { const TAggiornamento_maturato_mask& m = *(const TAggiornamento_maturato_mask*)pJolly; TRectype& rec = rel.curr(); const bool is_saldata = prov_saldata(rec); bool check_insoluti = false; TDate data_stampa; if (is_saldata && m.get_bool(F_CHECK_INSOLUTI)) { data_stampa = rec.get_date(PROV_DATASTAMPA); check_insoluti = data_stampa.ok(); } if (!check_insoluti && is_saldata) return true; const int anno = rec.get_int(PROV_ANNO); const TString& codnum(rec.get(PROV_CODNUM)) ; const long ndoc = rec.get_long(PROV_NDOC); TString80 key; key.format("D|%d|%s|%ld", anno, (const char *) codnum, ndoc); const long nreg = atol(cache().get(LF_DOC, key, DOC_NUMREG)); if (nreg <= 0) return true; // nessuna partita??? const TDate data_scad = m.get(F_DATA_SCAD); TDate data_rischio(data_scad); data_rischio -= m.get_long(F_GIORNI_RISCHIO); TPartite_array partite; partite.add_numreg(nreg); // Always 1 record bool changed_record = false; for (const TPartita* part = partite.first(); part && !changed_record; part = partite.next()) // Always 1 game { bool insoluti_in_ritardo = false; for (int nriga = part->last(); nriga > 0 && !changed_record; nriga = part->pred(nriga)) { const TRiga_partite& r = part->riga(nriga); if (check_insoluti && r.tipo() >= tm_insoluto) { const TDate data_insoluto = r.get(PART_DATAREG); if (data_insoluto > data_stampa) insoluti_in_ritardo = true; continue; } if (r.get_long(PART_NREG) != nreg || r.tipo() > tm_nota_credito) continue; if (rec.get_bool(PROV_SALDATA)) { if (check_insoluti && !insoluti_in_ritardo) continue; // Ignora righe saldate in assenza di insoluti } int nrata = rec.get_int(PROV_NRATA); if (nrata > 0 && !r.exist(nrata)) nrata = 0; const real importo_rata(rec.get_real(PROV_IMPRATA)); const real importo_pagato(rec.get_real(PROV_PAGATO)); const real provvigione_rata(rec.get_real(PROV_IMPPROVV)); const real provvigione_pagata(rec.get_real(PROV_PROVVPAG)); if (nrata > 0) { bool sbf = false; const TRiga_scadenze& s = r.rata(nrata); TImporto pagato(s.importo_pagato(false)); pagato -= s.esposto(false, data_scad, data_rischio, sbf); pagato.normalize('A'); if (pagato.valore() >= importo_rata) { const real importo_maturato = importo_rata - importo_pagato; const real provvigione_maturata = provvigione_rata - provvigione_pagata; rec.put(PROV_PAGMAT, importo_maturato); rec.put(PROV_PROVVMAT, provvigione_maturata); changed_record = true; } else { real importo_maturato = pagato.valore() - importo_pagato; if (importo_maturato < ZERO) { if (-importo_maturato > importo_pagato) importo_maturato = -importo_pagato; } if (importo_maturato >= ZERO) { real provvigione_maturata = provvigione_rata * importo_maturato / importo_rata; provvigione_maturata.round(2); rec.put(PROV_PAGMAT, importo_maturato); rec.put(PROV_PROVVMAT, provvigione_maturata); changed_record = true; } } } else { const TDate data_mat = rec.get_date(PROV_DATASCAD); if (data_mat <= data_scad) { changed_record = true; rec.put(PROV_PAGMAT, importo_rata); rec.put(PROV_PROVVMAT, provvigione_rata); } } if (changed_record) { TLocalisamfile provv(LF_PROVV); provv.curr() = rec; int err = provv.read(_isequal, _lock); if (err == NOERR) err = rec.rewrite(provv); if (err != NOERR) return yesno_box(FR("Errore %d in aggioramento agente %ld, Continuare ugualmente"), err, rec.get_long(PROV_CODAGE)); } } } return true; } void TAggiornamento_maturato_app::aggiorna_maturato(const TAggiornamento_maturato_mask &m) { const bool check_insoluti = m.get_bool(F_CHECK_INSOLUTI); TString filter = "(ANNO!=\"\")&&(CODNUM!=\"\")&&(NDOC!=\"\")"; if (!check_insoluti) filter << "&&(SALDATA!=\"X\")"; TRectype from(LF_PROVV), to(LF_PROVV); from.put(PROV_CODAGE, m.get(F_DA_CODAGE)); to.put(PROV_CODAGE, m.get(F_A_CODAGE)); TRelation rel(LF_PROVV); TCursor c(&rel, filter, 1, &from, &to); c.setregion(from, to); c.scan(scan_func, (void*)&m, TR("Aggiornamento provvigioni maturate")); } void TAggiornamento_maturato_app::main_loop() { TAggiornamento_maturato_mask m; while (m.run() == K_ENTER) aggiorna_maturato(m); } int pr0800(int argc, char** argv) { TAggiornamento_maturato_app a; a.run(argc, argv, TR("Aggiornamento provvigioni maturate")); return 0; }