// Stampa dettaglio disponibilita' articoli
#include <applicat.h>
#include <automask.h>
#include <colors.h>
#include <defmask.h>
#include <execp.h>
#include <progind.h>
#include <reprint.h>
#include <utility.h>

#include "../or/orlib.h"
#include "../cg/cglib01.h"
#include "../mg/anamag.h"
#include "../ve/velib07.h"

#include "ps0430300a.h"

#include <clifo.h> 
#include <cfven.h> 

///////////////////////////////////////////////////////////
// TArticoli_recordset
///////////////////////////////////////////////////////////

class TArticoli_recordset : public TISAM_recordset
{
  static TString8 __codmag;
  static int __codes;
	
  bool _sottoscorta;

protected:
	static bool filtra_sottoscorta(const TRelation* rel);

public:
	virtual TCursor* cursor() const;
	TArticoli_recordset(const char* use, bool sottoscorta, int codes, const char * codmag) : TISAM_recordset(use), _sottoscorta(sottoscorta) { __codes = codes; __codmag = codmag;}
	virtual ~TArticoli_recordset() {}
};

TString8 TArticoli_recordset::__codmag;
int      TArticoli_recordset::__codes;

bool TArticoli_recordset::filtra_sottoscorta(const TRelation* rel)
{
	((TRelation*)rel)->save_status();
  const char* codart = rel->curr(LF_ANAMAG).get(ANAMAG_CODART);
  TArticolo_giacenza artgiac(codart);

  const real giac = artgiac.giacenza_anno(__codmag, NULL, __codes);

  const bool ok = giac < artgiac.scorta_minima(__codmag, NULL, __codes);
	((TRelation*)rel)->restore_status();
	return ok;
}

TCursor* TArticoli_recordset::cursor() const
{
	TCursor* c = TISAM_recordset::cursor();
	if (c != NULL && _sottoscorta)
	  c->set_filterfunction(filtra_sottoscorta);
	return c;
}

///////////////////////////////////////////////////////////
// TConsumi_report
///////////////////////////////////////////////////////////

class TConsumi_report : public TDocument_report
{
protected:
  virtual bool use_mask() { return false; }

public:
  TConsumi_report();
};

TConsumi_report::TConsumi_report()
{
  load("ps0430300a");
}


///////////////////////////////////////////////////////////
// TGenera_ordini_mask
///////////////////////////////////////////////////////////

class TGenera_ordini_mask : public TAutomask
{
	TString _anamag_query;
	TString _disable_expr;
	TString8 _disable_num;
	TExpression _dis;
	TString _doc_filter;
	int _days_interval;
  int _riga_da_selezionare;
	bool _filter_changed, _order_changed;
	
private:
  void serialize(bool bSave);
	void load_user_defs();
	void update_sheet();
	void update_orders();
	void reconstruction(const TDocumento& doc2delete);

protected:
	bool on_sheet_event(TOperable_field& o, TField_event e, long jolly);
  virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
	virtual void next_page(int p);
  virtual void on_idle();

public:

  TGenera_ordini_mask();
  ~TGenera_ordini_mask();
};

///////////////////////////////////////////////////////////
// TCreazione_ordini
///////////////////////////////////////////////////////////

class TCreazione_ordini : public TSkeleton_application
{
  TGenera_ordini_mask* _mask;

protected:
  virtual const char * extra_modules() const {return "or";}
	TString_array _userfld;
	void aggiorna_stato_doc_orig(const TRectype& rdoc);

public:
  void generate_orders();
  void generate_carics();
  virtual bool create(); 
  virtual void main_loop();
  virtual bool destroy(); 
  virtual void print();
	void print_doc(const TRectype & doc);
};

inline TCreazione_ordini & capp() { return (TCreazione_ordini &) main_app();}

///////////////////////////////////////////////////////////
// TGenera_ordini_mask
///////////////////////////////////////////////////////////

