campo-sirio/in/inlib01.cpp
guy 6a84387e62 Semplificazione nomenclatura combinata da tre ad un solo campo
git-svn-id: svn://10.65.10.50/branches/R_10_00@23138 c028cbd2-c16b-5b4b-a496-9718f37d4682
2015-11-30 16:16:40 +00:00

710 lines
19 KiB
C++
Executable File
Raw Blame History

#include <currency.h>
#include <diction.h>
#include <prefix.h>
#include <progind.h>
#include <recarray.h>
#include <recset.h>
#include <relation.h>
#include "inlib01.h"
#include "in0500a.h"
#include "../cg/cgsaldac.h"
#include <mov.h>
///////////////////////////////////////////////////////////
// TIntra_frequency
///////////////////////////////////////////////////////////
char TIntra_frequency::frequenza(int a, char t) const
{
switch (t)
{
case 'A': break;
case 'C': break;
case 'B': t = 'A'; break; // Rettifiche su Acquisti
case 'D': t = 'C'; break; // Rettifiche su Cessioni
default : break;
}
const TDate d(TODAY);
if (a <= 0)
a = d.year();
if (a < d.year())
{
TLocalisamfile riep(LF_RIEPRETT);
riep.put("TIPO", t);
riep.put("ANNO", a);
if (riep.read(_isgteq) == NOERR)
{
if (riep.get_char("TIPO") == t && riep.get_int("ANNO") == a)
{
const char freq = riep.get_char("FREQUENZA");
if (freq > ' ')
return freq;
}
}
}
return (t == 'A') ? _freq_acq : _freq_ces;
}
int TIntra_frequency::date2periodo(const TDate& d, char tipo) const
{
const char freq = frequenza(d.year(), tipo);
if (freq == 'A')
return 1;
const int month = d.month();
if (freq == 'T')
return (month / 3) + 1;
return month;
}
int TIntra_frequency::compare_periodo(const TDate& dtcomp, const TDate& dtreg, char tipo) const
{
int cmp = dtcomp.year() - dtreg.year();
if (cmp == 0)
{
const int pc = date2periodo(dtcomp, tipo);
const int pr = date2periodo(dtreg, tipo);
cmp = pc - pr;
}
return cmp;
}
void TIntra_frequency::update()
{
const long firm = prefix().get_codditta();
const TRectype& ditta = cache().get(LF_NDITTE, firm);
_freq_ces = ditta.get_char("FREQCES");
_freq_acq = ditta.get_char("FREQACQ");
if (_freq_ces <= ' ') _freq_ces = 'T';
if (_freq_acq <= ' ') _freq_acq = 'T';
}
TIntra_frequency::TIntra_frequency()
{
update();
}
///////////////////////////////////////////////////////////
// TIntra_mask
// Maschera generica con dati utili a tutte quelle intra
///////////////////////////////////////////////////////////
void TIntra_mask::on_firm_change()
{
if (is_running())
TAutomask::on_firm_change();
_freq.update();
}
short TIntra_mask::type_field() const
{
NFCHECK("Non <20> stato specificato il campo del tipo");
return DLG_NULL;
}
short TIntra_mask::period_field() const
{ return DLG_NULL; }
char TIntra_mask::tipo() const
{
short id = type_field();
char t = get(id)[0];
return t;
}
char TIntra_mask::frequenza(int a, char t) const
{
if (a <= 0)
a = anno();
if (t < 'A' || t > 'D')
t = tipo();
return _freq.frequenza(a, t);
}
int TIntra_mask::date2periodo(const TDate& d) const
{ return _freq.date2periodo(d, tipo()); }
const char* TIntra_mask::periodo_str() const
{
const short id = period_field();
const char* pe = "01";
if (id != DLG_NULL)
{
switch(frequenza(anno()))
{
case 'M': pe = get(id); break;
case 'T': pe = get(id+1); break;
default : break;
}
}
else
NFCHECK("Non e' stato specificato il campo del periodo");
return pe;
}
int TIntra_mask::periodo() const
{
return atoi(periodo_str());
}
bool TIntra_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
if (jolly == 0 && o.dlg() == type_field())
{
if (e == fe_modify || e == fe_init)
{
const short id = period_field();
if (id != DLG_NULL)
{
const char freq = frequenza(anno());
show(id+0, freq == 'M');
show(id+1, freq == 'T');
show(id+2, freq == 'A');
}
}
}
return true;
}
TIntra_mask::TIntra_mask(const char* name)
: TAutomask(name)
{
on_firm_change();
}
///////////////////////////////////////////////////////////
// TDati_riepilogo
///////////////////////////////////////////////////////////
class TDati_riepilogo : public TSortable
{
TToken_string _key;
TCurrency _ammlire, _ammvaluta;
real _valstat, _massakg, _massaums;
long _numreg;
protected:
virtual TObject* dup() const { return new TDati_riepilogo(*this); }
virtual int compare(const TSortable& s) const;
public:
TDati_riepilogo& operator +=(const TDati_riepilogo& r);
void write(TRectype& rec) const;
const TString& stato(TString& c) const { _key.get(0, c); return c; }
const TString& partita_iva(TString& c) const { _key.get(1, c); return c; }
const TString& natura(TString& c) const { _key.get(3, c); return c; }
const TString& nomenclatura(TString& c) const { _key.get(4, c); return c; }
const TString& consegna(TString& c) const { _key.get(5, c); return c; }
const TString& trasporto(TString& c) const { _key.get(6, c); return c; }
const TString& paese(TString& c) const { _key.get(7, c); return c; }
const TString& paese_orig(TString& c) const { _key.get(8, c); return c; }
const TString& provincia(TString& c) const { _key.get(9, c); return c; }
TDati_riepilogo(const TDati_riepilogo& r);
TDati_riepilogo(const TToken_string& key, const TRectype& rec, const TString& codval);
virtual ~TDati_riepilogo() { }
};
int TDati_riepilogo::compare(const TSortable& s) const
{
const TDati_riepilogo& r = (const TDati_riepilogo&)s;
return _key.compare(r._key);
}
TDati_riepilogo& TDati_riepilogo::operator +=(const TDati_riepilogo& r)
{
_ammlire += r._ammlire;
_ammvaluta += r._ammvaluta;
_valstat += r._valstat;
_massakg += r._massakg;
_massaums += r._massaums;
return *this;
}
void TDati_riepilogo::write(TRectype& rec) const
{
TString str;
rec.put("STATO", stato(str));
rec.put("PIVA", partita_iva(str));
rec.put("NATURA", natura(str));
rec.put("NOMENCL", nomenclatura(str));
rec.put("CONSEGNA", consegna(str));
rec.put("TRASPORTO", trasporto(str));
rec.put("PAESE", paese(str));
rec.put("PAESEORIG", paese_orig(str));
rec.put("PROV", provincia(str));
rec.put("AMMLIRE", _ammlire.get_num());
if (_ammvaluta.is_zero() || _ammvaluta.is_firm_value())
{
rec.zero("CODVAL"); // Altrimenti genera falsi codici valuta EUR ...
rec.zero("AMMVALUTA"); // ... con importi nulli
}
else
{
rec.put("CODVAL", _ammvaluta.get_value());
rec.put("AMMVALUTA", _ammvaluta.get_num());
}
rec.put("VALSTAT", _valstat);
rec.put("MASSAKG", _massakg);
rec.put("MASSAUMS", _massaums);
rec.put("NUMREG", _numreg);
}
TDati_riepilogo::TDati_riepilogo(const TDati_riepilogo& r)
: _key(r._key), _valstat(r._valstat),
_ammlire(r._ammlire), _ammvaluta(r._ammvaluta),
_massakg(r._massakg), _massaums(r._massaums)
{ }
TDati_riepilogo::TDati_riepilogo(const TToken_string& key,
const TRectype& rec,
const TString& codval)
: _key(key), _ammlire(rec.get_real("AMMLIRE")),
_ammvaluta(rec.get_real("AMMVALUTA"), codval),
_valstat(rec.get_real("VALSTAT")),
_massakg(rec.get_real("MASSAKG")),
_massaums(rec.get_real("MASSAUMS")),
_numreg(rec.get_long("NUMREG"))
{ }
///////////////////////////////////////////////////////////
// TRiepiloghi
///////////////////////////////////////////////////////////
class TRiepiloghi : public TObject
{
TPointer_array _arr;
TAssoc_array _ass;
public:
void destroy() { _arr.destroy(); _ass.destroy(); }
void add(const TRectype& row, const TRectype& head, const TRectype& mov);
int items() const { return _arr.items(); }
int sort() { _arr.sort(); return items(); }
const TDati_riepilogo& operator[](int r) const
{ return (const TDati_riepilogo&)_arr[r]; }
};
void TRiepiloghi::add(const TRectype& row, const TRectype& head, const TRectype& mov)
{
TString8 cod; cod << head.get_char("TIPOCF") << '|' << head.get("CODCF");
const TRectype& clifo = cache().get(LF_CLIFO, cod);
TString4 codval = head.get("CODVAL");
if (::is_euro_value(codval))
codval.cut(0);
TToken_string key;
key.add(clifo.get("STATOPAIV"));
key.add(clifo.get("PAIV"));
key.add(codval); // Non e' chiaro se raggruppare per valuta!
key.add(row.get("NATURA"));
key.add(row.get("NOMENCL"));
key.add(row.get("CONSEGNA"));
key.add(row.get("TRASPORTO"));
key.add(row.get("PAESE"));
key.add(row.get("PAESEORIG")); // Campo solo per Acquisti
key.add(row.get("PROV"));
TDati_riepilogo* data = (TDati_riepilogo*)_ass.objptr(key);
if (data == NULL)
{
data = new TDati_riepilogo(key, row, codval);
_ass.add(key, data);
_arr.add(data);
}
else
{
const TDati_riepilogo dr(key, row, codval);
*data += dr;
}
}
class TRettifiche : public TObject
{
TArray _rett;
TIntra_frequency _freq;
protected:
long rett2riep(const TRectype& rett) const;
public:
int items() const { return _rett.items(); }
long nc2ft(long numreg_nc) const;
int add(const TRectype& rintra, const TRectype& mov, long nr_fattura);
int load_manual_rett(char tipo, int anno, int periodo);
int sort();
const TRectype& operator[](int r) const { return (const TRectype&)_rett[r]; }
};
long TRettifiche::nc2ft(long numreg_nc) const
{
long numreg_ft = 0L;
TPartite_array games;
games.add_numreg(numreg_nc); // Carica le partite in cui <20> coinvolta questa nota di credito (sempre e solo una!)
for (TPartita* p = games.first(); p != NULL && numreg_ft<=0; p = games.next())
{
#ifdef DBG
if (p->conto().codclifo() == 13201)
int farmoki = 1;
#endif
for (int r = p->prima_fattura(); r >= 0 && r <= p->last(); r = p->succ(r))
{
const TRiga_partite& partita = p->riga(r);
const tipo_movimento tm = partita.tipo();
if (tm == tm_fattura)
{
const long n = partita.get_long(PART_NREG);
if (n > 0 && n != numreg_nc) // Puo' succedere che n==numreg_nc con le fatture negative!
{
numreg_ft = n;
break;
}
}
}
}
return numreg_ft;
}
int TRettifiche::load_manual_rett(char tipo, int anno, int periodo)
{
_rett.destroy();
tipo = tipo < 'C' ? 'B' : 'D'; // forzatura tipo = B o D
TString query, filtro;
filtro << "TIPO=" << tipo << " ANNO=" << anno << " PERIODO=" << periodo;
query << "USE " << LF_RIEPRETT << " SELECT NUMREG=\"\"";
query << "\nFROM " << filtro;
query << "\nTO " << filtro;
TISAM_recordset rett(query);
for (bool good = rett.move_first(); good; good = rett.move_next())
_rett.add(rett.cursor()->curr());
return _rett.items();
}
long TRettifiche::rett2riep(const TRectype& rett) const
{
TString query, filter;
filter << "TIPO=" << (rett.get_char("TIPO")=='B' ? 'A' : 'C')
<< " ANNO=" << rett.get("ANNORETT") << " PERIODO=" << rett.get("PERETT");
query << "USE " << LF_RIEPRETT
<< "\nSELECT (NOMENCL='" << rett.get("NOMENCL") << "')&&(PIVA='" << rett.get("PIVA") << "')"
<< "\nFROM " << filter << "\nTO " << filter;
long nriga = 1;
TISAM_recordset rr(query);
if (rr.move_first())
nriga = rr.get("NUMRIG").as_int();
return nriga;
}
int TRettifiche::add(const TRectype& rintra, const TRectype& mov, long nr_fattura)
{
CHECKD(rintra.num() == LF_RINTRA, "Record non INTRA ", rintra.num());
const TDate datareg = mov.get(MOV_DATAREG);
TRectype rett(LF_RIEPRETT);
const char tipo = mov.get_char(MOV_TIPO)=='F' ? 'B' : 'D';
rett.put("TIPO", tipo);
rett.put("ANNO", datareg.year());
rett.put("PERIODO", _freq.date2periodo(datareg, tipo));
rett.put("NUMRIG", 0); // Auto
TString8 cod; cod << mov.get_char(MOV_TIPO) << '|' << mov.get(MOV_CODCF);
const TRectype& clifo = cache().get(LF_CLIFO, cod);
TString4 codval = mov.get("CODVALI");
if (::is_euro_value(codval))
codval.cut(0);
rett.put("STATO", clifo.get("STATOPAIV"));
rett.put("PIVA", clifo.get("PAIV"));
rett.put("NATURA", rintra.get("NATURA"));
rett.put("NOMENCL", rintra.get("NOMENCL"));
rett.put("CONSEGNA", rintra.get("CONSEGNA"));
rett.put("TRASPORTO", rintra.get("TRASPORTO"));
rett.put("PAESE", rintra.get("PAESE"));
if (tipo == 'B') // Campi solo per Acquisti
{
rett.put("PAESEORIG", rintra.get("PAESEORIG"));
rett.put("PROV", rintra.get("PROV"));
}
const real euri = rintra.get_real("AMMLIRE");
rett.put("AMMLIRE", abs(euri));
if (codval.full())
{
rett.put("CODVAL", codval);
rett.put("AMMVALUTA", abs(mov.get_real("CORRVALUTA")));
}
rett.put("SEGNORETT", euri>ZERO ? '+': '-');
rett.put("VALSTAT", abs(rintra.get_real("VALSTAT")));
rett.put("MASSAKG", rintra.get("MASSAKG"));
rett.put("MASSAUMS", rintra.get("MASSAUMS"));
rett.put("NUMREG", mov.get(MOV_NUMREG));
const TDate dt_fatt = cache().get(LF_MOV, nr_fattura, MOV_DATAREG);
rett.put("ANNORETT", dt_fatt.year());
rett.put("PERETT", _freq.date2periodo(dt_fatt, tipo));
rett.put("NUMRETT", rett2riep(rett));
return _rett.add(rett);
}
int TRettifiche::sort()
{
_rett.pack();
for (int i = 0; i < _rett.items(); i++)
{
TRectype* r = (TRectype*)_rett.objptr(i);
r->put("NUMRIG", i+1);
}
return _rett.items();
}
///////////////////////////////////////////////////////////
// TGenerazione_mask
///////////////////////////////////////////////////////////
class TGenerazione_mask : public TIntra_mask
{
TRiepiloghi _riep;
TRettifiche _rett;
protected:
virtual short type_field() const { return R_TIPO; }
virtual short period_field() const { return R_PERIODO_M; }
virtual int anno() const { return get_int(R_ANNO); }
public:
bool genera_riepiloghi();
TGenerazione_mask();
virtual ~TGenerazione_mask() { }
};
bool TGenerazione_mask::genera_riepiloghi()
{
const char tipo = get(R_TIPO)[0];
const int anno_r = anno();
const int peri = periodo();
const char freq = frequenza(anno_r, tipo);
TString msg;
msg.format(FR("Si sta per generare il riepilogo %s del periodo %d dell'anno %d."),
tipo == 'A' ? TR("acquisti") : TR("cessioni"), peri, anno_r);
if (is_riepilogo(tipo, anno_r, peri))
msg << TR("\nAttenzione questo riepilogo <20> gi<67> stato generato.\nSi desidera continuare ugualmente?");
else
msg << TR("\nSi desidera procedere?");
if (!yesno_box(msg))
return false;
_riep.destroy();
_rett.load_manual_rett(tipo+1, anno_r, peri);
int da_mese = peri, a_mese = peri;
switch (freq)
{
case 'T':
da_mese = (peri-1) * 3 + 1;
a_mese = da_mese+2;
break;
case 'A':
da_mese = 1; a_mese = 12;
break;
default:
da_mese = a_mese = peri;
break;
}
// Range delle date di competenza (o registrazione) intra
const TDate da_data(1, da_mese, anno_r);
const TDate a_data(TDate::last_day(a_mese, anno_r), a_mese, anno_r);
// Range delle date di registrazione intra
const TDate filtro_da_data(1, 1, anno_r-1);
const TDate filtro_a_data(31,12, anno_r+1);
TRectype filter_da(LF_INTRA), filter_a(LF_INTRA);
filter_da.put("DATAREG", filtro_da_data);
filter_a.put("DATAREG", filtro_a_data);
TRelation rel(LF_INTRA);
rel.add(LF_RINTRA, "NUMREG==NUMREG");
rel.add(LF_MOV, "NUMREG==NUMREG");
const TRectype& head = rel.curr(LF_INTRA);
const TRectype& row = rel.curr(LF_RINTRA);
const TRectype& mov = rel.curr(LF_MOV);
TString filter; filter << "TIPOMOV==\"" << tipo << '"';
TCursor cur(&rel, filter, 2, &filter_da, &filter_a); // Cursore ordinato per data
const long items = cur.items();
if (items > 0)
{
TProgress_monitor pi(items, TR("Lettura movimenti intra..."));
cur.freeze();
for (cur = 0; cur.pos() < items; ++cur)
{
if (!pi.add_status())
return warning_box(TR("Operazione annullata"));
const TDate datacomp = head.get_date(MOV_DATAREG);
if (datacomp >= da_data && datacomp <= a_data)
{
bool rowok = rel.is_first_match(LF_RINTRA);
while (rowok)
{
bool is_rettifica = false;
const tipo_movimento tm = (tipo_movimento)mov.get_int(MOV_TIPOMOV);
long numreg_ft = 0;
if (tm_nota_credito || (tm==tm_fattura && mov.get_real(MOV_TOTDOC) < ZERO))
{
const long numreg_nc = mov.get_long(MOV_NUMREG);
numreg_ft = _rett.nc2ft(numreg_nc);
if (numreg_ft > 0)
{
const TRectype& head_ft = cache().get(LF_MOV, numreg_ft);
const TDate data_ft = head_ft.get_date(MOV_DATAREG);
const int anno_ft = data_ft.year();
const int peri_ft = _freq.date2periodo(data_ft, tipo);
is_rettifica = anno_ft != anno_r || peri_ft != peri; // Rettifica solo se periodo diverso dalla fattura
}
}
if (is_rettifica)
_rett.add(row, mov, numreg_ft);
else
_riep.add(row, head, mov);
rowok = rel.next_match(LF_RINTRA);
}
}
}
}
else
return warning_box(TR("Non ci sono movimenti nel periodo specificato"));
TLocalisamfile riep(LF_RIEPRETT);
const int riepiloghi = _riep.sort();
if (riepiloghi > 0)
{
TProgress_monitor pi(riepiloghi, TR("Scrittura riepiloghi intra..."), false);
riep.put("TIPO", tipo);
riep.put("ANNO", anno_r);
riep.put("PERIODO", peri);
riep.put("NUMRIG", 1);
int err = riep.read();
for (int r = 0; r < riepiloghi; r++)
{
pi.add_status();
riep.put("TIPO", tipo);
riep.put("ANNO", anno_r);
riep.put("PERIODO", peri);
riep.put("NUMRIG", r+1);
_riep[r].write(riep.curr());
riep.put("FREQUENZA", freq);
const int werr = err == NOERR ? riep.rewrite() : riep.write();
if (werr != NOERR)
return error_box(FR("Errore %d durante la scrittura dei riepiloghi"), werr);
if (err == NOERR)
{
err = riep.next();
if (err == NOERR && riep.get_long("NUMRIG") == 1)
err = _iseof;
}
}
}
// Cancella eventuali altri riepiloghi del periodo
TString query;
query << "USE " << LF_RIEPRETT
<< "\nFROM TIPO=" << tipo << " ANNO=" << anno_r << " PERIODO=" << peri << " NUMRIG=" << long(riepiloghi+1)
<< "\nTO TIPO=" << tipo << " ANNO=" << anno_r << " PERIODO=" << peri;
TISAM_recordset riepset(query);
for (bool ok = riepset.move_first(); ok; ok = riepset.move_next())
riepset.cursor()->file().remove();
const int rettifiche = _rett.sort();
if (rettifiche > 0)
{
for (int r = 0; r < rettifiche; r++)
_rett[r].write_rewrite(riep);
}
// Cancella eventuali altre rettifiche del periodo
query.cut(0) << "USE " << LF_RIEPRETT
<< "\nFROM TIPO=" << char(tipo+1) << " ANNO=" << anno_r << " PERIODO=" << peri << " NUMRIG=" << long(rettifiche+1)
<< "\nTO TIPO=" << char(tipo+1) << " ANNO=" << anno_r << " PERIODO=" << peri;
TISAM_recordset rettset(query);
for (bool ok = rettset.move_first(); ok; ok = rettset.move_next())
rettset.cursor()->file().remove();
return true;
}
TGenerazione_mask::TGenerazione_mask()
: TIntra_mask("in0500b")
{ }
///////////////////////////////////////////////////////////
// Generazione riepiloghi
///////////////////////////////////////////////////////////
void genera_riepiloghi(char tipo, int anno, int periodo)
{
TGenerazione_mask m;
int num_fields = 0;
if (tipo > ' ' )
{
TString16 t; t << tipo;
m.set(R_TIPO, t);
num_fields++;
}
if (anno > 0)
{
m.set(R_ANNO, anno);
num_fields++;
}
if (periodo > 0)
{
m.set(R_PERIODO_M, periodo);
m.set(R_PERIODO_T, periodo);
num_fields++;
}
if (num_fields == 3 || m.run() == K_ENTER)
m.genera_riepiloghi();
}
bool is_riepilogo(char tipo, int anno, int periodo)
{
TLocalisamfile riep(LF_RIEPRETT);
riep.put("TIPO", tipo);
riep.put("ANNO", anno);
riep.put("PERIODO", periodo);
riep.put("NUMRIG", 1);
int err = riep.read();
return err == NOERR;
}