Files correlati : Ricompilazione Demo : [ ] Commento : personalizzazione anival the canival git-svn-id: svn://10.65.10.50/trunk@17900 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			363 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			363 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#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;
 | 
						||
} |