void TGenera_ordini_mask::update_sheet()
{
	_filter_changed = false;

  TWait_cursor hourglass;
  const TDate oggi(TODAY);

	TSheet_field& sf = sfield(F_ARTICLES);
	TEsercizi_contabili esc;
	TString query(_anamag_query);
	TString16 grmerc(get(F_GRMERC));
	const int pos = query.find("KEY ");
	TArticolo_giacenza art;
	TString8 codmag(get(F_MAG));
	const TString4 codnum(get(F_CODNUM));
	const bool check_expr = codnum == _disable_num;
	int anno = get_int(F_ANNO);
  if (anno <= 0)
    anno = oggi.year();

	codmag.left_just(3);
	codmag << get(F_DEP);
	codmag.trim();
	
	grmerc.left_just(3);
	grmerc << get(F_SGRMERC);
	grmerc.trim();

	if (grmerc.full())
	{
		if (pos > 0)
			query[pos + 4] = '3';
		query << "\nFROM GRMERC=#GRMERC\nTO GRMERC=#GRMERC";
	}
	else
		if (pos > 0)
			query[pos + 4] = '2';
	
	TString select;

	const TString & codart = get(F_SCODART);

	if (codart.full())
		select << "(UPPER(" << ANAMAG_CODART << ")?=UPPER(\"" << codart << "\"))";

	const TString & desart = get(F_SDESART);

	if (desart.full())
	{
		if (select.full())
			select << "&&";
		select << "(UPPER(" << ANAMAG_DESCR << ")?=UPPER(\"" << desart << "\"))";
	}

	const TString& desagg = get(F_SDESAGG);
	if (desagg.full())
	{
		if (select.full())
			select << "&&";
		select << "(UPPER(" << ANAMAG_DESCRAGG << ")?=UPPER(\"" << desagg << "\"))";
	}

	const TString& codforn = get(F_SCODFOR);
	if (codforn.full())
	{
		if (select.full())
			select << "&&";
		select << "(" << ANAMAG_CODFORN << "==\"" << codforn << "\")";
	}

	const TString& ragsoc = get(F_SRAGSOC);

	if (ragsoc.full())
	{
		if (select.full())
			select << "&&";
		select << "(UPPER(CLIFO.RAGSOC)?=UPPER(\"" <<  ragsoc << "\"))";
	}

	if (select.full())
	{
		int pos = query.find("SELECT ");
		if (pos > 0)
		{
			const int acapo = query.find('\n', pos);
			query.insert("((", pos+7);
      select.insert(")&&(");
			select << "))";
			query.insert(select, acapo+2);
		}
		else
		{
		  pos = query.find('\n');
			select.insert("\nSELECT ");
			query.insert(select, pos);
		}
	}


	TArticoli_recordset recset(query, get_bool(F_SOTTOSCORTA), esc.date2esc(oggi), get(F_MAG));
	TVariant var ;

	var = grmerc;
	recset.set_var("#GRMERC", var);
	var =  user();
	recset.set_var("#USER", var);
	TString8 codes; codes.format("%04d", esc.date2esc(oggi));
	var = codmag;
	recset.set_var("#CODMAG", var);
	var = (long)anno;
	recset.set_var("#ANNOES", var);
	
	int i = 0;

	sf.destroy();

  for (bool ok = recset.move_first(); ok; ok = recset.move_next())
  {
		TToken_string & row = sf.row(i);
		const TString & codart = recset.get(LF_ANAMAG, ANAMAG_CODART).as_string();

		row.add(codart, sf.cid2index(F_CODART));
		art.read(codart);
		const real giac = art.giacenza_anno(codmag, "", anno);
		row.add(recset.get(LF_ANAMAG, ANAMAG_DESCR).as_string(), sf.cid2index(F_DESCR));
		row.add(recset.get("UMART.UM").as_string(), sf.cid2index(F_UM));

		const long  codforn = recset.get(LF_ANAMAG, ANAMAG_CODFORN).as_int();
		
		row.add(codforn, sf.cid2index(F_FORNITORE));
		row.add(recset.get("CLIFO.RAGSOC").as_string(), sf.cid2index(F_RAGSOC));
		row.add(recset.get(LF_ANAMAG, ANAMAG_GIORNIRIOR).as_string(), sf.cid2index(F_LEADTIME));
		row.add(recset.get(LF_ANAMAG, ANAMAG_LOTTORIOR).as_string(), sf.cid2index(F_LOTTOMIN));
		row.add(recset.get(LF_ANAMAG, ANAMAG_DESCRAGG).as_string(), sf.cid2index(F_DESCRAGG));
		row.add(giac.string(), sf.cid2index(F_GIACENZA));

		row.add(recset.get(LF_ANAMAG, ANAMAG_PPCONF).as_string(), sf.cid2index(F_PPCONF));
		row.add(recset.get(LF_ANAMAG, ANAMAG_USER1).as_string(), sf.cid2index(F_USER1));
		row.add(recset.get(LF_ANAMAG, ANAMAG_USER2).as_string(), sf.cid2index(F_USER2));
		row.add(recset.get(LF_ANAMAG, ANAMAG_USER3).as_string(), sf.cid2index(F_USER3));
		row.add(recset.get(LF_ANAMAG, ANAMAG_USER4).as_string(), sf.cid2index(F_USER4));
		row.add(recset.get(LF_ANAMAG, ANAMAG_USER5).as_string(), sf.cid2index(F_USER5));
		row.add(recset.get(LF_ANAMAG, ANAMAG_USER6).as_string(), sf.cid2index(F_USER6));
		row.add(recset.get(LF_ANAMAG, ANAMAG_USER7).as_string(), sf.cid2index(F_USER7));
		row.add(recset.get(LF_ANAMAG, ANAMAG_USER8).as_string(), sf.cid2index(F_USER8));
		row.add(recset.get(LF_ANAMAG, ANAMAG_USER9).as_string(), sf.cid2index(F_USER9));
		row.add(recset.get(LF_ANAMAG, ANAMAG_USER10).as_string(), sf.cid2index(F_USER10));
		const real disp = art.disponibilita(codes, get(F_MAG), NULL);
		row.add(disp.string(), sf.cid2index(F_DISPON));
		sf.check_row(i);
		if (check_expr)
		{
			for (int j = _dis.numvar() - 1; j >= 0;  j--)
			{
				const TString16 varn =_dis.varname(j);

				if (varn == "GIAC")
					_dis.setvar(j, giac.string());
				else
					if (varn == "USER")
						_dis.setvar(j, user());
					else
						_dis.setvar(j, recset.get(varn).as_string());
			}
			if (_dis.as_bool())
				sf.disable_row(i);

		}
		i++;
	}

  sf.force_update();
}

void TGenera_ordini_mask::update_orders()
{
	_order_changed = false;
  TWait_cursor hourglass;

  TSheet_field& sh = sfield(F_ORDERS);
  sh.destroy();

  TString query;
  query << "USE RDOC\n";
  query << "SELECT (CODARTMAG!=\"\")&&(CODCMS==#CODCMS)"
				<< "&&(BETWEEN(33.STATO,#DASTATO,#ASTATO))"
				<< "&&(RIGAEVASA!=\"X\")\n";
  query << "JOIN ANAMAG INTO CODART==CODART\n";
  query << "JOIN DOC INTO PROVV==PROVV ANNO==ANNO CODNUM==CODNUM NDOC==NDOC\n";
  query << "JOIN CLIFO TO DOC INTO TIPOCF=\"F\" CODCF==CODCF\n";
  query << "FROM CODNUM=#CODNUM ANNO=#DAANNO\n";
  query << "TO   CODNUM=#CODNUM ANNO=#ADANNO\n";

  const long anno = get_int(F_ANNO);

  TISAM_recordset orders(query);
  orders.set_var("#DASTATO", TVariant(get(F_DASTATO)));
  orders.set_var("#ASTATO",  TVariant(get(F_ASTATO)));
  orders.set_var("#CODCMS",  TVariant(get(F_CDCT)));
  orders.set_var("#CODNUM",  TVariant(get(F_CODNUM)));
  orders.set_var("#DAANNO",  TVariant(anno-2L));
  orders.set_var("#ADANNO",  TVariant(anno));

  TMask& m = sh.sheet_mask();
  TRelation& rel = *orders.cursor()->relation();

	const int status_pos = sh.cid2index(S_STATODOC);
  for (bool ok = orders.move_first(); ok; ok = orders.move_next())
  {
    TToken_string& row = sh.row(-1);
    FOR_EACH_MASK_FIELD(m, i, f)
    {
      const TFieldref* fr = f->field();
      if (fr != NULL)
			{
	      const int j = sh.cid2index(f->dlg());
        row.add(fr->read(rel), j);
			}
    }
    const int nrow = sh.items()-1;
    switch (row.get_int(status_pos))
    {
    case  1: sh.set_back_and_fore_color(NORMAL_BACK_COLOR, NORMAL_COLOR, nrow); break;
    case  2: sh.set_back_and_fore_color(REQUIRED_BACK_COLOR, NORMAL_COLOR, nrow); break;
    default: sh.set_back_and_fore_color(DISABLED_BACK_COLOR, DISABLED_COLOR, nrow); break;
    }
		sh.check_row(nrow);
  }
  sh.force_update();
}

