#include <automask.h>
#include <diction.h>
#include <reprint.h>
#include <reputils.h>
#include <utility.h>

#include "velib04.h"
#include "velib04e.h"

#include <doc.h>


class TConsuntivazione_mask : public TAutomask
{
protected:
  void load_sheet();
  virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);

public:
  TConsuntivazione_mask() : TAutomask("velib04e") { }
  virtual ~TConsuntivazione_mask() { }
};

static bool scan_rilprod(const TRelation& rel, void* pJolly)
{
  const TRectype& rec = rel.curr();
  TSheet_field& sheet = *(TSheet_field*)pJolly;
  TToken_string& row = sheet.row(-1);
	TLocalisamfile righe(LF_RRILPROD);
	const TString codart(rec.get(RDOC_CODART));
	const int prog = rec.get_int("PROG");
	const TDate data(rec.get("DATA"));

	righe.put("CODART",   codart);
  righe.put("DATA",     data);
  righe.put("PROG",     prog);
	righe.put("NRIGA",   999);

  int err = righe.read(_isequal, _testandlock);
	if (err == _iskeynotfound)
		righe.prev();
  row.add(codart,   sheet.cid2index(S_CODART));
  row.add(format("%d", prog),     sheet.cid2index(S_PROG));
  row.add(data.string(),          sheet.cid2index(S_DATA));
  row.add(rec.get(RDOC_IMPIANTO), sheet.cid2index(S_IMPIANTO));
  row.add(rec.get(RDOC_LINEA),    sheet.cid2index(S_LINEA));
	if (codart == righe.get("CODART"))
		row.add(righe.get("DATAFINE"), sheet.cid2index(S_DATAPROD));
	row.add(rec.get(RDOC_QTA),      sheet.cid2index(S_QTA));
  row.add(rec.get("CHIUSO"),      sheet.cid2index(S_CHIUSO));

  row.add(rec.get(RDOC_PROVV),    sheet.cid2index(S_PROVV));
  row.add(rec.get(RDOC_ANNO),     sheet.cid2index(S_ANNO));
  row.add(rec.get(RDOC_CODNUM),   sheet.cid2index(S_CODNUM));
  row.add(rec.get(RDOC_NDOC),     sheet.cid2index(S_NDOC));
  row.add(rec.get(RDOC_NRIGA),    sheet.cid2index(S_NRIGA));
  return true;
}

void TConsuntivazione_mask::load_sheet()
{
  TRelation rel(LF_RILPROD);
  TCursor cur(&rel, "CODNUMP==\"\"");

  TSheet_field& sheet = sfield(F_SHEET);
  sheet.destroy();
  cur.scan(scan_rilprod, &sheet);
  sheet.force_update();
}


bool TConsuntivazione_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
  switch (o.dlg())
  {
  case F_SHEET:
    if (e == fe_init)
		{
      load_sheet();
      TSheet_field& s = sfield(F_SHEET);
      FOR_EACH_SHEET_ROW(s, n, row)
      {        
        const real  r(row->get(s.cid2index(S_QTA)));

        if (r <= ZERO)
					s.disable_row(n);
      }
      s.force_update();
		}
    break;
  case DLG_TUTTE:
    if (e == fe_button)
    {
      TSheet_field& s = sfield(F_SHEET);
      FOR_EACH_SHEET_ROW(s, n, row)
      {        
				const int pos = s.cid2index(S_SELECTED);
        const TString16  v(row->get(pos));

        if (s.row_enabled(n))
				{
					if (v.blank())
	          row->add("X", pos);
					else
			      row->add(" ", pos);
				}
      }
      s.force_update();
    }
    break;
  default:
    break;
  }
  return true;
}

bool TConsuntivazione_produzione::ref2doc(char & provv, int & anno, TString8 & codnum, long & ndoc, int & nriga, const TString & codart)
{
	const TString8 ordprod(tipo_iniziale(0));
	bool ok = true;

	if (codnum != ordprod)
	{

		char p = provv;
		int a = anno;
		TString8 c(codnum);
		long nd = ndoc;
		int nr = nriga;
		TLocalisamfile f(LF_RIGHEDOC);
		TRectype & rec = f.curr();

		rec.put(RDOC_DAPROVV, p);
		rec.put(RDOC_DAANNO, a);
		rec.put(RDOC_DACODNUM, c);
		rec.put(RDOC_DANDOC, nd);
		rec.put(RDOC_DAIDRIGA, nr);
		
		TRectype cmp(rec);

		f.setkey(4);
		ok = false;
		for (int err = f.read(_isequal); !ok && rec == cmp && err == NOERR; f.next())
		{
			if (rec.get(RDOC_CODNUM) == ordprod)
				if(rec.get(RDOC_CODARTMAG) == codart)
				{
					provv = rec.get_char(RDOC_PROVV);
					anno = rec.get_int(RDOC_ANNO);
					codnum = rec.get(RDOC_CODNUM);
					ndoc = rec.get_long(RDOC_NDOC);
					nriga = rec.get_int(RDOC_NRIGA);
					ok = true;
				}
		}
	}
	return ok;
}

