error_type TContabilizzazione::search_costo_ricavo(TBill& conto, const TRiga_documento& r)
{
  TConfig  conf(CONFIG_DITTA, "ve");
  _search_seq = new TToken_string((const char*)conf.get("RICERCACR","ve"));
  // costruisce la stringa che controlla la ricerca del conto costo/ricavo
  // Attenzione! non esegue alcun controllo di consistenza sulla corretta sequenza
  // presuppone che il programma di configurazione abbia generato correttamente
  // il tutto.
  if (_search_seq->items() == 0)
  {
    error_box("Non e' abilitata alcuna ricerca per il conto di costo/ricavo in configurazione.");
    return FALSE;
  }
  const int items = _search_seq->items();
  TLocalisamfile& cli_file = _clifo->lfile(); // YES, arriva qui dentro quando la relazione e' gia' posizionata
  const bool is_cli = cli_file.get(CLI_TIPOCF) == "C";
  bool skip_art_related = FALSE;
  bool skip_clifo = _clifo->bad();
  TCodiceIVA codiva(r.get(RDOC_CODIVA));
  const char t = r.tipo().tipo();

  // Istanzia la causale del documento corrente...
  const TTipo_documento& tipo = _doc->tipo();
  TString16 codcaus(tipo.causale());
  
  TToken_string  key;
  key.add(_doc->get(DOC_TIPOCF));
  key.add(_doc->get(DOC_CODCF));          
    
  const TRectype & cfven = cache().get(LF_CFVEN, key);              
  const TString16 caus_cli(cfven.get(CFV_CODCAUS)); 
  
  if (caus_cli.not_empty())
    codcaus = caus_cli;
  _caus = new TCausale(codcaus,data_reg.year());

  int gr,co;
  long so;
  
  switch (t)
  {
    case 'O': // righe omaggio come articoli spiaccicato identico (avranno imponibile 0)
    case 'M': // righe di merce
    {
      // posiziona l'anagrafica sull'articolo specificato sulla ..iga
      TString80 codart = r.get(RDOC_CODARTMAG);
      if codart.blank()
      	codart = r.get(RDOC_CODART);
      _anamag->put(ANAMAG_CODART, codart);
      if (_anamag->read() != NOERR) // se non trova l'articolo saltera' anche gmc,smc,rfa.
        skip_art_related = TRUE;
      
      TString16 tok;
      // Scorre la stringa di ricerca
      for (int i=0;i<items;i++)
      { 
        tok = _search_seq->get(i);
        if (tok == "CF")
        {
          if (skip_clifo) continue;
          gr = cli_file.get_int(CLI_GRUPPORIC);
          co = cli_file.get_int(CLI_CONTORIC);
          so = cli_file.get_long(CLI_SOTTOCRIC);
          conto.set(gr,co,so);
          if (conto.ok()) break; // se lo trova esce (tutti != 0)
        }
        else
        if (tok == "CA")
        {                        
        	
          CHECK(_caus,"Causale documento non valida");
          if (_caus->IVA2bill(codiva,conto)) break; // se lo trova esce
        }
        else
        if (tok == "AR")
        {
          if (skip_art_related) continue;
          gr = _anamag->get_int(is_cli ? ANAMAG_GRUPPOV : ANAMAG_GRUPPOA);
          co = _anamag->get_int(is_cli ? ANAMAG_CONTOV : ANAMAG_CONTOA);
          so = _anamag->get_long(is_cli ? ANAMAG_SOTTOCV : ANAMAG_SOTTOCA);
          conto.set(gr,co,so);
          if (!conto.ok()) // se il conto non c'e' guarda la categoria acquisti/vendite
          {
            TTable *t = is_cli ? _cra : _caa;
            
            t->put("CODTAB",_anamag->get(is_cli ? ANAMAG_CATCONV : ANAMAG_CATCONA));
            if (t->read() == NOERR)
            {
              gr = atoi(t->get("S1"));
              co = atoi(t->get("S2"));
              so = atol(t->get("S3"));
              conto.set(gr,co,so);
            }
          }
          if (conto.ok()) break;
        }
        else
        if (tok == "GM" || tok == "SM" || tok == "RF")
        {
          if (skip_art_related) continue;
          const bool is_fis = tok == "RF";
          TTable * tab = is_fis ? _rfa : _gmc;
          TString16 codtab(_anamag->get(is_fis ? ANAMAG_RAGGFIS : ANAMAG_GRMERC));
          if (tok == "GM" && codtab.len() > 3)
            codtab.cut(3); // gli ultimi 2 si riferiscono al sottogruppo.
          tab->put("CODTAB",codtab);
          if (tab->read() == NOERR)
          {
            gr = tab->get_int(is_cli ? "I3" : "I0");
            co = tab->get_int(is_cli ? "I4" : "I1");
            so = tab->get_long(is_cli ? "I5" : "I2");
            conto.set(gr,co,so);
          }
          if (conto.ok()) break;
        }
        else
        if (tok == "CV" || tok == "CC")
        {
          const bool is_cve = tok == "CV";
          if (is_cve && !is_cli) continue; // se e' un fornitore salta questa condizione
          TTable* t = is_cve ? _cve : _cco;
          TString16 cod(is_cve ? r.doc().get(DOC_CATVEN) : EMPTY_STRING);
          if (cod.empty())
          {
            if (skip_clifo) continue; // se non aveva trovato il cliente salta al prossimo
            cod = _clifo->lfile(LF_CFVEN).get(is_cve ? CFV_CATVEN : CFV_CODCATC);
          }
          t->put("CODTAB",cod);
          if (t->read() == NOERR)
          {
            const bool x =(is_cve || is_cli);
            gr = t->get_int(x ? "I3" : "I0");
            co = t->get_int(x ? "I4" : "I1");                                                                   	
            so = t->get_long(x ? "I5": "I2");
            conto.set(gr,co,so);
          }
          if (conto.ok()) break;
        }
      }
      break; // case 'M'
    }
    case 'P': // righe prestazione 
    case 'S': // righe spese
    {
      TTable*  tab = t == 'P' ? _prs : _spp;
      tab->put("CODTAB",r.get(RDOC_CODART));
      if (tab->read()==NOERR)
      {
        gr = tab->get_int(is_cli ? "I0" : "I3");
        co = tab->get_int(is_cli ? "I1" : "I4");
        so = tab->get_long(is_cli ? "I2" : "I5");
        conto.set(gr,co,so);                    
        if (!is_cli && !conto.ok())
        {
          gr = r.get_int("QTAGG1");
          co = r.get_int("QTAGG2");
          so = r.get_long("QTAGG3");
          conto.set(gr,co,so);                    
        }
      }
      
      if (!conto.find() && t == 'P') // Cerca il conto nella stringa di ricerca (solo per prestazioni)
      {
        TString16 tok;
        // Scorre la stringa di ricerca ma solo per causale o CLI/FO
        for (int i=0;i<items;i++)
        { 
          tok = _search_seq->get(i);
          if (tok == "CF")
          {
            if (skip_clifo) continue;
            gr = cli_file.get_int(CLI_GRUPPORIC);
            co = cli_file.get_int(CLI_CONTORIC);
            so = cli_file.get_long(CLI_SOTTOCRIC);
            conto.set(gr,co,so);
            if (conto.ok()) break;
          }
          else
            if (tok == "CA")
            {
              CHECK(_caus,"Causale documento non valida");
              if (_caus->IVA2bill(codiva,conto)) break;
            }
        }
      }
      break;  // case 'P','S'
    }
    case 'C':
      // righe sconti: vengono considerate in adjust_sconto_rows()
    case 'D': // righe descrizioni (saltare)
    default :
      break;
  } // end of switch
  if (good())
  {
    if (conto.ok() == 0 || !conto.find())
    {
      _conto_errato = conto;
      _error = conto_error;
    }
  }
  return _error;
}