campo-sirio/sc/sc2200.cpp
angelo dcf6553973 Corretti errori MI3360 e MI3361. Ora gli insoluti non vanno ad
aumentare la scdenza bensi' stornano i pagamenti. Decisione
presa con Gabriella.


git-svn-id: svn://10.65.10.50/trunk@2756 c028cbd2-c16b-5b4b-a496-9718f37d4682
1996-04-22 11:00:34 +00:00

1264 lines
51 KiB
C++
Executable File

#ifndef __PRINTAPP_H
#include <printapp.h>
#endif
#ifndef __CONFIG_H
#include <config.h>
#endif
#ifndef __ASSOC_H
#include <assoc.h>
#endif
#ifndef __UTILITY_H
#include <utility.h>
#endif
#ifndef __SALDACON_H
#include "../cg/saldacon.h"
#endif
#ifndef __DITTE_H
#include <nditte.h>
#endif
#ifndef __CLIFO_H
#include <clifo.h>
#endif
#ifndef __PCONTI_H
#include <pconti.h>
#endif
#ifndef __PARTITE_H
#include <partite.h>
#endif
#ifndef __SCADENZE_H
#include <scadenze.h>
#endif
#ifndef _FLD_CAUS_H
#include <causali.h>
#endif
#include <pagsca.h>
#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 work_imp,
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);
// 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 == 2)
{
work_imp = TImporto(sez,pag.get_real(field));
scdz += work_imp;
totalep -= work_imp;
}
}
char norm = 'D';
if (_tipost == fornitori) norm = 'A';
totalep.normalize((norm=='D') ? 'A' : 'D');
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(".3");
if (_w_imp_pag != 0.0)
_imp_pag=_w_imp_pag.string(".3");
}
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(".3");
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(".3");
else _riba=_w_imp_res.string(".");
}
break;
default: // Altri
if (_w_imp_res != 0.0)
{
if (_stvaluta && _codval != " ") _altri = _w_imp_res.string(".3");
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; n<MaxRowsForTotal; n++) reset_row(n);
n = 1;
set_row(n++,"");
print_totali(n,month_changed,FALSE);
switch (_tipost)
{
case clienti:
case fornitori:
set_page_clifo(n);
break;
case altri:
set_page_pcon(n);
break;
}
_modified=TRUE;
// Azzera i totali del giorno in ogni caso.
TAssoc_array& tlg = (TAssoc_array&) _tl[0];
tlg.destroy();
// Controlla se e' cambiato il mese azzera i relativi totali
if (month_changed)
{
_tm.destroy(); // Cancella tutti gli elementi del mese dopo averli stampati
TAssoc_array& tlm = (TAssoc_array&) _tl[1];
tlm.destroy();
}
}
// Tiene aggiornati tutti i totali mese/giorno/periodo (Totali lineari per valuta)
check_add_key_to_tl(daily, tipo_pag);
check_add_key_to_tl(monthly, tipo_pag);
check_add_key_to_tl(period, tipo_pag);
// Tiene aggiornati tutti i totali mese/periodo (Totali dei prospetti
check_add_key_to_tp(tipo_pag, ult_cla);
_cur_data = datascad;
_cur_codcf_s = format("%6ld",codcf);
}
// Qui stampa il totale generale e lo specchietto colonnello.
// Vale con l'ordinamento principale per data di scadenza.
// N.B viene eseguito solo come ultimo blocco, grazie ad una REPEAT_PAGE in postprocess_print()
if (_end_printed && file == LF_SCADENZE && _ordata)
{
reset_print();
int n=1;
set_row(n++,"");
print_totali(n,TRUE,TRUE);
}
// Qui stampa il totale di ogni cli/fo o conto, nel caso che l'ordinamento
// primario non sia per data di scadenza
if (!_ordata && !_end_printed && file!=LF_SCADENZE)
{
bool changed = TRUE;
// Vale anche con ordinamento primario per descrizione o ragione sociale: se essa cambia
// cambia anche il trio Gr/Co/So.
if (_cur_gr != -1 && _cur_co != -1 && _cur_codcf != -1)
if (_cur_gr != gruppo || _cur_co != conto || _cur_codcf != codcf)
{
for (int n=1; n<MaxRowsForTotal; n++) reset_row(n);
n = 1;
set_row(n++,"");
print_totali_c(n,FALSE);
if (_tipost == altri)
set_page_pcon(n);
else
set_page_clifo(n);
_modified=TRUE;
TAssoc_array& tlm = (TAssoc_array&) _tl[1];
tlm.destroy();
_tm.destroy(); // Cancella i valori del cli/fo/conto dopo averli stampati
}
else
{ // If group/count/codcf Remains The Same don't repeat _ragsoc, _des_conto...
*_ragsoc = "";
*_des_conto = "";
_cur_gr_s = "";
_cur_co_s = "";
_cur_codcf_s = "";
changed = FALSE;
}
if (changed)
{
_cur_gr_s = format("%3d",gruppo);
_cur_co_s = format("%3d",conto);
_cur_codcf_s = format("%6ld",codcf);
}
_cur_gr=gruppo;
_cur_co=conto;
_cur_codcf=codcf;
// Tiene aggiornati i totali per cli/fo/conto e periodo (Totali lineari per valuta)
check_add_key_to_tl(single, tipo_pag);
check_add_key_to_tl(period, tipo_pag);
// Tiene aggiornati i totali per cli/fo/conto e periodo (Totali per i prospetti)
check_add_key_to_tp(tipo_pag, ult_cla);
}
// Qui stampa il totale generale e lo schema riepilogativo.
// Vale con l'ordinamento principale per codice/descrizione/ragione sociale.
// N.B viene eseguito solo come ultime blocco, grazie ad una REPEAT_PAGE in postprocess_print()
if (_end_printed && file == LF_SCADENZE && !_ordata)
{
reset_print();
int n=1;
set_row(n++,"");
// Il confronto posso farlo solo su clienti/fornitori/altri, anche perche'
// per tutti e' obbligatorio l'ordinamento principale per data.
print_totali_c(n,TRUE);
}
return TRUE;
}
bool TStampaScadenzario::preprocess_print(int file, int counter)
{
return TRUE;
}
print_action TStampaScadenzario::postprocess_print(int file, int counter)
{
print_action rt = NEXT_PAGE;
// Setta _end_printed e ripete la pagina. Questa condizione puo' accadere
// solo alla fine dei record di LF_SCADENZE, percio' solo dopo aver stampato
// tutti gli altri; sia per LF_CLIFO che per LF_PCON, purche' LF_SCADENZE
// sia sempre il file principale della relazione e dell'albero di stampa.
// Ritornando REPEAT_PAGE resettera' le righe di stampa, e all'interno della
// preprocess_page formera' le righe dei riepiloghi finali.
// Se LF_PCON o LF_CLIFO sono i file principali della relazione e' necessario aggiungere
// una seconda condzione, valevole solamente se l'ordine principale non e' per data scadenza.
if (!_end_printed) // Se non e' ancora stato stampato il totale generale...
if ((file == LF_SCADENZE)) //&& _ordata) || (file !=LF_SCADENZE && !_ordata))
{
rt = REPEAT_PAGE;
_end_printed = TRUE;
}
return rt;
}
print_action TStampaScadenzario::postprocess_page(int file, int counter)
{
if (_modified)
reset_print();
return NEXT_PAGE;
}
bool TStampaScadenzario::user_create()
{
_rel1 = new TRelation(LF_SCADENZE); // Scadenze per data scadenza + CliFo (Codice & Ragione sociale)
_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->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.@125gImp. pagati@144gRimesse dir.@163gRi.ba./Tratte@182gAltri",(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.@125gImp. pagati@144gRimesse dir.@163gRi.ba./Tratte@182gAltri");
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#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.
{
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)
{
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(".3");
else value = v.string(".");
if (v != 0.0)
set_row(nriga++,"@0g!@3g%s@25g!@27g%c@32g!@34g%s@39g!@42g%18s@60g!",
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(61);
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@60g!",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@60g!",_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(".3");
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%18s@60g!",(const char*) val, (const char*) value);
}
else
{
if (val == " ") val = "LIT";
set_row(nriga++,"! Nessun valore totale in %s. @60g!",(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(".3");
else value = v._is.string(".");
if (v._is != 0.0)
set_row(nriga,"@101g%18s",(const char*) value);
if (_stvaluta && k != " ") value = v._ip.string(".3");
else value = v._ip.string(".");
if (v._ip != 0.0)
set_row(nriga,"@120g%18s",(const char*) value);
if (_stvaluta && k != " ") value = v._rd.string(".3");
else value = v._rd.string(".");
if (v._rd != 0.0)
set_row(nriga,"@139g%18s",(const char*) value);
if (_stvaluta && k != " ") value = v._ri.string(".3");
else value = v._ri.string(".");
if (v._ri != 0.0)
set_row(nriga,"@158g%18s",(const char*) value);
if (_stvaluta && k != " ") value = v._al.string(".3");
else value = v._al.string(".");
if (v._al != 0.0)
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,"@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;
}