void TGenera_ordini_mask::next_page(int p)
{
	TAutomask::next_page(p);
	
  if (_filter_changed)
	{
		const TSheet_field& sf = sfield(F_ARTICLES);
		if (win() == sf.parent())
			update_sheet();
	}
  if (_order_changed)
	{
		const TSheet_field& sf = sfield(F_ORDERS);
		if (win() == sf.parent())
			update_orders();
	}

}

bool TGenera_ordini_mask::on_sheet_event(TOperable_field& o, TField_event e, long jolly)
{
  switch(e)
  {
	case se_query_del:
	case se_query_add:
		return false;
  case fe_init:
    if (o.dlg() == F_ARTICLES)
      update_sheet();
    else
      update_orders();
    break;

  case se_notify_modify:
    if (o.dlg() == F_ARTICLES)
    {
      TEdit_field& cc = efield(F_CAZ_CODART);
      cc.reset();
      cc.set_focus();
    }
    break;

	default:
		break;
  }
  return true;
}

void TGenera_ordini_mask::reconstruction(const TDocumento& doc2delete)
{
	const char* const defpar = "or";
	TConfig c(CONFIG_USER, defpar);
	const char statoini = c.get_char("OR14_STATOINI");

  const int rows = doc2delete.rows();
  for (int i=1; i<=rows; i++) 
  {
    const TRiga_documento& r = doc2delete[i];
		const TRectype* original_doc = r.find_original_doc();
		if (original_doc != NULL)
		{
			TDocumento d(*original_doc);
			const long nriga = r.get_long(RDOC_DAIDRIGA);
			if (nriga != 0)
			{
				TRiga_documento& original_row = d[nriga];
				const real qta = r.quantita();
				const TString& name = original_row.field_qtaevasa();
				real qtaevasa = original_row.get_real(name) - qta;
				if (qtaevasa < ZERO)
					qtaevasa = ZERO;
				original_row.put(name, qtaevasa);
				if (qtaevasa < original_row.quantita())
					original_row.zero(RDOC_RIGAEVASA);
				else
					original_row.put(RDOC_RIGAEVASA, "X");
				if (statoini != ' ')
					d.stato(statoini);
				d.rewrite();
			}
		}
	}
}


