#include <applicat.h>
#include <execp.h>
#include <progind.h>
#include <reputils.h>
#include <tabmod.h>
#include <textset.h>
#include <utility.h>

#include "../ve/velib04.h"

#include "ps0920500a.h"

///////////////////////////////////////////////////////////
// TClosure_set
///////////////////////////////////////////////////////////

class TClosure_set : public TCSV_recordset
{
public:
  TClosure_set(const TFilename& n) : TCSV_recordset("CSV(\"|\")") { load_file(n); }
};

///////////////////////////////////////////////////////////
// TEvasione_mmag
///////////////////////////////////////////////////////////

class TEvasione_mmag : public TConsegna_ordini
{
  TLog_report* m_log;
  
  TString m_codart;
  int m_idriga;
  int m_qty;
  bool m_saldo;
  int m_scelta, m_lotto, m_pallet, m_spezzoni;

protected:
  virtual bool run_consegna_mask(TMask& cm);
  virtual void post_process(TLista_documenti& doc_out, TLista_documenti& doc_in);

public:
  bool get_choice_desc(long codcf, int s, TString& scelta, TString& tono) const;
  bool evade(int scelta, const TString& codart, int idriga, int qty, bool sld, int lotto, int pall, int spez);
  TEvasione_mmag(const char* codelab, TLog_report& log) : TConsegna_ordini(codelab), m_log(&log) {}
};

bool TEvasione_mmag::evade(int scelta, const TString& codart, int idriga, int qty, bool sld, int lotto, int pall, int spez)
{
  const bool good = (qty > 0 || sld) && idriga > 0 && codart.full();
  if (good)
  {
    m_scelta = scelta;
    m_codart = codart;
    m_idriga = idriga;
    m_qty = qty;
    m_saldo = sld;
    m_lotto = lotto; 
    m_pallet = pall;
    m_spezzoni = spez;
  }
  return good;
}

bool TEvasione_mmag::run_consegna_mask(TMask& cm)
{
  TSheet_field* sheet = NULL;
  for (int i = cm.fields()-1; i > 0; i--)
  {
    const TMask_field& f = cm.fld(i);
    if (f.is_sheet())
    {
      sheet = (TSheet_field*)&f;
      break;
    }
  }
  if (sheet == NULL)
  {
    TString msg;
    msg.format(FR("Maschera di consegna %s priva di spreadsheet"), (const char*)cm.source_file());
    m_log->log(2, msg);
    return false;
  }

  bool found = false;
  FOR_EACH_SHEET_ROW(*sheet, s, sow)
  {
    const char* art = sow->get(6);
    const int idr = sow->get_int(15);
    found = m_codart == art && m_idriga == idr;
    if (found)
    {
      if (sow->get_char(0) <= ' ') 
        sow->add("X", 0);
      if (m_qty > 0) 
      {
        const int residuo = sow->get_int(1);
        const int qta = sow->get_int(2) + m_qty;
        sow->add(qta, 2);
        if (qta >= residuo)
          m_saldo = true;
      }
      if (m_saldo) 
        sow->add("X", 3);
      break;
    }
  }
  
  if (!found)
  {
    TString msg;
    msg.format(FR("Impossibile trovare l'articolo %s sulla riga %d dell'ordine"), 
                (const char*)m_codart, m_idriga);
    m_log->log(1, msg);
  }

  return found;
}

bool TEvasione_mmag::get_choice_desc(long codcf, int s, TString& scelta, TString& tono) const
{
  TString8 key; key.format("%06ld", codcf);
  const TRectype& rec = cache().get("&PS0920SCE", key);
  
  if (s < 2)
  {
    scelta = rec.get("S1"); 
    if (scelta.blank())
      scelta = "1";
    tono.cut(0);
  }
  else
  {
    scelta = rec.get("S2"); 
    if (scelta.blank())
      scelta = "2";
    tono = rec.get("S4");
  }
  
  return !rec.empty();
}

