#include #include #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; 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: void check_year(long firm); public: virtual void main_loop(); }; static void LOG_IVA_DIFF(TLog_report & rep, TTrec & trec, const TRectype& id) { TString msg(300); for (int f = 0; f < trec.fields(); f++) { TToken_string tmp = trec.fielddef(f); const TString val = id.get(tmp.get(0)); const TFieldtypes type = (TFieldtypes) tmp.get_int(); int len = tmp.get_int(); len = len < 10 ? 10 : len; if ((type < _intfld) || (type == _charfld) || (type == _boolfld)) len = -len; const TString16 fmt = format("%%%ds", len); msg << format(fmt, (const char *) val) << " "; } rep.log(0, msg); msg.cut(0); for (int i = 0; i < 132; i++) msg <<'_'; rep.log(0, msg); } void TCheck_ivadiff::check_year(long firm) { 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; } 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(); TLocalisamfile id(LF_IVADIFF); TRectype& idcurr = id.curr(); TString pimsg; pimsg << TR("Ricalcolo IVA differita ditta ") << firm; TLog_report rep(pimsg, "bagn011a"); TTrec trec; TToken_string msg; TToken_string tmp; rep.set_orientation(2); trec.get(LF_IVADIFF); for (int f = 0; f < trec.fields(); f++) { TToken_string tmp = trec.fielddef(f); const TString val = tmp.get(0); const TFieldtypes type = (TFieldtypes) tmp.get_int(); int len = tmp.get_int(); len = len < 10 ? 10 : len; if ((type < _intfld) || (type == _charfld) || (type == _boolfld)) len = -len; const TString16 fmt = format("%%%ds", len); msg << format(fmt, (const char *) val) << " "; } rep.log(0, ""); rep.log(0, msg); rep.log(0, ""); 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); const TString16 filter("LIQDIFF==\"X\""); cur.freeze(false); cur.setregion(from, to); cur.setfilter(filter); items = cur.items(); cur.freeze(); { TProgress_monitor pi(items, pimsg, false); for (cur = 0L; cur.pos() < items; ++cur) { if (!pi.set_status(cur.pos())) break; const TDate data = mov.get(MOV_DATAREG); const int year = data.year(); const TDate primo(1, 1, year); const TDate ultimo(31, 12, year); TString16 key; key.format("%05ld%04d", firm, year); TRectype & lia = (TRectype &) cache().get("%LIA", key); const TString4 freqviva = lia.get("S7"); const TString4 codreg = mov.get("REG"); TString16 s; s << year; s << format("%-3s", (const char *) codreg); const TRectype & reg = cache().get("REG", s); const int liqmonth = mov.get_int(MOV_MESELIQ); const TString4 tipodoc = mov.get(MOV_TIPODOC); const bool corrisp = reg.get_bool("B0"); const tiporeg tipomov = (tiporeg) reg.get_int("I0"); // 1=Vendite; 2=Acquisti TPartite_array arrpart; // Partite interessate TPointer_array pagscatt; // Righe di pagsca interessate const bool iva_diff = is_IVA_diff(mov.curr()); const char sezfat = tipomov == vendita ? 'D' : 'A'; // Sezione preferita per fatture decisa in base a vendita->'A' o acquisto->'D' 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) { const TRiga_partite& rp = p->riga(row); TImporto pg_per, nc_per; const bool chiusa = partita_chiusa_al(*p, ultimo); rp.calcola_pagato_periodo(primo, eotime, 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), ultimo, 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(); } } TISAM_recordset recset("USE IVADIFF\nFROM NUMREG=#NR\nTO NUMREG=#NR"); recset.set_var("#NR", numreg); TLocalisamfile& id = recset.cursor()->file(); TImporto saldo; for (bool ok = recset.move_first(); ok; ok = recset.move_next()) { const TImporto imp(id.get_char("SEZIONE"), id.get_real("IMPORTO")); saldo += imp; } bool idchiusa = saldo.is_zero(); for (bool ok = recset.move_first(); ok; ok = recset.move_next()) { id.put("CHIUSA", idchiusa); id.rewrite(); } 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; char sezfat = (tipomov == vendita) ? 'D' : 'A'; const TDate datareg = mov.get(MOV_DATAREG); const int numrig = rmoviva.get_int(RMI_NUMRIG); id.put(RMI_NUMREG, numreg); id.put(RMI_NUMRIG, numrig); id.put("NUMPRO", 0); if (id.read(_isequal) != NOERR) { id.zero(); id.put(RMI_NUMREG, numreg); id.put(RMI_NUMRIG, numrig); id.put("NUMPRO", 0); id.put(PART_TIPOMOV, tm_fattura); 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); if (id.write() == NOERR) LOG_IVA_DIFF(rep, trec, id.curr()); } if (!pagscatt.empty()) { const char sezpag = tipomov == vendita ? 'A' : 'D'; real totfat = mov.get(MOV_TOTDOC); real tot = totfat; FOR_EACH_ARRAY_ITEM(pagscatt, r, obj) { const TRectype& pagsca = *(TRectype*)obj; const int nrigp = pagsca.get_int(PAGSCA_NRIGP); const long numreg = rmoviva.get_long(RMI_NUMREG); const int numrig = rmoviva.get_int(RMI_NUMRIG); const TPartita& p = arrpart.partita(pagsca); const TRiga_partite& rp = p.riga(nrigp); const long nregpag = rp.get_long(PART_NREG); const int nrigpag = rp.get_int(PART_NUMRIG); TImporto pagtmp = p.importo_pagsca(pagsca); pagtmp.normalize(sezpag); real val_imp = pagtmp.valore() * lordo_orig / tot; real val_iva; if (r == pagscatt.last() && chiusa) { TLocalisamfile rid(LF_IVADIFF); rid.put(MOV_NUMREG, numreg); rid.put(RMI_NUMRIG, numrig); val_iva = imposta_orig; bool pag_found = false; int err = rid.read(_isgteq); for (; err == NOERR ; err = rid.next()) { const long ridnumreg =rid.get_long(RMI_NUMREG); const int ridnumrig = rid.get_int(RMI_NUMRIG); const tipo_movimento ridtipopag = (tipo_movimento) rid.get_int(PART_TIPOMOV); if (ridnumreg == numreg && ridnumrig == numrig) { if ((ridtipopag != tm_fattura) && ((rid.get_long("NUMREGP") != nregpag) && (rid.get_int("NUMRIGP") != nrigpag))) { pag_found = true; if (sezfat != sezpag) val_iva -= rid.get_real(RMI_IMPOSTA); else val_iva += rid.get_real(RMI_IMPOSTA); } } else break; if (!pag_found) val_iva = civa.scorpora(val_imp, TCurrency::get_firm_dec()); else civa.scorpora(val_imp, TCurrency::get_firm_dec()); } } else val_iva = civa.scorpora(val_imp, TCurrency::get_firm_dec()); id.zero(); id.put(RMI_NUMREG, numreg); id.put(RMI_NUMRIG, numrig); CHECKD(nrigp > 0, "Invalid NRIGP ", nrigp); id.put("NUMPRO", nrigp); if (id.read(_isequal, _lock) != NOERR) { id.zero(); id.put(RMI_NUMREG, numreg); id.put(RMI_NUMRIG, numrig); id.put("NUMPRO", nrigp); id.put(MOV_DATAREG, mov.get(MOV_DATADOC)); id.put("TIPOATT", rmi_tipoatt); id.put("TIPOIVA", tipomov == 2 ? 2 : 1); id.put("TIPODIFF", 1); id.put(RMI_CODIVA, codiva); tipo_movimento tipomov_pag = tm_pagamento; if (nrigp <= 0) fatal_box("numero riga pagamento errato partita : %s/%s - %d", (const char *) pagsca.get(PAGSCA_ANNO), (const char *) pagsca.get(PAGSCA_NUMPART), nrigp); TDate d = rp.get(PART_DATAPAG); tipomov_pag = rp.tipo(); id.put(PART_TIPOMOV, tipomov_pag); id.put("NUMREGP", rp.get(PART_NREG)); id.put("NUMRIGP", rp.get(PART_NUMRIG)); if (!d.ok()) d = rp.get(PART_DATADOC); if (!d.ok()) d = rp.get(PART_DATAREG); id.put("DATAREGP", d); id.put("ANNOLIQ", d.year()); int meseliq = d.month(); if (freqviva == "T") { const int resto = meseliq % 3; if (resto > 0) meseliq += 3-resto; } id.put("MESELIQ", meseliq); id.put("SEZIONE", pagtmp.sezione()); id.put("IMPORTO", val_imp + val_iva); id.put(RMI_IMPONIBILE, val_imp); id.put(RMI_IMPOSTA, val_iva); if (id.write() == NOERR) LOG_IVA_DIFF(rep, trec, id.curr()); } } } } while (cur.next_match(LF_RMOVIVA)); } } } rep.print_or_preview(); } void TCheck_ivadiff::main_loop() { TCheck_ivadiff_mask m; while (m.run() == K_ENTER) check_year(m.get_long(F_CODDITTA)); } void controlla_ivadiff(int argc, char* argv[]) { TCheck_ivadiff cp; cp.run(argc, argv, TR("Ricalcolo IVA differita")); }