campo-sirio/sv/sv1100.cpp
augusto b9900da2e9 Aggiunto il filtro per documenti abilitati alle statistiche
git-svn-id: svn://10.65.10.50/trunk@5775 c028cbd2-c16b-5b4b-a496-9718f37d4682
1997-12-19 09:47:59 +00:00

750 lines
18 KiB
C++
Executable File

#include <applicat.h>
#include <config.h>
#include <form.h>
#include <msksheet.h>
#include <printer.h>
#include <progind.h>
#include <urldefid.h>
#include "../sc/scselect.h"
#include "../ve/velib.h"
#include <doc.h>
#include "sv1.h"
#include "sv1100a.h"
class TSchede_mask : public TSelection_mask
{
void init_sheet(short id);
void ini2sheet(short id);
void sheet2ini(short id);
protected:
static bool date_handler(TMask_field& f, KEY k);
static bool num_handler(TMask_field& f, KEY k);
static bool save_handler(TMask_field& f, KEY k);
static bool sheet_notify(TSheet_field& s, int row, KEY k);
static bool fieldname_handler(TMask_field& f, KEY k);
public:
void mask2ini();
void ini2mask();
TSchede_mask();
virtual ~TSchede_mask() { }
};
bool TSchede_mask::date_handler(TMask_field& f, KEY k)
{
bool ok = TRUE;
if (f.to_check(k))
{
TMask& m = f.mask();
const TDate fd(m.get(F_FROMDATE));
const TDate td(m.get(F_TODATE));
if (td.ok() && td < fd)
ok = f.error_box("La data finale deve seguire quella iniziale");
}
return ok;
}
bool TSchede_mask::num_handler(TMask_field& f, KEY k)
{
bool ok = TRUE;
if (f.to_check(k))
{
TMask& m = f.mask();
const TString& fn = m.get(F_FROMNUM);
const TString& tn = m.get(F_TONUM);
if (tn.not_empty() && tn < fn)
ok = f.error_box("La numerazione finale deve seguire quella iniziale");
}
return ok;
}
bool TSchede_mask::save_handler(TMask_field& f, KEY k)
{
if (k == K_SPACE)
{
TSchede_mask& m = (TSchede_mask&)f.mask();
m.mask2ini();
}
return TRUE;
}
bool TSchede_mask::fieldname_handler(TMask_field& f, KEY k)
{
if (f.to_check(k))
{
TSchede_mask& m = (TSchede_mask&)f.mask();
TEdit_field& head = m.efield(S_HEAD);
if (head.empty())
{
TParagraph_string para(m.get(S_DESCR), head.size());
head.set(para.get(0));
}
}
return TRUE;
}
bool TSchede_mask::sheet_notify(TSheet_field& s, int row, KEY k)
{
bool ok = TRUE;
switch(k)
{
case K_INS:
ok = s.items() < 8;
break;
default:
break;
}
return ok;
}
void TSchede_mask::sheet2ini(short id)
{
TSheet_field& sheet = sfield(id);
TString_array& arr = sheet.rows_array();
for (int r = arr.last(); r >= 0; r--)
if (arr.row(r)[0] <= ' ')
arr.destroy(r);
arr.pack();
const char* field = id == F_SINTETICA ? "SynField" : "DetField";
const char* head = id == F_SINTETICA ? "SynHead" : "DetHead";
TConfig ini(CONFIG_STUDIO, "sv1100");
for (r = arr.last(); r >= 0; r--)
{
TToken_string& row = arr.row(r);
ini.set(field, row.get(0), NULL, TRUE, r);
ini.set(head, row.get(), NULL, TRUE, r);
}
ini.remove(field, arr.items());
ini.remove(head, arr.items());
}
void TSchede_mask::ini2sheet(short id)
{
TSheet_field& sheet = sfield(id);
const char* field = id == F_SINTETICA ? "SynField" : "DetField";
const char* head = id == F_SINTETICA ? "SynHead" : "DetHead";
TConfig ini(CONFIG_STUDIO, "sv1100");
for (int r = 0; ; r++)
{
TString16 str = ini.get(field, NULL, r);
if (str.not_empty())
{
TToken_string& row = sheet.row(r);
row = str;
row.add(ini.get(head, NULL, r));
sheet.check_row(r);
}
else
break;
}
}
void TSchede_mask::mask2ini()
{
sheet2ini(F_SINTETICA);
sheet2ini(F_DETTAGLIATA);
}
void TSchede_mask::ini2mask()
{
ini2sheet(F_SINTETICA);
ini2sheet(F_DETTAGLIATA);
}
void TSchede_mask::init_sheet(short id)
{
TSheet_field& sheet = sfield(id);
sheet.set_notify(sheet_notify);
TMask& sm = sheet.sheet_mask();
sm.set_handler(S_FIELD, fieldname_handler);
}
TSchede_mask::TSchede_mask()
: TSelection_mask("sv1100a")
{
set_handler(F_TODATE, date_handler);
set_handler(F_TONUM, num_handler);
set_handler(DLG_SAVEREC, save_handler);
init_sheet(F_SINTETICA);
init_sheet(F_DETTAGLIATA);
ini2mask();
}
///////////////////////////////////////////////////////////
// TSchede_form
///////////////////////////////////////////////////////////
class TSchede_form : public TForm
{
public:
void init(const TSheet_field& sheet);
TSchede_form();
virtual ~TSchede_form() { }
};
TSchede_form::TSchede_form()
: TForm("sv1100a")
{
}
void TSchede_form::init(const TSheet_field& sheet)
{
TPrint_section& body = section('B', odd_page);
TString_array& arr = sheet.rows_array();
TString80 str;
bool on = TRUE;
for (word r = 3; r < body.fields(); r++)
{
const int riga = r-3;
if (on)
{
if (riga < arr.items())
{
str = arr.row(riga).get(0);
on = str.not_empty();
}
else
on = FALSE;
}
TForm_item& item = body.field(r);
if (!item.is_section())
{
item.show(on);
if (on)
{
str = arr.row(riga).get(1);
item.set_col_head(str);
}
}
}
const TPrint_section& head = section('H', odd_page);
const TPrint_section& foot = section('F', odd_page);
const int hh = head.height();
const int fh = foot.height();
const int fl = printer().formlen();
int rows[4]; // Righe orizzontali
rows[0] = hh-2; // Terzultima riga della testata
rows[1] = hh; // Ultima riga della testata
rows[2] = fl-fh+1; // Prima riga del footer
rows[3] = 0;
genera_fincatura(odd_page, rows[0], rows[2], rows);
genera_intestazioni(odd_page, hh-1);
}
///////////////////////////////////////////////////////////
// Main app
///////////////////////////////////////////////////////////
class TStampa_schede : public TApplication
{
TArray _file;
char _tipo; // <D>ettagliata o <S>intetica
char _sort; // <F>attura o <A>rticolo
char _prov; // <P>rovvisori o <D>efinitivi
TDate _fromdate, _todate; // Date limite
TString _fromnum, _tonum; // Numerazioni limite
TArray _totali; // Totali complessivi
TArray _totriga; // Totali di riga
long _progressivo; // Numero progressivo di record per file di stampa
TString _lastkey; // Ultima chiave del file di stampa temporaneo
TSchede_mask* _mask; // Mask di stampa
TSchede_form* _form; // Form di stampa
protected:
virtual bool menu(MENU_TAG mt);
virtual bool create();
virtual bool destroy();
protected:
void put_real(TRectype& tab, int index, real val, bool importo, const TDocumento& doc);
void fill_key(TRectype& tab, const TDocumento& doc);
void fill_key(TRectype& tab, const TRiga_documento& rdoc);
public:
void open_files(int logicnum, ...);
// stampa un documento (stampa sintetica)
bool fill_doc(TRectype& tab, const TDocumento& doc);
// stampa una riga documento (stampa dettagliata)
bool fill_rdoc(TRectype& tab, const TRiga_documento& rdoc);
void update_totriga(const TRectype& tab);
void fill_totriga(TRectype& tab);
void fill_tot(TRectype& tab);
bool write_tab(TLocalisamfile& tab) const;
bool write_totali_per_articolo(TLocalisamfile& tab);
bool stampa_sintetica() const { return _tipo == 'S'; }
bool stampa_dettagliata() const { return _tipo == 'D'; }
bool stampa_per_articolo() const { return _sort == 'A'; }
bool stampa_per_documento() const { return _sort == 'D'; }
bool stampa_clifo(TCursor& cur, const TString& ragsoc);
};
void TStampa_schede::put_real(TRectype& tab, int index, real val,
bool importo, const TDocumento& doc)
{
char erre[4]; sprintf(erre, "R%d", index);
if (importo && doc.in_valuta())
{
val *= doc.cambio();
val.round(0);
}
tab.put(erre, val);
real* r = (real*)_totali.objptr(index);
if (r == NULL)
_totali.add(val, index);
else
*r += val;
}
void TStampa_schede::fill_key(TRectype& tab, const TDocumento& doc)
{
tab.zero();
tab.put("COD", "PRN");
const TCli_for& clifo = doc.clifor();
tab.put("S8", clifo.tipo());
tab.put("I8", clifo.codice());
TString16 str;
TString80 key;
key = doc.data().string(ANSI);
str = doc.numerazione(); str.left_just(4);
key << str;
str.format("%4d", doc.numero());
key << str;
tab.put("S0", key);
tab.put("CODTAB", ++_progressivo);
}
void TStampa_schede::fill_key(TRectype& tab, const TRiga_documento& rdoc)
{
fill_key(tab, rdoc.doc());
_lastkey = tab.get("S0");
_lastkey.left_just(20);
if (stampa_per_articolo())
{
TString80 str = rdoc.get(RDOC_CODART);
str.left_just(20);
_lastkey.insert(str, 0);
}
TString16 numero;
numero.format("%4d", rdoc.numero());
_lastkey << numero;
tab.put("S0", _lastkey);
}
bool TStampa_schede::fill_doc(TRectype& tab, const TDocumento& doc)
{
if (stampa_dettagliata())
return FALSE;
const TTipo_documento& tipo = doc.tipo();
if (!tipo.statistiche()) // documento non abilitato per le statistiche
return FALSE;
fill_key(tab, doc);
TString descr(80);
const TCodice_numerazione& num = doc.codice_numerazione();
descr << tipo.descrizione() << ' ';
descr << num.prefisso();
descr << doc.numero();
descr << num.postfisso();
descr << " del " << doc.data();
tab.put("S1", descr);
put_real(tab, 0, doc.totale_netto(), TRUE, doc);
put_real(tab, 1, doc.totale_doc(), TRUE, doc);
TSheet_field& sheet = _mask->sfield(F_SINTETICA);
TString_array& arr = sheet.rows_array();
TString16 src;
for (int r = 0; r < arr.items(); r++)
{
TToken_string& row = arr.row(r);
src = row.get(0);
if (src.blank())
break;
const bool importo = row.get(3)[0] > ' ';
real val = doc.get(src);
put_real(tab, r+2, val, importo, doc);
}
return TRUE;
}
bool TStampa_schede::fill_rdoc(TRectype& tab, const TRiga_documento& rdoc)
{
if (stampa_sintetica())
return FALSE;
switch(rdoc.tipo().tipo())
{
case RIGA_MERCE : break;
case RIGA_OMAGGI : break;
case RIGA_PRESTAZIONI: break;
default : return FALSE;
}
const TDocumento& doc = rdoc.doc();
const TTipo_documento& tipo = doc.tipo();
if (!tipo.statistiche()) // documento non abilitato per le statistiche
return FALSE;
fill_key(tab, rdoc);
TString descr(80);
descr << rdoc.get(RDOC_CODART) << ' ';
descr << rdoc.get(RDOC_DESCR);
tab.put("S1", descr);
put_real(tab, 0, rdoc.importo(TRUE, FALSE, 0), TRUE, doc);
put_real(tab, 1, rdoc.importo(TRUE, TRUE, 0), TRUE, doc);
TSheet_field& sheet = _mask->sfield(F_DETTAGLIATA);
TString_array& arr = sheet.rows_array();
TString16 src;
for (int r = 0; r < arr.items(); r++)
{
TToken_string& row = arr.row(r);
src = row.get(0);
if (src.blank())
break;
const bool importo = row.get(3)[0] > ' ';
real val = rdoc.get(src);
put_real(tab, r+2, val, importo, doc);
}
return TRUE;
}
void TStampa_schede::update_totriga(const TRectype& tab)
{
char erre[4];
for (int r = _totali.last(); r >= 0; r--)
{
sprintf(erre, "R%d", r);
const real val(tab.get(erre));
real* tot = (real*)_totriga.objptr(r);
if (tot == NULL)
_totriga.add(val, r);
else
*tot += val;
}
}
void TStampa_schede::fill_totriga(TRectype& tab)
{
tab.zero();
tab.put("COD", "PRN");
tab.put("CODTAB", ++_progressivo);
_lastkey.overwrite("9999", _lastkey.len()-4);
tab.put("S0", _lastkey);
tab.put("S1", stampa_per_articolo() ? "Totale articolo" : "Totale documento");
tab.put("B8", TRUE); // Riga totale
for (int r = _totriga.last(); r >= 0; r--)
{
char erre[4]; sprintf(erre, "R%d", r);
tab.put(erre, (real&)_totriga[r]);
}
}
void TStampa_schede::fill_tot(TRectype& tab)
{
tab.zero();
tab.put("COD", "PRN");
tab.put("CODTAB", ++_progressivo);
tab.put("S0", "zzzzzzzzzzzzzzzzzzzz");
tab.put("S1", "Totale");
tab.put("B8", TRUE); // Riga totale
for (int r = _totali.last(); r >= 0; r--)
{
char erre[4]; sprintf(erre, "R%d", r);
tab.put(erre, (real&)_totali[r]);
}
}
bool TStampa_schede::write_tab(TLocalisamfile& tab) const
{
int err = tab.write();
if (err != NOERR)
error_box("Errore %d durante la scrittura sul file temporaneo", err);
return err == NOERR;
}
bool TStampa_schede::write_totali_per_articolo(TLocalisamfile& tab)
{
bool ok = TRUE;
TRectype& curtab = tab.curr();
const TRecfield key(curtab, "S0");
_lastkey.cut(0);
_totriga.destroy();
for (int err = tab.first(); err == NOERR && ok; err = tab.next())
{
if (_lastkey.not_empty() && _lastkey.compare((const char*)key, 20) != 0)
{
const TRecnotype pos = tab.recno();
fill_totriga(curtab);
ok = write_tab(tab);
tab.readat(pos);
_totriga.destroy();
}
_lastkey = (const char*)key;
update_totriga(curtab);
}
if (ok && _lastkey.not_empty())
{
fill_totriga(curtab);
ok = write_tab(tab);
}
return ok;
}
bool TStampa_schede::stampa_clifo(TCursor& cur, const TString& ragsoc)
{
const long items = cur.items();
TString header(160);
header = "Preparazione file temporaneo di stampa ...";
if (ragsoc.not_empty())
header << '\n' << ragsoc;
TProgind pi(items, header, TRUE, TRUE, 60);
cur.file().set_curr(new TDocumento);
TDocumento& doc = (TDocumento&)cur.file().curr();
TIsamtempfile* tab = new TIsamtempfile(LF_TAB, "svschede", TRUE,TRUE);
tab->setkey(2);
_form->relation()->replace(tab);
TRectype& curtab = tab->curr();
_totali.destroy();
_progressivo = 0;
bool can_print = TRUE;
for (cur = 0; cur.pos() < items && can_print; ++cur)
{
pi.addstatus(1);
if (pi.iscancelled())
{
can_print = FALSE;
break;
}
if (stampa_sintetica())
{
if (fill_doc(curtab, doc))
can_print = write_tab(*tab);
}
else
{
_totriga.destroy();
for (int r = doc.physical_rows(); r > 0 && can_print; r--)
{
const TRiga_documento& rdoc = doc[r];
if (fill_rdoc(curtab, rdoc))
{
can_print = write_tab(*tab);
if (stampa_per_documento())
update_totriga(curtab);
}
}
if (can_print && _totriga.items() > 0)
{
fill_totriga(curtab);
can_print = write_tab(*tab);
}
}
}
if (can_print && stampa_per_articolo())
can_print = write_totali_per_articolo(*tab);
if (can_print)
{
fill_tot(curtab);
can_print = write_tab(*tab);
}
pi.close_modal();
if (can_print && tab->items() > 0)
{
_form->print();
}
_form->relation()->replace(new TLocalisamfile(LF_TAB));
return can_print;
}
bool TStampa_schede::menu(MENU_TAG mt)
{
TSchede_mask& m = *_mask;
while (m.run() != K_QUIT)
{
_tipo = m.get(F_TIPO)[0];
_sort = m.get(F_ORDINE)[0];
_prov = m.get(F_PROVVIS)[0];
_fromdate = m.get_date(F_FROMDATE);
_todate = m.get_date(F_TODATE);
_fromnum = m.get(F_FROMNUM);
_tonum = m.get(F_TONUM);
_form->init(m.sfield(stampa_dettagliata() ? F_DETTAGLIATA : F_SINTETICA));
TString filter(80);
if (_fromdate.ok())
{
if (filter.not_empty()) filter << "&&";
filter << "(ANSI(" << DOC_DATADOC << ")>=\"" << _fromdate.string(ANSI) << "\")";
}
if (_todate.ok())
{
if (filter.not_empty()) filter << "&&";
filter << "(ANSI(" << DOC_DATADOC << ")<=\"" << _todate.string(ANSI) << "\")";
}
if (_fromnum.not_empty())
{
if (filter.not_empty()) filter << "&&";
filter << '(' << DOC_CODNUM << ">=\"" << _fromnum << "\")";
}
if (_tonum.not_empty())
{
if (filter.not_empty()) filter << "&&";
filter << '(' << DOC_CODNUM << "<=\"" << _tonum << "\")";
}
const TCursor_sheet& clifosheet = m.cur_sheet();
TCursor& clifocur = *clifosheet.cursor();
const long clifos = clifocur.items();
const bool all = clifosheet.checked() == 0;
TRelation rel(LF_DOC);
TRectype rec(LF_DOC);
TString ragsoc(80);
bool cancel = FALSE;
if (all)
{
TString msg;
msg.format("Attenzione: e' stata selezionata la stampa di tutti i %s!\n"
"Si desidera continuare ugualmente?",
m.get_who() == 'C' ? "clienti" : "fornitori");
cancel = !yesno_box(msg);
}
for (clifocur = 0; clifocur.pos() < clifos && !cancel; ++clifocur)
{
if (all || clifosheet.checked(clifocur.pos()))
{
const long codcf = clifocur.file().get_long(CLI_CODCF);
ragsoc = m.get_who() == 'C' ? "Cliente" : "Fornitore";
ragsoc << ' ' << codcf << " - " << clifocur.file().get(CLI_RAGSOC);
rec.put(DOC_TIPOCF, m.get_who());
rec.put(DOC_CODCF, codcf);
rec.put(DOC_PROVV, _prov);
// Uso la chiave 2: TIPOCF+CODCF+PROVV+ANNO+DATADOC+CODNUM+NDOC
TCursor cur(&rel, filter, 2, &rec, &rec);
if (cur.items() > 0)
{
cur.freeze();
cancel = !stampa_clifo(cur, ragsoc);
cur.freeze(FALSE);
}
}
}
}
return FALSE;
}
void TStampa_schede::open_files(int logicnum, ...)
{
va_list marker;
va_start(marker, logicnum);
while (logicnum > 0)
{
CHECKD(_file.objptr(logicnum) == NULL, "File gia' aperto: ", logicnum);
_file.add(new TLocalisamfile(logicnum), logicnum);
logicnum = va_arg(marker, int);
}
}
bool TStampa_schede::create()
{
open_files(LF_TABCOM, 0); // File comuni
open_files(LF_TAB, LF_CLIFO, LF_OCCAS, 0); // File ditta
open_files(LF_CFVEN, LF_DOC, LF_RIGHEDOC, 0); // File vendite
_mask = new TSchede_mask;
_form = new TSchede_form;
dispatch_e_menu(BAR_ITEM(1));
return TRUE;
}
bool TStampa_schede::destroy()
{
delete _form;
delete _mask;
_file.destroy();
return TRUE;
}
int sv1100(int argc, char* argv[])
{
TStampa_schede app;
app.run(argc, argv, "Stampa schede");
return 0;
}