diff --git a/sc/sc2200.cpp b/sc/sc2200.cpp index e98a25268..6a5ff5d13 100755 --- a/sc/sc2200.cpp +++ b/sc/sc2200.cpp @@ -1,1263 +1,1267 @@ -#ifndef __PRINTAPP_H -#include -#endif - -#ifndef __CONFIG_H -#include -#endif - -#ifndef __ASSOC_H -#include -#endif - -#ifndef __UTILITY_H -#include -#endif - -#ifndef __SALDACON_H -#include "../cg/saldacon.h" -#endif - -#ifndef __DITTE_H -#include -#endif - -#ifndef __CLIFO_H -#include -#endif - -#ifndef __PCONTI_H -#include -#endif - -#ifndef __PARTITE_H -#include -#endif - -#ifndef __SCADENZE_H -#include -#endif - -#ifndef _FLD_CAUS_H -#include -#endif - -#include - -#include "sc2.h" -#include "sc2200.h" -#include "sc2201.h" - -#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}; - -const char * tipi_tab[10] = {"Altro","Rimesse dirette","Tratte","Ricevute bancarie","Cessioni","Paghero'", - "Lettere di acc.","Tratte accettate","Rapp. interb. dir.","Bonifici"} ; - -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 *_caus, *_partite, *_pagsca; // File delle causali, serve per reperire le descrizioni, nel caso non ci siano sul file parite - 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 - 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; - // 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. - - 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. - friend 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 - // 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); - // Totalizza i pagamenti non assegnati per la partita corrente (NB si spera che siano tutti nella stessa valuta) - bool in_cache(TString& k); // ritorna vero se ci sono gia' non assegnati in _uns_cache; - void look_in_cache(real& a, real& b, TAssoc_array& uns, TAssoc_array& unsnc, TString& k); - void calcola_unassigned(TString& k); - void calcola_pagamenti(real& imp_scad, int riga, int rata); // calcola i pagamenti effettuati per questa rata e il residuo eventuale - - TStampaScadenzario(); -}; - -inline TStampaScadenzario& app() {return (TStampaScadenzario&)main_app();} - -bool filter_func(const TRelation *r) -{ // Filtro per rate saldate: se e' saldata e' ok solo quando - bool rt = FALSE; // e' abilitato il flag; se non e' saldata va sempre bene. - TLocalisamfile* scad = &(r->lfile(LF_SCADENZE)); - bool saldata = scad->get_bool(SCAD_PAGATA); - - if (!saldata || (saldata && app()._ratesald)) - { - rt=TRUE; - } - return rt; -} - -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; - 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::in_cache(TString& k) -{ - int rt = FALSE; - TAssoc_array& uns = (TAssoc_array&) _uns_cache[0]; - TAssoc_array& unsnc = (TAssoc_array&) _uns_cache[1]; - if (uns.is_key(k) || unsnc.is_key(k)) rt =TRUE; - return rt; -} - -void TStampaScadenzario::calcola_unassigned(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]; - TRecord_array& ra = _p->unassigned(); - real a,b; - a = 0.0; - b = 0.0; - - 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); - if (sum.get_int(PART_TIPOMOV) == 2) // Is it a credit note ? - b += rec.get_real(field); - else - a += rec.get_real(field); - } - if (a != 0.0) // Aggiungilo a TAssoc_array dei non assegnati - uns.add(k,a,TRUE); - if (b != 0.0) // Aggiungilo a TAssoc_array delle note di credito - unsnc.add(k,b,TRUE); -} - -void TStampaScadenzario::look_in_cache(real& a, real& b, TAssoc_array& uns, TAssoc_array& unsnc, TString& k) -//Estrae dai tassoc_array i valori, relativi alla partita corrente, di uns e unsnc, mettendoli in a e b -{ - a = 0.0; b = 0.0; - 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_str(PART_NUMPART); - if (uns.is_key(k)) a = (real&)uns[k]; - if (unsnc.is_key(k)) b = (real&)unsnc[k]; -} - -void TStampaScadenzario::calcola_pagamenti(real& imp_scad, int riga, int rata) -{ - TAssoc_array& uns = (TAssoc_array&) _uns_cache[0]; - TAssoc_array& unsnc = (TAssoc_array&) _uns_cache[1]; - 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,7); // 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 int tipomov = sum.get_int(PART_TIPOMOV); - switch (tipomov) - { - case 5: // Insoluto (aumenta scdz) - scdz += TImporto(sez,pag.get_real(field)); - break; - case 2: // Nota di credito assegnata (storna da scdz) - scdz -= TImporto(sez,pag.get_real(field)); - break; - default: - break; - } - } - char norm = 'D'; - if (_tipost == fornitori) norm = 'A'; - totalep.normalize(norm); scdz.normalize(norm); - _w_imp_pag = totalep.valore(); - imp_scad = scdz.valore(); - real a,b; - TString k; k.cut(0); - look_in_cache(a,b,uns,unsnc,k); - if (b > 0.0) // Scala le note di credito dalle scadenze - { - real gap = (b > imp_scad ? imp_scad : b); - imp_scad -= gap; - b -= gap; - if (b > 0.0) - unsnc.add(k,b,TRUE); - else - unsnc.remove(k); // Free some space when 0 reached. - } - if (a > 0.0 && 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. - real gap = (a > imp_scad ? imp_scad : a); - _w_imp_pag += gap; - a -= gap; - if (a > 0.0) - uns.add(k,a,TRUE); - else - uns.remove(k); // Free some space when 0 reached - } - _w_imp_res = imp_scad - _w_imp_pag; -} - - -bool TStampaScadenzario::preprocess_page(int file, int counter) -// Se ritorna FALSE salta questa scadenza e va alla prossima. -{ - 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) - { - TCursor_sheet& cs = _m->cur_sheet(); // Sheet di selezione (CLI/FO/PCON) - TCursor* c = cs.cursor(); - TRectype& rec = c->curr(); - if (_tipost == clienti || _tipost == fornitori) - rec = current_cursor()->curr(LF_CLIFO); - else - if (_tipost == altri) - rec = current_cursor()->curr(LF_PCON); - if (!cs.checked(c->read(_isequal))) // Se non e' stato selezionato salta alla prossima scdz - 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(_p->first()); - _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. - _caus->zero(); _caus->put(CAU_CODCAUS,row.get(PART_CODCAUS)); - if (_caus->read() == NOERR) - *_descrizione = _caus->get(CAU_DESCR); - } - } - calcola_pagamenti(imp_scad,nrigap,nratap); - if (_w_imp_res == 0.0 && ! _ratesald - || imp_scad == 0.0) // Se la rata e' stata saldata e non e' abilitato il flag di stampa - return FALSE; // oppure l'importo in scadenza e' 0 allora salta alla prossima scadenza - _annopart.format("%d",annop); - _annopart.ltrim(2); - _rimdir=""; - _riba=""; - _altri=""; - _imp_pag = ""; - if (_stvaluta && _codval != " ") - { - _imp_scad = imp_scad.string(".2"); - if (_w_imp_pag != 0.0) - _imp_pag=_w_imp_pag.string(".2"); - } - else - { - _imp_scad=imp_scad.string("."); - if (_w_imp_pag != 0.0) - _imp_pag=_w_imp_pag.string("."); - } - switch (tipo_pag) - { - case 1: // Rimesse dirette - if (_w_imp_res != 0.0) - { - if (_stvaluta && _codval != " ") _rimdir = _w_imp_res.string(".2"); - else _rimdir=_w_imp_res.string("."); - } - break; - case 2: // ri.ba / Tratte - case 3: - if (_w_imp_res != 0.0) - { - if (_stvaluta && _codval != " ") _riba = _w_imp_res.string(".2"); - else _riba=_w_imp_res.string("."); - } - break; - default: // Altri - if (_w_imp_res != 0.0) - { - if (_stvaluta && _codval != " ") _altri = _w_imp_res.string(".2"); - else _altri=_w_imp_res.string("."); - } - break; - } - } - - if (file==LF_CLIFO) - { - TString xxx(current_cursor()->curr(LF_CLIFO).get(CLI_RAGSOC)); - *_ragsoc = xxx.strip_d_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))) - { - if (_cur_data != botime && _cur_data != datascad) - { - // 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 - bool month_changed = _cur_data.month() != datascad.month(); - - for (int n=1; nadd(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->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 - _cur7 = add_cursor(new TCursor(_rel3,"",2)); - - _caus = new TLocalisamfile(LF_CAUSALI); - _partite = new TLocalisamfile(LF_PARTITE); - _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); - _uns_cache.add(new TAssoc_array);_uns_cache.add(new TAssoc_array); - 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 (_caus) - delete _caus; - if (_partite) - delete _partite; - 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) -{ - bool rt=FALSE,ok=FALSE; - KEY t; - while (!ok) - { - if ((t=_m->run())==K_ENTER) - { - if ( !_m->cur_sheet().checked()) - error_box("Non e' stata effettuata alcuna selezione."); - else - ok=TRUE; - } - else ok=TRUE; - } - - switch (t) - { - case K_ENTER: - { - _end_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; - if (_m->get_key() == 1) _ordcod = TRUE; - else _ordcod = FALSE; - _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.zero(); - a_data.zero(); - 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; - } - rt=TRUE; - break; - } - default: - break; - } - 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 rt; -} - -void TStampaScadenzario::print_header() -// Setta le righe dell'intestazione -{ - int soh = 1; - const long firm = get_firm(); - - reset_header (); - TLocalisamfile ditte(LF_NDITTE); - ditte.zero(); - ditte.put(NDT_CODDITTA, firm); - ditte.read(); - if (ditte.bad()) ditte.zero(); - - TString s; - s = ditte.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++,"@72g** SCADENZARIO FORNITORI **"); - s1 = "Ns."; s2 = "Banca"; - } - else - { - set_header(soh++,"@73g** SCADENZARIO CLIENTI **"); - s1 =""; s2 = ""; - } - set_header (soh++,"@64gPer il periodo dal %s al %s",(const char*)datai,(const char*)dataf); - rw.fill('-'); - set_header(soh++, (const char *) rw); - set_header(soh++,"@28gRif.@38gData@47gData@77gCd/Tp@91g%s",(const char*)s1); - set_header(soh++,"Codice@9gRagione sociale@28gpartita@38gscadenza@47gRegistr." - "@56gDescrizione@77gPag.@86gRata@91g%s@97gVal." - "@106gImp. in sca.@124gImp. pagati@142gRimesse dir.@160gRi.ba./Tratte@178gAltri",(const char*)s2); - set_header(soh++,"@28gData e Nr doc. @46gProt. IVA"); - set_header(soh++,(const char *)rw); - break; - } - case altri: // Piano dei conti - { - TString rw(201); - set_header (soh++, "Ditta : %ld %s@152gData@157g%s @190gPag. @#", - firm, (const char *)s, (const char *)data); - set_header(soh++,"@79g** SCADENZARIO **"); - set_header (soh++,"@66gPer il periodo dal %s al %s",(const char*)datai,(const char*)dataf); - rw.fill('-'); - set_header(soh++, (const char *) rw); - set_header(soh++,"@33gRif.@43gData@53gData@82gCd/Tp"); - set_header(soh++,"Gr. Co. So.@16gDescrizione@33gpartita@43gscadenza@53gRegistr." - "@61gDescrizione@82gPag.@89gRata@97gVal." - "@106gImp. in sca.@124gImp. pagati@142gRimesse dir.@160gRi.ba./Tratte@178gAltri"); - - set_header(soh++,"@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 -{ - 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#17t",&_imp_scad); - set_row(nriga,"@119g#17t",&_imp_pag); - set_row(nriga,"@137g#17t",&_rimdir); // rimesse dirette - set_row(nriga,"@155g#17t",&_riba); // Ri.ba. / tratte - set_row(nriga++,"@173g#17t",&_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. -{ - 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#17t",&_imp_scad); - set_row(nriga,"@119g#17t",&_imp_pag); - set_row(nriga,"@137g#17t",&_rimdir); // rimesse dirette - set_row(nriga,"@155g#17t",&_riba); // Ri.ba. / tratte - set_row(nriga++,"@173g#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) -{ - int nriga =1; - print_header(); - switch (_tipost) - { - case fornitori: - case clienti: - if (file == LF_CLIFO) - set_page_clifo(nriga); - break; - case altri: - if (file == LF_PCON) - set_page_pcon(nriga); - 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++) - { - TString k (as.row(i)); - TString val(k.right(3)); - TString value; - real& v = (real&)t[k]; - const int tipo = k[0]-'0'; - const char ult = k[1]; - - if (_stvaluta && val != " ") value = v.string(".2"); - else value = v.string("."); - if (v != 0.0) - set_row(nriga++,"@0g!@3g%s@25g!@27g%c@32g!@34g%s@39g!@42g%17s@59g!", - tipi_tab[tipo], ult, (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(60); - TAssoc_array totali; // Assoc array per i totali distinti per valuta - TString_array as; - - s.fill('-'); - nriga++; - set_row(nriga++,"%s",(const char *)s); - if (!type) - { - if (_ordata) - { - set_row(nriga++,"@0g!@2g%s@59g!",itom(_cur_data.month())); - set_row(nriga++,"%s",(const char*)s); - } - } else - { - set_row(nriga,"!@5gTotali dal %s al ",_datai.string(brief)); - set_row(nriga++,"%s@59g!",_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(); - for (int i=0; i < items; i++) - { - TString val(as.row(i)); - TString value; - real& tot = (real&)totali[val]; - if (_stvaluta && val != " ") value = tot.string(".2"); - else value = tot.string("."); - - if (tot != 0.0) - { - if (i == 0) - set_row(nriga++,"%s",(const char *)s); // Se c'e' almeno un totale != 0 allora stampa il separe' - set_row(nriga++,"!@34g%s@42g%17s@59g!",(const char*) val, (const char*) value); - } - else - { - if (val == " ") val = "LIT"; - set_row(nriga++,"! Nessun valore totale in %s. @59g!",(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; - default: - break; - } - TAssoc_array& xassoc = (TAssoc_array&) _tl[index]; - TString_array as; - const int items = xassoc.items(); - xassoc.get_keys(as); - as.sort(); - for (int i=0; i < items; i++) - { - TString k(as.row(i)); // Chiave di ordinamento(valuta) - TString value; - _LinearTotal& v = (_LinearTotal&)xassoc[k]; - if (k != " ") - set_row(nriga,"@97g%3s",(const char*)k); - if (_stvaluta && k != " ") value = v._is.string(".2"); - else value = v._is.string("."); - if (v._is != 0.0) - set_row(nriga,"@101g%17s",(const char*) value); - if (_stvaluta && k != " ") value = v._ip.string(".2"); - else value = v._ip.string("."); - if (v._ip != 0.0) - set_row(nriga,"@119g%17s",(const char*) value); - if (_stvaluta && k != " ") value = v._rd.string(".2"); - else value = v._rd.string("."); - if (v._rd != 0.0) - set_row(nriga,"@137g%17s",(const char*) value); - if (_stvaluta && k != " ") value = v._ri.string(".2"); - else value = v._ri.string("."); - if (v._ri != 0.0) - set_row(nriga,"@155g%17s",(const char*) value); - if (_stvaluta && k != " ") value = v._al.string(".2"); - else value = v._al.string("."); - if (v._al != 0.0) - set_row(nriga,"@173g%17s",(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,"@36g** TOTALI DEL @51g%s",_cur_data.string(brief)); - print_rows_totali(nriga, daily); - if (month_changed) - { - set_row(nriga,"@36g** TOTALI DI @51g%s",itom(_cur_data.month())); - print_rows_totali(nriga, monthly); - if (_striepilogo) print_riepilogo(nriga,FALSE); - } - if (ended) - { - set_row(nriga++,""); - set_row(nriga,"@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,"@70g** TOTALE CLIENTE"); - else - if (_tipost ==fornitori) - set_row(nriga,"@70g** TOTALE FORNITORE"); - else // altri... - set_row(nriga,"@70g** TOTALE CONTO"); - print_rows_totali(nriga, single); - if (_striepilogo) print_riepilogo(nriga,FALSE); - if (ended) - { - set_row(nriga,"@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++,""); - } -} - -TStampaScadenzario::TStampaScadenzario() -{ - _rel1=_rel2=_rel3=NULL; - _p = NULL; -} - -int sc2200(int argc, char** argv) -{ - TStampaScadenzario app; - app.run(argc, argv, "Stampa Scadenzario"); - return 0; -} +#ifndef __PRINTAPP_H +#include +#endif + +#ifndef __CONFIG_H +#include +#endif + +#ifndef __ASSOC_H +#include +#endif + +#ifndef __UTILITY_H +#include +#endif + +#ifndef __SALDACON_H +#include "../cg/saldacon.h" +#endif + +#ifndef __DITTE_H +#include +#endif + +#ifndef __CLIFO_H +#include +#endif + +#ifndef __PCONTI_H +#include +#endif + +#ifndef __PARTITE_H +#include +#endif + +#ifndef __SCADENZE_H +#include +#endif + +#ifndef _FLD_CAUS_H +#include +#endif + +#include + +#include "sc2.h" +#include "sc2200.h" +#include "sc2201.h" + +#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}; + +const char * tipi_tab[10] = {"Altro","Rimesse dirette","Tratte","Ricevute bancarie","Cessioni","Paghero'", + "Lettere di acc.","Tratte accettate","Rapp. interb. dir.","Bonifici"} ; + +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 *_caus, *_partite, *_pagsca; // File delle causali, serve per reperire le descrizioni, nel caso non ci siano sul file parite + 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 + 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; + // 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. + + 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. + friend 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 + // 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); + // Totalizza i pagamenti non assegnati per la partita corrente (NB si spera che siano tutti nella stessa valuta) + bool in_cache(TString& k); // ritorna vero se ci sono gia' non assegnati in _uns_cache; + void look_in_cache(real& a, real& b, TAssoc_array& uns, TAssoc_array& unsnc, TString& k); + void calcola_unassigned(TString& k); + void calcola_pagamenti(real& imp_scad, int riga, int rata); // calcola i pagamenti effettuati per questa rata e il residuo eventuale + + TStampaScadenzario(); +}; + +inline TStampaScadenzario& app() {return (TStampaScadenzario&)main_app();} + +bool filter_func(const TRelation *r) +{ // Filtro per rate saldate: se e' saldata e' ok solo quando + bool rt = FALSE; // e' abilitato il flag; se non e' saldata va sempre bene. + TLocalisamfile* scad = &(r->lfile(LF_SCADENZE)); + bool saldata = scad->get_bool(SCAD_PAGATA); + + if (!saldata || (saldata && app()._ratesald)) + { + rt=TRUE; + } + return rt; +} + +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; + 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::in_cache(TString& k) +{ + int rt = FALSE; + TAssoc_array& uns = (TAssoc_array&) _uns_cache[0]; + TAssoc_array& unsnc = (TAssoc_array&) _uns_cache[1]; + if (uns.is_key(k) || unsnc.is_key(k)) rt =TRUE; + return rt; +} + +void TStampaScadenzario::calcola_unassigned(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]; + TRecord_array& ra = _p->unassigned(); + real a,b; + a = 0.0; + b = 0.0; + + 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); + if (sum.get_int(PART_TIPOMOV) == 2) // Is it a credit note ? + b += rec.get_real(field); + else + a += rec.get_real(field); + } + if (a != 0.0) // Aggiungilo a TAssoc_array dei non assegnati + uns.add(k,a,TRUE); + if (b != 0.0) // Aggiungilo a TAssoc_array delle note di credito + unsnc.add(k,b,TRUE); +} + +void TStampaScadenzario::look_in_cache(real& a, real& b, TAssoc_array& uns, TAssoc_array& unsnc, TString& k) +//Estrae dai tassoc_array i valori, relativi alla partita corrente, di uns e unsnc, mettendoli in a e b +{ + a = 0.0; b = 0.0; + 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_str(PART_NUMPART); + if (uns.is_key(k)) a = (real&)uns[k]; + if (unsnc.is_key(k)) b = (real&)unsnc[k]; +} + +void TStampaScadenzario::calcola_pagamenti(real& imp_scad, int riga, int rata) +{ + TAssoc_array& uns = (TAssoc_array&) _uns_cache[0]; + TAssoc_array& unsnc = (TAssoc_array&) _uns_cache[1]; + 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,7); // 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 int tipomov = sum.get_int(PART_TIPOMOV); + if (tipomov == 2 || tipomov == 5) + scdz += TImporto(sez,pag.get_real(field)); +/* ------------------------------------------------------ + switch (tipomov) + { + case 5: // Insoluto (aumenta scdz) + scdz += TImporto(sez,pag.get_real(field)); + break; + case 2: // Nota di credito assegnata (storna da scdz) + scdz -= TImporto(sez,pag.get_real(field)); + break; + default: + break; + } + ----------------------------------------------------*/ + } + char norm = 'D'; + if (_tipost == fornitori) norm = 'A'; + totalep.normalize(norm); scdz.normalize(norm); + _w_imp_pag = totalep.valore(); + imp_scad = scdz.valore(); + real a,b; + TString k; k.cut(0); + look_in_cache(a,b,uns,unsnc,k); + if (b > 0.0) // Scala le note di credito dalle scadenze + { + real gap = (b > imp_scad ? imp_scad : b); + imp_scad -= gap; + b -= gap; + if (b > 0.0) + unsnc.add(k,b,TRUE); + else + unsnc.remove(k); // Free some space when 0 reached. + } + if (a > 0.0 && 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. + real gap = (a > imp_scad ? imp_scad : a); + _w_imp_pag += gap; + a -= gap; + if (a > 0.0) + uns.add(k,a,TRUE); + else + uns.remove(k); // Free some space when 0 reached + } + _w_imp_res = imp_scad - _w_imp_pag; +} + + +bool TStampaScadenzario::preprocess_page(int file, int counter) +// Se ritorna FALSE salta questa scadenza e va alla prossima. +{ + 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) + { + TCursor_sheet& cs = _m->cur_sheet(); // Sheet di selezione (CLI/FO/PCON) + TCursor* c = cs.cursor(); + TRectype& rec = c->curr(); + if (_tipost == clienti || _tipost == fornitori) + rec = current_cursor()->curr(LF_CLIFO); + else + if (_tipost == altri) + rec = current_cursor()->curr(LF_PCON); + if (!cs.checked(c->read(_isequal))) // Se non e' stato selezionato salta alla prossima scdz + 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(_p->first()); + _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. + _caus->zero(); _caus->put(CAU_CODCAUS,row.get(PART_CODCAUS)); + if (_caus->read() == NOERR) + *_descrizione = _caus->get(CAU_DESCR); + } + } + calcola_pagamenti(imp_scad,nrigap,nratap); + if (_w_imp_res == 0.0 && ! _ratesald + || imp_scad == 0.0) // Se la rata e' stata saldata e non e' abilitato il flag di stampa + return FALSE; // oppure l'importo in scadenza e' 0 allora salta alla prossima scadenza + _annopart.format("%d",annop); + _annopart.ltrim(2); + _rimdir=""; + _riba=""; + _altri=""; + _imp_pag = ""; + if (_stvaluta && _codval != " ") + { + _imp_scad = imp_scad.string(".2"); + if (_w_imp_pag != 0.0) + _imp_pag=_w_imp_pag.string(".2"); + } + else + { + _imp_scad=imp_scad.string("."); + if (_w_imp_pag != 0.0) + _imp_pag=_w_imp_pag.string("."); + } + switch (tipo_pag) + { + case 1: // Rimesse dirette + if (_w_imp_res != 0.0) + { + if (_stvaluta && _codval != " ") _rimdir = _w_imp_res.string(".2"); + else _rimdir=_w_imp_res.string("."); + } + break; + case 2: // ri.ba / Tratte + case 3: + if (_w_imp_res != 0.0) + { + if (_stvaluta && _codval != " ") _riba = _w_imp_res.string(".2"); + else _riba=_w_imp_res.string("."); + } + break; + default: // Altri + if (_w_imp_res != 0.0) + { + if (_stvaluta && _codval != " ") _altri = _w_imp_res.string(".2"); + else _altri=_w_imp_res.string("."); + } + break; + } + } + + if (file==LF_CLIFO) + { + TString xxx(current_cursor()->curr(LF_CLIFO).get(CLI_RAGSOC)); + *_ragsoc = xxx.strip_d_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))) + { + if (_cur_data != botime && _cur_data != datascad) + { + // 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 + bool month_changed = _cur_data.month() != datascad.month(); + + for (int n=1; nadd(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->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 + _cur7 = add_cursor(new TCursor(_rel3,"",2)); + + _caus = new TLocalisamfile(LF_CAUSALI); + _partite = new TLocalisamfile(LF_PARTITE); + _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); + _uns_cache.add(new TAssoc_array);_uns_cache.add(new TAssoc_array); + 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 (_caus) + delete _caus; + if (_partite) + delete _partite; + 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) +{ + bool rt=FALSE,ok=FALSE; + KEY t; + while (!ok) + { + if ((t=_m->run())==K_ENTER) + { + if ( !_m->cur_sheet().checked()) + error_box("Non e' stata effettuata alcuna selezione."); + else + ok=TRUE; + } + else ok=TRUE; + } + + switch (t) + { + case K_ENTER: + { + _end_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; + if (_m->get_key() == 1) _ordcod = TRUE; + else _ordcod = FALSE; + _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.zero(); + a_data.zero(); + 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; + } + rt=TRUE; + break; + } + default: + break; + } + 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 rt; +} + +void TStampaScadenzario::print_header() +// Setta le righe dell'intestazione +{ + int soh = 1; + const long firm = get_firm(); + + reset_header (); + TLocalisamfile ditte(LF_NDITTE); + ditte.zero(); + ditte.put(NDT_CODDITTA, firm); + ditte.read(); + if (ditte.bad()) ditte.zero(); + + TString s; + s = ditte.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++,"@72g** SCADENZARIO FORNITORI **"); + s1 = "Ns."; s2 = "Banca"; + } + else + { + set_header(soh++,"@73g** SCADENZARIO CLIENTI **"); + s1 =""; s2 = ""; + } + set_header (soh++,"@64gPer il periodo dal %s al %s",(const char*)datai,(const char*)dataf); + rw.fill('-'); + set_header(soh++, (const char *) rw); + set_header(soh++,"@28gRif.@38gData@47gData@77gCd/Tp@91g%s",(const char*)s1); + set_header(soh++,"Codice@9gRagione sociale@28gpartita@38gscadenza@47gRegistr." + "@56gDescrizione@77gPag.@86gRata@91g%s@97gVal." + "@106gImp. in sca.@124gImp. pagati@142gRimesse dir.@160gRi.ba./Tratte@178gAltri",(const char*)s2); + set_header(soh++,"@28gData e Nr doc. @46gProt. IVA"); + set_header(soh++,(const char *)rw); + break; + } + case altri: // Piano dei conti + { + TString rw(201); + set_header (soh++, "Ditta : %ld %s@152gData@157g%s @190gPag. @#", + firm, (const char *)s, (const char *)data); + set_header(soh++,"@79g** SCADENZARIO **"); + set_header (soh++,"@66gPer il periodo dal %s al %s",(const char*)datai,(const char*)dataf); + rw.fill('-'); + set_header(soh++, (const char *) rw); + set_header(soh++,"@33gRif.@43gData@53gData@82gCd/Tp"); + set_header(soh++,"Gr. Co. So.@16gDescrizione@33gpartita@43gscadenza@53gRegistr." + "@61gDescrizione@82gPag.@89gRata@97gVal." + "@106gImp. in sca.@124gImp. pagati@142gRimesse dir.@160gRi.ba./Tratte@178gAltri"); + + set_header(soh++,"@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 +{ + 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#17t",&_imp_scad); + set_row(nriga,"@119g#17t",&_imp_pag); + set_row(nriga,"@137g#17t",&_rimdir); // rimesse dirette + set_row(nriga,"@155g#17t",&_riba); // Ri.ba. / tratte + set_row(nriga++,"@173g#17t",&_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. +{ + 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#17t",&_imp_scad); + set_row(nriga,"@119g#17t",&_imp_pag); + set_row(nriga,"@137g#17t",&_rimdir); // rimesse dirette + set_row(nriga,"@155g#17t",&_riba); // Ri.ba. / tratte + set_row(nriga++,"@173g#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) +{ + int nriga =1; + print_header(); + switch (_tipost) + { + case fornitori: + case clienti: + if (file == LF_CLIFO) + set_page_clifo(nriga); + break; + case altri: + if (file == LF_PCON) + set_page_pcon(nriga); + 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++) + { + TString k (as.row(i)); + TString val(k.right(3)); + TString value; + real& v = (real&)t[k]; + const int tipo = k[0]-'0'; + const char ult = k[1]; + + if (_stvaluta && val != " ") value = v.string(".2"); + else value = v.string("."); + if (v != 0.0) + set_row(nriga++,"@0g!@3g%s@25g!@27g%c@32g!@34g%s@39g!@42g%17s@59g!", + tipi_tab[tipo], ult, (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(60); + TAssoc_array totali; // Assoc array per i totali distinti per valuta + TString_array as; + + s.fill('-'); + nriga++; + set_row(nriga++,"%s",(const char *)s); + if (!type) + { + if (_ordata) + { + set_row(nriga++,"@0g!@2g%s@59g!",itom(_cur_data.month())); + set_row(nriga++,"%s",(const char*)s); + } + } else + { + set_row(nriga,"!@5gTotali dal %s al ",_datai.string(brief)); + set_row(nriga++,"%s@59g!",_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(); + for (int i=0; i < items; i++) + { + TString val(as.row(i)); + TString value; + real& tot = (real&)totali[val]; + if (_stvaluta && val != " ") value = tot.string(".2"); + else value = tot.string("."); + + if (tot != 0.0) + { + if (i == 0) + set_row(nriga++,"%s",(const char *)s); // Se c'e' almeno un totale != 0 allora stampa il separe' + set_row(nriga++,"!@34g%s@42g%17s@59g!",(const char*) val, (const char*) value); + } + else + { + if (val == " ") val = "LIT"; + set_row(nriga++,"! Nessun valore totale in %s. @59g!",(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; + default: + break; + } + TAssoc_array& xassoc = (TAssoc_array&) _tl[index]; + TString_array as; + const int items = xassoc.items(); + xassoc.get_keys(as); + as.sort(); + for (int i=0; i < items; i++) + { + TString k(as.row(i)); // Chiave di ordinamento(valuta) + TString value; + _LinearTotal& v = (_LinearTotal&)xassoc[k]; + if (k != " ") + set_row(nriga,"@97g%3s",(const char*)k); + if (_stvaluta && k != " ") value = v._is.string(".2"); + else value = v._is.string("."); + if (v._is != 0.0) + set_row(nriga,"@101g%17s",(const char*) value); + if (_stvaluta && k != " ") value = v._ip.string(".2"); + else value = v._ip.string("."); + if (v._ip != 0.0) + set_row(nriga,"@119g%17s",(const char*) value); + if (_stvaluta && k != " ") value = v._rd.string(".2"); + else value = v._rd.string("."); + if (v._rd != 0.0) + set_row(nriga,"@137g%17s",(const char*) value); + if (_stvaluta && k != " ") value = v._ri.string(".2"); + else value = v._ri.string("."); + if (v._ri != 0.0) + set_row(nriga,"@155g%17s",(const char*) value); + if (_stvaluta && k != " ") value = v._al.string(".2"); + else value = v._al.string("."); + if (v._al != 0.0) + set_row(nriga,"@173g%17s",(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,"@36g** TOTALI DEL @51g%s",_cur_data.string(brief)); + print_rows_totali(nriga, daily); + if (month_changed) + { + set_row(nriga,"@36g** TOTALI DI @51g%s",itom(_cur_data.month())); + print_rows_totali(nriga, monthly); + if (_striepilogo) print_riepilogo(nriga,FALSE); + } + if (ended) + { + set_row(nriga++,""); + set_row(nriga,"@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,"@70g** TOTALE CLIENTE"); + else + if (_tipost ==fornitori) + set_row(nriga,"@70g** TOTALE FORNITORE"); + else // altri... + set_row(nriga,"@70g** TOTALE CONTO"); + print_rows_totali(nriga, single); + if (_striepilogo) print_riepilogo(nriga,FALSE); + if (ended) + { + set_row(nriga,"@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++,""); + } +} + +TStampaScadenzario::TStampaScadenzario() +{ + _rel1=_rel2=_rel3=NULL; + _p = NULL; +} + +int sc2200(int argc, char** argv) +{ + TStampaScadenzario app; + app.run(argc, argv, "Stampa Scadenzario"); + return 0; +}