bool TGenera_ordini_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
  bool ok = true;
	switch (o.dlg())
  {
	case F_GRMERC:
	case F_SGRMERC:
	case F_SOTTOSCORTA:
	case F_SCODART:
	case F_SDESART:
	case F_SDESAGG:
	case F_SCODFOR:
	case F_SRAGSOC:
		if (e == fe_modify)
			_filter_changed = true;
		break;
  case F_CODNUM:
		if (e == fe_modify)
		{
			_order_changed = true;
			_filter_changed = true;
		}
		break;
	case F_TIPODOC:
		if (e == fe_init || e == fe_modify)
		{
			const TTipo_documento tipodoc(o.get());
			const bool is_ordine = tipodoc.is_ordine();
			enable(DLG_ELABORA, is_ordine);
		}
		break;
  case F_ANNO:
		if (e == fe_init && o.empty())
    {
      const TDate oggi(TODAY);
      TString4 anno; anno << oggi.year();
      o.set(anno);
    }
		if (e == fe_modify)
			_filter_changed = true;
    // continue
  case F_DASTATO:
  case F_ASTATO:
    if (e == fe_modify)
      update_orders();
    break;

  case F_CAZ_CODART:  //ricerca riga da codart in testa alla maschera
    if (e == fe_modify)
    {
      int found = -1;
      bool non_esiste = true;

      const TString& selected_codart = o.get();
      //ricerca sui codici articolo in anagrafica possibili (sono quelli sullo sheet)
      TSheet_field& sf_righe = sfield(F_ARTICLES);
      FOR_EACH_SHEET_ROW(sf_righe, r, row)
      {
        const TString& riga_codart = row->get(0);
        if (selected_codart == riga_codart)
        {
          found = r;
          break;
        }
      }
      //se non lo pesca in anagrafica tenta con i codici articolo fornitore (CODCORR_CODARTALT)
      if (found < 0)
      {
        FOR_EACH_SHEET_ROW(sf_righe, r, row)
        {
          const TString& riga_codart = row->get(0);
          TString query;
          query << "USE CODCORR";
          query << "\nSELECT CODARTALT=#CODARTALT";
          query << "\nFROM CODART=#CODART";
          query << "\nTO CODART=#CODART";
          TISAM_recordset recset(query);
          recset.set_var("#CODARTALT", selected_codart);
          recset.set_var("#CODART", riga_codart);
          const int items = recset.items();
          //usando la chiave 1 -> items puo' essere 1 o 0 per ogni riga dello sheet
          if (items == 1)
          {
            if (found < 0)
              found = r;
            else
            {
              error_box(FR("Il codice %s puo' riferirsi alle righe %d e %d!\nRisolvere l'ambiguita' in anagrafica articoli."), 
                       (const char*)selected_codart, found + 1, r + 1);
              found = -1;
              non_esiste = false;
              break;
            }
          } //if(items==1...
        } //FOR_EACH_SHEET_ROW(sf_righe,...
      } //if(found<0...

      //ha trovato l'articolo nello sheet e si posiziona sulla sua riga
      if (found >= 0)
      {
        _riga_da_selezionare = found;
      }
      else  //se non l'ha trovato -> segnala che l'articolo selezionato non esiste nello sheet
      {
        if (non_esiste)
          error_box(TR("L'articolo %s selezionato non esiste nella lista"), (const char*)selected_codart);
      }
    }
    break;

  case DLG_PRINT:
    if (e == fe_button)
    {
      TConsumi_report cr;
      cr.mask2report(*this);
      TReport_book book;
      book.add(cr);
      book.print_or_preview();
      ok = false; // Non uscire
    }
    break;
	case DLG_PRINTDOC:
    if (e == fe_button)
    {
      TString query;
      
			query << "USE 33 ";
			if (_doc_filter.full())
				query << "SELECT " << _doc_filter; // CODCMS=#CODCMS\n"
			query <<  "\n"
            << "JOIN 20 INTO TIPOCF==TIPOCF CODCF==CODCF\n"
            << "FROM PROVV=D ANNO=#ANNO CODNUM=#CODNUM\n"
            << "TO PROVV=D ANNO=#ANNO CODNUM=#CODNUM";
      TISAM_recordset rset(query);
      rset.set_var("#CODCMS", TVariant(get(F_CDCT)));
      rset.set_var("#ANNO",   TVariant(get(F_ANNO)));
      rset.set_var("#CODNUM", TVariant(get(F_CODNUM)));

      TCursor* c = rset.cursor();
			TCursor_sheet sht(c, " |CODNUM|NDOC|DATADOC|DATACONS|CODCF|20->RAGSOC", TR("Selezione Documenti"),
		                    HR("@1|Ordine@6|Numero\nDoc.@7|Data\nDoc.@10|Data\nConsegna@10|Fornitore|Ragione Sociale@50"),0,1);
			sht.uncheck(-1);

			if (sht.run() && sht.one_checked())
			{
				const int items = c->items();
				for (*c = 0L; c->pos() < items; ++(*c)) if (sht.checked(c->pos()))
				  capp().print_doc(c->curr());

        update_sheet();
        update_orders();
			}
      ok = false; // Non uscire
    }
		break;
	case DLG_DELREC:
    if (e == fe_button)
    {
      TString query;
			TString select;

      query << "USE 33";
			if (_doc_filter.full())
				select << "(" << _doc_filter << ')'; // CODCMS=#CODCMS\n"
			if (_days_interval > 0)
			{
				TDate datalim(TODAY);
				datalim -= _days_interval;
				if (select.full())
          select << "&&";
			  select  << "(STR(NUM(ANSI(DATADOC))>" << datalim.date2ansi() << "))";
			}
			if (select.full())
				query << " SELECT " << select;
			query <<  "\n"
            << "JOIN 20 INTO TIPOCF==TIPOCF CODCF==CODCF\n"
            << "FROM PROVV=D ANNO=#ANNO CODNUM=#CODNUM\n"
            << "TO PROVV=D ANNO=#ANNO CODNUM=#CODNUM";
      TISAM_recordset rset(query);
      rset.set_var("#CODCMS", TVariant(get(F_CDCT)));
      rset.set_var("#ANNO",   TVariant(get(F_ANNO)));
      rset.set_var("#CODNUM", TVariant(get(F_CODNUM)));

      TCursor* c = rset.cursor();
			TCursor_sheet sht(c, " |CODNUM|NDOC|DATADOC|DATACONS|CODCF|20->RAGSOC", TR("Selezione Documenti"),
		                    HR("@1|Ordine@6|Numero\nDoc.@7|Data\nDoc.@10|Data\nConsegna@10|Fornitore|Ragione Sociale@50"),0,1);
			sht.uncheck(-1);
			if (sht.run() && sht.one_checked() && yesno_box("Si desidera cancellare %d documenti", sht.checked()))
			{
				const int items = c->items();
				c->freeze();
				for (*c = 0; c->pos() < items; ++(*c)) if (sht.checked(c->pos()))
				{
          TDocumento doc(c->curr());
					reconstruction(doc); // funzione che ricostruisce la situazione precedente al documento
          doc.remove();
				}
        update_sheet();
        update_orders();
			}
      ok = false; // Non uscire
    }
    break;
	case DLG_OK:
		if (e == fe_button && jolly == 0)
		{
			capp().generate_orders();
      update_orders();
			update_sheet();
			ok = false;
		}
		break;
	case DLG_ELABORA:
		if (e == fe_button && jolly == 0)
		{
			capp().generate_carics();
      update_orders();
			update_sheet();
			ok = false;
		}
		break;
  default:
    if (o.is_kind_of(CLASS_SHEET_FIELD))
		  ok = on_sheet_event(o, e, jolly);
    break;
  }
  return ok;
}

void TGenera_ordini_mask::serialize(bool bSave)
{
  const char* const defpar = "or";
  TConfig ini(CONFIG_DITTA, defpar);
  for (int i = fields()-1; i >= 0; i--)
  {
    TMask_field& f = fld(i);
    const TFieldref* fr = f.field();
    if (fr != NULL)
    {
      if (bSave)
        fr->write(ini, defpar, f.get());
      else
        f.set(fr->read(ini, defpar));
    }
  }
}

void TGenera_ordini_mask::load_user_defs()
{
  const char* const defpar = "or";
  TConfig ini(CONFIG_USER, defpar);
  for (int i = fields()-1; i >= 0; i--)
  {
    TMask_field& f = fld(i);
    const TFieldref* fr = f.field();
    if (fr != NULL)
    {
      const char * val = fr->read(ini, defpar);
			if (*val)
			{
	      f.set(val);
				f.disable();
			}
    }
  }
}

void TGenera_ordini_mask::on_idle()
{
  TAutomask::on_idle();
  if (_riga_da_selezionare >= 0)
  {
    //si posiziona sulla qta
    TSheet_field& sf_righe = sfield(F_ARTICLES);
    const int column = sf_righe.cid2index(F_QTA);
    sf_righe.select(_riga_da_selezionare, column, true);
    _riga_da_selezionare = -1;
    sf_righe.set_focus();
  }
}

