Files correlati : 777.exe Ricompilazione Demo : [ ] Commento : Aggiunto programma di trasferimento dati 770 per la Dylog git-svn-id: svn://10.65.10.50/trunk@7218 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			1465 lines
		
	
	
		
			39 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1465 lines
		
	
	
		
			39 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include <fstream.h>
 | 
						||
 | 
						||
#include <applicat.h>
 | 
						||
#include <form.h>
 | 
						||
#include <automask.h>
 | 
						||
#include <os_dep.h>
 | 
						||
#include <progind.h>
 | 
						||
#include <recarray.h>
 | 
						||
#include <utility.h>
 | 
						||
 | 
						||
#include "777.h"
 | 
						||
#include "777100a.h"
 | 
						||
 | 
						||
#include <anagr.h>
 | 
						||
#include <anafis.h>
 | 
						||
#include <anagiu.h>
 | 
						||
#include <comuni.h>
 | 
						||
#include <nditte.h>
 | 
						||
#include "base.h"
 | 
						||
#include "quadroc.h"
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// Dichiarazioni
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TForm770
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
class TRecord770;
 | 
						||
class TTrasferimento770;
 | 
						||
 | 
						||
class TForm770 : public TForm
 | 
						||
{
 | 
						||
  TCursor* _sortedcur;
 | 
						||
 | 
						||
  int _index;
 | 
						||
  TArray _records;
 | 
						||
  TPointer_array _positions;
 | 
						||
 | 
						||
protected:
 | 
						||
  bool compatible(const TRectype& r1, const TRectype& r2);
 | 
						||
  void add_rec(TRectype& r1, const TRectype& r2);
 | 
						||
 | 
						||
  long raggruppa_c();
 | 
						||
  int first();
 | 
						||
  int next();
 | 
						||
 | 
						||
  void transfer_section(TPrint_section& body, int rigo,
 | 
						||
                        TRecord770& rec, TTrasferimento770& file);
 | 
						||
  char log2rec(int num, int& rpm) const;
 | 
						||
 | 
						||
protected:
 | 
						||
 | 
						||
  virtual TCursor* cursor() { return _sortedcur ? _sortedcur : TForm::cursor(); }
 | 
						||
 | 
						||
public:
 | 
						||
  long trasfer(long codditta, TTrasferimento770& file, char tipo, int rpm);
 | 
						||
 | 
						||
  TForm770(const char* name);
 | 
						||
  virtual ~TForm770();
 | 
						||
};
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TRecord770
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
enum { FIELD_SIZE = 16, BLOCK_SIZE = 24, 
 | 
						||
       USEABLE_SIZE = 3997, TOTAL_SIZE = 4000 };
 | 
						||
 | 
						||
struct TField770 : public TObject
 | 
						||
{
 | 
						||
  TString _desc;
 | 
						||
  int     _pos;   // Base 1
 | 
						||
  int     _len;
 | 
						||
  char    _type;  // A/N
 | 
						||
};
 | 
						||
 | 
						||
class TTracciato770 : public TObject
 | 
						||
{
 | 
						||
  char _tipo;
 | 
						||
  TArray _fields;
 | 
						||
 | 
						||
protected:
 | 
						||
  int add_field(const char* name, char type, int pos, int len);
 | 
						||
  int add_filler(char type, int pos, int len) 
 | 
						||
  { return add_field("Filler", type, pos, len); }
 | 
						||
 | 
						||
public:
 | 
						||
  const TField770& field(int pos) const;
 | 
						||
  void auto_fill(TString& buffer) const;
 | 
						||
 | 
						||
  TTracciato770(char tipo);
 | 
						||
  virtual ~TTracciato770();
 | 
						||
};
 | 
						||
 | 
						||
class TTracciati770 : public TObject
 | 
						||
{
 | 
						||
  TArray _trc;
 | 
						||
  TAssoc_array _form;
 | 
						||
 | 
						||
public:
 | 
						||
  const TTracciato770& tracciato(char tipo);
 | 
						||
  TForm770& form(const char* quadro, char& tipo, int& rpm);
 | 
						||
 | 
						||
  void destroy();
 | 
						||
  
 | 
						||
  TTracciati770();
 | 
						||
  virtual ~TTracciati770();
 | 
						||
} _trc770;
 | 
						||
 | 
						||
class TCache770 : public TObject
 | 
						||
{
 | 
						||
  TArray _files;
 | 
						||
  TAssoc_array _tables;
 | 
						||
 | 
						||
public:
 | 
						||
  const TRectype& get(int num, const char* key);
 | 
						||
  const TRectype& get(int num, long key);
 | 
						||
  void destroy();
 | 
						||
 | 
						||
  TCache770() { }
 | 
						||
  virtual ~TCache770() { }
 | 
						||
} _cache770;
 | 
						||
 | 
						||