void TEvasione_mmag::post_process(TLista_documenti& doc_out, TLista_documenti& /*doc_in*/)
{
  for (int d = 0; d < doc_out.items(); d++)
  {
    TDocumento& mmag = doc_out[d];
    const long codcf = mmag.get_long(DOC_CODCF);
    TString8 scelta, tono;
    get_choice_desc(codcf, m_scelta, scelta, tono);

    FOR_EACH_PHYSICAL_RDOC(mmag, r, row)
    {
      TRiga_documento& riga = *row;
      if (riga.is_articolo() && riga.get_int(RDOC_QTAGG5) == 0) // Riga articolo non post-processata
      {
        int np = m_pallet;
        if (m_spezzoni > 0)
          np++;
        riga.add(RDOC_IMPFISSO, np);
        riga.put(RDOC_ASPBENI, scelta);
        riga.put(RDOC_QTAGG4, m_lotto);
        if (m_scelta > 1 && tono.full()) // Forzatura tono d'uscita
          riga.put(RDOC_CODAGG2, tono); 
  
        riga.put(RDOC_QTAGG5, 1);  // Segna riga come post-processata
      }
    }

    bool joined = true;
    while (joined)
    {
      joined = false;
      int nlast = mmag.rows();
      while (nlast > 1 && !mmag[nlast].is_articolo())
        nlast--;
      const TRiga_documento& r2 = mmag[nlast];
      for (int i = nlast-1; i > 0; i--)
      {
        TRiga_documento& r1 = mmag[i];
        if (r1.get(RDOC_CODART)  == r2.get(RDOC_CODART) && 
            r1.get(RDOC_ASPBENI) == r2.get(RDOC_ASPBENI) &&
            r1.get(RDOC_DAANNO)  == r2.get(RDOC_DAANNO) &&
            r1.get(RDOC_DACODNUM)== r2.get(RDOC_DACODNUM) &&
            r1.get(RDOC_DANDOC)  == r2.get(RDOC_DANDOC) &&
            r1.get(RDOC_DAIDRIGA)== r2.get(RDOC_DAIDRIGA))
        {
          r1.add(RDOC_QTA,      r2.get_real(RDOC_QTA));
          r1.add(RDOC_NCOLLI,   r2.get_real(RDOC_NCOLLI));
          r1.add(RDOC_IMPFISSO, r2.get_real(RDOC_IMPFISSO));
          r1.add(RDOC_PNETTO,   r2.get_real(RDOC_PNETTO));
          joined = mmag.destroy_row(nlast, true);
          break;
        } 
      }
    }
  }
}

///////////////////////////////////////////////////////////
// TClosure_msk
///////////////////////////////////////////////////////////

class TClosure_msk : public TAutomask
{
  bool _dirty;

protected:
  virtual bool on_field_event(TOperable_field& o, TField_event e , long jolly);

  const TRectype& get_doc(TToken_string& key, TLog_report& log) const;
  bool test_row(const TClosure_set& recset, TLog_report& log) const;
  bool check_file(TClosure_set& recset) const;
  bool import_file(TClosure_set& recset);
  bool evadi_ordine(TEvasione_mmag& jail, TToken_string& row, 
                    TLista_documenti& doc_in, TLista_documenti& doc_out, 
                    TLog_report& log);
  bool elabora(TString_array& records, TLog_report& log);
  bool chiudi_righe(TString_array& records, TLog_report& log);

public:
  void load_sheet();
  bool seleziona();
  bool cancella();
  bool salva();
  bool elabora();
  TClosure_msk() : TAutomask("ps0920500a") {}
};

const TRectype& TClosure_msk::get_doc(TToken_string& rdoc, TLog_report& log) const
{
  TToken_string key;
  key = "D";
  key.add(rdoc.get(1));
  key.add(rdoc.get(0));
  key.add(rdoc.get(2));
  const TRectype& doc = cache().get(LF_DOC, key);
  
  TString msg; msg << rdoc << " : ";

  bool is_bad = doc.empty();

  if (is_bad)
  {
    msg << "Documento inesistente";
  }
  else
  {
    is_bad = doc.get_bool(DOC_DOCEVASO);
    if (is_bad)
      msg << TR("Ordine gi� evaso");
  }

  if (is_bad)
  {
    log.log(2, msg);
    return cache().get(LF_DOC, "");
  }
  else
  {
    msg << "OK";
    log.log(0, msg);
  }

  return doc;
}

