#include "cglib.h" #include "cgsaldac.h" char frequenza_versamenti(const int year, long firm) { char freq = ' '; TString16 key; key.format("%05ld%d", firm, year); const TRectype & lia = cache().get("%LIA", key); if (firm <= 0L) firm = prefix().get_codditta(); freq = lia.get_char("S7"); if (freq != 'M' && freq != 'T') { const TRectype & firm_rec = cache().get(LF_NDITTE, firm); freq = firm_rec.get_char("FREQVIVA"); } if (freq != 'M' && freq != 'T') freq = 'M'; return freq; } int date2liq(const TDate& data, long firm) { const int anno = data.year(); int mese = data.month(); if (frequenza_versamenti(anno, firm) == 'T') mese += 2 - ((mese - 1) % 3); return mese; } bool controlla_liquidazione(const TDate & data, const TRegistro & registro, bool reset) { bool calcolata = false; const int anno = data.year(); const int mese = date2liq(data); // Chiave di LIM: Anno (1-4), Mese (5-6) TString16 key; key.format("%04d%02d", anno, mese); TTable lim("LIM"); lim.put("CODTAB", key); if (lim.read() == NOERR) { calcolata = data.month() <= registro.mese_stampa_ultima_liq(); // Controlla se progressivi ricalcolati (registri) if (reset) { // Resetta i flag di calcolato sulla liquidazione IVA del mese di registrazione lim.zero("B0"); // calcolato lim.rewrite(); } } if (reset) { const bool att_mista = registro.name().empty() ? FALSE : registro.attivita_mista(); const int att = att_mista ? 2 : 1; // Chiave di PLM: Anno (1-4), Cod. Att. (5-9), Tipo att. (10-10), Mese (11-12) TTable plm("PLM"); for (int a = 1; a <= att; a++) { TString16 chiave; TString8 attivita(registro.attivita()); attivita.right_just(5, '0'); TString4 mese; mese.format("%02d", data.month()); chiave << data.year() << attivita << a << mese; plm.put("CODTAB", chiave); if (plm.read() == NOERR && plm.get_bool("B0")) { plm.zero("B0"); plm.rewrite(); } } } return calcolata; } /////////////////////////////////////////////////////////// // Movimento di prima nota /////////////////////////////////////////////////////////// TMovimento_contabile::TMovimento_contabile() : TMultiple_rectype(LF_MOV), _old_iva(LF_RMOVIVA, RMI_NUMRIG) { add_file(LF_RMOV, RMV_NUMRIG); add_file(LF_RMOVIVA, RMV_NUMRIG); } TMovimento_contabile::TMovimento_contabile(const TMovimento_contabile& mov) : TMultiple_rectype(LF_MOV), _old_iva(LF_RMOVIVA, RMI_NUMRIG) { copy(mov); } TMovimento_contabile::TMovimento_contabile(long numreg) : TMultiple_rectype(LF_MOV), _old_iva(LF_RMOVIVA, RMI_NUMRIG) { add_file(LF_RMOV, RMV_NUMRIG); add_file(LF_RMOVIVA, RMV_NUMRIG); put(MOV_NUMREG, numreg); read(_isequal, _nolock); } TMovimento_contabile::TMovimento_contabile(const TRectype& mov) : TMultiple_rectype(LF_MOV), _old_iva(LF_RMOVIVA, RMI_NUMRIG) { add_file(LF_RMOV, RMV_NUMRIG); add_file(LF_RMOVIVA, RMV_NUMRIG); *this = mov; read(_isequal, _nolock); } int TMovimento_contabile::readat(TRecnotype nrec, word lockop) { TLocalisamfile f(LF_MOV); const int err = TMultiple_rectype::readat(f, nrec, lockop); if (err == NOERR) { _olddataliq = get_date(MOV_DATAREG); // Memorizza data liquidazione const int meseliq = get_int(MOV_MESELIQ); if (meseliq > 0 && meseliq != _olddataliq.month()) { _olddataliq.set_day(1); // Evita problemi coi mesi corti! _olddataliq.set_month(meseliq); } _old_iva = iva(); update_rev_charge(); } return err; } int TMovimento_contabile::read( word op, word lockop) { const int err = TMultiple_rectype::read(op, lockop); if (err == NOERR) { _olddataliq = get_date(MOV_DATAREG); // Memorizza data liquidazione const int meseliq = get_int(MOV_MESELIQ); if (meseliq > 0 && meseliq != _olddataliq.month()) { _olddataliq.set_day(1); // Evita problemi coi mesi corti! _olddataliq.set_month(meseliq); } _old_iva = iva(); update_rev_charge(); } return err; } int TMovimento_contabile::write_rewrite(TBaseisamfile& f, bool re) const { long numreg = get_long(MOV_NUMREG); // ?? TMovimento_contabile & this_mov = (TMovimento_contabile &)*this; if (numreg <= 0) { if (!re) // Tento di numerare automaticamente in caso di write { TLocalisamfile mov(LF_MOV); // Non sposto il file principale della relazione! if (mov.last() == NOERR) const long numreg = mov.get_long(MOV_NUMREG) + 1; this_mov.put(MOV_NUMREG, numreg); this_mov.cg().renum_key(RMV_NUMREG, numreg); this_mov.iva().renum_key(RMI_NUMREG, numreg); } else return _isnocurkey; } ((TMovimento_contabile *)this)->find_movcoll(); int err = TMultiple_rectype::write_rewrite(f, re); if (err == NOERR) { const int annoiva = get_int(MOV_ANNOIVA); const TString4 reg(get(MOV_REG)); TRegistro registro(reg, annoiva); const bool att_mista = reg.empty() ? false : registro.attivita_mista(); int last_iva = iva().last_row(); for (int i = iva().first_row(); i <= last_iva; i = iva().succ_row(i)) { TRectype & r = this_mov.iva(i); int tipoatt = 1; if (att_mista) { const char tipo = r.get_char(RMI_TIPOC); if (tipo <= ' ') { TBill c(r.get_int(RMI_GRUPPO), r.get_int(RMI_CONTO), r.get_long(RMI_SOTTOCONTO)); tipoatt = c.tipo_att(); } } r.put(RMI_TIPOATT, tipoatt); const TString & indetr = r.get(RMI_TIPODET); if (indetr.full()) { const TRectype& det = cache().get("%DET", indetr); if (!det.empty() && !det.get_bool("FPC")) { TTable tab("%DET"); tab.curr() = det; tab.curr().put("FPC", "X"); tab.rewrite(); } } } // Aggiorna data registrazione e protocollo IVA sul registro const TDate datareg(get(MOV_DATAREG)); if (reg.full()) { const long protiva = get_long(MOV_PROTIVA); const long uprotiva = get_long(MOV_UPROTIVA); const long max = protiva > uprotiva ? protiva : uprotiva; registro.update(max, datareg); } // Aggiorna flags di ricalcolo liquidazione TDate dataliq(datareg); const int mese_liq = get_int(MOV_MESELIQ); if (mese_liq > 0 && mese_liq != dataliq.month()) { dataliq.set_day(1); // Evita problemi coi mesi corti! dataliq.set_month(mese_liq); } bool reset = !re; if (reg.full()) { reset = (dataliq.month() != _olddataliq.month() || _old_iva != iva()); if (dataliq.month() != _olddataliq.month()) controlla_liquidazione(_olddataliq, registro, true); } else { const TCausale & causale = cached_causale(get(MOV_CODCAUS), annoiva); if (causale.saldaconto(datareg) && causale.tipomov() != tm_fattura) { TPartite_array partarray; partarray.add_numreg(numreg); const int npart = partarray.items(); for (TPartita * part = partarray.first(); !reset && part != nullptr; part = partarray.next()) { const int nrpart = part->last(); for (int r = part->prima_fattura(); !reset && r >= 0 && r <= nrpart; r = part->succ(r)) { TRiga_partite & rp = part->riga(r); if (rp.is_fattura()) { const TRectype & mov = cache().get(LF_MOV, rp.get(PART_NREG)); reset = mov.get_bool(MOV_LIQDIFF) || mov.get_bool(MOV_IVAXCASSA); } } } } } if (reset) controlla_liquidazione(dataliq, registro, reset); } return err; } TMovimento_contabile& TMovimento_contabile::copy(const TMovimento_contabile & mov) { TMultiple_rectype::operator=((TMultiple_rectype &)mov); _old_iva = mov._old_iva; _olddataliq = mov._olddataliq; return *this; } TRectype & TMovimento_contabile::operator =(const TRectype & mov) { return TMultiple_rectype::operator=(mov); } void TMovimento_contabile::find_movcoll() { if (get_long(MOV_MOVCOLL) == 0L) { const TCausale& cau = cached_causale(get(MOV_CODCAUS), get_int(MOV_ANNOES)); const TString4 cau_reg = cau.causale_reg_iva(); TToken_string key(get(MOV_TIPO)); key.add(get_long(MOV_CODCF)); const long codcli = cache().get(LF_CLIFO, key).get_long(CLI_CODCFASS); const long numreg = get_long(MOV_NUMREG); TString query("USE "); query << LF_MOV << " KEY 1 SELECT " << MOV_CODCAUS << "==\"" << cau_reg << "\"\nFROM " << MOV_NUMREG << "==" << numreg; TISAM_recordset mov(query); long movcoll = 0L; for (bool ok = mov.move_first(); ok && movcoll == 0L; ok = mov.move_next()) { TRectype& curr = (TRectype&)mov.cursor()->curr(); const long movcoll_found = curr.get_long(MOV_MOVCOLL); if ((curr.get_long(MOV_CODCF) == codcli) && ((movcoll_found == 0L) || (movcoll_found == numreg))) { movcoll = mov.get(MOV_NUMREG).as_int(); curr.put(MOV_MOVCOLL, numreg); curr.rewrite(TLocalisamfile(LF_MOV)); break; } } put(MOV_MOVCOLL, movcoll); } } void TMovimento_contabile::update_rev_charge() { const int year = get_int(MOV_ANNOIVA); const TString & codcaus = get(MOV_CODCAUS); const TCausale & caus = cached_causale(codcaus, year); const TipoIVA t = caus.iva(); if (t == iva_acquisti) { const bool rev_charge = caus.reverse_charge_pubb(); if (rev_charge) { real imp_revcharge; bool has_revcharge = false; int last_iva = iva().last_row(); for (int i = iva().first_row(); !has_revcharge && i <= last_iva; i = iva().succ_row(i)) { has_revcharge |= iva(i, false).get_bool(RMI_REVCHARGE); imp_revcharge += iva(i, false).get_real(RMI_IMPOSTA); } if (!has_revcharge) { if (get_real(MOV_REVCHARGE) <= ZERO) { put(MOV_REVCHARGE, imp_revcharge); sub(MOV_RITFIS, imp_revcharge); if (get_real(MOV_RITFIS) < ZERO) TRectype::zero(MOV_RITFIS); } for (int i = iva().first_row(); i <= last_iva; i = iva().succ_row(i)) iva(i, false).put(RMI_REVCHARGE, true); } } } } int TMovimento_contabile::remove() { const int err = TMultiple_rectype::remove(); if (err == NOERR) { const TString4 reg(get(MOV_REG)); const int annoiva = get_int(MOV_ANNOIVA); TRegistro registro(reg, annoiva); controlla_liquidazione(_olddataliq, registro, true); } return err; } real TMovimento_contabile::imponibile(const char * codiva) const { real imponibile; const TString8 cod(codiva); if (iva_rows() > 0) { const int last_iva = iva().last_row(); for (int i = iva().first_row(); i <= last_iva; i = iva().succ_row(i)) if (cod.blank() || cod == iva(i, false).get(RMI_CODIVA)) imponibile += iva(i, false).get_real(RMI_IMPONIBILE); } return imponibile; } real TMovimento_contabile::imposta(const char * codiva) const { real imposta; const TString8 cod(codiva); if (iva_rows() > 0) { int last_iva = iva().last_row(); for (int i = iva().first_row(); i <= last_iva; i = iva().succ_row(i)) if (cod.blank() || cod == iva(i, false).get(RMI_CODIVA)) imposta += iva(i, false).get_real(RMI_IMPOSTA); } return imposta; } // Aggiusta i row types se sono andati persi o non sono stati convertiti void TMovimento_contabile::adjust_rowtypes() { const char tipo = get_char(MOV_TIPO); const long codice = get_long(MOV_CODCF); const int annoiva = get_int(MOV_ANNOIVA); const int annodoc = get_date(MOV_DATADOC).year(); const TCausale causale(get(MOV_CODCAUS), annoiva); TBill billind; causale.bill(RIGA_IVA_NON_DETRAIBILE, billind); const bool corrispettivo = causale.corrispettivi(); const bool iva_ind_al_costo = !billind.ok(); TConti_array conti; const int last_iva = iva().last_row(); for (int i = iva().first_row(); i < last_iva; i = iva().succ_row(i)) { const TRectype& row = iva(i); const TBill bill(row); const real imponibile(row.get(RMI_IMPONIBILE)); const real imposta(row.get(RMI_IMPOSTA)); const TString4 codiva = row.get(RMI_CODIVA); const TString4 codind = row.get(RMI_TIPODET); int tipodet = 0; const real perc_ind = indetraibile_al(codind, causale, annodoc, tipodet); real imp_det, iva_det, imp_ind, iva_ind; analizza_IVA(imponibile, imposta, perc_ind, corrispettivo, iva_ind_al_costo, codiva, imp_det, iva_det, imp_ind, iva_ind); conti.add(bill, imponibile); conti.add_iva(false, iva_ind); conti.add_iva(true, iva_det); } const int last_cg = cg().last_row(); bool totale = false; bool ritfis = get_real(MOV_RITFIS) == ZERO; bool ritsoc = get_real(MOV_RITSOC) == ZERO; bool ivadet = conti.importo_iva(true) == ZERO; bool ivanon = conti.importo_iva(false) == ZERO; TBill conto_rit_fis; TBill conto_rit_soc; causale.bill(RIGA_PAG_RITFIS, conto_rit_fis); causale.bill(RIGA_PAG_RITSOC, conto_rit_soc); for (int c = cg().first_row(); c < last_cg; c = cg().succ_row(c)) { TRectype& row = cg(c); const char rt = row.get_char(RMV_ROWTYPE); switch(rt) { case cgrowtype_ritfis: ritfis = true; break; case cgrowtype_ritsoc: ritsoc = true; break; case cgrowtype_totale: totale = true; break; default : break; } if (rt == ' ') { if (!totale && row.get_char(RMV_TIPOC) == tipo && row.get_long(RMV_SOTTOCONTO) == codice) { row.put(RMV_ROWTYPE, cgrowtype_totale); totale = true; continue; } const real importo(row.get(RMV_IMPORTO)); const TBill bill(row); if (!ritfis && importo == get_real(MOV_RITFIS)) { if (!conto_rit_fis.ok() || conto_rit_fis == bill) { row.put(RMV_ROWTYPE, cgrowtype_ritfis); ritfis = true; continue; } } if (!ritsoc && importo == get_real(MOV_RITSOC)) { if (!conto_rit_soc.ok() || conto_rit_soc == bill) { row.put(RMV_ROWTYPE, cgrowtype_ritsoc); ritsoc = true; continue; } } if (conti.ok()) { if (importo == conti.importo(bill)) { row.put(RMV_ROWTYPE, cgrowtype_imponibile); conti.remove(bill); } else if (!ivadet && importo == conti.importo_iva(true)) { row.put(RMV_ROWTYPE, cgrowtype_IVAdet); conti.remove_iva(true); } else if (!ivanon && importo == conti.importo_iva(false)) { row.put(RMV_ROWTYPE, cgrowtype_IVAnondet); conti.remove_iva(FALSE); } } } } } TPagamento& TMovimento_contabile::pagamento() { const char tipocf = get_char(MOV_TIPO); const long codcf = get_long(MOV_CODCF); TDate data_in = get_date(MOV_DATADOC); const TString8 codpag(get(MOV_CODPAG)); _pag.set_clifo(codcf, tipocf); if (codpag != _pag.code()) { _pag.set_code(codpag); _pag.read(); _pag.set_inizio(data_in); // Perche' rispetta rate true? } else { if (data_in != _pag.get_datadoc()) _pag.set_inizio(data_in); // Perche' rispetta rate true? } return _pag; }