// ----------------------------------------------------------------- // Calcolo liquidazione // part 4: casi particolari // fv 2-2-94 // ----------------------------------------------------------------- #include "cg4300.h" class Annual_item : public TObject { real _imposta; real _imponibile; TString _codiva; TString _other; public: virtual TObject* dup() const { return new Annual_item(*this); } real& imposta() { return _imposta;} real& imponibile() { return _imponibile;} TString& codiva() { return _codiva;} TString& other() { return _other;} Annual_item() { _imposta = 0.0; _imponibile = 0.0; _codiva = ""; _other = ""; } virtual ~Annual_item() {} }; 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; //06/12/1995 /* if (r2 < (r0+r1)) describe_error("Acquisti in eccesso rispetto al plafond disponibile", att.cut(5)); */ //fine _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; // Nota: i commenti marcati con x13 indicano modifiche da rimuovere non appena implementato // correttamente il mese 13 // x13 TString key; bool is_key; TAssoc_array corr_ann; // Contiene corrispettivi annuali (temporaneo, da correggere // non appena implementato correttamente il mese 13) _CorrItem cx; // Se siamo in annuale non aggiornare i PIM/PAM/PLM dei mesi calcolati if (_month == 13 && month < 13) return; // fine x13 // 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 // x13 if ((month != 13 && ci->_month != month) || ci->_codatt != codatt) continue; key = ci->_codiva; is_key = corr_ann.is_key(key); cx._totale = 0; _CorrItem& ca = is_key ? (_CorrItem&) corr_ann[key] : cx; ca._totale += ci->_totale; if (!is_key) // se non c'e' lo aggiunge { ca._aliquota = ci->_aliquota; /* ca._codreg = ci->_codreg; ca._tipodet = ci->_tipodet; */ corr_ann.add(key,ca); } /* continue; // fine x13 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(); // 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(); */ } // Dopo aver calcolato la somma dei corrispettivi annualmente, li scorpora // x13 // if (month == 13) //{ real imp,iva,imp1,iva1; _CorrItem* cc; // Per le prossime scritture(PAM e PLM) uso impropriamente il mese 12, lo so e' terribile... // ma non appena possibile il mese 13 sara' disponibile tutto sara' piu' bello. //const int m = month == 13 ? 12 : month; for (cc = (_CorrItem *)corr_ann.first_item(); cc != NULL; cc = (_CorrItem *)corr_ann.succ_item()) { lordo2netto(cc->_totale, imp, iva, cc->_aliquota); imponibile += imp; imposta += iva; /* look_pim(m, codatt, cc->_codreg, "", corr_ann.get_hashobj()->key(), cc->_tipodet, TRUE); imp1 = _pim->get_real("R0"); iva1 = _pim->get_real("R1"); imp1 += imp; iva1 += iva; _pim->put("R0",imp1); _pim->put("R1",iva1); _pim->rewrite(); */ //} } look_plm(month, codatt); // Aggiorna l'iva vendite in PLM... real ive = _plm->get_real("R0"); ive += imposta; _plm->put("R0",ive); // ed il volume d'affari in PAM real vaf = _pam->get_real("R1"); vaf += imponibile; _pam->put("R1",vaf); _plm->rewrite(); _pam->rewrite(); // fine x13 } // 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); TArray annual_vent; Annual_item a_item; // 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()) { 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; for (int j = 0; j < _vent_arr.items(); j++) { _VentItem& vv = (_VentItem&)_vent_arr[j]; totacq += vv._totale; } const bool is_annual = _month == 13 && month == 13; for (j = 0; is_annual && j < _vend_arr.items(); j++) { _VendItem& vi = (_VendItem&)_vend_arr[j]; totven += vi._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 && !is_annual) continue; // questo serve solo per il prospettino di m. if (!is_annual) totven += vi->_totale; // 3.2) calcola percentuali di ripartizione e prepara l'affettatrice TDistrib dst(!is_annual ? vi->_totale : totven,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 real tlor = 0.0; 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 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); if (is_annual) { // memorizza i dati della ventilazione annuale in un TArray a_item.imposta() = imposta; a_item.imponibile() = imponibile; a_item.codiva() = vv->_codiva; a_item.other() = vv->_other; annual_vent.add(a_item); continue; } else if (_month != 13) { // 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(); } } if (is_annual) { // Cazzeggia e riscrive i PIM/PAM/PLM (veid sopra) ripartendo equamente gli importi annuali // tra i vari mesi, tipodet e codici IVA. const int slices = _vend_arr.items(); const int a_items = annual_vent.items(); real perc(1.0),imp_fetta, iva_fetta, tot_imp, tot_iva, delta; perc /= slices; for (i = 0; i < a_items; i++) { Annual_item& item = (Annual_item&) annual_vent[i]; TDistrib imp_s(item.imponibile(),ROUND_LIRA); TDistrib iva_s(item.imposta(),ROUND_LIRA); tot_imp = 0.0; tot_iva = 0.0; for (j = 0; j < slices; j++) { imp_s.add(perc); iva_s.add(perc); } for (j = 0; j < slices; j++) { _VendItem * vi = (_VendItem*) &_vend_arr[j]; imp_fetta = imp_s.get(); iva_fetta = iva_s.get(); tot_imp += imp_fetta; tot_iva += iva_fetta; // Serve per eventuali perdite di lirette... if (j == (slices - 1)) { delta = item.imponibile() - tot_imp; if (!delta.is_zero()) imp_fetta += delta; // Aggiusta l'ultima fetta(IVA e IMPONIBILE) delta = item.imposta() - tot_iva; // per eventali perdite di lire nella ripartizione if (!delta.is_zero()) iva_fetta += delta; } // aggiusto l'IVA vendite nei plm look_plm(vi->_month, codatt); real ive = _plm->get_real("R0"); ive += iva_fetta; _plm->put("R0",ive); _plm->rewrite(); // .. e il volume di affari nei pam real vaf = _pam->get_real("R1"); vaf += imp_fetta; _pam->put("R1", vaf); _pam->rewrite(); // Aggiorno i luridi pim bool was = look_pim(vi->_month, codatt, vi->_codreg, "0", item.codiva(), vi->_tipodet, TRUE); imp_fetta += _pim->get_real("R0"); iva_fetta += _pim->get_real("R1"); _pim->put("R0", imp_fetta); _pim->put("R1", iva_fetta); _pim->put("S4", item.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(item.codiva()); _pim->put("I1", (long)vendita); if (!_iva->get_bool("B4")) _pim->put("B3", "X"); } _pim->rewrite(); } } totven = 0.0; // Questa va azzerato, poiche' quando ancora non era prevista break; // la ventilazione annuale , registrava totven come 0.0 } } // memorizza totali per il prospettino di m. look_plm(month, codatt); // PAM e PUM _pam->put("R2",totacq); _pam->put("R3",totven); _pam->rewrite(); } // questa servIVA per il rimborso secondo le // nuove cazzonorme, mai entrate in vigore ma // devotamente programmate //class rObj : public TObject //{ //public: // real _imp; // real _iva; // real _perc; // // rObj() {} // virtual ~rObj() {} //}; _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 = 1; // se annuale considera tutti i mesi // 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 // u' casinu pazzescu d'u nuiu guvernu /*********************************************************************** Sembra che sia stato annullato subito dopo che ho finito di scrivere queste 150 righe di casino *********************************************************************** // due array dove ficcare i totali per // codiva in ordine di imponibile TArray varr, aarr; // 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; 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; } **************************************************************************/ // 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 || (month != 13 && (rmese < (next_trim(month)-2) || rmese > month))) continue; } else // Mensili if (year != ryear || (month != rmese && month != 13)) 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; }