bool TClosure_msk::test_row(const TClosure_set& recset, TLog_report& log) const
{
  TToken_string rdoc(recset.get(0).as_string(), '.');

  TString msg; msg << rdoc << " : ";
  TToken_string rkey = recset.get(1).as_string();
  const TRectype& anamag = cache().get(LF_ANAMAG, rkey);
  bool is_bad = anamag.empty();
  if (is_bad)
    msg << TR("Codice articolo non valido ") << rkey;
  else
  {
    const int ppp = anamag.get_int(ANAMAG_PPCOLLO) * anamag.get_int(ANAMAG_USER1) * anamag.get_int(ANAMAG_USER2);
    is_bad = ppp <= 0;
    if (is_bad)
      msg << TR("Articolo senza informazioni di palettizzazione ") << rkey;
    else
    {
      const long codcf = atol(rkey.left(3));
      rkey.format("C|%d", codcf);
      is_bad = cache().get(LF_CLIFO, rkey).empty();
      if (is_bad)
        msg << TR("Codice cliente non valido ") << codcf;
    }
  }

  if (!is_bad) // Se buono allora controllo anche evasione della riga ordine
  {
    const int idriga = rdoc.get_int(3);
    // Chiave per righe documento con campi in ordine demenziale 
    rkey = rdoc.get(0); rkey.add(rdoc.get(1));
    rkey.add("D");      rkey.add(rdoc.get(2));
    TRecord_array righe(rkey, LF_RIGHEDOC);
    for (int r = righe.rows(); r > 0; r = righe.pred_row(r))
    {
      const TRectype& riga = righe.row(r);
      if (riga.get_int(RDOC_IDRIGA) == idriga)
      {
        if (riga.get_bool(RDOC_RIGAEVASA))
        {
          msg << TR("Riga gi� evasa: ") << riga.get(RDOC_CODART);
          is_bad = true;
        }
        break;
      }
    }
  }

  if (is_bad)
    log.log(2, msg);

  return !is_bad;
}

bool TClosure_msk::check_file(TClosure_set& recset) const
{
  TLog_report log;
  int errors = 0;
  TToken_string rdoc("", '.');

  for (bool ok = recset.move_first(); ok; ok = recset.move_next())
  {
    rdoc = recset.get(0).as_string(); // NUM.YYYY.NDOC.NRIGA
    if (rdoc.blank())
      break;

    const TRectype& doc = get_doc(rdoc, log);
    if (doc.empty() || !test_row(recset, log))
      errors++;
  }

  if (errors > 0)
    log.preview();

  return errors == 0;
}

bool TClosure_msk::import_file(TClosure_set& recset)
{
  TLog_report log;
  TRecnotype r = 0;

  TModule_table mag("&PS0920MAG");
  long idrec = 1;
  if (mag.last() == NOERR)
    idrec += atol(mag.get("CODTAB"));

  TProgind pi(recset.items(), main_app().title());
  TToken_string rdoc(31, '.');
  TString16 str;
  TString key; 

  for (bool ok = recset.move_first(); ok; ok = recset.move_next())
  {
    if (!pi.addstatus(1))
      break;

    rdoc = recset.get(0).as_string(); // NUM.YYYY.NDOC.NRIGA
    if (rdoc.blank())
      break;

    const TRectype& doc = get_doc(rdoc, log);
    if (doc.empty() || !test_row(recset, log))
      continue;

    const int indsped = doc.get_int(DOC_CODINDSP);

    mag.zero();
    str.format("%010ld", idrec++);
    mag.put("CODTAB", str);

    // Riformatta il numero documento
    str = rdoc.get(2); str.right_just(7, '0');
    rdoc.add(str, 2);
    // Riformatta il numero riga
    str = rdoc.get(3); str.right_just(4, '0');
    rdoc.add(str, 3);

    // Inserisco l'indirizzo di spedizione
    str.format("%03d", indsped);
    rdoc.insert(".");
    rdoc.insert(str);

    // Inserisco il codice cliente davanti
    key = recset.get(1).as_string(); // CODART
    str = key.left(3);
    rdoc.insert(".");
    rdoc.insert(str);

    mag.put("S0", rdoc);
    mag.put("S1", key);                       // Articolo
    mag.put("I0", str);                       // Cliente
    mag.put("I1", recset.get(2).as_int());    // Palette di prima
    mag.put("I2", recset.get(3).as_int());    // Spezzoni di prima
    mag.put("I3", recset.get(4).as_int());    // Palette di seconda
    mag.put("I4", recset.get(5).as_int());    // Spezzoni di seconda
    mag.put("B0", recset.get(6).as_string() > " ");   // Saldo
    mag.put("B1", false);                     // Riga evasa
    mag.put("D1", 0L);                        // Data evasione
    mag.put("S6", recset.get(7).as_string()); // Lotto

    TDate ril(TODAY);
    str = recset.get(8).as_string().left(10);
    if (TDate::isdate(str))
      ril = TDate(str);
    mag.put("D0", ril); // Data rilevazione

    const int err = mag.write();
    if (err != NOERR)
    {
      TString msg; msg << rdoc << " : ";
      msg << TR("Impossibile registrare la riga: errore ") << err;
      log.log(2, msg);
      break;
    }
    else
      r++;
  }

  TString msg;
  msg << "Sono stati importati " << r << " record";
  log.log(0, "");
  log.log(0, msg);

  log.preview();

  return r > 0;
}

