diff --git a/build/fp0.vcxproj b/build/fp0.vcxproj index e15efcc10..67d245c33 100644 --- a/build/fp0.vcxproj +++ b/build/fp0.vcxproj @@ -245,6 +245,9 @@ true true + + true + diff --git a/build/fp0.vcxproj.filters b/build/fp0.vcxproj.filters index 6834d81aa..3a3da414f 100644 --- a/build/fp0.vcxproj.filters +++ b/build/fp0.vcxproj.filters @@ -123,6 +123,9 @@ Sqls + + Sqls + diff --git a/cd/test/f90888.txt b/cd/test/f90888.txt new file mode 100644 index 000000000..f68b5f602 --- /dev/null +++ b/cd/test/f90888.txt @@ -0,0 +1,3 @@ +f90.exe + +Corretta estrazione provvisoria diff --git a/cd/test/f90888a.ini b/cd/test/f90888a.ini new file mode 100644 index 000000000..0c93ce920 --- /dev/null +++ b/cd/test/f90888a.ini @@ -0,0 +1,19 @@ +[Main] +Demo=0 + +[f90] +File(0) = f90.exe|X +Patch = 0888 +Versione = 21511200 + +[f9] +Data = 14-10-2019 +Descrizione = Archiviazione Sostitutiva +Dischi = 1 +Moduli = fp,cg +OEM = +Patch = 888 +PostProcess = +PreProcess = +Versione = 21511200 + diff --git a/cd/test/f90888a1.zip b/cd/test/f90888a1.zip new file mode 100644 index 000000000..0a1753c85 Binary files /dev/null and b/cd/test/f90888a1.zip differ diff --git a/cd/test/fp0884.txt b/cd/test/fp0884.txt new file mode 100644 index 000000000..3a00e1dc6 --- /dev/null +++ b/cd/test/fp0884.txt @@ -0,0 +1,3 @@ +fp0.exe + +Corretta query eliminazione. Problema presentato alla CRPA: non esportava le fatture. diff --git a/cd/test/fp0884a.ini b/cd/test/fp0884a.ini new file mode 100644 index 000000000..7d25b5008 --- /dev/null +++ b/cd/test/fp0884a.ini @@ -0,0 +1,19 @@ +[Main] +Demo=0 + +[fp0] +File(0) = fp0.exe|X +Patch = 0884 +Versione = 21511200 + +[fp] +Data = 07-10-2019 +Descrizione = Fattura Elettronica +Dischi = 1 +Moduli = cg,ve +OEM = +Patch = 884 +PostProcess = +PreProcess = +Versione = 21511200 + diff --git a/cd/test/fp0884a1.zip b/cd/test/fp0884a1.zip new file mode 100644 index 000000000..d6ee20f36 Binary files /dev/null and b/cd/test/fp0884a1.zip differ diff --git a/cd/test/fp0886.txt b/cd/test/fp0886.txt new file mode 100644 index 000000000..3ab679188 --- /dev/null +++ b/cd/test/fp0886.txt @@ -0,0 +1,3 @@ +fp0.exe + +Cambiata funzione is_splitment: tolto controllo se ci sono ritenute: non piu necessario diff --git a/cd/test/fp0886a.ini b/cd/test/fp0886a.ini new file mode 100644 index 000000000..dfd68c2e8 --- /dev/null +++ b/cd/test/fp0886a.ini @@ -0,0 +1,19 @@ +[Main] +Demo=0 + +[fp0] +File(0) = fp0.exe|X +Patch = 0886 +Versione = 21511200 + +[fp] +Data = 08-10-2019 +Descrizione = Fattura Elettronica +Dischi = 1 +Moduli = cg,ve +OEM = +Patch = 886 +PostProcess = +PreProcess = +Versione = 21511200 + diff --git a/cd/test/fp0886a1.zip b/cd/test/fp0886a1.zip new file mode 100644 index 000000000..7df1d0677 Binary files /dev/null and b/cd/test/fp0886a1.zip differ diff --git a/cd/test/fp0888.txt b/cd/test/fp0888.txt new file mode 100644 index 000000000..c989ad991 --- /dev/null +++ b/cd/test/fp0888.txt @@ -0,0 +1,4 @@ +fp0.exe +sql\fp0\fp0112.sql + +Esportazione ddt fatturazione differita lavanderie diff --git a/cd/test/fp0888a.ini b/cd/test/fp0888a.ini new file mode 100644 index 000000000..64ddd8276 --- /dev/null +++ b/cd/test/fp0888a.ini @@ -0,0 +1,20 @@ +[Main] +Demo=0 + +[fp0] +File(0) = fp0.exe|X +File(8) = sql\fp0\fp0112.sql|X +Patch = 888 +Versione = 21511200 + +[fp] +Data = 10-10-2019 +Descrizione = Fattura Elettronica +Dischi = 1 +Moduli = cg,ve +OEM = +Patch = 0888 +PostProcess = +PreProcess = +Versione = 21511200 + diff --git a/cd/test/fp0888a1.zip b/cd/test/fp0888a1.zip new file mode 100644 index 000000000..a2fd233eb Binary files /dev/null and b/cd/test/fp0888a1.zip differ diff --git a/cd/test/lv0870.txt b/cd/test/lv0870.txt new file mode 100644 index 000000000..6676b2d6f --- /dev/null +++ b/cd/test/lv0870.txt @@ -0,0 +1,4 @@ +lv0400f.rep +lv0400c.rep + +Tolto CAUSLAV dai report diff --git a/cd/test/lv0870a.ini b/cd/test/lv0870a.ini new file mode 100644 index 000000000..84faa096f --- /dev/null +++ b/cd/test/lv0870a.ini @@ -0,0 +1,23 @@ +[Main] +Demo=0 + +[lv1] +Edit_168 = lv0 -3 +File(12) = lv0400c.rep|X +File(18) = lv0400f.rep|X +Patch = 870 +Versione = 21511200 + +[lv] +Data = 04-10-2019 +Descrizione = Gestione lavanderie +Dischi = 1 +Moduli = ve,mg +OEM = 2 +Patch = 870 +PostProcess = bainst -0 LV +PreProcess = +Prezzo(1) = +Prezzo(2) = +Versione = 21511200 + diff --git a/cd/test/lv0870a1.zip b/cd/test/lv0870a1.zip new file mode 100644 index 000000000..14bd8fcd0 Binary files /dev/null and b/cd/test/lv0870a1.zip differ diff --git a/cd/test/ve0886.txt b/cd/test/ve0886.txt new file mode 100644 index 000000000..21d91344a --- /dev/null +++ b/cd/test/ve0886.txt @@ -0,0 +1,6 @@ +ve0.exe +ve1.exe +ve5.exe +ve6.exe + +Cambiata funzione is_splitment: tolto controllo se ci sono ritenute: non piu necessario diff --git a/cd/test/ve0886a.ini b/cd/test/ve0886a.ini new file mode 100644 index 000000000..496bc0a88 --- /dev/null +++ b/cd/test/ve0886a.ini @@ -0,0 +1,144 @@ +[Main] +Demo=0 + +[ve0] +File(0) = ve0.exe|X +Patch = 0886 +Versione = 21511200 + +[ve1] +File(18) = ve1.exe|X +Patch = 0886 +Versione = 21511200 + +[ve5] +File(85) = ve5.exe|X +Patch = 0886 +Versione = 21511200 + +[ve6] +File(214) = ve6.exe|X +Patch = 0886 +Versione = 21511200 + +[ve99] +Kill(0) = batbimb.msk|x +Kill(1) = batbacr.msk|x +Kill(2) = bastfrd.msk|x +Kill(3) = bastbnp.rep|x +Kill(4) = bastcra.msk|x +Kill(5) = batbgmc.msk|x +Kill(6) = batbabe.msk|x +Kill(7) = efstbnp.msk|x +Kill(8) = batbfrm.msk|x +Kill(9) = batbcra.msk|x +Kill(10) = ve7300a.frm|x +Kill(11) = bastprs.msk|x +Kill(12) = batbnum.msk|x +Kill(13) = bastabe.msk|x +Kill(14) = bastrfc.rep|x +Kill(15) = bastasf.rep|x +Kill(16) = basttag.rep|x +Kill(17) = eftbbnp.msk|x +Kill(18) = ve7.exe|x +Kill(19) = batbgca.msk|x +Kill(20) = ve7200a.msk|x +Kill(21) = batbrfa.msk|x +Kill(22) = bastgca.rep|x +Kill(23) = batbrfc.msk|x +Kill(24) = basteld.rep|x +Kill(25) = bastums.rep|x +Kill(26) = ve7701a.ini|x +Kill(27) = batbfrr.msk|x +Kill(28) = bastcaa.rep|x +Kill(29) = basttri.rep|x +Kill(30) = batbtri.msk|x +Kill(31) = bastctr.msk|x +Kill(32) = batbtag.msk|x +Kill(33) = batbmre.msk|x +Kill(34) = baststd.rep|x +Kill(35) = ve7400a.ini|x +Kill(36) = baststd.msk|x +Kill(37) = batbcau.msk|x +Kill(38) = batbpro.msk|x +Kill(39) = bastabe.rep|x +Kill(40) = ve7400a.msk|x +Kill(41) = bastgca.msk|x +Kill(42) = bastimb.msk|x +Kill(43) = bastctr.rep|x +Kill(44) = batbtip.msk|x +Kill(45) = bastrfc.msk|x +Kill(46) = batbubi.msk|x +Kill(47) = bastcau.rep|x +Kill(48) = basttag.msk|x +Kill(49) = bastgcg.msk|x +Kill(50) = bastubi.rep|x +Kill(51) = basteld.msk|x +Kill(52) = bastcau.msk|x +Kill(53) = batbprs.msk|x +Kill(54) = batbctr.msk|x +Kill(55) = batbstd.msk|x +Kill(56) = ve7100a.msk|x +Kill(57) = bastums.msk|x +Kill(58) = batbcaa.msk|x +Kill(59) = bastspp.msk|x +Kill(60) = batbspp.msk|x +Kill(61) = batbfid.msk|x +Kill(62) = bastasf.msk|x +Kill(63) = bastfrm.rep|x +Kill(64) = bastnum.rep|x +Kill(65) = batbbnp.msk|x +Kill(66) = bastgmc.msk|x +Kill(67) = bastrfa.msk|x +Kill(68) = basttip.rep|x +Kill(69) = ve7600a.msk|x +Kill(70) = batbfsa.msk|x +Kill(71) = bastubi.msk|x +Kill(72) = batbgcg.msk|x +Kill(73) = bastimb.rep|x +Kill(74) = bastfca.rep|x +Kill(75) = bastfrd.rep|x +Kill(76) = batbums.msk|x +Kill(77) = bastnum.msk|x +Kill(78) = bastfrr.msk|x +Kill(79) = ve7500a.msk|x +Kill(80) = bastfca.msk|x +Kill(81) = ve7400conf.ini|x +Kill(82) = efstbnp.rep|x +Kill(83) = batbasf.msk|x +Kill(84) = bastfrr.rep|x +Kill(85) = bastprs.rep|x +Kill(86) = bastcaa.msk|x +Kill(87) = ve7200a.frm|x +Kill(88) = batbgsa.msk|x +Kill(89) = bastbnp.msk|x +Kill(90) = bastrfa.rep|x +Kill(91) = basttip.msk|x +Kill(92) = batbprv.msk|x +Kill(93) = batbfrd.msk|x +Kill(94) = bastfrm.msk|x +Kill(95) = bastgmc.rep|x +Kill(96) = bastgcg.rep|x +Kill(97) = batbfca.msk|x +Kill(98) = bastspp.rep|x +Kill(99) = batbcld.msk|x +Kill(100) = batbspt.msk|x +Kill(101) = ve7700a.msk|x +Kill(102) = batbeld.msk|x +Kill(103) = basttri.msk|x +Kill(104) = bastcra.rep|x +Kill(105) = ve7300a.msk|x + +[ve] +Data = 08-10-2019 +Descrizione = Vendite +Dischi = 1 +Moduli = ba,cg9,pr9,mg9,sv9,in9,ef9 +OEM = +Patch = 886 +PostProcess = bainst -0 VE +PreProcess = +Prezzo(1) = +Prezzo(2) = +Versione = 21511200 + diff --git a/cd/test/ve0886a1.zip b/cd/test/ve0886a1.zip new file mode 100644 index 000000000..a8dc11ec0 Binary files /dev/null and b/cd/test/ve0886a1.zip differ diff --git a/src/f9/f90100.cpp b/src/f9/f90100.cpp index cf1f3ad10..1fc33d73a 100644 --- a/src/f9/f90100.cpp +++ b/src/f9/f90100.cpp @@ -745,7 +745,8 @@ void TF9_app::load() TToken_string elab_f9(mov.get(MOV_ELABF9), ';'); // Se definitivo controllo il flag di stampato REGST - if (mov.get_bool(MOV_REGST) != flagpro && mov.get(MOV_NUMDOC).full() && TCausale(mov.get(MOV_CODCAUS)).reg().iva() == tipo + TCausale caus(mov.get(MOV_CODCAUS)); + if ((flagpro || mov.get_bool(MOV_REGST)) && mov.get(MOV_NUMDOC).full() && caus.reg().iva() == tipo && (elab_f9.items() == 3 && elab_f9.get(2)[0] != 'X' || elab_f9.empty())) // Controllo che non sia escluso { TToken_string t("", '|'); diff --git a/src/fp/fplib.h b/src/fp/fplib.h index 6f46946a6..29a7fd14e 100644 --- a/src/fp/fplib.h +++ b/src/fp/fplib.h @@ -290,6 +290,34 @@ public: TRecord_array& bodyof##__rdoc = (__doc).body(); \ for (int __r = bodyof##__rdoc.first_row(); bodyof##__rdoc.exist(__r) && (__rdoc=&(TFPRiga_documento&)bodyof##__rdoc.row(__r))!=NULL; __r=bodyof##__rdoc.succ_row(__r)) +class TFPBuono_di_consegna +{ +public: + TString20 _numdoc; + TDate _datadoc; + + bool already_exist(map& ancestors_s) const; + + + TFPBuono_di_consegna() { } + TFPBuono_di_consegna(const TString20& numdoc, const TDate& datadoc) : _numdoc(numdoc), _datadoc(datadoc) { } +}; + +inline bool operator==(const TFPBuono_di_consegna& l, const TFPBuono_di_consegna& r) +{ + TToken_string appo(l._numdoc, '/'); + if(appo.items() == 3) + return TString(appo.get(2)) == r._numdoc && l._datadoc == r._datadoc; + return l._numdoc == r._numdoc && l._datadoc == r._datadoc; +} + +#define FOR_EACH_BUONI(__buoni, __n, __buono) TFPBuono_di_consegna* (buono) = NULL; \ + map::iterator it; \ + it = (buoni).begin(); \ + int(n) = 0; \ + for (; it != (buoni).end() && ((buono) = &it->second)->_numdoc.full(); ++it, (n)++) + + /*********************************************************************************************************************************************************************** * PERSONALIZZAZIONI FP @@ -524,6 +552,7 @@ protected: //void set_rec_clifo(char tipocf, long codcf); public: + static void fill_buoni(map& buoni, const TString& memo); bool doc_to_paf(TDocumentoEsteso& doc); bool doc_to_paf(const TRectype& rec); bool doc_to_paf(const TDoc_key& key); diff --git a/src/fp/fplib01.cpp b/src/fp/fplib01.cpp index 5eb92e23f..5ba1d1930 100644 --- a/src/fp/fplib01.cpp +++ b/src/fp/fplib01.cpp @@ -417,12 +417,25 @@ TString& TPaf_record::remove_string(const bool id_riga) query << " AND " << prefix << "KEYPRGINVIO != ''"; CHECKS(++nkf >= 2, "Can't remove partial key on table ", static_cast(_table)); query << ';'; + + if (nkf == 0) + query.cut(0); // Crea una query sbagliata "WHERE AND": "DELETE FROM [table] WHERE AND [prefix]_KEYPRGINVIO != '';" return query; } // Elimina il record in base ai campi chiave bool TPaf_record::remove() { - return fp_db().sq_set_exec(remove_string()); + TString& str = remove_string(); + if (str.empty()) // Se la query e' vuota (sbagliata) salto, non c'e' nulla da eliminare + return true; + const bool ok = fp_db().sq_set_exec(str); + if (!ok) + { + ofstream fout; + fout.open("fperror_remove.txt"); + fout << str << "\n" << fp_db().sq_get_text_error(false) << "\n" << fp_db().sq_get_string_error(false); + } + return ok; } // Carica un record in base ai campi chiave bool TPaf_record::search() @@ -651,6 +664,19 @@ TAncestor::TAncestor(const TRectype& rdoc) _numdoc.format("%d/%s/%s", anno, static_cast(codnum), static_cast(numdoc)); _datadoc = doc.get_date(DOC_DATADOC); } +/*************************************************************************** + * TFPBuono_di_consegna + ***************************************************************************/ +bool TFPBuono_di_consegna::already_exist(map& ancestors_s) const +{ + for(auto it = ancestors_s.begin(); it != ancestors_s.end(); ++it) + { + TFPBuono_di_consegna b(it->first, it->second); + if (b == *this) + return true; + } + return false; +} /*************************************************************************** * TDoc_fp ***************************************************************************/ @@ -1400,6 +1426,25 @@ bool TDoc_fp::export_paf3200f() } return true; } + +void TDoc_fp::fill_buoni(map& buoni, const TString& memo) +{ + if (memo.full()) + { + TToken_string b(memo, 'n'); + for (int i = 4; i < b.items(); i++) + { + TToken_string str(b.get(i), ' '); + TString20 ndoc = str.get(1); + TDate data(str.get(3)); + if (data == TDate(NULLDATE)) + data = str.get(2); + TFPBuono_di_consegna buono(ndoc, data); + buoni.insert({ buono._numdoc, buono }); + } + } +} + bool TDoc_fp::doc_to_paf(TDocumentoEsteso& doc) { if (!initialize(doc)) @@ -1666,7 +1711,9 @@ bool TDoc_fp::doc_to_paf(TDocumentoEsteso& doc) TPaf_record& paf1900f = _paf_container.get_paf("PAF1900F"); TPaf_record& paf3000f = _paf_container.get_paf("PAF3000F"); long riga = 1; - + bool f_buonocons = false; + map ancestors_s; + TString riga_buoni_cons; FOR_EACH_PHYSICAL_FPRDOC(doc, r, rdoc) { // Controllo la riga @@ -1680,6 +1727,15 @@ bool TDoc_fp::doc_to_paf(TDocumentoEsteso& doc) const TString& descrizione_riga = descrizione(*rdoc); if (descrizione_riga.empty()) continue; + if (!f_buonocons && descrizione_riga.starts_with("Buono di consegna n. ")) + { + TString memo; memo << rdoc->get(RDOC_DESCR); + if (rdoc->get_bool(RDOC_DESCLUNGA)) + memo << rdoc->get(RDOC_DESCEST); + riga_buoni_cons = memo; + f_buonocons = true; + continue; + } reset(paf3000f); paf3000f.set("PT_RIFNUMLINEA", riga); paf3000f.set("PT_COMMENTO", descrizione_riga); @@ -1721,11 +1777,12 @@ bool TDoc_fp::doc_to_paf(TDocumentoEsteso& doc) * Ogni riga si puņ rifare a un DDT/Ordine diverso, per questo devo inserire i dati da qua e non in testata */ TArray ancestors; - find_ancestors(*rdoc, ancestors); + find_ancestors(*rdoc, ancestors); for (int i = ancestors.last(); i > 0; i = ancestors.pred(i)) { _has_bolla |= true; const TAncestor& a = dynamic_cast(ancestors[i]); + ancestors_s.insert({ a._numdoc, a._datadoc }); // Per i buoni di consegna lavanderie if (i == 1) { // @@ -1913,6 +1970,31 @@ bool TDoc_fp::doc_to_paf(TDocumentoEsteso& doc) riga++; } } + + /* Se ho una fattura che deriva dalla fatturazione differita delle lavanderie prendo + * dalla relativa riga descrizione tutti i riferimenti alle bolle che mancano */ + if (f_buonocons) + { + TString& memo = riga_buoni_cons; + if (memo.full()) + { + map buoni; + fill_buoni(buoni, memo); + paf1600f.set("PF_RIFNUMLINEA", "0"); + FOR_EACH_BUONI(buoni, n, buono) + { + if (!buono->already_exist(ancestors_s)) + { + reset(paf1600f); + paf1600f.set("PF_NUMDDDT", buono->_numdoc); + paf1600f.set("PF_DATADDT", buono->_datadoc); + paf1600f.set("PF_GESTIONE", "D"); + ok &= insert(paf1600f); + } + } + f_buonocons = true; + } + } // Controllo plafond // Riga esenzione? if (doc.is_fattura() && !doc.is_nota_credito()) diff --git a/src/fp/sql/fp0112.sql b/src/fp/sql/fp0112.sql new file mode 100644 index 000000000..088c98863 --- /dev/null +++ b/src/fp/sql/fp0112.sql @@ -0,0 +1,2 @@ +ALTER TABLE PAF1600F DROP CONSTRAINT PAF1600Q; +ALTER TABLE PAA1600F DROP CONSTRAINT PAA1600Q; \ No newline at end of file diff --git a/src/lv/lv2500.cpp b/src/lv/lv2500.cpp index 0656939c6..1dfcd12e7 100755 --- a/src/lv/lv2500.cpp +++ b/src/lv/lv2500.cpp @@ -599,25 +599,25 @@ void TFatturazione_lavanderie::post_process(TLista_documenti& doc_out, TLista_do doc.put(DOC_NOTE, descr); doc.destroy_row(1, true); } - if (!pack_rif() && doc.physical_rows() > 0 && doc[1].is_descrizione()) - { - TRiga_documento& rout = doc[1]; - TString descr = rout.get(RDOC_DESCR); + if (!pack_rif() && doc.physical_rows() > 0 && doc[1].is_descrizione()) + { + TRiga_documento& rout = doc[1]; + TString descr = rout.get(RDOC_DESCR); - descr << ' ' << rout.get(RDOC_DESCEST); + descr << ' ' << rout.get(RDOC_DESCEST); - const int l = descr.find("n. "); - int pos = descr.find("n. ", l + 1); - while (pos > 0) - { - descr.overwrite(" n. ", pos - l - 1, l + 4); - pos = descr.find("n. ", pos + 1); - } - descr.strip_double_spaces(); - rout.put(RDOC_DESCR, descr.left(50)); - rout.put(RDOC_DESCLUNGA, descr.len() > 50); - rout.put(RDOC_DESCEST, descr.mid(51)); - } + const int l = descr.find("n. "); + int pos = descr.find("n. ", l + 1); + while (pos > 0) + { + descr.overwrite(" n. ", pos - l - 1, l + 4); + pos = descr.find("n. ", pos + 1); + } + descr.strip_double_spaces(); + rout.put(RDOC_DESCR, descr.left(50)); + rout.put(RDOC_DESCLUNGA, descr.len() > 50); + rout.put(RDOC_DESCEST, descr.mid(51)); + } aggiorna_fattura(doc, contr.get_int(LVCONDV_CODCONT)); if (doc.physical_rows() > 0) doc.sort_rows(RDOC_CODART "|LVTYPE"); diff --git a/src/ve/velib03.cpp b/src/ve/velib03.cpp index c0b3d3d7f..c5f60dbc1 100755 --- a/src/ve/velib03.cpp +++ b/src/ve/velib03.cpp @@ -3345,7 +3345,7 @@ void TDocumento::get_protocolli_esenzione(TString& esenzione, TString& data_esen bool TDocumento::is_split_payment() const { bool yes = get_int(DOC_ANNO) >= 2015 && clifor().get_bool(CLI_SPLITPAY) && - (is_fattura() || is_nota_credito()) && !imposta().is_zero() && ritenute().is_zero(); + (is_fattura() || is_nota_credito()) && !imposta().is_zero(); if (yes) { const TRectype& causale = cache().get(LF_CAUSALI, tipo().causale());