diff --git a/src/ve01/ve0100.cpp b/src/ve01/ve0100.cpp index 207e9f8b5..1430369cf 100644 --- a/src/ve01/ve0100.cpp +++ b/src/ve01/ve0100.cpp @@ -15,7 +15,7 @@ #include "verig.h" #include "velib04.h" #include "velib07.h" -#include "../fp/fplib.h" +#include "../fp01/fplib.h" #include "../mg/mglib.h" #include "../li/lilib01.h" @@ -25,7 +25,6 @@ #include "../cg/cfban.h" - TCursor* TMotore_application::get_filtered_cursor() const { const TEdit_field& f = _msk->efield(F_NDOC); @@ -315,15 +314,15 @@ void TMotore_application::init_modify_mode( TMask& m ) { TString prg_invio = ((TDocumento_mask & )m).doc().get(DOC_PRG_INVIO); TString xml_name = ((TDocumento_mask &)m).doc().get(DOC_XML_NAME); - const TString & esito = ((TDocumento_mask &)m).doc().get(DOC_STATO_SDI); // "|Da generare X|Da inviare I|Inviate C|Consegnate E|In errore D|Diag. + const TString & esito = ((TDocumento_mask &)m).doc().get(DOC_STATO_SDI); // " |Da generare X|Da inviare I|Inviate C|Consegnate E|In errore D|Diag. bool has_xml = ((TDocumento_mask &)m).doc().acquisto() ? xml_name.full() : prg_invio.full(); m.disable(F_PRG_INVIO); m.disable(F_STATO_SDI); m.enable(DLG_XML_PREVIEW, has_xml); m.enable(DLG_PDF_PREVIEW, has_xml); - m.enable(DLG_CHECK_SDI, has_xml); - m.enable(DLG_INVIO_SDI, has_xml && esito == "X"); + m.enable(DLG_CHECK_SDI, has_xml && fp_has_check()); + m.enable(DLG_INVIO_SDI, has_xml && (esito == "X" || esito == "E" || esito == "D")); m.enable(DLG_ESITO_SDI, has_xml && esito == "C" && esito == "E"); } if (m.exist(F_ACQ_SHEET)) @@ -762,7 +761,8 @@ bool TMotore_application::user_create( ) { open_files(LF_DOC, LF_RIGHEDOC, LF_CONDV, LF_RCONDV, LF_ANAMAG, LF_SCONTI, LF_UMART, LF_DESLIN, LF_CODCORR, LF_TAB, LF_TABCOM, LF_CLIFO, LF_CFVEN, LF_INDSP, LF_OCCAS, LF_PCON, LF_MOV, LF_STOMAG, - LF_MOVMAG, LF_RMOVMAG, LF_MAG, LF_SVRIEP, LF_AGENTI, LF_PERCPROV, LF_ATTIV, LF_CAUSALI, 0); + LF_MOVMAG, LF_RMOVMAG, LF_MAG, LF_SVRIEP, LF_AGENTI, LF_PERCPROV, LF_ATTIV, LF_CAUSALI, + LF_RDOCTEMPLATE, 0); TISAM_recordset num("USE %NUM"); for (bool ok = num.move_first(); ok; ok = num.move_next()) @@ -1295,72 +1295,89 @@ void TMotore_application::mask2ini(const TMask& m, TConfig& ini) bool TMotore_application::save_and_print(bool savedoc, TPrtype mode) { - static bool already_printing = false; - if (already_printing) - return false; - already_printing = true; + static bool already_printing = false; + if (already_printing) + return false; + already_printing = true; - if (savedoc) + if (savedoc) { - TSheet_field& ss = edit_mask().sfield(F_SHEET); - if (!ss.on_key(K_ENTER)) - return already_printing = false; + TSheet_field& ss = edit_mask().sfield(F_SHEET); + if (!ss.on_key(K_ENTER)) + return already_printing = false; - if (save(false)) - edit_mask().update_father_rows(false); - else - return already_printing = false; - } + if (save(false)) + edit_mask().update_father_rows(false); + else + return already_printing = false; + } - const TDocumento& doc = (const TDocumento&)get_relation()->curr(); - - const TTipo_documento& tipo = doc.tipo(); - TFilename rep; + const TDocumento& doc = (const TDocumento&)get_relation()->curr(); - const bool da_stampare = doc.stampabile(); - const char old_stato = doc.stato(); + const TTipo_documento& tipo = doc.tipo(); + TFilename rep; - TString commandline; + int filter = has_module(RSAUT) ? 2 : 1; + while (filter > 0 && !tipo.main_print_profile(rep, filter)) + filter--; - commandline = "ve011 -2"; // Esiste il nuovo report :-) - commandline << ' ' << doc.get(DOC_CODNUM) << ' ' << doc.get(DOC_ANNO) - << ' ' << doc.get(DOC_PROVV) << ' ' << doc.get(DOC_NDOC) << ' '; - switch (mode) - { - case exportprinter: commandline << " E"; break; - case fileprinter : commandline << " P"; break; - case screenvis : commandline << " A"; break; - default : commandline << " S"; break; - } - commandline << ' ' << (da_stampare ? 'D' : 'P'); + if (filter > 0) + { + const bool da_stampare = doc.stampabile(); + const char old_stato = doc.stato(); - const int ncopie = tipo.ncopie(); - if (ncopie > 0) - commandline << ' ' << ncopie; + TString commandline; + commandline = "ve1 -"; + if (filter == 2) + commandline << 2; // Esiste il nuovo report :-) + else + commandline << 0; // Esiste il vecchio form :-( - TExternal_app interattivo( commandline ); + commandline << ' ' << doc.get(DOC_CODNUM) << ' ' << doc.get(DOC_ANNO) + << ' ' << doc.get(DOC_PROVV) << ' ' << doc.get(DOC_NDOC) << ' '; + switch (mode) + { + case exportprinter: commandline << " E"; break; + case fileprinter: commandline << " P"; break; + case screenvis: commandline << " A"; break; + default: commandline << " S"; break; + } + commandline << ' ' << (da_stampare ? 'D' : 'P'); - if (interattivo.run() == NOERR) - { - TDocumento_mask& m = edit_mask(); - TDocumento& maindoc = m.doc(); + const int ncopie = tipo.ncopie(); + if (ncopie > 0) + commandline << ' ' << ncopie; - if (da_stampare) // Aggiorna stato documento se necessario - { - maindoc.read(); // Aggiorna STATO e MOVMAG generati da ve1 + TExternal_app interattivo(commandline); + if (interattivo.run() == NOERR) + { + TDocumento_mask& m = edit_mask(); + TDocumento& maindoc = m.doc(); - // Lo stato del documento vive di vita propria - const char sfs = maindoc.tipo().stato_finale_stampa(); - const char new_stato = old_stato > sfs ? old_stato : sfs; - maindoc.stato(new_stato); - const char ss[2] = { new_stato, '\0' }; - m.set(F_STATO, ss, true); - init_modify_mode(m); - } - do_elab(maindoc, true); - } - already_printing = false; - return true; + if (da_stampare) // Aggiorna stato documento se necessario + { + maindoc.read(); // Aggiorna STATO e MOVMAG generati da ve1 + + // Lo stato del documento vive di vita propria + const char sfs = maindoc.tipo().stato_finale_stampa(); + const char new_stato = old_stato > sfs ? old_stato : sfs; + maindoc.stato(new_stato); + const char ss[2] = { new_stato, '\0' }; + m.set(F_STATO, ss, true); + init_modify_mode(m); + } + do_elab(maindoc, true); + } + } + else + { + rep.ext(""); + cantread_box(rep); + return already_printing = false; + } + + already_printing = false; + return true; } void TMotore_application::print() diff --git a/src/ve01/ve0100.h b/src/ve01/ve0100.h index 16c03329c..873d15636 100644 --- a/src/ve01/ve0100.h +++ b/src/ve01/ve0100.h @@ -37,7 +37,8 @@ class TMotore_application : public TRelation_application int _ncopie; protected: - // Array di maschere documento + + // Array di maschere documento TAssoc_array _doc_masks; // Ridefinizione dei metodi virtuali virtual bool user_create(); diff --git a/src/ve01/ve0100x.uml b/src/ve01/ve0100x.uml index 6fd0ec0c3..3eb9cc0e6 100644 --- a/src/ve01/ve0100x.uml +++ b/src/ve01/ve0100x.uml @@ -20,7 +20,7 @@ BEGIN FLAGS "D" END -LIST S_TIPODOCSDI 40 +LIST S_TIPODOCSDI 4 50 BEGIN PROMPT 25 1 "Tipo Doc SDI" ITEM "TD01|TD01 Fattura" @@ -29,6 +29,9 @@ BEGIN ITEM "TD04|TD04 Nota di credito" ITEM "TD05|TD05 Nota di debito" ITEM "TD06|TD06 Parcella" + ITEM "TD07|TD07 Fattura semplificata" + ITEM "TD08|TD08 Nota di credito semplificata" + ITEM "TD09|TD09 Nota di debito semplificata" ITEM "TD16|TD16 Integraz. fatt. rev.ch. interno" ITEM "TD17|TD17 Integ./autof. acq. servizi estero" ITEM "TD18|TD18 Integ. acq. beni intracomunitari" @@ -41,6 +44,8 @@ BEGIN ITEM "TD25|TD25 Fatt. differita art. 21 c.4 per.3 b" ITEM "TD26|TD26 Cess. beni ammort./passaggi interni" ITEM "TD27|TD27 Fatt. autoconsumo/cessioni gratuite" + ITEM "TD28|TD28 Autofattura acquisti da San Marino con IVA" + ITEM "TD29|TD29 Autofattura per errata o omessa fatturazione" FLAGS "D" END diff --git a/src/ve01/ve1300.cpp b/src/ve01/ve1300.cpp index 377715920..c20b47b8c 100644 --- a/src/ve01/ve1300.cpp +++ b/src/ve01/ve1300.cpp @@ -345,7 +345,7 @@ int TReport_doc::set_printed_status(TDocumento& doc) const TString stato; stato << doc.stato(); - ini.set(DOC_STATO, stato); + ini.set(DOC_STATO, stato); } ::dispatch_transaction(doc, tmpname); ::remove(tmpname); @@ -1248,16 +1248,26 @@ bool TReport_doc_app::get_mail_address(TToken_string& to, TToken_string& cc) con contacts.set_var("#CLIFO", clifo); - TToken_string data; + TAuto_token_string data; for (bool ok = contacts.move_first(); ok; ok = contacts.move_next()) { data = contacts.get("DATA").as_string(); + bool first = true; + int codcont = 0L; + FOR_EACH_TOKEN(data, tok) { + if (first) + { + codcont = atoi(tok); + first = false; + } + else + { if (_tipodoc.match(tok, true) || report.match(tok, true)) { - const TRectype& rub = cache().get(LF_CONTACT, contacts.get("SECOND").as_int()); + const TRectype& rub = cache().get(LF_CONTACT, codcont); TString80 mail = rub.get("MAIL"); if (mail.blank()) @@ -1274,8 +1284,7 @@ bool TReport_doc_app::get_mail_address(TToken_string& to, TToken_string& cc) con } } } - - + } return to.full(); } @@ -1483,7 +1492,7 @@ bool TReport_doc_app::print_loop(TRecordset& doc, TOutput_mode mode, bool final_ } // Controllo se devo archiviare in base ai parametri passati - arc = (_arc_type == _force) || (_arc_type == _auto && arc); + arc = (_arc_type == _force || _arc_type == _auto) && arc; set_next_pdf(&doc); @@ -1508,7 +1517,6 @@ bool TReport_doc_app::print_loop(TRecordset& doc, TOutput_mode mode, bool final_ } TReport_doc& report = reports.get(profilo); - if (send_mail) { if (mail_loop) @@ -1717,17 +1725,17 @@ TReport_doc_app::TOutput_mode TReport_doc_app::key2mode(KEY k) const k -= ' '; // toupper dei poveri if (k == 'A') k = K_VISUALIZE; - switch (k) - { - case K_VISUALIZE: mode = out_preview; break; - case 'E': mode = out_mail; break; - case 'e': mode = out_signed_mail; break; - case 'P': mode = out_pdf; break; - case 'X': mode = out_disk; break; - case 'p': mode = out_signed_pdf; break; - case 'S': - default: mode = out_print; break; - } + switch (k) + { + case K_VISUALIZE: mode = out_preview; break; + case 'E': mode = out_mail; break; + case 'e': mode = out_signed_mail; break; + case 'P': mode = out_pdf; break; + case 'X': mode = out_disk; break; + case 'p': mode = out_signed_pdf; break; + case 'S': + default: mode = out_print; break; + } return mode; } diff --git a/src/ve01/velib.h b/src/ve01/velib.h index 842f9a468..b6ffa336f 100644 --- a/src/ve01/velib.h +++ b/src/ve01/velib.h @@ -57,6 +57,10 @@ class TSelect_color_mask; #include #endif +#ifndef __RDOCDEF_H +#include +#endif + #ifndef __LILIB01_H #include "../li01/lilib01.h" #endif @@ -107,6 +111,17 @@ bool note_hndl(TMask_field& field, KEY key); bool data_hndl(TMask_field& field, KEY key); void set_curr_um(const TString& um); +inline bool fattura_semplificata(const TString & tipo_trasmissione) { return tipo_trasmissione.starts_with("FSM"); } +inline bool fattura_ordinaria(const TString & tipo_trasmissione) { return tipo_trasmissione.starts_with("FP"); } +inline bool fattura_ordinaria_privati(const TString & tipo_trasmissione) { return tipo_trasmissione.starts_with("FPR"); } +inline bool fattura_ordinaria_PA(const TString & tipo_trasmissione) { return tipo_trasmissione.starts_with("FPA"); } + +inline bool fattura_semplificata(const TXmlItem & dati_trasmissione) { return dati_trasmissione.GetEnclosedText("FormatoTrasmissione").starts_with("FSM"); } +inline bool fattura_ordinaria(const TXmlItem & dati_trasmissione) { return dati_trasmissione.GetEnclosedText("FormatoTrasmissione").starts_with("FP"); } +inline bool fattura_ordinaria_privati(const TXmlItem & dati_trasmissione) { return dati_trasmissione.GetEnclosedText("FormatoTrasmissione").starts_with("FPR"); } +inline bool fattura_ordinaria_PA(const TXmlItem & dati_trasmissione) { return dati_trasmissione.GetEnclosedText("FormatoTrasmissione").starts_with("FPA"); } + +TString & get_xml_filename(bool ven, int anno, const char * xml_filename); class TDocumento_variable_field : public TVariable_field { @@ -743,7 +758,7 @@ public: bool raggruppabile(const TRiga_documento& r, TToken_string& campi) const; TRiga_documento& operator +=(const TRiga_documento& r); - virtual void reset_fields(TAuto_variable_rectype& rec, bool all = true) { rec.remove_field(); } + virtual void reset_fields(TAuto_variable_rectype& rec, bool all = true) { rec.remove_field(nullptr, all); } void set_fields(TAuto_variable_rectype& rec); real prezzo(bool scontato, bool lordo, int ndec = AUTO_DECIMALS) const ; @@ -895,6 +910,7 @@ class TDocumento : public TMultiple_rectype // velib03 TMask * _sel_tiporiga; TFilename _xml_orig_name; TFP_tipo_art * _tipi_art; + TString _tipo_trasmissione; protected: virtual TRectype * new_body_record(int logicnum = 0) @@ -973,8 +989,11 @@ protected: bool find_codart(TString & codart, TString & codartmag, TString & tiporiga, bool artforn); void get_dati_gestionali(TXmlItem & riga); bool get_riga(TXmlItem & riga, bool newdoc, bool & first, TXmlItem * sconto = nullptr); + bool get_riga_semplificata(TXmlItem & riga, bool newdoc, bool & first); bool get_righeIVA(TAssoc_array & riepilogoIVA); - bool get_dettaglio(TXmlItem & corpo, bool newdoc, TAssoc_array & riepilogoIVA); + bool get_arrotondamento(TAssoc_array & riepilogoIVA); + bool get_dettaglio(TXmlItem & corpo, bool newdoc, TAssoc_array & riepilogoIVA, TAssoc_array & arrotondamenti); + bool get_dettaglio_semplificata(TXmlItem & corpo, bool newdoc); bool get_pagamento(TXmlItem & pagamento); bool get_allegati(TXmlItem & allegato); bool get_xml_body(TXmlItem & root, real & totale_imp, bool newdoc); @@ -982,6 +1001,10 @@ protected: TSpesa_prest * find_ritfisc(const TString & codicesdi); TSpesa_prest * find_ritsoc(const TString & codicesdi, bool soggrit); const char * find_codIVA(real aliquota, TString & natura); + bool fattura_semplificata() const { return ::fattura_semplificata(_tipo_trasmissione); } + bool fattura_ordinaria() const { return ::fattura_ordinaria(_tipo_trasmissione); } + bool fattura_ordinaria_privati() const { return ::fattura_ordinaria_privati(_tipo_trasmissione); } + bool fattura_ordinaria_PA() const { return::fattura_ordinaria_PA(_tipo_trasmissione); } public: virtual TRiga_documento * rowptr(int index); @@ -1182,6 +1205,7 @@ public: bool get_bank_presentazione(TString& iban, TString& abi, TString& cab, TString& istituto) const; bool get_bank_appoggio(TString& iban, TString& abi, TString& cab, TString& istituto) const; bool generate_xml(TLog_report * log = nullptr); + bool check(); bool send_xml(); bool import_xml(TFilename & xmlname, TLog_report * log = nullptr); @@ -1290,7 +1314,7 @@ public: class TDocumento_mask : public TVariable_mask // velib06 { - int _progs_page; // pagina in cui cominciano i progressivi + int _anal_page; // pagina analitica TSheet_field* _sheet; // Spreadsheet TDocumento _doc; // documento TCodgiac_livelli * _livelli_giac; // livelli di giacenza @@ -1362,6 +1386,8 @@ public: static bool sort_row_handler( TMask_field& f, KEY key ); static bool genera_xml_handler(TMask_field& f, KEY key); static bool importa_xml_handler(TMask_field& f, KEY key); + static bool incolla_handler(TMask_field& f, KEY k); + static bool copia_handler(TMask_field& f, KEY k); static bool savedef_handler(TMask_field& f, KEY k); static bool swap_handler(TMask_field& f, KEY k); static bool ss_notify(TSheet_field& ss, int r, KEY key); @@ -1429,12 +1455,11 @@ public: short cdc_end_sh() const { return _cdc_end_sh;} short cms_start_sh() const { return _cms_start_sh;} short cms_end_sh() const { return _cms_end_sh;} - TString& codcms() { return _codcms;} - const TString& codcms() const { return _codcms;} - TString& codcms_sh() { return _codcms_sh;} - const TString & codcms_sh() const { return _codcms_sh;} - TString& codart() { return _codart; } - const TString & codart() const { return _codart; } + TString& codcms(); + TString& codcms_sh(int nrow = -1); + TString& codart(int nrow = -1); + + const int anal_page() const { return _anal_page; } TArray& color_rules() { return _color_rules; } diff --git a/src/ve01/velib03.cpp b/src/ve01/velib03.cpp index 2e9123251..6284c95d2 100644 --- a/src/ve01/velib03.cpp +++ b/src/ve01/velib03.cpp @@ -1341,7 +1341,7 @@ static real doc_inventory_qta(const TCausale_magazzino & cau, const TString & co int TDocumento::write_rewrite(TBaseisamfile & f, bool re) const { TDocumento& myself = *((TDocumento *)this); - const bool new_doc = nuovo() || numero() <= 0; // E' nuovo di zecca! + const bool new_doc = nuovo() || numero() <= 0; // E' nuovo di zecca! if (new_doc) { @@ -1502,7 +1502,7 @@ int TDocumento::write_rewrite(TBaseisamfile & f, bool re) const const bool articolo = r.is_articolo(); bool valid_row = articolo; - cod_caus_riga = r.get(RDOC_CAUSMAG); + cod_caus_riga = r.get(RDOC_CAUSMAG); if (articolo) codart = r.get(RDOC_CODARTMAG); else @@ -1742,7 +1742,7 @@ int TDocumento::write_rewrite(TBaseisamfile & f, bool re) const rdoc->put(f, rdoc->retrieve_original_row_field(rif_fld)); } if (rdoc->is_descrizione()) - myself.reset_fields(*rdoc); + myself.reset_fields(*rdoc, false); } err = TMultiple_rectype::write_rewrite(f, re); @@ -3013,7 +3013,7 @@ void TDocumento::put_str(const char* fieldname, const char* val) if (TRectype::get(DOC_TIPODOC) != v) { TAuto_variable_rectype::put_str(fieldname, v); - reset_fields(*this); + reset_fields(*this, false); set_fields(*this); } else @@ -3446,26 +3446,26 @@ void TDocumento::update_conai_qta() { _conaiqta.destroy(); FOR_EACH_SELF_PHYSICAL_RDOC(i, r) - if (r->is_merce() || r->is_omaggio()) - { - TString current_cat; + if (r->is_merce() || r->is_omaggio()) + { + TString current_cat; - for (int i = 1; i <= FR_CMAX; i++) - { - TString8 cat = r->get(conai_sottocat_name(i)); + for (int i = 1; i <= FR_CMAX; i++) + { + TString8 cat = r->get(conai_sottocat_name(i)); - if (cat.full()) - { - const real rowqty = r->calc_conai_qta(i); + if (cat.full()) + { + const real rowqty = r->calc_conai_qta(i); - real * q = (real *)_conaiqta.objptr(cat); - - if (q == NULL) - _conaiqta.add(cat, q = new real); - *q += rowqty; - } - } - } + real * q = (real *) _conaiqta.objptr(cat); + + if (q == NULL) + _conaiqta.add(cat, q = new real); + *q += rowqty; + } + } + } } const char* get_cf_esenz(const TString& tipo_conai) diff --git a/src/ve01/velib06.cpp b/src/ve01/velib06.cpp index 6844e15ef..66214a2ad 100644 --- a/src/ve01/velib06.cpp +++ b/src/ve01/velib06.cpp @@ -94,9 +94,9 @@ short conai_sottocat_id(int id) /////////////////////////////////////////////////////////// TDocumento_mask::TDocumento_mask(const char* td, short cust_height) - : TVariable_mask(), _progs_page(-1), _condv(nullptr), //_smartcard(nullptr), + : TVariable_mask(), _condv(nullptr), //_smartcard(nullptr), _cms_start(-1), _cms_end(-1), _cms_start_sh(-1), _cms_end_sh(-1), - _cdc_start(-1), _cdc_end(-1), _cdc_start_sh(-1), _cdc_end_sh(-1), _xml_page(-1) + _cdc_start(-1), _cdc_end(-1), _cdc_start_sh(-1), _cdc_end_sh(-1), _xml_page(-1), _anal_page(-1) { CHECK(td && *td && strlen(td) <= 4, "TDocumento_mask(TipoDocumento) not (MaskName)"); { @@ -130,7 +130,7 @@ TDocumento_mask::TDocumento_mask(const char* td, short cust_height) if (d.tipo().sdi()) add_xml_page(); configura_sheet(*_sheet); - + ((TVariable_sheet_field*)_sheet)->set_getmask( ss_getmask ); if (_doc.tipo().clifo_optional()) { @@ -192,6 +192,7 @@ TDocumento_mask::TDocumento_mask(const char* td, short cust_height) set_field_handler(DLG_XML_PREVIEW, vis_xml_handler); set_field_handler(DLG_PDF_PREVIEW, vis_pdf_handler); set_field_handler(DLG_CHECK_ACQ, check_acquisti_handler); + set_field_handler(DLG_CHECK_SDI, check_sdi_handler); } } @@ -341,9 +342,7 @@ TDocumento_mask::TDocumento_mask(const char* td, short cust_height) } } } - - const TDongle& a = dongle(); - if (a.active(CTAUT) || a.active(PAAUT)) +// if (main_app().has_module(CTAUT, CHK_DONGLE) || main_app().has_module(PAAUT, CHK_DONGLE)) { if (_ges_ca && id2pos(F_CUP) > 0) // Se gestisco l'analtica ... { @@ -425,13 +424,13 @@ TDocumento_mask::TDocumento_mask(const char* td, short cust_height) } } } - else +/* else { hide(F_CUP); hide(F_DESCRCUP); hide(F_CIG); hide(F_DESCRCIG); - } + }*/ const bool gesoff = cfg.get_bool("GES", "ve", 3); enable(F_CODCAMP, gesoff); @@ -634,11 +633,16 @@ void TDocumento_mask::insert_anal_page() { if (id2pos(F_CDC1) >= 0) return; - int newpage = win2page(_sheet->parent()); - if (newpage == 0) - newpage++; - create_page(TR("Analitica"), newpage); // Inserisce una pagina vuota con un titolo a caso + TFilename pn; doc().tipo().profile_name(pn); + TConfig prof(pn); + + int newpage = prof.get_int("AnalPage", "MAIN", -1, 0) - 1; + + if (newpage < 0) + newpage = win2page(_sheet->parent()); + create_page(TR("Analitica"), newpage); // Inserisce una pagina vuota con un titolo a caso + _anal_page = newpage; add_groupbox(DLG_NULL, newpage, "", 1, 0, 78, 6); add_string(DLG_NULL, newpage, TR("Cod. num. "), 2, 1, 4, "D").set_group(2); add_string(DLG_NULL, newpage, "", 24, 1, 50, "D").set_group(3); @@ -861,6 +865,7 @@ void TDocumento_mask::add_xml_page() { add_string(F_PRG_INVIO, newpage, TR("Prog.invio "), 50, 6, 7, "D").set_field(DOC_PRG_INVIO); add_list(F_STATO_SDI, newpage, TR("Stato "), 2, 7, 30, "D", " |X|I|C|E|D", "Da generare|Da inviare|Inviata|Consegnata|In errore|Diagnosticata").set_field(DOC_STATO_SDI); + TList_field & stile = add_list(F_STILE_SDI, newpage, TR("Foglio di stile "), 2, 8, 50, "", "", ""); TToken_string codes; TToken_string items; @@ -876,8 +881,8 @@ void TDocumento_mask::add_xml_page() } stile.replace_items(codes, items); add_button(DLG_RECALC, newpage, TR("~Genera"), 2, 10, 10, 2, "", BMP_GENERA, BMP_GENERA); - add_button(DLG_INVIO_SDI, newpage, TR("~Invia"), 20, 10, 10, 2, "", TOOL_EXPORT, TOOL_EXPORT); - add_button(DLG_CHECK_SDI, newpage, TR("~Controlla"), 40, 10, 10, 2, "", BMP_CHECK2, BMP_CHECK2); + add_button(DLG_INVIO_SDI, newpage, TR("~Invia"), 20, 10, 10, 2, "", BMP_EXPORT, BMP_EXPORT); + add_button(DLG_CHECK_SDI, newpage, TR("~Controlla"), 40, 10, 10, 2, "", BMP_CHECK, BMP_CHECK); add_button(DLG_ESITO_SDI, newpage, TR("~Esito"), 60, 10, 10, 2, "", BMP_OK, BMP_OK); add_button(DLG_XML_PREVIEW, newpage, TR("~XML"), 2, 13, 10, 2, "", BMP_XML, BMP_XML); add_button(DLG_PDF_PREVIEW, newpage, TR("~PDF"), 20, 13, 10, 2, "", BMP_PDF, BMP_PDF); @@ -905,13 +910,14 @@ void TDocumento_mask::add_xml_page() } stile.replace_items(codes, items); - add_button(DLG_IMPORT, newpage, TR("~Importa"), 2, 11, 10, 2, "", BMP_IMPORT, BMP_IMPORT); - add_button(DLG_XML_PREVIEW, newpage, TR("~XML"), 33, 11, 10, 2, "", BMP_XML, BMP_XML); - add_button(DLG_PDF_PREVIEW, newpage, TR("~PDF"), 68, 11 , 10, 2, "", BMP_PDF, BMP_PDF); + add_button(DLG_IMPORT, newpage, TR("~Importa"), 2, 11, 11, 2, "", BMP_IMPORT, BMP_IMPORT); + add_button(DLG_XML_PREVIEW, newpage, TR("~XML"), 20, 11, 11, 2, "", BMP_XML, BMP_XML); + add_button(DLG_PDF_PREVIEW, newpage, TR("~PDF"), 40, 11 , 11, 2, "", BMP_PDF, BMP_PDF); + add_button(DLG_CHECK_SDI, newpage, TR("~Controlla"), 60, 11, 11, 2, "", BMP_CHECK, BMP_CHECK); TString head = "|Anno|Progressivo\ninvio@40|Tipo Documento\nSDI@40|Numero\nDocumento@40|Data\nDoc.@10|Data\nRicezione@8|Totale\nDocumento@12|Stato\nP.IVA@4|Partita IVA@10|Fornitore@6|Ragione Sociale@50|XML@80"; - TSheet_field & sh = add_sheet(F_ACQ_SHEET, newpage, "XML", "ve0100x", 0, head, 2, 13, 0, 10); + TSheet_field & sh = add_sheet(F_ACQ_SHEET, newpage, "XML", "ve0100x", 0, head, 2, 14, 0, 10); sh.set_notify(xml_notify); sh.sheet_mask().field(S_SELECTED).set_handler(xml_select); @@ -1274,7 +1280,15 @@ bool TDocumento_mask::on_key(KEY key) } return true; } - + else + if (key == K_SHIFT + K_F8) + { + const TSheet_field & sf = sfield(F_SHEET); + int curr_row = sf.selected(); + + riga_mask(curr_row)->field(FR_CODART).on_key(K_F8); + return true; + } return TVariable_mask::on_key(key); } @@ -1715,7 +1729,7 @@ void TDocumento_mask::spese2mask() if (s.not_empty()) spese.add(s); } - + doc().put(DOC_SPESEUPD, false); doc().put(DOC_CODVAL, get(F_CODVAL)); doc().put(DOC_CAMBIO, get(F_CAMBIO)); @@ -2037,7 +2051,7 @@ TVariable_mask* TDocumento_mask::riga_mask(int numriga) if (m->id2pos(FR_PREZZO) >= 0) { TEditable_field& f = (TEditable_field&)m->efield(FR_PREZZO); - f.reset_driver(F_CODVAL); + f.reset_driver(F_CODVAL); f.add_driver(-F_CODVAL); } @@ -2239,7 +2253,8 @@ bool TDocumento_mask::ss_handler(TMask_field& f, KEY key) { // Controllo se la commessa è veramente obbligatoria in base alla configurazione TConfig& ini = ca_config(); - if ((ini.get_int("Authorizations") & 0x6) && (ini.get_bool("CmsRequired") || ini.get("FathFasi").full())) + if ((ini.get_int("Authorizations") & 0x6) && ca_active(mask.get_date(F_DATADOC)) && + (ini.get_bool("CmsRequired") || ini.get("FathFasi").full())) { const short cmes = mask.cms_end_sh(); if (cmes > 0) // Puo' succedere che sia < 0 in assenza di righe buone @@ -4058,16 +4073,7 @@ void TElabora_mask::update_ndoc_filter(bool is_tipo_elaborazione) { if (aggiungi_doc_att) { - bool agg_test = e->aggiorna_testata_se_vuoto(); - - if (agg_test) - { - const int nrighe = _main->doc().physical_rows(); - - for (int i = 1;agg_test && i <= nrighe; i++) - if (!_main->doc()[i].is_generata()) - agg_test = false; - } + const bool agg_test = e->aggiorna_testata_se_vuoto() && !_main->doc().valid(); set(F_UPDATE_HEADER, agg_test ? "X" : ""); const TString4 num_in = e->codice_numerazione_iniziale(); @@ -4726,8 +4732,8 @@ bool TDocumento_mask::genera_xml_handler(TMask_field& f, KEY key) const TString & esito = m.get(F_STATO_SDI); // "|Da generare X|Da inviare I|Inviate C|Consegnate E|In errore D|Diag. m.enable(DLG_PDF_PREVIEW, prg_invio.full()); - m.enable(DLG_CHECK_SDI, prg_invio.full()); - m.enable(DLG_INVIO_SDI, prg_invio.full() && esito == "X"); + m.enable(DLG_CHECK_SDI, prg_invio.full() && fp_has_check()); + m.enable(DLG_INVIO_SDI, prg_invio.full() && (esito == "X" || esito == "E" || esito == "D")); m.enable(DLG_ESITO_SDI, prg_invio.full() && esito == "C" && esito == "E"); } } @@ -5220,6 +5226,38 @@ bool TDocumento_mask::sort_row_handler( TMask_field& f, KEY key ) return true; } +TString& TDocumento_mask::codcms() +{ + TString & codcms = get_tmp_string(); + + for (short id = cms_start(); id <= cms_end(); id++) + codcms << get(id); + return codcms; +} + +TString& TDocumento_mask::codcms_sh(int nrow) +{ + TString & codcms = get_tmp_string(); + TSheet_field & sh = sfield(F_SHEET); + + if (nrow < 0) + nrow = sh.selected(); + for (short id = cms_start_sh(); id <= cms_end_sh(); id++) + codcms << sh.get_str_row_cell(nrow, cid2index(id)); + return codcms; +} + +TString& TDocumento_mask::codart(int nrow) +{ + TString & codart = get_tmp_string(); + TSheet_field & sh = sfield(F_SHEET); + + if (nrow < 0) + nrow = sh.selected(); + codart = sh.get_str_row_cell(nrow, FR_CODART); + return codart; +} + void TDocumento_mask::sel_color() { const TString& mn = doc().tipo().mask_name(); diff --git a/src/ve01/velib06a.cpp b/src/ve01/velib06a.cpp index 02066c8ab..6c04805e9 100644 --- a/src/ve01/velib06a.cpp +++ b/src/ve01/velib06a.cpp @@ -2,7 +2,6 @@ #include #include #include -#include #include #include #include @@ -454,6 +453,8 @@ bool data_hndl( TMask_field& field, KEY key ) { TDocumento_mask& m = (TDocumento_mask &) field.mask(); + if ((field.initial_check(key) || field.to_check(key)) && m.anal_page() >= 0) + m.enable_single_page(m.anal_page(), ca_active(field.get_date())); if (field.to_check(key)) { if (m.id2pos(F_DATAINSC) > 0) @@ -1773,6 +1774,27 @@ bool link_row_handler(TMask_field& f, KEY key ) return codart_handler( f, key); } +HIDDEN real get_prezzo(const TString& codart, int tipoprezzo, TDate datadoc) +{ + real costo; + const TArticolo_giacenza& art = cached_article_balances(codart); + TEsercizi_contabili esc; + const int annoes = esc.date2esc(datadoc); + + switch (tipoprezzo) + { + case 1: costo = art.ultimo_costo(annoes); break; + case 2: costo = art.media_costi(annoes); break; + case 4: costo = art.costo_standard(annoes); break; + case 5: costo = art.costo_medio(annoes, "", ""); break; + case 6: costo = art.costo_mediopond(annoes, "", ""); break; + default: break; + } + if (costo.is_zero()) + costo = art.get_real(ANAMAG_COSTSTD); + return costo; +} + bool codart_handler(TMask_field& f, KEY key ) { TMask & row_mask = f.mask(); @@ -1979,13 +2001,16 @@ bool codart_handler(TMask_field& f, KEY key ) if (explode_db && !sh.sheet_mask().is_running()) { - const bool valcomp = ini_get_bool(CONFIG_DITTA, "ve", "VALCOMP"); - const bool matbase = ini_get_bool(CONFIG_DITTA, "ve", "TIPOESPL"); - const TExplosion_grouping raggart = (TExplosion_grouping) ini_get_int(CONFIG_DITTA, "ve", "RAGGART"); - const bool elrorig = ini_get_bool(CONFIG_DITTA, "ve", "ELRORIG"); - const int livello = ini_get_int(CONFIG_DITTA, "ve", "LIVESPL"); - const int ordin = ini_get_int(CONFIG_DITTA, "ve", "ORDDB"); + TString8 valcomp = ini_get_string(CONFIG_DITTA, "ve", "VALCOMP"); + bool matbase = ini_get_bool(CONFIG_DITTA, "ve", "TIPOESPL"); + TExplosion_grouping raggart = (TExplosion_grouping) ini_get_int(CONFIG_DITTA, "ve", "RAGGART"); + bool elrorig = ini_get_bool(CONFIG_DITTA, "ve", "ELRORIG"); + int livello = ini_get_int(CONFIG_DITTA, "ve", "LIVESPL"); + int ordin = ini_get_int(CONFIG_DITTA, "ve", "ORDDB"); + int tipoprezzof = ini_get_int(CONFIG_DITTA, "ve", "TIPOPREZZOF"); + int tipoprezzoc = ini_get_int(CONFIG_DITTA, "ve", "TIPOPREZZOC"); TDocumento & doc = mask.doc(); + const TDate datadoc = doc.get_date(DOC_DATADOC); TRiga_documento & curr_row = doc[current_doc_row]; const int start_level = curr_row.get_int(RDOC_LEVEL); @@ -1994,7 +2019,33 @@ bool codart_handler(TMask_field& f, KEY key ) TDistinta_tree db; TArray components; + TString8 caus(row_mask.get(FR_CAUS)); + if (caus.blank()) + caus = mask.get(F_CAUSMAG); + if (caus.full()) + { + const TCausale_magazzino & causale = cached_causale_magazzino(caus); + + if (causale.caus_collegata().full()) + caus = causale.caus_collegata(); + } + if (caus.full()) + { + const TCausale_magazzino & causale = cached_causale_magazzino(caus); + + if (causale.explodedoc()) + { + valcomp = causale.valcomp(); + matbase = causale.materiali(); + raggart = (TExplosion_grouping) causale.raggrart(); + elrorig = causale.elrorig(); + livello = causale.livello(); + ordin = causale.ordinamento(); + tipoprezzof = causale.tipoprezzof(); + tipoprezzoc = causale.tipoprezzoc(); + } + } db.set_root(curr_row); const int items = db.explode(components, matbase, raggart, livello, "A", ordin); @@ -2005,7 +2056,15 @@ bool codart_handler(TMask_field& f, KEY key ) const TString16 tiporiga(curr_row.tipo().codice()); TString_array& str_arr = sh.rows_array(); + TString8 codcaus = doc.get(DOC_CAUSMAG); + const TCausale_magazzino & caus = cached_causale_magazzino(codcaus); + TString8 codmag = caus.default_mag(); + if (caus.caus_collegata().full()) + { + codcaus = caus.caus_collegata(); + codmag = cached_causale_magazzino(codcaus).default_mag(); + } for (int i = components.first(); i < items; i = components.succ(i)) { pi.addstatus(1L); @@ -2022,16 +2081,28 @@ bool codart_handler(TMask_field& f, KEY key ) new_row.zero(RDOC_DESCEST); new_row.put(RDOC_CHECKED, ""); new_row.put(RDOC_UMQTA, r.um()); + new_row.put(RDOC_CAUSMAG, caus.caus_collegata()); + new_row.put(RDOC_CODMAG, codmag); new_row.put(RDOC_GENERATA, true); + new_row.put(RDOC_GENTIPO, "D"); new_row.put(RDOC_QTA, r.val() /* * qta_fin */); const int level = start_level + r.livello(); new_row.put(RDOC_LEVEL, level); - if (!valcomp) + if (valcomp == "P") { new_row.zero(RDOC_PREZZO); sh.row(row).add("0", sh.cid2index(FR_PREZZO)); row_mask.reset(FR_PREZZO); } + else + if (tipoprezzoc != 0) + { + const real prezzo = get_prezzo(r.articolo(), tipoprezzoc, datadoc); + + new_row.put(RDOC_PREZZO, prezzo); + sh.row(row).add(prezzo, sh.cid2index(FR_PREZZO)); + row_mask.set(FR_PREZZO, prezzo); + } new_row.autoload(sh); sh.check_row(row); new_row.autosave(sh); // Da sheet a rdoc @@ -2044,11 +2115,21 @@ bool codart_handler(TMask_field& f, KEY key ) row--; } else - if (valcomp) + { + if (valcomp == "C") { curr_row.zero(RDOC_PREZZO); curr_row.autoload(sh); } + else + if (tipoprezzof != 0) + { + const real prezzo = get_prezzo(curr_row.get(RDOC_CODARTMAG), tipoprezzof, datadoc); + + curr_row.put(RDOC_PREZZO, prezzo); + curr_row.autoload(sh); + } + } sh.force_update(); sh.post_select(current_doc_row - 1); sh.update_mask(current_doc_row - 1); @@ -2056,7 +2137,6 @@ bool codart_handler(TMask_field& f, KEY key ) } mask.update_giacenza(); } - return true; } @@ -2949,7 +3029,7 @@ bool codfase_handler(TMask_field& f, KEY key) TDocumento& doc = mask.doc(); TConfig& ini = ca_config(); - const bool req = doc.valid() && ini.get_bool("FscRequired"); + const bool req = doc.valid() && ca_active(doc.get_date(DOC_DATADOC)) && ini.get_bool("FscRequired"); if (req && f.empty()) return f.error_box(TR("La fase è obbligatoria per questo tipo documento")); @@ -2968,7 +3048,7 @@ bool codcdc_handler(TMask_field& f, KEY key) mask.mask2doc(); TDocumento& doc = mask.doc(); - const bool req = doc.valid() && doc.tipo().head_ca_required(); + const bool req = doc.valid() && ca_active(doc.get_date(DOC_DATADOC)) && doc.tipo().head_ca_required(); if (f.empty() && req) return f.error_box(TR("Il centro di costo è obbligatorio per questo tipo documento")); @@ -2984,11 +3064,20 @@ bool codcms_handler(TMask_field& f, KEY key) return true; if ((f.running_check(key) || key == K_ENTER) && f.dlg() == mask.cms_end()) // Opera solo sull'ultimo livello del codice commessa { + if (f.running_check(key) && f.dlg() == mask.cms_end()) + { + const TString key = mask.codcms(); + const TRectype & cms = cache().get(LF_COMMESSE, key); + const long codcf = cms.get_long(COMMESSE_CODCF); + + if (codcf != 0L) + mask.set(F_CODCF, codcf, 0x3); + } mask.mask2doc(); TDocumento& doc = mask.doc(); TSheet_field& sf = mask.sfield(F_SHEET); - const bool req = doc.valid() && doc.tipo().head_ca_required(); + const bool req = doc.valid() && ca_active(doc.get_date(DOC_DATADOC)) && doc.tipo().head_ca_required(); if (f.empty()) { @@ -3045,7 +3134,7 @@ bool codcms_handler(TMask_field& f, KEY key) { const int from = f->from(); const int to = f->to(); - mask.set(i, codcosto.sub(from, to), 0x2); + mask.set(i, codcosto.ssub(from, to), 0x2); } } } @@ -3776,22 +3865,6 @@ bool invia_xml_handler(TMask_field& f, KEY key) return true; } -TString & get_xml_filename(bool ven, int anno, const char * xml_filename) -{ - TFilename name; - - name = get_xml_dest(ven, anno); - name.add(xml_filename); - name.ext("xml"); - if (!ven && !name.exist()) - { - name = get_xml_src(); - name.add(xml_filename); - name.ext("xml"); - } - return get_tmp_string() << name; -} - bool vis_xml_handler(TMask_field& f, KEY key) { if (key == K_SPACE) @@ -3851,136 +3924,16 @@ bool vis_pdf_handler(TMask_field& f, KEY key) return true; } -#define MAX_SIZE 4096 - -HIDDEN int get_resp_prop(const char * prop, TString & val, const TString & response, int startpos = 0) -{ - val.cut(0); - int pos = response.find(prop); - int stop = 0; - - if (pos > 0) - { - pos += 2; - stop = response.find("\"", pos); - if (stop > 0) - stop--; - val = response.smid(pos, stop - pos); - } - return stop; -} - bool check_sdi_handler(TMask_field& f, KEY key) { if (key == K_SPACE) { TDocumento_mask& mask = (TDocumento_mask &)f.mask(); - TString4 tipo = get_fp_string_var(FP_TIPO_CHECK); - if (tipo == "F") - { - const char * server = "fex-app.com"; - TFilename xml_name = get_xml_filename(true, mask.get_int(F_ANNO), mask.get(F_XML_NAME)); - TString content; - - content << '{' << '\n' << "\"call\" : \"fexApi.errorsCount\"," << '\n' << "\"apiPars\" : {" << '\n'; - content << "\"sessid\" : \"" << get_fp_string_var(FP_SESSION_ID) << "\",\n"; - content << "\"xml\" : \""; - - ifstream i(xml_name); - TXmlItem xml; - char buf[MAX_SIZE + 1]; - TString line; - - while (!i.eof()) - { - i.read(buf, MAX_SIZE); - buf[i.gcount()] = '\0'; - - TString line = buf; - - line.strip("\n"); - content << unquote(line); - } - content << "\"" << "\n}\n}\n"; - - size_t length; - char * answer; - - if (http_post(server, "/api/def", content, answer, length, 2, 443, true, CONTENT_JSON)) - { - TString result; - - for (int i = 0; i < (int)length; i++) - result << answer[i]; - TString val; - int pos = get_resp_prop("block", val, result); - - int block_errors = atoi(val); - - pos = get_resp_prop("reservedSessid", val, result, pos); - - TString sess_id = val; - - pos = get_resp_prop("reqWas", val, result, pos); - if (val == "fexApi.errorsCount") - { - if (block_errors == 0) - { - mask.doc().put(DOC_STATO_SDI, "D"); - mask.set(F_STATO_SDI, "D"); - } - TString res_page = "https://"; - TFilename http; - - http.temp(); - res_page << "/fex-app.com/servizi/inizia?sessid=" << sess_id << "&auth=" << get_fp_string_var(FP_SESSION_ID); - - if (http_get(server, res_page, http)) - { - TFilename out = get_check_dest(mask.doc().get_int(DOC_ANNO)); - - out.add(xml_name.name_only()); - out.ext("pdf"); - html2pdf(http, out); - goto_url(out); - } - } - } - } - else - { - TString str = get_fp_string_var(FP_CHECK_APP); - TString command = str; - int p = str.find(""); - - if (p > 0) - { - int anno = mask.get_int(F_ANNO); - TFilename file = get_xml_dest(true, anno); - - file.add(mask.get(F_XML_NAME)); - file.ext("xml"); - command = str.sleft(p); - if (command[command.len() - 1] != ' ') - command << " "; - command << file; - if (p + 6 < str.len()) - { - if (command[command.len() - 1] != ' ') - command << " "; - command << str.smid(p + 7); - } - } - if (command.starts_with("http")) - goto_url(command); - else - { - TExternal_app check(command); - - int res = check.run(); - } - } + if (mask.doc().get(DOC_STATO_SDI).full() && + mask.doc().check() && mask.doc().get(DOC_STATO_SDI) != "I" && + mask.doc().tipo().vendite()) + mask.set(F_STATO_SDI, "D"); } return true; } @@ -4072,4 +4025,4 @@ bool copy_conto_handler(TMask_field& f, KEY key) } } return true; -} \ No newline at end of file +} diff --git a/src/ve01/velib08.cpp b/src/ve01/velib08.cpp index b7edd4867..964d45aec 100644 --- a/src/ve01/velib08.cpp +++ b/src/ve01/velib08.cpp @@ -1,7 +1,9 @@ #include #include #include +#include #include +#include #include #include @@ -883,7 +885,38 @@ bool TDocumento::add_riferimenti(TXmlItem & dati_generali) const TString16 cup = get(DOC_CUP); const TString16 cig = get(DOC_CIG); TBit_array ddt_linee; + TString80 con = get(DOC_CONTRATTO); + char tcon = get_char(DOC_MODPAG); + + if (tcon < 'C') tcon = 'C'; + + TDate datadoc; // Data contratto non obbligatoria + + // Codice commessa, spostato nel campo S5 di TABCOM + com = cco().get("S5"); + descr = cco().get("S0"); + + if (com.full()) + com.insert("Commessa "); + if (com.full() && descr.full()) + com << " - "; + com << descr; + + // Se una commessa della sanità bisogna aggiungere un cancelletto davanti e dietro + if (cco().get_bool("B0")) + { + com.add_front_and_back("#"); + } + if (con.full()) + datadoc = cco().get_date("D0"); + else + { + // IdDocumento obbligatorio + con = cig; + if (con.blank()) + con = cup; + } if (is_pa && cup.blank() && cig.blank()) get_xml_log()->log(1, "CIG e CUP assenti"); @@ -922,60 +955,26 @@ bool TDocumento::add_riferimenti(TXmlItem & dati_generali) const TRectype & doc = cache().get(LF_DOC, rif); - set_blocco_rif(rifsarr, pos, 0, rif, get_date(DOC_DATADOCRIF), "", "", cup, cig, doc); + set_blocco_rif(rifsarr, pos, 0, rif, get_date(DOC_DATADOCRIF), "", com, cup, cig, *this); } } - TString80 con = get(DOC_CONTRATTO); - if (con.full() || cup.full() || cig.full()) { - char tcon = get_char(DOC_MODPAG); - TRectype doc(LF_DOC); - - if (tcon < 'C') tcon = 'C'; - - TDate datadoc; // Data contratto non obbligatoria - - // Codice commessa, spostato nel campo S5 di TABCOM - com = cco().get("S5"); - descr = cco().get("S0"); - - if (com.full()) - com.insert("Commessa "); - if (com.full() && descr.full()) - com << " - "; - com << descr; - - // Se una commessa della sanità bisogna aggiungere un cancelletto davanti e dietro - if (cco().get_bool("B0")) - { - com.add_front_and_back("#"); - } - if (con.full()) - datadoc = cco().get_date("D0"); - else - { - // IdDocumento obbligatorio - con = cig; - if (con.blank()) - con = cup; - } - if (tcon == 'O') - set_blocco_rif(rifsarr, POS_ORDINE, 0, con, datadoc, "", com, cup, cig, doc); + set_blocco_rif(rifsarr, POS_ORDINE, 0, con, datadoc, "", com, cup, cig, *this); else if (tcon == 'C') - set_blocco_rif(rifsarr, POS_CONTRATTO, 0, con, datadoc, "", com, cup, cig, doc); + set_blocco_rif(rifsarr, POS_CONTRATTO, 0, con, datadoc, "", com, cup, cig, *this); else - if (tcon == 'V') - set_blocco_rif(rifsarr, POS_CONVENZIONE, 0, con, datadoc, "", com, cup, cig, doc); + if (tcon == 'V' && get(DOC_NUMDOCRIF).blank()) + set_blocco_rif(rifsarr, POS_CONVENZIONE, 0, con, datadoc, "", com, cup, cig, *this); else if (tcon == 'R') - set_blocco_rif(rifsarr, POS_RICEZIONE, 0, con, datadoc, "", com, cup, cig, doc); + set_blocco_rif(rifsarr, POS_RICEZIONE, 0, con, datadoc, "", com, cup, cig, *this); else if (tcon == 'F') - set_blocco_rif(rifsarr, POS_FATTURE, 0, con, datadoc, "", com, cup, cig, doc); + set_blocco_rif(rifsarr, POS_FATTURE, 0, con, datadoc, "", com, cup, cig, *this); } long riga = 1; @@ -987,57 +986,60 @@ bool TDocumento::add_riferimenti(TXmlItem & dati_generali) int numlinea = 1; { - // * Ogni riga si pu rifare a un DDT / Ordine diverso, per questo devo inserire i dati da qua e non in testata -// TArray row_ancestors; - TAssoc_array ancestors; - bool first_row = false; - - FOR_EACH_SELF_PHYSICAL_RDOC(r, rdoc) + if (!riftesta || get(DOC_NOTE).blank()) { - find_ancestors(*rdoc, ancestors, false); - if (riga_buoni_cons.empty() && rdoc->get(RDOC_DESCR).starts_with("Buono di consegna")) - { - riga_buoni_cons << rdoc->get(RDOC_DESCR); - if (rdoc->get_bool(RDOC_DESCLUNGA)) - riga_buoni_cons << rdoc->get(RDOC_DESCEST); - first_row = (r == 0); - } - } - if (ancestors.items() > 0) - { - TString_array keys; + // * Ogni riga si pu rifare a un DDT / Ordine diverso, per questo devo inserire i dati da qua e non in testata + // TArray row_ancestors; + TAssoc_array ancestors; + bool first_row = false; - ancestors.get_keys(keys); - keys.sort(); - FOR_EACH_ARRAY_ROW(keys, r, key) + FOR_EACH_SELF_PHYSICAL_RDOC(r, rdoc) { - TRif_Doc & a = (TRif_Doc &) ancestors[*key]; - const TTipo_documento & tipo = cached_tipodoc(a.tipodoc()); - - if (tipo.tipo() == _bolla) + find_ancestors(*rdoc, ancestors, false); + if (riga_buoni_cons.empty() && rdoc->get(RDOC_DESCR).starts_with("Buono di consegna")) { - set_blocco_DDT(rifsarr, a.numdoc(), TDate(a.datadoc()), a.numlinea(), a.doc()); - has_bolla = true; - ddt_linee.set(r); + riga_buoni_cons << rdoc->get(RDOC_DESCR); + if (rdoc->get_bool(RDOC_DESCLUNGA)) + riga_buoni_cons << rdoc->get(RDOC_DESCEST); + first_row = (r == 0); } - else - { - int pos; + } + if (ancestors.items() > 0) + { + TString_array keys; - switch (tipo.tipo()) + ancestors.get_keys(keys); + keys.sort(); + FOR_EACH_ARRAY_ROW(keys, r, key) + { + TRif_Doc & a = (TRif_Doc &)ancestors[*key]; + const TTipo_documento & tipo = cached_tipodoc(a.tipodoc()); + + if (tipo.tipo() == _bolla) { - case _fattura: - case _scontrino: - pos = POS_FATTURE; - break; - case _ordine: - pos = POS_ORDINE; - break; - default: - pos = POS_CONTRATTO; - break; + set_blocco_DDT(rifsarr, a.numdoc(), TDate(a.datadoc()), a.numlinea(), a.doc()); + has_bolla = true; + ddt_linee.set(r); + } + else + { + int pos; + + switch (tipo.tipo()) + { + case _fattura: + case _scontrino: + pos = POS_FATTURE; + break; + case _ordine: + pos = POS_ORDINE; + break; + default: + pos = POS_CONTRATTO; + break; + } + set_blocco_rif(rifsarr, pos, a.numlinea(), a.numdoc(), a.datadoc(), "", com, cup, cig, a.doc()); } - set_blocco_rif(rifsarr, pos, a.numlinea(), a.numdoc(), a.datadoc(), "", com, cup, cig, a.doc()); } } } @@ -2072,39 +2074,44 @@ bool TDocumento::get_bank_presentazione(TString& iban, TString& abi, TString& ca abi = get(DOC_CODABIP); cab = get(DOC_CODCABP); int prg = get_int(DOC_PROGBNP); - bool found = abi.full() && cab.full(); + iban = get(DOC_IBAN); + istituto = cache().get("%BAN", abi, "S0"); + bool found = true; - if (found) - get_bnp_iban(abi, cab, prg, iban); - else // Se non trovo banca sul DOC la cerco su CFBAN + if (iban.blank()) { - TToken_string key; - key.add("C"); - key.add(codcf()); - key.add("N"); - key.add(1); - const TRectype& cfban = cache().get(LF_CFBAN, key); - if (!cfban.empty()) + found = abi.full() && cab.full(); + + if (found) + get_bnp_iban(abi, cab, prg, iban); + else // Se non trovo banca sul DOC la cerco su CFBAN { - abi = cfban.get(CFBAN_ABI); - cab = cfban.get(CFBAN_CAB); + TToken_string key; + key.add("C"); + key.add(codcf()); + key.add("N"); + key.add(1); + const TRectype& cfban = cache().get(LF_CFBAN, key); + if (!cfban.empty()) + { + abi = cfban.get(CFBAN_ABI); + cab = cfban.get(CFBAN_CAB); + found = abi.full() && cab.full(); + iban = cfban.get(CFBAN_IBAN); + if (found && iban.blank()) + get_bnp_iban(abi, cab, -1, iban); + } + } + if (!found) // Se non trovo banca su CFBAN la cerco su CFVEN + { + const TRectype& cfven = clifor().vendite(); + abi = cfven.get(CFV_CODABIPR); + cab = cfven.get(CFV_CODCABPR); found = abi.full() && cab.full(); - iban = cfban.get(CFBAN_IBAN); - if (found && iban.blank()) - get_bnp_iban(abi, cab, -1, iban); + if (found) + get_bnp_iban(abi, cab, 0, iban); } } - if (!found) // Se non trovo banca su CFBAN la cerco su CFVEN - { - const TRectype& cfven = clifor().vendite(); - abi = cfven.get(CFV_CODABIPR); - cab = cfven.get(CFV_CODCABPR); - found = abi.full() && cab.full(); - if (found) - get_bnp_iban(abi, cab, 0, iban); - } - if (found) - istituto = cache().get("%BAN", abi, "S0"); return found; } @@ -2170,8 +2177,11 @@ bool TDocumento::add_pagamento(TXmlItem & body) if ((pag.data_rata(nr) - decorrenza_pagamento) != giorni) giorni = pag.data_rata(nr) - decorrenza_pagamento; - dett.AddEnclosedDateISO8601Full("DataRiferimentoTerminiPagamento", decorrenza_pagamento); - dett.AddEnclosedIntFull("GiorniTerminiPagamento", giorni); + if (!get_fp_bool_var(FP_RIF_PAG)) + { + dett.AddEnclosedDateISO8601Full("DataRiferimentoTerminiPagamento", decorrenza_pagamento); + dett.AddEnclosedIntFull("GiorniTerminiPagamento", giorni); + } dett.AddEnclosedDateISO8601Full("DataScadenzaPagamento", riga_scadenze.get_date(0)); // Data scadenza dett.AddEnclosedValue("ImportoPagamento", riga_scadenze.get_real()); // Importo rata @@ -2243,27 +2253,36 @@ bool TDocumento::add_allegati(TXmlItem & body) if (get_fp_bool_var(FP_ALLEG_FAT)) { - if (!tipo().main_print_profile(rep, 2)) - get_xml_log()->log(1, "Impossibile generare la fattura, non disponibile un profilo di stampa per questo tipo documento!"); + if (!dongle().active(RSAUT)) + get_xml_log()->log(1, "Impossibile generare la fattura, il modulo RS non abilitato!"); else - { - //ve1 -2 {CODNUM} {ANNO} {PROVV} {NDOC}(-{ANDOC}) {TIPO_ELABORAZIONE} {TIPO_STAMPA} {NUM_COPIE} {ARCHIVIAZIONE} - // Costruisco la chiamata + if (!tipo().main_print_profile(rep, 2)) + get_xml_log()->log(1, "Impossibile generare la fattura, non disponibile un profilo di stampa per questo tipo documento!"); + else + { + //ve1 -2 {CODNUM} {ANNO} {PROVV} {NDOC}(-{ANDOC}) {TIPO_ELABORAZIONE} {TIPO_STAMPA} {NUM_COPIE} {ARCHIVIAZIONE} + // Costruisco la chiamata TString commandline = "ve011 -2 "; - commandline << get(DOC_CODNUM) << ' ' << get(DOC_ANNO) << ' ' << get(DOC_PROVV) << ' ' << get(DOC_NDOC) << " X P 1 D"; // X: stampa su disco, P: provvisorio, 1: 1 copia, D: non archivia + commandline << get(DOC_CODNUM) << ' ' << get(DOC_ANNO) << ' ' << get(DOC_PROVV) << ' ' << get(DOC_NDOC) << " X P 1 D"; // X: stampa su disco, P: provvisorio, 1: 1 copia, D: disabilita archiviazione - TExternal_app interattivo(commandline); + TExternal_app interattivo(commandline); - interattivo.run(); - - TFilename pdf; pdf.tempdir(); - - pdf << SLASH << get(DOC_ANNO) << '_' << get(DOC_CODNUM) << '_' << get(DOC_NDOC) << ".pdf"; - if (!pdf.exist() && !yesno_box("Attenzione! Non stato possibile creare il pdf, continuare?")) - return false; - add_allegato(body, pdf, "Fattura di cortesia"); - } + if (interattivo.run() != NOERR) + { + TString msgerr = "Fallita generazione PDF documento "; + msgerr << get(DOC_CODNUM) << ' ' << get(DOC_ANNO) << ' ' << get(DOC_PROVV) << ' ' << get(DOC_NDOC); + error_box(msgerr); + } + else + { + TFilename pdf; pdf.tempdir(); + pdf << SLASH << get(DOC_ANNO) << '_' << get(DOC_CODNUM) << '_' << get(DOC_NDOC) << ".pdf"; + if (!pdf.exist() && !yesno_box("Attenzione! Non stato possibile creare il pdf, continuare?")) + return false; + add_allegato(body, pdf, "Fattura di cortesia"); + } + } } TToken_string allegati(get(DOC_CARTACEI), '\n'); @@ -2484,6 +2503,146 @@ bool TDocumento::generate_xml(TLog_report * log) return false; } +#define MAX_SIZE 4096 + +TString & get_xml_filename(bool ven, int anno, const char * xml_filename) +{ + TFilename name; + + name = get_xml_dest(ven, anno); + name.add(xml_filename); + name.ext("xml"); + if (!ven && !name.exist()) + { + name = get_xml_src(); + name.add(xml_filename); + name.ext("xml"); + } + return get_tmp_string() << name; +} + +HIDDEN int get_resp_prop(const char * prop, TString & val, const TString & response, int startpos = 0) +{ + val.cut(0); + int pos = response.find(prop, startpos); + int stop = 0; + + if (pos > 0) + { + pos = response.find("\"", pos) + 1; + pos = response.find("\"", pos) + 1; + stop = response.find("\"", pos); + + val = response.smid(pos, stop - pos); + } + return stop; +} + +bool TDocumento::check() +{ + bool ok = false; + + if (get(DOC_STATO_SDI).full()) + { + const TString& tipocheck = get_fp_string_var(FP_TIPO_CHECK); + + if (tipocheck == "F") + { + bool acquisto = tipo().acquisti(); + TFilename xml_name = get_xml_filename(tipo().vendite(), get_int(DOC_ANNO), get(DOC_XML_NAME)); + TString content; + TString answer; + if (acquisto && !xml_name.exist()) + { + xml_name = get_xml_filename(tipo().vendite(), 0, get(DOC_XML_NAME)); + if (!xml_name.exist()) + return error_box("File XML mancante"); + } + content << '{' << '\n' << "\"call\" : \"fexApi.errorsCount\"," << '\n' << "\"apiPars\" : {" << '\n'; + content << "\"sessid\" : \"" << get_fp_string_var(FP_SESSION_ID) << "\",\n"; + content << "\"xml\" : \""; + + int size = fsize(xml_name); + char * enc = new char[2 * size + 1]; + TFilename temp; + + temp.temp(); + + ofstream out(temp); + + xvt_str_base64_encode(xml_name, enc); + content << enc << "\"" << "\n}\n}\n"; + delete enc; + out << content; + out.close(); + content = "@"; + content << temp; + if (http_curl_post("https://fex-app.com", "/api/def", media_json, content, answer)) + { + TString val; + int pos = get_resp_prop("block", val, answer); + + int block_errors = atoi(val); + + pos = get_resp_prop("reservedSessid", val, answer, pos); + + TString sess_id = val; + + pos = get_resp_prop("reqWas", val, answer, pos); + if (val == "fexApi.errorsCount") + { + if (tipo().vendite() && block_errors == 0 && get(DOC_STATO_SDI) != "I") + put(DOC_STATO_SDI, "D"); + + TString http = "https:/fex-app.com/servizi/inizia?sessid="; + + http << sess_id << "&auth=" << get_fp_string_var(FP_SESSION_ID); + goto_url(http); + ok = true; + } + } + remove_file(temp); + } + else + { + TString str = get_fp_string_var(FP_CHECK_APP); + TString command = str; + int p = str.find(""); + + if (p > 0) + { + TFilename xml_name = get_xml_filename(true, get_int(DOC_ANNO), get(DOC_XML_NAME)); + + command = str.sleft(p); + if (command[command.len() - 1] != ' ') + command << " "; + command << xml_name; + if (p + 6 < str.len()) + { + if (command[command.len() - 1] != ' ') + command << " "; + command << str.smid(p + 7); + } + } + if (command.starts_with("http")) + { + goto_url(command); + ok = true; + } + else + { + TExternal_app check(command); + + int res = check.run(); + ok = res == 0; + } + if (tipo().vendite() && ok && get(DOC_STATO_SDI) != "I") + put(DOC_STATO_SDI, "D"); + } + } + return ok; +} + bool TDocumento::send_xml() { TString stato(get(DOC_STATO_SDI)); @@ -2509,7 +2668,7 @@ bool TDocumento::send_xml() return error_box(TR("La cartella di invio non esiste")); xml_dest.add(fname); xml_dest.ext("xml"); - if (!fcopy(filename, xml_dest)) + if (!fcopy(filename, xml_dest, false, true)) return error_box(TR("Invio fallito")); put(DOC_STATO_SDI, "I"); rewrite(); @@ -2519,6 +2678,7 @@ bool TDocumento::send_xml() bool TDocumento::get_dati_tras(TXmlItem & header) { TXmlItem * dati_trasmissione = header.FindFirstChild("DatiTrasmissione"); + if (dati_trasmissione != nullptr) { TXmlItem * id_trasmittente = dati_trasmissione->FindFirstChild("IdTrasmittente"); @@ -2529,7 +2689,7 @@ bool TDocumento::get_dati_tras(TXmlItem & header) put(DOC_PIVA_TR, id_trasmittente->GetEnclosedText("IdCodice")); } put(DOC_PRG_INV_TR, dati_trasmissione->GetEnclosedText("ProgressivoInvio")); - + _tipo_trasmissione = dati_trasmissione->GetEnclosedText("FormatoTrasmissione"); } else { @@ -2563,7 +2723,7 @@ bool TDocumento::get_cedente(TXmlItem & header) if (c != nullptr) { TXmlItem & cedente = *c; - TXmlItem * dati_anagr = cedente.FindFirstChild("DatiAnagrafici"); + TXmlItem * dati_anagr = fattura_ordinaria() ? cedente.FindFirstChild("DatiAnagrafici") : c; if (dati_anagr != nullptr) { @@ -2578,7 +2738,7 @@ bool TDocumento::get_cedente(TXmlItem & header) } cf = dati_anagr->GetEnclosedText("CodiceFiscale"); - TXmlItem * anagr = dati_anagr->FindFirstChild("Anagrafica"); + TXmlItem * anagr = fattura_ordinaria() ? dati_anagr->FindFirstChild("Anagrafica") : c; if (anagr != nullptr) { @@ -2801,7 +2961,8 @@ bool TDocumento::get_cessionario(TXmlItem & header, TXmlItem & root) TString stato_att = ditta.stato_partita_IVA(); TString paiva_att = ditta.partita_IVA(); - TXmlItem * dati_anagr = cessionario->FindFirstChild("DatiAnagrafici"); + TXmlItem * dati_anagr = fattura_ordinaria() ? cessionario->FindFirstChild("DatiAnagrafici") : + cessionario->FindFirstChild("IdentificativiFiscali"); if (dati_anagr != nullptr) { TXmlItem * id_fisc = dati_anagr->FindFirstChild("IdFiscaleIVA"); @@ -3137,6 +3298,11 @@ bool TDocumento::get_dati_generali(TXmlItem & dati_generali, real & totale_imp) return true; } +HIDDEN bool is_natura_revcharge(const TString & natura) +{ + return natura == "N3.2" || natura == "N3.3" || natura == "N3.4" || natura.starts_with("N6"); +} + const char * TDocumento::find_codIVA(real aliquota, TString & natura) { TToken_string ive = get_tmp_string(); @@ -3154,7 +3320,7 @@ const char * TDocumento::find_codIVA(real aliquota, TString & natura) __iva_loaded = true; } - if (tipo_doc_is_reverse()) + if (tipo_doc_is_reverse() && is_natura_revcharge(natura)) { static real __aliprev = ZERO; @@ -3402,7 +3568,7 @@ bool TDocumento::get_riga(TXmlItem & riga, bool newdoc, bool & first, TXmlItem * real qta = riga.GetEnclosedReal("Quantita"); if (sconto != nullptr) - tipocess = riga.GetEnclosedText("Tipo"); // SC=sconto AB=abbuono PR=Premio AC=Spese accessorie + tipocess = sconto->GetEnclosedText("Tipo"); // SC=sconto AB=abbuono PR=Premio AC=Spese accessorie if (tipocess == "AC") { if (qta == UNO || qta == ZERO) @@ -3469,21 +3635,25 @@ bool TDocumento::get_riga(TXmlItem & riga, bool newdoc, bool & first, TXmlItem * } if (sconto != nullptr && rows() > 0) { - nriga = rows(); - row(nriga).sub(RDOC_PREZZO, importo); + nriga = physical_rows(); + + TRiga_documento & rdoc = row(nriga); + if (scontop != ZERO) { - TString sconto = row(nriga).get(RDOC_SCONTO); + TString sconto = rdoc.get(RDOC_SCONTO); if (sconto.full() && scontop > ZERO) sconto << "+"; sconto << scontop.stringa(); - row(nriga).put(RDOC_SCONTO, sconto); + rdoc.put(RDOC_SCONTO, sconto); } + else + rdoc.sub(RDOC_PREZZO, importo); + if (rdoc.is_sconto()) + rdoc.set_tipo("01"); return true; } - else - qta = UNO; } TString8 tiporiga = (TString &) __cessione2riga[tipocess]; @@ -3511,6 +3681,7 @@ bool TDocumento::get_riga(TXmlItem & riga, bool newdoc, bool & first, TXmlItem * TRiga_documento & rigadescr = new_row("05"); rigadescr.put(RDOC_DESCR, "Righe aggiunte da xml"); + first = false; } TRiga_documento & rigadoc = nriga < 0 ? new_row(tiporiga) : row(nriga); @@ -3635,10 +3806,8 @@ bool TDocumento::get_riga(TXmlItem & riga, bool newdoc, bool & first, TXmlItem * if (tipo_doc_is_reverse()) { const TCodiceIVA & iva = cached_codIVA(codiva); - - if (iva.natura() == "N3.2" || iva.natura() == "N3.3" || - iva.natura() == "N3.4" || iva.natura().starts_with("N6")) - rigadoc.put(RDOC_REVCHARGE, true); + + rigadoc.put(RDOC_REVCHARGE, is_natura_revcharge(iva.natura())); } TBill conto; @@ -3672,6 +3841,138 @@ bool TDocumento::get_riga(TXmlItem & riga, bool newdoc, bool & first, TXmlItem * return true; } +bool TDocumento::get_riga_semplificata(TXmlItem & riga, bool newdoc, bool & first) +{ + TString descrizione = riga.GetEnclosedText("Descrizione"); + + if (descrizione.starts_with("Buono di consegna") || descrizione.starts_with("Stampa priva di valenza")) + return true; + + real qta = UNO; + TString um = get_fp_string_var(FP_UMDEFAULT); + + real prezzo = riga.GetEnclosedReal("Importo"); + + TXmlItem * iva = riga.FindFirstChild("DatiIVA"); + real aliquota; + TString natura = riga.GetEnclosedText("Natura"); + + if (iva != nullptr) + { + real imposta = iva->GetEnclosedReal("Imposta"); + + aliquota = iva->GetEnclosedReal("Aliquota"); + if (aliquota == ZERO && imposta != ZERO) + { + aliquota = imposta / (prezzo - imposta); + aliquota.round(2); + } + } + + if (!nuovo() && first) + { + TRiga_documento & rigadescr = new_row("05"); + + rigadescr.put(RDOC_DESCR, "Righe aggiunte da xml"); + } + + TRiga_documento & rigadoc = new_row("01"); + + if (descrizione.len() <= 50) + rigadoc.put(RDOC_DESCR, descrizione); + else + { + rigadoc.put(RDOC_DESCR, descrizione.sleft(50)); + rigadoc.put(RDOC_DESCLUNGA, true); + rigadoc.put(RDOC_DESCEST, descrizione.smid(50)); + } + rigadoc.put(RDOC_QTA, qta); + if (!rigadoc.is_descrizione() && um.blank()) + um = get_fp_string_var(FP_UMDEFAULT); + rigadoc.put(RDOC_UMQTA, um); + + if (in_valuta()) + { + TCurrency importoval(prezzo, TCurrency::get_firm_val(), UNO); + + importoval.change_value(get(DOC_CODVAL), get_real(DOC_CAMBIO)); + prezzo = importoval.get_num(); + } + + TString codiva = rigadoc.get(RDOC_CODIVA); + const TCodiceIVA & i = cached_codIVA(codiva); + + if (codiva.blank() || aliquota != real(i.aliquota()) || natura != i.natura()) + { + TToken_string ive = find_codIVA(aliquota, natura); + + if (ive.blank()) + { + TString msg = "Il codice IVA con aliquota "; + + msg << aliquota << " o natura " << natura << " non esiste, devo crearlo o cercarlo"; + if (yesno_box(msg)) + { + TTable i("%IVA"); + TRectype &iva = i.curr(); + + if (iva.edit(LF_TABCOM, ive)) + codiva = iva.get("CODTAB"); + else + { + TString msg1 = "Non trovo un codice IVA con aliquota "; + msg1 << aliquota.stringa() << " e natura " << (const char *)natura; + get_xml_log()->log(2, msg1); + } + } + } + else + { + if (get_fp_bool_var(FP_ADVIMP)) + { + TTable i("%IVA"); + TRectype &iva = i.curr(); + + if (iva.select(LF_TABCOM, ive)) + codiva = iva.get("CODTAB"); + } + if (codiva.blank()) + codiva = ive.get(); + } + } + rigadoc.put(RDOC_CODIVA, codiva); + const TCodiceIVA & i2 = cached_codIVA(codiva); + + i2.scorpora(prezzo); + rigadoc.put(RDOC_PREZZO, prezzo); + if (tipo_doc_is_reverse()) + rigadoc.put(RDOC_REVCHARGE, is_natura_revcharge(i2.natura())); + + TBill conto; + + conto.set(clifor().get_int(CLI_GRUPPORIC), clifor().get_int(CLI_CONTORIC), clifor().get_long(CLI_SOTTOCRIC)); + if (!conto.ok()) + { + const TString8 & codcaus = tipo().causale(); + + if (codcaus.full()) + { + const TCausale & caus = cached_causale(codcaus); + TBill conto_caus; + + caus.bill(RIGA_COSTO_RICAVO, conto); + conto = conto_caus; + } + } + if (conto.ok()) + { + rigadoc.put(RDOC_GRUPPO, conto.gruppo()); + rigadoc.put(RDOC_CONTO, conto.conto()); + rigadoc.put(RDOC_SOTTOCONTO, conto.sottoconto()); + } + return true; +} + bool TDocumento::get_righeIVA(TAssoc_array & riepilogoIVA) { FOR_EACH_ASSOC_OBJECT(riepilogoIVA, obj, key, item) @@ -3697,7 +3998,48 @@ bool TDocumento::get_righeIVA(TAssoc_array & riepilogoIVA) return rows() > 0; } -bool TDocumento::get_dettaglio(TXmlItem & corpo, bool newdoc, TAssoc_array & riepilogoIVA) +bool TDocumento::get_arrotondamento(TAssoc_array & arrotondamenti) +{ + FOR_EACH_ASSOC_OBJECT(arrotondamenti, obj, key, item) + { + TToken_string keyIVA = key; + real & arrotondamento = (real &)*item; + real aliquota = keyIVA.get_real(); + TString4 natura = keyIVA.get(); + TToken_string ive = find_codIVA(aliquota, natura); + const bool storna = false; // clifor().vendite().get_bool(CFV_STOARROT); + + if (ive.items() > 0) + { + TRiga_documento & row = new_row("01"); + TCodiceIVA c = cached_codIVA(ive.get()); + TString descr = "Arrotondamento IVA "; + + descr << c.descrizione(); + row.put(RDOC_DESCR, descr); + row.put(RDOC_CODIVA, c.codice()); + row.put(RDOC_UMQTA, get_fp_string_var(FP_UMDEFAULT)); + row.put(RDOC_QTA, UNO); + row.put(RDOC_PREZZO, arrotondamento); + if (storna) + { + TRiga_documento & row = new_row("01"); + const TCodiceIVA & iva_storno = cached_codIVA(ini_get_string(CONFIG_DITTA, "VE", "IVASTO")); + TString descr = "Storno arrotondamento IVA "; + + descr << c.descrizione(); + row.put(RDOC_DESCR, descr); + row.put(RDOC_CODIVA, iva_storno.codice()); + row.put(RDOC_UMQTA, get_fp_string_var(FP_UMDEFAULT)); + row.put(RDOC_QTA, UNO); + row.put(RDOC_PREZZO, -arrotondamento); + } + } + } + return rows() > 0; +} + +bool TDocumento::get_dettaglio(TXmlItem & corpo, bool newdoc, TAssoc_array & riepilogoIVA, TAssoc_array & arrotondamenti) { bool first = true; int last = 0; @@ -3708,14 +4050,35 @@ bool TDocumento::get_dettaglio(TXmlItem & corpo, bool newdoc, TAssoc_array & rie return false; int lastsco = 0; - + for (TXmlItem * sconto = riga->FindChild("ScontoMaggiorazione", lastsco); sconto != nullptr; sconto = riga->FindChild("ScontoMaggiorazione", lastsco)) - if (!get_riga(*sconto, newdoc, first, sconto)) + { + if (!get_riga(*riga, newdoc, first, sconto)) return false; + // if (clifor().vendite().get_bool(CFV_AZZSCOTES)) + // zero(DOC_SCONTOPERC); + } } + bool ok = true; + if (rows() == 0) - return get_righeIVA(riepilogoIVA); + ok = get_righeIVA(riepilogoIVA); + if (ok) + ok = get_arrotondamento(arrotondamenti); + return true; +} + +bool TDocumento::get_dettaglio_semplificata(TXmlItem & corpo, bool newdoc) +{ + bool first = true; + int last = 1; + + for (TXmlItem * riga = corpo.FindFirstChild("DatiBeniServizi"); riga != nullptr; riga = corpo.FindChild("DatiBeniServizi", last)) + { + if (!get_riga_semplificata(*riga, newdoc, first)) + return false; + } return true; } @@ -3867,29 +4230,49 @@ bool TDocumento::get_xml_body(TXmlItem & root, real & totale_imp, bool newdoc) { TXmlItem * corpo = body->FindFirstChild("DatiBeniServizi"); - if (corpo != nullptr) + if (fattura_ordinaria()) { - TAssoc_array riepilogoIVA; - int last = 0; - - for (TXmlItem * riepilogo = corpo->FindChild("DatiRiepilogo", last); riepilogo != nullptr; riepilogo = corpo->FindChild("DatiRiepilogo", last)) + if (corpo != nullptr) { - real imponibile = riepilogo->GetEnclosedReal("ImponibileImporto"); - TToken_string aliquota; - - aliquota.add(riepilogo->GetEnclosedReal("AliquotaIVA")); - - aliquota.add(riepilogo->GetEnclosedText("Natura")); - riepilogoIVA.add(aliquota, imponibile); + TAssoc_array riepilogoIVA; + TAssoc_array arrotondamenti; + int last = 0; + + for (TXmlItem * riepilogo = corpo->FindChild("DatiRiepilogo", last); riepilogo != nullptr; riepilogo = corpo->FindChild("DatiRiepilogo", last)) + { + const real imponibile = riepilogo->GetEnclosedReal("ImponibileImporto"); + const real arrotondamento = riepilogo->GetEnclosedReal("Arrotondamento"); + TToken_string aliquota; + + aliquota.add(riepilogo->GetEnclosedReal("AliquotaIVA")); + + aliquota.add(riepilogo->GetEnclosedText("Natura")); + riepilogoIVA.add(aliquota, imponibile); + if (arrotondamento != ZERO) + arrotondamenti.add(aliquota, arrotondamento); + } + if (get_dati_generali(*dati_generali, totale_imp) && get_pagamento(*body) && + get_dettaglio(*corpo, newdoc, riepilogoIVA, arrotondamenti) && get_allegati(*body)) + return true; + } + else + { + get_xml_log()->log(2, TR("Manca il corpo")); + return false; } - if (get_dati_generali(*dati_generali, totale_imp) && get_pagamento(*body) && - get_dettaglio(*corpo, newdoc, riepilogoIVA) && get_allegati(*body)) - return true; } else { - get_xml_log()->log(2, TR("Manca il corpo")); - return false; + if (corpo != nullptr) + { + if (get_dati_generali(*dati_generali, totale_imp) && get_dettaglio_semplificata(*body, newdoc) && get_allegati(*body)) + return true; + } + else + { + get_xml_log()->log(2, TR("Manca il corpo")); + return false; + } } } else @@ -3933,4 +4316,4 @@ bool TDocumento::import_xml(TFilename & xmlname, TLog_report * log) delete_xml_log(); } return ok; -} \ No newline at end of file +} diff --git a/src/ve01/vepriv.h b/src/ve01/vepriv.h index 951714b02..1725db8fd 100644 --- a/src/ve01/vepriv.h +++ b/src/ve01/vepriv.h @@ -64,8 +64,6 @@ bool check_acquisti_handler(TMask_field& f, KEY key); bool copy_conto_handler(TMask_field& f, KEY key); bool is_tipodoc_ok(const TString & tipodoc); -TString & get_xml_filename(bool ven, int anno, const char * xml_filename); - short conai_peso_id(int cc); short conai_sottocat_id(int cc);