Patch level : 2.2.

Files correlati     :
Ricompilazione Demo : [ ]
Commento            :
Aggiunto recordset per gestire "trasparentemente" i piani dei conti contabile o analitico.
Potenziato calcolo saldi per gestire anche i livelli intermedi dei conti e
soprattutto gestire la riclassificazione dei conti analitici tramite la tabella panapdc
Potenziato il generatore di movimenti casuale per gestire anche il piano dei conti contabile
nonche' la generazione automatica della tabela panapdc.


git-svn-id: svn://10.65.10.50/trunk@13265 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
guy 2005-07-07 17:05:02 +00:00
parent b3cc7469b0
commit 1cf194aed9
16 changed files with 1161 additions and 630 deletions

View File

@ -41,6 +41,7 @@
#define F_PDCI_4 136
#define F_DESPDCI_4 137
#define F_USE_PDCC 138
#define F_PREFIX 139
#define F_CDCREQ 140
#define F_CMSREQ 141

View File

@ -315,6 +315,18 @@ BOOLEAN F_USE_PDCC
BEGIN
PROMPT 2 11 "Utilizza il piano dei conti contabile"
FIELD UsePdcc
MESSAGE FALSE HIDE,F_PREFIX
MESSAGE TRUE SHOW,F_PREFIX
END
LIST F_PREFIX 1 10
BEGIN
PROMPT 54 11 "Prefisso "
ITEM "0|Nessuno"
ITEM "1|Livello 1"
ITEM "2|Livello 2"
ITEM "3|Livello 3"
FIELD PdcPrefix
END
TEXT -1
@ -345,8 +357,8 @@ END
STRING F_PDCI_2 20
BEGIN
PROMPT 2 14 "2 "
MESSAGE EMPTY CLEAR,F_PDCI_3|CLEAR,F_DESPDCI_3|K_TAB,F_PDCI_3|RESET,F_DESPDCI_2
MESSAGE ENABLE,F_PDCI_3|ENABLE,F_DESPDCI_3
MESSAGE EMPTY CLEAR,F_PDCI_3|CLEAR,F_DESPDCI_3|K_TAB,F_PDCI_3|RESET,F_DESPDCI_2|CLEAR,F_PREFIX
MESSAGE ENABLE,F_PDCI_3|ENABLE,F_DESPDCI_3|ENABLE,F_PREFIX
FLAGS "G"
FIELD Pdci(2)
END

View File

