campo-sirio/src/sc/sc2200.cpp
bonazzi 2a32c54e5d Patch level : 12.0 336
Files correlati     : sc2.exe pec.frm sc2200a.msk sc2300a.msk

MODIFICA CRPA 

Possibilità di stampare il pagamento del cliente nella testata dell'estratti conto.
Aggiunto filtro per ulteriore classificazione nello scadenziario.
Possibilità di stampare le note delle scadenze nella stampa scaduto.
Possibiltà di stampare il flag di rata bloccata e il dati di analitica e di filtrare per dati analitica nei solleciti.

git-svn-id: svn://10.65.10.50/branches/R_10_00@23573 c028cbd2-c16b-5b4b-a496-9718f37d4682
2017-01-31 08:22:52 +00:00

1689 lines
65 KiB
C++
Executable File
Raw Blame History

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