#include "lilib01.h" #include #include #include #define SOLUZIONE_UNICA 1 #define FINO_A_PLAFOND 2 const TString make_key(const int anno, const int numplaf) { static TString key; key.cut(0).format("%04d|%06d", anno, numplaf); return key; } void TLi_manager::elab_tipi_stati() { create_tipi_stati(_tipi, _stati); } const TToken_string& TLi_manager::get_use(TDocumento& d, const bool write) { static TToken_string& ret = get_tmp_string(); TAssoc_array tab_iva = d.tabella_iva(true); TString4 num_doc = d.numerazione(); real pla_util = ZERO; for (TRiepilogo_iva * totali = (TRiepilogo_iva *) tab_iva.get(); totali != NULL; totali = (TRiepilogo_iva *) tab_iva.get()) { if(check_iva(totali->cod_iva().codice())) // Se l'iva del documento è diversa non mi interessa { pla_util += totali->imp_orig(); } } if(pla_util > ZERO) { if(d.is_nota_credito()) { ret.cut(0) << incr_plaf(d, pla_util, write); } else { ret.cut(0) << cons_plaf(pla_util, write); if(ret.starts_with("ERRORE")) ret << " al documento " << d.numerazione() << " n." << d.numero() << "\nTotale plafond da utilizzare: " << pla_util.string() << "\nTotale rimasto: " << get_plafond().string(); } } return ret; } const TToken_string& TLi_manager::cons_plaf(real& plaf_used, const bool write) { static TToken_string used("", ','); used.cut(0); if(!_valid_plafond || plaf_used > get_plafond()) { used << "ERRORE NEL CALCOLO DEL PLAFOND"; return used; } bool close = false; TToken_string this_plaf("", ','); while(plaf_used > ZERO) { // Calcolo quanto plafond ho usato TString this_numprot = _plafondi.begin()->first; real this_amount = _plafondi.begin()->second; real this_utilizzato; if(plaf_used >= this_amount) { close = true; this_utilizzato = this_amount; // Rimuovo il plafond dalla lista, _plafondi.erase(this_numprot); if(write) { // lo chiudo change_stato(this_numprot, true); } // e diminuisco tutto _plafond -= this_amount; plaf_used -= this_amount; } else { close = false; this_utilizzato = plaf_used; // e diminuisco tutto _plafond -= plaf_used; _plafondi[this_numprot] -= plaf_used; plaf_used = ZERO; } // Segno di aver usato il plafond static TToken_string u; u.cut(0); u.add(this_numprot, _planno); u.add(this_utilizzato.string(), _plimporto); u.add(close? "X" : "", _plchiusura); used.add(u); } // Controllo di avere ancora plafond rimanente if(_plafond <= ZERO) _valid_plafond = false; // Tolgo la virgola finale used.cut(used.len()-1); return used; } /* Aggiungo al plafond quello che trovo */ const TToken_string& TLi_manager::incr_plaf(TDocumento& d, real imp_nc, const bool write) { static TToken_string used("", ','); used.cut(0); // Controllo se questa nota credito si riferisce a un singolo documento, in quel caso aggiorno faccio un aggiornamento sulle lettere di intento // Se si rifà a più documenti o non è specificato salta, meglio stare bassi if(d.get("NUMDOCRIF").blank() || d.get("CODNUMRIF").blank() || d.get("ANNORIF").blank() || _ini_dic_int.year() != d.get_int("ANNORIF")) { return used; } TDocumento ds('D', d.get_int("ANNORIF"), d.get("CODNUMRIF"), d.get_int("NUMDOCRIF")); TToken_string le_plafs(ds.get("PLAFOND"), ','); // [ANNO|NUMPROT|UTILIZZATO],... // Se il documento di riferimento non ha nulla inserito nel plafond esco, non mi interessa if(le_plafs.items() == 0) return used; // Controllo se non ho già ricevuto la quantità da stornare di plafond nella nota credito if(imp_nc == ZERO) { // In caso negativo la calcolo TAssoc_array tab_iva = d.tabella_iva(true); for (TRiepilogo_iva * totali = (TRiepilogo_iva *) tab_iva.get(); totali != NULL; totali = (TRiepilogo_iva *) tab_iva.get()) { if(check_iva(totali->cod_iva().codice())) { imp_nc += totali->imp_orig(); } } } // Controllo se ho del plafond da stornare if(imp_nc <= ZERO) return used; bool open = false; TToken_string this_plaf("", '|'); for(int i = le_plafs.items() - 1; i >= 0 && imp_nc > ZERO; i--) { le_plafs.get(i, this_plaf); // Importo utilizzato del plafond real importo_plaf = this_plaf.get(_plimporto); // Importo già riaccreditato da altre NC real importo_nc = this_plaf.get(_plNC); // Importo possibile di plafond da stornare real rimanente = importo_plaf - importo_nc; if(rimanente == ZERO) // This isn't the plafond you're looking for continue; if(rimanente < imp_nc) { imp_nc -= rimanente; } else { rimanente = imp_nc; imp_nc = ZERO; } // Salvo la quantità utilizzata nelle TToken_string this_plaf.add(rimanente, _plNC); le_plafs.add(this_plaf, i); // Aggiungo a plafond const TString key = make_key(this_plaf.get_int(_planno), this_plaf.get_int(_plnumprot)); if(_plafondi.find(key) != _plafondi.end()) { open = false; // Incremento! _plafondi[key] += rimanente; } else { // Va aggiunto ex novo! // Calcolo l'importo delle righe che rientrano nel plafond open = true; _plafondi.insert(std::pair(key, rimanente)); // Se devo scrivere abilito il plafond if(write) { change_stato(key, false); } } // Segno di aver usato il plafond static TToken_string u; u.cut(0); u.add(key, _planno); u.add(rimanente.string(), _plimporto); u.add(open? "X" : "", _plchiusura); used.add(u); } // Rigiro used, nelle note credito sono invertiti i plafond static TToken_string used_app("", ','); used_app.cut(0); for(int i = used.items(); i > 0; i--) used_app.add(used.get(used.items()-i), i-1); // Sovrascrivo il documento ds.put("PLAFOND", le_plafs); ds.rewrite(); // Tolgo la virgola finale used.cut(used.len()-1); // Succedono cose in memoria, devo rimediare così return used_app; } /* void TLi_manager::stornaDoc(const TDocumento& d, const bool write) { // Devo ricaricare le righe sui plafond che ho TToken_string plafs(d.get("PLAFOND"), ','); for(int i = 0; i < plafs.items(); i++) { TToken_string thisPlafond = plafs.get(i); static TString key; key.cut(0) << thisPlafond.get(_planno) << "|" << thisPlafond.get(_plnumprot); real thisImporto = thisPlafond.get(_plimporto); TString asd = thisImporto.string(); if(d.is_nota_credito()) { if(plafondi.find(key) != plafondi.end()) { if(thisImporto < plafondi[key]) { // Sottraggo plafondi[key] -= thisImporto; } else { if(DEBUG_ENABLED) { if(thisImporto > plafondi[key]) error_box("Importo maggiore del plafond rimanente"); } plafondi.erase(key); } } else if(DEBUG_ENABLED) { error_box("Houston abbiamo un problema...perchè non trovo questo plafond attivo!?"); } } else { if(plafondi.find(key) != plafondi.end()) { //Sommo plafondi[key] += thisImporto; } else { // Aggiungo ai plafond plafondi.insert(std::pair(key, thisImporto)); // Se devo scrivere abilito il plafond if(write) { changeStato(key, false); } } } } } // Storna i documenti dopo a quello che riceve void TLi_manager::stornaDocs(const TDocumento& d, const bool write) { TLista_documenti din; // Legge tutti i documenti di input // Trovo tutti i documenti che mi interessano din.read('D', _tipocf, _codcli, iniDicInt.year(), tipi, stati, d.data(), finDicInt); for(int i = 0; i < din.items(); i++) { if(d.numero() < din[i].numero()) { stornaDoc(din[i], write); } } } */ const TToken_string& TLi_manager::storna_doc(const TDocumento& d, real imp_dc, const bool write) { static TToken_string used("", ','); used.cut(0); // True se devo stornare tutto il Doc const bool totale = imp_dc.is_zero(); bool ok = true; // Devo ricaricare le righe sui plafond che ho TToken_string plafs(d.get("PLAFOND"), ','); for(int i = 0; i < plafs.items() && imp_dc > ZERO; i++) { TToken_string this_plafond = plafs.get(i); const TString key = make_key(this_plafond.get_int(_planno), this_plafond.get_int(_plnumprot)); real this_importo = this_plafond.get(_plimporto); if(totale) { if(this_importo >= imp_dc) { this_importo = imp_dc; // Controllo se vado a stornare solo una parte o tutto, nel primo caso cambio la Token, nel secondo elimino normalmente if(this_importo > imp_dc) { this_plafond.add(imp_dc, _plimporto); plafs.add(this_plafond, i); } else plafs.destroy(i); imp_dc = ZERO; } else { imp_dc -= this_importo; plafs.destroy(i); } } TString asd = this_importo.string(); if(d.is_nota_credito()) { if(_plafondi.find(key) != _plafondi.end()) { if(this_importo < _plafondi[key]) { // Sottraggo _plafondi[key] -= this_importo; } else { // Errore used.cut(0) << "ERRORE: Non è presente abbastanza plafond rimanente per stornare la Nota Credito"; return used; } } else { // Errore if(DEBUG_ENABLED) error_box("Houston abbiamo un problema...perchè non trovo questo plafond attivo!?"); used.cut(0) << "ERRORE: La lettera d'intento a cui si rifà questa Nota Credito non è aperta"; return used; } } else { if(_plafondi.find(key) != _plafondi.end()) { //Sommo _plafondi[key] += this_importo; } else { // Aggiungo ai plafond _plafondi.insert(std::pair(key, this_importo)); // Se devo scrivere abilito il plafond if(write) { change_stato(key, false); } } } } used.cut(0) << plafs; return used; } // Where did you come from Cotton Eye Joe! /* bool TLi_manager::recalcAfter(const TDocumento& d, TLog_report& lerr) { TLista_documenti din; // Legge tutti i documenti di input bool ok = true; int first = -1; // Trovo tutti i documenti che mi interessano din.read('D', _tipocf, _codcli, iniDicInt.year(), tipi, stati, d.data(), finDicInt); for(int i = 0; i < din.items() && ok; i++) { if(d.numero() < din[i].numero()) { if(first == -1) first = i; const TToken_string& use = getUse(din[i], true); if(use.starts_with("ERRORE")) { ok = false; lerr.log(2, use); } else din[i].put("PLAFOND", use); } } if(ok) { // Se va tutto bene scrivo tutti i documenti for(; first < din.items(); first++) din[first].rewrite(); } return ok; } */ /* Faccio un analisi di tutti i plafond aperti e li sommo salvandomeli in plafonds */ void TLi_manager::elab_plafond() { _valid_plafond = false; // Controllo preventivo per evitare di fare calcoli su anni precedenti al plafond if(_ini_dic_int.year() < 2017) return; TRelation letint(LF_LETINT); TRectype filtro(letint.curr()); filtro.add("CODCLI", _codcli); filtro.add("ANNO", _ini_dic_int.year()); // Creo un cursore ordinato e prelevo la prima riga non chiusa TCursor c_dicint(&letint, "", 2, &filtro, &filtro); if(c_dicint.items() > 0) { // Cerco finchè non arrivo alla fine o non trovo una soluzione for(c_dicint = 0; c_dicint.pos() < c_dicint.items() && !_soluzione; ++c_dicint) { TRectype row = c_dicint.curr(); // Esco se raggiungo una data successiva al nostro documento if(row.get_date("DAL") > _fin_dic_int) break; if(!row.get_bool("CHIUSA")) { if(row.get_int("TIPOOP") != FINO_A_PLAFOND && row.get_int("TIPOOP") != SOLUZIONE_UNICA) break; if(row.get_int("TIPOOP") == SOLUZIONE_UNICA) { // Faccio un controllo in più per bloccare un utente con plafond di diverso tipo if(_valid_plafond) { // ERRORE! Esiste già un plafond e ho trovato una soluzione unica! _valid_plafond = false; _plafondi.clear(); _plafond = -UNO; return; } _soluzione = true; } if(!_valid_plafond) _ini_dic_int = row.get_date("DAL"); // Aggiungo il plafond trovato all'elenco dei plafond const TString key = make_key(row.get_int("ANNO"), row.get_int("NUMPROT")); _plafondi.insert(std::pair(key, row.get_real("IMPORTO"))); // Aggiungo il valore del plafond al totale _plafond += row.get_real("IMPORTO"); _valid_plafond = true; } } } if(!_valid_plafond) _plafond = -UNO; } const real TLi_manager::get_pla_res() { return elab_pla_res(); } const real TLi_manager::get_pla_res(TToken_string tipi, TToken_string stati) { return elab_pla_res(tipi, stati); } const real TLi_manager::elab_pla_res(TToken_string t, TToken_string s, TDate ad) { if(_elab_pr) return _plafond; else _elab_pr = true; if(t.full() && s.full()) { _tipi = t; _stati = s; } if(!ad.ok()) ad = _fin_dic_int; _plafond = -UNO; if(!_valid_plafond) return _plafond; TLista_documenti din; // Legge tutti i documenti di input // Trovo tutti i documenti che mi interessano e sottraggo l'imponibile al _plafond din.read('D', _tipocf, _codcli, _ini_dic_int.year(), _tipi, _stati, _ini_dic_int, ad); for(int i = 0; i < din.items(); i++) { TToken_string plaf(din[i].get("PLAFOND"), ','); for(int j = 0; j < plaf.items(); j++) { TToken_string the_pla(plaf.get(j)); const TString key = make_key(the_pla.get_int(_planno), the_pla.get_int(_plnumprot)); static TString chiusura; chiusura.cut(0) << the_pla.get(_plchiusura); // La get ritorna un const char* if(din[i].tipo().nota_credito()) { if(_plafondi.find(key) != _plafondi.end()) { if(DEBUG_ENABLED && chiusura == "X" && yesno_box("Attenzione! La lettera con codice %s riferito alla nota credito %s, %d l'ho trovata ma dovevo aprirla adesso!\n Che faccio, azzero?", key, din[i].numerazione(), din[i].numero())) { _plafondi[key] = ZERO; } _plafondi[key] += static_cast(the_pla.get(_plimporto)); } else { // Va aggiunto ex novo! if(DEBUG_ENABLED && chiusura != "X" && yesno_box("Attenzione! La lettera con codice %s riferito alla nota credito %s, %d non l'ho trovata ma doveva già essere aperta!\n Che faccio, annullo?", key, din[i].numerazione(), din[i].numero())) { _valid_plafond = false; return _plafond; } // Calcolo l'importo delle righe che rientrano nel plafond _plafondi.insert(std::pair(key, static_cast(the_pla.get(_plimporto)))); } } else { if(_plafondi.find(key) != _plafondi.end()) { if(chiusura == "X") { if(DEBUG_ENABLED && _plafondi[key] != static_cast(the_pla.get(_plimporto)) && !yesno_box(TR("Questa lettera di intento è incongruente,\nTotale attivo: %s\nTotale da disattivare: %s\nContinuare?"), _plafondi[key].string(), the_pla.get(_plimporto))) { _valid_plafond = false; return _plafond; } _plafondi.erase(key); } else { _plafondi[key] -= static_cast(the_pla.get(_plimporto)); } } } } } // Calcolo il totale da mappa scansionata _plafond = ZERO; for(auto it = _plafondi.begin(); it != _plafondi.end(); ++it) _plafond += it->second; return _plafond; } const real TLi_manager::elab_util(TToken_string tipi, TToken_string stati, TDate ad) { if(!_valid_plafond) return -UNO; if(tipi.items() == 0) return ZERO; real utilizzato = ZERO; TLista_documenti din; // Legge tutti i documenti di input // Trovo tutti i documenti che mi interessano e sottraggo l'imponibile al plafond din.read('D', _tipocf, _codcli, _ini_dic_int.year(), tipi, stati, _ini_dic_int, ad); for(int i = 0; i < din.items(); i++) { TAssoc_array tab_iva = din[i].tabella_iva(true); for (TRiepilogo_iva * totali = (TRiepilogo_iva *) tab_iva.get(); totali != NULL; totali = (TRiepilogo_iva *) tab_iva.get()) { if(check_iva(totali->cod_iva().codice())) { utilizzato += cache().get("%TIP", din[i].tipo().codice()).get_bool("B7") ? -totali->imp_orig() : totali->imp_orig(); } } // Nel caso il plafond trovato fosse una soluzione unica e ho già trovato dei documenti vuol dire che il plafond non è più valido if(_soluzione) { utilizzato = -UNO; break; } } return utilizzato; } bool TLi_manager::test_plafond(TLista_documenti& dout, TLog_report& lerr) { bool err = false; static TToken_string& use = get_tmp_string(); // Faccio un ragionamento identico a getPlaRes, ma in input ho la lista di documenti appena elaborati for(int i = 0; i < dout.items() && !err; i++) { use.cut(0) << get_use(dout[i], true); if(use.starts_with("ERRORE")) { TString msgerr; msgerr << "Superata dichiarazione di intento cliente N." << dout[i].codcf() << "\n" << use; lerr.log(2, msgerr); revert_modifiche(); clear_modifiche(); err = true; } } return err; } /* Per scelte implementative non ha una accuratezza del 100% */ bool TLi_manager::check_utilizzo(TDocumento& d, real imp_nc) { bool ok = true; TToken_string le_plafs(d.get("PLAFOND"), ','); // Se me lo passa la funzione evito di calcolarlo if(imp_nc.is_zero()) { for (TRiepilogo_iva * totali = (TRiepilogo_iva *) d.tabella_iva(true).get(); totali != NULL; totali = (TRiepilogo_iva *) d.tabella_iva(true).get()) if(check_iva(totali->cod_iva().codice())) // Se l'iva del documento è diversa non mi interessa imp_nc += totali->imp_orig(); } /* Per sapere se non ho usato il plafond di questa NC controllo innanzitutto se c'è ne abbastanza * rimasto per coprire la NC, non è il controllo della vita ma toglie già un po' di calcoli */ ok = get_pla_res() > imp_nc; // Sucessivamente vado in dettaglio a verificare se sono sempre maggiori (getPlaRes() mi carica anche la variabile "plafondi" per gli altri calcoli) for(int i = 0; i < le_plafs.items() && ok; i++) { TToken_string this_plaf(le_plafs.get(i)); const TString key = make_key(this_plaf.get_int(_planno), this_plaf.get_int(_plnumprot)); if(_plafondi.find(key) != _plafondi.end()) { ok = _plafondi[key] > static_cast(le_plafs.get(_plimporto)); } else ok = false; } return ok; } void TLi_manager::change_stato(const TString& key, const bool stato) { TRectype Jean_Baptiste_Le_Rond_dAlembert = cache().get(LF_LETINT, key); // Che nome di classe! Jean_Baptiste_Le_Rond_dAlembert.put("CHIUSA", stato); Jean_Baptiste_Le_Rond_dAlembert.rewrite(TLocalisamfile(LF_LETINT)); TString skey; skey << key << "|" << stato ? "" : "X"; // Ottimizzazione portami via... _modifiche.insert(std::pair(_modifiche.size()+1, skey)); } void TLi_manager::revert_modifiche() { if(!has_modifiche()) return; TLocalisamfile baguette(LF_LETINT); for(auto it = _modifiche.begin(); it != _modifiche.end(); ++it) { TToken_string key = it->second; TRectype Jean_Baptiste_Le_Rond_dAlembert = cache().get(LF_LETINT, key.get(0)); // Che nome di classe! Jean_Baptiste_Le_Rond_dAlembert.put("CHIUSA", key.get(1)); Jean_Baptiste_Le_Rond_dAlembert.rewrite(baguette); } clear_modifiche(); } TLi_manager::TLi_manager(const char t, const long c, TDate iniDic, TDate finDic) : _tipocf (t), _codcli(c), _ini_dic_int(iniDic), _fin_dic_int(finDic), _codiva_def(ini_get_string(CONFIG_DITTA, "li", "CODIVA")), _codiva_alt(ini_get_string(CONFIG_DITTA, "li", "CODIVALT")), _plafond(ZERO), _valid_plafond(false), _soluzione(false), _elab_pr(false) { elab_tipi_stati(); elab_plafond(); } TLi_manager::TLi_manager(const char t, const long c, TDate finDic) : _tipocf (t), _codcli(c), _fin_dic_int(finDic), _codiva_def(ini_get_string(CONFIG_DITTA, "li", "CODIVA")), _codiva_alt(ini_get_string(CONFIG_DITTA, "li", "CODIVALT")), _plafond(ZERO), _valid_plafond(false), _soluzione(false), _elab_pr(false) { _ini_dic_int.set_day(01); _ini_dic_int.set_month(01); _ini_dic_int.set_year(finDic.year()); elab_tipi_stati(); elab_plafond(); } static void create_tipi_stati(TToken_string& tipi, TToken_string& stati) { static const TToken_string tipidoc(ini_get_string(CONFIG_DITTA, "li", "TIPIDOC")); if(tipi.blank() && stati.blank()) { for(int i = 0; i < tipidoc.items(); i++) { TString app(""); tipidoc.get(i, app); TToken_string statidoc(ini_get_string(CONFIG_DITTA, "li", app), ','); for(int j = statidoc.get_int(0); j <= statidoc.get_int(1); j++) { tipi.add(app); stati.add(j); } } } } bool genera_li_storico(const TDate& data_ini) { // Apro la tabella dei plafonds con chiave 2 (CODCLI+ANNO+NUMPROT) e per ogni cliente calcolo i plafond dal 2017 TRelation rletint(LF_LETINT); TString filter = "DAL>="; filter << data_ini.date2ansi(); TCursor cletint(&rletint, filter, 2); static TToken_string tipi, stati; create_tipi_stati(tipi, stati); static TString cod_ivap = ini_get_string(CONFIG_DITTA, "li", "CODIVA"); static TString cod_ivas = ini_get_string(CONFIG_DITTA, "li", "CODIVALT"); TProgress_monitor status(cletint.items(), "Aggiornamento plafond"); for(cletint = 0; cletint.pos() < cletint.items();) // Il cursore avanza sotto { if(!status.add_status()) break; TRectype rletint = cletint.curr(); ++cletint; TRectype rletintn = cletint.curr(); // Controllo subuto che non sia una dichiarazione a tempo if(rletint.get_int("TIPOOP") == 3) continue; // Date TDate start_curr = rletint.get_date("DAL"), end_curr; end_curr = rletint.get_int("CODCLI") == rletintn.get_int("CODCLI") ? --rletintn.get_date("DAL") : NULLDATE; // Dati lettera real imp_li = rletint.get_real("IMPORTO"); bool soluzione = rletint.get_int("TIPOOP") == SOLUZIONE_UNICA; // Adesso che so le date apro tutti i documenti TLista_documenti din; din.read('D', 'C', rletint.get_long("CODCLI"), start_curr.year(), tipi, stati, start_curr, end_curr); for(int i = 0; i < din.items(); i++) { #ifdef DBG if(din[i].numero() == 1202 && din[i].anno() == 2017) bool tolla = true; #endif real utilizzato = ZERO; TAssoc_array tab_iva = din[i].tabella_iva(true); for (TRiepilogo_iva * totali = (TRiepilogo_iva *) tab_iva.get(); totali != NULL; totali = (TRiepilogo_iva *) tab_iva.get()) { if(totali->cod_iva().codice() == cod_ivap || totali->cod_iva().codice() == cod_ivas) utilizzato += cache().get("%TIP", din[i].tipo().codice()).get_bool("B7") ? -totali->imp_orig() : totali->imp_orig(); } if(utilizzato.is_zero()) { if(DEBUG_ENABLED) { static bool erase = yesno_box("Vuoi resettare anche i documenti con utilizzo a zero?\nCi metterà più tempo"); din[i].put("PLAFOND", ""); din[i].rewrite(); } continue; } // Controllo di non superare il plafond if(imp_li >= utilizzato) { // Creo la chiave da scrivere e metto tutto dentro const TString key = make_key(rletint.get_int("ANNO"), rletint.get_int("NUMPROT")); din[i].put("PLAFOND", key); din[i].rewrite(); } else { // Error! if(DEBUG_ENABLED) warning_box("Superato plafond, si passa alla nuova lettera"); break; } // Solo per una lettera if(soluzione) break; } } return true; } bool popola_plafond(TLista_documenti & din, const TDate& data_elab) { std::map plafs; TProgress_monitor m_doc(din.items(), "Generazione plafond nelle fatture"); bool ok = true; for(int i = 0; i < din.items() && ok; i++) { if (!m_doc.add_status()) return false; // Per ogni fattura richiamo il plafond dell'intestatario e faccio le mie elaborazioni if (plafs.find(din[i].codcf()) == plafs.end()) { TLi_manager* app = new TLi_manager(din[i].tipocf(), din[i].codcf(), data_elab); plafs.insert(std::pair(din[i].codcf(), app)); } TLi_manager& this_pla = *plafs[din[i].codcf()]; // Forget about optimization! if (!this_pla.has_valid_plafond()) continue; // Calcolo quanto plafond sta utilizzando real utilizzato = ZERO; TAssoc_array tab_iva = din[i].tabella_iva(true); for (TRiepilogo_iva * totali = (TRiepilogo_iva *)tab_iva.get(); totali != NULL; totali = (TRiepilogo_iva *)tab_iva.get()) { if (this_pla.check_iva(totali->cod_iva().codice())) utilizzato += cache().get("%TIP", din[i].tipo().codice()).get_bool("B7") ? -totali->imp_orig() : totali->imp_orig(); } // Passo a un altro doc se non usa plafond if (utilizzato.is_zero()) continue; TToken_string used; if (din[i].tipo().nota_credito()) { used = this_pla.incr_plaf(din[i], utilizzato, true); } else { // Il controllo è andato bene, adesso mi segno i plafond che ho utilizzato nel memo del documento used = this_pla.cons_plaf(utilizzato, true); } // Rincontrollo che l'utilizzo del pladond sia tutto ok, meglio una volta in più che una in meno! if (used.starts_with("ERRORE")) { error_box("Errore! Superato l'utilizzo del plafond per il documento %s %d, del cli/fo %c%d, come è possibile?", din[i].tipo().codice(), din[i].numero(), din[i].tipocf(), din[i].codcf()); ok = false; } else { din[i].put("PLAFOND", used); } } for (auto it = plafs.begin(); it != plafs.end(); ++it) delete it->second; return ok; }