campo-sirio/cg/cg2101.cpp
alex 5dba0c34a0 Riportate modifiche dalla R_97_03_01M
git-svn-id: svn://10.65.10.50/trunk@5787 c028cbd2-c16b-5b4b-a496-9718f37d4682
1997-12-24 09:40:34 +00:00

464 lines
11 KiB
C++
Executable File

#include <stdlib.h>
#include <tabutil.h>
#include <prefix.h>
#include <utility.h>
#include "cg2101.h"
#include "cg2103.h"
///////////////////////////////////////////////////////////
// Movimento di prima nota
///////////////////////////////////////////////////////////
TMovimentoPN::TMovimentoPN()
: TRelation(LF_MOV), _cg(LF_RMOV, "NUMRIG"), _iva(LF_RMOVIVA, "NUMRIG")
{
add(LF_RMOV, "NUMREG=NUMREG");
add(LF_RMOVIVA, "NUMREG=NUMREG");
}
void TMovimentoPN::destroy_rows(long num)
{
_cg.destroy_rows();
_cg.renum_key("NUMREG", num);
_iva.destroy_rows();
_iva.renum_key("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);
}
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)
{
_olddate = file().get("DATAREG"); // Memorizza data operazione per aggiornare i saldi
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("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;
TString16 attivita(registro.attivita()); attivita.right_just(5, '0');
chiave << data.year() << attivita << a << format("%02d", data.month());
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)
{
int err = re ? TRelation::rewrite(force) : TRelation::write(force);
if (err != NOERR)
return err;
const TRectype& m = curr();
const long numreg = m.get_long("NUMREG");
if (!re)
_cg.renum_key("NUMREG", numreg);
err = _cg.write(re);
if (err != NOERR)
return err;
const int annoiva = m.get_int("ANNOIVA");
const TString reg(m.get("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("TIPOC");
if (tipo <= ' ')
{
TBill c(r.get_int("GRUPPO"), r.get_int("CONTO"), r.get_long("SOTTOCONTO"));
tipoatt = c.tipo_att();
}
}
r.put("TIPOATT", tipoatt);
}
if (!re)
_iva.renum_key("NUMREG", numreg);
err = _iva.write(re);
if (err != NOERR)
return err;
// Aggiorna data registrazione e protocollo IVA sul registro
const TDate datareg(m.get("DATAREG"));
if (reg.not_empty())
{
const long protiva = m.get_long("PROTIVA");
const long uprotiva = m.get_long("UPROTIVA");
const long max = protiva > uprotiva ? protiva : uprotiva;
registro.update(max, datareg);
}
// Aggiorna flags di ricalcolo liquidazione
controlla_liquidazione(datareg, registro, TRUE);
if (re && datareg != _olddate)
controlla_liquidazione(_olddate, 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 TDate datareg(m.get("DATAREG"));
const int annoiva = m.get_int("ANNOIVA");
const TString reg(m.get("REG"));
TRegistro registro(reg, annoiva);
controlla_liquidazione(datareg, 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)
{
const char* const key = det ? "D" : "N";
real* 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);
}
bool TMovimentoPN::detraibile(const TRectype& row, const TCausale& cau) const
{
if (cau.iva() == iva_vendite) // Vendite sempre detraibili
return TRUE;
const int tipo_det = row.get_int(RMI_TIPODET); // Leggi tipo detraibilita
if (tipo_det != 0)
return FALSE;
const int annodoc = curr().get_date(MOV_DATADOC).year();
const bool prorata100 = cau.reg().prorata100(annodoc);
return !prorata100; // Se prorata = 100% e' indetraibile
}
// 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 TCausale causale(mov.get(MOV_CODCAUS), annoiva);
TConti_array conti;
for (int r = 0; r < _iva.rows(); r++)
{
const TRectype& row = iva(r);
const TBill bill(row);
real imponibile(row.get(RMI_IMPONIBILE));
real imposta(row.get(RMI_IMPOSTA));
const bool det = detraibile(row, causale);
if (imposta.is_zero() && causale.corrispettivi())
{
const TCodiceIVA iva(row.get(RMI_CODIVA));
imposta = iva.scorpora(imponibile);
}
conti.add(bill, imponibile);
conti.add_iva(det, imposta);
}
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_RITENUTE_FISCALI, 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_RITENUTE_SOCIALI, 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;
}
}
}