campo-sirio/cg/cg4303.cpp
villa 4cec333328 Stampe, classificazione pim, scorporo corrispettivi
git-svn-id: svn://10.65.10.50/trunk@1205 c028cbd2-c16b-5b4b-a496-9718f37d4682
1995-04-04 09:05:49 +00:00

446 lines
11 KiB
C++
Executable File

// -----------------------------------------------------------------
// Calcolo liquidazione
// part 4: casi particolari
// fv 2-2-94
// -----------------------------------------------------------------
#include "cg4300.h"
void TLiquidazione_app::add_plafond(int month, const char* codatt, int type,
real& howmuch, bool intra)
{
look_ppa(month,codatt,type);
TString att(codatt);
real r0 = _ppa_r->get_real("R0");
real r1 = _ppa_r->get_real("R1");
real r2 = _ppa_r->get_real("R2");
if (intra) r1 += howmuch;
else r0 += howmuch;
if (r2 < (r0+r1))
describe_error("Acquisti in eccesso rispetto al plafond disponibile",
att.cut(5));
_ppa_r->put("R0",r0);
_ppa_r->put("R1",r1);
_ppa->rewrite();
}
void TLiquidazione_app::zero_plafond (int month, const char* codatt)
{
for (int jj = 1; jj <= 3; jj++) // three types of plafond
{
real r;
look_ppa(month,codatt,jj,TRUE);
if (is_first_month(month))
{
r = (jj == 1 ? _p8 : (jj == 2 ? _p8b : _p9));
}
else
{
long rn = _ppa->recno();
// se non c'e' quello del mese prima c'e' poco da fare,
// si ricalcola tutto
if (!look_ppa(previous_month(month),codatt,jj))
// mazza che bella chiamata ricorsiva
{
if (_recalc != needed)
{
describe_error("Progressivi plafond non ricalcolati per "
"i mesi precedenti: possibili errori",
codatt);
}
else
{
if (!update_att(previous_month(month),codatt, FALSE))
describe_error("Progressivi plafond non ricalcolati per "
"i mesi precedenti: possibili errori",
codatt);
look_ppa(previous_month(month),codatt,jj);
}
}
r = _ppa_r->get_real("R2") -
_ppa_r->get_real("R0") -
_ppa_r->get_real("R1");
_ppa->readat(rn);
}
_ppa_r->put("R2",r);
_ppa_r->put("R0","");
_ppa_r->put("R1","");
_ppa->rewrite();
} // for tipo esenzione plafond
}
// ricalcolo dei corrispettivi
void TLiquidazione_app::recalc_corrispettivi(int month, const char* codatt)
{
if (_corr_arr.items() == 0) return;
// ricalcola (solo per il mese in corso!) operando sull'array
for (int i = 0; i < _corr_arr.items(); i++)
{
_CorrItem* ci = (_CorrItem*)&_corr_arr[i];
if (ci->_month != month)
continue;
real imponibile = ci->_totale/(1.00 + ci->_aliquota);
imponibile.ceil(ROUND_LIRA);
real imposta = ci->_totale - imponibile;
// aggiusto l'IVA vendite nei plm
look_plm(month, codatt);
real ive = _plm->get_real("R0");
ive += imposta;
_plm->put("R0",ive);
_plm->rewrite();
// Aggiorno i luridi pim
look_pim(month, codatt, ci->_codreg, "", ci->_codiva, ci->_tipodet, TRUE);
imponibile += _pim->get_real("R0");
imposta += _pim->get_real("R1");
_pim->put("R0", imponibile);
_pim->put("R1", imposta);
_pim->rewrite();
}
}
// ricalcolo della malefica ventilazione
void TLiquidazione_app::recalc_ventilation(int month, const char* codatt)
{
if (!_isvent || _vend_arr.items() == 0) return;
TString att(codatt);
// 1) ricalcola i pim dei mesi dal primo al corrente se necessario
recalc rcl = _recalc;
_recalc = needed;
for (int m = 1; m < month; m++)
update_att(m,codatt, FALSE);
_recalc = rcl;
_vent_arr.destroy();
for (m = 1; m <= month; m++)
{
// aggiunge gli acquisti del mese m operando sui pim
for (_pim->first(); !_pim->eof(); _pim->next())
{
// se e' acquisto beni per rivendita
int tipocr = atoi(*_pim_tipocr);
int mese = atoi(*_pim_mese);
int tipodet = atoi(*_pim_tipodet);
/*
* se non si e' settato il ricalcolo nei parametri ditta
* considera soltanto quelli con detraibilita' == 3
* (passaggi interni)
* sensu Scudler 1994
*/
if (!_isricacq && tipodet != 3)
continue;
/*
* caso particolare SENSU Vladimiro (1995) #MI3001
* questi vengono pero' conteggiati nel totale
* acquisti per rivendita
*/
if (tipocr == 5 && tipodet == 3)
continue;
TString att(codatt);
if (tipocr == 1 && mese == m && att == (const char*)(*_pim_codatt))
{
look_iva(*_pim_codiva);
// base di riparto solo se non esente, non soggetto, non imponibile
TString tipoiva(_iva->get("S1"));
if (tipoiva != "NS" && tipoiva != "NI" && tipoiva != "ES")
{
real lurd = _pim->get_real("R0");
lurd += _pim->get_real("R1");
real perc = _iva->get_real("R0");
TString other = _iva->get("S6");
if (!other.empty())
{
// ventila a un altro codice
look_iva(other);
perc = _iva->get_real("R0");
}
add_ventilation(perc / CENTO, lurd, *_pim_codiva, other);
}
}
}
}
// 2) calcola totale acquisti su tutte le aliquote
real totacq = 0.0;
real totven = 0.0;
for (int j = 0; j < _vent_arr.items(); j++)
{
_VentItem* vv = (_VentItem*)&_vent_arr[j];
totacq += vv->_totale;
}
// 3) ricalcola (solo per il mese in corso!) operando sull'array
for (int i = 0; i < _vend_arr.items(); i++)
{
_VendItem* vi = (_VendItem*)&_vend_arr[i];
if (vi->_month != month)
continue;
// questo serve solo per il prospettino di m.
totven += vi->_totale;
// 3.2) calcola percentuali di ripartizione e prepara l'affettatrice
TDistrib dst(vi->_totale,ROUND_LIRA);
for (j = 0; j < _vent_arr.items(); j++)
{
_VentItem* vv = (_VentItem*)&_vent_arr[j];
dst.add(vv->_totale/totacq);
}
// 3.3) affetta l'importo
for (j = 0; j < _vent_arr.items(); j++)
{
_VentItem* vv = (_VentItem*)&_vent_arr[j];
real imponibile = dst.get();
real div(1.0); div += vv->_aliquota;
real imposta = imponibile - (imponibile/div);
imposta.ceil(ROUND_LIRA);
imponibile -= imposta;
// aggiusto l'IVA vendite nei plm
look_plm(month, codatt);
real ive = _plm->get_real("R0");
ive += imposta;
_plm->put("R0",ive);
_plm->rewrite();
// Aggiorno i luridi pim
look_pim(month, codatt, vi->_codreg, "0", vv->_codiva, vi->_tipodet, TRUE);
imponibile += _pim->get_real("R0");
imposta += _pim->get_real("R1");
_pim->put("R0", imponibile);
_pim->put("R1", imposta);
_pim->put("S4", vv->_other);
// segnale per comodita'
_pim->put("B1","X");
_pim->rewrite();
}
}
// memorizza totali per il prospettino di m.
look_plm(month, codatt);
// TBI PAM e PUM
_pam->put("R2",totacq);
_pam->put("R3",totven);
_pam->rewrite();
}
// questa serve per il rimborso secondo le
// nuove cazzonorme
class rObj : public TObject
{
public:
real _imp;
real _iva;
real _perc;
rObj() {}
virtual ~rObj() {}
};
_DescrItem* TLiquidazione_app::recalc_rimborso(int month, const char* codatts)
{
// calcola condizioni per il diritto al rimborso infracazzuale
// chiamata soltanto per i trimestri anche se annuale
// aggiornata a normative per anno liq. > 1994
bool rimborsami = FALSE;
_DescrItem* d = NULL;
TToken_string atts(codatts);
const char* tmpatt;
TString att;
real es_ni = 0.0;
real vol_aff = 0.0;;
while ((tmpatt = atts.get()) != NULL)
{
att = tmpatt;
for (int m = month - 2; m <= month; m++)
{
if (!look_plm(m,att)) continue;
vol_aff += _pam->get_real("R1");
es_ni += _pum->get_real("R6");
}
}
// condizione 1
if (!vol_aff.is_zero() && (es_ni/vol_aff) > MIN_PARTE_ESENTE)
{
rimborsami = TRUE;
d = new _DescrItem(RIMBORSO);
d->_f0 = TRUE;
d->_r0 = es_ni;
d->_r1 = vol_aff;
}
// ---------------------- condizione 2
// u'casinu pazzescu d'u nuiu guvernu
// due array dove ficcare i totali per
// codiva in ordine di imponibile
TArray varr, aarr;
real vtot = 0.0;
real atot = 0.0;
real ivav = 0.0;
real ivaa = 0.0;
// scorri i bellissimi progressivi mensili rimborso
for (_rmb->first(); !_rmb->eof(); _rmb->next())
{
int year = atoi((const char*)_year);
int ryear = atoi((const char*)(*_rmb_anno));
int rmese = atoi((const char*)(*_rmb_mese));
if (year != ryear || (rmese < (month - 2) || rmese > month))
continue;
real imp = _rmb->get("R0");
real iva = _rmb->get("R1");
real per = _rmb->get("R2");
rObj* rb = new rObj;
rb->_imp = imp;
rb->_iva = iva;
rb->_perc = per;
TArray& arr = (tiporeg)atoi((const char*)(*_rmb_tiporeg)) == vendita ? varr : aarr;
for (int i = 0; i < arr.items(); i++)
{
rObj& robj = (rObj&)arr[i];
if (robj._imp < imp)
break;
}
arr.insert(rb, i);
// totali imponibili
if ((tiporeg)atoi((const char*)(*_rmb_tiporeg)) == vendita)
vtot += imp;
else
atot += imp;
}
// se ci sono due o piu' imponibili uguali devo
// sostituire l'imposta con la media delle aliquote
// ciclo uguale sui due array
for (int w = 0; w < 2; w++)
{
TArray& arr = w == 0 ? varr : aarr;
for (int i = 0; i < arr.items(); i++)
{
rObj& robj = (rObj&)arr[i];
real impref = robj._imp;
real perc = robj._perc;
for (int j = i+1; j < arr.items(); j++)
{
rObj& rbj = (rObj&)arr[j];
if (rbj._imp != impref)
break;
perc += rbj._perc;
}
// riaggiustesbimo
if (j > i+1)
{
// funzionerebbe comunque ma risparmiamo una
// divisione per 1
real ndiv(j-i);
perc /= ndiv;
for (; i < j; i++)
{
rObj& rbj = (rObj&)arr[i];
rbj._iva = rbj._imp * (perc/CENTO);
rbj._iva.round(ROUND_LIRA);
}
i --;
}
}
}
// 51 per cento
vtot *= PERC_IMP_RIMBORSABILE;
atot *= PERC_IMP_RIMBORSABILE;
real alv = 0.0; // aliquota media vendite
real ala = 0.0; // aliquota media acquisti
for (w = 0; w < 2; w++)
{
TArray& arr = w == 0 ? varr : aarr;
real timp = w == 0 ? vtot : atot;
real tiva = 0.0;
for (int i = 0; i < arr.items(); i++)
{
rObj& robj = (rObj&)arr[i];
if (timp >= robj._imp)
{
tiva += robj._iva;
timp -= robj._imp;
}
else
{
real perc = timp/robj._imp;
if (!perc.is_zero())
{
real ttiv = robj._iva * perc;
ttiv.round(ROUND_LIRA);
tiva += ttiv;
}
break;
}
}
if (w == 0) ivav = tiva;
else ivaa = tiva;
}
// finalmente
alv = ivav/vtot; alv.round(2);
ala = ivaa/atot; ala.round(2);
if (ala > alv)
{
rimborsami = TRUE;
if (d == NULL) d = new _DescrItem(RIMBORSO);
d->_f1 = TRUE;
d->_r2 = vtot;
d->_r3 = atot;
d->_r4 = ivav;
d->_r5 = ivaa;
d->_r6 = alv * CENTO;
d->_r7 = ala * CENTO;
}
if (rimborsami)
{
look_lim(month);
_lim->put("B2", "X");
_lim->rewrite();
}
return d;
}