diff --git a/src/bs/BeeStore - Analisi Interfaccia SW Terzi.doc b/src/bs/BeeStore - Analisi Interfaccia SW Terzi.doc index 575c3b2da..d9093dd2f 100644 Binary files a/src/bs/BeeStore - Analisi Interfaccia SW Terzi.doc and b/src/bs/BeeStore - Analisi Interfaccia SW Terzi.doc differ diff --git a/src/bs/bs0100.cpp b/src/bs/bs0100.cpp index bfbf66bd4..6bf246572 100644 --- a/src/bs/bs0100.cpp +++ b/src/bs/bs0100.cpp @@ -20,6 +20,7 @@ TParametri_mask::TParametri_mask(const char * n) : TAutomask(n) set(F_DATASOURCE, ini_get_string(CONFIG_DITTA, "BS", "DSN")); set(F_USER, ini_get_string(CONFIG_DITTA, "BS", "USR")); set(F_PASSWORD, decode(ini_get_string(CONFIG_DITTA, "BS", "PSW"))); + set(F_ORIGINE, ini_get_int(CONFIG_DITTA, "BS", "Origine", 2)); set(F_LOG, ini_get_string(CONFIG_DITTA, "BS", "Log")); } @@ -60,6 +61,7 @@ void TParametri_ditta::main_loop() ini_set_string(CONFIG_DITTA, "BS", "DSN", pm.get(F_DATASOURCE)); ini_set_string(CONFIG_DITTA, "BS", "USR", pm.get(F_USER)); ini_set_string(CONFIG_DITTA, "BS", "PSW", encode(pm.get(F_PASSWORD))); + ini_set_int(CONFIG_DITTA, "BS", "Origine", pm.get_int(F_ORIGINE)); ini_set_string(CONFIG_DITTA, "BS", "Log", pm.get(F_LOG)); message_box("Dati salvati correttamente!"); } diff --git a/src/bs/bs0100a.h b/src/bs/bs0100a.h index 022e87592..42d0e5d0f 100644 --- a/src/bs/bs0100a.h +++ b/src/bs/bs0100a.h @@ -1,4 +1,5 @@ #define F_DATASOURCE 101 #define F_USER 102 #define F_PASSWORD 103 -#define F_LOG 104 +#define F_ORIGINE 104 +#define F_LOG 105 diff --git a/src/bs/bs0100a.uml b/src/bs/bs0100a.uml index 4a77fa1f3..bcb26b5ff 100644 --- a/src/bs/bs0100a.uml +++ b/src/bs/bs0100a.uml @@ -6,7 +6,7 @@ ENDPAGE PAGE "Parametri Bee Store" 0 2 0 0 -GROUPBOX DLG_NULL 78 6 +GROUPBOX DLG_NULL 78 7 BEGIN PROMPT 1 1 "@bODBC" END @@ -33,9 +33,18 @@ BEGIN FIELD PSW END +LIST F_ORIGINE 1 +BEGIN + PROMPT 2 5 "Seleziona l'origine di Campo " + ITEM "1|1" + ITEM "2|2" + FIELD Origin +END + + STRING F_LOG 260 50 BEGIN - PROMPT 2 5 "File di log errori SQL " + PROMPT 2 6 "File di log errori SQL " FIELD Log END diff --git a/src/bs/bs0200.cpp b/src/bs/bs0200.cpp index d207830ae..721051476 100644 --- a/src/bs/bs0200.cpp +++ b/src/bs/bs0200.cpp @@ -148,7 +148,7 @@ typedef bool TFieldEvaluator(const TISAM_recordset& rec, const char* fldname, co class TBeeStore_sync : public TSkeleton_application { - TString16 _dsn; + TString _dsn; TString _usr; TString _psw; TFilename _sqlog; diff --git a/src/bs/bs0300.cpp b/src/bs/bs0300.cpp new file mode 100644 index 000000000..9a6d8d24f --- /dev/null +++ b/src/bs/bs0300.cpp @@ -0,0 +1,2226 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../mg/mglib.h" +#include "../cg/cglib01.h" +#include "../cg/cg2101.h" +#include "../ve/velib.h" +#include +#include + +#include "bs0.h" + +#include "../fe/felib.h" +#include "../ve/condv.h" +#include "../ve/rcondv.h" + +#include +#include +#include +#include +#include +#include + +#define BS_DTULTAGG "DtUltAgg" + +/////////////////////////////////////////////////////////// +// Utility +/////////////////////////////////////////////////////////// + +const TString my_origin() +{ + static const TString my_orig = ini_get_string(CONFIG_DITTA, "BS", "Origine", "2"); + return my_orig; +} + +const TString their_origin() +{ + static const TString their_orig(1, (ini_get_int(CONFIG_DITTA, "BS", "Origine", 1) == 1 ? 2 : 1) + '0'); + return their_orig; +} + +const TString clifo_add_note(TLocalisamfile& cfv, TString& note) +{ + TString codnote = cfv.get(CFV_CODNOTE); + // Parto da un valore altissimo! Prima di questa modifica la dimensione di questo campo era 2 + TLocalisamfile tabcom(LF_TABCOM); + static int cod = 0; + if (cod == 0) + { + TRectype n(LF_TABCOM); + n.put("COD", "NOT"); + if (n.read(tabcom, _isgteq) == NOERR) + { + // Vado a prendere l'ultimo valore in NOT + while (n.get("COD") == "NOT") + n.next(tabcom); + n.prev(tabcom); + cod = n.get_int("CODTAB") + 1; + } + else + cod = 1; + } + TRectype nota(LF_TABCOM); + nota.put("COD", "NOT"); + if (codnote.blank()) + { + codnote.cut(0) << cod++; + } + nota.put("CODTAB", codnote); + for (int i = 0; i <= 12; i++) + { + TString field = "S"; field << i; + nota.put(field, note.left(tabcom.curr().length(field))); + note.ltrim(tabcom.curr().length(field)); + if (note.blank()) + break; + } + nota.write_rewrite(tabcom); + return codnote; +} + +/////////////////////////////////////////////////////////// +// TBeeStore_cache +/////////////////////////////////////////////////////////// + +class TBeeStore_cache : TCache +{ +protected: + virtual TObject* key2obj(const char* key) + { + const char tipo = *key; + const long codice = atol(key+1); + return new TAnagrafica(LF_CLIFO, tipo, codice); + } + +public: + const TAnagrafica& anag(char tipo, long codice) + { + CHECKD((tipo == 'C' || tipo == 'F') && codice > 0L, "Codice cli/for non valido", codice); + TString8 key; key.format("%c%06ld", tipo, codice); + const TAnagrafica* a = (const TAnagrafica*)objptr(key); + return *a; + } + const TAnagrafica& anag(const TRectype& rec) + { + const char tipo = rec.get_char(CLI_TIPOCF); + const long codice = rec.get_long(CLI_CODCF); + return anag(tipo, codice); + } + const TAnagrafica& anag(const TISAM_recordset& rec) + { return anag(rec.cursor()->curr()); } +}; + +static TBeeStore_cache _anagr; + +/////////////////////////////////////////////////////////// +// TBeestore_bin +/////////////////////////////////////////////////////////// + +class TBeestore_bin : public TObject +{ +private: + std::maptables; + std::map>idSpool; + TString _dsn; + TString _usr; + TString _psw; + +public: + void addTable(const TString table, const TString key); + void put(const TString table, const TString id); + bool clean(); + void setConnection(const TString dsn, const TString usr, const TString psw); + TBeestore_bin() {} +}; + +void TBeestore_bin::addTable(const TString table, const TString key) +{ + tables.insert(std::pair(table, key)); +} + +void TBeestore_bin::put(const TString table, const TString id) +{ + if (idSpool.find(table) == idSpool.end()) + { + std::vector app; app.push_back(id); + idSpool.insert(std::pair>(table, app)); + } + else + { + idSpool[table].push_back(id); + } +} + +bool TBeestore_bin::clean() +{ + TODBC_recordset rcs(""); + rcs.connect(_dsn, _usr, _psw); + bool ok = true; + for (auto it = tables.begin(); it != tables.end() && ok; ++it) + { + TString query; + for (auto ij = idSpool[it->first].begin(); ij != idSpool[it->first].end(); ++ij) + { + query << "DELETE FROM [" << it->first << "] WHERE [" << it->second << "] = '" << *ij << "';\n"; + } + ok &= rcs.exec(query) == 1; + } + if (ok) + { + tables.clear(); + idSpool.clear(); + ok = rcs.commit() != -1; + } + return ok; +} + +void TBeestore_bin::setConnection(const TString dsn, const TString usr, const TString psw) +{ + _dsn = dsn; + _usr = usr; + _psw = psw; +} + +TBeestore_bin& mastroBin() +{ + TBeestore_bin* mosieurBinne = NULL; + if (mosieurBinne == NULL) + mosieurBinne = new TBeestore_bin; + return *mosieurBinne; +} + +/////////////////////////////////////////////////////////// +// TBeeStore_mask +/////////////////////////////////////////////////////////// + +class TBeeStore_mask : public TAutomask +{ +protected: + virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); + +public: + void autoload(); + void autosave() const; + + bool get_bool(const char* fld) + { TMask_field* f = find_by_fieldname(fld); return f ? f->get().full() : false; } + + TDate get_date(const char* fld) + { TMask_field* f = find_by_fieldname(fld); return TDate(f ? f->get() : EMPTY_STRING); } + + TBeeStore_mask() : TAutomask("bs0200a") { autoload(); } + ~TBeeStore_mask() { autosave(); } +}; + +bool TBeeStore_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) +{ + if (e == fe_modify && !o.empty()) + { + const TFieldref* fr = o.field(); + if (fr && fr->name() == "CODCAUSC") + { + // Configura righe aggiuntive causale corrispettivi + TRecord_array rcaus(o.get(), LF_RCAUSALI); + if (!rcaus.exist(15) && yesno_box(TR("Si desidera configurare la causale per il collegamento a BeeStore?"))) + { + const char* codice[] = { "BEECN", "BEEBM", "BEECC", "BEEAS", "BEEAL", NULL }; + const char* descr[] = { "Contanti", "Bancomat", "Carta di credito", "Assegni", "Altro", NULL }; + + TTable dpn("%DPN"); + for (int i = 0; codice[i]; i++) + { + dpn.put("CODTAB", codice[i]); + dpn.put("S0", descr[i]); + dpn.write(); + TRectype& row = rcaus.row(15+i, true); + row.put(RCA_CODDESC, codice[i]); + row.put(RCA_DESC, descr[i]); + } + rcaus.rewrite(); + TRectype caus(LF_CAUSALI); + caus.put(RCA_CODCAUS, o.get()); + caus.edit(); + } + } + } + return true; +} + +void TBeeStore_mask::autoload() +{ + // Carica i valori default dei parametri dal [bs] in ditta,ini + FOR_EACH_MASK_FIELD(*this, i, f) + { + const TFieldref* fr = f->field(); + if (fr != NULL) + f->set(ini_get_string(CONFIG_DITTA, "bs", fr->name())); + } +} + +void TBeeStore_mask::autosave() const +{ + // Salva i valori dei parametri in [bs] in ditta,ini + FOR_EACH_MASK_FIELD(*this, i, f) + { + const TFieldref* fr = f->field(); + if (fr != NULL) + ini_set_string(CONFIG_DITTA, "bs", fr->name(), f->get()); + } +} + +/////////////////////////////////////////////////////////// +// TBeeStore_sync +/////////////////////////////////////////////////////////// + +typedef bool TFieldEvaluator(const TISAM_recordset& rec, const char* fldname, const char* expr, TVariant& var); + +class TBeeStore_sync : public TSkeleton_application +{ + TString _dsn; + TString _usr; + TString _psw; + TFilename _sqlog; + TLog_report* _log; + bool hasConai; + bool enableDelete; + +private: + const TString& comune(const TRecordset& recset, const char* fld_cap, const char* fld_den) const; + bool split_phone(const TRecordset& odbc, const char* number, TIsamfile& clifo, const char* pre, const char* num) const; + void load_clifo(char tipocf); + void save_clifo(int cfmask, const TDate& dal, const TDate& al); + void add_rmov(TMovimentoPN& mov, const real& importo, const TCausale& caus, const char* cod) const; + +protected: + bool save_and_delete_movmag(TMov_mag*& doc) const; + bool save_and_delete_doc(TDocumento*& doc) const; + + void load_their_origine(TISAM_recordset& out_set, const char* in_table, const TString_array& pairs); + void save_my_origine(TISAM_recordset& in_set, const char* out_table, const TString_array& pairs, TFieldEvaluator* feval = NULL); + + void sync_table(TISAM_recordset& in_set, const char* out_table, + const TString_array& pairs); + void sync_table(const char* in_table, const char* out_table, + const TString_array& fields, const TDate& dal, const TDate& al); + void sync_table(const int logicnum, const char* out_table, + const TString_array& fields, const TDate& dal, const TDate& al); + + void sync_iva (const TDate& dal, const TDate& al); + void sync_ums (const TDate& dal, const TDate& al); + void sync_lines (const TDate& dal, const TDate& al); + void sync_catmer (const TDate& dal, const TDate& al); + void sync_val (const TDate& dal, const TDate& al); + void sync_anamag (const TDate& dal, const TDate& al); + void sync_barcode (const TDate& dal, const TDate& al); + void sync_corrisp (const TDate& dal, const TDate& al); + void sync_mov(int tipotestata, const TDate& dal, const TDate& al); + void sync_scontrini(const TDate& dal, const TDate& al) { sync_mov(3, dal, al);} + void sync_doc (const TDate& dal , const TDate& al); + void sync_carscar (const TDate& dal, const TDate& al) { sync_mov(1, dal, al);} + void sync_generici (const TDate& dal , const TDate& al) { sync_mov(4, dal, al);} + void sync_clifo (int cfmask, const TDate& dal, const TDate& al); + void sync_listino (const TString& listino); + +public: + virtual bool create(); + virtual void main_loop(); +}; + +// Converte una TDate in una data SQL +const TString& date2sql(const TDate& d, int hour = 0) +{ + TString& tmp = get_tmp_string(); + if (d.ok()) + { + tmp.format("'%04d-%02d-%02d", d.year(), d.month(), d.day()); + switch (hour) + { + case 1: + tmp << "T00:00:00.000'"; + break; + case 2: + tmp << "T23:59:59.999'"; + break; + default: + case 0: + tmp << "'"; + } + } + else + tmp = "NULL"; + return tmp; +} + +// Coverte un qualsiasi TVariant in stringa SQL +const TString& var2sql(const TVariant& var) +{ + TString& tmp = get_tmp_string(); + switch (var.type()) + { + case _nullfld: + tmp = "NULL"; + break; + case _boolfld: + tmp = var.as_bool() ? "1" : "0"; + break; + case _datefld: + tmp = date2sql(var.as_date()); + break; + case _intfld: + case _longfld: + var.as_string(tmp); + break; + case _realfld: + if (var.is_empty()) + tmp = "0"; + else + { + tmp = var.as_real().string(0, 2); + if (tmp.ends_with(".00")) + tmp.rtrim(3); + } + break; + default: + { + var.as_string(tmp); + const int pos = tmp.find('\''); + if (pos >= 0) + { + for (int i = tmp.len()-1; i >= pos; i--) + if (tmp[i] == '\'') tmp.insert("'", i); + } + tmp.insert("'"); + tmp << "'"; + } + break; + } + return tmp; +} + +// Coverte una qualsiasi espressione in stringa SQL +const TString& expr2sql(const TISAM_recordset& set, const char* expr) +{ + TVariant var; + TExpression e(expr, _strexpr, true); + if (e.numvar() == 0) + { + if (real::is_natural(expr)) + var = atoi(expr); + else + var = expr; + } else + if (e.numvar() == 1 && xvt_str_same(e.varname(0), expr)) + { + var = set.get(expr); + } + else + { + for (int v = e.numvar()-1; v >= 0; v--) + { + var = set.get(e.varname(v)); + if (var.is_real() || var.is_bool()) + e.setvar(v, var.as_real()); + else + e.setvar(v, var.as_string()); + } + var = e.as_string(); + } + return var2sql(var); +} + +// Carica da BeeStore i record con Origine=their_origin(), cioè generati da lui ed eventualmente aggiorna i corrispondenti in Campo +void TBeeStore_sync::load_their_origine(TISAM_recordset& out_set, const char* in_table, const TString_array& pairs) +{ + TString str(255); + str << "SELECT "; + FOR_EACH_ARRAY_ROW(pairs, f, row) + str << row->get(0) << ','; + str.rtrim(1); // toglie ultima virgola + str << "\nFROM " << in_table << " WHERE (Origine=" << their_origin() << ");"; + + TODBC_recordset odbc(str); + odbc.connect(_dsn, _usr, _psw); + const TRecnotype n = odbc.items(); + if (n > 0) + { + TLocalisamfile& file = out_set.cursor()->file(); + const RecDes& rd = file.curr().rec_des(); + TToken_string key_fields; + for (int i = 0; i < rd.Ky->NkFields; i++) + { + const int nf = rd.Ky[0].FieldSeq[i] % MaxFields; + key_fields.add(rd.Fd[nf].Name); + } + + str.format(TR("Importazione %ld record dalla tabella %s"), n, in_table); + _log->log(0, ""); + _log->log(0, str); + + TProgress_monitor pi(n, str); + for (bool ok = odbc.move_first(); ok; ok = odbc.move_next()) + { + file.zero(); + TString80 cfld, bfld; // Campo field, BeeStore field e cut field + int ffld, tfld; + FOR_EACH_ARRAY_ROW(pairs, p, row) + { + bfld = row->get(0); + cfld = row->get(); + ffld = row->get_int(); ffld--; + tfld = row->get_int(); tfld--; + const int pos = key_fields.get_pos(cfld); + if (pos >= 0) + { + const TVariant& var = odbc.get(bfld); + if (!var.is_null()) + { + if(tfld > 0) + file.put(cfld, var.as_string().mid(ffld, tfld-ffld)); + else + file.put(cfld, var.as_string()); + } + if (pos == key_fields.items()-1) + break; + } + } + + int err = file.read(_isequal, _lock); + if (err == NOERR) + { + bool dirty = false; + const TDate dataagg = file.get(CLI_DATAAGG); + TDate dtultagg = odbc.get(BS_DTULTAGG).as_date(); + if (!dtultagg.ok()) dtultagg = TODAY; + + str = "record"; + FOR_EACH_TOKEN(key_fields, f) + str << ' ' << file.get(f); + + if (dtultagg >= dataagg) + { + FOR_EACH_ARRAY_ROW(pairs, r,row) + { + bfld = row->get(0); + cfld = row->get(); + ffld = row->get_int(); ffld--; + tfld = row->get_int(); tfld--; + + if (cfld[0] >= 'A' && cfld.find("->") < 0 && key_fields.get_pos(cfld) < 0) // Aggiorno solo i campi NON chiave + { + const TString& vec = file.get(cfld); + const TString& nov = odbc.get(bfld).as_string(); + if (nov != vec) + { + if (!dirty) + str << ' ' << bfld << "='" << nov << '\''; + if (tfld > 0) + file.put(cfld, nov.mid(ffld, tfld - ffld)); + else + file.put(cfld, nov); + dirty = true; + } + } + } + if (dirty) + { + TRectype& rec = file.curr(); + if (rec.exist(CLI_UTENTE)) + rec.put(CLI_UTENTE, "BEESTORE"); + if (rec.exist(CLI_DATAAGG)) + rec.put(CLI_DATAAGG, dtultagg); + } + else + str << " Nessuna variazione pertinente"; + } + else + str << " Data di ultimo aggiornamento obsoleta"; + if (dirty) + { + if (file.rewrite() == 0) + _log->log(1, str); + else + { + TString80 err; err << TR("ERRORE ") << err << TR(" aggiornando il "); + str.insert(err); + _log->log(2, str); + } + } + else + { + _log->log(0, str); + file.reread(_unlock); + } + } else + if (err == _iskeynotfound) + { + file.zero(); + FOR_EACH_ARRAY_ROW(pairs, r,row) + { + bfld = row->get(0); + cfld = row->get(); + ffld = row->get_int(); ffld--; + tfld = row->get_int(); tfld--; + if (cfld[0] >= 'A' && cfld.find("->")) + { + const TString& nov = odbc.get(bfld).as_string(); + if (tfld > 0) + file.put(cfld, nov.mid(ffld, tfld - ffld)); + else + file.put(cfld, nov); + } + } + if (file.write() == 0) + _log->log(1, str); + else + { + TString80 msg; msg << TR("ERRORE ") << err << TR(" inserendo il "); + str.insert(msg); + _log->log(2, str); + } + } + } + if (ini_get_bool(CONFIG_DITTA, "BS", "EmptyOnImp")) + { + str.cut(0) << "DELETE FROM " << in_table << " WHERE Origine=" << their_origin() << ";"; + odbc.exec(str); + } + } +} + +void TBeeStore_sync::save_my_origine(TISAM_recordset& in_set, const char* out_table, const TString_array& fields, TFieldEvaluator* fval) +{ + if (!ini_get_bool(CONFIG_DITTA, "BS", "EnableExp")) + return; + const TRecnotype n = in_set.items(); + TString str(255); + TODBC_recordset odbc(str); + odbc.connect(_dsn, _usr, _psw); + str.cut(0) << "DELETE FROM " << out_table << " WHERE Origine=" << my_origin() << ";"; + odbc.exec(str); + + str.format(TR("Esportazione %ld record in %s"), n, out_table); + _log->log(0, ""); + _log->log(0, str); + + const TRectype& curr = in_set.cursor()->curr(); + + TProgress_monitor pi(n, str); + for (bool ok = in_set.move_first(); ok; ok = in_set.move_next()) + { + + str.cut(0) << "INSERT INTO " << out_table << "\n("; + FOR_EACH_ARRAY_ROW(fields, sr, srow) + str << (sr ? ", " : "") << srow->get(0); + str << ", Origine, Errore, " BS_DTULTAGG; + str << ")\nVALUES ("; + + FOR_EACH_ARRAY_ROW(fields, ir, irow) + { + if (ir) str << ", "; + if (fval) + { + const char* fname = irow->get(0); // BeeStore field name + const char* fexpr = irow->get(); // Campo expression + TVariant var; + if (fval(in_set, fname, fexpr, var)) + { + str << var2sql(var); + continue; + } + } + + const TFixed_string cfld = irow->get(1); + if (cfld.find("SCONTO")>=0) + { + real sconto; + const TString& exp = curr.get(cfld); + if (exp.full()) + { + if (real::is_natural(exp)) + sconto = real(exp); + else + { + TString80 goodexp; real val_perc; + if (scontoexpr2perc(exp, false, goodexp, val_perc) && val_perc != UNO) + { + sconto = CENTO - CENTO*val_perc; + sconto.round(5); + } + } + } + str << var2sql(sconto); + } else + if ((cfld[0] >= 'A' && cfld[0] <= 'Z') || cfld.find("->") > 0) + str << expr2sql(in_set, cfld); + else + str << cfld; + } + + str << ", 2, 0, GETDATE()"; + str << ");"; + + const long err = odbc.exec(str); + if (err <= 0) + { + TParagraph_string par(str, 75); + if (par.items() > 4) + { + str.cut(0); + bool values = false; + FOR_EACH_TOKEN(par, s) + { + if (str.full() && !values) + { + values = _strnicmp(s, "VALUES", 6) == 0; + if (!values) + continue; + } + str << s << '\n'; + } + str.trim(); + } + _log->log(1, str); + str.format("SQL error %d", abs(err)); + _log->log(2, str); + } + + if (!pi.add_status()) + break; + } + + odbc.exec("COMMIT;"); +} + +void TBeeStore_sync::sync_table(TISAM_recordset& in_set, const char* out_table, const TString_array& fields) +{ + load_their_origine(in_set, out_table, fields); + save_my_origine(in_set, out_table, fields); +} + +static TString& build_query(const char* table, const TDate& dal, const TDate& al) +{ + TString& q = get_tmp_string(); + q << "USE " << table; + if (dal.ok() || al.ok()) + q << "SELECT BETWEEN(DATAAGG," << dal.date2ansi() << ',' << al.date2ansi() << ")"; + return q; +} + +static TString& build_query(const int logicnum, const TDate& dal, const TDate& al) +{ + const TRectype rec(logicnum); + TString& q = get_tmp_string(); + q << "USE " << logicnum; + + if (rec.exist(CLI_UTENTE)) + q << " SELECT (UTENTE!=\"BEESTORE\")"; + + if ((dal.ok() || al.ok()) && rec.exist(CLI_DATAAGG)) + { + if (q.find(" SELECT ") < 0) + q << " SELECT "; + else + q << "&&"; + q << "(BETWEEN(DATAAGG," << dal.date2ansi() << ',' << al.date2ansi() << "))"; + } + return q; +} + + +void TBeeStore_sync::sync_table(const char* table, const char* out_table, + const TString_array& fields, const TDate& dal, const TDate& al) +{ + const TString& q = build_query(table, dal, al); + TISAM_recordset set(q); + sync_table(set, out_table, fields); +} + +void TBeeStore_sync::sync_table(const int logicnum, const char* out_table, + const TString_array& fields, const TDate& dal, const TDate& al) +{ + const TString& q = build_query(logicnum, dal, al); + TISAM_recordset set(q); + sync_table(set, out_table, fields); +} + +void TBeeStore_sync::sync_ums(const TDate& dal, const TDate& al) +{ + TString_array fields; + fields.add("CodUntMis|CODTAB"); + fields.add("DSUntMis|S0"); + sync_table("%UMS", "tieUntMisura", fields, dal, al); +} + +void TBeeStore_sync::sync_iva(const TDate& dal, const TDate& al) +{ + TString_array fields; + fields.add("CodIva|CODTAB"); + fields.add("CodIvaSt|CODTAB"); + fields.add("DSIva|S0"); + fields.add("Aliquota|R0"); + + sync_table("%IVA", "tieIva", fields, dal, al); +} + +void TBeeStore_sync::sync_lines(const TDate& dal, const TDate& al) +{ + TString_array fields; + fields.add("CodLinea|CODTAB"); + fields.add("DSLinea|S0"); + + TString query = build_query("GMC", dal, al); + if (query.find("SELECT") < 0) + query << " SELECT "; + else + query << "&&"; + query << "(CODTAB?='???')"; + + TISAM_recordset lin(query); + sync_table(lin, "tieLineeArt", fields); +} + +void TBeeStore_sync::sync_catmer(const TDate& dal, const TDate& al) +{ + TString_array fields; + fields.add("CodCategoriaMerceologica|CODTAB"); + fields.add("DSCategoriaMerceologica|S0"); + fields.add("CodTipoEtichetta|''"); + + sync_table("GMC", "tieCategorieMerceologiche", fields, dal, al); +} + +void TBeeStore_sync::sync_anamag(const TDate& dal, const TDate& al) +{ + TString_array fields; + fields.add("CodPadre|" ANAMAG_CODART); + fields.add("DSArticolo|" ANAMAG_DESCR); + fields.add("DSArticoloAgg|" ANAMAG_DESCRAGG "|1|70"); + fields.add("CodUntMagazzino|49->UM"); + fields.add("CodIva|" ANAMAG_CODIVA); + fields.add("CodLinea|" ANAMAG_GRMERC "|1|3"); + fields.add("CodCategMerceologica|" ANAMAG_GRMERC); + fields.add("Bloccato|" ANAMAG_SOSPESO); + + TString query = build_query(LF_ANAMAG, dal, al); + query << "\nJOIN " << LF_UMART << " INTO CODART==CODART"; + + TISAM_recordset art(query); + sync_table(art, "tieArticoli", fields); + + // Controllo se esistono varianti e le aggiungo + query.cut(0) << "SELECT * FROM tieArtVarianti where origine=" << their_origin(); + TODBC_recordset odbc(query); + odbc.connect(_dsn, _usr, _psw); + + // Apro codcorr per aggiungere i codici dei clienti + TLocalisamfile ccor(LF_CODCORR); + TRectype rccor(LF_CODCORR); + for (bool go = odbc.move_first(); go; go = odbc.move_next()) + { + // Lavoro sul file ISAM, più veloce + // Azzero + ccor.first(); // Useless?? + rccor.zero(); + bool add = true; + int riga = 1; + rccor.put(CODCORR_CODART, odbc.get("CodPadre").as_string()); + rccor.put(CODCORR_NRIGA, riga); + if (ccor.read(rccor, _isequal) == NOERR) + { + TString a = rccor.get(CODCORR_CODART); + TString b = odbc.get("CodPadre").as_string(); + while (add && rccor.get(CODCORR_CODART) == odbc.get("CodPadre").as_string()) + { + riga = rccor.get_int(CODCORR_NRIGA); + add = rccor.get(CODCORR_CODARTALT) != odbc.get("CodArticolo").as_string(); + rccor.next(ccor); + } + } + if (add) + { + rccor.zero(); + rccor.put(CODCORR_CODART, odbc.get("CodPadre").as_string()); + rccor.put(CODCORR_NRIGA, riga++); + rccor.put(CODCORR_CODARTALT, odbc.get("CodArticolo").as_string()); + ccor.write(rccor); + } + } + + // Conai + if (hasConai) + { + // Apro anamag per aggiungere le informazioni sugli articoli + TLocalisamfile art(LF_ANAMAG); + TRectype rart(LF_ANAMAG); + query.cut(0) << "SELECT * FROM tieArtCONAI where origine=" << their_origin(); + odbc.exec(query); + for (bool go = odbc.move_first(); go; go = odbc.move_next()) + { + art.first(); // Useless?? + rart.zero(); + rart.put(ANAMAG_CODART, odbc.get("Cod_PK").as_string()); + if (rart.read(art, _isequal) == NOERR) + { + static TString catCON; + // Metodo del cazzo, format crasha e non ho tempo, magari in un futuro sistemarlo (se non ho visto male funziona solo su linux) + TString a = odbc.get("CatAC").as_string().left(4); a.lpad(4); + TString b = odbc.get("CatAL").as_string().left(4); b.lpad(4); + TString c = odbc.get("CatCA").as_string().left(4); c.lpad(4); + TString d = odbc.get("CatLE").as_string().left(4); d.lpad(4); + TString e = odbc.get("CatPL").as_string().left(4); e.lpad(4); + TString f = odbc.get("CatVE").as_string().left(4); f.lpad(4); + catCON.cut(0) << a << b << c << d << e << f; + + /* + catCON.format("%4 s%4 s%4 s%4 s%4 s%4 s", + odbc.get("CatAC").as_string().left(4), // Categoria Acciaio + odbc.get("CatAL").as_string().left(4), // Categoria Alluminio + odbc.get("CatCA").as_string().left(4), // Categoria Carta + odbc.get("CatLE").as_string().left(4), // Categoria Legno + odbc.get("CatPL").as_string().left(4), // Categoria Plastica + odbc.get("CatVE").as_string().left(4) // Categoria Vetro + ); + */ + rart.put(ANAMAG_CONAISC, catCON); + rart.put(ANAMAG_CONACC, odbc.get("PesoAC").as_real()); // Peso Acciaio + rart.put(ANAMAG_CONALL, odbc.get("PesoAL").as_real()); // Peso Alluminio + rart.put(ANAMAG_CONCAR, odbc.get("PesoCA").as_real()); // Peso Carta + rart.put(ANAMAG_CONLEG, odbc.get("PesoLE").as_real()); // Peso Legno + rart.put(ANAMAG_CONPLA, odbc.get("PesoPL").as_real()); // Peso Plastica + rart.put(ANAMAG_CONVET, odbc.get("PesoVE").as_real()); // Peso Vetro + art.rewrite(rart); + } + else + // EROR! EROR! + { + bool tolla = true; + } + } + } + + if (ini_get_bool(CONFIG_DITTA, "BS", "EnableExp")) + { + fields.destroy(); + fields.add("CodArticolo|" ANAMAG_CODART); + fields.add("CodPadre|" ANAMAG_CODART); + save_my_origine(art, "tieArtVarianti", fields); + } +} + +void TBeeStore_sync::sync_barcode(const TDate& dal, const TDate& al) +{ + TString_array fields; + fields.add("CodArticolo|" ANAMAG_CODART); + fields.add("BarCode|" ANAMAG_DESCR); + + TString str(255); + str << "SELECT "; + FOR_EACH_ARRAY_ROW(fields, f, row) + str << row->get(0) << ','; + str.rtrim(1); // toglie ultima virgola + str << "\nFROM tieArtBarCode WHERE (Origine= " << their_origin() << ");"; + + TODBC_recordset odbc(str); + odbc.connect(_dsn, _usr, _psw); + const TRecnotype n = odbc.items(); + if (n > 0) + { + TProgress_monitor pi(n, "Importazione codici a barre"); + for (bool go = odbc.move_first(); go; go = odbc.move_next()) + { + const TCodice_articolo ca = odbc.get("CodArticolo").as_string(); + const TCodice_articolo bc = odbc.get("BarCode").as_string(); + int tipo = 0; + switch (bc.len()) + { + case 8: tipo = 8; break; + case 13: tipo = 1; break; + default: break; + } + if (tipo) + { + TRecord_array codcor(ca, LF_CODCORR); + int n = 0; + for (n = codcor.last_row(); n > 0; n = codcor.pred_row(n)) + { + const TRectype& row = codcor.row(n); + if (row.get("CODARTALT") == bc && row.get_int("TIPO") == tipo) + break; // trovato! + } + if (n <= 0) + { + TRectype& row = codcor.row(-1, true); // Add new row + row.put("CODARTALT", bc); + row.put("TIPO", tipo); + codcor.rewrite(); + } + } + if (!pi.add_status()) + break; + } + } +} + + + static bool ClifoEvaluator(const TISAM_recordset& rec, const char* fldname, const char* expr, TVariant& var) +{ + const TAnagrafica& a = _anagr.anag(rec); + + if (xvt_str_same(fldname, "Cod_PK")) + { + TLocalisamfile& cfv = rec.cursor()->file(LF_CFVEN); + TString80 codprcf = cfv.get(CFV_CODPRCF); + if (codprcf.blank() || codprcf[0] == 'C') // Anagrafica gestita da Campo + { + const char t = rec.get(CLI_TIPOCF).as_string()[0]; + const long c = rec.get(CLI_CODCF).as_int(); + TString8 cod_pk; cod_pk.format("C%06ld%c", c, t); + if (cod_pk != codprcf) + { + cfv.put(CFV_CODPRCF, codprcf = cod_pk); + cfv.rewrite(); + } + } + var = codprcf; + return true; + } + if (xvt_str_same(fldname, "Cognome")) + { + if (a.fisica()) + var = a.cognome(); + return true; + } + if (xvt_str_same(fldname, "Nome")) + { + if (a.fisica()) + var = a.nome(); + return true; + } + if (xvt_str_same(fldname, "Indirizzo")) + { + TString ind; + ind = a.via_residenza(); + if (ind.full()) + { + const TString& civ = a.civico_residenza(); + if (civ.full()) ind << ',' << civ; + } + const TString& loc = a.localita_residenza(); + if (loc.full()) ind << ',' << loc; + ind.strip_double_spaces(); + var = ind; + return true; + } + if (xvt_str_same(fldname, "Citta")) + { + var = a.comune_residenza(); + return true; + } + if (xvt_str_same(fldname, "Provincia")) + { + var = a.provincia_residenza(); + return true; + } + if (xvt_str_same(fldname, "ComuneNascita")) + { + var = a.comune_nascita(); + return true; + } + if (xvt_str_same(fldname, "PVNascita")) + { + var = a.provincia_nascita(); + return true; + } + if (xvt_str_same(fldname, "Telefono") || xvt_str_same(fldname, "Cellulare") || xvt_str_same(fldname, "CellulareSMS")) + { + const char* suff = (*fldname == 'C') ? (strlen(fldname)>9 ? "3" : "2") : ""; + TString8 pref; pref << "PTEL" << suff; + TString80 tele; tele << "TEL" << suff; + TString80 str; rec.get(pref).as_string(str); str << ' ' << rec.get(tele).as_string(); + str.strip_double_spaces(); + char* s = str.get_buffer(); + for (const char* f = s; *f; f++) + { + if (*f == ' ' || (*f >= '0' && *f <= '9')) + { + if (f > s) *s = *f; + s++; + } + } + *s = '\0'; + } + + if (xvt_str_same(fldname, "Tipo")) + { + var = a.fisica() ? 1 : 2; + return true; + } + if (xvt_str_same(fldname, "Cliente")) + { + const char tipocf = rec.get(CLI_TIPOCF).as_string()[0]; + var = tipocf == 'C'; + return true; + } + if (xvt_str_same(fldname, "Fornitore")) + { + const char tipocf = rec.get(CLI_TIPOCF).as_string()[0]; + var = tipocf == 'F'; + return true; + } + if (_strnicmp(fldname,"Cli_",4) == 0) + { + const char tipocf = rec.get(CLI_TIPOCF).as_string()[0]; + return tipocf != 'C'; + } + if (_strnicmp(fldname,"For_",4) == 0) + { + const char tipocf = rec.get(CLI_TIPOCF).as_string()[0]; + return tipocf != 'F'; + } + + return false; +} + +const TString& TBeeStore_sync::comune(const TRecordset& recset, const char* fld_cap, const char* fld_den) const +{ + TString8 cap; if (fld_cap && *fld_cap) cap = recset.get(fld_cap).as_string().left(5); + TString80 den; if (fld_den && *fld_den) den = recset.get(fld_den).as_string(); + return ::cap2comune(cap, den); +} + +bool TBeeStore_sync::split_phone(const TRecordset& odbc, const char* number, TIsamfile& clifo, const char* pre, const char* num) const +{ + TString pn = odbc.get(number).as_string(); + if (pn.full()) + { + pn.strip_double_spaces(); + const int maxpref = clifo.curr().length(pre); + int split = -1; + for (int i = 0; pn[i] && i <= maxpref; i++) + { + if (!isdigit(pn[i])) + { + split = i; + break; + } + } + + if (split > 1) + { + clifo.put(pre, pn.left(split)); + clifo.put(num, pn.mid(split+1)); + } + else + { + clifo.put(pre, ""); + clifo.put(num, pn); + } + } + return pn.full(); +} + +void TBeeStore_sync::load_clifo(char tipocf) +{ + TString str(255); + str << "SELECT * FROM tieAnagCFP WHERE (Origine=" << their_origin() << ")AND"; + str << '(' << (tipocf == 'F' ? "Fornitore" : "Cliente") << "=1);"; + + TFast_isamfile clifo(LF_CLIFO); + + TODBC_recordset odbc(str); + odbc.connect(_dsn, _usr, _psw); + const TRecnotype n = odbc.items(); + + str.cut(0) << TR("Importazione ") << (tipocf == 'F' ? TR("Fornitori") : TR("Clienti")); + TProgress_monitor pi(n, str); + for (bool ok = odbc.move_first(); ok; ok = odbc.move_next()) + { + long codcf = odbc.get(tipocf == 'F' ? "For_CodFor" : "Cli_CodCG").as_int(); + TLocalisamfile cfv(LF_CFVEN); + cfv.put(CFV_TIPOCF, tipocf); + cfv.put(CFV_CODCF, codcf); + if (cfv.read(_isequal) != NOERR) + { + cfv.zero(); + cfv.put(CFV_TIPOCF, tipocf); + cfv.put(CFV_CODCF, codcf); + } + if (codcf <= 0) + { + const TString& cod_pk = odbc.get("Cod_PK").as_string(); + if (!ini_get_bool(CONFIG_DITTA, "BS", "ClifoDC") || (cod_pk.len() == 8 && cod_pk[7] == tipocf)) // Prima era solo per i clienti, proviamoci sempre! + codcf = atol(cod_pk.mid(1,6)); + } + + if (codcf > 0) + { + clifo.put(CLI_TIPOCF, tipocf); + clifo.put(CLI_CODCF, codcf); + if (clifo.read(_isequal) != NOERR) + { + clifo.zero(); + clifo.put(CLI_TIPOCF, tipocf); + clifo.put(CLI_CODCF, codcf); + } + } + else + { + codcf = 1L; + if (tipocf == 'F') + { + if (clifo.last() == NOERR && clifo.get_char(CLI_TIPOCF)=='F') + codcf += clifo.get_long(CLI_CODCF); + } + else + { + clifo.put(CLI_TIPOCF, 'F'); + clifo.put(CLI_CODCF, 0); + if (clifo.read(_isgteq) == NOERR) + { + if (clifo.prev() == NOERR && clifo.get_char(CLI_TIPOCF)=='C') + codcf += clifo.get_long(CLI_CODCF); + } + } + clifo.zero(); + clifo.put(CLI_TIPOCF, tipocf); + clifo.put(CLI_CODCF, codcf); + clifo.write(); + + TString8 codprcf; codprcf.format("C%06ld%c", codcf, tipocf); + cfv.put(CFV_CODPRCF, codprcf); + } + clifo.put(CLI_RAGSOC, odbc.get("RagSoc").as_string()); + + const int tipo = odbc.get("Tipo").as_int(); // 1=Fisica; 2=Giuridica; 3=Altro + if (tipo == 1) + { + clifo.put(CLI_SESSO, odbc.get("Sesso").as_string()); + clifo.put(CLI_DATANASC, odbc.get("DTNascita").as_date()); + clifo.put(CLI_COMNASC, comune(odbc, "", "ComuneNascita")); + clifo.put(CLI_TIPOPERS, 'F'); + } + else + clifo.put(CLI_TIPOPERS, 'G'); + + TToken_string indirizzo(odbc.get("Indirizzo").as_string(), ','); + TString ind = indirizzo.get(0); + TString civ = indirizzo.get(); + TString loc = indirizzo.get(); + if (civ.len() > 10) + { + if (loc.full()) + ind << ' ' << civ; + else + loc = civ; + civ.cut(0); + } + + clifo.put(CLI_INDCF, ind.left(50)); + clifo.put(CLI_CAPCF, odbc.get("Cap").as_string()); + + // Stato + TString statoISO = odbc.get("CodStato").as_string(), stato = ""; + if (statoISO.empty()) + statoISO = "IT"; + clifo.put(CLI_STATOPAIV, statoISO); + + // Se lo stato no è Italia devo fare una ricerca scomoda e lenta in %STA + if (statoISO != "IT") + { + TRelation relCom(LF_TABCOM); + TRectype& partCom = relCom.curr(); + partCom.zero(); + partCom.put("COD", "STA"); + TCursor cur(&relCom, "", 1, &partCom, &partCom); + for(cur = 0; cur.pos() < cur.items(); ++cur) + if (cur.curr().get("S10") == statoISO) + { + stato = cur.curr().get("CODTAB"); + break; + } + } + clifo.put(CLI_STATOCF, stato); + + // Comune + TString comune; + int errComuni; + TLocalisamfile isamComuni(LF_COMUNI); + + comune = odbc.get("Citta").as_string(); + + isamComuni.put("STATO", stato); + isamComuni.put("COM", comune); + errComuni = isamComuni.read(_isequal); + + // Se non lo trovo cambio la chiave e provo a cercarlo per Descrizione + if (errComuni != NOERR) + { + isamComuni.zero(); + isamComuni.setkey(2); + isamComuni.put("DENCOM", comune.upper()); + errComuni = isamComuni.read(_isequal); + comune = errComuni == NOERR ? isamComuni.get("COM") : ""; + } + clifo.put(CLI_COMCF, comune); + + + split_phone(odbc, "Telefono", clifo, CLI_PTEL, CLI_TEL); + split_phone(odbc, "Cellulare", clifo, CLI_PTEL2, CLI_TEL2); + split_phone(odbc, "CellulareSMS", clifo, CLI_PTEL3, CLI_TEL3); + clifo.put(CLI_MAIL, odbc.get("EMail").as_string()); + + clifo.put(CLI_MAIL, odbc.get("RaggDoc").as_int() == 1); + if (hasConai) + { + cfv.put(CFV_DATAECONAI, odbc.get("CNDataEs").as_date()); + cfv.put(CFV_ESACC, odbc.get("CNEsac").as_string()); // Esenzione Acciaio + cfv.put(CFV_ESALL, odbc.get("CNEsal").as_string()); // Esenzione Alluminio + cfv.put(CFV_ESCAR, odbc.get("CNEsca").as_string()); // Esenzione Carta + cfv.put(CFV_ESPLA, odbc.get("CNEspl").as_string()); // Esenzione Plastica + cfv.put(CFV_ESLEG, odbc.get("CNEsle").as_string()); // Esenzione Legno + cfv.put(CFV_ESVET, odbc.get("CNEsve").as_string()); // Esenzione Vetro + + // So bad is so good! + TString prodConai; + prodConai << odbc.get("CNPac").as_int() == 1 ? "X" : " "; // Produttore Acciaio + prodConai << odbc.get("CNPal").as_int() == 1 ? "X" : " "; // Produttore Alluminio + prodConai << odbc.get("CNPca").as_int() == 1 ? "X" : " "; // Produttore Carta + prodConai << odbc.get("CNPpl").as_int() == 1 ? "X" : " "; // Produttore Plastica + prodConai << odbc.get("CNPle").as_int() == 1 ? "X" : " "; // Produttore Legno + prodConai << odbc.get("CNPve").as_int() == 1 ? "X" : " "; // Produttore Vetro + cfv.put("PRODCONAI", prodConai); + } + + TLocalisamfile cfb(LF_CFBAN); + cfb.put("TIPOCF", tipocf); + cfb.put("CODCF", codcf); + cfb.put("TIPOBAN", "V"); + cfb.put("NRIGA", 1); + TString cin, abi, cab, contcor, iban; + if (tipocf == 'C') + { + abi = odbc.get("Cli_Abi").as_string(); + cab = odbc.get("Cli_Cab").as_string(); + contcor = odbc.get("Cli_ContoCorr").as_string(); + } + else + { + abi = odbc.get("For_Abi").as_string(); + cab = odbc.get("For_Cab").as_string(); + contcor = odbc.get("For_ContoCorr").as_string(); + } + int err = 1; + // Calcolo il CIN + TString msg, bban; + bban << "#" << abi << cab << contcor; + for (char cin = 'A'; cin <= 'Z' && err == 1; cin++) + { + bban[0] = cin; + err = bban_check(bban, msg); + if (err == 0) + { + cin = bban[0]; + break; + } + } + // Calcolo l'IBAN + if (err == NOERR) + { + err = 1; + iban.cut(0) << statoISO << "##" << bban; + for (int pp = 0; pp <= 99 && err == 1; pp++) + { + msg.format("%02d", pp); + iban.overwrite(msg, 2); + err = iban_check(iban, msg); + if (err == 0) + { + break; + } + } + } + + if (err == NOERR) + { + cfb.put("ABI", abi); + cfb.put("CAB", cab); + cfb.put("NUMCC", contcor); + cfb.put("IBAN", iban); + cfb.write_rewrite(); + } + + // Parso il campo Note + TToken_string note (odbc.get("Note").as_string()); + for (int i = 0; i < note.items(); i++) + { + int pipe = note.find('|'); + TString token = note.get(i); + if (token.starts_with("PNE=")) + { + TToken_string pne(token.mid(4), ','); + TString nonacc; + TString nonscd; + for (int k = 0; k < pne.items(); k++) + { + TToken_string pno(pne.get(k), '/'); + for (int j = 0; j < pne.items(); j++) + { + // DA GIORNO DA MESE A GIORNO A MESE + nonacc << pno.get(0) << "-" << pno.get(1) << ";" << pno.get(2) << "-" << pno.get(3) << ";"; + // IL GIORNO IL MESE + nonscd << pno.get(4) << "-" << pno.get(5) << ";"; + } + } + nonacc.cut(nonacc.len() - 1); + nonscd.cut(nonscd.len() - 1); + cfv.put(CFV_NONACCEFF, nonacc); + cfv.put(CFV_NONSCADEFF, nonscd); + } else + if (token.starts_with("RE=")) + { + cfv.put(CFV_RAGGEFF, token == "RE=X"); + } else + if (token.starts_with("NOTE=")) + { + TString note = token.mid(5); + if(!note.blank()) + cfv.put(CFV_CODNOTE, clifo_add_note(cfv, note)); + } + else + { + if (!token.blank()) + { + cfv.put(CFV_CODNOTE, clifo_add_note(cfv, token)); + } + else + { + TString err = "Token non riconosciuto: "; + err << token.left(token.find('=')) << "\nQuesto dato non verrà importato"; + warning_box(err); + } + } + } + + cfv.write_rewrite(); + + TString user = ini_get_string(CONFIG_DITTA, "BS", "ImportUser"); + if (user.empty()) + user = "BEESTORE"; + clifo.put(CLI_UTENTE, user); + TDate dua = odbc.get(BS_DTULTAGG).as_date(); + if (!dua.ok()) dua = TDate(TODAY); + clifo.put(CLI_DATAAGG, dua); + + clifo.rewrite(); + + if (!pi.add_status()) + break; + } +} + +void TBeeStore_sync::save_clifo(int cfmask, const TDate& dal, const TDate& al) +{ + TString_array fields; + fields.add("Cod_PK|" CLI_CODCF); + fields.add("RagSoc|" CLI_RAGSOC); + fields.add("Cognome|" CLI_RAGSOC); + fields.add("Nome|" CLI_RAGSOC); + fields.add("Indirizzo|" CLI_INDCF); + fields.add("Citta|" CLI_COMCF); + fields.add("Cap|" CLI_CAPCF); + fields.add("Provincia|"); + fields.add("Telefono|PTEL+TEL"); + fields.add("Cellulare|PTEL2+TEL2"); + fields.add("CellulareSMS|PTEL3+TEL3"); + fields.add("EMail|" CLI_MAIL); + fields.add("PartitaIva|" CLI_PAIV); + fields.add("CodFiscale|" CLI_COFI); + fields.add("Tipo|1"); + fields.add("Sesso|" CLI_SESSO); + fields.add("DTNascita|" CLI_DATANASC); + fields.add("ComuneNascita|" CLI_COMNASC); + fields.add("PVNascita|"); + fields.add("Cliente|"); + fields.add("Fornitore|"); + fields.add("For_CodFor|" CLI_CODCF); + fields.add("For_Blocco|" CLI_SOSPESO); + fields.add("Cli_CodCG|" CLI_CODCF); + fields.add("Cli_Blocco|" CLI_SOSPESO); + fields.add("MagInserAnagrafica|1"); + fields.add("CodStato|" CLI_STATOCF); + fields.add("Annullato|0"); + + TString query = build_query(LF_CLIFO, dal, al); + query << "\nJOIN " << LF_CFVEN << " INTO TIPOCF==TIPOCF CODCF==CODCF"; + if (cfmask == 1) + query << "\nFROM TIPOCF=C\nTO TIPOCF=C"; else + if (cfmask == 2) + query << "\nFROM TIPOCF=F\nTO TIPOCF=F"; + + TISAM_recordset clifo(query); + save_my_origine(clifo, "tieAnagCFP", fields, ClifoEvaluator); +} + +void TBeeStore_sync::sync_clifo(int cfmask, const TDate& dal, const TDate& al) +{ + if (cfmask & 1) load_clifo('C'); + if (cfmask & 2) load_clifo('F'); + + + if (enableDelete) + { + TString str(255); + TODBC_recordset clifo(str); + clifo.connect(_dsn, _usr, _psw); + str << "DELETE FROM tieAnagCFP WHERE Origine=" << their_origin() << ";"; + clifo.exec(str); // Elimina tutte le anagrafiche importate da BeeStore + } + + if (ini_get_bool(CONFIG_DITTA, "BS", "EnableExp")) + save_clifo(cfmask, dal, al); +} + +bool TBeeStore_sync::save_and_delete_movmag(TMov_mag*& doc) const +{ + int err = 0; + if (doc != NULL) + { + if (doc->rows() > 0) + { + TLocalisamfile mm(LF_MOVMAG); + err = doc->write(mm); + if (err != NOERR) + { + TString msg; + msg.format(FR("Errore %d in registrazione scontrino %ld del %s"), err, + doc->get_long(MOVMAG_NUMREG), (const char*)doc->get(MOVMAG_DATAREG)); + _log->log(2, msg); + msg << TR("\nSi desidera proseguire ugualmente?"); + if (noyes_box(msg)) + err = 0; + } + } + delete doc; + doc = NULL; + } + return err == 0; +} + +bool TBeeStore_sync::save_and_delete_doc(TDocumento*& doc) const +{ + int err = 0; + if (doc != NULL) + { + if (doc->rows() > 0) + { + err = doc->write(); + if (err != NOERR) + { + TString msg; + + msg.format(FR("Errore %d in registrazione dcoumento %s/%ld del %s"), err, + (const char *) doc->get(DOC_CODNUM), doc->get_long(DOC_NDOC), (const char*)doc->get(DOC_DATADOC)); + _log->log(2, msg); + msg << TR("\nSi desidera proseguire ugualmente?"); + if (noyes_box(msg)) + err = 0; + } + } + delete doc; + doc = NULL; + } + return err == 0; +} + +void TBeeStore_sync::sync_val(const TDate& dal, const TDate& al) +{ + TString_array fields; + fields.add("CodValuta|CODTAB"); + fields.add("DSValuta|S0"); + fields.add("Simbolo|CODTAB"); + sync_table("%VAL", "tieValute", fields, dal, al); +} + +void TBeeStore_sync::sync_listino(const TString& listino) +{ + TString str(255); + TODBC_recordset prz(str); + prz.connect(_dsn, _usr, _psw); + str = "DELETE FROM tiePrzVendita WHERE Origine="; str << their_origin() << ""; + prz.exec(str); // Ignora tutti i listini di BeeStore + + str.cut(0) << "USE " << LF_RCONDV << " SELECT " << LF_ANAMAG << ".CODART!=\"\"" + << "\nJOIN " << LF_ANAMAG << " INTO CODART==CODRIGA" + << "\nFROM TIPO=L TIPORIGA=A COD=" << listino + << "\nTO TIPO=L TIPORIGA=A COD=" << listino; + TISAM_recordset lis(str); + if (lis.move_first()) + { + TString16 eur; eur << "CodValuta|'" << TCurrency::get_euro_val() << "'"; + + TString16 key; key << "L||||" << listino; + const TRectype& condv = cache().get(LF_CONDV, key); + + TDate dt_inizio = condv.get(CONDV_VALIN); + if (!dt_inizio.ok()) dt_inizio = TDate(1,1,2000); + TDate dt_fine = condv.get(CONDV_VALFIN); + if (dt_fine < dt_inizio) dt_fine = TDate(31,12,2100); + + TString descr; descr << "DSListino|'" << condv.get(CONDV_DESCR) << '\''; + TString dtini; dtini << "DTInizio|'" << dt_inizio.string() << '\''; + TString dtfin; dtfin << "DTFine|'" << dt_fine.string() << '\''; + + TString_array fields; + fields.add("Cod_PK|" RCONDV_CODRIGA); + fields.add("CodPadre|" RCONDV_CODRIGA); + //fields.add("CodArticolo|" RCONDV_CODRIGA); // NON metterlo! + fields.add("TipoPrezzo|'1'"); // 1=Listino + fields.add(eur); + fields.add("Prezzo|" RCONDV_PREZZO); + fields.add("Prezzo2|0"); + fields.add("Sconto|" RCONDV_SCONTO); + if (real::is_natural(listino)) + fields.add("NumListino|" RCONDV_COD); + fields.add(descr); + fields.add(dtini); + fields.add(dtfin); + + save_my_origine(lis, "tiePrzVendita", fields); + } +} + +void TBeeStore_sync::sync_mov(int tipotestata, const TDate& dal, const TDate& al) +{ + const TString8 codcaus = ini_get_string(CONFIG_DITTA, "bs", MOVMAG_CODCAUS, "", tipotestata); + + if (codcaus.blank()) + { + _log->log(2, "Configurare parametri per movimenti Bee Store"); + return; + } + + TString str(255); + str << "SELECT * FROM tieDMovMag WHERE Origine=" << their_origin() << " AND TipoTestata=" << tipotestata; + if (dal.ok() || al.ok()) + { + str << " AND DataMov"; + if (dal.ok() && al.ok()) + str << " BETWEEN " << date2sql(dal, 1) << " AND " << date2sql(al, 2); + else + { + if (dal.ok()) + str << ">=" << date2sql(dal, 1); + else + str << "<=" << date2sql(al, 2); + } + } + str << "\nORDER BY NumMov,NumRiga"; + + TODBC_recordset mov(str); + mov.connect(_dsn, _usr, _psw); + TProgress_monitor pi(mov.items(), str); + + TString num_mov, nm; + TMov_mag* doc = NULL; + + for (bool ok = mov.move_first(); ok; ok = mov.move_next()) + { + nm = mov.get("NumMov").as_string(); + if (nm != num_mov) + { + if (!save_and_delete_movmag(doc)) + break; + num_mov = nm; + const TDate datadoc = mov.get("DataMov").as_date(); + doc = new TMov_mag; + doc->put(MOVMAG_CODCAUS, codcaus); + doc->put(MOVMAG_DATAREG, datadoc); + } + TRectype& rdoc = doc->new_row(); + rdoc.put(RMOVMAG_CODART, mov.get("CodArticolo").as_string()); + rdoc.put(RMOVMAG_UM, mov.get("CodUntMis").as_string()); + rdoc.put(RMOVMAG_PREZZO, mov.get("PrzCassaValuta").as_real()); + if (!pi.add_status()) + break; + } + save_and_delete_movmag(doc); // Salva ultimo documento in sospeso +} + +void TBeeStore_sync::add_rmov(TMovimentoPN& mov, const real& importo, const TCausale& caus, const char* cod_da) const +{ + if (!importo.is_zero()) + { + TRectype& rmov = mov.cg(-1); + rmov.put(RMV_SEZIONE, caus.sezione_clifo()); + rmov.put(RMV_IMPORTO, importo); + int i = caus.last(); + for (; i > 15; i--) + { + const char* cod = caus.cod_desc_agg(i); + if (xvt_str_same(cod, cod_da)) + break; + } + TBill zio1; caus.bill(1, zio1); + TBill zio2; caus.bill(i, zio2); + zio2.put(rmov); + zio1.put(rmov, true); + } +} + +void TBeeStore_sync::sync_doc(const TDate& dal, const TDate& al) +{ + const TString8 codcausdef = ini_get_string(CONFIG_DITTA, "bs", MOVMAG_CODCAUS, "", 2); +/* + if (codcausdef.blank()) + { + _log->log(2, "Configurare parametri per movimenti Bee Store"); + return; + } +*/ + TString str(255); + str << "SELECT tieDMovMag.*, tieTBolFat.*, tieTBolFat.Annullato AS DOCANNULLATO, tieDMovMagCONAI.*\n"; + str << "FROM tieDMovMag\nRIGHT JOIN tieTBolFat ON tieDMovMag.CodTestata = tieTBolFat.Cod_PK\n"; + if(hasConai) + str << "LEFT JOIN tieDMovMagCONAI ON tieDMovMag.Cod_PK = tieDMovMagCONAI.Cod_PK\n"; + str << "WHERE tieTBolFat.Origine = " << their_origin(); + //str << "WHERE tieDMovMag.Origine = " << their_origin() << " AND tieDMovMag.TipoTestata = 2"; // verificare + if (dal.ok() || al.ok()) + { + str << " AND DataMov"; + if (dal.ok() && al.ok()) + str << " BETWEEN " << date2sql(dal, 1) << " AND " << date2sql(al, 2); + else + { + if (dal.ok()) + str << ">=" << date2sql(dal, 1); + else + str << "<=" << date2sql(al, 2); + } + } + str << "\nORDER BY tieTBolFat.Cod_PK,tieDMovMag.NumRiga"; + + TODBC_recordset docs(str); + docs.connect(_dsn, _usr, _psw); + TProgress_monitor pi(docs.items(), str); + + long num_doc = -1, nd, codcf ; + TString4 tipocf; + TDocumento* doc = NULL; + + if (enableDelete) + { + // Aggiungo le tabelle al cestino globale + mastroBin().addTable("tieTBolFat", "Cod_Pk"); + mastroBin().addTable("tieDMovMag", "Cod_Pk"); + if (hasConai) + mastroBin().addTable("tieDMovMagCONAI", "Cod_Pk"); + } + for (bool ok = docs.move_first(); ok; ok = docs.move_next()) + { + if (enableDelete) + { + // Aggiungo a cestino i record da eliminare + mastroBin().put("tieTBolFat", docs.get("Cod_Pk").as_string()); + mastroBin().put("tieDMovMag", docs.get("CodTestata").as_string()); + if (hasConai) + mastroBin().put("tieDMovMagCONAI", docs.get("Cod_Pk").as_string()); + } + //TToken_string test(docs.get("CodTestata").as_string(), '\\'); + const TString keyDoc = docs.get("CodTestata").as_string(); + nd = docs.get("NumRif").as_int(); + TString wrk = docs.get("CodCliente").as_string(); + + while(wrk[0] >= 'A') + wrk.ltrim(1); + + codcf = atol(wrk); + tipocf = docs.get("TipoIntestatario").as_string(); + + if (tipocf != "C" && tipocf != "F") + warning_box("Attenzione! Per il doc n.%d è presente il tipo C/F = '%s'\nIl documento verrà saltato.", nd , tipocf); + + if (nd != num_doc) + { + if (num_doc > 0 && !save_and_delete_doc(doc)) + break; + num_doc = nd; + const TDate datadoc = docs.get("DataMov").as_date(); + TString8 numdoc; + TString8 tipodoc; + + // Controllo se ho ricevuto un codice Campo per il TipoDoc o devo prenderlo dalle impostazioni + if(docs.get("TipoDocCE").is_empty()) + { + switch (docs.get("TipoDoc").as_int()) + { + case 1: // Bolla + numdoc = ini_get_string(CONFIG_DITTA, "BS", "CODNUMBOL"); + tipodoc = ini_get_string(CONFIG_DITTA, "BS", "TIPODOCBOL"); + break; + case 2: // Fattura + numdoc = ini_get_string(CONFIG_DITTA, "BS", "CODNUMFAT"); + tipodoc = ini_get_string(CONFIG_DITTA, "BS", "TIPODOCFAT"); + break; + case 6: // NC + numdoc = ini_get_string(CONFIG_DITTA, "BS", "CODNUMNC"); + tipodoc = ini_get_string(CONFIG_DITTA, "BS", "TIPODOCNC"); + break; + case 7: // Richiesta Trasferimento da Altro Magazzino + numdoc = ini_get_string(CONFIG_DITTA, "BS", "CODNUMTAM"); + tipodoc = ini_get_string(CONFIG_DITTA, "BS", "TIPODOCTAM"); + break; + case 9: // Ordine Cliente + numdoc = ini_get_string(CONFIG_DITTA, "BS", "CODNUMORC"); + tipodoc = ini_get_string(CONFIG_DITTA, "BS", "TIPODOCORC"); + break; + default: + warning_box("Attenzione! Per il doc con codice: %s è presente un tipo documento non supportato.\nIl documento saltato", keyDoc); + } + } + else + { + numdoc = docs.get("TipoDocCE").as_string(); + tipodoc = docs.get("TipoDocCE").as_string(); + } + + if(numdoc.blank() || tipodoc.blank()) + { + _log->log(2, "Configurare parametri per movimenti Bee Store"); + return; + } + + TTipo_documento tipo(tipodoc); + const TString8 codcaus = tipo.caus_mov().blank() ? codcausdef : tipo.caus_mov(); + + // Controllo che il documento non esista già + static TDocumento existDoc; + if (existDoc.read('D', datadoc.year(), numdoc, nd) == NOERR) // Ha uno stato che considero bloccato + { + if (existDoc.stato() < '2' && docs.get("DOCANNULLATO").as_int() == 1) + { + existDoc.remove(); + } + else + { + TString err; err << "Il documento " << datadoc.year() << " " << numdoc << " " << nd << " con chiave " << docs.get("Cod_PK").as_string() << " non è stato sostituito in quanto definitivo o già importato."; + _log->log(2, err); + num_doc = -1; + continue; + } + } + + /* + // Salto i documenti annullati + if (docs.get("tieTBolFat.Annullato").as_int() == 1) + continue; + */ + + doc = new TDocumento(); + doc->put(DOC_ANNO, datadoc.year()); + doc->put(DOC_DATADOC, datadoc); + doc->put(DOC_NDOC, nd); + doc->put(DOC_PROVV, "D"); + doc->put(DOC_CODNUM, numdoc); + doc->put(DOC_TIPODOC, tipodoc); + doc->put(DOC_TIPOCF, tipocf); + doc->put(DOC_CODCF, codcf); + doc->cli2doc(); + + const TString8 codval = docs.get("CodValuta").as_string(); + const real cambio = docs.get("CambioValuta").as_real(); + const TString asp = docs.get("AspettoBeni").as_string(); + const int ncolli = docs.get("NumeroColli").as_int(); + + doc->put(DOC_CODVAL, codval); + doc->put(DOC_CAMBIO, cambio); + doc->put(DOC_ASPBENI1, asp.sleft(50)); + doc->put(DOC_ASPBENI2, asp.smid(50)); + doc->put(DOC_NCOLLI, ncolli); + doc->put(DOC_CAUSMAG, codcaus); + } + const int tipoart = docs.get("TipoArticolo").as_int(); + TString4 tiporiga; + // Se la riga è customizzata evito i controlli + if (tipoart >= 15) + { + tiporiga = docs.get("TipoArticolo").as_string(); + } + else + { + // Facciamo un po' di speculazioni + switch (tipoart) + { + default: + case 1: + // Tiporiga 1 -> Merce + if(hasConai && ini_get_bool(CONFIG_DITTA, "bs", "UseCustomRiga", false)) + tiporiga = ini_get_string(CONFIG_DITTA, "bs", "NumCustomRiga", "14"); + else + tiporiga = "01"; + break; + case 2: + // Se la QTA è 0 sarà una spesa a spesa a valore + if (docs.get("Quantita").as_int() == 0) + { + tiporiga = "02"; + } + else + { + tiporiga = "03"; + } + break; + case 3: + // Se non ho QTA sarà una descrizione + if (docs.get("Quantita").as_int() == 0) + { + tiporiga = "05"; // Descrizione + } + else + // nel dubbio, Merce + tiporiga = "01"; + } + } + + TRectype& rdoc = doc->new_row(tiporiga); + const TString80 codart = docs.get("CodArticolo").as_string(); + + rdoc.put(RDOC_CODART, codart); + + if (tipoart == 2) + { + if (cache().get("SPP" , codart).not_empty()) + rdoc.put(RDOC_CODARTMAG, codart); + } + else + { + if (cache().get(LF_ANAMAG, codart).not_empty()) + rdoc.put(RDOC_CODARTMAG, codart); + } + + rdoc.put(RDOC_CODARTMAG, codart); +// rdoc.check_row(); + + const TString descr = docs.get("DSRiga").as_string(); + + rdoc.put(RDOC_DESCR, descr.sleft(50)); + if (descr.len() > 50) + { + rdoc.put(RDOC_DESCLUNGA, "X"); + rdoc.put(RDOC_DESCEST, descr.smid(50)); + } + rdoc.put(RDOC_CODMAG, docs.get("CodMagazzino").as_string().left(5)); + rdoc.put(RDOC_CODMAGC, docs.get("CodMagazDest").as_string().left(5)); + rdoc.put(RDOC_UMQTA, docs.get("CodUntMis").as_string()); + rdoc.put(RDOC_QTA, docs.get("Quantita").as_real()); + rdoc.put(RDOC_PREZZO, docs.get("PrzNettoSede").as_real()); // o PrzNettoValuta ?? + + real valsconto1(docs.get("Sconto1").as_real()); + real valsconto2(docs.get("Sconto2").as_real()); + real valsconto3(docs.get("Sconto3").as_real()); + + TString codiva = docs.get("CodIva").as_string(); + if (codiva.blank() || codiva == "0") + { + codiva = cache().get(LF_ANAMAG, codart, "CODIVA"); + if (codiva.blank()) + codiva = ini_get_string(CONFIG_DITTA, "bs", "CodIvaDef"); + } + rdoc.put(RDOC_CODIVA, codiva); + + TString80 sconto; + + if (valsconto1 != ZERO) + sconto << valsconto1.stringa(6, 2); + if (valsconto2 != ZERO) + { + if (sconto.full()) + sconto << "+"; + sconto << valsconto2.stringa(6, 2); + } + if (valsconto3 != ZERO) + { + if (sconto.full()) + sconto << "+"; + sconto << valsconto3.stringa(6, 2); + } + rdoc.put(RDOC_SCONTO, sconto); + + + // "CONSCACC", "CONSCALL", "CONSCCAR", "CONSCPLA", "CONSCLEG", "CONSCVET" + TString keyCli; keyCli << tipocf << "|" << codcf; + if (hasConai && cache().get(LF_CFVEN, keyCli, "ADDCONAI") == "X") + { + // In base al conai che ha abilitato controllo + if (ini_get_bool(CONFIG_DITTA, "ve", "CONFACC")) // Acciaio + { + rdoc.put("CONSCACC", docs.get("CatAC").as_string()); + rdoc.put("CONPUACC", docs.get("PesoAC").as_string()); + } + if (ini_get_bool(CONFIG_DITTA, "ve", "CONFALL")) // Alluminio + { + rdoc.put("CONSCALL", docs.get("CatAL").as_string()); + rdoc.put("CONPUALL", docs.get("PesoAL").as_string()); + } + if (ini_get_bool(CONFIG_DITTA, "ve", "CONFCAR")) // Carta + { + rdoc.put("CONSCCAR", docs.get("CatCA").as_string()); + rdoc.put("CONPUCAR", docs.get("PesoCA").as_string()); + } + if (ini_get_bool(CONFIG_DITTA, "ve", "CONFLEG")) // Legno + { + rdoc.put("CONSCLEG", docs.get("CatLE").as_string()); + rdoc.put("CONPULEG", docs.get("PesoLE").as_string()); + } + if (ini_get_bool(CONFIG_DITTA, "ve", "CONFPLA")) // Plastica + { + rdoc.put("CONSCPLA", docs.get("CatPL").as_string()); + rdoc.put("CONPUPLA", docs.get("PesoPL").as_string()); + } + if (ini_get_bool(CONFIG_DITTA, "ve", "CONFVET")) // Vetro + { + rdoc.put("CONSCVET", docs.get("CatVE").as_string()); + rdoc.put("CONPUVET", docs.get("PesoVE").as_string()); + } + } + + if (!pi.add_status()) + break; + } + save_and_delete_doc(doc); // Salva ultimo documento in sospeso + mastroBin().clean(); +} + +void TBeeStore_sync::sync_corrisp(const TDate&, const TDate&) +{ + const TString8 codcaus = ini_get_string(CONFIG_DITTA, "bs", "CODCAUSC"); + if (codcaus.blank()) + { + _log->log(2, "Configurare la causale corrispettivi Bee Store"); + return; + } + + TString str(255); + str << "SELECT * FROM tieCorrispettivi WHERE Origine=" << their_origin() << ""; + str << "\nORDER BY DataCorr,CodCorrispettivo"; + + TODBC_recordset corr(str); + corr.connect(_dsn, _usr, _psw); + TProgress_monitor pi(corr.items(), str); + + TString num_mov, nm; + TMov_mag* doc = NULL; + + TMovimentoPN mov; + mov.read(_islast); + long numreg = mov.curr().get_long(MOV_NUMREG)+1; + + for (bool ok = corr.move_first(); ok; ok = corr.move_next()) + { + TRectype& mrec = mov.curr(); + mov.destroy_rows(numreg); + + const TDate datareg = corr.get("DataCorr").as_date(); + mrec.put(MOV_NUMREG, numreg); + mrec.put(MOV_DATAREG, datareg); + mrec.put(MOV_ANNOIVA, datareg.year()); + + mrec.put(MOV_DATADOC, datareg); + TString80 desc; desc.format(FR("Corrispettivi %s"), datareg.stringa()); + mrec.put(MOV_DESCR, desc); + + TEsercizi_contabili esc; + mrec.put(MOV_DATACOMP, datareg); + mrec.put(MOV_ANNOES, esc.date2esc(datareg)); + + const TCausale caus(codcaus, datareg.year()); + mrec.put(MOV_CODCAUS, codcaus); + mrec.put(MOV_REG, caus.reg().name()); + + const real totdoc = corr.get("Valore").as_real(); + mrec.put(MOV_TOTDOC, totdoc); + + str << "SELECT * FROM tieDCorrispettivi WHERE (Origine=" << their_origin() << ")"; + str << "AND(CodCorrispettivo='" << corr.get("CodCorrispettivo") << "')"; + TODBC_recordset dett(str); + dett.connect(_dsn, _usr, _psw); + + TBill zio1; caus.bill(1, zio1); + TBill zio2; caus.bill(2, zio2); + TBill zio3; caus.bill(3, zio3); + + int nriga = 0; + real imponibile, imposta; + for (bool dok = dett.move_first(); dok; dok = dett.move_next()) + { + const real imp = dett.get("ImportoReparto").as_real(); + const real iva = dett.get("ImportoIva").as_real(); + TRectype& irec = mov.iva(nriga++); + irec.put(RMI_IMPONIBILE, imp); + irec.put(RMI_CODIVA, dett.get("CodIva").as_string()); + irec.put(RMI_IMPOSTA, iva); + zio2.put(irec); + imponibile += imp; + imposta += iva; + } + + const char sez1 = caus.sezione_clifo(); + TRectype& r1 = mov.cg(0); + r1.put(RMV_SEZIONE, sez1); + r1.put(RMV_IMPORTO, totdoc); + zio1.put(r1); + zio2.put(r1, true); + r1.put(RMV_ROWTYPE, 'T'); + + const char sez2 = sez1=='D'?'A':'D'; + TRectype& r2 = mov.cg(1); + r2.put(RMV_SEZIONE, sez2); + r2.put(RMV_IMPORTO, imponibile); + zio2.put(r2); + zio1.put(r2, true); + r2.put(RMV_ROWTYPE, 'I'); + + TRectype& r3 = mov.cg(2); + r3.put(RMV_SEZIONE, sez2); + r3.put(RMV_IMPORTO, imposta); + zio3.put(r3); + zio1.put(r3, true); + r3.put(RMV_ROWTYPE, 'D'); + + TRectype& r4 = mov.cg(3); + r4.put(RMV_SEZIONE, sez2); + r4.put(RMV_IMPORTO, totdoc); + zio1.put(r4); + zio1.put(r4, true); + + const real contanti = corr.get("IncContanti").as_real(); + const real bancomat = corr.get("IncBancomat").as_real(); + const real credcard = corr.get("IncCarteCredito").as_real(); + const real assegni = corr.get("IncAssegni").as_real(); + real altro = corr.get("IncFinanziato").as_real(); + altro += corr.get("IncCrediti").as_real(); + altro += corr.get("IncBonifici").as_real(); + altro += corr.get("IncAltro").as_real(); + + add_rmov(mov, contanti, caus, "BEECN"); + add_rmov(mov, bancomat, caus, "BEEBM"); + add_rmov(mov, credcard, caus, "BEECC"); + add_rmov(mov, assegni, caus, "BEEAS"); + add_rmov(mov, altro, caus, "BEEAL"); + + while (mov.write() == _isreinsert) + mrec.put(MOV_NUMREG, numreg++); + + if (!pi.add_status()) + break; + } + + if (!pi.is_cancelled()) + { + TString str(255); + TODBC_recordset sco(str); + sco.connect(_dsn, _usr, _psw); + str = "DELETE FROM tieCorrispettivi WHERE Origine="; str << their_origin() << ""; + sco.exec(str); + + str = "DELETE FROM tieDCorrispettivi WHERE Origine="; str << their_origin() << ""; + sco.exec(str); + } +} + + +bool TBeeStore_sync::create() +{ + _dsn = ini_get_string(CONFIG_DITTA, "bs", "DSN", "BEESTORE"); + _sqlog = ini_get_string(CONFIG_DITTA, "bs", "Log", ""); + _usr = ini_get_string(CONFIG_DITTA, "bs", "USR", "BEESTORE"); + _psw = decode(ini_get_string(CONFIG_DITTA, "bs", "PSW", "BEESTORE")); + hasConai = ini_get_bool(CONFIG_DITTA, "bs", "EnabCONAI", false); + enableDelete = ini_get_bool(CONFIG_DITTA, "BS", "EmptyOnImp"); + + if (_dsn.full()) + { + TProgress_monitor ti(1, TR("Connessione a SQL Server"), false); + TString query; query << "SELECT * FROM tieValute;";//"ODBC(" << _dsn << ")\nSELECT * FROM tieValute;"; + TODBC_recordset recset(query); + recset.connect(_dsn, _usr, _psw); // Dovrebbe connettersi anche con solo _dsn valorizzato + recset.move_first(); + if (_sqlog.full() && _sqlog.is_relative_path()) + { + TFilename n; n.tempdir(); + n.add(_sqlog.name()); + _sqlog = n; + } + recset.set_log_file(_sqlog); + return TSkeleton_application::create(); + } + return error_box(FR("Impossibile connettersi al DSN '%s'"), (const char*)_dsn); + +} + +void TBeeStore_sync::main_loop() +{ + TBeeStore_mask mask; + + while (mask.run() == K_ENTER) + { + mask.autosave(); // Rende definitivi tutti i paramentri in [bs] + _log = new TLog_report; + + const TDate dal = mask.get_date("SyncDateFrom"); + const TDate al = mask.get_date("SyncDateTo"); + + if (mask.get_bool("SyncUMS")) + sync_ums(dal, al); + if (mask.get_bool("SyncIVA")) + sync_iva(dal, al); + if (mask.get_bool("SyncLinee")) + sync_lines(dal, al); + if (mask.get_bool("SyncCatMer")) + sync_catmer(dal, al); + if (mask.get_bool("SyncAnamag")) + sync_anamag(dal, al); + if (mask.get_bool("SyncBarCode")) + sync_barcode(dal, al); + if (mask.get_bool("SyncVAL")) + sync_val(dal, al); + + int cfmask = 0; + if (mask.get_bool("SyncClienti")) cfmask |= 1; + if (mask.get_bool("SyncFornitori")) cfmask |= 2; + if (cfmask) + sync_clifo(cfmask, dal, al); + + if (mask.get("SyncListino").full()) + sync_listino(mask.get("SyncListino")); + if (mask.get_bool("SyncScontr")) + sync_scontrini(dal, al); + if (mask.get_bool("SyncCorr")) + sync_corrisp(dal, al); + if (mask.get_bool("SyncDoc")) + sync_doc(dal, al); + if (mask.get_bool("SyncCarScar")) + sync_carscar(dal, al); + if (mask.get_bool("SyncGenerici")) + sync_generici(dal, al); + + _log->preview(); + delete _log; + _log = NULL; + } + +} + +int bs0200(int argc, char* argv[]) +{ + TBeeStore_sync bss; + bss.run(argc, argv, TR("BeeStore Synchronizer")); + return 0; +} \ No newline at end of file diff --git a/src/bs/bs0300a.h b/src/bs/bs0300a.h new file mode 100644 index 000000000..a04d77861 --- /dev/null +++ b/src/bs/bs0300a.h @@ -0,0 +1,49 @@ +#define F_DAL 101 +#define F_AL 102 + +#define F_UMS 103 +#define F_IVA 104 +#define F_LINEART 105 +#define F_CATMER 106 +#define F_ART 107 +#define F_LIST 108 +#define F_SCONTRINI 109 +#define F_CORRISPETTIVI 110 +#define F_DOCUMENTI 111 +#define F_CARSCAR 112 +#define F_GENERICI 113 +#define F_VALUTE 114 +#define F_CLIENTI 115 +#define F_FORNITORI 116 +#define F_BARCODE 117 + +#define F_CODNUMBOL 201 +#define F_TIPODOCBOL 202 +#define F_CODNUMFAT 203 +#define F_TIPODOCFAT 204 +#define F_CODNUMNC 205 +#define F_TIPODOCNC 206 +#define F_CODNUMTAM 207 +#define F_TIPODOCTAM 208 +#define F_CODNUMORC 209 +#define F_TIPODOCORC 210 +#define F_C_CARSCAR 211 +#define F_D_CARSCAR 212 +#define F_C_DOCUMENTI 213 +#define F_D_DOCUMENTI 214 +#define F_C_SCONTRINI 215 +#define F_D_SCONTRINI 216 +#define F_C_GENERICI 217 +#define F_D_GENERICI 218 +#define F_CLIFODC 219 +#define F_OVERRIG 220 +#define F_NUMCUSTRIG 221 +#define F_IMPORTUSER 222 +#define F_ENIMPORT 223 +#define F_ENEXPORT 224 +#define F_EMPTYONIMP 225 +#define F_ENABCONAI 226 +#define F_CODIVADEF 227 + +#define F_C_CORRISPETTIVI 301 +#define F_D_CORRISPETTIVI 302 diff --git a/src/bs/bs0300a.uml b/src/bs/bs0300a.uml new file mode 100644 index 000000000..ca84b40e5 --- /dev/null +++ b/src/bs/bs0300a.uml @@ -0,0 +1,461 @@ +#include "bs0200a.h" + +TOOLBAR "topbar" 0 0 0 2 +#include +ENDPAGE + +PAGE "Sincronizzazione Bee Store" 0 2 0 0 + +GROUPBOX DLG_NULL 78 13 +BEGIN + PROMPT 1 1 "@bArchivi" +END + +BOOLEAN F_UMS +BEGIN + PROMPT 2 2 "Unità di misura " + FIELD SyncUMS +END + +BOOLEAN F_IVA +BEGIN + PROMPT 2 3 "Codici IVA " + FIELD SyncIVA +END + +BOOLEAN F_LINEART +BEGIN + PROMPT 2 4 "Linee Articolo " + FIELD SyncLinee +END + +BOOLEAN F_CATMER +BEGIN + PROMPT 2 5 "Categorie Merceologiche" + FIELD SyncCatMer +END + +BOOLEAN F_ART +BEGIN + PROMPT 2 6 "Articoli " + FIELD SyncAnamag +END + +STRING F_LIST 3 +BEGIN + PROMPT 40 6 "Listino " + USE LF_CONDV + INPUT TIPO "L" + INPUT CATVEN "" + INPUT TIPOCF "" + INPUT CODCF "" + INPUT COD 148 + DISPLAY "Codice" COD + DISPLAY "Descrizione@50" DESCR + DISPLAY "Valuta@5" CODVAL + DISPLAY "Inizio@10" VALIN + DISPLAY "Fine@10" VALFIN + OUTPUT 148 COD + FIELD SyncListino +END + +BOOLEAN F_SCONTRINI +BEGIN + PROMPT 2 7 "Scontrini " + FIELD SyncScontr +END + +BOOLEAN F_CORRISPETTIVI +BEGIN + PROMPT 2 8 "Corrispettivi " + FIELD SyncCorr +END + +BOOLEAN F_DOCUMENTI +BEGIN + PROMPT 2 9 "Documenti " + FIELD SyncDoc +END + +BOOLEAN F_CARSCAR +BEGIN + PROMPT 2 10 "Carichi/scarichi " + FIELD SyncCarScar +END + +BOOLEAN F_GENERICI +BEGIN + PROMPT 2 11 "Mov.generici " + FIELD SyncGenerici +END + +BOOLEAN F_VALUTE +BEGIN + PROMPT 40 2 "Valute" + FIELD SyncVAL +END + +BOOLEAN F_CLIENTI +BEGIN + PROMPT 40 3 "Clienti" + FIELD SyncClienti +END + +BOOLEAN F_FORNITORI +BEGIN + PROMPT 40 4 "Fornitori " + FIELD SyncFornitori +END + +BOOLEAN F_BARCODE +BEGIN + PROMPT 40 5 "Codici a barre" + FIELD SyncBarCode +END + +GROUPBOX DLG_NULL 78 4 +BEGIN + PROMPT 1 14 "@bFiltri" +END + +DATE F_DAL +BEGIN + PROMPT 2 15 "Dalla data di modifica " + FIELD SyncDateFrom +END + +DATE F_AL +BEGIN + PROMPT 42 15 " al " + FIELD SyncDateTo +END + +ENDPAGE + +PAGE "Parametri" 0 2 0 0 + +GROUPBOX DLG_NULL 78 7 +BEGIN + PROMPT 1 1 "@bImpostazioni documenti" +END + +STRING F_CODNUMBOL 4 +BEGIN + PROMPT 2 2 "Numerazione bolle " + FIELD CODNUMBOL + HELP "Codice numerazione" + USE %NUM + INPUT CODTAB F_CODNUMBOL + DISPLAY "Codice" CODTAB + DISPLAY "Descrizione@50" S0 + OUTPUT F_CODNUMBOL CODTAB + FLAG "UPA" + WARNING "Numerazione assente" + KEY 1 2 +END + +STRING F_TIPODOCBOL 4 +BEGIN + PROMPT 40 2 "Tipo bolle " + FIELD TIPODOCBOL + HELP "Codice tipo documento" + USE %TIP + INPUT CODTAB F_TIPODOCBOL + DISPLAY "Codice" CODTAB + DISPLAY "Descrizione@50" S0 + OUTPUT F_TIPODOCBOL CODTAB + FLAG "UP" +END + +STRING F_CODNUMFAT 4 +BEGIN + PROMPT 2 3 "Numerazione fatture " + FIELD CODNUMFAT + HELP "Codice numerazione" + USE %NUM + INPUT CODTAB F_CODNUMFAT + DISPLAY "Codice" CODTAB + DISPLAY "Descrizione@50" S0 + OUTPUT F_CODNUMFAT CODTAB + FLAG "UPA" + WARNING "Numerazione assente" + KEY 1 2 +END + +STRING F_TIPODOCFAT 4 +BEGIN + PROMPT 40 3 "Tipo fatture " + FIELD TIPODOCFAT + HELP "Codice tipo documento" + USE %TIP + INPUT CODTAB F_TIPODOCFAT + DISPLAY "Codice" CODTAB + DISPLAY "Descrizione@50" S0 + OUTPUT F_TIPODOCFAT CODTAB + FLAG "UP" +END + +STRING F_CODNUMNC 4 +BEGIN + PROMPT 2 4 "Numerazione NC " + FIELD CODNUMNC + HELP "Codice numerazione" + USE %NUM + INPUT CODTAB F_CODNUMNC + DISPLAY "Codice" CODTAB + DISPLAY "Descrizione@50" S0 + OUTPUT F_CODNUMNC CODTAB + FLAG "UPA" + WARNING "Numerazione assente" + KEY 1 2 +END + +STRING F_TIPODOCNC 4 +BEGIN + PROMPT 40 4 "Tipo NC " + FIELD TIPODOCNC + HELP "Codice tipo documento" + USE %TIP + INPUT CODTAB F_TIPODOCNC + DISPLAY "Codice" CODTAB + DISPLAY "Descrizione@50" S0 + OUTPUT F_TIPODOCNC CODTAB + FLAG "UP" +END + +STRING F_CODNUMTAM 4 +BEGIN + PROMPT 2 5 "Numerazione TAM " + FIELD CODNUMTAM + HELP "Codice numerazione" + USE %NUM + INPUT CODTAB F_CODNUMTAM + DISPLAY "Codice" CODTAB + DISPLAY "Descrizione@50" S0 + OUTPUT F_CODNUMTAM CODTAB + FLAG "UPA" + WARNING "Numerazione assente" + KEY 1 2 +END + +STRING F_TIPODOCTAM 4 +BEGIN + PROMPT 40 5 "Tipo TAM " + FIELD TIPODOCTAM + HELP "Codice tipo documento" + USE %TIP + INPUT CODTAB F_TIPODOCTAM + DISPLAY "Codice" CODTAB + DISPLAY "Descrizione@50" S0 + OUTPUT F_TIPODOCTAM CODTAB + FLAG "UP" +END + +STRING F_CODNUMORC 4 +BEGIN + PROMPT 2 6 "Numerazione ORC " + FIELD CODNUMORC + HELP "Codice numerazione" + USE %NUM + INPUT CODTAB F_CODNUMORC + DISPLAY "Codice" CODTAB + DISPLAY "Descrizione@50" S0 + OUTPUT F_CODNUMORC CODTAB + FLAG "UPA" + WARNING "Numerazione assente" + KEY 1 2 +END + +STRING F_TIPODOCORC 4 +BEGIN + PROMPT 40 6 "Tipo ORC " + FIELD TIPODOCORC + HELP "Codice tipo documento" + USE %TIP + INPUT CODTAB F_TIPODOCORC + DISPLAY "Codice" CODTAB + DISPLAY "Descrizione@50" S0 + OUTPUT F_TIPODOCORC CODTAB + FLAG "UP" +END + +GROUPBOX DLG_NULL 78 6 +BEGIN + PROMPT 1 8 "@bMovimenti" +END + +STRING F_C_CARSCAR 4 +BEGIN + PROMPT 2 9 "Causale magazzino car./scar. " + USE %CAU SELECT (S2[8,8]=1)&&(S6="P") + INPUT CODTAB F_C_CARSCAR + DISPLAY "Codice" CODTAB + DISPLAY "Descrizione@50" S0 + OUTPUT F_C_CARSCAR CODTAB + OUTPUT F_D_CARSCAR S0 + CHECKTYPE NORMAL + FIELD CODCAUS(1) + ADD RUN mg0 -0 %CAU +END + +STRING F_D_CARSCAR 50 36 +BEGIN + PROMPT 40 9 "" + FLAGS "D" +END + +STRING F_C_DOCUMENTI 4 +BEGIN + PROMPT 2 10 "Causale magazzino documenti " + USE %CAU SELECT (S2[8,8]=1)&&(S6="P") + INPUT CODTAB F_C_DOCUMENTI + DISPLAY "Codice" CODTAB + DISPLAY "Descrizione@50" S0 + OUTPUT F_C_DOCUMENTI CODTAB + OUTPUT F_D_DOCUMENTI S0 + CHECKTYPE NORMAL + FIELD CODCAUS(2) + ADD RUN mg0 -0 %CAU +END + +STRING F_D_DOCUMENTI 50 36 +BEGIN + PROMPT 40 10 "" + FLAGS "D" +END + +STRING F_C_SCONTRINI 4 +BEGIN + PROMPT 2 11 "Causale magazzino scontrini " + USE %CAU SELECT (S2[8,8]=1)&&(S6="P") + INPUT CODTAB F_C_SCONTRINI + DISPLAY "Codice" CODTAB + DISPLAY "Descrizione@50" S0 + OUTPUT F_C_SCONTRINI CODTAB + OUTPUT F_D_SCONTRINI S0 + CHECKTYPE NORMAL + FIELD CODCAUS(3) + ADD RUN mg0 -0 %CAU +END + +STRING F_D_SCONTRINI 50 36 +BEGIN + PROMPT 40 11 "" + FLAGS "D" +END + +STRING F_C_GENERICI 4 +BEGIN + PROMPT 2 12 "Causale magazzino mov.generici " + USE %CAU SELECT (S2[8,8]=1)&&(S6="P") + INPUT CODTAB F_C_GENERICI + DISPLAY "Codice" CODTAB + DISPLAY "Descrizione@50" S0 + OUTPUT F_C_GENERICI CODTAB + OUTPUT F_D_GENERICI S0 + CHECKTYPE NORMAL + FIELD CODCAUS(4) + ADD RUN mg0 -0 %CAU +END + +STRING F_D_GENERICI 50 36 +BEGIN + PROMPT 40 12 "" + FLAGS "D" +END + +GROUPBOX DLG_NULL 78 3 +BEGIN + PROMPT 1 14 "@bCorrispettivi" +END + +STRING F_C_CORRISPETTIVI 4 +BEGIN + PROMPT 2 15 "Causale contabile " + USE LF_CAUSALI SELECT TIPODOC="CR" + INPUT CODCAUS F_C_CORRISPETTIVI + DISPLAY "Codice" CODCAUS + DISPLAY "Descrizione@50" DESCR + OUTPUT F_C_CORRISPETTIVI CODCAUS + OUTPUT F_D_CORRISPETTIVI DESCR + CHECKTYPE NORMAL + FIELD CODCAUSC + ADD RUN cg0 -4 +END + +STRING F_D_CORRISPETTIVI 50 36 +BEGIN + PROMPT 40 15 "" + FLAGS "D" +END + +BOOLEAN F_CLIFODC +BEGIN + PROMPT 2 17 "Doppio controllo cod.cli" + FIELD ClifoDC +END + +BOOLEAN F_OVERRIG +BEGIN + PROMPT 40 17 "Riga merce custom" + FIELD UseCustomRiga + MESSAGE FALSE DISABLE,F_NUMCUSTRIG + MESSAGE TRUE ENABLE,F_NUMCUSTRIG +END + +STRING F_NUMCUSTRIG 2 +BEGIN + PROMPT 60 17 "" + FIELD NumCustomRiga + FLAGS "D" + CHECKYPE REQUIRED +END + +STRING F_CODIVADEF 4 +BEGIN + PROMPT 2 18 "Utilizza cod.IVA default " + USE %IVA + INPUT CODTAB F_CODIVADEF + DISPLAY "Codice" CODTAB + DISPLAY "Descrizione@50" S0 + DISPLAY "%@6" R0 + DISPLAY "Tipo" S1 + OUTPUT F_CODIVADEF CODTAB + HELP "Codice IVA per righe con valore nullo" + FIELD CodIvaDef + CHECKTYPE REQUIRED +END + +BOOLEAN F_ENIMPORT +BEGIN + PROMPT 2 19 "Abilita Importazione" + FIELD EnableImp +END + +BOOLEAN F_ENEXPORT +BEGIN + PROMPT 40 19 "Abilita Esportazione" + FIELD EnableExp +END + +BOOLEAN F_EMPTYONIMP +BEGIN + PROMPT 2 20 "Svuola DB dopo importazione" + FIELD EmptyOnImp +END + +BOOLEAN F_ENABCONAI +BEGIN + PROMPT 40 20 "Abilita gestione CONAI" + FIELD EnabCONAI +END + +STRING F_IMPORTUSER 20 +BEGIN + PROMPT 2 21 "Utente che effettua l'importazione " + FIELD ImportUser +END + +ENDPAGE + +ENDMASK \ No newline at end of file