From 3c9e122db8bf4e11971b5ab9478e86cf2cd16b3c Mon Sep 17 00:00:00 2001 From: bonazzi Date: Fri, 2 Dec 2016 00:15:23 +0000 Subject: [PATCH] Patch level : 12.0 308 Files correlati : cg1.exe cg1300m.uml Commento : RIcalcolo IVA differita git-svn-id: svn://10.65.10.50/branches/R_10_00@23414 c028cbd2-c16b-5b4b-a496-9718f37d4682 --- src/cg/cg1300.cpp | 3 + src/cg/cg1300m.h | 4 + src/cg/cg1300m.uml | 50 +++++ src/cg/cg1301.h | 1 + src/cg/cg1312.cpp | 467 +++++++++++++++++++++++++++++++++++++++++++++ src/cg/cg4301.cpp | 11 +- 6 files changed, 531 insertions(+), 5 deletions(-) create mode 100644 src/cg/cg1300m.h create mode 100644 src/cg/cg1300m.uml create mode 100644 src/cg/cg1312.cpp diff --git a/src/cg/cg1300.cpp b/src/cg/cg1300.cpp index ebe613893..74a876d5b 100755 --- a/src/cg/cg1300.cpp +++ b/src/cg/cg1300.cpp @@ -133,6 +133,9 @@ int cg1300(int argc, char* argv[]) case 'X': xref_check(argc, argv); break; + case 'V': + controlla_ivadiff(argc, argv); + break; case 'Z': elimina_zoppi(argc, argv); break; diff --git a/src/cg/cg1300m.h b/src/cg/cg1300m.h new file mode 100644 index 000000000..01934dc68 --- /dev/null +++ b/src/cg/cg1300m.h @@ -0,0 +1,4 @@ +#define F_CODDITTA 201 +#define F_RAGSOC 202 +#define F_ANNO 203 + diff --git a/src/cg/cg1300m.uml b/src/cg/cg1300m.uml new file mode 100644 index 000000000..e37d29d36 --- /dev/null +++ b/src/cg/cg1300m.uml @@ -0,0 +1,50 @@ +#include "cg1300m.h" + +TOOLBAR "topbar" 0 0 0 2 + + +BUTTON DLG_ELABORA 10 2 +BEGIN + PROMPT -13 -11 "~Elabora" + PICTURE TOOL_ELABORA + MESSAGE EXIT,K_ENTER +END + +#include + +BUTTON DLG_CANCEL 10 2 +BEGIN + PROMPT -33 -1 "" +END + +ENDPAGE + +PAGE "Controllo IVA Differita" 0 0 0 2 + +NUMBER F_CODDITTA 5 +BEGIN + PROMPT 2 2 "Ditta " + FLAGS "FRD" + USE LF_NDITTE KEY 1 + CHECKTYPE REQUIRED + INPUT CODDITTA F_CODDITTA + OUTPUT F_CODDITTA CODDITTA + OUTPUT F_RAGSOC RAGSOC +END + +STRING F_RAGSOC 50 +BEGIN + PROMPT 2 6 "Ragione sociale " + FLAGS "D" +END + +NUMBER F_ANNO 4 +BEGIN + PROMPT 2 10 "Anno " + FLAGS "A" + CHECKTYPE REQUIRED +END + +ENDPAGE + +ENDMASK \ No newline at end of file diff --git a/src/cg/cg1301.h b/src/cg/cg1301.h index 1208d016f..e56cc6acf 100755 --- a/src/cg/cg1301.h +++ b/src/cg/cg1301.h @@ -4,3 +4,4 @@ void setta_meseliq(int argc, char* argv[]); void controlla_PIVA(int argc, char* argv[]); void agg_iban(int argc, char* argv[]); void xref_check(int argc, char* argv[]); +void controlla_ivadiff(int argc, char* argv[]); diff --git a/src/cg/cg1312.cpp b/src/cg/cg1312.cpp new file mode 100644 index 000000000..c254ce2f9 --- /dev/null +++ b/src/cg/cg1312.cpp @@ -0,0 +1,467 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "cgsaldac.h" +#include "cglib03.h" +#include "cg1300m.h" + +#include +#include +#include +#include +#include + +#define AGR_PCON1 201 +#define AGR_PCON2 202 + +enum tiporeg { vendita = 1, acquisto = 2 }; + +/////////////////////////////////////////////////////////// +// TCheck_ivadiff_mask +/////////////////////////////////////////////////////////// + +class TCheck_ivadiff_mask : public TAutomask +{ +protected: + virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); + +public: + TCheck_ivadiff_mask() : TAutomask("cg1300m") { } +}; + +// Carica lo sheet in base alle impostazioni correnti (F_CLIFO, F_COFI) +bool TCheck_ivadiff_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) +{ + switch (o.dlg()) + { + case F_CODDITTA: + break; + case F_ANNO: + break; + default: break; + } + return true; +} + +/////////////////////////////////////////////////////////// +// TCheck_ivadiff +/////////////////////////////////////////////////////////// + +static bool partita_chiusa_al(const TPartita& p, const TDate& d) +{ + bool c = p.chiusa(); + + if (c) + { + const TImporto imp = p.calcola_saldo_al(true, d, d, d); + c = imp.is_zero(); + } + return c; +} + +class TCheck_ivadiff : public TSkeleton_application +{ + +protected: + bool ivadiff_chiusa(const TRectype& mov, const TDate& fine) const; + void check_year(long firm, int year); + bool is_date_ok(const TDate& d, int liqmonth, int year) const; + +public: + virtual void main_loop(); +}; + +bool TCheck_ivadiff::ivadiff_chiusa(const TRectype& mov, const TDate& fine) const +{ + bool chiusa = false; + const long numreg = mov.get_long(MOV_NUMREG); + TLocalisamfile id(LF_IVADIFF); + TRectype& rid = id.curr(); + rid.put(MOV_NUMREG, numreg); + int err = id.read(_isgteq); + + if (err == NOERR && rid.get_long(MOV_NUMREG) == numreg) + { + bool some_pag = false; // Ci sono pagamenti? + TImporto tot; + for (; err == NOERR && rid.get_long(MOV_NUMREG) == numreg; err = id.next()) + { + const TDate data = rid.get("DATAREGP"); + if (data > fine) + continue; + if (data == fine && rid.get_long("NUMREGP") == numreg) + continue; // Ignora pagamento automatico dopo un anno + + const real imp = rid.get(RMI_IMPOSTA); + if (!imp.is_zero()) + { + const char sez = rid.get_char("SEZIONE"); + tot += TImporto(sez, imp); + if (!some_pag && rid.get_int(MOV_TIPOMOV) > 1) + some_pag = true; + } + } + chiusa = some_pag && tot.valore() < 0.01; + } + return chiusa; +} + +bool TCheck_ivadiff::is_date_ok(const TDate& d, int liqmonth, int year) const + // true se la data passata va considerata nel + // ricalcolo dei progressivi mensili per il mese e anno + // selezionati. Vedi cg4301.cpp per maggiori informazioni + // sul nuovo filtro di selezione movimenti. +{ + const int regyear = d.year(); + + return (regyear == year && liqmonth != 12) || (regyear == year + 1 && liqmonth == 12); +} + +void TCheck_ivadiff::check_year(long firm, int year) +{ + if (!(has_module(SCAUT, CHK_DONGLE) && ini_get_bool(CONFIG_DITTA, "cg", "GesSal"))) + { + warning_box("Per l'iva differita o per cassa è necessario il saldaconto"); + return; + } + + const long old_firm = prefix().get_codditta(); + + prefix().set_codditta(firm); + + TString16 key; key.format("%05ld%04d", firm, year); + TRectype & lia = (TRectype &) cache().get("%LIA", key); + const TString4 freqviva = lia.get("S7"); + TRelation rel(LF_MOV); + rel.add(LF_RMOVIVA,"NUMREG=NUMREG"); + rel.add(LF_PCON,"GRUPPO=GRUPPO|CONTO=CONTO",1,LF_RMOVIVA,AGR_PCON1); + rel.add(LF_PCON,"GRUPPO=GRUPPO|CONTO=CONTO|SOTTOCONTO=SOTTOCONTO",1,LF_RMOVIVA,AGR_PCON2); + rel.add(LF_CAUSALI,"CODCAUS=CODCAUS"); + + TCursor cur(&rel, "", 4); + TLocalisamfile & mov = cur.relation()->lfile(); + TLocalisamfile & rmoviva = cur.relation()->lfile(LF_RMOVIVA); + TRectype from(cur.curr()); from.zero(); + TRectype to(from); + TString8 fromreg("~"), toreg("0"); + TRelation regrel("REG"); + TCursor reg(®rel); + TString4 codreg; + long items = reg.items(); + const TDate fromdate(1, 1, year); + const TDate todate(31, 12, year); + TString filter; + + for (reg = 0L; reg.pos() < items; ++reg) + { + codreg = reg.curr().get("CODTAB").mid(4); + + if (codreg < fromreg) + fromreg = codreg; + if (codreg > toreg) + toreg = codreg; + } + + from.put(MOV_REG, fromreg); + to.put(MOV_REG, toreg); + filter.format("BETWEEN(DATAREG,%ld,%ld)&&NUM(LIQDIFF==\"X\")", fromdate.date2ansi(), todate.date2ansi()); + + cur.freeze(false); + cur.setregion(from, to); + cur.setfilter(filter); + items = cur.items(); + cur.freeze(); + + TString pimsg; + pimsg << TR("Ricalcolo IVA differita ditta ") << firm << TR(" anno ") << year; + + TProgress_monitor pi(items, pimsg, false); + + for (cur = 0L; cur.pos() < items; ++cur) + { + if (!pi.set_status(cur.pos())) + break; + + const TString4 codreg = mov.get("REG"); + TString16 s; s << year; s << format("%-3s", (const char *) codreg); + const TRectype & reg = cache().get("REG", s); + + TDate date = mov.get(MOV_DATAREG); + const int liqmonth = mov.get_int(MOV_MESELIQ); + const TString4 tipodoc = mov.get(MOV_TIPODOC); + const bool corrisp = reg.get_bool("B0"); + tipo_movimento tm = (tipo_movimento)mov.get_int(MOV_TIPOMOV); + const tiporeg tipomov = (tiporeg) reg.get_int("I0"); // 1=Vendite; 2=Acquisti + + + // Inizio gestione IVA differita + bool dok = is_date_ok(date, liqmonth, year); + TPartite_array arrpart; // Partite interessate + TPointer_array pagscatt; // Righe di pagsca interessate + + if (tm == tm_fattura) + { + const bool iva_diff = is_IVA_diff(mov.curr()); + const bool id_chiusa = ivadiff_chiusa(mov.curr(), TDate(31,12,year-1)); + + if (!dok && id_chiusa) + continue; // Salta vecchi movimenti differiti già chiusi + + // Sezione preferita per fatture decisa in base a vendita->'A' o acquisto->'D' + const char sezfat = tipomov == vendita ? 'D' : 'A'; + const char sezpag = (sezfat=='D') ? 'A' : 'D'; + const long numreg = mov.get_long(MOV_NUMREG); + real tot_incassato, tot_da_incassare; + bool game_found = false; + + arrpart.add_numreg(numreg); + const TPartita* p = arrpart.first(); + const int row = p ? p->mov2rig(numreg, 0) : 0; + game_found = row > 0; + if (game_found && !id_chiusa) + { + const TRiga_partite& rp = p->riga(row); + + TDate orizzonte = todate; // caso tradizionale + TImporto pg_per, nc_per; + + rp.calcola_pagato_periodo(fromdate+1L, orizzonte, pg_per, nc_per, &pagscatt); + if (pagscatt.items() >= 2) + { + // Fondo tra loro le righe generate dallo stesso pagamento + for (int p = pagscatt.last(); p > 0; p--) + { + const TRectype& p0 = (const TRectype&)pagscatt[p]; + const TRectype& p1 = (const TRectype&)pagscatt[p-1]; + if (p0.get_int(PAGSCA_NRIGP) == p1.get_int(PAGSCA_NRIGP)) + { + const real imp = p0.get_real(PAGSCA_IMPORTO); + ((TRectype&)p1).add(PAGSCA_IMPORTO, imp); + pagscatt.destroy(p, true); + } + } + } + if (iva_diff) + { + TPointer_array pagscaold; + TImporto pg_tot, nc_tot; + + rp.calcola_pagato_periodo(TDate(0L), orizzonte, pg_tot, nc_tot, &pagscaold); + // Controllo se ci siam persi delle note di credito negli anni scorsi + if (!nc_tot.is_zero() && pagscaold.items() > pagscatt.items()) + { + FOR_EACH_ARRAY_ITEM(pagscaold, i, obj) + { + const TRectype& pagsca = *(const TRectype*)obj; + const int anno = pagsca.get_int(PAGSCA_ANNO); + const int nrigp = pagsca.get_int(PAGSCA_NRIGP); + // Appartiene all'anno scorso? + if (anno < year && nrigp < 999) // 9999 on pagsca -> 999 on ivadiff + { + const TPartita& p = arrpart.partita(pagsca); + const TRiga_partite& rp = p.riga(nrigp); + // E' veramente una nota di credito? + if (rp.tipo() == tm_nota_credito) + { + bool found = false; + FOR_EACH_ARRAY_ITEM(pagscatt, j, ps) + { + if (ps == obj) + { + found = true; + break; + } + } + if (!found) + { + TLocalisamfile id(LF_IVADIFF); + id.put(RMI_NUMREG, rmoviva.get(RMI_NUMREG)); + id.put(RMI_NUMRIG, rmoviva.get(RMI_NUMRIG)); + id.put("NUMPRO", nrigp); + if (id.read(_isequal) != NOERR || id.get_int("ANNOLIQ") == 0) + pagscatt.add(obj); + } + } + } + } + } + + TImporto incasso = pg_tot; + TImporto saldo = rp.importo(false); + + incasso += nc_tot; + saldo += incasso; + saldo.normalize(sezfat); + incasso.normalize(sezpag); + if (saldo.valore() > ZERO) + tot_da_incassare = saldo.valore(); + if (incasso.valore() > ZERO) + tot_incassato = incasso.valore(); + } + } + } + + do + { + const int rmi_tipoatt = max(rmoviva.get_int(RMI_TIPOATT), 1); // Poteva capitare tipoatt == 0 + const TString4 codiva = rmoviva.get(RMI_CODIVA); + TCodiceIVA civa(codiva); + + if (!civa.ok()) + { + error_box(FR("Codice IVA \"%s\" non riconosciuto alla riga %d del movimento %ld."), + (const char*)codiva, rmoviva.get_int(RMI_NUMRIG), rmoviva.get_long(RMI_NUMREG)); + continue; + } + + const real imponibile_orig = rmoviva.get_real(RMI_IMPONIBILE); + const real imposta_orig = rmoviva.get_real(RMI_IMPOSTA); + const real lordo_orig = imponibile_orig + imposta_orig; + + + if (tm == tm_fattura) + { + const char sezfat = tipomov == vendita ? 'D' : 'A'; + const TDate datareg = mov.get(MOV_DATAREG); + + TLocalisamfile id(LF_IVADIFF); + id.put(RMI_NUMREG, rmoviva.get(RMI_NUMREG)); + id.put(RMI_NUMRIG, rmoviva.get(RMI_NUMRIG)); + id.put("NUMPRO", 0); + if (id.read(_isequal) != NOERR) + { + id.zero(); + id.put(RMI_NUMREG, rmoviva.get(RMI_NUMREG)); + id.put(RMI_NUMRIG, rmoviva.get(RMI_NUMRIG)); + id.put("NUMPRO", 0); + id.put(PART_TIPOMOV, tm); + id.put("TIPOATT", rmi_tipoatt); + id.put("ANNOLIQ", datareg.year()); + + int mesereg = datareg.month(); + if (freqviva == "T") + { + const int resto = mesereg % 3; + if (resto > 0) + mesereg += 3-resto; + } + + id.put("MESELIQ", mesereg); + id.put("TIPOIVA", tipomov == 2 ? 2 : 1); + id.put("TIPODIFF", 1); + id.put(MOV_DATAREG, mov.get(MOV_DATADOC)); + id.put(RMI_CODIVA, codiva); + id.put("SEZIONE", sezfat); + + id.put("IMPORTO", imponibile_orig+imposta_orig); + id.put(RMI_IMPONIBILE, imponibile_orig); + id.put(RMI_IMPOSTA, imposta_orig); + + const int ew = id.write(); + if (ew != NOERR) + cantwrite_box(id.description()); + } + } + + if (!pagscatt.empty()) + { + const char sezpag = tipomov == vendita ? 'A' : 'D'; + real totfat = mov.get(MOV_TOTDOC); + real tot = totfat; + + TLocalisamfile id(LF_IVADIFF); + TRectype& idcurr = id.curr(); + FOR_EACH_ARRAY_ITEM(pagscatt, r, obj) + { + const TRectype& pagsca = *(TRectype*)obj; + const int nrigp = pagsca.get_int(PAGSCA_NRIGP); + + id.zero(); + idcurr.put(RMI_NUMREG, rmoviva.get(RMI_NUMREG)); + idcurr.put(RMI_NUMRIG, rmoviva.get(RMI_NUMRIG)); + CHECKD(nrigp > 0, "Invalid NRIGP ", nrigp); + idcurr.put("NUMPRO", min(nrigp, 999)); + if (id.read(_isequal, _lock) != NOERR) + { + id.zero(); + idcurr.put(RMI_NUMREG, rmoviva.get(RMI_NUMREG)); + idcurr.put(RMI_NUMRIG, rmoviva.get(RMI_NUMRIG)); + idcurr.put("NUMPRO", min(nrigp, 999)); + idcurr.put(MOV_DATAREG, mov.get(MOV_DATADOC)); + idcurr.put("TIPOATT", rmi_tipoatt); + idcurr.put("TIPOIVA", tipomov == 2 ? 2 : 1); + idcurr.put("TIPODIFF", 1); + idcurr.put(RMI_CODIVA, codiva); + + TImporto pagtmp; + bool ultimo = false; + tipo_movimento tipomov_pag = tm_pagamento; + if (nrigp > 0) + { + const TPartita& p = arrpart.partita(pagsca); + const TRiga_partite& rp = p.riga(nrigp); + tipomov_pag = rp.tipo(); + idcurr.put(PART_TIPOMOV, tipomov_pag); + idcurr.put("NUMREGP", rp.get(PART_NREG)); + idcurr.put("NUMRIGP", rp.get(PART_NUMRIG)); + TDate d = rp.get(PART_DATAPAG); + if (!d.ok()) + d = rp.get(PART_DATADOC); + if (!d.ok()) + d = rp.get(PART_DATAREG); + idcurr.put("DATAREGP", d); + idcurr.put("ANNOLIQ", d.year()); + pagtmp = p.importo_pagsca(pagsca); + pagtmp.normalize(sezpag); + ultimo = (r == pagscatt.last()) && partita_chiusa_al(p, todate); + } + + int meseliq = id.get_date("DATAREGP").month(); + if (freqviva == "T") + { + const int resto = meseliq % 3; + if (resto > 0) + meseliq += 3-resto; + } + idcurr.put("MESELIQ", meseliq); + idcurr.put("SEZIONE", pagtmp.sezione()); + + real val_imp = pagtmp.valore() * lordo_orig / tot; + real val_iva = civa.scorpora(val_imp, TCurrency::get_firm_dec()); + + idcurr.put("IMPORTO", val_imp + val_iva); + idcurr.put(RMI_IMPONIBILE, val_imp); + idcurr.put(RMI_IMPOSTA, val_iva); + + if (id.write() != NOERR) + cantwrite_box(id.description()); + } + } + } + } while (cur.next_match(LF_RMOVIVA)); + + } + prefix().set_codditta(firm); +} + +void TCheck_ivadiff::main_loop() +{ + TCheck_ivadiff_mask m; + while (m.run() == K_ENTER) + check_year(m.get_long(F_CODDITTA), m.get_int(F_ANNO)); +} + +void controlla_ivadiff(int argc, char* argv[]) +{ + TCheck_ivadiff cp; + cp.run(argc, argv, TR("Ricalcolo IVA differita")); +} diff --git a/src/cg/cg4301.cpp b/src/cg/cg4301.cpp index 6c8d26bb9..50d8e32b9 100755 --- a/src/cg/cg4301.cpp +++ b/src/cg/cg4301.cpp @@ -103,7 +103,7 @@ bool TLiquidazione_app::recalc_all() * -------------------------------------------------------------- */ - int need_refresh = false; + /* int need_refresh = false; if (_recalc != ever) { int m = _month == 13 ? _month : 1; @@ -123,18 +123,20 @@ bool TLiquidazione_app::recalc_all() "risultano ricalcolati. E' consigliabile il ricalcolo. " "Si desidera eseguirlo?"))) _recalc = ever; - } + } int m; for (m = 1; m <= _month; m++) // fino a 13 compreso { if (is_month_plain(m) || _recalc == ever) update_firm(m); - } + } */ + if (is_month_plain(_month)) + update_firm(_month); // se ci sono altri mesi dopo l'ultimo calcolato, invalida il // flag 'calcolato' del primo, per causare il ricalcolo dei // successivi (evitando problemi per credito precedente) - for (m = _month+1; m <= 13; m++) + for (int m = _month+1; m <= 13; m++) { TRectype lim = get_lim(m); @@ -705,7 +707,6 @@ static bool partita_chiusa_al(const TPartita& p, const TDate& d) return c; } - static void LOG_IVA_DIFF(const TRectype& id) { #ifndef NDEBUG