8ef1b107f0
Files correlati : cg2 Ricompilazione Demo : [ ] Commento : Migliorata lettura TBill da record git-svn-id: svn://10.65.10.50/trunk@20536 c028cbd2-c16b-5b4b-a496-9718f37d4682
520 lines
13 KiB
C++
Executable File
520 lines
13 KiB
C++
Executable File
#include "cg2101.h"
|
|
#include "cg2103.h"
|
|
|
|
#include <diction.h>
|
|
#include <tabutil.h>
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Movimento di prima nota
|
|
///////////////////////////////////////////////////////////
|
|
|
|
TMovimentoPN::TMovimentoPN()
|
|
: TRelation(LF_MOV), _cg(LF_RMOV, RMV_NUMRIG), _iva(LF_RMOVIVA, RMI_NUMRIG)
|
|
{
|
|
add(LF_RMOV, "NUMREG=NUMREG");
|
|
add(LF_RMOVIVA, "NUMREG=NUMREG");
|
|
}
|
|
|
|
void TMovimentoPN::destroy_rows(long num)
|
|
{
|
|
_cg.destroy_rows();
|
|
_cg.renum_key(RMV_NUMREG, num);
|
|
_iva.destroy_rows();
|
|
_iva.renum_key(RMI_NUMREG, num);
|
|
}
|
|
|
|
|
|
TRectype& TMovimentoPN::cg(int i)
|
|
{
|
|
return _cg.row(i >= 0 ? i+1 : -1, TRUE);
|
|
}
|
|
|
|
TRectype& TMovimentoPN::iva(int i)
|
|
{
|
|
return _iva.row(i >= 0 ? i+1 : -1, TRUE);
|
|
}
|
|
|
|
void TMovimentoPN::destroy_cg_row(int i)
|
|
{
|
|
if (i < 0)
|
|
_cg.destroy_rows();
|
|
else
|
|
_cg.destroy_row(i+1, TRUE);
|
|
}
|
|
|
|
void TMovimentoPN::destroy_iva_row(int i)
|
|
{
|
|
if (i < 0)
|
|
_iva.destroy_rows();
|
|
else
|
|
_iva.destroy_row(i+1, TRUE);
|
|
}
|
|
|
|
int TMovimentoPN::read_mov_rows()
|
|
{
|
|
const TRectype& mov = curr();
|
|
const long numreg = mov.get_long(MOV_NUMREG);
|
|
|
|
TRectype* cgfilter = new TRectype(LF_RMOV);
|
|
cgfilter->put(RMV_NUMREG, numreg);
|
|
_cg.read(cgfilter);
|
|
|
|
TRectype* ivafilter = new TRectype(LF_RMOVIVA);
|
|
ivafilter->put(RMI_NUMREG, numreg);
|
|
_iva.read(ivafilter);
|
|
|
|
/*
|
|
if (_cg.rows() > 0 && _iva.rows() > 0 && cg(0).get_char(RMV_ROWTYPE) != 'T')
|
|
adjust_row_types();
|
|
*/
|
|
return _cg.rows();
|
|
}
|
|
|
|
|
|
int TMovimentoPN::read(TIsamop op, TReclock lockop)
|
|
{
|
|
const int err = TRelation::read(op, lockop);
|
|
if (err == NOERR)
|
|
{
|
|
_olddataliq = file().get(MOV_DATAREG); // Memorizza data liquidazione
|
|
const int meseliq = file().get_int(MOV_MESELIQ);
|
|
if (meseliq > 0 && meseliq != _olddataliq.month())
|
|
{
|
|
_olddataliq.set_day(1); // Evita problemi coi mesi corti!
|
|
_olddataliq.set_month(meseliq);
|
|
}
|
|
|
|
read_mov_rows(); // Riempie i due record array
|
|
}
|
|
return err;
|
|
}
|
|
|
|
char TMovimentoPN::frequenza_versamenti(int year) const
|
|
{
|
|
static int last_year = 0;
|
|
static long last_firm = 0;
|
|
static char last_freq = ' ';
|
|
|
|
const long firm = prefix().get_codditta();
|
|
|
|
if (firm != last_firm || year != last_year)
|
|
{
|
|
TString16 key; key.format("%05ld%d", firm, year);
|
|
TTable lia("%LIA");
|
|
lia.put("CODTAB", key);
|
|
if (lia.read() != NOERR)
|
|
{
|
|
TLocalisamfile nditte(LF_NDITTE);
|
|
nditte.put("CODDITTA", firm);
|
|
nditte.read();
|
|
last_freq = nditte.get_char("FREQVIVA");
|
|
}
|
|
else
|
|
last_freq = lia.get_char("S7");
|
|
|
|
if (last_freq != 'M' && last_freq != 'T')
|
|
{
|
|
error_box(FR("La frequenza versamenti IVA per la ditta %ld\n"
|
|
"non e' valida: la si considera mensile."), firm);
|
|
last_freq = 'M';
|
|
}
|
|
|
|
last_firm = firm;
|
|
last_year = year;
|
|
}
|
|
|
|
return last_freq;
|
|
}
|
|
|
|
int TMovimentoPN::date2liq(const TDate& data) const
|
|
{
|
|
const int anno = data.year();
|
|
int mese = data.month();
|
|
if (frequenza_versamenti(anno) == 'T')
|
|
mese += 2 - ((mese-1) % 3);
|
|
return mese;
|
|
}
|
|
|
|
|
|
bool TMovimentoPN::controlla_liquidazione(const TDate& data, TRegistro& registro, bool reset) const
|
|
{
|
|
bool calcolata = false;
|
|
|
|
const int anno = data.year();
|
|
const int mese = date2liq(data);
|
|
|
|
// Chiave di LIM: Anno (1-4), Mese (5-6)
|
|
TString16 key; key.format("%04d%02d", anno, mese);
|
|
TTable lim("LIM");
|
|
lim.setkey(1);
|
|
lim.put("CODTAB", key);
|
|
if (lim.read() == NOERR)
|
|
{
|
|
calcolata = data.month() <= registro.mese_stampa_ultima_liq(); // Controlla se progressivi ricalcolati (registri)
|
|
|
|
if (reset)
|
|
{
|
|
// Resetta i flag di calcolato sulla liquidazione IVA del mese di registrazione
|
|
lim.zero("B0"); // calcolato
|
|
lim.zero("B1"); // progressivi ricalcolati
|
|
lim.rewrite();
|
|
}
|
|
}
|
|
|
|
if (reset)
|
|
{
|
|
const bool att_mista = registro.name().empty() ? FALSE : registro.attivita_mista();
|
|
const int att = att_mista ? 2 : 1;
|
|
|
|
// Chiave di PLM: Anno (1-4), Cod. Att. (5-9), Tipo att. (10-10), Mese (11-12)
|
|
TTable plm("PLM");
|
|
for (int a = 1; a <= att; a++)
|
|
{
|
|
TString16 chiave;
|
|
TString8 attivita(registro.attivita()); attivita.right_just(5, '0');
|
|
TString4 mese; mese.format("%02d", data.month());
|
|
chiave << data.year() << attivita << a << mese;
|
|
plm.put("CODTAB", chiave);
|
|
if (plm.read() == NOERR)
|
|
{
|
|
const bool calcolato = plm.get_bool("B0");
|
|
if (calcolato)
|
|
{
|
|
plm.zero("B0");
|
|
plm.rewrite();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return calcolata;
|
|
}
|
|
|
|
|
|
int TMovimentoPN::registra(bool re, bool force)
|
|
{
|
|
const TRectype& m = curr();
|
|
long numreg = m.get_long(MOV_NUMREG);
|
|
|
|
if (!re && numreg <= 0) // Tento di numerare automaticamente in caso di write
|
|
{
|
|
TLocalisamfile mov(LF_MOV); // Non sposto il file principale della relazione!
|
|
numreg = 1;
|
|
if (mov.last() == NOERR)
|
|
numreg += mov.get_long(MOV_NUMREG);
|
|
curr().put(MOV_NUMREG, numreg);
|
|
}
|
|
|
|
int err = re ? TRelation::rewrite(force) : TRelation::write(force);
|
|
if (err != NOERR)
|
|
return err;
|
|
|
|
_cg.renum_key(MOV_NUMREG, numreg);
|
|
err = _cg.write(re);
|
|
if (err != NOERR)
|
|
return err;
|
|
|
|
const int annoiva = m.get_int(MOV_ANNOIVA);
|
|
const TString4 reg(m.get(MOV_REG));
|
|
TRegistro registro(reg, annoiva);
|
|
const bool att_mista = reg.empty() ? FALSE : registro.attivita_mista();
|
|
|
|
for (int i = 0 ; i < iva_items(); i++)
|
|
{
|
|
TRectype& r = iva(i);
|
|
int tipoatt = 1;
|
|
if (att_mista)
|
|
{
|
|
const char tipo = r.get_char(RMI_TIPOC);
|
|
if (tipo <= ' ')
|
|
{
|
|
TBill c(r.get_int(RMI_GRUPPO), r.get_int(RMI_CONTO), r.get_long(RMI_SOTTOCONTO));
|
|
tipoatt = c.tipo_att();
|
|
}
|
|
}
|
|
r.put(RMI_TIPOATT, tipoatt);
|
|
|
|
const TString & indetr = r.get(RMI_TIPODET);
|
|
|
|
if (indetr.full())
|
|
{
|
|
const TRectype & det = cache().get("%DET", indetr);
|
|
|
|
if (!det.empty() && !det.get_bool("FPC"))
|
|
{
|
|
TTable tab("%DET");
|
|
|
|
tab.curr() = det;
|
|
tab.curr().put("FPC", "X");
|
|
tab.rewrite();
|
|
}
|
|
}
|
|
}
|
|
|
|
_iva.renum_key(MOV_NUMREG, numreg);
|
|
err = _iva.write(re);
|
|
if (err != NOERR)
|
|
return err;
|
|
|
|
|
|
// Aggiorna data registrazione e protocollo IVA sul registro
|
|
const TDate datareg(m.get(MOV_DATAREG));
|
|
if (reg.not_empty())
|
|
{
|
|
const long protiva = m.get_long(MOV_PROTIVA);
|
|
const long uprotiva = m.get_long(MOV_UPROTIVA);
|
|
const long max = protiva > uprotiva ? protiva : uprotiva;
|
|
registro.update(max, datareg);
|
|
}
|
|
|
|
// Aggiorna flags di ricalcolo liquidazione
|
|
|
|
TDate dataliq(datareg);
|
|
const int mese_liq = m.get_int(MOV_MESELIQ);
|
|
if (mese_liq > 0 && mese_liq != dataliq.month())
|
|
{
|
|
dataliq.set_day(1); // Evita problemi coi mesi corti!
|
|
dataliq.set_month(mese_liq);
|
|
}
|
|
|
|
controlla_liquidazione(dataliq, registro, TRUE);
|
|
if (re && dataliq.month() != _olddataliq.month())
|
|
controlla_liquidazione(_olddataliq, registro, TRUE);
|
|
|
|
return err;
|
|
}
|
|
|
|
|
|
int TMovimentoPN::write(bool force)
|
|
{
|
|
return registra(FALSE, force);
|
|
}
|
|
|
|
int TMovimentoPN::rewrite(bool force)
|
|
{
|
|
return registra(TRUE, force);
|
|
}
|
|
|
|
int TMovimentoPN::remove()
|
|
{
|
|
int err = _cg.remove();
|
|
|
|
if (err == NOERR)
|
|
err = _iva.remove();
|
|
|
|
if (err == NOERR)
|
|
err = TRelation::remove();
|
|
|
|
if (err == NOERR)
|
|
{
|
|
const TRectype& m = curr();
|
|
const TString4 reg(m.get(MOV_REG));
|
|
const int annoiva = m.get_int(MOV_ANNOIVA);
|
|
TRegistro registro(reg, annoiva);
|
|
controlla_liquidazione(_olddataliq, registro, TRUE);
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Aggiustamento movimenti rovinati o convertiti male
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TConti_array : private TAssoc_array
|
|
{
|
|
public: // TObject
|
|
virtual bool ok() const { return items() != 0; }
|
|
|
|
public:
|
|
bool add(const TBill& conto, const real& importo);
|
|
real importo(const TBill& conto);
|
|
bool remove(const TBill& conto);
|
|
|
|
bool add_iva(bool det, const real& importo);
|
|
real importo_iva(bool det);
|
|
bool remove_iva(bool det);
|
|
|
|
TConti_array() {}
|
|
virtual ~TConti_array() {}
|
|
};
|
|
|
|
bool TConti_array::add(const TBill& conto, const real& importo)
|
|
{
|
|
const char* key = conto.string();
|
|
real* imp = (real*)objptr(key);
|
|
if (imp == NULL)
|
|
TAssoc_array::add(key, importo);
|
|
else
|
|
*imp += importo;
|
|
return imp != NULL;
|
|
}
|
|
|
|
real TConti_array::importo(const TBill& conto)
|
|
{
|
|
const char* key = conto.string();
|
|
const real* imp = (real*)objptr(key);
|
|
return imp ? *imp : ZERO;
|
|
}
|
|
|
|
bool TConti_array::remove(const TBill& conto)
|
|
{
|
|
const char* key = conto.string();
|
|
return TAssoc_array::remove(key);
|
|
}
|
|
|
|
bool TConti_array::add_iva(bool det, const real& importo)
|
|
{
|
|
real* imp = NULL;
|
|
if (!importo.is_zero())
|
|
{
|
|
const char* const key = det ? "D" : "N";
|
|
imp = (real*)objptr(key);
|
|
if (imp == NULL)
|
|
TAssoc_array::add(key, importo);
|
|
else
|
|
*imp += importo;
|
|
}
|
|
return imp != NULL;
|
|
}
|
|
|
|
real TConti_array::importo_iva(bool det)
|
|
{
|
|
const char* const key = det ? "D" : "N";
|
|
const real* imp = (real*)objptr(key);
|
|
return imp ? *imp : ZERO;
|
|
}
|
|
|
|
bool TConti_array::remove_iva(bool det)
|
|
{
|
|
const char* const key = det ? "D" : "N";
|
|
return TAssoc_array::remove(key);
|
|
}
|
|
|
|
real TMovimentoPN::indetraibile_al(const TString& codind, const TCausale& caus, int annodoc) const
|
|
{
|
|
int tipodet;
|
|
|
|
return ::indetraibile_al(codind, caus, annodoc, tipodet);
|
|
}
|
|
|
|
int TMovimentoPN::analizza_riga_IVA(const real& imptot, const real& ivatot, const TCausale& caus,
|
|
int annodoc, const TString& codiva, const TString& codind,
|
|
real& imp_det, real& iva_det, real& imp_ind, real& iva_ind) const
|
|
{
|
|
const real perc_ind = indetraibile_al(codind, caus, annodoc);
|
|
const bool corrispettivo = caus.corrispettivi();
|
|
TBill billind; caus.bill(RIGA_IVA_NON_DETRAIBILE, billind);
|
|
const bool iva_ind_al_costo = !billind.ok();
|
|
return analizza_IVA(imptot, ivatot, perc_ind, corrispettivo, iva_ind_al_costo,
|
|
codiva, imp_det, iva_det, imp_ind, iva_ind);
|
|
}
|
|
|
|
// Aggiusta i row types se sono andati persi o non sono stati convertiti
|
|
void TMovimentoPN::adjust_rowtypes()
|
|
{
|
|
const TRectype& mov = curr();
|
|
const char tipo = mov.get_char(MOV_TIPO);
|
|
const long codice = mov.get_long(MOV_CODCF);
|
|
const int annoiva = mov.get_int(MOV_ANNOIVA);
|
|
const int annodoc = mov.get_date(MOV_DATADOC).year();
|
|
const TCausale causale(mov.get(MOV_CODCAUS), annoiva);
|
|
|
|
TConti_array conti;
|
|
int r;
|
|
|
|
for (r = 0; r < _iva.rows(); r++)
|
|
{
|
|
const TRectype& row = iva(r);
|
|
const TBill bill(row);
|
|
const real imponibile(row.get(RMI_IMPONIBILE));
|
|
const real imposta(row.get(RMI_IMPOSTA));
|
|
const TString4 codiva = row.get(RMI_CODIVA);
|
|
const TString4 codind = row.get(RMI_TIPODET);
|
|
real imp_det, iva_det, imp_ind, iva_ind;
|
|
analizza_riga_IVA(imponibile, imposta, causale, annodoc, codiva, codind,
|
|
imp_det, iva_det, imp_ind, iva_ind);
|
|
|
|
conti.add(bill, imp_det+imp_ind);
|
|
conti.add_iva(false, iva_ind);
|
|
conti.add_iva(true, iva_det);
|
|
}
|
|
|
|
bool totale = FALSE;
|
|
bool ritfis = mov.get_real(MOV_RITFIS).is_zero();
|
|
bool ritsoc = mov.get_real(MOV_RITSOC).is_zero();
|
|
bool ivadet = conti.importo_iva(TRUE).is_zero();
|
|
bool ivanon = conti.importo_iva(FALSE).is_zero();
|
|
|
|
for (r = 0; r < _cg.rows(); r++)
|
|
{
|
|
TRectype& row = cg(r);
|
|
const char rt = row.get_char(RMV_ROWTYPE);
|
|
switch(rt)
|
|
{
|
|
case 'F': ritfis = true; break;
|
|
case 'S': ritsoc = true; break;
|
|
case 'T': totale = true; break;
|
|
default : break;
|
|
}
|
|
if (rt > ' ') continue;
|
|
|
|
if (!totale && row.get_char(RMV_TIPOC) == tipo && row.get_long(RMV_SOTTOCONTO) == codice)
|
|
{
|
|
row.put(RMV_ROWTYPE, 'T');
|
|
totale = TRUE;
|
|
continue;
|
|
}
|
|
|
|
const real importo(row.get(RMV_IMPORTO));
|
|
const TBill bill(row);
|
|
|
|
if (!ritfis && importo == mov.get_real(MOV_RITFIS))
|
|
{
|
|
TBill conto_rit; causale.bill(RIGA_PAG_RITFIS, conto_rit);
|
|
if (!conto_rit.ok() || conto_rit == bill)
|
|
{
|
|
row.put(RMV_ROWTYPE, 'F');
|
|
ritfis = true;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (!ritsoc && importo == mov.get_real(MOV_RITSOC))
|
|
{
|
|
TBill conto_rit; causale.bill(RIGA_PAG_RITSOC, conto_rit);
|
|
if (!conto_rit.ok() || conto_rit == bill)
|
|
{
|
|
row.put(RMV_ROWTYPE, 'S');
|
|
ritsoc = true;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (!conti.ok())
|
|
continue; // Ho esaurito i conti IVA
|
|
|
|
if (importo == conti.importo(bill))
|
|
{
|
|
row.put(RMV_ROWTYPE, 'I');
|
|
conti.remove(bill);
|
|
continue;
|
|
}
|
|
|
|
if (!ivadet && importo == conti.importo_iva(TRUE))
|
|
{
|
|
row.put(RMV_ROWTYPE, 'D');
|
|
conti.remove_iva(TRUE);
|
|
continue;
|
|
}
|
|
|
|
if (!ivanon && importo == conti.importo_iva(FALSE))
|
|
{
|
|
row.put(RMV_ROWTYPE, 'N');
|
|
conti.remove_iva(FALSE);
|
|
continue;
|
|
}
|
|
}
|
|
}
|