campo-sirio/ps/ps0099100.cpp

363 lines
10 KiB
C++
Raw Normal View History

#include "ps0099100a.h"
#include <automask.h>
#include <modaut.h>
#include <progind.h>
#include <reprint.h>
#include <textset.h>
#include "../cg/cglib01.h"
#include "../ve/velib07.h"
///////////////////////////////////////////////////////////
// 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() {}
};
TStatistiche_ANIVAL_mask::TStatistiche_ANIVAL_mask() : TAutomask("ps0099100a")
{
}
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
{
real _tot[13]; //array con i totali per mese (e anno)
protected:
//virtual const TVariant& get(const char* field_name) const;
long trova_riga(const TString& codart);
public:
TStatistiche_ANIVAL_csv_recordset();
void aggiungi_riga(const TRiga_documento& riga);
void compila_intestazione();
void calcola_percentuali();
};
TStatistiche_ANIVAL_csv_recordset::TStatistiche_ANIVAL_csv_recordset()
: TCSV_recordset("CSV(\"\t\")") //tab separated
{
//create_field("CODART", -1, 20, _alfafld); //codart
}
void TStatistiche_ANIVAL_csv_recordset::compila_intestazione()
{
insert_rec(0);
//riempie i campi del primo record del csv in modo da avere l'intestazione
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");
}
//metodo plutonico di ricerca dicotomica su una colonna di csv_recordset
long TStatistiche_ANIVAL_csv_recordset::trova_riga(const TString& codart)
{
long first = 0;
long last = items() - 1;
long riga = -1;
while(first <= last)
{
const long guess = (first + last) / 2;
move_to(guess);
const TString& guess_codart = get(0).as_string();
const int diff = guess_codart.compare(codart);
if (diff == 0)
{
riga = guess;
break;
}
if (diff > 0)
{
last = guess - 1;
}
else
{
first = guess + 1;
}
}
return riga;
}
//funzione di ordinamento per il campo codart (campo 0 sul csv)
static int compare_csv_rows_codart(const TObject** o1, const TObject** o2)
{
TToken_string& s1 = *(TToken_string*)*o1;
TToken_string& s2 = *(TToken_string*)*o2;
//deve ordinare sul campo codart
const TString& c1 = s1.get(0);
const TString& c2 = s2.get(0);
int cmp = c1.compare(c2);
return cmp;
}
//metodo per la scrittura del csv
void TStatistiche_ANIVAL_csv_recordset::aggiungi_riga(const TRiga_documento& riga)
{
//creazione di un nuovo record da esportare
//esiste gi<67> questo codart?
const TString80 codart = riga.get(RDOC_CODART);
long numriga = trova_riga(codart);
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));
//re-sorting per codart
sort(compare_csv_rows_codart);
numriga = trova_riga(codart);
CHECKS(numriga >= 0, "Articolo bastardo ", (const char*)codart);
}
//riempimento del record secondo il tracciato:
// codart+descrart+12*[impns+%incid]
//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...
//importo
const real importo = riga.importo(true, false); //importo riga corrente
real importone = get(column).as_real(); //importo totale della colonna mese corrispondente nel csv
importone += importo; //aggiunge l'importo riga all'importone articolo del mese nel csv
set(column, importone); //riscrive l'importone aggiornato nella sua colonna..
//..(in formato stringa, cio<69> con la "," e non il "."
//aggiorna l'importone del mese (ricordarsi che l'array parte da 0 quindi ci va -1 nell'indice)
_tot[mese - 1] += importo;
//aggiorna anche il totale annuale
_tot[12] += importo;
}
void TStatistiche_ANIVAL_csv_recordset::calcola_percentuali()
{
//%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
const real perc = imp_art_mese * CENTO / _tot[i/2 - 1]; //calcola la % incidenza articolo sul totale per quel mese
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);
}
}
///////////////////////////////////////////////////////////
// APPLICAZIONE
///////////////////////////////////////////////////////////
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();
};
//metodo di base per la ricerca delle righe documento che soddisfano i parametri dell'utonto
void TStatistiche_ANIVAL::elabora(const TMask& mask) const
{
TString query;
//scatta la query per la costruzione del recordset
query << "USE RDOC KEY 1\n";
query << "SELECT ((CODARTMAG!=\"\")&&(BETWEEN(33->DATADOC,#DADATA,#ADATA))&&(BETWEEN(CODARTMAG,#DACODART,#ACODART)))\n";
query << "JOIN DOC INTO PROVV==PROVV ANNO==ANNO CODNUM==CODNUM NDOC==NDOC\n";
query << "FROM CODNUM=#CODNUM ANNO=#ANNO PROVV='D'\n";
query << "TO CODNUM=#CODNUM ANNO=#ANNO PROVV='D'\n";
TDocument_recordset righe(query);
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)));
righe.set_var("#DACODART", TVariant(mask.get(F_DACODART)));
righe.set_var("#ACODART", TVariant(mask.get(F_ACODART)));
//se trova (si spera!) almeno una rigadoc buona comincia il bello del programma
const long righe_items = righe.items();
if (righe_items > 0)
{
//E crea pure la progind..
TProgind pi(righe_items, TR("Generazione file statanival.xls"), true, true);
//creazione del csv recordset che verra' riempito dai record del recordset righe
TStatistiche_ANIVAL_csv_recordset* csv = new TStatistiche_ANIVAL_csv_recordset;
//Scansione del recordset trovato
for (bool ok = righe.move_first(); ok; ok = righe.move_next())
{
if (!pi.addstatus(1))
break;
const TDocumento& doc = righe.doc(righe.cursor()->curr());
const int nriga = righe.get(RDOC_NRIGA).as_int();
//scrive sul CSV i campi che servono al file di excel e al report
csv->aggiungi_riga(doc[nriga]);
}
//aggiorna le colonne delle percentuali
csv->calcola_percentuali();
//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
csv->compila_intestazione();
//salva il file come richiesto
TString path = mask.get(F_PATH);
path.lower();
path << "\\statanival.xls";
csv->save_as(path, fmt_silk);
//accoppa la riga con le intestazioni dei campi
csv->destroy(0);
#ifdef DBG
xvt_sys_goto_url(path, "open");
#endif
}
//creazione del report di stampa
TStatistiche_ANIVAL_report rep;
bool ok = rep.load("ps0099100a");
//setta il recordset...
rep.set_recordset(csv);
if (ok)
{
TReport_book book;
ok = book.add(rep);
if (ok)
book.print_or_preview();
}
} //if(righe_items>0...
}
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"));
return TSkeleton_application::create();
}
int ps0099100(int argc, char* argv[])
{
TStatistiche_ANIVAL stat_anal;
stat_anal.run(argc, argv, TR("Statistiche ANIVAL"));
return 0;
}