class TRecord770 : public TObject
 | 
						||
{
 | 
						||
  TString _buffer;
 | 
						||
 | 
						||
protected: // TObject
 | 
						||
  virtual TObject* dup() const { return new TRecord770(*this); }
 | 
						||
  virtual void print_on(ostream& outs) const;
 | 
						||
  virtual void read_from(istream& ins);
 | 
						||
 | 
						||
protected: // TObject
 | 
						||
  const TTracciato770& tracciato() const 
 | 
						||
  { return _trc770.tracciato(tipo_record()); }
 | 
						||
  
 | 
						||
  const TField770& get_field(int pos) const
 | 
						||
  { return tracciato().field(pos); }
 | 
						||
 | 
						||
  void set(const TField770& fld, const char* val);
 | 
						||
  int calculate_blocks(const char* val) const;
 | 
						||
 | 
						||
  bool fill(const TRectype& rec);
 | 
						||
  bool fill_e(const TRectype& rec);
 | 
						||
  bool fill_comune(const TRectype& rec_anagr, int whichcom, bool swapcap, int offset);
 | 
						||
  bool fill_residenza(const TRectype& rec_anagr, int offset, int whichcom, bool swapcap);
 | 
						||
  bool fill_telefono(const TRectype& rec_anagr, int offset);
 | 
						||
  bool fill_persona(const TRectype& rec_anagr, int offset, int gap);
 | 
						||
 | 
						||
public:
 | 
						||
  void set(int pos, const char* val);
 | 
						||
  void set(int pos, int val);
 | 
						||
  void set(int pos, long val);
 | 
						||
  void set(int pos, const real& val);
 | 
						||
  void set(int pos, const TDate& val);
 | 
						||
  void set(int pos, char val);
 | 
						||
  void set(int pos, bool val);
 | 
						||
  bool add(const char* code, const char* val);
 | 
						||
 | 
						||
  const char* get(int pos, TString& str) const;
 | 
						||
  int get_int(int pos) const;
 | 
						||
  char get_char(int pos) const;
 | 
						||
 | 
						||
  const TRecord770& operator=(const TRecord770& rec) 
 | 
						||
  { _buffer = rec._buffer; return *this; }
 | 
						||
  
 | 
						||
  const TRecord770& operator=(const TRectype& rec)
 | 
						||
  { fill(rec); return *this; }
 | 
						||
 | 
						||
  char tipo_record() const { return _buffer[0]; }
 | 
						||
  void tipo_record(char tipo) 
 | 
						||
  { _buffer[0] = tipo; tracciato().auto_fill(_buffer); }
 | 
						||
 | 
						||
  void azzera_campi_non_posizionali();
 | 
						||
  void set_magnetic_support(bool mag) 
 | 
						||
  { _buffer[3997] = mag ? 'A' : ' '; }
 | 
						||
 | 
						||
  bool valid() const;
 | 
						||
 | 
						||
  TRecord770();
 | 
						||
  TRecord770(char tipo);
 | 
						||
  TRecord770(const TRecord770& rec);
 | 
						||
  TRecord770(const TRectype& rec);
 | 
						||
  virtual ~TRecord770();
 | 
						||
};
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TTrasferimento770
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
class TTrasferimento770 : public TObject
 | 
						||
{
 | 
						||
  TFilename _name;
 | 
						||
  ifstream* _in_stream;
 | 
						||
  ofstream* _out_stream;
 | 
						||
 | 
						||
public:
 | 
						||
  bool open(const char* path = "", char mode = 'r');
 | 
						||
  bool close();
 | 
						||
  bool write(const TRecord770& rec);
 | 
						||
  bool read(TRecord770& rec);
 | 
						||
  bool eof() const { return _in_stream && _in_stream->eof(); }
 | 
						||
 | 
						||
  const char* default_name() const { return "MOD77098"; }
 | 
						||
 | 
						||
  TTrasferimento770& operator<<(const TRecord770& rec)
 | 
						||
  { write(rec);  return *this; }
 | 
						||
  TTrasferimento770& operator>>(TRecord770& rec)
 | 
						||
  { read(rec); return *this; }
 | 
						||
 | 
						||
  long append_quadro(const char* quadro, long codditta, TProgind& pi);
 | 
						||
 | 
						||
  bool split(const char* dest_path);
 | 
						||
  void remove();
 | 
						||
 | 
						||
  TTrasferimento770(const char* name = "", char mode = 'r');
 | 
						||
  virtual ~TTrasferimento770();
 | 
						||
};
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// Implementazioni
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TForm770
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
void TForm770::transfer_section(TPrint_section& body, int rigo,
 | 
						||
                                TRecord770& rec, TTrasferimento770& file)
 | 
						||
{
 | 
						||
  TString16 basecode, code;
 | 
						||
  TString80 str;
 | 
						||
 | 
						||
  TCursor& cur = *cursor();
 | 
						||
  
 | 
						||
  body.update(); 
 | 
						||
  for (word f = 0; f < body.fields(); f++)
 | 
						||
  {
 | 
						||
    TForm_item& fi = body.field(f);
 | 
						||
    str = fi.get(); str.trim();
 | 
						||
    if (fi.shown() && str.not_empty())
 | 
						||
    {
 | 
						||
      basecode = fi.get_special_value("TRASFER");
 | 
						||
      if (basecode.not_empty())
 | 
						||
      {
 | 
						||
        if (fi.fields() > 0)
 | 
						||
        {
 | 
						||
          const TFieldref& fr = ((TForm_string&)fi).field(0);
 | 
						||
          const int num = fr.file();
 | 
						||
          const char* fn = fr.name();
 | 
						||
          const TFieldtypes ft = cur.curr(num).type(fn);
 | 
						||
          switch (ft)
 | 
						||
          {
 | 
						||
          case _boolfld:
 | 
						||
            if (!str.blank())
 | 
						||
              str = "1";
 | 
						||
            str.right_just(16);
 | 
						||
            break;
 | 
						||
          case _datefld:
 | 
						||
            if (str.len() == 10 && str[2] == '-' && str[5] == '-')
 | 
						||
            {
 | 
						||
              str[2] = str[3]; str[3] = str[4];
 | 
						||
              str[4] = str[8]; str[5] = str[9];
 | 
						||
              str.cut(6); str.right_just(16);
 | 
						||
            }
 | 
						||
            break;
 | 
						||
          case _realfld:
 | 
						||
            if (str.len() > 3)
 | 
						||
              str.rtrim(3);
 | 
						||
          case _intfld:
 | 
						||
          case _longfld:
 | 
						||
            str.right_just(16);
 | 
						||
            break;
 | 
						||
          default:
 | 
						||
            break;
 | 
						||
          }
 | 
						||
        }
 | 
						||
        const int vero_rigo = atoi(basecode.mid(2, 2)) + rigo;
 | 
						||
        code.format("%c%c%02d%c%c00", basecode[0], basecode[1], 
 | 
						||
                           vero_rigo, basecode[4], basecode[5]);
 | 
						||
        if (!rec.add(code, str))
 | 
						||
        {
 | 
						||
          file << rec;
 | 
						||
          rec.azzera_campi_non_posizionali();
 | 
						||
          rec.add(code, str);
 | 
						||
        }     
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
bool TForm770::compatible(const TRectype& r1, const TRectype& r2)
 | 
						||
{
 | 
						||
  if (r1.empty() || r2.empty())
 | 
						||
    return TRUE;
 | 
						||
 | 
						||
  if (r1.get_long(QUC_CODDITTA) != r2.get_long(QUC_CODDITTA))
 | 
						||
    return FALSE;
 | 
						||
  if (r1.get_char(QUC_TIPOA) != r2.get_char(QUC_TIPOA))
 | 
						||
    return FALSE;
 | 
						||
  if (r1.get_long(QUC_CODANAGR) != r2.get_long(QUC_CODANAGR))
 | 
						||
    return FALSE;
 | 
						||
  if (r1.get_char(QUC_CAUSALE) != r2.get_char(QUC_CAUSALE))
 | 
						||
    return FALSE;
 | 
						||
  if (r1.get_int(QUC_TASSAZIONE) != r2.get_int(QUC_TASSAZIONE))
 | 
						||
    return FALSE;
 | 
						||
 | 
						||
  const real p1 = r1.get_real(QUC_PERC);
 | 
						||
  const real p2 = r2.get_real(QUC_PERC);
 | 
						||
  bool yes = (p1 == ZERO && p2 != ZERO) || (p1 == p2);
 | 
						||
  return yes;
 | 
						||
}
 | 
						||
 | 
						||
void TForm770::add_rec(TRectype& r1, const TRectype& r2)
 | 
						||
{
 | 
						||
  if (r1.empty())
 | 
						||
    r1 = r2;
 | 
						||
  else
 | 
						||
  {
 | 
						||
    for (int f = r1.items()-1; f >= 0; f--)
 | 
						||
    {
 | 
						||
      const char* name = r1.fieldname(f);
 | 
						||
      if (r1.type(name) == _realfld)
 | 
						||
      {
 | 
						||
        real val = r1.get_real(name);
 | 
						||
        val += r2.get_real(name);
 | 
						||
        r1.put(name, val);
 | 
						||
      }
 | 
						||
    }
 | 
						||
    r1.put(QUC_PERC, r2.get(QUC_PERC));
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
long TForm770::raggruppa_c()
 | 
						||
{
 | 
						||
  TCursor& cur = *cursor();
 | 
						||
  TRectype& rc = cur.curr();
 | 
						||
  _records.destroy();
 | 
						||
  for (cur = 0; cur.ok(); ++cur)
 | 
						||
  {
 | 
						||
    bool append = TRUE;
 | 
						||
    const int last = _records.items()-1;
 | 
						||
    if (last >= 0)
 | 
						||
    {
 | 
						||
      TRectype& sum = (TRectype&)_records[last];
 | 
						||
      if (compatible(sum, rc))
 | 
						||
      {
 | 
						||
        add_rec(sum, rc);
 | 
						||
        append = FALSE;
 | 
						||
      }
 | 
						||
    }
 | 
						||
    if (append)
 | 
						||
    {
 | 
						||
      _records.add(rc);
 | 
						||
      _positions.add_long(cur.pos()+1);
 | 
						||
    }
 | 
						||
  }                
 | 
						||
 
 | 
						||
  return _records.items();
 | 
						||
}
 | 
						||
 | 
						||
int TForm770::first()
 | 
						||
{
 | 
						||
  TCursor& cur = *cursor();
 | 
						||
 | 
						||
  cur = 0;
 | 
						||
  bool ok = cur.ok();
 | 
						||
  
 | 
						||
  if (cur.file().num() == LF_QUAC)
 | 
						||
  {
 | 
						||
    if (ok)
 | 
						||
    {
 | 
						||
      raggruppa_c();
 | 
						||
      _index = 0;
 | 
						||
      cur.curr() = (TRectype&)_records[0];
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  return ok ? NOERR : _iseof;
 | 
						||
}
 | 
						||
 | 
						||
int TForm770::next()
 | 
						||
{
 | 
						||
  TCursor& cur = *cursor();
 | 
						||
 | 
						||
  bool ok;
 | 
						||
  if (cur.file().num() == LF_QUAC)
 | 
						||
  {
 | 
						||
    _index++;
 | 
						||
    ok = _index < _records.items();
 | 
						||
    if (ok)
 | 
						||
    {
 | 
						||
      cur = _positions.get_long(_index) - 1;
 | 
						||
      cur.curr() = (TRectype&)_records[_index];
 | 
						||
    }
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    ++cur;
 | 
						||
    ok = cur.ok();
 | 
						||
  }
 | 
						||
 | 
						||
  return ok ? NOERR : _iseof;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
long TForm770::trasfer(long codditta, TTrasferimento770& file, 
 | 
						||
                       char rectype, int rpm)
 | 
						||
{
 | 
						||
  TCursor& cur = *cursor();
 | 
						||
  
 | 
						||
  // Filtra il cursore sulla ditta corrente
 | 
						||
  TRectype filter(cur.curr());
 | 
						||
  filter.zero();
 | 
						||
  filter.put(BSE_CODDITTA, codditta);
 | 
						||
  cur.setregion(filter, filter);
 | 
						||
  
 | 
						||
  const long items = cur.items();
 | 
						||
  if (items > 0)         // Se c'e almeno un record ...
 | 
						||
  {
 | 
						||
    cur.freeze(TRUE);    // Per efficienza congela il cursore
 | 
						||
 | 
						||
    // Inizializza record col primo modulo
 | 
						||
    TRecord770 rec(rectype);
 | 
						||
    int modulo = 1;
 | 
						||
    int rigo = 0;
 | 
						||
    rec.set(6, modulo);
 | 
						||
 | 
						||
    int err = first();   // Deve sempre tornare NOERR
 | 
						||
    TPrint_section& head = section('H', first_page);
 | 
						||
    transfer_section(head, rigo, rec, file);
 | 
						||
    
 | 
						||
    for (; err == NOERR; err = next())
 | 
						||
    {
 | 
						||
      TPrint_section& body = section('B', odd_page);
 | 
						||
      transfer_section(body, rigo, rec, file);
 | 
						||
 | 
						||
      rigo++;
 | 
						||
      if (rigo >= rpm)
 | 
						||
      {
 | 
						||
        // Scrivi record se non vuoto
 | 
						||
        if (rec.get_char(7) > ' ')
 | 
						||
          file << rec;
 | 
						||
        
 | 
						||
        // Avanza al prossimo modulo ed azzera la  riga
 | 
						||
        rigo = 0;
 | 
						||
        modulo++;
 | 
						||
  
 | 
						||
        rec.azzera_campi_non_posizionali();
 | 
						||
        rec.set(6, modulo);
 | 
						||
        transfer_section(head, rigo, rec, file);
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    // Ultimo record parzialmente compilato
 | 
						||
    if (rec.get_char(7) > ' ')
 | 
						||
      file << rec;
 | 
						||
    
 | 
						||
    cur.freeze(FALSE);
 | 
						||
  }
 | 
						||
 | 
						||
  return items;
 | 
						||
}
 | 
						||
 | 
						||
TForm770::TForm770(const char* name)
 | 
						||
: TForm(name), _sortedcur(NULL)
 | 
						||
{
 | 
						||
  const char* key = NULL;
 | 
						||
  
 | 
						||
  switch (TForm::cursor()->file().num())
 | 
						||
  {
 | 
						||
  case LF_QUAC: key = "CODDITTA|TIPOA|216@->RAGSOC|CODANAGR|CODCAUS|PERC";
 | 
						||
  case LF_QUAD: key = "CODDITTA|216@->RAGSOC|TIPOA|CODANAGR"; break;
 | 
						||
  default     : break;
 | 
						||
  }
 | 
						||
  if (key)
 | 
						||
    _sortedcur = new TSorted_cursor(TForm::relation(), key);
 | 
						||
}
 | 
						||
 | 
						||
TForm770::~TForm770()
 | 
						||
{
 | 
						||
  if (_sortedcur)
 | 
						||
    delete _sortedcur;
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TTracciato770
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
int TTracciato770::add_field(const char* name, char type, int pos, int len)
 | 
						||
{
 | 
						||
  TField770* info = new TField770;
 | 
						||
  info->_desc = name;
 | 
						||
  info->_type = type;
 | 
						||
  info->_pos  = pos;
 | 
						||
  info->_len  = len;
 | 
						||
  _fields.add(info);
 | 
						||
  return _fields.items();
 | 
						||
}
 | 
						||
 | 
						||
const TField770& TTracciato770::field(int pos) const
 | 
						||
{
 | 
						||
  TField770* info = (TField770*)_fields.objptr(pos-1);
 | 
						||
  CHECKD(info, "Campo non valido ", pos);
 | 
						||
  return *info;
 | 
						||
}
 | 
						||
 | 
						||
void TTracciato770::auto_fill(TString& buffer) const
 | 
						||
{
 | 
						||
  buffer.fill(' ', TOTAL_SIZE);
 | 
						||
  for (int f = _fields.last(); f >= 0; f--)
 | 
						||
  {
 | 
						||
    const TField770& info = (const TField770&)_fields[f];
 | 
						||
    if (info._desc == "Filler")
 | 
						||
    {
 | 
						||
      const char fill = info._type == 'N' ? '0' : ' ';
 | 
						||
      char* index = buffer.get_buffer();
 | 
						||
      index += info._pos - 1;
 | 
						||
      memset(index, fill, info._len);
 | 
						||
    }
 | 
						||
  }
 | 
						||
  buffer[0] = _tipo;
 | 
						||
  buffer.overwrite("\r\n", TOTAL_SIZE-2);
 | 
						||
}
 | 
						||
 | 
						||
TTracciato770::TTracciato770(char tipo) : _tipo(tipo)
 | 
						||
{
 | 
						||
  if (strchr("AEFGHZ", tipo) == NULL)
 | 
						||
    NFCHECK("Tipo record non valido: %c", tipo);
 | 
						||
  
 | 
						||
  add_field("Tipo record", 'A', 1, 1);                          // 1
 | 
						||
  add_filler('N', 2, 2);                                        // 2 
 | 
						||
 | 
						||
  if (tipo == 'A' || tipo == 'Z')
 | 
						||
  {
 | 
						||
    add_filler('N', 4, 2);                                      // 3
 | 
						||
    add_field("Numero totale volumi inviati",   'N',  6, 3);    
 | 
						||
    add_field("Progressivo del volume inviato", 'N',  9, 3);
 | 
						||
    add_field("Data di emissione",              'N', 12, 6);
 | 
						||
    add_field("Codice fornitura",               'N', 18, 5);
 | 
						||
 | 
						||
    if (tipo == 'A')
 | 
						||
    {
 | 
						||
      add_field("Tipo fornitore",                'N',  23,  1); // 8
 | 
						||
      add_field("Codice fiscale del fornitore",  'A',  24, 16);
 | 
						||
      add_field("Cognome del fornitore",         'A',  40, 60);
 | 
						||
      add_field("Data di nascita del fornitore", 'N', 100,  8);
 | 
						||
      add_field("Comune o stato",                'A', 108, 40);
 | 
						||
      add_field("Provincia di nascita",          'A', 148,  2);
 | 
						||
      add_field("Indirizzo",                     'A', 150, 35);
 | 
						||
      add_field("C.A.P.",                        'N', 185,  5);
 | 
						||
      add_field("Comune di residenza",           'A', 190, 40);
 | 
						||
      add_field("Provincia di residenza",        'A', 230,  2);
 | 
						||
      add_field("Indirizzo di residenza",        'A', 232, 35);
 | 
						||
      add_field("C.A.P. di residenza",           'N', 267,  5);
 | 
						||
    }
 | 
						||
    else
 | 
						||
    {
 | 
						||
      add_field("Numero complessivo di record",  'N',  23, 9);  // 8
 | 
						||
      add_filler('N', 32, 9);
 | 
						||
      add_field("Numero record di tipo 'E'",     'N',  41, 9);
 | 
						||
      add_field("Numero record di tipo 'F'",     'N',  50, 9);
 | 
						||
      add_field("Numero record di tipo 'G'",     'N',  59, 9);
 | 
						||
      add_field("Numero record di tipo 'H'",     'N',  68, 9);
 | 
						||
      add_filler('A', 77, 3921);
 | 
						||
      add_field("Supporto magnetico",            'A',3998, 1);
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  if (tipo >= 'E' && tipo <= 'H')
 | 
						||
  {
 | 
						||
    add_field("Codice fiscale del soggetto dichiarante", 'A',  4, 16);   // 3
 | 
						||
    add_field("Protocollo",                              'A', 20, 25);
 | 
						||
    add_field("Spazio riservato all'applicazione",       'A', 45, 35);
 | 
						||
    if (tipo == 'E')
 | 
						||
    {
 | 
						||
      add_field("Data di presentazione",                   'N', 80,  6); // 6
 | 
						||
      add_field("Numero progressivo del pacco",            'N', 86,  7);
 | 
						||
      add_field("Numero sequenza all'interno del pacco",   'N', 93,  3);
 | 
						||
      add_field("Cognome",                                 'A', 96, 60);
 | 
						||
      add_field("Nome",                                    'A',120, 20);
 | 
						||
      add_filler('A',140, 16);
 | 
						||
      add_field("Dichiarazione integrativa",               'N',156,  1); // 12
 | 
						||
      add_field("Data di nascita del dichiarante",         'N',157,  6);
 | 
						||
      add_field("Sesso",                                   'A',163,  1);
 | 
						||
      add_field("Comune o Stato estero di nascita",        'A',164, 40);
 | 
						||
      add_field("Sigla provincia di nascita del dic",      'A',204,  2);
 | 
						||
      add_field("Mese di variazione residenza o domicilio",'N',206,  2);
 | 
						||
      add_field("Anno variazione residenza o domicilio",   'N',208,  2);
 | 
						||
      add_field("Comune di residenza o domicilio dich",    'A',210, 40);
 | 
						||
      add_field("Sigla provincia di resid o domicilio",    'A',250,  2); // 20
 | 
						||
      add_field("Indirizzo residenza o domicilio",         'A',252, 35);
 | 
						||
      add_field("CAP residenza o domicilio",               'N',287,  5);
 | 
						||
      add_field("Codice attivit<69> F",                       'A',292,  5);
 | 
						||
      add_field("Telefono F",                              'A',297, 13);
 | 
						||
      add_field("Mese variazione sede legale",             'N',310,  2);
 | 
						||
      add_field("Anno variazione sede legale",             'N',312,  2);
 | 
						||
      add_field("Comune della sede legale",                'A',314, 40);
 | 
						||
      add_field("Sigla provincia sede legale",             'A',354,  2);
 | 
						||
      add_field("Indirizzo sede legale",                   'A',356, 35);
 | 
						||
      add_field("CAP sede legale",                         'N',391,  5); // 30
 | 
						||
      add_field("Mese variazione domicilio fiscale",       'N',396,  2);
 | 
						||
      add_field("Anno variazione domicilio fiscale",       'N',398,  2);
 | 
						||
      add_field("Comune domicilio fiscale",                'N',400, 40);
 | 
						||
      add_field("Sigla provincia domicilio fiscale",       'N',440,  2);
 | 
						||
      add_field("Indirizzo domicilio fiscale",             'A',442, 35);
 | 
						||
      add_field("CAP domicilio fiscale",                   'N',477,  5);
 | 
						||
      add_field("Codice attivit<69> G",                       'A',482,  5);
 | 
						||
      add_field("Stato",                                   'N',487,  1);
 | 
						||
      add_field("Natura giuridica",                        'N',488,  2);
 | 
						||
      add_field("Situazione",                              'N',490,  1); // 40
 | 
						||
      add_field("Telefono G",                              'A',491, 13);
 | 
						||
      add_field("Codice fiscale",                          'A',504, 16);
 | 
						||
      add_field("Codice carica",                           'N',520,  1);
 | 
						||
      add_field("Cognome rappresentante",                  'A',521, 24);
 | 
						||
      add_field("Nome del rappresentante",                 'A',545, 20);
 | 
						||
      add_field("Sesso del rappresentante",                'A',565,  1);
 | 
						||
      add_field("Data nascita rappresentante",             'N',566,  6);
 | 
						||
      add_field("Comune nascita rappresentante",           'A',572, 40);
 | 
						||
      add_field("Sigla provincia nascita rap",             'A',612,  2);
 | 
						||
      add_field("Comune residenza anagrafica rap",         'A',614, 40); // 50
 | 
						||
      add_field("Sigla residenza anagrafica nascita rap",  'A',654,  2);
 | 
						||
      add_field("CAP residenza anagrafica rap",            'N',656,  5);
 | 
						||
      add_field("Indirizzo residenza anagrafica rap",      'A',661, 35);
 | 
						||
      add_field("Telefono rap",                            'A',696, 13);
 | 
						||
      add_field("Casella quadro SA",                       'N',709,  1);
 | 
						||
      add_field("Casella quadro SB",                       'N',710,  1);
 | 
						||
      add_field("Casella quadro SC",                       'N',711,  1);
 | 
						||
      add_field("Casella quadro SD",                       'N',712,  1);
 | 
						||
      add_field("Casella quadro SE",                       'N',713,  1);
 | 
						||
      add_field("Casella quadro SF",                       'N',714,  1); // 60
 | 
						||
      add_field("Casella quadro SG",                       'N',715,  1);
 | 
						||
      add_field("Casella quadro SH",                       'N',716,  1);
 | 
						||
      add_field("Casella quadro SK",                       'N',717,  1);
 | 
						||
      add_field("Casella quadro SL",                       'N',718,  1);
 | 
						||
      add_field("Casella quadro SM",                       'N',719,  1);
 | 
						||
      add_field("Casella quadro SN",                       'N',720,  1);
 | 
						||
      add_field("Casella quadro SP",                       'N',721,  1);
 | 
						||
      add_field("Casella quadro SQ",                       'N',722,  1);
 | 
						||
      add_field("Casella quadro SR",                       'N',723,  1);
 | 
						||
      add_field("Casella quadro SS",                       'N',724,  1); // 70
 | 
						||
      add_field("Casella quadro ST",                       'N',725,  1);
 | 
						||
      add_field("Casella quadro SU",                       'N',726,  1);
 | 
						||
      add_field("Casella quadro SV",                       'N',727,  1);
 | 
						||
      add_field("Casella quadro SW",                       'N',728,  1);
 | 
						||
      add_field("Casella quadro SZ",                       'N',729,  1);
 | 
						||
      add_field("Firma presidente o compon organo contr",  'N',730,  1);
 | 
						||
      add_field("Firma del dichiarante",                   'N',731,  1);
 | 
						||
      add_field("Codice fiscale del CAAF",                 'N',732, 11);
 | 
						||
      add_field("Numero iscrizione all'albo",              'N',743,  5);
 | 
						||
      add_field("Codice fiscale Direttore Tecnico CAAF",   'A',748, 16); // 80
 | 
						||
      add_field("Casella controlli",                       'N',764,  1);
 | 
						||
      add_field("Dichiarazione non compilata",             'N',765,  1);
 | 
						||
      add_field("Dichiarazione non firmata",               'N',766,  1);
 | 
						||
      add_field("Dichiarazione incompleta",                'N',767,  1);
 | 
						||
      add_field("Altri casi 1",                            'N',768,  1);
 | 
						||
      add_field("Altri casi 2",                            'N',769,  1);
 | 
						||
      add_field("Dichiarazione smarrita",                  'N',770,  1);
 | 
						||
    }
 | 
						||
    else
 | 
						||
    {
 | 
						||
      add_field("Numero modulo",         'N',   80,  6); // 6
 | 
						||
      add_field("Campi non posizionali", 'A',   86, 24); // 7
 | 
						||
      add_field("Supporto magnetico",    'A', 3998,  1); // 8
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
TTracciato770::~TTracciato770()
 | 
						||
{
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TTracciati770
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
const TTracciato770& TTracciati770::tracciato(char tipo)
 | 
						||
{
 | 
						||
  const int pos = tipo-'A';
 | 
						||
  TTracciato770* trc = (TTracciato770*)_trc.objptr(pos);
 | 
						||
  if (trc == NULL)
 | 
						||
  {
 | 
						||
    trc = new TTracciato770(tipo);
 | 
						||
    _trc.add(trc, pos);
 | 
						||
  }
 | 
						||
  return *trc;
 | 
						||
}
 | 
						||
 | 
						||
TForm770& TTracciati770::form(const char* quadro, char& tipo, int& rpm)
 | 
						||
{
 | 
						||
  CHECK(quadro && *quadro == 'S' && quadro[1] != '\0', 
 | 
						||
        "Codice quadro non valido");
 | 
						||
 | 
						||
  const char* name;
 | 
						||
  switch(quadro[1])
 | 
						||
  {
 | 
						||
    case 'C': name = "77qc";  tipo = 'F'; rpm = 11; break;
 | 
						||
    case 'F': name = "77qd";  tipo = 'G'; rpm =  9; break;
 | 
						||
    case 'G': name = "77qdb"; tipo = 'G'; rpm =  9; break;
 | 
						||
    case 'H': name = "77qd1"; tipo = 'G'; rpm =  9; break;
 | 
						||
    case 'K': name = "77qsk"; tipo = 'G'; rpm = 31; break;
 | 
						||
    case 'L': name = "77ql";  tipo = 'G'; rpm = 22; break;
 | 
						||
    case 'P': name = "77qe";  tipo = 'G'; rpm = 14; break;
 | 
						||
    case 'Q': name = "77qe1"; tipo = 'G'; rpm = 15; break;
 | 
						||
    default : name = NULL; break;
 | 
						||
  }
 | 
						||
 | 
						||
  TForm770* frm = (TForm770*)_form.objptr(name);
 | 
						||
  if (frm == NULL)
 | 
						||
  {
 | 
						||
    frm = new TForm770(name);
 | 
						||
    _form.add(name, frm);
 | 
						||
  }
 | 
						||
 | 
						||
  return *frm;
 | 
						||
}
 | 
						||
 | 
						||
void TTracciati770::destroy()
 | 
						||
{
 | 
						||
  _trc.destroy();
 | 
						||
  _form.destroy();
 | 
						||
}
 | 
						||
 | 
						||
TTracciati770::TTracciati770()
 | 
						||
{
 | 
						||
}
 | 
						||
 
 | 
						||
TTracciati770::~TTracciati770()
 | 
						||
{
 | 
						||
  destroy();   // Non viene mai chiamato!
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TCache770
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
const TRectype& TCache770::get(int num, const char* key)
 | 
						||
{
 | 
						||
  TRecord_cache* rc = (TRecord_cache*)_files.objptr(num);
 | 
						||
  if (rc == NULL)
 | 
						||
  {
 | 
						||
    rc = new TRecord_cache(num);
 | 
						||
    _files.add(rc, num);
 | 
						||
  }
 | 
						||
  return rc->get(key);
 | 
						||
}
 | 
						||
 | 
						||
const TRectype& TCache770::get(int num, long key)
 | 
						||
{
 | 
						||
  TString16 str; str << key;
 | 
						||
  return get(num, str);
 | 
						||
}
 | 
						||
 | 
						||
void TCache770::destroy()
 | 
						||
{
 | 
						||
  _files.destroy();
 | 
						||
  _tables.destroy();
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TRecord770
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
void TRecord770::print_on(ostream& outs) const
 | 
						||
{
 | 
						||
  outs.write(_buffer, TOTAL_SIZE);
 | 
						||
}
 | 
						||
 | 
						||
void TRecord770::read_from(istream& ins)
 | 
						||
{
 | 
						||
  _buffer.fill(' ', TOTAL_SIZE);
 | 
						||
  ins.read(_buffer.get_buffer(), TOTAL_SIZE);
 | 
						||
}
 | 
						||
 | 
						||
void TRecord770::set(const TField770& fld, const char* val)
 | 
						||
{
 | 
						||
  TString80 str(val); str.upper();
 | 
						||
  int lenstr = str.len();
 | 
						||
  if (lenstr > fld._len)
 | 
						||
  {
 | 
						||
#ifdef DBG
 | 
						||
    NFCHECK("Campo troppo lungo: %s (max. %d)", val, fld._len);
 | 
						||
#endif
 | 
						||
    str.cut(lenstr = fld._len);
 | 
						||
  }
 | 
						||
  if (lenstr != fld._len)
 | 
						||
  {
 | 
						||
    str.trim();
 | 
						||
    if (fld._type == 'N')
 | 
						||
      str.right_just(fld._len);
 | 
						||
    else
 | 
						||
      str.left_just(fld._len);
 | 
						||
  }
 | 
						||
  _buffer.overwrite(str, fld._pos-1);
 | 
						||
}
 | 
						||
 | 
						||
void TRecord770::set(int pos, const char* val)
 | 
						||
{
 | 
						||
  const TField770& fld = tracciato().field(pos);
 | 
						||
  set(fld, val);
 | 
						||
}
 | 
						||
 | 
						||
void TRecord770::set(int pos, int val)
 | 
						||
{
 | 
						||
  const TField770& fld = tracciato().field(pos);
 | 
						||
  CHECKD(fld._type == 'N', "Invalid numeric field ", pos);
 | 
						||
  TString16 str; str.format("%d", val);
 | 
						||
  set(fld, str);
 | 
						||
}
 | 
						||
 | 
						||
void TRecord770::set(int pos, long val)
 | 
						||
{
 | 
						||
  const TField770& fld = tracciato().field(pos);
 | 
						||
  CHECKD(fld._type == 'N', "Invalid numeric field ", pos);
 | 
						||
  TString16 str; str.format("%ld", val);
 | 
						||
  set(fld, str);
 | 
						||
}
 | 
						||
 | 
						||
void TRecord770::set(int pos, const real& val)
 | 
						||
{
 | 
						||
  const TField770& fld = tracciato().field(pos);
 | 
						||
  CHECKD(fld._type == 'N', "Invalid numeric field ", pos);
 | 
						||
  const char* str = val.string(fld._len, 0);
 | 
						||
  set(fld, str);
 | 
						||
}
 | 
						||
 | 
						||
void TRecord770::set(int pos, const TDate& val)
 | 
						||
{
 | 
						||
  const TField770& fld = tracciato().field(pos);
 | 
						||
  CHECKD(fld._type == 'N' && (fld._len == 6 || fld._len == 8), 
 | 
						||
         "Invalid date field ", pos);
 | 
						||
  const char* str;
 | 
						||
  if (fld._len == 8)
 | 
						||
    str = val.string(full, '\0', full, full, gma_date);
 | 
						||
  else
 | 
						||
    str = val.string(brief, '\0', full, full, gma_date);
 | 
						||
  set(fld, str);
 | 
						||
}
 | 
						||
 | 
						||
void TRecord770::set(int pos, char val)
 | 
						||
{
 | 
						||
  const TField770& fld = get_field(pos);
 | 
						||
  CHECKD(fld._type == 'A' && fld._len == 1, 
 | 
						||
         "Invalid char field ", pos);
 | 
						||
  const char str[2] = { val, '\0' };
 | 
						||
  set(fld, str);
 | 
						||
}
 | 
						||
 | 
						||
void TRecord770::set(int pos, bool val)
 | 
						||
{
 | 
						||
  const TField770& fld = get_field(pos);
 | 
						||
  CHECKD(fld._type == 'N' && fld._len == 1, 
 | 
						||
         "Invalid boolean field ", pos);
 | 
						||
  const char str[2] = { val ? '1' : '0', '\0' };
 | 
						||
  set(fld, str);
 | 
						||
}
 | 
						||
 | 
						||
const char* TRecord770::get(int pos, TString& str) const
 | 
						||
{
 | 
						||
  const TField770& fld = get_field(pos);
 | 
						||
  str = _buffer.mid(fld._pos-1, fld._len);
 | 
						||
  return str.trim();
 | 
						||
}
 | 
						||
 | 
						||
int TRecord770::get_int(int pos) const
 | 
						||
{
 | 
						||
  TString16 str; get(pos, str);
 | 
						||
  return atoi(str);
 | 
						||
}
 | 
						||
 | 
						||
char TRecord770::get_char(int pos) const
 | 
						||
{
 | 
						||
  const TField770& fld = get_field(pos);
 | 
						||
  CHECKD(fld._type == 'A', "Invalid char field ", pos);
 | 
						||
  return _buffer[fld._pos-1];
 | 
						||
}
 | 
						||
 | 
						||
// Calcola i blocchi necessari per contenere la stringa val
 | 
						||
int TRecord770::calculate_blocks(const char* val) const
 | 
						||
{
 | 
						||
  // Il primo blocco contiene 16 caratteri, 
 | 
						||
  // gli altri solo 15 perche' c'e' anche il +
 | 
						||
  int blocks = 1;
 | 
						||
  const int len = strlen(val);
 | 
						||
  if (len > 16)
 | 
						||
    blocks += (len-17) / 15 + 1;
 | 
						||
  return blocks;
 | 
						||
}
 | 
						||
 | 
						||
// Azzera tutti i campi non posizionali dei record di tipo F, G  e H
 | 
						||
void TRecord770::azzera_campi_non_posizionali()
 | 
						||
{
 | 
						||
  CHECK(strchr("FGH", tipo_record()) != NULL, 
 | 
						||
        "Impossibile azzerare un record senza campi non posizionali");
 | 
						||
  char* buf = _buffer.get_buffer() + 85;
 | 
						||
  memset(buf, ' ', TOTAL_SIZE-88);
 | 
						||
}
 | 
						||
 | 
						||
// Aggiunge un campo non posizionale ai record di tipo F, G  e H
 | 
						||
bool TRecord770::add(const char* code, const char* val)
 | 
						||
{
 | 
						||
  CHECK(strchr("FGH", tipo_record()) != NULL, 
 | 
						||
        "Impossibile aggiungere campi non posizionali");
 | 
						||
  CHECKS(code && strlen(code) == 8, "Invalid field code ", code);
 | 
						||
  CHECKS(val && *val, "Can't add empty field ", code);
 | 
						||
  
 | 
						||
  // Cerca il primo posto libero
 | 
						||
  for (int pos = 85; pos < USEABLE_SIZE; pos += BLOCK_SIZE)
 | 
						||
  {
 | 
						||
    if (_buffer[pos] == ' ')
 | 
						||
      break;
 | 
						||
  }
 | 
						||
  const int free_blocks = (USEABLE_SIZE - pos) / BLOCK_SIZE;
 | 
						||
  const int needed_blocks = calculate_blocks(val);
 | 
						||
  const bool ok = free_blocks >= needed_blocks;
 | 
						||
 | 
						||
  if (ok)  // Se ci sono abbastanza blocchi liberi
 | 
						||
  {
 | 
						||
    TString80 str(val); str.upper();
 | 
						||
    const int lenstr = str.len();
 | 
						||
    for (int i = 0; i < lenstr; )
 | 
						||
    {
 | 
						||
      _buffer.overwrite(code, pos);
 | 
						||
      pos += 8;
 | 
						||
      if (i != 0)
 | 
						||
      {
 | 
						||
        _buffer.overwrite("+", pos);
 | 
						||
        pos++;
 | 
						||
      }
 | 
						||
      const int maxlen = 15 + (i == 0);
 | 
						||
      const TString& substr = str.mid(i, maxlen);
 | 
						||
      _buffer.overwrite(substr, pos);
 | 
						||
      pos += maxlen;
 | 
						||
      i += maxlen;
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
bool TRecord770::fill_persona(const TRectype& rec_anagr, int offset, int gap)
 | 
						||
{
 | 
						||
  TString16 key = rec_anagr.get(ANA_CODANAGR);
 | 
						||
  const TRectype& rec_anafis = _cache770.get(LF_ANAGFIS, key);
 | 
						||
  
 | 
						||
  set(0+offset, rec_anagr.get(ANA_RAGSOC).left(24));
 | 
						||
  set(1+offset, rec_anagr.get(ANA_RAGSOC).mid(30, 20));
 | 
						||
  if (gap)
 | 
						||
  {
 | 
						||
    offset += gap;
 | 
						||
    set(2+offset, rec_anafis.get_date(ANF_DATANASC));
 | 
						||
    set(3+offset, rec_anafis.get(ANF_SESSO));
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    set(2+offset, rec_anafis.get(ANF_SESSO));
 | 
						||
    set(3+offset, rec_anafis.get_date(ANF_DATANASC));
 | 
						||
  }
 | 
						||
  key = rec_anafis.get(ANF_COMNASC); 
 | 
						||
  if (key.not_empty())
 | 
						||
  {
 | 
						||
    key.insert(" |");
 | 
						||
    const TRectype& rec_comnasc = _cache770.get(LF_COMUNI, key);
 | 
						||
    set(4+offset, rec_comnasc.get(COM_DENCOM).left(40));
 | 
						||
    set(5+offset, rec_comnasc.get(COM_PROVCOM).left(2));
 | 
						||
  }
 | 
						||
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
bool TRecord770::fill_telefono(const TRectype& rec_anagr,int offset)
 | 
						||
{
 | 
						||
  TString80 key = rec_anagr.get(ANA_PTELRF);
 | 
						||
  if (key.not_empty()) key << '-';
 | 
						||
  key << rec_anagr.get(ANA_TELRF);
 | 
						||
  key.cut(13);
 | 
						||
  set(offset, key);
 | 
						||
  return key.not_empty();
 | 
						||
}
 | 
						||
 | 
						||
bool TRecord770::fill_comune(const TRectype& rec_anagr, 
 | 
						||
                             int whichcom, bool swapcap, int offset)
 | 
						||
{
 | 
						||
  bool use_comres;
 | 
						||
  if (whichcom < 0)
 | 
						||
    use_comres = rec_anagr.get(ANA_COMRF).empty();
 | 
						||
  else
 | 
						||
    use_comres = whichcom ? TRUE : FALSE;
 | 
						||
 | 
						||
  TString80 key = rec_anagr.get(use_comres ? ANA_COMRES : ANA_COMRF);
 | 
						||
  if (key.not_empty())
 | 
						||
  {
 | 
						||
    key.insert(" |");
 | 
						||
    const TRectype& rec_comres = _cache770.get(LF_COMUNI, key);
 | 
						||
    set(0+offset, rec_comres.get(COM_DENCOM).left(40));
 | 
						||
    set(1+offset, rec_comres.get(COM_PROVCOM).left(2));
 | 
						||
 | 
						||
    key = rec_anagr.get(use_comres ? ANA_INDRES : ANA_INDRF);
 | 
						||
    if (key.not_empty()) key << ',';
 | 
						||
    key << rec_anagr.get(use_comres ? ANA_CIVRES : ANA_CIVRF);
 | 
						||
    key.cut(35);
 | 
						||
    if (swapcap)
 | 
						||
    {
 | 
						||
      set(3+offset, key);
 | 
						||
      set(2+offset, rec_anagr.get(use_comres ? ANA_CAPRES : ANA_CAPRF));
 | 
						||
    }
 | 
						||
    else
 | 
						||
    {
 | 
						||
      set(2+offset, key);
 | 
						||
      set(3+offset, rec_anagr.get(use_comres ? ANA_CAPRES : ANA_CAPRF));
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  return key.not_empty();
 | 
						||
}
 | 
						||
 | 
						||
bool TRecord770::fill_residenza(const TRectype& rec_anagr, int offset, 
 | 
						||
                                int whichcom, bool swapcap)
 | 
						||
{
 | 
						||
  bool use_comres;
 | 
						||
  if (whichcom < 0)
 | 
						||
    use_comres = rec_anagr.get(ANA_COMRF).empty();
 | 
						||
  else
 | 
						||
    use_comres = whichcom ? TRUE : FALSE;
 | 
						||
 | 
						||
  const TDate data_var_df = rec_anagr.get(use_comres ? ANA_DVARSLORES : ANA_DVARDF);
 | 
						||
 | 
						||
  set(0+offset, data_var_df.month());
 | 
						||
  set(1+offset, data_var_df.year() % 100);
 | 
						||
  return fill_comune(rec_anagr, whichcom, swapcap, 2+offset);
 | 
						||
}
 | 
						||
 | 
						||
bool TRecord770::fill_e(const TRectype& rec)
 | 
						||
{
 | 
						||
  TString80 key;  // Stringa multiuso
 | 
						||
 | 
						||
  tipo_record('E');
 | 
						||
  
 | 
						||
  key = rec.get(BSE_CODDIC);
 | 
						||
  if (key.empty())
 | 
						||
    key = rec.get(BSE_CODDITTA);
 | 
						||
 | 
						||
  const TRectype& rec_nditte = _cache770.get(LF_NDITTE, key);
 | 
						||
  if (rec_nditte.empty()) 
 | 
						||
    return error_box("Non esiste la ditta %s", (const char*)key);
 | 
						||
  
 | 
						||
  const char tipoa = rec_nditte.get_char(NDT_TIPOA);
 | 
						||
  const long codan = rec_nditte.get_long(NDT_CODANAGR);
 | 
						||
 | 
						||
  key.cut(0);
 | 
						||
  key << tipoa << '|' << rec_nditte.get(NDT_CODANAGR);
 | 
						||
  const TRectype& rec_anagr = _cache770.get(LF_ANAG, key);
 | 
						||
  if (rec_anagr.empty()) 
 | 
						||
    return error_box("Non esiste la persona %s", (const char*)key);
 | 
						||
 | 
						||
  set(3, rec_anagr.get(ANA_COFI));  //  Codice fiscale del dichiarante
 | 
						||
  
 | 
						||
  if (tipoa == 'F')
 | 
						||
  {
 | 
						||
    fill_persona(rec_anagr, 9, 2);             // 9 - 16
 | 
						||
    fill_residenza(rec_anagr, 17, -1, FALSE);  // 17 - 22
 | 
						||
    set(23, rec_nditte.get(NDT_CODATTPREV));
 | 
						||
    fill_telefono(rec_anagr, 24);
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    set(9, rec_anagr.get(ANA_RAGSOC));
 | 
						||
    fill_residenza(rec_anagr, 25, 1, FALSE);
 | 
						||
    fill_residenza(rec_anagr, 31, 0, FALSE);
 | 
						||
 | 
						||
    set(37, rec_nditte.get(NDT_CODATTPREV));
 | 
						||
 | 
						||
    const TRectype& rec_anagiu = _cache770.get(LF_ANAGGIU, codan);
 | 
						||
    set(38, rec_anagiu.get(ANG_STATOSOC));
 | 
						||
    set(39, rec_anagiu.get(ANG_NATGIU));
 | 
						||
    set(40, rec_anagiu.get(ANG_SITSOC));
 | 
						||
 | 
						||
    fill_telefono(rec_anagr, 41);
 | 
						||
  }
 | 
						||
 | 
						||
  // Rappresentante
 | 
						||
  key = rec_nditte.get(NDT_RAPPR);
 | 
						||
  if (key.not_empty())
 | 
						||
  {
 | 
						||
    key.insert("F|");
 | 
						||
    const TRectype& rec_anagr = _cache770.get(LF_ANAG, key);
 | 
						||
    if (!rec_anagr.empty()) 
 | 
						||
    {
 | 
						||
      set(42, rec_anagr.get(ANA_COFI));   //  Codice fiscale del dichiarante
 | 
						||
      fill_persona(rec_anagr, 44, 0);     // 44- 49
 | 
						||
      fill_comune(rec_anagr, -1, TRUE, 50);
 | 
						||
      fill_telefono(rec_anagr, 54);
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  TDecoder basebis(LF_BASEBIS, BSE_QCOMP);
 | 
						||
  key = rec.get(BSE_TIPOQUA);
 | 
						||
  key << '|' << rec.get(BSE_CODDITTA);
 | 
						||
  key = basebis.decode(key);
 | 
						||
  key.left_just(21);
 | 
						||
  for (int q = 0; q < 21; q++)
 | 
						||
  {
 | 
						||
    const bool yes = key[q] > ' ';
 | 
						||
    set(55+q, yes);
 | 
						||
  }
 | 
						||
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
// Assegna un rectype (serve solo per il quadro base)
 | 
						||
bool TRecord770::fill(const TRectype& rec)
 | 
						||
{
 | 
						||
  bool ok = FALSE;
 | 
						||
  switch(rec.num())
 | 
						||
  {
 | 
						||
  case LF_BASE: ok = fill_e(rec); break;
 | 
						||
  default: NFCHECK("Unsupported record assignment"); break;
 | 
						||
  }
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
bool TRecord770::valid() const
 | 
						||
{
 | 
						||
  char tipo = tipo_record();
 | 
						||
  bool ok = (tipo > ' ') && (strchr("AEFGHZ", tipo) != NULL);
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
TRecord770::TRecord770() : _buffer(TOTAL_SIZE, ' ')
 | 
						||
{
 | 
						||
}
 | 
						||
 | 
						||
TRecord770::TRecord770(char tipo) : _buffer(TOTAL_SIZE, ' ')
 | 
						||
{
 | 
						||
  tipo_record(tipo);
 | 
						||
}
 | 
						||
 | 
						||
TRecord770::TRecord770(const TRecord770& rec) : _buffer(rec._buffer)
 | 
						||
{ }
 | 
						||
 | 
						||
TRecord770::TRecord770(const TRectype& rec)
 | 
						||
{ fill(rec); }
 | 
						||
 | 
						||
TRecord770::~TRecord770()
 | 
						||
{ }
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TTrasferimento770
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
bool TTrasferimento770::open(const char* path, char mode)
 | 
						||
{
 | 
						||
  CHECK(mode == 'r' || mode == 'w', "Invalid open mode");
 | 
						||
  close();
 | 
						||
 | 
						||
  if (path && *path)
 | 
						||
  {
 | 
						||
    _name = path;
 | 
						||
    _name.add(default_name());
 | 
						||
  }
 | 
						||
  if (_name.empty())
 | 
						||
    _name = default_name();
 | 
						||
  if (mode == 'r')
 | 
						||
    _in_stream = new ifstream(_name, ios::in | ios::nocreate | ios::binary);
 | 
						||
  else
 | 
						||
    _out_stream = new ofstream(_name, ios::out | ios::binary);
 | 
						||
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
bool TTrasferimento770::close()
 | 
						||
{
 | 
						||
  if (_in_stream)
 | 
						||
  {
 | 
						||
    delete _in_stream;
 | 
						||
    _in_stream = NULL;
 | 
						||
  }
 | 
						||
  if (_out_stream)
 | 
						||
  {
 | 
						||
    delete _out_stream;
 | 
						||
    _out_stream = NULL;
 | 
						||
  }
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
bool TTrasferimento770::write(const TRecord770& rec)
 | 
						||
{
 | 
						||
  bool ok = _out_stream != NULL;
 | 
						||
  if (ok)
 | 
						||
    (*_out_stream) << rec;
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
bool TTrasferimento770::read(TRecord770& rec)
 | 
						||
{
 | 
						||
  bool ok = _in_stream != NULL && !_in_stream->eof(); 
 | 
						||
  if (ok)
 | 
						||
  {
 | 
						||
    (*_in_stream) >> rec;
 | 
						||
    ok = rec.valid();
 | 
						||
  }
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
long TTrasferimento770::append_quadro(const char* quadro, long codditta,
 | 
						||
                                      TProgind& pi)
 | 
						||
{
 | 
						||
  TString80 str;
 | 
						||
  str << "Trasferimento quadro " << quadro << " ditta " << codditta;
 | 
						||
  pi.set_text(str);
 | 
						||
  
 | 
						||
  char tipo;
 | 
						||
  int rpm;
 | 
						||
  TForm770& frm = _trc770.form(quadro, tipo, rpm);
 | 
						||
  long items = frm.trasfer(codditta, *this, tipo, rpm);
 | 
						||
  return items;
 | 
						||
}
 | 
						||
 | 
						||
bool TTrasferimento770::split(const char* path)
 | 
						||
{
 | 
						||
  close();
 | 
						||
 | 
						||
  long totale[4]; memset(totale, 0, sizeof(totale));
 | 
						||
  long records = fsize(_name) / TOTAL_SIZE;
 | 
						||
 | 
						||
  TRecord770 rec;
 | 
						||
 | 
						||
  if (records > 0)
 | 
						||
  {
 | 
						||
    open("", 'r');
 | 
						||
    TProgind pi(records, "Conteggio records da trasferire", FALSE, TRUE);
 | 
						||
    while (read(rec))
 | 
						||
    {
 | 
						||
      pi.addstatus(1);
 | 
						||
      const int pos = rec.tipo_record() - 'E';
 | 
						||
      if (pos >= 0 && pos < 4)
 | 
						||
        totale[pos]++;
 | 
						||
    }
 | 
						||
    records = totale[0]+totale[1]+totale[2]+totale[3];
 | 
						||
  }
 | 
						||
  else
 | 
						||
    return FALSE;
 | 
						||
 | 
						||
  long records_per_disk = 0;
 | 
						||
  int volumes = 1;
 | 
						||
  const bool magnetic = ::os_is_removable_drive(path);
 | 
						||
  if (magnetic)
 | 
						||
  {
 | 
						||
    if (!yesno_box("Inserire il primo disco del trasferimento nell'unita' %s\n"
 | 
						||
                   "Tutti i dischi devono essere vuoti ed avere la stesso formato.\n"
 | 
						||
                   "Si desidera iniziare il trasferimento?", path))
 | 
						||
      return FALSE;
 | 
						||
 | 
						||
    unsigned long disk_size = ::os_get_disk_size(path);
 | 
						||
    records_per_disk = long(disk_size / TOTAL_SIZE - 2);
 | 
						||
    volumes = int((records-1)/records_per_disk)+1;
 | 
						||
  }
 | 
						||
 | 
						||
  TProgind pi(records, "Trasferimento records", FALSE, TRUE);
 | 
						||
 | 
						||
  // Read from start
 | 
						||
  open("", 'r');
 | 
						||
 | 
						||
  for (int volume = 1; volume <= volumes; volume++)
 | 
						||
  {
 | 
						||
    if (magnetic && volume > 1)
 | 
						||
    {
 | 
						||
      if (!yesno_box("Inserire il disco %d di %d:\n"
 | 
						||
                     "Si desidera proseguire il trasferimento?",
 | 
						||
                     volume, volumes))
 | 
						||
      {
 | 
						||
        break;
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    TTrasferimento770 outfile(path, 'w');
 | 
						||
 | 
						||
    // Compila record di testata
 | 
						||
    rec.tipo_record('A');
 | 
						||
    if (magnetic)
 | 
						||
    {
 | 
						||
      rec.set(4, volumes);
 | 
						||
      rec.set(5, volume);
 | 
						||
    }
 | 
						||
    const TDate data_emissione(TODAY);
 | 
						||
    rec.set(6, data_emissione);
 | 
						||
    rec.set(7, "77098");
 | 
						||
    rec.set_magnetic_support(magnetic);
 | 
						||
    outfile << rec;  // Scrive record testata
 | 
						||
 | 
						||
    // Azzera totali
 | 
						||
    memset(totale, 0, sizeof(totale));
 | 
						||
    long written = 0;
 | 
						||
 | 
						||
    while (read(rec))
 | 
						||
    {
 | 
						||
      const char tipo_rec = rec.tipo_record();
 | 
						||
      if (tipo_rec == 'A' || tipo_rec == 'Z')
 | 
						||
        continue;
 | 
						||
 | 
						||
      const int pos = tipo_rec - 'E';
 | 
						||
      if (pos >= 0 && pos < 4)
 | 
						||
      {
 | 
						||
        rec.set_magnetic_support(magnetic);
 | 
						||
        outfile << rec;
 | 
						||
        totale[pos]++;
 | 
						||
        written++;
 | 
						||
        pi.addstatus(1);
 | 
						||
      }
 | 
						||
      else
 | 
						||
        error_box("Tipo record non riconosciuto: %c", tipo_rec);
 | 
						||
 | 
						||
      if (magnetic && written > records_per_disk)
 | 
						||
        break;
 | 
						||
    }
 | 
						||
 | 
						||
    // Compila record di coda
 | 
						||
    rec.tipo_record('Z');
 | 
						||
    if (magnetic)
 | 
						||
    {
 | 
						||
      rec.set(4, volumes);
 | 
						||
      rec.set(5, volume);
 | 
						||
      rec.set_magnetic_support(magnetic);
 | 
						||
    }
 | 
						||
    rec.set(6, data_emissione);
 | 
						||
    rec.set(7, "77098");
 | 
						||
    rec.set(8, written);
 | 
						||
    for (int r = 0; r < 4; r++)
 | 
						||
      rec.set(10+r, totale[r]);
 | 
						||
 | 
						||
    // Scrive record di coda
 | 
						||
    outfile << rec;
 | 
						||
  }
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
// Cancella il file
 | 
						||
void TTrasferimento770::remove()
 | 
						||
{
 | 
						||
  close();
 | 
						||
  ::remove(_name);
 | 
						||
}
 | 
						||
 | 
						||
TTrasferimento770::TTrasferimento770(const char* path, char  mode)
 | 
						||
: _in_stream(NULL), _out_stream(NULL)
 | 
						||
{
 | 
						||
  open(path, mode);
 | 
						||
}
 | 
						||
 | 
						||
TTrasferimento770::~TTrasferimento770()
 | 
						||
{
 | 
						||
  close();
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// main
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
HIDDEN int anno_dic()
 | 
						||
{
 | 
						||
  TConfig ini(CONFIG_STUDIO);
 | 
						||
  return ini.get_int("AnnoDic");
 | 
						||
}
 | 
						||
 | 
						||
class TTransfer770_msk : public TAutomask
 | 
						||
{
 | 
						||
protected:
 | 
						||
  virtual bool on_field_event(TOperable_field& of, TField_event fe, long jolly);
 | 
						||
 | 
						||
public:
 | 
						||
  TTransfer770_msk();
 | 
						||
  virtual ~TTransfer770_msk() { }
 | 
						||
};
 | 
						||
 | 
						||
bool TTransfer770_msk::on_field_event(TOperable_field& of, TField_event fe, long jolly)
 | 
						||
{
 | 
						||
  switch (of.dlg())
 | 
						||
  {
 | 
						||
  case F_PATH:
 | 
						||
    if (fe == fe_modify || fe == fe_close)
 | 
						||
    {
 | 
						||
      TFilename name = of.get();
 | 
						||
      if (!name.exist())
 | 
						||
        return error_box("Il percorso non e' valido");
 | 
						||
    }
 | 
						||
    break;
 | 
						||
  default:
 | 
						||
    break;
 | 
						||
  }
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
TTransfer770_msk::TTransfer770_msk() : TAutomask("777100a") 
 | 
						||
{ 
 | 
						||
  set(F_ANNO, anno_dic());
 | 
						||
}
 | 
						||
 | 
						||
class TTransfer770_app : public TSkeleton_application
 | 
						||
{
 | 
						||
protected:
 | 
						||
  virtual void main_loop();
 | 
						||
};
 | 
						||
 | 
						||
void TTransfer770_app::main_loop()
 | 
						||
{
 | 
						||
  TTransfer770_msk m;
 | 
						||
 | 
						||
  while (m.run() == K_ENTER)
 | 
						||
  {
 | 
						||
    TFilename tmp; tmp.tempdir();
 | 
						||
    TTrasferimento770 t(tmp, 'w');
 | 
						||
    TRecord770 rec;
 | 
						||
 | 
						||
    TRelation rel_base(LF_BASE);
 | 
						||
    TRectype da_rec(LF_BASE), a_rec(LF_BASE);
 | 
						||
    da_rec.put(BSE_CODDITTA, m.get(F_DADITTA));
 | 
						||
    a_rec.put(BSE_CODDITTA, m.get(F_ADITTA));
 | 
						||
 | 
						||
    TString filter;
 | 
						||
    filter << "ANNODIC=" << anno_dic();
 | 
						||
    TCursor cur_base(&rel_base, filter, 1, &da_rec, &a_rec);
 | 
						||
    
 | 
						||
    TProgind pi(cur_base.items(), "Generazione file di trasferimento", FALSE, TRUE);
 | 
						||
    cur_base.freeze();
 | 
						||
    for (cur_base = 0; cur_base.ok(); ++cur_base)
 | 
						||
    {
 | 
						||
      const TRectype& base = cur_base.curr();
 | 
						||
      const long codditta = base.get_long(BSE_CODDITTA);
 | 
						||
      pi.addstatus(1);
 | 
						||
 | 
						||
      rec = base;
 | 
						||
      t << rec;    // Append quadro base
 | 
						||
 | 
						||
      t.append_quadro("SC", codditta, pi);
 | 
						||
      t.append_quadro("SF", codditta, pi);
 | 
						||
      t.append_quadro("SG", codditta, pi);
 | 
						||
      t.append_quadro("SH", codditta, pi);
 | 
						||
      t.append_quadro("SK", codditta, pi);
 | 
						||
      t.append_quadro("SL", codditta, pi);
 | 
						||
      t.append_quadro("SP", codditta, pi);
 | 
						||
      t.append_quadro("SQ", codditta, pi);
 | 
						||
    }
 | 
						||
    pi.close_modal();
 | 
						||
 | 
						||
    if (m.get(F_SUPPORTO) == "D")
 | 
						||
      tmp = m.get(F_DISK);
 | 
						||
    else
 | 
						||
      tmp = m.get(F_PATH);
 | 
						||
 | 
						||
    t.split(tmp);
 | 
						||
    t.remove();
 | 
						||
  }
 | 
						||
 | 
						||
  _trc770.destroy();
 | 
						||
}
 | 
						||
 | 
						||
int m777100(int argc, char* argv[])
 | 
						||
{
 | 
						||
  TTransfer770_app app;
 | 
						||
  app.run(argc, argv, "Invio");
 | 
						||
  return 0;
 | 
						||
}
 | 
						||
 |