TGenera_ordini_mask::TGenera_ordini_mask() 
                   : TAutomask("ps0430300a"), _filter_changed(false), _order_changed(false)
{
  serialize(false);
	load_user_defs();
	
  TConfig c(CONFIG_DITTA, "or");
	_anamag_query = c.get("OR14_QUERY");
	if (_anamag_query.blank())
  {
		_anamag_query =  "USE ANAMAG KEY 2\nJOIN UMART INTO CODART==CODART NRIGA==1";
    _anamag_query << "\nJOIN CLIFO INTO TIPOCF==\"F\" CODCF==CODFORN";
  }
	else
		_anamag_query = esc(_anamag_query);

	_disable_num = esc(c.get("OR14_DISNUM"));
	_disable_expr = esc(c.get("OR14_DISABLE"));
	_dis.set(_disable_expr);

	_doc_filter = c.get("OR14_FILTER");
  if (_doc_filter.empty() && !field(F_CDCT).empty())
    _doc_filter = "CODCMS=#CODCMS";                   // Utile al Cigno

	_days_interval = c.get_int("OR14_DAYS");
	TSheet_field& sh = sfield(F_ARTICLES);
	TMask& sh_mask = sh.sheet_mask();
	TString prompt;
  
	for (int i = 1; i <= 10; i++)
  {                  
    const int col = sh.cid2index(F_USER1 + i -1);
    TEditable_field & f = sh_mask.efield(F_USER1 + i - 1);            
		
		if (c.get_bool("CHK_USER", "ve", i)	&& c.get_bool("USERDEF", "or", i))
    {  
      prompt = c.get("PROMPT_USER", "ve", i);
      prompt.rpad(20);              
			f.set_prompt(prompt);
			sh.set_column_header(col, prompt);
    }
		else
		{
			f.hide();
			sh.delete_column(col);
		}
  }

  //resetta l'indicatore di riga da selezionare
  _riga_da_selezionare = -1;
}

TGenera_ordini_mask::~TGenera_ordini_mask()
{
//  serialize(true);
}

///////////////////////////////////////////////////////////
// TCreazione_ordini
///////////////////////////////////////////////////////////

bool TCreazione_ordini::create()
{
  open_files(LF_DOC, LF_RIGHEDOC, LF_CONDV, LF_RCONDV, LF_ANAMAG, LF_SCONTI, LF_UMART, LF_DESLIN, LF_CODCORR,
             LF_TAB, LF_TABCOM, LF_CLIFO, LF_CFVEN, LF_INDSP, LF_OCCAS, LF_PCON, LF_MOV, LF_STOMAG, 
             LF_MOVMAG, LF_RMOVMAG, LF_MAG, LF_SVRIEP, LF_AGENTI, LF_PERCPROV, LF_ATTIV, LF_CAUSALI, 0);
	
  TConfig c(CONFIG_DITTA);
	for (int i = 0; i < 10; i++ )
		_userfld.add(c.get("USERFLD", NULL, i + 1), i);

  _mask = new TGenera_ordini_mask;

  return TSkeleton_application::create();
}

bool TCreazione_ordini::destroy()
{
  delete _mask;
  return TSkeleton_application::destroy();
}

void TCreazione_ordini::print()
{
  _mask->field(DLG_PRINT).on_hit();
}
void TCreazione_ordini::print_doc(const TRectype & doc)
{
  const TTipo_documento tipo(doc.get(DOC_TIPODOC));
  
  TFilename rep; tipo.main_print_profile(rep, 0);
  rep.ext("rep");
  
  TString commandline;
  if (rep.custom_path())     // Esiste il nuovo report :-)
    commandline = "ve1 -2";
  else                       // Esiste il vecchio form :-(
    commandline = "ve1 -0";
  
  commandline << ' ' << doc.get(DOC_CODNUM) << ' ' << doc.get(DOC_ANNO) << ' ';
  commandline << doc.get(DOC_PROVV) << ' ' << doc.get(DOC_NDOC) << ' ' << doc.get(DOC_NDOC);
  commandline << " D";

  const int ncopie = tipo.ncopie();
  if (ncopie > 0)
    commandline << ' ' << ncopie;

  TExternal_app interattivo( commandline );
  
	interattivo.run();
}

void TCreazione_ordini::aggiorna_stato_doc_orig(const TRectype& rdoc)
{
	const char provv = rdoc.get_char(RDOC_PROVV);
	const int anno = rdoc.get_int(RDOC_ANNO);
	const TString8 codnum = rdoc.get(RDOC_CODNUM);
	const long ndoc = rdoc.get_long(RDOC_NDOC);
	TDocumento doc_orig(provv, anno, codnum, ndoc);
	if (doc_orig.is_evaso())
	{
	  const char* const defpar = "or";
		TConfig c(CONFIG_USER, defpar);
		const char statoevaso = c.get_char("OR14_STATOEVASO");
		if (statoevaso != ' ')
		{
			doc_orig.stato(statoevaso);
			doc_orig.rewrite();
		}
	}
}

