campo-sirio/ca/ca3300.cpp
luca 67df99e22f Patch level :10.0 530
Files correlati     :
Ricompilazione Demo : [ ]
Commento            :
0001504: bilancio a sezioni contrapposte
Descrizione  sulla stampa del bilancio a sezioni contrapposte delle commesse:

l'esposizione dovrà partire dal conto economico, la dicitura bilancio dovrà essere sostituita con conto economico o situazione conto economico;
per quello che riguarda gli eventuali conti non patrimoniali la sezione dovrà chiamarsi riepilogo conti patrimoniali, dovrà contenere dei totali di sezione ed eventualmente un delta risultante dalla somma algebrica di attività e passività.


git-svn-id: svn://10.65.10.50/trunk@19645 c028cbd2-c16b-5b4b-a496-9718f37d4682
2009-11-18 09:54:04 +00:00

1071 lines
29 KiB
C++
Executable File

#include "ca3.h"
#include "calib01.h"
#include "calib02.h"
#include <execp.h>
#include <progind.h>
#include <reprint.h>
#include <pconti.h>
#include "movana.h"
#include "pconana.h"
#include "rmovana.h"
#include "../cg/cglib01.h"
#include "ca3300.h"
////////////////////////////////////////////////////////
// MASCHERA
////////////////////////////////////////////////////////
class TPrint_bilancio_ca_mask : public TAutomask
{
protected:
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
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:
TPrint_bilancio_ca_mask();
virtual ~TPrint_bilancio_ca_mask() {}
};
const TString& TPrint_bilancio_ca_mask::get_report_class() const
{
TString& lib = get_tmp_string();
lib = "ca3300";
const char bil = get(F_BILANCIO)[0]; // Verifica o sezioni Contrapposte
const char stp = get(F_TIPOSTAMPA)[0]; // Raffronto o No?
if (bil == 'V')
lib << (stp == 'R' ? 'a' : 'b'); // Verifica
else
lib << (stp == 'R' ? 'c' : 'd'); // Sezioni contrapposte
return lib;
}
bool TPrint_bilancio_ca_mask::test_compatible_report()
{
const TString& cls = get_report_class();
const TString& name = get(F_REPORT);
bool ok = name.not_empty();
if (ok && name != cls)
{
TReport rep;
ok = rep.load(name);
if (ok)
{
const TString& classe = rep.get_class();
ok = classe == cls;
}
}
if (!ok)
{
set(F_REPORT, cls);
TFilename path = cls;
path.ext("rep");
ok = path.custom_path();
}
return ok;
}
bool TPrint_bilancio_ca_mask::esistono_riclassificazioni() const
{
TLocalisamfile ric(LF_PANAPDC);
return ric.first() == NOERR;
}
bool TPrint_bilancio_ca_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
switch (o.dlg())
{
case F_ANNO:
case F_BILANCIO:
case F_STAMPA:
if (e == fe_modify || (e == fe_init && o.dlg() == F_ANNO))
{
test_compatible_report();
bool enable_from = false, enable_to = false;
if (get_int(F_STAMPA) == 1) // Stampa per data limite
{
enable_from = get(F_BILANCIO) == "V"; // Bilancio di verifica
enable_to = true;
}
if (!enable_from || !enable_to) // Cerco di proporre le date giuste se possibile
{
const int anno = get_int(F_ANNO);
if (anno > 0)
{
TEsercizi_contabili esc;
TDate dal, al;
esc.code2range(anno, dal, al);
if (!enable_from || o.dlg() == F_ANNO)
set(F_DATADA, dal);
if (!enable_to || o.dlg() == F_ANNO)
set(F_DATAA, al);
}
}
enable(F_DATADA, enable_from);
enable(F_DATAA, enable_to);
}
break;
case F_DATADA:
case F_DATAA:
if (e == fe_close)
{
const int anno = get_int(F_ANNO);
if (anno > 0)
{
TEsercizi_contabili esc;
TDate dal, al;
esc.code2range(anno, dal, al);
if (o.empty())
o.set(o.dlg() == F_DATADA ? dal : al);
else
{
const TDate d = o.get();
if (d < dal || d > al)
return error_box(FR("La data deve appartenere all'esercizio %d"), anno);
}
}
}
break;
case F_REPORT:
if (e == fe_button)
{
const TString8 lib = get_report_class();
TFilename path = o.get();
if (select_custom_file(path, "rep", lib))
{
path = path.name();
path.ext("");
o.set(path);
}
} else
if (e == fe_close)
{
if (!test_compatible_report())
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;
}
return true;
}
int TPrint_bilancio_ca_mask::create_sheet_fields(int lf, int& y, short& dlg, bool required)
{
TSheet_field& sf = sfield(F_RIGHE);
TMask& sm = sf.sheet_mask();
const int h = ca_create_fields(sm, 0, lf, 1, y, dlg, dlg+50);
for (int i = 0; i < h; i++)
{
TEdit_field& fld = sm.efield(dlg+i);
int logic = lf;
if (logic == LF_FASI)
{
const TMultilevel_code_info& fasinfo = ca_multilevel_code_info(LF_FASI);
if (fasinfo.parent() != 0)
{
const TMultilevel_code_info& parinfo = ca_multilevel_code_info(fasinfo.parent());
if (i < parinfo.levels())
logic = fasinfo.parent();
}
}
const char* fieldname = NULL;
switch(logic)
{
case LF_CDC : fieldname = RMOVANA_CODCCOSTO; break;
case LF_COMMESSE: fieldname = RMOVANA_CODCMS; break;
case LF_FASI : fieldname = RMOVANA_CODFASE; break;
default : fieldname = RMOVANA_CODCONTO; break;
}
TFieldref* f = (TFieldref*)fld.field();
f->set_name(fieldname);
fld.check_type(required ? CHECK_REQUIRED : CHECK_NORMAL);
TEdit_field& dfld = sm.efield(dlg+50+i);
dfld.set_field(EMPTY_STRING); // Toglie campi che fan saltare gli output!
}
y += h+1;
dlg += h;
return h;
}
void TPrint_bilancio_ca_mask::create_sheet()
{
TSheet_field& sf = sfield(F_RIGHE);
TMask& sm = sf.sheet_mask();
sm.hide(-1);
const TMultilevel_code_info& fasinfo = ca_multilevel_code_info(LF_FASI);
TConfig& ini = ca_config();
const bool fsc_req = ini.get_bool("FscRequired");
int y = 1;
short dlg = S_CDC1 + 100; // id del primo campo da generare
for (int i = 0; i < 2; i++)
{
const TString& level = ini.get("Level", NULL, i+1); // Legge il livello 1 o 2
if (level == "CDC") // Crea centro di costo
{
if (fasinfo.parent() == LF_CDC)
create_sheet_fields(LF_FASI, y, dlg, fsc_req);
else
{
const bool cdc_req = ini.get_bool("CdcRequired");
create_sheet_fields(LF_CDC, y, dlg, cdc_req);
}
} else
if (level == "CMS") // Crea commessa
{
if (fasinfo.parent() == LF_COMMESSE)
create_sheet_fields(LF_FASI, y, dlg, fsc_req);
else
{
const bool cms_req = ini.get_bool("CmsRequired");
create_sheet_fields(LF_COMMESSE, y, dlg, cms_req);
}
}
}
if (fasinfo.levels() > 0 && fasinfo.parent() <= 0)
create_sheet_fields(LF_FASI, y, dlg, fsc_req);
for (short id = S_CDC12+100; id >= S_CDC1+100; id--)
{
const int pos = sm.id2pos(id);
if (pos >= 0)
{
TMask_field& f = sm.fld(pos);
const int size = f.size();
const TString& prompt = f.prompt();
sf.set_column_header(id, prompt);
sf.set_column_justify(id, f.is_kind_of(CLASS_REAL_FIELD));
sf.set_column_width(id, (max(3+size, prompt.len()+1)) * CHARX);
}
else
sf.delete_column(id);
}
}
TPrint_bilancio_ca_mask::TPrint_bilancio_ca_mask()
:TAutomask("ca3300")
{
TConfig& cfg = ca_config();
const bool use_pdcc = cfg.get_bool("UsePdcc");
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;
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);
}
}
// creazione dei campi della seconda pagina della maschera
create_sheet();
set_handlers(); // Setta l'andler universale a tutti i nuovi campi
}
////////////////////////////////////////////////////////
// TReport_bilancio_verifica
////////////////////////////////////////////////////////
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_verifica(const char* name);
};
bool TReport_bilancio_verifica::set_recordset(const TString& /* sql */)
{
TPconana_recordset* rset = new TPconana_recordset();
return TReport::set_recordset(rset);
}
void TReport_bilancio_verifica::set_filter(const TMask& m, int row)
{
TString da_conto, a_conto, costo, commessa, fase;
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(dlg_da+i);
a_conto << m.get(dlg_al+i);
}
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
}
TDate dal, al;
const int anno = m.get_int(F_ANNO);
if (anno > 0)
{
TEsercizi_contabili esc;
esc.code2range(anno, dal, al);
}
// 1 = per data limite; 2 = all'ultima immissione
if (m.get_int(F_STAMPA) == 1)
{
if (!m.field(F_DATADA).empty())
dal = m.get(F_DATADA);
if (!m.field(F_DATAA).empty())
al = m.get(F_DATAA);
}
else
{
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++)
{
TReport_section& h = section('H', s);
h.deactivate();
h.hide();
TReport_section& f = section('F', s);
f.deactivate();
f.hide();
}
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);
costo = rel.curr().get(RMOVANA_CODCCOSTO);
commessa = rel.curr().get(RMOVANA_CODCMS);
fase = rel.curr().get(RMOVANA_CODFASE);
TPconana_recordset* rset = (TPconana_recordset*)recordset();
if (rset != NULL)
rset->set_filter(tc, da_conto, a_conto, costo, commessa, fase, dal, al, tipimov, movimentati, nonnulli);
}
TReport_bilancio_verifica::TReport_bilancio_verifica(const char* name)
{
load(name);
}
////////////////////////////////////////////////////////
// TRecordset_sezioni_contapposte
////////////////////////////////////////////////////////
struct TSaldo_contrapposto : public TObject
{
TString _conto;
TImporto _saldo, _preventivo, _consuntivo;
TSaldo_contrapposto& operator+=(const TSaldo_contrapposto& sc);
void reset();
};
TSaldo_contrapposto& TSaldo_contrapposto::operator+=(const TSaldo_contrapposto& sc)
{
_preventivo += sc._preventivo;
_consuntivo += sc._consuntivo;
_saldo += sc._saldo;
return *this;
}
void TSaldo_contrapposto::reset()
{
_preventivo.reset();
_consuntivo.reset();
_saldo.reset();
}
class TRecordset_sezioni_contrapposte : public TRecordset
{
char _tipo_piano;
TAnal_bill _filter;
TDate _da_data, _a_data;
word _tipimov;
bool _movimentati, _nonnulli;
TString _daconto, _aconto;
TString4 _tipostampa;
bool _print_ap;
TArray _attivita, _passivita, _costi, _ricavi; // Elenco di saldi contrapposti
TRecnotype _pos;
protected:
TRecnotype items_ap() const;
TRecnotype items_cr() const;
virtual const TVariant& get_fld(const TArray& a, int r, const char* field) const;
TArray& conti(int indbil);
void add_conto(const TString& b, const TImporto& s, const TImporto& p, const TImporto& c, TArray& a, int n = -1);
void add_conto(int indbil, const TString& b);
void calcola_totali();
void get_section(const TImporto& imp, TVariant& var) const;
public:
virtual TRecnotype items() const;
virtual bool move_to(TRecnotype pos);
virtual TRecnotype current_row() const { return _pos; }
virtual void requery();
virtual const TString& query_text() const { CHECK(false,"Perche' mi usi?"); return EMPTY_STRING; }
virtual unsigned int columns() const;
virtual const TRecordset_column_info& column_info(unsigned int column) const;
virtual const TVariant& get(unsigned int column) const { return NULL_VARIANT; }
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,
bool print_ap, const TString& daconto, const TString& aconto);
char tipo_piano() const { return _tipo_piano; }
TRecordset_sezioni_contrapposte(char tipo_piano) : _tipo_piano(tipo_piano) { }
};
TRecnotype TRecordset_sezioni_contrapposte::items_ap() const
{ return _print_ap ? max(_attivita.items(), _passivita.items()) : 0; }
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, bool print_ap, const TString& daconto, const TString& aconto)
{
_tipo_piano = piano;
_da_data = dal;
_a_data = al;
_tipimov = tipimov;
//serve per settare il tipostampa sul report!!!
switch (tipimov)
{
case 1: _tipostampa = "C"; break;
case 2:
case 4:
case 6: _tipostampa = "P"; break;
default: _tipostampa = "R"; break;
}
_movimentati = movimentati;
_nonnulli = nonnulli;
_print_ap = print_ap;
_filter.reset();
_filter.set_costo(costo);
_filter.set_commessa(commessa);
_filter.set_fase(fase);
_daconto = daconto;
_aconto = aconto;
}
TArray& TRecordset_sezioni_contrapposte::conti(int indbil)
{
TArray* ptar = NULL;
switch (indbil)
{
case 1: ptar = &_attivita; break;
case 2: ptar = &_passivita; break;
case 3: ptar = &_costi; break;
case 4: ptar = &_ricavi; break;
default: CHECKD(0, "Indicatore di bilancio errato:", indbil); break;
}
return *ptar;
}
void TRecordset_sezioni_contrapposte::add_conto(const TString& b,
const TImporto& s, const TImporto& p, const TImporto& c,
TArray& a, int n)
{
TSaldo_contrapposto* sc = new TSaldo_contrapposto;
sc->_conto = b;
sc->_saldo = s; sc->_saldo.normalize();
sc->_preventivo = p; sc->_preventivo.normalize();
sc->_consuntivo = c; sc->_consuntivo.normalize();
if (n < 0)
a.add(sc);
else
a.insert(sc, n);
}
void TRecordset_sezioni_contrapposte::add_conto(int indbil, const TString& b)
{
if (indbil >= 1 && indbil <= 4)
{
TAnal_bill bill(_filter);
bill.set_conto(b);
if ((_tipimov & _saldanal_qualsiasi) == _saldanal_qualsiasi) // Bilancio a sezioni contrapposte di raffronto
{
const TSaldanal& sp = ca_saldo(bill, _da_data, _a_data, _saldanal_preventivi);
const TSaldanal& sc = ca_saldo(bill, _da_data, _a_data, _saldanal_consuntivo);
if (!sp._fin.is_zero() || !sc._fin.is_zero())
{
TArray& a = conti(indbil);
TImporto s = sp._fin; s -= sc._fin; s.normalize();
add_conto(b, s, sp._fin, sc._fin, a);
}
}
else
{
const TSaldanal& sa = ca_saldo(bill, _da_data, _a_data, _tipimov);
if (!sa._fin.is_zero())
{
const TImporto zero;
TArray& a = conti(indbil);
add_conto(b, sa._fin, zero, zero, a);
}
}
}
}
void TRecordset_sezioni_contrapposte::calcola_totali()
{
const int logicnum = _tipo_piano == 'A' ? LF_PCONANA : LF_PCON;
const TMultilevel_code_info& info = ca_multilevel_code_info(logicnum);
const int break_level = info.levels()-1;
int maxlen[4]; // I livelli intermedi sono al massimo 3 ma facciamo conto pari
for (int level = 0; level < break_level; level++)
maxlen[level] = info.total_len(level);
// Scandisce tutti i 4 array dei conti
for (int indbil = 1; indbil <= 4; indbil++)
{
TArray& a = conti(indbil);
if (!a.empty())
{
TSaldo_contrapposto totale[4]; // Totali dei 3 livelli intermedi (4 per fare conto pari)
TString80 last_conto;
// Inserisci sentinella per far scattare il cambio del conto sull'ultimo record
a.insert(new TSaldo_contrapposto, 0);
for (int i = a.last(); i >= 0; i--)
{
const TSaldo_contrapposto& sc = (const TSaldo_contrapposto&)a[i];
if (last_conto.not_empty())
{
for (int level = break_level-1; level >= 0; level--)
{
const int cut = maxlen[level];
if (sc._conto.compare(last_conto, cut) != 0)
{
const TString& intermedio = last_conto.left(cut);
add_conto(intermedio,
totale[level]._saldo, totale[level]._preventivo, totale[level]._consuntivo,
a, i+1);
totale[level].reset();
}
else
break;
}
}
last_conto = sc._conto;
for (int l = 0; l < break_level; l++)
totale[l] += sc;
}
a.destroy(0, true); // Elimina sentinella
}
}
}
void TRecordset_sezioni_contrapposte::requery()
{
// Crea recordset del piano dei conti appropriato
TString query = "USE PCON";
if (_tipo_piano == 'A')
{
query << "ANA";
if (_daconto.full())
query << "\nFROM CODCONTO=" << _daconto;
if (_aconto.full())
query << "\nTO CODCONTO=" << _aconto;
}
else //piano 'C' (cazzuto)
{
if (_daconto.full())
query << "\nFROM GRUPPO=" << _daconto.left(3) << " CONTO=" << _daconto.mid(3,3) << " SOTTOCONTO=" << _daconto.mid(6,6);
if (_aconto.full())
query << "\nTO GRUPPO=" << _aconto.left(3) << " CONTO=" << _aconto.mid(3,3) << " SOTTOCONTO=" << _aconto.mid(6,6);
}
TISAM_recordset pconana(query);
TProgind pi(pconana.items(), TR("Elaborazione conti"), true, true);
TString80 conto;
int indicatore_bilancio = 0;
const TMultilevel_code_info& info = ca_multilevel_code_info(LF_PCONANA);
const int maxlen = info.total_len(4); // Calcola lunghezza livello massimo dei conti
// Scandisce il piano dei conti considerando solo quelli di livello piu' basso
for (TRecnotype i = 0; pconana.move_to(i); i++)
{
pi.addstatus(1);
if (pi.iscancelled())
break;
if (_tipo_piano == 'C')
{
const int g = pconana.get(PCN_GRUPPO).as_int();
const int c = pconana.get(PCN_CONTO).as_int();
const long s = pconana.get(PCN_SOTTOCONTO).as_int();
const TBill b(g, c, s);
if (s == 0 || !b.is_analitico())
continue; // Ignora tutti i gruppi e conti, ignora sottoconti non analitici
conto = b.string(0x8);
indicatore_bilancio = b.indicatore_bilancio();
}
else
{
conto = pconana.get(PCONANA_CODCONTO).as_string();
if (conto.len() < maxlen) // Ignora conti intermedi
continue;
const TAnal_bill b(conto);
indicatore_bilancio = b.indicatore_bilancio();
}
add_conto(indicatore_bilancio, conto);
}
calcola_totali(); // Aggiungi i gruppi e conti intermedi coi loro totali
move_to(0);
}
unsigned int TRecordset_sezioni_contrapposte::columns() const
{ return 1; }
const TRecordset_column_info& TRecordset_sezioni_contrapposte::column_info(unsigned int column) const
{
return *(TRecordset_column_info*)NULL;
}
void TRecordset_sezioni_contrapposte::get_section(const TImporto& imp, TVariant& var) const
{
if (imp.is_zero())
var = EMPTY_STRING;
else
{
const char sez[2] = { imp.sezione(), '\0' };
var = sez;
}
}
const TVariant& TRecordset_sezioni_contrapposte::get_fld(const TArray& a, int r, const char* field) const
{
TVariant& var = get_tmp_var();
if (r >= 0 && r < a.items())
{
const TFixed_string fld(field);
const TSaldo_contrapposto& sc = (const TSaldo_contrapposto&)a[r];
if (fld == "CONTO")
var = sc._conto; else
if (fld == "DESCR")
{
const TString& conto = sc._conto;
if (tipo_piano() == 'C')
{
TToken_string k;
k.add(conto.mid(0,3));
k.add(conto.mid(3,3));
k.add(conto.mid(6,6));
var = cache().get(LF_PCON, k, PCN_DESCR);
}
else
var = cache().get(LF_PCONANA, conto, PCONANA_DESCR);
} else
if (fld == "SALDO")
{
var = sc._saldo.valore();
} else
if (fld == "SALDOC")
{
var = sc._consuntivo.valore();
} else
if (fld == "SALDOP" || fld == "SALDOV")
{
var = sc._preventivo.valore();
} else
if (fld == "SEZIONE")
{
get_section(sc._saldo, var);
} else
if (fld == "SEZIONEC")
{
get_section(sc._consuntivo, var);
} else
if (fld == "SEZIONEP" || fld == "SEZIONEV")
{
get_section(sc._preventivo, var);
} else
if (fld == "LIVELLO")
{
const int len = sc._conto.len();
if (tipo_piano() == 'C')
var = len <= 3 ? 1 : (len <= 6 ? 2 : 3);
else
{
var = 1; // facile esercizio per gli studenti :-)
}
}
}
else
var = EMPTY_STRING;
return var;
}
const TVariant& TRecordset_sezioni_contrapposte::get(const char* field) const
{
const TFixed_string fld(field);
if (*field == '#')
{
if (fld == "#CMSCDC")
{
const TMultilevel_code_info& info = ca_multilevel_code_info(LF_FASI);
switch (info.parent())
{
case LF_CDC : return get_tmp_var() = _filter.costo();
case LF_COMMESSE: return get_tmp_var() = _filter.commessa();
default : return NULL_VARIANT;
}
}
if (fld == "#COSTO")
return get_tmp_var() = _filter.costo();
if (fld == "#COMMESSA")
return get_tmp_var() = _filter.commessa();
if (fld == "#FASE")
return get_tmp_var() = _filter.fase();
if (fld == "#DATA_INIZIALE")
return get_tmp_var() = _da_data;
if (fld == "#DATA_FINALE")
return get_tmp_var() = _a_data;
if (fld == "#TIPOPIANO")
{
TString4 tp; tp << tipo_piano();
return get_tmp_var() = tp;
}
if (fld == "#TIPOSTAMPA")
return get_tmp_var() = _tipostampa;
}
else
{
if (fld == "SEZIONE")
{
return get_tmp_var() = _pos < items_cr() ? "CR" : "AP";
}
const bool left = fld.starts_with("LEFT:");
if (_pos < items_cr())
{
if (left)
return get_fld(_costi, _pos, field+5);
else
return get_fld(_ricavi, _pos, field+6);
}
else
{
const TRecnotype pos = _pos - items_cr();
if (pos < items_ap())
{
if (left)
return get_fld(_attivita, pos, field+5);
else
return get_fld(_passivita, pos, field+6);
}
}
return get_tmp_var() = EMPTY_STRING;
}
return NULL_VARIANT;
}
////////////////////////////////////////////////////////
// TReport_bilancio_sezioni_contapposte
////////////////////////////////////////////////////////
class TReport_bilancio_sezioni_contrapposte : public TAnal_report
{
protected:
virtual bool set_recordset(const TString& sql);
virtual void msg_format_conto(TVariant_stack& stack);
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::msg_format_conto(TVariant_stack& stack)
{
const TRecordset_sezioni_contrapposte* rset = (TRecordset_sezioni_contrapposte*)recordset();
if (rset->tipo_piano() == 'C')
msg_format(LF_PCON, stack);
else
msg_format(LF_PCONANA, stack);
}
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;
esc.code2range(anno, dal, al);
}
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;
const bool print_ap = m.get_bool(F_PRINT_CONTO_ECON);
TSheet_field& sf = m.sfield(F_RIGHE);
TMask& sm = sf.sheet_mask();
sf.update_mask(row);
TRelation rel(LF_RMOVANA); // Relazione d'appoggio solo per salvare la riga dello sheet
sm.autosave(rel);
const TRectype& curr = rel.curr();
const TString80 costo = curr.get(RMOVANA_CODCCOSTO);
const TString80 commessa = curr.get(RMOVANA_CODCMS);
const TString16 fase = curr.get(RMOVANA_CODFASE);
//c'e' un range di conti da considerare?
const short dlg_da = tipo == 'C' ? F_PDC1_INI : F_PAN1_INI;
const short dlg_al = tipo == 'C' ? F_PDC1_FIN : F_PAN1_FIN;
TString daconto, aconto;
for (int i = 0; i < 4 && m.id2pos(dlg_da+i) > 0; i++)
{
daconto << m.get(dlg_da+i);
aconto << m.get(dlg_al+i);
}
TRecordset_sezioni_contrapposte* recset = new TRecordset_sezioni_contrapposte(tipo);
recset->set_filter(tipo, costo, commessa, fase, dal, al, tipimov, movimentati, nonnulli, print_ap, daconto, aconto);
TAnal_report::set_recordset(recset);
};
////////////////////////////////////////////////////////
// APPLICAZIONE
////////////////////////////////////////////////////////
class TPrint_bilancio_ca : public TSkeleton_application
{
protected:
virtual const char * extra_modules() const {return "cm";} //funziona anche con autorizzazione CM
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));
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::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)
{
TSheet_field& sf = mask.sfield(F_RIGHE);
if (sf.empty())
sf.row(-1); // Aggiungo riga vuota
if (mask.get(F_BILANCIO) == "C")
bilancio_a_sezioni_contrapposte(mask);
else
bilancio_di_verifica(mask);
}
}
int ca3300(int argc, char* argv[])
{
TPrint_bilancio_ca a;
a.run(argc, argv, TR("Stampa bilancio"));
return 0;
}