#include #include #include #include #include #include "velib.h" #include "ve7.h" #include "ve7200.h" #include "ve7200a.h" #include "../cg/cgsaldac.h" #include #include class TDocumentoOrdine : public TDocumento { TString_array _scadenze_array;// Array che contiene le scadenze ("|") int _scadenze_current; // indice per identificare l'elementi corrente sull'array (-1 se non ha ancora calcolato) public: // Funzioni per il ricalcolo delle scadenze void scadord_reset(); // riposiziona sulla prima scadenza void scadord_recalc(); // resetta e ricalcola le scadenze void scadord_set_next(); // seleziona il prossimo elemento dell'array delle scadenze const char * scadord_get(const TString& w); // reperisce l'informazione richiesta dall'elemento corrente int scadord_items() { return _scadenze_array.items(); } // restituisce il numero di scadenze TString_array& scadord() { return _scadenze_array; } TDocumentoOrdine (const TRectype & rec, dec_parm & parm) ; TDocumentoOrdine (const TRectype & rec) ; TDocumentoOrdine () ; virtual ~TDocumentoOrdine(); }; void TDocumentoOrdine::scadord_recalc() { TAssoc_array scadenze; scadenze.destroy(); _scadenze_array.destroy(); _scadenze_current = -1; TRectype& testadoc = head(); TPagamento& pag = pagamento(); const int rows = physical_rows(); for (int i = 0; i < rows; i++) { const TRiga_documento& rigadoc = physical_row(i+1); bool evasa = rigadoc.get_bool(RDOC_RIGAEVASA); if (!evasa) evasa = (rigadoc.qtaresidua() <= 0); if (!evasa) { TDate datacons = rigadoc.get_date(RDOC_DATACONS); if (!datacons.ok()) datacons = testadoc.get_date(DOC_DATACONS); TString16 codval = valuta(); real totimponibili = rigadoc.valore(FALSE, AUTO_DECIMALS); real totimposte = rigadoc.iva().imposta(totimponibili, AUTO_DECIMALS, codval); real totspese = ZERO; const bool is_in_valuta = in_valuta(); if (is_in_valuta) { const real change(cambio()); TCurrency_documento val1(totimponibili, *this); val1.change_to_firm_val(); TCurrency_documento val2(totimposte, *this); val2.change_to_firm_val(); TCurrency_documento val3(totspese, *this); val3.change_to_firm_val(); pag.set_total_valuta(totimponibili, totimposte, totspese, change, val1.get_num(), val2.get_num() ,val3.get_num(), codval); } else pag.set_total(totimponibili, totimposte, totspese); pag.set_inizio(datacons); pag.set_rate_auto(); const int numrate = pag.n_rate( ); real rata; for (int i = 0; i< numrate; i++) { rata = pag.importo_rata(i, is_in_valuta); const char* datastringa = (const char*) pag.data_rata(i).string(); if (scadenze.is_key(datastringa)) { real& valore = (real&)scadenze[datastringa]; valore+=rata; } else { real* oggetto = new real(rata); scadenze.add(datastringa,(TObject*)oggetto); } } } } scadenze.restart(); real* c; for (c = (real*) scadenze.first_item(); c != NULL; c = (real*) scadenze.succ_item()) { const char* datastringa = scadenze.get_hashobj()->key(); TToken_string t; t.add(datastringa); real importo(*c); t.add(importo.string()); _scadenze_array.add(t); } if (_scadenze_array.items() > 0) _scadenze_current++; } const char* TDocumentoOrdine::scadord_get(const TString& w) { const char* ret = ""; if (_scadenze_current == -1) // calcola le scadenze e le mette in _scadenze_array scadord_recalc(); if (_scadenze_current > -1 && _scadenze_current < _scadenze_array.items()) { if (w == "DATA") ret = _scadenze_array.row(_scadenze_current).get(0); // ritorna la data di scadenza if (w == "IMPORTO") ret = _scadenze_array.row(_scadenze_current).get(1); // ritorna l'importo in scadenza } return ret; } void TDocumentoOrdine::scadord_set_next() { if (_scadenze_current >= 0 && _scadenze_current < _scadenze_array.items() ) _scadenze_current++; } void TDocumentoOrdine::scadord_reset() { if (_scadenze_current > 0) _scadenze_current = 0; } TDocumentoOrdine::TDocumentoOrdine(const TRectype& rec) : TDocumento(rec), _scadenze_current(-1) { } TDocumentoOrdine::TDocumentoOrdine(const TRectype& rec, dec_parm & parm) : TDocumento(rec), _scadenze_current(-1) { } TDocumentoOrdine::TDocumentoOrdine() : TDocumento(), _scadenze_current(-1) { } TDocumentoOrdine::~TDocumentoOrdine() { } class TFlussi_form : public TForm { public: virtual bool validate(TForm_item &cf, TToken_string &s); void set_testata() {set_header(1,TRUE);} void set_pedata() {set_footer(1,FALSE); set_footer(1,TRUE);} TPrint_section& get_line() {return section('B', odd_page);} TFlussi_form(); virtual ~TFlussi_form(); }; TFlussi_form::TFlussi_form() :TForm ("ve7200a") { } TFlussi_form::~TFlussi_form() { } bool TFlussi_form::validate(TForm_item &cf, TToken_string &s) { return TForm::validate(cf,s); } class TFlussi_mask : public TAutomask { TRelation * _rel; TCursor * _cur; protected: bool on_field_event(TOperable_field& o, TField_event e, long jolly); public: TFlussi_mask(); virtual ~TFlussi_mask(){}; }; TFlussi_mask::TFlussi_mask() :TAutomask ("ve7200a") { } bool TFlussi_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { return TRUE; } class TStampaFlussiCassa : public TSkeleton_application { #pragma pack(1) struct struct_scadenza { char data[9]; real importo; char descrizione[80]; char estremidoc[45]; char statodoc; }; #pragma pack() TRelation* _rel; TCursor* _cur; TFlussi_mask* _msk; TFlussi_form* _form; TSort* _sort; TString_array _tipi_doc; // Array di stringhe contenente i tipi documenti da elaborare TDate _datascadi, _datascadf; real _totale; // totale a partire da saldo iniziale protected: virtual bool create(void); virtual bool destroy(void); virtual void main_loop() ; void elabora_scad(); void elabora_doc(); void stampa_flussi(); void print_header(); void print_footer(); void print_line(struct_scadenza* riga); public: TStampaFlussiCassa() {} ; virtual ~TStampaFlussiCassa() {} ; }; bool TStampaFlussiCassa::create() { open_files(LF_TAB, LF_TABCOM, LF_DOC, LF_RIGHEDOC, LF_PARTITE, LF_SCADENZE, LF_PAGSCA, LF_CLIFO, LF_CFVEN, 0); _rel = new TRelation(LF_SCADENZE); _rel->add(LF_PARTITE,"TIPOC==TIPOC|GRUPPO==GRUPPO|CONTO==CONTO|SOTTOCONTO==SOTTOCONTO|ANNO=ANNO|NUMPART==NUMPART",1,0); _rel->add(LF_PAGSCA, "TIPOC==TIPOC|GRUPPO==GRUPPO|CONTO==CONTO|SOTTOCONTO==SOTTOCONTO|ANNO==ANNO|NUMPART==NUMPART|NRIGA==NRIGA|NRATA==NRATA"); _cur = new TCursor(_rel, "PAGATA!=\"X\"", 2); _msk = new TFlussi_mask(); _form = new TFlussi_form(); _sort = new TSort(sizeof(struct_scadenza)); _sort->addsortkey(0,8); return TSkeleton_application::create(); } bool TStampaFlussiCassa::destroy() { delete _sort; delete _form; delete _msk; delete _cur; delete _rel; return TSkeleton_application::destroy(); } void TStampaFlussiCassa::main_loop() { while (_msk->run()!=K_QUIT) { _datascadi = _msk->get_date(F_DATASCADI); _datascadf = _msk->get_date(F_DATASCADF); _totale = _msk->get_real(F_SALDOINI); _sort->init(); // inizializza il sort elabora_scad(); // cominciamo dalle scadenze elabora_doc(); // continuiamo con i documenti _sort->endsort(); // fine sort stampa_flussi(); // stampiamo il tutto } } void TStampaFlussiCassa::stampa_flussi() { TString256 result; printer().open(); print_header(); print_footer(); TPrint_section& section = _form->get_line(); section.reset(); if (_totale > 0) { _form->find_field('B', odd_page, FF_B_IMPORTOD).set(_totale.string()); _form->find_field('B', odd_page, FF_B_IMPORTOA).set(""); } else { _form->find_field('B', odd_page, FF_B_IMPORTOA).set(_totale.string()); _form->find_field('B', odd_page, FF_B_IMPORTOD).set(""); } _form->find_field('B', odd_page, FF_B_ESTREMIDOC).set(""); _form->find_field('B', odd_page, FF_B_DESCRIZIONE).set("Saldo iniziale"); section.update(); for (word i = 0; i < section.height(); i++) { TPrintrow row = section.row(i); printer().print(section.row(i)); } struct_scadenza* riga; riga = (struct_scadenza*)_sort->retrieve(); while (riga != NULL) { print_line(riga); riga = (struct_scadenza*) _sort->retrieve(); } printer().close(); } void TStampaFlussiCassa::print_header() { _form->set_testata(); } void TStampaFlussiCassa::print_footer() { _form->set_pedata(); } void TStampaFlussiCassa::elabora_scad() { TRectype from(LF_SCADENZE), to(LF_SCADENZE); from.put(SCAD_DATASCAD, _datascadi); to.put(SCAD_DATASCAD, _datascadf); _cur->setregion(from, to); TRectype& recscad = _cur->curr(); const TRectype& recpartita = _cur->curr(LF_PARTITE); const TRecnotype items = _cur->items(); _cur->freeze(); TProgind pi(items, "Elaborazione scadenze", FALSE, TRUE); for (*_cur=0; _cur->pos()sort(record); } _cur->freeze(FALSE); } void TStampaFlussiCassa::elabora_doc() { TSheet_field& sheet = _msk->sfield(F_SHEETDOC); const int items = sheet.items(); if (items > 0) { TRelation doc_rel(LF_DOC); TRectype da(LF_DOC); TRectype a(LF_DOC); int year_from = _msk->get_int(F_ESERCIZIO); int year_to = _datascadf.year(); TString16 codnum, tipodoc; bool aresiduo; char dastato, astato; TString filt_expr; TDate dataini(1, 1, year_from); da.put("DATADOC", dataini); da.put("PROVV", "D"); da.put("ANNO", year_from); a.put("DATADOC", _datascadf); a.put("PROVV", "D"); a.put("ANNO", year_to); filt_expr << "("; FOR_EACH_SHEET_ROW(sheet, r, row) { codnum = row->get(0); tipodoc = row->get(2); dastato = row->get_char(4); astato = row->get_char(5); aresiduo = row->get_char(6) > ' '; if (codnum.not_empty() && tipodoc.not_empty()) { filt_expr << "((CODNUM=\""; filt_expr << codnum << "\")&&"; filt_expr << "(TIPODOC=\""; filt_expr << tipodoc << "\")"; if (dastato != ' ') filt_expr << " &&(STATO>=\"" << dastato << "\")"; if (astato != ' ') filt_expr << "&&(STATO<=\"" << astato << "\")"; filt_expr << ")||"; } } filt_expr.rtrim(2); filt_expr << ")"; TCursor doc_cur(&doc_rel,filt_expr,3,&da,&a); const TRecnotype cur_items = doc_cur.items(); // Scorre tutti i documenti che rientrano nell'intervallo selezionato if (cur_items != 0) { doc_cur.freeze(); const TRectype& cur_rec = doc_cur.curr(); TProgind pi(cur_items, "Elaborazione documenti", FALSE, TRUE); for (doc_cur = 0; doc_cur.pos() < cur_items; ++doc_cur) { pi.addstatus(1); TDocumento documento(cur_rec); if (documento.is_ordine()) { TDocumentoOrdine* doc = new TDocumentoOrdine; if (doc->read(doc_cur.curr()) == NOERR) // legge il documento { doc->scadord_recalc(); for (int i=0;i < doc->scadord_items(); i++) { struct_scadenza riga_scadenza; TDate datascad = doc->scadord_get("DATA"); if (datascad >= _datascadi && datascad <= _datascadf) { long data = datascad.date2ansi(); real importoscad = doc->scadord_get("IMPORTO"); const char sez = doc->tipocf(); TImporto importo((sez=='C' ? 'D' : 'A'), importoscad); importo.normalize('D'); TString16 codice; codice.cut(0); codice << doc->tipocf(); codice << '|' << doc->codcf(); TString80 descr = cache().get(LF_CLIFO, codice, CLI_RAGSOC); TString80 estremi = doc->tipo().codice(); estremi << " n. " << doc->numero(); estremi << " del " << doc->data().string(); const char stato = doc->stato(); sprintf(riga_scadenza.data, "%8ld", data); riga_scadenza.importo = importo.valore(); strcpy(riga_scadenza.descrizione, descr); strcpy(riga_scadenza.estremidoc, estremi); riga_scadenza.statodoc = stato; const char* record = (const char*) &riga_scadenza; _sort->sort(record); } doc->scadord_set_next(); } } delete doc; } else { TDocumentoEsteso* doc = new TDocumentoEsteso; if (doc->read(doc_cur.curr()) == NOERR) // legge il documento { doc->scadenze_recalc(); for (int i=0;i < doc->scadenze_items(); i++) { struct_scadenza riga_scadenza; TDate datascad = doc->scadenze_get("DATA"); if (datascad >= _datascadi && datascad <= _datascadf) { long data = datascad.date2ansi(); real importoscad = doc->scadenze_get("IMPORTO"); const char sez = doc->tipocf(); TImporto importo((sez=='C' ? 'D' : 'A'), importoscad); importo.normalize('D'); TString16 codice; codice.cut(0); codice << doc->tipocf(); codice << '|' << doc->codcf(); TString80 descr = cache().get(LF_CLIFO, codice, CLI_RAGSOC); TString80 estremi = doc->tipo().codice(); estremi << " n. " << doc->numero(); estremi << " del " << doc->data().string(); const char stato = doc->stato(); sprintf(riga_scadenza.data, "%8ld", data); riga_scadenza.importo = importo.valore(); strcpy(riga_scadenza.descrizione, descr); strcpy(riga_scadenza.estremidoc, estremi); riga_scadenza.statodoc = stato; const char* record = (const char*) &riga_scadenza; _sort->sort(record); } doc->scadenze_set_next(); } } delete doc; } } } } } void TStampaFlussiCassa::print_line(struct_scadenza* riga) { const long scadenza = atol(riga->data); const TDate datascad(scadenza); const real importo = riga->importo; TString80 descr = riga->descrizione; descr.trim(); _form->find_field('B', odd_page, FF_B_DESCRIZIONE).set(descr); if (importo.sign() >=0) { _form->find_field('B', odd_page, FF_B_IMPORTOD).set(importo.string()); _form->find_field('B', odd_page, FF_B_IMPORTOA).set(""); } else { _form->find_field('B', odd_page, FF_B_IMPORTOA).set(importo.string()); _form->find_field('B', odd_page, FF_B_IMPORTOD).set(""); } TString80 estremi = riga->estremidoc; _form->find_field('B', odd_page, FF_B_ESTREMIDOC).set(estremi); TString4 stato = ""; stato[0] = riga->statodoc; _form->find_field('B', odd_page, FF_B_STATODOC).set(stato); _form->find_field('B', odd_page, FF_B_SCADENZA).set(datascad); _totale += importo; _form->find_field('B', odd_page, FF_B_PROGRESSIVO).set(_totale.string()); TPrint_section& section = _form->get_line(); section.update(); for (word i = 0; i < section.height(); i++) { TPrintrow row = section.row(i); printer().print(section.row(i)); } } int ve7200(int argc, char **argv) { TStampaFlussiCassa a; a.run(argc, argv, TR("Stampa flussi di cassa")); return 0; }