@ -587,17 +587,11 @@ class TPrint_mastrini_ca_rep : public TAnal_report
protected:
virtual bool set_recordset(const TString& sql);
virtual bool get_usr_val(const TString& name, TVariant& var) const;
public:
void set_filter(const TPrint_mastrini_ca_mask& msk, int cms_row);
};
bool TPrint_mastrini_ca_rep::get_usr_val(const TString& name, TVariant& var) const
{
return TAnal_report::get_usr_val(name, var);
}
bool TPrint_mastrini_ca_rep::set_recordset(const TString& sql)
{
TPrint_mastrini_ca_recordset* rs = new TPrint_mastrini_ca_recordset(sql);

View File

@ -6,6 +6,8 @@
#include "pconana.h"
#include "rmovana.h"
#include "../cg/cglib01.h"
#include "ca3.h"
#include "calib01.h"
#include "calib02.h"
@ -23,6 +25,7 @@ protected:
const TString& get_report_class() const;
bool test_compatible_report();
bool esistono_riclassificazioni() const;
void create_sheet();
int create_sheet_fields(int lf, int& y, short& dlg, bool required);
public:
@ -95,6 +98,21 @@ bool TPrint_bilancio_ca_mask::on_field_event(TOperable_field& o, TField_event e,
return error_box("Impossibile trovare un report compatibile");
}
break;
case F_PRE1:
case F_PRE2:
case F_PRE3:
if ((e == fe_init || e == fe_modify) && o.active())
{
const int k = o.dlg()-F_PRE1;
set(F_PAN1_INI + k, o.get(), 0x2);
disable(F_PAN1_INI + k);
disable(F_PANDES1_INI + k);
set(F_PAN1_FIN + k, o.get(), 0x2);
disable(F_PAN1_FIN + k);
disable(F_PANDES1_FIN + k);
}
break;
default:
break;
}
@ -205,6 +223,11 @@ void TPrint_bilancio_ca_mask::create_sheet()
}
}
bool TPrint_bilancio_ca_mask::esistono_riclassificazioni() const
{
TLocalisamfile ric(LF_PANAPDC);
return ric.first() == NOERR;
}
TPrint_bilancio_ca_mask::TPrint_bilancio_ca_mask()
:TAutomask("ca3300")
@ -212,62 +235,152 @@ TPrint_bilancio_ca_mask::TPrint_bilancio_ca_mask()
TConfig_anal cfg;
const bool use_pdcc = cfg.get_bool("UsePdcc");
const int logicnum = use_pdcc ? LF_PCON : LF_PCONANA;
const TMultilevel_code_info& pconana_info = ca_multilevel_code_info(LF_PCONANA);
const int pconana_levels = pconana_info.levels();
int pconana_prefix = cfg.get_int("PdcPrefix");
if (pconana_prefix >= pconana_levels)
pconana_prefix = pconana_levels-1;
const int nfields = ca_create_fields(*this, 1, logicnum, 2, 1, F_PDC1_INI, F_DES1_INI, 0x0, PCONANA_CODCONTO);
ca_create_fields(*this, 1, logicnum, 2, 7, F_PDC1_FIN, F_DES1_FIN, 0x0, PCONANA_CODCONTO);
disable(F_PIANO);
set(F_PIANO, use_pdcc ? "C" : "A");
// Controllo se voglio (e posso) usare il conto analitico come prefisso di quello contabile
const int pref = cfg.get_int("PdcPrefix");
if (use_pdcc && pref > 0)
{
const TMultilevel_code_info& info = ca_multilevel_code_info(LF_PCONANA);
const int levels = info.levels();
if (levels >= 2 && pref < levels && esistono_riclassificazioni())
{
enable(F_PIANO);
ca_create_fields(*this, 1, LF_PCONANA, 2, 2, F_PRE1, F_PREDES1, 0x0, PCONANA_CODCONTO);
// Nascondi i campi che non fanno parte del prefisso
for (int i = 0; i < levels; i++)
{
if (i < pref)
{
field(F_PRE1 + i).check_type(CHECK_REQUIRED);
field(F_PRE1 + i).set_group(6);
field(F_PREDES1 + i).set_group(6);
}
else
{
field(F_PRE1 + i).hide();
field(F_PREDES1 + i).hide();
}
}
}
}
for (int g = 5; g <= 6; g++)
{
const int logicnum = g == 5 ? LF_PCON : LF_PCONANA;
const short da_dlg = g == 5 ? F_PDC1_INI : F_PAN1_INI;
const short da_des = g == 5 ? F_PDCDES1_INI : F_PANDES1_INI;
const short a_dlg = g == 5 ? F_PDC1_FIN : F_PAN1_FIN;
const short a_des = g == 5 ? F_PDCDES1_FIN : F_PANDES1_FIN;
const int nfields = ca_create_fields(*this, 1, logicnum, 2, 8, da_dlg, da_des, 0x0, PCONANA_CODCONTO);
ca_create_fields(*this, 1, logicnum, 2, 14, a_dlg, a_des, 0x0, PCONANA_CODCONTO);
for (int i = 0; i < nfields; i++)
{
TMask_field& daconto = field(da_dlg + i);
daconto.set_group(1);
daconto.set_group(4);
daconto.set_group(g);
daconto.check_type(CHECK_NORMAL);
field(da_des+i).set_group(4);
field(da_des+i).set_group(g);
TMask_field& aconto = field(a_dlg + i);
aconto.set_group(2);
aconto.set_group(4);
aconto.set_group(g);
aconto.check_type(CHECK_NORMAL);
field(a_des+i).set_group(4);
field(a_des+i).set_group(g);
}
}
for (int i = 0; i < nfields; i++)
{
TMask_field& daconto = field(F_PDC1_INI + i);
daconto.set_group(1);
daconto.check_type(CHECK_NORMAL);
TMask_field& aconto = field(F_PDC1_FIN + i);
aconto.set_group(2);
aconto.check_type(CHECK_NORMAL);
}
// creazione dei campi della seconda pagina della maschera
create_sheet();
set_handlers(); // Setta l'andler universale a tutti i nuovi campi
}
////////////////////////////////////////////////////////
// Report
// TReport_bilancio_verifica
////////////////////////////////////////////////////////
class TReport_bilancio_ca : public TAnal_report
class TReport_bilancio_verifica : public TAnal_report
{
protected:
virtual bool set_recordset(const TString& sql);
public:
void set_filter(const TMask& msk, int row);
TReport_bilancio_ca(const char* name);
TReport_bilancio_verifica(const char* name);
};
bool TReport_bilancio_ca::set_recordset(const TString& /* sql */)
bool TReport_bilancio_verifica::set_recordset(const TString& /* sql */)
{
TPconana_recordset* rset = new TPconana_recordset();
return TReport::set_recordset(rset);
}
void TReport_bilancio_ca::set_filter(const TMask& m, int row)
void TReport_bilancio_verifica::set_filter(const TMask& m, int row)
{
TString da_conto, a_conto, costo, commessa, fase;
for (int i = 0; m.id2pos(F_PDC1_INI+i) > 0; i++)
const char tc = m.get(F_PIANO)[0]; // Contabile o Analitico?
const short dlg_da = tc == 'C' ? F_PDC1_INI : F_PAN1_INI;
const short dlg_al = tc == 'C' ? F_PDC1_FIN : F_PAN1_FIN;
for (int i = 0; m.id2pos(dlg_da+i) > 0; i++)
{
da_conto << m.get(F_PDC1_INI+i);
a_conto << m.get(F_PDC1_FIN+i);
da_conto << m.get(dlg_da+i);
a_conto << m.get(dlg_al+i);
}
const TDate dal = m.get(F_DATADA);
const TDate al = m.get(F_DATAA);
TDate dal = m.get(F_DATADA);
TDate al = m.get(F_DATAA);
int tipimov = 0;
switch (m.get(F_TIPOSTAMPA)[0])
{
case 'C': tipimov = 1; break; // Consuntivo
case 'P': tipimov = 6; break; // Preventivo e variazioni
default : tipimov = 7; break; // Raffronto
case 'C': tipimov = _saldanal_consuntivo; break; // Consuntivo
case 'P': tipimov = _saldanal_preventivi; break; // Preventivo e variazione preventivo
default : tipimov = _saldanal_qualsiasi; break; // Tutti per raffronto
}
// 1 = per data limite; 2 = all'ultima immissione
if (m.get_int(F_STAMPA) == 2)
{
const int anno = m.get_int(F_ANNO);
if (anno > 0)
{
TEsercizi_contabili esc;
dal = esc[anno].inizio();
al = esc[anno].fine();
}
tipimov |= _saldanal_ultima_imm;
}
if (tc == 'A' && m.id2pos(F_PRE1) > 0)
{
tipimov |= _saldanal_riclassify;
}
const TMultilevel_code_info& info = ca_multilevel_code_info(tc == 'A' ? LF_PCONANA : LF_PCON);
for (int s = info.levels()+1; s <= 4; s++)
{
section('H', s).deactivate();
section('F', s).deactivate();
}
const bool movimentati = m.get_int(F_STAMPAV) == 1;
@ -283,42 +396,258 @@ void TReport_bilancio_ca::set_filter(const TMask& m, int row)
fase = rel.curr().get(RMOVANA_CODFASE);
TPconana_recordset* rset = (TPconana_recordset*)recordset();
rset->set_filter(da_conto, a_conto, costo, commessa, fase, dal, al, tipimov, movimentati, nonnulli);
if (rset != NULL)
rset->set_filter(tc, da_conto, a_conto, costo, commessa, fase, dal, al, tipimov, movimentati, nonnulli);
}
TReport_bilancio_ca::TReport_bilancio_ca(const char* name)
TReport_bilancio_verifica::TReport_bilancio_verifica(const char* name)
{
load(name);
}
////////////////////////////////////////////////////////
// TRecordset_sezioni_contapposte
////////////////////////////////////////////////////////
class TRecordset_sezioni_contrapposte : public TRecordset
{
char _tipo_piano;
TAnal_bill _filter;
TDate _da_data, _a_data;
int _tipimov;
bool _movimentati, _nonnulli;
TString_array _attivita, _passivita, _costi, _ricavi;
TRecnotype _pos;
TRecordset_column_info _info[4];
protected:
TRecnotype items_ap() const;
TRecnotype items_cr() const;
public:
virtual TRecnotype items() const;
virtual bool move_to(TRecnotype pos);
virtual TRecnotype current_row() const { return _pos; }
virtual void requery();
virtual unsigned int columns() const;
virtual const TRecordset_column_info& column_info(unsigned int column) const;
virtual const TVariant& get(unsigned int column) const;
virtual const TVariant& get(const char* field) const;
void set_filter(char piano, const char* costo, const char* commessa, const char* fase,
const TDate& dal, const TDate& al, word tipimov, bool movimentati, bool nonnulli);
TRecordset_sezioni_contrapposte(char tipo_piano) : _tipo_piano(tipo_piano) { }
};
TRecnotype TRecordset_sezioni_contrapposte::items_ap() const
{ return max(_attivita.items(), _passivita.items()); }
TRecnotype TRecordset_sezioni_contrapposte::items_cr() const
{ return max(_costi.items(), _ricavi.items()); }
TRecnotype TRecordset_sezioni_contrapposte::items() const
{
return items_ap() + items_cr();
}
bool TRecordset_sezioni_contrapposte::move_to(TRecnotype pos)
{
_pos = pos;
return _pos < items();
}
void TRecordset_sezioni_contrapposte::set_filter(char piano, const char* costo,
const char* commessa, const char* fase,
const TDate& dal, const TDate& al,
word tipimov, bool movimentati, bool nonnulli)
{
_tipo_piano = piano;
_da_data = dal;
_a_data = al;
_tipimov = tipimov;
_movimentati = movimentati;
_nonnulli = nonnulli;
_filter.reset();
_filter.set_costo(costo);
_filter.set_commessa(commessa);
_filter.set_fase(fase);
}
void TRecordset_sezioni_contrapposte::requery()
{
TPconana_recordset pconana(_tipo_piano);
pconana.set_filter(_tipo_piano, NULL, NULL, _filter.costo(), _filter.commessa(), _filter.fase(),
_da_data, _a_data, _tipimov, _movimentati, _nonnulli);
int indicatore_bilancio = 1;
for (TRecnotype i = 0; pconana.move_to(i); i++)
{
const int ib = pconana.get(PCONANA_INDBIL).as_int();
if (ib >= 1 && ib <= 4)
indicatore_bilancio = ib;
const TString& conto = pconana.get(PCONANA_CODCONTO).as_string();
switch (indicatore_bilancio)
{
case 1: _attivita.add(conto); break;
case 2: _passivita.add(conto); break;
case 3: _costi.add(conto); break;
case 4: _ricavi.add(conto); break;
default: break;
}
}
move_to(0);
}
unsigned int TRecordset_sezioni_contrapposte::columns() const
{ return 4; }
const TRecordset_column_info& TRecordset_sezioni_contrapposte::column_info(unsigned int column) const
{
return _info[column];
}
const TVariant& TRecordset_sezioni_contrapposte::get(unsigned int column) const
{
return NULL_VARIANT;
}
const TVariant& TRecordset_sezioni_contrapposte::get(const char* field) const
{
return NULL_VARIANT;
}
////////////////////////////////////////////////////////
// TReport_bilancio_sezioni_contapposte
////////////////////////////////////////////////////////
class TReport_bilancio_sezioni_contrapposte : public TAnal_report
{
protected:
virtual bool TReport_bilancio_sezioni_contrapposte::set_recordset(const TString& sql);
public:
void set_filter(const TMask& msk, int row);
TReport_bilancio_sezioni_contrapposte(const char* name) { load(name); }
};
bool TReport_bilancio_sezioni_contrapposte::set_recordset(const TString& /* sql */)
{
TRecordset_sezioni_contrapposte* rset = new TRecordset_sezioni_contrapposte('A');
return TReport::set_recordset(rset);
}
void TReport_bilancio_sezioni_contrapposte::set_filter(const TMask& m, int row)
{
TDate dal = m.get(F_DATADA);
TDate al = m.get(F_DATAA);
int tipimov = 0;
switch (m.get(F_TIPOSTAMPA)[0])
{
case 'C': tipimov = _saldanal_consuntivo; break; // Consuntivo
case 'P': tipimov = _saldanal_preventivi; break; // Preventivo e variazione preventivo
default : tipimov = _saldanal_qualsiasi; break; // Tutti per raffronto
}
// 1 = per data limite; 2 = all'ultima immissione
if (m.get_int(F_STAMPA) == 2)
{
const int anno = m.get_int(F_ANNO);
if (anno > 0)
{
TEsercizi_contabili esc;
dal = esc[anno].inizio();
al = esc[anno].fine();
}
tipimov |= _saldanal_ultima_imm;
}
const char tipo = m.get(F_PIANO)[0];
if (tipo == 'A' && m.id2pos(F_PRE1) > 0)
{
tipimov |= _saldanal_riclassify;
}
const bool movimentati = m.get_int(F_STAMPAV) == 1;
const bool nonnulli = m.get_int(F_STAMPAV) == 2;
TSheet_field& sf = m.sfield(F_RIGHE);
TMask& sm = sf.sheet_mask();
sf.update_mask(row);
TRelation rel(LF_RMOVANA);
sm.autosave(rel);
const TString80 costo = rel.curr().get(RMOVANA_CODCCOSTO);
const TString80 commessa = rel.curr().get(RMOVANA_CODCMS);
const TString16 fase = rel.curr().get(RMOVANA_CODFASE);
TRecordset_sezioni_contrapposte* recset = new TRecordset_sezioni_contrapposte(tipo);
recset->set_filter(tipo, costo, commessa, fase, dal, al, tipimov, movimentati, nonnulli);
TAnal_report::set_recordset(recset);
};
////////////////////////////////////////////////////////
// APPLICAZIONE
////////////////////////////////////////////////////////
class TPrint_bilancio_ca : public TSkeleton_application
{
protected:
void bilancio_a_sezioni_contrapposte(TMask& mask);
void bilancio_di_verifica(TMask& msk);
public:
virtual void main_loop();
};
void TPrint_bilancio_ca::bilancio_a_sezioni_contrapposte(TMask& mask)
{
TReport_bilancio_sezioni_contrapposte rep(mask.get(F_REPORT));
TSheet_field& sf = mask.sfield(F_RIGHE);
const int rows = sf.items();
TReport_book book;
for (int i = 0; i < rows; i++)
{
rep.set_filter(mask, i);
book.add(rep);
}
book.print_or_preview();
}
void TPrint_bilancio_ca::bilancio_di_verifica(TMask& mask)
{
TReport_bilancio_verifica rep(mask.get(F_REPORT));
const int rows = mask.sfield(F_RIGHE).items();
TReport_book book;
for (int i = 0; i < rows; i++)
{
rep.set_filter(mask, i);
book.add(rep);
}
book.print_or_preview();
}
void TPrint_bilancio_ca::main_loop()
{
TPrint_bilancio_ca_mask mask;
while (mask.run() != K_QUIT)
{
TReport_book book;
TReport_bilancio_ca rep(mask.get(F_REPORT));
TSheet_field& sf = mask.sfield(F_RIGHE);
if (sf.empty())
sf.row(-1); // Aggiungo riga vuota
const int rows = sf.items();
for (int i = 0; i < rows; i++)
{
rep.set_filter(mask, i);
book.add(rep);
}
book.print_or_preview();
if (mask.get(F_BILANCIO) == "C")
bilancio_a_sezioni_contrapposte(mask);
else
bilancio_di_verifica(mask);
}
}

View File

@ -8,22 +8,47 @@
#define F_ANNO 304
#define F_BILANCIO 105
#define F_STAMPA 107
#define F_CODICI 309
#define F_SALDO 310
#define F_STAMPAV 311
#define F_DATADA 312
#define F_DATAA 313
#define F_TIPOSTAMPA 314
//campi generati dal pdc
#define F_PDC1_INI 316
#define F_PDC4_INI 319
#define F_PDC1_FIN 336
#define F_PDC4_FIN 339
#define F_DES1_INI 356
#define F_DES4_INI 359
#define F_DES1_FIN 376
#define F_DES4_FIN 379
//campi generati dai piani dei conti
#define F_PIANO 319
#define F_PRE0 320
#define F_PRE1 321
#define F_PRE2 322
#define F_PRE3 323
// #define F_PRE4 324 // Non puo' e non deve esistere!
#define F_PREDES1 325
#define F_PREDES2 326
#define F_PREDES3 327
// #define F_PREDES4 328 // Non puo' e non deve esistere!
#define F_PDC0_INI 330
#define F_PDC1_INI 331
#define F_PDC4_INI 334
#define F_PDCDES1_INI 335
#define F_PDCDES4_INI 338
#define F_PDC0_FIN 340
#define F_PDC1_FIN 341
#define F_PDC4_FIN 344
#define F_PDCDES1_FIN 345
#define F_PDCDES4_FIN 348
#define F_PAN0_INI 350
#define F_PAN1_INI 351
#define F_PAN4_INI 354
#define F_PANDES1_INI 355
#define F_PANDES4_INI 358
#define F_PAN0_FIN 360
#define F_PAN1_FIN 361
#define F_PAN4_FIN 364
#define F_PANDES1_FIN 365
#define F_PANDES4_FIN 368
#define F_SELECT 394
#define F_REPORT 395