void TClosure_msk::load_sheet()
{
  TSheet_field& s = sfield(F_SHEET);
  s.hide();
  s.destroy();
  
  TRelation r("&PS0920MAG");

  TString filter;
  filter = "(B1!=\"X\")";
  if (get_bool(F_SHOWALL))
  {
    const TDate datadoc = get(F_DATADOC);
    const TDate datapre = datadoc-15L;
    filter << "||(BETWEEN(D0," << datapre.date2ansi() << ',' << datadoc.date2ansi() << "))";
  }

  TCursor c(&r, filter, 2);
  const TRecnotype n = c.items();
  c.freeze();
  const TRectype& rec = c.curr();

  TToken_string rif("", '.');

  for (c = 0; c.pos() < n; ++c)
  {
    rif = rec.get("S0");
    if (rif.full())
    {
      TToken_string& row = s.row(-1);
      row = " ";
      FOR_EACH_TOKEN(rif, tok)
        row.add(tok);

      row.add(rec.get("S1"),     s.cid2index(F_CODART));
      row.add(rec.get("I1"),     s.cid2index(F_PALET1));
      row.add(rec.get("I2"),     s.cid2index(F_SPEZZ1));
      row.add(rec.get("I3"),     s.cid2index(F_PALET2));
      row.add(rec.get("I4"),     s.cid2index(F_SPEZZ2));
      row.add(rec.get("B0"),     s.cid2index(F_SALDO));
      row.add(rec.get("S6"),     s.cid2index(F_LOTTO));
      row.add(rec.get("D0"),     s.cid2index(F_DATA));
      row.add(rec.get("B1"),     s.cid2index(F_EVASA));
      row.add(rec.get("D1"),     s.cid2index(F_DATEVAS));
      row.add(rec.get("CODTAB"), s.cid2index(F_RECORD));

      s.check_row(s.items()-1, 0x3); // Do outputs and checks
    }
  }

  const bool e = !s.empty();
  enable(DLG_DELREC,  e);
  enable(DLG_RECALC,  e);
  enable(DLG_ELABORA, e);
  enable(DLG_SAVEREC, _dirty = false);

  s.show();
  s.force_update();
}

bool TClosure_msk::chiudi_righe(TString_array& records, TLog_report& log)
{
  const TDate datadoc = get(F_DATADOC);
  int err = NOERR;
  TLocalisamfile mmag(LF_TABMOD);
  FOR_EACH_ARRAY_ROW(records, r, row) if (row->get_char(0) > ' ' && row->get_char(F_EVASA-101) > ' ')
  {
    const TString16 rec = row->get(F_RECORD-101);
    mmag.put("MOD",  "PS");
    mmag.put("CUST", 920);
    mmag.put("COD",  "MAG");
    mmag.put("CODTAB", rec);
    err = mmag.read(_isequal, _lock);
    if (err == NOERR)
    {
      mmag.put("B1", true);
      mmag.put("D1", datadoc);
      err = mmag.rewrite();
    }
    if (err != NOERR)
    {
      TString msg; 
      msg.format(FR("Errore %d in aggiornamento record %s"), err, (const char*)rec);
      log.log(2, msg);
      break;
    }
  }
  return err == NOERR;
}