void TCreazione_ordini::generate_carics()
{
	TGenera_ordini_mask& mask = *_mask;
	TSheet_field& sf = mask.sfield(F_ORDERS);

  long minforn = 999999L;
	long maxforn = 0L;
  TAssoc_array orders;

  if (sf.items() > 0)
  {
	  const TDate datadoc = mask.get_date(F_DATADOCCAR);

	  const char* const defpar = "or";
		TConfig c(CONFIG_USER, defpar);
		const TString& codnum = c.get("OR14_NUMCAR");
		const TString& tipodoc = c.get("OR14_TIPCAR");

	  const TTipo_documento tipo(tipodoc);
		
    //const bool ultimo_prezzo = mask.get(F_PREZZO) == "U";
	  const TString& commessat = mask.get(F_CDCT);
	  const TString& faset     = mask.get(F_FSCT);
	  
    //TString8 codmag(mask.get(F_MAG));
	  //codmag.right_just(3);
	  //codmag << mask.get(F_DEP);

    //TString8 codmagc(mask.get(F_MAGC));
	  //codmagc.right_just(3);
	  //codmagc << mask.get(F_DEPC);

		TLocalisamfile righedoc(LF_RIGHEDOC);

    TProgind pi(sf.items(), TR("Generazione documenti di carico"), true, true);
    FOR_EACH_SHEET_ROW(sf, n, row)
    {
      if (!pi.setstatus(n))
        break;
		  if (row->get_char(sf.cid2index(S_DAEVADERE) == 'X'))
			{
				const real qta = row->get(sf.cid2index(S_QTADAEVADERE));
				if (!qta.is_zero())
				{
					const TString8 codforn(row->get(sf.cid2index(S_FORNITORE)));
					const long cod = atol(codforn);
					TString8 key; key.format("F|%ld", cod);
					const TRectype& forn = cache().get(LF_CLIFO, key);
 					const TDate datacons(row->get(sf.cid2index(S_DATACONS)));
					const TString4 codval(forn.get(CLI_CODVAL));
					const TRectype& forven = cache().get(LF_CFVEN, key);
					const TString4 codiva(forven.get(CFV_ASSFIS));
					const TString commessa = row->get(sf.cid2index(S_CDC));
					const TString fase = row->get(sf.cid2index(S_FSC));

					TDocumento* d = (TDocumento*)orders.objptr(codforn);
					if (d == NULL)
					{
						d = new TDocumento('D', datadoc.year(), codnum, 0L);
						d->put(DOC_TIPODOC, tipodoc);
						d->put(DOC_TIPOCF, "F");
						d->put(DOC_CODCF, codforn);
						d->put(DOC_DATADOC, datadoc);
						d->put(DOC_DATACONS, datacons);
						d->put(DOC_CODVAL, codval);
						d->put(DOC_CODLIN, forn.get(CLI_CODLIN));
						d->put(DOC_CODPAG, forn.get(CLI_CODPAG));
						d->put(DOC_CODABIA, forn.get(CLI_CODABI));
						d->put(DOC_CODCABA, forn.get(CLI_CODCAB));
						d->put(DOC_IBAN, forn.get(CLI_IBAN));
						d->put(DOC_CODABIP, forven.get(CFV_CODABIPR));
						d->put(DOC_CODCABP, forven.get(CFV_CODCABPR));
						d->put(DOC_RAGGR, forven.get(CFV_RAGGDOC));
						d->put(DOC_RAGGREFF, forven.get(CFV_RAGGEFF));
						d->put(DOC_CODINDSP, forven.get(CFV_CODINDSP));
						d->put(DOC_CODAG, forven.get(CFV_CODAG));
						d->put(DOC_ZONA, forven.get(CFV_CODZONA));
						d->put(DOC_CODSPMEZZO, forven.get(CFV_CODSPMEZZO));
						d->put(DOC_CODPORTO, forven.get(CFV_CODPORTO));
						d->put(DOC_CODNOTESP1, forven.get(CFV_CODNOTESP1));
						d->put(DOC_CODNOTESP2, forven.get(CFV_CODNOTESP2));
						d->put(DOC_CODNOTE, forven.get(CFV_CODNOTE));
						d->put(DOC_CODVETT1, forven.get(CFV_CODVETT1));
						d->put(DOC_CODVETT2, forven.get(CFV_CODVETT2));
						d->put(DOC_CODVETT3, forven.get(CFV_CODVETT3));
						d->put(DOC_PERCSPINC, forven.get(CFV_PERCSPINC));  
						d->put(DOC_ADDBOLLI, forven.get(CFV_ADDBOLLI));
						d->put(DOC_CATVEN, forven.get(CFV_CATVEN));
						d->put(DOC_CODLIST, forven.get(CFV_CODLIST));
						d->put(DOC_CODCMS, commessat);
						// le note non dovrebbero servire
						//d->put(DOC_NOTE, mask.get(F_NOTE));

						const TString& causmag = tipo.caus_mov();
						d->put(DOC_CAUSMAG, causmag);
						
						orders.add(codforn, d);
						if (cod < minforn)
							minforn = cod;
						if (cod > maxforn)
							maxforn = cod;
					}

					TRiga_documento& rdoc = d->new_row("01");


					/* guy si e' molto arrabbiato nel leggere queste righe di pseudo codice (attenzione, morde!)
					const TString codart(row->get(sf.cid2index(S_CODART)));
					
					//rdoc.put(RDOC_CODMAG, codmag);
					//rdoc.put(RDOC_CODMAGC, codmagc);
					rdoc.put(RDOC_CODART, codart);
					rdoc.put(RDOC_CODARTMAG, codart);
					rdoc.put(RDOC_CHECKED, "X");
					rdoc.put(RDOC_DESCR, row->get(sf.cid2index(S_DESCART)));

					//const TString descr_agg(row->get(sf.cid2index(S_DESCRAGG)));
					//if (descr_agg.full())
					//{
					//	rdoc.put(RDOC_DESCLUNGA, "X");
					//	rdoc.put(RDOC_DESCEST, descr_agg);
					//}

					rdoc.put(RDOC_UMQTA, row->get(sf.cid2index(S_UM)));
					rdoc.put(RDOC_QTA, qta);
					rdoc.put(RDOC_DATACONS, datacons);
					
					const TRectype& articolo = cache().get(LF_ANAMAG, codart);
					//TPrice prezzo;
					//if (ultimo_prezzo)
					//	prezzo = articolo.get_real(ANAMAG_ULTCOS1);
					//else
					//	prezzo = articolo.get_real(ANAMAG_COSTSTD);
					//prezzo.change_value(codval);
					//rdoc.put(RDOC_PREZZO, prezzo.get_num());
					if (codiva.full())
						rdoc.put(RDOC_CODIVA, codiva);
					else
						rdoc.put(RDOC_CODIVA, articolo.get(ANAMAG_CODIVA));
					rdoc.put(RDOC_CODCMS, commessa);
					rdoc.put(RDOC_FASCMS, fase);
					
					for (int i = 0; i < 10 ; i++)
						if (_userfld.row(i).full())
							rdoc.put(_userfld.row(i), mask.get(F_USER1 + i));

					rdoc.put(RDOC_CODAGG1, row->get(sf.cid2index(F_CODAGG1)));
					rdoc.put(RDOC_CODAGG2, row->get(sf.cid2index(F_CODAGG2)));
					*/
					const TDate dataord = row->get(sf.cid2index(S_DATADOC));
					const long ndoc = row->get_long(sf.cid2index(S_NUMDOC));
					const int nriga = row->get_int(sf.cid2index(S_NUMRIGA));
					TRectype& rigord = righedoc.curr();
					rigord.put(RDOC_PROVV, 'D');
					rigord.put(RDOC_ANNO, dataord.year());
					rigord.put(RDOC_CODNUM, mask.get(F_CODNUM));
					rigord.put(RDOC_NDOC, ndoc);
					rigord.put(RDOC_NRIGA, nriga);
					int err = righedoc.read(_isequal, _lock);
					if (err == NOERR)
					{
						d->copy_data(rdoc, rigord);
						rdoc.put(rdoc.field_qta(), qta);
						rigord.add(rdoc.field_qtaevasa(), qta);
						if (rigord.get_real(rdoc.field_qtaevasa()) >= rigord.get_real(rdoc.field_qta()))
							rigord.put(RDOC_RIGAEVASA, true);
						rdoc.put(RDOC_DACODNUM, rigord.get(RDOC_CODNUM));
						rdoc.put(RDOC_DAANNO, rigord.get(RDOC_ANNO));
						rdoc.put(RDOC_DAPROVV, rigord.get(RDOC_PROVV));
						rdoc.put(RDOC_DANDOC, rigord.get(RDOC_NDOC));
						rdoc.put(RDOC_DAIDRIGA, rigord.get(RDOC_NRIGA));
						err = righedoc.rewrite();
						if (err == NOERR)
							aggiorna_stato_doc_orig(rigord);
	
					}
					if (err != NOERR)
						error_box(FR("Impossibile aggiornare la riga %d del doc. %ld"), nriga, ndoc);
				}
			}
		}
  }
	
  if (orders.items() > 0)
  {
    TProgind pi(orders.items(), TR("Registrazione documenti di carico"), true, true);
    TString cmdline;
    int cnt = 0;
    TString8 key;
    long mindoc = 0, maxdoc = 0;
	  for (long cod = minforn; cod <= maxforn; cod++)
	  {
		  key.format("%ld", cod);
		  TDocumento* d = (TDocumento*)orders.objptr(key);
		  if (d != NULL)
		  {
        if (!pi.addstatus(1))
          break;
			  if (d->write() == NOERR)
        {
					if (cmdline.blank())
					{
						const TTipo_documento& tipo = d->tipo();
						TFilename rep;
            tipo.main_print_profile(rep, 1);
							
						rep.ext("rep");
  
					  if (rep.custom_path())     // Esiste il nuovo report :-)
							cmdline = "ve1 -2";
					  else                       // Esiste il vecchio form :-(
							cmdline = "ve1 -0";
					}
			    cnt++;
          const long ndoc = d->get_long(DOC_NDOC);
          if (mindoc <= 0 || ndoc < mindoc)
            mindoc = ndoc;
          if (ndoc > maxdoc)
            maxdoc = ndoc;
        }
		  }
	  }
    if (yesno_box(TR("Sono stati generati %d documenti:\nSi desidera stamparli ora?"), cnt))
    {
  	  const TString& codnum = mask.get(F_CODNUM);
      const TDate datadoc(TODAY);
      const int anno = datadoc.year();
      cmdline << " " << codnum << ' ' << anno << " D " << mindoc << ' ' << maxdoc;
      TExternal_app prg(cmdline);
      prg.run(true, true, false);
    }
  }
}

