campo-sirio/tc/tc0700.cpp
luca 793b3a85b0 Patch level :4.0 649
Files correlati     :
Ricompilazione Demo : [ ]
Commento            :modulo TC; tc1 e tc9 sostituiscono cg7


git-svn-id: svn://10.65.10.50/trunk@15013 c028cbd2-c16b-5b4b-a496-9718f37d4682
2007-03-07 15:04:34 +00:00

1423 lines
39 KiB
C++
Executable File
Raw Blame History

#include "tc0.h"
#include "tc0700a.h"
#include <applicat.h>
#include <automask.h>
#include <prefix.h>
#include <progind.h>
#include <recarray.h>
#include <relation.h>
#include <reprint.h>
#include <reputils.h>
#include <textset.h>
#include <anagr.h>
#include <anafis.h>
#include <clifo.h>
#include <comuni.h>
#include <causali.h>
#include <nditte.h>
#include <mov.h>
#include <rmov.h>
#include <rmoviva.h>
#include <multirel.h>
#include "../cg/cglib01.h"
#define TSMAIALCONST 600
///////////////////////////////////////////////////////////
// TRiclassifica_cache
///////////////////////////////////////////////////////////
class TRiclassifica_cache : public TCache
{
TLocalisamfile _multirel;
protected:
virtual TObject* key2obj(const char* key);
public:
const char * sdecode(const char* tab, const TString& cod);
long decode(const char* tab, const TString& cod);
TRiclassifica_cache() : _multirel(LF_MULTIREL) { _multirel.setkey(2);}
};
TObject* TRiclassifica_cache::key2obj(const char* key)
{
TToken_string tok(key);
TString8 tab, cod;
tok.get(0,tab);
tok.get(1, cod);
_multirel.put(MULTI_COD, tab);
_multirel.put(MULTI_FIRST, "");
_multirel.put(MULTI_SECOND, cod);
int err = _multirel.read(_isgteq);
if (err == NOERR && _multirel.get(MULTI_SECOND) == cod)
return new TString(_multirel.get(MULTI_FIRST));
return NULL;
}
long TRiclassifica_cache::decode(const char* tab, const TString& cod)
{
TToken_string tok;
tok.add(tab);
tok.add(cod);
const TString* ric = (const TString*) objptr(tok);
return (ric ? atol(*ric) : 0);
}
const char * TRiclassifica_cache::sdecode(const char* tab, const TString& cod)
{
TToken_string tok;
tok.add(tab);
tok.add(cod);
const TString* ric = (const TString*) objptr(tok);
return ric ? (const char *) *ric : "";
}
///////////////////////////////////////////////////////////
// TTS_textset
///////////////////////////////////////////////////////////
class TTS_textset : public TAS400_recordset
{
TAssoc_array _contatori;
protected:
long add_count(const char* tipo, long n = 1);
protected:
void add_field(const char* trc, const char* name = "Filler", int len = 0, char tipo = 'a',
int from = -1, const char* def = NULL);
public:
virtual bool destroy(TRecnotype r);
virtual const TString& rec_type(TRecnotype r = -1) const;
virtual bool set(const char* field, const TVariant& v);
TTS_textset(const char* query = "");
};
class TIVA_item : public TObject
{
int _row;
long _conto;
long _codiva;
long _codiva11;
real _imponibile;
real _imposta;
public:
int & row() { return _row;}
long & conto() { return _conto;}
long & codiva() { return _codiva;}
long & codiva11() { return _codiva11;}
real & imponibile() { return _imponibile;}
real & imposta() { return _imposta;}
TIVA_item(int row, long conto, long codiva, long codiva11) : _row(row), _conto(conto), _codiva(codiva), _codiva11(codiva11) {}
virtual ~TIVA_item() {}
};
///////////////////////////////////////////////////////////
// TTS_sender
///////////////////////////////////////////////////////////
class TTS_sender : public TSkeleton_application
{
TRiclassifica_cache* _tabelle;
TRecord_cache* _conti;
TAssoc_array _riclassifica;
TTS_textset* _tsfile;
TLog_report* _log;
bool _errors_logged;
bool _send_cg;
TString8 _dittamulti;
TDate _from;
TArray _recsets;
TAssoc_array _iva;
TAssoc_array _contiiva;
protected:
bool new_rec(const char* t) { CHECK(t && *t, "Tipo non valido"); return _tsfile->new_rec(t) >= 0; }
void remove_last();
void set(const char* field, const TVariant& var);
void set(const char* field, const int n) { set(field, TVariant((long)n)); }
void set(const char* field, const char* s) { set(field, TVariant(s)); }
void set(const char* field, const TDate& d) { set(field, TVariant(d)); }
void set(const char* field, const real& v) { set(field, TVariant(v)); }
const TVariant& get(const char* field);
void add_mov(const TRecordset& mov);
void add_clifor(char tipocf, long codcf);
void add_header(const TRecordset& mov, const bool fullhead = true);
void add_datiiva(const TRecordset& mov);
void add_tot_fattura(const TRecordset& mov);
void add_conti_ricavo_costo(const TRecordset& mov);
void add_new_rec(const TRecordset& mov, const char tipocf, long codcf);
void add_diversi(const TRecordset& mov, const bool moviva);
void add_ratei_risconti(const TRecordset& mov);
void add_ulteriori(const TRecordset& mov);
const TString & scod2ricl(const char* tab, const TString& cod);
const TString & scod2ricl(const char* tab, const TVariant& cod);
const long cod2ricl(const char* tab, const TString& cod);
const long cod2ricl(const char* tab, const TVariant& cod);
const long bill2ricl(char & t, int gr, int co, long so, const bool header_cli = false);
virtual TRecordset & movrecset(const TDate & from = eotime, const TDate & to = botime);
virtual TRecordset & rmovrecset(const TRecordset & mov);
virtual TRecordset & rivarecset(const TRecordset & mov);
virtual TRecordset & clirecset(const char tipocf, const long codcf);
virtual void get_citta_provincia(const TRecordset& cli, TString & dencom, TString & provcom, bool nascita = false);
virtual const char * decode_causale(const TRecordset& mov);
virtual bool test_swap(const TRecordset& mov);
public:
void log(int sev, const char* msg);
TString & dittamulti() { return _dittamulti;}
TAssoc_array & riclassifica() {return _riclassifica;}
virtual void update_parameters(const TDate & d);
virtual void set_parameters();
virtual bool create();
virtual void main_loop();
virtual bool destroy();
TTS_sender() : _tabelle(NULL), _conti(NULL) {}
};
TTS_sender& app() { return (TTS_sender&)main_app(); }
///////////////////////////////////////////////////////////
// TTS_textset
///////////////////////////////////////////////////////////
long TTS_textset::add_count(const char* tipo, long i)
{
CHECK(strlen(tipo) == 1, "Tipo record non valido");
real* n = (real*)_contatori.objptr(tipo);
if (n == NULL)
{
n = new real;
_contatori.add(tipo, n);
}
*n += i;
return n->integer();
}
const TString& TTS_textset::rec_type(TRecnotype r) const
{
const TString& t = TAS400_recordset::rec_type(r);
return t;
}
bool TTS_textset::destroy(TRecnotype r)
{
bool ok;
if (r >= 0)
{
const TString& t = TAS400_recordset::rec_type(r); // Igora subtipo record!
ok = TAS400_recordset::destroy(r);
if (ok)
add_count(t, -1);
}
else
{
ok = TAS400_recordset::destroy(r);
if (ok)
_contatori.destroy();
}
return ok;
}
void TTS_textset::add_field(const char* trc, const char* name, int len,
char tipo, int from, const char* def)
{
const bool required = false;
CHECK(trc && *trc, "Tracciato nullo");
TString80 fname; fname << trc << '.' << name;
const TFieldtypes t = tipo == 'n' ? _longzerofld : _alfafld;
const int pos = from - 1;
if (def && *def)
{
CHECKS(def == NULL || (int)strlen(def) <= len, "Invalid default value ", def);
TVariant var(def); var.convert_to(t);
create_field(fname, pos, len, t, required, var);
}
else
create_field(fname, pos, len, t, required);
}
bool TTS_textset::set(const char* field, const TVariant& var)
{
const char* err = NULL;
int c = -1;
const TAS400_column_info* info = parse_field(field, c, false);
bool ok = info != NULL;
if (ok)
{
switch (var.type())
{
case _datefld:
if (var.is_zero())
ok = set_field(*info, NULL_VARIANT);
else
{
long ansi = 0;
const TDate d = var.as_date();
if (info->_width == 6)
ansi = d.day()*10000 + d.month()*100 + d.year()%100;
else
ansi = d.date2ansi();
ok = set_field(*info, TVariant(ansi));
}
break;
case _realfld:
if (var.is_zero())
ok = set_field(*info, NULL_VARIANT);
else
{
real v = var.as_real(); v *= CENTO;
ok = set_field(*info, TVariant(v.integer()));
}
break;
default:
ok = set_field(*info, var);
break;
}
if (!ok)
err = TR("Campo obbligatorio non compilato");
}
else
err = TR("Campo non riconosciuto");
if (err != NULL)
{
TString msg;
msg << field << ": " << err;
app().log(2, msg);
}
return ok;
}
TTS_textset::TTS_textset(const char* query)
: TAS400_recordset(TString("AS400(7001,1,6)\n") << query)
{
const char an = 'a';
const char n = 'n';
const bool o = true;
const bool f = false;
add_field("0", "TRF-DITTA", 5, n, 1); // codice ditta multi
add_field("0", "TRF-VERSIONE", 1, n, 6, "3"); // versione
add_field("0", "TRF-TARC", 1, n, 7, "0"); // tipo record
// dati cliente/fornitore
add_field("0", "TRF-COD-CLIFOR", 5, n, 8, "0"); // codice cliente/fornitore
add_field("0", "TRF-RASO", 32, an, 13); // ragione sociale
add_field("0", "TRF-IND", 30, an, 45); // indirizzo
add_field("0", "TRF-CAP", 5, n, 75); // cap
add_field("0", "TRF-CITTA", 25, an, 80); // citta
add_field("0", "TRF-PROV", 2, an, 105); // provincia
add_field("0", "TRF-COFI", 16, an, 107); // codice fiscale
add_field("0", "TRF-PIVA", 11, an, 123); // partita iva
add_field("0", "TRF-PF", 1, an, 134); // persona fisica S/N
add_field("0", "TRF-DIVIDE", 2, n, 135); // posizione spazio tra cognome e nome
add_field("0", "TRF-PAESE", 4, n, 137); // paese estero di residenza
add_field("0", "TRF-PIVA-ESTERO",12, an, 141); // partita iva estera
add_field("0", "TRF-COFI-ESTERO",20, an, 153); // codice fiscale estero
add_field("0", "TRF-SESSO", 1, an, 173); // sesso M/F
add_field("0", "TRF-DTNAS", 8, n, 174); // data di nascita
add_field("0", "TRF-COMNA", 25, an, 182); // comune di nascita
add_field("0", "TRF-PRVNA", 2, an, 207); // provincia di nascita
add_field("0", "TRF-PREF", 4, an, 209); // prefisso telefonico
add_field("0", "TRF-NTELENUM", 20, an, 213); // numero telefonico
add_field("0", "TRF-FAX-PREF", 4, an, 233); // prefisso fax
add_field("0", "TRF-FAX-NUM", 9, an, 237); // numero fax
add_field("0", "TRF-CFCONTO", 7, n, 246); // codice conto di costo abituale
add_field("0", "TRF-CFCODPAG", 4, n, 253); // codice condizioni pagamenti
add_field("0", "TRF-CFBANCA", 5, n, 257); // codice abi
add_field("0", "TRF-CFAGENZIA", 5, n, 262); // codice cab
add_field("0", "TRF-CFINTERM", 1, n, 267); // codice intermerdio clienti/fornitori
// dati fattura
add_field("0", "TRF-CAUSALE", 3, n, 268); // codice causale movimento
add_field("0", "TRF-CAU-DES", 15, an, 271); // descrizione causale
add_field("0", "TRF-CAU-AGG", 18, an, 286); // causale aggiuntiva
add_field("0", "TRF-CAU-AGG-1", 34, an, 304); // ulteriore causale aggiuntiva
add_field("0", "TRF-CAU-AGG-2", 34, an, 338); // ulteriore causale aggiuntiva
add_field("0", "TRF-DATA-REGISTRAZIONE", 8, n, 372); // data registrazione
add_field("0", "TRF-DATA-DOC", 8, n, 380); // data documento
add_field("0", "TRF-NUM-DOC-FOR", 8, n, 388); // numero documento fornitore compreso sezionale
add_field("0", "TRF-NDOC", 5, n, 396); // numero documento
add_field("0", "TRF-SERIE", 2, n, 401); // sezionale iva
add_field("0", "TRF-EC-PARTITA", 6, n, 403); // estratto conto numero partita
add_field("0", "TRF-EC-PARTITA-ANNO", 4, n, 409); // estratto conto anno partita
add_field("0", "TRF-EC-COD-VAL", 3, n, 413); // estratto conto in valuta codice valuta esetera
add_field("0", "TRF-EC-CAMBIO", 13, n, 416); // estratto conto in valuta cambio valuta estera
add_field("0", "TRF-EC-DATA-CAMBIO", 8, n, 429); // estratto conto in valuta data cambio
add_field("0", "TRF-EC-TOT-DOC-VAL", 16, n, 437); // estratto conto in valuta totale documento in valuta
add_field("0", "TRF-EC-TOT-IVA-VAL", 16, n, 453); // estratto conto in valuta totale iva in valuta
add_field("0", "TRF-PLAFOND", 6, n, 469); // mmaaaa riferimento plafond e fatture differite
TString80 field;
// dati iva
for (int i=0; i<8; i++)
{
field.format("TRF-IMPONIB_%d", i);
add_field("0", field, 12, n, 475+(31*i)); // imponibile
field.format("TRF-ALIQ_%d", i);
add_field("0", field, 3, n, 487+(31*i)); // aliquota iva o codice esenzione
field.format("TRF-ALIQ_AGRICOLA_%d", i);
add_field("0", field, 3, n, 490+(31*i)); // aliquota iva di compensazione agricola
field.format("TRF-IVA11_%d", i);
add_field("0", field, 2, n, 493+(31*i)); // codice di memorizzazione per iva11
field.format("TRF-IMPOSTA_%d", i);
add_field("0", field, 11, n, 495+(31*i)); // imposta
}
// totale fattura
add_field("0", "TRF-TOT-FATT", 12, n, 723); // totale fattura
// conti di ricavo/costo
for (int i = 0; i < 8; i++)
{
field.format("TRF-CONTORIC_%d", i);
add_field("0", field, 7, n, 735+(19*i)); // codice conto di ricavo/costo
field.format("TRF-IMP-RIC_%d", i);
add_field("0", field, 12, n, 742+(19*i)); // importo ricavo/costo
}
// dati eventuale pagamentofattura o movimenti diversi
add_field("0", "TRF-CAU-PAGAM", 3, n, 887); // codice causale
add_field("0", "TRF-CAU-DES-PAGAM", 15, an, 890); // descrizione causale
add_field("0", "TRF-CAU-AGG-1-PAGAM", 34, an, 905); // ulteriore descrizione aggiuntiva
add_field("0", "TRF-CAU-AGG-2-PAGAM", 34, an, 939); // ulteriore descrizione aggiuntiva
// altri movimenti
for (int i = 0; i < 80; i++)
{
field.format("TRF-CONTO_%d", i);
add_field("0", field, 7, n, 973+(64*i)); // codice conto
field.format("TRF-DA_%d", i);
add_field("0", field, 1, an, 980+(64*i)); // segno operazione D/A
field.format("TRF-IMPORTO_%d", i);
add_field("0", field, 12, n, 981+(64*i)); // importo
field.format("TRF-CAU-AGGIUNT_%d", i);
add_field("0", field, 18, an, 993+(64*i)); // causale aggiuntiva
field.format("TRF-EC-PARTITA-PAG_%d", i);
add_field("0", field, 6, n, 1011+(64*i)); // estratto conto numero partita
field.format("TRF-EC-PARTITA-ANNO-PAG_%d", i);
add_field("0", field, 4, n, 1017+(64*i)); // estratto conto anno partita
field.format("TRF-EC-IMP-VAL_%d", i);
add_field("0", field, 16, n, 1021+(64*i)); // estratto conto in valuta
}
// ratei e risconti
for (int i = 0; i < 10; i++)
{
field.format("TRF-RIFER-TAB_%d", i);
add_field("0", field, 1, an, 6093+(19*i)); // tabella di riferimento
field.format("TRF-IND-RIGA_%d", i);
add_field("0", field, 2, n, 6094+(19*i)); // indice della tabella
field.format("TRF-DT-INI_%d", i);
add_field("0", field, 8, n, 6096+(19*i)); // data inizio
field.format("TRF-DT-INI_%d", i);
add_field("0", field, 8, n, 6104+(19*i)); // data fine
}
// ndoc a 6 cifre se non bastano le 5 di tf-ndoc
add_field("0", "TRF-DOC6", 6, n, 6283); // ndoc a 6 cifre se non bastano le 5 di trf-doc
// ulteriori dati cliente/fornitore
add_field("0", "TRF-AN-OMONIMI", 1, an, 6289); // considera omonimo
add_field("0", "TRF-AN-TIPO-SOGG", 1, n, 6290); // tipo soggetto ritenuta di acconto
// ulteriori dati ev. pagamento o movimenti diversi
for (int i = 0; i < 80; i++)
{
field.format("TRF-EC-PARTITA-SEZ-PAG_%d", i);
add_field("0", field, 2, n, 6291+(2*i)); // numero sezionale partita estratto conto
}
// ulteriori dati gestione professionista per eventuale pagamento fattura o dati fattura
add_field("0", "TRF-NUM-DOC-PAG-PROF", 7, n, 6451); // numero doc. incasso/pagamento
add_field("0", "TRF-DATA-DOC-PAG-PROF", 8, n, 6458); // data doc. incasso/pagamento
add_field("0", "TRF-RIT-ACC", 12, n, 6466); // ritenuta d'acconto
add_field("0", "TRF-RIT-PREV", 12, n, 6478); // ritenuta previdenziale
add_field("0", "TRF-RIT-1", 12, n, 6490); // altre ritenute 1
add_field("0", "TRF-RIT-2", 12, n, 6502); // 2
add_field("0", "TRF-RIT-3", 12, n, 6514); // 3
add_field("0", "TRF-RIT-4", 12, n, 6526); // 4
// ulteriori dati per unita' produttive ricavi
for (int i = 0; i < 8; i++)
{
field.format("TRF-UNITA-RICAVI_%d", i);
add_field("0", field, 2, n, 6538+(2*i)); //
}
// ulteriori dati per unita' produttive pagamenti
for (int i = 0; i < 80; i++)
{
field.format("TRF-UNITA-PAGAM_%d", i);
add_field("0", field, 2, n, 6554+(2*i)); //
}
// ulteriori dati cliente/fornitore
add_field("0", "TRF-FAX-PREF-1", 4, an, 6714); // prefisso fax sostitutivo
add_field("0", "TRF-FAX-NUM-1", 20, an, 6718); // numero fax sositutivo
add_field("0", "TRF-SOLO-CLIFOR", 1, an, 6738); // C crea solo cliente F crea solo fornitore (non genera primanota)
add_field("0", "TRF-80-SEGUENTE", 1, an, 6739); // s=record successivo identico a quello attuale ma con tabella pag compilata (ultima=u)
// ulteriori dati gestione professionista per eventuale pagamento fattura o dati fattura
add_field("0", "TRF-CONTO-RIT-ACC", 7, n, 6740); // conto ritenuta d'acconto
add_field("0", "TRF-CONTO-RIT-PREV", 7, n, 6747); // conto ritenuta previdenziale
add_field("0", "TRF-CONTO-RIT-1", 7, n, 6754); // conto ritenuta 1
add_field("0", "TRF-CONTO-RIT-2", 7, n, 6761); // conto ritenuta 2
add_field("0", "TRF-CONTO-RIT-3", 7, n, 6768); // conto ritenuta 3
add_field("0", "TRF-CONTO-RIT-4", 7, n, 6775); // conto ritenuta 4
add_field("0", "TRF-DIFFERIMENTO-IVA", 1, an, 6782); // differimento registrazione iva per autotrasportatori S/N
add_field("0", "TRF-STORICO", 1, an, 6783); // aggiornamento storico anagrafica
add_field("0", "TRF-STORICO-DATA", 8, n, 6784); // data aggiornamento storico anagrafica
add_field("0", "TRF-CAUS-ORI", 3, n, 6792); // causale originaria
add_field("0", "TRF-PREV-TIPOMOV", 1, an, 6795); // previsionale
add_field("0", "TRF-PREV-RATRIS", 1, an, 6796); // rateo /risconto
add_field("0", "TRF-PREV-DTCOMP-INI", 8, n, 6797); // data iniziale competenza
add_field("0", "TRF-PREV-DTCOMP-FIN", 8, n, 6805); // data finale competenza
add_field("0", "TRF-PREV-FLAG-CONT", 1, an, 6813); // non contabilizza
add_field("0", "TRF-PREV-RIFERIMENTO",20, an, 6814); // riferimento record interno
add_field("0", "FILLER", 166, an, 6834); // spazio
add_field("0", "FINE-RECORD", 2, an, 7000, "\r\n"); // terminatore record
}
///////////////////////////////////////////////////////////
// TTS_mask
///////////////////////////////////////////////////////////
class TTS_mask : public TAutomask
{
clock_t _next_update;
bool _updating;
private:
bool apply_filter(const TRecordset& righe) const;
void serialize(bool bSave);
protected:
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
public:
TTS_mask();
~TTS_mask();
};
bool TTS_mask::apply_filter(const TRecordset& righe) const
{
const TDate dal = get(F_DATA_DA);
const TDate al = get(F_DATA_AL);
if (dal.ok() || al.ok())
{
const TDate scad = righe.get("DATASCAD").as_date();
if ((dal.ok() && scad < dal) || (al.ok() && scad > al))
return false;
}
return true;
}
bool TTS_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
bool ok = true;
switch (o.dlg())
{
case F_DATA_DA:
case F_DATA_AL:
break;
default:
break;
}
return ok;
}
void TTS_mask::serialize(bool bSave)
{
const char* defpar = "tc";
TConfig ini(CONFIG_DITTA, defpar);
for (int i = fields()-1; i >= 0; i--)
{
TMask_field& f = fld(i);
const TFieldref* fr = f.field();
if (fr != NULL)
{
if (bSave)
fr->write(ini, defpar, f.get());
else
f.set(fr->read(ini, defpar));
}
}
}
TTS_mask::TTS_mask()
: TAutomask("tc0700a"), _updating(false), _next_update(0)
{
serialize(false);
}
TTS_mask::~TTS_mask()
{
serialize(true);
}
///////////////////////////////////////////////////////////
// TTS_sender
///////////////////////////////////////////////////////////
void TTS_sender::log(int sev, const char* msg)
{
if (sev > 0)
{
TString m;
m << TR("Record") << ' ' << _tsfile->rec_type() << ": " << msg;
_log->log(sev, m);
_errors_logged = true;
}
else
_log->log(sev, msg);
}
void TTS_sender::set(const char* field, const TVariant& var)
{
_tsfile->set(field, var);
}
const TVariant& TTS_sender::get(const char* field)
{
return _tsfile->get(field);
}
void TTS_sender::remove_last()
{
_tsfile->destroy(_tsfile->last());
_tsfile->move_last();
}
void TTS_sender::add_ulteriori(const TRecordset& mov)
{
}
void TTS_sender::add_ratei_risconti(const TRecordset& mov)
{
}
void TTS_sender::add_new_rec(const TRecordset& mov, char tipocf, long codcf)
{
if (codcf > 0 && get("TRF-RASO").as_string().blank())
add_clifor(tipocf, codcf);
set("TRF-80-SEGUENTE", "S");
if (new_rec("0"))
{
add_header(mov, false);
set("TRF-80-SEGUENTE", "U");
}
}
void TTS_sender::add_diversi(const TRecordset& mov, const bool moviva)
{
const bool dont_send_clifo = _riclassifica.is_key("TSNOHCLI");
TRecordset & rmov = rmovrecset(mov);
int i = 0 , j = 0;
bool added_rec = false, valid_rec = false, as400 = false;
bool first_cli = true;
TString80 field;
TString16 key;
for (bool ok = rmov.move_first(); ok; ok = rmov.move_next(), i++)
{
const int gr = rmov.get(RMV_GRUPPO).as_int();
const int co = rmov.get(RMV_CONTO).as_int();
const long so = rmov.get(RMV_SOTTOCONTO).as_int();
char t = rmov.get(RMV_TIPOC).as_string()[0];
bool one_clifor =(dont_send_clifo && t > ' ');
const long contoricl = bill2ricl(t, gr, co, so, one_clifor);
bool add_rec = (j >= 80) || (dont_send_clifo && t > ' ');
if (moviva)
{
const char tiporiga = rmov.get(RMV_ROWTYPE).as_string()[0];
switch (tiporiga)
{
case 'T':
case 'I':
case 'D':
case 'N':
continue;
case 'F':
case 'S':
break;
default:
if (i == 0 && _send_cg && tiporiga <= ' ')
as400 = true;
if (!as400)
{
key.format("%08ld", contoricl);
if (_contiiva.is_key(key))
continue;
if (_iva.is_key(key))
{
const char sez = rmov.get(RMV_SEZIONE).as_string()[0];
const bool vendite = mov.get(MOV_TIPO).as_string()[0] != 'F';
if (vendite)
{
if (sez == 'A')
continue;
}
else
{
if (sez == 'D')
continue;
}
}
}
break;
}
}
if (add_rec)
{
if (!first_cli)
{
add_new_rec(mov, t, so);
j = 0;
added_rec = true;
valid_rec = false;
}
first_cli = false;
}
field.format("TRF-CONTO_%d", j);
set(field, contoricl);
field.format("TRF-IMPORTO_%d", j);
set(field, rmov.get(RMV_IMPORTO));
field.format("TRF-DA_%d", j);
set(field, rmov.get(RMV_SEZIONE));
j++;
valid_rec = true;
}
if (added_rec && !valid_rec)
{
remove_last();
set("TRF-80-SEGUENTE", "U");
}
}
void TTS_sender::add_conti_ricavo_costo(const TRecordset& mov)
{
if (_send_cg)
{
TRecordset & rmov = rmovrecset(mov);
rmov.move_first();
if (rmov.get(RMV_ROWTYPE).as_string()[0] <= ' ')
return;
}
TRecordset & riva = rivarecset(mov);
TString codice = scod2ricl("TSREG", mov.get(MOV_REG));
const bool corrispettivo = codice[0] == 'C';
int i = 0, j = 0;
real fattore = UNO;
TString16 key;
if (test_swap(mov))
fattore = -fattore;
_iva.destroy();
for (bool ok = riva.move_first(); ok; ok = riva.move_next(), i++)
{
const int gr = riva.get(RMI_GRUPPO).as_int();
const int co = riva.get(RMI_CONTO).as_int();
const long so = riva.get(RMI_SOTTOCONTO).as_int();
char t = riva.get(RMI_TIPOC).as_string()[0];
const long hcli = movrecset().get(MOV_CODCF).as_int();
const long contoricl = bill2ricl(t, gr, co, so, hcli == so);
real imponibile = riva.get(RMI_IMPONIBILE).as_real() * fattore;
if (corrispettivo)
{
if (riva.get(RMI_IMPOSTA).as_real() == ZERO)
{
TCodiceIVA c(riva.get(RMI_CODIVA).as_string());
c.scorpora(imponibile);
}
}
else
{
const bool indetraibile = riva.get(RMI_TIPODET).as_int() > '0'; //da modificare nella 3.1
if (indetraibile)
imponibile += riva.get(RMI_IMPOSTA).as_real() * fattore;
}
key.format("%08ld", contoricl);
TIVA_item * item = (TIVA_item *) _iva.objptr(key);
if (item == NULL)
{
item = new TIVA_item(j++, contoricl, 0L, 0L);
_iva.add(key, item);
}
item->imponibile() += imponibile;
}
TString80 field;
if (_iva.items() > 8)
log(2, TR("Registrazione con piu<69> di 8 conti di costo/ricavo"));
FOR_EACH_ASSOC_OBJECT(_iva, o, k, it)
{
TIVA_item & item = (TIVA_item &) *it;
const int row = item.row();
if (row < 8)
{
field.format("TRF-CONTORIC_%d", row);
set(field, item.conto());
field.format("TRF-IMP-RIC_%d", row);
set(field, item.imponibile());
}
}
}
bool TTS_sender::test_swap(const TRecordset& mov)
{
TRecordset & rmov = rmovrecset(mov);
rmov.move_first();
const char sez = rmov.get(RMV_SEZIONE).as_string()[0];
const bool vendite = mov.get(MOV_TIPO).as_string()[0] != 'F';
const bool s = vendite ^ (sez == 'D');
return s;
}
void TTS_sender::add_tot_fattura(const TRecordset& mov)
{
real totdoc = mov.get(MOV_TOTDOC).as_real();
if (test_swap(mov))
totdoc = -totdoc;
set("TRF-TOT-FATT", totdoc);
}
void TTS_sender::add_datiiva(const TRecordset& mov)
{
TRecordset & rmoviva = rivarecset(mov);
TString codice = scod2ricl("TSREG", mov.get(MOV_REG));
const bool corrispettivo = codice[0] == 'C';
int i = 0, j = 0;
real fattore = UNO;
TString16 key;
if (test_swap(mov))
fattore = -fattore;
_iva.destroy();
for (bool ok = rmoviva.move_first(); ok; ok = rmoviva.move_next(), i++)
{
real imponibile = rmoviva.get(RMI_IMPONIBILE).as_real() * fattore;
real imposta = rmoviva.get(RMI_IMPOSTA).as_real() * fattore;
if (corrispettivo)
{
if (imposta == ZERO)
{
TCodiceIVA c(rmoviva.get(RMI_CODIVA).as_string());
imposta = c.scorpora(imponibile);
}
}
long codiva = cod2ricl("TSIVA", rmoviva.get(RMI_CODIVA));
long codiva11 = 0L;
const bool indetraibile = rmoviva.get(RMI_TIPODET).as_int() > '0'; //da modificare nella 3.1
if (indetraibile)
codiva += TSMAIALCONST; // maialata
if (rmoviva.get(RMI_TIPOCR).as_int() > 0)
codiva11 = cod2ricl("TSI11", rmoviva.get(RMI_TIPOCR));
key.format("%04ld%04ld", codiva, codiva11);
TIVA_item * item = (TIVA_item *) _iva.objptr(key);
if (item == NULL)
{
item = new TIVA_item(j++, 0L, codiva, codiva11);
_iva.add(key, item);
}
item->imponibile() += imponibile;
item->imposta() += imposta;
}
TString80 field;
if (_iva.items() > 8)
log(2, TR("Registrazione con piu di 8 righe IVA"));
FOR_EACH_ASSOC_OBJECT(_iva, o, k, it)
{
TIVA_item & item = (TIVA_item &) *it;
const int row = item.row();
if (row < 8)
{
field.format("TRF-IMPONIB_%d", row);
set(field, item.imponibile());
field.format("TRF-ALIQ_%d", row);
set(field, item.codiva());
field.format("TRF-ALIQ_AGRICOLA_%d", row);
//set(field,field // dato non presente CHIEDERE
field.format("TRF-IVA11_%d", row);
set(field, item.codiva11());
field.format("TRF-IMPOSTA_%d", row);
set(field, item.imposta());
}
}
}
void TTS_sender::add_header(const TRecordset& mov, const bool fullhesd)
{
const bool moviva = !mov.get(MOV_REG).is_empty();
const long codcaus = cod2ricl("TSCAU", mov.get(MOV_CODCAUS));
// dati obbligatori
set("TRF-DITTA", _dittamulti);
set("TRF-CAUSALE", codcaus);
TString descaus(decode_causale(mov));
set("TRF-CAU-DES", descaus.left(15));
const TDate datareg(mov.get(MOV_DATAREG).as_string());
set("TRF-DATA-REGISTRAZIONE", datareg.string(full, '\0'));
const TDate datadoc( mov.get(MOV_DATADOC).as_string());
set("TRF-DATA-DOC", datadoc.string(full, '\0'));
TString numdoc(mov.get(MOV_NUMDOC).as_string());
TString codice = moviva ? scod2ricl("TSREG", mov.get(MOV_REG)) : EMPTY_STRING;
numdoc.left(6);
if (numdoc.full())
numdoc << codice.mid(1);
set("TRF-NUM-DOC-FOR", numdoc);
set("TRF-NDOC", mov.get(MOV_PROTIVA));
const bool send_clifo = !_riclassifica.is_key("TSNOHCLI");
if (send_clifo)
set("TRF-COD-CLIFOR", mov.get(MOV_CODCF));
if (moviva)
{
const long codreg = atol(codice.mid(1));
set("TRF-SERIE", codreg);
}
}
void TTS_sender::get_citta_provincia(const TRecordset& cli, TString & dencom, TString & provcom, bool nascita)
{
TString16 key;
if (nascita)
{
key << cli.get(CLI_STATONASC);
key << '|' << cli.get(CLI_COMNASC);
}
else
{
key << cli.get(CLI_STATOCF);
key << '|' << cli.get(CLI_COMCF);
}
const TRectype& com = cache().get(LF_COMUNI, key);
dencom.cut(0);
if (!nascita)
dencom << cli.get(CLI_LOCCF) << " ";
dencom << com.get(COM_DENCOM);
dencom.trim();
provcom = com.get(COM_PROVCOM);
}
const char * TTS_sender::decode_causale(const TRecordset& mov)
{
const TRectype& caus = cache().get(LF_CAUSALI, mov.get(MOV_CODCAUS).as_string());
return caus.get(CAU_DESCR);
}
void TTS_sender::add_clifor(char tipocf, long codcf)
{
// dati clienti/fornitore
if (codcf != 0)
{
TRecordset & cli = clirecset(tipocf, codcf);
const char tipocf = cli.get(CLI_TIPOCF).as_string()[0];
TString80 indirizzo;
indirizzo << cli.get(CLI_INDCF) << ' '
<< cli.get(CLI_CIVCF) << ' '
<< cli.get(CLI_LOCCF);
TString ragsoc(cli.get(CLI_RAGSOC).as_string());
const char tipopers = cli.get(CLI_TIPOPERS).as_string()[0];
const bool fisica = tipopers=='F';
int divide = 0;
if (fisica)
{
TString80 r1(ragsoc.left(30));
TString80 r2(ragsoc.mid(30));
r1.trim();
r2.trim();
ragsoc = r1;
divide = ragsoc.len() + 1;
ragsoc << " " << r2;
}
set("TRF-RASO", ragsoc);
set("TRF-IND", indirizzo);
set("TRF-CAP", cli.get(CLI_CAPCF));
TString dencom;
TString4 provcom;
get_citta_provincia(cli, dencom, provcom);
set("TRF-CITTA", dencom.left(80));
set("TRF-PROV", provcom);
set("TRF-COFI", cli.get(CLI_COFI));
set("TRF-PIVA", cli.get(CLI_PAIV));
set("TRF-PF", fisica ? "S" : "N");
set("TRF-DIVIDE", divide);
const long stato = cod2ricl("TSNAZ", cli.get(CLI_STATOCF));
set("TRF-PAESE", stato);
//set("TRF-PIVA-ESTERO",); // partita iva estera
//set("TRF-COFI-ESTERO",); // codice fiscale estero
if (fisica)
{
//set("TRF-SESSO",); // sesso M/F
const TDate dnasc(cli.get(CLI_DATANASC).as_string());
set("TRF-DTNAS", dnasc.string(full, '\0'));
get_citta_provincia(cli, dencom, provcom, true);
set("TRF-COMNA", dencom.left(80));
set("TRF-PRVNA", provcom);
}
set("TRF-PREF", cli.get(CLI_PTEL));
set("TRF-NTELENUM", cli.get(CLI_TEL));
set("TRF-FAX-PREF", cli.get(CLI_PFAX));
set("TRF-FAX-NUM", cli.get(CLI_FAX));
if (tipocf == 'F')
{
const int gr = cli.get(CLI_GRUPPORIC).as_int();
const int co = cli.get(CLI_CONTORIC).as_int();
const int so = cli.get(CLI_SOTTOCRIC).as_int();
char t = tipocf;
const long contoricl = bill2ricl(t, gr, co, so);
set("TRF-CFCONTO", contoricl);
}
const long codpag = cod2ricl("TSCDP", cli.get(CLI_CODPAG));
set("TRF-CFCODPAG", codpag);
set("TRF-CFBANCA", cli.get(CLI_CODABI));
set("TRF-CFAGENZIA", cli.get(CLI_CODCAB));
}
}
void TTS_sender::add_mov(const TRecordset& mov)
{
TString msg; msg << TR("Registrazione n.") << ' ' << mov.get(MOV_NUMREG);
log(0, msg);
if (new_rec("0"))
{
char tipocf = mov.get(MOV_TIPO).as_string()[0];
long codcf = mov.get(MOV_CODCF).as_int();
add_clifor(tipocf, codcf);
add_header(mov);
const bool moviva = !mov.get(MOV_REG).is_empty();
if (moviva)
{
add_datiiva(mov);
add_tot_fattura(mov);
add_conti_ricavo_costo(mov);
}
add_ratei_risconti(mov); // Non ce li abbiamo micca!
add_ulteriori(mov);
add_diversi(mov, moviva);
}
}
const long TTS_sender::bill2ricl(char & t, int gr, int co, long so, const bool header_cli)
{
long codricl = 0;
if (gr > 0)
{
const char* const tiporic = "TSCONTI";
const bool ricl = _riclassifica.is_key(tiporic);
if (ricl)
{
TToken_string cod;
cod.add(tiporic);
cod.add(gr);
cod.add(co);
if (t <= ' ')
cod.add(so);
// Provo il sottoconto ma se non riesco provo con conto e poi anche gruppo
for (int c = 3; c > 0 && codricl <= 0; c--)
{
codricl = atol(_conti->get(cod, "CODICE"));
cod.add(0, c);
}
if (codricl <= 0)
{
TString msg;
msg << TR("Conto") << " " << gr << " " << co << " " << so << " :" << TR("Non presente in tabella");
log(2, msg);
}
else
{
if (codricl % 10000 > 0)
t = ' ';
if (t > ' ')
{
if (header_cli)
{
if (t == 'C')
codricl = 9999999L;
else
codricl = 9999998L;
}
else
codricl += so;
}
}
}
else
codricl = gr*100000+co*1000+so;
}
return codricl;
}
const TString & TTS_sender::scod2ricl(const char* tab, const TString& cod)
{
TString & codricl = get_tmp_string();
if (cod.full())
{
const bool ricl = _riclassifica.is_key(tab);
const char* err = NULL;
if (ricl)
{
codricl = _tabelle->sdecode(tab, cod);
if (codricl.blank())
err = TR("Non presente in tabella");
}
else
codricl = cod;
if (err)
{
TString msg;
msg << TR("Codice") << " " << cod << " " << TR("Tabella") << " " << tab << " :" << err;
log(2, msg);
}
}
return codricl;
}
const TString & TTS_sender::scod2ricl(const char* tab, const TVariant& cod)
{
return scod2ricl(tab, cod.as_string());
}
const long TTS_sender::cod2ricl(const char* tab, const TString& cod)
{
long codricl = 0;
if (cod.full())
{
const bool ricl = _riclassifica.is_key(tab);
const char* err = NULL;
if (ricl)
{
codricl = _tabelle->decode(tab, cod);
if (codricl <= 0)
err = TR("Non presente in tabella");
}
else
{
if (real::is_natural(cod))
codricl = atol(cod);
else
err = TR("Non e' un codice numerico");
}
if (err)
{
TString msg;
msg << TR("Codice") << " " << cod << " " << TR("Tabella") << " " << tab << " :" << err;
log(2, msg);
}
}
return codricl;
}
const long TTS_sender::cod2ricl(const char* tab, const TVariant& cod)
{
return cod2ricl(tab, cod.as_string());
}
void TTS_sender::update_parameters(const TDate & d)
{
if (yesno_box(TR("Confermare il traferimento")))
{
TConfig configtc(CONFIG_DITTA);
TRecordset & mov = movrecset();
configtc.set("TSULTINV", d);
if (mov.items() > 0L)
{
TProgind pi(mov.items(), TR("Conferma movimenti"), true, true);
TLocalisamfile cgmov(LF_MOV);
for (bool ok = mov.move_first(); ok; ok = mov.move_next())
{
if (!pi.addstatus(1))
break;
const long numreg = mov.get(MOV_NUMREG).as_int();
cgmov.put(MOV_NUMREG, numreg);
if (cgmov.read(_isequal, _lock) == NOERR)
{
cgmov.put(MOV_INVIATO, true);
cgmov.rewrite();
}
}
}
}
}
void TTS_sender::set_parameters()
{
TConfig configtc(CONFIG_DITTA);
const TDate d(configtc.get("TSULTINV"));
_from = d;
_dittamulti = configtc.get("TSDitta");
_send_cg = configtc.get_bool("TSSENDCG");
TAssoc_array& tab = configtc.list_variables();
FOR_EACH_ASSOC_STRING(tab, h, k, v)
{
TString16 var(k);
if (var.starts_with("TSR"))
{
const bool ric = (*v > ' ') && strchr("1SXY", *v) != NULL;
if (ric)
{
var.format("TS%s", (const char *)var.mid(3));
_riclassifica.add(var, NULL);
}
}
}
bool go_on = true;
for (int i = 0; go_on; i++)
{
int gr = configtc.get_int("TSGIVA", NULL, i);
if (gr == 0)
go_on = false;
else
{
int co = configtc.get_int("TSCIVA", NULL, i);
long so = configtc.get_long("TSSIVA", NULL, i);
char t = ' ';
long contoricl = bill2ricl(t, gr, co, so);
TString16 key; key.format("%08ld", contoricl);
_contiiva.add(key, NULL);
}
}
}
bool TTS_sender::create()
{
_tabelle = new TRiclassifica_cache;
_conti = new TRecord_cache(LF_RICLPDC, 3);
set_parameters();
return TSkeleton_application::create();
}
bool TTS_sender::destroy()
{
delete _conti;
delete _tabelle;
return TSkeleton_application::destroy();
}
TRecordset & TTS_sender::movrecset(const TDate & from, const TDate & to)
{
TRecordset * mov = (TRecordset *) _recsets.objptr(LF_MOV);
if (mov == NULL)
{
TString query = "USE MOV KEY 2 SELECT INVIATO!=\"X\"";
query << "\nFROM DATAREG=#DATA_DA";
query << "\nTO DATAREG=#DATA_AL";
_recsets.add(::create_recordset(query), LF_MOV);
mov = (TRecordset *) _recsets.objptr(LF_MOV);
}
if (from != eotime)
mov->set_var("#DATA_DA", TVariant(from));
if (to != botime)
mov->set_var("#DATA_AL", TVariant(to));
return *mov;
}
TRecordset & TTS_sender::rmovrecset(const TRecordset & mov)
{
TRecordset * rmov = (TRecordset *) _recsets.objptr(LF_RMOV);
if (rmov == NULL)
{
_recsets.add(::create_recordset("USE RMOV\nFROM NUMREG=#NUMREG\nTO NUMREG=#NUMREG"), LF_RMOV);
rmov = (TRecordset *) _recsets.objptr(LF_RMOV);
}
const TVariant & numreg = mov.get(MOV_NUMREG);
if (numreg != rmov->get("#NUMREG"))
rmov->set_var("#NUMREG", numreg);
return *rmov;
}
TRecordset & TTS_sender::rivarecset(const TRecordset & mov)
{
TRecordset * rmoviva = (TRecordset *) _recsets.objptr(LF_RMOVIVA);
if (rmoviva == NULL)
{
_recsets.add(::create_recordset("USE RMOVIVA\nFROM NUMREG=#NUMREG\nTO NUMREG=#NUMREG"), LF_RMOVIVA);
rmoviva = (TRecordset *) _recsets.objptr(LF_RMOVIVA);
}
const TVariant & numreg = mov.get(MOV_NUMREG);
if (numreg != rmoviva->get("#NUMREG"))
rmoviva->set_var("#NUMREG", numreg);
return *rmoviva;
}
TRecordset & TTS_sender::clirecset(const char tipocf, const long codcf)
{
TRecordset * clifo = (TRecordset *) _recsets.objptr(LF_CLIFO);
if (clifo == NULL)
{
_recsets.add(::create_recordset("USE CLIFO\nFROM TIPOCF=#TIPOCF CODCF=#CODCF\nTO TIPOCF=#TIPOCF CODCF=#CODCF"), LF_CLIFO);
clifo = (TRecordset *) _recsets.objptr(LF_CLIFO);
}
TString4 w; w << tipocf;
TVariant t(w);
clifo->set_var("#TIPOCF", t);
clifo->set_var("#CODCF", codcf);
return *clifo;
}
void TTS_sender::main_loop()
{
TTS_mask m;
TDate to(TODAY);
to.addmonth(-1);
to.set_end_month();
if (to <= _from)
{
to = _from;
to.addmonth(1);
to.set_end_month();
}
m.set(F_DATA_DA, _from);
m.set(F_DATA_AL, to);
while (m.run() != K_QUIT)
{
const char* const title = TR("Invio a TeamSystem");
_tsfile = new TTS_textset;
_log = new TLog_report(title);
_errors_logged = false;
TRecordset & mov = movrecset(m.get_date(F_DATA_DA), m.get_date(F_DATA_AL));
TProgind pi(mov.items(), TR("Scansione movimenti"), true, true);
for (bool ok = mov.move_first(); ok; ok = mov.move_next())
{
if (!pi.addstatus(1))
break;
add_mov(mov);
}
TReport_book book;
book.add(*_log);
#ifdef DBG
TAS400_report rep(*_tsfile);
book.add(rep);
#endif
book.preview();
bool save = true;
if (_errors_logged)
{
save = yesno_box(TR("Sono stati riscontrati uno o piu' errori:\n"
"Si desidera salvare il file ugualmente?"));
}
if (save)
{
TFilename name = m.get(F_PATH);
name.add(m.get(F_FILE));
_tsfile->save_as(name);
update_parameters(m.get_date(F_DATA_AL));
}
delete _log;
delete _tsfile;
}
}
int tc0700(int argc, char* argv[])
{
TTS_sender app;
app.run(argc, argv, "Invio a TeamSystem");
return 0;
}