Files correlati : Ricompilazione Demo : [ ] Commento : Dalla 5.0: 1) corretto errore in caso di mancanza campo prefix sulla maschera 2) gestite le commessa senza Datafine (Ruffo) git-svn-id: svn://10.65.10.50/trunk@17211 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			1311 lines
		
	
	
		
			43 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1311 lines
		
	
	
		
			43 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include <progind.h>
 | 
						|
 | 
						|
#include "calib01.h"
 | 
						|
#include "calib02.h"
 | 
						|
#include "ca3883.h"
 | 
						|
 | 
						|
#include "panapdc.h"
 | 
						|
#include "pconana.h"
 | 
						|
#include "commesse.h"
 | 
						|
#include "fasi.h"
 | 
						|
#include "saldana.h"
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
// Classe per ricavare l'indicatore di bilancio dei conti analitici riclassificati e non
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
TObject* TIndbil_cache::key2obj(const char* key)
 | 
						|
{
 | 
						|
	TString80 conto = key;
 | 
						|
	if (_usepdcc && conto.len() == 12 && real::is_natural(conto))
 | 
						|
	{
 | 
						|
		TLocalisamfile panapdc(LF_PANAPDC);
 | 
						|
		panapdc.setkey(2);
 | 
						|
		const int gr = atoi(conto.left(3));
 | 
						|
		const int co = atoi(conto.mid(3,3));
 | 
						|
		const long so = atol(conto.mid(6,6));
 | 
						|
 | 
						|
		TRectype& panapdrec = panapdc.curr();
 | 
						|
    int i;
 | 
						|
		for (i = 2; i >= 0; i--)
 | 
						|
		{
 | 
						|
			panapdrec.zero();
 | 
						|
			panapdrec.put(PANAPDC_GRUPPO, gr);
 | 
						|
			if (i > 0)
 | 
						|
				panapdrec.put(PANAPDC_CONTO, co);
 | 
						|
			if (i == 2)
 | 
						|
				panapdrec.put(PANAPDC_SOTTOCONTO, so);
 | 
						|
 | 
						|
			//occhio al prefisso!
 | 
						|
			panapdrec.put(PANAPDC_CODCONTO, _prefix);
 | 
						|
 | 
						|
			if (panapdc.read(_isgteq) == NOERR)
 | 
						|
			{
 | 
						|
				bool found = panapdrec.get_int(PANAPDC_GRUPPO) == gr;
 | 
						|
				if (found)
 | 
						|
  				found = panapdrec.get_int(PANAPDC_CONTO) == (i > 0 ? co : 0);
 | 
						|
			  if (found)
 | 
						|
				  found = panapdrec.get_long(PANAPDC_SOTTOCONTO) == (i > 1 ? so : 0L);
 | 
						|
				if (found && _prefix.full())
 | 
						|
					found = panapdrec.get(PANAPDC_CODCONTO).starts_with(_prefix);
 | 
						|
 | 
						|
				if (found)
 | 
						|
				{
 | 
						|
				  conto = panapdrec.get(PANAPDC_CODCONTO);
 | 
						|
          if (cache().get(LF_PCONANA, conto).empty())
 | 
						|
            error_box(FR("Non esiste piu' il conto %s cui era legato %d %d %ld"), 
 | 
						|
                      (const char*)conto, gr, co, so);
 | 
						|
          else
 | 
						|
				    break;
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
		//se non trova il corrispondente conto analitico azzera il conto per il prossimo giro
 | 
						|
		if (i < 0)
 | 
						|
			conto.cut(0);
 | 
						|
	}
 | 
						|
	//conto analitico
 | 
						|
	TAnal_bill bill(conto);
 | 
						|
	int indbil = bill.indicatore_bilancio();
 | 
						|
	TToken_string* ib = new TToken_string;
 | 
						|
	*ib << indbil;
 | 
						|
	ib->add(conto);
 | 
						|
	return ib;
 | 
						|
}
 | 
						|
 | 
						|
int TIndbil_cache::get_indbil(const TString& conto, TString& conto_anale)
 | 
						|
{
 | 
						|
  int indicatore = 0;
 | 
						|
	TToken_string* ib = (TToken_string*)objptr(conto);
 | 
						|
	if (ib != NULL)
 | 
						|
  {
 | 
						|
	  indicatore = ib->get_int(0);
 | 
						|
		ib->get(1, conto_anale);
 | 
						|
  }
 | 
						|
  return indicatore;
 | 
						|
}
 | 
						|
 | 
						|
void TIndbil_cache::set_prefix(const char* prefix)
 | 
						|
{
 | 
						|
	if (_prefix != prefix)
 | 
						|
	{
 | 
						|
		_prefix = prefix;
 | 
						|
		destroy();
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
TIndbil_cache::TIndbil_cache()
 | 
						|
{
 | 
						|
	TConfig& cfg = ca_config();
 | 
						|
	_usepdcc = cfg.get_bool("UsePdcc");
 | 
						|
}
 | 
						|
 | 
						|
/////////////////////////////////////////////////////////////////////////////////
 | 
						|
//Classe di report speciale con numero colonne adattabile in base ad un parametro
 | 
						|
/////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
void TCRPA_report::merge_array(TString_array& c, TString_array& t, 
 | 
						|
															 TString_array& codici, TString_array& testate) const
 | 
						|
{
 | 
						|
	while (c.items() > 0)
 | 
						|
	{
 | 
						|
		TObject* cod = c.remove(0,true);
 | 
						|
		TObject* tes = t.remove(0,true);
 | 
						|
		codici.TArray::add(cod);
 | 
						|
		testate.TArray::add(tes);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void TCRPA_report::analize_pconana_structure (const TString& prefix, const int depth, 
 | 
						|
																						 TString_array& codici, TString_array& testate) const
 | 
						|
{
 | 
						|
	//cerca quale e' la lunghezza della stringa conto da considerare in base alla depth scelta
 | 
						|
	TConfig& cfg = ca_config();
 | 
						|
  const TMultilevel_code_info& pconana_info = ca_multilevel_code_info(LF_PCONANA);
 | 
						|
  const long total_length = pconana_info.total_len(depth);
 | 
						|
	
 | 
						|
	//scandisce il piano dei conti analitico alla ricerca dei conti di lunghezza pari a..
 | 
						|
	//..quella appena ricavata
 | 
						|
	TISAM_recordset recset("USE PCONANA\nSELECT LEN(CODCONTO)=#LUN\nFROM CODCONTO=#PREFIX\nTO CODCONTO=#PREFIX");
 | 
						|
	recset.set_var("#LUN", TVariant(total_length));
 | 
						|
	recset.set_var("#PREFIX", TVariant(prefix));
 | 
						|
	const int prefix_length = prefix.len();
 | 
						|
 | 
						|
	TString_array codici_c, testate_c, codici_r, testate_r;
 | 
						|
 | 
						|
	//riempie gli array con i codici conto di lunghezza opportuna e relative testate
 | 
						|
  TString80 codice;
 | 
						|
	for (bool ok = recset.move_first(); ok; ok = recset.move_next())
 | 
						|
	{
 | 
						|
		const TString& codconto = recset.get(PCONANA_CODCONTO).as_string();
 | 
						|
 | 
						|
		const TAnal_bill zio(codconto);
 | 
						|
		const int indbil = zio.indicatore_bilancio();
 | 
						|
		//solo Costi e Ricavi!
 | 
						|
		if (indbil == 3 || indbil == 4)
 | 
						|
		{
 | 
						|
      codice.cut(0) << "#RECORD." << codconto.mid(prefix_length);
 | 
						|
			const TString& testata = zio.testata();
 | 
						|
			if (indbil == 3)
 | 
						|
			{
 | 
						|
				codici_c.add(codice);
 | 
						|
				testate_c.add(testata);
 | 
						|
			}
 | 
						|
			else
 | 
						|
			{
 | 
						|
				codici_r.add(codice);
 | 
						|
				testate_r.add(testata);
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	if (codici_r.items() == 1)	//se il campo da stampare e' uno solo->e' il totale del livello
 | 
						|
	{
 | 
						|
		codici_r.destroy();
 | 
						|
		testate_r.destroy();
 | 
						|
	}
 | 
						|
	codici_r.add("#RICAVI");
 | 
						|
	testate_r.add(TR("RICAVI"));
 | 
						|
 | 
						|
	//..analogo per i Costi
 | 
						|
	if (codici_c.items() == 1)
 | 
						|
	{
 | 
						|
		codici_c.destroy();
 | 
						|
		testate_c.destroy();
 | 
						|
	}
 | 
						|
	codici_c.add("#COSTI");
 | 
						|
	testate_c.add(TR("COSTI"));
 | 
						|
 | 
						|
	//condensa gli array di Costo e Ricavo in un unico array che servira' di base per la stampa
 | 
						|
	merge_array(codici_r, testate_r, codici, testate);
 | 
						|
	merge_array(codici_c, testate_c, codici, testate);
 | 
						|
}
 | 
						|
 | 
						|
//metodo per il riempimento e lo spostamento dei campi della sola sezione F4 (totali di commessa)
 | 
						|
void TCRPA_report::offset_and_fill_sectionf4(TReport_section& rep_sect, const int model_id)
 | 
						|
{
 | 
						|
  //campo modello
 | 
						|
  TReport_field& rep_field = *rep_sect.find_field(model_id);
 | 
						|
  //nuovo campo
 | 
						|
	TReport_field* new_field = (TReport_field*)rep_field.dup();
 | 
						|
  //lo aggiunge alla sezione
 | 
						|
  rep_sect.add(new_field);
 | 
						|
  //gli da' l'id (e' il terzultimo campo)
 | 
						|
  TReport_section& b1 = section('B', 1);
 | 
						|
  const int body_fields_number = b1.items();
 | 
						|
  TReport_field& fld_costi = b1.field(body_fields_number - 3);
 | 
						|
	new_field->set_id(fld_costi.id());
 | 
						|
   
 | 
						|
  //posiziona tutti i campi della sezione
 | 
						|
  for (int i = 0; i < rep_sect.items(); i++)
 | 
						|
  {
 | 
						|
    //c'e' il campo con il mio numero (id) in questa sezione?
 | 
						|
    TReport_field& brock = rep_sect.field(i);
 | 
						|
    if (brock.id() >= model_id)
 | 
						|
    {
 | 
						|
      //se c'e' cerco nel body il mio omonumero; se lo trovo mi allineo come lui
 | 
						|
      //Es.: campi testata di pagina compaiono e si allineano in base ai campi body (fase,cdc ecc.)
 | 
						|
      TReport_field* champ = b1.find_field(brock.id());
 | 
						|
      if (champ != NULL)
 | 
						|
        brock.set_column(champ->get_rect().left());
 | 
						|
    }
 | 
						|
  }
 | 
						|
 
 | 
						|
}
 | 
						|
 | 
						|
//metodo per il riempimento e lo spostamento dei campi dinamici
 | 
						|
void TCRPA_report::offset_and_fill_columns(TReport_section& rep_sect, const TString_array& str_arr, 
 | 
						|
                                           const int model_id, const bool show_fasi, const bool show_cdc)
 | 
						|
{
 | 
						|
  //solo nel caso sia richiesta la sparizione di un campo...
 | 
						|
  if (!show_fasi || !show_cdc)
 | 
						|
  {
 | 
						|
    if (rep_sect.type() == 'B') //campi del body
 | 
						|
    {
 | 
						|
      //gestione campi a sinistra del campo modello
 | 
						|
      //la gestione dei campi a sinistra e' guidata dalle scelte utente sulla maschera
 | 
						|
      TReport_field* fld_fase = rep_sect.find_field(3);
 | 
						|
      if (fld_fase != NULL)   //in caso non esista il campo non deve fare nulla (report riassuntivi x fase/cdc)
 | 
						|
      {
 | 
						|
        TReport_field* fld_cdc = rep_sect.find_field(4);
 | 
						|
        TReport_field* fld_perc = rep_sect.find_field(5);
 | 
						|
 | 
						|
        int x0 = fld_fase->get_rect().left();
 | 
						|
        //mostra le fasi
 | 
						|
        if (show_fasi)
 | 
						|
          x0 = fld_fase->get_rect().right();
 | 
						|
        else
 | 
						|
          fld_fase->deactivate();  //era meglio hide() che deactivate() ma non bastava!
 | 
						|
 | 
						|
        if (fld_cdc != NULL)
 | 
						|
        {
 | 
						|
          if (show_cdc)
 | 
						|
          {
 | 
						|
            fld_cdc->set_column(x0);
 | 
						|
            x0 = fld_cdc->get_rect().right();
 | 
						|
          }
 | 
						|
          else
 | 
						|
            fld_cdc->deactivate();
 | 
						|
        }
 | 
						|
 | 
						|
        if (fld_perc != NULL)
 | 
						|
        {
 | 
						|
          //campo percentuale
 | 
						|
          fld_perc->set_column(x0);
 | 
						|
          x0 = fld_perc->get_rect().right();
 | 
						|
        }
 | 
						|
 | 
						|
        //campo modello
 | 
						|
        rep_sect.find_field(model_id)->set_column(x0);
 | 
						|
      } //if(fld_fase!=NULL..
 | 
						|
    }
 | 
						|
    else  //campi non del body
 | 
						|
    {
 | 
						|
      TReport_section& b1 = section('B', 1);
 | 
						|
      //sistema i campi tipo testata
 | 
						|
      for (int i = 0; i < rep_sect.items(); i++)
 | 
						|
      {
 | 
						|
        //c'e' il campo con il mio numero (id) in questa sezione?
 | 
						|
        TReport_field& brock = rep_sect.field(i);
 | 
						|
        const int id = brock.id();
 | 
						|
        if (id > 0)
 | 
						|
        {
 | 
						|
          //se c'e' cerco nel body il mio omonumero; se lo trovo mi mostro e allineo come lui
 | 
						|
          //Es.: campi testata di pagina compaiono e si allineano in base ai campi body (fase,cdc ecc.)
 | 
						|
          TReport_field* champ = b1.find_field(id);
 | 
						|
          if (champ != NULL)
 | 
						|
          {
 | 
						|
            brock.activate(champ->active());
 | 
						|
            brock.set_column(champ->get_rect().left());
 | 
						|
          }
 | 
						|
        } //if(id>0..
 | 
						|
      } //for(int i=0;...
 | 
						|
    } //else di if(rep_sect.type()=='B'... 
 | 
						|
  } //if(!show_fasi||!show_cdc...
 | 
						|
 | 
						|
	TReport_field& rep_field = *rep_sect.find_field(model_id);
 | 
						|
 | 
						|
  //prende il rettangolo del campo modello..
 | 
						|
	const TRectangle& rep_field_rect = rep_field.get_rect();
 | 
						|
 | 
						|
	//deve spostare i campi a destra della colonna modello
 | 
						|
	//si memorizza i campi a destra del campo modello per poterli mettere a destra di tutti..
 | 
						|
	//..i campi che saranno generati
 | 
						|
	TPointer_array campi_a_destra;
 | 
						|
	for (int j = 0; j < rep_sect.items(); j++)
 | 
						|
	{
 | 
						|
		const TReport_field& campo = rep_sect.field(j);
 | 
						|
    //solo i campi con un identificatore vanno spostati; gli altri sono parte dello sfondo
 | 
						|
    if (campo.id() > model_id)
 | 
						|
    {
 | 
						|
		  const TRectangle& rct = campo.get_rect();
 | 
						|
		  //se il campo e' a destra del modello lo aggiunge all'array dei campi_a_destra
 | 
						|
		  if (rct.left() >= rep_field_rect.right())
 | 
						|
			  campi_a_destra.add(campo);
 | 
						|
    }
 | 
						|
	}
 | 
						|
 | 
						|
	//duplica il campo modello e riempie i duplicati con i valori degli array
 | 
						|
	//serve il tipo di sezione poiche' gli header vanno trattati diversamente dai body
 | 
						|
	const char sect_type = rep_sect.type();
 | 
						|
 | 
						|
	//ciclo su tutti gli elementi dell'array con i valori da settare nei nuovi campi
 | 
						|
	for (int i = 0; i < str_arr.items(); i++)
 | 
						|
	{
 | 
						|
    //crea il nuovo campo i-esimo, copia del modello, spostato a destra rispetto al precedente (i-1)esimo..
 | 
						|
    //.., con id(i) = id(i-1) + 1
 | 
						|
		TReport_field* new_field = i == 0 ? &rep_field : (TReport_field*)rep_field.dup();
 | 
						|
		if (i > 0)
 | 
						|
		{
 | 
						|
			rep_sect.add(new_field);
 | 
						|
			new_field->set_pos(rep_field_rect.left() + rep_field_rect.width() * i, rep_field_rect.top());
 | 
						|
			new_field->set_id(rep_field.id() + i);
 | 
						|
		}
 | 
						|
		switch (sect_type)
 | 
						|
		{
 | 
						|
		case 'H':	//gli header devono stampare l'intestazione
 | 
						|
			{
 | 
						|
				new_field->set_picture(str_arr.row(i));
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		case 'B':	//i body devono stampare i valori e sommarli ai totali nei footer
 | 
						|
			{
 | 
						|
				new_field->set_field(str_arr.row(i));
 | 
						|
				TString ps = "MESSAGE ADD,F3.";
 | 
						|
				ps << new_field->id();
 | 
						|
 | 
						|
        if (find_section('F', 4) != NULL)
 | 
						|
          ps << "|ADD,F4." << new_field->id();
 | 
						|
				
 | 
						|
        new_field->set_postscript(ps);
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		case 'F':	//i footer devono calcolarsi i totali;ma i footer di totale fasi (4) non devono..
 | 
						|
      //..fare assolutamente nulla!
 | 
						|
			if (rep_sect.level() > 0 && rep_sect.level() < 4)
 | 
						|
			{
 | 
						|
        //crea il campo sul report con tanto di id,postscript ecc...
 | 
						|
			  new_field->set_field("");
 | 
						|
 | 
						|
        switch (rep_sect.level())
 | 
						|
        {
 | 
						|
        case 1:
 | 
						|
        {
 | 
						|
          //caso particolare del footer di report con i totali alla Adolf!
 | 
						|
          //Dalla matematica secondo Adolf:
 | 
						|
          //(a) TotGen = TotCmsNor + TotCmsSupp
 | 
						|
          //(b) DiffGen = TotCmsSupp - TotCmsNor
 | 
						|
          //->(c) DiffGen = TotGen - 2*TotCmsNor
 | 
						|
 | 
						|
          //i campi del totale generale si sommano ai campi delle differenze di Adolf
 | 
						|
          /**CAZZONE** tentata per utilizzare la (c) ma non funziona:questi non servono a una ceppa di minchia
 | 
						|
          new_field->set_field("");
 | 
						|
          TString ps = "MESSAGE ADD,F";
 | 
						|
	        ps << (rep_sect.level()) << '.' << (new_field->id() + 200);
 | 
						|
          new_field->set_prescript(ps);*/   
 | 
						|
 | 
						|
          //sub_new_field e' il campo SOTTO il new_field che appare solo nei totali di sezione 1 (F1)
 | 
						|
          //e' il campo che va nella riga delle Differenze
 | 
						|
          TReport_field* sub_new_field = (TReport_field*)new_field->dup();
 | 
						|
 			    rep_sect.add(sub_new_field);
 | 
						|
          sub_new_field->offset(TPoint(0, 250));
 | 
						|
          sub_new_field->set_id(new_field->id() + 200);
 | 
						|
          sub_new_field->set_groups("90");
 | 
						|
          sub_new_field->set_prescript("");
 | 
						|
        }
 | 
						|
          break;
 | 
						|
 | 
						|
        case 2:
 | 
						|
          {
 | 
						|
            //ogni campo di footer F2 deve sommarsi a quello piu' esterno F1
 | 
						|
            TString ps = "MESSAGE ADD,F";
 | 
						|
			      ps << (rep_sect.level() - 1) << '.' << new_field->id();
 | 
						|
 | 
						|
            //in caso di Commesse Supporto (LEVEL=4) il totale si deve sommare nelle differenze generali
 | 
						|
            ps << "\n#101 @\n";
 | 
						|
            ps << "4 = IF\n";
 | 
						|
            ps << "  MESSAGE ADD,F1." << (new_field->id() + 200) << "\n";
 | 
						|
            ps << "THEN";
 | 
						|
 | 
						|
            //setta il postscript al new_field
 | 
						|
            new_field->set_postscript(ps);
 | 
						|
 | 
						|
            //SUB_new_field, ovvero gestione dei campi adolfici dei totali e delle differenze
 | 
						|
            //Gestione totali delle commesse normali (Adolf!)
 | 
						|
            //Alla fine di tutte le 4 sezioni di commesse normali ci va il totale delle medesime; questo..
 | 
						|
            //..totale va stampato prima della sezione con le commesse di appoggio
 | 
						|
 | 
						|
            //sub_new_field e' il campo SOTTO il new_field che appare solo nei totali di sezione 2 (F2)
 | 
						|
            //e' il campo con il totale delle commesse normali
 | 
						|
            TReport_field* sub_new_field = (TReport_field*)new_field->dup();
 | 
						|
   			    rep_sect.add(sub_new_field);
 | 
						|
            sub_new_field->offset(TPoint(0, 250));
 | 
						|
            sub_new_field->set_id(new_field->id() + 200);
 | 
						|
            sub_new_field->set_groups("90");
 | 
						|
            sub_new_field->set_postscript("");
 | 
						|
 | 
						|
            //il totale delle commesse normali si sottrae nelle differenze generali
 | 
						|
            TString ps_diff;
 | 
						|
            //ps_diff << "#THIS @\n2\n*\n!\n";  **CAZZONE** tentata per applicare la (c);non funzia
 | 
						|
            ps_diff << "MESSAGE SUB,F1." << sub_new_field->id();
 | 
						|
            sub_new_field->set_postscript(ps_diff);
 | 
						|
          }
 | 
						|
          break;
 | 
						|
 | 
						|
        case 3:
 | 
						|
          {
 | 
						|
            //ogni campo di footer F3 deve sommarsi a quello piu' esterno F2
 | 
						|
            TString ps = "MESSAGE ADD,F";
 | 
						|
			      ps << (rep_sect.level() - 1) << '.' << new_field->id();
 | 
						|
            //deve anche sommarsi al totale delle Commesse Normali (che viene stampato al passaggio tra..
 | 
						|
            //..LEVEL=3 e LEVEL=4)
 | 
						|
            ps << "\nMESSAGE ADD,F2." << (new_field->id() + 200);
 | 
						|
            //setta il postscript al new_field
 | 
						|
            new_field->set_postscript(ps);
 | 
						|
          }
 | 
						|
          break;
 | 
						|
        default:
 | 
						|
          break;
 | 
						|
        } //switch(rep_sect.level())
 | 
						|
      }
 | 
						|
			break;
 | 
						|
		default:
 | 
						|
			break;
 | 
						|
		} //switch (sect_type)
 | 
						|
	} //for(inti=0;i<str_arr.items()...
 | 
						|
 | 
						|
	//sposta a destra gli ultimi campi non generati (169 e 170)
 | 
						|
	const TReport_field& ultimo_campo = rep_sect.field(rep_sect.last());
 | 
						|
  int x0 = ultimo_campo.get_rect().right();
 | 
						|
	for (int k = 0; k < campi_a_destra.items(); k++)
 | 
						|
	{
 | 
						|
		TReport_field& campo = (TReport_field&)campi_a_destra[k];
 | 
						|
		campo.set_column(x0);
 | 
						|
    x0 = campo.get_rect().right();
 | 
						|
	}
 | 
						|
 | 
						|
  //l'ultimo campo (margine di contribuzione) va generato a mano nel caso dei totali delle commesse normali!!
 | 
						|
  if (rep_sect.type() == 'F' && rep_sect.level() == 2)
 | 
						|
  {
 | 
						|
    TReport_field* sub_new_field_margine = (TReport_field*)rep_sect.find_field(169)->dup();
 | 
						|
    rep_sect.add(sub_new_field_margine);
 | 
						|
    sub_new_field_margine->offset(TPoint(0, 250));
 | 
						|
    sub_new_field_margine->set_id(369);
 | 
						|
    sub_new_field_margine->set_groups("90");
 | 
						|
    sub_new_field_margine->set_postscript("");
 | 
						|
  }
 | 
						|
 | 
						|
  //ordina i campi davvero sul report per id
 | 
						|
  rep_sect.sort();
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool TCRPA_report::generate_columns (TString_array& codici, TString_array& testate, const int model_id, 
 | 
						|
                                     const bool show_fasi, const bool show_cdc)
 | 
						|
{
 | 
						|
	//sezioni del report da modificare
 | 
						|
	TReport_section& b1 = section('B', 1);
 | 
						|
	
 | 
						|
	//controllo dell'esistenza dei campi modello da replicare e loro duplicazione e riempimento!
 | 
						|
	TReport_field* b1_model = b1.find_field(model_id);
 | 
						|
	if (b1_model == NULL)
 | 
						|
		return false;
 | 
						|
	offset_and_fill_columns(b1, codici, model_id, show_fasi, show_cdc);
 | 
						|
 | 
						|
	//testate
 | 
						|
	//la testata di pagina deve invece riempire le intestazioni delle colonne generate
 | 
						|
	TReport_section& h0 = section('H', 0);
 | 
						|
 | 
						|
	TReport_field* h0_model = h0.find_field(model_id);
 | 
						|
	if (h0_model == NULL)
 | 
						|
		warning_box(TR("Manca l'intestazione della colonna modello (H0.%d)"),model_id);
 | 
						|
	else
 | 
						|
		offset_and_fill_columns(h0, testate, model_id, show_fasi, show_cdc);
 | 
						|
 | 
						|
	//le testate di sezione devono resettare i campi totale dei corrispondenti footers
 | 
						|
	for (int j = 4; j > 0; j--)
 | 
						|
	{
 | 
						|
		TReport_section& head = section('H', j);
 | 
						|
		if (head.items() > 0)
 | 
						|
		{
 | 
						|
			TString ps(256);
 | 
						|
      ps = "MESSAGE ";
 | 
						|
			//i campi dei totali da resettare sono tanti quante le colonne generate
 | 
						|
			//k=0 per includere la colonna 69!!! usata nel caso i ricavi siano solo di livello 1 (depth=1)
 | 
						|
			for (int k = 0; k <= codici.items(); k++)
 | 
						|
			{		
 | 
						|
				if (k > 0)
 | 
						|
					ps << '|';
 | 
						|
        ps << "RESET,F" << head.level() << '.' << (k+model_id);
 | 
						|
			}
 | 
						|
			head.set_prescript(ps);
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	//footers
 | 
						|
	for (int i = find_max_level('F') - 1; i > 0; i--)
 | 
						|
	{
 | 
						|
	  TReport_section& foot = section('F', i);
 | 
						|
 | 
						|
	  TReport_field* foot_model = foot.find_field(model_id);
 | 
						|
	  if (foot_model == NULL)
 | 
						|
		  warning_box(TR("Manca la colonna modello (F%d.%d)"), i, model_id);
 | 
						|
		else
 | 
						|
			offset_and_fill_columns(foot, codici, model_id, show_fasi, show_cdc);
 | 
						|
	}
 | 
						|
 | 
						|
  //gestione della sezione con i totali di commessa (solo se esiste, visto che non c'e' in tutti i report)
 | 
						|
  TReport_section* f4 = find_section('F', 4); 
 | 
						|
  if (f4 != NULL)
 | 
						|
    offset_and_fill_sectionf4(*f4, model_id);
 | 
						|
 | 
						|
//#ifdef DBG
 | 
						|
  save("cazzone.rep");
 | 
						|
//#endif
 | 
						|
	return true;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
TCRPA_report::TCRPA_report (const char* rep_name, const TString& prefix, const int depth, 
 | 
						|
                            const bool show_fasi, const bool show_cdc)
 | 
						|
{
 | 
						|
	//che report usare?
 | 
						|
	load (rep_name);
 | 
						|
	//array contenenti i conti analitici e le loro descrizioni di testata che diventeranno..
 | 
						|
	//.colonne del report dopo lungo e periglioso travaglio
 | 
						|
	TString_array codici, testate;
 | 
						|
	//per prima cosa si deve analizzare la struttura del piano conti..
 | 
						|
	//..da stampare fino al livello richiesto!
 | 
						|
	analize_pconana_structure (prefix, depth, codici, testate);
 | 
						|
	//poi vanno generate le colonne del report corrispondenti alla struttura analizzata
 | 
						|
	generate_columns (codici, testate, 69, show_fasi, show_cdc);
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////////////
 | 
						|
// roba del recordset
 | 
						|
///////////////////////////////////////////////////////////////////
 | 
						|
const TFixed_string CMS_DEL_CAZZO("@@@@@@@@@@@@@@@@@@@@");
 | 
						|
 | 
						|
static int righe_compare(const TObject** o1, const TObject** o2)
 | 
						|
{
 | 
						|
  TAssoc_array& a1 = *(TAssoc_array*)*o1;
 | 
						|
  TAssoc_array& a2 = *(TAssoc_array*)*o2;
 | 
						|
 | 
						|
  int cmp = 0;
 | 
						|
 | 
						|
  const int l1 = atoi(*(TString*)a1.objptr("LEVEL"));
 | 
						|
  const int l2 = atoi(*(TString*)a2.objptr("LEVEL"));
 | 
						|
  cmp = l1 - l2;
 | 
						|
  if (cmp == 0)
 | 
						|
  {
 | 
						|
    const TString& c1 = *(TString*)a1.objptr("CODCMS");
 | 
						|
    const TString& c2 = *(TString*)a2.objptr("CODCMS");
 | 
						|
    cmp = c1.compare(c2);
 | 
						|
    if (cmp == 0)
 | 
						|
    {
 | 
						|
      const TString& f1 = *(TString*)a1.objptr("FASE");
 | 
						|
      const TString& f2 = *(TString*)a2.objptr("FASE");
 | 
						|
      cmp = f1.compare(f2);
 | 
						|
      if (cmp == 0)
 | 
						|
      {
 | 
						|
        const TString& d1 = *(TString*)a1.objptr("CDC");
 | 
						|
        const TString& d2 = *(TString*)a2.objptr("CDC");
 | 
						|
        cmp = d1.compare(d2);
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
        const int z1 = c1.starts_with("detr_");
 | 
						|
        const int z2 = c2.starts_with("detr_");
 | 
						|
        if (z1 || z2)
 | 
						|
          cmp = z1 - z2;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return cmp;
 | 
						|
}
 | 
						|
/////////////////////////////////////////////////////////////////////////////////
 | 
						|
//Classe di recordset speciale per stampe con saldana (ca3800, ca3900)
 | 
						|
/////////////////////////////////////////////////////////////////////////////////
 | 
						|
bool TPrint_saldana_recordset::move_to(TRecnotype pos)
 | 
						|
{
 | 
						|
	_curr = pos;
 | 
						|
	return pos >= 0 && pos < items();
 | 
						|
}
 | 
						|
 | 
						|
void TPrint_saldana_recordset::parse_bill(const TString& bill, TString& conto) const
 | 
						|
{
 | 
						|
	TConfig& cfg = ca_config();
 | 
						|
  const TMultilevel_code_info& pconana_info = ca_multilevel_code_info(LF_PCONANA);
 | 
						|
  const int pconana_levels = pconana_info.levels();  
 | 
						|
  const int prefix = cfg.get_int("PdcPrefix")-1;
 | 
						|
 | 
						|
	//lunghezza dell'eventuale prefisso di gruppo e conto
 | 
						|
	const int prefix_len = (prefix >= 0) ? pconana_info.total_len(prefix) : 0;
 | 
						|
	//quanto e' lungo il codice del conto da considerare? E' il livello - il prefisso
 | 
						|
	const int conto_end = pconana_info.total_len(_depth) - prefix_len;
 | 
						|
 | 
						|
	//stringa con cio' che segue il prefisso ed e' richiesto
 | 
						|
	conto = bill.mid(prefix_len, conto_end);
 | 
						|
}
 | 
						|
 | 
						|
int TPrint_saldana_recordset::estrai_saldi(const TRecordset& saldana, const int indbil, 
 | 
						|
																					 TImporto& saldo, TImporto& saldop, const bool cms_detraz) const
 | 
						|
{
 | 
						|
	int flag = 0;
 | 
						|
  saldo.reset();
 | 
						|
  saldop.reset();
 | 
						|
 | 
						|
  //stampa bilancio di commessa ca3800 (_tipo=8)
 | 
						|
  if (_tipo == 8)
 | 
						|
  {
 | 
						|
 | 
						|
    switch (_tipostima)
 | 
						|
    {
 | 
						|
    case 'R': //CostiConsuntivi RicaviConsuntivi (Cc/Rc)
 | 
						|
      {
 | 
						|
        const TImporto imp_saldo(saldana.get(SALDANA_SEZIONE).as_string()[0], 
 | 
						|
													       saldana.get(SALDANA_SALDO).as_real());
 | 
						|
        if (!imp_saldo.is_zero())
 | 
						|
        {
 | 
						|
          if (indbil == 3)  //indbil=3 costi
 | 
						|
          {
 | 
						|
	          saldo = imp_saldo;
 | 
						|
 	          flag = 1;
 | 
						|
          }
 | 
						|
          else  //indbil=4 ricavi
 | 
						|
          {
 | 
						|
            saldop = imp_saldo;
 | 
						|
            flag = 2;
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
      break;
 | 
						|
 | 
						|
    case 'C': //CostiConsuntivi RicaviPreventivi (Cc/Rp)
 | 
						|
      {
 | 
						|
        if (indbil == 3)  //costi
 | 
						|
        {
 | 
						|
          const TImporto imp_saldo(saldana.get(SALDANA_SEZIONE).as_string()[0], 
 | 
						|
														       saldana.get(SALDANA_SALDO).as_real());
 | 
						|
		      saldo = imp_saldo;
 | 
						|
		      flag |= saldo.is_zero() ? 0 : 1;
 | 
						|
        }
 | 
						|
        else  //indbil=4 ricavi
 | 
						|
        {
 | 
						|
          const TImporto imp_saldop(saldana.get(SALDANA_SEZIONEP).as_string()[0], 
 | 
						|
															      saldana.get(SALDANA_SALDOP).as_real());
 | 
						|
		      const TImporto imp_saldov(saldana.get(SALDANA_SEZIONEV).as_string()[0], 
 | 
						|
															      saldana.get(SALDANA_SALDOV).as_real());
 | 
						|
		      saldop = imp_saldop;
 | 
						|
		      saldop += imp_saldov;
 | 
						|
		      flag |= saldop.is_zero() ? 0 : 2;
 | 
						|
        }
 | 
						|
      }
 | 
						|
      break;
 | 
						|
 | 
						|
    case 'T': //CostiPreventivi RicaviPreventivi (Cc/Rp) = Tempo
 | 
						|
      //nel caso stia calcolando le detrazioni di anni precedenti (cms_detraz) e si sia scelto di farlo..
 | 
						|
      //..usando i consuntivi (Adolf rikiesten)...
 | 
						|
      if (cms_detraz && _tipodetr)
 | 
						|
      {
 | 
						|
        const TImporto imp_saldo(saldana.get(SALDANA_SEZIONE).as_string()[0], 
 | 
						|
														     saldana.get(SALDANA_SALDO).as_real());
 | 
						|
        saldo = imp_saldo;
 | 
						|
        flag |= saldo.is_zero() ? 0 : 1;
 | 
						|
      }
 | 
						|
      else  //in tutti gli altri casi vanno bene i preventivi
 | 
						|
      {       
 | 
						|
      	const TImporto imp_saldop(saldana.get(SALDANA_SEZIONEP).as_string()[0], 
 | 
						|
															    saldana.get(SALDANA_SALDOP).as_real());
 | 
						|
		    const TImporto imp_saldov(saldana.get(SALDANA_SEZIONEV).as_string()[0], 
 | 
						|
															    saldana.get(SALDANA_SALDOV).as_real());
 | 
						|
		    saldop = imp_saldop;
 | 
						|
		    saldop += imp_saldov;
 | 
						|
		    flag |= saldop.is_zero() ? 0 : 2;
 | 
						|
      }
 | 
						|
      break;
 | 
						|
 | 
						|
    } //switch (_tipostima)...
 | 
						|
 | 
						|
  } //if(_tipo=8...
 | 
						|
  // stampa stima ricavi ca3900 (_tipo=9)
 | 
						|
  else
 | 
						|
  {
 | 
						|
    const TImporto imp_saldo(saldana.get(SALDANA_SEZIONE).as_string()[0], 
 | 
						|
														 saldana.get(SALDANA_SALDO).as_real());
 | 
						|
		saldo = imp_saldo;
 | 
						|
		flag |= saldo.is_zero() ? 0 : 1;
 | 
						|
 | 
						|
		const TImporto imp_saldop(saldana.get(SALDANA_SEZIONEP).as_string()[0], 
 | 
						|
															saldana.get(SALDANA_SALDOP).as_real());
 | 
						|
		const TImporto imp_saldov(saldana.get(SALDANA_SEZIONEV).as_string()[0], 
 | 
						|
															saldana.get(SALDANA_SALDOV).as_real());
 | 
						|
		saldop = imp_saldop;
 | 
						|
		saldop += imp_saldov;
 | 
						|
		flag |= saldop.is_zero() ? 0 : 2;
 | 
						|
 | 
						|
    /* correzione per ottenere la sezione in base all'indicatore di bilancio
 | 
						|
    inutile per ora...
 | 
						|
    const char sezione_positiva = (indbil == 2 || indbil == 3) ? 'D' : 'A';
 | 
						|
    saldo.normalize(sezione_positiva);
 | 
						|
    saldop.normalize(sezione_positiva);*/
 | 
						|
  }
 | 
						|
  return flag;
 | 
						|
}
 | 
						|
 | 
						|
TAssoc_array& TPrint_saldana_recordset::get_row(TAssoc_array& cms, const char* chiave,
 | 
						|
																										 const int indice, const TString& codcms, const TString& fase,
 | 
						|
																										 const TString& cdc, const TString& descrizione) const
 | 
						|
{
 | 
						|
	//cerca se la commessa (e l'eventuale fase) esistono gia' nell'assocarray delle commesse
 | 
						|
	TAssoc_array* riga_array = (TAssoc_array*)cms.objptr(chiave);
 | 
						|
	//se non esiste la crea!
 | 
						|
	if (riga_array == NULL)
 | 
						|
	{
 | 
						|
  	riga_array = new TAssoc_array;
 | 
						|
 | 
						|
		TString4 str_indice;	//l'indice va stringato per l'assoc_array
 | 
						|
	  str_indice << indice;
 | 
						|
		
 | 
						|
		riga_array->add("LEVEL", str_indice);
 | 
						|
		riga_array->add("CODCMS", codcms);
 | 
						|
    if (_tipo == 8)
 | 
						|
    {
 | 
						|
		  riga_array->add("FASE", fase);
 | 
						|
      riga_array->add("CDC", cdc);
 | 
						|
    }
 | 
						|
 | 
						|
		riga_array->add("DESCRIZ", descrizione);
 | 
						|
    //inizializza i campi importo sicuramente presenti (modifica DECISIVA)
 | 
						|
    //senza questa inizializzazione, nel caso trovasse campi nulli (in realta' 0), il bastardo..
 | 
						|
    //..anziche' considerarli 0 ci mette l'ultimo valore != che ha in memoria nella stessa posizione..
 | 
						|
    //..facendo sballare tutti i conti!
 | 
						|
    //bilancio commessa ca3800 (_tipo=8)
 | 
						|
    if (_tipo == 8)
 | 
						|
    {
 | 
						|
      riga_array->add("RICAVI", EMPTY_STRING);
 | 
						|
      riga_array->add("COSTI", EMPTY_STRING);
 | 
						|
    }
 | 
						|
    //stima ricavi ca3900 (_tipo=9)
 | 
						|
    else
 | 
						|
    {
 | 
						|
      riga_array->add("COS_BDG", EMPTY_STRING);
 | 
						|
      riga_array->add("COS_MAT", EMPTY_STRING);
 | 
						|
      riga_array->add("RIC_BDG", EMPTY_STRING);
 | 
						|
      riga_array->add("RIC_MAT", EMPTY_STRING);
 | 
						|
    }
 | 
						|
		
 | 
						|
		//aggiunge la riga all'array-one
 | 
						|
		cms.add(chiave, riga_array);
 | 
						|
	}
 | 
						|
	return *riga_array;
 | 
						|
}
 | 
						|
 | 
						|
//for ca3800 only!
 | 
						|
void TPrint_saldana_recordset::aggiorna_importo(TAssoc_array& riga_array, const TString& livello, 
 | 
						|
     const int indbil, const TRecordset& saldana, const bool inverti, const bool cms_detraz) const
 | 
						|
{
 | 
						|
	TString* str_imp = (TString*)riga_array.objptr(livello);
 | 
						|
	if (str_imp == NULL)
 | 
						|
	{
 | 
						|
		str_imp = new TString;
 | 
						|
		riga_array.add(livello, str_imp);
 | 
						|
	}
 | 
						|
 | 
						|
	//dare o avere?
 | 
						|
	const char sezione = indbil == 3 ? 'D' : 'A';
 | 
						|
	TImporto imp(sezione, real(*str_imp));
 | 
						|
 | 
						|
	//ci sono tutti i tipi di saldo, ma solo quelli che rientrano nei parametri iniziali..
 | 
						|
	//..verranno considerati (_tipostima,indbil)
 | 
						|
	TImporto imp_saldo, imp_saldop;
 | 
						|
  estrai_saldi(saldana, indbil, imp_saldo, imp_saldop, cms_detraz);
 | 
						|
 | 
						|
	if (inverti)  // Devo sottrarre l'importo = gli scambio la sezione
 | 
						|
	{
 | 
						|
  	imp_saldo.swap_section();
 | 
						|
	  imp_saldop.swap_section();
 | 
						|
	}
 | 
						|
  imp += imp_saldo;
 | 
						|
	imp += imp_saldop;
 | 
						|
 | 
						|
	imp.normalize(sezione);
 | 
						|
	*str_imp = imp.valore().string();
 | 
						|
}
 | 
						|
 | 
						|
//for ca3800 only!
 | 
						|
real TPrint_saldana_recordset::calcola_avanzamento_tempo() const
 | 
						|
{
 | 
						|
  real avanzamento;
 | 
						|
 | 
						|
	const TDate& datafinesc = _esc[_anno].fine();
 | 
						|
  TDate dataini, datafine;
 | 
						|
  const TString& codfase = get("FASE").as_string();
 | 
						|
  const TString& codcdc = get("CDC").as_string();
 | 
						|
 | 
						|
  //fasi e cdc non specificati
 | 
						|
  if (codfase.empty())
 | 
						|
  {
 | 
						|
	  const TString& codcms = get("CODCMS").as_string();
 | 
						|
	  const TRectype& rec_commesse = cache().get(LF_COMMESSE, codcms);
 | 
						|
 | 
						|
	  dataini = rec_commesse.get(COMMESSE_DATAINIZIO);
 | 
						|
    //attenzione alle commesse prorogate di nascosto..
 | 
						|
    if (rec_commesse.get_bool(COMMESSE_PROROGA) && rec_commesse.get_date(COMMESSE_DATAPROR).ok())
 | 
						|
      datafine = rec_commesse.get(COMMESSE_DATAPROR);
 | 
						|
    else
 | 
						|
	    datafine = rec_commesse.get(COMMESSE_DATAFINE);
 | 
						|
  }
 | 
						|
  else  //specificata la fase
 | 
						|
  {
 | 
						|
	  const TRectype& rec_fasi = cache().get(LF_FASI, codfase);
 | 
						|
 | 
						|
	  dataini = rec_fasi.get(FASI_DATAINIZIO);
 | 
						|
	  datafine = rec_fasi.get(FASI_DATAFINE);
 | 
						|
  }
 | 
						|
	//Si prende SOLO la Fine Esercizio come riferimento di avanzamento (in realta' si..
 | 
						|
	//..potrebbe usare today al posto di datafinesc se si volesse la situazione ad oggi,..
 | 
						|
	//..ma i calcoli degli importi sarebbero da rivedere). Quindi:
 | 
						|
	//se la commessa finisce prima della fine dell'esercizio 
 | 
						|
	if (datafine < datafinesc)
 | 
						|
		avanzamento = CENTO;
 | 
						|
	//se invece prosegue anche dopo la fine dell'esercizio...
 | 
						|
	else
 | 
						|
	{
 | 
						|
		const long time_gone = datafinesc - dataini;
 | 
						|
		const long durata = datafine - dataini;
 | 
						|
		avanzamento = ((real)(time_gone * CENTO) / durata);
 | 
						|
	}
 | 
						|
  return avanzamento;
 | 
						|
}
 | 
						|
 | 
						|
//for ca3900 only!
 | 
						|
void TPrint_saldana_recordset::incrementa_importo(TAssoc_array& riga_array, 
 | 
						|
		 const TString& livello, const int indbil, const TImporto& saldo, const bool inverti) const
 | 
						|
{
 | 
						|
	TString* str_imp = (TString*)riga_array.objptr(livello);
 | 
						|
	if (str_imp == NULL)
 | 
						|
	{
 | 
						|
		str_imp = new TString;
 | 
						|
		riga_array.add(livello, str_imp);
 | 
						|
	}
 | 
						|
 | 
						|
	//dare o avere?
 | 
						|
	const char sezione = indbil == 3 ? 'D' : 'A';
 | 
						|
	TImporto imp(sezione, real(*str_imp));
 | 
						|
 | 
						|
	if (inverti)  // Devo sottrarre l'importo = gli scambio la sezione
 | 
						|
  	imp -= saldo;
 | 
						|
	else
 | 
						|
    imp += saldo;
 | 
						|
 | 
						|
	imp.normalize(sezione);
 | 
						|
	*str_imp = imp.valore().string();
 | 
						|
}
 | 
						|
 | 
						|
//metodo usato solo per la stima ricavi ca3900 (_tipo=9)
 | 
						|
void TPrint_saldana_recordset::aggiorna_importi(TAssoc_array& riga_array, 
 | 
						|
		         const int indbil, const TRecordset& saldana, const bool inverti) const
 | 
						|
{
 | 
						|
	TString8 livello;
 | 
						|
 | 
						|
	TImporto imp_saldo, imp_saldop;
 | 
						|
 | 
						|
  estrai_saldi(saldana, indbil, imp_saldo, imp_saldop, false);
 | 
						|
 | 
						|
	//saldi normali:Maturato
 | 
						|
	if (!imp_saldo.is_zero())
 | 
						|
	{
 | 
						|
	  livello.format("%s_MAT", indbil == 3 ? "COS" : "RIC");
 | 
						|
		incrementa_importo(riga_array, livello, indbil, imp_saldo, inverti);
 | 
						|
	}
 | 
						|
	//saldi preventivi:Budget
 | 
						|
	if (!imp_saldop.is_zero())
 | 
						|
	{
 | 
						|
	  livello.format("%s_BDG", indbil == 3 ? "COS" : "RIC");
 | 
						|
		incrementa_importo(riga_array, livello, indbil, imp_saldop, inverti);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void TPrint_saldana_recordset::create_lines_to_print(const TString& query)
 | 
						|
{
 | 
						|
  //prende le date di inizio e fine dell'eserizio selezionato sulla maschera
 | 
						|
	TEsercizi_contabili esc;
 | 
						|
	TDate datainiesc, datafinesc;
 | 
						|
	esc.code2range(_anno, datainiesc, datafinesc);
 | 
						|
  //deve procedere al confronto tra le date inizio-fine esercizio e quelle inizio-fine commessa..
 | 
						|
	//..per spostare il record in esame nell'array corretto
 | 
						|
	TAssoc_array cms[NUM_LEVELS];
 | 
						|
 | 
						|
  TISAM_recordset saldana(query);
 | 
						|
 | 
						|
	const long saldana_items = saldana.items();
 | 
						|
 | 
						|
	TProgind pi(saldana_items, "Scansione saldi...", true, true);
 | 
						|
 | 
						|
	for (bool ok = saldana.move_first(); ok; ok = saldana.move_next())
 | 
						|
	{
 | 
						|
		//progind tanto per gradire
 | 
						|
		pi.addstatus(1);
 | 
						|
    if (pi.iscancelled())
 | 
						|
      break;
 | 
						|
 | 
						|
		const TString& codconto = saldana.get(SALDANA_CONTO).as_string();
 | 
						|
		//trova l'indicatore di bilancio
 | 
						|
		TString80 conto_anale;
 | 
						|
 | 
						|
    const int indbil = _indicatori.get_indbil(codconto, conto_anale);
 | 
						|
		//solo i Costi(3) ed i Ricavi(4) devono essere considerati per la stampa
 | 
						|
		if (indbil == 3 || indbil == 4)
 | 
						|
		{
 | 
						|
      //estrae i dati di commessa e le date relative;le date servono successivamente per stabilire...
 | 
						|
      //..le sezioni in cui compariranno le commesse nella stampa
 | 
						|
    	const TString& codcms = saldana.get(SALDANA_COMMESSA).as_string();
 | 
						|
			const TRectype& rec_commesse = cache().get(LF_COMMESSE, codcms);
 | 
						|
			const TDate dataini = rec_commesse.get(COMMESSE_DATAINIZIO);
 | 
						|
 | 
						|
      //per la data fine deve tener conto di eventuali proroghe..
 | 
						|
      TDate datafine;
 | 
						|
      if (rec_commesse.get_bool(COMMESSE_PROROGA) && rec_commesse.get(COMMESSE_DATAPROR).ok())
 | 
						|
			  datafine = rec_commesse.get(COMMESSE_DATAPROR);
 | 
						|
      else
 | 
						|
        datafine = rec_commesse.get(COMMESSE_DATAFINE);
 | 
						|
 | 
						|
      //datafine.ok() va messo per gli utonti che mettono le commesse all'infinito senza specificare la datafine
 | 
						|
      //in questo modo la commessa e' come se terminasse l'anno dopo e viene stampata nella sezione 2 (vedi sotto)
 | 
						|
      if (!datafine.ok())
 | 
						|
      {
 | 
						|
        datafine = datafinesc;
 | 
						|
        datafine.addyear(1);
 | 
						|
      }
 | 
						|
 | 
						|
      //gruppo e conto servono solo per il caso _tipo=8 ma vanno dichiarati e ricavati..
 | 
						|
      //..qui in modo che siano a disposizione delle commesse del cazzo poco sotto
 | 
						|
      const char* gruppo = indbil == 3 ? "COSTI" : "RICAVI";
 | 
						|
      TString80 conto;
 | 
						|
		  parse_bill(conto_anale, conto);
 | 
						|
 | 
						|
			TImporto saldo, saldop;
 | 
						|
			const int flag = estrai_saldi(saldana, indbil, saldo, saldop, false);
 | 
						|
 | 
						|
      //Le commesse vengono suddivise in varie sezioni in base alle loro date di inizio/fine/proroga..
 | 
						|
      //..e al fatto che possono essere di appoggio (Adolf rikiesten!) secondo lo schema:
 | 
						|
      //  _ 0 terminano nell'anno selezionato / iniziate nel passato
 | 
						|
      //  _ 1 terminano nell'anno selezionato / iniziate nell'anno selezionato
 | 
						|
      //  _ 2 terminano nel futuro / iniziate nel passato
 | 
						|
      //  _ 3 terminano nel futuro / iniziate nell'anno selezionato
 | 
						|
      //  _ 4 di appoggio / terminano nell'anno selezionato / iniziate nell'anno selezionato 
 | 
						|
      //      (indice 1 ma di appoggio in pratica)
 | 
						|
			
 | 
						|
      //e' inutile considerare le commesse terminate prima dell'esercizio selezionato..
 | 
						|
			//..cioe' nel passato oppure che iniziano nel futuro!
 | 
						|
			if (datafine >= datainiesc && dataini <= datafinesc)
 | 
						|
			{
 | 
						|
        //indice e' il parametro che stabilisce in quale sezione del report viene stampata la commessa
 | 
						|
        //se la commessa termina prima della fine dell'esercizio selezionato -> indice 0, altrimenti..
 | 
						|
        //..indice 2
 | 
						|
				int indice = datafine <= datafinesc ? 0 : 2;
 | 
						|
        //se poi la commessa inizia dopo la data inizio esercizio selezionato -> l'indice va incrementato..
 | 
						|
        //..di una unita' (viene spostata nella sezione di stampa successiva)
 | 
						|
				if (dataini >= datainiesc)
 | 
						|
					indice++;
 | 
						|
 | 
						|
        //controlla se la commessa e' di appoggio e di indice 1 (inizia e finisce nell'anno selezionato)
 | 
						|
        //in questo caso la commessa ha indice 4 e va nella sezione distaccata in fondo al report (Adolf!)
 | 
						|
        if (indice == 1)
 | 
						|
        {
 | 
						|
          const bool cms_appoggio = rec_commesse.get_bool(COMMESSE_APPOGGIO);
 | 
						|
          if (cms_appoggio)
 | 
						|
            indice = 4;
 | 
						|
        }
 | 
						|
 | 
						|
        //ci sono filtri o raggruppamenti per fase o centro di costo?
 | 
						|
        const TString& fase = saldana.get(SALDANA_FASE).as_string();
 | 
						|
        const TString& cdc = saldana.get(SALDANA_COSTO).as_string();
 | 
						|
				TString80 chiave = codcms;
 | 
						|
        //selezione fasi solo su bilancio commessa (_tipo=8)
 | 
						|
        if (_tipo == 8 && (_tipostampa >= 1 && _tipostampa <= 3))
 | 
						|
        {
 | 
						|
          //se vuole entrambi i livelli di dettaglio occorre sapere chi e' il babbo delle fasi o dei cdc
 | 
						|
          if (_tipostampa == 3)
 | 
						|
          {
 | 
						|
            //le fasi sono figlie dei cdc?
 | 
						|
            if (ca_multilevel_code_info(LF_FASI).parent() == LF_CDC)
 | 
						|
              chiave << '|' << cdc << '|' << fase;
 | 
						|
            else  //in ogni altro caso (figlie delle commesse o di nessuno...)
 | 
						|
					    chiave << '|' << fase << '|' << cdc;
 | 
						|
          }
 | 
						|
          else  //livelli di dettaglio semplici
 | 
						|
          {
 | 
						|
            if (_tipostampa == 1)
 | 
						|
					    chiave << '|' << fase;    //dettaglia x fase
 | 
						|
            else
 | 
						|
              chiave << '|' << cdc;     //dettaglia x cdc
 | 
						|
          }
 | 
						|
        }
 | 
						|
 | 
						|
				//riempie le righe degli array da mandare poi in stampa
 | 
						|
				//dapprima le righe normali..
 | 
						|
        //bilancio di commessa ca3800 (_tipo=8)
 | 
						|
        if (_tipo == 8)
 | 
						|
        {
 | 
						|
          TAssoc_array& riga_array = get_row(cms[indice], chiave, indice, codcms, fase, cdc,
 | 
						|
																					   rec_commesse.get(COMMESSE_DESCRIZ));
 | 
						|
 | 
						|
				  //aggiunge gli importi e normalizza
 | 
						|
				  aggiorna_importo(riga_array, gruppo, indbil, saldana);
 | 
						|
				  aggiorna_importo(riga_array, conto, indbil, saldana);
 | 
						|
 | 
						|
          //aggiorna totali della commessa (importi per codcms senza tener conto di fase o cdc)
 | 
						|
          TAssoc_array& riga_tot = get_row(_totali[indice], codcms, indice, codcms, EMPTY_STRING, EMPTY_STRING,
 | 
						|
																					 gruppo);
 | 
						|
				  aggiorna_importo(riga_tot, gruppo, indbil, saldana);
 | 
						|
        }
 | 
						|
        //stima ricavi ca3900 (_tipo=9)
 | 
						|
        else
 | 
						|
        {
 | 
						|
          TAssoc_array& riga_array = get_row(cms[indice], chiave, indice, codcms, EMPTY_STRING, EMPTY_STRING, 
 | 
						|
																					   rec_commesse.get(COMMESSE_DESCRIZ));
 | 
						|
          //aggiunge gli importi e normalizza
 | 
						|
				  aggiorna_importi(riga_array, indbil, saldana);
 | 
						|
 | 
						|
        }
 | 
						|
 | 
						|
			}	//if (datafine >= datainiesc &&...
 | 
						|
 | 
						|
 | 
						|
  		//RIGHE COMMESSA DETRAZIONE: esistono solo se la commessa e' iniziata prima dell'anno
 | 
						|
			//selezionato e se ha a che fare con quello in corso,quindi l'indice e' 0 o 2
 | 
						|
      if (datafine >= datainiesc && dataini < datainiesc)
 | 
						|
			{
 | 
						|
        //indice e' il parametro che stabilisce in quale sezione del report viene stampata la commessa
 | 
						|
        //se la commessa termina prima della fine dell'esercizio selezionato -> indice 0, altrimenti..
 | 
						|
        //..indice 2
 | 
						|
				const int indice = datafine <= datafinesc ? 0 : 2;
 | 
						|
				//aggiorna il record speciale con la somma dei saldi con anno anteriore a quello..
 | 
						|
				//..selezionato sulla maschera (CRPA request)
 | 
						|
				const int anno = saldana.get(SALDANA_ANNO).as_int();
 | 
						|
				if (anno < _anno)
 | 
						|
				{
 | 
						|
					TString16 cazzo_cod; cazzo_cod.format("detr_al_%04d", _anno - 1);  
 | 
						|
					TString cazzo_descr = "DETRAZIONE PER COMPETENZA FINO AL ";
 | 
						|
					cazzo_descr << (_anno - 1);
 | 
						|
          TAssoc_array& riga_array = get_row(cms[indice], CMS_DEL_CAZZO, indice, cazzo_cod, 
 | 
						|
																						 EMPTY_STRING, EMPTY_STRING, cazzo_descr);
 | 
						|
          if (_tipo == 8)
 | 
						|
          {
 | 
						|
            //cms_detr con tipo detrazione a consuntivo o preventivo in base al valore di _tipodetr
 | 
						|
					  aggiorna_importo(riga_array, gruppo, indbil, saldana, true, _tipodetr);
 | 
						|
					  aggiorna_importo(riga_array, conto, indbil, saldana, true, _tipodetr);
 | 
						|
          }
 | 
						|
          else
 | 
						|
          {
 | 
						|
					  aggiorna_importi(riga_array, indbil, saldana, true);
 | 
						|
          }
 | 
						|
				} //if(anno<_anno...
 | 
						|
			}	//if(dataini<datainiesc...
 | 
						|
 | 
						|
		}	//if (indbil == 3 ||...
 | 
						|
	} //for(bool ok=saldana.move_first()..
 | 
						|
 | 
						|
	//merging dei 5 arrayini cms nell'arrayone _righe da mandare in stampa
 | 
						|
	_righe.destroy();
 | 
						|
	for (int i = 0; i < 5; i++)
 | 
						|
	{
 | 
						|
		TAssoc_array& a = cms[i];
 | 
						|
		TObject* cazzo_cms = NULL;
 | 
						|
    
 | 
						|
		FOR_EACH_ASSOC_OBJECT(a, h, k, r)
 | 
						|
		{
 | 
						|
      TObject* obj = h->remove_obj();
 | 
						|
			if (strcmp(k, CMS_DEL_CAZZO) == 0)
 | 
						|
        cazzo_cms = obj;
 | 
						|
			else
 | 
						|
			  _righe.add(obj); // Copia nella destinazione la riga corrente e la toglie dall'originale
 | 
						|
		}
 | 
						|
    if (cazzo_cms != NULL)
 | 
						|
			_righe.add(cazzo_cms);
 | 
						|
	}	//for(int...
 | 
						|
  _righe.sort(righe_compare);  //sorting delle commesse
 | 
						|
}
 | 
						|
 | 
						|
void TPrint_saldana_recordset::requery()
 | 
						|
{
 | 
						|
	TString query;
 | 
						|
	query = "USE SALDANA";  //vale sia per la 8 che per la 9
 | 
						|
 | 
						|
  //se ca3800...
 | 
						|
  if (_tipo == 8)
 | 
						|
  {
 | 
						|
    switch (_tipostampa)
 | 
						|
    {
 | 
						|
    case 1:
 | 
						|
    case 4:
 | 
						|
      if (_fase.full())
 | 
						|
        query << " SELECT FASE=\"" << _fase << "\"";
 | 
						|
      break;
 | 
						|
    case 2:
 | 
						|
    case 8:
 | 
						|
      if (_cdc.full())
 | 
						|
        query << " SELECT COSTO=\"" << _cdc << "\"";
 | 
						|
      break;
 | 
						|
    case 3:
 | 
						|
      if (_fase.full() || _cdc.full())
 | 
						|
      {
 | 
						|
        if (_fase.full() && _cdc.full())
 | 
						|
          query << " SELECT (FASE=\"" << _fase << "\")&&(COSTO=\"" << _cdc << "\")";
 | 
						|
        else
 | 
						|
        {
 | 
						|
          if (_fase.full())
 | 
						|
            query << " SELECT FASE=\"" << _fase << "\"";
 | 
						|
          else
 | 
						|
            query << " SELECT COSTO=\"" << _cdc << "\"";
 | 
						|
        }
 | 
						|
      }      
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    //stampa standard non a vita intera per la 3800
 | 
						|
    if (!_vitaintera)
 | 
						|
	    query << "\nTO ANNO=" << _anno;
 | 
						|
  } //if(_tipo==8..
 | 
						|
 | 
						|
  if (_tipo == 9)
 | 
						|
  {
 | 
						|
    query << "\nTO ANNO=" << _anno; //non vanno considerati saldi di esercizi futuri a quello scelto!!!
 | 
						|
  }
 | 
						|
 | 
						|
  //crea effettivamente la stampa !!!
 | 
						|
  create_lines_to_print(query);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
const TVariant& TPrint_saldana_recordset::get(unsigned int column) const
 | 
						|
{
 | 
						|
  return NULL_VARIANT;
 | 
						|
}
 | 
						|
 | 
						|
const TVariant& TPrint_saldana_recordset::get(const char* column_name) const
 | 
						|
{
 | 
						|
	if (_curr >= 0 && _curr < items())
 | 
						|
	{
 | 
						|
		if (*column_name == '#')
 | 
						|
			column_name++;
 | 
						|
		
 | 
						|
  	TVariant& var = get_tmp_var();
 | 
						|
		if (strcmp(column_name, "ANNO") == 0)
 | 
						|
		{
 | 
						|
			var.set(_anno);
 | 
						|
		}
 | 
						|
		else
 | 
						|
		if (strcmp(column_name, "TIPOSTIMA") == 0)
 | 
						|
		{
 | 
						|
      switch (_tipostima)
 | 
						|
      {
 | 
						|
      case 'T':
 | 
						|
        var.set("T");
 | 
						|
        break;
 | 
						|
      case 'C':
 | 
						|
        var.set("C");
 | 
						|
        break;
 | 
						|
      case 'R':
 | 
						|
        var.set("R");
 | 
						|
        break;
 | 
						|
      default:
 | 
						|
        break;
 | 
						|
      }
 | 
						|
		}
 | 
						|
		else
 | 
						|
		if (strcmp(column_name, "DEPTH") == 0)
 | 
						|
		{
 | 
						|
      var.set(_depth);
 | 
						|
		}
 | 
						|
    else
 | 
						|
    if (strcmp(column_name, "TIPODETR") == 0)
 | 
						|
    {
 | 
						|
      var.set(_tipodetr == true ? "X" : "");
 | 
						|
    }
 | 
						|
    else
 | 
						|
    if (strcmp(column_name, "VITAINTERA") == 0)
 | 
						|
		{
 | 
						|
      var.set(_vitaintera  == true ? "SI" : "NO");
 | 
						|
		}
 | 
						|
		else
 | 
						|
    if (strcmp(column_name, "STAMPAFASI") == 0)
 | 
						|
		{
 | 
						|
      var.set((_tipostampa == 1 || _tipostampa == 3) ? "X" : "");
 | 
						|
		}
 | 
						|
		else
 | 
						|
		if (strcmp(column_name, "FASESPEC") == 0)
 | 
						|
		{
 | 
						|
      if (_tipostampa == 1 || _tipostampa == 3 || _tipostampa == 4)
 | 
						|
			  var.set(_fase);
 | 
						|
      else
 | 
						|
        var.set(EMPTY_STRING);
 | 
						|
		}
 | 
						|
    else
 | 
						|
    if (strcmp(column_name, "STAMPACDC") == 0)
 | 
						|
		{
 | 
						|
      var.set((_tipostampa  == 2 || _tipostampa == 3) ? "X" : "");
 | 
						|
		}
 | 
						|
    else
 | 
						|
    if (strcmp(column_name, "CDCSPEC") == 0)
 | 
						|
		{
 | 
						|
      if (_tipostampa == 2 || _tipostampa == 3 || _tipostampa == 8)
 | 
						|
			  var.set(_cdc);
 | 
						|
      else
 | 
						|
        var.set(EMPTY_STRING);
 | 
						|
		}
 | 
						|
		else
 | 
						|
		if (strcmp(column_name, "AVANZAMENTO") == 0)
 | 
						|
		{
 | 
						|
			//Calcola lo stato di avanzamento della commessa in caso di stima x Tempo
 | 
						|
			real avanzamento;
 | 
						|
			if (_tipostima == 'T')
 | 
						|
			{
 | 
						|
        avanzamento = calcola_avanzamento_tempo();
 | 
						|
			}
 | 
						|
			else	//se stima e' di tipo Costi/Ricavi invece....Allah!!
 | 
						|
			{
 | 
						|
    		TAssoc_array& riga = (TAssoc_array&)_righe[_curr];
 | 
						|
        const real val = get("RICAVI").as_real();
 | 
						|
			  if (!val.is_zero())
 | 
						|
        {
 | 
						|
          int indice = get("LEVEL").as_int();
 | 
						|
     	    const TString& codcms = get("CODCMS").as_string();
 | 
						|
 | 
						|
          TAssoc_array& riga_tot = get_row((TAssoc_array&)_totali[indice], codcms, indice, codcms, EMPTY_STRING, EMPTY_STRING,
 | 
						|
																				   "RICAVI");
 | 
						|
          const TString* stric = (const TString*)riga_tot.objptr("RICAVI");
 | 
						|
          if (stric && stric->full())
 | 
						|
          {
 | 
						|
            const real totric = *stric;
 | 
						|
            if (!totric.is_zero())
 | 
						|
              avanzamento = val * CENTO / totric;
 | 
						|
          }
 | 
						|
        }
 | 
						|
			}
 | 
						|
			var.set(avanzamento);
 | 
						|
		}
 | 
						|
		else	//if(strcmp(column_name,AVANZAMENTO...
 | 
						|
		{
 | 
						|
  		TAssoc_array& riga = (TAssoc_array&)_righe[_curr];
 | 
						|
      if (strncmp(column_name, "RECORD.", 7) == 0)
 | 
						|
        column_name += 7;
 | 
						|
			const TString* val = (TString*)riga.objptr(column_name);
 | 
						|
			if (val)
 | 
						|
			  var.set(*val);
 | 
						|
			else
 | 
						|
				var.set_null();
 | 
						|
		}
 | 
						|
  	return var;
 | 
						|
	}
 | 
						|
  return NULL_VARIANT;
 | 
						|
}
 | 
						|
 | 
						|
void TPrint_saldana_recordset::set_filter(const TMask& msk, const TString& curr_sublevel)
 | 
						|
{
 | 
						|
  _fase = _cdc = "";
 | 
						|
	//tira su un po' di parametri dalla maschera...
 | 
						|
	_anno = msk.get_int(F_ESERCIZIO);
 | 
						|
	//prende anche il prefix
 | 
						|
	TString80 prefix;
 | 
						|
	for (short id = F_PRE1; id <= F_PRE3 && msk.id2pos(id) > 0; id++)
 | 
						|
		prefix << msk.get(id);
 | 
						|
	_indicatori.set_prefix(prefix);
 | 
						|
 | 
						|
  //solo per ca3800
 | 
						|
  if (_tipo == 8)
 | 
						|
  {
 | 
						|
    _tipostima = msk.get(F_TIPOSTIMA)[0];
 | 
						|
	  _vitaintera = msk.get_bool(F_VITAINTERA);
 | 
						|
    _depth = msk.get_int(F_DEPTH);
 | 
						|
    _tipodetr = msk.get_bool(F_TIPODETR);
 | 
						|
    _tipostampa = msk.get_int(F_TIPOSTAMPA);
 | 
						|
 | 
						|
    //in base al tipo di stampa selezionata setta un po' di parametri
 | 
						|
    switch (_tipostampa)
 | 
						|
    {
 | 
						|
    case 1:
 | 
						|
      _fase = msk.get(F_FASE);
 | 
						|
      _cdc.cut(0);
 | 
						|
      break;
 | 
						|
    case 2:
 | 
						|
      _cdc = msk.get(F_CDC);
 | 
						|
      _fase.cut(0);
 | 
						|
      break;
 | 
						|
    case 3:
 | 
						|
      _fase = msk.get(F_FASE);
 | 
						|
      _cdc = msk.get(F_CDC);
 | 
						|
      break;
 | 
						|
    case 4:
 | 
						|
      _fase = curr_sublevel;
 | 
						|
      break;
 | 
						|
    case 8:
 | 
						|
      _cdc = curr_sublevel;
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  } //if(tipo==8..
 | 
						|
}
 |