#include #include #include // TButton_tool #include // ID Bottoni #include "lilib01.h" #include "li0.h" #include "li0100a.h" #define PLA_COLS 10 // n° colonne di lettere di intento #define CPC(x) (START_PLA + x*3) /* Utility ***********************/ HIDDEN bool key_handler(TMask& m, KEY k) { // Per ora facciamo che il SHIFT+F12 attiva sempre il campo 3 if (k == K_SHIFT+K_F12) m.enable(DLG_OK); return true; } /*****************************************************************/ class TVisLI_mask : public TAutomask { private: void next_page(int p); bool _filter_changed; int _plColumns; void addRow(TSheet_field& sheet, TISAM_recordset& rec); void resetColumns(TSheet_field& sheet); void addColumns(TSheet_field& sheet, const int col); public: void load_sheet(); void setFilterChanged() { _filter_changed = true; } bool on_field_event(TOperable_field& o, TField_event e, long jolly); TVisLI_mask(); }; TVisLI_mask::TVisLI_mask() : TAutomask("li0100a"), _filter_changed(true) { if(get(F_DATAFIN).empty()) set(F_DATAFIN, TDate(TODAY)); set_handler(key_handler); disable(DLG_OK); } void TVisLI_mask::load_sheet() { _filter_changed = false; TSheet_field& sheet = sfield(F_RIGHE); sheet.hide(); // Nascondo lo sheet per guadagnare un 20% di velocità di caricamento, le ottimizzazioni da PRO! if(!sheet.empty()) sheet.destroy(); resetColumns(sheet); TString query = "USE DOC\n"; if(get(F_TIPORIC) == "D") { /* Facciamo una scelta intelligente per ottimizzare sempre la chiave da usare * Ho il filtro sul cliente? 2 * Ho il filtro sulla data? 3 * Ho il filtro sul codice numerazione? 5 * In caso di tutto negativo uso la chiave classica */ int key = get(F_DACODCF).full() ? 2 : (get(F_DATAINI).full() ? 3 : (get(F_CODNUM).full() ? 5 : 1)); query << "KEY " << key << "\n"; TString queryFrom, queryTo; switch (key) { case 2: { // 2: TIPOCF+CODCF+PROVV+ANNO+DATADOC+CODNUM+NDOC queryFrom.cut(0) << "FROM TIPOCF='C' CODCF=#DACODCF PROVV='D'"; queryTo.cut(0) << "TO TIPOCF='C' CODCF=#ACODCF PROVV='D'"; if(get(F_ANNO).full()) { queryFrom << " ANNO=#DAANNO"; queryTo << " ANNO=#AANNO"; if(get(F_DATAINI).full()) { queryFrom << " DATADOC=#DADATA"; if(get(F_CODNUM).full()) queryFrom << " CODNUM=#DACODNUM"; } if(get(F_DATAFIN).full()) { queryTo << " DATADOC=#ADATA"; if(get(F_CODNUM).full()) queryTo << " CODNUM=#ACODNUM"; } } } break; case 3: { // 3: DATADOC+PROVV+ANNO+CODNUM+NDOC queryFrom.cut(0) << "DATADOC=#DADATA PROVV='D'"; queryTo.cut(0) << "DATADOC=#ADATA PROVV='D'"; if(get(F_ANNO).full()) { queryFrom << " ANNO=#DAANNO"; queryTo << " ANNO=#AANNO"; if(get(F_CODNUM).full()) { queryFrom << " CODNUM=#DACODNUM"; queryTo << " CODNUM=#ACODNUM"; } } } break; case 5: { // 5: PROVV+CODNUM+ANNO+NDOC queryFrom.cut(0) << "PROVV='D' CODNUM=#DACODNUM"; queryTo.cut(0) << "PROVV='D' CODNUM=#ACODNUM"; if(get(F_ANNO).full()) { queryFrom << " ANNO=#DAANNO"; queryTo << " ANNO=#AANNO"; } } break; case 1: default: { // 1: PROVV+ANNO+CODNUM+NDOC queryFrom.cut(0) << "PROVV='D'"; queryTo.cut(0) << "PROVV='D'"; if(get(F_ANNO).full()) { queryFrom << " ANNO=#DAANNO"; queryTo << " ANNO=#AANNO"; } } break; } // Campi solo filtrabili con SELECT ************************** // TIPODOC+STATO if(get(F_TIPODOC).full()) query << "SELECT TIPODOC==#TIPODOC"; if(get(F_STATO).full()) query << "SELECT STATO==#STATO"; // Unisco query query << "FROM " << queryFrom << "\nTO " << queryTo << "\n"; // Creo recordset TISAM_recordset rec(query); // Uso il metodo di TISAM_recordset per valorizzare la query, è più sicuro if(get(F_DATAINI).full()) rec.set_var("#DADATA", get_date(F_DATAINI)); if(get(F_DATAFIN).full()) rec.set_var("#ADATA", get_date(F_DATAFIN)); if(get(F_CODNUM).full()) { rec.set_var("#DACODNUM", get(F_CODNUM)); rec.set_var("#ACODNUM", get(F_CODNUM)); } if(get(F_TIPODOC).full()) rec.set_var("#TIPODOC", get(F_TIPODOC)); if(get(F_ANNO).full()) { rec.set_var("#DAANNO", get(F_ANNO)); rec.set_var("#AANNO", get(F_ANNO)); } if(get(F_STATO).full()) rec.set_var("#STATO", get(F_STATO)); if(get(F_DACODCF).full()) rec.set_var("#DACODCF", get(F_DACODCF)); if(get(F_ACODCF).full()) rec.set_var("#ACODCF", get(F_ACODCF)); // Aggiungo le righe allo sheet for(bool ok = rec.move_first(); ok; ok = rec.move_next()) addRow(sheet, rec); } else { TString16 key; key << get(F_ANNO) << "|" << get(F_NUMPROT); TRectype letint = cache().get(LF_LETINT, key); // 2: TIPOCF+CODCF+PROVV+ANNO+DATADOC+CODNUM+NDOC query << "KEY 2\n" "FROM TIPOCF='C' CODCF=" << letint.get("CODCLI") << " PROVV='D' ANNO=" << letint.get("ANNO") << " DATADOC=" << letint.get("DAL") << "\n" "TO TIPOCF='C' CODCF=" << letint.get("CODCLI") << " PROVV='D' ANNO=" << letint.get("ANNO") << " DATADOC="<< letint.get("ANNO") << "1231"; TISAM_recordset rec(query); for(bool ok = rec.move_first(); ok; ok = rec.move_next()) { TToken_string lePlafs(rec.get("G1:PLAFOND").as_string(), ','); for(int i = 0; i < lePlafs.items(); i++) { TToken_string thisPlaf = lePlafs.get(i); if(strcmp(thisPlaf.get(1), get(F_NUMPROT)) == 0) // 1 -> _plnumprot from lilib.h { addRow(sheet, rec); break; } } } } // Forzo aggiornamento e mostro sheet sheet.force_update(); sheet.show(); } void TVisLI_mask::addRow(TSheet_field& sheet, TISAM_recordset& rec) { // Per ogni documento che aggiungo valuto quante lettere di intento utilizzo. // Ogni lettera di intento utilizzerà 2 colonne: // Num protocollo e QTA utilizzata // Controllo preventivo che abbia effettivamente il plafond sul documento if(rec.get("G1:PLAFOND").is_empty()) return; // Creo una nuova riga TToken_string& row = sheet.row(-1); // Data documento row.add(rec.get("DATADOC").as_date(), sheet.cid2index(A_DATADOC)); // Anno documento row.add(rec.get("ANNO").as_int(), sheet.cid2index(A_ANNO)); // Numero documento row.add(rec.get("NDOC").as_string(), sheet.cid2index(A_NUMDOC)); // Numero documento row.add(rec.get("CODNUM").as_string(), sheet.cid2index(A_CODNUM)); // Tipo documento row.add(rec.get("TIPODOC").as_string(), sheet.cid2index(A_TIPODOC)); // Tipo cliente row.add("C", sheet.cid2index(A_TIPOCF)); // Codice cliente row.add(rec.get("CODCF").as_int(), sheet.cid2index(A_CODCF)); // Ragione Sociale static TString key; key.cut(0) << "C|" << rec.get("CODCF").as_string(); row.add(cache().get(LF_CLIFO, key, "RAGSOC"), sheet.cid2index(A_RAGSOC)); // Totale documento row.add(rec.get("G1:TOTDOC").as_real(), sheet.cid2index(A_TOTDOC)); TToken_string lePlafs(rec.get("G1:PLAFOND").as_string(), ','); // Abilito le colonne che mi servono addColumns(sheet, lePlafs.items()); for(int i = 0; i < lePlafs.items() && i < PLA_COLS; i++) { TToken_string thisPlaf = lePlafs.get(i); row.add(thisPlaf.get(1), sheet.cid2index(CPC(i))); // _plnumprot row.add(thisPlaf.get(2), sheet.cid2index(CPC(i)+1)); // _plimporto } } void TVisLI_mask::resetColumns(TSheet_field& sheet) { return; // Disabled // Disabilito tutte le colonne che non uso for (int i = 0; i < PLA_COLS * 2; i++) sheet.show_column(START_PLA+i, false); } void TVisLI_mask::addColumns(TSheet_field& sheet, const int col) { return; // Disabled for(; _plColumns <= col && _plColumns <= PLA_COLS; _plColumns++) { sheet.show_column(CPC(_plColumns), true); sheet.show_column(CPC(_plColumns)+1, true); } } void TVisLI_mask::next_page(int p) { TAutomask::next_page(p); if (_filter_changed && curr_win() == sfield(F_RIGHE).parent()) { load_sheet(); } } bool TVisLI_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { const short id = o.dlg(); switch(id) { case F_CODNUM: { if(e == fe_modify) { TMask& m = o.mask(); const TString4& codnum = o.get(); if(codnum.full()) { const TCodice_numerazione & cod_num = cached_numerazione(codnum); m.set(F_DESNUM, cod_num.descrizione()); m.set(F_TIPODOC, cod_num.tipo_doc(0)); const TTipo_documento tipodoc(cod_num.tipo_doc(0)); m.set(F_DESTIPODOC, tipodoc.descrizione()); } } } break; case F_TIPORIC: if(e == fe_modify) { bool en = o.get() == "D"; enable(F_NUMPROT, !en); // Pulisco il campo se devo if(en) reset(F_NUMPROT); for(int i = START_DOC; i <= END_DOC; i++) { enable(i, en); // Pulisco i campi se devo if(!en) reset(i); } } break; case DLG_RECALC: if(e == fe_button) next_page(1); break; case DLG_OK: { // Creo una maschera che richiede la data TMask app("Creazione storico LI", 1, 50, 10); app.add_button_tool(DLG_OK, "Esegui", TOOL_OK); app.add_button_tool(DLG_CANCEL, "Annulla", TOOL_CANCEL); app.add_date(101, 0, "Data iniziale ", 1,1); app.field(101).check_type(CHECK_REQUIRED); // Lancio la maschera if(app.run() == K_ENTER) generaLiStorico(app.get_date(101)); break; } case DLG_USER: if (e == fe_button || e == fe_init) { // 1: PROVV+ANNO+CODNUM+NDOC const long anno = o.mask().get_long(A_ANNO); const TString codnum = o.mask().get(A_CODNUM); const long numdoc = o.mask().get_long(A_NUMDOC); const bool enab = numdoc > 0; if (e == fe_button && enab) { o.disable(); // Tecnica anti doppio click! TRectype doc(LF_DOC); doc.put("PROVV", 'D'); doc.put("ANNO", anno); doc.put("CODNUM", codnum); doc.put("NDOC", numdoc); doc.edit(); o.enable(); } else o.enable(enab); } default: break; } if (e == fe_modify && jolly == 0 && id >= START_MASK && id <= END_MASK) { setFilterChanged(); } return true; } class TVisLI_app : public TSkeleton_application { public: void main_loop(); }; void TVisLI_app::main_loop() { open_files(LF_LETINT, LF_DOC, LF_RIGHEDOC); TVisLI_mask m; while (m.run() == K_ENTER) { // DO DA TING } } int li0100(int argc, char* argv[]) { TVisLI_app a; a.run(argc, argv, TR("Riferimenti lettere/Documento")); return 0; }