Files correlati : Ricompilazione Demo : [ ] Commento : Riportata la versione 2.1 300 git-svn-id: svn://10.65.10.50/trunk@13091 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			1130 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1130 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
// Applicazione di generazione reports & stampe per MRP
 | 
						|
#include <applicat.h>
 | 
						|
#include <form.h>
 | 
						|
#include <relation.h>
 | 
						|
#include <reprint.h>
 | 
						|
#include <printer.h>
 | 
						|
#include <progind.h>
 | 
						|
 | 
						|
#include "mrplib.h"
 | 
						|
#include "../ve/velib.h"
 | 
						|
#include "../mg/mglib.h"
 | 
						|
 | 
						|
#include "mr1.h"
 | 
						|
#include "mr1100a.h"
 | 
						|
#include <defmask.h>
 | 
						|
 | 
						|
#include <doc.h>
 | 
						|
#include <rdoc.h>
 | 
						|
 | 
						|
#define LF_MRPREP    132
 | 
						|
 | 
						|
#define LAST_BUCKET 12
 | 
						|
 | 
						|
// Tipi di stampa 
 | 
						|
enum tipo_stampa {
 | 
						|
  articoli,   // produzione articoli nel tempo
 | 
						|
  linee,      // carico linee
 | 
						|
  scheduling, // scheduling delle linee
 | 
						|
  available   // Tipo di stampa non definita: ordinata per articoli e stampa del carico della linea
 | 
						|
};
 | 
						|
 | 
						|
// I tipi di stampa si identificano secondo la seguente tabella, tramite l'intersezione
 | 
						|
// tra l'ordinamento ed il valore impostati:
 | 
						|
/*
 | 
						|
     
 | 
						|
                   |----------------------+
 | 
						|
                   |quantita   | carico   |
 | 
						|
        -----------+-----------------------
 | 
						|
        articoli   |articoli   | available|
 | 
						|
        -----------+----------------------+
 | 
						|
        linea      |scheduling | linee    |
 | 
						|
        -----------+-----------------------
 | 
						|
          
 | 
						|
 */
 | 
						|
enum tipo_ordinamento {
 | 
						|
  articolo,
 | 
						|
  linea
 | 
						|
};
 | 
						|
 | 
						|
enum tipo_valore {
 | 
						|
  quantita,
 | 
						|
  carico
 | 
						|
};
 | 
						|
 | 
						|
enum tipo_dettaglio {
 | 
						|
  det_articolo,
 | 
						|
  det_giacenza,
 | 
						|
  det_impianto,
 | 
						|
  det_linea
 | 
						|
};
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// _TCapacitaLinea, usato per calcolare le capacita' delle linee
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
class _TCapacitaLinea : public TObject
 | 
						|
{ 
 | 
						|
  TArray _cap_min, // Array 1..LAST_BUCKET-1 di capacita' minime
 | 
						|
         _cap_max; // Array 1..LAST_BUCKET-1 di capacita' massime
 | 
						|
  
 | 
						|
public:
 | 
						|
  TArray& cap_min() { return _cap_min; }
 | 
						|
  TArray& cap_max() { return _cap_max; }
 | 
						|
  _TCapacitaLinea() ;
 | 
						|
  virtual ~_TCapacitaLinea() {}
 | 
						|
};
 | 
						|
 | 
						|
