2005-02-03 11:57:46 +00:00
|
|
|
#include <applicat.h>
|
|
|
|
#include <automask.h>
|
|
|
|
#include <progind.h>
|
|
|
|
#include <recarray.h>
|
|
|
|
#include <relation.h>
|
|
|
|
|
|
|
|
#include "calib01.h"
|
|
|
|
#include "ca2.h"
|
|
|
|
#include "ca2200a.h"
|
|
|
|
|
|
|
|
#include "movana.h"
|
|
|
|
#include "rmovana.h"
|
|
|
|
#include "rip.h"
|
|
|
|
#include "rrip.h"
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
// MASCHERA
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
class TRib_movanal_msk : public TAutomask
|
|
|
|
{
|
|
|
|
protected:
|
|
|
|
virtual bool on_field_event(TOperable_field& o, TField_event fe, long jolly);
|
|
|
|
|
|
|
|
public:
|
|
|
|
TRib_movanal_msk();
|
|
|
|
virtual ~TRib_movanal_msk(){};
|
|
|
|
};
|
|
|
|
|
|
|
|
TRib_movanal_msk::TRib_movanal_msk() :TAutomask ("ca2200a") { }
|
|
|
|
|
|
|
|
bool TRib_movanal_msk::on_field_event(TOperable_field& o, TField_event e, long jolly)
|
|
|
|
{
|
|
|
|
/* switch (o.dlg())
|
|
|
|
{
|
|
|
|
case :
|
|
|
|
break;
|
|
|
|
default: break;
|
|
|
|
}*/
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
// CLASSE PER RIPARTIZIONI RIGHE E TESTATE
|
|
|
|
//--------------------------------------------------------------------
|
2005-02-10 11:52:43 +00:00
|
|
|
class TRipartizione : public TMultiple_rectype
|
2005-02-03 11:57:46 +00:00
|
|
|
{
|
|
|
|
public:
|
2005-02-10 11:52:43 +00:00
|
|
|
TRipartizione(TString16 codice);
|
|
|
|
};
|
2005-02-03 11:57:46 +00:00
|
|
|
|
|
|
|
|
2005-02-10 11:52:43 +00:00
|
|
|
TRipartizione::TRipartizione(TString16 codice) : TMultiple_rectype(LF_RIP)
|
2005-02-03 11:57:46 +00:00
|
|
|
{
|
2005-02-10 11:52:43 +00:00
|
|
|
add_file(LF_RRIP, RRIP_CODICE);
|
|
|
|
if (codice.not_empty())
|
|
|
|
read();
|
2005-02-03 11:57:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
// CLASSE PER RIPARTIZIONI RIGHE
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
class TCache_ripartizioni : public TCache
|
|
|
|
{
|
|
|
|
protected:
|
|
|
|
virtual TObject* key2obj(const char* key);
|
|
|
|
|
|
|
|
public:
|
2005-03-02 15:28:14 +00:00
|
|
|
const TRecord_array& righe(const char* costo, const char* commessa);
|
2005-02-03 11:57:46 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
TObject* TCache_ripartizioni::key2obj(const char* key)
|
|
|
|
{
|
2005-03-02 15:28:14 +00:00
|
|
|
TToken_string parametro(key);
|
2005-02-23 09:30:28 +00:00
|
|
|
TLocalisamfile rip(LF_RIP);
|
2005-03-02 15:28:14 +00:00
|
|
|
rip.setkey(4); //chiave 4 (tipo+codcosto+codcms)
|
2005-02-23 09:30:28 +00:00
|
|
|
rip.put(RIP_TIPO, "B");
|
2005-03-02 15:28:14 +00:00
|
|
|
rip.put(RIP_CODCOSTO, parametro.get(0));
|
|
|
|
rip.put(RIP_CODCMS, parametro.get());
|
2005-02-23 09:30:28 +00:00
|
|
|
|
|
|
|
TString16 chiave;
|
|
|
|
if (rip.read() == NOERR)
|
|
|
|
chiave << "B|" << rip.get(RIP_CODICE);
|
|
|
|
|
|
|
|
TRecord_array* rows = new TRecord_array(chiave, LF_RRIP);
|
|
|
|
|
|
|
|
return (TObject*)rows;
|
2005-02-03 11:57:46 +00:00
|
|
|
}
|
|
|
|
|
2005-03-02 15:28:14 +00:00
|
|
|
const TRecord_array& TCache_ripartizioni::righe(const char* costo, const char* commessa)
|
2005-02-03 11:57:46 +00:00
|
|
|
{
|
2005-03-02 15:28:14 +00:00
|
|
|
TToken_string parametro;
|
|
|
|
parametro = costo;
|
|
|
|
parametro.add(commessa);
|
|
|
|
return *(const TRecord_array*)objptr(parametro);
|
2005-02-10 11:52:43 +00:00
|
|
|
}
|
2005-02-03 11:57:46 +00:00
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
// APPLICAZIONE
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
class TRib_movanal_app : public TSkeleton_application
|
|
|
|
{
|
|
|
|
TRib_movanal_msk * _mask;
|
2005-02-23 09:30:28 +00:00
|
|
|
TCache_ripartizioni _cache_rip;
|
2005-02-03 11:57:46 +00:00
|
|
|
|
2005-03-02 15:28:14 +00:00
|
|
|
virtual const char * extra_modules() const {return "cm";} //deve funzionare anche per le commesse
|
|
|
|
|
2005-02-03 11:57:46 +00:00
|
|
|
protected:
|
|
|
|
virtual bool create();
|
|
|
|
virtual bool destroy();
|
|
|
|
virtual void main_loop();
|
|
|
|
|
|
|
|
static bool cappotta_movimento(const TRelation& rel, void* pJolly);
|
2005-03-02 13:37:46 +00:00
|
|
|
void implode_rows(const TRecord_array& input_rows, TRecord_array& compact_rows);
|
|
|
|
bool explode_rows(const TRecord_array& input_rows, TRecord_array& output_rows);
|
|
|
|
bool can_merge_rows(const TRectype& compact_rec, const TRectype& rec);
|
|
|
|
|
2005-02-03 11:57:46 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
TRib_movanal_app() {}
|
|
|
|
};
|
|
|
|
|
|
|
|
bool TRib_movanal_app::create()
|
|
|
|
{
|
|
|
|
_mask = new TRib_movanal_msk;
|
|
|
|
return TSkeleton_application::create();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TRib_movanal_app::destroy()
|
|
|
|
{
|
|
|
|
delete _mask;
|
|
|
|
return TSkeleton_application::destroy();
|
|
|
|
}
|
|
|
|
|
2005-03-02 13:37:46 +00:00
|
|
|
static void copia_campo (const TRectype& src, const char* campo_src,
|
|
|
|
TRectype& dst, const char* campo_dst)
|
2005-02-23 09:30:28 +00:00
|
|
|
{
|
|
|
|
const TString& valore = src.get(campo_src);
|
|
|
|
if (!valore.blank())
|
|
|
|
dst.put(campo_dst, valore);
|
|
|
|
}
|
|
|
|
|
2005-03-02 13:37:46 +00:00
|
|
|
static void taglia_campo (TRectype& src, const char* campo_src,
|
|
|
|
TRectype& dst, const char* campo_dst)
|
2005-02-03 11:57:46 +00:00
|
|
|
{
|
2005-03-02 13:37:46 +00:00
|
|
|
copia_campo(src, campo_src, dst, campo_dst);
|
|
|
|
src.zero(campo_src);
|
|
|
|
}
|
2005-02-03 11:57:46 +00:00
|
|
|
|
2005-03-02 13:37:46 +00:00
|
|
|
bool TRib_movanal_app::can_merge_rows(const TRectype& compact_rec, const TRectype& rec)
|
|
|
|
{
|
|
|
|
return (compact_rec.get(RMOVANA_CODCCOSTO) == rec.get(RMOVANA_CODCCOSTO) &&
|
|
|
|
compact_rec.get(RMOVANA_CODCMS) == rec.get(RMOVANA_CODCMS) &&
|
|
|
|
compact_rec.get(RMOVANA_CODFASE) == rec.get(RMOVANA_CODFASE) &&
|
|
|
|
compact_rec.get(RMOVANA_CODFASE) == rec.get(RMOVANA_CODFASE) );
|
|
|
|
}
|
2005-02-10 11:52:43 +00:00
|
|
|
|
2005-03-02 13:37:46 +00:00
|
|
|
void TRib_movanal_app::implode_rows(const TRecord_array& input_rows, TRecord_array& compact_rows)
|
|
|
|
{
|
|
|
|
for (int r = 1; r <= input_rows.rows(); r++)
|
|
|
|
{
|
|
|
|
const TRectype& rec = input_rows.row(r); //record originale
|
|
|
|
TRectype* newrec = new TRectype(rec); //record destinazione
|
|
|
|
|
|
|
|
//ripristina i campi originali sul record di destinazione
|
|
|
|
taglia_campo(*newrec, RMOVANA_CODCCORI, *newrec, RMOVANA_CODCCOSTO);
|
|
|
|
taglia_campo(*newrec, RMOVANA_CODCMSORI, *newrec, RMOVANA_CODCMS);
|
|
|
|
taglia_campo(*newrec, RMOVANA_CODFASEORI, *newrec, RMOVANA_CODFASE);
|
|
|
|
taglia_campo(*newrec, RMOVANA_CODCONTORI, *newrec, RMOVANA_CODCONTO);
|
|
|
|
|
|
|
|
int i;
|
|
|
|
for (i = compact_rows.rows(); i > 0; i--) //giro sulle righe gia' compattate per scoprire se
|
|
|
|
{ //il nostro recoed esiste gia' o e' da aggiungere
|
|
|
|
const TRectype& nuovo_rec = compact_rows.row(i); //
|
|
|
|
if (can_merge_rows(nuovo_rec, rec)) //se esiste gia'...
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (i > 0) //...aggiunge solo importo e sezione...
|
|
|
|
{
|
|
|
|
const TImporto imp_rec(rec.get_char(RMOVANA_SEZIONE), rec.get_real(RMOVANA_IMPORTO));
|
|
|
|
TRectype& compact_rec = (TRectype&) compact_rows[i]; //record originale
|
|
|
|
TImporto imp_orig(compact_rec.get_char(RMOVANA_SEZIONE), compact_rec.get_real(RMOVANA_IMPORTO));
|
|
|
|
imp_orig += imp_rec;
|
|
|
|
imp_orig.normalize();
|
|
|
|
compact_rec.put(RMOVANA_SEZIONE, imp_orig.sezione());
|
|
|
|
compact_rec.put(RMOVANA_IMPORTO, imp_orig.valore());
|
|
|
|
}
|
|
|
|
else //...senno' aggiunge direttamente tutta la riga
|
|
|
|
compact_rows.add_row(newrec);
|
|
|
|
}
|
|
|
|
}
|
2005-02-03 11:57:46 +00:00
|
|
|
|
|
|
|
|
2005-03-02 13:37:46 +00:00
|
|
|
bool TRib_movanal_app::explode_rows(const TRecord_array& input_rows, TRecord_array& output_rows)
|
|
|
|
{
|
|
|
|
bool ho_cambiato_qualchecosa = false;
|
2005-02-23 09:30:28 +00:00
|
|
|
for (int r = 1; r <= input_rows.rows(); r++)
|
|
|
|
{
|
|
|
|
const TRectype& rec = input_rows.row(r);
|
2005-03-02 15:28:14 +00:00
|
|
|
const TRecord_array& rrip = _cache_rip.righe(rec.get(RMOVANA_CODCCOSTO), rec.get(RMOVANA_CODCMS));
|
|
|
|
|
2005-02-23 09:30:28 +00:00
|
|
|
if (rrip.rows() > 0) //ci sono righe di ripartizione
|
|
|
|
{
|
|
|
|
// Importo totale da distribuire arrotondato ai decimali della valuta di conto
|
|
|
|
TGeneric_distrib distrib(rec.get_real(RMOVANA_IMPORTO), TCurrency::get_firm_dec());
|
|
|
|
|
|
|
|
// Calcolo tutte le percentuali da ripartire
|
|
|
|
int i;
|
|
|
|
for (i = 1; i <= rrip.rows(); i++)
|
|
|
|
distrib.add(rrip[i].get_real("RIPARTO"));
|
|
|
|
|
|
|
|
for (i = 1; i <= rrip.rows(); i++)
|
|
|
|
{
|
|
|
|
TRectype* newrec = new TRectype(rec);
|
|
|
|
const real imp = distrib.get(); // Legge la quota da distribuire
|
|
|
|
newrec->put("IMPORTO", imp); //e la mette nella nuova riga
|
|
|
|
//poi copia i valori dei campi cdc,cms,fsc,con in quelli di tipo ori (nello stesso record)
|
|
|
|
copia_campo(rec, RMOVANA_CODCCOSTO, *newrec, RMOVANA_CODCCORI);
|
|
|
|
copia_campo(rec, RMOVANA_CODCMS, *newrec, RMOVANA_CODCMSORI);
|
|
|
|
copia_campo(rec, RMOVANA_CODFASE, *newrec, RMOVANA_CODFASEORI);
|
|
|
|
copia_campo(rec, RMOVANA_CODCONTO, *newrec, RMOVANA_CODCONTORI);
|
|
|
|
//e mette nei campi std i valori che trova nelle righe ripartizione
|
|
|
|
copia_campo(rrip[i], RRIP_CODCOSTO, *newrec, RMOVANA_CODCCOSTO);
|
|
|
|
copia_campo(rrip[i], RRIP_CODCMS, *newrec, RMOVANA_CODCMS);
|
|
|
|
copia_campo(rrip[i], RRIP_CODFASE, *newrec, RMOVANA_CODFASE);
|
|
|
|
copia_campo(rrip[i], RRIP_CODCONTO, *newrec, RMOVANA_CODCONTO);
|
|
|
|
|
|
|
|
output_rows.add_row(newrec);
|
|
|
|
ho_cambiato_qualchecosa = true;
|
|
|
|
}
|
2005-02-03 11:57:46 +00:00
|
|
|
|
2005-02-23 09:30:28 +00:00
|
|
|
}
|
|
|
|
else //nessuna riga di ripartizione->aggiungo la riga input all'output
|
|
|
|
{
|
|
|
|
output_rows.add_row(rec);
|
|
|
|
}
|
2005-02-03 11:57:46 +00:00
|
|
|
}
|
2005-03-02 13:37:46 +00:00
|
|
|
return ho_cambiato_qualchecosa;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool TRib_movanal_app::cappotta_movimento(const TRelation& rel, void* pJolly)
|
|
|
|
{
|
|
|
|
TRib_movanal_app& app = *(TRib_movanal_app*)pJolly;
|
2005-02-23 09:30:28 +00:00
|
|
|
|
2005-03-02 13:37:46 +00:00
|
|
|
TAnal_mov& anal_mov = (TAnal_mov&)rel.curr(); //movimento analitica
|
|
|
|
TRecord_array& input_rows = anal_mov.body(); //record_array con le righe del mov_anal (INPUT)
|
|
|
|
|
|
|
|
//Per prima cosa prende le righe del movimento su RMOVANA e le ricompatta..
|
|
|
|
TRecord_array compact_rows = input_rows; //record array con le righe compattate da creare con la
|
|
|
|
compact_rows.destroy_rows(); //implode_rows()
|
|
|
|
//Imploditore
|
|
|
|
app.implode_rows(input_rows, compact_rows);
|
|
|
|
|
|
|
|
//..poi lo riesplode in tutte le righe che possono nascere secondo le regole delle ripartizioni!
|
|
|
|
TRecord_array output_rows = input_rows; //crea il record_array di output come copia dell'INPUT..
|
|
|
|
output_rows.destroy_rows(); //..e poi lo pulisce
|
|
|
|
//Esploditore
|
|
|
|
if (app.explode_rows(compact_rows, output_rows))
|
2005-02-23 09:30:28 +00:00
|
|
|
output_rows.rewrite();
|
2005-03-02 13:37:46 +00:00
|
|
|
|
2005-02-03 11:57:46 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TRib_movanal_app::main_loop()
|
|
|
|
{
|
|
|
|
while (_mask->run() == K_ENTER)
|
|
|
|
{
|
|
|
|
//deve scandire il file MOVANA con chiave 2 (per data e numero di registrazione)
|
|
|
|
TRelation rel_movana(LF_MOVANA);
|
|
|
|
TRectype darec(LF_MOVANA), arec(LF_MOVANA);
|
|
|
|
darec.put(MOVANA_DATAREG, _mask->get_date(F_DATAINI));
|
|
|
|
arec.put(MOVANA_DATAREG, _mask->get_date(F_DATAFIN));
|
|
|
|
TString filtro;
|
|
|
|
filtro << "BLOCCATO==''";
|
|
|
|
|
|
|
|
TCursor cur_movana(&rel_movana, filtro, 2, &darec, &arec);
|
|
|
|
const long items = cur_movana.items();
|
|
|
|
//usa la scan dei TCursor,quindi niente progind e for,x' gia' nel metodo
|
|
|
|
if (items > 0)
|
|
|
|
{
|
2005-02-23 09:30:28 +00:00
|
|
|
rel_movana.lfile().set_curr(new TAnal_mov); //il record principale della rel e' un TMov_anal!!
|
2005-02-03 11:57:46 +00:00
|
|
|
cur_movana.scan(cappotta_movimento, this, "Ribaltamento movimenti...");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
message_box(TR("Non ci sono movimenti da ribaltare nel periodo selezionato"));
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int ca2200(int argc, char* argv[])
|
|
|
|
{
|
|
|
|
TRib_movanal_app app;
|
|
|
|
app.run(argc, argv, "Ribaltamento movimenti di analitica");
|
|
|
|
return 0;
|
|
|
|
}
|