Files correlati : Ricompilazione Demo : [ ] Commento :riportate le modifiche 5.0 alla 1072 git-svn-id: svn://10.65.10.50/trunk@16827 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			385 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			385 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include <applicat.h>
 | 
						|
#include <automask.h>
 | 
						|
#include <defmask.h>
 | 
						|
#include <recarray.h>
 | 
						|
#include <relation.h>
 | 
						|
 | 
						|
#include "../cg/cglib01.h"
 | 
						|
#include "calib01.h"
 | 
						|
#include "calib02.h"
 | 
						|
 | 
						|
#include "ca2.h"
 | 
						|
#include "ca2200a.h"
 | 
						|
 | 
						|
#include "movana.h"
 | 
						|
#include "rmovana.h"
 | 
						|
#include "rip.h"
 | 
						|
#include "rrip.h"
 | 
						|
 | 
						|
//--------------------------------------------------------------------
 | 
						|
//  MASCHERA
 | 
						|
//--------------------------------------------------------------------
 | 
						|
class TRib_movanal_msk : public TAnal_report_mask
 | 
						|
{
 | 
						|
protected:
 | 
						|
  virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
 | 
						|
 | 
						|
  void save_to_ini();
 | 
						|
  void load_from_ini();
 | 
						|
 | 
						|
public:
 | 
						|
  TRib_movanal_msk();
 | 
						|
};
 | 
						|
 | 
						|
