Files correlati : Ricompilazione Demo : [ ] Commento : Riportata la versione AGA 1.7 patch 349 git-svn-id: svn://10.65.10.50/trunk@10708 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			470 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			470 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include "mr2200.h"
 | 
						||
#include "mr2200a.h"
 | 
						||
#include "mr2200b.h"
 | 
						||
 | 
						||
void TPlanning_mask::print_exceptions(TExceptions_array &excepts)
 | 
						||
{
 | 
						||
  if (excepts.items())
 | 
						||
  {
 | 
						||
    TPrinter& pr = printer();
 | 
						||
    pr.open();
 | 
						||
  
 | 
						||
    pr.setheaderhandler(print_except_header);
 | 
						||
    pr.headerlen(6);
 | 
						||
    pr.setfooterhandler(print_footer);
 | 
						||
    pr.footerlen(2);
 | 
						||
  
 | 
						||
    TString_array keys;
 | 
						||
    TToken_string key, lastkey;
 | 
						||
    TString tmp;
 | 
						||
    excepts.get_keys(keys);
 | 
						||
    keys.sort();
 | 
						||
    int header=0;
 | 
						||
    for (int k=0; k< keys.items(); k++)
 | 
						||
    {
 | 
						||
      key = keys.row(k);
 | 
						||
      key.get(0,tmp);
 | 
						||
      if (tmp != lastkey.get(0))
 | 
						||
        header = 0;
 | 
						||
      else if (key.get(1,tmp)&& tmp != lastkey.get(1))
 | 
						||
        header = 0;
 | 
						||
      else if (key.get(2,tmp) && tmp != lastkey.get(2))
 | 
						||
        header = 1;
 | 
						||
      else 
 | 
						||
        header = 2;
 | 
						||
      const TException & e = (const TException &)excepts[key];
 | 
						||
      const TMRP_line &line = e.mrpline();
 | 
						||
      line.print_exception(e.from(), e.to(), e.qta(), header);
 | 
						||
      lastkey = key;
 | 
						||
    }
 | 
						||
    pr.close();
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
void TPlanning_mask::print_except_header(TPrinter& pr)
 | 
						||
{
 | 
						||
  TPrintrow row;
 | 
						||
  print_header(pr);
 | 
						||
  row.put("@48G@BSTAMPA TABULATO ECCEZIONI DA M.S.P.");
 | 
						||
  pr.setheaderline(1,row);
 | 
						||
  row.reset();
 | 
						||
  row.put((const char *)TString(131,'-'));
 | 
						||
  pr.setheaderline(4,row);
 | 
						||
}
 | 
						||
 | 
						||
void TPlanning_mask::print_articles(int from_col, int num_cols, const char * row_filter)
 | 
						||
{
 | 
						||
  const char* repname = "mr2200";
 | 
						||
  TSheet_field& sf = sfield(F_ARTICOLI);
 | 
						||
  const int nrows=sf.items();
 | 
						||
 | 
						||
  TIsamtempfile * report = new TIsamtempfile(LF_MRPREPORT,repname, TRUE, TRUE );
 | 
						||
  TString8 codimp,codlin;
 | 
						||
  TProgind pi(nrows, format("Stampa %s...",get_bool(F_MSCHEDULEPLAN)?
 | 
						||
    "Master Schedule Plan":"pianificazione ordini"));
 | 
						||
  
 | 
						||
  const int a_buck0 = sf.cid2index(F_BUCKET0);
 | 
						||
  for (int r=0; r<nrows; r++)
 | 
						||
  {
 | 
						||
    if (pi.iscancelled())
 | 
						||
    {
 | 
						||
      delete report;
 | 
						||
      return;
 | 
						||
    }
 | 
						||
    TToken_string &row=sf.row(r);
 | 
						||
    TRectype &record=report->curr();
 | 
						||
    record.put("TIPO", " ");
 | 
						||
    if (sf.cell_disabled(r, a_buck0 +2))
 | 
						||
    {
 | 
						||
      if (r<nrows-1 && sf.cell_disabled(r+1, a_buck0 +2))
 | 
						||
      {
 | 
						||
        if (row_filter==NULL || *row_filter=='\0' || strchr(row_filter,'C'))
 | 
						||
        {
 | 
						||
          record.zero(' ');
 | 
						||
          record.put("TIPO", "C");
 | 
						||
        }
 | 
						||
      } else {
 | 
						||
        if (row_filter==NULL || *row_filter=='\0' || strchr(row_filter,'G'))
 | 
						||
          record.put("TIPO", "G");
 | 
						||
      }
 | 
						||
    } else {
 | 
						||
      if (row_filter==NULL || *row_filter=='\0' || strchr(row_filter,'C'))
 | 
						||
        record.put("TIPO", "R");
 | 
						||
      else
 | 
						||
        record.put("TIPO", "c");
 | 
						||
    }
 | 
						||
    record.put("RIGA", r);
 | 
						||
    record.put("TIPOCF", row.get(sf.cid2index(F_TIPOCF_SHEET)));
 | 
						||
    record.put("CODCLI", row.get(sf.cid2index(F_CLIENTE)));
 | 
						||
    record.put("CODART", row.get(sf.cid2index(F_ARTICOLO)));
 | 
						||
    TString16 liv;
 | 
						||
    livelli_giacenza().pack_grpcode(liv, row.get(sf.cid2index(F_LIV1)),1);
 | 
						||
    livelli_giacenza().pack_grpcode(liv, row.get(sf.cid2index(F_LIV2)),2);
 | 
						||
    livelli_giacenza().pack_grpcode(liv, row.get(sf.cid2index(F_LIV3)),3);
 | 
						||
    livelli_giacenza().pack_grpcode(liv, row.get(sf.cid2index(F_LIV4)),4);
 | 
						||
    record.put("LIVELLO", liv);
 | 
						||
    record.put("IMPIANTO", row.get(sf.cid2index(F_CODIMP)));
 | 
						||
    record.put("LINEA", row.get(sf.cid2index(F_CODLIN)));
 | 
						||
//    record.put("CODMAG", row.get(sf.cid2index(F_LIVELLO)));
 | 
						||
    record.put("UM", row.get(sf.cid2index(F_UM)));
 | 
						||
    TString16 campo;
 | 
						||
    bool somevalue = 0;
 | 
						||
    for (int nbucket = LAST_BUCKET; nbucket >= 0; nbucket--)
 | 
						||
    {
 | 
						||
      switch(nbucket)
 | 
						||
      {
 | 
						||
        case 0: 
 | 
						||
          campo = "QTAFIRST"; break;
 | 
						||
        case LAST_BUCKET: 
 | 
						||
          campo = "QTALAST"; break;
 | 
						||
        default:
 | 
						||
          campo.format("QTA%d", nbucket); break;
 | 
						||
      }
 | 
						||
      record.put(campo, row.get(sf.cid2index(F_BUCKET0+nbucket*2)));
 | 
						||
      if (!record.get_real(campo).is_zero())
 | 
						||
        somevalue++;
 | 
						||
    }
 | 
						||
    if (record.get("TIPO")!="" && (somevalue || strchr(row_filter,'G')))
 | 
						||
      report->write();
 | 
						||
    pi.addstatus(1);
 | 
						||
  }
 | 
						||
  TMSP_form form(report);
 | 
						||
  // stampa
 | 
						||
  if (form.cursor()->items() > 0)
 | 
						||
  {
 | 
						||
    TDate fd(starting_date());
 | 
						||
    TDate td = get_date(F_ADATA);
 | 
						||
    const short first_id = 3;
 | 
						||
    const short last_id = 14;
 | 
						||
 | 
						||
    if (num_cols == 0) 
 | 
						||
      num_cols = last_id - first_id;
 | 
						||
    if (num_cols > 11) 
 | 
						||
      num_cols = 11;
 | 
						||
 | 
						||
    for (int c=0; c<14; c++)
 | 
						||
    {
 | 
						||
      if (c<from_col || c>=from_col+num_cols)
 | 
						||
        form.find_field('B', odd_page, first_id+c).hide();
 | 
						||
    }
 | 
						||
 | 
						||
    short b = -1;
 | 
						||
    --fd;
 | 
						||
    TString descr;
 | 
						||
    descr.format("Fino\nal %s", (const char*)fd);
 | 
						||
    form.find_field('B', odd_page, first_id).set_col_head(descr);
 | 
						||
    for (;fd <= td;)
 | 
						||
    {
 | 
						||
      ++b;
 | 
						||
      ++fd;
 | 
						||
      descr.format("Da %s\nAl ",(const char*)fd);
 | 
						||
      round_date(fd,TRUE,FALSE);
 | 
						||
      descr << fd.string();
 | 
						||
      if (first_id+b+1 > last_id)
 | 
						||
        continue;
 | 
						||
      form.find_field('B', odd_page, first_id+b+1).set_col_head(descr);
 | 
						||
    }
 | 
						||
    ++td;
 | 
						||
    descr.format("Dal %s", (const char*)td);
 | 
						||
    if (b == LAST_BUCKET)
 | 
						||
      form.find_field('B', odd_page, first_id+b+1).set_col_head(descr);
 | 
						||
    const int hh = 7;
 | 
						||
    const int fl = printer().formlen();
 | 
						||
      
 | 
						||
    int rows[4];         // Righe orizzontali
 | 
						||
    rows[0] = hh-3;
 | 
						||
    rows[1] = hh;
 | 
						||
    rows[2] = fl;
 | 
						||
    rows[3] = 0;
 | 
						||
 | 
						||
    form.genera_intestazioni(odd_page, hh-2);
 | 
						||
    form.genera_fincatura(odd_page, hh-3, fl, rows);
 | 
						||
    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
 | 
						||
}
 | 
						||
 | 
						||
void TPlanning_mask::print_capacities()
 | 
						||
{
 | 
						||
  const char* repname = "mr2200";
 | 
						||
  TIsamtempfile * report = new TIsamtempfile(LF_MRPREPORT,repname, TRUE, FALSE );
 | 
						||
  TRectype &record=report->curr();
 | 
						||
 | 
						||
  TString8 codimp,codlin;
 | 
						||
  TString codart;
 | 
						||
 | 
						||
  TSheet_field& sf = sfield(F_LINEE);
 | 
						||
  const int nrows=sf.items();
 | 
						||
  TProgind pi(nrows, format("Stampa %s...",(*get(F_LOADTYPE)=='M')?
 | 
						||
    "carico macchina":"carico uomo"));
 | 
						||
  const int a_buck0 = sf.cid2index(F_LBUCKET0);
 | 
						||
  for (int r=0; r <nrows ; r++)
 | 
						||
  {
 | 
						||
    if (pi.iscancelled())
 | 
						||
      return;
 | 
						||
    TToken_string &row=sf.row(r);
 | 
						||
    record.zero(' ');
 | 
						||
    codimp=row.get(sf.cid2index(F_CODIMPCRP));
 | 
						||
    codlin=row.get(sf.cid2index(F_CODLINCRP));
 | 
						||
    codart=row.get(sf.cid2index(F_CODARTCRP));
 | 
						||
    record.put("RIGA", r);
 | 
						||
    record.put("IMPIANTO", codimp);
 | 
						||
    record.put("LINEA", codlin);
 | 
						||
    record.put("CODART", codart);
 | 
						||
    char type = 'D';
 | 
						||
    if (!codart.blank() && codart != "Capacit<EFBFBD>" && codart != "Carico")
 | 
						||
      type = 'A';
 | 
						||
    else if (!codlin.blank())
 | 
						||
      type = 'L';
 | 
						||
    else if (!codimp.blank())
 | 
						||
      type = 'I';
 | 
						||
    const bool is_capacity = sf.cell_disabled(r, a_buck0 +2);
 | 
						||
    if (!is_capacity)
 | 
						||
      type = tolower(type);
 | 
						||
    record.put("TIPO",type);
 | 
						||
//    record.put("TIPOCF", row.get(sf.cid2index(F_TIPOCF_SHEET)));
 | 
						||
//    record.put("CODCLI", row.get(sf.cid2index(F_CLIENTE)));
 | 
						||
    record.put("UM", row.get(sf.cid2index(F_LUM)));
 | 
						||
    TString16 campo;
 | 
						||
    for (int b = LAST_BUCKET; b >= 0; b--)
 | 
						||
    {
 | 
						||
      switch(b)
 | 
						||
      {
 | 
						||
      case 0: campo = "QTAFIRST"; break;
 | 
						||
      case LAST_BUCKET: campo = "QTALAST"; break;
 | 
						||
      default: campo.format("QTA%d", b); break;
 | 
						||
      }
 | 
						||
      record.put(campo, row.get(a_buck0+b));
 | 
						||
    }
 | 
						||
    report->write();
 | 
						||
    pi.addstatus(1);
 | 
						||
  }
 | 
						||
  // stampa
 | 
						||
  TCRP_form form(report, sf);
 | 
						||
 | 
						||
  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
 | 
						||
}
 | 
						||
 | 
						||
bool TPlanning_mask::find_exceptions(TExceptions_array &e, bool anticipi, bool posticipi, bool extra, 
 | 
						||
                                                           bool stockbreak, bool codemiss, bool verbose)
 | 
						||
{
 | 
						||
  e.destroy();
 | 
						||
  if (!get_bool(F_RESCHEDULING))
 | 
						||
  {
 | 
						||
    _mrp_articles.destroy();
 | 
						||
    if (verbose)
 | 
						||
      message_box("Rescheduling non abilitato");
 | 
						||
  }
 | 
						||
  else if (load_MRP_lines(_rescheduling))
 | 
						||
  {
 | 
						||
    const TSheet_field& sf = sfield(F_ARTICOLI);
 | 
						||
    const int bucket1 = sf.cid2index(F_BUCKET1);
 | 
						||
    // PER OGNI ARTICOLO ...
 | 
						||
    const long max_mrp_rows=_mrp_articles.items();
 | 
						||
    TProgind pi=((max_mrp_rows+1)*LAST_BUCKET ,"Ricerca eccezioni...", TRUE, TRUE);
 | 
						||
    for (long mrp_row=0; mrp_row < max_mrp_rows; mrp_row++)
 | 
						||
    {
 | 
						||
      pi.addstatus(1);
 | 
						||
      if (pi.iscancelled()) 
 | 
						||
        return FALSE;
 | 
						||
      TMRP_line &mrpline=_mrp_articles[mrp_row];
 | 
						||
      mrpline.find_ad_excepts(anticipi, posticipi, e);
 | 
						||
      if (extra)
 | 
						||
        mrpline.find_extra_excepts(get_bool(F_NUMBERBYWEEK)||get_bool(F_NUMBERBYCLI), e);
 | 
						||
    } // ... for each article
 | 
						||
  }
 | 
						||
  if (verbose && e.items()<=0)
 | 
						||
    message_box("Nessuna eccezione rilevata");
 | 
						||
  return e.items()>0;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
TObject* TException::dup() const 
 | 
						||
{
 | 
						||
  return new TException(_mrpline, _from, _to, _q);
 | 
						||
}
 | 
						||
 | 
						||
TException::TException(const TMRP_line * line, int from, int to, const real & q) :
 | 
						||
  _mrpline(line), _from(from), _to(to), _q(q)
 | 
						||
{}
 | 
						||
 | 
						||
 | 
						||
TExceptions_array::add(const TException & e)
 | 
						||
{
 | 
						||
  return add((TException *)e.dup());
 | 
						||
}
 | 
						||
 | 
						||
TExceptions_array::add(TException * e)
 | 
						||
{
 | 
						||
  const TMRP_line & line = e->mrpline();
 | 
						||
  TToken_string key;
 | 
						||
  key.add(line.articolo());
 | 
						||
  key.add(line.livgiac());
 | 
						||
  key.add(format("%04d",e->from()));
 | 
						||
  key.add(format("%04d",e->from()==e->to() ? 9999 : e->to()));
 | 
						||
  key.add(line.codimp());
 | 
						||
  key.add(line.codlin());
 | 
						||
  key.add(line.codmagdep());
 | 
						||
  key.add(line.codmagdep_coll());
 | 
						||
  return TAssoc_array::add((const char *)key, e);
 | 
						||
}
 | 
						||
 | 
						||
void TMRP_line::reset_excepts()
 | 
						||
{
 | 
						||
  // PER OGNI BUCKET ...
 | 
						||
  int last(last_bucket()), first=0;
 | 
						||
  for (int nbucket = 0; nbucket <= last; nbucket++)
 | 
						||
  {
 | 
						||
    TMRP_record& mrprec = record(nbucket);
 | 
						||
    real ro=mrprec.resched_orders();
 | 
						||
    real uo=mrprec.unsched_orders();
 | 
						||
    if (!ro.is_zero())
 | 
						||
      mrprec.add_resched_ord(-ro);
 | 
						||
    if (!uo.is_zero())
 | 
						||
      mrprec.add_unsched_ord(-uo);
 | 
						||
  } // ... for each bucket
 | 
						||
}
 | 
						||
 | 
						||
bool TMRP_line::find_ad_excepts(bool anticipi, bool posticipi, TExceptions_array &e)
 | 
						||
{
 | 
						||
  bool some=FALSE;
 | 
						||
  // PER OGNI BUCKET ...
 | 
						||
  const int last = last_bucket();
 | 
						||
  int first = 0;
 | 
						||
  for (int nbucket = 0; nbucket <= last; nbucket++)
 | 
						||
  {
 | 
						||
    const real& sr=sched_receipts(nbucket);
 | 
						||
    const real& ro=resched_orders(nbucket);
 | 
						||
    const real& uo=unsched_orders(nbucket);
 | 
						||
    const real& pl=planned_orders(nbucket);
 | 
						||
    real totplan = pl - sr - ro + uo;
 | 
						||
    if (totplan > ZERO)
 | 
						||
    {
 | 
						||
      for (int pivot = first; totplan.sign() > 0 && pivot <= last; pivot++) if (nbucket != pivot)
 | 
						||
      {
 | 
						||
        const real& srp=sched_receipts(pivot);
 | 
						||
        const real& rop=resched_orders(pivot);
 | 
						||
        const real& uop=unsched_orders(pivot);
 | 
						||
        const real& plp=planned_orders(pivot);
 | 
						||
        real movable = srp;
 | 
						||
        // vecchia logica : posticipo solo se non devo poi ripianificare il pivot
 | 
						||
        //if (nbucket > pivot) 
 | 
						||
        // nuova logica: posticipo o anticipo solo se non devo poi ripianificare il pivot
 | 
						||
          movable -= plp;
 | 
						||
        movable -= uop;
 | 
						||
        if (movable > ZERO) // 
 | 
						||
        {
 | 
						||
          first = pivot;
 | 
						||
          const real diff = fnc_min(movable, totplan);
 | 
						||
          add_unsched_ord(pivot, diff);
 | 
						||
          add_resched_ord(nbucket, diff);
 | 
						||
          totplan -=  diff;
 | 
						||
          movable -=  diff;
 | 
						||
          if (pivot > nbucket && anticipi || pivot < nbucket && posticipi)
 | 
						||
          {
 | 
						||
            e.add(new TException(this, pivot, nbucket, diff));
 | 
						||
            some = TRUE;
 | 
						||
          }
 | 
						||
        } 
 | 
						||
        if (movable <= ZERO) // 
 | 
						||
          first++;
 | 
						||
      } // ..look for available sched. receipts to move
 | 
						||
    }
 | 
						||
  } // ... for each bucket
 | 
						||
  return some;
 | 
						||
}
 | 
						||
 | 
						||
bool TMRP_line::find_extra_excepts(bool fixdoc, TExceptions_array &e)
 | 
						||
{
 | 
						||
  bool some=FALSE;
 | 
						||
  real totplan,movable,diff;
 | 
						||
  // PER OGNI BUCKET ...
 | 
						||
  for (int nbucket = 1; nbucket <= last_bucket(); nbucket++)
 | 
						||
  {
 | 
						||
    const real & gr=gross_requirement(nbucket);
 | 
						||
    const real & sr=sched_receipts(nbucket);
 | 
						||
    const real & ro=resched_orders(nbucket);
 | 
						||
    const real & uo=unsched_orders(nbucket);
 | 
						||
    const real & pl=planned_orders(nbucket);
 | 
						||
    totplan = planned_orders(nbucket) - sched_receipts(nbucket) - resched_orders(nbucket) + unsched_orders(nbucket);
 | 
						||
    bool ex = totplan.sign() < 0; // troppa roba 
 | 
						||
    if (totplan.sign() > 0 && fixdoc) // 
 | 
						||
      ex = sr>0; 
 | 
						||
    if (ex)
 | 
						||
    {
 | 
						||
      diff = -totplan;
 | 
						||
      e.add(new TException(this, nbucket, nbucket, diff));
 | 
						||
      some = TRUE;
 | 
						||
    }
 | 
						||
  } // ... for each bucket
 | 
						||
  return some;
 | 
						||
}
 | 
						||
 | 
						||
void TMRP_line::print_exception(int from, int to, const real &diff, int header) const
 | 
						||
{
 | 
						||
  TPrinter& pr = printer();
 | 
						||
  if (!pr.isopen())
 | 
						||
    pr.open();
 | 
						||
  TPrintrow prow;
 | 
						||
 | 
						||
  TToken_string code(articolo());
 | 
						||
  TDate fromdate=time(from).date();
 | 
						||
  TDate todate=time(to).date();
 | 
						||
  if (header <= 0)
 | 
						||
  {
 | 
						||
    pr.print(prow);
 | 
						||
    prow.put(format("@bArticolo %s %s", (const char *)articolo(), (const char *)cache().get(LF_ANAMAG, code).get(ANAMAG_DESCR)));
 | 
						||
    pr.print(prow);
 | 
						||
    prow.reset();
 | 
						||
    if (livelli_giacenza().enabled())
 | 
						||
    {
 | 
						||
      int pos=0;
 | 
						||
      for (int l= 1; l <= livelli_giacenza().last_level(); l++)
 | 
						||
      {
 | 
						||
        prow.put(format("@%dg%s %s",pos,(const char *)livelli_giacenza().name(l), 
 | 
						||
          (const char *)livgiac(l)));
 | 
						||
        pos += livelli_giacenza().name(l).len()+1;
 | 
						||
        pos += livgiac(l).len()+1;
 | 
						||
      }
 | 
						||
      pr.print(prow);
 | 
						||
      prow.reset();
 | 
						||
    }
 | 
						||
  }
 | 
						||
  if (header <= 1)
 | 
						||
  {
 | 
						||
    prow.put(format("Ordini emessi con scadenza entro il @41g%s", (const char*)fromdate.string()));
 | 
						||
    pr.print(prow);
 | 
						||
    prow.reset();
 | 
						||
    // stampa dettaglio ordini
 | 
						||
    TMRP_docrefs * docrefs = record(from).scheduls_refs();
 | 
						||
    CHECK(docrefs,"Errore: rischedulazione senza riferimenti");
 | 
						||
    const int nrefs=docrefs->items();
 | 
						||
    for (int nref = 0; nref < nrefs; nref++)
 | 
						||
    {
 | 
						||
      TMRP_docref & docref = docrefs->get_ref(nref);
 | 
						||
      prow.put(format("@2gDocumento %s %4d n.%8ld riga %d %s %s",
 | 
						||
        (const char*)docref.codnumdoc(),docref.annodoc(),docref.numdoc(),docref.numrig(),
 | 
						||
        (const char*)docref.qta_residua().stringa(18,3),(const char*)docref.um()));
 | 
						||
      pr.print(prow);
 | 
						||
      prow.reset();
 | 
						||
    }
 | 
						||
  }
 | 
						||
  code.add("1");
 | 
						||
  const TString16 um =cache().get(LF_UMART,code).get("UM");
 | 
						||
  const real v = abs(diff);
 | 
						||
  prow.put(format("@2g%s %s %s",  (from == to) ? 
 | 
						||
      (diff.sign()>0 ? "Eliminare  " : "Aggiungere " ):
 | 
						||
      (from < to ? "Posticipare" : "Anticipare "),
 | 
						||
    (const char*)v.stringa(18,3), (const char *)um));
 | 
						||
  if (from != to)
 | 
						||
  {
 | 
						||
    prow.put(format("@38gal %s", (const char*)todate.string()));
 | 
						||
  }
 | 
						||
  pr.print(prow);
 | 
						||
}
 | 
						||
 |