Files correlati :ca3.exe Ricompilazione Demo : [ ] Commento :stampa rendiconto: nel caso una riga appartenga ad una fattura derivante da un ordine multiriga, la stampa della riga analitica corrispondente alla riga fattura deve mostrare la riga ordine originaria corrispondente per commessa e fase, non tutte le righe ordine. Adolfo! git-svn-id: svn://10.65.10.50/trunk@14344 c028cbd2-c16b-5b4b-a496-9718f37d4682
1337 lines
43 KiB
C++
Executable File
1337 lines
43 KiB
C++
Executable File
#include <applicat.h>
|
||
#include <execp.h>
|
||
#include <progind.h>
|
||
#include <reprint.h>
|
||
#include <doc.h>
|
||
#include <rdoc.h>
|
||
#include "../cg/cg2103.h"
|
||
#include "../cg/cglib01.h"
|
||
#include "../ve/velib04.h"
|
||
|
||
#include "panapdc.h"
|
||
#include "pconana.h"
|
||
#include "movana.h"
|
||
#include "rmovana.h"
|
||
|
||
#include "ca3.h"
|
||
#include "ca3700.h"
|
||
#include "calib01.h"
|
||
#include "calib02.h"
|
||
|
||
////////////////////////////////////////////////////////
|
||
// MASCHERA
|
||
////////////////////////////////////////////////////////
|
||
class TPrint_rendiconto_ca_mask : public TAnal_report_mask
|
||
{
|
||
protected:
|
||
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
|
||
const TString& get_report_class() const;
|
||
bool test_compatible_report();
|
||
|
||
public:
|
||
TPrint_rendiconto_ca_mask();
|
||
virtual ~TPrint_rendiconto_ca_mask() {}
|
||
};
|
||
|
||
const TString& TPrint_rendiconto_ca_mask::get_report_class() const
|
||
{
|
||
TString& classe = get_tmp_string();
|
||
classe = "ca3700a";
|
||
return classe;
|
||
}
|
||
|
||
bool TPrint_rendiconto_ca_mask::test_compatible_report()
|
||
{
|
||
const TString& cls = get_report_class();
|
||
const TString& name = get(F_REPORT);
|
||
bool ok = name.not_empty();
|
||
if (ok)
|
||
{
|
||
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_rendiconto_ca_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
|
||
{
|
||
switch (o.dlg())
|
||
{
|
||
case F_RIGHE:
|
||
if (e == fe_init) //azzera le righe dello sheet con le commesse ad inizio programma
|
||
{ //esplicita e bizzarra richiesta del CRPA
|
||
TSheet_field& s = (TSheet_field&)o;
|
||
s.destroy();
|
||
s.force_update();
|
||
}
|
||
break;
|
||
case F_DATAINI:
|
||
case F_DATAFIN:
|
||
if (e == fe_close)
|
||
{
|
||
const int anno = get_int(F_ANNO);
|
||
if (anno > 0) //se viene selezionato un esercizio..
|
||
{
|
||
TEsercizi_contabili esc; //..le date devono essere incluse nell'esercizio selezionato!
|
||
const TDate data = o.get();
|
||
if (!data.empty() && esc.date2esc(data) != anno)
|
||
return error_box(TR("La data deve appartenere all'anno selezionato"));
|
||
}
|
||
/* else //se l'esercizio <20> vuoto le date diventano obbligatorie!!
|
||
{
|
||
if (o.empty())
|
||
return error_box(TR("La data <20> obbligatoria in quanto manca l'esercizio"));
|
||
}*/
|
||
}
|
||
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(TR("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 TAnal_report_mask::on_field_event(o, e, jolly);
|
||
}
|
||
|
||
|
||
TPrint_rendiconto_ca_mask::TPrint_rendiconto_ca_mask()
|
||
:TAnal_report_mask("ca3700")
|
||
{
|
||
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 prefix = cfg.get_int("PdcPrefix");
|
||
if (prefix >= pconana_levels)
|
||
prefix = pconana_levels-1;
|
||
|
||
//setta nel campo F_PIANO il tipo di piano dei conti usato in base alla configurazione..
|
||
//..e disabilita il campo (non si puo' cambiare la configurazione in una stampa!!)
|
||
disable(F_PIANO);
|
||
set(F_PIANO, use_pdcc ? "C" : "A");
|
||
|
||
// Controllo se voglio (e posso) usare il conto analitico come prefisso di quello contabile
|
||
if (use_pdcc && prefix > 0)
|
||
{
|
||
const TMultilevel_code_info& info = ca_multilevel_code_info(LF_PCONANA);
|
||
const int levels = info.levels();
|
||
if (levels >= 2 && prefix < levels && esistono_riclassificazioni())
|
||
{
|
||
enable(F_PIANO);
|
||
ca_create_fields(*this, 1, LF_PCONANA, 2, 4, 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 < prefix)
|
||
{
|
||
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, 10, da_dlg, da_des, 0x0, PCONANA_CODCONTO);
|
||
ca_create_fields(*this, 1, logicnum, 2, 16, 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_SEARCH);
|
||
|
||
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_SEARCH);
|
||
|
||
field(a_des+i).set_group(4);
|
||
field(a_des+i).set_group(g);
|
||
}
|
||
}
|
||
|
||
// creazione dei campi della pagina della maschera con lo sheet di cdc/cms/fasi
|
||
create_sheet(F_RIGHE);
|
||
// setta gli handlers a tutti i campi generati della maschera;senza questa chiamata la on_field_event
|
||
// non puo' funzionare sui campi generati!!!
|
||
set_handlers();
|
||
}
|
||
|
||
|
||
///////////////////////////////////////////////////////////////
|
||
// RECORDSET
|
||
///////////////////////////////////////////////////////////////
|
||
#define IMPEGNATO 1
|
||
#define MATURATO 2
|
||
#define FATTURATO 4
|
||
|
||
class TPrint_rendiconto_ca_recordset : public TISAM_recordset
|
||
{
|
||
TExternisamfile* _tmp;
|
||
bool _riclassificato;
|
||
TString _prefix;
|
||
|
||
protected:
|
||
int _anno;
|
||
TString4 _piano;
|
||
TDate _dadata, _adata;
|
||
long _danumreg, _anumreg;
|
||
TString _daconto, _aconto, _codcosto, _codcms, _codfas;
|
||
|
||
protected: //da libreria
|
||
virtual const TVariant& get(const char* column_name) const;
|
||
|
||
protected:
|
||
static bool mov_filter(const TRelation* rel);
|
||
bool valid_record(const TRelation& rel) const;
|
||
virtual void set_custom_filter(TCursor& cur) const;
|
||
|
||
void crea_righe_da_rmovana();
|
||
void crea_righe_da_rdoc(const TPrint_rendiconto_ca_mask& msk);
|
||
void crea_trr(const TFilename& trr) const;
|
||
void scrive_riga(const TRectype& rmovana, const TRectype& movana, const TDocumento* doc);
|
||
void scrive_riga_speciale(const TDocumento* doc, const TString_array& special_docs);
|
||
TString riclassifica(const int gruppo, const int conto, const long sottoconto, TRectype& tmpcurr);
|
||
real get_budget(const TString& conto, char tipo) const;
|
||
|
||
|
||
public:
|
||
virtual void set_filter(const TPrint_rendiconto_ca_mask& msk, int cms_row);
|
||
|
||
TPrint_rendiconto_ca_recordset(const TString& sql) : TISAM_recordset(sql), _riclassificato(false) { _tmp = NULL;}
|
||
~TPrint_rendiconto_ca_recordset();
|
||
};
|
||
|
||
|
||
static TPrint_rendiconto_ca_recordset* myself = NULL;
|
||
|
||
TPrint_rendiconto_ca_recordset::~TPrint_rendiconto_ca_recordset()
|
||
{ }
|
||
|
||
|
||
void TPrint_rendiconto_ca_recordset::set_custom_filter(TCursor& cur) const
|
||
{
|
||
relation()->replace(_tmp); //sostituisce il vero file rmovana con quello temporaneo
|
||
|
||
//filtro sul file esterno (_tmp, cio<69> 1000) sui conti selezionati sulla maschera
|
||
TRectype darec(cur.curr()), arec(cur.curr()); //curr perch<63> <20> il file externisamfile
|
||
darec.zero();
|
||
arec.zero();
|
||
|
||
if (_daconto.not_empty())
|
||
darec.put("CONTO", _daconto);
|
||
if (_aconto.not_empty())
|
||
arec.put("CONTO", _aconto);
|
||
|
||
//filtro sulla data(non avendo anche codnum non ho la chiave completa per mettere la data nella setregion)
|
||
TString filtro;
|
||
if (_dadata.ok())
|
||
filtro << "(ANSI(DATA)>=" << _dadata << ")";
|
||
|
||
if (_adata.ok())
|
||
{
|
||
if (filtro.not_empty())
|
||
filtro << "&&";
|
||
filtro << "(ANSI(DATA)<=" << _adata << ")";
|
||
}
|
||
|
||
cur.setregion(darec, arec);
|
||
cur.setfilter(filtro);
|
||
|
||
myself = (TPrint_rendiconto_ca_recordset*)this;
|
||
}
|
||
|
||
//sconvolgente metodo per la normalizzazione dei conti
|
||
real TPrint_rendiconto_ca_recordset::get_budget(const TString& conto, char tipo) const
|
||
{
|
||
//data del cazzo che per<65> serve per costruire il conto analitico
|
||
const TDate null_date;
|
||
//ecco il conto analitico...
|
||
TAnal_bill zio(conto, _codcosto, _codcms, _codfas);
|
||
//..adesso si necessita del saldo del conto analitico appena creato..
|
||
word tipo_movimento = 0;
|
||
switch (tipo)
|
||
{
|
||
case 'P': tipo_movimento |= _saldanal_preventivo; break;
|
||
case 'V': tipo_movimento |= _saldanal_variazione; break;
|
||
default: tipo_movimento |= _saldanal_consuntivo; break;
|
||
}
|
||
|
||
if (_riclassificato)
|
||
tipo_movimento |= _saldanal_riclassify;
|
||
//..ecco quindi il saldo..
|
||
const TSaldanal& saldo = ca_saldo(zio, null_date, null_date, tipo_movimento);
|
||
//..che deve essere normalizzato in base alla sua sezione ed all'indicatore di bilancio del conto
|
||
TImporto imp = saldo._fin;
|
||
switch (zio.indicatore_bilancio())
|
||
{
|
||
case 1:
|
||
case 3:
|
||
imp.normalize('D');
|
||
break;
|
||
case 2:
|
||
case 4:
|
||
imp.normalize('A');
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
return imp.valore();
|
||
}
|
||
|
||
const TVariant& TPrint_rendiconto_ca_recordset::get(const char* column_name) const
|
||
{
|
||
|
||
if (*column_name == '#')
|
||
{
|
||
if (strcmp(column_name, "#COSTO") == 0)
|
||
{
|
||
TVariant& var = get_tmp_var();
|
||
var = _codcosto;
|
||
return var;
|
||
}
|
||
if (strcmp(column_name, "#COMMESSA") == 0)
|
||
{
|
||
TVariant& var = get_tmp_var();
|
||
var = _codcms;
|
||
return var;
|
||
}
|
||
if (strcmp(column_name, "#FASE") == 0)
|
||
{
|
||
TVariant& var = get_tmp_var();
|
||
var = _codfas;
|
||
return var;
|
||
}
|
||
if (strcmp(column_name, "#PIANO") == 0)
|
||
{
|
||
TVariant& var = get_tmp_var();
|
||
if (_piano == "A")
|
||
var = "Analitico";
|
||
else
|
||
var = "Contabile";
|
||
return var;
|
||
}
|
||
if (strcmp(column_name, "#DACONTO") == 0)
|
||
{
|
||
TVariant& var = get_tmp_var();
|
||
var = _daconto;
|
||
return var;
|
||
}
|
||
if (strcmp(column_name, "#ACONTO") == 0)
|
||
{
|
||
TVariant& var = get_tmp_var();
|
||
var = _aconto;
|
||
return var;
|
||
}
|
||
//cerca l'indicatore di bilancio del conto;utilizzato per stabilire il campo ove sommare..
|
||
//..i budget nella coda report
|
||
if (strcmp(column_name, "#INDBIL") == 0)
|
||
{
|
||
const TString& conto = TISAM_recordset::get("CONTO").as_string();
|
||
TAnal_bill zio(conto);
|
||
return get_tmp_var() = (long)zio.indicatore_bilancio();
|
||
}
|
||
//calcola il valore e la sezione del campo budget di un conto basandosi sull'indicatore di..
|
||
//..bilancio ed il saldo del conto (movimenti analitici di tipo preventivo)
|
||
if (strcmp(column_name, "#PREVENTIVO") == 0)
|
||
{
|
||
//stessa cosa del precedente ma per movimenti di tipo variazione preventivo
|
||
const TString& conto = TISAM_recordset::get("CONTO").as_string();
|
||
return get_tmp_var() = get_budget(conto, 'P');
|
||
}
|
||
if (strcmp(column_name, "#VARIAZIONE") == 0)
|
||
{
|
||
//prende il conto
|
||
const TString& conto = TISAM_recordset::get("CONTO").as_string();
|
||
return get_tmp_var() = get_budget(conto, 'V');
|
||
}
|
||
}
|
||
return TISAM_recordset::get(column_name);
|
||
}
|
||
|
||
TString TPrint_rendiconto_ca_recordset::riclassifica(const int gruppo, const int conto,
|
||
const long sottoconto, TRectype& tmpcurr)
|
||
{
|
||
TString conto_riclassificato;
|
||
//relazione e cursore su panapdc alla ricerca del conto riclassificato corrispondente
|
||
//alla triade gr/co/sottoc di rmovana
|
||
TRelation rel_panapdc(LF_PANAPDC);
|
||
//servono solamente i record con il gruppo = al gruppo di rmovana
|
||
TRectype da_panapdc(LF_PANAPDC);
|
||
da_panapdc.put(PANAPDC_GRUPPO, gruppo);
|
||
|
||
TString filtro;
|
||
if (_prefix.not_empty())
|
||
filtro << "(CODCONTO[1," << _prefix.len() << "]=='" << _prefix << "')";
|
||
|
||
TCursor cur_panapdc(&rel_panapdc, filtro, 2, &da_panapdc, &da_panapdc);
|
||
const long panapdc_items = cur_panapdc.items();
|
||
cur_panapdc.freeze();
|
||
if (panapdc_items > 0) //se non ci sono record con il gruppo=rmovana.gruppo ed il prefisso voluto->salta l'rmovana
|
||
{
|
||
TRectype& rec_panapdc = cur_panapdc.curr();
|
||
for (cur_panapdc = 0; cur_panapdc.pos() < panapdc_items; ++cur_panapdc)
|
||
{
|
||
int current_conto = rec_panapdc.get_int(PANAPDC_CONTO);
|
||
long current_sottoconto = rec_panapdc.get_long(PANAPDC_SOTTOCONTO);
|
||
|
||
if (current_conto == 0 && current_sottoconto == 0)
|
||
{
|
||
conto_riclassificato = rec_panapdc.get(PANAPDC_CODCONTO);
|
||
tmpcurr.put("CONTO", conto_riclassificato);
|
||
break; //esce dal casino e passa ai campi successivi
|
||
}
|
||
else if (conto == current_conto && current_sottoconto == 0)
|
||
{
|
||
conto_riclassificato = rec_panapdc.get(PANAPDC_CODCONTO);
|
||
tmpcurr.put("CONTO", conto_riclassificato);
|
||
break; //esce dal casino e passa ai campi successivi
|
||
}
|
||
else if (conto == current_conto && sottoconto == current_sottoconto)
|
||
{
|
||
conto_riclassificato = rec_panapdc.get(PANAPDC_CODCONTO);
|
||
tmpcurr.put("CONTO", conto_riclassificato);
|
||
break; //esce dal casino e passa ai campi successivi
|
||
}
|
||
} //for sugli elementi del cursore
|
||
} //if panapdc_items > 0
|
||
|
||
//ATTENZIONE! Se era stata operata una selezione sui conti riclassificati nella maschera
|
||
//ed il conto riclassificato attuale non ricade nell'intervallo selezionato il programma
|
||
//non deve aggiungere il record al file!!Quindi ritorna una stringa vuota che sara' il segnale..
|
||
//..per interrompere l'analisi del record corrente
|
||
if ((_daconto.not_empty() && conto_riclassificato < _daconto) ||
|
||
(_aconto.not_empty() && conto_riclassificato.compare(_aconto, _aconto.len()) > 0))
|
||
return EMPTY_STRING;
|
||
|
||
return conto_riclassificato;
|
||
}
|
||
|
||
|
||
//compila i campi del file temporaneo che sara' poi stampato
|
||
void TPrint_rendiconto_ca_recordset::scrive_riga(const TRectype& rmovana, const TRectype& movana, const TDocumento* doc)
|
||
{
|
||
|
||
TRectype& tmpcurr = _tmp->curr();
|
||
tmpcurr.zero();
|
||
TString8 codnum_desc; //codnum da usare sia per compilare il campo "CODNUM"
|
||
codnum_desc.cut(0);
|
||
|
||
// il conto puo' essere analitico o contabile...
|
||
//se <20> compilato l'archivio di collegamento PANAPDC
|
||
//si deve usare come conto il campo codconto del panapdc!!!...
|
||
if (_riclassificato)
|
||
{
|
||
//prende il gr/co/so dalla riga rmovana in esame
|
||
const int gruppo = atoi(rmovana.get(RMOVANA_CODCONTO).left(3));
|
||
const int conto = atoi(rmovana.get(RMOVANA_CODCONTO).mid(3,3));
|
||
const long sottoconto = atol(rmovana.get(RMOVANA_CODCONTO).mid(6,6));
|
||
|
||
//stringa che conterr<72> il conto riclassificato (se sara' trovato)
|
||
TString conto_riclassificato = riclassifica(gruppo, conto, sottoconto, tmpcurr);
|
||
//se il conto viene ritornato vuoto significa che non ricade nell'intervallo dei conti..
|
||
//..riclassificati selezionato dall'utente
|
||
if (conto_riclassificato == EMPTY_STRING)
|
||
return;
|
||
|
||
} //if(_riclassificato)
|
||
else //...senn<6E> si usa il normale piano dei conti analitico (cio<69> tutti tranne che il CRPA)
|
||
tmpcurr.put("CONTO", rmovana.get(RMOVANA_CODCONTO)); //conto
|
||
|
||
//in ogni caso riempio il campo conto_cg
|
||
tmpcurr.put("CONTOCG", rmovana.get(RMOVANA_CODCONTO)); //conto_cg
|
||
|
||
//tipo movimento CONSUNTIVO (o TEMPORANEO)
|
||
const char tipomov = movana.get_char(MOVANA_TIPOMOV);
|
||
if (tipomov <= ' ' || tipomov == 'T')
|
||
{
|
||
//serve un documento da cui ricavare i parametri di stampa
|
||
TDocumento* newdoc = (TDocumento*)doc;
|
||
bool should_delete = false;
|
||
if (newdoc == NULL && movana.get(MOVANA_DNDOC).not_empty())
|
||
{
|
||
const TString4 dacodnum = movana.get(MOVANA_DCODNUM);
|
||
newdoc = new TDocumento('D', movana.get_int(MOVANA_DANNO), dacodnum, movana.get_long(MOVANA_DNDOC));
|
||
should_delete = true; //settato true per cancellare il doc al termine del metodo(senn<6E> addio memoria!)
|
||
}
|
||
|
||
const bool dadoc = newdoc != NULL;
|
||
//i movimenti possono essere normali o generati da documento...
|
||
if (dadoc) //movimento generato da documento
|
||
{
|
||
codnum_desc = movana.get(MOVANA_DCODNUM); //serve anche in fondo al metodo
|
||
tmpcurr.put("CODNUM", codnum_desc); //codnum del documento che origina il movana
|
||
tmpcurr.put("ANNO", movana.get(MOVANA_DANNO)); //anno del doc di origine
|
||
tmpcurr.put("NUMRD", movana.get(MOVANA_DNDOC)); //numero del doc che origina movana
|
||
tmpcurr.put("DATA", newdoc->get(DOC_DATADOC)); //data del documento che genera movana..
|
||
} //..non esiste il campo in movana
|
||
else //movimento normale (senza documento)
|
||
{
|
||
tmpcurr.put("CODNUM", movana.get(MOVANA_CODCAUS)); //mette la causale del movimento
|
||
tmpcurr.put("ANNO", movana.get(MOVANA_ANNOES)); //anno del movimento
|
||
tmpcurr.put("NUMRD", movana.get(MOVANA_NUMREGCG)); //numregcg del movana
|
||
tmpcurr.put("DATA", movana.get(MOVANA_DATACOMP)); //data del movana
|
||
}
|
||
|
||
//ricerca del mitico documento padre della riga documento attuale!
|
||
int selettore = 0;
|
||
if (newdoc != NULL)
|
||
{
|
||
tmpcurr.put("NUMDOCRIF", newdoc->get(DOC_NUMDOCRIF)); //docrif del documento originante il movana
|
||
tmpcurr.put("DATADOCRIF", newdoc->get(DOC_DATADOCRIF)); //datadocrif del documento originante il movana
|
||
|
||
//procedura per ottenere i campi del documento
|
||
//deve tener conto del vero tipo del documento,nel caso sia classificato come _altro;in questo
|
||
//..caso si deve accorgere se e' in realta' una bolla o una fattura (utilizza la tipo_riclassificato())
|
||
const int tipo_documento = newdoc->tipo_riclassificato();
|
||
int tipo_babbo = TTipo_documento::_altro;
|
||
|
||
TToken_string riferimento(20, '\n'); //tokenstring su cui scrivere gli estremi dei docs padri (se li trova!)
|
||
TString80 rif; //stringa di lavoro su cui viene scritto un doc originale
|
||
const int rows = newdoc->physical_rows(); //righe del doc attuale
|
||
|
||
for (int i = 1; i <= rows; i++) //scandisce tutte le righe del doc..
|
||
{
|
||
const TRiga_documento& riga = (*newdoc)[i];
|
||
//commessa e fase della riga documento
|
||
const TString& codcms_rigadoc = riga.codice_commessa();
|
||
const TString& codfase_rigadoc = riga.fase_commessa();
|
||
//per evitare di scrivere per ogni riga documento tutte le righe del doc babbo (in pratica..
|
||
//..per evitare di avere n righe ordine ogni riga fattura) confronta commessa e fase..
|
||
//..della riga movimento analitico con quelli la riga movimento e procede solo nel..
|
||
//..caso coincidano (richiesta Adolfica!)
|
||
const TString codcms_rmovana = rmovana.get(RMOVANA_CODCMS);
|
||
const TString codfase_rmovana = rmovana.get(RMOVANA_CODFASE);
|
||
|
||
if (codcms_rigadoc == codcms_rmovana && codfase_rigadoc == codfase_rmovana)
|
||
{
|
||
const TRectype* babbo = riga.find_original_rdoc(); //cerca il doc padre della riga doc attuale
|
||
if (babbo != NULL) //se trova il doc padre..
|
||
{
|
||
const TString4 babbo_codnum = babbo->get(RDOC_CODNUM);
|
||
const int anno = babbo->get_int(RDOC_ANNO);
|
||
const long ndoc = babbo->get_long(RDOC_NDOC);
|
||
rif.cut(0) << babbo_codnum << '-' << anno << '-' << ndoc;
|
||
|
||
if (riferimento.get_pos(rif) < 0) //il doc originale va aggiunto solo se non esiste gia'!
|
||
{
|
||
riferimento.add(rif);
|
||
TDocumento doc_babbo('D', anno, babbo_codnum, ndoc); //crea una copia del doc padre per prendere..
|
||
tipo_babbo = doc_babbo.tipo_riclassificato(); //..il tipo documento..
|
||
}
|
||
} //if (babbo != NULL)..
|
||
}
|
||
} //for (int i..
|
||
|
||
tmpcurr.put("DOCORIG", riferimento); //documento di riferimento (mitologico documento originale)
|
||
|
||
/*[Tipo documento] //schema divino per destinare gli importi nei campi corretti
|
||
O=I**
|
||
B=IM*
|
||
BO=*M*
|
||
FB=**F
|
||
FO=*MF
|
||
F=IMF*/
|
||
switch (tipo_documento)
|
||
{
|
||
case TTipo_documento::_bolla: //bolla B -> IM a meno che non sia bolla da ordine BO -> M
|
||
selettore = MATURATO;
|
||
if (tipo_babbo != TTipo_documento::_ordine)
|
||
selettore |= IMPEGNATO;
|
||
break;
|
||
|
||
case TTipo_documento::_fattura:
|
||
selettore = FATTURATO; //fattura da bolla FB -> F
|
||
if (tipo_babbo == TTipo_documento::_ordine) //fattura da ordine FO -> MF
|
||
{
|
||
selettore |= MATURATO;
|
||
} else
|
||
if (tipo_babbo == TTipo_documento::_altro) //fattura senza padri F -> IMF
|
||
selettore |= (IMPEGNATO | MATURATO);
|
||
break;
|
||
|
||
case TTipo_documento::_ordine:
|
||
selettore = IMPEGNATO;
|
||
break;
|
||
|
||
case TTipo_documento::_altro:
|
||
CHECK(false, "Ma dove cavolo stai passando Willis?");
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
|
||
} //if(newdoc != NULL)
|
||
else //movimenti puri di analitica (no documento di origine!)
|
||
{
|
||
selettore = FATTURATO;
|
||
selettore |= MATURATO;
|
||
selettore |= IMPEGNATO;
|
||
} //if(newdoc != NULL)
|
||
|
||
//riempie i record del file temporaneo nel caso di rmovana con documento di origine
|
||
const char sezione = rmovana.get_char(RMOVANA_SEZIONE);
|
||
|
||
TImporto imp(sezione, rmovana.get_real(RMOVANA_IMPORTO));
|
||
const int anno_caus = movana.get_date(MOVANA_DATAREG).year();
|
||
|
||
TCausale caus(movana.get(MOVANA_CODCAUS), anno_caus);
|
||
TipoIVA tipoiva = caus.iva();
|
||
char sezione_normale;
|
||
|
||
if (tipoiva == iva_vendite)
|
||
sezione_normale = 'A';
|
||
else
|
||
if (tipoiva == iva_acquisti)
|
||
sezione_normale = 'D';
|
||
else
|
||
{
|
||
if (caus.sezione_clifo() == 'D')
|
||
sezione_normale = 'A';
|
||
else
|
||
sezione_normale = 'D';
|
||
}
|
||
|
||
imp.normalize(sezione_normale);
|
||
|
||
//riempie i record del file temporaneo nel caso di rmovana con documento di origine
|
||
if (selettore & FATTURATO)
|
||
tmpcurr.put("FATTURATO", imp.valore());
|
||
if (selettore & MATURATO)
|
||
tmpcurr.put("MATURATO", imp.valore());
|
||
if (selettore & IMPEGNATO)
|
||
tmpcurr.put("IMPEGNATO", imp.valore());
|
||
|
||
//campi comuni a rmovana e rdoc senza particolari operazioni
|
||
TString descr = movana.get(MOVANA_DESCR);
|
||
int pos = descr.find('$'); //solo per il CRPA!
|
||
if (pos > 0)
|
||
{
|
||
descr.ltrim(pos+1);
|
||
descr.trim();
|
||
}
|
||
|
||
tmpcurr.put("NUMREG", rmovana.get(RMOVANA_NUMREG));
|
||
tmpcurr.put("NUMREGCG", movana.get(MOVANA_NUMREGCG)); //numero di registrazione contabile
|
||
tmpcurr.put("DESC", descr); //descrizione movana
|
||
tmpcurr.put("NRIGA", rmovana.get(RMOVANA_NUMRIG)); //numero riga
|
||
tmpcurr.put("DESCRIGA", rmovana.get(RMOVANA_DESCR)); //descrizione rmovana
|
||
|
||
if (should_delete)
|
||
delete newdoc;
|
||
|
||
} //if (tipomov == ..)
|
||
else
|
||
{
|
||
tmpcurr.put("HIDDEN", "X");
|
||
}
|
||
|
||
_tmp->write();
|
||
|
||
}
|
||
|
||
|
||
//compila i campi del file temporaneo che sara' poi stampato per i documenti speciali..
|
||
//..quali le fatture da emettere e ricevere, la cui lista e' nel ca_config
|
||
void TPrint_rendiconto_ca_recordset::scrive_riga_speciale(const TDocumento* doc, const TString_array& special_docs)
|
||
{
|
||
const int rows = doc->physical_rows();
|
||
|
||
for (int i = 1; i <= rows; i++)
|
||
{
|
||
const TRiga_documento& rigadoc = (*doc)[i];
|
||
|
||
if (special_docs.find(rigadoc.get(RDOC_DACODNUM)) > 0)
|
||
{
|
||
TRectype& tmpcurr = _tmp->curr();
|
||
tmpcurr.zero();
|
||
TString8 codnum_desc;
|
||
codnum_desc.cut(0);
|
||
|
||
//prende il tipocf che gli serve un po' ovunque in seguito..
|
||
const char tipocf = doc->get_char(DOC_TIPOCF);
|
||
|
||
//se usa il piano dei conti contabile -> _piano = C..
|
||
if (_piano == "C")
|
||
{
|
||
//trova il conto senza movana e rmovana!!!
|
||
TContabilizzazione_analitica contab;
|
||
TBill conto;
|
||
if (contab.search_costo_ricavo(rigadoc, conto))
|
||
{
|
||
const int gr = conto.gruppo();
|
||
const int co = conto.conto();
|
||
const long so = conto.sottoconto();
|
||
|
||
if (_riclassificato)
|
||
{
|
||
//stringa che conterr<72> il conto riclassificato (se sara' trovato)
|
||
TString conto_riclassificato = riclassifica(gr, co, so, tmpcurr);
|
||
if (conto_riclassificato == EMPTY_STRING)
|
||
return;
|
||
|
||
} //if(_riclassificato)
|
||
else //...senn<6E> si usa il conto
|
||
tmpcurr.put("CONTO", conto.string(0x8));
|
||
}
|
||
}
|
||
else //se ivece usa il piano dei conti analitico -> _piano = A...
|
||
{
|
||
TString80 conto_anal;
|
||
if (rigadoc.is_articolo())
|
||
{
|
||
const TRectype& anamag = cache().get(LF_ANAMAG, rigadoc.get(RDOC_CODARTMAG));
|
||
conto_anal = anamag.get(tipocf == 'F' ? ANAMAG_CONTOINDA : ANAMAG_CONTOINDV);
|
||
}
|
||
else
|
||
{
|
||
if (rigadoc.is_spese() || rigadoc.is_prestazione() ||
|
||
rigadoc.is_risorsa() || rigadoc.is_attrezzatura())
|
||
{
|
||
const char tipo = rigadoc.tipo().tipo();
|
||
const TSpesa_prest spp(rigadoc.get(RDOC_CODART), tipo);
|
||
conto_anal = tipocf == 'F' ? spp.conto_analitico_acquisti() : spp.conto_analitico_vendite();
|
||
}
|
||
}
|
||
tmpcurr.put("CONTO", conto_anal);
|
||
}
|
||
|
||
//comincia a riempire i record
|
||
//prima i campi che prende direttamente dal doc speciale
|
||
tmpcurr.put("CODNUM", doc->get(DOC_CODNUM));
|
||
tmpcurr.put("ANNO", doc->get(DOC_ANNO));
|
||
tmpcurr.put("NUMRD", doc->get(DOC_NDOC));
|
||
tmpcurr.put("DATA", doc->get(DOC_DATADOC));
|
||
tmpcurr.put("NUMDOCRIF", doc->get(DOC_NUMDOCRIF)); //docrif del documento
|
||
tmpcurr.put("DATADOCRIF", doc->get(DOC_DATADOCRIF)); //datadocrif del documento
|
||
tmpcurr.put("NUMREG", doc->get(DOC_NUMREGCA));
|
||
tmpcurr.put("NUMREGCG", doc->get(DOC_NUMREG)); //numero di registrazione contabile
|
||
tmpcurr.put("NRIGA", rigadoc.get(RDOC_NRIGA)); //numero riga
|
||
|
||
//procedura per ottenere i campi del documento origine di quello in esame
|
||
const int tipo_documento = doc->tipo_riclassificato();
|
||
int tipo_babbo = TTipo_documento::_altro;
|
||
|
||
TToken_string riferimento(20, '\n'); //tokenstring su cui scrivere gli estremi dei docs padri (se li trova!)
|
||
TString80 rif; //stringa di lavoro su cui viene scritto un doc originale
|
||
const int rows = doc->physical_rows(); //righe del doc attuale
|
||
|
||
const TRectype* babbo = rigadoc.find_original_rdoc(); //cerca il doc padre della riga doc attuale
|
||
if (babbo != NULL) //se trova il doc padre..
|
||
{
|
||
const TString4 babbo_codnum = babbo->get(RDOC_CODNUM);
|
||
const int anno = babbo->get_int(RDOC_ANNO);
|
||
const long ndoc = babbo->get_long(RDOC_NDOC);
|
||
rif.cut(0) << babbo_codnum << '-' << anno << '-' << ndoc;
|
||
tmpcurr.put("DOCORIG", rif); //documento di riferimento (mitologico documento originale)
|
||
} //if (babbo != NULL)..
|
||
|
||
const real importo = rigadoc.imponibile();
|
||
const TTipo_documento& tipodoc = doc->tipo();
|
||
const TString& codcaus = tipodoc.causale();
|
||
if (codcaus.full())
|
||
{
|
||
TImporto imp(tipocf == 'F' ? 'D' : 'A', importo);
|
||
const int anno_caus = doc->get_int(DOC_ANNO);
|
||
TCausale caus(codcaus, anno_caus);
|
||
TipoIVA tipoiva = caus.iva();
|
||
char sezione_normale;
|
||
|
||
if (tipoiva == iva_vendite)
|
||
sezione_normale = 'A';
|
||
else
|
||
{
|
||
if (tipoiva == iva_acquisti)
|
||
sezione_normale = 'D';
|
||
else
|
||
{
|
||
if (caus.sezione_clifo() == 'D')
|
||
sezione_normale = 'A';
|
||
else
|
||
sezione_normale = 'D';
|
||
}
|
||
}
|
||
|
||
imp.normalize(sezione_normale);
|
||
//i documenti speciali vanno SOLO in FATTURATO
|
||
tmpcurr.put("FATTURATO", imp.valore());
|
||
}
|
||
else
|
||
{
|
||
//i documenti speciali vanno SOLO in FATTURATO
|
||
tmpcurr.put("FATTURATO", importo);
|
||
}
|
||
|
||
_tmp->write();
|
||
|
||
} //if(special_docs...
|
||
} // for (inti=1;i<=rows...
|
||
}
|
||
|
||
|
||
//scanning delle righe dei movimenti di analitica
|
||
void TPrint_rendiconto_ca_recordset::crea_righe_da_rmovana()
|
||
{
|
||
TRelation rel_rmovana(LF_RMOVANA);
|
||
rel_rmovana.add(LF_MOVANA, "NUMREG==NUMREG"); //aggiunge le testate x avere tipi mov e descr
|
||
|
||
//..crea un cursore su rmovana per vedere se i conti selezionati hanno veri movimenti che soddisfano
|
||
//i parametri del filtro sulla maschera. ACHTUNG! Questo filtro ha senso solo se non esiste la
|
||
//riclassificazione!!!
|
||
TRectype da_rmovana(LF_RMOVANA);
|
||
TRectype a_rmovana(LF_RMOVANA);
|
||
if (!_riclassificato)
|
||
{
|
||
da_rmovana.put(RMOVANA_CODCONTO, _daconto);
|
||
a_rmovana.put(RMOVANA_CODCONTO, _aconto);
|
||
}
|
||
|
||
TString filtro;
|
||
|
||
if (_dadata.ok())
|
||
filtro << "(ANSI(DATACOMP)>=" << _dadata.date2ansi() << ")";
|
||
if (_adata.ok())
|
||
{
|
||
if (filtro.not_empty())
|
||
filtro << "&&";
|
||
|
||
filtro << "(ANSI(DATACOMP)<=" << _adata.date2ansi() << ")";
|
||
}
|
||
|
||
if (_codcosto.not_empty())
|
||
{
|
||
if (filtro.not_empty())
|
||
filtro << "&&";
|
||
filtro << "(" << RMOVANA_CODCCOSTO << "?=\"" << _codcosto << "*\")";
|
||
}
|
||
if (_codcms.not_empty())
|
||
{
|
||
if (filtro.not_empty())
|
||
filtro << "&&";
|
||
filtro << "(" << RMOVANA_CODCMS << "?=\"" << _codcms << "*\")";
|
||
}
|
||
if (_codfas.not_empty())
|
||
{
|
||
if (filtro.not_empty())
|
||
filtro << "&&";
|
||
filtro << "(" << RMOVANA_CODFASE << "?=\"" << _codfas << "*\")";
|
||
}
|
||
|
||
TCursor cur_rmovana(&rel_rmovana, filtro, 2, &da_rmovana, &a_rmovana);
|
||
const TRecnotype rmovana_items = cur_rmovana.items();
|
||
//scorre le righe movimenti di analitica che soddisfano il filtro
|
||
//il join a movana serve nel caso necessitino dati di testata per la riga in questione
|
||
if (rmovana_items > 0)
|
||
{
|
||
cur_rmovana.freeze();
|
||
const TRectype& rmovana = cur_rmovana.curr();
|
||
const TRectype& movana = rel_rmovana.curr(LF_MOVANA);
|
||
TProgind pi(rmovana_items, "Scansione righe movimenti...", true, true);
|
||
for (cur_rmovana = 0; cur_rmovana.pos() < rmovana_items; ++cur_rmovana)
|
||
{
|
||
pi.addstatus(1);
|
||
if (pi.iscancelled())
|
||
break;
|
||
scrive_riga(rmovana, movana, NULL);
|
||
}
|
||
}
|
||
}
|
||
|
||
//scanning delle righe dei documenti
|
||
void TPrint_rendiconto_ca_recordset::crea_righe_da_rdoc(const TPrint_rendiconto_ca_mask& msk)
|
||
{
|
||
TRelation rel_rdoc(LF_RIGHEDOC);
|
||
rel_rdoc.add(LF_DOC, "CODNUM==CODNUM|ANNO==ANNO|PROVV==PROVV|NDOC==NDOC"); //aggiunge le testate
|
||
|
||
TRectype dardoc(LF_RIGHEDOC);
|
||
TRectype ardoc(LF_RIGHEDOC);
|
||
TString filtro_date;
|
||
|
||
dardoc.put(RDOC_PROVV, 'D');
|
||
ardoc.put(RDOC_PROVV, 'D');
|
||
|
||
//se siamo fortunati l'anno si pu<70> trovare cos<6F>..
|
||
int anno = msk.get_int(F_ANNO);
|
||
if (anno > 0)
|
||
{
|
||
dardoc.put(RDOC_ANNO, anno);
|
||
ardoc.put(RDOC_ANNO, anno);
|
||
}
|
||
else
|
||
{
|
||
dardoc.put(RDOC_ANNO, _dadata.year());
|
||
ardoc.put(RDOC_ANNO, _adata.year());
|
||
if (_dadata.year() == _adata.year())
|
||
anno = _dadata.year();
|
||
}
|
||
|
||
if (_dadata.ok())
|
||
filtro_date << "(ANSI(33->DATADOC)>=" << _dadata.date2ansi() << ")";
|
||
if (_adata.ok())
|
||
{
|
||
if (filtro_date.not_empty())
|
||
filtro_date << "&&";
|
||
|
||
filtro_date << "(ANSI(33->DATADOC)<=" << _adata.date2ansi() << ")";
|
||
}
|
||
|
||
TContabilizzazione_analitica cont_anal; //oggetto necessario per contabilizzare il documento in osservazione
|
||
|
||
//inizialmente il filtro di scansione delle righedoc coincide con quello sulle date
|
||
TString filtro = filtro_date;
|
||
|
||
//Controlla sul file di configurazione di CA (ditta.ini,[ca]) se esistono numerazioni relative
|
||
//..alle fatture da ricevere che devono essere trattate in modo particolare
|
||
TConfig& config = ca_config();
|
||
|
||
//TString_array contenente le numerazioni delle fatture da ricevere
|
||
TString_array num_fdr;
|
||
for (int j = 0;;j++)
|
||
{
|
||
TString codfdr(config.get("NF", NULL, j)); //scansione delle righe NF(i)=.. sul paragrafo di configurazione CA
|
||
if (codfdr.blank())
|
||
break;
|
||
num_fdr.add(codfdr);
|
||
}
|
||
|
||
//Filtro sulle righe documento (e testate collegate)
|
||
//Controlla sul file di configurazione di CA (ditta.ini,[ca]) se esistono numerazioni da escludere..
|
||
//..e se, per alcune numerazioni, deve tener conto dello stato del documento
|
||
bool update = false;
|
||
for (int i = 0;;i++) //scansione delle righe ND(i)=.. sul paragrafo di configurazione CA
|
||
{
|
||
TToken_string num_doc(config.get("ND", NULL, i));
|
||
|
||
const TString4 codnum = num_doc.get(0);
|
||
if (codnum.blank())
|
||
break;
|
||
|
||
const bool exclude = num_doc.get_char(1) == 'X';
|
||
if (filtro.not_empty())
|
||
filtro << "&&";
|
||
if (exclude) //numerazioni da escludere
|
||
{
|
||
filtro << "(CODNUM!=\"" << codnum << "\")";
|
||
}
|
||
else //numerazioni per le quali tener conto dello stato
|
||
{
|
||
filtro << "((CODNUM!=\"" << codnum << "\")";
|
||
filtro << "||((" << LF_DOC << "->STATO>=\"" << num_doc.get(2) << "\")";
|
||
filtro << "&&(" << LF_DOC << "->STATO<=\"" << num_doc.get(3) << "\")))";
|
||
update = true;
|
||
}
|
||
}
|
||
|
||
//poi deve aggiungere il filtro per cdc/cms/fas
|
||
if (_codcosto.not_empty())
|
||
{
|
||
if (filtro.not_empty())
|
||
filtro << "&&";
|
||
filtro << "(" << RDOC_CODCOSTO << "==\"" << _codcosto << "\")";
|
||
}
|
||
if (_codcms.not_empty())
|
||
{
|
||
if (filtro.not_empty())
|
||
filtro << "&&";
|
||
filtro << "(" << RDOC_CODCMS << "==\"" << _codcms << "\")";
|
||
}
|
||
if (_codfas.not_empty())
|
||
{
|
||
if (filtro.not_empty())
|
||
filtro << "&&";
|
||
filtro << "(" << RDOC_FASCMS << "==\"" << _codfas << "\")";
|
||
}
|
||
|
||
//il filtro <20> completo;pu<70> eseguire la scansione
|
||
TCursor cur_rdoc(&rel_rdoc, "", 3, &dardoc, &ardoc);
|
||
cur_rdoc.setfilter(filtro, update);
|
||
|
||
const TRecnotype rdoc_items = cur_rdoc.items();
|
||
if (rdoc_items > 0)
|
||
{
|
||
cur_rdoc.freeze();
|
||
TProgind pi(rdoc_items, "Scansione righe documenti...", true, true);
|
||
|
||
//memorizza l'ultimo doc per evitare doppioni in caso di doc con pi<70> righe (rielaborerebbe..
|
||
//..lo stesso documento tante volte quante sono le sue righe!)
|
||
TString old_key;
|
||
//scanning del file dei documenti alla ricerca di quelli che hanno la data ed il CODNUM
|
||
//validi nei filtri impostati dall'utente
|
||
for (cur_rdoc = 0; cur_rdoc.pos() < rdoc_items; ++cur_rdoc)
|
||
{
|
||
pi.addstatus(1);
|
||
if (pi.iscancelled())
|
||
break;
|
||
|
||
//La riga esaminata deve avere una testata valida!!!!Se la testata non esiste va saltata..
|
||
//..la riga
|
||
const TRectype& curr_doc = cur_rdoc.curr(LF_DOC);
|
||
if (!curr_doc.empty())
|
||
{
|
||
//controlla se il documento cui appartiene la rigadoc e' stato contabilizzato;
|
||
//se e' stato contabilizzato lo salta in quanto la riga documento apparira' attraverso le righe
|
||
//dei movimenti di analitica
|
||
const long numregca = curr_doc.get_long(DOC_NUMREGCA);
|
||
|
||
//**Modifca richiesta dal CRPA!Le righe documento che hanno DACODNUM di tipo fattura da..
|
||
//..ricevere/emettere, vanno ri-contabilizzate lo stesso anche se lo sono gia' state. Il loro..
|
||
//..importo verra' poi messo nel fatturato.
|
||
const TRectype& curr_rdoc = cur_rdoc.curr();
|
||
const TString& rdoc_dacodnum = curr_rdoc.get(RDOC_DACODNUM);
|
||
const bool is_special_doc = num_fdr.find(rdoc_dacodnum) > 0;
|
||
//documento non contabilizzato o fattura da ricevere con numerazione configurata speciale
|
||
if (numregca == 0 || is_special_doc)
|
||
{
|
||
const TString curr_key = curr_doc.build_key();
|
||
if (curr_key == old_key)
|
||
continue;
|
||
else
|
||
old_key = curr_key;
|
||
|
||
TDocumento doc(curr_doc);
|
||
TAnal_mov mov;
|
||
|
||
if (numregca == 0)
|
||
{
|
||
cont_anal.elabora(doc, 0, NULL, false, mov);
|
||
|
||
//estrae il tipo ed il codice clifo dal documento per metterlo nel movana che ha generato
|
||
//con la elabora (richiesta puramente adolfica!)
|
||
TString16 key;
|
||
key << doc.get(DOC_TIPOCF) << '|' << doc.get(DOC_CODCF);
|
||
const TString clifo = cache().get(LF_CLIFO, key, CLI_RAGSOC);
|
||
mov.put(MOVANA_DESCR, clifo);
|
||
|
||
for (int j = 1; j <= mov.rows(); j++)
|
||
{
|
||
//controlla che la riga in esame abbia realmente la cms/cdc/fas indicata nel filtro;
|
||
//procedimento necessario per evitare la stampa di righe appartenenti a docs elaborati
|
||
//perch<63> contenenti 1 riga con cms corretta ed altre righe con cms sbagliate
|
||
const TRectype& rmov = mov.body()[j];
|
||
|
||
if (_codcms.not_empty() && rmov.get(RMOVANA_CODCMS) != _codcms)
|
||
continue;
|
||
if (_codcosto.not_empty() && rmov.get(RMOVANA_CODCCOSTO) != _codcosto)
|
||
continue;
|
||
if (_codfas.not_empty() && rmov.get(RMOVANA_CODFASE) != _codfas)
|
||
continue;
|
||
scrive_riga(rmov, mov, &doc); //documenti "normali"
|
||
} //for int j...
|
||
}
|
||
//righe di documento configurate come da emettere/ricevere
|
||
if (is_special_doc)
|
||
scrive_riga_speciale(&doc, num_fdr);
|
||
} //if (numregca==0...
|
||
|
||
} //if !curr_doc.empty()
|
||
//Ha trovato una riga senza testata! non puo' considerarla ma avverte l'utente del problema
|
||
else
|
||
{
|
||
const TRectype& bad_row = cur_rdoc.curr();
|
||
const TString4 bad_codnum = bad_row.get(RDOC_CODNUM);
|
||
const int bad_anno = bad_row.get_int(RDOC_ANNO);
|
||
const long bad_ndoc = bad_row.get_long(RDOC_NDOC);
|
||
const int bad_nriga = bad_row.get_int(RDOC_NRIGA);
|
||
TString error_string;
|
||
error_string << bad_codnum << "|" << bad_anno << "|D|" << bad_ndoc << "|" << bad_nriga;
|
||
warning_box("Riga documento %s priva di testata!", (const char*)error_string);
|
||
}
|
||
} //for cur_rdoc..
|
||
} //if rdoc_items
|
||
|
||
}
|
||
|
||
|
||
void TPrint_rendiconto_ca_recordset::crea_trr(const TFilename& trr) const
|
||
{
|
||
ofstream of(trr);
|
||
of << 1000 << endl;
|
||
of << 18 << endl;
|
||
of << "CONTO|1|20|0|Conto analitico" << endl;
|
||
of << "DATA|5|8|0|Data movimento o documento" << endl;
|
||
of << "CODNUM|1|4|0|Numerazione documento" << endl;
|
||
of << "NUMRD|3|7|0|Numero registrazione contabile o numero documento di origine" << endl;
|
||
of << "NRIGA|2|3|0|Riga movimento o documento" << endl;
|
||
of << "NUMREG|3|7|0|Numero registrazione del movimento analitico" << endl;
|
||
of << "NUMREGCG|3|7|Numero registrazione contabile" << endl;
|
||
of << "ANNO|9|4|0|Anno" << endl;
|
||
of << "NUMDOCRIF|1|7|0|Numero documento riferimento" << endl;
|
||
of << "DATADOCRIF|5|8|0|Data documento riferimento" << endl;
|
||
of << "DESC|1|50|0|Descrizione movimento o documento" << endl;
|
||
of << "DESCRIGA|1|50|0|Descrizione riga movimento o documento" << endl;
|
||
of << "DOCORIG|11|10|0|Riferimenti ordine/bolla" << endl;
|
||
of << "FATTURATO|4|18|5|Fatturato" << endl;
|
||
of << "MATURATO|4|18|5|Maturato" << endl;
|
||
of << "IMPEGNATO|4|18|5|Impegnato" << endl;
|
||
of << "CONTOCG|1|12|0|Conto contabile" << endl;
|
||
of << "HIDDEN|8|1|0|Record nascosto" << endl;
|
||
of << 1 << endl;
|
||
of << "CONTO+DATA+CODNUM+NUMRD+NRIGA" << endl;
|
||
}
|
||
|
||
void TPrint_rendiconto_ca_recordset::set_filter(const TPrint_rendiconto_ca_mask& msk, int cms_row)
|
||
{
|
||
//se esiste il file temporano con tracciato persomalizzato lo cancella e lo ricrea vuoto
|
||
TFilename trr; //file tracciato record
|
||
trr.tempdir();
|
||
trr.add("rendy");
|
||
TFilename dbf(trr); //file dati
|
||
|
||
trr.ext("trr");
|
||
dbf.ext("dbf");
|
||
|
||
//crea il file .trr in base ai parametri del metodo
|
||
crea_trr(trr);
|
||
//svuota la memoria dal vecchio file temporaneo
|
||
if (_tmp != NULL)
|
||
delete _tmp;
|
||
|
||
//crea in memoria il nuovo file temporaneo e lo azzera (non si sa mai..)
|
||
_tmp = new TExternisamfile(dbf, trr);
|
||
_tmp->zap();
|
||
|
||
//prende un po' di dati dalla maschera...
|
||
_piano, _daconto, _aconto, _codcosto, _codcms, _codfas = "";
|
||
if (cms_row >= 0)
|
||
{
|
||
TSheet_field& sf = msk.sfield(F_RIGHE);
|
||
TMask& sm = sf.sheet_mask();
|
||
sf.update_mask(cms_row);
|
||
TRelation rel(LF_RMOVANA);
|
||
sm.autosave(rel);
|
||
_codcosto = rel.curr().get(RMOVANA_CODCCOSTO);
|
||
_codcms = rel.curr().get(RMOVANA_CODCMS);
|
||
_codfas = rel.curr().get(RMOVANA_CODFASE);
|
||
}
|
||
|
||
const char tc = msk.get(F_PIANO)[0]; // Piano dei conti 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;
|
||
|
||
//si utilizza la riclassificazione dei conti?
|
||
|
||
_piano = msk.get(F_PIANO);
|
||
if (_piano == "A")
|
||
{
|
||
TConfig& cfg = ca_config();
|
||
const bool use_pdcc = cfg.get_bool("UsePdcc");
|
||
_riclassificato = use_pdcc;
|
||
}
|
||
else
|
||
_riclassificato = false;
|
||
|
||
for (int i = 0; i < 4 && msk.id2pos(dlg_da+i) > 0; i++)
|
||
{
|
||
_daconto << msk.get(dlg_da+i);
|
||
_aconto << msk.get(dlg_al+i);
|
||
}
|
||
|
||
_dadata = msk.get_date(F_DATAINI);
|
||
_adata = msk.get_date(F_DATAFIN);
|
||
|
||
if (_riclassificato)
|
||
{
|
||
//esiste un prefisso a pi<70> livelli?
|
||
for (short id = F_PRE1; id <= F_PRE3 && msk.id2pos(id) > 0; id++)
|
||
{
|
||
const TString& pr = msk.get(id);
|
||
if (pr.not_empty())
|
||
_prefix << pr;
|
||
else
|
||
break;
|
||
}
|
||
}
|
||
//metodi per riempire il file da cui generare il report
|
||
//dati estratti dalle righe movimenti di contabilita' analitica
|
||
crea_righe_da_rmovana();
|
||
//dati estratti dalle righe documenti
|
||
crea_righe_da_rdoc(msk);
|
||
|
||
}
|
||
|
||
////////////////////////////////////////////////////////
|
||
// REPORT
|
||
////////////////////////////////////////////////////////
|
||
class TPrint_rendiconto_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_rendiconto_ca_mask& msk, int cms_row);
|
||
};
|
||
|
||
bool TPrint_rendiconto_ca_rep::get_usr_val(const TString& name, TVariant& var) const
|
||
{
|
||
return TAnal_report::get_usr_val(name, var);
|
||
}
|
||
|
||
bool TPrint_rendiconto_ca_rep::set_recordset(const TString& sql)
|
||
{
|
||
TPrint_rendiconto_ca_recordset* rs = new TPrint_rendiconto_ca_recordset(sql);
|
||
return TAnal_report::set_recordset(rs);
|
||
}
|
||
|
||
void TPrint_rendiconto_ca_rep::set_filter(const TPrint_rendiconto_ca_mask& msk, int cms_row)
|
||
{
|
||
TAnal_report::set_recordset(NULL); // Forza azzeramento file Rendy.dbf prima di ricostruirlo
|
||
|
||
const char* query ="USE 1000\nJOIN MOVANA INTO NUMREG==NUMRD\nJOIN RMOVANA INTO NUMREG==NUMRD NUMRIG==NRIGA";
|
||
|
||
TPrint_rendiconto_ca_recordset* recset = new TPrint_rendiconto_ca_recordset(query);
|
||
|
||
recset->set_filter(msk, cms_row);
|
||
TAnal_report::set_recordset(recset);
|
||
}
|
||
|
||
////////////////////////////////////////////////////////
|
||
// APPLICAZIONE
|
||
////////////////////////////////////////////////////////
|
||
class TPrint_rendiconto_ca : public TSkeleton_application
|
||
{
|
||
public:
|
||
const TMultilevel_code_info& get_first_level() const;
|
||
virtual void main_loop();
|
||
};
|
||
|
||
//metodo per accattarsi o' primo livello della configurazione CA
|
||
const TMultilevel_code_info& TPrint_rendiconto_ca::get_first_level() const
|
||
{
|
||
TConfig& cfg = ca_config();
|
||
const TString& first_lev = cfg.get("Level(1)");
|
||
const int logic = first_lev == "CDC" ? LF_CDC : LF_COMMESSE;
|
||
return ca_multilevel_code_info(logic);
|
||
}
|
||
|
||
|
||
void TPrint_rendiconto_ca::main_loop()
|
||
{
|
||
TPrint_rendiconto_ca_mask mask;
|
||
while (mask.run() == K_ENTER)
|
||
{
|
||
//report e book dei report
|
||
TReport_book book;
|
||
TString path = mask.get(F_REPORT);
|
||
if (path.empty())
|
||
path = "ca3700a";
|
||
TPrint_rendiconto_ca_rep rep;
|
||
rep.load(path);
|
||
|
||
TSheet_field& sheet = mask.sfield(F_RIGHE);
|
||
TString video_string; //stringa che compare nella progind
|
||
if (sheet.empty()) //se non ci sono righe sullo sheet (selezione su tutte le cms/cdc)...
|
||
{
|
||
TToken_string& row = sheet.row(-1); //crea la prima riga dello sheet
|
||
|
||
const TMultilevel_code_info& liv1 = get_first_level(); //stabilisce quale <20> il primo livello (tra CDC e CMS)..
|
||
TISAM_recordset set(liv1.logic() == LF_CDC ? "USE CDC" : "USE COMMESSE"); //..e di conseguenza scrive la use giusta
|
||
|
||
TProgind pi(set.items(), video_string, true, true);
|
||
for (int i = 0; set.move_to(i); i++) //fighissimo metodo per scandire un file in 1 riga!
|
||
{
|
||
pi.addstatus(1);
|
||
if (pi.iscancelled())
|
||
break;
|
||
row = set.get((unsigned int)0).as_string(); //prende il valore del primo campo del file (CDC o CMS code)
|
||
|
||
video_string = TR("Scansione");
|
||
video_string << " " << row; //completa la stringa da visualizzare sulla progind
|
||
pi.set_text(video_string);
|
||
|
||
for (int l = liv1.levels()-2; l >= 0; l--) //se la struttura <20> a pi<70> livelli costruisce la tokenstring
|
||
row.insert("|", liv1.total_len(l));
|
||
|
||
rep.set_filter(mask, 0); //fa la set filter sulla prima riga (che <20> quella usata)
|
||
book.add(rep);
|
||
}
|
||
sheet.destroy(); //cancella le commesse aggiunte in automatico sullo sheet
|
||
}
|
||
else //se ha almeno una riga sullo sheet delle cms/cdc...
|
||
{
|
||
FOR_EACH_SHEET_ROW(sheet, r, row) //per ogni cdc/cms che appare nello sheet di pag.1 della msk..
|
||
{
|
||
rep.set_filter(mask, r); //..chiama il metodone globale che crea e compila il file..
|
||
//..temporaneo i cui dati riempiranno il report
|
||
book.add(rep); //aggiunge il report relativo alla cdc/cms corrente al book
|
||
}
|
||
}
|
||
|
||
book.print_or_preview(); //stampa il book dei report
|
||
}
|
||
}
|
||
|
||
int ca3700(int argc, char* argv[])
|
||
{
|
||
TPrint_rendiconto_ca a;
|
||
a.run(argc, argv, TR("Stampa rendiconto"));
|
||
return 0;
|
||
}
|