void TRib_movanal_msk::save_to_ini()
 | 
						|
{
 | 
						|
  TConfig ini(CONFIG_DITTA, "ca");
 | 
						|
 | 
						|
  // Cancella tutte le variabili di pareggio
 | 
						|
  int j;
 | 
						|
  for (j = 1; ini.remove("Pareggio", j); j++);
 | 
						|
 | 
						|
  TSheet_field& sf = sfield(F_RIGHE);
 | 
						|
  const int idx = sf.cid2index(F_CODCAUS);
 | 
						|
 | 
						|
  // Salva tutte le righe dello sheet nel formato
 | 
						|
  // Pareggio(1) = Causale|Costo|Commessa|Fase
 | 
						|
  j = 0;
 | 
						|
  FOR_EACH_SHEET_ROW(sf, i, row) 
 | 
						|
  {
 | 
						|
    TToken_string par = row->get(idx);  // Codice causale
 | 
						|
    if (!par.blank())
 | 
						|
    {
 | 
						|
      TAnal_bill bill;
 | 
						|
      const int flags = get_row_bill(sf, i, bill);
 | 
						|
      if (flags != 0)
 | 
						|
      {
 | 
						|
        if (flags & 1) par.add(bill.costo(),    1);
 | 
						|
        if (flags & 2) par.add(bill.commessa(), 2);
 | 
						|
        if (flags & 4) par.add(bill.fase(),     3);
 | 
						|
        ini.set("Pareggio", par, NULL, true, ++j);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void TRib_movanal_msk::load_from_ini()
 | 
						|
{
 | 
						|
  // Svuota lo sheet
 | 
						|
  TSheet_field& sf = sfield(F_RIGHE);
 | 
						|
  sf.destroy();
 | 
						|
 | 
						|
  // Carica tutte le variabili di pareggio nello sheet
 | 
						|
  TConfig ini(CONFIG_DITTA, "ca");
 | 
						|
  TToken_string par;
 | 
						|
  for (int j = 1; ; j++)
 | 
						|
  {
 | 
						|
    par = ini.get("Pareggio", NULL, j);
 | 
						|
    if (par.empty_items())
 | 
						|
      break;
 | 
						|
    const TAnal_bill bill("", par.get(1), par.get(2), par.get(3));
 | 
						|
    set_row_bill(sf, -1, bill);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
bool TRib_movanal_msk::on_field_event(TOperable_field& o, TField_event e, long jolly)
 | 
						|
{
 | 
						|
  switch (o.dlg())
 | 
						|
  {
 | 
						|
	case F_DATAINI:
 | 
						|
	case F_DATAFIN:
 | 
						|
		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;
 | 
						|
  case DLG_OK: 
 | 
						|
  case DLG_SAVEREC: 
 | 
						|
    if (e == fe_button)
 | 
						|
      save_to_ini(); 
 | 
						|
    break;
 | 
						|
  default: 
 | 
						|
    break;
 | 
						|
  }
 | 
						|
  return TAnal_report_mask::on_field_event(o, e, jolly);
 | 
						|
}
 | 
						|
 | 
						|
TRib_movanal_msk::TRib_movanal_msk() : TAnal_report_mask("ca2200a")
 | 
						|
{
 | 
						|
  create_sheet(F_RIGHE);
 | 
						|
  load_from_ini();
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------
 | 
						|
//  APPLICAZIONE
 | 
						|
//--------------------------------------------------------------------
 | 
						|
class TRib_movanal_app : public TSkeleton_application
 | 
						|
{
 | 
						|
  TCache_ripartizioni _cache_rip;
 | 
						|
  bool _definitivo;
 | 
						|
  TAssoc_array _caus_cms;
 | 
						|
 | 
						|
  virtual const char* extra_modules() const { return "cm"; } //deve funzionare anche per le commesse
 | 
						|
 | 
						|
protected:
 | 
						|
  virtual void main_loop();
 | 
						|
 | 
						|
  bool explode_rows(const TRecord_array& input_rows, TRecord_array& output_rows, const int annoes, 
 | 
						|
                    const char tipomov);
 | 
						|
  bool pareggia_commessa(TAnal_mov& anal_mov);
 | 
						|
 | 
						|
public:
 | 
						|
  bool elabora_movimento(TAnal_mov& anal_mov, const bool esplodi);
 | 
						|
	TRib_movanal_app(){}
 | 
						|
};
 | 
						|
 | 
						|
bool TRib_movanal_app::explode_rows(const TRecord_array& input_rows, TRecord_array& output_rows, 
 | 
						|
                                    const int annoes, const char tipomov)
 | 
						|
{
 | 
						|
  bool ho_cambiato_qualchecosa = false;
 | 
						|
  for (int r = 1; r <= input_rows.rows(); r++)
 | 
						|
  {
 | 
						|
    const TRectype& rec = input_rows.row(r);
 | 
						|
    TAnal_bill zio(rec);
 | 
						|
    const int rmovana_indbil = zio.indicatore_bilancio();
 | 
						|
    const TAnal_ripartizioni_batch& rrip = _cache_rip.righe(rec.get(RMOVANA_CODCCOSTO), rec.get(RMOVANA_CODCMS),
 | 
						|
                                                            rec.get(RMOVANA_CODFASE), annoes, rmovana_indbil, tipomov);
 | 
						|
    //ci sono righe di ripartizione
 | 
						|
    const int righe_ripartizione = rrip.rows();
 | 
						|
    bool ripartisci = righe_ripartizione > 0;
 | 
						|
 | 
						|
    if (ripartisci)  
 | 
						|
    {
 | 
						|
      // Importo totale da distribuire arrotondato ai decimali della valuta di conto
 | 
						|
      TGeneric_distrib distrib(rec.get_real(RMOVANA_IMPORTO), TCurrency::get_firm_dec());
 | 
						|
 | 
						|
      // Calcolo tutte le percentuali da ripartire
 | 
						|
      int i;
 | 
						|
      for (i = 1; i <= righe_ripartizione; i++)
 | 
						|
        distrib.add(rrip[i].get_real(RRIP_RIPARTO));
 | 
						|
 | 
						|
      for (i = 1; i <= righe_ripartizione; i++)
 | 
						|
      {
 | 
						|
        const real imp = distrib.get(); // Legge la quota da distribuire
 | 
						|
 | 
						|
				if (imp != ZERO)
 | 
						|
				{
 | 
						|
					TRectype* newrec = new TRectype(rec);
 | 
						|
					newrec->put(RMOVANA_NUMRIG, output_rows.rows() + 1);
 | 
						|
					newrec->put(RMOVANA_IMPORTO, imp);  //e la mette nella nuova riga
 | 
						|
					//poi copia i valori dei campi cdc,cms,fsc,in quelli di tipo ori (nello stesso record)
 | 
						|
					ca_copia_campo(rec, RMOVANA_CODCCOSTO, *newrec, RMOVANA_CODCCORI);
 | 
						|
					ca_copia_campo(rec, RMOVANA_CODCMS,    *newrec, RMOVANA_CODCMSORI);
 | 
						|
					ca_copia_campo(rec, RMOVANA_CODFASE,   *newrec, RMOVANA_CODFASEORI);
 | 
						|
					ca_copia_campo(rec, RMOVANA_CODCONTO,  *newrec, RMOVANA_CODCONTORI);
 | 
						|
					//e mette nei campi std i valori che trova nelle righe ripartizione
 | 
						|
					ca_copia_campo(rrip[i], RRIP_CODCOSTO, *newrec, RMOVANA_CODCCOSTO);
 | 
						|
					ca_copia_campo(rrip[i], RRIP_CODCMS,   *newrec, RMOVANA_CODCMS);
 | 
						|
					ca_copia_campo(rrip[i], RRIP_CODFASE,  *newrec, RMOVANA_CODFASE);
 | 
						|
					ca_copia_campo(rrip[i], RRIP_CODCONTO, *newrec, RMOVANA_CODCONTO);
 | 
						|
 | 
						|
					output_rows.add_row(newrec);
 | 
						|
	        ho_cambiato_qualchecosa = true;
 | 
						|
				}
 | 
						|
      }
 | 
						|
    }
 | 
						|
    else  //nessuna riga di ripartizione->aggiungo la riga input all'output
 | 
						|
    {
 | 
						|
      TRectype* newrec = new TRectype(rec);
 | 
						|
      newrec->put(RMOVANA_NUMRIG, output_rows.rows() + 1);
 | 
						|
      output_rows.add_row(newrec);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return ho_cambiato_qualchecosa;
 | 
						|
}
 | 
						|
 | 
						|
bool TRib_movanal_app::pareggia_commessa(TAnal_mov& anal_mov)
 | 
						|
{
 | 
						|
  bool ho_cambiato_qualchecosa = false;
 | 
						|
 | 
						|
  const TString& codcaus = anal_mov.get(MOVANA_CODCAUS);
 | 
						|
  const TAnal_bill* cms = (const TAnal_bill*)_caus_cms.objptr(codcaus);
 | 
						|
  if (cms != NULL) // La causale del movimento e' tra quelle da pareggiare
 | 
						|
  {
 | 
						|
    const TImporto totdoc(anal_mov.get_char(MOVANA_SEZIONE), anal_mov.get_real(MOVANA_TOTDOC));
 | 
						|
    if (!totdoc.is_zero()) // Movimento da pareggiare
 | 
						|
    {
 | 
						|
      TRecord_array& body = anal_mov.body();
 | 
						|
      // Cerco la commessa/fase/costo tra le righe esistenti
 | 
						|
      int i;
 | 
						|
      for (i = body.last_row(); i > 0; i--)
 | 
						|
      {
 | 
						|
        const TRectype& row = body[i];
 | 
						|
        if ((cms->costo().blank() || row.get(RMOVANA_CODCCOSTO) == cms->costo()) &&
 | 
						|
            (cms->commessa().blank() || row.get(RMOVANA_CODCMS) == cms->commessa()) &&           
 | 
						|
            (cms->fase().blank() || row.get(RMOVANA_CODFASE) == cms->fase()))
 | 
						|
          break;
 | 
						|
      }
 | 
						|
      // Se non trovo nessuna riga compatibile, me la creo
 | 
						|
      if (i <= 0)
 | 
						|
      {
 | 
						|
        TRectype& rmovana = anal_mov.new_row();
 | 
						|
        rmovana.put(RMOVANA_DESCR, TR("Pareggio commessa"));
 | 
						|
        rmovana.put(RMOVANA_CODCCOSTO, cms->costo());
 | 
						|
        rmovana.put(RMOVANA_CODCMS,    cms->commessa());
 | 
						|
        rmovana.put(RMOVANA_CODFASE,   cms->fase());
 | 
						|
        i = rmovana.get_int(RMOVANA_NUMRIG);
 | 
						|
      }
 | 
						|
 | 
						|
      // Sottraggo all'importo della riga il totale documento, 
 | 
						|
      // il quale verra' quindi azzerato
 | 
						|
      TRectype& rmovana = body[i];
 | 
						|
      TImporto importo(rmovana.get_char(RMOVANA_SEZIONE), rmovana.get_real(RMOVANA_IMPORTO));
 | 
						|
      importo -= totdoc;
 | 
						|
      importo.normalize();
 | 
						|
      rmovana.put(RMOVANA_SEZIONE, importo.sezione());
 | 
						|
      rmovana.put(RMOVANA_IMPORTO, importo.valore());
 | 
						|
      anal_mov.put(MOVANA_TOTDOC, ZERO);
 | 
						|
 | 
						|
      ho_cambiato_qualchecosa = true;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  
 | 
						|
  return ho_cambiato_qualchecosa;
 | 
						|
}
 | 
						|
 | 
						|
bool TRib_movanal_app::elabora_movimento(TAnal_mov& anal_mov, const bool esplodi)
 | 
						|
{
 | 
						|
  TRecord_array& input_rows = anal_mov.body();  //record_array con le righe del mov_anal (INPUT)
 | 
						|
  bool do_rewrite = false;
 | 
						|
 | 
						|
//Per prima cosa prende le righe del movimento su RMOVANA e le ricompatta..
 | 
						|
  TRecord_array compact_rows = input_rows; //record array con le righe compattate da creare con la..
 | 
						|
  compact_rows.destroy_rows();             //..implode_rows(); intanto le azzera per sicurezza
 | 
						|
 | 
						|
  if (esplodi)
 | 
						|
  {
 | 
						|
    //Imploditore
 | 
						|
    ca_implode_rows(input_rows, compact_rows);
 | 
						|
    //..poi lo riesplode in tutte le righe che possono nascere secondo le regole delle ripartizioni!
 | 
						|
    TRecord_array output_rows = input_rows; //crea il record_array di output come copia dell'INPUT..
 | 
						|
    output_rows.destroy_rows();             //..e poi lo pulisce
 | 
						|
 | 
						|
    //Esploditore
 | 
						|
    if (explode_rows(compact_rows, output_rows, anal_mov.get_int(MOVANA_ANNOES), anal_mov.get_char(MOVANA_TIPOMOV)))
 | 
						|
    {
 | 
						|
      input_rows = output_rows; //rimette i record elaborati negli originali
 | 
						|
      do_rewrite = true;
 | 
						|
    }
 | 
						|
    if (pareggia_commessa(anal_mov))
 | 
						|
      do_rewrite = true;
 | 
						|
    
 | 
						|
    if (_definitivo)  //se l'elaborazione e' definitiva...
 | 
						|
    {
 | 
						|
      anal_mov.put(MOVANA_BLOCCATO, 'X'); //..mette bloccato = X nella testata del movimento
 | 
						|
      do_rewrite = true;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    //Imploditore
 | 
						|
    do_rewrite = ca_implode_rows(input_rows, compact_rows);
 | 
						|
    if (do_rewrite)
 | 
						|
      input_rows = compact_rows; // rimette i record compattati negli originali
 | 
						|
  }
 | 
						|
  return do_rewrite; //se ha elaborato delle righe e/o e' una elaborazione definitiva, riscrive la..
 | 
						|
}
 | 
						|
 | 
						|
static bool ripartisci_callback(const TRelation& rel, void* pJolly)
 | 
						|
{
 | 
						|
  TRib_movanal_app& app = *(TRib_movanal_app*)pJolly;
 | 
						|
  const long numreg = rel.curr().get_long(MOVANA_NUMREG);
 | 
						|
  TAnal_mov anal_mov(numreg);
 | 
						|
  //se va tutto bene riscrive l'intero movimento analitico con conseguente ricalcolo saldi
 | 
						|
  if (app.elabora_movimento(anal_mov, true))
 | 
						|
    anal_mov.rewrite(rel.lfile());
 | 
						|
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
static bool compatta_callback(const TRelation& rel, void* pJolly)
 | 
						|
{
 | 
						|
  TRib_movanal_app& app = *(TRib_movanal_app*)pJolly;
 | 
						|
  const long numreg = rel.curr().get_long(MOVANA_NUMREG);
 | 
						|
  TAnal_mov anal_mov(numreg);
 | 
						|
  //se va tutto bene riscrive l'intero movimento analitico con conseguente ricalcolo saldi
 | 
						|
  if (app.elabora_movimento(anal_mov, false))
 | 
						|
    anal_mov.rewrite(rel.lfile());
 | 
						|
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
void TRib_movanal_app::main_loop()
 | 
						|
{
 | 
						|
  TRib_movanal_msk mask;
 | 
						|
  while (mask.run() == K_ENTER)
 | 
						|
  { 
 | 
						|
    //deve scandire il file MOVANA con chiave 2 (per data e numero di registrazione)
 | 
						|
    TRelation rel_movana(LF_MOVANA);
 | 
						|
    TRectype darec(LF_MOVANA), arec(LF_MOVANA);
 | 
						|
    const TDate & dal = mask.get_date(F_DATAINI);
 | 
						|
    darec.put(MOVANA_DATACOMP, dal);
 | 
						|
		const TDate & al = mask.get_date(F_DATAFIN);
 | 
						|
    arec.put(MOVANA_DATACOMP, al);
 | 
						|
		_cache_rip.set_esercizio(mask.get_int(F_ANNO));
 | 
						|
 | 
						|
    TCursor cur_movana(&rel_movana, "BLOCCATO!=\"X\"", 2, &darec, &arec);
 | 
						|
    const long items = cur_movana.items();
 | 
						|
    if (items > 0)
 | 
						|
    {
 | 
						|
      bool run = yesno_box(FR("Si desidera elaborare %ld movimenti?"), items);
 | 
						|
      //e' una compattazione?
 | 
						|
      const bool compattazione = mask.get_bool(F_COMPATTA);
 | 
						|
      //se e' un ripartizione potrebbe essere definitiva!
 | 
						|
      if (!compattazione)
 | 
						|
      {
 | 
						|
        // avvisa l'utente scapestrato che se fa una ripartizione definitiva
 | 
						|
        // blocchera' i movimenti che processa e non potra' piu' tornare indietro
 | 
						|
        _definitivo = mask.get_bool(F_DEFINITIVO);
 | 
						|
        if (run && _definitivo)
 | 
						|
          run = yesno_box(TR("E' stata selezionata l'elaborazione definitiva\nSi desidera proseguire?"));
 | 
						|
      }
 | 
						|
 | 
						|
      //Presa la decisione si parte! Tenetevi forte...
 | 
						|
      if (run)
 | 
						|
      {
 | 
						|
        // Riempie la lista della causali dei movimenti da pareggiare
 | 
						|
        _caus_cms.destroy();
 | 
						|
        TSheet_field& sf = mask.sfield(F_RIGHE);
 | 
						|
        const int pos_codcaus = sf.cid2index(F_CODCAUS);
 | 
						|
        FOR_EACH_SHEET_ROW(sf, i, row) 
 | 
						|
        {
 | 
						|
          const TString4 codcaus = row->get(pos_codcaus);
 | 
						|
          if (codcaus.full())
 | 
						|
          {
 | 
						|
            TAnal_bill* bill = new TAnal_bill;
 | 
						|
            if (mask.get_row_bill(sf, i, *bill) != 0)
 | 
						|
              _caus_cms.add(codcaus, bill);
 | 
						|
            else
 | 
						|
              delete bill;
 | 
						|
          }
 | 
						|
        }
 | 
						|
 | 
						|
        if (compattazione)
 | 
						|
          cur_movana.scan(compatta_callback, this, TR("Compattamento movimenti..."));
 | 
						|
        else
 | 
						|
          cur_movana.scan(ripartisci_callback, this, TR("Ripartizione movimenti..."));
 | 
						|
      } //if(run)...
 | 
						|
    }
 | 
						|
    else
 | 
						|
      message_box(TR("Non ci sono movimenti da elaborare nel periodo selezionato"));
 | 
						|
  } 
 | 
						|
}
 | 
						|
 | 
						|
int ca2200(int argc, char* argv[])
 | 
						|
{
 | 
						|
  TRib_movanal_app app;
 | 
						|
  app.run(argc, argv, TR("Ripartizione movimenti di analitica"));
 | 
						|
  return 0;
 | 
						|
}
 |