diff --git a/ve/velib.h b/ve/velib.h index 4e85fa4bc..f4e692126 100755 --- a/ve/velib.h +++ b/ve/velib.h @@ -121,24 +121,24 @@ public: public: int read(const char* codice); - const TString& codice() const { return get("CODTAB");} + const TString& codice() const { return get("CODTAB"); } + char tipo() const { return get_char("S6"); } const TString& descrizione() const { return get("S0"); } - const TString& field_perc() const { return get("S5"); } // Solo spese - const TString& revenue() const { return get("S5"); } // Solo atrezzature - const TString & um() const { return get("S7"); } + const TString& field_perc() const { return get("S5"); } // Solo spese + const TString& revenue() const { return get("S5"); } // Solo attrezzature e risorse + const TString& um() const { return get("S7"); } const TString& cod_iva() const; // S3 real prezzo() const; // R10 o R0 real qta() const { return get_real("R1"); } real perc() const { return get_real("R2"); } - char tipo() const { return get_char("S6"); } char tipo_ritenuta() const { return get_char("S9"); } - const TString & tipo_riga() const { return get("S8"); } + 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 & 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); } + const TString& conto_analitico_vendite() const { return get("S1").left(20); } + const TString& conto_analitico_acquisti() const { return 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); } const int caus_770() const { return get_int("I6"); } TSpesa_prest(const char* codice = NULL, char tipo = 'S'); @@ -190,7 +190,7 @@ protected: public: TObject* dup() const { return new TFormula_documento(_tab == "%FRD" ? _documento : _riga, codice(), NULL, true); } const TString& codice() const { return get("CODTAB");} - const TString& name() const { return codice();} + const TString& name() const { return codice(); } TExpr_documento* expr() const { return _expr;} const TString& descrizione() const { return get("S0"); } @@ -266,13 +266,13 @@ public: const char * field_prezzo() const { return _field_prezzo; } const TString& field_qta() const { return _field_qta; } const TString& field_qtaevasa() const { return _field_qtaevasa; } - const TString& field_qta_mag() const { return _field_qta_mag; } - const TString& field_qtaevasa_mag() const { return _field_qtaevasa_mag; } + const TString& field_qta_mag() const { return _field_qta_mag; } + const TString& field_qtaevasa_mag() const { return _field_qtaevasa_mag; } bool check_giac() const { return _check_qta == 'G'; } bool check_disp() const { return _check_qta == 'D'; } - bool load_cont() const { return _load_cont; } - const TString& raee_cod() const { return _raee_cod; } - const TString& raee_fld() const { return _raee_fld; } + bool load_cont() const { return _load_cont; } + const TString& raee_cod() const { return _raee_cod; } + const TString& raee_fld() const { return _raee_fld; } const TString & descrizione() const { return get("S0"); } const TString & riferimento(const TDocumento& doc, TString& rif) const; @@ -574,7 +574,7 @@ public: virtual TRectype& operator =(const TRectype & r); virtual TRectype& operator =(const char * r); - void cost2revenue(); + bool cost2revenue(); bool raggruppabile(const TRiga_documento& r, TToken_string& campi) const; TRiga_documento& operator +=(const TRiga_documento& r); @@ -854,6 +854,12 @@ public: virtual ~TDocumento(); }; +#define FOR_EACH_PHYSICAL_RDOC(__doc, __rdoc) TRiga_documento* __rdoc=NULL; TRecord_array& __b = (__doc).body(); \ + for (int __r = __b.first_row(); __b.exist(__r) && (__rdoc=&(__doc)[__r])!=NULL; __r=__b.succ_row(__r)) +#define FOR_EACH_PHYSICAL_RDOC_BACK(__doc, __rdoc) TRiga_documento* __rdoc=NULL; TRecord_array& __b = (__doc).body(); \ + for (int __r = __b.last_row(); __r>0 && (__rdoc=&(__doc)[__r])!= NULL; __r = __b.pred_row(__r)) + + class TCurrency_documento : public TCurrency { protected: diff --git a/ve/velib02.cpp b/ve/velib02.cpp index 9e47f39d6..055f6797b 100755 --- a/ve/velib02.cpp +++ b/ve/velib02.cpp @@ -337,33 +337,55 @@ TRectype & TRiga_documento::operator =(const char * r) return *this; } -void TRiga_documento::cost2revenue() +bool TRiga_documento::cost2revenue() { + bool done = false; if (is_attrezzatura() || is_risorsa()) { - const TSpesa_prest & s = spesa(); - const TString codice(s.revenue()); - - if (codice.not_empty()) + const TSpesa_prest& s = spesa(); + const TString80 codice(s.revenue()); + done = codice.full(); + if (done) { - const TString4 tipo(s.tipo()); - if (tipo.not_empty()) - put(RDOC_TIPORIGA, tipo); - put(RDOC_TIPORIGA, codice); + TString4 tipo = s.tipo(); + if (tipo.blank()) tipo = "06"; + put(RDOC_TIPORIGA, tipo); + put(RDOC_CODART, codice); + zero(RDOC_CODARTMAG); + put(RDOC_CHECKED, true); + put(RDOC_DESCR, s.descrizione()); + put(RDOC_UMQTA, s.um()); + put(RDOC_PREZZO, s.prezzo()); + if (get(RDOC_CODIVA).blank()) + put(RDOC_CODIVA, s.cod_iva()); } } + return done; } // Ritorna TRUE se le due righe del documento possono essere sommate bool TRiga_documento::raggruppabile(const TRiga_documento& r, TToken_string& campi) const -{ - bool ok = field_qta() == r.field_qta() && field_qtaevasa() == r.field_qtaevasa(); +{ + // Controlla che i nomi dei campi quantita' siano coerenti + bool ok = (tipo().codice() == r.tipo().codice()) || + (field_qta() == r.field_qta() && field_qtaevasa() == r.field_qtaevasa()); - for (const char* c = campi.get(0); c && ok; c = campi.get()) + if (ok) { - const TString & campo = get(c); // Separare le due get! - ok &= campo == r.get(c); - } + TString campo1, campo2; + FOR_EACH_TOKEN(campi, c) + { + campo1 = get(c); + if (campo1.empty() && doc().exist(c)) // Succede con COMMESSA, FASE, CODCOSTO + campo1 = doc().get(c); + campo2 = r.get(c); + if (campo2.empty() && r.doc().exist(c)) // Succede con COMMESSA, FASE, CODCOSTO + campo2 = r.doc().get(c); + ok = campo1 == campo2; + if (!ok) + break; + } + } return ok; } @@ -1464,26 +1486,20 @@ void TTipo_riga_documento::set_defaults(TSheet_field& s, int row) const } } // Setta i campi della maschera - TToken_string & r = s.row(row - 1); + TToken_string& r = s.row(row - 1); FOR_EACH_ARRAY_ROW(_defaults, i, tt) - { r.add(*tt, s.cid2index(i)); - } } bool TRiga_documento::edit(int logicnum, const char* alternate_key_fields, const char* hint) const { - TString app; - TString4 module = doc().tipo().module(); - - module.upper(); - if (module == "CO") - app = "co0 -6"; - else - if (module == "LV") - app = "lv3 -0"; - else - if (module == "PE") - app = "pe0 -3"; + const char* app = NULL; + const TString& module = doc().tipo().module(); + if (module.compare("CO", -1, true) == 0) + app = "co0 -6"; else + if (module.compare("LV", -1, true) == 0) + app = "lv3 -0"; else + if (module.compare("PE", -1, true) == 0) + app = "pe0 -3"; return TRectype::edit(logicnum, alternate_key_fields, app); } diff --git a/ve/velib03.cpp b/ve/velib03.cpp index 3aa79c954..4930513e5 100755 --- a/ve/velib03.cpp +++ b/ve/velib03.cpp @@ -953,18 +953,30 @@ 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; + TRiga_documento* row0 = (TRiga_documento*)*r0; + TRiga_documento* row1 = (TRiga_documento*)*r1; int res = 0; - TToken_string & key = * __key; - TString val0, val1; - FOR_EACH_TOKEN(key, fldname) + TString val0, val1; + TToken_string valist(50,','); + + FOR_EACH_STR_TOKEN(*__key, fldname) { - const int reverse = *fldname == '-' ? -1 : 1; - - if (reverse < 0) - 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); @@ -981,7 +993,7 @@ HIDDEN int sort_doc_rows(const TObject** r0, const TObject** r1) const real r1 = val1; if (r0 != r1) - res = (r0 < r1 ? -1 : 1) * reverse; + res = (r0 < r1 ? -1 : 1) * direction; } break; case _datefld : @@ -990,12 +1002,21 @@ HIDDEN int sort_doc_rows(const TObject** r0, const TObject** r1) const TDate d1 = val1; if (d0 != d1) - res = (d0 < d1 ? -1 : 1) * reverse; + res = (d0 < d1 ? -1 : 1) * direction; } break; default: if (val0 != val1) - res = xvt_str_compare_ignoring_case(val0, val1) * reverse; + { + 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) @@ -1004,7 +1025,7 @@ HIDDEN int sort_doc_rows(const TObject** r0, const TObject** r1) return res; } -void TDocumento::sort_rows(const char * key) +void TDocumento::sort_rows(const char* key) { __key = new TToken_string(key); body().sort(sort_doc_rows); diff --git a/ve/velib03a.cpp b/ve/velib03a.cpp index 9656b3562..6800a9471 100755 --- a/ve/velib03a.cpp +++ b/ve/velib03a.cpp @@ -186,8 +186,7 @@ const TString_array& TTipo_documento::keys_descrs() const { if (_keys_descrs.empty()) { - TFilename pn; - profile_name(pn); + TFilename pn; profile_name(pn); TConfig prof(pn, "RIGHE"); TTipo_riga_documento tr; TToken_string k, d; @@ -195,7 +194,6 @@ const TString_array& TTipo_documento::keys_descrs() const for (int i = 0; ; i++) { const TString& tiporiga = prof.get("Tipo", NULL, i); - if (tiporiga.full()) { tr.read(tiporiga); diff --git a/ve/velib04.h b/ve/velib04.h index 29d3f3ca1..0750cdd74 100755 --- a/ve/velib04.h +++ b/ve/velib04.h @@ -241,9 +241,8 @@ public: class TFatturazione_bolle : public TElaborazione // velib04a { - TToken_string _cod_desc; + TToken_string _cod_desc, _lista_campi, _rowsort; bool _cambia_codice; - TToken_string _lista_campi; protected: virtual void campi_raggruppamento_righe(TToken_string& campi_riga) const; diff --git a/ve/velib04a.cpp b/ve/velib04a.cpp index b79edd53e..b655d6a44 100755 --- a/ve/velib04a.cpp +++ b/ve/velib04a.cpp @@ -10,10 +10,11 @@ TFatturazione_bolle::TFatturazione_bolle(const char* cod) : TElaborazione(cod) { - TConfig c(CONFIG_DITTA, "ve"); TString16 name; name.format("AGGFLD(%s)", cod); + _lista_campi = ini_get_string(CONFIG_DITTA, "ve", name); - _lista_campi = c.get(name); + name.format("ROWSORT(%s)", cod); + _rowsort = ini_get_string(CONFIG_DITTA, "ve", name); } void TFatturazione_bolle::tipi_validi(TToken_string& tipi) const @@ -23,7 +24,7 @@ void TFatturazione_bolle::tipi_validi(TToken_string& tipi) const for (int i = 0; i < TElaborazione::_max_tipi_doc_elab; i++) { t = tipo_iniziale(i); - if (t.not_empty()) + if (t.full()) tipi.add(t); } CHECK(!tipi.empty_items(), "Nessun tipo documento valido"); @@ -44,10 +45,9 @@ void TFatturazione_bolle::stati_validi(TToken_string& stati) const void TFatturazione_bolle::campi_raggruppamento_righe(TToken_string& campi_riga) const { const bool ragg_rig = raggruppa_righe(); - if (ragg_rig) { - campi_riga = "CODART|UMQTA"; // Uguali sempre + campi_riga = RDOC_CODART"|"RDOC_UMQTA; // Uguali sempre // Uguali se commesse attive if (dongle().active(CAAUT) || dongle().active(CMAUT)) { @@ -56,22 +56,23 @@ void TFatturazione_bolle::campi_raggruppamento_righe(TToken_string& campi_riga) campi_riga.add(RDOC_CODCOSTO); } // Uguali opzionalmente - if (riga_uguale(0)) campi_riga.add("CODMAG"); - if (riga_uguale(1)) campi_riga.add("CODIVA"); - if (riga_uguale(2)) campi_riga.add("PREZZO|SCONTO"); - + if (riga_uguale(0)) campi_riga.add(RDOC_CODMAG); + if (riga_uguale(1)) campi_riga.add(RDOC_CODIVA); + if (riga_uguale(2)) campi_riga.add(RDOC_PREZZO"|"RDOC_SCONTO); } + else + campi_riga.cut(0); } void TFatturazione_bolle::campi_raggruppamento(TToken_string& campi) const { - campi = "TIPOCF|CODCF|CODVAL|CODLIN"; // Uguali sempre + campi = DOC_TIPOCF"|"DOC_CODCF"|"DOC_CODVAL"|"DOC_CODLIN; // Uguali sempre // Uguali opzionalmente - const char* cond[] = { "CAMBIO", "SCONTO", "TIPODOC", "CODNUM", - "CODPAG", "CODABIA|CODCABA", "CODLIST", "CODAG|CODAGVIS", - "CODSPMEZZO", "CODPORTO", "CAUSTRASP", "CODVETT1|CODVETT2|CODVETT3", - "CODINDSP", "CODCMS", + const char* cond[] = { DOC_CAMBIO, "SCONTO", DOC_TIPODOC, DOC_CODNUM, + DOC_CODPAG, DOC_CODABIA"|"DOC_CODCABA, DOC_CODLIST, DOC_CODAG"|"DOC_CODAGVIS, + DOC_CODSPMEZZO, DOC_CODPORTO, DOC_CAUSTRASP, DOC_CODVETT1"|"DOC_CODVETT2"|"DOC_CODVETT3, + DOC_CODINDSP, DOC_CODCMS, NULL }; for (int u = 0; cond[u]; u++) @@ -120,27 +121,13 @@ void TFatturazione_bolle::create_row(TDocumento& doc_out, const TRiga_documento& void TFatturazione_bolle::elabora_riga(TRiga_documento& r, TDocumento& doc_out, bool usa_dcons, bool ragg_rig, bool ignora_desc, TToken_string & campi_riga, const TDate & dcons, const TDate & ddoc) { - TRiga_documento rin(r); - - const bool rindesc = rin.sola_descrizione(); // La riga di input e' descrittiva + const bool rindesc = r.sola_descrizione(); // La riga di input e' descrittiva if (ignora_desc && rindesc) return; - if (rin.is_attrezzatura() || rin.is_risorsa()) - { - const TSpesa_prest & risatt = rin.spesa(); - const TString codprest(risatt.revenue()); - if ( codprest.full()) - { - const TSpesa_prest prest(codprest, RIGA_PRESTAZIONI); - rin.put(RDOC_TIPORIGA, "06"); - rin.put(RDOC_CODART, prest.codice()); - rin.put(RDOC_DESCR, prest.descrizione()); - rin.put(RDOC_UMQTA, prest.um()); - rin.put(RDOC_PREZZO, prest.prezzo()); - rin.put(RDOC_CODIVA, prest.cod_iva()); - } - } + TRiga_documento rin(r); + if (rin.is_attrezzatura() || rin.is_risorsa()) + rin.cost2revenue(); if (usa_dcons) { @@ -160,26 +147,23 @@ void TFatturazione_bolle::elabora_riga(TRiga_documento& r, TDocumento& doc_out, // Raggruppo le righe se e' settato il flag di raggruppamento e // se la riga non contiene solo una descrizione - if (ragg_rig && !rindesc) // Se devo raggruppare le righe ... + if (ragg_rig && !rindesc && da_raggruppare(rin)) // Se devo raggruppare le righe ... { - const int last = doc_out.physical_rows(); - for (int o = 1; o <= last; o++) // ... cerca una riga compatibile + FOR_EACH_PHYSICAL_RDOC(doc_out, rout) // ... cerca una riga compatibile { - TRiga_documento& rout = doc_out[o]; - if (rout.sola_descrizione()) // Ignora le righe descrittive + if (rout->sola_descrizione()) // Ignora le righe descrittive continue; - if (da_raggruppare(rin) && rin.raggruppabile(rout, campi_riga)) // Se esiste una riga compatibile ... + if (rin.raggruppabile(*rout, campi_riga)) // Se esiste una riga compatibile ... { - add_rows(rout, rin); - elaborata = true; // Ricorda di averla gia' elaborata + add_rows(*rout, rin); + elaborata = true; // Ricorda di averla gia' elaborata break; } } } - if (!elaborata) // Se la riga non e' stata gia' sommata ... + if (!elaborata) // Se la riga non e' stata gia' sommata ... create_row(doc_out, rin); - } bool TFatturazione_bolle::raggruppa(TDocumento& doc_in, TDocumento& doc_out) @@ -208,11 +192,9 @@ bool TFatturazione_bolle::raggruppa(TDocumento& doc_in, TDocumento& doc_out) if (usa_dcons) { bool da_elaborare = FALSE; - for (int r = 1; !da_elaborare && r <= doc_in.physical_rows(); r++) + FOR_EACH_PHYSICAL_RDOC(doc_in, rin) { - const TRiga_documento* rin = &doc_in[r]; TDate data_cons = rin->get_date(RDOC_DATACONS); - if (!data_cons.ok()) data_cons = dcons; da_elaborare = ddoc >= data_cons && !rin->get_bool(RDOC_RIGAEVASA); @@ -332,9 +314,7 @@ bool TFatturazione_bolle::raggruppa(TDocumento& doc_in, TDocumento& doc_out) const bool ignora_desc = ignora_descrizioni(); TToken_string campi_riga(80); - campi_raggruppamento_righe(campi_riga); - const bool ragg_rig = campi_riga.full(); for (int r = 1; r <= doc_in.physical_rows(); r++) @@ -549,35 +529,36 @@ bool TFatturazione_bolle::elabora(TLista_documenti& doc_in, TLista_documenti& do for (int i = 0; i < tot; i++) // Forza tipo e numerazione documento. { - TDocumento & d = doc_out[i]; + TDocumento& d = doc_out[i]; d.put(DOC_CODNUM, codnum); TToken_string key; key.add(d.get(DOC_TIPOCF)); key.add(d.get(DOC_CODCF)); const TRectype & cfven = cache().get(LF_CFVEN, key); const TString4 tipo_cli(cfven.get(CFV_TIPODOCFAT)); - const TString & tipo_out = get_tipo_out(d); // Tipo del documento di output + const TString& tipo_out = get_tipo_out(d); // Tipo del documento di output TRecfield td(d, DOC_TIPODOC); // Uso il TRecfield per scavalcare tutti gli automatismi td = tipo_cli.empty() ? tipo_out : tipo_cli; const TString& sconto = d.get(DOC_SCONTOPERC); d.put(DOC_SCONTOPERC, sconto); if (change_clifo()) { - const TString8 tipodoc(d.tipo().codice()); + const TString4 tipodoc(d.tipo().codice()); TDocumento_mask m(tipodoc); if (reload_prices()) { - const int rows = d.physical_rows(); - - for (int i = 1; i <= rows;i++) - d[i].zero(RDOC_CHECKED); + FOR_EACH_PHYSICAL_RDOC_BACK(d, r) + r->zero(RDOC_CHECKED); } m.doc() = d; m.doc2mask(true, true); m.mask2doc(); d = m.doc(); } + + if (_rowsort.full()) + d.sort_rows(_rowsort); } post_process_output(doc_out); return tot > 0;