bool TClosure_msk::evadi_ordine(TEvasione_mmag& jail, TToken_string& row, TLista_documenti& doc_in, TLista_documenti& doc_out, TLog_report& log)
{
  for (int scelta = 1; scelta <= 2; scelta++)
  {
    const int pall  = row.get_int((scelta == 1 ? F_PALET1 : F_PALET2) - 101);
    const int spez  = row.get_int((scelta == 1 ? F_SPEZZ1 : F_SPEZZ2) - 101);
    const int pezzi = row.get_int((scelta == 1 ? F_PEZZ1  : F_PEZZ2 ) - 101);
    bool sld  = false;
    if (row.get_char(F_SALDO - 101) > ' ')
    {
      if (scelta == 1)
        sld = row.get_int(F_PEZZ2 - 101) <= 0;
      else
        sld = pezzi > 0;
    }
    if (pezzi > 0 || sld)
    {
      const TString codart = row.get(F_CODART - 101);
      const long codcf = atol(codart.left(3));
      const int idriga = row.get_int(F_IDRIGA - 101);
      const int lotto = row.get_long(F_LOTTO  - 101);
      jail.evade(scelta, codart, idriga, pezzi, sld, lotto, pall, spez);

      TString8 s, t;
      jail.get_choice_desc(codcf, scelta, s, t);
      TString msg; 
      msg << TR("Elaborazione scelta ") << s << ' ' << t;
      log.log(0, msg);
      const bool good = jail.elabora(doc_in, doc_out, get_date(F_DATADOC));
      if (good)
      {
        row.add("X", F_EVASA-101);
      }
      else
      {
        log.log(2, TR("Elaborazione annullata"));
        return false;
      }
    }
  }
  return true;
}

bool TClosure_msk::elabora(TString_array& records, TLog_report& log)
{
  if (records.empty())
    return false;

  TEvasione_mmag jail(get(F_CODELAB), log);

  TLista_documenti doc_in, doc_out;

  const TDate data_doc = get(F_DATADOC);
  const int annof = data_doc.year();
  const TString4 codnumf = jail.codice_numerazione_finale();

  const long codcf = records.row(0).get_long(1);
  const int indsped = records.row(0).get_int(2);
  TDocumento* mmag = NULL;
  FOR_EACH_ARRAY_ROW(records, r, row)
  {
    const char provv      = 'D';
    const int anno        = row->get_int (F_ANNO  -101);
    const TString4 codnum = row->get     (F_CODNUM-101);
    const long ndoc       = row->get_long(F_NDOC  -101);
    if (!doc_in.find(provv, anno, codnum, ndoc))
    {
      if (mmag != NULL && doc_in.items())
      {
        doc_in.rewrite();
        doc_in.destroy(-1);
      }

      TString msg; msg << TR("Caricamento ordine ") << anno << '/' << codnum << '/' << ndoc;
      log.log(0, msg);

      TDocumento* orc = new TDocumento(provv, anno, codnum, ndoc);
      doc_in.add(orc);

      if (mmag == NULL)
      {
        msg.cut(0) << TR("Creazione nuovo documento ") << annof << '/' << codnumf;
        log.log(0, msg);
        
        mmag = new TDocumento('D', annof, codnumf, 0L);
        mmag->put(DOC_TIPODOC, jail.tipo_finale());
        mmag->put(DOC_STATO, jail.stato_finale());
        mmag->put(DOC_DATADOC, data_doc);
        mmag->put(DOC_TIPOCF, 'C');
        mmag->put(DOC_CODCF, codcf);
        mmag->put(DOC_CODINDSP, indsped);

        mmag->copy_data(mmag->head(), orc->head());
        mmag->put(DOC_TIPODOC, jail.tipo_finale());
        mmag->put(DOC_STATO,   jail.stato_finale());
        mmag->put(DOC_DATADOC, data_doc);
        mmag->put(DOC_CAUSMAG, mmag->tipo().caus_mov());

        doc_out.add(mmag);
      }
    }
    evadi_ordine(jail, *row, doc_in, doc_out, log);
  }
  if (mmag != NULL && doc_in.items())
  {
    doc_in.rewrite();
    doc_in.destroy(-1);
  }

  int err = doc_out.write();
  if (err == NOERR)
  {
    chiudi_righe(records, log);
  }
  else
  {
    TString80 msg;
    msg << TR("Impossibile registrare il documento ") << annof << '/' << codnumf << '/' << mmag->get(DOC_NDOC);
    log.log(2, msg);
  }

  return err == NOERR;
}

