campo-sirio/src/sc/sc2401.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

1168 lines
32 KiB
C++
Executable File

#include <printer.h>
#include "../cg/cgsaldac.h"
#include "sc21pec.h"
#include "sc2401.h"
#include "../ca/calib01.h"
#include "../ca/movana.h"
#include <causali.h>
#include <modaut.h>
#include <mov.h>
bool TESSL_mask::codprof_handler(TMask_field& f, KEY k)
{
if (f.to_check(k))
{
TEdit_field & e = (TEdit_field &) f;
e.check_type(CHECK_REQUIRED);
const bool ok = e.check();
e.check_type(CHECK_NONE);
if (k == K_ENTER && !ok)
{
if (f.is_editable())
{
TEditable_field& ef = (TEditable_field&) f;
return f.error_box(ef.get_warning());
}
}
}
return TRUE;
}
bool TESSL_mask::lingua_handler(TMask_field& f, KEY k)
{
if (k == K_TAB && f.focusdirty())
{
TCursor& cur = *(((TEdit_field&)(f.mask().field(F_CODPROF))).browse()->cursor());
// whew
TString16 lin = f.get();
if (lin != cur.curr().get("CODPROF").mid(4))
f.mask().field(F_CODPROF).check(RUNNING_CHECK);
}
return TRUE;
}
TESSL_mask::TESSL_mask(const char *name) : TSelection_mask(name), _ditta(LF_NDITTE)
{
_ditta.add(LF_ANAG, "TIPOA==TIPOA|CODANAGR==CODANAGR");
_ditta.add(LF_COMUNI, "COM==COMRF(COMRES)", 1, LF_ANAG, 101);
_ditta.add(LF_COMUNI, "COM==COMRES", 1, LF_ANAG, 102);
set_handler(F_CODPROF, codprof_handler);
set_handler(F_LINPROF, lingua_handler);
}
TESSL_mask::~TESSL_mask() {}
void TESSL_mask::on_firm_change()
{
TMask::on_firm_change();
_ditta[0].put("CODDITTA", prefix().get_codditta());
if (_ditta.read() == NOERR) {
const int alias = _ditta[LF_ANAG].get_char("TIPOA") == 'F' ? -101 : -102;
set(F_LUOGOSEND, _ditta.lfile(alias).get("DENCOM"));
}
}
void TESSL_mask::start_run()
{
on_firm_change();
}
const char *TESSL_mask::get_prof_base() const
{
return BASE_EC_PROFILE;
}
const TString &TESSL_mask::get_prof_code() const
{
return get(F_CODPROF);
}
const char *TESSL_mask::get_prof_name() const
{
TString& tmp=(TString&)_tmp;
tmp = get(F_CODPROF);
tmp << get(F_LINPROF);
return _tmp;
}
const TString &TESSL_mask::get_prof_lang() const {
return get(F_LINPROF);
}
bool TESSL_mask::stampa_saldo() const {
return get_bool(F_STAMPSALDO);
}
///////////////////////////////////////////////////////////
// TESSL_row
///////////////////////////////////////////////////////////
TESSL_row::TESSL_row(const TRiga_partite& row, const TDate& data, const TImporto& imp, int rata)
: _num_prot(0), _num_reg(0), _salvo_buon_fine(false)
{
_riga = row.get_int(PART_NRIGA);
_rata = rata;
_data = data;
_causale = row.get(PART_CODCAUS);
_data_doc = row.get(PART_DATADOC);
_num_doc = row.get(PART_NUMDOC);
_num_prot = row.get_long(PART_PROTIVA);
_num_reg = row.get_long(PART_NREG);
_importo = imp; _importo.normalize();
_descrizione = row.get(PART_DESCR);
_valuta.get(row);
const bool valuta = form().in_valuta() && _valuta.in_valuta();
const char* const field = valuta ? PART_IMPTOTVAL : PART_IMPTOTDOC;
_totale = row.get_real(field);
}
TESSL_row::TESSL_row(const char* desc, const TImporto& imp, const TValuta& val)
: _riga(9999), _rata(9999), _num_prot(0), _num_reg(0), _salvo_buon_fine(false)
{
_descrizione = desc;
_importo = imp; _importo.normalize();
_valuta = val;
}
// le righe dell'estratto conto sono ordinate per data, riga partita, numero rata,
// posizione iniziale nell'array (in caso di uguaglianza di tutto il resto)
int TESSL_row::compare(const TSortable& s) const
{
const TESSL_row& r = (const TESSL_row&)s;
int c = 0;
if (_data == r._data)
{
c = r._riga - _riga;
if (c == 0) c = _rata - r._rata;
}
else
c = _data < r._data ? -1 : +1;
return c;
}
// Annulla i campi uguali alla riga precedente
void TESSL_row::reset_uguali()
{
_num_doc = "";
_data_doc = botime;
_num_prot = 0;
_totale = ZERO;
}
void TESSL_row::set_imp(TForm_item& fi, const real& imp, const char* cod_val) const
{
fi.set(imp.string());
}
TESSL_form& TESSL_row::form() const
{
TESSL_form* f = TESSL_form::_form;
CHECK(f, "NULL form");
return *f;
}
void TESSL_row::print_on(TPrint_section& body)
{
TESSL_form& form = (TESSL_form&)body.form();
const bool show_value = form.in_valuta() && in_valuta();
const TString& cod_valuta = show_value ? valuta().codice() : EMPTY_STRING;
TForm_item& campo_valuta = body.find_field(PEC_VALUTA);
campo_valuta.set(cod_valuta);
TForm_item& causale = body.find_field(PEC_CODCAUS);
causale.set(_causale);
if (_causale.not_empty() && _descrizione.empty())
{
TDecoder& causali = form.causali();
_descrizione = causali.decode(_causale);
}
TForm_item& descr = body.find_field(PEC_DESCR);
if (num_reg() > 0) // Riga di partita vera e propria (non totale parziale)
{
TString s(80);
s = descr.prompt();
TESSL_form::_form->change_magic_body(*this, s);
descr.set(s);
}
else
descr.set(_descrizione);
TForm_item& datadoc = body.find_field(PEC_DATADOC);
datadoc.set(_data_doc.string());
TForm_item& numdoc = body.find_field(PEC_NUMDOC);
numdoc.set(_num_doc);
TForm_item& numprot = body.find_field(PEC_PROTIVA);
TString16 protiva; protiva << _num_prot;
numprot.set(protiva);
TForm_item& datapag = body.find_field(PEC_DATAPAG);
datapag.set(_data.string());
const real& imp = _importo.valore();
TForm_item& dare = body.find_field(PEC_DARE);
TForm_item& avere = body.find_field(PEC_AVERE);
if (_importo.sezione() == 'D')
{
set_imp(dare, imp, cod_valuta);
avere.set("");
}
else
{
set_imp(avere, imp, cod_valuta);
dare.set("");
}
TForm_item& importo_in_euro = body.find_field(PEC_IMPEURO);
set_imp(importo_in_euro, _importo_euro, ""); // In generale va espresso nella valuta della ditta
TForm_item& scaduto = body.find_field(PEC_SCADUTO);
set_imp(scaduto, _scaduto, cod_valuta);
TForm_item& esposto = body.find_field(PEC_ESPOSTO);
set_imp(esposto, _esposto, cod_valuta);
esposto.set_prompt(_salvo_buon_fine ? "*" : " ");
TForm_item& totdoc = body.find_field(PEC_TOTDOC);
//old_pictures.add(totdoc.picture());
set_imp(totdoc, _totale, cod_valuta);
TForm_item& cambio = body.find_field(PEC_CAMBIO);
cambio.set(_valuta.cambio().string());
TForm_item& datacambio = body.find_field(PEC_DATACAM);
datacambio.set(_valuta.data().string());
TForm_item& bloccata = body.find_field(PEC_BLOCCATA);
bloccata.set(_bloccata ? "X" : "");
TForm_item& analitica = body.find_field(PEC_ANALITICA);
analitica.set(_codici_analitica);
TParagraph_string p(_codici_analitica, analitica.width());
const int h = analitica.height();
int i = 0;
for (i = 0; p.get() != NULL && i < h; i++);
analitica.section().set_height(p.empty() ? 1 : i);
const TString old_prompt(descr.prompt());
descr.set_prompt(""); // Nasconde temporaneamente il prompt per non stampare i <magic>
body.update(); // crea la vera riga di stampa
esposto.set_prompt(" ");
descr.set_prompt(old_prompt); // Ripristina il vecchio prompt
// dare.set_picture(old_pictures.row(0));
// avere.set_picture(old_pictures.row(1));
// scaduto.set_picture(old_pictures.row(2));
// esposto.set_picture(old_pictures.row(3));
// totdoc.set_picture(old_pictures.row(4));
}
static int val_compare(const void* o1, const void* o2) {
const THash_object* h1 = (const THash_object*)o1;
const THash_object* h2 = (const THash_object*)o2;
const TString& s1 = (const TString&)h1->obj();
const TString& s2 = (const TString&)h2->obj();
return s2.compare(s1, -1, TRUE); // same as stricmp(s1, s2) in reverse order
}
///////////////////////////////////////////////////////////
// TESSL_array
///////////////////////////////////////////////////////////
TPartita* TESSL_array::_sort_game = NULL;
// Calcola l'importo su di una riga di pagamento
TImporto TESSL_array::importo(const TPartita& game, const TRectype& pag, bool valuta) const
{
const int nriga = pag.get_int(PAGSCA_NRIGA);
const TRiga_partite& fat = game.riga(nriga); // Riga di fattura
const bool fat_val = fat.in_valuta();
const int nrigp = pag.get_int(PAGSCA_NRIGP);
const TRiga_partite& sum = game.riga(nrigp); // Riga di pagamento
const char sez = sum.sezione();
const char* const field = valuta && fat_val ? PAGSCA_IMPORTOVAL : PAGSCA_IMPORTO;
TImporto imp(sez, pag.get_real(field)); // Importo base
if (!fat_val)
{
imp.valore() += pag.get_real(PAGSCA_RITENUTE); // Sommo le ritenute se sono in lire
const TImporto ritsoc(sum.sezione_ritsoc(), pag.get_real(PAGSCA_RITSOC));
imp += ritsoc;
}
if (pag.get_char(PAGSCA_ACCSAL) == 'S') // Se il pagamento ha abbuoni o differenze cambio
{
real abb(pag.get(PAGSCA_ABBUONI));
if (!valuta && fat_val) // Se voglio gli abbuoni in lire ma la fattura non lo e'
{
const TValuta val(sum); // Leggo il cambio dalla riga di partita
val.val2eur(abb); // Converto in lire gli abbuoni
abb += pag.get_real(PAGSCA_DIFFCAM); // Sommo l'eventuale differenza cambio (gia' in lire)
}
imp.valore() += abb; // Sommo il tutto all'importo base (sez e' uguale per tutti i valori)
}
return imp;
}
// Certified 100%
TImporto& TESSL_array::importo_riga_scaduto(int n)
{
CHECKD(n > 0 && n < 9999, "Riga scaduto errata ", n);
TImporto* imp = importo_riga_scaduto_ptr(n);
if (imp == NULL)
{
imp = new TImporto;
_scaduto.add(imp, n);
}
return *imp;
}
// Ordina i pagamenti in ordine di DATAPAG
int TESSL_array::ordina_pag(const void* pag1, const void* pag2)
{
const int r1 = (*(TRectype**)pag1)->get_int(PAGSCA_NRIGP);
const TDate d1 = _sort_game->riga(r1).get(PART_DATAPAG);
const int r2 = (*(TRectype**)pag2)->get_int(PAGSCA_NRIGP);
const TDate d2 = _sort_game->riga(r2).get(PART_DATAPAG);
const int diff = d1 == d2 ? 0 : (d1 > d2 ? +1 : -1);
return diff;
}
real TESSL_array::calcola_scaduto(const TRiga_scadenze& rata, bool valuta)
{
const TPartita& game = rata.partita();
const char sezione = game.conto().tipo() == 'C' ? 'D' : 'A';
TImporto scaduto_rata = rata.importo(valuta);
int riga_corrente_scaduto = 0;
const int numpag = rata.rows(); // Numero totale di pagamenti sulla rata
TRectype** arrpag = NULL; // Array di puntatori ai pagamenti
if (numpag > 0)
{
arrpag = new TRectype*[numpag];
int i = 0;
for (int p = rata.last(); p > 0; p = rata.pred(p))
arrpag[i++] = (TRectype*)&rata.row(p); // Copia puntatori ai pagamenti nell'array
_sort_game = (TPartita*)&game; // Inizializza partita di appoggio al sort
qsort(arrpag, numpag, sizeof(TRectype*), ordina_pag);
}
for (int i = 0; i < numpag; i++)
{
const TRectype& pag = *arrpag[i];
const int nrigp = pag.get_int(PAGSCA_NRIGP);
const TRiga_partite& sum = game.riga(nrigp);
TImporto imp = importo(game, pag, valuta);
tipo_movimento tm = sum.tipo(); // Determina tipo riga
// Normalmente gli utenti non usano il tipo pagamento insoluto, per cui devo
// riconoscere i pagamenti che in realta' sono a fronte di insoluti:
// 1) hanno tipo movimento = tm_pagamento
// 2) ho gia' incontrato un insoluto
// 3) il saldo della rata e' a zero o sommando l'importo arriva sotto zero
if (tm == tm_pagamento && riga_corrente_scaduto != 0)
{
if (scaduto_rata.is_zero())
{
tm = tm_pagamento_insoluto;
}
else
{
TImporto p(scaduto_rata);
p += imp;
p.normalize(sezione);
if (p.valore() < ZERO)
{
scaduto_rata.set('D', ZERO);
imp += p;
tm = tm_pagamento_insoluto;
}
}
}
if (tm == tm_insoluto || tm == tm_pagamento_insoluto)
{
if (tm == tm_insoluto)
riga_corrente_scaduto = nrigp;
else
CHECKD(riga_corrente_scaduto > 0, "Pagamento insoluto senza insoluto ", nrigp);
importo_riga_scaduto(riga_corrente_scaduto) += imp;
}
else
{
scaduto_rata += imp;
}
}
if (arrpag != NULL)
delete arrpag;
scaduto_rata.normalize(sezione);
return scaduto_rata.valore();
}
TESSL_row& TESSL_array::new_row(const TRiga_partite& row, const TDate& data, const TImporto& imp, int n)
{
CHECKD(n > 0, "Numero rata errato: ", n);
TESSL_row* riga = new TESSL_row(row, data, imp, n);
add(riga);
return *riga;
}
void TESSL_array::add_row(const TRiga_partite& row)
{
const bool in_valuta = form().in_valuta() && row.in_valuta();
real importo_in_lire;
const char sezione = form().sezione_normale();
const TDate data_op = row.get(PART_DATAREG);
if (data_op <= form().data_limite_operazione())
{
TString codanal;
if (main_app().has_module(CAAUT))
{
const TString& numregcg = row.get(PART_NREG);
const long numreg = atol(_anal.decode(numregcg));
if (numreg > 0)
{
TAnal_mov anal_mov(numreg);
TRecord_array & rows = anal_mov.body();
const int nrows = rows.rows();
for (int i = 1; i <= nrows; i++)
{
const TString80 s = anal_mov.row_code(i);
if (s.full() && codanal.find(s) < 0)
{
if (codanal.full())
codanal << '\n';
if (s.full())
codanal << s;
}
}
}
}
if (row.is_fattura())
{
for (int r = 1; r <= row.rate(); r++)
{
const TRiga_scadenze& rata = row.rata(r);
const TDate data_scad = rata.get(SCAD_DATASCAD);
TESSL_row& rec = new_row(row, data_scad, rata.importo(in_valuta), r);
if (in_valuta)
{
TImporto il(rata.importo(false));
il.normalize(sezione);
rec.importo_in_euro(il.valore());
}
if (data_scad <= form().data_limite_scaduto())
{
const real s = calcola_scaduto(rata, in_valuta);
rec.scaduto(s);
}
rec.rata_bloccata(rata.get_bool(SCAD_BLOCCATA));
rec.codici_analitica(codanal);
}
}
else
{
const TDate data_pag(row.get(PART_DATAPAG));
const TImporto imp(row.importo(in_valuta, 0x1)); // Importo pulito senza nient'altro
TESSL_row& riga = new_row(row, data_pag, imp, RIGA_PAGAMENTO);
if (in_valuta)
{
TImporto i(row.importo(FALSE, 0x1));
i.normalize(sezione);
riga.importo_in_euro(i.valore());
}
riga.codici_analitica(codanal);
const int tipo_pag = row.get_int(PART_TIPOPAG);
const tipo_movimento tipo_mov = row.tipo();
// Controlla se e' un pagamento con effetti
if ((tipo_mov == tm_pagamento || tipo_mov == tm_pagamento_insoluto) &&
(tipo_pag >= 2 && tipo_pag <= 7))
{
const TDate& dls = form().data_limite_scaduto();
const int gr = form().giorni_rischio();
const TDate& dir = form().data_inizio_rischio();
bool sbf = false;
TImporto esposto(row.esposto(in_valuta, dls, dir, sbf));
bool esp = !esposto.is_zero();
if (esp)
{
esposto.normalize(sezione);
riga.salvo_buon_fine(sbf); // Esposto salvo buon fine
riga.esposto(esposto.valore());
}
}
TImporto ritenute(row.importo(FALSE, 0x8));
if (!ritenute.is_zero())
{
TESSL_row& r = new_row(row, data_pag, TImporto('D', ZERO), RIGA_RITENUTE);
r.descrizione(form().describe(PEC_RITENUTE));
if (in_valuta)
{
ritenute.normalize(sezione);
r.importo_in_euro(ritenute.valore());
}
else
r.importo(ritenute);
r.codici_analitica(codanal);
}
const TImporto abbuoni(row.importo(in_valuta, 0x2));
if (!abbuoni.is_zero())
{
TESSL_row& r = new_row(row, data_pag, abbuoni, RIGA_ABBUONI);
r.descrizione(form().describe(PEC_ABBUONI));
if (in_valuta)
{
TImporto il(row.importo(FALSE, 0x2));
il.normalize(sezione == 'D' ? 'A' : 'D');
r.importo_in_euro(il.valore());
}
r.codici_analitica(codanal);
}
TImporto diffcam(row.importo(FALSE, 0x4));
if (!diffcam.is_zero() && !in_valuta)
{
TESSL_row& r = new_row(row, data_pag, TImporto('D', ZERO), RIGA_DIFFCAM);
r.descrizione(form().describe(PEC_DIFFCAM));
r.importo(diffcam);
r.codici_analitica(codanal); }
}
}
}
void TESSL_array::arrange_scaduto(const TPartita& game)
{
const bool in_valuta = form().in_valuta() && row(0).in_valuta();
TImporto totpag(game.importo_pagato_unassigned(in_valuta));
const char sezione = game.conto().tipo() == 'C' ? 'D' : 'A';
totpag.normalize(sezione);
int r;
for (r = items()-1; r >= 0; r--)
{
TESSL_row& s = row(r);
real imp(s.scaduto());
if (imp.sign() < 0)
{
totpag += TImporto(sezione, imp);
s.scaduto(ZERO);
}
}
for (r = 0; r < items() && totpag.valore() >= ZERO; r++)
{
TESSL_row& s = row(r);
real imp = s.scaduto();
if (imp.sign() > 0)
{
if (imp >= totpag.valore())
{
imp -= totpag.valore();
s.scaduto(imp);
totpag = TImporto(sezione, ZERO);
}
else
{
s.scaduto(ZERO);
totpag -= TImporto(sezione, imp);
}
}
}
}
TESSL_array::TESSL_array(const TPartita& game, const TESSL_form* f)
:_form(f), _anal(LF_MOVANA, MOVANA_NUMREG, 3)
{
int r;
for (r = game.last(); r > 0; r = game.pred(r))
add_row(game.riga(r));
const char sezione = f->sezione_normale();
for (r = items()-1; r >= 0; r--)
{
TESSL_row& s = row(r);
if (s.rata() == RIGA_PAGAMENTO)
{
TImporto* imp = importo_riga_scaduto_ptr(s.riga());
if (imp != NULL)
{
imp->normalize(sezione);
s.scaduto(imp->valore());
}
}
}
if (items() > 0)
{
sort();
arrange_scaduto(game);
}
}
///////////////////////////////////////////////////////////
// TESSL_form: form speciale per estratti conto e solleciti
///////////////////////////////////////////////////////////
TESSL_form * TESSL_form::_form = NULL;
void TESSL_form::stampa_testata(TPrinter& pr)
{
TPrint_section& head = section('H');
TForm_item& pagina = head.find_field(PEC_PAGINA);
TString16 pg; pg << int(pr.getcurrentpage());
pagina.set(pg);
head.update();
const word r = head.height()-1;
for (word j = 0; j <= r; j++)
pr.setheaderline(j, head.row(j));
}
static int tot_compare(const void* o1, const void* o2)
{
if (o1 == o2) // Sfrutto una piccola debolezza di qsort:
return 0; // ogni tanto confronta oggetti con se stessi
const THash_object* h1 = *((const THash_object**)o1);
const THash_object* h2 = *((const THash_object**)o2);
return h1->key().compare(h2->key(), -1, true); // was stricmp
}
word TESSL_form::ordina_totali_per_valuta(THash_object* tot[MAXTOT])
{
// I totali sono in un assoc array disordinato per cui li copio in un array e li ordino
// alfabeticamente in base al loro codice valuta
TTotalizer& arr = totali();
arr.restart();
word num_rip = 0;
for (THash_object* obj = arr.get_hashobj();
num_rip < MAXTOT && obj != NULL;
obj = arr.get_hashobj())
tot[num_rip++] = obj;
qsort(tot, num_rip, sizeof(THash_object*), tot_compare);
return num_rip;
}
void TESSL_form::stampa_riporti(TPrinter& pr)
{
THash_object* tot[MAXTOT];
_num_rip = ordina_totali_per_valuta(tot);
if (_num_rip > _maxtot)
_num_rip = _maxtot;
const TString& riporto = describe(PEC_RIPORTO);
TString desc(80);
TPrint_section& body = section('B');
for (word j = 0; j < _num_rip; j++)
{
const TString& key = tot[j]->key();
TTotal& t = (TTotal&)(tot[j]->obj());
desc = riporto;
TValuta val;
if (key.not_empty())
{
desc << ' ' << key;
TValuta val1(key,botime,ZERO); // E' una valuta fittizia, giusto per far
val = val1; // eseguire in set_imp() i calcoli per i decimali.
}
TESSL_row rip(desc, t.importo().normalize(),val);
rip.scaduto(t.scaduto());
rip.esposto(t.esposto());
rip.importo_in_euro(t.importo_euro());
rip.print_on(body);
pr.setfooterline(j + 1, body.row(0));
}
}
int TESSL_form::find_magic(TString& s, TString& magic1, TString& magic2) const
{
const int pos = s.find('<', 0);
int end;
if (pos >= 0)
{
end = s.find('>', pos);
if (end > pos)
{
int p1 = pos+1;
magic1 = s.mid(p1, 2);
while (isalnum(s[p1])) p1++;
while (p1 < end && !isalnum(s[p1])) p1++;
if (p1 < end)
magic2 = s.mid(p1, 2);
else
magic2.cut(0);
}
else
end = s.len()-1;
const TString right(s.mid(end+1));
s.cut(pos); s << right;
}
return pos;
}
void TESSL_form::change_magic_body(const TESSL_row& row, TString& s)
{
TString magic1(4), magic2(4), val(50);
int pos;
while ((pos = find_magic(s, magic1, magic2)) >= 0)
{
val.cut(0);
if (magic1 == "PA" || magic2 == "PA")
{
val = row.descrizione();
if (val.empty())
val = causali().decode(row.causale());
}
if (magic1 == "MO" || magic2 == "MO")
{
val = movimenti().decode(row.num_reg());
}
s.insert(val, pos);
}
}
void TESSL_form::change_magic_footer(const THash_object& o, TString& s)
{
TString magic1(4), magic2(4), val(50);
int pos;
while ((pos = find_magic(s, magic1, magic2)) >= 0)
{
val.cut(0);
if (magic1 == "DA")
{
const TDate& d = magic2 == "SC" ? _dls : _dlo;
if (d != eotime)
val = d.string();
}
if (magic1 == "VA")
val = o.key();
if (magic1 == "DE")
val = valute().decode(o.key());
s.insert(val, pos);
}
}
void TESSL_form::print_total(int riga, const THash_object& o)
{
const short MAXID = 5;
const short f_id[MAXID] = { PEC_TSALDO, PEC_TSCADUTO, PEC_TESPOSTO, PEC_TIMPEURO, PEC_TUNASSIGNED };
TString_array prompt(MAXID);
TPrint_section& foot = section('F');
TPrint_section& body = section('B');
TForm_item& bdesc = body.find_field(PEC_DESCR);
// Sostituisce magic-names nei prompt
TString s(80);
int i;
for (i = 0; i < MAXID; i++)
{
TForm_item& desc_field = foot.find_field(f_id[i]);
if (desc_field.shown())
{
s = desc_field.prompt();
prompt.add(s, i);
change_magic_footer(o, s);
desc_field.set_prompt(s);
if (desc_field.x() <= 0)
desc_field.set_x(bdesc.x());
}
}
const TTotal& t = (const TTotal&)o.obj();
const TImporto& imp = t.importo();
const bool in_valuta = o.key().not_empty();
TForm_item& dare = foot.find_field(PEC_DARE);
TForm_item& avere = foot.find_field(PEC_AVERE);
TString_array old_pictures;//pictures da rippristinare dopo aver stampato
if (dare.x() <= 0 || avere.x() <= 0)
{
TForm_item& bdare = body.find_field(PEC_DARE);
dare.set_x(bdare.x());
dare.width() = bdare.width();
TForm_item& bavere = body.find_field(PEC_AVERE);
avere.set_x(bavere.x());
avere.width() = bavere.width();
}
//modify_picture(dare,old_pictures,in_valuta);
//modify_picture(avere,old_pictures,in_valuta);
char sez = imp.sezione();
real num = imp.valore();
if (sez=='D' && num<0)
{
num = abs(num); sez = 'A';
}
if (sez=='A' && num<0)
{
num = abs(num); sez = 'D';
}
if (sez == 'D')
{
dare.set(num.string());
avere.set("");
}
else
{
dare.set("");
avere.set(num.string());
}
TForm_item& scaduto = foot.find_field(PEC_SCADUTO);
if (scaduto.x() <= 0)
{
TForm_item& bscaduto = body.find_field(PEC_SCADUTO);
scaduto.set_x(bscaduto.x());
scaduto.width() = bscaduto.width();
}
//modify_picture(scaduto,old_pictures,in_valuta);
scaduto.set(t.scaduto().string());
TForm_item& esposto = foot.find_field(PEC_ESPOSTO);
if (esposto.x() <= 0)
{
TForm_item& besposto = body.find_field(PEC_ESPOSTO);
esposto.set_x(besposto.x());
esposto.width() = besposto.width();
}
//modify_picture(esposto,old_pictures,in_valuta);
esposto.set(t.esposto().string());
TForm_item& implire = foot.find_field(PEC_IMPEURO);
if (implire.x() <= 0)
{
TForm_item& bimplire = body.find_field(PEC_IMPEURO);
implire.set_x(bimplire.x());
implire.width() = bimplire.width();
if (bimplire.shown()) implire.show();
else implire.hide();
}
//modify_picture(implire,old_pictures,FALSE);
implire.set(t.importo_euro().string());
TForm_item& unreferenced = foot.find_field(PEC_UNASSIGNED);
if (unreferenced.x() <= 0)
{
TForm_item& uns = body.find_field(PEC_AVERE);
unreferenced.set_x(uns.x());
unreferenced.width() = avere.width();
}
//modify_picture(unreferenced,old_pictures,in_valuta);
unreferenced.set(t.unassigned().valore().string());
foot.update();
// Ripristina prompt originari
for (i = 0; i < MAXID; i++)
{
const TString* p = (const TString*)prompt.objptr(i);
if (p)
{
TForm_item& desc_field = foot.find_field(f_id[i]);
desc_field.set_prompt(*p);
}
}
for (word r = 0; r < _total_rows; r++)
printer().setfooterline(riga + r, foot.row(r));
}
void TESSL_form::stampa_pedata(TPrinter& pr)
{
THash_object* tot[MAXTOT];
word num_rip = ordina_totali_per_valuta(tot);
// La prima riga del footer deve essere lasciata libera per la fincatura
// Ogni sottosezione di totale occupa _total_rows righe: per cui devo calcolare
// quanti totali ci stanno nelle righe riservate al footer
// const word maxtot = (section('F').height()-1) / _total_rows;
if (num_rip > _maxtot)
num_rip = _maxtot;
for (word j = 0; j < num_rip; j++)
print_total(j*_total_rows+1, *tot[j]);
}
void TESSL_form::ultima_pagina()
{
set_last_page(TRUE);
}
void TESSL_form:: header_handler(TPrinter& pr)
{
pr.resetheader();
_form->stampa_testata(pr);
}
void TESSL_form::footer_handler(TPrinter& pr)
{
pr.resetfooter();
if (_form->page(pr) > 0) // Normal page
_form->stampa_riporti(pr);
else // Last page
_form->stampa_pedata(pr);
}
void TESSL_form::azzera_totali()
{
totali().destroy(); // Azzera tutti i riporti
_num_rip = 0; // Azzera il numero di righe di riporto
set_last_page(FALSE); // Azzera il flag di ultima pagina di stampa
TPrint_section& foot = section('F');
printer().footerlen(foot.height());
printer().setcurrentpage(1);
}
bool TESSL_form::print_game(const TPartita& game)
{
bool ok = false;
TESSL_array righe(game, this);
TPrinter& pr = printer();
TPrintrow prow;
TPrint_section& body = section('B');
TImporto saldo;
real scaduto, esposto, impeuro;
// Stampa le righe di partita
int ultima_riga = 0;
int ultima_rata = 0;
int r;
for (r = 0; r < righe.items(); r++)
{
TESSL_row& riga = righe.row(r);
if (pr.rows_left() <= (body.height()+1))
{
pr.formfeed();
for (word nr = 0; nr < _num_rip; nr++)
{
TPrintrow* fl = pr.getfooterline(nr + 1);
CHECKD(fl, "Manca la riga di riporto ", nr + 1);
pr.print(*fl);
}
}
const int ri = riga.riga();
const int ra = riga.rata();
if (ri == ultima_riga && ra == ultima_rata+1)
riga.reset_uguali();
ultima_riga = ri;
ultima_rata = ra;
real resp = riga.esposto();
if (resp < ZERO)
{
resp = -resp;
riga.esposto(resp);
}
riga.print_on(body);
pr.print(body.row(0));
totali().add(riga.importo(), riga.scaduto(), riga.esposto(),
riga.importo_in_euro(), riga.valuta().codice());
saldo += riga.importo();
scaduto += riga.scaduto();
esposto += riga.esposto();
impeuro += riga.importo_in_euro();
ok = true;
}
if (ok)
{
if (_stampa_saldo)
{
saldo.normalize();
TString desc;
desc = describe(PEC_SALDO);
const TValuta& val = righe.row(r-1).valuta();
if (val.in_valuta())
desc << ' ' << val.codice();
TESSL_row sld(desc, saldo, val);
sld.scaduto(scaduto);
sld.esposto(esposto);
sld.importo_in_euro(impeuro);
sld.print_on(body);
pr.print(body.row(0));
}
// Salta una riga vuota
TPrintrow vuota;
pr.print(vuota);
}
return ok;
}
const TString& TESSL_form::describe(short id, char sez, pagetype pt) const
{
const TForm_item& fi = find_field(sez, pt, id);
return fi.prompt();
}
void TESSL_form::init_header(const TMask& m)
{
TPrint_section& head = section('H');
TForm_item& luogo_invio = head.find_field(PEC_LUOGOIN);
luogo_invio.set(m.get(F_LUOGOSEND));
TForm_item& data_invio = head.find_field(PEC_DATAIN);
data_invio.set(m.get(F_DATASEND));
TForm_item& fi = head.find_field(PEC_MEMO);
if (fi.shown())
{
TString key;
key.format("%s|%s|H0|%d", (const char *) name(), (const char *) code(), PEC_MEMO);
const TRectype & rform = cache().get(LF_RFORM, key);
if (!rform.empty())
fi.set(rform.get("TESTO"));
}
}
TESSL_form::TESSL_form(const TESSL_mask& m, bool gesval, short id_datalim, short id_datascad,
short id_giorni_rischio)
:TForm(BASE_EC_PROFILE, m.get_prof_name()),
_in_valuta(FALSE), _num_rip(0), _total_rows(0),
_causali(LF_CAUSALI, CAU_DESCR),
_movimenti(LF_MOV, MOV_DESCR),
_valute("%VAL"), _giorni_rischio(0), _maxtot(1),
_stampa_saldo(TRUE)
{
_form = this;
_lingua = m.get_prof_lang();
_who = m.get_who();
_stampa_esp = m.get_bool(F_STAMPESP);
TCursor_sheet& cs = m.cur_sheet();
_cursore = cs.cursor();
_dlo = id_datalim > 0 ? m.get_date(id_datalim) : eotime;
if (!_dlo.ok())
_dlo = eotime;
_dls = id_datascad > 0 ? m.get_date(id_datascad) : eotime;
if (id_giorni_rischio > 0)
_giorni_rischio = m.get_int(id_giorni_rischio);
_dir = _dls; _dir -= _giorni_rischio;
TPrinter& pr = printer();
pr.setheaderhandler(header_handler);
TPrint_section& head = section('H');
pr.headerlen(head.height());
TForm_item& flags = find_field('H', last_page, PEC_FLAGS);
TToken_string f(flags.prompt());
_in_valuta = gesval && f.get_char(0) == 'X'; // Il profilo e' in valuta se c'e' il flag di valuta
_fincatura = f.get_int(1);
TForm_item& esp = section('B').find_field(PEC_ESPOSTO);
if (esp.shown()) esp.show(_stampa_esp); //setta la colonna esposto solo se abilitata
genera_intestazioni(odd_page, head.height() - 1);
init_header(m); // Set fixed text
pr.setfooterhandler(footer_handler);
const TPrint_section& foot = section('F');
pr.footerlen(foot.height());
_total_rows = 1;
for (word fi = 0; fi < foot.fields(); fi++)
{
const TForm_item& item = foot.field(fi);
if (item.shown())
{
const word y = (word)item.y();
if (y > _total_rows)
_total_rows = y;
}
}
_maxtot = f.get_int(3);
if (_maxtot <= 0 || _maxtot > ((int)foot.height() - 2) / _total_rows)
_maxtot = (foot.height() - 2) / _total_rows;
int rows[] = { (int)head.height(), (int)(pr.formlen() - foot.height() + 1), 0};
TPrint_section& fink = section('G');
if (_fincatura)
{
set_fink_mode(_fincatura == 1 ? FALSE : TRUE);
genera_fincatura(odd_page, rows[0] - 2, rows[1] + (_maxtot * _total_rows) + 2, rows);
}
if (fink.fields() > 0)
fink.update(); // Setta il backgroud di stampa
}
TESSL_form::~TESSL_form()
{
TPrinter& pr = printer();
pr.setheaderhandler(NULL);
pr.setfooterhandler(NULL);
_form = NULL;
}