bool TConsuntivazione_produzione::elabora(TLista_documenti& doc_in, TLista_documenti& doc_out,
                                          const TDate& data_elab, bool interattivo)
{ 
  TConsuntivazione_mask msk;
	TLog_report log("Consuntivazione produzione");
  bool done = false;
  if (msk.run() == K_ENTER)
  {
    TSheet_field& sheet = msk.sfield(F_SHEET);
    TLocalisamfile rilevazioni(LF_RILPROD);
    TRectype& ril = rilevazioni.curr();

		pre_process_input(doc_in);
		if (doc_out.items() == 0)
		{
			TDocumento d('D', data_elab.year(), codice_numerazione_finale(), 0L);
			d.set_tipo(tipo_finale());
			d.stato(stato_finale()[0]);
			d.put(DOC_DATADOC, data_elab);
			d.write();
			TDocumento * d1 = new TDocumento(d.head());
			doc_out.add(d1);
		}

    TDocumento& outdoc = doc_out[0];
	  TDocumento ordine;

    FOR_EACH_SHEET_ROW(sheet, i, row) if (*row->get(0)=='X')  // Per ogni riga selezionata
    {
      const TString codart  = row->get(sheet.cid2index(S_CODART));
      const TDate data      = row->get(sheet.cid2index(S_DATA));
      const int prog        = row->get_int(sheet.cid2index(S_PROG));
      const real qta        = row->get(sheet.cid2index(S_QTA));
      bool chiuso           = row->get(sheet.cid2index(S_CHIUSO))[0] > ' ';
      char provv      = row->get(sheet.cid2index(S_PROVV))[0];
      int anno        = row->get_int(sheet.cid2index(S_ANNO));
      TString8 codnum = row->get(sheet.cid2index(S_CODNUM));
      long ndoc       = row->get_long(sheet.cid2index(S_NDOC));
      int nriga       = row->get_int(sheet.cid2index(S_NRIGA));

			if (ref2doc(provv, anno, codnum, ndoc, nriga, codart))
			{
				int err = ordine.read(provv, anno, codnum, ndoc, _isequal, _testandlock);
				if (err == NOERR)
				{
					if (nriga > 0 && nriga <= ordine.rows())
					{
						TRiga_documento& riga_ordine = ordine[nriga];
						const TString& qta_fld = riga_ordine.field_qta();
						const TString& qte_fld = riga_ordine.field_qtaevasa();

						const real qta_evasa = riga_ordine.qtaevasa() + qta;      
						riga_ordine.put(qte_fld, qta_evasa);
						if (chiuso || riga_ordine.qtaresidua().is_zero())
						{
							riga_ordine.put(RDOC_RIGAEVASA, 'X');
							chiuso = true;
						}

						const TString4 tiporiga = riga_ordine.get(RDOC_TIPORIGA);
						TRiga_documento& outrec = outdoc.new_row(tiporiga);
						TDocumento::copy_data(outrec, riga_ordine);
						outrec.put(qta_fld, qta);
						if (qta_fld != RDOC_QTA) 
						{
							const real q = riga_ordine.get_real(RDOC_QTA);
							if (q.is_zero()) 
								outrec.put(RDOC_QTA, UNO);             // Pezza temporanea
						}
						if (kill_descrizione_estesa())             // Cancello eventualmente la descrizione estesa
						{
							outrec.zero(RDOC_DESCLUNGA);
							outrec.zero(RDOC_DESCEST);
						}
						outrec.dirty_fields();                     // Forza ricalcolo peso etc. 
						outrec.put(RDOC_DATACONS, data);           // Setta la data di consegna con la data di produzione
						outrec.zero(qte_fld);                      // Azzera quantita' evasa erroneamente copiata dall'ordine
						outrec.zero(RDOC_RIGAEVASA);               // Azzera flag di evasa erroneamente copiata dall'ordine
						outrec.set_original_rdoc_key(riga_ordine);
					}
					else
					{
		        const char* msg = TR("Impossibile aggiornare il documento");
				    log.log(1, format("%s %d %s %ld", msg, anno, (const char*)codnum, ndoc));
					}
					if (ordine.is_evaso())
						ordine.stato(stato_finale_doc_iniziale()[0]);
					err = ordine.rewrite();  // Unlocca
		      if (err != NOERR)
				  {
		        const char* msg = TR("Impossibile aggiornare il documento");
				    log.log(1, format("%s %d %s %ld", msg, anno, (const char*)codnum, ndoc));
					}
					done = true;

					ril.put("CODART",   codart);
					ril.put("DATA",     data);
					ril.put("PROG",     prog);
					err = rilevazioni.read(_isequal, _testandlock);
					if (err == NOERR)
					{
						if (chiuso)
							ril.put("CHIUSO", chiuso);
						ril.put("PROVVP",   outdoc.get(DOC_PROVV));
						ril.put("ANNOP",    outdoc.get(DOC_ANNO));
						ril.put("CODNUMP",  outdoc.get(DOC_CODNUM));
						ril.put("NDOCP",    outdoc.get(DOC_NDOC));
						ril.put("NRIGAP",   outdoc.rows());
						err = rilevazioni.rewrite();
					}
					if (err != NOERR)
					{
						const char* msg = TR("Impossibile aggiornare la riga di rilevazione");
						log.log(1, format("%s %s %s %d", msg, (const char*)codart, (const char*)data.string(), prog));
						break;
					}
				}
				else
				{
					const char* msg = TR("Impossibile leggere l'ordine di produzione");
					log.log(1, format("%s %d %s %ld", msg, anno, (const char*)codnum, ndoc));
				}
      }
			else
			{
		    const char* msg = TR("Impossibile trovare l'ordine di produzione relativo all'ordine cliente");
				log.log(1, format("%s %d %s %ld", msg, anno, (const char*)codnum, ndoc));
				ril.put("CODART",   codart);
				ril.put("DATA",     data);
				ril.put("PROG",     prog);
				if (rilevazioni.read(_isequal, _testandlock) == NOERR)
				{
					ril.put("CHIUSO", chiuso);
					ril.put("CODNUMP",  outdoc.get(DOC_CODNUM));
					rilevazioni.rewrite();
				}
			}
    }
  }
	TReport_book book;

	book.add(log);
	book.preview();
	post_process_input(doc_in);
  post_process_output(doc_out);
	return done;
}