diff --git a/src/sc/sc2100.cpp b/src/sc/sc2100.cpp index 15c4a0860..91d0867d2 100755 --- a/src/sc/sc2100.cpp +++ b/src/sc/sc2100.cpp @@ -22,31 +22,17 @@ #include #include -class TEC_recordset : public TAS400_recordset -{ - char _who; - TString _agente; - TString _pagam; - -public: - char get_who() const { return _who; } - TString & set_agente(const char * agente) { _agente = agente; return _agente; } - TString & set_pagam(const char * pagam) { _pagam = pagam; return _pagam; } - void add_fields(); - TEC_recordset(const char who); -}; - void TEC_recordset::add_fields() { set("Pagamento", _pagam); set("Agente", _agente); } -TEC_recordset::TEC_recordset(char who) : TAS400_recordset("AS400(512,0,0)"), _who(who) +TEC_recordset::TEC_recordset(const char * who) : TAS400_recordset("AS400(512,0,0)"), _who(who) { - if (who >= 'C') + if (who >= "C") { - if (who == 'F') + if (who == "F") create_field("Fornitore", 0, 6, _longfld); else create_field("Cliente", 0, 6, _longfld); @@ -75,87 +61,6 @@ TEC_recordset::TEC_recordset(char who) : TAS400_recordset("AS400(512,0,0)"), _wh create_field("Agente", -1, 60); } -/////////////////////////////////////////////////////////// -// TEC_form -/////////////////////////////////////////////////////////// - -class TEC_form : public TForm -{ - friend class TEC_row; - - static TEC_form* _form; - TEC_recordset* _recordset; - - enum { MAXTOT = 16 }; - - TCursor* _cursore; - TTotalizer _totali; - - TString _lingua; // Codice lingua del form - TDate _dlo, _dls, _dir; // Data limite operazione, scaduto e inizio rischio - int _giorni_rischio; // Numero giorni rischio nella maschera di selezione - bool _in_valuta; // Il form e' in valuta - int _fincatura; // 0 = nessuna, 1 = testo, 2 = grafica - word _num_rip; // Numero di righe usate per i riporti - word _total_rows; // Numero di righe usate per i totali - word _maxtot; // Numero massimo di totali da stampare - bool _stampa_saldo; // Stampa il saldo di ogni partita - bool _note_scadenti; // Considera scadute le note di credito non assegnate - - -protected: - void init_header(const TMask& m); - word ordina_totali_per_valuta(THash_object* tot[MAXTOT]); - - int find_magic(TString& s, TString& magic1, TString& magic2) const; - void change_magic_body(const TEC_row& o, TString& s); - void change_magic_footer(const THash_object& o, TString& s); - void print_total(int riga, const THash_object& o); - - void stampa_testata(TPrinter& p); - void stampa_pedata(); - void stampa_riporti(TPrinter& p); - - static void ec_header_handler(TPrinter& p); - static void ec_footer_handler(TPrinter& p); - -public: - TTotalizer& totali() { return _totali; } - - virtual TRelation* relation() const { return _cursore->relation(); } - virtual TCursor* cursor() { return _cursore; } - virtual TEC_recordset* recordset() { return _recordset; } - - const TDate& data_limite_operazione() const { return _dlo; } - const TDate& data_limite_scaduto() const { return _dls; } - int giorni_rischio() const { return _giorni_rischio; } - const TDate& data_inizio_rischio() const { return _dir; } - bool note_scadenti() const { return _note_scadenti; } - - const TString& lingua() const { return _lingua; } - bool in_valuta() const { return _in_valuta; } - const TString& describe(short id, char sez = 'H', pagetype pt = last_page) const; - - void azzera_totali(); - void ultima_pagina(); - bool print_game(const TPartita& game); - bool stampa_saldo() const { return _stampa_saldo; } - void stampa_saldo(bool ss) { _stampa_saldo = ss; } - - void set_agente(const TString& codag); - - bool printing() const { return _recordset == NULL; } - bool exporting() const { return _recordset != NULL; } - void export_total(); - - void set_pagam(const TString& codpag); - - TEC_recordset& recordset() const { CHECK(exporting(), "Not exporting"); return *_recordset; } - - TEC_form(const TEC_mask& m, bool gesval, bool excel); - virtual ~TEC_form(); -}; - TEC_form* TEC_form::_form = NULL; /////////////////////////////////////////////////////////// @@ -338,7 +243,7 @@ void TEC_row::print_on(TPrint_section& body) TForm_item& descr = body.find_field(PEC_DESCR); // Riga di partita vera e propria (non totale parziale) - if (rata() < RIGA_PART_PAGAMENTO) + if (rata() < RIGA_PAGAMENTO) { TString256 s = descr.prompt(); TEC_form::_form->change_magic_body(*this, s); @@ -718,7 +623,7 @@ void TEC_array::add_row(const TRiga_partite& row) { const TDate data_pag(row.get(PART_DATAPAG)); const TImporto imp(row.importo(in_valuta, 0x1)); // Importo pulito senza nient'altro - TEC_row& riga = new_row(row, data_pag, imp, RIGA_PART_PAGAMENTO); + TEC_row& riga = new_row(row, data_pag, imp, RIGA_PAGAMENTO); if (row.in_valuta()) { @@ -764,7 +669,7 @@ void TEC_array::add_row(const TRiga_partite& row) const TImporto abbuoni(row.importo(in_valuta, 0x2)); if (!abbuoni.is_zero()) { - TEC_row& rec = new_row(row, data_pag, abbuoni, RIGA_PART_ABBUONI); + TEC_row& rec = new_row(row, data_pag, abbuoni, RIGA_ABBUONI); rec.descrizione(form().describe(PEC_ABBUONI)); if (in_valuta) { @@ -786,7 +691,7 @@ void TEC_array::add_row(const TRiga_partite& row) TImporto diffcam(row.importo(false, 0x4)); if (!diffcam.is_zero() && !in_valuta) { - TEC_row& rec = new_row(row, data_pag, TImporto('D', ZERO), RIGA_DIFFCAM); + TEC_row& rec = new_row(row, data_pag, TImporto('D', ZERO), RIGA_DIFFCAMBI); rec.descrizione(form().describe(PEC_DIFFCAM)); rec.importo(diffcam); rec.codici_analitica(codanal); @@ -795,7 +700,7 @@ void TEC_array::add_row(const TRiga_partite& row) TImporto ritenute(row.importo(false, 0x8)); if (!ritenute.is_zero()) { - TEC_row& rec = new_row(row, data_pag, TImporto('D', ZERO), RIGA_PART_RITENUTE); + TEC_row& rec = new_row(row, data_pag, TImporto('D', ZERO), RIGA_RITENUTE); rec.descrizione(form().describe(PEC_RITENUTE)); if (in_valuta) { @@ -869,7 +774,7 @@ TEC_array::TEC_array(const TPartita& game, const TEC_form* f) for (r = items()-1; r >= 0; r--) { TEC_row& s = row(r); - if (s.rata() == RIGA_PART_PAGAMENTO) + if (s.rata() == RIGA_PAGAMENTO) { TImporto* imp = importo_riga_scaduto_ptr(s.riga()); if (imp != NULL) @@ -1219,20 +1124,15 @@ void TEC_form::azzera_totali() bool TEC_form::print_game(const TPartita& game) { bool ok = false; - TEC_array righe(game, this); - - - TPrint_section& body = section('B'); - + TPrint_section& body = section('B'); TImporto saldo; real scaduto, esposto, implire, impval; - // Stampa le righe di partita - int ultima_riga = 0; int ultima_rata = 0; int r; + for (r = 0; r < righe.items(); r++) { if (printing()) @@ -1421,15 +1321,14 @@ void TEC_form::set_agente(const TString& codag) } } -TEC_form::TEC_form(const TEC_mask& m, bool gesval, bool excel) - : TForm(BASE_EC_PROFILE, m.get_prof_name()), _recordset(NULL), - _in_valuta(false), _stampa_saldo(true), _num_rip(0), _total_rows(0) +TEC_form::TEC_form(const TEC_mask& m, bool gesval) + : TESSL_form(m, gesval), _recordset(nullptr), + _in_valuta(false), _export(m.export_print()), _stampa_saldo(true), _num_rip(0), _total_rows(0) { - _form = this; - - TCursor_sheet& cs = m.cur_sheet(); - _cursore = cs.cursor(); + TCursor_sheet& cs = m.cur_sheet(); + _form = this; + _cursore = cs.cursor(); if (relation()->log2ind(LF_COMUNI) < 0) { if (relation()->file().num() == LF_CLIFO) @@ -1437,13 +1336,13 @@ TEC_form::TEC_form(const TEC_mask& m, bool gesval, bool excel) else relation()->add(LF_COMUNI, "COM=\"\""); } - - _lingua = m.get_prof_lang(); // Lingua profilo _dlo = m.get(F_DATALIMOP); if (!_dlo.ok()) _dlo = eotime; _dls = m.get(F_DATALIMSC); + if (!_dls.ok()) + _dls = eotime; _giorni_rischio = m.get_int(F_GIORISCH); _dir = _dls; _dir -= _giorni_rischio; _note_scadenti = m.get_bool(F_NC_SCAD); @@ -1462,94 +1361,70 @@ TEC_form::TEC_form(const TEC_mask& m, bool gesval, bool excel) codanal.show(); } - if (!excel) - { - TPrinter& pr = printer(); - - pr.setheaderhandler(ec_header_handler); - TPrint_section& head = section('H'); - pr.headerlen(head.height()); - - pr.setfooterhandler(ec_footer_handler); - const TPrint_section& foot = section('F'); - pr.footerlen(foot.height()); - - if (_fincatura > 0) - { - const int first = head.height()-2; - const int last = pr.formlen(); - const int horiz[] = { first+2, last-foot.height()+1, 0 }; - set_fink_mode(_fincatura == 1 ? false : true); - genera_fincatura(odd_page, first, last, horiz); - } - - TForm_item& uns = section('F').find_field(PEC_UNASSIGNED); - TForm_item& tuns = section('F').find_field(PEC_TUNASSIGNED); - if (uns.shown()) uns.hide(); - if (tuns.shown()) tuns.hide(); - - genera_intestazioni(odd_page, head.height() - 1); - init_header(m); // Set fixed text - - _total_rows = 1; - for (word fi = 0; fi < foot.fields(); fi++) - { - const TForm_item& item = foot.field(fi); - if (item.shown()) - { - const word y = (word)item.y(); - if (y > _total_rows) - _total_rows = y; - } - } - - _maxtot = f.get_int(3); - - // La prima e l'ultima riga del footer devono essere lasciate libere per la fincatura - // Ogni totale occupa _total_rows righe: per cui posso calcolare il massimo di totali - // che posso stampare nel footer. - const word max = (foot.height() - 2) / _total_rows; - if (_maxtot <= 0 || _maxtot > max) - _maxtot = max; - } + if (_export) + _recordset = new TEC_recordset(m.who()); else { - _recordset = new TEC_recordset(m.get_who()); + TPrinter& pr = printer(); + + pr.setheaderhandler(ec_header_handler); + TPrint_section& head = section('H'); + pr.headerlen(head.height()); + + pr.setfooterhandler(ec_footer_handler); + const TPrint_section& foot = section('F'); + pr.footerlen(foot.height()); + + if (_fincatura > 0) + { + const int first = head.height() - 2; + const int last = pr.formlen(); + const int horiz[] = { first + 2, last - foot.height() + 1, 0 }; + set_fink_mode(_fincatura == 1 ? false : true); + genera_fincatura(odd_page, first, last, horiz); + } + + TForm_item& uns = section('F').find_field(PEC_UNASSIGNED); + TForm_item& tuns = section('F').find_field(PEC_TUNASSIGNED); + if (uns.shown()) uns.hide(); + if (tuns.shown()) tuns.hide(); + + genera_intestazioni(odd_page, head.height() - 1); + init_header(m); // Set fixed text + + _total_rows = 1; + for (word fi = 0; fi < foot.fields(); fi++) + { + const TForm_item& item = foot.field(fi); + if (item.shown()) + { + const word y = (word)item.y(); + if (y > _total_rows) + _total_rows = y; + } + } + + _maxtot = f.get_int(3); + + // La prima e l'ultima riga del footer devono essere lasciate libere per la fincatura + // Ogni totale occupa _total_rows righe: per cui posso calcolare il massimo di totali + // che posso stampare nel footer. + const word max = (foot.height() - 2) / _total_rows; + if (_maxtot <= 0 || _maxtot > max) + _maxtot = max; } } TEC_form::~TEC_form() { - if (printing()) - { - TPrinter& pr = printer(); - pr.setheaderhandler(NULL); - pr.setfooterhandler(NULL); - } - else - { - delete _recordset; - } + TPrinter& pr = printer(); + + pr.setheaderhandler(nullptr); + pr.setfooterhandler(nullptr); + safe_delete(_recordset); _form = NULL; } -/////////////////////////////////////////////////////////// -// TEC_gamelist -/////////////////////////////////////////////////////////// - -class TEC_Game_list -{ - TAssoc_array _games; - -protected: - void signature(const TRectype& rec, TToken_string& signature) const; - -public: - void add_game(const TRectype& rec); - bool has_clifo(long codcf); - bool has_game(const TRectype& rec); -}; - void TEC_Game_list::signature(const TRectype& rec, TToken_string& signature) const { signature = rec.get(SCAD_TIPOCF); @@ -1590,27 +1465,21 @@ bool TEC_Game_list::has_game(const TRectype& rec) class TStampaEC_application : public TSkeleton_application { - TEC_mask* _msk; - TEC_form* _form; - - TString _lingua_ditta; - bool _gesval; // Gestione valuta - char _tiponumec; // Tipo numerazione EC ' ', 'G', 'A' - long _lastnumec; // Ultimo numero EC 'G' - TAssoc_array _lastnumcf; // Ultimo numero stampato 'A' + TEC_mask * _msk; + TEC_form * _form; protected: // TSkeleton_application virtual bool create(); virtual bool destroy(); virtual void main_loop(); virtual void on_firm_change(); - virtual void on_config_change(); + virtual void print() override { _msk->on_field_event((TButton_field &)_msk->field(DLG_PRINT), fe_button, 0L); } + void find_agents_scads(TAssoc_array& agents); void find_agents_unassigned_pags(TAssoc_array& agents); public: - static TStampaEC_application& app() { return (TStampaEC_application&)main_app(); } long find_agents_games(TAssoc_array& agents); TEC_mask& mask() { return *_msk; } @@ -1619,540 +1488,13 @@ public: void update_numec(const TRectype& clf, int sign); void save_numec(); - bool print_selected(); // print selected items - bool print_agents(); // print selected items by agent int print_ec(TEC_Game_list* games = NULL); // print one ec only TStampaEC_application(); - virtual ~TStampaEC_application() {} + virtual ~TStampaEC_application() { safe_delete(_form); } }; -bool TStampaEC_application::print_selected() -{ - const char who = mask().get_who(); - - TCursor_sheet& s = sheet(); - TCursor& c = *s.cursor(); // Il cursore del form coincide con quello dello sheet - - /* - const int key = mask().get_key(); - - // Filtra il cursore del form in modo che diventi uguale al cursor_sheet corrente - // Qui sarebbe bello copiarsi l'indice dell'altro cursore - TCursor& fc = *form().cursor(); - fc.setkey(key); - - if (who >= 'C') - { - TRectype filter = fc.curr(); filter.zero(); - filter.put(CLI_TIPOCF, who); - fc.setregion(filter, filter); - } - */ - - form().set_agente(EMPTY_STRING); // Nascondi agente - - const long print_all = !s.one_checked(); // Se non ho selezionato nulla allora li stampo tutti - long analfabeti = 0; // Persone non stampate in quanto aventi lingua errata - const bool printing = form().printing(); - const long items = c.items(); - - TProgress_monitor* pi = NULL; - if (printing) - printer().open(); - else - pi = new TProgress_monitor(items, TR("Calcolo estratto conto")); - - for (long i = 0; i < items; i++) - { - if (print_all || s.checked(i)) - { - c = i; // Muove il cursore alla posizione corrente - const int ret = print_ec(); - if (ret < 0) - analfabeti++; - } - - if (printing) - { - if (printer().frozen()) - break; - } - else - { - if (!pi->addstatus(1)) - break; - } - } - - if (printing) - { - printer().close(); - if (_tiponumec > ' ' && who == 'C') - save_numec(); - - if (analfabeti > 0) - { - const char* anag = who == 'C' ? TR("clienti") : TR("fornitori"); - warning_box(FR("%ld %s non sono stati stampati in quanto " - "il codice lingua non corrispondeva al profilo di stampa"), - analfabeti, anag); - } - } - else - delete pi; - - return true; -} - -void TStampaEC_application::find_agents_scads(TAssoc_array& agents) -{ - const TString& fromage = mask().get(F_FROM_AGENT); - const TString& toage = mask().get(F_TO_AGENT); - const long fromcli = mask().get_long(SC_CFCODFR); - const long tocli = mask().get_long(SC_CFCODTO); - - TRelation rel(LF_SCADENZE); - rel.add(LF_PAGSCA, "TIPOC==TIPOC|GRUPPO==GRUPPO|CONTO==CONTO|SOTTOCONTO==SOTTOCONTO|" - "ANNO==ANNO|NUMPART==NUMPART|NRIGA==NRIGA|NRATA==NRATA"); - - TRectype& curr = rel.curr(); - const TRectype& pagsca = rel.curr(LF_PAGSCA); - - curr.put(SCAD_TIPOCF, mask().get(SC_CLIFO)); - TRectype recfr(curr), recto(curr); - if (fromcli > 0) - recfr.put(PAGSCA_SOTTOCONTO, fromcli); - if (tocli >= fromcli) - recto.put(PAGSCA_SOTTOCONTO, tocli); - - TString filter; - if (!mask().get_bool(F_STAMPCHIU)) - filter << "PAGATA!=\"X\""; - TCursor cur(&rel, filter, 1, &recfr, &recto); - const long items = cur.items(); - cur.freeze(); - - TProgind pi(items, TR("Ricerca scadenze aperte per agente..."), true, true); - for (cur = 0L; cur.pos() < items; ++cur) - { - if (!pi.addstatus(1)) - break; - - const char* codag = pagsca.get(PAGSCA_CODAG); - if (*codag == '\0') - { - codag = curr.get(SCAD_CODAG); - if (*codag == '\0') - continue; - } - if (fromage.not_empty() && fromage > codag) - continue; - if (toage.not_empty() && toage < codag) - continue; - - TEC_Game_list* games = (TEC_Game_list*)agents.objptr(codag); - if (games == NULL) - { - games = new TEC_Game_list; - agents.add(codag, (TObject*)games); - } - games->add_game(curr); - } -} - -void TStampaEC_application::find_agents_unassigned_pags(TAssoc_array& agents) -{ - TEC_mask& m = mask(); - const char tipocf = m.get(SC_CLIFO)[0]; - if (tipocf < 'C') - return; - - const TString& fromage = m.get(F_FROM_AGENT); - const TString& toage = m.get(F_TO_AGENT); - const long fromcli = m.get_long(SC_CFCODFR); - const long tocli = m.get_long(SC_CFCODTO); - - TRelation rel(LF_PAGSCA); - TRectype& curr = rel.curr(); - curr.put(PAGSCA_TIPOC, tipocf); // Imposta C o F - - TRectype recfr(curr), recto(curr); - if (fromcli > 0) - recfr.put(PAGSCA_SOTTOCONTO, fromcli); // Imposta cliente iniziale - if (tocli >= fromcli) - recto.put(PAGSCA_SOTTOCONTO, tocli); // Imposta cliente finale - - TString filter; - filter << '(' << PAGSCA_NRATA <<"==9999)"; - if (fromage.full()) - filter << "&&(" << PAGSCA_CODAG << ">='" << fromage << "')"; - else - filter << "&&(" << PAGSCA_CODAG << "!='')"; - if (toage.full()) - filter << "&&(" << PAGSCA_CODAG << "<='" << toage << "')"; - - TCursor cur(&rel, filter, 1, &recfr, &recto); - const long items = cur.items(); - if (items > 0) - { - cur.freeze(); - TProgind pi(items, TR("Ricerca pagamenti non assegnati per agente..."), true, true); - for (cur = 0L; cur.pos() < items; ++cur) - { - if (!pi.addstatus(1)) - break; - const char* codag = curr.get(PAGSCA_CODAG); - TEC_Game_list* games = (TEC_Game_list*)agents.objptr(codag); - if (games == NULL) - { - games = new TEC_Game_list; - agents.add(codag, (TObject*)games); - } - games->add_game(curr); - } - } -} - -long TStampaEC_application::find_agents_games(TAssoc_array& agents) -{ - find_agents_scads(agents); - find_agents_unassigned_pags(agents); - return agents.items(); -} - -bool TStampaEC_application::print_agents() -{ - TCursor_sheet& s = sheet(); - TCursor& c = *s.cursor(); - - const char who = mask().get_who(); - const int key = mask().get_selected_key(); - - // Filtra il cursore del form in modo che diventi uguale al cursor_sheet corrente - // Qui sarebbe bello copiarsi l'indice dell'altro cursore - TCursor& fc = *form().cursor(); - fc.setkey(key); - TRectype filter(LF_CLIFO); - filter.put(CLI_TIPOCF, who); - fc.setregion(filter, filter); - - const bool printing = form().printing(); - const long print_all = !s.one_checked(); // Se non ho selezionato nulla allora li stampo tutti - long analfabeti = 0; // Persone non stampate in quanto aventi lingua errata - - TAssoc_array agents; - const long totag = find_agents_games(agents); - if (totag <= 0) - return false; - - TRelation rel(LF_AGENTI); - TCursor cur(&rel); - const long items = cur.items(); - cur.freeze(); - - TProgind* pi = NULL; - if (printing) - printer().open(); - else - pi = new TProgind(items, "Calcolo estratto conto", true, true); - - for (cur = 0L; cur.pos() < items; ++cur) - { - const TString& codag = cur.curr().get(AGE_CODAGE); - TEC_Game_list* games = (TEC_Game_list*)agents.objptr(codag); - - if (games != NULL) - { - form().set_agente(codag); - form().set_pagam(fc.curr().get(CLI_CODPAG)); - const long items = c.items(); - for (long i = 0; i < items; i++) - { - if (print_all || s.checked(i)) - { - fc = i; // Muove il cursore alla posizione corrente - const long codcf = fc.curr().get_long(CLI_CODCF); - if (games->has_clifo(codcf)) - { - const int ret = print_ec(games); - if (ret < 0) - analfabeti++; - } - } - if (printing) - { - if (printer().frozen()) - break; - } - else - { - if (!pi->addstatus(1)) - break; - } - } - } - } - - if (printing) - { - printer().close(); - if (_tiponumec > ' ' && who == 'C') - save_numec(); - - if (analfabeti > 0) - { - const char* anag = who == 'C' ? TR("clienti") : TR("fornitori"); - warning_box(FR("%ld %s non sono stati stampati, avendo " - "il codice lingua non corrispondente al profilo di stampa"), - analfabeti, anag); - } - } - else - delete pi; - - - return true; -} - - -void TStampaEC_application::save_numec() -{ - // Ho numerato qualche estratto conto? - if (_lastnumcf.items() > 0 && form().printing()) - { - if (yesno_box(TR("Si desidera aggiornare il numero di estratto conto stampato definitivamente?"))) - { - TProgind pi(_lastnumcf.items(), TR("Aggiornamento numero estratto conto..."), false, true); - const char tipocf = mask().get_who(); // Dovrebbe essere sempre 'C' - TLocalisamfile cfven(LF_CFVEN); - FOR_EACH_ASSOC_STRING(_lastnumcf, obj, key, str) - { - pi.addstatus(1); - cfven.put(CFV_TIPOCF, tipocf); - cfven.put(CFV_CODCF, key); - const int err = cfven.read(); - if (err != NOERR) - { - cfven.zero(); - cfven.put(CFV_TIPOCF, tipocf); - cfven.put(CFV_CODCF, key); - } - cfven.put("NUMESC", str); - cfven.put("DATAESC", mask().get(F_DATASEND)); - if (err == NOERR) - cfven.rewrite(); - else - cfven.write(); - } - if (_tiponumec == 'G') - { - TConfig c(CONFIG_DITTA, "cg"); - c.set("LastEC", _lastnumec); - } - } - else - { - // Ripristino vecchio numero di estratto conto sulla maschera - if (_tiponumec == 'G') - { - TConfig c(CONFIG_DITTA, "cg"); - _lastnumec = c.get_long("LastEC"); - } - } - _lastnumcf.destroy(); // Azzera comunque elenco EC stampati - } -} - -void TStampaEC_application::update_numec(const TRectype& clf, int sign) -{ - const char tipocf = clf.exist(CLI_TIPOCF) ? clf.get_char(CLI_TIPOCF) : ' '; - if (_tiponumec > ' ' && tipocf == 'C' && form().printing()) - { - TForm_item& nec = form().find_field('H', odd_page, PEC_NUMPROG); - if (nec.shown()) - { - const TString8 codcf = clf.get(CLI_CODCF); - TString16 num; - switch(_tiponumec) - { - case 'A': - if (sign > 0) - { - TString16 key; - key.format("%c|%s", tipocf, (const char*)codcf); - const TRectype& cfven = cache().get(LF_CFVEN, key); - num << (cfven.get_long("NUMESC")+1); - } - break; - case 'G': - if (sign > 0) - { - _lastnumec++; - num << _lastnumec; - } - else - _lastnumec--; - break; - default: - break; - } - if (num.full()) - { - nec.set(num); - _lastnumcf.add(codcf, num); - } - else - _lastnumcf.remove(codcf); - } - } -} - - -// Nuovo modo con cursore -int TStampaEC_application::print_ec(TEC_Game_list* games) -{ - TWait_cursor hourglass; - - TEC_form& f = form(); - const bool printing = f.printing(); - - const TRectype& clf = f.cursor()->curr(); - - if (printing && clf.num() == LF_CLIFO) - { - // make controllations per lingua profilo/CF - const TString& lincf = clf.get(CLI_CODLIN); - bool ok = true; - if ((f.lingua() == _lingua_ditta && lincf.full()) || - f.lingua() != _lingua_ditta) - ok = lincf == f.lingua(); - if (!ok) // Cliente analfabeta - return -1; - } - TToken_string key(clf.get(CLI_TIPOCF)); - - key.add(clf.get(CLI_CODCF)); - form().set_agente(cache().get(LF_CFVEN, key, CFV_CODAG)); - form().set_pagam(clf.get(CLI_CODPAG)); - - f.azzera_totali(); // Azzera totali di fine pagina - - // Filtra solo le partite del cliente selezionato - TRelation rel(LF_PARTITE); - TRectype& curr = rel.curr(); - if (clf.num() == LF_CLIFO) - { - curr.put(PART_TIPOCF, clf.get(CLI_TIPOCF)); - curr.put(PART_SOTTOCONTO, clf.get(CLI_CODCF)); - } - else - { - curr.zero(PART_TIPOCF); - curr.put(PART_GRUPPO, clf.get(PCN_GRUPPO)); - curr.put(PART_CONTO, clf.get(PCN_CONTO)); - curr.put(PART_SOTTOCONTO, clf.get(PCN_SOTTOCONTO)); - } - TCursor cur(&rel, "", 1, &curr, &curr); - - const long items = cur.items(); - cur.freeze(); - - const bool stampa_chiuse = mask().get_bool(F_STAMPCHIU); - const TDate data_chiuse = mask().get(F_DATACHIU); - - TString status; - - int printed = 0; // Non ho stampato ancora nulla - - if (printing && clf.num() == LF_CLIFO) - update_numec(clf, +1); // Incrementa contatore - - TString8 last_game; - int last_year = 0; - - for (cur = 0; cur.pos() < items; ++cur) - { - const int curr_year = curr.get_int(PART_ANNO); - const TString& curr_game = curr.get(PART_NUMPART); - if (curr_year == last_year && curr_game == last_game) - continue; - last_game = curr_game; - last_year = curr_year; - - // Non fregare i clienti agli altri agenti! - if (games != NULL && !games->has_game(curr)) - continue; - - TPartita game(curr); - - status.cut(0); - status << game.anno() << ' ' << game.numero(); - xvtil_statbar_set(status); - do_events(); - - const TDate& dir = f.data_inizio_rischio(); - const TDate& dlo = f.data_limite_operazione(); - const TDate& dls = f.data_limite_scaduto(); - const TImporto saldo = game.calcola_saldo_al(f.in_valuta(), dlo, dls, dir); - if (saldo.is_zero()) - { - int r = 0; - if (stampa_chiuse) - { - for (r = game.last(); r > 0 ; r = game.pred(r)) - { - const TRiga_partite& riga = game.riga(r); - if (riga.is_fattura()) - { - const TDate dd = riga.get(PART_DATADOC); - if (dd >= data_chiuse) - break; - } - } - } - if (r == 0) - continue; - } - - if (printing) - { - if (printed) - { - TPrintrow empty; // Salta una riga vuota - printer().print(empty); // (Non farlo alla fine di ogni partita!) - } - if (printer().frozen()) - break; - } - - if (f.print_game(game)) - printed++; - } - - if (printing) - { - if (printed > 0) - { - f.ultima_pagina(); - printer().formfeed(); - } - else - update_numec(clf, -1); - } - else - { - if (printed > 0 && f.stampa_saldo()) - { - f.export_total(); -// f.recordset().new_rec(); - } - } - - xvtil_statbar_set(NULL); - - return printed; -} +TStampaEC_application& app() { return (TStampaEC_application&)main_app(); } /////////////////////////////////////////////////////////// // Generic TApplication methods @@ -2179,63 +1521,15 @@ void TStampaEC_application::on_firm_change() TApplication::on_firm_change(); } -void TStampaEC_application::on_config_change() -{ - TConfig c(CONFIG_DITTA, "cg"); - _lingua_ditta = c.get("CodLin"); - _gesval = c.get_bool("GesVal"); - _tiponumec = c.get_char("NumEC"); - _lastnumec = c.get_long("LastEC"); -} void TStampaEC_application::main_loop() { - TEC_mask& m = mask(); - m.set(F_STAMPSALDO, "X"); - - while (true) - { - m.show(F_ULTIMOEC, _tiponumec == 'G'); - m.set(F_ULTIMOEC, _lastnumec); - const KEY k = m.run(); - if (k == K_QUIT) - break; + TEC_mask& m = mask(); - const bool excel = k != K_ENTER; - - _form = new TEC_form(m, _gesval, excel); - - _form->stampa_saldo(m.get_bool(F_STAMPSALDO)); - - if (!excel) - { - TForm_item& nec = _form->find_field('H', odd_page, PEC_NUMPROG); - if (nec.enabled() && nec.shown()) - { - nec.show(_tiponumec > ' ' && m.get_who() == 'C'); - _lastnumec = m.get_long(F_ULTIMOEC); - } - } - if (m.get_bool(F_GROUPAGENT)) - print_agents(); - else - print_selected(); - - if (excel) - { - TFilename xls; xls.tempdir(); xls.add("ec.xls"); - _form->recordset()->save_as(xls, fmt_html); - xvt_sys_goto_url(xls, "open"); - } - - delete _form; - _form = NULL; - - } + while (m.run() != K_QUIT); } -TStampaEC_application::TStampaEC_application() - : _lingua_ditta(1), _msk(NULL), _form(NULL) +TStampaEC_application::TStampaEC_application() : _msk(nullptr), _form(nullptr) {} int sc2100(int argc, char** argv) diff --git a/src/sc/sc2100a.h b/src/sc/sc2100a.h index 6b0495bdc..e11de7fb9 100755 --- a/src/sc/sc2100a.h +++ b/src/sc/sc2100a.h @@ -23,7 +23,5 @@ #define F_TO_AGENT 123 #define F_TO_AGENT_D 124 -// basename of profile -#define BASE_EC_PROFILE "PEC" #endif diff --git a/src/sc/sc2100a.uml b/src/sc/sc2100a.uml index 357e6f343..10d8a7491 100755 --- a/src/sc/sc2100a.uml +++ b/src/sc/sc2100a.uml @@ -3,14 +3,32 @@ TOOLBAR "" 0 0 0 2 -BUTTON DLG_EDIT 10 2 +BUTTON DLG_PRINT 2 2 BEGIN - PROMPT 1 1 "~Esporta" - PICTURE TOOL_EXCEL - MESSAGE EXIT,69 + PROMPT 1 4 "~Stampa" + PICTURE TOOL_PRINT END -#include +BUTTON DLG_SETPRINT 2 2 +BEGIN + PROMPT 2 4 "~Imposta" + PICTURE TOOL_SETPRINT +END + +BUTTON DLG_EMAIL 2 2 +BEGIN + PROMPT 3 4 "Mail" + PICTURE TOOL_EMAIL +END + + +BUTTON DLG_EDIT 10 2 +BEGIN + PROMPT 4 4 "~Esporta" + PICTURE TOOL_EXCEL +END + +#include ENDPAGE @@ -76,7 +94,6 @@ BEGIN FLAGS "D" END - DATE F_DATALIMOP BEGIN PROMPT 2 4 "Data limite operazione " @@ -91,7 +108,6 @@ END DATE F_DATALIMSC BEGIN PROMPT 2 5 "Data limite scaduto " - CHECKTYPE REQUIRED END NUMBER F_GIORISCH 3 @@ -160,7 +176,7 @@ BEGIN PROMPT 65 11 "A~zzera" END -NUMBER SC_NSEL 4 +NUMBER SC_NSEL 6 BEGIN PROMPT 52 12 "Selezionati " FLAGS "D" diff --git a/src/sc/sc2100b.h b/src/sc/sc2100b.h new file mode 100644 index 000000000..797f5d3ed --- /dev/null +++ b/src/sc/sc2100b.h @@ -0,0 +1,16 @@ +#define F_SHEET 201 +#define F_FROMEMAIL 202 +#define F_PASSWORD 203 +#define F_CCEMAIL 204 +#define F_CCNEMAIL 205 +#define F_RECEIPT 206 +#define F_MESSAGE 207 +#define F_SUBJ 208 +#define F_TESTEMAIL 209 +#define F_SORT 210 + +#define S_SELECTED 101 +#define S_EMAIL 102 +#define S_CODCF 103 +#define S_RAGSOC 104 + diff --git a/src/sc/sc2100b.uml b/src/sc/sc2100b.uml new file mode 100644 index 000000000..e4a86e1ce --- /dev/null +++ b/src/sc/sc2100b.uml @@ -0,0 +1,135 @@ +#include "sc2100b.h" + +TOOLBAR "topbar" 0 0 0 2 + +BUTTON DLG_ALL 2 2 +BEGIN + PROMPT 1 3 "~Tutti" + PICTURE TOOL_MULTISEL +END + +BUTTON DLG_OK 2 2 +BEGIN + PROMPT 2 3 "Invia" + PICTURE TOOL_EMAIL +END + +BUTTON DLG_PREVIEW 2 2 +BEGIN + PROMPT 3 3 "~Anteprima" + PICTURE TOOL_PREVIEW +END + +#include + +ENDPAGE + +PAGE "Invio Estratti conto" 0 2 0 0 + +LISTBOX F_SORT 1 15 +BEGIN + PROMPT 1 0 "Ordinamento " + ITEM "1|Codice" + ITEM "2|Ragione sociale" +END + +STRING F_FROMEMAIL 50 +BEGIN + PROMPT 1 1 "Email di invio " +END + +STRING F_PASSWORD 50 +BEGIN + PROMPT 1 2 "Password " + FLAGS "*" +END + +STRING F_CCEMAIL 50 +BEGIN + PROMPT 1 3 "Conoscenza " +END + +BOOLEAN F_RECEIPT +BEGIN + PROMPT 70 3 "Ricevuta" +END + +STRING F_CCNEMAIL 50 +BEGIN + PROMPT 1 4 "Conosc.nascosta " +END + +ZOOM F_SUBJ 50 +BEGIN + PROMPT 1 5 "Oggetto " +END + +ZOOM F_MESSAGE 50 +BEGIN + PROMPT 1 6 "Messaggio " +END + +STRING F_TESTEMAIL 50 +BEGIN + PROMPT 1 7 "Email prova " + FLAGS "H" +END + +SPREADSHEET F_SHEET -1 -1 +BEGIN + PROMPT 0 9 "" + ITEM "@1" + ITEM "Email@50" + ITEM "Codice" + ITEM "Ragione Sociale@50" +END + +ENDPAGE + +ENDMASK + +PAGE "" -1 -1 80 7 + +BOOLEAN S_SELECTED +BEGIN + PROMPT 1 1 "Email " +END + +STRING S_EMAIL 50 +BEGIN + PROMPT 1 2 "Email " +END + +NUMBER S_CODCF 6 +BEGIN + PROMPT 1 4 "Codice " + FLAG "D" +END + +STRING S_RAGSOC 50 +BEGIN + PROMPT 1 5 "Ragione Sociale " + FLAG "D" +END + +ENDPAGE + +TOOLBAR "" 0 0 0 2 + +BUTTON DLG_OK 2 2 +BEGIN + PROMPT 1 1 "" +END + +BUTTON DLG_DELREC 2 2 +BEGIN + PROMPT 1 1 "" +END + +BUTTON DLG_CANCEL 2 2 +BEGIN + PROMPT 1 1 "" +END + +ENDPAGE +ENDMASK \ No newline at end of file diff --git a/src/sc/sc2101.cpp b/src/sc/sc2101.cpp index 88e70dda4..6a080edad 100755 --- a/src/sc/sc2101.cpp +++ b/src/sc/sc2101.cpp @@ -1,54 +1,111 @@ -#include "sc2101.h" -#include "sc2100a.h" +#include +#include -bool TEC_mask::codprof_handler(TMask_field& f, KEY k) -{ - if (!f.empty() && f.to_check(k)) - { - TEdit_field & e = (TEdit_field &) f; - - e.check_type(CHECK_REQUIRED); - - const bool ok = e.check(); - - e.check_type(CHECK_NONE); - - if (k == K_ENTER && !ok) - { - if (f.is_editable()) - { - TEditable_field& ef = (TEditable_field&) f; - return f.error_box(ef.get_warning()); - } - } - } - return TRUE; -} +#include "../pr/agenti.h" - -bool TEC_mask::lingua_handler(TMask_field& f, KEY k) -{ - if (k == K_TAB && f.focusdirty()) - { - TEdit_field& cod = f.mask().efield(F_CODPROF); - TCursor& cur = *(cod.browse()->cursor()); - const TString& lin = f.get(); - if (lin != cur.curr().get("CODPROF").mid(4)) - cod.check(RUNNING_CHECK); - } - return TRUE; -} - - - -TEC_mask::TEC_mask(const char* name) : TSelection_mask(name), _ditta(LF_NDITTE) +#include "sc2101.h" +#include "sc2100a.h" +#include "sc21pec.h" + +bool TEC_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { - _ditta.add(LF_ANAG, "TIPOA==TIPOA|CODANAGR==CODANAGR"); + switch (o.dlg()) + { + case F_STAMPSALDO: + if (e == fe_init) + { + set(F_STAMPSALDO, true); + show(F_ULTIMOEC, _tiponumec == 'G'); + set(F_ULTIMOEC, _lastnumec); + } + return true; + break; + case F_CODPROF: + if (e == fe_close) + { + o.check_type(CHECK_REQUIRED); + + const bool ok = o.check(); + + o.check_type(CHECK_NONE); + + if (!ok) + return error_box(((TEditable_field &)o).get_warning()); + else + return true; + } + return true; + break; + case F_LINPROF: + if (e == fe_modify) + { + TEdit_field& cod = efield(F_CODPROF); + TCursor& cur = *(cod.browse()->cursor()); + const TString& lin = o.get(); + + if (lin != cur.curr().get("CODPROF").smid(4)) + cod.check(RUNNING_CHECK); + } + return true; + break; + case DLG_EDIT: + if (e == fe_button) + { + TFilename xls; + + xls.temp("ec", "xls"); + safe_delete(_form); + set_export(); + + TEC_form & f = (TEC_form &)form(); + + if (get_bool(F_GROUPAGENT)) + print_agents(); + else + print_selected(); + f.recordset()->save_as(xls, fmt_html); + xvt_sys_goto_url(xls, "open"); + show(F_ULTIMOEC, _tiponumec == 'G'); + set(F_ULTIMOEC, _lastnumec); + } + return true; + break; + case DLG_PRINT: + if (e == fe_button) + { + update_checked(); + safe_delete(_form); + set_export(false); + + TForm_item& nec = form().find_field('H', odd_page, PEC_NUMPROG); + + if (nec.enabled() && nec.shown()) + { + nec.show(_tiponumec > ' ' && who() == "C"); + _lastnumec = get_long(F_ULTIMOEC); + } + if (get_bool(F_GROUPAGENT)) + print_agents(); + else + print_selected(); + show(F_ULTIMOEC, _tiponumec == 'G'); + set(F_ULTIMOEC, _lastnumec); + } + return true; + break; + default: + break; + } + return TSelection_mask::on_field_event(o, e, jolly); +} + +TEC_mask::TEC_mask(const char* name) : TSelection_mask(name), _ditta(LF_NDITTE), _ec_mail("sc2100b"), _form(nullptr), _games(nullptr), _export(false) +{ + _ditta.add(LF_ANAG, "TIPOA==TIPOA|CODANAGR==CODANAGR"); _ditta.add(LF_COMUNI, "COM==COMRF(COMRES)", 1, LF_ANAG, 101); _ditta.add(LF_COMUNI, "COM==COMRES", 1, LF_ANAG, 102); - - set_handler(F_CODPROF, codprof_handler); - set_handler(F_LINPROF, lingua_handler); + _tiponumec = ini_get_string(CONFIG_DITTA, "cg", "NumEC")[0]; + _lastnumec = ini_get_long(CONFIG_DITTA, "cg", "LastEC"); } TEC_mask::~TEC_mask() @@ -72,26 +129,573 @@ void TEC_mask::start_run() on_firm_change(); } -const char* TEC_mask::get_prof_base() const +TESSL_form & TEC_mask::form() { - return BASE_EC_PROFILE; -} - -const TString& TEC_mask::get_prof_code() const -{ - return get(F_CODPROF); -} - -const TString& TEC_mask::get_prof_lang() const -{ - return get(F_LINPROF); + if (_form == nullptr) + _form = new TEC_form(*this, ini_get_bool(CONFIG_DITTA, "cg", "GesVal")); + return *_form; } -const char* TEC_mask::get_prof_name() const -{ - TString& tmp=(TString&)_tmp; - tmp = get_prof_code(); - tmp << get_prof_lang(); - return _tmp; + +bool TEC_mask::print_selected() +{ + TCursor_sheet& s = cur_sheet(); + TCursor& c = *s.cursor(); // Il cursore del form coincide con quello dello sheet + + _form->set_agente(EMPTY_STRING); // Nascondi agente + + if (s.checked() == 0L) + s.check_all(); + const long print_all = s.checked() == s.items(); // Se non ho selezionato nulla allora li stampo tutti + long analfabeti = 0; // Persone non stampate in quanto aventi lingua errata + const bool printing = _form->printing(); + const long items = c.items(); + + { + TProgress_monitor pi(items, TR("Calcolo estratto conto")); + const long last = s.last_one(); + + if (printing) + printer().open(); + + _games = nullptr; + for (long i = s.first_one(); pi.addstatus() && i <= last; i++) + { + if (s.checked(i)) + { + c = i; // Muove il cursore alla posizione corrente + if (print_one(who(), c.curr().get_long(CLI_CODCF)) < 0) + analfabeti++; + } + if (printing && printer().frozen()) + break; + } +} + if (printing) + { + printer().close(); + if (_tiponumec > ' ' && who() == "C") + save_numec(); + if (analfabeti > 0) + { + const char* anag = (who() == "C") ? TR("clienti") : TR("fornitori"); + warning_box(FR("%ld %s non sono stati stampati in quanto " + "il codice lingua non corrispondeva al profilo di stampa"), + analfabeti, anag); + } + } + return true; } +void TEC_mask::find_agents_scads(TAssoc_array& agents) +{ + const TString& fromage = get(F_FROM_AGENT); + const TString& toage = get(F_TO_AGENT); + const long fromcli = get_long(SC_CFCODFR); + const long tocli = get_long(SC_CFCODTO); + + TRelation rel(LF_SCADENZE); + rel.add(LF_PAGSCA, "TIPOC==TIPOC|GRUPPO==GRUPPO|CONTO==CONTO|SOTTOCONTO==SOTTOCONTO|" + "ANNO==ANNO|NUMPART==NUMPART|NRIGA==NRIGA|NRATA==NRATA"); + + TRectype& curr = rel.curr(); + const TRectype& pagsca = rel.curr(LF_PAGSCA); + + curr.put(SCAD_TIPOCF, get(SC_CLIFO)); + TRectype recfr(curr), recto(curr); + if (fromcli > 0) + recfr.put(PAGSCA_SOTTOCONTO, fromcli); + if (tocli >= fromcli) + recto.put(PAGSCA_SOTTOCONTO, tocli); + + TString filter; + + if (!get_bool(F_STAMPCHIU)) + filter << "PAGATA!=\"X\""; + TCursor cur(&rel, filter, 1, &recfr, &recto); + const long items = cur.items(); + + cur.freeze(); + + TProgind pi(items, TR("Ricerca scadenze aperte per agente..."), true, true); + for (cur = 0L; cur.pos() < items; ++cur) + { + if (!pi.addstatus(1)) + break; + + const char* codag = pagsca.get(PAGSCA_CODAG); + if (*codag == '\0') + { + codag = curr.get(SCAD_CODAG); + if (*codag == '\0') + continue; + } + if (fromage.not_empty() && fromage > codag) + continue; + if (toage.not_empty() && toage < codag) + continue; + + TEC_Game_list* games = (TEC_Game_list*)agents.objptr(codag); + if (games == NULL) + { + games = new TEC_Game_list; + agents.add(codag, (TObject*)games); + } + games->add_game(curr); + } +} + +void TEC_mask::find_agents_unassigned_pags(TAssoc_array& agents) +{ + const char tipocf = get(SC_CLIFO)[0]; + + if (tipocf >= 'C') + { + const TString& fromage = get(F_FROM_AGENT); + const TString& toage = get(F_TO_AGENT); + const long fromcli = get_long(SC_CFCODFR); + const long tocli = get_long(SC_CFCODTO); + + TRelation rel(LF_PAGSCA); + TRectype& curr = rel.curr(); + curr.put(PAGSCA_TIPOC, tipocf); // Imposta C o F + + TRectype recfr(curr), recto(curr); + if (fromcli > 0) + recfr.put(PAGSCA_SOTTOCONTO, fromcli); // Imposta cliente iniziale + if (tocli >= fromcli) + recto.put(PAGSCA_SOTTOCONTO, tocli); // Imposta cliente finale + + TString filter; + filter << '(' << PAGSCA_NRATA << "==9999)"; + if (fromage.full()) + filter << "&&(" << PAGSCA_CODAG << ">='" << fromage << "')"; + else + filter << "&&(" << PAGSCA_CODAG << "!='')"; + if (toage.full()) + filter << "&&(" << PAGSCA_CODAG << "<='" << toage << "')"; + + TCursor cur(&rel, filter, 1, &recfr, &recto); + const long items = cur.items(); + if (items > 0) + { + cur.freeze(); + TProgind pi(items, TR("Ricerca pagamenti non assegnati per agente..."), true, true); + for (cur = 0L; cur.pos() < items; ++cur) + { + if (!pi.addstatus(1)) + break; + const char* codag = curr.get(PAGSCA_CODAG); + TEC_Game_list* games = (TEC_Game_list*)agents.objptr(codag); + if (games == NULL) + { + games = new TEC_Game_list; + agents.add(codag, (TObject*)games); + } + games->add_game(curr); + } + } + } +} + +long TEC_mask::find_agents_games(TAssoc_array& agents) +{ + find_agents_scads(agents); + find_agents_unassigned_pags(agents); + return agents.items(); +} + +bool TEC_mask::print_agents() +{ + TCursor_sheet& s = cur_sheet(); + TCursor& c = *s.cursor(); + + // Filtra il cursore del form in modo che diventi uguale al cursor_sheet corrente + // Qui sarebbe bello copiarsi l'indice dell'altro cursore + TCursor& fc = *(_form->cursor()); + + fc.setkey(key()); + TRectype filter(LF_CLIFO); + filter.put(CLI_TIPOCF, who()); + fc.setregion(filter, filter); + + const bool printing = _form->printing(); + const long print_all = !s.one_checked(); // Se non ho selezionato nulla allora li stampo tutti + long analfabeti = 0; // Persone non stampate in quanto aventi lingua errata + TAssoc_array agents; + const long totag = find_agents_games(agents); + + if (totag > 0) + { + TRelation rel(LF_AGENTI); + TCursor cur(&rel); + const long items = cur.items(); + cur.freeze(); + + { + TProgind pi(items, "Calcolo estratto conto", true, true); + + if (printing) + printer().open(); + for (cur = 0L; pi.addstatus() && cur.pos() < items; ++cur) + { + const TString& codag = cur.curr().get(AGE_CODAGE); + _games = (TEC_Game_list*)agents.objptr(codag); + + if (_games != nullptr) + { + _form->set_agente(codag); + _form->set_pagam(fc.curr().get(CLI_CODPAG)); + + const long items = c.items(); + + for (long i = 0; i < items; i++) + { + if (print_all || s.checked(i)) + { + fc = i; // Muove il cursore alla posizione corrente + + const long codcf = fc.curr().get_long(CLI_CODCF); + + if (_games->has_clifo(codcf)) + { + if (print_one(who(), codcf) < 0) + analfabeti++; + } + } + if (printing && printer().frozen()) + break; + } + } + } + } + } + if (printing) + { + printer().close(); + if (_tiponumec > ' ' && who() == "C") + save_numec(); + if (analfabeti > 0) + { + const char* anag = (who() == 'C') ? TR("clienti") : TR("fornitori"); + warning_box(FR("%ld %s non sono stati stampati, avendo " + "il codice lingua non corrispondente al profilo di stampa"), + analfabeti, anag); + } + } + return true; +} + +void TEC_mask::save_numec() +{ + // Ho numerato qualche estratto conto? + if (_lastnumcf.items() > 0 && _form->printing()) + { + if (yesno_box(TR("Si desidera aggiornare il numero di estratto conto stampato definitivamente?"))) + { + TProgind pi(_lastnumcf.items(), TR("Aggiornamento numero estratto conto..."), false, true); + const TString & tipocf = who(); // Dovrebbe essere sempre 'C' + TLocalisamfile cfven(LF_CFVEN); + FOR_EACH_ASSOC_STRING(_lastnumcf, obj, key, str) + { + pi.addstatus(1); + cfven.put(CFV_TIPOCF, tipocf); + cfven.put(CFV_CODCF, key); + const int err = cfven.read(); + if (err != NOERR) + { + cfven.zero(); + cfven.put(CFV_TIPOCF, tipocf); + cfven.put(CFV_CODCF, key); + } + cfven.put("NUMESC", str); + cfven.put("DATAESC", get(F_DATASEND)); + if (err == NOERR) + cfven.rewrite(); + else + cfven.write(); + } + if (_tiponumec == 'G') + { + TConfig c(CONFIG_DITTA, "cg"); + + c.set("LastEC", _lastnumec); + } + } + else + { + // Ripristino vecchio numero di estratto conto sulla maschera + if (_tiponumec == 'G') + { + TConfig c(CONFIG_DITTA, "cg"); + _lastnumec = c.get_long("LastEC"); + } + } + _lastnumcf.destroy(); // Azzera comunque elenco EC stampati + } +} + +void TEC_mask::update_numec(const TRectype& clf, int sign) +{ + const char tipocf = clf.exist(CLI_TIPOCF) ? clf.get_char(CLI_TIPOCF) : ' '; + + if (_tiponumec > ' ' && tipocf == 'C' && _form->printing()) + { + TForm_item& nec = form().find_field('H', odd_page, PEC_NUMPROG); + + if (nec.shown()) + { + const TString8 codcf = clf.get(CLI_CODCF); + TString16 num; + switch (_tiponumec) + { + case 'A': + if (sign > 0) + { + TString16 key; + key.format("%c|%s", tipocf, (const char*)codcf); + const TRectype& cfven = cache().get(LF_CFVEN, key); + num << (cfven.get_long("NUMESC") + 1); + } + break; + case 'G': + if (sign > 0) + { + _lastnumec++; + num << _lastnumec; + } + else + _lastnumec--; + break; + default: + break; + } + if (num.full()) + { + nec.set(num); + _lastnumcf.add(codcf, num); + } + else + _lastnumcf.remove(codcf); + } + } +} + +bool TEC_mask::some_to_print(const char * tipo, const long codice) +{ + TRelation rel(LF_PARTITE); + TRectype filter(rel.curr()); + TRectype & fcrec = _form->cursor()->curr(); + + if (fcrec.num() == LF_CLIFO) + { + filter.put(PART_TIPOCF, tipo); + filter.put(PART_SOTTOCONTO, codice); + } + else + { + filter.zero(PART_TIPOCF); + filter.put(PART_GRUPPO, _form->cursor()->curr().get(PCN_GRUPPO)); + filter.put(PART_CONTO, _form->cursor()->curr().get(PCN_CONTO)); + filter.put(PART_SOTTOCONTO, _form->cursor()->curr().get(PCN_SOTTOCONTO)); + } + + TCursor cur(&rel, "", 1, &filter, &filter); + const long items = cur.items(); + bool any_to_print = false; + const bool stampa_chiuse = get_bool(F_STAMPCHIU); + const TDate data_chiuse = get(F_DATACHIU); + TString8 last_game; + int last_year = 0; + + cur.freeze(); + for (cur = 0; cur.pos() < items; ++cur) + { + const TRectype & curr = cur.curr(); + const int curr_year = curr.get_int(PART_ANNO); + const TString& curr_game = curr.get(PART_NUMPART); + + if (curr_year == last_year && curr_game == last_game) + continue; + last_game = curr_game; + last_year = curr_year; + + TPartita game(curr); + + // Non fregare i clienti agli altri agenti! + if (_games != nullptr && !_games->has_game(curr)) + continue; + const TDate& dir = _form->data_inizio_rischio(); + const TDate& dlo = _form->data_limite_operazione(); + const TDate& dls = _form->data_limite_scaduto(); + const TImporto saldo = game.calcola_saldo_al(_form->in_valuta(), dlo, dls, dir); + + if (saldo.is_zero()) + { + if (stampa_chiuse) + { + int r = 0; + + for (r = game.last(); r > 0; r = game.pred(r)) + { + const TRiga_partite& riga = game.riga(r); + + if (riga.is_fattura()) + { + const TDate dd = riga.get(PART_DATADOC); + + if (dd >= data_chiuse) + break; + } + } + any_to_print |= (r > 0); + } + } + else + any_to_print = true; + } + return any_to_print; +} + +// Nuovo modo con cursore +int TEC_mask::print_one(const char * tipo, const long codice) +{ + TWait_cursor hourglass; + const bool printing = _form->printing(); + int printed = 0; // Non ho stampato ancora nulla + + if (printing && _form->cursor()->curr().num() == LF_CLIFO) + { + // make controllations per lingua profilo/CF + const TString & lincf = _form->cursor()->curr().get(CLI_CODLIN); + const TString & lind = ini_get_string(CONFIG_DITTA, "cg", "CodLin"); + const TString & linf = _form->lingua(); + bool ok = true; + + if (linf == lind && lincf.full()) + ok = (lincf == linf); + if (linf != lind) + ok = (lincf == linf); + if (!ok) // Cliente analfabeta + return -1; + } + + if (some_to_print(tipo, codice)) + { + TToken_string key(tipo); + + key.add(codice); + _form->set_agente(cache().get(LF_CFVEN, key, CFV_CODAG)); + _form->set_pagam(cache().get(LF_CLIFO, key, CLI_CODPAG)); + _form->azzera_totali(); // Azzera totali di fine pagina + + // Filtra solo le partite del cliente selezionato + TRectype & fcrec = _form->cursor()->curr(); + TRelation rel(LF_PARTITE); + TRectype filter(rel.curr()); + + if (fcrec.num() == LF_CLIFO) + { + filter.put(PART_TIPOCF, tipo); + filter.put(PART_SOTTOCONTO, codice); + } + else + { + filter.zero(PART_TIPOCF); + filter.put(PART_GRUPPO, _form->cursor()->curr().get(PCN_GRUPPO)); + filter.put(PART_CONTO, _form->cursor()->curr().get(PCN_CONTO)); + filter.put(PART_SOTTOCONTO, _form->cursor()->curr().get(PCN_SOTTOCONTO)); + } + + TCursor cur(&rel, "", 1, &filter, &filter); + const long items = cur.items(); + const bool stampa_chiuse = get_bool(F_STAMPCHIU); + const TDate data_chiuse = get(F_DATACHIU); + TString status; + TString8 last_game; + int last_year = 0; + + cur.freeze(); + if (printing && fcrec.num() == LF_CLIFO) + update_numec(fcrec, +1); // Incrementa contatore + for (cur = 0; cur.pos() < items; ++cur) + { + const TRectype & curr = cur.curr(); + const int curr_year = curr.get_int(PART_ANNO); + const TString& curr_game = curr.get(PART_NUMPART); + + if (curr_year == last_year && curr_game == last_game) + continue; + last_game = curr_game; + last_year = curr_year; + + TPartita game(curr); + + // Non fregare i clienti agli altri agenti! + if (_games != nullptr && !_games->has_game(curr)) + continue; + const TDate& dir = _form->data_inizio_rischio(); + const TDate& dlo = _form->data_limite_operazione(); + const TDate& dls = _form->data_limite_scaduto(); + const TImporto saldo = game.calcola_saldo_al(_form->in_valuta(), dlo, dls, dir); + + if (saldo.is_zero() && stampa_chiuse) + { + int r = 0; + + for (r = game.last(); r > 0; r = game.pred(r)) + { + const TRiga_partite& riga = game.riga(r); + + if (riga.is_fattura()) + { + const TDate dd = riga.get(PART_DATADOC); + + if (dd >= data_chiuse) + break; + } + } + if (r == 0) + continue; + } + status.cut(0); + status << game.anno() << ' ' << game.numero(); + xvtil_statbar_set(status); + do_events(); + if (printing) + { + if (printed) + { + TPrintrow empty; // Salta una riga vuota + printer().print(empty); // (Non farlo alla fine di ogni partita!) + } + if (printer().frozen()) + break; + } + + if (_form->print_game(game)) + printed++; + } + + if (printing) + { + if (printed > 0) + { + _form->ultima_pagina(); + printer().formfeed(); + } + else + update_numec(_form->cursor()->curr(), -1); + } + else + { + if (printed > 0 && _form->stampa_saldo()) + { + _form->export_total(); + // f.recordset().new_rec(); + } + } + } + xvtil_statbar_set(nullptr); + return printed; +} diff --git a/src/sc/sc2101.h b/src/sc/sc2101.h index 637264990..7be0f262e 100755 --- a/src/sc/sc2101.h +++ b/src/sc/sc2101.h @@ -1,26 +1,164 @@ #ifndef __SC2101_H #define __SC2101_H +#ifndef __TEXTSET_H +#include "textset.h" +#endif + #ifndef __SCSELECT_H #include "scselect.h" #endif +class TEC_mask; + +class TEC_recordset : public TAS400_recordset +{ + TString4 _who; + TString _agente; + TString _pagam; + +public: + const TString & who() const { return _who; } + TString & set_agente(const char * agente) { _agente = agente; return _agente; } + TString & set_pagam(const char * pagam) { _pagam = pagam; return _pagam; } + void add_fields(); + TEC_recordset(const char * who); +}; + +/////////////////////////////////////////////////////////// +// TEC_gamelist +/////////////////////////////////////////////////////////// + +class TEC_Game_list +{ + TAssoc_array _games; + +protected: + void signature(const TRectype& rec, TToken_string& signature) const; + +public: + void add_game(const TRectype& rec); + bool has_clifo(long codcf); + bool has_game(const TRectype& rec); +}; + +/////////////////////////////////////////////////////////// +// TEC_form +/////////////////////////////////////////////////////////// + +class TEC_form : public TESSL_form +{ + friend class TEC_row; + + static TEC_form* _form; + TEC_recordset* _recordset; + + enum { MAXTOT = 16 }; + + TCursor* _cursore; + TTotalizer _totali; + bool _export; + + TString _lingua; // Codice lingua del form + TDate _dlo, _dls, _dir; // Data limite operazione, scaduto e inizio rischio + int _giorni_rischio; // Numero giorni rischio nella maschera di selezione + bool _in_valuta; // Il form e' in valuta + int _fincatura; // 0 = nessuna, 1 = testo, 2 = grafica + word _num_rip; // Numero di righe usate per i riporti + word _total_rows; // Numero di righe usate per i totali + word _maxtot; // Numero massimo di totali da stampare + bool _stampa_saldo; // Stampa il saldo di ogni partita + bool _note_scadenti; // Considera scadute le note di credito non assegnate + +protected: + void init_header(const TMask& m); + word ordina_totali_per_valuta(THash_object* tot[MAXTOT]); + + int find_magic(TString& s, TString& magic1, TString& magic2) const; + void change_magic_body(const TEC_row& o, TString& s); + void change_magic_footer(const THash_object& o, TString& s); + void print_total(int riga, const THash_object& o); + + void stampa_testata(TPrinter& p); + void stampa_pedata(); + void stampa_riporti(TPrinter& p); + + static void ec_header_handler(TPrinter& p); + static void ec_footer_handler(TPrinter& p); + +public: + TTotalizer& totali() { return _totali; } + + virtual TRelation* relation() const { return _cursore->relation(); } + virtual TCursor* cursor() { return _cursore; } + virtual TEC_recordset* recordset() { return _recordset; } + + const TDate& data_limite_operazione() const { return _dlo; } + const TDate& data_limite_scaduto() const { return _dls; } + int giorni_rischio() const { return _giorni_rischio; } + const TDate& data_inizio_rischio() const { return _dir; } + bool note_scadenti() const { return _note_scadenti; } + + const TString& lingua() const { return _lingua; } + bool in_valuta() const { return _in_valuta; } + const TString& describe(short id, char sez = 'H', pagetype pt = last_page) const; + + void azzera_totali(); + void ultima_pagina(); + bool print_game(const TPartita& game); + bool stampa_saldo() const { return _stampa_saldo; } + void stampa_saldo(bool ss) { _stampa_saldo = ss; } + + void set_agente(const TString& codag); + + bool exporting() const { return _export; } + bool printing() const { return !exporting(); } + void set_export(const bool on) { _export = on; } + void export_total(); + + void set_pagam(const TString& codpag); + + + + TEC_recordset& recordset() const { CHECK(_export == true, "Not exporting"); return *_recordset; } + + TEC_form(const TEC_mask& m, bool gesval); + virtual ~TEC_form(); +}; + class TEC_mask : public TSelection_mask { TRelation _ditta; - TString _tmp; + TMail_mask _ec_mail; + TEC_form * _form; + TEC_Game_list * _games; + char _tiponumec; // Tipo numerazione EC ' ', 'G', 'A' + long _lastnumec; // Ultimo numero EC 'G' + TAssoc_array _lastnumcf; // Ultimo numero stampato 'A' + bool _export; + protected: // TMask virtual void on_firm_change(); virtual void start_run(); - static bool lingua_handler(TMask_field& f, KEY k); - static bool codprof_handler(TMask_field& f, KEY k); + virtual TESSL_form & form() override; + virtual const TToken_string & get_anal_filter() const override { return EMPTY_STRING; } + virtual bool some_to_print(const char * tipo, const long codice) override; + virtual int print_one(const char * tipo, const long codice) override; + bool print_selected(); // print selected items + void save_numec(); + void update_numec(const TRectype& clf, int sign); + + void find_agents_scads(TAssoc_array& agents); + void find_agents_unassigned_pags(TAssoc_array& agents); + long find_agents_games(TAssoc_array& agents); + bool print_agents(); // print selected items by agent + virtual TMail_mask & mail_mask() override { return _ec_mail; } public: - const char* get_prof_base() const; - const TString& get_prof_code() const; - const TString& get_prof_lang() const; - const char* get_prof_name() const; + virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); + bool export_print() const { return _export; } + void set_export(bool on = true) { _export = on; } TEC_mask(const char* name); virtual ~TEC_mask(); diff --git a/src/sc/sc21pec.h b/src/sc/sc21pec.h index 1aff944df..19cd9b270 100755 --- a/src/sc/sc21pec.h +++ b/src/sc/sc21pec.h @@ -51,9 +51,9 @@ #define PEC_PICTURE 500 -#define RIGA_PART_PAGAMENTO 10001 -#define RIGA_PART_ABBUONI 10002 -#define RIGA_PART_DIFFCAM 10003 -#define RIGA_PART_RITENUTE 10004 +#define RIGA_PAGAMENTO 10001 +#define RIGA_ABBUONI 10002 +#define RIGA_DIFFCAMBI 10003 +#define RIGA_RITENUTE 10004 #endif diff --git a/src/sc/sc2200.cpp b/src/sc/sc2200.cpp index c8a965a2b..7b376c22d 100755 --- a/src/sc/sc2200.cpp +++ b/src/sc/sc2200.cpp @@ -17,8 +17,6 @@ #define PCONSCAD_ALIAS 54 #define MaxRowsForTotal 17 -#define TPString TParagraph_string // Comodita'... - struct _LinearTotal : public TObject // Oggetto base per gli elementi di tlg, tlm, tlp { // Contiene i totali da stampare su una linea real _is, // Importo in scadenza @@ -41,13 +39,10 @@ class TStampaScadenzario : public TPrintapp _cur2, _cur3, _cur4, _cur41, // piu' avanti spiega tutto. _cur5, _cur6, _cur7; TSelection_ext_mask *_m; - TPartita *_p; // Oggetto partita corrente. Viene ricaricato ad ogni cambio partita, - // ovvero ogni volta che la rata corrente cambia i "connotati" - TLocalisamfile *_pagsca; - TString _annopart,_datareg,_numdoc,_datadoc, // Anno partita (2 cifre), data registrazione, nr. documento, data doc. - _protiva, _codval; // Numero di protocollo IVA (TString perche' se vale 0 non stampa nulla), e codice valuta - TString _last_ban, _desc_ban; // Banca correntemente in corso di raggruppamento - TPString *_descrizione,*_ragsoc,*_des_conto; // Descrizione (da LF_PARTITE), ragione sociale (da LF_CLIFO) + TString _annopart,_datareg,_numdoc,_datadoc, // Anno partita (2 cifre), data registrazione, nr. documento, data doc. + _protiva, _codval; // Numero di protocollo IVA (TString perche' se vale 0 non stampa nulla), e codice valuta + TString _last_ban, _desc_ban; // Banca correntemente in corso di raggruppamento + TParagraph_string _descrizione,_ragsoc, _des_conto; // Descrizione (da LF_PARTITE), ragione sociale (da LF_CLIFO) // Descrizione conto (da LF_PCON) TString _imp_scad,_imp_pag,_rimdir,_riba,_altri,_bonifico, // Valori calcolati in preprocess_page: rimesse dirette, Ri.ba e altri _cur_gr_s, _cur_co_s, _cur_codcf_s; // _imp_scad e _imp_pag vengono anch'essi calcolati in preprocess_page. @@ -61,7 +56,6 @@ class TStampaScadenzario : public TPrintapp _end_printed, // VERO=riepilogo finale da stampare _ratesald, // VERO=stampa anche le rate saldate _ordata, // VERO=ordine primario per data, FALSO=ordine primario impostato da _ordcod - _ordcod, // VERO=ordine per codice, FALSO=ordine per ragione sociale _stvaluta, // Vero se abilitata la stampa in valuta; _group_ban, // Vero se abilitato il raggruppamento per banca _totbank_printed; // Vero se é stato stampato il totale per banca @@ -100,7 +94,8 @@ class TStampaScadenzario : public TPrintapp // chiave relativa alla partita, ed eventualmente utilizzare tale valore in memoria. static bool filter_func(const TRelation *); // Funzione di filtro [_datai.._dataf] -public: +public: + TSelection_ext_mask & mask() const { return *_m; } // print functions virtual bool preprocess_page(int file, int counter); // Qui stampa i totali e i riepiloghi virtual bool preprocess_print(int file, int counter); // Qui non fa proprio nulla! @@ -130,21 +125,20 @@ public: void check_add_key_to_tp(int t, char u); // controlla e aggiunge i valori relativi alla chiave k ai totali del prospetto void check_add_key_to_tl(tipo_pe p, int t); // controlla e aggiunge i valori elaborati all'assoc array indicato dal periodo (_tlxxx) // Ritorna true se la partita corrente _p non e' piu' riferita alla scadenza corrente - bool scad_changed(char tipo, int gruppo, int conto, long codcf, int anno, const TString& nump); + bool scad_changed(const TPartita & p, char tipo, int gruppo, int conto, long codcf, int anno, const TString& nump); // Ritorna true se la scadenza corrente ha una banca diversa dalla precedente // bool bank_will_change(); // Totalizza i pagamenti non assegnati per la partita corrente (NB si spera che siano tutti nella stessa valuta) bool in_cache(const TString& k); // ritorna vero se ci sono gia' non assegnati in _uns_cache; - void look_in_cache(real& a, real& b, real& c, TAssoc_array& uns, TAssoc_array& unsnc, TAssoc_array& unsins, TString& k); - void calcola_unassigned(const TString& k); - void calcola_pagamenti(real& imp_scad, int riga, int rata, TBill& bill); // calcola i pagamenti effettuati per questa rata e il residuo eventuale + void look_in_cache(const TPartita & p, real& a, real& b, real& c, TAssoc_array& uns, TAssoc_array& unsnc, TAssoc_array& unsins, TString& k); + void calcola_unassigned(const TPartita & p, const TString& k); + void calcola_pagamenti(const TPartita & p, real& imp_scad, int riga, int rata, TBill& bill); // calcola i pagamenti effettuati per questa rata e il residuo eventuale const char * tipi_tab(int tipo) const; - TLocalisamfile& pagamenti() const { return *_pagsca; } - void print_intestazione_banca(int &nriga); - TStampaScadenzario(); + TStampaScadenzario() : _m(nullptr), _rel1(nullptr), _rel2(nullptr), _rel3(nullptr), + _descrizione(19), _ragsoc(19), _des_conto(19) {} }; inline TStampaScadenzario& app() {return (TStampaScadenzario&)main_app();} @@ -177,7 +171,7 @@ const TString& TScadenza_rec::get_str(const char* fieldname) const rec.put(PAGSCA_NRIGA, TRectype::get_str(SCAD_NRIGA)); rec.put(PAGSCA_NRATA, TRectype::get_str(SCAD_NRATA)); - TLocalisamfile& pagamenti = app().pagamenti(); + TLocalisamfile pagamenti(LF_PAGSCA); TRectype& curpag = pagamenti.curr(); bool found = curpag.compare_key(rec,1,1) == 0; if (!found) @@ -345,11 +339,10 @@ void TStampaScadenzario::check_add_key_to_tp(int t, char u) _tp.add(k,_w_imp_res); } -bool TStampaScadenzario::scad_changed(char tipo, int gruppo, int conto, long codcf, int anno, const TString& nump) +bool TStampaScadenzario::scad_changed(const TPartita & p, char tipo, int gruppo, int conto, long codcf, int anno, const TString& nump) { - if (_p == NULL) - return true; - TRiga_partite& rp = _p->riga(_p->first()); + TRiga_partite& rp = p.riga(p.first()); + if (tipo != rp.get_char(PART_TIPOCF) || gruppo != rp.get_int(PART_GRUPPO) || conto != rp.get_int(PART_CONTO) || codcf != rp.get_long(PART_SOTTOCONTO) || anno != rp.get_int(PART_ANNO) || nump != rp.get(PART_NUMPART)) @@ -391,7 +384,7 @@ bool TStampaScadenzario::in_cache(const TString& k) return rt; } -void TStampaScadenzario::calcola_unassigned(const TString& k) +void TStampaScadenzario::calcola_unassigned(const TPartita & p, const TString& k) // Calcola i pagamenti non assegnati normali, e quelli riferiti a note di credito // ovvero quelli con tipo di movimento 2. Vanno percio' tenuti separati due totali: // _uns_cache[0] per i non assegnati normali, utilizzato per i pagamenti; @@ -401,13 +394,13 @@ void TStampaScadenzario::calcola_unassigned(const TString& k) TAssoc_array& unsnc = (TAssoc_array&) _uns_cache[1]; TAssoc_array& unsins = (TAssoc_array&) _uns_cache[2]; - real a,b,c; - - TRecord_array& ra = _p->unassigned(); + real a, b, c; + TRecord_array& ra = ((TPartita &) p).unassigned(); + for (int r = ra.last_row(); r > 0; r = ra.pred_row(r)) { const TRectype& rec = ra.row(r); - const TRiga_partite& sum = _p->riga(rec.get_int(PAGSCA_NRIGP)); + const TRiga_partite& sum = p.riga(rec.get_int(PAGSCA_NRIGP)); const char* field = (_stvaluta && sum.in_valuta() ? PAGSCA_IMPORTOVAL : PAGSCA_IMPORTO); const tipo_movimento tm = (tipo_movimento)sum.get_int(PART_TIPOMOV); @@ -428,12 +421,13 @@ void TStampaScadenzario::calcola_unassigned(const TString& k) unsins.add(k,c,true); } -void TStampaScadenzario::look_in_cache(real& a, real& b, real& c, +void TStampaScadenzario::look_in_cache(const TPartita & p, real& a, real& b, real& c, TAssoc_array& uns, TAssoc_array& unsnc, TAssoc_array& unsins, TString& k) //Estrae dai tassoc_array i valori, relativi alla partita corrente, di uns e unsnc, mettendoli in a e b { - TRiga_partite& rp = _p->riga(_p->first()); + TRiga_partite& rp = p.riga(p.first()); + k << rp.get_char(PART_TIPOCF) << rp.get_int(PART_GRUPPO); k << rp.get_int(PART_CONTO) << rp.get_long(PART_SOTTOCONTO); k << rp.get_int(PART_ANNO); @@ -445,20 +439,20 @@ void TStampaScadenzario::look_in_cache(real& a, real& b, real& c, if (unsins.is_key(k)) c = (real&)unsins[k]; } -void TStampaScadenzario::calcola_pagamenti(real& imp_scad, int riga, int rata, TBill& bill) +void TStampaScadenzario::calcola_pagamenti(const TPartita & p, real& imp_scad, int riga, int rata, TBill& bill) { _w_imp_blocked = false; - if (!_p->esiste(riga, rata)) + if (!p.esiste(riga, rata)) { imp_scad = _w_imp_pag = _w_imp_res = ZERO; error_box("Nella partita %c %ld %d %s la rata %d non corrisponde ad una riga di fattura (%d)", - bill.tipo(), bill.codclifo(), _p->anno(), (const char*)_p->numero(), rata, riga); + bill.tipo(), bill.codclifo(), p.anno(), (const char*) p.numero(), rata, riga); return; } - const TRiga_scadenze& rs = _p->rata(riga, rata); + const TRiga_scadenze& rs = p.rata(riga, rata); // Non perder tempo con partite chiuse! - if (!_ratesald && (rs.chiusa() || _p->chiusa(true))) + if (!_ratesald && (rs.chiusa() || p.chiusa(true))) { imp_scad = rs.importo(_stvaluta).valore(); _w_imp_pag = imp_scad; @@ -470,22 +464,23 @@ void TStampaScadenzario::calcola_pagamenti(real& imp_scad, int riga, int rata, T TAssoc_array& unsnc = (TAssoc_array&)_uns_cache[1]; TAssoc_array& unsins = (TAssoc_array&)_uns_cache[2]; - const char ssez = _p->riga(riga).sezione(); + const char ssez = p.riga(riga).sezione(); const char* field = (_stvaluta && rs.in_valuta()) ? PAGSCA_IMPORTOVAL : PAGSCA_IMPORTO; const char* sfield = (_stvaluta && rs.in_valuta()) ? SCAD_IMPORTOVAL : SCAD_IMPORTO; TImporto totalep, // Totale dei pagamenti scdz; // Importo in scadenza scdz += TImporto(ssez,rs.get_real(sfield)); totalep += rs.importo_pagato(_stvaluta); // Quanto e' stato pagato per questa scadenza? - for (int p = rs.last(); p > 0; p = rs.pred(p)) // Calcola il totale pagamenti e discrimina + for (int r = rs.last(); r > 0; r = rs.pred(r)) // Calcola il totale pagamenti e discrimina { // Il TIPOMOV: 1,5 : fattura insoluto - const TRectype pag = rs.row(p); // 2 : nota di credito - const TRiga_partite& sum = _p->riga(p); // 3,4,6 : incasso/pagamento/abbuono/pag.insoluto/diff.cambio/rit.prof + const TRectype pag = rs.row(r); // 2 : nota di credito + const TRiga_partite& sum = p.riga(r); // 3,4,6 : incasso/pagamento/abbuono/pag.insoluto/diff.cambio/rit.prof const char sez = sum.sezione(); const tipo_movimento tipomov = (tipo_movimento)sum.get_int(PART_TIPOMOV); // se tipomov e' 2 (Nota di credito assegnata) // storna da scdz. In entrambi i casi si ha l'operatore +=, perche' nel TImporto e' gia' // compresa la sezione opposta + if (tipomov == tm_nota_credito) { const TImporto work_imp = TImporto(sez,pag.get_real(field)); @@ -505,7 +500,7 @@ void TStampaScadenzario::calcola_pagamenti(real& imp_scad, int riga, int rata, T imp_scad = scdz.valore(); real a,b,c; TString80 k; - look_in_cache(a,b,c,uns,unsnc,unsins,k); + look_in_cache(p, a, b, c,uns, unsnc, unsins, k); if (b > ZERO) // Scala le note di credito dalle scadenze { const real gap = b > imp_scad ? imp_scad : b; @@ -561,7 +556,7 @@ const char* TStampaScadenzario::tipi_tab(int tipo) const case 9: return TR("Bonifici"); default: break; } - return ""; + return EMPTY_STRING; } bool TStampaScadenzario::preprocess_page(int file, int counter) @@ -603,38 +598,30 @@ bool TStampaScadenzario::preprocess_page(int file, int counter) if (!_m->selected(bill)) return false; - _descrizione->restart(); - if (scad_changed(tipoc,gruppo,conto,codcf,annop,nump)) - { - TRectype rp(LF_PARTITE); - rp.put(PART_TIPOCF,tipoc); - rp.put(PART_GRUPPO,gruppo); - rp.put(PART_CONTO,conto); - rp.put(PART_SOTTOCONTO,codcf); - rp.put(PART_ANNO,annop); - rp.put(PART_NUMPART,nump); - if (_p) delete _p; - _p = new TPartita(rp); - - TString80 k; // compone la chiave dei tassoc_array dentro a _uns_cache - k << tipoc << gruppo ; - k << conto << codcf; - k << annop << nump; - if (!in_cache(k)) - calcola_unassigned(k); - TRiga_partite& row = _p->riga(nrigap); - _datareg = row.get_date(PART_DATAREG).string(brief); - _datadoc = row.get_date(PART_DATADOC).string(brief); - _numdoc = row.get(PART_NUMDOC); - _protiva.format("%5ld",row.get_long(PART_PROTIVA)); - *_descrizione = row.get(PART_DESCR); - _codval = row.get(PART_CODVAL); - //Per indicare che non e' indicata la valuta o e' Euro (se la stampa in valuta is disabled) - if (_codval.empty() || !_stvaluta) _codval = " "; - if (_descrizione->items() == 0) // Se sulla partita non c'e' descrizione allora va leggerla sulla causale. - *_descrizione = cache().get(LF_CAUSALI, row.get(PART_CODCAUS), CAU_DESCR); - } - calcola_pagamenti(imp_scad,nrigap,nratap, bill); +// _descrizione.restart(); + + TPartita p(bill, annop, nump); + TString80 k; // compone la chiave dei tassoc_array dentro a _uns_cache + + k << tipoc << gruppo ; + k << conto << codcf; + k << annop << nump; + if (!in_cache(k)) + calcola_unassigned(p, k); + + TRiga_partite& row = p.riga(nrigap); + + _datareg = row.get_date(PART_DATAREG).string(brief); + _datadoc = row.get_date(PART_DATADOC).string(brief); + _numdoc = row.get(PART_NUMDOC); + _protiva.format("%5ld",row.get_long(PART_PROTIVA)); + _descrizione = row.get(PART_DESCR); + _codval = row.get(PART_CODVAL); + //Per indicare che non e' indicata la valuta o e' Euro (se la stampa in valuta is disabled) + if (_codval.empty() || !_stvaluta) _codval = " "; + if (_descrizione.blank()) // Se sulla partita non c'e' descrizione allora va leggerla sulla causale. + _descrizione = cache().get(LF_CAUSALI, row.get(PART_CODCAUS), CAU_DESCR); + calcola_pagamenti(p, imp_scad, nrigap, nratap, bill); // Se la rata e' stata saldata e non e' abilitato il flag di stampa // oppure l'importo in scadenza e' 0 allora salta alla prossima scadenza @@ -644,11 +631,11 @@ bool TStampaScadenzario::preprocess_page(int file, int counter) _annopart.format("%d",annop); _annopart.ltrim(2); - _rimdir = ""; - _riba = ""; - _bonifico = ""; - _altri = ""; - _imp_pag = ""; + _rimdir = EMPTY_STRING; + _riba = EMPTY_STRING; + _bonifico = EMPTY_STRING; + _altri = EMPTY_STRING; + _imp_pag = EMPTY_STRING; const bool print_in_valuta = _stvaluta && is_true_value(_codval); const TString& divisa = print_in_valuta ? _codval : EMPTY_STRING; @@ -680,11 +667,11 @@ bool TStampaScadenzario::preprocess_page(int file, int counter) if (file == LF_CLIFO) { - TString80 xxx = current_cursor()->curr(LF_CLIFO).get(CLI_RAGSOC); - *_ragsoc = xxx.strip_double_spaces(); + _ragsoc = current_cursor()->curr(LF_CLIFO).get(CLI_RAGSOC); + _ragsoc.strip_double_spaces(); } if (file == LF_PCON) - *_des_conto = current_cursor()->curr(LF_PCON).get(PCN_DESCR); + _des_conto = current_cursor()->curr(LF_PCON).get(PCN_DESCR); // Se l'ordinamento principale e' per data scadenza stampa il totale del giorno e del mese if (_ordata && !_end_printed) @@ -705,7 +692,7 @@ bool TStampaScadenzario::preprocess_page(int file, int counter) for (int i=1; ilfile().set_curr(new TScadenza_rec); - _rel1->add(LF_CLIFO,"TIPOCF=TIPOC|CODCF=SOTTOCONTO",1,0,SCADCLIFO_ALIAS); - _cur1 = add_cursor(new TSorted_cursor(_rel1,"DATASCAD|SOTTOCONTO|ANNO|NUMPART|NRIGA|NRATA","",2)); + _rel1->add(LF_CLIFO, "TIPOCF=TIPOC|CODCF=SOTTOCONTO",1,0,SCADCLIFO_ALIAS); + _cur1 = add_cursor(new TSorted_cursor(_rel1,"DATASCAD|SOTTOCONTO|ANNO|NUMPART|NRIGA|NRATA",EMPTY_STRING,2)); // Per data scadenza + ragione sociale e' necessario un TSorted_cursor con update del file collegato: - _cur11 = add_cursor(new TSorted_cursor(_rel1,"DATASCAD|UPPER(20->RAGSOC)|ANNO|NUMPART|NRIGA|NRATA","",2)); + _cur11 = add_cursor(new TSorted_cursor(_rel1,"DATASCAD|UPPER(20->RAGSOC)|ANNO|NUMPART|NRIGA|NRATA",EMPTY_STRING,2)); // Scadenze per CliFo (Codice & Ragione sociale) + data scadenza - _cur2 = add_cursor(new TSorted_cursor(_rel1,"SOTTOCONTO|DATASCAD|ANNO|NUMPART|NRIGA|NRATA","",2)); - _cur3 = add_cursor(new TSorted_cursor(_rel1,"UPPER(20->RAGSOC)|DATASCAD|ANNO|NUMPART|NRIGA|NRATA","",2)); + _cur2 = add_cursor(new TSorted_cursor(_rel1,"SOTTOCONTO|DATASCAD|ANNO|NUMPART|NRIGA|NRATA",EMPTY_STRING,2)); + _cur3 = add_cursor(new TSorted_cursor(_rel1,"UPPER(20->RAGSOC)|DATASCAD|ANNO|NUMPART|NRIGA|NRATA",EMPTY_STRING,2)); _rel2 = new TRelation(LF_SCADENZE); // Scadenze per data scadenza + piano dei conti (Codice & Descrizione) _rel2->lfile().set_curr(new TScadenza_rec); _rel2->add(LF_PCON,"GRUPPO=GRUPPO|CONTO=CONTO|SOTTOCONTO=SOTTOCONTO",1,0,SCADPCON_ALIAS); - _cur4 = add_cursor(new TSorted_cursor(_rel2,"DATASCAD|GRUPPO|CONTO|SOTTOCONTO|ANNO|NUMPART|NRIGA|NRATA","",2)); + _cur4 = add_cursor(new TSorted_cursor(_rel2,"DATASCAD|GRUPPO|CONTO|SOTTOCONTO|ANNO|NUMPART|NRIGA|NRATA",EMPTY_STRING,2)); // Per data scadenza + descrizione e' necessario un TSorted_cursor con update del file collegato: - _cur41 = add_cursor(new TSorted_cursor(_rel2,"DATASCAD|UPPER(19->DESCR)|ANNO|NUMPART|NRIGA|NRATA","",2)); + _cur41 = add_cursor(new TSorted_cursor(_rel2,"DATASCAD|UPPER(19->DESCR)|ANNO|NUMPART|NRIGA|NRATA",EMPTY_STRING,2)); // Scadenze per Conti (Codice & descrizione) + data scadenza - _cur5 = add_cursor(new TSorted_cursor(_rel2,"GRUPPO|CONTO|SOTTOCONTO|DATASCAD|ANNO|NUMPART|NRIGA|NRATA","",2)); - _cur6 = add_cursor(new TSorted_cursor(_rel2,"UPPER(19->DESCR)|DATASCAD|ANNO|NUMPART|NRIGA|NRATA","",2)); + _cur5 = add_cursor(new TSorted_cursor(_rel2,"GRUPPO|CONTO|SOTTOCONTO|DATASCAD|ANNO|NUMPART|NRIGA|NRATA",EMPTY_STRING,2)); + _cur6 = add_cursor(new TSorted_cursor(_rel2,"UPPER(19->DESCR)|DATASCAD|ANNO|NUMPART|NRIGA|NRATA",EMPTY_STRING,2)); _rel3 = new TRelation(LF_SCADENZE); // Scadenze (Tutte) per data scadenza _rel3->lfile().set_curr(new TScadenza_rec); - _cur7 = add_cursor(new TCursor(_rel3,"",2)); - + _cur7 = add_cursor(new TCursor(_rel3,EMPTY_STRING,2)); open_files(LF_TABCOM, LF_TAB, LF_CAUSALI, LF_PARTITE, LF_PAGSCA, 0); - - _pagsca = new TLocalisamfile(LF_PAGSCA); - _descrizione = new TParagraph_string("",19); - _ragsoc = new TParagraph_string("",19); - _des_conto = new TParagraph_string("",19); - _tl.add(new TAssoc_array);_tl.add(new TAssoc_array);_tl.add(new TAssoc_array);_tl.add(new TAssoc_array); _uns_cache.add(new TAssoc_array); // Pagamenti _uns_cache.add(new TAssoc_array); // Note di credito @@ -928,17 +911,9 @@ bool TStampaScadenzario::user_destroy() // dalla printapp, poiche' e' lei stessa che // effettua tale operazione nella propria destroy(). // - if (_rel1) delete _rel1; - if (_rel2) delete _rel2; - if (_rel3) delete _rel3; - if (_pagsca) - delete _pagsca; - if (_descrizione) - delete _descrizione; - if (_des_conto) - delete _des_conto; - if (_ragsoc) - delete _ragsoc; + safe_delete(_rel1); + safe_delete(_rel2); + safe_delete(_rel3); _tl.destroy(); _uns_cache.destroy(); _tm.destroy(); @@ -965,20 +940,39 @@ bool TStampaScadenzario::set_print(int) _m->reset(F_SORTBAN); _m->reset(F_CODAG); _m->reset(F_TIPOPAG); - const bool ok = _m->run() == K_ENTER; + + TDate data = today; + + data.set_day(1); + if (!_m->get_date(F_DATASCADENZAI).ok()) + _m->set(F_DATASCADENZAI, data); + if (!_m->get_date(F_DATAFATTI).ok()) + _m->set(F_DATAFATTI, data); + data.set_end_month(); + if (!_m->get_date(F_DATASCADENZAF).ok()) + _m->set(F_DATASCADENZAF, data); + if (!_m->get_date(F_DATAFATTF).ok()) + _m->set(F_DATAFATTF, data); + + const bool ok = _m->run() == K_ENTER; + if (ok) { _last_bank_rec = 0; _end_printed = false; _totbank_printed = false; + _m->update_assoc(); reset_files(); reset_print(); // Inizializza i membri necessari al calcolo totali nel caso sia stato scelto l'ordine // primario secondo la data di scadenza. - if (_m->get_who() == 'P') _tipost = altri; - else if (_m->get_who() == 'C') _tipost = clienti; - else _tipost = fornitori; - _ordcod = _m->get_selected_key() == 1; // Stampa ordinata per codice? + if (_m->conti()) + _tipost = altri; + else + if (_m->clienti()) + _tipost = clienti; + else + _tipost = fornitori; _group_ban = _m->get_bool(F_SORTBAN); // Raggruppamento per banca di presentazione _codag = _m->get(F_CODAG); // codice agente selezionato _tipopag = _m->get_int(F_TIPOPAG); // tipo pagamento selezionato @@ -998,9 +992,9 @@ bool TStampaScadenzario::set_print(int) // Per calcolare i totali nel caso l'ordine primario non sia per data scadenze // utilizzera' le variabili _tp_* per il totale generale e _tm_* per i singoli totali. // E' necessario resettare anche queste TParagraph_string... Puo' servire in futuro... - *_ragsoc = ""; - *_des_conto = ""; - *_descrizione = ""; + _ragsoc = EMPTY_STRING; + _des_conto = EMPTY_STRING; + _descrizione = EMPTY_STRING; _ratesald = _m->get_bool(F_RATESALDATE); _ordata = _m->get_bool(F_ORDDATA); _stvaluta = _m->get_bool(F_VALUTA); @@ -1043,6 +1037,7 @@ bool TStampaScadenzario::set_print(int) if (!sel_datafatt) { TRectype da_data(LF_SCADENZE), a_data(LF_SCADENZE); + da_data.put(SCAD_DATASCAD,_datai); a_data.put(SCAD_DATASCAD,_dataf); get_cursor(_cur1)->setregion(da_data,a_data); @@ -1055,15 +1050,15 @@ bool TStampaScadenzario::set_print(int) get_cursor(_cur6)->setregion(da_data,a_data); get_cursor(_cur7)->setregion(da_data,a_data); } - get_cursor(_cur1)->setfilter(""); - get_cursor(_cur11)->setfilter(""); - get_cursor(_cur2)->setfilter(""); - get_cursor(_cur3)->setfilter(""); - get_cursor(_cur4)->setfilter(""); - get_cursor(_cur41)->setfilter(""); - get_cursor(_cur5)->setfilter(""); - get_cursor(_cur6)->setfilter(""); - get_cursor(_cur7)->setfilter(""); + get_cursor(_cur1)->setfilter(EMPTY_STRING); + get_cursor(_cur11)->setfilter(EMPTY_STRING); + get_cursor(_cur2)->setfilter(EMPTY_STRING); + get_cursor(_cur3)->setfilter(EMPTY_STRING); + get_cursor(_cur4)->setfilter(EMPTY_STRING); + get_cursor(_cur41)->setfilter(EMPTY_STRING); + get_cursor(_cur5)->setfilter(EMPTY_STRING); + get_cursor(_cur6)->setfilter(EMPTY_STRING); + get_cursor(_cur7)->setfilter(EMPTY_STRING); switch (_tipost) { case tutti: @@ -1072,76 +1067,75 @@ bool TStampaScadenzario::set_print(int) break; case clienti: case fornitori: - if (_ordata) // Ordine primario per data - { // Controlla l'ordine secondario (codice o ragione sociale) - if (_ordcod) // Per codice... - { - select_cursor(_cur1); - if (_tipost==clienti) - get_cursor(_cur1)->setfilter("(TIPOC=\"C\")"); - else - get_cursor(_cur1)->setfilter("(TIPOC=\"F\")"); - } - else - { - select_cursor(_cur11); // Per ragione sociale - if (_tipost==clienti) - get_cursor(_cur11)->setfilter("(TIPOC=\"C\")"); - else - get_cursor(_cur11)->setfilter("(TIPOC=\"F\")"); - } - } - else // Ordine primario per codice o ragione sociale - { - if (_ordcod) // Codice... - { - select_cursor(_cur2); - if (_tipost==clienti) - get_cursor(_cur2)->setfilter("(TIPOC=\"C\")"); - else - get_cursor(_cur2)->setfilter("(TIPOC=\"F\")"); - } - else // Ragione sociale - { - select_cursor(_cur3); - if (_tipost==clienti) - get_cursor(_cur3)->setfilter("(TIPOC=\"C\")"); - else - get_cursor(_cur3)->setfilter("(TIPOC=\"F\")"); - } - } - add_file(LF_SCADENZE); - add_file(LF_CLIFO,LF_SCADENZE); + { + TString filter("(TIPOC = \""); + + filter << _m->who() << "\")"; + if (_ordata) // Ordine primario per data + { + + get_cursor(_cur3)->setfilter(filter); + if (_m->key() == 1) // Per codice... + { + select_cursor(_cur1); + get_cursor(_cur1)->setfilter(filter); + } + else + { + select_cursor(_cur11); // Per ragione sociale + get_cursor(_cur11)->setfilter(filter); + } + } + else // Ordine primario per codice o ragione sociale + { + if (_m->key() == 1) // Codice... + { + select_cursor(_cur2); + get_cursor(_cur2)->setfilter(filter); + } + else // Ragione sociale + { + select_cursor(_cur3); + get_cursor(_cur3)->setfilter(filter); + } + } + add_file(LF_SCADENZE); + add_file(LF_CLIFO, LF_SCADENZE); + } break; case altri: - if (_ordata) // Ordine primario per data - { // Controlla l'ordine secondario (Codice o descrizione) - if (_ordcod) // Per codice ... - { - select_cursor(_cur4); - get_cursor(_cur4)->setfilter("(TIPOC=\"\")"); // Filtro per i conti normali! - } - else - { - select_cursor(_cur41); // Per descrizione. - get_cursor(_cur41)->setfilter("(TIPOC=\"\")"); - } - } - else // Ordine primario per codice o descrizione - { - if (_ordcod) // Codice... - { - select_cursor(_cur5); - get_cursor(_cur5)->setfilter("(TIPOC=\"\")"); // Filtro per i conti normali! - } - else // Descrizione - { - select_cursor(_cur6); - get_cursor(_cur6)->setfilter("(TIPOC=\"\")"); // Filtro per i conti normali! - } - } - add_file(LF_SCADENZE); - add_file(LF_PCON,LF_SCADENZE); + { + const TString filter = "(TIPOC=\"\")"; + + if (_ordata) // Ordine primario per data + { // Controlla l'ordine secondario (Codice o descrizione) + if (_m->key() == 1) // Per codice ... + { + select_cursor(_cur4); + get_cursor(_cur4)->setfilter(filter); // Filtro per i conti normali! + } + else + { + select_cursor(_cur41); // Per descrizione. + get_cursor(_cur41)->setfilter(filter); + } + } + else // Ordine primario per codice o descrizione + { + if (_m->key() == 1) // Codice... + { + select_cursor(_cur5); + get_cursor(_cur5)->setfilter(filter); // Filtro per i conti normali! + } + else // Descrizione + { + select_cursor(_cur6); + get_cursor(_cur6)->setfilter(filter); // Filtro per i conti normali! + } + } + add_file(LF_SCADENZE); + add_file(LF_PCON, LF_SCADENZE); + } break; default: break; @@ -1180,16 +1174,10 @@ bool TStampaScadenzario::set_print(int) } } - if (_p) - { - delete _p; // Questo deve essere cancellato, altrimenti rimane in memoria, - _p = NULL; // provocando casini al prossimo "giro" - } - TAssoc_array& a =(TAssoc_array&) _uns_cache[0]; TAssoc_array& b =(TAssoc_array&) _uns_cache[1]; + a.destroy(); b.destroy(); // Libera i TAssoc_array impiegati. - return ok; } @@ -1225,7 +1213,7 @@ void TStampaScadenzario::print_header() else { set_header(soh++,FR("@56g** SCADENZARIO CLIENTI **")); - s1 = s2 = ""; + s1 = s2 = EMPTY_STRING; } set_header (soh++,FR("@56gPeriodo dal %s al %s"),(const char*)datai,(const char*)dataf); @@ -1282,7 +1270,7 @@ void TStampaScadenzario::print_header() default: break; } - set_header(soh,""); + set_header(soh,EMPTY_STRING); } void TStampaScadenzario::set_page_clifo(int nriga) @@ -1290,13 +1278,13 @@ void TStampaScadenzario::set_page_clifo(int nriga) { if (_group_ban) print_intestazione_banca(nriga); - set_row(nriga++,""); + set_row(nriga++,EMPTY_STRING); set_row(nriga,"@b#6t@r",&_cur_codcf_s); - set_row(nriga,"@b@7g#a@r",_ragsoc); + set_row(nriga,"@b@7g#a@r",&_ragsoc); set_row(nriga,"@28g#2t/@7s",&_annopart,FLD(LF_SCADENZE,SCAD_NUMPART)); set_row(nriga,"@38g@d",FLD(LF_SCADENZE,SCAD_DATASCAD)); set_row(nriga,"@47g#t",&_datareg); - set_row(nriga,"@56g#a",_descrizione); + set_row(nriga,"@56g#a",&_descrizione); set_row(nriga,"@77g@4,rs/@1n",FLD(LF_SCADENZE,SCAD_CODPAG),FLD(LF_SCADENZE,SCAD_TIPOPAG)); set_row(nriga,"@86g@4n",FLD(LF_SCADENZE,SCAD_NRATA)); if (_tipost == fornitori) @@ -1309,7 +1297,7 @@ void TStampaScadenzario::set_page_clifo(int nriga) set_row(nriga,"@164g#15t",&_bonifico); // Bonifico set_row(nriga,"@180g#15t",&_altri); // Altri tipi di pagamento //set_row(nriga,"@198g@1s",FLD(LF_SCADENZE,SCAD_BLOCCATA)); - set_row(nriga,"@197g%s", _w_imp_blocked ? "Si" : ""); + set_row(nriga,"@197g%s", _w_imp_blocked ? "Si" : EMPTY_STRING); nriga++; set_row(nriga,"@28g#t",&_datadoc); set_row(nriga,"@38g#8t",&_numdoc); @@ -1321,12 +1309,12 @@ void TStampaScadenzario::set_page_pcon(int nriga) { if (_group_ban) print_intestazione_banca(nriga); - set_row(nriga++,""); + set_row(nriga++,EMPTY_STRING); set_row(nriga,"@b#3t@5g#3t@9g#6t@r",&_cur_gr_s,&_cur_co_s,&_cur_codcf_s); - set_row(nriga,"@b@16g#a@r",_des_conto); + set_row(nriga,"@b@16g#a@r", &_des_conto); set_row(nriga,"@33g#2t/@7s",&_annopart,FLD(LF_SCADENZE,SCAD_NUMPART)); set_row(nriga,"@43g@d@53g#t",FLD(LF_SCADENZE,SCAD_DATASCAD),&_datareg); - set_row(nriga,"@61g#a",_descrizione); + set_row(nriga,"@61g#a",&_descrizione); set_row(nriga,"@82g@4,rs/@1n@89g@4n",FLD(LF_SCADENZE,SCAD_CODPAG),FLD(LF_SCADENZE,SCAD_TIPOPAG), FLD(LF_SCADENZE,SCAD_NRATA)); set_row(nriga,"@96g#t", &_codval); @@ -1376,14 +1364,17 @@ void TStampaScadenzario::print_rows_riepilogo(int& nriga, bool type, TAssoc_arra if (v.is_zero()) continue; - const TString4 val = k.right(3); + const TString4 val = k.sright(3); const int tipo = k[0]-'0'; const char ult = k[1]; TString80 ult_class; + if (ult > ' ') { - const char cod[3] = { tipo+'0', ult, '\0' }; + TString cod; + + cod << (tipo + '0') << ult; ult_class = cache().get("%CLR", cod, "S0"); ult_class.cut(27); } @@ -1391,6 +1382,7 @@ void TStampaScadenzario::print_rows_riepilogo(int& nriga, bool type, TAssoc_arra const bool stampa_in_valuta = _stvaluta && is_true_value(val); const TString& divisa = stampa_in_valuta ? val : EMPTY_STRING; TString80 value; + print_real(value, v, divisa); set_row(nriga++,"@0g! %s@25g! %s@55g! %s@61g!@64g%18s@82g!", tipi_tab(tipo), (const char*)ult_class, (const char*)val, (const char*)value); @@ -1532,9 +1524,9 @@ void TStampaScadenzario::print_rows_totali(int &nriga, tipo_pe p) if (v._al != ZERO) set_row(nriga,"@180g%15s",(const char*) value); - set_row(++nriga,""); + set_row(++nriga,EMPTY_STRING); } - set_row(++nriga,""); + set_row(++nriga,EMPTY_STRING); } void TStampaScadenzario::print_totali(int &nriga, bool month_changed, bool ended) @@ -1558,15 +1550,15 @@ void TStampaScadenzario::print_totali(int &nriga, bool month_changed, bool ended if (_group_ban) { print_totali_bank(nriga); - set_row(nriga++,""); + set_row(nriga++,EMPTY_STRING); } - set_row(nriga++,""); + set_row(nriga++,EMPTY_STRING); set_row(nriga, TR("@36g** TOTALI PERIODO")); print_rows_totali(nriga, period); if (_striepilogo > 0) print_riepilogo(nriga,true); - set_row(nriga++,"");set_row(nriga++,""); - set_row(nriga++,"");set_row(nriga++,""); + set_row(nriga++,EMPTY_STRING);set_row(nriga++,EMPTY_STRING); + set_row(nriga++,EMPTY_STRING);set_row(nriga++,EMPTY_STRING); } } @@ -1594,14 +1586,14 @@ void TStampaScadenzario::print_totali_c(int &nriga, bool ended) if (_group_ban) { print_totali_bank(nriga); - set_row(nriga++,"");set_row(nriga++,""); + set_row(nriga++,EMPTY_STRING);set_row(nriga++,EMPTY_STRING); } set_row(nriga, TR("@56g** TOTALE GENERALE")); print_rows_totali(nriga, period); if (_striepilogo > 0 ) print_riepilogo(nriga,true); - set_row(nriga++,"");set_row(nriga++,""); - set_row(nriga++,"");set_row(nriga++,""); + set_row(nriga++,EMPTY_STRING);set_row(nriga++,EMPTY_STRING); + set_row(nriga++,EMPTY_STRING);set_row(nriga++,EMPTY_STRING); } } @@ -1668,18 +1660,12 @@ void TStampaScadenzario::print_intestazione_banca(int &nriga) if (_last_bank_rec != 0) print_totali_bank(nriga); - set_row(nriga++, ""); + set_row(nriga++, EMPTY_STRING); set_row(nriga++, FR("@bBANCA DI PRESENTAZIONE %s@r"), (const char*)_desc_ban); - set_row(nriga++, ""); + set_row(nriga++, EMPTY_STRING); } } -TStampaScadenzario::TStampaScadenzario() -{ - _rel1=_rel2=_rel3=NULL; - _p = NULL; -} - int sc2200(int argc, char** argv) { TStampaScadenzario app; diff --git a/src/sc/sc2200a.uml b/src/sc/sc2200a.uml index ea73b9c98..b509e4ca2 100755 --- a/src/sc/sc2200a.uml +++ b/src/sc/sc2200a.uml @@ -54,7 +54,6 @@ BEGIN HELP "Data di inizio scadenza" CHECKTYPE REQUIRED WARNING "Data di inizio scadenza non valida" - FLAGS "A" GROUP 10 END @@ -74,7 +73,6 @@ BEGIN HELP "Data di inizio scadenza" CHECKTYPE REQUIRED WARNING "Data di inizio scadenza non valida" - FLAGS "A" GROUP 11 END @@ -141,7 +139,7 @@ BEGIN PROMPT 68 10 "A~zzera" END -NUMBER SC_NSEL 3 +NUMBER SC_NSEL 6 BEGIN PROMPT 55 11 "Selezionati " FLAGS "D" diff --git a/src/sc/sc2201.cpp b/src/sc/sc2201.cpp index 368e8df08..d4f48b925 100755 --- a/src/sc/sc2201.cpp +++ b/src/sc/sc2201.cpp @@ -9,6 +9,208 @@ /////////////////////////////////////////////////////////////////////////////// // TSelection_ext_mask // /////////////////////////////////////////////////////////////////////////////// +bool TSelection_ext_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) +{ + switch (o.dlg()) + { + case SC_SORTCF: + if (e == fe_modify) + { + const int ordine = atoi(o.get()); + const TString & tipo = get(SC_CLIFO); + bool g3 = false, g4 = false, g5 = false, g6 = false; + + if (tipo != "P") + { + g3 = ordine == 1; + g4 = !g3; + } + else + { + g5 = ordine == 1; + g6 = !g5; + } + show(-3, g3); // Abilita clifo per codice + show(-4, g4); // Abilita clifo per ragsoc + show(-5, g5); // Abilita pcon per conto + show(-6, g6); // Abilita pcon per descrizione + set_key(ordine); + reset_sheets(); + } + return true; + break; + case SC_SELECT: + if (e == fe_button) + { + TCursor_sheet& c = cur_sheet(); + + c.enable_check(); + c.run(); + if (who() == "P") + { + if (key() == 2) + set_des_pcon_limits(); + else + set_pcon_limits(); + } + else + { + if (key() == 2) + set_des_clifo_limits(); + else + set_clifo_limits(); + } + } + return true; + break; + case SC_PCONCODFR3: + if (e == fe_modify) + { + int grf, grt, cof, cot; + long sof, sot; + + grf = get_int(SC_PCONCODFR1); + cof = get_int(SC_PCONCODFR2); + sof = get_long(SC_PCONCODFR3); + grt = get_int(SC_PCONCODTO1); + cot = get_int(SC_PCONCODTO2); + sot = get_long(SC_PCONCODTO3); + select_pcon_range(grf, cof, sof, grt, cot, sot); + } + else + if (e == fe_button) + { + TCursor_sheet& c = cur_sheet(); + + c.disable_check(); + c.disable(DLG_USER); + if (c.run() == K_ENTER) + { + TToken_string& t = c.row(c.selected()); + int grf, grt, cof, cot; + long sof, sot; + int g = key(); + + grf = t.get_int(g++); + cof = t.get_int(g++); + sof = t.get_long(g); + grt = get_int(SC_PCONCODTO1); + cot = get_int(SC_PCONCODTO2); + sot = get_long(SC_PCONCODTO3); + set(SC_PCONCODFR1, grf); + set(SC_PCONCODFR2, cof); + set(SC_PCONCODFR3, sof); + select_pcon_range(grf, cof, sof, grt, cot, sot); + } + c.enable(DLG_USER); + } + return true; + break; + case SC_PCONCODTO3: + if (e == fe_modify) + { + int grf, grt, cof, cot; + long sof, sot; + + grf = get_int(SC_PCONCODFR1); + cof = get_int(SC_PCONCODFR2); + sof = get_long(SC_PCONCODFR3); + grt = get_int(SC_PCONCODTO1); + cot = get_int(SC_PCONCODTO2); + sot = get_long(SC_PCONCODTO3); + select_pcon_range(grf, cof, sof, grt, cot, sot); + } + if (e == fe_button) + { + TCursor_sheet& c = cur_sheet(); + + c.disable_check(); + c.disable(DLG_USER); + if (c.run() == K_ENTER) + { + TToken_string& t = c.row(c.selected()); + int grf, grt, cof, cot; + long sof, sot; + int g = key(); + + grt = t.get_int(g++); + cot = t.get_int(g++); + sot = t.get_long(g); + grf = get_int(SC_PCONCODFR1); + cof = get_int(SC_PCONCODFR2); + sof = get_long(SC_PCONCODFR3); + set(SC_PCONCODTO1, grt); + set(SC_PCONCODTO2, cot); + set(SC_PCONCODTO3, sot); + select_pcon_range(grf, cof, sof, grt, cot, sot); + } + c.enable(DLG_USER); + } + return true; + break; + case SC_PCONDESFR: + if (e == fe_modify) + { + const TString des1(o.get()); + const TString des2(get(SC_PCONDESTO)); + + select_des_pcon_range(des1, des2); + } + else + if (e == fe_button) + { + TCursor_sheet& c = cur_sheet(); + + c.disable_check(); + c.disable(DLG_USER); + if (c.run() == K_ENTER) + { + TToken_string& t = c.row(c.selected()); + const TString des1(t.get(3 - key())); + const TString des2 = get(SC_PCONDESTO); + + set(SC_PCONDESFR, des1); + select_des_pcon_range(des1, des2); + } + c.enable(DLG_USER); + } + break; + case SC_PCONDESTO: + if (e == fe_modify) + { + const TString des2(o.get()); + const TString des1(get(SC_PCONDESFR)); + + select_des_pcon_range(des1, des2); + } + else + if (e == fe_button) + { + TCursor_sheet& c = cur_sheet(); + + c.disable_check(); + c.disable(DLG_USER); + if (c.run() == K_ENTER) + { + TToken_string& t = c.row(c.selected()); + const TString des1(get(SC_PCONDESFR)); + const TString des2(t.get(3 - key())); + + set(SC_PCONDESTO, des2); + select_des_pcon_range(des1, des2); + } + c.enable(DLG_USER); + } + return true; + break; + case DLG_PRINT: + return true; + break; + default: + break; + } + return TSelection_mask::on_field_event(o, e, jolly); +} TSelection_ext_mask::TSelection_ext_mask(const char* name) : TSelection_mask(name), _pcon_rel(NULL), _pcon_cur_k1(NULL), _pcon_cur_k2(NULL), _pcon_sh_k1(NULL), _pcon_sh_k2(NULL) @@ -23,15 +225,6 @@ TSelection_ext_mask::TSelection_ext_mask(const char* name) : TSelection_mask(nam HR("@1|Gruppo|Conto|Sottoconto|Descrizione@50"),0,1); _pcon_sh_k2 = new TCursor_sheet(_pcon_cur_k2, " |DESCR|GRUPPO|CONTO|SOTTOCONTO", "Selezione conti per descrizione", HR("@1|Descrizione@50|Gruppo|Conto|Sottoconto"),0,1); - - set_handler(SC_CLIFO, rpcon_handler); // Redefined handler... - set_handler(SC_SORTCF, rsortpcon_handler); // Redefined handler... - set_handler(SC_SELECT, bselectpcon_handler); // Redefined handler... - set_handler(SC_RESET, bresetpcon_handler); // Redefined handler... - set_handler(SC_PCONCODFR3, ffrompcon_handler); // New handler... - set_handler(SC_PCONCODTO3, ftopcon_handler); // New handler... - set_handler(SC_PCONDESFR, fdfrompcon_handler); // New handler... - set_handler(SC_PCONDESTO, fdtopcon_handler); // New handler... } TSelection_ext_mask::~TSelection_ext_mask() @@ -46,15 +239,113 @@ TSelection_ext_mask::~TSelection_ext_mask() TCursor_sheet& TSelection_ext_mask::cur_sheet() { TCursor_sheet* cs; - if (get_selected_key() == 1) cs = get_who() == 'P' ? _pcon_sh_k1 : NULL; - else cs = get_who() == 'P' ? _pcon_sh_k2 : NULL; + const bool pconti = who() == "P"; + + if (key() == 1) + cs = pconti ? _pcon_sh_k1 : nullptr; + else + cs = pconti ? _pcon_sh_k2 : nullptr; - if (get_who() != 'P') + if (!pconti) return TSelection_mask::cur_sheet(); CHECK(cs, "Can't use a NULL TCursor_sheet"); return *cs; } +void TSelection_ext_mask::update_assoc() +{ + _assoc.destroy(); + update_checked(); + + TCursor_sheet& cs = cur_sheet(); // Sheet di selezione (CLI/FO/PCON) + + if (cs.checked() != cs.items()) + { + const int first = key(); + TString16 key; + + for (long i = cs.items() - 1; i >= 0; i--) + if (cs.checked(i)) + { + TToken_string& row = cs.row(i); + if (who() == "C" || who() == "F") + { + key.format("000000%06ld", row.get_long(first)); + } + else + { + const TBill b(row, first, 0x0); + key.format("%03d%03d%06ld", + b.gruppo(), b.conto(), b.sottoconto()); + } + _assoc.add(key); + } + } +} + +bool TSelection_ext_mask::selected(int g, int c, long s) +{ + TCursor_sheet & cs = cur_sheet(); // Sheet di selezione (CLI/FO/PCON) + + if (cs.checked() != cs.items()) + { + TString16 key; + + key.format("%03d%03d%06ld", g, c, s); + return _assoc.is_key(key); + } + return true; +} + +TRecnotype TSelection_ext_mask::get_clifo_range(long& first, long& last) +{ + first = last = 0L; + + TRecnotype items = 0; + + if (who() >= "C") + { + TCursor_sheet & s = cur_sheet(); // Sheet di selezione (CLI/FO/PCON) + + if (s.checked() == s.items()) + { + items = s.items(); + if (items > 0) + { + TToken_string & firstrow = s.row(0L); + + first = firstrow.get_long(0); + + TToken_string & lastrow = s.row(s.items() - 1L); + + last = lastrow.get_long(0); + } + } + else + { + TAssoc_array& ass = (TAssoc_array&)_assoc; // Trick the compiler + FOR_EACH_ASSOC_OBJECT(ass, obj, key, item) + { + const TFixed_string gcs(key); + const long codcf = atol(gcs.sright(6)); + if (first == 0 || codcf < first) + first = codcf; + if (last == 0 || codcf > last) + last = codcf; + items++; + } + } + } + return items; +} + +TESSL_form & TSelection_ext_mask::form() +{ + if (_form == nullptr) + _form = new TESSL_form(*this, false); + return *_form; +} + void TSelection_ext_mask::reset_sheets() { _pcon_sh_k1->uncheck(-1); @@ -74,15 +365,13 @@ void TSelection_ext_mask::select_des_pcon_range(const TString& from, const TStri { TCursor_sheet& c = cur_sheet(); const long items = c.items(); - const int key = get_selected_key(); - CHECK(key == 2, "La chiave deve essere la 2"); TString s_from(from), s_to(to); - - if (s_to.empty() && items) + + CHECK(key() == 2, "La chiave deve essere la 2"); + if (s_to.empty() && items) s_to = c.row(items-1).get(1); s_from.upper(); s_to.upper(); - if (s_from > s_to) // Controlla limiti { s_to = from; @@ -131,9 +420,8 @@ void TSelection_ext_mask::set_des_pcon_limits() TString from,to; TCursor_sheet& c = cur_sheet(); const long items = c.items(); - const int key = get_selected_key(); - CHECK(key == 2, "La chiave deve essere la 2"); - + + CHECK(key() == 2, "La chiave deve essere la 2"); for (long i = 0; i < items; i++) if (c.checked(i)) { @@ -170,15 +458,15 @@ void TSelection_ext_mask::select_pcon_range(int grf, int cof,long sof,int grt,in { TCursor_sheet& c = cur_sheet(); const long items = c.items(); - const int key = get_selected_key(); + const int k = key(); TCursor* crs = c.cursor(); if (grt==0 && cot==0 && sot==0 && items) { TToken_string& t = c.row(items-1); - grt = t.get_int(key); - cot = t.get_int(key+1); - sot = t.get_long(key+2); + grt = t.get_int(k); + cot = t.get_int(k+1); + sot = t.get_long(k+2); } if (grf > grt || (grf==grt && cof > cot) || (grf==grt && cof==cot && sof>sot)) { // Swap them... @@ -230,7 +518,7 @@ void TSelection_ext_mask::set_pcon_limits() TCursor_sheet& c = cur_sheet(); const long items = c.items(); - const int key = get_selected_key(); + const int k = key(); long first = -1, last = -1; // Ricerca veloce di estremi (vale solo su GR/CO/SO) @@ -252,12 +540,13 @@ void TSelection_ext_mask::set_pcon_limits() { TToken_string fitem(c.row(first)); TToken_string litem(c.row(last)); - gf = fitem.get_int(key); - cf = fitem.get_int(key+1); - sf = fitem.get_long(key+2); - gl = litem.get_int(key); - cl = litem.get_int(key+1); - sl = litem.get_long(key+2); + + gf = fitem.get_int(k); + cf = fitem.get_int(k+1); + sf = fitem.get_long(k+2); + gl = litem.get_int(k); + cl = litem.get_int(k+1); + sl = litem.get_long(k+2); if (gf > gl || (gf==gl && cf > cl) || (gf==gl && cf==cl && sf>sl)) { // Swap them... int t1 = gf,t2 = cf;long t3 = sf; @@ -273,233 +562,3 @@ void TSelection_ext_mask::set_pcon_limits() set(SC_PCONCODTO3, sl); set(SC_NSEL, c.checked()); } - -bool TSelection_ext_mask::ffrompcon_handler(TMask_field& f, KEY k) -{ - TSelection_ext_mask& m = (TSelection_ext_mask&)f.mask(); - - if (k == K_F9) - { - TSelection_ext_mask& m = (TSelection_ext_mask&)f.mask(); - TCursor_sheet& c = m.cur_sheet(); - const int key = m.get_selected_key(); - c.disable_check(); - c.disable(DLG_USER); - if (c.run() == K_ENTER) - { - TToken_string& t = c.row(c.selected()); - int grf,grt,cof,cot; - long sof,sot; - grf =t.get_int(key); - cof =t.get_int(key+1); - sof =t.get_long(key+2); - grt = m.get_int(SC_PCONCODTO1); - cot = m.get_int(SC_PCONCODTO2); - sot = m.get_long(SC_PCONCODTO3); - m.set(SC_PCONCODFR1, grf); - m.set(SC_PCONCODFR2, cof); - m.set(SC_PCONCODFR3, sof); - m.select_pcon_range(grf,cof,sof,grt,cot,sot); - } - c.enable(DLG_USER); - } - else - if (k == K_TAB && f.focusdirty()) - { - int grf,grt,cof,cot; - long sof,sot; - grf = m.get_int(SC_PCONCODFR1); - cof = m.get_int(SC_PCONCODFR2); - sof = m.get_long(SC_PCONCODFR3); - grt = m.get_int(SC_PCONCODTO1); - cot = m.get_int(SC_PCONCODTO2); - sot = m.get_long(SC_PCONCODTO3); - m.select_pcon_range(grf,cof,sof,grt,cot,sot); - } - return TRUE; -} - -bool TSelection_ext_mask::ftopcon_handler(TMask_field& f, KEY k) -{ - TSelection_ext_mask& m = (TSelection_ext_mask&)f.mask(); - - if (k == K_F9) - { - TSelection_ext_mask& m = (TSelection_ext_mask&)f.mask(); - TCursor_sheet& c = m.cur_sheet(); - const int key = m.get_selected_key(); - c.disable_check(); - c.disable(DLG_USER); - if (c.run() == K_ENTER) - { - TToken_string& t = c.row(c.selected()); - int grf,grt,cof,cot; - long sof,sot; - grt =t.get_int(key); - cot =t.get_int(key+1); - sot =t.get_long(key+2); - grf = m.get_int(SC_PCONCODFR1); - cof = m.get_int(SC_PCONCODFR2); - sof = m.get_long(SC_PCONCODFR3); - m.set(SC_PCONCODTO1, grt); - m.set(SC_PCONCODTO2, cot); - m.set(SC_PCONCODTO3, sot); - m.select_pcon_range(grf,cof,sof,grt,cot,sot); - } - c.enable(DLG_USER); - } - else - if (k == K_TAB && f.focusdirty()) - { - int grf,grt,cof,cot; - long sof,sot; - grf = m.get_int(SC_PCONCODFR1); - cof = m.get_int(SC_PCONCODFR2); - sof = m.get_long(SC_PCONCODFR3); - grt = m.get_int(SC_PCONCODTO1); - cot = m.get_int(SC_PCONCODTO2); - sot = m.get_long(SC_PCONCODTO3); - m.select_pcon_range(grf,cof,sof,grt,cot,sot); - } - return TRUE; -} - -bool TSelection_ext_mask::fdfrompcon_handler(TMask_field& f, KEY k) -{ - TSelection_ext_mask& m = (TSelection_ext_mask&)f.mask(); - - if (k == K_F9) - { - TSelection_ext_mask& m = (TSelection_ext_mask&)f.mask(); - TCursor_sheet& c = m.cur_sheet(); - - c.disable_check(); - c.disable(DLG_USER); - if (c.run() == K_ENTER) - { - TToken_string& t = c.row(c.selected()); - const TString des1(t.get(3 - m.get_selected_key())); - const TString des2 = m.get(SC_PCONDESTO); - m.set(SC_PCONDESFR, des1); - m.select_des_pcon_range(des1, des2); - } - c.enable(DLG_USER); - } - else - if (k == K_TAB && f.focusdirty()) - { - const TString des1(f.get()); - const TString des2(m.get(SC_PCONDESTO)); - m.select_des_pcon_range(des1, des2); - } - return TRUE; -} - -bool TSelection_ext_mask::fdtopcon_handler(TMask_field& f, KEY k) -{ - TSelection_ext_mask& m = (TSelection_ext_mask&)f.mask(); - - if (k == K_F9) - { - TSelection_ext_mask& m = (TSelection_ext_mask&)f.mask(); - TCursor_sheet& c = m.cur_sheet(); - - c.disable_check(); - c.disable(DLG_USER); - if (c.run() == K_ENTER) - { - TToken_string& t = c.row(c.selected()); - const TString des1(m.get(SC_PCONDESFR)); - const TString des2(t.get(3 - m.get_selected_key())); - m.set(SC_PCONDESTO, des2); - m.select_des_pcon_range(des1, des2); - } - c.enable(DLG_USER); - } - else - if (k == K_TAB && f.focusdirty()) - { - const TString des2(f.get()); - const TString des1(m.get(SC_PCONDESFR)); - m.select_des_pcon_range(des1, des2); - } - return TRUE; -} - -bool TSelection_ext_mask::bresetpcon_handler(TMask_field& f, KEY k) -{ - if (k == K_SPACE) - { - TSelection_ext_mask& m = (TSelection_ext_mask&)f.mask(); - m.reset_sheets(); - } - return TRUE; -} - -bool TSelection_ext_mask::bselectpcon_handler(TMask_field& f, KEY k) -{ - if (k == K_SPACE) - { - TSelection_ext_mask& m = (TSelection_ext_mask&)f.mask(); - TCursor_sheet& c = m.cur_sheet(); - c.enable_check(); - c.run(); - char who = m.get_who(); - int key = m.get_selected_key(); - if (who =='P') - if (key == 2) - m.set_des_pcon_limits(); - else - m.set_pcon_limits(); - else - if (key == 2) - m.set_des_clifo_limits(); - else - m.set_clifo_limits(); - } - return TRUE; -} - -bool TSelection_ext_mask::rpcon_handler(TMask_field& f, KEY k) -{ - if (k == K_SPACE) - { - TSelection_ext_mask& m = (TSelection_ext_mask&)f.mask(); - char who = f.get()[0]; - if (who != m.get_who()) - { - m.set_key(1); - m.set_who(who); - } - m.reset_sheets(); - } - return TRUE; -} - -bool TSelection_ext_mask::rsortpcon_handler(TMask_field& f, KEY k) -{ - if (k == K_SPACE) - { - TSelection_ext_mask& m = (TSelection_ext_mask&)f.mask(); - const int ordine = atoi(f.get()); - TString tipo = m.get(SC_CLIFO); - bool g3 = FALSE, g4 = FALSE, g5 = FALSE, g6 = FALSE; - if (tipo != "P") - { - g3 = ordine == 1; - g4 = !g3; - } - else - { - g5 = ordine == 1; - g6 = !g5; - } - m.show(-3, g3); // Abilita clifo per codice - m.show(-4, g4); // Abilita clifo per ragsoc - m.show(-5, g5); // Abilita pcon per conto - m.show(-6, g6); // Abilita pcon per descrizione - m.set_key(ordine); - m.reset_sheets(); - } - return TRUE; -} diff --git a/src/sc/sc2201.h b/src/sc/sc2201.h index 0cf6e0c4d..af2e56864 100755 --- a/src/sc/sc2201.h +++ b/src/sc/sc2201.h @@ -7,31 +7,30 @@ class TSelection_ext_mask : public TSelection_mask { + TAssoc_array _assoc; TRelation* _pcon_rel; TCursor* _pcon_cur_k1; TCursor* _pcon_cur_k2; - TCursor_sheet* _pcon_sh_k1; TCursor_sheet* _pcon_sh_k2; + TESSL_form * _form; protected: void select_pcon_range(int grf, int cof,long sof,int grt,int cot, long sot); void select_des_pcon_range(const TString& from, const TString& to); void set_pcon_limits(); void set_des_pcon_limits(); - virtual void reset_sheets(); - static bool ffrompcon_handler(TMask_field& f, KEY k); - static bool ftopcon_handler(TMask_field& f, KEY k); - static bool bresetpcon_handler(TMask_field& f, KEY k); - static bool bselectpcon_handler(TMask_field& f, KEY k); - static bool rpcon_handler(TMask_field& f, KEY k); - static bool rsortpcon_handler(TMask_field& f, KEY k); - static bool fdfrompcon_handler(TMask_field& f, KEY k); - static bool fdtopcon_handler(TMask_field& f, KEY k); - + public: - virtual TCursor_sheet& cur_sheet(); + virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly) override; + virtual TCursor_sheet& cur_sheet(); + virtual const TToken_string & get_anal_filter() const override { return EMPTY_STRING; } + virtual TESSL_form & form() override; + void update_assoc(); + bool selected(const TBill& b) { return selected(b.gruppo(), b.conto(), b.sottoconto()); } + bool selected(int g, int c, long s); + TRecnotype get_clifo_range(long& first, long& last); TSelection_ext_mask(const char* name); virtual ~TSelection_ext_mask(); diff --git a/src/sc/sc2300.cpp b/src/sc/sc2300.cpp index 9e09bc1e1..6404a4abe 100755 --- a/src/sc/sc2300.cpp +++ b/src/sc/sc2300.cpp @@ -231,10 +231,9 @@ void TStampaScaduto::compute_all(TPartita& p, TBill& bill) return; // Ignora partite chiuse da tempo immemorabile } - - TGameLog gl(p); - + TGameLog gl(p); real residuo,nonscad,buonf,s1,s2,s3,s4,s5,s6,s7,res_pagati; + compute_unassigned(p); for (int r = p.last(); r > 0; r = p.pred(r)) // Browse all rows (partite) { @@ -242,6 +241,7 @@ void TStampaScaduto::compute_all(TPartita& p, TBill& bill) // se la data di registrazione della partita ' > di _limop (data lim operazione) // non deve scorrere le scadenze const TDate data_reg = rp.get_date(PART_DATAREG); + if (data_reg > _limop) continue; @@ -252,8 +252,8 @@ void TStampaScaduto::compute_all(TPartita& p, TBill& bill) const char* field = (_stvaluta && rs.in_valuta()) ? PAGSCA_IMPORTOVAL : PAGSCA_IMPORTO; const char* sfield = (_stvaluta && rs.in_valuta()) ? SCAD_IMPORTOVAL : SCAD_IMPORTO; const char ssez = rp.sezione(); - TImporto scd,pag,bf,work_imp; + scd += TImporto(ssez,rs.get_real(sfield)); // Importo in scadenza... pag += rs.importo_pagato(_stvaluta); // Quanto e' stato pagato per questa scadenza? @@ -263,6 +263,7 @@ void TStampaScaduto::compute_all(TPartita& p, TBill& bill) const int lst = rs.last(); int prima_riga_pagamento = -1; TDate first_date;// data relativa alla prima riga di pagamento + int pp; for (pp = rs.first(); pp <= lst; pp = rs.succ(pp)) { @@ -285,17 +286,17 @@ void TStampaScaduto::compute_all(TPartita& p, TBill& bill) // se tipomov e' 2 (Nota di credito assegnata) // storna da scdz. In entrambi i casi si ha l'operatore +=, perche' nel TImporto e' gia' // compresa la sezione opposta - if (tipomov==tm_nota_credito) + if (tipomov == tm_nota_credito) { work_imp = TImporto(sez,pg.get_real(field)); scd += work_imp; pag -= work_imp; } - if ((tipomov==3 || tipomov==5) && _tipost==clienti && _gcr!=0) + if ((tipomov == tm_pagamento || tipomov == tm_insoluto) && _tipost==clienti && _gcr!=0) { TDate data_pag(sum.get_date(PART_DATAPAG)); int tipo_pag = rs.get_int(SCAD_TIPOPAG); - if (tipo_pag>=2 && tipo_pag<=7 && data_pag.ok()) //Incasso tramite effetto + if (tipo_pag >= tm_nota_credito && tipo_pag <= tm_pagamento_insoluto && data_pag.ok()) //Incasso tramite effetto { if (prima_riga_pagamento > -1 && prima_riga_pagamento == pp) data_pag = d; // Se e' il primo pagamento(in ordine di data) di questa rata @@ -330,17 +331,6 @@ void TStampaScaduto::compute_all(TPartita& p, TBill& bill) if (b == ZERO) // Se le scadenze sono a zero, vuol dire che sono state stornate res = ZERO; // da qualche nota di credito o non assegnato percio' non si ha residuo -/* - if (res < ZERO) // Significa che l'importo pagato e' maggiore dell'importo in scadenza - { // c'e' un residuo positivo, e quindi va memorizzato - res *= -1.0; // cambia il segno - res_pagati+= res; // Residui pagati in piu' - res = ZERO; - } -*/ -#ifdef __LONGDOUBLE__ - res.round(5); -#endif if (res.sign() * b.sign() < 0) // Ho pagato piu' della scadenza { res_pagati -= res; // Residui pagati in piu' @@ -476,7 +466,8 @@ bool TStampaScaduto::preprocess_page(int file, int counter) } if (curr.empty()) // Attenzione: Possono succedere anche queste cose! - return false; + return false; + TPartita p(curr); //Pesca gli estremi dalla prima riga di fattura, che non e' necessariamente la riga #1 @@ -620,17 +611,25 @@ bool TStampaScaduto::user_destroy() bool TStampaScaduto::set_print(int) { + TDate data = today; + + data.set_end_month(); + if (!_m->get_date(F_DATASCADUTO).ok()) + _m->set(F_DATASCADUTO, data); + const bool rt = _m->run() == K_ENTER; + if (rt) { + _m->update_assoc(); reset_files(); reset_print(); - if (_m->get_who() == 'P') + if (_m->conti()) _tipost = altri; else - _tipost = _m->get_who() == 'C' ? clienti : fornitori; - _ordcod = _m->get_selected_key() == 1; + _tipost = _m->clienti() ? clienti : fornitori; + _ordcod = _m->key() == 1; _end_printed = _pending_clifo = false; _gcr = _m->get_int(F_GIORNI); _stvaluta = _m->get_bool(F_VALUTA); diff --git a/src/sc/sc2300a.uml b/src/sc/sc2300a.uml index 3919b6843..6028e2b97 100755 --- a/src/sc/sc2300a.uml +++ b/src/sc/sc2300a.uml @@ -74,7 +74,7 @@ END RADIOBUTTON SC_CLIFO 20 BEGIN - PROMPT 1 9 "Selezione" + PROMPT 1 10 "Selezione" ITEM "C|Clienti" MESSAGE ENABLE, F_GIORNI|K_SPACE,SC_SORTCF ITEM "F|Fornitori" MESSAGE DISABLE, F_GIORNI|K_SPACE,SC_SORTCF ITEM "P|Conti" MESSAGE DISABLE, F_GIORNI|K_SPACE,SC_SORTCF @@ -83,104 +83,104 @@ END RADIOBUTTON SC_SORTCF 29 BEGIN GROUP 1 - PROMPT 23 9 "Ordinamento" + PROMPT 23 10 "Ordinamento" ITEM "1|Per codice/conto" ITEM "2|Per rag.soc./descrizione" END BUTTON SC_SELECT 10 1 BEGIN - PROMPT 55 10 "S~elezione" + PROMPT 55 11 "S~elezione" END BUTTON SC_RESET 10 1 BEGIN - PROMPT 55 11 "A~zzera" + PROMPT 55 12 "A~zzera" END NUMBER SC_CFCODFR 6 BEGIN - PROMPT 2 14 "Da codice " + PROMPT 2 15 "Da codice " FLAGS "B" GROUP 3 END NUMBER SC_CFCODTO 6 BEGIN - PROMPT 37 14 "a codice " + PROMPT 37 15 "a codice " FLAGS "B" GROUP 3 END STRING SC_CFDESFR 50 40 BEGIN - PROMPT 2 14 "Da ragione sociale " + PROMPT 2 15 "Da ragione sociale " GROUP 4 FLAGS "HB" END STRING SC_CFDESTO 50 40 BEGIN - PROMPT 2 15 "A ragione sociale " + PROMPT 2 16 "A ragione sociale " GROUP 4 FLAGS "HB" END NUMBER SC_PCONCODFR1 3 BEGIN - PROMPT 2 14 "Da conto " + PROMPT 2 15 "Da conto " GROUP 5 END NUMBER SC_PCONCODFR2 3 BEGIN - PROMPT 15 14 "" + PROMPT 15 15 "" GROUP 5 END NUMBER SC_PCONCODFR3 6 BEGIN - PROMPT 19 14 "" + PROMPT 19 15 "" FLAGS "B" GROUP 5 END NUMBER SC_PCONCODTO1 3 BEGIN - PROMPT 31 14 "a conto " + PROMPT 31 15 "a conto " GROUP 5 END NUMBER SC_PCONCODTO2 3 BEGIN - PROMPT 43 14 "" + PROMPT 43 15 "" GROUP 5 END NUMBER SC_PCONCODTO3 6 BEGIN - PROMPT 47 14 "" + PROMPT 47 15 "" FLAGS "B" GROUP 5 END STRING SC_PCONDESFR 50 40 BEGIN - PROMPT 2 14 "Da descrizione " + PROMPT 2 15 "Da descrizione " GROUP 6 FLAGS "HB" END STRING SC_PCONDESTO 50 40 BEGIN - PROMPT 2 15 "A descrizione " + PROMPT 2 16 "A descrizione " GROUP 6 FLAGS "HB" END -NUMBER SC_NSEL 3 +NUMBER SC_NSEL 6 BEGIN - PROMPT 60 13 "N. " + PROMPT 48 14 "Selezionati " FLAGS "D" END diff --git a/src/sc/sc2400.cpp b/src/sc/sc2400.cpp index dc2b92b6b..56734714a 100755 --- a/src/sc/sc2400.cpp +++ b/src/sc/sc2400.cpp @@ -13,6 +13,8 @@ #include #include + +#include "sc2402.h" /////////////////////////////////////////////////////////// // Stampa solleciti @@ -20,10 +22,7 @@ class TStampaSol_application: public TSkeleton_application { - TString _lingua_ditta; TSol_mask* _msk; - bool _gesval; - TSol_form* _form; protected: virtual bool create(); @@ -31,500 +30,18 @@ protected: virtual void main_loop(); virtual void on_firm_change(); virtual void on_config_change(); - - bool get_mail_address(TToken_string& to, TToken_string& cc) const; - virtual bool get_next_mail(TToken_string& to, TToken_string& cc, TToken_string& ccn, - TString& subj, TString& text, TToken_string& attach, short& ui) const; - - const TString& game_key(const TRectype& part) const; // Costruisce chiave univoca per TAssoc_array partite - bool ci_sono_scadenze_aperte(const TPartita& game, const TDate& dal, const TDate& al, const TDate& data_rischio) const; - bool puoi_scartare(const TPartita& game, const TDate& datalim) const; - int print_sol(); // stampa l'elemento corrente + virtual void print() override { _msk->on_field_event((TButton_field &)_msk->field(DLG_PRINT), fe_button, 0L); } public: TSol_mask& mask() const { return *_msk; } - TSol_form& form() const { return *_form; } TCursor_sheet& sheet() { return _msk->cur_sheet(); } - bool print_selected(); // cicla la stampa sugli elementi selezionati bool mail_selected(); // manda email agli elementi selezionati TStampaSol_application(); - virtual ~TStampaSol_application() {} + virtual ~TStampaSol_application() = default; }; -bool TStampaSol_application::print_selected() -{ - TCursor_sheet &s = sheet(); - TCursor &c = *s.cursor(); - - const char who = mask().get_who(); - const int key = mask().get_selected_key(); - - // Attiva la stampa del saldo partita - form().stampa_saldo(mask().stampa_saldo()); - form().anal_filter(mask().get_anal_filter()); - - // filtra il cursore del form in modo che diventi uguale al cursor_sheet corrente - // Qui sarebbe bello copiarsi l'indice dell'altro cursore - TCursor &fc = *form().cursor(); - fc.setkey(key); - TRectype filter(LF_CLIFO); - filter.put(CLI_TIPOCF, who); - fc.setregion(filter, filter); - - const long print_all = !s.one_checked(); // se non ho selezionato nulla allora li stampo tutti - long analfabeti = 0; // persone non stampate in quanto aventi lingua errata - - TPrinter& pr = printer(); - pr.open(); - - const long items = c.items(); - for (long i=0; i < items; i++) - { - if (print_all || s.checked(i)) - { - fc = i; // muove il cursore alla posizione corrente - const int ret = print_sol(); - if (ret < 0) - analfabeti++; - } - - if (pr.frozen()) - break; - } - pr.close(); - - if (analfabeti > 0) - warning_box(FR("%ld clienti non sono stati stampati in quanto " - "il codice lingua non corrispondeva al profilo di stampa"), analfabeti); - - return true; -} - -bool TStampaSol_application::ci_sono_scadenze_aperte(const TPartita& game, const TDate& dal, const TDate& al, const TDate& data_rischio) const -{ - bool found = false; - - for (int r = game.last(); r > 0; r = game.pred(r)) - { - const TRiga_partite& row = game.riga(r); - if (row.is_fattura() && row.get_date(PART_DATAREG) <= al) - { - for (int s = row.rate(); s > 0 ;s--) - { - const TRiga_scadenze& rata = row.rata(s); - const TDate data = rata.get(SCAD_DATASCAD); - if (data >= dal && data <= al) - { - found = !rata.chiusa(); - if (!found) - { - TImporto rat = rata.importo(true); - TImporto imp = rata.importo_pagato_al(true, data_rischio); - imp.normalize(rat.sezione()); - const real saldo = rat.valore() + imp.valore(); - found = saldo > ZERO; - } - if (found) - break; - } - } - } - } - return found; -} - - -const TString& TStampaSol_application::game_key(const TRectype& part) const -{ - TToken_string& tok = get_tmp_string(); - tok = part.get(PART_ANNO); - tok.add(part.get(PART_NUMPART)); - return tok; -} - -bool TStampaSol_application::puoi_scartare(const TPartita& game, const TDate& datalim) const -{ - bool yes = game.chiusa(); - if (yes && datalim.ok()) - { - TDate last; - for (int r = game.last(); r > 0; r = game.pred(r)) - { - const TRiga_partite& riga = game.riga(r); - if (riga.tipo() > tm_fattura) - { - const TDate d = riga.get(PART_DATAPAG); - if (d > last) - last = d; - } - } - yes = last < datalim; - } - return yes; -} - -int TStampaSol_application::print_sol() -{ - TSol_form& f = form(); - - // preparazione variabili per controllo lingua - const TRectype &clf= f.cursor()->file().curr(); - const TString4 lincf = clf.get(CLI_CODLIN); - bool ok = true; - - // controllo lingua ditta corrente - if ((f.lingua() == _lingua_ditta && !lincf.empty()) || f.lingua() != _lingua_ditta) ok= (lincf == f.lingua()); - if (!ok) return -1; // cliente analfabeta - - f.azzera_totali(); - // filtra solo le partite del cliente selezionato - TLocalisamfile partite(LF_PARTITE); - partite.zero(); - partite.put(PART_TIPOCF, clf.get(CLI_TIPOCF)); - partite.put(PART_SOTTOCONTO, clf.get(CLI_CODCF)); - - const TRectype& parkur = partite.curr(); - const TRectype filter(parkur); - - bool one_printed = false; // booleano di controllo di riuscita della stampa - const bool sel_tot_saldo = f.get_sel_tot_saldo(); // selezione sul saldo totale cliente - const real sel_importo(f.get_sel_importo()); // importo di selezione - const TDate data_inizio_soll = _msk->get(F_DATAINISCAD); - const TDate data_limite_soll = f.data_limite_operazione(); - const TDate data_limite_scaduto = f.data_limite_scaduto(); - TToken_string anal_filter = form().get_anal_filter(); - const bool select_analitica = (dongle().active(CAAUT) || dongle().active(CMAUT)) && anal_filter.full() ; - TDecoder anal(LF_MOVANA, MOVANA_NUMREG, 3); - const TDate data_rischio = f.data_inizio_rischio(); - - TAssoc_array games_in_range; - - if ((sel_tot_saldo && sel_importo > ZERO) || data_inizio_soll.ok()) - { - real saldo; - for (int err = partite.read(_isgteq); - err == NOERR && parkur == filter; - err = partite.read(_isgreat)) - { - const TPartita game(parkur); - if (!puoi_scartare(game, data_rischio)) - { - if (sel_tot_saldo) - { - const real sld = game.calcola_scaduto_al(false, data_limite_soll); - saldo += sld; - } - if (data_inizio_soll.ok()) - { - if (ci_sono_scadenze_aperte(game, data_inizio_soll, data_limite_soll, data_rischio)) - games_in_range.add(game_key(parkur)); - } - } - partite.put(PART_NRIGA, 9999); - } - - if (sel_tot_saldo && sel_importo > ZERO && saldo < sel_importo) - return 0; - if (data_inizio_soll.ok() && games_in_range.empty()) - return 0; - - partite.curr() = filter; - } - - for (int err = partite.read(_isgteq); - err == NOERR && parkur == filter; - err = partite.read(_isgreat)) - { - if (data_inizio_soll.ok() && !games_in_range.is_key(game_key(parkur))) - continue; // Scarta parite fuori range di date - - const TPartita game(parkur); - if (!puoi_scartare(game, data_rischio)) - { - const real saldo = game.calcola_scaduto_al(false, data_limite_scaduto); - - TImporto unreferenced; //Totale non assegnati per questa partita. - { - // E' giusto calcolare il saldo, comprendente i non assegnati. - // se il saldo della partita chiude in avere va sommato ad unreferenced - const TRiga_partite& sum = game.riga(game.first()); - unreferenced = game.calcola_saldo_al(game.in_valuta() && f.in_valuta(),data_limite_soll, data_limite_scaduto, data_rischio); - if (unreferenced.valore() > ZERO && unreferenced.sezione() == 'A') - { - unreferenced.normalize('A'); //per i non assegnati/anticipi c'e' solo la colonna AVERE - const TString4 valuta = sum.get(PART_CODVAL); - form().totali().add(unreferenced,valuta); - } - } - - if (select_analitica) - { - bool print = false; - for (int r = game.first(); !print && r <= game.last(); r = game.succ(r)) - { - const TRiga_partite& row = game.riga(r); - const TString& numregcg = row.get(PART_NREG); - const long numreg = atol(anal.decode(numregcg)); - - if (numreg > 0) - { - TAnal_mov anal_mov(numreg); - TRecord_array & rows = anal_mov.body(); - const int nrows = rows.rows(); - TString s; - - for (int i = 1; !print && i <= nrows; i++) - { - const TRectype & row = anal_mov.body().row(i); - TString f = anal_filter.get(0); - f.trim(); - - if (f.full()) - { - s = row.get(RMOVANA_CODCMS); - print |= s.match(f); - } - f = anal_filter.get(); - if (f.full()) - { - s = row.get(RMOVANA_CODCCOSTO); - print |= s.match(f); - } - f = anal_filter.get(); - if (f.full()) - { - s = row.get(RMOVANA_CODFASE); - print |= s.match(f); - } - } - } - } - if (!print) - return 0; - } - if (sel_tot_saldo || (saldo > ZERO && saldo >= sel_importo ) || (saldo.is_zero() && !unreferenced.is_zero() && data_rischio < data_limite_scaduto)) - { - const bool printed = form().print_game(game); - one_printed |= printed; - } - } - - partite.put(PART_NRIGA, 9999); - - if (printer().frozen()) - break; - } - - if (one_printed) - { - f.ultima_pagina(); - printer().formfeed(); - } - - return one_printed ? 1 : 0; -} - -bool TStampaSol_application::get_mail_address(TToken_string& to, TToken_string& cc) const -{ - const TRectype& fc = form().cursor()->curr(); - const long codcf = fc.get_long(CLI_CODCF); - TString8 clifo; clifo.format("C%06ld", codcf); - TISAM_recordset contacts("USE MULTIREL\nFROM COD=BACON FIRST=#CLIFO\nTO COD=BACON FIRST=#CLIFO"); - contacts.set_var("#CLIFO", clifo); - - TToken_string data; - for (bool ok = contacts.move_first(); ok; ok = contacts.move_next()) - { - data = contacts.get("DATA").as_string(); - FOR_EACH_TOKEN(data, tok) - { - const TFixed_string doc(tok); - if (doc.starts_with("sc2400", true) || doc.starts_with("sollec", true)) - { - const TRectype& rub = cache().get(LF_CONTACT, contacts.get("SECOND").as_int()); - TString80 mail = rub.get("MAIL"); - if (mail.blank()) - mail = rub.get("MAIL2"); - if (mail.full()) - { - if (to.blank()) - to = mail; - else - cc.add(mail); - break; - } - } - } - } - - if (to.blank()) - { - TString8 key; key << "C|" << codcf; - to = cache().get(LF_CLIFO, key, CLI_DOCMAIL); - } - - return to.full(); -} - - -bool TStampaSol_application::get_next_mail(TToken_string& to, TToken_string& cc, TToken_string& ccn, - TString& subj, TString& text, TToken_string& attach, short& ui) const -{ - bool ok = TApplication::get_next_mail(to, cc, ccn, subj, text, attach, ui) && get_mail_address(to, cc); - - if (ok) - { - const TRectype& clifo = form().cursor()->curr(); - TDate oggi = mask().get(F_DATALIMSOL); - if (!oggi.ok()) - oggi = mask().get_date(F_DATASEND); - - subj << TR("Sollecito ") << prefix().firm().ragione_sociale(); - TString ragsoc = clifo.get(CLI_RAGSOC); ragsoc.strip_double_spaces(); - text << "Spett. " << ragsoc << '\n' - << TR("Si ricorda il rispetto delle scadenze aperte al ") << oggi << '\n' - << TR(" riepilogate nel file allegato ") << attach << '\n' - << prefix().firm().ragione_sociale(); - if (to.full()) - ui &= ~0x1; // No user interface - ui |= 0x2; // Query receipt - - const long codcf = clifo.get_long(CLI_CODCF); - TFilename pdf; - ok = get_next_pdf(oggi.year(), -1, "SOLL", oggi.date2ansi(), codcf, pdf); - attach = pdf; - } - - return ok; -} - -struct TMail_message : public TObject -{ - TToken_string _to, _cc, _ccn; - TString _subj, _text; - TToken_string _attach; - short _ui; -}; - -bool TStampaSol_application::mail_selected() -{ - TCursor_sheet &s = sheet(); - TCursor &c = *s.cursor(); - - const char who = mask().get_who(); - const int key = mask().get_selected_key(); - - // Attiva la stampa del saldo partita - form().stampa_saldo(mask().stampa_saldo()); - form().anal_filter(mask().get_anal_filter()); - - // filtra il cursore del form in modo che diventi uguale al cursor_sheet corrente - // Qui sarebbe bello copiarsi l'indice dell'altro cursore - TCursor &fc = *form().cursor(); - fc.setkey(key); - TRectype filter(LF_CLIFO); - filter.put(CLI_TIPOCF, who); - fc.setregion(filter, filter); - - const long print_all = !s.one_checked(); // se non ho selezionato nulla allora li stampo tutti - - TLog_report log; - - TArray mail; - - const long items = c.items(); - if (items > 0) - { - const TDate oggi(TODAY); - TProgind pi(items); - - TPrinter& pr = printer(); - for (long i=0; i < items; i++) - { - if (!pi.addstatus(1)) - break; - if (print_all || s.checked(i)) - { - fc = i; // muove il cursore alla posizione corrente - - pr.set_export_file("soll.pdf", true); - pr.open(); - const int ret = print_sol(); - pr.close(); - - if (ret > 0) - { - TString msg; - msg << fc.curr().get(CLI_RAGSOC) << ": "; - msg.strip_double_spaces(); - - TMail_message* m = new TMail_message; - bool done = false; - if (get_next_mail(m->_to, m->_cc, m->_ccn, m->_subj, m->_text, m->_attach, m->_ui)) - { - const TFilename fn = m->_attach; - xvt_vobj_destroy(883); - done = pr.print_pdf(printer().get_txt(), fn); - if (done) - { - msg << TR("invio ") << fn.name() << TR(" a ") << m->_to; - log.log(0, msg); - mail.add(m); - } - else - { - msg << TR("Impossibile genereare ") << fn; - log.log(2, msg); - } - } - else - { - msg << TR("Impossibile trovare un indirizzo e-mail valido"); - log.log(2, msg); - } - - if (!done) - delete m; - } - } - } - pr.read_configuration(); - } - - log.preview(); - - if (!mail.empty()) - { - TArray_sheet sheet(-1, -1, 78, 20, TR("Mail"), HR("@1|Destinatario@32|Messaggio@50"), 0, 1); - FOR_EACH_ARRAY_ITEM(mail, r, obj) - { - const TMail_message& m = *(TMail_message*)obj; - TToken_string* row = new TToken_string; - *row = "X"; - row->add(m._to); - row->add(m._text.before('\n')); - sheet.add(row); - } - if (sheet.run() == K_ENTER) - { - const long m = sheet.checked(); - if (m > 0 && yesno_box(FR("Confermare l'invio di %ld mail?"), m)) - { - FOR_EACH_CHECKED_ROW(sheet, r, row) - { - const TMail_message& m = (const TMail_message&)mail[r]; - xvt_mail_send(m._to, m._cc, m._ccn, m._subj, m._text, m._attach, m._ui); - } - } - } - } - - return true; -} - - bool TStampaSol_application::create() { TApplication::create(); @@ -550,10 +67,6 @@ void TStampaSol_application::on_config_change() mask().set(F_STAMPSALDO, "X"); TApplication::on_firm_change(); - - TConfig c(CONFIG_DITTA, "cg"); - _lingua_ditta= c.get("CodLin"); - _gesval= c.get_bool("GesVal"); } void TStampaSol_application::on_firm_change() @@ -565,23 +78,11 @@ void TStampaSol_application::on_firm_change() void TStampaSol_application::main_loop() { TSol_mask& m = mask(); - for (;;) - { - const KEY key = m.run(); - if (key == K_QUIT) - break; - - _form= new TSol_form(m, _gesval, F_DATALIMOP, F_DATALIMSOL, F_GGRISCHIO); - if (key == 'M') - mail_selected(); - else - print_selected(); - delete _form; - _form= NULL; - } + + while (m.run() != K_QUIT); } -TStampaSol_application::TStampaSol_application(): _lingua_ditta(1), _msk(NULL), _form(NULL) {} +TStampaSol_application::TStampaSol_application(): _msk(nullptr) {} int sc2400(int argc, char** argv) { diff --git a/src/sc/sc2400a.uml b/src/sc/sc2400a.uml index b9942016c..380afbf2a 100755 --- a/src/sc/sc2400a.uml +++ b/src/sc/sc2400a.uml @@ -5,21 +5,20 @@ TOOLBAR "" 0 0 0 2 BUTTON DLG_PRINT 2 2 BEGIN - PROMPT 1 1 "Stampa" + PROMPT 1 3 "Stampa" PICTURE TOOL_PRINT END BUTTON DLG_SETPRINT 2 2 BEGIN - PROMPT 2 1 "Imposta" + PROMPT 2 3 "Imposta" PICTURE TOOL_SETPRINT END BUTTON DLG_EMAIL 2 2 BEGIN - PROMPT 1 1 "Mail" + PROMPT 3 3 "Mail" PICTURE TOOL_EMAIL - MESSAGE EXIT,77 END #include @@ -95,6 +94,7 @@ END DATE F_DATALIMOP BEGIN PROMPT 2 4 "Data limite operazione " + FLAGS "A" END NUMBER F_GGRISCHIO 3 @@ -108,7 +108,6 @@ DATE F_DATALIMSOL BEGIN PROMPT 2 5 "Data limite solleciti " FLAGS "A" - CHECKTYPE REQUIRED END DATE F_DATAINISCAD @@ -199,9 +198,9 @@ BEGIN FLAGS "HB" END -NUMBER SC_NSEL 3 +NUMBER SC_NSEL 6 BEGIN - PROMPT 60 13 "N. " + PROMPT 49 13 "Selezionati " FLAGS "D" END diff --git a/src/sc/sc2400b.h b/src/sc/sc2400b.h new file mode 100644 index 000000000..41e9488a9 --- /dev/null +++ b/src/sc/sc2400b.h @@ -0,0 +1 @@ +#include "sc2100b.h" diff --git a/src/sc/sc2400b.uml b/src/sc/sc2400b.uml new file mode 100644 index 000000000..f7fdb7368 --- /dev/null +++ b/src/sc/sc2400b.uml @@ -0,0 +1,135 @@ +#include "sc2400b.h" + +TOOLBAR "topbar" 0 0 0 2 + +BUTTON DLG_ALL 2 2 +BEGIN + PROMPT 1 3 "~Tutti" + PICTURE TOOL_MULTISEL +END + +BUTTON DLG_OK 2 2 +BEGIN + PROMPT 2 3 "Invia" + PICTURE TOOL_EMAIL +END + +BUTTON DLG_PREVIEW 2 2 +BEGIN + PROMPT 3 3 "~Anteprima" + PICTURE TOOL_PREVIEW +END + +#include + +ENDPAGE + +PAGE "Invio solleciti" 0 2 0 0 + +LISTBOX F_SORT 1 15 +BEGIN + PROMPT 1 0 "Ordinamento " + ITEM "1|Codice" + ITEM "2|Ragione sociale" +END + +STRING F_FROMEMAIL 50 +BEGIN + PROMPT 1 1 "Email di invio " +END + +STRING F_PASSWORD 50 +BEGIN + PROMPT 1 2 "Password " + FLAGS "*" +END + +STRING F_CCEMAIL 50 +BEGIN + PROMPT 1 3 "Conoscenza " +END + +BOOLEAN F_RECEIPT +BEGIN + PROMPT 70 3 "Ricevuta" +END + +STRING F_CCNEMAIL 50 +BEGIN + PROMPT 1 4 "Conosc.nascosta " +END + +ZOOM F_SUBJ 50 +BEGIN + PROMPT 1 5 "Oggetto " +END + +ZOOM F_MESSAGE 50 +BEGIN + PROMPT 1 6 "Messaggio " +END + +STRING F_TESTEMAIL 50 +BEGIN + PROMPT 1 7 "Email prova " + FLAGS "H" +END + +SPREADSHEET F_SHEET -1 -1 +BEGIN + PROMPT 0 9 "" + ITEM "@1" + ITEM "Email@50" + ITEM "Codice" + ITEM "Ragione Sociale@50" +END + +ENDPAGE + +ENDMASK + +PAGE "" -1 -1 80 7 + +BOOLEAN S_SELECTED +BEGIN + PROMPT 1 1 "Email " +END + +STRING S_EMAIL 50 +BEGIN + PROMPT 1 2 "Email " +END + +NUMBER S_CODCF 6 +BEGIN + PROMPT 1 4 "Codice " + FLAG "D" +END + +STRING S_RAGSOC 50 +BEGIN + PROMPT 1 5 "Ragione Sociale " + FLAG "D" +END + +ENDPAGE + +TOOLBAR "" 0 0 0 2 + +BUTTON DLG_OK 2 2 +BEGIN + PROMPT 1 1 "" +END + +BUTTON DLG_DELREC 2 2 +BEGIN + PROMPT 1 1 "" +END + +BUTTON DLG_CANCEL 2 2 +BEGIN + PROMPT 1 1 "" +END + +ENDPAGE +ENDMASK \ No newline at end of file diff --git a/src/sc/sc2401.cpp b/src/sc/sc2401.cpp index fe50a2709..cca1442ba 100755 --- a/src/sc/sc2401.cpp +++ b/src/sc/sc2401.cpp @@ -10,56 +10,99 @@ #include #include - -bool TESSL_mask::codprof_handler(TMask_field& f, KEY k) -{ - if (f.to_check(k)) - { - TEdit_field & e = (TEdit_field &) f; - - e.check_type(CHECK_REQUIRED); - - const bool ok = e.check(); - - e.check_type(CHECK_NONE); - - if (k == K_ENTER && !ok) - { - if (f.is_editable()) - { - TEditable_field& ef = (TEditable_field&) f; - return f.error_box(ef.get_warning()); - } - } - } - return TRUE; -} - -bool TESSL_mask::lingua_handler(TMask_field& f, KEY k) -{ - if (k == K_TAB && f.focusdirty()) - { - TCursor& cur = *(((TEdit_field&)(f.mask().field(F_CODPROF))).browse()->cursor()); - // whew - TString16 lin = f.get(); - if (lin != cur.curr().get("CODPROF").mid(4)) - f.mask().field(F_CODPROF).check(RUNNING_CHECK); - } - return TRUE; -} - - TESSL_mask::TESSL_mask(const char *name) : TSelection_mask(name), _ditta(LF_NDITTE) { _ditta.add(LF_ANAG, "TIPOA==TIPOA|CODANAGR==CODANAGR"); _ditta.add(LF_COMUNI, "COM==COMRF(COMRES)", 1, LF_ANAG, 101); _ditta.add(LF_COMUNI, "COM==COMRES", 1, LF_ANAG, 102); - - set_handler(F_CODPROF, codprof_handler); - set_handler(F_LINPROF, lingua_handler); } -TESSL_mask::~TESSL_mask() {} +bool TESSL_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) +{ + switch (o.dlg()) + { + case F_CODPROF: + if (e == fe_close) + { + o.check_type(CHECK_REQUIRED); + + const bool ok = o.check(); + + o.check_type(CHECK_NONE); + + if (!ok) + return error_box(((TEditable_field &)o).get_warning()); + else + return true; + } + return true; + break; + case F_LINPROF: + if (e == fe_modify) + { + TEdit_field& cod = efield(F_CODPROF); + TCursor& cur = *(cod.browse()->cursor()); + const TString& lin = o.get(); + + if (lin != cur.curr().get("CODPROF").smid(4)) + cod.check(RUNNING_CHECK); + return true; + } + return true; + break; + case DLG_PRINT: + if (e == fe_button) + { + TCursor_sheet &s = cur_sheet(); + TCursor &c = *s.cursor(); + + // Attiva la stampa del saldo partita + form().stampa_saldo(stampa_saldo()); + form().anal_filter(get_anal_filter()); + + // filtra il cursore del form in modo che diventi uguale al cursor_sheet corrente + // Qui sarebbe bello copiarsi l'indice dell'altro cursore + TCursor & fc = *form().cursor(); + + fc.setkey(key()); + TRectype filter(LF_CLIFO); + filter.put(CLI_TIPOCF, who()); + fc.setregion(filter, filter); + + long failed = 0; // persone non stampate in quanto aventi lingua errata + TPrinter& pr = printer(); + + pr.open(); + update_checked(); + + const int last = s.last_one(); + + for (long pos = s.first_one(); pos <= last; pos++) + { + if (s.checked(pos)) + { + fc = pos; // muove il cursore alla posizione corrente + + const int ret = print_one(fc.curr().get(CLI_TIPOCF), fc.curr().get_long(CLI_CODCF)); + + if (ret < 0) + failed++; + } + if (pr.frozen()) + break; + } + pr.close(); + if (failed > 0) + warning_box(FR("%ld clienti non sono stati stampati in quanto " + "il codice lingua non corrispondeva al profilo di stampa"), failed); + } + return true; + break; + default: + break; + } + return TSelection_mask::on_field_event(o, e, jolly); +} void TESSL_mask::on_firm_change() { @@ -77,1091 +120,5 @@ void TESSL_mask::start_run() on_firm_change(); } -const char *TESSL_mask::get_prof_base() const -{ - return BASE_EC_PROFILE; -} -const TString &TESSL_mask::get_prof_code() const -{ - return get(F_CODPROF); -} - -const char *TESSL_mask::get_prof_name() const -{ - TString& tmp=(TString&)_tmp; - tmp = get(F_CODPROF); - tmp << get(F_LINPROF); - return _tmp; -} - -const TString &TESSL_mask::get_prof_lang() const { - return get(F_LINPROF); -} - -bool TESSL_mask::stampa_saldo() const { - return get_bool(F_STAMPSALDO); -} - -/////////////////////////////////////////////////////////// -// TESSL_row -/////////////////////////////////////////////////////////// - -TESSL_row::TESSL_row(const TRiga_partite& row, const TDate& data, const TImporto& imp, int rata) - : _num_prot(0), _num_reg(0), _salvo_buon_fine(false) - { - _riga = row.get_int(PART_NRIGA); - _rata = rata; - - _data = data; - _causale = row.get(PART_CODCAUS); - _data_doc = row.get(PART_DATADOC); - _num_doc = row.get(PART_NUMDOC); - _num_prot = row.get_long(PART_PROTIVA); - _num_reg = row.get_long(PART_NREG); - _importo = imp; _importo.normalize(); - _descrizione = row.get(PART_DESCR); - - _valuta.get(row); - - const bool valuta = form().in_valuta() && _valuta.in_valuta(); - const char* const field = valuta ? PART_IMPTOTVAL : PART_IMPTOTDOC; - - _totale = row.get_real(field); - -} - -TESSL_row::TESSL_row(const char* desc, const TImporto& imp, const TValuta& val) - : _riga(9999), _rata(9999), _num_prot(0), _num_reg(0), _salvo_buon_fine(false) -{ - _descrizione = desc; - _importo = imp; _importo.normalize(); - _valuta = val; -} - -// le righe dell'estratto conto sono ordinate per data, riga partita, numero rata, -// posizione iniziale nell'array (in caso di uguaglianza di tutto il resto) -int TESSL_row::compare(const TSortable& s) const -{ - const TESSL_row& r = (const TESSL_row&)s; - int c = 0; - if (_data == r._data) - { - c = r._riga - _riga; - if (c == 0) c = _rata - r._rata; - } - else - c = _data < r._data ? -1 : +1; - return c; -} - -// Annulla i campi uguali alla riga precedente -void TESSL_row::reset_uguali() -{ - _num_doc = ""; - _data_doc = botime; - _num_prot = 0; - _totale = ZERO; -} - -void TESSL_row::set_imp(TForm_item& fi, const real& imp, const char* cod_val) const -{ - fi.set(imp.string()); -} - -TESSL_form& TESSL_row::form() const -{ - TESSL_form* f = TESSL_form::_form; - CHECK(f, "NULL form"); - return *f; -} - -void TESSL_row::print_on(TPrint_section& body) -{ - TESSL_form& form = (TESSL_form&)body.form(); - - const bool show_value = form.in_valuta() && in_valuta(); - const TString& cod_valuta = show_value ? valuta().codice() : EMPTY_STRING; - - TForm_item& campo_valuta = body.find_field(PEC_VALUTA); - campo_valuta.set(cod_valuta); - - TForm_item& causale = body.find_field(PEC_CODCAUS); - causale.set(_causale); - if (_causale.not_empty() && _descrizione.empty()) - { - TDecoder& causali = form.causali(); - _descrizione = causali.decode(_causale); - } - - TForm_item& descr = body.find_field(PEC_DESCR); - if (num_reg() > 0) // Riga di partita vera e propria (non totale parziale) - { - TString s(80); - s = descr.prompt(); - TESSL_form::_form->change_magic_body(*this, s); - descr.set(s); - } - else - descr.set(_descrizione); - - TForm_item& datadoc = body.find_field(PEC_DATADOC); - datadoc.set(_data_doc.string()); - - TForm_item& numdoc = body.find_field(PEC_NUMDOC); - numdoc.set(_num_doc); - - TForm_item& numprot = body.find_field(PEC_PROTIVA); - TString16 protiva; protiva << _num_prot; - numprot.set(protiva); - - TForm_item& datapag = body.find_field(PEC_DATAPAG); - datapag.set(_data.string()); - - const real& imp = _importo.valore(); - TForm_item& dare = body.find_field(PEC_DARE); - TForm_item& avere = body.find_field(PEC_AVERE); - - if (_importo.sezione() == 'D') - { - set_imp(dare, imp, cod_valuta); - avere.set(""); - } - else - { - set_imp(avere, imp, cod_valuta); - dare.set(""); - } - - TForm_item& importo_in_euro = body.find_field(PEC_IMPEURO); - set_imp(importo_in_euro, _importo_euro, ""); // In generale va espresso nella valuta della ditta - - TForm_item& scaduto = body.find_field(PEC_SCADUTO); - set_imp(scaduto, _scaduto, cod_valuta); - - TForm_item& esposto = body.find_field(PEC_ESPOSTO); - set_imp(esposto, _esposto, cod_valuta); - esposto.set_prompt(_salvo_buon_fine ? "*" : " "); - - TForm_item& totdoc = body.find_field(PEC_TOTDOC); - //old_pictures.add(totdoc.picture()); - set_imp(totdoc, _totale, cod_valuta); - - TForm_item& cambio = body.find_field(PEC_CAMBIO); - cambio.set(_valuta.cambio().string()); - - TForm_item& datacambio = body.find_field(PEC_DATACAM); - datacambio.set(_valuta.data().string()); - - TForm_item& bloccata = body.find_field(PEC_BLOCCATA); - bloccata.set(_bloccata ? "X" : ""); - - TForm_item& analitica = body.find_field(PEC_ANALITICA); - analitica.set(_codici_analitica); - TParagraph_string p(_codici_analitica, analitica.width()); - const int h = analitica.height(); - int i = 0; - for (i = 0; p.get() != NULL && i < h; i++); - analitica.section().set_height(p.empty() ? 1 : i); - - const TString old_prompt(descr.prompt()); - descr.set_prompt(""); // Nasconde temporaneamente il prompt per non stampare i - - body.update(); // crea la vera riga di stampa - - esposto.set_prompt(" "); - descr.set_prompt(old_prompt); // Ripristina il vecchio prompt -// dare.set_picture(old_pictures.row(0)); -// avere.set_picture(old_pictures.row(1)); -// scaduto.set_picture(old_pictures.row(2)); -// esposto.set_picture(old_pictures.row(3)); -// totdoc.set_picture(old_pictures.row(4)); -} - -static int val_compare(const void* o1, const void* o2) { - const THash_object* h1 = (const THash_object*)o1; - const THash_object* h2 = (const THash_object*)o2; - const TString& s1 = (const TString&)h1->obj(); - const TString& s2 = (const TString&)h2->obj(); - return s2.compare(s1, -1, TRUE); // same as stricmp(s1, s2) in reverse order -} - - -/////////////////////////////////////////////////////////// -// TESSL_array -/////////////////////////////////////////////////////////// - -TPartita* TESSL_array::_sort_game = NULL; - -// Calcola l'importo su di una riga di pagamento -TImporto TESSL_array::importo(const TPartita& game, const TRectype& pag, bool valuta) const -{ - const int nriga = pag.get_int(PAGSCA_NRIGA); - const TRiga_partite& fat = game.riga(nriga); // Riga di fattura - const bool fat_val = fat.in_valuta(); - - const int nrigp = pag.get_int(PAGSCA_NRIGP); - const TRiga_partite& sum = game.riga(nrigp); // Riga di pagamento - const char sez = sum.sezione(); - - const char* const field = valuta && fat_val ? PAGSCA_IMPORTOVAL : PAGSCA_IMPORTO; - TImporto imp(sez, pag.get_real(field)); // Importo base - - if (!fat_val) - { - imp.valore() += pag.get_real(PAGSCA_RITENUTE); // Sommo le ritenute se sono in lire - const TImporto ritsoc(sum.sezione_ritsoc(), pag.get_real(PAGSCA_RITSOC)); - imp += ritsoc; - } - - if (pag.get_char(PAGSCA_ACCSAL) == 'S') // Se il pagamento ha abbuoni o differenze cambio - { - real abb(pag.get(PAGSCA_ABBUONI)); - if (!valuta && fat_val) // Se voglio gli abbuoni in lire ma la fattura non lo e' - { - const TValuta val(sum); // Leggo il cambio dalla riga di partita - val.val2eur(abb); // Converto in lire gli abbuoni - abb += pag.get_real(PAGSCA_DIFFCAM); // Sommo l'eventuale differenza cambio (gia' in lire) - } - imp.valore() += abb; // Sommo il tutto all'importo base (sez e' uguale per tutti i valori) - } - - return imp; -} - -// Certified 100% -TImporto& TESSL_array::importo_riga_scaduto(int n) -{ - CHECKD(n > 0 && n < 9999, "Riga scaduto errata ", n); - TImporto* imp = importo_riga_scaduto_ptr(n); - if (imp == NULL) - { - imp = new TImporto; - _scaduto.add(imp, n); - } - return *imp; -} - -// Ordina i pagamenti in ordine di DATAPAG -int TESSL_array::ordina_pag(const void* pag1, const void* pag2) -{ - const int r1 = (*(TRectype**)pag1)->get_int(PAGSCA_NRIGP); - const TDate d1 = _sort_game->riga(r1).get(PART_DATAPAG); - const int r2 = (*(TRectype**)pag2)->get_int(PAGSCA_NRIGP); - const TDate d2 = _sort_game->riga(r2).get(PART_DATAPAG); - const int diff = d1 == d2 ? 0 : (d1 > d2 ? +1 : -1); - return diff; -} - -real TESSL_array::calcola_scaduto(const TRiga_scadenze& rata, bool valuta) -{ - const TPartita& game = rata.partita(); - const char sezione = game.conto().tipo() == 'C' ? 'D' : 'A'; - - TImporto scaduto_rata = rata.importo(valuta); - - int riga_corrente_scaduto = 0; - - const int numpag = rata.rows(); // Numero totale di pagamenti sulla rata - TRectype** arrpag = NULL; // Array di puntatori ai pagamenti - if (numpag > 0) - { - arrpag = new TRectype*[numpag]; - int i = 0; - for (int p = rata.last(); p > 0; p = rata.pred(p)) - arrpag[i++] = (TRectype*)&rata.row(p); // Copia puntatori ai pagamenti nell'array - _sort_game = (TPartita*)&game; // Inizializza partita di appoggio al sort - qsort(arrpag, numpag, sizeof(TRectype*), ordina_pag); - } - - for (int i = 0; i < numpag; i++) - { - const TRectype& pag = *arrpag[i]; - const int nrigp = pag.get_int(PAGSCA_NRIGP); - const TRiga_partite& sum = game.riga(nrigp); - TImporto imp = importo(game, pag, valuta); - - tipo_movimento tm = sum.tipo(); // Determina tipo riga - - // Normalmente gli utenti non usano il tipo pagamento insoluto, per cui devo - // riconoscere i pagamenti che in realta' sono a fronte di insoluti: - // 1) hanno tipo movimento = tm_pagamento - // 2) ho gia' incontrato un insoluto - // 3) il saldo della rata e' a zero o sommando l'importo arriva sotto zero - if (tm == tm_pagamento && riga_corrente_scaduto != 0) - { - if (scaduto_rata.is_zero()) - { - tm = tm_pagamento_insoluto; - } - else - { - TImporto p(scaduto_rata); - p += imp; - p.normalize(sezione); - - if (p.valore() < ZERO) - { - scaduto_rata.set('D', ZERO); - imp += p; - tm = tm_pagamento_insoluto; - } - } - } - if (tm == tm_insoluto || tm == tm_pagamento_insoluto) - { - if (tm == tm_insoluto) - riga_corrente_scaduto = nrigp; - else - CHECKD(riga_corrente_scaduto > 0, "Pagamento insoluto senza insoluto ", nrigp); - importo_riga_scaduto(riga_corrente_scaduto) += imp; - } - else - { - scaduto_rata += imp; - } - } - - if (arrpag != NULL) - delete arrpag; - - scaduto_rata.normalize(sezione); - return scaduto_rata.valore(); -} - -TESSL_row& TESSL_array::new_row(const TRiga_partite& row, const TDate& data, const TImporto& imp, int n) -{ - CHECKD(n > 0, "Numero rata errato: ", n); - TESSL_row* riga = new TESSL_row(row, data, imp, n); - add(riga); - return *riga; -} - -void TESSL_array::add_row(const TRiga_partite& row) -{ - const bool in_valuta = form().in_valuta() && row.in_valuta(); - real importo_in_lire; - const char sezione = form().sezione_normale(); - - const TDate data_op = row.get(PART_DATAREG); - if (data_op <= form().data_limite_operazione()) - { - TString codanal; - - if (main_app().has_module(CAAUT, CHK_DONGLE)) - { - const TString& numregcg = row.get(PART_NREG); - const long numreg = atol(_anal.decode(numregcg)); - - if (numreg > 0) - { - TAnal_mov anal_mov(numreg); - TRecord_array & rows = anal_mov.body(); - const int nrows = rows.rows(); - - for (int i = 1; i <= nrows; i++) - { - const TString80 s = anal_mov.row_code(i); - if (s.full() && codanal.find(s) < 0) - { - if (codanal.full()) - codanal << '\n'; - if (s.full()) - codanal << s; - } - } - } - } - if (row.is_fattura()) - { - for (int r = 1; r <= row.rate(); r++) - { - const TRiga_scadenze& rata = row.rata(r); - const TDate data_scad = rata.get(SCAD_DATASCAD); - TESSL_row& rec = new_row(row, data_scad, rata.importo(in_valuta), r); - if (in_valuta) - { - TImporto il(rata.importo(false)); - il.normalize(sezione); - rec.importo_in_euro(il.valore()); - } - if (data_scad <= form().data_limite_scaduto()) - { - const real s = calcola_scaduto(rata, in_valuta); - rec.scaduto(s); - } - rec.rata_bloccata(rata.get_bool(SCAD_BLOCCATA)); - rec.codici_analitica(codanal); - } - } - else - { - const TDate data_pag(row.get(PART_DATAPAG)); - const TImporto imp(row.importo(in_valuta, 0x1)); // Importo pulito senza nient'altro - TESSL_row& riga = new_row(row, data_pag, imp, RIGA_PART_PAGAMENTO); - if (in_valuta) - { - TImporto i(row.importo(FALSE, 0x1)); - i.normalize(sezione); - riga.importo_in_euro(i.valore()); - } - riga.codici_analitica(codanal); - - const int tipo_pag = row.get_int(PART_TIPOPAG); - const tipo_movimento tipo_mov = row.tipo(); - - // Controlla se e' un pagamento con effetti - if ((tipo_mov == tm_pagamento || tipo_mov == tm_pagamento_insoluto) && - (tipo_pag >= 2 && tipo_pag <= 7)) - { - const TDate& dls = form().data_limite_scaduto(); - const int gr = form().giorni_rischio(); - const TDate& dir = form().data_inizio_rischio(); - - bool sbf = false; - TImporto esposto(row.esposto(in_valuta, dls, dir, sbf)); - bool esp = !esposto.is_zero(); - - if (esp) - { - esposto.normalize(sezione); - riga.salvo_buon_fine(sbf); // Esposto salvo buon fine - riga.esposto(esposto.valore()); - } - } - - TImporto ritenute(row.importo(FALSE, 0x8)); - if (!ritenute.is_zero()) - { - TESSL_row& r = new_row(row, data_pag, TImporto('D', ZERO), RIGA_PART_RITENUTE); - r.descrizione(form().describe(PEC_RITENUTE)); - if (in_valuta) - { - ritenute.normalize(sezione); - r.importo_in_euro(ritenute.valore()); - } - else - r.importo(ritenute); - r.codici_analitica(codanal); - } - - const TImporto abbuoni(row.importo(in_valuta, 0x2)); - if (!abbuoni.is_zero()) - { - TESSL_row& r = new_row(row, data_pag, abbuoni, RIGA_PART_ABBUONI); - r.descrizione(form().describe(PEC_ABBUONI)); - if (in_valuta) - { - TImporto il(row.importo(FALSE, 0x2)); - il.normalize(sezione == 'D' ? 'A' : 'D'); - r.importo_in_euro(il.valore()); - } - r.codici_analitica(codanal); - } - - TImporto diffcam(row.importo(FALSE, 0x4)); - if (!diffcam.is_zero() && !in_valuta) - { - TESSL_row& r = new_row(row, data_pag, TImporto('D', ZERO), RIGA_DIFFCAM); - r.descrizione(form().describe(PEC_DIFFCAM)); - r.importo(diffcam); - r.codici_analitica(codanal); } - } - } -} - -void TESSL_array::arrange_scaduto(const TPartita& game) - -{ - const bool in_valuta = form().in_valuta() && row(0).in_valuta(); - TImporto totpag(game.importo_pagato_unassigned(in_valuta)); - const char sezione = game.conto().tipo() == 'C' ? 'D' : 'A'; - - totpag.normalize(sezione); - int r; - for (r = items()-1; r >= 0; r--) - { - TESSL_row& s = row(r); - real imp(s.scaduto()); - if (imp.sign() < 0) - { - totpag += TImporto(sezione, imp); - s.scaduto(ZERO); - } - } - for (r = 0; r < items() && totpag.valore() >= ZERO; r++) - { - TESSL_row& s = row(r); - real imp = s.scaduto(); - if (imp.sign() > 0) - { - if (imp >= totpag.valore()) - { - imp -= totpag.valore(); - s.scaduto(imp); - totpag = TImporto(sezione, ZERO); - } - else - { - s.scaduto(ZERO); - totpag -= TImporto(sezione, imp); - } - } - } -} - -TESSL_array::TESSL_array(const TPartita& game, const TESSL_form* f) - :_form(f), _anal(LF_MOVANA, MOVANA_NUMREG, 3) -{ - int r; - for (r = game.last(); r > 0; r = game.pred(r)) - add_row(game.riga(r)); - const char sezione = f->sezione_normale(); - for (r = items()-1; r >= 0; r--) - { - TESSL_row& s = row(r); - if (s.rata() == RIGA_PART_PAGAMENTO) - { - TImporto* imp = importo_riga_scaduto_ptr(s.riga()); - if (imp != NULL) - { - imp->normalize(sezione); - s.scaduto(imp->valore()); - } - } - } - if (items() > 0) - { - sort(); - arrange_scaduto(game); - } -} - - -/////////////////////////////////////////////////////////// -// TESSL_form: form speciale per estratti conto e solleciti -/////////////////////////////////////////////////////////// - -TESSL_form * TESSL_form::_form = NULL; - -void TESSL_form::stampa_testata(TPrinter& pr) -{ - TPrint_section& head = section('H'); - - TForm_item& pagina = head.find_field(PEC_PAGINA); - TString16 pg; pg << int(pr.getcurrentpage()); - pagina.set(pg); - - head.update(); - - const word r = head.height()-1; - - for (word j = 0; j <= r; j++) - pr.setheaderline(j, head.row(j)); - -} - -static int tot_compare(const void* o1, const void* o2) -{ - if (o1 == o2) // Sfrutto una piccola debolezza di qsort: - return 0; // ogni tanto confronta oggetti con se stessi - - const THash_object* h1 = *((const THash_object**)o1); - const THash_object* h2 = *((const THash_object**)o2); - return h1->key().compare(h2->key(), -1, true); // was stricmp -} - -word TESSL_form::ordina_totali_per_valuta(THash_object* tot[MAXTOT]) -{ - // I totali sono in un assoc array disordinato per cui li copio in un array e li ordino - // alfabeticamente in base al loro codice valuta - TTotalizer& arr = totali(); - arr.restart(); - word num_rip = 0; - for (THash_object* obj = arr.get_hashobj(); - num_rip < MAXTOT && obj != NULL; - obj = arr.get_hashobj()) - tot[num_rip++] = obj; - qsort(tot, num_rip, sizeof(THash_object*), tot_compare); - return num_rip; -} - -void TESSL_form::stampa_riporti(TPrinter& pr) -{ - THash_object* tot[MAXTOT]; - _num_rip = ordina_totali_per_valuta(tot); - - if (_num_rip > _maxtot) - _num_rip = _maxtot; - - const TString& riporto = describe(PEC_RIPORTO); - - TString desc(80); - TPrint_section& body = section('B'); - for (word j = 0; j < _num_rip; j++) - { - const TString& key = tot[j]->key(); - TTotal& t = (TTotal&)(tot[j]->obj()); - - desc = riporto; - TValuta val; - if (key.not_empty()) - { - desc << ' ' << key; - TValuta val1(key,botime,ZERO); // E' una valuta fittizia, giusto per far - val = val1; // eseguire in set_imp() i calcoli per i decimali. - } - TESSL_row rip(desc, t.importo().normalize(),val); - rip.scaduto(t.scaduto()); - rip.esposto(t.esposto()); - rip.importo_in_euro(t.importo_euro()); - rip.print_on(body); - pr.setfooterline(j + 1, body.row(0)); - } -} - -int TESSL_form::find_magic(TString& s, TString& magic1, TString& magic2) const -{ - const int pos = s.find('<', 0); - int end; - if (pos >= 0) - { - end = s.find('>', pos); - if (end > pos) - { - int p1 = pos+1; - magic1 = s.mid(p1, 2); - while (isalnum(s[p1])) p1++; - while (p1 < end && !isalnum(s[p1])) p1++; - if (p1 < end) - magic2 = s.mid(p1, 2); - else - magic2.cut(0); - } - else - end = s.len()-1; - - const TString right(s.mid(end+1)); - s.cut(pos); s << right; - } - return pos; -} - -void TESSL_form::change_magic_body(const TESSL_row& row, TString& s) -{ - TString magic1(4), magic2(4), val(50); - int pos; - while ((pos = find_magic(s, magic1, magic2)) >= 0) - { - val.cut(0); - if (magic1 == "PA" || magic2 == "PA") - { - val = row.descrizione(); - if (val.empty()) - val = causali().decode(row.causale()); - } - if (magic1 == "MO" || magic2 == "MO") - { - val = movimenti().decode(row.num_reg()); - } - s.insert(val, pos); - } -} - -void TESSL_form::change_magic_footer(const THash_object& o, TString& s) -{ - TString magic1(4), magic2(4), val(50); - int pos; - while ((pos = find_magic(s, magic1, magic2)) >= 0) - { - val.cut(0); - if (magic1 == "DA") - { - const TDate& d = magic2 == "SC" ? _dls : _dlo; - if (d != eotime) - val = d.string(); - } - if (magic1 == "VA") - val = o.key(); - if (magic1 == "DE") - val = valute().decode(o.key()); - - s.insert(val, pos); - } -} - -void TESSL_form::print_total(int riga, const THash_object& o) -{ - const short MAXID = 5; - const short f_id[MAXID] = { PEC_TSALDO, PEC_TSCADUTO, PEC_TESPOSTO, PEC_TIMPEURO, PEC_TUNASSIGNED }; - TString_array prompt(MAXID); - - TPrint_section& foot = section('F'); - TPrint_section& body = section('B'); - TForm_item& bdesc = body.find_field(PEC_DESCR); - - // Sostituisce magic-names nei prompt - TString s(80); - int i; - for (i = 0; i < MAXID; i++) - { - TForm_item& desc_field = foot.find_field(f_id[i]); - if (desc_field.shown()) - { - s = desc_field.prompt(); - prompt.add(s, i); - change_magic_footer(o, s); - desc_field.set_prompt(s); - if (desc_field.x() <= 0) - desc_field.set_x(bdesc.x()); - } - } - - const TTotal& t = (const TTotal&)o.obj(); - const TImporto& imp = t.importo(); - const bool in_valuta = o.key().not_empty(); - TForm_item& dare = foot.find_field(PEC_DARE); - TForm_item& avere = foot.find_field(PEC_AVERE); - TString_array old_pictures;//pictures da rippristinare dopo aver stampato - - if (dare.x() <= 0 || avere.x() <= 0) - { - TForm_item& bdare = body.find_field(PEC_DARE); - dare.set_x(bdare.x()); - dare.width() = bdare.width(); - - TForm_item& bavere = body.find_field(PEC_AVERE); - avere.set_x(bavere.x()); - avere.width() = bavere.width(); - } - //modify_picture(dare,old_pictures,in_valuta); - //modify_picture(avere,old_pictures,in_valuta); - char sez = imp.sezione(); - real num = imp.valore(); - if (sez=='D' && num<0) - { - num = abs(num); sez = 'A'; - } - if (sez=='A' && num<0) - { - num = abs(num); sez = 'D'; - } - if (sez == 'D') - { - dare.set(num.string()); - avere.set(""); - } - else - { - dare.set(""); - avere.set(num.string()); - } - - TForm_item& scaduto = foot.find_field(PEC_SCADUTO); - if (scaduto.x() <= 0) - { - TForm_item& bscaduto = body.find_field(PEC_SCADUTO); - scaduto.set_x(bscaduto.x()); - scaduto.width() = bscaduto.width(); - } - //modify_picture(scaduto,old_pictures,in_valuta); - scaduto.set(t.scaduto().string()); - - TForm_item& esposto = foot.find_field(PEC_ESPOSTO); - if (esposto.x() <= 0) - { - TForm_item& besposto = body.find_field(PEC_ESPOSTO); - esposto.set_x(besposto.x()); - esposto.width() = besposto.width(); - } - //modify_picture(esposto,old_pictures,in_valuta); - esposto.set(t.esposto().string()); - - TForm_item& implire = foot.find_field(PEC_IMPEURO); - if (implire.x() <= 0) - { - TForm_item& bimplire = body.find_field(PEC_IMPEURO); - implire.set_x(bimplire.x()); - implire.width() = bimplire.width(); - if (bimplire.shown()) implire.show(); - else implire.hide(); - } - //modify_picture(implire,old_pictures,FALSE); - implire.set(t.importo_euro().string()); - - TForm_item& unreferenced = foot.find_field(PEC_UNASSIGNED); - if (unreferenced.x() <= 0) - { - TForm_item& uns = body.find_field(PEC_AVERE); - unreferenced.set_x(uns.x()); - unreferenced.width() = avere.width(); - } - //modify_picture(unreferenced,old_pictures,in_valuta); - unreferenced.set(t.unassigned().valore().string()); - - foot.update(); - - // Ripristina prompt originari - for (i = 0; i < MAXID; i++) - { - const TString* p = (const TString*)prompt.objptr(i); - if (p) - { - TForm_item& desc_field = foot.find_field(f_id[i]); - desc_field.set_prompt(*p); - } - } - for (word r = 0; r < _total_rows; r++) - printer().setfooterline(riga + r, foot.row(r)); -} - -void TESSL_form::stampa_pedata(TPrinter& pr) -{ - THash_object* tot[MAXTOT]; - word num_rip = ordina_totali_per_valuta(tot); - - // La prima riga del footer deve essere lasciata libera per la fincatura - // Ogni sottosezione di totale occupa _total_rows righe: per cui devo calcolare - // quanti totali ci stanno nelle righe riservate al footer -// const word maxtot = (section('F').height()-1) / _total_rows; - if (num_rip > _maxtot) - num_rip = _maxtot; - - for (word j = 0; j < num_rip; j++) - print_total(j*_total_rows+1, *tot[j]); -} - -void TESSL_form::ultima_pagina() -{ - set_last_page(TRUE); -} - -void TESSL_form:: header_handler(TPrinter& pr) -{ - pr.resetheader(); - - _form->stampa_testata(pr); -} - -void TESSL_form::footer_handler(TPrinter& pr) -{ - pr.resetfooter(); - if (_form->page(pr) > 0) // Normal page - _form->stampa_riporti(pr); - else // Last page - _form->stampa_pedata(pr); -} - - -void TESSL_form::azzera_totali() -{ - totali().destroy(); // Azzera tutti i riporti - _num_rip = 0; // Azzera il numero di righe di riporto - set_last_page(FALSE); // Azzera il flag di ultima pagina di stampa - - TPrint_section& foot = section('F'); - printer().footerlen(foot.height()); - printer().setcurrentpage(1); -} - -bool TESSL_form::print_game(const TPartita& game) -{ - bool ok = false; - - TESSL_array righe(game, this); - - TPrinter& pr = printer(); - TPrintrow prow; - - TPrint_section& body = section('B'); - - TImporto saldo; - real scaduto, esposto, impeuro; - - // Stampa le righe di partita - - int ultima_riga = 0; - int ultima_rata = 0; - int r; - for (r = 0; r < righe.items(); r++) - { - TESSL_row& riga = righe.row(r); - if (pr.rows_left() <= (body.height()+1)) - { - pr.formfeed(); - for (word nr = 0; nr < _num_rip; nr++) - { - TPrintrow* fl = pr.getfooterline(nr + 1); - CHECKD(fl, "Manca la riga di riporto ", nr + 1); - pr.print(*fl); - } - } - - const int ri = riga.riga(); - const int ra = riga.rata(); - if (ri == ultima_riga && ra == ultima_rata+1) - riga.reset_uguali(); - ultima_riga = ri; - ultima_rata = ra; - - real resp = riga.esposto(); - if (resp < ZERO) - { - resp = -resp; - riga.esposto(resp); - } - - riga.print_on(body); - pr.print(body.row(0)); - - - totali().add(riga.importo(), riga.scaduto(), riga.esposto(), - riga.importo_in_euro(), riga.valuta().codice()); - - saldo += riga.importo(); - scaduto += riga.scaduto(); - esposto += riga.esposto(); - impeuro += riga.importo_in_euro(); - ok = true; - } - - if (ok) - { - if (_stampa_saldo) - { - saldo.normalize(); - - TString desc; - desc = describe(PEC_SALDO); - const TValuta& val = righe.row(r-1).valuta(); - if (val.in_valuta()) - desc << ' ' << val.codice(); - - TESSL_row sld(desc, saldo, val); - - sld.scaduto(scaduto); - sld.esposto(esposto); - sld.importo_in_euro(impeuro); - sld.print_on(body); - pr.print(body.row(0)); - } - - // Salta una riga vuota - TPrintrow vuota; - pr.print(vuota); - } - return ok; -} - -const TString& TESSL_form::describe(short id, char sez, pagetype pt) const -{ - const TForm_item& fi = find_field(sez, pt, id); - return fi.prompt(); -} - -void TESSL_form::init_header(const TMask& m) -{ - TPrint_section& head = section('H'); - - TForm_item& luogo_invio = head.find_field(PEC_LUOGOIN); - luogo_invio.set(m.get(F_LUOGOSEND)); - - TForm_item& data_invio = head.find_field(PEC_DATAIN); - data_invio.set(m.get(F_DATASEND)); - - TForm_item& fi = head.find_field(PEC_MEMO); - if (fi.shown()) - { - TString key; - - key.format("%s|%s|H0|%d", (const char *) name(), (const char *) code(), PEC_MEMO); - - const TRectype & rform = cache().get(LF_RFORM, key); - if (!rform.empty()) - fi.set(rform.get("TESTO")); - } - -} - -TESSL_form::TESSL_form(const TESSL_mask& m, bool gesval, short id_datalim, short id_datascad, - short id_giorni_rischio) - :TForm(BASE_EC_PROFILE, m.get_prof_name()), - _in_valuta(FALSE), _num_rip(0), _total_rows(0), - _causali(LF_CAUSALI, CAU_DESCR), - _movimenti(LF_MOV, MOV_DESCR), - _valute("%VAL"), _giorni_rischio(0), _maxtot(1), - _stampa_saldo(TRUE) -{ - _form = this; - - _lingua = m.get_prof_lang(); - _who = m.get_who(); - - _stampa_esp = m.get_bool(F_STAMPESP); - - TCursor_sheet& cs = m.cur_sheet(); - _cursore = cs.cursor(); - - _dlo = id_datalim > 0 ? m.get_date(id_datalim) : eotime; - if (!_dlo.ok()) - _dlo = eotime; - _dls = id_datascad > 0 ? m.get_date(id_datascad) : eotime; - if (id_giorni_rischio > 0) - _giorni_rischio = m.get_int(id_giorni_rischio); - - _dir = _dls; _dir -= _giorni_rischio; - - TPrinter& pr = printer(); - - pr.setheaderhandler(header_handler); - TPrint_section& head = section('H'); - pr.headerlen(head.height()); - - TForm_item& flags = find_field('H', last_page, PEC_FLAGS); - TToken_string f(flags.prompt()); - _in_valuta = gesval && f.get_char(0) == 'X'; // Il profilo e' in valuta se c'e' il flag di valuta - _fincatura = f.get_int(1); - TForm_item& esp = section('B').find_field(PEC_ESPOSTO); - if (esp.shown()) esp.show(_stampa_esp); //setta la colonna esposto solo se abilitata - genera_intestazioni(odd_page, head.height() - 1); - init_header(m); // Set fixed text - - pr.setfooterhandler(footer_handler); - const TPrint_section& foot = section('F'); - pr.footerlen(foot.height()); - - _total_rows = 1; - for (word fi = 0; fi < foot.fields(); fi++) - { - const TForm_item& item = foot.field(fi); - if (item.shown()) - { - const word y = (word)item.y(); - if (y > _total_rows) - _total_rows = y; - } - } - _maxtot = f.get_int(3); - if (_maxtot <= 0 || _maxtot > ((int)foot.height() - 2) / _total_rows) - _maxtot = (foot.height() - 2) / _total_rows; - - int rows[] = { (int)head.height(), (int)(pr.formlen() - foot.height() + 1), 0}; - TPrint_section& fink = section('G'); - if (_fincatura) - { - set_fink_mode(_fincatura == 1 ? FALSE : TRUE); - genera_fincatura(odd_page, rows[0] - 2, rows[1] + (_maxtot * _total_rows) + 2, rows); - } - if (fink.fields() > 0) - fink.update(); // Setta il backgroud di stampa -} - -TESSL_form::~TESSL_form() -{ - TPrinter& pr = printer(); - pr.setheaderhandler(NULL); - pr.setfooterhandler(NULL); - _form = NULL; -} - diff --git a/src/sc/sc2401.h b/src/sc/sc2401.h index be70a5c11..eb76447f4 100755 --- a/src/sc/sc2401.h +++ b/src/sc/sc2401.h @@ -41,203 +41,11 @@ protected: virtual void on_firm_change(); virtual void start_run(); - static bool lingua_handler(TMask_field& f, KEY k); - static bool codprof_handler(TMask_field& f, KEY k); - public: - const char *get_prof_base() const; - const TString &get_prof_code() const; - const char *get_prof_name() const; - const TString &get_prof_lang() const; - - bool stampa_saldo() const; + virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); TESSL_mask(const char *name); - virtual ~TESSL_mask(); + virtual ~TESSL_mask() = default; }; -class TESSL_form; - -/////////////////////////////////////////////////////////// -// TESSL_row -/////////////////////////////////////////////////////////// - -class TESSL_row : public TSortable -{ - TDate _data; // Data scadenza o pagamento - int _riga; // Riga della fattura - int _rata; // Numero rata o progrssivo - - TString _causale; // Codice causale - TString _descrizione; // Sua descrizione - - TDate _data_doc; // Data del documento - TString _num_doc; // Numero documento - long _num_prot; // Protocollo IVA - long _num_reg; // Numero registrazione - TImporto _importo; // Importo in valuta - real _importo_euro; // Importo in euro - real _scaduto; // Importo scaduto - real _esposto; // Importo esposto - bool _salvo_buon_fine; // Importo esposto salvo buon fine - real _totale; // Totale documento - TValuta _valuta; // Codice valuta, data cambio e cambio - bool _bloccata; // Rata bloccata - TString _codici_analitica; // codici analitica corrispondenti alle fatture - -protected: // TSortable - virtual int compare(const TSortable& s) const; - void set_imp(TForm_item& fi, const real& imp, const char* cod_val) const; - - TESSL_form& form() const; - -public: - int riga() const { return _riga; } - int rata() const { return _rata; } - - void reset_uguali(); - void descrizione(const char* s) { _descrizione = s; } - void importo(const TImporto& i) { _importo = i; } - void scaduto(const real& s) { _scaduto = s; } - void esposto(const real& e) { _esposto = e; } - void importo_in_euro(const real& imp) { _importo_euro = imp; } - void salvo_buon_fine(bool sbf) { _salvo_buon_fine = sbf; } - void rata_bloccata(bool rb) { _bloccata = rb; } - void codici_analitica(const char * s) { _codici_analitica = s; } - - const TString& causale() const { return _causale; } - const TString& descrizione() const { return _descrizione; } - long num_reg() const { return _num_reg; } - const TValuta& valuta() const { return _valuta; } - const TImporto& importo() const { return _importo; } - const real& importo_in_euro() const { return _importo_euro; } - const real& scaduto() const { return _scaduto; } - const real& esposto() const { return _esposto; } - const TDate& data() const { return _data; } - bool in_valuta() const { return _valuta.in_valuta(); } - - void print_on(TPrint_section& body); - - TESSL_row(const TRiga_partite& row, const TDate& data, const TImporto& imp, int rata); - TESSL_row(const char* desc, const TImporto& imp, const TValuta& val); - virtual ~TESSL_row() {} -}; - -/////////////////////////////////////////////////////////// -// TESSL_form: form speciale per estratti conto -/////////////////////////////////////////////////////////// - -class TESSL_form : public TForm -{ - friend class TESSL_row; - - static TESSL_form* _form; - - enum { MAXTOT = 16 }; - - TCursor* _cursore; - TTotalizer _totali; - - TString _lingua; - TDate _dlo, _dls, _dir; - - int _fincatura; // 0 = nessuna, 1 = testo, 2 = grafica - char _who; - - int _giorni_rischio; - word _maxtot; // numero massimo di totali - - bool _in_valuta; - bool _stampa_esp; - bool _stampa_saldo; // Stampa il saldo di ogni partita - - TToken_string _anal_filter; - - word _num_rip; // numero di righe usate per i riporti - word _total_rows; // numero di righe usate per i totali - - TDecoder _causali; // Decodificatore dei codici causale - TDecoder _movimenti; // Decodificatore delle descrizioni dei movimenti - TDecoder _valute; // Decodificatore dei codici valuta - -protected: - void init_header(const TMask& m); - word ordina_totali_per_valuta(THash_object* tot[MAXTOT]); - int find_magic(TString& s, TString& magic1, TString& magic2) const; - void change_magic_body(const TESSL_row& o, TString& s); - void change_magic_footer(const THash_object& o, TString& s); -// void modify_picture(TForm_item& fi, TString_array& op, const bool in_valuta); - void print_total(int riga, const THash_object& o); - - void stampa_testata(TPrinter& p); - void stampa_pedata(TPrinter& p); - void stampa_riporti(TPrinter& p); - - static void header_handler(TPrinter& p); - static void footer_handler(TPrinter& p); - -public: - TTotalizer& totali() { return _totali; } - TDecoder& causali() { return _causali; } - TDecoder& valute() { return _valute; } - TDecoder& movimenti() { return _movimenti; } - - const TDate& data_limite_operazione() const { return _dlo; } - const TDate& data_limite_scaduto() const { return _dls; } - int giorni_rischio() const { return _giorni_rischio; } - const TDate& data_inizio_rischio() const { return _dir; } - - const TString& lingua() const { return _lingua; } - bool in_valuta() const { return _in_valuta; } - const TString& describe(short id, char sez = 'H', pagetype pt = last_page) const; - const char sezione_normale() const { return _who == 'C' ? 'D' : 'A' ; } - - void stampa_saldo(bool ss = TRUE) { _stampa_saldo = ss; } - void anal_filter(const TToken_string & f) { _anal_filter = f; } - const TToken_string &get_anal_filter() const { return _anal_filter; } - - void azzera_totali(); - void ultima_pagina(); - virtual bool print_game(const TPartita& game); - - TESSL_form(const TESSL_mask& m, bool gesval, short id_datalim = 0 , short id_datascad = 0, short id_giorni_rischio = 0); - virtual ~TESSL_form(); -}; - -/////////////////////////////////////////////////////////// -// TESSL_array -/////////////////////////////////////////////////////////// - -class TESSL_array : public TArray -{ - TArray _scaduto; // Array di importi scaduti - TDecoder _anal; - - - const TESSL_form* _form; - -protected: - TESSL_row& new_row(const TRiga_partite& row, const TDate& data, const TImporto& imp, int rata = 0); - void add_row(const TRiga_partite& row); - - const TESSL_form& form() const { return *_form; } - real calcola_scaduto(const TRiga_scadenze& rata, bool valuta); - - - TImporto* importo_riga_scaduto_ptr(int n) const { return (TImporto*)_scaduto.objptr(n); } - TImporto& importo_riga_scaduto(int n); - - TImporto importo(const TPartita& game, const TRectype& pag, bool valuta) const; - - static TPartita* _sort_game; - static int ordina_pag(const void* pag1, const void* pag2); - void arrange_scaduto(const TPartita& game); - -public: - TESSL_row& row(int r) const { return (TESSL_row&)operator[](r); } - - TESSL_array(const TPartita& game, const TESSL_form* f); - virtual ~TESSL_array() {} -}; - #endif // __SC2401_H diff --git a/src/sc/sc2402.cpp b/src/sc/sc2402.cpp index 1cc9a61b9..d34bb2ea7 100755 --- a/src/sc/sc2402.cpp +++ b/src/sc/sc2402.cpp @@ -1,17 +1,21 @@ #include "sc21pec.h" -#include "sc2102.h" + +#ifndef __SC2402_H #include "sc2402.h" +#endif #include "../cg/cgsaldac.h" #include "../ca/calib01.h" #include +#include "../ca/movana.h" +#include "../ca/rmovana.h" #include #include +#include -TSol_mask::TSol_mask(const char *name) - :TESSL_mask(name) +TSol_mask::TSol_mask(const char *name) : _sol_mail("sc2400b"), TESSL_mask(name), _form(nullptr) { _cdc_start = 0; _cdc_end = 0; @@ -71,15 +75,23 @@ TSol_mask::TSol_mask(const char *name) } } +TESSL_form & TSol_mask::form() +{ + if (_form == nullptr) + _form = new TSol_form(*this, ini_get_bool(CONFIG_DITTA, "cg", "GesVal"), F_DATALIMOP, F_DATALIMSOL, F_GGRISCHIO); + return *_form; +} + int TSol_mask::insert_anal_fields(TMask& m, int page, int lf, int& y, - short& dlg, short& dlgd) + short& dlg, short& dlgd) { const int h = ca_create_fields(m, page, lf, 2, y, dlg, dlgd); for (int i = 0; i < h; i++) { - TEdit_field& fld = m.efield(dlg+i); + TEdit_field& fld = m.efield(dlg + i); int logic = lf; + if (logic == LF_FASI) { const TMultilevel_code_info& fasinfo = ca_multilevel_code_info(LF_FASI); @@ -91,17 +103,265 @@ int TSol_mask::insert_anal_fields(TMask& m, int page, int lf, int& y, } } - TEdit_field& dfld = m.efield(dlgd+i); + TEdit_field& dfld = m.efield(dlgd + i); + dfld.set_field(EMPTY_STRING); // Toglie campi che fan saltare gli output! } - y += h+1; dlg += h; dlgd += h; return h; } -TSol_mask::~TSol_mask() {} +bool TSol_mask::ci_sono_scadenze_aperte(const TPartita& game, const TDate& dal, const TDate& al, const TDate& data_rischio) const +{ + bool found = false; + + for (int r = game.last(); r > 0; r = game.pred(r)) + { + const TRiga_partite& row = game.riga(r); + if (row.is_fattura() && row.get_date(PART_DATAREG) <= al) + { + for (int s = row.rate(); s > 0; s--) + { + const TRiga_scadenze& rata = row.rata(s); + const TDate data = rata.get(SCAD_DATASCAD); + if (data >= dal && data <= al) + { + found = !rata.chiusa(); + if (!found) + { + TImporto rat = rata.importo(true); + TImporto imp = rata.importo_pagato_al(true, data_rischio); + imp.normalize(rat.sezione()); + const real saldo = rat.valore() + imp.valore(); + found = saldo > ZERO; + } + if (found) + break; + } + } + } + } + return found; +} + +const TString& TSol_mask::game_key(const TRectype& part) const +{ + TToken_string& tok = get_tmp_string(); + + tok = part.get(PART_ANNO); + tok.add(part.get(PART_NUMPART)); + return tok; +} + +bool TSol_mask::puoi_scartare(const TPartita& game, const TDate& datalim) const +{ + bool yes = game.chiusa(); + + if (yes && datalim.ok()) + { + TDate last; + + for (int r = game.last(); r > 0; r = game.pred(r)) + { + const TRiga_partite& riga = game.riga(r); + + if (riga.tipo() > tm_fattura) + { + const TDate d = riga.get(PART_DATAPAG); + + if (d > last) + last = d; + } + } + yes = last < datalim; + } + return yes; +} + +bool TSol_mask::some_to_print(const char * tipo, const long codice) +{ + TSol_form& f = (TSol_form&) form(); + const bool sel_tot_saldo = f.get_sel_tot_saldo(); // selezione sul saldo totale cliente + const real sel_importo(f.get_sel_importo()); // importo di selezione + const TDate data_inizio_soll = get(F_DATAINISCAD); + const TDate data_limite_soll = f.data_limite_operazione(); + const TDate data_limite_scaduto = f.data_limite_scaduto(); + const TDate data_rischio = f.data_inizio_rischio(); + TAssoc_array games_in_range; + real saldo; + bool any_to_print = false; + // filtra solo le partite del cliente selezionato + TRectype filter(LF_PARTITE); + TLocalisamfile partite(LF_PARTITE); + const TRectype& parkur = partite.curr(); + + filter.put(PART_TIPOCF, tipo); + filter.put(PART_SOTTOCONTO, codice); + partite.curr() = filter; + for (int err = partite.read(_isgteq); + err == NOERR && parkur == filter; + err = partite.read(_isgreat)) + { + const TPartita game(parkur); + + if (!puoi_scartare(game, data_rischio)) + { + if (sel_tot_saldo) + { + const real sld = game.calcola_scaduto_al(false, data_limite_soll); + saldo += sld; + } + if (data_inizio_soll.ok()) + { + if (ci_sono_scadenze_aperte(game, data_inizio_soll, data_limite_soll, data_rischio)) + any_to_print = true; + } + else + any_to_print = true; + } + partite.put(PART_NRIGA, 9999); + } + if (sel_tot_saldo && sel_importo > ZERO && saldo < sel_importo) + any_to_print = false; + return any_to_print; +} + +int TSol_mask::print_one(const char * tipo, const long codice) +{ + TSol_form& f = (TSol_form&)form(); + + // preparazione variabili per controllo lingua +; + const TString4 lincf = f.cursor()->file().curr().get(CLI_CODLIN); + bool ok = true; + TString lind = ini_get_string(CONFIG_DITTA, "cg", "CodLin"); + TString linf = f.lingua(); + + // controllo lingua ditta corrente + if (linf == lind && lincf.full()) + ok = (lincf == linf); + if (linf != lind) + ok = (lincf == linf); + if (!ok) + return -1; // cliente analfabeta + f.azzera_totali(); + // filtra solo le partite del cliente selezionato + TLocalisamfile partite(LF_PARTITE); + partite.zero(); + partite.put(PART_TIPOCF, tipo); + partite.put(PART_SOTTOCONTO, codice); + + const TRectype& parkur = partite.curr(); + const TRectype filter(parkur); + bool one_printed = false; // booleano di controllo di riuscita della stampa + const bool sel_tot_saldo = f.get_sel_tot_saldo(); // selezione sul saldo totale cliente + const real sel_importo(f.get_sel_importo()); // importo di selezione + const TDate data_inizio_soll = get(F_DATAINISCAD); + const TDate data_limite_soll = f.data_limite_operazione(); + const TDate data_limite_scaduto = f.data_limite_scaduto(); + TToken_string anal_filter = form().get_anal_filter(); + const bool select_analitica = (dongle().active(CAAUT) || dongle().active(CMAUT)) && anal_filter.full(); + TDecoder anal(LF_MOVANA, MOVANA_NUMREG, 3); + const TDate data_rischio = f.data_inizio_rischio(); + TAssoc_array games_in_range; + + if (some_to_print(tipo, codice)) + { + partite.curr() = filter; + + for (int err = partite.read(_isgteq); + err == NOERR && parkur == filter; + err = partite.read(_isgreat)) + { + if (data_inizio_soll.ok() && !games_in_range.is_key(game_key(parkur))) + continue; // Scarta parite fuori range di date + + const TPartita game(parkur); + if (!puoi_scartare(game, data_rischio)) + { + const real saldo = game.calcola_scaduto_al(false, data_limite_scaduto); + + TImporto unreferenced; //Totale non assegnati per questa partita. + { + // E' giusto calcolare il saldo, comprendente i non assegnati. + // se il saldo della partita chiude in avere va sommato ad unreferenced + const TRiga_partite& sum = game.riga(game.first()); + unreferenced = game.calcola_saldo_al(game.in_valuta() && f.in_valuta(), data_limite_soll, data_limite_scaduto, data_rischio); + if (unreferenced.valore() > ZERO && unreferenced.sezione() == 'A') + { + unreferenced.normalize('A'); //per i non assegnati/anticipi c'e' solo la colonna AVERE + const TString4 valuta = sum.get(PART_CODVAL); + form().totali().add(unreferenced, valuta); + } + } + + if (select_analitica) + { + bool print = false; + for (int r = game.first(); !print && r <= game.last(); r = game.succ(r)) + { + const TRiga_partite& row = game.riga(r); + const TString& numregcg = row.get(PART_NREG); + const long numreg = atol(anal.decode(numregcg)); + + if (numreg > 0) + { + TAnal_mov anal_mov(numreg); + TRecord_array & rows = anal_mov.body(); + const int nrows = rows.rows(); + TString s; + + for (int i = 1; !print && i <= nrows; i++) + { + const TRectype & row = anal_mov.body().row(i); + TString f = anal_filter.get(0); + f.trim(); + + if (f.full()) + { + s = row.get(RMOVANA_CODCMS); + print |= s.match(f); + } + f = anal_filter.get(); + if (f.full()) + { + s = row.get(RMOVANA_CODCCOSTO); + print |= s.match(f); + } + f = anal_filter.get(); + if (f.full()) + { + s = row.get(RMOVANA_CODFASE); + print |= s.match(f); + } + } + } + } + if (!print) + return 0; + } + if (sel_tot_saldo || (saldo > ZERO && saldo >= sel_importo) || (saldo.is_zero() && !unreferenced.is_zero() && data_rischio < data_limite_scaduto)) + { + const bool printed = form().print_game(game); + one_printed |= printed; + } + } + + partite.put(PART_NRIGA, 9999); + + if (printer().frozen()) + break; + } + if (one_printed) + { + f.ultima_pagina(); + printer().formfeed(); + } + } + return one_printed ? 1 : 0; +} bool TSol_mask::get_sel_tot_saldo() const { @@ -198,6 +458,7 @@ const TToken_string & TSol_mask::get_anal_filter() const f.cut(0); return f; } + /////////////////////////////////////////////////////////// // TSol_row /////////////////////////////////////////////////////////// @@ -220,6 +481,7 @@ TSol_form::TSol_form(const TSol_mask& m, bool gesval, short id_datalim, short id { _sel_tot_saldo = m.get_sel_tot_saldo(); _sel_importo = m.get_sel_importo(); + _stampa_esposto = m.get_bool(F_STAMPESP); } /////////////////////////////////////////////////////////// diff --git a/src/sc/sc2402.h b/src/sc/sc2402.h index 028da8646..1e5dc4681 100755 --- a/src/sc/sc2402.h +++ b/src/sc/sc2402.h @@ -5,23 +5,7 @@ #include "sc2401.h" #endif -class TSol_mask: public TESSL_mask -{ - short _cdc_start, _cdc_end, - _cms_start, _cms_end, - _fas_start, _fas_end; - -protected: - int insert_anal_fields(TMask& m, int page, int lf, int& y, short& dlg, short& dlgd); - -public: - bool get_sel_tot_saldo() const ; - real get_sel_importo() const ; - const TToken_string &get_anal_filter() const; - - TSol_mask(const char *name); - virtual ~TSol_mask(); -}; +class TSol_mask; /////////////////////////////////////////////////////////// // TSol_row @@ -44,12 +28,14 @@ public: class TSol_form : public TESSL_form { - bool _sel_tot_saldo; - real _sel_importo; + bool _sel_tot_saldo; + real _sel_importo; + bool _stampa_esposto; protected: public: + virtual bool stampa_esposto() const override{ return _stampa_esposto; } bool get_sel_tot_saldo() const { return _sel_tot_saldo;} const real& get_sel_importo() const { return _sel_importo; } TSol_form(const TSol_mask& m, bool gesval, short id_datalim, short id_datascad, short id_ggrischio); @@ -66,5 +52,34 @@ public: virtual ~TSol_array() {} }; +class TSol_mask : public TESSL_mask +{ + TMail_mask _sol_mail; + short _cdc_start, + _cdc_end, + _cms_start, + _cms_end, + _fas_start, + _fas_end; + TSol_form * _form; + +protected: + int insert_anal_fields(TMask& m, int page, int lf, int& y, short& dlg, short& dlgd); + const TString& game_key(const TRectype& part) const; // Costruisce chiave univoca per TAssoc_array partite + bool ci_sono_scadenze_aperte(const TPartita& game, const TDate& dal, const TDate& al, const TDate& data_rischio) const; + bool puoi_scartare(const TPartita& game, const TDate& datalim) const; + virtual TMail_mask & mail_mask() override { return _sol_mail; } + +public: + bool get_sel_tot_saldo() const; + real get_sel_importo() const; + virtual const TToken_string & get_anal_filter() const override; + virtual bool some_to_print(const char * tipo, const long codice) override; // c'è qualcosa da stampare + virtual int print_one(const char * tipo, const long codice) override; // stampa l'elemento corrente + virtual TESSL_form & form() override; + + TSol_mask(const char *name); + virtual ~TSol_mask() { safe_delete(_form); }; +}; #endif // __SC2402_H diff --git a/src/sc/sc2600.cpp b/src/sc/sc2600.cpp index 4c9201304..00e06216d 100755 --- a/src/sc/sc2600.cpp +++ b/src/sc/sc2600.cpp @@ -108,8 +108,6 @@ class TProspettoScadenze : public TPrintapp bool _excel; TPRSC_recordset * _recset; - //static TString80 _last_game; - //static bool fil_function(const TRelation *); TString_array _colnames; int _limiti[NUMERO_FASCE]; @@ -136,7 +134,7 @@ public: void compute_unassigned(TPartita& p, const TDate & datalim); void compute_all(TPartita& p); void print_real(TString& dest, const real& num); - void riempi_conti_mastro(const char cf); + void riempi_conti_mastro(const char * cf); void calcola_saldo(); TProspettoScadenze(); }; @@ -292,7 +290,8 @@ void TProspettoScadenze::compute_all(TPartita& p) { TDate data_pag(sum.get_date(PART_DATAPAG)); int tipo_pag = sum.get_int(PART_TIPOPAG); - if (tipo_pag>=2 && tipo_pag<=7 && data_pag.ok()) //Incasso tramite effetto + + if (tipo_pag >= tm_nota_credito && tipo_pag <= tm_pagamento_insoluto && data_pag.ok()) //Incasso tramite effetto { if (prima_riga_pagamento > -1 && prima_riga_pagamento == pp) data_pag = d; // Se e' il primo pagamento(in ordine di data) di questa rata @@ -498,12 +497,12 @@ bool TProspettoScadenze::open_print() reset_files(); reset_print(); printer().footerlen(5); - if (_m->get_who() == 'C') + if (_m->who() == "C") _tipost = clienti; else _tipost = fornitori; - riempi_conti_mastro(_m->get_who()); - if (_m->get_selected_key() == 1) + riempi_conti_mastro(_m->who()); + if (_m->key() == 1) _ordcod = true; else _ordcod = false; @@ -711,12 +710,12 @@ bool TProspettoScadenze::user_destroy() return true; } -void TProspettoScadenze::riempi_conti_mastro(const char cf) +void TProspettoScadenze::riempi_conti_mastro(const char * cf) { _conti_cf.destroy(); TRelation rel = TRelation(LF_PCON); TString80 filtro; - filtro.format("TMCF==\'%c\'", cf); + filtro.format("TMCF==\"%s\"", cf); TCursor cur(&rel, filtro); TToken_string gc(10); for (cur=0; cur.pos() < cur.items(); ++cur) @@ -736,9 +735,18 @@ bool TProspettoScadenze::set_print(int) if (!repeat) { + TDate data = today; + + data.set_end_month(); + if (!_m->get_date(F_DATASCADUTO).ok()) + _m->set(F_DATASCADUTO, data); + KEY k = _m->run(); + _excel = k != K_ENTER; print = k != K_QUIT; + if (print || _excel) + _m->update_assoc(); int nmesi = _m->get_int(F_NMESI); if (nmesi == 0) diff --git a/src/sc/sc2600a.uml b/src/sc/sc2600a.uml index 555f8ecf2..1a0159d63 100755 --- a/src/sc/sc2600a.uml +++ b/src/sc/sc2600a.uml @@ -185,9 +185,9 @@ BEGIN FLAGS "HB" END -NUMBER SC_NSEL 3 +NUMBER SC_NSEL 6 BEGIN - PROMPT 60 13 "N. " + PROMPT 48 13 "Selezionati " FLAGS "D" END diff --git a/src/sc/scselect.cpp b/src/sc/scselect.cpp index 7a76aec15..aec4c7553 100755 --- a/src/sc/scselect.cpp +++ b/src/sc/scselect.cpp @@ -1,9 +1,18 @@ #include #include +#include +#include #include -#include "scselect.h" +#include +#include "scselect.h" +#include "sc2400a.h" +#include "sc2400b.h" +#include "sc21pec.h" #include +#include "../ca/calib01.h" +#include "../ca/movana.h" + static bool sc_filter_handler(TMask_field& f, KEY k) { if (k == K_SPACE) @@ -48,27 +57,1164 @@ static bool sc_ragsoc_handler(TMask_field& f, KEY k) return true; } -TSelection_mask::TSelection_mask(const char* name) - : TMask(name), _who('C'), _key(1), _clifo_rel(NULL), _pdc_rel(NULL), - _cli_cur_k1(NULL), _cli_cur_k2(NULL), _for_cur_k1(NULL), _for_cur_k2(NULL), - _pdc_cur_k1(NULL), _pdc_cur_k2(NULL) +/////////////////////////////////////////////////////////// +// TESSL_row +/////////////////////////////////////////////////////////// + +TESSL_row::TESSL_row(const TRiga_partite& row, const TDate& data, const TImporto& imp, int rata) + : _num_prot(0), _num_reg(0), _salvo_buon_fine(false) { - // crea relazioni, cursori e cursor_sheets - _clifo_rel = new TRelation(LF_CLIFO); - _clifo_rel->add(LF_CFVEN,"TIPOCF==TIPOCF|CODCF==CODCF"); - TString rf = get_user_read_filter(); - - TRectype filter(LF_CLIFO); - filter.put(CLI_TIPOCF, "C"); - _cli_cur_k1 = new TCursor(_clifo_rel, rf, 1, &filter, &filter); - _cli_cur_k2 = new TCursor(_clifo_rel, rf, 2, &filter, &filter); - - _cli_sh_k1 = new TCursor_sheet(_cli_cur_k1, " |CODCF|RAGSOC|PAIV", TR("Selezione cliente per codice"), - "@1|Codice|Ragione Sociale@50",0,1); - _cli_sh_k2 = new TCursor_sheet(_cli_cur_k2, " |RAGSOC|CODCF", "Selezione cliente per ragione sociale", - "@1|Ragione Sociale@50|Codice",0,1); - _cli_sh_k2->add_checkbutton(SC_CLIFO+500, 0, "", 68, 0, 2, 1, "", 10112, 10113).set_handler(sc_filter_handler); - + _riga = row.get_int(PART_NRIGA); + _rata = rata; + + _data = data; + _causale = row.get(PART_CODCAUS); + _data_doc = row.get(PART_DATADOC); + _num_doc = row.get(PART_NUMDOC); + _num_prot = row.get_long(PART_PROTIVA); + _num_reg = row.get_long(PART_NREG); + _importo = imp; _importo.normalize(); + _descrizione = row.get(PART_DESCR); + + _valuta.get(row); + + const bool valuta = form().in_valuta() && _valuta.in_valuta(); + const char* const field = valuta ? PART_IMPTOTVAL : PART_IMPTOTDOC; + + _totale = row.get_real(field); + +} + +TESSL_row::TESSL_row(const char* desc, const TImporto& imp, const TValuta& val) + : _riga(9999), _rata(9999), _num_prot(0), _num_reg(0), _salvo_buon_fine(false) +{ + _descrizione = desc; + _importo = imp; _importo.normalize(); + _valuta = val; +} + +// le righe dell'estratto conto sono ordinate per data, riga partita, numero rata, +// posizione iniziale nell'array (in caso di uguaglianza di tutto il resto) +int TESSL_row::compare(const TSortable& s) const +{ + const TESSL_row& r = (const TESSL_row & )s; + int c = 0; + + if (_data == r._data) + { + c = r._riga - _riga; + if (c == 0) c = _rata - r._rata; + } + else + c = _data < r._data ? -1 : +1; + return c; +} + +// Annulla i campi uguali alla riga precedente +void TESSL_row::reset_uguali() +{ + _num_doc = ""; + _data_doc = botime; + _num_prot = 0; + _totale = ZERO; +} + +void TESSL_row::set_imp(TForm_item& fi, const real& imp, const char* cod_val) const +{ + fi.set(imp.string()); +} + +TESSL_form& TESSL_row::form() const +{ + TESSL_form* f = TESSL_form::_form; + + CHECK(f, "NULL form"); + return *f; +} + +void TESSL_row::print_on(TPrint_section& body) +{ + TESSL_form& form = (TESSL_form&)body.form(); + + const bool show_value = form.in_valuta() && in_valuta(); + const TString& cod_valuta = show_value ? valuta().codice() : EMPTY_STRING; + + TForm_item& campo_valuta = body.find_field(PEC_VALUTA); + campo_valuta.set(cod_valuta); + + TForm_item& causale = body.find_field(PEC_CODCAUS); + causale.set(_causale); + if (_causale.not_empty() && _descrizione.empty()) + { + TDecoder& causali = form.causali(); + _descrizione = causali.decode(_causale); + } + + TForm_item& descr = body.find_field(PEC_DESCR); + + if (num_reg() > 0) // Riga di partita vera e propria (non totale parziale) + { + TString s(80); + + s = descr.prompt(); + + TESSL_form::_form->change_magic_body(*this, s); + + descr.set(s); + } + else + descr.set(_descrizione); + + TForm_item& datadoc = body.find_field(PEC_DATADOC); + + datadoc.set(_data_doc.string()); + + TForm_item& numdoc = body.find_field(PEC_NUMDOC); + + numdoc.set(_num_doc); + + TForm_item& numprot = body.find_field(PEC_PROTIVA); + TString16 protiva; protiva << _num_prot; + + numprot.set(protiva); + + TForm_item& datapag = body.find_field(PEC_DATAPAG); + + datapag.set(_data.string()); + + const real& imp = _importo.valore(); + TForm_item& dare = body.find_field(PEC_DARE); + TForm_item& avere = body.find_field(PEC_AVERE); + + if (_importo.sezione() == 'D') + { + set_imp(dare, imp, cod_valuta); + avere.set(""); + } + else + { + set_imp(avere, imp, cod_valuta); + dare.set(""); + } + + TForm_item& importo_in_euro = body.find_field(PEC_IMPEURO); + + set_imp(importo_in_euro, _importo_euro, ""); // In generale va espresso nella valuta della ditta + + TForm_item& scaduto = body.find_field(PEC_SCADUTO); + + set_imp(scaduto, _scaduto, cod_valuta); + + TForm_item& esposto = body.find_field(PEC_ESPOSTO); + + set_imp(esposto, _esposto, cod_valuta); + esposto.set_prompt(_salvo_buon_fine ? "*" : " "); + + TForm_item& totdoc = body.find_field(PEC_TOTDOC); + + //old_pictures.add(totdoc.picture()); + set_imp(totdoc, _totale, cod_valuta); + + TForm_item& cambio = body.find_field(PEC_CAMBIO); + + cambio.set(_valuta.cambio().string()); + + TForm_item& datacambio = body.find_field(PEC_DATACAM); + datacambio.set(_valuta.data().string()); + + TForm_item& bloccata = body.find_field(PEC_BLOCCATA); + + bloccata.set(_bloccata ? "X" : ""); + + TForm_item& analitica = body.find_field(PEC_ANALITICA); + + analitica.set(_codici_analitica); + + TParagraph_string p(_codici_analitica, analitica.width()); + const int h = analitica.height(); + int i = 0; + + for (i = 0; p.get() != nullptr && i < h; i++); + analitica.section().set_height(p.empty() ? 1 : i); + + const TString old_prompt(descr.prompt()); + + descr.set_prompt(""); // Nasconde temporaneamente il prompt per non stampare i + + body.update(); // crea la vera riga di stampa + + esposto.set_prompt(" "); + descr.set_prompt(old_prompt); // Ripristina il vecchio prompt +// dare.set_picture(old_pictures.row(0)); +// avere.set_picture(old_pictures.row(1)); +// scaduto.set_picture(old_pictures.row(2)); +// esposto.set_picture(old_pictures.row(3)); +// totdoc.set_picture(old_pictures.row(4)); +} + +static int val_compare(const void* o1, const void* o2) +{ + const THash_object* h1 = (const THash_object*)o1; + const THash_object* h2 = (const THash_object*)o2; + const TString& s1 = (const TString&)h1->obj(); + const TString& s2 = (const TString&)h2->obj(); + + return s2.compare(s1, -1, true); // same as stricmp(s1, s2) in reverse order +} + + +/////////////////////////////////////////////////////////// +// TESSL_array +/////////////////////////////////////////////////////////// + +TPartita* TESSL_array::_sort_game = nullptr; + +// Calcola l'importo su di una riga di pagamento +TImporto TESSL_array::importo(const TPartita& game, const TRectype& pag, bool valuta) const +{ + const int nriga = pag.get_int(PAGSCA_NRIGA); + const TRiga_partite& fat = game.riga(nriga); // Riga di fattura + const bool fat_val = fat.in_valuta(); + const int nrigp = pag.get_int(PAGSCA_NRIGP); + const TRiga_partite& sum = game.riga(nrigp); // Riga di pagamento + const char sez = sum.sezione(); + const char* const field = valuta && fat_val ? PAGSCA_IMPORTOVAL : PAGSCA_IMPORTO; + TImporto imp(sez, pag.get_real(field)); // Importo base + + if (!fat_val) + { + imp.valore() += pag.get_real(PAGSCA_RITENUTE); // Sommo le ritenute se sono in lire + const TImporto ritsoc(sum.sezione_ritsoc(), pag.get_real(PAGSCA_RITSOC)); + + imp += ritsoc; + } + + if (pag.get_char(PAGSCA_ACCSAL) == 'S') // Se il pagamento ha abbuoni o differenze cambio + { + real abb(pag.get(PAGSCA_ABBUONI)); + + if (!valuta && fat_val) // Se voglio gli abbuoni in lire ma la fattura non lo e' + { + const TValuta val(sum); // Leggo il cambio dalla riga di partita + val.val2eur(abb); // Converto in lire gli abbuoni + abb += pag.get_real(PAGSCA_DIFFCAM); // Sommo l'eventuale differenza cambio (gia' in lire) + } + imp.valore() += abb; // Sommo il tutto all'importo base (sez e' uguale per tutti i valori) + } + return imp; +} + +// Certified 100% +TImporto& TESSL_array::importo_riga_scaduto(int n) +{ + CHECKD(n > 0 && n < 9999, "Riga scaduto errata ", n); + + TImporto* imp = importo_riga_scaduto_ptr(n); + + if (imp == nullptr) + { + imp = new TImporto; + _scaduto.add(imp, n); + } + return *imp; +} + +// Ordina i pagamenti in ordine di DATAPAG +int TESSL_array::ordina_pag(const void* pag1, const void* pag2) +{ + const int r1 = (*(TRectype**)pag1)->get_int(PAGSCA_NRIGP); + const TDate d1 = _sort_game->riga(r1).get(PART_DATAPAG); + const int r2 = (*(TRectype**)pag2)->get_int(PAGSCA_NRIGP); + const TDate d2 = _sort_game->riga(r2).get(PART_DATAPAG); + const int diff = d1 == d2 ? 0 : (d1 > d2 ? +1 : -1); + + return diff; +} + +real TESSL_array::calcola_scaduto(const TRiga_scadenze& rata, bool valuta) +{ + const TPartita& game = rata.partita(); + const char sezione = game.conto().tipo() == 'C' ? 'D' : 'A'; + TImporto scaduto_rata = rata.importo(valuta); + int riga_corrente_scaduto = 0; + const int numpag = rata.rows(); // Numero totale di pagamenti sulla rata + TRectype** arrpag = nullptr; // Array di puntatori ai pagamenti + + if (numpag > 0) + { + arrpag = new TRectype*[numpag]; + + int i = 0; + + for (int p = rata.last(); p > 0; p = rata.pred(p)) + arrpag[i++] = (TRectype*)&rata.row(p); // Copia puntatori ai pagamenti nell'array + _sort_game = (TPartita*)&game; // Inizializza partita di appoggio al sort + qsort(arrpag, numpag, sizeof(TRectype*), ordina_pag); + } + + for (int i = 0; i < numpag; i++) + { + const TRectype& pag = *arrpag[i]; + const int nrigp = pag.get_int(PAGSCA_NRIGP); + const TRiga_partite& sum = game.riga(nrigp); + TImporto imp = importo(game, pag, valuta); + + tipo_movimento tm = sum.tipo(); // Determina tipo riga + + // Normalmente gli utenti non usano il tipo pagamento insoluto, per cui devo + // riconoscere i pagamenti che in realta' sono a fronte di insoluti: + // 1) hanno tipo movimento = tm_pagamento + // 2) ho gia' incontrato un insoluto + // 3) il saldo della rata e' a zero o sommando l'importo arriva sotto zero + if (tm == tm_pagamento && riga_corrente_scaduto != 0) + { + if (scaduto_rata.is_zero()) + { + tm = tm_pagamento_insoluto; + } + else + { + TImporto p(scaduto_rata); + p += imp; + p.normalize(sezione); + + if (p.valore() < ZERO) + { + scaduto_rata.set('D', ZERO); + imp += p; + tm = tm_pagamento_insoluto; + } + } + } + if (tm == tm_insoluto || tm == tm_pagamento_insoluto) + { + if (tm == tm_insoluto) + riga_corrente_scaduto = nrigp; + else + CHECKD(riga_corrente_scaduto > 0, "Pagamento insoluto senza insoluto ", nrigp); + importo_riga_scaduto(riga_corrente_scaduto) += imp; + } + else + { + scaduto_rata += imp; + } + } + + if (arrpag != nullptr) + delete arrpag; + + scaduto_rata.normalize(sezione); + return scaduto_rata.valore(); +} + +TESSL_row& TESSL_array::new_row(const TRiga_partite& row, const TDate& data, const TImporto& imp, int n) +{ + CHECKD(n > 0, "Numero rata errato: ", n); + + TESSL_row* riga = new TESSL_row(row, data, imp, n); + + add(riga); + return *riga; +} + +void TESSL_array::add_row(const TRiga_partite& row) +{ + const bool in_valuta = form().in_valuta() && row.in_valuta(); + real importo_in_lire; + const char sezione = form().sezione_normale(); + const TDate data_op = row.get(PART_DATAREG); + + if (data_op <= form().data_limite_operazione()) + { + TString codanal; + + if (main_app().has_module(CAAUT, CHK_DONGLE)) + { + const TString& numregcg = row.get(PART_NREG); + const long numreg = atol(_anal.decode(numregcg)); + + if (numreg > 0) + { + TAnal_mov anal_mov(numreg); + TRecord_array & rows = anal_mov.body(); + const int nrows = rows.rows(); + + for (int i = 1; i <= nrows; i++) + { + const TString80 s = anal_mov.row_code(i); + + if (s.full() && codanal.find(s) < 0) + { + if (codanal.full()) + codanal << '\n'; + if (s.full()) + codanal << s; + } + } + } + } + if (row.is_fattura()) + { + for (int r = 1; r <= row.rate(); r++) + { + const TRiga_scadenze& rata = row.rata(r); + const TDate data_scad = rata.get(SCAD_DATASCAD); + TESSL_row& rec = new_row(row, data_scad, rata.importo(in_valuta), r); + + if (in_valuta) + { + TImporto il(rata.importo(false)); + + il.normalize(sezione); + rec.importo_in_euro(il.valore()); + } + if (data_scad <= form().data_limite_scaduto()) + { + const real s = calcola_scaduto(rata, in_valuta); + rec.scaduto(s); + } + rec.rata_bloccata(rata.get_bool(SCAD_BLOCCATA)); + rec.codici_analitica(codanal); + } + } + else + { + const TDate data_pag(row.get(PART_DATAPAG)); + const TImporto imp(row.importo(in_valuta, 0x1)); // Importo pulito senza nient'altro + TESSL_row& riga = new_row(row, data_pag, imp, RIGA_PAGAMENTO); + + if (in_valuta) + { + TImporto i(row.importo(false, 0x1)); + i.normalize(sezione); + riga.importo_in_euro(i.valore()); + } + riga.codici_analitica(codanal); + + const int tipo_pag = row.get_int(PART_TIPOPAG); + const tipo_movimento tipo_mov = row.tipo(); + + // Controlla se e' un pagamento con effetti + if ((tipo_mov == tm_pagamento || tipo_mov == tm_pagamento_insoluto) && + (tipo_pag >= 2 && tipo_pag <= 7)) + { + const TDate& dls = form().data_limite_scaduto(); + const int gr = form().giorni_rischio(); + const TDate& dir = form().data_inizio_rischio(); + bool sbf = false; + TImporto esposto(row.esposto(in_valuta, dls, dir, sbf)); + bool esp = !esposto.is_zero(); + + if (esp) + { + esposto.normalize(sezione); + riga.salvo_buon_fine(sbf); // Esposto salvo buon fine + riga.esposto(esposto.valore()); + } + } + + TImporto ritenute(row.importo(false, 0x8)); + + if (!ritenute.is_zero()) + { + TESSL_row& r = new_row(row, data_pag, TImporto('D', ZERO), RIGA_RITENUTE); + + r.descrizione(form().describe(PEC_RITENUTE)); + if (in_valuta) + { + ritenute.normalize(sezione); + r.importo_in_euro(ritenute.valore()); + } + else + r.importo(ritenute); + r.codici_analitica(codanal); + } + + const TImporto abbuoni(row.importo(in_valuta, 0x2)); + + if (!abbuoni.is_zero()) + { + TESSL_row& r = new_row(row, data_pag, abbuoni, RIGA_ABBUONI); + + r.descrizione(form().describe(PEC_ABBUONI)); + if (in_valuta) + { + TImporto il(row.importo(false, 0x2)); + + il.normalize(sezione == 'D' ? 'A' : 'D'); + r.importo_in_euro(il.valore()); + } + r.codici_analitica(codanal); + } + + TImporto diffcam(row.importo(false, 0x4)); + + if (!diffcam.is_zero() && !in_valuta) + { + TESSL_row& r = new_row(row, data_pag, TImporto('D', ZERO), RIGA_DIFFCAMBI); + + r.descrizione(form().describe(PEC_DIFFCAM)); + r.importo(diffcam); + r.codici_analitica(codanal); + } + } + } +} + +void TESSL_array::arrange_scaduto(const TPartita& game) + +{ + const bool in_valuta = form().in_valuta() && row(0).in_valuta(); + TImporto totpag(game.importo_pagato_unassigned(in_valuta)); + const char sezione = game.conto().tipo() == 'C' ? 'D' : 'A'; + + totpag.normalize(sezione); + + int r; + + for (r = items() - 1; r >= 0; r--) + { + TESSL_row& s = row(r); + real imp(s.scaduto()); + + if (imp.sign() < 0) + { + totpag += TImporto(sezione, imp); + s.scaduto(ZERO); + } + } + for (r = 0; r < items() && totpag.valore() >= ZERO; r++) + { + TESSL_row& s = row(r); + real imp = s.scaduto(); + + if (imp.sign() > 0) + { + if (imp >= totpag.valore()) + { + imp -= totpag.valore(); + s.scaduto(imp); + totpag = TImporto(sezione, ZERO); + } + else + { + s.scaduto(ZERO); + totpag -= TImporto(sezione, imp); + } + } + } +} + +TESSL_array::TESSL_array(const TPartita& game, const TESSL_form* f) + :_form(f), _anal(LF_MOVANA, MOVANA_NUMREG, 3) +{ + int r; + + for (r = game.last(); r > 0; r = game.pred(r)) + add_row(game.riga(r)); + + const char sezione = f->sezione_normale(); + + for (r = items() - 1; r >= 0; r--) + { + TESSL_row& s = row(r); + + if (s.rata() == RIGA_PAGAMENTO) + { + TImporto* imp = importo_riga_scaduto_ptr(s.riga()); + + if (imp != nullptr) + { + imp->normalize(sezione); + s.scaduto(imp->valore()); + } + } + } + if (items() > 0) + { + sort(); + arrange_scaduto(game); + } +} + +/////////////////////////////////////////////////////////// +// TESSL_form: form speciale per estratti conto e solleciti +/////////////////////////////////////////////////////////// + +TESSL_form * TESSL_form::_form = nullptr; + +void TESSL_form::stampa_testata(TPrinter& pr) +{ + TPrint_section& head = section('H'); + TForm_item& pagina = head.find_field(PEC_PAGINA); + TString16 pg; pg << int(pr.getcurrentpage()); + + pagina.set(pg); + head.update(); + + const word r = head.height() - 1; + + for (word j = 0; j <= r; j++) + pr.setheaderline(j, head.row(j)); +} + +static int tot_compare(const void* o1, const void* o2) +{ + if (o1 == o2) // Sfrutto una piccola debolezza di qsort: + return 0; // ogni tanto confronta oggetti con se stessi + + const THash_object* h1 = *((const THash_object**)o1); + const THash_object* h2 = *((const THash_object**)o2); + + return h1->key().compare(h2->key(), -1, true); // was stricmp +} + +word TESSL_form::ordina_totali_per_valuta(THash_object* tot[MAXTOT]) +{ + // I totali sono in un assoc array disordinato per cui li copio in un array e li ordino + // alfabeticamente in base al loro codice valuta + TTotalizer& arr = totali(); + + arr.restart(); + + word num_rip = 0; + + for (THash_object* obj = arr.get_hashobj(); + num_rip < MAXTOT && obj != nullptr; + obj = arr.get_hashobj()) + tot[num_rip++] = obj; + qsort(tot, num_rip, sizeof(THash_object*), tot_compare); + return num_rip; +} + +void TESSL_form::stampa_riporti(TPrinter& pr) +{ + THash_object* tot[MAXTOT]; + + _num_rip = ordina_totali_per_valuta(tot); + if (_num_rip > _maxtot) + _num_rip = _maxtot; + + const TString& riporto = describe(PEC_RIPORTO); + TString desc(80); + TPrint_section& body = section('B'); + + for (word j = 0; j < _num_rip; j++) + { + const TString& key = tot[j]->key(); + TTotal& t = (TTotal&)(tot[j]->obj()); + + desc = riporto; + + TValuta val; + + if (key.not_empty()) + { + desc << ' ' << key; + + TValuta val1(key, botime, ZERO); // E' una valuta fittizia, giusto per far + + val = val1; // eseguire in set_imp() i calcoli per i decimali. + } + TESSL_row rip(desc, t.importo().normalize(), val); + + rip.scaduto(t.scaduto()); + rip.esposto(t.esposto()); + rip.importo_in_euro(t.importo_euro()); + rip.print_on(body); + pr.setfooterline(j + 1, body.row(0)); + } +} + +int TESSL_form::find_magic(TString& s, TString& magic1, TString& magic2) const +{ + const int pos = s.find('<', 0); + int end; + + if (pos >= 0) + { + end = s.find('>', pos); + if (end > pos) + { + int p1 = pos + 1; + magic1 = s.smid(p1, 2); + while (isalnum(s[p1])) p1++; + while (p1 < end && !isalnum(s[p1])) p1++; + if (p1 < end) + magic2 = s.smid(p1, 2); + else + magic2.cut(0); + } + else + end = s.len() - 1; + + const TString right(s.smid(end + 1)); + + s.cut(pos); s << right; + } + return pos; +} + +void TESSL_form::change_magic_body(const TESSL_row& row, TString& s) +{ + TString magic1(4), magic2(4), val(50); + int pos; + + while ((pos = find_magic(s, magic1, magic2)) >= 0) + { + val.cut(0); + if (magic1 == "PA" || magic2 == "PA") + { + val = row.descrizione(); + if (val.empty()) + val = causali().decode(row.causale()); + } + if (magic1 == "MO" || magic2 == "MO") + { + val = movimenti().decode(row.num_reg()); + } + s.insert(val, pos); + } +} + +void TESSL_form::change_magic_footer(const THash_object& o, TString& s) +{ + TString magic1(4), magic2(4), val(50); + int pos; + + while ((pos = find_magic(s, magic1, magic2)) >= 0) + { + val.cut(0); + if (magic1 == "DA") + { + const TDate& d = magic2 == "SC" ? _dls : _dlo; + + if (d != eotime) + val = d.string(); + } + if (magic1 == "VA") + val = o.key(); + if (magic1 == "DE") + val = valute().decode(o.key()); + s.insert(val, pos); + } +} + +void TESSL_form::print_total(int riga, const THash_object& o) +{ + const short MAXID = 5; + const short f_id[MAXID] = { PEC_TSALDO, PEC_TSCADUTO, PEC_TESPOSTO, PEC_TIMPEURO, PEC_TUNASSIGNED }; + TString_array prompt(MAXID); + TPrint_section& foot = section('F'); + TPrint_section& body = section('B'); + TForm_item& bdesc = body.find_field(PEC_DESCR); + // Sostituisce magic-names nei prompt + TString s(80); + int i; + + for (i = 0; i < MAXID; i++) + { + TForm_item& desc_field = foot.find_field(f_id[i]); + + if (desc_field.shown()) + { + s = desc_field.prompt(); + prompt.add(s, i); + change_magic_footer(o, s); + desc_field.set_prompt(s); + if (desc_field.x() <= 0) + desc_field.set_x(bdesc.x()); + } + } + + const TTotal& t = (const TTotal&)o.obj(); + const TImporto& imp = t.importo(); + const bool in_valuta = o.key().not_empty(); + TForm_item& dare = foot.find_field(PEC_DARE); + TForm_item& avere = foot.find_field(PEC_AVERE); + TString_array old_pictures;//pictures da rippristinare dopo aver stampato + + if (dare.x() <= 0 || avere.x() <= 0) + { + TForm_item& bdare = body.find_field(PEC_DARE); + + dare.set_x(bdare.x()); + dare.width() = bdare.width(); + + TForm_item& bavere = body.find_field(PEC_AVERE); + + avere.set_x(bavere.x()); + avere.width() = bavere.width(); + } + //modify_picture(dare,old_pictures,in_valuta); + //modify_picture(avere,old_pictures,in_valuta); + char sez = imp.sezione(); + real num = imp.valore(); + + if (sez == 'D' && num < 0) + { + num = abs(num); sez = 'A'; + } + if (sez == 'A' && num < 0) + { + num = abs(num); sez = 'D'; + } + if (sez == 'D') + { + dare.set(num.string()); + avere.set(""); + } + else + { + dare.set(""); + avere.set(num.string()); + } + + TForm_item& scaduto = foot.find_field(PEC_SCADUTO); + + if (scaduto.x() <= 0) + { + TForm_item& bscaduto = body.find_field(PEC_SCADUTO); + + scaduto.set_x(bscaduto.x()); + scaduto.width() = bscaduto.width(); + } + //modify_picture(scaduto,old_pictures,in_valuta); + scaduto.set(t.scaduto().string()); + + TForm_item& esposto = foot.find_field(PEC_ESPOSTO); + + if (esposto.x() <= 0) + { + TForm_item& besposto = body.find_field(PEC_ESPOSTO); + + esposto.set_x(besposto.x()); + esposto.width() = besposto.width(); + } + //modify_picture(esposto,old_pictures,in_valuta); + esposto.set(t.esposto().string()); + + TForm_item& implire = foot.find_field(PEC_IMPEURO); + + if (implire.x() <= 0) + { + TForm_item& bimplire = body.find_field(PEC_IMPEURO); + implire.set_x(bimplire.x()); + implire.width() = bimplire.width(); + if (bimplire.shown()) implire.show(); + else implire.hide(); + } + //modify_picture(implire,old_pictures,false); + implire.set(t.importo_euro().string()); + + TForm_item& unreferenced = foot.find_field(PEC_UNASSIGNED); + + if (unreferenced.x() <= 0) + { + TForm_item& uns = body.find_field(PEC_AVERE); + + unreferenced.set_x(uns.x()); + unreferenced.width() = avere.width(); + } + //modify_picture(unreferenced,old_pictures,in_valuta); + unreferenced.set(t.unassigned().valore().string()); + + foot.update(); + + // Ripristina prompt originari + for (i = 0; i < MAXID; i++) + { + const TString* p = (const TString*)prompt.objptr(i); + + if (p) + { + TForm_item& desc_field = foot.find_field(f_id[i]); + + desc_field.set_prompt(*p); + } + } + for (word r = 0; r < _total_rows; r++) + printer().setfooterline(riga + r, foot.row(r)); +} + +void TESSL_form::stampa_pedata(TPrinter& pr) +{ + THash_object* tot[MAXTOT]; + word num_rip = ordina_totali_per_valuta(tot); + // La prima riga del footer deve essere lasciata libera per la fincatura + // Ogni sottosezione di totale occupa _total_rows righe: per cui devo calcolare + // quanti totali ci stanno nelle righe riservate al footer +// const word maxtot = (section('F').height()-1) / _total_rows; + + if (num_rip > _maxtot) + num_rip = _maxtot; + for (word j = 0; j < num_rip; j++) + print_total(j*_total_rows + 1, *tot[j]); +} + +void TESSL_form::ultima_pagina() +{ + set_last_page(true); +} + +void TESSL_form::header_handler(TPrinter& pr) +{ + pr.resetheader(); + + _form->stampa_testata(pr); +} + +void TESSL_form::footer_handler(TPrinter& pr) +{ + pr.resetfooter(); + if (_form->page(pr) > 0) // Normal page + _form->stampa_riporti(pr); + else // Last page + _form->stampa_pedata(pr); +} + +void TESSL_form::azzera_totali() +{ + totali().destroy(); // Azzera tutti i riporti + _num_rip = 0; // Azzera il numero di righe di riporto + set_last_page(false); // Azzera il flag di ultima pagina di stampa + + TPrint_section& foot = section('F'); + + printer().footerlen(foot.height()); + printer().setcurrentpage(1); +} + +bool TESSL_form::print_game(const TPartita& game) +{ + bool ok = false; + + TESSL_array righe(game, this); + TPrinter& pr = printer(); + TPrintrow prow; + TPrint_section& body = section('B'); + TImporto saldo; + real scaduto, esposto, impeuro; + // Stampa le righe di partita + int ultima_riga = 0; + int ultima_rata = 0; + int r; + + for (r = 0; r < righe.items(); r++) + { + TESSL_row& riga = righe.row(r); + + if (pr.rows_left() <= (body.height() + 1)) + { + pr.formfeed(); + for (word nr = 0; nr < _num_rip; nr++) + { + TPrintrow* fl = pr.getfooterline(nr + 1); + + CHECKD(fl, "Manca la riga di riporto ", nr + 1); + pr.print(*fl); + } + } + + const int ri = riga.riga(); + const int ra = riga.rata(); + + if (ri == ultima_riga && ra == ultima_rata + 1) + riga.reset_uguali(); + ultima_riga = ri; + ultima_rata = ra; + + real resp = riga.esposto(); + + if (resp < ZERO) + { + resp = -resp; + riga.esposto(resp); + } + + riga.print_on(body); + pr.print(body.row(0)); + totali().add(riga.importo(), riga.scaduto(), riga.esposto(), + riga.importo_in_euro(), riga.valuta().codice()); + saldo += riga.importo(); + scaduto += riga.scaduto(); + esposto += riga.esposto(); + impeuro += riga.importo_in_euro(); + ok = true; + } + if (ok) + { + if (_stampa_saldo) + { + saldo.normalize(); + + TString desc; + + desc = describe(PEC_SALDO); + + const TValuta& val = righe.row(r - 1).valuta(); + + if (val.in_valuta()) + desc << ' ' << val.codice(); + + TESSL_row sld(desc, saldo, val); + + sld.scaduto(scaduto); + sld.esposto(esposto); + sld.importo_in_euro(impeuro); + sld.print_on(body); + pr.print(body.row(0)); + } + + // Salta una riga vuota + TPrintrow vuota; + + pr.print(vuota); + } + return ok; +} + +const TString& TESSL_form::describe(short id, char sez, pagetype pt) const +{ + const TForm_item& fi = find_field(sez, pt, id); + + return fi.prompt(); +} + +void TESSL_form::init_header(const TMask& m) +{ + TPrint_section& head = section('H'); + + TForm_item& luogo_invio = head.find_field(PEC_LUOGOIN); + luogo_invio.set(m.get(F_LUOGOSEND)); + + TForm_item& data_invio = head.find_field(PEC_DATAIN); + data_invio.set(m.get(F_DATASEND)); + + TForm_item& fi = head.find_field(PEC_MEMO); + if (fi.shown()) + { + TString key; + + key.format("%s|%s|H0|%d", (const char *)name(), (const char *)code(), PEC_MEMO); + + const TRectype & rform = cache().get(LF_RFORM, key); + if (!rform.empty()) + fi.set(rform.get("TESTO")); + } + +} + +TESSL_form::TESSL_form(const TSelection_mask & m, bool gesval, short id_datalim, short id_datascad, + short id_giorni_rischio) + : TForm(BASE_EC_PROFILE, m.get_prof_name()), _in_valuta(false), _num_rip(0), + _total_rows(0), _causali(LF_CAUSALI, CAU_DESCR), _movimenti(LF_MOV, MOV_DESCR), + _valute("%VAL"), _giorni_rischio(0), _maxtot(1), _stampa_saldo(true) +{ + _form = this; + _lingua = m.get_prof_lang(); + _who = m.who(); + _stampa_esp = stampa_esposto(); + + TCursor_sheet& cs = m.cur_sheet(); + + _cursore = cs.cursor(); + _dlo = id_datalim > 0 ? m.get_date(id_datalim) : eotime; + if (!_dlo.ok()) + _dlo = eotime; + _dls = id_datascad > 0 ? m.get_date(id_datascad) : eotime; + if (!_dls.ok()) + _dls = eotime; + if (id_giorni_rischio > 0) + _giorni_rischio = m.get_int(id_giorni_rischio); + _dir = _dls; _dir -= _giorni_rischio; + + TPrinter& pr = printer(); + + pr.setheaderhandler(header_handler); + + TPrint_section& head = section('H'); + + pr.headerlen(head.height()); + + TForm_item& flags = find_field('H', last_page, PEC_FLAGS); + TToken_string f(flags.prompt()); + + _in_valuta = gesval && f.get_char(0) == 'X'; // Il profilo e' in valuta se c'e' il flag di valuta + _fincatura = f.get_int(1); + + TForm_item& esp = section('B').find_field(PEC_ESPOSTO); + + if (esp.shown()) esp.show(_stampa_esp); //setta la colonna esposto solo se abilitata + genera_intestazioni(odd_page, head.height() - 1); + init_header(m); // Set fixed text + pr.setfooterhandler(footer_handler); + + const TPrint_section& foot = section('F'); + + pr.footerlen(foot.height()); + _total_rows = 1; + for (word fi = 0; fi < foot.fields(); fi++) + { + const TForm_item& item = foot.field(fi); + + if (item.shown()) + { + const word y = (word)item.y(); + + if (y > _total_rows) + _total_rows = y; + } + } + _maxtot = f.get_int(3); + if (_maxtot <= 0 || _maxtot > ((int)foot.height() - 2) / _total_rows) + _maxtot = (foot.height() - 2) / _total_rows; + + int rows[] = { (int)head.height(), (int)(pr.formlen() - foot.height() + 1), 0 }; + TPrint_section& fink = section('G'); + + if (_fincatura) + { + set_fink_mode(_fincatura == 1 ? false : true); + genera_fincatura(odd_page, rows[0] - 2, rows[1] + (_maxtot * _total_rows) + 2, rows); + } + if (fink.fields() > 0) + fink.update(); // Setta il backgroud di stampa +} + +TESSL_form::~TESSL_form() +{ + TPrinter& pr = printer(); + + pr.setheaderhandler(nullptr); + pr.setfooterhandler(nullptr); + _form = nullptr; +} + +TSelection_mask::TSelection_mask(const char* name) + : TAutomask(name), _who("C"), _key(1), _clifo_rel(nullptr), _pdc_rel(nullptr), + _cli_cur_k1(nullptr), _cli_cur_k2(nullptr), _for_cur_k1(nullptr), _for_cur_k2(nullptr), + _pdc_cur_k1(nullptr), _pdc_cur_k2(nullptr), _cli_sh_k1(nullptr), _cli_sh_k2(nullptr), + _for_sh_k1(nullptr), _for_sh_k2(nullptr), _pdc_sh_k1(nullptr), _pdc_sh_k2(nullptr) + +{ + // crea relazioni, cursori e cursor_sheets + _clifo_rel = new TRelation(LF_CLIFO); + _clifo_rel->add(LF_CFVEN, "TIPOCF==TIPOCF|CODCF==CODCF"); + TString rf = get_user_read_filter(); + + TRectype filter(LF_CLIFO); + + filter.put(CLI_TIPOCF, "C"); + _cli_cur_k1 = new TCursor(_clifo_rel, rf, 1, &filter, &filter); + _cli_cur_k2 = new TCursor(_clifo_rel, rf, 2, &filter, &filter); + + _cli_sh_k1 = new TCursor_sheet(_cli_cur_k1, " |CODCF|RAGSOC|PAIV", TR("Selezione cliente per codice"), + "@1|Codice|Ragione Sociale@50", 0, 1); + _cli_sh_k2 = new TCursor_sheet(_cli_cur_k2, " |RAGSOC|CODCF", "Selezione cliente per ragione sociale", + "@1|Ragione Sociale@50|Codice", 0, 1); + _cli_sh_k2->add_checkbutton(SC_CLIFO + 500, 0, "", 68, 0, 2, 1, "", 10112, 10113).set_handler(sc_filter_handler); + if (id2pos(SC_CLIFO) >= 0) { filter.put(CLI_TIPOCF, "F"); @@ -81,15 +1227,7 @@ TSelection_mask::TSelection_mask(const char* name) _for_sh_k2->add_string(SC_CLIFO, 0, PR("Ragione sociale "), 1, 0, 50, "").set_handler(sc_ragsoc_handler); _for_sh_k2->add_checkbutton(SC_CLIFO+500, 0, "", 68, 0, 2, 1, "", 10112, 10113).set_handler(sc_filter_handler); } - else - { - _for_cur_k1 = NULL; - _for_cur_k2 = NULL; - _for_sh_k1 = NULL; - _for_sh_k2 = NULL; - } - - if (id2pos(SC_CLIFO) >= 0 && TToken_string(lfield(SC_CLIFO).get_codes()).items()>2) + if (id2pos(SC_CLIFO) >= 0 && TToken_string(lfield(SC_CLIFO).get_codes()).items() > 2) { _pdc_rel = new TRelation(LF_PCON); TRectype& filter = _pdc_rel->curr(); @@ -102,75 +1240,63 @@ TSelection_mask::TSelection_mask(const char* name) _pdc_sh_k2->add_string(SC_CLIFO, 0, PR("Descrizione "), 1, 0, 50, "").set_handler(sc_ragsoc_handler); _pdc_sh_k2->add_checkbutton(SC_CLIFO+500, 0, "", 68, 0, 2, 1, "", 10112, 10113).set_handler(sc_filter_handler); } - else - { - _pdc_rel = NULL; - _pdc_cur_k1 = NULL; - _pdc_cur_k2 = NULL; - _pdc_sh_k1 = NULL; - _pdc_sh_k2 = NULL; - } - - set_handler(SC_CLIFO, rclifo_handler); - set_handler(SC_SORTCF, rsortcf_handler); - set_handler(SC_SELECT, bselect_handler); - set_handler(SC_RESET, breset_handler); - set_handler(SC_CFCODFR, ffrom_handler); - set_handler(SC_CFCODTO, fto_handler); - set_handler(SC_CFDESFR, fdfrom_handler); - set_handler(SC_CFDESTO, fdto_handler); } TSelection_mask::~TSelection_mask() { - if (_pdc_sh_k1 != NULL) - { - delete _pdc_sh_k2; - delete _pdc_sh_k1; - delete _pdc_cur_k2; - delete _pdc_cur_k1; - delete _pdc_rel; - } - - if (_for_sh_k1 != NULL) - { - delete _for_sh_k2; - delete _for_sh_k1; - delete _for_cur_k2; - delete _for_cur_k1; - } - - delete _cli_sh_k2; - delete _cli_sh_k1; - delete _cli_cur_k2; - delete _cli_cur_k1; - - delete _clifo_rel; + safe_delete(_pdc_sh_k2); + safe_delete(_pdc_sh_k1); + safe_delete(_pdc_cur_k2); + safe_delete(_pdc_cur_k1); + safe_delete(_pdc_rel); + safe_delete(_for_sh_k2); + safe_delete(_for_sh_k1); + safe_delete(_for_cur_k2); + safe_delete(_cli_sh_k2); + safe_delete(_cli_sh_k1); + safe_delete(_cli_cur_k2); + safe_delete(_cli_cur_k1); + safe_delete(_clifo_rel); } -bool TSelection_mask::stop_run(KEY k) -{ - const bool ok = TMask::stop_run(k); - if (ok && k != K_QUIT) - update_assoc(); - return ok; +bool TSelection_mask::stampa_saldo() const +{ + return get_bool(F_STAMPSALDO); } -void TSelection_mask::set_handler(short fld_id, CONTROL_HANDLER handler) -{ - const int pos = id2pos(fld_id); - if (pos >= 0) - fld(pos).set_handler(handler); +const TString& TSelection_mask::get_prof_lang() const +{ + return get(F_LINPROF); +} + +const TString & TSelection_mask::get_prof_base() const +{ + return get_tmp_string() = BASE_EC_PROFILE; +} + +const TString& TSelection_mask::get_prof_code() const +{ + return get(F_CODPROF); +} + +const TString & TSelection_mask::get_prof_name() const +{ + TString& tmp = get_tmp_string(); + + tmp = get_prof_code(); + tmp << get_prof_lang(); + return tmp; } TCursor_sheet& TSelection_mask::cur_sheet() const { - TCursor_sheet* cs = NULL; - switch (get_who()) + TCursor_sheet* cs = nullptr; + + switch (who()[0]) { - case 'C': cs = get_selected_key() == 1 ? _cli_sh_k1 : _cli_sh_k2; break; - case 'F': cs = get_selected_key() == 1 ? _for_sh_k1 : _for_sh_k2; break; - default : cs = get_selected_key() == 1 ? _pdc_sh_k1 : _pdc_sh_k2; break; + case 'C': cs = key() == 1 ? _cli_sh_k1 : _cli_sh_k2; break; + case 'F': cs = key() == 1 ? _for_sh_k1 : _for_sh_k2; break; + default : cs = key() == 1 ? _pdc_sh_k1 : _pdc_sh_k2; break; } CHECK(cs, "Can't use a NULL TCursor_sheet"); return *cs; @@ -197,6 +1323,66 @@ void TSelection_mask::reset_sheets() reset(SC_NSEL); } +bool TMail_mask::on_key(KEY k) +{ + if (k == K_SHIFT + K_F12) + show(F_TESTEMAIL); + return TAutomask::on_key(k); +} + +int sort(TSheet_field & s, int r1, int r2) +{ + int key = s.mask().get_int(F_SORT); + int res = 0; + + if (key == 1) + { + int cod1 = s.get_long_row_cell(r1, S_CODCF); + int cod2 = s.get_long_row_cell(r2, S_CODCF); + + res = cod1 - cod2; + } + else + { + const TString & rag1 = s.get_str_row_cell(r1, S_RAGSOC); + const TString & rag2 = s.get_str_row_cell(r2, S_RAGSOC); + + res = _stricmp(rag1, rag2); + } + return res; +} + +bool TMail_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) +{ + switch (o.dlg()) + { + case F_SORT: + if (e == fe_modify) + { + TSheet_field & sh = sfield(F_SHEET); + + sh.sort(sort); + sh.force_update(); + } + break; + case F_SHEET: + if (e == se_leave) + { + TSheet_field & sh = (TSheet_field &) o; + const int row = jolly; + TString email = sh.get_str_row_cell(row, S_EMAIL); + const bool on = email.full(); + + sh.enable_cell(row, S_SELECTED, on); + sh.set_row_cell(S_SELECTED, on, row); + sh.force_update(row); + } + break; + default: + break; + } + return true; +} // Seleziona tutti i clienti con codice compreso tra due estremi void TSelection_mask::select_clifo_range(long from, long to) @@ -204,11 +1390,11 @@ void TSelection_mask::select_clifo_range(long from, long to) TWait_cursor hourglass; TCursor_sheet& c = cur_sheet(); const long items = c.items(); - const int key = get_selected_key(); - + const int k = key(); TCursor* crs = c.cursor(); + if (to == 0 && items) - to = c.row(items-1).get_long(key); + to = c.row(items-1).get_long(k); if (from > to) // Controlla limiti { @@ -220,17 +1406,21 @@ void TSelection_mask::select_clifo_range(long from, long to) long firs = 0; TRectype& rec = crs->file().curr(); + rec.zero(); - rec.put(CLI_TIPOCF,get_who()); + rec.put(CLI_TIPOCF,who()); rec.put(CLI_CODCF,from); const TRecnotype start = crs->read(_isgteq); + firs = rec.get_long(CLI_CODCF); rec.zero(); - rec.put(CLI_TIPOCF,get_who()); + rec.put(CLI_TIPOCF,who()); rec.put(CLI_CODCF,to); + TRectype recx(rec); TRecnotype end = crs->read(_isgteq); + if (rec > recx) { end--; @@ -244,7 +1434,6 @@ void TSelection_mask::select_clifo_range(long from, long to) set(SC_CFCODFR, firs); if (get(SC_CFCODTO).not_empty()) set(SC_CFCODTO, last); - set(SC_NSEL, c.checked()); } @@ -253,8 +1442,8 @@ void TSelection_mask::select_des_clifo_range(const TString& from, const TString TWait_cursor hourglass; TCursor_sheet& c = cur_sheet(); const long items = c.items(); - const int key = get_selected_key(); - CHECK(key == 2, "La chiave deve essere la 2"); + const int k = key(); + CHECK(k == 2, "La chiave deve essere la 2"); TString s_from(from), s_to(to); if (s_to.empty() && items) @@ -277,26 +1466,27 @@ void TSelection_mask::select_des_clifo_range(const TString& from, const TString TString last; TString firs; - - const char who = get_who(); TCursor* crs = c.cursor(); TRectype& rec = crs->file().curr(); + rec.zero(); - if (who >= 'C') + if (who() >= "C") { - rec.put(CLI_TIPOCF, who); + rec.put(CLI_TIPOCF, who()); rec.put(CLI_RAGSOC, s_from); } else rec.put(PCN_DESCR, s_from); + const TRecnotype start = crs->read(_isgteq); - firs = rec.get(who >= 'C' ? CLI_RAGSOC : PCN_DESCR); + + firs = rec.get(who() >= "C" ? CLI_RAGSOC : PCN_DESCR); rec.zero(); - rec.put(CLI_TIPOCF,get_who()); + rec.put(CLI_TIPOCF, who()); rec.put(CLI_RAGSOC,s_to); -if (who >= 'C') +if (who() >= "C") { - rec.put(CLI_TIPOCF, who); + rec.put(CLI_TIPOCF, who()); rec.put(CLI_RAGSOC, s_to); } else @@ -304,12 +1494,13 @@ if (who >= 'C') TRectype recx(rec); TRecnotype end = crs->read(_isgteq); + if (rec > recx) { end--; (*crs)-=1; } - last = rec.get(who >= 'C' ? CLI_RAGSOC : PCN_DESCR); + last = rec.get(who() >= "C" ? CLI_RAGSOC : PCN_DESCR); c.uncheck(-1); for (long i = start; i <= end; i++) c.check(i); @@ -328,7 +1519,6 @@ void TSelection_mask::set_clifo_limits() TCursor_sheet& c = cur_sheet(); const long items = c.items(); - const int key = get_selected_key(); long first = -1, last = -1; for (long i = 0; i < items; i++) @@ -349,11 +1539,13 @@ void TSelection_mask::set_clifo_limits() { TToken_string fitem(c.row(first)); TToken_string litem(c.row(last)); - from = fitem.get_long(key); - to = litem.get_long(key); - if (from>to) + + from = fitem.get_long(key()); + to = litem.get_long(key()); + if (from > to) { long t = to; + to=from; from=t; } @@ -370,9 +1562,9 @@ void TSelection_mask::set_des_clifo_limits() TString from,to; TCursor_sheet& c = cur_sheet(); const long items = c.items(); - const int key = get_selected_key(); - CHECK(key == 2, "La chiave deve essere la 2"); - + + CHECK(key() == 2, "La chiave deve essere la 2"); + for (long i = 0; i < items; i++) if (c.checked(i)) { @@ -391,6 +1583,7 @@ void TSelection_mask::set_des_clifo_limits() { TToken_string fitem(c.row(first)); TToken_string litem(c.row(last)); + from = fitem.get(1); to = litem.get(1); if (from>to) @@ -405,284 +1598,394 @@ void TSelection_mask::set_des_clifo_limits() set(SC_NSEL, c.checked()); } -// handlers - -bool TSelection_mask::ffrom_handler(TMask_field& f, KEY k) -{ - TSelection_mask& m = (TSelection_mask&)f.mask(); - - if (k == K_TAB && f.focusdirty()) - { - const long cod1 = atol(f.get()); - const long cod2 = m.get_long(SC_CFCODTO); - m.select_clifo_range(cod1, cod2); - } - else - if (k == K_F9) - { - TCursor_sheet& c = m.cur_sheet(); - c.cursor()->curr().put(CLI_CODCF, f.get()); - c.cursor()->read(); - c.disable_check(); - c.disable(DLG_USER); - if (c.run() == K_ENTER) - { - TToken_string& t = c.row(c.selected()); - const long cod1 = t.get_long(m.get_selected_key()); - const long cod2 = m.get_long(SC_CFCODTO); - m.set(SC_CFCODFR, cod1); - m.select_clifo_range(cod1, cod2); - } - c.enable(DLG_USER); - c.enable_check(); - } - - - return true; -} - -bool TSelection_mask::fto_handler(TMask_field& f, KEY k) -{ - TSelection_mask& m = (TSelection_mask&)f.mask(); - - if (k == K_TAB && f.focusdirty()) - { - const long cod1 = m.get_long(SC_CFCODFR); - const long cod2 = atol(f.get()); - m.select_clifo_range(cod1, cod2); - } - else - if (k == K_F9) - { - TSelection_mask& m = (TSelection_mask&)f.mask(); - TCursor_sheet& c = m.cur_sheet(); - c.cursor()->curr().put(CLI_CODCF, f.get()); - c.cursor()->read(); - c.disable_check(); - c.disable(DLG_USER); - if (c.run() == K_ENTER) - { - TToken_string& t = c.row(c.selected()); - const long cod2 = t.get_long(m.get_selected_key()); - const long cod1 = m.get_long(SC_CFCODFR); - m.set(SC_CFCODTO, cod2); - m.select_clifo_range(cod1, cod2); - } - c.enable(DLG_USER); - c.enable_check(); - } - return true; -} - -bool TSelection_mask::fdfrom_handler(TMask_field& f, KEY k) -{ - TSelection_mask& m = (TSelection_mask&)f.mask(); - - if (k == K_TAB && f.focusdirty()) - { - const TString des1(f.get()); - const TString des2(m.get(SC_CFDESTO)); - m.select_des_clifo_range(des1, des2); - } - else - if (k == K_F9) - { - TCursor_sheet& c = m.cur_sheet(); - const char* fld = m.get_who() >= 'C' ? CLI_RAGSOC : PCN_DESCR; - const TString& value = f.get(); - c.cursor()->curr().put(fld, value); - c.cursor()->read(); - if(c.find_by_id(SC_CLIFO) != NULL) - c.set(SC_CLIFO, value, 0x3); - c.disable_check(); - c.disable(DLG_USER); - if (c.run() == K_ENTER) - { - TToken_string& t = c.row(c.selected()); - const TString des1(t.get(1)); - const TString des2 = m.get(SC_CFDESTO); - m.set(SC_CFDESFR, des1); - m.select_des_clifo_range(des1, des2); - } - c.enable(DLG_USER); - c.enable_check(); - } - - return true; -} - -bool TSelection_mask::fdto_handler(TMask_field& f, KEY k) -{ - TSelection_mask& m = (TSelection_mask&)f.mask(); - - if (k == K_TAB && f.focusdirty()) - { - const TString des2(f.get()); - const TString des1(m.get(SC_CFDESFR)); - m.select_des_clifo_range(des1, des2); - } - else - if (k == K_F9) - { - TCursor_sheet& c = m.cur_sheet(); - const char* fld = m.get_who() >= 'C' ? CLI_RAGSOC : PCN_DESCR; - const TString& value = f.get(); - c.cursor()->curr().put(fld, value); - c.cursor()->read(); - if (c.find_by_id(SC_CLIFO) != NULL) - c.set(SC_CLIFO, value, 0x3); - c.disable_check(); - c.disable(DLG_USER); - if (c.run() == K_ENTER) - { - TToken_string& t = c.row(c.selected()); - const TString des1(m.get(SC_CFDESFR)); - const TString des2(t.get(1)); - m.set(SC_CFDESTO, des2); - m.select_des_clifo_range(des1, des2); - } - c.enable(DLG_USER); - c.enable_check(); - } - return true; -} - -bool TSelection_mask::breset_handler(TMask_field& f, KEY k) +bool TSelection_mask::get_cc_address(const char * tipo, const long cod, TToken_string& cc) const { - if (k == K_SPACE) - { - TSelection_mask& m = (TSelection_mask&)f.mask(); - m.reset_sheets(); - } - return true; + TString8 clifo; clifo.format("%s%06ld", (const char *) tipo, cod); + TISAM_recordset contacts("USE MULTIREL\nFROM COD=BACON FIRST=#CLIFO\nTO COD=BACON FIRST=#CLIFO"); + TToken_string data; + + contacts.set_var("#CLIFO", clifo); + for (bool ok = contacts.move_first(); ok; ok = contacts.move_next()) + { + data = contacts.get("DATA").as_string(); + FOR_EACH_TOKEN(data, tok) + { + const TFixed_string doc(tok); + + if (doc.starts_with("sc2400", true) || doc.starts_with("sollec", true)) + { + const TRectype& rub = cache().get(LF_CONTACT, contacts.get("SECOND").as_int()); + TString80 mail = rub.get("MAIL"); + + if (mail.blank()) + mail = rub.get("MAIL2"); + if (mail.full() && cc.find(mail) < 0) + { + cc.add(mail); + break; + } + } + } + } + return cc.full(); } -bool TSelection_mask::bselect_handler(TMask_field& f, KEY k) +int TSelection_mask::send_doc(long codice, const TString & ragsoc, const TToken_string& email, + TToken_string & cc, TToken_string & ccn, bool rcpt, const TString & test_email, + const TString & subj, const TString & msg, TLog_report & log) +{ + const bool test = test_email.full(); + TFilename pdf; + TPrinter & pr = printer(); + TToken_string to(email, ';'), attachment("", ';'); + TString esito("Invio a "); + TString subject(subj); + TString message(msg); + TString stat("Invio a "); + + stat << ' ' << ragsoc; + xvtil_statbar_set(stat); + TDate data; + bool sollecito = find_by_id(F_DATALIMSOL) != nullptr; + + if (sollecito) + data = get_date(F_DATALIMSOL); + if (!data.ok()) + data = get_date(F_DATASEND); + if (!data.ok()) + data = today; + if (subject.blank()) + subject << (sollecito ? TR("Sollecito da ") : TR("Estratto conto da ")); + subject << ' ' << prefix().firm().ragione_sociale(); + if (message.blank()) + { + message << "Spett. " << ragsoc << '\n'; + if (sollecito) + message << TR("Si ricorda il rispetto delle scadenze aperte al ") << data << '\n' + << TR(" riepilogate nel file allegato ") << '\n'; + else + message << TR("Invio estratto conto al ") << data << TR(" nel file allegato ") << '\n'; + message << prefix().firm().ragione_sociale(); + } + pdf.temp("cu", "pdf"); + attachment.add(pdf); + pr.set_export_file(pdf, true); + pr.open(); + + int ret = print_one(who(), codice); + + if (ret > 0) + { + pr.close(); + message << ragsoc << " (" << email << ")"; + if (msg.full()) + message << '\n' << msg << '.'; + esito << email; + if (!send_mail(to, cc, ccn, subject, message, attachment, false, rcpt)) + { + ret = 0; + esito << " non "; + } + esito << " riuscito"; + log.log(0, esito); + } + xvtil_statbar_set(nullptr); + return ret; +} + +bool TSelection_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { - if (k == K_SPACE) - { - TSelection_mask& m = (TSelection_mask&)f.mask(); - TCursor_sheet& c = m.cur_sheet(); - c.enable_check(); - c.run(); - if (m.get_selected_key() == 2) - m.set_des_clifo_limits(); - else - m.set_clifo_limits(); - } - return true; + switch (o.dlg()) + { + case SC_CLIFO : + if (e == fe_modify) + { + set_who(o.get()); + reset_sheets(); + } + break; + case SC_SORTCF : + if (e == fe_modify) + { + set_key(o.get_int()); + reset_sheets(); + } + break; + case SC_SELECT : + if (e == fe_button) + { + TCursor_sheet& c = cur_sheet(); + + c.enable_check(); + c.run(); + if (key() == 2) + set_des_clifo_limits(); + else + set_clifo_limits(); + } + break; + case SC_RESET : + if (e == fe_button) + reset_sheets(); + break; + case SC_CFCODFR : + if (e == fe_modify) + { + const long cod1 = o.get_long(); + const long cod2 = get_long(SC_CFCODTO); + + select_clifo_range(cod1, cod2); + } + else + if (e == fe_button) + { + TCursor_sheet& c = cur_sheet(); + + c.cursor()->curr().put(CLI_CODCF, o.get()); + c.cursor()->read(); + c.disable_check(); + c.disable(DLG_USER); + if (c.run() == K_ENTER) + { + TToken_string& t = c.row(c.selected()); + const long cod1 = t.get_long(key()); + const long cod2 = get_long(SC_CFCODTO); + + set(SC_CFCODFR, cod1); + select_clifo_range(cod1, cod2); + } + c.enable(DLG_USER); + c.enable_check(); + } + break; + case SC_CFCODTO : + if (e == fe_modify) + { + const long cod1 = get_long(SC_CFCODFR); + const long cod2 = o.get_long(); + + select_clifo_range(cod1, cod2); + } + else + if (e == fe_button) + { + TCursor_sheet& c = cur_sheet(); + + c.cursor()->curr().put(CLI_CODCF, o.get()); + c.cursor()->read(); + c.disable_check(); + c.disable(DLG_USER); + if (c.run() == K_ENTER) + { + TToken_string& t = c.row(c.selected()); + const long cod2 = t.get_long(key()); + const long cod1 = get_long(SC_CFCODFR); + + set(SC_CFCODTO, cod2); + select_clifo_range(cod1, cod2); + } + c.enable(DLG_USER); + c.enable_check(); + } + break; + case SC_CFDESFR : + if (e == fe_modify) + { + const TString des1(o.get()); + const TString des2(get(SC_CFDESTO)); + + select_des_clifo_range(des1, des2); + } + else + if (e == fe_button) + { + TCursor_sheet& c = cur_sheet(); + const char* fld = who() >= "C" ? CLI_RAGSOC : PCN_DESCR; + const TString& value = o.get(); + + c.cursor()->curr().put(fld, value); + c.cursor()->read(); + if (c.find_by_id(SC_CLIFO) != nullptr) + c.set(SC_CLIFO, value, 0x3); + c.disable_check(); + c.disable(DLG_USER); + if (c.run() == K_ENTER) + { + TToken_string& t = c.row(c.selected()); + const TString des1(t.get(1)); + const TString des2 = get(SC_CFDESTO); + + set(SC_CFDESFR, des1); + select_des_clifo_range(des1, des2); + } + c.enable(DLG_USER); + c.enable_check(); + } + break; + case SC_CFDESTO : + if (e == fe_modify) + { + const TString des2(o.get()); + const TString des1(get(SC_CFDESFR)); + + select_des_clifo_range(des1, des2); + } + else + if (e == fe_button) + { + TCursor_sheet& c = cur_sheet(); + const char* fld = who() >= "C" ? CLI_RAGSOC : PCN_DESCR; + const TString& value = o.get(); + + c.cursor()->curr().put(fld, value); + c.cursor()->read(); + if (c.find_by_id(SC_CLIFO) != nullptr) + c.set(SC_CLIFO, value, 0x3); + c.disable_check(); + c.disable(DLG_USER); + if (c.run() == K_ENTER) + { + TToken_string& t = c.row(c.selected()); + const TString des1(get(SC_CFDESFR)); + const TString des2(t.get(1)); + + set(SC_CFDESTO, des2); + select_des_clifo_range(des1, des2); + } + c.enable(DLG_USER); + c.enable_check(); + } + break; + case DLG_EMAIL: + if (e == fe_button) + { + TLog_report log("Invio solleciti"); + TMail_mask & mail = mail_mask(); + TSheet_field & sh = mail.sfield(F_SHEET); + + if (who() >= "C") + { + TCursor & fc = *form().cursor(); + TCursor_sheet &s = cur_sheet(); + + fc.setkey(key()); + + TRectype filter(LF_CLIFO); + + filter.put(CLI_TIPOCF, who()); + fc.setregion(filter, filter); + + long failed = 0; // solleciti non stampati + + mail.load(); + sh.reset(); + update_checked(); + + const int last = s.last_one(); + + for (long pos = s.first_one(); pos <= last; pos++) + { + fc = pos; + + const TRectype & cli = fc.curr(); + const TString & tipo = cli.get(CLI_TIPOCF); + const long codice = cli.get_long(CLI_CODCF); + + if (s.checked(pos) && some_to_print(tipo, codice)) + { + TString ragsoc = cli.get(CLI_RAGSOC); + TToken_string email; + + email = cli.get(CLI_PEC); + if (email.blank()) + email = cli.get(CLI_MAIL); + if (email.blank()) + email = cli.get(CLI_DOCMAIL); + + const int nrow = sh.set_row_cell(S_SELECTED, email.full()); + + sh.enable_cell(nrow, S_SELECTED, email.full()); + sh.set_row_cell(S_CODCF, cli.get_long(CLI_CODCF), nrow); + sh.set_row_cell(S_EMAIL, email, nrow); + ragsoc.strip_double_spaces(); + sh.set_row_cell(S_RAGSOC, ragsoc, nrow); + } + } + sh.sort(sort); + if (mail.run() == K_ENTER) + { + TToken_string cc(mail.get(F_CCEMAIL), ';'); + TToken_string ccn(mail.get(F_CCNEMAIL), ';'); + const TString test_mail = mail.get(F_TESTEMAIL); + const TString from = mail.get(F_FROMEMAIL); + const TString pwd = mail.get(F_PASSWORD); + const bool rcpt = mail.get_bool(F_RECEIPT); + const TString subj = mail.get(F_SUBJ); + const TString msg = mail.get(F_MESSAGE); + + set_test_mail(test_mail); + if (from.full()) + xvt_set_mail_params(nullptr, nullptr, from, pwd, nullptr); + + FOR_EACH_SHEET_ITEM(sh, r) + { + if (sh.get_bool_row_cell(r, S_SELECTED)) + { + const TToken_string & email = sh.get_str_row_cell(r, S_EMAIL); + const long codice = sh.get_long_row_cell(r, S_CODCF); + TString ragsoc = sh.get_str_row_cell(r, S_RAGSOC); + + ragsoc.strip_double_spaces(); + get_cc_address(who(), codice, ccn); + + int ret = send_doc(codice, ragsoc, email, cc, ccn, rcpt, test_mail, subj, msg, log); + + if (ret < 0) + failed++; + } + } + if (failed > 0) + warning_box(FR("%ld clienti non sono stati stampati in quanto " + "il codice lingua non corrispondeva al profilo di stampa"), failed); + } + mail.save(EMPTY_STRING, false, false); + if (log.rows() > 0) + log.preview(); + } + } + break; + default: + break; + } + return true; } -bool TSelection_mask::rclifo_handler(TMask_field& f, KEY k) -{ - if (k == K_SPACE) - { - TSelection_mask& m = (TSelection_mask&)f.mask(); - m.set_who(f.get()[0]); - m.reset_sheets(); - } - return true; -} - -bool TSelection_mask::rsortcf_handler(TMask_field& f, KEY k) -{ - if (k == K_SPACE) - { - TSelection_mask& m = (TSelection_mask&)f.mask(); - m.set_key(atoi(f.get())); - m.reset_sheets(); - } - return true; -} - -void TSelection_mask::update_assoc() +void TSelection_mask::update_checked() { - _assoc.destroy(); - _all_selected = false; - TCursor_sheet& cs = cur_sheet(); // Sheet di selezione (CLI/FO/PCON) const long checked = cs.checked(); - if (checked == 0L || checked == cs.items()) - _all_selected =true; - else - { - const int first = get_selected_key(); - const char who = get_who(); - TString16 key; - - for (long i = cs.items()-1; i >= 0; i--) if (cs.checked(i)) - { - TToken_string& row = cs.row(i); - if (who == 'C' || who == 'F') - { - key.format("000000%06ld", row.get_long(first)); - } - else - { - const TBill b(row, first, 0x0); - key.format("%03d%03d%06ld", - b.gruppo(), b.conto(), b.sottoconto()); - } - _assoc.add(key); - } - } + + if (checked == 0L) + cs.check_all(); } -bool TSelection_mask::selected(const TBill& b) const -{ - bool ok = _all_selected; - if (!ok) - { - TString16 key; - key.format("%03d%03d%06ld", - b.gruppo(), b.conto(), b.sottoconto()); - ok = _assoc.is_key(key); - } - return ok; -} - -bool TSelection_mask::selected(int g, int c, long s) const -{ - bool ok = _all_selected; - if (!ok) - { - TString16 key; - key.format("%03d%03d%06ld", g, c, s); - ok = _assoc.is_key(key); - } - return ok; -} - -TRecnotype TSelection_mask::get_clifo_range(long& first, long& last) const +TRecnotype TSelection_mask::get_clifo_range(long& first, long& last) { first = last = 0L; TRecnotype items = 0; - if (get_who() >= 'C') + if (who() >= "C") { - if (_all_selected) - { - TCursor& c = *cur_sheet().cursor(); // Sheet di selezione (CLI/FO/PCON) - items = c.items(); - if (items > 0) - { - c = 0L; first = c.curr().get_long(CLI_CODCF); - c = c.items()-1L; last = c.curr().get_long(CLI_CODCF); - } - } - else - { - TAssoc_array& ass = (TAssoc_array&)_assoc; // Trick the compiler - FOR_EACH_ASSOC_OBJECT(ass, obj, key, item) - { - const TFixed_string gcs(key); - const long codcf = atol(gcs.right(6)); - if (first == 0 || codcf < first) - first = codcf; - if (last == 0 || codcf > last) - last = codcf; - items++; - } - } + TCursor_sheet & s = cur_sheet(); // Sheet di selezione (CLI/FO/PCON) + + update_checked(); + first = s.last_one(); + last = s.last_one(); + if (s.checked() == s.items()) + items = s.items(); + else + for (long i = first; i <= last; i++) + if (s.checked(i)) + items++; } return items; } diff --git a/src/sc/scselect.h b/src/sc/scselect.h index d3ea22dcc..e8443d8fd 100755 --- a/src/sc/scselect.h +++ b/src/sc/scselect.h @@ -5,8 +5,12 @@ #include #endif -#ifndef __MASK_H -#include +#ifndef __AUTOMASK_H +#include +#endif + +#ifndef __FORM_H +#include #endif #ifndef __RELATION_H @@ -21,6 +25,10 @@ #include #endif +#ifndef __CGSALDAC_H +#include "../cg/cgsaldac.h" +#endif + #ifndef __SCSELMSK_H #include "scselmsk.h" #endif @@ -29,8 +37,213 @@ #include "../cg/cglib.h" #endif -class TSelection_mask : public TMask -{ +#ifndef __SC2102_H +#include "sc2102.h" +#endif + +class TESSL_form; +class TSelection_mask; + +/////////////////////////////////////////////////////////// +// TESSL_row +/////////////////////////////////////////////////////////// + +class TESSL_row : public TSortable +{ + TDate _data; // Data scadenza o pagamento + int _riga; // Riga della fattura + int _rata; // Numero rata o progrssivo + + TString _causale; // Codice causale + TString _descrizione; // Sua descrizione + + TDate _data_doc; // Data del documento + TString _num_doc; // Numero documento + long _num_prot; // Protocollo IVA + long _num_reg; // Numero registrazione + TImporto _importo; // Importo in valuta + real _importo_euro; // Importo in euro + real _scaduto; // Importo scaduto + real _esposto; // Importo esposto + bool _salvo_buon_fine; // Importo esposto salvo buon fine + real _totale; // Totale documento + TValuta _valuta; // Codice valuta, data cambio e cambio + bool _bloccata; // Rata bloccata + TString _codici_analitica; // codici analitica corrispondenti alle fatture + +protected: // TSortable + virtual int compare(const TSortable& s) const; + void set_imp(TForm_item& fi, const real& imp, const char* cod_val) const; + + TESSL_form & form() const; + +public: + int riga() const { return _riga; } + int rata() const { return _rata; } + + void reset_uguali(); + void descrizione(const char* s) { _descrizione = s; } + void importo(const TImporto& i) { _importo = i; } + void scaduto(const real& s) { _scaduto = s; } + void esposto(const real& e) { _esposto = e; } + void importo_in_euro(const real& imp) { _importo_euro = imp; } + void salvo_buon_fine(bool sbf) { _salvo_buon_fine = sbf; } + void rata_bloccata(bool rb) { _bloccata = rb; } + void codici_analitica(const char * s) { _codici_analitica = s; } + + const TString& causale() const { return _causale; } + const TString& descrizione() const { return _descrizione; } + long num_reg() const { return _num_reg; } + const TValuta& valuta() const { return _valuta; } + const TImporto& importo() const { return _importo; } + const real& importo_in_euro() const { return _importo_euro; } + const real& scaduto() const { return _scaduto; } + const real& esposto() const { return _esposto; } + const TDate& data() const { return _data; } + bool in_valuta() const { return _valuta.in_valuta(); } + + void print_on(TPrint_section& body); + + TESSL_row(const TRiga_partite& row, const TDate& data, const TImporto& imp, int rata); + TESSL_row(const char* desc, const TImporto& imp, const TValuta& val); + virtual ~TESSL_row() {} +}; + +/////////////////////////////////////////////////////////// +// TESSL_form: form speciale per estratti conto +/////////////////////////////////////////////////////////// + +class TESSL_form : public TForm +{ + friend class TESSL_row; + + static TESSL_form* _form; + + enum { MAXTOT = 16 }; + + TCursor* _cursore; + TTotalizer _totali; + + TString _lingua; + TDate _dlo, _dls, _dir; + + int _fincatura; // 0 = nessuna, 1 = testo, 2 = grafica + TString4 _who; + + int _giorni_rischio; + word _maxtot; // numero massimo di totali + + bool _in_valuta; + bool _stampa_esp; + bool _stampa_saldo; // Stampa il saldo di ogni partita + + TToken_string _anal_filter; + + word _num_rip; // numero di righe usate per i riporti + word _total_rows; // numero di righe usate per i totali + + TDecoder _causali; // Decodificatore dei codici causale + TDecoder _movimenti; // Decodificatore delle descrizioni dei movimenti + TDecoder _valute; // Decodificatore dei codici valuta + +protected: + void init_header(const TMask& m); + word ordina_totali_per_valuta(THash_object* tot[MAXTOT]); + int find_magic(TString& s, TString& magic1, TString& magic2) const; + void change_magic_body(const TESSL_row& o, TString& s); + void change_magic_footer(const THash_object& o, TString& s); + // void modify_picture(TForm_item& fi, TString_array& op, const bool in_valuta); + void print_total(int riga, const THash_object& o); + + void stampa_testata(TPrinter& p); + void stampa_pedata(TPrinter& p); + void stampa_riporti(TPrinter& p); + + static void header_handler(TPrinter& p); + static void footer_handler(TPrinter& p); + +public: + virtual TESSL_form & form() { return *_form; } + TTotalizer& totali() { return _totali; } + TDecoder& causali() { return _causali; } + TDecoder& valute() { return _valute; } + TDecoder& movimenti() { return _movimenti; } + + const TDate& data_limite_operazione() const { return _dlo; } + const TDate& data_limite_scaduto() const { return _dls; } + int giorni_rischio() const { return _giorni_rischio; } + const TDate& data_inizio_rischio() const { return _dir; } + + const TString& lingua() const { return _lingua; } + bool in_valuta() const { return _in_valuta; } + const TString& describe(short id, char sez = 'H', pagetype pt = last_page) const; + const char sezione_normale() const { return _who == 'C' ? 'D' : 'A'; } + + void stampa_saldo(bool ss = true) { _stampa_saldo = ss; } + void anal_filter(const TToken_string & f) { _anal_filter = f; } + const TToken_string &get_anal_filter() const { return _anal_filter; } + + void azzera_totali(); + void ultima_pagina(); + virtual bool print_game(const TPartita& game); + virtual bool stampa_esposto() const { return false; } + + TESSL_form(const TSelection_mask & m, bool gesval, short id_datalim = 0, short id_datascad = 0, + short id_giorni_rischio = 0); + virtual ~TESSL_form(); +}; + +/////////////////////////////////////////////////////////// +// TESSL_array +/////////////////////////////////////////////////////////// + +class TESSL_array : public TArray +{ + TArray _scaduto; // Array di importi scaduti + TDecoder _anal; + + const TESSL_form* _form; + +protected: + TESSL_row& new_row(const TRiga_partite& row, const TDate& data, const TImporto& imp, int rata = 0); + void add_row(const TRiga_partite& row); + + const TESSL_form& form() const { return *_form; } + real calcola_scaduto(const TRiga_scadenze& rata, bool valuta); + + + TImporto* importo_riga_scaduto_ptr(int n) const { return (TImporto*)_scaduto.objptr(n); } + TImporto& importo_riga_scaduto(int n); + + TImporto importo(const TPartita& game, const TRectype& pag, bool valuta) const; + + static TPartita* _sort_game; + static int ordina_pag(const void* pag1, const void* pag2); + void arrange_scaduto(const TPartita& game); + +public: + TESSL_row& row(int r) const { return (TESSL_row&)operator[](r); } + + TESSL_array(const TPartita& game, const TESSL_form* f); + virtual ~TESSL_array() {} +}; + +class TMail_mask : public TAutomask +{ +protected: + virtual bool on_key(KEY k) override; + virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly) override; + +public: + + TMail_mask() : TAutomask() {} + TMail_mask(const char * name) : TAutomask(name) {} + ~TMail_mask() = default; +}; + +class TSelection_mask : public TAutomask +{ + TMail_mask _empty_mask; TCursor_sheet* _cli_sh_k1; TCursor_sheet* _cli_sh_k2; TCursor_sheet* _for_sh_k1; @@ -38,7 +251,7 @@ class TSelection_mask : public TMask TCursor_sheet* _pdc_sh_k1; TCursor_sheet* _pdc_sh_k2; - char _who; // Clienti, fornitori, conti + TString4 _who; // Clienti, fornitori, conti int _key; // 1 = per codice, 2 = per descrizione TRelation* _clifo_rel; TCursor* _cli_cur_k1; @@ -48,49 +261,49 @@ class TSelection_mask : public TMask TRelation* _pdc_rel; TCursor* _pdc_cur_k1; TCursor* _pdc_cur_k2; - - TAssoc_array _assoc; - bool _all_selected; - -protected: // TMask - virtual void set_handler(short fld_id, CONTROL_HANDLER handler); - virtual bool stop_run(KEY k); - + +protected: + virtual TESSL_form & form() pure; + bool stampa_saldo() const; + virtual const TToken_string & get_anal_filter() const pure ; + virtual bool some_to_print(const char * tipo, const long codice) { return true; } + virtual int print_one(const char * tipo, const long codice) { return true; } + virtual TMail_mask & mail_mask() { return _empty_mask; } + protected: void select_clifo_range(long from, long to); void select_des_clifo_range(const TString & from, const TString & to); void set_clifo_limits(); void set_des_clifo_limits(); - void set_who(char w) { _who = w; } + virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly) override; + + void set_who(const char * w) { _who = w; } void set_key (int k) { _key = k; } void reset_sheets(); - void update_assoc(); + void update_checked(); - // handlers - static bool bfrom_handler(TMask_field& f, KEY k); - static bool bto_handler(TMask_field& f, KEY k); - static bool ffrom_handler(TMask_field& f, KEY k); - static bool fto_handler(TMask_field& f, KEY k); - static bool breset_handler(TMask_field& f, KEY k); - static bool bselect_handler(TMask_field& f, KEY k); - static bool rclifo_handler(TMask_field& f, KEY k); - static bool rsortcf_handler(TMask_field& f, KEY k); - static bool bdfrom_handler(TMask_field& f, KEY k); - static bool bdto_handler(TMask_field& f, KEY k); - static bool fdfrom_handler(TMask_field& f, KEY k); - static bool fdto_handler(TMask_field& f, KEY k); + bool get_cc_address(const char * tipo, const long cod, TToken_string& cc) const; + int send_doc(long codice, const TString & ragsoc, const TToken_string& email, + TToken_string & cc, TToken_string & ccn, bool rcpt, + const TString & test_email, const TString & subj, const TString & msg, TLog_report & log); public: + const TString & get_prof_lang() const; + const TString & get_prof_base() const; + const TString & get_prof_code() const; + const TString & get_prof_name() const; + TCursor_sheet& cur_sheet() const; - char get_who() const { return _who; } - int get_selected_key() const { return _key; } - - bool selected(const TBill& c) const; - bool selected(int g, int c, long s) const; - TRecnotype get_clifo_range(long& first, long& last) const; + const TString & who() const { return _who; } + const bool clienti() const { return who() == "C"; } + const bool conti() const { return who() == "P"; } + const bool fornitori() const { return who() == "F"; } + int key() const { return _key; } + + TRecnotype get_clifo_range(long& first, long& last); TSelection_mask(const char* name); virtual ~TSelection_mask();