campo-sirio/cg/cg4303.cpp
angelo 773c181813 Implementazione del PIM13 (finalmente): migliorata gestione ventilazione
e corrispettivi.
Cambiato nome da _BolgArray/_BolgItem (veramente poco significativo)
in _Iva11Array/Iva11Item.
Migliorata l'indentazione in cg4301.cpp.
Tolte alcune istruzioni commentate ed oramai fossilizzate da secoli.


git-svn-id: svn://10.65.10.50/trunk@5425 c028cbd2-c16b-5b4b-a496-9718f37d4682
1997-10-23 09:34:10 +00:00

439 lines
12 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;
_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)
{
const int items = _corr_arr.items();
if (items == 0) return;
real imponibile,imposta;
// Se siamo in annuale non aggiornare i PIM/PAM/PLM dei mesi calcolati
// ricalcola (solo per il mese in corso!) operando sull'array
for (int i = 0; i < items; i++)
{
_CorrItem* ci = (_CorrItem*)&_corr_arr[i];
// memorizza per codiva
if (ci->_month != month || ci->_codatt != codatt)
continue;
lordo2netto(ci->_totale, imponibile, imposta, ci->_aliquota);
// aggiusto l'IVA vendite nei plm
look_plm(month, codatt);
real ive = _plm->get_real("R0");
ive += imposta;
_plm->put("R0",ive);
_plm->rewrite();
// .. e il volume di affari nei pam
real vaf = _pam->get_real("R1");
vaf += imponibile;
_pam->put("R1", vaf);
_pam->rewrite();
}
}
// ricalcolo della malefica ventilazione
void TLiquidazione_app::recalc_ventilation(int month, const char* codatt)
{
if (!_isvent || _isagricolo || _isviaggio || _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();
m = month == 13 ? 13 : 1; // In annuale legge solo il PIM13
for (; m <= month; m++)
{
// aggiunge gli acquisti del mese m operando sui pim
for (_pim->first(); !_pim->eof(); _pim->next())
{
if (_year != *_pim_anno) continue;
// se e' acquisto beni per rivendita
int tipocr = atoi(*_pim_tipocr);
int mese = atoi(*_pim_mese);
int tipodet = atoi(*_pim_tipodet);
look_iva(*_pim_codiva);
// base di riparto solo se non esente, non soggetto, non imponibile
TString16 tipoiva(_iva->get("S1"));
TString16 reg = *_pim_codreg;
/*
* 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))
{
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;
const int vent_items = _vent_arr.items();
for (int j = 0; j < vent_items; j++)
{
_VentItem& vv = (_VentItem&)_vent_arr[j];
totacq += vv._totale;
}
// 3) ricalcola (solo per il mese in corso!) operando sull'array
const int vend_items = _vend_arr.items();
for (int i = 0; i < vend_items; i++)
{
_VendItem* vi = (_VendItem*)&_vend_arr[i];
totven += vi->_totale;
// 3.2) calcola percentuali di ripartizione e prepara l'affettatrice
TDistrib dst(vi->_totale, ROUND_LIRA);
for (j = 0; j < vent_items; j++)
{
_VentItem* vv = (_VentItem*)&_vent_arr[j];
dst.add(vv->_totale/totacq);
}
// 3.3) affetta l'importo
real tlor = 0.0;
for (j = 0; j < vent_items; j++)
{
_VentItem* vv = (_VentItem*)&_vent_arr[j];
real imponibile = dst.get();
real div(1.0); div += vv->_aliquota;
real totale = imponibile;
real imposta = imponibile - (imponibile/div);
imposta.ceil(ROUND_LIRA);
imponibile -= imposta;
// quadratura del cerchione
real delta = totale - imponibile - imposta;
if (!delta.is_zero())
imposta += delta;
tlor += imponibile + imposta;
// quadratura generale (solo per unita', che peraltro
// dovrebbe essere l'unica possibile stronzata
if ((totven - tlor) == real(1.0))
imposta += real(1.0);
// aggiusto l'IVA vendite nei plm
look_plm(month, codatt);
real ive = _plm->get_real("R0");
ive += imposta;
_plm->put("R0",ive);
_plm->rewrite();
// .. e il volume di affari nei pam
real vaf = _pam->get_real("R1");
vaf += imponibile;
_pam->put("R1", vaf);
_pam->rewrite();
// Aggiorno i luridi pim
bool was = 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' in stampa prospetto
_pim->put("B1","X");
// se e' nuovo, il segnale per usare l'importo nel calcolo del rimborso
// viene amorosamente messo a quanto il codice IVA prevede
if (!was)
{
look_iva(vv->_codiva);
_pim->put("I1", (long)vendita);
if (!_iva->get_bool("B4")) _pim->put("B3", "X");
}
_pim->rewrite();
}
}
// memorizza totali per il prospettino di m.
look_plm(month, codatt);
// PAM e PUM
_pam->put("R2",totacq);
_pam->put("R3",totven);
_pam->rewrite();
}
_DescrItem* TLiquidazione_app::recalc_rimborso(int month, const char* codatts,
bool stliq)
{
// 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;
const bool is_mens = _freqviva == "M";
// variabili per condizione 1
real es_ni = 0.0;
real vol_aff = 0.0;
int m;
if (is_mens) m = month; // per le mensili considera solo il mese attuale
else m = next_trim(month)-2; // per le trimestrali considera i mesi del trimestre
if (month == 13) m = 13; // se annuale considera solo il mese 13
// variabili per condizione 2
real vtot = 0.0;
real atot = 0.0;
real ivav = 0.0;
real ivaa = 0.0;
real alv = 0.0; // aliquota media vendite
real ala = 0.0; // aliquota media acquisti
// Condizione 1...
while ((tmpatt = atts.get()) != NULL)
{
att = tmpatt;
for (; m <= month; m++)
{
if (!look_plm(m,att)) continue;
vol_aff += _pam->get_real("R1");
es_ni += _pum->get_real("R12");
if (_isagricolo) // questo calcolo per il regime agricolo, riguarda la condizione 2
{
vtot += _pum->get_real("R11");
ivav += _plm->get_real("R6");
}
}
}
// condizione 1
real prc = es_ni/vol_aff; prc.round(2);
if (stliq && !vol_aff.is_zero() && prc > MIN_PARTE_ESENTE)
{
rimborsami = TRUE;
d = new _DescrItem(RIMBORSO);
d->_f0 = TRUE;
d->_r0 = es_ni;
d->_r1 = vol_aff;
}
// Condizione 2...
// scorri i bellissimi progressivi mensili
// Nota: i valori ricavati vanno poi integrati con R3, dove sono memorizzati i corrispettivi da scorporare
// anche qui si accumula per codice iva e si effettua lo scorporo alla fine del ciclo.
TAssoc_array corr_ann;
TString codiva;
_CorrItem cx,*cc;
bool is_key;
const int year = atoi((const char*)_year);
for (_pim->first(); !_pim->eof(); _pim->next())
{
int ryear = atoi(*_pim_anno);
int rmese = atoi(*_pim_mese);
int tipodet = atoi(*_pim_tipodet);
codiva = *_pim_codiva;
// B3 significa che e' acq. o vendita valido per rimb. per aliquota
if (!_pim->get_bool("B3")) continue;
// Se il tipo di codice e' NS non va considerato nella sommatoria del tot. acquisti
look_iva(codiva);
const bool non_sogg = _iva->get("S1") == "NS";
if (!is_mens) // Trimestrali
{
if (year != ryear ||
(rmese < (next_trim(month)-2) || rmese > month))
continue;
} else // Mensili
if (year != ryear || month != rmese)
continue;
int tipomov = (tiporeg)_pim->get_long("I1");
real imp = _pim->get("R0");
real iva = _pim->get("R1");
// totali imponibili
if (tipomov == vendita)
{
if (!_isagricolo)
{ // per il regime agricolo il calcolo e' a parte: si reperiscono PUM->R11(Imponibile) e PLM->R6(Imposta)
// vedi sopra...
vtot += imp;
ivav += iva;
is_key = corr_ann.is_key(codiva);
cx._totale = 0;
_CorrItem& ca = is_key ? (_CorrItem&) corr_ann[codiva] : cx;
ca._totale += _pim->get_real("R3");
if (!is_key) // se non c'e' lo aggiunge
{
ca._aliquota = _iva->get_real("R0")/CENTO; // Se e' nuovo setta l'aliquota
corr_ann.add(codiva,ca);
}
}
}
else
if (tipodet != 9) // I progressivi con tipo detraibilita' a 9 vanno saltati (MI2209)
{
if (!non_sogg)
atot += imp;
ivaa += iva;
}
} // end of for
real impc,ivac; // Aggiunge lo scorporo dei corrispettivi alle vendite calcolate
for (cc = (_CorrItem *)corr_ann.first_item(); cc != NULL; cc = (_CorrItem *)corr_ann.succ_item())
{
lordo2netto(cc->_totale,impc,ivac,cc->_aliquota);
vtot += impc;
ivav += ivac;
}
// finalmente
alv = ivav/vtot; alv.round(4);
ala = ivaa/atot; ala.round(4);
// vedi condizioni
rimborsami = ala > alv;
if (rimborsami)
{
// vedi di quanto ala eccede alv; deve essere > 10%
real ecc = ((ala/alv) - real(1.0));
rimborsami = (ecc >= SOGLIA_MAGGIORE_ALIQUOTA_DEL_CAZZO_PER_AVER_DIRITTO_AL_RIMBORSO);
}
if (stliq && rimborsami)
{
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 && is_month_ok_strict(month))
{
look_lim(month);
_lim->put("B2", "X");
_lim->rewrite();
}
return d;
}