campo-sirio/ca/cacnv.cpp

534 lines
17 KiB
C++
Raw Normal View History

#include <applicat.h>
#include <confapp.h>
#include <progind.h>
#include <relation.h>
#include <tabutil.h>
#include <utility.h>
#include <mov.h>
#include <rmov.h>
#include <rmoviva.h>
#include <pconti.h>
#include "../cg/cg2101.h"
#include "calib01.h"
#include "cdc.h"
//#include "cms.h"
#include "movana.h"
#include "rmovana.h"
#include "cacnva.h"
#define usage "Errore - uso : cacnv [0|1]"
//--------------------------------------------------------------
// IMPORTO DESCRITTO (utilizzato nella conversione movimenti)
//--------------------------------------------------------------
class TImporto_descritto : public TImporto
{
TString _descr;
public:
const TString& descrizione() const {return _descr;}
TImporto_descritto(const char* descr) : _descr(descr) {}
};
//----------------------------------------------------------
// MASCHERA COVERSIONE MOVIMENTI
//----------------------------------------------------------
class TConversione_anal_msk : public TAutomask
{
protected:
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
public:
TConversione_anal_msk() : TAutomask("cacnva") {}
};
bool TConversione_anal_msk::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
// switch (o.dlg())
// {
// default: break;
// }
return TRUE;
}
//----------------------------------------------------------
// APPLICAZIONE
//----------------------------------------------------------
class TConversione_cm2ca : public TSkeleton_application
{
int _nconv;
protected:
virtual void main_loop();
void create_new_movana(long numreg_cg, bool definitiva);
public:
bool convert_clerks();
bool convert_phases();
bool set_anal();
bool convert_movs();
TConversione_cm2ca() {}
~TConversione_cm2ca() {}
};
//gestione del menu (vari tipi di conversione)
void TConversione_cm2ca::main_loop()
{
_nconv = abs(atoi(argv(1)));
switch (_nconv)
{
case 0:
{
if (set_anal()) //setta il flag anal nel pcon
{
convert_clerks(); //da tabella cms a commesse
convert_phases(); //da tabella fsc a fasi
}
}
break;
case 1:
{
convert_movs(); //converte i movimenti di contabilita' (da CG a CA)
break;
}
default:
break;
}
}
//------------------------------------------------------------------------------------------------
// trasferisce i dati dalle tabelle Commesse e Fasi ai nuovi file di analitica (COMMESSE e FASI)
//------------------------------------------------------------------------------------------------
bool TConversione_cm2ca::convert_clerks()
{
TLocalisamfile commesse(LF_COMMESSE); //la conversione blocca in automatico gli altri utenti
//non e' necessario un TSystemisamfile con _excllock
const long items = commesse.items();
//trasferimento dati possibile solo se il file di destinazione e' vuoto
if (items > 0)
{
if (yesno_box(TR("File delle commesse non vuoto!\nSi desidera azzerarlo?")))
if (yesno_box(TR("File delle commesse non vuoto!\nSi desidera veramente azzerarlo?")))
{
TSystemisamfile cms(LF_COMMESSE); //sono zappabili solo i Systemisamfiles
cms.zap();
}
else
return true;
else
return true;
}
TRelation relcms("CMS");
TCursor curcms(&relcms);
const TRectype& cms = relcms.curr();
const long nrectab = curcms.items();
curcms.freeze();
TRectype& commesse_rec = commesse.curr();
TProgind pi(nrectab, "Conversione tabella commesse");
for (curcms = 0; curcms.pos() < nrectab; ++curcms)
{
pi.addstatus(1);
commesse_rec.zero(); //azzerare il record prima di cominciare...
commesse_rec.put("CODCMS", cms.get("CODTAB"));
commesse_rec.put("DESCRIZ", cms.get("S0"));
commesse_rec.put("CODCF", cms.get("I0"));
commesse_rec.put("REGIVA", cms.get("S7"));
commesse_rec.put("PRORATA", cms.get("B4"));
commesse_rec.put("PUBBLICA", cms.get("B0"));
commesse_rec.put("RENDIC", cms.get("B1"));
commesse_rec.put("DATAINIZIO", cms.get("D0"));
commesse_rec.put("DATAFINE", cms.get("D1"));
commesse_rec.put("CHIUSA", cms.get("B3"));
commesse_rec.put("PROROGA", cms.get("B2"));
commesse_rec.put("CODRESP", cms.get("S4"));
commesse.write();
}
return true;
}
bool TConversione_cm2ca::convert_phases()
{
TLocalisamfile fasi(LF_FASI);
const long items = fasi.items();
if (items > 0)
{
if (yesno_box(TR("File delle fasi non vuoto!\nSi desidera azzerarlo?")))
if (yesno_box(TR("File delle fasi non vuoto!\nSi desidera veramente azzerarlo?")))
{
TSystemisamfile fsc(LF_FASI);
fsc.zap();
}
else
return true;
else
return true;
}
TRelation relfsc("FSC");
TCursor curfsc(&relfsc);
const TRectype& fsc = relfsc.curr();
const long nrectab = curfsc.items();
curfsc.freeze();
TRectype& fasi_rec = fasi.curr();
TProgind pi(nrectab, "Conversione tabella fasi");
TRelation* relazione = NULL;
TCursor* cursore = NULL;
//se sono gia' state configurate le fasi nel ditta.ini...
/* TConfig config(CONFIG_DITTA, "ca");
const TString& fathfasi = config.get( "FathFasi", "ca");
if (fathfasi == "CDC")
{
TLocalisamfile cdc(LF_CDC); //devono gia' essere stati creati i files dell'analitica
if (cdc.first() == NOERR) //se il file del piano dei conti ha almeno un record...
{
relazione = new TRelation(LF_CDC);
cursore = new TCursor(relazione);
}
}
else if (fathfasi == "CMS")
{
TLocalisamfile cms(LF_COMMESSE); //devono gia' essere stati creati i files dell'analitica
if (cms.first() == NOERR) //se il file del piano dei conti ha almeno un record...
{
relazione = new TRelation(LF_COMMESSE);
cursore = new TCursor(relazione);
}
}
TRecnotype items = 0;
if (cursore !=NULL)
{
items = cursore->items();
cursore->freeze();
}
*/
for (curfsc = 0; curfsc.pos() < nrectab; ++curfsc)
{
pi.addstatus(1);
if (cursore == NULL)
{
fasi_rec.zero();
fasi_rec.put("CODFASE", fsc.get("CODTAB"));
fasi_rec.put("DESCRIZ", fsc.get("S0"));
fasi.write();
}
/* else
{
TString80 codice;
const TRectype& rec = cursore->curr();
for (*cursore = 0; cursore->pos() < items; ++*cursore)
{
switch (rec.num())
{
case LF_CDC:
codice = rec.get(CDC_CODCOSTO);
break;
case LF_CMS:
codice = rec.get("CODCMS");
break;
default:
break;
}
fasi_rec.zero();
fasi_rec.put("CODCMSFAS", codice);
fasi_rec.put("CODFASE", fsc.get("CODTAB"));
fasi_rec.put("DESCRIZ", fsc.get("S0"));
fasi.write();
}
}*/
}
return true;
}
//------------------------------------------------------------------------------------------------
// mette il flag di ANALITICA nei gr.co.stc. aventi codcms e/o codfsc
//------------------------------------------------------------------------------------------------
bool TConversione_cm2ca::set_anal()
{
TRelation relpcon(LF_PCON);
TCursor curpcon(&relpcon);
TRectype& recpcon = relpcon.curr();
if (!recpcon.exist("ANALITICA")) //check se gia' avvenuta la conversione con aggiunta del campo ANAL
return error_box(TR("Prima del controllo e' necessario eseguire una conversione archivi"));
else
{
const long nrecpcon = curpcon.items();
curpcon.freeze();
TProgind pi(nrecpcon, "Controllo commesse e fasi sul piano dei conti");
for (curpcon = 0; curpcon.pos() < nrecpcon; ++curpcon)
{
pi.addstatus(1);
if (recpcon.get("CODCMS").not_empty() || recpcon.get("FASCMS").not_empty())
{
recpcon.put("ANALITICA", "X");
relpcon.rewrite();
}
}
return true;
}
}
//----------------------------------------------------------------------------------------------------
// trasferisce i movimenti e le righe relative (MOV,RMOV) nei nuovi file di analitica (MOVANA,RMOVANA)
// ---------------------------------------------------------------------------------------------------
void TConversione_cm2ca::create_new_movana(long numreg_cg, bool definitiva)
{
TAnal_mov analmov;
//riempie le righe di testata
TMovimentoPN mov;
TRectype& mov_head = mov.curr();
mov_head.put(MOV_NUMREG, numreg_cg);
mov.read();
analmov.put(MOVANA_ANNOES, mov_head.get(MOV_ANNOES));
analmov.put(MOVANA_DATAREG, mov_head.get(MOV_DATAREG));
analmov.put(MOVANA_DATACOMP, mov_head.get(MOV_DATACOMP));
analmov.put(MOVANA_DATADOC, mov_head.get(MOV_DATADOC));
analmov.put(MOVANA_NUMREGCG, mov_head.get(MOV_NUMREG));
analmov.put(MOVANA_NUMDOC, mov_head.get(MOV_NUMDOC));
analmov.put(MOVANA_TIPODOC, mov_head.get(MOV_TIPODOC));
analmov.put(MOVANA_DESCR, mov_head.get(MOV_DESCR));
analmov.put(MOVANA_CODCAUS, mov_head.get(MOV_CODCAUS));
analmov.put(MOVANA_TIPOMOV, ""); //deve mettere sempre 0
//MOVANA_TOTDOC e' il totale di tutte le sue righe;ancora non si conosce
//deve scorrere tutte le righe del movimento e sommare gli importi di quelle che hanno la
//stessa chiave CODCMS+CODFSC
TAssoc_array righe_cms;
TToken_string chiave;
//scansione righe movimentoPN
for (int l = 0; l < mov.cg_items(); l++)
{
const TRectype& rmov = mov.cg(l);
chiave = "";
chiave.add(rmov.get(RMV_CODCMS));
chiave.add(rmov.get(RMV_FASCMS));
if (!chiave.empty_items() && rmov.get(RMV_ROWTYPE) != "T")
{
//alla chiave va aggiunto il vecchio gr/co/stc
TString16 conto_cg;
conto_cg.format("%03d%03d%06ld", rmov.get_int(RMV_GRUPPO), rmov.get_int(RMV_CONTO), rmov.get_long(RMV_SOTTOCONTO));
chiave.add(conto_cg);
TImporto_descritto* importo = (TImporto_descritto*)righe_cms.objptr(chiave);
if (importo == NULL) //la chiave non esisteva nell'assoc
{
importo = new TImporto_descritto(rmov.get(RMV_DESCR)) ;
righe_cms.add(chiave, importo);
}
const char sezione = rmov.get_char(RMV_SEZIONE);
const real valore = rmov.get(RMV_IMPORTO);
*importo += TImporto(sezione, valore); //crea un importo e lo somma a quello dell'array
}
}
//scansione dell Assoc_array che adesso contiene le nuove righe del movimento di analitica
TImporto importone;
FOR_EACH_ASSOC_OBJECT(righe_cms, h, k, a)
{
TRectype& analriga = analmov.new_row();
analriga.put(RMOVANA_ANNOES, analmov.get(MOVANA_ANNOES));
analriga.put(RMOVANA_DATAREG, analmov.get(MOVANA_DATAREG));
//deve prendere la sezione dell'importo di ogni riga
TImporto_descritto* importo = (TImporto_descritto*)a;
importo->normalize();
analriga.put(RMOVANA_SEZIONE, importo->sezione());
analriga.put(RMOVANA_IMPORTO, importo->valore());
analriga.put(RMOVANA_DESCR, importo->descrizione());
importone += *importo;
chiave = k;
analriga.put(RMOVANA_CODCMS, chiave.get(0));
analriga.put(RMOVANA_CODFASE, chiave.get(1));
analriga.put(RMOVANA_CODCONTO, chiave.get(2));
}
//e alla fine riesce a mettere anche l'importone in testata
importone.normalize(); //x evitare problemi di segno...
analmov.put(MOVANA_SEZIONE, importone.sezione());
analmov.put(MOVANA_TOTDOC, importone.valore());
//se e' riuscita la scrittura dei movimenti di analitica ed e' una conversione definitiva...
if (analmov.write() == NOERR && definitiva)
{
//RIGHE MOVIMENTI CONTABILI
TArray cg_records;
for (int m = 0; m < mov.cg_items(); m++)
{
const TRectype& rmov = mov.cg(m);
int add_to = -1;
//se la riga movimento contabile ha un ROWTYPE...
if (rmov.get(RMV_ROWTYPE).not_empty())
{
//cerca nell'array dei record riga mov(cg_records) partendo dall'ultima a scalare..
for(add_to = cg_records.last(); add_to >=0; add_to--)
{
//prende il record add_to-esimo..
const TRectype& rec = (TRectype&)cg_records[add_to];
//se i campi gr.co.sottoc. di un record dell'array(cg_records) = a quelli della riga
//movimento contabile in esame(rmov) -> esce con add_to = al numero del record dell'
//array che soddisfa la condizione (quindi add_to > 0)
if (rmov.get_int(RMV_GRUPPO) == rec.get_int(RMV_GRUPPO) &&
rmov.get_int(RMV_CONTO) == rec.get_int(RMV_CONTO) &&
rmov.get_long(RMV_SOTTOCONTO) == rec.get_long(RMV_SOTTOCONTO))
break;
}
}
//se add_to e' rimasto = -1 (la condizione di eguaglianza gr.co.sott. non e' stata soddisfatta
//da alcuna riga dell'array cg_records)..
if (add_to < 0)
{
TRectype* rec = new TRectype(rmov);
//azzera i campi codice commessa e fase in RMOV di origine...
rec->zero(RMV_CODCMS);
rec->zero(RMV_FASCMS);
//e aggiunge all'array cg_records il nuovo record ripulito
cg_records.add(rec);
rec->put(RMV_NUMRIG, cg_records.items());
}
//se ivece add_to > 0 (vedi test su condizione gr.co.sott. sopra)..
else
{
//prende il record(rec) dell'array che soddsfaceva la condizione e somma ad esso importo e sezione
//di quello in esame(rmov)
TRectype& rec = (TRectype&)cg_records[add_to];
TImporto imp_tot(rec.get_char(RMV_SEZIONE), rec.get_real(RMV_IMPORTO));
TImporto imp_original(rmov.get_char(RMV_SEZIONE), rmov.get_real(RMV_IMPORTO));
imp_tot += imp_original;
imp_tot.normalize();
rec.put(RMV_SEZIONE, imp_tot.sezione());
rec.put(RMV_IMPORTO, imp_tot.valore());
//notare che i campi descrittivi resteranno sempre quelli del primo record di cg_records
//che ha gr.co.sottoc. soddisfacenti la condizione sopra!
}
}
//cancella solo le righe contabili del movimento originale..
mov.destroy_cg_row(-1);
//e le sostituisce con le nuove che sono contenute (compattate) in cg-records
FOR_EACH_ARRAY_ITEM(cg_records, cg_i, cg_obj)
{
mov.cg(cg_i) = *(TRectype*)cg_obj;
}
//RIGHE MOVIMENTI IVA (rifa' tutto il giochetto di prima per rmoviva)
TArray iva_records;
for (int n = 0; n < mov.iva_items(); n++)
{
const TRectype& rmoviva = mov.iva(n);
int add_to = -1;
for(add_to = iva_records.last(); add_to >=0; add_to--)
{
const TRectype& rec = (TRectype&)iva_records[add_to];
if (rmoviva.get_int(RMI_GRUPPO) == rec.get_int(RMI_GRUPPO) &&
rmoviva.get_int(RMI_CONTO) == rec.get_int(RMI_CONTO) &&
rmoviva.get_long(RMI_SOTTOCONTO) == rec.get_long(RMI_SOTTOCONTO) &&
rmoviva.get(RMI_CODIVA) == rec.get(RMI_CODIVA) &&
rmoviva.get_int(RMI_TIPODET) == rec.get_int(RMI_TIPODET))
break;
}
if (add_to < 0)
{
TRectype* rec = new TRectype(rmoviva);
rec->zero(RMI_CODCMS);
rec->zero(RMI_FASCMS);
iva_records.add(rec);
rec->put(RMI_NUMRIG, iva_records.items());
}
else
{
TRectype& rec = (TRectype&)iva_records[add_to];
//imponibile..
real tot = rec.get_real(RMI_IMPONIBILE);
real original = rmoviva.get_real(RMI_IMPONIBILE);
tot += original;
rec.put(RMI_IMPONIBILE, tot);
//..e imposta
tot = rec.get_real(RMI_IMPOSTA);
original = rmoviva.get_real(RMI_IMPOSTA);
tot += original;
rec.put(RMI_IMPOSTA, tot);
}
}
mov.destroy_iva_row(-1);
FOR_EACH_ARRAY_ITEM(iva_records, iva_i, iva_obj)
{
mov.iva(iva_i) = *(TRectype*)iva_obj;
}
mov.rewrite(); //puo' finalmente riscrivere i files di origine puliti e compattati
}
}
bool TConversione_cm2ca::convert_movs()
{
TConversione_anal_msk msk;
msk.run();
//scandisce il file RMOV,alla ricerca dei record con codice fase o codice commessa compilato
TRelation rel_rmov(LF_RMOV);
const bool definitiva = msk.get_int(F_TIPOCONV) != 0;
//costruzione filtro con date (in caso di conversione provvisoria)
TString filtro;
filtro << "((CODCMS!='')||(FASCMS!=''))&&(ROWTYPE!='T')";
if (!definitiva)
{
const TDate dataini = msk.get_date(F_DATAINI);
if (dataini.ok())
filtro << "&&(ANSI(DATAREG)>=" << dataini.string(ANSI) << ")";
const TDate datafin = msk.get_date(F_DATAFIN);
if (datafin.ok())
filtro << "&&(ANSI(DATAREG)<=" << datafin.string(ANSI) << ")";
}
TCursor cur_rmov(&rel_rmov, filtro);
TRectype& rec_rmov = rel_rmov.curr();
const long rmov_items = cur_rmov.items();
if (rmov_items > 0)
{
cur_rmov.freeze();
TProgind pi(rmov_items, "Trasferimento righe movimenti", false);
long last_numreg_cg = 0; //numero registrazione originaria
for (cur_rmov = 0; cur_rmov.pos() < rmov_items; ++cur_rmov)
{
pi.addstatus(1);
const long curr_numreg_cg = rec_rmov.get_long(RMV_NUMREG);
if (curr_numreg_cg != last_numreg_cg)
{
//se il numreg di questa riga e' nuovo -> crea un nuovo movimento di analitica (testata)
create_new_movana(curr_numreg_cg, definitiva);
last_numreg_cg = curr_numreg_cg;
}
}
}
return true;
}
///////////////////////////////////////////////////////////
// Programma di conversione da CM a CA
///////////////////////////////////////////////////////////
int main(int argc,char** argv)
{
TConversione_cm2ca a;
a.run(argc,argv, "Trasferimento dati da CG a CA");
return 0;
}