campo-sirio/crpa/crpa0.cpp
luca 12cf07f356 Patch level :
Files correlati     :
Ricompilazione Demo : [ ]
Commento            :


git-svn-id: svn://10.65.10.50/trunk@18313 c028cbd2-c16b-5b4b-a496-9718f37d4682
2009-02-23 11:30:11 +00:00

1200 lines
36 KiB
C++
Executable File

#include <applicat.h>
#include <dongle.h>
#include <execp.h>
#include <odbcrset.h>
#include <tabutil.h>
#include <utility.h>
#include <clifo.h>
#include <cfven.h>
#include <mov.h>
#include "../ce/collces.h"
#include "../ve/velib.h"
#include "../cg/cg2103.h"
#include "../ca/movana.h"
#include "../ca/rmovana.h"
// Fine del comando sql con separatore magico per crpa.exe
#define SQL_EOL "æ"
class TIni2Sql: public TSkeleton_application
{
TRelation* _clifo;
TConfig* _configfile;
TConfig* _inputfile;
ofstream* _sqlfile;
TLocalisamfile* _anamag;
TLocalisamfile* _fcaus;
TLocalisamfile* _frcaus;
TCausale * _caus;
long _firm;
TDocumento* _doc;
TDocumento* _dadoc;
TRiga_documento* _rigadoc;
TFilename _inputfilename;
TBill _conto;
TToken_string _search_seq;
// Sequenza di ricerca del conto costo/ricavo la correttezza dell'ordinamento
// va controllata nel programma di modifica parametri:
// "" = fine ordinamento
// CF = cliente fornitore
// CA = causale
// AR = articolo (costo/ricavo)
// GM = gruppo merceologico
// SM = sottogruppo merceologico
// RF = raggruppamento fiscale
// CV = categoria di vendita
// CC = categoria contabile
// Gli utlimi 6 fanno parte della ricerca per costi ricavi, in particolare AR,GM,SM e RF
// non possono essere interrotti da CV o CC. Ad es. CA|CF|AR|CV|GM|CC|RF non e' valida come stringa
// di ricerca.
protected:
virtual bool create(void);
virtual void main_loop();
virtual bool destroy(void);
virtual const char * extra_modules() const { return "BA"; }
void process_field(const TString& inputfield, TString& outputstr, int len = -1, const bool apici = TRUE);
void validate(const TString& elabfield, TString& outputstr);
void leggidadoc(const TString& elabfield, TString& outputstr);
void build_paragraph(const TString& paragrafo, TString& outputstr);
int build_nriga(const TString& paragrafo);
int get_tipo_dadoc(const TDocumento& doc) const;
int get_tipo_doc(const TDocumento& doc) const;
bool get_fdaric_dadoc(const TDocumento& doc) const;
long get_protiva(const TDocumento& doc) const;
bool search_costo_ricavo(TBill& conto, const TRiga_documento& r);
bool search_conto_cespite(TBill& conto, const TRiga_documento& r);
bool test_swap() const;
bool test_swap_conto(const int gr, const int co, const char sezione) const;
public:
void write_sqlinsert();
void write_sqldelete();
TIni2Sql();
virtual ~TIni2Sql() {}
};
TIni2Sql::TIni2Sql()
{
if (user().blank())
user() = dongle().administrator();
}
// restituisce un riferimento all' applicazione
inline TIni2Sql& app() { return (TIni2Sql&) main_app();}
// creazione dell'applicazione
bool TIni2Sql::create()
{
if (argc() > 1)
{
_inputfilename = argv(1);
if (_inputfilename[0] == '/' || _inputfilename[0] == '-')
_inputfilename.ltrim(2);
if (_inputfilename.exist())
{
open_files(LF_MOV, LF_RMOV, LF_RMOVIVA, LF_DOC, LF_RIGHEDOC, LF_MOVANA, LF_RMOVANA, LF_CLIFO, LF_PCON, LF_ABPCON, LF_CFVEN, LF_TABCOM, LF_TAB, 0);
_inputfile = new TConfig(_inputfilename);
_configfile = new TConfig("crpa.ini");
_sqlfile = NULL;
_doc = NULL;
_dadoc = NULL;
_rigadoc = NULL;
_clifo = new TRelation(LF_CLIFO);
_clifo->add(LF_CFVEN,"TIPOCF=TIPOCF|CODCF=CODCF");
_anamag = new TLocalisamfile(LF_ANAMAG);
_fcaus = new TLocalisamfile(LF_CAUSALI);
_frcaus = new TLocalisamfile(LF_RCAUSALI);// Per far andare TCausale
return TSkeleton_application::create();
}
else
error_box("Il file %s non esiste", (const char*) _inputfilename);
}
else
error_box("Usage: CRPA0 -i<filename>");
return FALSE;
}
bool TIni2Sql::test_swap_conto(const int gr, const int co, const char sezione) const
{
TString8 key; key.format("%d|%d", gr, co);
const int indbil = atoi(cache().get(LF_PCON, key, "INDBIL"));
return ((indbil == 3) && (sezione == 'A')) || ((indbil == 4) && (sezione == 'D'));
}
bool TIni2Sql::test_swap() const
{
bool s = false;
if (_caus != NULL && *_caus->codice() > ' ') // esiste la causale
{
const char sez = _caus->sezione_clifo();
const TipoIVA iva = _caus->iva();
const bool vendite = iva == nessuna_iva ? _doc->tipocf() == 'C' : iva == iva_vendite;
s = vendite ^ (sez == 'D');
}
return s;
}
// legge da documento o da riga il campo indicato (primo carattere = #)
// se occorre usare una funzione dei doc. o delle righe si fa seguire al carattere # la stringa
// ?? !_,<nome elaborazione>
void TIni2Sql::leggidadoc(const TString& elabfield, TString& tmpstr)
{
tmpstr="";
TToken_string s(elabfield, ',') ;
const TString code(s.get(0));
const TString field(s.get(1));
if (code == "!_")
{
if (field == "IMPORTO")
{
if (_rigadoc != NULL)
{
bool non_rilevante = false;
const bool acquisto = _doc->tipocf() == 'F';
if (acquisto)
{
const TString& codcms = _rigadoc->codice_commessa();
non_rilevante = cache().get("CMS", codcms, "S7") == "NR";
}
real importo = _rigadoc->importo(true, non_rilevante);
if (acquisto && !non_rilevante)
{
const TString4 tipodet = _rigadoc->get(RDOC_TIPODET);
CHECK(_caus,"Causale documento non valida");
if (tipodet.full())
{
const int anno = _doc->get_date(DOC_DATADOC).year();
int tdet = 0;
const real perc_ind = indetraibile_al(tipodet, *_caus, anno, tdet);
const int dec = _rigadoc->doc().decimals();
real impind = importo * perc_ind / CENTO; impind.round(dec);
const TCodiceIVA iva(_rigadoc->get(RDOC_CODIVA));
const real ivaind = iva.imposta(impind, dec);
importo += ivaind;
}
}
if (test_swap())
importo = -importo;
tmpstr = importo.string();
}
}
else if (field == "QTA")
{
if (_rigadoc != NULL)
{
real qta;
if (_doc->is_evaso())
qta = _rigadoc->qtaevasa();
else
qta = _rigadoc->quantita();
tmpstr = qta.string();
}
}
else if (field == "COMMESSA")
{
if (_rigadoc != NULL)
{
tmpstr = _rigadoc->codice_commessa();
tmpstr.upper();
tmpstr.replace('/','_');
}
}
else if (field == "FASE")
{
if (_rigadoc != NULL)
{
tmpstr = _rigadoc->fase_commessa();
tmpstr.upper();
tmpstr.replace('/','_');
}
}
else if (field == "DATACONS")
{
if (_rigadoc != NULL)
{
TString str = _rigadoc->get(field);
TDate datactrl(str);
if (!datactrl.ok())
{
str = _doc->get(field);
datactrl = TDate(str);
}
if (datactrl.ok())
tmpstr.format("TO_DATE('%s','dd-mm-yyyy')", (const char*) str);
}
}
}
else if (code == "DRDOC")
{
if (_rigadoc != NULL)
{
TString str = _rigadoc->get(field);
TDate datactrl(str);
if (datactrl.ok())
tmpstr.format("TO_DATE('%s','dd-mm-yyyy')", (const char*) str);
}
}
else if (code == "DOC")
{
if (_doc != NULL)
tmpstr = _doc->get(field);
}
else if (code == "RDOC")
{
if (_rigadoc != NULL)
tmpstr = _rigadoc->get(field);
}
}
bool TIni2Sql::search_costo_ricavo(TBill& conto, const TRiga_documento& r)
{
if (_search_seq.empty())
{
TConfig conf(CONFIG_DITTA, "ve");
_search_seq = conf.get("RICERCACR");
// costruisce la stringa che controlla la ricerca del conto costo/ricavo
// Attenzione! non esegue alcun controllo di consistenza sulla corretta sequenza
// presuppone che il programma di configurazione abbia generato correttamente
// il tutto.
if (_search_seq.items() == 0)
{
error_box("Non e' abilitata alcuna ricerca per il conto di costo/ricavo in configurazione.");
return FALSE;
}
}
const int items = _search_seq.items();
TLocalisamfile& cli_file = _clifo->lfile(); // YES, arriva qui dentro quando la relazione e' gia' posizionata
const bool is_cli = cli_file.get(CLI_TIPOCF) == "C";
bool skip_art_related = FALSE;
bool skip_clifo = _clifo->bad();
TCodiceIVA codiva(r.get(RDOC_CODIVA));
const char t = r.tipo().tipo();
// Istanzia la causale del documento corrente...
const TTipo_documento& tipo = _doc->tipo(); // deve diventare tipo_riclassificato()
TString16 codcaus(tipo.causale());
TToken_string key;
key.add(_doc->get(DOC_TIPOCF));
key.add(_doc->get(DOC_CODCF));
const TRectype & cfven = cache().get(LF_CFVEN, key);
const TString16 caus_cli(cfven.get(CFV_CODCAUS));
if (caus_cli.not_empty())
codcaus = caus_cli;
TDate data = _doc->data();
_caus = new TCausale(codcaus, data.year());
int gr,co;
long so;
switch (t)
{
case 'O': // righe omaggio come articoli spiaccicato identico (avranno imponibile 0)
case 'M': // righe di merce
{
// posiziona l'anagrafica sull'articolo specificato sulla ..iga
TString80 codart = r.get(RDOC_CODARTMAG);
if (codart.blank())
codart = r.get(RDOC_CODART);
_anamag->put(ANAMAG_CODART, codart);
if (_anamag->read() != NOERR) // se non trova l'articolo saltera' anche gmc,smc,rfa.
skip_art_related = TRUE;
TString16 tok;
// Scorre la stringa di ricerca
for (int i=0;i<items;i++)
{
tok = _search_seq.get(i);
if (tok == "CF")
{
if (skip_clifo) continue;
gr = cli_file.get_int(CLI_GRUPPORIC);
co = cli_file.get_int(CLI_CONTORIC);
so = cli_file.get_long(CLI_SOTTOCRIC);
conto.set(gr,co,so);
if (conto.ok()) break; // se lo trova esce (tutti != 0)
}
else
if (tok == "CA")
{
CHECK(_caus,"Causale documento non valida");
if (_caus->IVA2bill(codiva,conto)) break; // se lo trova esce
}
else
if (tok == "AR")
{
if (skip_art_related) continue;
gr = _anamag->get_int(is_cli ? ANAMAG_GRUPPOV : ANAMAG_GRUPPOA);
co = _anamag->get_int(is_cli ? ANAMAG_CONTOV : ANAMAG_CONTOA);
so = _anamag->get_long(is_cli ? ANAMAG_SOTTOCV : ANAMAG_SOTTOCA);
conto.set(gr,co,so);
if (!conto.ok()) // se il conto non c'e' guarda la categoria acquisti/vendite
{
const TString16 catcon = _anamag->get(is_cli ? ANAMAG_CATCONV : ANAMAG_CATCONA);
const TRectype& cat = cache().get(is_cli ? "CRA" : "CAA", catcon);
if (!cat.empty())
{
gr = cat.get_int("S1");
co = cat.get_int("S2");
so = cat.get_long("S3");
conto.set(gr,co,so);
}
}
if (conto.ok())
break;
}
else
if (tok == "GM" || tok == "SM" || tok == "RF")
{
if (skip_art_related) continue;
const bool is_fis = tok == "RF";
TString16 codtab = _anamag->get(is_fis ? ANAMAG_RAGGFIS : ANAMAG_GRMERC);
if (tok == "GM" && codtab.len() > 3)
codtab.cut(3); // gli ultimi 2 si riferiscono al sottogruppo.
const TRectype& tab = cache().get(is_fis ? "RFA" : "GMC", codtab);
if (!tab.empty())
{
gr = tab.get_int(is_cli ? "I3" : "I0");
co = tab.get_int(is_cli ? "I4" : "I1");
so = tab.get_long(is_cli ? "I5" : "I2");
conto.set(gr,co,so);
}
if (conto.ok()) break;
}
else
if (tok == "CV" || tok == "CC")
{
const bool is_cve = tok == "CV";
if (is_cve && !is_cli)
continue; // se e' un fornitore salta questa condizione
TString16 cod = is_cve ? r.doc().get(DOC_CATVEN) : EMPTY_STRING;
if (cod.empty())
{
if (skip_clifo) continue; // se non aveva trovato il cliente salta al prossimo
cod = _clifo->lfile(LF_CFVEN).get(is_cve ? CFV_CATVEN : CFV_CODCATC);
}
const TRectype& t = cache().get(is_cve ? "CVE" : "CCO", cod);
if (!t.empty())
{
const bool x =(is_cve || is_cli);
gr = t.get_int(x ? "I3" : "I0");
co = t.get_int(x ? "I4" : "I1");
so = t.get_long(x ? "I5": "I2");
conto.set(gr,co,so);
}
if (conto.ok())
break;
}
}
break; // case 'M'
}
case 'P': // righe prestazione
case 'S': // righe spese
{
const TRectype& tab = cache().get(t == 'P' ? "PRS" : "SPP", r.get(RDOC_CODART));
if (!tab.empty())
{
gr = tab.get_int(is_cli ? "I0" : "I3");
co = tab.get_int(is_cli ? "I1" : "I4");
so = tab.get_long(is_cli ? "I2" : "I5");
conto.set(gr,co,so);
if (!is_cli && !conto.ok())
{
gr = r.get_int("QTAGG1");
co = r.get_int("QTAGG2");
so = r.get_long("QTAGG3");
conto.set(gr,co,so);
}
}
if (!conto.find() && t == 'P') // Cerca il conto nella stringa di ricerca (solo per prestazioni)
{
TString16 tok;
// Scorre la stringa di ricerca ma solo per causale o CLI/FO
for (int i=0;i<items;i++)
{
tok = _search_seq.get(i);
if (tok == "CF")
{
if (skip_clifo) continue;
gr = cli_file.get_int(CLI_GRUPPORIC);
co = cli_file.get_int(CLI_CONTORIC);
so = cli_file.get_long(CLI_SOTTOCRIC);
conto.set(gr,co,so);
if (conto.ok()) break;
}
else
if (tok == "CA")
{
CHECK(_caus,"Causale documento non valida");
if (_caus->IVA2bill(codiva,conto)) break;
}
}
}
break; // case 'P','S'
}
case 'C':
// righe sconti: vengono considerate in adjust_sconto_rows()
case 'D': // righe descrizioni (saltare)
default :
break;
} // end of switch
return (conto.ok());
}
long TIni2Sql::get_protiva(const TDocumento& doc) const
{
long protiva = 0;
// solo se é un documento di spesa (chiedere??)
// e solo se é stato contabilizzato
if (!doc.tipo().is_generic())
{
// creo un cursore con
// tipocf, codcf, datareg = datadoc
TRelation relmov(LF_MOV);
TRectype da(LF_MOV);
da.put(MOV_TIPO, doc.tipocf());
da.put(MOV_CODCF, doc.codcf());
da.put(MOV_DATAREG, doc.data());
TCursor curmov(&relmov, "", 3, &da, &da);
TString str;
const TString& rif = doc.riferimento(str);
long count = curmov.items();
curmov = 0;
while ((curmov.pos() < count) && (protiva == 0))
{
TString desmov = curmov.curr().get(MOV_DESCR);
if (desmov.find(rif) >= 0)
protiva = curmov.curr().get_long(MOV_PROTIVA);
++curmov;
}
}
return protiva;
}
int TIni2Sql::get_tipo_doc(const TDocumento& doc) const
{
const TString4 codnum = doc.get(DOC_CODNUM);
int tipo = atoi(cache().get("%NUM", codnum, "I1"));
return tipo;
}
int TIni2Sql::get_tipo_dadoc(const TDocumento& doc) const
{
int datipo = 0;
for (int r = 1; r <= doc.rows(); r++)
{
const TRiga_documento& rdoc = doc[r];
const TString4 dacodnum = rdoc.get(RDOC_DACODNUM);
if (dacodnum.not_empty())
{
datipo = atoi(cache().get("%NUM", dacodnum, "I1"));
break;
}
}
return datipo;
}
bool TIni2Sql::get_fdaric_dadoc(const TDocumento& doc) const
{
bool daric = FALSE;
for (int r = 1; r <= doc.rows(); r++)
{
const TRiga_documento& rdoc = doc[r];
const TString4 dacodnum = rdoc.get(RDOC_DACODNUM);
if (dacodnum.not_empty())
{
daric = cache().get("%NUM", dacodnum).get_bool("B3");
break;
}
}
return daric;
}
// esegue l'elaborazione indicata
void TIni2Sql::validate(const TString& elabfield, TString& str)
{
TString tmpstr = "";
str="";
TToken_string s(elabfield, ',') ;
const TString code(s.get(0));
if (code == "_D") // campo da trasformare in data
{
tmpstr = _inputfile->get((s.get()));
TDate datactrl(tmpstr);
if (datactrl.ok())
str.format("TO_DATE('%s','dd-mm-yyyy')", (const char*) tmpstr);
}
else if (code == "_T") // campo da tagliare alla lunghezza indicata
{
int len = atoi(s.get(1));
tmpstr = s.get(2);
process_field(tmpstr, str, len, FALSE);
}
else if (code == "_DATAORA") // campo che contiene data e ora del momento
{
TDate today(TODAY);
char time[128];
_strtime(time);
str.format("TO_DATE('%s %s','dd-mm-yyyy hh24:mi:ss')", today.string(), time);
}
else if (code == "_FIRM") // campo ditta (01, 02, ...)
{
tmpstr = s.get();
if (tmpstr.empty())
str.format("%02ld", _firm);
else
str.format("%02ld%s", _firm, (const char*) tmpstr);
}
else if (code == "_UNICMOV") // campo UNICARCH nel caso di movimenti
{
const char* codcaus = _inputfile->get("CODCAUS","107");
const char* annoes = _inputfile->get("ANNOES", "107");
long numreg = _inputfile->get_long(MOVANA_NUMREGCG, "107");
if (numreg <= 0)
numreg = _inputfile->get_long(MOVANA_NUMREG, "107");
str.format("%s-%s-%ld", codcaus, annoes, numreg);
}
else if (code == "_UNICDOC") // campo UNICARCH nel caso di documenti
str.format("%s-%s-%s", (const char*) _inputfile->get("CODNUM", "33"), (const char*) _inputfile->get("ANNO", "33"), (const char*) _inputfile->get("NDOC", "33"));
else if (code == "_CODVAL") // campo codice valuta
{
tmpstr = _inputfile->get("CODVAL");
if ((tmpstr[0] == '"') || (tmpstr.empty()))
{
TExchange e;
tmpstr = e.get_value();
}
str = _configfile->get(tmpstr, "Codice valuta");
}
else if (code == "_ELSPESAMOV" || code == "_ELSPESADOC") // campo ELSPESA
{
TToken_string key;
if (code == "_ELSPESAMOV") // per righe movimenti
{
key = _inputfile->get("CODCONTO");
key.insert("|", 6);
key.insert("|", 3);
}
else // per righe documenti
key.format("%d|%d|%ld", _conto.gruppo(), _conto.conto(), _conto.sottoconto());
if (!key.empty_items())
{
key = cache().get(LF_PCON, key, "CODCBL");
str = cache().get(LF_ABPCON, key, "DESCRIZ");
str.cut(6);
str.upper();
}
else
str.cut(0);
}
else if (code == "_DESRMOV") // campo DESART per righe movimenti
{
process_field("DESCR", tmpstr, -1, FALSE);
str.format("%s-%s", (const char*) _inputfile->get("CODCAUS","107"), (const char*) tmpstr);
}
else if (code == "_DESMOV") // campo DESART per movimenti
{
process_field("DESCR", tmpstr, -1, FALSE);
str.format("%s (%s)", (const char*) tmpstr, (const char*) _inputfile->get("PROTIVA"));
}
else if (code == "_CODART") // campo CODART per movimenti
{
str = _inputfile->get("CODCONTO");
str.format("%d-%d-%ld", atoi(str.left(3)), atoi(str.mid(3,3)), atol(str.right(6)));
}
else if (code == "_IMPORTORMOV") // campo importo per righe movimenti
{
real importo(_inputfile->get("IMPORTO"));
//const int gruppo = atoi(_inputfile->get("GRUPPO"));
//const int conto = atoi(_inputfile->get("CONTO"));
TString80 codcosto;
codcosto = _inputfile->get("CODCCOSTO");
const int gruppo = atoi(codcosto.sub(0,3));
const int conto = atoi(codcosto.sub(3,3));
str = _inputfile->get("SEZIONE");
const char sezione = str[0];
if (test_swap_conto(gruppo, conto, sezione))
importo = importo * (-1);
str = importo.string();
}
else if (code == "_SEZIONERMOV") // campo sezione per righe movimenti
{
//const int gruppo = atoi(_inputfile->get("GRUPPO"));
//const int conto = atoi(_inputfile->get("CONTO"));
TString80 codcosto;
codcosto = _inputfile->get("CODCCOSTO");
const int gruppo = atoi(codcosto.sub(0,3));
const int conto = atoi(codcosto.sub(3,3));
str = _inputfile->get("SEZIONE");
const char sezione = str[0];
if (test_swap_conto(gruppo, conto, sezione))
{
if (sezione == 'D')
str = "A";
else if (sezione == 'A')
str = "D";
}
}
else if (code == "_DESDOC") // campo DESDOC per documenti
{
TString16 key = _doc->numerazione();
TString desnum = cache().get("%NUM", key, "S0");
key = _inputfile->get("TIPOCF");
key << '|' << _inputfile->get("CODCF");
TString ragsoc = cache().get(LF_CLIFO, key, "RAGSOC");
long protiva = get_protiva(*_doc);
str.format("%s-%s",(const char*) desnum, (const char*) ragsoc);
if (protiva != 0)
str << '(' << protiva << ')';
TString16 tipodoc = _doc->tipo().codice();
TToken_string descrizioni = _configfile->get(tipodoc, "Descrizioni");
TString16 separatore = _configfile->get("SEPARATORE", "Descrizioni");
TString80 cod;
FOR_EACH_TOKEN(descrizioni,tok)
{
cod = tok;
int virgola = cod.find(',');
if (virgola > -1)
{
TString80 prompt = cod.sub(0,virgola);
TString80 campo = cod.sub(virgola+1);
str << separatore;
str << prompt;
str << _doc->get(campo);
}
}
}
else if (code == "_TIPODOC") // campo TIPDOC
{
if (_doc != NULL)
{
const int tipodoc = get_tipo_doc(*_doc);
if (tipodoc == TTipo_documento::_ordine)
tmpstr = "O";
else if (tipodoc == TTipo_documento::_bolla)
{
// restituisce il tipo documento origine della prima riga che ha un doc. di origine
const int datipodoc = get_tipo_dadoc(*_doc); // si assume che sia il tipo documento di origine per tutto il documento
tmpstr = (datipodoc == TTipo_documento::_ordine) ? "BO" : "B";
}
else if (tipodoc == TTipo_documento::_fattura || tipodoc == TTipo_documento::_altro)
{
const bool daricevere = cache().get("%NUM", _doc->numerazione()).get_bool("B3");
if (daricevere)
tmpstr = "FR";
else if (tipodoc == TTipo_documento::_fattura)
{
const int datipodoc = get_tipo_dadoc(*_doc);
if (datipodoc == TTipo_documento::_bolla)
tmpstr = "FB";
else if (datipodoc == TTipo_documento::_ordine)
tmpstr = "FO";
else
{
const bool daric = get_fdaric_dadoc(*_doc);
tmpstr = daric ? "FF" : "F";
}
}
}
str = _configfile->get(tmpstr, "Tipo documento");
}
}
else if ((code == "_RIFORD") || (code == "_RIFBOL")) // campi RIFORD e RIFBOL
{
if (_dadoc != NULL)
{
const int ord_bol = get_tipo_doc(*_dadoc);
const bool daricevere = cache().get("%NUM", _dadoc->numerazione()).get_bool("B3");
if (((ord_bol == TTipo_documento::_ordine || daricevere) && (code == "_RIFORD")) || ((ord_bol == TTipo_documento::_bolla) && (code == "_RIFBOL")))
{
str << _dadoc->numerazione() << '-';
str << _dadoc->anno() << '-';
str << _dadoc->numero();
}
}
}
}
// prende nome campo di input indicato nel file crpa.ini (puo' essere un campo o una elaborazione)
// e mi restituisce il valore da inserire in VALUES
void TIni2Sql::process_field(const TString& inputfield, TString& tmpstr, int len, const bool apici)
{
tmpstr.cut(0);
if (inputfield.not_empty())
{
// campo elaborato
if (inputfield[0] == '!')
validate(inputfield.sub(1), tmpstr);
// valore fisso
else if (inputfield[0] == ':')
tmpstr = inputfield.sub(1);
// il campo va letto dai documenti o dalle righe
else if (inputfield[0] == '#')
leggidadoc(inputfield.sub(1), tmpstr);
// campo da leggere dal file di input
else if (inputfield == "CODVAL")
{
tmpstr = _inputfile->get(inputfield);
if ((tmpstr[0] == '"') || (tmpstr.empty()))
{
TExchange e;
tmpstr = e.get_value();
tmpstr = tmpstr.sub(0,2);
}
}
else if (inputfield == "CODCMS")
{
tmpstr = _inputfile->get(inputfield);
tmpstr.upper();
tmpstr.replace('/','_');
}
else if (inputfield == "FASCMS")
{
tmpstr = _inputfile->get(inputfield);
tmpstr.upper();
tmpstr.replace('/','_');
}
else if (inputfield == "CODCF")
{
long codcf = _inputfile->get_long(inputfield);
if (codcf != 0)
{
if (_firm == 2)
codcf+=100000;
tmpstr.format("%ld", codcf);
}
}
else
{
tmpstr = _inputfile->get(inputfield);
if (tmpstr.find('.') >= 0 && real::is_real(tmpstr))
{
const real n = tmpstr;
tmpstr = n.string();
}
}
tmpstr.trim();
if (tmpstr.not_empty())
{
if ((tmpstr.sub(0,7) != "TO_DATE") && apici)
{
int l = tmpstr.find("'");
while (l >= 0)
{
tmpstr.insert("'",l);
l = tmpstr.find("'",l+2);
}
}
int l = tmpstr.len();
if ((tmpstr[0] == '"') && (tmpstr[l-1] == '"'))
tmpstr = tmpstr.sub(1,l-1);
tmpstr.trim();
if (len >= 0)
tmpstr.cut(len);
if (apici && tmpstr.not_empty() && (tmpstr.sub(0,7) != "TO_DATE"))
{
tmpstr.insert("'"); tmpstr << '\'';
}
}
}
}
// distruzione dell'applicazione
bool TIni2Sql::destroy()
{
delete _fcaus;
delete _frcaus;
delete _anamag;
delete _clifo;
delete _inputfile;
delete _configfile;
if (_sqlfile != NULL)
delete _sqlfile;
if (_doc != NULL)
delete _doc;
if (_dadoc != NULL)
delete _doc;
if (_rigadoc != NULL)
delete _rigadoc;
return TSkeleton_application::destroy();
}
void TIni2Sql::build_paragraph(const TString& paragrafo, TString& output)
{
output = paragrafo;
const int posvirgola = output.find(',');
if (posvirgola > 0)
output.cut(posvirgola);
}
int TIni2Sql::build_nriga(const TString& paragrafo)
{
int nriga = 0;
const int posvirgola = paragrafo.find(',');
if (posvirgola > 0)
nriga = atoi(paragrafo.sub(posvirgola+1));
return nriga;
}
bool TIni2Sql::search_conto_cespite(TBill& conto, const TRiga_documento& r)
{
int gr,co;
long so;
int codcat;
TString16 idcesp = r.get(RDOC_CODART);
if (idcesp.empty())
codcat = r.doc().get_int(DOC_NDOC);
else
{
const TRectype& cespi = cache().get(LF_CESPI, idcesp);
codcat = cespi.get_int("CODCAT");
}
TEsercizi_contabili esercizi;
int esc = esercizi.date2esc(r.doc().get_date(DOC_DATADOC));
TString16 str; str.format("%04d", esc);
TTable tabccb("CCB");
tabccb.put("CODTAB", str);
tabccb.read();
TString80 codtab = tabccb.get("CODTAB");
if (codtab.sub(0,4) == str)
{
int codgruppo = atoi(codtab.sub(5,6));
const char* codspecie = codtab.sub(7,10);
TLocalisamfile collces(LF_COLLCES);
collces.zero();
collces.put(COLLCES_CODGRUPPO, codgruppo);
collces.put(COLLCES_CODSPECIE, codspecie);
collces.put(COLLCES_CODCAT, codcat);
collces.read();
gr = collces.get_int(COLLCES_GRUPPOQNO);
co = collces.get_int(COLLCES_CONTOQNO);
so = collces.get_int(COLLCES_SOTTOCQNO);
conto.set(gr,co,so);
}
return (conto.ok());
}
// scrive il file che contiene il comando insert completo dei record da inserire
void TIni2Sql::write_sqlinsert()
{
bool is_cespite = false;
TString80 numcesp = _configfile->get("CodNum", "Cespiti");
TString_array lp;
if (_inputfile->list_paragraphs(lp) > 0)
{
bool almenounariga = false;
TString insert, colonne, valori;
_firm = _inputfile->get_int("Firm", "Transaction");
TString16 firm;
firm.format("%ld", _firm);
if (_configfile->get(firm, "Ditte")[0] == 'S')
{
if (_firm != get_firm())
{
set_firm(_firm);
_search_seq.cut(0); // Forzo ricostruzione della sequenza
}
FOR_EACH_ARRAY_ROW(lp, p, paragrafo)
{
if (*paragrafo == "Transaction")
{
}
else
{
TString strpar;
build_paragraph(*paragrafo, strpar);
insert.format("INSERT INTO %s", (const char*) _configfile->get("TABLE", strpar));
colonne = NULL;
valori = NULL;
_inputfile->set_paragraph(*paragrafo);
bool ok = TRUE; // se e' una riga va passata solo ad alcune condizioni
if (strpar == "33") // creo subito il TDocumento per usare tutti i metodi offerti gratis
{
if (_doc == NULL)
{
const TString16 codnum = _inputfile->get("CODNUM");
is_cespite = (codnum == numcesp);
const char provv = _inputfile->get("PROVV")[0];
const int anno = atoi(_inputfile->get("ANNO"));
const long numdoc = atol(_inputfile->get("NDOC"));
_doc = new TDocumento(provv, anno, codnum, numdoc);
_clifo->lfile().put(CLI_TIPOCF, _doc->tipocf());
_clifo->lfile().put(CLI_CODCF, _doc->codcf());
_clifo->read();
}
}
// se riga movimento deve avere gruppo inserito nel pragrafo gruppi di crpa.ini
if (strpar == "24")
{
const TString8 gruppo = _inputfile->get("GRUPPO");
ok = _configfile->get_bool(gruppo, "Gruppi");
}
if (strpar == "108")
{
TString16 gruppo = _inputfile->get("CODCONTO");
gruppo.cut(3);
gruppo.format("%d", atoi(gruppo));
ok = _configfile->get_bool(gruppo, "Gruppi");
}
// vecchia condizione: se riga documento deve avere codice iva oppure essere tipo riga spesa e avere gruppo 4 o 5 (andare su anamag con codart o )
// se riga documento preocedo come la contabilizzazione per cercare il gruppo-conto-sottoconto, che deve essere presente in crpa.ini
if (strpar == "34")
{
const TString8 codiva = _inputfile->get("CODIVA");
const TString8 tiporiga = _inputfile->get("TIPORIGA");
const char tiporigatab = cache().get("%TRI", tiporiga, "S7")[0];
ok = (codiva.not_empty()) || (tiporigatab == 'S');
if (ok)
{
const int nriga = build_nriga(*paragrafo);
if (nriga <= _doc->rows())
{
if (_caus != NULL)
_caus = NULL;
_rigadoc = new TRiga_documento((*_doc)[nriga]);
if (is_cespite)
ok = search_conto_cespite(_conto, (*_rigadoc));
else
ok = search_costo_ricavo(_conto, (*_rigadoc));
if (ok)
{
TString8 gruppos;
int gruppo = _conto.gruppo();
gruppos.format("%d", _conto.gruppo());
ok = (_configfile->get_bool(gruppos, "Gruppi"));
}
}
}
}
// verifico che la riga abbia una commessa
if ((ok) && (strpar == "24" || strpar == "34"))
{
TString80 codcms;
if (strpar == "24")
codcms = _inputfile->get("CODCMS");
if (strpar == "34")
{
if (_rigadoc != NULL)
codcms = _rigadoc->codice_commessa();
}
ok = codcms.not_empty();
}
if (ok)
{
if ((strpar=="24") || (strpar=="34") || (strpar=="108"))
almenounariga = true;
if ((strpar== "34") && (_rigadoc != NULL))
{
TString16 codnum = _rigadoc->get("DACODNUM");
const char provv = _rigadoc->get("DAPROVV")[0];
const int anno = _rigadoc->get_int("DAANNO");
const long numdoc = _rigadoc->get_long("DANDOC");
if (codnum.not_empty())
_dadoc = new TDocumento(provv, anno, (const char*) codnum, numdoc);
}
TString_array lv;
_configfile->list_variables(lv, TRUE, strpar);
TString16 key;
TString str;
TString risultato;
FOR_EACH_ARRAY_ROW(lv, r, row)
{
_inputfile->set_paragraph(*paragrafo);
key = row->get(0);
str = row->get();
if (strcmp(key,"TABLE") == 0)
{
}
else
{
process_field(str, risultato);
if (risultato.not_empty())
{
if (colonne.len()>0)
colonne << ", ";
colonne << key;
if (valori.len()>0)
valori << ", ";
valori << risultato;
}
}
}
if (_rigadoc != NULL)
_rigadoc =NULL;
if (_dadoc != NULL)
_dadoc = NULL;
}
}
if (colonne.len() > 0)
{
colonne.insert(" ("); colonne << ") ";
valori.insert(" VALUES ("); valori << ") ";
*_sqlfile << insert << endl;
*_sqlfile << colonne << endl;
*_sqlfile << valori << endl;
*_sqlfile << SQL_EOL << endl;
}
}
if (!almenounariga)
{
if (_sqlfile != NULL)
delete _sqlfile;
_sqlfile = new ofstream("crpa.sql");
write_sqldelete();
}
}
}
}
// scrive il file che contiene il comando delete completo dei record da cancellare
void TIni2Sql::write_sqldelete()
{
TString_array lp;
if (_inputfile->list_paragraphs(lp) > 0)
{
TString cancella, condizione;
_firm = _inputfile->get_int("Firm", "Transaction");
TString strpar, risultato;
// Vado all'indietro per cancellare prima le righe e poi la testata
FOR_EACH_ARRAY_ROW_BACK(lp, p, paragrafo)
{
build_paragraph(*paragrafo, strpar);
const int numpar = atoi(strpar);
const int numrig = build_nriga(*paragrafo);
condizione.cut(0);
if (
(numpar == 107 || numpar == 33) || // Inizialmente era richiesto di cancellare solo le testate ...
((numpar == 108 || numpar == 34) && numrig == 1) // ... ovviamente ora non più
)
{
cancella.format("DELETE FROM %s", (const char*) _configfile->get("TABLE", strpar));
_inputfile->set_paragraph(*paragrafo);
process_field(_configfile->get("ARCH"), risultato);
if (risultato.not_empty())
condizione << "(ARCH=" << risultato << ')';
process_field(_configfile->get("UNICARCH"), risultato);
if (risultato.not_empty())
{
if (condizione.not_empty())
condizione << " AND ";
condizione << "(UNICARCH=" << risultato << ')';
}
}
if (condizione.not_empty())
{
condizione.insert(" WHERE ("); condizione << ") ";
*_sqlfile << cancella << condizione << endl;
*_sqlfile << SQL_EOL << endl;
}
}
}
}
// carica la maschera
void TIni2Sql::main_loop()
{
_sqlfile = new ofstream("crpa.sql");
TString16 action = _inputfile->get("Action", "Transaction");
action.upper();
switch (action[0])
{
case 'I':
write_sqlinsert();
break;
case 'D':
write_sqldelete();
break;
case 'M':
{
write_sqldelete();
write_sqlinsert();
}
break;
}
int err = 0;
if (_sqlfile != NULL)
{
_sqlfile->flush();
delete _sqlfile;
_sqlfile = NULL;
if (_configfile->get("Run", "Oracle") == "OK")
{
TString rigapar;
if ((_inputfilename[0] != '.') && (_inputfilename[1] != ':'))
_inputfilename.insert("./", 0);
rigapar << "crpa.exe crpa.sql " << _inputfilename;
TExternal_app esegui_sql(rigapar);
esegui_sql.run();
}
else
{
ifstream f("crpa.sql");
TString query;
TString header;
TString & buffer = get_tmp_string(4096);
char * b = buffer.get_buffer(4096);
header << "ODBC(" << _configfile->get("Connect") << ',' << _configfile->get("Username") << ',' <<_configfile->get("Password") << ")\n";
TODBC_recordset pmc40(header);
while (f.good())
{
f.getline(b, 4096);
query << buffer;
}
int err = pmc40.exec(query);
if (err != 0)
{
_inputfile->set("Result", "Error", "Transaction");
_inputfile->set("Error", err, "Transaction");
}
}
}
// non devo scrivere niente nelle tavole oracle
// ma devo comunque segnalare come eseguita la transazione altrimenti rimane nel postino
else
{
_inputfile->set("Result", "OK", "Transaction");
_inputfile->set("Error", "0", "Transaction");
}
}
int main(int argc, char** argv)
{
TIni2Sql a;
a.run(argc, argv, TR("Trasferimento dati da EuroCampo"));
return 0;
}