View File

@ -72,9 +72,9 @@ RADIOBUTTON F_BILANCIO 1 28
BEGIN
PROMPT 2 4 "@bBilancio"
ITEM "C|A sezioni contrapposte"
MESSAGE HIDE,4@|SHOW,3@
MESSAGE CLEAR,4@|ENABLE,3@
ITEM "V|Di verifica"
MESSAGE SHOW,4@|HIDE,3@
MESSAGE ENABLE,4@|CLEAR,3@
END
LIST F_TIPOSTAMPA 11
@ -120,12 +120,6 @@ BEGIN
GROUP 4
END
BOOLEAN F_CODICI
BEGIN
PROMPT 42 8 "Non stampare codici conti "
GROUP 4
END
STRING F_REPORT 256 66
BEGIN
PROMPT 2 9 "Report "
@ -154,14 +148,31 @@ ENDPAGE
PAGE "Selezioni" -1 -1 74 20
GROUPBOX DLG_NULL 78 6
LIST F_PIANO 1 20
BEGIN
PROMPT 1 0 "@bDa:"
PROMPT 1 0 "Piano dei conti "
ITEM "A|Analitico"
MESSAGE HIDE,5@|SHOW,6@
ITEM "C|Contabile"
MESSAGE SHOW,5@|HIDE,6@
END
GROUPBOX DLG_NULL 78 6
GROUPBOX F_PRE0 78 6
BEGIN
PROMPT 1 6 "@bA:"
PROMPT 1 1 "@bPrefisso del piano dei conti analitico:"
GROUP 6
END
GROUPBOX F_PDC0_INI 78 6
BEGIN
PROMPT 1 7 "@bDa conto:"
GROUP 4
END
GROUPBOX F_PDC0_FIN 78 6
BEGIN
PROMPT 1 13 "@bA conto:"
GROUP 4
END
ENDPAGE

View File

@ -1,257 +1,34 @@
<report name="ca3300a" orientation="2" lpi="8" command="ca3 -2" class="ca3300a">
<description>Bilancio di raffronto di verifica</description>
<font face="Courier New" size="8" />
<report name="ca3300a" lpi="6">
<description>Stampa mastrini contabilta' analitica</description>
<font face="Courier New" size="10" />
<section type="Head">
<font italic="1" face="Courier New" bold="1" size="10" />
<field type="Stringa" width="50" pattern="1">
<font face="Courier New" bold="1" size="10" />
<source>#SYSTEM.RAGSOC</source>
</field>
<field x="90" type="Data" width="10" pattern="1">
<source>#SYSTEM.DATE</source>
</field>
<field x="164" type="Numero" align="right" width="4" pattern="1">
<source>#REPORT.PAGE</source>
</field>
<field y="2" type="Testo" width="20" pattern="1" text="Centro di costo:" />
<field x="20" y="2" type="Stringa" width="24" pattern="1">
<source>#COSTO</source>
</field>
<field x="45" y="2" type="Stringa" width="50" pattern="1">
<prescript>MESSAGE ISAMREAD,CDC,CODCOSTO=#COSTO,DESCRIZ</prescript>
</field>
<field y="3" type="Testo" width="20" pattern="1" text="Commessa:" />
<field x="20" y="3" type="Stringa" width="24" pattern="1">
<source>#COMMESSA</source>
</field>
<field x="45" y="3" type="Stringa" width="50" pattern="1">
<prescript>MESSAGE ISAMREAD,COMMESSE,CODCMS=#COMMESSA,DESCRIZ</prescript>
</field>
<field y="4" type="Testo" width="20" pattern="1" text="Fase:" />
<field x="20" y="4" type="Stringa" width="13" pattern="1">
<source>#FASE</source>
</field>
<field x="45" y="4" type="Stringa" width="50" pattern="1">
<prescript>MESSAGE ISAMREAD,FASI,CODCMSFAS=#CMSCDC!CODFASE=#FASE,DESCRIZ</prescript>
</field>
<field border="1" y="6" type="Linea" width="168" height="0" pattern="1" />
<field x="85" y="6" type="Testo" align="center" width="27" pattern="1" text="SALDO INIZIALE" />
<field x="113" y="6" type="Testo" align="center" width="27" pattern="1" text="MOVIMENTI DEL PERIODO" />
<field x="141" y="6" type="Testo" align="center" width="27" pattern="1" text="SALDO FINALE" />
<field y="6.5" type="Testo" width="10" pattern="1" text="Conto" />
<field x="30" y="6.5" type="Testo" width="15" pattern="1" text="Descrizione" />
<field x="78" y="7" type="Testo" align="right" width="13" pattern="1" text="DARE" />
<field x="92" y="7" type="Testo" align="right" width="13" pattern="1" text="AVERE" />
<field x="109" y="7" type="Testo" align="right" width="13" pattern="1" text="DARE" />
<field x="123" y="7" type="Testo" align="right" width="13" pattern="1" text="AVERE" />
<field x="141" y="7" type="Testo" align="right" width="13" pattern="1" text="DARE" />
<field x="155" y="7" type="Testo" align="right" width="13" pattern="1" text="AVERE" />
<field border="1" x="-1" y="8" type="Linea" width="168" height="0" pattern="1" />
</section>
<section type="Head" level="1" height="3">
<field border="1" radius="100" x="1" type="Testo" valign="center" align="center" shade_offset="25" width="166" height="2.5" text="BILANCIO DI RAFFRONTO DI VERIFICA">
<font face="Courier New" bold="1" size="16" />
<field y="1" type="Testo" valign="center" align="center" width="198" height="2" pattern="1" text="Stampa Bilancio di Contabilita' Analitica">
<font face="Courier New" bold="1" size="14" />
</field>
</section>
<section type="Head" level="1" />
<section type="Head" level="2">
<condition>CODCONTO:2!=""</condition>
<groupby>CODCONTO:1</groupby>
<prescript description="H2 PRESCRIPT">"CODCONTO:1" @
"F2.101" !
"F2" AZZERA_TOTALI
</prescript>
</section>
<section type="Head" level="3">
<condition>CODCONTO:3!=""</condition>
<groupby>CODCONTO:2</groupby>
<prescript description="H3 PRESCRIPT">"CODCONTO:2" @
"F3.101" !
"F3" AZZERA_TOTALI
</prescript>
</section>
<section type="Head" level="4">
<condition>CODCONTO:4 != ""</condition>
<groupby>CODCONTO:3</groupby>
<prescript description="H4 PRESCRIPT">"CODCONTO:3" @
"F4.101" !
"F4" AZZERA_TOTALI
</prescript>
<groupby>CODCONTO</groupby>
<font face="Courier New" bold="1" size="12" />
<field border="1" y="3" type="Linea" width="198" height="0" pattern="1" />
</section>
<section type="Body" />
<section type="Body" level="1" height="4">
<field type="Stringa" width="24" id="101" pattern="1">
<source>CODCONTO</source>
<prescript description="B1.101 PRESCRIPT">CA_FORMAT_CONTO</prescript>
<section type="Body" level="1" />
<section type="Foot" height="1">
<field x="2" type="Data" width="10" pattern="1">
<source>#SYSTEM.DATE</source>
</field>
<field x="25" type="Stringa" width="50" id="102" pattern="1">
<source>DESCR</source>
</field>
<field x="78" type="Valuta" align="right" width="13" id="103" pattern="1" hide_zero="1" text="###.###.###,@@">
<source>SALDO:INI_DAREP</source>
</field>
<field x="92" type="Valuta" align="right" width="13" id="104" pattern="1" hide_zero="1" text="###.###.###,@@">
<source>SALDO:INI_AVEREP</source>
</field>
<field x="109" type="Valuta" align="right" width="13" id="105" pattern="1" hide_zero="1" text="###.###.###,@@">
<source>SALDO:MOV_DAREP</source>
</field>
<field x="123" type="Valuta" align="right" width="13" id="106" pattern="1" hide_zero="1" text="###.###.###,@@">
<source>SALDO:MOV_AVEREP</source>
</field>
<field x="141" type="Valuta" align="right" width="13" id="107" pattern="1" hide_zero="1" text="###.###.###,@@">
<source>SALDO:FIN_DAREP</source>
</field>
<field x="155" type="Valuta" align="right" width="13" id="108" pattern="1" hide_zero="1" text="###.###.###,@@">
<source>SALDO:FIN_AVEREP</source>
</field>
<field x="78" y="1" type="Valuta" align="right" width="13" id="203" pattern="1" hide_zero="1" text="###.###.###,@@">
<source>SALDO:INI_DAREC</source>
</field>
<field x="92" y="1" type="Valuta" align="right" width="13" id="204" pattern="1" hide_zero="1" text="###.###.###,@@">
<source>SALDO:INI_AVEREC</source>
</field>
<field x="109" y="1" type="Valuta" align="right" width="13" id="205" pattern="1" hide_zero="1" text="###.###.###,@@">
<source>SALDO:MOV_DAREC</source>
</field>
<field x="123" y="1" type="Valuta" align="right" width="13" id="206" pattern="1" hide_zero="1" text="###.###.###,@@">
<source>SALDO:MOV_AVEREC</source>
</field>
<field x="141" y="1" type="Valuta" align="right" width="13" id="207" pattern="1" hide_zero="1" text="###.###.###,@@">
<source>SALDO:FIN_DAREC</source>
</field>
<field x="155" y="1" type="Valuta" align="right" width="13" id="208" pattern="1" hide_zero="1" text="###.###.###,@@">
<source>SALDO:FIN_AVEREC</source>
</field>
<field x="78" y="2" type="Valuta" align="right" width="13" id="303" pattern="1" hide_zero="1" text="###.###.###,@@">
<source>#103-#203</source>
<postscript description="B1.303 POSTSCRIPT">MESSAGE ADD,F4.103|ADD,F3.103|ADD,F2.103</postscript>
</field>
<field x="92" y="2" type="Valuta" align="right" width="13" id="304" pattern="1" hide_zero="1" text="###.###.###,@@">
<source>#104-#204</source>
<postscript description="B1.304 POSTSCRIPT">MESSAGE ADD,F4.104|ADD,F3.104|ADD,F2.104</postscript>
</field>
<field x="109" y="2" type="Valuta" align="right" width="13" id="305" pattern="1" hide_zero="1" text="###.###.###,@@">
<source>#105-#205</source>
<postscript description="B1.305 POSTSCRIPT">MESSAGE ADD,F4.105|ADD,F3.105|ADD,F2.105</postscript>
</field>
<field x="123" y="2" type="Valuta" align="right" width="13" id="306" pattern="1" hide_zero="1" text="###.###.###,@@">
<source>#106-#206</source>
<postscript description="B1.306 POSTSCRIPT">MESSAGE ADD,F4.106|ADD,F3.106|ADD,F2.106</postscript>
</field>
<field x="141" y="2" type="Valuta" align="right" width="13" id="307" pattern="1" hide_zero="1" text="###.###.###,@@">
<source>#107-#207</source>
<postscript description="B1.307 POSTSCRIPT">MESSAGE ADD,F4.107|ADD,F3.107|ADD,F2.107</postscript>
</field>
<field x="155" y="2" type="Valuta" align="right" width="13" id="308" pattern="1" hide_zero="1" text="###.###.###,@@">
<source>#108-#208</source>
<postscript description="B1.308 POSTSCRIPT">MESSAGE ADD,F4.108|ADD,F3.108|ADD,F2.108</postscript>
<field x="180" type="Numero" align="right" width="10" pattern="1">
<source>#REPORT.PAGE</source>
</field>
</section>
<section type="Foot" />
<section type="Foot" level="1" />
<section type="Foot" level="2">
<condition>#101 != ""</condition>
<field type="Stringa" width="23" id="101" pattern="1">
<prescript>#THIS @ #102 !
CA_FORMAT_CONTO</prescript>
</field>
<field x="25" type="Stringa" width="50" id="102" pattern="1">
<font face="Courier New" bold="1" size="8" />
<prescript description="F2.102 PRESCRIPT">MESSAGE ISAMREAD,PCONANA,CODCONTO=#102,DESCR</prescript>
</field>
<field x="78" type="Valuta" align="right" width="13" id="103" pattern="1" hide_zero="1" text="###.###.###,@@">
<prescript>103 DARE_AVERE</prescript>
</field>
<field x="92" type="Valuta" align="right" width="13" id="104" pattern="1" hide_zero="1" text="###.###.###,@@" />
<field x="109" type="Valuta" align="right" width="13" id="105" pattern="1" hide_zero="1" text="###.###.###,@@">
<font face="Courier New" bold="1" size="8" />
</field>
<field x="123" type="Valuta" align="right" width="13" id="106" pattern="1" hide_zero="1" text="###.###.###,@@">
<font face="Courier New" bold="1" size="8" />
</field>
<field x="141" type="Valuta" align="right" width="13" id="107" pattern="1" hide_zero="1" text="###.###.###,@@">
<font face="Courier New" bold="1" size="8" />
<prescript description="F2.107 PRESCRIPT">107 DARE_AVERE</prescript>
</field>
<field x="155" type="Valuta" align="right" width="13" id="108" pattern="1" hide_zero="1" text="###.###.###,@@">
<font face="Courier New" bold="1" size="8" />
</field>
</section>
<section type="Foot" level="3">
<condition>#101 != ""</condition>
<font face="Courier New" bold="1" size="8" />
<field type="Stringa" width="23" id="101" pattern="1">
<prescript>#THIS @ #102 !
CA_FORMAT_CONTO</prescript>
</field>
<field x="25" type="Stringa" width="50" id="102" pattern="1">
<prescript>MESSAGE ISAMREAD,PCONANA,CODCONTO=#102,DESCR</prescript>
</field>
<field x="78" type="Valuta" align="right" width="13" id="103" pattern="1" hide_zero="1" text="###.###.###,@@">
<prescript>103 DARE_AVERE</prescript>
</field>
<field x="92" type="Valuta" align="right" width="13" id="104" pattern="1" hide_zero="1" text="###.###.###,@@" />
<field x="109" type="Valuta" align="right" width="13" id="105" pattern="1" hide_zero="1" text="###.###.###,@@" />
<field x="123" type="Valuta" align="right" width="13" id="106" pattern="1" hide_zero="1" text="###.###.###,@@" />
<field x="141" type="Valuta" align="right" width="13" id="107" pattern="1" hide_zero="1" text="###.###.###,@@">
<prescript>107 DARE_AVERE</prescript>
</field>
<field x="155" type="Valuta" align="right" width="13" id="108" pattern="1" hide_zero="1" text="###.###.###,@@" />
</section>
<section type="Foot" level="4">
<condition>#101 != ""</condition>
<font face="Courier New" bold="1" size="8" />
<field type="Stringa" width="23" id="101" pattern="1">
<prescript>#THIS @ #102 !
CA_FORMAT_CONTO</prescript>
</field>
<field x="25" type="Stringa" width="50" id="102" pattern="1">
<prescript>MESSAGE ISAMREAD,PCONANA,CODCONTO=#102,DESCR</prescript>
</field>
<field x="78" type="Valuta" align="right" width="13" id="103" pattern="1" hide_zero="1" text="###.###.###,@@">
<prescript>103 DARE_AVERE</prescript>
</field>
<field x="92" type="Valuta" align="right" width="13" id="104" pattern="1" hide_zero="1" text="###.###.###,@@" />
<field x="109" type="Valuta" align="right" width="13" id="105" pattern="1" hide_zero="1" text="###.###.###,@@" />
<field x="123" type="Valuta" align="right" width="13" id="106" pattern="1" hide_zero="1" text="###.###.###,@@" />
<field x="141" type="Valuta" align="right" width="13" id="107" pattern="1" hide_zero="1" text="###.###.###,@@">
<prescript>107 DARE_AVERE</prescript>
</field>
<field x="155" type="Valuta" align="right" width="13" id="108" pattern="1" hide_zero="1" text="###.###.###,@@" />
</section>
<sql>USE PCONANA SELECT LEN(CODCONTO)=10</sql>
<prescript description="PRESCRIPT">: AZZERA_TOTALI ( ID_SEC - )
109 103 DO
DUP \ Duplica codice sezione
"." + \ Aggiunge punto
I + \ Aggiunge codice campo
0 SWAP ! \ Lo azzera
LOOP
DROP
;
: DARE_AVERE ( ID_DARE -- )
VARIABLE _DARE
VARIABLE _AVERE
DUP
_DARE !
1 + _AVERE !
_DARE @ @ \ DARE
_AVERE @ @ \ AVERE
- \ DARE-AVERE
DUP
0 &#3C; IF \ Se negativo
-1 * \ Cambia segno
_AVERE @ ! \ Setta AVERE
0 _DARE @ ! \ Azzera DARE
ELSE
_DARE @ ! \ Setta DARE
0 _AVERE @ ! \ Azzera AVERE
THEN
;
</prescript>
<section type="Foot" level="2" />
<sql>USE RMOVANA
JOIN PCONANA INTO CODCONTO==CODCONTO</sql>
</report>