bool TClosure_msk::elabora()
{
  TRecnotype c = 0;

  TSheet_field&s = sfield(F_SHEET);
  FOR_EACH_SHEET_ROW(s, r1, row1)
    c += row1->get_char(0) > ' '; 

  if (c == 0 || !yesno_box(FR("Confermare l'elaborazione di %ld righe"), c))
    return false;

  TLog_report log;

  TString_array records;
  long last_cf = 0;
  int last_ind = 0;

  FOR_EACH_SHEET_ROW(s, r, row) if (row->get_char(0) > ' ')
  {
    const long codcf   = row->get_long(s.cid2index(F_CLIFO));
    const int  indsped = row->get_int(s.cid2index(F_INDSPED));
    if (codcf != last_cf || indsped != last_ind)
    {
      elabora(records, log);
      last_cf = codcf;
      last_ind = indsped;
      records.destroy();
    }
    records.add(*row); // Attenzione: NON records.add(row)
  }
  elabora(records, log);

  log.preview();

  return true;
}

bool TClosure_msk::seleziona()
{
  bool one_checked = false;
  
  TSheet_field&s = sfield(F_SHEET);
  FOR_EACH_SHEET_ROW(s, r1, row1)
  {
    if (row1->get_char(0) > ' ')
    {
      one_checked = true;
      break;
    }
  }
  FOR_EACH_SHEET_ROW(s, r2, row2)
    row2->add(one_checked ? " " : "X", 0);
  s.force_update();

  return !one_checked;
}

bool TClosure_msk::cancella()
{
  int err = NOERR;
  
  TSheet_field&s = sfield(F_SHEET);

  // Conta reord selezionati
  TRecnotype k = 0;
  FOR_EACH_SHEET_ROW(s, r1, row1)
    k += row1->starts_with("X");

  // Elminazione su richiesta
  if (k > 0 && noyes_box(FR("Confermare l'eliminazione di %ld record?"), k))
  {
    const int nRec = s.cid2index(F_RECORD);
    TLocalisamfile mmag(LF_TABMOD);
    TString16 n;
    FOR_EACH_SHEET_ROW(s, r2, row2) if (row2->starts_with("X"))
    {
      n.format("%010ld", row2->get_long(nRec));
      mmag.put("MOD",  "PS");
      mmag.put("CUST", 920);
      mmag.put("COD",  "MAG");
      mmag.put("CODTAB", n);
      err = mmag.remove();
      if (err != NOERR)
      {
        error_box(FR("Errore %d durante la cancellazione del record %ld"), err, atol(n));
        break;
      }
    }
    load_sheet();
  }
  return err == NOERR;
}

bool TClosure_msk::salva()
{
  int err = NOERR;
  
  TSheet_field&s = sfield(F_SHEET);

  const int nRec = s.cid2index(F_RECORD);
  const int nPa1 = s.cid2index(F_PALET1);
  const int nSp1 = s.cid2index(F_SPEZZ1);
  const int nPa2 = s.cid2index(F_PALET2);
  const int nSp2 = s.cid2index(F_SPEZZ2);
  const int nSld = s.cid2index(F_SALDO);
  const int nLot = s.cid2index(F_LOTTO);
  
  TLocalisamfile mmag(LF_TABMOD);
  TString16 n;
  FOR_EACH_SHEET_ROW(s, r, row)
  {
    n.format("%010ld", row->get_long(nRec));
    mmag.put("MOD",  "PS");
    mmag.put("CUST", 920);
    mmag.put("COD",  "MAG");
    mmag.put("CODTAB", n);
    err = mmag.read(_isequal, _lock);
    if (err == NOERR)
    {
      mmag.put("I1", row->get(nPa1));
      mmag.put("I2", row->get(nSp1));
      mmag.put("I3", row->get(nPa2));
      mmag.put("I4", row->get(nSp2));
      mmag.put("B0", row->get(nSld));
      mmag.put("S6", row->get(nLot));
      err = mmag.rewrite();
    }
    if (err != NOERR)
    {
      error_box(FR("Errore %d durante l'aggiornamento del record %ld"), err, atol(n));
      break;
    }
  }

  if (err == NOERR)
    enable(DLG_SAVEREC, _dirty = false);

  return err == NOERR;
}

