// ------------------------------------------------------------- // calcolo liquidazioni // part 3: utilities // fv 2-2-94 // -------------------------------------------------------------- #include #include #include "cg4300.h" bool TLiquidazione_app::is_trim(int x) // TRUE se il mese passato e' un trimestre { return x == 3 || x == 6 || x == 9 || x == 12; } bool TLiquidazione_app::is_month_ok_strict(int x, int month) // TRUE se il mese passato e' compatibile con il regime // di liquidazione e (opz) non e' maggiore di quello scelto { if (month == -1) month = x; return _freqviva == "M" ? ( x > 0 && x <= month) : ( x <= month && is_trim(x)); } bool TLiquidazione_app::is_month_plain(int x) // la piu' semplice: vero se mese == _month o se fa parte del // trimestre indicato da month { bool ok = x == _month; if (!ok && _freqviva == "T") { // aggiusta al trimestre il mese da calcolare int mto = _month; mto += 2 - ((mto-1) % 3); ok = x > (mto - 3) && x <= mto; } return ok; } bool TLiquidazione_app::is_month_ok(int x, int mtocalc) // TRUE se il mese passato e' compatibile con il mese da calcolare // rispetto al regime di liquidazione scelto { bool ret = x == mtocalc; if (!ret && _freqviva == "T" && mtocalc != 13) { // aggiusta al trimestre il mese da calcolare mtocalc += 2 - ((mtocalc-1) % 3); ret = x > (mtocalc - 3) && x <= mtocalc; } else if (!ret && mtocalc == 13) { // per l'annuale ritorna TRUE per tutti i mesi da liquidare ret = x <= 13; } return ret; } int TLiquidazione_app::liq_month(int x) // ritorna il mese da liquidare (= LIM presente) // che corrisponde al mese passato { if (x == 13 || _freqviva == "M") return x; else return next_trim(x); } int TLiquidazione_app::next_trim(int x) { if (x == 13) x = 12; return x + (2 - ((x-1) % 3)); } bool TLiquidazione_app::is_in_liq_period(TDate& d) { bool ok = FALSE; const int y = atoi(_year); if (_freqviva == "M") ok = d.month() == _month && d.year() == y; else { int m = liq_month(_month); ok = d.month() > m - 3 && d.month() <= m && d.year() == y; } return ok; } bool TLiquidazione_app::is_first_month(int m) { return _freqviva == "M" ? m == 1 : m == 3; } int TLiquidazione_app::previous_month(int m) { // vale per LIM (mese o trimestre precedente) if (_freqviva == "M") return m == 1 ? 1 : m - 1; else return m == 3 ? 3 : m - 3; } bool TLiquidazione_app::is_date_ok(TDate& d, int month) // TRUE se la data (di mov o pim) passata va considerata nel // ricalcolo dei progressivi mensili per il mese e anno // selezionati; se month == 13 vanno bene tutte purche' // sia giusto l'anno { if (d.month() > month || d.year() != atoi(_year)) return FALSE; if (month == 13) return d.month() <= month; else return d.month() == month; } void TLiquidazione_app::add_ventilation(real iva, real howmuch, const char* codiva, const char* other) { _VentItem* vi = NULL; for (int i = 0; i < _vent_arr.items(); i++) { vi = (_VentItem*)&_vent_arr[i]; if (vi->_codiva == codiva) break; } if (i == _vent_arr.items()) { _vent_arr.add(vi = new _VentItem); vi->_aliquota = iva; vi->_codiva = codiva; vi->_other = other; } vi->_totale += howmuch; } void TLiquidazione_app::add_vendite(int month, const char* codreg, int tipodet, real& r) { _VendItem* vi = NULL; for (int i = 0; i < _vend_arr.items(); i++) { vi = (_VendItem*)&_vend_arr[i]; if (vi->_codreg == codreg && vi->_month == month && vi->_tipodet == tipodet) break; } if (i == _vend_arr.items()) { _vend_arr.add(vi = new _VendItem); vi->_codreg = codreg; vi->_month = month; vi->_tipodet = tipodet; } vi->_totale += r; } void TLiquidazione_app::add_corrisp(int month, const char* codreg, real& r, real& p, int tipodet, const char* codiva, const char* codatt) { _CorrItem* ci = NULL; const int nitems = _corr_arr.items(); for (int i = 0; i < nitems; i++) { ci = (_CorrItem*)&_corr_arr[i]; if (ci->_codreg == codreg && ci->_month == month && ci->_codiva == codiva && ci->_tipodet == tipodet && ci->_codatt == codatt) break; } if (i == nitems) { _corr_arr.add(ci = new _CorrItem); ci->_codreg = codreg; ci->_month = month; ci->_codiva = codiva; ci->_codatt = codatt; ci->_tipodet = tipodet; ci->_aliquota = p; } ci->_totale += r; } void TLiquidazione_app::lordo2netto(const real& totale, real& imponibile, real& imposta, const real& aliquota) { /* *** Questo e' stato preso da recalc_corrispettivi() real imposta = (abs(ci->_totale) * ci->_aliquota)/(ci->_aliquota + 1.00); imposta.ceil(); if (ci->_totale.sign() < 0) imposta = -imposta; real imponibile = ci->_totale - imposta; // quadratura del cerchione real delta = ci->_totale - imponibile - imposta; if (!delta.is_zero()) imposta += delta; */ imposta = (abs(totale) * aliquota)/(aliquota + 1.00); imposta.ceil(); if (totale.sign() < 0) imposta = -imposta; imponibile = totale - imposta; // quadratura del cerchione real delta = totale - imponibile - imposta; if (!delta.is_zero()) imposta += delta; } void TLiquidazione_app::lordo2netto(real& imponibile, real& imposta, const real& aliquota) { real totale(imponibile); lordo2netto(totale, imponibile, imposta, aliquota); } bool TLiquidazione_app::look_pim(int month, const char* codatt, const char* codreg, const char* tipocr, const char* codiva, int tipodet, bool create) // ritorna il PIM corrispondente alla chiave passata; se // create = TRUE lo crea se non lo trova. Ritorna se c'era { bool ok = FALSE; _pim_r->zero(); (*_pim_anno) = _year; (*_pim_mese) = format("%02d", month); (*_pim_codreg) = codreg; (*_pim_codiva) = codiva; (*_pim_codatt) = codatt; (*_pim_tipocr) = tipocr; (*_pim_tipodet) = tipodet; TString s = _pim_r->get("CODTAB"); _pim->read(); ok = _pim->good(); if (!ok && create) { _pim_r->zero(); _pim_r->put("CODTAB",s); _pim->write(); } return ok; } bool TLiquidazione_app::look_plm(int m, const char* a, bool create) { bool ok = FALSE; _plm_r->zero(); //(*_plm_codatt) = format("%06ld", atol(a)); (*_plm_codatt) = format("%6s", a); (*_plm_mese) = format("%02d",m); (*_plm_anno) = _year; TString s = _plm_r->get("CODTAB"); _plm->read(); ok = _plm->good(); if (!ok && create) { _plm_r->zero(); _plm_r->put("CODTAB",s); _plm->write(); } // crea/posiziona tabelle gemelle PAM, PUM, POM look_pam(m,a,!ok); look_pum(m,a,!ok); look_pom(m,a,!ok); return ok; } bool TLiquidazione_app::look_pum(int m, const char* a, bool create) { bool ok = FALSE; _pum->zero(); //(*_pum_codatt) = format("%06ld", atol(a)); (*_pum_codatt) = format("%6s", a); (*_pum_mese) = format("%02d",m); (*_pum_anno) = _year; TString s = _pum->get("CODTAB"); _pum->read(); ok = _pum->good(); if (!ok && create) { _pum->zero(); _pum->put("CODTAB",s); _pum->write(); } return ok; } bool TLiquidazione_app::look_pom(int m, const char* a, bool create) { bool ok = FALSE; _pom->zero(); //(*_pom_codatt) = format("%06ld", atol(a)); (*_pom_codatt) = format("%6s", a); (*_pom_mese) = format("%02d",m); (*_pom_anno) = _year; TString s = _pom->get("CODTAB"); _pom->read(); ok = _pom->good(); if (!ok && create) { _pom->zero(); _pom->put("CODTAB",s); _pom->write(); } return ok; } bool TLiquidazione_app::look_pam(int m, const char* a, bool create) { bool ok = FALSE; _pam->zero(); //(*_pam_codatt) = format("%06ld", atol(a)); (*_pam_codatt) = format("%6s", a); (*_pam_mese) = format("%02d",m); (*_pam_anno) = _year; TString s = _pam->get("CODTAB"); _pam->read(); ok = _pam->good(); if (!ok && create) { _pam->zero(); _pam->put("CODTAB",s); _pam->write(); } return ok; } bool TLiquidazione_app::look_lim(int m, bool create) { bool ok = FALSE; _lim_r->zero(); (*_lim_mese) = format("%02d",m); (*_lim_anno) = _year; TString s = _lim_r->get("CODTAB"); _lim->read(); ok = _lim->good(); if (!ok && create) { _lim_r->zero(); _lim_r->put("CODTAB",s); _lim->write(); } // crea o posiziona la tabella gemella LAM look_lam(m, !ok); return ok; } bool TLiquidazione_app::look_lam(int m, bool create) { bool ok = FALSE; _lam_r->zero(); (*_lam_mese) = format("%02d",m); (*_lam_anno) = _year; TString s = _lam_r->get("CODTAB"); _lam->read(); ok = _lam->good(); if (!ok && create) { _lam_r->zero(); _lam_r->put("CODTAB",s); _lam->write(); } return ok; } bool TLiquidazione_app::look_pla(const char* a, bool create) { bool ok = FALSE; _pla_r->zero(); // forza il tipoatt a 1 TString buf(a); buf.ltrim(); buf.rtrim(1); buf << "1"; while (buf.len() < 6) buf.insert("0"); (*_pla_ditta) = format("%05ld", get_firm()); (*_pla_anno) = _year; (*_pla_codatt) = buf; TString16 s = _pla_r->get("CODTAB"); _pla->read(); ok = _pla->good(); if (!ok && create) { _pla->zero(); _pla_r->put("CODTAB",s); _pla->write(); } return ok; } bool TLiquidazione_app::look_reg(const char* reg) { TString s(12); s << _year; s << format("%-3s",reg); bool rt = TRUE; const bool is_key = _reg_arr.is_key(s); if (is_key) _reg->curr() = (TRectype&) _reg_arr[s]; else { _reg_r->zero(); _reg_r->put("CODTAB",s); if (_reg->read() == NOERR) _reg_arr.add(s,_reg->curr()); else rt = FALSE; } return rt; } bool TLiquidazione_app::look_iva(const char* cod) { bool rt = TRUE; TString16 s(cod); const bool is_key = _codiva_arr.is_key(cod); if (is_key) _iva->curr() = (TRectype&) _codiva_arr[s]; else { _iva->zero(); _iva->put("CODTAB",s); if (_iva->read() == NOERR) _codiva_arr.add(s,_iva->curr()); else rt = FALSE; } return rt; } bool TLiquidazione_app::look_ppa(int month, const char* codatt, int type, bool create) { _ppa->zero(); (*_ppa_year) = _year; (*_ppa_month) = format("%02d",month); //(*_ppa_codatt) = format("%06ld", atol(codatt)); (*_ppa_codatt) = format("%6s", codatt); (*_ppa_kind) = type; TString ctab = _ppa_r->get("CODTAB"); _ppa->read(); bool ok = _ppa->good(); if (!ok && create) { _ppa_r->zero(); _ppa_r->put("CODTAB",ctab); _ppa->write(); } return ok; } bool TLiquidazione_app::look_del(int month, int type, bool create) { // se chiamata con il flag di creazione, aggiorna le info su // codici tributo, concessione, conto fiscale anche se la // delega esiste gia' // Molto pericoloso chiamare con create = TRUE: // se e' gia' stata fatta l'estrazione versamenti // e l'utente cambia titcf e isdel sull'anagrafica // sono c... suoi!!! (Maurizio) // deve rifarsi la delega con l'ESTRAZIONE VERSAMENTI // io l'ho lasciato per rispetto del lavoro altrui long ditta = _nditte->curr().get_long("CODDITTA"); _del->zero(); (*_del_ditta) = format("%05ld", ditta); (*_del_anno) = _year; (*_del_mese) = format("%02d", month); (*_del_tipo) = format("%1d", type); TString16 ctab = _del->get("CODTAB"); _del->read(); bool ok = _del->good(); if (!ok && create) { _del->zero(); _del->put("CODTAB",ctab); } if (create) { // vedi se titolare conto fiscale bool titcf = FALSE; bool isdel = FALSE; int uffiva; TLocalisamfile anag(LF_ANAG); anag.zero(); anag.put("TIPOA", _nditte->lfile().get("TIPOA")); anag.put("CODANAGR", _nditte->lfile().get("CODANAGR")); if (anag.read() == NOERR) { titcf = anag.get_bool("TITCF"); isdel = anag.get_long("TIPOSTDEL") == 0l; uffiva = anag.get_int("UFFIVA"); } if (!titcf || isdel) { // non titolare conto fiscale oppure paga con delega: // cerca banca // codici ABI e CAB da anagrafica ditte TString16 abi, cab; abi = _nditte->lfile().get("ABIBAN"); cab = _nditte->lfile().get("CABBAN"); if (abi.empty()) { /* abi = anag.get("CODABI"); cab = anag.get("CODCAB"); */ TConfig c (CONFIG_STUDIO, "cg"); abi = c.get("CodABI"); cab = c.get("CodCAB"); } _del->put("S7", abi); _del->put("S8", cab); _del->put("S9", ""); // per sicurezza! (visto che non devono mai } // esistere entrambe else { // non usa delega bensi' bollettino o distinta: // cerca concessione comune // infila ufficio concessione in S9 // e descrizione comune in S2 TString16 con; TString uva; if (look_conc(con, uva)) { _del->put("S9", con); _del->put("S2", uva); _del->put("S7", ""); _del->put("S8", ""); } } } //fine create // le descrizioni sulla delega non vengono // memorizzate dai vari programmi di gestione // e estrazione ma solo qui. if (ok) { int uffiva; TLocalisamfile anag(LF_ANAG); anag.zero(); anag.put("TIPOA", _nditte->lfile().get("TIPOA")); anag.put("CODANAGR", _nditte->lfile().get("CODANAGR")); if (anag.read() == NOERR) uffiva = anag.get_int("UFFIVA"); TString16 abi = _del->get("S7"); TString16 cab = _del->get("S8"); TString16 con = _del->get("S9"); // descrizione banca if (abi.not_empty()) { TTable ban("%BAN"); ban.zero(); TString codban = format("%05ld", atol(abi)); if (!cab.empty()) codban << format("%05ld", atol(cab)); ban.put("CODTAB", codban); if (ban.read() == NOERR) { TString desban(ban.get("S0")); _del->put("S1", desban); } //che rottura: ogni giorno alla prassi cambiano idea!!! TTable uiv("%UIV"); uiv.zero(); TString16 coduff = format("%03d", uffiva); uiv.put("CODTAB", coduff); if (uiv.read() == NOERR) { TString desiva(uiv.get("S0")); _del->put("S2", desiva); } } else if (con.not_empty()) { TString uva; if (look_conc(con, uva)) _del->put("S2", uva); } } // scrive codice tributo int ctri = 6000; if (month == 13 && type == 7) ctri = 6035; // acconto IVA annuale (trimestrali?) else if (month == 13 && type == 1) ctri = 6099; // IVA annuale else if (month < 13 && type == 7) ctri = 6013; // acconto mensile else if (month < 13 && type == 1) // regular ctri = _freqviva == "M" ? 6000 + month : 6030 + (month/3); _del->put("S6", format("%d",ctri)); if (!ok) _del->write(); else _del->rewrite(); return ok; } bool TLiquidazione_app::look_lia(long ditta, bool create, int year) { if (year == 0) year = atoi(_year); if (ditta == 0l) ditta = get_firm(); TString16 y; y.format("%05ld%04d", ditta, year); _lia->zero(); _lia->put("CODTAB", y); _lia->read(); const bool ok = _lia->good(); if (!ok && create) { _lia->zero(); _lia->put("CODTAB", y); _lia->put("S7", _freqviva); _lia->write(); } return ok; } real TLiquidazione_app::result_liq(int month) // risultato esatto della liquidazione del mese month, <0 a credito // > 0 a debito; comprende TUTTI, anche il conguaglio prorata in annuale { real r(0.0); // ulteriori detrazioni, acconti, versamenti, // rettifiche, conguagli sono gia' compresi in R0 if (look_lim(month)) r = _lim->get_real("R0"); return r; } real TLiquidazione_app::debt_prec(int month) { real r(0.0); if (!is_first_month(month)) { if (look_lim(previous_month(month))) { r = result_liq(previous_month(month)); if (!(r.sign() > 0 && r < IVA_DA_RIPORTARE)) r = ZERO; } } return r; } real TLiquidazione_app::credito_prec(int month) // ritorna l'appropriato credito precedente al mese in corso { real c(0.0); if (is_first_month(month)) { // credito inizio anno if (look_lia()) c = _lia->get_real("R0"); // e' positivo o 0 } else { c = result_liq(previous_month(month)); if (c.sign() < 0) c = abs(c); else c = real(0.0); } return c; } real TLiquidazione_app::credito_costo_prec(int month) // ritorna l'appropriato credito di costo precedente al mese in corso // (travel agency only) { real c(0.0); if (is_first_month(month) || month == 13) { // credito inizio anno if (look_lia()) c = _lia->get_real("R5"); } else { if (look_lim(previous_month(month))) // qui il rimborso non c'e' c = _lim->get_real("R2"); } look_lim(month); return c; } real TLiquidazione_app::versamenti_IVA(int month, const char* types, bool intr) { real ret(0.0); TToken_string typ(types); for (int i = 0; i < typ.items(); i++) { int tp = typ.get_int(i); if (look_del(month,tp)) { //if (_del->get_bool("B0") || _is_visliq) // solo se stampata, a meno // che non sia per visliq real importo_dovuto_non_arrotondato(_del->get_real("R2")); real interessi(_del->get_real("R1")); real importo_dovuto_arrotondato(_del->get_real("R0")); real work(importo_dovuto_non_arrotondato); //work.round(ROUND_MILLELIRE); round_mille_lire(work); if (_month == 13 && _freqviva == "T" && importo_dovuto_arrotondato == work) ret += importo_dovuto_non_arrotondato; // Questo e' l'importo lordo non arrotondato!! else ret += importo_dovuto_arrotondato; //gli interessi vengono memorizzati solo se si //devono pagare (=> nessun controllo su intra) if (!(_is_visliq && _freqviva == "T")) // toglie gli interessi se non siamo in visualiz. e la ditta non e' TRIM ret -= interessi; // al netto degli interessi // In caso di 13a liq e per trimestrali... devo fare la somma // degli importi netti dovuti, ecco perche' leggo R2, // perche togliendo poi gli interessi ottengo il dovuto netto! // Questa casistica vale pero' solo se in R2 c'e' qualcosa(!=0) ed // e' relativo all'importo presente in R0. Ovvero: // nel caso si estraggano i versamenti trimestrali, i campi R2 // vengono correttamente compilati. Se poi si modificano a mano i // valori di R0 (tramite gestione versamenti, visualizzazione o // calcolo acconti) tale importo non e' piu' consistente, ecco quindi // il controllo effettuato tra R0 e ROUND(R2). In realta' sarebbe piu' // oppurtuno che in gestione versamenti, visualizzazione liquidazione e // calcolo acconti, vi sia la possibilita' di modificare anche R2. // Tutto cio' e' relativo all'errore MI3386. } } return ret; } void TLiquidazione_app::round_mille_lire(real& d) { if (d % 500.0 == ZERO) d -= 1.0; d.round(ROUND_MILLELIRE); } // Ritorna il parametro della liquidazione differita per la ditta corrente, cosi come // e' scritto sui parametri liquidazione (LIA) // Se si passa 0 (default) vede prende la ditta correntemente in corso di calcolo // Analogamente per l'anno bool TLiquidazione_app::is_differita(long firm, int year) { long d = (firm == 0) ? _nditte->lfile().get_long("CODDITTA") : firm; int y = (year == 0) ? atoi(_year) : year; if (look_lia(d,atoi(_year))) return _lia->get_bool("B1"); else return FALSE; } real TLiquidazione_app::aliquota_agvia() { TConfig cnf(CONFIG_STUDIO); look_iva(cnf.get("CodAgv")); real r = _iva->get_real("R0"); return r; } real TLiquidazione_app::interesse_trimestrale(int month) { month--; month /= 3; real r(_ver->get(month)); // month varia da 0 a 4, proprio come da P_1_TRIMESTRE... in poi return r; } bool TLiquidazione_app::look_conc(TString& uffcon, TString& uffiva) { // piazza nelle TString passate: l'ufficio concessioni // l'ufficio IVA. Quest'ultimo e' preso dall'anagrafica se // c'e', dal comune (primo non vuoto) se non // Assume _nditte correctly positioned TString ana(_nditte->lfile().get("TIPOA")); TString codana(_nditte->lfile().get("CODANAGR")); // look anagrafica TLocalisamfile anagr(LF_ANAG); anagr.zero(); anagr.put("TIPOA", ana); anagr.put("CODANAGR", codana); if (anagr.read() != NOERR) return FALSE; // becca comune residenza fiscale TString com(anagr.get("COMRF")); // se non c'e', residenza if (com.empty()) com = anagr.get("COMRES"); if (com.empty()) return FALSE; // becca comune TLocalisamfile comuni(LF_COMUNI); comuni.zero(); // STATO = "" ovvero ITAGLIA comuni.put("COM", com); if (comuni.read() != NOERR) return FALSE; const int uffa = comuni.get_int("UFFCONC"); if (uffcon.empty()) uffcon = format("%03d",uffa); if (uffcon.not_empty()) { TTable ucc("%UCC"); ucc.zero(); ucc.put("CODTAB", uffcon); if (ucc.read() == NOERR) uffiva = ucc.get("S0"); } /* uffiva = comuni.get("DENCOM"); if (!comuni.get("PROVCOM").empty()) uffiva << " (" << comuni.get("PROVCOM") << ")"; */ return TRUE; }