View File

@ -58,6 +58,8 @@
<groupby>CODCONTO:1</groupby>
<prescript description="H2 PRESCRIPT">"CODCONTO:1" @
"F2.101" !
"DESCR:1" @
"F2.102" !
"F2" AZZERA_TOTALI
</prescript>
@ -67,6 +69,8 @@
<groupby>CODCONTO:2</groupby>
<prescript description="H3 PRESCRIPT">"CODCONTO:2" @
"F3.101" !
"DESCR:2" @
"F3.102" !
"F3" AZZERA_TOTALI</prescript>
</section>
@ -75,6 +79,8 @@
<groupby>CODCONTO:3</groupby>
<prescript description="H4 PRESCRIPT">"CODCONTO:3" @
"F4.101" ! \ Copia il codice conto nel footer
"DESCR:3" @
"F4.102" !
"F4" AZZERA_TOTALI</prescript>
</section>
@ -119,12 +125,9 @@
<condition>#101 != ""</condition>
<font face="Courier New" bold="1" size="8" />
<field type="Stringa" width="23" id="101" pattern="1">
<prescript description="F2.101 PRESCRIPT">#THIS @ #102 !
CA_FORMAT_CONTO</prescript>
</field>
<field x="25" type="Stringa" width="50" id="102" pattern="1">
<prescript description="F2.102 PRESCRIPT">MESSAGE ISAMREAD,PCONANA,CODCONTO=#102,DESCR</prescript>
<prescript description="F2.101 PRESCRIPT">CA_FORMAT_CONTO</prescript>
</field>
<field x="25" type="Stringa" width="50" id="102" pattern="1" />
<field x="78" type="Valuta" align="right" width="13" id="103" pattern="1" hide_zero="1" text="###.###.###,@@">
<prescript description="F2.103 PRESCRIPT">103 DARE_AVERE</prescript>
</field>
@ -140,12 +143,9 @@ CA_FORMAT_CONTO</prescript>
<condition>#101 != ""</condition>
<font face="Courier New" bold="1" size="8" />
<field type="Stringa" width="23" id="101" pattern="1">
<prescript description="F3.101 PRESCRIPT">#THIS @ #102 !
CA_FORMAT_CONTO</prescript>
</field>
<field x="25" type="Stringa" width="50" id="102" pattern="1">
<prescript description="F3.102 PRESCRIPT">MESSAGE ISAMREAD,PCONANA,CODCONTO=#102,DESCR</prescript>
<prescript description="F3.101 PRESCRIPT">CA_FORMAT_CONTO</prescript>
</field>
<field x="25" type="Stringa" width="50" id="102" pattern="1" />
<field x="78" type="Valuta" align="right" width="13" id="103" pattern="1" hide_zero="1" text="###.###.###,@@">
<prescript description="F3.103 PRESCRIPT">103 DARE_AVERE</prescript>
</field>
@ -161,12 +161,9 @@ CA_FORMAT_CONTO</prescript>
<condition>#101 != ""</condition>
<font face="Courier New" bold="1" size="8" />
<field type="Stringa" width="23" id="101" pattern="1">
<prescript description="F4.101 PRESCRIPT">#THIS @ #102 !
CA_FORMAT_CONTO</prescript>
</field>
<field x="25" type="Stringa" width="50" id="102" pattern="1">
<prescript description="F4.102 PRESCRIPT">MESSAGE ISAMREAD,PCONANA,CODCONTO=#102,DESCR</prescript>
<prescript description="F4.101 PRESCRIPT">CA_FORMAT_CONTO</prescript>
</field>
<field x="25" type="Stringa" width="50" id="102" pattern="1" />
<field x="78" type="Valuta" align="right" width="13" id="103" pattern="1" hide_zero="1" text="###.###.###,@@">
<prescript description="F4.103 PRESCRIPT">103 DARE_AVERE</prescript>
</field>

View File

