Patch level :10.0

Files correlati     :
Ricompilazione Demo : [ ]
Commento            :
prima stesura del programma di generazione rendiconto sintetico in formato excel (funziona per ora SOLO in configurazione dinamica/crpa)


git-svn-id: svn://10.65.10.50/trunk@18650 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
luca 2009-04-01 10:12:25 +00:00
parent 5a25b2949f
commit e9fbb16d39
3 changed files with 256 additions and 32 deletions

View File

@ -9,6 +9,7 @@
#include "../cg/cglib01.h"
#include "../ve/velib04.h"
#include "commesse.h"
#include "panapdc.h"
#include "pconana.h"
#include "movana.h"
@ -146,6 +147,14 @@ bool TPrint_rendiconto_ca_mask::on_field_event(TOperable_field& o, TField_event
return false;
}
break;
case DLG_EXPORT:
if (e == fe_button)
{
TString path = get(F_PATH);
if (path.empty())
return error_box(TR("Specificare una cartella dove creare il file rendiconto.xls!"));
}
break;
default:
break;
}
@ -260,6 +269,7 @@ protected:
int _anno;
TString4 _piano;
TDate _dadata, _adata;
bool _vitaintera;
long _danumreg, _anumreg;
TString _daconto, _aconto, _codcosto, _codcms, _codfas;
@ -339,7 +349,7 @@ void TPrint_rendiconto_ca_recordset::set_custom_filter(TCursor& cur) const
if (_dadata.ok())
filtro << "(ANSI(DATA)>=" << _dadata << ")";
if (_adata.ok())
if (_adata.ok() && !_vitaintera) //se vitaintera non si può avere una data limite superiore
{
if (filtro.not_empty())
filtro << "&&";
@ -476,7 +486,7 @@ const TVariant& TPrint_rendiconto_ca_recordset::get(const char* column_name) con
int TPrint_rendiconto_ca_recordset::sort_indbil(int indbil) const
{
if (_reverse_cos_ric) //sono del CRPA/CSA
if (_reverse_cos_ric) //sono del CRPA/DINAMICA
{
if (indbil == 3 || indbil == 4)
indbil = 7 - indbil;
@ -592,13 +602,13 @@ void TPrint_rendiconto_ca_recordset::scrive_riga(const TRectype& rmovana, const
TString codcontocg;
int indbil = 0;
bool conto_non_riclass = false; //indicatore che serve per tener conto di specialissimi conti del CRPA...
//E' una lampante dimostrazione di quanto sia generico questo programma...
//E' una lampante dimostrazione di quanto sia generico questo programma...
// il conto puo' essere analitico o contabile...
//se è compilato l'archivio di collegamento PANAPDC..
//..si deve usare come conto il campo codconto del panapdc!!!...
//Ricordare che SOLO se si ha un conto contabile e' possibile riclassificare in analitico!!!
if (_riclassificato) //traduzione:sei il CRPA/CSA
if (_riclassificato) //traduzione:sei il CRPA/DINAMICA
{
//stringa che conterrà il conto riclassificato (se sara' trovato)
const TString conto_riclassificato = riclassifica(codconto, tmpcurr);
@ -900,11 +910,14 @@ F=IMF*/
tmpcurr.put("ORDCONT", ordcont);
//----Scrittura dati riga movimento----//
tmpcurr.put("NUMREG", rmovana.get(RMOVANA_NUMREG));
tmpcurr.put("NUMREG", rmovana.get(RMOVANA_NUMREG)); //numero di registrazione analitica
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("DESC", descr); //descrizione movana
tmpcurr.put("NRIGA", rmovana.get(RMOVANA_NUMRIG)); //numero riga
tmpcurr.put("DESCRIGA", rmovana.get(RMOVANA_DESCR)); //descrizione rmovana
tmpcurr.put("CODCMS", rmovana.get(RMOVANA_CODCMS)); //codice commessa
tmpcurr.put("CODCOSTO", rmovana.get(RMOVANA_CODCCOSTO)); //codice cdc
tmpcurr.put("CODFASE", rmovana.get(RMOVANA_CODFASE)); //codice fase
if (should_delete)
delete newdoc;
@ -1009,15 +1022,19 @@ void TPrint_rendiconto_ca_recordset::scrive_riga_speciale(const TDocumento* doc,
//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("CODNUM", doc->get(DOC_CODNUM)); //numerazione doc speciale
tmpcurr.put("ANNO", doc->get(DOC_ANNO)); //anno doc speciale
tmpcurr.put("NUMRD", doc->get(DOC_NDOC)); //numero del doc speciale
tmpcurr.put("DATA", doc->get(DOC_DATADOC)); //data del doc speciale
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
tmpcurr.put("NUMREG", doc->get(DOC_NUMREGCA)); //numero di registrazione analitica
tmpcurr.put("NUMREGCG", doc->get(DOC_NUMREG)); //numero di registrazione contabile
tmpcurr.put("NRIGA", rigadoc.get(RDOC_NRIGA)); //numero riga
tmpcurr.put("CODCMS", rigadoc.get(RDOC_CODCMS)); //codice commessa
tmpcurr.put("CODCOSTO", rigadoc.get(RDOC_CODCOSTO)); //codice cdc
tmpcurr.put("CODFASE", rigadoc.get(RDOC_FASCMS)); //codice fase
//procedura per ottenere i campi del documento origine di quello in esame
const int tipo_documento = doc->tipo_riclassificato();
@ -1105,7 +1122,7 @@ void TPrint_rendiconto_ca_recordset::crea_righe_da_rmovana()
if (_dadata.ok())
filtro << "(ANSI(DATACOMP)>=" << _dadata.date2ansi() << ")";
if (_adata.ok())
if (_adata.ok() && !_vitaintera) //se vitaintera non si può avere una data limite superiore
{
if (filtro.not_empty())
filtro << "&&";
@ -1229,7 +1246,7 @@ void TPrint_rendiconto_ca_recordset::crea_righe_da_rdoc(const TPrint_rendiconto_
if (_dadata.ok())
filtro_date << "(ANSI(33->DATADOC)>=" << _dadata.date2ansi() << ")";
if (_adata.ok())
if (_adata.ok() && !_vitaintera) //se vitaintera non si può avere una data limite superiore
{
if (filtro_date.not_empty())
filtro_date << "&&";
@ -1410,13 +1427,16 @@ void TPrint_rendiconto_ca_recordset::crea_trr(const TFilename& trr) const
{
ofstream of(trr);
of << 1000 << endl;
of << 19 << endl;
of << 22 << endl;
of << "ORDCONT|1|1|0|Ordinatore in base a indicatore di bilancio" << 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 << "CODCMS|1|20|0|Codice commessa" << endl;
of << "CODCOSTO|1|20|0|Codice centro di costo" << endl;
of << "CODFASE|1|20|0|Codice fase (eventualmente legato a CODCMS)" << 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;
@ -1509,10 +1529,10 @@ void TPrint_rendiconto_ca_recordset::set_filter(const TPrint_rendiconto_ca_mask&
//sei al CRPA e vuoi implodere le righemovana ripartite in precedenza?
_implode_rows = msk.get_bool(F_IMPLODE_ROWS);
//c'e' un fottuto range di date?
//c'e' un fottuto range di date? oppure si va a vita intera?
_dadata = msk.get_date(F_DATAINI);
_adata = msk.get_date(F_DATAFIN);
_vitaintera = msk.get_bool(F_VITAINTERA);
//metodi per riempire il file da cui generare il report
//dati estratti dalle righe movimenti di contabilita' analitica
@ -1570,6 +1590,8 @@ protected:
void print_or_preview(bool pr);
virtual void print() { print_or_preview(true); }
virtual void preview() { print_or_preview(false); }
void esporta_csv(TMask& mask, TRecordset& rendy, const TString& codcms, const TString& cdc, const TString& codfase);
void incrementa(TToken_string& riga, const int col, const real& valore) const;
public:
const TMultilevel_code_info& get_first_level() const;
@ -1582,6 +1604,82 @@ void TPrint_rendiconto_ca::print_or_preview(bool pr)
_msk->send_key(K_SPACE, pr ? DLG_PRINT : DLG_PREVIEW);
}
void TPrint_rendiconto_ca::incrementa(TToken_string& riga, const int col, const real& valore) const
{
real r; riga.get(col, r);
r += valore;
riga.add(r.string(), col);
}
//metodo di alto livello per l'esportazione dei dati di totale in un file per excel
void TPrint_rendiconto_ca::esporta_csv(TMask& mask, TRecordset& rendy,
const TString& codcms, const TString& cdc, const TString& codfase)
{
//crea una token string su cui mettere i valori dei record letti dal file .dbf
TToken_string riga(512, '\t');
riga.add(codcms);
riga.add(cache().get(LF_COMMESSE, codcms, COMMESSE_DESCRIZ));
riga.add(cdc);
riga.add(codfase);
//recordset sul file .dbf, da scandire tutto uno per volta
for (bool ok = rendy.move_first(); ok; ok = rendy.move_next())
{
const int indbil = rendy.get("ORDCONT").as_int();
const bool budget = rendy.get("HIDDEN").as_bool();
const real impegnato = rendy.get("IMPEGNATO").as_real();
const real fatturato = rendy.get("FATTURATO").as_real();
const real maturato = rendy.get("MATURATO").as_real();
//in base al valore di indbil e budget i valori degli importi vengono posizionati nel record
int col;
switch (indbil)
{
case 1: col = 18; break; //attività
case 2: col = 25; break; //passività
case 3: col = 4; break; //costi
case 4: col = 11; break; //ricavi
}
//simpatico metodo algoritmico per stabilire la colonna iniziale di sezione, invalidato da richieste dinamica/crpa
//const int col = 4 + (7*(indbil-1));
//lo schema è questo: budget\impegnato\fatturato\maturato\da impegnare\da fatturare\da maturare
if (budget)
{
incrementa(riga, col, impegnato);
}
else
{
incrementa(riga, col + 1, impegnato);
incrementa(riga, col + 2, fatturato);
incrementa(riga, col + 3, maturato);
//il da maturare è più incasinato, perchè deve tener conto di valori già totalizzati sulla riga
const real imp_budget = riga.get(col);
const real imp_consuntivo = riga.get(col + 1);
const real da_impegnare = imp_budget - imp_consuntivo;
riga.add(da_impegnare.string(), col + 4); //da impegnare
incrementa(riga, col + 5, impegnato - fatturato); //da fatturare
incrementa(riga, col + 6, impegnato - maturato); //da maturare
}
} //for (bool ok = rendy.move_first()...
for (int i = 4; i < 32; i++)
{
const real r = riga.get(i);
if (!r.is_zero())
riga.add(r.stringe(), i);
}
//aggiorna il file da esportare appendendo la nuova riga
TFilename path = mask.get(F_PATH);
path.lower();
path.add("rendiconto.xls");
ofstream file_to_date(path, ios::app);
file_to_date << riga << endl;
}
//metodo per accattarsi o' primo livello della configurazione CA
const TMultilevel_code_info& TPrint_rendiconto_ca::get_first_level() const
{
@ -1596,8 +1694,83 @@ void TPrint_rendiconto_ca::main_loop()
_msk = new TPrint_rendiconto_ca_mask;
TPrint_rendiconto_ca_mask& mask = *_msk;
while (mask.run() == K_ENTER)
while (true)
{
//il programma deve cominciare l'eleaborazione solo nel caso di Stampa/Anteprima (K_ENTER) o Esportazione CSV (K_F6)
KEY key = mask.run();
if (key != K_ENTER && key != K_F6)
break;
//resetta e prepara le intestazioni del file rendiconto.xls
if (key == K_F6)
{
TFilename file_xls = mask.get(F_PATH);
file_xls.lower();
file_xls.add("rendiconto.xls");
ofstream file_to_date(file_xls);
//intestazione primaria
TToken_string intestazione_1(512, '\t');
intestazione_1.add("Commessa");
intestazione_1.add("Descr. commessa");
intestazione_1.add("C.d.C.");
intestazione_1.add("Fase");
const bool reverse_cos_ric = mask.get_bool(F_REV_COSRIC); //occhio al flag di rovesciamento
for (int i = 0; i < 4; i++)
{
switch (i)
{
case 0:
{
if (reverse_cos_ric)
intestazione_1.add("Ricavi");
else
intestazione_1.add("Costi");
}
break;
case 1:
{
if (reverse_cos_ric)
intestazione_1.add("Costi");
else
intestazione_1.add("Ricavi");
}
break;
case 2: intestazione_1.add("Attività"); break;
case 3: intestazione_1.add("Passività"); break;
}
for (int j = 0; j < 6; j++)
intestazione_1.add("");
}
file_to_date << intestazione_1 << endl;
//intestazione secondaria
TToken_string intestazione_2(512, '\t');
for (int k = 0; k < 4; k++)
intestazione_2.add("");
for (int l = 0; l < 4; l++)
{
for (int n = 0; n < 7; n++)
{
switch (n)
{
case 0: intestazione_2.add("Budget"); break;
case 1: intestazione_2.add("Impegnato"); break;
case 2: intestazione_2.add("Fatturato"); break;
case 3: intestazione_2.add("Maturato"); break;
case 4: intestazione_2.add("Da impegnare"); break;
case 5: intestazione_2.add("Da fatturare"); break;
case 6: intestazione_2.add("Da maturare"); break;
}
}
}
file_to_date << intestazione_2 << endl;
}
//report e book dei report
TReport_book book;
TString path = mask.get(F_REPORT);
@ -1630,8 +1803,18 @@ void TPrint_rendiconto_ca::main_loop()
for (int l = liv1.levels()-2; l >= 0; l--) //se la struttura è a più livelli costruisce la tokenstring
row.insert("|", liv1.total_len(l));
rep.set_filter(mask, 0); //fa la set filter sulla prima riga (che è quella usata)
book.add(rep);
rep.set_filter(mask, 0); //fa la set filter sulla prima riga (che è quella usata)
//se stampa o anteprima..
if (key == K_ENTER)
book.add(rep);
else
{
const TString codcms = row.get(0);
const TString cdc = row.get();
const TString codfase = row.get();
esporta_csv(mask, *rep.recordset(), codcms, cdc, codfase);
}
}
sheet.destroy(); //cancella le commesse aggiunte in automatico sullo sheet
}
@ -1640,16 +1823,29 @@ void TPrint_rendiconto_ca::main_loop()
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
//..temporaneo i cui dati riempiranno il report
//se stampa o anteprima
if (key == K_ENTER)
book.add(rep); //aggiunge il report relativo alla cdc/cms corrente al book
else
{
const TString codcms = row->get(0);
const TString cdc = row->get();
const TString codfase = row->get();
esporta_csv(mask, *rep.recordset(), codcms, cdc, codfase);
}
}
}
//se stampa o anteprima
if (key == K_ENTER)
{
if (mask.print_mode() == 'A')
book.preview();
else
book.print(); //stampa il book dei report
}
if (mask.print_mode() == 'A')
book.preview();
else
book.print(); //stampa il book dei report
}
} //while(true)...
delete _msk;
_msk = NULL;

View File

@ -11,6 +11,8 @@
#define F_DATAFIN 257
#define F_REV_COSRIC 258
#define F_IMPLODE_ROWS 259
#define F_VITAINTERA 261
#define F_PATH 262
//campi generati dai piani dei conti
#define F_PIANO 319

View File

@ -3,6 +3,14 @@
TOOLBAR "topbar" 0 0 0 2
#include <aprintbar.h>
BUTTON DLG_EXPORT 2 2
BEGIN
PROMPT 1 1 "~Esporta XLS"
MESSAGE EXIT,K_F6
PICTURE TOOL_EXPORT
END
ENDPAGE
TOOLBAR "bottombar" 0 -2 0 1
@ -90,14 +98,32 @@ BEGIN
ITEM "Cdc12"
END
BOOLEAN F_VITAINTERA
BEGIN
PROMPT 2 -6 "Includere esercizi successivi (vita intera)"
MESSAGE FALSE ENABLE,F_DATAFIN
MESSAGE TRUE CLEAR,F_DATAFIN
END
DATE F_DATAINI
BEGIN
PROMPT 2 -4 "Dalla data "
PROMPT 2 -5 "Dalla data "
END
DATE F_DATAFIN
BEGIN
PROMPT 40 -4 "Alla data "
PROMPT 36 -5 "Alla data "
END
TEXT DLG_NULL
BEGIN
PROMPT 2 -3 "Digitare o selezionare attraverso la ricerca la cartella in cui creare il file rendiconto.xls. E' necessario indicare l'intero percorso!"
END
STRING F_PATH 256 40
BEGIN
PROMPT 2 -2 "Cartella dove esportare il file rendiconto.xls "
DSELECT
END
ENDPAGE