Files correlati : f151.dir f151.trr ca1.exe ca2.exe ca3.exe ca3100.uml ca3100a.rep ca3100b.rep ca3200.uml ca3200a.rep ca3200b.rep ca3300.uml ca3300a.rep ca3300b.rep ca3300c.rep ca3300d.rep ca3600.uml ca3600a.rep ca3700.uml ca3700a.rep ca3700b.rep ca3800.uml ca3800a.rep ca3800as.rep ca3800b.rep ca3800bs.rep ca3800c.rep ca3800cs.rep ca3883.cpp ca3900.uml ca3900a.rep Commento : Aggiunta contabilità separata alle stampe di analitica. Aggiunto meccanismo per lanciare le stampe in batch. Sintassi: ca3 -7 -b <nome del file che contiene i valori dell maschera> <tipo di output <P>rint|<E>xport|E<X>cel|PD<F>|<T>esto|<D>Base|<V>isualizza> <nome del file di output Esempio: ca3 -7 -b select.sav X c:\out\rend esporta il rendiconto di commessa usando i parametri salvati in select.sav nel file c:\out\rend.xls
873 lines
29 KiB
C++
Executable File
873 lines
29 KiB
C++
Executable File
#include <dongle.h>
|
|
#include <execp.h>
|
|
#include <modaut.h>
|
|
#include <progind.h>
|
|
#include <recset.h>
|
|
|
|
#include <causali.h>
|
|
#include <pconti.h>
|
|
|
|
#include "../cg/cglib.h"
|
|
#include "calib01.h"
|
|
#include "../ve/velib04.h"
|
|
|
|
#include "fasi.h"
|
|
#include "movana.h"
|
|
#include "rmovana.h"
|
|
#include "rip.h"
|
|
#include "rrip.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
|
|
//----------------------------------------------------------
|
|
class TConversione_anal_msk : public TAutomask
|
|
{
|
|
protected:
|
|
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
|
|
|
|
public:
|
|
TConversione_anal_msk();
|
|
};
|
|
|
|
TConversione_anal_msk::TConversione_anal_msk()
|
|
: TAutomask("cacnva")
|
|
{
|
|
}
|
|
|
|
bool TConversione_anal_msk::on_field_event(TOperable_field& o, TField_event e, long jolly)
|
|
{
|
|
switch (o.dlg())
|
|
{
|
|
case F_MOVIMENTI:
|
|
//solo se la chiave ha l'analitica si può vedere il bUleano per le ripartizioni
|
|
//chi ha CM non può ripartire
|
|
if (e == fe_modify)
|
|
{
|
|
if (o.get() == "X")
|
|
{
|
|
if(dongle().active(CAAUT))
|
|
show(F_RIPARTISCI);
|
|
}
|
|
else
|
|
{
|
|
hide(F_RIPARTISCI);
|
|
reset(F_RIPARTISCI);
|
|
}
|
|
}
|
|
break;
|
|
case F_TABELLE:
|
|
//al caricamento della maschera, se il file delle commesse analitiche (LF_COMMESSE) è vuoto, prespunta il flag..
|
|
//..e impedisce il trasferimento definitivo dei movimenti, che si troverebbero ad avere delle commesse sulle righe..
|
|
//..senza alcun riferimento!
|
|
if (e == fe_init)
|
|
{
|
|
TLocalisamfile commesse(LF_COMMESSE);
|
|
const long items = commesse.items();
|
|
if (items == 0)
|
|
{
|
|
o.set("X");
|
|
disable(F_TIPOCONV);
|
|
}
|
|
else
|
|
enable(F_TIPOCONV);
|
|
}
|
|
break;
|
|
case F_DATAINI:
|
|
if (e == fe_init)
|
|
{
|
|
const TDate data_att = ca_config().get("DtAttCa");
|
|
if (data_att.ok())
|
|
o.set(data_att.string());
|
|
}
|
|
if (e == fe_modify || e == fe_close)
|
|
{
|
|
//controllo sulla data attivazione Contabilita' analitica nel file di configurazione
|
|
const TDate data_att = ca_config().get("DtAttCa");
|
|
if (data_att.ok())
|
|
{
|
|
const TDate& dataini = get_date(F_DATAINI);
|
|
if (dataini < data_att)
|
|
return error_box(TR("La data inizio non puo' essere antecedente la data di attivazione"));
|
|
}
|
|
}
|
|
break;
|
|
case F_TIPOCONV:
|
|
if (e == fe_modify)
|
|
{
|
|
const TDate data_att = ca_config().get("DtAttCa");
|
|
set(F_DATAINI, data_att);
|
|
}
|
|
break;
|
|
default: break;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// RIPARTITORE
|
|
//---------------------------------------------------------
|
|
|
|
class TAnal_rip : public TMultiple_rectype
|
|
{
|
|
public:
|
|
TAnal_rip();
|
|
};
|
|
|
|
TAnal_rip::TAnal_rip() : TMultiple_rectype(LF_RIP)
|
|
{
|
|
add_file(LF_RRIP, RRIP_NRIGA);
|
|
}
|
|
//----------------------------------------------------------
|
|
// APPLICAZIONE
|
|
//----------------------------------------------------------
|
|
|
|
class TConversione_cm2ca : public TSkeleton_application
|
|
{
|
|
TCache_ripartizioni _cache_rip;
|
|
|
|
protected:
|
|
virtual const char * extra_modules() const {return "cm";} //funziona anche con autorizzazione CM
|
|
|
|
virtual void main_loop();
|
|
void create_new_movana(long numreg_cg, bool definitiva, TAssoc_array& cg_lines_to_anal, TConversione_anal_msk& mask);
|
|
bool test_configuration();
|
|
void ripartisci(TRectype& recpcon);
|
|
void check_phase(const TRectype& analriga);
|
|
void set_caus_anal(const TString& codcaus) const;
|
|
|
|
public:
|
|
bool convert_clerks();
|
|
bool convert_phases();
|
|
bool set_anal();
|
|
void kill_temp_movana(TConversione_anal_msk& mask);
|
|
void kill_old_tabs(const TString& tab);
|
|
bool convert_movs(TConversione_anal_msk& mask);
|
|
|
|
TConversione_cm2ca() {}
|
|
~TConversione_cm2ca() {}
|
|
};
|
|
|
|
bool TConversione_cm2ca::test_configuration()
|
|
{
|
|
const TString& first_level = ca_config(true).get("Level", "ca", 1);
|
|
return first_level.not_empty();
|
|
}
|
|
|
|
//gestione del menu (vari tipi di conversione)
|
|
void TConversione_cm2ca::main_loop()
|
|
{
|
|
TConversione_anal_msk mask;
|
|
while (mask.run() == K_ENTER)
|
|
{
|
|
if (mask.get_bool(F_TABELLE))
|
|
{
|
|
if (set_anal()) //setta il flag anal nel pcon
|
|
{
|
|
convert_clerks(); //da tabella cms a commesse
|
|
convert_phases(); //da tabella fsc a fasi
|
|
}
|
|
}
|
|
|
|
if (mask.get_bool(F_MOVIMENTI))
|
|
{
|
|
//controlla se compilata la configurazione della CA dul ditta.ini
|
|
bool ok = test_configuration();
|
|
if (!ok)
|
|
{
|
|
if (yesno_box(TR("Per procedere alla conversione e' necessario avere configurato\nla Contabilita' Analitica\nSi desidera procedere alla configurazione?")))
|
|
{
|
|
TExternal_app app("ca0 -2");
|
|
app.run();
|
|
ok = test_configuration();
|
|
}
|
|
}
|
|
//solo se e' stata fatta la configurazione minima e' possibile procedere alla conversione
|
|
if (ok)
|
|
convert_movs(mask); //converte i movimenti di contabilita' (da CG a CA)
|
|
} //end get_bool(F_MOVIMENTI)
|
|
} //end while
|
|
|
|
}
|
|
|
|
|
|
//-------------------------------------------------
|
|
// ** TRASFERIMENTO DATI COMMESSE/FASI **
|
|
//-------------------------------------------------
|
|
//------------------------------------------------------------------------------------------------
|
|
// 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("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("B2"));
|
|
commesse_rec.put("PROROGA", cms.get("B4"));
|
|
commesse_rec.put("DATAPROR", cms.get("D2"));
|
|
commesse_rec.put("CODRESP", cms.get("S4"));
|
|
|
|
commesse.write();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool TConversione_cm2ca::convert_phases()
|
|
{
|
|
//se sono gia' state configurate le fasi nel ditta.ini non procede oltre!
|
|
//fara' la conversione delle fasi nel trasferimento dei movimenti
|
|
const TString& fathfasi = ca_config().get( "FathFasi");
|
|
if (fathfasi.not_empty())
|
|
return false;
|
|
|
|
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 = nullptr;
|
|
TCursor* cursore = nullptr;
|
|
|
|
for (curfsc = 0; curfsc.pos() < nrectab; ++curfsc)
|
|
{
|
|
pi.addstatus(1);
|
|
if (cursore == nullptr)
|
|
{
|
|
fasi_rec.zero();
|
|
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
|
|
//------------------------------------------------------------------------------------------------
|
|
void TConversione_cm2ca::ripartisci(TRectype& recpcon)
|
|
{
|
|
const int gruppo = recpcon.get_int(PCN_GRUPPO);
|
|
const int conto = recpcon.get_int(PCN_CONTO);
|
|
const long sottoconto = recpcon.get_long(PCN_SOTTOCONTO);
|
|
const TString80 codcms = recpcon.get(PCN_CODCMS);
|
|
const TString16 fascms = recpcon.get(PCN_FASCMS);
|
|
|
|
if (codcms.empty() && fascms.empty())
|
|
return;
|
|
//cerca nel file rip se esiste gia' un record con la medesima chiave (chiave 3!!)
|
|
TLocalisamfile rip_file(LF_RIP);
|
|
rip_file.last();
|
|
rip_file.put(RIP_TIPO, "I");
|
|
rip_file.put(RIP_CODICE, "ZZZZZZZZ");
|
|
if (rip_file.read(_isgreat) == NOERR)
|
|
rip_file.prev();
|
|
const long last_cod = atol(rip_file.get(RIP_CODICE)) + 1L;
|
|
rip_file.setkey(3);
|
|
|
|
rip_file.put(RIP_GRUPPO, gruppo);
|
|
rip_file.put(RIP_CONTO, conto);
|
|
rip_file.put(RIP_SOTTOCONTO, sottoconto);
|
|
|
|
if (rip_file.read() != NOERR)
|
|
{
|
|
TAnal_rip rip;
|
|
TString80 cod;
|
|
|
|
cod.format("%08ld", last_cod);
|
|
rip.head().put(RIP_TIPO, "I");
|
|
rip.put(RIP_CODICE, cod);
|
|
rip.put(RIP_GRUPPO, gruppo);
|
|
rip.put(RIP_CONTO, conto);
|
|
rip.put(RIP_SOTTOCONTO, sottoconto);
|
|
|
|
|
|
TRectype& rrip = rip.new_row();
|
|
rrip.put(RRIP_RIPARTO, 100);
|
|
rrip.put(RRIP_CODCMS, codcms);
|
|
rrip.put(RRIP_CODFASE, fascms);
|
|
if (ca_config().get_bool("UsePdcc")) //solo se in CA si usa il piano dei conti contabile..
|
|
{
|
|
TString80 codconto;
|
|
|
|
codconto.format("%03d%03d%06ld", gruppo, conto, sottoconto);
|
|
rrip.put(RRIP_CODCONTO, codconto);
|
|
}
|
|
|
|
rip.write(); //scrive sia rip che rrip con nuova chiave 1 (TIPO+CODICE)
|
|
}
|
|
|
|
}
|
|
|
|
bool TConversione_cm2ca::set_anal()
|
|
{
|
|
TRelation relpcon(LF_PCON);
|
|
TCursor curpcon(&relpcon);
|
|
TRectype& recpcon = relpcon.curr();
|
|
|
|
if (!recpcon.exist(PCN_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 dalla Manutenzione!"));
|
|
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(PCN_CODCMS).not_empty() || recpcon.get(PCN_FASCMS).not_empty())
|
|
{
|
|
recpcon.put(PCN_ANALITICA, "X");
|
|
relpcon.rewrite();
|
|
//deve creare una testata e una riga di ripartizione (se non esistono con lo stesso gr/co/sott)
|
|
ripartisci(recpcon);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------
|
|
// ** CONVERSIONE MOVIMENTI CONTABILI **
|
|
//----------------------------------------------------------
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// trasferisce i movimenti e le righe relative (MOV,RMOV) nei nuovi file di analitica (MOVANA,RMOVANA)
|
|
// ---------------------------------------------------------------------------------------------------
|
|
void TConversione_cm2ca::check_phase(const TRectype& analriga)
|
|
{
|
|
const TString16 codfase = analriga.get(RMOVANA_CODFASE);
|
|
if (codfase.blank())
|
|
return;
|
|
const TString& fathfasi = ca_config().get("FathFasi");
|
|
if (fathfasi.blank())
|
|
return;
|
|
|
|
TLocalisamfile file_fasi(LF_FASI);
|
|
TString codcmsfas;
|
|
if (fathfasi == "CDC")
|
|
codcmsfas = analriga.get(RMOVANA_CODCCOSTO);
|
|
else //se non e' "CDC", il FathFasi puo' essere solo "CMS"
|
|
codcmsfas = analriga.get(RMOVANA_CODCMS);
|
|
|
|
file_fasi.put(FASI_CODFASE, codfase);
|
|
file_fasi.put(FASI_CODCMSFAS, codcmsfas);
|
|
|
|
const int err = file_fasi.read();
|
|
if (err != NOERR)
|
|
{
|
|
file_fasi.curr().zero();
|
|
file_fasi.put(FASI_CODFASE, codfase);
|
|
file_fasi.put(FASI_CODCMSFAS, codcmsfas);
|
|
|
|
const TString& descrfase = cache().get("FSC", codfase, "S0");
|
|
file_fasi.put(FASI_DESCRIZ, descrfase);
|
|
file_fasi.write();
|
|
}
|
|
}
|
|
|
|
void TConversione_cm2ca::set_caus_anal(const TString& codcaus) const
|
|
{
|
|
TLocalisamfile causali(LF_CAUSALI);
|
|
causali.put(CAU_CODCAUS, codcaus);
|
|
int err = causali.read();
|
|
if (err == NOERR)
|
|
{
|
|
const bool is_anal = causali.get_bool(CAU_MOVIND);
|
|
if (!is_anal)
|
|
{
|
|
causali.put(CAU_MOVIND, "X");
|
|
causali.rewrite();
|
|
}
|
|
}
|
|
}
|
|
|
|
void TConversione_cm2ca::create_new_movana(long numreg_cg, bool definitiva, TAssoc_array& cg_lines_to_anal,
|
|
TConversione_anal_msk& mask)
|
|
{
|
|
TLocalisamfile f(LF_MOVANA);
|
|
TAnal_mov analmov; //testata movimento analitico
|
|
//riempie le righe di testata del movimento prima nota mov
|
|
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));
|
|
//deve anche mettere il flag di analitica alla causale!
|
|
set_caus_anal(mov_head.get(MOV_CODCAUS));
|
|
|
|
if (definitiva)
|
|
analmov.put(MOVANA_TRASFERITO, " ");
|
|
else
|
|
analmov.put(MOVANA_TRASFERITO, "X"); //deve mettere "Trasferito" nell'apposito campo (conversione NON definitiva)
|
|
|
|
const char provv = mov_head.get_char(MOV_DPROVV);
|
|
analmov.put(MOVANA_DPROVV, provv);
|
|
const int danno = mov_head.get_int(MOV_DANNO);
|
|
analmov.put(MOVANA_DANNO, danno);
|
|
const TString4 dcodnum = mov_head.get(MOV_DCODNUM);
|
|
analmov.put(MOVANA_DCODNUM, dcodnum);
|
|
const long dndoc = mov_head.get_long(MOV_DNDOC);
|
|
analmov.put(MOVANA_DNDOC, dndoc);
|
|
|
|
//MOVANA_TOTDOC e' il totale di tutte le sue righe;ancora non si conosce;sara' compilato..
|
|
//..successivamente utilizzando importone
|
|
|
|
//deve scorrere tutte le righe del movimento e sommare gli importi di quelle che hanno la..
|
|
//..stessa chiave CODCMS+CODFSC
|
|
TAssoc_array righe_cms; //array con le righe del movimento che sono da trasferire
|
|
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("CODCMS"));
|
|
chiave.add(rmov.get("FASCMS"));
|
|
|
|
//se ci sono la commessa e/o la fase nella riga movimento e la riga iva non e' tipo T..
|
|
//..procede al calcolo dell'importo
|
|
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 == nullptr) //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
|
|
|
|
//aggiunge gr/co/sottoc all'assoc_array dei conti da trasformare in analitici sul piano dei conti
|
|
cg_lines_to_anal.add(conto_cg);
|
|
}
|
|
}
|
|
|
|
TImporto importone; //importo totale del movimento (totale di testata)
|
|
|
|
FOR_EACH_ASSOC_OBJECT(righe_cms, m, n, a) //giro sull'assoc array delle righe movimento da trasferire
|
|
{
|
|
//aggiunge l'importo della riga all'importo totale
|
|
TImporto_descritto& importo = *(TImporto_descritto*)a;
|
|
importo.normalize();
|
|
importone += importo;
|
|
|
|
chiave = n; //chiave = commessa|fase|gruppo|conto|sottoconto
|
|
const int gruppo = chiave.get_int(2);
|
|
const int conto = chiave.get_int();
|
|
const long sottoconto = chiave.get_long();
|
|
const TBill zio(gruppo, conto, sottoconto);
|
|
//controlla se il gr/co/stc del movimento deve essere ripartito;in caso affermativo procede..
|
|
//..alla ripartizione delle righe del movimento
|
|
//Per prima cosa crea l'array delle righe di ripartizione con questo gr/co/stc/annoes
|
|
const int annoes = mov_head.get_int(MOV_ANNOES);
|
|
|
|
const TAnal_ripartizioni_batch& rrip = _cache_rip.righe_interattive(zio, annoes);
|
|
|
|
const int righe_ripartizione = rrip.rows();
|
|
const bool ripartisci = righe_ripartizione > 0;
|
|
|
|
//ci sono righe ripartizione: da 1 riga mov CG a N righe mov CA
|
|
//ovviamente deve essere stato scelto il ripartisci nella maschera
|
|
if (ripartisci && mask.get_bool(F_RIPARTISCI))
|
|
{
|
|
// Importo totale da distribuire arrotondato ai decimali della valuta di conto
|
|
TGeneric_distrib distrib(importo.valore(), TCurrency::get_firm_dec());
|
|
|
|
// Calcola tutte le percentuali da ripartire
|
|
int i;
|
|
for (i = 1; i <= rrip.rows(); i++)
|
|
distrib.add(rrip[i].get_real(RRIP_RIPARTO));
|
|
|
|
//Compila le righe del movimento di analitica in base alle righe ripartizione
|
|
for (i = 1; i <= rrip.rows(); i++)
|
|
{
|
|
const TRectype& riga_rip = rrip.row(i);
|
|
|
|
TRectype& analriga = analmov.new_row();
|
|
const real imp = distrib.get(); // Legge la quota da distribuire
|
|
analriga.put(RMOVANA_SEZIONE, importo.sezione());
|
|
analriga.put(RMOVANA_IMPORTO, imp); //e la mette nella nuova riga
|
|
analriga.put(RMOVANA_DESCR, importo.descrizione());
|
|
|
|
analriga.put(RMOVANA_ANNOES, analmov.get(MOVANA_ANNOES));
|
|
analriga.put(RMOVANA_DATACOMP, analmov.get(MOVANA_DATAREG));
|
|
|
|
//parametri da prendere dalle righe ripartizione!!
|
|
analriga.put(RMOVANA_CODCCOSTO, riga_rip.get(RRIP_CODCOSTO));
|
|
analriga.put(RMOVANA_CODCMS, riga_rip.get(RRIP_CODCMS));
|
|
analriga.put(RMOVANA_CODFASE, riga_rip.get(RRIP_CODFASE));
|
|
analriga.put(RMOVANA_CODCONTO, riga_rip.get(RRIP_CODCONTO));
|
|
|
|
//controlla la coppia fase/(cdc-commessa) e decide se aggiungerla al file delle fasi
|
|
check_phase(analriga);
|
|
}
|
|
}
|
|
else //nessuna riga ripartizione -> da 1 riga movimento CG ad 1 riga movimento CA
|
|
{
|
|
if (ca_config().get_bool("UsePdcc")) //solo se in CA si usa il piano dei conti contabile..
|
|
{ //..e' possibile costruire la riga movimento
|
|
//Compila la riga del movimentodi analitica
|
|
TRectype& analriga = analmov.new_row();
|
|
|
|
analriga.put(RMOVANA_SEZIONE, importo.sezione());
|
|
analriga.put(RMOVANA_IMPORTO, importo.valore());
|
|
analriga.put(RMOVANA_DESCR, importo.descrizione());
|
|
|
|
analriga.put(RMOVANA_ANNOES, analmov.get(MOVANA_ANNOES));
|
|
analriga.put(RMOVANA_DATACOMP, analmov.get(MOVANA_DATAREG));
|
|
|
|
analriga.put(RMOVANA_CODCMS, chiave.get(0));
|
|
analriga.put(RMOVANA_CODFASE, chiave.get(1));
|
|
|
|
TString16 codconto;
|
|
codconto.format("%03d%03d%06ld", gruppo, conto, sottoconto);
|
|
analriga.put(RMOVANA_CODCONTO, codconto);
|
|
|
|
//controlla la coppia fase/(cdc-commessa) e decide se aggiungerla al file delle fasi
|
|
check_phase(analriga);
|
|
}
|
|
else //qui va aggiunta la lista dei conti che non hanno ripartizione quando NON si usa il..
|
|
//..piano dei conti contabile in analitica
|
|
error_box(TR("Manca la ripartizione di un conto"));
|
|
}
|
|
} //end FOR_EACH..
|
|
|
|
//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());
|
|
|
|
//Seconda parte del trasferimento: compatta e riscrive i movimenti(+righe) originali!
|
|
//Se e' riuscita la scrittura dei movimenti di analitica (MOVANA,RMOVANA)ed e' una conversione..
|
|
//..DEFINITIVA,riordina le righe e le testate dei movimenti originari (MOV,RMOV,RMOVIVA)..
|
|
//..riscrivendole
|
|
if (analmov.write(f) == NOERR && definitiva)
|
|
{
|
|
//se la chiave del documento origine e' completa puo' completare tale documento riempiendo il..
|
|
//..campo NUMREGCA (con lo stesso numero di NUMREG di analmov, in generale != da NUMREGCG
|
|
if (provv != ' ' && danno > 0 && dcodnum.not_empty() && dndoc > 0)
|
|
{
|
|
TDocumento dadoc(provv, danno, dcodnum, dndoc);
|
|
dadoc.put(DOC_NUMREGCA, analmov.get(MOVANA_NUMREG));
|
|
dadoc.rewrite();
|
|
}
|
|
//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("CODCMS");
|
|
rec->zero("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("CODCMS");
|
|
rec->zero("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;
|
|
}
|
|
|
|
//puo' finalmente riscrivere i files di origine puliti e compattati (sia iva che non)
|
|
mov.rewrite();
|
|
} //if(write=NOERR && definitiva...
|
|
}
|
|
|
|
void TConversione_cm2ca::kill_temp_movana(TConversione_anal_msk& mask)
|
|
{
|
|
TString query;
|
|
query << "USE MOVANA\nSELECT (TRASFERITO=\"X\")";
|
|
const TDate dataini = mask.get_date(F_DATAINI);
|
|
const TDate datafin = mask.get_date(F_DATAFIN);
|
|
|
|
if (dataini.ok() || datafin.ok())
|
|
query << "&&(BETWEEN(DATACOMP," << dataini.date2ansi() << "," << datafin.date2ansi() << "))";
|
|
|
|
TISAM_recordset temp_movana(query);
|
|
const long temp_movana_items = temp_movana.items();
|
|
TProgind pi(temp_movana_items, "Eliminazione movimenti trasferiti precedentemente...", false);
|
|
for (bool ok = temp_movana.move_first(); ok; ok = temp_movana.move_next())
|
|
{
|
|
pi.addstatus(1);
|
|
TAnal_mov movana(temp_movana.cursor()->curr(LF_MOVANA));
|
|
movana.remove(temp_movana.cursor()->file());
|
|
}
|
|
}
|
|
|
|
void TConversione_cm2ca::kill_old_tabs(const TString& tab)
|
|
{
|
|
//cancella la tabella commesse
|
|
TRelation rel_cms(tab);
|
|
TCursor cur_cms(&rel_cms);
|
|
const long items_cms = cur_cms.items();
|
|
if (items_cms > 0)
|
|
{
|
|
cur_cms.freeze();
|
|
for (cur_cms = 0; cur_cms.pos() < items_cms; ++cur_cms)
|
|
cur_cms.file().remove();
|
|
}
|
|
}
|
|
|
|
bool TConversione_cm2ca::convert_movs(TConversione_anal_msk& mask)
|
|
{
|
|
//ammazza tutti i movimenti di tipo "trasferito" provenienti da precedenti trasferimenti provvisori, tenendo..
|
|
//..conto dell'eventuale intervallo di date selezionato (per il trasferimento definitivo vuol dire tutti)
|
|
kill_temp_movana(mask);
|
|
|
|
//scandisce il file RMOV,alla ricerca dei record con codice fase o codice commessa compilato
|
|
TRelation rel_rmov(LF_RMOV);
|
|
//aggiunge MOV alla relazione per avere le DATACOMP da usare nel filtro
|
|
rel_rmov.add(LF_MOV, "NUMREG==NUMREG");
|
|
const bool definitiva = mask.get_int(F_TIPOCONV) != 0;
|
|
//costruzione filtro con date (in caso di conversione provvisoria)
|
|
TString filtro;
|
|
filtro << "((CODCMS!='')||(FASCMS!=''))&&(ROWTYPE!='T')";
|
|
|
|
const TDate dataini = mask.get_date(F_DATAINI);
|
|
if (dataini.ok())
|
|
filtro << "&&(ANSI(23->DATACOMP)>=" << dataini.string(ANSI) << ")";
|
|
const TDate datafin = mask.get_date(F_DATAFIN);
|
|
if (datafin.ok())
|
|
filtro << "&&(ANSI(23->DATACOMP)<=" << 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 movimenti e righe...", false);
|
|
|
|
long last_numreg_cg = 0; //numero registrazione originaria
|
|
|
|
TAssoc_array cg_lines_to_anal; //record array da riempire con gr/co/sott delle righe trasferite
|
|
|
|
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, cg_lines_to_anal, mask);
|
|
last_numreg_cg = curr_numreg_cg;
|
|
}
|
|
}
|
|
|
|
//aggiorna il piano dei conti flaggando i conti "analitici"
|
|
if (cg_lines_to_anal.items() > 0)
|
|
{
|
|
TLocalisamfile pcon(LF_PCON);
|
|
|
|
FOR_EACH_ASSOC_OBJECT(cg_lines_to_anal, h, k, object)
|
|
{
|
|
TToken_string tok = k;
|
|
const int gruppo = tok.get_int(0);
|
|
const int conto = tok.get_int(1);
|
|
const long sottoconto = tok.get_long(2);
|
|
//cerca il record con gr/co/sottoc sul file del piano dei conti...
|
|
pcon.put(PCN_GRUPPO, gruppo);
|
|
pcon.put(PCN_CONTO, conto);
|
|
pcon.put(PCN_SOTTOCONTO, sottoconto);
|
|
//..se lo trova e non e' gia' anale...
|
|
if (pcon.read() == NOERR && !pcon.get_bool(PCN_ANALITICA))
|
|
{
|
|
pcon.put(PCN_ANALITICA, "X"); //..lo analizza!..
|
|
pcon.rewrite(); //..e lo riscrive
|
|
}
|
|
}
|
|
}
|
|
} //end if(rmov_items>0)
|
|
|
|
//alla fine della fiera, in caso di trasferimento definitivo, elimina le commesse dalla vecchia tabella CMS e ..
|
|
//..le fasi dalla tabella FSC
|
|
if (definitiva)
|
|
{
|
|
kill_old_tabs("FSC");
|
|
kill_old_tabs("CMS");
|
|
}
|
|
return true;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Programma di conversione da CM a CA
|
|
///////////////////////////////////////////////////////////
|
|
|
|
int main(int argc,char** argv)
|
|
{
|
|
TConversione_cm2ca a;
|
|
a.run(argc,argv, "Trasferimento dati a Contabilita' Analitica");
|
|
|
|
return 0;
|
|
} |