@ -460,13 +460,11 @@ void TPrint_rendiconto_ca_alternative_recordset::set_filter(const TPrint_rendico
aconto.put(PCONANA_CODCONTO, _aconto);
//solo i gr/co/sottoc completi interessano!!!
int contolen = 0;
const TMultilevel_code_info& info = ca_multilevel_code_info(LF_PCONANA);
for (int l = info.levels()-1; l >= 0; l--)
contolen += info.len(l);
const int min_contolen = info.total_len(-1);
TString filtro;
filtro << "LEN(CODCONTO)==" << contolen;
filtro << "STR(LEN(CODCONTO)>" << min_contolen << ')';
TCursor cur_pconana(&rel_pconana, filtro, 1, &daconto, &aconto);
const long pconana_items = cur_pconana.items();

View File

@ -3,6 +3,11 @@
#include <progind.h>
#include <urldefid.h>
#include <causali.h>
#include <pconti.h>
#include "cdc.h"
#include "fasi.h"
#include "movana.h"
#include "pconana.h"
#include "rmovana.h"
@ -11,69 +16,198 @@
#include "calib01.h"
#include "../cg/cglib01.h"
class TCode_generator
{
TRelation* _rel;
TCursor* _cur;
public:
TRecnotype items() const { return _cur->items(); }
const TString& code();
TCode_generator(int logicnum);
~TCode_generator();
};
const TString& TCode_generator::code()
{
const TRecnotype i = items();
if (i > 0)
{
*_cur = rand() % i;
const TRectype& curr = _rel->curr();
const int logicnum = curr.num();
switch (logicnum)
{
case LF_CAUSALI:
return curr.get(CAU_CODCAUS);
case LF_CDC:
return curr.get(CDC_CODCOSTO);
case LF_COMMESSE:
return curr.get("CODCMS");
case LF_FASI:
return curr.get(FASI_CODFASE);
case LF_PCON:
{
TString& tmp = get_tmp_string(12);
tmp.format("%03d%03d%06ld",
curr.get_int(PCN_GRUPPO), curr.get_int(PCN_CONTO), curr.get_long(PCN_SOTTOCONTO));
return tmp;
}
case LF_PCONANA:
return curr.get(PCONANA_CODCONTO);
default:
break;
}
}
return EMPTY_STRING;
}
TCode_generator::TCode_generator(int logicnum)
{
TWait_cursor hourglass;
TString filter;
if (logicnum <= 0)
{
TConfig_anal cfg;
const bool use_pdcc = cfg.get_bool("UsePdcc");
logicnum = use_pdcc ? LF_PCON : LF_PCONANA;
}
switch (logicnum)
{
case LF_CAUSALI:
filter = "MOVIND=\"X\"";
break;
case LF_PCON:
filter = "SOTTOCONTO!=''";
break;
case LF_PCONANA:
{
const TMultilevel_code_info& info = ca_multilevel_code_info(LF_PCONANA);
const int min_len = info.total_len(-1);
filter << "STR(NUM(LEN(CODCONTO))>" << min_len << ')';
}
break;
default:
break;
}
_rel = new TRelation(logicnum);
_cur = new TCursor(_rel, filter);
const TRecnotype conti = _cur->items();
_cur->freeze();
}
TCode_generator::~TCode_generator()
{
delete _cur;
delete _rel;
}
////////////////////////////////////////////////////////
// APPLICAZIONE
////////////////////////////////////////////////////////
class TRandom_ca : public TSkeleton_application
{
protected:
bool chiedi_quanti(int& mov, bool& ric);
void kill_bill();
void genera(int quanti);
void genera_riclass();
public:
void riclassify(const TString& conto);
virtual void main_loop();
};
bool TRandom_ca::chiedi_quanti(int& mov, bool& ric)
{
TMask mask("Movimenti casuali ma perfetti", 1, 60, 6);
TReal_field& add_number (short id, int page, const char* prompt, int x, int y, int dim, const char* flags = "", int ndec = 0);
mask.add_number(101, 0, "Numero di movimenti ", 1, 1, 4, "U");
mask.add_boolean(102, 0, "Genera riclassificazioni", 1, 2);
mask.add_static (DLG_NULL, 0, "@bAttenzione: verranno distrutti movimenti e saldi", 1, 3);
mask.add_button(DLG_OK, 0, "", -12, -1, 10, 2);
mask.add_button(DLG_QUIT, 0, "", -22, -1, 10, 2);
mask.set(101, 100);
const bool ok = mask.run() != K_QUIT;
if (ok)
{
mov = (mask.get_int(101)+1)/2;
ric = mask.get_bool(102);
}
return ok;
}
void TRandom_ca::kill_bill()
{
const int lnum[3] = { LF_MOVANA, LF_RMOVANA, LF_SALDANA };
for (int i = 0; i < 3; i++)
const int lnum[] = { LF_MOVANA, LF_RMOVANA, LF_SALDANA, 0 };
for (int i = 0; lnum[i]; i++)
{
TSystemisamfile f(lnum[i]);
f.zap();
}
}
void TRandom_ca::main_loop()
void TRandom_ca::riclassify(const TString& conto)
{
TMask mask("Movimenti casuali ma perfetti", 1, 60, 6);
TReal_field& add_number (short id, int page, const char* prompt, int x, int y, int dim, const char* flags = "", int ndec = 0);
mask.add_number(101, 0, "Numero di movimenti ", 1, 1, 4, "U");
mask.add_static (DLG_NULL, 0, "@bAttenzione: verranno distrutti movimenti e saldi", 1, 3);
mask.add_button(DLG_OK, 0, "", -12, -1, 10, 2);
mask.add_button(DLG_QUIT, 0, "", -22, -1, 10, 2);
mask.set(101, 100);
if (mask.run() == K_QUIT)
return;
kill_bill();
const TMultilevel_code_info& info = ca_multilevel_code_info(LF_PCONANA);
TString filter;
int len = 0;
for (int l = info.levels()-1; l >= 0; l--)
len += info.len(l);
filter << "LEN(CODCONTO)==" << len;
const int min_len = info.total_len(-1);
if (conto.len() > min_len)
{
TRecord_array ric(conto, LF_PANAPDC);
TRelation relconti(LF_PCONANA);
TCursor curconti(&relconti, filter);
const TRecnotype conti = curconti.items();
curconti.freeze();
TCode_generator conti(LF_PCON);
const int righe = rand() % 4 + 1;
for (int i = 1; i <= righe; i++)
{
TRectype& row = ric.row(i, true);
const TString& c = conti.code();
row.put(PCN_GRUPPO, c.mid(0, 3));
row.put(PCN_CONTO, c.mid(3, 3));
row.put(PCN_SOTTOCONTO, c.mid(6, 6));
}
ric.write();
}
}
TRelation relcommesse(LF_COMMESSE);
TCursor curcommesse(&relcommesse);
const TRecnotype commesse = curcommesse.items();
curcommesse.freeze();
static bool riclass_callback(const TRelation& rel, void* jolly)
{
TRandom_ca* myself = (TRandom_ca*)jolly;
const TString80 conto = rel.curr().get(PCONANA_CODCONTO);
myself->riclassify(conto);
return true;
}
TRelation relcaus(LF_CAUSALI);
TCursor curcaus(&relcaus, "MOVIND=\"X\"");
const TRecnotype causali = curcaus.items();
curcaus.freeze();
void TRandom_ca::genera_riclass()
{
{
TSystemisamfile f(LF_PANAPDC);
f.zap();
}
TRelation rel(LF_PCONANA);
TCursor cur(&rel);
cur.scan(riclass_callback, this, "Generazione riclassificazioni");
}
void TRandom_ca::genera(int quanti)
{
TEsercizi_contabili esc;
const int quanti = (mask.get_int(101)+1)/2;
TProgind pi(quanti, "Generazione in corso", FALSE, TRUE);
TCode_generator conti(0);
TCode_generator commesse(LF_COMMESSE);
TCode_generator fasi(LF_FASI);
TCode_generator costi(LF_CDC);
TCode_generator causali(LF_CAUSALI);
TLocalisamfile fmov(LF_MOVANA);
TProgind pi(quanti, "Generazione movimenti", FALSE, TRUE);
for (int m = 0; m < quanti; m++)
{
pi.addstatus(1);
@ -86,11 +220,7 @@ void TRandom_ca::main_loop()
mov.put(MOVANA_ANNOES, esc.date2esc(data));
mov.put(MOVANA_DESCR, "Movimento random preventivo");
mov.put(MOVANA_TIPOMOV, "P");
if (causali > 0)
{
curcaus = rand() % causali;
mov.put(MOVANA_CODCAUS, curcaus.curr().get("CODCAUS"));
}
mov.put(MOVANA_CODCAUS, causali.code());
const int rows = rand()%10+1;
TImporto tot;
@ -100,17 +230,11 @@ void TRandom_ca::main_loop()
TRectype& rmov = mov.new_row();
TString80 descr; descr.format("Riga casuale %d", i+1);
rmov.put(RMOVANA_DESCR, descr);
rmov.put(RMOVANA_CODCONTO, conti.code());
rmov.put(RMOVANA_CODCMS, commesse.code());
rmov.put(RMOVANA_CODFASE, fasi.code());
rmov.put(RMOVANA_CODCCOSTO, costi.code());
if (conti > 0)
{
curconti = rand() % conti;
rmov.put(RMOVANA_CODCONTO, curconti.curr().get(PCONANA_CODCONTO));
}
if (commesse > 0)
{
curcommesse = rand() % commesse;
rmov.put(RMOVANA_CODCMS, curcommesse.curr().get("CODCMS"));
}
const TImporto imp(i & 0x1 ? 'A' : 'D', real(10*(rand()%1000+1)));
rmov.put(RMOVANA_SEZIONE, imp.sezione());
rmov.put(RMOVANA_IMPORTO, imp.valore());
@ -121,7 +245,6 @@ void TRandom_ca::main_loop()
mov.put(MOVANA_SEZIONE, tot.sezione());
mov.put(MOVANA_TOTDOC, tot.valore());
TLocalisamfile fmov(LF_MOVANA);
mov.write(fmov);
// Consuntivo
@ -151,6 +274,22 @@ void TRandom_ca::main_loop()
}
}
void TRandom_ca::main_loop()
{
int quanti = 100;
bool ric = false;
if (chiedi_quanti(quanti, ric))
{
if (quanti > 0)
{
kill_bill();
genera(quanti);
}
if (ric)
genera_riclass();
}
}
int ca3900(int argc, char* argv[])
{
TRandom_ca a;

View File

@ -61,6 +61,8 @@ int TMultilevel_code_info::levels() const
const TString& TMultilevel_code_info::picture(int level) const
{
if (level < 0 || level >= levels())
return EMPTY_STRING;
return _picture.row(level);
}
@ -86,9 +88,22 @@ int TMultilevel_code_info::len(int level) const
{
return picture(level).len();
}
int TMultilevel_code_info::total_len(int level) const
{
const int max_lev = levels();
if (level < 0) // -1 = fino al penultimo
level = max_lev+level-1;
int l = 0;
for (int i = 0; i <= level && i < max_lev; i++)
l += picture(i).len();
return l;
}
const TString& TMultilevel_code_info::prompt(int level) const
{
if (level < 0 || level >= _prompt.items())
return EMPTY_STRING;
return _prompt.row(level);
}

View File

@ -35,6 +35,7 @@ protected:
public:
int levels() const;
int len(int level) const;
int total_len(int level) const;
const TString& picture(int level) const;
bool is_numeric_picture(int level) const;
bool is_required(int level) const;

View File

@ -4,7 +4,9 @@
#include "calib02.h"
#include "../cg/cglib01.h"
#include "../include/rdoc.h"
#include <rdoc.h>
#include <pconti.h>
#include "movana.h"
#include "pconana.h"
@ -15,81 +17,151 @@
// TPconana_recordset
///////////////////////////////////////////////////////////
const TVariant& TPconana_recordset::get(const char* column_name) const
const TVariant& TPconana_recordset::get(const char* field) const
{
if (strncmp(column_name, "SALDO:", 6) == 0)
const TFixed_string column_name(field);
if (*column_name == '#')
{
TString16 sub_field = column_name+6;
const char last = sub_field.right(1)[0];
int tipimov = 0;
switch (last)
if (strcmp(column_name, "#CMSCDC") == 0)
{
case 'C': tipimov = 1; sub_field.rtrim(1); break; // Consuntivo
case 'P':
case 'V': tipimov = 6; sub_field.rtrim(1); break; // Preventivo o variazaione preventivo
default : tipimov = _tipimov; break;
const TMultilevel_code_info& info = ca_multilevel_code_info(LF_FASI);
switch (info.parent())
{
case LF_CDC : return get_tmp_var() = _bill.costo();
case LF_COMMESSE: return get_tmp_var() = _bill.commessa();
default : return NULL_VARIANT;
}
}
if (strcmp(column_name, "#COSTO") == 0)
return get_tmp_var() = _bill.costo();
if (strcmp(column_name, "#COMMESSA") == 0)
return get_tmp_var() = _bill.commessa();
if (strcmp(column_name, "#FASE") == 0)
return get_tmp_var() = _bill.fase();
}
else
{
if (column_name.compare(PCONANA_CODCONTO, 8) == 0)
{
TString80 str;
if (_tipo == 'C')
{
const TBill b(relation()->curr());
str = b.string(0x8);
}
else
str = TISAM_recordset::get(PCONANA_CODCONTO).as_string();
if (column_name[8] == ':')
{
const TMultilevel_code_info& info = ca_multilevel_code_info(_tipo == 'C' ? LF_PCON : LF_PCONANA);
const int level = column_name[9] - '1';
str.cut(info.total_len(level));
}
return get_tmp_var() = str;
}
if (column_name.compare(PCONANA_DESCR, 5) == 0)
{
TString80 str;
if (_tipo == 'C')
{
TBill b(relation()->curr());
if (column_name[5] == ':')
{
if (column_name[6] == '1')
b.set(b.gruppo(), 0, 0); else
if (column_name[6] == '2')
b.set(b.gruppo(), b.conto(), 0);
}
str = b.descrizione();
}
else
{
if (column_name[5] == ':')
{
const TMultilevel_code_info& info = ca_multilevel_code_info(LF_PCONANA);
const int level = column_name[6] - '1';
str = TISAM_recordset::get(PCONANA_CODCONTO).as_string();
str.cut(info.total_len(level));
str = cache().get(LF_PCONANA, str, PCONANA_DESCR);
}
else
str = TISAM_recordset::get(PCONANA_DESCR).as_string();
}
return get_tmp_var() = str;
}
((TAnal_bill&)_bill).set_conto(relation()->curr().get(PCONANA_CODCONTO));
const TSaldanal& s = ca_saldo(_bill, _dal, _al, tipimov);
if (column_name.compare("SALDO:", 6) == 0)
{
TString16 sub_field = column_name+6;
const char last = sub_field.right(1)[0];
int tipimov = 0;
switch (last)
{
case 'C': tipimov = _saldanal_consuntivo; sub_field.rtrim(1); break; // Consuntivo
case 'P':
case 'V': tipimov = _saldanal_preventivi; sub_field.rtrim(1); break; // Preventivo o variazione preventivo
default : tipimov = _tipimov; break;
}
TVariant& var = get_tmp_var();
if (strcmp(sub_field, "INI_DARE") == 0)
{
var = s._ini.sezione() == 'D' ? s._ini.valore() : ZERO;
} else
if (strcmp(sub_field, "INI_AVERE") == 0)
{
var = s._ini.sezione() == 'A' ? s._ini.valore() : ZERO;
} else
if (strcmp(sub_field, "MOV_DARE") == 0)
{
var = s._dare.valore();
} else
if (strcmp(sub_field, "MOV_AVERE") == 0)
{
var = s._avere.valore();
} else
if (strcmp(sub_field, "FIN_DARE") == 0)
{
var = s._fin.sezione() == 'D' ? s._fin.valore() : ZERO;
} else
if (strcmp(sub_field, "FIN_AVERE") == 0)
{
var = s._fin.sezione() == 'A' ? s._fin.valore() : ZERO;
}
return var;
}
if (strcmp(column_name, "#CMSCDC") == 0)
{
const TMultilevel_code_info& info = ca_multilevel_code_info(LF_FASI);
switch (info.parent())
{
case LF_CDC : column_name = "#COSTO"; break;
case LF_COMMESSE: column_name = "#COMMESSA"; break;
default : return NULL_VARIANT;
((TAnal_bill&)_bill).set_conto(get(PCONANA_CODCONTO).as_string());
const TSaldanal& s = ca_saldo(_bill, _dal, _al, tipimov);
TVariant& var = get_tmp_var();
if (strcmp(sub_field, "INI_DARE") == 0)
{
var = s._ini.sezione() == 'D' ? s._ini.valore() : ZERO;
} else
if (strcmp(sub_field, "INI_AVERE") == 0)
{
var = s._ini.sezione() == 'A' ? s._ini.valore() : ZERO;
} else
if (strcmp(sub_field, "MOV_DARE") == 0)
{
var = s._dare.valore();
} else
if (strcmp(sub_field, "MOV_AVERE") == 0)
{
var = s._avere.valore();
} else
if (strcmp(sub_field, "FIN_DARE") == 0)
{
var = s._fin.sezione() == 'D' ? s._fin.valore() : ZERO;
} else
if (strcmp(sub_field, "FIN_AVERE") == 0)
{
var = s._fin.sezione() == 'A' ? s._fin.valore() : ZERO;
}
return var;
}
}
if (strcmp(column_name, "#COSTO") == 0)
return get_tmp_var() = _bill.costo();
if (strcmp(column_name, "#COMMESSA") == 0)
return get_tmp_var() = _bill.commessa();
if (strcmp(column_name, "#FASE") == 0)
return get_tmp_var() = _bill.fase();
return TISAM_recordset::get(column_name);
}
bool TPconana_recordset::valid_record(const TRelation& rel) const
{
TString80 conto;
if (_tipo == 'C')
{
const TBill b(rel.curr());
if (b.sottoconto() <= 0 || !b.is_analitico())
return false;
conto = b.string(0x8);
}
else
{
conto = rel.curr().get(PCONANA_CODCONTO);
if (conto.len() <= _conto_minlen)
return false;
}
if (_movimentati || _nonnulli)
{
const TString& conto = rel.curr().get(PCONANA_CODCONTO);
((TAnal_bill&)_bill).set_conto(conto);
const TSaldanal& s = ca_saldo(_bill, _dal, _al, _tipimov);
if (_movimentati && !s._movimentato)
return false;
if (_nonnulli && s._ini.is_zero() && s._dare.is_zero() && s._avere.is_zero())
if (_nonnulli && s._fin.is_zero())
return false;
}
return true;
@ -102,33 +174,57 @@ bool TPconana_recordset::pianoconti_filter(const TRelation* rel)
void TPconana_recordset::set_custom_filter(TCursor& cursor) const
{
TString filter;
filter << "LEN(" << PCONANA_CODCONTO << ")==" << _contolen;
cursor.setfilter(filter);
TRectype darec(LF_PCONANA), arec(LF_PCONANA);
darec.put(PCONANA_CODCONTO, _da_conto);
arec.put(PCONANA_CODCONTO, _a_conto);
cursor.setregion(darec, arec);
if (_movimentati || _nonnulli)
if (_tipo == 'C')
{
_current_recset = this;
cursor.set_filterfunction(pianoconti_filter);
TRectype darec(LF_PCON), arec(LF_PCON);
darec.put(PCN_GRUPPO, _da_conto.mid(0,3));
darec.put(PCN_CONTO, _da_conto.mid(3,3));
darec.put(PCN_SOTTOCONTO, _da_conto.mid(6,6));
arec.put(PCN_GRUPPO, _a_conto.mid(0,3));
arec.put(PCN_CONTO, _a_conto.mid(3,3));
arec.put(PCN_SOTTOCONTO, _a_conto.mid(6,6));
cursor.setregion(darec, arec);
}
else
cursor.set_filterfunction(NULL);
{
TRectype darec(LF_PCONANA), arec(LF_PCONANA);
darec.put(PCONANA_CODCONTO, _da_conto);
arec.put(PCONANA_CODCONTO, _a_conto);
cursor.setregion(darec, arec);
}
_current_recset = this;
cursor.set_filterfunction(pianoconti_filter);
}
void TPconana_recordset::set_filter(const char* da_conto, const char* a_conto,
void TPconana_recordset::set_tipo(char tipo)
{
if (tipo != 'A' && tipo != 'C')
{
TConfig_anal cfg;
tipo = cfg.get_bool("UsePdcc") ? 'C' : 'A';
}
_tipo = tipo;
if (_tipo == 'A')
{
set("USE PCONANA");
const TMultilevel_code_info& info = ca_multilevel_code_info(LF_PCONANA);
_conto_minlen = info.total_len(-1); // Lunghezza fino al penultimo livello
}
else
{
set("USE PCON");
_conto_minlen = 6; // Gruppo(3)+Conto(3)
}
}
void TPconana_recordset::set_filter(char tipo, const char* da_conto, const char* a_conto,
const char* costo, const char* commessa, const char* fase,
const TDate& dal, const TDate& al,
word tipimov, bool movimentati, bool nonnulli)
{
_contolen = 0;
const TMultilevel_code_info& info = ca_multilevel_code_info(LF_PCONANA);
for (int l = info.levels()-1; l >= 0; l--)
_contolen += info.len(l);
set_tipo(tipo);
_da_conto = da_conto;
_a_conto = a_conto;
@ -146,50 +242,15 @@ void TPconana_recordset::set_filter(const char* da_conto, const char* a_conto,
_bill.set_fase(fase);
}
TPconana_recordset::TPconana_recordset() : TISAM_recordset("USE PCONANA")
{ }
TPconana_recordset::TPconana_recordset(char tipo) : TISAM_recordset("USE PCONANA")
{
set_tipo(tipo);
}
///////////////////////////////////////////////////////////
// TAnal_report
///////////////////////////////////////////////////////////
bool TAnal_report::get_usr_val(const TString& name, TVariant& var) const
{
// CODCONTO:1, CODCMS:3, FASCMS:2, ecc...
const int namelen = name.len();
if (namelen >= 6 && name[namelen-2] == ':')
{
int logicnum = 0;
if (name.starts_with("CODCONTO:"))
logicnum = LF_PCONANA; else
if (name.starts_with("CODCMS:"))
logicnum = LF_COMMESSE; else
if (name.starts_with("CODCOSTO:"))
logicnum = LF_CDC; else
if (name.starts_with("FASCMS:"))
logicnum = LF_FASI;
if (logicnum > 0)
{
const TMultilevel_code_info& mci = ca_multilevel_code_info(logicnum);
const int level = name[namelen-1]-'1';
if (level < mci.levels())
{
TString16 fldname = name; fldname.cut(namelen-2);
TFieldref field = mci.fieldref(level);
field.set_name(fldname);
field.set_from(0);
fldname.cut(0) << field; // Trasformo il TFieldref in stringa!
get_record_field(fldname, var);
}
else
var.set_null();
return true;
}
}
return TReport::get_usr_val(name, var);
}
size_t TAnal_report::get_usr_words(TString_array& words) const
{
TReport::get_usr_words(words);
@ -223,19 +284,9 @@ void TAnal_report::msg_format(int logicnum, TVariant_stack& stack)
if (separator.not_empty())
{
const TMultilevel_code_info& mci = ca_multilevel_code_info(logicnum);
TString str_out;
for (int i = 0; i < mci.levels(); i++)
{
const TFieldref& fld = mci.fieldref(i);
const TString& str = str_in.sub(fld.from(), fld.to());
if (str.not_empty())
{
if (i > 0) str_out << separator;
str_out << str;
}
else
break;
}
TString80 str_out = str_in;
for (int i = mci.levels()-2; i >= 0; i--)
str_out.insert(separator, mci.total_len(i));
curr_field()->set(str_out);
}
}
@ -251,7 +302,16 @@ void TAnal_report::msg_format_fase (TVariant_stack& stack)
{ msg_format(LF_FASI, stack); }
void TAnal_report::msg_format_conto (TVariant_stack& stack)
{ msg_format(LF_PCONANA, stack); }
{
// Cerca di determinare se si usa il piano contabile o analitico
const TFixed_string gruppo(PCN_GRUPPO);
TVariant var;
get_record_field(gruppo, var);
if (var.is_null())
msg_format(LF_PCONANA, stack);
else
msg_format(LF_PCON, stack);
}
void TAnal_report::msg_format_commessa_costo(TVariant_stack& stack)
{
@ -368,10 +428,7 @@ bool TAnal_bill::get(const TRectype& rec)
return ok;
}
TAnal_bill::TAnal_bill()
{ }
TAnal_bill::TAnal_bill(const TAnal_bill& b)
void TAnal_bill::copy(const TAnal_bill& b)
{
set_conto(b.conto());
set_costo(b.costo());
@ -379,6 +436,18 @@ TAnal_bill::TAnal_bill(const TAnal_bill& b)
set_fase(b.fase());
}
const TAnal_bill& TAnal_bill::operator=(const TAnal_bill& b)
{
copy(b);
return *this;
}
TAnal_bill::TAnal_bill()
{ }
TAnal_bill::TAnal_bill(const TAnal_bill& b)
{ copy(b); }
TAnal_bill::TAnal_bill(const char* conto, const char* costo, const char* commessa, const char* fase)
{
set_conto(conto);
@ -392,90 +461,209 @@ TAnal_bill::TAnal_bill(const TRectype& rec)
get(rec);
}
///////////////////////////////////////////////////////////
// TAnal_balance
///////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
// TRiclassify_cache
////////////////////////////////////////////////////////
class TAnal_balance : public TObject
class TRiclassify_cache : public TCache
{
int _conto_min;
protected:
virtual TObject* key2obj(const char* key);
void extract(const char* conto, TString_array& conti) const;
public:
TImporto saldo_fine_anno(const TAnal_bill& bill, int annofin, word tipo) const;
bool saldo_movimenti(const TAnal_bill& bill, const TDate& dal, const TDate& al, word tipo, TSaldanal& s) const;
bool saldi(const TAnal_bill& bill, const TDate& dal, const TDate& al, word tipo, TSaldanal& s) const;
const TString_array& conti(const TString& conto);
TRiclassify_cache();
};
TImporto TAnal_balance::saldo_fine_anno(const TAnal_bill& b, int anno, word tipo) const
void TRiclassify_cache::extract(const char* conto, TString_array& conti) const
{
TImporto saldo;
if (anno > 0)
TRecord_array table(conto, LF_PANAPDC);
for (int r = table.last_row(); r > 0; r = table.pred_row(r))
{
TString query, select;
if (b.costo().not_empty())
select << "(CODCOSTO=='" << b.costo() << "')";
if (b.commessa().not_empty())
{
if (select.not_empty()) select << "&&";
select << "(CODCMS=='" << b.commessa() << "')";
}
if (b.fase().not_empty())
{
if (select.not_empty()) select << "&&";
select << "(FASCMS=='" << b.fase() << "')";
}
if (b.conto().not_empty())
{
if (select.not_empty()) select << "&&";
select << "(CONTO=='" << b.conto() << "')";
}
query << "USE SALDANA";
if (select.not_empty())
query << " SELECT " << select;
if (anno > 0)
query << "\nTO ANNO=" << anno << '\n';
TISAM_recordset saldini(query);
for (int i = 0; i < saldini.items(); i++)
{
if (tipo & 1)
{
const char sez = saldini.get(SALDANA_SEZIONE).as_string()[0];
const real imp = saldini.get(SALDANA_SALDO).as_real();
saldo += TImporto(sez, imp);
}
if (tipo & 2)
{
const char sez = saldini.get(SALDANA_SEZIONEP).as_string()[0];
const real imp = saldini.get(SALDANA_SALDOP).as_real();
saldo += TImporto(sez, imp);
}
if (tipo & 4)
{
const char sez = saldini.get(SALDANA_SEZIONEV).as_string()[0];
const real imp = saldini.get(SALDANA_SALDOV).as_real();
saldo += TImporto(sez, imp);
}
}
saldo.normalize();
const TRectype& row = table.row(r);
const TBill b(row);
conti.add(b.string(0x8));
}
return saldo;
}
bool TAnal_balance::saldo_movimenti(const TAnal_bill& b,
const TDate& dal, const TDate& al, word tipo,
TSaldanal& s) const
TObject* TRiclassify_cache::key2obj(const char* key)
{
TString_array* k = new TString_array;
if (key && int(strlen(key)) > _conto_min)
{
extract(key, *k);
}
else
{
TString query = "USE PCONANA";
if (key && *key)
{
query << "\nFROM CODCONTO=" << key;
query << "\nTO CODCONTO=" << key;
}
TISAM_recordset pconana(query);
for (TRecnotype i = 0; pconana.move_to(i); i++)
{
const TString& conto = pconana.get(PCONANA_CODCONTO).as_string();
extract(conto, *k);
}
}
return k;
}
const TString_array& TRiclassify_cache::conti(const TString& conto)
{
return *(const TString_array*)objptr(conto);
}
TRiclassify_cache::TRiclassify_cache() : TCache(7)
{
const TMultilevel_code_info& info = ca_multilevel_code_info(LF_PCONANA);
_conto_min = info.total_len(-1); // Lunghezza conti fino al penultimo livello
}
////////////////////////////////////////////////////////
// TSaldi_cache
////////////////////////////////////////////////////////
class TSaldi_cache : private TCache
{
TEsercizi_contabili _esc;
TRiclassify_cache _riclass;
protected:
virtual TObject* key2obj(const char* key);
bool int_saldo_annuale(const TAnal_bill& bill, int annoini, int annofin, word tipo, TImporto& dare, TImporto& avere) const;
bool int_saldo_movimenti(const TAnal_bill& bill, const TDate& dal, const TDate& al, word tipo, TSaldanal& s) const;
protected:
bool saldo_annuale(const TAnal_bill& bill, int annoini, int annofin, word tipo, TImporto& dare, TImporto& avere);
bool saldo_movimenti(const TAnal_bill& bill, const TDate& dal, const TDate& al, word tipo, TSaldanal& s);
bool saldi(const TAnal_bill& bill, const TDate& dal, const TDate& al, word tipo, TSaldanal& s);
public:
const TSaldanal& saldo(const TAnal_bill& bill, const TDate& dal, const TDate& al, word tipi = 0x1);
TSaldi_cache();
};
// Calcolo saldo annuale di un conto reale NON riclassificato
bool TSaldi_cache::int_saldo_annuale(const TAnal_bill& b, int da_anno, int ad_anno, word tipo,
TImporto& dare, TImporto& avere) const
{
CHECKD(ad_anno > 0, "Anno saldo finale errato: ", ad_anno);
bool movim = false;
TString query, select;
if (b.costo().not_empty())
select << "(COSTO=='" << b.costo() << "')";
if (b.commessa().not_empty())
{
if (select.not_empty()) select << "&&";
select << "(COMMESSA=='" << b.commessa() << "')";
}
if (b.fase().not_empty())
{
if (select.not_empty()) select << "&&";
select << "(FASE=='" << b.fase() << "')";
}
if (b.conto().not_empty() && da_anno != ad_anno)
{
if (select.not_empty()) select << "&&";
select << "(CONTO[1," << b.conto().len() << "]=='" << b.conto() << "')";
}
query << "USE SALDANA";
if (select.not_empty())
query << " SELECT " << select;
if (da_anno > 0)
{
query << "\nFROM ANNO=" << da_anno;
if (b.conto().not_empty())
query << " CONTO='" << b.conto() << '\'';
query << '\n';
}
query << "\nTO ANNO=" << ad_anno;
if (b.conto().not_empty())
query << " CONTO='" << b.conto() << '\'';
query << '\n';
TISAM_recordset saldini(query);
for (TRecnotype i = 0; saldini.move_to(i); i++)
{
char sez = ' ';
real imp;
if (tipo & _saldanal_consuntivo)
{
sez = saldini.get(SALDANA_SEZIONE).as_string()[0];
imp = saldini.get(SALDANA_SALDO).as_real();
}
if (tipo & _saldanal_preventivo)
{
sez = saldini.get(SALDANA_SEZIONEP).as_string()[0];
imp = saldini.get(SALDANA_SALDOP).as_real();
}
if (tipo & _saldanal_variazione)
{
sez = saldini.get(SALDANA_SEZIONEV).as_string()[0];
imp = saldini.get(SALDANA_SALDOV).as_real();
}
if (sez > ' ')
{
if (sez == 'D')
dare += TImporto('D', imp);
else
avere += TImporto('A', imp);
movim = true;
}
}
return movim;
}
bool TSaldi_cache::saldo_annuale(const TAnal_bill& b, int da_anno, int ad_anno, word tipo,
TImporto& dare, TImporto& avere)
{
bool movim = false;
if (ad_anno > 0)
{
if (tipo & _saldanal_riclassify)
{
// Legge tabella di riclassificazione
const TString_array& table = _riclass.conti(b.conto());
if (!table.empty())
{
TAnal_bill c(b); // Conto riclassificato
FOR_EACH_ARRAY_ROW(table, i, row)
{
c.set_conto(*row);
movim |= int_saldo_annuale(c, da_anno, ad_anno, tipo, dare, avere);
}
}
}
else
movim = int_saldo_annuale(b, da_anno, ad_anno, tipo, dare, avere);
}
return movim;
}
bool TSaldi_cache::int_saldo_movimenti(const TAnal_bill& b,
const TDate& dal, const TDate& al,
word tipo, TSaldanal& s) const
{
TDate dataini;
if (dal.ok())
{
TEsercizi_contabili esc;
const int annoprec = esc.date2prevesc(dal);
const int annoprec = _esc.date2prevesc(dal);
if (annoprec > 0)
dataini = esc[annoprec].fine()+1L;
dataini = _esc[annoprec].fine()+1L;
}
TString query, select;
@ -504,7 +692,9 @@ bool TAnal_balance::saldo_movimenti(const TAnal_bill& b,
query << "SELECT " << select << "\n";
// Faccio la join solo se mi serve il tipo movimento in testata
if (tipo != 0 && tipo != 7)
const bool filtra_tipo = (tipo & _saldanal_qualsiasi) != 0 &&
(tipo & _saldanal_qualsiasi) != _saldanal_qualsiasi;
if (filtra_tipo)
query << "JOIN MOVANA INTO NUMREG==NUMREG\n";
query << "FROM CODCONTO=" << b.conto();
@ -519,22 +709,19 @@ bool TAnal_balance::saldo_movimenti(const TAnal_bill& b,
TISAM_recordset rmovana(query);
s._movimentato = false;
for (int i = 0; i < rmovana.items(); i++)
for (TRecnotype i = 0; rmovana.move_to(i); i++)
{
rmovana.move_to(i);
// Controllo il tipo movimento solo se necessario
if (tipo != 0 && tipo != 7)
if (filtra_tipo)
{
const char tipomov = rmovana.get("107.TIPOMOV").as_string()[0];
int ntipomov = 0;
if (tipomov == 'P')
ntipomov = 2; else
ntipomov = _saldanal_preventivo; else
if (tipomov == 'V')
ntipomov = 4;
ntipomov = _saldanal_variazione;
else
ntipomov = 1;
ntipomov = _saldanal_consuntivo;
if ((ntipomov & tipo) == 0)
continue;
}
@ -555,40 +742,69 @@ bool TAnal_balance::saldo_movimenti(const TAnal_bill& b,
s._ini += imp;
}
}
return s._movimentato;
}
bool TSaldi_cache::saldo_movimenti(const TAnal_bill& b,
const TDate& dal, const TDate& al,
word tipo, TSaldanal& s)
{
bool movim = false;
if (tipo & _saldanal_riclassify)
{
// Legge tabella di riclassificazione
const TString_array& table = _riclass.conti(b.conto());
if (!table.empty())
{
TAnal_bill c(b); // Conto riclassificato
FOR_EACH_ARRAY_ROW(table, i, row)
{
c.set_conto(*row);
movim |= int_saldo_movimenti(c, dal, al, tipo, s);
}
}
}
else
movim = int_saldo_movimenti(b, dal, al, tipo, s);
return movim;
}
bool TSaldi_cache::saldi(const TAnal_bill& bill,
const TDate& dal, const TDate& al, word tipo,
TSaldanal& s)
{
// Calcolo i saldi fino all'anno scorso.
// In assemza di data iniziale mi torna 0
const int anno_prec = _esc.date2prevesc(dal);
if (anno_prec > 0)
{
TImporto dare, avere;
saldo_annuale(bill, 0, anno_prec, tipo, dare, avere);
s._ini = dare;
s._ini += avere;
}
if (tipo & _saldanal_ultima_imm)
{
// Calcolo i saldi di quest'anno
// In assemza di data iniziale somma tutti gli anni (fino al 9999)
const int anno_ini = _esc.date2esc(dal);
const int anno_fin = anno_ini > 0 ? anno_ini : 9999;
s._movimentato = saldo_annuale(bill, anno_ini, anno_fin, tipo, s._dare, s._avere);
}
else
{
saldo_movimenti(bill, dal, al, tipo, s);
}
s._ini.normalize();
s._fin = s._ini;
s._fin += s._dare;
s._fin += s._avere;
s._fin.normalize();
return s._movimentato;
}
bool TAnal_balance::saldi(const TAnal_bill& bill,
const TDate& dal, const TDate& al, word tipo,
TSaldanal& s) const
{
TEsercizi_contabili esc;
const int annoprec = esc.date2prevesc(dal);
s._ini = saldo_fine_anno(bill, annoprec, tipo);
return saldo_movimenti(bill, dal, al, tipo, s);
}
////////////////////////////////////////////////////////
// TSaldi_cache
////////////////////////////////////////////////////////
class TSaldi_cache : private TCache
{
TAnal_balance _bal;
protected:
virtual TObject* key2obj(const char* key);
public:
const TSaldanal& saldo(const TAnal_bill& bill, const TDate& dal, const TDate& al, word tipi = 0x1);
TSaldi_cache() : TCache(3883) { }
};
TObject* TSaldi_cache::key2obj(const char* key)
{
TSaldanal* s = new TSaldanal;
@ -598,7 +814,7 @@ TObject* TSaldi_cache::key2obj(const char* key)
const TDate dal = tok.get(4); // Le get precedenti avvengono in ordine inverso!
const TDate al = tok.get();
const int tipo = tok.get_int();
s->_movimentato = _bal.saldi(bill, dal, al, tipo, *s);
s->_movimentato = saldi(bill, dal, al, tipo, *s);
return s;
}
@ -615,6 +831,10 @@ const TSaldanal& TSaldi_cache::saldo(const TAnal_bill& bill, const TDate& dal, c
return *(const TSaldanal*)objptr(key);
}
TSaldi_cache::TSaldi_cache() : TCache(3881) // Numero primo
{ }
const TSaldanal& ca_saldo(const TAnal_bill& bill, const TDate& dal, const TDate& al, word tipi)
{
static TSaldi_cache* cache = NULL;

View File

@ -14,6 +14,9 @@ class TAnal_bill : public TSortable
{
TString _conto, _costo, _commessa, _fase;
protected:
void copy(const TAnal_bill& bill);
public:
virtual int compare(const TSortable& s) const;
bool match(const TAnal_bill& b) const;
@ -32,6 +35,8 @@ public:
bool get(const TRectype& rec);
void reset();
const TAnal_bill& operator=(const TAnal_bill& bill);
TAnal_bill();
TAnal_bill(const TAnal_bill& bill);
TAnal_bill(const char* conto, const char* costo, const char* commessa, const char* fase);
@ -42,7 +47,13 @@ public:
// TAnal_balance
///////////////////////////////////////////////////////////
// Tipi di saldo: 1 = Normale; 2 = Preventivo; 4 = Variazione preventivo; 7 = Tutti
#define _saldanal_consuntivo 0x1
#define _saldanal_preventivo 0x2
#define _saldanal_variazione 0x4
#define _saldanal_preventivi 0x6
#define _saldanal_qualsiasi 0x7
#define _saldanal_ultima_imm 0x8
#define _saldanal_riclassify 0x10
struct TSaldanal : public TObject
{
@ -50,7 +61,7 @@ struct TSaldanal : public TObject
bool _movimentato;
};
const TSaldanal& ca_saldo(const TAnal_bill& bill, const TDate& dal, const TDate& al, word tipi = 1);
const TSaldanal& ca_saldo(const TAnal_bill& bill, const TDate& dal, const TDate& al, word tipi = _saldanal_consuntivo);
////////////////////////////////////////////////////////
// TPconana_recordset
@ -58,9 +69,10 @@ const TSaldanal& ca_saldo(const TAnal_bill& bill, const TDate& dal, const TDate&
class TPconana_recordset : public TISAM_recordset
{
char _tipo;
word _tipimov;
TString _da_conto, _a_conto;
int _contolen;
int _conto_minlen;
TAnal_bill _bill;
TDate _dal, _al;
bool _movimentati, _nonnulli;
@ -74,12 +86,12 @@ protected:
public:
virtual const TVariant& get(const char* column_name) const;
void set_filter(const char* da_conto, const char* a_conto,
void set_tipo(char tipo);
void set_filter(char tipo, const char* da_conto, const char* a_conto,
const char* costo, const char* commessa, const char* fase,
const TDate& dal, const TDate& al,
word tipimov, bool movimentati, bool nonnulli);
TPconana_recordset();
TPconana_recordset(char tipo = ' ');
};
///////////////////////////////////////////////////////////
@ -91,7 +103,6 @@ class TAnal_report : public TReport
unsigned int _first_msg;
protected: // protected is safer
virtual bool get_usr_val(const TString& name, TVariant& var) const;
virtual size_t get_usr_words(TString_array& words) const;
virtual bool execute_usr_word(unsigned int opcode, TVariant_stack& stack);
virtual bool use_mask() { return false;}

View File

@ -12,4 +12,4 @@ SALDOP|4|18|3|Saldo (Preventivo)
SEZIONEV|7|1|0|Sezione (Variazione preventivo)
SALDOV|4|18|3|Saldo (Variazione preventivo)
1
ANNO+COSTO+COMMESSA+FASE+CONTO|
ANNO+CONTO+COSTO+COMMESSA+FASE|

View File

@ -1,9 +1,10 @@
#ifndef __PCONANA_H
#define __PCONANA_H
#define PCONANA_CODCONTO "CODCONTO"
#define PCONANA_DESCR "DESCR"
#define PCONANA_SEZSALDI "SEZSALDI"
#define PCONANA_SOSPESO "SOSPESO"
#define PCONANA_CODCONTO "CODCONTO"
#define PCONANA_DESCR "DESCR"
#define PCONANA_SEZSALDI "SEZSALDI"
#define PCONANA_SOSPESO "SOSPESO"
#define PCONANA_INDBIL "INDBIL"
#endif