#include #include "../cg/cgsaldac.h" #include "sc2.h" #include "sc2200.h" #include "sc2201.h" #include #include #include #include #define SCADCLIFO_ALIAS 51 #define CLIFOSCAD_ALIAS 52 #define SCADPCON_ALIAS 53 #define PCONSCAD_ALIAS 54 #define MaxRowsForTotal 17 #define TPString TParagraph_string // Comodita'... struct _LinearTotal : public TObject // Oggetto base per gli elementi di tlg, tlm, tlp { // Contiene i totali da stampare su una linea real _is, // Importo in scadenza _ip, // Importo pagato _rd, // Rimesse dirette _ri, // Ri.ba/Tratte _al; // Altri virtual TObject* dup() const { return new _LinearTotal(*this); } _LinearTotal() {_is = 0.0; _ip = 0.0; _rd = 0.0; _ri = 0.0; _al = 0.0; } }; enum tipo_st {nessuno=0, tutti=1, clienti=2, fornitori=3, altri=4}; enum tipo_pe {daily, monthly, period, single, bank}; class TStampaScadenzario : public TPrintapp { TRelation *_rel1, *_rel2, *_rel3; // Relazioni di lavoro... int _cur1, _cur11, // Identificatori dei cursori di lavoro... _cur2, _cur3, _cur4, _cur41, // piu' avanti spiega tutto. _cur5, _cur6, _cur7; TSelection_ext_mask *_m; TPartita *_p; // Oggetto partita corrente. Viene ricaricato ad ogni cambio partita, // ovvero ogni volta che la rata corrente cambia i "connotati" TLocalisamfile *_pagsca; TString _annopart,_datareg,_numdoc,_datadoc, // Anno partita (2 cifre), data registrazione, nr. documento, data doc. _protiva, _codval; // Numero di protocollo IVA (TString perche' se vale 0 non stampa nulla), e codice valuta TString _last_ban, _desc_ban; // Banca correntemente in corso di raggruppamento TPString *_descrizione,*_ragsoc,*_des_conto; // Descrizione (da LF_PARTITE), ragione sociale (da LF_CLIFO) // Descrizione conto (da LF_PCON) TString _imp_scad,_imp_pag,_rimdir,_riba,_altri, // Valori calcolati in preprocess_page: rimesse dirette, Ri.ba e altri _cur_gr_s, _cur_co_s, _cur_codcf_s; // _imp_scad e _imp_pag vengono anch'essi calcolati in preprocess_page. TDate _datai, _dataf, _datas, // Data inizio, fine e stampa _cur_data; // Data di scadenza riferita al record corrente long _cur_codcf; // Cli/Fo riferito al record corrente int _cur_gr,_cur_co; // Gruppo/Conto riferito al record corrente. tipo_st _tipost; // Tipo di stampa impostato bool _modified, // VERO=E' stato stampato il totale giornaliero (mensile) _end_printed, // VERO=riepilogo finale da stampare _ratesald, // VERO=stampa anche le rate saldate _ordata, // VERO=ordine primario per data, FALSO=ordine primario impostato da _ordcod _ordcod, // VERO=ordine per codice, FALSO=ordine per ragione sociale _striepilogo, // VERO=stampa il riepilogo mensile per pagamento _stvaluta, // Vero se abilitata la stampa in valuta; _group_ban, // Vero se abilitato il raggruppamento per banca _totbank_printed; // vero se é stato stampato il totale per banca // Se _tipost=tutti non e' possibile impostare l'ordine primario per // ragione sociale o descrizione. L'unico tipo stampa possibile e' quello // in ordine di data scadenza // Se _tipost=altri scorre il piano dei conti. // Se _tipost=clienti || fornitori scorre clifo. TString16 _codag; // codice agente selezionato int _tipopag; // tipo pagamento selezionato TRecnotype _last_bank_rec; // ultimo record con banca stampato real _w_imp_pag, _w_imp_res; // Qui dentro memorizza i valori calcolati in calcola_pagamenti, // rispettivamente l'importo pagato e l'importo residuo, relativo alla rata. TAssoc_array _tm, _tp; // Dentro a codesti array vi sono i totali per la stampa prospetti: // durante l'elaborazione cerca la chiave relativa, aggiungendo o // aggiornando l'elemento se necessario; una volta pronto per stampare // il prospetto viene "ordinato" tramite la TAssoc_array::get_keys() // e il sort di TArray_string. _tm e' il totale del mese o del cli/fo/conto // (nel caso di ordinamento diversa da data), _tp e' il totale del periodo. // La chiave e' cosi' composta: Tipo pag.+ult. class.+cod valuta // // Qui memorizza i totali "lineari". Analogamente ai 2 precedenti // TAssoc_array, durante l'elaborazione cerca la chiave relativa, aggiungendo o // aggiornando l'elemento se necessario; esegue un sort prima di stamparlo. // Se l'ordinamento principale non e' per data utilizza tlm per i totali // del cli/fo/conto e tlp per i totali del periodo. La chiave e' per: // codice valuta TArray _tl; // Contiene tlg, tlm, tlp (vedi user_create()), cosi' vi accedo tramite un indice. TArray _uns_cache; // cache dei non assegnati: l'elemento [0] contiene un TAssoc_array dei non assegnati normali, // l'elemento [1] contiene un TAssoc_array dei non assegnati relativi a nonte dei credito. La // chiave per tali TAssoc_array e': TIPO+GRUPPO+CONTO+SOTTOCONTO+ANNO+NUMPART. // prima di ricalcolare i non assegnati e' necessario guardare in questa cache, se esiste la // chiave relativa alla partita, ed eventualmente utilizzare tale valore in memoria. static bool filter_func(const TRelation *); // Funzione di filtro [_datai.._dataf] public: // print functions virtual bool preprocess_page(int file, int counter); // Qui stampa i totali e i riepiloghi virtual bool preprocess_print(int file, int counter); // Qui non fa proprio nulla! virtual print_action postprocess_print(int file, int counter); // Qui setta i flags per stampare il riepilogo finale! virtual print_action postprocess_page(int file, int counter); // Qui fa molte cose... virtual void preprocess_header() {}; // Very Very Dummy... virtual bool user_create(); // Qui creo i cursori... virtual bool user_destroy(); // e qui li distruggo. virtual bool set_print(int); // Qui c'e' la maschera di selezione. virtual void set_page (int file, int counter); // Setta le righe di stampa. void set_page_clifo(int nriga); // Frammenti di set_page void set_page_pcon (int nriga); void print_header(); // Stampa l'header. // Le seguenti funzioni valgono con ordinamento principale per data. void print_rows_riepilogo(int& nriga, bool type, TAssoc_array& tot); // Stampa effettivamente lo specchietto void print_riepilogo(int &nriga, bool type); // type == FALSE prints month totals, type == TRUE prints period totals. void print_rows_totali(int &nriga, tipo_pe p); void print_totali(int &nriga, bool month_changed, bool ended); // month_changed indica se il mese e' cambiato. //ended indica il raggiungimento di fine periodo. // La seguente funzione serve per il riepilogo dei totali nel caso l'ordinamento principale non sia per data. void print_totali_c(int &nriga, bool ended); // ended indica di stampare anche il riepilogo del periodo void print_totali_bank(int &nriga); // Funzioni per calcolo dei pagamenti e di aggiornamento totali void check_add_key_to_tp(int t, char u); // controlla e aggiunge i valori relativi alla chiave k ai totali del prospetto void check_add_key_to_tl(tipo_pe p, int t); // controlla e aggiunge i valori elaborati all'assoc array indicato dal periodo (_tlxxx) // Ritorna TRUE se la partita corrente _p non e' piu' riferita alla scadenza corrente bool scad_changed(char tipo, int gruppo, int conto, long codcf, int anno, TString& nump); // Ritorna TRUE se la scadenza corrente ha una banca diversa dalla precedente // bool bank_will_change(); // Totalizza i pagamenti non assegnati per la partita corrente (NB si spera che siano tutti nella stessa valuta) bool in_cache(const TString& k); // ritorna vero se ci sono gia' non assegnati in _uns_cache; void look_in_cache(real& a, real& b, real& c, TAssoc_array& uns, TAssoc_array& unsnc, TAssoc_array& unsins, TString& k); void calcola_unassigned(const TString& k); void calcola_pagamenti(real& imp_scad, int riga, int rata, TBill& bill); // calcola i pagamenti effettuati per questa rata e il residuo eventuale const char * tipi_tab(int tipo); TLocalisamfile& pagamenti() const { return *_pagsca; } void print_intestazione_banca(int &nriga); TStampaScadenzario(); }; inline TStampaScadenzario& app() {return (TStampaScadenzario&)main_app();} /////////////////////////////////////////////////////////// class TScadenza_rec : public TRectype { TString _codice; protected: virtual const TString& get_str(const char* fieldname) const; public: TScadenza_rec() : TRectype(LF_SCADENZE) { } }; const TString& TScadenza_rec::get_str(const char* fieldname) const { if (strcmp(fieldname, SCAD_CODABIPR) == 0 || strcmp(fieldname, SCAD_CODCABPR) == 0 || strcmp(fieldname, SCAD_CODAG) == 0) { TRectype rec(LF_PAGSCA); rec.put(PAGSCA_TIPOC, TRectype::get_str(SCAD_TIPOCF)); rec.put(PAGSCA_GRUPPO, TRectype::get_str(SCAD_GRUPPO)); rec.put(PAGSCA_CONTO, TRectype::get_str(SCAD_CONTO)); rec.put(PAGSCA_SOTTOCONTO, TRectype::get_str(SCAD_SOTTOCONTO)); rec.put(PAGSCA_ANNO, TRectype::get_str(SCAD_ANNO)); rec.put(PAGSCA_NUMPART, TRectype::get_str(SCAD_NUMPART)); rec.put(PAGSCA_NRIGA, TRectype::get_str(SCAD_NRIGA)); rec.put(PAGSCA_NRATA, TRectype::get_str(SCAD_NRATA)); TLocalisamfile& pagamenti = app().pagamenti(); TRectype& curpag = pagamenti.curr(); bool found = curpag.compare_key(rec,1,1) == 0; if (!found) { curpag = rec; const int err = pagamenti.read(_isgteq); found = (err == NOERR) && (curpag.compare_key(rec,1,1) == 0); } TString& cod = ((TScadenza_rec*)this)->_codice; // Fool the compiler cod = TRectype::get_str(fieldname); // Valore di default sulla scadenza if (found) { const TString& val = curpag.get(fieldname); if (val.not_empty()) cod = val; // Valore presente sul pagamento effettivo } if (strcmp(fieldname, SCAD_CODABIPR) == 0 || strcmp(fieldname, SCAD_CODCABPR) == 0) cod.format("%05ld", atol(_codice)); // riformatta codice banca return _codice; } return TRectype::get_str(fieldname); } /////////////////////////////////////////////////////////// HIDDEN void print_real(TString& dest, const real& num, const char* val) { const TCurrency cur(num, val); dest = cur.string(TRUE); dest.right_just(18); } bool TStampaScadenzario::filter_func(const TRelation *r) { if (app()._group_ban) { const TMask& m = *(app()._m); const long fromabi = m.get_long(F_FROMABI); const long toabi = m.get_long(F_TOABI); if (fromabi > 0 || toabi > 0) { const TRectype& rec = r->curr(); const long abi = rec.get_long(SCAD_CODABIPR); const long cab = rec.get_long(SCAD_CODCABPR); if (fromabi > 0) { if (abi < fromabi) return FALSE; const long fromcab = m.get_long(F_FROMCAB); if (fromcab > 0 && abi == fromabi) { if (cab < fromcab) return FALSE; } } if (toabi > 0) { if (abi > toabi) return FALSE; const long tocab = m.get_long(F_TOCAB); if (tocab > 0 && abi == toabi) { if (cab > tocab) return FALSE; } } } } if (app()._codag.not_empty()) { const TRectype& rec = r->curr(); const TString16 codag = rec.get(SCAD_CODAG); if (app()._codag != codag) return FALSE; } if (app()._tipopag != 0) { const TRectype& rec = r->curr(); const int tipopag = rec.get_int(SCAD_TIPOPAG); if (app()._tipopag != tipopag) return FALSE; } return TRUE; } void TStampaScadenzario::check_add_key_to_tl(tipo_pe p, int t) // Aggiorna i totali per i totali sulla linea { TString kl(_codval); _LinearTotal newtot; int index = 0; // Default DAILY switch (p) // Seleziona l'assoc array da usare { case monthly: case single: index = 1; break; case period: index = 2; break; case bank: index = 3; break; default: // Se p == daily e' gia settato di default (vedi sopra) break; } TAssoc_array& xassoc = (TAssoc_array&) _tl[index]; const bool is_key = xassoc.is_key(kl); // Esiste l'elemento ? // Se si' allora prendi quello, altrimenti prendine uno nuovo (newtot) _LinearTotal& xtotal = (is_key ? (_LinearTotal&) xassoc[kl] : newtot); //Aggiorna xtotal (importi in scadenza, pagati, riba, rimesse e altri) xtotal._is += (_w_imp_pag + _w_imp_res); xtotal._ip += _w_imp_pag; switch (t) { case 1: xtotal._rd += _w_imp_res; break; case 2: case 3: xtotal._ri += _w_imp_res; break; default: xtotal._al += _w_imp_res; break; } xassoc.add(kl,xtotal,is_key); } void TStampaScadenzario::check_add_key_to_tp(int t, char u) // Aggiorna i totali per i prospetti finali { TString k; // compone la chiave, valida per _tm e _tp k << t; if (u == '\0') u = ' '; // Per indicare che non c'e' ult class k << u << _codval ; if (_tm.is_key(k)) // Se esiste gia' in _tm allora { // gli aggiunge il valore attuale real& r=(real&)_tm[k]; r += _w_imp_res; _tm.add(k,r,TRUE); } else _tm.add(k,_w_imp_res); if (_tp.is_key(k)) // Se esiste gia' in _tp allora { // gli aggiunge il valore attuale real& r=(real&)_tp[k]; r += _w_imp_res; _tp.add(k,r,TRUE); } else _tp.add(k,_w_imp_res); } bool TStampaScadenzario::scad_changed(char tipo, int gruppo, int conto, long codcf, int anno, TString& nump) { if (_p == NULL) return TRUE; TRiga_partite& rp = _p->riga(_p->first()); if (tipo != rp.get_char(PART_TIPOCF) || gruppo != rp.get_int(PART_GRUPPO) || conto != rp.get_int(PART_CONTO) || codcf != rp.get_long(PART_SOTTOCONTO) || anno != rp.get_int(PART_ANNO) || nump != rp.get(PART_NUMPART)) return TRUE; return FALSE; } /* bool TStampaScadenzario::bank_will_change() { bool yes = FALSE; if (_group_ban) { TCursor& cur = *current_cursor(); if (cur.pos() > 0 && cur.pos() < cur.items()-1) { const TRectype& rc = cur.curr(); const TString8 oldabi = rc.get(SCAD_CODABIPR); const TString8 oldcab = rc.get(SCAD_CODCABPR); ++cur; const TString8 newabi = rc.get(SCAD_CODABIPR); const TString8 newcab = rc.get(SCAD_CODCABPR); yes = oldabi != newabi || oldcab != newcab; --cur; } else yes = TRUE; } return yes; } */ bool TStampaScadenzario::in_cache(const TString& k) { TAssoc_array& uns = (TAssoc_array&) _uns_cache[0]; TAssoc_array& unsnc = (TAssoc_array&) _uns_cache[1]; TAssoc_array& unsins = (TAssoc_array&) _uns_cache[2]; bool rt = uns.is_key(k) || unsnc.is_key(k) || unsins.is_key(k); return rt; } void TStampaScadenzario::calcola_unassigned(const TString& k) // Calcola i pagamenti non assegnati normali, e quelli riferiti a note di credito // ovvero quelli con tipo di movimento 2. Vanno percio' tenuti separati due totali: // _uns_cache[0] per i non assegnati normali, utilizzato per i pagamenti; // _uns_cache[1] per i non assegnati, riferiti a note di credito, da scalare all'importo in scadenza { TAssoc_array& uns = (TAssoc_array&) _uns_cache[0]; TAssoc_array& unsnc = (TAssoc_array&) _uns_cache[1]; TAssoc_array& unsins = (TAssoc_array&) _uns_cache[2]; real a,b,c; TRecord_array& ra = _p->unassigned(); for (int r = ra.last_row(); r > 0; r = ra.pred_row(r)) { const TRectype& rec = ra.row(r); const TRiga_partite& sum = _p->riga(rec.get_int(PAGSCA_NRIGP)); const char* field = (_stvaluta && sum.in_valuta() ? PAGSCA_IMPORTOVAL : PAGSCA_IMPORTO); const tipo_movimento tm = (tipo_movimento)sum.get_int(PART_TIPOMOV); switch (tm) { case tm_nota_credito : b += rec.get_real(field); break; // Is it a credit note? case tm_insoluto : c += rec.get_real(field); break; // Is unsolved? case tm_pagamento_insoluto: c -= rec.get_real(field); break; // Is unsolved payed? default : a += rec.get_real(field); break; } } if (a != ZERO) // Aggiungilo a TAssoc_array dei non assegnati uns.add(k,a,TRUE); if (b != ZERO) // Aggiungilo a TAssoc_array delle note di credito unsnc.add(k,b,TRUE); if (c != ZERO) // Aggiungilo a TAssoc_array degli insoluti unsins.add(k,c,TRUE); } void TStampaScadenzario::look_in_cache(real& a, real& b, real& c, TAssoc_array& uns, TAssoc_array& unsnc, TAssoc_array& unsins, TString& k) //Estrae dai tassoc_array i valori, relativi alla partita corrente, di uns e unsnc, mettendoli in a e b { TRiga_partite& rp = _p->riga(_p->first()); k << rp.get_char(PART_TIPOCF) << rp.get_int(PART_GRUPPO); k << rp.get_int(PART_CONTO) << rp.get_long(PART_SOTTOCONTO); k << rp.get_int(PART_ANNO); k << rp.get(PART_NUMPART); a = b = c = ZERO; if (uns.is_key(k)) a = (real&)uns[k]; if (unsnc.is_key(k)) b = (real&)unsnc[k]; if (unsins.is_key(k)) c = (real&)unsins[k]; } void TStampaScadenzario::calcola_pagamenti(real& imp_scad, int riga, int rata, TBill& bill) { TAssoc_array& uns = (TAssoc_array&) _uns_cache[0]; TAssoc_array& unsnc = (TAssoc_array&) _uns_cache[1]; TAssoc_array& unsins = (TAssoc_array&) _uns_cache[2]; TRiga_scadenze& rs = _p->rata(riga,rata); const char ssez = _p->riga(riga).sezione(); const char* field = (_stvaluta && rs.in_valuta()) ? PAGSCA_IMPORTOVAL : PAGSCA_IMPORTO; const char* sfield = (_stvaluta && rs.in_valuta()) ? SCAD_IMPORTOVAL : SCAD_IMPORTO; TImporto totalep, // Totale dei pagamenti scdz; // Importo in scadenza scdz += TImporto(ssez,rs.get_real(sfield)); totalep += rs.importo_pagato(_stvaluta); // Quanto e' stato pagato per questa scadenza? for (int p = rs.last(); p > 0; p = rs.pred(p)) // Calcola il totale pagamenti e discrimina { // Il TIPOMOV: 1,5 : fattura insoluto const TRectype pag = rs.row(p); // 2 : nota di credito const TRiga_partite& sum = _p->riga(p); // 3,4,6 : incasso/pagamento/abbuono/pag.insoluto/diff.cambio/rit.prof const char sez = sum.sezione(); const tipo_movimento tipomov = (tipo_movimento)sum.get_int(PART_TIPOMOV); // se tipomov e' 2 (Nota di credito assegnata) // storna da scdz. In entrambi i casi si ha l'operatore +=, perche' nel TImporto e' gia' // compresa la sezione opposta if (tipomov == tm_nota_credito) { const TImporto work_imp = TImporto(sez,pag.get_real(field)); scdz += work_imp; totalep -= work_imp; } } char norm = 'D'; if (_tipost == fornitori) norm = 'A'; else if (_tipost == altri && bill.find()) norm = bill.sezione(); totalep.normalize((norm=='D') ? 'A' : 'D'); scdz.normalize(norm); _w_imp_pag = totalep.valore(); imp_scad = scdz.valore(); real a,b,c; TString k; look_in_cache(a,b,c,uns,unsnc,unsins,k); if (b > ZERO) // Scala le note di credito dalle scadenze { const real gap = b > imp_scad ? imp_scad : b; imp_scad -= gap; b -= gap; if (b > ZERO) unsnc.add(k,b,TRUE); else unsnc.remove(k); // Free some space when 0 reached. } if (a > ZERO && imp_scad > _w_imp_pag) { // Lo scalare dei non assegnati e' progressivo a partire dalla rata piu' vecchia. // Se ce n'e' in piu' vengono ignorati. const real gap = a > imp_scad ? imp_scad : a; _w_imp_pag += gap; a -= gap; if (a > ZERO) uns.add(k,a,TRUE); else uns.remove(k); // Free some space when 0 reached } if (c > ZERO) { const real gap = c > _w_imp_pag ? _w_imp_pag : c; _w_imp_pag -= gap; c -= gap; if (c > ZERO) unsins.add(k,c,TRUE); else unsins.remove(k); // Free some space when 0 reached } _w_imp_res = imp_scad - _w_imp_pag; } const char * TStampaScadenzario::tipi_tab(int tipo) { switch (tipo) { case 0: return TR("Altro"); break; case 1: return TR("Rimesse dirette"); break; case 2: return TR("Tratte"); break; case 3: return TR("Ricevute bancarie"); break; case 4: return TR("Cessioni"); break; case 5: return TR("Paghero'"); break; case 6: return TR("Lettere di acc."); break; case 7: return TR("Tratte accettate"); break; case 8: return TR("Rapp. interb. dir."); break; case 9: return TR("Bonifici"); break; default: return ""; break; } } bool TStampaScadenzario::preprocess_page(int file, int counter) // Se ritorna FALSE salta questa scadenza e va alla prossima. { const TRectype &rc = current_cursor()->curr(LF_SCADENZE); char tipoc = rc.get_char(SCAD_TIPOCF); // Tipo int gruppo = rc.get_int(SCAD_GRUPPO); // Gruppo int conto = rc.get_int(SCAD_CONTO); // Conto long codcf = rc.get_long(SCAD_SOTTOCONTO); // Codice Cliente/Fornitore/Conto int annop = rc.get_int(SCAD_ANNO); // Anno partita TString nump ( rc.get(SCAD_NUMPART)); // Nr partita int nrigap = rc.get_int(SCAD_NRIGA); // Nr riga int nratap = rc.get_int(SCAD_NRATA); // Nr rata TDate datascad = rc.get_date(SCAD_DATASCAD); // Data scadenza int tipo_pag = rc.get_int(SCAD_TIPOPAG); // Tipo di pagamento char ult_cla = rc.get_char(SCAD_ULTCLASS); // Ulteriore classificazione real imp_scad ; // Importo in scadenza (vale IMPORTO o // IMPORTOVAL a seconda sia stata impostata la // stampa in valuta. if (_end_printed && (file == LF_CLIFO || file == LF_PCON)) return FALSE; // Dopo aver stampato i totali finali non deve rientrare per stampare // LF_CLIFO o LF_PCON if (_end_printed) { // Qui controlla se ci sono totali da stampare TAssoc_array& tp = (TAssoc_array&)_tl[2]; if (tp.items() == 0) return FALSE; } if (file == LF_SCADENZE && !_end_printed) { TBill bill(rc); if (!_m->selected(bill)) return FALSE; _descrizione->restart(); if (scad_changed(tipoc,gruppo,conto,codcf,annop,nump)) { TRectype rp(LF_PARTITE); rp.zero(); rp.put(PART_TIPOCF,tipoc); rp.put(PART_GRUPPO,gruppo); rp.put(PART_CONTO,conto); rp.put(PART_SOTTOCONTO,codcf); rp.put(PART_ANNO,annop); rp.put(PART_NUMPART,nump); if (_p) delete _p; _p = new TPartita(rp); TString k; // compone la chiave dei tassoc_array dentro a _uns_cache k << tipoc << gruppo ; k << conto << codcf; k << annop << nump; if (!in_cache(k)) calcola_unassigned(k); TRiga_partite& row = _p->riga(nrigap); _datareg = row.get_date(PART_DATAREG).string(brief); _datadoc = row.get_date(PART_DATADOC).string(brief); _numdoc = row.get(PART_NUMDOC); _protiva.format("%5ld",row.get_long(PART_PROTIVA)); *_descrizione = row.get(PART_DESCR); _codval = row.get(PART_CODVAL); //Per indicare che non e' indicata la valuta o e' LIRA (se la stampa in valuta is disabled) if (_codval.empty() || !_stvaluta) _codval = " "; if (_descrizione->items() == 0) // Se sulla partita non c'e' descrizione allora va leggerla sulla causale. *_descrizione = cache().get(LF_CAUSALI, row.get(PART_CODCAUS), CAU_DESCR); } calcola_pagamenti(imp_scad,nrigap,nratap, bill); // Se la rata e' stata saldata e non e' abilitato il flag di stampa // oppure l'importo in scadenza e' 0 allora salta alla prossima scadenza if (!_ratesald && _w_imp_res == 0.0) return FALSE; _annopart.format("%d",annop); _annopart.ltrim(2); _rimdir=""; _riba=""; _altri=""; _imp_pag = ""; const bool print_in_valuta = _stvaluta && is_true_value(_codval); print_real(_imp_scad, imp_scad, print_in_valuta ? _codval : EMPTY_STRING); if (_w_imp_pag != ZERO) print_real(_imp_pag, _w_imp_pag, print_in_valuta ? _codval : EMPTY_STRING); if (_w_imp_res != ZERO) switch (tipo_pag) { case 1: // Rimesse dirette print_real(_rimdir, _w_imp_res, print_in_valuta ? _codval : EMPTY_STRING); break; case 2: // ri.ba / Tratte case 3: print_real(_riba, _w_imp_res, print_in_valuta ? _codval : EMPTY_STRING); break; default: // Altri print_real(_altri, _w_imp_res, print_in_valuta ? _codval : EMPTY_STRING); break; } } if (file==LF_CLIFO) { TString80 xxx(current_cursor()->curr(LF_CLIFO).get(CLI_RAGSOC)); *_ragsoc = xxx.strip_double_spaces(); } if (file ==LF_PCON) *_des_conto = current_cursor()->curr(LF_PCON).get(PCN_DESCR); // Se l'ordinamento principale e' per data scadenza stampa il totale del giorno e del mese if (_ordata && !_end_printed) if ((file == LF_SCADENZE && _tipost == tutti) || (file == LF_PCON && _tipost == altri) || (file ==LF_CLIFO && (_tipost == clienti || _tipost == fornitori))) { bool date_changed = false; if (_cur_data.ok()) date_changed = _cur_data != datascad; if (date_changed) { // Se la data di scadenza e' cambiata e non e' il primo record della relazione // allora stampa i totali del giorno. // Controlla poi se e' cambiato il mese, in caso affermativo stampa anche i // totali del mese e lo schema riepilogativo mensile const bool month_changed = _cur_data.month() != datascad.month(); for (int i=1; ilfile().set_curr(new TScadenza_rec); _rel1->add(LF_CLIFO,"TIPOCF=TIPOC|CODCF=SOTTOCONTO",1,0,SCADCLIFO_ALIAS); _cur1 = add_cursor(new TSorted_cursor(_rel1,"DATASCAD|SOTTOCONTO|ANNO|NUMPART|NRIGA|NRATA","",2)); // Per data scadenza + ragione sociale e' necessario un TSorted_cursor con update del file collegato: _cur11 = add_cursor(new TSorted_cursor(_rel1,"DATASCAD|UPPER(20->RAGSOC)|ANNO|NUMPART|NRIGA|NRATA","",2)); // Scadenze per CliFo (Codice & Ragione sociale) + data scadenza _cur2 = add_cursor(new TSorted_cursor(_rel1,"SOTTOCONTO|DATASCAD|ANNO|NUMPART|NRIGA|NRATA","",2)); _cur3 = add_cursor(new TSorted_cursor(_rel1,"UPPER(20->RAGSOC)|DATASCAD|ANNO|NUMPART|NRIGA|NRATA","",2)); _rel2 = new TRelation(LF_SCADENZE); // Scadenze per data scadenza + piano dei conti (Codice & Descrizione) _rel2->lfile().set_curr(new TScadenza_rec); _rel2->add(LF_PCON,"GRUPPO=GRUPPO|CONTO=CONTO|SOTTOCONTO=SOTTOCONTO",1,0,SCADPCON_ALIAS); _cur4 = add_cursor(new TSorted_cursor(_rel2,"DATASCAD|GRUPPO|CONTO|SOTTOCONTO|ANNO|NUMPART|NRIGA|NRATA","",2)); // Per data scadenza + descrizione e' necessario un TSorted_cursor con update del file collegato: _cur41 = add_cursor(new TSorted_cursor(_rel2,"DATASCAD|UPPER(19->DESCR)|ANNO|NUMPART|NRIGA|NRATA","",2)); // Scadenze per Conti (Codice & descrizione) + data scadenza _cur5 = add_cursor(new TSorted_cursor(_rel2,"GRUPPO|CONTO|SOTTOCONTO|DATASCAD|ANNO|NUMPART|NRIGA|NRATA","",2)); _cur6 = add_cursor(new TSorted_cursor(_rel2,"UPPER(19->DESCR)|DATASCAD|ANNO|NUMPART|NRIGA|NRATA","",2)); _rel3 = new TRelation(LF_SCADENZE); // Scadenze (Tutte) per data scadenza _rel3->lfile().set_curr(new TScadenza_rec); _cur7 = add_cursor(new TCursor(_rel3,"",2)); open_files(LF_TABCOM, LF_TAB, LF_CAUSALI, LF_PARTITE, LF_PAGSCA, 0); _pagsca = new TLocalisamfile(LF_PAGSCA); _descrizione = new TParagraph_string("",17); _ragsoc = new TParagraph_string("",17); _des_conto = new TParagraph_string("",17); _tl.add(new TAssoc_array);_tl.add(new TAssoc_array);_tl.add(new TAssoc_array);_tl.add(new TAssoc_array); _uns_cache.add(new TAssoc_array); // Pagamenti _uns_cache.add(new TAssoc_array); // Note di credito _uns_cache.add(new TAssoc_array); // Insoluti TConfig conf (CONFIG_DITTA,"cg"); _m = new TSelection_ext_mask("sc2200a"); _m->enable(F_VALUTA,conf.get_bool("GesVal")); enable_print_menu(); return TRUE; } bool TStampaScadenzario::user_destroy() { // // Color che di Printapp conoscon nulla, // evitar, dovrebber, il delete che trastulla // onde la nausea, ch'assale il tuo fardello, // mejo la new lasciar nel suo castello. // // Nota del trastullatore: // Mai fare la delete di un cursore usato // dalla printapp, poiche' e' lei stessa che // effettua tale operazione nella propria destroy(). // if (_rel1) delete _rel1; if (_rel2) delete _rel2; if (_rel3) delete _rel3; if (_pagsca) delete _pagsca; if (_descrizione) delete _descrizione; if (_des_conto) delete _des_conto; if (_ragsoc) delete _ragsoc; _tl.destroy(); _uns_cache.destroy(); _tm.destroy(); _tp.destroy(); if (_m) delete _m; // la delete di _tl viene fatta nel distruttore dell'applicazione. return TRUE; } bool TStampaScadenzario::set_print(int) { _m->reset(F_SORTBAN); _m->reset(F_CODAG); _m->reset(F_TIPOPAG); const bool ok = _m->run() == K_ENTER; if (ok) { _last_bank_rec = 0; _end_printed = FALSE; _totbank_printed = FALSE; reset_files(); reset_print(); // Inizializza i membri necessari al calcolo totali nel caso sia stato scelto l'ordine // primario secondo la data di scadenza. if (_m->get_who() == 'P') _tipost = altri; else if (_m->get_who() == 'C') _tipost = clienti; else _tipost = fornitori; _ordcod = _m->get_key() == 1; // Stampa ordinata per codice? _group_ban = _m->get_bool(F_SORTBAN); // Raggruppamento per banca di presentazione _codag = _m->get(F_CODAG); // codice agente selezionato _tipopag = _m->get_int(F_TIPOPAG); // tipo pagamento selezionato _cur_data = botime; _tm.destroy(); _tp.destroy(); // Totali per i prospetti for (int it=0; it < _tl.items(); it++) { TAssoc_array& aa = (TAssoc_array&) _tl[it]; aa.destroy(); // Totali lineari (tlg, tlm, tlp) } // Inizializza i membri necessari al calcolo totali nel caso sia stato scelto l'ordine // primario per codice/gr.co.so. ragione sociale/descrizione _cur_codcf = -1; _cur_gr=_cur_co = -1; // Per calcolare i totali nel caso l'ordine primario non sia per data scadenze // utilizzera' le variabili _tp_* per il totale generale e _tm_* per i singoli totali. // E' necessario resettare anche queste TParagraph_string... Puo' servire in futuro... *_ragsoc = ""; *_des_conto = ""; *_descrizione = ""; _ratesald = _m->get_bool(F_RATESALDATE); _ordata = _m->get_bool(F_ORDDATA); _stvaluta = _m->get_bool(F_VALUTA); _striepilogo = _m->get_bool(F_RIEPILOGO); _datai = (const char *)(_m->get(F_DATASCADENZAI)); _dataf = (const char *)(_m->get(F_DATASCADENZAF)); _datas = (const char *)(_m->get(F_DATASTAMPA)); // N.B I cursori sono tutti TSorted_cursor; alcuni di questi(_cur11 e _cur41) referenziano a campi di sort // presenti anche su altri file (LF_CLIFO o LF_PCON), percio' e' necessario che il metodo filtercursor() // (v. TCursor o TSorted_cursor) forzi un update della relazione ad ogni record che viene processato. // I cursori 1,2,4 e 6 sono TSorted_cursor anch'essi, siccome la funzione di filtro deve reperire il nr. // di record del file inerente alla selezione, e' necessario fare l'update ogni volta. // I cursori hanno tutti la stessa funzione di filtro, per la stampa della rate saldate. // L'unico TCursor e' _cur7, poiche' e' utilizzato per stampare solo i record di LF_SCADENZE. get_cursor(_cur1)->set_filterfunction(filter_func,TRUE); // Cursore 1: Datascad + Clifo (codice) get_cursor(_cur11)->set_filterfunction(filter_func,TRUE);// Cursore 1.1: Datascad + Clifo (ragione sociale) get_cursor(_cur2)->set_filterfunction(filter_func,TRUE); // Cursore 2: Clifo(codice) + Datascad get_cursor(_cur3)->set_filterfunction(filter_func,TRUE); // Cursore 3: Clifo(ragione sociale) + Datascad get_cursor(_cur4)->set_filterfunction(filter_func,TRUE); // Cursore 4: Datascad + PCon (codice) get_cursor(_cur41)->set_filterfunction(filter_func,TRUE);// Cursore 4.1: Datascad + PCon (descrizione) get_cursor(_cur5)->set_filterfunction(filter_func,TRUE); // Cursore 5: PCon (Codice) + Datascad get_cursor(_cur6)->set_filterfunction(filter_func,TRUE); // Cursore 6: PCon (descrizione) + Datascad get_cursor(_cur7)->set_filterfunction(filter_func); // Cursore 7: Datascad // Setta l'intervallo di data. Si puo' fare per tutti i cursori, poiche' // il file principale e' sempre LF_SCADENZE. TRectype da_data(LF_SCADENZE), a_data(LF_SCADENZE); da_data.put(SCAD_DATASCAD,_datai); a_data.put(SCAD_DATASCAD,_dataf); get_cursor(_cur1)->setregion(da_data,a_data); get_cursor(_cur11)->setregion(da_data,a_data); get_cursor(_cur2)->setregion(da_data,a_data); get_cursor(_cur3)->setregion(da_data,a_data); get_cursor(_cur4)->setregion(da_data,a_data); get_cursor(_cur41)->setregion(da_data,a_data); get_cursor(_cur5)->setregion(da_data,a_data); get_cursor(_cur6)->setregion(da_data,a_data); get_cursor(_cur7)->setregion(da_data,a_data); switch (_tipost) { case tutti: select_cursor(_cur7); add_file(LF_SCADENZE); break; case clienti: case fornitori: if (_ordata) // Ordine primario per data { // Controlla l'ordine secondario (codice o ragione sociale) if (_ordcod) // Per codice... { select_cursor(_cur1); if (_tipost==clienti) get_cursor(_cur1)->setfilter("(TIPOC=\"C\")"); else get_cursor(_cur1)->setfilter("(TIPOC=\"F\")"); } else { select_cursor(_cur11); // Per ragione sociale if (_tipost==clienti) get_cursor(_cur11)->setfilter("(TIPOC=\"C\")"); else get_cursor(_cur11)->setfilter("(TIPOC=\"F\")"); } } else // Ordine primario per codice o ragione sociale { if (_ordcod) // Codice... { select_cursor(_cur2); if (_tipost==clienti) get_cursor(_cur2)->setfilter("(TIPOC=\"C\")"); else get_cursor(_cur2)->setfilter("(TIPOC=\"F\")"); } else // Ragione sociale { select_cursor(_cur3); if (_tipost==clienti) get_cursor(_cur3)->setfilter("(TIPOC=\"C\")"); else get_cursor(_cur3)->setfilter("(TIPOC=\"F\")"); } } add_file(LF_SCADENZE); add_file(LF_CLIFO,LF_SCADENZE); break; case altri: if (_ordata) // Ordine primario per data { // Controlla l'ordine secondario (Codice o descrizione) if (_ordcod) // Per codice ... { select_cursor(_cur4); get_cursor(_cur4)->setfilter("(TIPOC=\"\")"); // Filtro per i conti normali! } else { select_cursor(_cur41); // Per descrizione. get_cursor(_cur41)->setfilter("(TIPOC=\"\")"); } } else // Ordine primario per codice o descrizione { if (_ordcod) // Codice... { select_cursor(_cur5); get_cursor(_cur5)->setfilter("(TIPOC=\"\")"); // Filtro per i conti normali! } else // Descrizione { select_cursor(_cur6); get_cursor(_cur6)->setfilter("(TIPOC=\"\")"); // Filtro per i conti normali! } } add_file(LF_SCADENZE); add_file(LF_PCON,LF_SCADENZE); break; default: break; } if (current_cursor()->is_sorted()) // Should always be true! { TSorted_cursor* sorcur = (TSorted_cursor*)current_cursor(); TToken_string sortexpr = sorcur->get_order(); const bool has_ban = sortexpr.starts_with(SCAD_CODABIPR); if (_group_ban != has_ban) { if (_group_ban) sortexpr.insert("CODABIPR|CODCABPR|"); else sortexpr.ltrim(18); sorcur->change_order(sortexpr); } _last_ban.cut(0); // Azzera ultima banca stampata } } if (_p) { delete _p; // Questo deve essere cancellato, altrimenti rimane in memoria, _p = NULL; // provocando casini al prossimo "giro" } TAssoc_array& a =(TAssoc_array&) _uns_cache[0]; TAssoc_array& b =(TAssoc_array&) _uns_cache[1]; a.destroy(); b.destroy(); // Libera i TAssoc_array impiegati. return ok; } void TStampaScadenzario::print_header() // Setta le righe dell'intestazione { int soh = 1; const long firm = get_firm(); const TRectype & ditta = cache().get(LF_NDITTE, firm); reset_header (); TString s; s = ditta.get(NDT_RAGSOC); TString data = _datas.string(); TString datai = _datai.string(); TString dataf = _dataf.string(); switch (_tipost) { case fornitori: case clienti: { TString rw(201); TString s1,s2; set_header (soh++, "Ditta : %ld %s@148gData@153g%s @190gPag. @#", firm, (const char *)s, (const char *)data); if (_tipost==fornitori) { set_header(soh++,FR("@72g** SCADENZARIO FORNITORI **")); s1 = "Ns."; s2 = "Banca"; } else { set_header(soh++,FR("@73g** SCADENZARIO CLIENTI **")); s1 =""; s2 = ""; } set_header (soh++,FR("@64gPer il periodo dal %s al %s"),(const char*)datai,(const char*)dataf); if (_codag.not_empty()) set_header (soh++,FR("@bAgente: %s %s@r"),(const char*)_codag,(const char*)_m->get(F_CODAG_D)); if (_tipopag != 0) { TList_field& fld_tipopag = (TList_field&) _m->field(F_TIPOPAG); TToken_string pagam(fld_tipopag.get_values()); set_header (soh++,FR("@bTipo pagamento: %d %s@r"),_tipopag, (const char*)pagam.get(_tipopag)); } rw.fill('_'); set_header(soh++, (const char *) rw); set_header(soh++,FR("@28gRif.@38gData@47gData@77gCd/Tp@91g%s"),(const char*)s1); set_header(soh++,FR("Codice@9gRagione sociale@28gpartita@38gscadenza@47gRegistr." "@56gDescrizione@77gPag.@86gRata@91g%s@97gVal." "@106gImp. in sca.@125gImp. pagati@144gRimesse dir.@163gRi.ba./Tratte@182gAltri"), (const char*)s2); set_header(soh++,FR("@28gData e Nr doc. @46gProt. IVA")); set_header(soh++,(const char *)rw); break; } case altri: // Piano dei conti { TString rw(201); set_header (soh++, FR("Ditta : %ld %s@152gData@157g%s @190gPag. @#"), firm, (const char *)s, (const char *)data); set_header(soh++,FR("@79g** SCADENZARIO **")); set_header (soh++,FR("@66gPer il periodo dal %s al %s"),(const char*)datai,(const char*)dataf); if (_codag.not_empty()) set_header (soh++,FR("@bAgente: %s %s@r"),(const char*)_codag,(const char*)_m->get(F_CODAG_D)); if (_tipopag != 0) { TList_field& fld_tipopag = (TList_field&) _m->field(F_TIPOPAG); TToken_string pagam(fld_tipopag.get_values()); set_header (soh++,FR("@bTipo pagamento: %d %s@r"),_tipopag, (const char*)pagam.get(_tipopag)); } rw.fill('_'); set_header(soh++, (const char *) rw); set_header(soh++,FR("@33gRif.@43gData@53gData@82gCd/Tp")); set_header(soh++,FR("Gr. Co. So.@16gDescrizione@33gpartita@43gscadenza@53gRegistr." "@61gDescrizione@82gPag.@89gRata@97gVal." "@106gImp. in sca.@125gImp. pagati@144gRimesse dir.@163gRi.ba./Tratte@182gAltri")); set_header(soh++,FR("@36gData e Nr doc. @54gProt. IVA")); set_header(soh++,(const char *)rw); break; } default: break; } set_header(soh,""); } void TStampaScadenzario::set_page_clifo(int nriga) // Setta le righe per stampare le scadenze clienti/fornitori { if (_group_ban) print_intestazione_banca(nriga); set_row(nriga++,""); set_row(nriga,"@b#6t@r",&_cur_codcf_s); set_row(nriga,"@b@9g#a@r",_ragsoc); set_row(nriga,"@28g#2t",&_annopart); set_row(nriga,"@30g/@7s",FLD(LF_SCADENZE,SCAD_NUMPART)); set_row(nriga,"@38g@d",FLD(LF_SCADENZE,SCAD_DATASCAD)); set_row(nriga,"@47g#t",&_datareg); set_row(nriga,"@56g#a",_descrizione); set_row(nriga,"@77g@4,rs/@1n",FLD(LF_SCADENZE,SCAD_CODPAG),FLD(LF_SCADENZE,SCAD_TIPOPAG)); set_row(nriga,"@86g@4n",FLD(LF_SCADENZE,SCAD_NRATA)); if (_tipost == fornitori) set_row(nriga,"@91g@5pn",FLD(LF_SCADENZE,SCAD_CODABIPR,"@@@@@")); set_row(nriga,"@97g#t", &_codval); set_row(nriga,"@101g#18t",&_imp_scad); set_row(nriga,"@120g#18t",&_imp_pag); set_row(nriga,"@139g#18t",&_rimdir); // rimesse dirette set_row(nriga,"@158g#18t",&_riba); // Ri.ba. / tratte set_row(nriga++,"@177g#18t",&_altri); // Altri tipi di pagamento set_row(nriga,"@31g#t",&_datadoc); set_row(nriga,"@40g#t",&_numdoc); set_row(nriga,"@49g#-5t",&_protiva); } void TStampaScadenzario::set_page_pcon(int nriga) // Setta le righe per stampare le scadenze degli altri conti. { if (_group_ban) print_intestazione_banca(nriga); set_row(nriga++,""); set_row(nriga,"@b#3t@5g#3t@9g#6t@r",&_cur_gr_s,&_cur_co_s,&_cur_codcf_s); set_row(nriga,"@b@16g#a@r",_des_conto); set_row(nriga,"@33g#2t/@7s",&_annopart,FLD(LF_SCADENZE,SCAD_NUMPART)); set_row(nriga,"@43g@d@53g#t",FLD(LF_SCADENZE,SCAD_DATASCAD),&_datareg); set_row(nriga,"@61g#a",_descrizione); set_row(nriga,"@82g@4,rs/@1n@89g@4n",FLD(LF_SCADENZE,SCAD_CODPAG),FLD(LF_SCADENZE,SCAD_TIPOPAG), FLD(LF_SCADENZE,SCAD_NRATA)); set_row(nriga,"@97g#t", &_codval); set_row(nriga,"@101g#18t",&_imp_scad); set_row(nriga,"@120g#18t",&_imp_pag); set_row(nriga,"@139g#18t",&_rimdir); // rimesse dirette set_row(nriga,"@158g#18t",&_riba); // Ri.ba. / tratte set_row(nriga++,"@177g#17t",&_altri); // Altri tipi di pagamento set_row(nriga,"@36g#t@45g#t@54g#-5t",&_datadoc,&_numdoc,&_protiva); } void TStampaScadenzario::set_page(int file, int counter) { print_header(); switch (_tipost) { case fornitori: case clienti: if (file == LF_CLIFO) set_page_clifo(1); break; case altri: if (file == LF_PCON) set_page_pcon(1); break; default: break; } } void TStampaScadenzario::print_rows_riepilogo(int& nriga, bool type, TAssoc_array& tot) { TString_array as; TAssoc_array& t = (type ? _tp : _tm); const int items = t.items(); t.get_keys(as); as.sort(); for (int i=0; i < items; i++) { const TString& k = as.row(i); real& v = (real&)t[k]; if (v.is_zero()) continue; TString16 val = k.right(3); const int tipo = k[0]-'0'; const char ult = k[1]; TString80 ult_class; if (ult > ' ') { const char cod[3] = { tipo+'0', ult, '\0' }; ult_class = cache().get("%CLR", cod).get("S0"); ult_class.cut(27); } const bool stampa_in_valuta = _stvaluta && !val.blank(); TString80 value; print_real(value, v, stampa_in_valuta ? val : "_FIRM"); set_row(nriga++,"@0g! %s@25g! %s@55g! %s@61g!@64g%18s@82g!", tipi_tab(tipo), (const char*)ult_class, (const char*)val, (const char*)value); // Cerca la valuta "val" nell'assoc array dei totali per il prospetto if (tot.is_key(val)) { real& tv = (real&) tot[val]; tv += v; tot.add(val,tv,TRUE); } else // Se non esiste aggiunge il valore tot.add(val,v); } } void TStampaScadenzario::print_riepilogo(int &nriga, bool type) // Setta le righe di stampa per lo schema riepilogativo con ordinamento primario per data // Con type == 1 stampa il riepilogo del periodo; viceversa quello del mese. { TString s(83); TAssoc_array totali; // Assoc array per i totali distinti per valuta TString_array as; s.fill('-', 83); nriga++; set_row(nriga++,"%s",(const char *)s); if (!type) { if (_ordata) { set_row(nriga++,"@0g! %s@82g!",itom(_cur_data.month())); set_row(nriga++,"%s",(const char*)s); } } else { set_row(nriga,FR("!@5gTotali dal %s al "),_datai.string(brief)); set_row(nriga++,"%s@82g!",_dataf.string(brief)); set_row(nriga++,"%s",(const char *)s); } print_rows_riepilogo(nriga, type, totali); totali.get_keys(as); as.sort(); const int items = totali.items(); TString val, value; for (int i=0; i < items; i++) { val = as.row(i); const bool stampa_in_valuta = _stvaluta && is_true_value(val); const real& tot = (real&)totali[val]; print_real(value, tot, stampa_in_valuta ? val : EMPTY_STRING); if (tot != ZERO) { if (i == 0) set_row(nriga++,"%s",(const char *)s); // Se c'e' almeno un totale != 0 allora stampa il separe' set_row(nriga++,"@55g! %s@61g!@64g%18s@82g!",(const char*) val, (const char*) value); } else { if (!is_true_value(val)) val = TCurrency::get_firm_val(); set_row(nriga++,FR("! Partite pareggiate in %s. @82g!"),(const char*) val); } } set_row(nriga++,"%s",(const char *)s); } void TStampaScadenzario::print_rows_totali(int &nriga, tipo_pe p) { int index = 0; // Default of DAILY switch (p) { case monthly: case single: index = 1; break; case period: index = 2; break; case bank: index = 3; break; default: break; } TAssoc_array& xassoc = (TAssoc_array&) _tl[index]; TString_array as; const int items = xassoc.items(); xassoc.get_keys(as); as.sort(); TString k, value; for (int i=0; i < items; i++) { k = as.row(i); // Chiave di ordinamento(valuta) const bool stampa_in_valuta = _stvaluta && is_true_value(k); _LinearTotal& v = (_LinearTotal&)xassoc[k]; if (is_true_value(k)) set_row(nriga,"@97g%3s",(const char*)k); if (!stampa_in_valuta) k.cut(0); print_real(value, v._is, k); if (v._is != ZERO) set_row(nriga,"@101g%18s",(const char*) value); print_real(value, v._ip, k); if (v._ip != ZERO) set_row(nriga,"@120g%18s",(const char*) value); print_real(value, v._rd, k); if (v._rd != ZERO) set_row(nriga,"@139g%18s",(const char*) value); print_real(value, v._ri, k); if (v._ri != ZERO) set_row(nriga,"@158g%18s",(const char*) value); print_real(value, v._al, k); if (v._al != ZERO) set_row(nriga,"@177g%18s",(const char*) value); set_row(++nriga,""); } set_row(++nriga,""); } void TStampaScadenzario::print_totali(int &nriga, bool month_changed, bool ended) // Setta le righe per stampare i totali (giorno e mese) delle scadenze clienti/fornitori // Ordinamento primario per data! { set_row(nriga,FR("@36g** TOTALI DEL @51g%s"),_cur_data.string(brief)); print_rows_totali(nriga, daily); if (month_changed) { set_row(nriga,FR("@36g** TOTALI DI @51g%s"),itom(_cur_data.month())); print_rows_totali(nriga, monthly); if (_striepilogo) print_riepilogo(nriga,FALSE); } if (ended) { if (_group_ban) { print_totali_bank(nriga); set_row(nriga++,""); } set_row(nriga++,""); set_row(nriga,FR("@36g** TOTALI PERIODO")); print_rows_totali(nriga, period); if (_striepilogo) print_riepilogo(nriga,TRUE); set_row(nriga++,"");set_row(nriga++,""); set_row(nriga++,"");set_row(nriga++,""); } } void TStampaScadenzario::print_totali_c(int &nriga, bool ended) // Setta le righe per stampare i totali delle scadenze clienti/fornitori/conti // Ordinamento primario per codice o ragione sociale! { if (_tipost==clienti) set_row(nriga,FR("@70g** TOTALE CLIENTE")); else if (_tipost ==fornitori) set_row(nriga,FR("@70g** TOTALE FORNITORE")); else // altri... set_row(nriga,FR("@70g** TOTALE CONTO")); print_rows_totali(nriga, single); if (_striepilogo) print_riepilogo(nriga,FALSE); if (ended) { if (_group_ban) { print_totali_bank(nriga); set_row(nriga++,"");set_row(nriga++,""); } set_row(nriga,FR("@70g** TOTALE GENERALE")); print_rows_totali(nriga, period); if (_striepilogo) print_riepilogo(nriga,TRUE); set_row(nriga++,"");set_row(nriga++,""); set_row(nriga++,"");set_row(nriga++,""); } } void TStampaScadenzario::print_totali_bank(int &nriga) // Setta le righe per stampare i totali della banca // Ordinamento primario per codice o ragione sociale! { if (!real::is_null(_last_ban)) { if (_ordata) // Errore 158 - Non stampa il totale del giorno se cambia solo la banca e non il giorno { const TRectype &rc = current_cursor()->curr(LF_SCADENZE); const TDate datascad = rc.get(SCAD_DATASCAD); if (datascad == _cur_data) // Non e' cambiato il giorno { nriga++; // Salto una riga print_totali(nriga, true, false); // Stampa totali del giorno e del mese ((TAssoc_array&)_tl[0]).destroy(); // Azzera totali del giorno ((TAssoc_array&)_tl[1]).destroy(); // Azzera totali del mese } } nriga++; if (_ordata) set_row(nriga,FR("@36g** TOTALI BANCA")); else set_row(nriga,FR("@70g** TOTALE BANCA")); print_rows_totali(nriga, bank); _totbank_printed = true; } } void TStampaScadenzario::print_intestazione_banca(int &nriga) { const TRectype &rc = current_cursor()->curr(LF_SCADENZE); const TString8 abi = rc.get(SCAD_CODABIPR); const TString8 cab = rc.get(SCAD_CODCABPR); TString16 curr_ban; curr_ban << abi << cab; bool print_bank = false; if (curr_ban != _last_ban) { _last_ban = curr_ban; if (abi != "00000") { _desc_ban.cut(0) << abi << ' ' << cab; _desc_ban << ' ' << cache().get("%BAN", abi, "S0"); if (cab > 0) _desc_ban << " - " << cache().get("%BAN", _last_ban, "S0"); } else _desc_ban = FR("NON INDICATA"); _last_bank_rec = current_cursor()->pos(); print_bank = true; } else { print_bank = current_cursor()->pos() == _last_bank_rec; } if (print_bank) { // stampa totali banca precedente if (_last_bank_rec != 0) print_totali_bank(nriga); set_row(nriga++, ""); set_row(nriga++, FR("@bBANCA DI PRESENTAZIONE %s@r"), (const char*)_desc_ban); set_row(nriga++, ""); } } TStampaScadenzario::TStampaScadenzario() { _rel1=_rel2=_rel3=NULL; _p = NULL; } int sc2200(int argc, char** argv) { TStampaScadenzario app; app.run(argc, argv, FR("Stampa Scadenzario")); return 0; }