_TCapacitaLinea::_TCapacitaLinea()
 | 
						|
{
 | 
						|
  for (int i = 0; i < LAST_BUCKET-1; i++)
 | 
						|
  {
 | 
						|
    _cap_min.add(new real);
 | 
						|
    _cap_max.add(new real);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TMRP_rep_record
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
class TMRP_rep_record : public TObject
 | 
						|
{
 | 
						|
public:
 | 
						|
  real _qta;
 | 
						|
  
 | 
						|
  TMRP_rep_record() { }
 | 
						|
};
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TMRP_rep_record_array;
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
class TMRP_rep_record_array : public TObject
 | 
						|
{
 | 
						|
  TArray _buckets;
 | 
						|
 | 
						|
public:
 | 
						|
  int items() const { return _buckets.items(); }
 | 
						|
  int last() const { return _buckets.last(); }
 | 
						|
  int pred(int i) const { return _buckets.pred(i); }
 | 
						|
 | 
						|
  TMRP_rep_record& operator[](int b);
 | 
						|
};
 | 
						|
 | 
						|
TMRP_rep_record& TMRP_rep_record_array::operator[](int b)
 | 
						|
{
 | 
						|
  CHECKD(b >= 0, "Invalid TMRP_rep_record_array ", b);
 | 
						|
  TMRP_rep_record* qta = (TMRP_rep_record*)_buckets.objptr(b);
 | 
						|
  if (qta == NULL)
 | 
						|
  {
 | 
						|
    qta = new TMRP_rep_record;
 | 
						|
    _buckets.add(qta, b);
 | 
						|
  }
 | 
						|
  return *qta;
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TMRP_rep_line
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
class TMRP_rep_line : public TSortable
 | 
						|
{
 | 
						|
  TCodice_articolo _codart;
 | 
						|
  TString16 _giac;
 | 
						|
  TString8 _imp, _lin;
 | 
						|
  TString4 _um;
 | 
						|
 | 
						|
  TMRP_rep_record_array _bucket;
 | 
						|
 | 
						|
protected:
 | 
						|
  virtual int compare(const TSortable& s) const;
 | 
						|
 | 
						|
public:
 | 
						|
  const TCodice_articolo& codice() const { return _codart; }
 | 
						|
  const TString& livgiac() const { return _giac; }
 | 
						|
  const TString& codimp() const { return _imp; }
 | 
						|
  const TString& codlin() const { return _lin; }
 | 
						|
  const TString& um() const { return _um; }
 | 
						|
 | 
						|
  int last() const { return _bucket.last(); }
 | 
						|
  int pred(int i) const { return _bucket.pred(i); }
 | 
						|
 | 
						|
  real& qta(int b) { return _bucket[b]._qta; }
 | 
						|
  
 | 
						|
  void fill(TRectype& record, TAssoc_array* capacita = NULL);
 | 
						|
 | 
						|
  TMRP_rep_line(const TCodice_articolo& codart, 
 | 
						|
                const TString& giac, const TString& imp,
 | 
						|
                const TString& lin, const TString& um);
 | 
						|
  virtual ~TMRP_rep_line() { }
 | 
						|
};
 | 
						|
 | 
						|
void TMRP_rep_line::fill(TRectype& record, TAssoc_array* capacita)
 | 
						|
{
 | 
						|
  record.zero();
 | 
						|
  record.put("TIPO", "R");
 | 
						|
  record.put("CODART", _codart);
 | 
						|
  record.put("LIVELLO", _giac);
 | 
						|
  record.put("IMPIANTO", _imp);
 | 
						|
  record.put("LINEA", _lin);
 | 
						|
  record.put("UM", _um);
 | 
						|
  TString16 campo;
 | 
						|
  for (int b = last(); b >= 0; b = pred(b))
 | 
						|
  {
 | 
						|
    switch(b)
 | 
						|
    {
 | 
						|
    case 0: 
 | 
						|
      campo = "QTAFIRST"; break;
 | 
						|
    case LAST_BUCKET:
 | 
						|
      campo = "QTALAST"; break;
 | 
						|
    default:
 | 
						|
      campo.format("QTA%d", b); break;
 | 
						|
    }
 | 
						|
    record.put(campo, qta(b));
 | 
						|
  }
 | 
						|
  
 | 
						|
  if (capacita)
 | 
						|
    for (b=1; b<LAST_BUCKET; b++)
 | 
						|
    {
 | 
						|
      _TCapacitaLinea* cl = (_TCapacitaLinea*)capacita->objptr(_lin);
 | 
						|
      if (cl)
 | 
						|
      { 
 | 
						|
        TArray& cmin = cl->cap_min();
 | 
						|
        TArray& cmax = cl->cap_max();
 | 
						|
        campo.format("CMIN%d", b);
 | 
						|
        record.put(campo, (real&)cmin[b-1]); // Capacita' minima...
 | 
						|
        campo.format("CMAX%d", b);
 | 
						|
        record.put(campo, (real&)cmax[b-1]); // e massima
 | 
						|
      }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
int TMRP_rep_line::compare(const TSortable& s) const
 | 
						|
{
 | 
						|
  const TMRP_rep_line& c = (const TMRP_rep_line&)s;
 | 
						|
  int cmp = _codart.compare(c._codart);
 | 
						|
  if (cmp == 0)
 | 
						|
  {
 | 
						|
    cmp = _giac.compare(c._giac);
 | 
						|
    if (cmp == 0)
 | 
						|
    {
 | 
						|
      cmp = _imp.compare(c._imp);
 | 
						|
      if (cmp == 0)
 | 
						|
      {
 | 
						|
        cmp = _lin.compare(c._lin);
 | 
						|
        if (cmp == 0)
 | 
						|
          cmp = _um.compare(c._um);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return cmp;
 | 
						|
}
 | 
						|
 | 
						|
TMRP_rep_line::TMRP_rep_line(const TCodice_articolo& codart, 
 | 
						|
                             const TString& giac, 
 | 
						|
                             const TString& imp, const TString& lin,
 | 
						|
                             const TString& um)
 | 
						|
: _codart(codart), _giac(giac), _imp(imp), _lin(lin), _um(um)
 | 
						|
{ }
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TMRP_rep_lines
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
class TMRP_rep_lines : public TMRP_array
 | 
						|
{
 | 
						|
protected:
 | 
						|
  virtual TSortable* new_obj(const TToken_string& key) const;
 | 
						|
 | 
						|
public:
 | 
						|
  TMRP_rep_line* find(const TCodice_articolo& codart, 
 | 
						|
                      const TString& giac, const TString& imp, 
 | 
						|
                      const TString& lin, const TString& um,
 | 
						|
                      bool create);
 | 
						|
  TMRP_rep_line& operator[](long n) const
 | 
						|
  { return (TMRP_rep_line&)find_obj(n); }
 | 
						|
};
 | 
						|
 | 
						|
TSortable* TMRP_rep_lines::new_obj(const TToken_string& key) const
 | 
						|
{
 | 
						|
  TCodice_articolo art; key.get(0, art);
 | 
						|
  TString          gia; key.get(1, gia);
 | 
						|
  TString          imp; key.get(2, imp);
 | 
						|
  TString          lin; key.get(3, lin);
 | 
						|
  TString          um ; key.get(4, um);
 | 
						|
  return new TMRP_rep_line(art, gia, imp, lin, um);
 | 
						|
}
 | 
						|
 | 
						|
TMRP_rep_line* TMRP_rep_lines::find(const TCodice_articolo& codart,
 | 
						|
                                    const TString& giac,
 | 
						|
                                    const TString& imp,
 | 
						|
                                    const TString& lin,
 | 
						|
                                    const TString& um,
 | 
						|
                                    bool create)
 | 
						|
{
 | 
						|
  _key = codart;
 | 
						|
  _key.add(giac);
 | 
						|
  _key.add(imp);
 | 
						|
  _key.add(lin);
 | 
						|
  _key.add(um);
 | 
						|
  TSortable* s = create ? add_obj(_key) : find_obj(_key);
 | 
						|
  return (TMRP_rep_line*)s;
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// MRP report generator mask
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
class TRepgen_mask : public TCalendar_mask
 | 
						|
{
 | 
						|
protected:
 | 
						|
  void calcola_capacita(TAssoc_array&) const ;
 | 
						|
  bool test_tipodoc_num( const TSheet_field &sheet_num , const TSheet_field &sheet_type) ;
 | 
						|
  virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
 | 
						|
 | 
						|
  void round_field(TMask_field& fld, bool up) const;
 | 
						|
 | 
						|
public:
 | 
						|
  int round_date(TDate& date, bool up) const;
 | 
						|
	int get_bucket_size() const { return get_int(F_BUCKET) * get_int(F_DAYXBUCK);}
 | 
						|
	const TDate start_date() const { return get_date(F_DADATA);} 
 | 
						|
	const TDate end_date() const { return get_date(F_ADATA);} 
 | 
						|
	int last_bucket() { TDate d(end_date()); return round_date(d, true);}
 | 
						|
  bool elabora() const;
 | 
						|
  TRepgen_mask();
 | 
						|
  virtual ~TRepgen_mask() { }
 | 
						|
};
 | 
						|
 | 
						|
bool TRepgen_mask::test_tipodoc_num(const  TSheet_field &sheet_num ,const  TSheet_field &sheet_type) 
 | 
						|
{
 | 
						|
  TString16 tipo;
 | 
						|
  TString_array& nums = sheet_num.rows_array();
 | 
						|
  TString_array& types = sheet_type.rows_array();
 | 
						|
  for (int j = types.items()-1; j >= 0; j--)
 | 
						|
  {
 | 
						|
    bool ok=FALSE;
 | 
						|
    tipo = types.row(j).get(0) ;
 | 
						|
    for (int i = nums.items()-1; i >= 0; i--)
 | 
						|
    {
 | 
						|
      TCodice_numerazione num(nums.row(i).get(0));
 | 
						|
      for (int n = num.ntipi_doc()-1;n >= 0; n--)
 | 
						|
      {
 | 
						|
        const char* t = num.tipo_doc(n);
 | 
						|
        if (tipo == t)
 | 
						|
          ok = TRUE;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if (!ok) 
 | 
						|
      return error_box(FR("Il tipo '%s' non appartiene a nessuna delle numerazioni scelte"),(const char*)tipo);
 | 
						|
  }
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
int TRepgen_mask::round_date(TDate& date, bool up) const
 | 
						|
{
 | 
						|
  // Dimensione del bucket in giorni
 | 
						|
	const int bucket_size = get_bucket_size();
 | 
						|
 | 
						|
  TDate inizio(start_date());
 | 
						|
  int bucket;
 | 
						|
  if (bucket_size == 31) // mese solare
 | 
						|
  {
 | 
						|
    if (up)
 | 
						|
    {
 | 
						|
      date.set_end_month();
 | 
						|
      int wday = date.wday();
 | 
						|
      wday = (7-wday) % 7;
 | 
						|
      if (wday<0)
 | 
						|
        date += wday;
 | 
						|
    }
 | 
						|
    else
 | 
						|
      date.set_day(1);
 | 
						|
    bucket = (date.year()-inizio.year())*12 + date.month() - inizio.month();
 | 
						|
    if (bucket < 0)
 | 
						|
			bucket = 0;
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    if (bucket_size > 1) // non vado a giorni
 | 
						|
    {
 | 
						|
      const int wday = inizio.wday();
 | 
						|
      if (wday > 1) inizio -= wday-1;
 | 
						|
    }
 | 
						|
    // Calcola il bucket di appartenenza
 | 
						|
    const int days = int(date - inizio);
 | 
						|
    
 | 
						|
		bucket = days / bucket_size;
 | 
						|
		if (bucket < 0)
 | 
						|
      bucket = 0;
 | 
						|
    else
 | 
						|
			if (bucket > LAST_BUCKET)
 | 
						|
				bucket = LAST_BUCKET;
 | 
						|
    if (up) // Arrotonda alla fine del bucket
 | 
						|
      date = inizio + long((bucket+1 )* bucket_size - 1 /*-  get_int(F_LASTWRKDAY)*/);
 | 
						|
    else    // Arrotonda all'inizio del bucket  
 | 
						|
      date = inizio + long(bucket * bucket_size);
 | 
						|
  }
 | 
						|
  return bucket;
 | 
						|
}
 | 
						|
 | 
						|
void TRepgen_mask::round_field(TMask_field& fld, bool up) const
 | 
						|
{
 | 
						|
  TDate date = fld.get();
 | 
						|
  if (date.ok())
 | 
						|
  {
 | 
						|
    round_date(date, up);
 | 
						|
    fld.set(date);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void TRepgen_mask::calcola_capacita(TAssoc_array& capacita) const
 | 
						|
{
 | 
						|
  if (capacita.items() == 0)
 | 
						|
    return;
 | 
						|
 | 
						|
  const bool carico_uomo = get_bool(F_MANLOAD);
 | 
						|
  const TDate df(start_date());
 | 
						|
  const TDate dt(end_date());
 | 
						|
  TDate wd1,wd2;
 | 
						|
  TString16 codimp;
 | 
						|
  
 | 
						|
  capacita.restart();
 | 
						|
  TProgind pi(capacita.items(), TR("Calcolo capacita linee"), FALSE, TRUE);
 | 
						|
  THash_object* ho = capacita.get_hashobj();
 | 
						|
  for (;ho != NULL; ho = capacita.get_hashobj())
 | 
						|
  {
 | 
						|
    pi.addstatus(1L);
 | 
						|
    const TString& linea = ho->key();
 | 
						|
    _TCapacitaLinea& cl = (_TCapacitaLinea&) ho->obj();
 | 
						|
    TLinea_prod lp(linea);
 | 
						|
    codimp = lp.codimp();
 | 
						|
    
 | 
						|
    TMRP_calendar& mc = TMRP_time::get_calendar(codimp, linea);
 | 
						|
    TArray& cap_min = cl.cap_min();
 | 
						|
    TArray& cap_max = cl.cap_max();
 | 
						|
    
 | 
						|
    for (wd1 = df; wd1 <= dt; ++wd1) // Piglia tutte le date nel range! (very, very heavy...)
 | 
						|
    {
 | 
						|
      wd2 = wd1;
 | 
						|
      const int bucket = round_date(wd2, FALSE); // da 0 a 10 al massimo
 | 
						|
      
 | 
						|
			if (bucket > 10)
 | 
						|
        break; // Fine
 | 
						|
      real & v1 = (real&) cap_min[bucket];
 | 
						|
      v1 += carico_uomo ? mc.add_oreuomo(v1, wd1)   : mc.add_oremacchina(v1, wd1);
 | 
						|
      real & v2 = (real&) cap_max[bucket];
 | 
						|
      v2 += carico_uomo ? mc.add_oreuomo_max(v2, wd1) : mc.add_oremacchina_max(v2, wd1);
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
bool TRepgen_mask::elabora() const
 | 
						|
{
 | 
						|
  TRelation rel(LF_RIGHEDOC);
 | 
						|
  TCursor cur(&rel);
 | 
						|
  const TRectype& riga = cur.curr();
 | 
						|
  TRectype filter_fr(riga), filter_to(riga);
 | 
						|
 | 
						|
  const TDate date_fr(start_date());
 | 
						|
  const int year_fr = date_fr.year();
 | 
						|
  TDate  date_to(end_date());
 | 
						|
  const int year_to = date_to.year();
 | 
						|
	const int bucket_size = get_bucket_size();
 | 
						|
  const TExplosion_grouping raggr = (TExplosion_grouping)get_int(F_RAGGRUM);
 | 
						|
  const tipo_valore ts = (tipo_valore) get_int(F_VAL2PRINT);
 | 
						|
  const bool carico_uomo = get_bool(F_MANLOAD);
 | 
						|
 | 
						|
  const int last_bucket = round_date(date_to,TRUE)+1;
 | 
						|
  
 | 
						|
  TString16 ws;
 | 
						|
 | 
						|
  TDistinta_tree distinta;
 | 
						|
  TArray  lav_array;
 | 
						|
 | 
						|
  TMRP_rep_lines articles;
 | 
						|
  TAssoc_array capacita;
 | 
						|
  
 | 
						|
  TString msg;
 | 
						|
  TSheet_field& numerazioni = sfield(F_NUMERAZIONI);
 | 
						|
  FOR_EACH_SHEET_ROW(numerazioni, r, row)
 | 
						|
  {
 | 
						|
    const TString16 codnum = row->get(0);
 | 
						|
    // Filtra il cursore in modo da limitarlo alla numerazione
 | 
						|
    // corrente ed agli anni specificati dalle due date limite
 | 
						|
    filter_fr.put(RDOC_PROVV, "D");
 | 
						|
    filter_fr.put(RDOC_CODNUM, codnum);
 | 
						|
    filter_fr.put(RDOC_ANNO, year_fr);
 | 
						|
 | 
						|
    filter_to.put(RDOC_PROVV, "D");
 | 
						|
    filter_to.put(RDOC_CODNUM, codnum);
 | 
						|
    filter_to.put(RDOC_ANNO, year_to);   
 | 
						|
    
 | 
						|
    cur.setregion(filter_fr, filter_to);
 | 
						|
    const long items = cur.items();
 | 
						|
    cur.freeze(TRUE);
 | 
						|
 | 
						|
    msg = TR("Elaborazione numerazione "); msg << codnum;
 | 
						|
    TProgind pi(items, msg, FALSE, TRUE);
 | 
						|
 | 
						|
    // Scandisce le righe dei documenti
 | 
						|
    for (cur = 0; cur.pos() < items; ++cur)    
 | 
						|
    {        
 | 
						|
      pi.addstatus(1);
 | 
						|
      const TCodice_articolo art = riga.get(RDOC_CODARTMAG);
 | 
						|
      if (art.not_empty())
 | 
						|
      {
 | 
						|
        real qta;
 | 
						|
        if (!riga.get_bool(RDOC_RIGAEVASA))
 | 
						|
        {
 | 
						|
          qta = riga.get_real(RDOC_QTA);
 | 
						|
          qta -= riga.get_real(RDOC_QTAEVASA);
 | 
						|
        }
 | 
						|
        // Seleziona le righe articolo non ancora evase
 | 
						|
        if (qta > ZERO)
 | 
						|
        {
 | 
						|
          const TString16 liv = riga.get(RDOC_LIVELLO); 
 | 
						|
          const TString16 imp = riga.get(RDOC_IMPIANTO); 
 | 
						|
          const TString16 lin = riga.get(RDOC_LINEA); 
 | 
						|
          const TCodice_um um = riga.get(RDOC_UMQTA);
 | 
						|
          TQuantita q(art, um, qta);
 | 
						|
		      TDate datacons = riga.get(RDOC_DATACONS);
 | 
						|
          
 | 
						|
          int bucket = round_date(datacons, FALSE);
 | 
						|
          if (bucket < 0) 
 | 
						|
            bucket = 0;
 | 
						|
          if (bucket > last_bucket) 
 | 
						|
            bucket = last_bucket;
 | 
						|
 | 
						|
          // Calcoli per carico
 | 
						|
          if (ts == carico)
 | 
						|
          {
 | 
						|
            distinta.set_root(riga);
 | 
						|
            real ore,tot;
 | 
						|
            
 | 
						|
            TRiga_esplosione * llav = distinta.first_labor(lav_array, raggr);
 | 
						|
            TLavorazione * lavorazione = TDistinta_tree::find_labor(llav);
 | 
						|
            
 | 
						|
            while (llav)
 | 
						|
            {
 | 
						|
              const int linea = lavorazione->find_linea(lin);
 | 
						|
              
 | 
						|
              const real prod_linea = lavorazione->produttiv_linea(linea);
 | 
						|
              ore = (llav->val() * lavorazione->um_temporale().converti_in_ore()) / prod_linea;
 | 
						|
              if (carico_uomo)
 | 
						|
                ore *= lavorazione->numpers_linea(linea);
 | 
						|
              
 | 
						|
              //rep.qta(bucket) += ore;
 | 
						|
              tot += ore;
 | 
						|
              llav = distinta.next_labor(lav_array);
 | 
						|
            }
 | 
						|
            
 | 
						|
            if (tot > ZERO)
 | 
						|
            {
 | 
						|
              TMRP_rep_line& rep = *articles.find(art, liv, imp, lin, ws, TRUE);
 | 
						|
              rep.qta(bucket) += tot;
 | 
						|
            }
 | 
						|
            
 | 
						|
            
 | 
						|
            // Sbatte nella cache le linee di cui dopo calcolera' le capacita' minime e massime
 | 
						|
            // In modo che il calcolo venga effettuato una volta sola per ogni linea.
 | 
						|
            if (capacita.objptr(lin) == NULL)
 | 
						|
              capacita.add(lin, new _TCapacitaLinea); // Vuoto per ora... lo riempie poco piu' giu'
 | 
						|
          }
 | 
						|
          else // Produzione articoli nel tempo & scheduling linee
 | 
						|
          {
 | 
						|
            TMRP_rep_line& rep = *articles.find(art, liv, imp, lin, q.um(), TRUE);
 | 
						|
            switch (raggr)
 | 
						|
            {
 | 
						|
             case RAGGR_EXP_UMBASE: q.convert2umbase(); break;
 | 
						|
             case RAGGR_EXP_UMDIST: q.convert2umdist(); break;
 | 
						|
             default: break;   
 | 
						|
            }
 | 
						|
            rep.qta(bucket) += q.val();
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
    cur.freeze(FALSE);
 | 
						|
  }
 | 
						|
  
 | 
						|
  if (ts == carico && get_bool(F_CAPACITA))
 | 
						|
    calcola_capacita(capacita);
 | 
						|
 | 
						|
  const long total = articles.items();
 | 
						|
  TProgind pi(total, TR("Generazione file"), FALSE, TRUE);
 | 
						|
 | 
						|
  TMask_field& fld = field(F_FILENAME);
 | 
						|
 | 
						|
  TLocalisamfile* rep = NULL;
 | 
						|
 | 
						|
  if (fld.empty())
 | 
						|
  {
 | 
						|
    TSystemisamfile mrprep(LF_MRPREP);
 | 
						|
    mrprep.zap();
 | 
						|
 | 
						|
    rep = new TLocalisamfile(LF_MRPREP);
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    TFilename filename = fld.get();
 | 
						|
    if (filename.empty())
 | 
						|
      filename.temp("mrprep");
 | 
						|
    fld.set(filename);
 | 
						|
    filename.insert("%");
 | 
						|
    rep = new TIsamtempfile(LF_MRPREP, filename);
 | 
						|
  }
 | 
						|
    
 | 
						|
  // Scrive la testata (Record tipo "H");
 | 
						|
  rep->put("TIPO","H");
 | 
						|
  rep->put("CODART", date_fr.string());
 | 
						|
  rep->put("LIVELLO", get(F_ADATA));
 | 
						|
  rep->put("IMPIANTO", bucket_size);
 | 
						|
  rep->put("LINEA", ts == quantita  ? "Q" : "C");
 | 
						|
 | 
						|
  // Scrive le date nelle quantita' dei buckets
 | 
						|
  TDate fd = date_fr; 
 | 
						|
  --fd; 
 | 
						|
  rep->put("QTAFIRST", fd.string(ANSI));
 | 
						|
  ++fd;
 | 
						|
  for (int b = 1; b <= last_bucket; b++)
 | 
						|
  {
 | 
						|
    TString8 fldname; fldname.format("QTA%d", b);
 | 
						|
    rep->put(fldname, fd.string(ANSI));
 | 
						|
		fd += bucket_size;
 | 
						|
  }
 | 
						|
  rep->put("QTALAST", fd.string(ANSI));
 | 
						|
  
 | 
						|
  rep->write();
 | 
						|
  
 | 
						|
  for (long i = 0; i < total; i++)
 | 
						|
  {
 | 
						|
    pi.addstatus(1);
 | 
						|
    articles[i].fill(rep->curr(), ts == carico ? &capacita : NULL);
 | 
						|
    int err = rep->write();
 | 
						|
    if (err != NOERR)
 | 
						|
      rep->rewrite();
 | 
						|
  }
 | 
						|
  delete rep;
 | 
						|
  
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
bool TRepgen_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
 | 
						|
{
 | 
						|
  switch(o.dlg())
 | 
						|
  {
 | 
						|
  case F_DADATA:
 | 
						|
    if (e == fe_modify || e == fe_close)
 | 
						|
      round_field(o, false);
 | 
						|
    break;
 | 
						|
  case F_ADATA:
 | 
						|
    if (e == fe_modify || e == fe_close)
 | 
						|
      round_field(o, true);
 | 
						|
    break;
 | 
						|
  case F_BUCKET:
 | 
						|
    if (e == fe_modify)
 | 
						|
    {
 | 
						|
      round_field(field(F_DADATA), false);
 | 
						|
      round_field(field(F_ADATA), true);
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case F_NUMERAZIONI:
 | 
						|
    if (e == fe_init)
 | 
						|
    {
 | 
						|
      TSheet_field& s = (TSheet_field&)o;
 | 
						|
      if (s.items() == 0)
 | 
						|
      {
 | 
						|
        s.row(0);
 | 
						|
        s.force_update();
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if (e == fe_close)
 | 
						|
    {
 | 
						|
      const TSheet_field& s = (const TSheet_field&)o;
 | 
						|
      FOR_EACH_SHEET_ROW_BACK(s, r, row)
 | 
						|
        if (!row->empty_items()) return TRUE;
 | 
						|
      return error_box(TR("E' necessario inserire almeno una numerazione"));
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case F_TIPI:
 | 
						|
    if (e == fe_init)
 | 
						|
    {
 | 
						|
      TSheet_field& s = (TSheet_field&)o;
 | 
						|
      if (s.items() == 0)
 | 
						|
      {
 | 
						|
        s.row(0);
 | 
						|
        s.force_update();
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if (e == fe_close)
 | 
						|
    {
 | 
						|
      const TSheet_field& s = (const TSheet_field&)o;
 | 
						|
      FOR_EACH_SHEET_ROW_BACK(s, r, row)
 | 
						|
        if (!row->empty_items()) 
 | 
						|
        {
 | 
						|
          const bool ok=test_tipodoc_num(sfield(F_NUMERAZIONI), s );
 | 
						|
          return ok;
 | 
						|
        }
 | 
						|
      return error_box(TR("E' necessario inserire almeno una riga"));
 | 
						|
    }
 | 
						|
    break;                      
 | 
						|
  case F_YEAR:
 | 
						|
  case F_IMPIANTO:
 | 
						|
  case F_LINEA:
 | 
						|
    if (e == fe_modify)
 | 
						|
      update_calendar(F_CALENDAR, F_YEAR, F_IMPIANTO, F_LINEA);
 | 
						|
    break;
 | 
						|
  case DLG_PRINT:
 | 
						|
  case DLG_ELABORA:
 | 
						|
    if (e == fe_button)
 | 
						|
    {
 | 
						|
      if (check_fields())
 | 
						|
        save_profile();
 | 
						|
      if (o.dlg() == DLG_ELABORA)
 | 
						|
        elabora();
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  default:
 | 
						|
    break;
 | 
						|
  }
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
TRepgen_mask::TRepgen_mask() 
 | 
						|
            : TCalendar_mask("mr1100a") 
 | 
						|
{ 
 | 
						|
  load_profile(); 
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// MRP Form
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
class TMRP_form : public TForm
 | 
						|
{
 | 
						|
  TCodgiac_livelli *_codgiac;
 | 
						|
  int               _level;
 | 
						|
 | 
						|
protected:
 | 
						|
  virtual bool validate(TForm_item &, TToken_string &); // gestione dei messaggi estesi nei campi
 | 
						|
 | 
						|
public:
 | 
						|
  TMRP_form(const char* name, TCodgiac_livelli* c, int l);
 | 
						|
  virtual ~TMRP_form() {} ;
 | 
						|
};
 | 
						|
 | 
						|
TMRP_form::TMRP_form(const char* name, TCodgiac_livelli* c, int l) : TForm(name)
 | 
						|
{
 | 
						|
  _codgiac  = c;
 | 
						|
  _level = l;
 | 
						|
}
 | 
						|
 | 
						|
bool TMRP_form::validate(TForm_item &cf, TToken_string &s)
 | 
						|
{
 | 
						|
  const TString code(s.get(0)); 
 | 
						|
  
 | 
						|
  if (code == "_MRP")
 | 
						|
  {
 | 
						|
    TLocalisamfile& rep = cf.form().cursor()->file();
 | 
						|
    TString action(s.get(1));
 | 
						|
    TString livello, descr;
 | 
						|
    if (action == "DESCRLIV")
 | 
						|
    {
 | 
						|
      if (_level > 0)
 | 
						|
        livello = rep.get("LIVELLO");
 | 
						|
      if (livello.not_empty())
 | 
						|
      {
 | 
						|
        for (int lev=1; lev <= _level; lev++)
 | 
						|
        {
 | 
						|
          if (!_codgiac->enabled(lev))
 | 
						|
            continue;
 | 
						|
          const int starts = _codgiac->code_start(lev) -1;
 | 
						|
          const int length   = _codgiac->code_length(lev);
 | 
						|
          descr << "/";
 | 
						|
          descr << livello.mid(starts,length);
 | 
						|
        }
 | 
						|
        descr << "   " << _codgiac->name(_level);
 | 
						|
        descr << " " << _codgiac->group_descr(livello,_level);
 | 
						|
      }
 | 
						|
      cf.set(descr);
 | 
						|
    }
 | 
						|
    else
 | 
						|
    if (action == "LOAD")
 | 
						|
    {
 | 
						|
      //CALCOLO percentuale carico
 | 
						|
      // MESSAGE _MRP,LOAD,<id campo1>,<id campo2>
 | 
						|
      // formula:  #id campo1 * 100 / #id campo2
 | 
						|
      // prende i contenuti dei campi specificati e ne calcola il rapporto % come indicato
 | 
						|
      real v1(cf.find_field(s.get(2)).get());
 | 
						|
      real v2(cf.find_field(s.get(3)).get());
 | 
						|
      
 | 
						|
      v1 *= 100;
 | 
						|
      if (v2 != ZERO)
 | 
						|
        v1 /= v2;
 | 
						|
      if (v1 > ZERO && v1 <= 100.0)
 | 
						|
        cf.set(v1.string("##@,@@ %"));
 | 
						|
      else
 | 
						|
        if (v1 <= ZERO)
 | 
						|
          cf.set("");
 | 
						|
        else
 | 
						|
          cf.set("*****");
 | 
						|
    }
 | 
						|
    // Ignore any other command
 | 
						|
  }
 | 
						|
  return TForm::validate(cf, s);
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// MRP report file generator
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
class TMRP_repgen : public TSkeleton_application
 | 
						|
{
 | 
						|
  TRepgen_mask     * _m;
 | 
						|
  TMRP_form        * _form;
 | 
						|
  TCodgiac_livelli *_codgiac;
 | 
						|
  int               _livello;
 | 
						|
  tipo_ordinamento  _tipo_ord;
 | 
						|
  tipo_valore       _tipo_val;
 | 
						|
  tipo_dettaglio    _dettaglio;
 | 
						|
  
 | 
						|
protected:  
 | 
						|
  void set_buckets_description();
 | 
						|
  void set_buckets();
 | 
						|
  void set_form();
 | 
						|
  virtual bool create(); 
 | 
						|
  virtual bool destroy(); 
 | 
						|
  virtual void main_loop();
 | 
						|
 | 
						|
public:
 | 
						|
  TMRP_repgen() { _m = NULL; }
 | 
						|
  virtual ~TMRP_repgen() {}
 | 
						|
};
 | 
						|
 | 
						|
bool TMRP_repgen::create()
 | 
						|
{
 | 
						|
  open_files(LF_MRPREP, LF_RIGHEDOC, LF_ANAMAG, LF_TAB, 0);
 | 
						|
 | 
						|
  TConfig ini(CONFIG_DITTA, "mr");
 | 
						|
 | 
						|
  _m = new TRepgen_mask;
 | 
						|
  _codgiac = new  TCodgiac_livelli;
 | 
						|
  if (!_codgiac->enabled())
 | 
						|
    _m->hide(F_LIVDET);
 | 
						|
  return TSkeleton_application::create();
 | 
						|
}
 | 
						|
 | 
						|
bool TMRP_repgen::destroy()
 | 
						|
{
 | 
						|
  delete _codgiac;
 | 
						|
  if (_m)
 | 
						|
    delete _m;
 | 
						|
  return TSkeleton_application::destroy();
 | 
						|
}
 | 
						|
 | 
						|
void TMRP_repgen::set_buckets_description()
 | 
						|
{
 | 
						|
  TString descr;
 | 
						|
	TRepgen_mask & mask = *_m;
 | 
						|
  TDate fd(mask.start_date());
 | 
						|
  TConfig ini(CONFIG_DITTA, "mr");
 | 
						|
  const bool week_complete = ini.get_bool("WEEKCOMPLETE");
 | 
						|
	const int bucket_size = _m->get_bucket_size();
 | 
						|
  int weekd, yeard;
 | 
						|
  const short first_id = 3;
 | 
						|
  const short last_id = 15;
 | 
						|
	int last_bucket = mask.last_bucket();
 | 
						|
 | 
						|
  if (last_bucket >= LAST_BUCKET)
 | 
						|
		last_bucket = LAST_BUCKET - 1;
 | 
						|
	--fd;
 | 
						|
	descr.cut(0);
 | 
						|
	if (bucket_size != 1)
 | 
						|
		descr << "\n";
 | 
						|
	descr  << TR("Al") << "  " << fd.string();
 | 
						|
	if (bucket_size == 7)
 | 
						|
	{
 | 
						|
		fd.get_week_year(weekd, yeard, week_complete);
 | 
						|
		descr << "\n" << TR("Sett.") << " " << weekd << ' ' << yeard;
 | 
						|
	}
 | 
						|
  TForm_item & ff = _form->find_field('B', odd_page, first_id);
 | 
						|
	ff.set_col_head(descr);
 | 
						|
  for (short i = 1; i <= (short) last_bucket; i++)
 | 
						|
  {
 | 
						|
    ++fd;
 | 
						|
		descr.cut(0);
 | 
						|
		if (bucket_size != 1)
 | 
						|
			descr << FR("Dal"); fd.string();
 | 
						|
		descr << " " << fd.string() << " ";
 | 
						|
		if (bucket_size != 1)
 | 
						|
		{
 | 
						|
			fd += bucket_size-1;
 | 
						|
			descr << "\n" << FR("Al") << "  " << fd.string();
 | 
						|
			if (bucket_size == 7)
 | 
						|
			{
 | 
						|
				fd.get_week_year(weekd, yeard, week_complete);
 | 
						|
				descr << "\n" << TR("Sett.") << " " << weekd << ' ' << yeard;
 | 
						|
			}
 | 
						|
		}
 | 
						|
    TForm_item & fi = _form->find_field('B', odd_page, first_id + i);
 | 
						|
		fi.set_col_head(descr);
 | 
						|
  }
 | 
						|
	++fd;
 | 
						|
	descr.cut(0);
 | 
						|
	descr << FR("Dal ") << fd.string();
 | 
						|
	if (bucket_size == 7)
 | 
						|
	{
 | 
						|
		fd.get_week_year(weekd, yeard, week_complete);
 | 
						|
		descr << TR("\n\nSett. ") << weekd << ' ' << yeard;
 | 
						|
	}
 | 
						|
  TForm_item & lf = _form->find_field('B', odd_page, last_id);
 | 
						|
	lf.set_col_head(descr);
 | 
						|
}
 | 
						|
 | 
						|
void TMRP_repgen::set_buckets()
 | 
						|
{
 | 
						|
  TString tmp;
 | 
						|
 | 
						|
  // Calcola l'ultimo bucket visibile: 
 | 
						|
  // Il bucket iniziale e quello finale dovrebbero essere sempre visibili
 | 
						|
  const short last_bucket = _m->last_bucket();
 | 
						|
 | 
						|
  // Disabilita le colonne in base al numero di buckets da visualizzare
 | 
						|
	if (last_bucket < LAST_BUCKET - 1)
 | 
						|
	{
 | 
						|
		const short first_id = 4;   // Bucket  1
 | 
						|
		const short last_id  = 14;  // Bucket  11
 | 
						|
 | 
						|
		for (short id = first_id+last_bucket; id <= last_id; id++)
 | 
						|
			 _form->find_field('B',odd_page,id).disable();
 | 
						|
 | 
						|
		// Nella stampa scheduling linee, non esiste un totale per linea/impianto ma per articolo/liv giacenza
 | 
						|
		for (id = first_id+last_bucket+100; id <= (last_id+100); id++)
 | 
						|
			 _form->find_field('B',odd_page,id).disable();
 | 
						|
	}
 | 
						|
 | 
						|
  set_buckets_description();
 | 
						|
  
 | 
						|
  // Show delle subsections necessarie
 | 
						|
  TToken_string sections;
 | 
						|
  const bool tl = _tipo_ord == linea;
 | 
						|
  
 | 
						|
  switch (_dettaglio)
 | 
						|
  {
 | 
						|
    case det_articolo:
 | 
						|
      sections = tl ? "IMPIANTI|LINEE" : "";
 | 
						|
      break;
 | 
						|
    case det_giacenza:
 | 
						|
      sections = tl ? "IMPIANTI|LINEE|ARTICOLI" :  "ARTICOLI";
 | 
						|
      break;
 | 
						|
    case det_impianto:
 | 
						|
      sections = tl ? "" : "ARTICOLI|LIVELLI";
 | 
						|
      break;
 | 
						|
    case det_linea:
 | 
						|
			sections = tl ? "IMPIANTI" : "ARTICOLI|LIVELLI|IMPIANTI";
 | 
						|
      break;
 | 
						|
    default: break;
 | 
						|
  }
 | 
						|
  
 | 
						|
  const int items = sections.items();
 | 
						|
  for (int i=0; i<items; i++)
 | 
						|
    _form->find_field('B', odd_page, sections.get(i)).show();
 | 
						|
 | 
						|
  if ((tl && _dettaglio == det_giacenza) || (!tl && _dettaglio >= det_giacenza))
 | 
						|
    if (_livello > 0)
 | 
						|
    {
 | 
						|
      tmp.format("LIVELLO[1,%d]", _codgiac->packed_length(_livello));
 | 
						|
      _form->find_field('B', odd_page, "LIVELLI").setcondition(tmp,_strexpr);
 | 
						|
    }
 | 
						|
  
 | 
						|
  if (tl && _m->get_bool(F_CAPACITA)) // Abilitato il calcolo capacita/carico linea?
 | 
						|
  {
 | 
						|
    _form->find_field('B', odd_page, 238).show();
 | 
						|
    short lid = 240 + last_bucket;
 | 
						|
		if (lid > 250)
 | 
						|
			lid = 250;
 | 
						|
    for (short id = 240; id<lid; id++)
 | 
						|
      _form->find_field('B', odd_page, id).show();
 | 
						|
  }
 | 
						|
  
 | 
						|
  if (tl)
 | 
						|
	{
 | 
						|
		if (_tipo_val == quantita) // Stampa scheduling, disabilita totali per linea/impianto)
 | 
						|
		{
 | 
						|
			// Abilita i campi per l'unita di misura sui totali per livello giac. e articolo
 | 
						|
			_form->find_field('B', odd_page, 2).show();
 | 
						|
			_form->find_field('B', odd_page, 302).show();
 | 
						|
			_form->find_field('B', odd_page, 402).show();
 | 
						|
			_form->find_field('B', odd_page, 502).show();
 | 
						|
			for (short id = 201; id <= 215; id++)
 | 
						|
				_form->find_field('B', odd_page, id).hide(); // Riga totale linea
 | 
						|
			for (id = 101; id <= 115; id++)
 | 
						|
				_form->find_field('B', odd_page, id).hide(); // Riga totale impianto
 | 
						|
		}
 | 
						|
	}
 | 
						|
  else
 | 
						|
		if (_tipo_val == carico) // Stampa carico per articoli
 | 
						|
		{
 | 
						|
			// Nasconde la colonna delle unita' di misura.
 | 
						|
			// Il calcolo capacita' non ha senso e quindi viene omesso in
 | 
						|
			// stampa, sebbene sia possibile effettuarne il calcolo.
 | 
						|
			_form->find_field('B', odd_page, 2).hide();
 | 
						|
			_form->find_field('B', odd_page, 102).hide();
 | 
						|
			_form->find_field('B', odd_page, 202).hide();
 | 
						|
			_form->find_field('B', odd_page, 302).hide();
 | 
						|
			_form->find_field('B', odd_page, 402).hide();
 | 
						|
		}
 | 
						|
  
 | 
						|
  // Prende il titolo della stampa dal nome profilo
 | 
						|
  _form->find_field('H', odd_page,4).set(_m->get(DLG_PROFILE));
 | 
						|
}
 | 
						|
 | 
						|
void TMRP_repgen::set_form()
 | 
						|
{
 | 
						|
  TString expr,tmp;
 | 
						|
  TString from(_m->get(_tipo_ord == articolo ? F_ARTFROM : F_IMPIANTOFROM));
 | 
						|
  TString to(_m->get(_tipo_ord == articolo ? F_ARTTO : F_IMPIANTOTO));
 | 
						|
 | 
						|
  expr.format("(TIPO==\"R\")");
 | 
						|
  if (_tipo_ord == articolo)
 | 
						|
  {
 | 
						|
    if (from.not_empty())
 | 
						|
    {
 | 
						|
      expr << "&&";  
 | 
						|
      tmp.format("(CODART>=\"%s\")",(const char*)from);
 | 
						|
      expr << tmp;
 | 
						|
    }
 | 
						|
    if (to.not_empty())
 | 
						|
    {
 | 
						|
      if (expr.not_empty())
 | 
						|
        expr << "&&";  
 | 
						|
      tmp.format("(CODART<=\"%s\")",(const char*)to);
 | 
						|
      expr << tmp;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    if (from.not_empty())
 | 
						|
    {
 | 
						|
      expr << "&&";  
 | 
						|
      tmp.format("(IMPIANTO>=\"%s\")",(const char*)from);
 | 
						|
      expr << tmp;
 | 
						|
    }
 | 
						|
  
 | 
						|
    if (to.not_empty())
 | 
						|
    {
 | 
						|
      if (expr.not_empty())
 | 
						|
        expr << "&&";  
 | 
						|
      tmp.format("(IMPIANTO<=\"%s\")",(const char*)to);
 | 
						|
      expr << tmp;
 | 
						|
    }
 | 
						|
  
 | 
						|
  
 | 
						|
    from = _m->get(F_LINEAFROM);
 | 
						|
    to   = _m->get(F_LINEAFROM);
 | 
						|
  
 | 
						|
    if (from.not_empty())
 | 
						|
    {
 | 
						|
      if (expr.not_empty())
 | 
						|
        expr << "&&";  
 | 
						|
      tmp.format("(LINEA>=\"%s\")",(const char*)from);
 | 
						|
      expr << tmp;
 | 
						|
    }
 | 
						|
  
 | 
						|
    if (to.not_empty())
 | 
						|
    {
 | 
						|
      if (expr.not_empty())
 | 
						|
        expr << "&&";  
 | 
						|
      tmp.format("(LINEA<=\"%s\")",(const char*)to);
 | 
						|
      expr << tmp;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  
 | 
						|
  if (expr.not_empty()) // Filtronzo... il filtro gonzo
 | 
						|
    _form->cursor()->setfilter(expr);
 | 
						|
  
 | 
						|
  set_buckets();
 | 
						|
}
 | 
						|
 | 
						|
void TMRP_repgen::main_loop()
 | 
						|
{
 | 
						|
	KEY k;
 | 
						|
  while ((k = _m->run()) != K_QUIT)
 | 
						|
  {
 | 
						|
    const bool use_file = _m->get_bool(F_USAFILE);
 | 
						|
    if (use_file || _m->elabora())
 | 
						|
    {
 | 
						|
			if (k == K_ENTER)
 | 
						|
			{
 | 
						|
				TFilename report_name(_m->get(F_REPORT));
 | 
						|
				
 | 
						|
				if (report_name.empty())
 | 
						|
				{
 | 
						|
					_tipo_ord = (tipo_ordinamento) _m->get_int(F_ORDINAMENTO);
 | 
						|
					_tipo_val = (tipo_valore)      _m->get_int(F_VAL2PRINT);
 | 
						|
					_livello = _m->get_int(F_LIVDET);
 | 
						|
 | 
						|
					const bool delfile = !_m->get_bool(F_GENREPORT) && !use_file;
 | 
						|
      
 | 
						|
					if (delfile)
 | 
						|
					{
 | 
						|
						_m->reset(F_FILENAME);
 | 
						|
					}
 | 
						|
 | 
						|
					// Utilizza questo file per la stampa del form   
 | 
						|
					_dettaglio  = (tipo_dettaglio) _m->get_int(_tipo_ord == articolo ? F_DETTAGLIO1 : F_DETTAGLIO2);
 | 
						|
					_form = new TMRP_form(_tipo_ord == articolo ? "mr1100a" : "mr1100b", _codgiac, _livello);
 | 
						|
					TRelation* rel = _form->relation();
 | 
						|
 | 
						|
					if (!delfile)
 | 
						|
					{
 | 
						|
						TFilename fname(_m->get(F_FILENAME)); // Presente 24 ore su 24
 | 
						|
						fname.insert("%"); // e questo dove lo mettiamo?
 | 
						|
						TIsamtempfile * report = new TIsamtempfile(LF_MRPREP,fname, FALSE, delfile);
 | 
						|
						rel->replace(report);
 | 
						|
					}
 | 
						|
					set_form();
 | 
						|
      
 | 
						|
					const int hh = 7;
 | 
						|
					const int fl = printer().formlen();
 | 
						|
      
 | 
						|
					int rows[4];         // Righe orizzontali
 | 
						|
					rows[0] = hh-4;
 | 
						|
					rows[1] = hh;
 | 
						|
					rows[2] = fl;
 | 
						|
					rows[3] = 0;
 | 
						|
					_form->genera_intestazioni(odd_page, hh-3);
 | 
						|
					_form->genera_fincatura(odd_page, hh-4, fl, rows);
 | 
						|
  
 | 
						|
					// stampa
 | 
						|
					if (_form->cursor()->items() > 0)
 | 
						|
						_form->print();
 | 
						|
					// report non va cancellato, poiche' ne viene fatta la sostituzione nella relazione del form
 | 
						|
					// quindi la delete viene gia' fatta alla distruzione di _form
 | 
						|
					delete _form;
 | 
						|
					_form = NULL;
 | 
						|
				}
 | 
						|
				else
 | 
						|
				{
 | 
						|
					TReport_book book;
 | 
						|
					TReport rep; 
 | 
						|
					
 | 
						|
					if (rep.load(report_name))
 | 
						|
					{
 | 
						|
						book.add(rep);
 | 
						|
						if (book.pages() > 0)
 | 
						|
							book.print_or_preview();
 | 
						|
					}
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
int mr1100(int argc, char* argv[])
 | 
						|
{
 | 
						|
  TMRP_repgen a;
 | 
						|
  a.run(argc, argv, TR("Generazione MRP reports"));
 | 
						|
  return 0;
 | 
						|
}
 |