diff --git a/ve/ve1.cpp b/ve/ve1.cpp index 78db953ec..a2b8a7c35 100755 --- a/ve/ve1.cpp +++ b/ve/ve1.cpp @@ -11,6 +11,7 @@ int main(int argc, char **argv) case 2 : ve1300(argc, argv); break; //stampa report documenti 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 } return 0; diff --git a/ve/ve1.h b/ve/ve1.h index 8dc030e2e..109a2dd34 100755 --- a/ve/ve1.h +++ b/ve/ve1.h @@ -6,6 +6,7 @@ int ve1200(int argc, char* argv[]); int ve1300(int argc, char* argv[]); int ve1400(int argc, char* argv[]); int ve1500(int argc, char* argv[]); +int ve1600(int argc, char* argv[]); #endif // __VE1_H diff --git a/ve/ve1600.cpp b/ve/ve1600.cpp new file mode 100644 index 000000000..7ed9b8c90 --- /dev/null +++ b/ve/ve1600.cpp @@ -0,0 +1,404 @@ +#include +#include +#include +#include + +#include "velib04.h" + +#include "ve1.h" +#include "ve1600a.h" + +//////////////////////////////////////////////////////// +// MASCHERA +//////////////////////////////////////////////////////// + +static TAssoc_array _tipi_doc; +static TString_array _cod_nums; +static char _stato_finale = 'Z'; + +class TStampa_bolfat_mask : public TAutomask +{ + static bool codnum_filter(const TRelation* rel); + +protected: + virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); + +public: + const TString_array& numerazioni() const { return _cod_nums; } + TStampa_bolfat_mask(); +}; + +bool TStampa_bolfat_mask::codnum_filter(const TRelation* rel) +{ + const TString& codnum = rel->curr().get("CODTAB"); + return _cod_nums.find(codnum) >= 0; +} + +bool TStampa_bolfat_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) +{ + switch (o.dlg()) + { + case F_DATAINIZIO: + case F_DATAFINE: + if ((e == fe_modify || e == fe_close) && !o.empty()) + { + const TDate d = o.get(); + const int anno = get_int(F_ANNO); + if (d.year() != anno) + return error_box(FR("La data deve appartenere all'anno %d"), anno); + } + break; + case F_NUMERAZIONE: + if (e == fe_init) + { + TEdit_field& e = (TEdit_field&)o; + e.browse()->cursor()->set_filterfunction(codnum_filter); + } + if ((e == fe_modify || e == fe_close) && !o.empty()) + { + if (_cod_nums.find(o.get()) < 0) + return error_box(TR("Numerazione non valida per le bolle")); + } + break; + case F_DESCNUM: + if (e == fe_init) + { + TEdit_field& e = (TEdit_field&)o; + e.browse()->cursor()->set_filterfunction(codnum_filter); + } + default: break; + } + return true; +} + +TStampa_bolfat_mask::TStampa_bolfat_mask() : TAutomask("ve1600a") +{ + _tipi_doc.destroy(); + _cod_nums.destroy(); + _stato_finale = 'Z'; + + //giro sulle elaborazioni + TISAM_recordset eld("USE %ELD"); + for (bool ok = eld.move_first(); ok; ok = eld.move_next()) + { + const TElaborazione e(eld.cursor()->curr()); + if (e.tipo() == _fatturazione_bolle) + { + const TString& codnumfat = e.codice_numerazione_finale(); + const TCodice_numerazione n(codnumfat); + if (n.get_int("I1") == 2) // Genera vere fatture + { + TToken_string tipi, stati; + e.tipi_stati_iniziali(tipi, stati); + if (!tipi.empty_items()) + { + const char sfdi = e.stato_finale_doc_iniziale()[0]; + if (sfdi < _stato_finale) + _stato_finale = sfdi; + FOR_EACH_TOKEN(tipi, t) + _tipi_doc.add(t); + } + } + } + } + + //giro sulle numerazioni + TISAM_recordset num("USE %NUM"); + for (bool ok = num.move_first(); ok; ok = num.move_next()) + { + const TString4 codnum = num.get("CODTAB").as_string(); + const TCodice_numerazione n(codnum); + for (int i = n.ntipi_doc()-1; i >= 0; i--) + { + const TString& td = n.tipo_doc(i); + if (_tipi_doc.is_key(td)) + { + _cod_nums.add(codnum); + break; + } + } + } +} + +/////////////////////////////////////////////////////////////// +// RECORDSET +/////////////////////////////////////////////////////////////// + +class TDocache : public TRecord_cache +{ +protected: + virtual TObject* rec2obj(const TRectype& rec) const { return new TDocumento(rec); } + +public: + TDocumento& doc(const char* key) { return (TDocumento&)query(key); } + TDocache(); +}; + +TDocache::TDocache() : TRecord_cache(LF_DOC, 1) +{ + test_file_changes(); // Tieni d'occhio le modifiche sul file + set_items_limit(64); +} + + +class TStampa_bolfat_recordset : public TRecordset +{ + TDocache _doc; + TRecnotype _pos; + TString_array _bolle; + +protected: + virtual void requery() { } + virtual const TString& query_text() const { return EMPTY_STRING; } + virtual const TRecordset_column_info& column_info(unsigned int column) const; + virtual const TVariant& get(unsigned int column) const; + virtual TRecnotype current_row() const { return _pos; } + virtual TRecnotype items() const { return _bolle.items(); } + virtual bool move_to(TRecnotype pos); + virtual unsigned int columns() const; + virtual const TVariant& get(const char* column_name) const; + +public: + void add(const TRectype& rbol, const char* message); + TStampa_bolfat_recordset() { } +}; + +bool TStampa_bolfat_recordset::move_to(TRecnotype pos) +{ + const bool ok = pos >= 0 && pos < items(); + if (ok) + _pos = pos; + return ok; +} + +unsigned int TStampa_bolfat_recordset::columns() const +{ return 6; } + +const TRecordset_column_info& TStampa_bolfat_recordset::column_info(unsigned int column) const +{ + static TRecordset_column_info _info; + + _info._pos = column; + _info._type = _alfafld; + switch (column) + { + case 0: _info._name = RDOC_PROVV; _info._width = 1; break; + case 1: _info._name = RDOC_ANNO; _info._width = 4; _info._type = _realfld; break; + case 2: _info._name = RDOC_CODNUM; _info._width = 4; break; + case 3: _info._name = RDOC_NDOC; _info._width = 6; _info._type = _realfld; break; break; + case 4: _info._name = RDOC_NRIGA; _info._width = 4; _info._type = _realfld; break; break; + default: _info._name = "MESSAGE"; _info._width =50; break; + } + + return _info; +} + +const TVariant& TStampa_bolfat_recordset::get(unsigned int column) const +{ + if (column < columns()) + { + TToken_string* row = (TToken_string*)_bolle.objptr(_pos); + if (row != NULL) + return get_tmp_var() = row->get(column); + } + return NULL_VARIANT; +} + +const TVariant& TStampa_bolfat_recordset::get(const char* column_name) const +{ + if (_pos < 0 || _pos >= items()) + return NULL_VARIANT; + + + TToken_string& row = (TToken_string&)_bolle.row(_pos); + + const TFixed_string field(column_name); + if (field.ends_with("MESSAGE")) + { + const TFixed_string val(row.get(5)); + return get_tmp_var() = val; + } + + TToken_string bolkey; + bolkey.add(row.get(0)); + bolkey.add(row.get()); + bolkey.add(row.get()); + bolkey.add(row.get()); + const TDocumento& bol = ((TDocache&)_doc).doc(bolkey); + if (field.starts_with("33.")) + return get_tmp_var() = bol.get(field.mid(3)); + + const TRiga_documento& rbol = bol[row.get_int(4)]; + + if (field.find('.') < 0) + return get_tmp_var() = rbol.get(field); + + if (field.starts_with("34.")) + return get_tmp_var() = rbol.get(field.mid(3)); + + if (field[2] == '@') + { + TLocalisamfile ffat(LF_RIGHEDOC); + ffat.setkey(4); + TRectype& rfat = ffat.curr(); + rfat.put(RDOC_DAPROVV, rbol.get(RDOC_PROVV)); + rfat.put(RDOC_DAANNO, rbol.get(RDOC_ANNO)); + rfat.put(RDOC_DACODNUM, rbol.get(RDOC_CODNUM)); + rfat.put(RDOC_DANDOC, rbol.get(RDOC_NDOC)); + rfat.put(RDOC_DAIDRIGA, rbol.get(RDOC_IDRIGA)); + if (ffat.read() == NOERR) + { + if (field.starts_with("34@.")) + return get_tmp_var() = rfat.get(field.mid(4)); + TToken_string fatkey; + fatkey.add(rfat.get(RDOC_PROVV)); + fatkey.add(rfat.get(RDOC_ANNO)); + fatkey.add(rfat.get(RDOC_CODNUM)); + fatkey.add(rfat.get(RDOC_NDOC)); + TDocumento& fat = ((TDocache&)_doc).doc(fatkey); + if (field.starts_with("33@.")) + return get_tmp_var() = fat.get(field.mid(4)); + } + } + + return get_tmp_var() = EMPTY_STRING; +} + +void TStampa_bolfat_recordset::add(const TRectype& rbol, const char* message) +{ + TToken_string* str = new TToken_string; + str->add(rbol.get(RDOC_PROVV)); + str->add(rbol.get(RDOC_ANNO)); + str->add(rbol.get(RDOC_CODNUM)); + str->add(rbol.get(RDOC_NDOC)); + str->add(rbol.get(RDOC_NRIGA)); + str->add(message); + _bolle.add(str); +} + +//////////////////////////////////////////////////////// +// REPORT +//////////////////////////////////////////////////////// +class TStampa_bolfat_rep : public TReport +{ +protected: + virtual bool use_mask() { return false; } + +public: + TStampa_bolfat_rep() { load("ve1600a"); } +}; + +//////////////////////////////////////////////////////// +// APPLICAZIONE +//////////////////////////////////////////////////////// +class TStampa_bolfat : public TSkeleton_application +{ +protected: + void scan_num(const TString& num, const TDate& dal, const TDate& al, TStampa_bolfat_recordset& recset); + virtual void main_loop(); +}; + + +void TStampa_bolfat::scan_num(const TString& codnum, const TDate& dal, const TDate& al, TStampa_bolfat_recordset& recset) +{ + TString query; + query << "USE 33 SELECT BETWEEN(DATADOC,#DATAINIZIO,#DATAFINE)" + << "\nFROM PROVV=D ANNO=#ANNO CODNUM=#CODNUM" + << "\nTO PROVV=D ANNO=#ANNO CODNUM=#CODNUM"; + TISAM_recordset bolle(query); + bolle.set_var("#ANNO", long(dal.year())); + bolle.set_var("#CODNUM", codnum); + bolle.set_var("#DATAINIZIO", dal); + bolle.set_var("#DATAFINE", al); + + TLocalisamfile rfat(LF_RIGHEDOC); + rfat.setkey(4); + + TString msg; msg << TR("Controllo numerazione ") << codnum; + TProgind pi(bolle.items(), msg); + for (bool ok = bolle.move_first(); ok; ok = bolle.move_next()) + { + if (!pi.addstatus(1)) + break; + const TRectype& bol = bolle.cursor()->curr(); + const TString& tipodoc = bol.get(DOC_TIPODOC); + const char stato = bol.get_char(DOC_STATO); + if (stato >= _stato_finale && _tipi_doc.is_key(tipodoc)) + { + TDocumento bolla(bol); + FOR_EACH_PHYSICAL_RDOC(bolla, r, rbol) if (!rbol->is_descrizione()) + { + const real bol_qta = rbol->get(RDOC_QTA); + if (!bol_qta.is_zero()) + { + rfat.put(RDOC_DAPROVV, rbol->get(RDOC_PROVV)); + rfat.put(RDOC_DAANNO, rbol->get(RDOC_ANNO)); + rfat.put(RDOC_DACODNUM, rbol->get(RDOC_CODNUM)); + rfat.put(RDOC_DANDOC, rbol->get(RDOC_NDOC)); + rfat.put(RDOC_DAIDRIGA, rbol->get(RDOC_IDRIGA)); + if (rfat.read() == NOERR) + { + TToken_string msg(50, '\n'); + const TString& codart = rbol->get(RDOC_CODART); + if (codart.full() && codart != rfat.get(RDOC_CODART)) + msg.add(TR("Diverso articolo in fattura")); + + const real fat_qta = rfat.get(RDOC_QTA); + if (bol_qta != fat_qta) + msg.add(TR("Diversa quantità in fattura")); + + if (msg.full()) + recset.add(*rbol, msg); + } + else + recset.add(*rbol, TR("Nessuna fattura associata")); + } + } + } + } +} + +void TStampa_bolfat::main_loop() +{ + TStampa_bolfat_mask mask; + while (mask.run() == K_ENTER) + { + TStampa_bolfat_recordset* recset = new TStampa_bolfat_recordset; + + const TString& codnum = mask.get(F_NUMERAZIONE); + const int anno = mask.get_int(F_ANNO); + TDate dal = mask.get(F_DATAINIZIO); + if (dal.year() != anno) + dal = TDate(1,1,anno); + TDate al = mask.get(F_DATAFINE); + if (al < dal || al.year() != anno) + al = TDate(31, 12, anno); + + if (codnum.blank()) + { + TProgind pi(mask.numerazioni().items(), title()); + FOR_EACH_ARRAY_ROW(mask.numerazioni(), i, row) + { + if (!pi.addstatus(1)) + break; + const TFixed_string c = row->get(0); + scan_num(c, dal, al, *recset); + } + } + else + scan_num(codnum, dal, al, *recset); + + TStampa_bolfat_rep rep; + rep.set_recordset(recset); + rep.print_or_preview(); //stampa il book dei report + } +} + +int ve1600(int argc, char* argv[]) +{ + TStampa_bolfat a; + a.run(argc, argv, TR("Controllo bolle fatturate")); + return 0; +} + + diff --git a/ve/ve1600a.h b/ve/ve1600a.h new file mode 100644 index 000000000..45ed1862f --- /dev/null +++ b/ve/ve1600a.h @@ -0,0 +1,5 @@ +#define F_ANNO 201 +#define F_DATAINIZIO 202 +#define F_DATAFINE 203 +#define F_NUMERAZIONE 204 +#define F_DESCNUM 205 diff --git a/ve/ve1600a.rep b/ve/ve1600a.rep new file mode 100644 index 000000000..9a0674f7f --- /dev/null +++ b/ve/ve1600a.rep @@ -0,0 +1,54 @@ + + + +
+ + + + + + + + + + +
+
+
+
+ + MESSAGE + + + 33.DATADOC + + + 33.CODNUM + + + 33.NDOC + + + 34.NRIGA + + + 34.CODART + + + 34.DESCR + + + 34.UMQTA + + + 34.QTA + +
+
+
+ USE 34 SELECT TIPODOC="B01" +JOIN 33 INTO PROVV==PROVV ANNO==ANNO CODNUM==CODNUM NDOC==NDOC +FROM PROVV=D ANNO=#ANNO +TO PROVV=D ANNO=#ANNO + + \ No newline at end of file diff --git a/ve/velib04.cpp b/ve/velib04.cpp index 8bf2c3352..0b4129b63 100755 --- a/ve/velib04.cpp +++ b/ve/velib04.cpp @@ -414,6 +414,12 @@ const TString & TParametri_elaborazione::get(const char * name) const // TElaborazione /////////////////////////////////////////////////////////// +bool TElaborazione::elabora(TLista_documenti& doc_in, TLista_documenti& doc_out, const TDate& data_elab, bool interattivo) +{ + SORRY_BOX(); + return false; +} + TElaborazione::TElaborazione(const char* cod) : TRectype(LF_TABCOM) { settab("ELD"); diff --git a/ve/velib04.h b/ve/velib04.h index 7ce6c0c6c..69a724b9e 100755 --- a/ve/velib04.h +++ b/ve/velib04.h @@ -17,8 +17,6 @@ #include #endif - - class TLista_documenti : public TObject // velib04 { TArray _documenti; @@ -172,7 +170,6 @@ public: virtual void tipi_stati_iniziali(TToken_string& tipi, TToken_string& stati) const; - bool doc_uguale(int u) const { return get("S1").mid(u, 1) == "X"; } bool riga_uguale(int u) const { return get("S1").mid(40+u, 1) == "X"; } @@ -210,7 +207,7 @@ public: TParametri_elaborazione & params() { return _parms;} virtual bool elabora(TLista_documenti& doc_in, TLista_documenti& doc_out, - const TDate& data_elab, bool interattivo = false) pure; + const TDate& data_elab, bool interattivo = false); TElaborazione(const char* cod); TElaborazione(const TRectype& rec) : TRectype(rec) { } diff --git a/ve/vetbeld.uml b/ve/vetbeld.uml index 04773fe8f..436493db3 100755 --- a/ve/vetbeld.uml +++ b/ve/vetbeld.uml @@ -552,12 +552,6 @@ BEGIN GROUP 3 END -BOOLEAN F_AGGIORNA_TESTATA -BEGIN - PROMPT 2 19 "Aggiorna testata dopo l'elaborazione, se il documento e' vuoto" - FIELD B6 -END - BOOLEAN F_CHGCF BEGIN PROMPT 2 19 "Aggiorna il codice cliente/fornitore" @@ -565,9 +559,15 @@ BEGIN GROUP 2 END +BOOLEAN F_AGGIORNA_TESTATA +BEGIN + PROMPT 2 20 "Aggiorna testata dopo l'elaborazione, se il documento e' vuoto" + FIELD B6 +END + STRING F_APPLICAZIONE 70 50 BEGIN - PROMPT 2 20 "Applicazione " + PROMPT 2 21 "Applicazione " FIELD S3 GROUP 9 END