void TCreazione_ordini::generate_orders()
{
  TGenera_ordini_mask& mask = *_mask;
	TSheet_field& sf = mask.sfield(F_ARTICLES);

  long minforn = 999999L;
	long maxforn = 0L;
  TAssoc_array orders;

  if (sf.items() > 0)
  {
	  const TDate datadoc = mask.get_date(F_DATADOC);
	  const TString& codnum = mask.get(F_CODNUM);
	  const TString& tipodoc = mask.get(F_TIPODOC);
	  const TTipo_documento tipo(tipodoc);

    const bool ultimo_prezzo = mask.get(F_PREZZO) == "U";
	  const TString& commessat = mask.get(F_CDCT);
	  const TString& faset     = mask.get(F_FSCT);
	  
    TString8 codmag(mask.get(F_MAG));
	  codmag.right_just(3);
	  codmag << mask.get(F_DEP);

    TString8 codmagc(mask.get(F_MAGC));
	  codmagc.right_just(3);
	  codmagc << mask.get(F_DEPC);

    TProgind pi(sf.items(), TR("Generazione ordini"), true, true);
    FOR_EACH_SHEET_ROW(sf, n, row)
    {
      if (!pi.setstatus(n))
        break;
		  
      const real qta = row->get(sf.cid2index(F_QTA));
		  if (!qta.is_zero())
		  {
			  const TString8 codforn(row->get(sf.cid2index(F_FORNITORE)));
			  const long cod = atol(codforn);
			  TString8 key; key.format("F|%ld", cod);
			  const TRectype& forn = cache().get(LF_CLIFO, key);
 			  const TDate datacons(row->get(sf.cid2index(F_DATACONS)));
			  const TString4 codval(forn.get(CLI_CODVAL));
			  const TRectype& forven = cache().get(LF_CFVEN, key);
			  const TString4 codiva(forven.get(CFV_ASSFIS));
			  const TString commessa = row->get(sf.cid2index(F_CDC));
			  const TString fase = row->get(sf.cid2index(F_FSC));

			  TDocumento* d = (TDocumento*)orders.objptr(codforn);
			  if (d == NULL)
			  {
				  d = new TDocumento('D', datadoc.year(), codnum, 0L);
				  d->put(DOC_TIPODOC, tipodoc);
				  d->put(DOC_TIPOCF, "F");
				  d->put(DOC_CODCF, codforn);
				  d->put(DOC_DATADOC, datadoc);
				  d->put(DOC_DATACONS, datacons);
				  d->put(DOC_CODVAL, codval);
				  d->put(DOC_CODLIN, forn.get(CLI_CODLIN));
				  d->put(DOC_CODPAG, forn.get(CLI_CODPAG));
				  d->put(DOC_CODABIA, forn.get(CLI_CODABI));
				  d->put(DOC_CODCABA, forn.get(CLI_CODCAB));
				  d->put(DOC_IBAN, forn.get(CLI_IBAN));
				  d->put(DOC_CODABIP, forven.get(CFV_CODABIPR));
				  d->put(DOC_CODCABP, forven.get(CFV_CODCABPR));
				  d->put(DOC_RAGGR, forven.get(CFV_RAGGDOC));
				  d->put(DOC_RAGGREFF, forven.get(CFV_RAGGEFF));
				  d->put(DOC_CODINDSP, forven.get(CFV_CODINDSP));
				  d->put(DOC_CODAG, forven.get(CFV_CODAG));
				  d->put(DOC_ZONA, forven.get(CFV_CODZONA));
				  d->put(DOC_CODSPMEZZO, forven.get(CFV_CODSPMEZZO));
				  d->put(DOC_CODPORTO, forven.get(CFV_CODPORTO));
				  d->put(DOC_CODNOTESP1, forven.get(CFV_CODNOTESP1));
				  d->put(DOC_CODNOTESP2, forven.get(CFV_CODNOTESP2));
				  d->put(DOC_CODNOTE, forven.get(CFV_CODNOTE));
				  d->put(DOC_CODVETT1, forven.get(CFV_CODVETT1));
				  d->put(DOC_CODVETT2, forven.get(CFV_CODVETT2));
				  d->put(DOC_CODVETT3, forven.get(CFV_CODVETT3));
				  d->put(DOC_PERCSPINC, forven.get(CFV_PERCSPINC));  
				  d->put(DOC_ADDBOLLI, forven.get(CFV_ADDBOLLI));
				  d->put(DOC_CATVEN, forven.get(CFV_CATVEN));
				  d->put(DOC_CODLIST, forven.get(CFV_CODLIST));
				  d->put(DOC_CODCMS, commessat);
				  d->put(DOC_NOTE, mask.get(F_NOTE));

          const TString& causmag = tipo.caus_mov();
				  d->put(DOC_CAUSMAG, causmag);
				  
          orders.add(codforn, d);
				  if (cod < minforn)
					  minforn = cod;
				  if (cod > maxforn)
					  maxforn = cod;
			  }

			  TRiga_documento& rdoc = d->new_row("01");
			  const TString codart(row->get(sf.cid2index(F_CODART)));
			  
			  rdoc.put(RDOC_CODMAG, codmag);
			  rdoc.put(RDOC_CODMAGC, codmagc);
			  rdoc.put(RDOC_CODART, codart);
			  rdoc.put(RDOC_CODARTMAG, codart);
			  rdoc.put(RDOC_CHECKED, "X");
			  rdoc.put(RDOC_DESCR, row->get(sf.cid2index(F_DESCR)));

			  const TString descr_agg(row->get(sf.cid2index(F_DESCRAGG)));
			  if (descr_agg.full())
			  {
				  rdoc.put(RDOC_DESCLUNGA, "X");
				  rdoc.put(RDOC_DESCEST, descr_agg);
			  }

        rdoc.put(RDOC_UMQTA, row->get(sf.cid2index(F_UM)));
			  rdoc.put(RDOC_QTA, qta);
			  rdoc.put(RDOC_DATACONS, datacons);
			  
        const TRectype& articolo = cache().get(LF_ANAMAG, codart);
			  TPrice prezzo;
			  if (ultimo_prezzo)
				  prezzo = articolo.get_real(ANAMAG_ULTCOS1);
			  else
				  prezzo = articolo.get_real(ANAMAG_COSTSTD);
			  prezzo.change_value(codval);
			  rdoc.put(RDOC_PREZZO, prezzo.get_num());
			  if (codiva.full())
				  rdoc.put(RDOC_CODIVA, codiva);
			  else
				  rdoc.put(RDOC_CODIVA, articolo.get(ANAMAG_CODIVA));
			  rdoc.put(RDOC_CODCMS, commessa);
			  rdoc.put(RDOC_FASCMS, fase);
			  
        for (int i = 0; i < 10 ; i++)
				  if (_userfld.row(i).full())
					  rdoc.put(_userfld.row(i), mask.get(F_USER1 + i));

			  rdoc.put(RDOC_CODAGG1, row->get(sf.cid2index(F_CODAGG1)));
			  rdoc.put(RDOC_CODAGG2, row->get(sf.cid2index(F_CODAGG2)));
		  }
	  }
  }
	
  if (orders.items() > 0)
  {
    TProgind pi(orders.items(), TR("Registrazione ordini"), true, true);
    TString cmdline;
    int cnt = 0;
    TString8 key;
    long mindoc = 0, maxdoc = 0;
	  for (long cod = minforn; cod <= maxforn; cod++)
	  {
		  key.format("%ld", cod);
		  TDocumento* d = (TDocumento*)orders.objptr(key);
		  if (d != NULL)
		  {
        if (!pi.addstatus(1))
          break;
			  if (d->write() == NOERR)
        {
					if (cmdline.blank())
					{
						const TTipo_documento& tipo = d->tipo();
						TFilename rep;
            tipo.main_print_profile(rep, 0);				
						rep.ext("rep");
  
					  if (rep.custom_path())     // Esiste il nuovo report :-)
							cmdline = "ve1 -2";
					  else                       // Esiste il vecchio form :-(
							cmdline = "ve1 -0";
					}
			    cnt++;
          const long ndoc = d->get_long(DOC_NDOC);
          if (mindoc <= 0 || ndoc < mindoc)
            mindoc = ndoc;
          if (ndoc > maxdoc)
            maxdoc = ndoc;
        }
		  }
	  }
    if (yesno_box(TR("Sono stati generati %d documenti:\nSi desidera stamparli ora?"), cnt))
    {
  	  const TString& codnum = mask.get(F_CODNUM);
      const TDate datadoc(TODAY);
      const int anno = datadoc.year();
      cmdline << " " << codnum << ' ' << anno << " D " << mindoc << ' ' << maxdoc;
      TExternal_app prg(cmdline);
      prg.run(true, true, false);
    }
  }
}

void TCreazione_ordini::main_loop()
{

	KEY tasto = K_ENTER;
	while (tasto == K_ENTER)
		tasto = _mask->run();
}

int ps0430300(int argc, char* argv[])
{
  TCreazione_ordini a;
  a.run(argc,argv,TR("Generazione Ordini a fornitore"));
  return 0;
}