#include #include #include #include #include #include #include "velib.h" #include "ve1200a.h" #include /////////////////////////////////////////////////////////// // TScoperto_msk /////////////////////////////////////////////////////////// class TScoperto_msk : public TAutomask { protected: virtual bool on_field_event(TOperable_field& f, TField_event e, long jolly); bool fill_sheet(); public: TScoperto_msk(); }; bool TScoperto_msk::on_field_event(TOperable_field& f, TField_event e, long jolly) { switch (f.dlg()) { case F_CONSORD: if (e == fe_modify) fill_sheet(); break; case F_BOLLE: if (e == se_query_add || e == se_query_del) return FALSE; if (e == fe_close) { TSheet_field& s = sfield(F_BOLLE); FOR_EACH_SHEET_ROW(s, r, row) { if (*row->get(0) == 'X') return TRUE; } return error_box("Selezionare almeno una numerazione"); } break; case 100: if (e == fe_button) { TMask& m = f.mask(); // Sheet mask m.set(F_SELECTED, m.get_bool(F_SELECTED) ? "" : "X"); if (!m.is_open()) sfield(F_BOLLE).force_update(); } break; default: break; } return TRUE; } bool TScoperto_msk::fill_sheet() { TSheet_field& sheet = sfield(F_BOLLE); sheet.destroy(); const TTipo_elaborazione tipo_elab_bolle = get_bool(F_CONSORD) ? _consegna_ordini : _fatturazione_bolle; const TTipo_elaborazione tipo_elab_fatt = _contabilizzazione; TWait_cursor hourglass; TTable num("%NUM"); for (int err = num.first(); err == NOERR; err = num.next()) if (num.get_int("I1") == 1) // bolle { TToken_string tipi(50, ','); const TCodice_numerazione codnum(num.curr()); for (int t = codnum.ntipi_doc()-1; t >= 0; t--) { const TString8 td = codnum.tipo_doc(t); const TTipo_documento& tpd = TDocumento::tipo(td); TFilename prof; tpd.profile_name(prof); TConfig ini(prof, "MAIN"); if (ini.get("TIPOCF") == "F") tipi.add(td); } if (tipi.not_empty()) { TTable eld("%ELD"); TToken_string fatture(50, ','); TString8 stato_bolla, stato_fatt; for (int err = eld.first(); err == NOERR; err = eld.next()) { const TTipo_elaborazione te = (TTipo_elaborazione)eld.get_int("I0"); if (te == tipo_elab_bolle) { TElaborazione_esterna elab(eld.curr()); // Una vale l'altra :-) TString8 ti; for (int i = 0; ; i++) { ti = elab.tipo_iniziale(i); // Tipo iniziale if (ti.empty()) break; if (tipi.get_pos(ti) >= 0) { if (stato_bolla.empty()) stato_bolla << elab.stato_iniziale(i); const TString8 codfatt = elab.codice_numerazione_finale(); if (fatture.get_pos(codfatt) < 0) // Non e' già presente in lista { const TRectype& numfatt = cache().get("%NUM", codfatt); if (numfatt.get_int("I1") == 2) // Fattura vera! fatture.add(codfatt); } } } } if (te == tipo_elab_fatt && stato_fatt.empty()) { TElaborazione_esterna elab(eld.curr()); // Una vale l'altra :-) const TString8 codfatt = elab.codice_numerazione_finale(); bool is_fatt = fatture.get_pos(codfatt) >= 0; if (!is_fatt) { const TRectype& numfatt = cache().get("%NUM", codfatt); is_fatt = numfatt.get_int("I1") == 2; } if (is_fatt) stato_fatt << elab.stato_finale_doc_iniziale(); } } if (fatture.not_empty()) { TToken_string& row = sheet.row(-1); row = " "; row.add(codnum.codice()); row.add(codnum.descrizione()); row.add(tipi); row.add(stato_bolla); // Stato bolle non fatturate row.add(fatture); row.add(stato_fatt); // Stato fatture contabilizzate } } } sheet.force_update(); return sheet.items() > 0; } TScoperto_msk::TScoperto_msk() : TAutomask("ve1200a") { if (!fill_sheet()) { set(F_CONSORD, "X"); fill_sheet(); } } /////////////////////////////////////////////////////////// // TScoperto_form /////////////////////////////////////////////////////////// class TScoperto_form : public TForm { TDate _data_rif; bool _work_on_residual; char _stato_bolle; char _stato_fatture; private: static TScoperto_form* _curr_form; static void header_handler(TPrinter& p); protected: virtual bool validate(TForm_item& f, TToken_string& msg); const TRectype& head_of(const TRectype& row) const; public: void print_header(); int print_bolla(const TRectype& doc, TArray* fatt); void print_total(); TScoperto_form(const TDate& dr, bool wor, char sb, char sf); virtual ~TScoperto_form(); }; TScoperto_form* TScoperto_form::_curr_form = NULL; bool TScoperto_form::validate(TForm_item& f, TToken_string& msg) { if (msg == "_CLIFO") { const TRectype& r = cursor()->curr(LF_DOC); TToken_string key; key.add(r.get(DOC_TIPOCF)); key.add(r.get(DOC_CODCF)); const TRectype& rec = cache().get(LF_CLIFO, key); key = rec.get("RAGSOC"); if (key.len() > 30 && key[29] == ' ') { const TString nome = key.mid(30); key.cut(30); key.rtrim(); key << ' ' << nome; } f.set(key); return TRUE; } if (msg == "_DESCART") { const TRectype& r = cursor()->curr(LF_RIGHEDOC); TToken_string key; key.add(r.get(RDOC_CODARTMAG)); const TRectype& rec = cache().get(LF_ANAMAG, key); f.set(rec.get("DESCR")); return TRUE; } return TForm::validate(f, msg); } void TScoperto_form::print_header() { TPrint_section& head = section('H'); head.find_field(H_DATARIF).set(_data_rif.string()); set_header(1, FALSE); set_header(1, TRUE); } const TRectype& TScoperto_form::head_of(const TRectype& row) const { TToken_string key; key.add(row.get(RDOC_PROVV)); key.add(row.get(RDOC_ANNO)); key.add(row.get(RDOC_CODNUM)); key.add(row.get(RDOC_NDOC)); return cache().get(LF_DOC, key); } int TScoperto_form::print_bolla(const TRectype& dochead, TArray* fatt) { TDocumento& doc =(TDocumento& )cursor()->curr(LF_DOC); doc.read(dochead); TPrint_section& body = section('B', odd_page); TString_array note; bool testata_stampata = FALSE; for (int r = 1; r <= doc.physical_rows(); r++) { TRiga_documento& riga = doc[r]; if (riga.is_merce()) { real quant, valore; TString16 docrif, datarif, codnum, ndoc, postilla; if (_work_on_residual) { // Cerco le righe di fattura generate da questa riga di bolla if (fatt != NULL) { real qtafatt; // Quantità fatturata int fatture = 0; TToken_string key_bol, key_fat; key_bol = riga.get(RDOC_PROVV); key_bol.add(riga.get(RDOC_ANNO)); key_bol.add(riga.get(RDOC_CODNUM)); key_bol.add(riga.get(RDOC_NDOC)); key_bol.add(riga.get(RDOC_IDRIGA)); for (int r = fatt->last(); r >= 0; r--) { const TRectype& rfatt = (const TRectype&)(*fatt)[r]; const TRectype& fatt_head = head_of(rfatt); const TDate data_fatt = fatt_head.get(DOC_DATADOC); const char stato_fatt = fatt_head.get_char(DOC_STATO); if (stato_fatt < _stato_fatture || data_fatt > _data_rif) { key_fat = rfatt.get(RDOC_DAPROVV); key_fat.add(rfatt.get(RDOC_DAANNO)); key_fat.add(rfatt.get(RDOC_DACODNUM)); key_fat.add(rfatt.get(RDOC_DANDOC)); key_fat.add(rfatt.get(RDOC_DAIDRIGA)); if (key_fat == key_bol) { qtafatt += rfatt.get_real(RDOC_QTA); fatture++; if (docrif.empty()) { docrif = fatt_head.get(DOC_NUMDOCRIF); datarif = fatt_head.get(DOC_DATADOCRIF); codnum = fatt_head.get(DOC_CODNUM); ndoc = fatt_head.get(DOC_NDOC); } else { TToken_string n(50, ','); n = fatt_head.get(DOC_NUMDOCRIF); if (n != docrif) // Non annotare il documento principale! { TToken_string* nota = (TToken_string*)note.objptr(r); if (nota == NULL) { nota = new TToken_string; note.add(nota, r); postilla.format("(%d)", note.items()); } n.add(fatt_head.get(DOC_DATADOCRIF)); n.add(fatt_head.get(DOC_CODNUM)); n.add(fatt_head.get(DOC_NDOC)); if (nota->get_pos(n) < 0) // Non annotare due volte lo stesso documento! nota->add(n); } } } } } if (!qtafatt.is_zero()) { // Calcolo nuova quantita evasa sulla riga della bolla // Se la riga è completamente evasa da una sola fattura devo azzerara la quantità evasa // altrimenti devo scalare da questa la quantità specificata sulla fattura real qtaevasa; if (fatture > 1 || !riga.get_bool(RDOC_RIGAEVASA)) { qtaevasa = riga.get_real(riga.field_qtaevasa()); qtaevasa -= qtafatt; } riga.put(riga.field_qtaevasa(), qtaevasa); riga.put(RDOC_RIGAEVASA, ""); // La riga non può essere evasa completamente } } quant = riga.qtaresidua(); valore = riga.valore(FALSE, AUTO_DECIMALS); } else { if (fatt != NULL) { TToken_string key_bol, key_fat; key_bol = riga.get(RDOC_PROVV); key_bol.add(riga.get(RDOC_ANNO)); key_bol.add(riga.get(RDOC_CODNUM)); key_bol.add(riga.get(RDOC_NDOC)); key_bol.add(riga.get(RDOC_IDRIGA)); for (int r = fatt->last(); r >= 0; r--) { const TRectype& rfatt = (const TRectype&)(*fatt)[r]; const TRectype& fatt_head = head_of(rfatt); const TDate data_fatt = fatt_head.get(DOC_DATADOC); const char stato_fatt = fatt_head.get_char(DOC_STATO); if (stato_fatt < _stato_fatture || data_fatt > _data_rif) { key_fat = rfatt.get(RDOC_DAPROVV); key_fat.add(rfatt.get(RDOC_DAANNO)); key_fat.add(rfatt.get(RDOC_DACODNUM)); key_fat.add(rfatt.get(RDOC_DANDOC)); key_fat.add(rfatt.get(RDOC_DAIDRIGA)); if (key_fat == key_bol) { if (docrif.empty()) { docrif = fatt_head.get(DOC_NUMDOCRIF); datarif = fatt_head.get(DOC_DATADOCRIF); codnum = fatt_head.get(DOC_CODNUM); ndoc = fatt_head.get(DOC_NDOC); break; // Non ne dovrebbero esistere altre } } } } } quant = riga.quantita(); valore = riga.valore(TRUE, AUTO_DECIMALS); } if (valore > ZERO) // Devo stampare la riga { if (!testata_stampata) // Controllo se devo stampare la testata relativa { set_body(1, FALSE); // Inizializza BODY FIRST set_body(1, TRUE); // Stampa testata bolla testata_stampata = TRUE; } cursor()->curr(LF_RIGHEDOC) = riga; body.find_field(R_QUANT).set(quant.string()); body.find_field(R_VALORE).set(valore.string()); body.find_field(R_DOCRIF).set(docrif); body.find_field(R_DATARIF).set(datarif); body.find_field(R_CODNUM_FAT).set(codnum); body.find_field(R_NDOC_FAT).set(ndoc); body.find_field(R_NOTA).set(postilla); set_body(3, FALSE); // Inizializza BODY ODD set_body(3, TRUE); // Stampa riga bolla } } } if (testata_stampata) { set_body(2, FALSE); // Inizializza BODY EVEN set_body(2, TRUE); // Stampa totale bolla if (note.items() > 0) { TPrinter& pr = printer(); TPrintrow prow; pr.print(prow); int progr = 0; FOR_EACH_ARRAY_ROW(note, n, nota) { TString r; r.format("@b(%d) ATTENZIONE!@r ", ++progr); r << "La riga della bolla ha generato righe di merce anche sulle seguenti fatture: "; prow.reset(); prow.put(r); pr.print(prow); FOR_EACH_TOKEN((*nota), tok) { TToken_string t(tok, ','); prow.reset(); prow.put("Fattura di riferimento: "); prow.put(t.get(0)); prow.put(" "); prow.put(t.get()); prow.put(" Fattura: "); prow.put(t.get()); prow.put(" "); prow.put(t.get()); pr.print(prow); } } } } return testata_stampata ? 1 : 0; } void TScoperto_form::print_total() { set_body(0, FALSE); // Inizializza BODY LAST set_body(0, TRUE); // Stampa totale generale printer().formfeed(); } void TScoperto_form::header_handler(TPrinter&) { _curr_form->print_header(); } TScoperto_form::TScoperto_form(const TDate& dr, bool wor, char sb, char sf) : TForm("ve1200a"), _data_rif(dr), _work_on_residual(wor), _stato_bolle(sb), _stato_fatture(sf) { TCursor* cur = cursor(); TDocumento *doc = new TDocumento; // Don't delete! cur->file(LF_DOC).set_curr(doc); cur->file(LF_RIGHEDOC).set_curr(new TRiga_documento(doc));// Don't delete! _curr_form = this; printer().setheaderhandler(header_handler); // Setta handler testata } TScoperto_form::~TScoperto_form() { _curr_form = NULL; } /////////////////////////////////////////////////////////// // TLista_bolle /////////////////////////////////////////////////////////// class TLista_bolle : public TObject { TAssoc_array _bolle; TToken_string _key; protected: const TString& key(const TRectype& rec); public: void add_riga_fatt(const TRectype& rdoc_fatt); TArray* find_bolla(const TRectype& doc_bolla); void destroy() { _bolle.destroy(); } }; const TString& TLista_bolle::key(const TRectype& rec) { if (rec.num() == LF_RIGHEDOC) { _key = rec.get(RDOC_DAPROVV); _key.add(rec.get(RDOC_DAANNO)); _key.add(rec.get(RDOC_DACODNUM)); _key.add(rec.get(RDOC_DANDOC)); } else { _key = rec.get(DOC_PROVV); _key.add(rec.get(DOC_ANNO)); _key.add(rec.get(DOC_CODNUM)); _key.add(rec.get(DOC_NDOC)); } return _key; } void TLista_bolle::add_riga_fatt(const TRectype& riga_fatt) { const TString& k = key(riga_fatt); TArray* fatture = (TArray*)_bolle.objptr(k); if (fatture == NULL) { fatture = new TArray; _bolle.add(k, fatture); } fatture->add(riga_fatt); } TArray* TLista_bolle::find_bolla(const TRectype& doc_bolla) { const TString& k = key(doc_bolla); return (TArray*)_bolle.objptr(k); } /////////////////////////////////////////////////////////// // TScoperto_app /////////////////////////////////////////////////////////// class TScoperto_app : public TSkeleton_application { TLista_bolle _bolle_fatturate; protected: virtual void main_loop(); public: bool trova_bolle_fatturate_dal(TString_array& bolle, TString_array& fatture, char stato_fatt, const TDate& datarif); void print_bolle(TString_array& bolle, char stato_bolle, char stato_fatture, const TDate& datarif, bool work_on_res); }; bool TScoperto_app::trova_bolle_fatturate_dal(TString_array& bolle, TString_array& fatture, char stato_fatt, const TDate& datarif) { TEsercizi_contabili esc; const int codes = esc.date2esc(datarif); const TDate inies = esc[codes].inizio(); TRelation rel(LF_DOC); TRectype& curr = rel.curr(); TString str; str << "Ricerca bolle fatturate dopo il " << datarif; _bolle_fatturate.destroy(); curr.put(DOC_DATADOC, inies); if (fatture.items() == 1) // Ottimizziamo un po' il filtro, se c'é una sola fattura { curr.put(DOC_PROVV, "D"); curr.put(DOC_ANNO, inies.year()); curr.put(DOC_CODNUM, fatture.row(0)); } TCursor cur(&rel, "", 3, &curr); const long items = cur.items(); cur.freeze(); TProgind pi(items, str, TRUE, TRUE); TRecord_array righe(LF_RIGHEDOC, RDOC_NRIGA); for (cur = 0; cur.pos() < items; ++cur) { pi.addstatus(1); if (pi.iscancelled()) return FALSE; const TString& codnumfat = curr.get(DOC_CODNUM); if (fatture.find(codnumfat) >= 0) // E' proprio una fattura! { const TDate data = curr.get(DOC_DATADOC); const char stato = curr.get_char(DOC_STATO); // Devo considerare le fatture dopo la datarif // oppure quelle non ancora contabilizzate prima della datarif if (data > datarif || stato < stato_fatt) { TRectype* chiave = new TRectype(LF_RIGHEDOC); chiave->put(RDOC_PROVV, curr.get(DOC_PROVV)); chiave->put(RDOC_ANNO, curr.get(DOC_ANNO)); chiave->put(RDOC_CODNUM, curr.get(DOC_CODNUM)); chiave->put(RDOC_NDOC, curr.get(DOC_NDOC)); righe.read(chiave); for (int r = righe.rows(); r > 0; r--) { const TRectype& riga = righe.row(r); const TString& codnumbol = riga.get(RDOC_DACODNUM); if (codnumbol.not_empty() && bolle.find(codnumbol) >= 0) // Riga generata da fattura! _bolle_fatturate.add_riga_fatt(riga); } } } } return TRUE; } void TScoperto_app::print_bolle(TString_array& bolle, char stato_bolle, char stato_fatture, const TDate& datarif, bool work_on_res) { TEsercizi_contabili esc; const int codes = esc.date2esc(datarif); const TDate inies = esc[codes].inizio(); TRelation rel(LF_DOC); TRectype& curr = rel.curr(); curr.put(DOC_DATADOC, inies); TRectype recfin = curr; recfin.put(DOC_DATADOC, datarif); // Elenco di tutte le bolle comprese tra inizio esercizio e datarif TString filter; for (int i = 0; i < bolle.items(); i++) { if (i > 0) filter << "||"; filter << "(" << DOC_CODNUM << "==\"" << bolle.row(i) << "\")"; } TCursor cur(&rel, filter, 3, &curr, &recfin); const long items = cur.items(); if (items > 0) { cur.freeze(); TScoperto_form form(datarif, work_on_res, stato_bolle, stato_fatture); printer().open(); long printed = 0; for (cur = 0L; cur.pos() < items; ++cur) { if (printer().frozen()) break; const char stato = curr.get_char(DOC_STATO); if (stato == stato_bolle) // Bolla da fatturare { printed += form.print_bolla(curr, NULL); } else { TArray* fatt = _bolle_fatturate.find_bolla(curr); if (fatt != NULL) // Bolla fatturata printed += form.print_bolla(curr, fatt); } } if (printed > 0) form.print_total(); printer().close(); } } void TScoperto_app::main_loop() { open_files(LF_TABCOM, LF_DOC, LF_RIGHEDOC, LF_CLIFO, LF_CFVEN, 0); TScoperto_msk msk; while (msk.run() != K_QUIT) { const TDate datarif = msk.get(F_DATA); const bool work_on_res = msk.get_bool(F_CONSORD); TSheet_field& s = msk.sfield(F_BOLLE); char stato_bolle = ' ', stato_fatt = ' '; // Costruisco la lista delle bolle e delle fatture da leggere TString_array bolle, fatture; FOR_EACH_SHEET_ROW(s, r, row) if (*row->get(0) == 'X') { bolle.add(row->get(F_CODNUM-FIRST_FIELD)); if (stato_bolle <= ' ') stato_bolle = row->get(F_STATOBOLL-FIRST_FIELD)[0]; TToken_string f(row->get(F_FATTURE-FIRST_FIELD), ','); FOR_EACH_TOKEN(f, t) { if (fatture.find(t) < 0) fatture.add(t); } if (stato_fatt <= ' ') stato_fatt = row->get(F_STATOFATT-FIRST_FIELD)[0]; } bool ok = trova_bolle_fatturate_dal(bolle, fatture, stato_fatt, datarif); if (ok) print_bolle(bolle, stato_bolle, stato_fatt, datarif, work_on_res); } } int ve1200(int argc, char* argv[]) { TScoperto_app a; a.run(argc, argv, TR("Scoperto da fattura")); return (0); }