bool TClosure_msk::on_field_event(TOperable_field& o, TField_event e , long jolly)
{
  switch (o.dlg())
  {
  case DLG_IMPORT:
    if (e == fe_button)
    {
      TFilename file = get(F_PATH); 
      file.add("*.dat");
      if (!input_filename(file))
        return false;
      TClosure_set recset(file);
      const TRecnotype n = recset.items();
      if (n > 0) // Prima valutazione del numero di elementi
      {
        // Controllo degli ordini validi
        if (!check_file(recset) && !noyes_box(TR("Si desidera proseguire nonostante i problemi rilevati?"))) 
          return false;

        if (!yesno_box(FR("Confermare la lettura di %ld righe"), n))
          return false;

        if (import_file(recset))
        {
          save_profile();
          if (yesno_box(FR("Si desidera eliminare il file %s"), (const char*)file))
            file.fremove();
        }
        load_sheet();
      }
      else
        cantread_box(file);
    }
    break;
  case F_SHOWALL:
    if (e == fe_modify)
      load_sheet();
    break;
  case DLG_RECALC:
    if (e == fe_button)
      seleziona();
    break;
  case DLG_DELREC:
    if (e == fe_button)
    {
      cancella();
      return false; // Altrimenti esce dalla maschera
    }
    break;
  case DLG_SAVEREC:
    if (e == fe_button)
    {
      salva();
      return false; // Altrimenti esce dalla maschera
    }
    break;
  case DLG_ELABORA:
    if (e == fe_button)
    {
      elabora();
      load_sheet();
    }
    break;
  case DLG_LINK:
    if (e == fe_button)
    {
      TExternal_app app("ps0920 -5 &PS0920SCE");
      app.run();
    }
    break;
  case F_CODELAB:
  case F_DATADOC:
  case F_SHEET:
    if (e == fe_init || e == fe_modify)
    {
      short ids[4] = { F_CODELAB, F_DATADOC, F_SHEET, 0 };
      bool one_empty = false;
      for (int i = 0; ids[i]; i++)
        one_empty |= field(ids[i]).empty();
      enable(DLG_ELABORA, !one_empty);
    }
    break;
  case F_PALET1:
  case F_SPEZZ1:
  case F_PALET2:
  case F_SPEZZ2:
    if (e == fe_modify || e == fe_init)
    {
      TMask& sm = o.mask();
      const TRectype& art = cache().get(LF_ANAMAG, sm.get(F_CODART));
      const int pps = art.get_int(ANAMAG_PPCOLLO);                                 // Pezzi per spezzone
      const int ppp = art.get_int(ANAMAG_USER1) * art.get_int(ANAMAG_USER2) * pps; // Pezzi per pallet
      const real peso = art.get(ANAMAG_PESO);
      const int id = o.dlg() < F_PALET2 ? F_PALET1 : F_PALET2;
      sm.set(id+2, sm.get_int(id)*ppp + sm.get_int(id+1)*pps);
      sm.set(id+3, real(peso * sm.get_int(id+2)));

      if (e == fe_modify && !_dirty && is_running())
        enable(DLG_SAVEREC, _dirty = true);
    }
    break;
  case F_SALDO:
  case F_LOTTO:
    if (e == fe_modify && !_dirty && is_running())
      enable(DLG_SAVEREC, _dirty = true);
    break;
  default: break;
  }
  return true;
}

///////////////////////////////////////////////////////////
// TClosure_app
///////////////////////////////////////////////////////////

class TClosure_app : public TSkeleton_application
{
protected:
  virtual bool check_autorization() const   { return false; }
  virtual const char* extra_modules() const { return "ve"; }
  virtual void main_loop();
};

void TClosure_app::main_loop()
{
  open_files(LF_TABCOM, LF_TAB, LF_TABMOD, 
             LF_CLIFO, LF_ANAMAG,
             LF_DOC, LF_RIGHEDOC, 0);
  TClosure_msk m;
  m.load_sheet();
  while (m.run() == K_ENTER);
}

int ps0920500(int argc, char* argv[])
{
  TClosure_app a;
  a.run(argc, argv, TR("Ordini da terminale"));
  return 0;
}