#include #include #include #include #include #include #include "ps6215.h" #include "ps6215100a.h" #include "utility.h" #include "clifo.h" #include "comuni.h" #include "cfven.h" #include "sqlset.h" #include #include "ps6215partite.h" #define CLIFO_RECLEN 730 class TFixed_record { int* _dims; /**< Array of the elements dimension. */ const char** _fields_name; int _items; char* _str; /**< Full record. */ int _tot_len; /**< \a _str dimension. */ /** Semplice controllo dell'indice degli elementi. */ bool check_index(int _Idx) const; /** \returns la posizione reale nel record del campo all'indice \a _Idx. */ int pos(int _Idx) const; public: /** \returns la posizione dell'elemento che corrisponde alla colonna con il nome passato, se i nomi sono stati passati. */ int find_column(const char* field_name) const; /** \returns il record per intero. */ const char* get_line() const { return (const char*)_str; } /** \returns the name of the field at the given index. */ const char* get_name_field(int _Idx = 0) const; /** Set the string \a _Str in the given position \a _Idx. */ void set_str(int _Idx, const char* _Str) const; /** \returns a fixed string of the element at the index. */ TFixed_string operator[](int _Idx) const; /** \returns a fixed string of the element of specified column name \a field_name. */ TFixed_string operator[](const char* field_name) const; TFixed_record(int items, const int dims[]); TFixed_record() : TFixed_record(0, nullptr) { } TFixed_record(int items, const int dims[], const char* fields_name[]); ~TFixed_record(); }; bool TFixed_record::check_index(int _Idx) const { return _Idx >= 0 && _Idx <= _items; } int TFixed_record::pos(int _Idx) const { int real_idx = 0; if (check_index(_Idx)) { for (int i = 0; i < _Idx; ++i) real_idx += _dims[i]; } return real_idx; } int TFixed_record::find_column(const char* field_name) const { if (!_fields_name) return -1; for (int i = 0; i < _items; ++i) if(strcmp(get_name_field(i), field_name) == 0) return i; return -1; } void TFixed_record::set_str(int _Idx, const char* _Str) const { const int p = pos(_Idx); for (int i = p; i < p + _dims[_Idx] && i < (int)strlen(_Str) + p; ++i) _str[i] = _Str[i - p]; } const char* TFixed_record::get_name_field(int _Idx) const { return check_index(_Idx) && _fields_name ? _fields_name[_Idx] : ""; } TFixed_string TFixed_record::operator[](int _Idx) const { static TFixed_string* f_str = nullptr; delete f_str; if (check_index(_Idx)) { const int p = pos(_Idx); TString appo(_str); appo = appo.sub(p, p + _dims[_Idx]); const TFixed_string str(appo, _dims[_Idx] + 1); f_str = new TFixed_string(str); } else f_str = new TFixed_string(""); return *f_str; } TFixed_string TFixed_record::operator[](const char* field_name) const { return operator[](find_column(field_name)); } TFixed_record::TFixed_record(const int items, const int dims[]) : _fields_name(nullptr), _items(items), _tot_len(0) { _dims = new int[items]; for (int i = 0; i < items; ++i) { _dims[i] = dims[i]; _tot_len += dims[i]; } _str = new char[++_tot_len]; memset(_str, ' ', _tot_len); _str[_tot_len - 1] = '\0'; } TFixed_record::TFixed_record(int items, const int dims[], const char* fields_name[]) : TFixed_record(items, dims) { _fields_name = new const char*[_items]; for(int i = 0; i < _items; ++i) _fields_name[i] = fields_name[i]; } TFixed_record::~TFixed_record() { delete[] _dims; delete[] _fields_name; delete[] _str; } /////////////////////////////////////////////////////////// // Utilities /////////////////////////////////////////////////////////// void copy_wzero(char* dest, const int size, const char* source) { for(int i = 0; i < size; ++i) { const char c = source[i]; if (c == '\0') break; dest[i] = c; } } TString& trim_n(TString& str, const int max) { if(str.len() > max) str.rtrim(str.len() - max); return str; } TString to_escape(const TString& val) { TString& app = get_tmp_string(); for (int k = 0; k < val.len(); k++) { switch (val[k]) { case '\'': app << "''"; break; default: app << val[k]; break; } } return app; } /////////////////////////////////////////////////////////// // Main Mask /////////////////////////////////////////////////////////// class TComariExport_mask final : public TAutomask { protected: bool on_field_event(TOperable_field& o, TField_event e, long jolly) override; void load_all(); public: void save_all() const; TComariExport_mask(); ~TComariExport_mask() { save_all(); } }; bool TComariExport_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { return true; } TComariExport_mask::TComariExport_mask() : TAutomask("ps6215100a") { load_all(); } void TComariExport_mask::save_all() const { ini_set_string(CONFIG_DITTA, "ps6215", "flddest", get(F_FLDDEST)); ini_set_string(CONFIG_DITTA, "ps6215", "clifor_bool", get(F_CLIFOR)); ini_set_string(CONFIG_DITTA, "ps6215", "partopen_bool", get(F_PARTOPEN)); } void TComariExport_mask::load_all() { TFilename temp; temp.tempdir(); set(F_FLDDEST, ini_get_string(CONFIG_DITTA, "ps6215", "flddest", temp)); set(F_CLIFOR, ini_get_string(CONFIG_DITTA, "ps6215", "clifor_bool", "X")); set(F_PARTOPEN, ini_get_string(CONFIG_DITTA, "ps6215", "partopen_bool", "X")); } /////////////////////////////////////////////////////////// // Main Program /////////////////////////////////////////////////////////// class TComariExport_app : public TSkeleton_application { TString _fld_dest; bool export_all() const; static void add_to_record(char* record, TString& str, int len, int& index); static void export_clifo(ofstream& fout); static void export_parti(ofstream& fout); bool export_table(short id) const; public: bool create() override; void main_loop() override; TComariExport_app() = default; }; bool TComariExport_app::export_all() const { return export_table(F_CLIFOR) && export_table(F_PARTOPEN) && export_table(F_PIANOCONTI) && export_table(F_MASTRI); } void TComariExport_app::add_to_record(char* record, TString& str, int len, int& index) { trim_n(str, len); copy_wzero(record + index, CLIFO_RECLEN - index, str); index += len; } void TComariExport_app::export_clifo(ofstream& fout) { int index = 0; TLocalisamfile clifo(LF_CLIFO); bool ok = clifo.read(_isfirst) == NOERR; int items = clifo.items(); TProgress_monitor bar(items, "Esportazione Tabella Clienti Fornitori"); for(; ok; ok = clifo.next() == NOERR) { if (!bar.add_status()) break; char record[CLIFO_RECLEN]; memset(record, ' ', CLIFO_RECLEN); index = 0; TLocalisamfile comuni(LF_COMUNI), cfven(LF_CFVEN); comuni.put(COM_STATO, clifo.get(CLI_STATOCF)); comuni.put(COM_COM, clifo.get(CLI_COMCF)); comuni.read(); cfven.put(CFV_CODCF, clifo.get(CLI_CODCF)); cfven.put(CFV_TIPOCF, clifo.get(CLI_TIPOCF)); cfven.read(); // Tipo: TString a = clifo.get(CLI_TIPOCF); if(a[0] != 'C' && a != 'F') a[0] = 'C'; add_to_record(record, a, 1, index); // Codcf: a = clifo.get(CLI_CODCF); add_to_record(record, a, 15, index); // Descrizione: a = clifo.get(CLI_RAGSOC); a.rpad(50); TString b = a.sleft(30); add_to_record(record, b, 40, index); // Descrizione2: b = a.sright(20); add_to_record(record, b, 40, index); // Indirizzo: a = clifo.get(CLI_INDCF); a << ", " << clifo.get(CLI_CIVCF); add_to_record(record, a, 35, index); // Indirizzo2: a = ""; add_to_record(record, a, 35, index); // CAP: a = clifo.get(CLI_CAPCF); add_to_record(record, a, 5, index); // Localita': a = clifo.get(CLI_LOCCF); add_to_record(record, a, 30, index); // Provincia: a = comuni.get(COM_PROVCOM); add_to_record(record, a, 2, index); // Telefono: a = clifo.get(CLI_PTEL); a << clifo.get(CLI_TEL); add_to_record(record, a, 18, index); // Cellulare: a = clifo.get(CLI_PTEL2); a << clifo.get(CLI_TEL2); add_to_record(record, a, 18, index); // Fax: a = clifo.get(CLI_PFAX); a << clifo.get(CLI_FAX); add_to_record(record, a, 18, index); // Persona fisica: a = clifo.get(CLI_TIPOPERS)[0] == 'F' ? "S" : "N"; add_to_record(record, a, 1, index); // Sesso: a = clifo.get(CLI_SESSO); add_to_record(record, a, 1, index); // Nascita: a = clifo.get_date(CLI_DATANASC).date2ansi(); add_to_record(record, a, 8, index); // Luogo di nascita: comuni.zero(); comuni.put(COM_STATO, clifo.get(CLI_STATONASC)); comuni.put(COM_COM, clifo.get(CLI_COMNASC)); comuni.read(); a = comuni.get(COM_DENCOM); add_to_record(record, a, 30, index); // Provincia Nascita: a = comuni.get(COM_PROVCOM); add_to_record(record, a, 2, index); // Codice fiscale: a = clifo.get(CLI_COFI); add_to_record(record, a, 16, index); // Partita IVA: a = clifo.get(CLI_PAIV); add_to_record(record, a, 12, index); // Mastro: a = clifo.get(CLI_GRUPPO); a << clifo.get(CLI_CONTO); add_to_record(record, a, 20, index); // Partite: a = " "; add_to_record(record, a, 1, index); // Codice pagamento: a = clifo.get(CLI_CODPAG); add_to_record(record, a, 5, index); // Codice zona: a = cfven.get(CFV_CODZONA); add_to_record(record, a, 5, index); // Codice agente1: a = cfven.get(CFV_CODAG1); add_to_record(record, a, 5, index); // Codice Iva: a = cfven.get(CFV_ASSFIS); add_to_record(record, a, 5, index); // Codice Valuta: a = clifo.get(CLI_CODVAL); add_to_record(record, a, 5, index); // Codice Banca: a = clifo.get(CLI_CODABI); a << clifo.get(CLI_CODCAB); add_to_record(record, a, 10, index); // Primo mese: a = " "; add_to_record(record, a, 2, index); // Secondo mese: a = " "; add_to_record(record, a, 2, index); // Primo gg scadenze: a = " "; add_to_record(record, a, 2, index); // Secondo gg: a = " "; add_to_record(record, a, 2, index); // Codice Lingua: a = clifo.get(CLI_CODLIN); add_to_record(record, a, 5, index); // Conto corrente: a = clifo.get(CLI_NUMCC); add_to_record(record, a, 15, index); // Indirizzo e-mail: a = clifo.get(CLI_DOCMAIL); add_to_record(record, a, 50, index); // Ritenute: a = "N"; add_to_record(record, a, 1, index); // Codice tributo: a = " "; add_to_record(record, a, 4, index); // Codice tributo: a = " "; add_to_record(record, a, 4, index); // Categoria contabile : a = " "; add_to_record(record, a, 5, index); // Annotazioni: a = " "; add_to_record(record, a, 255, index); fout << record << '\n'; } } void TComariExport_app::export_parti(ofstream& fout) { const char* fields[] = { PART_ANNO, PART_NUMPART, PART_NRIGA, PART_TIPOCF, PART_SOTTOCONTO, PART_TIPOMOV, PART_TIPOPAG, PART_NREG, PART_NUMRIG, PART_DATAREG, PART_DATADOC, PART_DATAPAG, PART_NUMDOC, PART_REG, PART_PROTIVA, PART_CODCAUS, PART_SEZ, PART_IMPORTO, PART_IMPOSTA, PART_SPESE, PART_IMPTOTDOC, PART_RITENUTE, PART_RITSOC, PART_SEZABB, PART_ABBUONI, PART_SEZDIFCAM, PART_DIFFCAM, PART_GRUPPOCL, PART_CONTOCL }; const int dim_fields[] = { D_ANNO, D_NUMPART, D_NRIGA, D_TIPOC, D_SOTTOCONTO, D_TIPOMOV, D_TIPOPAG, D_NREG, D_NUMRIG, D_DATAREG, D_DATADOC, D_DATAPAG, D_NUMDOC, D_REG, D_PROTIVA, D_CODCAUS, D_SEZ, D_IMPORTO, D_IMPOSTA, D_SPESE, D_IMPTOTDOC, D_RITENUTE, D_RITSOC, D_SEZABB, D_ABBUONI, D_SEZDIFCAM, D_DIFFCAM, D_GRUPPOCL, D_CONTOCL }; TString4 last_game = ini_get_string(CONFIG_DITTA, "ps6215", "last_year_open_game", "2019"); const string year = (const char*)last_game; const int y = stol(year); if (y < 2000 || y > 2029) last_game = "2019"; ini_set_string(CONFIG_DITTA, "ps6215", "last_game", last_game); const int items = (int)(sizeof dim_fields / sizeof *dim_fields); TString sql; sql << "SELECT "; for (int i = 0; i < items - 1; ++i) sql << fields[i] << ", "; sql << fields[items - 1] << '\n'; sql << " FROM part WHERE CHIUSA<>'X' AND ANNO <=" << last_game << ";"; TSQL_recordset openpart(sql); if (!openpart.items()) message_box("Non ci sono partite aperte al %s da esportare.", (const char*)last_game); else if(openpart.move_first()) { TProgress_monitor bar(openpart.items(), "Esportazione Partite Aperte"); for(bool ok = true; ok; ok = openpart.move_next()) { if (!bar.add_status()) break; TFixed_record rec(items, dim_fields, fields); for (int i = 0; i < items; ++i) { if (openpart.column_info(i)._type == _datefld) { TString ansi; ansi << TDate(openpart.get(i).as_date()).date2ansi(); if(ansi != "0") // Butto le date "vuote" rec.set_str(i, ansi); } else if(i >= I_IMPORTO && i <= I_RITSOC || i == I_ABBUONI || i == I_DIFFCAM) // reali (non so perche' ma becca come reali anche gli interi...) rec.set_str(i, TString(openpart.get(i).as_real().string(18, 3, ' '))); else rec.set_str(i, openpart.get(i).as_string()); } fout << rec.get_line() << endl; } } else warning_box(TR("Impossibile leggere file partite aperte.")); } bool TComariExport_app::export_table(const short id) const { bool ok = false; ofstream fout; TString path = _fld_dest; const char* name, *name_file; switch (id) { default: case F_CLIFOR: name_file = "clifo.txt"; path << "\\" << name_file; fout.open(path, ios_base::out); if ((ok = fout.is_open())) { export_clifo(fout); fout.close(); } name = "Clienti Fornitori"; break; case F_PARTOPEN: name_file = "partiteaperte.txt"; path << "\\" << name_file; fout.open(path, ios_base::out); if ((ok = fout.is_open())) { export_parti(fout); fout.close(); } name = "Clienti Fornitori"; break; case F_PIANOCONTI: // Not implemented name_file = "pianoconti.txt"; path << "\\" << name_file; ok = true; name = "Piano dei Conti"; break; case F_MASTRI: // Not implemented name_file = "mastri.txt"; path << "\\" << name_file; ok = true; name = "Mastri"; break; } TString msg; msg << "Esportazione " << name << (ok ? " " : " non ") << "completata.\nFile: " << (ok ? path : name_file); if (ok) message_box(msg); else warning_box(msg); return ok; } bool TComariExport_app::create() { open_files(LF_CLIFO, LF_CFVEN, LF_COMUNI, 0); return TSkeleton_application::create(); } void TComariExport_app::main_loop() { const TFixed_string arg = argv(2); if(arg.starts_with("-a") || arg.starts_with("-A")) { const WINDOW task = TASK_WIN; xvt_vobj_set_visible(task, FALSE); export_all(); } else { TComariExport_mask msk; while (msk.run() == K_ENTER) { bool ok = false; _fld_dest = msk.get(F_FLDDEST); for (short i = F_CLIFOR; i <= F_MASTRI; ++i) { if (msk.get_bool(i)) export_table(i); } } } } int ps6215100(const int argc, char* argv[]) { TComariExport_app pe; pe.run(argc, argv, TR("Esportazione CO.MA.RI.")); return 0; }