diff --git a/src/ve/ve0100.cpp b/src/ve/ve0100.cpp index d8371b216..744a67bbe 100755 --- a/src/ve/ve0100.cpp +++ b/src/ve/ve0100.cpp @@ -585,9 +585,9 @@ bool TMotore_application::remove() // C 90 void TMotore_application::on_firm_change() { - if (_config_ditta != NULL) - delete _config_ditta; - _config_ditta = new TConfig(CONFIG_DITTA); +// if (_config_ditta != NULL) +// delete _config_ditta; +// _config_ditta = new TConfig(CONFIG_DITTA); _doc_masks.destroy(); load_auto_reopen_data(); TRelation_application::on_firm_change(); @@ -721,7 +721,7 @@ bool TMotore_application::user_create( ) cached_tipodoc(tip.get("CODTAB").as_string()); } - _config_ditta = new TConfig(CONFIG_DITTA); + //_config_ditta = new TConfig(CONFIG_DITTA); // Metto in relazione testata e righe _rel = new TRelation(LF_DOC); @@ -827,8 +827,8 @@ bool TMotore_application::user_destroy( ) utente.set( "CODNUM", _codnum ); utente.set( "TIPODOC", _tipodoc ); - if (_config_ditta != NULL) - delete _config_ditta; + // if (_config_ditta != NULL) + // delete _config_ditta; // Distruggo la maschera di modifica if ( _msk != NULL ) delete _msk; diff --git a/src/ve/ve0100.h b/src/ve/ve0100.h index 5033721aa..bab5e9ad0 100755 --- a/src/ve/ve0100.h +++ b/src/ve/ve0100.h @@ -22,7 +22,7 @@ class TMotore_application : public TRelation_application TArray _file; // Tutti i file da usare // Puntatore al profilo del documento caricato - TConfig * _config_ditta; + // TConfig * _config_ditta; // Puntatore alla maschera di ricerca TMask * _msk; @@ -99,7 +99,7 @@ public: virtual TDocumento_mask & edit_mask() const { CHECK( _docmsk, "Maschera di edit nulla!" ); return *_docmsk; } TRelation & rel() { CHECK( _rel, "Relazione nulla!" ); return *_rel; } TSheet_field & sheet() { return edit_mask().sheet(); } - TConfig & config_ditta() {return *_config_ditta; } +// TConfig & config_ditta() {return *_config_ditta; } TDocumento & doc() {return edit_mask().doc(); } // Operazione diff --git a/src/ve/velib.h b/src/ve/velib.h index 02ec93c53..0b8a81e65 100755 --- a/src/ve/velib.h +++ b/src/ve/velib.h @@ -28,8 +28,7 @@ class TViswin; #ifndef __CGLIB_H #include "../cg/cglib.h" #endif - - + #ifndef __CGPAGAME_H #include "../cg/cgpagame.h" #endif @@ -81,6 +80,7 @@ class TCond_vendita; class TIVA_array; class TArticolo_giacenza; class TCache_articoli; +class TConsegna_ordini; // class TSmart_card; bool ora_hndl(TMask_field& field, KEY key); @@ -383,6 +383,9 @@ public: bool check_double_art() const { return _check_double_art; } bool ignora_anticipi_fatturazione() const { return _ignora_anticipi_fatturazione; } const TDate & first_ok_date(); + + bool auto_evasione() const { return get_bool("B15"); } + const TString & auto_evasione_elab() const { return get("S12"); } TTipo_documento(const char* tipodoc = NULL); TTipo_documento(const TRectype& rec); @@ -605,6 +608,7 @@ public: void dirty_fields(bool dirty_document = true); bool doc_dependent() const; int numero() const { return get_int(RDOC_NRIGA); } + const TString & codice() const { return get(RDOC_CODARTMAG).full() ? get(RDOC_CODARTMAG) : get(RDOC_CODART); } void set_numero(int numero) { put(RDOC_NRIGA, numero);} bool is_generata() const { return get_bool(RDOC_GENERATA);} void generata(bool on = true) { put(RDOC_GENERATA, on);} @@ -707,6 +711,9 @@ public: void set_descr(const char* descr); // Setta DESCR ed eventualmente DESCLUNGA+DESCEST + void update_orders(real qta, TToken_string & tipi, TToken_string & stati, + const char stato_aperto, const char stato_evaso); + TRiga_documento(TDocumento* doc, const char* tipo = NULL); TRiga_documento(const TRiga_documento & row); virtual ~TRiga_documento() {} @@ -793,6 +800,7 @@ class TDocumento : public TMultiple_rectype // velib03 static TCodgiac_livelli *_livelli; TAssoc_array _conaiqta; // Per ogni sottocategoria CONAI mi calcola la qta + TArray _qta_evasa_auto; protected: virtual TRectype * new_body_record(int logicnum = 0) @@ -824,8 +832,11 @@ protected: void check_modules(); virtual void set_variables(TExpression * e) const ; void update_raee(); + void update_orders(int nrow, real & qta); + public: + virtual TRiga_documento * rowptr(int index); int set_row_ids(); long renum_ndoc(long numdoc = 0); virtual bool renum() { return renum_ndoc() > 0;} @@ -970,7 +981,14 @@ public: bool is_split_payment() const; void cli2doc(); - + + void update_row_auto_qta(int nrow, real & qta, bool plus = true); + bool check_auto_evasione() const { return _qta_evasa_auto.items() > 0; } + void auto_evasione(); + + int find_nrow(const char * tiporiga, const char * codice) const; + TRiga_documento & find_row(const char * tiporiga, const char * codice); + TDocumento (); TDocumento (const TDocumento& d); TDocumento(char provv, int anno, const char* codnum, long numdoc); @@ -979,18 +997,54 @@ public: virtual ~TDocumento(); }; -/* -#define FOR_EACH_PHYSICAL_RDOC(__doc, __r, __rdoc) TRiga_documento* __rdoc=NULL; \ - TRecord_array& bodyof##__rdoc = (__doc).body(); \ - for (int __r = bodyof##__rdoc.first_row(); bodyof##__rdoc.exist(__r) && (__rdoc=&(__doc)[__r])!=NULL; __r=bodyof##__rdoc.succ_row(__r)) -*/ -#define FOR_EACH_PHYSICAL_RDOC(__doc, __r, __rdoc) TRiga_documento* __rdoc=NULL; \ - TRecord_array& bodyof##__rdoc = (__doc).body(); \ - for (int __r = bodyof##__rdoc.first_row(); bodyof##__rdoc.exist(__r) && (__rdoc=&(TRiga_documento&)bodyof##__rdoc.row(__r))!=NULL; __r=bodyof##__rdoc.succ_row(__r)) +// With doc -#define FOR_EACH_PHYSICAL_RDOC_BACK(__doc, __r, __rdoc) TRiga_documento* __rdoc=NULL; \ - TRecord_array& bodyof##__rdoc = (__doc).body(); \ - for (int __r = bodyof##__rdoc.last_row(); __r>0 && (__rdoc=&(TRiga_documento&)bodyof##__rdoc.row(__r))!= NULL; __r = bodyof##__rdoc.pred_row(__r)) + +#define FOR_EACH_PHYSICAL_RDOC(__doc, __r, __rdoc) \ + const int nr##__r = ((TDocumento &)__doc).physical_rows(); \ + int __r = 1; \ + for (TRiga_documento *__rdoc = ((TDocumento &)__doc).rowptr(__r); \ + __r <= nr##__r; __rdoc = ((TDocumento &)__doc).rowptr(++__r)) + +#define FOR_EACH_PHYSICAL_RDOC_BACK(__doc, __r, __rdoc) \ + int __r = ((TDocumento &)__doc).physical_rows(); \ + for (TRiga_documento *__rdoc = ((TDocumento &)__doc).rowptr(__r); \ + __r > 0; __rdoc = ((TDocumento &)__doc).rowptr(--__r)) + +#define FOR_EACH_RDOC(_doc, __r, __row) \ + const int nr##__r = ((TDocumento &)__doc).rows(); \ + int __r = 1; \ + for (TRiga_documento *__rdoc = ((TDocumento &)__doc).rowptr(__r); \ + __r <= nr##__r; __rdoc = ((TDocumento &)__doc).rowptr(++__r)) + +#define FOR_EACH_RDOC_BACK(__doc, __r, __rdoc) \ + int __r = ((TDocumento &)__doc).rows(); \ + for (TRiga_documento *__rdoc = ((TDocumento &)__doc).rowptr(__r); \ + __r > 0; __rdoc = &(((TDocumento &)__doc).rowptr(--__r))) + +// Without doc + +#define FOR_EACH_SELF_PHYSICAL_RDOC(__r, __rdoc) \ + const int nr##__r = physical_rows(); \ + int __r = 1; \ + for (TRiga_documento *__rdoc = ((TDocumento *)this)->rowptr(__r); \ + __r <= nr##__r; __rdoc = ((TDocumento *)this)->rowptr(++__r)) + +#define FOR_EACH_SELF_PHYSICAL_RDOC_BACK(__r, __rdoc) \ + int __r = physical_rows(); \ + for (TRiga_documento *__rdoc = ((TDocumento *)this)->rowptr(__r); \ + __r > 0; __rdoc = ((TDocumento *)this)->rowptr(--__r)) + +#define FOR_EACH_SELF_RDOC(__r, __rdoc) \ + const int nr##__r = rows(); \ + int __r = 1; \ + for (TRiga_documento *__rdoc = ((TDocumento *)this)->rowptr(__r); \ + __r <= nr##__r; __rdoc = ((TDocumento *)this)->rowptr(++__r)) + +#define FOR_EACH_SELF_RDOC_BACK(__r, __rdoc) \ + int __r = rows(); \ + for (TRiga_documento *__rdoc = ((TDocumento *)this)->rowptr(__r); \ + __r > 0; __rdoc = ((TDocumento *)this)->rowptr(--__r)) class TCurrency_documento : public TCurrency { diff --git a/src/ve/velib02.cpp b/src/ve/velib02.cpp index 2886f6d63..36c3cca85 100755 --- a/src/ve/velib02.cpp +++ b/src/ve/velib02.cpp @@ -1,4 +1,5 @@ #include "velib.h" +#include "velib04.h" #include "sconti.h" #include "vepriv.h" #include "../ca/commesse.h" @@ -225,7 +226,8 @@ const TSpesa_prest & TRiga_documento::spesa() const TString80 index; index << tipor << codice; TSpesa_prest* s = (TSpesa_prest*)_spese.objptr(index); - if (s == NULL) + + if (s == nullptr) { s = new TSpesa_prest(codice, tipor); _spese.add(index, s); @@ -323,6 +325,124 @@ void TRiga_documento::test_firm() _firm = new_firm; } } + +void TRiga_documento::update_orders(real qta, TToken_string & tipi, TToken_string & stati, + const char stato_aperto, const char stato_evaso) +{ + if (is_evadibile() && qta != ZERO) + { + const bool storno = qta < ZERO; + const TString4 tiporiga = tipo().codice(); + const TString40 codart = codice(); + real qta_da_evadere = storno ? -qta : qta; + + if (codart.full()) + { + const int year = _doc->get_date(DOC_DATADOC).year(); + const TDate dadata(1, 1, year - 5); + const TDate adata(31, 12, year); + TLista_documenti docs; + TString_array saved; + TString_array evaded; + TString_array to_delete; + TToken_string original(get_original_rdoc_key(), ','); + const TString & refs = get(RDOC_ORIGINAL_ROWS); + + if (refs.full()) + original.add(refs); + saved.tok2arr(original, false); + docs.read('D', _doc->get_char(DOC_TIPOCF), _doc->get_long(DOC_CODCF), + year, tipi, stati, dadata, adata); + + int ndocs = docs.items(); + + for (int i = 0; i < ndocs; i++) + if (docs[i].find_nrow(tiporiga, codart) < 0) + docs.destroy(i, false); + docs.pack(); + if (storno) + { + FOR_EACH_ARRAY_ROW(saved, i, keystr) + { + TDoc_key key(keystr->get_int(1), keystr->get(0), keystr->get_long(3), keystr->get_char(2)); + TDocumento saved_doc(key); + + if (saved_doc.stato() == stato_evaso && docs.find(saved_doc) == -1) + docs.add(saved_doc); + } + docs.sort(); + } + // docs->merge(actdocs); + ndocs = docs.items(); + for (int i = storno ? ndocs - 1 : 0; qta_da_evadere > ZERO && (storno ? i >= 0 : i < ndocs); storno ? i-- : i++) + { + TDocumento & d = docs[i]; + TRiga_documento & rdoc = d.find_row(tiporiga, codart); + TToken_string rdoc_key = rdoc.get_rdoc_key(); + real qta_evasa = qta_da_evadere; + bool riga_evasa = false; + + if (storno) + { + const real & evaso = rdoc.qtaevasa(); + + if (qta_evasa > evaso) + { + qta_evasa = evaso; + to_delete.add(rdoc_key); + } + rdoc.sub(RDOC_QTAEVASA, qta_evasa); + } + else + { + const real & residuo = rdoc.qtaresidua(); + + if (residuo <= qta_da_evadere ) + { + if (i < ndocs - 1) + qta_evasa = residuo; + riga_evasa = true; + } + rdoc.add(RDOC_QTAEVASA, qta_evasa); + evaded.add(rdoc_key); + } + rdoc.put(RDOC_RIGAEVASA, riga_evasa); + qta_da_evadere -= qta_evasa; + } + for (int i = 0; i < ndocs; i++) + if (docs[i].is_evaso()) + docs[i].stato(stato_evaso); + else + if (docs[i].stato() == stato_evaso) + docs[i].stato(stato_aperto); + docs.rewrite(); + saved.merge_token(evaded); + FOR_EACH_ARRAY_ITEM(to_delete, i, riga) + { + const int pos = saved.find(*((TToken_string *)riga)); + + if (pos >= 0) + saved.destroy(pos); + } + saved.pack(); + + TToken_string original_key; + + if (saved.items() > 0) + { + original_key = saved.row(0); + saved.destroy(0, true); + } + put(RDOC_DACODNUM, original_key.get(0)); + put(RDOC_DAANNO, original_key.get()); + put(RDOC_DAPROVV, original_key.get()); + put(RDOC_DANDOC, original_key.get()); + put(RDOC_DAIDRIGA, original_key.get()); + saved.arr2tok(original); + put(RDOC_ORIGINAL_ROWS, original); + } + } +} TRectype & TRiga_documento::operator =(const TRectype & r) { @@ -739,7 +859,7 @@ real TRiga_documento::ritenuta(const char tipor, bool lordo, int ndec) const real val; if (tipo().tipo() == RIGA_SPESEDOC) - { + { const char tipo_rit = spesa().tipo_ritenuta(); if ((tipor != '\0' && tipo_rit == tipor) || (tipor == '\0' && tipo_rit != '\0')) @@ -748,24 +868,22 @@ real TRiga_documento::ritenuta(const char tipor, bool lordo, int ndec) const if (spesa().is_percentuale() && spesa().field_perc().blank()) { real imponibile; + TDocumento & d = *_doc; + const int nrow = get_int(RDOC_NRIGA); - FOR_EACH_PHYSICAL_RDOC(doc(), r, rdoc1) - { - if (rdoc1->is_prestazione()) - { - imponibile += rdoc1->imponibile(); - } - } + FOR_EACH_PHYSICAL_RDOC(d, r1, rdoc) + if (r1 != nrow && rdoc->is_prestazione() && rdoc->spesa().tipo_ritenuta() != tipo_rit) + imponibile += rdoc->imponibile(); // Riciclo per sommare la % delle spese da sommare - FOR_EACH_PHYSICAL_RDOC(doc(), r, rdoc2) + FOR_EACH_PHYSICAL_RDOC(d, r2, rdoc) { - if (rdoc2->is_spese() && rdoc2->spesa().spe_cal_rit()) + if (r2 != nrow && rdoc->is_spese() && rdoc->spesa().spe_cal_rit()) { - if (rdoc2->spesa().is_percentuale()) - val += imponibile * rdoc2->spesa().perc() / CENTO; + if (rdoc->spesa().is_percentuale()) + val += imponibile * rdoc->spesa().perc() / CENTO; else - val = rdoc2->importo(true, lordo, ndec); + val = rdoc->importo(true, lordo, ndec); } } @@ -1446,11 +1564,16 @@ TArticolo_giacenza& TRiga_documento::articolo_giacenza() const const TToken_string & TRiga_documento::get_original_rdoc_key() const { TToken_string & key = get_tmp_string(32); + key.add(get(RDOC_DACODNUM)); - key.add(get(RDOC_DAANNO)); - key.add(get(RDOC_DAPROVV)); - key.add(get(RDOC_DANDOC)); - key.add(get(RDOC_DAIDRIGA)); + if (key.full()) + { + key.add(get(RDOC_DAANNO)); + key.add(get(RDOC_DAPROVV)); + key.add(get(RDOC_DANDOC)); + key.add(get(RDOC_DAIDRIGA)); + } + key.trim(); return key; } diff --git a/src/ve/velib03.cpp b/src/ve/velib03.cpp index 9a14e925e..ec1bf07fb 100755 --- a/src/ve/velib03.cpp +++ b/src/ve/velib03.cpp @@ -18,11 +18,24 @@ #include "veini.h" #include "velib.h" +#include "velib04.h" #include "sconti.h" #include "vepriv.h" #include "veuml.h" +static TRiga_documento * __empty_row = nullptr; + +HIDDEN TRiga_documento & empty_row(TDocumento * doc) +{ + if (__empty_row == nullptr) + __empty_row = new TRiga_documento(doc); + else + __empty_row->set_doc(doc); + return *__empty_row; +} + + /////////////////////////////////////////////////////////// // TTipo_documento_cache /////////////////////////////////////////////////////////// @@ -379,9 +392,10 @@ real TDocumento::spese_incasso(real & imp, int ndec, TTipo_importo t) const { if (ndec == AUTO_DECIMALS) ndec = decimals(); - if (spese_inc.objptr(_rim_dir) == NULL) // Inizializzo le spese d'incasso se necessario + if (spese_inc.objptr(_rim_dir) == nullptr) // 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)); @@ -862,6 +876,12 @@ void TDocumento::on_read(int err, word lockop) _old_agente = get(DOC_CODAG); _old_agente1 = get(DOC_CODAGVIS); } + _qta_evasa_auto.destroy(); + if (get(DOC_TIPODOC).full() && tipo().auto_evasione()) + { + FOR_EACH_SELF_PHYSICAL_RDOC(i, rdoc) + update_row_auto_qta(i, rdoc->quantita(), false); + } } int TDocumento::read(TBaseisamfile& f, word op, word lockop) @@ -1550,6 +1570,12 @@ int TDocumento::write_rewrite(TBaseisamfile & f, bool re) const // Aggiunte per il controllo plafond ((TDocumento &)*this).plafond().write_rewrite((TDocumento &)*this, re); + if (tipo().auto_evasione()) + { + FOR_EACH_SELF_PHYSICAL_RDOC(i, rdoc) + myself.update_row_auto_qta(i, rdoc->quantita()); + myself.auto_evasione(); + } err = TMultiple_rectype::write_rewrite(f, re); @@ -1599,7 +1625,6 @@ int TDocumento::write_rewrite(TBaseisamfile & f, bool re) const st_agg->sub(myself.row(i)); } } - #endif } return err; @@ -1610,6 +1635,8 @@ int TDocumento::remove(TBaseisamfile& f) const { if (!cancellabile() && !delete_box("Documento non cancellabile.\nSi desidera continuare ugualmente?")) return NOERR; + + TDocumento& myself = *((TDocumento *)this); const bool check_movmag = _has_mag && tipo().mov_mag(); const bool doc_bloccato = bloccato(); @@ -1650,11 +1677,10 @@ int TDocumento::remove(TBaseisamfile& f) const } #endif if (_has_provv && tipo().provvigioni()) - { - TDocumento& myself = *((TDocumento *)this); myself.update_provvigioni(true); - } - ((TDocumento &)*this).plafond().remove((TDocumento &)*this); + myself.plafond().remove(myself); + if (tipo().auto_evasione()) + myself.auto_evasione(); } return TMultiple_rectype::remove(f); } @@ -1907,19 +1933,19 @@ TRiga_documento & TDocumento::row(int index) 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"); - } + 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)); + r = &((TRiga_documento &) b.row(index, false)); } else - { + { CHECKD(index <= rows(), "Riga documento non esistente ", index); @@ -1933,16 +1959,20 @@ TRiga_documento & TDocumento::row(int index) if(index_richiesto == index_sconto) { r = _sconto; - } else if (index_richiesto == index_esenzione) - { - r = _esenzione; - } else if (index_richiesto == index_valfisc) - { - r = _valfisc; } + else + if (index_richiesto == index_esenzione) + { + r = _esenzione; + } + else + if (index_richiesto == index_valfisc) + { + r = _valfisc; + } } - if (r != NULL) + if (r != nullptr) r->set_doc(this); return *r; } @@ -2070,10 +2100,10 @@ void TDocumento::set_fields(TAuto_variable_rectype & rec) } for (TVariable_field* src_field = rec.first_variable_field(); - src_field != NULL; src_field = rec.succ_variable_field()) + src_field != nullptr; src_field = rec.succ_variable_field()) { const char* fieldname = src_field->name(); - if (src_field->expression() == NULL) + if (src_field->expression() == nullptr) put(fieldname, rec.get(fieldname)); } } @@ -2240,23 +2270,25 @@ void TDocumento::update_tabella_iva(bool solo_imponibili) 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) + FOR_EACH_SELF_PHYSICAL_RDOC(j, rdoc) { - const TRiga_documento& r = *rowptr; - if (!r.is_sconto() && !r.is_descrizione()) + if (!rdoc->is_sconto() && !rdoc->is_descrizione()) { - const TCodiceIVA & iva = r.iva(); + const TCodiceIVA & iva = rdoc->iva(); + if (iva.ok()) { const TString & cod = iva.codice(); TRiepilogo_iva* aliquota = (TRiepilogo_iva*)table.objptr(cod); - if (aliquota == NULL) + + if (aliquota == nullptr) { 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; + const real imponibile = doc_al_lordo ? rdoc->importo(true, true, ndec) : rdoc->imponibile(); + + aliquota->imp_orig() += imponibile; } } } @@ -2536,9 +2568,9 @@ real TDocumento::spese() const { real r; - FOR_EACH_PHYSICAL_RDOC(*this, i, rdoc) - if (rdoc->is_spese()) - r += rdoc->imponibile(); + FOR_EACH_SELF_PHYSICAL_RDOC(i, rdoc) + if (rdoc->is_spese()) + r += rdoc->imponibile(); return r; } } @@ -2554,7 +2586,7 @@ real TDocumento::spese(const TString & tipo_spesa) const { real r; - FOR_EACH_PHYSICAL_RDOC(*this, i, rdoc) + FOR_EACH_SELF_PHYSICAL_RDOC(i, rdoc) if (rdoc->is_spese()) { const TSpesa_prest s(rdoc->get(RDOC_CODART)); @@ -2635,11 +2667,12 @@ real TDocumento::provvigione(bool first, int ndec) const real TDocumento::valore(bool totale, bool lordo, int ndec) const { real val; - TDocumento& doc = *(TDocumento*)this; - FOR_EACH_PHYSICAL_RDOC_BACK(doc, i, r) + + FOR_EACH_SELF_PHYSICAL_RDOC_BACK(i, r) { const char t = r->tipo().tipo(); - if (strchr("MSPRA", t) != NULL) // Merce, Spese, Prestazioni, Risorse, Attrezzature + + if (strchr("MSPRA", t) != nullptr) // Merce, Spese, Prestazioni, Risorse, Attrezzature val += r->valore(totale, lordo, ndec); } return val; @@ -2711,14 +2744,14 @@ const real TDocumento::importo_plafond() const { real importo_plafond; - FOR_EACH_PHYSICAL_RDOC(*this, r, row) + FOR_EACH_SELF_PHYSICAL_RDOC( r, rdoc) // Se l'iva del documento è diversa non mi interessa - if (!row->is_descrizione() && !row->is_descrizione()) + if (!rdoc->is_descrizione() && !rdoc->is_descrizione()) { - const TString & codiva = row->iva().codice(); + const TString & codiva = rdoc->iva().codice(); if (codiva.full() && check_iva_plafond(codiva)) - importo_plafond += row->imponibile(); + importo_plafond += rdoc->imponibile(); } if (is_nota_credito()) importo_plafond = -importo_plafond; @@ -2786,6 +2819,7 @@ 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); @@ -3043,26 +3077,27 @@ void TDocumento::update_conai_qta() { _conaiqta.destroy(); - FOR_EACH_PHYSICAL_RDOC(*this, i, r) if (r->is_merce() || r->is_omaggio()) - { - TString current_cat; + FOR_EACH_SELF_PHYSICAL_RDOC(i, r) + if (r->is_merce() || r->is_omaggio()) + { + TString current_cat; - for (int i = 1; i <= FR_CMAX; i++) - { - TString8 cat = r->get(conai_sottocat_name(i)); + for (int i = 1; i <= FR_CMAX; i++) + { + TString8 cat = r->get(conai_sottocat_name(i)); - if (cat.full()) - { - const real rowqty = r->calc_conai_qta(i); + if (cat.full()) + { + const real rowqty = r->calc_conai_qta(i); - real * q = (real *) _conaiqta.objptr(cat); + real * q = (real *) _conaiqta.objptr(cat); - if (q == NULL) - _conaiqta.add(cat, q = new real); - *q += rowqty; - } - } - } + if (q == NULL) + _conaiqta.add(cat, q = new real); + *q += rowqty; + } + } + } } const char* get_cf_esenz(const TString& tipo_conai) @@ -3246,6 +3281,7 @@ bool TDocumento::is_evaso() const for (int r = 1; ok && r <= physical_rows(); r++) { const TRiga_documento& riga = physical_row(r); + if (riga.is_evadibile()) ok = riga.is_evasa(); } @@ -3290,6 +3326,14 @@ TCurrency_documento::TCurrency_documento(const real& num, const TDocumento & doc set_num(num); } +TRiga_documento * TDocumento::rowptr(int index) +{ + if (index > 0 && index <= rows()) + return &row(index); + else + return nullptr; +} + int TDocumento::set_row_ids() { const int phrw = physical_rows(); @@ -3322,13 +3366,12 @@ int TDocumento::set_row_ids() const TRiga_documento* TDocumento::get_row_id(long id) const { - TDocumento& doc = *(TDocumento*)this; - FOR_EACH_PHYSICAL_RDOC_BACK(doc, r, row) + FOR_EACH_SELF_PHYSICAL_RDOC_BACK(r, rdoc) { - if (row->get_long(RDOC_IDRIGA) == id) - return row; + if (rdoc->get_long(RDOC_IDRIGA) == id) + return rdoc; } - return NULL; + return nullptr; } int TDocumento::id2rownum(long id) const @@ -3504,3 +3547,47 @@ void TDocumento::cli2doc() put(DOC_CODPORTO, v.get(CFV_CODPORTO)); } +void TDocumento::update_row_auto_qta(int nrow, real & qta, bool plus) +{ + real * qta_evasa = (real *)_qta_evasa_auto.objptr(nrow); + + if (qta_evasa == nullptr) + _qta_evasa_auto.add(qta_evasa = new real, nrow); + *qta_evasa += (plus ? qta : -qta); + if (*qta_evasa == ZERO) + _qta_evasa_auto.destroy(nrow); +} + +void TDocumento::auto_evasione() +{ +// TLista_documenti docs; + TConsegna_ordini e(tipo().auto_evasione_elab()); + const char stato_evaso = e.cstato_finale_doc_iniziale(); + const char stato_aperto = e.stato_iniziale(0); + TToken_string tipi; + TToken_string stati; + + e.tipi_stati_iniziali(tipi, stati); + FOR_EACH_SELF_PHYSICAL_RDOC(i, rdoc) + if (rdoc->is_evadibile() && _qta_evasa_auto.objptr(i) != nullptr) + rdoc->update_orders((real &)_qta_evasa_auto[i], tipi, stati, stato_aperto, stato_evaso); +} + +int TDocumento::find_nrow(const char * tiporiga, const char * codice) const +{ + FOR_EACH_SELF_RDOC(i, rdoc) + if ((rdoc->tipo().codice() == tiporiga) && (rdoc->codice() == codice)) + return i; + return -1; +} + +TRiga_documento & TDocumento::find_row(const char * tiporiga, const char * codice) +{ + const int i = find_nrow(tiporiga, codice); + + if (i > 0) + return row(i); + else + return empty_row(this); +} + diff --git a/src/ve/velib04.cpp b/src/ve/velib04.cpp index e2e34ac8e..7b203b625 100755 --- a/src/ve/velib04.cpp +++ b/src/ve/velib04.cpp @@ -20,26 +20,35 @@ TDate TLista_documenti::num2date(char provv, int anno, const char* codnum, long return doc.get_date(DOC_DATADOC); } -bool TLista_documenti::find(char provv, int anno, const char* codnum, long ndoc) const +int TLista_documenti::find(char provv, int anno, const char* codnum, long ndoc) const { - bool found = false; - const int it = items(); - if (ndoc > 0 && it > 0) - { - for (int i = 0; !found && i < it; i++) - { - const TRectype& head = doc(i).head(); - found = (head.get_long(DOC_NDOC) == ndoc) && - (head.get_char(DOC_PROVV) == provv) && - (head.get_int(DOC_ANNO) == anno) && - (head.get(DOC_CODNUM) == codnum); - } - } - return found; + if (ndoc > 0 && it > 0) + { + for (int i = 0; i < it; i++) + { + const TRectype& head = doc(i).head(); + + if ((head.get_long(DOC_NDOC) == ndoc) && + (head.get_char(DOC_PROVV) == provv) && + (head.get_int(DOC_ANNO) == anno) && + (head.get(DOC_CODNUM) == codnum)) + return i; + } + } + return -1; } +int TLista_documenti::find(const TDocumento & doc) const +{ + const char provv = doc.get_char(DOC_PROVV); + const int anno = doc.get_int(DOC_ANNO); + const TString& codnum = doc.get(DOC_CODNUM); + const long ndoc = doc.get_long(DOC_NDOC); + + return find(provv, anno, codnum, ndoc); +} int TLista_documenti::read(char provv, char tipocf, long clifo, int anno, TToken_string& tipidoc, TToken_string& statidoc, const TDate& dd, const TDate& ad, @@ -207,13 +216,46 @@ static int doc_cmp(const TSortable& o1, const TSortable& o2, void* jolly) return cmp; } +int TLista_documenti::add(const TLista_documenti & docs, const bool no_dups) +{ + const int ndocs = docs.items(); + + for (int i = 0; i < ndocs; i++) + if (!no_dups || !exist(docs[i].get_char(DOC_PROVV), docs[i].anno(), docs[i].codice_numerazione().codice(), docs[i].numero())) + add(docs[i]); + return items(); +} + int TLista_documenti::sort(const char* fields) { TToken_string orderby = fields; + + if (orderby.blank()) + { + orderby.add(DOC_PROVV); + orderby.add(DOC_ANNO); + orderby.add(DOC_CODNUM); + orderby.add(DOC_NDOC); + } _documenti.sort(doc_cmp, &orderby); return items(); } +const TLista_documenti & TLista_documenti::merge(const TLista_documenti & d) +{ + const int ndocs = d.items(); + + for (int i = 0; i < ndocs; i++) + { + const TDocumento & doc = d[i]; + + if (find(doc) == -1) + add(doc); + } + sort(); + return *this; +} + /////////////////////////////////////////////////////////// // TLista_clifo /////////////////////////////////////////////////////////// diff --git a/src/ve/velib04.h b/src/ve/velib04.h index aee4f8a89..540747e82 100755 --- a/src/ve/velib04.h +++ b/src/ve/velib04.h @@ -22,23 +22,29 @@ protected: TDate num2date(char provv, int anno, const char* codnum, long num) const; public: - bool find(char provv, int anno, const char * codnum, long ndoc) const; - int read(char provv, char tipo, long clifo, int anno, + int find(char provv, int anno, const char * codnum, long ndoc) const; + int find(const TDocumento & doc) const; + bool exist(char provv, int anno, const char * codnum, long ndoc) const { return find(provv, anno,codnum, ndoc) > 0; } + int read(char provv, char tipo, long clifo, int anno, TToken_string& tipidoc, TToken_string& statidoc, - const TDate& dd, const TDate& ad, + const TDate& dd = nulldate, const TDate& ad = nulldate, const char* codnum = "", long dn = 0L, long an = 0L); int write(bool re = false) const; int rewrite() const { return write(true); } int add(TDocumento* doc) { return _documenti.add(doc); } int add(const TDocumento& doc) { return _documenti.add(doc); } + int add(const TLista_documenti & docs, const bool no_dups = true); int destroy(int i, bool pack = true) { return _documenti.destroy(i, pack); } + void pack() { _documenti.pack();} + const TLista_documenti & merge(const TLista_documenti & d); + TDocumento * objptr(int n) const { return (TDocumento *)_documenti.objptr(n); } const TDocumento& operator[] (int n) const { return doc(n); } TDocumento& operator[] (int n) { return (TDocumento&)_documenti[n]; } int items() const { return _documenti.items(); } - int sort(const char* fields); // token string of field names + int sort(const char* fields = ""); // token string of field names TLista_documenti() { } virtual ~TLista_documenti() {}; @@ -201,7 +207,8 @@ public: const TString& tipo_finale() const { return get("S8"); } const TString& stato_finale_doc_iniziale() const { return get("S4"); } const TString& stato_finale() const { return get("S9"); } - + const char cstato_finale_doc_iniziale() const { return get_char("S4"); } + const char cstato_finale() const { return get_char("S9"); } const TString& codice_numerazione_finale() const { return get("S6"); } const TString& applicazione_esterna() const { return get("S3"); } void set_params(const TParametri_elaborazione& parms) { _parms = parms;} diff --git a/src/ve/vetbtip.uml b/src/ve/vetbtip.uml index 110c44d79..57f20fa47 100755 --- a/src/ve/vetbtip.uml +++ b/src/ve/vetbtip.uml @@ -1449,6 +1449,25 @@ BEGIN ITEM "2|Nessuno" END +BOOLEAN F_AUTOCLOSE +BEGIN + PROMPT 2 20 "Chiusura automatica documenti" + MESSAGE FALSE CLEAR,F_AUTOELAB + MESSAGE TRUE ENABLE,F_AUTOELAB + FIELD B15 +END + +STRING F_AUTOELAB 4 +BEGIN + PROMPT 2 22 "Elaborazione di chiusura automatica " + FIELD S12 + USE %ELD SELECT I0=1 + INPUT CODTAB F_AUTOELAB + DISPLAY "Codice@10" CODTAB + DISPLAY "Descrizione@50" S0 + DISPLAY "Tipo" I0 + OUTPUT F_AUTOELAB CODTAB +END ENDPAGE ENDMASK