diff --git a/src/include/clifo.h b/src/include/clifo.h index 315a4d841..eb57ccdd2 100755 --- a/src/include/clifo.h +++ b/src/include/clifo.h @@ -1,85 +1,85 @@ #ifndef __CLIFO_H #define __CLIFO_H -#define CLI_TIPOCF "TIPOCF" -#define CLI_CODCF "CODCF" -#define CLI_RAGSOC "RAGSOC" -#define CLI_INDCF "INDCF" -#define CLI_CIVCF "CIVCF" -#define CLI_STATOCF "STATOCF" -#define CLI_LOCCF "LOCALITACF" -#define CLI_COMCF "COMCF" -#define CLI_CAPCF "CAPCF" -#define CLI_COFI "COFI" -#define CLI_STATOPAIV "STATOPAIV" -#define CLI_PAIV "PAIV" -#define CLI_TIPOPERS "TIPOPERS" -#define CLI_ALLEG "ALLEG" -#define CLI_CODALLEG "CODALLEG" -#define CLI_GRUPPO "GRUPPO" -#define CLI_CONTO "CONTO" -#define CLI_GRUPPORIC "GRUPPORIC" -#define CLI_CONTORIC "CONTORIC" -#define CLI_SOTTOCRIC "SOTTOCRIC" +#define CLI_TIPOCF "TIPOCF" +#define CLI_CODCF "CODCF" +#define CLI_RAGSOC "RAGSOC" +#define CLI_INDCF "INDCF" +#define CLI_CIVCF "CIVCF" +#define CLI_STATOCF "STATOCF" +#define CLI_LOCCF "LOCALITACF" +#define CLI_COMCF "COMCF" +#define CLI_CAPCF "CAPCF" +#define CLI_COFI "COFI" +#define CLI_STATOPAIV "STATOPAIV" +#define CLI_PAIV "PAIV" +#define CLI_TIPOPERS "TIPOPERS" +#define CLI_ALLEG "ALLEG" +#define CLI_CODALLEG "CODALLEG" +#define CLI_GRUPPO "GRUPPO" +#define CLI_CONTO "CONTO" +#define CLI_GRUPPORIC "GRUPPORIC" +#define CLI_CONTORIC "CONTORIC" +#define CLI_SOTTOCRIC "SOTTOCRIC" -#define CLI_TIPOAPER "TIPOAPER" +#define CLI_TIPOAPER "TIPOAPER" #define CLI_CODANAGPER "CODANAGPER" -#define CLI_PTEL "PTEL" -#define CLI_TEL "TEL" -#define CLI_PTEL2 "PTEL2" -#define CLI_TEL2 "TEL2" -#define CLI_PTEL3 "PTEL3" -#define CLI_TEL3 "TEL3" -#define CLI_PFAX "PFAX" -#define CLI_FAX "FAX" -#define CLI_PTELEX "PTELEX" -#define CLI_TELEX "TELEX" -#define CLI_BYMAIL "BYMAIL" -#define CLI_DOCMAIL "DOCMAIL" -#define CLI_MAIL "MAIL" -#define CLI_PEC "PEC" -#define CLI_DATANASC "DATANASC" -#define CLI_STATONASC "STATONASC" -#define CLI_COMNASC "COMNASC" -#define CLI_SESSO "SESSO" -#define CLI_SCONTO "SCONTO" -#define CLI_RAGGRB "RAGGRB" -#define CLI_RAGGFT "RAGGFT" -#define CLI_CODVETT1 "CODVETT1" -#define CLI_CODVETT2 "CODVETT2" -#define CLI_CODVETT3 "CODVETT3" -#define CLI_CODCFFATT "CODCFFATT" -#define CLI_DESTIN "DESTIN" -#define CLI_CODAG "CODAG" -#define CLI_CODZONA "CODZONA" -#define CLI_CODSTAT "CODSTAT" -#define CLI_CODABI "CODABI" -#define CLI_CODCAB "CODCAB" -#define CLI_NUMCC "NUMCC" -#define CLI_IBAN "IBAN" -#define CLI_OCCAS "OCCAS" -#define CLI_STATO "STATO" -#define CLI_CODVAL "CODVAL" -#define CLI_CODLIN "CODLIN" -#define CLI_FIDO "FIDO" -#define CLI_CODPAG "CODPAG" -#define CLI_RICALT "RICALT" -#define CLI_OGGETTI "OGGETTI" -#define CLI_SOSPESO "SOSPESO" -#define CLI_DIRTY "DIRTY" -#define CLI_REFERENTE "REFERENTE" -#define CLI_VALINTRA "VALINTRA" -#define CLI_CODCFASS "CODCFASS" -#define CLI_DIPPUBB "DIPPUBB" -#define CLI_ENTE "ENTE" -#define CLI_AUTORIZ "AUTORIZ" -#define CLI_SPLITPAY "SPLITPAY" +#define CLI_PTEL "PTEL" +#define CLI_TEL "TEL" +#define CLI_PTEL2 "PTEL2" +#define CLI_TEL2 "TEL2" +#define CLI_PTEL3 "PTEL3" +#define CLI_TEL3 "TEL3" +#define CLI_PFAX "PFAX" +#define CLI_FAX "FAX" +#define CLI_PTELEX "PTELEX" +#define CLI_TELEX "TELEX" +#define CLI_BYMAIL "BYMAIL" +#define CLI_DOCMAIL "DOCMAIL" +#define CLI_MAIL "MAIL" +#define CLI_PEC "PEC" +#define CLI_DATANASC "DATANASC" +#define CLI_STATONASC "STATONASC" +#define CLI_COMNASC "COMNASC" +#define CLI_SESSO "SESSO" +#define CLI_SCONTO "SCONTO" +#define CLI_RAGGRB "RAGGRB" +#define CLI_RAGGFT "RAGGFT" +#define CLI_CODVETT1 "CODVETT1" +#define CLI_CODVETT2 "CODVETT2" +#define CLI_CODVETT3 "CODVETT3" +#define CLI_CODCFFATT "CODCFFATT" +#define CLI_DESTIN "DESTIN" +#define CLI_CODAG "CODAG" +#define CLI_CODZONA "CODZONA" +#define CLI_CODSTAT "CODSTAT" +#define CLI_CODABI "CODABI" +#define CLI_CODCAB "CODCAB" +#define CLI_NUMCC "NUMCC" +#define CLI_IBAN "IBAN" +#define CLI_OCCAS "OCCAS" +#define CLI_STATO "STATO" +#define CLI_CODVAL "CODVAL" +#define CLI_CODLIN "CODLIN" +#define CLI_FIDO "FIDO" +#define CLI_CODPAG "CODPAG" +#define CLI_RICALT "RICALT" +#define CLI_OGGETTI "OGGETTI" +#define CLI_SOSPESO "SOSPESO" +#define CLI_DIRTY "DIRTY" +#define CLI_REFERENTE "REFERENTE" +#define CLI_VALINTRA "VALINTRA" +#define CLI_CODCFASS "CODCFASS" +#define CLI_DIPPUBB "DIPPUBB" +#define CLI_ENTE "ENTE" +#define CLI_AUTORIZ "AUTORIZ" +#define CLI_SPLITPAY "SPLITPAY" -#define CLI_UTENTE "UTENTE" -#define CLI_DATAAGG "DATAAGG" +#define CLI_UTENTE "UTENTE" +#define CLI_DATAAGG "DATAAGG" -#define CLI_CODFPCUST "CODFPCUST" -#define CLI_DISCUSTFP "DISCUSTFP" +#define CLI_CODFPCUST "CODFPCUST" +#define CLI_DISCUSTFP "DISCUSTFP" #endif diff --git a/src/li/letint.h b/src/li/letint.h index e4741b514..623b92bcd 100755 --- a/src/li/letint.h +++ b/src/li/letint.h @@ -14,6 +14,9 @@ #define LETINT_DAL "DAL" #define LETINT_AL "AL" #define LETINT_STAMPATO "STAMPATO" -#define LETINT_INVIATO "INVIATO" +#define LETINT_INVIATO "INVIATO" +#define LETINT_PROTINTF "PROTINTF" +#define LETINT_PROTINTS "PROTINTS" +#define LETINT_CHIUSA "CHIUSA" #endif diff --git a/src/li/lilib01.cpp b/src/li/lilib01.cpp index c9cc760e6..6a4b0881a 100644 --- a/src/li/lilib01.cpp +++ b/src/li/lilib01.cpp @@ -1,11 +1,14 @@ #include "lilib01.h" -#include +#include "letint.h" +#include "sqlset.h" #include #include #define SOLUZIONE_UNICA 1 #define FINO_A_PLAFOND 2 +class TSQL_recordset; + const TString make_key(const int anno, const int numplaf) { static TString key; @@ -881,3 +884,155 @@ bool popola_plafond(TLista_documenti & din, const TDate& data_elab) return ok; } + +void scrivi_plafond(TLista_documenti & din, const TDate& data_elab) +{ + std::map plafonds; // Mappa di clienti-plafond: il plafond e' l'insieme delle lettere + TProgress_monitor m_doc(din.items(), "Generazione plafond nelle fatture"); + for (int i = 0; i < din.items(); i++) + { + if (!m_doc.add_status()) + return; + + // Per ogni fattura richiamo il plafond dell'intestatario e faccio le mie elaborazioni + if (plafonds.find(din[i].codcf()) == plafonds.end()) + { + TLi_manager* plaf = new TLi_manager(din[i].tipocf(), din[i].codcf(), data_elab); + plafonds.insert(std::pair(din[i].codcf(), plaf)); + } + TLi_manager& this_pla = *plafonds[din[i].codcf()]; // Forget about optimization! + if (!this_pla.has_valid_plafond()) + continue; + // Prima di tutto guardo se il documento ha righe esenti, altrimenti vado avanti + real esenz_this_doc = 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())) + esenz_this_doc += cache().get("%TIP", din[i].tipo().codice()).get_bool("B7") ? -totali->imp_orig() : totali->imp_orig(); + } + if (esenz_this_doc.is_zero()) + continue; + + // Non mi fido di cosa e' stato scritto sui documenti, ricontrollo a caldo che le lettere siano ancora aperte (ogni volta... lo so...) + // Prendo tutti i documenti, prendo tutte le righe di esenzione e le vado a sottrarre alla prima lettera. Se la supero guardo se ce ne sono altre. + // Se sto dentro sono a posto e so che sto usando ancora quella dichiarazione, se invece la supero e non c'e' un'altra ho sforato il plafond. + TLocalisamfile lint(LF_LETINT); + TSQL_recordset rec_lint(""); + TString sql; sql << "SELECT * FROM LETINT WHERE ANNO=" << din[i].anno() << " AND CODCLI=" << din[i].clifor().codice(); + rec_lint.set(sql); + int n_letint = rec_lint.items(); + if (n_letint > 0) + rec_lint.move_next(); + lint.put(LETINT_ANNO, din[i].anno()); + lint.put(LETINT_NUMPROT, rec_lint.get(rec_lint.find_column(LETINT_NUMPROT)).as_string()); + lint.read(); + + bool ok = true; + TSQL_recordset docs(""); + TToken_string tipi, stati; + create_tipi_stati(tipi, stati); + + sql.cut(0) << "SELECT * FROM DOC\n" + "WHERE ANNO=" << din[i].anno() << " AND TIPOCF='" << din[i].clifor().tipo() << "' AND CODCF=" << din[i].clifor().codice() << " AND ("; + sql << "CODNUM='" << tipi.get(0) << "' AND STATO=" << stati.get(0); + for(int z = 1; z < tipi.items(); ++z) + sql << " OR CODNUM='" << tipi.get(z) << "' AND STATO=" << stati.get(z); + sql << ")\nORDER BY NDOC"; + docs.set(sql); + real valore = rec_lint.get(rec_lint.find_column(LETINT_IMPORTO)).as_real(); + for (bool ok_d = docs.move_next(); ok_d; ok_d = docs.move_next()) + { + int ndoc = docs.get(docs.find_column(DOC_NDOC)).as_int(); + const char* codnum = docs.get(docs.find_column(DOC_CODNUM)).as_string(); + TDocumento p_doc('D', din[i].anno(), codnum, ndoc); + // Calcolo quanto plafond sta utilizzando + real esenzione = ZERO; + // Calcolo quant'e' l'importo di esenzione sommando tutte le righe che hanno il codice esenzione iva per plafond + tab_iva.destroy(); + tab_iva = p_doc.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())) + esenzione += cache().get("%TIP", p_doc.tipo().codice()).get_bool("B7") ? -totali->imp_orig() : totali->imp_orig(); + } + if(!p_doc.is_nota_credito()) + valore -= esenzione; + else + valore += esenzione; + if(valore < ZERO) + { + lint.put(LETINT_CHIUSA, "X"); // Chiudo + lint.write(); + lint.rewrite(); + real resto = ZERO; + if (rec_lint.move_next()) // Passo alla successiva se c'e' + { + lint.put(LETINT_ANNO, din[i].anno()); // Dopo la move + lint.put(LETINT_NUMPROT, rec_lint.get(rec_lint.find_column(LETINT_NUMPROT)).as_string()); + lint.read(); + resto = -valore; + valore = rec_lint.get(rec_lint.find_column(LETINT_IMPORTO)).as_real() - resto; + } + else if(valore < ZERO) + { + ok = false; + break; + } + } + } + if(!ok) + message_box("Attenzione c'e' almeno un documento che sfora il plafond per questo cliente: %d", din[i].clifor().codice()); + // Scrivo sul documento le lettere di intento utilizzate e l'importo di ciascuna + // N._riferimento_lettera1|anno1|importo_usato1,N._riferimento_lettera2|anno2|importo_usato2,... + TToken_string used("", ','); + TToken_string single_used("", '|'); + if (valore.not_zero()) + { + // Guardo se ci sta tutto nella prima lettera o devo usare anche la successiva + single_used.add(TString(lint.get(LETINT_PROTINTF)) << " " << lint.get(LETINT_PROTINTS)); + single_used.add(lint.get(LETINT_ANNO)); + real this_letint_importo = lint.get_real(LETINT_IMPORTO); + real resto = valore - esenz_this_doc; + single_used.add(resto >= ZERO ? esenz_this_doc : valore); + used.add(single_used); // Aggiungo primo riferimento + single_used = ""; + if (valore < esenz_this_doc) + { + lint.put(LETINT_CHIUSA, "X"); // Chiudo + lint.write(); + lint.rewrite(); + if (rec_lint.move_next()) // Se sforo la prima guardo se c'e' un'altra lettera altrimenti ho sforato veramente + { + lint.put(LETINT_ANNO, din[i].anno()); + lint.put(LETINT_NUMPROT, rec_lint.get(rec_lint.find_column(LETINT_NUMPROT)).as_string()); + lint.read(); + single_used.add(TString(lint.get(LETINT_PROTINTF)) << " " << lint.get(LETINT_PROTINTS)); + single_used.add(lint.get(LETINT_ANNO)); + if (lint.get_real(LETINT_IMPORTO) < -resto) + message_box("Errore... impossibile inserire ulteriori lettere di intento per questo documento."); + if (lint.get_real(LETINT_IMPORTO) == -resto) + { + lint.put(LETINT_CHIUSA, "X"); // Chiudo + lint.write(); + lint.rewrite(); + } + single_used.add(-resto); + used.add(single_used); + } + else + message_box("Attenzione c'e' un documento che sfora il plafond per questo cliente:\n%d, %s", din[i].clifor().codice(), din[i].clifor().get(CLI_RAGSOC)); + } + else if (valore == esenz_this_doc) // Se uguale chiudo la lettera + { + lint.put(LETINT_CHIUSA, "X"); + lint.write(); + lint.rewrite(); + } + } + din[i].put("PLAFOND", used); + } + + for (auto it = plafonds.begin(); it != plafonds.end(); ++it) + delete it->second; +} diff --git a/src/li/lilib01.h b/src/li/lilib01.h index 672d745ac..a089ab372 100644 --- a/src/li/lilib01.h +++ b/src/li/lilib01.h @@ -104,6 +104,7 @@ public: static void create_tipi_stati(TToken_string& tipi, TToken_string& stati); bool genera_li_storico(const TDate& data_ini); bool popola_plafond(TLista_documenti& din, const TDate& data_elab); +void scrivi_plafond(TLista_documenti& din, const TDate& data_elab); #endif \ No newline at end of file diff --git a/src/ve/ve6200.cpp b/src/ve/ve6200.cpp index 14ad8ce60..bb05f7dd5 100755 --- a/src/ve/ve6200.cpp +++ b/src/ve/ve6200.cpp @@ -6,6 +6,7 @@ #include "ve6200.h" #include "ve6200a.h" #include "../li/lilib01.h" +#include "../li/lilib01.cpp" #include @@ -37,21 +38,53 @@ bool TFatturazione_bolle_app::process(TProgress_monitor& iw, TElaborazione & eld iw.set_text(msg); // Messaggio sul cliente do_events(); // Attende visualizzazione - // Una volta che di documenti sono elaborati ci scrivo sopra il valore del plafond - if (!popola_plafond(dout, data_elab)) - { - return error_box("Errore durante la generazione del plafond, le fatture non son state create"); - } - int err = dout.write(); // Scrive documenti di output - if (err == NOERR) + // Test Plafond + TToken_string tipi, stati; + create_tipi_stati(tipi, stati); + int clifo = din[0].clifor().codice(); + + TDate aData(TODAY); + TLi_manager currentCli('C', clifo, aData); // Inizializzo l'oggetto per la gestione del plafond + real plafond, res_plafond, tot_fat; + if (currentCli.has_valid_plafond()) { - err = din.rewrite(); // Aggiorna stato dei documenti di input - if (err != NOERR) - ok = error_box("Errore %d durante la scrittura dei documenti raggruppati!", err); + plafond = currentCli.get_plafond(); + res_plafond = plafond - currentCli.elab_util(tipi, stati, aData); + for (int i = 0; i < din.items(); ++i) + tot_fat += din[i].totale_doc(); + + TLog_report lerr; + if (tot_fat > res_plafond) + { + bool plur = din.items() > 1; + TString err; + err << "Errore durante la generazione del plafond:\n" << + (plur ? "I documenti da elaborare superano" : "Il documento da elaborare supera") << " il plafond per questo cliente.\n" + "Plafond rimanente: %s\n" << + (plur ? "Totale fatture: %s\n" : "Totale fattura: %s\n") << + (plur ? "Le fatture non sono state create." : "La fattura non e' stata creata."); + return error_box(err, res_plafond.string(), tot_fat.string()); + } + + // Una volta che di documenti sono elaborati ci scrivo sopra il valore del plafond + scrivi_plafond(dout, data_elab); + //if (!popola_plafond(dout, data_elab)) + //{ + // return error_box("Errore durante la generazione del plafond, le fatture non son state create"); + //} + + int err = dout.write(); // Scrive documenti di output + if (err == NOERR) + { + err = din.rewrite(); // Aggiorna stato dei documenti di input + if (err != NOERR) + ok = error_box("Errore %d durante la scrittura dei documenti raggruppati!", err); + } + else + ok = error_box("Errore %d durante l'aggiornamento dei documenti da raggruppare!", err); } - else - ok = error_box("Errore %d durante l'aggiornamento dei documenti da raggruppare!", err); + } return ok; }