2009-11-09 14:55:44 +00:00
|
|
|
|
#include "ps0099100.h"
|
2008-12-12 12:29:06 +00:00
|
|
|
|
|
|
|
|
|
#include <automask.h>
|
|
|
|
|
#include <modaut.h>
|
|
|
|
|
#include <progind.h>
|
|
|
|
|
#include <reprint.h>
|
|
|
|
|
#include <textset.h>
|
|
|
|
|
|
|
|
|
|
#include "../cg/cglib01.h"
|
2008-12-12 16:00:01 +00:00
|
|
|
|
#include "../ve/velib07.h"
|
2008-12-12 12:29:06 +00:00
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
// MASCHERA
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
class TStatistiche_ANIVAL_mask : public TAutomask
|
|
|
|
|
{
|
|
|
|
|
protected:
|
|
|
|
|
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
TStatistiche_ANIVAL_mask();
|
|
|
|
|
virtual ~TStatistiche_ANIVAL_mask() {}
|
|
|
|
|
};
|
|
|
|
|
|
2009-11-09 14:55:44 +00:00
|
|
|
|
TStatistiche_ANIVAL_mask::TStatistiche_ANIVAL_mask() : TAutomask("ps0099100")
|
2008-12-12 12:29:06 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TStatistiche_ANIVAL_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
|
|
|
|
|
{
|
|
|
|
|
switch (o.dlg())
|
|
|
|
|
{
|
|
|
|
|
case F_ANNO:
|
|
|
|
|
if (e == fe_modify && !o.empty())
|
|
|
|
|
{
|
|
|
|
|
TEsercizi_contabili esc;
|
|
|
|
|
TDate inies, fines;
|
|
|
|
|
if (esc.code2range(atoi(o.get()), inies, fines))
|
|
|
|
|
{
|
|
|
|
|
set(F_DADATA, inies);
|
|
|
|
|
set(F_ADATA, fines);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case F_DADATA:
|
|
|
|
|
case F_ADATA:
|
|
|
|
|
if (e == fe_close)
|
|
|
|
|
{
|
|
|
|
|
const int anno = get_int(F_ANNO);
|
|
|
|
|
|
|
|
|
|
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"));
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////
|
|
|
|
|
// REPORT
|
|
|
|
|
/////////////////////////////////////////////////////////////
|
|
|
|
|
class TStatistiche_ANIVAL_report : public TReport
|
|
|
|
|
{
|
|
|
|
|
protected:
|
|
|
|
|
virtual bool use_mask() { return false; }
|
|
|
|
|
public:
|
|
|
|
|
TStatistiche_ANIVAL_report() {}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////
|
|
|
|
|
// CSV RECORDSET
|
|
|
|
|
/////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
class TStatistiche_ANIVAL_csv_recordset : public TCSV_recordset
|
|
|
|
|
{
|
2008-12-15 17:11:55 +00:00
|
|
|
|
real _tot[13]; //array con i totali per mese (e anno)
|
|
|
|
|
|
2008-12-12 12:29:06 +00:00
|
|
|
|
protected:
|
2009-11-09 14:55:44 +00:00
|
|
|
|
long trova_riga(const TToken_string& key, const char tipo_stat, const char tipo_dettaglio);
|
2008-12-15 17:11:55 +00:00
|
|
|
|
|
2008-12-12 12:29:06 +00:00
|
|
|
|
public:
|
2009-11-09 14:55:44 +00:00
|
|
|
|
TStatistiche_ANIVAL_csv_recordset(const TMask& mask);
|
|
|
|
|
|
|
|
|
|
//virtual const TVariant& get(const char* column_name) const;
|
|
|
|
|
//virtual const TVariant& get(unsigned int column) const { return TCSV_recordset::get(column); }
|
|
|
|
|
|
|
|
|
|
void aggiungi_ai_totali(const TRiga_documento& riga, const char tipo_dati);
|
|
|
|
|
void aggiungi_riga(TDocument_recordset& righe, const char tipo_dati, const char tipo_stat, const char tipo_dettaglio); //const TRiga_documento& riga, const char tipo_dati);
|
2008-12-15 17:11:55 +00:00
|
|
|
|
void compila_intestazione();
|
|
|
|
|
void calcola_percentuali();
|
2008-12-12 12:29:06 +00:00
|
|
|
|
};
|
|
|
|
|
|
2009-11-09 14:55:44 +00:00
|
|
|
|
TStatistiche_ANIVAL_csv_recordset::TStatistiche_ANIVAL_csv_recordset(const TMask& mask)
|
2008-12-15 17:11:55 +00:00
|
|
|
|
: TCSV_recordset("CSV(\"\t\")") //tab separated
|
2008-12-12 12:29:06 +00:00
|
|
|
|
{
|
2009-11-09 14:55:44 +00:00
|
|
|
|
FOR_EACH_MASK_FIELD(mask, i, field)
|
|
|
|
|
{
|
|
|
|
|
const TFieldref* f = field->field();
|
|
|
|
|
if (f != NULL)
|
|
|
|
|
{
|
|
|
|
|
const TString& name = f->name();
|
|
|
|
|
set_var(name, field->get(), true);
|
|
|
|
|
}
|
|
|
|
|
}
|
2008-12-12 12:29:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2009-11-09 14:55:44 +00:00
|
|
|
|
/*const TVariant& TStatistiche_ANIVAL_csv_recordset::get(const char* field_name) const
|
|
|
|
|
{
|
|
|
|
|
if (*field_name == '#')
|
|
|
|
|
return get_var(field_name);
|
|
|
|
|
|
|
|
|
|
return TRecordset::get(field_name);
|
|
|
|
|
}*/
|
|
|
|
|
|
2008-12-15 17:11:55 +00:00
|
|
|
|
void TStatistiche_ANIVAL_csv_recordset::compila_intestazione()
|
|
|
|
|
{
|
|
|
|
|
insert_rec(0);
|
2009-11-09 14:55:44 +00:00
|
|
|
|
//riempie i campi del primo record del csv in modo da avere l'intestazione (0=A...29=AD in excel)
|
2008-12-15 17:11:55 +00:00
|
|
|
|
set(0, "CODART");
|
|
|
|
|
set(1, "DESCRIZIONE");
|
|
|
|
|
set(2, "GENNAIO");
|
|
|
|
|
set(3, "%GEN");
|
|
|
|
|
set(4, "FEBBRAIO");
|
|
|
|
|
set(5, "%FEB");
|
|
|
|
|
set(6, "MARZO");
|
|
|
|
|
set(7, "%MAR");
|
|
|
|
|
set(8, "APRILE");
|
|
|
|
|
set(9, "%APR");
|
|
|
|
|
set(10, "MAGGIO");
|
|
|
|
|
set(11, "%MAG");
|
|
|
|
|
set(12, "GIUGNO");
|
|
|
|
|
set(13, "%GIU");
|
|
|
|
|
set(14, "LUGLIO");
|
|
|
|
|
set(15, "%LUG");
|
|
|
|
|
set(16, "AGOSTO");
|
|
|
|
|
set(17, "%AGO");
|
|
|
|
|
set(18, "SETTEMBRE");
|
|
|
|
|
set(19, "%SET");
|
|
|
|
|
set(20, "OTTOBRE");
|
|
|
|
|
set(21, "%OTT");
|
|
|
|
|
set(22, "NOVEMBRE");
|
|
|
|
|
set(23, "%NOV");
|
|
|
|
|
set(24, "DICEMBRE");
|
|
|
|
|
set(25, "%DIC");
|
|
|
|
|
set(26, "ANNO");
|
|
|
|
|
set(27, "%ANNO");
|
2009-11-09 14:55:44 +00:00
|
|
|
|
set(28, "GRMERC");
|
|
|
|
|
set(29, "CODCLI");
|
2008-12-15 17:11:55 +00:00
|
|
|
|
}
|
2008-12-12 12:29:06 +00:00
|
|
|
|
|
2009-11-09 14:55:44 +00:00
|
|
|
|
|
2008-12-15 17:11:55 +00:00
|
|
|
|
//metodo plutonico di ricerca dicotomica su una colonna di csv_recordset
|
2009-11-09 14:55:44 +00:00
|
|
|
|
long TStatistiche_ANIVAL_csv_recordset::trova_riga(const TToken_string& key, const char tipo_stat, const char tipo_dettaglio)
|
2008-12-12 12:29:06 +00:00
|
|
|
|
{
|
2008-12-15 17:11:55 +00:00
|
|
|
|
long first = 0;
|
|
|
|
|
long last = items() - 1;
|
|
|
|
|
long riga = -1;
|
2008-12-12 12:29:06 +00:00
|
|
|
|
|
2008-12-15 17:11:55 +00:00
|
|
|
|
while(first <= last)
|
|
|
|
|
{
|
|
|
|
|
const long guess = (first + last) / 2;
|
|
|
|
|
move_to(guess);
|
2009-11-09 14:55:44 +00:00
|
|
|
|
//const TString& guess_codart = get(0).as_string(); //ori
|
|
|
|
|
//const int diff = guess_codart.compare(codart); //ori
|
|
|
|
|
|
|
|
|
|
TToken_string guess_key;
|
|
|
|
|
|
|
|
|
|
switch (tipo_stat)
|
|
|
|
|
{
|
|
|
|
|
case 'A': //articolo
|
|
|
|
|
guess_key.add(get(0).as_string());
|
|
|
|
|
break;
|
|
|
|
|
case 'C': //cliente-codart codart-cliente
|
|
|
|
|
if (tipo_dettaglio == 'A')
|
|
|
|
|
{
|
|
|
|
|
guess_key.add(get(0).as_string()); //colonna 0=A codart
|
|
|
|
|
guess_key.add(get(29).as_string()); //colonna 29=AD codcf
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
guess_key.add(get(29).as_string()); //colonna 29=AD codcf
|
|
|
|
|
guess_key.add(get(0).as_string()); //colonna 0=A codart
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 'G': //grmerc-codart
|
|
|
|
|
guess_key.add(get(28).as_string()); //colonna 28=AC grmerc
|
|
|
|
|
guess_key.add(get(0).as_string());
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const int diff = guess_key.compare(key);
|
2008-12-15 17:11:55 +00:00
|
|
|
|
if (diff == 0)
|
|
|
|
|
{
|
|
|
|
|
riga = guess;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (diff > 0)
|
|
|
|
|
{
|
|
|
|
|
last = guess - 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
first = guess + 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
2008-12-12 12:29:06 +00:00
|
|
|
|
|
2008-12-15 17:11:55 +00:00
|
|
|
|
return riga;
|
|
|
|
|
}
|
2008-12-12 12:29:06 +00:00
|
|
|
|
|
|
|
|
|
|
2008-12-15 17:11:55 +00:00
|
|
|
|
//funzione di ordinamento per il campo codart (campo 0 sul csv)
|
|
|
|
|
static int compare_csv_rows_codart(const TObject** o1, const TObject** o2)
|
2008-12-12 16:00:01 +00:00
|
|
|
|
{
|
2008-12-15 17:11:55 +00:00
|
|
|
|
TToken_string& s1 = *(TToken_string*)*o1;
|
|
|
|
|
TToken_string& s2 = *(TToken_string*)*o2;
|
|
|
|
|
|
2009-11-09 14:55:44 +00:00
|
|
|
|
//deve ordinare sul campo codart ed eventualmente clifo
|
2008-12-15 17:11:55 +00:00
|
|
|
|
const TString& c1 = s1.get(0);
|
|
|
|
|
const TString& c2 = s2.get(0);
|
|
|
|
|
int cmp = c1.compare(c2);
|
|
|
|
|
|
|
|
|
|
return cmp;
|
2008-12-12 16:00:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2009-11-09 14:55:44 +00:00
|
|
|
|
//funzione di ordinamento per il campo grmerc (campo 28 sul csv)
|
|
|
|
|
static int compare_csv_rows_grmerc_codart(const TObject** o1, const TObject** o2)
|
|
|
|
|
{
|
|
|
|
|
TToken_string& s1 = *(TToken_string*)*o1;
|
|
|
|
|
TToken_string& s2 = *(TToken_string*)*o2;
|
|
|
|
|
|
|
|
|
|
//deve ordinare sul campo grmerc ed eventualmente codart
|
|
|
|
|
TToken_string c1;
|
|
|
|
|
c1.add(s1.get(28));
|
|
|
|
|
c1.add(s1.get(0));
|
|
|
|
|
|
|
|
|
|
TToken_string c2;
|
|
|
|
|
c2.add(s2.get(28));
|
|
|
|
|
c2.add(s2.get(0));
|
|
|
|
|
|
|
|
|
|
int cmp = c1.compare(c2);
|
|
|
|
|
|
|
|
|
|
return cmp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//funzione di ordinamento per il campo codcf (campo 29 sul csv)
|
|
|
|
|
static int compare_csv_rows_codcf_codart(const TObject** o1, const TObject** o2)
|
|
|
|
|
{
|
|
|
|
|
TToken_string& s1 = *(TToken_string*)*o1;
|
|
|
|
|
TToken_string& s2 = *(TToken_string*)*o2;
|
|
|
|
|
|
|
|
|
|
//deve ordinare sul campo codcf ed eventualmente codart
|
|
|
|
|
TToken_string c1;
|
|
|
|
|
c1.add(s1.get(29));
|
|
|
|
|
c1.add(s1.get(0));
|
|
|
|
|
|
|
|
|
|
TToken_string c2;
|
|
|
|
|
c2.add(s2.get(29));
|
|
|
|
|
c2.add(s2.get(0));
|
|
|
|
|
|
|
|
|
|
int cmp = c1.compare(c2);
|
|
|
|
|
|
|
|
|
|
return cmp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//funzione di ordinamento per il campo codcf (campo 29 sul csv)
|
|
|
|
|
static int compare_csv_rows_codart_codcf(const TObject** o1, const TObject** o2)
|
|
|
|
|
{
|
|
|
|
|
TToken_string& s1 = *(TToken_string*)*o1;
|
|
|
|
|
TToken_string& s2 = *(TToken_string*)*o2;
|
|
|
|
|
|
|
|
|
|
//deve ordinare sul campo codart ed eventualmente codcf
|
|
|
|
|
TToken_string c1;
|
|
|
|
|
c1.add(s1.get(0));
|
|
|
|
|
c1.add(s1.get(29));
|
|
|
|
|
|
|
|
|
|
TToken_string c2;
|
|
|
|
|
c2.add(s2.get(0));
|
|
|
|
|
c2.add(s2.get(29));
|
|
|
|
|
|
|
|
|
|
int cmp = c1.compare(c2);
|
|
|
|
|
|
|
|
|
|
return cmp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TStatistiche_ANIVAL_csv_recordset::aggiungi_ai_totali(const TRiga_documento& riga, const char tipo_dati)
|
|
|
|
|
{
|
|
|
|
|
//datadoc (serve a stabilire in quale colonna andr<64> a sommarsi l'importo della riga corrente
|
|
|
|
|
const TDate datadoc = riga.doc().get_date(DOC_DATADOC);
|
|
|
|
|
const int mese = datadoc.month();
|
|
|
|
|
|
|
|
|
|
real dato;
|
|
|
|
|
//i dati da analizzare possono essere 'P'rezzi o 'Q'uantit<69>
|
|
|
|
|
if (tipo_dati == 'P')
|
|
|
|
|
dato = riga.importo(true, false); //importo riga corrente
|
|
|
|
|
else
|
|
|
|
|
dato = riga.quantita(); //qta riga corrente
|
|
|
|
|
|
|
|
|
|
//aggiorna l'importone del mese (ricordarsi che l'array parte da 0 quindi ci va -1 nell'indice)
|
|
|
|
|
_tot[mese - 1] += dato;
|
|
|
|
|
//aggiorna anche il totale annuale
|
|
|
|
|
_tot[12] += dato;
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-12 16:00:01 +00:00
|
|
|
|
//metodo per la scrittura del csv
|
2009-11-09 14:55:44 +00:00
|
|
|
|
void TStatistiche_ANIVAL_csv_recordset::aggiungi_riga(TDocument_recordset& righe,
|
|
|
|
|
const char tipo_dati, const char tipo_stat, const char tipo_dettaglio)
|
2008-12-12 16:00:01 +00:00
|
|
|
|
{
|
2009-11-09 14:55:44 +00:00
|
|
|
|
const TDocumento& doc = righe.doc(righe.cursor()->curr());
|
|
|
|
|
const int nriga = righe.get(RDOC_NRIGA).as_int();
|
|
|
|
|
const TRiga_documento& riga = doc[nriga];
|
|
|
|
|
|
2008-12-12 16:00:01 +00:00
|
|
|
|
//creazione di un nuovo record da esportare
|
2008-12-15 17:11:55 +00:00
|
|
|
|
//esiste gi<67> questo codart?
|
|
|
|
|
const TString80 codart = riga.get(RDOC_CODART);
|
2009-11-09 14:55:44 +00:00
|
|
|
|
const long codcf = righe.get("DOC.CODCF").as_int();
|
|
|
|
|
const TString& grmerc = righe.get("ANAMAG.GRMERC").as_string();
|
|
|
|
|
|
|
|
|
|
//attenzione ai vari casi di composizione chiave!
|
|
|
|
|
//A=articolo G=GrMerc+Articolo C=Cliente+Articolo o Articolo+Cliente in base al tipo di stampa scelta
|
|
|
|
|
TToken_string key;
|
|
|
|
|
switch (tipo_stat)
|
|
|
|
|
{
|
|
|
|
|
case 'A':
|
|
|
|
|
key.add(codart);
|
|
|
|
|
break;
|
|
|
|
|
case 'C':
|
|
|
|
|
{
|
|
|
|
|
if (tipo_dettaglio == 'A') //raccolto per articolo
|
|
|
|
|
{
|
|
|
|
|
key.add(codart);
|
|
|
|
|
key.add(codcf);
|
|
|
|
|
}
|
|
|
|
|
else //raccolto per cliente (con o senza esplosione)
|
|
|
|
|
{
|
|
|
|
|
key.add(codcf);
|
|
|
|
|
key.add(codart);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 'G':
|
|
|
|
|
key.add(grmerc);
|
|
|
|
|
key.add(codart);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
long numriga = trova_riga(key, tipo_stat, tipo_dettaglio);
|
|
|
|
|
|
2008-12-15 17:11:55 +00:00
|
|
|
|
if (numriga < 0)
|
|
|
|
|
{
|
|
|
|
|
//codart
|
|
|
|
|
new_rec("");
|
|
|
|
|
set(0, TVariant(codart));
|
|
|
|
|
//descrart
|
|
|
|
|
const TString& descrart = cache().get(LF_ANAMAG, codart, ANAMAG_DESCR);
|
|
|
|
|
set(1, TVariant(descrart));
|
|
|
|
|
|
2009-11-09 14:55:44 +00:00
|
|
|
|
set(28, TVariant(grmerc));
|
|
|
|
|
set(29, TVariant(codcf));
|
|
|
|
|
|
|
|
|
|
//re-sorting per codart (serve perch<63> solo il recordset ordinato <20> scannerizzabile con il plutonico metodo dicotomico)
|
|
|
|
|
switch (tipo_stat)
|
|
|
|
|
{
|
|
|
|
|
case 'A':
|
|
|
|
|
sort(compare_csv_rows_codart);
|
|
|
|
|
break;
|
|
|
|
|
case 'C':
|
|
|
|
|
if (tipo_dettaglio == 'A')
|
|
|
|
|
sort(compare_csv_rows_codart_codcf);
|
|
|
|
|
else
|
|
|
|
|
sort(compare_csv_rows_codcf_codart);
|
|
|
|
|
break;
|
|
|
|
|
case 'G':
|
|
|
|
|
sort(compare_csv_rows_grmerc_codart);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//chiave.add(codart);
|
|
|
|
|
|
|
|
|
|
numriga = trova_riga(key, tipo_stat, tipo_dettaglio);
|
|
|
|
|
|
2008-12-15 17:11:55 +00:00
|
|
|
|
CHECKS(numriga >= 0, "Articolo bastardo ", (const char*)codart);
|
|
|
|
|
}
|
2008-12-12 16:00:01 +00:00
|
|
|
|
//riempimento del record secondo il tracciato:
|
2009-11-09 14:55:44 +00:00
|
|
|
|
// codart+descrart+12*[impns+%incid]+grmerc+codcf
|
2008-12-15 17:11:55 +00:00
|
|
|
|
|
2008-12-12 16:00:01 +00:00
|
|
|
|
//datadoc (serve a stabilire in quale colonna andr<64> a sommarsi l'importo della riga corrente
|
|
|
|
|
const TDate datadoc = riga.doc().get_date(DOC_DATADOC);
|
|
|
|
|
const int mese = datadoc.month();
|
|
|
|
|
const int column = mese * 2; //le colonne dei mesi sono gennaio=2,febbraio=4,marzo=6...
|
2009-11-09 14:55:44 +00:00
|
|
|
|
|
|
|
|
|
real dato;
|
|
|
|
|
real datone;
|
|
|
|
|
|
|
|
|
|
if (tipo_dati == 'P')
|
|
|
|
|
dato = riga.importo(true, false); //'P'rezzo->importo
|
|
|
|
|
else
|
|
|
|
|
dato = riga.quantita(); //'Q'uantita
|
|
|
|
|
|
|
|
|
|
//parte comune ai due casi
|
|
|
|
|
datone = get(column).as_real(); //valora totale della colonna mese corrispondente nel csv
|
|
|
|
|
datone += dato; //aggiunge il valore riga al valore totale articolo del mese nel csv
|
|
|
|
|
set(column, datone); //riscrive il valore totale aggiornato nella sua colonna(in formato stringa, cio<69> con la "," e non il ".")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//aggiunge anche grmerc, utilizzando codartmag per risalire al grmerc (se usasse codart potrebbe non esistere in anagrafica!)
|
|
|
|
|
set(28, grmerc);
|
|
|
|
|
//aggiunge pure il cliente
|
|
|
|
|
set(29, codcf);
|
|
|
|
|
|
2008-12-12 16:00:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2008-12-15 17:11:55 +00:00
|
|
|
|
void TStatistiche_ANIVAL_csv_recordset::calcola_percentuali()
|
2008-12-12 16:00:01 +00:00
|
|
|
|
{
|
2008-12-15 17:11:55 +00:00
|
|
|
|
//%incidenza articolo sul mese = imp_articolo mese / imp tot mese
|
|
|
|
|
for (bool ok = move_first(); ok; ok = move_next())
|
|
|
|
|
{
|
|
|
|
|
real totale_anno;
|
|
|
|
|
for (int i = 2; i <= 24; i += 2)
|
|
|
|
|
{
|
|
|
|
|
const real imp_art_mese = get(i).as_real();
|
|
|
|
|
//ricordando che l'array parte da 0
|
2009-11-09 14:55:44 +00:00
|
|
|
|
real perc = imp_art_mese * CENTO / _tot[i/2 - 1]; //calcola la % incidenza articolo sul totale per quel mese
|
|
|
|
|
perc.round(5);
|
2008-12-15 17:11:55 +00:00
|
|
|
|
set(i + 1, perc);
|
|
|
|
|
totale_anno += imp_art_mese;
|
|
|
|
|
}
|
|
|
|
|
set(26, totale_anno);
|
|
|
|
|
const real perc_anno = totale_anno * CENTO / _tot[12]; //calcola la % incidenza articolo sul totale annuale
|
|
|
|
|
set(27, perc_anno);
|
|
|
|
|
}
|
|
|
|
|
}
|
2008-12-12 16:00:01 +00:00
|
|
|
|
|
2009-11-09 14:55:44 +00:00
|
|
|
|
|
2008-12-15 17:11:55 +00:00
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
// APPLICAZIONE
|
|
|
|
|
///////////////////////////////////////////////////////////
|
2008-12-12 16:00:01 +00:00
|
|
|
|
|
2008-12-15 17:11:55 +00:00
|
|
|
|
class TStatistiche_ANIVAL : public TSkeleton_application
|
|
|
|
|
{
|
|
|
|
|
virtual bool check_autorization() const {return false;}
|
|
|
|
|
virtual const char * extra_modules() const {return "ve";}
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
void elabora(const TMask& mask) const;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
virtual bool create();
|
|
|
|
|
virtual void main_loop();
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
2008-12-12 16:00:01 +00:00
|
|
|
|
|
2008-12-12 12:29:06 +00:00
|
|
|
|
|
|
|
|
|
//metodo di base per la ricerca delle righe documento che soddisfano i parametri dell'utonto
|
|
|
|
|
void TStatistiche_ANIVAL::elabora(const TMask& mask) const
|
|
|
|
|
{
|
2009-11-09 14:55:44 +00:00
|
|
|
|
//PARAMETRI DI STAMPA
|
|
|
|
|
//--------------------
|
|
|
|
|
//tipo dati da estrarre (si utilizza nel metodo di scrittura riga e totali;stabilisce se si vuole qta o prezzo)
|
|
|
|
|
const char tipo_dati = mask.get(F_TIPODATA)[0];
|
|
|
|
|
//tipologia di statistica (Articolo - GruppoMerceologico - Cliente)
|
|
|
|
|
const char tipo_stat = mask.get(F_TIPOSTAT)[0];
|
|
|
|
|
//se sceglie per cliente ha 3 possibilit<69> di dettaglio (''=nessuno,'C'=raccolto per cliente,'A'=raccolto per articolo)
|
|
|
|
|
const char tipo_dettaglio = mask.get(F_DETTAGLIO)[0];
|
|
|
|
|
|
|
|
|
|
//stampa particolare bernazzalica in caso di UN SOLO CLIENTE selezionato nella stampa per clienete dettagliata per cliente
|
|
|
|
|
//in questo caso i totali non sono generali ma solo su quel cliente (paranoie!)
|
|
|
|
|
bool bernazzata = false;
|
|
|
|
|
if (tipo_stat == 'C' && tipo_dettaglio == 'C')
|
|
|
|
|
{
|
|
|
|
|
const long dacli = mask.get_long(F_DACODCLI);
|
|
|
|
|
const long acodcli = mask.get_long(F_ACODCLI);
|
|
|
|
|
if (dacli == acodcli)
|
|
|
|
|
bernazzata = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//creazione del csv recordset che verra' riempito dai record del recordset righe
|
|
|
|
|
TStatistiche_ANIVAL_csv_recordset* csv = new TStatistiche_ANIVAL_csv_recordset(mask);
|
|
|
|
|
|
|
|
|
|
//recordset per il calcolo dei totali mese/anno;servono per i calcoli futuri delle percentuali
|
|
|
|
|
TString prequery;
|
|
|
|
|
prequery << "USE RDOC KEY 1\n";
|
|
|
|
|
prequery << "SELECT ((CODARTMAG!=\"\")&&(BETWEEN(33->DATADOC,#DADATA,#ADATA))";
|
|
|
|
|
if (bernazzata)
|
|
|
|
|
prequery << "&&(DOC.TIPOCF=='C')&&(DOC.CODCF==#DACODCLI)";
|
|
|
|
|
prequery <<")\n";
|
|
|
|
|
prequery << "JOIN DOC INTO PROVV==PROVV ANNO==ANNO CODNUM==CODNUM NDOC==NDOC\n";
|
|
|
|
|
prequery << "FROM CODNUM=#CODNUM ANNO=#ANNO PROVV='D'\n";
|
|
|
|
|
prequery << "TO CODNUM=#CODNUM ANNO=#ANNO PROVV='D'\n";
|
|
|
|
|
TDocument_recordset totali(prequery);
|
|
|
|
|
totali.set_var("#CODNUM", TVariant(mask.get(F_CODNUM)));
|
|
|
|
|
totali.set_var("#DADATA", mask.get_date(F_DADATA));
|
|
|
|
|
totali.set_var("#ADATA", mask.get_date(F_ADATA));
|
|
|
|
|
totali.set_var("#ANNO", TVariant((long)mask.get_int(F_ANNO)));
|
|
|
|
|
if (bernazzata)
|
|
|
|
|
totali.set_var("#DACODCLI", mask.get_long(F_DACODCLI));
|
|
|
|
|
const long totali_items = totali.items();
|
|
|
|
|
if (totali_items > 0)
|
|
|
|
|
{
|
|
|
|
|
//E crea pure la progind..
|
|
|
|
|
TProgind pi(totali_items, TR("Calcolo totali mensili ed annuali"), true, true);
|
2008-12-12 12:29:06 +00:00
|
|
|
|
|
2009-11-09 14:55:44 +00:00
|
|
|
|
//Scansione del recordset trovato
|
|
|
|
|
for (bool ok = totali.move_first(); ok; ok = totali.move_next())
|
|
|
|
|
{
|
|
|
|
|
if (!pi.addstatus(1))
|
|
|
|
|
break;
|
|
|
|
|
const TDocumento& doc = totali.doc(totali.cursor()->curr());
|
|
|
|
|
const int nriga = totali.get(RDOC_NRIGA).as_int();
|
|
|
|
|
//scrive sul CSV i campi che servono al file di excel e al report
|
|
|
|
|
csv->aggiungi_ai_totali(doc[nriga], tipo_dati);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//CREAZIONE QUERY
|
|
|
|
|
//---------------
|
|
|
|
|
//scatta la query per la costruzione del recordset
|
|
|
|
|
TString query;
|
|
|
|
|
query << "USE RDOC KEY 1\n";
|
|
|
|
|
query << "SELECT ((CODARTMAG!=\"\")&&(BETWEEN(33->DATADOC,#DADATA,#ADATA))&&";
|
|
|
|
|
|
|
|
|
|
switch (tipo_stat)
|
|
|
|
|
{
|
|
|
|
|
case 'A': //range su articoli (CODARTMAG)
|
|
|
|
|
query << "(BETWEEN(CODARTMAG,#DACODART,#ACODART)))\n";
|
|
|
|
|
break;
|
|
|
|
|
case 'C':
|
|
|
|
|
query << "(DOC.TIPOCF=='C')&&(BETWEEN(DOC.CODCF,#DACODCLI,#ACODCLI)))\n";
|
|
|
|
|
break;
|
|
|
|
|
case 'G':
|
|
|
|
|
query << "(BETWEEN(ANAMAG.GRMERC,#DAGRMERC,#AGRMERC)))\n";
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//parte comune ai vari casi di statistica della query
|
|
|
|
|
query << "JOIN DOC INTO PROVV==PROVV ANNO==ANNO CODNUM==CODNUM NDOC==NDOC\n";
|
|
|
|
|
|
|
|
|
|
//parte non comune (deve joinare anameg per avere il grmerc
|
|
|
|
|
if (tipo_stat == 'G')
|
|
|
|
|
query << "JOIN ANAMAG INTO CODART==CODARTMAG\n";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//ri-parte comune
|
|
|
|
|
query << "FROM CODNUM=#CODNUM ANNO=#ANNO PROVV='D'\n";
|
|
|
|
|
query << "TO CODNUM=#CODNUM ANNO=#ANNO PROVV='D'\n";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//CREAZIONE RECORDSET
|
|
|
|
|
//-------------------
|
|
|
|
|
TDocument_recordset righe(query);
|
|
|
|
|
|
|
|
|
|
//parte comune di settaggio variabili
|
|
|
|
|
righe.set_var("#CODNUM", TVariant(mask.get(F_CODNUM)));
|
|
|
|
|
righe.set_var("#DADATA", mask.get_date(F_DADATA));
|
|
|
|
|
righe.set_var("#ADATA", mask.get_date(F_ADATA));
|
|
|
|
|
righe.set_var("#ANNO", TVariant((long)mask.get_int(F_ANNO)));
|
|
|
|
|
|
|
|
|
|
switch(tipo_stat)
|
|
|
|
|
{
|
|
|
|
|
case 'A':
|
|
|
|
|
righe.set_var("#DACODART", TVariant(mask.get(F_DACODART)));
|
|
|
|
|
righe.set_var("#ACODART", TVariant(mask.get(F_ACODART)));
|
|
|
|
|
break;
|
|
|
|
|
case 'C':
|
|
|
|
|
righe.set_var("#DACODCLI", TVariant(mask.get(F_DACODCLI)));
|
|
|
|
|
righe.set_var("#ACODCLI", TVariant(mask.get(F_ACODCLI)));
|
|
|
|
|
break;
|
|
|
|
|
case 'G':
|
|
|
|
|
righe.set_var("#DAGRMERC", TVariant(mask.get(F_DAGRMERC)));
|
|
|
|
|
righe.set_var("#AGRMERC", TVariant(mask.get(F_AGRMERC)));
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//CREAZIONE STAMPE/ESPORTAZIONI
|
|
|
|
|
//-----------------------------
|
2008-12-12 12:29:06 +00:00
|
|
|
|
//se trova (si spera!) almeno una rigadoc buona comincia il bello del programma
|
2008-12-12 16:00:01 +00:00
|
|
|
|
const long righe_items = righe.items();
|
|
|
|
|
if (righe_items > 0)
|
2008-12-12 12:29:06 +00:00
|
|
|
|
{
|
2008-12-12 16:00:01 +00:00
|
|
|
|
//E crea pure la progind..
|
2009-11-09 14:55:44 +00:00
|
|
|
|
TProgind pi(righe_items, TR("Generazione file statistiche..."), true, true);
|
2008-12-12 16:00:01 +00:00
|
|
|
|
|
|
|
|
|
//Scansione del recordset trovato
|
|
|
|
|
for (bool ok = righe.move_first(); ok; ok = righe.move_next())
|
|
|
|
|
{
|
|
|
|
|
if (!pi.addstatus(1))
|
|
|
|
|
break;
|
|
|
|
|
//scrive sul CSV i campi che servono al file di excel e al report
|
2009-11-09 14:55:44 +00:00
|
|
|
|
csv->aggiungi_riga(righe, tipo_dati, tipo_stat, tipo_dettaglio);
|
2008-12-12 16:00:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2008-12-15 17:11:55 +00:00
|
|
|
|
//aggiorna le colonne delle percentuali
|
|
|
|
|
csv->calcola_percentuali();
|
2008-12-12 16:00:01 +00:00
|
|
|
|
|
|
|
|
|
//se richiesto il file in formato excel...
|
|
|
|
|
if (mask.get_bool(F_EXCEL))
|
|
|
|
|
{
|
|
|
|
|
//crea la riga con le intestazioni dei campi e la mette all'inizio
|
2008-12-15 17:11:55 +00:00
|
|
|
|
csv->compila_intestazione();
|
2009-11-09 14:55:44 +00:00
|
|
|
|
//salva il file come richiesto; il nome del file viene deciso in base al tipo di statistica richiesta; il file alla fine..
|
|
|
|
|
//..della storia <20> sempre lo stesso ma ordinato in modo diverso
|
2008-12-12 16:00:01 +00:00
|
|
|
|
TString path = mask.get(F_PATH);
|
|
|
|
|
path.lower();
|
2009-11-09 14:55:44 +00:00
|
|
|
|
path << "\\statanival";
|
|
|
|
|
switch (tipo_stat)
|
|
|
|
|
{
|
|
|
|
|
case 'A':
|
|
|
|
|
path << "_art.xls";
|
|
|
|
|
break;
|
|
|
|
|
case 'C':
|
|
|
|
|
path << "_cli.xls";
|
|
|
|
|
break;
|
|
|
|
|
case 'G':
|
|
|
|
|
path << "_gmc.xls";
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
2008-12-15 17:11:55 +00:00
|
|
|
|
csv->save_as(path, fmt_silk);
|
2008-12-12 16:00:01 +00:00
|
|
|
|
|
|
|
|
|
//accoppa la riga con le intestazioni dei campi
|
|
|
|
|
csv->destroy(0);
|
|
|
|
|
|
|
|
|
|
#ifdef DBG
|
|
|
|
|
xvt_sys_goto_url(path, "open");
|
|
|
|
|
#endif
|
|
|
|
|
}
|
2009-11-09 14:55:44 +00:00
|
|
|
|
|
|
|
|
|
//REPORT DI STAMPA
|
|
|
|
|
//----------------
|
2008-12-12 16:00:01 +00:00
|
|
|
|
//creazione del report di stampa
|
|
|
|
|
TStatistiche_ANIVAL_report rep;
|
2009-11-09 14:55:44 +00:00
|
|
|
|
bool stampa;
|
|
|
|
|
//in base alle scelte dell'utonto stabilisce quale report usare
|
|
|
|
|
switch(tipo_stat)
|
|
|
|
|
{
|
|
|
|
|
case 'A':
|
|
|
|
|
stampa = rep.load("ps0099100a");
|
|
|
|
|
break;
|
|
|
|
|
case 'C':
|
|
|
|
|
{
|
|
|
|
|
switch (tipo_dettaglio)
|
|
|
|
|
{
|
|
|
|
|
case 'A':
|
|
|
|
|
stampa = rep.load("ps0099100e");
|
|
|
|
|
break;
|
|
|
|
|
case 'C':
|
|
|
|
|
stampa = rep.load("ps0099100d");
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
stampa = rep.load("ps0099100c");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 'G':
|
|
|
|
|
stampa = rep.load("ps0099100b");
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-12 16:00:01 +00:00
|
|
|
|
//setta il recordset...
|
|
|
|
|
rep.set_recordset(csv);
|
|
|
|
|
|
2009-11-09 14:55:44 +00:00
|
|
|
|
if (stampa)
|
2008-12-12 16:00:01 +00:00
|
|
|
|
{
|
|
|
|
|
TReport_book book;
|
2009-11-09 14:55:44 +00:00
|
|
|
|
stampa = book.add(rep);
|
|
|
|
|
if (stampa)
|
2008-12-12 16:00:01 +00:00
|
|
|
|
book.print_or_preview();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} //if(righe_items>0...
|
2009-11-09 14:55:44 +00:00
|
|
|
|
else
|
|
|
|
|
delete csv;
|
2008-12-12 12:29:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TStatistiche_ANIVAL::main_loop()
|
|
|
|
|
{
|
|
|
|
|
TStatistiche_ANIVAL_mask mask;
|
|
|
|
|
|
|
|
|
|
while (mask.run() == K_ENTER)
|
|
|
|
|
{
|
|
|
|
|
elabora(mask);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TStatistiche_ANIVAL::create()
|
|
|
|
|
{
|
|
|
|
|
//se non ha le vendite <20> impossibile da utilizzare
|
|
|
|
|
if (!has_module(VEAUT))
|
|
|
|
|
return error_box(TR("Modulo non autorizzato"));
|
|
|
|
|
|
2009-11-09 14:55:44 +00:00
|
|
|
|
//se non paghi ti stronco!!!
|
|
|
|
|
const TDate oggi(TODAY);
|
|
|
|
|
if (oggi >= 20091114)
|
|
|
|
|
return false;
|
|
|
|
|
|
2008-12-12 12:29:06 +00:00
|
|
|
|
return TSkeleton_application::create();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ps0099100(int argc, char* argv[])
|
|
|
|
|
{
|
|
|
|
|
TStatistiche_ANIVAL stat_anal;
|
|
|
|
|
stat_anal.run(argc, argv, TR("Statistiche ANIVAL"));
|
|
|
|
|
return 0;
|
|
|
|
|
}
|