diff --git a/src/ve/ve0100.cpp b/src/ve/ve0100.cpp index 61b05d508..f176810f1 100755 --- a/src/ve/ve0100.cpp +++ b/src/ve/ve0100.cpp @@ -4,10 +4,10 @@ #include #include #include +#include #include #include #include "../li/lilib01.h" - #include "ve0100.h" #include "veini.h" @@ -16,9 +16,13 @@ #include "verig.h" #include "velib04.h" #include "../mg/mglib.h" +#include "../li/lilib01.h" #include "sconti.h" #include +#include "../mg/anamag.h" + +#include "../cg/cfban.h" TCursor* TMotore_application::get_filtered_cursor() const { @@ -153,13 +157,18 @@ void TMotore_application::init_insert_mode( TMask& m ) m.set(F_STATO, str_stato); TDate data_doc(TODAY); - const bool magic_datadoc = m.field(F_DATADOC).automagic(); - if (!magic_datadoc) - { - long ndoc = 0; // unused - last_doc(provv, anno, codnum, ndoc, data_doc); - } - m.set(F_DATADOC, data_doc, 0x1); + const bool permanent = m.field(F_DATADOC).persistent(); + + if (!permanent || m.get(F_DATADOC).blank()) + { + const bool magic_datadoc = m.field(F_DATADOC).automagic(); + if (!magic_datadoc) + { + long ndoc = 0; // unused + last_doc(provv, anno, codnum, ndoc, data_doc); + } + m.set(F_DATADOC, data_doc, 0x1); + } int pos = m.id2pos( F_DATACAMBIO1); if (pos >= 0 && m.fld(pos).active() && !m.get(F_CODVAL).empty()) @@ -406,6 +415,17 @@ bool TMotore_application::menu(MENU_TAG mt) if (_docmsk != NULL) _docmsk->sel_color(); } + if (mt == MENU_ITEM_ID(2)) + { + TMask m("Copie", 1, 40, 8); + + m.add_button_tool(DLG_OK, "", TOOL_OK); + m.add_button_tool(DLG_CANCEL, "", TOOL_CANCEL); + m.add_number(101, 0, "Numero di copie", 2, 3, 3); + m.set(101, _ncopie); + if (m.run() == K_ENTER) + _ncopie = m.get_int(101); + } else ok = TRelation_application::menu(mt); return ok; @@ -491,6 +511,7 @@ int TMotore_application::write( const TMask& m ) // C 90 { TDocumento_mask& mask = (TDocumento_mask&) m; TDocumento& d = (TDocumento&)_rel->curr(); + mask.mask2doc(); d = mask.doc(); // Trasferisce il documento da maschera a record // Se ho attivato la creazione automatica delle righe allora cancello quelle vuote finali @@ -539,6 +560,7 @@ int TMotore_application::rewrite( const TMask& m ) // C 90 if (d.bloccato()) return NOERR; + mask.mask2doc(); d = ((TDocumento_mask&)m).doc(); // Trasferisce il documento da maschera a record // Aggiunte per il controllo plafond @@ -707,8 +729,10 @@ bool TMotore_application::user_create( ) _msk->set_handler(F_CODNUM, TDocumento_mask::num_handler); _msk->set_handler(F_TIPODOC, tdoc_handler); _msk->set_handler(F_NUMDOCRIF, TDocumento_mask::numdocrif_search_handler); - //_msk->set_handler(F_RAGSOCSEARCH, TDocumento_mask::ragsoc_search_handler); - _msk->set_handler(F_NDOC, ndoc_handler); + // _msk->set_handler(F_RAGSOCSEARCH, TDocumento_mask::ragsoc_search_handler); + if (_msk->id2pos(F_RIFSEARCH) > 0) + _msk->set_handler( F_RIFSEARCH, TDocumento_mask::rif_search_handler ); + _msk->set_handler(F_NDOC, ndoc_handler); const int args = argc() ; @@ -772,6 +796,10 @@ bool TMotore_application::user_create( ) } } } + else + if (arg.starts_with("-c")) + _ncopie = atoi(arg.mid(2)); + } TConfig utente(CONFIG_GUI, app().name().left(2)); @@ -781,6 +809,7 @@ bool TMotore_application::user_create( ) _tipodoc = utente.get("TIPODOC"); _docmsk = NULL; + TSheet_field::set_line_number_width(4); load_auto_reopen_data(); return true; @@ -1058,7 +1087,7 @@ void TMotore_application::ini2mask(TConfig& ini, TMask& msk, bool query) ini.set_paragraph(*pa); // Considera solo i tipi riga validi - const TString4 tipo(ini.get(RDOC_TIPORIGA)); + const TString16 tipo(ini.get(RDOC_TIPORIGA)); if (tr.read(tipo) == NOERR) { // Crea una nuova riga documento diff --git a/src/ve/ve0100.h b/src/ve/ve0100.h index 1b1739191..fce640064 100755 --- a/src/ve/ve0100.h +++ b/src/ve/ve0100.h @@ -34,6 +34,7 @@ class TMotore_application : public TRelation_application TString4 _codnum; TString4 _tipodoc; TString80 __last_key; + int _ncopie; protected: // Array di maschere documento @@ -102,7 +103,7 @@ public: TDocumento & doc() {return edit_mask().doc(); } // Operazione - TMotore_application( ) { } + TMotore_application( ) : _ncopie(-1){ } virtual ~TMotore_application( ) { } virtual const char* get_next_key( ); diff --git a/src/ve/ve0100a.uml b/src/ve/ve0100a.uml index d3b90c68a..b9b68946e 100755 --- a/src/ve/ve0100a.uml +++ b/src/ve/ve0100a.uml @@ -113,8 +113,9 @@ NUMBER F_NDOC 6 BEGIN PROMPT 24 7 "Numero " FIELD NDOC - USE LF_DOC SELECT (#F_STATO=="")||(STATO==#F_STATO) - JOIN LF_CLIFO TO LF_DOC INTO TIPOCF==TIPOCF CODCF==CODCF + USE LF_DOC SELECT (#F_STATO=="")||(STATO==#F_STATO) + JOIN LF_CLIFO TO LF_DOC INTO TIPOCF==TIPOCF CODCF==CODCF + JOIN LF_COMUNI TO LF_CLIFO INTO STATO==STATOCF COM==COMCF INPUT PROVV F_PROVV SELECT INPUT ANNO F_ANNO SELECT INPUT CODNUM F_CODNUM SELECT @@ -129,6 +130,10 @@ BEGIN DISPLAY "C/F" TIPOCF DISPLAY "Codice" CODCF DISPLAY "Ragione Sociale@50" LF_CLIFO->RAGSOC + DISPLAY "Indirizzo@35" LF_CLIFO->INDCF + DISPLAY "Numero@15" LF_CLIFO->CIVCF + DISPLAY "Località@50" LF_CLIFO->LOCALITACF + DISPLAY "Comune@50" LF_COMUNI->DENCOM OUTPUT F_NDOC NDOC OUTPUT F_TIPODOC TIPODOC OUTPUT F_PROVV PROVV @@ -163,6 +168,7 @@ BEGIN /* USE LF_DOC KEY 2 SELECT (CODNUM==#F_CODNUM)&&(PROVV==#F_PROVV)&&(ANNO==#F_ANNO)&&((#F_STATO=="")||(STATO==#F_STATO)) JOIN LF_CLIFO INTO TIPOCF==TIPOCF CODCF==CODCF + JOIN LF_COMUNI TO LF_CLIFO INTO STATO==STATOCF COM==COMCF INPUT TIPOCF F_TIPOCF SELECT INPUT CODCF F_CODCF SELECT INPUT PROVV F_PROVV @@ -188,6 +194,11 @@ BEGIN DISPLAY "Data\ndocumento@10" DATADOC DISPLAY "Valuta" CODVAL DISPLAY "Totale\ndocumento@18V" G1:TOTDOC + DISPLAY "Stato" STATO + DISPLAY "Indirizzo@35" LF_CLIFO->INDCF + DISPLAY "Numero@15" LF_CLIFO->CIVCF + DISPLAY "Località@50" LF_CLIFO->LOCALITACF + DISPLAY "Comune@50" LF_COMUNI->DENCOM COPY OUTPUT F_NDOC OUTPUT F_CODCF CODCF CHECKTYPE NORMAL diff --git a/src/ve/ve0200g.uml b/src/ve/ve0200g.uml index aacf5fd99..dec36f0b6 100755 --- a/src/ve/ve0200g.uml +++ b/src/ve/ve0200g.uml @@ -8,7 +8,7 @@ PAGE "Distinta Base" 0 0 0 0 GROUPBOX DLG_NULL 78 9 BEGIN -PROMPT 1 1 "@bParametri esplosione ditinte" +PROMPT 1 1 "@bParametri esplosione distinte" END BOOLEAN F_EXPLODEDB diff --git a/src/ve/ve0300.cpp b/src/ve/ve0300.cpp index b1381c115..4b6fb86c4 100755 --- a/src/ve/ve0300.cpp +++ b/src/ve/ve0300.cpp @@ -126,7 +126,10 @@ public: // DISPLAY void display( const TString& s ){ outline( s, "DI " ); }; - // INPUT + // join + void join( const int file, const TString& s ){ _out << "JO " << file << " INTO " << s << "\n"; }; + + // INPUT void input( const TString& s ){ outline( s, "IN " ); }; // OUTPUT @@ -1383,7 +1386,7 @@ void TMask_generator::genera_testata_1() _m->use( LF_CLIFO, 1 ); temp_s.format( "TIPOCF \"%c\"~CODCF %d", tipo_cf, F_CODCF); _m->input( temp_s ); - _m->display( "\"Codice\" CODCF~\"Ragione Sociale@50\" RAGSOC~\"Partita IVA@12\" PAIV~\"Sospeso\" SOSPESO" ); + _m->display( "\"Codice\" CODCF~\"Ragione Sociale@50\" RAGSOC~\"Partita IVA@12\" PAIV~\"Sospeso\" SOSPESO~\"Indirizzo@35\" INDCF ~\"Numero@15\" CIVCF~\"Località@50\" LOCALITACF ~\"Comune@50\" 13->DENCOM" ); temp_s.format( "%d CODCF~%d RAGSOC", F_CODCF, F_RAGSOC ); _m->output( temp_s ); _m->check( S_OBBLIGATORIO ); @@ -1407,6 +1410,7 @@ void TMask_generator::genera_testata_1() _m->prompt( 24, 4, "" ); _m->group( 1 ); _m->use( LF_CLIFO, 2 ); + _m->join(LF_COMUNI, "STATO==STATOCF COM==COMCF"); temp_s.format( "TIPOCF \"%c\"~RAGSOC %d", tipo_cf, F_RAGSOC ); _m->input( temp_s ); _m->display( "\"Ragione Sociale@50\" RAGSOC~\"Partita IVA@12\" PAIV~\"Codice\" CODCF" ); diff --git a/src/ve/ve0300a.src b/src/ve/ve0300a.src index 7e2ee7c9b..3c42b4c5e 100755 --- a/src/ve/ve0300a.src +++ b/src/ve/ve0300a.src @@ -17,6 +17,7 @@ // T_CORNICE // T_ZOOM // T_CURRENCY +// T_SHEET // SIZE = E' la dimesione del campo nella maschera. Per i tipi che richiedono due dimensioni, // si fa dimensione1 * 100 + dimesione2 // PROMPT = E' il prompt di default per il campo ( pur essere cambiato nel .INI ) @@ -79,7 +80,7 @@ Y=0 MSKID=F_COFI TYPE=T_STRINGA PROMPT="Cod. fisc. " -USE=LF_CLIFO KE 4 +USE=LF_CLIFO KE 4~JO LF_COMUNI INTO STATO==STATOCF COM==COMCF INPUT=TIPOCF F_TIPOCF SELECT~COFI F_COFI DISPLAY="Codice Fiscale@16" COFI~"Ragione sociale@50" RAGSOC~"Codice" CODCF~"Indrizzo@35" INDCF OUTPUT=@F_CODCF @@ -127,7 +128,7 @@ Y=1 MSKID=F_PAIVA TYPE=T_STRINGA PROMPT="" -USE=LF_CLIFO KE 5 +USE=LF_CLIFO KE 5~JO LF_COMUNI INTO STATO==STATOCF COM==COMCF INPUT=TIPOCF F_TIPOCF SELECT~STATOPAIV F_STATOPAIVA~PAIV F_PAIVA DISPLAY="Partita IVA@12" PAIV~"Ragione sociale@50" RAGSOC~"Codice" CODCF~"Indrizzo@35" INDCF OUTPUT=@F_CODCF diff --git a/src/ve/ve1.cpp b/src/ve/ve1.cpp index a2b8a7c35..c38ab1bf5 100755 --- a/src/ve/ve1.cpp +++ b/src/ve/ve1.cpp @@ -12,7 +12,8 @@ int main(int argc, char **argv) case 3 : ve1400(argc, argv); break; //stampa tabelle vendita ed utilita' varie case 4 : ve1500(argc, argv); break; //stampa di controllo documenti contabilizzati case 5 : ve1600(argc, argv); break; //stampa di controllo bolle fatturate - default: ve1100(argc, argv); break; //stampa documenti di vendita + case 6 : ve1700(argc, argv); break; //Lista documento con report +default: ve1100(argc, argv); break; //stampa documenti di vendita } return 0; } diff --git a/src/ve/ve1.h b/src/ve/ve1.h index 109a2dd34..d2604b6bd 100755 --- a/src/ve/ve1.h +++ b/src/ve/ve1.h @@ -7,6 +7,7 @@ int ve1300(int argc, char* argv[]); int ve1400(int argc, char* argv[]); int ve1500(int argc, char* argv[]); int ve1600(int argc, char* argv[]); +int ve1700(int argc, char* argv[]); #endif // __VE1_H diff --git a/src/ve/ve1300.alx b/src/ve/ve1300.alx index 2b6656d65..1ffa31283 100755 --- a/src/ve/ve1300.alx +++ b/src/ve/ve1300.alx @@ -46,10 +46,14 @@ DOC_TOT_IMPONIBILI \ user defined word in ve1.exe ; +: MESSAGE_TABELLA_IVA ( b1 s1 n1 -- ) + DOC_TABELLA_IVA \ user defined word in ve1.exe +; + : MESSAGE_LV_DOT ( s1 -- ) DOC_LV_DOT \ user defined word in ve1.exe ; : MESSAGE_ADD_ROW ( s1 s2 s3 -- ) DOC_ADD_ROW \ user defined word in ve1.exe -; \ No newline at end of file +; diff --git a/src/ve/ve1700.cpp b/src/ve/ve1700.cpp new file mode 100644 index 000000000..105e0d363 --- /dev/null +++ b/src/ve/ve1700.cpp @@ -0,0 +1,484 @@ +// freeze +// valuta +// output +// librerie +// 99999 +////////////////////////////////////////////////////////////// +// Stampa documenti +////////////////////////////////////////////////////////////// + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "velib07.h" +#include "sconti.h" +#include "ve1700.h" + +#include +#include + +////////////////////////////////////////////////////////////////////////////////////////////// +// classe TListaDoc_application customizzata dalla TApplication per l'applicazione principale +////////////////////////////////////////////////////////////////////////////////////////////// + +class TStampa_lista_docs_mask : public TAutomask +{ + TCursor_sheet _clifo; + +protected: + bool on_field_event(TOperable_field& o, TField_event e, long jolly); + +public: + TCursor_sheet & clifo() { return _clifo; } + long select_cod_range(long from, long to); + void reset_choices(); + void set_choice_limits(); + void build_clifo_list(); + TStampa_lista_docs_mask(); + virtual ~TStampa_lista_docs_mask() {} +}; + +long TStampa_lista_docs_mask::select_cod_range(long from, long to) +{ + TWait_cursor hourglass; + if (from < 0L) + from = _clifo.row(_clifo.selected()).get_long(1); + if (to < 0L) + to = _clifo.row(_clifo.selected()).get_long(1); + else + if (to == 0L) + to = 999999L; + + for (int i = 0; i < _clifo.items(); i++) + { + TToken_string& c = _clifo.row(i); + + const long cod = c.get_long(1); + if (cod >= from && cod <= to) + _clifo.check(i); + else + _clifo.uncheck(i); + } + set_choice_limits(); + return _clifo.checked(); +} + +void TStampa_lista_docs_mask::set_choice_limits() +{ + long first = 999999L, last = -1L; + + for (int i = 0; i < _clifo.items(); i++) + { + if (_clifo.checked(i)) + { + const long cf = _clifo.row(i).get_long(1); + if (first > cf) + first = cf; + if (last < cf) + last = cf; + } + } + if (first != -1) + set(F_CODFR, first); + if (last != -1) + set(F_CODTO, last); + set(F_SELECTED, _clifo.checked()); +} + +void TStampa_lista_docs_mask::build_clifo_list() +{ + // Semplice ed efficace + TRectype rec(LF_CLIFO); + rec.put(CLI_TIPOCF, get(F_TIPOCF)); + _clifo.cursor()->setregion(rec, rec); +} + +void TStampa_lista_docs_mask::reset_choices() +{ + reset(F_SELECTED); + reset(F_CODFR); + reset(F_CODTO); + _clifo.check(-1, false); +} + +bool TStampa_lista_docs_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) +{ + switch (o.dlg()) + { + case F_TIPOCF: + if (e == fe_modify) + { + TWait_cursor hourglass; + reset_choices(); + build_clifo_list(); + } + break; + case F_CODFR : + if (e == fe_button) + { + _clifo.disable_check(); + _clifo.disable(DLG_USER); + if (_clifo.run() == K_ENTER) + select_cod_range(-1, o.mask().get_long(F_CODTO)); + _clifo.enable(DLG_USER); + } + else + if (e == fe_modify) + select_cod_range(o.get_long(), o.mask().get_long(F_CODTO)); + break; + case F_CODTO : + if (e == fe_button) + { + _clifo.disable_check(); + _clifo.disable(DLG_USER); + if (_clifo.run() == K_ENTER) + select_cod_range(o.mask().get_long(F_CODFR), -1); + _clifo.enable(DLG_USER); + } + else + if (e == fe_modify) + select_cod_range(o.mask().get_long(F_CODFR), o.get_long()); + break; + case BUT_SEL: + if (e == fe_button) + { + _clifo.enable_check(); + if (_clifo.run() == K_ENTER) + set_choice_limits(); + } + break; + case BUT_ANN: + if (e == fe_button) + reset_choices(); + break; + case 102: + if (e == fe_button) + { + TSheet_field & s = sfield(F_SHEETNUMS); + TToken_string & row = s.row(s.selected()); + TArray_sheet as(-1,-1,70,20,TR("Tipi documento"),HR("Codice|Descrizione@50")); //costruisce uno sheet di selezione dei tipi doc + + const TCodice_numerazione& cn = cached_numerazione(row.get(1)); + for (int t = cn.ntipi_doc()-1; t >= 0; t--) + { + const TString4 tipodoc = cn.tipo_doc(t); + TToken_string row; //classica token_string con codice e descrizione del tipodoc: questa viene scelta nella tabella + row.add(tipodoc); //dei tipi docs %TIP + row.add(cache().get("%TIP", tipodoc, "S0")); + as.add(row); //..e viene aggiunta allo sheet di selezione + } + if (as.run() != K_ESC) + { + TToken_string& riga = as.row(-1); //setta sul campo a maschera il codice della riga selezionata di as + o.set(riga.get(0)); + } + } + else + if (e == fe_close && o.get().full()) + { + TSheet_field & s = sfield(F_SHEETNUMS); + TToken_string & row = s.row(s.selected()); + const TCodice_numerazione& cn = cached_numerazione(row.get(s.cid2index(101))); + for (int t = cn.ntipi_doc()-1; t >= 0; t--) + { + const TString& tipodoc = cn.tipo_doc(t); + if (tipodoc == o.get()) + return true; + } + return o.error_box(FR("Tipo documento non valido per la numerazione %s"), (const char*)cn.codice()); + } + break; + default: break; + } + return true; +} + +TStampa_lista_docs_mask::TStampa_lista_docs_mask() + : TAutomask("ve1600a"), + _clifo(new TCursor(new TRelation(LF_CLIFO)), + " |CODCF|RAGSOC", TR("Selezione Clienti/Fornitori"), + HR("@1|Codice@6R|Descrizione@50"), 0, 1) +{ + ((TButton_tool&)field(DLG_PREVIEW)).set_exit_key('A'); +} + +/////////////////////////////////////////////////////////// +// TLista_documenti_recordset +/////////////////////////////////////////////////////////// +static void add_term(TString & expr, const char * term1, const char * op, const char * term2, + const bool string = true, const bool and = true, const bool is_string = true) +{ + if (expr.full()) + expr << (and ? "&&" : "||"); + if (is_string) + { + if (!string) + expr << "STR"; + } + else + if (string) + expr << "VAL"; + expr << '(' << term1 << op << term2 << ')'; +} + +static void add_expr(TString & expr, const char * subexpr, const bool string = true, + const bool and = true, const bool is_string = true) +{ + if (subexpr && *subexpr) + { + if (expr.full()) + expr << (and ? "&&" : "||"); + if (is_string) + { + if (!string) + expr << "STR"; + } + else + if (string) + expr << "VAL"; + expr << '(' << subexpr << ')'; + } +} +static const char * stringify(TString & s) +{ + s.insert("\""); + s << '"'; + return s; +} + +class TLista_documenti_recordset : public TDocument_recordset +{ + TStampa_lista_docs_mask * _m; +static TAssoc_array _clifo_sel; // Assoc array con solo i cli/fo selezionati. Facilita il filter... + +protected: + virtual TCursor* cursor() const; + static bool filter_clifo(const TRelation* r); + +public: + + TLista_documenti_recordset(const char* use, TStampa_lista_docs_mask * m) : TDocument_recordset(use), _m(m) {} + virtual ~TLista_documenti_recordset() { } +}; + +TAssoc_array TLista_documenti_recordset::_clifo_sel; // Assoc array con solo i cli/fo selezionati. Facilita il filter... + +bool TLista_documenti_recordset::filter_clifo(const TRelation* r) +{ + const long codcf = r->curr().get_long(CLI_CODCF); + TString8 key; key.format("%06ld", codcf); + return _clifo_sel.is_key(key); +} + +TCursor* TLista_documenti_recordset::cursor() const +{ + const bool to_create = !valid_cursor(); + TCursor * cur = TDocument_recordset::cursor(); + + if (to_create && cur != NULL) + { + TStampa_lista_docs_mask & m = *_m; + TCursor_sheet & clifo = m.clifo(); + + cur->setkey(3); + ((TLista_documenti_recordset *) this)->set_firmval(m.get_int(F_SELVAL) == 3); + // Compone la lista dei clienti/forntitori selezionati + _clifo_sel.destroy(); + TString16 key; + const long items = clifo.items(); + for (long i = 0L; iset_filterfunction(clifo.checked() > 0 ? filter_clifo : NULL); + // NB: se _clifo_sel non contiene nulla, non viene effettuato alcun filter su CLI/FO (non setta la funzione!!) + + TString filter(cur->filter()); + TString val = m.get(F_TIPOCF); + const int selval = m.get_int(F_SELVAL); + + ::add_term(filter, DOC_TIPOCF, "==", stringify(val)); + val = m.get(F_ANNO); + ::add_term(filter, DOC_ANNO, "==", stringify(val)); + val = m.get(F_PROVV); + ::add_term(filter, DOC_PROVV, "==", stringify(val)); + if (selval == 1) //In Lire + { + TString16 firm_val(TCurrency::get_firm_val()); + + if (firm_val.full()) + ::add_term(filter, "(" DOC_CODVAL, "==", stringify(firm_val)); + ::add_term(filter, DOC_CODVAL, "==", "\"\")", true, false); + } + else + if (selval == 2) // nella valuta specificata + { + val = m.get(F_VALUTA); + ::add_term(filter, DOC_CODVAL, "==", stringify(val)); + } + + // Compone l'espressione filter... + // prende tutte le righe dello spreasheet che non sono totalmente vuote: + // (CODNUM=="xxx"&&(STATO=="x"||STATO=="y"||STATO=="z"...)) ---> questo per una singola riga... + // se vi sono piu' righe, lo si ripete aggiungendo prima un bellissimo "||" + TSheet_field& sf = m.sfield(F_SHEETNUMS); + const int rows = sf.items(); + TString docfilter; + TString from_num("ZZZZ"); + TString to_num; + + for (int j=0; j str) + from_num = str; + if (to_num < str) + to_num = str; + } + str = riga.get(); + if (str.full()) + ::add_term(docfilter, DOC_TIPODOC, "==", stringify(str)); + + for (int k = 2; k <= 7; k++) // Famme vede' li stati generali... Aho' A BURINO! Che e' la Rivoluzione Francese? + { + TString4 c = riga.get(k); + + if (c.full()) + ::add_term(statofilter, DOC_STATO, "==", stringify(c), true, false); + } + ::add_expr(docfilter, statofilter); + } + ::add_expr(filter, docfilter); + + TRectype from(LF_DOC); + TRectype to(from); + TDate da = m.get_date(F_DA_DATADOC); + TDate a = m.get_date(F_A_DATADOC); + const int anno = m.get_int(F_ANNO); + + if (!da.ok()) + da = TDate(1, 1, anno); + if (!a.ok()) + a = TDate(31, 12, anno); + from.put(DOC_DATADOC, da); + to.put(DOC_DATADOC, a); + val = m.get(F_ANNO); + from.put(DOC_ANNO, val); + to.put(DOC_ANNO, val); + val = m.get(F_PROVV); + from.put(DOC_PROVV, val); + to.put(DOC_PROVV, val); + from.put(DOC_CODNUM, from_num); + to.put(DOC_CODNUM, to_num); + cur->freeze(false); + cur->setregion(from, to); + cur->setfilter(filter); + const TRecnotype it = cur->items(); + cur->freeze(); + if (it > 0L) + *cur = 0L; + } + return cur; +} + + +////////////////////////////////////////////////////////////////////////////////////////////// +// classe TListaDoc_application customizzata dalla TApplication per l'applicazione principale +////////////////////////////////////////////////////////////////////////////////////////////// + + +// Chiavi di ordinamento LF_DOC: +// Chiave 1: ordinamento per Provvisorio + Anno + Codice numerazione + Numero documento +// Chiave 3: ordinamento per Data documento + Provvisorio + Anno + Codice numerazione + Numero documento + +class TLista_documenti_report : public TDocument_report +{ +/* TString _codnum; // codice di numerazione + char _provv; // stampa documenti provvisiori o definitivi (D o P) + int _anno; // anno della documentazione + int _ncopie; // numero di copie per ogni documento + long _dalnum, _alnum; // estremi di numerazione dei documenti + TDate _dadata, _adata; // estremi di data dei documenti */ + TStampa_lista_docs_mask * _m; + + +protected: + bool set_recordset(const TString& query); + +public: + TLista_documenti_report(TStampa_lista_docs_mask * m) : _m(m) {} +}; + +bool TLista_documenti_report::set_recordset(const TString& query) +{ + return TReport::set_recordset(new TLista_documenti_recordset(query, _m)); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +// classe TListaDoc_application customizzata dalla TApplication per l'applicazione principale +////////////////////////////////////////////////////////////////////////////////////////////// + +class TListaDoc_application: public TSkeleton_application +{ +protected: + virtual bool create(); + virtual void main_loop(); + +public: + TListaDoc_application() {}; + virtual ~TListaDoc_application() {}; +}; + +bool TListaDoc_application::create() +{ + return TSkeleton_application::create(); +} + +void TListaDoc_application::main_loop() +{ + TStampa_lista_docs_mask m; + TLista_documenti_report report(&m); + + m.set(F_REPORT, "ve16001"); + + while (m.run() != K_QUIT) + { + TReport_book book; + TFilename report_name = m.get(F_REPORT); + + if (report_name.blank()) + report_name = "ve16001"; + report.load(report_name); + book.add(report); + if (book.pages() > 0) + book.print_or_preview(); + m.set(F_REPORT, "ve16001"); + } +} + +// Do all the work! +int ve1700(int argc, char* argv[]) +{ + TListaDoc_application a; + a.run(argc, argv, TR("Lista documenti")); + return 0; +} \ No newline at end of file diff --git a/src/ve/ve1700.h b/src/ve/ve1700.h new file mode 100644 index 000000000..15f2b248a --- /dev/null +++ b/src/ve/ve1700.h @@ -0,0 +1,30 @@ +#define F_CODNUM 121 +#define F_ANNO 122 +#define F_PROVV 123 +#define F_NCOPIE 124 + +#define F_DATA_O_NUM 125 + +#define F_DA_NDOC 126 +#define F_A_NDOC 127 + +#define F_DA_DATADOC 128 +#define F_A_DATADOC 129 +#define F_TIPOST 130 + +#define F_TIPOCF 110 +#define F_CODFR 111 +#define F_CODTO 112 +#define F_SELECTED 113 +#define BUT_SEL 114 +#define BUT_ANN 115 +#define F_SELVAL 116 +#define F_VALUTA 117 +#define F_DESCR_CLI 119 +#define F_REPORT 130 + +#define F_SHEETNUMS 201 + +#define GROUP_PRICES 29 +#define GROUP_QTA 30 +#define GROUP_IMPORTI 31 diff --git a/src/ve/ve17001.rep b/src/ve/ve17001.rep new file mode 100644 index 000000000..5cae82a67 --- /dev/null +++ b/src/ve/ve17001.rep @@ -0,0 +1,178 @@ + + + Lista documenti + +
+ + + + #SYSTEM.RAGSOC + + + #SYSTEM.DATE + + + #PAGE + + + + + + MESSAGE _SEPARATOR,157 + + + MESSAGE _SEPARATOR,157 + + + + + + + + + + + + + + + + + +
+
+ MESSAGE RESET,F1 +
+
+ + "" + +
+
+ + + + + + CODCF + + + CODAG + + + CODPAG + + + MESSAGE _TABELLA_IVA,0,IMP + MESSAGE ADD,F1.15 + + + MESSAGE _TABELLA_IVA,0,COD + + + MESSAGE _TABELLA_IVA,0,IVA + MESSAGE ADD,F1.16 + + + MESSAGE _TABELLA_IVA,1,IMP + MESSAGE ADD,F1.15 + + + MESSAGE _TABELLA_IVA,1,COD + + + MESSAGE _TABELLA_IVA,1,IVA + MESSAGE ADD,F1.16 + + + MESSAGE _TABELLA_IVA,2,IMP + MESSAGE ADD,F1.15 + + + MESSAGE _TABELLA_IVA,2,COD + + + MESSAGE _TABELLA_IVA,2,IVA + MESSAGE ADD,F1.16 + + + MESSAGE _TABELLA_IVA,3,IMP + MESSAGE ADD,F1.15 + + + MESSAGE _TABELLA_IVA,3,COD + + + MESSAGE _TABELLA_IVA,3,IVA + MESSAGE ADD,F1.16 + + + MESSAGE _TABELLA_IVA,4,IMP + MESSAGE ADD,F1.15 + + + MESSAGE _TABELLA_IVA,4,COD + + + MESSAGE _TABELLA_IVA,4,IVA + MESSAGE ADD,F1.16 + + + + CODNUM+"F;"+TIPODOC + + + DATADOC + + + 33.NDOC + + + + STATO + + + MESSAGE _CLIENTE,!RAGSOC + + + CODVAL + + + TOTDOC + #THIS @ +"F1.17" +! + + +
+
+
+ + MESSAGE _SEPARATOR,157 + + + + + + + + + + + + + +
+ USE DOC + + \ No newline at end of file diff --git a/src/ve/ve17002.rep b/src/ve/ve17002.rep new file mode 100644 index 000000000..4c49314a7 --- /dev/null +++ b/src/ve/ve17002.rep @@ -0,0 +1,254 @@ + + + Lista documenti con dettaglio + +
+ + + + #SYSTEM.RAGSOC + + + #SYSTEM.DATE + + + #PAGE + + + + + + MESSAGE _SEPARATOR,157 + + + MESSAGE _SEPARATOR,157 + + + + + + + + + + + +
+
+ MESSAGE RESET,F1 +
+
+ CODNUM+NDOC + + + + + + + + CODNUM+"F;"+TIPODOC + + + DATADOC + + + 33.NDOC + + + + STATO + + + + MESSAGE _CLIENTE,!RAGSOC + + + CODCF + + + CODVAL + + + CODAG + + + CODPAG + +
+
+ + "" + +
+
+ + + + +
+
+ MESSAGE RESET,F11 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ USE RDOC SELECT TIPORIGA!="05" +FROM CODNUM=#PARENT.CODNUM ANNO=#PARENT.ANNO PROVV=#PARENT.PROVV NDOC=#PARENT.NDOC +TO CODNUM=#PARENT.CODNUM ANNO=#PARENT.ANNO PROVV=#PARENT.PROVV NDOC=#PARENT.NDOC + + + CODART + + + MESSAGE _DESCRIGA + + + UMQTA + + + QTA + + + PREZZO + + + SCONTO + + + IMPNS + MESSAGE ADD,F11.15 + + + CODIVA + + + IMPOSTA + MESSAGE ADD,F11.16 + + + IMPNS+IMPOSTA + MESSAGE ADD,F11.14 + +
+
+ + + + + + + MESSAGE ADD,F1.14 + + + + + MESSAGE ADD,F1.15 + + + + MESSAGE ADD,F1.16 + +
+
+
+ + MESSAGE _SEPARATOR,157 + + + + + + + + + + + + + +
+
+ USE DOC + + \ No newline at end of file diff --git a/src/ve/ve1700a.uml b/src/ve/ve1700a.uml new file mode 100644 index 000000000..90b3946c9 --- /dev/null +++ b/src/ve/ve1700a.uml @@ -0,0 +1,233 @@ +#include "ve1700.h" + +TOOLBAR "topbar" 0 0 0 2 +#include +ENDPAGE + +PAGE "Lista documenti" -1 -1 60 21 + +NUMBER F_ANNO 4 0 +BEGIN + PROMPT 2 1 "Anno " + FLAG "AP" + CHECKTYPE REQUIRED +END + +LIST F_PROVV 12 +BEGIN + PROMPT 24 1 "Tipo numerazione " + ITEM "D|Definitiva" + ITEM "P|Provvisoria" + FLAG "P" +END + +SPREADSHEET F_SHEETNUMS 78 8 +BEGIN + PROMPT 1 2 "" + ITEM "Cod. num." + ITEM "Tipo doc." + ITEM "Stato 1" + ITEM "Stato 2" + ITEM "Stato 3" + ITEM "Stato 4" + ITEM "Stato 5" + ITEM "Stato 6" +END + +DATE F_DA_DATADOC +BEGIN + PROMPT 2 11 "Dalla data " +END + +DATE F_A_DATADOC +BEGIN + PROMPT 2 12 "Alla data " +END + +LIST F_TIPOCF 1 11 +BEGIN + PROMPT 25 12 "Tipo " + ITEM "C|Clienti" + ITEM "F|Fornitori" +END + +NUMBER F_CODFR 6 +BEGIN + PROMPT 25 13 "Da codice " + FLAGS "B" +END + +NUMBER F_CODTO 6 +BEGIN + PROMPT 25 14 "A codice " + FLAGS "B" +END + +STRING F_SELECTED 5 +BEGIN + PROMPT 25 15 "Scelte n. " + FLAGS "DR" +END + +BUTTON BUT_SEL 10 2 +BEGIN + PROMPT 45 13 "~Selezione" + PICTURE BMP_SELECT +END + +BUTTON BUT_ANN 10 +BEGIN + PROMPT 45 15 "A~zzera" +END + +RADIOBUTTON F_SELVAL 20 +BEGIN + PROMPT 2 13 "Stampa documenti" + ITEM "1|Valuta ditta" + MESSAGE CLEAR,F_VALUTA + ITEM "2|In valuta" + MESSAGE ENABLE,F_VALUTA + ITEM "3|Tutti" + MESSAGE CLEAR,F_VALUTA +END + +STRING F_VALUTA 3 +BEGIN + PROMPT 25 16 "Cod. val. " + FLAGS "U" + USE %VAL + INPUT CODTAB F_VALUTA + DISPLAY "Codice" CODTAB + DISPLAY "Descrizione@50" S0 + OUTPUT F_VALUTA CODTAB + CHECKTYPE REQUIRED +END + +STRING F_DESCR_CLI 50 30 +BEGIN + PROMPT 2 18 "Ragione sociale " + USE LF_CLIFO KEY 2 + INPUT TIPOCF F_TIPOCF SELECT + INPUT RAGSOC F_DESCR_CLI + DISPLAY "Ragione Sociale@50" RAGSOC + DISPLAY "Codice@15" CODCF + OUTPUT F_CODFR CODCF + OUTPUT F_CODTO CODCF +END + +STRING F_REPORT 50 +BEGIN + PROMPT 2 -3 "Report " + RSELECT "ve1600" + CHECKTYPE NORMAL +END + +STRING DLG_PROFILE 50 +BEGIN + PROMPT 2 -2 "Profilo " + PSELECT +END + +ENDPAGE + +ENDMASK + +PAGE "" -1 -1 75 10 + +STRING 101 4 +BEGIN + PROMPT 1 1 "Codice numerazione " + FLAGS "U" + USE %NUM + INPUT CODTAB 101 + DISPLAY "Cod. Num." CODTAB + DISPLAY "Descrizione@50" S0 + OUTPUT 101 CODTAB + CHECKTYPE NORMAL +END + +STRING 102 4 +BEGIN + PROMPT 1 2 "Tipo documento " + FLAGS "UB" +END + +STRING 103 1 +BEGIN + PROMPT 1 3 "Stato 1 " + USE %STD + INPUT CODTAB 103 + DISPLAY "Stato" CODTAB + DISPLAY "Descrizione@50" S0 + OUTPUT 103 CODTAB + CHECKTYPE NORMAL +END + +STRING 104 1 +BEGIN + PROMPT 1 4 "Stato 2 " + USE %STD + INPUT CODTAB 104 + DISPLAY "Stato" CODTAB + DISPLAY "Descrizione@50" S0 + OUTPUT 104 CODTAB + CHECKTYPE NORMAL +END + +STRING 105 1 +BEGIN + PROMPT 1 5 "Stato 3 " + USE %STD + INPUT CODTAB 105 + DISPLAY "Stato" CODTAB + DISPLAY "Descrizione@50" S0 + OUTPUT 105 CODTAB + CHECKTYPE NORMAL +END + +STRING 106 1 +BEGIN + PROMPT 1 6 "Stato 4 " + USE %STD + INPUT CODTAB 106 + DISPLAY "Stato" CODTAB + DISPLAY "Descrizione@50" S0 + OUTPUT 106 CODTAB + CHECKTYPE NORMAL +END + +STRING 107 1 +BEGIN + PROMPT 1 7 "Stato 5 " + USE %STD + INPUT CODTAB 107 + DISPLAY "Stato" CODTAB + DISPLAY "Descrizione@50" S0 + OUTPUT 107 CODTAB + CHECKTYPE NORMAL +END + +STRING 108 1 +BEGIN + PROMPT 1 8 "Stato 6 " + USE %STD + INPUT CODTAB 108 + DISPLAY "Stato" CODTAB + DISPLAY "Descrizione@50" S0 + OUTPUT 108 CODTAB + CHECKTYPE NORMAL +END + +BUTTON DLG_OK 10 2 +BEGIN + PROMPT -12 -1 "" +END + +BUTTON DLG_QUIT 10 2 +BEGIN + PROMPT -22 -1 "" +END + +ENDPAGE + +ENDMASK diff --git a/src/ve/ve2400.cpp b/src/ve/ve2400.cpp index 4945730a8..05b51015b 100755 --- a/src/ve/ve2400.cpp +++ b/src/ve/ve2400.cpp @@ -922,18 +922,18 @@ bool TMask_anamag::handle_anno(TMask_field &fld, KEY k) if (original_row == row) { mag.zero(); - TString16 codmag = original_row.get(fld_giac.cid2index(F_CODMAG)); - - codmag.rpad(3); - codmag << original_row.get(fld_giac.cid2index(F_CODDEP)); + TString16 codmag = original_row.get(fld_giac.cid2index(F_CODMAG)); + + codmag.rpad(3); + codmag << original_row.get(fld_giac.cid2index(F_CODDEP)); mag.put(MAG_CODMAG, codmag); mag.put(MAG_CODART, mask.get(F_CODART)); - - TString livello = original_row.get(fld_giac.cid2index(F_LIV1)); - - livello << original_row.get(fld_giac.cid2index(F_LIV2)); - livello << original_row.get(fld_giac.cid2index(F_LIV3)); - livello << original_row.get(fld_giac.cid2index(F_LIV4)); + + TString livello = original_row.get(fld_giac.cid2index(F_LIV1)); + + livello << original_row.get(fld_giac.cid2index(F_LIV2)); + livello << original_row.get(fld_giac.cid2index(F_LIV3)); + livello << original_row.get(fld_giac.cid2index(F_LIV4)); mag.put(MAG_LIVELLO, livello); mag.put(MAG_ANNOES, annoes); @@ -2151,18 +2151,18 @@ int TAnagrafica_magazzino::rewrite(const TMask& m) { mag.zero(); mag.put(MAG_ANNOES, annoes); - TString16 codmag = original_row.get(fld_giac.cid2index(F_CODMAG)); - - codmag.rpad(3); - codmag << original_row.get(fld_giac.cid2index(F_CODDEP)); + TString16 codmag = original_row.get(fld_giac.cid2index(F_CODMAG)); + + codmag.rpad(3); + codmag << original_row.get(fld_giac.cid2index(F_CODDEP)); mag.put(MAG_CODMAG, codmag); mag.put(MAG_CODART, m.get(F_CODART)); - - TString livello = original_row.get(fld_giac.cid2index(F_LIV1)); - - livello << original_row.get(fld_giac.cid2index(F_LIV2)); - livello << original_row.get(fld_giac.cid2index(F_LIV3)); - livello << original_row.get(fld_giac.cid2index(F_LIV4)); + + TString livello = original_row.get(fld_giac.cid2index(F_LIV1)); + + livello << original_row.get(fld_giac.cid2index(F_LIV2)); + livello << original_row.get(fld_giac.cid2index(F_LIV3)); + livello << original_row.get(fld_giac.cid2index(F_LIV4)); mag.put(MAG_LIVELLO, livello); if (mag.read(_isequal) == NOERR) diff --git a/src/ve/ve2401.cpp b/src/ve/ve2401.cpp index ac4a184e5..fb5a2d23c 100755 --- a/src/ve/ve2401.cpp +++ b/src/ve/ve2401.cpp @@ -107,6 +107,7 @@ void TCodart_mask::start_run() } _restart.cut(0); enable(101, !spegni101); + enable(201, !spegni101); } TAutomask::start_run(); } diff --git a/src/ve/ve6.cpp b/src/ve/ve6.cpp index c43ffdd06..9e74295af 100755 --- a/src/ve/ve6.cpp +++ b/src/ve/ve6.cpp @@ -21,7 +21,8 @@ int main( int argc, char** argv ) case 7: ve6700(argc, argv); break; // copia documenti interattiva da ditta a ditta case 8: ve6800(argc, argv); break; // contabilizzazione analitica documenti case 9: ve6900(argc, argv); break; // controllo ordini evasi - case 10: ve61000(argc, argv); break; // Eliminazione documenti + case 10: ve6a00(argc, argv); break; // generazione regolarizzazioni + case 11: ve6b00(argc, argv); break; // Eliminazione documenti default: ve6100(argc, argv); break; // contabilizzazione documenti } return 0; diff --git a/src/ve/ve6.h b/src/ve/ve6.h index 2e6684b2a..b651b6747 100755 --- a/src/ve/ve6.h +++ b/src/ve/ve6.h @@ -10,6 +10,7 @@ int ve6600 (int, char**); int ve6700 (int, char**); int ve6800 (int, char**); int ve6900 (int, char**); -int ve61000 (int, char**); +int ve6a00 (int, char**); +int ve6b00 (int, char**); #endif diff --git a/src/ve/ve6100a.uml b/src/ve/ve6100a.uml index 267f88fb4..26063e7ae 100755 --- a/src/ve/ve6100a.uml +++ b/src/ve/ve6100a.uml @@ -68,6 +68,7 @@ END BOOLEAN F_DATA_AUTO BEGIN PROMPT 40 3 "Data registrazione automatica" + MESSAGE FALSE ENABLE,F_DATA_REG MESSAGE TRUE CLEAR,F_DATA_REG|"",F_DATA_REG END diff --git a/src/ve/ve6a00.cpp b/src/ve/ve6a00.cpp new file mode 100644 index 000000000..ae5ad4f2d --- /dev/null +++ b/src/ve/ve6a00.cpp @@ -0,0 +1,137 @@ +#include "velib.h" +#include "ve6700a.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "ve6700a.h" +#include "velib04.h" +#include "../mg/mglib.h" + +/////////////////////////////////////////////////////////// +// Applicazione principale +/////////////////////////////////////////////////////////// + +class TCreazione_regolarizzazione : public TSkeleton_application +{ + +public: + bool load(); + virtual void main_loop(); +}; + +bool TCreazione_regolarizzazione::load() +{ + bool ok = false; + + if (argc() > 2) + { + const TString& arg = argv(2); + if ((arg[0] != '-' && arg[0] != '/') || (arg[1] != 'i' && arg[1] != 'I')) + return false; + + TFilename ini_name(arg.mid(2)); + if (ini_name.blank() && argc() > 3) + ini_name = argv(3); + + if (ini_name.exist()) + { + TConfig ini(ini_name, "33"); + char provv = ini.get_char(DOC_PROVV); + const int anno = ini.get_int(DOC_ANNO); + TString16 codnum(ini.get(DOC_CODNUM)); + long numdoc = ini.get_long(DOC_NDOC); + TDocumento indoc; + bool ok = numdoc > 0 && indoc.read(provv, anno, codnum, numdoc) == NOERR; + + if (ok) + { + const TElaborazione_esterna ee(ini.get("Action", "Transaction")); + + provv = 'D'; + codnum = ee.codice_numerazione_finale(); + numdoc = indoc.get_long("NUMDOCREG"); + + TDocumento outdoc; + const long codcli = indoc.clifor().get_long(CLI_CODCFASS); + + ok = codcli > 0L; + if (!ok) + return message_box("Cliente corrispondente assente"); + if (ok && (numdoc == 0 || outdoc.read(provv, anno, codnum, numdoc) != NOERR)) + { + outdoc.zero(); + TDocumento::set_key(outdoc, provv, anno, codnum, 0L); + outdoc.renum_ndoc(); + outdoc.set_tipo(ee.tipo_finale()); + outdoc.stato(ee.stato_finale()[0]); + outdoc.put(DOC_DATADOC, indoc.get_date(DOC_DATADOC)); + outdoc.put(DOC_TIPOCF, "C"); + outdoc.put(DOC_CODCF, codcli); + outdoc.cli2doc(); + } + outdoc.put(DOC_DATADOCRIF, indoc.get_date(DOC_DATADOCRIF)); + outdoc.put(DOC_NUMDOCRIF, indoc.get(DOC_NUMDOCRIF)); + outdoc.destroy_rows(); + TAssoc_array & iva = indoc.tabella_iva(); // no reference + + // Scorre tutti gli elementi della tabella IVA del documento (elementi per codice iva) + for (const TRiepilogo_iva* riep = (const TRiepilogo_iva*) iva.first_item(); + riep != NULL; riep = (const TRiepilogo_iva*) iva.succ_item()) + { + TRiga_documento & row = outdoc.new_row("01"); + + row.put(RDOC_DESCR, "Regolarizzazione"); + row.put(RDOC_QTA, UNO); + row.put(RDOC_PREZZO, riep->imponibile()); + row.put(RDOC_CODIVA, riep->cod_iva().codice()); + } + + int err = outdoc.rewrite(); + ok = err == NOERR; + if (!ok) + return error_box(FR("Errore %d di riscrittura del documento destinazione"), err); +// qui outdoc.do_elab(); + err = outdoc.rewrite(); + ok = err == NOERR; + if (!ok) + return error_box(FR("Errore %d di riscrittura del documento destinazione"), err); + + ini.set("Result", "OUTDOC"); + indoc.put("NUMDOCREG", outdoc.numero()); + indoc.stato(ee.stato_finale_doc_iniziale()[0]); + err = indoc.rewrite(); + ok = err == NOERR; + if (!ok) + return error_box(FR("Errore %d di riscrittura del documento sorgente"), err); + } + } + } + return ok; +} + +void TCreazione_regolarizzazione::main_loop() +{ + open_files(LF_TAB, LF_TABCOM, LF_DOC, LF_RIGHEDOC, LF_MOVMAG, NULL); + open_files(LF_ANAMAG, LF_CLIFO, LF_CFVEN, LF_OCCAS, LF_RMOVMAG, NULL); + + load(); +} + +int ve6a00(int argc, char** argv) +{ + TCreazione_regolarizzazione app; + + app.run(argc, argv, TR("Generazione regolarizzazione")); + return 0; +} diff --git a/src/ve/ve61000.cpp b/src/ve/ve6b00.cpp similarity index 97% rename from src/ve/ve61000.cpp rename to src/ve/ve6b00.cpp index b5bdf6eb6..2578fcad7 100644 --- a/src/ve/ve61000.cpp +++ b/src/ve/ve6b00.cpp @@ -1,5 +1,5 @@ /************************************************** - * File: ve61000.cpp * + * File: ve600.cpp * * Programma per il controllo degli ordini evasi * * Authors: Alessandro Bonazzi, Mattia Tollari * **************************************************/ @@ -14,7 +14,7 @@ #include "velib04.h" #include "../cg/cgsaldac.h" -#include "ve61000a.h" +#include "ve6b00a.h" /////////////////////////////////////////////// @@ -154,7 +154,7 @@ void TEliminazione_documenti_app::main_loop() check(); } -int ve61000 (int argc, char **argv) +int ve6b00 (int argc, char **argv) { TEliminazione_documenti_app a; a.run(argc,argv, TR("Elimiazione documenti")); diff --git a/src/ve/ve61000a.h b/src/ve/ve6b00a.h similarity index 74% rename from src/ve/ve61000a.h rename to src/ve/ve6b00a.h index 3fc58ddd6..fa4cb9f8e 100644 --- a/src/ve/ve61000a.h +++ b/src/ve/ve6b00a.h @@ -1,4 +1,4 @@ -// Include file per ve61000a.uml +// Include file per ve6b00a.uml #define F_PROVV 101 #define F_DA_ANNO 102 diff --git a/src/ve/ve61000a.uml b/src/ve/ve6b00a.uml similarity index 96% rename from src/ve/ve61000a.uml rename to src/ve/ve6b00a.uml index 1bbc792d5..b1beed106 100644 --- a/src/ve/ve61000a.uml +++ b/src/ve/ve6b00a.uml @@ -1,4 +1,4 @@ -#include "ve61000a.h" +#include "ve6b00a.h" PAGE "Eliminazione documenti" -1 -1 50 5 diff --git a/src/ve/veini.h b/src/ve/veini.h index 41f35b9ff..4eefa0b63 100755 --- a/src/ve/veini.h +++ b/src/ve/veini.h @@ -9,6 +9,7 @@ #define T_ZOOM 9 #define T_GOLEM 10 #define T_CURRENCY 11 +#define T_SHEET 12 #define S_NASCOSTO 0 #define S_NON_VISIBILE 1 diff --git a/src/ve/velib.h b/src/ve/velib.h index 1dbf7fe08..b7f021843 100755 --- a/src/ve/velib.h +++ b/src/ve/velib.h @@ -118,6 +118,9 @@ class TDocumento_variable_field : public TVariable_field class TSpesa_prest : public TRectype // velib01 { +protected: + const TString & cod() const { return get("COD"); } + public: TObject* dup() const { return new TSpesa_prest(codice()); } @@ -140,8 +143,8 @@ public: char tipo_ritenuta() const { return get_char("S9"); } const TString& tipo_riga() const { return get("S8"); } char genere() const; - const TString& conto_analitico_vendite() const { return get("S1").left(20); } - const TString& conto_analitico_acquisti() const { return get("S2"); } + const TString& conto_analitico_vendite() const { return ((cod() == "ATR") || (cod() == "RSS")) ? EMPTY_STRING : get("S1").left(20); } + const TString& conto_analitico_acquisti() const { return ((cod() == "ATR") || (cod() == "RSS")) ? get("S1").left(20) : get("S2"); } const TString& cdc() const { return get("S1").mid(20, 20); } const TString& cms() const { return get("S1").mid(40, 20); } const TString& fase() const { return get("S1").mid(60); } @@ -1074,10 +1077,13 @@ public: TCodgiac_livelli& livelli() const { return *_livelli_giac; } static bool anno_handler( TMask_field& f, KEY key); static bool num_handler( TMask_field& f, KEY key ); + static bool tipo_handler( TMask_field& f, KEY key ); static bool numdocrif_search_handler( TMask_field& f, KEY key ); - //static bool ragsoc_search_handler( TMask_field& f, KEY key ); + static bool ragsoc_search_handler( TMask_field& f, KEY key ); + static bool rif_search_handler( TMask_field& f, KEY key ); static bool datadocrif_handler(TMask_field& f, KEY key); - static bool liqdiff_handler( TMask_field& f, KEY key ); + static bool sheet_handler(TMask_field& f, KEY key); + static bool liqdiff_handler( TMask_field& f, KEY key ); virtual void highlight_row(int row, COLOR back = COLOR_INVALID, COLOR fore = COLOR_INVALID, bool dirty = true, bool update = true); diff --git a/src/ve/velib03.cpp b/src/ve/velib03.cpp index bbe35f213..5deeda5e7 100755 --- a/src/ve/velib03.cpp +++ b/src/ve/velib03.cpp @@ -1,3237 +1,3242 @@ -#include -#include -#include -#include -#include -#include - -#include "../cg/cg2103.h" -#include "../db/dblib.h" -#include "../pr/prlib.h" -#include "../li/letint.h" - -#ifdef LIVE_STATISTICS -#include "../sv/svlib01.h" -#endif - -#include "veini.h" -#include "velib.h" -#include "sconti.h" -#include "vepriv.h" -#include "veuml.h" - -/////////////////////////////////////////////////////////// -// TTipo_documento_cache -/////////////////////////////////////////////////////////// - -class TTipo_documento_cache : public TRecord_cache -{ -protected: - virtual TObject* rec2obj(const TRectype& rec) const; - -public: - TTipo_documento& tipo(const char* key); - TTipo_documento_cache(); - virtual ~TTipo_documento_cache() { } -}; - -TTipo_documento_cache::TTipo_documento_cache() - : TRecord_cache("%TIP", 1) -{ - test_file_changes(); // Tieni d'occhio le modifiche sul file - set_items_limit(59); // Standard -} - -TObject* TTipo_documento_cache::rec2obj(const TRectype& curr) const -{ - return new TTipo_documento(curr); -} - -TTipo_documento& TTipo_documento_cache::tipo(const char* key) -{ - TString8 k; k << "TIP|" << key; - return (TTipo_documento&)query(k); -} - -const TTipo_documento& cached_tipodoc(const char* tipodoc) -{ - HIDDEN TTipo_documento_cache __cache_tipi_documento; - return __cache_tipi_documento.tipo(tipodoc); -} - -/////////////////////////////////////////////////////////// -// TTipo_numerazione_cache -/////////////////////////////////////////////////////////// -class TNumerazione_cache : public TRecord_cache -{ -protected: - virtual TObject* rec2obj(const TRectype& rec) const; - -public: - TCodice_numerazione & num(const char* key); - TNumerazione_cache(); - virtual ~TNumerazione_cache() { } -}; - -TNumerazione_cache::TNumerazione_cache() - : TRecord_cache("%NUM", 1) -{ - test_file_changes(); // Tieni d'occhio le modifiche sul file - set_items_limit(59); // Standard -} - -TObject* TNumerazione_cache::rec2obj(const TRectype& curr) const -{ - return new TCodice_numerazione(curr); -} - -TCodice_numerazione & TNumerazione_cache::num(const char* key) -{ - TString8 k; k << "NUM|" << key; - return (TCodice_numerazione&)query(k); -} - -const TCodice_numerazione& cached_numerazione(const char * codnum) -{ - HIDDEN TNumerazione_cache __cache_numerazioni; - return __cache_numerazioni.num(codnum); -} - -// calcola il prezzo per le spese -void sppr_calc(const TRectype & rec, const TString & valuta_doc, const real & cambio, real & prezzo) -{ - const TString& sppr_valuta = rec.get("S4"); - - if (!same_values(sppr_valuta, valuta_doc)) - { - const bool prezzo_un = rec.get_char("S6") == 'Q'; - /* Non capisco bene il cambio in gioco ... - if (prezzo_un) - { - TPrice val(prezzo, sppr_valuta); - val.change_value(valuta_doc, cambio); - prezzo = val.get_num(); - } - else - { - TCurrency val(prezzo, sppr_valuta); - val.change_value(valuta_doc, cambio); - prezzo = val.get_num(); - } - */ - // ... ma mi adeguo - TCurrency val(prezzo, sppr_valuta, ZERO, prezzo_un); - val.change_value(valuta_doc, cambio); - prezzo = val.get_num(); - } -} - -/////////////////////////////////////////////////////////// -// Movimento di magazzino -/////////////////////////////////////////////////////////// - -class TMov_mag_doc : public TMov_mag -{ - TString_array _codmagc; - -protected: - virtual const char* codmag_rauto(int r) const; - -public: - void add_magc(const char* magc) - { - CHECKS(magc && strlen(magc) <= 5, "Invalid CODMAG ", magc); - _codmagc.add(magc); - } - void reset_magc(int r) { _codmagc.add("", r - 1); } - void destroy_magc(int r) { _codmagc.destroy(r - 1); } -}; - -const char* TMov_mag_doc::codmag_rauto(int r) const -{ - const char* codmagc = NULL; - const int num_magc = _codmagc.items(); - if (num_magc > 0) // Impossibile trovare un codmagc - { - const TRecord_array& b = body(); - if (r > 0 && r <= b.rows()) // Can't check non-existent rows - { - const char tr = b[r].get_char(RMOVMAG_TIPORIGA); - if (tr == 'D' || tr == 'A') // These are customer's added rows - { - int j = -1; // Indice per reperire il mag. collegato da _codmagc - for (int i = r; i > 0; i--) // Scorre dalla riga r in su e conta quante righe D - if (b[i].get_char(RMOVMAG_TIPORIGA) == 'D') - j++; - if (j >= 0 && j < num_magc) - codmagc = _codmagc.row(j); - } - } - } - return codmagc; -} - -///////////////////////////////////////////////////////////// -// TRiepilogo IVA -///////////////////////////////////////////////////////////// -TRiepilogo_iva& TRiepilogo_iva::copy(const TRiepilogo_iva& a) -{ - _codiva = a.cod_iva(); - _imp = a._imp; - _imp_orig = a._imp_orig; - _imp_spese = a._imp_spese; - _imp_spese_row = a._imp_spese_row; - _iva = a._iva; - _iva_spese = a._iva_spese; - _sconto_perc = a._sconto_perc; - _sconto_imp = a._sconto_imp; - _iva_sconto = a._iva_sconto; - _tipo = a._tipo; - return *this; -} - -TRiepilogo_iva::TRiepilogo_iva(const TCodiceIVA & codiva) : _codiva(codiva) -{ - const TString& t =_codiva.tipo(); - if (t == "VE") - _tipo = 2; else - if (t == "ES") - _tipo = 4; else - if (t == "NI") - _tipo = 8; else - if (t == "NS") - _tipo = 16; - else - _tipo = 1; -} - -/////////////////////////////////////////////////////////// -// Agenti -/////////////////////////////////////////////////////////// -class TAgenti_cache : public TRecord_cache -{ -protected: - virtual TObject* rec2obj(const TRectype& rec) const { return new TAgente(rec);} - -public: - const TAgente& agente(const char* chiave) { return (const TAgente &) get(chiave);} - - TAgenti_cache() : TRecord_cache(LF_AGENTI) {} - virtual ~TAgenti_cache() { } -}; - -HIDDEN TAgenti_cache * _agenti = NULL; - -/////////////////////////////////////////////////////////// -// Documento per vendite -/////////////////////////////////////////////////////////// - -long TDocumento::_firm = -1; -TString4 TDocumento::_codiva_spese; -TString4 TDocumento::_codiva_bolli; -short TDocumento::_has_mag = 3; -short TDocumento::_has_provv = 3; -#ifdef LIVE_STATISTICS -short TDocumento::_has_stat_ven = 3; -#endif - -TCodgiac_livelli * TDocumento::_livelli=NULL; - -HIDDEN TAssoc_array _docs_to_agg; - -void TDocumento::init() -{ - add_file(LF_RIGHEDOC, RDOC_NRIGA); - set_memo_fld("G1"); - - _tipocf = new TRecfield(*this, DOC_TIPOCF); - _codcf = new TRecfield(*this, DOC_CODCF); - _cod_occas = new TRecfield(*this, DOC_OCFPI); - - _sconto = _esenzione = NULL; - _stato_originale = ' '; - _dirty_deny = false; - - check_modules(); -} - -TDocumento::TDocumento() : TMultiple_rectype(LF_DOC) -{ - init(); -} - -TDocumento::TDocumento(const TDocumento & d) - : TMultiple_rectype(LF_DOC) -{ - init(); - copy(d); -} - -TDocumento::TDocumento(char provv, int anno, const char* codnum, long numdoc) - : TMultiple_rectype(LF_DOC) -{ - init(); - if (numdoc > 0) - read(provv, anno, codnum, numdoc); - else - set_key(*this, provv, anno, codnum, 0L); -} - -TDocumento::TDocumento(const TDoc_key& key) - : TMultiple_rectype(LF_DOC) -{ - init(); - const long ndoc = key.ndoc(); - if (ndoc > 0) - read(key.provv(), key.anno(), key.codnum(), ndoc); - else - set_key(*this, key.provv(), key.anno(), key.codnum(), 0L); -} - - -TDocumento::TDocumento(const TRectype& rec) - : TMultiple_rectype(LF_DOC) -{ - init(); - read(rec); -} - -TDocumento::~TDocumento() -{ - delete _tipocf; - delete _codcf; - delete _cod_occas; - - if (_sconto != NULL) delete _sconto; - if (_esenzione != NULL) delete _esenzione; -} - -const TString& TDocumento::codiva_spese() const -{ ((TDocumento *)this)->test_firm(); return _codiva_spese;} - -const TString& TDocumento::codiva_bolli() const -{ ((TDocumento *)this)->test_firm(); return _codiva_bolli;} - -void TDocumento::check_modules() -{ - if (_has_mag < 0 || _has_mag > 1) - { - const TDongle& din = dongle(); - _has_mag = din.active(MGAUT); - _has_provv = din.active(PRAUT); -#ifdef LIVE_STATISTICS - _has_stat_ven = din.active(SVAUT); -#endif - } -} - -void TDocumento::set_variables(TExpression * e) const -{ - CHECK(e, "Null expression"); - const int items = e->numvar(); - for (int i = 0; i < items; i++) - { - const TFieldref field(e->varname(i), LF_DOC); - - switch (field.file()) - { - case LF_CLIFO : - e->setvar(i, clifor().get(field.name())); - break; - case LF_CFVEN : - e->setvar(i, clifor().vendite().get(field.name())); - break; - default: - e->setvar(i, get(field.name())); - break; - } - } -} - -void TDocumento::test_firm() -{ - const long new_firm = prefix().get_codditta(); - - if (_firm != new_firm) - { - TConfig conf(CONFIG_DITTA, "ve"); - _codiva_spese = conf.get("SPINCODIVA"); - _codiva_bolli = conf.get("SPBOCODIVA"); - _firm = new_firm; - } -} - -real TDocumento::spese_incasso(real & imp, int ndec, TTipo_importo t) const -{ - static TArray spese_inc; - static real maxadd, spadd; - - real imp_spese; - const real percentuale = get(DOC_PERCSPINC); - - if (percentuale > ZERO) - { - if (ndec == AUTO_DECIMALS) - ndec = decimals(); - if (spese_inc.objptr(_rim_dir) == NULL) // Inizializzo le spese d'incasso se necessario - { - TConfig conf(CONFIG_STUDIO, "ve"); - for (TTipo_pag p = _rim_dir; p < _nessun_pag; p = TTipo_pag((int)p + 1)) - { - const real r(conf.get("IMPSPINC", "ve", p)); - spese_inc.add(r, p); - } - maxadd = (real)conf.get("MAXADD"); - spadd = (real)conf.get("SPADD"); - } - - // Calcola l'eventuale importo minimo per effetti (solitamente zero) - const TRectype& cfven = clifor().vendite(); - const real impmineff = cfven.get_real(CFV_IMPMINEFF); - - // Somma le spese di ogni singola rata - const TPagamento& pag = ((TDocumento *)this)->pagamento(); - const int nrate = pag.n_rate(); - - for (int i = 0; i < nrate; i++) - { - if (pag.importo_rata(i) >= impmineff) // Se la rata supera il minimo contrattuale - { - const TTipo_pag tp = (TTipo_pag)pag.tipo_rata(i); - - if (spese_inc.objptr(tp) != NULL) - imp_spese += (const real&)spese_inc[tp]; - } - } - - if (imp_spese > ZERO && imp < maxadd) - imp_spese += spadd; - imp_spese = imp_spese * percentuale / CENTO; - - if (t == _lordo || t == _imposta) - { - TString4 codiva_es; iva_esente(codiva_es); - const real iva_spese = TRiga_documento::iva(codiva_es.full() ? (const TString&)codiva_es : codiva_spese()).imposta(imp_spese, ndec); - if (t == _lordo) - imp_spese += iva_spese; - else - if (t == _imposta) - imp_spese = iva_spese; - } - - const real cambio = get(DOC_CAMBIO); - if (!cambio.is_zero()) - { - // Converte le spese nella valuta del documento - imp_spese = change_currency(imp_spese, "", ZERO, get(DOC_CODVAL), cambio, -1); - } - - imp_spese.round(ndec); - } - - return imp_spese; -} - -void TDocumento::iva_esente(TString& codiva_es) const -{ - codiva_es.cut(0); - - const int rows = physical_rows(); - for (int r = 1; codiva_es.empty() && r <= rows; r++) - { - const TRiga_documento& riga = ((TDocumento*)this)->row(r); - const TString4 str_codiva = riga.get(RDOC_CODIVA); - - if (str_codiva.full()) - { - const TCodiceIVA codiva(str_codiva); - const TString& tipoiva = codiva.tipo(); - if (tipoiva.empty()) - break; - if (tipoiva == "NI") - codiva_es = str_codiva; - } - } -} - -real TDocumento::bolli(real & imp, int ndec, TTipo_importo t) const -{ - real tot_bolli; - static TArray sca_bolli; - static TArray imp_bolli; - static real bolli_es; - static real impmin_bolli; - static int nscagl; - - if (get_bool("ADDBOLLI")) - { - if (sca_bolli.objptr(0) == NULL) - { - TConfig conf(CONFIG_STUDIO, "ve"); - - bolli_es = (real) conf.get("BOLLIES", "ve"); - impmin_bolli = (real) conf.get("IMPMINBOLLI", "ve"); - for (nscagl = 0; nscagl < 7; nscagl++) - { - real s(conf.get("SPBOSCA", "ve", nscagl + 1)); - real i(conf.get("SPBOIMP", "ve", nscagl + 1)); - - if (s == ZERO && i == ZERO) - break; - sca_bolli.add(s, nscagl); - imp_bolli.add(i, nscagl); - } - } - if (ndec == AUTO_DECIMALS) - ndec = decimals(); - - TCurrency_documento imp_val(imp); - imp_val.change_to_firm_val(); - real importo = imp_val.get_num(); - - TPagamento & pag = ((TDocumento*)this)->pagamento(); - const int nrate = pag.n_rate(); - real old_bolli = -1.00; - real iva_bolli; - - TCurrency_documento imp_orig_val(imposta()); - imp_orig_val.change_to_firm_val(); - const real imp_orig = imp_orig_val.get_num(); - - TCurrency_documento spese_val(spese()); - spese_val.change_to_firm_val(); - const real sp_orig = spese_val.get_num(); - bool estero = FALSE; // Assumiamo per ora non estero - - TString4 codiva_es; - iva_esente(codiva_es); - - for (int j = 0; j < 5 && tot_bolli+iva_bolli != old_bolli; j++) - { - old_bolli = tot_bolli + iva_bolli; - const real imposte = imp_orig + iva_bolli; - const real imp_spese = sp_orig + tot_bolli - iva_bolli; - const real imponibile = importo - imposte - imp_spese; - tot_bolli = ZERO; - if (!tipo().nota_credito()) - { - real imponibile_esente; - for (int r = physical_rows(); r > 0; r--) - { - const TRiga_documento& riga = ((TDocumento*)this)->row(r); - const TCodiceIVA codiva(riga.get(RDOC_CODIVA)); - - if (codiva.tipo().not_empty()) - imponibile_esente += riga.imponibile(); - } - if (imponibile_esente >= impmin_bolli) - tot_bolli = bolli_es; - } - pag.set_total(imponibile, imposte, imp_spese); - pag.set_rate_auto(); - - for (int i = 0; i < nrate; i++) - { - const TTipo_pag p = (TTipo_pag) pag.tipo_rata(i); - real imp = pag.importo_rata(i); - - switch (p) - { - case _ric_ban: - { - int i; - - for (i = 0; i < nscagl - 1; i++) - if ((real &) sca_bolli[i] >= imp) - break; - if (imp_bolli.items() > 0) - tot_bolli += (real &) imp_bolli[i]; - } - break; - case _tratta: - case _tratta_acc: - { - if (j == 0) // Dobbiamo inizializzare la variabile 'estero' - { - TString16 key; - key.format("%c|%ld", get_char(DOC_TIPOCF), get_long(DOC_CODCF)); - const TRectype& clifo = cache().get(LF_CLIFO, key); - - const TString& stato_iva = clifo.get(CLI_STATOPAIV); - estero = stato_iva.not_empty() && stato_iva != "IT"; - if (!estero) - { - const TString& stato_cf = clifo.get(CLI_STATOCF); - estero = (stato_cf.not_empty() && stato_cf != "IT") || clifo.get_char(CLI_COMCF) == 'Z'; - } - } - real r(imp); - const int ndec = decimals(); - r.ceil(ndec == 0 ? -3 : 0); - if (estero) - r *= 0.009; - else - r *= 0.012; - r.round(ndec == 0 ? -2 : ndec); - tot_bolli += r; - } - break; - case _cessione: - case _paghero: - case _let_cred: - case _rim_dir: - case _rid: - case _bonfico: - default: - break; - } - } - iva_bolli = TRiga_documento::iva(codiva_bolli()).imposta(tot_bolli, ndec); - importo += (tot_bolli + iva_bolli - old_bolli); - } - if (t == _lordo) - tot_bolli += iva_bolli; - else - if (t == _imposta) - tot_bolli = iva_bolli; - - if (in_valuta()) - { - const real cambio = get_real(DOC_CAMBIO); - tot_bolli = change_currency(tot_bolli, "", ZERO, get(DOC_CODVAL), cambio, -1); - } - tot_bolli.round(ndec); - } - - return tot_bolli; -} - -const TString & TDocumento::commessa_principale() const -{ - if (codice_commessa().blank()) - { - const int row = physical_rows(); - - for (int i = 1; i <= rows(); i++) - { - const TRiga_documento &r = ((TRiga_documento &) ((TDocumento *)this)->row(i)); - - if (!r.codice_commessa().blank()) - return r.codice_commessa(); - } - } - return codice_commessa(); -} - -// Controlla se un documento è incluso nelle statistiche definitive -static bool doc_invalidating_stats(const TDocumento& doc) -{ - bool inv = false; - if (dongle().active(SVAUT) && doc.tipo().statistiche()) - { - const TDate datadoc = doc.get(DOC_DATADOC); - if (datadoc.ok()) - { - const TDate datalast = ini_get_string(CONFIG_DITTA, "sv", "UltimoCalcolo"); - inv = datadoc <= datalast; - } - } - return inv; -} - -bool TDocumento::modificabile() const -{ - bool maybe = true; - - const char stato_attuale = stato(); - if (stato_attuale > ' ') - { - const TString& stati_modifica = tipo().stati_iniziali_modifica(); - maybe = stati_modifica.blank() || stati_modifica.find(stato_attuale) >= 0; - - if (maybe && doc_invalidating_stats(*this)) - maybe = false; - } - - return maybe; -} - -bool TDocumento::cancellabile() const -{ - bool maybe = true; - - const char stato_attuale = stato(); - if (stato_attuale > ' ') - { - const TString& stati_cancellazione = tipo().stati_iniziali_cancellazione(); - maybe = stati_cancellazione.blank() || stati_cancellazione.find(stato_attuale) >= 0; - - if (maybe && doc_invalidating_stats(*this)) - maybe = false; - } - return maybe; -} - -bool TDocumento::stampabile() const -{ - const char stato_attuale = stato(); - if (stato_attuale <= ' ') - return true; - - if (stato_attuale == tipo().stato_finale_stampa()) - return false; - - const TString& stati_stampa = tipo().stati_iniziali_stampa(); - return stati_stampa.blank() || stati_stampa.find(stato_attuale) >= 0; -} - -bool TDocumento::bloccato() const -{ - const char stato_attuale = stato(); - if (stato_attuale <= ' ') - return false; - - if (doc_invalidating_stats(*this)) - return true; - - char stato_bloccato = tipo().stato_bloccato(); - if (stato_bloccato <= ' ') - return false; - - return stato_attuale >= stato_bloccato; -} - -bool TDocumento::chiuso() const -{ - if (!tipo().is_scontrino()) - return false; - - const char stato_attuale = stato(); - if (stato_attuale <= ' ') - return false; - - char stato_chiuso = tipo().stato_chiuso(); - if (stato_chiuso <= ' ') - return false; - - return stato_attuale >= stato_chiuso; -} - -// Funzione statica utile a tutti gli utenti di LF_DOC e LF_RIGHEDOC -void TDocumento::set_key(TRectype& rec, char provv, int anno, const char* codnum, long numdoc) -{ - CHECK(provv == 'D' || provv == 'P', "Provvisorio o Definitivo?"); - CHECKD(anno > 1900, "Anno non valido: ", anno); - CHECK(codnum && *codnum, "Codice numerazione nullo"); - CHECKD(numdoc >= 0, "Numero documento non valido ", numdoc); - - rec.put(DOC_PROVV, provv); - rec.put(DOC_ANNO, anno); - rec.put(DOC_CODNUM, codnum); - rec.put(DOC_NDOC, numdoc); -} - -// Funzione statica utile a tutti gli utenti di LF_DOC e LF_RIGHEDOC -void TDocumento::copy_data(TRectype& dst, const TRectype& src) -{ - const bool is_riga = dst.num() == LF_RIGHEDOC; - - // Memorizza tutti i campi chiave - const char provv = dst.get_char(RDOC_PROVV); - const int anno = dst.get_int(RDOC_ANNO); - const TString4 codnum = dst.get(RDOC_CODNUM); - - const long numdoc = dst.get_long(RDOC_NDOC); - const int nriga = is_riga ? dst.get_int(RDOC_NRIGA) : 0; - const long idriga = is_riga ? dst.get_long(RDOC_IDRIGA) : 0; - // Copia tutto il record - dst = src; - // Ripristina tutti i campi chiave - set_key(dst, provv, anno, codnum, numdoc); - dst.init_memo(RECORD_NON_FISICO); - if (is_riga) - { - dst.put(RDOC_NRIGA, nriga); - dst.put(RDOC_IDRIGA, idriga); - dst.zero(RDOC_MOVMAG); - const TString& memo = src.get(RDOC_DESCEST); - dst.put(RDOC_DESCEST, memo); - const TString& g1 = src.get(RDOC_RG1); - dst.put(RDOC_RG1, g1); - ((TRiga_documento&)dst).load_memo(); - } - else - { - dst.zero(DOC_MOVMAG); - dst.zero(DOC_NUMREG); - dst.zero(DOC_NUMREGCA); - dst.put(DOC_NOTE, src.get(DOC_NOTE)); - } -} - -// Funzione statica utile a tutti gli utenti di LF_RIGHEDOC -void TDocumento::copy_data(TRiga_documento& dst, const TRiga_documento& src) -{ - copy_data((TRectype&)dst, (const TRectype&)src); - dst.put(RDOC_CODCMS, src.codice_commessa()); - dst.put(RDOC_FASCMS, src.fase_commessa()); - dst.put(RDOC_CODCOSTO, src.codice_costo()); -} - -void TDocumento::copy_contents(const TDocumento& src, bool copy_header) -{ - if (copy_header) - copy_data(head(), src.head()); - destroy_rows(); - const int rows = src.physical_rows(); - for (int i = 1; i <= rows ; i++) - { - const TRiga_documento& s = src[i]; - TRiga_documento & r = new_row(s.tipo().codice()); - copy_data(r, s); - r.set_original_rdoc_key(s); - } -} - -TRiga_documento& TDocumento::insert_row(int row, const char *tipo) -{ - TRiga_documento& r = (TRiga_documento&)TMultiple_rectype::insert_row(row); - if (tipo && *tipo) - r.set_tipo(tipo); - return r; -} - -TRiga_documento& TDocumento::new_row(const char *tipo) -{ - TRiga_documento& r = (TRiga_documento&)TMultiple_rectype::new_row(); - - r.set_doc(this); - if (tipo && *tipo) - r.set_tipo(tipo); - return r; -} - -void TDocumento::on_read(int err, word lockop) -{ - _cli_for.zero(); - _occas.zero(); - - set_riga_sconto(); - if (is_fattura()) - set_riga_esenzione(); - _stato_originale = stato(); - -#ifdef LIVE_STATISTICS - if (err == NOERR && _has_stat_ven && tipo_valido() && tipo().statistiche() ) - { - const TDoc_key key(head()); - TObject* o = _docs_to_agg.objptr(key); - - const bool is_nota_credito = tipo().nota_credito(); - - if (lockop >= _lock && o == NULL) - { - TStats_agg* st_agg = new TStats_agg; - for (int i = physical_rows(); i > 0; i--) - { - if (is_nota_credito) - st_agg->add(row(i)); - else - st_agg->sub(row(i)); - } - _docs_to_agg.add(key, st_agg, true); - } - else - { - if (lockop == _unlock && o != NULL) - _docs_to_agg.remove(key); - } - } -#endif - - _old_agente.cut(0); - _old_agente1.cut(0); - if (err == NOERR && _has_provv) - { - _old_agente = get(DOC_CODAG); - _old_agente1 = get(DOC_CODAGVIS); - } -} - -int TDocumento::read(TBaseisamfile& f, word op, word lockop) -{ - const int err = TMultiple_rectype::read(f, op, lockop); - on_read(err, lockop); - return err; -} - -int TDocumento::readat(TBaseisamfile& f, TRecnotype nrec, word lockop) -{ - const int err = TMultiple_rectype::readat(f, nrec, lockop); - on_read(err, lockop); - return err; -} - -int TDocumento::read(char provv, int anno, const char* codnum, long numdoc, word op, word lockop) -{ - CHECK(numdoc > 0, "Numero documento nullo."); - zero(); - set_key(*this, provv, anno, codnum, numdoc); - return read(op, lockop); -} - -long TDocumento::renum_ndoc(long numdoc) -{ - if (numdoc <= 0) - { - const char tn = tipo_numerazione(); - const int an = anno(); - const TString4 nu = numerazione(); - numdoc = get_next_key(tn, an, nu); - } - put(DOC_NDOC, numdoc); // Aggiorna testata - TMultiple_rectype::renum_key(); // Aggiorna righe ok - return numdoc; -} - -void TDocumento::set_riga_sconto() -{ - const TString80 sconto(get(DOC_SCONTOPERC)); - - if (!is_real_discount(sconto)) - { - if(_sconto != NULL) - delete _sconto; - _sconto = NULL; - } - else - { - if (_sconto == NULL) - { - static TString4 _tipo_riga_sc; - if (_tipo_riga_sc.empty()) - { - TConfig conf(CONFIG_STUDIO, "ve"); - _tipo_riga_sc = conf.get("TRSCONTI", "ve"); - // Se non esiste il tipo riga lo cerca, lo setta di default ed avvisa - if (_tipo_riga_sc.empty()) - { - _tipo_riga_sc = "08"; - conf.set("TRSCONTI", _tipo_riga_sc); - warning_box(FR("Il tipo riga sconti di testa non risultava impostato.\nL'applicazione userà automaticamente il tipo %s"), (const char*) _tipo_riga_sc); - } - } - _sconto = new TRiga_documento(this, _tipo_riga_sc); - _sconto->put(RDOC_DESCR, TR("Sconto")); - } - _sconto->put(RDOC_SCONTO, sconto); - } -} - -void TDocumento::update_esenzione() -{ - if (clifor().use_lettere()) - { - bool to_update = false; - const TString4 codiva = codesiva(); - for (int i = physical_rows(); !to_update && i > 0; i--) - { - const TString & cod = row(i).get(RDOC_CODIVA); - to_update = cod.full() && cod != codiva; - } - - if (to_update) - for (int i = physical_rows(); i > 0; i--) - { - TRiga_documento & rdoc = row(i); - const TString& cod = rdoc.get(RDOC_CODIVA); - - if (cod.full()) - { - if (codiva.full()) - rdoc.put(RDOC_CODIVA, codiva); - else - { - const TCodiceIVA i(cod); - const bool plafond = i.get_int("S3") > 0; - - if (plafond) - { - TString4 codivarow; - - if (rdoc.is_merce()) - codivarow =cached_article(rdoc.get(RDOC_CODARTMAG)).get(ANAMAG_CODIVA); - else - if (rdoc.is_spese()) - { - const TSpesa_prest s(rdoc.get(RDOC_CODART)); - codivarow = s.cod_iva(); - } - else - if (rdoc.is_prestazione()) - { - TSpesa_prest p(rdoc.get(RDOC_CODART), 'P'); - codivarow = p.cod_iva(); - } - else - if (rdoc.is_risorsa()) - { - TSpesa_prest r(rdoc.get(RDOC_CODART), 'R'); - codivarow = r.cod_iva(); - } - else - if (rdoc.is_attrezzatura()) - { - TSpesa_prest a(rdoc.get(RDOC_CODART), 'A'); - codivarow = a.cod_iva(); - } - if (codivarow.full()) - rdoc.put(RDOC_CODIVA, codivarow); - } - } - } - } - } -} - -void TDocumento::set_riga_esenzione() -{ - TCli_for & c = clifor(); - const TCodiceIVA codes(c.vendite().get(CFV_ASSFIS)); - TString16 v_esenzione; - TString16 v_data_esenzione; - TString16 n_registrazione; - TString16 n_data_registrazione; - - if (codes.codice().full()) - get_protocolli_esenzione(v_esenzione, v_data_esenzione, n_registrazione, n_data_registrazione); - bool esente = codes.tipo().not_empty() && v_esenzione.not_empty() && - v_data_esenzione.not_empty() && n_registrazione.not_empty() && - n_data_registrazione.not_empty(); - if (esente) - { - esente = false; - const TString4 codiva = codes.codice(); - for (int i = physical_rows(); !esente && i > 0; i--) - esente = row(i).get(RDOC_CODIVA) == codiva; - } - - if (!esente) - { - if (_esenzione != NULL) - { - delete _esenzione; - _esenzione = NULL; - } - } - else - { - static TString4 _tipo_riga_es; - static TString80 _des_esenz; - static real _bollo_es; - if (_tipo_riga_es.empty()) - { - TConfig conf(CONFIG_STUDIO, "ve"); - _tipo_riga_es = conf.get("TRESENZ", "ve"); - _bollo_es = (real)conf.get("BOLLIES", "ve"); - if (_tipo_riga_es.empty()) - { - _tipo_riga_es = "05"; - conf.set("TRESENZ", _tipo_riga_es); - warning_box("Il tipo riga esenzione non risultava impostato.\n L'applicazione userà automaticamente il tipo %s", (const char*) _tipo_riga_es); - } - _des_esenz = conf.get("DESESENZ", "ve"); - if (_des_esenz.not_empty()) - _des_esenz.insert(" "); - _des_esenz.insert("Fattura non imponibile"); - } - if (_esenzione == NULL) - _esenzione = new TRiga_documento(this, _tipo_riga_es); - TString d(256); d = _des_esenz; - - d << format(" come da vostra dichiarazione n. %s del %s da noi annotata al n. %s il %s.", - (const char*)v_esenzione, (const char*)v_data_esenzione, - (const char*)n_registrazione, (const char*)n_data_registrazione); - _esenzione->set_descr(d); - } -} - -void TDocumento::dirty_fields() -{ - if (!_dirty_deny) - { - for (TDocumento_variable_field* f = (TDocumento_variable_field*)first_variable_field(); - f != NULL; f = (TDocumento_variable_field*)succ_variable_field()) - f->set_dirty(); - dirty_tabella_iva(); - - if (loaded_rows(LF_RIGHEDOC)) // Se ho già caricato delle righe in memoria - { - TRecord_array& righe = body(LF_RIGHEDOC); - for (int i = righe.last_row(); i > 0; i = righe.pred_row(i)) - { - TRiga_documento& r = (TRiga_documento&)righe[i]; - r.dirty_fields(false); - } - } - _dirty_deny = true; - } -} - -static TToken_string * __key; - -HIDDEN int sort_doc_rows(const TObject** r0, const TObject** r1) -{ - TRiga_documento* row0 = (TRiga_documento*)*r0; - TRiga_documento* row1 = (TRiga_documento*)*r1; - int res = 0; - - TString val0, val1; - TToken_string valist(50,','); - - FOR_EACH_STR_TOKEN(*__key, fldname) - { - int direction = +1; - if (fldname[0] == '-') - { - direction = -1; - fldname.ltrim(1); - } - const int par = fldname.find('('); - if (par > 0) - { - valist = fldname.mid(par+1); - valist.strip("()"); - fldname.cut(par); - } - else - valist.cut(0); - - const TFieldref fld(fldname, 0); - val0 = fld.read(*row0); - val1 = fld.read(*row1); - - switch (row0->type(fld.name())) - { - case _intfld : - case _longfld : - case _realfld : - case _wordfld : - { - const real r0 = val0; - const real r1 = val1; - - if (r0 != r1) - res = (r0 < r1 ? -1 : 1) * direction; - } - break; - case _datefld : - { - const TDate d0 = val0; - const TDate d1 = val1; - - if (d0 != d1) - res = (d0 < d1 ? -1 : 1) * direction; - } - break; - default: - if (val0 != val1) - { - if (valist.full()) - { - int pos0 = valist.get_pos(val0); if (pos0 < 0) pos0 = valist.items(); - int pos1 = valist.get_pos(val1); if (pos1 < 0) pos1 = valist.items(); - res = (pos0 - pos1) * direction; - } - else - res = xvt_str_compare_ignoring_case(val0, val1) * direction; - } - break; - } - if (res != 0) - break; - } - return res; -} - -void TDocumento::sort_rows(const char* key) -{ - __key = new TToken_string(key); - body().sort(sort_doc_rows); - delete __key; - __key = NULL; -} - -static real doc_inventory_qta(const TCausale_magazzino & cau, const TString & codart, const TString & codmag, - const TString & livello, int anno, const real & qta) -{ - const real giac = cached_article_balances(codart).giacenza_anno(codmag, livello, anno); - - real q = qta - giac; - switch (cau.sgn(s_giac)) - { - case 1: break; - case -1: q = -q; break; - default: break; - } - return q; -} - -int TDocumento::write_rewrite(TBaseisamfile & f, bool re) const -{ - TDocumento& myself = *((TDocumento *)this); - const bool new_doc = nuovo() || numero() <= 0; // E' nuovo di zecca! - - if (new_doc) - { - char stato_finale = tipo().stato_finale_inserimento(); - if (stato() == '\0' && stato_finale > ' ') - myself.stato(stato_finale); - } - else - myself._stato_originale = stato(); - - const bool doc_bloccato = bloccato(); - const char stato_doc(stato()); - - int err = NOERR; - - if (!doc_bloccato) - { - if (tipo().spese_aut() && !get_bool(DOC_SPESEUPD)) - { - char name[8] = "CODSP0"; - TString_array spese; - const TRectype& ven_rec = clifor().vendite(); - for (int i = 1; i <= 4; i++) - { - name[5] = '0' + i; - const TString& s = ven_rec.get(name); - if (s.full()) - spese.add(s); - } - myself.update_spese_aut(spese); - } - myself.update_conai(); - myself.update_raee(); - myself.set_row_ids(); - myself.put(DOC_UTENTE, user()); - myself.put(DOC_DATAAGG, TDate(TODAY)); - - const bool check_movmag = _has_mag && tipo().mov_mag(); - if (check_movmag) - { - const bool do_movmag = tipo().stato_with_mov_mag(stato_doc) && get(DOC_CAUSMAG).full(); - long num_movmag = get_long(DOC_MOVMAG); - bool diff_inv = get_bool("DIFFINV"); - - TMov_mag_doc mov; - TLocalisamfile m(LF_MOVMAG); - mov.zero(); - if (!new_doc && do_movmag && num_movmag <= 0) - { - m.setkey(6); - m.zero(); - m.put(MOVMAG_DOCPROVV, myself.get(DOC_PROVV)); - m.put(MOVMAG_ANNODOC, myself.anno()); - m.put(MOVMAG_CODNUM, myself.numerazione()); - m.put(MOVMAG_NUMDOC, myself.numero()); - if (m.read(_isequal) == NOERR) - { - num_movmag = m.get_long(MOVMAG_NUMREG); - myself.put(DOC_MOVMAG, num_movmag); - } - m.setkey(1); - m.zero(); - } - if (do_movmag && num_movmag <= 0) - { - err = mov.write(m); - if (err != NOERR) - return err; - num_movmag = mov.get_long(MOVMAG_NUMREG); - myself.put(DOC_MOVMAG, num_movmag); - } - if (num_movmag > 0) - { - const bool scarica_residuo = tipo().scarica_residuo(); - - mov.put(MOVMAG_NUMREG, num_movmag); - while (mov.read(m, _isequal, _testandlock) == _islocked) - message_box("Movimento di magazzino n. %ld in uso da parte di un'altro utente", num_movmag); - if (do_movmag) - { - TRecord_array & b = mov.body(); - const int mag_rows = mov.rows(); - int i; - for (i = mag_rows; i > 0; i--) - { - TRectype & r = b[i]; - if (r.get_char(RMOVMAG_TIPORIGA) == riga_dadocumento) - { - b.destroy_row(i); - if (b.exist(i + 1) && - b[i + 1].get_char(RMOVMAG_TIPORIGA) == riga_automatica) - b.destroy_row(i + 1); - } - else - if (r.get_bool(RMOVMAG_ESPLOSA)) - b.destroy_row(i); - } - b.pack(); - - const TDate d(get(DOC_DATADOC)); - TString4 codes; codes.format("%04d", mov.codice_esercizio(d)); - mov.put(MOVMAG_ANNOES, codes); - mov.put(MOVMAG_DATAREG, d); - mov.put(MOVMAG_DATACOMP, d); - mov.put(MOVMAG_DOCPROVV, get(DOC_PROVV)); - mov.put(MOVMAG_ANNODOC, get(DOC_ANNO)); - mov.put(MOVMAG_CODNUM, get(DOC_CODNUM)); - long numdoc = get_long(DOC_NDOC); - if (numdoc <= 0L) - numdoc = myself.renum_ndoc(numdoc); - - mov.put(MOVMAG_NUMDOC, numdoc); - const long ex_numdoc = get_long(DOC_NUMDOCRIF); - if (ex_numdoc == 0) - { - mov.put(MOVMAG_EXNUMDOC, numdoc); - mov.put(MOVMAG_EXDATADOC, d); - } - else - { - mov.put(MOVMAG_EXNUMDOC, ex_numdoc); - const TDate ex_d(get("DATADOCRIF")); - mov.put(MOVMAG_EXDATADOC, ex_d); - } - mov.put(MOVMAG_CATVEN, get("CATVEN")); - mov.put(MOVMAG_CODLIST, get("CODLIST")); - mov.put(MOVMAG_CODCONT, get("CODCONT")); - mov.put(MOVMAG_CODCAMP, get("CODCAMP")); - mov.put(MOVMAG_CODCAUS, get("CAUSMAG")); - const TString4 codnum(numerazione()); - - mov.put(MOVMAG_DESCR, format("%s %s n. %ld del %s", (const char *) tipo().get("S1"),(const char *)codnum, numdoc, (const char *) d.string())); - mov.put(MOVMAG_TIPOCF, get("TIPOCF")); - mov.put(MOVMAG_CODCF, get("CODCF")); - if (ini_get_bool(CONFIG_DITTA, "mg", "MOV_INDSPED")) - mov.put(MOVMAG_CODINDSP, get(DOC_CODINDSP)); - - int j = 1; - real cambio = ZERO; - - if (get(DOC_CODVAL).not_empty()) - cambio = get_real(DOC_CAMBIO); - if (cambio == ZERO) - cambio = 1.0; - const TString8 cod_caus(mov.get(MOVMAG_CODCAUS)); - const TCausale_magazzino & caus = cached_causale_magazzino(cod_caus); - const bool esplodente = caus.esplodente(); - const bool scarica_alt = caus.scarica_alternativi(); - TString8 cod_caus_riga; - TDistinta_tree dist; - TCodice_articolo codart; - const int anno = get_int(DOC_ANNO); - - for (i = 1; i <= physical_rows(); i++) - { - TRiga_documento & r = myself.row(i); - const bool articolo = r.is_articolo(); - bool valid_row = articolo; - - cod_caus_riga = r.get(RDOC_CAUSMAG); - if (articolo) - codart = r.get(RDOC_CODARTMAG); - else - { - codart = r.get(RDOC_CODART); - if (codart.full() && (cod_caus_riga.full() ? cached_causale_magazzino(cod_caus_riga).esplodente() : esplodente)) - valid_row = dist.set_root(codart); - } - if (valid_row) - { - long r_num = r.get_long(RDOC_MOVMAG); - if (r_num == 0) - { - r_num = num_movmag; - r.put(RDOC_MOVMAG, r_num); - } - - real qta = scarica_residuo ? r.qtaresidua_mag(): r.quantita_mag(); - - if (r_num == num_movmag && !qta.is_zero()) - { - TRectype & rm = mov.insert_row(j++); - - mov.add_magc(r.get(RDOC_CODMAGC)); - - rm.put(RMOVMAG_IMPIANTO, r.get(RDOC_IMPIANTO)); - rm.put(RMOVMAG_LINEA, r.get(RDOC_LINEA)); - const TString8 codmag = r.get(RDOC_CODMAG); - rm.put(RMOVMAG_CODMAG, codmag); - if (articolo && (cod_caus_riga.full() ? cached_causale_magazzino(cod_caus_riga).scarica_alternativi() : scarica_alt)) - { - const TRectype art = cache().get(LF_ANAMAG, codart); - const TString & alt = art.get(ANAMAG_CODARTALT); - - if (alt.full()) - codart = alt; - } - rm.put(RMOVMAG_CODART, codart); - const TString livello = r.get(RDOC_LIVELLO); - rm.put(RMOVMAG_LIVGIAC, livello); - rm.put(RMOVMAG_UM, r.get(RDOC_UMQTA)); - - if (diff_inv) - qta = doc_inventory_qta((cod_caus_riga.full() ? cached_causale_magazzino(cod_caus_riga) : caus), codart, - codmag, livello, anno, qta); - - rm.put(RMOVMAG_QUANT, qta); - - TCurrency_documento prezzo(r.prezzo(true, FALSE), *this, true); - - prezzo.change_to_firm_val(); - rm.put(RMOVMAG_PREZZO, prezzo.get_num()); - rm.put(RMOVMAG_CODCAUS, cod_caus_riga); - rm.put(RMOVMAG_TIPORIGA, (char) riga_dadocumento); - } - - if (main_app().has_module(LVAUT)) - { - const TString & codcauslav = r.get(RDOC_CODAGG1); - const TRectype & caulav = cache().get("&LVCAU", codcauslav); - if (!caulav.empty()) - { - if (!qta.is_zero() && (j > 1)) - { - const TString & causcons = caulav.get("S2"); - - if (causcons.full()) - { - mov[LF_RMOVMAG][j - 1].put(RMOVMAG_CODCAUS, causcons); - mov[LF_RMOVMAG][j - 1].put(RMOVMAG_CODMAG, r.get(RDOC_CODMAGC)); - mov.reset_magc(j - 1); - } - else - { - mov.destroy_row(--j, true); - mov.destroy_magc(j); - } - } - - const real qtarit = r.get(RDOC_QTAGG1); - const TString & causrit = caulav.get("S1"); - - if (r_num == num_movmag && !qtarit.is_zero() && causrit.full()) - { - TRectype & rm = mov.insert_row(j++); - - mov.add_magc(""); - rm.put(RMOVMAG_IMPIANTO, r.get(RDOC_IMPIANTO)); - rm.put(RMOVMAG_LINEA, r.get(RDOC_LINEA)); - rm.put(RMOVMAG_CODMAG, r.get(RDOC_CODMAG)); - if (articolo && (causrit.full() ? cached_causale_magazzino(causrit).scarica_alternativi() : scarica_alt)) - { - const TRectype art = cache().get(LF_ANAMAG, codart); - const TString & alt = art.get(ANAMAG_CODARTALT); - - if (alt.full()) - codart = alt; - } - rm.put(RMOVMAG_CODART, codart); - rm.put(RMOVMAG_LIVGIAC, r.get(RDOC_LIVELLO)); - rm.put(RMOVMAG_UM, r.get(RDOC_UMQTA)); - rm.put(RMOVMAG_QUANT, qtarit); - rm.put(RMOVMAG_CODCAUS, causrit); - rm.put(RMOVMAG_TIPORIGA, (char) riga_dadocumento); - } - } - } - } - - const TString & indetr = r.get(RDOC_TIPODET); - - if (indetr.full()) - { - const TRectype & det = cache().get("%DET", indetr); - - if (!det.empty() && !det.get_bool("FPC")) - { - TTable tab("%DET"); - - tab.curr() = det; - tab.curr().put("FPC", "X"); - tab.rewrite(); - } - } - - } - mov.rewrite(m); - } - else - { - mov.remove(m); - for (int i = physical_rows(); i > 0; i--) - { - TRiga_documento & r = myself.row(i); - r.zero(RDOC_MOVMAG); - } - myself.zero(DOC_MOVMAG); - } - } - } - } - - { - TLocalisamfile anamag(LF_ANAMAG); - TLocalisamfile codalt(LF_CODCORR); - codalt.setkey(2); - bool docevaso = true; - const TDate datacons(get_date(DOC_DATACONS)); - const TString80 codcms(get(DOC_CODCMS)); - const TString80 fascms(get(DOC_FASCMS)); - const TString80 codcos(get(DOC_CODCOSTO)); - - for (int i = physical_rows(); i > 0; i--) - { - TRiga_documento& r = myself.row(i); - if ((r.is_merce() || r.is_omaggio()) && !r.is_checked()) - { - if (r.get(RDOC_CODARTMAG) == NULL_CODART) - r.put(RDOC_CODARTMAG, ""); - else - { - const TString & codart = r.get("CODART"); - anamag.put("CODART", codart); - if (anamag.read() == NOERR) - r.put("CODARTMAG", codart); - else - { - codalt.put("CODARTALT", codart); - if (codalt.read() == NOERR) - r.put("CODARTMAG", codalt.get("CODART")); - } - r.checked(); - } - } - if (r.is_evadibile() && datacons.ok()) // on 27-9-2013 was if (r.is_evadibile() && is_ordine()) - { - docevaso &= r.is_evasa(); - const TDate dcons = r.get_date(RDOC_DATACONS); - if (!dcons.ok()) - r.put(RDOC_DATACONS, datacons); - } - - /* dal 27-9-2013 considero singolarmente i campi di analitica replicati sulle righe - if (r.get(RDOC_CODCMS).blank() && r.get(RDOC_FASCMS).blank() && r.get(RDOC_CODCOSTO).blank()) - { - r.put(RDOC_CODCMS, codcms); - r.put(RDOC_FASCMS, fascms); - r.put(RDOC_CODCOSTO, codcos); - } - */ - if (r.get(RDOC_CODCMS).blank()) r.put(RDOC_CODCMS, codcms); - if (r.get(RDOC_FASCMS).blank()) r.put(RDOC_FASCMS, fascms); - if (r.get(RDOC_CODCOSTO).blank()) r.put(RDOC_CODCOSTO, codcos); - } - if (is_ordine()) - ((TDocumento *)this)->put(DOC_DOCEVASO, docevaso); // Tutte le righe evase -> doc evaso - } // Almeno una riga aperta -> doc aperto - - err = TMultiple_rectype::write_rewrite(f, re); - - if (!doc_bloccato && err == NOERR) - { - if (clifor().occasionale()) - { - if (get("OCFPI").not_empty()) - { - TLocalisamfile o(LF_OCCAS); - TOccasionale & occ = occas(); - - err = occ.write(o); - if (err == _isreinsert) - err = occ.rewrite(o); - } - } - if (_has_provv && tipo().provvigioni() && tipo().stato_provvigioni() <= stato()) - myself.update_provvigioni(false); - -#ifdef LIVE_STATISTICS - if (_has_stat_ven && tipo().statistiche()) - { - const TDoc_key key(myself.head()); - TStats_agg* st_agg = (TStats_agg*)_docs_to_agg.objptr(key); - const bool is_nota_credito = tipo().nota_credito(); - - if (st_agg == NULL) - { - st_agg = new TStats_agg; - _docs_to_agg.add(key, st_agg, true); - } - - for (int i = physical_rows(); i > 0; i--) - { - if (is_nota_credito) - st_agg->sub(myself.row(i)); - else - st_agg->add(myself.row(i)); - } - st_agg->update(); - for (int i = physical_rows(); i > 0; i--) - { - if (is_nota_credito) - st_agg->add(myself.row(i)); - else - st_agg->sub(myself.row(i)); - } - } - -#endif - } - return err; -} - -// eliminare anche il mov di mag. ?????? -int TDocumento::remove(TBaseisamfile& f) const -{ - if (!cancellabile() && !delete_box("Documento non cancellabile.\nSi desidera continuare ugualmente?")) - return NOERR; - const bool check_movmag = _has_mag && tipo().mov_mag(); - const bool doc_bloccato = bloccato(); - - if (check_movmag) - { - const long num = get_long("MOVMAG"); - - if (num > 0) - { - TMov_mag_doc mov; - TLocalisamfile m(LF_MOVMAG); - mov.put(MOVMAG_NUMREG, num); - while (mov.read(m, _isequal, _testandlock) == _islocked) - message_box("Movimento di magazzino in uso da parte di un'altro utente"); - if (doc_bloccato) - { - const int rows = mov.rows(); - for (int i= 1; i <= rows; i++) - mov.body()[i].zero(RMOVMAG_TIPORIGA); - mov.rewrite(m); - } - else - mov.remove(m); - } - } - if (!doc_bloccato) - { -#ifdef LIVE_STATISTICS - if (_has_stat_ven && tipo().statistiche()) - { - const TDoc_key key(head()); - TStats_agg* st_agg = (TStats_agg*)_docs_to_agg.objptr(key); - if (st_agg != NULL) - { - st_agg->update(); - _docs_to_agg.remove(key); - } - } -#endif - if (_has_provv && tipo().provvigioni()) - { - TDocumento& myself = *((TDocumento *)this); - myself.update_provvigioni(true); - } - } - return TMultiple_rectype::remove(f); -} - -int TDocumento::decimals(bool price) const -{ - const TString4 codval(get(DOC_CODVAL)); - const TExchange exc(codval); - const int ndec = exc.decimals(price); - return ndec; -} - -void TDocumento::flush_rows() -{ - remove_body(LF_RIGHEDOC); -} - -void TDocumento::calc_provvigione(TProvvigioni_agente & provv, const TString & key, bool first, bool generata) -{ - const int anno = TDocumento::anno(); - const TString4 codnum = numerazione(); - const long ndoc = numero(); - const TDate datadoc(data()); - - while (provv.read(key, anno, codnum, ndoc) == _islocked) // Legge le provvigioni per questo documento - if (!yesno_box("Dati agente %s in uso da un altro utente. Riprovare?", (const char *) key)) - return ; - - const real change(cambio()); - const real perc = provv.perc_fatt(); - TCurrency_documento tot_doc(totale_doc(), *this); - TCurrency_documento tot_netto(totale_netto(), *this); - TCurrency_documento tot_provv(provvigione(first), *this); - TCurrency_documento provv_fat((tot_provv.get_num() / CENTO) * perc, *this); // Provvigione sul fatturato (rata 0) - TCurrency_documento provv_pag = tot_provv - provv_fat; // Provvigione sul pagato (da suddivere secondo il pagamento) - const bool valuta = in_valuta(); - - // Calcolo rate per provvigioni e documento - TPagamento& pag1 = pagamento(); // Per rate documento - TPagamento* pag2 = new TPagamento(pag1.code(), datadoc.string()); // Per rate documento - - // Rilegge il pagamento, nel caso in cui venga chiamata la scrittura del documento - // corrente dopo che è stata effettuata una contabilizzazione; la contabilizzazione - // nel caso di anticipo aggiunge una rata in più - if (pag1.n_rate() > pag2->n_rate()) - pag1.read(); - - TCurrency_documento totspese(spese(), *this); - TCurrency_documento totimposte(imposta(), *this); - TCurrency_documento totimponibili(tot_doc - totimposte - totspese); - TCurrency_documento anticipo(get_real(DOC_IMPPAGATO), *this); - - if (is_nota_credito()) // Se il documento e' una nota di credito, cambia segno - { - tot_doc = -tot_doc; - tot_netto = -tot_netto; - tot_provv = -tot_provv; - provv_fat = -provv_fat; - provv_pag = -provv_pag; - totspese = -totspese; - totimposte = -totimposte; - totimponibili = -totimponibili; - } - - // Considera l'anticipo, come in contabilizzazione ed in generazione effetti - // - // Un anticipo su di una nota di credito non dovrebbe comunque mai esistere, non ha senso. - // Se esiste è un errore in inserimento da parte del cliente. - if ((double)anticipo.get_num() < abs(tot_doc.get_num())) - { - TGeneric_distrib d(anticipo.get_num(), decimals()); - - d.add(totimponibili.get_num()); - d.add(totimposte.get_num()); - d.add(totspese.get_num()); - - const TCurrency_documento pagtotimponibili(totimponibili.get_num() - d.get(), *this); - const TCurrency_documento pagtotimposte(totimposte.get_num() - d.get(), *this); - const TCurrency_documento pagtotspese(totspese.get_num() - d.get(), *this); - - TCurrency zero(ZERO); - if (valuta) - { - TCurrency_documento val2(pagtotimposte); val2.change_to_firm_val(); - TCurrency_documento val3(pagtotspese); val3.change_to_firm_val(); - TCurrency_documento val1(tot_doc); val1.change_to_firm_val(); val1 -= val2 - val3; - pag1.set_total_valuta(pagtotimponibili, pagtotimposte, pagtotspese, val1, val2, val3); - TCurrency_documento provv_pag_base(provv_pag) ; provv_pag_base.change_to_firm_val(); - pag2->set_total_valuta(provv_pag, zero, zero, provv_pag_base, zero, zero); - } - else - { - pag1.set_total(pagtotimponibili, pagtotimposte, pagtotspese); - pag2->set_total(provv_pag, zero, zero); - } - pag1.set_rate_auto(); - pag2->set_rate_auto(); - } - else - { - pag1.zap_rate(); - pag2->zap_rate(); - } - - const bool is_anticipo = anticipo.get_num() > ZERO; - - if (is_anticipo) - { - pag1.add_rata(); - TDate first_scad(pag1.data_rata(0)); - - if (datadoc == first_scad) - pag1.set_datarata(0, ++first_scad); - for (int k=pag1.n_rate()-1; k>0; k--) - pag1.rata(k) = pag1.rata(k-1); - - if (anticipo >= tot_doc) - anticipo = tot_doc; - - TCurrency_documento anticipo_base(anticipo); anticipo_base.change_to_firm_val(); - - pag1.set_rata(0, valuta ? anticipo.get_num() : ZERO, anticipo_base.get_num(), datadoc, 1, "", FALSE); - } - - // Crea le nuove rate provvigionali - const bool isnew = provv.items() == 0; // Il documento non ha righe provvigionali - TRate_doc& rd = provv.rate(anno, codnum, ndoc, isnew); - - // A questo punto rd e' vuoto: settiamo i dati del documento: - const int ndec = tot_doc.decimals(); - - TToken_string t; - t.add(anno); t.add(codnum); t.add(ndoc); t.add(datadoc.string()); - t.add(tot_doc.get_num().string(-1, ndec)); - t.add(tot_provv.get_num().string(-1, ndec)); - t.add(tot_netto.get_num().string(-1, ndec)); - t.add(codcf()); - t.add(TDocumento::valuta()); - t.add(change.string()); - t.add(get(DOC_DATACAMBIO)); - rd.set(t); - - // Adesso si possono aggiungere le rate (per quelle gia' esistenti sostituisce solo alcuni valori) - // - Rata 0 : importo rata = 0; importo provvigione = provvigione all'atto della fattura (percentuale sugli agenti) - // data scadenza viene settata uguale alla data documento - // la provvigione rimanente va suddivisa in rate a seconda del codice pagamento - // Nel caso si ha un anticipo documento, l'importo della rata non sarà 0 ma eguale all'anticipo stesso - // Se poi abbiamo il caso in cui l'anticipo paga completamente il documento - // non avremo alcuna rata e tutto l'importo della provvigione del doc. andrà comunque - // sulla rata 0, anche se la provvigione sul fatturato è 0 (% a 0) - - const int nrate = pag1.n_rate(); - - if (nrate == 1 && is_anticipo) // significa che l'anticipo paga tutto ora, quindi provv_fat vale tutta la provvigione del documento - provv_fat = tot_provv; - - const bool first_rata_ok = !provv_fat.is_zero(); - - // Impostazione prima rata solo se la provvigione sul fatturato è diversa da 0 - if (first_rata_ok) - { - TRata& rt = rd.row(0,true); - rt.set_rata(0); rt.set_datascad(datadoc); rt.set_tipopag(1); - rt.set_imprata(anticipo.get_num()); rt.set_impprovv(provv_fat.get_num()); - rt.set_generata(generata); - } - - // Setta le rate rimanenti - int i; - - for (i = 1; i <= nrate; i++) - { - if (i == nrate && is_anticipo) - break; - - const int index = is_anticipo ? i : i - 1; - TRata& rt = rd.row(first_rata_ok ? i : i - 1, true); - rt.set_rata(i); - rt.set_datascad(pag1.data_rata(index)); - rt.set_tipopag(pag1.tipo_rata(index)); - rt.set_imprata(pag1.importo_rata(index,valuta ? true : FALSE)); - rt.set_impprovv(pag2->importo_rata(i-1,valuta ? true : FALSE)); - rt.set_generata(generata); - } - - // Rimuove eventuali righe in eccesso - const int rd_items = rd.items(); // Rate precedenti - for (i = first_rata_ok ? nrate+1 : nrate; i < rd_items; i++) - rd.remove_rata(i); - delete pag2; -} - -int TDocumento::update_provvigione(bool remove, const bool first) -{ - TProvvigioni_agente provv; - const TString8 old = first ? _old_agente : _old_agente1; - const TString8 agente = first ? get(DOC_CODAG) : get(DOC_CODAGVIS); - const int anno = TDocumento::anno(); - const TString & codnum = numerazione(); - const long ndoc = numero(); - const TDate datadoc(data()); - int err = NOERR; - - if (remove || old != agente) - { - while (provv.read(old, anno, codnum, ndoc) == _islocked) // Legge le provvigioni per questo documento - if (!yesno_box("Dati agente %s in uso da un altro utente. Riprovare?", (const char *) old)) - return err; - if (err != NOERR) - return err; - err = provv.remove(); - if (remove) - return err; - } - - if (agente.blank()) - return NOERR; - calc_provvigione(provv, agente, first); - return provv.write(); -} - -int TDocumento::update_provvigioni(bool remove) -{ - int err; - - if ((err = update_provvigione(remove)) == NOERR) - err = update_provvigione(remove, false); - return err; -} - -bool TDocumento::in_valuta() const -{ - const TString& val = valuta(); - return is_true_value(val); -} - -TCodgiac_livelli & TDocumento::livelli() const -{ - if (_livelli == NULL) - _livelli = new TCodgiac_livelli(); - return *_livelli; -} - -TRiga_documento & TDocumento::row(int index) -{ - TRecord_array & b = body(); - const int nrows = b.last_row(); - TRiga_documento * r = NULL; - - if (index <= nrows) - { -#ifdef DBG - if (!b.exist(index)) - { - const long ndoc = get_long(DOC_NDOC); - const int anno = get_int(DOC_ANNO); - const char* codnum = get(DOC_CODNUM); - error_box("Riga documento %d non esistente nel documento %d %s %ld", index, anno, codnum, ndoc); - insert_row(index, "05"); - } -#endif - r = &((TRiga_documento &) b.row(index, FALSE)); - } - else - { - CHECKD((index == nrows + 1 && (_sconto != NULL || _esenzione != NULL)) || (index == nrows + 2 && _sconto != NULL && _esenzione != NULL), - "Riga documento non esistente ", index); - if (index == nrows + 1) - { - r = _sconto != NULL ? _sconto : _esenzione; - } else - if (index == nrows + 2) - r = _esenzione; - } - return *r; -} - -const TRiga_documento& TDocumento::physical_row(int index) const -{ - TRecord_array& b = body(); - return (TRiga_documento&)b.row(index, false); -} - -long TDocumento::get_next_key(char provv, int anno, const char* codnum) const -{ - long n = 0; - - TLocalisamfile doc(LF_DOC); - TRectype& curr = doc.curr(); - set_key(curr, provv, anno, codnum, 9999999L); - - const int err = doc.read(_isgreat); - - if (err != _isemptyfile) - { - if (err == NOERR) - doc.prev(); - if (curr.get_char(DOC_PROVV) == provv && - curr.get_int(DOC_ANNO) == anno && - curr.get(DOC_CODNUM) == codnum) - n = curr.get_long(DOC_NDOC); - } - - n++; - return n; -} - -const TTipo_documento& TDocumento::tipo() const -{ - TString4 tipodoc(get(DOC_TIPODOC)); -#ifdef DBG - if (tipodoc.blank()) // Test necessario per lavorare anche su dati rovinati - { - const TCodice_numerazione& codnum = codice_numerazione(); - tipodoc = codnum.tipo_doc(0); - yesnofatal_box("Tipo documento nullo su %d %s %ld\nforzato a %s", - get_int(DOC_ANNO), (const char*)get(DOC_CODNUM), get_long(DOC_NDOC), (const char*)tipodoc); - ((TDocumento*)this)->set_tipo(tipodoc); - } -#endif - return cached_tipodoc(tipodoc); -} - -const TCodice_numerazione& TDocumento::codice_numerazione(const char * numerazione) -{ - return cached_numerazione(numerazione); -} - - -const TCodice_numerazione& TDocumento::codice_numerazione() const -{ - return cached_numerazione(numerazione()); -} - -bool TDocumento::raggruppabile(const TDocumento& doc, TToken_string& campi) const -{ - bool ok = raggruppabile() && doc.raggruppabile(); - if (ok) - { - TString campo; - for (const char* c = campi.get(0); c && ok; c = campi.get()) - { - if (strncmp(c, "CODABI", 6) == 0 || strncmp(c, "CODCAB", 6) == 0) - { - long cod = get_long(c); - ok &= (cod == doc.get_long(c)); - } - else - { - campo = get(c); - ok &= campo == doc.get(c); - } - } - } - return ok; -} - -void TDocumento::set_fields(TAuto_variable_rectype & rec) -{ - if (tipo_valido()) - { - TTipo_documento& tipo_doc = (TTipo_documento&)tipo(); // first_formula() is NOT const - const TString& tot_doc = tipo_doc.totale_doc(); - - for (const TFormula_documento* f = tipo_doc.first_formula(); f; f = tipo_doc.succ_formula()) - { - TExpr_documento* exp = f->expr(); - if (exp != NULL) // Puo' succedere che sia NULL con dati incoerenti - { - if (tot_doc == f->name()) - { - TString16 tot_doc_netto(tot_doc); - tot_doc_netto.insert("_"); - - const TFixed_string netto_def(exp->string()); - TExpr_documento netto_exp(netto_def, _numexpr, this); - - add_field(new TDocumento_variable_field(tot_doc_netto, netto_exp)); - - if (netto_def == "IMPONIBILI()+IMPOSTE()") - { - TExpr_documento tot_exp("IMPONIBILI(1)+IMPOSTE(1)", _numexpr, this); - add_field(new TDocumento_variable_field(tot_doc, tot_exp)); - } - else - { - TExpr_documento tot_exp(format("%s + _BOLLI(%s)", (const char *) tot_doc_netto, - (const char*)tot_doc_netto), _numexpr, this); - add_field(new TDocumento_variable_field(tot_doc, tot_exp)); - } - } - else - { - exp->set_doc(this); - add_field(new TDocumento_variable_field(f->name(), *exp)); - } - } - } - - for (TVariable_field* src_field = rec.first_variable_field(); - src_field != NULL; src_field = rec.succ_variable_field()) - { - const char* fieldname = src_field->name(); - if (src_field->expression() == NULL) - put(fieldname, rec.get(fieldname)); - } - } -} - -real TDocumento::imponibile(bool spese, int ndec) const -{ - real val; - if (physical_rows() > 0) - { - TAssoc_array& table = ((TDocumento*)this)->tabella_iva(); - table.restart(); - for (TRiepilogo_iva* ri = (TRiepilogo_iva*)table.get(); ri != NULL; ri = (TRiepilogo_iva*)table.get()) - val += ri->imponibile(spese); - if (ndec == AUTO_DECIMALS) - ndec = decimals(); - val.round(ndec); - } - return val; -} - -void TDocumento::calc_iva_fattura_commerciale() -{ - // Calcolo iva per fatture commerciali: - // 1) effettua la sommatoria di tutti i real per ogni elementi di _tabella_iva in un TRiepilogo_iva unico - // 2) azzera _tabella_iva - // 3) scorpora in % a seconda di cio' che e' indicato in configurazione, e mette i nuovi elementi in _tabella_iva - // 4) per ogni nuovo elemento di _tabella_iva, ricalcola la relativa imposta. - TAssoc_array & table = _tabella_iva; - TRiepilogo_iva t; - static TString_array tabella_ripartizione; - const int ndec = decimals(); - - if (tabella_ripartizione.items() == 0) - { - TConfig cnf(CONFIG_STUDIO, "ve"); - for (int k = 1; k <= MAX_IVA_SLICES; k++) - { - TToken_string* tt = new TToken_string(); - tt->add(cnf.get("EXCLUDE_PERC", NULL, k)); - tt->add(cnf.get("EXCLUDE_IVA", NULL, k)); - tabella_ripartizione.add(tt); - } - } - - // 1) - table.restart(); - for (TRiepilogo_iva * ri = (TRiepilogo_iva *) table.get(); ri != NULL; - ri = (TRiepilogo_iva *) table.get()) - { - t.imp() += ri->imp(); - t.imp_spese() += ri->imp_spese(); - t.imp_spese_row() += ri->imp_spese_row(); - t.iva_spese() += ri->iva_spese(); - t.iva_sconto() += ri->iva_sconto(); - t.sconto_perc() += ri->sconto_perc(); - t.sconto_imp() += ri->sconto_imp(); - } - // 2) - table.destroy(); - - // 3) - TArray tda; - - tda.add(new TDistrib(t.imp(), ndec)); - tda.add(new TDistrib(t.imp_spese(), ndec)); - tda.add(new TDistrib(t.imp_spese_row(), ndec)); - tda.add(new TDistrib(t.iva_spese(), ndec)); - tda.add(new TDistrib(t.iva_sconto(), ndec)); - tda.add(new TDistrib(t.sconto_perc(), ndec)); - tda.add(new TDistrib(t.sconto_imp(), ndec)); - - int k; - - for (k = 0; k < MAX_IVA_SLICES; k++) - for (int j = 0; j < 7; j++) - { - const real p (tabella_ripartizione.row(k).get(0)); - TDistrib& td = (TDistrib&) tda[j]; - td.add(p); - } - - // 4) - for (k = 0; k < MAX_IVA_SLICES; k++) - { - TString16 cod(tabella_ripartizione.row(k).get(1)); - cod.trim(); - if (cod.empty()) - continue; - - const TCodiceIVA civa(cod); - TRiepilogo_iva * rp = (TRiepilogo_iva *) table.objptr(cod); - if (rp == NULL) - { - rp = new TRiepilogo_iva(civa); - table.add(cod, rp); - } - - for (int j = 0; j < tda.items(); j++) - { - TDistrib& td = (TDistrib&)tda[j]; - const real rr = td.get(); - - switch (j) - { - case 0: - rp->imp() = rr; - rp->iva() = civa.imposta(rr, ndec); - break; - case 1: - rp->imp_spese() = rr; - break; - case 2: - rp->imp_spese_row() = rr; - break; - case 3: - rp->iva_spese() = rr; - break; - case 4: - rp->iva_sconto() = rr; - break; - case 5: - rp->sconto_perc() = rr; - break; - case 6: - rp->sconto_imp() = rr; - break; - default: - break; - } - } - } -} - -void TDocumento::update_tabella_iva(bool solo_imponibili) -{ - static bool __solo_imponibili = false; - const int items = rows(); - TAssoc_array & table = _tabella_iva; - - if (items == 0) - { - table.destroy(); - return; - } - if (__solo_imponibili != solo_imponibili) - { - table.destroy(); - __solo_imponibili = solo_imponibili; - } - - if (table.items() > 0) - { - if (items == 0) - table.destroy(); - return; - } - - const bool doc_al_lordo = tipo().calcolo_lordo(); - const int ndec = decimals(); - - // Test di consistenza solitamente inutile, ma fallisce in ve1 -0 L - const int r1 = body(LF_RIGHEDOC).first_row(); - if (r1 > 0 && row(r1).get_int(RDOC_NRIGA) != r1) - remove_body(LF_RIGHEDOC); // Forza il caricamento ex-novo delle righe - - FOR_EACH_PHYSICAL_RDOC(*this, j, rowptr) - { - const TRiga_documento& r = *rowptr; - if (!r.is_sconto() && !r.is_descrizione()) - { - const TCodiceIVA & iva = r.iva(); - if (iva.ok()) - { - const TString & cod = iva.codice(); - TRiepilogo_iva* aliquota = (TRiepilogo_iva*)table.objptr(cod); - if (aliquota == NULL) - { - aliquota = new TRiepilogo_iva(iva); - table.add(cod, aliquota); - } - const real imponibile = doc_al_lordo ? r.importo(true, true, ndec) : r.imponibile(); - aliquota->imp_orig() += imponibile; - } - } - } - - if (solo_imponibili) - return; - - real tot_doc; - real tot_sconti; - real tot_sconti_perc; - TArray imponibili; - const bool fatt_comm = tipo().fattura_commerciale(); - - TString4 codiva_es; iva_esente(codiva_es); - - for (int i = items; i > 0; i--) - { - const TRiga_documento& r = row(i); - const real imponibile = doc_al_lordo ? r.importo(true, true, ndec) : r.imponibile(); - - tot_doc += imponibile; - if (r.is_sconto()) - { - tot_sconti += imponibile; - if (r.is_sconto_perc()) - tot_sconti_perc += imponibile; - } - else - if (!r.is_descrizione()) - { - const real imposta = doc_al_lordo ? ZERO : r.imposta(false); - // Aggiorna o aggiunge l'elemento se non esiste - const TCodiceIVA & iva = r.iva(); - - if (iva.ok()) - { - const TString & cod = iva.codice(); - - TRiepilogo_iva* aliquota = (TRiepilogo_iva *) table.objptr(cod); - if (aliquota == NULL) - { - aliquota = new TRiepilogo_iva(iva); - table.add(cod, aliquota); - } - - aliquota->imp() += imponibile; - if (r.is_spese() && iva.tipo().not_empty()) - aliquota->imp_spese_row() += imponibile; - aliquota->iva() += imposta; - } - tot_doc += imposta; - } - } - - if (table.empty()) - return; - - if (tot_sconti != ZERO) - { - TGeneric_distrib d(tot_sconti, ndec); - real tot_sconti_imp = tot_sconti - tot_sconti_perc; - - if (!table.empty()) - { - FOR_EACH_ASSOC_OBJECT(table, obj, key, o) - { - TRiepilogo_iva* aliquota = (TRiepilogo_iva*)o; - const real i = aliquota->imp() - aliquota->imp_spese_row(); - d.add(i); - } - } - - FOR_EACH_ASSOC_OBJECT(table, obj, key, o) - { - TRiepilogo_iva& aliquota = *(TRiepilogo_iva*)o; - const TCodiceIVA& ci = aliquota.cod_iva(); - const real i = d.get(); - - real& imponibile = aliquota.imp(); - imponibile += i; - - TGeneric_distrib s(i, ndec); - - s.add(tot_sconti_imp); - s.add(tot_sconti_perc); - - aliquota.sconto_imp() = s.get(); - aliquota.sconto_perc() = s.get(); - - real& iva = aliquota.iva(); - -/* if (doc_al_lordo) - { - const real imposta(ci.imposta(i, ndec)); - - TGeneric_distrib iva(imposta, ndec); - iva.add(tot_sconti_imp); - iva.add(tot_sconti_perc); - - imponibile += imposta; - aliquota->sconto_imp() += iva.get(); - aliquota->sconto_perc() += iva.get(); - - tot_doc += imposta; - } - else */ - if (!doc_al_lordo) - { - const real imposta(ci.imposta(i, ndec)); - - iva += imposta; - aliquota.iva_sconto() = imposta; - tot_doc += imposta; - } - } - } - - if (fatt_comm) - calc_iva_fattura_commerciale(); - - const real rit = ritenute(); - real val = spese_incasso(real(tot_doc - rit), ALL_DECIMALS, doc_al_lordo ? _lordo : _netto); - - if (!val.is_zero()) - { - const TString& codiva = codiva_es.full() ? (const TString&)codiva_es : codiva_spese(); - TRiepilogo_iva* ri = (TRiepilogo_iva*)table.objptr(codiva); - if (ri == NULL && codiva.full()) - { - ri = new TRiepilogo_iva(TCodiceIVA(codiva)); - table.add(codiva, ri); - } - if (ri != NULL) - ri->imp_spese() += val; - tot_doc += val; - - if (!doc_al_lordo) - { - val = spese_incasso(real(tot_doc - rit), ALL_DECIMALS, _imposta); - if (ri != NULL) - ri->iva_spese() += val; - tot_doc += val; - } - } - - val = bolli(real(tot_doc - rit), ALL_DECIMALS, doc_al_lordo ? _lordo : _netto); - if (val != ZERO) - { - const TString& codiva = codiva_bolli(); - if (codiva.full()) - { - TRiepilogo_iva* ri = (TRiepilogo_iva*)table.objptr(codiva); - if (ri == NULL) - { - ri = new TRiepilogo_iva(TCodiceIVA(codiva)); - table.add(codiva, ri); - } - if (!doc_al_lordo) - { - real valiva = bolli(real(tot_doc - rit), ALL_DECIMALS, _imposta); - ri->iva_spese() += valiva; - tot_doc += valiva; - } - ri->imp_spese() += val; - } - - tot_doc += val; - } - -// SCORPORO - if (doc_al_lordo) - { - FOR_EACH_ASSOC_OBJECT(table, obj, key, o) - { - TRiepilogo_iva * aliquota = (TRiepilogo_iva*) o; - const TCodiceIVA& iva = aliquota->cod_iva(); - - aliquota->iva() = iva.scorpora(aliquota->imp(), ndec); - aliquota->iva_spese() = iva.scorpora(aliquota->imp_spese(), ndec); - iva.scorpora(aliquota->imp_spese_row(), ndec); - - aliquota->iva_sconto() = iva.scorpora(aliquota->sconto_imp(), ndec); - aliquota->iva_sconto() += iva.scorpora(aliquota->sconto_perc(), ndec); - } - } -} - -real TDocumento::imposta(bool spese, int ndec) const -{ - real val = ZERO; - if (physical_rows() > 0) - { - TAssoc_array& table = ((TDocumento*)this)->tabella_iva(); - - if (ndec == AUTO_DECIMALS) - ndec = decimals(); - - for (TRiepilogo_iva * ri = (TRiepilogo_iva *) table.get(); ri != NULL; - ri = (TRiepilogo_iva *) table.get()) - { - real iva = ri->imposta(spese); - - if (ndec == 0) - { - if (iva < ZERO) - iva.floor(ndec); - else - iva.ceil(ndec); - } - else - iva.round(ndec); - val += iva; - } - } - return val; -} - -real TDocumento::totale_doc() const -{ -/* A pag.1 c'e' scritto di non fare cosi' - const TString16 field(tipo().totale_doc()); - - if (field.not_empty()) - return get_real(field); - else - { - real r = imponibile() + imposta(); - const int ndec = decimals(); - - r += spese_incasso(r - ritenute()), ndec); - r += bolli(real(r - ritenute()), ndec); - return r; - } -*/ - // Cosi' e' piu' ordinato, strutturato e veloce - real r; - const TString& field = tipo().totale_doc(); - if (field.blank()) - { - const int ndec = decimals(); - const bool lordo = tipo().calcolo_lordo(); - - r = imponibile(lordo); - if (!lordo) - r += imposta(); - r += spese_incasso(real(r - ritenute()), ndec); - r += bolli(real(r - ritenute()), ndec); - } - else - r = get_real(field); - - return r; -} - -real TDocumento::totale_netto() const -{ - const TString& field = tipo().totale_netto(); - if (field.full()) - return get_real(field); - else - return imponibile() + imposta(); -} - -real TDocumento::basesconto() const -{ - const TString& field = tipo().basesconto(); - return field.full() ? get_real(field) : ZERO; -} - -real TDocumento::spese() const -{ - const TString& field = tipo().spese(); - - if (field.full()) - return get_real(field); - else - { - real r; - - FOR_EACH_PHYSICAL_RDOC(*this, i, rdoc) - if (rdoc->is_spese()) - r += rdoc->imponibile(); - return r; - } -} - -real TDocumento::spese(const TString & tipo_spesa) const -{ - TString16 field = tipo().spese(); - - field << tipo_spesa; - if (tipo().exist(field)) - return get_real(field); - else - { - real r; - - FOR_EACH_PHYSICAL_RDOC(*this, i, rdoc) - if (rdoc->is_spese()) - { - const TSpesa_prest s(rdoc->get(RDOC_CODART)); - - if (s.get("S11").sleft(1) == tipo_spesa) - r += rdoc->imponibile(); - } - return r; - } -} - -real TDocumento::ritenute(const char tipo, bool lordo, int ndec) const -{ - real val; - for (int i = rows(); i > 0; i--) - { - const TRiga_documento& r = ((TDocumento*)this)->row(i); - val += r.ritenuta(tipo, lordo, ndec); - } - return val; -} - -TPagamento& TDocumento::pagamento() -{ - const char tipocf = get_char(DOC_TIPOCF); - const long codcf = get_long(DOC_CODCF); - _pag.set_clifo(codcf, tipocf); - - TDate data_in = get_date(DOC_DATAINSC); - if (data_in.empty()) - data_in = get_date(DOC_DATADOC); - - const TString8 codpag(get(DOC_CODPAG)); - if (codpag != _pag.code()) - { - _pag.set_code(codpag); - _pag.read(); - _pag.set_inizio(data_in); // Perche' rispetta rate true? - } - else - { - if (data_in != _pag.get_datadoc()) - _pag.set_inizio(data_in); // Perche' rispetta rate true? - } - - return _pag; -} - -real TDocumento::provvigione(bool first, int ndec) const -{ - TString16 field = agente(first).campoprovv(); - if (field.empty()) - field = first ? tipo().totprovv() : tipo().totprovv1(); - - real val; - if (field.not_empty()) - val = get_real(field); - else - { - if (ndec == AUTO_DECIMALS) - ndec = decimals(); - for (int i = physical_rows(); i > 0; i--) - val += physical_row(i).provvigione(first, ndec); - } - return val; -} - -real TDocumento::valore(bool totale, bool lordo, int ndec) const -{ - real val; - TDocumento& doc = *(TDocumento*)this; - FOR_EACH_PHYSICAL_RDOC_BACK(doc, i, r) - { - const char t = r->tipo().tipo(); - if (strchr("MSPRA", t) != NULL) // Merce, Spese, Prestazioni, Risorse, Attrezzature - val += r->valore(totale, lordo, ndec); - } - return val; -} - -void TDocumento::put_str(const char* fieldname, const char* val) -{ - const TFixed_string fn(fieldname); - if (fn == DOC_TIPODOC) - { - const TString4 v(val); - if (TRectype::get(DOC_TIPODOC) != v) - { - TAuto_variable_rectype::put_str(fieldname, v); - reset_fields(*this); - set_fields(*this); - } - else - dirty_fields(); - } else - if (fn == DOC_CODCF) - { - const TString8 v(val); - put(DOC_SPESEUPD, TRectype::get(DOC_CODCF) == v); - TAuto_variable_rectype::put_str(fieldname, v); - dirty_fields(); - } - else - { - TAuto_variable_rectype::put_str(fieldname, val); - dirty_fields(); - if (fn == DOC_SCONTOPERC) - set_riga_sconto(); - } -} - -const TString& TDocumento::get_str(const char* fieldname) const -{ - if (_dirty_deny && variable_field(fieldname) != NULL) - (bool&) _dirty_deny = false; - - return TMultiple_rectype::get_str(fieldname); -} - -void TDocumento::zero(const char * fieldname) -{ - if (strcmp(fieldname, DOC_TIPODOC) == 0) - reset_fields(*this); - TAuto_variable_rectype::zero(fieldname); - dirty_fields(); -} - -TCli_for& TDocumento::clifor(bool force_reload) const -{ - const char tipo = tipocf(); - const long codice = codcf(); - TCli_for& cf = (TCli_for&)_cli_for; - if (force_reload || cf.empty() || cf.tipo() != tipo || cf.codice() != codice) - cf.read(tipo, codice); - return cf; -} - -TOccasionale& TDocumento::occas() const -{ - const TString16 occ_code = cod_occas(); // Codice occasionale in testata - - TOccasionale& rec = (TOccasionale&)_occas; - if (occ_code != rec.codice()) - { - TLocalisamfile o(LF_OCCAS); - rec.put(OCC_CFPI, occ_code); - if (rec.read(o) != NOERR) - { - rec.zero(); - rec.put(OCC_CFPI, occ_code); - } - } - return rec; -} - -const TAgente & TDocumento::agente(bool first) const -{ - if (_agenti == NULL) - _agenti = new TAgenti_cache; - return _agenti->agente(first ? get(DOC_CODAG) : get(DOC_CODAGVIS)); -} - -TDocumento& TDocumento::copy(const TDocumento & d) -{ - TMultiple_rectype::operator=((TMultiple_rectype &)d); - reset_fields(*this); - set_fields((TAuto_variable_rectype &) d); - for (int i = physical_rows(); i > 0; i--) - { - TRiga_documento& r = row(i); - - r.set_doc(this); - r.reset_fields(r); - r.set_fields(((TAuto_variable_rectype &)d[i])); - } - set_riga_sconto(); - if (is_fattura()) - set_riga_esenzione(); - _occas = d.occas(); - return *this; -} - -TRectype & TDocumento::operator =(const TRectype & r) -{ - return TMultiple_rectype::operator=(r); -} - -TRectype & TDocumento::operator =(const char * r) -{ - return TMultiple_rectype::operator=(r); -} - -TRecord_array& TDocumento::body(int logicnum) const -{ - logicnum = LF_RIGHEDOC; // logicnum may be 0! - const bool reset_data_cons = loaded_rows(logicnum) == 0; - - if (reset_data_cons) - ((TDocumento*)this)->_dirty_deny = true; - - TRecord_array& r = TMultiple_rectype::body(logicnum); - - if (reset_data_cons) - { - const TDate datacons(get(DOC_DATACONS)); - const TString80 codcms(get(DOC_CODCMS)); - const TString80 fascms(get(DOC_FASCMS)); - const TString80 codcos(get(DOC_CODCOSTO)); - const bool order = datacons.ok(); // on 27-09-2013 was order=is_ordine(); - const bool can_reset_ca = (codcms.full() || codcos.full()) && ini_get_string(CONFIG_DITTA, "ca", "FathFasi").blank(); - - for (int i = r.last_row(); i > 0; i = r.pred_row(i)) - { - TRectype& rec = r[i]; - TRecfield dcons(rec, RDOC_DATACONS); - if (order && datacons == dcons) - dcons = ""; - if (can_reset_ca) - { - TRecfield ccms(rec, RDOC_CODCMS); - TRecfield fcms(rec, RDOC_FASCMS); - TRecfield ccos(rec, RDOC_CODCOSTO); - if (codcms == ccms) ccms = ""; - if (fascms == fcms) fcms = ""; - if (codcos == ccos) ccos = ""; - } - } - ((TDocumento*)this)->_dirty_deny = false; - } - return r; -} - -void TDocumento::update_raee() -{ - const TString & r_cod = tipo().raee_cod(); - const TString & r_fld = tipo().raee_fld(); - - if (r_cod.full() && r_fld.full() && tipo().stati_iniziali_modifica().find(stato()) >= 0) - { - TSpesa_prest sp(r_cod); - TString4 cod_iva_cli; - TLocalisamfile cfven(LF_CFVEN); - cfven.put("TIPOCF", get("TIPOCF")); - cfven.put("CODCF", get("CODCF")); - if (cfven.read() == NOERR) - cod_iva_cli = cfven.get("ASSFIS"); - int nrows = physical_rows(); - int i; - - for (i = nrows; i > 0; i--) - { - TRiga_documento & r = row(i); - - if (r.tipo().tipo() == RIGA_SPESEDOC && r.is_generata() && r.get("GENTIPO") == "R") - destroy_row(i, true); - } - nrows = physical_rows(); - for (i = nrows; i > 0; i--) - { - TRiga_documento & r = row(i); - - if (r.is_articolo()) - { - TArticolo & art = r.articolo(); - real tax = art.get_real(r_fld); - - if (tax != ZERO) - { - const TCurrency_documento val(tax, *this, true); - TString16 t(sp.tipo_riga()); - TRiga_documento & r1 = insert_row(i + 1, t); - - copy_data(r1, r); - r1.set_tipo(t); - r1.put(RDOC_CODART, r_cod); - TString d(sp.descrizione()); - - if (d.full()) - d << " - "; - d << r1.get(RDOC_DESCR); - d << r1.get(RDOC_DESCEST); - r1.set_descr(d); - - const TString& um = sp.um(); - if (um.full()) - r1.put(RDOC_UMQTA, um); - if (cod_iva_cli.blank()) - { - const TString& codiva = sp.cod_iva(); - if (codiva.full()) - r1.put(RDOC_CODIVA, codiva); - } - else - r1.put(RDOC_CODIVA, cod_iva_cli); - tax = val.get_num(); - r1.put(RDOC_PREZZO, tax); - if (tipo().calcolo_lordo()) - { - tax = r1.iva().lordo(tax, ALL_DECIMALS); - r1.put(RDOC_PREZZOL, tax); - } - r1.generata(); - r1.put(RDOC_GENTIPO, "R"); - } - } - } - } -} - -void TDocumento::update_spese_aut(TString_array & spese_aut, bool preserve_old, TSheet_field* sh, bool force) -{ - const bool updated = get_bool(DOC_SPESEUPD); - if (!force && updated) - return; - - const bool interactive = sh != NULL; - - if (force || tipo().spese_aut()) - { - const int nrows = physical_rows(); - int i; - - for (i = nrows; i > 0; i--) - { - TRiga_documento & r = row(i); - bool tipo_spese = r.get(RDOC_GENTIPO).empty(); - - if (r.tipo().tipo() == RIGA_SPESEDOC && r.is_generata() && tipo_spese) - { - if (preserve_old) - return; - destroy_row(i, true); - if (interactive) - sh->destroy(i - 1); - } - } - - TString4 cod_iva_cli; - const int nspese = spese_aut.items(); - - if (nspese > 0) - { - TSpesa_prest sp; - cod_iva_cli = codesiva(); - - for (i = 0; i < nspese; i++) - { - const TString& s = spese_aut.row(i); - - if (sp.read(s) != NOERR) - warning_box("Codice spesa '%s' assente", (const char*)s); - else - { - const TString4 tipo(sp.tipo_riga()); - TRiga_documento& riga = new_row(tipo); - - riga.put(RDOC_CODART, s); - riga.generata(); - riga.put(RDOC_DESCR, sp.descrizione()); - if (cod_iva_cli.blank()) - riga.put(RDOC_CODIVA, sp.cod_iva()); - else - riga.put(RDOC_CODIVA, cod_iva_cli); - switch (sp.tipo()) - { - case 'Q': - { - real qta = sp.qta(); - if (qta == ZERO) - qta = UNO; - riga.put("QTA", qta); - } - // Continua perche' e' quantita' e valore - case 'V': - { - const real cambio = get_real(DOC_CAMBIO); - const TString4 valuta = get(DOC_CODVAL); - real prezzo = sp.prezzo(); - - sppr_calc(sp, valuta, cambio, prezzo); - if (this->tipo().calcolo_lordo()) - { - prezzo = riga.iva().lordo(prezzo, ALL_DECIMALS); - riga.put(RDOC_PREZZOL, prezzo); - } - riga.put(RDOC_PREZZO, prezzo); - riga.put(RDOC_UMQTA, sp.um()); - } - break; - case 'P': - default: - riga.put(RDOC_QTA, sp.perc()); - break; - } - if (cod_iva_cli.empty()) - riga.put(RDOC_CODIVA, sp.cod_iva()); - else - riga.put(RDOC_CODIVA, cod_iva_cli); - - riga.put(RDOC_CODCOSTO, sp.cdc()); - riga.put(RDOC_CODCMS, sp.cms()); - riga.put(RDOC_FASCMS, sp.fase()); - riga.cms2tipodet(); - - if (interactive) - { - const int nrow = sh->insert(-1, FALSE); - riga.autoload(*sh); - sh->check_row(nrow); - } - } - } - } - } - put(DOC_SPESEUPD, true); -} - -// Calcola il peso in Kg degli imballaggi di una data categoria CONAI -real TDocumento::calc_conai_qta(TCONAI_class cc) -{ - real qta; - if (conai_configured_class(cc)) - { - FOR_EACH_PHYSICAL_RDOC(*this, i, r) if (r->is_merce() || r->is_omaggio()) - { - const real rowqty = r->calc_conai_qta(cc); - qta += rowqty; - } - qta.round(5); // Arrotondamento al centigrammo - } - return qta; -} - -void TDocumento::update_conai() -{ - if (main_app().has_module(DCAUT, CHK_DONGLE) && tipo().add_conai() && tipo().stati_iniziali_modifica().find(stato()) >= 0) - { - const TRectype& cfven = clifor().vendite(); - const bool cli_add_conai = cfven.get_bool("ADDCONAI"); - const char * const __conai_cf_names[] = {"ESACC", "ESALL", "ESCAR", "ESPLA", "ESLEG", "ESVET"}; - - const TDate datadoc = get(DOC_DATADOC); - const TDate dataes = cfven.get(CFV_DATAECONAI); - bool esponi_esenti = false; - - TString_array conai_sp(CONAI_CLASSES); // Codici spesa conai - { - const char* const conai_cod[CONAI_CLASSES] = { "CODACC", "CODALL", "CODCAR", "CODPLA", "CODLEG", "CODVET" }; - TConfig c(CONFIG_DITTA, "ve"); - for (int i = 0; i < CONAI_CLASSES; i++) - conai_sp.add(c.get(conai_cod[i])); - - esponi_esenti = c.get_bool("ESPONIESENTI"); - } - - bool updated[CONAI_CLASSES] = {false,false,false,false,false,false}; - for (int i = physical_rows(); i > 0; i--) - { - TRiga_documento& r = row(i); - const bool tipo_conai = r.get_char("GENTIPO") == 'C'; - - // Elimina righe generate - if (tipo_conai) - { - const TString& cod = r.get(RDOC_CODART); - const TCONAI_class pos = (TCONAI_class)conai_sp.find(cod); - - if (pos >= CONAI_FIRST && pos <= CONAI_LAST) - { - if (cli_add_conai) - { - real perc_esenz = cfven.get_real(__conai_cf_names[pos]); - real qta = calc_conai_qta(pos); - if (dataes.ok() && datadoc > dataes) - perc_esenz = ZERO; - const bool cli_esente = esponi_esenti && (perc_esenz >= CENTO); - if (!cli_esente && !perc_esenz.is_zero()) - qta = qta * (CENTO - perc_esenz) / CENTO; // More precise - if (qta > ZERO) - { - r.put(RDOC_QTA, qta); - if (cli_esente) - r.zero(RDOC_PREZZO); - } - else - destroy_row(i, true); - } - else - destroy_row(i, true); - updated[pos] = true; - } - } - } - - // Genera nuove righe - if (cli_add_conai) - { - const TString4 cod_iva_cli = codesiva(); - TSpesa_prest sp; - - FOR_EACH_CONFIGURED_CONAI_CLASS(ct) if (!updated[ct]) - { - const real perc_esenz = cfven.get_real(__conai_cf_names[ct]); - const bool cli_esente = (esponi_esenti) && (perc_esenz >= CENTO); - const real qta_lorda = calc_conai_qta(ct); - real qta = qta_lorda; - if (!cli_esente && !qta_lorda.is_zero() && !perc_esenz.is_zero()) - { - qta = qta_lorda * (CENTO - perc_esenz) / CENTO; - qta.round(5); - } - - if (qta > ZERO) - { - const TString& s = conai_sp.row(ct); - - if (sp.read(s) != NOERR) - message_box(FR("Il codice spesa CONAI %s specificato nei parametri ditta è assente: '%s'"), - conai_material(ct), (const char*)s); - else - { - const TString4 tipo = sp.tipo_riga(); - TRiga_documento& riga = new_row(tipo); - - riga.put(RDOC_CODART, s); - riga.generata(); - riga.put(RDOC_GENTIPO, 'C'); - riga.put(RDOC_DESCR, sp.descrizione()); - riga.put(RDOC_QTA, qta); - - const real cambio = get_real(DOC_CAMBIO); - const TString4 valuta = get(DOC_CODVAL); - real prezzo = cli_esente ? ZERO : sp.prezzo(); - - sppr_calc(sp, valuta, cambio, prezzo); - if (this->tipo().calcolo_lordo()) - prezzo = riga.iva().lordo(prezzo, ALL_DECIMALS); - riga.put(RDOC_PREZZO, prezzo); - riga.put(RDOC_UMQTA, sp.um()); - if (cod_iva_cli.empty()) - riga.put(RDOC_CODIVA, sp.cod_iva()); - else - riga.put(RDOC_CODIVA, cod_iva_cli); - } - } - } - } - } -} - -bool TDocumento::is_evaso() const -{ - bool ok = is_ordine() || is_bolla() || is_generic(); - - if (ok && tipo().is_ordine_quadro()) - return false; - - for (int r = 1; ok && r <= physical_rows(); r++) - { - const TRiga_documento& riga = physical_row(r); - if (riga.is_evadibile()) - ok = riga.is_evasa(); - } - return ok; -} - -bool TDocumento::is_nota_credito() const -{ - bool swap = false; - - // Controlla prima l'esistenza del flag nota-credito sul tipo documento; - // se non e' settato controlla la causale - if (tipo().nota_credito()) - swap = true; - else - { - if (tipo().is_fattura()) - { - const TString4 codcaus(tipo().causale()); - if (codcaus.full()) - { - TCausale c(codcaus, data().year()); - const char sez = c.sezione_clifo(); - //controllo ulteriore sull'iva - TipoIVA tiva = c.reg().iva(); - const char tcf = tipocf(); - if (tiva == nessuna_iva && tcf > ' ') - tiva = tcf == 'C' ? iva_vendite : iva_acquisti; - if (tiva != nessuna_iva) - swap = ((tiva == iva_vendite) ^ (sez == 'D')); - } - } - } - return swap; -} - -TCurrency_documento::TCurrency_documento(const real& num, const TDocumento & doc, bool price) - : TCurrency(ZERO, "", ZERO, price) -{ - const TString4 val = doc.get(DOC_CODVAL); - force_value(val, doc.get_real(DOC_CAMBIO)); - set_num(num); -} - -int TDocumento::set_row_ids() -{ - const int phrw = physical_rows(); - long maxid = 0L; - int first_needed = 0; - for (int r = 1; r <= phrw; r++) - { - const TRiga_documento& row = physical_row(r); - const long id = row.get_long(RDOC_IDRIGA); - if (id > maxid) - maxid = id; - else - { - if (first_needed == 0 && id <= 0) - first_needed = r; - } - } - if (first_needed > 0) - { - for (int r = first_needed; r <= phrw; r++) - { - TRiga_documento& row = (TRiga_documento&)physical_row(r); - const long id = row.get_long(RDOC_IDRIGA); - if (id <= 0) - row.put(RDOC_IDRIGA, ++maxid); - } - } - return phrw; -} - -const TRiga_documento* TDocumento::get_row_id(long id) const -{ - TDocumento& doc = *(TDocumento*)this; - FOR_EACH_PHYSICAL_RDOC_BACK(doc, r, row) - { - if (row->get_long(RDOC_IDRIGA) == id) - return row; - } - return NULL; -} - -int TDocumento::id2rownum(long id) const -{ - const TRiga_documento* rdoc = get_row_id(id); - return rdoc ? rdoc->get_int(RDOC_NRIGA) : -1; -} - - -int TDocumento::tipo_riclassificato() const -{ - int tipo_riclassificato = tipo().tipo(); - if (tipo_riclassificato == TTipo_documento::_altro) - { - const TCodice_numerazione& num = codice_numerazione(); - if (num.fattura_emettere_ricevere()) - tipo_riclassificato = TTipo_documento::_bolla; - else - tipo_riclassificato = TTipo_documento::_fattura; - } - return tipo_riclassificato; -} - -const TString& TDocumento::codesiva() const -{ - TCli_for& c = clifor(); - - const TString& codiva = c.vendite().get(CFV_ASSFIS); - if (!c.use_lettere()) - return codiva; - - const TCodiceIVA i(codiva); - if (!i.has_plafond()) // Era presente nella 3.x, poi è sparito nella 10, ora torna nella 11.0 (7-3-2013) - return codiva; - - const TDate datadoc = get(DOC_DATADOC); - if (c.read_lettera(datadoc)) - return c.vendite().get(CFV_ASSFIS); // codiva may be lost - - return EMPTY_STRING; -} - -void TDocumento::get_protocolli_esenzione(TString& esenzione, TString& data_esenzione, - TString& registrazione, TString& data_registrazione) const -{ - TCli_for& c = clifor(); - if (c.use_lettere()) - { - if (c.read_lettera(get_date(DOC_DATADOC), true)) - { - const TRectype& rec = c.lettera(); - esenzione = rec.get(LETINT_VSPROT); - data_esenzione = rec.get(LETINT_VSDATA); - registrazione = rec.get(LETINT_NUMPROT); - data_registrazione = rec.get(LETINT_DATAREG); - } - } - else - { - esenzione = c.vendite().get(CFV_VSPROT); - data_esenzione = c.vendite().get(CFV_VSDATAREG); - registrazione = c.vendite().get(CFV_NSPROT); - data_registrazione = c.vendite().get(CFV_NSDATAREG); - } -} +#include +#include +#include +#include +#include +#include + +#include "../cg/cg2103.h" +#include "../db/dblib.h" +#include "../pr/prlib.h" +#include "../li/letint.h" + +#ifdef LIVE_STATISTICS +#include "../sv/svlib01.h" +#endif + +#include "veini.h" +#include "velib.h" +#include "sconti.h" +#include "vepriv.h" +#include "veuml.h" + +/////////////////////////////////////////////////////////// +// TTipo_documento_cache +/////////////////////////////////////////////////////////// + +class TTipo_documento_cache : public TRecord_cache +{ +protected: + virtual TObject* rec2obj(const TRectype& rec) const; + +public: + TTipo_documento& tipo(const char* key); + TTipo_documento_cache(); + virtual ~TTipo_documento_cache() { } +}; + +TTipo_documento_cache::TTipo_documento_cache() + : TRecord_cache("%TIP", 1) +{ + test_file_changes(); // Tieni d'occhio le modifiche sul file + set_items_limit(59); // Standard +} + +TObject* TTipo_documento_cache::rec2obj(const TRectype& curr) const +{ + return new TTipo_documento(curr); +} + +TTipo_documento& TTipo_documento_cache::tipo(const char* key) +{ + TString8 k; k << "TIP|" << key; + return (TTipo_documento&)query(k); +} + +const TTipo_documento& cached_tipodoc(const char* tipodoc) +{ + HIDDEN TTipo_documento_cache __cache_tipi_documento; + return __cache_tipi_documento.tipo(tipodoc); +} + +/////////////////////////////////////////////////////////// +// TTipo_numerazione_cache +/////////////////////////////////////////////////////////// +class TNumerazione_cache : public TRecord_cache +{ +protected: + virtual TObject* rec2obj(const TRectype& rec) const; + +public: + TCodice_numerazione & num(const char* key); + TNumerazione_cache(); + virtual ~TNumerazione_cache() { } +}; + +TNumerazione_cache::TNumerazione_cache() + : TRecord_cache("%NUM", 1) +{ + test_file_changes(); // Tieni d'occhio le modifiche sul file + set_items_limit(59); // Standard +} + +TObject* TNumerazione_cache::rec2obj(const TRectype& curr) const +{ + return new TCodice_numerazione(curr); +} + +TCodice_numerazione & TNumerazione_cache::num(const char* key) +{ + TString8 k; k << "NUM|" << key; + return (TCodice_numerazione&)query(k); +} + +const TCodice_numerazione& cached_numerazione(const char * codnum) +{ + HIDDEN TNumerazione_cache __cache_numerazioni; + return __cache_numerazioni.num(codnum); +} + +// calcola il prezzo per le spese +void sppr_calc(const TRectype & rec, const TString & valuta_doc, const real & cambio, real & prezzo) +{ + const TString& sppr_valuta = rec.get("S4"); + + if (!same_values(sppr_valuta, valuta_doc)) + { + const bool prezzo_un = rec.get_char("S6") == 'Q'; + /* Non capisco bene il cambio in gioco ... + if (prezzo_un) + { + TPrice val(prezzo, sppr_valuta); + val.change_value(valuta_doc, cambio); + prezzo = val.get_num(); + } + else + { + TCurrency val(prezzo, sppr_valuta); + val.change_value(valuta_doc, cambio); + prezzo = val.get_num(); + } + */ + // ... ma mi adeguo + TCurrency val(prezzo, sppr_valuta, ZERO, prezzo_un); + val.change_value(valuta_doc, cambio); + prezzo = val.get_num(); + } +} + +/////////////////////////////////////////////////////////// +// Movimento di magazzino +/////////////////////////////////////////////////////////// + +class TMov_mag_doc : public TMov_mag +{ + TString_array _codmagc; + +protected: + virtual const char* codmag_rauto(int r) const; + +public: + void add_magc(const char* magc) + { + CHECKS(magc && strlen(magc) <= 5, "Invalid CODMAG ", magc); + _codmagc.add(magc); + } + void reset_magc(int r) { _codmagc.add("", r - 1); } + void destroy_magc(int r) { _codmagc.destroy(r - 1); } +}; + +const char* TMov_mag_doc::codmag_rauto(int r) const +{ + const char* codmagc = NULL; + const int num_magc = _codmagc.items(); + if (num_magc > 0) // Impossibile trovare un codmagc + { + const TRecord_array& b = body(); + if (r > 0 && r <= b.rows()) // Can't check non-existent rows + { + const char tr = b[r].get_char(RMOVMAG_TIPORIGA); + if (tr == 'D' || tr == 'A') // These are customer's added rows + { + int j = -1; // Indice per reperire il mag. collegato da _codmagc + for (int i = r; i > 0; i--) // Scorre dalla riga r in su e conta quante righe D + if (b[i].get_char(RMOVMAG_TIPORIGA) == 'D') + j++; + if (j >= 0 && j < num_magc) + codmagc = _codmagc.row(j); + } + } + } + return codmagc; +} + +///////////////////////////////////////////////////////////// +// TRiepilogo IVA +///////////////////////////////////////////////////////////// +TRiepilogo_iva& TRiepilogo_iva::copy(const TRiepilogo_iva& a) +{ + _codiva = a.cod_iva(); + _imp = a._imp; + _imp_orig = a._imp_orig; + _imp_spese = a._imp_spese; + _imp_spese_row = a._imp_spese_row; + _iva = a._iva; + _iva_spese = a._iva_spese; + _sconto_perc = a._sconto_perc; + _sconto_imp = a._sconto_imp; + _iva_sconto = a._iva_sconto; + _tipo = a._tipo; + return *this; +} + +TRiepilogo_iva::TRiepilogo_iva(const TCodiceIVA & codiva) : _codiva(codiva) +{ + const TString& t =_codiva.tipo(); + if (t == "VE") + _tipo = 2; else + if (t == "ES") + _tipo = 4; else + if (t == "NI") + _tipo = 8; else + if (t == "NS") + _tipo = 16; + else + _tipo = 1; +} + +/////////////////////////////////////////////////////////// +// Agenti +/////////////////////////////////////////////////////////// +class TAgenti_cache : public TRecord_cache +{ +protected: + virtual TObject* rec2obj(const TRectype& rec) const { return new TAgente(rec);} + +public: + const TAgente& agente(const char* chiave) { return (const TAgente &) get(chiave);} + + TAgenti_cache() : TRecord_cache(LF_AGENTI) {} + virtual ~TAgenti_cache() { } +}; + +HIDDEN TAgenti_cache * _agenti = NULL; + +/////////////////////////////////////////////////////////// +// Documento per vendite +/////////////////////////////////////////////////////////// + +long TDocumento::_firm = -1; +TString4 TDocumento::_codiva_spese; +TString4 TDocumento::_codiva_bolli; +short TDocumento::_has_mag = 3; +short TDocumento::_has_provv = 3; +#ifdef LIVE_STATISTICS +short TDocumento::_has_stat_ven = 3; +#endif + +TCodgiac_livelli * TDocumento::_livelli=NULL; + +HIDDEN TAssoc_array _docs_to_agg; + +void TDocumento::init() +{ + add_file(LF_RIGHEDOC, RDOC_NRIGA); + set_memo_fld("G1"); + + _tipocf = new TRecfield(*this, DOC_TIPOCF); + _codcf = new TRecfield(*this, DOC_CODCF); + _cod_occas = new TRecfield(*this, DOC_OCFPI); + + _sconto = _esenzione = NULL; + _stato_originale = ' '; + _dirty_deny = false; + + check_modules(); +} + +TDocumento::TDocumento() : TMultiple_rectype(LF_DOC) +{ + init(); +} + +TDocumento::TDocumento(const TDocumento & d) + : TMultiple_rectype(LF_DOC) +{ + init(); + copy(d); +} + +TDocumento::TDocumento(char provv, int anno, const char* codnum, long numdoc) + : TMultiple_rectype(LF_DOC) +{ + init(); + if (numdoc > 0) + read(provv, anno, codnum, numdoc); + else + set_key(*this, provv, anno, codnum, 0L); +} + +TDocumento::TDocumento(const TDoc_key& key) + : TMultiple_rectype(LF_DOC) +{ + init(); + const long ndoc = key.ndoc(); + if (ndoc > 0) + read(key.provv(), key.anno(), key.codnum(), ndoc); + else + set_key(*this, key.provv(), key.anno(), key.codnum(), 0L); +} + + +TDocumento::TDocumento(const TRectype& rec) + : TMultiple_rectype(LF_DOC) +{ + init(); + read(rec); +} + +TDocumento::~TDocumento() +{ + delete _tipocf; + delete _codcf; + delete _cod_occas; + + if (_sconto != NULL) delete _sconto; + if (_esenzione != NULL) delete _esenzione; +} + +const TString& TDocumento::codiva_spese() const +{ ((TDocumento *)this)->test_firm(); return _codiva_spese;} + +const TString& TDocumento::codiva_bolli() const +{ ((TDocumento *)this)->test_firm(); return _codiva_bolli;} + +void TDocumento::check_modules() +{ + if (_has_mag < 0 || _has_mag > 1) + { + const TDongle& din = dongle(); + _has_mag = din.active(MGAUT); + _has_provv = din.active(PRAUT); +#ifdef LIVE_STATISTICS + _has_stat_ven = din.active(SVAUT); +#endif + } +} + +void TDocumento::set_variables(TExpression * e) const +{ + CHECK(e, "Null expression"); + const int items = e->numvar(); + for (int i = 0; i < items; i++) + { + const TFieldref field(e->varname(i), LF_DOC); + + switch (field.file()) + { + case LF_CLIFO : + e->setvar(i, clifor().get(field.name())); + break; + case LF_CFVEN : + e->setvar(i, clifor().vendite().get(field.name())); + break; + default: + e->setvar(i, get(field.name())); + break; + } + } +} + +void TDocumento::test_firm() +{ + const long new_firm = prefix().get_codditta(); + + if (_firm != new_firm) + { + TConfig conf(CONFIG_DITTA, "ve"); + _codiva_spese = conf.get("SPINCODIVA"); + _codiva_bolli = conf.get("SPBOCODIVA"); + _firm = new_firm; + } +} + +real TDocumento::spese_incasso(real & imp, int ndec, TTipo_importo t) const +{ + static TArray spese_inc; + static real maxadd, spadd; + + real imp_spese; + const real percentuale = get(DOC_PERCSPINC); + + if (percentuale > ZERO) + { + if (ndec == AUTO_DECIMALS) + ndec = decimals(); + if (spese_inc.objptr(_rim_dir) == NULL) // Inizializzo le spese d'incasso se necessario + { + TConfig conf(CONFIG_STUDIO, "ve"); + for (TTipo_pag p = _rim_dir; p < _nessun_pag; p = TTipo_pag((int)p + 1)) + { + const real r(conf.get("IMPSPINC", "ve", p)); + spese_inc.add(r, p); + } + maxadd = (real)conf.get("MAXADD"); + spadd = (real)conf.get("SPADD"); + } + + // Calcola l'eventuale importo minimo per effetti (solitamente zero) + const TRectype& cfven = clifor().vendite(); + const real impmineff = cfven.get_real(CFV_IMPMINEFF); + + // Somma le spese di ogni singola rata + const TPagamento& pag = ((TDocumento *)this)->pagamento(); + const int nrate = pag.n_rate(); + + for (int i = 0; i < nrate; i++) + { + if (pag.importo_rata(i) >= impmineff) // Se la rata supera il minimo contrattuale + { + const TTipo_pag tp = (TTipo_pag)pag.tipo_rata(i); + + if (spese_inc.objptr(tp) != NULL) + imp_spese += (const real&)spese_inc[tp]; + } + } + + if (imp_spese > ZERO && imp < maxadd) + imp_spese += spadd; + imp_spese = imp_spese * percentuale / CENTO; + + if (t == _lordo || t == _imposta) + { + TString4 codiva_es; iva_esente(codiva_es); + const real iva_spese = TRiga_documento::iva(codiva_es.full() ? (const TString&)codiva_es : codiva_spese()).imposta(imp_spese, ndec); + if (t == _lordo) + imp_spese += iva_spese; + else + if (t == _imposta) + imp_spese = iva_spese; + } + + const real cambio = get(DOC_CAMBIO); + if (!cambio.is_zero()) + { + // Converte le spese nella valuta del documento + imp_spese = change_currency(imp_spese, "", ZERO, get(DOC_CODVAL), cambio, -1); + } + + imp_spese.round(ndec); + } + + return imp_spese; +} + +void TDocumento::iva_esente(TString& codiva_es) const +{ + codiva_es.cut(0); + + const int rows = physical_rows(); + for (int r = 1; codiva_es.empty() && r <= rows; r++) + { + const TRiga_documento& riga = ((TDocumento*)this)->row(r); + const TString4 str_codiva = riga.get(RDOC_CODIVA); + + if (str_codiva.full()) + { + const TCodiceIVA codiva(str_codiva); + const TString& tipoiva = codiva.tipo(); + if (tipoiva.empty()) + break; + if (tipoiva == "NI") + codiva_es = str_codiva; + } + } +} + +real TDocumento::bolli(real & imp, int ndec, TTipo_importo t) const +{ + real tot_bolli; + static TArray sca_bolli; + static TArray imp_bolli; + static real bolli_es; + static real impmin_bolli; + static int nscagl; + + if (get_bool("ADDBOLLI")) + { + if (sca_bolli.objptr(0) == NULL) + { + TConfig conf(CONFIG_STUDIO, "ve"); + + bolli_es = (real) conf.get("BOLLIES", "ve"); + impmin_bolli = (real) conf.get("IMPMINBOLLI", "ve"); + for (nscagl = 0; nscagl < 7; nscagl++) + { + real s(conf.get("SPBOSCA", "ve", nscagl + 1)); + real i(conf.get("SPBOIMP", "ve", nscagl + 1)); + + if (s == ZERO && i == ZERO) + break; + sca_bolli.add(s, nscagl); + imp_bolli.add(i, nscagl); + } + } + if (ndec == AUTO_DECIMALS) + ndec = decimals(); + + TCurrency_documento imp_val(imp); + imp_val.change_to_firm_val(); + real importo = imp_val.get_num(); + + TPagamento & pag = ((TDocumento*)this)->pagamento(); + const int nrate = pag.n_rate(); + real old_bolli = -1.00; + real iva_bolli; + + TCurrency_documento imp_orig_val(imposta()); + imp_orig_val.change_to_firm_val(); + const real imp_orig = imp_orig_val.get_num(); + + TCurrency_documento spese_val(spese()); + spese_val.change_to_firm_val(); + const real sp_orig = spese_val.get_num(); + bool estero = FALSE; // Assumiamo per ora non estero + + TString4 codiva_es; + iva_esente(codiva_es); + + for (int j = 0; j < 5 && tot_bolli+iva_bolli != old_bolli; j++) + { + old_bolli = tot_bolli + iva_bolli; + const real imposte = imp_orig + iva_bolli; + const real imp_spese = sp_orig + tot_bolli - iva_bolli; + const real imponibile = importo - imposte - imp_spese; + tot_bolli = ZERO; + if (!tipo().nota_credito()) + { + real imponibile_esente; + for (int r = physical_rows(); r > 0; r--) + { + const TRiga_documento& riga = ((TDocumento*)this)->row(r); + const TCodiceIVA codiva(riga.get(RDOC_CODIVA)); + + if (codiva.tipo().not_empty()) + imponibile_esente += riga.imponibile(); + } + if (imponibile_esente >= impmin_bolli) + tot_bolli = bolli_es; + } + pag.set_total(imponibile, imposte, imp_spese); + pag.set_rate_auto(); + + for (int i = 0; i < nrate; i++) + { + const TTipo_pag p = (TTipo_pag) pag.tipo_rata(i); + real imp = pag.importo_rata(i); + + switch (p) + { + case _ric_ban: + { + int i; + + for (i = 0; i < nscagl - 1; i++) + if ((real &) sca_bolli[i] >= imp) + break; + if (imp_bolli.items() > 0) + tot_bolli += (real &) imp_bolli[i]; + } + break; + case _tratta: + case _tratta_acc: + { + if (j == 0) // Dobbiamo inizializzare la variabile 'estero' + { + TString16 key; + key.format("%c|%ld", get_char(DOC_TIPOCF), get_long(DOC_CODCF)); + const TRectype& clifo = cache().get(LF_CLIFO, key); + + const TString& stato_iva = clifo.get(CLI_STATOPAIV); + estero = stato_iva.not_empty() && stato_iva != "IT"; + if (!estero) + { + const TString& stato_cf = clifo.get(CLI_STATOCF); + estero = (stato_cf.not_empty() && stato_cf != "IT") || clifo.get_char(CLI_COMCF) == 'Z'; + } + } + real r(imp); + const int ndec = decimals(); + r.ceil(ndec == 0 ? -3 : 0); + if (estero) + r *= 0.009; + else + r *= 0.012; + r.round(ndec == 0 ? -2 : ndec); + tot_bolli += r; + } + break; + case _cessione: + case _paghero: + case _let_cred: + case _rim_dir: + case _rid: + case _bonfico: + default: + break; + } + } + iva_bolli = TRiga_documento::iva(codiva_bolli()).imposta(tot_bolli, ndec); + importo += (tot_bolli + iva_bolli - old_bolli); + } + if (t == _lordo) + tot_bolli += iva_bolli; + else + if (t == _imposta) + tot_bolli = iva_bolli; + + if (in_valuta()) + { + const real cambio = get_real(DOC_CAMBIO); + tot_bolli = change_currency(tot_bolli, "", ZERO, get(DOC_CODVAL), cambio, -1); + } + tot_bolli.round(ndec); + } + + return tot_bolli; +} + +const TString & TDocumento::commessa_principale() const +{ + if (codice_commessa().blank()) + { + const int row = physical_rows(); + + for (int i = 1; i <= rows(); i++) + { + const TRiga_documento &r = ((TRiga_documento &) ((TDocumento *)this)->row(i)); + + if (!r.codice_commessa().blank()) + return r.codice_commessa(); + } + } + return codice_commessa(); +} + +// Controlla se un documento è incluso nelle statistiche definitive +static bool doc_invalidating_stats(const TDocumento& doc) +{ + bool inv = false; + if (dongle().active(SVAUT) && doc.tipo().statistiche()) + { + const TDate datadoc = doc.get(DOC_DATADOC); + if (datadoc.ok()) + { + const TDate datalast = ini_get_string(CONFIG_DITTA, "sv", "UltimoCalcolo"); + inv = datadoc <= datalast; + } + } + return inv; +} + +bool TDocumento::modificabile() const +{ + bool maybe = true; + + const char stato_attuale = stato(); + if (stato_attuale > ' ') + { + const TString& stati_modifica = tipo().stati_iniziali_modifica(); + maybe = stati_modifica.blank() || stati_modifica.find(stato_attuale) >= 0; + + if (maybe && doc_invalidating_stats(*this)) + maybe = false; + } + + return maybe; +} + +bool TDocumento::cancellabile() const +{ + bool maybe = true; + + const char stato_attuale = stato(); + if (stato_attuale > ' ') + { + const TString& stati_cancellazione = tipo().stati_iniziali_cancellazione(); + maybe = stati_cancellazione.blank() || stati_cancellazione.find(stato_attuale) >= 0; + + if (maybe && doc_invalidating_stats(*this)) + maybe = false; + } + return maybe; +} + +bool TDocumento::stampabile() const +{ + const char stato_attuale = stato(); + if (stato_attuale <= ' ') + return true; + + if (stato_attuale == tipo().stato_finale_stampa()) + return false; + + const TString& stati_stampa = tipo().stati_iniziali_stampa(); + return stati_stampa.blank() || stati_stampa.find(stato_attuale) >= 0; +} + +bool TDocumento::bloccato() const +{ + const char stato_attuale = stato(); + if (stato_attuale <= ' ') + return false; + + if (doc_invalidating_stats(*this)) + return true; + + char stato_bloccato = tipo().stato_bloccato(); + if (stato_bloccato <= ' ') + return false; + + return stato_attuale >= stato_bloccato; +} + +bool TDocumento::chiuso() const +{ + if (!tipo().is_scontrino()) + return false; + + const char stato_attuale = stato(); + if (stato_attuale <= ' ') + return false; + + char stato_chiuso = tipo().stato_chiuso(); + if (stato_chiuso <= ' ') + return false; + + return stato_attuale >= stato_chiuso; +} + +// Funzione statica utile a tutti gli utenti di LF_DOC e LF_RIGHEDOC +void TDocumento::set_key(TRectype& rec, char provv, int anno, const char* codnum, long numdoc) +{ + CHECK(provv == 'D' || provv == 'P', "Provvisorio o Definitivo?"); + CHECKD(anno > 1900, "Anno non valido: ", anno); + CHECK(codnum && *codnum, "Codice numerazione nullo"); + CHECKD(numdoc >= 0, "Numero documento non valido ", numdoc); + + rec.put(DOC_PROVV, provv); + rec.put(DOC_ANNO, anno); + rec.put(DOC_CODNUM, codnum); + rec.put(DOC_NDOC, numdoc); +} + +// Funzione statica utile a tutti gli utenti di LF_DOC e LF_RIGHEDOC +void TDocumento::copy_data(TRectype& dst, const TRectype& src) +{ + const bool is_riga = dst.num() == LF_RIGHEDOC; + + // Memorizza tutti i campi chiave + const char provv = dst.get_char(RDOC_PROVV); + const int anno = dst.get_int(RDOC_ANNO); + const TString4 codnum = dst.get(RDOC_CODNUM); + + const long numdoc = dst.get_long(RDOC_NDOC); + const int nriga = is_riga ? dst.get_int(RDOC_NRIGA) : 0; + const long idriga = is_riga ? dst.get_long(RDOC_IDRIGA) : 0; + // Copia tutto il record + dst = src; + // Ripristina tutti i campi chiave + set_key(dst, provv, anno, codnum, numdoc); + dst.init_memo(RECORD_NON_FISICO); + if (is_riga) + { + dst.put(RDOC_NRIGA, nriga); + dst.put(RDOC_IDRIGA, idriga); + dst.zero(RDOC_MOVMAG); + const TString& memo = src.get(RDOC_DESCEST); + dst.put(RDOC_DESCEST, memo); + const TString& g1 = src.get(RDOC_RG1); + dst.put(RDOC_RG1, g1); + ((TRiga_documento&)dst).load_memo(); + } + else + { + dst.zero(DOC_MOVMAG); + dst.zero(DOC_NUMREG); + dst.zero(DOC_NUMREGCA); + dst.put(DOC_NOTE, src.get(DOC_NOTE)); + } +} + +// Funzione statica utile a tutti gli utenti di LF_RIGHEDOC +void TDocumento::copy_data(TRiga_documento& dst, const TRiga_documento& src) +{ + copy_data((TRectype&)dst, (const TRectype&)src); + dst.put(RDOC_CODCMS, src.codice_commessa()); + dst.put(RDOC_FASCMS, src.fase_commessa()); + dst.put(RDOC_CODCOSTO, src.codice_costo()); +} + +void TDocumento::copy_contents(const TDocumento& src, bool copy_header) +{ + if (copy_header) + copy_data(head(), src.head()); + destroy_rows(); + const int rows = src.physical_rows(); + for (int i = 1; i <= rows ; i++) + { + const TRiga_documento& s = src[i]; + TRiga_documento & r = new_row(s.tipo().codice()); + copy_data(r, s); + r.set_original_rdoc_key(s); + } +} + +TRiga_documento& TDocumento::insert_row(int row, const char *tipo) +{ + TRiga_documento& r = (TRiga_documento&)TMultiple_rectype::insert_row(row); + if (tipo && *tipo) + r.set_tipo(tipo); + return r; +} + +TRiga_documento& TDocumento::new_row(const char *tipo) +{ + TRiga_documento& r = (TRiga_documento&)TMultiple_rectype::new_row(); + + r.set_doc(this); + if (tipo && *tipo) + r.set_tipo(tipo); + return r; +} + +void TDocumento::on_read(int err, word lockop) +{ + _cli_for.zero(); + _occas.zero(); + + set_riga_sconto(); + if (is_fattura()) + set_riga_esenzione(); + _stato_originale = stato(); + +#ifdef LIVE_STATISTICS + if (err == NOERR && _has_stat_ven && tipo_valido() && tipo().statistiche() ) + { + const TDoc_key key(head()); + TObject* o = _docs_to_agg.objptr(key); + + const bool is_nota_credito = tipo().nota_credito(); + + if (lockop >= _lock && o == NULL) + { + TStats_agg* st_agg = new TStats_agg; + for (int i = physical_rows(); i > 0; i--) + { + if (is_nota_credito) + st_agg->add(row(i)); + else + st_agg->sub(row(i)); + } + _docs_to_agg.add(key, st_agg, true); + } + else + { + if (lockop == _unlock && o != NULL) + _docs_to_agg.remove(key); + } + } +#endif + + _old_agente.cut(0); + _old_agente1.cut(0); + if (err == NOERR && _has_provv) + { + _old_agente = get(DOC_CODAG); + _old_agente1 = get(DOC_CODAGVIS); + } +} + +int TDocumento::read(TBaseisamfile& f, word op, word lockop) +{ + const int err = TMultiple_rectype::read(f, op, lockop); + on_read(err, lockop); + return err; +} + +int TDocumento::readat(TBaseisamfile& f, TRecnotype nrec, word lockop) +{ + const int err = TMultiple_rectype::readat(f, nrec, lockop); + on_read(err, lockop); + return err; +} + +int TDocumento::read(char provv, int anno, const char* codnum, long numdoc, word op, word lockop) +{ + CHECK(numdoc > 0, "Numero documento nullo."); + zero(); + set_key(*this, provv, anno, codnum, numdoc); + return read(op, lockop); +} + +long TDocumento::renum_ndoc(long numdoc) +{ + if (numdoc <= 0) + { + const char tn = tipo_numerazione(); + const int an = anno(); + const TString4 nu = numerazione(); + numdoc = get_next_key(tn, an, nu); + } + put(DOC_NDOC, numdoc); // Aggiorna testata + TMultiple_rectype::renum_key(); // Aggiorna righe ok + return numdoc; +} + +void TDocumento::set_riga_sconto() +{ + const TString80 sconto(get(DOC_SCONTOPERC)); + + if (!is_real_discount(sconto)) + { + if(_sconto != NULL) + delete _sconto; + _sconto = NULL; + } + else + { + if (_sconto == NULL) + { + static TString4 _tipo_riga_sc; + if (_tipo_riga_sc.empty()) + { + TConfig conf(CONFIG_STUDIO, "ve"); + _tipo_riga_sc = conf.get("TRSCONTI", "ve"); + // Se non esiste il tipo riga lo cerca, lo setta di default ed avvisa + if (_tipo_riga_sc.empty()) + { + _tipo_riga_sc = "08"; + conf.set("TRSCONTI", _tipo_riga_sc); + warning_box(FR("Il tipo riga sconti di testa non risultava impostato.\nL'applicazione userà automaticamente il tipo %s"), (const char*) _tipo_riga_sc); + } + } + _sconto = new TRiga_documento(this, _tipo_riga_sc); + _sconto->put(RDOC_DESCR, TR("Sconto")); + } + _sconto->put(RDOC_SCONTO, sconto); + } +} + +void TDocumento::update_esenzione() +{ + if (clifor().use_lettere()) + { + bool to_update = false; + const TString4 codiva = codesiva(); + for (int i = physical_rows(); !to_update && i > 0; i--) + { + const TString & cod = row(i).get(RDOC_CODIVA); + to_update = cod.full() && cod != codiva; + } + + if (to_update) + for (int i = physical_rows(); i > 0; i--) + { + TRiga_documento & rdoc = row(i); + const TString& cod = rdoc.get(RDOC_CODIVA); + + if (cod.full()) + { + if (codiva.full()) + rdoc.put(RDOC_CODIVA, codiva); + else + { + const TCodiceIVA i(cod); + const bool plafond = i.get_int("S3") > 0; + + if (plafond) + { + TString4 codivarow; + + if (rdoc.is_merce()) + codivarow =cached_article(rdoc.get(RDOC_CODARTMAG)).get(ANAMAG_CODIVA); + else + if (rdoc.is_spese()) + { + const TSpesa_prest s(rdoc.get(RDOC_CODART)); + codivarow = s.cod_iva(); + } + else + if (rdoc.is_prestazione()) + { + TSpesa_prest p(rdoc.get(RDOC_CODART), 'P'); + codivarow = p.cod_iva(); + } + else + if (rdoc.is_risorsa()) + { + TSpesa_prest r(rdoc.get(RDOC_CODART), 'R'); + codivarow = r.cod_iva(); + } + else + if (rdoc.is_attrezzatura()) + { + TSpesa_prest a(rdoc.get(RDOC_CODART), 'A'); + codivarow = a.cod_iva(); + } + if (codivarow.full()) + rdoc.put(RDOC_CODIVA, codivarow); + } + } + } + } + } +} + +void TDocumento::set_riga_esenzione() +{ + TCli_for & c = clifor(); + const TCodiceIVA codes(c.vendite().get(CFV_ASSFIS)); + TString16 v_esenzione; + TString16 v_data_esenzione; + TString16 n_registrazione; + TString16 n_data_registrazione; + + if (codes.codice().full()) + get_protocolli_esenzione(v_esenzione, v_data_esenzione, n_registrazione, n_data_registrazione); + bool esente = codes.tipo().not_empty() && v_esenzione.not_empty() && + v_data_esenzione.not_empty() && n_registrazione.not_empty() && + n_data_registrazione.not_empty(); + if (esente) + { + esente = false; + const TString4 codiva = codes.codice(); + for (int i = physical_rows(); !esente && i > 0; i--) + esente = row(i).get(RDOC_CODIVA) == codiva; + } + + if (!esente) + { + if (_esenzione != NULL) + { + delete _esenzione; + _esenzione = NULL; + } + } + else + { + static TString4 _tipo_riga_es; + static TString80 _des_esenz; + static real _bollo_es; + if (_tipo_riga_es.empty()) + { + TConfig conf(CONFIG_STUDIO, "ve"); + _tipo_riga_es = conf.get("TRESENZ", "ve"); + _bollo_es = (real)conf.get("BOLLIES", "ve"); + if (_tipo_riga_es.empty()) + { + _tipo_riga_es = "05"; + conf.set("TRESENZ", _tipo_riga_es); + warning_box("Il tipo riga esenzione non risultava impostato.\n L'applicazione userà automaticamente il tipo %s", (const char*) _tipo_riga_es); + } + _des_esenz = conf.get("DESESENZ", "ve"); + if (_des_esenz.not_empty()) + _des_esenz.insert(" "); + _des_esenz.insert("Fattura non imponibile"); + } + if (_esenzione == NULL) + _esenzione = new TRiga_documento(this, _tipo_riga_es); + TString d(256); d = _des_esenz; + + d << format(" come da vostra dichiarazione n. %s del %s da noi annotata al n. %s il %s.", + (const char*)v_esenzione, (const char*)v_data_esenzione, + (const char*)n_registrazione, (const char*)n_data_registrazione); + _esenzione->set_descr(d); + } +} + +void TDocumento::dirty_fields() +{ + if (!_dirty_deny) + { + for (TDocumento_variable_field* f = (TDocumento_variable_field*)first_variable_field(); + f != NULL; f = (TDocumento_variable_field*)succ_variable_field()) + f->set_dirty(); + dirty_tabella_iva(); + + if (loaded_rows(LF_RIGHEDOC)) // Se ho già caricato delle righe in memoria + { + TRecord_array& righe = body(LF_RIGHEDOC); + for (int i = righe.last_row(); i > 0; i = righe.pred_row(i)) + { + TRiga_documento& r = (TRiga_documento&)righe[i]; + r.dirty_fields(false); + } + } + _dirty_deny = true; + } +} + +static TToken_string * __key; + +HIDDEN int sort_doc_rows(const TObject** r0, const TObject** r1) +{ + TRiga_documento* row0 = (TRiga_documento*)*r0; + TRiga_documento* row1 = (TRiga_documento*)*r1; + int res = 0; + + TString val0, val1; + TToken_string valist(50,','); + + FOR_EACH_STR_TOKEN(*__key, fldname) + { + int direction = +1; + if (fldname[0] == '-') + { + direction = -1; + fldname.ltrim(1); + } + const int par = fldname.find('('); + if (par > 0) + { + valist = fldname.mid(par+1); + valist.strip("()"); + fldname.cut(par); + } + else + valist.cut(0); + + const TFieldref fld(fldname, 0); + val0 = fld.read(*row0); + val1 = fld.read(*row1); + + switch (row0->type(fld.name())) + { + case _intfld : + case _longfld : + case _realfld : + case _wordfld : + { + const real r0 = val0; + const real r1 = val1; + + if (r0 != r1) + res = (r0 < r1 ? -1 : 1) * direction; + } + break; + case _datefld : + { + const TDate d0 = val0; + const TDate d1 = val1; + + if (d0 != d1) + res = (d0 < d1 ? -1 : 1) * direction; + } + break; + default: + if (val0 != val1) + { + if (valist.full()) + { + int pos0 = valist.get_pos(val0); if (pos0 < 0) pos0 = valist.items(); + int pos1 = valist.get_pos(val1); if (pos1 < 0) pos1 = valist.items(); + res = (pos0 - pos1) * direction; + } + else + res = xvt_str_compare_ignoring_case(val0, val1) * direction; + } + break; + } + if (res != 0) + break; + } + return res; +} + +void TDocumento::sort_rows(const char* key) +{ + __key = new TToken_string(key); + body().sort(sort_doc_rows); + delete __key; + __key = NULL; +} + +static real doc_inventory_qta(const TCausale_magazzino & cau, const TString & codart, const TString & codmag, + const TString & livello, int anno, const real & qta) +{ + const real giac = cached_article_balances(codart).giacenza_anno(codmag, livello, anno); + + real q = qta - giac; + switch (cau.sgn(s_giac)) + { + case 1: break; + case -1: q = -q; break; + default: break; + } + return q; +} + +int TDocumento::write_rewrite(TBaseisamfile & f, bool re) const +{ + TDocumento& myself = *((TDocumento *)this); + const bool new_doc = nuovo() || numero() <= 0; // E' nuovo di zecca! + + if (new_doc) + { + char stato_finale = tipo().stato_finale_inserimento(); + if (stato() == '\0' && stato_finale > ' ') + myself.stato(stato_finale); + } + else + myself._stato_originale = stato(); + + const bool doc_bloccato = bloccato(); + const char stato_doc(stato()); + + int err = NOERR; + + if (!doc_bloccato) + { + if (tipo().spese_aut() && !get_bool(DOC_SPESEUPD)) + { + char name[8] = "CODSP0"; + TString_array spese; + const TRectype& ven_rec = clifor().vendite(); + for (int i = 1; i <= 4; i++) + { + name[5] = '0' + i; + const TString& s = ven_rec.get(name); + if (s.full()) + spese.add(s); + } + myself.update_spese_aut(spese); + } + myself.update_conai(); + myself.update_raee(); + myself.set_row_ids(); + myself.put(DOC_UTENTE, user()); + myself.put(DOC_DATAAGG, TDate(TODAY)); + + const bool check_movmag = _has_mag && tipo().mov_mag(); + if (check_movmag) + { + const bool do_movmag = tipo().stato_with_mov_mag(stato_doc) && get(DOC_CAUSMAG).full(); + long num_movmag = get_long(DOC_MOVMAG); + bool diff_inv = get_bool("DIFFINV"); + + TMov_mag_doc mov; + TLocalisamfile m(LF_MOVMAG); + mov.zero(); + if (!new_doc && do_movmag && num_movmag <= 0) + { + m.setkey(6); + m.zero(); + m.put(MOVMAG_DOCPROVV, myself.get(DOC_PROVV)); + m.put(MOVMAG_ANNODOC, myself.anno()); + m.put(MOVMAG_CODNUM, myself.numerazione()); + m.put(MOVMAG_NUMDOC, myself.numero()); + if (m.read(_isequal) == NOERR) + { + num_movmag = m.get_long(MOVMAG_NUMREG); + myself.put(DOC_MOVMAG, num_movmag); + } + m.setkey(1); + m.zero(); + } + if (do_movmag && num_movmag <= 0) + { + err = mov.write(m); + if (err != NOERR) + return err; + num_movmag = mov.get_long(MOVMAG_NUMREG); + myself.put(DOC_MOVMAG, num_movmag); + } + if (num_movmag > 0) + { + const bool scarica_residuo = tipo().scarica_residuo(); + + mov.put(MOVMAG_NUMREG, num_movmag); + while (mov.read(m, _isequal, _testandlock) == _islocked) + message_box("Movimento di magazzino n. %ld in uso da parte di un'altro utente", num_movmag); + if (do_movmag) + { + TRecord_array & b = mov.body(); + const int mag_rows = mov.rows(); + int i; + for (i = mag_rows; i > 0; i--) + { + TRectype & r = b[i]; + if (r.get_char(RMOVMAG_TIPORIGA) == riga_dadocumento) + { + b.destroy_row(i); + if (b.exist(i + 1) && + b[i + 1].get_char(RMOVMAG_TIPORIGA) == riga_automatica) + b.destroy_row(i + 1); + } + else + if (r.get_bool(RMOVMAG_ESPLOSA)) + b.destroy_row(i); + } + b.pack(); + + const TDate d(get(DOC_DATADOC)); + TString4 codes; codes.format("%04d", mov.codice_esercizio(d)); + mov.put(MOVMAG_ANNOES, codes); + mov.put(MOVMAG_DATAREG, d); + mov.put(MOVMAG_DATACOMP, d); + mov.put(MOVMAG_DOCPROVV, get(DOC_PROVV)); + mov.put(MOVMAG_ANNODOC, get(DOC_ANNO)); + mov.put(MOVMAG_CODNUM, get(DOC_CODNUM)); + long numdoc = get_long(DOC_NDOC); + if (numdoc <= 0L) + numdoc = myself.renum_ndoc(numdoc); + + mov.put(MOVMAG_NUMDOC, numdoc); + const long ex_numdoc = get_long(DOC_NUMDOCRIF); + if (ex_numdoc == 0) + { + mov.put(MOVMAG_EXNUMDOC, numdoc); + mov.put(MOVMAG_EXDATADOC, d); + } + else + { + mov.put(MOVMAG_EXNUMDOC, ex_numdoc); + const TDate ex_d(get("DATADOCRIF")); + mov.put(MOVMAG_EXDATADOC, ex_d); + } + mov.put(MOVMAG_CATVEN, get("CATVEN")); + mov.put(MOVMAG_CODLIST, get("CODLIST")); + mov.put(MOVMAG_CODCONT, get("CODCONT")); + mov.put(MOVMAG_CODCAMP, get("CODCAMP")); + mov.put(MOVMAG_CODCAUS, get("CAUSMAG")); + const TString4 codnum(numerazione()); + + mov.put(MOVMAG_DESCR, format("%s %s n. %ld del %s", (const char *) tipo().get("S1"),(const char *)codnum, numdoc, (const char *) d.string())); + mov.put(MOVMAG_TIPOCF, get("TIPOCF")); + mov.put(MOVMAG_CODCF, get("CODCF")); + if (ini_get_bool(CONFIG_DITTA, "mg", "MOV_INDSPED")) + mov.put(MOVMAG_CODINDSP, get(DOC_CODINDSP)); + + int j = 1; + real cambio = ZERO; + + if (get(DOC_CODVAL).not_empty()) + cambio = get_real(DOC_CAMBIO); + if (cambio == ZERO) + cambio = 1.0; + const TString8 cod_caus(mov.get(MOVMAG_CODCAUS)); + const TCausale_magazzino & caus = cached_causale_magazzino(cod_caus); + const bool esplodente = caus.esplodente(); + const bool scarica_alt = caus.scarica_alternativi(); + TString8 cod_caus_riga; + TDistinta_tree dist; + TCodice_articolo codart; + const int anno = get_int(DOC_ANNO); + + for (i = 1; i <= physical_rows(); i++) + { + TRiga_documento & r = myself.row(i); + const bool articolo = r.is_articolo(); + bool valid_row = articolo; + + cod_caus_riga = r.get(RDOC_CAUSMAG); + if (articolo) + codart = r.get(RDOC_CODARTMAG); + else + { + codart = r.get(RDOC_CODART); + if (codart.full() && (cod_caus_riga.full() ? cached_causale_magazzino(cod_caus_riga).esplodente() : esplodente)) + valid_row = dist.set_root(codart); + } + if (valid_row) + { + long r_num = r.get_long(RDOC_MOVMAG); + if (r_num == 0) + { + r_num = num_movmag; + r.put(RDOC_MOVMAG, r_num); + } + + real qta = scarica_residuo ? r.qtaresidua_mag(): r.quantita_mag(); + const TString8 codmag = r.get(RDOC_CODMAG); + const TString livello = r.get(RDOC_LIVELLO); + if (diff_inv) + qta = doc_inventory_qta((cod_caus_riga.full() ? cached_causale_magazzino(cod_caus_riga) : caus), codart, + codmag, livello, anno, qta); + + if (r_num == num_movmag && !qta.is_zero()) + { + TRectype & rm = mov.insert_row(j++); + + mov.add_magc(r.get(RDOC_CODMAGC)); + + rm.put(RMOVMAG_IMPIANTO, r.get(RDOC_IMPIANTO)); + rm.put(RMOVMAG_LINEA, r.get(RDOC_LINEA)); + const TString8 codmag = r.get(RDOC_CODMAG); + rm.put(RMOVMAG_CODMAG, codmag); + if (articolo && (cod_caus_riga.full() ? cached_causale_magazzino(cod_caus_riga).scarica_alternativi() : scarica_alt)) + { + const TRectype art = cache().get(LF_ANAMAG, codart); + const TString & alt = art.get(ANAMAG_CODARTALT); + + if (alt.full()) + codart = alt; + } + rm.put(RMOVMAG_CODART, codart); + const TString livello = r.get(RDOC_LIVELLO); + rm.put(RMOVMAG_LIVGIAC, livello); + rm.put(RMOVMAG_UM, r.get(RDOC_UMQTA)); + + if (diff_inv) + qta = doc_inventory_qta((cod_caus_riga.full() ? cached_causale_magazzino(cod_caus_riga) : caus), codart, + codmag, livello, anno, qta); + + rm.put(RMOVMAG_QUANT, qta); + + TCurrency_documento prezzo(r.prezzo(true, FALSE), *this, true); + + prezzo.change_to_firm_val(); + rm.put(RMOVMAG_PREZZO, prezzo.get_num()); + rm.put(RMOVMAG_CODCAUS, cod_caus_riga); + rm.put(RMOVMAG_TIPORIGA, (char) riga_dadocumento); + } + + if (main_app().has_module(LVAUT)) + { + const TString & codcauslav = r.get(RDOC_CODAGG1); + const TRectype & caulav = cache().get("&LVCAU", codcauslav); + if (!caulav.empty()) + { + if (!qta.is_zero() && (j > 1)) + { + const TString & causcons = caulav.get("S2"); + + if (causcons.full()) + { + mov[LF_RMOVMAG][j - 1].put(RMOVMAG_CODCAUS, causcons); + mov[LF_RMOVMAG][j - 1].put(RMOVMAG_CODMAG, r.get(RDOC_CODMAGC)); + mov.reset_magc(j - 1); + } + else + { + mov.destroy_row(--j, true); + mov.destroy_magc(j); + } + } + + const real qtarit = r.get(RDOC_QTAGG1); + const TString & causrit = caulav.get("S1"); + + if (r_num == num_movmag && !qtarit.is_zero() && causrit.full()) + { + TRectype & rm = mov.insert_row(j++); + + mov.add_magc(""); + rm.put(RMOVMAG_IMPIANTO, r.get(RDOC_IMPIANTO)); + rm.put(RMOVMAG_LINEA, r.get(RDOC_LINEA)); + rm.put(RMOVMAG_CODMAG, r.get(RDOC_CODMAG)); + if (articolo && (causrit.full() ? cached_causale_magazzino(causrit).scarica_alternativi() : scarica_alt)) + { + const TRectype art = cache().get(LF_ANAMAG, codart); + const TString & alt = art.get(ANAMAG_CODARTALT); + + if (alt.full()) + codart = alt; + } + rm.put(RMOVMAG_CODART, codart); + rm.put(RMOVMAG_LIVGIAC, r.get(RDOC_LIVELLO)); + rm.put(RMOVMAG_UM, r.get(RDOC_UMQTA)); + rm.put(RMOVMAG_QUANT, qtarit); + rm.put(RMOVMAG_CODCAUS, causrit); + rm.put(RMOVMAG_TIPORIGA, (char) riga_dadocumento); + } + } + } + } + + const TString & indetr = r.get(RDOC_TIPODET); + + if (indetr.full()) + { + const TRectype & det = cache().get("%DET", indetr); + + if (!det.empty() && !det.get_bool("FPC")) + { + TTable tab("%DET"); + + tab.curr() = det; + tab.curr().put("FPC", "X"); + tab.rewrite(); + } + } + + } + mov.rewrite(m); + } + else + { + mov.remove(m); + for (int i = physical_rows(); i > 0; i--) + { + TRiga_documento & r = myself.row(i); + r.zero(RDOC_MOVMAG); + } + myself.zero(DOC_MOVMAG); + } + } + } + } + + { + TLocalisamfile anamag(LF_ANAMAG); + TLocalisamfile codalt(LF_CODCORR); + codalt.setkey(2); + bool docevaso = true; + const TDate datacons(get_date(DOC_DATACONS)); + const TString80 codcms(get(DOC_CODCMS)); + const TString80 fascms(get(DOC_FASCMS)); + const TString80 codcos(get(DOC_CODCOSTO)); + + for (int i = physical_rows(); i > 0; i--) + { + TRiga_documento& r = myself.row(i); + if ((r.is_merce() || r.is_omaggio()) && !r.is_checked()) + { + if (r.get(RDOC_CODARTMAG) == NULL_CODART) + r.put(RDOC_CODARTMAG, ""); + else + { + const TString & codart = r.get("CODART"); + anamag.put("CODART", codart); + if (anamag.read() == NOERR) + r.put("CODARTMAG", codart); + else + { + codalt.put("CODARTALT", codart); + if (codalt.read() == NOERR) + r.put("CODARTMAG", codalt.get("CODART")); + } + r.checked(); + } + } + if (r.is_evadibile() && datacons.ok()) // on 27-9-2013 was if (r.is_evadibile() && is_ordine()) + { + docevaso &= r.is_evasa(); + const TDate dcons = r.get_date(RDOC_DATACONS); + if (!dcons.ok()) + r.put(RDOC_DATACONS, datacons); + } + + /* dal 27-9-2013 considero singolarmente i campi di analitica replicati sulle righe + if (r.get(RDOC_CODCMS).blank() && r.get(RDOC_FASCMS).blank() && r.get(RDOC_CODCOSTO).blank()) + { + r.put(RDOC_CODCMS, codcms); + r.put(RDOC_FASCMS, fascms); + r.put(RDOC_CODCOSTO, codcos); + } + */ + if (r.get(RDOC_CODCMS).blank()) r.put(RDOC_CODCMS, codcms); + if (r.get(RDOC_FASCMS).blank()) r.put(RDOC_FASCMS, fascms); + if (r.get(RDOC_CODCOSTO).blank()) r.put(RDOC_CODCOSTO, codcos); + } + if (is_ordine()) + ((TDocumento *)this)->put(DOC_DOCEVASO, docevaso); // Tutte le righe evase -> doc evaso + } // Almeno una riga aperta -> doc aperto + + err = TMultiple_rectype::write_rewrite(f, re); + + if (!doc_bloccato && err == NOERR) + { + if (clifor().occasionale()) + { + if (get("OCFPI").not_empty()) + { + TLocalisamfile o(LF_OCCAS); + TOccasionale & occ = occas(); + + err = occ.write(o); + if (err == _isreinsert) + err = occ.rewrite(o); + } + } + if (_has_provv && tipo().provvigioni() && tipo().stato_provvigioni() <= stato()) + myself.update_provvigioni(false); + +#ifdef LIVE_STATISTICS + if (_has_stat_ven && tipo().statistiche()) + { + const TDoc_key key(myself.head()); + TStats_agg* st_agg = (TStats_agg*)_docs_to_agg.objptr(key); + const bool is_nota_credito = tipo().nota_credito(); + + if (st_agg == NULL) + { + st_agg = new TStats_agg; + _docs_to_agg.add(key, st_agg, true); + } + + for (int i = physical_rows(); i > 0; i--) + { + if (is_nota_credito) + st_agg->sub(myself.row(i)); + else + st_agg->add(myself.row(i)); + } + st_agg->update(); + for (int i = physical_rows(); i > 0; i--) + { + if (is_nota_credito) + st_agg->add(myself.row(i)); + else + st_agg->sub(myself.row(i)); + } + } + +#endif + } + return err; +} + +// eliminare anche il mov di mag. ?????? +int TDocumento::remove(TBaseisamfile& f) const +{ + if (!cancellabile() && !delete_box("Documento non cancellabile.\nSi desidera continuare ugualmente?")) + return NOERR; + const bool check_movmag = _has_mag && tipo().mov_mag(); + const bool doc_bloccato = bloccato(); + + if (check_movmag) + { + const long num = get_long("MOVMAG"); + + if (num > 0) + { + TMov_mag_doc mov; + TLocalisamfile m(LF_MOVMAG); + mov.put(MOVMAG_NUMREG, num); + while (mov.read(m, _isequal, _testandlock) == _islocked) + message_box("Movimento di magazzino in uso da parte di un'altro utente"); + if (doc_bloccato) + { + const int rows = mov.rows(); + for (int i= 1; i <= rows; i++) + mov.body()[i].zero(RMOVMAG_TIPORIGA); + mov.rewrite(m); + } + else + mov.remove(m); + } + } + if (!doc_bloccato) + { +#ifdef LIVE_STATISTICS + if (_has_stat_ven && tipo().statistiche()) + { + const TDoc_key key(head()); + TStats_agg* st_agg = (TStats_agg*)_docs_to_agg.objptr(key); + if (st_agg != NULL) + { + st_agg->update(); + _docs_to_agg.remove(key); + } + } +#endif + if (_has_provv && tipo().provvigioni()) + { + TDocumento& myself = *((TDocumento *)this); + myself.update_provvigioni(true); + } + } + return TMultiple_rectype::remove(f); +} + +int TDocumento::decimals(bool price) const +{ + const TString4 codval(get(DOC_CODVAL)); + const TExchange exc(codval); + const int ndec = exc.decimals(price); + return ndec; +} + +void TDocumento::flush_rows() +{ + remove_body(LF_RIGHEDOC); +} + +void TDocumento::calc_provvigione(TProvvigioni_agente & provv, const TString & key, bool first, bool generata) +{ + const int anno = TDocumento::anno(); + const TString4 codnum = numerazione(); + const long ndoc = numero(); + const TDate datadoc(data()); + + while (provv.read(key, anno, codnum, ndoc) == _islocked) // Legge le provvigioni per questo documento + if (!yesno_box("Dati agente %s in uso da un altro utente. Riprovare?", (const char *) key)) + return ; + + const real change(cambio()); + const real perc = provv.perc_fatt(); + TCurrency_documento tot_doc(totale_doc(), *this); + TCurrency_documento tot_netto(totale_netto(), *this); + TCurrency_documento tot_provv(provvigione(first), *this); + TCurrency_documento provv_fat((tot_provv.get_num() / CENTO) * perc, *this); // Provvigione sul fatturato (rata 0) + TCurrency_documento provv_pag = tot_provv - provv_fat; // Provvigione sul pagato (da suddivere secondo il pagamento) + const bool valuta = in_valuta(); + + // Calcolo rate per provvigioni e documento + TPagamento& pag1 = pagamento(); // Per rate documento + TPagamento* pag2 = new TPagamento(pag1.code(), datadoc.string()); // Per rate documento + + // Rilegge il pagamento, nel caso in cui venga chiamata la scrittura del documento + // corrente dopo che è stata effettuata una contabilizzazione; la contabilizzazione + // nel caso di anticipo aggiunge una rata in più + if (pag1.n_rate() > pag2->n_rate()) + pag1.read(); + + TCurrency_documento totspese(spese(), *this); + TCurrency_documento totimposte(imposta(), *this); + TCurrency_documento totimponibili(tot_doc - totimposte - totspese); + TCurrency_documento anticipo(get_real(DOC_IMPPAGATO), *this); + + if (is_nota_credito()) // Se il documento e' una nota di credito, cambia segno + { + tot_doc = -tot_doc; + tot_netto = -tot_netto; + tot_provv = -tot_provv; + provv_fat = -provv_fat; + provv_pag = -provv_pag; + totspese = -totspese; + totimposte = -totimposte; + totimponibili = -totimponibili; + } + + // Considera l'anticipo, come in contabilizzazione ed in generazione effetti + // + // Un anticipo su di una nota di credito non dovrebbe comunque mai esistere, non ha senso. + // Se esiste è un errore in inserimento da parte del cliente. + if (anticipo.get_num() < abs(tot_doc.get_num())) + { + TGeneric_distrib d(anticipo.get_num(), decimals()); + + d.add(totimponibili.get_num()); + d.add(totimposte.get_num()); + d.add(totspese.get_num()); + + const TCurrency_documento pagtotimponibili(totimponibili.get_num() - d.get(), *this); + const TCurrency_documento pagtotimposte(totimposte.get_num() - d.get(), *this); + const TCurrency_documento pagtotspese(totspese.get_num() - d.get(), *this); + + TCurrency zero(ZERO); + if (valuta) + { + TCurrency_documento val2(pagtotimposte); val2.change_to_firm_val(); + TCurrency_documento val3(pagtotspese); val3.change_to_firm_val(); + TCurrency_documento val1(tot_doc); val1.change_to_firm_val(); val1 -= val2 - val3; + pag1.set_total_valuta(pagtotimponibili, pagtotimposte, pagtotspese, val1, val2, val3); + TCurrency_documento provv_pag_base(provv_pag) ; provv_pag_base.change_to_firm_val(); + pag2->set_total_valuta(provv_pag, zero, zero, provv_pag_base, zero, zero); + } + else + { + pag1.set_total(pagtotimponibili, pagtotimposte, pagtotspese); + pag2->set_total(provv_pag, zero, zero); + } + pag1.set_rate_auto(); + pag2->set_rate_auto(); + } + else + { + pag1.zap_rate(); + pag2->zap_rate(); + } + + const bool is_anticipo = anticipo.get_num() > ZERO; + + if (is_anticipo) + { + pag1.add_rata(); + TDate first_scad(pag1.data_rata(0)); + + if (datadoc == first_scad) + pag1.set_datarata(0, ++first_scad); + for (int k=pag1.n_rate()-1; k>0; k--) + pag1.rata(k) = pag1.rata(k-1); + + if (anticipo >= tot_doc) + anticipo = tot_doc; + + TCurrency_documento anticipo_base(anticipo); anticipo_base.change_to_firm_val(); + + pag1.set_rata(0, valuta ? anticipo.get_num() : ZERO, anticipo_base.get_num(), datadoc, 1, "", FALSE); + } + + // Crea le nuove rate provvigionali + const bool isnew = provv.items() == 0; // Il documento non ha righe provvigionali + TRate_doc& rd = provv.rate(anno, codnum, ndoc, isnew); + + // A questo punto rd e' vuoto: settiamo i dati del documento: + const int ndec = tot_doc.decimals(); + + TToken_string t; + t.add(anno); t.add(codnum); t.add(ndoc); t.add(datadoc.string()); + t.add(tot_doc.get_num().string(-1, ndec)); + t.add(tot_provv.get_num().string(-1, ndec)); + t.add(tot_netto.get_num().string(-1, ndec)); + t.add(codcf()); + t.add(TDocumento::valuta()); + t.add(change.string()); + t.add(get(DOC_DATACAMBIO)); + rd.set(t); + + // Adesso si possono aggiungere le rate (per quelle gia' esistenti sostituisce solo alcuni valori) + // - Rata 0 : importo rata = 0; importo provvigione = provvigione all'atto della fattura (percentuale sugli agenti) + // data scadenza viene settata uguale alla data documento + // la provvigione rimanente va suddivisa in rate a seconda del codice pagamento + // Nel caso si ha un anticipo documento, l'importo della rata non sarà 0 ma eguale all'anticipo stesso + // Se poi abbiamo il caso in cui l'anticipo paga completamente il documento + // non avremo alcuna rata e tutto l'importo della provvigione del doc. andrà comunque + // sulla rata 0, anche se la provvigione sul fatturato è 0 (% a 0) + + const int nrate = pag1.n_rate(); + + if (nrate == 1 && is_anticipo) // significa che l'anticipo paga tutto ora, quindi provv_fat vale tutta la provvigione del documento + provv_fat = tot_provv; + + const bool first_rata_ok = !provv_fat.is_zero(); + + // Impostazione prima rata solo se la provvigione sul fatturato è diversa da 0 + if (first_rata_ok) + { + TRata& rt = rd.row(0,true); + rt.set_rata(0); rt.set_datascad(datadoc); rt.set_tipopag(1); + rt.set_imprata(anticipo.get_num()); rt.set_impprovv(provv_fat.get_num()); + rt.set_generata(generata); + } + + // Setta le rate rimanenti + int i; + + for (i = 1; i <= nrate; i++) + { + if (i == nrate && is_anticipo) + break; + + const int index = is_anticipo ? i : i - 1; + TRata& rt = rd.row(first_rata_ok ? i : i - 1, true); + rt.set_rata(i); + rt.set_datascad(pag1.data_rata(index)); + rt.set_tipopag(pag1.tipo_rata(index)); + rt.set_imprata(pag1.importo_rata(index,valuta ? true : FALSE)); + rt.set_impprovv(pag2->importo_rata(i-1,valuta ? true : FALSE)); + rt.set_generata(generata); + } + + // Rimuove eventuali righe in eccesso + const int rd_items = rd.items(); // Rate precedenti + for (i = first_rata_ok ? nrate+1 : nrate; i < rd_items; i++) + rd.remove_rata(i); + delete pag2; +} + +int TDocumento::update_provvigione(bool remove, const bool first) +{ + TProvvigioni_agente provv; + const TString8 old = first ? _old_agente : _old_agente1; + const TString8 agente = first ? get(DOC_CODAG) : get(DOC_CODAGVIS); + const int anno = TDocumento::anno(); + const TString & codnum = numerazione(); + const long ndoc = numero(); + const TDate datadoc(data()); + int err = NOERR; + + if (remove || old != agente) + { + while (provv.read(old, anno, codnum, ndoc) == _islocked) // Legge le provvigioni per questo documento + if (!yesno_box("Dati agente %s in uso da un altro utente. Riprovare?", (const char *) old)) + return err; + if (err != NOERR) + return err; + err = provv.remove(); + if (remove) + return err; + } + + if (agente.blank()) + return NOERR; + calc_provvigione(provv, agente, first); + return provv.write(); +} + +int TDocumento::update_provvigioni(bool remove) +{ + int err; + + if ((err = update_provvigione(remove)) == NOERR) + err = update_provvigione(remove, false); + return err; +} + +bool TDocumento::in_valuta() const +{ + const TString& val = valuta(); + return is_true_value(val); +} + +TCodgiac_livelli & TDocumento::livelli() const +{ + if (_livelli == NULL) + _livelli = new TCodgiac_livelli(); + return *_livelli; +} + +TRiga_documento & TDocumento::row(int index) +{ + TRecord_array & b = body(); + const int nrows = b.last_row(); + TRiga_documento * r = NULL; + + if (index <= nrows) + { +#ifdef DBG + if (!b.exist(index)) + { + const long ndoc = get_long(DOC_NDOC); + const int anno = get_int(DOC_ANNO); + const char* codnum = get(DOC_CODNUM); + error_box("Riga documento %d non esistente nel documento %d %s %ld", index, anno, codnum, ndoc); + insert_row(index, "05"); + } +#endif + r = &((TRiga_documento &) b.row(index, FALSE)); + } + else + { + CHECKD((index == nrows + 1 && (_sconto != NULL || _esenzione != NULL)) || (index == nrows + 2 && _sconto != NULL && _esenzione != NULL), + "Riga documento non esistente ", index); + if (index == nrows + 1) + { + r = _sconto != NULL ? _sconto : _esenzione; + } else + if (index == nrows + 2) + r = _esenzione; + } + return *r; +} + +const TRiga_documento& TDocumento::physical_row(int index) const +{ + TRecord_array& b = body(); + return (TRiga_documento&)b.row(index, false); +} + +long TDocumento::get_next_key(char provv, int anno, const char* codnum) const +{ + long n = 0; + + TLocalisamfile doc(LF_DOC); + TRectype& curr = doc.curr(); + set_key(curr, provv, anno, codnum, 9999999L); + + const int err = doc.read(_isgreat); + + if (err != _isemptyfile) + { + if (err == NOERR) + doc.prev(); + if (curr.get_char(DOC_PROVV) == provv && + curr.get_int(DOC_ANNO) == anno && + curr.get(DOC_CODNUM) == codnum) + n = curr.get_long(DOC_NDOC); + } + + n++; + return n; +} + +const TTipo_documento& TDocumento::tipo() const +{ + TString4 tipodoc(get(DOC_TIPODOC)); +#ifdef DBG + if (tipodoc.blank()) // Test necessario per lavorare anche su dati rovinati + { + const TCodice_numerazione& codnum = codice_numerazione(); + tipodoc = codnum.tipo_doc(0); + yesnofatal_box("Tipo documento nullo su %d %s %ld\nforzato a %s", + get_int(DOC_ANNO), (const char*)get(DOC_CODNUM), get_long(DOC_NDOC), (const char*)tipodoc); + ((TDocumento*)this)->set_tipo(tipodoc); + } +#endif + return cached_tipodoc(tipodoc); +} + +const TCodice_numerazione& TDocumento::codice_numerazione(const char * numerazione) +{ + return cached_numerazione(numerazione); +} + + +const TCodice_numerazione& TDocumento::codice_numerazione() const +{ + return cached_numerazione(numerazione()); +} + +bool TDocumento::raggruppabile(const TDocumento& doc, TToken_string& campi) const +{ + bool ok = raggruppabile() && doc.raggruppabile(); + if (ok) + { + TString campo; + for (const char* c = campi.get(0); c && ok; c = campi.get()) + { + if (strncmp(c, "CODABI", 6) == 0 || strncmp(c, "CODCAB", 6) == 0) + { + long cod = get_long(c); + ok &= (cod == doc.get_long(c)); + } + else + { + campo = get(c); + ok &= campo == doc.get(c); + } + } + } + return ok; +} + +void TDocumento::set_fields(TAuto_variable_rectype & rec) +{ + if (tipo_valido()) + { + TTipo_documento& tipo_doc = (TTipo_documento&)tipo(); // first_formula() is NOT const + const TString& tot_doc = tipo_doc.totale_doc(); + + for (const TFormula_documento* f = tipo_doc.first_formula(); f; f = tipo_doc.succ_formula()) + { + TExpr_documento* exp = f->expr(); + if (exp != NULL) // Puo' succedere che sia NULL con dati incoerenti + { + if (tot_doc == f->name()) + { + TString16 tot_doc_netto(tot_doc); + tot_doc_netto.insert("_"); + + const TFixed_string netto_def(exp->string()); + TExpr_documento netto_exp(netto_def, _numexpr, this); + + add_field(new TDocumento_variable_field(tot_doc_netto, netto_exp)); + + if (netto_def == "IMPONIBILI()+IMPOSTE()") + { + TExpr_documento tot_exp("IMPONIBILI(1)+IMPOSTE(1)", _numexpr, this); + add_field(new TDocumento_variable_field(tot_doc, tot_exp)); + } + else + { + TExpr_documento tot_exp(format("%s + _BOLLI(%s)", (const char *) tot_doc_netto, + (const char*)tot_doc_netto), _numexpr, this); + add_field(new TDocumento_variable_field(tot_doc, tot_exp)); + } + } + else + { + exp->set_doc(this); + add_field(new TDocumento_variable_field(f->name(), *exp)); + } + } + } + + for (TVariable_field* src_field = rec.first_variable_field(); + src_field != NULL; src_field = rec.succ_variable_field()) + { + const char* fieldname = src_field->name(); + if (src_field->expression() == NULL) + put(fieldname, rec.get(fieldname)); + } + } +} + +real TDocumento::imponibile(bool spese, int ndec) const +{ + real val; + if (physical_rows() > 0) + { + TAssoc_array& table = ((TDocumento*)this)->tabella_iva(); + table.restart(); + for (TRiepilogo_iva* ri = (TRiepilogo_iva*)table.get(); ri != NULL; ri = (TRiepilogo_iva*)table.get()) + val += ri->imponibile(spese); + if (ndec == AUTO_DECIMALS) + ndec = decimals(); + val.round(ndec); + } + return val; +} + +void TDocumento::calc_iva_fattura_commerciale() +{ + // Calcolo iva per fatture commerciali: + // 1) effettua la sommatoria di tutti i real per ogni elementi di _tabella_iva in un TRiepilogo_iva unico + // 2) azzera _tabella_iva + // 3) scorpora in % a seconda di cio' che e' indicato in configurazione, e mette i nuovi elementi in _tabella_iva + // 4) per ogni nuovo elemento di _tabella_iva, ricalcola la relativa imposta. + TAssoc_array & table = _tabella_iva; + TRiepilogo_iva t; + static TString_array tabella_ripartizione; + const int ndec = decimals(); + + if (tabella_ripartizione.items() == 0) + { + TConfig cnf(CONFIG_STUDIO, "ve"); + for (int k = 1; k <= MAX_IVA_SLICES; k++) + { + TToken_string* tt = new TToken_string(); + tt->add(cnf.get("EXCLUDE_PERC", NULL, k)); + tt->add(cnf.get("EXCLUDE_IVA", NULL, k)); + tabella_ripartizione.add(tt); + } + } + + // 1) + table.restart(); + for (TRiepilogo_iva * ri = (TRiepilogo_iva *) table.get(); ri != NULL; + ri = (TRiepilogo_iva *) table.get()) + { + t.imp() += ri->imp(); + t.imp_spese() += ri->imp_spese(); + t.imp_spese_row() += ri->imp_spese_row(); + t.iva_spese() += ri->iva_spese(); + t.iva_sconto() += ri->iva_sconto(); + t.sconto_perc() += ri->sconto_perc(); + t.sconto_imp() += ri->sconto_imp(); + } + // 2) + table.destroy(); + + // 3) + TArray tda; + + tda.add(new TDistrib(t.imp(), ndec)); + tda.add(new TDistrib(t.imp_spese(), ndec)); + tda.add(new TDistrib(t.imp_spese_row(), ndec)); + tda.add(new TDistrib(t.iva_spese(), ndec)); + tda.add(new TDistrib(t.iva_sconto(), ndec)); + tda.add(new TDistrib(t.sconto_perc(), ndec)); + tda.add(new TDistrib(t.sconto_imp(), ndec)); + + int k; + + for (k = 0; k < MAX_IVA_SLICES; k++) + for (int j = 0; j < 7; j++) + { + const real p (tabella_ripartizione.row(k).get(0)); + TDistrib& td = (TDistrib&) tda[j]; + td.add(p); + } + + // 4) + for (k = 0; k < MAX_IVA_SLICES; k++) + { + TString16 cod(tabella_ripartizione.row(k).get(1)); + cod.trim(); + if (cod.empty()) + continue; + + const TCodiceIVA civa(cod); + TRiepilogo_iva * rp = (TRiepilogo_iva *) table.objptr(cod); + if (rp == NULL) + { + rp = new TRiepilogo_iva(civa); + table.add(cod, rp); + } + + for (int j = 0; j < tda.items(); j++) + { + TDistrib& td = (TDistrib&)tda[j]; + const real rr = td.get(); + + switch (j) + { + case 0: + rp->imp() = rr; + rp->iva() = civa.imposta(rr, ndec); + break; + case 1: + rp->imp_spese() = rr; + break; + case 2: + rp->imp_spese_row() = rr; + break; + case 3: + rp->iva_spese() = rr; + break; + case 4: + rp->iva_sconto() = rr; + break; + case 5: + rp->sconto_perc() = rr; + break; + case 6: + rp->sconto_imp() = rr; + break; + default: + break; + } + } + } +} + +void TDocumento::update_tabella_iva(bool solo_imponibili) +{ + static bool __solo_imponibili = false; + const int items = rows(); + TAssoc_array & table = _tabella_iva; + + if (items == 0) + { + table.destroy(); + return; + } + if (__solo_imponibili != solo_imponibili) + { + table.destroy(); + __solo_imponibili = solo_imponibili; + } + + if (table.items() > 0) + { + if (items == 0) + table.destroy(); + return; + } + + const bool doc_al_lordo = tipo().calcolo_lordo(); + const int ndec = decimals(); + + // Test di consistenza solitamente inutile, ma fallisce in ve1 -0 L + const int r1 = body(LF_RIGHEDOC).first_row(); + if (r1 > 0 && row(r1).get_int(RDOC_NRIGA) != r1) + remove_body(LF_RIGHEDOC); // Forza il caricamento ex-novo delle righe + + FOR_EACH_PHYSICAL_RDOC(*this, j, rowptr) + { + const TRiga_documento& r = *rowptr; + if (!r.is_sconto() && !r.is_descrizione()) + { + const TCodiceIVA & iva = r.iva(); + if (iva.ok()) + { + const TString & cod = iva.codice(); + TRiepilogo_iva* aliquota = (TRiepilogo_iva*)table.objptr(cod); + if (aliquota == NULL) + { + aliquota = new TRiepilogo_iva(iva); + table.add(cod, aliquota); + } + const real imponibile = doc_al_lordo ? r.importo(true, true, ndec) : r.imponibile(); + aliquota->imp_orig() += imponibile; + } + } + } + + if (solo_imponibili) + return; + + real tot_doc; + real tot_sconti; + real tot_sconti_perc; + TArray imponibili; + const bool fatt_comm = tipo().fattura_commerciale(); + + TString4 codiva_es; iva_esente(codiva_es); + + for (int i = items; i > 0; i--) + { + const TRiga_documento& r = row(i); + const real imponibile = doc_al_lordo ? r.importo(true, true, ndec) : r.imponibile(); + + tot_doc += imponibile; + if (r.is_sconto()) + { + tot_sconti += imponibile; + if (r.is_sconto_perc()) + tot_sconti_perc += imponibile; + } + else + if (!r.is_descrizione()) + { + const real imposta = doc_al_lordo ? ZERO : r.imposta(false); + // Aggiorna o aggiunge l'elemento se non esiste + const TCodiceIVA & iva = r.iva(); + + if (iva.ok()) + { + const TString & cod = iva.codice(); + + TRiepilogo_iva* aliquota = (TRiepilogo_iva *) table.objptr(cod); + if (aliquota == NULL) + { + aliquota = new TRiepilogo_iva(iva); + table.add(cod, aliquota); + } + + aliquota->imp() += imponibile; + if (r.is_spese() && iva.tipo().not_empty()) + aliquota->imp_spese_row() += imponibile; + aliquota->iva() += imposta; + } + tot_doc += imposta; + } + } + + if (table.empty()) + return; + + if (tot_sconti != ZERO) + { + TGeneric_distrib d(tot_sconti, ndec); + real tot_sconti_imp = tot_sconti - tot_sconti_perc; + + if (!table.empty()) + { + FOR_EACH_ASSOC_OBJECT(table, obj, key, o) + { + TRiepilogo_iva* aliquota = (TRiepilogo_iva*)o; + const real i = aliquota->imp() - aliquota->imp_spese_row(); + d.add(i); + } + } + + FOR_EACH_ASSOC_OBJECT(table, obj, key, o) + { + TRiepilogo_iva& aliquota = *(TRiepilogo_iva*)o; + const TCodiceIVA& ci = aliquota.cod_iva(); + const real i = d.get(); + + real& imponibile = aliquota.imp(); + imponibile += i; + + TGeneric_distrib s(i, ndec); + + s.add(tot_sconti_imp); + s.add(tot_sconti_perc); + + aliquota.sconto_imp() = s.get(); + aliquota.sconto_perc() = s.get(); + + real& iva = aliquota.iva(); + +/* if (doc_al_lordo) + { + const real imposta(ci.imposta(i, ndec)); + + TGeneric_distrib iva(imposta, ndec); + iva.add(tot_sconti_imp); + iva.add(tot_sconti_perc); + + imponibile += imposta; + aliquota->sconto_imp() += iva.get(); + aliquota->sconto_perc() += iva.get(); + + tot_doc += imposta; + } + else */ + if (!doc_al_lordo) + { + const real imposta(ci.imposta(i, ndec)); + + iva += imposta; + aliquota.iva_sconto() = imposta; + tot_doc += imposta; + } + } + } + + if (fatt_comm) + calc_iva_fattura_commerciale(); + + const real rit = ritenute(); + real val = spese_incasso(real(tot_doc - rit), ALL_DECIMALS, doc_al_lordo ? _lordo : _netto); + + if (!val.is_zero()) + { + const TString& codiva = codiva_es.full() ? (const TString&)codiva_es : codiva_spese(); + TRiepilogo_iva* ri = (TRiepilogo_iva*)table.objptr(codiva); + if (ri == NULL && codiva.full()) + { + ri = new TRiepilogo_iva(TCodiceIVA(codiva)); + table.add(codiva, ri); + } + if (ri != NULL) + ri->imp_spese() += val; + tot_doc += val; + + if (!doc_al_lordo) + { + val = spese_incasso(real(tot_doc - rit), ALL_DECIMALS, _imposta); + if (ri != NULL) + ri->iva_spese() += val; + tot_doc += val; + } + } + + val = bolli(real(tot_doc - rit), ALL_DECIMALS, doc_al_lordo ? _lordo : _netto); + if (val != ZERO) + { + const TString& codiva = codiva_bolli(); + if (codiva.full()) + { + TRiepilogo_iva* ri = (TRiepilogo_iva*)table.objptr(codiva); + if (ri == NULL) + { + ri = new TRiepilogo_iva(TCodiceIVA(codiva)); + table.add(codiva, ri); + } + if (!doc_al_lordo) + { + real valiva = bolli(real(tot_doc - rit), ALL_DECIMALS, _imposta); + ri->iva_spese() += valiva; + tot_doc += valiva; + } + ri->imp_spese() += val; + } + + tot_doc += val; + } + +// SCORPORO + if (doc_al_lordo) + { + FOR_EACH_ASSOC_OBJECT(table, obj, key, o) + { + TRiepilogo_iva * aliquota = (TRiepilogo_iva*) o; + const TCodiceIVA& iva = aliquota->cod_iva(); + + aliquota->iva() = iva.scorpora(aliquota->imp(), ndec); + aliquota->iva_spese() = iva.scorpora(aliquota->imp_spese(), ndec); + iva.scorpora(aliquota->imp_spese_row(), ndec); + + aliquota->iva_sconto() = iva.scorpora(aliquota->sconto_imp(), ndec); + aliquota->iva_sconto() += iva.scorpora(aliquota->sconto_perc(), ndec); + } + } +} + +real TDocumento::imposta(bool spese, int ndec) const +{ + real val = ZERO; + if (physical_rows() > 0) + { + TAssoc_array& table = ((TDocumento*)this)->tabella_iva(); + + if (ndec == AUTO_DECIMALS) + ndec = decimals(); + + for (TRiepilogo_iva * ri = (TRiepilogo_iva *) table.get(); ri != NULL; + ri = (TRiepilogo_iva *) table.get()) + { + real iva = ri->imposta(spese); + + if (ndec == 0) + { + if (iva < ZERO) + iva.floor(ndec); + else + iva.ceil(ndec); + } + else + iva.round(ndec); + val += iva; + } + } + return val; +} + +real TDocumento::totale_doc() const +{ +/* A pag.1 c'e' scritto di non fare cosi' + const TString16 field(tipo().totale_doc()); + + if (field.not_empty()) + return get_real(field); + else + { + real r = imponibile() + imposta(); + const int ndec = decimals(); + + r += spese_incasso(r - ritenute()), ndec); + r += bolli(real(r - ritenute()), ndec); + return r; + } +*/ + // Cosi' e' piu' ordinato, strutturato e veloce + real r; + const TString& field = tipo().totale_doc(); + if (field.blank()) + { + const int ndec = decimals(); + const bool lordo = tipo().calcolo_lordo(); + + r = imponibile(lordo); + if (!lordo) + r += imposta(); + r += spese_incasso(real(r - ritenute()), ndec); + r += bolli(real(r - ritenute()), ndec); + } + else + r = get_real(field); + + return r; +} + +real TDocumento::totale_netto() const +{ + const TString& field = tipo().totale_netto(); + if (field.full()) + return get_real(field); + else + return imponibile() + imposta(); +} + +real TDocumento::basesconto() const +{ + const TString& field = tipo().basesconto(); + return field.full() ? get_real(field) : ZERO; +} + +real TDocumento::spese() const +{ + const TString& field = tipo().spese(); + + if (field.full()) + return get_real(field); + else + { + real r; + + FOR_EACH_PHYSICAL_RDOC(*this, i, rdoc) + if (rdoc->is_spese()) + r += rdoc->imponibile(); + return r; + } +} + +real TDocumento::spese(const TString & tipo_spesa) const +{ + TString16 field = tipo().spese(); + + field << tipo_spesa; + if (tipo().exist(field)) + return get_real(field); + else + { + real r; + + FOR_EACH_PHYSICAL_RDOC(*this, i, rdoc) + if (rdoc->is_spese()) + { + const TSpesa_prest s(rdoc->get(RDOC_CODART)); + + if (s.get("S11").sleft(1) == tipo_spesa) + r += rdoc->imponibile(); + } + return r; + } +} + +real TDocumento::ritenute(const char tipo, bool lordo, int ndec) const +{ + real val; + for (int i = rows(); i > 0; i--) + { + const TRiga_documento& r = ((TDocumento*)this)->row(i); + val += r.ritenuta(tipo, lordo, ndec); + } + return val; +} + +TPagamento& TDocumento::pagamento() +{ + const char tipocf = get_char(DOC_TIPOCF); + const long codcf = get_long(DOC_CODCF); + _pag.set_clifo(codcf, tipocf); + + TDate data_in = get_date(DOC_DATAINSC); + if (data_in.empty()) + data_in = get_date(DOC_DATADOC); + + const TString8 codpag(get(DOC_CODPAG)); + if (codpag != _pag.code()) + { + _pag.set_code(codpag); + _pag.read(); + _pag.set_inizio(data_in); // Perche' rispetta rate true? + } + else + { + if (data_in != _pag.get_datadoc()) + _pag.set_inizio(data_in); // Perche' rispetta rate true? + } + + return _pag; +} + +real TDocumento::provvigione(bool first, int ndec) const +{ + TString16 field = agente(first).campoprovv(); + if (field.empty()) + field = first ? tipo().totprovv() : tipo().totprovv1(); + + real val; + if (field.not_empty()) + val = get_real(field); + else + { + if (ndec == AUTO_DECIMALS) + ndec = decimals(); + for (int i = physical_rows(); i > 0; i--) + val += physical_row(i).provvigione(first, ndec); + } + return val; +} + +real TDocumento::valore(bool totale, bool lordo, int ndec) const +{ + real val; + TDocumento& doc = *(TDocumento*)this; + FOR_EACH_PHYSICAL_RDOC_BACK(doc, i, r) + { + const char t = r->tipo().tipo(); + if (strchr("MSPRA", t) != NULL) // Merce, Spese, Prestazioni, Risorse, Attrezzature + val += r->valore(totale, lordo, ndec); + } + return val; +} + +void TDocumento::put_str(const char* fieldname, const char* val) +{ + const TFixed_string fn(fieldname); + if (fn == DOC_TIPODOC) + { + const TString4 v(val); + if (TRectype::get(DOC_TIPODOC) != v) + { + TAuto_variable_rectype::put_str(fieldname, v); + reset_fields(*this); + set_fields(*this); + } + else + dirty_fields(); + } else + if (fn == DOC_CODCF) + { + const TString8 v(val); + put(DOC_SPESEUPD, TRectype::get(DOC_CODCF) == v); + TAuto_variable_rectype::put_str(fieldname, v); + dirty_fields(); + } + else + { + TAuto_variable_rectype::put_str(fieldname, val); + dirty_fields(); + if (fn == DOC_SCONTOPERC) + set_riga_sconto(); + } +} + +const TString& TDocumento::get_str(const char* fieldname) const +{ + if (_dirty_deny && variable_field(fieldname) != NULL) + (bool&) _dirty_deny = false; + + return TMultiple_rectype::get_str(fieldname); +} + +void TDocumento::zero(const char * fieldname) +{ + if (strcmp(fieldname, DOC_TIPODOC) == 0) + reset_fields(*this); + TAuto_variable_rectype::zero(fieldname); + dirty_fields(); +} + +TCli_for& TDocumento::clifor(bool force_reload) const +{ + const char tipo = tipocf(); + const long codice = codcf(); + TCli_for& cf = (TCli_for&)_cli_for; + if (force_reload || cf.empty() || cf.tipo() != tipo || cf.codice() != codice) + cf.read(tipo, codice); + return cf; +} + +TOccasionale& TDocumento::occas() const +{ + const TString16 occ_code = cod_occas(); // Codice occasionale in testata + + TOccasionale& rec = (TOccasionale&)_occas; + if (occ_code != rec.codice()) + { + TLocalisamfile o(LF_OCCAS); + rec.put(OCC_CFPI, occ_code); + if (rec.read(o) != NOERR) + { + rec.zero(); + rec.put(OCC_CFPI, occ_code); + } + } + return rec; +} + +const TAgente & TDocumento::agente(bool first) const +{ + if (_agenti == NULL) + _agenti = new TAgenti_cache; + return _agenti->agente(first ? get(DOC_CODAG) : get(DOC_CODAGVIS)); +} + +TDocumento& TDocumento::copy(const TDocumento & d) +{ + TMultiple_rectype::operator=((TMultiple_rectype &)d); + reset_fields(*this); + set_fields((TAuto_variable_rectype &) d); + for (int i = physical_rows(); i > 0; i--) + { + TRiga_documento& r = row(i); + + r.set_doc(this); + r.reset_fields(r); + r.set_fields(((TAuto_variable_rectype &)d[i])); + } + set_riga_sconto(); + if (is_fattura()) + set_riga_esenzione(); + _occas = d.occas(); + return *this; +} + +TRectype & TDocumento::operator =(const TRectype & r) +{ + return TMultiple_rectype::operator=(r); +} + +TRectype & TDocumento::operator =(const char * r) +{ + return TMultiple_rectype::operator=(r); +} + +TRecord_array& TDocumento::body(int logicnum) const +{ + logicnum = LF_RIGHEDOC; // logicnum may be 0! + const bool reset_data_cons = loaded_rows(logicnum) == 0; + + if (reset_data_cons) + ((TDocumento*)this)->_dirty_deny = true; + + TRecord_array& r = TMultiple_rectype::body(logicnum); + + if (reset_data_cons) + { + const TDate datacons(get(DOC_DATACONS)); + const TString80 codcms(get(DOC_CODCMS)); + const TString80 fascms(get(DOC_FASCMS)); + const TString80 codcos(get(DOC_CODCOSTO)); + const bool order = datacons.ok(); // on 27-09-2013 was order=is_ordine(); + const bool can_reset_ca = (codcms.full() || codcos.full()) && ini_get_string(CONFIG_DITTA, "ca", "FathFasi").blank(); + + for (int i = r.last_row(); i > 0; i = r.pred_row(i)) + { + TRectype& rec = r[i]; + TRecfield dcons(rec, RDOC_DATACONS); + if (order && datacons == dcons) + dcons = ""; + if (can_reset_ca) + { + TRecfield ccms(rec, RDOC_CODCMS); + TRecfield fcms(rec, RDOC_FASCMS); + TRecfield ccos(rec, RDOC_CODCOSTO); + if (codcms == ccms) ccms = ""; + if (fascms == fcms) fcms = ""; + if (codcos == ccos) ccos = ""; + } + } + ((TDocumento*)this)->_dirty_deny = false; + } + return r; +} + +void TDocumento::update_raee() +{ + const TString & r_cod = tipo().raee_cod(); + const TString & r_fld = tipo().raee_fld(); + + if (r_cod.full() && r_fld.full() && tipo().stati_iniziali_modifica().find(stato()) >= 0) + { + TSpesa_prest sp(r_cod); + TString4 cod_iva_cli; + TLocalisamfile cfven(LF_CFVEN); + cfven.put("TIPOCF", get("TIPOCF")); + cfven.put("CODCF", get("CODCF")); + if (cfven.read() == NOERR) + cod_iva_cli = cfven.get("ASSFIS"); + int nrows = physical_rows(); + int i; + + for (i = nrows; i > 0; i--) + { + TRiga_documento & r = row(i); + + if (r.tipo().tipo() == RIGA_SPESEDOC && r.is_generata() && r.get("GENTIPO") == "R") + destroy_row(i, true); + } + nrows = physical_rows(); + for (i = nrows; i > 0; i--) + { + TRiga_documento & r = row(i); + + if (r.is_articolo()) + { + TArticolo & art = r.articolo(); + real tax = art.get_real(r_fld); + + if (tax != ZERO) + { + const TCurrency_documento val(tax, *this, true); + TString16 t(sp.tipo_riga()); + TRiga_documento & r1 = insert_row(i + 1, t); + + copy_data(r1, r); + r1.set_tipo(t); + r1.put(RDOC_CODART, r_cod); + TString d(sp.descrizione()); + + if (d.full()) + d << " - "; + d << r1.get(RDOC_DESCR); + d << r1.get(RDOC_DESCEST); + r1.set_descr(d); + + const TString& um = sp.um(); + if (um.full()) + r1.put(RDOC_UMQTA, um); + if (cod_iva_cli.blank()) + { + const TString& codiva = sp.cod_iva(); + if (codiva.full()) + r1.put(RDOC_CODIVA, codiva); + } + else + r1.put(RDOC_CODIVA, cod_iva_cli); + tax = val.get_num(); + r1.put(RDOC_PREZZO, tax); + if (tipo().calcolo_lordo()) + { + tax = r1.iva().lordo(tax, ALL_DECIMALS); + r1.put(RDOC_PREZZOL, tax); + } + r1.generata(); + r1.put(RDOC_GENTIPO, "R"); + } + } + } + } +} + +void TDocumento::update_spese_aut(TString_array & spese_aut, bool preserve_old, TSheet_field* sh, bool force) +{ + const bool updated = get_bool(DOC_SPESEUPD); + if (!force && updated) + return; + + const bool interactive = sh != NULL; + + if (force || tipo().spese_aut()) + { + const int nrows = physical_rows(); + int i; + + for (i = nrows; i > 0; i--) + { + TRiga_documento & r = row(i); + bool tipo_spese = r.get(RDOC_GENTIPO).empty(); + + if (r.tipo().tipo() == RIGA_SPESEDOC && r.is_generata() && tipo_spese) + { + if (preserve_old) + return; + destroy_row(i, true); + if (interactive) + sh->destroy(i - 1); + } + } + + TString4 cod_iva_cli; + const int nspese = spese_aut.items(); + + if (nspese > 0) + { + TSpesa_prest sp; + cod_iva_cli = codesiva(); + + for (i = 0; i < nspese; i++) + { + const TString& s = spese_aut.row(i); + + if (sp.read(s) != NOERR) + warning_box("Codice spesa '%s' assente", (const char*)s); + else + { + const TString4 tipo(sp.tipo_riga()); + TRiga_documento& riga = new_row(tipo); + + riga.put(RDOC_CODART, s); + riga.generata(); + riga.put(RDOC_DESCR, sp.descrizione()); + if (cod_iva_cli.blank()) + riga.put(RDOC_CODIVA, sp.cod_iva()); + else + riga.put(RDOC_CODIVA, cod_iva_cli); + switch (sp.tipo()) + { + case 'Q': + { + real qta = sp.qta(); + if (qta == ZERO) + qta = UNO; + riga.put("QTA", qta); + } + // Continua perche' e' quantita' e valore + case 'V': + { + const real cambio = get_real(DOC_CAMBIO); + const TString4 valuta = get(DOC_CODVAL); + real prezzo = sp.prezzo(); + + sppr_calc(sp, valuta, cambio, prezzo); + if (this->tipo().calcolo_lordo()) + { + prezzo = riga.iva().lordo(prezzo, ALL_DECIMALS); + riga.put(RDOC_PREZZOL, prezzo); + } + riga.put(RDOC_PREZZO, prezzo); + riga.put(RDOC_UMQTA, sp.um()); + } + break; + case 'P': + default: + riga.put(RDOC_QTA, sp.perc()); + break; + } + if (cod_iva_cli.empty()) + riga.put(RDOC_CODIVA, sp.cod_iva()); + else + riga.put(RDOC_CODIVA, cod_iva_cli); + + riga.put(RDOC_CODCOSTO, sp.cdc()); + riga.put(RDOC_CODCMS, sp.cms()); + riga.put(RDOC_FASCMS, sp.fase()); + riga.cms2tipodet(); + + if (interactive) + { + const int nrow = sh->insert(-1, FALSE); + riga.autoload(*sh); + sh->check_row(nrow); + } + } + } + } + } + put(DOC_SPESEUPD, true); +} + +// Calcola il peso in Kg degli imballaggi di una data categoria CONAI +real TDocumento::calc_conai_qta(TCONAI_class cc) +{ + real qta; + if (conai_configured_class(cc)) + { + FOR_EACH_PHYSICAL_RDOC(*this, i, r) if (r->is_merce() || r->is_omaggio()) + { + const real rowqty = r->calc_conai_qta(cc); + qta += rowqty; + } + qta.round(5); // Arrotondamento al centigrammo + } + return qta; +} + +void TDocumento::update_conai() +{ + if (main_app().has_module(DCAUT, CHK_DONGLE) && tipo().add_conai() && tipo().stati_iniziali_modifica().find(stato()) >= 0) + { + const TRectype& cfven = clifor().vendite(); + const bool cli_add_conai = cfven.get_bool("ADDCONAI"); + const char * const __conai_cf_names[] = {"ESACC", "ESALL", "ESCAR", "ESPLA", "ESLEG", "ESVET"}; + + const TDate datadoc = get(DOC_DATADOC); + const TDate dataes = cfven.get(CFV_DATAECONAI); + bool esponi_esenti = false; + + TString_array conai_sp(CONAI_CLASSES); // Codici spesa conai + { + const char* const conai_cod[CONAI_CLASSES] = { "CODACC", "CODALL", "CODCAR", "CODPLA", "CODLEG", "CODVET" }; + TConfig c(CONFIG_DITTA, "ve"); + for (int i = 0; i < CONAI_CLASSES; i++) + conai_sp.add(c.get(conai_cod[i])); + + esponi_esenti = c.get_bool("ESPONIESENTI"); + } + + bool updated[CONAI_CLASSES] = {false,false,false,false,false,false}; + for (int i = physical_rows(); i > 0; i--) + { + TRiga_documento& r = row(i); + const bool tipo_conai = r.get_char("GENTIPO") == 'C'; + + // Elimina righe generate + if (tipo_conai) + { + const TString& cod = r.get(RDOC_CODART); + const TCONAI_class pos = (TCONAI_class)conai_sp.find(cod); + + if (pos >= CONAI_FIRST && pos <= CONAI_LAST) + { + if (cli_add_conai) + { + real perc_esenz = cfven.get_real(__conai_cf_names[pos]); + real qta = calc_conai_qta(pos); + if (dataes.ok() && datadoc > dataes) + perc_esenz = ZERO; + const bool cli_esente = esponi_esenti && (perc_esenz >= CENTO); + if (!cli_esente && !perc_esenz.is_zero()) + qta = qta * (CENTO - perc_esenz) / CENTO; // More precise + if (qta > ZERO) + { + r.put(RDOC_QTA, qta); + if (cli_esente) + r.zero(RDOC_PREZZO); + } + else + destroy_row(i, true); + } + else + destroy_row(i, true); + updated[pos] = true; + } + } + } + + // Genera nuove righe + if (cli_add_conai) + { + const TString4 cod_iva_cli = codesiva(); + TSpesa_prest sp; + + FOR_EACH_CONFIGURED_CONAI_CLASS(ct) if (!updated[ct]) + { + const real perc_esenz = cfven.get_real(__conai_cf_names[ct]); + const bool cli_esente = (esponi_esenti) && (perc_esenz >= CENTO); + const real qta_lorda = calc_conai_qta(ct); + real qta = qta_lorda; + if (!cli_esente && !qta_lorda.is_zero() && !perc_esenz.is_zero()) + { + qta = qta_lorda * (CENTO - perc_esenz) / CENTO; + qta.round(5); + } + + if (qta > ZERO) + { + const TString& s = conai_sp.row(ct); + + if (sp.read(s) != NOERR) + message_box(FR("Il codice spesa CONAI %s specificato nei parametri ditta è assente: '%s'"), + conai_material(ct), (const char*)s); + else + { + const TString4 tipo = sp.tipo_riga(); + TRiga_documento& riga = new_row(tipo); + + riga.put(RDOC_CODART, s); + riga.generata(); + riga.put(RDOC_GENTIPO, 'C'); + riga.put(RDOC_DESCR, sp.descrizione()); + riga.put(RDOC_QTA, qta); + + const real cambio = get_real(DOC_CAMBIO); + const TString4 valuta = get(DOC_CODVAL); + real prezzo = cli_esente ? ZERO : sp.prezzo(); + + sppr_calc(sp, valuta, cambio, prezzo); + if (this->tipo().calcolo_lordo()) + prezzo = riga.iva().lordo(prezzo, ALL_DECIMALS); + riga.put(RDOC_PREZZO, prezzo); + riga.put(RDOC_UMQTA, sp.um()); + if (cod_iva_cli.empty()) + riga.put(RDOC_CODIVA, sp.cod_iva()); + else + riga.put(RDOC_CODIVA, cod_iva_cli); + } + } + } + } + } +} + +bool TDocumento::is_evaso() const +{ + bool ok = is_ordine() || is_bolla() || is_generic(); + + if (ok && tipo().is_ordine_quadro()) + return false; + + for (int r = 1; ok && r <= physical_rows(); r++) + { + const TRiga_documento& riga = physical_row(r); + if (riga.is_evadibile()) + ok = riga.is_evasa(); + } + return ok; +} + +bool TDocumento::is_nota_credito() const +{ + bool swap = false; + + // Controlla prima l'esistenza del flag nota-credito sul tipo documento; + // se non e' settato controlla la causale + if (tipo().nota_credito()) + swap = true; + else + { + if (tipo().is_fattura()) + { + const TString4 codcaus(tipo().causale()); + if (codcaus.full()) + { + TCausale c(codcaus, data().year()); + const char sez = c.sezione_clifo(); + //controllo ulteriore sull'iva + TipoIVA tiva = c.reg().iva(); + const char tcf = tipocf(); + if (tiva == nessuna_iva && tcf > ' ') + tiva = tcf == 'C' ? iva_vendite : iva_acquisti; + if (tiva != nessuna_iva) + swap = ((tiva == iva_vendite) ^ (sez == 'D')); + } + } + } + return swap; +} + +TCurrency_documento::TCurrency_documento(const real& num, const TDocumento & doc, bool price) + : TCurrency(ZERO, "", ZERO, price) +{ + const TString4 val = doc.get(DOC_CODVAL); + force_value(val, doc.get_real(DOC_CAMBIO)); + set_num(num); +} + +int TDocumento::set_row_ids() +{ + const int phrw = physical_rows(); + long maxid = 0L; + int first_needed = 0; + for (int r = 1; r <= phrw; r++) + { + const TRiga_documento& row = physical_row(r); + const long id = row.get_long(RDOC_IDRIGA); + if (id > maxid) + maxid = id; + else + { + if (first_needed == 0 && id <= 0) + first_needed = r; + } + } + if (first_needed > 0) + { + for (int r = first_needed; r <= phrw; r++) + { + TRiga_documento& row = (TRiga_documento&)physical_row(r); + const long id = row.get_long(RDOC_IDRIGA); + if (id <= 0) + row.put(RDOC_IDRIGA, ++maxid); + } + } + return phrw; +} + +const TRiga_documento* TDocumento::get_row_id(long id) const +{ + TDocumento& doc = *(TDocumento*)this; + FOR_EACH_PHYSICAL_RDOC_BACK(doc, r, row) + { + if (row->get_long(RDOC_IDRIGA) == id) + return row; + } + return NULL; +} + +int TDocumento::id2rownum(long id) const +{ + const TRiga_documento* rdoc = get_row_id(id); + return rdoc ? rdoc->get_int(RDOC_NRIGA) : -1; +} + + +int TDocumento::tipo_riclassificato() const +{ + int tipo_riclassificato = tipo().tipo(); + if (tipo_riclassificato == TTipo_documento::_altro) + { + const TCodice_numerazione& num = codice_numerazione(); + if (num.fattura_emettere_ricevere()) + tipo_riclassificato = TTipo_documento::_bolla; + else + tipo_riclassificato = TTipo_documento::_fattura; + } + return tipo_riclassificato; +} + +const TString& TDocumento::codesiva() const +{ + TCli_for& c = clifor(); + + const TString& codiva = c.vendite().get(CFV_ASSFIS); + if (!c.use_lettere()) + return codiva; + + const TCodiceIVA i(codiva); + if (!i.has_plafond()) // Era presente nella 3.x, poi è sparito nella 10, ora torna nella 11.0 (7-3-2013) + return codiva; + + const TDate datadoc = get(DOC_DATADOC); + if (c.read_lettera(datadoc)) + return c.vendite().get(CFV_ASSFIS); // codiva may be lost + + return EMPTY_STRING; +} + +void TDocumento::get_protocolli_esenzione(TString& esenzione, TString& data_esenzione, + TString& registrazione, TString& data_registrazione) const +{ + TCli_for& c = clifor(); + if (c.use_lettere()) + { + if (c.read_lettera(get_date(DOC_DATADOC), true)) + { + const TRectype& rec = c.lettera(); + esenzione = rec.get(LETINT_VSPROT); + data_esenzione = rec.get(LETINT_VSDATA); + registrazione = rec.get(LETINT_NUMPROT); + data_registrazione = rec.get(LETINT_DATAREG); + } + } + else + { + esenzione = c.vendite().get(CFV_VSPROT); + data_esenzione = c.vendite().get(CFV_VSDATAREG); + registrazione = c.vendite().get(CFV_NSPROT); + data_registrazione = c.vendite().get(CFV_NSDATAREG); + } +} diff --git a/src/ve/velib03a.cpp b/src/ve/velib03a.cpp index b9628f74f..a239a31dd 100755 --- a/src/ve/velib03a.cpp +++ b/src/ve/velib03a.cpp @@ -170,6 +170,9 @@ const TString& TTipo_documento::riferimento(const TDocumento & doc, TString& rif TString val; switch (field.file()) { + case LF_DOC: + val = field.read(doc); + break; case LF_CLIFO: case LF_CFVEN: if (doc.get_long(DOC_CODCF) > 0) diff --git a/src/ve/velib04b.cpp b/src/ve/velib04b.cpp index c4a3f86be..37c4287c3 100755 --- a/src/ve/velib04b.cpp +++ b/src/ve/velib04b.cpp @@ -435,6 +435,8 @@ bool TMovimentoPN_VE::movement_ok() int TMovimentoPN_VE::recalc_cg_rows(const TString& descr_cr, TCausale& caus) { + if (caus.soloiva()) + return 0; const int righe_IVA = iva_items(); const TRectype& head = curr(); @@ -1536,20 +1538,6 @@ error_type TContabilizzazione::compile_head_mov_re(TDocumento& doc) // calcola il numero documento aggiungendo l'eventuale prefisso/postfisso. TString numdoc; cod_num.complete_num(doc.numero(), numdoc); - if (acquisto) - { - const TString& numdocrif = doc.get(DOC_NUMDOCRIF); - if (numdocrif.full()) - numdoc = numdocrif; - } - - if (numdoc.empty() || !cod_num.ok()) - { - _error = nr_doc_error; - return _error; - } - numdoc.upper(); // Il numero documento e' uppercase! - // Istanzia la causale del documento corrente... _caus = get_caus(doc, data_reg.year()); @@ -1561,6 +1549,20 @@ error_type TContabilizzazione::compile_head_mov_re(TDocumento& doc) _righe_iva->set_caus(_caus); _movimento->set_caus(_caus); + if (acquisto || _caus->soloiva()) + { + TString16 numdocrif(doc.get(DOC_NUMDOCRIF)); + if (numdocrif.not_empty()) + numdoc = numdocrif; + } + + if (numdoc.empty() || !cod_num.ok()) + { + _error = nr_doc_error; + return _error; + } + numdoc.upper(); // Il numero documento e' uppercase! + // per reperire il tipo documento ed il tipo movimento // reperisce la descrizione dal tipo documento e la completa con la data documento ed il // numero documento @@ -1576,7 +1578,7 @@ error_type TContabilizzazione::compile_head_mov_re(TDocumento& doc) } const TString16 rif = doc.get(DOC_NUMDOCRIF); - const bool use_rif = _caus->iva() == iva_acquisti && rif.full(); + const bool use_rif = (_caus->soloiva() || _caus->iva() == iva_acquisti) && rif.not_empty(); if (use_rif) { descr << "n. " << rif; @@ -2146,7 +2148,7 @@ error_type TContabilizzazione::adjust_iva_rows(TDocumento& doc) inc_field(rigaiva, RMI_IMPOSTA, diffimp); } } - if (_caus->intra()) + if (_caus->intra() || _caus->reverse_charge()) { real ritfis; for (int i = 0; i < items; i++) @@ -2230,6 +2232,8 @@ error_type TContabilizzazione::create_iva_rows(TDocumento& doc) error_type TContabilizzazione::create_total_doc_row(TDocumento& doc) // Crea la riga contabile di totale documento { + if (_caus->soloiva()) + return no_error; TRectype& rec_cg = _movimento->cg(0); TRectype& head = _movimento->curr(); const int annoes = head.get_int(MOV_ANNOES); @@ -3183,31 +3187,36 @@ error_type TContabilizzazione::write_all(TDocumento& doc, TMovimentoPN_VE & movi return generic_error; } // Aggiorno subito i saldi - aggiorna_saldi(saldo, movimento, true); - - const bool has_sc = sc_enabled(head.get_date(MOV_DATAREG)); - if (has_sc) - write_scadenze(doc, numreg == old_numreg); // Recontabilizing? - - if (good() && in_enabled()) - write_intra(doc); - - if (good() && (ca_config().get_int("Authorizations") & 0x5)) // No CI qui - write_anal(doc, movimento); - - const int tipocoll = _caus->link_m770(); - const bool do_770 = tipocoll == 1 || tipocoll == 5 || tipocoll == 6; - - if (good() && dongle().active(M77AUT) && do_770) - write_percip(doc, movimento); - - // nella 3.1 testava solo l'importo, ma nella 10.0 testava anche has_sc, dal 2/9/2014 si torna al vecchio modo - if (!doc.get_real(DOC_IMPPAGATO).is_zero()) + if (_caus->soloiva()) + movimento.destroy_cg_row(-1); + else { - if (write_anticipo(doc, movimento) != no_error) - movimento.remove(); // Se si è verificato un errore nella scrittura dell'anticipo rimuove il movimento di prima nota - } - + aggiorna_saldi(saldo, movimento, true); + + const bool has_sc = sc_enabled(head.get_date(MOV_DATAREG)); + if (has_sc) + write_scadenze(doc, numreg == old_numreg); // Recontabilizing? + + if (good() && in_enabled()) + write_intra(doc); + + if (good() && (ca_config().get_int("Authorizations") & 0x5)) // No CI qui + write_anal(doc, movimento); + + const int tipocoll = _caus->link_m770(); + const bool do_770 = tipocoll == 1 || tipocoll == 5 || tipocoll == 6; + + if (good() && dongle().active(M77AUT) && do_770) + write_percip(doc, movimento); + + + // nella 3.1 testava solo l'importo, ma nella 10.0 testava anche has_sc, dal 2/9/2014 si torna al vecchio modo + if (!doc.get_real(DOC_IMPPAGATO).is_zero()) + { + if (write_anticipo(doc, movimento) != no_error) + movimento.remove(); // Se si è verificato un errore nella scrittura dell'anticipo rimuove il movimento di prima nota + } + } if (good()) { _total_docs++; diff --git a/src/ve/velib04c.cpp b/src/ve/velib04c.cpp index 05c7bc27f..a70d21365 100755 --- a/src/ve/velib04c.cpp +++ b/src/ve/velib04c.cpp @@ -1,4 +1,5 @@ #include +#include #include "velib04.h" #include "../cg/cgsaldac.h" @@ -502,6 +503,12 @@ long TGenerazione_effetti::group_bills(TAssoc_array& group_array, bool interatti riga.put(REFF_IMPFATT,totale_fatt.get_num()); riga.put(REFF_IMPORTO,imprata); riga.put(REFF_ANNO, annodocrif); + + const TString4 npart_type = ini_get_string(CONFIG_DITTA, "cg", "RifPro"); + + if (npart_type == "M" && effetto.get(EFF_TIPOCF) == "C") + riga.put(REFF_NUMPART, format("%02d", datafatt.month())); + else riga.put(REFF_NUMPART, numdocrif); if (valuta) { @@ -553,7 +560,8 @@ void TGenerazione_effetti::calc_pagamento(TDocumento& doc) const TCurrency_documento totspese(doc.spese(), doc); const TCurrency_documento totimposte(doc.imposta(TRUE), doc); const TCurrency_documento totimponibili(tot_doc - totimposte - totspese); - TCurrency_documento anticipo(doc.get_real(DOC_IMPPAGATO), doc); + const bool is_anticipo = doc.clifor().vendite().get(CFV_CODCAUSINC).full() || doc.tipo().caus_anticipo().full(); + TCurrency_documento anticipo(is_anticipo ? doc.get_real(DOC_IMPPAGATO) : ZERO, doc); const bool valuta = doc.in_valuta(); //Riaggiusta le rate a seconda del valore gia' pagato @@ -628,7 +636,8 @@ void TGenerazione_effetti::generate_bill(TDocumento& doc, bool interattivo) // b const real tot = doc.totale_doc() - doc.ritenute(); const TCurrency_documento totale_fatt(tot, doc); // Importo in valuta - const TCurrency_documento imppagato(doc.get_real(DOC_IMPPAGATO), doc); // Anticipo pagamento + const bool anticipo = doc.clifor().vendite().get(CFV_CODCAUSINC).full() || doc.tipo().caus_anticipo().full(); + const TCurrency_documento imppagato(anticipo ? doc.get_real(DOC_IMPPAGATO) : ZERO, doc); // Anticipo pagamento if (totale_fatt > imppagato && !doc.get_bool(DOC_ACCSALDO)) // procede se non e' a saldo { const bool is_anticipo = imppagato.get_num() != ZERO; @@ -650,7 +659,7 @@ void TGenerazione_effetti::generate_bill(TDocumento& doc, bool interattivo) // b const long codcf = doc.get_long(DOC_CODCF); const TString4 codval(doc.get(DOC_CODVAL)); const TDate data_cambio = doc.get_date(DOC_DATACAMBIO); - //const bool contro_euro = doc.get_bool(DOC_CONTROEURO); + const bool contro_euro = doc.get_bool(DOC_CONTROEURO); const long codabi = doc.get_long(DOC_CODABIA); const long codcab = doc.get_long(DOC_CODCABA); const TString80 iban = doc.get(DOC_IBAN); @@ -674,7 +683,6 @@ void TGenerazione_effetti::generate_bill(TDocumento& doc, bool interattivo) // b effetto.put(EFF_DATASCAD, pag.data_rata(i)); effetto.put(EFF_TIPOPAG,pag.tipo_rata(i)); effetto.put(EFF_ULTCLASS,pag.ulc_rata(i)); - effetto.put(EFF_MANDATO,doc.get(DOC_MANDATO)); effetto.put(EFF_TIPOCF, tipocf); effetto.put(EFF_CODCF, codcf); effetto.put(EFF_CODVAL, codval); @@ -706,7 +714,21 @@ void TGenerazione_effetti::generate_bill(TDocumento& doc, bool interattivo) // b reffetto.put(REFF_ANNO, doc.get_date(DOC_DATADOCRIF).year()); reffetto.put(REFF_NUMPART, doc.get(DOC_NUMDOCRIF)); } + else + { + const TString4 npart_type = ini_get_string(CONFIG_DITTA, "cg", "RifPro"); + if (npart_type == "M" && effetto.get(EFF_TIPOCF) == "C") + { + reffetto.put(REFF_ANNO, datafatt.year()); + reffetto.put(REFF_NUMPART, format("%02d", datafatt.month())); + } + else + { + reffetto.put(REFF_ANNO, doc.get_date(DOC_DATADOCRIF).year()); + reffetto.put(REFF_NUMPART, doc.get(DOC_NUMDOCRIF)); + } + } importo = pag.importo_rata(i,FALSE); effetto.put(EFF_IMPORTO,importo); reffetto.put(REFF_IMPFATT,totale_fatt.get_num()); diff --git a/src/ve/velib04d.cpp b/src/ve/velib04d.cpp index 73862629a..0ff548746 100755 --- a/src/ve/velib04d.cpp +++ b/src/ve/velib04d.cpp @@ -702,7 +702,8 @@ bool TConsegna_ordini::elabora(TLista_documenti& doc_in, TLista_documenti& doc_o { int j = outdoc.physical_rows(); - if (raggruppa_per_riferimento()) + const bool ordina_per_doc = ini_get_bool(CONFIG_DITTA, "ve", "ORDINA_PER_DOC", true); + if (ordina_per_doc || raggruppa_per_riferimento()) { TToken_string key = inrec.get_rdoc_key(); diff --git a/src/ve/velib04f.cpp b/src/ve/velib04f.cpp index 868584892..2e2447a6d 100755 --- a/src/ve/velib04f.cpp +++ b/src/ve/velib04f.cpp @@ -400,7 +400,7 @@ bool TContabilizzazione_analitica::find_conti(const TRiga_documento& riga, TStri } else { - if (!search_costo_ricavo(riga, bill, riclassifica_fdr_fde)) + if (_usepdcc && !search_costo_ricavo(riga, bill, riclassifica_fdr_fde)) return true; if (bill.ok() && !bill.is_analitico()) { @@ -816,7 +816,7 @@ bool TContabilizzazione_analitica::elabora(TDocumento& doc, long numreg_cg, TVis } } - if (!amount_to_split.is_zero()) + if (amount_to_split != ZERO) split_sp_amount(mov, has_pareggio, totdoc, spese, amount_to_split, no_ca_amount, doc.decimals()); if (can_write && mov.rows() > 0) diff --git a/src/ve/velib05.cpp b/src/ve/velib05.cpp index 655a7a536..242308f3c 100755 --- a/src/ve/velib05.cpp +++ b/src/ve/velib05.cpp @@ -168,7 +168,8 @@ void TDocumentoEsteso::scadenze_recalc() TPagamento& pag = pagamento(); real totspese = spese(); real totimposte = imposta(TRUE); - real pagato = hh.get_real(DOC_IMPPAGATO); + const bool anticipo = clifor().vendite().get(CFV_CODCAUSINC).full() || tipo().caus_anticipo().full(); + real pagato = anticipo ? hh.get_real(DOC_IMPPAGATO) : ZERO; const bool saldo = hh.get_bool(DOC_ACCSALDO); real totimponibili = totale_doc() - ritenute() - totimposte - totspese; const bool is_in_valuta = in_valuta(); diff --git a/src/ve/velib06.cpp b/src/ve/velib06.cpp index 1c3fca807..0f24b6b5c 100755 --- a/src/ve/velib06.cpp +++ b/src/ve/velib06.cpp @@ -155,7 +155,7 @@ TDocumento_mask::TDocumento_mask(const char* td) set_field_handler( F_NUMDOCRIF, datadocrif_handler); set_field_handler( F_DATADOCRIF, datadocrif_handler); set_field_handler( F_LIQDIFF, liqdiff_handler); - + set_field_handler( F_SHEET, sheet_handler); set_handler( DLG_ELABORA, elabora_handler ); set_handler( DLG_PRINT, print_handler ); set_handler( DLG_PREVIEW, print_handler ); @@ -566,6 +566,8 @@ void TDocumento_mask::insert_anal_page() add_number(DLG_NULL, newpage, TR("Cliente "), 2, 4, 6, "D").set_group(10); add_string(DLG_NULL, newpage, "", 24, 4, 50, "D").set_group(11); + add_groupbox(DLG_NULL, newpage, TR("Contabilita' Analitica"), 1, 6, 78, 14); + const TMultilevel_code_info& fasinfo = ca_multilevel_code_info(LF_FASI); const bool use_fsc = fasinfo.levels() > 0; TConfig& ini = ca_config(); @@ -1429,7 +1431,7 @@ void TDocumento_mask::spese2mask() void TDocumento_mask::reset_masks(const TString& tipo_doc) { - static TString4 last_tipo_doc; + static TString16 last_tipo_doc; if (tipo_doc != last_tipo_doc) { @@ -1814,7 +1816,8 @@ void TDocumento_mask::update_giacenza() break; } - TString8 causmag = row.get(sf.cid2index(FR_CAUS)); + TString16 causmag = row.get(sf.cid2index(FR_CAUS)); + if (causmag.blank()) causmag = get(F_CAUSMAG); @@ -1908,7 +1911,9 @@ bool TDocumento_mask::ss_handler(TMask_field& f, KEY key) const TSheet_field& ss = (TSheet_field&)f; TDocumento_mask& mask = (TDocumento_mask&)ss.mask(); - const short cme = mask.cms_end(); + if (!app().is_transaction() && ss.empty()) + ok = yesno_box(TR("Il documento e' privo di righe:\n")); + const short cme = mask.cms_end(); // Se la commessa in testata è vuota controllo che sia presente sulle righe if (cme > 0 && mask.efield(cme).empty()) { @@ -2086,10 +2091,16 @@ bool TDocumento_mask::ss_notify( TSheet_field& ss, int r, KEY key ) riga_mask.enable(DLG_USER, on); } const bool merce = TRiga_documento::tipo(riga_mask.get(FR_TIPORIGA)).is_merce(); - const bool artmag = merce && riga_mask.get(FR_CODARTMAG).full(); - riga_mask.show(FR_UMQTA, artmag); - riga_mask.show(FR_UMQTA2, !artmag); + if (merce) + { + const bool artmag = riga_mask.get(FR_CODARTMAG).full(); + + riga_mask.show(FR_UMQTA, artmag); + riga_mask.show(FR_UMQTA2, !artmag); + } + else + riga_mask.show(FR_UMQTA); if (rdoc.get(RDOC_CODART).empty() && rdoc.get(RDOC_DESCR).empty()) { @@ -3426,7 +3437,7 @@ bool TElabora_mask::elabora() return false ; char provv = get(F_PROVV_ELAB)[0]; int anno = get_int(F_ANNO_ELAB); - const TString4 codnum = get(F_CODNUM_ELAB); + TString16 codnum(get(F_CODNUM_ELAB)); long ndoc = get_long(F_NDOC_ELAB); if (ndoc > 0L && !in.find(provv, anno, codnum, ndoc)) @@ -3868,27 +3879,33 @@ void TDocumento_mask::set_field_handler(short fieldid, CONTROL_HANDLER handler) void TDocumento_mask::user_set_handler(short fieldid, int index) { - switch (index) + switch( index ) { - case 1: set_field_handler(fieldid, ora_hndl); break; - case 2: set_field_handler(fieldid, totdoc_hndl); break; - case 3: set_field_handler(fieldid, numdocrif_hndl); break; - case 4: - /* Cassato il macchinaro! - _smartcard = new TSmart_card(); - if (_smartcard->type() != no_smartcard) - { - set_field_handler(fieldid, smart_hndl); - set_handler(fieldid, universal_handler); - } - else - { - disable(fieldid); - delete _smartcard; - _smartcard = NULL; - } - */ + case 1: + set_field_handler(fieldid, ora_hndl); break; + case 2: + set_field_handler(fieldid, totdoc_hndl); + break; + case 3: + set_field_handler(fieldid, numdocrif_hndl); + break; + /* case 4: + { + _smartcard = new TSmart_card(); + if (_smartcard->type() != no_smartcard) + { + set_field_handler(fieldid, smart_hndl); + set_handler(fieldid, universal_handler); + } + else + { + disable(fieldid); + delete _smartcard; + _smartcard = NULL; + } + } + break; */ case 5: set_field_handler(fieldid, dummy_hndl); break; case 6: set_field_handler(fieldid, fido_hndl); break; case 7: set_field_handler(fieldid, subappalto_hndl); break; @@ -4010,6 +4027,19 @@ bool TDocumento_mask::num_handler( TMask_field& f, KEY key) return TRUE; } +bool TDocumento_mask::tipo_handler( TMask_field& f, KEY key) +{ + if (f.to_check(key, true)) + { + const TTipo_documento & t = cached_tipodoc(f.get()); + + if (t.tipocf() == 'F') + f.mask().set(F_TIPOCF, "F"); + else + f.mask().set(F_TIPOCF, "C"); + } + return true; +} bool TDocumento_mask::codlist_handler( TMask_field& f, KEY key ) { if (key == K_TAB && f.focusdirty()) @@ -4177,7 +4207,7 @@ void TDocumento_mask::update_father_rows(bool add) if (r.is_merce() || r.is_omaggio()|| r.is_prestazione()) { - const TRectype* original_row = r.find_original_rdoc(); + TRiga_documento * original_row = (TRiga_documento *) r.find_original_rdoc(); if (original_row != NULL && _auto_reopen_nums.objptr(original_row->get(RDOC_CODNUM)) != NULL) { @@ -4207,7 +4237,7 @@ void TDocumento_mask::update_father_rows(bool add) *qta += value; else *qta -= value; - if (qta->is_zero()) + if (*qta == ZERO) _father_rows.remove(key); } } diff --git a/src/ve/velib06a.cpp b/src/ve/velib06a.cpp index edd7733d9..d045f9da8 100755 --- a/src/ve/velib06a.cpp +++ b/src/ve/velib06a.cpp @@ -98,6 +98,59 @@ bool totdoc_hndl( TMask_field& field, KEY key ) return true; } +/*bool smart_hndl( TMask_field& field, KEY key ) + +{ + if (key == K_SPACE) + { + TDocumento_mask & m = (TDocumento_mask &) field.mask(); + TSmart_card * s = m.smartcard(); + + if (s != NULL) + { + smartcard_error err = s->connect_card(); + if (err == no_smarterror) + err = s->check_key(m); + if (err == no_smarterror) + { + s->card2mask(m); + if (s->with_card(m)) + m.enable(DLG_SAVEREC); + m.disable(F_CODCF); + m.disable(F_RAGSOC); + } + else + { + s->display_error(err); + if (err == new_card) + if (m.get(F_CODCF).empty() && m.field(F_CODCF).on_key(K_F9) == false) + { + s->disconnect_card(); + return false; + } + } + } + } + else + if (key == K_ENTER) + { + TDocumento_mask & m = (TDocumento_mask &) field.mask(); + TSmart_card * s = m.smartcard(); + + if (s != NULL && s->card_connected()) + { + s->mask2card(m); + smartcard_error err = s->write(); + if (err != no_smarterror) + s->display_error(err); + if (m.insert_mode() && m.doc().codice_numerazione().save_and_new()) + s->disconnect_card(); + } + } + + return true; +} */ + bool fido_hndl(TMask_field& field, KEY key) { if (key == K_ENTER && !field.empty()) @@ -2391,27 +2444,39 @@ bool sppr_handler( TMask_field& f, KEY key ) { const TRectype& curr = ((TEdit_field&)f).browse()->cursor()->curr(); const TSpesa_prest sp(curr); - + const TDocumento_mask& mask = (const TDocumento_mask&)row_mask.get_sheet()->mask(); + TSheet_field & s = mask.sfield(F_SHEET); const int pos = row_mask.id2pos(FR_PREZZO); if (pos >= 0 && !sp.empty()) { const char tipo = sp.tipo(); - const bool qta_val_fl = tipo == 'Q'; + const bool qta_val_fl = (tipo == 'Q') || (tipo <= ' '); const bool perc_fl = tipo == 'P'; int pos = row_mask.id2pos(FR_UMQTASP); if (pos >= 0) + { + row_mask.fld(pos).show(!perc_fl); row_mask.fld(pos).enable(!perc_fl); + s.enable_cell(s.selected(), s.cid2index(FR_UMQTASP), !perc_fl); + + } pos = row_mask.id2pos(FR_PREZZO); if (pos >= 0) + { row_mask.fld(pos).enable(!perc_fl); + s.enable_cell(s.selected(), s.cid2index(FR_SCONTO), !perc_fl); + } pos = row_mask.id2pos(FR_SCONTO); if (pos >= 0) - row_mask.fld(pos).enable(!perc_fl); - pos = row_mask.id2pos(FR_QTA); + { + row_mask.fld(pos).enable(!perc_fl); + s.enable_cell(s.selected(), s.cid2index(FR_SCONTO), !perc_fl); + } + pos = row_mask.id2pos(FR_QTA); if (pos >= 0) { - row_mask.fld(pos).show(!perc_fl); + row_mask.fld(pos).show(qta_val_fl); row_mask.fld(pos).enable(qta_val_fl); } pos = row_mask.id2pos(FR_PERCSP); @@ -2420,9 +2485,14 @@ bool sppr_handler( TMask_field& f, KEY key ) row_mask.fld(pos).show(perc_fl); row_mask.fld(pos).enable(perc_fl); } + s.enable_cell(s.selected(), s.cid2index(FR_QTA), perc_fl || qta_val_fl); + if (!perc_fl) { const TDocumento_mask& mask = (const TDocumento_mask&)row_mask.get_sheet()->mask(); + TSheet_field & s = mask.sfield(F_SHEET); + + s.enable_cell(s.selected(), s.cid2index(FR_QTA), qta_val_fl); const real cambio = mask.get_real(F_CAMBIO); real prezzo = sp.prezzo(); const TString& doc_valuta = mask.get(F_CODVAL); @@ -2557,7 +2627,6 @@ bool TDocumento_mask::numdocrif_search_handler(TMask_field& f, KEY key) return true; } -/* bool TDocumento_mask::ragsoc_search_handler(TMask_field& f, KEY key) { if (key == K_F9) @@ -2566,6 +2635,7 @@ bool TDocumento_mask::ragsoc_search_handler(TMask_field& f, KEY key) TRelation rel(LF_DOC); rel.add(LF_CLIFO, "TIPOCF==TIPOCF|CODCF==CODCF"); + rel.add(LF_COMUNI, "STATO==STATOCF|COM==COMCF", 1 , LF_CLIFO); TRectype& filtrec = rel.curr(); filtrec.put(DOC_PROVV, m.get(F_PROVV)); @@ -2604,7 +2674,54 @@ bool TDocumento_mask::ragsoc_search_handler(TMask_field& f, KEY key) } return true; } -*/ + +bool TDocumento_mask::rif_search_handler(TMask_field& f, KEY key) +{ + if (key == K_F9) + { + TMask& m = f.mask(); + + TRelation rel(LF_DOC); + rel.add(LF_CLIFO, "TIPOCF==TIPOCF|CODCF==CODCF"); + rel.add(LF_COMUNI, "STATO==STATOCF|COM==COMCF", 1 , LF_CLIFO); + + TRectype& filtrec = rel.curr(); + filtrec.put(DOC_PROVV, m.get(F_PROVV)); + filtrec.put(DOC_ANNO, m.get(F_ANNO)); + filtrec.put(DOC_CODNUM, m.get(F_CODNUM)); + + TSorted_cursor cur(&rel, "TIPOCF|UPPER(20->RICALT)|PROVV|ANNO|CODNUM|PROVV|NDOC", "", 1, &filtrec, &filtrec); + TString filter; filter.format("(CODNUM==\"%s\")&&(PROVV==\"D\")&&(TIPOCF==\"%s\")", + (const char*)m.get(F_CODNUM), (const char*)m.get(F_TIPOCF)); + + cur.setfilter(filter, true); + TToken_string siblings; + TToken_string header(HR("Ric.Altern.@15|Ragione Sociale@50|Codice|Documento|Data\nDocumento@10|Totale\nDocumento@18V|Valuta|Stato|Partita IVA|Indirizzo@50|Numero@15|Località@50|Comune@50")); + TToken_string fieldlist("20->RICALT|20->RAGSOC|CODCF|NDOC|DATADOC|G1:TOTDOC|CODVAL|STATO|20->PAIV|20->INDCF|20->CIVCF|20->LOCALITACF|13->DENCOM"); + add_custom_search_fields(m, fieldlist, header); + + TBrowse_sheet sheet(&cur, fieldlist, TR("Ricerca Alternativa"), + header, 0, (TEdit_field&)f, siblings); + + if (!f.empty()) + { + TString rif(f.get()); rif.upper(); + filtrec.zero(); + filtrec.put(DOC_TIPOCF, m.get(F_TIPOCF)); + rel.curr(LF_CLIFO).put(CLI_RICALT, rif); + cur.read(); + } + + if (sheet.run() == K_ENTER) + { + const int pos_ndoc = fieldlist.get_pos(DOC_NDOC); + const long ndoc = sheet.row(-1).get_long(pos_ndoc); + m.set(F_NDOC, ndoc); + m.stop_run(K_AUTO_ENTER); + } + } + return true; +} bool TDocumento_mask::datadocrif_handler(TMask_field& f, KEY key) { @@ -2622,6 +2739,40 @@ bool TDocumento_mask::datadocrif_handler(TMask_field& f, KEY key) return true; } +bool TDocumento_mask::sheet_handler(TMask_field& f, KEY key) +{ + if (key == K_CTRL + 'V') + { + TDocumento_mask& m = (TDocumento_mask&)f.mask(); + TDocumento & doc = m.doc(); + TSheet_field & s = m.sfield(F_SHEET); + int from, to, offset; + + if (!s.get_range_selection(from, to)) + { + from = 0; + to = s.items() - 1; + } + offset = to - from; + from = s.selected() + 1; + if (from <= 0) + from = 1; + else + if(from > doc.physical_rows()) + from = doc.physical_rows() + 1; + + to = from + offset; + for (int i = from; i <= to ; i++) + if (i > doc.physical_rows()) + doc.new_row(s.row(i - 1).get(s.cid2index(FR_TIPORIGA))); + else + doc.insert_row(i, s.row(i).get(s.cid2index(FR_TIPORIGA))); + for (int i = from; i <= to ; i++) + doc[i].autosave(s); + } + return true; +} + bool TDocumento_mask::liqdiff_handler( TMask_field& f, KEY key ) { if (key == K_ENTER && f.get().full()) diff --git a/src/ve/velib07.cpp b/src/ve/velib07.cpp index a558cf794..a307c5404 100755 --- a/src/ve/velib07.cpp +++ b/src/ve/velib07.cpp @@ -266,6 +266,12 @@ TObject* TDocument_cache::key2obj(const char* key) return doc; } +void TDocument_cache::set_firmval(bool firmval) +{ + _firmval = firmval; + destroy(); +} + TDocumento& TDocument_cache::doc(const TRectype& rec) { TToken_string key; @@ -278,7 +284,7 @@ TDocumento& TDocument_cache::doc(const TRectype& rec) } -TDocument_cache:: TDocument_cache() : TCache(3) +TDocument_cache:: TDocument_cache(bool firmval) : TCache(3), _firmval(firmval) { } @@ -441,6 +447,107 @@ void TDocument_report::reset_values(const TString& output) } } +bool TDocument_report::msg_cliente(TVariant_stack& stack) +{ + TReport_field& cf = *curr_field(); + const int idx =((TISAM_recordset *)recordset())->cursor()->relation()->log2ind(LF_DOC); + + if (idx < 0) + return false; + + const TRectype& rec = ((TISAM_recordset*)recordset())->cursor()->relation()->file(idx).curr(); + TDocumento & doc = (TDocumento &)((TDocument_recordset*)recordset())->doc(rec); + + const TCli_for& cli_for = doc.clifor(); + const TOccasionale& cli_occ = doc.occas(); + const bool occasionale = cli_for.occasionale(); + + TString in = stack.pop().as_string(); // prende la macro o il fieldref + TString valore; + + if (in[0] != '!') + { + // Controlla l'esistenza dei campi... + if (occasionale && cli_occ.exist(in)) + valore = cli_occ.get(in); + + if (!occasionale && cli_for.exist(in)) + valore = cli_for.get(in); + + cf.set(valore); + return true; + } + in.ltrim(1); + if (in=="INDNUM") + { + valore = occasionale ? cli_occ.get(OCC_INDIR) : cli_for.get(CLI_INDCF); + valore << ' '; + valore << (occasionale ? cli_occ.get(OCC_CIV) : cli_for.get(CLI_CIVCF)); + cf.set(valore); + return true; + } + if (in.find("COM") == 0) + { + const bool nascita = in[3] == 'N'; + const int p = in.find("->"); + if (p > 0) + in.ltrim(p + 2); + + TString8 key; + if (nascita) + { + key = occasionale ? cli_occ.get(OCC_STATONASC) : cli_for.get(CLI_STATONASC); + key << '|' << (occasionale ? cli_occ.get(OCC_COMNASC) : cli_for.get(CLI_COMNASC)); + } + else + { + key = occasionale ? cli_occ.get(OCC_STATO): cli_for.get(CLI_STATOCF); + key << '|' << (occasionale ? cli_occ.get(OCC_COM): cli_for.get(CLI_COMCF)); + } + valore = cache().get(LF_COMUNI, key, in); + cf.set(valore); + return true; + } + if (in.find("CAP") == 0) + { + valore = occasionale ? cli_occ.get(OCC_CAP) : cli_for.get(CLI_CAPCF); + cf.set(valore); + return true; + } + if (in.find("TEL") == 0) + { + if (!occasionale) + { + if (in.len() == 3) + in << "1"; + const TString num(cli_for.get(in)); + in.insert("P"); + valore = cli_for.get(in); + valore << "/" << num; + } + cf.set(valore); + return true; + } + if (in=="FAX") + { + if (!occasionale) + { + valore = cli_for.get("PFAX"); + valore << "/" << cli_for.get("FAX"); + } + cf.set(valore); + return true; + } + if (in=="RAGSOC") + { + valore = occasionale ? cli_occ.get(in) : cli_for.get(in); + valore.strip_double_spaces(); + cf.set(valore); + return true; + } + return false; +} + bool TDocument_report::msg_parent_doc(TVariant_stack& stack) { TReport_field& cf = *curr_field(); @@ -567,11 +674,61 @@ bool TDocument_report::msg_parent_row(TVariant_stack& stack) return true; } +bool TDocument_report::msg_riepilogo_iva(TVariant_stack& stack) +{ + // tabella riepilogo aliquote iva e relative imposte + // sintassi: _RIEPILOGOIVA,, + // dove: parte da zero se ' e minore di zero vengono scritti tutti + // dove: è uno dei seguenti: + // COD colonna dei codici + // IMP colonna degli imponibili + // IVA colonna delle imposte + // ALI colonna delle aliquote + // DES colonna delle descrizioni (stampata solo se il regime IVA non e' normale) + + int index = stack.pop().as_int(); + const int idx =((TISAM_recordset *)recordset())->cursor()->relation()->log2ind(LF_DOC); + + if (idx < 0) + return false; + + const TRectype& rec = ((TISAM_recordset*)recordset())->cursor()->relation()->file(idx).curr(); + TDocumento & doc = (TDocumento &)((TDocument_recordset*)recordset())->doc(rec); + TAssoc_array & IVA = doc.tabella_iva(); // serve per aggiornare la tebella + TRiepilogo_iva * r = (TRiepilogo_iva *) doc.riepilogo_iva(index); + TString value; + if (r != NULL) + { + const TString& what = stack.pop().as_string(); // cosa deve stampare ? + + if (what == "COD") // Ritorna il codice IVA + value = r->cod_iva().codice(); + else + if (what == "IMP") // Ritorna l'imponibile + value = r->imp().string(); + else + if (what == "IVA") // Ritorna l'imposta + value = r->iva().string(); + else + if (what == "ALI") // Ritorna l'aliquota % + value << r->cod_iva().percentuale().string(); + else + if (what == "DES" && r->cod_iva().tipo().not_empty()) + value == r->cod_iva().descrizione(); + } + + const bool full = value.full(); + + curr_field()->show(full); + curr_field()->set(TVariant(full ? value : "")); + return true; +} + size_t TDocument_report::get_usr_words(TString_array& words) const { TReport::get_usr_words(words); - - const char* const name[] = { "DOC_PARENT_DOC", "DOC_PARENT_ROW", NULL }; + const char* const name[] = { "DOC_CLIENTE", "DOC_PARENT_DOC", "DOC_PARENT_ROW", + "DOC_TABELLA_IVA", NULL}; ((TDocument_report*)this)->_first_msg = words.items(); // Calcola il primo numero disponibile for (size_t i = 0; name[i] != NULL; i++) @@ -587,9 +744,11 @@ bool TDocument_report::execute_usr_word(unsigned int opcode, TVariant_stack& sta opcode -= _first_msg; switch (opcode) { - case 0 : msg_parent_doc(stack); break; - case 1 : msg_parent_row(stack); break; - default: break; + case 0: msg_cliente(stack); break; + case 1: msg_parent_doc(stack); break; + case 2: msg_parent_row(stack); break; + case 3: msg_riepilogo_iva(stack); break; + default: break; } while (!stack.pop().is_null()); // Svuota eventuali parametri variabili inutilizzati @@ -618,6 +777,8 @@ static const TString_array& mastro(char tipocf) const int conto = mastri.get(PCN_CONTO).as_int(); const int indbil = mastri.get(PCN_INDBIL).as_int(); const char tipocf = mastri.get(PCN_TMCF).as_string()[0]; + if (tipocf > ' ') + { TToken_string info; info.add(gruppo); info.add(conto); @@ -625,10 +786,11 @@ static const TString_array& mastro(char tipocf) m[tipocf == 'C' ? 0 : 1].add(info); } } + } return a; } -static real calcola_saldo_contabile(const long codcf, const TDate& datacalc) +static real calcola_saldo_contabile(const char tipocf, const long codcf, const TDate& datacalc) { real saldone; @@ -644,7 +806,7 @@ static real calcola_saldo_contabile(const long codcf, const TDate& datacalc) datainies.set_month(1); } - const TString_array& a = mastro('C'); + const TString_array& a = mastro(tipocf); //per tutti i mastri selezionati va a calcolare il saldo del cliente/fornitore in input FOR_EACH_ARRAY_ROW(a, i, row) @@ -669,18 +831,18 @@ static TImporto get_importo(const TISAM_recordset& partite, const char* sezione, } -static real calcola_esposto_da_saldaconto (long codcf, const TDate& datacalc) +static real calcola_esposto_da_saldaconto (const char tipocf, const long codcf, const TDate& datacalc, const int riskdays) { - const int riskdays = ini_get_int(CONFIG_DITTA, "ve", "FIDO_RISKDAYS"); - //estrae le righe partita relative a pagamenti successivi alla data di rischio (e con tipopag >2,<7) TString query; query << "USE PART\nSELECT BETWEEN(DATAPAG,#DATASBF,0)&&BETWEEN(TIPOPAG,2,7)\n"; - query << "FROM TIPOC=C GRUPPO=0 CONTO=0 SOTTOCONTO=#CODCF ANNO=#ANNO\n"; - query << "TO TIPOC=C GRUPPO=0 CONTO=0 SOTTOCONTO=#CODCF"; + query << "FROM TIPOC=#TIPOCF GRUPPO=0 CONTO=0 SOTTOCONTO=#CODCF ANNO=#ANNO\n"; + query << "TO TIPOC=#TIPOCF GRUPPO=0 CONTO=0 SOTTOCONTO=#CODCF"; TISAM_recordset partite(query); + TString4 str_tipocf = tipocf; + partite.set_var("#TIPOCF", TVariant(str_tipocf)); partite.set_var("#CODCF", codcf); partite.set_var("#DATACALC", datacalc); //data considerante i giorni di rischio ammessi dall'utonto @@ -719,8 +881,8 @@ static real calcola_esposto_da_saldaconto (long codcf, const TDate& datacalc) } //la normalizzazione del totale delle partite va fatta in base al fatto che si parli di 'C'liente o 'F'ornitore - //const char sezione_finale = (tipocf == 'C') ? 'A' : 'D'; - importone_esposto.normalize('A'); + const char sezione_finale = (tipocf == 'C') ? 'A' : 'D'; + importone_esposto.normalize(sezione_finale); //valore in output real esposto; @@ -730,40 +892,42 @@ static real calcola_esposto_da_saldaconto (long codcf, const TDate& datacalc) } -static real calcola_fido_da_documenti(long codcf, const TDate& datacalc, const TDoc_key& ignore) +static real calcola_fido_da_documenti(const char tipocf, const long codcf, const TDate& datacalc, const TDoc_key& ignore) { real totalone; - - // scansione delle righe FIDO_XX(j)=.. sul paragrafo di configurazione VE - // per avere i parametri di numerazione/tipo da considerare TConfig config(CONFIG_DITTA, "ve"); - for (int j = 0; ;j++) + + //scansione delle righe FIDO_XX(j)=.. sul paragrafo di configurazione VE per avere i parametri di numerazione/tipo.. + //..da considerare + for (int j = 0;;j++) { const TString& num_fido = config.get("FIDO_NUM", NULL, j); //se manca la numerazione si può fermare,in quanto non può esistere un tipo senza numerazione if (num_fido.blank()) break; - const TString& tipo_fido = config.get("FIDO_TIP", NULL, j); - const TString& da_stato_fido = config.get("FIDO_DASTA", NULL, j); - const TString& a_stato_fido = config.get("FIDO_ASTA", NULL, j); - const bool residuo_fido = config.get_bool("FIDO_RES", NULL, j); + const TString& tipo_fido = config.get("FIDO_TIP", NULL, j); + const TString4 da_stato_fido = config.get("FIDO_DASTA", NULL, j); + const TString4 a_stato_fido = config.get("FIDO_ASTA", NULL, j); + const bool residuo_fido = config.get_bool("FIDO_RES", NULL, j); //per la numerazione scelta queryzza gli archivi alla ricerca dei documenti che rientrano nei parametri TString query; query << "USE DOC KEY 2\n"; query << "SELECT (CODNUM=#CODNUM)&&(TIPODOC=#TIPODOC)&&(BETWEEN(STATO,#DASTATO,#ASTATO))\n"; - query << "FROM TIPOCF=C CODCF=#CODCF PROVV='D'\n"; - query << "TO TIPOCF=C CODCF=#CODCF PROVV='D' ANNO=#ANNO DATADOC=#DATACALC"; + query << "FROM TIPOCF=#TIPOCF CODCF=#CODCF PROVV='D'\n"; + query << "TO TIPOCF=#TIPOCF CODCF=#CODCF PROVV='D' ANNO=#ANNO DATADOC=#DATACALC"; TISAM_recordset documenti(query); - documenti.set_var("#CODCF", codcf); - documenti.set_var("#ANNO", (long)datacalc.year()); + const char str_tipocf[2] = { tipocf, 0 }; + documenti.set_var("#TIPOCF", TVariant(str_tipocf)); + documenti.set_var("#CODCF", codcf); + documenti.set_var("#ANNO", TVariant((long)datacalc.year())); documenti.set_var("#DATACALC", datacalc); - documenti.set_var("#CODNUM", num_fido); - documenti.set_var("#TIPODOC", tipo_fido); - documenti.set_var("#DASTATO", da_stato_fido); - documenti.set_var("#ASTATO", a_stato_fido); + documenti.set_var("#CODNUM", TVariant(num_fido)); + documenti.set_var("#TIPODOC", TVariant(tipo_fido)); + documenti.set_var("#DASTATO", TVariant(da_stato_fido)); + documenti.set_var("#ASTATO", TVariant(a_stato_fido)); const int items = documenti.items(); if (items > 0) @@ -808,11 +972,11 @@ static real calcola_fido_da_documenti(long codcf, const TDate& datacalc, const T real calcola_fido_cliente (long codcf, const TDate& datacalc, const TDoc_key& ignore) { //PRIMA PARTE: controlla i movimenti - real saldo_contabile = calcola_saldo_contabile(codcf, datacalc); + real saldo_contabile = calcola_saldo_contabile('C', codcf, datacalc); //SECONDA PARTE: controlla il saldaconto - real esposto_saldaconto = calcola_esposto_da_saldaconto(codcf, datacalc); + real esposto_saldaconto = calcola_esposto_da_saldaconto('C', codcf, datacalc, 10); // 10 giorni ? //TERZA PARTE: controlla i documenti - real tot_documenti = calcola_fido_da_documenti(codcf, datacalc, ignore); + real tot_documenti = calcola_fido_da_documenti('C',codcf, datacalc, ignore); return saldo_contabile + esposto_saldaconto + tot_documenti; } diff --git a/src/ve/velib07.h b/src/ve/velib07.h index 880c8e110..728dfb98c 100755 --- a/src/ve/velib07.h +++ b/src/ve/velib07.h @@ -67,13 +67,16 @@ public: class TDocument_cache : TCache { + bool _firmval; + protected: virtual TObject* key2obj(const char* key); public: + void set_firmval(bool firmval = true); TDocumento& doc(const TRectype& rec); - TDocument_cache(); + TDocument_cache(bool firmval = false); virtual ~TDocument_cache(); }; @@ -90,6 +93,7 @@ protected: virtual const TVariant& get_field(int num, const char* field) const; public: + void set_firmval(bool firmval = true) { _cache.set_firmval(firmval);} const TDocumento& doc(const TRectype& rec) { return _cache.doc(rec);} TDocument_recordset(const char* use) : TISAM_recordset(use) { } @@ -108,8 +112,11 @@ class TDocument_report : public TReport protected: virtual size_t get_usr_words(TString_array& words) const; virtual bool execute_usr_word(unsigned int opcode, TVariant_stack& stack); + bool msg_cliente(TVariant_stack& stack); bool msg_parent_doc(TVariant_stack& stack); bool msg_parent_row(TVariant_stack& stack); + bool msg_riepilogo_iva(TVariant_stack& stack); + void output_values(const TRectype& rec, const TString& output); void reset_values(const TString& output); diff --git a/src/ve/verig02.uml b/src/ve/verig02.uml index 8d1e53eab..ba4801727 100755 --- a/src/ve/verig02.uml +++ b/src/ve/verig02.uml @@ -11,6 +11,9 @@ DEFINE_FIELD(DESCRSPV) DEFINE_FIELD(UMQTASP) DEFINE_FIELD(VALORE) DEFINE_FIELD(QTA) +DEFINE_FIELD(QTAEVASA) +DEFINE_FIELD(RIGAEVASA) +DEFINE_FIELD(DATACONS) DEFINE_FIELD(SCONTO) F_POS(SCONTO, 2, 11,"Sconto " ) DEFINE_FIELD(CODIVA) diff --git a/src/ve/verig03.uml b/src/ve/verig03.uml index 903086a6a..7eda4180e 100755 --- a/src/ve/verig03.uml +++ b/src/ve/verig03.uml @@ -10,6 +10,9 @@ DEFINE_FIELD(DESCRSPQ) DEFINE_FIELD(UMQTASP) DEFINE_FIELD(QTA) DEFINE_FIELD(PREZZO) +DEFINE_FIELD(QTAEVASA) +DEFINE_FIELD(RIGAEVASA) +DEFINE_FIELD(DATACONS) DEFINE_FIELD(SCONTO) F_POS(SCONTO, 2, 11,"Sconto " ) DEFINE_FIELD(CODIVA) diff --git a/src/ve/veuml.h b/src/ve/veuml.h index a536de1a5..4697910e2 100755 --- a/src/ve/veuml.h +++ b/src/ve/veuml.h @@ -104,6 +104,7 @@ #define F_CODDITTA 209 #define F_RAGSOCDITTA 210 #define F_LIQDIFF 211 +#define F_RIFSEARCH 212 #define F_CODNUMRIF 212 #define F_ANNORIF 213