campo-sirio/ce/ce4400.cpp
luca f721c1e01a Patch level :10.0
Files correlati     :
Ricompilazione Demo : [ ]
Commento            :collegamento CE/CG in corso di sviluppo


git-svn-id: svn://10.65.10.50/trunk@15948 c028cbd2-c16b-5b4b-a496-9718f37d4682
2008-01-02 15:50:26 +00:00

413 lines
11 KiB
C++
Executable File

#include <applicat.h>
#include <automask.h>
#include <progind.h>
#include <reprint.h>
#include <reputils.h>
#include "../cg/cg2101.h"
#include "celib.h"
#include "ce2101.h"
#include "ce4400a.h"
#include "ammce.h"
#include "cespi.h"
//===============================================================================================
//maschera
class TTrasf_mov_ce_cg_mask: public TAutomask
{
protected:
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
public:
TTrasf_mov_ce_cg_mask():TAutomask("ce4400a") { ditta_cespiti().init_mask(*this); }
};
bool TTrasf_mov_ce_cg_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
/* switch (o.dlg())
{
default: break;
}*/
return true;
}
//===============================================================================================
//Struct che serve per avere ammortamenti per categoria (Codcat|Qamm_tot|Qperse_tot)
struct TSaldo_per_codice :public TSortable
{
TString4 _spc;
int _grp, _cat;
TString80 _idcespite;
real _qnor, _qant, _qacc, _qperse;
void add(const TRectype& rec_ammce);
virtual int compare(const TSortable& s) const;
const TRectype& categoria() const;
int compila_rmov(const int tipo, const int riga_nor, TArray& righe_mov, TLog_report& log, const int movdett) const;
int genera_righe(TArray& righe_mov, TLog_report& log, const int movdett) const;
TSaldo_per_codice(const int grp, const TString4 spc, const int cat, const char* idcespite = "")
: _grp(grp),_spc(spc), _cat(cat), _idcespite(idcespite) {}
};
void TSaldo_per_codice::add(const TRectype& rec_ammce)
{
//valore totale degli ammortamenti del cespite di tipo qnor,qant,qacc che trova in AMMCE
const real qnor = rec_ammce.get_real(AMMCE_QNOR);
const real qant = rec_ammce.get_real(AMMCE_QANT);
const real qacc = rec_ammce.get_real(AMMCE_QACC);
//valore totale delle qperse del cespite che trova in AMMCE
const real qperse = rec_ammce.get_real(AMMCE_QPERSE);
_qnor += qnor;
_qant += qant;
_qacc += qacc;
_qperse += qperse;
}
//confrontatore di saldi_per_codice
int TSaldo_per_codice::compare(const TSortable& s) const
{
int cmp = 0;
const TSaldo_per_codice& sc = (const TSaldo_per_codice&)s;
cmp = _grp - sc._grp;
if (cmp == 0)
{
cmp = _spc.compare(sc._spc);
if (cmp == 0)
{
cmp = _cat - sc._cat;
if (cmp == 0)
cmp = _idcespite.compare(sc._idcespite);
}
}
return cmp;
}
bool str2bill(const TString& stringona, const int pos, TBill& zio)
{
const int gr = atoi(stringona.mid(pos, 3));
const int co = atoi(stringona.mid(pos+3, 3));
if (co <= 0)
return false;
const long so = atoi(stringona.mid(pos+6, 6));
zio.set(gr, co, so);
return true;
}
int TSaldo_per_codice::compila_rmov(const int tipo, const int riga_nor, TArray& righe_mov, TLog_report& log,
const int movdett) const
{
int pos = 0;
const char* field = "S1";
real quota;
switch (tipo)
{
case 1: quota = _qnor; pos = 24; break;
case 2: quota = _qant; pos = 36; break;
case 3: quota = _qacc; pos = 48; break;
case 4: quota = _qperse; pos = 0; field = "S2"; break;
default: break;
}
if (quota <= ZERO)
return -1;
const TRectype& rec_cac = categoria();
const TString& stringona = rec_cac.get(field);
TBill zio;
if (!str2bill(stringona, pos, zio))
{
if (tipo < 4)
{
pos = 24;
if (tipo == 1 || !str2bill(stringona, pos, zio))
{
TString msg;
msg << TR("Manca il conto per le quote ammortamento normali della categoria ") << rec_cac.get("CODTAB");
log.log(2, msg);
return -1;
}
}
else
{
TString msg;
msg << TR("Manca il conto per le quote perse della categoria ") << rec_cac.get("CODTAB");
log.log(2, msg);
return -1;
}
}
if (pos == 24 && riga_nor >= 0)
{
TRectype& rmovnor = (TRectype&)righe_mov[riga_nor];
rmovnor.add(RMV_IMPORTO, quota);
return riga_nor;
}
TRectype* rmov = new TRectype(LF_RMOV);
rmov->put(RMV_SEZIONE, "D");
rmov->put(RMV_IMPORTO, quota);
//conto e descrizione dipendono dal livello di dettaglio stabilito nella configurazione del collegamento CG/CE
switch (movdett)
{
case 0:
rmov->put(RMV_DESCR, rec_cac.get("S0"));
break;
case 1:
{
const TRectype& rec_cespi = cache().get(LF_CESPI, _idcespite);
rmov->put(RMV_DESCR, rec_cespi.get(CESPI_DESC));
}
break;
case 2:
{
const TRectype& rec_cespi = cache().get(LF_CESPI, _idcespite);
rmov->put(RMV_DESCR, rec_cespi.get(CESPI_DESC));
bool ok = real::is_natural(_idcespite);
if (ok)
{
const long sottoc = atol(_idcespite);
ok = sottoc > 0 && sottoc < 1000000;
if (ok)
zio.set(zio.gruppo(), zio.conto(), sottoc);
}
if (!ok)
{
TString msg;
msg.format(FR("Il codice cespite %s non e' un sottoconto valido"), (const char*)_idcespite);
log.log(2, msg);
}
}
break;
default:
break;
}
zio.put(*rmov);
return righe_mov.add(rmov);
}
//metodo di alto livello per la compilazione delle righe contabili;chiama il metodo di basso livello..
//..compila_rmov con i parametri caso x caso
int TSaldo_per_codice::genera_righe(TArray& righe_mov, TLog_report& log, const int movdett) const
{
const int righe_prima = righe_mov.items();
const int riga_nor = compila_rmov(1, -1, righe_mov, log, movdett);
const int riga_ant = compila_rmov(2, riga_nor, righe_mov, log, movdett);
const int riga_acc = compila_rmov(3, riga_nor, righe_mov, log, movdett);
const int riga_persa = compila_rmov(4, -1, righe_mov, log, movdett);
const int righe_dopo = righe_mov.items();
return righe_dopo - righe_prima; //messo qui tanto per poter compilare
}
const TRectype& TSaldo_per_codice::categoria() const
{
return ditta_cespiti().categoria(_grp, _spc, _cat);
}
//===============================================================================================
//Applicazione
class TTrasf_mov_ce_cg : public TSkeleton_application
{
TTrasf_mov_ce_cg_mask* _mask;
protected:
virtual void main_loop();
virtual bool create();
virtual bool destroy();
void elabora();
void delete_old_movs(const TDate& ini_es);
public:
};
void TTrasf_mov_ce_cg::delete_old_movs(const TDate& ini_es)
{
TMovimentoPN pn;
TRectype darec(LF_MOV);
darec.put(MOV_DATAREG, ini_es);
TString filtro;
filtro.format("(PROVVIS==\"C\")");
TCursor cur_mov (&pn, filtro, 2, &darec);
const long items = cur_mov.items();
cur_mov.freeze();
TProgind progind(items, "Eliminazione vecchi movimenti provvisori cespiti in corso...", false, true);
for (cur_mov = 0; cur_mov.pos() < items; ++cur_mov)
{
progind.addstatus(1);
pn.read();
pn.remove();
}
}
//metodo per gestire la successione degli eventi ad alto livello
void TTrasf_mov_ce_cg::elabora()
{
//gettiamo un po' di parametri dalla maschera
const long codes = _mask->get_long(F_ESERCIZIO);
const TDate ini_es = _mask->get_date(F_INIZIO_ES);
const TDate fine_es = _mask->get_date(F_FINE_ES);
//deve accoppare i movimenti provvisori di prima nota da inizio esercizio ad oggi?
if (_mask->get_bool(F_KILLOLD))
delete_old_movs(ini_es);
TDate datacalc;
//se il trasferimento e' definitivo la data di calcolo e' quella finale dell'esercizio selezionato, senno'...
//...e' quella indicata in F_DATACALC
if (_mask->get_bool(F_PROVDEF))
datacalc = _mask->get_date(F_FINE_ES);
else
datacalc = _mask->get_date(F_DATACALC);
//programma vero e proprio (calcolo ammortamenti, selezione cespiti validi, trasferimento)
TISAM_recordset cespiti("USE CESPI");
const TRecnotype nrec = cespiti.items();
//report con log errori
TLog_report cont_cesp_log(TR("Contabilizzazione cespiti"));
//Legge un po' di parametri dal ditta.ini che servono al tipo di calcolo
TConfig config_ditta_ce(CONFIG_DITTA, "ce");
//Situazione fiscale (99,99%) o civilistica (1 suora su 1.000.000)?
const int tpamm = config_ditta_ce.get_int("TPAMM");
//Tipo di calcolo da eseguire in base al dettaglio
const int movdett = config_ditta_ce.get_int("MOVDETT");
//Assoc_array Categoria-QammTot-QperseTot
TAssoc_array quote_per_codice;
TProgind pi(nrec, TR("Ricalcolo ammortamenti in corso..."), true, true);
for (int i = 0; cespiti.move_to(i); i++)
{
if (!pi.addstatus(1))
break;
//id e categoria del cespite corrente
const TString& idcespite = cespiti.get(CESPI_IDCESPITE).as_string();
const int gruppo = cespiti.get(CESPI_CODCGRA).as_int();
const TString4 specie = cespiti.get(CESPI_CODSPA).as_string();
const int codcat = cespiti.get(CESPI_CODCAT).as_int();
//calcola gli ammortamenti di tutti i cespiti; situazione presa dal config_ditta poco prima
//la calc_amm pensa da sola a calcolare gli ammortamenti solo per i cespiti validi
//l'ultimo parametro e' true x' il calcolo viene fatto in memoria!
TCespite cespite(idcespite);
if (cespite.calc_amm(tpamm, datacalc, false, true))
{
//controlla le quote del cespite in questione su AMMCE
const TRectype& rec_ammce = cespite.amm_pro();
//in base al tipo di dettaglio sceglie il codice dell'assoc_array
//movdett=0 -> codice=codice categoria (assoc_array con record per categorie)
//movdett=1;2 -> codice=idcespite (assoc_array con record per cespite)
TToken_string gsc;
gsc.add(gruppo); gsc.add(specie); gsc.add(codcat);
if (movdett != 0)
gsc.add(idcespite);
TSaldo_per_codice* sc = (TSaldo_per_codice*)quote_per_codice.objptr(gsc);
//se non trova il codice (categoria o cespite) lo aggiunge...
if (sc == NULL)
{
sc = new TSaldo_per_codice(gruppo, specie, codcat, idcespite);
quote_per_codice.add(gsc, sc);
}
//..e poi somma i valori comunque
sc->add(rec_ammce);
}
} //for(int i...
TArray saldi_ordinati;
//riempie l'array saldi_ordinati con gli elementi dell'assoc quote_per_codice
FOR_EACH_ASSOC_OBJECT(quote_per_codice, h, k, obj)
saldi_ordinati.add(h->remove_obj());
//accoppa l'assoc
quote_per_codice.destroy();
//e ordina l'array (questo assurdo giro serve perche' l'assoc non e' ordinabile)
saldi_ordinati.sort();
//array con le righe movimento CG
TArray righe_mov;
//riempie l'array delle righe movimento CG
FOR_EACH_ARRAY_ITEM(saldi_ordinati, riga, sldobj)
{
const TSaldo_per_codice& sld = *(const TSaldo_per_codice*)sldobj;
sld.genera_righe(righe_mov, cont_cesp_log, movdett);
}
/*TMovimentoPN mov;
mov.last();
//primo numero libero da usare come numreg
long numreg = mov.curr().get_long(MOV_NUMREG) + 1;*/
TReport_book book;
book.add(cont_cesp_log);
book.preview();
//calcolati,se richiesti,gli ammortamenti, passa in rassegna AMMCE e AMMMV alla ricerca dei cespiti..
//..da considerare per il trasferimento vero e proprio (sono quelli
}
bool TTrasf_mov_ce_cg::create()
{
_mask = new TTrasf_mov_ce_cg_mask;
return TSkeleton_application::create();
}
bool TTrasf_mov_ce_cg::destroy()
{
delete _mask;
return true;
}
void TTrasf_mov_ce_cg::main_loop()
{
KEY k = K_ENTER;
while (k != K_QUIT)
{
k = _mask->run();
switch (k)
{
case K_ENTER:
elabora();
break;
default:
break;
}
}
}
int ce4400(int argc, char* argv[])
{
TTrasf_mov_ce_cg a;
a.run(argc,argv,TR("Trasferimento cespiti in contabilita'"));
return 0;
}