#include #include #include #include #include "velib04.h" #include "ve1.h" #include "ve1600a.h" //////////////////////////////////////////////////////// // MASCHERA //////////////////////////////////////////////////////// static TAssoc_array _tipi_bol; static TString_array _nums_bol; static TAssoc_array _nums_fat; 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 _nums_bol; } TStampa_bolfat_mask(); }; bool TStampa_bolfat_mask::codnum_filter(const TRelation* rel) { const TString& codnum = rel->curr().get("CODTAB"); return _nums_bol.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 (_nums_bol.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_bol.destroy(); _nums_bol.destroy(); _nums_fat.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 || e.tipo() == _esterna) { const TString4 codnumfat = e.codice_numerazione_finale(); const TCodice_numerazione n(codnumfat); if (n.get_int("I1") == 2) // Genera vere fatture { const char sfdi = e.stato_finale_doc_iniziale()[0]; // Stato finale documento iniziale bool found = false; TToken_string tipi, stati; e.tipi_stati_iniziali(tipi, stati); FOR_EACH_TOKEN(tipi, t) { const char sidi = stati.get_char(); // Stato iniziale documento iniziale if (sfdi > sidi) { found = true; _tipi_bol.add(t); if (sfdi < _stato_finale) _stato_finale = sfdi; } } if (found) _nums_fat.add(codnumfat); } } } // giro sulle numerazioni delle bolle TISAM_recordset num("USE %NUM SELECT I1=1"); 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_bol.is_key(td)) { _nums_bol.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, char bof); 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 7; } 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; case 5: _info._name = "MESSAGE"; _info._width =50; break; default: _info._name = "TYPE"; _info._width = 1; 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; } if (field.ends_with("TYPE")) { const TFixed_string val(row.get(6)); 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)); return NULL_VARIANT; } void TStampa_bolfat_recordset::add(const TRectype& rdoc, const char* message, char bof) { TToken_string* str = new TToken_string; str->add(rdoc.get(RDOC_PROVV)); str->add(rdoc.get(RDOC_ANNO)); str->add(rdoc.get(RDOC_CODNUM)); str->add(rdoc.get(RDOC_NDOC)); str->add(rdoc.get(RDOC_NRIGA)); str->add(message); str->add(bof); _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: const char* compare_rows(const TRectype& rbol, const TRectype& rfat) const; void scan_num(const TString& num, const TDate& dal, const TDate& al, TStampa_bolfat_recordset& recset); virtual void main_loop(); }; const char* TStampa_bolfat::compare_rows(const TRectype& rbol, const TRectype& rfat) const { const TString& codart_b = rbol.get(RDOC_CODART); const TString& codart_f = rfat.get(RDOC_CODART); if (codart_b.full() && codart_b != codart_f) return TR("Diverso articolo in fattura"); const real qta_b = rbol.get(RDOC_QTA); const real qta_f = rfat.get(RDOC_QTA); if (!qta_b.is_zero() && qta_b != qta_f) return TR("Diversa quantità in fattura"); return NULL; } 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); const TRectype& bol = bolle.cursor()->curr(); TLocalisamfile rfat(LF_RIGHEDOC); rfat.setkey(4); TRectype& recfat = rfat.curr(); 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 TString& tipodoc = bol.get(DOC_TIPODOC); const char stato = bol.get_char(DOC_STATO); if (stato >= _stato_finale && _tipi_bol.is_key(tipodoc)) { TToken_string rdoc_key; rdoc_key.add(bol.get(DOC_CODNUM)); rdoc_key.add(bol.get(DOC_ANNO)); rdoc_key.add(bol.get(DOC_PROVV)); rdoc_key.add(bol.get(DOC_NDOC)); TRecord_array bolla(rdoc_key, LF_RIGHEDOC); for (int r = 1; r > 0 && r <= bolla.rows(); r = bolla.succ_row(r)) { const TRectype& rbol = bolla.row(r); if (rbol.get(RDOC_CODART).blank() || rbol.get_real(RDOC_QTA).is_zero()) continue; recfat.put(RDOC_DAPROVV, rbol.get(RDOC_PROVV)); recfat.put(RDOC_DAANNO, rbol.get(RDOC_ANNO)); recfat.put(RDOC_DACODNUM, rbol.get(RDOC_CODNUM)); recfat.put(RDOC_DANDOC, rbol.get(RDOC_NDOC)); recfat.put(RDOC_DAIDRIGA, rbol.get(RDOC_IDRIGA)); TArray matches; for (int err = rfat.read(); err == NOERR; err = rfat.next()) { if (recfat.get_long(RDOC_DAIDRIGA) == rbol.get_long(RDOC_IDRIGA) && recfat.get_long(RDOC_DANDOC) == rbol.get_long(RDOC_NDOC)) { // Devo fare attenzione a scartare gli altri documenti // che possono derivare dalla bolla pur non essendo fatture if (_nums_fat.is_key(recfat.get(RDOC_CODNUM))) matches.add(recfat); } else break; } if (!matches.empty()) { bool bolled = false; FOR_EACH_ARRAY_ITEM(matches, r, obj) { const TRectype& rigafatt = *(const TRectype*)obj; const char* msg = compare_rows(rbol, rigafatt); if ((msg == NULL || *msg < ' ') && matches.items() > 1) msg = TR("Doppia elaborazione"); if (msg && *msg) { if (!bolled) { recset.add(rbol, " ", 'B'); bolled = true; } recset.add(rigafatt, msg, 'F'); } } } else recset.add(rbol, TR("Nessuna fattura associata"), 'B'); } } } } 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 TString4 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; }